Skip to content

feat(orchestration): API keys, API profiles and agent-to-agent delegation - #64

Closed
BIackFIame wants to merge 2 commits into
howdeploy:mainfrom
BIackFIame:stack/2-orchestration
Closed

BIackFIame wants to merge 2 commits into
howdeploy:mainfrom
BIackFIame:stack/2-orchestration

Conversation

@BIackFIame

@BIackFIame BIackFIame commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Goal

Let agents delegate to other agents (including other vendors) through CanvasTTY, and give API-key based agents a safe place for keys and backend settings.

Behavior

  • Provider API keys are stored in the main process, encrypted with Electron safeStorage, in one atomically written file with size quotas. It fails closed when OS encryption is unavailable. The renderer only sees which keys exist.
  • API profiles name a model backend: protocol, HTTPS base URL, key reference and default model, with built-in presets. They are not agents and never appear in launchers.
  • Session hierarchy: sessions carry role and parentSessionId, and restore drops orphaned subagents. This also fixes assertCreateRequest rejecting the four new providers over IPC.
  • Capability descriptors state what CanvasTTY can really do with each agent, and a missing provider fails to compile.
  • Agent control (spawn, send, observe, result, cancel, children) works over ordinary terminal sessions.
  • Orchestration MCP reuses the agent-bridge design: an authenticated user-local socket, one-use bootstrap capabilities, rotated reconnect tokens, and scoping to the caller's own session subtree. MCP config is injected for Claude, Codex, OpenCode, Kimi and Hermes. Only orchestrator sessions receive it, and ordinary launches are unchanged.

Orchestration contract (maintainer's #32 review)

The maintainer's review of #32 lists requirements for an orchestration feature. This stack meets them as follows.

  • Role: the launch dialog has an explicit Orchestrator option (added in feat(routing): launch routing, reasoning effort, server preparation and sign-in #69) and keeps the provider fixed. Cards show Orchestrator or Subagent. The option is separate from normal/YOLO permissions and keeps the selected profile.
  • Ownership: an orchestrator sees and controls only its own subtree. Stale sessions are rejected, and an unrelated manual session is never owned by it.
Agent Orchestrator Subagent (worker) Lifecycle source Result / approvals
Claude, Codex, Qwen Yes (PTY + MCP) Yes Hooks Terminal
OpenCode Yes (PTY + MCP) Yes Structured events Terminal
Kimi Yes (PTY + MCP, ACP) Yes Hooks / ACP Terminal / ACP
Hermes Yes (PTY + MCP) Yes Hooks Terminal
Cursor, MiniMax Code Yes over ACP; no PTY adapter Yes Process / ACP Terminal / ACP
Grok, OMP, Pi No (no verified MCP adapter) Yes Hooks (Grok) / process Terminal
Devin, Antigravity No Yes Process Terminal

What is missing is stated plainly: Grok, OMP, Pi, Devin and Antigravity cannot be orchestrators yet, and a child's result is its terminal tail rather than a structured final answer.

Documentation

ADR: docs/adr/ADR-20260921-orchestration-mcp-rides-agent-bridge.md.

Verification

  • npm run typecheck passed. Full suite: 723/723; Even G2 companion tests (npm run test:even): 47/47.
  • Orchestration is covered by socket-level tests with fake agent processes.
  • Live, with real models, on the final state of the series (macOS, OpenCode on the Z.AI plan):
    • an orchestrator called spawn_agent; the child started as a Subagent, wrote sub.txt, and the orchestrator waited and recorded the child's id;
    • with two children, one finished its file task and the orchestrator stopped the other with cancel_agent ({"canceled":true}, gone from list_agents).
  • Not shown live: mixed-vendor delegation (only OpenCode is signed in on the test machine), approval prompts inside a child, and Linux or Windows desktops.

Series

Each part is one commit on top of the previous one. Please merge them in order. Until #63 is merged, GitHub also shows the earlier parts here; review only the top commit 9d4cb0b (Commits tab → last commit).

Part PR Scope Lines
1 #63 Providers: Cursor, MiniMax Code, Devin, Antigravity +579/−90
2 #64 API keys, API profiles, agent delegation (MCP) +4275/−63
3 #65 Remote servers, placement, privacy tiers, accounts +6620/−40
4 #66 Isolation: capsules, worktrees, containers +5508/−839
5 #67 ACP, connection settings, remote containers +6827/−563
6 #68 Project context and learning +6148/−370
7 #69 Routing, reasoning effort, server preparation, sign-in +3122/−467
8 #70 Open issues and safe fixes from open PRs +306/−58

Compatibility with open upstream PRs

integration/stack-with-open-prs is this whole stack with #54–#62 merged on top and every conflict resolved. On that branch both TypeScript checks, 1492/1492 tests, npm run test:even (47/47) and electron-vite build pass.

I will rebase this stack onto whichever of these lands first.

🤖 Generated with Claude Code

BIackFIame and others added 2 commits September 23, 2026 17:16
Provider CLI resolution is driven by declarative command definitions
instead of assuming the executable matches the provider id. MiniMax
Code (`mcode`), Antigravity (`agy`) and Cursor resolve through the same
registry, known install directories, recheck and install links that howdeploy#52
introduced. Cursor prefers `cursor-agent`; a generic `agent` is accepted
only when its real path is verified as Cursor, because Grok also
installs an `agent` executable.

Each new agent gets normal and resume launches where the CLI documents
them, its YOLO flag only where one exists, launcher entries with a
settings migration, its provider mark and session restore. MiniMax Code
has no permission-bypass flag, so its YOLO profile launches the stock
CLI and says so. Antigravity restores as a fresh session because it has
no resumable id that CanvasTTY can persist.

Provider ids, labels and launcher order live in a dependency-free
`providerCatalog.ts` that `contracts.ts` re-exports, so the Even G2
companion bundle stays free of URLs outside its network whitelist; its
phone launcher lists the new agents too.

Lifecycle hooks are prepared only for providers that have a hook adapter, so
the new agents never write Grok's shared hook configuration.

ADR: docs/adr/ADR-20260921-provider-cli-command-definitions.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tion

- Provider API keys are stored in the main process, encrypted with
  Electron safeStorage; the renderer only sees which keys exist.
- API profiles name a model backend (protocol, HTTPS base URL, key
  reference, default model) with built-in presets.
- Sessions carry role and parent metadata; restore drops orphaned
  subagents instead of resurrecting them.
- Per-provider capability descriptors state what CanvasTTY can really do
  with each agent, and agent control (spawn, send, observe, result,
  cancel, children) works over ordinary terminal sessions.
- An orchestration MCP surface rides the existing agent-bridge design:
  authenticated user-local socket, one-use bootstrap capabilities, scoping
  to the caller's own session subtree, and MCP injection for Claude,
  Codex, OpenCode, Kimi and Hermes. Only orchestrator sessions receive it;
  ordinary launches are unchanged.

ADR: docs/adr/ADR-20260921-orchestration-mcp-rides-agent-bridge.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@BIackFIame
BIackFIame force-pushed the stack/2-orchestration branch from 19efbac to 9d4cb0b Compare September 23, 2026 14:26
howdeploy added a commit that referenced this pull request Sep 24, 2026
@howdeploy

Copy link
Copy Markdown
Owner

Integrated into main via #73. Your authored orchestration commit and @claude co-author trailer are preserved in the merge history. Thank you, @BIackFIame.

@howdeploy howdeploy closed this Sep 24, 2026
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.

2 participants