ResearchAgent OrchestrationMulti Agent Collaboration

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 / idle state 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.create is 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 carries agent, provider, and codename per session.
  • session.send (inject the task brief into a worker's PTY) and events (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 / idle model that the Capsule already derives and that the agent runtime status authority makes reliable. The done-vs-idle split 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).

StateGlyphColor tokenMeaning
workingPHOSPHOR_GREENoutput flowing or foreground process running
doneWHITE on CAPSULE_MENU_AWAITING_BGfinished, awaiting operator review (not reaped)
blockedSTATUS_BLOCKED_REDsilent with a foreground process — needs input
idle·PHOSPHOR_DIMreviewed or no work in progress
orchestratorWHITE boldthe planner node, always visually distinct
selected node cursorPHOSPHOR_GREENfollows 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 workers

Interaction 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 is PHOSPHOR_GREEN when the tab bar owns focus and WHITE when content does.
  • Inside Conductor: / move the node and row cursor , enter attaches to that agent's tab, Esc / BackTab returns focus to the tab bar.
  • The prefix model is unchanged; the multiplexer command prefix (⌃B, or JACKIN_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.model come from the in-container agent registry plus the per-agent model overrides in agent.toml.
  • The node state glyph comes from the existing working / blocked / done / idle derivation 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.collect MCP calls and the events stream — the only genuinely new data the view needs.

Open design questions

  1. Plan format. Does the planner emit a structured task list through a jackin.delegate tool 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.
  2. 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.
  3. Worker isolation. Same container and shared workspace (fast, but file-collision risk), one worker per worktree or clone mount (the per-mount isolation already supports this), or separate instances? The per-mount clone mode is the natural safe default.
  4. 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.

On this page