@mono-agent/agent-runtime 0.20.11 → 0.21.0
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/ARCHITECTURE.md +50 -11
- package/MIGRATION.md +288 -26
- package/README.md +352 -477
- package/package.json +13 -44
- package/src/agent/tool-bloat.js +145 -9
- package/src/agent/tools/agent-tool.js +108 -9
- package/src/agent/tools/bash.js +11 -26
- package/src/agent/tools/codex-subscription-search.js +123 -29
- package/src/agent/tools/exec.js +10 -2
- package/src/agent/tools/index.js +7 -0
- package/src/agent/tools/monitor.js +149 -0
- package/src/agent/tools/pi-bridge.js +123 -19
- package/src/agent/tools/shared/bash-environment.js +31 -0
- package/src/agent/tools/shared/monitors.js +293 -0
- package/src/agent/tools/shared/path-resolver.js +25 -6
- package/src/agent/tools/shared/process-jobs.js +6 -1
- package/src/agent/tools/shared/process-runner.js +26 -6
- package/src/agent/tools/shared/tool-context.js +8 -0
- package/src/agent/tools/web-access-interstitial.js +70 -0
- package/src/agent/tools/web-browser-render.js +83 -58
- package/src/agent/tools/web-controller.js +112 -21
- package/src/agent/tools/web-document-extractor.js +379 -0
- package/src/agent/tools/web-fetch.js +271 -243
- package/src/agent/tools/web-request.js +65 -0
- package/src/agent/tools/web-search-output.js +165 -0
- package/src/agent/tools/web-search-state.js +75 -0
- package/src/agent/tools/web-search.js +532 -71
- package/src/ai/cost.js +13 -68
- package/src/ai/failure.js +3 -3
- package/src/ai/index.js +5 -17
- package/src/ai/observer.js +8 -0
- package/src/ai/pi-interop.js +221 -1
- package/src/ai/pi-oauth-compat.js +1 -1
- package/src/ai/provider-check.js +131 -0
- 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 +94 -42
- package/src/ai/providers/pi-native/compaction-summary.js +140 -0
- package/src/ai/providers/pi-native/harness-adapter.js +376 -0
- package/src/ai/providers/pi-native/prompt-cache-diagnostics.js +103 -0
- package/src/ai/providers/pi-native/provider-attribution.js +102 -0
- package/src/ai/providers/pi-native/result-builder.js +38 -14
- package/src/ai/providers/pi-native/session-lifecycle.js +253 -55
- package/src/ai/providers/pi-native/stream-subscriber.js +52 -6
- package/src/ai/providers/pi-native/terminal-recovery.js +40 -0
- package/src/ai/providers/pi-native/turn-runner.js +279 -28
- package/src/ai/providers/pi-native.js +206 -61
- package/src/ai/runtime/capabilities.js +11 -56
- package/src/ai/runtime/live-input-events.js +250 -54
- package/src/ai/runtime/model-refs.js +118 -153
- package/src/ai/runtime/registry.js +22 -56
- package/src/ai/runtime/router.js +76 -417
- 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/tool-lifecycle.js +32 -18
- package/src/ai/types.js +37 -112
- package/src/index.js +0 -6
- package/src/runtime.js +29 -16
- package/types/agent/tool-bloat.d.ts +1 -1
- package/types/agent/tools/agent-tool.d.ts +4 -2
- package/types/agent/tools/bash.d.ts +5 -3
- package/types/agent/tools/codex-subscription-search.d.ts +7 -3
- package/types/agent/tools/exec.d.ts +5 -3
- package/types/agent/tools/index.d.ts +1 -0
- package/types/agent/tools/monitor.d.ts +47 -0
- package/types/agent/tools/pi-bridge.d.ts +7 -4
- package/types/agent/tools/shared/bash-environment.d.ts +4 -0
- package/types/agent/tools/shared/monitors.d.ts +98 -0
- package/types/agent/tools/shared/process-jobs.d.ts +5 -1
- package/types/agent/tools/shared/process-runner.d.ts +14 -4
- package/types/agent/tools/shared/tool-context.d.ts +2 -0
- package/types/agent/tools/web-access-interstitial.d.ts +23 -0
- package/types/agent/tools/web-browser-render.d.ts +4 -1
- package/types/agent/tools/web-controller.d.ts +4 -2
- package/types/agent/tools/web-document-extractor.d.ts +27 -0
- package/types/agent/tools/web-fetch.d.ts +19 -24
- package/types/agent/tools/web-request.d.ts +20 -0
- package/types/agent/tools/web-search-output.d.ts +31 -0
- package/types/agent/tools/web-search-state.d.ts +21 -0
- package/types/agent/tools/web-search.d.ts +10 -45
- package/types/ai/cost.d.ts +1 -2
- package/types/ai/index.d.ts +2 -4
- package/types/ai/observer.d.ts +6 -0
- package/types/ai/pi-interop.d.ts +81 -0
- package/types/ai/provider-check.d.ts +53 -0
- package/types/ai/providers/codex/app-server-client.d.ts +37 -0
- package/types/ai/providers/pi-native/compaction-driver.d.ts +2 -1
- package/types/ai/providers/pi-native/compaction-summary.d.ts +19 -0
- package/types/ai/providers/pi-native/harness-adapter.d.ts +58 -0
- package/types/ai/providers/pi-native/prompt-cache-diagnostics.d.ts +3 -0
- package/types/ai/providers/pi-native/provider-attribution.d.ts +26 -0
- package/types/ai/providers/pi-native/result-builder.d.ts +14 -4
- package/types/ai/providers/pi-native/session-lifecycle.d.ts +25 -6
- package/types/ai/providers/pi-native/stream-subscriber.d.ts +2 -2
- package/types/ai/providers/pi-native/terminal-recovery.d.ts +2 -0
- package/types/ai/providers/pi-native/turn-runner.d.ts +68 -10
- package/types/ai/providers/pi-native.d.ts +21 -4
- package/types/ai/runtime/capabilities.d.ts +21 -70
- package/types/ai/runtime/live-input-events.d.ts +32 -8
- 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/tool-lifecycle.d.ts +4 -3
- package/types/ai/types.d.ts +162 -256
- 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,14 @@ 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
|
-
|
|
30
|
-
|
|
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`.
|
|
29
|
+
|
|
30
|
+
When a host enables background Exec/Bash, `wake_on_completion` defaults to true;
|
|
31
|
+
explicit false retains terminal lifecycle updates without a completion turn.
|
|
32
|
+
Using that field without `background: true` is invalid. Host-provided
|
|
33
|
+
`processJobsAvailability` exposes lineage and exhaustion diagnostics even
|
|
34
|
+
when a request has no start controller.
|
|
31
35
|
|
|
32
36
|
Create one runtime for a host, parse a model reference, and run a turn:
|
|
33
37
|
|
|
@@ -39,8 +43,7 @@ import {
|
|
|
39
43
|
|
|
40
44
|
const runtime = createRuntime({ workspace: process.cwd() });
|
|
41
45
|
const result = await runtime.run("You are a concise repository assistant.", {
|
|
42
|
-
model: parseRuntimeModelReference("
|
|
43
|
-
executionMode: "sdk",
|
|
46
|
+
model: parseRuntimeModelReference("anthropic:claude-sonnet-4-6"),
|
|
44
47
|
messages: [{ role: "user", content: "Summarize README.md." }],
|
|
45
48
|
cwd: process.cwd(),
|
|
46
49
|
allowedTools: ["Read"],
|
|
@@ -50,6 +53,16 @@ if (result.error) throw new Error(result.error);
|
|
|
50
53
|
console.log(result.text);
|
|
51
54
|
```
|
|
52
55
|
|
|
56
|
+
Requests to Pi providers `opencode` and `opencode-go`, and to custom models whose
|
|
57
|
+
exact URL hostname is `opencode.ai`, carry `x-opencode-client: mono-agent` and an
|
|
58
|
+
`x-opencode-session` continuity value. The value is the raw internal provider
|
|
59
|
+
session id, not a channel conversation id. It remains stable for a continuous
|
|
60
|
+
conversation epoch, rotates on reset or invalidation, and is fresh per call when
|
|
61
|
+
a direct caller supplies no session or attribution identity. Existing
|
|
62
|
+
case-insensitive auth/model/request headers—including explicit `null`
|
|
63
|
+
suppression—and caller header transforms take precedence. Other providers receive
|
|
64
|
+
no `x-opencode-*` headers.
|
|
65
|
+
|
|
53
66
|
`Glob` and `Grep` prefer the packaged `@vscode/ripgrep` binary on supported
|
|
54
67
|
platforms. An explicit `ripgrepPath` wins, with `PATH` as the final fallback.
|
|
55
68
|
|
|
@@ -61,19 +74,24 @@ capability. The host then explicitly intersects the two reviewed protocol
|
|
|
61
74
|
revisions, reads only the originating tool's declared `ui://` resource, and
|
|
62
75
|
receives one exact connection capability. Successful registration retains that
|
|
63
76
|
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.
|
|
77
|
+
eviction closes the client, transport, and sandbox cleanup.
|
|
66
78
|
See [Reply files and MCP Apps](https://mono-agent-docs.vercel.app/tools/rich-replies/).
|
|
67
79
|
|
|
68
80
|
## Architecture
|
|
69
81
|
|
|
82
|
+
The injected Pi-native `Monitor` tool supports `wake_on: "batch" | "exit"`,
|
|
83
|
+
`dedupe: "none" | "batch"`, and `min_wake_interval_ms` (defaults batch/none/0).
|
|
84
|
+
The start receipt reports the host's effective policy, including interval
|
|
85
|
+
clamping. Terminal delivery bypasses batch suppression and timing. A cancelled
|
|
86
|
+
watch is intentionally stopped and must not be automatically recreated.
|
|
87
|
+
|
|
70
88
|
The package uses a fixed registry of bridge descriptors and loads provider code
|
|
71
89
|
only after a run selects a matching model reference and execution mode:
|
|
72
90
|
|
|
73
91
|
### Data flow
|
|
74
92
|
|
|
75
93
|
1. `createRuntime()` binds host callbacks and creates an isolated tool context.
|
|
76
|
-
2. `resolveRuntimeBridge()`
|
|
94
|
+
2. `resolveRuntimeBridge()` resolves the single static bridge descriptor.
|
|
77
95
|
3. The selected descriptor lazily imports its provider implementation.
|
|
78
96
|
4. The bridge prepares the runtime inputs it supports, including managed or MCP
|
|
79
97
|
tools only where that bridge can represent them, and streams normalized
|
|
@@ -91,7 +109,7 @@ only after a run selects a matching model reference and execution mode:
|
|
|
91
109
|
| --- | --- |
|
|
92
110
|
| `src/runtime.js` | Host binding, per-instance tool context, bridge dispatch, and observer flushing |
|
|
93
111
|
| `src/ai/runtime/` | Model-reference parsing, the lazy bridge registry, capabilities, sessions, and fallback routing |
|
|
94
|
-
| `src/ai/providers/` |
|
|
112
|
+
| `src/ai/providers/` | Pi provider integrations |
|
|
95
113
|
| `src/agent/tools/` | Managed tools, MCP adaptation, output limits, and the injectable sandbox seam |
|
|
96
114
|
| `src/agent/` | Approvals, allowlists, transcript snapshots, and compaction policy helpers |
|
|
97
115
|
|
|
@@ -100,13 +118,23 @@ the [architecture guide](https://github.com/robertsreberski/mono-agent/blob/main
|
|
|
100
118
|
|
|
101
119
|
### Managed-tool lifecycle fidelity
|
|
102
120
|
|
|
121
|
+
Native event admission precedes queued storage: observers receive `recordEvent`
|
|
122
|
+
and optional `recordToolLifecycle` callbacks synchronously. The latter receives
|
|
123
|
+
the normalized lifecycle event before persistence begins. This lets the harness
|
|
124
|
+
retain work emitted before cancellation while its sidecar is busy. Persistence
|
|
125
|
+
and client delivery remain serialized; later cancellation cannot reclassify an
|
|
126
|
+
already admitted tool result.
|
|
127
|
+
|
|
103
128
|
`RuntimeRunOptions.toolLifecycleSink` is an awaited host-owned boundary. The
|
|
104
129
|
runtime sends redaction-eligible raw arguments/content plus stable provider call
|
|
105
130
|
id and name; the host returns only record/sequence, persistence/truncation byte
|
|
106
131
|
metadata, and opaque artifact references. That returned metadata is attached to
|
|
107
|
-
the exact normalized `tool_use` / `tool_result` event rendered by clients.
|
|
108
|
-
|
|
109
|
-
|
|
132
|
+
the exact normalized `tool_use` / `tool_result` event rendered by clients.
|
|
133
|
+
`persistence: "deferred"` preserves a host-accepted write whose foreground
|
|
134
|
+
confirmation window elapsed; `failed` plus an error code is reserved for a
|
|
135
|
+
definitive sink rejection. Both remain fail-soft for the provider outcome and
|
|
136
|
+
neither is converted into fake success. A callback exception cannot duplicate a
|
|
137
|
+
client event.
|
|
110
138
|
|
|
111
139
|
Provider bridges only claim terminal distinctions their structured protocol
|
|
112
140
|
actually supplies:
|
|
@@ -114,11 +142,6 @@ actually supplies:
|
|
|
114
142
|
| Bridge | Genuine tool-result distinctions | Conservative fallback |
|
|
115
143
|
| --- | --- | --- |
|
|
116
144
|
| 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
145
|
|
|
123
146
|
The runtime never derives a state from result prose. Structured timeout, signal,
|
|
124
147
|
non-zero exit, completed success, and a specific non-runtime, non-cancellation
|
|
@@ -157,13 +180,14 @@ provider-supplied known kind when available and otherwise `runtime_error`.
|
|
|
157
180
|
| API | Use it for |
|
|
158
181
|
| --- | --- |
|
|
159
182
|
| `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
183
|
| `createRouterRuntime()` | Retry an ordered model chain while preserving explicit route-safety contracts |
|
|
162
|
-
| `parseRuntimeModelReference()` | Convert a canonical
|
|
163
|
-
| `listRuntimeBridges()` / `runtimeCapabilities()` | Inspect the
|
|
184
|
+
| `parseRuntimeModelReference()` | Convert a canonical `<provider>:<model>` string into the object required by `run()` |
|
|
185
|
+
| `listRuntimeBridges()` / `runtimeCapabilities()` | Inspect the built-in bridge descriptor without loading provider implementations |
|
|
164
186
|
| `createPiOAuthApiKeyResolver()` | Bind a host-owned Pi auth file with refresh-safe writes |
|
|
165
187
|
| `listPiBuiltinModels()` / `getPiBuiltinModel()` | Read cloned snapshots from the runtime-owned, exact-pinned Pi model catalog without importing Pi directly |
|
|
166
188
|
| `resolvePiOAuthApiKey()` / `loginPiOAuth()` | Use the runtime-owned Pi OAuth implementation without importing Pi's mutable provider registry |
|
|
189
|
+
| `describePiProviderAuth()` / `checkPiProviderAuth()` / `loginPiProviderAuth()` | Bridge Pi's provider-owned auth descriptions, detection, prompts, device events, and returned credential without exposing its mutable registry |
|
|
190
|
+
| `runPiProviderCheck()` | Execute one isolated, bounded Pi request for an explicitly selected provider/model and return only a fixed sanitized outcome; only provider-construction options are admitted, never session/history/tool/hook state |
|
|
167
191
|
| `createMetricsObserver()` | Aggregate normalized event, token, cache, cost, tool, error, turn, and approval metrics |
|
|
168
192
|
|
|
169
193
|
Most hosts should use `@mono-agent/runtime-adapter` instead of importing deep
|
|
@@ -178,25 +202,26 @@ Every symbol exported by each public code entrypoint is listed below.
|
|
|
178
202
|
**`@mono-agent/agent-runtime`**
|
|
179
203
|
|
|
180
204
|
```text
|
|
181
|
-
ACP_PROTOCOL_VERSION
|
|
182
|
-
ACTIVE_RUNTIME_KINDS
|
|
183
205
|
ALLOWLIST_MODE_ALL
|
|
184
206
|
ALLOWLIST_MODE_CUSTOM
|
|
185
207
|
APPROVAL_DECISIONS
|
|
186
|
-
AcpCallbackContext
|
|
187
|
-
AcpClientError
|
|
188
|
-
AcpClientHostOptions
|
|
189
|
-
AcpInteractionRequest
|
|
190
|
-
AcpListedSession
|
|
191
|
-
AcpProfileDescriptor
|
|
192
|
-
AcpSessionListResult
|
|
193
208
|
BINARY_BLOAT_TOOLS
|
|
194
209
|
BridgeSpec
|
|
195
|
-
CLAUDE_SDK_CATALOG_VERSION
|
|
196
210
|
DEFAULT_RUNTIME_BRAND
|
|
197
211
|
DEFAULT_TOOL_BLOAT_CONFIG
|
|
198
212
|
MAX_TOOL_RESULT_BYTES
|
|
199
|
-
|
|
213
|
+
PROVIDER_CHECK_PROMPT
|
|
214
|
+
PiBuiltinModelSnapshot
|
|
215
|
+
PiBuiltinProviderSnapshot
|
|
216
|
+
PiOAuthCredentialsSnapshot
|
|
217
|
+
PiOAuthLoginCallbacks
|
|
218
|
+
PiProviderAuthCheck
|
|
219
|
+
PiProviderAuthDescription
|
|
220
|
+
PiProviderAuthInteraction
|
|
221
|
+
PiProviderAuthPrompt
|
|
222
|
+
PiReasoningLevel
|
|
223
|
+
ProviderCheckCode
|
|
224
|
+
ProviderCheckOutcome
|
|
200
225
|
RISK_TIERS
|
|
201
226
|
RUNTIME_CAPABILITIES
|
|
202
227
|
RuntimeBridge
|
|
@@ -204,47 +229,38 @@ RuntimeBridgeDescriptor
|
|
|
204
229
|
RuntimeBridgeId
|
|
205
230
|
RuntimeModelRef
|
|
206
231
|
UNKNOWN_CAPABILITY
|
|
207
|
-
acpRuntimeBridge
|
|
208
|
-
authenticateAcpProfile
|
|
209
232
|
buildCapabilitiesUsed
|
|
210
233
|
buildTranscriptTailSnapshot
|
|
211
|
-
|
|
234
|
+
checkPiProviderAuth
|
|
235
|
+
classifyProviderCheckFailure
|
|
212
236
|
configureToolRuntime
|
|
213
237
|
createApprovalManager
|
|
214
|
-
createClaudeSdkDiscoveryIsolation
|
|
215
238
|
createMetricsObserver
|
|
216
239
|
createObserverHub
|
|
217
240
|
createPiOAuthApiKeyResolver
|
|
218
241
|
createRouterRuntime
|
|
219
242
|
createRuntime
|
|
220
243
|
createSessionRegistry
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
discoverClaudeSdkModels
|
|
244
|
+
describePiBuiltinProvider
|
|
245
|
+
describePiProviderAuth
|
|
224
246
|
disposeAllProviderSessions
|
|
225
247
|
disposeProviderSession
|
|
226
|
-
executionModeIncompatibilityReason
|
|
227
|
-
generateAcpResponse
|
|
228
248
|
generatePiNativeResponse
|
|
229
249
|
getPiBuiltinModel
|
|
230
250
|
inferAllowlistMode
|
|
231
251
|
invalidateProviderSession
|
|
232
252
|
isLikelyContextTermination
|
|
233
|
-
isModelCompatibleWithExecutionMode
|
|
234
|
-
listAcpSessions
|
|
235
253
|
listPiBuiltinModels
|
|
254
|
+
listPiBuiltinProviders
|
|
236
255
|
listRuntimeBridges
|
|
237
256
|
loginPiOAuth
|
|
238
|
-
|
|
257
|
+
loginPiProviderAuth
|
|
239
258
|
normalizeAllowlistMode
|
|
240
|
-
normalizeClaudeSdkCatalog
|
|
241
|
-
normalizeClaudeSdkModelId
|
|
242
259
|
normalizeList
|
|
243
260
|
normalizeRuntimeModelReference
|
|
244
261
|
parseRuntimeModelReference
|
|
245
262
|
parseStoredAllowlist
|
|
246
263
|
piNativeRuntimeBridge
|
|
247
|
-
probeAcpProfile
|
|
248
264
|
readRuntimeBrand
|
|
249
265
|
readToolRuntime
|
|
250
266
|
reasoningLevelsForPiModel
|
|
@@ -257,13 +273,11 @@ resolveAllowlistMap
|
|
|
257
273
|
resolvePiOAuthApiKey
|
|
258
274
|
resolveRuntimeBrand
|
|
259
275
|
resolveRuntimeBridge
|
|
276
|
+
runPiProviderCheck
|
|
260
277
|
runtimeCapabilities
|
|
261
|
-
sdkFromModelReference
|
|
262
278
|
storedAllowlistMode
|
|
263
279
|
syncProviderSession
|
|
264
280
|
toolCompactionAppliedFromWarnings
|
|
265
|
-
validateAcpProfileId
|
|
266
|
-
validateAcpProviderSessionId
|
|
267
281
|
wrapToolsWithApprovalGate
|
|
268
282
|
```
|
|
269
283
|
|
|
@@ -332,6 +346,8 @@ inferSkillsRoot
|
|
|
332
346
|
|
|
333
347
|
```text
|
|
334
348
|
DEFAULT_CODEX_SEARCH_MODEL
|
|
349
|
+
DEFAULT_MONITOR_TIMEOUT_MS
|
|
350
|
+
MIN_MONITOR_TIMEOUT_MS
|
|
335
351
|
bashToolImpl
|
|
336
352
|
bashToolRun
|
|
337
353
|
createWebToolController
|
|
@@ -343,9 +359,12 @@ grepToolImpl
|
|
|
343
359
|
inspectCodexSubscriptionSearch
|
|
344
360
|
isPathAllowed
|
|
345
361
|
isWorkdirAllowed
|
|
362
|
+
monitorStopToolRun
|
|
363
|
+
monitorToolRun
|
|
346
364
|
normalizeBackgroundBashTimeoutMs
|
|
347
365
|
normalizeBackgroundTimeoutMs
|
|
348
366
|
normalizeBashTimeoutMs
|
|
367
|
+
normalizeMonitorTimeoutMs
|
|
349
368
|
normalizeProcessTimeoutMs
|
|
350
369
|
performWebFetch
|
|
351
370
|
performWebSearch
|
|
@@ -393,64 +412,54 @@ renderResumeSnapshot
|
|
|
393
412
|
**`@mono-agent/agent-runtime/ai`**
|
|
394
413
|
|
|
395
414
|
```text
|
|
396
|
-
ACP_PROTOCOL_VERSION
|
|
397
|
-
ACTIVE_RUNTIME_KINDS
|
|
398
|
-
AcpCallbackContext
|
|
399
|
-
AcpClientError
|
|
400
|
-
AcpClientHostOptions
|
|
401
|
-
AcpInteractionRequest
|
|
402
|
-
AcpListedSession
|
|
403
|
-
AcpProfileDescriptor
|
|
404
|
-
AcpSessionListResult
|
|
405
415
|
BridgeSpec
|
|
406
|
-
|
|
407
|
-
|
|
416
|
+
PROVIDER_CHECK_PROMPT
|
|
417
|
+
PiBuiltinModelSnapshot
|
|
418
|
+
PiBuiltinProviderSnapshot
|
|
419
|
+
PiOAuthCredentialsSnapshot
|
|
420
|
+
PiOAuthLoginCallbacks
|
|
421
|
+
PiProviderAuthCheck
|
|
422
|
+
PiProviderAuthDescription
|
|
423
|
+
PiProviderAuthInteraction
|
|
424
|
+
PiProviderAuthPrompt
|
|
425
|
+
PiReasoningLevel
|
|
426
|
+
ProviderCheckCode
|
|
427
|
+
ProviderCheckOutcome
|
|
408
428
|
RUNTIME_CAPABILITIES
|
|
409
429
|
RuntimeBridge
|
|
410
430
|
RuntimeBridgeDescriptor
|
|
411
431
|
RuntimeBridgeId
|
|
412
432
|
RuntimeModelRef
|
|
413
433
|
UNKNOWN_CAPABILITY
|
|
414
|
-
acpRuntimeBridge
|
|
415
|
-
authenticateAcpProfile
|
|
416
434
|
buildCapabilitiesUsed
|
|
417
|
-
|
|
418
|
-
|
|
435
|
+
checkPiProviderAuth
|
|
436
|
+
classifyProviderCheckFailure
|
|
419
437
|
createMetricsObserver
|
|
420
438
|
createObserverHub
|
|
421
439
|
createSessionRegistry
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
discoverClaudeSdkModels
|
|
440
|
+
describePiBuiltinProvider
|
|
441
|
+
describePiProviderAuth
|
|
425
442
|
disposeAllProviderSessions
|
|
426
443
|
disposeProviderSession
|
|
427
|
-
executionModeIncompatibilityReason
|
|
428
|
-
generateAcpResponse
|
|
429
444
|
generatePiNativeResponse
|
|
430
445
|
getPiBuiltinModel
|
|
431
446
|
invalidateProviderSession
|
|
432
|
-
isModelCompatibleWithExecutionMode
|
|
433
|
-
listAcpSessions
|
|
434
447
|
listPiBuiltinModels
|
|
448
|
+
listPiBuiltinProviders
|
|
435
449
|
listRuntimeBridges
|
|
436
450
|
loginPiOAuth
|
|
437
|
-
|
|
438
|
-
normalizeClaudeSdkCatalog
|
|
439
|
-
normalizeClaudeSdkModelId
|
|
451
|
+
loginPiProviderAuth
|
|
440
452
|
normalizeRuntimeModelReference
|
|
441
453
|
parseRuntimeModelReference
|
|
442
454
|
piNativeRuntimeBridge
|
|
443
|
-
probeAcpProfile
|
|
444
455
|
reasoningLevelsForPiModel
|
|
445
456
|
refreshProviderSession
|
|
446
457
|
resolvePiOAuthApiKey
|
|
447
458
|
resolveRuntimeBridge
|
|
459
|
+
runPiProviderCheck
|
|
448
460
|
runtimeCapabilities
|
|
449
|
-
sdkFromModelReference
|
|
450
461
|
syncProviderSession
|
|
451
462
|
toolCompactionAppliedFromWarnings
|
|
452
|
-
validateAcpProfileId
|
|
453
|
-
validateAcpProviderSessionId
|
|
454
463
|
```
|
|
455
464
|
|
|
456
465
|
**`@mono-agent/agent-runtime/ai/cost.js`**
|
|
@@ -498,93 +507,32 @@ statsForCompletedChange
|
|
|
498
507
|
formatLiveInputGuidance
|
|
499
508
|
```
|
|
500
509
|
|
|
501
|
-
**`@mono-agent/agent-runtime/ai/providers/
|
|
502
|
-
|
|
503
|
-
```text
|
|
504
|
-
acpRuntimeBridge
|
|
505
|
-
generateAcpResponse
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
**`@mono-agent/agent-runtime/ai/providers/claude-cli.js`**
|
|
510
|
+
**`@mono-agent/agent-runtime/ai/providers/codex/app-server-client.js`**
|
|
509
511
|
|
|
510
512
|
```text
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
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
|
|
513
|
+
CODEX_APP_SERVER_ARGS
|
|
514
|
+
CODEX_APP_SERVER_ISOLATED_ARGS
|
|
515
|
+
addOpaqueSensitiveValue
|
|
516
|
+
codexErrorMessage
|
|
545
517
|
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
|
|
518
|
+
isCodexRequestTimeout
|
|
519
|
+
isSensitivePayloadField
|
|
520
|
+
normalizedSensitiveName
|
|
521
|
+
redactCodexDiagnostic
|
|
522
|
+
redactCodexPayload
|
|
523
|
+
sanitizeCodexDiagnostic
|
|
524
|
+
sanitizeCodexNotification
|
|
525
|
+
sanitizeCodexResponseError
|
|
526
|
+
sensitiveEnvironmentValues
|
|
527
|
+
utf8Head
|
|
574
528
|
```
|
|
575
529
|
|
|
576
530
|
**`@mono-agent/agent-runtime/ai/runtime/model-refs.js`**
|
|
577
531
|
|
|
578
532
|
```text
|
|
579
|
-
ACTIVE_RUNTIME_KINDS
|
|
580
|
-
RESERVED_RUNTIME_KINDS
|
|
581
533
|
RuntimeModelRef
|
|
582
|
-
canonicalizeLegacyModelReference
|
|
583
|
-
executionModeIncompatibilityReason
|
|
584
|
-
isModelCompatibleWithExecutionMode
|
|
585
534
|
normalizeRuntimeModelReference
|
|
586
535
|
parseRuntimeModelReference
|
|
587
|
-
sdkFromModelReference
|
|
588
536
|
```
|
|
589
537
|
|
|
590
538
|
**`@mono-agent/agent-runtime/ai/runtime/registry.js`**
|
|
@@ -600,33 +548,21 @@ resolveRuntimeBridge
|
|
|
600
548
|
runtimeCapabilities
|
|
601
549
|
```
|
|
602
550
|
|
|
603
|
-
**`@mono-agent/agent-runtime/ai/streaming/codex-events.js`**
|
|
604
|
-
|
|
605
|
-
```text
|
|
606
|
-
normalizeCodexItemEvent
|
|
607
|
-
normalizeCodexItemType
|
|
608
|
-
```
|
|
609
|
-
|
|
610
551
|
<!-- public-api-inventory:end -->
|
|
611
552
|
|
|
612
553
|
### When to reach for this vs. other JS agent runtimes
|
|
613
554
|
|
|
614
555
|
`@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
556
|
|
|
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
|
|
557
|
+
- **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.
|
|
558
|
+
- **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
559
|
- **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
560
|
- **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
561
|
- **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
562
|
|
|
622
563
|
**What we natively bridge (no extra packages):**
|
|
623
564
|
|
|
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.
|
|
565
|
+
- 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
566
|
|
|
631
567
|
**At-a-glance:**
|
|
632
568
|
|
|
@@ -646,81 +582,28 @@ normalizeCodexItemType
|
|
|
646
582
|
|
|
647
583
|
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
584
|
|
|
649
|
-
###
|
|
585
|
+
### Model references
|
|
650
586
|
|
|
651
|
-
|
|
587
|
+
There is one runtime. A `model` is a parsed
|
|
588
|
+
`{ provider, model, reference }` object whose `reference` must be the canonical
|
|
589
|
+
`<provider>:<model>` spelling; convert reference strings with
|
|
590
|
+
`parseRuntimeModelReference()` before calling `run()` — `run()` does not parse
|
|
591
|
+
strings.
|
|
652
592
|
|
|
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.
|
|
593
|
+
#### ACP
|
|
594
|
+
|
|
595
|
+
The ACP *client* runtime backend was removed in 0.21.0. `mono-agent bridge acp`
|
|
596
|
+
— serving ACP to clients — is unaffected and lives in `@mono-agent/agent-app`.
|
|
710
597
|
|
|
711
598
|
### `createRuntime(host)`
|
|
712
599
|
|
|
713
|
-
Pass host-level integration once at boot.
|
|
714
|
-
backend contract requires them.
|
|
600
|
+
Pass host-level integration once at boot. Every key is optional.
|
|
715
601
|
|
|
716
602
|
```js
|
|
717
603
|
createRuntime({
|
|
718
604
|
// -- host callbacks --
|
|
719
605
|
resolveCustomPricing, // (parsed) => NormalizedPricing | null
|
|
720
606
|
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
607
|
persistArtifact, // ({ filename, buffer, toolName, toolUseId }) => path | null
|
|
725
608
|
onCompactionRecorded, // (compactionRow) => void — fired when the pi bridge
|
|
726
609
|
// runs an automatic compaction (proactive or reactive
|
|
@@ -729,6 +612,8 @@ createRuntime({
|
|
|
729
612
|
// -- tool runtime context (process-level config for the tool kernel) --
|
|
730
613
|
workspace, // primary allowed root for path-based tools
|
|
731
614
|
repoRoot, // secondary allowed root
|
|
615
|
+
additionalReadRoots, // extra realpath-contained file-tool read roots
|
|
616
|
+
additionalWriteRoots, // extra realpath-contained file-tool write roots
|
|
732
617
|
ripgrepPath, // explicit path to `rg`; falls back to packaged binary, then PATH
|
|
733
618
|
qaOutputDir, // fallback dir for Playwright MCP filename routing
|
|
734
619
|
sandboxPolicy, // optional SandboxPolicy for tools and stdio MCP (enforced
|
|
@@ -744,9 +629,10 @@ createRuntime({
|
|
|
744
629
|
observers: [],
|
|
745
630
|
|
|
746
631
|
// -- 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
|
|
632
|
+
// Optional. When set, the runtime asks the host before every BUILT-IN tool
|
|
633
|
+
// call whose risk tier is "medium" or "high" (and not session-allowlisted).
|
|
634
|
+
// MCP-backed tools are not gated. See the "Approval gates" section below
|
|
635
|
+
// for the request/response shape.
|
|
750
636
|
onToolApprovalRequest, // async (req) => { decision, reason? }
|
|
751
637
|
toolRiskTiers: { Bash: "high" }, // per-tool tier override (low|medium|high)
|
|
752
638
|
approvalDefaultRiskTier: "medium",
|
|
@@ -761,9 +647,6 @@ createRuntime({
|
|
|
761
647
|
tempdirPrefix: "agent-runtime-cli-", // mkdtemp prefix for CLI provider scratch dirs
|
|
762
648
|
providerModelPrefix: "agent", // id prefix for custom Pi providers
|
|
763
649
|
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
650
|
},
|
|
768
651
|
});
|
|
769
652
|
```
|
|
@@ -793,6 +676,10 @@ defensively cloned model snapshots; `getPiBuiltinModel(providerId, modelId)`
|
|
|
793
676
|
returns one cloned snapshot or `undefined`; and
|
|
794
677
|
`reasoningLevelsForPiModel(model)` translates a Pi model into mono-agent's
|
|
795
678
|
reasoning vocabulary, including `none` rather than Pi's `off`.
|
|
679
|
+
Pi 0.85.1 exposes GPT-6 Astra through these same catalog APIs as
|
|
680
|
+
`openai:gpt-6-astra` for OpenAI API keys and
|
|
681
|
+
`openai-codex:gpt-6-astra` for Codex subscriptions; no separate model allowlist
|
|
682
|
+
is maintained by mono-agent.
|
|
796
683
|
`resolvePiOAuthApiKey(providerId, credentials)` refreshes a caller-owned
|
|
797
684
|
credential snapshot and returns `{ apiKey, newCredentials }` or `null`, while
|
|
798
685
|
`loginPiOAuth(providerId, callbacks)` runs the selected supported login flow.
|
|
@@ -802,13 +689,25 @@ manual-code, and abort callbacks pass through unchanged.
|
|
|
802
689
|
These functions deliberately do not expose Pi's mutable model collections or
|
|
803
690
|
OAuth-provider registry.
|
|
804
691
|
|
|
692
|
+
Headless hosts can instead use `describePiProviderAuth()` to enumerate a
|
|
693
|
+
provider's OAuth/API-key methods, `checkPiProviderAuth()` to distinguish stored
|
|
694
|
+
or ambient credential detection without refreshing or making a model request,
|
|
695
|
+
and `loginPiProviderAuth()` to relay Pi's typed prompts and events. The last
|
|
696
|
+
function returns a credential to its caller but does not persist it; the owning
|
|
697
|
+
application must apply its own safe-store transaction and must never serialize
|
|
698
|
+
prompt answers into an operator projection. Abort can close supported Pi flows
|
|
699
|
+
and discard an uncooperative provider's late result, but it cannot undo a
|
|
700
|
+
provider-side grant or a filesystem mutation that already began; the owning app
|
|
701
|
+
must fence pre-mutation persistence and safely drain atomic promotion/cleanup.
|
|
702
|
+
|
|
805
703
|
Returns:
|
|
806
704
|
|
|
807
705
|
- `run(systemPrompt, options)` — async, runs one agent turn against the chosen backend.
|
|
808
706
|
- `configureTools(next)` — update the tool runtime context after construction.
|
|
809
707
|
- `syncSession(id)` — fsync provider-owned durable state before canonical history commits.
|
|
810
708
|
- `refreshSession(id)` — guarantee the next resume cannot reuse process-local state; absence succeeds and cleanup uncertainty rejects.
|
|
811
|
-
- `
|
|
709
|
+
- `recoverSession(receipt, { appliedInputIds })` — validate and fsync an opted-in, settled durable Pi tail without executing the provider or appending a message. A host-owned `sessionRecovery: { runId, revision }` run option enables receipts; retries/backups strip that option and every returned receipt. Pending recovery blocks native resume. Failed/aborted assistant messages stay on disk and are filtered by Pi; completed tool evidence retains its native bytes. False or uncertain recovery requires host retirement. See [session recovery](../../docs/runtime/sessions-concurrency.md).
|
|
710
|
+
- `retireDurableSession(id, sessionsRoot)` — delete and verify every exact-id durable Pi transcript, including cold duplicates. If the matching live session is still unwinding after cancellation or failure, refresh it out of the registry and unlink and fsync its current JSONL; a post-runtime retry also removes any headerless exact-name file recreated by a late append. Uncoordinated calls retain the legacy rollback behavior; opted-in admitted durable calls can retain a provisional tail for host recovery.
|
|
812
711
|
- `disposeSession(id)` / `invalidateSession(id)` / `disposeAllSessions()` — ordinary best-effort eviction, destructive live invalidation, and shutdown cleanup.
|
|
813
712
|
|
|
814
713
|
#### `runtime.run(systemPrompt, options)`
|
|
@@ -818,163 +717,58 @@ Per-call options (a non-exhaustive selection):
|
|
|
818
717
|
| Option | Type | Notes |
|
|
819
718
|
|---|---|---|
|
|
820
719
|
| `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
720
|
| `messages` | `Message[]` | Conversation history. |
|
|
823
721
|
| `cwd` | `string` | Working directory for the agent's tools. |
|
|
824
722
|
| `allowedTools` | `string[]` | Built-in tool allowlist. Default: all. |
|
|
825
723
|
| `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. |
|
|
724
|
+
| `subagents` | `RuntimeSubagentsOptions` | In-process `Agent` delegation: profiles, caps, and the nested-run callback. This replaced the withdrawn caller-defined native teammate profiles. |
|
|
725
|
+
| `skills` / `skillsRoot` | `{name, description}[]` / `string` | Skills disclosed to the run and the directory holding `<name>/SKILL.md`. |
|
|
726
|
+
| `mcpServers` | `Record<string, McpServerConfig>` | Configured MCP servers (stdio / sse / http). |
|
|
831
727
|
| `sandboxPolicy` | `SandboxPolicy` | Optional fail-closed sandbox policy for built-in tools and stdio MCP process startup. |
|
|
832
|
-
| `webSearchConfig` | `{ backend?, endpoint?, codex?: { model? } }` | Run-scoped
|
|
728
|
+
| `webSearchConfig` | `{ backend?, maxRequestsPerRun?, searxng?: { endpoint? }, ollama?: { baseUrl?, apiKey?, apiKeyEnv?, trustPublicUrl? }, codex?: { model? } }` | Run-scoped ordered WebSearch selection and a 1–20 actual-provider-request budget (default 4). `auto` uses explicitly configured Ollama, configured SearXNG, Codex, then keyless; named modes are strict. The deprecated top-level `endpoint` remains a SearXNG compatibility alias. |
|
|
833
729
|
| `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
|
|
730
|
+
| `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
731
|
| `maxTurns` | `number` | Hard cap on agent turns. |
|
|
836
|
-
| `outputSchema` | `JSONSchema` | Requests structured JSON
|
|
732
|
+
| `outputSchema` | `JSONSchema` | Requests structured JSON; see “Structured output” below. |
|
|
837
733
|
| `abortSignal` | `AbortSignal` | Cancel the run. |
|
|
838
|
-
| `liveInput` | `AsyncIterable<
|
|
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. |
|
|
734
|
+
| `liveInput` | `AsyncIterable<RuntimeLiveInputMessage>` | Stream of in-flight user messages. `accepted` reports native queue acceptance; `acknowledge` reports exact owned-operation transcript consumption; `uncertain` fences ambiguous delivery; proved-safe `reject` permits identified router replay. Stable nonblank IDs are required for cross-attempt replay. |
|
|
840
735
|
| `onEvent` | `(event) => void` | Fired for every runtime event (assistant text, tool calls/results, applied live input, runtime warnings, structured output). |
|
|
736
|
+
| `persistArtifact` | `({ filename, buffer, toolName, toolUseId }) => path \| null` | Synchronous artifact sink for this run. A run value overrides the host default and route-attempt resolvers cannot replace it. |
|
|
841
737
|
| `runId` | `string` | Tag this run for downstream callbacks (e.g. `onCompactionRecorded`). |
|
|
842
738
|
| `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. |
|
|
739
|
+
| `runArtifactDir` | `string` | Used as the Playwright MCP filename target. |
|
|
847
740
|
|
|
848
741
|
`runtimeCapabilities()` and each descriptor returned by
|
|
849
|
-
`listRuntimeBridges()` expose `tool_policy`.
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
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.
|
|
920
|
-
|
|
921
|
-
Returns:
|
|
922
|
-
|
|
923
|
-
```ts
|
|
924
|
-
{
|
|
925
|
-
text: string, // raw assistant text
|
|
926
|
-
structuredResult?: any, // captured JSON on supported bridges
|
|
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`.
|
|
742
|
+
`listRuntimeBridges()` expose `tool_policy`. The Pi bridge reports
|
|
743
|
+
`"projected"`, meaning it projects restrictive `allowedTools` /
|
|
744
|
+
`disallowedTools` as written, so named-only lists, `[]`, and denylists are all
|
|
745
|
+
supported. A wildcard dominates named entries, so `["*", "Read"]` is allow-all.
|
|
746
|
+
The `"allow_all_only"` value survives for custom structural bridges that accept
|
|
747
|
+
only an effective unrestricted policy; omission by such a bridge means the
|
|
748
|
+
capability is unknown.
|
|
749
|
+
|
|
750
|
+
Live input is native on the Pi bridge. Native acceptance is not consumption.
|
|
751
|
+
Consumption requires the exact Pi entry's user `message_end` in the one
|
|
752
|
+
main-lane prompt operation owned by the Mono run, plus the prompt result's
|
|
753
|
+
matching operation ID. This proves transcript incorporation only—not provider
|
|
754
|
+
receipt, answer use, or adherence. `live_input_consumed` records native
|
|
755
|
+
evidence; legacy `live_input_applied` follows only when host acknowledgement
|
|
756
|
+
returns exactly `recorded`. Void, `ignored`, throwing, or thenable callbacks
|
|
757
|
+
produce settlement-unconfirmed diagnostics instead of false success.
|
|
758
|
+
|
|
759
|
+
The logical-run fence keys stable IDs across retry and failover. The first
|
|
760
|
+
occurrence owns its body and callbacks; later same-ID occurrences are suppressed
|
|
761
|
+
as invalid duplicates. A proved pre-acceptance rejection or native queue removal
|
|
762
|
+
can replay the original owner. Accepted, consumed, and uncertain IDs never
|
|
763
|
+
replay. Missing IDs remain compatible but are exposed only in the first iterator
|
|
764
|
+
generation. Diagnostics contain metadata only, never guidance bodies.
|
|
765
|
+
|
|
766
|
+
### Project instructions
|
|
767
|
+
|
|
768
|
+
The Pi runtime does not read another tool's filesystem settings, hooks, plugins,
|
|
769
|
+
or project documents. Subagents are the kernel's own in-process delegation
|
|
770
|
+
surface (the `Agent` tool), configured by the host rather than discovered from a
|
|
771
|
+
provider's on-disk profiles.
|
|
978
772
|
|
|
979
773
|
### Built-in tools
|
|
980
774
|
|
|
@@ -988,12 +782,13 @@ by one lazily started Node.js REPL child per run. You select them via
|
|
|
988
782
|
`allowedTools`. Tool implementations honor:
|
|
989
783
|
|
|
990
784
|
- `cwd` (required for path-based tools)
|
|
991
|
-
- The runtime context's `workspace` / `repoRoot` allow-list (paths outside both, plus `/tmp` and `process.cwd()`, are rejected)
|
|
992
|
-
- Output truncation with optional artifact persistence
|
|
785
|
+
- The runtime context's `workspace` / `repoRoot` allow-list (paths outside both, plus `/tmp` and `process.cwd()`, are rejected), with optional `additionalReadRoots` / `additionalWriteRoots` for narrowly scoped managed file-tool access. Additional roots require both the requested path and its realpath to stay inside the configured roots, so a symlink cannot escape them.
|
|
786
|
+
- Output truncation with optional host-provided artifact persistence. The configured app binds this per run under `artifacts.dir/tool-output/<runId>/`.
|
|
993
787
|
|
|
994
788
|
The Pi-native tool context may structurally receive a host process-job
|
|
995
|
-
controller. Only then do Exec and Bash add optional `background
|
|
996
|
-
|
|
789
|
+
controller. Only then do Exec and Bash add optional `background` and
|
|
790
|
+
`wake_on_completion`. A host can disclose lineage diagnostics independently
|
|
791
|
+
of that controller; a background request without one is rejected. A background call
|
|
997
792
|
hands the exact prepared command to the controller and stops awaiting it. The
|
|
998
793
|
kernel first creates a command-agnostic detached POSIX group leader; only after
|
|
999
794
|
the host durably records its PID, equal PGID, and process incarnation does the
|
|
@@ -1004,14 +799,34 @@ contract package for this boundary.
|
|
|
1004
799
|
|
|
1005
800
|
`NodeRepl` uses Node's default `node:repl` evaluator, so variables, `_`, `_error`, and loaded modules persist across calls in the same run. It supports multiline input and top-level `await`, resolves workspace-installed packages, and is closed with the run. Its child is prepared through the same sandbox seam as `Exec`/`Bash` and communicates through token-authenticated, length-prefixed JSON frames on ordinary stdin/stdout; abort, the fixed 120-second timeout, child exit, or hard output overflow resets the session. It deliberately has no session ids, persistent history, terminal commands, or package-install surface.
|
|
1006
801
|
|
|
1007
|
-
`WebSearch` uses a configured loopback SearXNG
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
802
|
+
`WebSearch` uses explicit Ollama Web Search, a configured loopback SearXNG
|
|
803
|
+
endpoint, and deterministic public fallbacks. Strict backends do not fall
|
|
804
|
+
through, and `auto` tries explicitly configured Ollama → configured SearXNG →
|
|
805
|
+
Codex → keyless. Hosted Ollama bearer credentials are accepted only for the
|
|
806
|
+
exact official origin. Search canonicalizes and deduplicates results, trying
|
|
807
|
+
supplied alternate queries only if the primary has no relevant results. Codex
|
|
808
|
+
subscription search preserves a 10% allowance reserve. An optional host-injected
|
|
809
|
+
coordinator shares admission and cooldowns across processes. `WebFetch`
|
|
810
|
+
deterministically decodes and extracts HTML, JSON, feeds, PDFs, and text locally
|
|
811
|
+
with bounded redirects, bodies, headers, retries, and structured parser
|
|
812
|
+
failures. Config can opt into isolated `agent-browser` rendering for sparse
|
|
813
|
+
client-rendered HTML; an explicit `render: "always"` call is browser-first.
|
|
814
|
+
One ephemeral controller per run deduplicates identical calls and closes every
|
|
815
|
+
browser namespace at run end. WebFetch `start_line` and `max_lines` reuse a
|
|
816
|
+
bounded run-scoped document cache. Search and fetch use total deadlines of 60
|
|
817
|
+
and 45 seconds respectively, with bounded transport cleanup after cancellation.
|
|
818
|
+
WebSearch also shares a default hard budget of four actual provider requests
|
|
819
|
+
across route retries in one logical run. Cache hits, in-flight followers,
|
|
820
|
+
cooldown skips, and quota skips do not spend it. Rate-limited providers are
|
|
821
|
+
deferred for that run, with retry timing and an explicit next action returned
|
|
822
|
+
to the model; children and later runs receive fresh budgets.
|
|
823
|
+
|
|
824
|
+
Each normalized WebSearch result caps its title at 500 characters and its
|
|
825
|
+
snippet at 4,000 characters, including a visible truncation marker directing
|
|
826
|
+
the model to `WebFetch`. The ranked result body is capped at 64 KiB UTF-8;
|
|
827
|
+
lower-ranked snippets shrink before whole results are omitted, while the
|
|
828
|
+
control, metadata, filter, and balanced untrusted-result framing always remain.
|
|
829
|
+
Ollama receives the caller's effective 1–10 result limit as `max_results`.
|
|
1015
830
|
|
|
1016
831
|
Pi runs with selected skills also expose `ReadSkill`. It returns the complete
|
|
1017
832
|
skill instructions by default, including content beyond the former
|
|
@@ -1021,51 +836,59 @@ truncation is explicitly desired; omitting it is not a separate hidden limit.
|
|
|
1021
836
|
The standard 256 KiB tool-payload guard still applies to oversized tool results.
|
|
1022
837
|
|
|
1023
838
|
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.
|
|
839
|
+
Declaring a server is the authorization boundary: it exposes that server's whole
|
|
840
|
+
tool surface to the run, and `sandboxPolicy` does not reach state the server
|
|
841
|
+
owns on the other side of the connection. Do not declare a server whose complete
|
|
842
|
+
tool surface is not authorized for the run: there is no per-call gate behind it.
|
|
843
|
+
`onToolApprovalRequest` wraps the built-in tool set only (`getPiBuiltinTools`);
|
|
844
|
+
`initPiMcpTools` is initialized without an approval manager, so an MCP call runs
|
|
845
|
+
without asking the host, whatever risk tier is configured.
|
|
1035
846
|
|
|
1036
847
|
### Structured output
|
|
1037
848
|
|
|
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.
|
|
849
|
+
Pass `options.outputSchema` (a JSON Schema). The Pi runtime surfaces captured
|
|
850
|
+
JSON as `result.structuredResult`.
|
|
1047
851
|
|
|
1048
852
|
### Provider fallback router
|
|
1049
853
|
|
|
1050
|
-
`createRouterRuntime({ host, chain,
|
|
854
|
+
`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. Only the primary's first attempt can keep a provider session; retries and backups are stateless and their successful results withhold `providerSessionId`. Entry `effort` is tri-state: a string fixes that route, `null` asks for provider default, and omission inherits the legacy per-run effort.
|
|
855
|
+
|
|
856
|
+
The primary's first attempt owns the provider session. Retries and failovers run
|
|
857
|
+
stateless with bounded transcript-tail replay. With coordinated durable Pi history,
|
|
858
|
+
any answer from a retry or backup retires the primary epoch. The next turn
|
|
859
|
+
cold-reseeds from canonical history; after a primary first-attempt success,
|
|
860
|
+
subsequent turns resume the new session and are eligible for provider caching.
|
|
861
|
+
|
|
862
|
+
On a warm turn whose primary attempt fails, the retry or backup attempt runs
|
|
863
|
+
stateless with the current message and a bounded snapshot of the failed attempt,
|
|
864
|
+
without the earlier conversation; the next turn reseeds from canonical history.
|
|
865
|
+
|
|
866
|
+
Provider attribution remains stable across attempts even when the router withholds
|
|
867
|
+
the resumable result id. Fresh stateless Pi calls use a private in-memory repository
|
|
868
|
+
to avoid colliding with, or deleting, a primary transcript sharing that attribution.
|
|
869
|
+
Lifecycle methods forward to the router's original inner runtime; a custom
|
|
870
|
+
`resolveAttempt().runtime` must not assume those methods target its own independent
|
|
871
|
+
session store.
|
|
1051
872
|
|
|
1052
873
|
```js
|
|
1053
|
-
import { createRouterRuntime } from "@mono-agent/agent-runtime";
|
|
874
|
+
import { createRouterRuntime, parseRuntimeModelReference } from "@mono-agent/agent-runtime";
|
|
1054
875
|
|
|
876
|
+
// A RuntimeModelRef is { provider, model, reference }; `reference` is required
|
|
877
|
+
// and must be the canonical `<provider>:<model>` spelling, so build refs with
|
|
878
|
+
// parseRuntimeModelReference rather than writing the object literal by hand.
|
|
1055
879
|
const router = createRouterRuntime({
|
|
1056
880
|
host: { /* same shape as createRuntime */ },
|
|
1057
|
-
routeSafety: "per-route-native",
|
|
1058
881
|
// Backoff shape for same-model retries; per-route counts live on `attempts`.
|
|
1059
882
|
retry: { backoffMs: 1000, maxBackoffMs: 15000 },
|
|
1060
883
|
chain: [
|
|
1061
|
-
{ model:
|
|
1062
|
-
{ model:
|
|
1063
|
-
{ model:
|
|
884
|
+
{ model: parseRuntimeModelReference("anthropic:claude-sonnet-5"), effort: "high", attempts: 2 },
|
|
885
|
+
{ model: parseRuntimeModelReference("openai-codex:gpt-5.6-sol"), effort: "xhigh" },
|
|
886
|
+
{ model: parseRuntimeModelReference("ollama:gemma4:31b"), effort: null },
|
|
1064
887
|
],
|
|
1065
888
|
});
|
|
1066
889
|
|
|
1067
890
|
const result = await router.run("...", { /* same shape as runtime.run */ });
|
|
1068
|
-
console.log(result.failoverHistory
|
|
891
|
+
console.log(result.failoverHistory);
|
|
1069
892
|
```
|
|
1070
893
|
|
|
1071
894
|
Behaviour:
|
|
@@ -1073,32 +896,30 @@ Behaviour:
|
|
|
1073
896
|
- Successful run on entry N → returns the result with `failoverHistory` set to attempts 0..N-1.
|
|
1074
897
|
- 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
898
|
- 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: `
|
|
899
|
+
- 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
900
|
- 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
901
|
- 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
902
|
- Provider auth failure → retries the next chain entry and preserves `failureKind: "provider_auth"` in `failoverHistory` for the failed attempt.
|
|
1080
903
|
- Malformed request/config/billing-type non-retryable failure → returns immediately with `failoverHistory` containing the one attempt.
|
|
1081
904
|
- Cancellation → returns immediately.
|
|
1082
905
|
- 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.
|
|
906
|
+
- Every route is Pi-native, so the whole chain shares one monotonic runtime
|
|
907
|
+
contract. There is no per-route safety negotiation and no
|
|
908
|
+
`provider_route_safety` event: with a single contract there is nothing to
|
|
909
|
+
reconcile between routes. Pi routes retain the sandbox policy, including
|
|
910
|
+
routes reached through `Agent` children.
|
|
1094
911
|
- A resolver-supplied Pi runtime may own provider credentials and lifecycle,
|
|
1095
912
|
but must expose `configureTools()`: before every attempt the router replaces
|
|
1096
913
|
its mutable tool context with the router's effective host/configured safety
|
|
1097
914
|
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
|
-
|
|
915
|
+
that cannot accept this projection fails the attempt before it runs.
|
|
916
|
+
- Attempt-resolver failures — that missing `configureTools()` included — surface
|
|
917
|
+
as `failureKind: "provider_unavailable"`, with the error text fixed to
|
|
918
|
+
`The route attempt could not be resolved before execution.` (only a
|
|
919
|
+
`ResolverProtectedOptionError`, built from a repository-owned allowlist key,
|
|
920
|
+
reports its own message). Resolver credentials/options never enter result
|
|
921
|
+
telemetry, and such a failure advances to the next entry rather than consuming
|
|
922
|
+
the route's remaining `attempts`.
|
|
1102
923
|
- `resolveAttempt` runs once per attempt — including every same-model retry — and
|
|
1103
924
|
receives `{ attemptIndex, retryIndex }`, where `attemptIndex` stays the chain
|
|
1104
925
|
index. Its `cleanup` runs after each attempt.
|
|
@@ -1116,12 +937,16 @@ The runtime emits structured events for everything that happens during a run —
|
|
|
1116
937
|
A built-in aggregator covers the common metrics:
|
|
1117
938
|
|
|
1118
939
|
```js
|
|
1119
|
-
import {
|
|
940
|
+
import {
|
|
941
|
+
createMetricsObserver,
|
|
942
|
+
createRuntime,
|
|
943
|
+
parseRuntimeModelReference,
|
|
944
|
+
} from "@mono-agent/agent-runtime";
|
|
1120
945
|
|
|
1121
946
|
const metrics = createMetricsObserver();
|
|
1122
947
|
const runtime = createRuntime({ observers: [metrics] });
|
|
1123
948
|
|
|
1124
|
-
await runtime.run("...", { model:
|
|
949
|
+
await runtime.run("...", { model: parseRuntimeModelReference("anthropic:claude-sonnet-4-6") });
|
|
1125
950
|
|
|
1126
951
|
console.log(metrics.snapshot());
|
|
1127
952
|
// {
|
|
@@ -1146,7 +971,7 @@ Notable new events emitted by the bridges:
|
|
|
1146
971
|
|
|
1147
972
|
### Approval gates (human-in-the-loop)
|
|
1148
973
|
|
|
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.
|
|
974
|
+
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
975
|
|
|
1151
976
|
```js
|
|
1152
977
|
const runtime = createRuntime({
|
|
@@ -1175,32 +1000,86 @@ Responses:
|
|
|
1175
1000
|
- `{ decision: "deny", reason? }` — block; the agent receives a tool error.
|
|
1176
1001
|
- `{ decision: "always" }` — allow + session-allowlist for the run.
|
|
1177
1002
|
|
|
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.
|
|
1003
|
+
Coverage is the Pi runtime's built-in tool set, via tool dispatch wrapping.
|
|
1004
|
+
MCP-backed tools are outside the gate — the MCP bridge is built without an
|
|
1005
|
+
approval manager — so for those, declaring the server is the authorization
|
|
1006
|
+
boundary, not approving the call.
|
|
1187
1007
|
|
|
1188
1008
|
### Tool-result bloat handling
|
|
1189
1009
|
|
|
1190
1010
|
The kernel's tool-bloat guard (`agent/tool-bloat.js`, internal) enforces a 256 KB default cap per `tool_result`. When a payload exceeds the cap, the kernel:
|
|
1191
1011
|
|
|
1192
1012
|
1. Calls your `persistArtifact({ filename, buffer, toolName, toolUseId })` callback (if you supplied one).
|
|
1193
|
-
2.
|
|
1013
|
+
2. For text-only overflow, substitutes a compact summary plus a UTF-8-safe
|
|
1014
|
+
60/40 head/tail sample inside a new balanced untrusted frame. The explicit
|
|
1015
|
+
notice says the omitted middle may contain content and the retained tail is
|
|
1016
|
+
not the source ending. Image, binary, and mixed payloads stay summary-only.
|
|
1194
1017
|
3. Emits a `runtime_warning` with `warning_kind: "tool_payload_truncated"` and the saved-paths array.
|
|
1195
1018
|
|
|
1196
|
-
Hosts that don't supply `persistArtifact
|
|
1019
|
+
Hosts that don't supply `persistArtifact`, or whose sink fails, get honest
|
|
1020
|
+
`persistence unavailable` text and no on-disk capture; the tool call still
|
|
1021
|
+
completes. The configured app writes owner-private raw, untrusted files under
|
|
1022
|
+
`artifacts.dir/tool-output/<runId>/`. Neither run-artifact retention nor
|
|
1023
|
+
tool-history retention cleans them up automatically.
|
|
1197
1024
|
|
|
1198
1025
|
Before that byte cap runs, the builtin `Read` tool normalizes raster images with an edge longer than 8,000 px to fit within an 8,000 × 8,000 px box. Resizing preserves aspect ratio and the source format (resized BMP input becomes PNG), retains GIF/WebP animation, and never modifies the source file. Images already within the limit are embedded byte-for-byte unchanged.
|
|
1199
1026
|
|
|
1027
|
+
### System instructions and transcript assembly
|
|
1028
|
+
|
|
1029
|
+
The host supplies stable system instructions separately from ordered messages.
|
|
1030
|
+
`@mono-agent/agent-harness` projects core/SOUL, identity and skill instructions
|
|
1031
|
+
by typed section ids; its full inspection prompt is not dispatched as system
|
|
1032
|
+
text. The runtime still appends its structured-output instruction here.
|
|
1033
|
+
The current user message starts with the host's latest Session/warm-skill
|
|
1034
|
+
envelope, followed by user/attachment text and recall. Tool authorization and
|
|
1035
|
+
delivery routing remain host-enforced.
|
|
1036
|
+
|
|
1037
|
+
On every cold/stateless/retry path, canonical historical text precedes the cold
|
|
1038
|
+
untrusted tool-history projection and current turn. Canonical replay preserves
|
|
1039
|
+
speaker and stored timestamp labels, but cannot reconstruct native reasoning
|
|
1040
|
+
signatures or tool calls. A true Pi resume skips all supplied prior messages and
|
|
1041
|
+
keeps its native transcript; a missing durable JSONL seeds prior messages once.
|
|
1042
|
+
History retention remains last-64 for the configured host. Compaction can replace
|
|
1043
|
+
an older native prefix and remove previously loaded skill bodies, so warm-skill
|
|
1044
|
+
guidance only says complete instructions may remain visible.
|
|
1045
|
+
|
|
1200
1046
|
### Context compaction
|
|
1201
1047
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1048
|
+
Summary preparation preserves labelled heads and tails of text tool results within
|
|
1049
|
+
Pi's 2,000-character serializer allowance. Copies retain tool identities and
|
|
1050
|
+
arguments; live results remain unchanged. Confirmed `Read`/`Write`/`Edit` results
|
|
1051
|
+
augment file metadata using `file_path`; failed or unmatched writes remain
|
|
1052
|
+
unresolved evidence. File metadata and supplemental file-operation evidence each
|
|
1053
|
+
have a 4 KiB bound, with omission counts. Record references remain unavailable
|
|
1054
|
+
without a proven host resolver.
|
|
1055
|
+
|
|
1056
|
+
A versioned focus supplements both Pi summary requests, including split turns:
|
|
1057
|
+
intent, approval constraints, open work, decisions, exact symbols, errors, and next
|
|
1058
|
+
action, distinguishing current instructions from superseded ones. Pi's prompts,
|
|
1059
|
+
cut rules, recent tail and output budgets remain unchanged. Empty, malformed,
|
|
1060
|
+
aborted and output-truncated summaries are rejected before persistence.
|
|
1061
|
+
|
|
1062
|
+
Each `context_compaction` event includes metadata-only `accounting` (version 1).
|
|
1063
|
+
Terminal events retain separately identified summary requests and their status,
|
|
1064
|
+
duration, provider tokens and cost, including rejected requests. Missing usage or
|
|
1065
|
+
cost stays `null`. Transcript and full-request before/after estimates are comparable
|
|
1066
|
+
and explicitly inexact; `afterSource` distinguishes a candidate preview from the
|
|
1067
|
+
persisted context. Summary text estimates, appended metadata bytes, tail
|
|
1068
|
+
estimate, policy and preparation omission counts are separate. Summary content,
|
|
1069
|
+
paths, tool arguments and raw cache keys are excluded from accounting.
|
|
1070
|
+
|
|
1071
|
+
With prompt-cache diagnostics enabled, assistant payload diagnostics and usage
|
|
1072
|
+
share a request ID and phase. `context_usage.providerCostUsd` preserves unknown
|
|
1073
|
+
provider cost as `null` alongside the existing compatibility cost field. Summary requests use operation-scoped IDs in
|
|
1074
|
+
compaction accounting; their usage never flows into assistant request totals.
|
|
1075
|
+
`scripts/summarize-prompt-cache.mjs` reports boundaries, separate assistant/summary
|
|
1076
|
+
cost, and first differing observed message fingerprints for full inputs. Differences
|
|
1077
|
+
are evidence of payload changes, not proof of cache misses; delta/unsupported
|
|
1078
|
+
prefix comparisons remain unknown. Pi summary requests retain their existing
|
|
1079
|
+
`cacheRetention: "none"` behavior.
|
|
1080
|
+
|
|
1081
|
+
The sole pi bridge runs on pi-agent-core's native `AgentHarness`. Pi supports native checkpoint and overflow compaction; mono-agent disables that path
|
|
1082
|
+
and drives guarded compaction itself: before each turn it estimates the
|
|
1204
1083
|
running model's context usage and calls `AgentHarness.compact()` when near the window
|
|
1205
1084
|
(proactive), and if a turn still overflows it compacts once and re-prompts exactly once
|
|
1206
1085
|
only after a rebuilt-context preview proves positive reduction (reactive recovery).
|
|
@@ -1256,23 +1135,18 @@ These are stable but treated as advanced API. Most consumers should reach for `c
|
|
|
1256
1135
|
|
|
1257
1136
|
## Dependency Boundary
|
|
1258
1137
|
|
|
1259
|
-
This package has zero `@mono-agent/*` workspace dependencies. Its runtime
|
|
1260
|
-
|
|
1261
|
-
`@
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
`@earendil-works/pi-ai`
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
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
|
|
1138
|
+
This package has zero `@mono-agent/*` workspace dependencies. Its runtime core
|
|
1139
|
+
uses `@earendil-works/pi-agent-core`, `@earendil-works/pi-ai`,
|
|
1140
|
+
`@modelcontextprotocol/sdk`, `@vscode/ripgrep`, `cross-spawn`, and `zod`.
|
|
1141
|
+
Managed web extraction owns its direct parser dependencies: Defuddle,
|
|
1142
|
+
Readability, linkedom, Turndown, fast-xml-parser, and unpdf. Image inspection
|
|
1143
|
+
uses bmp-ts and sharp.
|
|
1144
|
+
|
|
1145
|
+
The runtime owns and exact-pins its Pi dependencies; consumers use the runtime's
|
|
1146
|
+
Pi façade rather than coordinating a second direct `@earendil-works/pi-ai`
|
|
1147
|
+
dependency. If a downstream test suite still needs Pi's faux-provider helpers,
|
|
1148
|
+
isolate that fixture or keep its development-only Pi dependency on the runtime's
|
|
1149
|
+
exact version until the fixture is removed; a broad host range can otherwise
|
|
1276
1150
|
float Pi Agent Core's own upstream dependency independently of this façade.
|
|
1277
1151
|
|
|
1278
1152
|
Sandbox enforcement is an injectable `RuntimeSandbox` seam.
|
|
@@ -1298,7 +1172,8 @@ runtime fails closed.
|
|
|
1298
1172
|
- [Programmatic approvals and structured output](https://mono-agent-docs.vercel.app/programmatic/approval-and-structured-output/)
|
|
1299
1173
|
shows the code-only host hooks.
|
|
1300
1174
|
- [Local-first web research](https://mono-agent-docs.vercel.app/tools/web-research/)
|
|
1301
|
-
documents SearXNG, extraction, retry, browser isolation, and
|
|
1175
|
+
documents Ollama/SearXNG selection, extraction, retry, browser isolation, and
|
|
1176
|
+
sandbox policy.
|
|
1302
1177
|
- [Reply files and MCP Apps](https://mono-agent-docs.vercel.app/tools/rich-replies/)
|
|
1303
1178
|
documents the host bridge, browser sandbox, and lifecycle limits.
|
|
1304
1179
|
- [Architecture](https://github.com/robertsreberski/mono-agent/blob/main/packages/agent-runtime/ARCHITECTURE.md)
|