fix: mark handoff triage-to-specialist edges as loop edges

The forward edges from triage to specialists participate in cycles
(triage→specialist + specialist→triage), so they must be marked with
isLoop, condition, and maxIterations to pass validation.

Fixes the Handoff Support Flow template and scaffoldGraphForMode()
for handoff mode. Updates the corresponding test expectation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-04-06 23:37:34 +02:00
co-authored by Copilot
parent 5ac6980b3f
commit a68c9ee837
2 changed files with 19 additions and 9 deletions
+15 -3
View File
@@ -883,7 +883,11 @@ export function scaffoldGraphForMode(
edges: [
createWorkflowEdge(`edge-start-to-${triage.id}`, 'start', triage.id),
createWorkflowEdge(`edge-${triage.id}-to-end`, triage.id, 'end'),
...specialists.map((specialist) => createWorkflowEdge(`edge-${triage.id}-to-${specialist.id}`, triage.id, specialist.id)),
...specialists.map((specialist) => createWorkflowEdge(`edge-${triage.id}-to-${specialist.id}`, triage.id, specialist.id, 'direct', {
isLoop: true,
maxIterations: 4,
condition: { type: 'always' },
})),
...specialists.map((specialist) => createWorkflowEdge(`edge-${specialist.id}-to-${triage.id}`, specialist.id, triage.id, 'direct', {
isLoop: true,
maxIterations: 4,
@@ -1147,8 +1151,16 @@ export function createBuiltinWorkflows(timestamp: string): WorkflowDefinition[]
edges: [
createWorkflowEdge('edge-start-to-agent-handoff-triage', 'start', 'agent-handoff-triage'),
createWorkflowEdge('edge-agent-handoff-triage-to-end', 'agent-handoff-triage', 'end'),
createWorkflowEdge('edge-agent-handoff-triage-to-agent-handoff-ux', 'agent-handoff-triage', 'agent-handoff-ux'),
createWorkflowEdge('edge-agent-handoff-triage-to-agent-handoff-runtime', 'agent-handoff-triage', 'agent-handoff-runtime'),
createWorkflowEdge('edge-agent-handoff-triage-to-agent-handoff-ux', 'agent-handoff-triage', 'agent-handoff-ux', 'direct', {
isLoop: true,
maxIterations: 4,
condition: { type: 'always' },
}),
createWorkflowEdge('edge-agent-handoff-triage-to-agent-handoff-runtime', 'agent-handoff-triage', 'agent-handoff-runtime', 'direct', {
isLoop: true,
maxIterations: 4,
condition: { type: 'always' },
}),
createWorkflowEdge('edge-agent-handoff-ux-to-agent-handoff-triage', 'agent-handoff-ux', 'agent-handoff-triage', 'direct', {
isLoop: true,
maxIterations: 4,
+4 -6
View File
@@ -430,12 +430,10 @@ describe('workflow validation', () => {
const loopEdges = graph.edges.filter((edge) => edge.isLoop);
expect(graph.nodes.map((node) => node.id)).toContain('agent-handoff-triage');
expect(loopEdges).toHaveLength(1);
expect(loopEdges[0]).toMatchObject({
source: 'agent-handoff-specialist-1',
target: 'agent-handoff-triage',
maxIterations: 4,
});
// Both forward (triage→specialist) and return (specialist→triage) edges are loops
expect(loopEdges).toHaveLength(2);
expect(loopEdges.every((edge) => edge.maxIterations === 4)).toBe(true);
expect(loopEdges.every((edge) => edge.condition?.type === 'always')).toBe(true);
});
test('scaffolds group-chat mode with loop edges between agent nodes', () => {