@mono-agent/agent-runtime 0.14.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/MIGRATION.md +147 -69
  2. package/README.md +83 -20
  3. package/package.json +3 -6
  4. package/src/agent/compaction.js +0 -11
  5. package/src/agent/prompt/skill-index.js +5 -1
  6. package/src/ai/index.js +7 -1
  7. package/src/ai/observer.js +48 -13
  8. package/src/ai/pi-interop.js +156 -0
  9. package/src/ai/providers/claude-cli.js +2 -13
  10. package/src/ai/providers/claude-sdk.js +14 -8
  11. package/src/ai/providers/codex-app.js +235 -56
  12. package/src/ai/providers/opencode-app.js +168 -3
  13. package/src/ai/providers/pi-messages.js +0 -8
  14. package/src/ai/providers/pi-native/compaction-driver.js +106 -10
  15. package/src/ai/providers/pi-native/result-builder.js +2 -14
  16. package/src/ai/providers/pi-native/stream-subscriber.js +20 -2
  17. package/src/ai/providers/pi-native/turn-runner.js +31 -8
  18. package/src/ai/providers/pi-native.js +2 -5
  19. package/src/ai/runtime/live-input-events.js +94 -0
  20. package/src/ai/runtime/registry.js +8 -1
  21. package/src/ai/runtime/router.js +21 -0
  22. package/src/ai/types.js +2 -1
  23. package/src/runtime.js +3 -0
  24. package/types/agent/compaction.d.ts +0 -2
  25. package/types/agent/prompt/skill-index.d.ts +3 -0
  26. package/types/ai/index.d.ts +1 -1
  27. package/types/ai/observer.d.ts +4 -2
  28. package/types/ai/pi-interop.d.ts +113 -0
  29. package/types/ai/providers/claude-cli.d.ts +6 -30
  30. package/types/ai/providers/claude-sdk.d.ts +2 -9
  31. package/types/ai/providers/codex-app.d.ts +4 -10
  32. package/types/ai/providers/pi-messages.d.ts +0 -1
  33. package/types/ai/providers/pi-native/result-builder.d.ts +3 -11
  34. package/types/ai/providers/pi-native/stream-subscriber.d.ts +4 -2
  35. package/types/ai/providers/pi-native/turn-runner.d.ts +1 -1
  36. package/types/ai/runtime/live-input-events.d.ts +22 -0
  37. package/types/ai/types.d.ts +10 -2
  38. package/src/ai/backend.js +0 -17
  39. package/src/ai/registry.js +0 -5
  40. package/types/ai/backend.d.ts +0 -57
  41. package/types/ai/registry.d.ts +0 -1
package/MIGRATION.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # `@mono-agent/agent-runtime` — Migration Guide
2
2
 
3
3
  Breaking and behavioral changes for consumers upgrading from `0.3.x` to the
4
- current `0.13.x` contract. `createRuntime()` remains the package entry point;
4
+ current pre-1.0 contract. `createRuntime()` remains the package entry point;
5
5
  `createMonoRuntime()` remains the typed facade in
6
6
  `@mono-agent/runtime-adapter`. Provider-session input/output uses
7
7
  `providerSessionId`, with `disposeSession()` and `disposeAllSessions()` retained.
@@ -13,7 +13,99 @@ primary route.
13
13
 
14
14
  ---
15
15
 
