@mono-agent/agent-runtime 0.20.11 → 0.20.14
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/MIGRATION.md +264 -25
- package/README.md +139 -448
- package/package.json +7 -43
- package/src/agent/tools/agent-tool.js +5 -5
- package/src/agent/tools/bash.js +1 -24
- package/src/agent/tools/codex-subscription-search.js +1 -1
- package/src/agent/tools/index.js +7 -0
- package/src/agent/tools/monitor.js +140 -0
- package/src/agent/tools/pi-bridge.js +92 -7
- package/src/agent/tools/shared/bash-environment.js +31 -0
- package/src/agent/tools/shared/monitors.js +274 -0
- package/src/agent/tools/shared/process-runner.js +23 -5
- package/src/ai/cost.js +13 -68
- package/src/ai/index.js +4 -17
- package/src/ai/pi-interop.js +65 -1
- package/src/ai/pi-oauth-compat.js +1 -1
- package/src/ai/providers/codex/app-server-client.js +592 -0
- package/src/ai/providers/pi-models.js +18 -10
- package/src/ai/providers/pi-native/compaction-driver.js +49 -21
- package/src/ai/providers/pi-native/harness-adapter.js +338 -0
- package/src/ai/providers/pi-native/result-builder.js +10 -10
- package/src/ai/providers/pi-native/session-lifecycle.js +95 -40
- package/src/ai/providers/pi-native/stream-subscriber.js +23 -5
- package/src/ai/providers/pi-native/turn-runner.js +34 -15
- package/src/ai/providers/pi-native.js +48 -22
- package/src/ai/runtime/capabilities.js +11 -56
- package/src/ai/runtime/model-refs.js +118 -153
- package/src/ai/runtime/registry.js +22 -56
- package/src/ai/runtime/router.js +48 -408
- package/src/ai/runtime/session-liveness.js +3 -4
- package/src/ai/runtime/sessions.js +4 -5
- package/src/ai/runtime/tool-policy.js +0 -2
- package/src/ai/types.js +12 -108
- package/src/index.js +0 -6
- package/src/runtime.js +8 -14
- package/types/agent/tools/agent-tool.d.ts +1 -2
- package/types/agent/tools/codex-subscription-search.d.ts +1 -1
- package/types/agent/tools/index.d.ts +1 -0
- package/types/agent/tools/monitor.d.ts +44 -0
- package/types/agent/tools/pi-bridge.d.ts +3 -2
- package/types/agent/tools/shared/bash-environment.d.ts +4 -0
- package/types/agent/tools/shared/monitors.d.ts +83 -0
- package/types/agent/tools/shared/process-runner.d.ts +11 -2
- package/types/ai/cost.d.ts +1 -2
- package/types/ai/index.d.ts +1 -4
- package/types/ai/pi-interop.d.ts +20 -0
- package/types/ai/providers/codex/app-server-client.d.ts +37 -0
- package/types/ai/providers/pi-native/harness-adapter.d.ts +56 -0
- package/types/ai/providers/pi-native/result-builder.d.ts +3 -3
- package/types/ai/providers/pi-native/session-lifecycle.d.ts +2 -1
- package/types/ai/providers/pi-native/stream-subscriber.d.ts +2 -2
- package/types/ai/providers/pi-native/turn-runner.d.ts +33 -6
- package/types/ai/providers/pi-native.d.ts +21 -4
- package/types/ai/runtime/capabilities.d.ts +21 -70
- package/types/ai/runtime/model-refs.d.ts +0 -24
- package/types/ai/runtime/router.d.ts +3 -10
- package/types/ai/runtime/tool-policy.d.ts +0 -2
- package/types/ai/types.d.ts +28 -250
- package/types/index.d.ts +0 -1
- package/src/ai/providers/acp-client.js +0 -1149
- package/src/ai/providers/acp-privacy.js +0 -124
- package/src/ai/providers/acp-public.js +0 -21
- package/src/ai/providers/acp-session-tokens.js +0 -282
- package/src/ai/providers/acp-transport.js +0 -356
- package/src/ai/providers/acp.js +0 -543
- package/src/ai/providers/claude-cli.js +0 -883
- package/src/ai/providers/claude-sandbox.js +0 -71
- package/src/ai/providers/claude-sdk-discovery-worker.js +0 -53
- package/src/ai/providers/claude-sdk-discovery.js +0 -352
- package/src/ai/providers/claude-sdk.js +0 -1127
- package/src/ai/providers/claude-subagent-activity.js +0 -719
- package/src/ai/providers/claude-subagents.js +0 -88
- package/src/ai/providers/codex-app.js +0 -2946
- package/src/ai/providers/opencode-app.js +0 -1109
- package/src/ai/providers/opencode-discovery.js +0 -39
- package/src/ai/providers/opencode-server.js +0 -508
- package/src/ai/runtime/context-windows.js +0 -46
- package/src/ai/runtime/fast-mode.js +0 -8
- package/src/ai/streaming/codex-events.js +0 -146
- package/src/ai/streaming/opencode-events.js +0 -59
- package/types/ai/providers/acp-client.d.ts +0 -227
- package/types/ai/providers/acp-privacy.d.ts +0 -25
- package/types/ai/providers/acp-public.d.ts +0 -7
- package/types/ai/providers/acp-session-tokens.d.ts +0 -41
- package/types/ai/providers/acp-transport.d.ts +0 -45
- package/types/ai/providers/acp.d.ts +0 -93
- package/types/ai/providers/claude-cli.d.ts +0 -305
- package/types/ai/providers/claude-sandbox.d.ts +0 -79
- package/types/ai/providers/claude-sdk-discovery-worker.d.ts +0 -1
- package/types/ai/providers/claude-sdk-discovery.d.ts +0 -97
- package/types/ai/providers/claude-sdk.d.ts +0 -138
- package/types/ai/providers/claude-subagent-activity.d.ts +0 -53
- package/types/ai/providers/claude-subagents.d.ts +0 -18
- package/types/ai/providers/codex-app.d.ts +0 -151
- package/types/ai/providers/opencode-app.d.ts +0 -96
- package/types/ai/providers/opencode-discovery.d.ts +0 -4
- package/types/ai/providers/opencode-server.d.ts +0 -20
- package/types/ai/runtime/context-windows.d.ts +0 -9
- package/types/ai/runtime/fast-mode.d.ts +0 -2
- package/types/ai/streaming/codex-events.d.ts +0 -40
- package/types/ai/streaming/opencode-events.d.ts +0 -42
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @mono-agent/agent-runtime
|
|
2
2
|
|
|
3
3
|
Use this package when you need direct, capability-aware access to mono-agent's
|
|
4
|
-
|
|
4
|
+
Pi runtime and the ~39 providers it reaches.
|
|
5
5
|
|
|
6
6
|
## Category
|
|
7
7
|
|
|
@@ -10,13 +10,13 @@ six built-in model runtime bridges, including product-neutral ACP v1 agents.
|
|
|
10
10
|
|
|
11
11
|
Category: `runtime`
|
|
12
12
|
Tier: `core`
|
|
13
|
-
Catalog responsibility: Provides
|
|
13
|
+
Catalog responsibility: Provides the Pi SDK runtime bridge with native tools, MCP, sessions, compaction, and provider-catalog integration.
|
|
14
14
|
|
|
15
15
|
<!-- package-metadata:end -->
|
|
16
16
|
|
|
17
17
|
## Responsibility
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Implements the Pi runtime. This is the runtime layer that `@mono-agent/runtime-adapter` wraps behind runtime contracts. Pi-owned stdio children enforce optional mono-agent sandbox policy through an injectable `RuntimeSandbox` seam (a fail-closed passthrough by default; `@mono-agent/runtime-adapter` injects the real implementation). Every route in a fallback chain is Pi-native and shares one contract; no route silently drops required capabilities.
|
|
20
20
|
|
|
21
21
|
## Install / Usage
|
|
22
22
|
|
|
@@ -24,10 +24,8 @@ Provides six runtime bridges (ACP v1, Claude SDK, Claude Code CLI, Codex app-ser
|
|
|
24
24
|
pnpm add @mono-agent/agent-runtime
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Node.js 22.19 or newer is required.
|
|
28
|
-
|
|
29
|
-
requires stable OpenCode 1.15.0 or newer. SDK-only Claude and Pi runs do not
|
|
30
|
-
spawn those CLIs.
|
|
27
|
+
Node.js 22.19 or newer is required. Pi is the only runtime, and it talks to
|
|
28
|
+
providers over their SDKs, so no provider CLI has to be on `PATH`.
|
|
31
29
|
|
|
32
30
|
Create one runtime for a host, parse a model reference, and run a turn:
|
|
33
31
|
|
|
@@ -39,8 +37,7 @@ import {
|
|
|
39
37
|
|
|
40
38
|
const runtime = createRuntime({ workspace: process.cwd() });
|
|
41
39
|
const result = await runtime.run("You are a concise repository assistant.", {
|
|
42
|
-
model: parseRuntimeModelReference("
|
|
43
|
-
executionMode: "sdk",
|
|
40
|
+
model: parseRuntimeModelReference("anthropic:claude-sonnet-4-6"),
|
|
44
41
|
messages: [{ role: "user", content: "Summarize README.md." }],
|
|
45
42
|
cwd: process.cwd(),
|
|
46
43
|
allowedTools: ["Read"],
|
|
@@ -61,8 +58,7 @@ capability. The host then explicitly intersects the two reviewed protocol
|
|
|
61
58
|
revisions, reads only the originating tool's declared `ui://` resource, and
|
|
62
59
|
receives one exact connection capability. Successful registration retains that
|
|
63
60
|
existing MCP client instead of creating a client per UI call; host LRU/idle
|
|
64
|
-
eviction closes the client, transport, and sandbox cleanup.
|
|
65
|
-
backends do not advertise or receive this extension.
|
|
61
|
+
eviction closes the client, transport, and sandbox cleanup.
|
|
66
62
|
See [Reply files and MCP Apps](https://mono-agent-docs.vercel.app/tools/rich-replies/).
|
|
67
63
|
|
|
68
64
|
## Architecture
|
|
@@ -73,7 +69,7 @@ only after a run selects a matching model reference and execution mode:
|
|
|
73
69
|
### Data flow
|
|
74
70
|
|
|
75
71
|
1. `createRuntime()` binds host callbacks and creates an isolated tool context.
|
|
76
|
-
2. `resolveRuntimeBridge()`
|
|
72
|
+
2. `resolveRuntimeBridge()` resolves the single static bridge descriptor.
|
|
77
73
|
3. The selected descriptor lazily imports its provider implementation.
|
|
78
74
|
4. The bridge prepares the runtime inputs it supports, including managed or MCP
|
|
79
75
|
tools only where that bridge can represent them, and streams normalized
|
|
@@ -91,7 +87,7 @@ only after a run selects a matching model reference and execution mode:
|
|
|
91
87
|
| --- | --- |
|
|
92
88
|
| `src/runtime.js` | Host binding, per-instance tool context, bridge dispatch, and observer flushing |
|
|
93
89
|
| `src/ai/runtime/` | Model-reference parsing, the lazy bridge registry, capabilities, sessions, and fallback routing |
|
|
94
|
-
| `src/ai/providers/` |
|
|
90
|
+
| `src/ai/providers/` | Pi provider integrations |
|
|
95
91
|
| `src/agent/tools/` | Managed tools, MCP adaptation, output limits, and the injectable sandbox seam |
|
|
96
92
|
| `src/agent/` | Approvals, allowlists, transcript snapshots, and compaction policy helpers |
|
|
97
93
|
|
|
@@ -114,11 +110,6 @@ actually supplies:
|
|
|
114
110
|
| Bridge | Genuine tool-result distinctions | Conservative fallback |
|
|
115
111
|
| --- | --- | --- |
|
|
116
112
|
| Pi native | `success`, `error`, numeric `exit_nonzero`, structured `timeout`, structured `signal`, and abort-backed `cancelled`; host approval denial/expiry adds `rejected`/`timeout` | Unknown failed outcome → `error` |
|
|
117
|
-
| Codex app-server | `success`, `error`, and numeric command `exit_nonzero`; shared host abort rules still apply | Other failed item → `error`; no result before run end remains dangling for host closure/recovery |
|
|
118
|
-
| Claude SDK | `success` / `error`; shared host approval events can add `rejected`/`timeout` and an aborted error result can add `cancelled` | Undistinguished failed result → `error` |
|
|
119
|
-
| Claude Code CLI | `success` / `error`; a Codex-shaped command item with an explicit non-zero code is `exit_nonzero`; shared approval/abort rules still apply | Undistinguished failed result → `error` |
|
|
120
|
-
| OpenCode app-server | `success` / `error`; shared approval/abort rules still apply | Undistinguished failed result → `error` |
|
|
121
|
-
| ACP v1 | `completed` → `success`, `failed` → `error`; shared approval/abort rules still apply | ACP exposes no tool-level signal/exit/timeout distinction, so failed → `error` |
|
|
122
113
|
|
|
123
114
|
The runtime never derives a state from result prose. Structured timeout, signal,
|
|
124
115
|
non-zero exit, completed success, and a specific non-runtime, non-cancellation
|
|
@@ -157,10 +148,9 @@ provider-supplied known kind when available and otherwise `runtime_error`.
|
|
|
157
148
|
| API | Use it for |
|
|
158
149
|
| --- | --- |
|
|
159
150
|
| `createRuntime()` | Run one model bridge with host-owned credentials, observers, tools, and lifecycle callbacks |
|
|
160
|
-
| `probeAcpProfile()` / ACP management helpers | Probe, authenticate, log out, list sessions, validate opaque handles, or delete an ACP provider session |
|
|
161
151
|
| `createRouterRuntime()` | Retry an ordered model chain while preserving explicit route-safety contracts |
|
|
162
|
-
| `parseRuntimeModelReference()` | Convert a canonical
|
|
163
|
-
| `listRuntimeBridges()` / `runtimeCapabilities()` | Inspect the
|
|
152
|
+
| `parseRuntimeModelReference()` | Convert a canonical `<provider>:<model>` string into the object required by `run()` |
|
|
153
|
+
| `listRuntimeBridges()` / `runtimeCapabilities()` | Inspect the built-in bridge descriptor without loading provider implementations |
|
|
164
154
|
| `createPiOAuthApiKeyResolver()` | Bind a host-owned Pi auth file with refresh-safe writes |
|
|
165
155
|
| `listPiBuiltinModels()` / `getPiBuiltinModel()` | Read cloned snapshots from the runtime-owned, exact-pinned Pi model catalog without importing Pi directly |
|
|
166
156
|
| `resolvePiOAuthApiKey()` / `loginPiOAuth()` | Use the runtime-owned Pi OAuth implementation without importing Pi's mutable provider registry |
|
|
@@ -178,25 +168,19 @@ Every symbol exported by each public code entrypoint is listed below.
|
|
|
178
168
|
**`@mono-agent/agent-runtime`**
|
|
179
169
|
|
|
180
170
|
```text
|
|
181
|
-
ACP_PROTOCOL_VERSION
|
|
182
|
-
ACTIVE_RUNTIME_KINDS
|
|
183
171
|
ALLOWLIST_MODE_ALL
|
|
184
172
|
ALLOWLIST_MODE_CUSTOM
|
|
185
173
|
APPROVAL_DECISIONS
|
|
186
|
-
AcpCallbackContext
|
|
187
|
-
AcpClientError
|
|
188
|
-
AcpClientHostOptions
|
|
189
|
-
AcpInteractionRequest
|
|
190
|
-
AcpListedSession
|
|
191
|
-
AcpProfileDescriptor
|
|
192
|
-
AcpSessionListResult
|
|
193
174
|
BINARY_BLOAT_TOOLS
|
|
194
175
|
BridgeSpec
|
|
195
|
-
CLAUDE_SDK_CATALOG_VERSION
|
|
196
176
|
DEFAULT_RUNTIME_BRAND
|
|
197
177
|
DEFAULT_TOOL_BLOAT_CONFIG
|
|
198
178
|
MAX_TOOL_RESULT_BYTES
|
|
199
|
-
|
|
179
|
+
PiBuiltinModelSnapshot
|
|
180
|
+
PiBuiltinProviderSnapshot
|
|
181
|
+
PiOAuthCredentialsSnapshot
|
|
182
|
+
PiOAuthLoginCallbacks
|
|
183
|
+
PiReasoningLevel
|
|
200
184
|
RISK_TIERS
|
|
201
185
|
RUNTIME_CAPABILITIES
|
|
202
186
|
RuntimeBridge
|
|
@@ -204,47 +188,34 @@ RuntimeBridgeDescriptor
|
|
|
204
188
|
RuntimeBridgeId
|
|
205
189
|
RuntimeModelRef
|
|
206
190
|
UNKNOWN_CAPABILITY
|
|
207
|
-
acpRuntimeBridge
|
|
208
|
-
authenticateAcpProfile
|
|
209
191
|
buildCapabilitiesUsed
|
|
210
192
|
buildTranscriptTailSnapshot
|
|
211
|
-
canonicalizeLegacyModelReference
|
|
212
193
|
configureToolRuntime
|
|
213
194
|
createApprovalManager
|
|
214
|
-
createClaudeSdkDiscoveryIsolation
|
|
215
195
|
createMetricsObserver
|
|
216
196
|
createObserverHub
|
|
217
197
|
createPiOAuthApiKeyResolver
|
|
218
198
|
createRouterRuntime
|
|
219
199
|
createRuntime
|
|
220
200
|
createSessionRegistry
|
|
221
|
-
|
|
222
|
-
deleteAcpSession
|
|
223
|
-
discoverClaudeSdkModels
|
|
201
|
+
describePiBuiltinProvider
|
|
224
202
|
disposeAllProviderSessions
|
|
225
203
|
disposeProviderSession
|
|
226
|
-
executionModeIncompatibilityReason
|
|
227
|
-
generateAcpResponse
|
|
228
204
|
generatePiNativeResponse
|
|
229
205
|
getPiBuiltinModel
|
|
230
206
|
inferAllowlistMode
|
|
231
207
|
invalidateProviderSession
|
|
232
208
|
isLikelyContextTermination
|
|
233
|
-
isModelCompatibleWithExecutionMode
|
|
234
|
-
listAcpSessions
|
|
235
209
|
listPiBuiltinModels
|
|
210
|
+
listPiBuiltinProviders
|
|
236
211
|
listRuntimeBridges
|
|
237
212
|
loginPiOAuth
|
|
238
|
-
logoutAcpProfile
|
|
239
213
|
normalizeAllowlistMode
|
|
240
|
-
normalizeClaudeSdkCatalog
|
|
241
|
-
normalizeClaudeSdkModelId
|
|
242
214
|
normalizeList
|
|
243
215
|
normalizeRuntimeModelReference
|
|
244
216
|
parseRuntimeModelReference
|
|
245
217
|
parseStoredAllowlist
|
|
246
218
|
piNativeRuntimeBridge
|
|
247
|
-
probeAcpProfile
|
|
248
219
|
readRuntimeBrand
|
|
249
220
|
readToolRuntime
|
|
250
221
|
reasoningLevelsForPiModel
|
|
@@ -258,12 +229,9 @@ resolvePiOAuthApiKey
|
|
|
258
229
|
resolveRuntimeBrand
|
|
259
230
|
resolveRuntimeBridge
|
|
260
231
|
runtimeCapabilities
|
|
261
|
-
sdkFromModelReference
|
|
262
232
|
storedAllowlistMode
|
|
263
233
|
syncProviderSession
|
|
264
234
|
toolCompactionAppliedFromWarnings
|
|
265
|
-
validateAcpProfileId
|
|
266
|
-
validateAcpProviderSessionId
|
|
267
235
|
wrapToolsWithApprovalGate
|
|
268
236
|
```
|
|
269
237
|
|
|
@@ -332,6 +300,8 @@ inferSkillsRoot
|
|
|
332
300
|
|
|
333
301
|
```text
|
|
334
302
|
DEFAULT_CODEX_SEARCH_MODEL
|
|
303
|
+
DEFAULT_MONITOR_TIMEOUT_MS
|
|
304
|
+
MIN_MONITOR_TIMEOUT_MS
|
|
335
305
|
bashToolImpl
|
|
336
306
|
bashToolRun
|
|
337
307
|
createWebToolController
|
|
@@ -343,9 +313,12 @@ grepToolImpl
|
|
|
343
313
|
inspectCodexSubscriptionSearch
|
|
344
314
|
isPathAllowed
|
|
345
315
|
isWorkdirAllowed
|
|
316
|
+
monitorStopToolRun
|
|
317
|
+
monitorToolRun
|
|
346
318
|
normalizeBackgroundBashTimeoutMs
|
|
347
319
|
normalizeBackgroundTimeoutMs
|
|
348
320
|
normalizeBashTimeoutMs
|
|
321
|
+
normalizeMonitorTimeoutMs
|
|
349
322
|
normalizeProcessTimeoutMs
|
|
350
323
|
performWebFetch
|
|
351
324
|
performWebSearch
|
|
@@ -393,64 +366,42 @@ renderResumeSnapshot
|
|
|
393
366
|
**`@mono-agent/agent-runtime/ai`**
|
|
394
367
|
|
|
395
368
|
```text
|
|
396
|
-
ACP_PROTOCOL_VERSION
|
|
397
|
-
ACTIVE_RUNTIME_KINDS
|
|
398
|
-
AcpCallbackContext
|
|
399
|
-
AcpClientError
|
|
400
|
-
AcpClientHostOptions
|
|
401
|
-
AcpInteractionRequest
|
|
402
|
-
AcpListedSession
|
|
403
|
-
AcpProfileDescriptor
|
|
404
|
-
AcpSessionListResult
|
|
405
369
|
BridgeSpec
|
|
406
|
-
|
|
407
|
-
|
|
370
|
+
PiBuiltinModelSnapshot
|
|
371
|
+
PiBuiltinProviderSnapshot
|
|
372
|
+
PiOAuthCredentialsSnapshot
|
|
373
|
+
PiOAuthLoginCallbacks
|
|
374
|
+
PiReasoningLevel
|
|
408
375
|
RUNTIME_CAPABILITIES
|
|
409
376
|
RuntimeBridge
|
|
410
377
|
RuntimeBridgeDescriptor
|
|
411
378
|
RuntimeBridgeId
|
|
412
379
|
RuntimeModelRef
|
|
413
380
|
UNKNOWN_CAPABILITY
|
|
414
|
-
acpRuntimeBridge
|
|
415
|
-
authenticateAcpProfile
|
|
416
381
|
buildCapabilitiesUsed
|
|
417
|
-
canonicalizeLegacyModelReference
|
|
418
|
-
createClaudeSdkDiscoveryIsolation
|
|
419
382
|
createMetricsObserver
|
|
420
383
|
createObserverHub
|
|
421
384
|
createSessionRegistry
|
|
422
|
-
|
|
423
|
-
deleteAcpSession
|
|
424
|
-
discoverClaudeSdkModels
|
|
385
|
+
describePiBuiltinProvider
|
|
425
386
|
disposeAllProviderSessions
|
|
426
387
|
disposeProviderSession
|
|
427
|
-
executionModeIncompatibilityReason
|
|
428
|
-
generateAcpResponse
|
|
429
388
|
generatePiNativeResponse
|
|
430
389
|
getPiBuiltinModel
|
|
431
390
|
invalidateProviderSession
|
|
432
|
-
isModelCompatibleWithExecutionMode
|
|
433
|
-
listAcpSessions
|
|
434
391
|
listPiBuiltinModels
|
|
392
|
+
listPiBuiltinProviders
|
|
435
393
|
listRuntimeBridges
|
|
436
394
|
loginPiOAuth
|
|
437
|
-
logoutAcpProfile
|
|
438
|
-
normalizeClaudeSdkCatalog
|
|
439
|
-
normalizeClaudeSdkModelId
|
|
440
395
|
normalizeRuntimeModelReference
|
|
441
396
|
parseRuntimeModelReference
|
|
442
397
|
piNativeRuntimeBridge
|
|
443
|
-
probeAcpProfile
|
|
444
398
|
reasoningLevelsForPiModel
|
|
445
399
|
refreshProviderSession
|
|
446
400
|
resolvePiOAuthApiKey
|
|
447
401
|
resolveRuntimeBridge
|
|
448
402
|
runtimeCapabilities
|
|
449
|
-
sdkFromModelReference
|
|
450
403
|
syncProviderSession
|
|
451
404
|
toolCompactionAppliedFromWarnings
|
|
452
|
-
validateAcpProfileId
|
|
453
|
-
validateAcpProviderSessionId
|
|
454
405
|
```
|
|
455
406
|
|
|
456
407
|
**`@mono-agent/agent-runtime/ai/cost.js`**
|
|
@@ -498,93 +449,32 @@ statsForCompletedChange
|
|
|
498
449
|
formatLiveInputGuidance
|
|
499
450
|
```
|
|
500
451
|
|
|
501
|
-
**`@mono-agent/agent-runtime/ai/providers/
|
|
452
|
+
**`@mono-agent/agent-runtime/ai/providers/codex/app-server-client.js`**
|
|
502
453
|
|
|
503
454
|
```text
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
**`@mono-agent/agent-runtime/ai/providers/claude-cli.js`**
|
|
509
|
-
|
|
510
|
-
```text
|
|
511
|
-
buildCliCommand
|
|
512
|
-
claudeCodeRuntimeBridge
|
|
513
|
-
createThinkingBuffer
|
|
514
|
-
generateCliResponse
|
|
515
|
-
normalizeCliEvent
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
**`@mono-agent/agent-runtime/ai/providers/claude-sdk-discovery.js`**
|
|
519
|
-
|
|
520
|
-
```text
|
|
521
|
-
CLAUDE_SDK_CATALOG_VERSION
|
|
522
|
-
ClaudeSdkCatalogModel
|
|
523
|
-
ClaudeSdkEffort
|
|
524
|
-
createClaudeSdkDiscoveryIsolation
|
|
525
|
-
curatedClaudeSdkModels
|
|
526
|
-
discoverClaudeSdkModels
|
|
527
|
-
normalizeClaudeSdkCatalog
|
|
528
|
-
normalizeClaudeSdkModelId
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
**`@mono-agent/agent-runtime/ai/providers/claude-sdk.js`**
|
|
532
|
-
|
|
533
|
-
```text
|
|
534
|
-
claudeEffortOptions
|
|
535
|
-
claudeRuntimeBridge
|
|
536
|
-
claudeSdkModelForQuery
|
|
537
|
-
generateClaudeResponse
|
|
538
|
-
toolPayloadLimit
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
**`@mono-agent/agent-runtime/ai/providers/codex-app.js`**
|
|
542
|
-
|
|
543
|
-
```text
|
|
544
|
-
codexAppRuntimeBridge
|
|
455
|
+
CODEX_APP_SERVER_ARGS
|
|
456
|
+
CODEX_APP_SERVER_ISOLATED_ARGS
|
|
457
|
+
addOpaqueSensitiveValue
|
|
458
|
+
codexErrorMessage
|
|
545
459
|
createCodexAppServerClient
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
```text
|
|
558
|
-
CLAUDE_ONE_MILLION_CONTEXT_MODELS
|
|
559
|
-
DEFAULT_CONTEXT_WINDOW
|
|
560
|
-
ONE_MILLION_CONTEXT_WINDOW
|
|
561
|
-
claudeModelSupportsContextWindow
|
|
562
|
-
claudeModelSupportsOneMillionContext
|
|
563
|
-
hasExplicitOneMillionContextWindow
|
|
564
|
-
modelWithContextWindow
|
|
565
|
-
normalizeContextWindow
|
|
566
|
-
stripContextWindowSuffix
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
**`@mono-agent/agent-runtime/ai/runtime/fast-mode.js`**
|
|
570
|
-
|
|
571
|
-
```text
|
|
572
|
-
codexModelSupportsFastMode
|
|
573
|
-
normalizeFastMode
|
|
460
|
+
isCodexRequestTimeout
|
|
461
|
+
isSensitivePayloadField
|
|
462
|
+
normalizedSensitiveName
|
|
463
|
+
redactCodexDiagnostic
|
|
464
|
+
redactCodexPayload
|
|
465
|
+
sanitizeCodexDiagnostic
|
|
466
|
+
sanitizeCodexNotification
|
|
467
|
+
sanitizeCodexResponseError
|
|
468
|
+
sensitiveEnvironmentValues
|
|
469
|
+
utf8Head
|
|
574
470
|
```
|
|
575
471
|
|
|
576
472
|
**`@mono-agent/agent-runtime/ai/runtime/model-refs.js`**
|
|
577
473
|
|
|
578
474
|
```text
|
|
579
|
-
ACTIVE_RUNTIME_KINDS
|
|
580
|
-
RESERVED_RUNTIME_KINDS
|
|
581
475
|
RuntimeModelRef
|
|
582
|
-
canonicalizeLegacyModelReference
|
|
583
|
-
executionModeIncompatibilityReason
|
|
584
|
-
isModelCompatibleWithExecutionMode
|
|
585
476
|
normalizeRuntimeModelReference
|
|
586
477
|
parseRuntimeModelReference
|
|
587
|
-
sdkFromModelReference
|
|
588
478
|
```
|
|
589
479
|
|
|
590
480
|
**`@mono-agent/agent-runtime/ai/runtime/registry.js`**
|
|
@@ -600,33 +490,21 @@ resolveRuntimeBridge
|
|
|
600
490
|
runtimeCapabilities
|
|
601
491
|
```
|
|
602
492
|
|
|
603
|
-
**`@mono-agent/agent-runtime/ai/streaming/codex-events.js`**
|
|
604
|
-
|
|
605
|
-
```text
|
|
606
|
-
normalizeCodexItemEvent
|
|
607
|
-
normalizeCodexItemType
|
|
608
|
-
```
|
|
609
|
-
|
|
610
493
|
<!-- public-api-inventory:end -->
|
|
611
494
|
|
|
612
495
|
### When to reach for this vs. other JS agent runtimes
|
|
613
496
|
|
|
614
497
|
`@mono-agent/agent-runtime` is purpose-built for **autonomous, long-running agent work** with provider portability and operational resilience as first-class concerns. It is *not* a streaming-chat UI kit. Where each peer fits:
|
|
615
498
|
|
|
616
|
-
- **Vercel AI SDK** — best when you're building a chat / generative-UI experience inside a React or Next.js app. `useChat`, `useCompletion`, streaming server components, and edge-runtime compatibility are their strengths. Their provider list is curated (Anthropic, OpenAI, Google, etc., via `@ai-sdk/*` packages); there's no Pi gateway
|
|
617
|
-
- **Claude Agent SDK** (`@anthropic-ai/claude-agent-sdk`) — first-party Anthropic SDK. Tight integration with Claude features (canUseTool, sub-agents, hooks, MCP). We
|
|
499
|
+
- **Vercel AI SDK** — best when you're building a chat / generative-UI experience inside a React or Next.js app. `useChat`, `useCompletion`, streaming server components, and edge-runtime compatibility are their strengths. Their provider list is curated (Anthropic, OpenAI, Google, etc., via `@ai-sdk/*` packages); there's no Pi gateway and no per-call provider fallback. If you're rendering a streaming chat into a browser, use them. If you're orchestrating multi-turn autonomous work that must survive a rate-limited primary provider, use us.
|
|
500
|
+
- **Claude Agent SDK** (`@anthropic-ai/claude-agent-sdk`) — first-party Anthropic SDK. Tight integration with Claude features (canUseTool, sub-agents, hooks, MCP). We reach Anthropic models through the Pi gateway instead, and add transcript-resume across provider drops, a structured failure taxonomy, a tool-bloat guard with artifact persistence, and a provider fallback router. Reach for the bare Anthropic SDK when you only ever talk to Claude and don't need cross-provider portability or resume.
|
|
618
501
|
- **Mastra** — a workflow engine + memory + RAG stack. Different category: it's the layer *above* a runtime. You can layer Mastra workflows on top of `@mono-agent/agent-runtime` if you want both.
|
|
619
502
|
- **OpenAI Agents SDK** — first-party OpenAI SDK. Same trade-off as the Claude Agent SDK: tight integration with OpenAI, no other providers. Pi providers in our runtime cover OpenAI plus a dozen others through a single API.
|
|
620
503
|
- **LangChain.js** — kitchen sink with deep abstraction stacks. We're deliberately lean; if you want chains, agents, vector stores, and parsers under one umbrella, LangChain is built for that. If you want a focused runtime kernel, use us.
|
|
621
504
|
|
|
622
505
|
**What we natively bridge (no extra packages):**
|
|
623
506
|
|
|
624
|
-
- Anthropic
|
|
625
|
-
- Anthropic Claude via the `claude` Code CLI binary.
|
|
626
|
-
- OpenAI's Codex via the `codex` app-server CLI.
|
|
627
|
-
- OpenCode providers via an isolated, password-authenticated `opencode` app-server.
|
|
628
|
-
- Any ACP v1 stdio agent resolved by the host from an `acp:<profile-id>` reference.
|
|
629
|
-
- OpenAI, Google Gemini, AWS Bedrock, OpenRouter, xAI, Groq, Mistral, Perplexity, DeepSeek, Ollama, LlamaCPP, GLM, Vercel AI Gateway, GitHub Copilot, Gemini CLI — all through the Pi (`@earendil-works/pi-ai`) provider gateway, which our SDK adapter speaks directly.
|
|
507
|
+
- Anthropic, OpenAI-Codex, OpenAI, Google Gemini, AWS Bedrock, OpenRouter, xAI, Groq, Mistral, Perplexity, DeepSeek, Ollama, LlamaCPP, GLM, Vercel AI Gateway, GitHub Copilot, Gemini CLI — all through the Pi (`@earendil-works/pi-ai`) provider gateway, which our SDK adapter speaks directly.
|
|
630
508
|
|
|
631
509
|
**At-a-glance:**
|
|
632
510
|
|
|
@@ -646,81 +524,28 @@ normalizeCodexItemType
|
|
|
646
524
|
|
|
647
525
|
Honest summary: if the agent runs **without a human watching the screen** for minutes-to-hours and **must survive provider blips**, this is the right tool. If a human is watching a streaming chat, Vercel's SDK is the right tool. Both can coexist in the same app.
|
|
648
526
|
|
|
649
|
-
###
|
|
527
|
+
### Model references
|
|
650
528
|
|
|
651
|
-
|
|
529
|
+
There is one runtime. A `model` is a parsed
|
|
530
|
+
`{ provider, model, reference }` object whose `reference` must be the canonical
|
|
531
|
+
`<provider>:<model>` spelling; convert reference strings with
|
|
532
|
+
`parseRuntimeModelReference()` before calling `run()` — `run()` does not parse
|
|
533
|
+
strings.
|
|
652
534
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
| `"pi"` | `"sdk"` (or omitted) | Pi SDK |
|
|
658
|
-
| `"codex"` | `"cli"` | Codex app-server CLI |
|
|
659
|
-
| `"opencode"` | `"cli"` | Isolated OpenCode app-server CLI |
|
|
660
|
-
| `"acp"` | `"acp"` | ACP v1 stdio client |
|
|
661
|
-
|
|
662
|
-
A `model` is a parsed `{ sdk, model, provider? }` object. Convert canonical
|
|
663
|
-
strings such as `"pi:openai:gpt-5.5"` with
|
|
664
|
-
`parseRuntimeModelReference()` before calling `run()`.
|
|
665
|
-
|
|
666
|
-
#### ACP v1 host contract
|
|
667
|
-
|
|
668
|
-
ACP references are canonical `acp:<profile-id>` strings and always use the
|
|
669
|
-
dedicated `executionMode: "acp"`. The host supplies
|
|
670
|
-
`resolveAcpProfile(profileId, context)` either to `createRuntime()` or per run;
|
|
671
|
-
per-run callbacks win. A profile contains an absolute executable command,
|
|
672
|
-
literal arguments, an exact child environment, ownership declarations for
|
|
673
|
-
configuration/workspace/MCP, explicit capability policy, and bounded process
|
|
674
|
-
limits. The runtime never invokes a shell or inherits `process.env`.
|
|
675
|
-
|
|
676
|
-
Client-owned filesystem, terminal, permission, and elicitation behavior must be
|
|
677
|
-
provided as callbacks and is advertised only when enabled. The runtime-adapter
|
|
678
|
-
facade injects mono-agent's real sandbox implementation; direct kernel callers
|
|
679
|
-
must provide their own when policy requires it. Every owned stdio bridge is
|
|
680
|
-
closed after the operation with stdin close, TERM, then bounded KILL escalation.
|
|
681
|
-
Callback payloads retain their typed operation fields but omit raw protocol
|
|
682
|
-
session ids, extension metadata, and copied raw-id strings. Session-scoped
|
|
683
|
-
callbacks receive the corresponding opaque handle as
|
|
684
|
-
`AcpCallbackContext.providerSessionId`; request ids are opaque host correlation
|
|
685
|
-
tokens as well.
|
|
686
|
-
Session-update dispatch reads only validated own protocol fields. If a valid
|
|
687
|
-
transport frame is too structurally complex for the bounded host sanitizer,
|
|
688
|
-
the turn fails explicitly as `provider_protocol` instead of emitting a partial
|
|
689
|
-
tool, plan, or message event.
|
|
690
|
-
|
|
691
|
-
ACP provider-session ids and list cursors are confidential, authenticated v2
|
|
692
|
-
handles bound to their token kind and profile. The host must supply an exact
|
|
693
|
-
32-byte binary `acpSessionTokenKey` for every task run, list, validation, and
|
|
694
|
-
delete operation. Call
|
|
695
|
-
`validateAcpProviderSessionId(handle, expectedProfileId, key)` at untrusted
|
|
696
|
-
ingress. Keep the key stable and secret across host restarts; changing it
|
|
697
|
-
invalidates every outstanding handle. Legacy `acp:v1:` and `acp-cursor:v1:`
|
|
698
|
-
values are rejected.
|
|
699
|
-
|
|
700
|
-
Preserve each returned handle byte-for-byte and pass it back only to the
|
|
701
|
-
matching high-level resume, list, validation, or delete operation. Encryption
|
|
702
|
-
uses a fresh nonce, so two handles for the same remote id are not equality
|
|
703
|
-
keys. Raw protocol session ids, cursors, token keys, and transport connections
|
|
704
|
-
remain private runtime state and are omitted from profile resolver context,
|
|
705
|
-
callbacks, and diagnostics. Under the default `auto` recovery policy, the
|
|
706
|
-
client prefers `session/resume`, then `session/load`, and finally a fresh
|
|
707
|
-
session when neither capability is advertised. Explicit `resume` or `load`
|
|
708
|
-
policies fail closed if missing. Stable usage comes from the latest typed
|
|
709
|
-
`usage_update` notification; unstable `PromptResponse.usage` is ignored.
|
|
535
|
+
#### ACP
|
|
536
|
+
|
|
537
|
+
The ACP *client* runtime backend was removed in 0.21.0. `mono-agent bridge acp`
|
|
538
|
+
— serving ACP to clients — is unaffected and lives in `@mono-agent/agent-app`.
|
|
710
539
|
|
|
711
540
|
### `createRuntime(host)`
|
|
712
541
|
|
|
713
|
-
Pass host-level integration once at boot.
|
|
714
|
-
backend contract requires them.
|
|
542
|
+
Pass host-level integration once at boot. Every key is optional.
|
|
715
543
|
|
|
716
544
|
```js
|
|
717
545
|
createRuntime({
|
|
718
546
|
// -- host callbacks --
|
|
719
547
|
resolveCustomPricing, // (parsed) => NormalizedPricing | null
|
|
720
548
|
resolvePiApiKey, // async (provider) => string | undefined
|
|
721
|
-
resolveAcpProfile, // async (profileId, context) => AcpProfileDescriptor
|
|
722
|
-
onAcpInteractionRequest, // async permission/elicitation fallback callback
|
|
723
|
-
acpSessionTokenKey, // Uint8Array(32), required for ACP task/session-handle operations
|
|
724
549
|
persistArtifact, // ({ filename, buffer, toolName, toolUseId }) => path | null
|
|
725
550
|
onCompactionRecorded, // (compactionRow) => void — fired when the pi bridge
|
|
726
551
|
// runs an automatic compaction (proactive or reactive
|
|
@@ -744,9 +569,10 @@ createRuntime({
|
|
|
744
569
|
observers: [],
|
|
745
570
|
|
|
746
571
|
// -- approval gates (HITL) --
|
|
747
|
-
// Optional. When set, the runtime asks the host before every tool
|
|
748
|
-
// whose risk tier is "medium" or "high" (and not session-allowlisted).
|
|
749
|
-
// See the "Approval gates" section below
|
|
572
|
+
// Optional. When set, the runtime asks the host before every BUILT-IN tool
|
|
573
|
+
// call whose risk tier is "medium" or "high" (and not session-allowlisted).
|
|
574
|
+
// MCP-backed tools are not gated. See the "Approval gates" section below
|
|
575
|
+
// for the request/response shape.
|
|
750
576
|
onToolApprovalRequest, // async (req) => { decision, reason? }
|
|
751
577
|
toolRiskTiers: { Bash: "high" }, // per-tool tier override (low|medium|high)
|
|
752
578
|
approvalDefaultRiskTier: "medium",
|
|
@@ -761,9 +587,6 @@ createRuntime({
|
|
|
761
587
|
tempdirPrefix: "agent-runtime-cli-", // mkdtemp prefix for CLI provider scratch dirs
|
|
762
588
|
providerModelPrefix: "agent", // id prefix for custom Pi providers
|
|
763
589
|
doctorCommand: "agent-runtime doctor", // command suggested in tool error messages
|
|
764
|
-
serviceName: "agent-runtime", // Codex app-server serviceName
|
|
765
|
-
clientInfoName: "agent-runtime", // Codex app-server clientInfo.name
|
|
766
|
-
clientInfoTitle: "Agent Runtime", // Codex app-server clientInfo.title
|
|
767
590
|
},
|
|
768
591
|
});
|
|
769
592
|
```
|
|
@@ -818,163 +641,51 @@ Per-call options (a non-exhaustive selection):
|
|
|
818
641
|
| Option | Type | Notes |
|
|
819
642
|
|---|---|---|
|
|
820
643
|
| `model` | `RuntimeModelRef` | **Required.** Pass the object returned by `parseRuntimeModelReference()`; `run()` does not parse strings. |
|
|
821
|
-
| `executionMode` | `"sdk" \| "cli" \| "acp"` | Default `"sdk"`; ACP references require `"acp"`. |
|
|
822
644
|
| `messages` | `Message[]` | Conversation history. |
|
|
823
645
|
| `cwd` | `string` | Working directory for the agent's tools. |
|
|
824
646
|
| `allowedTools` | `string[]` | Built-in tool allowlist. Default: all. |
|
|
825
647
|
| `disallowedTools` | `string[]` | Block list. |
|
|
826
|
-
| `
|
|
827
|
-
| `
|
|
828
|
-
| `
|
|
829
|
-
| `codexSandboxNetworkAccess` | `boolean` | Code-only Codex app-server per-turn network control. Only strict `true` enables it for plan/default/acceptEdits; omitted or any other value disables it. |
|
|
830
|
-
| `mcpServers` | `Record<string, McpServerConfig>` | Configured MCP servers (stdio / sse / http); on direct Codex, each forwarded server authorizes its own tool calls. |
|
|
648
|
+
| `subagents` | `RuntimeSubagentsOptions` | In-process `Agent` delegation: profiles, caps, and the nested-run callback. This replaced the withdrawn caller-defined native teammate profiles. |
|
|
649
|
+
| `skills` / `skillsRoot` | `{name, description}[]` / `string` | Skills disclosed to the run and the directory holding `<name>/SKILL.md`. |
|
|
650
|
+
| `mcpServers` | `Record<string, McpServerConfig>` | Configured MCP servers (stdio / sse / http). |
|
|
831
651
|
| `sandboxPolicy` | `SandboxPolicy` | Optional fail-closed sandbox policy for built-in tools and stdio MCP process startup. |
|
|
832
652
|
| `webSearchConfig` | `{ backend?, endpoint?, codex?: { model? } }` | Run-scoped local SearXNG, ChatGPT-subscription Codex, and keyless WebSearch backend selection. |
|
|
833
653
|
| `webFetchConfig` | `{ render?, browserCommand? }` | Run-scoped static extraction and optional isolated browser-render policy. |
|
|
834
|
-
| `piToolExecutionMode` | `"safe-parallel" \| "sequential"` | Pi built-in scheduling. Safe parallelism is the default; stateful/mutating
|
|
654
|
+
| `piToolExecutionMode` | `"safe-parallel" \| "sequential"` | Pi built-in scheduling. Safe parallelism is the default; read-only tools may overlap only when the offered tool set contains no stateful/mutating or MCP tool. Otherwise Pi 0.85 serializes the whole batch. |
|
|
835
655
|
| `maxTurns` | `number` | Hard cap on agent turns. |
|
|
836
|
-
| `outputSchema` | `JSONSchema` | Requests structured JSON
|
|
656
|
+
| `outputSchema` | `JSONSchema` | Requests structured JSON; see “Structured output” below. |
|
|
837
657
|
| `abortSignal` | `AbortSignal` | Cancel the run. |
|
|
838
|
-
| `liveInput` | `AsyncIterable<{ body: string; id?: string; receivedAt?: string; acknowledge?: () => void; reject?: (error?: unknown) => void }>` | Stream of in-flight user messages for steering
|
|
839
|
-
| `claudeAgentQuery` | `typeof query` | Advanced programmatic/test seam for the Claude SDK bridge. When omitted, the bridge uses the runtime's pinned Claude Agent SDK. This is not a config field or telemetry value. |
|
|
658
|
+
| `liveInput` | `AsyncIterable<{ body: string; id?: string; receivedAt?: string; acknowledge?: () => void; reject?: (error?: unknown) => void }>` | Stream of in-flight user messages for steering the active run. The bridge acknowledges only after its native steering boundary accepts the message; per-attempt rejection permits router replay. Acknowledgement emits metadata-only `live_input_applied` telemetry. |
|
|
840
659
|
| `onEvent` | `(event) => void` | Fired for every runtime event (assistant text, tool calls/results, applied live input, runtime warnings, structured output). |
|
|
841
660
|
| `runId` | `string` | Tag this run for downstream callbacks (e.g. `onCompactionRecorded`). |
|
|
842
661
|
| `providerSessionId` | `string` | Resume a prior provider session. |
|
|
843
|
-
| `
|
|
844
|
-
| `runArtifactDir` | `string` | Used by some providers as the Playwright MCP filename target. |
|
|
845
|
-
| `codexAppServerCommand` | `string` | Override the Codex CLI binary. |
|
|
846
|
-
| `codexAppServerArgs` | `string[]` | Override the Codex CLI arguments. |
|
|
662
|
+
| `runArtifactDir` | `string` | Used as the Playwright MCP filename target. |
|
|
847
663
|
|
|
848
664
|
`runtimeCapabilities()` and each descriptor returned by
|
|
849
|
-
`listRuntimeBridges()` expose `tool_policy`.
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
one-shot Claude CLI and direct OpenCode bridges advertise it as unsupported so
|
|
860
|
-
routers skip them when a direct runtime call requires steering.
|
|
861
|
-
After a native bridge invokes `acknowledge()`, the runtime emits exactly one
|
|
665
|
+
`listRuntimeBridges()` expose `tool_policy`. The Pi bridge reports
|
|
666
|
+
`"projected"`, meaning it projects restrictive `allowedTools` /
|
|
667
|
+
`disallowedTools` as written, so named-only lists, `[]`, and denylists are all
|
|
668
|
+
supported. A wildcard dominates named entries, so `["*", "Read"]` is allow-all.
|
|
669
|
+
The `"allow_all_only"` value survives for custom structural bridges that accept
|
|
670
|
+
only an effective unrestricted policy; omission by such a bridge means the
|
|
671
|
+
capability is unknown.
|
|
672
|
+
|
|
673
|
+
Live input is native on the Pi bridge.
|
|
674
|
+
After the bridge invokes `acknowledge()`, the runtime emits exactly one
|
|
862
675
|
`{ type: "live_input_applied", inputId, receivedAt? }` event for that logical
|
|
863
676
|
run. It deliberately omits the guidance body. A fallback router reuses the same
|
|
864
677
|
instrumented input stream, so replay or duplicate acknowledgement cannot emit a
|
|
865
678
|
second applied event. A throwing host `acknowledge` or `reject` callback cannot
|
|
866
|
-
|
|
867
|
-
`
|
|
868
|
-
|
|
869
|
-
### Provider-native subagents and project instructions
|
|
870
|
-
|
|
871
|
-
Claude SDK runs are filesystem-isolated by default: mono-agent passes
|
|
872
|
-
`settingSources: []`, which disables user, project, and local settings sources,
|
|
873
|
-
including their `CLAUDE.md`, hooks, plugins, and `.claude/agents` profiles.
|
|
874
|
-
Anthropic managed settings remain in force and may still configure hooks or
|
|
875
|
-
plugins; `settingSources` is not a managed-policy bypass. Opt into only the
|
|
876
|
-
needed sources, for example `settingSources: ["project"]`. User, project, and
|
|
877
|
-
local settings may execute configured hooks and plugins, so enable only trusted
|
|
878
|
-
settings and avoid opting in while running in an untrusted checkout. This
|
|
879
|
-
option is SDK only. The Claude Code CLI performs its own settings discovery,
|
|
880
|
-
and mono-agent does not pass it a `--setting-sources` value.
|
|
881
|
-
|
|
882
|
-
Codex app-server owns its native collaboration agents and their profiles. The
|
|
883
|
-
bridge observes and normalizes their lifecycle, but it does not synthesize a
|
|
884
|
-
`collaborationMode` payload or inject caller-defined `nativeSubagents`
|
|
885
|
-
teammates. A non-empty configured teammate list fails before app-server startup
|
|
886
|
-
with `skipped_capability_mismatch`, allowing a fallback router to continue to a
|
|
887
|
-
Claude route.
|
|
888
|
-
|
|
889
|
-
Codex app-server runs disable automatic repository-instruction discovery by
|
|
890
|
-
default with `project_doc_max_bytes=0`. Set `codexLoadProjectDocs: true` when
|
|
891
|
-
Codex and its own collaboration agents should load repository instructions. If
|
|
892
|
-
`codexAppServerArgs` is supplied, that explicit argument vector is authoritative
|
|
893
|
-
and `codexLoadProjectDocs` does not alter it.
|
|
894
|
-
|
|
895
|
-
`codexSandboxNetworkAccess` is a separate code-only, provider-native control.
|
|
896
|
-
It is unrelated to `RuntimeRunOptions.sandboxPolicy`, which controls
|
|
897
|
-
mono-agent's own sandbox and is not consumed by Codex's provider-owned tool
|
|
898
|
-
loop. Only strict `true` enables network access for plan/read-only and
|
|
899
|
-
default/acceptEdits/workspace-write turns; the no-tools probe remains offline
|
|
900
|
-
and bypass remains danger-full-access. Combining workspace-write with network
|
|
901
|
-
access grants repository read and network egress in the same turn. Prefer
|
|
902
|
-
`permissionMode: "plan"` when only read-only browsing is needed.
|
|
903
|
-
|
|
904
|
-
Provider-native and in-process delegation share `subagent_activity` telemetry.
|
|
905
|
-
`subagent.id` is the canonical parent attachment key: the initiating parent
|
|
906
|
-
tool-use id whenever the provider exposes it, or a stable synthetic key for an
|
|
907
|
-
orphan lifecycle record. `nativeId` is an optional provider task/thread id for
|
|
908
|
-
correlation only and never replaces that key.
|
|
909
|
-
The normalized phases are `agent_started`, `started`, `completed`, `message`,
|
|
910
|
-
and `agent_completed`. A `message` belongs to the child and must not be treated
|
|
911
|
-
as parent answer text or as a completed tool call.
|
|
912
|
-
|
|
913
|
-
Restrictive allowlists must still authorize the delegation surface. Include
|
|
914
|
-
`Agent` for the in-process built-in. Claude-native teammate definitions add
|
|
915
|
-
`Task` to an explicit allowed list automatically; filesystem profiles enabled
|
|
916
|
-
only through `settingSources` require callers to include `Task` themselves.
|
|
917
|
-
An explicit deny still wins. Direct Codex remains an allow-all-only bridge, so
|
|
918
|
-
a named restrictive allowlist fails before provider startup rather than being
|
|
919
|
-
silently widened.
|
|
679
|
+
undo the steer that already reached the harness; it surfaces as a bounded
|
|
680
|
+
`live_input_failed` runtime warning and ends that run's live-input consumer, so
|
|
681
|
+
later guidance for the same run is no longer steered.
|
|
920
682
|
|
|
921
|
-
|
|
683
|
+
### Project instructions
|
|
922
684
|
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
structuredResultSource?: string, // where structuredResult came from
|
|
928
|
-
events: RuntimeEvent[], // full event stream (for host-side parsing)
|
|
929
|
-
usage: {
|
|
930
|
-
input_tokens, output_tokens,
|
|
931
|
-
cache_read_tokens, cache_creation_tokens,
|
|
932
|
-
cost_usd,
|
|
933
|
-
},
|
|
934
|
-
durationMs: number,
|
|
935
|
-
numTurns: number,
|
|
936
|
-
model: string,
|
|
937
|
-
effort: string,
|
|
938
|
-
sdk: "claude" | "pi" | "codex" | "opencode",
|
|
939
|
-
cancelled: boolean,
|
|
940
|
-
error: string | null,
|
|
941
|
-
errorDetails: object | null,
|
|
942
|
-
failureKind: string | null,
|
|
943
|
-
providerSessionId: string | null,
|
|
944
|
-
runtimeWarnings: RuntimeWarning[],
|
|
945
|
-
diagnostics: object,
|
|
946
|
-
capabilitiesUsed: { // what the backend actually did this call
|
|
947
|
-
prompt_cache_active: true|false|null,
|
|
948
|
-
thinking_enabled: true|false|null,
|
|
949
|
-
structured_output_enforced: boolean,
|
|
950
|
-
subagent_invoked: true|false|null,
|
|
951
|
-
mcp_servers_used: string[],
|
|
952
|
-
native_subagents_used: string[],
|
|
953
|
-
tool_compaction_applied: boolean,
|
|
954
|
-
context_compaction_applied: true|false|null,
|
|
955
|
-
},
|
|
956
|
-
}
|
|
957
|
-
```
|
|
958
|
-
|
|
959
|
-
`capabilitiesUsed` is the per-call complement to `runtimeCapabilities()`. Tristate fields use `null` to mean "this provider can't tell" — distinct from `false` ("definitely off"). It's also emitted as a `capabilities_resolved` event near the end of the run, so observers can capture it without inspecting the result object.
|
|
960
|
-
|
|
961
|
-
Successful provider requests may also emit exact context telemetry through
|
|
962
|
-
`onEvent` and `result.events`:
|
|
963
|
-
|
|
964
|
-
- `context_usage` is one provider-counted request snapshot, never the run's
|
|
965
|
-
aggregate processed-token total. Pi emits it at each successful assistant
|
|
966
|
-
`message_end`; Codex uses `thread/tokenUsage/updated.tokenUsage.last`; direct
|
|
967
|
-
OpenCode requires a completed assistant message with native `tokens.total`;
|
|
968
|
-
ACP normalizes the agent's exact `usage_update` `used`/`size` pair.
|
|
969
|
-
Each event identifies the measured model and includes `contextWindow` only
|
|
970
|
-
when the provider's own model metadata supplied it. The Claude bridges do not
|
|
971
|
-
currently emit this event.
|
|
972
|
-
- `context_compaction` is a lifecycle event with a stable `operationId`,
|
|
973
|
-
`status` (`running`, `succeeded`, `skipped`, or `failed`), `sdk`, `trigger`,
|
|
974
|
-
`timestamp`, and optional safe reason/model/count fields. Pi drives and emits
|
|
975
|
-
its own lifecycle; Codex and OpenCode normalize their native notifications and
|
|
976
|
-
suppress deprecated duplicate notifications. Pi's before/after counts are
|
|
977
|
-
estimates and explicitly set `tokenCountsExact: false`.
|
|
685
|
+
The Pi runtime does not read another tool's filesystem settings, hooks, plugins,
|
|
686
|
+
or project documents. Subagents are the kernel's own in-process delegation
|
|
687
|
+
surface (the `Agent` tool), configured by the host rather than discovered from a
|
|
688
|
+
provider's on-disk profiles.
|
|
978
689
|
|
|
979
690
|
### Built-in tools
|
|
980
691
|
|
|
@@ -1021,51 +732,42 @@ truncation is explicitly desired; omitting it is not a separate hidden limit.
|
|
|
1021
732
|
The standard 256 KiB tool-payload guard still applies to oversized tool results.
|
|
1022
733
|
|
|
1023
734
|
Override or extend the tool surface by passing `mcpServers` for MCP-backed tools.
|
|
1024
|
-
|
|
1025
|
-
the
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
This also applies under direct Codex `permissionMode: "plan"`: the read-only
|
|
1032
|
-
sandbox constrains Codex-owned filesystem and command execution, but a declared
|
|
1033
|
-
MCP tool can still change state managed by its server. Do not declare a server
|
|
1034
|
-
whose complete tool surface is not authorized for the run.
|
|
735
|
+
Declaring a server is the authorization boundary: it exposes that server's whole
|
|
736
|
+
tool surface to the run, and `sandboxPolicy` does not reach state the server
|
|
737
|
+
owns on the other side of the connection. Do not declare a server whose complete
|
|
738
|
+
tool surface is not authorized for the run: there is no per-call gate behind it.
|
|
739
|
+
`onToolApprovalRequest` wraps the built-in tool set only (`getPiBuiltinTools`);
|
|
740
|
+
`initPiMcpTools` is initialized without an approval manager, so an MCP call runs
|
|
741
|
+
without asking the host, whatever risk tier is configured.
|
|
1035
742
|
|
|
1036
743
|
### Structured output
|
|
1037
744
|
|
|
1038
|
-
Pass `options.outputSchema` (a JSON Schema).
|
|
1039
|
-
|
|
1040
|
-
the schema and reports that structured output was enforced, but its bridge
|
|
1041
|
-
returns provider text rather than parsing `structuredResult`; hosts must parse
|
|
1042
|
-
and validate `result.text`. Direct OpenCode rejects `outputSchema` with a typed
|
|
1043
|
-
capability mismatch.
|
|
1044
|
-
|
|
1045
|
-
The package does **not** validate captured output against your schema. Hosts run
|
|
1046
|
-
their own validation (Zod, AJV, and similar) before applying domain effects.
|
|
745
|
+
Pass `options.outputSchema` (a JSON Schema). The Pi runtime surfaces captured
|
|
746
|
+
JSON as `result.structuredResult`.
|
|
1047
747
|
|
|
1048
748
|
### Provider fallback router
|
|
1049
749
|
|
|
1050
|
-
`createRouterRuntime({ host, chain,
|
|
750
|
+
`createRouterRuntime({ host, chain, resolveAttempt })` wraps the standard runtime with an ordered chain of model references. On a retryable provider/auth failure it retries the logical run against the next entry with one bounded transcript-tail snapshot. A chain is stateless across provider sessions. Entry `effort` is tri-state: a string fixes that route, `null` asks for provider default, and omission inherits the legacy per-run effort.
|
|
1051
751
|
|
|
1052
752
|
```js
|
|
1053
|
-
import { createRouterRuntime } from "@mono-agent/agent-runtime";
|
|
753
|
+
import { createRouterRuntime, parseRuntimeModelReference } from "@mono-agent/agent-runtime";
|
|
1054
754
|
|
|
755
|
+
// A RuntimeModelRef is { provider, model, reference }; `reference` is required
|
|
756
|
+
// and must be the canonical `<provider>:<model>` spelling, so build refs with
|
|
757
|
+
// parseRuntimeModelReference rather than writing the object literal by hand.
|
|
1055
758
|
const router = createRouterRuntime({
|
|
1056
759
|
host: { /* same shape as createRuntime */ },
|
|
1057
|
-
routeSafety: "per-route-native",
|
|
1058
760
|
// Backoff shape for same-model retries; per-route counts live on `attempts`.
|
|
1059
761
|
retry: { backoffMs: 1000, maxBackoffMs: 15000 },
|
|
1060
762
|
chain: [
|
|
1061
|
-
{ model:
|
|
1062
|
-
{ model:
|
|
1063
|
-
{ model:
|
|
763
|
+
{ model: parseRuntimeModelReference("anthropic:claude-sonnet-5"), effort: "high", attempts: 2 },
|
|
764
|
+
{ model: parseRuntimeModelReference("openai-codex:gpt-5.6-sol"), effort: "xhigh" },
|
|
765
|
+
{ model: parseRuntimeModelReference("ollama:gemma4:31b"), effort: null },
|
|
1064
766
|
],
|
|
1065
767
|
});
|
|
1066
768
|
|
|
1067
769
|
const result = await router.run("...", { /* same shape as runtime.run */ });
|
|
1068
|
-
console.log(result.failoverHistory
|
|
770
|
+
console.log(result.failoverHistory);
|
|
1069
771
|
```
|
|
1070
772
|
|
|
1071
773
|
Behaviour:
|
|
@@ -1073,32 +775,30 @@ Behaviour:
|
|
|
1073
775
|
- Successful run on entry N → returns the result with `failoverHistory` set to attempts 0..N-1.
|
|
1074
776
|
- Retryable provider failure → retries the SAME entry while it has `attempts` left (emitting `provider_retry_started` after a doubling backoff), then emits `provider_failover_started`, builds a transcript snapshot, and advances to the next entry. `attempts` defaults to `1` per entry, so the kernel is single-shot unless a host opts in — `@mono-agent/config` supplies the product default of 2 on the primary.
|
|
1075
777
|
- Same-model retries fire only for transient subkinds (`overloaded`, `rate_limited`, `timeout`, `network`, `server_error`, `retryable_request`, terminated streams). A retry drops the route's provider session, since the failed attempt already appended to it, and appends its own `failoverHistory` entry carrying `retryIndex`.
|
|
1076
|
-
- A retry is *not* a failover: `
|
|
778
|
+
- A retry is *not* a failover: `provider_failover_started` is emitted once per entry, and `provider_failover_completed` only fires when a genuinely different model answered.
|
|
1077
779
|
- This is a whole-logical-turn retry sitting strictly outside the provider bridges' own transport retries. On a `pi` route, `attempts: 2` combined with pi's default `maxRetries: 2` means up to six provider stream starts.
|
|
1078
780
|
- Context-window failure after bridge compaction recovery → never retries the same entry (a second identical request against the same window is a guaranteed second failure); preserves `failureKind: "context_limit"` in `failoverHistory` and tries the next entry; quota/output/max-turn `usage_limit` remains terminal.
|
|
1079
781
|
- Provider auth failure → retries the next chain entry and preserves `failureKind: "provider_auth"` in `failoverHistory` for the failed attempt.
|
|
1080
782
|
- Malformed request/config/billing-type non-retryable failure → returns immediately with `failoverHistory` containing the one attempt.
|
|
1081
783
|
- Cancellation → returns immediately.
|
|
1082
784
|
- Chain exhausted → `failureKind: "provider_unavailable_exhausted"`, `failoverHistory` lists every attempt.
|
|
1083
|
-
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
sets preserve ordinary provider-native behavior, while Pi routes retain the
|
|
1089
|
-
policy. The same invariant covers model routes reached through `Agent`
|
|
1090
|
-
children.
|
|
1091
|
-
- Pi route telemetry distinguishes `disabled`, fail-closed `mono-agent-srt`,
|
|
1092
|
-
and `mono-agent-srt-unsafe-host-fallback`; the last describes a configured
|
|
1093
|
-
policy that prefers SRT but permits host execution, not which branch ran.
|
|
785
|
+
- Every route is Pi-native, so the whole chain shares one monotonic runtime
|
|
786
|
+
contract. There is no per-route safety negotiation and no
|
|
787
|
+
`provider_route_safety` event: with a single contract there is nothing to
|
|
788
|
+
reconcile between routes. Pi routes retain the sandbox policy, including
|
|
789
|
+
routes reached through `Agent` children.
|
|
1094
790
|
- A resolver-supplied Pi runtime may own provider credentials and lifecycle,
|
|
1095
791
|
but must expose `configureTools()`: before every attempt the router replaces
|
|
1096
792
|
its mutable tool context with the router's effective host/configured safety
|
|
1097
793
|
inputs, while request-scoped overrides remain on that exact run. A runtime
|
|
1098
|
-
that cannot accept this projection fails
|
|
1099
|
-
- Attempt-resolver failures
|
|
1100
|
-
|
|
1101
|
-
|
|
794
|
+
that cannot accept this projection fails the attempt before it runs.
|
|
795
|
+
- Attempt-resolver failures — that missing `configureTools()` included — surface
|
|
796
|
+
as `failureKind: "provider_unavailable"`, with the error text fixed to
|
|
797
|
+
`The route attempt could not be resolved before execution.` (only a
|
|
798
|
+
`ResolverProtectedOptionError`, built from a repository-owned allowlist key,
|
|
799
|
+
reports its own message). Resolver credentials/options never enter result
|
|
800
|
+
telemetry, and such a failure advances to the next entry rather than consuming
|
|
801
|
+
the route's remaining `attempts`.
|
|
1102
802
|
- `resolveAttempt` runs once per attempt — including every same-model retry — and
|
|
1103
803
|
receives `{ attemptIndex, retryIndex }`, where `attemptIndex` stays the chain
|
|
1104
804
|
index. Its `cleanup` runs after each attempt.
|
|
@@ -1116,12 +816,16 @@ The runtime emits structured events for everything that happens during a run —
|
|
|
1116
816
|
A built-in aggregator covers the common metrics:
|
|
1117
817
|
|
|
1118
818
|
```js
|
|
1119
|
-
import {
|
|
819
|
+
import {
|
|
820
|
+
createMetricsObserver,
|
|
821
|
+
createRuntime,
|
|
822
|
+
parseRuntimeModelReference,
|
|
823
|
+
} from "@mono-agent/agent-runtime";
|
|
1120
824
|
|
|
1121
825
|
const metrics = createMetricsObserver();
|
|
1122
826
|
const runtime = createRuntime({ observers: [metrics] });
|
|
1123
827
|
|
|
1124
|
-
await runtime.run("...", { model:
|
|
828
|
+
await runtime.run("...", { model: parseRuntimeModelReference("anthropic:claude-sonnet-4-6") });
|
|
1125
829
|
|
|
1126
830
|
console.log(metrics.snapshot());
|
|
1127
831
|
// {
|
|
@@ -1146,7 +850,7 @@ Notable new events emitted by the bridges:
|
|
|
1146
850
|
|
|
1147
851
|
### Approval gates (human-in-the-loop)
|
|
1148
852
|
|
|
1149
|
-
Pass `onToolApprovalRequest` to gate tool calls behind a runtime approval. The runtime calls your callback once per tool invocation whose risk tier requires it, and pauses the agent until you respond.
|
|
853
|
+
Pass `onToolApprovalRequest` to gate built-in tool calls behind a runtime approval. The runtime calls your callback once per built-in tool invocation whose risk tier requires it, and pauses the agent until you respond.
|
|
1150
854
|
|
|
1151
855
|
```js
|
|
1152
856
|
const runtime = createRuntime({
|
|
@@ -1175,15 +879,10 @@ Responses:
|
|
|
1175
879
|
- `{ decision: "deny", reason? }` — block; the agent receives a tool error.
|
|
1176
880
|
- `{ decision: "always" }` — allow + session-allowlist for the run.
|
|
1177
881
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
Approval lifecycle is observable via `onEvent`:
|
|
1183
|
-
|
|
1184
|
-
- `tool_approval_pending` — emitted before calling the host.
|
|
1185
|
-
- `tool_approval_granted` — host approved.
|
|
1186
|
-
- `tool_approval_denied` — host denied, timed out, threw, or no callback for a high-risk tool.
|
|
882
|
+
Coverage is the Pi runtime's built-in tool set, via tool dispatch wrapping.
|
|
883
|
+
MCP-backed tools are outside the gate — the MCP bridge is built without an
|
|
884
|
+
approval manager — so for those, declaring the server is the authorization
|
|
885
|
+
boundary, not approving the call.
|
|
1187
886
|
|
|
1188
887
|
### Tool-result bloat handling
|
|
1189
888
|
|
|
@@ -1257,22 +956,14 @@ These are stable but treated as advanced API. Most consumers should reach for `c
|
|
|
1257
956
|
## Dependency Boundary
|
|
1258
957
|
|
|
1259
958
|
This package has zero `@mono-agent/*` workspace dependencies. Its runtime
|
|
1260
|
-
dependencies are `@
|
|
1261
|
-
`@
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
Anthropic dependency tree: Pi AI pins `@anthropic-ai/sdk@0.91.1`, while the
|
|
1269
|
-
Claude Agent SDK requires `@anthropic-ai/sdk>=0.93.0` and the runtime supplies
|
|
1270
|
-
its compatible newer SDK. Two isolated Anthropic SDK versions are therefore
|
|
1271
|
-
expected. `RuntimeRunOptions.claudeAgentQuery` provides deterministic Claude
|
|
1272
|
-
tests without mocking package resolution or sending real SDK traffic.
|
|
1273
|
-
If a downstream test suite still needs Pi's faux-provider helpers, isolate that
|
|
1274
|
-
fixture or keep its development-only Pi dependency on the runtime's exact
|
|
1275
|
-
`0.80.6` version until the fixture is removed; a broad host range can otherwise
|
|
959
|
+
dependencies are `@earendil-works/pi-agent-core`, `@earendil-works/pi-ai`,
|
|
960
|
+
`@modelcontextprotocol/sdk`, `@vscode/ripgrep`, `cross-spawn`, and `zod`.
|
|
961
|
+
|
|
962
|
+
The runtime owns and exact-pins its Pi dependencies; consumers use the runtime's
|
|
963
|
+
Pi façade rather than coordinating a second direct `@earendil-works/pi-ai`
|
|
964
|
+
dependency. If a downstream test suite still needs Pi's faux-provider helpers,
|
|
965
|
+
isolate that fixture or keep its development-only Pi dependency on the runtime's
|
|
966
|
+
exact version until the fixture is removed; a broad host range can otherwise
|
|
1276
967
|
float Pi Agent Core's own upstream dependency independently of this façade.
|
|
1277
968
|
|
|
1278
969
|
Sandbox enforcement is an injectable `RuntimeSandbox` seam.
|