@mono-agent/agent-runtime 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ARCHITECTURE.md CHANGED
@@ -166,8 +166,12 @@ Key responsibilities by subsystem:
166
166
  - `agent/tools/*`: implements built-in tools, path/workdir guards, sandbox
167
167
  policy checks, MCP tool adaptation, Playwright artifact routing, and output
168
168
  limits.
169
- - `agent/compaction.js`: estimates context pressure and compacts long agent
170
- conversations for providers that support the package's compaction loop.
169
+ - `agent/compaction.js`: two pure helpers consumed by the pi bridge —
170
+ `resolveAgentCompactionPolicy` (derives the context-window compaction trigger +
171
+ tool-output payload limits from `agent_compaction_*` settings and the running
172
+ model) and `isLikelyContextTermination` (classifies a context-pressure error).
173
+ The bridge drives compaction itself via `AgentHarness.compact()` (proactive +
174
+ reactive recovery); the legacy in-loop `transformContext` manager was removed.
171
175
  - `agent/transcript.js`: builds bounded resume snapshots from prior provider
172
176
  events so a fallback or continuation can keep context.
173
177
  - `agent/approval.js`: provides host-driven human-in-the-loop tool approval
@@ -204,11 +208,52 @@ The host is responsible for:
204
208
  - resolving credentials and custom provider/model rows before provider calls
205
209
  - choosing model references, execution mode, effort, fallback chains, and
206
210
  runtime settings
207
- - persisting artifacts, compaction rows, raw logs, run rows, and UI-facing state
211
+ - persisting artifacts, raw logs, run rows, and UI-facing state (the legacy
212
+ compaction-row hook is inert on the current pi bridge)
208
213
  - validating structured output against the host's domain contract
209
214
  - converting runtime failures into product workflow behavior
210
215
  - deciding when to retry, recover, continue, cancel, or ask for user input
211
216
 
217
+ ## Sessions, Follow-ups & Concurrency
218
+
219
+ When `runtime.session.mode = "continuous"`, the harness keeps a conversation's
220
+ provider session warm and serializes its turns through a per-conversation queue
221
+ (`@mono-agent/agent-harness` `LiveSessionManager`). A message that arrives while
222
+ a turn is in flight is **queued and answered on the warm session after the
223
+ current turn finishes** (queue-after-turn) rather than rejected — this is what
224
+ powers follow-up messages in chat channels. Different conversations run
225
+ concurrently; an optional `concurrency.maxConcurrentRuns` bounds simultaneous
226
+ model runs via admission control around the provider call (queued follow-ups
227
+ hold no slot, so the bound never deadlocks against the queue). Note this bound is
228
+ **per harness instance** — the app builds one harness per channel, so the limiter
229
+ is per-channel, not a single global cap; with N enabled channels the effective
230
+ ceiling is N× the configured value. Channels surface
231
+ a user cancel through `responder.cancel(conversationId)`, which aborts the
232
+ in-flight turn and clears that conversation's queue.
233
+
234
+ **Honest per-provider session behavior** — parity is *behavioral* (every
235
+ provider exposes queue-after-turn), not durability/cost:
236
+
237
+ The pi runtime is built on pi-agent-core's native `AgentHarness` (the hand-rolled
238
+ bridge was removed once native reached parity); it owns the session and
239
+ pi-ai-managed retry, and context/window handling is delegated to the harness.
240
+ There is **no** automatic in-loop summarization pass driven by this package, so
241
+ runs report `context_compaction_applied: null` (unknown/unsupported) rather than
242
+ asserting compaction ran.
243
+
244
+ | Provider | Warm session | Resume across turns | Survives process restart |
245
+ |---|---|---|---|
246
+ | **pi** | Yes (pi `AgentHarness` + JSONL session repo) | session repo | **Yes** (only one) |
247
+ | **claude-sdk** | No persistent process (stream closes at turn end) | `queryOptions.resume` | No (Anthropic-side id) |
248
+ | **claude-cli** | No — respawns `claude --resume` per turn (re-inits MCP) | `--resume` replay | No |
249
+ | **codex-app** | Live subprocess thread (dies with the subprocess) | next turn on the thread, else replay | No |
250
+
251
+ claude-cli and codex only *approximate* a warm session (resume/replay), so do
252
+ not assume warm-session latency wins there. Recall (memory embeddings) is bounded
253
+ by a timeout + circuit breaker and degrades to empty (with a `memory_degraded`
254
+ warning) rather than blocking or failing a turn; selected skills are mtime-cached
255
+ across turns.
256
+
212
257
  ## Essential Takeaway
