@mono-agent/agent-runtime 0.15.0 → 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/MIGRATION.md CHANGED
@@ -11,9 +11,118 @@ exports map, a five-bridge lazy registry, typed policy objects, stricter sandbox
11
11
  behavior, and revised provider-session semantics even when Pi is not your
12
12
  primary route.
13
13
 
14
+ Migration policy: every newly introduced fail-closed validation belongs in the
15
+ first affected version section, even when it tightens behavior without changing
16
+ the configuration schema.
17
+
14
18
  ---
15
19
 
16
- ## Pre-1.0 public-surface cleanup
20
+ ## 0.15.2
21
+
22
+ - **Tool-policy capability discovery:** built-in bridge capabilities now report
23
+ `tool_policy: "projected" | "allow_all_only"`. Pi, Claude SDK, and Claude Code
24
+ report `projected`; direct Codex and direct OpenCode report
25
+ `allow_all_only`. Custom structural bridges that omit the field have unknown
26
+ capability.
27
+ - **Wildcard normalization:** any `allowedTools` list containing `"*"` is
28
+ semantically allow-all. Direct Codex, direct OpenCode, and the public legacy
29
+ Codex CLI export now accept forms such as `["*", "Read"]` when
30
+ `disallowedTools` is empty. Named-only lists, `[]`, and every non-empty
31
+ denylist still fail closed on those non-projecting routes. The guided Codex
32
+ readiness probe retains its exact no-tool contract.
33
+ - **Telemetry compatibility:** the route-safety value
34
+ `tools: "exact-allow-all"` is unchanged. It now explicitly denotes the
35
+ effective unrestricted contract rather than requiring a literal one-element
36
+ `["*"]` array.
37
+
38
+ ## 0.15.1
39
+
40
+ - **Runtime-owned Pi interoperability:** consumers that directly import
41
+ `@earendil-works/pi-ai` only for catalog, reasoning, or OAuth behavior should
42
+ switch to `listPiBuiltinModels`, `getPiBuiltinModel`,
43
+ `reasoningLevelsForPiModel`, `resolvePiOAuthApiKey`, and `loginPiOAuth` from
44
+ `@mono-agent/agent-runtime/ai`. The runtime keeps Pi AI and Pi Agent Core
45
+ exact-pinned at `0.80.6`; the façade returns cloned model and credential
46
+ snapshots rather than exposing mutable upstream registries.
47
+ - **Claude test seam:** downstream tests should pass
48
+ `RuntimeRunOptions.claudeAgentQuery` instead of mocking
49
+ `@anthropic-ai/claude-agent-sdk` by package name. Normal runs omit this option
50
+ and use the runtime-owned SDK. Pi AI's `@anthropic-ai/sdk@0.91.1` pin and the
51
+ Claude Agent SDK's `@anthropic-ai/sdk>=0.93.0` requirement intentionally
52
+ remain as two isolated SDK versions.
53
+ - **Compaction policy cleanup:** the inert
54
+ `toolPayloadCompactionTriggerChars` and `toolPruneTriggerTokens` properties
55
+ were removed from `AgentCompactionPolicy`, policy resolution, defaults, and
56
+ declarations. They had no supported typed/config path and did not activate
57
+ runtime pruning, so no replacement is required.
58
+ - **Codex live-input teardown:** a Codex app-server transport death now also
59
+ terminates a pending live-input read. Runs settle with the existing
60
+ `provider_unavailable` / `codex_app_server_closed` classification instead of
61
+ waiting forever for the input iterator. If a host `acknowledge` or `reject`
62
+ callback throws, the already-decided native steering result remains
63
+ authoritative and the runtime emits a bounded
64
+ `live_input_callback_failed` warning.
65
+
66
+ ## 0.15.x baseline
67
+
68
+ This is the current published baseline for the detailed pre-1.0 reference
69
+ below. It includes the explicit exports map, the five-bridge lazy registry,
70
+ typed runtime policies, runtime-owned provider dependencies, and the
71
+ public-surface cleanup described in this guide.
72
+
73
+ ## 0.12.x
74
+
75
+ - Persistent provider context overflow is classified as `context_limit`, which
76
+ lets a fallback router try its next model without conflating context capacity
77
+ with quota, output, or max-turn `usage_limit` failures.
78
+ - Omitted Pi compaction values resolve from effective context window `W`:
79
+ trigger ratio `0.70`, retained context `10%`, summary output `4%`, and minimum
80
+ proactive savings `10%`, subject to the documented scalar clamps. Numeric
81
+ provider limits and generic overflow evidence may lower a learned
82
+ process-local ceiling; `contextWindowOverride` remains the persistent
83
+ correction.
84
+
85
+ ## 0.10.x
86
+
87
+ - Direct Codex normal runs introduced a fail-closed tool-policy gate: omitted
88
+ `allowedTools` or the explicit `["*"]` sentinel was accepted with no denied
89
+ tools, while named-only allowlists, `[]`, and deny lists were rejected before
90
+ provider startup. Version 0.15.2 preserves that safety boundary while
91
+ normalizing every wildcard-containing allowlist to the same effective
92
+ allow-all meaning.
93
+ - `ReadSkill` returns complete skill instructions by default, including content
94
+ beyond the former 12,000-character boundary. Programmatic callers of
95
+ `formatSkillBodyWithPathNote()` opt into truncation by passing a positive
96
+ `maxChars`; omitting it means no helper-level cap. The standard 256 KiB
97
+ tool-payload guard remains in effect.
98
+
99
+ ## 0.7.x
100
+
101
+ - Omitting Claude SDK effort now preserves the provider default instead of
102
+ deriving a `thinking` option. Supported effort values are forwarded exactly;
103
+ explicit `none` is unsupported (`skipped_capability_mismatch` through the
104
+ bridge, while direct `claudeEffortOptions("none")` calls throw).
105
+ - Cancellation uses a private abort controller and closes the active Claude SDK
106
+ `Query` with `Query.close()`. Test doubles must honor both boundaries rather
107
+ than implementing only iterator `return()`.
108
+ - `Glob` and `Grep` prefer an explicit `ripgrepPath`, then the packaged
109
+ `@vscode/ripgrep` binary on supported platforms, and finally `PATH`.
110
+
111
+ ## 0.6.2
112
+
113
+ - Codex file edits use a flat top-level `file_change` event instead of synthetic
114
+ assistant/user `file_edit` tool-use/tool-result pairs.
115
+ - The synthetic `createClaudeFileEditHooks`,
116
+ `createFileEditToolUseEvent`, and `createFileEditToolResultEvent` exports were
117
+ removed. Consumers should observe normalized runtime events or use the
118
+ remaining file-change statistics helpers rather than recreating provider hook
119
+ behavior.
120
+
121
+ ---
122
+
123
+ ## Detailed pre-1.0 reference
124
+
125
+ ### Pre-1.0 public-surface cleanup
17
126
 
