@tangle-network/agent-runtime 0.197.1 → 0.198.2

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 (103) hide show
  1. package/README.md +1 -2
  2. package/dist/{improve-DZs0KXhK.d.ts → activation-DFRTurvU.d.ts} +99 -5
  3. package/dist/{activation-BxMZybuo.js → activation-IBEVN3VI.js} +2 -2
  4. package/dist/{activation-BxMZybuo.js.map → activation-IBEVN3VI.js.map} +1 -1
  5. package/dist/agent.d.ts +1 -1
  6. package/dist/agent.js +2 -2
  7. package/dist/candidate-execution/index.d.ts +370 -2
  8. package/dist/candidate-execution/index.js +828 -4
  9. package/dist/candidate-execution/index.js.map +1 -0
  10. package/dist/{coordination-driver-zkCrfEbS.js → coordination-driver-NFvZ5ofi.js} +57 -26
  11. package/dist/coordination-driver-NFvZ5ofi.js.map +1 -0
  12. package/dist/{delegate-DHeUYU5E.js → delegate-dN5yooEj.js} +2 -2
  13. package/dist/{delegate-DHeUYU5E.js.map → delegate-dN5yooEj.js.map} +1 -1
  14. package/dist/durable.d.ts +2 -2
  15. package/dist/durable.js +4 -5
  16. package/dist/durable.js.map +1 -1
  17. package/dist/{graph-51SJOEcw.js → graph-CgCVtMuz.js} +3 -3
  18. package/dist/{graph-51SJOEcw.js.map → graph-CgCVtMuz.js.map} +1 -1
  19. package/dist/{improvement-cycle-Tw5nYT5R.js → improvement-cycle-Cfu6kDOs.js} +8 -10
  20. package/dist/{improvement-cycle-Tw5nYT5R.js.map → improvement-cycle-Cfu6kDOs.js.map} +1 -1
  21. package/dist/{index-CYOJsxSg.d.ts → index-CMTUgh-T.d.ts} +9 -11
  22. package/dist/index.d.ts +694 -16
  23. package/dist/index.js +1780 -17
  24. package/dist/index.js.map +1 -1
  25. package/dist/intelligence.d.ts +3 -7
  26. package/dist/intelligence.js +5 -6
  27. package/dist/intelligence.js.map +1 -1
  28. package/dist/kernel.d.ts +2 -5
  29. package/dist/kernel.js +8 -10
  30. package/dist/{loop-runner-bin-DwrSB04m.d.ts → loop-runner-bin-CAf1OQot.d.ts} +3 -3
  31. package/dist/{loop-runner-bin-2LQSjRTB.js → loop-runner-bin-WQniYJ8C.js} +3 -3
  32. package/dist/{loop-runner-bin-2LQSjRTB.js.map → loop-runner-bin-WQniYJ8C.js.map} +1 -1
  33. package/dist/loop-runner-bin.d.ts +1 -1
  34. package/dist/loop-runner-bin.js +1 -1
  35. package/dist/mcp/bin.js +3 -3
  36. package/dist/mcp/index.d.ts +2 -3
  37. package/dist/mcp/index.js +4 -5
  38. package/dist/mcp/index.js.map +1 -1
  39. package/dist/{prepare-DDGp0-rW.js → prepare-CAO1yXov.js} +2407 -2407
  40. package/dist/prepare-CAO1yXov.js.map +1 -0
  41. package/dist/{protected-model-port-DxFN8DLS.js → protected-model-port-B5avcRiQ.js} +2 -2
  42. package/dist/{protected-model-port-DxFN8DLS.js.map → protected-model-port-B5avcRiQ.js.map} +1 -1
  43. package/dist/{provision-supervisor-CpMMShE_.js → provision-supervisor-BxsIaJ35.js} +3 -6
  44. package/dist/{provision-supervisor-CpMMShE_.js.map → provision-supervisor-BxsIaJ35.js.map} +1 -1
  45. package/dist/{redact-Cbl2O-4N.js → redact-DqfB7oB4.js} +5233 -2526
  46. package/dist/redact-DqfB7oB4.js.map +1 -0
  47. package/dist/{runtime-BSFz2z7h.js → runtime-CHEtvaTY.js} +427 -23
  48. package/dist/runtime-CHEtvaTY.js.map +1 -0
  49. package/dist/{server-COXa19sp.js → server-ccGua5tH.js} +4 -4
  50. package/dist/{server-COXa19sp.js.map → server-ccGua5tH.js.map} +1 -1
  51. package/dist/{types-DFLZMaeh.d.ts → stream-agent-turn-CLOQr497.d.ts} +1986 -6
  52. package/dist/{structural-rollout-DPbZWgEm.js → structural-rollout-BmDuXyR9.js} +1101 -8
  53. package/dist/structural-rollout-BmDuXyR9.js.map +1 -0
  54. package/dist/{supervise-b93YUaka.js → supervise-DVt8-TI-.js} +9 -5
  55. package/dist/supervise-DVt8-TI-.js.map +1 -0
  56. package/dist/testing.d.ts +2 -2
  57. package/dist/testing.js +13 -13
  58. package/dist/tui/index.d.ts +1 -1
  59. package/dist/tui/index.js +1 -1
  60. package/dist/{workspace-archive-Ybomp7AN.js → workspace-archive-BMOnloFf.js} +3 -3
  61. package/dist/{workspace-archive-Ybomp7AN.js.map → workspace-archive-BMOnloFf.js.map} +1 -1
  62. package/package.json +1 -28
  63. package/dist/activation-DyWB0K6E.d.ts +0 -98
  64. package/dist/authored-code-URmkdgjv.js +0 -37
  65. package/dist/authored-code-URmkdgjv.js.map +0 -1
  66. package/dist/candidate-execution-nvqVIMyS.js +0 -829
  67. package/dist/candidate-execution-nvqVIMyS.js.map +0 -1
  68. package/dist/conversation-BxJ0SIBM.js +0 -1363
  69. package/dist/conversation-BxJ0SIBM.js.map +0 -1
  70. package/dist/conversation.d.ts +0 -2
  71. package/dist/conversation.js +0 -2
  72. package/dist/coordination-driver-zkCrfEbS.js.map +0 -1
  73. package/dist/environment-provider-1fKZh2zl.js +0 -2281
  74. package/dist/environment-provider-1fKZh2zl.js.map +0 -1
  75. package/dist/environment-provider-B-I2jlQy.d.ts +0 -143
  76. package/dist/environment-provider.d.ts +0 -2
  77. package/dist/environment-provider.js +0 -2
  78. package/dist/graph.d.ts +0 -753
  79. package/dist/graph.js +0 -2111
  80. package/dist/graph.js.map +0 -1
  81. package/dist/index-CUosKU4N.d.ts +0 -372
  82. package/dist/index-D9mb6fn2.d.ts +0 -691
  83. package/dist/index-ZnxSe6iK.d.ts +0 -138
  84. package/dist/jsonl-file-BEpaEYjT.js +0 -141
  85. package/dist/jsonl-file-BEpaEYjT.js.map +0 -1
  86. package/dist/knowledge-B_MsOtDG.js +0 -428
  87. package/dist/knowledge-B_MsOtDG.js.map +0 -1
  88. package/dist/knowledge.d.ts +0 -2
  89. package/dist/knowledge.js +0 -2
  90. package/dist/materialization-Cy0oM8tb.js +0 -672
  91. package/dist/materialization-Cy0oM8tb.js.map +0 -1
  92. package/dist/prepare-DDGp0-rW.js.map +0 -1
  93. package/dist/primeintellect/index.d.ts +0 -218
  94. package/dist/primeintellect/index.js +0 -739
  95. package/dist/primeintellect/index.js.map +0 -1
  96. package/dist/redact-Cbl2O-4N.js.map +0 -1
  97. package/dist/runtime-0xNaV6TJ.d.ts +0 -1699
  98. package/dist/runtime-BSFz2z7h.js.map +0 -1
  99. package/dist/stream-agent-turn-Dt5mZpc3.js +0 -1103
  100. package/dist/stream-agent-turn-Dt5mZpc3.js.map +0 -1
  101. package/dist/stream-agent-turn-urHpmO_Z.d.ts +0 -160
  102. package/dist/structural-rollout-DPbZWgEm.js.map +0 -1
  103. package/dist/supervise-b93YUaka.js.map +0 -1