16
- ## 1. Pi is now native-only (`pi-sdk.js` → `pi-native.js`)
16
+ ## 0.15.1
17
+
18
+ - **Runtime-owned Pi interoperability:** consumers that directly import
19
+ `@earendil-works/pi-ai` only for catalog, reasoning, or OAuth behavior should
20
+ switch to `listPiBuiltinModels`, `getPiBuiltinModel`,
21
+ `reasoningLevelsForPiModel`, `resolvePiOAuthApiKey`, and `loginPiOAuth` from
22
+ `@mono-agent/agent-runtime/ai`. The runtime keeps Pi AI and Pi Agent Core
23
+ exact-pinned at `0.80.6`; the façade returns cloned model and credential
24
+ snapshots rather than exposing mutable upstream registries.
25
+ - **Claude test seam:** downstream tests should pass
26
+ `RuntimeRunOptions.claudeAgentQuery` instead of mocking
27
+ `@anthropic-ai/claude-agent-sdk` by package name. Normal runs omit this option
28
+ and use the runtime-owned SDK. Pi AI's `@anthropic-ai/sdk@0.91.1` pin and the
29
+ Claude Agent SDK's `@anthropic-ai/sdk>=0.93.0` requirement intentionally
30
+ remain as two isolated SDK versions.
31
+ - **Compaction policy cleanup:** the inert
32
+ `toolPayloadCompactionTriggerChars` and `toolPruneTriggerTokens` properties
33
+ were removed from `AgentCompactionPolicy`, policy resolution, defaults, and
34
+ declarations. They had no supported typed/config path and did not activate
35
+ runtime pruning, so no replacement is required.
36
+ - **Codex live-input teardown:** a Codex app-server transport death now also
37
+ terminates a pending live-input read. Runs settle with the existing
38
+ `provider_unavailable` / `codex_app_server_closed` classification instead of
39
+ waiting forever for the input iterator. If a host `acknowledge` or `reject`
40
+ callback throws, the already-decided native steering result remains
41
+ authoritative and the runtime emits a bounded
42
+ `live_input_callback_failed` warning.
43
+
44
+ ## 0.15.x baseline
45
+
46
+ This is the current published baseline for the detailed pre-1.0 reference
47
+ below. It includes the explicit exports map, the five-bridge lazy registry,
48
+ typed runtime policies, runtime-owned provider dependencies, and the
49
+ public-surface cleanup described in this guide.
50
+
51
+ ## 0.12.x
52
+
53
+ - Persistent provider context overflow is classified as `context_limit`, which
54
+ lets a fallback router try its next model without conflating context capacity
55
+ with quota, output, or max-turn `usage_limit` failures.
56
+ - Omitted Pi compaction values resolve from effective context window `W`:
57
+ trigger ratio `0.70`, retained context `10%`, summary output `4%`, and minimum
58
+ proactive savings `10%`, subject to the documented scalar clamps. Numeric
59
+ provider limits and generic overflow evidence may lower a learned
60
+ process-local ceiling; `contextWindowOverride` remains the persistent
61
+ correction.
62
+
63
+ ## 0.10.x
64
+
65
+ - `ReadSkill` returns complete skill instructions by default, including content
66
+ beyond the former 12,000-character boundary. Programmatic callers of
67
+ `formatSkillBodyWithPathNote()` opt into truncation by passing a positive
68
+ `maxChars`; omitting it means no helper-level cap. The standard 256 KiB
69
+ tool-payload guard remains in effect.
70
+
71
+ ## 0.7.x
72
+
73
+ - Omitting Claude SDK effort now preserves the provider default instead of
74
+ deriving a `thinking` option. Supported effort values are forwarded exactly;
75
+ explicit `none` is unsupported (`skipped_capability_mismatch` through the
76
+ bridge, while direct `claudeEffortOptions("none")` calls throw).
77
+ - Cancellation uses a private abort controller and closes the active Claude SDK
78
+ `Query` with `Query.close()`. Test doubles must honor both boundaries rather
79
+ than implementing only iterator `return()`.
80
+ - `Glob` and `Grep` prefer an explicit `ripgrepPath`, then the packaged
81
+ `@vscode/ripgrep` binary on supported platforms, and finally `PATH`.
82
+
83
+ ## 0.6.2
84
+
85
+ - Codex file edits use a flat top-level `file_change` event instead of synthetic
86
+ assistant/user `file_edit` tool-use/tool-result pairs.
87
+ - The synthetic `createClaudeFileEditHooks`,
88
+ `createFileEditToolUseEvent`, and `createFileEditToolResultEvent` exports were
89
+ removed. Consumers should observe normalized runtime events or use the
90
+ remaining file-change statistics helpers rather than recreating provider hook
91
+ behavior.
92
+
93
+ ---
94
+
95
+ ## Detailed pre-1.0 reference
96
+
97
+ ### Pre-1.0 public-surface cleanup
98
+
99
+ The compatibility entrypoints `./ai/backend.js` and `./ai/registry.js` were
100
+ removed after repository-wide reachability checks found no supported caller.
101
+ The old `findProviderForModel` / `listProviders` aliases and provider/backend
102
+ constant objects were removed at the same time. Import `resolveRuntimeBridge`
103
+ or `listRuntimeBridges` from `@mono-agent/agent-runtime` (or its `./ai` barrel)
104
+ instead. Runtime behavior and the canonical bridge descriptors are unchanged.
105
+
106
+ ---
107
+
108
+ ### 1. Pi is now native-only (`pi-sdk.js` → `pi-native.js`)
17
109
 
18
110
  The hand-rolled Pi bridge that drove the low-level `Agent` was replaced by a
19
111
  bridge built on `@earendil-works/pi-agent-core`'s high-level `AgentHarness`. The
@@ -32,7 +124,7 @@ registry resolves `pi` → the native bridge unconditionally; there is no
32
124
  `@mono-agent/agent-runtime/ai/failure.js`. The `pi*Backend` aliases are gone —