213
258
 
214
259
  Think of `@mono-agent/agent-runtime` as the portable agent process engine
package/MIGRATION.md ADDED
@@ -0,0 +1,115 @@
1
+ # `@mono-agent/agent-runtime` — Migration Guide
2
+
3
+ Breaking and behavioral changes for consumers upgrading **from `0.3.x`** (the
4
+ `feat/runtime-live-sessions` line). The public entry points are unchanged —
5
+ `createRuntime` / `createMonoRuntime`, the run-options contract, and provider
6
+ session support (`sessionId` in, `provider_session_id` out, `disposeSession` /
7
+ `disposeAllSessions`) all keep their shapes. The changes below affect the **Pi
8
+ runtime bridge, a few run options, durable-session semantics, the fallback
9
+ router, and some diagnostics**.
10
+
11
+ If you only use the Claude SDK / Claude CLI / Codex backends and do not touch Pi
12
+ or durable sessions, this is a no-op upgrade.
13
+
14
+ ---
15
+
16
+ ## 1. Pi is now native-only (`pi-sdk.js` → `pi-native.js`)
17
+
18
+ The hand-rolled Pi bridge that drove the low-level `Agent` was replaced by a
19
+ bridge built on `@earendil-works/pi-agent-core`'s high-level `AgentHarness`. The
20
+ registry resolves `pi` → the native bridge unconditionally; there is no
21
+ `piEngine` flag.
22
+
23
+ - **Public runtime API** (`createRuntime`, model reference `"pi:<provider>:<model>"`)
24
+ is unchanged — `pi:openai:gpt-5.5` etc. still work.
25
+ - **Deep imports** of `@mono-agent/agent-runtime/ai/providers/pi-sdk.js` still
26
+ resolve via a **deprecated compatibility shim** that re-exports the native
27
+ equivalents (`generatePiResponse` → `generatePiNativeResponse`,
28
+ `piRuntimeBridge` → `piNativeRuntimeBridge`, `isContextLimitError`,
29
+ `normalizePiErrorMessage`, and the `pi*Backend` symbols). **Action:** migrate
30
+ deep imports to `./ai/providers/pi-native.js`; the shim may be removed in a
31
+ future major.
32
+
33
+ ## 2. Removed run options: `piReasoningSummary`, `piCodexTransport`
34
+
35
+ These were Pi-bridge knobs the native path does not consume.
36
+
37
+ - `piReasoningSummary` is **no longer read** and was removed from the run-options
38
+ type. Pi-native derives reasoning from `effort` (`thinkingLevel`); the
39
+ codex/claude CLIs emit reasoning summaries on their own. **Action:** stop
40
+ passing `piReasoningSummary` — it was already a no-op on the native path; remove
41
+ it from your call sites. (Host config `runtime.reasoningSummary` still validates
42
+ for back-compat but is not wired to a runtime option.)
43
+ - `piCodexTransport` was doc-only and is removed. No replacement is needed.
44
+
45
+ ## 3. Pi context compaction: bridge-driven via AgentHarness.compact()
46
+
47
+ `AgentHarness` has no automatic compaction, so the pi bridge drives it directly
48
+ (the legacy low-level `transformContext` / `afterToolCall` hooks and
49
+ `createAgentCompactionManager` were removed):
50
+
51
+ - Before each turn the bridge estimates the running model's context usage and
52
+ calls `AgentHarness.compact()` when near the window (proactive). If a turn still
53
+ overflows the bridge compacts once and re-prompts (reactive recovery).
54
+ - Runs report **`capabilitiesUsed.context_compaction_applied`** as `true` (a
55
+ compaction fired), `false` (enabled but not needed), or `null` (disabled via
56
+ `agent_compaction_enabled: false`). If you assert on this value, expect this
57
+ tristate on the Pi path.
58
+ - The host **`onCompactionRecorded`** callback now **fires on each automatic
59
+ compaction** on the Pi path (previously inert).
60
+ - The trigger window auto-tracks the model actually serving the request
61
+ (`harness.getModel()`) and self-corrects from any real ceiling stated in an
62
+ overflow error, so a wrong/default `context_window` no longer defeats it.
63
+ `resolveAgentCompactionPolicy` (`agent_compaction_*` settings) remains exported.
64
+
65
+ ## 4. Durable Pi session resume: create-on-miss semantics
66
+
67
+ When a run supplies a `sessionId` **and** durable storage is configured
68
+ (`piSessionsRoot`), Pi-native now **creates the session with that id if no
69
+ on-disk JSONL exists** (create-on-miss), instead of returning
70
+ `session_not_found`. An existing JSONL is reopened and resumed as before.
71
+
72
+ This makes a **stable, conversation-derived session id resume across process
73
+ restarts** (the on-disk transcript is the durable history; the in-memory
74
+ conversation→session map is no longer required to resume). **Action:** if you
75
+ passed an arbitrary `sessionId` to a durable run expecting a hard
76
+ `session_not_found` on first use, note it now succeeds by creating that session.
77
+ The in-memory (non-durable) resume path still fast-fails `session_not_found` on a
78
+ miss.
79
+
80
+ ## 5. Fallback router enforces requested native-subagent capability
81
+
82
+ Pi advertises `supports_native_subagents: false`. The fallback router now infers
83
+ a `supports_native_subagents` requirement when a run passes
84
+ `options.nativeSubagents.teammates` (non-empty), the same way it already infers
85
+ `structured_output` from `outputSchema`. A chain entry that cannot satisfy it
86
+ (e.g. a Pi fallback behind a Claude primary that was handed native teammates) is
87
+ **skipped** (`skipped_capability_mismatch`) rather than silently succeeding with
88
+ `nativeSubagentsUsed: []`. **Action:** if you configure fallback chains for
89
+ native-subagent runs, ensure at least one entry supports native subagents, or the
90
+ run reports exhausted instead of degrading silently.
91
+
92
+ ## 6. Diagnostics & internal behavior changes (no API change)
93
+
94
+ - **Pi multimodal**: image inputs are delivered to the model as image content
95
+ blocks (internal fix; affects behavior, not the call shape).
96
+ - **Tool-output limits**: settings-driven clamps (`agent_tool_text_limit_chars`,
97
+ `agent_search_result_limit`, `toolPayloadMaxBytes`, …) are honored again on the
98
+ Pi path (built-ins + MCP). The 256 KB tool-payload ceiling is unchanged.
99
+ - **WebFetch** retries transient network errors (timeout / ECONNRESET / 5xx)
100
+ in-tool with backoff before returning an error.
101
+ - **Claude CLI**: the temporary `mcp.json` written for a CLI run is now created
102
+ with `0600` (owner-only) permissions.
103
+ - Pi session lifecycle is hardened: aborts during setup are honored before the
104
+ provider call, fresh durable sessions are deleted on setup/abort failure, and
105
+ resumed sessions roll back to their pre-turn leaf on host-side (outer-catch)
106
+ failures. These are correctness fixes with no API surface change.
107
+
108
+ ---
109
+
110
+ ## Version
111
+
112
+ These changes ship in the first `agent-runtime` release after `0.3.0` on the
113
+ `feat/runtime-live-sessions` line (a minor/major bump; see the release tag). The
114
+ paired `@mono-agent/runtime-adapter` drops the `piReasoningSummary` field from its
115
+ run-options type in lockstep.
package/README.md CHANGED
@@ -42,10 +42,12 @@ Generic agent runtime that supports four backends out of the box:
42
42
  - **Pi SDK** (`@earendil-works/pi-agent-core`, used for OpenAI / Codex / Gemini / OpenRouter / Ollama / etc. via Pi providers)
