Skip to content

Start orchestration workers as native chats for every agent that has native chat - #26776

Merged
brennanb2025 merged 3 commits into
mainfrom
brennanb2025/orchestration-native-chat-workers-all-agents
Oct 9, 2026
Merged

brennanb2025 merged 3 commits into
mainfrom
brennanb2025/orchestration-native-chat-workers-all-agents

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​51 $\color{#cf222e}{\Huge{\mathbf{−}}}$​33 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​18
Prod 7 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​13 $\color{#cf222e}{\Huge{\mathbf{−}}}$​24 $\color{#cf222e}{\Huge{\mathbf{−}}}$​11

ELI5

When you start an orchestration worker with OpenCode, Grok, OMP or Pi while native chat is on, it now opens as a native chat, the same as Claude and Codex workers do. Before, these four always fell back to a terminal, even though each of them already opens as a native chat everywhere else in Orca.

What Changed

The problem. With native chat on, orca orchestration worker-start --agent opencode (or grok, omp, pi) started a terminal worker instead of a chat. The start report blamed the agent: "this agent has no structured session". That is false: all four are registered for native chat and open as chats from the New tab menu. For OpenCode the terminal fallback was worse than a different look. The terminal sat at "Starting background server…" until Orca gave up waiting for the agent to be ready, so the worker never got its task.

Why it happened. Orchestration turned native chat off for these agents on purpose, in two places. The worker launch decision passed an empty list of extra native-chat agents (registeredStructuredAgents: []). The code that creates a native-chat worker refused anything other than Claude and Codex. The comment beside the empty list said workers would take the other agents "once structured workers take registered agents". The worker path itself never depended on Claude or Codex: creating the session, delivering the task as a chat message, waking the worker when mail arrives, reading its transcript and releasing it all go through code shared with every native chat.

User-facing change. With native chat on, an orchestration worker for any agent that has native chat (Claude, Codex, OpenCode, Grok, OMP, Pi) opens as a native chat tab. Agents without native chat (Gemini, for example) still start in a terminal, with the same receipt as before. With native chat off, every worker is a terminal, as before.

Mechanism.

  • Workers now use the same list of native-chat agents as every other launch. The per-surface option that let a caller narrow that list had no other users, so it is removed.
  • The Claude/Codex-only refusal in the worker factory is removed, and the worker's agent type is widened from 'claude' | 'codex' to any agent.
  • After an Orca restart, a worker's agent is read back from its saved chat session. That lookup used to turn any agent other than Codex into claude. That label is written permanently into the released worker's saved transcript, so a restarted OpenCode worker would have been archived as Claude. It now keeps the real agent.

Permissions. A native-chat worker asks for permission exactly as that agent's chat does, which is set by the Agent Permissions setting for that agent (the same setting that adds the bypass flag to its terminal launch). In QA, OMP was not on full access, so its worker showed a permission card for pwd and waited until someone approved it. A terminal OMP worker with the same setting asks too.

Why

The worker code already handled any agent, so the fix removes the gates rather than adding a separate path for these agents. Keeping the terminal fallback and only fixing OpenCode's readiness wait (open PRs #24115 and #20451 work on that) would leave these agents as terminal workers while their chats work everywhere else. A worker would then look and behave differently from the chat you get when you open the same agent yourself.

Linked Issue

None. Found while checking whether orchestration supports every native-chat agent.

Visual Proof

All "after" screenshots below come from a hidden dev Orca running this branch. Each worker was started with orca orchestration worker-start --agent <agent> and ran on its real CLI and my own login. Every worker opened as a native chat tab next to the coordinator's terminal tab.

There is no "before" screenshot. On main the same command starts a terminal worker, and its start receipt reads "Started a terminal agent worker … because this agent has no structured session".

OpenCode worker: ran pwd, then sent worker_done itself through orca-dev orchestration send.
opencode-bottom.png

Grok worker: ran pwd and orchestration check, then sent worker_done.
grok-bottom.png

OMP worker, not on full access: it waits on a permission card for pwd, as an OMP chat does.
omp-state.png

OMP worker after "Allow once" on its two requests: it finished and sent worker_done.
omp-done.png

Testing

  • I manually tested these changes locally
  • Automated tests added/updated, or explained why not below

Manual, macOS: a hidden dev build of this branch with an isolated profile, and the real OpenCode 2.0.14, Grok 1.0.50 and OMP 17.0.5 CLIs. For each agent:

  • worker-start returned mode: structured, and the requested and actual agent matched.
  • The task arrived as a chat message.
  • The worker sent worker_done, and the dispatch settled as completed / succeeded. Times: OpenCode 19 s, Grok 37 s, OMP after its permission requests were approved.
  • worker-release succeeded. worker-read afterwards returned the saved transcript with the right agent (opencode, grok, omp).

Not run live:

  • Pi, which isn't installed here; it is covered by the unit tests.
  • An Orca restart between start and release; the restored-agent label is covered by unit tests.
  • Linux, Windows and SSH. Nothing platform-specific changed. Workers placed with --on still go through federation as terminal workers, and remote or WSL workspaces still fall back through the host's native-chat support check, both unchanged.

Automated:

  • orchestration-worker-start-registered-agent.test.ts now checks that every registered native-chat agent starts as a native-chat worker. It also checks that the host can still turn one into a terminal, that an agent without native chat stays a terminal, and that native chat off means a terminal.
  • structured-worker-authority.test.ts checks that a restored OpenCode, Grok, OMP or Pi worker keeps its own agent.
  • 281 orchestration and worker test files pass, pnpm tc:node passes, and orca-ci-checks passes (22 of 22).

Review

Not yet reviewed.

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • Security: no change. Permission prompts follow each agent's existing Agent Permissions setting.
  • Platforms: no platform-specific code.
  • SSH and remote: remote placements are unchanged, as described under Testing.
  • Mobile: nothing on the wire changes.
  • Older peers: a worker's start receipt can now say "structured" for these agents. Receipts already carry that value for Claude and Codex.
  • Performance: none.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

@brennanb2025

Copy link
Copy Markdown
Contributor Author

Review and QA summary (head 7d5650d)

The problem. With native chat on, orca orchestration worker-start --agent opencode (or grok, omp, pi) started a terminal worker instead of a chat, and the start receipt wrongly said the agent "has no structured session". All four already open as native chats everywhere else in Orca. For OpenCode the terminal worker also hung at "Starting background server…" and never received its task. Two hard-coded Claude/Codex-only checks on the worker path caused this.

What changes for you. With native chat on, a worker for any agent that has native chat (Claude, Codex, OpenCode, Grok, OMP, Pi) opens as a chat tab beside the coordinator. Agents without native chat still start in a terminal. With native chat off, every worker is a terminal, as before. After an Orca restart, a worker keeps its real agent name (it no longer turns into "claude") in worker-show, in worker-read, and in the saved transcript written when the worker is released.

Review. One adversarial review round looked at three areas: the per-agent worker path, restart and remote placement, and the overall design. A separate reviewer then ran the readiness checklist on the final diff. Neither found any P0, P1 or P2 issues.

  • The design removes the per-agent block outright instead of adding a parallel path. Workers now use the same list of native-chat agents, and the same host support check, as every other chat launch. Splitting the PR doesn't work: removing the block without the restart-label fix would save restarted workers as Claude, and the label fix does nothing on its own.
  • SSH and WSL workspaces, workers placed with --on, and Windows hosts that can't read process start times all still start terminal workers. Pi below its minimum version falls back to a terminal (confirmed in QA).
  • Permissions follow each agent's existing Agent Permissions setting. Nothing persisted or sent over the wire changes shape, and no mobile surface is touched.

Fixed during review

  • (P3) The comment on the restored-worker fallback claimed only an unreadable record could reach it. It now also says that a provider this build doesn't recognise falls back to Claude. Comment only, no behaviour change (7d5650d).

Deferred (P3, already present before this PR)

  • --model and --effort are still checked against each agent's terminal launch options before Orca knows the worker will be a chat. So Grok and Pi refuse --model, and OpenCode refuses --effort, even though their chats offer a model choice. Terminal workers for these agents behave the same way today.
  • If an agent can't reload a saved session, its worker comes back as a fresh chat after an app restart, or after Orca stops it for being idle once its task is done. The next mail then reaches a worker that has lost its earlier context. Whether this happens depends on the agent. OpenCode kept its context across a restart in QA.

Verified

  • CI is green on 7d5650d. pnpm tc:node passes, the targeted tests pass, and the static analysis checks pass (22 of 22).
  • Live QA on a second Mac ran a hidden dev build of 7d5650d, with the real OpenCode 2.0.21 and Pi 0.73.1 CLIs talking to a local scripted model.
    • OpenCode worker: started as a native chat (receipt mode: structured), received the task as a chat message, ran pwd and sent worker_done. The dispatch completed. After release, worker-read returned the transcript labelled opencode.
    • Restart between start and release: after a quit and relaunch on the same profile, the worker's chat tab and transcript came back with no extra notice. worker-show and worker-read reported opencode. Mail woke the restored chat, it finished with its context intact, and the saved transcript after release was labelled opencode.
    • Controls: an agent without native chat still started in a terminal. With native chat off, --agent opencode started in a terminal.
    • Pi 0.73.1: below Orca's native-chat minimum, so it correctly fell back to a terminal worker and completed.

OpenCode worker, native chat:
a1-opencode-bottom.png

After an Orca restart, the worker's chat tab is restored:
b0-after-restart.png

The restored worker is woken by mail and finishes:
c1-after-mail.png

Pi below its native-chat minimum falls back to a terminal worker:
a2-pi.png

Not verified

  • A Pi worker as a native chat: no Pi at version 0.84.0 or later was available, so this is covered only by unit tests.
  • Grok and OMP in this round (Grok was not run, to keep it out of the real Grok home). The earlier laptop QA in the PR body covers both.
  • Real model accounts in this round: a scripted local model was used.
  • Windows, Linux, WSL and SSH, live. These paths are unchanged and were confirmed by code reading only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant