@full-self-browsing/lattice 1.3.0-rc.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1010 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
+ import { O as isArtifactRef, a as createNoopAgentHost, f as validateSchemaOutput, k as toArtifactRef, n as runAgentInternal, p as formatToolsForProvider, u as createNoopSurvivabilityAdapter, y as createReceipt } from "./runtime-D25ehzCj.js";
3
+ import canonicalize from "canonicalize";
4
+ //#region src/receipts/cid.ts
5
+ /**
6
+ * Derive the content-addressed CID of a receipt envelope.
7
+ *
8
+ * Returns `sha256:<hex>` where `<hex>` is the 64-char lowercase SHA-256
9
+ * digest of the decoded DSSE payload bytes. No KeySet, signer, or other
10
+ * key material is required — callers chaining receipts (parentReceiptCid)
11
+ * compute this from the parent envelope alone.
12
+ */
13
+ async function receiptCid(envelope) {
14
+ const bytes = Uint8Array.from(atob(envelope.payload), (c) => c.charCodeAt(0));
15
+ const copy = new Uint8Array(bytes.byteLength);
16
+ copy.set(bytes);
17
+ const digest = await crypto.subtle.digest("SHA-256", copy.buffer);
18
+ return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
19
+ }
20
+ //#endregion
21
+ //#region src/agent/infra/cost-tracker.ts
22
+ const WARNING_THRESHOLD = .8;
23
+ function createCostTracker() {
24
+ let promptTokens = 0;
25
+ let completionTokens = 0;
26
+ let costUsd = null;
27
+ return {
28
+ kind: "cost-tracker",
29
+ recordIteration(usage) {
30
+ promptTokens += usage.promptTokens;
31
+ completionTokens += usage.completionTokens;
32
+ if (usage.costUsd !== null) costUsd = (costUsd ?? 0) + usage.costUsd;
33
+ },
34
+ total() {
35
+ return {
36
+ promptTokens,
37
+ completionTokens,
38
+ costUsd
39
+ };
40
+ },
41
+ budgetStatus(budget) {
42
+ const max = budget?.maxCostUsd;
43
+ if (max === void 0 || costUsd === null) return "ok";
44
+ if (costUsd >= max) return "exceeded";
45
+ if (costUsd >= max * WARNING_THRESHOLD) return "warning";
46
+ return "ok";
47
+ }
48
+ };
49
+ }
50
+ //#endregion
51
+ //#region src/receipts/lineage.ts
52
+ const encoder = new TextEncoder();
53
+ const LEAF_DOMAIN = encoder.encode("lattice-lineage-leaf-v1:");
54
+ const NODE_DOMAIN = encoder.encode("lattice-lineage-node-v1:");
55
+ /**
56
+ * Compute a deterministic descriptor-only merkle root for artifact lineage.
57
+ *
58
+ * The root commits to `ArtifactRef` descriptors and nested lineage graphs, not
59
+ * raw artifact values. Returns undefined when no lineage metadata exists.
60
+ */
61
+ async function computeArtifactLineageMerkleRoot(artifacts) {
62
+ const leaves = artifacts.filter((artifact) => artifact.lineage !== void 0).map((artifact) => canonicalLineageLeaf(artifact));
63
+ if (leaves.length === 0) return void 0;
64
+ let level = (await Promise.all(leaves.map((leaf) => sha256(concatBytes(LEAF_DOMAIN, leaf))))).sort(compareBytes);
65
+ while (level.length > 1) {
66
+ const next = [];
67
+ for (let i = 0; i < level.length; i += 2) {
68
+ const left = level[i];
69
+ const right = level[i + 1] ?? left;
70
+ next.push(await sha256(concatBytes(NODE_DOMAIN, left, right)));
71
+ }
72
+ level = next.sort(compareBytes);
73
+ }
74
+ return `sha256:${bytesToHex(level[0])}`;
75
+ }
76
+ function canonicalLineageLeaf(artifact) {
77
+ const json = canonicalize(sanitizeArtifactRef(artifact));
78
+ if (json === void 0) throw new Error("computeArtifactLineageMerkleRoot: lineage descriptor is not canonicalizable.");
79
+ return encoder.encode(json);
80
+ }
81
+ function sanitizeArtifactRef(input) {
82
+ const ref = toArtifactRef(input);
83
+ return compactObject({
84
+ id: ref.id,
85
+ kind: ref.kind,
86
+ source: ref.source,
87
+ privacy: ref.privacy,
88
+ mediaType: ref.mediaType,
89
+ label: ref.label,
90
+ metadata: sanitizeUnknown(ref.metadata),
91
+ size: sanitizeUnknown(ref.size),
92
+ fingerprint: sanitizeUnknown(ref.fingerprint),
93
+ storage: sanitizeUnknown(ref.storage),
94
+ lineage: ref.lineage !== void 0 ? sanitizeLineage(ref.lineage) : void 0
95
+ });
96
+ }
97
+ function sanitizeLineage(lineage) {
98
+ return compactObject({
99
+ parents: lineage.parents.map((parent) => sanitizeArtifactRef(parent)).sort(compareCanonicalJson),
100
+ transform: compactObject({
101
+ kind: lineage.transform.kind,
102
+ name: lineage.transform.name,
103
+ metadata: sanitizeUnknown(lineage.transform.metadata)
104
+ })
105
+ });
106
+ }
107
+ function sanitizeUnknown(value) {
108
+ if (value === void 0) return void 0;
109
+ if (value === null) return null;
110
+ switch (typeof value) {
111
+ case "string":
112
+ case "boolean": return value;
113
+ case "number": return Number.isFinite(value) ? value : void 0;
114
+ case "bigint": return value.toString();
115
+ case "object": {
116
+ if (Array.isArray(value)) return value.map((item) => sanitizeUnknown(item)).filter((item) => item !== void 0);
117
+ const out = {};
118
+ for (const key of Object.keys(value).sort()) {
119
+ const child = sanitizeUnknown(value[key]);
120
+ if (child !== void 0) out[key] = child;
121
+ }
122
+ return out;
123
+ }
124
+ default: return;
125
+ }
126
+ }
127
+ function compactObject(input) {
128
+ const out = {};
129
+ for (const key of Object.keys(input).sort()) {
130
+ const value = input[key];
131
+ if (value !== void 0) out[key] = value;
132
+ }
133
+ return out;
134
+ }
135
+ function compareCanonicalJson(a, b) {
136
+ const aJson = canonicalize(a) ?? "";
137
+ const bJson = canonicalize(b) ?? "";
138
+ return aJson.localeCompare(bJson);
139
+ }
140
+ async function sha256(bytes) {
141
+ const digest = await crypto.subtle.digest("SHA-256", toArrayBuffer(bytes));
142
+ return new Uint8Array(digest);
143
+ }
144
+ function concatBytes(...chunks) {
145
+ const total = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
146
+ const out = new Uint8Array(total);
147
+ let offset = 0;
148
+ for (const chunk of chunks) {
149
+ out.set(chunk, offset);
150
+ offset += chunk.byteLength;
151
+ }
152
+ return out;
153
+ }
154
+ function compareBytes(a, b) {
155
+ return bytesToHex(a).localeCompare(bytesToHex(b));
156
+ }
157
+ function bytesToHex(bytes) {
158
+ return Array.from(bytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
159
+ }
160
+ function toArrayBuffer(bytes) {
161
+ const copy = new Uint8Array(bytes.byteLength);
162
+ copy.set(bytes);
163
+ return copy.buffer;
164
+ }
165
+ //#endregion
166
+ //#region src/agent/infra/action-history.ts
167
+ /**
168
+ * ActionHistory — Phase 21 (v1.2).
169
+ *
170
+ * Detects stuck patterns in the agent loop's tool-call sequence:
171
+ * - "consecutive-identical-tool-call" — same (toolName, argsHash) N+ times in a row
172
+ * - "ping-pong" — last 4 records alternate between 2 distinct (toolName, argsHash) pairs
173
+ * - "no-progress" — reserved for callers wiring goal-progress feedback here
174
+ *
175
+ * Standalone (no dependency on the agent runtime); callers register the
176
+ * primitive externally and pump `recordAction` from their loop or hook.
177
+ */
178
+ const STUCK_REASONS = [
179
+ "consecutive-identical-tool-call",
180
+ "no-progress",
181
+ "ping-pong"
182
+ ];
183
+ function actionKey(record) {
184
+ return `${record.toolName}::${record.argsHash}`;
185
+ }
186
+ function createActionHistory(options = {}) {
187
+ const consecutiveLimit = options.consecutiveLimit ?? 3;
188
+ const records = [];
189
+ return {
190
+ kind: "action-history",
191
+ recordAction(action) {
192
+ records.push(action);
193
+ if (records.length >= consecutiveLimit) {
194
+ const tail = records.slice(-consecutiveLimit);
195
+ const firstKey = actionKey(tail[0]);
196
+ if (tail.every((r) => actionKey(r) === firstKey)) return "consecutive-identical-tool-call";
197
+ }
198
+ if (records.length >= 4) {
199
+ const keys = records.slice(-4).map(actionKey);
200
+ if (Array.from(new Set(keys)).length === 2 && keys[0] === keys[2] && keys[1] === keys[3] && keys[0] !== keys[1]) return "ping-pong";
201
+ }
202
+ return null;
203
+ },
204
+ history() {
205
+ return Object.freeze([...records]);
206
+ }
207
+ };
208
+ }
209
+ //#endregion
210
+ //#region src/agent/crew/dispatcher.ts
211
+ /**
212
+ * Create the crew dispatch chokepoint for one agent spec.
213
+ *
214
+ * `spec` is the agent whose loop this dispatcher serves (its `childAgents`
215
+ * are the dispatchable targets); `ctx` carries every crew-level concern.
216
+ */
217
+ function createCrewDispatcher(spec, ctx) {
218
+ return createDispatcherNode(spec, ctx, {
219
+ exhausted: false,
220
+ runId: `lattice-crew-${crypto.randomUUID()}`
221
+ });
222
+ }
223
+ function createDispatcherNode(spec, ctx, shared) {
224
+ const children = spec.childAgents ?? [];
225
+ const terminalBlock = /* @__PURE__ */ new Map();
226
+ const childHost = ctx.sharedPrefix.length > 0 ? {
227
+ ...ctx.childHost,
228
+ transport: withCachePrefixHoist(ctx.sharedPrefix, ctx.childHost.transport)
229
+ } : ctx.childHost;
230
+ async function dispatchToolUse(req, _loopCtx) {
231
+ const childSpec = children.find((child) => child.id === req.name);
232
+ if (childSpec === void 0) return;
233
+ const blocked = terminalBlock.get(childSpec.id);
234
+ if (blocked !== void 0) return { content: blocked };
235
+ if (req.name === spec.id || ctx.ancestry.includes(req.name)) return errorResult({
236
+ kind: "crew-cycle-rejected",
237
+ reason: `Dispatch of "${req.name}" rejected: the id already appears in the crew ancestry chain (D-05 cycle prevention).`,
238
+ terminal: false
239
+ });
240
+ if (ctx.ancestry.length >= ctx.policy.maxDepth) return errorResult({
241
+ kind: "crew-depth-exceeded",
242
+ reason: `Dispatch of "${req.name}" rejected: crew maxDepth ${ctx.policy.maxDepth} reached (ancestry depth ${ctx.ancestry.length}).`,
243
+ terminal: false
244
+ });
245
+ const pool = ctx.remainingBudget();
246
+ if (isPoolExhausted(pool)) {
247
+ shared.exhausted = true;
248
+ return errorResult({
249
+ kind: "crew-budget-exceeded",
250
+ reason: "Crew budget pool exhausted — the crew run must end (D-10).",
251
+ terminal: true
252
+ });
253
+ }
254
+ const task = extractTaskArg(req.args);
255
+ if (task === null) return errorResult({
256
+ kind: "invalid-dispatch-args",
257
+ reason: `Dispatch args for child agent "${childSpec.id}" must be { "task": string }.`,
258
+ terminal: false
259
+ });
260
+ const effectiveBudget = deriveChildBudget(childSpec.contract?.budget, pool, ctx.policy.maxIterationsPerAgent);
261
+ const childAncestry = [...ctx.ancestry, spec.id];
262
+ const childNode = childSpec.childAgents !== void 0 && childSpec.childAgents.length > 0 ? createDispatcherNode(childSpec, {
263
+ ...ctx,
264
+ ancestry: childAncestry
265
+ }, shared) : void 0;
266
+ const childResult = await runAgentInternal({
267
+ task,
268
+ tools: childNode !== void 0 ? [...childSpec.tools, ...childNode.childToolDeclarations] : childSpec.tools,
269
+ host: childHost,
270
+ survivabilityAdapter: withAncestrySnapshot(createNoopSurvivabilityAdapter(), [...childAncestry, childSpec.id]),
271
+ ...effectiveBudget !== void 0 ? { contract: {
272
+ kind: "capability-contract",
273
+ budget: effectiveBudget
274
+ } } : {},
275
+ ...ctx.signer !== void 0 ? { signer: ctx.signer } : {},
276
+ ...ctx.tracer !== void 0 ? { tracer: ctx.tracer } : {},
277
+ ...ctx.pipeline !== void 0 ? { pipeline: ctx.pipeline } : {}
278
+ }, ctx.config, childNode !== void 0 ? { dispatchToolUse: childNode.dispatchToolUse } : {});
279
+ ctx.recordUsage(childSpec.id, childResult.usage);
280
+ ctx.recordAgentResult?.(childSpec.id, childResult);
281
+ if (childResult.kind !== "success") {
282
+ const classified = classifyChildFailure(childSpec.id, childResult);
283
+ const result = errorResult(classified);
284
+ if (classified.terminal) {
285
+ terminalBlock.set(childSpec.id, result.content);
286
+ if (classified.kind === "crew-budget-exceeded") shared.exhausted = true;
287
+ }
288
+ return result;
289
+ }
290
+ const receipts = [];
291
+ const childArtifacts = extractArtifacts(childResult);
292
+ if (ctx.signer !== void 0) try {
293
+ const lineageMerkleRoot = await computeArtifactLineageMerkleRoot(childArtifacts);
294
+ const envelope = await createReceipt({
295
+ runId: shared.runId,
296
+ model: {
297
+ requested: "lattice-crew/agent-completion",
298
+ observed: null
299
+ },
300
+ route: {
301
+ providerId: "lattice-crew",
302
+ capabilityId: "lattice-crew/agent-completion",
303
+ attemptNumber: 1
304
+ },
305
+ ...ctx.crewRootCid !== void 0 ? { parentReceiptCid: ctx.crewRootCid } : {},
306
+ usage: childResult.usage,
307
+ ...lineageMerkleRoot !== void 0 ? { lineageMerkleRoot } : {},
308
+ contractVerdict: "success",
309
+ contractHash: null,
310
+ inputHashes: [],
311
+ outputHash: null,
312
+ stepName: `crew-agent-completion:${childSpec.id}`
313
+ }, ctx.signer);
314
+ ctx.mintedReceipts(envelope);
315
+ receipts.push(await receiptCid(envelope));
316
+ } catch {}
317
+ const envelope = {
318
+ summary: extractSummary(childResult.output),
319
+ artifacts: childArtifacts,
320
+ receipts
321
+ };
322
+ const validation = await validateSchemaOutput(childSpec.id, childSpec.summaryReturnSchema, envelope);
323
+ if (!validation.ok) return errorResult({
324
+ kind: "summary-validation-failed",
325
+ reason: validation.issue.issues.map((issue) => issue.message).join("; "),
326
+ terminal: false
327
+ });
328
+ return { content: JSON.stringify(envelope) };
329
+ }
330
+ return {
331
+ dispatchToolUse,
332
+ childToolDeclarations: synthesizeChildDeclarations(children),
333
+ crewBudgetExhausted: () => shared.exhausted
334
+ };
335
+ }
336
+ /**
337
+ * Per-dimension `min(spec.contract?.budget, remaining crew pool)` with the
338
+ * iteration dimension additionally capped by `maxIterationsPerAgent`.
339
+ *
340
+ * Cost-dimension min applies ONLY when both sides are numbers — a pool
341
+ * derived from null-cost (unmeasured) usage omits `maxCostUsd`, and even a
342
+ * literal `null` never poisons the arithmetic (Pitfall 4).
343
+ */
344
+ function deriveChildBudget(specBudget, pool, maxIterationsPerAgent) {
345
+ const maxIterations = minDefined$1(minDefined$1(specBudget?.maxIterations, pool?.maxIterations), maxIterationsPerAgent);
346
+ const maxWallTimeMs = minDefined$1(specBudget?.maxWallTimeMs, pool?.maxWallTimeMs);
347
+ const maxCostUsd = minDefined$1(specBudget?.maxCostUsd, pool?.maxCostUsd);
348
+ if (maxIterations === void 0 && maxWallTimeMs === void 0 && maxCostUsd === void 0) return;
349
+ return {
350
+ ...maxIterations !== void 0 ? { maxIterations } : {},
351
+ ...maxWallTimeMs !== void 0 ? { maxWallTimeMs } : {},
352
+ ...maxCostUsd !== void 0 ? { maxCostUsd } : {}
353
+ };
354
+ }
355
+ /** min() that only applies when BOTH sides are real numbers (Pitfall 4). */
356
+ function minDefined$1(a, b) {
357
+ const aNum = typeof a === "number" && Number.isFinite(a) ? a : void 0;
358
+ const bNum = typeof b === "number" && Number.isFinite(b) ? b : void 0;
359
+ if (aNum !== void 0 && bNum !== void 0) return Math.min(aNum, bNum);
360
+ return aNum ?? bNum;
361
+ }
362
+ /**
363
+ * Crew-ceiling predicate (D-10): the pool is exhausted when ANY bounded
364
+ * dimension is at/below zero. Null/absent dimensions (unmeasured cost)
365
+ * never count as exhausted (Pitfall 4).
366
+ */
367
+ function isPoolExhausted(pool) {
368
+ if (pool === void 0) return false;
369
+ return typeof pool.maxIterations === "number" && pool.maxIterations <= 0 || typeof pool.maxWallTimeMs === "number" && pool.maxWallTimeMs <= 0 || typeof pool.maxCostUsd === "number" && pool.maxCostUsd <= 0;
370
+ }
371
+ /**
372
+ * Compose the byte-stable crew cache prefix for one tool surface: the
373
+ * `describeForSystem()` block (tool descriptions + envelope instructions),
374
+ * derived from deterministic, version-pinned inputs ONLY — no timestamps,
375
+ * random ids, or unsorted keys (Phase 35 scaffold discipline; any
376
+ * non-byte-stable fragment silently zeroes the cache-hit rate).
377
+ *
378
+ * The 39-06 orchestrator composes this ONCE per crew at crew start and
379
+ * threads it as `CrewDispatchContext.sharedPrefix`. All members sharing a
380
+ * tool surface share byte-identical prefix bytes across dispatches.
381
+ */
382
+ function composeCrewCachePrefix(tools) {
383
+ return formatToolsForProvider("lattice-crew", tools).describeForSystem();
384
+ }
385
+ /**
386
+ * Transport wrapper implementing the quirks-gated prefix hoist:
387
+ *
388
+ * - Adapter discloses `quirks.promptCachingSupported === true` (Anthropic
389
+ * block-granular caching) AND the outgoing task starts with the shared
390
+ * prefix → the prefix is hoisted to `cacheSystemPrefix` and `task`
391
+ * carries ONLY the conversation body. The 39-03 byte-equality invariant
392
+ * (`describeForSystem() + "\n" + buildTaskBody(conv) === buildTask(conv)`)
393
+ * guarantees the stripped remainder IS the body-only rendering — the
394
+ * prefix is never duplicated.
395
+ * - Any other adapter → the request passes through UNTOUCHED: no
396
+ * `cacheSystemPrefix` own-property is ever created (Pitfall 6) and the
397
+ * prefix stays at the head of `task` (OpenAI automatic token-prefix path).
398
+ *
399
+ * Composes over an existing `AgentTransport` (FSB offscreen bridge etc.);
400
+ * when `inner` is absent it dispatches `provider.execute()` directly,
401
+ * matching the runtime's default transport behavior.
402
+ */
403
+ function withCachePrefixHoist(sharedPrefix, inner) {
404
+ const marker = `${sharedPrefix}\n`;
405
+ return { async call(provider, request) {
406
+ const outbound = sharedPrefix.length > 0 && supportsPromptCaching(provider) && request.task.startsWith(marker) ? {
407
+ ...request,
408
+ task: request.task.slice(marker.length),
409
+ cacheSystemPrefix: sharedPrefix
410
+ } : request;
411
+ if (inner !== void 0) return inner.call(provider, outbound);
412
+ if (provider.execute === void 0) throw new Error(`CrewDispatcher: provider "${provider.id}" has no execute() method.`);
413
+ return provider.execute(outbound);
414
+ } };
415
+ }
416
+ /** Quirks gate: only adapters that disclose block-granular prompt caching. */
417
+ function supportsPromptCaching(provider) {
418
+ return provider.quirks?.promptCachingSupported === true;
419
+ }
420
+ /**
421
+ * Map a child `AgentFailure` to the structured tool-result error body.
422
+ *
423
+ * Terminal (D-10): tripwire violations and contract no-match (the
424
+ * `isTerminal()` kinds in results/errors.ts — the agent loop reuses
425
+ * `no-contract-match` for child cost-budget exhaustion), crew-ceiling
426
+ * breaches, and non-stuck SAFETY-band denials (AgentDeniedError aligns
427
+ * with TripwireViolationError terminal semantics). Recoverable (D-09):
428
+ * iteration/wall-time exhaustion and STUCK_REASONS stalls — the parent
429
+ * MAY re-dispatch.
430
+ */
431
+ function classifyChildFailure(childId, failure) {
432
+ return {
433
+ kind: failure.kind,
434
+ reason: failure.reason ?? `Child agent "${childId}" failed with kind "${failure.kind}".`,
435
+ terminal: isTerminalChildFailure(failure)
436
+ };
437
+ }
438
+ function isTerminalChildFailure(failure) {
439
+ if (failure.kind === "tripwire-violated" || failure.kind === "no-contract-match" || failure.kind === "crew-budget-exceeded") return true;
440
+ if (failure.kind === "agent-iteration-denied") {
441
+ const reason = failure.reason ?? "";
442
+ return !STUCK_REASONS.some((stuck) => reason.includes(stuck));
443
+ }
444
+ return false;
445
+ }
446
+ function errorResult(body) {
447
+ return { content: JSON.stringify({ error: {
448
+ kind: body.kind,
449
+ reason: body.reason,
450
+ terminal: body.terminal
451
+ } }) };
452
+ }
453
+ function extractTaskArg(args) {
454
+ if (typeof args !== "object" || args === null) return null;
455
+ const task = args["task"];
456
+ return typeof task === "string" ? task : null;
457
+ }
458
+ function extractSummary(output) {
459
+ if (typeof output === "object" && output !== null) {
460
+ const answer = output["answer"];
461
+ if (typeof answer === "string") return answer;
462
+ }
463
+ if (typeof output === "string") return output;
464
+ try {
465
+ return JSON.stringify(output);
466
+ } catch {
467
+ return String(output);
468
+ }
469
+ }
470
+ function extractArtifacts(result) {
471
+ const artifacts = result.artifacts;
472
+ return Array.isArray(artifacts) ? artifacts.filter(isArtifactRef).map(toArtifactRef) : [];
473
+ }
474
+ /**
475
+ * Wrap a survivability adapter so serialized child snapshots carry the
476
+ * root-first ancestry chain (D-05; AgentSnapshot.ancestry from 39-03).
477
+ * The `agent-snapshot/v1` version literal is unchanged — the field is
478
+ * additive-optional (Pitfall 8).
479
+ */
480
+ function withAncestrySnapshot(base, ancestry) {
481
+ return {
482
+ ...base,
483
+ serialize: (state) => base.serialize({
484
+ ...state,
485
+ ancestry
486
+ })
487
+ };
488
+ }
489
+ function synthesizeChildDeclarations(children) {
490
+ return children.map((child) => ({
491
+ kind: "tool",
492
+ name: child.id,
493
+ description: `Delegate a task to the "${child.id}" child agent. Agent intent: ${child.intent} Returns a JSON summary envelope { "summary": string, "artifacts": array, "receipts": array } validated against the agent's summaryReturnSchema.`,
494
+ inputSchema: makeDispatchArgsSchema(child.id),
495
+ execute: () => {
496
+ throw new Error(`Child agent "${child.id}" must be dispatched through the CrewDispatcher (kind:"agent" branch) — direct tool execution is forbidden (D-01/D-02).`);
497
+ }
498
+ }));
499
+ }
500
+ /**
501
+ * Deterministic `~standard` schema for `{ task: string }` dispatch args.
502
+ * Carries a fixed `toJSONSchema()` so `formatToolsForProvider` renders a
503
+ * meaningful args_schema (byte-stable — no timestamps/random ids; the
504
+ * declarations feed the shared cache prefix).
505
+ */
506
+ function makeDispatchArgsSchema(childId) {
507
+ return {
508
+ "~standard": {
509
+ version: 1,
510
+ vendor: "lattice-crew",
511
+ validate: (value) => {
512
+ if (typeof value === "object" && value !== null && typeof value["task"] === "string") return { value };
513
+ return { issues: [{ message: `Dispatch args for child agent "${childId}" must be { "task": string }.` }] };
514
+ }
515
+ },
516
+ toJSONSchema: () => ({
517
+ type: "object",
518
+ properties: { task: {
519
+ type: "string",
520
+ description: "The task to delegate to this child agent."
521
+ } },
522
+ required: ["task"],
523
+ additionalProperties: false
524
+ })
525
+ };
526
+ }
527
+ //#endregion
528
+ //#region src/agent/crew/crew-policy.ts
529
+ /**
530
+ * Validates and normalizes a `CrewPolicy`.
531
+ *
532
+ * - Applies defaults: `maxDepth: 1`, `maxConcurrentChildren: 1`,
533
+ * `coordination: "managed"`.
534
+ * - Throws `TypeError` when `maxConcurrentChildren > 1` (serial-only v1.3
535
+ * limit, D-11) or when any structural cap is a non-integer or < 1.
536
+ * - Returns a frozen normalized policy; the input is never mutated.
537
+ */
538
+ function validateCrewPolicy(policy = {}) {
539
+ assertStructuralCap("maxConcurrentChildren", policy.maxConcurrentChildren);
540
+ if (policy.maxConcurrentChildren !== void 0 && policy.maxConcurrentChildren > 1) throw new TypeError("CrewPolicy.maxConcurrentChildren > 1 is not supported in v1.3 — children execute serially (D-11).");
541
+ assertStructuralCap("maxDepth", policy.maxDepth);
542
+ assertStructuralCap("maxTotalIterations", policy.maxTotalIterations);
543
+ assertStructuralCap("maxIterationsPerAgent", policy.maxIterationsPerAgent);
544
+ return Object.freeze({
545
+ ...policy.budget !== void 0 ? { budget: Object.freeze({ ...policy.budget }) } : {},
546
+ ...policy.maxTotalIterations !== void 0 ? { maxTotalIterations: policy.maxTotalIterations } : {},
547
+ ...policy.maxIterationsPerAgent !== void 0 ? { maxIterationsPerAgent: policy.maxIterationsPerAgent } : {},
548
+ maxConcurrentChildren: policy.maxConcurrentChildren ?? 1,
549
+ maxDepth: policy.maxDepth ?? 1,
550
+ ...policy.limits !== void 0 ? { limits: Object.freeze(Object.fromEntries(Object.entries(policy.limits).map(([adapterId, override]) => [adapterId, Object.freeze({ ...override })]))) } : {},
551
+ coordination: policy.coordination ?? "managed"
552
+ });
553
+ }
554
+ function assertStructuralCap(field, value) {
555
+ if (value === void 0) return;
556
+ if (!Number.isInteger(value) || value < 1) throw new TypeError(`CrewPolicy.${field} must be a positive integer (>= 1); received ${String(value)}.`);
557
+ }
558
+ //#endregion
559
+ //#region src/agent/infra/rate-limit-group.ts
560
+ /** Anthropic Tier 1 requests/minute (fetched 2026-06-10). */
561
+ const DEFAULT_REQUESTS_PER_MINUTE = 50;
562
+ /** Anthropic Tier 1 input tokens/minute, Sonnet-class (fetched 2026-06-10). */
563
+ const DEFAULT_TOKENS_PER_MINUTE = 3e4;
564
+ const MS_PER_MINUTE = 6e4;
565
+ /**
566
+ * Absorbs floating-point drift in two places: bucket-level comparisons
567
+ * (`available >= need`) and deficit-wait rounding. 1e-6 of a token/request
568
+ * (or millisecond) is far above accumulated IEEE-754 error at these
569
+ * magnitudes and far below anything rate-limit-relevant.
570
+ */
571
+ const FLOAT_EPSILON = 1e-6;
572
+ function createBucket(perMinute, label) {
573
+ if (!Number.isFinite(perMinute) || perMinute <= 0) throw new TypeError(`createRateLimitGroup: ${label} must be a positive finite number, got ${perMinute}.`);
574
+ return {
575
+ available: perMinute,
576
+ capacity: perMinute,
577
+ perMsRate: perMinute / MS_PER_MINUTE
578
+ };
579
+ }
580
+ function createRateLimitGroup(options = {}) {
581
+ const now = options.now ?? Date.now;
582
+ const requests = createBucket(options.requestsPerMinute ?? DEFAULT_REQUESTS_PER_MINUTE, "requestsPerMinute");
583
+ const tokens = createBucket(options.tokensPerMinute ?? DEFAULT_TOKENS_PER_MINUTE, "tokensPerMinute");
584
+ let lastRefillAt = now();
585
+ const waiters = [];
586
+ let timer = null;
587
+ /** Lazy continuous refill from the clock delta — never a recurring timer. */
588
+ function refill() {
589
+ const t = now();
590
+ const elapsed = t - lastRefillAt;
591
+ if (elapsed <= 0) return;
592
+ lastRefillAt = t;
593
+ requests.available = Math.min(requests.capacity, requests.available + elapsed * requests.perMsRate);
594
+ tokens.available = Math.min(tokens.capacity, tokens.available + elapsed * tokens.perMsRate);
595
+ }
596
+ /**
597
+ * Token requirement for availability checks, clamped to capacity so an
598
+ * oversized estimate (> bucket capacity) proceeds at full bucket instead
599
+ * of deadlocking; the full amount is still debited (the bucket goes into
600
+ * debt and recovers via drain).
601
+ */
602
+ function tokenNeed(inputTokens) {
603
+ return Math.min(inputTokens, tokens.capacity);
604
+ }
605
+ function tryDebit(inputTokens) {
606
+ if (requests.available + FLOAT_EPSILON >= 1 && tokens.available + FLOAT_EPSILON >= tokenNeed(inputTokens)) {
607
+ requests.available -= 1;
608
+ tokens.available -= inputTokens;
609
+ return true;
610
+ }
611
+ return false;
612
+ }
613
+ /** Exact wait (ms) until both dimensions can cover the head waiter. */
614
+ function deficitWaitMs(inputTokens) {
615
+ const requestDeficit = Math.max(0, 1 - requests.available);
616
+ const tokenDeficit = Math.max(0, tokenNeed(inputTokens) - tokens.available);
617
+ const requestWait = requestDeficit / requests.perMsRate;
618
+ const tokenWait = tokenDeficit / tokens.perMsRate;
619
+ return Math.max(requestWait, tokenWait);
620
+ }
621
+ function scheduleNext() {
622
+ if (timer !== null) return;
623
+ const head = waiters[0];
624
+ if (head === void 0) return;
625
+ const waitMs = Math.max(1, Math.ceil(deficitWaitMs(head.inputTokens) - FLOAT_EPSILON));
626
+ timer = setTimeout(() => {
627
+ timer = null;
628
+ pump();
629
+ }, waitMs);
630
+ }
631
+ /** Refill, resolve as many FIFO waiters as capacity allows, reschedule. */
632
+ function pump() {
633
+ if (timer !== null) {
634
+ clearTimeout(timer);
635
+ timer = null;
636
+ }
637
+ refill();
638
+ while (waiters.length > 0) {
639
+ const head = waiters[0];
640
+ if (head === void 0 || !tryDebit(head.inputTokens)) break;
641
+ waiters.shift();
642
+ head.resolve(createLease(head.inputTokens));
643
+ }
644
+ scheduleNext();
645
+ }
646
+ function createLease(estimateTokens) {
647
+ let released = false;
648
+ return { release(actual) {
649
+ if (released) return;
650
+ released = true;
651
+ refill();
652
+ const actualTokens = typeof actual.promptTokens === "number" && Number.isFinite(actual.promptTokens) ? actual.promptTokens : estimateTokens;
653
+ tokens.available = Math.min(tokens.capacity, tokens.available + (estimateTokens - actualTokens));
654
+ pump();
655
+ } };
656
+ }
657
+ return {
658
+ kind: "rate-limit-group",
659
+ async acquire(estimate) {
660
+ refill();
661
+ if (waiters.length === 0 && tryDebit(estimate.inputTokens)) return createLease(estimate.inputTokens);
662
+ return new Promise((resolve) => {
663
+ waiters.push({
664
+ inputTokens: estimate.inputTokens,
665
+ resolve
666
+ });
667
+ scheduleNext();
668
+ });
669
+ }
670
+ };
671
+ }
672
+ /**
673
+ * chars/4 heuristic for lease reservation (matches the transcript-store
674
+ * default `TokenEstimator`). Persistent estimation error is benign: `release`
675
+ * reconciles every lease against the actual `Usage.promptTokens` (A2).
676
+ */
677
+ function estimateInputTokens(task) {
678
+ return Math.ceil(task.length / 4);
679
+ }
680
+ /**
681
+ * Wrap an `AgentTransport` so every provider call is gated through `group`.
682
+ *
683
+ * Every transport wrapped with the SAME group instance shares one bucket —
684
+ * `runAgentCrew` (39-06) wraps parent + child hosts with one shared group per
685
+ * adapter instance, structurally guaranteeing crew-wide coordination (D-13).
686
+ * `ProviderAdapter` is never modified (INV-03 parity invariant intact).
687
+ *
688
+ * - `inner` provided → dispatch nests through `inner.call(provider, request)`,
689
+ * composing with consumer transports (e.g. cross-process bridges).
690
+ * - `inner` undefined → falls through to `provider.execute(request)`, guarded
691
+ * the same way as `createNoopAgentHost` (error names the provider id only).
692
+ *
693
+ * Release policy:
694
+ * - Success → release with `normalizedUsage.promptTokens`; when usage is
695
+ * missing or non-finite, fall back to the estimate (no NaN arithmetic —
696
+ * the `costUsd: null` "unmeasured" discipline analog).
697
+ * - Throw → release with the ORIGINAL estimate (burn — no refund; the
698
+ * provider may have consumed quota despite the error) and rethrow the
699
+ * same error unchanged. Request objects and headers are never serialized
700
+ * into error paths.
701
+ */
702
+ function withRateLimit(group, inner) {
703
+ return { async call(provider, request) {
704
+ const estimate = estimateInputTokens(request.task);
705
+ const lease = await group.acquire({ inputTokens: estimate });
706
+ try {
707
+ let response;
708
+ if (inner !== void 0) response = await inner.call(provider, request);
709
+ else {
710
+ if (provider.execute === void 0) throw new Error(`AgentTransport: provider ${provider.id} has no execute() method.`);
711
+ response = await provider.execute(request);
712
+ }
713
+ const actual = response.normalizedUsage?.promptTokens;
714
+ lease.release({ promptTokens: typeof actual === "number" && Number.isFinite(actual) ? actual : estimate });
715
+ return response;
716
+ } catch (error) {
717
+ lease.release({ promptTokens: estimate });
718
+ throw error;
719
+ }
720
+ } };
721
+ }
722
+ //#endregion
723
+ //#region src/agent/crew/run-crew.ts
724
+ var run_crew_exports = /* @__PURE__ */ __exportAll({ runAgentCrew: () => runAgentCrew });
725
+ const ZERO_USAGE = {
726
+ promptTokens: 0,
727
+ completionTokens: 0,
728
+ costUsd: null
729
+ };
730
+ /**
731
+ * Execute a crew rooted at `options.root`.
732
+ */
733
+ async function runAgentCrew(options, config = {}) {
734
+ const policy = validateCrewPolicy(options.policy);
735
+ const runId = `runAgentCrew-${Date.now()}-${Math.random().toString(16).slice(2)}`;
736
+ const startedAt = Date.now();
737
+ const accounting = /* @__PURE__ */ new Map();
738
+ const receipts = [];
739
+ const receiptCidsByAgent = /* @__PURE__ */ new Map();
740
+ const crewRoot = await maybeMintCrewRoot({
741
+ runId,
742
+ root: options.root,
743
+ ...options.signer !== void 0 ? { signer: options.signer } : {}
744
+ });
745
+ if (crewRoot !== void 0) receipts.push(crewRoot.envelope);
746
+ const groupForProvider = createRateLimitGroupResolver(policy);
747
+ const childHost = wrapHostWithRateLimits(options.hosts.childHost, groupForProvider);
748
+ function recordUsage(agentId, usage) {
749
+ entryFor(accounting, agentId).tracker.recordIteration(usage);
750
+ }
751
+ function recordAgentResult(agentId, result) {
752
+ const entry = entryFor(accounting, agentId);
753
+ entry.iterations += result.iterations.length;
754
+ }
755
+ function remainingBudget() {
756
+ return deriveRemainingBudget({
757
+ policy,
758
+ usage: totalUsage(accounting),
759
+ iterations: totalIterations(accounting),
760
+ startedAt
761
+ });
762
+ }
763
+ const dispatcher = createCrewDispatcher(options.root, {
764
+ policy,
765
+ childHost,
766
+ ancestry: [],
767
+ recordUsage,
768
+ recordAgentResult,
769
+ remainingBudget,
770
+ sharedPrefix: composeSharedPrefix(options.root),
771
+ mintedReceipts(envelope) {
772
+ receipts.push(envelope);
773
+ },
774
+ config,
775
+ ...crewRoot !== void 0 ? { crewRootCid: crewRoot.cid } : {},
776
+ ...options.signer !== void 0 ? { signer: options.signer } : {},
777
+ ...options.tracer !== void 0 ? { tracer: options.tracer } : {},
778
+ ...options.pipeline !== void 0 ? { pipeline: options.pipeline } : {}
779
+ });
780
+ const parentResult = await runAgentInternal({
781
+ task: options.root.intent,
782
+ tools: [...options.root.tools, ...dispatcher.childToolDeclarations],
783
+ host: wrapHostWithRateLimits(createNoopAgentHost(), groupForProvider),
784
+ ...options.root.contract !== void 0 ? { contract: options.root.contract } : {},
785
+ ...options.signer !== void 0 ? { signer: options.signer } : {},
786
+ ...options.tracer !== void 0 ? { tracer: options.tracer } : {},
787
+ ...options.pipeline !== void 0 ? { pipeline: options.pipeline } : {}
788
+ }, config, { dispatchToolUse: dispatcher.dispatchToolUse });
789
+ recordUsage(options.root.id, parentResult.usage);
790
+ recordAgentResult(options.root.id, parentResult);
791
+ if (options.signer !== void 0 && crewRoot !== void 0) {
792
+ const parentEnvelope = await createAgentCompletionReceipt({
793
+ runId,
794
+ agentId: options.root.id,
795
+ usage: parentResult.usage,
796
+ signer: options.signer,
797
+ parentReceiptCid: crewRoot.cid,
798
+ success: parentResult.kind === "success",
799
+ artifacts: parentResult.kind === "success" ? parentResult.artifacts ?? [] : []
800
+ });
801
+ receipts.push(parentEnvelope);
802
+ }
803
+ await populateReceiptCidIndex(receipts, receiptCidsByAgent);
804
+ return freezeCrewResult({
805
+ result: dispatcher.crewBudgetExhausted() || crewBudgetViolated({
806
+ policy,
807
+ usage: totalUsage(accounting),
808
+ iterations: totalIterations(accounting),
809
+ startedAt
810
+ }) ? buildCrewBudgetFailure(parentResult) : parentResult,
811
+ perAgent: buildPerAgent(accounting, receiptCidsByAgent),
812
+ usage: totalUsage(accounting),
813
+ totalIterations: totalIterations(accounting),
814
+ receipts,
815
+ ...crewRoot !== void 0 ? { crewRootCid: crewRoot.cid } : {}
816
+ });
817
+ }
818
+ function entryFor(accounting, agentId) {
819
+ let entry = accounting.get(agentId);
820
+ if (entry === void 0) {
821
+ entry = {
822
+ tracker: createCostTracker(),
823
+ iterations: 0
824
+ };
825
+ accounting.set(agentId, entry);
826
+ }
827
+ return entry;
828
+ }
829
+ function totalUsage(accounting) {
830
+ const total = {
831
+ promptTokens: 0,
832
+ completionTokens: 0,
833
+ costUsd: null
834
+ };
835
+ for (const entry of accounting.values()) accumulate(total, entry.tracker.total());
836
+ return snapshot(total);
837
+ }
838
+ function totalIterations(accounting) {
839
+ let total = 0;
840
+ for (const entry of accounting.values()) total += entry.iterations;
841
+ return total;
842
+ }
843
+ function accumulate(total, usage) {
844
+ total.promptTokens += usage.promptTokens;
845
+ total.completionTokens += usage.completionTokens;
846
+ if (usage.costUsd !== null) total.costUsd = (total.costUsd ?? 0) + usage.costUsd;
847
+ }
848
+ function snapshot(usage) {
849
+ return {
850
+ promptTokens: usage.promptTokens,
851
+ completionTokens: usage.completionTokens,
852
+ costUsd: usage.costUsd
853
+ };
854
+ }
855
+ function deriveRemainingBudget(input) {
856
+ const remaining = {};
857
+ const budget = input.policy.budget;
858
+ const iterationCeiling = minDefined(budget?.maxIterations, input.policy.maxTotalIterations);
859
+ if (iterationCeiling !== void 0) remaining.maxIterations = iterationCeiling - input.iterations;
860
+ if (budget?.maxWallTimeMs !== void 0) remaining.maxWallTimeMs = budget.maxWallTimeMs - (Date.now() - input.startedAt);
861
+ if (budget?.maxCostUsd !== void 0 && input.usage.costUsd !== null) remaining.maxCostUsd = budget.maxCostUsd - input.usage.costUsd;
862
+ else if (budget?.maxCostUsd !== void 0 && input.usage.costUsd === null) remaining.maxCostUsd = budget.maxCostUsd;
863
+ if (budget?.p95LatencyMs !== void 0) remaining.p95LatencyMs = budget.p95LatencyMs;
864
+ return Object.keys(remaining).length > 0 ? remaining : void 0;
865
+ }
866
+ function crewBudgetViolated(input) {
867
+ const iterationCeiling = minDefined(input.policy.budget?.maxIterations, input.policy.maxTotalIterations);
868
+ if (iterationCeiling !== void 0 && input.iterations > iterationCeiling) return true;
869
+ const maxWallTimeMs = input.policy.budget?.maxWallTimeMs;
870
+ if (maxWallTimeMs !== void 0 && Date.now() - input.startedAt > maxWallTimeMs) return true;
871
+ const maxCostUsd = input.policy.budget?.maxCostUsd;
872
+ return maxCostUsd !== void 0 && input.usage.costUsd !== null && input.usage.costUsd > maxCostUsd;
873
+ }
874
+ function minDefined(a, b) {
875
+ if (a !== void 0 && b !== void 0) return Math.min(a, b);
876
+ return a ?? b;
877
+ }
878
+ function createRateLimitGroupResolver(policy) {
879
+ if (policy.coordination === "unmanaged") return () => void 0;
880
+ const groups = /* @__PURE__ */ new Map();
881
+ return (provider) => {
882
+ let group = groups.get(provider);
883
+ if (group === void 0) {
884
+ group = createRateLimitGroup(rateLimitOptionsFor(policy, provider));
885
+ groups.set(provider, group);
886
+ }
887
+ return group;
888
+ };
889
+ }
890
+ function rateLimitOptionsFor(policy, provider) {
891
+ const override = policy.limits?.[provider.id];
892
+ return {
893
+ ...override?.requestsPerMinute !== void 0 ? { requestsPerMinute: override.requestsPerMinute } : {},
894
+ ...override?.tokensPerMinute !== void 0 ? { tokensPerMinute: override.tokensPerMinute } : {}
895
+ };
896
+ }
897
+ function wrapHostWithRateLimits(host, groupForProvider) {
898
+ return {
899
+ ...host,
900
+ transport: wrapTransport(host.transport, groupForProvider)
901
+ };
902
+ }
903
+ function wrapTransport(inner, groupForProvider) {
904
+ return { call(provider, request) {
905
+ const group = groupForProvider(provider);
906
+ if (group !== void 0) return withRateLimit(group, inner).call(provider, request);
907
+ if (inner !== void 0) return inner.call(provider, request);
908
+ if (provider.execute === void 0) throw new Error(`AgentTransport: provider ${provider.id} has no execute() method.`);
909
+ return provider.execute(request);
910
+ } };
911
+ }
912
+ function composeSharedPrefix(root) {
913
+ const firstChild = root.childAgents?.[0];
914
+ return composeCrewCachePrefix(firstChild?.tools ?? root.tools);
915
+ }
916
+ async function maybeMintCrewRoot(input) {
917
+ if (input.signer === void 0) return void 0;
918
+ const envelope = await createReceipt({
919
+ runId: input.runId,
920
+ model: {
921
+ requested: "lattice-crew/root",
922
+ observed: null
923
+ },
924
+ route: {
925
+ providerId: "lattice-crew",
926
+ capabilityId: "lattice-crew/run",
927
+ attemptNumber: 1
928
+ },
929
+ usage: ZERO_USAGE,
930
+ contractVerdict: "success",
931
+ contractHash: null,
932
+ inputHashes: [],
933
+ outputHash: null,
934
+ stepName: `crew-start:${input.root.id}`
935
+ }, input.signer);
936
+ return {
937
+ envelope,
938
+ cid: await receiptCid(envelope)
939
+ };
940
+ }
941
+ async function createAgentCompletionReceipt(input) {
942
+ const lineageMerkleRoot = await computeArtifactLineageMerkleRoot(input.artifacts ?? []);
943
+ return createReceipt({
944
+ runId: input.runId,
945
+ model: {
946
+ requested: "lattice-crew/agent-completion",
947
+ observed: null
948
+ },
949
+ route: {
950
+ providerId: "lattice-crew",
951
+ capabilityId: "lattice-crew/agent-completion",
952
+ attemptNumber: 1
953
+ },
954
+ parentReceiptCid: input.parentReceiptCid,
955
+ ...lineageMerkleRoot !== void 0 ? { lineageMerkleRoot } : {},
956
+ usage: input.usage,
957
+ contractVerdict: input.success ? "success" : "execution-failed",
958
+ contractHash: null,
959
+ inputHashes: [],
960
+ outputHash: null,
961
+ stepName: `crew-agent-completion:${input.agentId}`
962
+ }, input.signer);
963
+ }
964
+ async function populateReceiptCidIndex(receipts, byAgent) {
965
+ for (const envelope of receipts) {
966
+ const agentId = parseCompletionAgentId(decodeReceiptBody(envelope).stepName);
967
+ if (agentId === null) continue;
968
+ const cids = byAgent.get(agentId) ?? [];
969
+ cids.push(await receiptCid(envelope));
970
+ byAgent.set(agentId, cids);
971
+ }
972
+ }
973
+ function decodeReceiptBody(envelope) {
974
+ return JSON.parse(atob(envelope.payload));
975
+ }
976
+ function parseCompletionAgentId(stepName) {
977
+ if (stepName?.startsWith("crew-agent-completion:") !== true) return null;
978
+ return stepName.slice(22);
979
+ }
980
+ function buildPerAgent(accounting, receiptCidsByAgent) {
981
+ return Object.freeze(Array.from(accounting.entries(), ([id, entry]) => Object.freeze({
982
+ id,
983
+ usage: Object.freeze(entry.tracker.total()),
984
+ iterations: entry.iterations,
985
+ receiptCids: Object.freeze([...receiptCidsByAgent.get(id) ?? []])
986
+ })));
987
+ }
988
+ function freezeCrewResult(result) {
989
+ return Object.freeze({
990
+ result: result.result,
991
+ perAgent: Object.freeze([...result.perAgent]),
992
+ usage: Object.freeze({ ...result.usage }),
993
+ totalIterations: result.totalIterations,
994
+ receipts: Object.freeze([...result.receipts]),
995
+ ...result.crewRootCid !== void 0 ? { crewRootCid: result.crewRootCid } : {}
996
+ });
997
+ }
998
+ function buildCrewBudgetFailure(parentResult) {
999
+ return {
1000
+ kind: "crew-budget-exceeded",
1001
+ reason: "Crew budget pool exhausted — the crew run ended with terminal semantics.",
1002
+ usage: parentResult.usage,
1003
+ iterations: Object.freeze([...parentResult.iterations]),
1004
+ ...parentResult.receipt !== void 0 ? { receipt: parentResult.receipt } : {}
1005
+ };
1006
+ }
1007
+ //#endregion
1008
+ export { STUCK_REASONS as a, createCostTracker as c, withRateLimit as i, receiptCid as l, run_crew_exports as n, createActionHistory as o, createRateLimitGroup as r, computeArtifactLineageMerkleRoot as s, runAgentCrew as t };
1009
+
1010
+ //# sourceMappingURL=run-crew-CKdBjh5P.js.map