@elizaos/plugin-agent-orchestrator 2.0.0-alpha.9 → 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.
- package/CHANGELOG.md +60 -0
- package/LICENSE +21 -0
- package/README.md +232 -0
- package/docs/SUBAGENT_FLOW_AND_PARITY.md +138 -0
- package/docs/default-eliza-skills-and-agent-bridge-plan.md +225 -0
- package/docs/economics-goal-runbook.md +140 -0
- package/docs/multi-account-orchestration.md +76 -0
- package/docs/orchestrator-buildout-followups.md +124 -0
- package/docs/orchestrator-dashboard-task-widget-secrets-assessment.md +174 -0
- package/docs/orchestrator-dashboard-task-widget-secrets-design.md +301 -0
- package/docs/research/orchestrator-view-research-report.md +273 -0
- package/docs/sub-agent-routing.md +227 -0
- package/package.json +197 -38
- package/dist/index.d.ts +0 -21
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -21120
- package/dist/index.js.map +0 -109
- package/dist/src/actions/messaging.d.ts +0 -24
- package/dist/src/actions/messaging.d.ts.map +0 -1
- package/dist/src/actions/peek-subagent.d.ts +0 -3
- package/dist/src/actions/peek-subagent.d.ts.map +0 -1
- package/dist/src/actions/subagent-management.d.ts +0 -7
- package/dist/src/actions/subagent-management.d.ts.map +0 -1
- package/dist/src/actions/task-management.d.ts +0 -9
- package/dist/src/actions/task-management.d.ts.map +0 -1
- package/dist/src/config.d.ts +0 -4
- package/dist/src/config.d.ts.map +0 -1
- package/dist/src/providers/orchestrator-config.d.ts +0 -80
- package/dist/src/providers/orchestrator-config.d.ts.map +0 -1
- package/dist/src/providers/task-context.d.ts +0 -3
- package/dist/src/providers/task-context.d.ts.map +0 -1
- package/dist/src/services/agent-orchestrator-service.d.ts +0 -59
- package/dist/src/services/agent-orchestrator-service.d.ts.map +0 -1
- package/dist/src/services/messaging-service.d.ts +0 -111
- package/dist/src/services/messaging-service.d.ts.map +0 -1
- package/dist/src/services/sandbox-service.d.ts +0 -103
- package/dist/src/services/sandbox-service.d.ts.map +0 -1
- package/dist/src/services/subagent-service.d.ts +0 -140
- package/dist/src/services/subagent-service.d.ts.map +0 -1
- package/dist/src/sub-agents/adapter.d.ts +0 -13
- package/dist/src/sub-agents/adapter.d.ts.map +0 -1
- package/dist/src/sub-agents/claude-agent-sdk-sub-agent.d.ts +0 -18
- package/dist/src/sub-agents/claude-agent-sdk-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/codex-sdk-sub-agent.d.ts +0 -18
- package/dist/src/sub-agents/codex-sdk-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/eliza-sub-agent.d.ts +0 -27
- package/dist/src/sub-agents/eliza-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/elizaos-native-sub-agent.d.ts +0 -61
- package/dist/src/sub-agents/elizaos-native-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/index.d.ts +0 -10
- package/dist/src/sub-agents/index.d.ts.map +0 -1
- package/dist/src/sub-agents/opencode-sub-agent.d.ts +0 -44
- package/dist/src/sub-agents/opencode-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/registry.d.ts +0 -3
- package/dist/src/sub-agents/registry.d.ts.map +0 -1
- package/dist/src/sub-agents/sweagent-sub-agent.d.ts +0 -19
- package/dist/src/sub-agents/sweagent-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/tools.d.ts +0 -15
- package/dist/src/sub-agents/tools.d.ts.map +0 -1
- package/dist/src/sub-agents/types.d.ts +0 -170
- package/dist/src/sub-agents/types.d.ts.map +0 -1
- package/dist/src/types/index.d.ts +0 -12
- package/dist/src/types/index.d.ts.map +0 -1
- package/dist/src/types/messaging.d.ts +0 -202
- package/dist/src/types/messaging.d.ts.map +0 -1
- package/dist/src/types/sandbox.d.ts +0 -228
- package/dist/src/types/sandbox.d.ts.map +0 -1
- package/dist/src/types/subagent.d.ts +0 -232
- package/dist/src/types/subagent.d.ts.map +0 -1
- package/dist/src/types.d.ts +0 -138
- package/dist/src/types.d.ts.map +0 -1
- package/dist/src/utils/index.d.ts +0 -7
- package/dist/src/utils/index.d.ts.map +0 -1
- package/dist/src/utils/session.d.ts +0 -184
- package/dist/src/utils/session.d.ts.map +0 -1
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Default Eliza Skills And Agent Bridge Plan
|
|
2
|
+
|
|
3
|
+
Date: 2026-05-10
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Make Eliza's default task workers self-sufficient:
|
|
8
|
+
|
|
9
|
+
- They should receive editable, repo-owned default skills for Eliza, elizaOS plugin/app development, Eliza Cloud APIs, and monetization.
|
|
10
|
+
- Claude, Codex, and OpenCode workers should receive those defaults through the ACP agent orchestrator.
|
|
11
|
+
- Applications should be able to override defaults without forking the shipped skill package.
|
|
12
|
+
- Workers should be able to ask the running parent Eliza agent for context or actions that only the parent can perform.
|
|
13
|
+
- Paid, private, or destructive operations should remain mediated by the parent agent and its confirmation flow.
|
|
14
|
+
|
|
15
|
+
## Current Inventory
|
|
16
|
+
|
|
17
|
+
### Shipped skills
|
|
18
|
+
|
|
19
|
+
Repo-owned default skills live under:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
packages/skills/skills/<slug>/SKILL.md
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The `@elizaos/skills` package publishes those files. Runtime startup wires bundled, workspace, and extra skill roots through `packages/agent/src/runtime/eliza.ts`. Managed/workspace copies override bundled defaults.
|
|
26
|
+
|
|
27
|
+
Relevant shipped skills now include:
|
|
28
|
+
|
|
29
|
+
- `eliza` for the running Eliza app, parent-agent callback protocol, capabilities, and lifecycle.
|
|
30
|
+
- `elizaos` for upstream runtime/plugin abstractions.
|
|
31
|
+
- `eliza-app-development` for this app repo's build and edit workflow.
|
|
32
|
+
- `eliza-cloud` for Cloud APIs, apps, credits, billing, containers, domains, auth, and earnings.
|
|
33
|
+
- `build-monetized-app` for the new-app deploy and monetization loop.
|
|
34
|
+
- `task-agent-eliza-bridge` for low-level task-agent bridge details.
|
|
35
|
+
|
|
36
|
+
### Agent orchestration
|
|
37
|
+
|
|
38
|
+
The task agent infrastructure is in `plugins/plugin-agent-orchestrator`.
|
|
39
|
+
|
|
40
|
+
Important surfaces:
|
|
41
|
+
|
|
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
|
+
- `src/services/skill-manifest.ts` renders the task-local manifest and virtual broker skills.
|
|
45
|
+
- `src/services/skill-lifeops-context-broker.ts` already exposes task-scoped LifeOps context.
|
|
46
|
+
|
|
47
|
+
### Cloud and monetization
|
|
48
|
+
|
|
49
|
+
Current Cloud source-of-truth files:
|
|
50
|
+
|
|
51
|
+
- OpenAPI: `cloud/apps/api/openapi.json/route.ts`
|
|
52
|
+
- SDK: `cloud/packages/sdk/src/client.ts`
|
|
53
|
+
- billing/pricing: `cloud/packages/lib/services/ai-billing.ts`, `ai-pricing.ts`, `credits.ts`
|
|
54
|
+
- app chat: `cloud/apps/api/v1/apps/[id]/chat/route.ts`
|
|
55
|
+
- OpenAI-compatible chat: `cloud/apps/api/v1/chat/completions/route.ts`
|
|
56
|
+
- app monetization: `cloud/apps/api/v1/apps/[id]/monetization/route.ts`
|
|
57
|
+
- app credits: `cloud/packages/lib/services/app-credits.ts`
|
|
58
|
+
- container billing: `cloud/apps/api/cron/container-billing/route.ts`
|
|
59
|
+
|
|
60
|
+
Active app monetization is markup/share based. Inference in the current app-chat path debits the caller/user org credits and credits creator markup to redeemable earnings. App-credit purchase/share flows exist, but should not be assumed to fund inference unless the endpoint being edited explicitly does so.
|
|
61
|
+
|
|
62
|
+
## Implemented Architecture
|
|
63
|
+
|
|
64
|
+
### Default editable skills
|
|
65
|
+
|
|
66
|
+
Default skills remain bundled in `@elizaos/skills` and are seeded into the managed skills directory only when the user does not already have an editable copy.
|
|
67
|
+
|
|
68
|
+
Applications and workspaces can override defaults by placing a same-slug skill in a higher-priority skill root. This preserves:
|
|
69
|
+
|
|
70
|
+
- global defaults included with Eliza
|
|
71
|
+
- user/application customization
|
|
72
|
+
- stable slugs for orchestrator recommendation and invocation
|
|
73
|
+
- short `SKILL.md` bodies with longer references under `references/`
|
|
74
|
+
|
|
75
|
+
The root `scripts/ensure-skills.mjs` now resolves the shipped skill tree from `@elizaos/skills`, then falls back to `packages/skills/skills`, then legacy `skills/`.
|
|
76
|
+
|
|
77
|
+
### Parent-agent broker
|
|
78
|
+
|
|
79
|
+
A new virtual broker skill, `parent-agent`, lets a child ask the running parent Eliza agent to use its loaded capabilities:
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
USE_SKILL parent-agent {"request":"Find the next open 30 minute slot on my calendar tomorrow afternoon"}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The broker builds a synthetic message memory and sends it through the parent's normal `messageService.handleMessage(...)` pipeline with `continueAfterActions: true`. This means the parent can use the same actions, providers, services, connectors, model handlers, confirmation policies, and user approval flow it already uses for normal chat.
|
|
86
|
+
|
|
87
|
+
It also supports action discovery:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
USE_SKILL parent-agent {"mode":"list-actions","query":"github","limit":25}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Sensitive broker access is session allow-listed. The orchestrator includes `parent-agent` in generated manifests for coding-task sessions and registers the manifest slugs as the session allow-list.
|
|
94
|
+
|
|
95
|
+
### Worker manifest
|
|
96
|
+
|
|
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.
|
|
98
|
+
|
|
99
|
+
The injected parent runtime memory also now explains:
|
|
100
|
+
|
|
101
|
+
- read-only loopback endpoints
|
|
102
|
+
- `ELIZA_SKILLS_MANIFEST` / `SKILLS.md`
|
|
103
|
+
- `USE_SKILL parent-agent`
|
|
104
|
+
- `USE_SKILL lifeops-context`
|
|
105
|
+
- when to ask the parent for connector/private/paid actions
|
|
106
|
+
|
|
107
|
+
### Git hygiene
|
|
108
|
+
|
|
109
|
+
The orchestrator-managed gitignore block now includes common generated agent files:
|
|
110
|
+
|
|
111
|
+
- `CLAUDE.md`
|
|
112
|
+
- `.claude/`
|
|
113
|
+
- `AGENTS.md`
|
|
114
|
+
- `.codex/`
|
|
115
|
+
- `.opencode/`
|
|
116
|
+
- `SKILLS.md`
|
|
117
|
+
|
|
118
|
+
Tracked repo files with the same names still need care; ignore rules only prevent new untracked files from being committed.
|
|
119
|
+
|
|
120
|
+
## Security Model
|
|
121
|
+
|
|
122
|
+
The child worker never receives the parent API key, full memory dump, or raw connector credentials.
|
|
123
|
+
|
|
124
|
+
Allowed paths:
|
|
125
|
+
|
|
126
|
+
- read-only loopback endpoints for bounded parent context
|
|
127
|
+
- `USE_SKILL` directives for session allow-listed skill/broker slugs
|
|
128
|
+
- parent-agent requests mediated by the parent message pipeline
|
|
129
|
+
- parent confirmation flow for paid, destructive, private, or external operations
|
|
130
|
+
|
|
131
|
+
Denied or discouraged paths:
|
|
132
|
+
|
|
133
|
+
- ad hoc POSTs to loopback context endpoints
|
|
134
|
+
- bypassing Cloud/user confirmation for paid steps
|
|
135
|
+
- directly recreating parent credentials inside a child workspace
|
|
136
|
+
- treating task-agent output as a persistent authenticated identity
|
|
137
|
+
|
|
138
|
+
## Five-Pass Implementation Plan
|
|
139
|
+
|
|
140
|
+
### Pass 1: Prep
|
|
141
|
+
|
|
142
|
+
- Inventory shipped skills and confirm `@elizaos/skills` is the bundled default source.
|
|
143
|
+
- Inventory orchestrator spawn/memory/manifest/callback code.
|
|
144
|
+
- Inventory Cloud billing, monetization, app chat, SDK, and container deploy source-of-truth files.
|
|
145
|
+
- Decide stable slugs and default override model.
|
|
146
|
+
- Define task-scoped broker protocol and sensitive-broker allow-list behavior.
|
|
147
|
+
|
|
148
|
+
Status: implemented for the default skill and broker surfaces.
|
|
149
|
+
|
|
150
|
+
### Pass 2: Implementation
|
|
151
|
+
|
|
152
|
+
- Add `eliza` default skill and references.
|
|
153
|
+
- Expand app-development, Cloud, monetization, and task-agent bridge skills.
|
|
154
|
+
- Fix root shipped-skill seeding to resolve `@elizaos/skills`.
|
|
155
|
+
- Add `parent-agent` virtual broker.
|
|
156
|
+
- Include `parent-agent` in `SKILLS.md` and the session allow-list.
|
|
157
|
+
- Update worker memory injection and manifest protocol text.
|
|
158
|
+
- Add generated agent files to orchestrator gitignore.
|
|
159
|
+
|
|
160
|
+
Status: implemented.
|
|
161
|
+
|
|
162
|
+
### Pass 3: Cleanup
|
|
163
|
+
|
|
164
|
+
- Keep skill prose short and push details into references.
|
|
165
|
+
- Remove stale "read-only only / no action delegation" wording from task-agent bridge docs.
|
|
166
|
+
- Correct monetization docs where they implied app-specific inference balances in the active route.
|
|
167
|
+
- Align Cloud skill references to current implementation files.
|
|
168
|
+
|
|
169
|
+
Status: implemented.
|
|
170
|
+
|
|
171
|
+
### Pass 4: Review And Fixing
|
|
172
|
+
|
|
173
|
+
Review focus:
|
|
174
|
+
|
|
175
|
+
- Type correctness around synthetic `Memory` construction and `messageService.handleMessage`.
|
|
176
|
+
- Session allow-list behavior for virtual brokers.
|
|
177
|
+
- Whether all ACP agent types can see `SKILLS.md` and parent memory text.
|
|
178
|
+
- Whether tracked `AGENTS.md` repos need a safer memory-file strategy than writing in the workspace root.
|
|
179
|
+
- Whether OpenCode's vendored ACP path has enough smoke coverage against Cerebras.
|
|
180
|
+
|
|
181
|
+
Status: partially implemented. The first three are covered by code/tests; live OpenCode/Cerebras validation remains credential-gated.
|
|
182
|
+
|
|
183
|
+
### Pass 5: Testing, Verification, Validation
|
|
184
|
+
|
|
185
|
+
Minimum local tests:
|
|
186
|
+
|
|
187
|
+
- unit test `parent-agent` broker list-actions, missing request, and message pipeline callback capture
|
|
188
|
+
- unit test `USE_SKILL` directive parsing and sensitive broker routing if practical
|
|
189
|
+
- typecheck `plugin-agent-orchestrator`
|
|
190
|
+
- test `packages/skills` loader/frontmatter paths
|
|
191
|
+
- run `scripts/ensure-skills.mjs` against a temporary `ELIZA_STATE_DIR`
|
|
192
|
+
|
|
193
|
+
Live validation:
|
|
194
|
+
|
|
195
|
+
- Start a parent Eliza runtime with agent skills and orchestrator loaded.
|
|
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 ...`.
|
|
198
|
+
- Simulate:
|
|
199
|
+
- action listing
|
|
200
|
+
- parent memory search
|
|
201
|
+
- calendar/GitHub/browser-style parent request
|
|
202
|
+
- confirmation-required paid Cloud/domain request
|
|
203
|
+
- denied broker when not allow-listed
|
|
204
|
+
- task continuation after a returned parent result
|
|
205
|
+
- Run existing SWE/orchestrator benchmarks with and without the broker skill hint.
|
|
206
|
+
|
|
207
|
+
Status: local unit/type/skills tests are implemented and passing. Live OpenCode/Cerebras/SWE benchmarking requires running services and credentials, so it remains follow-up unless the environment already has them active.
|
|
208
|
+
|
|
209
|
+
## Remaining Gaps
|
|
210
|
+
|
|
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.
|
|
212
|
+
- Live agent benchmarking against OpenCode + Eliza Cloud + Cerebras requires credentials and running infrastructure.
|
|
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.
|
|
214
|
+
|
|
215
|
+
## AGI-Level Direction
|
|
216
|
+
|
|
217
|
+
The long-term target is not a hardcoded "agent helper" action. It is a capability broker:
|
|
218
|
+
|
|
219
|
+
- the parent runtime exposes a typed capability graph derived from loaded plugins, actions, providers, services, connectors, and policies
|
|
220
|
+
- workers receive task-scoped manifests and can request capabilities without knowing implementation details
|
|
221
|
+
- the parent decides whether to answer, execute, request confirmation, redact, or deny
|
|
222
|
+
- applications override skills and policies by configuration rather than editing orchestrator code
|
|
223
|
+
- benchmarks measure whether workers solve more repo tasks with fewer human interventions and fewer credential leaks
|
|
224
|
+
|
|
225
|
+
The current implementation establishes the default skill surface and the child-to-parent request path needed for that architecture.
|
|
@@ -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.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Multi-account coding-agent orchestration
|
|
2
|
+
|
|
3
|
+
Goal: an Eliza orchestrator agent that runs **multiple Claude Code + Codex
|
|
4
|
+
subscriptions** (and rotates OpenCode across pooled Cerebras accounts), picks
|
|
5
|
+
the **least-used** account for each new
|
|
6
|
+
sub-agent, tracks per-account **session + weekly usage**, manages those
|
|
7
|
+
sub-agents in a **shared task room**, and decides **when to interrupt** a
|
|
8
|
+
running sub-agent vs. let it keep working.
|
|
9
|
+
|
|
10
|
+
## What already existed (do not rebuild)
|
|
11
|
+
|
|
12
|
+
| Layer | Location | Status |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| Account contracts (`LinkedAccountConfig`, `LinkedAccountUsage`, 12 provider ids) | `packages/contracts/src/service-routing.ts` | ✅ |
|
|
15
|
+
| Credential storage (`<stateDir>/auth/{providerId}/{accountId}.json`) | `packages/agent/src/auth/account-storage.ts` | ✅ |
|
|
16
|
+
| OAuth flows (Anthropic + Codex) + coding-plan keys + API keys | `packages/agent/src/auth/oauth-flow.ts`, `credentials.ts` | ✅ |
|
|
17
|
+
| `AccountPool` — priority / round-robin / **least-used** / quota-aware, affinity, health | `packages/app-core/src/services/account-pool.ts` | ✅ |
|
|
18
|
+
| Usage probes (`pollAnthropicUsage`, `pollCodexUsage`) + JSONL day counters | `packages/app-core/src/services/account-usage.ts` | ✅ |
|
|
19
|
+
| Accounts REST API (`/api/accounts/*` incl. OAuth SSE) | `packages/agent/src/api/accounts-routes.ts` | ✅ |
|
|
20
|
+
| Settings UI (AccountList / AccountCard / AddAccountDialog / RotationStrategyPicker) + `useAccounts` | `packages/ui/src/components/accounts/*` | ✅ |
|
|
21
|
+
| Multi-account API-key routing for the *main agent* | `credential-resolver.ts` → `resolveProviderCredentialMulti` | ✅ |
|
|
22
|
+
| Orchestrator tasks, sessions, task-rooms, event bridge, usage rollup, REST + SSE | `plugins/plugin-agent-orchestrator/*` | ✅ |
|
|
23
|
+
| `shouldRespond` (RESPOND/IGNORE/STOP) + per-room `TurnControllerRegistry` abort | `packages/core/src/*` | ✅ |
|
|
24
|
+
|
|
25
|
+
## The keystone gap
|
|
26
|
+
|
|
27
|
+
The `AccountPool` was wired into **API-key model routing** but **not into the
|
|
28
|
+
coding-agent spawn path**. Coding agents authenticate by *subscription*, not API
|
|
29
|
+
key: `applySubscriptionCredentialsLocal` never injects Claude/Codex tokens into
|
|
30
|
+
`process.env`, and `AcpService.buildEnv` even *strips* an OAuth
|
|
31
|
+
`ANTHROPIC_API_KEY` so Claude Code falls back to the single machine login
|
|
32
|
+
(`~/.claude`). So every spawned sub-agent used one account, with no rotation and
|
|
33
|
+
no per-account attribution.
|
|
34
|
+
|
|
35
|
+
The orchestrator plugin depends only on `@elizaos/core`, so it cannot import the
|
|
36
|
+
pool. `account-pool.ts` already solves this with `globalThis`-symbol **bridges**
|
|
37
|
+
(Anthropic + subscription-selector). We add a third: a **coding-agent selector
|
|
38
|
+
bridge**.
|
|
39
|
+
|
|
40
|
+
## Hitlist
|
|
41
|
+
|
|
42
|
+
### P0 — Keystone: account selection on spawn (round-robin / least-used)
|
|
43
|
+
- [x] `coding-account-bridge.ts` (app-core): install `Symbol.for("eliza.account-pool.coding-agent.v1")` bridge — `select(agentType)`, `markRateLimited`, `markNeedsReauth`, `recordUsage`, `describe()`.
|
|
44
|
+
- [x] Per-agent credential injection: claude → `CLAUDE_CODE_OAUTH_TOKEN`; codex → per-account `CODEX_HOME/auth.json` + minimal `config.toml`; opencode → `CEREBRAS_API_KEY` (pooled Cerebras); direct API providers → their env key.
|
|
45
|
+
- [x] Wire into `AcpService.spawnSession`: select before transport branch, merge `envPatch` into `customCredentials`, stamp `session.metadata.account*`, surface on `SpawnResult.metadata`.
|
|
46
|
+
- [x] `buildEnv`: when `CLAUDE_CODE_OAUTH_TOKEN` is injected for claude, drop `ANTHROPIC_API_KEY` so the selected subscription wins.
|
|
47
|
+
- [x] `OrchestratorTaskSession` carries `accountProviderId` / `accountId` / `accountLabel`; populate from `result.metadata`.
|
|
48
|
+
- [x] Exclude-on-failure retry: on auth/rate-limit error, mark account + re-select excluding it.
|
|
49
|
+
|
|
50
|
+
### P1 — Usage attribution + stats
|
|
51
|
+
- [x] `recordUsage` also calls the bridge → pool `recordCall` + `account-usage` JSONL keyed by the serving account.
|
|
52
|
+
- [x] `/api/orchestrator/accounts` route: connected accounts + live usage + which sub-agents are on which account.
|
|
53
|
+
- [x] Settings already shows per-account usage; orchestrator dashboard widget adds the accounts + usage summary.
|
|
54
|
+
|
|
55
|
+
### P2 — Room system + interruption decider
|
|
56
|
+
- [x] Per-participant interruption decider: a running sub-agent keeps working; a new room message is classified (deliver / queue / interrupt / ignore) before it is injected. The "busy" check covers `tool_running` (the dominant mid-turn state), not just `busy`; queued messages flush when the session returns to `ready`. An Eliza participant's `shouldRespond` verdict threads through unchanged when a caller supplies it; coding sub-agents use the structural decider. `multiParty` (more than one live sub-agent in the room) is computed in the forward handler so ambient-chatter suppression is live.
|
|
57
|
+
- [x] Task-room participant **view**: the "Coding accounts" sidebar widget shows the live sub-agent → account assignment map + per-account usage (the flat global map). The dedicated per-room participant roster (orchestrator + owning user + each sub-agent grouped by room, with `activeAgentCount` / `multiParty`) now ships as `GET /api/orchestrator/rooms` (`OrchestratorTaskService.getRoomRoster`), the room-scoped counterpart to `/accounts`. Rooms with no sub-agent sessions are omitted.
|
|
58
|
+
|
|
59
|
+
### P3 — Tests + mocks + live E2E
|
|
60
|
+
- [x] Mock account fixtures (multi-account, multi-provider) + an in-memory pool for unit tests.
|
|
61
|
+
- [x] Unit tests: selection strategy, per-agent env injection + API-key drop (Claude & Codex), intra-provider retry, usage attribution, interruption decider, route registration.
|
|
62
|
+
- [x] Live E2E (gated `ORCHESTRATOR_LIVE_MULTI_ACCOUNT=1`): validates the selector bridge + usage probe against ≥2 **real** linked accounts (distinct-account rotation via the exclude set; live session/weekly usage).
|
|
63
|
+
- [x] **Composed offline E2E** (`bun run --cwd plugins/plugin-agent-orchestrator test:e2e:multi-account`): real app-core `AccountPool` (real-format mock accounts in a temp state dir) → installed selector bridge → orchestrator `AcpService.spawnSession` → a REAL spawned subprocess (a fake "acpx" standing in for the subscription CLI). Asserts 10/10: two Claude spawns pick **distinct** accounts (least-used round-robin), each subprocess receives its account's `CLAUDE_CODE_OAUTH_TOKEN`, the parent `ANTHROPIC_API_KEY`/`OPENAI_API_KEY` are dropped, Codex gets a per-account `CODEX_HOME/auth.json` with the right token+account_id. Point `ELIZA_ACP_CLI` at the real binary + connect real accounts for true live-key validation. (This harness caught a real cli-transport bug: `runAcpx` rebuilt the env without `agentType`, re-adding the parent keys — now fixed.)
|
|
64
|
+
|
|
65
|
+
### P4 — Connect-accounts window
|
|
66
|
+
- [x] The connect-accounts window (Settings → Accounts: `AddAccountDialog` OAuth / API-key / coding-plan-key flows, `AccountList`, `RotationStrategyPicker`) pre-exists and is the surface for linking multiple accounts of each type.
|
|
67
|
+
|
|
68
|
+
## Known constraints / follow-ups
|
|
69
|
+
- **OpenCode pool-rotates across Cerebras accounts only.** OpenCode resolves a pooled key for exactly one backend — Cerebras (`CEREBRAS_API_KEY`, see `buildOpencodeSpawnConfig`) — so `opencode` is a multi-account selector type mapped to `cerebras-api`: it least-used-rotates across linked Cerebras accounts (the bridge injects the selected `CEREBRAS_API_KEY`, which OpenCode's config reads) and no-ops when none are linked (Eliza Cloud / single-key setups are unchanged). OpenCode's other backends (Eliza Cloud, local, user-configured opencode.json) are not pooled. Precedence: a `CEREBRAS_API_KEY` runtime **setting** still wins over a pooled injection — pooling is authoritative only when no single key is configured.
|
|
70
|
+
- **z.ai / Kimi / GLM have no first-party coding CLI.** Their linked accounts serve the main runtime's API-key routing (`resolveProviderCredentialMulti` for `zai-api` / `moonshot-api`) and OpenCode's provider config — there is no `zai`/`kimi`/`glm` spawnable agent type, so they are not advertised as coding-agent selector candidates.
|
|
71
|
+
|
|
72
|
+
## Quality bar
|
|
73
|
+
- No regression when zero accounts are linked (bridge returns null → today's behavior).
|
|
74
|
+
- Selected account is **observable** (session metadata + structured log + dashboard), never assumed.
|
|
75
|
+
- Subscription tokens only ever flow to the first-party coding subprocess (TOS), never into runtime `process.env`.
|
|
76
|
+
- Per-agent credential precedence is enforced: a selected Claude subscription drops `ANTHROPIC_API_KEY`; a selected Codex subscription (per-account `CODEX_HOME`) drops a forwarded `OPENAI_API_KEY` — so the chosen account always authenticates.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Orchestrator (`/orchestrator`) build-out — status & follow-ups
|
|
2
|
+
|
|
3
|
+
Date: 2026-05-29. Companion to [`research/orchestrator-view-research-report.md`](./research/orchestrator-view-research-report.md).
|
|
4
|
+
|
|
5
|
+
This records what was finished in the `nubs/orchestrator-view-feature` branch and the
|
|
6
|
+
exact, code-grounded plan for the remaining design-heavy work. The earlier research
|
|
7
|
+
report is largely **out of date**: the durable task model, SQL store, `/api/orchestrator/*`
|
|
8
|
+
routes, central goal-wrapper, validation-gated completion, token aggregation, the
|
|
9
|
+
`OrchestratorWorkbench` view, and the real (non-stub) client methods all already exist
|
|
10
|
+
(Shaw shipped most of it on 2026-05-29). Verify against current code, not the report's
|
|
11
|
+
line numbers.
|
|
12
|
+
|
|
13
|
+
## Done in this branch (verified)
|
|
14
|
+
|
|
15
|
+
1. **Mounted the sub-agent credential bridge** (`plugin-agent-orchestrator/src/api/routes.ts`).
|
|
16
|
+
`handleBridgeRoutes` was built+tested but never dispatched. + dispatcher regression test.
|
|
17
|
+
2. **Unified the goal-wrapper** so the `TASKS` planner action uses the central
|
|
18
|
+
`buildGoalPrompt`/`buildGoalFollowUp` (`goal-prompt.ts`, `actions/tasks.ts`) instead of a
|
|
19
|
+
divergent inline envelope. Workspace-routing / URL-mapping / swarm-room content preserved
|
|
20
|
+
via new optional `GoalPromptInput` fields. + equivalence test (action env == API env).
|
|
21
|
+
3. **Folded durable task threads into `getCodingAgentStatus`** (`packages/ui` client) — was
|
|
22
|
+
hardcoded to `taskThreadCount:0`. Documented the two genuinely-vestigial ACP stubs
|
|
23
|
+
(`/metrics`, `/workspace-files`) pointing at the real `/api/orchestrator/*` usage surface.
|
|
24
|
+
4. **Declared capability param schemas** for the 15 orchestrator view capabilities so
|
|
25
|
+
voice/NL routing can pass `taskId`/`title`/`goal`/etc. **Mounted the sensitive-request
|
|
26
|
+
REST routes** (`packages/app-core/src/api/server.ts`) — the secret create/submit/fulfill
|
|
27
|
+
path that orchestrator provider setup will use.
|
|
28
|
+
5. **Locked capability manifest↔dispatch parity** with a regression test
|
|
29
|
+
(`plugin-task-coordinator/__tests__/unit/orchestrator-capability-parity.test.ts`) + a
|
|
30
|
+
`test` script so CI runs it. The declared capabilities (`ORCHESTRATOR_CAPABILITIES` in
|
|
31
|
+
`index.ts`) must exactly match the ids `runOrchestratorCapability` dispatches; this drift
|
|
32
|
+
previously reopened (`orchestrator-update-task`/`-validate-task`).
|
|
33
|
+
|
|
34
|
+
## App-shell hardening (this branch)
|
|
35
|
+
|
|
36
|
+
**Stale/unreachable saved server can no longer wedge first-run.** A persisted
|
|
37
|
+
`elizaos:active-server` pointing at a now-dead / CSP-blocked remote backend pinned the
|
|
38
|
+
client to that address; the startup poll (`packages/ui/src/state/startup-phase-poll.ts`)
|
|
39
|
+
retried it until `BACKEND_TIMEOUT` and onboarding hung forever (clearing cookies didn't
|
|
40
|
+
help — the pointer lives in localStorage). Fix: on a *connection-level* failure (the request
|
|
41
|
+
never received an HTTP response) against a non-loopback, non-same-origin base on an http(s)
|
|
42
|
+
page — never on native mobile, where the remote IS the agent — clear the saved server,
|
|
43
|
+
re-point the client at the local origin, and reach the backend (one-shot). The decision is a
|
|
44
|
+
pure exported `shouldFallBackToLocalOrigin` covered by a unit matrix, plus an end-to-end
|
|
45
|
+
recovery test.
|
|
46
|
+
|
|
47
|
+
**Onboarding boot issues we hit that are environmental, not code bugs (no regression test
|
|
48
|
+
applies):**
|
|
49
|
+
- *"No provider registered for TEXT_EMBEDDING" → agent won't boot* — caused by a local
|
|
50
|
+
`ELIZA_DISABLE_LOCAL_EMBEDDINGS=1` in `.env.worktree` with no cloud route, i.e. *zero*
|
|
51
|
+
embedding providers. With local embeddings enabled the agent boots degraded-but-non-fatal
|
|
52
|
+
(the intended behavior). A graceful-degradation guard for the "no embedding provider at
|
|
53
|
+
all" edge would live in agent/runtime bootstrap, not here; flagged for the runtime owner.
|
|
54
|
+
- *Dev service-worker / HTTPS-upgrade theories* — investigated and **disproven** by
|
|
55
|
+
reproduction; the actual cause was the stale active-server above. The dev SW renders fine
|
|
56
|
+
with caching active. An optional dev-only self-unregistering SW remains available as a
|
|
57
|
+
hygiene improvement but guards no confirmed bug.
|
|
58
|
+
|
|
59
|
+
## Remaining work (specced, not yet built)
|
|
60
|
+
|
|
61
|
+
Ordered by leverage. `[BE]` backend, `[FE]` frontend, `[T]` tests.
|
|
62
|
+
|
|
63
|
+
### A. `orchestrator-open-task` should navigate the workbench `[FE]` — S/M
|
|
64
|
+
`runOrchestratorCapability` ("open-task") fetches detail but does not call `setSelectedId`,
|
|
65
|
+
so a voice "open task X" returns data without visually navigating. `interact()` is a
|
|
66
|
+
module-level function with no handle to the live component state. Fix: have the workbench
|
|
67
|
+
register a navigation callback (e.g. a module-scoped `setSelectedTaskHandler` the mounted
|
|
68
|
+
`OrchestratorWorkbench` sets in a `useEffect`, called by the open-task capability), or route
|
|
69
|
+
selection through the existing `?task=` deep-link that `readInitialTaskId` already reads.
|
|
70
|
+
|
|
71
|
+
### B. Bridge-backed provider setup `[BE][FE]` — M (design-touching)
|
|
72
|
+
Today `LlmProviderSection`/`CodingAgentSettingsSection` write `ANTHROPIC_API_KEY` etc.
|
|
73
|
+
straight into agent env via `client.updateConfig({ env })` — not the vault. Now that the
|
|
74
|
+
sensitive-request REST routes are mounted, wire missing-key flows to fire `SECRETS
|
|
75
|
+
action=request` (or POST `/api/sensitive-requests`) so secrets land in `sharedVault`. Reuse
|
|
76
|
+
the existing `ProviderCard`/`ProviderPanels`/`useProviderSelection` components rather than the
|
|
77
|
+
bespoke password inputs. Needs a decision on which providers/scopes/validation; do not change
|
|
78
|
+
secret-storage policy without the design owner. Secure-cloud / secure-local / insecure-local
|
|
79
|
+
fallbacks + redaction tests per the report's "Secret And OAuth Flow" section.
|
|
80
|
+
|
|
81
|
+
### C. Workbench UX gaps `[FE]` — small each, need visual iteration
|
|
82
|
+
From the fidelity review of `OrchestratorWorkbench.tsx` (largely complete; these are the gaps):
|
|
83
|
+
- **Jump-to-latest / autoscroll** in the timeline — no scroll ref/affordance today (net-new).
|
|
84
|
+
- **Change-provider control** — no UI and no `orchestrator-change-provider` capability/backend; provider policy is read-only. Needs a backend capability first.
|
|
85
|
+
- **Branch display** in the sub-agent roster (only repo/workdir shown).
|
|
86
|
+
- **System-event collapse**: only a global show/hide toggle, not expandable clusters.
|
|
87
|
+
- **Verification checklist**: only per-artifact status pills, no dedicated pass/fail surface.
|
|
88
|
+
- **Per-task USD spend** in the left rail (rail shows tokens; cost only in header + inspector).
|
|
89
|
+
- **Provider "state"**: shows policy/identity, not live health/availability.
|
|
90
|
+
|
|
91
|
+
### D. Remote / mobile for the orchestrator `[BE][FE]` — L (separate design)
|
|
92
|
+
Pairing primitives exist (`auth-pairing-routes`, `tunnel-to-mobile-client`) but **no `tunnel`
|
|
93
|
+
runtime service is registered** (so `runtime.getService("tunnel")` lookups and
|
|
94
|
+
`tunnel_authenticated_link` delivery are inert). The workbench is **polling-only**
|
|
95
|
+
(`POLL_INTERVAL_MS = 5000`); there is no SSE/WS for task updates. Needs: a registered tunnel
|
|
96
|
+
service (`getStatus/isActive/getUrl`), a relay decision (cloud gateway vs Headscale/ngrok per
|
|
97
|
+
the tunnel-to-mobile design), remote-API auth, and SSE/WS to replace the 5s poll so remote/
|
|
98
|
+
mobile clients aren't hammering. Do not attempt blind — design + visual iteration required.
|
|
99
|
+
|
|
100
|
+
### E. Test depth `[T]`
|
|
101
|
+
Add the report's e2e workflow matrix with mocked providers (create/fork/pause-all/archive/
|
|
102
|
+
search/secret-flows/validation-failure-reopen), keeping live Claude/Codex tests env-gated.
|
|
103
|
+
Also add an integration-level test that drives a `/credentials/*` request through the runtime
|
|
104
|
+
route matcher (`matchPluginRoutePath`), not just the in-process dispatcher, so the
|
|
105
|
+
registry-registration gap (fixed in this branch) can't silently reopen.
|
|
106
|
+
|
|
107
|
+
### F. Deferred from adversarial review (low priority, not regressions)
|
|
108
|
+
- **Bridge loopback hardening** `[BE]` — `bridge-routes.ts:isLoopback` trusts only
|
|
109
|
+
`req.socket.remoteAddress` (same model as the existing parent-context bridge). If the
|
|
110
|
+
runtime is ever fronted by a loopback-bound reverse proxy, mirror the extra checks from
|
|
111
|
+
`isTrustedLocalRequest` (reject forwarded/proxy-client headers and cross-site
|
|
112
|
+
`sec-fetch-site`). The single-use scopedToken remains the per-request defense regardless.
|
|
113
|
+
- **Re-anchor follow-ups to the durable goal** `[BE]` — `buildGoalFollowUp` reads
|
|
114
|
+
`metadata.goal`, but the planner spawn paths in `tasks.ts` never stamp a `goal` key, so
|
|
115
|
+
follow-ups currently re-anchor to the latest message rather than the original objective.
|
|
116
|
+
Stash `goal: task` (or the durable goal) onto session metadata at spawn time to realize
|
|
117
|
+
the intended re-anchoring. Not a regression — the old code sent raw text.
|
|
118
|
+
|
|
119
|
+
## How to work this branch
|
|
120
|
+
Isolated worktree `/home/nubs/Git/iqlabs/eliza-labs/eliza-orchestrator-feat`, branch
|
|
121
|
+
`nubs/orchestrator-view-feature`. Fresh worktrees need `@elizaos/core` built first
|
|
122
|
+
(`cd packages/core && bun run build`) or vitest can't resolve `@elizaos/core`; building the
|
|
123
|
+
full plugin set is required to run app-core integration tests. Rebase onto the active branch
|
|
124
|
+
before merging (file sets don't overlap with the desktop/local-inference work in flight).
|