From f4cb4c768be144a6f38d446ccf0a3819d164bbbd Mon Sep 17 00:00:00 2001 From: David Kaya Date: Mon, 6 Apr 2026 23:30:01 +0200 Subject: [PATCH] feat: add frontend orchestration mode UI to workflow designer - Add OrchestrationModePanel with mode cards for all 5 modes (single, sequential, concurrent, handoff, group-chat) - Add handoff settings panel: triage agent selector, tool-call filtering, return-to-previous toggle, custom instructions - Add group-chat settings panel: selection strategy display, max rounds input - Add auto-inference indicator when mode is not explicitly set - Add scaffold dialog when changing mode with existing agents - Add mode badge (top-left pill) on workflow graph canvas - Wire orchestration mode panel into WorkflowSettingsPanel above general settings Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/renderer/components/WorkflowEditor.tsx | 7 + .../workflow/OrchestrationModePanel.tsx | 503 ++++++++++++++++++ .../workflow/WorkflowGraphCanvas.tsx | 33 +- 3 files changed, 541 insertions(+), 2 deletions(-) create mode 100644 src/renderer/components/workflow/OrchestrationModePanel.tsx diff --git a/src/renderer/components/WorkflowEditor.tsx b/src/renderer/components/WorkflowEditor.tsx index 70204bd..940ba76 100644 --- a/src/renderer/components/WorkflowEditor.tsx +++ b/src/renderer/components/WorkflowEditor.tsx @@ -21,6 +21,7 @@ import { WorkflowGraphCanvas } from './workflow/WorkflowGraphCanvas'; import { ExportDropdown, ExportModal, ImportModal } from './workflow/WorkflowExportImportPanel'; import { WorkflowGraphInspector } from './workflow/WorkflowGraphInspector'; import { WorkflowNodePalette } from './workflow/WorkflowNodePalette'; +import { OrchestrationModePanel } from './workflow/OrchestrationModePanel'; interface WorkflowEditorProps { availableModels: ReadonlyArray; @@ -655,6 +656,12 @@ function WorkflowSettingsPanel({

Settings

+ + {/* Orchestration mode — prominent, above general settings */} +
+ +
+
[m.value, m])); + +/* ── Scaffold confirmation dialog ──────────────────────────── */ + +function ScaffoldDialog({ + fromMode, + toMode, + onAccept, + onDecline, +}: { + fromMode: string; + toMode: WorkflowOrchestrationMode; + onAccept: () => void; + onDecline: () => void; +}) { + const target = modeMap.get(toMode); + return ( +
+
+

+ Restructure graph for {target?.label ?? toMode}? +

+

+ This will update edges to match the {target?.label ?? toMode} topology while keeping your existing agents. + {fromMode && ( + + Changing from {fromMode}. + + )} +

+
+ + +
+
+
+ ); +} + +/* ── Mode selector card ────────────────────────────────────── */ + +function ModeCard({ + option, + selected, + onClick, +}: { + option: ModeOption; + selected: boolean; + onClick: () => void; +}) { + const Icon = option.icon; + return ( + + ); +} + +/* ── Handoff settings sub-panel ────────────────────────────── */ + +function HandoffSettingsPanel({ + settings, + agentNodes, + onChange, +}: { + settings: HandoffModeSettings; + agentNodes: WorkflowNode[]; + onChange: (settings: HandoffModeSettings) => void; +}) { + const triageOptions = useMemo(() => [ + { value: '', label: 'First agent (default)' }, + ...agentNodes.map((node) => ({ + value: node.id, + label: node.label || (node.config.kind === 'agent' ? node.config.name : node.id), + })), + ], [agentNodes]); + + const filteringOptions = [ + { value: 'none', label: 'None — All tools available' }, + { value: 'handoff-only', label: 'Handoff-only — Restrict to handoff tools' }, + { value: 'all', label: 'All — Full tool filtering' }, + ]; + + return ( +
+
+ + + Handoff Settings + +
+ + + onChange({ ...settings, triageAgentNodeId: v || undefined })} + /> + + + + onChange({ ...settings, toolCallFiltering: v as HandoffModeSettings['toolCallFiltering'] })} + /> + + +
+
+
Return to Previous
+

Allow specialists to hand back to the previous agent

+
+ +
+ + +