@sema-agent/core 5.60.1 → 5.61.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/CHANGELOG.md +58 -0
- package/dist/agents/subagent.d.ts +4 -2
- package/dist/agents/subagent.js +9 -9
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +2 -2
- package/dist/core/memory-engine/consolidation-driver.d.ts +19 -1
- package/dist/core/memory-engine/consolidation-driver.js +75 -3
- package/dist/core/memory-engine/consolidation.d.ts +52 -5
- package/dist/core/memory-engine/consolidation.js +3 -1
- package/dist/core/memory-engine/distiller.d.ts +89 -1
- package/dist/core/memory-engine/distiller.js +94 -5
- package/dist/core/memory-engine/engine.d.ts +8 -0
- package/dist/core/memory-engine/engine.js +51 -8
- package/dist/core/memory-engine/index.d.ts +1 -1
- package/dist/core/memory-engine/index.js +1 -1
- package/dist/core/runner/prepare-task.d.ts +6 -3
- package/dist/core/runner/runtask.js +57 -26
- package/dist/core/task-notification.d.ts +50 -23
- package/dist/core/task-notification.js +20 -4
- package/dist/core/types.d.ts +76 -19
- package/dist/engine/harness/agent-harness.d.ts +58 -2
- package/dist/engine/harness/agent-harness.js +115 -5
- package/dist/engine/loop/agent-loop.js +153 -15
- package/dist/engine/loop/types.d.ts +32 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +7 -2
- package/dist/orchestration/run-workflow-tool.js +1 -1
- package/dist/tools/monitor.d.ts +3 -3
- package/dist/tools/monitor.js +1 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +7 -1
|
@@ -252,12 +252,15 @@ export function sanitizeLlmGroups(groups, { candidateIds, maxInputsPerProduct =
|
|
|
252
252
|
}
|
|
253
253
|
return { groups: clean, repairs, claimedIds: [...claimed] };
|
|
254
254
|
}
|
|
255
|
-
|
|
255
|
+
function assertMintConfig(chat, model) {
|
|
256
256
|
if (typeof chat !== "function")
|
|
257
257
|
throw distillerConfigRefusal("mintLlmConsolidationPlan needs a chat function (the explicit model seat) — a distiller that silently skips would publish an empty plan as a model's answer.");
|
|
258
258
|
if (typeof model !== "string" || model.trim() === "" || isAliasModelId(model)) {
|
|
259
259
|
throw distillerConfigRefusal(`mintLlmConsolidationPlan needs an EXPLICIT model id, got ${JSON.stringify(model)} — an alias can be re-pointed upstream and would move the run with no trace in the plan.`);
|
|
260
260
|
}
|
|
261
|
+
}
|
|
262
|
+
export async function mintLlmConsolidationPlan({ candidates, chat, model, baseUrl, maxInputsPerProduct = DISTILLER_DEFAULT_MAX_INPUTS_PER_PRODUCT, contract = MEMORY_DISTILLER_CONTRACT_V1, onProgress = null, armLabel, }) {
|
|
263
|
+
assertMintConfig(chat, model);
|
|
261
264
|
const rows = candidates.map((c, i) => ({ n: i + 1, id: c?.entry?.id, rev: c?.entry?.rev, text: renderCandidate(i + 1, c) }));
|
|
262
265
|
const missingId = rows.filter((r) => typeof r.id !== "string");
|
|
263
266
|
if (missingId.length > 0)
|
|
@@ -277,7 +280,7 @@ export async function mintLlmConsolidationPlan({ candidates, chat, model, baseUr
|
|
|
277
280
|
for (let attempt = 0; attempt <= contract.retries && groups === null; attempt++) {
|
|
278
281
|
groupingAttempts += 1;
|
|
279
282
|
const user = attempt === 0 ? groupingUser : `${groupingUser}\n\nYour previous answer could not be read: ${lastError}. Answer with one JSON object and nothing else.`;
|
|
280
|
-
const out = await record(`grouping#${attempt + 1}`, () => chat({ system: contract.grouping.system, user, maxTokens: contract.sampling.maxTokens.grouping, temperature: contract.sampling.temperature }));
|
|
283
|
+
const out = await record(`grouping${armLabel !== undefined ? `.${armLabel}` : ""}#${attempt + 1}`, () => chat({ system: contract.grouping.system, user, maxTokens: contract.sampling.maxTokens.grouping, temperature: contract.sampling.temperature }));
|
|
281
284
|
if (out.finishReason === "length") {
|
|
282
285
|
lastError = "the answer was cut off at the token limit";
|
|
283
286
|
continue;
|
|
@@ -312,7 +315,7 @@ export async function mintLlmConsolidationPlan({ candidates, chat, model, baseUr
|
|
|
312
315
|
let err = null;
|
|
313
316
|
for (let attempt = 0; attempt <= contract.retries && written === null; attempt++) {
|
|
314
317
|
const u = attempt === 0 ? user : `${user}\n\nYour previous answer could not be read: ${err}. Answer with one JSON object and nothing else.`;
|
|
315
|
-
const out = await record(`writing#${i + 1}:${g.key}#${attempt + 1}`, () => chat({ system: contract.writing.system, user: u, maxTokens: contract.sampling.maxTokens.writing, temperature: contract.sampling.temperature }));
|
|
318
|
+
const out = await record(`writing${armLabel !== undefined ? `.${armLabel}` : ""}#${i + 1}:${g.key}#${attempt + 1}`, () => chat({ system: contract.writing.system, user: u, maxTokens: contract.sampling.maxTokens.writing, temperature: contract.sampling.temperature }));
|
|
316
319
|
if (out.finishReason === "length") {
|
|
317
320
|
err = "the answer was cut off at the token limit";
|
|
318
321
|
continue;
|
|
@@ -372,17 +375,103 @@ export async function mintLlmConsolidationPlan({ candidates, chat, model, baseUr
|
|
|
372
375
|
},
|
|
373
376
|
};
|
|
374
377
|
}
|
|
378
|
+
export const normalizedCandidateRev = (rev) => (typeof rev === "string" ? rev : "");
|
|
379
|
+
const rosterOf = (list) => list.map((c) => ({ id: c.entry.id, rev: normalizedCandidateRev(c.entry.rev), marked: c.marked === true }));
|
|
380
|
+
const armUsageOf = (arm, plan, candidateCount) => ({
|
|
381
|
+
arm,
|
|
382
|
+
candidateCount,
|
|
383
|
+
calls: plan.minting.calls,
|
|
384
|
+
promptTokens: plan.minting.usage.promptTokens,
|
|
385
|
+
completionTokens: plan.minting.usage.completionTokens,
|
|
386
|
+
retries: plan.minting.parseRepairs.retries,
|
|
387
|
+
truncations: plan.minting.parseRepairs.lengthCapped.length,
|
|
388
|
+
groupingPrompt: plan.minting.prompts.grouping,
|
|
389
|
+
});
|
|
390
|
+
export async function mintExposurePartitionedPlan(args) {
|
|
391
|
+
assertMintConfig(args.chat, args.model);
|
|
392
|
+
const { candidates, ...rest } = args;
|
|
393
|
+
const clean = (candidates ?? []).filter((c) => c?.marked !== true);
|
|
394
|
+
const marked = (candidates ?? []).filter((c) => c?.marked === true);
|
|
395
|
+
if (marked.length === 0) {
|
|
396
|
+
const res = await mintLlmConsolidationPlan({ ...rest, candidates: clean });
|
|
397
|
+
if (!res.ok)
|
|
398
|
+
return res;
|
|
399
|
+
return { ok: true, plan: { ...res.plan, mintExposure: "partitioned", servedCandidates: rosterOf(clean) } };
|
|
400
|
+
}
|
|
401
|
+
const cleanRes = clean.length > 0 ? await mintLlmConsolidationPlan({ ...rest, candidates: clean, armLabel: "clean" }) : undefined;
|
|
402
|
+
if (cleanRes !== undefined && !cleanRes.ok) {
|
|
403
|
+
return { ok: false, reason: `clean arm: ${cleanRes.reason}`, calls: cleanRes.calls };
|
|
404
|
+
}
|
|
405
|
+
const markedRes = marked.length >= 2 ? await mintLlmConsolidationPlan({ ...rest, candidates: marked, armLabel: "marked" }) : undefined;
|
|
406
|
+
if (markedRes !== undefined && !markedRes.ok) {
|
|
407
|
+
return { ok: false, reason: `marked arm: ${markedRes.reason}`, calls: [...(cleanRes?.plan.minting.transcript ?? []), ...markedRes.calls] };
|
|
408
|
+
}
|
|
409
|
+
const arms = [
|
|
410
|
+
...(cleanRes !== undefined ? [{ res: cleanRes.plan, tag: "clean", count: clean.length }] : []),
|
|
411
|
+
...(markedRes !== undefined ? [{ res: markedRes.plan, tag: "marked", count: marked.length }] : []),
|
|
412
|
+
];
|
|
413
|
+
const served = [...(cleanRes !== undefined ? clean : []), ...(markedRes !== undefined ? marked : [])];
|
|
414
|
+
const transcript = arms.flatMap((a) => a.res.minting.transcript);
|
|
415
|
+
const sumRepairs = (k) => arms.reduce((n, a) => n + a.res.minting.repairs[k], 0);
|
|
416
|
+
const anchor = arms[0]?.res;
|
|
417
|
+
return {
|
|
418
|
+
ok: true,
|
|
419
|
+
plan: {
|
|
420
|
+
kind: "llm-consolidation-plan",
|
|
421
|
+
contractVersion: anchor?.contractVersion ?? (rest.contract ?? MEMORY_DISTILLER_CONTRACT_V1).version,
|
|
422
|
+
model: rest.model,
|
|
423
|
+
...(rest.baseUrl !== undefined ? { baseUrl: rest.baseUrl } : {}),
|
|
424
|
+
mintedAt: anchor?.mintedAt ?? new Date().toISOString(),
|
|
425
|
+
maxInputsPerProduct: anchor?.maxInputsPerProduct ?? rest.maxInputsPerProduct ?? DISTILLER_DEFAULT_MAX_INPUTS_PER_PRODUCT,
|
|
426
|
+
candidateCount: (candidates ?? []).length,
|
|
427
|
+
products: arms.flatMap((a) => a.res.products),
|
|
428
|
+
mintExposure: "partitioned",
|
|
429
|
+
servedCandidates: rosterOf(served),
|
|
430
|
+
withheldFromCleanArm: marked.length,
|
|
431
|
+
minting: {
|
|
432
|
+
calls: transcript.length,
|
|
433
|
+
groupingAttempts: arms.reduce((n, a) => n + a.res.minting.groupingAttempts, 0),
|
|
434
|
+
groupingParseRepairs: arms.reduce((n, a) => n + a.res.minting.groupingParseRepairs, 0),
|
|
435
|
+
parseRepairs: planParseRepairs({ minting: { transcript } }),
|
|
436
|
+
repairs: {
|
|
437
|
+
hallucinatedMembers: sumRepairs("hallucinatedMembers"),
|
|
438
|
+
duplicateMembers: sumRepairs("duplicateMembers"),
|
|
439
|
+
emptyGroups: sumRepairs("emptyGroups"),
|
|
440
|
+
oversizeGroups: arms.flatMap((a) => a.res.minting.repairs.oversizeGroups),
|
|
441
|
+
nonIntegerMembers: sumRepairs("nonIntegerMembers"),
|
|
442
|
+
},
|
|
443
|
+
writeFailures: arms.flatMap((a) => a.res.minting.writeFailures),
|
|
444
|
+
usage: {
|
|
445
|
+
promptTokens: arms.reduce((n, a) => n + a.res.minting.usage.promptTokens, 0),
|
|
446
|
+
completionTokens: arms.reduce((n, a) => n + a.res.minting.usage.completionTokens, 0),
|
|
447
|
+
},
|
|
448
|
+
prompts: {
|
|
449
|
+
grouping: anchor?.minting.prompts.grouping ?? "",
|
|
450
|
+
writingTemplate: (rest.contract ?? MEMORY_DISTILLER_CONTRACT_V1).writing.instructions,
|
|
451
|
+
systems: {
|
|
452
|
+
grouping: (rest.contract ?? MEMORY_DISTILLER_CONTRACT_V1).grouping.system,
|
|
453
|
+
writing: (rest.contract ?? MEMORY_DISTILLER_CONTRACT_V1).writing.system,
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
transcript,
|
|
457
|
+
...(arms.length > 0 ? { arms: arms.map((a) => armUsageOf(a.tag, a.res, a.count)) } : {}),
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
};
|
|
461
|
+
}
|
|
375
462
|
export function llmPlanDistiller(plan) {
|
|
376
463
|
const products = plan?.products ?? [];
|
|
464
|
+
const mintExposure = plan?.mintExposure === "partitioned" ? "partitioned" : undefined;
|
|
377
465
|
return (candidates, _snapshot, scope) => {
|
|
378
466
|
const offered = new Map();
|
|
379
467
|
for (const x of (candidates ?? [])) {
|
|
380
468
|
const id = x?.entry?.id ?? x?.id;
|
|
381
469
|
if (typeof id === "string")
|
|
382
|
-
offered.set(id,
|
|
470
|
+
offered.set(id, normalizedCandidateRev(x?.entry?.rev));
|
|
383
471
|
}
|
|
384
472
|
return {
|
|
385
473
|
scope,
|
|
474
|
+
...(mintExposure !== undefined ? { mintExposure } : {}),
|
|
386
475
|
products: products.map((p) => {
|
|
387
476
|
const ids = p.inputIds ?? [];
|
|
388
477
|
const live = ids.filter((id) => offered.has(id));
|
|
@@ -527,7 +616,7 @@ export async function driveConsolidationToFixpoint(engine, scope, opts) {
|
|
|
527
616
|
let receipt;
|
|
528
617
|
let commitError = null;
|
|
529
618
|
try {
|
|
530
|
-
receipt = await engine.commitConsolidationPlan(snapshot.cycleToken, { scope, products: plan.picked }, { requestId: `${requestIdPrefix}-c${cycle}` });
|
|
619
|
+
receipt = await engine.commitConsolidationPlan(snapshot.cycleToken, { scope, products: plan.picked, ...(proposal.mintExposure !== undefined ? { mintExposure: proposal.mintExposure } : {}) }, { requestId: `${requestIdPrefix}-c${cycle}` });
|
|
531
620
|
}
|
|
532
621
|
catch (err) {
|
|
533
622
|
commitError = err;
|
|
@@ -475,6 +475,10 @@ export interface ConsolidationCommitReceipt {
|
|
|
475
475
|
settled: string[];
|
|
476
476
|
pending: string[];
|
|
477
477
|
};
|
|
478
|
+
/** True ⇔ the RUN-LEVEL single-value fold applied to this plan (design/376-C1 D-6: an
|
|
479
|
+
* un-attested freeze over a marked served set). An attested (exposure-partitioned) plan
|
|
480
|
+
* answers false here even when some of its products carry origin — per-product outcomes live
|
|
481
|
+
* in the plan summary's `markedProducts` and in each product's own committed bytes. */
|
|
478
482
|
foldedOrigin: boolean;
|
|
479
483
|
notices: EngineNotice[];
|
|
480
484
|
}
|
|
@@ -510,6 +514,10 @@ export interface ConsolidationPlanSummary {
|
|
|
510
514
|
state?: ConsolidationPlanFile["state"];
|
|
511
515
|
createdAt?: number;
|
|
512
516
|
products?: number;
|
|
517
|
+
/** design/376-C1 D-6 (additive) — how many of the plan's frozen products carry an origin marker
|
|
518
|
+
* in their own bytes. Counts BOTH fold forms truthfully: a run-level plan's single value rides
|
|
519
|
+
* every product, an attested plan marks exactly the products whose declared inputs were marked. */
|
|
520
|
+
markedProducts?: number;
|
|
513
521
|
directed?: number;
|
|
514
522
|
intents?: number;
|
|
515
523
|
}
|
|
@@ -2596,7 +2596,7 @@ export class MemoryEngine {
|
|
|
2596
2596
|
if (fresh.epoch !== epoch) {
|
|
2597
2597
|
throw new ConsolidationRefusedError("memory.consolidation_stale_snapshot", `memory consolidation refused: the ${JSON.stringify(scope)} watermark advanced during the snapshot read — retake the snapshot.`);
|
|
2598
2598
|
}
|
|
2599
|
-
fresh.snapshot = { token: cycleToken, at, epoch, candidates: candidateRevs, eligible: eligibleRevs, marked };
|
|
2599
|
+
fresh.snapshot = { token: cycleToken, at, epoch, candidates: candidateRevs, eligible: eligibleRevs, marked, markedIds: candidates.filter((c) => c.marked).map((c) => c.entry.id) };
|
|
2600
2600
|
let announce = false;
|
|
2601
2601
|
if (opts.force !== undefined && fresh.lastForcedRequestId !== opts.force.requestId) {
|
|
2602
2602
|
fresh.lastForcedRequestId = opts.force.requestId;
|
|
@@ -2656,6 +2656,9 @@ export class MemoryEngine {
|
|
|
2656
2656
|
else if (p.inputs.length > screened.maxInputsPerProduct)
|
|
2657
2657
|
reasons.push(`product #${i}: ${p.inputs.length} inputs > maxInputsPerProduct ${screened.maxInputsPerProduct}`);
|
|
2658
2658
|
}
|
|
2659
|
+
if (proposal.mintExposure !== undefined && proposal.mintExposure !== "partitioned") {
|
|
2660
|
+
reasons.push(`mintExposure ${JSON.stringify(proposal.mintExposure)} is not a member of the closed attestation set {"partitioned"} — omit it (run-level fold) or spell it exactly`);
|
|
2661
|
+
}
|
|
2659
2662
|
if (proposal.products.length === 0 && intents.length === 0) {
|
|
2660
2663
|
reasons.push("empty plan: zero products and zero directed intents — a plan with nothing to apply must not settle as a completed run (the vacuous completion would stamp the eligible set into the fingerprint and blind the incremental face)");
|
|
2661
2664
|
}
|
|
@@ -2741,19 +2744,43 @@ export class MemoryEngine {
|
|
|
2741
2744
|
}
|
|
2742
2745
|
const activeSetSize = headers.filter((h) => !superseded.has(h.id) && !exclusions.has(h.id)).length;
|
|
2743
2746
|
const ceiling = supersessionFuseCeiling(activeSetSize, screened);
|
|
2747
|
+
const attested = proposal.mintExposure === "partitioned";
|
|
2748
|
+
if (attested) {
|
|
2749
|
+
const staleAxes = [];
|
|
2750
|
+
const baseline = snapshot.markedIds !== undefined ? new Set(snapshot.markedIds) : undefined;
|
|
2751
|
+
for (const [id, rev] of Object.entries(snapshot.candidates)) {
|
|
2752
|
+
const h = headerById.get(id);
|
|
2753
|
+
if (h === undefined)
|
|
2754
|
+
staleAxes.push(`served candidate ${id} left the committed listing`);
|
|
2755
|
+
else if (h.rev !== rev)
|
|
2756
|
+
staleAxes.push(`served candidate ${id} moved rev since the snapshot`);
|
|
2757
|
+
else if (exclusions.has(id))
|
|
2758
|
+
staleAxes.push(`served candidate ${id} entered the challenge/latch exclusion set`);
|
|
2759
|
+
else if (h.exposure !== undefined && (baseline === undefined || !baseline.has(id))) {
|
|
2760
|
+
staleAxes.push(baseline === undefined
|
|
2761
|
+
? `served candidate ${id} is marked and the snapshot row predates the markedIds baseline — no proof the mark predates the mint (conservative arm)`
|
|
2762
|
+
: `served candidate ${id} turned marked since the snapshot`);
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
if (staleAxes.length > 0) {
|
|
2766
|
+
throw new ConsolidationRefusedError("memory.consolidation_stale_snapshot", `memory consolidation refused: the attested (exposure-partitioned) mint's clean-arm premise is stale — the ${JSON.stringify(scope)} world moved between snapshot and freeze; retake the snapshot and re-mint`, staleAxes);
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2744
2769
|
let visibleMarked = snapshot.marked;
|
|
2745
|
-
if (!visibleMarked) {
|
|
2770
|
+
if (!attested && !visibleMarked) {
|
|
2746
2771
|
const inputIds = [...new Set(proposal.products.flatMap((p) => p.inputs.map((i2) => i2.id)))];
|
|
2747
2772
|
const committedInputs = await face.getByIds(inputIds);
|
|
2748
2773
|
visibleMarked = committedInputs.some((e) => committedOriginOf(e.frontmatter) !== undefined);
|
|
2749
2774
|
}
|
|
2750
|
-
const foldedOrigin = visibleMarked ? { taint: "external", cause: "derived", at } : undefined;
|
|
2775
|
+
const foldedOrigin = !attested && visibleMarked ? { taint: "external", cause: "derived", at } : undefined;
|
|
2776
|
+
const productMarked = (p) => p.inputs.some((i2) => headerById.get(i2.id)?.exposure !== undefined);
|
|
2751
2777
|
for (let i = 0; i < proposal.products.length; i++) {
|
|
2752
2778
|
const p = proposal.products[i];
|
|
2753
2779
|
if (!isInstructionEntry({ ...(p.type !== undefined ? { type: p.type } : {}) }))
|
|
2754
2780
|
continue;
|
|
2755
|
-
|
|
2756
|
-
|
|
2781
|
+
const hardArm = attested ? productMarked(p) : visibleMarked;
|
|
2782
|
+
if (hardArm) {
|
|
2783
|
+
wholeReasons.push(`product #${i}: instruction-form product (type ${JSON.stringify(p.type)}) refused — ${attested ? "the product's declared inputs contain marked content" : "the run's visible set contains marked content"} (the laundering hard gate, G7/G26; no option opens this arm)`);
|
|
2757
2784
|
}
|
|
2758
2785
|
else if (!screened.allowInstructionProducts) {
|
|
2759
2786
|
wholeReasons.push(`product #${i}: instruction-form product (type ${JSON.stringify(p.type)}) refused — instruction-form consolidation products are refused unconditionally by default (a consolidation must not mint privileged entries out of ordinary notes); the host escape hatch is consolidation.allowInstructionProducts: true`);
|
|
@@ -2784,6 +2811,7 @@ export class MemoryEngine {
|
|
|
2784
2811
|
}
|
|
2785
2812
|
const id = uuidv7();
|
|
2786
2813
|
const slug = deriveProductSlug(p.name, `consolidated-${id.slice(0, 8)}`);
|
|
2814
|
+
const productOrigin = attested ? (productMarked(p) ? { taint: "external", cause: "derived", at } : undefined) : foldedOrigin;
|
|
2787
2815
|
const entry = {
|
|
2788
2816
|
id,
|
|
2789
2817
|
slug,
|
|
@@ -2792,7 +2820,7 @@ export class MemoryEngine {
|
|
|
2792
2820
|
name: p.name ?? slug,
|
|
2793
2821
|
...(p.description !== undefined ? { description: p.description } : {}),
|
|
2794
2822
|
...(p.type !== undefined ? { type: p.type } : {}),
|
|
2795
|
-
...(
|
|
2823
|
+
...(productOrigin !== undefined ? { origin: { ...productOrigin } } : {}),
|
|
2796
2824
|
distilled: {
|
|
2797
2825
|
planId,
|
|
2798
2826
|
at,
|
|
@@ -2917,6 +2945,7 @@ export class MemoryEngine {
|
|
|
2917
2945
|
epoch: snapshot.epoch,
|
|
2918
2946
|
visibleMarked,
|
|
2919
2947
|
...(foldedOrigin !== undefined ? { foldedOrigin } : {}),
|
|
2948
|
+
...(attested ? { mintExposure: "partitioned" } : {}),
|
|
2920
2949
|
products: assembled,
|
|
2921
2950
|
productStates: Object.fromEntries(assembled.map((e) => [e.id, "pending"])),
|
|
2922
2951
|
...(freezeRefusedInputIds.length > 0 ? { freezeRefusedInputIds } : {}),
|
|
@@ -2924,7 +2953,21 @@ export class MemoryEngine {
|
|
|
2924
2953
|
intents: intents.map((it) => ({ requestId: it.requestId, state: "pending" })),
|
|
2925
2954
|
state: "open",
|
|
2926
2955
|
audit: [
|
|
2927
|
-
{
|
|
2956
|
+
{
|
|
2957
|
+
at,
|
|
2958
|
+
event: "frozen",
|
|
2959
|
+
requestId: input.requestId,
|
|
2960
|
+
...((() => {
|
|
2961
|
+
const parts = [];
|
|
2962
|
+
if (attested) {
|
|
2963
|
+
const markedProducts = assembled.filter((e) => e.frontmatter.origin !== undefined).length;
|
|
2964
|
+
parts.push(`attested exposure-partitioned mint: ${markedProducts} marked / ${assembled.length - markedProducts} clean product(s)`);
|
|
2965
|
+
}
|
|
2966
|
+
if (refusedProducts.length > 0)
|
|
2967
|
+
parts.push(`${refusedProducts.length} product(s) refused at freeze: ${refusedProducts.map((r) => `#${r.index}: ${r.reason}`).join(" | ")}`);
|
|
2968
|
+
return parts.length > 0 ? { detail: parts.join("; ") } : {};
|
|
2969
|
+
})()),
|
|
2970
|
+
},
|
|
2928
2971
|
],
|
|
2929
2972
|
};
|
|
2930
2973
|
writeConsolidationPlan(this.controlDir, plan);
|
|
@@ -3492,7 +3535,7 @@ export class MemoryEngine {
|
|
|
3492
3535
|
if (read.state === "absent")
|
|
3493
3536
|
continue;
|
|
3494
3537
|
const p = read.plan;
|
|
3495
|
-
out.push({ planId, scope: p.scope, state: p.state, createdAt: p.createdAt, products: p.products.length, directed: p.directed.length, intents: p.intents.length });
|
|
3538
|
+
out.push({ planId, scope: p.scope, state: p.state, createdAt: p.createdAt, products: p.products.length, markedProducts: p.products.filter((e) => e.frontmatter?.origin !== undefined).length, directed: p.directed.length, intents: p.intents.length });
|
|
3496
3539
|
}
|
|
3497
3540
|
return out;
|
|
3498
3541
|
}
|
|
@@ -9,7 +9,7 @@ export { readV2HeaderHints, isInstructionEntry, type V2HeaderHints } from "./hea
|
|
|
9
9
|
export { parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, committedOriginOf, originEquals, ambiguousOriginRepresentation, type ParsedEntryFile } from "./frontmatter.js";
|
|
10
10
|
export { committedDistilledOf, distilledEquals } from "./frontmatter.js";
|
|
11
11
|
export { CONSOLIDATION_DEFAULTS, ConsolidationRefusedError, MEMORY_SEARCH_SUPERSEDED_TAG, consolidationTypeEligible, deriveSupersededSet, memorySupersededNote, readIntentCredentials, supersessionFuseCeiling, type ConsolidationGateRead, type ConsolidationGateRow, type ConsolidationIntent, type ConsolidationIntentCredentialRow, type ConsolidationLeaseSeat, type ConsolidationProductProposal, type ConsolidationProposal, type MemoryConsolidationOptions, CONSOLIDATION_RUN_STOP_REASONS, type ConsolidationRunStopReason, } from "./consolidation.js";
|
|
12
|
-
export { DISTILLER_DEFAULT_MAX_INPUTS_PER_PRODUCT, LLM_DISTILLER_CONTRACT, LLM_DISTILLER_CONTRACT_DL2, LLM_DISTILLER_CONTRACT_DL3, LLM_DISTILLER_CONTRACTS, MEMORY_DISTILLER_CONTRACT_V1, contractGroupingDiff, driveConsolidationToFixpoint, isAliasModelId, llmPlanDistiller, mintLlmConsolidationPlan, openAiCompatChatSeat, parseJsonAnswer, planParseRepairs, sanitizeLlmGroups, scheduleUnderFuse, type ConsolidationDistillFn, type ConsolidationDriveCycleRow, type ConsolidationDriveEngine, type ConsolidationDriveResult, type ConsolidationFoldState, type DistillerCandidate, type DistillerChatAnswer, type DistillerChatFn, type DistillerChatRequest, type FuseSchedule, type LlmConsolidationPlan, type LlmConsolidationPlanProduct, type LlmDistillerContract, type MintLlmConsolidationPlanResult, type PlanParseRepairs, type SanitizedLlmGroups, } from "./distiller.js";
|
|
12
|
+
export { DISTILLER_DEFAULT_MAX_INPUTS_PER_PRODUCT, LLM_DISTILLER_CONTRACT, LLM_DISTILLER_CONTRACT_DL2, LLM_DISTILLER_CONTRACT_DL3, LLM_DISTILLER_CONTRACTS, MEMORY_DISTILLER_CONTRACT_V1, contractGroupingDiff, driveConsolidationToFixpoint, isAliasModelId, llmPlanDistiller, mintExposurePartitionedPlan, mintLlmConsolidationPlan, openAiCompatChatSeat, parseJsonAnswer, planParseRepairs, sanitizeLlmGroups, scheduleUnderFuse, type ConsolidationDistillFn, type ConsolidationDriveCycleRow, type ConsolidationDriveEngine, type ConsolidationDriveResult, type ConsolidationFoldState, type DistillerCandidate, type DistillerChatAnswer, type DistillerChatFn, type DistillerChatRequest, type FuseSchedule, type LlmConsolidationPlan, type LlmConsolidationPlanArm, type LlmConsolidationPlanProduct, type LlmDistillerContract, type MintLlmConsolidationPlanResult, type PlanParseRepairs, type SanitizedLlmGroups, } from "./distiller.js";
|
|
13
13
|
export { CONSOLIDATION_DRIVER_PLANS_DIR, CONSOLIDATION_DRIVER_RUNS_FILE, archiveDistillerPlan, readConsolidationDriverRun, runMemoryConsolidationDriver, type ConsolidationDriverEngine, type ConsolidationDriverRunRow, type ConsolidationRunReceipt, type RunMemoryConsolidationOptions, } from "./consolidation-driver.js";
|
|
14
14
|
export type { OriginClearanceRow, OriginClearanceEvent } from "./origin-clearance.js";
|
|
15
15
|
export { MEMORY_ORIGIN_CAUSES } from "./types.js";
|
|
@@ -9,7 +9,7 @@ export { readV2HeaderHints, isInstructionEntry } from "./header-hints.js";
|
|
|
9
9
|
export { parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, committedOriginOf, originEquals, ambiguousOriginRepresentation } from "./frontmatter.js";
|
|
10
10
|
export { committedDistilledOf, distilledEquals } from "./frontmatter.js";
|
|
11
11
|
export { CONSOLIDATION_DEFAULTS, ConsolidationRefusedError, MEMORY_SEARCH_SUPERSEDED_TAG, consolidationTypeEligible, deriveSupersededSet, memorySupersededNote, readIntentCredentials, supersessionFuseCeiling, CONSOLIDATION_RUN_STOP_REASONS, } from "./consolidation.js";
|
|
12
|
-
export { DISTILLER_DEFAULT_MAX_INPUTS_PER_PRODUCT, LLM_DISTILLER_CONTRACT, LLM_DISTILLER_CONTRACT_DL2, LLM_DISTILLER_CONTRACT_DL3, LLM_DISTILLER_CONTRACTS, MEMORY_DISTILLER_CONTRACT_V1, contractGroupingDiff, driveConsolidationToFixpoint, isAliasModelId, llmPlanDistiller, mintLlmConsolidationPlan, openAiCompatChatSeat, parseJsonAnswer, planParseRepairs, sanitizeLlmGroups, scheduleUnderFuse, } from "./distiller.js";
|
|
12
|
+
export { DISTILLER_DEFAULT_MAX_INPUTS_PER_PRODUCT, LLM_DISTILLER_CONTRACT, LLM_DISTILLER_CONTRACT_DL2, LLM_DISTILLER_CONTRACT_DL3, LLM_DISTILLER_CONTRACTS, MEMORY_DISTILLER_CONTRACT_V1, contractGroupingDiff, driveConsolidationToFixpoint, isAliasModelId, llmPlanDistiller, mintExposurePartitionedPlan, mintLlmConsolidationPlan, openAiCompatChatSeat, parseJsonAnswer, planParseRepairs, sanitizeLlmGroups, scheduleUnderFuse, } from "./distiller.js";
|
|
13
13
|
export { CONSOLIDATION_DRIVER_PLANS_DIR, CONSOLIDATION_DRIVER_RUNS_FILE, archiveDistillerPlan, readConsolidationDriverRun, runMemoryConsolidationDriver, } from "./consolidation-driver.js";
|
|
14
14
|
export { MEMORY_ORIGIN_CAUSES } from "./types.js";
|
|
15
15
|
export { memoryBackendContract, assertMemoryBackendSearchEquivalence, } from "./memory-backend-contract.js";
|
|
@@ -1490,9 +1490,12 @@ export interface RunInternals {
|
|
|
1490
1490
|
* `TaskStream.detach(toolCallId)`; the hands Bash tool threads `signalFor(toolCallId)` into env.exec. */
|
|
1491
1491
|
detachHub?: import("../tool-detach.js").ToolDetachHub;
|
|
1492
1492
|
onTaskNotification?: (notification: TaskNotificationPayload,
|
|
1493
|
-
/**
|
|
1494
|
-
*
|
|
1495
|
-
* "
|
|
1493
|
+
/** Injection tier (design/373 — the ladder is LIVE): "next" = the running turn's next boundary
|
|
1494
|
+
* (arrival order, consecutive frames batch); "later" = the run's would-otherwise-stop seat
|
|
1495
|
+
* (never folded into work in progress); "now" = class-head + earliest natural boundary on this
|
|
1496
|
+
* lane (interrupt authority belongs to the steer face, never to notifications). Internal
|
|
1497
|
+
* producers declare their tier explicitly (§3.7 census — completion-class lanes are "next");
|
|
1498
|
+
* the parameterless default "later" serves the external verb's omitting callers only. */
|
|
1496
1499
|
opts?: {
|
|
1497
1500
|
priority?: import("../task-notification.js").SystemInjectionPriority;
|
|
1498
1501
|
}) => void;
|
|
@@ -50,7 +50,7 @@ import { RunnerSharedToolResultStore } from "../tool-result-store.js";
|
|
|
50
50
|
import { formatDiagnosticsBlock } from "../lsp-diagnostics.js";
|
|
51
51
|
import { checkToolPolicyProjection, constraintChainDigest, constraintChainEntryOf, isApprovalSettledBy, refuseOutOfContractDecision, screenApproverAttribution, toolPolicyNameSets } from "../tool-policy.js";
|
|
52
52
|
import { defaultTaskRegistry } from "../task-registry.js";
|
|
53
|
-
import { discloseDroppedPending, isDelegatedAgentTerminal, isSystemInjectionPriority, PendingSessionNotifications, renderTaskNotificationXml, SYSTEM_INJECTION_PRIORITIES, SystemInjectionQueue, taskNotificationDedupKey } from "../task-notification.js";
|
|
53
|
+
import { discloseDroppedPending, isDelegatedAgentTerminal, isSystemInjectionPriority, isTerminalTaskNotification, PendingSessionNotifications, renderTaskNotificationXml, SYSTEM_INJECTION_PRIORITIES, SystemInjectionQueue, taskNotificationDedupKey } from "../task-notification.js";
|
|
54
54
|
import { ToolDetachHub } from "../tool-detach.js";
|
|
55
55
|
import { createPeerInboundChainRef, createPeerSelfRef } from "../../agents/peer-admission.js";
|
|
56
56
|
import { workflowSizeGuidelineChangeNotice } from "../../orchestration/workflow-size-guideline.js";
|
|
@@ -78,6 +78,7 @@ function nextHumanInputSeq(key) {
|
|
|
78
78
|
function sameAcceptedSteerInput(a, b) {
|
|
79
79
|
return (a.payload === b.payload &&
|
|
80
80
|
a.trusted === b.trusted &&
|
|
81
|
+
a.priority === b.priority &&
|
|
81
82
|
a.actor?.id === b.actor?.id &&
|
|
82
83
|
a.actor?.hostAsserted === b.actor?.hostAsserted &&
|
|
83
84
|
a.actor?.issuer === b.actor?.issuer);
|
|
@@ -1829,6 +1830,11 @@ export class Runner {
|
|
|
1829
1830
|
throw steeringError(`inputId "${LEGACY_PENDING_STEER_INPUT_ID}" is reserved for a pre-queue parked steer and cannot be supplied by a caller`, "steering.invalid_content");
|
|
1830
1831
|
}
|
|
1831
1832
|
}
|
|
1833
|
+
const priorityIn = options?.priority;
|
|
1834
|
+
if (priorityIn !== undefined && !isSystemInjectionPriority(priorityIn)) {
|
|
1835
|
+
throw steeringError(`priority must be one of ${SYSTEM_INJECTION_PRIORITIES.join("/")} when supplied`, "steering.invalid_content");
|
|
1836
|
+
}
|
|
1837
|
+
const priority = priorityIn ?? "next";
|
|
1832
1838
|
const actorIn = options?.actor;
|
|
1833
1839
|
const actor = actorIn === undefined ? undefined : snapshotActorAssertion(actorIn);
|
|
1834
1840
|
const projected = projectHumanInput({ text, actor, source: "steer" });
|
|
@@ -1837,6 +1843,7 @@ export class Runner {
|
|
|
1837
1843
|
text,
|
|
1838
1844
|
trusted,
|
|
1839
1845
|
inputId: effectiveInputId,
|
|
1846
|
+
...(priorityIn !== undefined ? { priority } : {}),
|
|
1840
1847
|
...(actor !== undefined ? { actor } : {}),
|
|
1841
1848
|
};
|
|
1842
1849
|
let payload;
|
|
@@ -1872,7 +1879,7 @@ export class Runner {
|
|
|
1872
1879
|
throw steeringError("the task is not running");
|
|
1873
1880
|
payload = trusted ? formatHookFeedback(projected, h.reminderMark) : frameMidTurnUserInput(projected);
|
|
1874
1881
|
mintsAFrame = payload.trim().length !== 0;
|
|
1875
|
-
replay = { payload, trusted, ...(actor !== undefined ? { actor } : {}) };
|
|
1882
|
+
replay = { payload, trusted, priority, ...(actor !== undefined ? { actor } : {}) };
|
|
1876
1883
|
if (typeof inputId === "string") {
|
|
1877
1884
|
const prior = acceptedSteerInputs.get(inputId);
|
|
1878
1885
|
if (prior !== undefined) {
|
|
@@ -1885,9 +1892,32 @@ export class Runner {
|
|
|
1885
1892
|
return;
|
|
1886
1893
|
}
|
|
1887
1894
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1895
|
+
const injectFramed = async () => {
|
|
1896
|
+
const noteOptions = { provenance: "engine-note", callerAuthored: true, parkRecord, ...(actor !== undefined ? { actor } : {}) };
|
|
1897
|
+
if (priority === "later") {
|
|
1898
|
+
await h.harness.followUp(payload, noteOptions);
|
|
1899
|
+
noteAccepted(h);
|
|
1900
|
+
return;
|
|
1901
|
+
}
|
|
1902
|
+
const frame = await h.harness.steer(payload, { ...noteOptions, ...(priority === "now" ? { immediate: true } : {}) });
|
|
1890
1903
|
noteAccepted(h);
|
|
1904
|
+
if (priority === "now" && frame !== undefined && h.harness.interruptTurn(frame)) {
|
|
1905
|
+
deliverEngineNotice(this.deps.onNotice, {
|
|
1906
|
+
code: "task.turn_interrupted",
|
|
1907
|
+
message: "a caller-provenance steer with priority \"now\" interrupted the running turn: in-flight work was cut at " +
|
|
1908
|
+
"a manufactured boundary (finished tool calls keep their real results; never-started ones settle as " +
|
|
1909
|
+
"interrupted) and the run continues with the steer at the queue head.",
|
|
1910
|
+
detail: {
|
|
1911
|
+
inputId: effectiveInputId,
|
|
1912
|
+
sessionId: h.sessionId,
|
|
1913
|
+
...(actor?.id !== undefined ? { actorId: actor.id } : {}),
|
|
1914
|
+
...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}),
|
|
1915
|
+
},
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
};
|
|
1919
|
+
try {
|
|
1920
|
+
await injectFramed();
|
|
1891
1921
|
return;
|
|
1892
1922
|
}
|
|
1893
1923
|
catch (e) {
|
|
@@ -1897,8 +1927,7 @@ export class Runner {
|
|
|
1897
1927
|
const birthDeadline = Date.now() + READY_TIMEOUT_MS;
|
|
1898
1928
|
while (resultValue === undefined && !h.loop.ended && Date.now() < birthDeadline) {
|
|
1899
1929
|
try {
|
|
1900
|
-
await
|
|
1901
|
-
noteAccepted(h);
|
|
1930
|
+
await injectFramed();
|
|
1902
1931
|
return;
|
|
1903
1932
|
}
|
|
1904
1933
|
catch (e2) {
|
|
@@ -1938,9 +1967,14 @@ export class Runner {
|
|
|
1938
1967
|
if (input.source !== undefined && typeof input.source !== "string") {
|
|
1939
1968
|
throw notifyError("input.source must be a string when present", "notify.invalid_payload");
|
|
1940
1969
|
}
|
|
1941
|
-
|
|
1970
|
+
const priorityIn = opts?.priority;
|
|
1971
|
+
if (priorityIn !== undefined && !isSystemInjectionPriority(priorityIn)) {
|
|
1942
1972
|
throw notifyError(`opts.priority must be one of ${SYSTEM_INJECTION_PRIORITIES.join("/")} when present`, "notify.invalid_payload");
|
|
1943
1973
|
}
|
|
1974
|
+
const priority = priorityIn;
|
|
1975
|
+
if (priority === "now") {
|
|
1976
|
+
throw notifyError('priority "now" (turn interrupt) is not a notification-lane power — it belongs to the steer face; use "next" for earliest-boundary delivery', "notify.invalid_priority");
|
|
1977
|
+
}
|
|
1944
1978
|
const payload = {
|
|
1945
1979
|
task_id: input.task_id,
|
|
1946
1980
|
task_type: "external",
|
|
@@ -1954,7 +1988,7 @@ export class Runner {
|
|
|
1954
1988
|
if (!h || notifyRef.inject === undefined) {
|
|
1955
1989
|
throw notifyError("the task is not running", "notify.not_running");
|
|
1956
1990
|
}
|
|
1957
|
-
notifyRef.inject(payload,
|
|
1991
|
+
notifyRef.inject(payload, priority !== undefined ? { priority } : undefined);
|
|
1958
1992
|
},
|
|
1959
1993
|
compact: async (opts) => {
|
|
1960
1994
|
if (resultValue)
|
|
@@ -2050,7 +2084,7 @@ export class Runner {
|
|
|
2050
2084
|
let descendantAnchorDisclosed = false;
|
|
2051
2085
|
const parkTaskNotification = (payload, priority) => {
|
|
2052
2086
|
if (notificationSessionId !== undefined)
|
|
2053
|
-
this.pendingSessionNotifications.pend(notificationSessionId, payload);
|
|
2087
|
+
this.pendingSessionNotifications.pend(notificationSessionId, payload, priority);
|
|
2054
2088
|
if (!isDelegatedAgentTerminal(payload))
|
|
2055
2089
|
return;
|
|
2056
2090
|
const uplink = internals?.parentNotify;
|
|
@@ -2065,7 +2099,7 @@ export class Runner {
|
|
|
2065
2099
|
}
|
|
2066
2100
|
const rootAnchor = internals?.rootSessionId;
|
|
2067
2101
|
if (rootAnchor !== undefined && rootAnchor !== notificationSessionId) {
|
|
2068
|
-
this.pendingSessionNotifications.pend(rootAnchor, payload);
|
|
2102
|
+
this.pendingSessionNotifications.pend(rootAnchor, payload, priority);
|
|
2069
2103
|
return;
|
|
2070
2104
|
}
|
|
2071
2105
|
if (internals?.parentSessionId !== undefined && !descendantAnchorDisclosed) {
|
|
@@ -2074,10 +2108,17 @@ export class Runner {
|
|
|
2074
2108
|
}
|
|
2075
2109
|
};
|
|
2076
2110
|
const unsubscribeTaskNotifications = taskNotificationQueue.subscribe((item) => {
|
|
2077
|
-
queue.push({ type: "task_notification", notification: item.payload, ...notificationIdent() });
|
|
2111
|
+
queue.push({ type: "task_notification", notification: item.payload, priority: item.priority, ...notificationIdent() });
|
|
2078
2112
|
if (notificationHarness && prepared.batchHaltRef.current === undefined) {
|
|
2079
2113
|
const xml = renderTaskNotificationXml(item.payload);
|
|
2080
|
-
const
|
|
2114
|
+
const noteOptions = {
|
|
2115
|
+
provenance: "engine-note",
|
|
2116
|
+
enginePayload: item.payload,
|
|
2117
|
+
...(item.payload.task_type !== "external" && isTerminalTaskNotification(item.payload) ? { capPreferred: true } : {}),
|
|
2118
|
+
};
|
|
2119
|
+
const deliver = item.priority === "later"
|
|
2120
|
+
? notificationHarness.followUp(xml, noteOptions)
|
|
2121
|
+
: notificationHarness.steer(xml, { ...noteOptions, ...(item.priority === "now" ? { immediate: true } : {}) });
|
|
2081
2122
|
void deliver.then(() => item.onDisposition?.("queued"), () => {
|
|
2082
2123
|
parkTaskNotification(item.payload, item.priority);
|
|
2083
2124
|
item.onDisposition?.("parked");
|
|
@@ -2090,18 +2131,7 @@ export class Runner {
|
|
|
2090
2131
|
});
|
|
2091
2132
|
const upstreamTaskNotification = internals?.onTaskNotification;
|
|
2092
2133
|
const deliveredAtTurnOpen = new Set();
|
|
2093
|
-
let priorityNowDisclosed = false;
|
|
2094
2134
|
const injectTaskNotification = (notification, opts) => {
|
|
2095
|
-
if (opts?.priority === "now" && !priorityNowDisclosed) {
|
|
2096
|
-
priorityNowDisclosed = true;
|
|
2097
|
-
deliverEngineNotice(this.deps.onNotice, {
|
|
2098
|
-
code: "task.injection_priority_unimplemented",
|
|
2099
|
-
message: `a notification was injected with priority "now", which this engine does not implement: all injection ` +
|
|
2100
|
-
`priorities deliver at the NEXT turn boundary and none aborts the running turn. The notification is ` +
|
|
2101
|
-
`delivered — only the interrupting semantics are absent.`,
|
|
2102
|
-
detail: { priority: "now", ...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}), sessionId: prepared.sessionId },
|
|
2103
|
-
});
|
|
2104
|
-
}
|
|
2105
2135
|
if (deliveredAtTurnOpen.has(taskNotificationDedupKey(notification)))
|
|
2106
2136
|
return Promise.resolve("dropped_duplicate");
|
|
2107
2137
|
if (!notificationLaneLive) {
|
|
@@ -2196,16 +2226,17 @@ export class Runner {
|
|
|
2196
2226
|
const pendingIdle = this.pendingSessionNotifications.drain(prepared.sessionId);
|
|
2197
2227
|
if (pendingIdle !== undefined) {
|
|
2198
2228
|
for (const payload of discloseDroppedPending(pendingIdle)) {
|
|
2229
|
+
const parkedPriority = pendingIdle.priorities?.get(payload);
|
|
2199
2230
|
deliveredAtTurnOpen.add(taskNotificationDedupKey(payload));
|
|
2200
|
-
queue.push({ type: "task_notification", notification: payload, ...ident() });
|
|
2231
|
+
queue.push({ type: "task_notification", notification: payload, ...(parkedPriority !== undefined ? { priority: parkedPriority } : {}), ...ident() });
|
|
2201
2232
|
void prepared.harness.nextTurn(renderTaskNotificationXml(payload), { provenance: "engine-note", enginePayload: payload }).catch(() => {
|
|
2202
|
-
this.pendingSessionNotifications.pend(prepared.sessionId, payload);
|
|
2233
|
+
this.pendingSessionNotifications.pend(prepared.sessionId, payload, parkedPriority);
|
|
2203
2234
|
});
|
|
2204
2235
|
}
|
|
2205
2236
|
}
|
|
2206
2237
|
}
|
|
2207
2238
|
const loopLatch = { ended: false, userInterrupted: false };
|
|
2208
|
-
onReady({ harness: prepared.harness, abortController: prepared.abortController, loop: loopLatch, reminderMark: prepared.reminderMark });
|
|
2239
|
+
onReady({ harness: prepared.harness, abortController: prepared.abortController, loop: loopLatch, reminderMark: prepared.reminderMark, sessionId: prepared.sessionId });
|
|
2209
2240
|
const stats = { turns: 0, tokens: 0, toolCalls: 0, promptTokens: 0, totalInputTokens: 0, cachedTokens: 0, cacheWriteTokens: 0, cacheWriteTokensLong: 0, outputTokens: 0, costMicroUsd: 0 };
|
|
2210
2241
|
prepared.liveSpendRef.get = () => ({ costMicroUsd: stats.costMicroUsd, tokens: stats.tokens, turns: stats.turns, walltimeMs: Math.round(performance.now() - rs.telemetry.taskStartMonotonic) });
|
|
2211
2242
|
if (resume &&
|