@elizaos/plugin-agent-orchestrator 2.0.0-beta.1 → 2.0.3-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/CHANGELOG.md +6 -8
  2. package/README.md +102 -30
  3. package/docs/SUBAGENT_FLOW_AND_PARITY.md +138 -0
  4. package/docs/default-eliza-skills-and-agent-bridge-plan.md +9 -15
  5. package/docs/economics-goal-runbook.md +140 -0
  6. package/docs/multi-account-orchestration.md +76 -0
  7. package/docs/orchestrator-buildout-followups.md +124 -0
  8. package/docs/orchestrator-dashboard-task-widget-secrets-assessment.md +174 -0
  9. package/docs/orchestrator-dashboard-task-widget-secrets-design.md +301 -0
  10. package/docs/research/orchestrator-view-research-report.md +273 -0
  11. package/docs/sub-agent-routing.md +53 -23
  12. package/package.json +108 -25
  13. package/PROJECT.md +0 -119
  14. package/dist/browser/index.browser.js +0 -21051
  15. package/dist/browser/index.browser.js.map +0 -29
  16. package/dist/browser/index.d.ts +0 -2
  17. package/dist/cjs/index.d.ts +0 -2
  18. package/dist/cjs/index.node.cjs +0 -20491
  19. package/dist/cjs/index.node.js.map +0 -72
  20. package/dist/index.d.ts +0 -2
  21. package/dist/node/index.browser.d.ts +0 -3
  22. package/dist/node/index.browser.d.ts.map +0 -1
  23. package/dist/node/index.d.ts +0 -2
  24. package/dist/node/index.d.ts.map +0 -1
  25. package/dist/node/index.node.d.ts +0 -4
  26. package/dist/node/index.node.d.ts.map +0 -1
  27. package/dist/node/index.node.js +0 -20471
  28. package/dist/node/index.node.js.map +0 -72
  29. package/dist/node/src/actions/cancel-task.d.ts +0 -3
  30. package/dist/node/src/actions/cancel-task.d.ts.map +0 -1
  31. package/dist/node/src/actions/coding-task-handlers.d.ts +0 -69
  32. package/dist/node/src/actions/coding-task-handlers.d.ts.map +0 -1
  33. package/dist/node/src/actions/coding-task-helpers.d.ts +0 -35
  34. package/dist/node/src/actions/coding-task-helpers.d.ts.map +0 -1
  35. package/dist/node/src/actions/common.d.ts +0 -56
  36. package/dist/node/src/actions/common.d.ts.map +0 -1
  37. package/dist/node/src/actions/create-task.d.ts +0 -8
  38. package/dist/node/src/actions/create-task.d.ts.map +0 -1
  39. package/dist/node/src/actions/eval-metadata.d.ts +0 -11
  40. package/dist/node/src/actions/eval-metadata.d.ts.map +0 -1
  41. package/dist/node/src/actions/finalize-workspace.d.ts +0 -11
  42. package/dist/node/src/actions/finalize-workspace.d.ts.map +0 -1
  43. package/dist/node/src/actions/list-agents.d.ts +0 -4
  44. package/dist/node/src/actions/list-agents.d.ts.map +0 -1
  45. package/dist/node/src/actions/manage-issues.d.ts +0 -11
  46. package/dist/node/src/actions/manage-issues.d.ts.map +0 -1
  47. package/dist/node/src/actions/provision-workspace.d.ts +0 -11
  48. package/dist/node/src/actions/provision-workspace.d.ts.map +0 -1
  49. package/dist/node/src/actions/sandbox-stub.d.ts +0 -21
  50. package/dist/node/src/actions/sandbox-stub.d.ts.map +0 -1
  51. package/dist/node/src/actions/send-to-agent.d.ts +0 -4
  52. package/dist/node/src/actions/send-to-agent.d.ts.map +0 -1
  53. package/dist/node/src/actions/spawn-agent.d.ts +0 -8
  54. package/dist/node/src/actions/spawn-agent.d.ts.map +0 -1
  55. package/dist/node/src/actions/stop-agent.d.ts +0 -4
  56. package/dist/node/src/actions/stop-agent.d.ts.map +0 -1
  57. package/dist/node/src/actions/task-control.d.ts +0 -3
  58. package/dist/node/src/actions/task-control.d.ts.map +0 -1
  59. package/dist/node/src/actions/task-history.d.ts +0 -3
  60. package/dist/node/src/actions/task-history.d.ts.map +0 -1
  61. package/dist/node/src/actions/task-share.d.ts +0 -3
  62. package/dist/node/src/actions/task-share.d.ts.map +0 -1
  63. package/dist/node/src/actions/task-thread-target.d.ts +0 -11
  64. package/dist/node/src/actions/task-thread-target.d.ts.map +0 -1
  65. package/dist/node/src/actions/tasks.d.ts +0 -88
  66. package/dist/node/src/actions/tasks.d.ts.map +0 -1
  67. package/dist/node/src/api/agent-routes.d.ts +0 -18
  68. package/dist/node/src/api/agent-routes.d.ts.map +0 -1
  69. package/dist/node/src/api/bridge-routes.d.ts +0 -32
  70. package/dist/node/src/api/bridge-routes.d.ts.map +0 -1
  71. package/dist/node/src/api/coordinator-routes.d.ts +0 -22
  72. package/dist/node/src/api/coordinator-routes.d.ts.map +0 -1
  73. package/dist/node/src/api/hook-routes.d.ts +0 -18
  74. package/dist/node/src/api/hook-routes.d.ts.map +0 -1
  75. package/dist/node/src/api/issue-routes.d.ts +0 -17
  76. package/dist/node/src/api/issue-routes.d.ts.map +0 -1
  77. package/dist/node/src/api/parent-context-routes.d.ts +0 -17
  78. package/dist/node/src/api/parent-context-routes.d.ts.map +0 -1
  79. package/dist/node/src/api/route-utils.d.ts +0 -18
  80. package/dist/node/src/api/route-utils.d.ts.map +0 -1
  81. package/dist/node/src/api/routes.d.ts +0 -23
  82. package/dist/node/src/api/routes.d.ts.map +0 -1
  83. package/dist/node/src/api/workspace-routes.d.ts +0 -17
  84. package/dist/node/src/api/workspace-routes.d.ts.map +0 -1
  85. package/dist/node/src/index.d.ts +0 -32
  86. package/dist/node/src/index.d.ts.map +0 -1
  87. package/dist/node/src/providers/action-examples.d.ts +0 -14
  88. package/dist/node/src/providers/action-examples.d.ts.map +0 -1
  89. package/dist/node/src/providers/active-sub-agents.d.ts +0 -15
  90. package/dist/node/src/providers/active-sub-agents.d.ts.map +0 -1
  91. package/dist/node/src/providers/active-workspace-context.d.ts +0 -13
  92. package/dist/node/src/providers/active-workspace-context.d.ts.map +0 -1
  93. package/dist/node/src/providers/available-agents.d.ts +0 -4
  94. package/dist/node/src/providers/available-agents.d.ts.map +0 -1
  95. package/dist/node/src/register-routes.d.ts +0 -11
  96. package/dist/node/src/register-routes.d.ts.map +0 -1
  97. package/dist/node/src/routes/coding-agents-fallback-routes.d.ts +0 -19
  98. package/dist/node/src/routes/coding-agents-fallback-routes.d.ts.map +0 -1
  99. package/dist/node/src/services/acp-service.d.ts +0 -61
  100. package/dist/node/src/services/acp-service.d.ts.map +0 -1
  101. package/dist/node/src/services/acpx-subprocess.d.ts +0 -3
  102. package/dist/node/src/services/acpx-subprocess.d.ts.map +0 -1
  103. package/dist/node/src/services/agent-credentials.d.ts +0 -23
  104. package/dist/node/src/services/agent-credentials.d.ts.map +0 -1
  105. package/dist/node/src/services/agent-metrics.d.ts +0 -30
  106. package/dist/node/src/services/agent-metrics.d.ts.map +0 -1
  107. package/dist/node/src/services/agent-selection.d.ts +0 -53
  108. package/dist/node/src/services/agent-selection.d.ts.map +0 -1
  109. package/dist/node/src/services/ansi-utils.d.ts +0 -64
  110. package/dist/node/src/services/ansi-utils.d.ts.map +0 -1
  111. package/dist/node/src/services/claude-code-skill-installer.d.ts +0 -33
  112. package/dist/node/src/services/claude-code-skill-installer.d.ts.map +0 -1
  113. package/dist/node/src/services/config-env.d.ts +0 -23
  114. package/dist/node/src/services/config-env.d.ts.map +0 -1
  115. package/dist/node/src/services/coordinator-event-normalizer.d.ts +0 -50
  116. package/dist/node/src/services/coordinator-event-normalizer.d.ts.map +0 -1
  117. package/dist/node/src/services/custom-validator-runner.d.ts +0 -66
  118. package/dist/node/src/services/custom-validator-runner.d.ts.map +0 -1
  119. package/dist/node/src/services/debug-capture.d.ts +0 -38
  120. package/dist/node/src/services/debug-capture.d.ts.map +0 -1
  121. package/dist/node/src/services/json-model-output.d.ts +0 -2
  122. package/dist/node/src/services/json-model-output.d.ts.map +0 -1
  123. package/dist/node/src/services/parent-agent-broker.d.ts +0 -21
  124. package/dist/node/src/services/parent-agent-broker.d.ts.map +0 -1
  125. package/dist/node/src/services/pty-auto-response.d.ts +0 -30
  126. package/dist/node/src/services/pty-auto-response.d.ts.map +0 -1
  127. package/dist/node/src/services/pty-init.d.ts +0 -55
  128. package/dist/node/src/services/pty-init.d.ts.map +0 -1
  129. package/dist/node/src/services/pty-service.d.ts +0 -218
  130. package/dist/node/src/services/pty-service.d.ts.map +0 -1
  131. package/dist/node/src/services/pty-session-io.d.ts +0 -49
  132. package/dist/node/src/services/pty-session-io.d.ts.map +0 -1
  133. package/dist/node/src/services/pty-spawn.d.ts +0 -104
  134. package/dist/node/src/services/pty-spawn.d.ts.map +0 -1
  135. package/dist/node/src/services/pty-types.d.ts +0 -94
  136. package/dist/node/src/services/pty-types.d.ts.map +0 -1
  137. package/dist/node/src/services/repo-input.d.ts +0 -16
  138. package/dist/node/src/services/repo-input.d.ts.map +0 -1
  139. package/dist/node/src/services/session-event-queue.d.ts +0 -25
  140. package/dist/node/src/services/session-event-queue.d.ts.map +0 -1
  141. package/dist/node/src/services/session-store.d.ts +0 -107
  142. package/dist/node/src/services/session-store.d.ts.map +0 -1
  143. package/dist/node/src/services/skill-callback-bridge.d.ts +0 -78
  144. package/dist/node/src/services/skill-callback-bridge.d.ts.map +0 -1
  145. package/dist/node/src/services/skill-essentials.d.ts +0 -16
  146. package/dist/node/src/services/skill-essentials.d.ts.map +0 -1
  147. package/dist/node/src/services/skill-lifeops-context-broker.d.ts +0 -20
  148. package/dist/node/src/services/skill-lifeops-context-broker.d.ts.map +0 -1
  149. package/dist/node/src/services/skill-manifest.d.ts +0 -48
  150. package/dist/node/src/services/skill-manifest.d.ts.map +0 -1
  151. package/dist/node/src/services/skill-recommender.d.ts +0 -51
  152. package/dist/node/src/services/skill-recommender.d.ts.map +0 -1
  153. package/dist/node/src/services/spawn-trajectory.d.ts +0 -23
  154. package/dist/node/src/services/spawn-trajectory.d.ts.map +0 -1
  155. package/dist/node/src/services/stall-classifier.d.ts +0 -69
  156. package/dist/node/src/services/stall-classifier.d.ts.map +0 -1
  157. package/dist/node/src/services/structured-proof-bridge.d.ts +0 -99
  158. package/dist/node/src/services/structured-proof-bridge.d.ts.map +0 -1
  159. package/dist/node/src/services/sub-agent-router.d.ts +0 -38
  160. package/dist/node/src/services/sub-agent-router.d.ts.map +0 -1
  161. package/dist/node/src/services/swarm-coordinator-prompts.d.ts +0 -93
  162. package/dist/node/src/services/swarm-coordinator-prompts.d.ts.map +0 -1
  163. package/dist/node/src/services/swarm-coordinator.d.ts +0 -473
  164. package/dist/node/src/services/swarm-coordinator.d.ts.map +0 -1
  165. package/dist/node/src/services/swarm-decision-loop.d.ts +0 -69
  166. package/dist/node/src/services/swarm-decision-loop.d.ts.map +0 -1
  167. package/dist/node/src/services/swarm-event-triage.d.ts +0 -49
  168. package/dist/node/src/services/swarm-event-triage.d.ts.map +0 -1
  169. package/dist/node/src/services/swarm-history.d.ts +0 -27
  170. package/dist/node/src/services/swarm-history.d.ts.map +0 -1
  171. package/dist/node/src/services/swarm-idle-watchdog.d.ts +0 -22
  172. package/dist/node/src/services/swarm-idle-watchdog.d.ts.map +0 -1
  173. package/dist/node/src/services/task-acceptance.d.ts +0 -8
  174. package/dist/node/src/services/task-acceptance.d.ts.map +0 -1
  175. package/dist/node/src/services/task-agent-auth.d.ts +0 -69
  176. package/dist/node/src/services/task-agent-auth.d.ts.map +0 -1
  177. package/dist/node/src/services/task-agent-frameworks.d.ts +0 -90
  178. package/dist/node/src/services/task-agent-frameworks.d.ts.map +0 -1
  179. package/dist/node/src/services/task-kind.d.ts +0 -3
  180. package/dist/node/src/services/task-kind.d.ts.map +0 -1
  181. package/dist/node/src/services/task-policy.d.ts +0 -17
  182. package/dist/node/src/services/task-policy.d.ts.map +0 -1
  183. package/dist/node/src/services/task-registry.d.ts +0 -550
  184. package/dist/node/src/services/task-registry.d.ts.map +0 -1
  185. package/dist/node/src/services/task-share.d.ts +0 -18
  186. package/dist/node/src/services/task-share.d.ts.map +0 -1
  187. package/dist/node/src/services/task-validation.d.ts +0 -69
  188. package/dist/node/src/services/task-validation.d.ts.map +0 -1
  189. package/dist/node/src/services/task-verifier-runner.d.ts +0 -5
  190. package/dist/node/src/services/task-verifier-runner.d.ts.map +0 -1
  191. package/dist/node/src/services/trajectory-context.d.ts +0 -73
  192. package/dist/node/src/services/trajectory-context.d.ts.map +0 -1
  193. package/dist/node/src/services/trajectory-feedback.d.ts +0 -53
  194. package/dist/node/src/services/trajectory-feedback.d.ts.map +0 -1
  195. package/dist/node/src/services/types.d.ts +0 -152
  196. package/dist/node/src/services/types.d.ts.map +0 -1
  197. package/dist/node/src/services/workspace-git-ops.d.ts +0 -28
  198. package/dist/node/src/services/workspace-git-ops.d.ts.map +0 -1
  199. package/dist/node/src/services/workspace-github.d.ts +0 -60
  200. package/dist/node/src/services/workspace-github.d.ts.map +0 -1
  201. package/dist/node/src/services/workspace-lifecycle.d.ts +0 -18
  202. package/dist/node/src/services/workspace-lifecycle.d.ts.map +0 -1
  203. package/dist/node/src/services/workspace-service.d.ts +0 -122
  204. package/dist/node/src/services/workspace-service.d.ts.map +0 -1
  205. package/dist/node/src/services/workspace-types.d.ts +0 -81
  206. package/dist/node/src/services/workspace-types.d.ts.map +0 -1
  207. package/dist/node/src/setup-routes.d.ts +0 -9
  208. package/dist/node/src/setup-routes.d.ts.map +0 -1
  209. package/dist/node/vitest.config.d.ts +0 -3
  210. package/dist/node/vitest.config.d.ts.map +0 -1
