@tangle-network/agent-runtime 0.142.3 → 0.143.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{activation-o7JKmtxi.js → activation-mi8TgSLM.js} +2 -2
- package/dist/{activation-o7JKmtxi.js.map → activation-mi8TgSLM.js.map} +1 -1
- package/dist/agent.d.ts +2 -2
- package/dist/agent.js +3 -3
- package/dist/{analyst-loop-GcX0BY75.js → analyst-loop-CvkmfhUB.js} +2 -2
- package/dist/{analyst-loop-GcX0BY75.js.map → analyst-loop-CvkmfhUB.js.map} +1 -1
- package/dist/analyst-loop.d.ts +1 -1
- package/dist/analyst-loop.js +1 -1
- package/dist/{authoring-Bm1WlGPv.js → authoring-DuyShLdw.js} +2 -2
- package/dist/{authoring-Bm1WlGPv.js.map → authoring-DuyShLdw.js.map} +1 -1
- package/dist/{conversation-DXKJHyqB.js → conversation-1hNtDeMM.js} +3 -3
- package/dist/{conversation-DXKJHyqB.js.map → conversation-1hNtDeMM.js.map} +1 -1
- package/dist/conversation.d.ts +1 -1
- package/dist/conversation.js +1 -1
- package/dist/durable.d.ts +2 -2
- package/dist/durable.js +1 -1
- package/dist/{environment-provider-BicwCDK5.d.ts → environment-provider-B8eZ85Ga.d.ts} +3 -3
- package/dist/{environment-provider-DCEACNt9.js → environment-provider-DCBJ13VP.js} +2 -2
- package/dist/{environment-provider-DCEACNt9.js.map → environment-provider-DCBJ13VP.js.map} +1 -1
- package/dist/environment-provider.d.ts +1 -1
- package/dist/environment-provider.js +1 -1
- package/dist/{graph-DhrLuLOS.js → graph-De_XEsfH.js} +2 -2
- package/dist/{graph-DhrLuLOS.js.map → graph-De_XEsfH.js.map} +1 -1
- package/dist/{improvement-cycle-lcwlR6E2.js → improvement-cycle-Bi-Tf4QF.js} +5 -5
- package/dist/{improvement-cycle-lcwlR6E2.js.map → improvement-cycle-Bi-Tf4QF.js.map} +1 -1
- package/dist/{index-Bx3-tqG-.d.ts → index-B8rKtH3U.d.ts} +4 -4
- package/dist/{index-D_aH0F4C.d.ts → index-C2caGomG.d.ts} +12 -27
- package/dist/{index-CV1xRWy2.d.ts → index-D4sLkOPY.d.ts} +3 -3
- package/dist/index.d.ts +9 -9
- package/dist/index.js +9 -9
- package/dist/intelligence.d.ts +5 -5
- package/dist/intelligence.js +4 -4
- package/dist/kernel.d.ts +7 -7
- package/dist/kernel.js +10 -10
- package/dist/{knowledge-C9LlSJAR.js → knowledge-CVE6Wk1i.js} +3 -3
- package/dist/{knowledge-C9LlSJAR.js.map → knowledge-CVE6Wk1i.js.map} +1 -1
- package/dist/knowledge.d.ts +1 -1
- package/dist/knowledge.js +1 -1
- package/dist/{loop-runner-bin-CctBy5-X.d.ts → loop-runner-bin-BoHdQqLm.d.ts} +3 -3
- package/dist/{loop-runner-bin-DFo6Ss-1.js → loop-runner-bin-DdaI1nLL.js} +4 -4
- package/dist/{loop-runner-bin-DFo6Ss-1.js.map → loop-runner-bin-DdaI1nLL.js.map} +1 -1
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/{materialization-CrdcfWXp.js → materialization-P86EciBw.js} +43 -2
- package/dist/materialization-P86EciBw.js.map +1 -0
- package/dist/mcp/bin.js +3 -3
- package/dist/mcp/index.d.ts +5 -5
- package/dist/mcp/index.js +4 -4
- package/dist/{openai-tools-CSm460sC.js → openai-tools-BiAWKjh6.js} +2 -2
- package/dist/{openai-tools-CSm460sC.js.map → openai-tools-BiAWKjh6.js.map} +1 -1
- package/dist/{openai-tools-t5-6h5bj.d.ts → openai-tools-z-whdYNC.d.ts} +2 -2
- package/dist/primeintellect/index.d.ts +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/{redact-B0gDSTZO.d.ts → redact-DexTuAiX.d.ts} +3 -3
- package/dist/{runtime-DQs5xHdt.js → runtime-BnqjbOGX.js} +18 -12
- package/dist/{runtime-DQs5xHdt.js.map → runtime-BnqjbOGX.js.map} +1 -1
- package/dist/{runtime-htqI3fKL.d.ts → runtime-J6Toky8K.d.ts} +22 -10
- package/dist/{sandbox-events-BK-g19wx.js → sandbox-events-COwCWUVB.js} +6 -49
- package/dist/sandbox-events-COwCWUVB.js.map +1 -0
- package/dist/{stream-agent-turn-Dfy12OjG.d.ts → stream-agent-turn-C1Vs_3B9.d.ts} +6 -3
- package/dist/{stream-agent-turn-BMHUIuQS.js → stream-agent-turn-CXRugSGO.js} +55 -14
- package/dist/stream-agent-turn-CXRugSGO.js.map +1 -0
- package/dist/{structural-rollout-CzZKDkmA.js → structural-rollout-CJgj9YXH.js} +4 -4
- package/dist/{structural-rollout-CzZKDkmA.js.map → structural-rollout-CJgj9YXH.js.map} +1 -1
- package/dist/{supervise-BEs5MB91.js → supervise-hCgG6ROJ.js} +3 -3
- package/dist/{supervise-BEs5MB91.js.map → supervise-hCgG6ROJ.js.map} +1 -1
- package/dist/{supervisor-B_0ISTFG.js → supervisor-s8SfZYbW.js} +107 -43
- package/dist/supervisor-s8SfZYbW.js.map +1 -0
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +11 -11
- package/dist/{types-DZrBoBpN.d.ts → types-DeX8ibLc.d.ts} +4 -1
- package/dist/{types-_7w24mMg.d.ts → types-Df9vulGc.d.ts} +2 -2
- package/package.json +5 -5
- package/dist/materialization-CrdcfWXp.js.map +0 -1
- package/dist/sandbox-events-BK-g19wx.js.map +0 -1
- package/dist/stream-agent-turn-BMHUIuQS.js.map +0 -1
- package/dist/supervisor-B_0ISTFG.js.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { E as SandboxClient, i as ExecCtx, k as Validator } from "./types-
|
|
2
|
-
import { I as Scope, Q as UsageEvent, U as Spend, d as ExecutorFactory, gn as ExecutorProgress, ln as TraceSource, m as ExecutorRegistry } from "./types-
|
|
3
|
-
import { i as AgentEnvironmentProvider, o as AgentEnvironmentProviderRegistry, w as ProviderExecutorOptions } from "./environment-provider-
|
|
1
|
+
import { E as SandboxClient, i as ExecCtx, k as Validator } from "./types-DeX8ibLc.js";
|
|
2
|
+
import { I as Scope, Q as UsageEvent, U as Spend, a as DefaultVerdict, d as ExecutorFactory, gn as ExecutorProgress, ln as TraceSource, m as ExecutorRegistry } from "./types-Df9vulGc.js";
|
|
3
|
+
import { i as AgentEnvironmentProvider, o as AgentEnvironmentProviderRegistry, w as ProviderExecutorOptions } from "./environment-provider-B8eZ85Ga.js";
|
|
4
4
|
import { AgentProfile, AgentProfileMcpServer, HarnessType, ReasoningEffort } from "@tangle-network/agent-interface";
|
|
5
5
|
import { WorkspacePlanReceipt } from "@tangle-network/agent-profile-materialize";
|
|
6
6
|
import { ChildProcess } from "node:child_process";
|
|
7
|
+
import { AgentRunOutcome } from "@tangle-network/sandbox/runtime";
|
|
7
8
|
import { BackendType, SandboxEvent } from "@tangle-network/sandbox";
|
|
8
9
|
//#region src/mcp/protocol.d.ts
|
|
9
10
|
/**
|
|
@@ -770,6 +771,21 @@ interface ResolvedMcpServerLaunch {
|
|
|
770
771
|
*/
|
|
771
772
|
declare function resolveMcpServerLaunch(server: AgentProfileMcpServer, keys: KeyProvider | undefined, label: string): Promise<ResolvedMcpServerLaunch>;
|
|
772
773
|
//#endregion
|
|
774
|
+
//#region src/runtime/sandbox-executor-output.d.ts
|
|
775
|
+
/** One tool call retained in a Sandbox executor artifact. */
|
|
776
|
+
interface SandboxExecutorToolCall {
|
|
777
|
+
id?: string;
|
|
778
|
+
name: string;
|
|
779
|
+
arguments: unknown;
|
|
780
|
+
}
|
|
781
|
+
/** Parsed output of one Sandbox executor turn. */
|
|
782
|
+
interface SandboxLeafOut {
|
|
783
|
+
events: SandboxEvent[];
|
|
784
|
+
content: string;
|
|
785
|
+
toolCalls?: SandboxExecutorToolCall[];
|
|
786
|
+
outcome?: AgentRunOutcome;
|
|
787
|
+
}
|
|
788
|
+
//#endregion
|
|
773
789
|
//#region src/runtime/supervise/inbox.d.ts
|
|
774
790
|
/** A message from the run's AUTHORITY — the parent driver. These two kinds carry instruction. */
|
|
775
791
|
interface AuthorityInboxMessage {
|
|
@@ -833,6 +849,7 @@ interface SteerableSandboxSession {
|
|
|
833
849
|
artifact(): {
|
|
834
850
|
outRef: string;
|
|
835
851
|
out: unknown;
|
|
852
|
+
verdict?: DefaultVerdict;
|
|
836
853
|
spent: Spend;
|
|
837
854
|
} | undefined;
|
|
838
855
|
teardown(): Promise<void>;
|
|
@@ -1109,11 +1126,6 @@ interface RouterToolsSeam {
|
|
|
1109
1126
|
durationMs?: number;
|
|
1110
1127
|
}) => void;
|
|
1111
1128
|
}
|
|
1112
|
-
/** Parsed output of the sandbox leaf: the iteration's raw event stream. What a
|
|
1113
|
-
* `SandboxSeam.validator` receives as its `output` argument. */
|
|
1114
|
-
interface SandboxLeafOut {
|
|
1115
|
-
events: SandboxEvent[];
|
|
1116
|
-
}
|
|
1117
1129
|
/**
|
|
1118
1130
|
* The leaf `createWorktreeCliExecutor` as a backend-as-data factory: a supervisor-authored
|
|
1119
1131
|
* `AgentProfile` driving claude / codex / opencode on its own worktree. `budgetExempt` like
|
|
@@ -1161,5 +1173,5 @@ declare function createExecutor(config: ExecutorConfig): ExecutorFactory<unknown
|
|
|
1161
1173
|
*/
|
|
1162
1174
|
declare function createExecutorRegistry(): ExecutorRegistry;
|
|
1163
1175
|
//#endregion
|
|
1164
|
-
export {
|
|
1165
|
-
//# sourceMappingURL=runtime-
|
|
1176
|
+
export { RemoveWorktreeOptions as $, resolveMcpServerLaunch as A, JsonRpcMessage as At, DEFAULT_LOCAL_HARNESS as B, createInbox as C, PeerMailbox as Ct, ResolvedMcpServerLaunch as D, isPeerMailEnvelope as Dt, KeyProvider as E, createPeerMailbox as Et, WorktreeHarnessResult as F, harnessSupportsReasoningEffort as G, LocalHarness as H, WorktreeProfileMaterializationReceipt as I, runLocalHarness as J, localHarnessExecutable as K, CodexExecutionEvidence as L, secretEnvOfMcpServer as M, McpToolDescriptor as Mt, WorktreeCheckRunner as N, McpTransport as Nt, envKeyProvider as O, peerMailTools as Ot, WorktreeCommandResult as P, GitRunner as Q, CodexExecutionPolicy as R, PeerInboxMessage as S, PeerMailSendInput as St, SandboxLeafOut as T, claimsAuthority as Tt, LocalHarnessResult as U, LOCAL_HARNESSES as V, RunLocalHarnessOptions as W, DiffOptions as X, CreateWorktreeOptions as Y, DiffResult as Z, SteerableSandboxSession as _, PeerMailKind as _t, CliWorktreeSeam as a, ToolSpec as at, Inbox as b, PeerMailReadout as bt, RouterSeam as c, ToolLoopCompaction as ct, cliWorktreeExecutor as d, ToolLoopToolCall as dt, WorktreeHandle as et, createExecutor as f, AUTHORITY_MARKERS as ft, SteerableSandboxArgs as g, PeerMailEvent as gt, SandboxSteeringOptions as h, PeerMailEnvelope as ht, CliWorktreeBridgeSeam as i, RouterTransportConfig as it, resolveSecretEnv as j, JsonRpcResponse as jt, mcpSecretEnvMetadataKey as k, peerMailVerbNames as kt, RouterToolsSeam as l, ToolLoopCompactionOptions as lt, DEFAULT_SANDBOX_STEERING_MAX_TURNS as m, PEER_MAIL_WIRE_KEY as mt, BridgeSeam as n, createWorktree as nt, ExecutorConfig as o, ToolLoopCallContext as ot, createExecutorRegistry as p, DEFAULT_PEER_MAIL_LIMITS as pt, parseCodexTokenUsage as q, CliSeam as r, removeWorktree as rt, ProviderSeam as s, ToolLoopChat as st, BridgeModelCredential as t, captureWorktreeDiff as tt, SandboxSeam as u, ToolLoopMessageRecord as ut, createSteerableSandboxSession as v, PeerMailLimits as vt, SandboxExecutorToolCall as w, PeerMailboxOptions as wt, InboxMessage as x, PeerMailRefusal as xt, AuthorityInboxMessage as y, PeerMailOutcome as yt, CodexTokenUsage as z };
|
|
1177
|
+
//# sourceMappingURL=runtime-J6Toky8K.d.ts.map
|
|
@@ -155,43 +155,6 @@ function copyPlainSpine(value, seen) {
|
|
|
155
155
|
for (const [key, child] of Object.entries(value)) copy[key] = copyPlainSpine(child, seen);
|
|
156
156
|
return copy;
|
|
157
157
|
}
|
|
158
|
-
/** Event types that settle one sandbox execution. A status or `success` flag is read as a
|
|
159
|
-
* verdict on the whole execution only here; on any other event it describes that event. */
|
|
160
|
-
const TERMINAL_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
161
|
-
"done",
|
|
162
|
-
"result",
|
|
163
|
-
"final"
|
|
164
|
-
]);
|
|
165
|
-
/**
|
|
166
|
-
* Return the terminal failure carried by one Sandbox event.
|
|
167
|
-
*
|
|
168
|
-
* Sandbox transports report execution failure in-band: commonly an `error`
|
|
169
|
-
* event followed by a synthetic `done`. Treating the iterable as successfully
|
|
170
|
-
* drained therefore turns a provider/configuration failure into a completed
|
|
171
|
-
* empty artifact.
|
|
172
|
-
*
|
|
173
|
-
* The decoder reads a failure from exactly two places, so that a mid-stream
|
|
174
|
-
* event describing its OWN failure cannot fail the execution: an `error`-typed
|
|
175
|
-
* event, and a terminal event (`done`/`result`/`final`) whose `success` is
|
|
176
|
-
* `false` or whose status is a failed one. A failing tool part therefore stays
|
|
177
|
-
* a tool result, which is what {@link mapSandboxToolEvent} already projects it
|
|
178
|
-
* to.
|
|
179
|
-
*/
|
|
180
|
-
function sandboxEventFailure(event) {
|
|
181
|
-
if (!event || typeof event !== "object") return void 0;
|
|
182
|
-
const type = String(event.type ?? "");
|
|
183
|
-
const data = event.data && typeof event.data === "object" ? event.data : {};
|
|
184
|
-
const outcome = plainRecord(data.outcome);
|
|
185
|
-
const status = firstString(data.status, outcome?.type, outcome?.status, plainRecord(data.result)?.status);
|
|
186
|
-
const terminalFailure = TERMINAL_EVENT_TYPES.has(type) && (data.success === false || status !== void 0 && TERMINAL_FAILURE.test(status));
|
|
187
|
-
if (type !== "error" && !terminalFailure) return void 0;
|
|
188
|
-
return describeSandboxError(data.error) ?? describeSandboxError(outcome?.error) ?? describeSandboxError(plainRecord(data.result)?.error) ?? (typeof data.message === "string" && data.message.length > 0 ? data.message : void 0) ?? (status !== void 0 ? `sandbox execution ended with status ${status}` : "sandbox execution failed");
|
|
189
|
-
}
|
|
190
|
-
/** Fail the live execution instead of allowing an in-band failure to become an empty success. */
|
|
191
|
-
function assertSandboxEventSucceeded(event) {
|
|
192
|
-
const failure = sandboxEventFailure(event);
|
|
193
|
-
if (failure !== void 0) throw new Error(`sandbox execution failed: ${failure}`);
|
|
194
|
-
}
|
|
195
158
|
/**
|
|
196
159
|
* Read the served execution identity off one Sandbox event.
|
|
197
160
|
*
|
|
@@ -264,12 +227,6 @@ function stripProviderPrefix(id, providers) {
|
|
|
264
227
|
}
|
|
265
228
|
return out;
|
|
266
229
|
}
|
|
267
|
-
function describeSandboxError(value) {
|
|
268
|
-
if (typeof value === "string" && value.length > 0) return value;
|
|
269
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
270
|
-
const error = value;
|
|
271
|
-
return firstString(error.message, error.error, error.reason, error.code);
|
|
272
|
-
}
|
|
273
230
|
function firstString(...values) {
|
|
274
231
|
return values.find((value) => typeof value === "string" && value.length > 0);
|
|
275
232
|
}
|
|
@@ -279,8 +236,8 @@ function firstString(...values) {
|
|
|
279
236
|
* so the kernel can iterate the full stream without branching.
|
|
280
237
|
*
|
|
281
238
|
* Pure by contract: it never throws on a failed run. The terminal truth
|
|
282
|
-
* boundary is
|
|
283
|
-
*
|
|
239
|
+
* boundary is the public Sandbox outcome tracker, applied after the complete
|
|
240
|
+
* stream. Post-hoc readers — {@link sumSandboxUsage}, the
|
|
284
241
|
* analyst trace store, the chat projection — must stay able to read a failed
|
|
285
242
|
* turn's events, which is when reading them matters most.
|
|
286
243
|
*
|
|
@@ -534,8 +491,8 @@ function createSandboxToolPartState() {
|
|
|
534
491
|
seq: 0
|
|
535
492
|
};
|
|
536
493
|
}
|
|
537
|
-
/** Statuses that settle
|
|
538
|
-
*
|
|
494
|
+
/** Statuses that settle one tool call as a failure. A failed tool call stays a tool result:
|
|
495
|
+
* the run's terminal state comes from the public Sandbox outcome tracker, never from here. */
|
|
539
496
|
const TERMINAL_FAILURE = /^(error|errored|failed|failure|cancelled|canceled|timeout|timed_out)$/i;
|
|
540
497
|
/**
|
|
541
498
|
* Project one `SandboxEvent` onto the `tool_call` / `tool_result` variants of
|
|
@@ -690,6 +647,6 @@ function mapSandboxEvent(event, opts = {}) {
|
|
|
690
647
|
return extractLlmCallEvent(event, opts.agentRunName ?? "agent");
|
|
691
648
|
}
|
|
692
649
|
//#endregion
|
|
693
|
-
export {
|
|
650
|
+
export { mapSandboxEvent as a, sandboxEventServedBackend as c, parseCanonicalTransportEvent as d, extractLlmCallEvent as i, sumSandboxUsage as l, canonicalStreamEventFromSandboxEvent as n, mapSandboxToolEvent as o, createSandboxToolPartState as r, notifySandboxEventObserver as s, assertSandboxServedModel as t, extractTransportEventIdentity as u };
|
|
694
651
|
|
|
695
|
-
//# sourceMappingURL=sandbox-events-
|
|
652
|
+
//# sourceMappingURL=sandbox-events-COwCWUVB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-events-COwCWUVB.js","names":[],"sources":["../src/runtime/timestamps.ts","../src/runtime/sandbox-transport-events.ts","../src/runtime/sandbox-events.ts"],"sourcesContent":["import { RuntimeEventEnvelopeSchema } from '@tangle-network/agent-interface'\n\nconst validTimestamp = '2026-01-01T00:00:00.000Z'\n\n/** Validate a timestamp with the public runtime envelope contract. */\nexport function assertRuntimeTimestamp(value: unknown, label: string): asserts value is string {\n try {\n RuntimeEventEnvelopeSchema.parse({\n runId: 'runtime',\n eventId: 'event',\n sequence: 0,\n occurredAt: value,\n receivedAt: validTimestamp,\n event: { type: 'status', status: 'processing' },\n })\n } catch (error) {\n throw new Error(`${label} must be a valid ISO timestamp`, { cause: error })\n }\n}\n\n/** Return whether a value satisfies the public runtime timestamp contract. */\nexport function isRuntimeTimestamp(value: unknown): value is string {\n try {\n assertRuntimeTimestamp(value, 'occurredAt')\n return true\n } catch {\n return false\n }\n}\n","import { CanonicalStreamEventSchema, type StreamEvent } from '@tangle-network/agent-interface'\nimport { assertRuntimeTimestamp } from './timestamps'\n\n/** Parse canonical payload fields without treating transport identity as event data. */\nexport function parseCanonicalTransportEvent(\n type: unknown,\n data: Record<string, unknown>,\n normalized: unknown,\n source: string,\n): StreamEvent | undefined {\n if (!isRecord(data)) {\n throw new Error(`${source} emitted a canonical event without an object payload`)\n }\n const outerType = String(type ?? '')\n if (normalized !== undefined) {\n if (\n typeof normalized === 'object' &&\n normalized !== null &&\n 'type' in normalized &&\n typeof normalized.type === 'string' &&\n normalized.type !== outerType\n ) {\n throw new Error(\n `${source} canonical event type \"${normalized.type}\" does not match transport type \"${outerType}\"`,\n )\n }\n const candidate = CanonicalStreamEventSchema.safeParse(normalized)\n if (!candidate.success) {\n throw new Error(`${source} emitted an invalid normalized canonical event`, {\n cause: candidate.error,\n })\n }\n return candidate.data\n }\n const {\n type: embeddedType,\n eventId: _eventId,\n cursor: _cursor,\n sequence: _sequence,\n occurredAt: _occurredAt,\n normalized: _normalized,\n ...payload\n } = data\n if (embeddedType !== undefined && embeddedType !== outerType) {\n throw new Error(\n `${source} canonical event type \"${String(embeddedType)}\" does not match transport type \"${outerType}\"`,\n )\n }\n const candidate = CanonicalStreamEventSchema.safeParse({ ...payload, type: outerType })\n return candidate.success ? candidate.data : undefined\n}\n\n/** Identity fields carried by either the transport envelope or its data payload. */\nexport interface TransportEventIdentity {\n readonly eventId?: string\n readonly cursor?: string\n readonly sequence?: number\n readonly occurredAt?: string\n}\n\n/** Extract shared event identity without privileging one provider wire shape. */\nexport function extractTransportEventIdentity(event: unknown): TransportEventIdentity {\n const record = isRecord(event) ? event : {}\n const data = isRecord(record.data) ? record.data : {}\n const providerEvent = isRecord(record.providerEvent) ? record.providerEvent : {}\n const providerData = isRecord(providerEvent.data) ? providerEvent.data : {}\n const eventId = canonicalEventId(record, data, providerEvent, providerData)\n const cursor = stableString(\n record.cursor ?? data.cursor ?? providerEvent.cursor ?? providerData.cursor,\n )\n const sequence = optionalSequence(\n record.sequence ?? data.sequence ?? providerEvent.sequence ?? providerData.sequence,\n )\n const occurredAt = optionalTimestamp(\n record.occurredAt ?? data.occurredAt ?? providerEvent.occurredAt ?? providerData.occurredAt,\n )\n return {\n ...(eventId === undefined ? {} : { eventId }),\n ...(cursor === undefined ? {} : { cursor }),\n ...(sequence === undefined ? {} : { sequence }),\n ...(occurredAt === undefined ? {} : { occurredAt }),\n }\n}\n\nfunction canonicalEventId(\n record: Record<string, unknown>,\n data: Record<string, unknown>,\n providerEvent: Record<string, unknown>,\n providerData: Record<string, unknown>,\n): string | undefined {\n const candidates = [\n ['data.eventId', data.eventId],\n ['providerEvent.eventId', providerEvent.eventId],\n ['providerData.eventId', providerData.eventId],\n ['record.eventId', record.eventId],\n ] as const\n const present = candidates.filter(([, value]) => value !== undefined)\n // `record.id` may be the provider's replay cursor, so use it only without a canonical field.\n if (present.length === 0) return stableString(record.id ?? providerEvent.id)\n\n const normalized = present.map(([source, value]) => {\n const eventId = stableString(value)\n if (eventId === undefined) throw new Error(`transport event ${source} must be a stable string`)\n return { source, eventId }\n })\n const first = normalized[0]!\n if (normalized.some((candidate) => candidate.eventId !== first.eventId)) {\n throw new Error('transport event canonical identities disagree')\n }\n return first.eventId\n}\n\nfunction stableString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 && value.trim() === value ? value : undefined\n}\n\nfunction finiteNonNegativeInteger(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined\n}\n\nfunction optionalSequence(value: unknown): number | undefined {\n if (value === undefined) return undefined\n if (finiteNonNegativeInteger(value) === undefined) {\n throw new Error('transport event sequence must be a non-negative safe integer')\n }\n return value as number\n}\n\nfunction optionalTimestamp(value: unknown): string | undefined {\n if (value === undefined) return undefined\n assertRuntimeTimestamp(value, 'occurredAt')\n return value\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","/**\n * Sandbox-event → runtime-event mapping.\n *\n * The sandbox SDK emits a polymorphic `SandboxEvent = { type, data, id? }`\n * whose `type` vocabulary is backend-determined (opencode, etc.) rather than\n * enumerated by the SDK. Two consumers project it:\n * - the loop kernel's cost ledger (`extractLlmCallEvent`) — sums usage off\n * every cost-bearing event, regardless of stream shape;\n * - the `AgentRuntime.act` streaming contract (`mapSandboxEvent`) — projects\n * incremental events to the `RuntimeStreamEvent` chat-UX vocabulary.\n *\n * Both live here so the empirically-observed `type` vocabulary has one home.\n */\n\nimport type { StreamEvent } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport type { RuntimeStreamEvent } from '../types'\nimport { parseCanonicalTransportEvent } from './sandbox-transport-events'\n\nconst CANONICAL_STREAM_EVENT_TYPES: ReadonlySet<string> = new Set([\n 'message.part.updated',\n 'tool-heartbeat',\n 'tool-slow',\n 'model-processing',\n 'status',\n 'warning',\n 'raw',\n 'session.updated',\n 'interaction',\n 'interaction.cancel',\n 'plan.submitted',\n])\n\n/** Decode one known Agent Interface event from a Sandbox event. */\nexport function canonicalStreamEventFromSandboxEvent(event: SandboxEvent): StreamEvent | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n const normalized = data.normalized\n if (normalized === undefined && !CANONICAL_STREAM_EVENT_TYPES.has(type)) return undefined\n return parseCanonicalTransportEvent(type, data, normalized, 'sandbox')\n}\n\n/**\n * Forward a sandbox event to an optional observer without letting observer\n * behavior affect the run. The observer receives a defensive copy, synchronous\n * throws are swallowed, and returned promises are deliberately not awaited.\n */\nexport function notifySandboxEventObserver<Meta>(\n event: SandboxEvent,\n observer: ((event: SandboxEvent, meta: Meta) => void | PromiseLike<void>) | undefined,\n meta: Meta,\n): void {\n if (!observer) return\n try {\n const result = observer(cloneEventForObserver(event), meta)\n if (result && typeof result.then === 'function') {\n void result.then(undefined, () => {})\n }\n } catch {\n // Live observation is optional and must never interrupt the event stream.\n }\n}\n\nfunction cloneEventForObserver(event: SandboxEvent): SandboxEvent {\n try {\n return structuredClone(event)\n } catch {\n return copyPlainSpine(event, new WeakMap()) as SandboxEvent\n }\n}\n\nfunction copyPlainSpine(value: unknown, seen: WeakMap<object, unknown>): unknown {\n if (value === null || typeof value !== 'object') return value\n const existing = seen.get(value)\n if (existing !== undefined) return existing\n if (Array.isArray(value)) {\n const copy: unknown[] = []\n seen.set(value, copy)\n for (const item of value) copy.push(copyPlainSpine(item, seen))\n return copy\n }\n const proto = Object.getPrototypeOf(value)\n if (proto !== Object.prototype && proto !== null) return {}\n const copy: Record<string, unknown> = {}\n seen.set(value, copy)\n for (const [key, child] of Object.entries(value)) {\n copy[key] = copyPlainSpine(child, seen)\n }\n return copy\n}\n\n/** The provider/model the platform reports it actually bound to a turn, when it reports one.\n * `source` is the platform's own account of where that choice came from — `environment` means\n * the platform chose, not the request. */\nexport interface SandboxServedBackend {\n readonly provider?: string\n readonly model?: string\n readonly source?: string\n}\n\n/**\n * Read the served execution identity off one Sandbox event.\n *\n * The platform reports `effectiveBackend` on `execution.started` and again on the terminal\n * event (`@tangle-network/sandbox`, `EffectiveBackend`). Absence returns `undefined`\n * and must stay unknown — a request is not a receipt, so nothing here may be inferred from\n * what was asked for.\n */\nexport function sandboxEventServedBackend(event: SandboxEvent): SandboxServedBackend | undefined {\n if (!event || typeof event !== 'object') return undefined\n const data = plainRecord(event.data)\n const served = plainRecord(data?.effectiveBackend)\n if (!served) return undefined\n const provider = firstString(served.provider)\n const model = firstString(served.model)\n const source = firstString(served.source)\n if (provider === undefined && model === undefined) return undefined\n return {\n ...(provider !== undefined ? { provider } : {}),\n ...(model !== undefined ? { model } : {}),\n ...(source !== undefined ? { source } : {}),\n }\n}\n\n/**\n * Fail the execution when the platform reports serving a model other than the exact one asked for.\n *\n * Measured motive (agent-runtime#892, live infrastructure 2026-08-17): 6 of 6 boxes whose profile\n * declared `zai-coding-plan/glm-5.2` reported\n * `{\"provider\":\"openai-compat\",\"model\":\"deepseek/deepseek-v4-flash\",\"source\":\"environment\"}`,\n * while the materialization receipt recorded the declared model as `status: \"known\"`. Sending\n * `backend.model` makes that substitution unlikely; only reading the report back makes it\n * detectable. A run that cannot say which model produced its evidence must not settle as one\n * that can.\n *\n * Silent when the platform reports no served model: unobserved stays unobserved.\n */\nexport function assertSandboxServedModel(\n event: SandboxEvent,\n expected: { readonly provider?: string; readonly model?: string } | undefined,\n): void {\n const wanted = expected?.model?.trim()\n if (!wanted) return\n const served = sandboxEventServedBackend(event)\n if (served?.model === undefined) return\n if (sameModelId(served.model, wanted, [served.provider, expected?.provider])) return\n const attribution = [\n served.provider !== undefined ? `provider ${JSON.stringify(served.provider)}` : undefined,\n served.source !== undefined ? `source ${JSON.stringify(served.source)}` : undefined,\n ].filter((part): part is string => part !== undefined)\n const detail = attribution.length > 0 ? ` (${attribution.join(', ')})` : ''\n throw new Error(\n `sandbox served model ${JSON.stringify(served.model)}${detail} instead of the exact profile model ${JSON.stringify(wanted)}`,\n )\n}\n\n/**\n * Do two model ids name the same model, allowing for routing prefixes?\n *\n * Either side may spell the model bare (`glm-5.2`), provider-qualified\n * (`zai-coding-plan/glm-5.2`), or route-qualified, and the platform reports the provider in its\n * own field rather than always in the id. So the comparison drops any known provider prefix and\n * then accepts a `/`-boundary suffix match: a longer route to the SAME leaf model is a routing\n * difference, not a substitution.\n *\n * What it deliberately does NOT absorb is a different leaf: `glm-5.2` against `glm-5.3` stays a\n * mismatch, which is the substitution measured directly against the provider API (a request for\n * `glm-5.2` was served `glm-5.3`). A version suffix is the whole difference between two\n * instruments, so nothing here may treat it as noise.\n */\nfunction sameModelId(\n served: string,\n wanted: string,\n providers: readonly (string | undefined)[],\n): boolean {\n const a = stripProviderPrefix(served, providers)\n const b = stripProviderPrefix(wanted, providers)\n return a === b || a.endsWith(`/${b}`) || b.endsWith(`/${a}`)\n}\n\nfunction stripProviderPrefix(id: string, providers: readonly (string | undefined)[]): string {\n let out = id.trim().toLowerCase()\n for (const provider of providers) {\n const prefix = provider?.trim().toLowerCase()\n if (prefix && out.startsWith(`${prefix}/`)) out = out.slice(prefix.length + 1)\n }\n return out\n}\n\nfunction firstString(...values: unknown[]): string | undefined {\n return values.find((value): value is string => typeof value === 'string' && value.length > 0)\n}\n\n/**\n * Extract a `RuntimeStreamEvent`-shaped `llm_call` from a sandbox event when\n * the event carries usage/cost data. Returns `undefined` for non-cost events\n * so the kernel can iterate the full stream without branching.\n *\n * Pure by contract: it never throws on a failed run. The terminal truth\n * boundary is the public Sandbox outcome tracker, applied after the complete\n * stream. Post-hoc readers — {@link sumSandboxUsage}, the\n * analyst trace store, the chat projection — must stay able to read a failed\n * turn's events, which is when reading them matters most.\n *\n * Canonical cost-carrying types observed in the wild:\n * - `llm_call` — `data: { model, tokensIn, tokensOut, costUsd, ... }`\n * - `message.completed` / `result` — `data: { usage: { inputTokens,\n * outputTokens, totalCostUsd? } }`\n * - `cost.usage` / `usage` — same shape under a dedicated type\n *\n * Numeric coercion is strict: `Number.isFinite` gates every accumulator write\n * so a sentinel `NaN` from a misbehaving backend cannot poison the ledger.\n */\nexport function extractLlmCallEvent(\n event: SandboxEvent,\n agentRunName: string,\n): (RuntimeStreamEvent & { type: 'llm_call' }) | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'llm_call' || type === 'cost.usage' || type === 'usage') {\n return buildLlmCall(data, agentRunName)\n }\n if (type === 'message.completed' || type === 'result' || type === 'final') {\n const usage = data.usage as Record<string, unknown> | undefined\n if (!usage || typeof usage !== 'object') return undefined\n return buildLlmCall({ ...usage, model: data.model ?? usage.model }, agentRunName)\n }\n // sandbox 0.4.0 terminal event: `data = { tokenUsage: { inputTokens, outputTokens,\n // reasoningTokens, cacheReadInputTokens }, totalCostUsd }`. Usage lives under\n // `tokenUsage` (not `usage`) and the cost is top-level — neither matched the\n // branches above, so an in-process loopDispatch run reported {0,0} and the\n // backend-integrity guard misread a real run as a stub. Reasoning tokens are\n // billed output (reasoning models), so they fold into the output count. The prompt-cache\n // counters are read off the SAME `tokenUsage` record rather than re-derived, because only\n // that record states what the provider billed.\n if (type === 'done') {\n const usage = data.tokenUsage as Record<string, unknown> | undefined\n if (!usage || typeof usage !== 'object') return undefined\n const out = pickFiniteNumber(usage, ['outputTokens', 'completion_tokens', 'tokensOut'])\n const reasoning = pickFiniteNumber(usage, ['reasoningTokens'])\n const mergedOut =\n out !== undefined || reasoning !== undefined ? (out ?? 0) + (reasoning ?? 0) : undefined\n const cache = readPromptCacheUsage(usage)\n return buildLlmCall(\n {\n inputTokens: usage.inputTokens,\n outputTokens: mergedOut,\n totalCostUsd: data.totalCostUsd,\n model: data.model ?? usage.model,\n ...(cache !== undefined ? { promptCache: cache } : {}),\n },\n agentRunName,\n )\n }\n return undefined\n}\n\n/**\n * Sum the token usage + USD cost of a sandbox turn's events — the one honest way to meter an\n * `openSandboxRun` cell. Folds `extractLlmCallEvent` over the stream (which reads usage off EVERY backend\n * event shape), so a `runProfileMatrix` dispatch can report it to `ctx.cost`:\n *\n * receipt: (turn) => {\n * const u = sumSandboxUsage(turn.events)\n * return { model, inputTokens: u.input, outputTokens: u.output,\n * ...(u.tokensKnown === false ? { usageUnknown: true } : {}),\n * ...(u.usdKnown !== false && u.costUsd > 0 ? { actualCostUsd: u.costUsd } : {}),\n * ...(u.usdKnown === false ? { costUnknown: true } : {}),\n * ...(u.estimatedCostUsd !== undefined ? { estimatedCostUsd: u.estimatedCostUsd } : {}) }\n * }\n *\n * Without this a cell reads `{tokens:0, cost:0}` and the backend-integrity guard correctly aborts the\n * matrix as a stub. `agentRunName` is the fallback model label for cost-only events (default `'agent'`).\n */\nexport function sumSandboxUsage(\n events: readonly SandboxEvent[],\n agentRunName = 'agent',\n): {\n input: number\n output: number\n costUsd: number\n tokensKnown?: false\n usdKnown?: false\n estimatedCostUsd?: number\n} {\n let input = 0\n let output = 0\n let costUsd = 0\n let estimatedCostUsd = 0\n let sawEstimate = false\n let sawCall = false\n let tokensKnown = true\n let usdKnown = true\n for (const ev of events) {\n const call = extractLlmCallEvent(ev, agentRunName)\n if (!call) continue\n sawCall = true\n input += call.tokensIn ?? 0\n output += call.tokensOut ?? 0\n costUsd += call.costUsd ?? 0\n if (call.tokensKnown === false) tokensKnown = false\n if (call.usdKnown === false) usdKnown = false\n if (call.estimatedCostUsd !== undefined) {\n estimatedCostUsd += call.estimatedCostUsd\n sawEstimate = true\n }\n }\n return {\n input,\n output,\n costUsd,\n ...(sawCall && tokensKnown ? {} : { tokensKnown: false as const }),\n ...(sawCall && usdKnown ? {} : { usdKnown: false as const }),\n ...(sawEstimate ? { estimatedCostUsd } : {}),\n }\n}\n\nfunction buildLlmCall(\n data: Record<string, unknown>,\n agentRunName: string,\n): (RuntimeStreamEvent & { type: 'llm_call' }) | undefined {\n const tokensIn = pickFiniteNumber(data, ['tokensIn', 'inputTokens', 'prompt_tokens'])\n const outputTokens = pickFiniteNumber(data, ['tokensOut', 'outputTokens', 'completion_tokens'])\n const reasoningTokens = pickFiniteNumber(data, ['reasoningTokens'])\n const tokensOut =\n outputTokens !== undefined || reasoningTokens !== undefined\n ? (outputTokens ?? 0) + (reasoningTokens ?? 0)\n : undefined\n const reportedCostUsd = pickFiniteNumber(data, ['costUsd', 'totalCostUsd', 'cost_usd', 'cost'])\n const explicitTokensKnown = data.tokensKnown ?? data.tokens_known\n const explicitCostKnown = data.costKnown ?? data.cost_known ?? data.usdKnown ?? data.usd_known\n const costProvenance = data.costProvenance ?? data.cost_provenance\n const explicitEstimate = pickFiniteNumber(data, ['estimatedCostUsd', 'estimated_cost_usd'])\n const catalogEstimate =\n costProvenance === 'catalog-estimate' ? (explicitEstimate ?? reportedCostUsd) : explicitEstimate\n const costUsd = costProvenance === 'catalog-estimate' ? undefined : reportedCostUsd\n const promptCache = readPromptCacheUsage(data)\n const tokensKnown =\n explicitTokensKnown !== false && tokensIn !== undefined && tokensOut !== undefined\n // Sandbox's canonical terminal `totalCostUsd` is already the provider-reported receipt. The\n // current SDK carries no provenance tag, so absence means the canonical receipt rather than\n // \"unknown\". Explicit estimates and explicit false-known markers remain unknown.\n const usdKnown =\n explicitCostKnown !== false &&\n costUsd !== undefined &&\n (costProvenance === undefined ||\n costProvenance === 'provider-receipt' ||\n costProvenance === 'billing-receipt')\n if (\n tokensIn === undefined &&\n tokensOut === undefined &&\n costUsd === undefined &&\n catalogEstimate === undefined &&\n promptCache === undefined &&\n explicitTokensKnown !== false &&\n explicitCostKnown !== false\n ) {\n return undefined\n }\n const model = typeof data.model === 'string' && data.model.length > 0 ? data.model : agentRunName\n const event: RuntimeStreamEvent & { type: 'llm_call' } = {\n type: 'llm_call',\n model,\n }\n if (tokensIn !== undefined) event.tokensIn = tokensIn\n if (tokensOut !== undefined) event.tokensOut = tokensOut\n if (!tokensKnown) event.tokensKnown = false\n if (costUsd !== undefined) event.costUsd = costUsd\n if (!usdKnown) event.usdKnown = false\n if (catalogEstimate !== undefined) event.estimatedCostUsd = catalogEstimate\n if (promptCache !== undefined) event.promptCache = promptCache\n return event\n}\n\n/**\n * Every wire spelling of a prompt-cache READ counter, in precedence order: the canonical name\n * first, then the spellings observed on the paths that reach this extractor — the sandbox terminal\n * `tokenUsage` record, the cli-bridge OpenAI-compatible usage object (which normalizes every\n * backend to Anthropic's `cache_read_input_tokens`), Anthropic verbatim, OpenAI's\n * `prompt_tokens_details.cached_tokens`, and DeepSeek's `prompt_cache_hit_tokens`.\n */\nconst PROMPT_CACHE_READ_KEYS = [\n 'readTokens',\n 'read_tokens',\n 'cacheReadInputTokens',\n 'cache_read_input_tokens',\n 'cacheRead',\n 'cache_read',\n 'cachedInputTokens',\n 'cachedTokens',\n 'cached_tokens',\n 'prompt_cache_hit_tokens',\n]\n\n/**\n * Every wire spelling of a prompt-cache WRITE counter. OpenAI reports no write counter at all, so\n * an OpenAI-shaped usage record matches nothing here and the write stays absent — which is the\n * point: absent is not zero.\n */\nconst PROMPT_CACHE_WRITE_KEYS = [\n 'writeTokens',\n 'write_tokens',\n 'cacheWriteInputTokens',\n 'cache_write_input_tokens',\n 'cacheCreationInputTokens',\n 'cache_creation_input_tokens',\n 'cacheWrite',\n 'cache_write',\n]\n\nconst PROMPT_CACHE_MISS_KEYS = ['missTokens', 'miss_tokens', 'prompt_cache_miss_tokens']\n\nconst PROMPT_CACHE_SAVINGS_KEYS = ['readSavingsUsd', 'read_savings_usd']\n\n/**\n * Read the provider's own prompt-cache accounting off one usage-bearing event payload, in the\n * `PromptCacheUsage` vocabulary the router, driver, and chat-client paths already speak.\n *\n * Two sources, one record. A payload that already carries a `promptCache` / `prompt_cache` object\n * is forwarded VERBATIM — those fields are the provider's own report, and an unrecognized one must\n * stay visible rather than be bucketed away. On top of that, flat provider counters are translated\n * to the canonical names, filling only the names the verbatim object did not already define.\n *\n * A counter the payload does not carry is left out. Defaulting it to zero would assert the provider\n * measured no cache, which is a different fact from a provider that reported nothing — and it is\n * the fact the budget reads to decide whether its charge is a measurement or a bound.\n */\nfunction readPromptCacheUsage(\n data: Record<string, unknown>,\n): Record<string, number | string> | undefined {\n const declared = finiteMetadata(data.promptCache ?? data.prompt_cache)\n const nested = plainRecord(data.promptCache) ?? plainRecord(data.prompt_cache)\n const details = plainRecord(data.prompt_tokens_details)\n const sources = [nested, data, details].filter(\n (s): s is Record<string, unknown> => s !== undefined,\n )\n\n const canonical: Record<string, number | string> = {}\n const readTokens = pickTokenCount(sources, PROMPT_CACHE_READ_KEYS)\n const writeTokens = pickTokenCount(sources, PROMPT_CACHE_WRITE_KEYS)\n const missTokens = pickTokenCount(sources, PROMPT_CACHE_MISS_KEYS)\n const readSavingsUsd = pickNonNegativeNumber(sources, PROMPT_CACHE_SAVINGS_KEYS)\n const status =\n nested !== undefined && typeof nested.status === 'string' ? nested.status : undefined\n if (readTokens !== undefined) canonical.readTokens = readTokens\n if (writeTokens !== undefined) canonical.writeTokens = writeTokens\n if (missTokens !== undefined) canonical.missTokens = missTokens\n if (readSavingsUsd !== undefined) canonical.readSavingsUsd = readSavingsUsd\n if (status !== undefined) canonical.status = status\n\n const merged = { ...canonical, ...declared }\n return Object.keys(merged).length > 0 ? merged : undefined\n}\n\nfunction plainRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined\n}\n\nfunction pickTokenCount(\n sources: readonly Record<string, unknown>[],\n keys: readonly string[],\n): number | undefined {\n for (const key of keys) {\n for (const source of sources) {\n const value = source[key]\n if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return value\n }\n }\n return undefined\n}\n\nfunction pickNonNegativeNumber(\n sources: readonly Record<string, unknown>[],\n keys: readonly string[],\n): number | undefined {\n for (const key of keys) {\n for (const source of sources) {\n const value = source[key]\n if (typeof value === 'number' && Number.isFinite(value) && value >= 0) return value\n }\n }\n return undefined\n}\n\nfunction finiteMetadata(value: unknown): Record<string, number | string> | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined\n const result: Record<string, number | string> = {}\n for (const [key, entry] of Object.entries(value)) {\n if ((typeof entry === 'number' && Number.isFinite(entry)) || typeof entry === 'string') {\n result[key] = entry\n }\n }\n return Object.keys(result).length > 0 ? result : undefined\n}\n\nfunction pickFiniteNumber(data: Record<string, unknown>, keys: string[]): number | undefined {\n for (const key of keys) {\n const value = data[key]\n if (typeof value === 'number' && Number.isFinite(value)) return value\n }\n return undefined\n}\n\n/**\n * Cross-event state for {@link mapSandboxToolEvent}. Sandbox backends emit a\n * tool invocation as MANY `message.part.updated` frames on the same call id\n * (pending → running → completed), so faithful projection needs per-call\n * status memory: one `tool_call` on first sighting, at most one `tool_result`\n * on the terminal transition, nothing on intermediate re-frames. Create one\n * state per turn via {@link createSandboxToolPartState}.\n *\n * @experimental\n */\nexport interface SandboxToolPartState {\n /** Last seen status per tool call id. A terminal status is sticky — later\n * frames on a settled call project to nothing. */\n statusByCall: Map<string, string>\n /** Sequence for synthesized call ids when an event carries none. */\n seq: number\n}\n\n/**\n * Fresh per-turn {@link SandboxToolPartState} for {@link mapSandboxToolEvent} — an\n * empty call-status map so each turn projects tool frames independently.\n *\n * @experimental\n */\nexport function createSandboxToolPartState(): SandboxToolPartState {\n return { statusByCall: new Map(), seq: 0 }\n}\n\n/** Statuses that settle one tool call as a failure. A failed tool call stays a tool result:\n * the run's terminal state comes from the public Sandbox outcome tracker, never from here. */\nconst TERMINAL_FAILURE = /^(error|errored|failed|failure|cancelled|canceled|timeout|timed_out)$/i\n\n/**\n * Project one `SandboxEvent` onto the `tool_call` / `tool_result` variants of\n * `RuntimeStreamEvent` — the tool-part projection `mapSandboxEvent`\n * deliberately does NOT perform. Opt-in and additive: `mapSandboxEvent`'s\n * default vocabulary (text/reasoning deltas + `llm_call`) is unchanged;\n * consumers that need the tool surface (chat UIs rendering tool activity)\n * compose this projector alongside it — `streamAgentTurn` does exactly that\n * under its `preserveToolParts` option.\n *\n * Handled shapes (observed on the opencode / claude-code sandbox backends):\n * - `message.part.updated` with `part.type === 'tool'` — stateful: a\n * `tool_call` on the call id's first frame (args from `state.input` or\n * `state.metadata.input`), a `tool_result` when the status transitions to\n * `completed` (result from `state.output` / `metadata.output`) or to a\n * terminal failure (result is `{ error, status, output? }` — the error\n * surfaced in-band, never dropped).\n * - bare `tool*` event types (`tool.call`, `tool_result`, …) — stateless:\n * `*result*` types project to `tool_result`, the rest to `tool_call`.\n *\n * Returns `[]` for every non-tool event.\n *\n * @experimental\n */\nexport function mapSandboxToolEvent(\n event: SandboxEvent,\n state: SandboxToolPartState,\n): (RuntimeStreamEvent & { type: 'tool_call' | 'tool_result' })[] {\n if (!event || typeof event !== 'object') return []\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'message.part.updated') {\n const part =\n data.part && typeof data.part === 'object' ? (data.part as Record<string, unknown>) : {}\n if (String(part.type ?? '') !== 'tool') return []\n return projectToolPart(part, state, typeof event.id === 'string' ? event.id : undefined)\n }\n\n if (type.includes('tool')) {\n const callId =\n pickString(data, ['toolCallId', 'tool_use_id', 'id']) ??\n (typeof event.id === 'string' ? event.id : undefined) ??\n `sandbox-tool-${++state.seq}`\n const toolName = pickString(data, ['name', 'toolName', 'tool']) ?? 'sandbox_tool'\n if (type.includes('result')) {\n return [\n {\n type: 'tool_result',\n toolName,\n toolCallId: callId,\n result: data.output ?? data.result ?? data.content ?? data,\n },\n ]\n }\n return [\n { type: 'tool_call', toolName, toolCallId: callId, args: data.input ?? data.args ?? {} },\n ]\n }\n\n return []\n}\n\nfunction projectToolPart(\n part: Record<string, unknown>,\n state: SandboxToolPartState,\n eventId: string | undefined,\n): (RuntimeStreamEvent & { type: 'tool_call' | 'tool_result' })[] {\n const callId =\n pickString(part, ['callID', 'callId', 'toolCallId', 'id']) ??\n eventId ??\n `sandbox-tool-${++state.seq}`\n const toolName = pickString(part, ['tool', 'toolName', 'name']) ?? 'sandbox_tool'\n const toolState =\n part.state && typeof part.state === 'object' ? (part.state as Record<string, unknown>) : {}\n const metadata =\n toolState.metadata && typeof toolState.metadata === 'object'\n ? (toolState.metadata as Record<string, unknown>)\n : {}\n const status = pickString(toolState, ['status']) ?? 'updated'\n\n const previous = state.statusByCall.get(callId)\n const settled =\n previous === 'completed' || (previous !== undefined && TERMINAL_FAILURE.test(previous))\n if (settled) return []\n\n const out: (RuntimeStreamEvent & { type: 'tool_call' | 'tool_result' })[] = []\n if (previous === undefined) {\n out.push({\n type: 'tool_call',\n toolName,\n toolCallId: callId,\n args: toolState.input ?? metadata.input ?? {},\n })\n }\n state.statusByCall.set(callId, status)\n\n if (status === 'completed') {\n out.push({\n type: 'tool_result',\n toolName,\n toolCallId: callId,\n result: toolState.output ?? metadata.output ?? '',\n })\n } else if (TERMINAL_FAILURE.test(status)) {\n const message =\n pickString(toolState, ['error', 'message']) ??\n pickString(metadata, ['error', 'message']) ??\n `sandbox tool ended with status ${status}`\n const output = toolState.output ?? metadata.output\n out.push({\n type: 'tool_result',\n toolName,\n toolCallId: callId,\n result: { error: message, status, ...(output !== undefined ? { output } : {}) },\n })\n }\n return out\n}\n\nfunction pickString(data: Record<string, unknown>, keys: string[]): string | undefined {\n for (const key of keys) {\n const value = data[key]\n if (typeof value === 'string' && value.length > 0) return value\n }\n return undefined\n}\n\n/**\n * Project one `SandboxEvent` onto the `RuntimeStreamEvent` chat-UX vocabulary,\n * for runtimes that bridge a sandbox `streamPrompt` into the\n * `AgentRuntime.act` streaming contract. Returns `undefined` for events that\n * have no faithful projection — the raw stream is preserved separately for the\n * `OutputAdapter`, so an unmapped event never loses data.\n *\n * Mapped (the task-optional incremental variants — no synthesized task\n * lifecycle, no guessed tool-part shapes):\n * - `message.part.updated` text part → `text_delta`\n * - `message.part.updated` reasoning/thinking part → `reasoning_delta`\n * - cost-bearing events → `llm_call` (shared with the ledger extractor)\n *\n * Tool parts are deliberately NOT mapped here (unchanged default) — compose\n * {@link mapSandboxToolEvent} alongside when a consumer needs them.\n *\n * The opencode backend emits incremental text as\n * `{ type: 'message.part.updated', data: { part: { type, text }, delta } }`;\n * `delta` is the increment, `part.text` the running accumulation.\n */\nexport function mapSandboxEvent(\n event: SandboxEvent,\n opts: { agentRunName?: string } = {},\n): RuntimeStreamEvent | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'message.part.updated') {\n const part =\n data.part && typeof data.part === 'object' ? (data.part as Record<string, unknown>) : {}\n const partType = String(part.type ?? '')\n const delta = typeof data.delta === 'string' ? data.delta : undefined\n const text = delta ?? (typeof part.text === 'string' ? part.text : undefined)\n if (text === undefined) return undefined\n if (partType === 'text') return { type: 'text_delta', text }\n if (partType === 'reasoning' || partType === 'thinking')\n return { type: 'reasoning_delta', text }\n return undefined\n }\n\n return extractLlmCallEvent(event, opts.agentRunName ?? 'agent')\n}\n\nexport {\n extractTransportEventIdentity,\n parseCanonicalTransportEvent,\n type TransportEventIdentity,\n} from './sandbox-transport-events'\n"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { J as AgentTaskStatus, Y as BackendErrorDetail, at as RuntimeStreamEvent } from "./types-
|
|
2
|
-
import { d as ExecutorFactory } from "./types-
|
|
1
|
+
import { J as AgentTaskStatus, Y as BackendErrorDetail, at as RuntimeStreamEvent } from "./types-DeX8ibLc.js";
|
|
2
|
+
import { d as ExecutorFactory } from "./types-Df9vulGc.js";
|
|
3
3
|
import { AgentProfile } from "@tangle-network/agent-interface";
|
|
4
|
+
import { AgentRunOutcome } from "@tangle-network/sandbox/runtime";
|
|
4
5
|
import { PromptOptions, SandboxEvent, SandboxInstance } from "@tangle-network/sandbox";
|
|
5
6
|
import { AgentTurnInput, AgentTurnInput as AgentTurnInput$1 } from "@tangle-network/agent-interface/environment-provider";
|
|
6
7
|
//#region src/runtime/stream-agent-turn.d.ts
|
|
@@ -99,6 +100,8 @@ interface CollectedAgentTurn {
|
|
|
99
100
|
events: RuntimeStreamEvent[];
|
|
100
101
|
status: AgentTaskStatus;
|
|
101
102
|
error?: BackendErrorDetail;
|
|
103
|
+
/** Public Sandbox outcome, when the turn ran through a Sandbox stream or executor. */
|
|
104
|
+
sandboxOutcome?: AgentRunOutcome;
|
|
102
105
|
}
|
|
103
106
|
/**
|
|
104
107
|
* Run ONE agent turn on any backend kind and stream its events. Yields the
|
|
@@ -122,4 +125,4 @@ declare function streamAgentTurn(backend: AgentTurnBackend, input: AgentTurnInpu
|
|
|
122
125
|
declare function collectAgentTurn(stream: AsyncIterable<RuntimeStreamEvent>): Promise<CollectedAgentTurn>;
|
|
123
126
|
//#endregion
|
|
124
127
|
export { StreamAgentTurnOptions as a, CollectedAgentTurn as i, AgentTurnInput$1 as n, collectAgentTurn as o, AgentTurnUsage as r, streamAgentTurn as s, AgentTurnBackend as t };
|
|
125
|
-
//# sourceMappingURL=stream-agent-turn-
|
|
128
|
+
//# sourceMappingURL=stream-agent-turn-C1Vs_3B9.d.ts.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { D as providerMessageText, E as promptOptionsFromAgentTurnInput, T as promptFromAgentTurnInput, d as awaitAbortable } from "./retained-run-binding-Dp2e8xne.js";
|
|
2
2
|
import { m as ValidationError, p as SessionMismatchError, r as BackendTransportError } from "./errors-CDZ8XsVj.js";
|
|
3
|
-
import {
|
|
3
|
+
import { a as mapSandboxEvent, n as canonicalStreamEventFromSandboxEvent, o as mapSandboxToolEvent, r as createSandboxToolPartState } from "./sandbox-events-COwCWUVB.js";
|
|
4
|
+
import { C as unknownExecutionBindingReceipt, D as projectSandboxOutcome, O as readSandboxOutcome, T as executableAgentProfileSnapshot, a as authoredProfileDigest, c as knownExecutionBindingReceipt, l as knownMaterializationReceipt, v as runtimeOwnedExecutorExecutionBinding, w as unknownMaterializationReceipt, x as runtimeOwnedPendingExecutorMaterialization, y as runtimeOwnedExecutorMaterialization } from "./materialization-P86EciBw.js";
|
|
4
5
|
import { c as profileProviderModel, i as concreteModelId, o as profileBridgeWireModel } from "./model-policy-DgRJIJse.js";
|
|
5
|
-
import { C as unknownExecutionBindingReceipt, T as executableAgentProfileSnapshot, a as authoredProfileDigest, c as knownExecutionBindingReceipt, l as knownMaterializationReceipt, v as runtimeOwnedExecutorExecutionBinding, w as unknownMaterializationReceipt, x as runtimeOwnedPendingExecutorMaterialization, y as runtimeOwnedExecutorMaterialization } from "./materialization-CrdcfWXp.js";
|
|
6
6
|
import { canonicalCandidateDigest, renderInputPartsAsText } from "@tangle-network/agent-interface";
|
|
7
7
|
import { scoreKnowledgeReadiness } from "@tangle-network/agent-eval";
|
|
8
|
+
import { createAgentRunOutcomeTracker } from "@tangle-network/sandbox/runtime";
|
|
8
9
|
//#region src/sessions.ts
|
|
9
10
|
/**
|
|
10
11
|
*
|
|
@@ -431,7 +432,9 @@ async function* streamAgentTurnInternal(backend, input, opts) {
|
|
|
431
432
|
promptCache: {},
|
|
432
433
|
tokensKnown: false,
|
|
433
434
|
usdKnown: false,
|
|
434
|
-
sawLlmCall: false
|
|
435
|
+
sawLlmCall: false,
|
|
436
|
+
sawTokenUsage: false,
|
|
437
|
+
sawCostUsage: false
|
|
435
438
|
};
|
|
436
439
|
const deadline = deriveTurnSignal(opts.signal, opts.timeoutMs ?? 0);
|
|
437
440
|
const startedAt = Date.now();
|
|
@@ -517,10 +520,11 @@ async function* streamAgentTurnInternal(backend, input, opts) {
|
|
|
517
520
|
({materialization, executionBinding} = executorEvidence(executor, profile, attemptId));
|
|
518
521
|
assertExactExecutorEvidence(materialization, executionBinding);
|
|
519
522
|
}
|
|
520
|
-
|
|
523
|
+
const terminalOutcome = acc.sandboxOutcome ? projectSandboxOutcome(acc.sandboxOutcome) : {
|
|
521
524
|
status: "completed",
|
|
522
525
|
reason: "turn completed"
|
|
523
|
-
}
|
|
526
|
+
};
|
|
527
|
+
yield buildFinalEvent(task, session, acc, terminalOutcome, turnProvenance(startedAt, opts.timeoutMs, profileDigest, taskDigest, materialization, executionBinding, correlation));
|
|
524
528
|
} catch (err) {
|
|
525
529
|
if (materialization?.status === "unknown" && materialization.reason === "executor-receipt-pending" && executionBinding?.status === "unknown") {
|
|
526
530
|
const terminal = unknownMaterializationReceipt({
|
|
@@ -532,9 +536,10 @@ async function* streamAgentTurnInternal(backend, input, opts) {
|
|
|
532
536
|
materialization = terminal;
|
|
533
537
|
}
|
|
534
538
|
const callerAborted = opts.signal?.aborted === true;
|
|
535
|
-
const
|
|
536
|
-
const
|
|
537
|
-
const
|
|
539
|
+
const sandboxProjection = acc.sandboxOutcome ? projectSandboxOutcome(acc.sandboxOutcome) : void 0;
|
|
540
|
+
const status = callerAborted ? "aborted" : sandboxProjection?.status ?? "failed";
|
|
541
|
+
const message = sandboxProjection?.reason ?? (err instanceof Error ? err.message : String(err));
|
|
542
|
+
const error = sandboxProjection?.error ?? (err instanceof BackendTransportError ? {
|
|
538
543
|
kind: "transport",
|
|
539
544
|
message,
|
|
540
545
|
status: err.status,
|
|
@@ -542,7 +547,7 @@ async function* streamAgentTurnInternal(backend, input, opts) {
|
|
|
542
547
|
} : {
|
|
543
548
|
kind: "backend",
|
|
544
549
|
message
|
|
545
|
-
};
|
|
550
|
+
});
|
|
546
551
|
yield {
|
|
547
552
|
type: "backend_error",
|
|
548
553
|
task,
|
|
@@ -582,6 +587,7 @@ async function collectAgentTurn(stream) {
|
|
|
582
587
|
if (final?.type !== "final") throw new Error(`collectAgentTurn: stream ended without a terminal 'final' event (last: ${final ? final.type : "none"})`);
|
|
583
588
|
const metadata = final.metadata ?? {};
|
|
584
589
|
const resultMetadata = metadata.result && typeof metadata.result === "object" ? metadata.result : void 0;
|
|
590
|
+
const sandboxOutcome = metadata.sandboxOutcome && typeof metadata.sandboxOutcome === "object" ? metadata.sandboxOutcome : void 0;
|
|
585
591
|
const tokenUsage = metadata.tokenUsage && typeof metadata.tokenUsage === "object" ? metadata.tokenUsage : {};
|
|
586
592
|
const usage = {
|
|
587
593
|
input: finiteNumber(tokenUsage.input) ?? 0,
|
|
@@ -611,7 +617,8 @@ async function collectAgentTurn(stream) {
|
|
|
611
617
|
toolCalls,
|
|
612
618
|
events,
|
|
613
619
|
status: final.status,
|
|
614
|
-
...final.error ? { error: final.error } : {}
|
|
620
|
+
...final.error ? { error: final.error } : {},
|
|
621
|
+
...sandboxOutcome ? { sandboxOutcome } : {}
|
|
615
622
|
};
|
|
616
623
|
}
|
|
617
624
|
/** Start the backend's session when it owns one (`chat` kind); mint a local
|
|
@@ -645,7 +652,9 @@ async function* driveBoxTurn(box, input, signal, agentRunName, acc, cfg) {
|
|
|
645
652
|
signal
|
|
646
653
|
});
|
|
647
654
|
const toolParts = cfg.preserveToolParts ? createSandboxToolPartState() : void 0;
|
|
655
|
+
const outcomeTracker = createAgentRunOutcomeTracker();
|
|
648
656
|
for await (const event of abortableValues(stream, signal)) {
|
|
657
|
+
outcomeTracker.observe(event);
|
|
649
658
|
if (cfg.onRawEvent) await awaitAbortable(Promise.resolve().then(() => cfg.onRawEvent(event)), signal);
|
|
650
659
|
const terminalText = terminalTextFromSandboxEvent(event);
|
|
651
660
|
if (terminalText !== void 0) acc.terminalText = terminalText;
|
|
@@ -661,6 +670,9 @@ async function* driveBoxTurn(box, input, signal, agentRunName, acc, cfg) {
|
|
|
661
670
|
yield mapped;
|
|
662
671
|
}
|
|
663
672
|
}
|
|
673
|
+
acc.sandboxOutcome = outcomeTracker.finish();
|
|
674
|
+
const projection = projectSandboxOutcome(acc.sandboxOutcome);
|
|
675
|
+
if (projection.status === "failed") throw new Error(projection.reason);
|
|
664
676
|
}
|
|
665
677
|
/** One turn over an in-process backend: its own `stream()` surface, projected
|
|
666
678
|
* through the same `normalizeBackendStreamEvent` the task lifecycle applies. */
|
|
@@ -683,10 +695,14 @@ async function* driveExecutorTurn(executor, task, session, input, signal, acc, d
|
|
|
683
695
|
const run = executor.execute(taskValue, signal);
|
|
684
696
|
let result;
|
|
685
697
|
if (isAsyncIterable(run)) {
|
|
686
|
-
for await (const
|
|
698
|
+
for await (const usage of abortableValues(run, signal)) {
|
|
699
|
+
foldUsageEvent(usage, acc);
|
|
700
|
+
throwIfAborted(signal);
|
|
701
|
+
}
|
|
687
702
|
result = executor.resultArtifact();
|
|
688
703
|
} else result = await awaitAbortable(run, signal);
|
|
689
704
|
acc.result = result;
|
|
705
|
+
acc.sandboxOutcome = readSandboxOutcome(result.out);
|
|
690
706
|
acc.terminalText = executorResultText(result.out);
|
|
691
707
|
acc.input = result.spent.tokens.input;
|
|
692
708
|
acc.output = result.spent.tokens.output;
|
|
@@ -744,6 +760,7 @@ async function* driveExecutorTurn(executor, task, session, input, signal, acc, d
|
|
|
744
760
|
},
|
|
745
761
|
timestamp: nowIso()
|
|
746
762
|
};
|
|
763
|
+
if (acc.sandboxOutcome && projectSandboxOutcome(acc.sandboxOutcome).status === "failed") throw new Error(projectSandboxOutcome(acc.sandboxOutcome).reason);
|
|
747
764
|
}
|
|
748
765
|
function executorTaskValue(input) {
|
|
749
766
|
const messages = input.providerOptions?.messages;
|
|
@@ -835,6 +852,26 @@ function executorResultToolCalls(value) {
|
|
|
835
852
|
}];
|
|
836
853
|
});
|
|
837
854
|
}
|
|
855
|
+
/** Fold one normalized executor usage event into the turn accumulator. */
|
|
856
|
+
function foldUsageEvent(event, acc) {
|
|
857
|
+
if (event.kind === "tokens") {
|
|
858
|
+
const known = event.tokensKnown !== false;
|
|
859
|
+
acc.tokensKnown = acc.sawTokenUsage ? acc.tokensKnown && known : known;
|
|
860
|
+
acc.sawTokenUsage = true;
|
|
861
|
+
acc.input += event.input;
|
|
862
|
+
acc.output += event.output;
|
|
863
|
+
} else if (event.kind === "cost") {
|
|
864
|
+
const known = event.usdKnown !== false;
|
|
865
|
+
acc.usdKnown = acc.sawCostUsage ? acc.usdKnown && known : known;
|
|
866
|
+
acc.sawCostUsage = true;
|
|
867
|
+
acc.costUsd += event.usd;
|
|
868
|
+
if (event.usdEstimated !== void 0) {
|
|
869
|
+
acc.estimatedCostUsd += event.usdEstimated;
|
|
870
|
+
acc.sawEstimatedCost = true;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
if (event.kind === "tokens" || event.kind === "cost") acc.sawLlmCall = true;
|
|
874
|
+
}
|
|
838
875
|
/** Fold one normalized event into the turn accumulator (text + usage).
|
|
839
876
|
* `fallbackModelLabel` — a mapper-stamped run label to exclude from
|
|
840
877
|
* `usage.model` (it is not a backend-reported model). */
|
|
@@ -903,12 +940,16 @@ function buildFinalEvent(task, session, acc, outcome, provenance) {
|
|
|
903
940
|
...acc.model ? { model: acc.model } : {},
|
|
904
941
|
...acc.stopReason ? { stopReason: acc.stopReason } : {},
|
|
905
942
|
...acc.transportAttempts !== void 0 ? { transportAttempts: acc.transportAttempts } : {},
|
|
943
|
+
...acc.sandboxOutcome ? {
|
|
944
|
+
sandboxOutcome: acc.sandboxOutcome,
|
|
945
|
+
verdict: projectSandboxOutcome(acc.sandboxOutcome).verdict
|
|
946
|
+
} : {},
|
|
906
947
|
...acc.result ? { result: {
|
|
907
948
|
outRef: acc.result.outRef,
|
|
908
949
|
output: acc.result.out,
|
|
909
|
-
...acc.result.verdict ? { verdict: acc.result.verdict } : {},
|
|
950
|
+
...acc.sandboxOutcome ? { verdict: projectSandboxOutcome(acc.sandboxOutcome).verdict } : acc.result.verdict ? { verdict: acc.result.verdict } : {},
|
|
910
951
|
spent: acc.result.spent
|
|
911
|
-
} } : {},
|
|
952
|
+
} } : acc.sandboxOutcome ? { result: { verdict: projectSandboxOutcome(acc.sandboxOutcome).verdict } } : {},
|
|
912
953
|
...provenance
|
|
913
954
|
},
|
|
914
955
|
...outcome.error ? { error: outcome.error } : {},
|
|
@@ -959,4 +1000,4 @@ function deriveTurnSignal(callerSignal, timeoutMs) {
|
|
|
959
1000
|
//#endregion
|
|
960
1001
|
export { normalizeBackendStreamEvent as a, nowIso as c, createSandboxPromptBackend as i, startOrResumeRuntimeSession as l, streamAgentTurn as n, InMemoryRuntimeSessionStore as o, createIterableBackend as r, newRuntimeSession as s, collectAgentTurn as t, touchSession as u };
|
|
961
1002
|
|
|
962
|
-
//# sourceMappingURL=stream-agent-turn-
|
|
1003
|
+
//# sourceMappingURL=stream-agent-turn-CXRugSGO.js.map
|