@@ -1,1699 +0,0 @@
1
- import { E as SandboxClient, at as RuntimeStreamEvent, i as ExecCtx, k as Validator } from "./types-Q0PMagdm.js";
2
- import { B as Scope, _ as ExecutorRegistry, _n as TraceSource, a as DefaultVerdict, b as ExecutorToolCall, g as ExecutorProgressEvent, it as UsageEvent, l as ExecutorCancellation, p as ExecutorFactory, q as Spend, u as ExecutorCancellationRequest, wn as ExecutorProgress } from "./types-DFLZMaeh.js";
3
- import { i as AgentEnvironmentProvider, o as AgentEnvironmentProviderRegistry, w as ProviderExecutorOptions } from "./environment-provider-B-I2jlQy.js";
4
- import { AgentProfile, AgentProfileMcpServer, HarnessType, ReasoningEffort, StreamEvent } from "@tangle-network/agent-interface";
5
- import { WorkspacePlanReceipt } from "@tangle-network/agent-profile-materialize";
6
- import { ChildProcess } from "node:child_process";
7
- import { AgentRunOutcome } from "@tangle-network/sandbox/runtime";
8
- import { BackendType, SandboxEvent } from "@tangle-network/sandbox";
9
- //#region src/mcp/protocol.d.ts
10
- /**
11
- * Shared wire contracts for the in-process stdio MCP servers.
12
- *
13
- * Keeping these types in one module prevents the delegation and generic tool
14
- * servers from accepting subtly different JSON-RPC messages.
15
- *
16
- * @experimental
17
- */
18
- /** A callable MCP tool exposed by either stdio server. @experimental */
19
- interface McpToolDescriptor {
20
- name: string;
21
- description: string;
22
- inputSchema: Record<string, unknown>;
23
- handler: (raw: unknown) => Promise<unknown>;
24
- }
25
- /** Stdio-shaped transport used by the shared JSON-RPC server implementation. @experimental */
26
- interface McpTransport {
27
- input: NodeJS.ReadableStream;
28
- output: NodeJS.WritableStream;
29
- }
30
- /** One JSON-RPC 2.0 request or notification. @experimental */
31
- interface JsonRpcMessage {
32
- jsonrpc: '2.0';
33
- id?: number | string | null;
34
- method: string;
35
- params?: unknown;
36
- }
37
- /** One JSON-RPC 2.0 response. @experimental */
38
- interface JsonRpcResponse {
39
- jsonrpc: '2.0';
40
- id: number | string | null;
41
- result?: unknown;
42
- error?: {
43
- code: number;
44
- message: string;
45
- data?: unknown;
46
- };
47
- }
48
- //#endregion
49
- //#region src/runtime/supervise/peer-mail.d.ts
50
- /**
51
- * What one envelope IS, typed so a reader can act on it without parsing prose.
52
- *
53
- * - `ask` — request a fact the sender lacks; expects an `answer`.
54
- * - `tell` — share a result; MUST carry evidence refs.
55
- * - `challenge` — dispute a peer's claim; MUST cite the refs of the claim it disputes.
56
- * - `answer` — reply to an `ask` or a `challenge`.
57
- */
58
- type PeerMailKind = 'ask' | 'tell' | 'challenge' | 'answer';
59
- /** One admitted peer message. `threadId` is the root mail's id; `depth` is 0 for a root mail and
60
- * one more than its parent for a reply, which is what the reply-depth cap counts. */
61
- interface PeerMailEnvelope {
62
- readonly mailId: string;
63
- readonly threadId: string;
64
- readonly depth: number;
65
- /** The bound sender — resolved from the capability, never from a tool argument. */
66
- readonly from: string;
67
- readonly to: string;
68
- readonly kind: PeerMailKind;
69
- readonly subject: string;
70
- readonly body: string;
71
- /** Evidence the receiver can re-check for itself. Required for `tell` and `challenge`. */
72
- readonly evidenceRefs: ReadonlyArray<string>;
73
- /** The mail id this replies to. Never a coordination question id — a peer cannot address the
74
- * parent's answer channel. */
75
- readonly replyTo?: string;
76
- readonly at: number;
77
- }
78
- /** Why an attempt did not reach a sibling. Each value is a fact the sender can read and act on. */
79
- type PeerMailRefusal = 'sender-unbound' | 'self-addressed' | 'send-quota-exhausted' | 'mailbox-full' | 'thread-depth-exceeded' | 'thread-stopped' | 'unknown-reply-target' | 'evidence-required' | 'subject-too-large' | 'body-too-large' | 'forged-authority' | 'unknown-worker' | 'already-settled' | 'worker-has-no-inbox' | 'scope-stopped' | 'runtime-error';
80
- type PeerMailOutcome = 'delivered' | PeerMailRefusal;
81
- /** The audit record for one attempt — published whether it delivered or was refused, because a
82
- * refused attempt is exactly what a parent auditing a channel needs to see. */
83
- interface PeerMailEvent {
84
- readonly envelope: PeerMailEnvelope;
85
- readonly delivered: boolean;
86
- readonly outcome: PeerMailOutcome;
87
- /** Canonical digest of the exact admitted body, so a later claim can name the bytes it read. */
88
- readonly bodyDigest: string;
89
- readonly error?: string;
90
- }
91
- /** Hard bounds. Every one fails closed with a refusal the sender can read. */
92
- interface PeerMailLimits {
93
- /** Mail one worker may attempt to send for the whole run. */
94
- readonly maxSentPerWorker: number;
95
- /** Mail one worker may receive for the whole run. */
96
- readonly maxInboxPerWorker: number;
97
- /** Total admitted body bytes one worker may receive for the whole run. */
98
- readonly maxInboxBytesPerWorker: number;
99
- /** Maximum reply depth; a root mail is depth 0, so `2` allows ask → answer → answer. */
100
- readonly maxThreadDepth: number;
101
- readonly maxBodyBytes: number;
102
- readonly maxSubjectBytes: number;
103
- }
104
- /** Bounds chosen so a peer channel cannot become the dominant cost of a run: eight sends and
105
- * sixteen receives per worker, 32 KiB of received body, and a reply chain that terminates. */
106
- declare const DEFAULT_PEER_MAIL_LIMITS: PeerMailLimits;
107
- /**
108
- * Phrases that mark the run's AUTHORITY in a folded prompt. A peer that writes one of these is
109
- * trying to speak as the supervisor, so intake refuses the envelope outright.
110
- *
111
- * The render-time fence in the inbox is the second half of this defence and neither half is
112
- * sufficient alone: a fence loses to a body that closes it, and an intake filter loses to a body
113
- * that invents a new authority phrase. Together they make forgery mechanically detectable and give
114
- * the standing prompt one concrete boundary to bind to. Neither makes a model OBEY a boundary.
115
- */
116
- declare const AUTHORITY_MARKERS: ReadonlyArray<string>;
117
- /** The wire property carrying an envelope to a worker inbox. Deliberately its OWN discriminant:
118
- * reusing `steer`/`answer` would let a peer mint a message on the parent's channels. */
119
- declare const PEER_MAIL_WIRE_KEY = "mail";
120
- /** The tool names a mail capability endpoint serves. It serves NOTHING else. */
121
- declare const peerMailVerbNames: readonly ["send_mail", "read_mail"];
122
- /** What a worker sees when it reads its own mailbox. */
123
- interface PeerMailReadout {
124
- /** The reading worker's own id, so a worker can address a reply correctly. */
125
- readonly you: string;
126
- /** Every envelope admitted to this worker so far, oldest first. */
127
- readonly inbox: ReadonlyArray<PeerMailEnvelope>;
128
- /** Live siblings this worker may write to (itself excluded). Without this a worker knows no
129
- * peer's id and the channel is unusable. */
130
- readonly peers: ReadonlyArray<{
131
- readonly workerId: string;
132
- readonly label: string;
133
- }>;
134
- readonly sent: number;
135
- /** Sends still allowed, or `null` when this run set no send quota. */
136
- readonly sendQuotaLeft: number | null;
137
- readonly limits: PeerMailLimits;
138
- }
139
- interface PeerMailSendInput {
140
- readonly to: unknown;
141
- readonly kind: unknown;
142
- readonly subject: unknown;
143
- readonly body: unknown;
144
- readonly evidenceRefs?: unknown;
145
- readonly replyTo?: unknown;
146
- }
147
- interface PeerMailbox {
148
- readonly limits: PeerMailLimits;
149
- /**
150
- * Publish the base URL of the capability listener once it has a port. Until it is set no spawn
151
- * receives a mail endpoint: a capability nobody can reach is not worth handing out, and a URL
152
- * built from an unassigned port would be a lie.
153
- */
154
- setEndpoint(baseUrl: string): void;
155
- /** Mint (idempotently, per assignment) the capability URL for one spawn. Undefined before the
156
- * listener has published its endpoint. */
157
- mintCapability(assignmentId: string): string | undefined;
158
- /** Bind a minted capability to the concrete worker the spawn produced. Until this runs the
159
- * capability can send nothing. */
160
- bindCapability(assignmentId: string, workerId: string): void;
161
- /** Resolve the capability path segment carried in a request URL. */
162
- hasCapability(capabilityId: string): boolean;
163
- /** The two tools a single capability serves, with the sender closed over. */
164
- tools(capabilityId: string): McpToolDescriptor[];
165
- send(capabilityId: string, input: PeerMailSendInput): Promise<PeerMailEvent>;
166
- read(capabilityId: string): PeerMailReadout;
167
- /** The parent's control: refuse every further mail on one thread. Returns false when the thread
168
- * was already stopped. Mail already delivered is not recalled — this stops the next reply. */
169
- stopThread(threadId: string): boolean;
170
- /** Every attempt in order — delivered and refused alike. */
171
- history(): ReadonlyArray<PeerMailEvent>;
172
- }
173
- interface PeerMailboxOptions {
174
- readonly scope: Scope<unknown>;
175
- /** Publish one attempt as a coordination event. Awaited, so a durable subscriber commits the
176
- * record before the sender learns the outcome. */
177
- readonly publish: (event: PeerMailEvent) => Promise<void>;
178
- readonly limits?: Partial<PeerMailLimits>;
179
- readonly now?: () => number;
180
- }
181
- /** True when `text` carries a phrase reserved for the run's authority. Case-insensitive, because
182
- * the render is read by a model and case is not what distinguishes an instruction. */
183
- declare function claimsAuthority(text: string): boolean;
184
- /** True when `value` is an envelope this runtime produced. The worker inbox parses with this, so a
185
- * malformed or partial wire object is discarded rather than rendered as a peer message. */
186
- declare function isPeerMailEnvelope(value: unknown): value is PeerMailEnvelope;
187
- /** Create the run's post office. One per manager scope; the manager's siblings are its addresses. */
188
- declare function createPeerMailbox(opts: PeerMailboxOptions): PeerMailbox;
189
- /**
190
- * The two tools ONE capability serves. `capabilityId` is closed over and `from` is not a parameter,
191
- * so the endpoint a worker holds can only ever speak as that worker. The descriptions carry the
192
- * authority rule, because the receiving model reads them as part of the channel's contract.
193
- */
194
- declare function peerMailTools(mailbox: PeerMailbox, capabilityId: string): McpToolDescriptor[];
195
- //#endregion
196
- //#region src/runtime/router-retry-policy.d.ts
197
- /** Exact retry controls accepted at `AgentProfile.model.metadata.retry`. */
198
- interface RouterRetryPolicy {
199
- /** Total attempts, including the first request. */
200
- readonly maxAttempts?: number;
201
- /** Delay before the second attempt. Later delays grow exponentially. */
202
- readonly initialBackoffMs?: number;
203
- /** Maximum delay between attempts. */
204
- readonly maxBackoffMs?: number;
205
- /** Symmetric random variation around each delay, from 0 through 1. */
206
- readonly jitter?: number;
207
- /** HTTP statuses that may be retried. */
208
- readonly retryStatuses?: ReadonlyArray<number>;
209
- /** Deadline for receiving one attempt's response headers. Zero disables it. */
210
- readonly requestTimeoutMs?: number;
211
- }
212
- //#endregion
213
- //#region src/runtime/tool-loop.d.ts
214
- /** Provider-neutral conversation record accepted by a tool-loop brain. */
215
- type ToolLoopMessageRecord = Record<string, unknown>;
216
- /** One provider-neutral tool request emitted by a tool-loop model. */
217
- interface ToolLoopToolCall {
218
- id: string;
219
- name: string;
220
- /** Raw JSON arguments emitted by the model. */
221
- arguments: string;
222
- }
223
- /** Runtime-owned identity and cancellation for one logical inference call. The wrapper is frozen
224
- * before dispatch; a transport may observe the signal but cannot replace the authority it names. */
225
- interface ToolLoopCallContext {
226
- readonly signal: AbortSignal;
227
- readonly callId: string;
228
- readonly correlationId: string;
229
- }
230
- /** One inference turn over the running conversation + the tool specs → the model's text, any
231
- * tool calls, and token usage. The seam every brain satisfies. */
232
- type ToolLoopChat = (messages: ReadonlyArray<ToolLoopMessageRecord>, tools: ReadonlyArray<ToolSpec>, context?: ToolLoopCallContext) => Promise<{
233
- content?: string | null;
234
- toolCalls: ToolLoopToolCall[];
235
- usage?: {
236
- input: number;
237
- output: number;
238
- reasoning?: number;
239
- };
240
- /** Dollar value reported for the turn. It is not billed spend unless provenance says so. */
241
- costUsd?: number;
242
- costProvenance?: 'provider-receipt' | 'billing-receipt' | 'catalog-estimate';
243
- /** The turn ran but its usage was not reported when the transport EXPECTED one (the streamed
244
- * router transport asks for usage and this says it never arrived). A metering caller records an
245
- * unknown turn on it; `runBrainLoop` itself ignores it. */
246
- usageUnknown?: true;
247
- /** Provider-observed model identity. Profile-bound callers validate it before accepting output. */
248
- model?: string;
249
- /** Provider-reported prompt-cache evidence; missing fields remain missing. */
250
- promptCache?: Readonly<Record<string, number | string>>;
251
- /** Physical HTTP/injected-transport attempts spent by this one logical call. */
252
- transportAttempts?: number;
253
- }>;
254
- /** Self-compaction — bound the loop's OWN context window the way a fresh-respawn (dumb-Ralph) loop
255
- * does, but in place. A stateless chat API re-sends the WHOLE running conversation every turn, so an
256
- * agent that accumulates dozens of turns of tool results re-bills its entire transcript on every
257
- * inference — the context-overflow-one-level-up that the conserved budget pool cannot fix. With
258
- * compaction set, once the conversation exceeds `thresholdTokens` the accumulated middle (every prior
259
- * assistant turn + tool result) is distilled into ONE compact progress note and the conversation is
260
- * reset to `[...head, digest]`: the preserved head (system + the original task) survives, the stale
261
- * turn-by-turn history does not. The model keeps deciding; it stops re-billing the whole transcript.
262
- * Fires at a CLEAN turn boundary (after a turn's tool results are folded in, before the next
263
- * inference) so it never orphans an assistant `tool_calls` from its `tool` replies. */
264
- interface ToolLoopCompaction {
265
- /** Compact once the estimated token count of the conversation exceeds this. */
266
- readonly thresholdTokens: number;
267
- /** Distill the conversation into a compact progress note that REPLACES the middle. Receives the
268
- * full conversation (so it can summarize everything done so far); returns the digest string. */
269
- readonly distill: (messages: ReadonlyArray<ToolLoopMessageRecord>) => Promise<string> | string;
270
- /** Leading messages preserved verbatim (system + the original task). Default 2. */
271
- readonly preserveHead?: number;
272
- /** Token estimator over the conversation. Default ≈ chars/4 (incl. tool-call arguments). */
273
- readonly estimateTokens?: (messages: ReadonlyArray<ToolLoopMessageRecord>) => number;
274
- /** Notified each time a compaction fires — for observability/metering. */
275
- readonly onCompact?: (info: {
276
- turn: number;
277
- beforeTokens: number;
278
- afterTokens: number;
279
- }) => void;
280
- }
281
- /** Public supervisor-facing compaction config: same knobs as the primitive, but `distill` is optional
282
- * because the supervisor has a default digest that combines a brain note with live worker state. */
283
- type ToolLoopCompactionOptions = Omit<ToolLoopCompaction, 'distill'> & {
284
- readonly distill?: ToolLoopCompaction['distill'];
285
- };
286
- //#endregion
287
- //#region src/runtime/router-client.d.ts
288
- /**
289
- * Connection details for Runtime's Router-backed executors.
290
- *
291
- * This is deliberately transport-only: model, prompt, tools, generation settings, and retry
292
- * policy belong to the exact executable `AgentProfile` consumed by `streamAgentTurn`.
293
- */
294
- interface RouterTransportConfig {
295
- routerBaseUrl: string;
296
- routerKey: string;
297
- /** Injectable OpenAI-compatible transport for offline execution. */
298
- complete?: (body: Record<string, unknown>, request?: {
299
- readonly headers: Readonly<Record<string, string>>;
300
- readonly signal?: AbortSignal;
301
- }) => Promise<unknown>;
302
- }
303
- /**
304
- * Private request configuration used by Runtime's Router adapter.
305
- *
306
- * Do not export this through a package entry point. Public callers execute a concrete
307
- * `AgentProfile` through `createExecutor` + `streamAgentTurn`; only Runtime may lower that profile
308
- * into these provider request fields.
309
- */
310
- interface RouterConfig extends RouterTransportConfig {
311
- model: string;
312
- /** Exact retry controls lowered from `AgentProfile.model.metadata.retry`. */
313
- retry?: RouterRetryPolicy;
314
- /**
315
- * Optional ceiling for one completion, forwarded as `max_tokens`.
316
- *
317
- * A REASONING model spends this budget on hidden thinking BEFORE it emits a visible token, so
318
- * the default can truncate one mid-thought and return no content at all — observed live with a
319
- * model that spent 8,188 of the 8,192 on reasoning and answered with nothing. Raise it for a
320
- * thinking model; the ceiling belongs to the router and model a caller chose, which is why it
321
- * lives here rather than on one call site.
322
- */
323
- maxTokens?: number;
324
- /**
325
- * Optional ceiling on TOTAL completion tokens — visible answer plus hidden reasoning —
326
- * forwarded as `max_completion_tokens`. Distinct from `maxTokens`: a reasoning model can spend
327
- * an entire `max_tokens` budget on hidden thinking, so only this field bounds what the provider
328
- * bills for one completion.
329
- */
330
- maxCompletionTokens?: number;
331
- /**
332
- * Take the tool-calling completion over SSE instead of one buffered POST. Off by default —
333
- * `routerChatWithTools` never streams, and every existing caller keeps the buffered transport
334
- * byte for byte.
335
- *
336
- * Why it exists: a buffered POST holds one connection idle for the WHOLE completion, and a
337
- * supervisor turn is the longest completion in the system. An intermediary gateway with an
338
- * idle-read timeout kills that connection mid-completion (the 524/503 family). A streamed
339
- * response puts bytes on the wire from the first generated token on, so the connection is only
340
- * idle through prefill. It does NOT shorten prefill, so a gateway whose deadline is
341
- * time-to-FIRST-byte is unaffected; only an idle-timeout gateway is.
342
- *
343
- * Mutually exclusive with `complete`: the injected transport returns one parsed JSON body and has
344
- * no stream to read, so setting both throws rather than silently taking the buffered path.
345
- *
346
- * WHICH PATHS CAN OPT IN. This flag is read in exactly one place (the private `chatWithTools` transport switch), so
347
- * every entry point that takes a caller-supplied `RouterConfig` honors it: `routerBrain`,
348
- * `routerToolLoop`, and `supervisorAgent` (which spreads `deps.router` into the brain's config —
349
- * the supervisor turn this exists for). Two production call sites build a `RouterConfig` literal
350
- * from their own options and therefore CANNOT express it today: the bench strategy's
351
- * `routerToolLoop` config in `strategy.ts` and the local sandbox client's `routerBrain` config in
352
- * `local-sandbox-client.ts`. Neither drives a supervisor-length turn; setting `stream` on a
353
- * config handed to either has no path to reach them, and they stay buffered.
354
- */
355
- stream?: boolean;
356
- }
357
- interface ToolSpec {
358
- type: 'function';
359
- function: {
360
- name: string;
361
- description?: string;
362
- parameters: unknown;
363
- };
364
- }
365
- //#endregion
366
- //#region src/mcp/local-harness.d.ts
367
- /**
368
- * Local coding harness available inside the sandbox — a narrowing of the shared `HarnessType`
369
- * vocabulary, NOT a private spelling of it. The harness id is `claude-code`; `claude` is the
370
- * EXECUTABLE name and lives only in the `command` field below. Keeping one vocabulary is what
371
- * lets a `LocalHarness` be handed straight to the profile materializer and the capability table
372
- * with no translation step.
373
- */
374
- type LocalHarness = Extract<HarnessType, 'claude-code' | 'codex' | 'opencode' | 'pi'>;
375
- /** Every local harness, in table order — the one list `AGENT_RUNTIME_LOCAL_HARNESSES` and any
376
- * other harness enumeration reads, so adding a row above is the only edit a new harness needs. */
377
- declare const LOCAL_HARNESSES: ReadonlyArray<LocalHarness>;
378
- /** The harness a caller gets when it expresses no preference. A composition-root default, not a
379
- * capability claim: one constant so the several entry points cannot drift apart. */
380
- declare const DEFAULT_LOCAL_HARNESS: LocalHarness;
381
- /** The CLI binary a harness id runs. The two are NOT the same string (`claude-code` runs `claude`),
382
- * so anything spawning a harness — a version probe, a login check — reads it from here rather than
383
- * passing the harness id as a command. */
384
- declare function localHarnessExecutable(harness: LocalHarness): string;
385
- /**
386
- * Whether the harness's native control can express this reasoning effort. Admission checks read
387
- * this so a profile the invocation would later refuse is rejected BEFORE any workspace state is
388
- * created, against the same table that emits the argv.
389
- */
390
- declare function harnessSupportsReasoningEffort(harness: LocalHarness, reasoningEffort: ReasoningEffort): boolean;
391
- /** @experimental */
392
- interface RunLocalHarnessOptions {
393
- harness: LocalHarness;
394
- /** Working directory for the subprocess (typically a worktree path). */
395
- cwd: string;
396
- /** Prompt forwarded as the harness CLI's task argument. */
397
- taskPrompt: string;
398
- /**
399
- * Pre-built command + args (e.g. from `harnessInvocation` so the full authored
400
- * `AgentProfile` — systemPrompt + model — reaches the harness). When set it OVERRIDES the
401
- * default prompt-only `buildArgs(taskPrompt)` path; `command` defaults to the harness's
402
- * default binary when only `args` is supplied. When absent the legacy prompt-only shape
403
- * is used unchanged.
404
- */
405
- invocation?: {
406
- command?: string;
407
- args: ReadonlyArray<string>;
408
- };
409
- /** Allow autonomous edits without an interactive approval gate, using whichever bypass argv the
410
- * harness declares. Use only when `cwd` is an isolated candidate worktree. */
411
- dangerouslySkipPermissions?: boolean;
412
- /** Isolate Codex from ambient configuration/instructions and require JSONL token usage.
413
- * The invocation should come from `harnessInvocation(..., { codexReproducible: true })`. */
414
- codexReproducible?: boolean;
415
- /** Absolute host paths that reproducible Codex must not read. The normalized set is compiled
416
- * into the controlled permission profile and its digest is returned in execution evidence. */
417
- codexReadDeniedPaths?: ReadonlyArray<string>;
418
- /** Optional wall-clock kill deadline (ms). Omit it for no timer. A positive value sends
419
- * SIGTERM on expiry. */
420
- timeoutMs?: number;
421
- /** Newest stdout/stderr bytes retained per stream. Default 64 MiB. */
422
- maxOutputBytes?: number;
423
- /** Caller cancellation. SIGTERM is sent on abort. */
424
- signal?: AbortSignal;
425
- /** Override env (defaults to inheriting from the parent). */
426
- env?: NodeJS.ProcessEnv;
427
- /**
428
- * Test seam — inject a custom spawner so unit tests can mock the
429
- * subprocess without touching the OS. Defaults to node's `child_process.spawn`.
430
- */
431
- spawn?: (command: string, args: ReadonlyArray<string>, opts: {
432
- cwd: string;
433
- env: NodeJS.ProcessEnv;
434
- stdio: 'pipe';
435
- detached: boolean;
436
- }) => ChildProcess;
437
- /** Test seam for locating the native Codex executable before it is staged in the worktree. */
438
- resolveCodexExecutable?: (command: string, env: NodeJS.ProcessEnv) => Promise<string>;
439
- }
440
- /**
441
- * Exact aggregate usage emitted by Codex's terminal `turn.completed` JSONL event.
442
- *
443
- * `cachedInputTokens` is a part of `inputTokens` and `reasoningOutputTokens` is a part of
444
- * `outputTokens`; neither adds to the total it describes. `cacheWriteInputTokens` is optional
445
- * because the codex CLI reports it and a provider-normalized capture omits it, and an absent
446
- * counter must stay absent rather than become a zero that claims no cache write was measured.
447
- */
448
- interface CodexTokenUsage {
449
- inputTokens: number;
450
- cachedInputTokens: number;
451
- outputTokens: number;
452
- reasoningOutputTokens: number;
453
- cacheWriteInputTokens?: number;
454
- }
455
- /** Isolation settings asserted before a reproducible Codex run is allowed to start. */
456
- interface CodexExecutionPolicy {
457
- sessionPersistence: 'ephemeral';
458
- userConfig: false;
459
- rules: false;
460
- projectInstructions: false;
461
- skillInstructions: false;
462
- appInstructions: false;
463
- toolSuggestions: false;
464
- multiAgentInstructions: false;
465
- sandbox: 'workspace-write';
466
- permissionProfile: 'agent_runtime_reproducible';
467
- approvalPolicy: 'never';
468
- shellNetwork: false;
469
- webSearch: false;
470
- serviceTier: 'default';
471
- shellEnvironment: 'core-filtered';
472
- loginShell: false;
473
- credentialsReadable: false;
474
- hostHomeReadable: false;
475
- procEnvironment: 'private-sanitized';
476
- sensitiveEnvironmentNamesVisible: false;
477
- parentRepoRead: false;
478
- gitMetadata: false;
479
- temporaryDirectory: 'workspace-private';
480
- stagedExecutable: 'static-elf-read-only';
481
- callerReadDeniedPaths: 'enforced';
482
- containerSockets: false;
483
- }
484
- /** Zero-model-call evidence for the exact Codex process about to run. */
485
- interface CodexExecutionEvidence {
486
- cliVersion: string;
487
- executableSha256: string;
488
- /** SHA-256 of the exact composed prompt argument proved present in the rendered prompt. */
489
- requestedPromptSha256: string;
490
- effectivePromptSha256: string;
491
- nonPromptArgsSha256: string;
492
- controlledConfigSha256: string;
493
- /** Sorted normalized paths compiled into the permission profile. */
494
- readDeniedPaths: string[];
495
- readDeniedPathsSha256: string;
496
- readDeniedPathCount: number;
497
- policy: CodexExecutionPolicy;
498
- }
499
- /** @experimental */
500
- interface LocalHarnessResult {
501
- /** OS exit code. `null` when killed before exit. */
502
- exitCode: number | null;
503
- /** Concatenated stdout. */
504
- stdout: string;
505
- /** Concatenated stderr. */
506
- stderr: string;
507
- /** Set when the process exited via signal (timeout / abort). */
508
- killedBySignal: NodeJS.Signals | null;
509
- /** Wall-clock duration ms (spawn → exit). */
510
- durationMs: number;
511
- /** Set when timeoutMs elapsed before exit. */
512
- timedOut: boolean;
513
- /**
514
- * Set when the caller's AbortSignal fired before this result settled.
515
- * Optional so injected runners and stored results from older releases remain valid.
516
- */
517
- aborted?: boolean;
518
- /** Present for a reproducible Codex run; parsed from the real terminal JSONL event. */
519
- usage?: CodexTokenUsage;
520
- /** Present for reproducible Codex runs; generated and checked before model execution. */
521
- evidence?: CodexExecutionEvidence;
522
- }
523
- /**
524
- * Spawn a local coding harness CLI as a subprocess + collect its output.
525
- *
526
- * NOT responsible for parsing the harness's output or extracting a diff —
527
- * the in-process executor's `streamPrompt` orchestrates `git diff` against
528
- * the worktree after this resolves. This function is intentionally narrow:
529
- * spawn, wait, capture, return.
530
- *
531
- * Fails loud — throws when:
532
- * - `cwd` doesn't exist (subprocess emits ENOENT; surfaced as Error)
533
- * - the harness binary is not on PATH (ENOENT)
534
- * - the caller signal was already aborted before process launch
535
- *
536
- * Does NOT throw when:
537
- * - the subprocess exits non-zero (`result.exitCode` carries the code)
538
- * - a non-reproducible subprocess is aborted / timed out (`result.aborted` /
539
- * `result.timedOut` carries the reason even when a TERM-aware child exits zero)
540
- *
541
- * Reproducible Codex additionally requires a terminal usage event. If cancellation
542
- * prevents that event, this rejects with `CodexExecutionDiagnosticError` instead of
543
- * returning an incomplete reproducibility receipt.
544
- *
545
- * @experimental
546
- */
547
- declare function runLocalHarness(options: RunLocalHarnessOptions): Promise<LocalHarnessResult>;
548
- /**
549
- * Parse and validate the one terminal usage event emitted by `codex exec --json`.
550
- *
551
- * The JSONL framing is this surface's own; the usage RECORD is read by `parseCodexUsageRecord`,
552
- * the one codex usage reader the sandbox decoder also calls, so both surfaces hold the same field
553
- * policy and the same two cross-field invariants.
554
- */
555
- declare function parseCodexTokenUsage(stdout: string): CodexTokenUsage;
556
- //#endregion
557
- //#region src/mcp/worktree.d.ts
558
- /**
559
- *
560
- * Git worktree helpers for the in-process delegation executor. Each
561
- * delegation runs in its own worktree so multiple parallel harness
562
- * subprocesses (claude / codex / opencode in a 3-way fanout) don't clobber
563
- * each other's edits on the shared workspace.
564
- *
565
- * Worktrees live under `<repoRoot>/.agent-worktrees/<runId>/`. After the
566
- * harness exits + the diff is captured, the worktree is removed.
567
- *
568
- * All operations spawn `git` via `child_process.spawn` synchronously
569
- * (via a `runGit` helper). Stays narrow on purpose: no commits, no rebases.
570
- * Diff capture stages all changes (`git add -A`) into the ephemeral worktree's
571
- * index so created (untracked) files appear in the `--cached` diff.
572
- *
573
- * @experimental
574
- */
575
- /** @experimental */
576
- interface WorktreeHandle {
577
- /** Absolute path to the worktree directory. */
578
- path: string;
579
- /** SHA the worktree was created at. */
580
- baseSha: string;
581
- /** Branch name created for this worktree (typically `delegate/<runId>`). */
582
- branch: string;
583
- }
584
- /** @experimental */
585
- interface CreateWorktreeOptions {
586
- /** Absolute path to the main git checkout. */
587
- repoRoot: string;
588
- /** Unique id for the worktree path + branch. Use the delegation run id. */
589
- runId: string;
590
- /** Parent directory the worktree lives under. Defaults to `.agent-worktrees`. */
591
- variantsDir?: string;
592
- /** Override the base ref (default `HEAD`). */
593
- baseRef?: string;
594
- /** Test seam — inject a custom git runner. */
595
- runGit?: GitRunner;
596
- }
597
- /** @experimental */
598
- interface DiffOptions {
599
- /** Worktree to diff. */
600
- worktree: WorktreeHandle;
601
- /** What to compare against. Default `worktree.baseSha`. */
602
- baseRef?: string;
603
- /**
604
- * Repository-relative input paths to omit from the captured worker patch.
605
- * Paths are passed to Git with literal exclusion magic, so profile-provided
606
- * `*`, `?`, `[` and `:` characters can never expand into broader pathspecs.
607
- */
608
- excludePaths?: ReadonlyArray<string>;
609
- /** Test seam. */
610
- runGit?: GitRunner;
611
- }
612
- /** @experimental */
613
- interface DiffResult {
614
- patch: string;
615
- stats: {
616
- filesChanged: number;
617
- insertions: number;
618
- deletions: number;
619
- };
620
- }
621
- /** @experimental */
622
- interface RemoveWorktreeOptions {
623
- worktree: WorktreeHandle;
624
- repoRoot: string;
625
- /** Force removal even if dirty (default true; the loser of a fanout has uncommitted changes). */
626
- force?: boolean;
627
- /** Test seam. */
628
- runGit?: GitRunner;
629
- }
630
- /** Pluggable git runner (sync) — replaceable in tests. */
631
- type GitRunner = (args: ReadonlyArray<string>, opts: {
632
- cwd: string;
633
- }) => {
634
- stdout: string;
635
- stderr: string;
636
- exitCode: number;
637
- };
638
- /** Checkout a fresh git worktree for a delegation run on a new branch under `variantsDir`. @experimental */
639
- declare function createWorktree(options: CreateWorktreeOptions): Promise<WorktreeHandle>;
640
- /** Stage worker changes and return the diff + shortstat, excluding declared input paths. @experimental */
641
- declare function captureWorktreeDiff(options: DiffOptions): Promise<DiffResult>;
642
- /**
643
- * Remove a git worktree and delete its branch. Already-removed paths are harmless; every other
644
- * Git failure rejects so callers cannot report a worktree as destroyed when cleanup failed.
645
- * @experimental
646
- */
647
- declare function removeWorktree(options: RemoveWorktreeOptions): Promise<void>;
648
- //#endregion
649
- //#region src/mcp/worktree-harness.d.ts
650
- /** Outcome of one verification command run in the worktree (test or typecheck). */
651
- interface WorktreeCommandResult {
652
- /** The shell command line that was run. */
653
- command: string;
654
- /** Did the command exit 0? The PASS signal a deliverable gate / coder output reads. */
655
- passed: boolean;
656
- /** OS exit code, or `null` when killed before exit. */
657
- exitCode: number | null;
658
- /** Combined stdout+stderr (capped) — surfaced in traces for diagnosis. */
659
- output: string;
660
- }
661
- /** Proof of the profile inputs delivered before the worker process started. */
662
- interface WorktreeProfileMaterializationReceipt {
663
- /** Digest of the exact materializer plan: files, modes, environment, flags, and unsupported rows. */
664
- workspacePlanDigest: string;
665
- /** Repository-relative profile input files written into the worker worktree. */
666
- writtenPaths: string[];
667
- /** Must be empty on a successful run because this path fails closed. */
668
- unsupported: WorkspacePlanReceipt['unsupported'];
669
- /** Environment variable names added to the worker process. Values remain out of telemetry. */
670
- environmentNames: string[];
671
- /** Exact additional CLI arguments emitted by the materializer. */
672
- flags: string[];
673
- /** `resources.instructions` bypasses native project files so reproducible Codex cannot drop it. */
674
- resourceInstructions: {
675
- delivery: 'none' | 'invocation-prompt';
676
- sha256: string | null;
677
- byteLength: number;
678
- };
679
- }
680
- /** The canonical result of one worktree-harness run, projected by each port to its own shape. */
681
- interface WorktreeHarnessResult {
682
- /** The branch the worktree was cut on (`delegate/<runId>`). */
683
- branch: string;
684
- /** `git diff` of the worktree against its base — the unified patch the harness produced. */
685
- patch: string;
686
- /** Shortstat-derived change counts. */
687
- stats: {
688
- filesChanged: number;
689
- insertions: number;
690
- deletions: number;
691
- };
692
- /**
693
- * Exact profile materialization applied before the harness launched.
694
- * Absent on transports that cannot return a materializer receipt; never fabricated.
695
- */
696
- profileMaterialization?: WorktreeProfileMaterializationReceipt;
697
- /** The harness subprocess outcome. */
698
- harness: {
699
- name: LocalHarness | 'bridge';
700
- exitCode: number | null;
701
- timedOut: boolean;
702
- killedBySignal: NodeJS.Signals | null;
703
- durationMs: number;
704
- stdout: string;
705
- stderr: string;
706
- /** Exact Codex JSONL usage when reproducible mode is enabled. */
707
- usage?: CodexTokenUsage;
708
- /** Installed CLI version captured immediately before execution. */
709
- cliVersion?: string;
710
- /** SHA-256 of the native Codex executable staged read-only in the candidate worktree. */
711
- executableSha256?: string;
712
- /** SHA-256 of the exact composed prompt argument proved present in Codex's rendered prompt. */
713
- requestedPromptSha256?: string;
714
- /** SHA-256 of `codex debug prompt-input` output for the exact isolated prompt. */
715
- effectivePromptSha256?: string;
716
- /** SHA-256 of the exact executable + argv with prompt content replaced by `<PROMPT>`. */
717
- nonPromptArgsSha256?: string;
718
- /** SHA-256 of the isolated config that fixes permissions and shell environment. */
719
- controlledConfigSha256?: string;
720
- /** SHA-256 of the normalized caller-supplied host read-denial paths. */
721
- readDeniedPathsSha256?: string;
722
- /** Sorted normalized caller-supplied host read-denial paths. */
723
- readDeniedPaths?: string[];
724
- /** Number of normalized caller-supplied host read-denial paths. */
725
- readDeniedPathCount?: number;
726
- /** Explicit isolation claims checked before model execution. */
727
- executionPolicy?: CodexExecutionPolicy;
728
- };
729
- /** Verification signals derived in the live worktree (present only when commands were given). */
730
- checks?: {
731
- tests?: WorktreeCommandResult;
732
- typecheck?: WorktreeCommandResult;
733
- };
734
- }
735
- /** The single shell-command-in-worktree runner seam (replaces the per-executor copies). */
736
- type WorktreeCheckRunner = (opts: {
737
- command: string;
738
- cwd: string;
739
- timeoutMs: number;
740
- signal?: AbortSignal;
741
- }) => Promise<{
742
- exitCode: number | null;
743
- output: string;
744
- }>;
745
- /** The canonical result of one in-place harness run. The edits are the DIRECTORY, not a patch:
746
- * the caller supplied the workspace and reads it directly. */
747
- interface InPlaceHarnessResult {
748
- /** The directory the harness ran in, exactly as supplied. */
749
- workspacePath: string;
750
- /** Exact profile materialization applied before the harness launched, and removed after it. */
751
- profileMaterialization: WorktreeProfileMaterializationReceipt;
752
- /** The harness subprocess outcome. */
753
- harness: WorktreeHarnessResult['harness'];
754
- }
755
- //#endregion
756
- //#region src/runtime/harness-usage.d.ts
757
- /**
758
- * One harness's own token-usage report for one turn, in the runtime's field names.
759
- *
760
- * `input` is the provider's TOTAL prompt count and `output` is its TOTAL completion count.
761
- * The other three counters CLASSIFY a part of one of those totals; none of them adds to it.
762
- * `cachedInput` and `cacheWriteInput` classify `input`, which is the convention
763
- * `promptCacheTokenClasses` (`util.ts`) folds: `freshInput = input - cacheRead - cacheWrite`.
764
- * `reasoningOutput` classifies `output`.
765
- *
766
- * A counter the harness does not report stays absent, because a zero would claim the harness
767
- * measured none.
768
- */
769
- interface HarnessUsage {
770
- /** The harness family whose adapter produced this report. */
771
- readonly harness: HarnessType;
772
- /** Total prompt tokens the provider charged for the turn, the cached ones included. */
773
- readonly input: number;
774
- /** Total completion tokens the provider charged for the turn, the reasoning ones included. */
775
- readonly output: number;
776
- /** The part of `input` the provider served from its prompt cache. */
777
- readonly cachedInput?: number;
778
- /** The part of `input` the provider wrote into its prompt cache. */
779
- readonly cacheWriteInput?: number;
780
- /** The part of `output` the model spent on reasoning. Never added to `output`. */
781
- readonly reasoningOutput?: number;
782
- }
783
- /**
784
- * Decode a sandbox event with one harness's adapter, or `undefined` when the event carries no
785
- * harness-native usage.
786
- *
787
- * A NAMED harness reads with that harness's adapter only, and a named harness with no adapter
788
- * reports nothing. It never falls through to another harness's adapter: a different harness's
789
- * `turn.completed` decoded as codex would either drop the counters codex does not name or fail on
790
- * a field codex requires, and both answers would be about the wrong harness. The composite over
791
- * every registered adapter runs only when the caller cannot name the harness.
792
- *
793
- * Throws `ValidationError` when an adapter recognizes the event as its harness's usage carrier and
794
- * cannot read the numbers.
795
- */
796
- declare function decodeHarnessUsage(event: SandboxEvent, harness?: HarnessType): HarnessUsage | undefined;
797
- //#endregion
798
- //#region src/runtime/codex-rollout-store.d.ts
799
- /** Who wrote one rollout, exactly as its own `session_meta` states it. Nothing here is inferred. */
800
- interface CodexRolloutIdentity {
801
- /** The rollout's own thread id (`session_meta.payload.id`). */
802
- readonly sessionId: string;
803
- /** The thread this one was spawned or forked from, when it was. */
804
- readonly parentThreadId?: string;
805
- /** The thread whose rows are prepended into this file, when this file is a fork. */
806
- readonly forkedFromId?: string;
807
- /** True when `thread_source` reads `subagent`: a harness-native child, invisible to the journal. */
808
- readonly nativeChild: boolean;
809
- /** The child's own path in the harness's agent tree (`/root/c1_b_grid`), when it has one. */
810
- readonly agentPath?: string;
811
- /** The harness's own nickname for the child ("Turing"), when it has one. */
812
- readonly agentNickname?: string;
813
- /** Spawn depth the harness recorded. `1` is a direct child of the seat. */
814
- readonly depth?: number;
815
- /** The working directory the session ran in, used to attribute a store to a workspace. */
816
- readonly cwd?: string;
817
- /** The codex build that wrote it. */
818
- readonly cliVersion?: string;
819
- /** When the session itself started, from its own `session_meta` timestamp. */
820
- readonly startedAtMs?: number;
821
- }
822
- /** How this reader isolated the session's own rows from the parent rows prepended to its file. */
823
- type CodexForkBoundary =
824
- /** Not a fork: every row in the file belongs to this session. */
825
- {
826
- readonly kind: 'whole-file';
827
- } |
828
- /** A fork whose own first turn was isolated, and by which rule. */
829
- {
830
- readonly kind: 'resolved';
831
- readonly rule: 'history-start-ordinal' | 'turn-is-session' | 'turn-uuid-v7' | 'turn-start-time';
832
- /** The `turn_id` of the session's own first turn. */
833
- readonly turnId?: string;
834
- /** Rows credited to the parent and excluded from `own`. */
835
- readonly inheritedTurns: number;
836
- } |
837
- /** A fork this reader could not isolate. `own` is absent; nothing may be charged. */
838
- {
839
- readonly kind: 'unresolved';
840
- readonly reason: string;
841
- };
842
- /** One turn of one session, with the counters it added to the session's cumulative total. */
843
- interface CodexRolloutTurn {
844
- readonly turnId?: string;
845
- readonly startedAtMs?: number;
846
- readonly usage: HarnessUsage;
847
- }
848
- /** One rollout file, read. */
849
- interface CodexRolloutSession {
850
- readonly identity: CodexRolloutIdentity;
851
- readonly boundary: CodexForkBoundary;
852
- /**
853
- * The session's OWN spend — the cumulative delta from its fork boundary to its last report.
854
- * ABSENT when the boundary is unresolved: an unattributable number must not be charged.
855
- */
856
- readonly own?: HarnessUsage;
857
- /** The session's own turns, newest last. Empty when the file reported no usage. */
858
- readonly turns: readonly CodexRolloutTurn[];
859
- /**
860
- * The file's final cumulative `total_token_usage`, kept ONLY as the diagnostic that shows how
861
- * far a naive file total is from the truth. Never charge this.
862
- */
863
- readonly fileCumulativeInput: number;
864
- readonly fileCumulativeOutput: number;
865
- }
866
- /** What one incremental read of a store observed. */
867
- interface CodexStoreDelta {
868
- /** Spend by sessions that are NOT native children — the seat's own turns. */
869
- readonly seat: HarnessUsage;
870
- /** Spend by `thread_source: subagent` sessions — the harness-native children. */
871
- readonly native: HarnessUsage;
872
- /** Sessions whose fork boundary could not be isolated, so their spend is absent, not zero. */
873
- readonly unresolved: ReadonlyArray<{
874
- readonly sessionId: string;
875
- readonly reason: string;
876
- }>;
877
- /**
878
- * Every session this read touched, for evidence. Each one states its WHOLE own spend and turn
879
- * list, which is not the same number as `seat` / `native`: those two carry only what this read
880
- * newly observed.
881
- */
882
- readonly sessions: readonly CodexRolloutSession[];
883
- }
884
- /** A store reader that credits each turn once: it tails only the bytes appended since the last read. */
885
- interface CodexRolloutStoreReader {
886
- /**
887
- * Read everything appended since the previous call and attribute it.
888
- *
889
- * The FIRST call establishes the baseline. Call it before the first turn so pre-existing rows are
890
- * consumed and credited to nothing; every later call returns exactly that turn's spend.
891
- */
892
- read(): Promise<CodexStoreDelta>;
893
- }
894
- /** Where a harness keeps its own session store, and which workspace may be credited from it. */
895
- interface CodexRolloutStoreRef {
896
- /**
897
- * Absolute path to the harness home the CLI writes into — `CODEX_HOME`, or `$HOME/.codex`.
898
- * This MUST be the run's own isolated store. Pointing it at an ambient host store credits one
899
- * run with another run's files, which is the exact defect this reader exists to end.
900
- */
901
- readonly root: string;
902
- /**
903
- * Credit only sessions whose recorded `cwd` is this path or below it. Absent credits every
904
- * session under `root`, which is correct only for a store no other run writes to.
905
- */
906
- readonly workspaceRoot?: string;
907
- }
908
- /**
909
- * Read one rollout's rows into a session record.
910
- *
911
- * `rows` is the file's JSON values in file order. Pass the whole file to read a completed session;
912
- * the store reader passes appended slices and carries the identity forward itself.
913
- */
914
- declare function readCodexRolloutSession(rows: Iterable<unknown>): CodexRolloutSession | undefined;
915
- /**
916
- * Open an incremental reader over a codex store.
917
- *
918
- * Nothing is read until `read()` is called, and every read is bounded by the bytes appended since
919
- * the previous one, so a 695MB rollout is scanned once rather than once per turn.
920
- */
921
- declare function createCodexRolloutStoreReader(ref: CodexRolloutStoreRef): CodexRolloutStoreReader;
922
- /** Sum two usage reports on every counter both of them state. */
923
- declare function addHarnessUsage(left: HarnessUsage, right: HarnessUsage): HarnessUsage;
924
- /** True when a report states any spend at all. */
925
- declare function harnessUsageIsEmpty(usage: HarnessUsage): boolean;
926
- //#endregion
927
- //#region src/runtime/key-provider.d.ts
928
- /** Resolve named secrets. The ONE seam every secret store adapts to. */
929
- interface KeyProvider {
930
- /** The value for `name`, or `undefined` when this provider does not hold it. */
931
- get(name: string): Promise<string | undefined>;
932
- }
933
- /** The env-backed provider: reads the (dotenvx-loaded) process env. Empty /
934
- * whitespace-only values count as absent — fail loud, not with a blank key. */
935
- declare function envKeyProvider(env?: Record<string, string | undefined>): KeyProvider;
936
- /** The `AgentProfileMcpServer.metadata` key the declarative secret-env map
937
- * rides under: `{ ENV_VAR_NAME: 'PROVIDER_KEY_NAME' }`. Names only — values
938
- * are resolved at materialize time and never stored. */
939
- declare const mcpSecretEnvMetadataKey = "secretEnv";
940
- /** Read (and validate) a server entry's declared secret-env map, if any.
941
- * Malformed metadata throws — a half-declared secret must never half-boot. */
942
- declare function secretEnvOfMcpServer(server: AgentProfileMcpServer): Record<string, string> | undefined;
943
- /**
944
- * Resolve a declared secret-env map into the real env entries for a server
945
- * spawn. Fail-closed: no provider or a missing key throws, naming the KEY
946
- * NAME only (the value never appears in any message). `label` names the
947
- * server for the error (e.g. `profile.mcp['exa']`).
948
- */
949
- declare function resolveSecretEnv(secretEnv: Record<string, string>, keys: KeyProvider | undefined, label: string): Promise<Record<string, string>>;
950
- /** The spawn-ready strings for one stdio MCP server: profile config values
951
- * resolved, secrets separated so the client can redact them. */
952
- interface ResolvedMcpServerLaunch {
953
- args?: string[];
954
- /** Public env, safe to appear in diagnostics. */
955
- env?: Record<string, string>;
956
- /** Resolved secret env. Reaches only the child process; redacted everywhere else. */
957
- protectedEnv?: Record<string, string>;
958
- }
959
- /**
960
- * Resolve a profile MCP server's `args`/`env` config values (interface ≥0.40
961
- * `AgentProfileConfigValue`) plus the legacy `metadata.secretEnv` channel into
962
- * the plain strings a spawn needs.
963
- *
964
- * Rules, all fail-closed:
965
- * - `args` must be public values. A secret-ref in argv is refused: argv is
966
- * readable by every host process (/proc/PID/cmdline) and outside the
967
- * protected-value redaction channel, so a secret there cannot be contained.
968
- * - `env` secret-refs resolve through the KeyProvider (missing provider or key
969
- * throws, naming the KEY NAME only) and land in `protectedEnv`.
970
- * - An env var declared secret on BOTH channels (env secret-ref and
971
- * metadata.secretEnv) is ambiguous configuration and throws.
972
- * - A public `env` entry shadowed by a legacy metadata secret keeps the
973
- * pre-0.40 spawn precedence: the secret value wins in the child env.
974
- */
975
- declare function resolveMcpServerLaunch(server: AgentProfileMcpServer, keys: KeyProvider | undefined, label: string): Promise<ResolvedMcpServerLaunch>;
976
- //#endregion
977
- //#region src/runtime/sandbox-events.d.ts
978
- /** The provider/model the platform reports it actually bound to a turn, when it reports one.
979
- * `source` is the platform's own account of where that choice came from — `environment` means
980
- * the platform chose, not the request. */
981
- interface SandboxServedBackend {
982
- readonly provider?: string;
983
- readonly model?: string;
984
- readonly source?: string;
985
- }
986
- /**
987
- * Read the served execution identity off one Sandbox event.
988
- *
989
- * The platform reports `effectiveBackend` on `execution.started` and again on the terminal
990
- * event (`@tangle-network/sandbox`, `EffectiveBackend`). Absence returns `undefined`
991
- * and must stay unknown — a request is not a receipt, so nothing here may be inferred from
992
- * what was asked for.
993
- */
994
- declare function sandboxEventServedBackend(event: SandboxEvent): SandboxServedBackend | undefined;
995
- /**
996
- * Fail the execution when the platform reports serving a model other than the exact one asked for.
997
- *
998
- * Measured motive (agent-runtime#892, live infrastructure 2026-08-17): 6 of 6 boxes whose profile
999
- * declared `zai-coding-plan/glm-5.2` reported
1000
- * `{"provider":"openai-compat","model":"deepseek/deepseek-v4-flash","source":"environment"}`,
1001
- * while the materialization receipt recorded the declared model as `status: "known"`. Sending
1002
- * `backend.model` makes that substitution unlikely; only reading the report back makes it
1003
- * detectable. A run that cannot say which model produced its evidence must not settle as one
1004
- * that can.
1005
- *
1006
- * Silent when the platform reports no served model: unobserved stays unobserved.
1007
- */
1008
- declare function assertSandboxServedModel(event: SandboxEvent, expected: {
1009
- readonly provider?: string;
1010
- readonly model?: string;
1011
- } | undefined): void;
1012
- /**
1013
- * Extract a `RuntimeStreamEvent`-shaped `llm_call` from a sandbox event when
1014
- * the event carries usage/cost data. Returns `undefined` for non-cost events
1015
- * so the kernel can iterate the full stream without branching.
1016
- *
1017
- * Pure by contract: it never throws on a failed run. The terminal truth
1018
- * boundary is the public Sandbox outcome tracker, applied after the complete
1019
- * stream. Post-hoc readers — {@link sumSandboxUsage}, the
1020
- * analyst trace store, the chat projection — must stay able to read a failed
1021
- * turn's events, which is when reading them matters most.
1022
- *
1023
- * Canonical cost-carrying types observed in the wild:
1024
- * - `llm_call` — `data: { model, tokensIn, tokensOut, costUsd, ... }`
1025
- * - `message.completed` / `result` — `data: { usage: { inputTokens,
1026
- * outputTokens, totalCostUsd? } }`
1027
- * - `cost.usage` / `usage` — same shape under a dedicated type
1028
- *
1029
- * Numeric coercion is strict: `Number.isFinite` gates every accumulator write
1030
- * so a sentinel `NaN` from a misbehaving backend cannot poison the ledger.
1031
- */
1032
- declare function extractLlmCallEvent(event: SandboxEvent, agentRunName: string): (RuntimeStreamEvent & {
1033
- type: 'llm_call';
1034
- }) | undefined;
1035
- /**
1036
- * Per-turn usage accounting over BOTH the canonical events and the harness-native ones.
1037
- *
1038
- * Some harnesses report a turn's tokens only inside their own event (`harness-usage.ts`), and a
1039
- * stream may carry that report AND a canonical usage event for the same turn. Crediting both
1040
- * counts one turn twice, so this ledger holds the precedence rule: a canonical usage event WINS,
1041
- * and a harness-native report is credited only for a turn in which no canonical usage arrived.
1042
- *
1043
- * The harness-native report is held until the turn ends, because it can arrive before the
1044
- * canonical answer is known — codex emits `turn.completed` ahead of the terminal transport
1045
- * events. Call {@link SandboxUsageLedger.observe} for every event of a turn, then
1046
- * {@link SandboxUsageLedger.settleTurn} once at the turn boundary; settling also resets the
1047
- * ledger for the next turn, so one ledger serves a whole multi-turn session.
1048
- *
1049
- * The ledger never throws on a receipt it cannot read: `observe` returns a receipt with
1050
- * `tokensKnown: false` and `tokensUnknownReason`, so one policy serves every consumer.
1051
- */
1052
- interface SandboxUsageLedger {
1053
- /** Account one event. Returns the canonical usage receipt to credit now, if the event is one. */
1054
- observe(event: SandboxEvent, agentRunName: string): (RuntimeStreamEvent & {
1055
- type: 'llm_call';
1056
- }) | undefined;
1057
- /** End the turn. Returns the held harness-native receipt when no canonical usage arrived. */
1058
- settleTurn(agentRunName: string): (RuntimeStreamEvent & {
1059
- type: 'llm_call';
1060
- }) | undefined;
1061
- }
1062
- /** A {@link SandboxUsageLedger} for one worker. Pass the worker's harness to decode with that
1063
- * harness's adapter; omit it to try every registered adapter. */
1064
- declare function createSandboxUsageLedger(harness?: HarnessType): SandboxUsageLedger;
1065
- /**
1066
- * Sum the token usage + USD cost of a sandbox turn's events — the one honest way to meter an
1067
- * `openSandboxRun` cell. Folds a {@link SandboxUsageLedger} over the stream, so it reads usage off
1068
- * EVERY backend event shape — the canonical events plus a harness that reports usage only in its
1069
- * own event — and a `runProfileMatrix` dispatch can report it to `ctx.cost`:
1070
- *
1071
- * receipt: (turn) => {
1072
- * const u = sumSandboxUsage(turn.events)
1073
- * return { model, inputTokens: u.input, outputTokens: u.output,
1074
- * ...(u.tokensKnown === false ? { usageUnknown: true } : {}),
1075
- * ...(u.usdKnown !== false && u.costUsd > 0 ? { actualCostUsd: u.costUsd } : {}),
1076
- * ...(u.usdKnown === false ? { costUnknown: true } : {}),
1077
- * ...(u.estimatedCostUsd !== undefined ? { estimatedCostUsd: u.estimatedCostUsd } : {}) }
1078
- * }
1079
- *
1080
- * Without this a cell reads `{tokens:0, cost:0}` and the backend-integrity guard correctly aborts the
1081
- * matrix as a stub. `agentRunName` is the fallback model label for cost-only events (default `'agent'`).
1082
- *
1083
- * Pure by contract, like the ledger it folds: it never throws. A harness receipt the ledger cannot
1084
- * read leaves the result at `tokensKnown: false` with `tokensUnknownReason` carrying the decode
1085
- * message — an unreadable receipt is a different fact from a turn that reported no usage, and a
1086
- * post-hoc reader that threw would lose the whole failed turn it exists to report.
1087
- */
1088
- declare function sumSandboxUsage(events: readonly SandboxEvent[], agentRunName?: string): {
1089
- input: number;
1090
- output: number;
1091
- costUsd: number;
1092
- tokensKnown?: false;
1093
- usdKnown?: false;
1094
- estimatedCostUsd?: number;
1095
- tokensUnknownReason?: string;
1096
- };
1097
- /**
1098
- * Cross-event state for {@link mapSandboxToolEvent}. Sandbox backends emit a
1099
- * tool invocation as MANY `message.part.updated` frames on the same call id
1100
- * (pending → running → completed), so faithful projection needs per-call
1101
- * status memory: one `tool_call` on first sighting, at most one `tool_result`
1102
- * on the terminal transition, nothing on intermediate re-frames. Create one
1103
- * state per turn via {@link createSandboxToolPartState}.
1104
- *
1105
- * @experimental
1106
- */
1107
- interface SandboxToolPartState {
1108
- /** Last seen status per tool call id. A terminal status is sticky — later
1109
- * frames on a settled call project to nothing. */
1110
- statusByCall: Map<string, string>;
1111
- /** Sequence for synthesized call ids when an event carries none. */
1112
- seq: number;
1113
- }
1114
- /**
1115
- * Fresh per-turn {@link SandboxToolPartState} for {@link mapSandboxToolEvent} — an
1116
- * empty call-status map so each turn projects tool frames independently.
1117
- *
1118
- * @experimental
1119
- */
1120
- declare function createSandboxToolPartState(): SandboxToolPartState;
1121
- /**
1122
- * Project one `SandboxEvent` onto the `tool_call` / `tool_result` variants of
1123
- * `RuntimeStreamEvent` — the tool-part projection `mapSandboxEvent`
1124
- * deliberately does NOT perform. Opt-in and additive: `mapSandboxEvent`'s
1125
- * default vocabulary (text/reasoning deltas + `llm_call`) is unchanged;
1126
- * consumers that need the tool surface (chat UIs rendering tool activity)
1127
- * compose this projector alongside it — `streamAgentTurn` does exactly that
1128
- * under its `preserveToolParts` option.
1129
- *
1130
- * Handled shapes (observed on the opencode / claude-code sandbox backends):
1131
- * - `message.part.updated` with `part.type === 'tool'` — stateful: a
1132
- * `tool_call` on the call id's first frame (args from `state.input` or
1133
- * `state.metadata.input`), a `tool_result` when the status transitions to
1134
- * `completed` (result from `state.output` / `metadata.output`) or to a
1135
- * terminal failure (result is `{ error, status, output? }` — the error
1136
- * surfaced in-band, never dropped).
1137
- * - bare `tool*` event types (`tool.call`, `tool_result`, …) — stateless:
1138
- * `*result*` types project to `tool_result`, the rest to `tool_call`.
1139
- *
1140
- * Returns `[]` for every non-tool event.
1141
- *
1142
- * @experimental
1143
- */
1144
- declare function mapSandboxToolEvent(event: SandboxEvent, state: SandboxToolPartState): (RuntimeStreamEvent & {
1145
- type: 'tool_call' | 'tool_result';
1146
- })[];
1147
- /**
1148
- * Project one `SandboxEvent` onto the `RuntimeStreamEvent` chat-UX vocabulary,
1149
- * for runtimes that bridge a sandbox `streamPrompt` into the
1150
- * `AgentRuntime.act` streaming contract. Returns `undefined` for events that
1151
- * have no faithful projection — the raw stream is preserved separately for the
1152
- * `OutputAdapter`, so an unmapped event never loses data.
1153
- *
1154
- * Mapped (the task-optional incremental variants — no synthesized task
1155
- * lifecycle, no guessed tool-part shapes):
1156
- * - `message.part.updated` text part → `text_delta`
1157
- * - `message.part.updated` reasoning/thinking part → `reasoning_delta`
1158
- * - cost-bearing events → `llm_call` (shared with the ledger extractor)
1159
- *
1160
- * Tool parts are deliberately NOT mapped here (unchanged default) — compose
1161
- * {@link mapSandboxToolEvent} alongside when a consumer needs them.
1162
- *
1163
- * The opencode backend emits incremental text as
1164
- * `{ type: 'message.part.updated', data: { part: { type, text }, delta } }`;
1165
- * `delta` is the increment, `part.text` the running accumulation.
1166
- */
1167
- declare function mapSandboxEvent(event: SandboxEvent, opts?: {
1168
- agentRunName?: string;
1169
- }): RuntimeStreamEvent | undefined;
1170
- /**
1171
- * Project one `SandboxEvent` onto Runtime's executor progress vocabulary: incremental text and
1172
- * reasoning, tool calls and results, and an interaction request. It composes the existing
1173
- * projections ({@link mapSandboxEvent}, {@link mapSandboxToolEvent}, and the canonical Agent
1174
- * Interface decode) so every sandbox-shaped executor publishes live output through one reader.
1175
- * Usage-bearing events project to nothing here — accounting stays on the `tokens`/`cost`
1176
- * channels.
1177
- *
1178
- * Pass one {@link SandboxToolPartState} per turn so a multi-frame tool call yields one call and
1179
- * at most one result.
1180
- *
1181
- * @experimental
1182
- */
1183
- declare function sandboxProgressEvents(event: SandboxEvent, state: SandboxToolPartState): ExecutorProgressEvent[];
1184
- //#endregion
1185
- //#region src/runtime/sandbox-executor-output.d.ts
1186
- /**
1187
- * What a settled turn produced, as an explicit marker.
1188
- *
1189
- * `text` carries the byte length of the answer, `empty` says a text-bearing terminal event was
1190
- * observed and carried nothing, and `absent` says no text-bearing event was observed at all.
1191
- * The three are distinct on purpose: an empty settle blob used to be indistinguishable from lost
1192
- * output, so a reader could not tell a box that produced nothing from one whose answer never
1193
- * arrived.
1194
- */
1195
- type SandboxOutputMarker = {
1196
- readonly kind: 'text';
1197
- readonly bytes: number;
1198
- } | {
1199
- readonly kind: 'empty';
1200
- } | {
1201
- readonly kind: 'absent';
1202
- };
1203
- /** Parsed output of one Sandbox executor turn. */
1204
- interface SandboxLeafOut {
1205
- events: SandboxEvent[];
1206
- /** The observed answer. `undefined` when no text-bearing event was observed — never `''`. */
1207
- content: string | undefined;
1208
- /** Explicit account of what the turn produced. */
1209
- output: SandboxOutputMarker;
1210
- /**
1211
- * Provider and model the platform reported serving this turn, when it reported one. Absent means
1212
- * the platform said nothing; it is never filled from the request, because a request is not a
1213
- * receipt.
1214
- */
1215
- servedBackend?: SandboxServedBackend;
1216
- toolCalls?: ExecutorToolCall[];
1217
- outcome?: AgentRunOutcome;
1218
- }
1219
- //#endregion
1220
- //#region src/runtime/supervise/inbox.d.ts
1221
- /** A message from the run's AUTHORITY — the parent driver. These two kinds carry instruction. */
1222
- interface AuthorityInboxMessage {
1223
- readonly kind: 'steer' | 'answer';
1224
- readonly text: string;
1225
- /** Forceful messages abort the in-flight turn; queued ones wait for the boundary flush. */
1226
- readonly interrupt: boolean;
1227
- /** Present for an `answer` — the question id it resolves. */
1228
- readonly questionId?: string;
1229
- }
1230
- /** A message from a SIBLING worker. Information, never instruction — the parent stays the only
1231
- * authority over this worker's task. */
1232
- interface PeerInboxMessage {
1233
- readonly kind: 'mail';
1234
- readonly text: string;
1235
- /** Always false. Peer mail is queued by construction; see this file's header. */
1236
- readonly interrupt: false;
1237
- readonly envelope: PeerMailEnvelope;
1238
- }
1239
- type InboxMessage = AuthorityInboxMessage | PeerInboxMessage;
1240
- interface Inbox {
1241
- /** The `Executor.deliver` implementation. Returns false when the raw message is malformed and
1242
- * therefore was not queued; callers must not acknowledge a message this inbox discarded. */
1243
- deliver(msg: unknown): boolean;
1244
- /** Remove and return all pending messages (the flush). */
1245
- drain(): InboxMessage[];
1246
- pending(): number;
1247
- /** Pending messages from the run's AUTHORITY only. This is what the pre-settle fence counts:
1248
- * a worker may not finish while a steer or answer it never read is queued, but peer mail must
1249
- * never be able to hold a finished worker open. */
1250
- pendingAuthority(): number;
1251
- /** Open a fresh per-turn interrupt signal; a later forceful `deliver` aborts it. The loop links
1252
- * this into the signal it passes to its inference call, then re-plans when it fires. */
1253
- freshInterrupt(): AbortSignal;
1254
- /** Render drained messages as ONE operator turn to fold into the worker's conversation. */
1255
- fold(messages: ReadonlyArray<InboxMessage>): string;
1256
- }
1257
- /** Create the worker-side inbox for the down-leg: the driver's `steer_agent` / `answer_question` messages and a sibling's peer mail queue here, and the worker's loop drains them at step boundaries and before settle. */
1258
- declare function createInbox(): Inbox;
1259
- //#endregion
1260
- //#region src/runtime/supervise/sandbox-session.d.ts
1261
- /** Ceiling on continuation turns. Turn 0 is the task; every later turn is a folded steer, so
1262
- * this bounds how many times a supervisor may redirect ONE worker before it must respawn. */
1263
- declare const DEFAULT_SANDBOX_STEERING_MAX_TURNS = 24;
1264
- /** Opt-in configuration for the steerable sandbox worker (`SandboxSeam.steering`). Absent, the
1265
- * sandbox executor keeps its historical single-shot `runAgentRounds` composition verbatim. */
1266
- interface SandboxSteeringOptions {
1267
- /** Max turns for one worker (turn 0 + folded steers). Default {@link DEFAULT_SANDBOX_STEERING_MAX_TURNS}. */
1268
- readonly maxTurns?: number;
1269
- /** How many recent tool/turn notes `progress()` reports. Default 12. */
1270
- readonly activityWindow?: number;
1271
- /** Per-turn wall-clock ceiling; the turn's stream is aborted when it elapses. */
1272
- readonly turnTimeoutMs?: number;
1273
- }
1274
- /** What the steerable session exposes to its executor: the usage stream plus the live reads. */
1275
- interface SteerableSandboxSession {
1276
- /** Drive the worker to settlement. `signal` is the spawn-scoped abort handed to `execute`. */
1277
- stream(task: unknown, signal: AbortSignal): AsyncIterable<UsageEvent>;
1278
- progress(): ExecutorProgress;
1279
- /** Ask the box to stop the running execution on this exact session and report what it answered. */
1280
- cancel(request: ExecutorCancellationRequest): Promise<ExecutorCancellation>;
1281
- traceSource(): TraceSource;
1282
- artifact(): {
1283
- outRef: string;
1284
- out: unknown;
1285
- verdict?: DefaultVerdict;
1286
- spent: Spend;
1287
- } | undefined;
1288
- teardown(): Promise<void>;
1289
- }
1290
- interface SteerableSandboxArgs {
1291
- readonly controller: AbortController;
1292
- readonly profile: AgentProfile;
1293
- readonly harness: BackendType;
1294
- readonly sandboxClient: SandboxClient;
1295
- readonly inbox: Inbox;
1296
- readonly taskToPrompt: (task: unknown) => string;
1297
- readonly options?: SandboxSteeringOptions;
1298
- readonly loopCtx?: Partial<Omit<ExecCtx, 'sandboxClient' | 'signal'>>;
1299
- /**
1300
- * Inherited `TRACE_ID` / `PARENT_SPAN_ID` for the box, merged into `CreateSandboxOptions.env` so
1301
- * the remote worker's own spans join the supervisor's trace under the spawning node's span.
1302
- * Absent when the run records no spans — the create options are then untouched.
1303
- */
1304
- readonly traceEnv?: Record<string, string>;
1305
- readonly contentRef: (prefix: string, value: unknown) => string;
1306
- readonly now?: () => number;
1307
- }
1308
- /** One steerable sandbox worker. The returned session is inert until `stream()` is drained. */
1309
- declare function createSteerableSandboxSession(args: SteerableSandboxArgs): SteerableSandboxSession;
1310
- //#endregion
1311
- //#region src/runtime/supervise/runtime.d.ts
1312
- /**
1313
- * Router/inline transport seam. The profile owns model, prompt, and generation behavior.
1314
- */
1315
- interface RouterSeam {
1316
- routerBaseUrl: string;
1317
- routerKey: string;
1318
- /** Injectable transport for offline/local execution; still passes through Runtime metering. */
1319
- complete?: RouterConfig['complete'];
1320
- /** When present, return one turn's requested tool calls without executing them. */
1321
- tools?: ReadonlyArray<ToolSpec>;
1322
- }
1323
- /**
1324
- * Sandbox executor seam. The `sandboxClient` the composed `runAgentRounds` creates
1325
- * boxes through, plus the optional trace/run/lineage wiring forwarded into the
1326
- * loop. `lineage` is opaque here (PR #150's `RunAgentRoundsOptions.lineage`): forwarded
1327
- * forward-compatibly, never inspected — this executor does NOT reinvent
1328
- * checkpoint/fork.
1329
- */
1330
- interface SandboxSeam {
1331
- sandboxClient: SandboxClient;
1332
- /** Forwarded into the composed `runAgentRounds`'s `ctx` (trace emitter, run handle, etc.). */
1333
- loopCtx?: Partial<Omit<ExecCtx, 'sandboxClient' | 'signal'>>;
1334
- /** PR #150 `RunAgentRoundsOptions.lineage` passthrough — opaque; forwarded, not parsed. */
1335
- lineage?: unknown;
1336
- /** Hard cap on the composed loop's iterations. The budget pool reserves against
1337
- * the spawn `Budget.maxIterations`; this is the leaf's own ceiling. Default 1. */
1338
- maxIterations?: number;
1339
- /**
1340
- * OPT-IN executable score for this worker. Forwarded to the composed
1341
- * `runAgentRounds` as its `validator`, so the kernel calls `validate` while the
1342
- * iteration's box is still alive: `ValidationCtx.box` is a LIVE `SandboxInstance`
1343
- * and the check can run commands or read files in the container it is scoring.
1344
- * Every other supervised hook fires after teardown and can only read the artifact.
1345
- *
1346
- * The resulting verdict becomes the winner's verdict, which this executor already
1347
- * surfaces on its `ExecutorResult`. Absent, nothing changes: the loop runs
1348
- * unscored and the leaf falls back to its own settle verdict.
1349
- *
1350
- * Not representable with `steering` — a steerable session is a multi-turn session
1351
- * on one box, not a `runAgentRounds` composition, so the pair is rejected instead
1352
- * of silently dropping the score.
1353
- */
1354
- validator?: Validator<SandboxLeafOut>;
1355
- /**
1356
- * OPT-IN: run this worker as a multi-turn, STEERABLE session instead of the historical
1357
- * single-shot `runAgentRounds` composition. Setting it gives the sandbox worker an `Executor.deliver`
1358
- * inbox (so `Scope.send` / `steer_agent` actually reach it), a live tool-activity trace, and a
1359
- * `progress()` read — turning the default cloud worker from something a supervisor can only
1360
- * wait on into something it can watch and correct.
1361
- *
1362
- * Absent, nothing changes: the same `runAgentRounds` leaf, no inbox, `steer_agent` still reports
1363
- * `delivered:false`. Opt-in because a steerable worker holds ONE box across several turns,
1364
- * which is a different resource profile from a fire-and-forget shot.
1365
- */
1366
- steering?: SandboxSteeringOptions;
1367
- }
1368
- /**
1369
- * UNMETERED CLI subprocess seam. `bin` + `args` describe the process to spawn.
1370
- *
1371
- * READ THIS BEFORE CHOOSING `backend: 'cli'`. This backend pipes a prompt to a subprocess's stdin
1372
- * and reads its stdout. It has no usage receipt of any kind, so it reports its spend with
1373
- * `Spend.tokensKnown: false`: the work is recorded, its `{0,0}` tokens and `$0` are a FLOOR rather
1374
- * than a measurement, and a ceiling priced from either is a ceiling that cannot fire. The executor
1375
- * is also `budgetExempt: true`, which is why `driveHarnessFromBackend` refuses it outright rather
1376
- * than pretending to budget it.
1377
- *
1378
- * If you need a metered harness worker, use `backend: 'bridge'` (a cli-bridge session, which
1379
- * reports the harness's real per-turn tokens and cost) or `backend: 'cli-worktree'` with
1380
- * `codexReproducible`. Reach for this seam only when the subprocess genuinely is not an inference
1381
- * agent, or when you have accepted that its cost is invisible.
1382
- *
1383
- * `args` is argv for a LOCAL, in-process spawn under this process's own privileges. It is not a
1384
- * remote channel and nothing forwards it over a wire.
1385
- */
1386
- interface CliSeam {
1387
- bin: string;
1388
- args?: string[];
1389
- /** Extra environment for the subprocess (merged over `process.env`). */
1390
- env?: Record<string, string>;
1391
- /** Working directory for the subprocess. */
1392
- cwd?: string;
1393
- }
1394
- /**
1395
- * cli-worktree seam. A supervisor-authored `AgentProfile` driving a local coding-harness CLI
1396
- * (claude / codex / opencode) on its own git worktree — the leaf `createWorktreeCliExecutor`
1397
- * named as data. `repoRoot` is transport data; `AgentProfile.harness` selects the CLI.
1398
- * `taskPrompt` remains an optional direct-call fallback for callers that execute with `undefined`.
1399
- * The authored
1400
- * `profile.prompt.systemPrompt` + `profile.model.default` reach the harness via the §1.5
1401
- * `harnessInvocation` mapper. Everything else mirrors `WorktreeCliExecutorOptions`.
1402
- */
1403
- interface CliWorktreeSeam {
1404
- repoRoot: string;
1405
- taskPrompt?: string;
1406
- runId?: string;
1407
- baseRef?: string;
1408
- harnessTimeoutMs?: number;
1409
- /** Isolated, network-off Codex execution with terminal JSONL usage capture. */
1410
- codexReproducible?: boolean;
1411
- /** Absolute host paths denied to reproducible Codex. */
1412
- codexReadDeniedPaths?: ReadonlyArray<string>;
1413
- testCmd?: string;
1414
- typecheckCmd?: string;
1415
- checkTimeoutMs?: number;
1416
- checkOutputCap?: number;
1417
- budgetExempt?: boolean;
1418
- /** Live cli-bridge transport inside the worktree. When set, the worktree leaf accepts
1419
- * `deliver()` messages and resumes the same bridge session in this worktree cwd. */
1420
- bridge?: CliWorktreeBridgeSeam;
1421
- /** Test seam — forwarded to worktree helpers. */
1422
- runGit?: GitRunner;
1423
- /** Test seam — forwarded to verification checks. */
1424
- runCommand?: WorktreeCheckRunner;
1425
- }
1426
- /**
1427
- * cli-in-place seam. A supervisor-authored `AgentProfile` driving a local coding-harness CLI
1428
- * (claude-code / codex / opencode / pi) on a workspace the CALLER supplies — the leaf
1429
- * `createInPlaceCliExecutor` named as data. `workspacePath` is transport data;
1430
- * `AgentProfile.harness` selects the CLI, and the authored `profile.prompt.systemPrompt` +
1431
- * `profile.model.default` reach the harness via the §1.5 `harnessInvocation` mapper.
1432
- *
1433
- * READ THIS BEFORE CHOOSING BETWEEN THIS AND `cli-worktree`. They differ in ONE thing, and it is
1434
- * the thing that decides which one a caller wants:
1435
- *
1436
- * - `cli-worktree` cuts a git worktree of its OWN off `repoRoot`, runs the harness there,
1437
- * returns the captured patch, and removes the worktree at teardown. The directory it was
1438
- * given is never edited. That is correct for a fanout of N candidate authors that must not
1439
- * clobber each other, and for a caller whose deliverable IS the patch.
1440
- * - `cli-in-place` runs the harness in `workspacePath` itself. The edits stay in that directory
1441
- * after the call, so the NEXT call sees them. That is what a caller needs when the workspace
1442
- * has to persist between calls — a multi-shot author resuming on top of its own edits
1443
- * (`agenticGenerator`), or a candidate directory the caller commits itself.
1444
- *
1445
- * Because the workspace persists, so would the profile inputs this path materializes into it. They
1446
- * are removed before the call returns, so the directory a caller inspects afterwards holds the
1447
- * harness's own edits and nothing else, and a `git status` over it answers "did the author change
1448
- * anything" rather than "did Runtime write a settings file".
1449
- *
1450
- * There is no reproducible-Codex mode here: that mode stages an executable and a write probe INTO
1451
- * its working directory, which a caller-owned workspace is not the place for. Use `cli-worktree`
1452
- * with `codexReproducible` when the isolated, metered Codex run is what you want.
1453
- */
1454
- interface CliInPlaceSeam {
1455
- /** Absolute path to the EXISTING directory the harness edits. Runtime never creates, cleans, or
1456
- * removes it. */
1457
- workspacePath: string;
1458
- taskPrompt?: string;
1459
- harnessTimeoutMs?: number;
1460
- /** Test seam — inject the harness runner so unit tests script a `LocalHarnessResult`. */
1461
- runHarness?: typeof runLocalHarness;
1462
- }
1463
- interface CliWorktreeBridgeSeam {
1464
- bridgeUrl: string;
1465
- bridgeBearer: string;
1466
- /** Caller-owned deadline for each bridge turn. Runtime enforces it locally and sends the
1467
- * same value in `execution.timeoutMs` so cli-bridge cannot substitute its own cutoff. */
1468
- timeoutMs?: number;
1469
- /** Stable cli-bridge session id. Defaults to `bridge-worktree-${runId}`. */
1470
- sessionId?: string;
1471
- /** Transport reconnects allowed after the first POST. Default 3; set 0 to disable. */
1472
- maxReconnects?: number;
1473
- }
1474
- /**
1475
- * cli-bridge seam. A local OpenAI-compatible bridge that fronts harness CLIs
1476
- * (claude-code / opencode / kimi / pi) behind one HTTP surface. The spawned
1477
- * `AgentProfile` is the sole harness/provider/model and behavioral authority and
1478
- * is forwarded verbatim per request; this seam carries transport data only.
1479
- *
1480
- * The executor opens a resumable cli-bridge session. `sessionId` identifies the
1481
- * harness conversation across turns; each turn also receives its own durable run id.
1482
- * A dropped HTTP reader reattaches to that exact run and explicit cancel is the only
1483
- * operation allowed to stop it. Omit `sessionId` and the executor mints one per spawn.
1484
- *
1485
- * ── HOW TO CONTROL WHAT THE HARNESS LOADS (there is no argv field, by design) ──
1486
- *
1487
- * A worker often needs the harness started in a KNOWN state — no ambient extensions, skills,
1488
- * context files, or prompt templates — because ambient state is how a paired experiment silently
1489
- * loses its pairing: an installed extension that persists memory across runs carries arm A's state
1490
- * into arm B, and nothing reports it.
1491
- *
1492
- * That is what the spawned `AgentProfile` is FOR. `agent_profile`
1493
- * rides every request verbatim, and cli-bridge maps it onto each harness's own native controls:
1494
- *
1495
- * - Materializing any profile at all already starts the harness isolated from ambient
1496
- * workspace state — for pi that is `--no-context-files --no-skills --no-prompt-templates`,
1497
- * applied to every request that carries an `agent_profile`.
1498
- * - `AgentProfile.extensions.<harness>` is the named, per-harness control channel. An explicit
1499
- * `extensions: { pi: { load: [] } }` disables ambient extension discovery outright
1500
- * (pi's `--no-extensions`); listing package names loads exactly those and nothing else.
1501
- * - `permissions` / `tools` / `mcp` map onto the harness's native tool and server controls.
1502
- *
1503
- * A caller therefore does NOT need to hand-roll an `Executor` to isolate a harness run, and the
1504
- * profile expressing it stays portable: the same declaration means the same thing on a different
1505
- * harness, whereas an argv string means nothing anywhere else.
1506
- *
1507
- * WHY NOT A GENERAL ARGV PASSTHROUGH. `bridgeUrl` addresses a process-spawning server. Forwarding
1508
- * an arbitrary argv array to it would let any caller holding a bearer token choose the flags of a
1509
- * process on the bridge host — which for real harness CLIs includes flags that load code from a
1510
- * path, read a file into the prompt, redirect the working directory, or turn off the isolation the
1511
- * bridge applies. cli-bridge deliberately confines workers (a filesystem jail and deny-by-default
1512
- * network egress), and every one of those confinements is expressed as spawn configuration, so an
1513
- * argv channel is a channel for unwinding them. It would also break this executor's own contract:
1514
- * the durable-run replay protocol, session pinning, and streaming mode are all argv the bridge
1515
- * owns, and a caller-supplied duplicate silently wins or corrupts the parse. The structured profile
1516
- * channel is validated, per-harness, portable, and refuses controls it does not understand — keep
1517
- * new harness capability there.
1518
- */
1519
- interface BridgeSeam {
1520
- bridgeUrl: string;
1521
- bridgeBearer: string;
1522
- /**
1523
- * Optional request-scoped model credential.
1524
- *
1525
- * The key name is portable configuration. The provider is a live service and is intentionally
1526
- * not serialised. Runtime resolves both values immediately before every bridge POST and sends
1527
- * them only to a loopback bridge through private request headers.
1528
- */
1529
- modelCredential?: BridgeModelCredential;
1530
- /** Optional working directory forwarded to cli-bridge and persisted with the session. */
1531
- cwd?: string;
1532
- /**
1533
- * The harness's OWN on-disk session store, read as a spend receipt.
1534
- *
1535
- * cli-bridge forwards no token usage for a codex worker, so a turn whose provider counters exist
1536
- * only in codex's rollout meters `{0, 0}` with `tokensKnown: false`. Measured on one live seat
1537
- * (discovery#80): 9 of 9 `metered` events read zero while 27,320,482 codex tokens sat in the same
1538
- * run directory, 1,453,948 of them belonging to harness-native children the journal never saw.
1539
- *
1540
- * Naming the store here turns those rows into evidence. The executor tails it once per turn and
1541
- * credits the DELTA, so each turn is charged once, and it reports the counters with
1542
- * `provenance: 'harness-store'` so a reader can tell a disk receipt from a stream receipt.
1543
- *
1544
- * The path must be the run's OWN isolated store. An ambient host store credits this run with
1545
- * another run's files, and `workspaceRoot` is the structural guard against it.
1546
- */
1547
- harnessStore?: BridgeHarnessStore;
1548
- /** Caller-owned deadline for each bridge turn. Runtime enforces it locally and sends the
1549
- * same value in `execution.timeoutMs` so the bridge-owned process follows the same policy. */
1550
- timeoutMs?: number;
1551
- /** Stable, caller-owned cli-bridge session id for harness-side resume. Defaults
1552
- * to a freshly minted per-spawn id so each worker is its own resumable session. */
1553
- sessionId?: string;
1554
- /** Transport reconnects allowed after the first POST. Default 3; set 0 to disable. */
1555
- maxReconnects?: number;
1556
- /** Newest-last activity window `progress()` reports. Default 12. */
1557
- activityWindow?: number;
1558
- }
1559
- /**
1560
- * A harness's own session store on the bridge host, named so the runtime may read it.
1561
- *
1562
- * Only `codex` has a reader today. Any other harness is REFUSED rather than read with codex's
1563
- * decoder: a different harness's file decoded as a codex rollout would either drop counters it does
1564
- * not name or credit a number that is about the wrong wire shape.
1565
- */
1566
- interface BridgeHarnessStore extends CodexRolloutStoreRef {
1567
- /** The harness family that wrote the store. */
1568
- readonly harness: HarnessType;
1569
- }
1570
- /** A live, request-scoped model credential reference for a local cli-bridge. */
1571
- interface BridgeModelCredential {
1572
- /** Provider key name for the scoped model token. */
1573
- key: string;
1574
- /** Provider key name for the exact scoped HTTPS model gateway URL. */
1575
- baseUrlKey: string;
1576
- /** Live credential service. Runtime retains this reference through reusable captures. */
1577
- provider: KeyProvider;
1578
- }
1579
- /**
1580
- * Generic environment provider executor config. External packages implement
1581
- * `AgentEnvironmentProvider`; this built-in wrapper lets `createExecutor` consume them as backend
1582
- * data while preserving the existing usage channel. Runtime depends on no provider package, so a
1583
- * Tangle provider and a hand-written one compose identically. Worked wiring:
1584
- * `examples/provider-executor/`.
1585
- *
1586
- * Everything a create needs travels on `CreateAgentEnvironmentInput` through
1587
- * {@link ProviderExecutorOptions.defaults}; everything one turn needs travels on
1588
- * {@link ProviderExecutorOptions.promptOptions}. Wrapping the provider's own client to reach a
1589
- * field is what this seam exists to replace: the wrapper is invisible to Runtime, so its options
1590
- * are absent from every record the run produces.
1591
- *
1592
- * READINESS IS THE PROVIDER'S CONTRACT. `provider.create` resolves with an environment that can
1593
- * take a turn, so this seam streams straight into it and adds no readiness wait of its own. The
1594
- * sandbox seam's `acquireSandbox` exists because a raw `SandboxClient.create` returns before the
1595
- * box is ready; a second poll here would hide a provider that does not honor the contract, and
1596
- * that provider is an upstream defect to report rather than a race to paper over.
1597
- */
1598
- interface ProviderSeam extends ProviderExecutorOptions {
1599
- provider: AgentEnvironmentProvider | string;
1600
- registry?: AgentEnvironmentProviderRegistry;
1601
- /**
1602
- * Compose the provider through the existing steerable sandbox session.
1603
- * The exact profile must name its harness, and the provider must expose live
1604
- * continuation plus session controls. The provider still owns environment
1605
- * creation and session semantics.
1606
- */
1607
- steering?: SandboxSteeringOptions;
1608
- }
1609
- /**
1610
- * Router seam WITH tool use — the tool-using router backend. Same direct
1611
- * OpenAI-compatible endpoint as `RouterSeam`, but each turn passes `tools`; when
1612
- * the model emits tool_calls they run via `executeToolCall` ON THIS HOST and the
1613
- * results fold back as `tool` messages, repeating until the model answers without
1614
- * a tool or `maxTurns` is hit. A real agentic loop, OFF-BOX — no sandbox, so it
1615
- * is unaffected by a box's egress allowlist. One turn = one completion = the
1616
- * equal-compute unit. `executeToolCall` receives the task so per-task tool
1617
- * surfaces (e.g. a gym keyed by task) can dispatch correctly.
1618
- */
1619
- interface RouterToolsSeam {
1620
- routerBaseUrl: string;
1621
- routerKey: string;
1622
- complete?: RouterConfig['complete'];
1623
- tools: ReadonlyArray<ToolSpec>;
1624
- executeToolCall: (name: string, args: Record<string, unknown>, task: unknown) => Promise<string>;
1625
- /** Exact conversation to continue. Runtime validates its system message against the profile. */
1626
- initialMessages?: ReadonlyArray<Readonly<Record<string, unknown>>>;
1627
- /** Observe the detached final conversation for session persistence. */
1628
- onMessages?: (messages: ReadonlyArray<Readonly<Record<string, unknown>>>) => void | Promise<void>;
1629
- /** Online observer of each tool step — the seam a `DetectorMonitor` taps to watch the live pipe
1630
- * (raise a `finding` when the worker loops/errors). Called after every tool call resolves, with
1631
- * real per-call wall-clock (`startedAt`/`endedAt`/`durationMs`) so a push `TraceSource` can carry
1632
- * non-zero span durations onto the unified timeline. */
1633
- onToolStep?: (step: {
1634
- toolName: string;
1635
- args: Record<string, unknown>;
1636
- status: 'ok' | 'error';
1637
- startedAt?: number;
1638
- endedAt?: number;
1639
- durationMs?: number;
1640
- }) => void;
1641
- }
1642
- /**
1643
- * The leaf `createWorktreeCliExecutor` as a backend-as-data factory: a supervisor-authored
1644
- * `AgentProfile` driving claude / codex / opencode on its own worktree. `budgetExempt` like
1645
- * the other CLI leaves; the authored systemPrompt + model reach the harness via §1.5.
1646
- */
1647
- declare const cliWorktreeExecutor: ExecutorFactory<unknown>;
1648
- /**
1649
- * The leaf `createInPlaceCliExecutor` as a backend-as-data factory: a supervisor-authored
1650
- * `AgentProfile` driving a local coding CLI in the workspace the caller supplied, so its edits are
1651
- * still there for the next spawn. `budgetExempt` like the other CLI leaves; the authored
1652
- * systemPrompt + model reach the harness via §1.5.
1653
- */
1654
- declare const cliInPlaceExecutor: ExecutorFactory<unknown>;
1655
- /**
1656
- * Config for {@link createExecutor}: the backend is DATA — the cost dial a profile,
1657
- * an experiment config, or a replay journal can name — not an import choice. Each
1658
- * variant carries its backend's seam.
1659
- */
1660
- type ExecutorConfig = ({
1661
- backend: 'router';
1662
- } & RouterSeam) | ({
1663
- backend: 'router-tools';
1664
- } & RouterToolsSeam) | ({
1665
- backend: 'bridge';
1666
- } & BridgeSeam) | ({
1667
- backend: 'cli';
1668
- } & CliSeam) | ({
1669
- backend: 'cli-worktree';
1670
- } & CliWorktreeSeam) | ({
1671
- backend: 'cli-in-place';
1672
- } & CliInPlaceSeam) | ({
1673
- backend: 'provider';
1674
- } & ProviderSeam) | ({
1675
- backend: 'sandbox';
1676
- } & SandboxSeam);
1677
- /**
1678
- * The single built-in executor factory. Picks a leaf backend by data (`config.backend`),
1679
- * injects the matching seam, and delegates to that backend's built-in implementation.
1680
- * The `Executor` port stays OPEN: bring-your-own agents implement `Executor` directly, while Scope
1681
- * or `createExecutorRegistry` still parses and seals their exact profile before use. Use this instead of a
1682
- * per-vendor adapter or a closed `inline|sandbox|cli` switch — those bypass the
1683
- * `UsageEvent` reporting channel.
1684
- */
1685
- declare function createExecutor(config: ExecutorConfig): ExecutorFactory<unknown>;
1686
- /**
1687
- * The open resolver/registry. Pre-registers the three built-ins under their
1688
- * runtime tags (`'router'`, `'sandbox'`, `'cli'`) and accepts `register(name,
1689
- * factory)` for any additional runtime. A BYO `AgentSpec.executor` has highest routing precedence
1690
- * after the same exact-profile intake validation. Registration + BYO remain open extension points.
1691
- *
1692
- * `resolve` precedence (frozen in `ExecutorRegistry`): a BYO `spec.executorFactory` →
1693
- * `spec.executor` → `harness === null` → the `'router'` factory; else a registered factory for the
1694
- * harness-derived runtime (`'sandbox'` for any `BackendType`); else fail loud.
1695
- */
1696
- declare function createExecutorRegistry(): ExecutorRegistry;
1697
- //#endregion
1698
- export { CodexRolloutTurn as $, PeerMailboxOptions as $t, SandboxToolPartState as A, localHarnessExecutable as At, sumSandboxUsage as B, ToolLoopToolCall as Bt, Inbox as C, CodexTokenUsage as Ct, SandboxLeafOut as D, LocalHarnessResult as Dt, createInbox as E, LocalHarness as Et, extractLlmCallEvent as F, ToolLoopCallContext as Ft, resolveMcpServerLaunch as G, PeerMailEvent as Gt, ResolvedMcpServerLaunch as H, DEFAULT_PEER_MAIL_LIMITS as Ht, mapSandboxEvent as I, ToolLoopChat as It, CodexForkBoundary as J, PeerMailOutcome as Jt, resolveSecretEnv as K, PeerMailKind as Kt, mapSandboxToolEvent as L, ToolLoopCompaction as Lt, assertSandboxServedModel as M, runLocalHarness as Mt, createSandboxToolPartState as N, RouterTransportConfig as Nt, SandboxOutputMarker as O, RunLocalHarnessOptions as Ot, createSandboxUsageLedger as P, ToolSpec as Pt, CodexRolloutStoreRef as Q, PeerMailbox as Qt, sandboxEventServedBackend as R, ToolLoopCompactionOptions as Rt, AuthorityInboxMessage as S, CodexExecutionPolicy as St, PeerInboxMessage as T, LOCAL_HARNESSES as Tt, envKeyProvider as U, PEER_MAIL_WIRE_KEY as Ut, KeyProvider as V, AUTHORITY_MARKERS as Vt, mcpSecretEnvMetadataKey as W, PeerMailEnvelope as Wt, CodexRolloutSession as X, PeerMailRefusal as Xt, CodexRolloutIdentity as Y, PeerMailReadout as Yt, CodexRolloutStoreReader as Z, PeerMailSendInput as Zt, DEFAULT_SANDBOX_STEERING_MAX_TURNS as _, WorktreeHandle as _t, CliSeam as a, JsonRpcMessage as an, HarnessUsage as at, SteerableSandboxSession as b, removeWorktree as bt, ExecutorConfig as c, McpTransport as cn, WorktreeCheckRunner as ct, RouterToolsSeam as d, WorktreeProfileMaterializationReceipt as dt, claimsAuthority as en, CodexStoreDelta as et, SandboxSeam as f, CreateWorktreeOptions as ft, createExecutorRegistry as g, RemoveWorktreeOptions as gt, createExecutor as h, GitRunner as ht, CliInPlaceSeam as i, peerMailVerbNames as in, readCodexRolloutSession as it, SandboxUsageLedger as j, parseCodexTokenUsage as jt, SandboxServedBackend as k, harnessSupportsReasoningEffort as kt, ProviderSeam as l, WorktreeCommandResult as lt, cliWorktreeExecutor as m, DiffResult as mt, BridgeModelCredential as n, isPeerMailEnvelope as nn, createCodexRolloutStoreReader as nt, CliWorktreeBridgeSeam as o, JsonRpcResponse as on, decodeHarnessUsage as ot, cliInPlaceExecutor as p, DiffOptions as pt, secretEnvOfMcpServer as q, PeerMailLimits as qt, BridgeSeam as r, peerMailTools as rn, harnessUsageIsEmpty as rt, CliWorktreeSeam as s, McpToolDescriptor as sn, InPlaceHarnessResult as st, BridgeHarnessStore as t, createPeerMailbox as tn, addHarnessUsage as tt, RouterSeam as u, WorktreeHarnessResult as ut, SandboxSteeringOptions as v, captureWorktreeDiff as vt, InboxMessage as w, DEFAULT_LOCAL_HARNESS as wt, createSteerableSandboxSession as x, CodexExecutionEvidence as xt, SteerableSandboxArgs as y, createWorktree as yt, sandboxProgressEvents as z, ToolLoopMessageRecord as zt };
1699
- //# sourceMappingURL=runtime-0xNaV6TJ.d.ts.map