Files
windmill/frontend/src/lib/components/modulesTest.svelte.ts
T
Ruben FiszelandClaude Opus 5 4c4387d52a feat(flow-editor): show an agent's tool-call status without moving the graph (#10557)
* feat(flow-editor): surface an agent's tool-call status without moving the graph

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: count only an agent's tool calls and key them in one place

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: report an agent's replies alongside its tool calls

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: break the agent summary down by action kind

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: key agent tool nodes by kind and keep the summary clear of the tool row

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* refactor: read agent action status from the run's success array

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test: pin the tool joins a local run cannot reach

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: place the agent summary beside the step and match MCP paths bare

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: feed a single-step agent test's calls into the graph status

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 02:17:34 +00:00

64 lines
1.8 KiB
TypeScript

import type { Job } from '$lib/gen'
import type { GraphModuleState } from './graph'
export type ModuleTestState = {
loading: boolean
cancel?: () => Promise<void>
testJob?: Job
hiddenInGraph?: boolean
}
export class ModulesTestStates {
states: Record<string, ModuleTestState> = $state({})
runTestCb?: (moduleId: string) => void
hideJobsInGraph() {
for (const state of Object.values(this.states)) {
state.hiddenInGraph = true
}
}
constructor(runTestCb?: (moduleId: string) => void) {
this.states = {}
this.runTestCb = runTestCb
}
}
export function jobToGraphModuleState(testState: ModuleTestState): GraphModuleState | undefined {
if (testState.hiddenInGraph) {
return undefined
}
// Testing one step runs it as a single-module flow preview, so an agent's calls land on that
// preview's own status. They arrive while it is still running, which is when they are worth
// showing, so they have to be read before the loading short-circuit.
const agentModule = testState.testJob?.['flow_status']?.modules?.[0]
const agentActions = agentModule?.agent_actions
? {
agent_actions: agentModule.agent_actions,
agent_actions_success: agentModule.agent_actions_success
}
: undefined
if (testState.loading) {
return {
type: 'InProgress',
args: {},
...agentActions
}
} else if (testState.testJob) {
return {
args: testState.testJob.args,
type:
testState.testJob.type === 'QueuedJob'
? 'InProgress'
: testState.testJob['success']
? 'Success'
: 'Failure',
job_id: testState.testJob.id,
tag: testState.testJob.tag,
duration_ms: testState.testJob['duration_ms'],
started_at: testState.testJob.started_at
? new Date(testState.testJob.started_at).getTime()
: undefined,
...agentActions
}
}
}