@mono-agent/agent-runtime 0.1.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.
Files changed (60) hide show
  1. package/ARCHITECTURE.md +219 -0
  2. package/LICENSE +674 -0
  3. package/README.md +430 -0
  4. package/package.json +46 -0
  5. package/src/agent/allowlists.js +49 -0
  6. package/src/agent/approval.js +211 -0
  7. package/src/agent/compaction.js +752 -0
  8. package/src/agent/index.js +40 -0
  9. package/src/agent/prompt/skill-index.js +66 -0
  10. package/src/agent/tool-bloat.js +164 -0
  11. package/src/agent/tools/bash.js +156 -0
  12. package/src/agent/tools/edit.js +15 -0
  13. package/src/agent/tools/glob.js +71 -0
  14. package/src/agent/tools/grep.js +84 -0
  15. package/src/agent/tools/index.js +17 -0
  16. package/src/agent/tools/pi-bridge.js +638 -0
  17. package/src/agent/tools/read.js +39 -0
  18. package/src/agent/tools/shared/constants.js +21 -0
  19. package/src/agent/tools/shared/dedup.js +31 -0
  20. package/src/agent/tools/shared/output-truncation.js +54 -0
  21. package/src/agent/tools/shared/path-resolver.js +156 -0
  22. package/src/agent/tools/shared/ripgrep.js +130 -0
  23. package/src/agent/tools/shared/runtime-context.js +69 -0
  24. package/src/agent/tools/web-fetch.js +59 -0
  25. package/src/agent/tools/web-search.js +21 -0
  26. package/src/agent/tools/write.js +14 -0
  27. package/src/agent/transcript.js +227 -0
  28. package/src/ai/backend.js +17 -0
  29. package/src/ai/cost.js +164 -0
  30. package/src/ai/failure.js +165 -0
  31. package/src/ai/file-change-stats.js +234 -0
  32. package/src/ai/index.js +16 -0
  33. package/src/ai/live-input-prompt.js +15 -0
  34. package/src/ai/observer.js +233 -0
  35. package/src/ai/providers/claude-cli.js +694 -0
  36. package/src/ai/providers/claude-sdk.js +864 -0
  37. package/src/ai/providers/claude-subagents.js +67 -0
  38. package/src/ai/providers/codex-app.js +1045 -0
  39. package/src/ai/providers/opencode-app.js +356 -0
  40. package/src/ai/providers/opencode-discovery.js +39 -0
  41. package/src/ai/providers/pi-events.js +62 -0
  42. package/src/ai/providers/pi-messages.js +68 -0
  43. package/src/ai/providers/pi-models.js +111 -0
  44. package/src/ai/providers/pi-sdk.js +1310 -0
  45. package/src/ai/registry.js +5 -0
  46. package/src/ai/runtime/capabilities-used.js +56 -0
  47. package/src/ai/runtime/capabilities.js +44 -0
  48. package/src/ai/runtime/context-windows.js +38 -0
  49. package/src/ai/runtime/fast-mode.js +8 -0
  50. package/src/ai/runtime/model-refs.js +144 -0
  51. package/src/ai/runtime/registry.js +57 -0
  52. package/src/ai/runtime/router.js +214 -0
  53. package/src/ai/runtime/sessions.js +126 -0
  54. package/src/ai/streaming/codex-events.js +139 -0
  55. package/src/ai/streaming/opencode-events.js +54 -0
  56. package/src/ai/types.js +70 -0
  57. package/src/index.js +23 -0
  58. package/src/pi-auth.js +80 -0
  59. package/src/runtime-brand.js +32 -0
  60. package/src/runtime.js +104 -0