package/CHANGELOG.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  ## 0.2.0 (unreleased)
4
4
 
5
- Consolidated ACP-based spawn, PTY sessions, and workspace services into
5
+ ACP-based spawn, sub-agent routing, and workspace services into
6
6
  a single package at `plugins/plugin-agent-orchestrator`. Internal
7
- `@elizaos/plugin-acpx` callers were rewritten to the consolidated package.
7
+ `@elizaos/plugin-acpx` callers were rewritten to the package.
8
8
 
9
9
  ### Added
10
10
 
@@ -33,7 +33,7 @@ a single package at `plugins/plugin-agent-orchestrator`. Internal
33
33
  instead of importing `createUniqueUuid` from `@elizaos/core`. This keeps
34
34
  the router's import surface type-only.
35
35
  - Browser build dropped: this package owns Node-only services
36
- (`PTYService`, `CodingWorkspaceService`, child_process spawn).
36
+ (`AcpService`, `CodingWorkspaceService`, child_process spawn).
37
37
 
38
38
  ### Fixed
39
39
 
@@ -46,12 +46,10 @@ a single package at `plugins/plugin-agent-orchestrator`. Internal
46
46
  `listSessions`/`getSession` for FileSessionStore + RuntimeDbSessionStore,
47
47
  `enforceSessionLimit` excluding both `"error"` and `"errored"`.
