@sema-agent/core 1.452.0 → 2.0.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/agents/agent-transcript-tool.d.ts +15 -0
- package/dist/agents/agent-transcript-tool.js +122 -0
- package/dist/agents/cascade.js +5 -8
- package/dist/agents/repair-loop.d.ts +1 -1
- package/dist/agents/repair-loop.js +1 -1
- package/dist/agents/retain-ledger.d.ts +60 -0
- package/dist/agents/retain-ledger.js +225 -0
- package/dist/agents/roster-store.d.ts +1 -0
- package/dist/agents/roster-store.js +9 -0
- package/dist/agents/send-message-tool.d.ts +41 -0
- package/dist/agents/send-message-tool.js +469 -0
- package/dist/agents/subagent.d.ts +33 -108
- package/dist/agents/subagent.js +22 -834
- package/dist/agents/teacher.d.ts +0 -1
- package/dist/agents/teacher.js +0 -9
- package/dist/bin/sema-tb.js +3 -3
- package/dist/brain/anthropic.js +15 -40
- package/dist/brain/openai.js +15 -40
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/stream-engine.js +2 -2
- package/dist/brain/stream-shared.d.ts +17 -0
- package/dist/brain/stream-shared.js +50 -0
- package/dist/brain/timeout.d.ts +1 -1
- package/dist/brain/timeout.js +1 -1
- package/dist/config/catalog.js +1 -3
- package/dist/config/defaults.d.ts +6 -0
- package/dist/config/defaults.js +6 -0
- package/dist/core/ask-question.d.ts +1 -1
- package/dist/core/background-shell.d.ts +1 -1
- package/dist/core/checkpoint-store.d.ts +0 -1
- package/dist/core/exec-gate.d.ts +1 -1
- package/dist/core/exec-output-tail.d.ts +1 -0
- package/dist/core/exec-output-tail.js +6 -0
- package/dist/core/file-snapshot-store.d.ts +1 -1
- package/dist/core/fs-write-gate-policy.d.ts +1 -1
- package/dist/core/git-worktree-env.d.ts +1 -1
- package/dist/core/hooks.d.ts +1 -1
- package/dist/core/image-downsample.d.ts +44 -0
- package/dist/core/image-downsample.js +97 -0
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/mcp.d.ts +3 -45
- package/dist/core/mcp.js +2 -97
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-recall.d.ts +0 -12
- package/dist/core/memory-recall.js +0 -222
- package/dist/core/memory.d.ts +0 -6
- package/dist/core/memory.js +0 -88
- package/dist/core/message-utils.d.ts +1 -1
- package/dist/core/oracle-isolation.d.ts +1 -1
- package/dist/core/remote-env.d.ts +1 -1
- package/dist/core/roles.d.ts +1 -1
- package/dist/core/runner/active-skill-scope.d.ts +1 -1
- package/dist/core/runner/assemble-result.d.ts +0 -2
- package/dist/core/runner/memory-consolidation.d.ts +1 -1
- package/dist/core/runner/prepare-memory.d.ts +16 -0
- package/dist/core/runner/prepare-memory.js +191 -0
- package/dist/core/runner/prepare-task.d.ts +4 -28
- package/dist/core/runner/prepare-task.js +19 -207
- package/dist/core/runner/prompt-suggestions.d.ts +1 -1
- package/dist/core/runner/runtask.d.ts +2 -3
- package/dist/core/runner/runtask.js +337 -529
- package/dist/core/runner/session-rule-policy.d.ts +1 -1
- package/dist/core/runner/synthetic-tools.d.ts +5 -5
- package/dist/core/runner/synthetic-tools.js +4 -4
- package/dist/core/runner/tool-disclosure.d.ts +3 -3
- package/dist/core/runner/tool-disclosure.js +2 -2
- package/dist/core/runner/tool-output-projection.d.ts +6 -0
- package/dist/core/runner/tool-output-projection.js +81 -0
- package/dist/core/runtime.d.ts +1 -1
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/session-reconcile.d.ts +1 -1
- package/dist/core/session-store.d.ts +2 -1
- package/dist/core/session-store.js +2 -1
- package/dist/core/session.d.ts +0 -1
- package/dist/core/task-registry-agent.d.ts +115 -0
- package/dist/core/task-registry-agent.js +1163 -0
- package/dist/core/task-registry-monitor.d.ts +13 -0
- package/dist/core/task-registry-monitor.js +347 -0
- package/dist/core/task-registry-shared.d.ts +294 -0
- package/dist/core/task-registry-shared.js +271 -0
- package/dist/core/task-registry-workflow.d.ts +5 -0
- package/dist/core/task-registry-workflow.js +143 -0
- package/dist/core/task-registry.d.ts +51 -216
- package/dist/core/task-registry.js +127 -1940
- package/dist/core/task-tool-shape.d.ts +32 -0
- package/dist/core/task-tool-shape.js +83 -0
- package/dist/core/tool-policy.d.ts +1 -2
- package/dist/core/tool-result-budget.d.ts +1 -1
- package/dist/core/tool-result-store.d.ts +2 -2
- package/dist/core/tool-result-store.js +1 -1
- package/dist/core/tools.d.ts +2 -3
- package/dist/core/tools.js +0 -8
- package/dist/core/trace.d.ts +2 -2
- package/dist/core/types.d.ts +0 -29
- package/dist/core/workflow-run-store-contract.d.ts +1 -1
- package/dist/core/workflow-run-store-contract.js +19 -19
- package/dist/engine/execution-env/node-execution-env.d.ts +13 -0
- package/dist/engine/execution-env/node-execution-env.js +55 -25
- package/dist/engine/lsp/frame-decoder.d.ts +1 -1
- package/dist/engine/lsp/frame-decoder.js +1 -1
- package/dist/engine/lsp/node-lsp-manager.d.ts +1 -1
- package/dist/engine/lsp/stdio-lsp-transport.js +2 -2
- package/dist/index.d.ts +16 -14
- package/dist/index.js +13 -11
- package/dist/internal/harness-types.d.ts +7 -0
- package/dist/internal/harness-types.js +1 -0
- package/dist/internal/harness.d.ts +1 -7
- package/dist/internal/harness.js +1 -0
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +1 -1
- package/dist/orchestration/workflow-types.d.ts +193 -0
- package/dist/orchestration/workflow-types.js +54 -0
- package/dist/orchestration/workflow.d.ts +3 -193
- package/dist/orchestration/workflow.js +7 -59
- package/dist/prompt-assembly/assemble.d.ts +3 -3
- package/dist/prompt-assembly/assemble.js +0 -16
- package/dist/prompt-assembly/explain.d.ts +1 -1
- package/dist/prompt-assembly/tool-catalog.d.ts +1 -1
- package/dist/prompts/default.d.ts +1 -6
- package/dist/prompts/default.js +3 -11
- package/dist/scenarios/env.d.ts +1 -1
- package/dist/scenarios/full-body.d.ts +0 -3
- package/dist/scenarios/full-body.js +0 -2
- package/dist/stores/file/background-agent-store.d.ts +2 -15
- package/dist/stores/file/background-agent-store.js +30 -100
- package/dist/stores/file/checkpoint-store.d.ts +1 -14
- package/dist/stores/file/checkpoint-store.js +47 -119
- package/dist/stores/file/file-snapshot-store.d.ts +1 -1
- package/dist/stores/file/shared-ledger.d.ts +35 -0
- package/dist/stores/file/shared-ledger.js +94 -0
- package/dist/stores/file/workflow-run-store.d.ts +1 -14
- package/dist/stores/file/workflow-run-store.js +24 -93
- package/dist/tools/fs/bash-readonly-classifier.d.ts +8 -0
- package/dist/tools/fs/bash-readonly-classifier.js +166 -0
- package/dist/tools/fs/fs-bash.d.ts +31 -0
- package/dist/tools/fs/fs-bash.js +672 -0
- package/dist/tools/fs/fs-pdf.d.ts +22 -0
- package/dist/tools/fs/fs-pdf.js +236 -0
- package/dist/tools/fs/fs-read.d.ts +8 -0
- package/dist/tools/fs/fs-read.js +286 -0
- package/dist/tools/fs/fs-search-tools.d.ts +5 -0
- package/dist/tools/fs/fs-search-tools.js +173 -0
- package/dist/tools/fs/fs-shared.d.ts +55 -0
- package/dist/tools/fs/fs-shared.js +144 -0
- package/dist/tools/fs/fs-write.d.ts +8 -0
- package/dist/tools/fs/fs-write.js +423 -0
- package/dist/tools/fs/index.d.ts +12 -65
- package/dist/tools/fs/index.js +26 -2090
- package/dist/tools/fs/pdf.d.ts +1 -1
- package/dist/tools/fs/repo-map.d.ts +3 -3
- package/dist/tools/fs/repo-map.js +1 -1
- package/dist/tools/fs/safety.d.ts +1 -1
- package/dist/tools/fs/search.d.ts +1 -1
- package/dist/tools/monitor.d.ts +1 -1
- package/dist/tools/scheduler-tools.d.ts +1 -1
- package/dist/tools/web.d.ts +2 -2
- package/dist/tools/web.js +1 -1
- package/dist/tools/worktree.d.ts +1 -1
- package/package.json +1 -1
- package/dist/core/dynamic-recall.d.ts +0 -32
- package/dist/core/dynamic-recall.js +0 -76
|
@@ -18,8 +18,6 @@ import { runWithBrainTelemetry, runWithStatusSink } from "../../brain/status-sin
|
|
|
18
18
|
import { expandTiers, resolveModel, resolveTaskModel } from "../roles.js";
|
|
19
19
|
import { runSideQuery } from "../side-query.js";
|
|
20
20
|
import { generatePromptSuggestions } from "./prompt-suggestions.js";
|
|
21
|
-
import { runMemoryConsolidation } from "./memory-consolidation.js";
|
|
22
|
-
import { advanceCursorAfterInline } from "../consolidate-scope.js";
|
|
23
21
|
import { PushQueue } from "../push-queue.js";
|
|
24
22
|
import { TtlSessionStore } from "../session-store.js";
|
|
25
23
|
import { toImageContent } from "./image.js";
|
|
@@ -41,16 +39,24 @@ import { toolPolicyNameSets } from "../tool-policy.js";
|
|
|
41
39
|
import { defaultTaskRegistry } from "../task-registry.js";
|
|
42
40
|
import { discloseDroppedPending, PendingSessionNotifications, renderTaskNotificationXml, SystemInjectionQueue, taskNotificationDedupKey } from "../task-notification.js";
|
|
43
41
|
import { ToolDetachHub } from "../tool-detach.js";
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
import { DEFAULT_MAX_TURNS } from "../../config/defaults.js";
|
|
43
|
+
import { structuredFrom, toolOutputFrom } from "./tool-output-projection.js";
|
|
44
|
+
export { DEFAULT_MAX_TURNS };
|
|
45
|
+
function createRunState() {
|
|
46
|
+
return {
|
|
47
|
+
telemetry: { cacheFamily: "input-excludes-cached", pricing: { inputPer1M: 0, outputPer1M: 0 }, tracer: undefined, taskId: "", taskStart: 0, taskStartMonotonic: 0, cacheBreakReported: false },
|
|
48
|
+
degrade: { degradeToModel: undefined, degraded: undefined, outputErrorStreak: 0, outputInvalid: false, recordDegraded: () => { } },
|
|
49
|
+
limits: { turnsExceeded: false, budgetHit: undefined, outputRetryCap: 0, effectiveMaxTurns: undefined },
|
|
50
|
+
budget: { remainingMicroUsd: undefined, maxCostMicroUsd: undefined, overBudget: () => false, streamCancel: false, callOutputChars: 0, lastStreamBudgetCheck: 0, projectedOverBudget: () => false },
|
|
51
|
+
turn: { callStartAt: undefined, firstTokenAt: undefined, turnUsage: undefined, turnUsageMissing: false, turnStopReason: undefined, lastTurnHadToolCalls: false },
|
|
52
|
+
counters: { nudgesSent: 0, callCutoffs: 0, repetitionCuts: 0, repetitionSpared: 0, repetitionEvents: [], REPETITION_EVENTS_CAP: 0, preemptIgnoredReported: false, wroteThisRun: false, finalVerifyInjections: 0, groundingSignalPreR9: false, groundingSignalPostR9: false, cadenceTurns: 0 },
|
|
53
|
+
attach: { attachmentsCfg: undefined, agentListingOn: false, skillsListingOn: false, attachState: undefined, dateState: undefined, instrProbe: undefined, instrState: undefined },
|
|
54
|
+
};
|
|
55
|
+
}
|
|
49
56
|
const MAX_CONSECUTIVE_COMPACTION_FAILURES = 3;
|
|
50
57
|
const STOP_HOOK_BLOCK_CAP = 8;
|
|
51
58
|
const COMPACTION_REGROWTH_FACTOR = 1.5;
|
|
52
59
|
const COMPACTION_FREED_EPSILON = 256;
|
|
53
|
-
const MAX_TOOL_END_OUTPUT_CHARS = 16384;
|
|
54
60
|
const BATCH_RESPONSE_MAX_CHARS = 500;
|
|
55
61
|
function batchResponseDigest(result) {
|
|
56
62
|
const content = result !== null && typeof result === "object" ? result.content : result;
|
|
@@ -220,9 +226,7 @@ export class Runner {
|
|
|
220
226
|
parentConstraintRegistry = new Map();
|
|
221
227
|
static PARENT_CONSTRAINT_REGISTRY_CAP = 1024;
|
|
222
228
|
constructor(deps) {
|
|
223
|
-
this.deps = deps
|
|
224
|
-
? { ...deps, memoryStore: guardedMemoryStore(deps.memoryStore, deps.utilityGate) }
|
|
225
|
-
: deps;
|
|
229
|
+
this.deps = deps;
|
|
226
230
|
if (this.deps.tiers) {
|
|
227
231
|
this.deps = { ...this.deps, models: expandTiers(this.deps.models, this.deps.tiers) };
|
|
228
232
|
}
|
|
@@ -333,7 +337,6 @@ export class Runner {
|
|
|
333
337
|
const queue = new PushQueue();
|
|
334
338
|
const detachHub = new ToolDetachHub();
|
|
335
339
|
let resultValue;
|
|
336
|
-
let consolidationDone = Promise.resolve();
|
|
337
340
|
let suggestionsDone = Promise.resolve([]);
|
|
338
341
|
let handle;
|
|
339
342
|
let publishReady;
|
|
@@ -378,8 +381,6 @@ export class Runner {
|
|
|
378
381
|
}
|
|
379
382
|
this.parentConstraintRegistry.set(r.checkpointToken, pcs);
|
|
380
383
|
}
|
|
381
|
-
}, (p) => {
|
|
382
|
-
consolidationDone = p;
|
|
383
384
|
}, (p) => {
|
|
384
385
|
suggestionsDone = p;
|
|
385
386
|
}, (h) => {
|
|
@@ -440,7 +441,7 @@ export class Runner {
|
|
|
440
441
|
result: "",
|
|
441
442
|
errorMessage: err instanceof Error ? err.message : String(err),
|
|
442
443
|
errorCode: code,
|
|
443
|
-
stats: { turns: 0, tokens: 0, toolCalls: 0, cachedTokens: 0,
|
|
444
|
+
stats: { turns: 0, tokens: 0, toolCalls: 0, cachedTokens: 0, costMicroUsd: 0 },
|
|
444
445
|
};
|
|
445
446
|
emitTrace(spec.tracer ?? this.deps.tracer, () => ({
|
|
446
447
|
kind: "task.end",
|
|
@@ -499,10 +500,6 @@ export class Runner {
|
|
|
499
500
|
await settled;
|
|
500
501
|
return resultValue;
|
|
501
502
|
},
|
|
502
|
-
consolidation: async () => {
|
|
503
|
-
await run.catch(() => { });
|
|
504
|
-
await consolidationDone.catch(() => { });
|
|
505
|
-
},
|
|
506
503
|
suggestions: async () => {
|
|
507
504
|
await run.catch(() => { });
|
|
508
505
|
return suggestionsDone.catch(() => []);
|
|
@@ -626,7 +623,7 @@ export class Runner {
|
|
|
626
623
|
})()),
|
|
627
624
|
};
|
|
628
625
|
}
|
|
629
|
-
async runLocked(spec, queue, setResult,
|
|
626
|
+
async runLocked(spec, queue, setResult, onSuggestions, onReady, onSuspend, manualCompactRef, taskIdRef, resume, internals, notifyRef) {
|
|
630
627
|
const prepareResume = resume
|
|
631
628
|
? {
|
|
632
629
|
leafId: resume.cp.leafId,
|
|
@@ -641,9 +638,6 @@ export class Runner {
|
|
|
641
638
|
resume.outcome.decision === "allow",
|
|
642
639
|
}
|
|
643
640
|
: undefined;
|
|
644
|
-
const memorySelector = this.deps.memoryRecall?.enabled || this.deps.dynamicRecall?.enabled
|
|
645
|
-
? (this.deps.memoryRecall?.select ?? createBrainMemorySelector(this, { model: this.deps.memoryRecall?.selectorModel, release: (id) => releaseSession(this, id) }))
|
|
646
|
-
: undefined;
|
|
647
641
|
const taskNotificationQueue = new SystemInjectionQueue();
|
|
648
642
|
const detachHub = internals?.detachHub ?? new ToolDetachHub();
|
|
649
643
|
let notificationHarness;
|
|
@@ -691,7 +685,7 @@ export class Runner {
|
|
|
691
685
|
resolve("queued");
|
|
692
686
|
});
|
|
693
687
|
};
|
|
694
|
-
const prepared = await prepareTask(spec, this.deps, this.sessions, prepareResume,
|
|
688
|
+
const prepared = await prepareTask(spec, this.deps, this.sessions, prepareResume, {
|
|
695
689
|
...(internals ?? {}),
|
|
696
690
|
detachHub,
|
|
697
691
|
onTaskNotification: (notification, opts) => {
|
|
@@ -731,8 +725,8 @@ export class Runner {
|
|
|
731
725
|
}
|
|
732
726
|
}
|
|
733
727
|
onReady({ harness: prepared.harness, abortController: prepared.abortController });
|
|
734
|
-
const stats = { turns: 0, tokens: 0, toolCalls: 0, promptTokens: 0, cachedTokens: 0, cacheWriteTokens: 0, cacheWriteTokensLong: 0, outputTokens: 0,
|
|
735
|
-
prepared.liveSpendRef.get = () => ({ costMicroUsd: stats.costMicroUsd, tokens: stats.tokens, turns: stats.turns, walltimeMs: Math.round(performance.now() - taskStartMonotonic) });
|
|
728
|
+
const stats = { turns: 0, tokens: 0, toolCalls: 0, promptTokens: 0, cachedTokens: 0, cacheWriteTokens: 0, cacheWriteTokensLong: 0, outputTokens: 0, costMicroUsd: 0 };
|
|
729
|
+
prepared.liveSpendRef.get = () => ({ costMicroUsd: stats.costMicroUsd, tokens: stats.tokens, turns: stats.turns, walltimeMs: Math.round(performance.now() - rs.telemetry.taskStartMonotonic) });
|
|
736
730
|
if (resume &&
|
|
737
731
|
resume.cp.suspendedAt !== undefined &&
|
|
738
732
|
(resume.cp.gate.kind === "human" ||
|
|
@@ -746,12 +740,12 @@ export class Runner {
|
|
|
746
740
|
const gateToolName = "toolName" in resume.cp.gate ? resume.cp.gate.toolName : undefined;
|
|
747
741
|
prepared.humanReviewRef.gates.push({ kind: resume.cp.gate.kind, waitMs, ...(decision !== undefined ? { decision } : {}), ...(gateToolName !== undefined ? { toolName: gateToolName } : {}) });
|
|
748
742
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
743
|
+
const rs = createRunState();
|
|
744
|
+
rs.telemetry.cacheFamily = cacheFamilyOf(prepared.model);
|
|
745
|
+
rs.telemetry.pricing = this.deps.pricing?.[prepared.model.id] ?? modelCostToPricing(prepared.model.cost);
|
|
752
746
|
if (spec.degrade) {
|
|
753
747
|
try {
|
|
754
|
-
degradeToModel = resolveModel(spec.degrade.to, this.deps.models);
|
|
748
|
+
rs.degrade.degradeToModel = resolveModel(spec.degrade.to, this.deps.models);
|
|
755
749
|
}
|
|
756
750
|
catch (e) {
|
|
757
751
|
this.deps.onError?.(e, { phase: "degraded", sessionId: prepared.sessionId });
|
|
@@ -761,25 +755,23 @@ export class Runner {
|
|
|
761
755
|
if (famOverride && !["input-includes-cached", "input-excludes-cached", "openai", "anthropic"].includes(famOverride)) {
|
|
762
756
|
this.deps.onError?.(new Error(`prompt-cache: unrecognized model.params.promptCacheFamily "${famOverride}" — ignored (fell back to model.api inference). Use "input-includes-cached" | "input-excludes-cached" (aliases "openai" | "anthropic").`), { phase: "prompt-cache", sessionId: prepared.sessionId });
|
|
763
757
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
const tracer = spec.tracer ?? this.deps.tracer;
|
|
773
|
-
const taskId = spec.taskId ?? prepared.sessionId;
|
|
758
|
+
rs.limits.turnsExceeded = false;
|
|
759
|
+
rs.degrade.outputErrorStreak = 0;
|
|
760
|
+
rs.degrade.outputInvalid = false;
|
|
761
|
+
rs.telemetry.cacheBreakReported = false;
|
|
762
|
+
rs.limits.outputRetryCap = resolveOutputRetries(spec.outputRetries);
|
|
763
|
+
rs.limits.effectiveMaxTurns = resolveMaxTurns(spec.limits);
|
|
764
|
+
rs.telemetry.tracer = spec.tracer ?? this.deps.tracer;
|
|
765
|
+
rs.telemetry.taskId = spec.taskId ?? prepared.sessionId;
|
|
774
766
|
if (taskIdRef) {
|
|
775
|
-
taskIdRef.current = taskId;
|
|
767
|
+
taskIdRef.current = rs.telemetry.taskId;
|
|
776
768
|
taskIdRef.sessionId = prepared.sessionId;
|
|
777
769
|
}
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
void Promise.resolve(this.sessions.noteTaskRun?.(prepared.sessionId, taskId)).catch(() => { });
|
|
781
|
-
|
|
782
|
-
if (degraded !== undefined)
|
|
770
|
+
rs.telemetry.taskStart = Date.now();
|
|
771
|
+
rs.telemetry.taskStartMonotonic = performance.now();
|
|
772
|
+
void Promise.resolve(this.sessions.noteTaskRun?.(prepared.sessionId, rs.telemetry.taskId)).catch(() => { });
|
|
773
|
+
rs.degrade.recordDegraded = (info, toModel) => {
|
|
774
|
+
if (rs.degrade.degraded !== undefined)
|
|
783
775
|
return;
|
|
784
776
|
let m = toModel;
|
|
785
777
|
if (!m) {
|
|
@@ -791,16 +783,16 @@ export class Runner {
|
|
|
791
783
|
}
|
|
792
784
|
}
|
|
793
785
|
if (m) {
|
|
794
|
-
pricing = this.deps.pricing?.[m.id] ?? modelCostToPricing(m.cost);
|
|
795
|
-
cacheFamily = cacheFamilyOf(m);
|
|
786
|
+
rs.telemetry.pricing = this.deps.pricing?.[m.id] ?? modelCostToPricing(m.cost);
|
|
787
|
+
rs.telemetry.cacheFamily = cacheFamilyOf(m);
|
|
796
788
|
}
|
|
797
789
|
else {
|
|
798
790
|
if (this.deps.pricing?.[info.to])
|
|
799
|
-
pricing = this.deps.pricing[info.to];
|
|
800
|
-
cacheFamily = "input-excludes-cached";
|
|
791
|
+
rs.telemetry.pricing = this.deps.pricing[info.to];
|
|
792
|
+
rs.telemetry.cacheFamily = "input-excludes-cached";
|
|
801
793
|
}
|
|
802
|
-
degraded = info;
|
|
803
|
-
emitTrace(tracer, () => ({ kind: "task.degraded", version: 1, taskId, from: info.from, to: info.to, reason: info.reason, atTurn: info.atTurn, ts: Date.now() }));
|
|
794
|
+
rs.degrade.degraded = info;
|
|
795
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "task.degraded", version: 1, taskId: rs.telemetry.taskId, from: info.from, to: info.to, reason: info.reason, atTurn: info.atTurn, ts: Date.now() }));
|
|
804
796
|
try {
|
|
805
797
|
this.deps.onError?.(new Error(`degraded to a cheaper model: ${info.from} → ${info.to} (${info.reason}) at turn ${info.atTurn}`), { phase: "degraded", sessionId: prepared.sessionId });
|
|
806
798
|
}
|
|
@@ -808,63 +800,62 @@ export class Runner {
|
|
|
808
800
|
}
|
|
809
801
|
};
|
|
810
802
|
const sliceWindowMicroUsd = spec.maxCostUsd !== undefined ? Math.round(spec.maxCostUsd * 1e6) : undefined;
|
|
811
|
-
|
|
803
|
+
rs.budget.remainingMicroUsd = prepared.resourceLedger
|
|
812
804
|
? remainingBudgetMicroUsd(prepared.resourceLedger)
|
|
813
805
|
: spec.resourceSuspend?.totalBudgetUsd !== undefined
|
|
814
806
|
? Math.round(spec.resourceSuspend.totalBudgetUsd * 1e6)
|
|
815
807
|
: undefined;
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
808
|
+
rs.budget.maxCostMicroUsd =
|
|
809
|
+
sliceWindowMicroUsd !== undefined && rs.budget.remainingMicroUsd !== undefined
|
|
810
|
+
? Math.min(sliceWindowMicroUsd, rs.budget.remainingMicroUsd)
|
|
811
|
+
: (sliceWindowMicroUsd ?? rs.budget.remainingMicroUsd);
|
|
812
|
+
rs.budget.overBudget = () => (rs.budget.maxCostMicroUsd !== undefined && stats.costMicroUsd > rs.budget.maxCostMicroUsd) ||
|
|
820
813
|
(spec.maxTokens !== undefined && stats.tokens > spec.maxTokens);
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
814
|
+
rs.budget.streamCancel =
|
|
815
|
+
(spec.budgetStreamCancel ?? rs.budget.maxCostMicroUsd !== undefined) && prepared.suspendForResource === undefined;
|
|
816
|
+
rs.budget.callOutputChars = 0;
|
|
817
|
+
rs.budget.lastStreamBudgetCheck = 0;
|
|
818
|
+
rs.budget.projectedOverBudget = () => {
|
|
819
|
+
const estOut = Math.ceil(rs.budget.callOutputChars / 4);
|
|
820
|
+
if (rs.budget.maxCostMicroUsd !== undefined) {
|
|
821
|
+
const estOutMicro = computeCostMicroUsd({ totalInputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, cacheWriteTokensLong: 0, outputTokens: estOut }, rs.telemetry.pricing);
|
|
822
|
+
if (stats.costMicroUsd + estOutMicro > rs.budget.maxCostMicroUsd)
|
|
829
823
|
return true;
|
|
830
824
|
}
|
|
831
825
|
return spec.maxTokens !== undefined && stats.tokens + estOut > spec.maxTokens;
|
|
832
826
|
};
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
let cadenceTurns = 0;
|
|
860
|
-
let lastTurnHadToolCalls = false;
|
|
861
|
-
if (attachState !== undefined && attachmentsCfg?.backgroundTasks === true) {
|
|
827
|
+
rs.turn.turnUsageMissing = false;
|
|
828
|
+
rs.counters.nudgesSent = 0;
|
|
829
|
+
rs.counters.callCutoffs = 0;
|
|
830
|
+
rs.counters.repetitionCuts = 0;
|
|
831
|
+
rs.counters.repetitionSpared = 0;
|
|
832
|
+
rs.counters.repetitionEvents = [];
|
|
833
|
+
rs.counters.REPETITION_EVENTS_CAP = 20;
|
|
834
|
+
rs.counters.preemptIgnoredReported = false;
|
|
835
|
+
rs.counters.wroteThisRun = false;
|
|
836
|
+
rs.counters.finalVerifyInjections = 0;
|
|
837
|
+
rs.counters.groundingSignalPreR9 = false;
|
|
838
|
+
rs.counters.groundingSignalPostR9 = false;
|
|
839
|
+
rs.attach.attachmentsCfg = spec.attachments;
|
|
840
|
+
rs.attach.agentListingOn = rs.attach.attachmentsCfg?.agentListing !== false && eventDefaultOn("agent_listing");
|
|
841
|
+
rs.attach.skillsListingOn = rs.attach.attachmentsCfg?.skillsListing !== false && eventDefaultOn("skills_listing");
|
|
842
|
+
const listingsLive = (rs.attach.agentListingOn && prepared.agentListing !== undefined) || (rs.attach.skillsListingOn && prepared.skillsListing !== undefined);
|
|
843
|
+
rs.attach.attachState = rs.attach.attachmentsCfg !== undefined || listingsLive ? createAttachmentState() : undefined;
|
|
844
|
+
rs.attach.dateState = prepared.dateChange !== undefined ? { announcedDate: prepared.dateChange.legDate } : undefined;
|
|
845
|
+
rs.attach.instrProbe = this.deps.probeInstructionSources;
|
|
846
|
+
rs.attach.instrState =
|
|
847
|
+
rs.attach.instrProbe !== undefined && prepared.instructionSources !== undefined && prepared.instructionSources.length > 0
|
|
848
|
+
? { lastAnnouncedHash: new Map(prepared.instructionSources.map((s) => [s.path, s.contentHash])) }
|
|
849
|
+
: undefined;
|
|
850
|
+
rs.counters.cadenceTurns = 0;
|
|
851
|
+
rs.turn.lastTurnHadToolCalls = false;
|
|
852
|
+
if (rs.attach.attachState !== undefined && rs.attach.attachmentsCfg?.backgroundTasks === true) {
|
|
862
853
|
try {
|
|
863
854
|
const branch = await prepared.session.getBranch();
|
|
864
855
|
for (let i = branch.length - 1; i >= 0; i--) {
|
|
865
856
|
const e = branch[i];
|
|
866
857
|
if (e.type === "compaction") {
|
|
867
|
-
attachState.postCompactPending = true;
|
|
858
|
+
rs.attach.attachState.postCompactPending = true;
|
|
868
859
|
break;
|
|
869
860
|
}
|
|
870
861
|
if (e.type === "message" && e.message.role === "assistant")
|
|
@@ -874,9 +865,9 @@ export class Runner {
|
|
|
874
865
|
catch {
|
|
875
866
|
}
|
|
876
867
|
}
|
|
877
|
-
if (attachState !== undefined &&
|
|
878
|
-
((agentListingOn && prepared.agentListing?.seedAnnounced === true) ||
|
|
879
|
-
(skillsListingOn && prepared.skillsListing?.seedAnnounced === true))) {
|
|
868
|
+
if (rs.attach.attachState !== undefined &&
|
|
869
|
+
((rs.attach.agentListingOn && prepared.agentListing?.seedAnnounced === true) ||
|
|
870
|
+
(rs.attach.skillsListingOn && prepared.skillsListing?.seedAnnounced === true))) {
|
|
880
871
|
const cpListings = resume?.cp.state.announcedListings;
|
|
881
872
|
let entryListings;
|
|
882
873
|
try {
|
|
@@ -927,23 +918,23 @@ export class Runner {
|
|
|
927
918
|
return undefined;
|
|
928
919
|
}
|
|
929
920
|
};
|
|
930
|
-
if (agentListingOn && prepared.agentListing?.seedAnnounced === true) {
|
|
921
|
+
if (rs.attach.agentListingOn && prepared.agentListing?.seedAnnounced === true) {
|
|
931
922
|
const listing = prepared.agentListing;
|
|
932
923
|
if (cpListings?.agents === undefined && entryListings?.agents !== undefined) {
|
|
933
924
|
const descOf = new Map(listing.entries.map((e) => [e.name, e.description]));
|
|
934
|
-
attachState.announcedAgentTypes = new Map(entryListings.agents.map((n) => [n, descOf.get(n) ?? ""]));
|
|
925
|
+
rs.attach.attachState.announcedAgentTypes = new Map(entryListings.agents.map((n) => [n, descOf.get(n) ?? ""]));
|
|
935
926
|
prepared.announcedListingsRef.agents = [...entryListings.agents];
|
|
936
927
|
if (entryListings.models !== undefined) {
|
|
937
|
-
attachState.announcedModels = [...entryListings.models];
|
|
928
|
+
rs.attach.attachState.announcedModels = [...entryListings.models];
|
|
938
929
|
prepared.announcedListingsRef.models = [...entryListings.models];
|
|
939
930
|
}
|
|
940
931
|
}
|
|
941
932
|
else if (cpListings?.agents !== undefined) {
|
|
942
933
|
const descOf = new Map(listing.entries.map((e) => [e.name, e.description]));
|
|
943
|
-
attachState.announcedAgentTypes = new Map(cpListings.agents.map((n) => [n, descOf.get(n) ?? ""]));
|
|
934
|
+
rs.attach.attachState.announcedAgentTypes = new Map(cpListings.agents.map((n) => [n, descOf.get(n) ?? ""]));
|
|
944
935
|
prepared.announcedListingsRef.agents = [...cpListings.agents];
|
|
945
936
|
if (cpListings.models !== undefined) {
|
|
946
|
-
attachState.announcedModels = [...cpListings.models];
|
|
937
|
+
rs.attach.attachState.announcedModels = [...cpListings.models];
|
|
947
938
|
prepared.announcedListingsRef.models = [...cpListings.models];
|
|
948
939
|
}
|
|
949
940
|
}
|
|
@@ -955,26 +946,26 @@ export class Runner {
|
|
|
955
946
|
});
|
|
956
947
|
if (replayed !== undefined) {
|
|
957
948
|
const descOf = new Map(listing.entries.map((e) => [e.name, e.description]));
|
|
958
|
-
attachState.announcedAgentTypes = new Map([...replayed].map((n) => [n, descOf.get(n) ?? ""]));
|
|
949
|
+
rs.attach.attachState.announcedAgentTypes = new Map([...replayed].map((n) => [n, descOf.get(n) ?? ""]));
|
|
959
950
|
prepared.announcedListingsRef.agents = [...replayed];
|
|
960
951
|
const replayedModels = replayAnnouncedModels(await branchLoad());
|
|
961
952
|
if (replayedModels !== undefined) {
|
|
962
|
-
attachState.announcedModels = [...replayedModels];
|
|
953
|
+
rs.attach.attachState.announcedModels = [...replayedModels];
|
|
963
954
|
prepared.announcedListingsRef.models = [...replayedModels];
|
|
964
955
|
}
|
|
965
956
|
}
|
|
966
957
|
}
|
|
967
958
|
}
|
|
968
|
-
if (skillsListingOn && prepared.skillsListing?.seedAnnounced === true) {
|
|
959
|
+
if (rs.attach.skillsListingOn && prepared.skillsListing?.seedAnnounced === true) {
|
|
969
960
|
const listing = prepared.skillsListing;
|
|
970
961
|
if (cpListings?.skills === undefined && entryListings?.skills !== undefined) {
|
|
971
962
|
const descOf = new Map(listing.entries.map((e) => [e.name, e.description]));
|
|
972
|
-
attachState.announcedSkills = new Map(entryListings.skills.map((n) => [n, descOf.get(n) ?? ""]));
|
|
963
|
+
rs.attach.attachState.announcedSkills = new Map(entryListings.skills.map((n) => [n, descOf.get(n) ?? ""]));
|
|
973
964
|
prepared.announcedListingsRef.skills = [...entryListings.skills];
|
|
974
965
|
}
|
|
975
966
|
else if (cpListings?.skills !== undefined) {
|
|
976
967
|
const descOf = new Map(listing.entries.map((e) => [e.name, e.description]));
|
|
977
|
-
attachState.announcedSkills = new Map(cpListings.skills.map((n) => [n, descOf.get(n) ?? ""]));
|
|
968
|
+
rs.attach.attachState.announcedSkills = new Map(cpListings.skills.map((n) => [n, descOf.get(n) ?? ""]));
|
|
978
969
|
prepared.announcedListingsRef.skills = [...cpListings.skills];
|
|
979
970
|
}
|
|
980
971
|
else {
|
|
@@ -985,7 +976,7 @@ export class Runner {
|
|
|
985
976
|
});
|
|
986
977
|
if (replayed !== undefined) {
|
|
987
978
|
const descOf = new Map(listing.entries.map((e) => [e.name, e.description]));
|
|
988
|
-
attachState.announcedSkills = new Map([...replayed].map((n) => [n, descOf.get(n) ?? ""]));
|
|
979
|
+
rs.attach.attachState.announcedSkills = new Map([...replayed].map((n) => [n, descOf.get(n) ?? ""]));
|
|
989
980
|
prepared.announcedListingsRef.skills = [...replayed];
|
|
990
981
|
}
|
|
991
982
|
}
|
|
@@ -1002,11 +993,11 @@ export class Runner {
|
|
|
1002
993
|
const text = typeof m.content === "string"
|
|
1003
994
|
? m.content
|
|
1004
995
|
: m.content.map((b) => (b !== null && typeof b === "object" && b.type === "text" ? String(b.text ?? "") : "")).join("\n");
|
|
1005
|
-
if (text.includes("<system-reminder>[final verification]") && finalVerifyInjections < 2)
|
|
1006
|
-
finalVerifyInjections += 1;
|
|
996
|
+
if (text.includes("<system-reminder>[final verification]") && rs.counters.finalVerifyInjections < 2)
|
|
997
|
+
rs.counters.finalVerifyInjections += 1;
|
|
1007
998
|
}
|
|
1008
|
-
else if (m.role === "toolResult" && !wroteThisRun && (prepared.toolEffects.get(m.toolName) ?? "write") !== "read") {
|
|
1009
|
-
wroteThisRun = true;
|
|
999
|
+
else if (m.role === "toolResult" && !rs.counters.wroteThisRun && (prepared.toolEffects.get(m.toolName) ?? "write") !== "read") {
|
|
1000
|
+
rs.counters.wroteThisRun = true;
|
|
1010
1001
|
}
|
|
1011
1002
|
}
|
|
1012
1003
|
}
|
|
@@ -1014,10 +1005,10 @@ export class Runner {
|
|
|
1014
1005
|
}
|
|
1015
1006
|
}
|
|
1016
1007
|
let attachmentsInjected = 0;
|
|
1017
|
-
const todoToolMounted = attachState !== undefined && prepared.tools.some((t) => canonicalToolName(t.name) === "TodoWrite");
|
|
1018
|
-
const taskToolsMounted = attachState !== undefined && prepared.tools.some((t) => canonicalToolName(t.name) === "TaskCreate");
|
|
1008
|
+
const todoToolMounted = rs.attach.attachState !== undefined && prepared.tools.some((t) => canonicalToolName(t.name) === "TodoWrite");
|
|
1009
|
+
const taskToolsMounted = rs.attach.attachState !== undefined && prepared.tools.some((t) => canonicalToolName(t.name) === "TaskCreate");
|
|
1019
1010
|
const writeFamilyByName = new Map();
|
|
1020
|
-
if (attachState !== undefined) {
|
|
1011
|
+
if (rs.attach.attachState !== undefined) {
|
|
1021
1012
|
for (const t of prepared.tools) {
|
|
1022
1013
|
const family = writeFamilyOfCanonical(canonicalToolName(t.name));
|
|
1023
1014
|
if (family !== undefined)
|
|
@@ -1029,11 +1020,11 @@ export class Runner {
|
|
|
1029
1020
|
const toolStartAt = new Map();
|
|
1030
1021
|
const turnToolSpan = {};
|
|
1031
1022
|
const startedToolCallIds = new Set();
|
|
1032
|
-
emitTrace(tracer, () => ({ kind: "task.start", version: 1, taskId, model: prepared.model.id, engineVersion: engineVersion(), ts: taskStart }));
|
|
1033
|
-
emitTrace(tracer, () => ({
|
|
1023
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "task.start", version: 1, taskId: rs.telemetry.taskId, model: prepared.model.id, engineVersion: engineVersion(), ts: rs.telemetry.taskStart }));
|
|
1024
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
1034
1025
|
kind: "prompt.assembled",
|
|
1035
1026
|
version: 1,
|
|
1036
|
-
taskId,
|
|
1027
|
+
taskId: rs.telemetry.taskId,
|
|
1037
1028
|
constitution: prepared.promptManifest.constitution,
|
|
1038
1029
|
blocks: prepared.promptManifest.blocks,
|
|
1039
1030
|
...(prepared.promptManifest.sections ? { sections: prepared.promptManifest.sections } : {}),
|
|
@@ -1041,36 +1032,36 @@ export class Runner {
|
|
|
1041
1032
|
...(prepared.promptManifest.snapshot ? { snapshot: prepared.promptManifest.snapshot } : {}),
|
|
1042
1033
|
...(prepared.promptManifest.lowering ? { lowering: prepared.promptManifest.lowering } : {}),
|
|
1043
1034
|
totalChars: prepared.promptManifest.blocks.reduce((n, b) => n + b.chars, 0),
|
|
1044
|
-
ts: taskStart,
|
|
1035
|
+
ts: rs.telemetry.taskStart,
|
|
1045
1036
|
}));
|
|
1046
|
-
emitTrace(tracer, () => {
|
|
1037
|
+
emitTrace(rs.telemetry.tracer, () => {
|
|
1047
1038
|
const reasons = declarationReasons(spec.configOverrides);
|
|
1048
1039
|
return {
|
|
1049
1040
|
kind: "config.assembled",
|
|
1050
1041
|
version: 1,
|
|
1051
|
-
taskId,
|
|
1042
|
+
taskId: rs.telemetry.taskId,
|
|
1052
1043
|
catalogVersion: CONFIG_CATALOG_VERSION,
|
|
1053
1044
|
fields: resolveEffectiveConfig(spec, { modelMaxTokens: prepared.model.maxTokens }),
|
|
1054
1045
|
...(Object.keys(reasons).length > 0 ? { overrideReasons: reasons } : {}),
|
|
1055
|
-
ts: taskStart,
|
|
1046
|
+
ts: rs.telemetry.taskStart,
|
|
1056
1047
|
};
|
|
1057
1048
|
});
|
|
1058
1049
|
if (prepared.turnSnapshot !== undefined) {
|
|
1059
|
-
prepared.turnSnapshot.onChange = (snap) => emitTrace(tracer, () => ({
|
|
1050
|
+
prepared.turnSnapshot.onChange = (snap) => emitTrace(rs.telemetry.tracer, () => ({
|
|
1060
1051
|
kind: "prompt.snapshot_changed",
|
|
1061
1052
|
version: 1,
|
|
1062
|
-
taskId,
|
|
1053
|
+
taskId: rs.telemetry.taskId,
|
|
1063
1054
|
snapshot: { cacheIdentity: snap.cacheIdentity, elements: { ...snap.elements } },
|
|
1064
1055
|
ts: Date.now(),
|
|
1065
1056
|
}));
|
|
1066
1057
|
}
|
|
1067
1058
|
if (prepared.thinking && prepared.thinking !== "off" && prepared.model.reasoning === true) {
|
|
1068
|
-
emitTrace(tracer, () => {
|
|
1059
|
+
emitTrace(rs.telemetry.tracer, () => {
|
|
1069
1060
|
const r = resolveReasoning(prepared.thinking, prepared.model);
|
|
1070
1061
|
return {
|
|
1071
1062
|
kind: "reasoning.resolved",
|
|
1072
1063
|
version: 1,
|
|
1073
|
-
taskId,
|
|
1064
|
+
taskId: rs.telemetry.taskId,
|
|
1074
1065
|
model: prepared.model.id,
|
|
1075
1066
|
requested: r.requested,
|
|
1076
1067
|
effective: r.effective,
|
|
@@ -1091,8 +1082,8 @@ export class Runner {
|
|
|
1091
1082
|
const effectiveTimeoutMs = sliceWindowWalltimeMs !== undefined && remainingWalltimeBudgetMs !== undefined
|
|
1092
1083
|
? Math.min(sliceWindowWalltimeMs, remainingWalltimeBudgetMs)
|
|
1093
1084
|
: (sliceWindowWalltimeMs ?? remainingWalltimeBudgetMs);
|
|
1094
|
-
const walltimeDeadlineMs = effectiveTimeoutMs !== undefined ? taskStart + effectiveTimeoutMs : undefined;
|
|
1095
|
-
const walltimeMonotonicDeadline = effectiveTimeoutMs !== undefined ? taskStartMonotonic + effectiveTimeoutMs : undefined;
|
|
1085
|
+
const walltimeDeadlineMs = effectiveTimeoutMs !== undefined ? rs.telemetry.taskStart + effectiveTimeoutMs : undefined;
|
|
1086
|
+
const walltimeMonotonicDeadline = effectiveTimeoutMs !== undefined ? rs.telemetry.taskStartMonotonic + effectiveTimeoutMs : undefined;
|
|
1096
1087
|
if (prepared.callCapRef && prepared.suspendForResource === undefined && walltimeDeadlineMs !== undefined) {
|
|
1097
1088
|
prepared.callCapRef.deadlineMs = walltimeDeadlineMs;
|
|
1098
1089
|
if (spec.limits?.gracefulFinalize !== false) {
|
|
@@ -1109,7 +1100,7 @@ export class Runner {
|
|
|
1109
1100
|
if (conf !== false && budgetSec && budgetSec > 0) {
|
|
1110
1101
|
const [a, b] = conf?.at ?? [0.8, 0.95];
|
|
1111
1102
|
if (a > 0 && a < 1) {
|
|
1112
|
-
const t1 = taskStart + a * budgetSec * 1000;
|
|
1103
|
+
const t1 = rs.telemetry.taskStart + a * budgetSec * 1000;
|
|
1113
1104
|
const remainMin = Math.max(1, Math.round((budgetSec * 1000 * (1 - a)) / 60_000));
|
|
1114
1105
|
const budgetMin = Math.max(1, Math.round(budgetSec / 60));
|
|
1115
1106
|
nudgeSchedule.push({
|
|
@@ -1117,7 +1108,7 @@ export class Runner {
|
|
|
1117
1108
|
text: `<system-reminder>[deadline] ~${remainMin} min of the ~${budgetMin}-min wall-clock budget remain. ` +
|
|
1118
1109
|
`Start converging: persist finished work (write files / commit), prefer completing in-flight items over opening new ones.</system-reminder>`,
|
|
1119
1110
|
});
|
|
1120
|
-
const t2 = taskStart + Math.max(Math.min(b * budgetSec * 1000, budgetSec * 1000 - 120_000), a * budgetSec * 1000 + 1);
|
|
1111
|
+
const t2 = rs.telemetry.taskStart + Math.max(Math.min(b * budgetSec * 1000, budgetSec * 1000 - 120_000), a * budgetSec * 1000 + 1);
|
|
1121
1112
|
if (b > a && b < 1) {
|
|
1122
1113
|
nudgeSchedule.push({
|
|
1123
1114
|
atMs: t2,
|
|
@@ -1139,7 +1130,7 @@ export class Runner {
|
|
|
1139
1130
|
`</system-reminder>`;
|
|
1140
1131
|
const timeout = startTimeout(prepared.harness, prepared.abortController, walltimeMonotonicDeadline !== undefined ? walltimeMonotonicDeadline - performance.now() : undefined, prepared.suspendForResource !== undefined);
|
|
1141
1132
|
const parentToolCallId = internals?.parentToolCallId;
|
|
1142
|
-
const ident = () => parentToolCallId !== undefined ? { eventId: uuidv7(), parentToolCallId, sourceTaskId: taskId } : { eventId: uuidv7() };
|
|
1133
|
+
const ident = () => parentToolCallId !== undefined ? { eventId: uuidv7(), parentToolCallId, sourceTaskId: rs.telemetry.taskId } : { eventId: uuidv7() };
|
|
1143
1134
|
notificationIdent = ident;
|
|
1144
1135
|
const pushContent = (e) => {
|
|
1145
1136
|
queue.push(e);
|
|
@@ -1168,121 +1159,41 @@ export class Runner {
|
|
|
1168
1159
|
});
|
|
1169
1160
|
};
|
|
1170
1161
|
const telemetryEmit = (t) => {
|
|
1171
|
-
emitTrace(tracer, () => t.kind === "failover"
|
|
1162
|
+
emitTrace(rs.telemetry.tracer, () => t.kind === "failover"
|
|
1172
1163
|
? {
|
|
1173
1164
|
kind: "brain.failover",
|
|
1174
1165
|
version: 1,
|
|
1175
|
-
taskId,
|
|
1166
|
+
taskId: rs.telemetry.taskId,
|
|
1176
1167
|
servedIndex: t.servedIndex,
|
|
1177
1168
|
total: t.total,
|
|
1178
1169
|
...(t.errorCode !== undefined ? { errorCode: t.errorCode } : {}),
|
|
1179
1170
|
ts: Date.now(),
|
|
1180
1171
|
}
|
|
1181
1172
|
: t.kind === "breaker"
|
|
1182
|
-
? { kind: "breaker.transition", version: 1, taskId, key: t.key, phase: t.phase, failures: t.failures, ts: Date.now() }
|
|
1173
|
+
? { kind: "breaker.transition", version: 1, taskId: rs.telemetry.taskId, key: t.key, phase: t.phase, failures: t.failures, ts: Date.now() }
|
|
1183
1174
|
: t.kind === "retry"
|
|
1184
|
-
? { kind: "brain.retry", version: 1, taskId, attempt: t.attempt, phase: t.phase, ts: Date.now() }
|
|
1185
|
-
: { kind: "vision.placeholder", version: 1, taskId, count: t.count, ts: Date.now() });
|
|
1175
|
+
? { kind: "brain.retry", version: 1, taskId: rs.telemetry.taskId, attempt: t.attempt, phase: t.phase, ts: Date.now() }
|
|
1176
|
+
: { kind: "vision.placeholder", version: 1, taskId: rs.telemetry.taskId, count: t.count, ts: Date.now() });
|
|
1186
1177
|
};
|
|
1187
1178
|
const withBrainSinks = (fn) => runWithStatusSink(statusEmit, () => runWithBrainTelemetry(telemetryEmit, fn));
|
|
1188
|
-
const safeJsonLength = (v) => {
|
|
1189
|
-
try {
|
|
1190
|
-
return JSON.stringify(v)?.length;
|
|
1191
|
-
}
|
|
1192
|
-
catch {
|
|
1193
|
-
return undefined;
|
|
1194
|
-
}
|
|
1195
|
-
};
|
|
1196
|
-
const trunc = (s) => ({
|
|
1197
|
-
text: s.slice(0, MAX_TOOL_END_OUTPUT_CHARS) + `…[+${s.length - MAX_TOOL_END_OUTPUT_CHARS} chars truncated]`,
|
|
1198
|
-
totalChars: s.length,
|
|
1199
|
-
});
|
|
1200
|
-
const toolOutputFrom = (result) => {
|
|
1201
|
-
const content = result !== null && typeof result === "object" ? result.content : result;
|
|
1202
|
-
if (content === undefined)
|
|
1203
|
-
return undefined;
|
|
1204
|
-
if (typeof content === "string") {
|
|
1205
|
-
if (content.length <= MAX_TOOL_END_OUTPUT_CHARS)
|
|
1206
|
-
return { output: content, truncated: false };
|
|
1207
|
-
const t = trunc(content);
|
|
1208
|
-
return { output: t.text, truncated: true, totalChars: t.totalChars };
|
|
1209
|
-
}
|
|
1210
|
-
let serialized;
|
|
1211
|
-
try {
|
|
1212
|
-
serialized = JSON.stringify(content) ?? "";
|
|
1213
|
-
}
|
|
1214
|
-
catch {
|
|
1215
|
-
return { output: "[unserializable tool output]", truncated: false };
|
|
1216
|
-
}
|
|
1217
|
-
if (serialized.length <= MAX_TOOL_END_OUTPUT_CHARS)
|
|
1218
|
-
return { output: content, truncated: false };
|
|
1219
|
-
let anyNonText = false;
|
|
1220
|
-
let trueChars = 0;
|
|
1221
|
-
const raw = Array.isArray(content)
|
|
1222
|
-
? content
|
|
1223
|
-
.map((b) => {
|
|
1224
|
-
const block = b;
|
|
1225
|
-
if (block?.type === "text" && typeof block.text === "string") {
|
|
1226
|
-
trueChars += block.text.length;
|
|
1227
|
-
return block.text;
|
|
1228
|
-
}
|
|
1229
|
-
anyNonText = true;
|
|
1230
|
-
trueChars += typeof block?.data === "string" ? block.data.length : (safeJsonLength(block) ?? 0);
|
|
1231
|
-
return `[${typeof block?.type === "string" ? block.type : "block"}${typeof block?.mimeType === "string" ? `: ${block.mimeType}` : ""}]`;
|
|
1232
|
-
})
|
|
1233
|
-
.join("\n")
|
|
1234
|
-
: serialized;
|
|
1235
|
-
const totalChars = Array.isArray(content) ? trueChars : serialized.length;
|
|
1236
|
-
if (raw.length > MAX_TOOL_END_OUTPUT_CHARS) {
|
|
1237
|
-
const t = trunc(raw);
|
|
1238
|
-
return { output: t.text, truncated: true, totalChars };
|
|
1239
|
-
}
|
|
1240
|
-
if (!anyNonText) {
|
|
1241
|
-
return { output: raw, truncated: false };
|
|
1242
|
-
}
|
|
1243
|
-
return { output: raw, truncated: true, totalChars };
|
|
1244
|
-
};
|
|
1245
|
-
const CC_DETAIL_TYPES = new Set([
|
|
1246
|
-
"edit", "multiedit", "create", "update", "bash", "notebook-edit", "notebook", "text", "grep", "glob", "mcp",
|
|
1247
|
-
"agent", "task", "task-list", "task-output", "memory-saved", "workflow-run",
|
|
1248
|
-
"web-fetch", "web-search", "todo", "cron-create", "cron-delete", "cron-list", "image",
|
|
1249
|
-
"task-stop", "tool-search", "memory-recall", "repo-map", "fork", "enter-plan-mode", "exit-plan-mode",
|
|
1250
|
-
]);
|
|
1251
|
-
const structuredFrom = (result) => {
|
|
1252
|
-
const details = result !== null && typeof result === "object" ? result.details : undefined;
|
|
1253
|
-
if (details === null || typeof details !== "object")
|
|
1254
|
-
return undefined;
|
|
1255
|
-
const t = details.type;
|
|
1256
|
-
if (typeof t !== "string" || !CC_DETAIL_TYPES.has(t))
|
|
1257
|
-
return undefined;
|
|
1258
|
-
try {
|
|
1259
|
-
const serialized = JSON.stringify(details) ?? "";
|
|
1260
|
-
if (serialized.length > MAX_TOOL_END_OUTPUT_CHARS * 4)
|
|
1261
|
-
return undefined;
|
|
1262
|
-
}
|
|
1263
|
-
catch {
|
|
1264
|
-
return undefined;
|
|
1265
|
-
}
|
|
1266
|
-
return details;
|
|
1267
|
-
};
|
|
1268
1179
|
const onMessageUpdate = (event) => {
|
|
1269
1180
|
const ev = event.assistantMessageEvent;
|
|
1270
|
-
if (callStartAt === undefined)
|
|
1271
|
-
callStartAt = Date.now();
|
|
1181
|
+
if (rs.turn.callStartAt === undefined)
|
|
1182
|
+
rs.turn.callStartAt = Date.now();
|
|
1272
1183
|
if (ev.type === "text_delta" && ev.delta) {
|
|
1273
|
-
if (firstTokenAt === undefined)
|
|
1274
|
-
firstTokenAt = Date.now();
|
|
1184
|
+
if (rs.turn.firstTokenAt === undefined)
|
|
1185
|
+
rs.turn.firstTokenAt = Date.now();
|
|
1275
1186
|
pushContent({ type: "text_delta", delta: ev.delta, ...ident() });
|
|
1276
1187
|
}
|
|
1277
1188
|
else if (ev.type === "thinking_delta" && ev.delta) {
|
|
1278
1189
|
pushContent({ type: "reasoning_delta", delta: ev.delta, ...ident() });
|
|
1279
1190
|
}
|
|
1280
|
-
if (streamCancel && !budgetHit && (ev.type === "text_delta" || ev.type === "thinking_delta") && ev.delta) {
|
|
1281
|
-
callOutputChars += ev.delta.length;
|
|
1282
|
-
if (callOutputChars - lastStreamBudgetCheck >= 256) {
|
|
1283
|
-
lastStreamBudgetCheck = callOutputChars;
|
|
1284
|
-
if (projectedOverBudget()) {
|
|
1285
|
-
budgetHit = "exceeded";
|
|
1191
|
+
if (rs.budget.streamCancel && !rs.limits.budgetHit && (ev.type === "text_delta" || ev.type === "thinking_delta") && ev.delta) {
|
|
1192
|
+
rs.budget.callOutputChars += ev.delta.length;
|
|
1193
|
+
if (rs.budget.callOutputChars - rs.budget.lastStreamBudgetCheck >= 256) {
|
|
1194
|
+
rs.budget.lastStreamBudgetCheck = rs.budget.callOutputChars;
|
|
1195
|
+
if (rs.budget.projectedOverBudget()) {
|
|
1196
|
+
rs.limits.budgetHit = "exceeded";
|
|
1286
1197
|
void prepared.harness.abort();
|
|
1287
1198
|
prepared.abortController.abort();
|
|
1288
1199
|
}
|
|
@@ -1294,55 +1205,54 @@ export class Runner {
|
|
|
1294
1205
|
if (event.entryId !== undefined && (m.role === "user" || m.role === "assistant" || m.role === "toolResult")) {
|
|
1295
1206
|
emitCommitted(event.entryId, m.role, m.role === "toolResult" ? m.toolCallId : undefined);
|
|
1296
1207
|
}
|
|
1297
|
-
if (degraded === undefined && m.role === "assistant") {
|
|
1208
|
+
if (rs.degrade.degraded === undefined && m.role === "assistant") {
|
|
1298
1209
|
const deg = readDegradation(m);
|
|
1299
1210
|
if (deg)
|
|
1300
|
-
recordDegraded({ from: deg.from, to: deg.to, reason: deg.reason, atTurn: stats.turns + 1, ...(deg.chain && { chain: deg.chain }) });
|
|
1211
|
+
rs.degrade.recordDegraded({ from: deg.from, to: deg.to, reason: deg.reason, atTurn: stats.turns + 1, ...(deg.chain && { chain: deg.chain }) });
|
|
1301
1212
|
}
|
|
1302
1213
|
if (m.role === "assistant" && "usage" in m && m.usage) {
|
|
1303
1214
|
if (m.usageMissing)
|
|
1304
|
-
turnUsageMissing = true;
|
|
1215
|
+
rs.turn.turnUsageMissing = true;
|
|
1305
1216
|
const u = m.usage;
|
|
1306
1217
|
stats.tokens += u.totalTokens || 0;
|
|
1307
|
-
const { totalInputTokens: turnInput, costMicroUsd: turnCostMicroUsd } = usageCostMicroUsd(cacheFamily, u, pricing);
|
|
1218
|
+
const { totalInputTokens: turnInput, costMicroUsd: turnCostMicroUsd } = usageCostMicroUsd(rs.telemetry.cacheFamily, u, rs.telemetry.pricing);
|
|
1308
1219
|
stats.promptTokens += turnInput;
|
|
1309
1220
|
stats.cachedTokens += u.cacheRead || 0;
|
|
1310
1221
|
stats.cacheWriteTokens += u.cacheWrite || 0;
|
|
1311
1222
|
stats.outputTokens += u.output || 0;
|
|
1312
|
-
stats.costUsd += u.cost?.total || 0;
|
|
1313
1223
|
stats.costMicroUsd += turnCostMicroUsd;
|
|
1314
|
-
turnUsage ??= { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, costMicroUsd: 0 };
|
|
1315
|
-
turnUsage.inputTokens += turnInput;
|
|
1316
|
-
turnUsage.outputTokens += u.output || 0;
|
|
1317
|
-
turnUsage.cacheReadTokens += u.cacheRead || 0;
|
|
1318
|
-
turnUsage.cacheWriteTokens += u.cacheWrite || 0;
|
|
1319
|
-
turnUsage.costMicroUsd += turnCostMicroUsd;
|
|
1224
|
+
rs.turn.turnUsage ??= { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, costMicroUsd: 0 };
|
|
1225
|
+
rs.turn.turnUsage.inputTokens += turnInput;
|
|
1226
|
+
rs.turn.turnUsage.outputTokens += u.output || 0;
|
|
1227
|
+
rs.turn.turnUsage.cacheReadTokens += u.cacheRead || 0;
|
|
1228
|
+
rs.turn.turnUsage.cacheWriteTokens += u.cacheWrite || 0;
|
|
1229
|
+
rs.turn.turnUsage.costMicroUsd += turnCostMicroUsd;
|
|
1320
1230
|
const callEndAt = Date.now();
|
|
1321
1231
|
const callIssuedAt = prepared.callIssuedAtRef?.current;
|
|
1322
1232
|
if (prepared.callIssuedAtRef)
|
|
1323
1233
|
prepared.callIssuedAtRef.current = undefined;
|
|
1324
1234
|
const capLast = prepared.callCapRef?.state.last;
|
|
1325
1235
|
if (prepared.callCapRef) {
|
|
1326
|
-
recordCallSample(prepared.callCapRef.state, u.output || 0, callStartAt !== undefined ? callEndAt - callStartAt : 0, {
|
|
1236
|
+
recordCallSample(prepared.callCapRef.state, u.output || 0, rs.turn.callStartAt !== undefined ? callEndAt - rs.turn.callStartAt : 0, {
|
|
1327
1237
|
contentValid: m.usageMissing === true && hasRealContent(m.content),
|
|
1328
1238
|
});
|
|
1329
|
-
if (callStartAt !== undefined && firstTokenAt !== undefined) {
|
|
1330
|
-
recordTtftSample(prepared.callCapRef.state, firstTokenAt - callStartAt);
|
|
1239
|
+
if (rs.turn.callStartAt !== undefined && rs.turn.firstTokenAt !== undefined) {
|
|
1240
|
+
recordTtftSample(prepared.callCapRef.state, rs.turn.firstTokenAt - rs.turn.callStartAt);
|
|
1331
1241
|
}
|
|
1332
1242
|
prepared.callCapRef.state.last = undefined;
|
|
1333
1243
|
}
|
|
1334
|
-
emitTrace(tracer, () => ({
|
|
1244
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
1335
1245
|
kind: "brain.call",
|
|
1336
1246
|
version: 1,
|
|
1337
|
-
taskId,
|
|
1247
|
+
taskId: rs.telemetry.taskId,
|
|
1338
1248
|
model: m.model,
|
|
1339
1249
|
provider: m.provider,
|
|
1340
1250
|
promptTokens: turnInput,
|
|
1341
1251
|
completionTokens: u.output || 0,
|
|
1342
1252
|
cacheRead: u.cacheRead || 0,
|
|
1343
1253
|
cacheWrite: u.cacheWrite || 0,
|
|
1344
|
-
latencyMs: callStartAt !== undefined ? callEndAt - callStartAt : 0,
|
|
1345
|
-
firstTokenMs: callStartAt !== undefined && firstTokenAt !== undefined ? firstTokenAt - callStartAt : undefined,
|
|
1254
|
+
latencyMs: rs.turn.callStartAt !== undefined ? callEndAt - rs.turn.callStartAt : 0,
|
|
1255
|
+
firstTokenMs: rs.turn.callStartAt !== undefined && rs.turn.firstTokenAt !== undefined ? rs.turn.firstTokenAt - rs.turn.callStartAt : undefined,
|
|
1346
1256
|
...(callIssuedAt !== undefined ? { callStartedAt: callIssuedAt } : {}),
|
|
1347
1257
|
costMicroUsd: turnCostMicroUsd,
|
|
1348
1258
|
...(capLast !== undefined ? { callCap: capLast.cap, capThinkingSkipped: capLast.thinkingSkipped } : {}),
|
|
@@ -1373,16 +1283,16 @@ export class Runner {
|
|
|
1373
1283
|
cacheRead: u.cacheRead || 0,
|
|
1374
1284
|
});
|
|
1375
1285
|
if (finding) {
|
|
1376
|
-
cacheBreakReported = true;
|
|
1286
|
+
rs.telemetry.cacheBreakReported = true;
|
|
1377
1287
|
this.deps.onError?.(new Error(`prompt-cache: break at turn ${finding.turn} — cache_read ${finding.cacheReadBefore}→${finding.cacheReadAfter}; ${finding.detail}. See design/31.`), { phase: "prompt-cache", sessionId: prepared.sessionId, classification: finding.cause });
|
|
1378
1288
|
}
|
|
1379
1289
|
}
|
|
1380
1290
|
}
|
|
1381
1291
|
if (m.role === "assistant" && typeof m.stopReason === "string") {
|
|
1382
|
-
turnStopReason = m.stopReason;
|
|
1292
|
+
rs.turn.turnStopReason = m.stopReason;
|
|
1383
1293
|
}
|
|
1384
1294
|
if (m.role === "assistant" && m.errorMessage === WALLTIME_CUTOFF_MESSAGE) {
|
|
1385
|
-
callCutoffs += 1;
|
|
1295
|
+
rs.counters.callCutoffs += 1;
|
|
1386
1296
|
if (prepared.callCapRef)
|
|
1387
1297
|
prepared.callCapRef.finalizeMode = true;
|
|
1388
1298
|
if (!finalizeInjected) {
|
|
@@ -1404,16 +1314,16 @@ export class Runner {
|
|
|
1404
1314
|
];
|
|
1405
1315
|
for (const { action, e } of observed) {
|
|
1406
1316
|
if (action === "cut")
|
|
1407
|
-
repetitionCuts += 1;
|
|
1317
|
+
rs.counters.repetitionCuts += 1;
|
|
1408
1318
|
else
|
|
1409
|
-
repetitionSpared += 1;
|
|
1410
|
-
if (repetitionEvents.length < REPETITION_EVENTS_CAP) {
|
|
1411
|
-
repetitionEvents.push({ turn: stats.turns + 1, action, rule: e.rule, period: e.period, reps: e.reps, segment: e.segment });
|
|
1319
|
+
rs.counters.repetitionSpared += 1;
|
|
1320
|
+
if (rs.counters.repetitionEvents.length < rs.counters.REPETITION_EVENTS_CAP) {
|
|
1321
|
+
rs.counters.repetitionEvents.push({ turn: stats.turns + 1, action, rule: e.rule, period: e.period, reps: e.reps, segment: e.segment });
|
|
1412
1322
|
}
|
|
1413
|
-
emitTrace(tracer, () => ({
|
|
1323
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
1414
1324
|
kind: "repetition.detected",
|
|
1415
1325
|
version: 1,
|
|
1416
|
-
taskId,
|
|
1326
|
+
taskId: rs.telemetry.taskId,
|
|
1417
1327
|
turn: stats.turns + 1,
|
|
1418
1328
|
action,
|
|
1419
1329
|
rule: e.rule,
|
|
@@ -1434,14 +1344,14 @@ export class Runner {
|
|
|
1434
1344
|
}
|
|
1435
1345
|
if (m.role === "assistant") {
|
|
1436
1346
|
const content = m.content;
|
|
1437
|
-
if (attachState !== undefined)
|
|
1438
|
-
cadenceTurns = advanceCadenceClock(attachState, cadenceTurns, content, writeFamilyOf);
|
|
1439
|
-
lastTurnHadToolCalls = Array.isArray(content) && content.some((c) => c?.type === "toolCall");
|
|
1440
|
-
}
|
|
1441
|
-
callStartAt = undefined;
|
|
1442
|
-
firstTokenAt = undefined;
|
|
1443
|
-
callOutputChars = 0;
|
|
1444
|
-
lastStreamBudgetCheck = 0;
|
|
1347
|
+
if (rs.attach.attachState !== undefined)
|
|
1348
|
+
rs.counters.cadenceTurns = advanceCadenceClock(rs.attach.attachState, rs.counters.cadenceTurns, content, writeFamilyOf);
|
|
1349
|
+
rs.turn.lastTurnHadToolCalls = Array.isArray(content) && content.some((c) => c?.type === "toolCall");
|
|
1350
|
+
}
|
|
1351
|
+
rs.turn.callStartAt = undefined;
|
|
1352
|
+
rs.turn.firstTokenAt = undefined;
|
|
1353
|
+
rs.budget.callOutputChars = 0;
|
|
1354
|
+
rs.budget.lastStreamBudgetCheck = 0;
|
|
1445
1355
|
};
|
|
1446
1356
|
const toolLabels = new Map(prepared.tools.flatMap((t) => (t.label !== undefined && t.label !== t.name ? [[t.name, t.label]] : [])));
|
|
1447
1357
|
const postToolBatchHook = (spec.hooks ?? this.deps.hooks)?.postToolBatch;
|
|
@@ -1453,11 +1363,11 @@ export class Runner {
|
|
|
1453
1363
|
startedToolCallIds.add(event.toolCallId);
|
|
1454
1364
|
batchArgs?.set(event.toolCallId, event.args);
|
|
1455
1365
|
stats.toolCalls += 1;
|
|
1456
|
-
if (spec.finalVerification === true && !(finalVerifyInjections === 0 ? groundingSignalPreR9 : groundingSignalPostR9) && hasVerifiableStructureSignal(event.args)) {
|
|
1457
|
-
if (finalVerifyInjections === 0)
|
|
1458
|
-
groundingSignalPreR9 = true;
|
|
1366
|
+
if (spec.finalVerification === true && !(rs.counters.finalVerifyInjections === 0 ? rs.counters.groundingSignalPreR9 : rs.counters.groundingSignalPostR9) && hasVerifiableStructureSignal(event.args)) {
|
|
1367
|
+
if (rs.counters.finalVerifyInjections === 0)
|
|
1368
|
+
rs.counters.groundingSignalPreR9 = true;
|
|
1459
1369
|
else
|
|
1460
|
-
groundingSignalPostR9 = true;
|
|
1370
|
+
rs.counters.groundingSignalPostR9 = true;
|
|
1461
1371
|
}
|
|
1462
1372
|
const activityArg = primaryActivityArg(event.args);
|
|
1463
1373
|
internals?.onActivity?.({ phase: "start", toolCallId: event.toolCallId, toolName: event.toolName, at: startAt, ...(activityArg !== undefined ? { arg: activityArg } : {}) });
|
|
@@ -1479,13 +1389,13 @@ export class Runner {
|
|
|
1479
1389
|
turnToolSpan.startMin = turnToolSpan.startMin === undefined ? toolStarted : Math.min(turnToolSpan.startMin, toolStarted);
|
|
1480
1390
|
turnToolSpan.endMax = turnToolSpan.endMax === undefined ? toolNow : Math.max(turnToolSpan.endMax, toolNow);
|
|
1481
1391
|
}
|
|
1482
|
-
if (!wroteThisRun && (prepared.toolEffects.get(event.toolName) ?? "write") !== "read") {
|
|
1483
|
-
wroteThisRun = true;
|
|
1392
|
+
if (!rs.counters.wroteThisRun && (prepared.toolEffects.get(event.toolName) ?? "write") !== "read") {
|
|
1393
|
+
rs.counters.wroteThisRun = true;
|
|
1484
1394
|
}
|
|
1485
|
-
if (attachState !== undefined && !event.isError) {
|
|
1395
|
+
if (rs.attach.attachState !== undefined && !event.isError) {
|
|
1486
1396
|
const det = event.result?.details;
|
|
1487
1397
|
if (det !== undefined)
|
|
1488
|
-
reduceToolEnd(attachState, det);
|
|
1398
|
+
reduceToolEnd(rs.attach.attachState, det);
|
|
1489
1399
|
}
|
|
1490
1400
|
if (postToolBatchHook !== undefined) {
|
|
1491
1401
|
if (prepared.blockedToolCalls.delete(event.toolCallId)) {
|
|
@@ -1503,10 +1413,10 @@ export class Runner {
|
|
|
1503
1413
|
batchArgs?.delete(event.toolCallId);
|
|
1504
1414
|
}
|
|
1505
1415
|
}
|
|
1506
|
-
emitTrace(tracer, () => ({
|
|
1416
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
1507
1417
|
kind: "tool.call",
|
|
1508
1418
|
version: 1,
|
|
1509
|
-
taskId,
|
|
1419
|
+
taskId: rs.telemetry.taskId,
|
|
1510
1420
|
name: event.toolName,
|
|
1511
1421
|
durationMs: toolStarted !== undefined ? toolNow - toolStarted : 0,
|
|
1512
1422
|
ok: !event.isError,
|
|
@@ -1547,33 +1457,33 @@ export class Runner {
|
|
|
1547
1457
|
}
|
|
1548
1458
|
if (spec.outputSchema && event.toolName === OUTPUT_TOOL_NAME) {
|
|
1549
1459
|
if (event.isError) {
|
|
1550
|
-
outputErrorStreak += 1;
|
|
1551
|
-
if (outputErrorStreak > outputRetryCap) {
|
|
1552
|
-
outputInvalid = true;
|
|
1460
|
+
rs.degrade.outputErrorStreak += 1;
|
|
1461
|
+
if (rs.degrade.outputErrorStreak > rs.limits.outputRetryCap) {
|
|
1462
|
+
rs.degrade.outputInvalid = true;
|
|
1553
1463
|
void prepared.harness.abort();
|
|
1554
1464
|
prepared.abortController.abort();
|
|
1555
1465
|
}
|
|
1556
1466
|
}
|
|
1557
1467
|
else {
|
|
1558
|
-
outputErrorStreak = 0;
|
|
1468
|
+
rs.degrade.outputErrorStreak = 0;
|
|
1559
1469
|
}
|
|
1560
1470
|
}
|
|
1561
1471
|
};
|
|
1562
1472
|
const onTurnEnd = () => {
|
|
1563
1473
|
stats.turns += 1;
|
|
1564
|
-
const stopExtra = turnStopReason !== undefined ? { stopReason: turnStopReason } : {};
|
|
1565
|
-
queue.push(turnUsage
|
|
1566
|
-
? { type: "turn_end", usage: turnUsage, ...(turnUsageMissing ? { usageMissing: true } : {}), ...stopExtra, ...ident() }
|
|
1474
|
+
const stopExtra = rs.turn.turnStopReason !== undefined ? { stopReason: rs.turn.turnStopReason } : {};
|
|
1475
|
+
queue.push(rs.turn.turnUsage
|
|
1476
|
+
? { type: "turn_end", usage: rs.turn.turnUsage, ...(rs.turn.turnUsageMissing ? { usageMissing: true } : {}), ...stopExtra, ...ident() }
|
|
1567
1477
|
: { type: "turn_end", usageMissing: true, ...stopExtra, ...ident() });
|
|
1568
|
-
turnUsageMissing = false;
|
|
1569
|
-
turnStopReason = undefined;
|
|
1478
|
+
rs.turn.turnUsageMissing = false;
|
|
1479
|
+
rs.turn.turnStopReason = undefined;
|
|
1570
1480
|
if (parentToolCallId !== undefined) {
|
|
1571
1481
|
const progress = {
|
|
1572
1482
|
type: "task_progress",
|
|
1573
|
-
taskId,
|
|
1483
|
+
taskId: rs.telemetry.taskId,
|
|
1574
1484
|
...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}),
|
|
1575
1485
|
...(subagentName ? { name: subagentName } : {}),
|
|
1576
|
-
usage: { totalTokens: stats.tokens, toolUses: stats.toolCalls, durationMs: Date.now() - taskStart },
|
|
1486
|
+
usage: { totalTokens: stats.tokens, toolUses: stats.toolCalls, durationMs: Date.now() - rs.telemetry.taskStart },
|
|
1577
1487
|
status: "running",
|
|
1578
1488
|
...ident(),
|
|
1579
1489
|
};
|
|
@@ -1584,37 +1494,37 @@ export class Runner {
|
|
|
1584
1494
|
catch {
|
|
1585
1495
|
}
|
|
1586
1496
|
}
|
|
1587
|
-
emitTrace(tracer, () => ({ kind: "turn.end", version: 1, taskId, turn: stats.turns, ts: Date.now() }));
|
|
1588
|
-
turnUsage = undefined;
|
|
1589
|
-
callStartAt = undefined;
|
|
1590
|
-
firstTokenAt = undefined;
|
|
1591
|
-
callOutputChars = 0;
|
|
1592
|
-
lastStreamBudgetCheck = 0;
|
|
1497
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "turn.end", version: 1, taskId: rs.telemetry.taskId, turn: stats.turns, ts: Date.now() }));
|
|
1498
|
+
rs.turn.turnUsage = undefined;
|
|
1499
|
+
rs.turn.callStartAt = undefined;
|
|
1500
|
+
rs.turn.firstTokenAt = undefined;
|
|
1501
|
+
rs.budget.callOutputChars = 0;
|
|
1502
|
+
rs.budget.lastStreamBudgetCheck = 0;
|
|
1593
1503
|
toolStartAt.clear();
|
|
1594
|
-
if (effectiveMaxTurns !== undefined && effectiveMaxTurns > 0 && stats.turns >= effectiveMaxTurns) {
|
|
1595
|
-
turnsExceeded = true;
|
|
1504
|
+
if (rs.limits.effectiveMaxTurns !== undefined && rs.limits.effectiveMaxTurns > 0 && stats.turns >= rs.limits.effectiveMaxTurns) {
|
|
1505
|
+
rs.limits.turnsExceeded = true;
|
|
1596
1506
|
if (prepared.suspendForResource === undefined) {
|
|
1597
1507
|
void prepared.harness.abort();
|
|
1598
1508
|
prepared.abortController.abort();
|
|
1599
1509
|
}
|
|
1600
1510
|
}
|
|
1601
1511
|
else {
|
|
1602
|
-
if (degraded === undefined &&
|
|
1512
|
+
if (rs.degrade.degraded === undefined &&
|
|
1603
1513
|
spec.degrade &&
|
|
1604
|
-
degradeToModel &&
|
|
1605
|
-
maxCostMicroUsd !== undefined &&
|
|
1606
|
-
stats.costMicroUsd >= spec.degrade.atCostFraction * maxCostMicroUsd) {
|
|
1607
|
-
void prepared.harness.setModel(degradeToModel);
|
|
1608
|
-
recordDegraded({ from: prepared.model.id, to: degradeToModel.id, reason: "budget", atTurn: stats.turns }, degradeToModel);
|
|
1514
|
+
rs.degrade.degradeToModel &&
|
|
1515
|
+
rs.budget.maxCostMicroUsd !== undefined &&
|
|
1516
|
+
stats.costMicroUsd >= spec.degrade.atCostFraction * rs.budget.maxCostMicroUsd) {
|
|
1517
|
+
void prepared.harness.setModel(rs.degrade.degradeToModel);
|
|
1518
|
+
rs.degrade.recordDegraded({ from: prepared.model.id, to: rs.degrade.degradeToModel.id, reason: "budget", atTurn: stats.turns }, rs.degrade.degradeToModel);
|
|
1609
1519
|
if (prepared.callCapRef &&
|
|
1610
1520
|
spec.limits?.maxOutputTokens === undefined &&
|
|
1611
|
-
degradeToModel.maxTokens !== undefined &&
|
|
1612
|
-
(prepared.callCapRef.staticCapTokens === undefined || degradeToModel.maxTokens < prepared.callCapRef.staticCapTokens)) {
|
|
1613
|
-
prepared.callCapRef.staticCapTokens = degradeToModel.maxTokens;
|
|
1521
|
+
rs.degrade.degradeToModel.maxTokens !== undefined &&
|
|
1522
|
+
(prepared.callCapRef.staticCapTokens === undefined || rs.degrade.degradeToModel.maxTokens < prepared.callCapRef.staticCapTokens)) {
|
|
1523
|
+
prepared.callCapRef.staticCapTokens = rs.degrade.degradeToModel.maxTokens;
|
|
1614
1524
|
}
|
|
1615
1525
|
}
|
|
1616
|
-
if (!budgetHit && overBudget()) {
|
|
1617
|
-
budgetHit = "exceeded";
|
|
1526
|
+
if (!rs.limits.budgetHit && rs.budget.overBudget()) {
|
|
1527
|
+
rs.limits.budgetHit = "exceeded";
|
|
1618
1528
|
if (prepared.suspendForResource === undefined) {
|
|
1619
1529
|
void prepared.harness.abort();
|
|
1620
1530
|
prepared.abortController.abort();
|
|
@@ -1634,11 +1544,10 @@ export class Runner {
|
|
|
1634
1544
|
stats.cachedTokens += u.cacheRead || 0;
|
|
1635
1545
|
stats.cacheWriteTokens += u.cacheWrite || 0;
|
|
1636
1546
|
stats.outputTokens += u.output || 0;
|
|
1637
|
-
stats.costUsd += u.cost?.total || 0;
|
|
1638
1547
|
stats.costMicroUsd += costMicroUsd;
|
|
1639
1548
|
stats.compactionMicroUsd = (stats.compactionMicroUsd ?? 0) + costMicroUsd;
|
|
1640
|
-
emitTrace(tracer, () => ({
|
|
1641
|
-
kind: "brain.call", version: 1, taskId, model: m.id, provider: m.provider,
|
|
1549
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
1550
|
+
kind: "brain.call", version: 1, taskId: rs.telemetry.taskId, model: m.id, provider: m.provider,
|
|
1642
1551
|
promptTokens: totalInputTokens, completionTokens: u.output || 0,
|
|
1643
1552
|
cacheRead: u.cacheRead || 0, cacheWrite: u.cacheWrite || 0,
|
|
1644
1553
|
latencyMs: 0, costMicroUsd, ...(typeof msg?.stopReason === "string" ? { stopReason: msg.stopReason } : {}), ts: Date.now(),
|
|
@@ -1658,11 +1567,11 @@ export class Runner {
|
|
|
1658
1567
|
const compactionBreaker = { failures: 0 };
|
|
1659
1568
|
const compactionThroughputRef = {};
|
|
1660
1569
|
const windowSafetyOptions = (mainModel) => ({
|
|
1661
|
-
...(maxCostMicroUsd !== undefined
|
|
1570
|
+
...(rs.budget.maxCostMicroUsd !== undefined
|
|
1662
1571
|
? {
|
|
1663
1572
|
fallbackBudget: {
|
|
1664
1573
|
spentMicroUsd: () => stats.costMicroUsd,
|
|
1665
|
-
capMicroUsd: maxCostMicroUsd,
|
|
1574
|
+
capMicroUsd: rs.budget.maxCostMicroUsd,
|
|
1666
1575
|
mainInputPer1M: (this.deps.pricing?.[mainModel.id] ?? modelCostToPricing(mainModel.cost)).inputPer1M,
|
|
1667
1576
|
},
|
|
1668
1577
|
}
|
|
@@ -1678,10 +1587,10 @@ export class Runner {
|
|
|
1678
1587
|
: {}),
|
|
1679
1588
|
onWindowSafety: (info) => {
|
|
1680
1589
|
if (info.kind === "fallback") {
|
|
1681
|
-
emitTrace(tracer, () => ({
|
|
1590
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
1682
1591
|
kind: "compaction.model_fallback",
|
|
1683
1592
|
version: 1,
|
|
1684
|
-
taskId,
|
|
1593
|
+
taskId: rs.telemetry.taskId,
|
|
1685
1594
|
contentTokens: info.contentTokens,
|
|
1686
1595
|
headroomTokens: info.headroomTokens ?? 0,
|
|
1687
1596
|
truncationRatio: info.truncationRatio,
|
|
@@ -1690,10 +1599,10 @@ export class Runner {
|
|
|
1690
1599
|
}));
|
|
1691
1600
|
}
|
|
1692
1601
|
else {
|
|
1693
|
-
emitTrace(tracer, () => ({
|
|
1602
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
1694
1603
|
kind: "compaction.clamp_disclosure",
|
|
1695
1604
|
version: 1,
|
|
1696
|
-
taskId,
|
|
1605
|
+
taskId: rs.telemetry.taskId,
|
|
1697
1606
|
truncationRatio: info.truncationRatio,
|
|
1698
1607
|
reason: info.reason ?? "tolerance",
|
|
1699
1608
|
...(info.estCostMicroUsd !== undefined ? { estCostMicroUsd: info.estCostMicroUsd } : {}),
|
|
@@ -1710,13 +1619,13 @@ export class Runner {
|
|
|
1710
1619
|
if (prepared.abortController.signal.aborted || prepared.suspendRef.token !== undefined)
|
|
1711
1620
|
return [];
|
|
1712
1621
|
if (finalVerificationOn &&
|
|
1713
|
-
(finalVerifyInjections === 0 || (finalVerifyInjections === 1 && groundingSignalPreR9 && !groundingSignalPostR9)) &&
|
|
1714
|
-
wroteThisRun &&
|
|
1622
|
+
(rs.counters.finalVerifyInjections === 0 || (rs.counters.finalVerifyInjections === 1 && rs.counters.groundingSignalPreR9 && !rs.counters.groundingSignalPostR9)) &&
|
|
1623
|
+
rs.counters.wroteThisRun &&
|
|
1715
1624
|
prepared.outputRef.set !== true &&
|
|
1716
1625
|
!finalizeInjected &&
|
|
1717
|
-
!(effectiveMaxTurns !== undefined && effectiveMaxTurns > 0 && stats.turns >= effectiveMaxTurns - 1)) {
|
|
1718
|
-
finalVerifyInjections += 1;
|
|
1719
|
-
if (finalVerifyInjections === 2) {
|
|
1626
|
+
!(rs.limits.effectiveMaxTurns !== undefined && rs.limits.effectiveMaxTurns > 0 && stats.turns >= rs.limits.effectiveMaxTurns - 1)) {
|
|
1627
|
+
rs.counters.finalVerifyInjections += 1;
|
|
1628
|
+
if (rs.counters.finalVerifyInjections === 2) {
|
|
1720
1629
|
return [
|
|
1721
1630
|
{
|
|
1722
1631
|
role: "user",
|
|
@@ -1860,7 +1769,7 @@ export class Runner {
|
|
|
1860
1769
|
minTokens: 0,
|
|
1861
1770
|
force: true,
|
|
1862
1771
|
overheadTokens: prepared.promptOverheadTokens,
|
|
1863
|
-
onInputTruncated: (info) => emitTrace(tracer, () => ({ kind: "compaction.input_truncated", version: 1, taskId, label: info.label, droppedChars: info.droppedChars, keptChars: info.keptChars, ts: Date.now() })),
|
|
1772
|
+
onInputTruncated: (info) => emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.input_truncated", version: 1, taskId: rs.telemetry.taskId, label: info.label, droppedChars: info.droppedChars, keptChars: info.keptChars, ts: Date.now() })),
|
|
1864
1773
|
workingFileAttachments: spec.compaction?.attachWorkingFiles !== false && prepared.readTaskFile
|
|
1865
1774
|
? {
|
|
1866
1775
|
readFile: prepared.readTaskFile,
|
|
@@ -1903,12 +1812,12 @@ export class Runner {
|
|
|
1903
1812
|
if (comp.phaseDurations !== undefined && comp.durationMs !== undefined) {
|
|
1904
1813
|
const pd = comp.phaseDurations;
|
|
1905
1814
|
const pdDur = comp.durationMs;
|
|
1906
|
-
emitTrace(tracer, () => ({ kind: "compaction.phase_timings", version: 1, taskId, ...pd, durationMs: pdDur, ts: Date.now() }));
|
|
1815
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.phase_timings", version: 1, taskId: rs.telemetry.taskId, ...pd, durationMs: pdDur, ts: Date.now() }));
|
|
1907
1816
|
}
|
|
1908
1817
|
prepared.cacheBreakDetector?.notifyCompaction();
|
|
1909
|
-
if (attachState !== undefined) {
|
|
1910
|
-
attachState.postCompactPending = true;
|
|
1911
|
-
rebaseCadenceWindows(attachState, cadenceTurns);
|
|
1818
|
+
if (rs.attach.attachState !== undefined) {
|
|
1819
|
+
rs.attach.attachState.postCompactPending = true;
|
|
1820
|
+
rebaseCadenceWindows(rs.attach.attachState, rs.counters.cadenceTurns);
|
|
1912
1821
|
}
|
|
1913
1822
|
}
|
|
1914
1823
|
else {
|
|
@@ -1964,31 +1873,31 @@ export class Runner {
|
|
|
1964
1873
|
}
|
|
1965
1874
|
if (due) {
|
|
1966
1875
|
void prepared.harness.steer(due.text, { engineMinted: true }).catch(() => { });
|
|
1967
|
-
nudgesSent += 1;
|
|
1876
|
+
rs.counters.nudgesSent += 1;
|
|
1968
1877
|
boundarySteered = true;
|
|
1969
1878
|
queue.push({ type: "steering_injected", source: "deadline_nudge", preview: due.text.slice(0, 220), ...ident() });
|
|
1970
1879
|
}
|
|
1971
1880
|
}
|
|
1972
1881
|
const walltimeHit = walltimeMonotonicDeadline !== undefined && performance.now() >= walltimeMonotonicDeadline;
|
|
1973
1882
|
const preemptHit = spec.preemptSignal?.aborted === true;
|
|
1974
|
-
if (preemptHit && !prepared.suspendForResource && !preemptIgnoredReported) {
|
|
1975
|
-
preemptIgnoredReported = true;
|
|
1976
|
-
emitTrace(tracer, () => ({ kind: "preempt.ignored", version: 1, taskId, ts: Date.now() }));
|
|
1883
|
+
if (preemptHit && !prepared.suspendForResource && !rs.counters.preemptIgnoredReported) {
|
|
1884
|
+
rs.counters.preemptIgnoredReported = true;
|
|
1885
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "preempt.ignored", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
1977
1886
|
}
|
|
1978
1887
|
if (prepared.suspendForResource &&
|
|
1979
|
-
(turnsExceeded || budgetHit !== undefined || walltimeHit || preemptHit) &&
|
|
1888
|
+
(rs.limits.turnsExceeded || rs.limits.budgetHit !== undefined || walltimeHit || preemptHit) &&
|
|
1980
1889
|
prepared.suspendRef.token === undefined) {
|
|
1981
1890
|
const reason = preemptHit
|
|
1982
1891
|
? "preempt"
|
|
1983
|
-
: budgetHit !== undefined
|
|
1892
|
+
: rs.limits.budgetHit !== undefined
|
|
1984
1893
|
? "budget"
|
|
1985
1894
|
: walltimeHit
|
|
1986
1895
|
? "walltime"
|
|
1987
1896
|
: "turns";
|
|
1988
|
-
const sliceSpend = { costMicroUsd: stats.costMicroUsd, tokens: stats.tokens, turns: stats.turns, walltimeMs: Math.round(performance.now() - taskStartMonotonic) };
|
|
1897
|
+
const sliceSpend = { costMicroUsd: stats.costMicroUsd, tokens: stats.tokens, turns: stats.turns, walltimeMs: Math.round(performance.now() - rs.telemetry.taskStartMonotonic) };
|
|
1989
1898
|
if (await prepared.suspendForResource(reason, sliceSpend)) {
|
|
1990
|
-
turnsExceeded = false;
|
|
1991
|
-
budgetHit = undefined;
|
|
1899
|
+
rs.limits.turnsExceeded = false;
|
|
1900
|
+
rs.limits.budgetHit = undefined;
|
|
1992
1901
|
}
|
|
1993
1902
|
else {
|
|
1994
1903
|
void prepared.harness.abort();
|
|
@@ -2020,7 +1929,7 @@ export class Runner {
|
|
|
2020
1929
|
await prepared.suspendForReview(reason);
|
|
2021
1930
|
return undefined;
|
|
2022
1931
|
}
|
|
2023
|
-
emitTrace(tracer, () => ({ kind: "review.dropped", version: 1, taskId, ts: Date.now() }));
|
|
1932
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "review.dropped", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
2024
1933
|
}
|
|
2025
1934
|
if (prepared.lspDiagnostics && !prepared.lspDiagnostics.registry.isEmpty() && !prepared.abortController.signal.aborted) {
|
|
2026
1935
|
const files = prepared.lspDiagnostics.registry.drain();
|
|
@@ -2033,18 +1942,18 @@ export class Runner {
|
|
|
2033
1942
|
}
|
|
2034
1943
|
let boundaryAttachmentBytes = 0;
|
|
2035
1944
|
let attachmentsPayload;
|
|
2036
|
-
if ((dateState !== undefined || instrState !== undefined || attachState !== undefined) &&
|
|
1945
|
+
if ((rs.attach.dateState !== undefined || rs.attach.instrState !== undefined || rs.attach.attachState !== undefined) &&
|
|
2037
1946
|
!boundarySteered &&
|
|
2038
1947
|
!finalizeInjected &&
|
|
2039
|
-
finalVerifyInjections === 0 &&
|
|
1948
|
+
rs.counters.finalVerifyInjections === 0 &&
|
|
2040
1949
|
!prepared.abortController.signal.aborted) {
|
|
2041
1950
|
const due = [];
|
|
2042
|
-
if (attachState !== undefined) {
|
|
2043
|
-
const changedFilesOn = Boolean(attachmentsCfg?.changedFiles);
|
|
1951
|
+
if (rs.attach.attachState !== undefined) {
|
|
1952
|
+
const changedFilesOn = Boolean(rs.attach.attachmentsCfg?.changedFiles);
|
|
2044
1953
|
let changed;
|
|
2045
1954
|
if (changedFilesOn && prepared.detectExternalChanges !== undefined) {
|
|
2046
|
-
const maxFiles = typeof attachmentsCfg?.changedFiles === "object"
|
|
2047
|
-
? (attachmentsCfg.changedFiles.maxFiles ?? CHANGED_FILES_MAX)
|
|
1955
|
+
const maxFiles = typeof rs.attach.attachmentsCfg?.changedFiles === "object"
|
|
1956
|
+
? (rs.attach.attachmentsCfg.changedFiles.maxFiles ?? CHANGED_FILES_MAX)
|
|
2048
1957
|
: CHANGED_FILES_MAX;
|
|
2049
1958
|
const SCAN_CEILING_MS = 2_000;
|
|
2050
1959
|
const scan = await Promise.race([
|
|
@@ -2055,53 +1964,53 @@ export class Runner {
|
|
|
2055
1964
|
}),
|
|
2056
1965
|
]);
|
|
2057
1966
|
for (const p of scan.evicted)
|
|
2058
|
-
attachState.surfacedMtime.delete(p);
|
|
1967
|
+
rs.attach.attachState.surfacedMtime.delete(p);
|
|
2059
1968
|
changed = scan.changed;
|
|
2060
1969
|
}
|
|
2061
|
-
const backgroundTasksOn = attachmentsCfg?.backgroundTasks === true;
|
|
2062
|
-
const bgTasks = backgroundTasksOn && attachState.postCompactPending ? prepared.listBackgroundTasks() : undefined;
|
|
2063
|
-
const toolsDeltaOn = attachmentsCfg?.toolsDelta === true;
|
|
1970
|
+
const backgroundTasksOn = rs.attach.attachmentsCfg?.backgroundTasks === true;
|
|
1971
|
+
const bgTasks = backgroundTasksOn && rs.attach.attachState.postCompactPending ? prepared.listBackgroundTasks() : undefined;
|
|
1972
|
+
const toolsDeltaOn = rs.attach.attachmentsCfg?.toolsDelta === true;
|
|
2064
1973
|
const pendingTools = toolsDeltaOn && prepared.toolsDeltaRef !== undefined && prepared.toolsDeltaRef.pending.length > 0
|
|
2065
1974
|
? [...prepared.toolsDeltaRef.pending]
|
|
2066
1975
|
: undefined;
|
|
2067
|
-
const mcpInstructionsOn = attachmentsCfg?.mcpInstructions === true;
|
|
1976
|
+
const mcpInstructionsOn = rs.attach.attachmentsCfg?.mcpInstructions === true;
|
|
2068
1977
|
const mcpDelta = prepared.mcp.instructionsDelta;
|
|
2069
1978
|
const mcpAdds = mcpInstructionsOn && mcpDelta.pendingAdds.length > 0 ? [...mcpDelta.pendingAdds] : undefined;
|
|
2070
1979
|
const mcpRemovals = mcpInstructionsOn && mcpDelta.pendingRemovals.length > 0 ? [...mcpDelta.pendingRemovals] : undefined;
|
|
2071
1980
|
const mcpDropped = mcpInstructionsOn && prepared.mcp.droppedTools.length > 0 ? selectMcpDroppedBatch(prepared.mcp.droppedTools) : undefined;
|
|
2072
|
-
const budgetUsdOn = attachmentsCfg?.budgetUsd === true && maxCostMicroUsd !== undefined && lastTurnHadToolCalls;
|
|
2073
|
-
due.push(...collectDueAttachments(attachState, {
|
|
1981
|
+
const budgetUsdOn = rs.attach.attachmentsCfg?.budgetUsd === true && rs.budget.maxCostMicroUsd !== undefined && rs.turn.lastTurnHadToolCalls;
|
|
1982
|
+
due.push(...collectDueAttachments(rs.attach.attachState, {
|
|
2074
1983
|
turn: stats.turns,
|
|
2075
|
-
cadenceTurn: cadenceTurns,
|
|
1984
|
+
cadenceTurn: rs.counters.cadenceTurns,
|
|
2076
1985
|
todoMounted: todoToolMounted,
|
|
2077
1986
|
taskListMounted: taskToolsMounted,
|
|
2078
1987
|
planActive: prepared.planModeRef.active,
|
|
2079
1988
|
config: {
|
|
2080
|
-
todoReminder: attachmentsCfg?.todoReminder === true,
|
|
2081
|
-
...(attachmentsCfg?.todoReminderMode !== undefined ? { todoReminderMode: attachmentsCfg.todoReminderMode } : {}),
|
|
1989
|
+
todoReminder: rs.attach.attachmentsCfg?.todoReminder === true,
|
|
1990
|
+
...(rs.attach.attachmentsCfg?.todoReminderMode !== undefined ? { todoReminderMode: rs.attach.attachmentsCfg.todoReminderMode } : {}),
|
|
2082
1991
|
changedFiles: changedFilesOn,
|
|
2083
|
-
planModeReminder: attachmentsCfg?.planModeReminder === true,
|
|
1992
|
+
planModeReminder: rs.attach.attachmentsCfg?.planModeReminder === true,
|
|
2084
1993
|
budgetUsd: budgetUsdOn,
|
|
2085
1994
|
backgroundTasks: backgroundTasksOn,
|
|
2086
1995
|
toolsDelta: toolsDeltaOn,
|
|
2087
|
-
agentListing: agentListingOn,
|
|
2088
|
-
skillsListing: skillsListingOn,
|
|
1996
|
+
agentListing: rs.attach.agentListingOn,
|
|
1997
|
+
skillsListing: rs.attach.skillsListingOn,
|
|
2089
1998
|
mcpInstructions: mcpInstructionsOn,
|
|
2090
1999
|
},
|
|
2091
2000
|
...(changed !== undefined ? { changedFiles: changed } : {}),
|
|
2092
|
-
...(budgetUsdOn && maxCostMicroUsd !== undefined
|
|
2093
|
-
? { budgetUsd: { used: stats.costMicroUsd / 1e6, total: maxCostMicroUsd / 1e6 } }
|
|
2001
|
+
...(budgetUsdOn && rs.budget.maxCostMicroUsd !== undefined
|
|
2002
|
+
? { budgetUsd: { used: stats.costMicroUsd / 1e6, total: rs.budget.maxCostMicroUsd / 1e6 } }
|
|
2094
2003
|
: {}),
|
|
2095
2004
|
...(bgTasks !== undefined ? { backgroundTasks: bgTasks } : {}),
|
|
2096
2005
|
...(pendingTools !== undefined ? { newTools: pendingTools } : {}),
|
|
2097
|
-
...(agentListingOn && prepared.agentListing !== undefined
|
|
2006
|
+
...(rs.attach.agentListingOn && prepared.agentListing !== undefined
|
|
2098
2007
|
? {
|
|
2099
2008
|
agentListing: prepared.agentListing.entries,
|
|
2100
2009
|
agentToolName: prepared.agentListing.toolName,
|
|
2101
2010
|
...(prepared.agentListing.models !== undefined ? { agentModels: prepared.agentListing.models } : {}),
|
|
2102
2011
|
}
|
|
2103
2012
|
: {}),
|
|
2104
|
-
...(skillsListingOn && prepared.skillsListing !== undefined ? { skillsListing: prepared.skillsListing.entries } : {}),
|
|
2013
|
+
...(rs.attach.skillsListingOn && prepared.skillsListing !== undefined ? { skillsListing: prepared.skillsListing.entries } : {}),
|
|
2105
2014
|
...(mcpAdds !== undefined || mcpRemovals !== undefined
|
|
2106
2015
|
? { mcpInstructions: { added: mcpAdds ?? [], removed: mcpRemovals ?? [] } }
|
|
2107
2016
|
: {}),
|
|
@@ -2121,41 +2030,41 @@ export class Runner {
|
|
|
2121
2030
|
due.some((a) => a.source === "mcp_dropped_tools" && a.body === renderMcpDroppedTools(mcpDropped))) {
|
|
2122
2031
|
prepared.mcp.droppedTools.splice(0, mcpDropped.length);
|
|
2123
2032
|
}
|
|
2124
|
-
if (agentListingOn && prepared.agentListing !== undefined && due.some((a) => a.source === "agent_listing")) {
|
|
2033
|
+
if (rs.attach.agentListingOn && prepared.agentListing !== undefined && due.some((a) => a.source === "agent_listing")) {
|
|
2125
2034
|
const listing = prepared.agentListing;
|
|
2126
|
-
const intactBody = renderAgentListingDelta(attachState, listing.entries, listing.toolName, listing.models);
|
|
2035
|
+
const intactBody = renderAgentListingDelta(rs.attach.attachState, listing.entries, listing.toolName, listing.models);
|
|
2127
2036
|
if (intactBody !== undefined && due.some((a) => a.source === "agent_listing" && a.body === intactBody)) {
|
|
2128
|
-
commitAgentListing(attachState, listing.entries, listing.models);
|
|
2037
|
+
commitAgentListing(rs.attach.attachState, listing.entries, listing.models);
|
|
2129
2038
|
prepared.announcedListingsRef.agents = listing.entries.map((e) => e.name);
|
|
2130
2039
|
if (listing.models !== undefined)
|
|
2131
2040
|
prepared.announcedListingsRef.models = [...listing.models];
|
|
2132
2041
|
await prepared.session.appendAnnouncedListing(prepared.announcedListingsRef).catch(() => undefined);
|
|
2133
2042
|
}
|
|
2134
2043
|
}
|
|
2135
|
-
if (skillsListingOn && prepared.skillsListing !== undefined && due.some((a) => a.source === "skills_listing")) {
|
|
2044
|
+
if (rs.attach.skillsListingOn && prepared.skillsListing !== undefined && due.some((a) => a.source === "skills_listing")) {
|
|
2136
2045
|
const listing = prepared.skillsListing;
|
|
2137
|
-
const intactBody = renderSkillsListingDelta(attachState, listing.entries);
|
|
2046
|
+
const intactBody = renderSkillsListingDelta(rs.attach.attachState, listing.entries);
|
|
2138
2047
|
if (intactBody !== undefined && due.some((a) => a.source === "skills_listing" && a.body === intactBody)) {
|
|
2139
|
-
commitSkillsListing(attachState, listing.entries);
|
|
2048
|
+
commitSkillsListing(rs.attach.attachState, listing.entries);
|
|
2140
2049
|
prepared.announcedListingsRef.skills = listing.entries.map((e) => e.name);
|
|
2141
2050
|
await prepared.session.appendAnnouncedListing(prepared.announcedListingsRef).catch(() => undefined);
|
|
2142
2051
|
}
|
|
2143
2052
|
}
|
|
2144
2053
|
}
|
|
2145
|
-
if (dateState !== undefined && lastTurnHadToolCalls) {
|
|
2054
|
+
if (rs.attach.dateState !== undefined && rs.turn.lastTurnHadToolCalls) {
|
|
2146
2055
|
const today = prepared.dateChange.today();
|
|
2147
|
-
const cand = collectDateChange(dateState, today);
|
|
2056
|
+
const cand = collectDateChange(rs.attach.dateState, today);
|
|
2148
2057
|
if (cand !== undefined) {
|
|
2149
2058
|
due.unshift(cand);
|
|
2150
|
-
dateState.announcedDate = today;
|
|
2059
|
+
rs.attach.dateState.announcedDate = today;
|
|
2151
2060
|
}
|
|
2152
2061
|
}
|
|
2153
|
-
if (instrState !== undefined && instrProbe !== undefined && lastTurnHadToolCalls) {
|
|
2062
|
+
if (rs.attach.instrState !== undefined && rs.attach.instrProbe !== undefined && rs.turn.lastTurnHadToolCalls) {
|
|
2154
2063
|
let probed = null;
|
|
2155
2064
|
try {
|
|
2156
2065
|
const PROBE_CEILING_MS = 2_000;
|
|
2157
2066
|
probed = await Promise.race([
|
|
2158
|
-
instrProbe(prepared.instructionSources),
|
|
2067
|
+
rs.attach.instrProbe(prepared.instructionSources),
|
|
2159
2068
|
new Promise((resolve) => {
|
|
2160
2069
|
const t = setTimeout(() => resolve(null), PROBE_CEILING_MS);
|
|
2161
2070
|
t.unref?.();
|
|
@@ -2165,10 +2074,10 @@ export class Runner {
|
|
|
2165
2074
|
catch {
|
|
2166
2075
|
probed = null;
|
|
2167
2076
|
}
|
|
2168
|
-
const cand = collectInstructionsChange(instrState, probed);
|
|
2077
|
+
const cand = collectInstructionsChange(rs.attach.instrState, probed);
|
|
2169
2078
|
if (cand !== undefined) {
|
|
2170
2079
|
due.splice(due.length > 0 && due[0].source === "date_change" ? 1 : 0, 0, cand.attachment);
|
|
2171
|
-
commitInstructionsChange(instrState, cand.announced);
|
|
2080
|
+
commitInstructionsChange(rs.attach.instrState, cand.announced);
|
|
2172
2081
|
}
|
|
2173
2082
|
}
|
|
2174
2083
|
if (due.length > 0) {
|
|
@@ -2186,7 +2095,7 @@ export class Runner {
|
|
|
2186
2095
|
const batch = toolBatch;
|
|
2187
2096
|
toolBatch = [];
|
|
2188
2097
|
batchArgs?.clear();
|
|
2189
|
-
if (!boundarySteered && !finalizeInjected && finalVerifyInjections === 0 && !prepared.abortController.signal.aborted) {
|
|
2098
|
+
if (!boundarySteered && !finalizeInjected && rs.counters.finalVerifyInjections === 0 && !prepared.abortController.signal.aborted) {
|
|
2190
2099
|
try {
|
|
2191
2100
|
const r = await postToolBatchHook(batch);
|
|
2192
2101
|
if (r?.additionalContext) {
|
|
@@ -2220,17 +2129,17 @@ export class Runner {
|
|
|
2220
2129
|
prepared.suspendRef.token !== undefined ||
|
|
2221
2130
|
prepared.reviewRef.token !== undefined) {
|
|
2222
2131
|
if (forceManual) {
|
|
2223
|
-
emitTrace(tracer, () => ({ kind: "compaction.mooted", version: 1, taskId, reason: "task_ending", ts: Date.now() }));
|
|
2132
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.mooted", version: 1, taskId: rs.telemetry.taskId, reason: "task_ending", ts: Date.now() }));
|
|
2224
2133
|
drainManualCompact("mooted");
|
|
2225
2134
|
}
|
|
2226
2135
|
return undefined;
|
|
2227
2136
|
}
|
|
2228
2137
|
if (compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES) {
|
|
2229
2138
|
if (forceManual) {
|
|
2230
|
-
emitTrace(tracer, () => ({
|
|
2139
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
2231
2140
|
kind: "compaction.failed",
|
|
2232
2141
|
version: 1,
|
|
2233
|
-
taskId,
|
|
2142
|
+
taskId: rs.telemetry.taskId,
|
|
2234
2143
|
trigger: "manual",
|
|
2235
2144
|
reason: "compaction circuit breaker open (3 consecutive failures this task) — manual request drained without an attempt",
|
|
2236
2145
|
ts: Date.now(),
|
|
@@ -2275,7 +2184,7 @@ export class Runner {
|
|
|
2275
2184
|
const trimPressure = trimPressureArmed && !trimForceBackoff;
|
|
2276
2185
|
let manualOutcome = "failed";
|
|
2277
2186
|
if (finalizeInjected && forceManual) {
|
|
2278
|
-
emitTrace(tracer, () => ({ kind: "compaction.manual_in_finalize", version: 1, taskId, ts: Date.now() }));
|
|
2187
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.manual_in_finalize", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
2279
2188
|
}
|
|
2280
2189
|
const manualInstructions = claimedManual?.instructions;
|
|
2281
2190
|
try {
|
|
@@ -2297,7 +2206,7 @@ export class Runner {
|
|
|
2297
2206
|
...(manualCancelSignal !== undefined ? { manualCancelSignal } : {}),
|
|
2298
2207
|
minTokens: forceManual ? 0 : compactionFloor,
|
|
2299
2208
|
force: forceManual,
|
|
2300
|
-
onInputTruncated: (info) => emitTrace(tracer, () => ({ kind: "compaction.input_truncated", version: 1, taskId, label: info.label, droppedChars: info.droppedChars, keptChars: info.keptChars, ts: Date.now() })),
|
|
2209
|
+
onInputTruncated: (info) => emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.input_truncated", version: 1, taskId: rs.telemetry.taskId, label: info.label, droppedChars: info.droppedChars, keptChars: info.keptChars, ts: Date.now() })),
|
|
2301
2210
|
forceUnderThreshold: trimPressure,
|
|
2302
2211
|
overheadTokens: prepared.promptOverheadTokens,
|
|
2303
2212
|
workingFileAttachments: spec.compaction?.attachWorkingFiles !== false && prepared.readTaskFile
|
|
@@ -2318,10 +2227,10 @@ export class Runner {
|
|
|
2318
2227
|
...this.compactionHookOptions(spec, prepared.sessionId, trimPressure ? "forced" : forceManual ? "manual" : "auto"),
|
|
2319
2228
|
});
|
|
2320
2229
|
if (comp.blocked) {
|
|
2321
|
-
emitTrace(tracer, () => ({
|
|
2230
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
2322
2231
|
kind: "compaction.blocked",
|
|
2323
2232
|
version: 1,
|
|
2324
|
-
taskId,
|
|
2233
|
+
taskId: rs.telemetry.taskId,
|
|
2325
2234
|
trigger: forceManual ? "manual" : "auto",
|
|
2326
2235
|
ts: Date.now(),
|
|
2327
2236
|
}));
|
|
@@ -2335,10 +2244,10 @@ export class Runner {
|
|
|
2335
2244
|
}
|
|
2336
2245
|
if (comp.suppressedByFloor) {
|
|
2337
2246
|
const s = comp.suppressedByFloor;
|
|
2338
|
-
emitTrace(tracer, () => ({
|
|
2247
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
2339
2248
|
kind: "compaction.suppressed",
|
|
2340
2249
|
version: 1,
|
|
2341
|
-
taskId,
|
|
2250
|
+
taskId: rs.telemetry.taskId,
|
|
2342
2251
|
estTokens: s.estTokens,
|
|
2343
2252
|
floor: s.floor,
|
|
2344
2253
|
ts: Date.now(),
|
|
@@ -2347,10 +2256,10 @@ export class Runner {
|
|
|
2347
2256
|
manualOutcome = comp.compacted ? "compacted" : comp.blocked ? "blocked" : comp.disabled ? "disabled" : "noop";
|
|
2348
2257
|
if (forceManual && !comp.compacted && !comp.blocked) {
|
|
2349
2258
|
if (comp.disabled) {
|
|
2350
|
-
emitTrace(tracer, () => ({ kind: "compaction.disabled", version: 1, taskId, ts: Date.now() }));
|
|
2259
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.disabled", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
2351
2260
|
}
|
|
2352
2261
|
else {
|
|
2353
|
-
emitTrace(tracer, () => ({ kind: "compaction.noop", version: 1, taskId, ts: Date.now() }));
|
|
2262
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.noop", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
2354
2263
|
}
|
|
2355
2264
|
}
|
|
2356
2265
|
if (comp.compacted && !forceManual) {
|
|
@@ -2379,24 +2288,23 @@ export class Runner {
|
|
|
2379
2288
|
if (comp.phaseDurations !== undefined && comp.durationMs !== undefined) {
|
|
2380
2289
|
const pd = comp.phaseDurations;
|
|
2381
2290
|
const pdDur = comp.durationMs;
|
|
2382
|
-
emitTrace(tracer, () => ({ kind: "compaction.phase_timings", version: 1, taskId, ...pd, durationMs: pdDur, ts: Date.now() }));
|
|
2291
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.phase_timings", version: 1, taskId: rs.telemetry.taskId, ...pd, durationMs: pdDur, ts: Date.now() }));
|
|
2383
2292
|
}
|
|
2384
2293
|
prepared.cacheBreakDetector?.notifyCompaction();
|
|
2385
|
-
if (attachState !== undefined) {
|
|
2386
|
-
attachState.postCompactPending = true;
|
|
2387
|
-
rebaseCadenceWindows(attachState, cadenceTurns);
|
|
2294
|
+
if (rs.attach.attachState !== undefined) {
|
|
2295
|
+
rs.attach.attachState.postCompactPending = true;
|
|
2296
|
+
rebaseCadenceWindows(rs.attach.attachState, rs.counters.cadenceTurns);
|
|
2388
2297
|
}
|
|
2389
2298
|
if ((comp.freedTokens ?? 0) >= COMPACTION_FREED_EPSILON) {
|
|
2390
2299
|
const postSize = comp.postTriggerTokens ?? Math.max(0, (comp.triggerTokens ?? comp.tokensBefore ?? 0) - (comp.freedTokens ?? 0));
|
|
2391
2300
|
compactionFloor = Math.ceil(postSize * COMPACTION_REGROWTH_FACTOR);
|
|
2392
2301
|
}
|
|
2393
|
-
await this.maybeDynamicRecall(prepared);
|
|
2394
2302
|
}
|
|
2395
2303
|
}
|
|
2396
2304
|
catch (err) {
|
|
2397
2305
|
const manualCancelAbort = !prepared.abortController.signal.aborted && isCompactionManualCancel(err);
|
|
2398
2306
|
if (manualCancelAbort) {
|
|
2399
|
-
emitTrace(tracer, () => ({ kind: "compaction.mooted", version: 1, taskId, reason: "cancelled", ts: Date.now() }));
|
|
2307
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.mooted", version: 1, taskId: rs.telemetry.taskId, reason: "cancelled", ts: Date.now() }));
|
|
2400
2308
|
manualOutcome = "mooted";
|
|
2401
2309
|
}
|
|
2402
2310
|
else if (!prepared.abortController.signal.aborted) {
|
|
@@ -2405,10 +2313,10 @@ export class Runner {
|
|
|
2405
2313
|
compactionBreaker.failures += 1;
|
|
2406
2314
|
this.deps.onError?.(err, { phase: "compaction", sessionId: prepared.sessionId });
|
|
2407
2315
|
const msg = String(err instanceof Error ? err.message : err);
|
|
2408
|
-
emitTrace(tracer, () => ({
|
|
2316
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
2409
2317
|
kind: "compaction.failed",
|
|
2410
2318
|
version: 1,
|
|
2411
|
-
taskId,
|
|
2319
|
+
taskId: rs.telemetry.taskId,
|
|
2412
2320
|
trigger: trimPressure ? "forced" : forceManual ? "manual" : "auto",
|
|
2413
2321
|
reason: walltimeAbort
|
|
2414
2322
|
? "walltime soft-deadline abort (engine-initiated write-out protection; not counted toward the breaker)"
|
|
@@ -2462,13 +2370,13 @@ export class Runner {
|
|
|
2462
2370
|
const walltimeExhaustedResume = effectiveTimeoutMs !== undefined && effectiveTimeoutMs <= 0;
|
|
2463
2371
|
if (!walltimeExhaustedResume && resume.outcome.gate !== "wake") {
|
|
2464
2372
|
await this.applyResumeDecision(prepared, resume, (e) => queue.push(e), emitCommitted, (toolName, details) => {
|
|
2465
|
-
if (attachState === undefined)
|
|
2373
|
+
if (rs.attach.attachState === undefined)
|
|
2466
2374
|
return;
|
|
2467
2375
|
const family = writeFamilyOf(toolName);
|
|
2468
2376
|
if (family !== undefined)
|
|
2469
|
-
stampWriteAnchor(attachState, family, cadenceTurns);
|
|
2377
|
+
stampWriteAnchor(rs.attach.attachState, family, rs.counters.cadenceTurns);
|
|
2470
2378
|
if (details !== undefined)
|
|
2471
|
-
reduceToolEnd(attachState, details);
|
|
2379
|
+
reduceToolEnd(rs.attach.attachState, details);
|
|
2472
2380
|
}, (toolCallId) => {
|
|
2473
2381
|
startedToolCallIds.add(toolCallId);
|
|
2474
2382
|
if (resume !== undefined && resume.cp.pendingAction.kind === "tool_approval" && toolCallId === resume.cp.pendingAction.toolCallId) {
|
|
@@ -2482,8 +2390,8 @@ export class Runner {
|
|
|
2482
2390
|
void prepared.harness.abort();
|
|
2483
2391
|
prepared.abortController.abort();
|
|
2484
2392
|
}
|
|
2485
|
-
else if (maxCostMicroUsd !== undefined && maxCostMicroUsd <= 0) {
|
|
2486
|
-
budgetHit = "exceeded";
|
|
2393
|
+
else if (rs.budget.maxCostMicroUsd !== undefined && rs.budget.maxCostMicroUsd <= 0) {
|
|
2394
|
+
rs.limits.budgetHit = "exceeded";
|
|
2487
2395
|
}
|
|
2488
2396
|
else {
|
|
2489
2397
|
let continuation = resumeContinuation(resume);
|
|
@@ -2524,9 +2432,9 @@ export class Runner {
|
|
|
2524
2432
|
}
|
|
2525
2433
|
}
|
|
2526
2434
|
const firstFrames = [];
|
|
2527
|
-
if (attachState !== undefined) {
|
|
2528
|
-
const attach = attachState;
|
|
2529
|
-
if (agentListingOn && prepared.agentListing !== undefined) {
|
|
2435
|
+
if (rs.attach.attachState !== undefined) {
|
|
2436
|
+
const attach = rs.attach.attachState;
|
|
2437
|
+
if (rs.attach.agentListingOn && prepared.agentListing !== undefined) {
|
|
2530
2438
|
const listing = prepared.agentListing;
|
|
2531
2439
|
const body = renderAgentListingDelta(attach, listing.entries, listing.toolName, listing.models);
|
|
2532
2440
|
if (body !== undefined) {
|
|
@@ -2542,7 +2450,7 @@ export class Runner {
|
|
|
2542
2450
|
});
|
|
2543
2451
|
}
|
|
2544
2452
|
}
|
|
2545
|
-
if (skillsListingOn && prepared.skillsListing !== undefined) {
|
|
2453
|
+
if (rs.attach.skillsListingOn && prepared.skillsListing !== undefined) {
|
|
2546
2454
|
const listing = prepared.skillsListing;
|
|
2547
2455
|
const body = renderSkillsListingDelta(attach, listing.entries);
|
|
2548
2456
|
if (body !== undefined) {
|
|
@@ -2560,7 +2468,7 @@ export class Runner {
|
|
|
2560
2468
|
effectiveObjective = `${firstFrames.map((f) => `<system-reminder>\n${sanitizeUntrustedText(f.body)}\n</system-reminder>`).join("\n")}\n${effectiveObjective}`;
|
|
2561
2469
|
}
|
|
2562
2470
|
}
|
|
2563
|
-
const precallMicroUsd = maxCostMicroUsd === undefined
|
|
2471
|
+
const precallMicroUsd = rs.budget.maxCostMicroUsd === undefined
|
|
2564
2472
|
? 0
|
|
2565
2473
|
: computeCostMicroUsd({
|
|
2566
2474
|
totalInputTokens: Math.ceil(effectiveObjective.length / 4),
|
|
@@ -2568,12 +2476,12 @@ export class Runner {
|
|
|
2568
2476
|
cacheWriteTokens: 0,
|
|
2569
2477
|
cacheWriteTokensLong: 0,
|
|
2570
2478
|
outputTokens: prepared.model.maxTokens ?? 4096,
|
|
2571
|
-
}, pricing);
|
|
2572
|
-
const precallCeilingMicroUsd = prepared.suspendForResource !== undefined ? remainingMicroUsd : maxCostMicroUsd;
|
|
2479
|
+
}, rs.telemetry.pricing);
|
|
2480
|
+
const precallCeilingMicroUsd = prepared.suspendForResource !== undefined ? rs.budget.remainingMicroUsd : rs.budget.maxCostMicroUsd;
|
|
2573
2481
|
if (promptBlocked) {
|
|
2574
2482
|
}
|
|
2575
2483
|
else if (precallCeilingMicroUsd !== undefined && precallMicroUsd > precallCeilingMicroUsd) {
|
|
2576
|
-
budgetHit = "precall";
|
|
2484
|
+
rs.limits.budgetHit = "precall";
|
|
2577
2485
|
}
|
|
2578
2486
|
else if (effectiveTimeoutMs !== undefined && effectiveTimeoutMs <= 0) {
|
|
2579
2487
|
timeout.fired = true;
|
|
@@ -2637,7 +2545,7 @@ export class Runner {
|
|
|
2637
2545
|
const reviewPaused = prepared.reviewRef.token !== undefined && prepared.reviewRef.gate !== undefined;
|
|
2638
2546
|
const durablyPaused = suspended || reviewPaused;
|
|
2639
2547
|
const interrupted = !durablyPaused &&
|
|
2640
|
-
(threw !== undefined || timeout.fired || turnsExceeded || budgetHit !== undefined || abortedLive || final?.stopReason === "aborted");
|
|
2548
|
+
(threw !== undefined || timeout.fired || rs.limits.turnsExceeded || rs.limits.budgetHit !== undefined || abortedLive || final?.stopReason === "aborted");
|
|
2641
2549
|
if (interrupted) {
|
|
2642
2550
|
try {
|
|
2643
2551
|
const report = await reconcileInterruptedSession(prepared.session, prepared.toolEffects, undefined, startedToolCallIds);
|
|
@@ -2662,8 +2570,8 @@ export class Runner {
|
|
|
2662
2570
|
});
|
|
2663
2571
|
}
|
|
2664
2572
|
}
|
|
2665
|
-
if (attachState?.postCompactPending === true && attachmentsCfg?.backgroundTasks === true) {
|
|
2666
|
-
emitTrace(tracer, () => ({ kind: "compaction.announce_dropped", version: 1, taskId, ts: Date.now() }));
|
|
2573
|
+
if (rs.attach.attachState?.postCompactPending === true && rs.attach.attachmentsCfg?.backgroundTasks === true) {
|
|
2574
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.announce_dropped", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
2667
2575
|
}
|
|
2668
2576
|
const comp = await this.finish(spec, prepared, {
|
|
2669
2577
|
skipCompaction: durablyPaused || compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES,
|
|
@@ -2691,7 +2599,7 @@ export class Runner {
|
|
|
2691
2599
|
if (comp.phaseDurations !== undefined && comp.durationMs !== undefined) {
|
|
2692
2600
|
const pd = comp.phaseDurations;
|
|
2693
2601
|
const pdDur = comp.durationMs;
|
|
2694
|
-
emitTrace(tracer, () => ({ kind: "compaction.phase_timings", version: 1, taskId, ...pd, durationMs: pdDur, ts: Date.now() }));
|
|
2602
|
+
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.phase_timings", version: 1, taskId: rs.telemetry.taskId, ...pd, durationMs: pdDur, ts: Date.now() }));
|
|
2695
2603
|
}
|
|
2696
2604
|
prepared.cacheBreakDetector?.notifyCompaction();
|
|
2697
2605
|
}
|
|
@@ -2700,7 +2608,6 @@ export class Runner {
|
|
|
2700
2608
|
tokens: prepared.nestedStats.tokens,
|
|
2701
2609
|
turns: prepared.nestedStats.turns,
|
|
2702
2610
|
tasks: prepared.nestedStats.tasks,
|
|
2703
|
-
costUsd: prepared.nestedStats.costUsd || undefined,
|
|
2704
2611
|
costMicroUsd: prepared.nestedStats.costMicroUsd || undefined,
|
|
2705
2612
|
};
|
|
2706
2613
|
}
|
|
@@ -2710,9 +2617,9 @@ export class Runner {
|
|
|
2710
2617
|
this.deps.onError?.(new Error(`prompt-cache: usage/api mismatch — cachedTokens (${stats.cachedTokens}) > promptTokens (${stats.promptTokens}); the cache family is likely wrong. Does model.api match the brain serving it? Override with model.params.promptCacheFamily = "input-includes-cached" | "input-excludes-cached".`), { phase: "prompt-cache", sessionId: prepared.sessionId });
|
|
2711
2618
|
}
|
|
2712
2619
|
stats.cacheHitRate = Math.min(1, rawHit);
|
|
2713
|
-
if (!cacheBreakReported && stats.turns >= 2 && stats.promptTokens >= 8000 && stats.cacheHitRate < 0.15) {
|
|
2714
|
-
const cause = degraded
|
|
2715
|
-
? `a mid-task model switch (${degraded.from} → ${degraded.to}, degradation) reset the prefix cache — this is the likely cause`
|
|
2620
|
+
if (!rs.telemetry.cacheBreakReported && stats.turns >= 2 && stats.promptTokens >= 8000 && stats.cacheHitRate < 0.15) {
|
|
2621
|
+
const cause = rs.degrade.degraded
|
|
2622
|
+
? `a mid-task model switch (${rs.degrade.degraded.from} → ${rs.degrade.degraded.to}, degradation) reset the prefix cache — this is the likely cause`
|
|
2716
2623
|
: `the cacheable prefix looks unstable. Keep volatile content (memory/timestamps/ids) out of the prompt prefix and tool order stable, or it's a server-side/TTL miss`;
|
|
2717
2624
|
this.deps.onError?.(new Error(`prompt-cache: low prefix-cache hit rate ${(stats.cacheHitRate * 100).toFixed(0)}% over ${stats.turns} turns (${stats.promptTokens} prompt tokens) — ${cause}. See design/09.`), { phase: "prompt-cache", sessionId: prepared.sessionId });
|
|
2718
2625
|
}
|
|
@@ -2720,7 +2627,6 @@ export class Runner {
|
|
|
2720
2627
|
if (prepared.resourceLedger &&
|
|
2721
2628
|
(resume?.cp.gate.kind === "resource_limit" || prepared.suspendRef.gate?.kind === "resource_limit")) {
|
|
2722
2629
|
stats.costMicroUsd += prepared.resourceLedger.spentMicroUsd;
|
|
2723
|
-
stats.costUsd += prepared.resourceLedger.spentMicroUsd / 1e6;
|
|
2724
2630
|
stats.tokens += prepared.resourceLedger.spentTokens;
|
|
2725
2631
|
stats.turns += prepared.resourceLedger.spentTurns;
|
|
2726
2632
|
}
|
|
@@ -2736,34 +2642,34 @@ export class Runner {
|
|
|
2736
2642
|
const toolCuts = prepared.callCapRef?.toolCuts ?? 0;
|
|
2737
2643
|
const pendingCutTools = prepared.callCapRef?.pendingCutTools ?? 0;
|
|
2738
2644
|
const toolCutKills = prepared.cutKills?.kills ?? 0;
|
|
2739
|
-
if (finalizeInjected || nudgesSent > 0 || capShrinks > 0 || callCutoffs > 0 || toolClamps > 0 || toolCuts > 0 || toolCutKills > 0 || pendingCutTools > 0 || finalVerifyInjections > 0 || attachmentsInjected > 0 || repetitionCuts > 0 || repetitionSpared > 0) {
|
|
2645
|
+
if (finalizeInjected || rs.counters.nudgesSent > 0 || capShrinks > 0 || rs.counters.callCutoffs > 0 || toolClamps > 0 || toolCuts > 0 || toolCutKills > 0 || pendingCutTools > 0 || rs.counters.finalVerifyInjections > 0 || attachmentsInjected > 0 || rs.counters.repetitionCuts > 0 || rs.counters.repetitionSpared > 0) {
|
|
2740
2646
|
stats.mechanisms = {
|
|
2741
2647
|
...(finalizeInjected ? { finalizeInjected: true } : {}),
|
|
2742
|
-
...(nudgesSent > 0 ? { nudgesSent } : {}),
|
|
2648
|
+
...(rs.counters.nudgesSent > 0 ? { nudgesSent: rs.counters.nudgesSent } : {}),
|
|
2743
2649
|
...(capShrinks > 0 ? { capShrinks } : {}),
|
|
2744
|
-
...(callCutoffs > 0 ? { callCutoffs } : {}),
|
|
2650
|
+
...(rs.counters.callCutoffs > 0 ? { callCutoffs: rs.counters.callCutoffs } : {}),
|
|
2745
2651
|
...(toolClamps > 0 ? { toolClamps } : {}),
|
|
2746
2652
|
...(toolCuts > 0 ? { toolCuts } : {}),
|
|
2747
2653
|
...(toolCutKills > 0 ? { toolCutKills } : {}),
|
|
2748
2654
|
...(pendingCutTools > 0 ? { pendingCutTools } : {}),
|
|
2749
|
-
...(finalVerifyInjections > 0 ? { finalVerifyInjected: true } : {}),
|
|
2750
|
-
...(finalVerifyInjections > 0 ? { finalVerifyInjections } : {}),
|
|
2655
|
+
...(rs.counters.finalVerifyInjections > 0 ? { finalVerifyInjected: true } : {}),
|
|
2656
|
+
...(rs.counters.finalVerifyInjections > 0 ? { finalVerifyInjections: rs.counters.finalVerifyInjections } : {}),
|
|
2751
2657
|
...(attachmentsInjected > 0 ? { attachmentsInjected } : {}),
|
|
2752
|
-
...(repetitionCuts > 0 ? { repetitionCuts } : {}),
|
|
2753
|
-
...(repetitionSpared > 0 ? { repetitionSpared } : {}),
|
|
2754
|
-
...(repetitionEvents.length > 0 ? { repetitionEvents } : {}),
|
|
2658
|
+
...(rs.counters.repetitionCuts > 0 ? { repetitionCuts: rs.counters.repetitionCuts } : {}),
|
|
2659
|
+
...(rs.counters.repetitionSpared > 0 ? { repetitionSpared: rs.counters.repetitionSpared } : {}),
|
|
2660
|
+
...(rs.counters.repetitionEvents.length > 0 ? { repetitionEvents: rs.counters.repetitionEvents } : {}),
|
|
2755
2661
|
};
|
|
2756
2662
|
}
|
|
2757
2663
|
const result = assembleResult(spec, prepared.sessionId, final, stats, {
|
|
2758
2664
|
threw,
|
|
2759
2665
|
model: prepared.model.id,
|
|
2760
2666
|
abortedForTimeout: timeout.fired,
|
|
2761
|
-
abortedForTurns: turnsExceeded,
|
|
2667
|
+
abortedForTurns: rs.limits.turnsExceeded,
|
|
2762
2668
|
abortedLive,
|
|
2763
|
-
budgetHit,
|
|
2669
|
+
budgetHit: rs.limits.budgetHit,
|
|
2764
2670
|
blockedReason: prepared.blockedRef.reason,
|
|
2765
2671
|
conflict: prepared.conflictRef.hit,
|
|
2766
|
-
outputInvalid,
|
|
2672
|
+
outputInvalid: rs.degrade.outputInvalid,
|
|
2767
2673
|
suspendLoop: prepared.suspendLoopRef.hit,
|
|
2768
2674
|
suspendRef: prepared.suspendRef.token !== undefined && prepared.suspendRef.gate !== undefined
|
|
2769
2675
|
? { token: prepared.suspendRef.token, gate: prepared.suspendRef.gate }
|
|
@@ -2815,8 +2721,8 @@ export class Runner {
|
|
|
2815
2721
|
final.errorMessage !== DEGENERATE_MESSAGE &&
|
|
2816
2722
|
final.errorMessage !== WALLTIME_CUTOFF_MESSAGE &&
|
|
2817
2723
|
threw === undefined &&
|
|
2818
|
-
budgetHit === undefined &&
|
|
2819
|
-
!outputInvalid &&
|
|
2724
|
+
rs.limits.budgetHit === undefined &&
|
|
2725
|
+
!rs.degrade.outputInvalid &&
|
|
2820
2726
|
!prepared.suspendLoopRef.hit &&
|
|
2821
2727
|
!abortedLive &&
|
|
2822
2728
|
result.errorCode !== "conflict") {
|
|
@@ -2835,8 +2741,8 @@ export class Runner {
|
|
|
2835
2741
|
}
|
|
2836
2742
|
}
|
|
2837
2743
|
}
|
|
2838
|
-
if (degraded)
|
|
2839
|
-
result.degraded = degraded;
|
|
2744
|
+
if (rs.degrade.degraded)
|
|
2745
|
+
result.degraded = rs.degrade.degraded;
|
|
2840
2746
|
if (prepared.outputRef.set)
|
|
2841
2747
|
result.structuredOutput = prepared.outputRef.value;
|
|
2842
2748
|
const committedToken = prepared.suspendRef.token ?? prepared.reviewRef.token;
|
|
@@ -2867,16 +2773,16 @@ export class Runner {
|
|
|
2867
2773
|
}
|
|
2868
2774
|
if (prepared.memoryEngineSession)
|
|
2869
2775
|
await prepared.memoryEngineSession.harvest();
|
|
2870
|
-
emitTrace(tracer, () => ({
|
|
2776
|
+
emitTrace(rs.telemetry.tracer, () => ({
|
|
2871
2777
|
kind: "task.end",
|
|
2872
2778
|
version: 1,
|
|
2873
|
-
taskId,
|
|
2779
|
+
taskId: rs.telemetry.taskId,
|
|
2874
2780
|
status: result.status,
|
|
2875
2781
|
errorCode: result.errorCode,
|
|
2876
2782
|
turns: stats.turns,
|
|
2877
2783
|
tokens: stats.tokens,
|
|
2878
2784
|
costMicroUsd: stats.costMicroUsd,
|
|
2879
|
-
durationMs: Date.now() - taskStart,
|
|
2785
|
+
durationMs: Date.now() - rs.telemetry.taskStart,
|
|
2880
2786
|
...(prepared.outputRef.set ? { hasStructuredOutput: true } : {}),
|
|
2881
2787
|
...(stats.mechanisms !== undefined
|
|
2882
2788
|
? { mechanisms: (({ repetitionEvents: _events, ...scalars }) => scalars)(stats.mechanisms) }
|
|
@@ -2891,10 +2797,10 @@ export class Runner {
|
|
|
2891
2797
|
if (parentToolCallId !== undefined && (result.status === "completed" || result.status === "failed" || result.status === "timeout" || result.status === "blocked")) {
|
|
2892
2798
|
const terminalTick = {
|
|
2893
2799
|
type: "task_progress",
|
|
2894
|
-
taskId,
|
|
2800
|
+
taskId: rs.telemetry.taskId,
|
|
2895
2801
|
...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}),
|
|
2896
2802
|
...(subagentName ? { name: subagentName } : {}),
|
|
2897
|
-
usage: { totalTokens: stats.tokens, toolUses: stats.toolCalls, durationMs: Date.now() - taskStart },
|
|
2803
|
+
usage: { totalTokens: stats.tokens, toolUses: stats.toolCalls, durationMs: Date.now() - rs.telemetry.taskStart },
|
|
2898
2804
|
status: result.status === "completed" ? "completed" : "failed",
|
|
2899
2805
|
...ident(),
|
|
2900
2806
|
};
|
|
@@ -2910,9 +2816,6 @@ export class Runner {
|
|
|
2910
2816
|
if (spec.rewindFiles && result.status === "completed") {
|
|
2911
2817
|
await this.snapshotTurn(prepared);
|
|
2912
2818
|
}
|
|
2913
|
-
if (prepared.consolidation && prepared.consolidation.notes.length > 0) {
|
|
2914
|
-
onConsolidation(this.consolidateMemory(spec, prepared, result));
|
|
2915
|
-
}
|
|
2916
2819
|
if (spec.suggestNextPrompts && result.status === "completed") {
|
|
2917
2820
|
onSuggestions(this.suggestNextPrompts(spec, prepared, result));
|
|
2918
2821
|
}
|
|
@@ -2927,8 +2830,8 @@ export class Runner {
|
|
|
2927
2830
|
await defaultTaskRegistry.settleKilledForOwner({ owner: spec.taskId ?? prepared.sessionId, scope: spec.principal ?? "default", sessionId: prepared.sessionId }, {
|
|
2928
2831
|
source: abortedLive &&
|
|
2929
2832
|
!timeout.fired &&
|
|
2930
|
-
!turnsExceeded &&
|
|
2931
|
-
budgetHit === undefined &&
|
|
2833
|
+
!rs.limits.turnsExceeded &&
|
|
2834
|
+
rs.limits.budgetHit === undefined &&
|
|
2932
2835
|
prepared.suspendRef.token === undefined &&
|
|
2933
2836
|
prepared.reviewRef.token === undefined
|
|
2934
2837
|
? "user"
|
|
@@ -2981,67 +2884,6 @@ export class Runner {
|
|
|
2981
2884
|
await this.teardownOwnedEnv(prepared);
|
|
2982
2885
|
}
|
|
2983
2886
|
}
|
|
2984
|
-
async consolidateMemory(spec, prepared, result) {
|
|
2985
|
-
const consolidation = prepared.consolidation;
|
|
2986
|
-
if (!consolidation || !this.deps.memoryStore) {
|
|
2987
|
-
return;
|
|
2988
|
-
}
|
|
2989
|
-
const { scope, notes, settings } = consolidation;
|
|
2990
|
-
const onWarn = (err) => {
|
|
2991
|
-
try {
|
|
2992
|
-
this.deps.onError?.(err, { phase: "memory", sessionId: prepared.sessionId });
|
|
2993
|
-
}
|
|
2994
|
-
catch {
|
|
2995
|
-
}
|
|
2996
|
-
};
|
|
2997
|
-
const ac = new AbortController();
|
|
2998
|
-
const timer = settings.timeoutSec > 0 ? setTimeout(() => ac.abort(), settings.timeoutSec * 1000) : undefined;
|
|
2999
|
-
timer?.unref?.();
|
|
3000
|
-
try {
|
|
3001
|
-
let model = prepared.model;
|
|
3002
|
-
let thinking = prepared.thinking;
|
|
3003
|
-
try {
|
|
3004
|
-
const resolved = resolveTaskModel({ modelRole: settings.role, roles: spec.roles }, this.deps);
|
|
3005
|
-
model = resolved.model;
|
|
3006
|
-
thinking = resolved.thinking;
|
|
3007
|
-
}
|
|
3008
|
-
catch {
|
|
3009
|
-
}
|
|
3010
|
-
const pricing = this.deps.pricing?.[model.id] ?? modelCostToPricing(model.cost);
|
|
3011
|
-
const stats = await runMemoryConsolidation({
|
|
3012
|
-
store: this.deps.memoryStore,
|
|
3013
|
-
scope,
|
|
3014
|
-
notes,
|
|
3015
|
-
band: settings.band,
|
|
3016
|
-
searchLimit: settings.searchLimit,
|
|
3017
|
-
maxNotes: settings.maxNotes,
|
|
3018
|
-
onWarn,
|
|
3019
|
-
llm: {
|
|
3020
|
-
brain: this.deps.brain,
|
|
3021
|
-
model,
|
|
3022
|
-
pricing,
|
|
3023
|
-
thinking,
|
|
3024
|
-
getApiKeyAndHeaders: spec.getApiKeyAndHeaders,
|
|
3025
|
-
signal: ac.signal,
|
|
3026
|
-
},
|
|
3027
|
-
});
|
|
3028
|
-
await advanceCursorAfterInline(this.deps.memoryStore, scope, stats?.consolidatedIds ?? [], stats?.addedIds ?? [], stats?.failedIds ?? [], onWarn);
|
|
3029
|
-
if (stats) {
|
|
3030
|
-
result.stats.memory = { tokens: stats.tokens, costMicroUsd: stats.costMicroUsd, applied: stats.applied };
|
|
3031
|
-
if (result.stats.costBreakdown) {
|
|
3032
|
-
result.stats.costBreakdown.memoryConsolidationMicroUsd = stats.costMicroUsd;
|
|
3033
|
-
}
|
|
3034
|
-
}
|
|
3035
|
-
}
|
|
3036
|
-
catch (err) {
|
|
3037
|
-
onWarn(err);
|
|
3038
|
-
}
|
|
3039
|
-
finally {
|
|
3040
|
-
if (timer) {
|
|
3041
|
-
clearTimeout(timer);
|
|
3042
|
-
}
|
|
3043
|
-
}
|
|
3044
|
-
}
|
|
3045
2887
|
async suggestNextPrompts(spec, prepared, result) {
|
|
3046
2888
|
const cfg = typeof spec.suggestNextPrompts === "object" ? spec.suggestNextPrompts : {};
|
|
3047
2889
|
const count = cfg.count && cfg.count > 0 ? Math.min(cfg.count, SUGGESTIONS_MAX_COUNT) : SUGGESTIONS_DEFAULT_COUNT;
|
|
@@ -3471,40 +3313,6 @@ export class Runner {
|
|
|
3471
3313
|
consecutiveProviderReuse: prepared.compactionReuseRef.consecutive,
|
|
3472
3314
|
};
|
|
3473
3315
|
}
|
|
3474
|
-
async maybeDynamicRecall(prepared) {
|
|
3475
|
-
const dr = prepared.dynamicRecall;
|
|
3476
|
-
if (!dr)
|
|
3477
|
-
return;
|
|
3478
|
-
try {
|
|
3479
|
-
const cfg = this.deps.dynamicRecall;
|
|
3480
|
-
const { messages } = await prepared.session.buildContext();
|
|
3481
|
-
const query = buildRecallQuery(messages, cfg?.recentMessageWindow, cfg?.maxQueryChars);
|
|
3482
|
-
if (query.length === 0)
|
|
3483
|
-
return;
|
|
3484
|
-
const outcome = await runDynamicRecall({
|
|
3485
|
-
store: this.deps.memoryStore,
|
|
3486
|
-
scopes: dr.scopes,
|
|
3487
|
-
selector: dr.selector,
|
|
3488
|
-
query,
|
|
3489
|
-
recentTools: dr.recentTools,
|
|
3490
|
-
maxSelected: this.deps.memoryRecall?.maxSelected,
|
|
3491
|
-
maxLinked: this.deps.memoryRecall?.maxLinked,
|
|
3492
|
-
timeoutMs: this.deps.memoryRecall?.timeoutMs,
|
|
3493
|
-
signal: prepared.abortController.signal,
|
|
3494
|
-
priorSurfacedIds: dr.surfacedIds,
|
|
3495
|
-
priorSurfacedKeys: dr.surfacedKeys,
|
|
3496
|
-
});
|
|
3497
|
-
if (!outcome.block)
|
|
3498
|
-
return;
|
|
3499
|
-
for (const id of outcome.surfacedIds)
|
|
3500
|
-
dr.surfacedIds.add(id);
|
|
3501
|
-
for (const k of outcome.surfacedKeys)
|
|
3502
|
-
dr.surfacedKeys.add(k);
|
|
3503
|
-
await prepared.harness.steer(outcome.block, { provenance: "engine-note" });
|
|
3504
|
-
}
|
|
3505
|
-
catch {
|
|
3506
|
-
}
|
|
3507
|
-
}
|
|
3508
3316
|
compactionHookOptions(spec, sessionId, trigger) {
|
|
3509
3317
|
const hooks = spec.hooks ?? this.deps.hooks;
|
|
3510
3318
|
const pre = hooks?.preCompact;
|