43
43
  - **Codex CLI** (the `codex` app-server)
44
44
 
45
- Hosts wire in their own pricing, persistence, credential, and compaction-recording callbacks. The runtime returns raw text + raw structured output; hosts that want a domain-specific contract parse it on their end.
45
+ Hosts wire in their own pricing, persistence, and credential callbacks (plus a legacy compaction-recording hook that is inert on the current pi bridge — see "Context compaction"). The runtime returns raw text + raw structured output; hosts that want a domain-specific contract parse it on their end.
46
46
 
47
47
  See [ARCHITECTURE.md](./ARCHITECTURE.md) for the package boundary, runtime
48
- selection flow, lifecycle diagrams, and host responsibilities.
48
+ selection flow, lifecycle diagrams, and host responsibilities. Upgrading from
49
+ `0.3.x`? See [MIGRATION.md](./MIGRATION.md) for the Pi-native bridge, removed run
50
+ options, durable-session resume semantics, and fallback-router changes.
49
51
 
50
52
  ## Install / Usage
51
53
 
@@ -89,7 +91,7 @@ console.log(result.text);
89
91
  `@mono-agent/agent-runtime` is purpose-built for **autonomous, long-running agent work** with provider portability and operational resilience as first-class concerns. It is *not* a streaming-chat UI kit. Where each peer fits:
