@mono-agent/agent-runtime 0.11.3 → 0.11.5

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
@@ -190,35 +190,49 @@ falls back to its own env vars, exactly as returning `undefined` from the old ho
190
190
  did). **No host action needed** — `resolvePiApiKey` behaves as before.
191
191
 
192
192
  Dependency bump: **`@earendil-works/pi-ai` and `@earendil-works/pi-agent-core` are
193
- now `^0.80.x`** (were `^0.79.1`). Compaction is driven natively (section 3).
193
+ now `0.80.6`** (the initial Pi 0.80 migration landed at `0.80.5`, from
194
+ `^0.79.1`). Compaction is driven natively (section 3). The `0.80.6` refresh also
195
+ preserves model-native `max` reasoning and Pi's request-wide pricing tiers.
194
196
 
195
197
  ## 11. Exports map: wildcards removed (explicit deep-path map)
196
198
 
197
199
  The package's `./ai/*` and `./agent/*` **wildcard exports were replaced by an
198
- explicit `exports` map**: 3 barrels (`.`, `./ai`, `./agent`) plus **21 named deep
199
- `.js` subpaths**, each carrying its own generated `types` condition. A deep import
200
- that is not on the map **no longer resolves** — a wildcard used to silently
201
- resolve anything under `src/`, so a moved/renamed/mistyped subpath is now a loud
202
- failure (guarded by `scripts/verify-deep-imports.mjs`).
203
-
204
- The 21 supported deep paths:
205
-
206
- ```
207
- ./ai/failure.js ./agent/tools/index.js
208
- ./ai/cost.js ./agent/tools/shared/runtime-context.js
209
- ./ai/backend.js ./agent/tools/shared/ripgrep.js
210
- ./ai/runtime/model-refs.js ./agent/prompt/skill-index.js
211
- ./ai/runtime/registry.js ./agent/allowlists.js
212
- ./ai/runtime/context-windows.js ./agent/transcript.js
213
- ./ai/runtime/fast-mode.js ./agent/compaction.js
214
- ./ai/streaming/codex-events.js
215
- ./ai/live-input-prompt.js
216
- ./ai/file-change-stats.js
217
- ./ai/providers/claude-sdk.js
218
- ./ai/providers/claude-cli.js
219
- ./ai/providers/codex-app.js
220
- ./ai/providers/opencode-discovery.js
200
+ explicit `exports` map**: 3 barrels (`.`, `./ai`, `./agent`) plus the generated
201
+ deep-path inventory below, with every entry carrying its own `types` condition.
202
+ A deep import that is not on the map **no longer resolves** — a wildcard used to
203
+ silently resolve anything under `src/`, so a moved/renamed/mistyped subpath is
204
+ now a loud failure (guarded by `scripts/verify-deep-imports.mjs`).
205
+
206
+ <!-- public-api-js-subpaths:start -->
207
+ <!-- Generated by scripts/generate-public-api-docs.mjs. Do not edit by hand. -->
208
+
209
+ The package exposes **22 named deep `.js` subpaths**:
210
+
211
+ ```text
212
+ @mono-agent/agent-runtime/agent/allowlists.js
213
+ @mono-agent/agent-runtime/agent/compaction.js
214
+ @mono-agent/agent-runtime/agent/prompt/skill-index.js
215
+ @mono-agent/agent-runtime/agent/tools/index.js
216
+ @mono-agent/agent-runtime/agent/tools/shared/ripgrep.js
217
+ @mono-agent/agent-runtime/agent/tools/shared/runtime-context.js
218
+ @mono-agent/agent-runtime/agent/transcript.js
219
+ @mono-agent/agent-runtime/ai/backend.js
220
+ @mono-agent/agent-runtime/ai/cost.js
221
+ @mono-agent/agent-runtime/ai/failure.js
222
+ @mono-agent/agent-runtime/ai/file-change-stats.js
223
+ @mono-agent/agent-runtime/ai/live-input-prompt.js
224
+ @mono-agent/agent-runtime/ai/providers/claude-cli.js
225
+ @mono-agent/agent-runtime/ai/providers/claude-sdk-discovery.js
226
+ @mono-agent/agent-runtime/ai/providers/claude-sdk.js
227
+ @mono-agent/agent-runtime/ai/providers/codex-app.js
228
+ @mono-agent/agent-runtime/ai/providers/opencode-discovery.js
229
+ @mono-agent/agent-runtime/ai/runtime/context-windows.js
230
+ @mono-agent/agent-runtime/ai/runtime/fast-mode.js
231
+ @mono-agent/agent-runtime/ai/runtime/model-refs.js
232
+ @mono-agent/agent-runtime/ai/runtime/registry.js
233
+ @mono-agent/agent-runtime/ai/streaming/codex-events.js
221
234
  ```
235
+ <!-- public-api-js-subpaths:end -->
222
236
 
223
237
  **Action:** if you deep-import a subpath not in this list, switch to the closest
224
238
  supported one, a barrel (`./ai` / `./agent`), or the public runtime registry.
@@ -254,9 +268,9 @@ Run these before/at the port:
254
268
  in `src/`.)*
255
269
  2. **Dependencies.** Post-decoupling the kernel has **zero workspace-package
256
270
  deps**; only the third-party pins need aligning: `@earendil-works/pi-ai` +
257
- `@earendil-works/pi-agent-core` (`^0.80.x`), `@modelcontextprotocol/sdk`,
271
+ `@earendil-works/pi-agent-core` (`0.80.6`), `@modelcontextprotocol/sdk`,
258
272
  `@opencode-ai/sdk`, `@anthropic-ai/claude-agent-sdk`, `zod`.
259
- 3. **Pi bump `^0.74.0` → `^0.80.x` in lockstep.** worklab tests that use old pi
273
+ 3. **Pi bump `^0.74.0` → `0.80.6` in lockstep.** worklab tests that use old pi
260
274
  APIs are rewritten at the port. Do not restore the old `pi-sdk.js` deep
261
275
  import; use `generatePiNativeResponse` from `@mono-agent/agent-runtime/ai`.
262
276
  4. **Sandbox.** worklab passes **no** `sandbox` implementation → `passthroughSandbox`,
package/README.md CHANGED
@@ -10,14 +10,397 @@ Provides five runtime bridges (Claude SDK, Claude Code CLI, Codex app-server, Op
10
10
 
11
11
  ## Public API
12
12
 
13
- - `createRuntime` — runtime factory dispatching to the backend bridges
14
- - `ai/runtime/model-refs.js` `parseRuntimeModelReference`, `executionModeIncompatibilityReason`
15
- - `ai/runtime/registry.js` — `listRuntimeBridges`
16
- - `ai/providers/claude-sdk-discovery.js` isolated Claude SDK model discovery without importing ambient auth/config
17
- - `createRouterRuntime({ chain, routeSafety, resolveAttempt })` — ordered fallback routing with exact route effort and bounded safety/failover telemetry
18
- - Provider bridges for `claude` (SDK + CLI), `codex` (app-server), `pi` (Pi SDK), and `opencode`
19
- - Provider session support: bridges accept `sessionId` in run options and report `provider_session_id`; the runtime exposes best-effort disposal, strict cold-refresh, exact-id durable retirement, invalidation, and whole-runtime shutdown operations
20
- - Sandbox-aware built-in tools and stdio MCP startup through an injectable `RuntimeSandbox` seam (`agent/sandbox-seam.js`) — no direct dependency on `@mono-agent/runtime-adapter`
13
+ <!-- public-api-inventory:start -->
14
+ <!-- Generated by scripts/generate-public-api-docs.mjs. Do not edit by hand. -->
15
+
16
+ Every symbol exported by each public code entrypoint is listed below.
17
+
18
+ **`@mono-agent/agent-runtime`**
19
+
20
+ ```text
21
+ ACTIVE_RUNTIME_KINDS
22
+ ALLOWLIST_MODE_ALL
23
+ ALLOWLIST_MODE_CUSTOM
24
+ APPROVAL_DECISIONS
25
+ BINARY_BLOAT_TOOLS
26
+ BridgeSpec
27
+ CLAUDE_SDK_CATALOG_VERSION
28
+ DEFAULT_RUNTIME_BRAND
29
+ DEFAULT_TOOL_BLOAT_CONFIG
30
+ MAX_TOOL_RESULT_BYTES
31
+ RESERVED_RUNTIME_KINDS
32
+ RISK_TIERS
33
+ RUNTIME_CAPABILITIES
34
+ RuntimeBridge
35
+ RuntimeBridgeDescriptor
36
+ RuntimeBridgeId
37
+ RuntimeModelRef
38
+ UNKNOWN_CAPABILITY
39
+ buildCapabilitiesUsed
40
+ buildTranscriptTailSnapshot
41
+ canonicalizeLegacyModelReference
42
+ configureToolRuntime
43
+ createApprovalManager
44
+ createClaudeSdkDiscoveryIsolation
45
+ createMetricsObserver
46
+ createObserverHub
47
+ createPiOAuthApiKeyResolver
48
+ createRouterRuntime
49
+ createRuntime
50
+ createSessionRegistry
51
+ curatedClaudeSdkModels
52
+ discoverClaudeSdkModels
53
+ disposeAllProviderSessions
54
+ disposeProviderSession
55
+ executionModeIncompatibilityReason
56
+ findProviderForModel
57
+ generatePiNativeResponse
58
+ inferAllowlistMode
59
+ invalidateProviderSession
60
+ isLikelyContextTermination
61
+ isModelCompatibleWithExecutionMode
62
+ listProviders
63
+ listRuntimeBridges
64
+ normalizeAllowlistMode
65
+ normalizeClaudeSdkCatalog
66
+ normalizeClaudeSdkModelId
67
+ normalizeList
68
+ normalizeRuntimeModelReference
69
+ parseRuntimeModelReference
70
+ parseStoredAllowlist
71
+ piNativeRuntimeBridge
72
+ readRuntimeBrand
73
+ readToolRuntime
74
+ refreshProviderSession
75
+ renderResumeSnapshot
76
+ resetToolRuntime
77
+ resolveAgentCompactionPolicy
78
+ resolveAllowlist
79
+ resolveAllowlistMap
80
+ resolveRuntimeBrand
81
+ resolveRuntimeBridge
82
+ runtimeCapabilities
83
+ sdkFromModelReference
84
+ storedAllowlistMode
85
+ syncProviderSession
86
+ toolCompactionAppliedFromWarnings
87
+ wrapToolsWithApprovalGate
88
+ ```
89
+
90
+ **`@mono-agent/agent-runtime/agent`**
91
+
92
+ ```text
93
+ ALLOWLIST_MODE_ALL
94
+ ALLOWLIST_MODE_CUSTOM
95
+ APPROVAL_DECISIONS
96
+ BINARY_BLOAT_TOOLS
97
+ DEFAULT_TOOL_BLOAT_CONFIG
98
+ MAX_TOOL_RESULT_BYTES
99
+ RISK_TIERS
100
+ buildTranscriptTailSnapshot
101
+ createApprovalManager
102
+ inferAllowlistMode
103
+ isLikelyContextTermination
104
+ normalizeAllowlistMode
105
+ normalizeList
106
+ parseStoredAllowlist
107
+ renderResumeSnapshot
108
+ resolveAgentCompactionPolicy
109
+ resolveAllowlist
110
+ resolveAllowlistMap
111
+ storedAllowlistMode
112
+ wrapToolsWithApprovalGate
113
+ ```
114
+
115
+ **`@mono-agent/agent-runtime/agent/allowlists.js`**
116
+
117
+ ```text
118
+ ALLOWLIST_MODE_ALL
119
+ ALLOWLIST_MODE_CUSTOM
120
+ inferAllowlistMode
121
+ normalizeAllowlistMode
122
+ normalizeList
123
+ parseStoredAllowlist
124
+ resolveAllowlist
125
+ resolveAllowlistMap
126
+ storedAllowlistMode
127
+ ```
128
+
129
+ **`@mono-agent/agent-runtime/agent/compaction.js`**
130
+
131
+ ```text
132
+ AgentCompactionPolicy
133
+ DEPRECATED_SETTINGS_WARNING_KIND
134
+ deprecatedSettingsWarning
135
+ estimateFixedOverheadTokens
136
+ isLikelyContextTermination
137
+ resolveAgentCompactionPolicy
138
+ resolveRuntimePolicyInputs
139
+ ```
140
+
141
+ **`@mono-agent/agent-runtime/agent/prompt/skill-index.js`**
142
+
143
+ ```text
144
+ buildSkillIndex
145
+ buildSkillPathNote
146
+ formatSkillBodyWithPathNote
147
+ getSkillAccessDirs
148
+ inferSkillsRoot
149
+ ```
150
+
151
+ **`@mono-agent/agent-runtime/agent/tools/index.js`**
152
+
153
+ ```text
154
+ bashToolImpl
155
+ editToolImpl
156
+ globToolImpl
157
+ grepToolImpl
158
+ isPathAllowed
159
+ isWorkdirAllowed
160
+ normalizeBashTimeoutMs
161
+ readToolImpl
162
+ resolveRgPath
163
+ webFetchToolImpl
164
+ webSearchToolImpl
165
+ writeToolImpl
166
+ ```
167
+
168
+ **`@mono-agent/agent-runtime/agent/tools/shared/ripgrep.js`**
169
+
170
+ ```text
171
+ cachedRgPath
172
+ capLines
173
+ excludedGlobArgs
174
+ excludedPathSummary
175
+ formatSearchLines
176
+ normalizeGlobPattern
177
+ resolveRgPath
178
+ ripgrepMissingMessage
179
+ ```
180
+
181
+ **`@mono-agent/agent-runtime/agent/tools/shared/runtime-context.js`**
182
+
183
+ ```text
184
+ ToolContext
185
+ ToolRuntimeContext
186
+ configureToolRuntime
187
+ readRuntimeBrand
188
+ readToolRuntime
189
+ resetToolRuntime
190
+ resolveSandboxPolicy
191
+ ```
192
+
193
+ **`@mono-agent/agent-runtime/agent/transcript.js`**
194
+
195
+ ```text
196
+ RESUME_SNAPSHOT_DEFAULTS
197
+ buildTranscriptTailSnapshot
198
+ renderResumeSnapshot
199
+ ```
200
+
201
+ **`@mono-agent/agent-runtime/ai`**
202
+
203
+ ```text
204
+ ACTIVE_RUNTIME_KINDS
205
+ BridgeSpec
206
+ CLAUDE_SDK_CATALOG_VERSION
207
+ RESERVED_RUNTIME_KINDS
208
+ RUNTIME_CAPABILITIES
209
+ RuntimeBridge
210
+ RuntimeBridgeDescriptor
211
+ RuntimeBridgeId
212
+ RuntimeModelRef
213
+ UNKNOWN_CAPABILITY
214
+ buildCapabilitiesUsed
215
+ canonicalizeLegacyModelReference
216
+ createClaudeSdkDiscoveryIsolation
217
+ createMetricsObserver
218
+ createObserverHub
219
+ createSessionRegistry
220
+ curatedClaudeSdkModels
221
+ discoverClaudeSdkModels
222
+ disposeAllProviderSessions
223
+ disposeProviderSession
224
+ executionModeIncompatibilityReason
225
+ findProviderForModel
226
+ generatePiNativeResponse
227
+ invalidateProviderSession
228
+ isModelCompatibleWithExecutionMode
229
+ listProviders
230
+ listRuntimeBridges
231
+ normalizeClaudeSdkCatalog
232
+ normalizeClaudeSdkModelId
233
+ normalizeRuntimeModelReference
234
+ parseRuntimeModelReference
235
+ piNativeRuntimeBridge
236
+ refreshProviderSession
237
+ resolveRuntimeBridge
238
+ runtimeCapabilities
239
+ sdkFromModelReference
240
+ syncProviderSession
241
+ toolCompactionAppliedFromWarnings
242
+ ```
243
+
244
+ **`@mono-agent/agent-runtime/ai/backend.js`**
245
+
246
+ ```text
247
+ BACKEND_CAPABILITIES
248
+ backendCapabilities
249
+ backendSupportsSessionResume
250
+ backendUsesExecenvConfig
251
+ ```
252
+
253
+ **`@mono-agent/agent-runtime/ai/cost.js`**
254
+
255
+ ```text
256
+ NormalizedPricing
257
+ ParsedModelReference
258
+ PricingInputRow
259
+ estimateCost
260
+ isPrivateHost
261
+ normalizePricing
262
+ parseReference
263
+ pricingHasRates
264
+ resolvePricing
265
+ unknownPricing
266
+ zeroPricing
267
+ ```
268
+
269
+ **`@mono-agent/agent-runtime/ai/failure.js`**
270
+
271
+ ```text
272
+ FAILURE_KINDS
273
+ FailureKind
274
+ PROVIDER_ABORT_RE
275
+ RetryableProviderFailureInfo
276
+ classifyFailure
277
+ createStderrTail
278
+ isProviderAuthFailureText
279
+ retryableProviderFailureInfo
280
+ ```
281
+
282
+ **`@mono-agent/agent-runtime/ai/file-change-stats.js`**
283
+
284
+ ```text
285
+ createFileChangePayload
286
+ fileChangeSummary
287
+ readFileChangeSnapshot
288
+ statsForCompletedChange
289
+ ```
290
+
291
+ **`@mono-agent/agent-runtime/ai/live-input-prompt.js`**
292
+
293
+ ```text
294
+ formatLiveInputGuidance
295
+ ```
296
+
297
+ **`@mono-agent/agent-runtime/ai/providers/claude-cli.js`**
298
+
299
+ ```text
300
+ buildCliCommand
301
+ claudeCodeBackend
302
+ claudeCodeRuntimeBridge
303
+ codexCliBackend
304
+ createThinkingBuffer
305
+ generateCliResponse
306
+ normalizeCliEvent
307
+ ```
308
+
309
+ **`@mono-agent/agent-runtime/ai/providers/claude-sdk-discovery.js`**
310
+
311
+ ```text
312
+ CLAUDE_SDK_CATALOG_VERSION
313
+ ClaudeSdkCatalogModel
314
+ ClaudeSdkEffort
315
+ createClaudeSdkDiscoveryIsolation
316
+ curatedClaudeSdkModels
317
+ discoverClaudeSdkModels
318
+ normalizeClaudeSdkCatalog
319
+ normalizeClaudeSdkModelId
320
+ ```
321
+
322
+ **`@mono-agent/agent-runtime/ai/providers/claude-sdk.js`**
323
+
324
+ ```text
325
+ claudeEffortOptions
326
+ claudeRuntimeBridge
327
+ claudeSdkBackend
328
+ claudeSdkModelForQuery
329
+ generateClaudeResponse
330
+ toolPayloadLimit
331
+ ```
332
+
333
+ **`@mono-agent/agent-runtime/ai/providers/codex-app.js`**
334
+
335
+ ```text
336
+ codexAppBackend
337
+ codexAppRuntimeBridge
338
+ createCodexAppServerClient
339
+ generateCodexAppResponse
340
+ ```
341
+
342
+ **`@mono-agent/agent-runtime/ai/providers/opencode-discovery.js`**
343
+
344
+ ```text
345
+ discoverOpencodeProviders
346
+ ```
347
+
348
+ **`@mono-agent/agent-runtime/ai/runtime/context-windows.js`**
349
+
350
+ ```text
351
+ CLAUDE_ONE_MILLION_CONTEXT_MODELS
352
+ DEFAULT_CONTEXT_WINDOW
353
+ ONE_MILLION_CONTEXT_WINDOW
354
+ claudeModelSupportsContextWindow
355
+ claudeModelSupportsOneMillionContext
356
+ hasExplicitOneMillionContextWindow
357
+ modelWithContextWindow
358
+ normalizeContextWindow
359
+ stripContextWindowSuffix
360
+ ```
361
+
362
+ **`@mono-agent/agent-runtime/ai/runtime/fast-mode.js`**
363
+
364
+ ```text
365
+ codexModelSupportsFastMode
366
+ normalizeFastMode
367
+ ```
368
+
369
+ **`@mono-agent/agent-runtime/ai/runtime/model-refs.js`**
370
+
371
+ ```text
372
+ ACTIVE_RUNTIME_KINDS
373
+ RESERVED_RUNTIME_KINDS
374
+ RuntimeModelRef
375
+ canonicalizeLegacyModelReference
376
+ executionModeIncompatibilityReason
377
+ isModelCompatibleWithExecutionMode
378
+ normalizeRuntimeModelReference
379
+ parseRuntimeModelReference
380
+ sdkFromModelReference
381
+ ```
382
+
383
+ **`@mono-agent/agent-runtime/ai/runtime/registry.js`**
384
+
385
+ ```text
386
+ BridgeSpec
387
+ RUNTIME_CAPABILITIES
388
+ RuntimeBridge
389
+ RuntimeBridgeDescriptor
390
+ RuntimeBridgeId
391
+ listRuntimeBridges
392
+ resolveRuntimeBridge
393
+ runtimeCapabilities
394
+ ```
395
+
396
+ **`@mono-agent/agent-runtime/ai/streaming/codex-events.js`**
397
+
398
+ ```text
399
+ normalizeCodexItemEvent
400
+ normalizeCodexItemType
401
+ ```
402
+
403
+ <!-- public-api-inventory:end -->
21
404
 
22
405
  ## Dependency Boundary
23
406
 
package/package.json CHANGED
@@ -1,9 +1,14 @@
1
1
  {
2
2
  "name": "@mono-agent/agent-runtime",
3
- "version": "0.11.3",
3
+ "version": "0.11.5",
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",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/robertsreberski/mono-agent.git",
10
+ "directory": "packages/agent-runtime"
11
+ },
7
12
  "keywords": [
8
13
  "ai",
9
14
  "agents",
@@ -132,8 +137,8 @@
132
137
  "dependencies": {
133
138
  "@anthropic-ai/claude-agent-sdk": "0.3.206",
134
139
  "@anthropic-ai/sdk": "^0.110.0",
135
- "@earendil-works/pi-agent-core": "^0.80.5",
136
- "@earendil-works/pi-ai": "^0.80.5",
140
+ "@earendil-works/pi-agent-core": "0.80.6",
141
+ "@earendil-works/pi-ai": "0.80.6",
137
142
  "@modelcontextprotocol/sdk": "^1.29.0",
138
143
  "@opencode-ai/sdk": "^1.15.13",
139
144
  "@vscode/ripgrep": "1.18.0",
@@ -1,8 +1,7 @@
1
- // Public surface of the agent kernel. The kernel is consumed by the
2
- // worker, the assistant, the Slack triage path, and the coordinator's
3
- // run-spawn path. Everything below is intentionally re-exported; anything
4
- // not listed here is private to the kernel and should not be imported
5
- // from edge layers.
1
+ // Public agent-kernel barrel for runtime hosts. Everything below is
2
+ // intentionally re-exported through `@mono-agent/agent-runtime/agent`;
3
+ // agent modules not exposed by the package's exports map remain private
4
+ // implementation details.
6
5
 
7
6
  export {
8
7
  isLikelyContextTermination,
package/src/ai/cost.js CHANGED
@@ -4,6 +4,7 @@
4
4
  // deprecated/compat-only). `getBuiltinModel(provider, id)` from `providers/all`
5
5
  // is the non-deprecated replacement with the same signature and the same
6
6
  // undefined-on-miss behavior the pricing lookup below relies on.
7
+ import { calculateCost as calculatePiCost } from "@earendil-works/pi-ai";
7
8
  import { getBuiltinModel as getPiModel } from "@earendil-works/pi-ai/providers/all";
8
9
 
9
10
  /**
@@ -192,9 +193,9 @@ function pricingHasRates(pricing = {}) {
192
193
  * - sdk "claude": looked up under pi's "anthropic" provider (its models carry
193
194
  * `cost`), so pi's live rates win over the static CLAUDE_PRICING fallback.
194
195
  * @param {ParsedModelReference|null|undefined} parsed
195
- * @returns {NormalizedPricing|null}
196
+ * @returns {import("@earendil-works/pi-ai").Model<any>|null}
196
197
  */
197
- function piCatalogPricing(parsed) {
198
+ function piCatalogModel(parsed) {
198
199
  if (!parsed?.model) return null;
199
200
  let provider;
200
201
  if (parsed.sdk === "pi" && parsed.provider) provider = parsed.provider;
@@ -204,13 +205,21 @@ function piCatalogPricing(parsed) {
204
205
  // `provider` may be a caller-supplied id (custom providers included), wider
205
206
  // than pi-ai's built-in KnownProvider catalog union; the catalog lookup
206
207
  // itself is the runtime check, guarded by the catch below.
207
- const model = getPiModel(/** @type {*} */ (provider), parsed.model);
208
- return model?.cost ? normalizePricing(model.cost, { source: "pi-catalog" }) : null;
208
+ return getPiModel(/** @type {*} */ (provider), parsed.model) || null;
209
209
  } catch {
210
210
  return null;
211
211
  }
212
212
  }
213
213
 
214
+ /**
215
+ * @param {ParsedModelReference|null|undefined} parsed
216
+ * @returns {NormalizedPricing|null}
217
+ */
218
+ function piCatalogPricing(parsed) {
219
+ const model = piCatalogModel(parsed);
220
+ return model?.cost ? normalizePricing(model.cost, { source: "pi-catalog" }) : null;
221
+ }
222
+
214
223
  /**
215
224
  * @param {ParsedModelReference|null|undefined} parsed
216
225
  * @returns {NormalizedPricing|null}
@@ -244,6 +253,19 @@ export function resolvePricing({ resolveCustomPricing, model } = {}) {
244
253
  || unknownPricing();
245
254
  }
246
255
 
256
+ /**
257
+ * @param {any} model
258
+ * @param {{input: number, output: number, cacheRead: number, cacheWrite: number}} usage
259
+ * @returns {number}
260
+ */
261
+ function estimatePiCatalogCost(model, usage) {
262
+ return calculatePiCost(model, {
263
+ ...usage,
264
+ totalTokens: usage.input + usage.output + usage.cacheRead + usage.cacheWrite,
265
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
266
+ }).total;
267
+ }
268
+
247
269
  export { normalizePricing, zeroPricing, unknownPricing, pricingHasRates, isPrivateHost, parseReference };
248
270
 
249
271
  /**
@@ -266,12 +288,22 @@ export function estimateCost({
266
288
  cacheWriteTokens = 0,
267
289
  cacheCreationTokens = 0,
268
290
  } = {}) {
269
- const pricing = resolvePricing({ resolveCustomPricing, model });
270
- if (!pricing?.priced) return null;
271
291
  const cacheRead = Math.max(0, Number(cachedTokens) || 0);
272
292
  const cacheWrite = Math.max(0, Number(cacheWriteTokens ?? cacheCreationTokens) || 0);
273
293
  const input = Math.max(0, Number(inputTokens) || 0);
274
294
  const output = Math.max(0, Number(outputTokens) || 0);
295
+ const parsed = parseReference(model);
296
+ const customPricing = parsed && typeof resolveCustomPricing === "function"
297
+ ? resolveCustomPricing(parsed)
298
+ : null;
299
+ const piModel = customPricing ? null : piCatalogModel(parsed);
300
+ if (piModel?.cost) {
301
+ return estimatePiCatalogCost(piModel, { input, output, cacheRead, cacheWrite });
302
+ }
303
+ const pricing = customPricing
304
+ || claudePricing(parsed)
305
+ || unknownPricing();
306
+ if (!pricing?.priced) return null;
275
307
  const parts = [
276
308
  [input, pricing.input],
277
309
  [cacheRead, pricing.cacheRead],
@@ -24,8 +24,11 @@ const MAX_CLAUDE_ERROR_CHARS = 2_000;
24
24
 
25
25
  /**
26
26
  * Preserve the provider default when effort is omitted. The current Agent SDK
27
- * accepts the five values below verbatim; mono-agent must not infer thinking
28
- * enablement/disablement from a requested effort level.
27
+ * public effort contract accepts the five values below. Its shipped JavaScript
28
+ * currently forwards out-of-contract values to Claude Code, so mono-agent keeps
29
+ * this route inside the pinned public contract rather than relying on that
30
+ * untyped pass-through. Mono-agent must not infer thinking enablement/disablement
31
+ * from a requested effort level.
29
32
  * @param {unknown} effort
30
33
  * @returns {{effort?: "low" | "medium" | "high" | "xhigh" | "max"}}
31
34
  */
@@ -34,12 +37,12 @@ export function claudeEffortOptions(effort) {
34
37
  const normalized = String(effort).trim();
35
38
  if (normalized === "none") {
36
39
  throw new Error(
37
- 'Claude Agent SDK does not support effort "none". Omit effort to use the provider default, or choose low, medium, high, xhigh, or max.',
40
+ 'Mono-agent\'s Claude SDK route does not support effort "none": the pinned Claude Agent SDK public effort contract starts at "low". Omit effort to use the provider default, or choose low, medium, high, xhigh, or max.',
38
41
  );
39
42
  }
40
43
  if (!CLAUDE_EFFORT_LEVELS.has(normalized)) {
41
44
  throw new Error(
42
- `Claude Agent SDK does not support effort "${boundedText(normalized, 64)}". Choose low, medium, high, xhigh, or max, or omit effort.`,
45
+ `Mono-agent's Claude SDK route does not support effort "${boundedText(normalized, 64)}": the pinned Claude Agent SDK public effort contract ends at "max". Choose low, medium, high, xhigh, or max, or omit effort.`,
43
46
  );
