feat: in-app Orchestrator (Phase 2) — multi-agent conductor
Brings the deterministic Han-flow conductor into BooCode: launch any read-only flow from BooChat or BooCoder, watch each agent stream live in a Paseo-style run pane, get an evidence-disciplined report — on local Qwen, persisted and resumable. Read-only enforced hard via qwen --approval-mode plan (orchestrator tasks fail closed if qwen is unavailable; never fall to write-capable native). Backend (apps/coder): re-homed conductor defs, flow_runs/flow_steps schema, flow-runner + dispatcher onTaskTerminal hook, restart-resume, runs routes (launch/list/get/cancel), user-channel WS. Contracts: two flow_run_* frames. Web: orchestrator pane kind + OrchestratorPane, Workflow button + slash flows (BooChat/BooCoder parity), FlowLauncherDialog, "New Orchestrator" in the + and split menus, runs history + export. Plan: openspec/changes/orchestrator. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Code, Columns2, History, MessageSquare, Plus, RotateCcw, Terminal, X } from 'lucide-react';
|
||||
import { Code, Columns2, History, MessageSquare, Plus, RotateCcw, Terminal, Workflow, X } from 'lucide-react';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -16,6 +16,9 @@ interface Props {
|
||||
// (the second control) adds a new pane.
|
||||
onNewTab: (kind: 'chat' | 'terminal' | 'coder') => void;
|
||||
onSplitPane: (kind: 'chat' | 'terminal' | 'coder') => void;
|
||||
// When provided, shows a "New Orchestrator" item that opens the flow launcher.
|
||||
// Orchestrators are always split (run-bound; can't live as a tab in another pane).
|
||||
onNewOrchestrator?: () => void;
|
||||
onReopenPane?: () => void;
|
||||
onShowHistory: () => void;
|
||||
onRemovePane?: () => void;
|
||||
@@ -31,6 +34,7 @@ const BTN =
|
||||
export function PaneHeaderActions({
|
||||
onNewTab,
|
||||
onSplitPane,
|
||||
onNewOrchestrator,
|
||||
onReopenPane,
|
||||
onShowHistory,
|
||||
onRemovePane,
|
||||
@@ -62,6 +66,11 @@ export function PaneHeaderActions({
|
||||
<DropdownMenuItem onSelect={() => onNewTab('coder')}>
|
||||
<Code size={14} /> New BooCode
|
||||
</DropdownMenuItem>
|
||||
{onNewOrchestrator && (
|
||||
<DropdownMenuItem onSelect={onNewOrchestrator}>
|
||||
<Workflow size={14} /> New Orchestrator
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
@@ -87,6 +96,11 @@ export function PaneHeaderActions({
|
||||
<DropdownMenuItem onSelect={() => onSplitPane('coder')}>
|
||||
<Code size={14} /> New BooCode
|
||||
</DropdownMenuItem>
|
||||
{onNewOrchestrator && (
|
||||
<DropdownMenuItem onSelect={onNewOrchestrator}>
|
||||
<Workflow size={14} /> New Orchestrator
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user