Agent-to-agent collaboration (Conductor view)
An orchestrator-workers topology made visible inside the Capsule multiplexer: an expensive planner agent decomposes a task and delegates it to cheap worker agents, with every delegation, status change, and message rendered in a dedicated Conductor layout mode.
Status: Open — research and design proposal
Problem
jackin❯ already runs many agents in parallel, each in its own visible, attachable Capsule pane, but those agents are isolated islands. There is no supported way for one agent to hand work to another, and no way for the operator to watch a multi-agent collaboration unfold. Operators who want the obvious high-value pattern — let an expensive, high-reasoning model produce a detailed plan, then delegate the bounded implementation work to cheaper, faster agents — have to do the routing by hand: copy the plan out of one tab, paste task slices into other tabs, poll each tab to see whether it finished, and stitch the results back together themselves. That manual relay is exactly the coordination overhead that makes parallel agents feel like more work instead of more throughput.
Every general orchestrator that solves this (Conductor, Emdash, Optio, and the projects surveyed in agent workflow orchestration) hides the "manager" in a background process. The operator sees a task board or a diff, not the manager agent thinking and delegating. jackin❯ has a property none of them can bolt on after the fact: the Capsule multiplexer already owns every agent's PTY, already tracks per-session working / blocked / done / idle state, and already records each session's agent, provider, and codename. The manager does not have to be invisible. It can be a pane the operator watches, attaches to, and hijacks at any moment.
Why it matters
This is the feature that turns jackin❯ from "a safe place to run one agent at a time" into "a visible control room for a small team of agents." It is uniquely enabled by the Capsule-first architecture, it composes directly with several already-shipping building blocks, and it answers the operator's most-requested workflow — plan expensive, implement cheap — without inventing a new runtime.
- Hybrid cost routing across agents, not just inside one. The planner runs the frontier model (for example a high-reasoning Claude model) once, on the hard part — decomposition and review. Workers run the cheap providers jackin❯ already supports through alternative LLM providers (Z.AI GLM, Kimi, MiniMax) or a future local model engine on the bounded, well-specified subtasks. This is the industry's emerging hybrid-routing pattern applied at the agent level.
- Visible by construction. The planner and every worker are real Capsule panes. Nothing runs in a hidden loop the operator cannot inspect. This preserves the core jackin❯ promise that every agent session stays visible, attachable, and hijackable.
- Mostly reuse, little new. The control plane, the
working/blocked/done/idlestate model, the per-session agent/provider/codename registry, the MCP auto-registration pattern, and the multiplexer renderer all exist today. The genuinely new pieces are narrow and are already named as needed work elsewhere in the roadmap. - No host mutation. All spawning and messaging happens inside the container over the Capsule control socket at
/jackin/run/jackin.sock; the planner cannot touch the host. A blocked worker that needs a host secret routes through the existing host bridge approval flow, so the operator stays in control of every privileged action.
Topology: one expensive planner, N cheap workers
The collaboration is the classic orchestrator-workers shape. One orchestrator agent owns the plan and the integration; several worker agents own one bounded subtask each.
╭──────────────────────────────────────╮
│ ★ ORCHESTRATOR (Tab 0) │
│ high-reasoning frontier model │
│ · reads the task │
│ · produces a structured PLAN │
│ · delegates + reviews + integrates │
╰─────────────────┬────────────────────╯
delegate(task) │ result + status
╭──────────┬───────────┬┴─────────┬──────────╮
▼ ▼ ▼ ▼ ▼
╭─────────╮╭─────────╮ ╭─────────╮ ╭─────────╮╭─────────╮
│worker A ││worker B │ │worker C │ │ ... ││ │
│GLM/Kimi ││ Codex │ │ local │ │ cheap ││ │
│⟳ working││⏸ blocked│ │ ✓ done │ │ models ││ │
╰─────────╯╰─────────╯ ╰─────────╯ ╰─────────╯╰─────────╯
╰──── all are visible Capsule panes, attachable & hijackable ────╯The orchestrator spends the expensive reasoning budget once, on the part that benefits most from it — breaking a large task into independent, well-specified pieces and reviewing the results. The workers each consume a single piece with a cheaper, faster, or local model. Because the workers are sandboxed Capsule panes, a worker that misbehaves cannot corrupt the others' state, and the operator can drop into any worker at any time.
The communication substrate
The orchestrator does not shell out to the workers and does not share mutable state with them through a filesystem. It talks through an auto-registered MCP server inside the container — the same auto-registration pattern the Capsule already uses for the Claude runtime's tirith / shellfirm tools and reused by the host bridge. That MCP server is a thin client of the existing Capsule control socket at /jackin/run/jackin.sock.
ORCHESTRATOR ──MCP tool call──▶ jackin-orchestrate MCP server
jackin.delegate(task, model) │ (in-container; speaks the control protocol)
jackin.await(worker_ids) ▼
jackin.collect(worker_id) ╭───────────────────────────╮
│ CAPSULE control plane │
│ session.create ← spawn │
│ session.send ← inject │ task brief into worker PTY
│ events → status │ working → done stream
│ session.read ← result │
╰───────────────────────────╯How each piece maps to what exists today:
session.createis already named in the Capsule control-protocol design as a Phase 3 method; it spawns a worker tab with a chosen agent and provider/model. The session registry already carriesagent,provider, andcodenameper session.session.send(inject the task brief into a worker's PTY) andevents(a state-change stream) are the two genuinely new control-plane pieces. Both are already named as needed work in terminal observation and automation and in the agent workflow orchestration control-surface section. Agent-to-agent collaboration is the feature that justifies building them.- Status comes from the
working/blocked/done/idlemodel that the Capsule already derives and that the agent runtime status authority makes reliable. Thedone-vs-idlesplit already exists so a finished worker is not reaped before its result is collected. - Codenames come from agent codenames: every worker already gets a stable, never-reused
JACKIN_AGENT_CODENAME, so the orchestrator can address "falcon, take task 1" and the operator can read the same handle on screen.
Lifecycle
End to end, one collaboration runs as a single loop the operator watches from the Conductor tab — plan once with the expensive model, fan out to cheap workers, collect, review, and gate at a pull request:
operator states the goal in Tab 0
│
▼
ORCHESTRATOR (frontier model, high reasoning) ── emits a structured PLAN (task list)
│ calls jackin.delegate(task, cheap_model) per task
▼
CAPSULE session.create worker ──▶ session.send(task brief + plan slice)
│
▼
WORKERS run in parallel (cheap / local models) ── status: working → done | blocked
│ blocked? ──▶ surfaces on the board + (optionally) a host-bridge secret request
▼
CAPSULE events: worker done ──▶ jackin.collect returns the result to the ORCHESTRATOR
│
▼
ORCHESTRATOR reviews each result ── integrates / re-delegates / asks the operator
│
▼
operator gate ──▶ PR (ties into workspace-native PR verification)Visual design: the Conductor view
The collaboration is rendered in a new Capsule layout mode — Conductor view — that follows the existing capsule chrome, the PHOSPHOR palette, and the W3C ARIA tab navigation. It is a pinned, always-first ◆ Conductor tab in the existing tab strip, toggleable from the command palette (for example a prefix o binding). The per-agent tabs are unchanged (one PTY each); the Conductor tab is a composited overview of all of them plus the delegation state. Selecting a node and pressing enter jumps to that agent's real tab (attach and hijack), so Conductor is the map and the per-agent tabs are the territory.
Compact form
At a small terminal size, Conductor collapses to a single tiled panel: the plan on the left, the orchestrator and any blocked worker called out on the right, and the live worker tiles below. The bottom rail doubles as a legend and the attach hint.
╭ jackin❯ the-architect ──────────────────── [Conductor] ⌃B ? ╮
│ ╭─ PLAN ────────────────────────────╮ ╭─ orchestrator (opus) ─╮│
│ │ 1 ✓ scaffold module falcon │ │ ▸ decomposed into 5 ││
│ │ 2 ⟳ wire config osprey │ │ tasks. delegating... ││
│ │ 3 ⟳ migration + fixtures heron │ │ ▸ awaiting 2,3,4 ││
│ │ 4 ⏸ blocked: needs token raven │ │ ││
│ │ 5 · docs sweep — │ ╰────────────────────────╯│
│ ╰───────────────────────────────────╯ ╭─ raven (blocked) ──────╮│
│ ╭─ osprey (GLM, working) ───────────╮ │ needs JACKIN token to ││
│ │ editing config/migrations.rs... │ │ run jackin role migrate││
│ ╰───────────────────────────────────╯ ╰────────────────────────╯│
╰ falcon ✓done osprey ⟳ heron ⟳ raven ⏸ · [enter] attach ────╯Layout anatomy
At full width the panel splits into four regions inside the Conductor tab:
row0 jackin❯ ┃ ◆ Conductor ┃ 1 opus ┃ 2 falcon ┃ 3 osprey ┃ + the-architect
╭──────────────┬──────────────────────────────────────────────────────────╮
│ PLAN BOARD │ DELEGATION GRAPH │
│ (left rail) │ orchestrator hub ──▶ worker nodes, live edges │
│ ├──────────────────────────────────────────────────────────┤
│ tasks bound │ WORKER ROSTER │
│ to workers │ compact card per agent: who / model / state / doing │
│ + status ├──────────────────────────────────────────────────────────┤
│ │ MESSAGE TICKER ── who said what to whom, newest on top │
╰──────────────┴──────────────────────────────────────────────────────────╯
bot │ ⟳ working ✓ done ⏸ blocked · idle feature/refactor-auth-layer ⌃B ? │
╰─────────────────────────────────────────────────────────────────────────╯The overview
The four regions each answer one operator question: what is being built and by whom (plan board), who is communicating with whom (delegation graph), what each agent is doing right now (roster), and the running conversation log (message ticker).
┌ jackin❯ ┃ ◆ Conductor ┃ 1 opus ┃ 2 falcon ┃ 3 osprey ┃ 4 heron ┃ + ─────────────┐
│ ━━━━━━━━━━━ │
│ ┌ Plan ──────────────┐ ┌ Delegation ──────────────────────────────────────┐ │
│ │ ◆ refactor auth │ │ ╭─────────────╮ │ │
│ │ layer (5 tasks) │ │ │ ★ orchestratr│ opus·hi-reason │ │
│ │ │ │ │ ⟳ planning │ │ │
│ │ 1 ✓ scaffold falcon│ │ ╰──┬───┬───┬────╯ │ │
│ │ 2 ⟳ config osprey│ │ delegate ▸▸▸ │ │ │ ◂◂◂ result │ │
│ │ 3 ⟳ migrate heron │ │ ╭────────╯ │ ╰────────╮ │ │
│ │ 4 ⏸ tokens raven │ │ ▼ ▼ ▼ │ │
│ │ 5 · docs — │ │ ╭────────╮ ╭────────╮ ╭────────╮ │ │
│ │ │ │ │ osprey ⟳│ │ heron ⟳ │ │ raven ⏸ │ │ │
│ │ progress ▰▰▰▱▱ 2/5 │ │ ╰────────╯ ╰────────╯ ╰───┬────╯ │ │
│ │ │ │ ⚠ wants host secret│ │
│ └─────────────────────┘ └──────────────────────────────────────────────────┘ │
│ ┌ Roster ──────────────────────────────────────────────────────────────────┐ │
│ │ ★ orchestrator claude·opus ⟳ working · decomposed → delegating 2,3,4 │ │
│ │ falcon codex·gpt ✓ done · scaffolded module, 0 errors │ │
│ │ ▸ osprey opencode·GLM ⟳ working · editing config/migrations.rs │ │
│ │ heron kimi·k2 ⟳ working · writing migration + fixtures │ │
│ │ raven codex·GLM ⏸ blocked · needs JACKIN token for migrate │ │
│ └────────────────────────────────────────────────────────────────────────────┘ │
│ ┌ Messages ─────────────────────────────────────────────────────────────────┐ │
│ │ 14:02:11 orchestrator ▸ heron task 3 "migration + fixtures for v1a8" │ │
│ │ 14:02:09 orchestrator ▸ osprey task 2 "wire [docker.grants] into config" │ │
│ │ 14:01:58 falcon ◂ done "module scaffolded, 4 files, cargo ok" │ │
│ │ 14:01:40 orchestrator ▸ falcon task 1 "scaffold profile module" │ │
│ └────────────────────────────────────────────────────────────────────────────┘ │
│ ⟳ working ✓ done ⏸ blocked · idle feature/refactor-auth-layer ⌃B ? │
└───────────────────────────────────────────────────────────────────────────────────┘Status glyphs and colors
Every glyph reuses the four-state model the Capsule already derives, mapped to existing palette tokens (no new state machine, no new colors).
| State | Glyph | Color token | Meaning |
|---|---|---|---|
| working | ⟳ | PHOSPHOR_GREEN | output flowing or foreground process running |
| done | ✓ | WHITE on CAPSULE_MENU_AWAITING_BG | finished, awaiting operator review (not reaped) |
| blocked | ⏸ | STATUS_BLOCKED_RED | silent with a foreground process — needs input |
| idle | · | PHOSPHOR_DIM | reviewed or no work in progress |
| orchestrator | ★ | WHITE bold | the planner node, always visually distinct |
| selected node | ▸ cursor | PHOSPHOR_GREEN | follows the ARIA selection cursor rules |
How communication is animated
The edge between two nodes is the visible channel. It has resting and active forms so the operator can see a message move:
idle edge │ PHOSPHOR_DARK, thin ╶╶╶╶╶╶
delegate (down) │ orchestrator ▸ worker, GREEN ▸▸▸▸▸▸ (pulse travels down)
result (up) │ worker ◂ orchestrator, GREEN ◂◂◂◂◂◂ (pulse travels up)
blocked escalate │ worker ⚠ operator, RED ⚠╴╴╴╴ (edge to the ⚠ glyph)When jackin.delegate(task, model) fires, the matching edge pulses ▸▸▸ downward for roughly 600 ms and a line lands at the top of the message ticker. When a worker's state flips to done and jackin.collect returns, the edge pulses ◂◂◂ upward and the plan row's glyph flips to ✓. A blocked worker grows the ⚠ "wants host secret" tag and, if it is a real host-bridge request, the existing approval prompt surfaces through the host bridge — the Conductor view shows why the agent is stuck. Animation timing honors the reduced-motion flag already used by the launch progress TUI.
Per-worker card (the drill-in target)
Hovering or selecting a worker expands its roster line into a card; enter attaches to its real PTY (hijackable, per the visible-session rule). The focused card border uses CAPSULE_PANE_FOCUSED.
┌ osprey ─────────────────────────── opencode · GLM-4.6 ┐ border = CAPSULE_PANE_FOCUSED
│ ⟳ working · 00:01:23 · task 2 "wire [docker.grants]" │ when this node is selected
│ ──────────────────────────────────────────────────────│
│ editing crates/jackin-config/src/docker.rs │ ← live tail of the worker PTY
│ + added GrantSet, CapabilityGrant, ResourceBudget │ (last N rows of its grid)
│ running cargo check -p jackin-config … │
│ ──────────────────────────────────────────────────────│
│ [enter] attach & hijack [r] re-delegate [k] kill │ hints, WHITE keys
└────────────────────────────────────────────────────────┘State variants
A blocked worker turns its node and plan row STATUS_BLOCKED_RED, sprouts the ⚠ escalation glyph, and explains itself in the ticker:
│ 4 ⏸ tokens raven │ ╭────────╮
│ │ │ raven ⏸│ ⚠ blocked 0:42 — needs JACKIN token
│ ⚠ 1 agent waiting │ ╰───┬────╯ to run `jackin role migrate`
⚠╴╴╴▸ host-bridge: approve secret? [biometric/polkit]When every task reaches done, the orchestrator flips to done and Conductor surfaces the integration gate, which ties into workspace-native PR verification:
│ progress ▰▰▰▰▰ 5/5 │ ★ orchestrator ✓ done · "5/5 integrated, branch ready"
│ ✓ ready for review │ [enter] review diff [P] open PR [x] eject workersInteraction model
The Conductor view adds no global keys that bypass the prefix model, and it follows the existing tab and focus conventions:
- ARIA tabs:
←/→cycle tabs; the active-tab underline━isPHOSPHOR_GREENwhen the tab bar owns focus andWHITEwhen content does. - Inside Conductor:
↑/↓move the node and row cursor▸,enterattaches to that agent's tab,Esc/BackTabreturns focus to the tab bar. - The prefix model is unchanged; the multiplexer command prefix (
⌃B, orJACKIN_PREFIX) still gates multiplexer commands, Conductor adds no global keys that bypass it, and the branch/PR context bar stays pinned at the bottom exactly as today.
How it maps to real data
Every value in these mockups is already available or already named as in-flight work, so the view is not faked:
- Node identity and
agent.modelcome from the in-container agent registry plus the per-agent model overrides inagent.toml. - The node state glyph comes from the existing
working/blocked/done/idlederivation and the agent runtime status authority. - The roster activity line comes from the per-pane label and PTY title already tracked in the snapshot.
- The edges and message ticker come from the new
jackin.delegate/jackin.collectMCP calls and theeventsstream — the only genuinely new data the view needs.
Open design questions
- Plan format. Does the planner emit a structured task list through a
jackin.delegatetool call (clean and parseable) or do we parse a markdown task list from its visible output (works with any agent, fuzzier)? Start with the MCP tool. - Result hand-back. Inject the worker's summary into the planner's PTY (simple, but pollutes the planner's context) or return it as the async MCP tool result (cleaner)? Lean toward the async result.
- Worker isolation. Same container and shared workspace (fast, but file-collision risk), one worker per
worktreeorclonemount (the per-mount isolation already supports this), or separate instances? The per-mountclonemode is the natural safe default. - Failure and loop control. A per-worker budget cap and a maximum re-delegation count so the planner cannot spin cheap workers indefinitely. This pairs with the budget-enforcement idea tracked in the brainstorm backlog.
Relationship to other roadmap items
This item is the visible, opinionated orchestrator-workers product built on the substrate that agent workflow orchestration is designing. That item owns the durable run/event spine and the question of whether to build a native runner or adopt an external orchestrator; this item owns the specific planner-delegates-to-workers topology and its in-multiplexer Conductor visualization. It consumes the agent runtime status authority, agent codenames, the host bridge, and the control-surface primitives named in terminal observation and automation, and it feeds workspace-native PR verification when the integrated branch is ready.
Related Files
crates/jackin-protocol/src/control.rs— the shared control-channel protocol the newsession.create/session.send/eventsmethods extend.crates/jackin-capsule/src/session.rs— where theworking/blocked/done/idlestate is derived per session.crates/jackin-capsule/src/runtime_setup.rs— the MCP auto-registration pattern thejackin-orchestrateMCP server would extend.crates/jackin-capsule/src/tui/components/chrome.rs— top chrome (brand pill, tab strip) the Conductor tab plugs into.crates/jackin-capsule/src/tui/components/status_bar.rs— shared status-bar tab rendering.crates/jackin-capsule/src/tui/components/pane.rs— pane rendering reused by the roster cards and drill-in.crates/jackin-capsule/src/tui/components/palette.rs— command palette that gains the Conductor toggle.crates/jackin-tui/src/theme.rs— palette tokens (PHOSPHOR_*,STATUS_BLOCKED_RED,CAPSULE_PANE_FOCUSED,CAPSULE_MENU_AWAITING_BG) the view consumes.