@@ -0,0 +1,219 @@
1
+ # Agent Runtime Architecture
2
+
3
+ ## What It Is
4
+
5
+ `@mono-agent/agent-runtime` is a provider-agnostic agent execution
6
+ kernel. It does not own tasks, database state, UI, scheduling, or a host's
7
+ domain-specific result contract. It owns the lower-level act of running an
8
+ agent turn:
9
+
10
+ - pick the right backend from a model reference and execution mode
11
+ - expose built-in tools, MCP tools, approvals, structured output, and live input
12
+ - enforce optional sandbox policy for built-in tool execution and stdio MCP startup
13
+ - normalize provider events into one runtime event stream
14
+ - classify runtime failures and retryable provider errors
15
+ - collect usage, cost, cache, capability, and warning telemetry
16
+ - return raw text plus raw structured output to the host
17
+
18
+ Hosts consume the package through `src/runtime.js`.
19
+
20
+ ## Package Boundary
21
+
22
+ ```mermaid
23
+ flowchart TB
24
+ HostApp["Host app<br/>API / coordinator / worker / UI / DB"] --> CoreAI["host runtime composition"]
25
+
26
+ CoreAI --> Runtime["agent-runtime<br/>createRuntime() / createRouterRuntime()"]
27
+
28
+ Runtime --> Registry["Runtime bridge registry<br/>model ref + executionMode -> backend"]
29
+ Runtime --> AgentKernel["Agent kernel<br/>built-in tools, MCP, approvals,<br/>compaction, transcript snapshots"]
30
+ Runtime --> Observability["Observers + metrics<br/>usage, cost, events, warnings"]
31
+ Runtime --> Failure["Failure taxonomy<br/>retryable provider detection"]
32
+
33
+ Registry --> ClaudeSDK["Claude SDK bridge"]
34
+ Registry --> ClaudeCLI["Claude Code CLI bridge"]
35
+ Registry --> PiSDK["Pi SDK bridge<br/>OpenAI, Codex, Gemini, OpenRouter,<br/>Ollama, custom providers"]
36
+ Registry --> CodexApp["Codex app-server CLI bridge"]
37
+
38
+ AgentKernel --> Builtins["Read / Write / Edit / Glob / Grep / Bash<br/>WebFetch / WebSearch"]
39
+ AgentKernel --> MCP["MCP stdio / SSE / HTTP tools"]
40
+ AgentKernel --> Sandbox["Sandbox policy<br/>path/network checks + stdio command wrapping"]
41
+ AgentKernel --> Artifacts["Tool-output bloat guard<br/>host artifact persistence"]
42
+
43
+ ClaudeSDK --> Providers["External model/provider surfaces"]
44
+ ClaudeCLI --> Providers
45
+ PiSDK --> Providers
46
+ CodexApp --> Providers
47
+
48
+ Runtime --> Result["RuntimeResult<br/>text, structuredResult, events,<br/>usage, diagnostics, failureKind"]
49
+ Result --> CoreAI
50
+ CoreAI --> HostContract["Host parses domain contract<br/>assistant result / task effects"]
51
+ ```
52
+
53
+ The runtime stays below host domain behavior. Provider code in this package
54
+ must not import host DB, API, coordinator, or UI modules. Hosts pass callbacks
55
+ and pre-resolved settings into the runtime instead.
56
+
57
+ ## Runtime Selection
58
+
59
+ ```mermaid
60
+ flowchart LR
61
+ ModelRef["options.model<br/>claude:* / pi:*:* / codex:*"] --> Parse["parseRuntimeModelReference()"]
62
+ Parse --> Mode["options.executionMode<br/>sdk or cli"]
63
+ Mode --> Resolve["resolveRuntimeBridge()"]
64
+
65
+ Resolve -->|sdk=claude + sdk mode| ClaudeSDK["claude bridge<br/>@anthropic-ai/claude-agent-sdk"]
66
+ Resolve -->|sdk=claude + cli mode| ClaudeCLI["claude-code bridge<br/>claude binary"]
67
+ Resolve -->|sdk=pi| PiSDK["pi bridge<br/>@earendil-works/pi-agent-core"]
68
+ Resolve -->|sdk=codex + cli mode| CodexApp["codex-app bridge<br/>codex app-server"]
69
+
70
+ Resolve --> Caps["runtimeCapabilities()<br/>static backend features"]
71
+ Caps --> Used["capabilitiesUsed<br/>per-call observed features"]
72
+ ```
73
+
74
+ Canonical active model references are:
75
+
76
+ - `claude:<modelId>` for Claude SDK or Claude Code CLI, selected by
77
+ `executionMode`
78
+ - `pi:<providerId>:<modelName>` for Pi SDK providers
79
+ - `codex:<modelId>` for Codex app-server CLI
80
+
81
+ Legacy aliases are canonicalized at host ingress when needed. The strict parser
82
+ keeps the package boundary honest by rejecting reserved runtime IDs such as
83
+ `openai:*`, `vercel:*`, and `claude-code:*`.
84
+
85
+ ## Run Lifecycle
86
+
87
+ ```mermaid
88
+ sequenceDiagram
89
+ participant Host as Host app
90
+ participant Runtime as createRuntime()
91
+ participant Registry as Bridge registry
92
+ participant Bridge as Provider bridge
93
+ participant Kernel as Agent kernel
94
+ participant Provider as SDK / CLI / app-server
95
+ participant Observer as Observer hub
96
+
97
+ Host->>Runtime: run(systemPrompt, options)
98
+ Runtime->>Registry: resolveRuntimeBridge(model, executionMode)
99
+ Registry-->>Runtime: bridge.execute()
100
+ Runtime->>Observer: create hub from host + call observers
101
+ Runtime->>Bridge: execute(systemPrompt, normalized options)
102
+
103
+ Bridge->>Kernel: prepare tools, MCP, approvals, limits
104
+ Kernel-->>Bridge: provider-specific tool surface
105
+ Bridge->>Provider: send prompt, messages, tools, schema, settings
106
+
107
+ loop streaming events
108
+ Provider-->>Bridge: assistant/tool/result/provider events
109
+ Bridge->>Observer: normalized runtime events
110
+ Bridge->>Kernel: execute built-in/MCP tools as needed
111
+ Kernel-->>Bridge: tool results or tool errors
112
+ end
113
+
114
+ Bridge-->>Runtime: RuntimeResult
115
+ Runtime->>Observer: flush()
116
+ Runtime-->>Host: text, structuredResult, events, usage, diagnostics
117
+ Host->>Host: validate/parse host-specific contract
118
+ ```
119
+
120
+ The package forwards provider structured output as `structuredResult`, but it
121
+ does not validate that output against a host domain schema. Hosts own that
122
+ validation and any state-machine side effects.
123
+
124
+ ## Main Subsystems
125
+
126
+ ```mermaid
127
+ flowchart TB
128
+ Public["Public API<br/>src/index.js"] --> RuntimeFactory["runtime.js<br/>createRuntime()"]
129
+ Public --> Router["ai/runtime/router.js<br/>createRouterRuntime()"]
130
+ Public --> AIExports["ai/index.js<br/>model refs, registry, observers"]
131
+ Public --> AgentExports["agent/index.js<br/>allowlists, compaction,<br/>approvals, transcript"]
132
+
133
+ RuntimeFactory --> Registry["ai/runtime/registry.js"]
134
+ Registry --> Providers["ai/providers/*"]
135
+
136
+ Providers --> Claude["claude-sdk.js"]
137
+ Providers --> ClaudeCode["claude-cli.js"]
138
+ Providers --> Pi["pi-sdk.js<br/>pi-models/messages/events"]
139
+ Providers --> Codex["codex-app.js"]
140
+
141
+ AgentExports --> Tools["agent/tools/*"]
142
+ Tools --> ToolRuntime["shared/runtime-context.js<br/>workspace, repoRoot, rg, brand"]
143
+ Tools --> PiBridge["tools/pi-bridge.js<br/>built-ins + MCP adaptation"]
144
+
145
+ AgentExports --> Compaction["agent/compaction.js"]
146
+ AgentExports --> Transcript["agent/transcript.js"]
147
+ AgentExports --> Approval["agent/approval.js"]
148
+ AgentExports --> Bloat["agent/tool-bloat.js"]
149
+
150
+ AIExports --> Failure["ai/failure.js"]
151
+ AIExports --> Cost["ai/cost.js"]
152
+ AIExports --> Observer["ai/observer.js"]
153
+ AIExports --> Capabilities["ai/runtime/capabilities*.js"]
154
+ ```
155
+
156
+ Key responsibilities by subsystem:
157
+
158
+ - `runtime.js`: binds host callbacks once, configures tool runtime context, and
159
+ routes each call to the resolved bridge.
160
+ - `ai/runtime/registry.js`: maps model reference plus execution mode to one of
161
+ the built-in provider bridges.
162
+ - `ai/runtime/router.js`: retries across an ordered fallback chain on retryable
163
+ provider failures, carrying a transcript-tail resume snapshot forward.
164
+ - `ai/providers/*`: owns provider-specific request shapes, event conversion,
165
+ structured-output extraction, native subagent wiring, usage, and diagnostics.
166
+ - `agent/tools/*`: implements built-in tools, path/workdir guards, sandbox
167
+ policy checks, MCP tool adaptation, Playwright artifact routing, and output
168
+ limits.
169
+ - `agent/compaction.js`: estimates context pressure and compacts long agent
170
+ conversations for providers that support the package's compaction loop.
171
+ - `agent/transcript.js`: builds bounded resume snapshots from prior provider
172
+ events so a fallback or continuation can keep context.
173
+ - `agent/approval.js`: provides host-driven human-in-the-loop tool approval
174
+ gates where the backend supports runtime tool dispatch.
175
+ - `ai/failure.js`: normalizes spawn, usage-limit, provider, cancellation, and
176
+ retryability decisions into stable failure kinds.
177
+
178
+ ## Host Responsibilities
179
+
180
+ ```mermaid
181
+ flowchart LR
182
+ Host["Host app"] --> Pricing["resolveCustomPricing"]
183
+ Host --> Auth["resolvePiApiKey"]
184
+ Host --> Persist["persistArtifact"]
185
+ Host --> Compact["onCompactionRecorded"]
186
+ Host --> Approval["onToolApprovalRequest"]
187
+ Host --> Brand["runtimeBrand"]
188
+ Host --> Roots["workspace / repoRoot / ripgrepPath"]
189
+
190
+ Pricing --> Runtime["agent-runtime host callbacks"]
191
+ Auth --> Runtime
192
+ Persist --> Runtime
193
+ Compact --> Runtime
194
+ Approval --> Runtime
195
+ Brand --> Runtime
196
+ Roots --> Runtime
197
+
198
+ Runtime --> Raw["Raw runtime result"]
199
+ Raw --> Domain["Host-owned domain validation<br/>result contract, state machine,<br/>DB writes, UI surfaces"]
200
+ ```
201
+
202
+ The host is responsible for:
203
+
204
+ - resolving credentials and custom provider/model rows before provider calls
205
+ - choosing model references, execution mode, effort, fallback chains, and
206
+ runtime settings
207
+ - persisting artifacts, compaction rows, raw logs, run rows, and UI-facing state
208
+ - validating structured output against the host's domain contract
209
+ - converting runtime failures into product workflow behavior
210
+ - deciding when to retry, recover, continue, cancel, or ask for user input
211
+
212
+ ## Essential Takeaway
213
+
214
+ Think of `@mono-agent/agent-runtime` as the portable agent process engine
215
+ underneath a host app. The host decides what a task means, which agent should
216
+ run, how state changes, and how results are persisted. The runtime decides how
217
+ to talk to Claude, Pi, and Codex execution surfaces; how tools are exposed; how
218
+ provider failures are normalized; and how enough telemetry is returned for a
219
+ host to make reliable orchestration decisions.