33
125
  all Pi routes through the native bridge.
34
126
 
35
- ## 2. Removed run options: `piReasoningSummary`, `piCodexTransport`
127
+ ### 2. Removed run options: `piReasoningSummary`, `piCodexTransport`
36
128
 
37
129
  These were Pi-bridge knobs the native path does not consume.
38
130
 
@@ -43,7 +135,7 @@ These were Pi-bridge knobs the native path does not consume.
43
135
  `runtime.reasoningSummary` config field has also been removed.
44
136
  - `piCodexTransport` was doc-only and is removed. No replacement is needed.
45
137
 
46
- ## 3. Pi context compaction: bridge-driven via AgentHarness.compact()
138
+ ### 3. Pi context compaction: bridge-driven via AgentHarness.compact()
47
139
 
48
140
  `AgentHarness` has no automatic compaction, so the pi bridge drives it directly
49
141
  (the legacy low-level `transformContext` / `afterToolCall` hooks and
@@ -65,7 +157,7 @@ These were Pi-bridge knobs the native path does not consume.
65
157
  correction. Deprecated programmatic `agent_compaction_*` settings and
66
158
  `resolveAgentCompactionPolicy` remain compatibility surfaces.
67
159
 
68
- ## 4. Durable Pi session resume: create-on-miss semantics
160
+ ### 4. Durable Pi session resume: create-on-miss semantics
69
161
 
70
162
  When a run supplies a `providerSessionId` (or the legacy `sessionId` alias) **and**
71
163
  durable storage is configured (`piSessionsRoot`), Pi-native now **creates the
@@ -80,7 +172,7 @@ passed an arbitrary `providerSessionId` to a durable run expecting a hard
80
172
  The in-memory (non-durable) resume path still fast-fails `session_not_found` on a
81
173
  miss.
82
174
 
83
- ## 5. Fallback router enforces requested native-subagent capability
175
+ ### 5. Fallback router enforces requested native-subagent capability
84
176
 
85
177
  Pi advertises `supports_native_subagents: false`. The fallback router now infers
86
178
  a `supports_native_subagents` requirement when a run passes
@@ -92,7 +184,7 @@ a `supports_native_subagents` requirement when a run passes
92
184
  native-subagent runs, ensure at least one entry supports native subagents, or the
93
185
  run reports exhausted instead of degrading silently.
94
186
 
95
- ## 6. Diagnostics & internal behavior changes (no API change)
187
+ ### 6. Diagnostics & internal behavior changes (no API change)
96
188
 
97
189
  - **Pi multimodal**: image inputs are delivered to the model as image content
98
190
  blocks (internal fix; affects behavior, not the call shape).
@@ -108,7 +200,7 @@ run reports exhausted instead of degrading silently.
108
200
  resumed sessions roll back to their pre-turn leaf on host-side (outer-catch)
109
201
  failures. These are correctness fixes with no API surface change.
110
202
 
111
- ## 7. Sandbox enforcement is now an injectable seam (agent-runtime has zero workspace-package dependencies)
203
+ ### 7. Sandbox enforcement is now an injectable seam (agent-runtime has zero workspace-package dependencies)
112
204
 
113
205
  `@mono-agent/agent-runtime` does not depend on `@mono-agent/runtime-adapter`. Sandbox
114
206
  enforcement (command sandboxing, network-policy checks, and monotonic policy
@@ -136,7 +228,7 @@ mono-agent hosts — no action needed if you build your runtime through
136
228
  `@mono-agent/runtime-adapter`, also pass a `sandbox` implementation, or drop
137
229
  the policy.
138
230
 
139
- ## 8. Typed run options replace the `settings` bag (`toolLimits` / `compaction` / `prompts`)
231
+ ### 8. Typed run options replace the `settings` bag (`toolLimits` / `compaction` / `prompts`)
140
232
 
141
233
  The flat `options.settings` bag is **deprecated** as the way to configure
142
234
  tool-output clamps and context compaction. The supported replacements are typed,
@@ -166,7 +258,7 @@ mapper's fallback window.
166
258
  **Action:** migrate `settings` → `toolLimits` / `compaction`; until then the shim
167
259
  keeps working with one deprecation warning per run.
168
260
 
169
- ## 9. New per-run overrides: `sandbox`, `sandboxPolicy`, `prompts`
261
+ ### 9. New per-run overrides: `sandbox`, `sandboxPolicy`, `prompts`
170
262
 
171
263
  Beyond `toolLimits` / `compaction`, `RuntimeRunOptions` gained:
172
264
 
@@ -182,7 +274,7 @@ Beyond `toolLimits` / `compaction`, `RuntimeRunOptions` gained:
182
274
  (byte-identical default). These are also accepted on `AgentRuntimeHostOptions`
183
275
  as the host-level default.
184
276
 
185
- ## 10. Pi 0.80 auth: `Models` credential store (`resolvePiApiKey` semantics preserved)
277
+ ### 10. Pi 0.80 auth: `Models` credential store (`resolvePiApiKey` semantics preserved)
186
278
 
187
279
  Pi 0.80 removed the harness `getApiKeyAndHeaders` hook; request auth now resolves
188
280
  through a `Models` collection's `CredentialStore`. The bridge's **per-run
@@ -197,7 +289,7 @@ now `0.80.6`** (the initial Pi 0.80 migration landed at `0.80.5`, from
197
289
  `^0.79.1`). Compaction is driven natively (section 3). The `0.80.6` refresh also
198
290
  preserves model-native `max` reasoning and Pi's request-wide pricing tiers.
199
291
 
200
- ## 11. Exports map: wildcards removed (explicit deep-path map)
292
+ ### 11. Exports map: wildcards removed (explicit deep-path map)
201
293
 
202
294
  The package's `./ai/*` and `./agent/*` **wildcard exports were replaced by an
203
295
  explicit `exports` map**: 3 barrels (`.`, `./ai`, `./agent`) plus the generated
@@ -209,7 +301,7 @@ now a loud failure (guarded by `scripts/verify-deep-imports.mjs`).
209
301
  <!-- public-api-js-subpaths:start -->
210
302
  <!-- Generated by scripts/generate-public-api-docs.mjs. Do not edit by hand. -->
211
303
 
212
- The package exposes **22 named deep `.js` subpaths**:
304
+ The package exposes **21 named deep `.js` subpaths**:
213
305
 
214
306
  ```text
215
307
  @mono-agent/agent-runtime/agent/allowlists.js
@@ -219,7 +311,6 @@ The package exposes **22 named deep `.js` subpaths**:
219
311
  @mono-agent/agent-runtime/agent/tools/shared/ripgrep.js
220
312
  @mono-agent/agent-runtime/agent/tools/shared/runtime-context.js
221
313
  @mono-agent/agent-runtime/agent/transcript.js
222
- @mono-agent/agent-runtime/ai/backend.js
223
314
  @mono-agent/agent-runtime/ai/cost.js
224
315
  @mono-agent/agent-runtime/ai/failure.js
225
316
  @mono-agent/agent-runtime/ai/file-change-stats.js
@@ -247,64 +338,51 @@ a compatibility subpath.
247
338
 
248
339
  ## Version
249
340
 
250
- This guide describes the published `0.13.x` package contract. Keep
341
+ This guide describes the published `0.15.x` package contract. Keep
251
342
  `@mono-agent/agent-runtime`, `@mono-agent/runtime-adapter`, and other
252
343
  `@mono-agent/*` packages on the same lockstep version when upgrading. The paired
253
344
  runtime adapter no longer exposes `piReasoningSummary` in its run-options type.
254
345
 
255
346
  ---
256
347
 
257
- ## Appendix — Porting this kernel to a new scope/host (worklab port-readiness)
258
-
259
- This kernel is designed to be vendored into a differently-scoped host (the
260
- concrete target is **worklab**, `@worklab-ai/agent-runtime`, GPL-3.0-only, npm
261
- workspaces, pure-JS no-build, consuming this package's raw `src/`). The port
262
- itself is a follow-up; this is the executable checklist, with the port-readiness
263
- dry-run results recorded inline (verified against the worklab tree read-only).
264
-
265
- Run these before/at the port:
266
-
267
- 1. **Scope rename `@mono-agent/` `@worklab-ai/`.** Touches `package.json`
268
- (`name` + the package-name prefix inside each `exports` key's consumer
269
- specifier) only the kernel's own source uses **relative** imports, so no
270
- source import references the scope. *(Verified: zero `@mono-agent/*` specifiers
271
- in `src/`.)*
272
- 2. **Dependencies.** Post-decoupling the kernel has **zero workspace-package
273
- deps**; only the third-party pins need aligning: `@earendil-works/pi-ai` +
274
- `@earendil-works/pi-agent-core` (`0.80.6`), `@modelcontextprotocol/sdk`,
275
- `@opencode-ai/sdk`, `@anthropic-ai/claude-agent-sdk`, `zod`.
276
- 3. **Pi bump `^0.74.0` `0.80.6` in lockstep.** worklab tests that use old pi
277
- APIs are rewritten at the port. Do not restore the old `pi-sdk.js` deep
278
- import; use `generatePiNativeResponse` from `@mono-agent/agent-runtime/ai`.
279
- 4. **Sandbox.** worklab passes **no** `sandbox` implementation → `passthroughSandbox`,
280
- and **never sets `sandboxPolicy`** *(verified: zero `sandboxPolicy` /
281
- `sandbox:` in worklab `src/`)*, so with no policy every tool runs unsandboxed
282
- exactly as today — behavior is byte-identical. (If worklab later adds a policy,
283
- it must also inject a `RuntimeSandbox` impl section 7's fail-closed rule.)
284
- 5. **License / packaging.** GPL-3.0-only stays; `files` includes `types/`
285
- (additive worklab consumes raw `src/`, `.d.ts` generation is optional).
286
- 6. **Deep imports resolve.** `node scripts/verify-deep-imports.mjs` (default +
287
- types conditions) is green. Every worklab **non-test** deep import resolves in
288
- the explicit exports map *(verified no gap)*, and the Worklab-test provider
289
- bridge imports for `claude-sdk.js`, `claude-cli.js`, and `codex-app.js` are
290
- supported as exported subpaths. The only worklab deep import NOT in the map is
291
- the removed **test-only** `pi-sdk.js`; those tests are rewritten at the port
292
- (step 3), so no export entry is added for it.
293
- 7. **Contract supersets.** `HOST_KEYS` worklab's host bag *(verified:
294
- worklab passes `resolveCustomPricing`, `onCompactionRecorded`, `persistArtifact`,
295
- `resolvePiApiKey`, `observers` all covered)*; the deep-import
296
- `configureToolRuntime` accepts worklab's keys *(verified: `workspace`,
297
- `repoRoot`, `runId`, `toolArtifactDir`, `ripgrepPath`, `qaOutputDir` ⊂
298
- `TOOL_CONTEXT_KEYS`)*; and every `RuntimeResult` field worklab's
299
- `worker/agent-turn.js` reads exists on the result *(verified: `cancelled`,
300
- `providerSessionId`, `error`, `failureKind`, `errorDetails`, `diagnostics`,
301
- `runtimeWarnings`, plus `text`/`usage`/`model`/`effort`/`numTurns`/
302
- `structuredResult`/`capabilitiesUsed`/`durationMs`/`failoverHistory`;
303
- `observerSnapshot` is worklab-side, folded from its own metrics observer)*.
304
- 8. **`options.settings` day one.** Works via the deprecated shim (section 8) with
305
- one `deprecated_settings_option` warning per run; worklab later maps
306
- `settings` → the typed policy objects in its `core/ai.js`.
307
- 9. **Test layout + no-build consumption.** `src/__tests__` + vitest already match;
308
- the package is fully consumable from raw `src/` with **no build**
309
- *(verified: a smoke import of `createRuntime` / `createRouterRuntime` from
310
- `src/index.js` constructs a runtime with no model call)*.
348
+ ## Appendix — Worklab shared-kernel adoption
349
+
350
+ Worklab should consume the published `@mono-agent/agent-runtime` package rather
351
+ than vendor or rename its source. The products remain separate, but provider
352
+ execution has one owner. Apply this downstream checklist when removing
353
+ Worklab's runtime fork:
354
+
355
+ 1. **Install the lockstep runtime package.** Keep the `@mono-agent/*` packages a
356
+ Worklab release uses on the same published version. Preserve the shared
357
+ kernel's `GPL-3.0-only` distribution boundary.
358
+ 2. **Remove direct provider ownership.** Delete Worklab production imports from
359
+ `@earendil-works/pi-ai`, its separate Pi version constraint, and local copies
360
+ of provider bridge code. Move tests off Pi's faux-provider helpers too; until
361
+ that is complete, isolate the fixture or pin its development-only Pi
362
+ dependency to exact `0.80.6` rather than a floating range. Do not restore the
363
+ removed `pi-sdk.js` subpath.
364
+ 3. **Use the public Pi surfaces.** Run models through
365
+ `generatePiNativeResponse` or the runtime registry. Use
366
+ `listPiBuiltinModels`, `getPiBuiltinModel`,
367
+ `reasoningLevelsForPiModel`, `resolvePiOAuthApiKey`, and `loginPiOAuth` for
368
+ catalog and OAuth integration. Those façades keep Pi mutable state and the
369
+ exact `0.80.6` compatibility pin inside the runtime. OAuth login adapters
370
+ must supply `onAuth`, `onDeviceCode`, `onPrompt`, and `onSelect`; the façade
371
+ rejects an incomplete callback contract before starting provider login.
372
+ 4. **Inject Claude tests.** Replace package-level mocks of
373
+ `@anthropic-ai/claude-agent-sdk` with
374
+ `RuntimeRunOptions.claudeAgentQuery`. Production calls omit the seam. Expect
375
+ the runtime installation to retain Pi's Anthropic SDK `0.91.1` beside the
376
+ newer Anthropic SDK required by Claude; do not force-deduplicate them.
377
+ 5. **Preserve the sandbox boundary.** A direct runtime consumer that supplies
378
+ `sandboxPolicy` must also inject a `RuntimeSandbox`; otherwise the runtime
379
+ intentionally fails closed. With neither a policy nor an implementation,
380
+ passthrough behavior remains unchanged.
381
+ 6. **Use supported contracts.** Keep host callbacks within
382
+ `AgentRuntimeHostOptions`, tool state within the exported tool-runtime
383
+ context, and reads within `RuntimeResult`. Replace deprecated
384
+ `options.settings` with typed `toolLimits` and `compaction` objects.
385
+ 7. **Verify the installed package.** Run Worklab's provider and worker tests
386
+ against the packed or published package, assert that no production import
387
+ resolves Pi directly, and prove the injected Claude query performs no
388
+ 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
@@ -142,14 +144,15 @@ discoverClaudeSdkModels
142
144
  disposeAllProviderSessions
143
145
  disposeProviderSession
144
146
  executionModeIncompatibilityReason
145
- findProviderForModel
146
147
  generatePiNativeResponse
148
+ getPiBuiltinModel
147
149
  inferAllowlistMode
148
150
  invalidateProviderSession
149
151
  isLikelyContextTermination
150
152
  isModelCompatibleWithExecutionMode
151
- listProviders
153
+ listPiBuiltinModels
152
154
  listRuntimeBridges
155
+ loginPiOAuth
153
156
  normalizeAllowlistMode
154
157
  normalizeClaudeSdkCatalog
155
158
  normalizeClaudeSdkModelId
@@ -160,12 +163,14 @@ parseStoredAllowlist
160
163
  piNativeRuntimeBridge
161
164
  readRuntimeBrand
162
165
  readToolRuntime
166
+ reasoningLevelsForPiModel
163
167
  refreshProviderSession
164
168
  renderResumeSnapshot
165
169
  resetToolRuntime
166
170
  resolveAgentCompactionPolicy
167
171
  resolveAllowlist
168
172
  resolveAllowlistMap
173
+ resolvePiOAuthApiKey
169
174
  resolveRuntimeBrand
170
175
  resolveRuntimeBridge
171
176
  runtimeCapabilities
@@ -311,18 +316,21 @@ discoverClaudeSdkModels
311
316
  disposeAllProviderSessions
312
317
  disposeProviderSession
313
318
  executionModeIncompatibilityReason
314
- findProviderForModel
315
319
  generatePiNativeResponse
320
+ getPiBuiltinModel
316
321
  invalidateProviderSession
317
322
  isModelCompatibleWithExecutionMode
318
- listProviders
323
+ listPiBuiltinModels
319
324
  listRuntimeBridges
325
+ loginPiOAuth
320
326
  normalizeClaudeSdkCatalog
321
327
  normalizeClaudeSdkModelId
322
328
  normalizeRuntimeModelReference
323
329
  parseRuntimeModelReference
324
330
  piNativeRuntimeBridge
331
+ reasoningLevelsForPiModel
325
332
  refreshProviderSession
333
+ resolvePiOAuthApiKey
326
334
  resolveRuntimeBridge
327
335
  runtimeCapabilities
328
336
  sdkFromModelReference
@@ -330,15 +338,6 @@ syncProviderSession
330
338
  toolCompactionAppliedFromWarnings
331
339
  ```
332
340
 
333
- **`@mono-agent/agent-runtime/ai/backend.js`**
334
-
335
- ```text
336
- BACKEND_CAPABILITIES
337
- backendCapabilities
338
- backendSupportsSessionResume
339
- backendUsesExecenvConfig
340
- ```
341
-
342
341
  **`@mono-agent/agent-runtime/ai/cost.js`**
343
342
 
344
343
  ```text
@@ -388,9 +387,7 @@ formatLiveInputGuidance
388
387
 
389
388
  ```text
390
389
  buildCliCommand
391
- claudeCodeBackend
392
390
  claudeCodeRuntimeBridge
393
- codexCliBackend
394
391
  createThinkingBuffer
395
392
  generateCliResponse
396
393
  normalizeCliEvent
@@ -414,7 +411,6 @@ normalizeClaudeSdkModelId
414
411
  ```text
415
412
  claudeEffortOptions
416
413
  claudeRuntimeBridge
417
- claudeSdkBackend
418
414
  claudeSdkModelForQuery
419
415
  generateClaudeResponse
420
416
  toolPayloadLimit
@@ -423,7 +419,6 @@ toolPayloadLimit
423
419
  **`@mono-agent/agent-runtime/ai/providers/codex-app.js`**
424
420
 
425
421
  ```text
426
- codexAppBackend
427
422
  codexAppRuntimeBridge
428
423
  createCodexAppServerClient
429
424
  generateCodexAppResponse
@@ -619,6 +614,21 @@ The resolver reads provider credentials from the configured file, delegates toke
619
614
  refresh to `@earendil-works/pi-ai/oauth`, and writes refreshed credentials back
620
615
  with `0600` permissions.
621
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
+
622
632
  Returns:
623
633
 
624
634
  - `run(systemPrompt, options)` — async, runs one agent turn against the chosen backend.
@@ -645,14 +655,26 @@ Per-call options (a non-exhaustive selection):
645
655
  | `maxTurns` | `number` | Hard cap on agent turns. |
646
656
  | `outputSchema` | `JSONSchema` | Requests structured JSON on capable bridges; see “Structured output” below for bridge-specific return behavior. |
647
657
  | `abortSignal` | `AbortSignal` | Cancel the run. |
648
- | `liveInput` | `AsyncIterable<{ body: string; id?: string }>` | Stream of in-flight user messages for steering on capable bridges. |
649
- | `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). |
650
661
  | `runId` | `string` | Tag this run for downstream callbacks (e.g. `onCompactionRecorded`). |
651
662
  | `providerSessionId` | `string` | Resume a prior provider session. |
652
663
  | `runArtifactDir` | `string` | Used by some providers as the Playwright MCP filename target. |
653
664
  | `codexAppServerCommand` | `string` | Override the Codex CLI binary. |
654
665
  | `codexAppServerArgs` | `string[]` | Override the Codex CLI arguments. |
655
666
 
667
+ Live input is native on the Claude SDK, Codex app-server, and Pi bridges. The
668
+ one-shot Claude CLI and direct OpenCode bridges advertise it as unsupported so
669
+ routers skip them when a direct runtime call requires steering.
670
+ After a native bridge invokes `acknowledge()`, the runtime emits exactly one
671
+ `{ type: "live_input_applied", inputId, receivedAt? }` event for that logical
672
+ run. It deliberately omits the guidance body. A fallback router reuses the same
673
+ instrumented input stream, so replay or duplicate acknowledgement cannot emit a
674
+ second applied event. A throwing host `acknowledge` or `reject` callback cannot
675
+ change the native steering outcome; the Codex bridge reports it as a bounded
676
+ `live_input_callback_failed` runtime warning.
677
+
656
678
  Returns:
657
679
 
658
680
  ```ts
@@ -693,6 +715,23 @@ Returns:
693
715
 
694
716
  `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.
695
717
 
718
+ Successful provider requests may also emit exact context telemetry through
719
+ `onEvent` and `result.events`:
720
+
721
+ - `context_usage` is one provider-counted request snapshot, never the run's
722
+ aggregate processed-token total. Pi emits it at each successful assistant
723
+ `message_end`; Codex uses `thread/tokenUsage/updated.tokenUsage.last`; direct
724
+ OpenCode requires a completed assistant message with native `tokens.total`.
725
+ Each event identifies the measured model and includes `contextWindow` only
726
+ when the provider's own model metadata supplied it. The Claude bridges do not
727
+ currently emit this event.
728
+ - `context_compaction` is a lifecycle event with a stable `operationId`,
729
+ `status` (`running`, `succeeded`, `skipped`, or `failed`), `sdk`, `trigger`,
730
+ `timestamp`, and optional safe reason/model/count fields. Pi drives and emits
731
+ its own lifecycle; Codex and OpenCode normalize their native notifications and
732
+ suppress deprecated duplicate notifications. Pi's before/after counts are
733
+ estimates and explicitly set `tokenCountsExact: false`.
734
+
696
735
  ### Built-in tools
697
736
 
698
737
  The agent kernel's managed tools are `Read`, `Write`, `Edit`, `Glob`, `Grep`, `Bash`, `NodeRepl`, `WebFetch`, and `WebSearch`. `NodeRepl({ code })` is backed by one lazily started Node.js REPL child per run. You select them via `allowedTools`. Tool implementations honor:
@@ -703,6 +742,13 @@ The agent kernel's managed tools are `Read`, `Write`, `Edit`, `Glob`, `Grep`, `B
703
742
 
704
743
  `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.
705
744
 
745
+ Pi runs with selected skills also expose `ReadSkill`. It returns the complete
746
+ skill instructions by default, including content beyond the former
747
+ 12,000-character boundary. Programmatic callers of
748
+ `formatSkillBodyWithPathNote()` may pass a positive `maxChars` only when
749
+ truncation is explicitly desired; omitting it is not a separate hidden limit.
750
+ The standard 256 KiB tool-payload guard still applies to oversized tool results.
751
+
706
752
  Override or extend the tool surface by passing `mcpServers` for MCP-backed tools.
707
753
 
708
754
  ### Structured output
@@ -784,7 +830,7 @@ console.log(metrics.snapshot());
784
830
  // cache: { hits, misses, hitRatio, readTokensFromEvents },
785
831
  // tools: { callsByName: { Bash: 3, Read: 2 }, errorsByName: { ... } },
786
832
  // errors: { total, byKind: { provider_unavailable: 1 } },
787
- // turns: { count, latencyMsP50, latencyMsP95 },
833
+ // turns: { count, sampleCount, latencyMsP50, latencyMsP95 },
788
834
  // approvals: { pending, granted, denied },
789
835
  // }
790
836
  ```
@@ -868,6 +914,10 @@ correction, while learned evidence may still lower it.
868
914
  Runs report `context_compaction_applied: true` (fired), `false` (enabled but not needed),
869
915
  or `null` (disabled), plus request-estimate, fixed-overhead, reactive-attempted,
870
916
  tokens-after, and reduced diagnostics.
917
+ Every attempt also emits one `context_compaction` start and exactly one terminal
918
+ lifecycle event. A successful retry then emits a new exact `context_usage`
919
+ snapshot, allowing consumers to discard the pre-compaction value rather than
920
+ guessing the resulting occupancy from the compaction estimate.
871
921
  Persistent overflow is classified as `context_limit`, allowing the fallback router to
872
922
  try the next configured model. The other backends manage their windows per their own behavior.
873
923
  (`docs/reference/feature-registry.md` is the source of truth for this row.)
@@ -909,6 +959,19 @@ dependencies are `@anthropic-ai/claude-agent-sdk`, `@anthropic-ai/sdk`,
909
959
  `@modelcontextprotocol/sdk`, `@opencode-ai/sdk`, `@vscode/ripgrep`,
910
960
  `cross-spawn`, and `zod`.
911
961
 
962
+ The runtime owns and exact-pins the compatible Pi pair at `0.80.6`; consumers
963
+ use the runtime's Pi façade rather than coordinating a second direct
964
+ `@earendil-works/pi-ai` dependency. Do not attempt to flatten the resulting
965
+ Anthropic dependency tree: Pi AI pins `@anthropic-ai/sdk@0.91.1`, while the
966
+ Claude Agent SDK requires `@anthropic-ai/sdk>=0.93.0` and the runtime supplies
967
+ its compatible newer SDK. Two isolated Anthropic SDK versions are therefore
968
+ expected. `RuntimeRunOptions.claudeAgentQuery` provides deterministic Claude
969
+ tests without mocking package resolution or sending real SDK traffic.
970
+ If a downstream test suite still needs Pi's faux-provider helpers, isolate that
971
+ fixture or keep its development-only Pi dependency on the runtime's exact
972
+ `0.80.6` version until the fixture is removed; a broad host range can otherwise
973
+ float Pi Agent Core's own upstream dependency independently of this façade.
974
+
912
975
  Sandbox enforcement is an injectable `RuntimeSandbox` seam.
913
976
  `@mono-agent/runtime-adapter` supplies the mono-agent implementation; a direct
914
977
  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.14.0",
3
+ "version": "0.15.1",
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",
@@ -39,10 +39,6 @@
39
39
  "types": "./types/ai/cost.d.ts",
40
40
  "default": "./src/ai/cost.js"
41
41
  },
42
- "./ai/backend.js": {
43
- "types": "./types/ai/backend.d.ts",
44
- "default": "./src/ai/backend.js"
45
- },
46
42
  "./ai/runtime/model-refs.js": {
47
43
  "types": "./types/ai/runtime/model-refs.d.ts",
48
44
  "default": "./src/ai/runtime/model-refs.js"
@@ -147,6 +143,7 @@
147
143
  },
148
144
  "scripts": {
149
145
  "build": "tsc -p tsconfig.types.json",
150
- "test": "vitest run --passWithNoTests"
146
+ "typecheck": "tsc -p tsconfig.types.json --noEmit",
147
+ "test": "vitest run"
151
148
  }
152
149
  }
@@ -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) {