@mono-agent/agent-runtime 0.15.3 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +41 -13
- package/README.md +43 -6
- package/package.json +7 -3
- package/src/agent/tools/agent-tool.js +894 -0
- package/src/agent/tools/bash.js +241 -123
- package/src/agent/tools/exec.js +238 -0
- package/src/agent/tools/index.js +10 -3
- package/src/agent/tools/node-repl.js +231 -95
- package/src/agent/tools/pi-bridge.js +115 -24
- package/src/agent/tools/shared/process-runner.js +162 -0
- package/src/agent/tools/shared/semaphore.js +73 -0
- package/src/agent/tools/web-browser-render.js +221 -0
- package/src/agent/tools/web-controller.js +160 -0
- package/src/agent/tools/web-fetch.js +653 -68
- package/src/agent/tools/web-search.js +568 -16
- package/src/ai/pi-interop.js +7 -5
- package/src/ai/pi-oauth-compat.js +193 -0
- package/src/ai/providers/pi-native/stream-subscriber.js +37 -0
- package/src/ai/providers/pi-native/turn-runner.js +73 -8
- package/src/ai/providers/pi-native.js +67 -7
- package/src/ai/runtime/router.js +310 -166
- package/src/ai/types.js +54 -2
- package/src/pi-auth.js +2 -2
- package/src/runtime.js +58 -1
- package/types/agent/tools/agent-tool.d.ts +80 -0
- package/types/agent/tools/bash.d.ts +55 -7
- package/types/agent/tools/exec.d.ts +53 -0
- package/types/agent/tools/index.d.ts +5 -3
- package/types/agent/tools/node-repl.d.ts +28 -3
- package/types/agent/tools/pi-bridge.d.ts +6 -2
- package/types/agent/tools/shared/process-runner.d.ts +33 -0
- package/types/agent/tools/shared/semaphore.d.ts +29 -0
- package/types/agent/tools/web-browser-render.d.ts +16 -0
- package/types/agent/tools/web-controller.d.ts +20 -0
- package/types/agent/tools/web-fetch.d.ts +74 -5
- package/types/agent/tools/web-search.d.ts +81 -5
- package/types/ai/pi-oauth-compat.d.ts +57 -0
- package/types/ai/providers/pi-native/turn-runner.d.ts +33 -2
- package/types/ai/providers/pi-native.d.ts +12 -0
- package/types/ai/runtime/router.d.ts +23 -3
- package/types/ai/types.d.ts +174 -4
- package/types/ai/backend.d.ts +0 -57
- package/types/ai/registry.d.ts +0 -1
package/MIGRATION.md
CHANGED
|
@@ -42,8 +42,8 @@ the configuration schema.
|
|
|
42
42
|
switch to `listPiBuiltinModels`, `getPiBuiltinModel`,
|
|
43
43
|
`reasoningLevelsForPiModel`, `resolvePiOAuthApiKey`, and `loginPiOAuth` from
|
|
44
44
|
`@mono-agent/agent-runtime/ai`. The runtime keeps Pi AI and Pi Agent Core
|
|
45
|
-
exact-pinned at `0.
|
|
46
|
-
snapshots rather than exposing
|
|
45
|
+
exact-pinned at `0.83.0`; the façade returns cloned model and credential
|
|
46
|
+
snapshots rather than exposing upstream provider objects.
|
|
47
47
|
- **Claude test seam:** downstream tests should pass
|
|
48
48
|
`RuntimeRunOptions.claudeAgentQuery` instead of mocking
|
|
49
49
|
`@anthropic-ai/claude-agent-sdk` by package name. Normal runs omit this option
|
|
@@ -63,12 +63,27 @@ the configuration schema.
|
|
|
63
63
|
authoritative and the runtime emits a bounded
|
|
64
64
|
`live_input_callback_failed` warning.
|
|
65
65
|
|
|
66
|
-
## 0.
|
|
66
|
+
## 0.16.x baseline
|
|
67
67
|
|
|
68
68
|
This is the current published baseline for the detailed pre-1.0 reference
|
|
69
|
-
below. It
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
below. It carries the whole 0.15.x contract forward and adds:
|
|
70
|
+
|
|
71
|
+
- `skills` and `skillsRoot` on the run options. `skills` is the disclosed
|
|
72
|
+
`{name, description}` set for a run; a non-empty value makes `supports_skills`
|
|
73
|
+
a routing requirement, so a chain entry lacking it is skipped. `skillsRoot`
|
|
74
|
+
names the directory holding `<name>/SKILL.md` and is required alongside
|
|
75
|
+
`skills` for `ReadSkill` to exist. A subagent run now inherits both from its
|
|
76
|
+
parent unless a host-supplied `run` withholds them, so a child no longer has
|
|
77
|
+
to rediscover by trial and error what its parent could look up.
|
|
78
|
+
- Provider failover detail reaches whoever is watching the run rather than being
|
|
79
|
+
flattened at the boundary.
|
|
80
|
+
- Pi SDK 0.83.0.
|
|
81
|
+
|
|
82
|
+
## 0.15.x
|
|
83
|
+
|
|
84
|
+
- The explicit exports map, the five-bridge lazy registry, typed runtime
|
|
85
|
+
policies, runtime-owned provider dependencies, and the public-surface cleanup
|
|
86
|
+
described in this guide.
|
|
72
87
|
|
|
73
88
|
## 0.12.x
|
|
74
89
|
|
|
@@ -313,9 +328,22 @@ falls back to its own env vars, exactly as returning `undefined` from the old ho
|
|
|
313
328
|
did). **No host action needed** — `resolvePiApiKey` behaves as before.
|
|
314
329
|
|
|
315
330
|
Dependency bump: **`@earendil-works/pi-ai` and `@earendil-works/pi-agent-core` are
|
|
316
|
-
now `0.
|
|
317
|
-
`^0.79.1
|
|
318
|
-
|
|
331
|
+
now `0.83.0`** (the initial Pi 0.80 migration landed at `0.80.5`, from
|
|
332
|
+
`^0.79.1`, and ran at `0.80.6` until the 0.83 upgrade). Compaction is driven
|
|
333
|
+
natively (section 3), and model-native `max` reasoning plus Pi's request-wide
|
|
334
|
+
pricing tiers are preserved.
|
|
335
|
+
|
|
336
|
+
The 0.83 upgrade carries two upstream removals, both absorbed inside the runtime
|
|
337
|
+
so hosts need no action:
|
|
338
|
+
|
|
339
|
+
- `@earendil-works/pi-ai/oauth` became a type-only entry point. The generic
|
|
340
|
+
registry (`getOAuthApiKey`, `getOAuthProvider`, `getOAuthProviders`) is gone,
|
|
341
|
+
and the per-provider flows are not importable. `src/ai/pi-oauth-compat.js`
|
|
342
|
+
rebuilds the same contracts over `provider.auth.oauth`, so `resolvePiApiKey`,
|
|
343
|
+
`resolvePiOAuthApiKey`, and `loginPiOAuth` keep their existing signatures and
|
|
344
|
+
behaviour, including the refresh-on-expiry trigger.
|
|
345
|
+
- `AgentHarnessOptions.env` was removed in favour of a per-turn `toolContext`.
|
|
346
|
+
The runtime passes neither: it uses none of Pi's built-in file/shell tools.
|
|
319
347
|
|
|
320
348
|
### 11. Exports map: wildcards removed (explicit deep-path map)
|
|
321
349
|
|
|
@@ -366,7 +394,7 @@ a compatibility subpath.
|
|
|
366
394
|
|
|
367
395
|
## Version
|
|
368
396
|
|
|
369
|
-
This guide describes the published `0.
|
|
397
|
+
This guide describes the published `0.16.x` package contract. Keep
|
|
370
398
|
`@mono-agent/agent-runtime`, `@mono-agent/runtime-adapter`, and other
|
|
371
399
|
`@mono-agent/*` packages on the same lockstep version when upgrading. The paired
|
|
372
400
|
runtime adapter no longer exposes `piReasoningSummary` in its run-options type.
|
|
@@ -387,14 +415,14 @@ Worklab's runtime fork:
|
|
|
387
415
|
`@earendil-works/pi-ai`, its separate Pi version constraint, and local copies
|
|
388
416
|
of provider bridge code. Move tests off Pi's faux-provider helpers too; until
|
|
389
417
|
that is complete, isolate the fixture or pin its development-only Pi
|
|
390
|
-
dependency to exact `0.
|
|
418
|
+
dependency to exact `0.83.0` rather than a floating range. Do not restore the
|
|
391
419
|
removed `pi-sdk.js` subpath.
|
|
392
420
|
3. **Use the public Pi surfaces.** Run models through
|
|
393
421
|
`generatePiNativeResponse` or the runtime registry. Use
|
|
394
422
|
`listPiBuiltinModels`, `getPiBuiltinModel`,
|
|
395
423
|
`reasoningLevelsForPiModel`, `resolvePiOAuthApiKey`, and `loginPiOAuth` for
|
|
396
|
-
catalog and OAuth integration. Those façades keep Pi
|
|
397
|
-
exact `0.
|
|
424
|
+
catalog and OAuth integration. Those façades keep Pi provider objects and the
|
|
425
|
+
exact `0.83.0` compatibility pin inside the runtime. OAuth login adapters
|
|
398
426
|
must supply `onAuth`, `onDeviceCode`, `onPrompt`, and `onSelect`; the façade
|
|
399
427
|
rejects an incomplete callback contract before starting provider login.
|
|
400
428
|
4. **Inject Claude tests.** Replace package-level mocks of
|
package/README.md
CHANGED
|
@@ -246,12 +246,19 @@ inferSkillsRoot
|
|
|
246
246
|
|
|
247
247
|
```text
|
|
248
248
|
bashToolImpl
|
|
249
|
+
bashToolRun
|
|
250
|
+
createWebToolController
|
|
249
251
|
editToolImpl
|
|
252
|
+
execToolImpl
|
|
253
|
+
execToolRun
|
|
250
254
|
globToolImpl
|
|
251
255
|
grepToolImpl
|
|
252
256
|
isPathAllowed
|
|
253
257
|
isWorkdirAllowed
|
|
254
258
|
normalizeBashTimeoutMs
|
|
259
|
+
normalizeProcessTimeoutMs
|
|
260
|
+
performWebFetch
|
|
261
|
+
performWebSearch
|
|
255
262
|
readToolImpl
|
|
256
263
|
resolveRgPath
|
|
257
264
|
webFetchToolImpl
|
|
@@ -652,6 +659,9 @@ Per-call options (a non-exhaustive selection):
|
|
|
652
659
|
| `disallowedTools` | `string[]` | Block list. |
|
|
653
660
|
| `mcpServers` | `Record<string, McpServerConfig>` | Configured MCP servers (stdio / sse / http); on direct Codex, each forwarded server authorizes its own tool calls. |
|
|
654
661
|
| `sandboxPolicy` | `SandboxPolicy` | Optional fail-closed sandbox policy for built-in tools and stdio MCP process startup. |
|
|
662
|
+
| `webSearchConfig` | `{ backend?, endpoint? }` | Run-scoped local SearXNG/keyless WebSearch backend selection. |
|
|
663
|
+
| `webFetchConfig` | `{ render?, browserCommand? }` | Run-scoped static extraction and optional isolated browser-render policy. |
|
|
664
|
+
| `piToolExecutionMode` | `"safe-parallel" \| "sequential"` | Pi built-in scheduling. Safe parallelism is the default; stateful/mutating and MCP tools stay sequential. |
|
|
655
665
|
| `maxTurns` | `number` | Hard cap on agent turns. |
|
|
656
666
|
| `outputSchema` | `JSONSchema` | Requests structured JSON on capable bridges; see “Structured output” below for bridge-specific return behavior. |
|
|
657
667
|
| `abortSignal` | `AbortSignal` | Cancel the run. |
|
|
@@ -744,13 +754,29 @@ Successful provider requests may also emit exact context telemetry through
|
|
|
744
754
|
|
|
745
755
|
### Built-in tools
|
|
746
756
|
|
|
747
|
-
The agent kernel's managed tools are `Read`, `Write`, `Edit`, `Glob`, `Grep`,
|
|
757
|
+
The agent kernel's managed tools are `Read`, `Write`, `Edit`, `Glob`, `Grep`,
|
|
758
|
+
`Exec`, `Bash`, `NodeRepl`, `WebFetch`, and `WebSearch`.
|
|
759
|
+
`Exec({ executable, args })` invokes one executable directly; `Bash` is the
|
|
760
|
+
clean non-interactive shell surface for pipelines, redirection, and other shell
|
|
761
|
+
syntax. Both preserve bounded partial stdout/stderr and structured exit,
|
|
762
|
+
timeout, abort, signal, and truncation metadata. `NodeRepl({ code })` is backed
|
|
763
|
+
by one lazily started Node.js REPL child per run. You select them via
|
|
764
|
+
`allowedTools`. Tool implementations honor:
|
|
748
765
|
|
|
749
766
|
- `cwd` (required for path-based tools)
|
|
750
767
|
- The runtime context's `workspace` / `repoRoot` allow-list (paths outside both, plus `/tmp` and `process.cwd()`, are rejected)
|
|
751
768
|
- Output truncation with optional artifact persistence (`{toolArtifactDir}/tool-output/{runId}/...` when `toolArtifactDir` is configured)
|
|
752
769
|
|
|
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
|
|
770
|
+
`NodeRepl` uses Node's default `node:repl` evaluator, so variables, `_`, `_error`, and loaded modules persist across calls in the same run. It supports multiline input and top-level `await`, resolves workspace-installed packages, and is closed with the run. Its child is prepared through the same sandbox seam as `Exec`/`Bash` and communicates through token-authenticated, length-prefixed JSON frames on ordinary stdin/stdout; abort, the fixed 120-second timeout, child exit, or hard output overflow resets the session. It deliberately has no session ids, persistent history, terminal commands, or package-install surface.
|
|
771
|
+
|
|
772
|
+
`WebSearch` uses a configured loopback SearXNG endpoint and/or deterministic
|
|
773
|
+
public fallbacks that require no credentials. It canonicalizes and deduplicates
|
|
774
|
+
results, then fuses multiple query rankings. `WebFetch` extracts HTML, JSON,
|
|
775
|
+
feeds, PDFs, and text locally with
|
|
776
|
+
bounded redirects, bodies, headers, and retries. Config can opt into isolated
|
|
777
|
+
`agent-browser` rendering for sparse client-rendered HTML. One ephemeral
|
|
778
|
+
controller per run deduplicates identical calls and closes every browser
|
|
779
|
+
namespace at run end.
|
|
754
780
|
|
|
755
781
|
Pi runs with selected skills also expose `ReadSkill`. It returns the complete
|
|
756
782
|
skill instructions by default, including content beyond the former
|
|
@@ -794,8 +820,10 @@ import { createRouterRuntime } from "@mono-agent/agent-runtime";
|
|
|
794
820
|
const router = createRouterRuntime({
|
|
795
821
|
host: { /* same shape as createRuntime */ },
|
|
796
822
|
routeSafety: "per-route-native",
|
|
823
|
+
// Backoff shape for same-model retries; per-route counts live on `attempts`.
|
|
824
|
+
retry: { backoffMs: 1000, maxBackoffMs: 15000 },
|
|
797
825
|
chain: [
|
|
798
|
-
{ model: { sdk: "claude", model: "claude-sonnet-5" }, effort: "high" },
|
|
826
|
+
{ model: { sdk: "claude", model: "claude-sonnet-5" }, effort: "high", attempts: 2 },
|
|
799
827
|
{ model: { sdk: "codex", model: "gpt-5.6-sol" }, effort: "xhigh" },
|
|
800
828
|
{ model: { sdk: "pi", provider: "ollama", model: "gemma4:31b" }, effort: null },
|
|
801
829
|
],
|
|
@@ -808,8 +836,11 @@ console.log(result.failoverHistory, result.routeSafetyHistory);
|
|
|
808
836
|
Behaviour:
|
|
809
837
|
|
|
810
838
|
- Successful run on entry N → returns the result with `failoverHistory` set to attempts 0..N-1.
|
|
811
|
-
- Retryable provider failure → emits `provider_failover_started`, builds a transcript snapshot, and
|
|
812
|
-
-
|
|
839
|
+
- Retryable provider failure → retries the SAME entry while it has `attempts` left (emitting `provider_retry_started` after a doubling backoff), then emits `provider_failover_started`, builds a transcript snapshot, and advances to the next entry. `attempts` defaults to `1` per entry, so the kernel is single-shot unless a host opts in — `@mono-agent/config` supplies the product default of 2 on the primary.
|
|
840
|
+
- Same-model retries fire only for transient subkinds (`overloaded`, `rate_limited`, `timeout`, `network`, `server_error`, `retryable_request`, terminated streams). A retry drops the route's provider session, since the failed attempt already appended to it, and appends its own `failoverHistory` entry carrying `retryIndex`.
|
|
841
|
+
- A retry is *not* a failover: `provider_route_safety` and `provider_failover_started` are emitted once per entry, and `provider_failover_completed` only fires when a genuinely different model answered.
|
|
842
|
+
- This is a whole-logical-turn retry sitting strictly outside the provider bridges' own transport retries. On a `pi` route, `attempts: 2` combined with pi's default `maxRetries: 2` means up to six provider stream starts.
|
|
843
|
+
- Context-window failure after bridge compaction recovery → never retries the same entry (a second identical request against the same window is a guaranteed second failure); preserves `failureKind: "context_limit"` in `failoverHistory` and tries the next entry; quota/output/max-turn `usage_limit` remains terminal.
|
|
813
844
|
- Provider auth failure → retries the next chain entry and preserves `failureKind: "provider_auth"` in `failoverHistory` for the failed attempt.
|
|
814
845
|
- Malformed request/config/billing-type non-retryable failure → returns immediately with `failoverHistory` containing the one attempt.
|
|
815
846
|
- Cancellation → returns immediately.
|
|
@@ -825,7 +856,11 @@ Behaviour:
|
|
|
825
856
|
inputs, while request-scoped overrides remain on that exact run. A runtime
|
|
826
857
|
that cannot accept this projection fails closed as `safety_unavailable`.
|
|
827
858
|
- Attempt-resolver failures are sanitized to `safety_unavailable`; resolver
|
|
828
|
-
credentials/options never enter result telemetry
|
|
859
|
+
credentials/options never enter result telemetry, and they advance to the next
|
|
860
|
+
entry rather than consuming the route's remaining `attempts`.
|
|
861
|
+
- `resolveAttempt` runs once per attempt — including every same-model retry — and
|
|
862
|
+
receives `{ attemptIndex, retryIndex }`, where `attemptIndex` stays the chain
|
|
863
|
+
index. Its `cleanup` runs after each attempt.
|
|
829
864
|
|
|
830
865
|
Chain entries can require backend capabilities via `requires: { structured_output: true, supports_mcp: true, ... }`; entries that don't satisfy the requirements are skipped (logged in `failoverHistory` as `failureKind: "skipped_capability_mismatch"`).
|
|
831
866
|
|
|
@@ -1015,6 +1050,8 @@ runtime fails closed.
|
|
|
1015
1050
|
documents all five bridges and their execution modes.
|
|
1016
1051
|
- [Programmatic approvals and structured output](https://mono-agent-docs.vercel.app/programmatic/approval-and-structured-output/)
|
|
1017
1052
|
shows the code-only host hooks.
|
|
1053
|
+
- [Local-first web research](https://mono-agent-docs.vercel.app/tools/web-research/)
|
|
1054
|
+
documents SearXNG, extraction, retry, browser isolation, and sandbox policy.
|
|
1018
1055
|
- [Architecture](https://github.com/robertsreberski/mono-agent/blob/main/packages/agent-runtime/ARCHITECTURE.md)
|
|
1019
1056
|
and [migration guide](https://github.com/robertsreberski/mono-agent/blob/main/packages/agent-runtime/MIGRATION.md)
|
|
1020
1057
|
cover internal flow and upgrades from `0.3.x`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mono-agent/agent-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
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",
|
|
@@ -133,12 +133,16 @@
|
|
|
133
133
|
"dependencies": {
|
|
134
134
|
"@anthropic-ai/claude-agent-sdk": "0.3.206",
|
|
135
135
|
"@anthropic-ai/sdk": "^0.110.0",
|
|
136
|
-
"@earendil-works/pi-agent-core": "0.
|
|
137
|
-
"@earendil-works/pi-ai": "0.
|
|
136
|
+
"@earendil-works/pi-agent-core": "0.83.0",
|
|
137
|
+
"@earendil-works/pi-ai": "0.83.0",
|
|
138
138
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
139
|
+
"@mozilla/readability": "0.6.0",
|
|
139
140
|
"@opencode-ai/sdk": "^1.15.13",
|
|
140
141
|
"@vscode/ripgrep": "1.18.0",
|
|
141
142
|
"cross-spawn": "^7.0.6",
|
|
143
|
+
"defuddle": "0.19.2",
|
|
144
|
+
"linkedom": "0.18.13",
|
|
145
|
+
"unpdf": "1.8.0",
|
|
142
146
|
"zod": "^4.3.6"
|
|
143
147
|
},
|
|
144
148
|
"scripts": {
|