18
127
  The compatibility entrypoints `./ai/backend.js` and `./ai/registry.js` were
19
128
  removed after repository-wide reachability checks found no supported caller.
@@ -24,7 +133,7 @@ instead. Runtime behavior and the canonical bridge descriptors are unchanged.
24
133
 
25
134
  ---
26
135
 
27
- ## 1. Pi is now native-only (`pi-sdk.js` → `pi-native.js`)
136
+ ### 1. Pi is now native-only (`pi-sdk.js` → `pi-native.js`)
28
137
 
29
138
  The hand-rolled Pi bridge that drove the low-level `Agent` was replaced by a
30
139
  bridge built on `@earendil-works/pi-agent-core`'s high-level `AgentHarness`. The
@@ -43,7 +152,7 @@ registry resolves `pi` → the native bridge unconditionally; there is no
43
152
  `@mono-agent/agent-runtime/ai/failure.js`. The `pi*Backend` aliases are gone —
44
153
  all Pi routes through the native bridge.
45
154
 
46
- ## 2. Removed run options: `piReasoningSummary`, `piCodexTransport`
155
+ ### 2. Removed run options: `piReasoningSummary`, `piCodexTransport`
47
156
 
48
157
  These were Pi-bridge knobs the native path does not consume.
49
158
 
@@ -54,7 +163,7 @@ These were Pi-bridge knobs the native path does not consume.
54
163
  `runtime.reasoningSummary` config field has also been removed.
55
164
  - `piCodexTransport` was doc-only and is removed. No replacement is needed.
56
165
 
57
- ## 3. Pi context compaction: bridge-driven via AgentHarness.compact()
166
+ ### 3. Pi context compaction: bridge-driven via AgentHarness.compact()
58
167
 
59
168
  `AgentHarness` has no automatic compaction, so the pi bridge drives it directly