48
48
 
49
- ### Deprecated
49
+ ### Removed
50
50
 
51
- - `swarm-coordinator.ts` and the entire `swarm-*` / `pty-*` family are
52
- retained for callers that still depend on `PTYService`, but are
53
- dormant for ACP-spawned sessions. Retiring them is a follow-up
54
- cleanup; new work should use `AcpService` + `SubAgentRouter`.
51
+ - Removed the legacy swarm/terminal implementation family. The plugin now
52
+ has one task-agent transport: `AcpService` + `SubAgentRouter`.
55
53
 
56
54
  ## 0.1.0
57
55
 
package/README.md CHANGED
@@ -4,27 +4,47 @@
4
4
  [![CI](https://github.com/elizaos/eliza/actions/workflows/ci.yml/badge.svg)](https://github.com/elizaos/eliza/actions/workflows/ci.yml)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
6
6
 
7
- The canonical orchestration plugin for ElizaOS task agents. Spawns local coding agents (codex, claude, gemini, ...) via the [`acpx`](https://github.com/0xouroboros/acp) CLI using the structured Agent Client Protocol, routes their output back through the runtime so the main agent decides what to do, and bundles workspace lifecycle, GitHub PR integration, task share, and supporting services in a single package.
7
+ The canonical orchestration plugin for elizaOS task agents. Spawns local coding agents (elizaos, pi-agent, opencode, codex, claude) through Agent Client Protocol transports, routes their output back through the runtime so the main agent decides what to do, and bundles workspace lifecycle, GitHub PR integration, task share, and supporting services in a single package.
8
8
 
9
- > Naming: this plugin is *not* the same thing as `@elizaos/plugin-acp`. That package is Shaw's ACP gateway client (IDE bridge over a remote ACP gateway). `@elizaos/plugin-agent-orchestrator` is the *task backend* that uses `acpx` to run coding agents as subprocesses on the same host as the runtime.
9
+ > Naming: this plugin is *not* the same thing as `@elizaos/plugin-acp`. That package is Shaw's ACP gateway client (IDE bridge over a remote ACP gateway). `@elizaos/plugin-agent-orchestrator` is the *task backend* that runs coding agents as subprocesses on the same host as the runtime.
10
10
 
11
11
  ## What it does
12
12
 
13
13
  The plugin combines three concerns:
14
14
 
15
- 1. **Spawn** coding agents via ACP. The ACP path uses typed JSON-RPC events `tool_call` / `tool_call_update`, `agent_message_chunk`, cooperative `session/cancel`, parallel sessions in the same workspace, recoverable via `session/load`.
16
- 2. **Route** sub-agent terminal events (`task_complete`, `error`, `blocked`) back into the runtime as synthetic inbound messages addressed to the original `roomId`/`userId`/`messageId`. The main agent's normal action layer then decides whether to `REPLY` to the user, `SEND_TO_AGENT` to push the sub-agent further, or both. See [`docs/sub-agent-routing.md`](./docs/sub-agent-routing.md).
15
+ 1. **Spawn** coding agents via ACP. The default path embeds ACP JSON-RPC session management in this plugin and talks directly to an ACP-compatible agent process; the legacy path can still shell out to [`acpx`](https://github.com/openclaw/acpx) when `ELIZA_ACP_TRANSPORT=cli`.
16
+ 2. **Route** sub-agent terminal events (`task_complete`, `error`, `blocked`) and swarm coordination events back into the runtime as synthetic inbound messages addressed to the task room, worktree room, or original `roomId`/`userId`/`messageId`. The main agent's normal action layer then decides whether to `REPLY` to the user, `SEND_TO_AGENT` to push the sub-agent further, ask the task creator a question, or coordinate with other agents. See [`docs/sub-agent-routing.md`](./docs/sub-agent-routing.md).
17
17
  3. **Coordinate** workspace lifecycle (clone, branch, commit, push, PR open) and GitHub issue management for repo-hosted tasks.
18
18
 
19
19
  ## Installation
20
20
 
21
21
  ```bash
22
22
  npm install @elizaos/plugin-agent-orchestrator
23
+ ```
24
+
25
+ Native TypeScript ACP is the default transport. Set the default coding agent with `ELIZA_ACP_DEFAULT_AGENT` (`elizaos`, `pi-agent`, or `opencode` are the primary supported defaults):
26
+
27
+ ```bash
28
+ export ELIZA_ACP_TRANSPORT=native
29
+ export ELIZA_ACP_DEFAULT_AGENT=elizaos
30
+ export ELIZA_ELIZAOS_ACP_COMMAND="elizaos"
31
+ export ELIZA_PI_AGENT_ACP_COMMAND="pi-agent"
32
+ export ELIZA_CODEX_ACP_COMMAND="npx -y @zed-industries/codex-acp@0.14.0"
33
+ export ELIZA_CLAUDE_ACP_COMMAND="npx -y @agentclientprotocol/claude-agent-acp@0.34.0"
34
+ ```
35
+
36
+ Authenticate the underlying agent you plan to use before spawning sessions. Native Codex and Claude defaults use `npx`, so pin or replace those commands in production if you do not want runtime downloads.
37
+
38
+ The legacy command-wrapper path remains available for compatibility:
39
+
40
+ ```bash
23
41
  npm install -g acpx@latest
24
- acpx --version
42
+ export ELIZA_ACP_TRANSPORT=cli
25
43
  ```
26
44
 
27
- You also need at least one ACP-compatible agent CLI (`codex`, `claude`, or `gemini`) installed and authenticated.
45
+ Adapter packaging decision: this release does not vendor the Codex or Claude ACP adapter packages. Native transport is the default; Codex and Claude use pinned `npx` commands unless deployment config overrides them. OpenCode is the exception: the package prefers the bundled OpenCode shim when available, then falls back to `opencode acp`.
46
+
47
+ `coding-agent-adapters` is a runtime registry/API dependency used by this plugin's agent inventory and routes; it is not a bundled Codex or Claude ACP adapter executable.
28
48
 
29
49
  ## Quick start
30
50
 
@@ -38,17 +58,24 @@ export default {
38
58
 
39
59
  ## Action surface
40
60
 
41
- | Action | Purpose |
42
- | --- | --- |
43
- | `ACPX_CREATE_TASK` (`CREATE_TASK`) | One-shot: spawn + prompt + return. Captures origin metadata for routing. |
44
- | `SPAWN_AGENT` | Start a long-lived ACP coding-agent session. Returns `data.agents[]`. |
45
- | `SEND_TO_AGENT` | Send a follow-up prompt to a running session. The main agent uses this to push a sub-agent further when its proof is unsatisfying. |
46
- | `STOP_AGENT` | Cooperatively cancel + close a session. |
47
- | `LIST_AGENTS` | List active and persisted sessions. |
48
- | `CANCEL_TASK` | Cancel an in-flight task while preserving history. |
49
- | `TASK_HISTORY` / `TASK_CONTROL` / `TASK_SHARE` | Task lifecycle ops over the coordinator surface. |
50
- | `PROVISION_WORKSPACE` / `FINALIZE_WORKSPACE` | Git workspace setup, commit, push, PR open. |
51
- | `MANAGE_ISSUES` | GitHub issue create/list/update/close. |
61
+ All actions are virtual sub-operations of the single `TASKS` parent action, promoted via `promoteSubactionsToActions` with the `TASKS_` prefix.
62
+
63
+ | Promoted action | Sub-operation | Purpose |
64
+ | --- | --- | --- |
65
+ | `TASKS_CREATE` | `create` | One-shot: spawn + prompt + return. Captures origin metadata for routing. |
66
+ | `TASKS_SPAWN_AGENT` | `spawn_agent` | Start a long-lived ACP coding-agent session. Returns active session info. |
67
+ | `TASKS_SEND` | `send` | Send a follow-up prompt to a running session (`SEND_TO_AGENT` simile). |
68
+ | `TASKS_STOP_AGENT` | `stop_agent` | Cooperatively cancel + close a session. |
69
+ | `TASKS_LIST_AGENTS` | `list_agents` | List active and persisted sessions. |
70
+ | `TASKS_CANCEL` | `cancel` | Cancel an in-flight task while preserving history. |
71
+ | `TASKS_HISTORY` | `history` | Retrieve past task sessions. |
72
+ | `TASKS_CONTROL` | `control` | Lifecycle control: pause/resume/stop/continue/archive/reopen. |
73
+ | `TASKS_SHARE` | `share` | Share a task session. |
74
+ | `TASKS_PROVISION_WORKSPACE` | `provision_workspace` | Clone repo, create git worktree for a task. |
75
+ | `TASKS_SUBMIT_WORKSPACE` | `submit_workspace` | Commit, push, open PR for a workspace. |
76
+ | `TASKS_MANAGE_ISSUES` | `manage_issues` | GitHub issue create/list/get/update/comment/close/reopen/add_labels. |
77
+ | `TASKS_ARCHIVE` | `archive` | Archive a completed coding task. |
78
+ | `TASKS_REOPEN` | `reopen` | Reopen an archived task. |
52
79
 
53
80
  ## Providers
54
81
 
@@ -56,13 +83,14 @@ export default {
56
83
  - `ACTIVE_SUB_AGENTS` — cache-stable view of currently-routed sub-agent sessions; sorted by sessionId, structural fields only (no timestamps, no message excerpts), so the planner-visible block stays cached across status flips.
57
84
  - `ACTIVE_WORKSPACE_CONTEXT` — live workspace/session state.
58
85
  - `CODING_AGENT_EXAMPLES` — structured action call examples.
86
+ - `CODING_SESSION_CHANGES` — real git changeset for "show me the diff" queries.
59
87
 
60
88
  ## Services
61
89
 
62
- - `AcpService` — ACP subprocess lifecycle, NDJSON parsing, session state, event emission. Registers under `ACP_SUBPROCESS_SERVICE`.
63
- - `SubAgentRouter` (canonical) subscribes to `AcpService.onSessionEvent`, posts terminal-event synthetic memories to `runtime.messageService.handleMessage`. Per-session round-trip cap (`ACPX_SUB_AGENT_ROUND_TRIP_CAP`, default 32) force-stops runaway loops. Disable with `ACPX_SUB_AGENT_ROUTER_DISABLED=1`.
64
- - `PTYService` — PTY-based spawn surface. Bound to `pty-manager`.
65
- - `CodingWorkspaceService` — git workspace lifecycle helpers.
90
+ - `AcpService` — ACP subprocess lifecycle, session state, event emission, and transport selection. Registers under `ACP_SUBPROCESS_SERVICE`.
91
+ - `OrchestratorTaskService` — durable task store, sub-agent lifecycle API, event bridge from ACP to task records. Registers under `ORCHESTRATOR_TASK_SERVICE`.
92
+ - `SubAgentRouter` — subscribes to `AcpService.onSessionEvent`, posts terminal-event synthetic memories to `runtime.messageService.handleMessage`. Registers under `ACPX_SUB_AGENT_ROUTER`. Per-session round-trip cap (`ACPX_SUB_AGENT_ROUND_TRIP_CAP`, default 32) force-stops runaway loops. Disable with `ACPX_SUB_AGENT_ROUTER_DISABLED=1`.
93
+ - `CodingWorkspaceService` — git workspace lifecycle helpers. Registers under `CODING_WORKSPACE_SERVICE`.
66
94
 
67
95
  ```ts
68
96
  import { AcpService, SubAgentRouter } from "@elizaos/plugin-agent-orchestrator";
@@ -106,21 +134,34 @@ You usually don't subscribe directly — `SubAgentRouter` already does, and rout
106
134
 
107
135
  ## Configuration
108
136
 
109
- All configuration is via environment variables. Sensible defaults; most users only need `ELIZA_ACP_CLI` if `acpx` is not on `PATH`.
137
+ All configuration is via environment variables. Use `ELIZA_ACP_TRANSPORT=native` for the embedded TypeScript ACP client and `ELIZA_ACP_TRANSPORT=cli` only when you deliberately want the existing `acpx` wrapper.
110
138
 
111
139
  | Variable | Default | Purpose |
112
140
  | --- | --- | --- |
113
- | `ELIZA_ACP_CLI` | `acpx` | ACPX executable name or absolute path. |
114
- | `ELIZA_ACP_DEFAULT_AGENT` | `codex` | Default agent type. |
141
+ | `ELIZA_ACP_TRANSPORT` | `native` | Transport mode. Accepted values include `native`/`direct` and `cli`/`acpx`. |
142
+ | `ELIZA_ACP_CLI` | `acpx` | ACPX executable name or absolute path for the CLI transport. |
143
+ | `ELIZA_ACP_DEFAULT_AGENT` | `elizaos` | Default agent type. Primary choices: `elizaos`, `pi-agent`, `opencode`. |
144
+ | `ELIZA_ELIZAOS_ACP_COMMAND` | `elizaos` | Native elizaOS ACP command. |
145
+ | `ELIZA_PI_AGENT_ACP_COMMAND` | `pi-agent` | Native Pi Agent ACP command. |
146
+ | `ELIZA_CODEX_ACP_COMMAND` | `npx -y @zed-industries/codex-acp@0.14.0` | Native Codex ACP command. |
147
+ | `ELIZA_CLAUDE_ACP_COMMAND` | `npx -y @agentclientprotocol/claude-agent-acp@0.34.0` | Native Claude ACP command. |
148
+ | `ELIZA_OPENCODE_ACP_COMMAND` | bundled shim or `opencode acp` | Native OpenCode ACP command override. |
115
149
  | `ELIZA_ACP_DEFAULT_APPROVAL` | `autonomous` | Approval preset (`read-only`, `auto`, `permissive`, `autonomous`, `full-access`). |
116
- | `ELIZA_ACP_PROMPT_TIMEOUT_MS` / `ACPX_DEFAULT_TIMEOUT_MS` | `1800000` (30m) | Per-prompt timeout. |
117
- | `ELIZA_ACP_AUTH_TIMEOUT_MS` | `120000` | Auth handshake timeout. |
118
- | `ELIZA_ACP_STATE_DIR` | `~/.eliza/plugin-acpx` | Where to persist session state when no runtime DB. |
150
+ | `ELIZA_ACP_PROMPT_TIMEOUT_MS` / `ACPX_DEFAULT_TIMEOUT_MS` | `300000` (5m) | Per-prompt timeout. |
151
+ | `ELIZA_ACP_STATE_DIR` | `~/.eliza/plugin-acp` | Where to persist session state when no runtime DB. |
119
152
  | `ACPX_DEFAULT_CWD` | runtime cwd | Base directory for spawned agent workdirs. |
120
- | `ELIZA_ACP_LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error`. |
121
153
  | `ELIZA_ACP_MAX_SESSIONS` | `8` | Concurrent session cap. |
122
154
  | `ACPX_SUB_AGENT_ROUTER_DISABLED` | unset | Set to `1` to keep the router service registered but unbound (test/staging). |
123
155
  | `ACPX_SUB_AGENT_ROUND_TRIP_CAP` | `32` | Per-session inject cap before force-stop to prevent ping-pong loops. |
156
+ | `ACPX_PROGRESS_MODE` / `ELIZA_SUB_AGENT_PROGRESS_MODE` | `compact` | Sub-agent progress UX: `compact` delays and edits one status message, `threaded` preserves per-task threads, `silent` disables visible progress. |
157
+ | `ACPX_PROGRESS_DELAY_MS` / `ELIZA_SUB_AGENT_PROGRESS_DELAY_MS` | `15000` | Delay before the first visible progress message, so short tasks only show the final answer. |
158
+ | `ACPX_PROGRESS_REACTIONS` / `ELIZA_SUB_AGENT_PROGRESS_REACTIONS` | unset | Set to `1` to add progress reactions in `threaded` mode. |
159
+
160
+ ### Native transport status
161
+
162
+ Native transport is an ACP JSON-RPC client. It currently handles `initialize`, `session/new`, `session/prompt`, cooperative `session/cancel`, `session/close`, file reads/writes scoped to the session workspace, permission requests, and basic terminal requests from the agent.
163
+
164
+ Use the CLI transport only when you need the existing `acpx` command wrapper semantics.
124
165
 
125
166
  ## Persistence
126
167
 
@@ -143,13 +184,44 @@ node tests/e2e/acp-codex-smoke.mjs
143
184
 
144
185
  # Full router loop (vitest, gated):
145
186
  RUN_LIVE_ACPX=1 bun run test
187
+
188
+ # Native ACP adapter smoke (gated, no-op unless enabled):
189
+ RUN_LIVE_NATIVE_ACP=1 node tests/e2e/live-native-acp-smoke.mjs
146
190
  ```
147
191
 
148
- `acp-codex-smoke.mjs` spawns a real codex session, sends "what is 7 + 8?", and verifies `task_complete` fires with response `"15"`. The vitest live test (`__tests__/live/sub-agent-router.live.test.ts`) verifies the synthetic Memory routes back from a real subprocess into a fake `messageService.handleMessage` with all routing keys intact. Both no-op (skip) when `acpx` isn't installed.
192
+ `acp-codex-smoke.mjs` exercises the legacy `acpx` path by spawning a real codex session, sending "what is 7 + 8?", and verifying `task_complete` fires with response `"15"`. The vitest live test (`__tests__/live/sub-agent-router.live.test.ts`) verifies the synthetic Memory routes back from a real subprocess into a test `messageService.handleMessage` with all routing keys intact. Both no-op (skip) when `acpx` isn't installed.
193
+
194
+ `live-native-acp-smoke.mjs` sets `ELIZA_ACP_TRANSPORT=native`, starts a native ACP adapter over stdio, sends a tiny math prompt, and verifies the prompt response ended with `stopReason: "end_turn"` and final text containing `15`. Optional providers require explicit commands:
195
+
196
+ ```bash
197
+ RUN_LIVE_NATIVE_ACP=1 LIVE_NATIVE_ACP_AGENT=claude ELIZA_CLAUDE_ACP_COMMAND="npx -y @agentclientprotocol/claude-agent-acp@0.34.0" node tests/e2e/live-native-acp-smoke.mjs
198
+ RUN_LIVE_NATIVE_ACP=1 LIVE_NATIVE_ACP_AGENT=opencode ELIZA_OPENCODE_ACP_COMMAND="opencode acp" node tests/e2e/live-native-acp-smoke.mjs
199
+ ```
200
+
201
+ The native smoke skips successfully when `RUN_LIVE_NATIVE_ACP` is unset, when an optional provider command is not configured, or when the adapter reports missing authentication/credentials. Use `RUN_LIVE_NATIVE_ACP=1 bun run test -- __tests__/live/native-acp-smoke.live.test.ts` to run the same smoke through Vitest.
202
+
203
+ Native transport is covered by unit tests under `__tests__/unit/acp-native-transport.test.ts` and by the gated live smoke above.
204
+
205
+ ## Package scripts
206
+
207
+ | Script | Purpose |
208
+ | --- | --- |
209
+ | `bun run build` / `bun run build:ts` | Build Node ESM, CJS, and declaration outputs. |
210
+ | `bun run dev` | Rebuild in watch mode. |
211
+ | `bun run typecheck` | Run TypeScript without emitting files. |
212
+ | `bun run test` | Run the plugin vitest suite. |
213
+ | `bun run test:unit` | Run unit tests only. |
214
+ | `bun run test:e2e:manual` | Run the manual `acp-codex-smoke.mjs` smoke against installed/authenticated `acpx` + Codex. |
215
+ | `bun run test:watch` | Run the vitest suite in watch mode. |
216
+ | `bun run lint:check` | Run Biome checks without writing changes. |
217
+ | `bun run lint` | Run Biome checks with write/unsafe fixes. |
218
+ | `bun run format:check` | Check formatting. |
219
+ | `bun run format` | Write formatting changes. |
220
+ | `bun run clean` | Remove local build/cache outputs. |
149
221
 
150
222
  ## Status
151
223
 
152
- `0.2.0` — consolidated package. ACP subprocess sessions are the primary spawn path; PTY services remain available for terminal-backed route handlers and coordinator tooling.
224
+ `2.0.3-beta.14` — package. ACP subprocess sessions are the only task-agent spawn path. The native ACP client is the default (`ELIZA_ACP_TRANSPORT=native`).
153
225
 
154
226
  ## Contributing
155
227
 
@@ -0,0 +1,138 @@
1
+ # Sub-agent flow & Codex / Claude-Code parity review
2
+
3
+ A thorough walk of how the main agent creates a task, spawns sub-agents,
4
+ provisions them, and communicates — across the elizaOS, Codex, and Claude
5
+ frameworks — plus an honest parity assessment against standalone Codex CLI and
6
+ Claude Code, and the concrete open items.
7
+
8
+ ## 1. End-to-end flow
9
+
10
+ ```
11
+ user msg → planner → TASKS_CREATE ─────────────► durable task (status: open)
12
+ │ roomId, taskRoomId, ownerUserId,
13
+ │ originalRequest, acceptanceCriteria
14
+
15
+ TASKS_SPAWN_AGENT ────────────► AcpService.spawnSession(SpawnOptions)
16
+ │ goal-prompt.ts wraps agentType, workdir, goalPrompt,
17
+ │ the goal + rooms + approvalPreset, metadata{roomId,
18
+ │ acceptance criteria source, label, worldId, userId}
19
+
20
+ ACP subprocess (native JSON-RPC over stdio)
21
+ elizaos | codex | claude | opencode | pi-agent
22
+ │ session/new → session/prompt(goal)
23
+
24
+ events: ready · tool_running · message · reasoning · plan ·
25
+ blocked · task_complete · error · usage_update
26
+
27
+ ┌────────────────┴───────────────────────────────┐
28
+ ▼ ▼
29
+ OrchestratorTaskService.onSessionEvent SubAgentRouter.handleEvent
30
+ (durable: addEvent / updateSession / (synthetic Memory → planner;
31
+ recordMessage; task_complete → "validating") round-trip cap = 32)
32
+
33
+
34
+ planner ↔ subAgentCompletionResponseEvaluator
35
+ → reply to user OR TASKS_SEND_TO_AGENT
36
+ ```
37
+
38
+ **Key files:** task create `actions/tasks.ts:685` → `services/orchestrator-task-service.ts:746`;
39
+ spawn `actions/tasks.ts:743` → `services/acp-service.ts:511`; goal wrap
40
+ `services/goal-prompt.ts:129`; event bridge `orchestrator-task-service.ts:519`;
41
+ routing `services/sub-agent-router.ts`; completion gate
42
+ `orchestrator-task-service.ts:608` (`task_complete` → `validating`, never straight
43
+ to `done`); evaluator `evaluators/sub-agent-completion.ts`.
44
+
45
+ **Provisioning** happens at spawn: `acp-service.ts` resolves the workdir, captures
46
+ a git baseline SHA + dirty set (for the completion changeset), and writes a
47
+ sub-agent `AGENTS.md`/`CLAUDE.md` identity manifest on bare workdirs
48
+ (`sub-agent-identity.ts`). Explicit repo clone / worktree / branch / commit / push
49
+ / PR is `CodingWorkspaceService` (`workspace-*.ts`), driven by
50
+ `TASKS_PROVISION_WORKSPACE` / `TASKS_SUBMIT_WORKSPACE`.
51
+
52
+ ## 2. Sub-agent rooms per task
53
+
54
+ - `roomId` = the originating user channel (where the final reply goes).
55
+ `taskRoomId` = a dedicated task-scoped room; all sessions' messages
56
+ (`senderKind: user|orchestrator|sub_agent|system`) append there. Exposed via
57
+ `GET /api/orchestrator/tasks/:id/messages`, `/timeline`, and `/stream` (SSE).
58
+ - The in-app **task view** (`plugin-task-coordinator/src/OrchestratorWorkbench.tsx`)
59
+ renders this as a per-task message room: the merged timeline + per-sub-agent
60
+ sessions list + plan + diff + usage + recovery, with near-live polling.
61
+ - On chat connectors, the **progress thread** (`index.ts emitProgress`) routes all
62
+ sub-agent narration into a per-task Discord thread / Telegram forum topic
63
+ (capability-gated on `create_thread` + `post_to_thread` + threaded progress
64
+ mode), keeping the main channel clean. This is the "task info as threads in TG
65
+ and Discord" surface.
66
+
67
+ ## 3. Inter-agent communication
68
+
69
+ **Topology: hub-and-spoke.** Sub-agents do not address each other directly. Each
70
+ talks only to the parent:
71
+ - parent → sub: initial goal prompt; mid-flight `TASKS_SEND_TO_AGENT`; live user
72
+ messages in the task room are auto-forwarded to the active session
73
+ (`index.ts` MESSAGE_RECEIVED listener).
74
+ - sub → parent: terminal ACP events → synthetic memories; plus a sub-agent can
75
+ emit `USE_SKILL parent-agent {…}` which the router dispatches to the
76
+ parent-agent broker (`parent-agent-dispatch.ts` / `parent-agent-broker.ts`) and
77
+ replies back over the session.
78
+ - sub → parent context: loopback-only bridge `GET /api/coding-agents/:id/context/*`
79
+ (parent character, current room, memory search, active workspaces).
80
+
81
+ Multiple sub-agents per task are supported (`sessions[]`), unsynchronized; the
82
+ router de-dupes concurrent `task_complete` so only the first posts to the user.
83
+
84
+ ## 4. Framework matrix (elizaOS / Codex / Claude)
85
+
86
+ All run as ACP subprocesses over the native JSON-RPC transport
87
+ (`acp-native-transport.ts`); spawn command per framework is env-overridable
88
+ (`ELIZA_{ELIZAOS,CODEX,CLAUDE,OPENCODE,PI_AGENT}_ACP_COMMAND`; Codex/Claude default
89
+ to pinned `npx` ACP shims). The orchestrator implements the ACP client side of:
90
+ `session/new`, `session/prompt`, `session/cancel`, `session/update` (streaming
91
+ `agent_message_chunk` / `agent_thought_chunk` / `tool_call` / `plan`),
92
+ `session/request_permission`, `fs/read_text_file`, `fs/write_text_file`, and the
93
+ `terminal/*` family. Approval presets (`readonly|standard|permissive|autonomous`)
94
+ gate file/terminal ops. Credentials reach sub-agents via the loopback credential
95
+ tunnel (`bridge-routes.ts`); host connector tokens are denylisted from the child
96
+ env, and Claude OAuth-subscription tokens are stripped so the child uses its own
97
+ subscription.
98
+
99
+ ## 5. Parity vs standalone Codex CLI / Claude Code
100
+
101
+ **At parity:** multi-framework spawn + routing; file read/write; terminal exec;
102
+ plan/reasoning/tool streaming; approval gates; real git-diff capture & surfacing
103
+ (`coding-session-changes.ts`); token usage; orphaned-session recovery on restart;
104
+ durable task store + task view; per-task threads on connectors.
105
+
106
+ **Partial:** plan/todo events are emitted by OpenCode but not uniformly by
107
+ Codex/Claude; diff surfacing truncates (20 files / 50 lines) with no inline
108
+ per-line review UI; sub-agents run `--no-terminal` (event-driven, no interactive
109
+ TUI — correct for orchestration, but differs from a human at the CLI).
110
+
111
+ **Gaps:**
112
+ 1. **MCP forwarding** — ✅ implemented (opt-in). `acp-native-transport.ts`
113
+ forwards `ELIZA_ACP_MCP_SERVERS` (a JSON array of stdio/http MCP server
114
+ configs) into `session/new.mcpServers` via `parseAcpMcpServersEnv`, so
115
+ sub-agents get the parent's MCP tools (Codex / Claude-Code parity). Defaults
116
+ to `[]` (prior behavior) so spawning never regresses. Remaining: auto-inherit
117
+ the parent runtime's MCP set without explicit env config (needs a runtime
118
+ MCP-config surface, which doesn't exist yet).
119
+ 2. **Sub-agent nesting** (open) — no spawn-child API; a sub-agent cannot delegate
120
+ to its own sub-agents (single level of orchestration). Feature-level work.
121
+ 3. **Inline code-review surface** — diffs are captured but there's no structured
122
+ per-file/line review/approve UI in the task view.
123
+
124
+ ## 6. Open items checklist
125
+
126
+ - [x] Interaction protocol (forms / choice + custom / secret / task) across app + TG + Discord
127
+ - [x] Pick-an-option round-trip on both connectors; secret/OAuth DM link-out on both
128
+ - [x] Per-task threads on TG + Discord (orchestrator-driven; both connectors now capable)
129
+ - [x] Task view with sub-agent message room (OrchestratorWorkbench)
130
+ - [x] Real interaction-widget + connector round-trip tests
131
+ - [x] MCP server forwarding to sub-agents (opt-in via `ELIZA_ACP_MCP_SERVERS`)
132
+ - [ ] Sub-agent nesting / delegation (gap #2 — feature-level)
133
+ - [ ] Inline diff review UI in the task view (gap #3)
134
+ - [ ] Live connector E2E (needs TG/Discord credentials) + orchestrator HTTP task-flow E2E
135
+ - [ ] Optional: `outgoing_before_deliver` central interaction normalization hook
136
+
137
+ See `@elizaos/core` `src/messaging/interactions/README.md` for the interaction
138
+ protocol; this doc covers the orchestration + sub-agent layer.
@@ -7,7 +7,7 @@ Date: 2026-05-10
7
7
  Make Eliza's default task workers self-sufficient:
8
8
 
9
9
  - They should receive editable, repo-owned default skills for Eliza, elizaOS plugin/app development, Eliza Cloud APIs, and monetization.
10
- - Claude, Codex, OpenCode, Gemini, Aider, and other orchestrated workers should receive those defaults through the agent orchestrator.
10
+ - Claude, Codex, and OpenCode workers should receive those defaults through the ACP agent orchestrator.
11
11
  - Applications should be able to override defaults without forking the shipped skill package.
12
12
  - Workers should be able to ask the running parent Eliza agent for context or actions that only the parent can perform.
13
13
  - Paid, private, or destructive operations should remain mediated by the parent agent and its confirmation flow.
@@ -39,10 +39,9 @@ The task agent infrastructure is in `plugins/plugin-agent-orchestrator`.
39
39
 
40
40
  Important surfaces:
41
41
 
42
- - `src/services/pty-service.ts` spawns agents, writes adapter memory files, injects parent runtime loopback context, and manages session lifecycle.
43
- - `src/actions/coding-task-handlers.ts` prepares `SKILLS.md`, recommends skills, spawns task sessions, and registers per-session skill allow-lists.
42
+ - `src/services/acp-service.ts` spawns ACP agents, records session metadata, and manages session lifecycle.
43
+ - `src/actions/tasks.ts` prepares ACP spawn/send/list/control requests through the single task-agent action surface.
44
44
  - `src/services/skill-manifest.ts` renders the task-local manifest and virtual broker skills.
45
- - `src/services/skill-callback-bridge.ts` listens for child output lines matching `USE_SKILL <slug> <json_args>` and routes them back to the parent runtime.
46
45
  - `src/services/skill-lifeops-context-broker.ts` already exposes task-scoped LifeOps context.
47
46
 
48
47
  ### Cloud and monetization
@@ -95,7 +94,7 @@ Sensitive broker access is session allow-listed. The orchestrator includes `pare
95
94
 
96
95
  ### Worker manifest
97
96
 
98
- `SKILLS.md` now tells workers to emit a standalone `USE_SKILL <slug> <json_args>` line. The orchestrator writes this manifest into the workspace and sets `ELIZA_SKILLS_MANIFEST`, so Codex/Claude/Gemini/Aider-style workers can discover skill protocol without hardcoding.
97
+ `SKILLS.md` now tells workers to emit a standalone `USE_SKILL <slug> <json_args>` line. The orchestrator writes this manifest into the workspace and sets `ELIZA_SKILLS_MANIFEST`, so Codex/Claude/OpenCode workers can discover skill protocol without hardcoding.
99
98
 
100
99
  The injected parent runtime memory also now explains:
101
100
 
@@ -113,9 +112,6 @@ The orchestrator-managed gitignore block now includes common generated agent fil
113
112
  - `.claude/`
114
113
  - `AGENTS.md`
115
114
  - `.codex/`
116
- - `GEMINI.md`
117
- - `.gemini/`
118
- - `.aider*`
119
115
  - `.opencode/`
120
116
  - `SKILLS.md`
121
117
 
@@ -178,11 +174,11 @@ Review focus:
178
174
 
179
175
  - Type correctness around synthetic `Memory` construction and `messageService.handleMessage`.
180
176
  - Session allow-list behavior for virtual brokers.
181
- - Whether all spawned adapter types can see `SKILLS.md` and parent memory text.
177
+ - Whether all ACP agent types can see `SKILLS.md` and parent memory text.
182
178
  - Whether tracked `AGENTS.md` repos need a safer memory-file strategy than writing in the workspace root.
183
- - Whether OpenCode should become a first-class adapter type instead of shell-compatible spawn.
179
+ - Whether OpenCode's vendored ACP path has enough smoke coverage against Cerebras.
184
180
 
185
- Status: partially implemented. The first three are covered by code/tests; the last two remain follow-up design items.
181
+ Status: partially implemented. The first three are covered by code/tests; live OpenCode/Cerebras validation remains credential-gated.
186
182
 
187
183
  ### Pass 5: Testing, Verification, Validation
188
184
 
@@ -197,8 +193,8 @@ Minimum local tests:
197
193
  Live validation:
198
194
 
199
195
  - Start a parent Eliza runtime with agent skills and orchestrator loaded.
200
- - Spawn Codex and Claude workers and verify they read `SKILLS.md`.
201
- - Spawn OpenCode using Eliza Cloud with Cerebras OpenAI `gpt-oss-120b` and verify it can emit `USE_SKILL parent-agent ...`.
196
+ - Spawn Codex, Claude, and OpenCode workers and verify they read `SKILLS.md`.
197
+ - Spawn OpenCode through ACP using the vendored OpenCode shim with Cerebras `gpt-oss-120b` and verify it can emit `USE_SKILL parent-agent ...`.
202
198
  - Simulate:
203
199
  - action listing
204
200
  - parent memory search
@@ -212,8 +208,6 @@ Status: local unit/type/skills tests are implemented and passing. Live OpenCode/
212
208
 
213
209
  ## Remaining Gaps
214
210
 
215
- - OpenCode is currently treated through shell-compatible spawn paths in parts of the orchestrator. It should become a first-class memory/config adapter if the project wants equivalent behavior to Claude/Codex/Gemini.
216
- - `PARALLAX_DEFAULT_AGENT_TYPE` fixed-default parsing still only accepts `claude`, `gemini`, `codex`, and `aider`. Routing can rank OpenCode, but fixed default should be extended after type/API review.
217
211
  - Writing adapter memory files named `AGENTS.md` can collide with repos that already track `AGENTS.md`. A safer strategy is needed for Codex memory injection in tracked-repo workspaces.
218
212
  - Live agent benchmarking against OpenCode + Eliza Cloud + Cerebras requires credentials and running infrastructure.
219
213
  - The parent-agent broker currently asks through the normal parent message pipeline. Direct action invocation APIs could be added later, but the message path is more flexible and preserves confirmation behavior.
@@ -0,0 +1,140 @@
1
+ # Economics `/goal` runbook — autonomous monetized-app loop
2
+
3
+ How to drive (and what currently blocks) a `/goal` sub-agent that autonomously
4
+ runs the monetized-app loop: create app → deploy container → enable monetization
5
+ → buy a domain → stay alive on earnings, with paid Cloud commands auto-authorized
6
+ within a spend cap.
7
+
8
+ ## What already works (verified)
9
+
10
+ - **Capped self-spend allowance.** `decideSpendAuthorization`
11
+ (`src/services/spend-allowance.ts`) gates each Cloud command by risk/cap, and
12
+ `runCloudCommand` (`src/services/parent-agent-broker.ts:1067`) emits the
13
+ structured `event: "spend_auto_authorized"` log when a self-spend command
14
+ auto-authorizes within `ELIZA_AGENT_SPEND_CAP_USD`. Confirmed by
15
+ `src/__tests__/parent-agent-broker.test.ts` › _capped self-spend allowance_
16
+ (4 cases pass: within-cap auto-authorizes, over-cap confirms, non-self-spend
17
+ mutating auto-authorizes).
18
+ - **Economics capability profile.** `/economics` (or `/monetize`,
19
+ `/monetized-app`) in the composer sets `metadata.capabilityProfile = "economics"`
20
+ (`plugin-task-coordinator` composer directives → `createOrchestratorTask`), and
21
+ `spawnAgentForTask` reads `coerceGoalCapabilityProfile(task.metadata.capabilityProfile)`
22
+ and widens the goal fence via `ECONOMICS_GOAL_CAPABILITIES` (`goal-prompt.ts`).
23
+ - **The Cloud loop itself.** `apps.create → monetization.update → domains.buy
24
+ (real credit debit) → earnings → survival economics` is exercised end-to-end
25
+ against the mock stack by
26
+ `packages/test/cloud-e2e/tests/monetized-app-loop.spec.ts`.
27
+
28
+ ## Runbook
29
+
30
+ 1. Boot a stubbed-but-real Cloud so paid commands succeed without real money:
31
+
32
+ ```bash
33
+ CLOUD_E2E=1 NODE_ENV=test bun run cloud:mock --reset
34
+ # note the printed "Ready on http://127.0.0.1:<apiPort>"
35
+ ```
36
+
37
+ `cloud:mock` opens its PGlite store as a single-writer file, so you cannot
38
+ seed an org/API key from a second process while it runs. To seed live (and to
39
+ give the broker a key the granular per-route permission gate accepts), boot
40
+ through the cloud-e2e stack fixture instead — it stands up a PGlite **TCP
41
+ bridge** + the same wrangler launcher, then `seedTestUser()` mints an org with
42
+ credits + an API key. Mint the key with `permissions: ["*"]` if you want the
43
+ actual `containers.create` / `domains.buy` cloud calls to succeed (the default
44
+ `read/write/admin` seed key still proves `spend_auto_authorized`, because that
45
+ log fires from the cap decision *before* the HTTP call — but the call itself
46
+ 401s on routes that require granular scopes like `containers:write`).
47
+
48
+ 2. Point the broker at the mock and arm the spend cap (these resolve through
49
+ `config-env.ts`, so the eliza config `env` section or process env both work):
50
+
51
+ ```bash
52
+ ELIZA_CLOUD_BASE_URL=http://127.0.0.1:<apiPort>
53
+ ELIZAOS_CLOUD_API_KEY=<a seeded org API key> # see cloud-e2e seedTestUser
54
+ ELIZA_AGENT_SPEND_CAP_USD=20
55
+ ELIZA_ACP_DEFAULT_AGENT=opencode # Cerebras auto-detected; or codex/claude with their keys
56
+ OPENCODE_DISABLE_AUTOUPDATE=1 # opencode's network update check can blow the spawn timeout
57
+ ACPX_DEFAULT_TIMEOUT_MS=600000 # first opencode init (compile + provider fetch) ~3-5min
58
+ ```
59
+
60
+ 3. Create an economics task — `/economics build and monetize a tiny app` in the
61
+ composer, or `POST /api/orchestrator` with
62
+ `metadata: { capabilityProfile: "economics" }`.
63
+
64
+ 4. The sub-agent loads the `build-monetized-app` skill and SKILLS.md and drives
65
+ the loop through the parent-agent broker. Watch the logs for
66
+ `event: "spend_auto_authorized"` on `containers.create` / `domains.buy` —
67
+ that line is the proof the agent spent within its cap without a human prompt.
68
+
69
+ - **Domains gotcha:** `domains.buy` (and `media.*`/`promote.*`) resolve to
70
+ unknown cost and stall on confirmation unless the agent first calls
71
+ `domains.check` and threads the quote into `params.spendEstimateUsd`.
72
+ `containers.create` has a built-in `$0.67/day` estimate, so it
73
+ auto-authorizes without a hint.
74
+ - **`containers.create` needs a `name`** in addition to `appId`/`image`, or
75
+ the cloud call 422s (the spend log still fires; the deploy record is not
76
+ created). A capable agent self-corrects via `list-cloud-commands`.
77
+
78
+ ## Sub-agent → broker dispatcher (now wired)
79
+
80
+ `runCloudCommand` (the only emitter of `spend_auto_authorized`) is now reachable
81
+ by a live agent. The three gaps the earlier draft of this runbook called out are
82
+ closed:
83
+
84
+ 1. **Dispatch.** `SubAgentRouter.handleEvent` accumulates the child's streamed
85
+ `message` text and, when a complete `USE_SKILL parent-agent <json>` directive
86
+ appears, bridges it to `runParentAgentBroker({ runtime, sessionId, session,
87
+ args })` and streams `result.text` back via `acp.sendToSession`
88
+ (`src/services/parent-agent-dispatch.ts`). Detection is marker-guarded (it
89
+ only acts on text containing `USE_SKILL parent-agent`, which ordinary coding
90
+ tasks never emit) and capped by `ACPX_SUB_AGENT_ROUND_TRIP_CAP`.
91
+ 2. **Advertise.** `spawnAgentForTask` writes a `SKILLS.md` into the workdir for
92
+ `capabilityProfile === "economics"` tasks via `buildSkillsManifest(runtime, {
93
+ recommendedSlugs: ["build-monetized-app", "eliza-cloud"], virtualSkills:
94
+ [PARENT_AGENT_BROKER_MANIFEST_ENTRY] })`, so the child learns the `parent-agent`
95
+ slug and its arg contract.
96
+ 3. **Estimate.** The broker's unknown-cost stall now returns an *actionable*
97
+ instruction ("fetch a quote with `domains.check` and retry with
98
+ `params.spendEstimateUsd`") instead of a human-only yes/no, and the manifest
99
+ guidance advertises the same pattern — so an autonomous agent self-authorizes
100
+ `domains.buy` within the cap without a human turn.
101
+
102
+ The directive parser and the broker→`sendToSession` bridge are unit-tested in
103
+ `src/__tests__/parent-agent-dispatch.test.ts`; `spend_auto_authorized` itself
104
+ stays covered by `parent-agent-broker.test.ts`.
105
+
106
+ ## Live verification (2026-06-06)
107
+
108
+ The full loop was run end-to-end against `cloud:mock` with a real
109
+ `opencode` ACP child on a Cerebras key (`gpt-oss-120b`) — no human in the loop:
110
+
111
+ - The child read `SKILLS.md`, then drove `cloud.health → apps.create →
112
+ containers.create` entirely through `USE_SKILL parent-agent {…}` directives.
113
+ `apps.create` created a real app; `containers.create` self-authorized within
114
+ the cap and emitted, verbatim:
115
+ `event:"spend_auto_authorized" command:"containers.create" risk:"paid"
116
+ estimatedCostUsd:0.67 runningTotalUsd:0.67 capUsd:20 reason:"within-cap"`.
117
+ When the first `containers.create` 422'd (missing `name`), the child called
118
+ `list-cloud-commands`, corrected the params, and re-authorized — no human turn.
119
+ - The `domains.buy` self-resolve path was verified at the broker level against
120
+ the same live mock: `domains.check` returned a `$14.95` quote, that price was
121
+ threaded into `params.spendEstimateUsd`, `domains.buy` emitted
122
+ `spend_auto_authorized` ($14.95 of the $20 cap), and the org credit balance
123
+ dropped **1000.00 → 985.05** — a real debit.
124
+
125
+ Two defects the live run surfaced (both fixed):
126
+
127
+ 1. **Windows env forwarding (`acp-service.ts`).** `shouldForwardEnv` matched
128
+ `PATH` case-sensitively, but the repo runtime is Bun and Bun-on-Windows
129
+ reports the key as `Path` — so ACP sub-agents spawned with NO `PATH` and the
130
+ opencode shim died with `'bun' is not recognized`. Now matched
131
+ case-insensitively (+ Windows system vars), with the path key canonicalized
132
+ to `PATH` in `buildEnv`.
133
+ 2. **Mid-turn reply delivery (`parent-agent-dispatch.ts`).** A child emits its
134
+ directive *mid-turn* and ends the turn awaiting the reply; delivering the
135
+ reply is a new prompt, which the transport rejects ("session is already
136
+ busy") until the turn finishes. The old code dropped the reply, stalling the
137
+ loop on the first directive. Delivery now retries until the session goes idle.
138
+
139
+ See `default-eliza-skills-and-agent-bridge-plan.md` for the broader bridge design;
140
+ this runbook is the economics-specific slice.