90
92
 
91
93
  - **Vercel AI SDK** — best when you're building a chat / generative-UI experience inside a React or Next.js app. `useChat`, `useCompletion`, streaming server components, and edge-runtime compatibility are their strengths. Their provider list is curated (Anthropic, OpenAI, Google, etc., via `@ai-sdk/*` packages); there's no Pi gateway, no Claude Code CLI, no Codex CLI app-server, and no per-call provider fallback. If you're rendering a streaming chat into a browser, use them. If you're orchestrating multi-turn autonomous work that must survive a rate-limited primary provider, use us.
92
- - **Claude Agent SDK** (`@anthropic-ai/claude-agent-sdk`) — first-party Anthropic SDK. Tight integration with Claude features (canUseTool, sub-agents, hooks, MCP). We *wrap* it as one of our four backends and add context compaction, transcript-resume across provider drops, a 22-kind failure taxonomy, a tool-bloat guard with artifact persistence, and a provider fallback router. Reach for the bare Anthropic SDK when you only ever talk to Claude and don't need cross-provider portability or resume.
94
+ - **Claude Agent SDK** (`@anthropic-ai/claude-agent-sdk`) — first-party Anthropic SDK. Tight integration with Claude features (canUseTool, sub-agents, hooks, MCP). We *wrap* it as one of our four backends and add transcript-resume across provider drops, a 22-kind failure taxonomy, a tool-bloat guard with artifact persistence, and a provider fallback router. Context/window handling stays with the provider — the runtime does not run its own in-loop summarization pass. Reach for the bare Anthropic SDK when you only ever talk to Claude and don't need cross-provider portability or resume.
93
95
  - **Mastra** — a workflow engine + memory + RAG stack. Different category: it's the layer *above* a runtime. You can layer Mastra workflows on top of `@mono-agent/agent-runtime` if you want both.
94
96
  - **OpenAI Agents SDK** — first-party OpenAI SDK. Same trade-off as the Claude Agent SDK: tight integration with OpenAI, no other providers. Pi providers in our runtime cover OpenAI plus a dozen others through a single API.
95
97
  - **LangChain.js** — kitchen sink with deep abstraction stacks. We're deliberately lean; if you want chains, agents, vector stores, and parsers under one umbrella, LangChain is built for that. If you want a focused runtime kernel, use us.
@@ -109,7 +111,7 @@ console.log(result.text);
109
111
  | Multi-provider portability | ✓ (4 backends, 15+ providers) | partial | ✗ |
110
112
  | CLI providers (claude/codex binaries) | ✓ | ✗ | ✗ |
111
113
  | Provider fallback on rate limit / overload | ✓ (`createRouterRuntime`) | ✗ | ✗ |
112
- | Aggressive context compaction with summarization | ✓ | | partial |
114
+ | Context handling delegated to the provider (no host auto-summarization) | ✓ | | |
113
115
  | Transcript-tail resume after provider drops | ✓ | ✗ | ✗ |
114
116
  | Tool-output bloat guard + artifact persistence | ✓ | ✗ | ✗ |
115
117
  | MCP transports out of the box (stdio/SSE/HTTP) | ✓ | partial | ✓ |
