@tangle-network/agent-runtime 0.30.1 → 0.32.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/{chunk-QZEDHTT2.js → chunk-IORDTTVB.js} +35 -2
- package/dist/{chunk-QZEDHTT2.js.map → chunk-IORDTTVB.js.map} +1 -1
- package/dist/{chunk-TZ53F7M7.js → chunk-PACEJFUE.js} +59 -4
- package/dist/chunk-PACEJFUE.js.map +1 -0
- package/dist/{chunk-ZJACJZF7.js → chunk-XNZYEQMF.js} +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/loops.d.ts +103 -4
- package/dist/loops.js +7 -1
- package/dist/mcp/bin.js +2 -2
- package/dist/mcp/index.d.ts +3 -3
- package/dist/mcp/index.js +3 -3
- package/dist/{otel-export-B2UBcPV4.d.ts → otel-export-CsgwKFq8.d.ts} +56 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/{types-Cbe54nB7.d.ts → types-Co507h15.d.ts} +15 -1
- package/package.json +4 -4
- package/dist/chunk-TZ53F7M7.js.map +0 -1
- /package/dist/{chunk-ZJACJZF7.js.map → chunk-XNZYEQMF.js.map} +0 -0
package/dist/loops.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export { AgentProfile, CreateSandboxOptions, SandboxEvent, SandboxInstance } from '@tangle-network/sandbox';
|
|
2
|
-
import { D as Driver, I as Iteration, A as AgentRunSpec, O as OutputAdapter, V as Validator, E as ExecCtx, L as LoopWinner, a as LoopResult } from './types-
|
|
3
|
-
export {
|
|
4
|
-
import { DefaultVerdict } from '@tangle-network/agent-eval';
|
|
2
|
+
import { D as Driver, I as Iteration, A as AgentRunSpec, O as OutputAdapter, V as Validator, E as ExecCtx, L as LoopWinner, a as LoopResult, b as LoopSandboxClient } from './types-Co507h15.js';
|
|
3
|
+
export { c as LoopDecisionPayload, d as LoopEndedPayload, e as LoopIterationDispatchPayload, f as LoopIterationEndedPayload, g as LoopIterationStartedPayload, h as LoopSandboxPlacement, i as LoopStartedPayload, j as LoopTokenUsage, k as LoopTraceEmitter, l as LoopTraceEvent, m as ValidationCtx } from './types-Co507h15.js';
|
|
4
|
+
import { DefaultVerdict, AgentProfile } from '@tangle-network/agent-eval';
|
|
5
5
|
export { DefaultVerdict } from '@tangle-network/agent-eval';
|
|
6
|
+
import { Scenario, DispatchFn, ProfileDispatchFn } from '@tangle-network/agent-eval/campaign';
|
|
6
7
|
import './runtime-run-B8VIiOhI.js';
|
|
7
8
|
import './types-CsCCryln.js';
|
|
8
9
|
|
|
@@ -153,4 +154,102 @@ interface RunLoopOptions<Task, Output, Decision> {
|
|
|
153
154
|
/** @experimental */
|
|
154
155
|
declare function runLoop<Task, Output, Decision>(options: RunLoopOptions<Task, Output, Decision>): Promise<LoopResult<Task, Output, Decision>>;
|
|
155
156
|
|
|
156
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Bridge a finished `runLoop` into an agent-eval campaign / profile-matrix
|
|
159
|
+
* dispatch.
|
|
160
|
+
*
|
|
161
|
+
* `runProfileMatrix` (and `runCampaign`) run the backend-integrity guard over
|
|
162
|
+
* the token usage a dispatch reports through `ctx.cost`. A dispatch that wraps
|
|
163
|
+
* `runLoop` must forward the loop's cost AND token usage, or the guard reads
|
|
164
|
+
* the run as a stub and throws. `reportLoopUsage` is that one line:
|
|
165
|
+
*
|
|
166
|
+
* const dispatch: ProfileDispatchFn<S, A> = async (profile, scenario, ctx) => {
|
|
167
|
+
* const result = await runLoop({ ...optsFor(profile, scenario), ctx: loopCtx })
|
|
168
|
+
* reportLoopUsage(ctx, result)
|
|
169
|
+
* return result.winner?.output as A
|
|
170
|
+
* }
|
|
171
|
+
*
|
|
172
|
+
* Typed structurally against the campaign `DispatchContext.cost` so this module
|
|
173
|
+
* stays free of an agent-eval import — it works with any cost meter exposing
|
|
174
|
+
* `observe` + `observeTokens`.
|
|
175
|
+
*/
|
|
176
|
+
|
|
177
|
+
/** The slice of an agent-eval campaign `DispatchContext.cost` this needs. */
|
|
178
|
+
interface UsageSink {
|
|
179
|
+
observe(amountUsd: number, source: string): void;
|
|
180
|
+
observeTokens(usage: {
|
|
181
|
+
input: number;
|
|
182
|
+
output: number;
|
|
183
|
+
}): void;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Forward a `LoopResult`'s aggregated cost + token usage into a campaign cost
|
|
187
|
+
* meter so the backend-integrity guard sees real LLM activity. `source`
|
|
188
|
+
* defaults to `'loop'`.
|
|
189
|
+
*/
|
|
190
|
+
declare function reportLoopUsage<Task, Output, Decision>(cost: UsageSink, result: Pick<LoopResult<Task, Output, Decision>, 'costUsd' | 'tokenUsage'>, source?: string): void;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* `loopDispatch` — turn `runLoop` into an agent-eval campaign dispatch.
|
|
194
|
+
*
|
|
195
|
+
* Without this adapter a consumer wiring `runLoop` into `runProfileMatrix` /
|
|
196
|
+
* `runCampaign` has to, by hand, every time: (a) build an `ExecCtx` with a
|
|
197
|
+
* sandbox client, (b) adapt the campaign `DispatchContext.trace` into a
|
|
198
|
+
* `LoopTraceEmitter` (or lose all loop trace correlation), and (c) remember to
|
|
199
|
+
* forward the loop's cost + tokens via `ctx.cost` (forgetting it yields a
|
|
200
|
+
* `{0,0}` cell the backend-integrity guard reads as a stub). Three foot-guns,
|
|
201
|
+
* the third silent. The fleet's products skipped (c) and fell back to a
|
|
202
|
+
* `workerRecords[]` side-channel — the exact anti-pattern the substrate exists
|
|
203
|
+
* to kill.
|
|
204
|
+
*
|
|
205
|
+
* `loopDispatch` collapses all three into one typed call:
|
|
206
|
+
*
|
|
207
|
+
* const dispatch = loopDispatch({
|
|
208
|
+
* sandboxClient,
|
|
209
|
+
* toLoopOptions: (scenario, profile) => ({ driver, agentRun, output, validator, task }),
|
|
210
|
+
* })
|
|
211
|
+
* await runProfileMatrix({ profiles, scenarios, dispatch, judges, commitSha })
|
|
212
|
+
*
|
|
213
|
+
* Usage is reported automatically; trace events are forwarded automatically;
|
|
214
|
+
* the ctx is built automatically. The seam becomes impossible to mis-wire.
|
|
215
|
+
*
|
|
216
|
+
* Typed structurally against the campaign `DispatchContext` (imported type-only
|
|
217
|
+
* from `@tangle-network/agent-eval/campaign`) — a downward dependency, never an
|
|
218
|
+
* inversion.
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
/** runLoop options minus the `ctx` (loopDispatch builds the ctx). */
|
|
222
|
+
type LoopOptionsForDispatch<Task, Output, Decision> = Omit<RunLoopOptions<Task, Output, Decision>, 'ctx'>;
|
|
223
|
+
interface LoopDispatchOptions<Task, Output, Decision, TScenario extends Scenario, TArtifact> {
|
|
224
|
+
/** Sandbox client used for every cell's `runLoop`. Supplied once. */
|
|
225
|
+
sandboxClient: LoopSandboxClient;
|
|
226
|
+
/** Build the per-cell runLoop options from the scenario (+ profile, when
|
|
227
|
+
* used with `runProfileMatrix`). */
|
|
228
|
+
toLoopOptions: (scenario: TScenario, profile: AgentProfile) => LoopOptionsForDispatch<Task, Output, Decision>;
|
|
229
|
+
/** Map the finished loop to the artifact the judges score. Default:
|
|
230
|
+
* `result.winner?.output`. A loop with no winner yields `undefined` (judges
|
|
231
|
+
* skip the cell) — but the loop's token usage is STILL reported, so the
|
|
232
|
+
* integrity guard sees real activity. */
|
|
233
|
+
toArtifact?: (result: LoopResult<Task, Output, Decision>) => TArtifact;
|
|
234
|
+
/** Forward `loop.*` trace events into the campaign's scoped trace so loop
|
|
235
|
+
* spans correlate with the cell. Default true. */
|
|
236
|
+
forwardTrace?: boolean;
|
|
237
|
+
/** Cost-meter source label for the loop's spend. Default `'loop'`. */
|
|
238
|
+
costSource?: string;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Adapter for `runProfileMatrix` (profile is an axis). Returns a
|
|
242
|
+
* `ProfileDispatchFn` that runs `runLoop` per (profile, scenario) cell and
|
|
243
|
+
* reports usage automatically.
|
|
244
|
+
*/
|
|
245
|
+
declare function loopDispatch<Task, Output, Decision, TScenario extends Scenario, TArtifact>(opts: LoopDispatchOptions<Task, Output, Decision, TScenario, TArtifact>): ProfileDispatchFn<TScenario, TArtifact>;
|
|
246
|
+
/**
|
|
247
|
+
* Adapter for `runCampaign` (no profile axis). `toLoopOptions` receives only
|
|
248
|
+
* the scenario; the `profile` passed to the shared core is a stable sentinel
|
|
249
|
+
* so a single `runLoop` config is reused across cells.
|
|
250
|
+
*/
|
|
251
|
+
declare function loopCampaignDispatch<Task, Output, Decision, TScenario extends Scenario, TArtifact>(opts: Omit<LoopDispatchOptions<Task, Output, Decision, TScenario, TArtifact>, 'toLoopOptions'> & {
|
|
252
|
+
toLoopOptions: (scenario: TScenario) => LoopOptionsForDispatch<Task, Output, Decision>;
|
|
253
|
+
}): DispatchFn<TScenario, TArtifact>;
|
|
254
|
+
|
|
255
|
+
export { AgentRunSpec, type CreateFanoutVoteDriverOptions, type CreateRefineDriverOptions, Driver, ExecCtx, type FanoutVoteDecision, type FanoutVoteScored, Iteration, type LoopDispatchOptions, type LoopOptionsForDispatch, LoopResult, LoopSandboxClient, LoopWinner, OutputAdapter, type RefineDecision, type RunLoopOptions, type UsageSink, Validator, createFanoutVoteDriver, createRefineDriver, loopCampaignDispatch, loopDispatch, refineWinnerIndex, reportLoopUsage, runLoop, scoreFanoutVoteIterations };
|
package/dist/loops.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createRefineDriver,
|
|
3
|
+
loopCampaignDispatch,
|
|
4
|
+
loopDispatch,
|
|
3
5
|
refineWinnerIndex,
|
|
6
|
+
reportLoopUsage,
|
|
4
7
|
runLoop
|
|
5
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-PACEJFUE.js";
|
|
6
9
|
import {
|
|
7
10
|
createFanoutVoteDriver,
|
|
8
11
|
scoreFanoutVoteIterations
|
|
@@ -12,7 +15,10 @@ import "./chunk-DGUM43GV.js";
|
|
|
12
15
|
export {
|
|
13
16
|
createFanoutVoteDriver,
|
|
14
17
|
createRefineDriver,
|
|
18
|
+
loopCampaignDispatch,
|
|
19
|
+
loopDispatch,
|
|
15
20
|
refineWinnerIndex,
|
|
21
|
+
reportLoopUsage,
|
|
16
22
|
runLoop,
|
|
17
23
|
scoreFanoutVoteIterations
|
|
18
24
|
};
|
package/dist/mcp/bin.js
CHANGED
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
createDefaultCoderDelegate,
|
|
4
4
|
createMcpServer,
|
|
5
5
|
detectExecutor
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-XNZYEQMF.js";
|
|
7
7
|
import "../chunk-UNQM6XQO.js";
|
|
8
8
|
import "../chunk-GLR25NG7.js";
|
|
9
9
|
import {
|
|
10
10
|
runLoop
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-PACEJFUE.js";
|
|
12
12
|
import "../chunk-CBQVID7G.js";
|
|
13
13
|
import "../chunk-URDSRUPQ.js";
|
|
14
14
|
import "../chunk-XZYF3YJN.js";
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b as LoopSandboxClient, h as LoopSandboxPlacement, k as LoopTraceEmitter } from '../types-Co507h15.js';
|
|
2
2
|
import { SandboxInstance } from '@tangle-network/sandbox';
|
|
3
3
|
import { CoderOutput } from '../profiles.js';
|
|
4
4
|
import { L as LocalHarness, r as runLocalHarness } from '../local-harness-KrdFTY5R.js';
|
|
5
5
|
export { a as LocalHarnessResult, R as RunLocalHarnessOptions } from '../local-harness-KrdFTY5R.js';
|
|
6
|
-
import { O as OtelExporter } from '../otel-export-
|
|
7
|
-
export { m as mcpToolsForRuntimeMcp, a as mcpToolsForRuntimeMcpSubset } from '../otel-export-
|
|
6
|
+
import { O as OtelExporter } from '../otel-export-CsgwKFq8.js';
|
|
7
|
+
export { m as mcpToolsForRuntimeMcp, a as mcpToolsForRuntimeMcpSubset } from '../otel-export-CsgwKFq8.js';
|
|
8
8
|
import '@tangle-network/agent-eval';
|
|
9
9
|
import '../runtime-run-B8VIiOhI.js';
|
|
10
10
|
import '../types-CsCCryln.js';
|
package/dist/mcp/index.js
CHANGED
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
createWorktree,
|
|
10
10
|
detectExecutor,
|
|
11
11
|
removeWorktree
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-XNZYEQMF.js";
|
|
13
13
|
import {
|
|
14
14
|
createOtelExporter,
|
|
15
15
|
loopEventToOtelSpan,
|
|
16
16
|
mcpToolsForRuntimeMcp,
|
|
17
17
|
mcpToolsForRuntimeMcpSubset
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-IORDTTVB.js";
|
|
19
19
|
import {
|
|
20
20
|
DELEGATE_CODE_DESCRIPTION,
|
|
21
21
|
DELEGATE_CODE_INPUT_SCHEMA,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
import {
|
|
51
51
|
runLocalHarness
|
|
52
52
|
} from "../chunk-GLR25NG7.js";
|
|
53
|
-
import "../chunk-
|
|
53
|
+
import "../chunk-PACEJFUE.js";
|
|
54
54
|
import "../chunk-CBQVID7G.js";
|
|
55
55
|
import "../chunk-URDSRUPQ.js";
|
|
56
56
|
import "../chunk-XZYF3YJN.js";
|
|
@@ -110,5 +110,60 @@ declare function loopEventToOtelSpan(event: {
|
|
|
110
110
|
timestamp: number;
|
|
111
111
|
payload: object;
|
|
112
112
|
}, traceId: string, parentSpanId?: string): OtelSpan;
|
|
113
|
+
/** Wire version the eval-runs ingest enforces (X-Tangle-Wire-Version + body). */
|
|
114
|
+
declare const INTELLIGENCE_WIRE_VERSION = "2026-05-26.v1";
|
|
115
|
+
interface EvalRunGeneration {
|
|
116
|
+
/** 0-based ordinal of this generation within the run (required by ingest). */
|
|
117
|
+
index: number;
|
|
118
|
+
/** Identity of the proposed surface change (content-addressed hash). */
|
|
119
|
+
surfaceHash: string;
|
|
120
|
+
/** Arbitrary provenance for this generation (rationale, evidence, source). */
|
|
121
|
+
surface?: unknown;
|
|
122
|
+
/** Per-scenario results; empty until the generation is measured. */
|
|
123
|
+
cells?: unknown[];
|
|
124
|
+
/** Mean composite score (0 when unmeasured — pair with labels.measured). */
|
|
125
|
+
compositeMean: number;
|
|
126
|
+
costUsd: number;
|
|
127
|
+
durationMs: number;
|
|
128
|
+
}
|
|
129
|
+
interface EvalRunEvent {
|
|
130
|
+
runId: string;
|
|
131
|
+
runDir: string;
|
|
132
|
+
/** ISO timestamp. */
|
|
133
|
+
timestamp: string;
|
|
134
|
+
status: 'started' | 'baseline-complete' | 'generation-complete' | 'gate-decided' | 'finished' | 'errored';
|
|
135
|
+
labels?: Record<string, string>;
|
|
136
|
+
baseline?: EvalRunGeneration;
|
|
137
|
+
generations?: EvalRunGeneration[];
|
|
138
|
+
gateDecision?: 'ship' | 'hold' | 'need_more_work' | 'model_ceiling' | 'arch_ceiling';
|
|
139
|
+
holdoutLift?: number;
|
|
140
|
+
totalCostUsd: number;
|
|
141
|
+
totalDurationMs: number;
|
|
142
|
+
errorMessage?: string;
|
|
143
|
+
}
|
|
144
|
+
interface EvalRunsExportConfig {
|
|
145
|
+
/** Bearer key — tenant is resolved server-side from it. Reads TANGLE_API_KEY. */
|
|
146
|
+
apiKey?: string;
|
|
147
|
+
/** Intelligence base. Reads INTELLIGENCE_BASE env, else prod. */
|
|
148
|
+
base?: string;
|
|
149
|
+
/** Idempotency-Key header (e.g. the runId) — safe retries + upsert. */
|
|
150
|
+
idempotencyKey?: string;
|
|
151
|
+
}
|
|
152
|
+
interface EvalRunsExportResult {
|
|
153
|
+
ok: boolean;
|
|
154
|
+
status: number;
|
|
155
|
+
accepted: number;
|
|
156
|
+
rejected: Array<{
|
|
157
|
+
index: number;
|
|
158
|
+
reason: string;
|
|
159
|
+
}>;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Ship self-improvement eval-run events to Tangle Intelligence. Unlike the
|
|
163
|
+
* best-effort span exporter, this RESOLVES with the ingest verdict (accepted /
|
|
164
|
+
* rejected per event) so a consumer's loop can assert its provenance landed.
|
|
165
|
+
* Throws only on a missing key or network failure.
|
|
166
|
+
*/
|
|
167
|
+
declare function exportEvalRuns(events: EvalRunEvent[], config?: EvalRunsExportConfig): Promise<EvalRunsExportResult>;
|
|
113
168
|
|
|
114
|
-
export { type OtelExporter as O, mcpToolsForRuntimeMcpSubset as a, type
|
|
169
|
+
export { type EvalRunEvent as E, INTELLIGENCE_WIRE_VERSION as I, type OtelExporter as O, mcpToolsForRuntimeMcpSubset as a, type EvalRunGeneration as b, type EvalRunsExportConfig as c, type EvalRunsExportResult as d, type OtelAttribute as e, type OtelExportConfig as f, type OtelSpan as g, createOtelExporter as h, exportEvalRuns as i, loopEventToOtelSpan as l, mcpToolsForRuntimeMcp as m };
|
package/dist/profiles.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentProfile } from '@tangle-network/sandbox';
|
|
2
|
-
import { O as OutputAdapter, V as Validator, A as AgentRunSpec, D as Driver } from './types-
|
|
2
|
+
import { O as OutputAdapter, V as Validator, A as AgentRunSpec, D as Driver } from './types-Co507h15.js';
|
|
3
3
|
import '@tangle-network/agent-eval';
|
|
4
4
|
import './runtime-run-B8VIiOhI.js';
|
|
5
5
|
import './types-CsCCryln.js';
|
|
@@ -74,6 +74,14 @@ interface AgentRunSpec<Task> {
|
|
|
74
74
|
interface OutputAdapter<Output> {
|
|
75
75
|
parse(events: SandboxEvent[]): Output;
|
|
76
76
|
}
|
|
77
|
+
/** LLM token usage. Structurally matches agent-eval's `RunTokenUsage` /
|
|
78
|
+
* `CampaignTokenUsage` ({ input, output }) so a loop result maps straight
|
|
79
|
+
* onto `ctx.cost.observeTokens` in a `runProfileMatrix` dispatch — without
|
|
80
|
+
* which the backend-integrity guard reads the run as a stub. */
|
|
81
|
+
interface LoopTokenUsage {
|
|
82
|
+
input: number;
|
|
83
|
+
output: number;
|
|
84
|
+
}
|
|
77
85
|
/** @experimental */
|
|
78
86
|
interface Iteration<Task, Output> {
|
|
79
87
|
/** 0-based iteration index assigned by the kernel. */
|
|
@@ -89,6 +97,8 @@ interface Iteration<Task, Output> {
|
|
|
89
97
|
startedAt: number;
|
|
90
98
|
endedAt: number;
|
|
91
99
|
costUsd: number;
|
|
100
|
+
/** Summed LLM token usage across every `llm_call` event in this iteration. */
|
|
101
|
+
tokenUsage: LoopTokenUsage;
|
|
92
102
|
}
|
|
93
103
|
/** @experimental */
|
|
94
104
|
interface Driver<Task, Output, Decision> {
|
|
@@ -125,6 +135,10 @@ interface LoopResult<Task, Output, Decision> {
|
|
|
125
135
|
durationMs: number;
|
|
126
136
|
/** Sum of every iteration's `costUsd`. */
|
|
127
137
|
costUsd: number;
|
|
138
|
+
/** Sum of every iteration's token usage. Forward to
|
|
139
|
+
* `ctx.cost.observeTokens` in a `runProfileMatrix` dispatch so the
|
|
140
|
+
* integrity guard sees real LLM activity. */
|
|
141
|
+
tokenUsage: LoopTokenUsage;
|
|
128
142
|
}
|
|
129
143
|
/**
|
|
130
144
|
* Minimal sandbox client surface the kernel calls. Satisfied structurally by
|
|
@@ -267,4 +281,4 @@ interface ExecCtx {
|
|
|
267
281
|
parentSpanId?: string;
|
|
268
282
|
}
|
|
269
283
|
|
|
270
|
-
export type { AgentRunSpec as A, Driver as D, ExecCtx as E, Iteration as I, LoopWinner as L, OutputAdapter as O, Validator as V, LoopResult as a,
|
|
284
|
+
export type { AgentRunSpec as A, Driver as D, ExecCtx as E, Iteration as I, LoopWinner as L, OutputAdapter as O, Validator as V, LoopResult as a, LoopSandboxClient as b, LoopDecisionPayload as c, LoopEndedPayload as d, LoopIterationDispatchPayload as e, LoopIterationEndedPayload as f, LoopIterationStartedPayload as g, LoopSandboxPlacement as h, LoopStartedPayload as i, LoopTokenUsage as j, LoopTraceEmitter as k, LoopTraceEvent as l, ValidationCtx as m };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Reusable runtime lifecycle for domain-specific agents.",
|
|
5
5
|
"homepage": "https://github.com/tangle-network/agent-runtime#readme",
|
|
6
6
|
"repository": {
|
|
@@ -65,11 +65,10 @@
|
|
|
65
65
|
"publishConfig": {
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
|
-
"dependencies": {
|
|
69
|
-
"@tangle-network/agent-eval": "^0.54.0"
|
|
70
|
-
},
|
|
68
|
+
"dependencies": {},
|
|
71
69
|
"devDependencies": {
|
|
72
70
|
"@biomejs/biome": "^2.4.0",
|
|
71
|
+
"@tangle-network/agent-eval": "^0.61.0",
|
|
73
72
|
"@tangle-network/sandbox": "^0.4.0",
|
|
74
73
|
"@types/node": "^25.6.0",
|
|
75
74
|
"tsup": "^8.0.0",
|
|
@@ -81,6 +80,7 @@
|
|
|
81
80
|
},
|
|
82
81
|
"license": "MIT",
|
|
83
82
|
"peerDependencies": {
|
|
83
|
+
"@tangle-network/agent-eval": ">=0.61.0 <1.0.0",
|
|
84
84
|
"@tangle-network/agent-knowledge": ">=1.3.0 <2.0.0",
|
|
85
85
|
"@tangle-network/sandbox": ">=0.1.2 <0.5.0"
|
|
86
86
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/loops/drivers/refine.ts","../src/loops/run-loop.ts"],"sourcesContent":["/**\n * @experimental\n *\n * Refine driver — single task per iteration, validator-gated.\n *\n * `plan` returns `[task]` (possibly transformed via `refineTask`) until the\n * prior verdict is valid OR the local cap is hit, then `[]`.\n * `decide` returns `'stop'` once the latest verdict is valid OR the cap is\n * reached. The kernel's `maxIterations` is an orthogonal safety cap;\n * whichever is lower wins.\n */\n\nimport { ValidationError } from '../../errors'\nimport type { DefaultVerdict, Driver, Iteration } from '../types'\n\nexport type RefineDecision = 'continue' | 'stop'\n\n/** @experimental */\nexport interface CreateRefineDriverOptions<Task> {\n /** Hard cap on iterations. Default 5. */\n maxIterations?: number\n /**\n * Optional task transform applied each round based on the prior verdict.\n * When omitted, the same task is replayed and the agent is expected to\n * inspect the sandbox session state for prior attempts.\n */\n refineTask?: (task: Task, prior: DefaultVerdict) => Task\n /** Stable identifier surfaced in trace events. Default `'refine'`. */\n name?: string\n}\n\n/** @experimental */\nexport function createRefineDriver<Task, Output>(\n options: CreateRefineDriverOptions<Task> = {},\n): Driver<Task, Output, RefineDecision> {\n const maxIterations = options.maxIterations ?? 5\n if (!Number.isFinite(maxIterations) || maxIterations <= 0) {\n throw new ValidationError('createRefineDriver: maxIterations must be > 0')\n }\n const refineTask = options.refineTask\n return {\n name: options.name ?? 'refine',\n async plan(task, history) {\n if (history.length >= maxIterations) return []\n if (history.length === 0) return [task]\n const prior = history.at(-1)\n if (!prior) return [task]\n if (prior.verdict?.valid === true) return []\n // Worker error: replay the same task so the agent can self-correct.\n // The driver has no signal beyond `verdict`; only the validator\n // controls \"good enough\".\n if (!refineTask || !prior.verdict) return [prior.task]\n return [refineTask(prior.task, prior.verdict)]\n },\n decide(history) {\n const last = history.at(-1)\n if (!last) return 'continue'\n if (last.verdict?.valid === true) return 'stop'\n if (history.length >= maxIterations) return 'stop'\n return 'continue'\n },\n }\n}\n\n/**\n * Test helper: select the last-valid iteration (or the last attempt if\n * none passed). Mirrors the kernel's default selector ordering for refine\n * topologies — the most recent successful attempt wins.\n *\n * @experimental\n */\nexport function refineWinnerIndex<Task, Output>(\n iterations: ReadonlyArray<Iteration<Task, Output>>,\n): number | undefined {\n for (let i = iterations.length - 1; i >= 0; i -= 1) {\n if (iterations[i]?.verdict?.valid) return i\n }\n return iterations.length > 0 ? iterations.length - 1 : undefined\n}\n","/**\n * @experimental\n *\n * `runLoop` — the topology-agnostic kernel built atop the sandbox SDK.\n *\n * Each iteration:\n * 1. `driver.plan(task, history)` → N tasks (1 = refine, N = fanout, 0 = stop)\n * 2. For each task (parallel, bounded by `maxConcurrency`):\n * a. round-robin an `AgentRunSpec` from `agentRuns`\n * b. `sandboxClient.create({ backend: { profile }, ...overrides })`\n * c. emit `loop.iteration.dispatch` with the placement\n * (`{ sibling, sandboxId }` or `{ fleet, fleetId, machineId, sandboxId }`)\n * d. iterate `box.streamPrompt(taskToPrompt(task))` and collect events\n * 3. `output.parse(events)` → typed `Output`\n * 4. `validator?.validate(output)` → `DefaultVerdict`\n * 5. Append `Iteration` to history; emit `loop.iteration.ended`\n * 6. `driver.decide(history)` → if terminal, return result + winner\n *\n * The kernel owns: iteration accounting, per-iteration timing, error\n * capture, abort propagation, concurrency cap, cost aggregation, and trace\n * emission. The kernel does NOT own: what the agent runs (sandbox SDK +\n * profile), how outputs are decoded (output adapter), how outputs are\n * scored (validator), or topology (driver).\n */\n\nimport type {\n AgentProfile,\n CreateSandboxOptions,\n SandboxEvent,\n SandboxInstance,\n} from '@tangle-network/sandbox'\nimport { ValidationError } from '../errors'\nimport type { RuntimeStreamEvent } from '../types'\nimport type {\n AgentRunSpec,\n Driver,\n ExecCtx,\n Iteration,\n LoopResult,\n LoopSandboxClient,\n LoopSandboxPlacement,\n LoopTraceEmitter,\n LoopTraceEvent,\n LoopWinner,\n OutputAdapter,\n Validator,\n} from './types'\n\nconst DEFAULT_MAX_ITERATIONS = 10\nconst DEFAULT_MAX_CONCURRENCY = 4\n\n/** @experimental */\nexport interface RunLoopOptions<Task, Output, Decision> {\n driver: Driver<Task, Output, Decision>\n /**\n * Single agent spec — every iteration uses this profile. Mutually\n * exclusive with `agentRuns`.\n */\n agentRun?: AgentRunSpec<Task>\n /**\n * Multiple specs for heterogeneous fanout. The kernel round-robins\n * through them when the driver plans N tasks. Mutually exclusive with\n * `agentRun`.\n */\n agentRuns?: AgentRunSpec<Task>[]\n output: OutputAdapter<Output>\n validator?: Validator<Output>\n task: Task\n ctx: ExecCtx\n /** Default 10. Hard cap on total iterations across all `plan()` rounds. */\n maxIterations?: number\n /** Default 4. In-flight worker cap within a single `plan()` batch. */\n maxConcurrency?: number\n /**\n * Pre-allocated id for trace correlation. Default = `loop-${random}`.\n * Surfaces as `runId` on every emitted `LoopTraceEvent`.\n */\n runId?: string\n /**\n * Clock override; default `Date.now`. Deterministic tests pass a\n * monotonic counter to stabilize iteration timing fields.\n */\n now?: () => number\n /**\n * Override the default winner selector (highest-valid-score, ties broken\n * by earliest iteration).\n */\n selectWinner?: (iterations: Iteration<Task, Output>[]) => LoopWinner<Task, Output> | undefined\n}\n\n/** @experimental */\nexport async function runLoop<Task, Output, Decision>(\n options: RunLoopOptions<Task, Output, Decision>,\n): Promise<LoopResult<Task, Output, Decision>> {\n const specs = resolveAgentRuns(options)\n const maxIterations = options.maxIterations ?? DEFAULT_MAX_ITERATIONS\n if (!Number.isFinite(maxIterations) || maxIterations <= 0) {\n throw new ValidationError('runLoop: maxIterations must be > 0')\n }\n const maxConcurrency = options.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY\n if (!Number.isFinite(maxConcurrency) || maxConcurrency <= 0) {\n throw new ValidationError('runLoop: maxConcurrency must be > 0')\n }\n if (!options.ctx?.sandboxClient || typeof options.ctx.sandboxClient.create !== 'function') {\n throw new ValidationError('runLoop: ctx.sandboxClient.create is required')\n }\n const now = options.now ?? Date.now\n const runId = options.runId ?? `loop-${randomSuffix()}`\n const loopStart = now()\n const driverName = options.driver.name ?? 'driver'\n const iterations: Iteration<Task, Output>[] = []\n\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.started',\n runId,\n timestamp: now(),\n payload: {\n driver: driverName,\n agentRunNames: specs.map((spec) => spec.name ?? spec.profile.name ?? 'agent'),\n maxIterations,\n maxConcurrency,\n },\n })\n\n const controller = new AbortController()\n const onOuterAbort = () => controller.abort()\n if (options.ctx.signal) {\n if (options.ctx.signal.aborted) controller.abort()\n else options.ctx.signal.addEventListener('abort', onOuterAbort, { once: true })\n }\n\n try {\n while (iterations.length < maxIterations) {\n if (controller.signal.aborted) throwAbort()\n const planned = await options.driver.plan(options.task, iterations)\n if (planned.length === 0) break\n\n const remaining = maxIterations - iterations.length\n const slice = planned.slice(0, remaining)\n const baseIndex = iterations.length\n // Reserve slots up front so concurrent workers may mutate by index.\n for (let i = 0; i < slice.length; i += 1) {\n const spec = specs[(baseIndex + i) % specs.length]!\n iterations.push({\n index: baseIndex + i,\n task: slice[i] as Task,\n agentRunName: spec.name ?? spec.profile.name ?? 'agent',\n events: [],\n startedAt: now(),\n endedAt: 0,\n costUsd: 0,\n })\n }\n\n await runBatch({\n slice,\n baseIndex,\n iterations,\n specs,\n output: options.output,\n validator: options.validator,\n maxConcurrency,\n signal: controller.signal,\n ctx: options.ctx,\n runId,\n now,\n })\n\n if (controller.signal.aborted) throwAbort()\n\n const decision = await options.driver.decide(iterations)\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.decision',\n runId,\n timestamp: now(),\n payload: { decision: serializeDecision(decision), historyLength: iterations.length },\n })\n if (isTerminalDecision(decision)) {\n return finalize({\n options,\n decision,\n iterations,\n startMs: loopStart,\n now,\n runId,\n })\n }\n }\n\n if (iterations.length >= maxIterations) {\n // Cap reached without a terminal decision — ask the driver one more time\n // for its final state, then close out.\n const decision = await options.driver.decide(iterations)\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.decision',\n runId,\n timestamp: now(),\n payload: { decision: serializeDecision(decision), historyLength: iterations.length },\n })\n return finalize({ options, decision, iterations, startMs: loopStart, now, runId })\n }\n // `plan()` returned `[]` before `decide()` reached a terminal state.\n const decision = await options.driver.decide(iterations)\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.decision',\n runId,\n timestamp: now(),\n payload: { decision: serializeDecision(decision), historyLength: iterations.length },\n })\n return finalize({ options, decision, iterations, startMs: loopStart, now, runId })\n } finally {\n if (options.ctx.signal) options.ctx.signal.removeEventListener('abort', onOuterAbort)\n }\n}\n\ninterface RunBatchArgs<Task, Output> {\n slice: Task[]\n baseIndex: number\n iterations: Iteration<Task, Output>[]\n specs: AgentRunSpec<Task>[]\n output: OutputAdapter<Output>\n validator: Validator<Output> | undefined\n maxConcurrency: number\n signal: AbortSignal\n ctx: ExecCtx\n runId: string\n now: () => number\n}\n\nasync function runBatch<Task, Output>(args: RunBatchArgs<Task, Output>) {\n const queue = args.slice.map((task, offset) => ({ task, index: args.baseIndex + offset }))\n const inflight = new Set<Promise<void>>()\n while (queue.length > 0 || inflight.size > 0) {\n while (inflight.size < args.maxConcurrency && queue.length > 0) {\n const item = queue.shift()!\n const p = executeIteration({ ...args, item }).finally(() => inflight.delete(p))\n inflight.add(p)\n }\n if (inflight.size === 0) break\n await Promise.race(inflight)\n }\n}\n\ninterface ExecuteIterationArgs<Task, Output> extends RunBatchArgs<Task, Output> {\n item: { task: Task; index: number }\n}\n\nasync function executeIteration<Task, Output>(args: ExecuteIterationArgs<Task, Output>) {\n const slot = args.iterations[args.item.index]\n if (!slot)\n throw new ValidationError(`runLoop: missing iteration slot at index ${args.item.index}`)\n const spec = args.specs[args.item.index % args.specs.length]\n if (!spec) throw new ValidationError('runLoop: no AgentRunSpec available for iteration')\n slot.startedAt = args.now()\n slot.agentRunName = spec.name ?? spec.profile.name ?? 'agent'\n\n await emitTrace(args.ctx.traceEmitter, {\n kind: 'loop.iteration.started',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n taskHash: hashJson(args.item.task),\n },\n })\n\n try {\n const box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal)\n const placement = describePlacementSafe(args.ctx.sandboxClient, box)\n await emitTrace(args.ctx.traceEmitter, {\n kind: 'loop.iteration.dispatch',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n placement: placement.kind,\n sandboxId: placement.sandboxId,\n fleetId: placement.fleetId,\n machineId: placement.machineId,\n },\n })\n const message = spec.taskToPrompt(args.item.task)\n const events: SandboxEvent[] = []\n for await (const event of box.streamPrompt(message, { signal: args.signal })) {\n events.push(event)\n const llmCall = extractLlmCallEvent(event, slot.agentRunName)\n if (llmCall) {\n slot.costUsd += llmCall.costUsd ?? 0\n args.ctx.runHandle?.observe(llmCall)\n }\n }\n slot.events = events\n slot.output = args.output.parse(events)\n if (args.validator) {\n slot.verdict = await args.validator.validate(slot.output, {\n iteration: args.item.index,\n signal: args.signal,\n traceEmitter: args.ctx.traceEmitter,\n })\n }\n } catch (err) {\n slot.error = err instanceof Error ? err : new Error(String(err))\n } finally {\n slot.endedAt = args.now()\n await emitTrace(args.ctx.traceEmitter, {\n kind: 'loop.iteration.ended',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n outputHash: slot.output !== undefined ? hashJson(slot.output) : undefined,\n verdict: slot.verdict,\n error: slot.error?.message,\n costUsd: slot.costUsd,\n durationMs: slot.endedAt - slot.startedAt,\n },\n })\n }\n}\n\nfunction describePlacementSafe(\n client: LoopSandboxClient,\n box: SandboxInstance,\n): LoopSandboxPlacement {\n if (typeof client.describePlacement === 'function') {\n try {\n const result = client.describePlacement(box)\n if (\n result &&\n typeof result === 'object' &&\n (result.kind === 'sibling' || result.kind === 'fleet')\n ) {\n return {\n kind: result.kind,\n sandboxId: result.sandboxId ?? readSandboxId(box),\n fleetId: result.fleetId,\n machineId: result.machineId,\n }\n }\n } catch {\n // Adapter bug must not corrupt the iteration; fall through to default.\n }\n }\n return { kind: 'sibling', sandboxId: readSandboxId(box) }\n}\n\nfunction readSandboxId(box: SandboxInstance): string | undefined {\n const raw = (box as unknown as { id?: unknown }).id\n return typeof raw === 'string' && raw.length > 0 ? raw : undefined\n}\n\nasync function createSandboxForSpec<Task>(\n client: LoopSandboxClient,\n spec: AgentRunSpec<Task>,\n signal: AbortSignal,\n): Promise<SandboxInstance> {\n const overrides = spec.sandboxOverrides ?? {}\n const overrideBackend = overrides.backend\n const opts: CreateSandboxOptions = {\n ...overrides,\n backend: {\n type: overrideBackend?.type ?? inferBackendType(spec.profile),\n profile: spec.profile satisfies AgentProfile,\n ...(overrideBackend?.model ? { model: overrideBackend.model } : {}),\n ...(overrideBackend?.server ? { server: overrideBackend.server } : {}),\n },\n }\n // Cooperative cancellation: if the abort signal fires while .create is\n // pending, the promise itself is not abortable but the inflight prompt is.\n if (signal.aborted) throwAbort()\n return client.create(opts)\n}\n\nfunction inferBackendType(\n profile: AgentProfile,\n): CreateSandboxOptions['backend'] extends infer B\n ? B extends { type: infer T }\n ? T\n : never\n : never {\n // The sandbox SDK accepts profile-driven backend selection by name. When the\n // profile has no explicit hint we fall through to the SDK's default\n // ('opencode' on the platform side). Returning a literal here would lie\n // about provenance — let the SDK pick.\n type BackendType = NonNullable<CreateSandboxOptions['backend']>['type']\n const explicit = profile.metadata?.backendType\n if (typeof explicit === 'string') return explicit as BackendType\n return 'opencode' as BackendType\n}\n\ninterface FinalizeArgs<Task, Output, Decision> {\n options: RunLoopOptions<Task, Output, Decision>\n decision: Decision\n iterations: Iteration<Task, Output>[]\n startMs: number\n now: () => number\n runId: string\n}\n\nfunction finalize<Task, Output, Decision>(\n args: FinalizeArgs<Task, Output, Decision>,\n): LoopResult<Task, Output, Decision> {\n const winner = (args.options.selectWinner ?? defaultSelectWinner)(args.iterations)\n const costUsd = args.iterations.reduce((sum, iter) => sum + (iter.costUsd || 0), 0)\n const result: LoopResult<Task, Output, Decision> = {\n decision: args.decision,\n iterations: args.iterations,\n winner,\n durationMs: args.now() - args.startMs,\n costUsd,\n }\n void emitTrace(args.options.ctx.traceEmitter, {\n kind: 'loop.ended',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n winnerIterationIndex: winner?.iterationIndex,\n totalCostUsd: costUsd,\n durationMs: result.durationMs,\n iterations: args.iterations.length,\n },\n })\n return result\n}\n\nfunction defaultSelectWinner<Task, Output>(\n iterations: Iteration<Task, Output>[],\n): LoopWinner<Task, Output> | undefined {\n const candidates = iterations.filter((iter) => iter.output !== undefined && !iter.error)\n if (candidates.length === 0) return undefined\n const valid = candidates.filter((iter) => iter.verdict?.valid === true)\n const pool = valid.length > 0 ? valid : candidates\n const sorted = [...pool].sort(\n (a, b) => (b.verdict?.score ?? 0) - (a.verdict?.score ?? 0) || a.index - b.index,\n )\n const top = sorted[0]\n if (!top || top.output === undefined) return undefined\n return {\n task: top.task,\n output: top.output,\n verdict: top.verdict,\n iterationIndex: top.index,\n agentRunName: top.agentRunName,\n }\n}\n\nfunction resolveAgentRuns<Task, Output, Decision>(\n options: RunLoopOptions<Task, Output, Decision>,\n): AgentRunSpec<Task>[] {\n if (options.agentRun && options.agentRuns) {\n throw new ValidationError('runLoop: pass exactly one of `agentRun` or `agentRuns`')\n }\n if (options.agentRun) return [options.agentRun]\n if (options.agentRuns && options.agentRuns.length > 0) return options.agentRuns\n throw new ValidationError('runLoop: `agentRun` or non-empty `agentRuns` is required')\n}\n\nfunction isTerminalDecision(decision: unknown): boolean {\n return (\n decision === 'stop' || decision === 'pick-winner' || decision === 'fail' || decision === 'done'\n )\n}\n\nfunction serializeDecision(decision: unknown): string {\n if (typeof decision === 'string') return decision\n if (decision === null || decision === undefined) return 'null'\n try {\n return JSON.stringify(decision)\n } catch {\n return String(decision)\n }\n}\n\nasync function emitTrace(\n emitter: LoopTraceEmitter | undefined,\n event: LoopTraceEvent,\n): Promise<void> {\n if (!emitter) return\n await emitter.emit(event)\n}\n\nfunction randomSuffix(len = 8): string {\n return Math.random()\n .toString(36)\n .slice(2, 2 + len)\n}\n\nfunction throwAbort(): never {\n const err = new Error('aborted')\n err.name = 'AbortError'\n throw err\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 * Sandbox SDK emits a polymorphic `SandboxEvent = { type, data, id? }`. The\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` — same shape under a dedicated type\n *\n * Numeric coercion is strict: `Number.isFinite` gates every accumulator\n * write so a sentinel `NaN` from a misbehaving backend cannot poison the\n * ledger.\n */\nfunction 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 return undefined\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 tokensOut = pickFiniteNumber(data, ['tokensOut', 'outputTokens', 'completion_tokens'])\n const costUsd = pickFiniteNumber(data, ['costUsd', 'totalCostUsd', 'cost_usd', 'cost'])\n if (tokensIn === undefined && tokensOut === undefined && costUsd === undefined) {\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 (costUsd !== undefined) event.costUsd = costUsd\n return event\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 * Stable hash for the trace payload. Not cryptographic — only used so\n * downstream eval pipelines can group iterations whose task / output is the\n * same. Bare structural hash; non-JSON values stringify via their `toString`.\n */\nfunction hashJson(value: unknown): string {\n let str: string\n try {\n str = JSON.stringify(value) ?? String(value)\n } catch {\n str = String(value)\n }\n // FNV-1a 32-bit — branch-free, dependency-free, good enough for grouping.\n let h = 0x811c9dc5\n for (let i = 0; i < str.length; i += 1) {\n h ^= str.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return (h >>> 0).toString(16).padStart(8, '0')\n}\n"],"mappings":"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","names":["decision"]}
|
|
File without changes
|