44
47
  }
45
48
  return { effort: /** @type {"low" | "medium" | "high" | "xhigh" | "max"} */ (normalized) };
@@ -2,6 +2,7 @@
2
2
  // deprecated/compat-only. `getBuiltinModel(provider, id)` from `providers/all`
3
3
  // is the non-deprecated replacement — same 2-arg signature, and it returns
4
4
  // `undefined` on an unknown provider/model exactly like the old `getModel`.
5
+ import { getSupportedThinkingLevels } from "@earendil-works/pi-ai";
5
6
  import { getBuiltinModel as getPiModel } from "@earendil-works/pi-ai/providers/all";
6
7
  import { readRuntimeBrand } from "../../agent/tools/shared/runtime-context.js";
7
8
 
@@ -42,6 +43,18 @@ function customCompat(capabilities, isPrivate) {
42
43
  };
43
44
  }
44
45
 
46
+ /**
47
+ * Translate Pi's model-native thinking levels to mono-agent's public effort
48
+ * spelling. Pi calls the disabled level `off`; mono-agent calls it `none`.
49
+ * Keeping this derived from the model lets new native levels (such as `max`)
50
+ * flow through without maintaining a second hard-coded catalog.
51
+ * @param {any} model
52
+ * @returns {string[]}
53
+ */
54
+ export function reasoningLevelsForPiModel(model) {
55
+ return getSupportedThinkingLevels(model).map((level) => level === "off" ? "none" : level);
56
+ }
57
+
45
58
  // Build the pi-runtime view of a custom provider/model from