@@ -142,7 +144,9 @@ createRuntime({
142
144
  resolveCustomPricing, // (parsed) => NormalizedPricing | null
143
145
  resolvePiApiKey, // async (provider) => string | undefined
144
146
  persistArtifact, // ({ filename, buffer, toolName, toolUseId }) => path | null
145
- onCompactionRecorded, // (compactionRow) => void
147
+ onCompactionRecorded, // (compactionRow) => void — fired when the pi bridge
148
+ // runs an automatic compaction (proactive or reactive
149
+ // recovery) via AgentHarness.compact()
146
150
 
147
151
  // -- tool runtime context (process-level config for the tool kernel) --
148
152
  workspace, // primary allowed root for path-based tools
@@ -228,7 +232,6 @@ Per-call options (a non-exhaustive selection):
228
232
  | `runId` | `string` | Tag this run for downstream callbacks (e.g. `onCompactionRecorded`). |
229
233
  | `providerSessionId` | `string` | Resume a prior provider session. |
230
234
  | `runArtifactDir` | `string` | Used by some providers as the Playwright MCP filename target. |
231
- | `piCodexTransport` | `string` | Forwarded to Pi when running OpenAI Codex models. |
232
235
  | `codexAppServerCommand` | `string` | Override the Codex CLI binary. |
233
236
  | `codexAppServerArgs` | `string[]` | Override the Codex CLI arguments. |
234
237
 
@@ -405,7 +408,20 @@ Hosts that don't supply `persistArtifact` get the truncation summary but no on-d
405
408
 
406
409
  ## Context compaction
407
410
 
408
- `@mono-agent/agent-runtime/agent/compaction.js` provides `createAgentCompactionManager(...)` which the Pi SDK provider invokes automatically. Configure via the agent's settings (`agent_compaction_*` keys). When a compaction completes, the kernel hands a structured row to your `onCompactionRecorded(record)` callback so the host can persist it however it likes.
411
+ The sole pi bridge runs on pi-agent-core's native `AgentHarness`. pi performs **no**
412
+ automatic in-loop compaction, so the bridge drives it: before each turn it estimates the
413
+ running model's context usage and calls `AgentHarness.compact()` when near the window
414
+ (proactive), and if a turn still overflows it compacts once and re-prompts (reactive
415
+ recovery). The context window auto-tracks the model actually serving the request
416
+ (`harness.getModel()`), self-correcting from any real ceiling stated in an overflow error.
417
+ Runs report `context_compaction_applied: true` (fired), `false` (enabled but not needed),
418
+ or `null` (disabled). The other backends manage their windows per their own behavior.
419
+ (`docs/feature-registry.md` is the source of truth for this row.)
420
+
421
+ `resolveAgentCompactionPolicy(...)` (the `agent_compaction_*` settings: trigger ratio,
422
+ keep-recent, enable/disable) and the `onCompactionRecorded(record)` host callback (fired
423
+ on each automatic compaction) are exported from
424
+ `@mono-agent/agent-runtime/agent/compaction.js` and consumed by the pi bridge.
409
425
 
410
426
  ## Advanced exports
411
427
 
@@ -414,7 +430,7 @@ The package exposes its inner pieces via subpath imports:
414
430
  ```js
415
431
  import { resolveRuntimeBridge, listRuntimeBridges, runtimeCapabilities } from "@mono-agent/agent-runtime/ai/runtime/registry.js";
416
432
  import { generateClaudeResponse } from "@mono-agent/agent-runtime/ai/providers/claude-sdk.js";
417
- import { createAgentCompactionManager, estimateFirstTurnInput } from "@mono-agent/agent-runtime/agent/compaction.js";
433
+ import { resolveAgentCompactionPolicy, isLikelyContextTermination } from "@mono-agent/agent-runtime/agent/compaction.js";
418
434
  import { configureToolRuntime, readToolRuntime } from "@mono-agent/agent-runtime/agent/tools/shared/runtime-context.js";
419
435
  // ...
420
436
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mono-agent/agent-runtime",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "description": "Agent runtime supporting Claude SDK, Claude CLI, Codex CLI, and PI SDK out of the box",
5
5
  "type": "module",
6
6
  "license": "GPL-3.0-only",
@@ -25,6 +25,7 @@
25
25
  "src/**/*.js",
26
26
  "!src/__tests__/**",
27
27
  "ARCHITECTURE.md",
28
+ "MIGRATION.md",
28
29
  "README.md",
29
30
  "LICENSE"
30
31
  ],
@@ -35,7 +36,7 @@
35
36
  "@anthropic-ai/claude-agent-sdk": "^0.1.0",
36
37
  "@earendil-works/pi-agent-core": "^0.79.1",
37
38
  "@earendil-works/pi-ai": "^0.79.1",
38
- "@mono-agent/sandbox": "0.2.2",
39
+ "@mono-agent/sandbox": "0.4.0",
39
40
  "@modelcontextprotocol/sdk": "^1.12.0",
40
41
  "@opencode-ai/sdk": "^1.15.13",
41
42
  "zod": "^4.3.6"