60
169
  (the legacy low-level `transformContext` / `afterToolCall` hooks and
@@ -76,7 +185,7 @@ These were Pi-bridge knobs the native path does not consume.
76
185
  correction. Deprecated programmatic `agent_compaction_*` settings and
77
186
  `resolveAgentCompactionPolicy` remain compatibility surfaces.
78
187
 
79
- ## 4. Durable Pi session resume: create-on-miss semantics
188
+ ### 4. Durable Pi session resume: create-on-miss semantics
80
189
 
81
190
  When a run supplies a `providerSessionId` (or the legacy `sessionId` alias) **and**
82
191
  durable storage is configured (`piSessionsRoot`), Pi-native now **creates the
@@ -91,7 +200,7 @@ passed an arbitrary `providerSessionId` to a durable run expecting a hard
91
200
  The in-memory (non-durable) resume path still fast-fails `session_not_found` on a
92
201
  miss.
93
202
 
94
- ## 5. Fallback router enforces requested native-subagent capability
203
+ ### 5. Fallback router enforces requested native-subagent capability
95
204
 
96
205
  Pi advertises `supports_native_subagents: false`. The fallback router now infers
97
206
  a `supports_native_subagents` requirement when a run passes
@@ -103,7 +212,7 @@ a `supports_native_subagents` requirement when a run passes
103
212
  native-subagent runs, ensure at least one entry supports native subagents, or the
104
213
  run reports exhausted instead of degrading silently.
105
214
 
106
- ## 6. Diagnostics & internal behavior changes (no API change)
215
+ ### 6. Diagnostics & internal behavior changes (no API change)
107
216
 
108
217
  - **Pi multimodal**: image inputs are delivered to the model as image content
109
218
  blocks (internal fix; affects behavior, not the call shape).
@@ -119,7 +228,7 @@ run reports exhausted instead of degrading silently.
119
228
  resumed sessions roll back to their pre-turn leaf on host-side (outer-catch)
120
229
  failures. These are correctness fixes with no API surface change.
121
230
 
122
- ## 7. Sandbox enforcement is now an injectable seam (agent-runtime has zero workspace-package dependencies)
231
+ ### 7. Sandbox enforcement is now an injectable seam (agent-runtime has zero workspace-package dependencies)
123
232
 
124
233
  `@mono-agent/agent-runtime` does not depend on `@mono-agent/runtime-adapter`. Sandbox
125
234
  enforcement (command sandboxing, network-policy checks, and monotonic policy
@@ -147,7 +256,7 @@ mono-agent hosts — no action needed if you build your runtime through
147
256
  `@mono-agent/runtime-adapter`, also pass a `sandbox` implementation, or drop
148
257
  the policy.
149
258
 
150
- ## 8. Typed run options replace the `settings` bag (`toolLimits` / `compaction` / `prompts`)
259
+ ### 8. Typed run options replace the `settings` bag (`toolLimits` / `compaction` / `prompts`)
151
260
 
152
261
  The flat `options.settings` bag is **deprecated** as the way to configure
153
262
  tool-output clamps and context compaction. The supported replacements are typed,
@@ -177,7 +286,7 @@ mapper's fallback window.
177
286
  **Action:** migrate `settings` → `toolLimits` / `compaction`; until then the shim
178
287
  keeps working with one deprecation warning per run.
179
288
 
180
- ## 9. New per-run overrides: `sandbox`, `sandboxPolicy`, `prompts`
289
+ ### 9. New per-run overrides: `sandbox`, `sandboxPolicy`, `prompts`
181
290
 
182
291
  Beyond `toolLimits` / `compaction`, `RuntimeRunOptions` gained:
183
292
 
@@ -193,7 +302,7 @@ Beyond `toolLimits` / `compaction`, `RuntimeRunOptions` gained:
193
302
  (byte-identical default). These are also accepted on `AgentRuntimeHostOptions`
194
303
  as the host-level default.
195
304
 
196
- ## 10. Pi 0.80 auth: `Models` credential store (`resolvePiApiKey` semantics preserved)
305
+ ### 10. Pi 0.80 auth: `Models` credential store (`resolvePiApiKey` semantics preserved)
197
306
 
198
307
  Pi 0.80 removed the harness `getApiKeyAndHeaders` hook; request auth now resolves
199
308
  through a `Models` collection's `CredentialStore`. The bridge's **per-run
@@ -208,7 +317,7 @@ now `0.80.6`** (the initial Pi 0.80 migration landed at `0.80.5`, from
208
317
  `^0.79.1`). Compaction is driven natively (section 3). The `0.80.6` refresh also
209
318
  preserves model-native `max` reasoning and Pi's request-wide pricing tiers.
210
319
 
211
- ## 11. Exports map: wildcards removed (explicit deep-path map)
320
+ ### 11. Exports map: wildcards removed (explicit deep-path map)
212
321
 
213
322
  The package's `./ai/*` and `./agent/*` **wildcard exports were replaced by an
214
323
  explicit `exports` map**: 3 barrels (`.`, `./ai`, `./agent`) plus the generated
@@ -257,64 +366,51 @@ a compatibility subpath.
257
366
 
258
367
  ## Version
259
368
 
260
- This guide describes the published `0.13.x` package contract. Keep
369
+ This guide describes the published `0.15.x` package contract. Keep
261
370
  `@mono-agent/agent-runtime`, `@mono-agent/runtime-adapter`, and other
262
371
  `@mono-agent/*` packages on the same lockstep version when upgrading. The paired
263
372
  runtime adapter no longer exposes `piReasoningSummary` in its run-options type.
264
373
 
265
374
  ---
266
375
 
267
- ## Appendix — Porting this kernel to a new scope/host (worklab port-readiness)
268
-
269
- This kernel is designed to be vendored into a differently-scoped host (the
270
- concrete target is **worklab**, `@worklab-ai/agent-runtime`, GPL-3.0-only, npm
271
- workspaces, pure-JS no-build, consuming this package's raw `src/`). The port
272
- itself is a follow-up; this is the executable checklist, with the port-readiness
273
- dry-run results recorded inline (verified against the worklab tree read-only).
274
-
275
- Run these before/at the port:
276
-
277
- 1. **Scope rename `@mono-agent/` `@worklab-ai/`.** Touches `package.json`
278
- (`name` + the package-name prefix inside each `exports` key's consumer
279
- specifier) only the kernel's own source uses **relative** imports, so no
280
- source import references the scope. *(Verified: zero `@mono-agent/*` specifiers
281
- in `src/`.)*
282
- 2. **Dependencies.** Post-decoupling the kernel has **zero workspace-package
283
- deps**; only the third-party pins need aligning: `@earendil-works/pi-ai` +
284
- `@earendil-works/pi-agent-core` (`0.80.6`), `@modelcontextprotocol/sdk`,
285
- `@opencode-ai/sdk`, `@anthropic-ai/claude-agent-sdk`, `zod`.
286
- 3. **Pi bump `^0.74.0` `0.80.6` in lockstep.** worklab tests that use old pi
287
- APIs are rewritten at the port. Do not restore the old `pi-sdk.js` deep
288
- import; use `generatePiNativeResponse` from `@mono-agent/agent-runtime/ai`.
289
- 4. **Sandbox.** worklab passes **no** `sandbox` implementation → `passthroughSandbox`,
290
- and **never sets `sandboxPolicy`** *(verified: zero `sandboxPolicy` /
291
- `sandbox:` in worklab `src/`)*, so with no policy every tool runs unsandboxed
292
- exactly as today — behavior is byte-identical. (If worklab later adds a policy,
293
- it must also inject a `RuntimeSandbox` impl section 7's fail-closed rule.)
294
- 5. **License / packaging.** GPL-3.0-only stays; `files` includes `types/`
295
- (additive worklab consumes raw `src/`, `.d.ts` generation is optional).
296
- 6. **Deep imports resolve.** `node scripts/verify-deep-imports.mjs` (default +
297
- types conditions) is green. Every worklab **non-test** deep import resolves in
298
- the explicit exports map *(verified no gap)*, and the Worklab-test provider
299
- bridge imports for `claude-sdk.js`, `claude-cli.js`, and `codex-app.js` are
300
- supported as exported subpaths. The only worklab deep import NOT in the map is
301
- the removed **test-only** `pi-sdk.js`; those tests are rewritten at the port
302
- (step 3), so no export entry is added for it.
303
- 7. **Contract supersets.** `HOST_KEYS` worklab's host bag *(verified:
304
- worklab passes `resolveCustomPricing`, `onCompactionRecorded`, `persistArtifact`,
305
- `resolvePiApiKey`, `observers` all covered)*; the deep-import
306
- `configureToolRuntime` accepts worklab's keys *(verified: `workspace`,
307
- `repoRoot`, `runId`, `toolArtifactDir`, `ripgrepPath`, `qaOutputDir` ⊂
308
- `TOOL_CONTEXT_KEYS`)*; and every `RuntimeResult` field worklab's
309
- `worker/agent-turn.js` reads exists on the result *(verified: `cancelled`,
310
- `providerSessionId`, `error`, `failureKind`, `errorDetails`, `diagnostics`,
311
- `runtimeWarnings`, plus `text`/`usage`/`model`/`effort`/`numTurns`/
312
- `structuredResult`/`capabilitiesUsed`/`durationMs`/`failoverHistory`;
313
- `observerSnapshot` is worklab-side, folded from its own metrics observer)*.
314
- 8. **`options.settings` day one.** Works via the deprecated shim (section 8) with
315
- one `deprecated_settings_option` warning per run; worklab later maps
316
- `settings` → the typed policy objects in its `core/ai.js`.
317
- 9. **Test layout + no-build consumption.** `src/__tests__` + vitest already match;
318
- the package is fully consumable from raw `src/` with **no build**
319
- *(verified: a smoke import of `createRuntime` / `createRouterRuntime` from
320
- `src/index.js` constructs a runtime with no model call)*.
376
+ ## Appendix — Worklab shared-kernel adoption
377
+
378
+ Worklab should consume the published `@mono-agent/agent-runtime` package rather
379
+ than vendor or rename its source. The products remain separate, but provider
380
+ execution has one owner. Apply this downstream checklist when removing
381
+ Worklab's runtime fork:
382
+
383
+ 1. **Install the lockstep runtime package.** Keep the `@mono-agent/*` packages a
384
+ Worklab release uses on the same published version. Preserve the shared
385
+ kernel's `GPL-3.0-only` distribution boundary.
386
+ 2. **Remove direct provider ownership.** Delete Worklab production imports from
387
+ `@earendil-works/pi-ai`, its separate Pi version constraint, and local copies
388
+ of provider bridge code. Move tests off Pi's faux-provider helpers too; until
389
+ that is complete, isolate the fixture or pin its development-only Pi
390
+ dependency to exact `0.80.6` rather than a floating range. Do not restore the
391
+ removed `pi-sdk.js` subpath.
392
+ 3. **Use the public Pi surfaces.** Run models through
393
+ `generatePiNativeResponse` or the runtime registry. Use
394
+ `listPiBuiltinModels`, `getPiBuiltinModel`,
395
+ `reasoningLevelsForPiModel`, `resolvePiOAuthApiKey`, and `loginPiOAuth` for
396
+ catalog and OAuth integration. Those façades keep Pi mutable state and the
397
+ exact `0.80.6` compatibility pin inside the runtime. OAuth login adapters
398
+ must supply `onAuth`, `onDeviceCode`, `onPrompt`, and `onSelect`; the façade
399
+ rejects an incomplete callback contract before starting provider login.
400
+ 4. **Inject Claude tests.** Replace package-level mocks of
401
+ `@anthropic-ai/claude-agent-sdk` with
402
+ `RuntimeRunOptions.claudeAgentQuery`. Production calls omit the seam. Expect
403
+ the runtime installation to retain Pi's Anthropic SDK `0.91.1` beside the
404
+ newer Anthropic SDK required by Claude; do not force-deduplicate them.
405
+ 5. **Preserve the sandbox boundary.** A direct runtime consumer that supplies
406
+ `sandboxPolicy` must also inject a `RuntimeSandbox`; otherwise the runtime
407
+ intentionally fails closed. With neither a policy nor an implementation,
408
+ passthrough behavior remains unchanged.
409
+ 6. **Use supported contracts.** Keep host callbacks within
410
+ `AgentRuntimeHostOptions`, tool state within the exported tool-runtime
411
+ context, and reads within `RuntimeResult`. Replace deprecated
412
+ `options.settings` with typed `toolLimits` and `compaction` objects.
413
+ 7. **Verify the installed package.** Run Worklab's provider and worker tests
414
+ against the packed or published package, assert that no production import
415
+ resolves Pi directly, and prove the injected Claude query performs no
416
+ network call.
package/README.md CHANGED
@@ -93,6 +93,8 @@ the [architecture guide](https://github.com/robertsreberski/mono-agent/blob/main
93
93
  | `parseRuntimeModelReference()` | Convert a canonical `claude:`, `codex:`, `opencode:`, or `pi:` string into the object required by `run()` |
94
94
  | `listRuntimeBridges()` / `runtimeCapabilities()` | Inspect the five built-in bridge descriptors without loading provider implementations |
95
95
  | `createPiOAuthApiKeyResolver()` | Bind a host-owned Pi auth file with refresh-safe writes |
96
+ | `listPiBuiltinModels()` / `getPiBuiltinModel()` | Read cloned snapshots from the runtime-owned, exact-pinned Pi model catalog without importing Pi directly |
97
+ | `resolvePiOAuthApiKey()` / `loginPiOAuth()` | Use the runtime-owned Pi OAuth implementation without importing Pi's mutable provider registry |
96
98
  | `createMetricsObserver()` | Aggregate normalized event, token, cache, cost, tool, error, turn, and approval metrics |
97
99
 
98
100
  Most hosts should use `@mono-agent/runtime-adapter` instead of importing deep
@@ -143,11 +145,14 @@ disposeAllProviderSessions
143
145
  disposeProviderSession
144
146
  executionModeIncompatibilityReason
145
147
  generatePiNativeResponse
148
+ getPiBuiltinModel
146
149
  inferAllowlistMode
147
150
  invalidateProviderSession
148
151
  isLikelyContextTermination
149
152
  isModelCompatibleWithExecutionMode
153
+ listPiBuiltinModels
150
154
  listRuntimeBridges
155
+ loginPiOAuth
151
156
  normalizeAllowlistMode
152
157
  normalizeClaudeSdkCatalog
153
158
  normalizeClaudeSdkModelId
@@ -158,12 +163,14 @@ parseStoredAllowlist
158
163
  piNativeRuntimeBridge
159
164
  readRuntimeBrand
160
165
  readToolRuntime
166
+ reasoningLevelsForPiModel
161
167
  refreshProviderSession
162
168
  renderResumeSnapshot
163
169
  resetToolRuntime
164
170
  resolveAgentCompactionPolicy
165
171
  resolveAllowlist
166
172
  resolveAllowlistMap
173
+ resolvePiOAuthApiKey
167
174
  resolveRuntimeBrand
168
175
  resolveRuntimeBridge
169
176
  runtimeCapabilities
@@ -310,15 +317,20 @@ disposeAllProviderSessions
310
317
  disposeProviderSession
311
318
  executionModeIncompatibilityReason
312
319
  generatePiNativeResponse
320
+ getPiBuiltinModel
313
321
  invalidateProviderSession
314
322
  isModelCompatibleWithExecutionMode
323
+ listPiBuiltinModels
315
324
  listRuntimeBridges
325
+ loginPiOAuth
316
326
  normalizeClaudeSdkCatalog
317
327
  normalizeClaudeSdkModelId
318
328
  normalizeRuntimeModelReference
319
329
  parseRuntimeModelReference
320
330
  piNativeRuntimeBridge
331
+ reasoningLevelsForPiModel
321
332
  refreshProviderSession
333
+ resolvePiOAuthApiKey
322
334
  resolveRuntimeBridge
323
335
  runtimeCapabilities
324
336
  sdkFromModelReference
@@ -602,6 +614,21 @@ The resolver reads provider credentials from the configured file, delegates toke
602
614
  refresh to `@earendil-works/pi-ai/oauth`, and writes refreshed credentials back
603
615
  with `0600` permissions.
604
616
 
617
+ Consumers that need lower-level Pi interoperability should still import only
618
+ `@mono-agent/agent-runtime/ai`. `listPiBuiltinModels(providerId)` returns fresh,
619
+ defensively cloned model snapshots; `getPiBuiltinModel(providerId, modelId)`
620
+ returns one cloned snapshot or `undefined`; and
621
+ `reasoningLevelsForPiModel(model)` translates a Pi model into mono-agent's
622
+ reasoning vocabulary, including `none` rather than Pi's `off`.
623
+ `resolvePiOAuthApiKey(providerId, credentials)` refreshes a caller-owned
624
+ credential snapshot and returns `{ apiKey, newCredentials }` or `null`, while
625
+ `loginPiOAuth(providerId, callbacks)` runs the selected supported login flow.
626
+ Login callers must implement Pi's four required interaction callbacks:
627
+ `onAuth`, `onDeviceCode`, `onPrompt`, and `onSelect`; optional progress,
628
+ manual-code, and abort callbacks pass through unchanged.
629
+ These functions deliberately do not expose Pi's mutable model collections or
630
+ OAuth-provider registry.
631
+
605
632
  Returns:
606
633
 
607
634
  - `run(systemPrompt, options)` — async, runs one agent turn against the chosen backend.
@@ -628,17 +655,35 @@ Per-call options (a non-exhaustive selection):
628
655
  | `maxTurns` | `number` | Hard cap on agent turns. |
629
656
  | `outputSchema` | `JSONSchema` | Requests structured JSON on capable bridges; see “Structured output” below for bridge-specific return behavior. |
630
657
  | `abortSignal` | `AbortSignal` | Cancel the run. |
631
- | `liveInput` | `AsyncIterable<{ body: string; id?: string; receivedAt?: string; acknowledge?: () => void; reject?: (error?: unknown) => void }>` | Stream of in-flight user messages for steering on capable bridges. A bridge acknowledges only after its native steering boundary accepts the message; per-attempt rejection permits router replay. |
632
- | `onEvent` | `(event) => void` | Fired for every event the provider emits (assistant text, tool calls/results, runtime warnings, structured output). |
658
+ | `liveInput` | `AsyncIterable<{ body: string; id?: string; receivedAt?: string; acknowledge?: () => void; reject?: (error?: unknown) => void }>` | Stream of in-flight user messages for steering on capable bridges. A 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. |
659
+ | `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. |
660
+ | `onEvent` | `(event) => void` | Fired for every runtime event (assistant text, tool calls/results, applied live input, runtime warnings, structured output). |
633
661
  | `runId` | `string` | Tag this run for downstream callbacks (e.g. `onCompactionRecorded`). |
634
662
  | `providerSessionId` | `string` | Resume a prior provider session. |
635
663
  | `runArtifactDir` | `string` | Used by some providers as the Playwright MCP filename target. |
636
664
  | `codexAppServerCommand` | `string` | Override the Codex CLI binary. |
637
665
  | `codexAppServerArgs` | `string[]` | Override the Codex CLI arguments. |
638
666
 
667
+ `runtimeCapabilities()` and each descriptor returned by
668
+ `listRuntimeBridges()` expose `tool_policy`. `"projected"` means the bridge can
669
+ project restrictive `allowedTools` / `disallowedTools`; `"allow_all_only"`
670
+ means it accepts only an effective unrestricted policy—`allowedTools` omitted
671
+ or containing `"*"`, with no denied tools. A wildcard dominates named entries,
672
+ so `["*", "Read"]` is allow-all. Named-only lists, `[]`, and any denylist remain
673
+ unsupported on the direct Codex and direct OpenCode bridges and fail before
674
+ provider startup. Built-in bridges always report this field; omission by a
675
+ custom structural bridge means the capability is unknown.
676
+
639
677
  Live input is native on the Claude SDK, Codex app-server, and Pi bridges. The
640
678
  one-shot Claude CLI and direct OpenCode bridges advertise it as unsupported so
641
679
  routers skip them when a direct runtime call requires steering.
680
+ After a native bridge invokes `acknowledge()`, the runtime emits exactly one
681
+ `{ type: "live_input_applied", inputId, receivedAt? }` event for that logical
682
+ run. It deliberately omits the guidance body. A fallback router reuses the same
683
+ instrumented input stream, so replay or duplicate acknowledgement cannot emit a
684
+ second applied event. A throwing host `acknowledge` or `reject` callback cannot
685
+ change the native steering outcome; the Codex bridge reports it as a bounded
686
+ `live_input_callback_failed` runtime warning.
642
687
 
643
688
  Returns:
644
689
 
@@ -707,6 +752,13 @@ The agent kernel's managed tools are `Read`, `Write`, `Edit`, `Glob`, `Grep`, `B
707
752
 
708
753
  `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 `Bash`; 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.
709
754
 
755
+ Pi runs with selected skills also expose `ReadSkill`. It returns the complete
756
+ skill instructions by default, including content beyond the former
757
+ 12,000-character boundary. Programmatic callers of
758
+ `formatSkillBodyWithPathNote()` may pass a positive `maxChars` only when
759
+ truncation is explicitly desired; omitting it is not a separate hidden limit.
760
+ The standard 256 KiB tool-payload guard still applies to oversized tool results.
761
+
710
762
  Override or extend the tool surface by passing `mcpServers` for MCP-backed tools.
711
763
 
712
764
  ### Structured output
@@ -917,6 +969,19 @@ dependencies are `@anthropic-ai/claude-agent-sdk`, `@anthropic-ai/sdk`,
917
969
  `@modelcontextprotocol/sdk`, `@opencode-ai/sdk`, `@vscode/ripgrep`,
918
970
  `cross-spawn`, and `zod`.
919
971
 
972
+ The runtime owns and exact-pins the compatible Pi pair at `0.80.6`; consumers
973
+ use the runtime's Pi façade rather than coordinating a second direct
974
+ `@earendil-works/pi-ai` dependency. Do not attempt to flatten the resulting
975
+ Anthropic dependency tree: Pi AI pins `@anthropic-ai/sdk@0.91.1`, while the
976
+ Claude Agent SDK requires `@anthropic-ai/sdk>=0.93.0` and the runtime supplies
977
+ its compatible newer SDK. Two isolated Anthropic SDK versions are therefore
978
+ expected. `RuntimeRunOptions.claudeAgentQuery` provides deterministic Claude
979
+ tests without mocking package resolution or sending real SDK traffic.
980
+ If a downstream test suite still needs Pi's faux-provider helpers, isolate that
981
+ fixture or keep its development-only Pi dependency on the runtime's exact
982
+ `0.80.6` version until the fixture is removed; a broad host range can otherwise
983
+ float Pi Agent Core's own upstream dependency independently of this façade.
984
+
920
985
  Sandbox enforcement is an injectable `RuntimeSandbox` seam.
921
986
  `@mono-agent/runtime-adapter` supplies the mono-agent implementation; a direct
922
987
  consumer that configures a sandbox policy must inject an implementation or the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mono-agent/agent-runtime",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
4
4
  "description": "Agent runtime supporting Claude SDK/CLI, Codex, OpenCode, and Pi SDK bridges out of the box",
5
5
  "type": "module",
6
6
  "license": "GPL-3.0-only",
@@ -22,8 +22,6 @@
22
22
  * @property {number} summaryMaxTokens
23
23
  * @property {boolean} fixedOverheadEnabled
24
24
  * @property {number} compactionMinSavingsTokens
25
- * @property {number} toolPayloadCompactionTriggerChars
26
- * @property {number} toolPruneTriggerTokens
27
25
  * @property {number} toolTextLimitChars
28
26
  * @property {number} bashOutputLimitChars
29
27
  * @property {number} mcpTextLimitChars
@@ -36,8 +34,6 @@
36
34
 
37
35
  const DEFAULT_CONTEXT_WINDOW = 128000;
38
36
  const DEFAULT_TRIGGER_RATIO = 0.70;
39
- const DEFAULT_TOOL_PAYLOAD_COMPACTION_TRIGGER_CHARS = 0;
40
- const DEFAULT_TOOL_PRUNE_TRIGGER_TOKENS = 40000;
41
37
  // intelligence-ramp Phase 3: lifted from 16K/20K/12K. Mid-task tool reads
42
38
  // (large file edits, long bash output, deep MCP results) were being silently
43
39
  // clipped before the agent could reason about them. The 256KB hard ceiling
@@ -134,13 +130,6 @@ export function resolveAgentCompactionPolicy(settings = {}, model = {}) {
134
130
  0,
135
131
  500000,
136
132
  ),
137
- toolPayloadCompactionTriggerChars: clampInteger(
138
- settings.agent_tool_payload_compaction_trigger_chars,
139
- DEFAULT_TOOL_PAYLOAD_COMPACTION_TRIGGER_CHARS,
140
- 0,
141
- 10 * 1024 * 1024,
142
- ),
143
- toolPruneTriggerTokens: clampInteger(settings.agent_tool_prune_trigger_tokens, DEFAULT_TOOL_PRUNE_TRIGGER_TOKENS, 0, 500000),
144
133
  toolTextLimitChars: clampInteger(settings.agent_tool_text_limit_chars, DEFAULT_TOOL_TEXT_LIMIT_CHARS, 1000, 200000),
145
134
  bashOutputLimitChars: clampInteger(settings.agent_bash_output_limit_chars, DEFAULT_BASH_OUTPUT_LIMIT_CHARS, 1000, 200000),
146
135
  mcpTextLimitChars: clampInteger(settings.agent_mcp_text_limit_chars, DEFAULT_MCP_TEXT_LIMIT_CHARS, 1000, 200000),
@@ -35,6 +35,9 @@ export function buildSkillPathNote({ assetsPath, skillsRoot } = {}) {
35
35
  }
36
36
 
37
37
  /**
38
+ * Render a complete skill body plus its path note. Omitting `maxChars` returns
39
+ * the full text; pass a positive `maxChars` only when explicit truncation is
40
+ * required by the caller.
38
41
  * @param {{body?: string, assetsPath?: string, skillsRoot?: any, maxChars?: number}} [options]
39
42
  */
40
43
  export function formatSkillBodyWithPathNote({ body, assetsPath, skillsRoot, maxChars } = {}) {
@@ -42,7 +45,8 @@ export function formatSkillBodyWithPathNote({ body, assetsPath, skillsRoot, maxC
42
45
  buildSkillPathNote({ assetsPath, skillsRoot }),
43
46
  String(body || "").trim(),
44
47
  ].filter(Boolean).join("\n\n");
45
- return maxChars ? text.slice(0, maxChars) : text;
48
+ const limit = Number(maxChars);
49
+ return Number.isFinite(limit) && limit > 0 ? text.slice(0, Math.floor(limit)) : text;
46
50
  }
47
51
 
48
52
  export function buildSkillIndex(skills) {
package/src/ai/index.js CHANGED
@@ -12,6 +12,13 @@ export {
12
12
  } from "./runtime/sessions.js";
13
13
  export { createMetricsObserver, createObserverHub } from "./observer.js";
14
14
  export { generatePiNativeResponse, piNativeRuntimeBridge } from "./providers/pi-native.js";
15
+ export {
16
+ getPiBuiltinModel,
17
+ listPiBuiltinModels,
18
+ loginPiOAuth,
19
+ reasoningLevelsForPiModel,
20
+ resolvePiOAuthApiKey,
21
+ } from "./pi-interop.js";
15
22
  export {
16
23
  CLAUDE_SDK_CATALOG_VERSION,
17
24
  createClaudeSdkDiscoveryIsolation,