A multi-agent collaboration control panel for Claude Code. Orchestra coordinates a team of specialized subagents through a shared JSON-based communication bus powered by FastAPI WebSocket.
graph TB
subgraph "Control Panel (Browser)"
UI["http://localhost:5173"]
end
subgraph "FastAPI Backend"
API["REST API<br/>/api/*"]
WS["WebSocket<br/>/ws"]
SCHED["Scheduler<br/>(auto-assign)"]
WATCH["File Watcher<br/>(event-driven)"]
AGENT_MGR["Agent Manager<br/>/launch"]
CONPTY["ConPTY Sessions"]
PROC_REG["Process Registry"]
HELPER["HelperProcess<br/>(PTY + STDIN)"]
end
subgraph "Shared .orchestra/ Directory"
DB["orchestra.db<br/>(SQLite)"]
STATE["state.json<br/>(global state)"]
AGENTS["agents/{id}.json<br/>(per-agent state)"]
TASKS["tasks.json<br/>(task queue)"]
BROADCAST["broadcast.md<br/>(panel msgs)"]
PLUGINS["plugins/{name}/<br/>(extensions)"]
MEMORY["memory/<br/>(3-tier memory)"]
CHECKPOINTS["checkpoints/<br/>(task snapshots)"]
CLAUDE_AGENTS[".claude/agents/<br/>(CC prompt files)"]
WORKFLOWS["workflows/<br/>(DAG templates)"]
CONPTY_OUT["ConPTY output<br/>(log_tail)"]
STDIN_INJ["stdin_injector<br/>(rate-limited injection)"]
end
UI <-->|"WebSocket / HTTP"| WS
API --> DB
WS --> DB
SCHED --> DB
WATCH --> DB
AGENT_MGR --> HELPER
CONPTY --> CONPTY_OUT
PROC_REG --> DB
HELPER --> STDIN_INJ
Data flow: The control panel can control Claude Code processes. Agents are collaborators that run as Interactive CLI windows with persistent context. Orchestra schedules tasks, monitors state, and can send commands to agents (STDIN injection, terminal monitoring). Supports both headless (claude -p) and interactive (Windows Terminal + ConPTY) modes.
One-command startup (PowerShell):
cd orchestra
powershell -File scripts/start.ps1 -WorkspaceDir "D:\your\workspace"One-command startup (Windows Batch):
cd orchestra\scripts
run.batStop services:
cd orchestra\scripts
stop.batRestart services:
cd orchestra\scripts
restart.batManual setup (two terminals):
Terminal 1 — Backend:
cd orchestra/backend
pip install -r requirements.txt
$env:ORCHESTRA_WORKSPACE = "D:\your\workspace"
$env:PORT = 4001
python main.pyTerminal 2 — Frontend:
cd orchestra/frontend
npm install
npm run devOpen http://localhost:5173 in your browser.
| Requirement | Version | Notes |
|---|---|---|
| Python | 3.11+ | Backend runtime |
| Node.js | 18+ | Frontend build |
| Claude Code CLI | Latest | Available in PATH as claude |
Via UI:
- Enter a task title and description in the input panel at the bottom of the screen
- Select priority (Low / Normal / High)
- Click Submit Task
- The task appears in the queue with status
pending
The scheduler automatically assigns pending tasks to idle agents within 5 seconds.
Via API:
curl -X POST http://localhost:4001/api/tasks \
-H "Content-Type: application/json" \
-d '{
"title": "Write authentication tests",
"description": "Add unit tests for the auth module covering login, logout, and session expiry",
"priority": "high"
}'The API response includes a size_estimate advisory (micro / small / medium / large / xlarge) and size_ok flag indicating whether the task is within the optimal 5–30 minute range.
Via UI:
- Click the "+" button in the Agent Panel (left sidebar)
- Fill in agent details: name, display name, role description, skills
- Click Create Agent
Via API:
# Create agent
curl -X POST http://localhost:4001/api/agents \
-H "Content-Type: application/json" \
-d '{
"agent_id": "coder",
"display_name": "Coder",
"role_description": "Expert at writing and refactoring code",
"skills": ["python", "typescript", "debugging"],
"max_concurrent_tasks": 2
}'
# Update agent status
curl -X PATCH http://localhost:4001/api/agents/coder \
-H "Content-Type: application/json" \
-d '{"status": "idle"}'
# Delete agent (cannot delete if agent has active tasks)
curl -X DELETE http://localhost:4001/api/agents/coderCreating an agent generates a prompt file at .claude/agents/orchestra-{agent_id}.md.
Auto-discovery: On backend startup, Orchestra automatically scans .orchestra/agents/*.json and registers any found agents — no manual creation is needed for agents that already have state files.
pending → assigned → working → done
↘ ↘
error cancelled
↘
blocked (dependency not met)
| Status | Description |
|---|---|
pending |
Awaiting assignment by the scheduler |
assigned |
Claimed by an agent, work not yet started |
working |
Agent is actively processing |
done |
Completed successfully |
error |
Failed, timed out, or rejected (size violation, max retries exceeded) |
cancelled |
Manually cancelled |
blocked |
Waiting on dependency tasks to complete |
Tasks can declare dependencies on other tasks. A task with unmet dependencies is automatically marked blocked and unblocks when all dependencies reach done status.
Via API when creating:
curl -X POST http://localhost:4001/api/tasks \
-H "Content-Type: application/json" \
-d '{
"title": "Second task",
"description": "Depends on first task completing first",
"dependencies": ["task-20260409-xxxx-abc1"]
}'Via UI (Workflow tab):
- Click the Workflow tab to see tasks with dependencies as a node graph
- Right-click a node to add or remove dependencies
- Click a node to open the task detail modal
When assigning tasks, the scheduler uses a three-tier matching strategy:
preferred_agent— If specified and that agent is idle with capacity, always prefer first- Skills matching — Score agents by overlap between
task.skills_requiredandagent.skills - Keyword fallback — Match agent ID keywords in task title (e.g., "coder" in title matches the
coderagent)
curl -X POST http://localhost:4001/api/tasks \
-H "Content-Type: application/json" \
-d '{
"title": "Fix Python bug",
"description": "Debug the authentication module",
"skills_required": ["python", "debugging"],
"preferred_agent": "coder"
}'Select multiple tasks using the checkboxes in the task queue:
- Batch Cancel — Cancel all selected tasks
- Batch Retry — Retry all selected failed tasks
A counter shows how many tasks are currently selected.
Agents report a heartbeat timestamp. If no heartbeat is received for 60 seconds, a warning icon (yellow triangle) appears next to the agent name in the Agent Card. This helps identify agents that may have crashed or become unresponsive.
The Workflow tab displays tasks with dependencies as a directed acyclic graph (DAG):
- Click a node to open the task detail modal
- Right-click a node to add or remove dependencies via context menu
- Nodes are color-coded by status
- Tasks without dependencies are not shown
Plugins live in .orchestra/plugins/{plugin_name}/ and require a plugin.json manifest:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "What the plugin does",
"hooks": [
"on_task_created",
"on_task_assigned",
"on_task_completed"
],
"tools": [
{
"name": "tool_name",
"description": "What the tool does",
"input_schema": {"type": "object", "properties": {"param": {"type": "string"}}},
"handler": "handler_function_name"
}
]
}Available hooks:
on_task_created— Fired when a new task is createdon_task_assigned— Fired when a task is assigned to an agenton_task_completed— Fired when a task is marked done
MCP-style tool registry:
# List all registered tools
curl http://localhost:4001/api/tools
# Call a registered tool
curl -X POST http://localhost:4001/api/tools/my-plugin.tool_name/call \
-H "Content-Type: application/json" \
-d '{"param": "value"}'Base URL: http://localhost:4001
Create task:
curl -X POST http://localhost:4001/api/tasks \
-H "Content-Type: application/json" \
-d '{"title": "Write tests", "description": "Add unit tests for auth module", "priority": "high"}'Get full state:
curl http://localhost:4001/api/stateCancel task:
curl -X DELETE http://localhost:4001/api/tasks/{task_id}Update task (with actions):
# Claim task for agent
curl -X PATCH http://localhost:4001/api/tasks/{task_id} \
-H "Content-Type: application/json" \
-d '{"action": "claim", "agent_id": "coder"}'
# Mark complete
curl -X PATCH http://localhost:4001/api/tasks/{task_id} \
-H "Content-Type: application/json" \
-d '{"action": "complete", "result_summary": "All tests passing"}'
# Retry failed task
curl -X PATCH http://localhost:4001/api/tasks/{task_id} \
-H "Content-Type: application/json" \
-d '{"action": "retry"}'Checkpoint & Resume:
# Save checkpoint
curl -X PATCH http://localhost:4001/api/tasks/{id}/checkpoint \
-H "Content-Type: application/json" \
-d '{"checkpoint_data": {"progress": 50, "artifacts": ["file1.md"]}}'
# Get checkpoint
curl http://localhost:4001/api/tasks/{id}/checkpoint
# Resume from checkpoint
curl -X POST http://localhost:4001/api/tasks/{id}/resumeUpdate agent:
curl -X PATCH http://localhost:4001/api/agents/{agent_id} \
-H "Content-Type: application/json" \
-d '{"status": "idle"}'Get Agent Card (A2A):
curl http://localhost:4001/api/agents/{agent_id}/card
# Returns: {agent_id, display_name, version, capabilities: {skills, max_concurrent_tasks}, status, endpoint}
curl http://localhost:4001/api/agents/cards
# Returns: {agents: [...]} for all registered agentsDelete agent (cannot delete if agent has active assigned/working tasks):
curl -X DELETE http://localhost:4001/api/agents/{agent_id}# All agents, limit 50
curl "http://localhost:4001/api/logs?limit=50"
# Filter by agent
curl "http://localhost:4001/api/logs?agent_id=coder"
# Search in log content
curl "http://localhost:4001/api/logs?search=error&limit=20"# Get recent scheduler decisions (why tasks were assigned/rejected)
curl "http://localhost:4001/api/scheduler/log?limit=50"# Send a message
curl -X POST http://localhost:4001/api/messages \
-H "Content-Type: application/json" \
-d '{
"from_agent": "coder",
"to_agent": "analyst",
"type": "request",
"priority": "normal",
"content": {"summary": "Analysis requested", "body": "Please analyze the performance data"},
"context_summary": "Completed profiling task, need analysis"
}'
# Get messages (optionally filtered)
curl "http://localhost:4001/api/messages?agent_id=coder&limit=20"
# Get messages since a timestamp
curl "http://localhost:4001/api/messages?since=2026-04-08T10:00:00"# Launch an agent process (interactive mode - opens Windows Terminal tab)
curl -X POST http://localhost:4001/api/agents/{agent_id}/launch?mode=interactive
# Launch an agent process (headless mode - runs assigned task in background)
curl -X POST http://localhost:4001/api/agents/{agent_id}/launch?mode=headless
# Terminate an agent process
curl -X DELETE http://localhost:4001/api/agents/{agent_id}/launch
# Get agent process status
curl http://localhost:4001/api/agents/{agent_id}/process
# List all agent processes
curl http://localhost:4001/api/processes# Natural language task decomposition - sends goal to orchestrator agent
curl -X POST http://localhost:4001/api/orchestrate \
-H "Content-Type: application/json" \
-d '{"goal": "Build a user authentication system"}'
# List available workflow templates
curl http://localhost:4001/api/workflows
# Run a workflow template (creates tasks from template)
curl -X POST http://localhost:4001/api/workflows/full-stack-feature/runcurl http://localhost:4001/api/metrics/agents
# Returns per-agent: total_tasks, completed_tasks, failed_tasks, timeouts, retries,
# avg_completion_time, last_success, token_usedThree-tier memory for agent context management:
# Save memory snapshot
curl -X POST http://localhost:4001/api/memory/snapshot \
-H "Content-Type: application/json" \
-d '{"tier": "hot", "content": "Discovered issue in module X"}'
# Retrieve memory
curl http://localhost:4001/api/memory/hot
curl http://localhost:4001/api/memory/diary
curl http://localhost:4001/api/memory/semantic- hot: Recent events in
hot.jsonl(append-only JSONL, auto-truncated to last 50 entries) - diary: Daily interaction log in
diary_YYYY-MM-DD.md - semantic: Long-term knowledge in
semantic.md(overwritten on update)
Trigger memory compaction (clears hot.jsonl and resets high context pressure agents):
curl -X POST http://localhost:4001/api/memory/compactcurl -X POST http://localhost:4001/api/broadcast \
-H "Content-Type: application/json" \
-d '{"message": "Please check the failing tests"}'# Instantly cancel ALL active tasks and set all agents offline
curl -X POST http://localhost:4001/api/emergency/stop
# Returns: {cancelled_tasks: [...], offline_agents: [...]}curl http://localhost:4001/api/health
# Returns: {status, workspace, plugins_loaded, connected_clients, uptime_seconds}Connect to ws://localhost:4001/ws for real-time state updates:
- Full state on connect
{"type": "ping"}every 30 seconds as keepalive{"type": "state_update", "data": {...}}on any state change
| Variable | Default | Description |
|---|---|---|
ORCHESTRA_WORKSPACE |
. |
Workspace directory containing .orchestra/ |
PORT |
4001 |
Backend server port |
The UI auto-detects your browser language (English or Chinese).
Force a specific language:
localStorage.setItem('orchestra-lang', 'zh') // Chinese
localStorage.setItem('orchestra-lang', 'en') // EnglishRetry: Tasks that fail can be retried up to 3 times (configurable via max_retries on each task). The retry_count increments on each retry attempt.
Timeout: Tasks in assigned or working status for more than 10 minutes are automatically marked error with message "Task timed out after 10 minutes".
Max Iterations: Each task has a constraints.max_iterations field (default 5). Exceeding it marks the task as error with "Max iterations exceeded".
Task Size Boundary: Tasks are validated on assignment:
- Under 50 chars description + under 20 chars title — rejected as too small
- Mentions "implement full" / "rewrite entire" / "migrate all" / "build complete" — flagged as potentially > 30 min
- Optimal task size: 5–30 minutes of work
Circuit Breaker: If an agent fails 3 consecutive times, it is skipped for 30 seconds while the circuit is "open", then retried once in half_open state. Success resets the circuit.
Context pressure is a proxy metric (0–100) indicating how "full" an agent's context is likely to be, computed from:
- Recent task count (last 10): +3 per task
- Total description length: +1 per 100 chars
- History entries: +2 per entry
The scheduler computes and updates context_pressure for each agent every cycle. When context_pressure exceeds 70, the agent is flagged for auto-compaction. The Stats tab and Agent Card display color-coded pressure bars (green <50, yellow 50–70, red >70).
Trigger compaction manually:
curl -X POST http://localhost:4001/api/memory/compactClick the Stats tab to see:
- Task overview: total vs completed today (with ring chart)
- Agent status distribution (with donut chart)
- Per-agent performance metrics: completed / failed / timeout / retry counts
- Average completion time and token usage per agent
- Context pressure indicator per agent
- Recent task list
| Shortcut | Action |
|---|---|
Ctrl+N |
Focus task input |
Ctrl+K |
Quick search |
Escape |
Close context menus and modals |
Ctrl+1/2/3 |
Switch Tasks/Stats/Messages tabs |
? |
Show shortcuts help panel |
cd frontend
npm install
npm run test # Run tests once
npm run test:watch # Watch mode
npm run coverage # With coverage report测试文件位于 frontend/src/__tests__/:
AgentCard.test.tsx- AgentCard 组件测试useOrchestra.test.ts- useOrchestra Hook 测试useNotifications.test.ts- 通知系统测试Terminal.test.tsx- Terminal 组件测试
当前状态:59/59 测试通过
cd backend
python -m pytest -q # 快速运行
python -m pytest --cov # 带覆盖率当前状态:845/845 测试通过