46
59
  // pre-resolved primitives. The caller (core/ai.js#generateResponse) reads
47
60
  // the provider/model rows and computes the capabilities + isPrivate flag
@@ -118,7 +131,7 @@ export function resolvePiRuntimeModel(resolved, options) {
118
131
  tool_use: true,
119
132
  reasoning: !!model.reasoning,
120
133
  reasoning_mode: model.reasoning ? "effort" : "none",
121
- reasoning_levels: model.reasoning ? ["none", "low", "medium", "high", "xhigh"] : undefined,
134
+ reasoning_levels: model.reasoning ? reasoningLevelsForPiModel(model) : undefined,
122
135
  reasoning_disable_supported: true,
123
136
  vision: Array.isArray(model.input) ? model.input.includes("image") : false,
124
137
  json_mode: true,
@@ -14,17 +14,6 @@ import {
14
14
  streamContentKey,
15
15
  } from "../pi-events.js";
16
16
 
17
- /**
18
- * The tool-start progress line surfaced as a thinking block, or null for a
19
- * blank/invalid tool name.
20
- * @param {unknown} toolName
21
- * @returns {string|null}
22
- */
23
- export function toolStartProgressText(toolName) {
24
- if (typeof toolName !== "string" || toolName.trim().length === 0) return null;
25
- return `Running ${toolName}...`;
26
- }
27
-
28
17
  function toolResultFileChange(result) {
29
18
  const fileChange = result?.details?.file_change;
30
19
  return fileChange && typeof fileChange === "object" && !Array.isArray(fileChange)
@@ -84,10 +73,6 @@ export function createStreamSubscriber(runState, { onEvent, options, toolLimits,
84
73
  if (event.toolName) runState.lastToolName = event.toolName;
85
74
  if (event.toolCallId) runState.toolStartTimes.set(event.toolCallId, Date.now());
86
75
  const input = eventToolArgs(event.toolName, event.args, { cwd: options.cwd, toolLimits });
87
- const progressText = toolStartProgressText(event.toolName);
88
- if (progressText) {
89
- onEvent({ type: "assistant", message: { content: [{ type: "thinking", text: progressText }] } });
90
- }
91
76
  onEvent({
92
77
  type: "assistant",
93
78
  message: { content: [{ type: "tool_use", id: event.toolCallId, name: event.toolName, input }] },
@@ -147,10 +147,19 @@ export async function buildTurnTools(runState, {
147
147
  export function thinkingLevelForEffort(effort, capabilities) {
148
148
  if (!capabilities?.reasoning || capabilities.reasoning_mode === "none") return "off";
149
149
  if (effort === "none") return "off";
150
- if (effort === "max") return "xhigh";
150
+ // Pi <0.80.6 and older/custom model metadata do not advertise native max.
151
+ // Preserve the historical xhigh ceiling for those models, but pass max
152
+ // through when the resolved model explicitly declares it.
153
+ if (effort === "max") {
154
+ return Array.isArray(capabilities.reasoning_levels)
155
+ && capabilities.reasoning_levels.includes("max")
156
+ ? "max"
157
+ : "xhigh";
158
+ }
151
159
  if (effort === "xhigh") return "xhigh";
152
160
  if (effort === "high") return "high";
153
161
  if (effort === "medium") return "medium";
162
+ if (effort === "minimal") return "minimal";
154
163
  return "low";
155
164
  }
156
165
 
@@ -34,7 +34,7 @@ import {
34
34
  import { closePiMcpClients } from "../../agent/tools/pi-bridge.js";
35
35
  import { createApprovalManager } from "../../agent/approval.js";
36
36
  import { buildCapabilitiesUsed, toolCompactionAppliedFromWarnings } from "../runtime/capabilities-used.js";
37
- import { resolvePiRuntimeModel } from "./pi-models.js";
37
+ import { reasoningLevelsForPiModel, resolvePiRuntimeModel } from "./pi-models.js";
38
38
  import {
39
39
  textFromContent,
40
40
  thinkingFromContent,
@@ -358,6 +358,9 @@ export async function generatePiNativeResponse(systemPrompt, options = {}) {
358
358
  tool_use: true,
359
359
  reasoning: !!options.piResolvedModel.reasoning,
360
360
  reasoning_mode: options.piResolvedModel.reasoning ? "effort" : "none",
361
+ reasoning_levels: options.piResolvedModel.reasoning
362
+ ? reasoningLevelsForPiModel(options.piResolvedModel)
363
+ : undefined,
361
364
  json_mode: true,
362
365
  },
363
366
  apiKeys: new Map(),
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * Preserve the provider default when effort is omitted. The current Agent SDK
3
- * accepts the five values below verbatim; mono-agent must not infer thinking
4
- * enablement/disablement from a requested effort level.
3
+ * public effort contract accepts the five values below. Its shipped JavaScript
4
+ * currently forwards out-of-contract values to Claude Code, so mono-agent keeps
5
+ * this route inside the pinned public contract rather than relying on that
6
+ * untyped pass-through. Mono-agent must not infer thinking enablement/disablement
7
+ * from a requested effort level.
5
8
  * @param {unknown} effort
6
9
  * @returns {{effort?: "low" | "medium" | "high" | "xhigh" | "max"}}
7
10
  */
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Translate Pi's model-native thinking levels to mono-agent's public effort
3
+ * spelling. Pi calls the disabled level `off`; mono-agent calls it `none`.
4
+ * Keeping this derived from the model lets new native levels (such as `max`)
5
+ * flow through without maintaining a second hard-coded catalog.
6
+ * @param {any} model
7
+ * @returns {string[]}
8
+ */
9
+ export function reasoningLevelsForPiModel(model: any): string[];
1
10
  export function resolvePiRuntimeModel(resolved: any, options: any): {
2
11
  model: {
3
12
  id: any;
@@ -1,10 +1,3 @@
1
- /**
2
- * The tool-start progress line surfaced as a thinking block, or null for a
3
- * blank/invalid tool name.
4
- * @param {unknown} toolName
5
- * @returns {string|null}
6
- */
7
- export function toolStartProgressText(toolName: unknown): string | null;
8
1
  /**
9
2
  * The slice of run state the stream subscriber reads and mutates. A structural
10
3
  * subset of the orchestrator's runState.