@caupulican/pi-adaptative 0.94.1 → 0.95.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/README.md +32 -13
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +7 -4
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +173 -293
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +247 -392
- package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.d.ts +52 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.d.ts.map +1 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.js +118 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.js.map +1 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.ts +169 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/templates/builder-validator.json +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/templates/provider-prompt-smoke.json +1 -1
- package/dist/bundled-resources/skills/pi-harness-learning/SKILL.md +13 -7
- package/dist/bundled-resources/skills/worker-profile-writer/SKILL.md +11 -11
- package/dist/core/agent-session.d.ts +11 -41
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +93 -160
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.d.ts +6 -1
- package/dist/core/autonomy/envelope-enforcement.d.ts.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.js +26 -25
- package/dist/core/autonomy/envelope-enforcement.js.map +1 -1
- package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -1
- package/dist/core/autonomy/lane-private-paths.js +2 -1
- package/dist/core/autonomy/lane-private-paths.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +8 -8
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +45 -30
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/worker-session-private-scope.d.ts +12 -0
- package/dist/core/autonomy/worker-session-private-scope.d.ts.map +1 -0
- package/dist/core/autonomy/worker-session-private-scope.js +42 -0
- package/dist/core/autonomy/worker-session-private-scope.js.map +1 -0
- package/dist/core/autonomy/worker-tool-adapter-registry.d.ts +65 -0
- package/dist/core/autonomy/worker-tool-adapter-registry.d.ts.map +1 -0
- package/dist/core/autonomy/worker-tool-adapter-registry.js +145 -0
- package/dist/core/autonomy/worker-tool-adapter-registry.js.map +1 -0
- package/dist/core/background-lane-controller.d.ts +1 -1
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +1 -1
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/background-tool-task-controller.d.ts +8 -2
- package/dist/core/background-tool-task-controller.d.ts.map +1 -1
- package/dist/core/background-tool-task-controller.js +10 -2
- package/dist/core/background-tool-task-controller.js.map +1 -1
- package/dist/core/cost-guard-controller.d.ts +37 -0
- package/dist/core/cost-guard-controller.d.ts.map +1 -0
- package/dist/core/cost-guard-controller.js +71 -0
- package/dist/core/cost-guard-controller.js.map +1 -0
- package/dist/core/cost-guard.d.ts +9 -4
- package/dist/core/cost-guard.d.ts.map +1 -1
- package/dist/core/cost-guard.js +7 -3
- package/dist/core/cost-guard.js.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.d.ts +1 -1
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.js +0 -1
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.d.ts +16 -3
- package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.js +114 -55
- package/dist/core/delegation/worker-authority-resolver.js.map +1 -1
- package/dist/core/delegation/worker-claim.d.ts +1 -2
- package/dist/core/delegation/worker-claim.d.ts.map +1 -1
- package/dist/core/delegation/worker-claim.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +19 -6
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +125 -40
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-delegation-request.d.ts +3 -3
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js +13 -19
- package/dist/core/delegation/worker-delegation-request.js.map +1 -1
- package/dist/core/delegation/worker-execution-policy.d.ts +3 -2
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
- package/dist/core/delegation/worker-execution-policy.js +54 -39
- package/dist/core/delegation/worker-execution-policy.js.map +1 -1
- package/dist/core/delegation/worker-fleet-limits.d.ts +3 -3
- package/dist/core/delegation/worker-fleet-limits.d.ts.map +1 -1
- package/dist/core/delegation/worker-fleet-limits.js +7 -7
- package/dist/core/delegation/worker-fleet-limits.js.map +1 -1
- package/dist/core/delegation/worker-machine-scope.d.ts +12 -0
- package/dist/core/delegation/worker-machine-scope.d.ts.map +1 -0
- package/dist/core/delegation/worker-machine-scope.js +38 -0
- package/dist/core/delegation/worker-machine-scope.js.map +1 -0
- package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.js +6 -1
- package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-runner.d.ts +5 -7
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +1 -4
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +3 -2
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-write-reservation-coordinator.js +50 -25
- package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -1
- package/dist/core/durable-custom-message-turn-controller.d.ts +6 -0
- package/dist/core/durable-custom-message-turn-controller.d.ts.map +1 -1
- package/dist/core/durable-custom-message-turn-controller.js +38 -15
- package/dist/core/durable-custom-message-turn-controller.js.map +1 -1
- package/dist/core/extension-binding-controller.d.ts +5 -1
- package/dist/core/extension-binding-controller.d.ts.map +1 -1
- package/dist/core/extension-binding-controller.js +15 -0
- package/dist/core/extension-binding-controller.js.map +1 -1
- package/dist/core/extensions/factory-runtime.d.ts.map +1 -1
- package/dist/core/extensions/factory-runtime.js +5 -0
- package/dist/core/extensions/factory-runtime.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +8 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/foreground-terminal-handoff-controller.d.ts +14 -0
- package/dist/core/foreground-terminal-handoff-controller.d.ts.map +1 -1
- package/dist/core/foreground-terminal-handoff-controller.js +188 -72
- package/dist/core/foreground-terminal-handoff-controller.js.map +1 -1
- package/dist/core/goals/goal-session-controller.d.ts +2 -0
- package/dist/core/goals/goal-session-controller.d.ts.map +1 -1
- package/dist/core/goals/goal-session-controller.js +8 -0
- package/dist/core/goals/goal-session-controller.js.map +1 -1
- package/dist/core/goals/goal-tool-core.d.ts +5 -4
- package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
- package/dist/core/goals/goal-tool-core.js +23 -19
- package/dist/core/goals/goal-tool-core.js.map +1 -1
- package/dist/core/learning/auto-learn-settings.d.ts +84 -0
- package/dist/core/learning/auto-learn-settings.d.ts.map +1 -0
- package/dist/core/learning/auto-learn-settings.js +66 -0
- package/dist/core/learning/auto-learn-settings.js.map +1 -0
- package/dist/core/learning/reflection-engine.d.ts +4 -0
- package/dist/core/learning/reflection-engine.d.ts.map +1 -1
- package/dist/core/learning/reflection-engine.js +48 -10
- package/dist/core/learning/reflection-engine.js.map +1 -1
- package/dist/core/local-prefix-warm-controller.d.ts +24 -0
- package/dist/core/local-prefix-warm-controller.d.ts.map +1 -0
- package/dist/core/local-prefix-warm-controller.js +79 -0
- package/dist/core/local-prefix-warm-controller.js.map +1 -0
- package/dist/core/memory/providers/file-store.d.ts +2 -0
- package/dist/core/memory/providers/file-store.d.ts.map +1 -1
- package/dist/core/memory/providers/file-store.js +71 -15
- package/dist/core/memory/providers/file-store.js.map +1 -1
- package/dist/core/memory/worker-memory-tools.d.ts +5 -0
- package/dist/core/memory/worker-memory-tools.d.ts.map +1 -0
- package/dist/core/memory/worker-memory-tools.js +5 -0
- package/dist/core/memory/worker-memory-tools.js.map +1 -0
- package/dist/core/model-capability.d.ts +7 -0
- package/dist/core/model-capability.d.ts.map +1 -1
- package/dist/core/model-capability.js +12 -0
- package/dist/core/model-capability.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +2 -10
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +3 -2
- package/dist/core/model-router-controller.d.ts.map +1 -1
- package/dist/core/model-router-controller.js +3 -2
- package/dist/core/model-router-controller.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +16 -12
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +2 -2
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.d.ts +2 -2
- package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.js +6 -1
- package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
- package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
- package/dist/core/orchestration/profile-registry.js +14 -0
- package/dist/core/orchestration/profile-registry.js.map +1 -1
- package/dist/core/orchestration/task-profile-writer.d.ts +7 -4
- package/dist/core/orchestration/task-profile-writer.d.ts.map +1 -1
- package/dist/core/orchestration/task-profile-writer.js +71 -59
- package/dist/core/orchestration/task-profile-writer.js.map +1 -1
- package/dist/core/orchestration/thinking-level-schema.d.ts +7 -0
- package/dist/core/orchestration/thinking-level-schema.d.ts.map +1 -0
- package/dist/core/orchestration/thinking-level-schema.js +19 -0
- package/dist/core/orchestration/thinking-level-schema.js.map +1 -0
- package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.js +12 -5
- package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
- package/dist/core/provider-prompt-contracts.d.ts +1 -4
- package/dist/core/provider-prompt-contracts.d.ts.map +1 -1
- package/dist/core/provider-prompt-contracts.js +4 -10
- package/dist/core/provider-prompt-contracts.js.map +1 -1
- package/dist/core/provider-request-context-controller.d.ts +2 -0
- package/dist/core/provider-request-context-controller.d.ts.map +1 -1
- package/dist/core/provider-request-context-controller.js +10 -3
- package/dist/core/provider-request-context-controller.js.map +1 -1
- package/dist/core/reflection-controller.d.ts +56 -27
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +206 -117
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +1 -0
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +25 -14
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -1
- package/dist/core/secrets/credential-exposure-guard.js +55 -10
- package/dist/core/secrets/credential-exposure-guard.js.map +1 -1
- package/dist/core/session-role.d.ts +6 -8
- package/dist/core/session-role.d.ts.map +1 -1
- package/dist/core/session-role.js +8 -18
- package/dist/core/session-role.js.map +1 -1
- package/dist/core/settings-manager.d.ts +13 -16
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +53 -50
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skill-vault.d.ts +15 -0
- package/dist/core/skill-vault.d.ts.map +1 -1
- package/dist/core/skill-vault.js +79 -45
- package/dist/core/skill-vault.js.map +1 -1
- package/dist/core/skills.d.ts +3 -0
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +6 -6
- package/dist/core/skills.js.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +2 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.js +52 -12
- package/dist/core/system-prompt-builder.js.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tool-capability-policy.d.ts +3 -0
- package/dist/core/tool-capability-policy.d.ts.map +1 -1
- package/dist/core/tool-capability-policy.js +13 -2
- package/dist/core/tool-capability-policy.js.map +1 -1
- package/dist/core/toolkit/script-runner.d.ts +2 -1
- package/dist/core/toolkit/script-runner.d.ts.map +1 -1
- package/dist/core/toolkit/script-runner.js +10 -2
- package/dist/core/toolkit/script-runner.js.map +1 -1
- package/dist/core/tools/delegate-status.d.ts +1 -1
- package/dist/core/tools/delegate-status.d.ts.map +1 -1
- package/dist/core/tools/delegate-status.js +1 -1
- package/dist/core/tools/delegate-status.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +4 -15
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +111 -73
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/goal.d.ts +3 -4
- package/dist/core/tools/goal.d.ts.map +1 -1
- package/dist/core/tools/goal.js +24 -7
- package/dist/core/tools/goal.js.map +1 -1
- package/dist/core/tools/profile-writer.d.ts +2 -8
- package/dist/core/tools/profile-writer.d.ts.map +1 -1
- package/dist/core/tools/profile-writer.js +6 -18
- package/dist/core/tools/profile-writer.js.map +1 -1
- package/dist/core/tools/run-toolkit-script.d.ts +1 -1
- package/dist/core/tools/run-toolkit-script.d.ts.map +1 -1
- package/dist/core/tools/run-toolkit-script.js +2 -2
- package/dist/core/tools/run-toolkit-script.js.map +1 -1
- package/dist/core/tools/skill-audit.d.ts +28 -1
- package/dist/core/tools/skill-audit.d.ts.map +1 -1
- package/dist/core/tools/skill-audit.js +56 -12
- package/dist/core/tools/skill-audit.js.map +1 -1
- package/dist/core/tools/skill.d.ts +12 -1
- package/dist/core/tools/skill.d.ts.map +1 -1
- package/dist/core/tools/skill.js +52 -0
- package/dist/core/tools/skill.js.map +1 -1
- package/dist/core/tools/skillify.d.ts.map +1 -1
- package/dist/core/tools/skillify.js +16 -7
- package/dist/core/tools/skillify.js.map +1 -1
- package/dist/core/tools/task-steps.js +1 -1
- package/dist/core/tools/task-steps.js.map +1 -1
- package/dist/core/tools/tmux-dispatch.d.ts +4 -16
- package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
- package/dist/core/tools/tmux-dispatch.js +5 -20
- package/dist/core/tools/tmux-dispatch.js.map +1 -1
- package/dist/core/worktree-sync/codes.d.ts +1 -2
- package/dist/core/worktree-sync/codes.d.ts.map +1 -1
- package/dist/core/worktree-sync/codes.js +1 -2
- package/dist/core/worktree-sync/codes.js.map +1 -1
- package/dist/core/worktree-sync/lane-gate.d.ts +4 -8
- package/dist/core/worktree-sync/lane-gate.d.ts.map +1 -1
- package/dist/core/worktree-sync/lane-gate.js +5 -51
- package/dist/core/worktree-sync/lane-gate.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/auto-learn-controller.d.ts +6 -7
- package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -1
- package/dist/modes/interactive/auto-learn-controller.js +30 -207
- package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
- package/dist/modes/interactive/autonomy-commands.js +2 -2
- package/dist/modes/interactive/autonomy-commands.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +17 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/fitness-role-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/fitness-role-selector.js +2 -2
- package/dist/modes/interactive/components/fitness-role-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +150 -73
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/report-commands.d.ts.map +1 -1
- package/dist/modes/interactive/report-commands.js +8 -4
- package/dist/modes/interactive/report-commands.js.map +1 -1
- package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -1
- package/dist/modes/interactive/settings-selector-flow.js +10 -0
- package/dist/modes/interactive/settings-selector-flow.js.map +1 -1
- package/docs/extensions.md +8 -0
- package/docs/harness-architecture.md +28 -32
- package/docs/index.md +1 -1
- package/docs/process-matrix.md +8 -6
- package/docs/resources.md +1 -1
- package/docs/settings.md +61 -51
- package/docs/tmux-agent-manager.md +47 -40
- package/docs/usage.md +1 -1
- package/docs/worker-profiles.md +8 -6
- package/docs/worktree-sync.md +26 -20
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +0 -133
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +0 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +0 -199
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +0 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +0 -312
|
@@ -14,6 +14,7 @@ const RECORD_KEYS = [
|
|
|
14
14
|
"taskId",
|
|
15
15
|
"toolCallId",
|
|
16
16
|
"toolName",
|
|
17
|
+
"goalId",
|
|
17
18
|
"status",
|
|
18
19
|
"startedAt",
|
|
19
20
|
"completedAt",
|
|
@@ -62,18 +63,21 @@ export function loadBackgroundToolTaskRecordsNewestFirst(sessionManager) {
|
|
|
62
63
|
fromId = entry.parentId;
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
|
-
export function createBackgroundToolTerminalMessage(records) {
|
|
66
|
+
export function createBackgroundToolTerminalMessage(records, options) {
|
|
66
67
|
if (records.length === 0)
|
|
67
68
|
throw new TypeError("Background tool terminal handoff requires at least one record");
|
|
68
69
|
const included = records.slice(0, MAX_TERMINAL_HANDOFF_RECORDS);
|
|
69
70
|
const omitted = records.length - included.length;
|
|
71
|
+
const wakeParent = options?.wakeParent ?? true;
|
|
70
72
|
return {
|
|
71
73
|
customType: "background-tool-completion",
|
|
72
74
|
content: [
|
|
73
75
|
"Background tool terminal handoff:",
|
|
74
76
|
...included.map((record) => `- ${record.taskId}: ${record.status} tool=${record.toolName}`),
|
|
75
77
|
...(omitted > 0 ? [`- ${omitted} additional terminal tool task(s) omitted.`] : []),
|
|
76
|
-
|
|
78
|
+
...(wakeParent
|
|
79
|
+
? ["Parent woke. Need result: tool_task action=wait once; never poll."]
|
|
80
|
+
: ["Parent was not woken because the owning goal is no longer active. Wait for explicit user input."]),
|
|
77
81
|
].join("\n"),
|
|
78
82
|
display: true,
|
|
79
83
|
details: {
|
|
@@ -159,6 +163,7 @@ function decodeRecord(value, sessionIds) {
|
|
|
159
163
|
(value.completedAt !== undefined &&
|
|
160
164
|
(typeof value.completedAt !== "string" || !Number.isFinite(Date.parse(value.completedAt)))) ||
|
|
161
165
|
(value.status !== "running" && value.completedAt === undefined) ||
|
|
166
|
+
(value.goalId !== undefined && (typeof value.goalId !== "string" || value.goalId.length === 0)) ||
|
|
162
167
|
typeof value.elapsedBeforeHandoffMs !== "number" ||
|
|
163
168
|
!Number.isFinite(value.elapsedBeforeHandoffMs) ||
|
|
164
169
|
value.elapsedBeforeHandoffMs < 0 ||
|
|
@@ -180,6 +185,7 @@ function decodeRecord(value, sessionIds) {
|
|
|
180
185
|
taskId: value.taskId,
|
|
181
186
|
toolCallId: value.toolCallId,
|
|
182
187
|
toolName: value.toolName,
|
|
188
|
+
...(value.goalId ? { goalId: value.goalId } : {}),
|
|
183
189
|
status: value.status,
|
|
184
190
|
startedAt: value.startedAt,
|
|
185
191
|
...(value.completedAt ? { completedAt: value.completedAt } : {}),
|
|
@@ -218,11 +224,13 @@ export class BackgroundToolTaskController {
|
|
|
218
224
|
const sessionId = this.deps.getSessionId();
|
|
219
225
|
const taskId = `tool-task-${this.nextTaskId++}`;
|
|
220
226
|
const startedAt = this.now().toISOString();
|
|
227
|
+
const goalId = this.deps.getGoalId?.();
|
|
221
228
|
const record = {
|
|
222
229
|
sessionId,
|
|
223
230
|
taskId,
|
|
224
231
|
toolCallId: context.toolCall.id,
|
|
225
232
|
toolName: context.toolCall.name,
|
|
233
|
+
...(goalId ? { goalId } : {}),
|
|
226
234
|
status: "running",
|
|
227
235
|
startedAt,
|
|
228
236
|
elapsedBeforeHandoffMs: context.elapsedMs,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"background-tool-task-controller.js","sourceRoot":"","sources":["../../src/core/background-tool-task-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tBackgroundToolCallCompletion,\n\tBackgroundToolCallContext,\n\tBackgroundToolCallHandoff,\n} from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Usage } from \"@caupulican/pi-ai\";\nimport type { ArtifactStore } from \"./context/context-artifacts.ts\";\nimport { formatArtifactNotice, packToolOutput } from \"./context/tool-output-packer.ts\";\nimport { hasOnlyKeys, isPlainRecord } from \"./util/value-guards.ts\";\n\nexport const DEFAULT_BACKGROUND_TOOL_CALL_AFTER_MS = 15_000;\nexport const DEFAULT_BACKGROUND_TOOL_TASK_WAIT_TIMEOUT_MS = 30_000;\nexport const BACKGROUND_TOOL_TASK_CUSTOM_TYPE = \"background_tool_task\";\n\nconst MAX_RETAINED_TERMINAL_TASKS = 64;\nconst MAX_INLINE_OUTPUT_BYTES = 32 * 1024;\nconst MAX_INLINE_OUTPUT_LINES = 400;\nconst MAX_SUMMARY_CHARS = 200;\nconst MAX_TERMINAL_HANDOFF_RECORDS = 8;\nconst TASK_ID_PATTERN = /^tool-task-([1-9]\\d*)$/;\nconst RECORD_KEYS = [\n\t\"sessionId\",\n\t\"taskId\",\n\t\"toolCallId\",\n\t\"toolName\",\n\t\"status\",\n\t\"startedAt\",\n\t\"completedAt\",\n\t\"elapsedBeforeHandoffMs\",\n\t\"summary\",\n\t\"output\",\n\t\"artifactId\",\n\t\"usage\",\n\t\"cancellationRequested\",\n\t\"terminalDelivery\",\n] as const;\n\nexport type BackgroundToolTaskStatus = \"running\" | \"completed\" | \"failed\" | \"canceled\";\nexport type BackgroundToolTerminalDelivery = \"pending\" | \"delivered\";\n\nexport type BackgroundToolTaskRef = Pick<BackgroundToolTaskRecord, \"taskId\" | \"toolCallId\" | \"status\">;\n\n/** Match a goal/task_steps evidence uri to a session background tool task by task id or toolCallId. */\nexport function findBackgroundToolTask<T extends BackgroundToolTaskRef>(\n\trecords: readonly T[],\n\turi: string,\n): T | undefined {\n\tconst id = uri.trim();\n\tif (!id) return undefined;\n\treturn records.find((record) => record.taskId === id || record.toolCallId === id);\n}\n\n/** True only when the cited background task finished successfully. Undefined when no task matches. */\nexport function isCompletedBackgroundToolEvidence(\n\trecords: readonly BackgroundToolTaskRef[],\n\turi: string,\n): boolean | undefined {\n\tconst task = findBackgroundToolTask(records, uri);\n\tif (!task) return undefined;\n\treturn task.status === \"completed\";\n}\n\nexport function collectCitedRunningToolTaskIds(args: {\n\trecords: readonly BackgroundToolTaskRef[];\n\turis: readonly string[];\n}): string[] {\n\tconst running = new Set<string>();\n\tfor (const uri of args.uris) {\n\t\tconst task = findBackgroundToolTask(args.records, uri);\n\t\tif (task?.status === \"running\") running.add(task.taskId);\n\t}\n\treturn [...running];\n}\n\nexport interface BackgroundToolTaskRecord {\n\tsessionId: string;\n\ttaskId: string;\n\ttoolCallId: string;\n\ttoolName: string;\n\tstatus: BackgroundToolTaskStatus;\n\tstartedAt: string;\n\tcompletedAt?: string;\n\telapsedBeforeHandoffMs: number;\n\tsummary: string;\n\toutput: string;\n\tartifactId?: string;\n\tusage?: Usage;\n\tcancellationRequested?: boolean;\n\t/** Durable terminal handoff state. Undefined on legacy records, which are treated as delivered. */\n\tterminalDelivery?: BackgroundToolTerminalDelivery;\n\t/** Runtime-only receipt; never serialized into the durable task record. */\n\tobservedAt?: string;\n}\n\nexport interface BackgroundToolTaskLiveView {\n\ttaskId: string;\n\ttoolCallId: string;\n\ttoolName: string;\n\tdescription: string;\n}\n\nexport interface BackgroundToolTerminalMessage {\n\tcustomType: \"background-tool-completion\";\n\tcontent: string;\n\tdisplay: true;\n\tdetails: {\n\t\trecords: Array<{\n\t\t\ttaskId: string;\n\t\t\tstatus: BackgroundToolTaskStatus;\n\t\t\ttoolName: string;\n\t\t\tartifactId?: string;\n\t\t}>;\n\t};\n}\n\nexport interface BackgroundToolTaskControllerDeps {\n\tgetSessionId(): string;\n\t/** Current session followed by the authoritative fork ancestry whose branch records remain visible. */\n\tgetSessionLineageIds?(): readonly string[];\n\tgetArtifactStore(): ArtifactStore | undefined;\n\t/** Durable task records on the active branch, newest first, without rebuilding full model context. */\n\tloadPersistedRecordsNewestFirst?(): readonly unknown[];\n\tpersist(record: BackgroundToolTaskRecord): void;\n\tnotifyTerminal(records: readonly BackgroundToolTaskRecord[], options: { wakeParent: boolean }): Promise<void> | void;\n\tonLiveTasksChanged?(tasks: readonly BackgroundToolTaskLiveView[]): void;\n\trecordUsage?(taskId: string, usage: Usage): void;\n\tonError?(message: string, error: unknown): void;\n\tnow?(): Date;\n\t/** Event-wait watchdog; completion still arrives through the terminal handoff after this bound. */\n\twaitTimeoutMs?: number;\n}\n\ninterface BackgroundToolTaskState {\n\trecord: BackgroundToolTaskRecord;\n\tcancel: () => void;\n\tcancellationRequested: boolean;\n\twaitingConsumers: number;\n\tterminal: Promise<BackgroundToolTaskRecord>;\n\tresolveTerminal: (record: BackgroundToolTaskRecord) => void;\n\tartifactHolderId: string;\n}\n\n/** Read only task records on the active branch without allocating or hydrating the full branch context. */\nexport function loadBackgroundToolTaskRecordsNewestFirst(\n\tsessionManager: Pick<SessionManager, \"getLatestCustomEntryOnBranch\">,\n): unknown[] {\n\tconst records: unknown[] = [];\n\tlet fromId: string | undefined;\n\tfor (;;) {\n\t\tconst entry = sessionManager.getLatestCustomEntryOnBranch(BACKGROUND_TOOL_TASK_CUSTOM_TYPE, fromId);\n\t\tif (!entry) return records;\n\t\trecords.push(entry.data);\n\t\tif (entry.parentId === null) return records;\n\t\tfromId = entry.parentId;\n\t}\n}\n\nexport function createBackgroundToolTerminalMessage(\n\trecords: readonly BackgroundToolTaskRecord[],\n): BackgroundToolTerminalMessage {\n\tif (records.length === 0) throw new TypeError(\"Background tool terminal handoff requires at least one record\");\n\tconst included = records.slice(0, MAX_TERMINAL_HANDOFF_RECORDS);\n\tconst omitted = records.length - included.length;\n\treturn {\n\t\tcustomType: \"background-tool-completion\",\n\t\tcontent: [\n\t\t\t\"Background tool terminal handoff:\",\n\t\t\t...included.map((record) => `- ${record.taskId}: ${record.status} tool=${record.toolName}`),\n\t\t\t...(omitted > 0 ? [`- ${omitted} additional terminal tool task(s) omitted.`] : []),\n\t\t\t\"Parent woke. Need result: tool_task action=wait once; never poll.\",\n\t\t].join(\"\\n\"),\n\t\tdisplay: true,\n\t\tdetails: {\n\t\t\trecords: included.map((record) => ({\n\t\t\t\ttaskId: record.taskId,\n\t\t\t\tstatus: record.status,\n\t\t\t\ttoolName: record.toolName,\n\t\t\t\t...(record.artifactId ? { artifactId: record.artifactId } : {}),\n\t\t\t})),\n\t\t},\n\t};\n}\n\nfunction renderCompletionOutput(completion: BackgroundToolCallCompletion): string {\n\tconst blocks = completion.result.content.map((block) =>\n\t\tblock.type === \"text\" ? block.text : \"[Image output retained outside the foreground transcript]\",\n\t);\n\treturn blocks.join(\"\\n\") || \"Tool completed without text output.\";\n}\n\nfunction oneLine(value: string): string {\n\treturn value\n\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nfunction summaryFor(status: BackgroundToolTaskStatus, toolName: string, output: string): string {\n\tconst prefix = `${toolName} ${status}`;\n\tconst firstLine = oneLine(output);\n\tif (!firstLine) return prefix;\n\tconst remaining = Math.max(0, MAX_SUMMARY_CHARS - prefix.length - 2);\n\treturn `${prefix}: ${firstLine.slice(0, remaining)}`;\n}\n\nfunction taskNumber(taskId: string): number | undefined {\n\tconst match = TASK_ID_PATTERN.exec(taskId);\n\tif (!match) return undefined;\n\tconst value = Number(match[1]);\n\treturn Number.isSafeInteger(value) && value > 0 ? value : undefined;\n}\n\nfunction cloneUsage(value: unknown): Usage | undefined {\n\tif (!isPlainRecord(value)) return undefined;\n\tconst cost = value.cost;\n\tif (!isPlainRecord(cost)) return undefined;\n\tconst fields = [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"totalTokens\"] as const;\n\tconst costFields = [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"total\"] as const;\n\tif (\n\t\tfields.some((field) => typeof value[field] !== \"number\" || !Number.isFinite(value[field])) ||\n\t\tcostFields.some((field) => typeof cost[field] !== \"number\" || !Number.isFinite(cost[field]))\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tinput: value.input as number,\n\t\toutput: value.output as number,\n\t\tcacheRead: value.cacheRead as number,\n\t\tcacheWrite: value.cacheWrite as number,\n\t\ttotalTokens: value.totalTokens as number,\n\t\tcost: {\n\t\t\tinput: cost.input as number,\n\t\t\toutput: cost.output as number,\n\t\t\tcacheRead: cost.cacheRead as number,\n\t\t\tcacheWrite: cost.cacheWrite as number,\n\t\t\ttotal: cost.total as number,\n\t\t},\n\t};\n}\n\nfunction decodeRecord(value: unknown, sessionIds: ReadonlySet<string>): BackgroundToolTaskRecord | undefined {\n\tif (!isPlainRecord(value) || !hasOnlyKeys(value, RECORD_KEYS)) return undefined;\n\tif (\n\t\ttypeof value.sessionId !== \"string\" ||\n\t\tvalue.sessionId.length === 0 ||\n\t\t!sessionIds.has(value.sessionId) ||\n\t\ttypeof value.taskId !== \"string\" ||\n\t\ttaskNumber(value.taskId) === undefined ||\n\t\ttypeof value.toolCallId !== \"string\" ||\n\t\tvalue.toolCallId.length === 0 ||\n\t\ttypeof value.toolName !== \"string\" ||\n\t\tvalue.toolName.length === 0 ||\n\t\t(value.status !== \"running\" &&\n\t\t\tvalue.status !== \"completed\" &&\n\t\t\tvalue.status !== \"failed\" &&\n\t\t\tvalue.status !== \"canceled\") ||\n\t\ttypeof value.startedAt !== \"string\" ||\n\t\t!Number.isFinite(Date.parse(value.startedAt)) ||\n\t\t(value.completedAt !== undefined &&\n\t\t\t(typeof value.completedAt !== \"string\" || !Number.isFinite(Date.parse(value.completedAt)))) ||\n\t\t(value.status !== \"running\" && value.completedAt === undefined) ||\n\t\ttypeof value.elapsedBeforeHandoffMs !== \"number\" ||\n\t\t!Number.isFinite(value.elapsedBeforeHandoffMs) ||\n\t\tvalue.elapsedBeforeHandoffMs < 0 ||\n\t\ttypeof value.summary !== \"string\" ||\n\t\ttypeof value.output !== \"string\" ||\n\t\t(value.artifactId !== undefined &&\n\t\t\t(typeof value.artifactId !== \"string\" || !/^[0-9a-f]{1,64}$/.test(value.artifactId))) ||\n\t\t(value.cancellationRequested !== undefined && typeof value.cancellationRequested !== \"boolean\") ||\n\t\t(value.terminalDelivery !== undefined &&\n\t\t\tvalue.terminalDelivery !== \"pending\" &&\n\t\t\tvalue.terminalDelivery !== \"delivered\")\n\t) {\n\t\treturn undefined;\n\t}\n\tconst usage = value.usage === undefined ? undefined : cloneUsage(value.usage);\n\tif (value.usage !== undefined && !usage) return undefined;\n\treturn {\n\t\tsessionId: value.sessionId,\n\t\ttaskId: value.taskId,\n\t\ttoolCallId: value.toolCallId,\n\t\ttoolName: value.toolName,\n\t\tstatus: value.status,\n\t\tstartedAt: value.startedAt,\n\t\t...(value.completedAt ? { completedAt: value.completedAt } : {}),\n\t\telapsedBeforeHandoffMs: value.elapsedBeforeHandoffMs,\n\t\tsummary: value.summary,\n\t\toutput: value.output,\n\t\t...(value.artifactId ? { artifactId: value.artifactId } : {}),\n\t\t...(usage ? { usage } : {}),\n\t\t...(value.cancellationRequested !== undefined ? { cancellationRequested: value.cancellationRequested } : {}),\n\t\t...(value.terminalDelivery !== undefined ? { terminalDelivery: value.terminalDelivery } : {}),\n\t};\n}\n\n/**\n * Session-owned registry for foreground tool calls transferred into background execution.\n * It emits edge records for durability and a replace-style live-task signal for UI consumers.\n */\nexport class BackgroundToolTaskController {\n\tprivate readonly deps: BackgroundToolTaskControllerDeps;\n\tprivate readonly tasks = new Map<string, BackgroundToolTaskState>();\n\tprivate readonly handoffRequests = new Map<string, Set<() => void>>();\n\tprivate readonly queuedNotifications: Array<{ record: BackgroundToolTaskRecord; wakeParent: boolean }> = [];\n\tprivate readonly activeNotificationRecords = new Set<BackgroundToolTaskRecord>();\n\tprivate notificationDrain: Promise<void> | undefined;\n\tprivate notificationRetryTimer: ReturnType<typeof setTimeout> | undefined;\n\tprivate notificationRetryCompletion: Promise<void> | undefined;\n\tprivate resolveNotificationRetry: (() => void) | undefined;\n\tprivate notificationRetryCount = 0;\n\tprivate readonly waitTimeoutMs: number;\n\tprivate nextTaskId = 1;\n\tprivate disposed = false;\n\n\tconstructor(deps: BackgroundToolTaskControllerDeps) {\n\t\tthis.deps = deps;\n\t\tthis.waitTimeoutMs = deps.waitTimeoutMs ?? DEFAULT_BACKGROUND_TOOL_TASK_WAIT_TIMEOUT_MS;\n\t\tif (!Number.isSafeInteger(this.waitTimeoutMs) || this.waitTimeoutMs < 1) {\n\t\t\tthrow new TypeError(\"Background tool task wait timeout must be a positive safe integer.\");\n\t\t}\n\t\tthis.restorePersistedTasks();\n\t}\n\n\thandoff(context: BackgroundToolCallContext): BackgroundToolCallHandoff | undefined {\n\t\tif (this.disposed || context.toolCall.name === \"tool_task\") return undefined;\n\t\tconst sessionId = this.deps.getSessionId();\n\t\tconst taskId = `tool-task-${this.nextTaskId++}`;\n\t\tconst startedAt = this.now().toISOString();\n\t\tconst record: BackgroundToolTaskRecord = {\n\t\t\tsessionId,\n\t\t\ttaskId,\n\t\t\ttoolCallId: context.toolCall.id,\n\t\t\ttoolName: context.toolCall.name,\n\t\t\tstatus: \"running\",\n\t\t\tstartedAt,\n\t\t\telapsedBeforeHandoffMs: context.elapsedMs,\n\t\t\tsummary: `${context.toolCall.name} running in the background`,\n\t\t\toutput: \"\",\n\t\t};\n\t\tconst state = this.createState(record, context.cancel);\n\t\tthis.tasks.set(taskId, state);\n\t\tif (!this.persist(record)) {\n\t\t\tthis.tasks.delete(taskId);\n\t\t\treturn undefined;\n\t\t}\n\t\tthis.emitLiveTasks();\n\t\tcontext.completion.then(\n\t\t\t(completion) => this.settle(state, completion),\n\t\t\t(error) => this.settleRejected(state, error),\n\t\t);\n\n\t\treturn {\n\t\t\tresult: {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: [\n\t\t\t\t\t\t\t`Tool ${context.toolCall.name} exceeded ${Math.max(1, Math.round(context.elapsedMs / 1000))}s; running as session task ${taskId}.`,\n\t\t\t\t\t\t\t\"Continue independent work. Dependency: tool_task action=wait once with taskId; event-driven, never poll.\",\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { sessionId, taskId, status: \"running\" as const },\n\t\t\t},\n\t\t};\n\t}\n\n\tlist(): BackgroundToolTaskRecord[] {\n\t\treturn [...this.tasks.values()].map((state) => ({ ...state.record }));\n\t}\n\n\t/** Model-facing read that consumes terminal delivery without approving its outcome. */\n\tobserve(taskIds?: string | readonly string[]): BackgroundToolTaskRecord[] {\n\t\tconst ids = typeof taskIds === \"string\" ? [taskIds] : taskIds;\n\t\tconst states = ids\n\t\t\t? ids.flatMap((taskId) => {\n\t\t\t\t\tconst state = this.tasks.get(taskId);\n\t\t\t\t\treturn state === undefined ? [] : [state];\n\t\t\t\t})\n\t\t\t: [...this.tasks.values()];\n\t\tfor (const state of states) this.observeState(state);\n\t\treturn states.map((state) => ({ ...state.record }));\n\t}\n\n\twait(taskId: string, signal?: AbortSignal): Promise<BackgroundToolTaskRecord> {\n\t\tconst state = this.tasks.get(taskId);\n\t\tif (!state) return Promise.reject(new Error(`Unknown background tool task: ${taskId}`));\n\t\tif (state.record.status !== \"running\") {\n\t\t\tthis.observeState(state);\n\t\t\treturn Promise.resolve({ ...state.record });\n\t\t}\n\t\tif (signal?.aborted) return Promise.resolve({ ...state.record });\n\t\tstate.waitingConsumers++;\n\t\tlet waiting = true;\n\t\tconst releaseWaiter = (): void => {\n\t\t\tif (!waiting) return;\n\t\t\twaiting = false;\n\t\t\tstate.waitingConsumers--;\n\t\t};\n\t\treturn new Promise<BackgroundToolTaskRecord>((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst finishWait = (record: BackgroundToolTaskRecord): void => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tclearTimeout(watchdog);\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\treleaseWaiter();\n\t\t\t\tif (record.status !== \"running\") this.observeState(state);\n\t\t\t\tresolve({ ...state.record });\n\t\t\t};\n\t\t\tconst onAbort = (): void => {\n\t\t\t\tfinishWait(state.record);\n\t\t\t};\n\t\t\tconst watchdog = setTimeout(() => finishWait(state.record), this.waitTimeoutMs);\n\t\t\twatchdog.unref?.();\n\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tstate.terminal.then(finishWait);\n\t\t});\n\t}\n\n\tcancel(taskId: string): boolean {\n\t\tconst state = this.tasks.get(taskId);\n\t\tif (!state || state.record.status !== \"running\") return false;\n\t\tstate.cancellationRequested = true;\n\t\tstate.record = { ...state.record, cancellationRequested: true };\n\t\ttry {\n\t\t\tstate.cancel();\n\t\t} catch (error) {\n\t\t\tthis.deps.onError?.(`Failed to cancel background tool task ${taskId}`, error);\n\t\t}\n\t\treturn true;\n\t}\n\n\tsubscribeHandoffRequest(toolCallId: string, request: () => void): () => void {\n\t\tif (this.disposed) return () => {};\n\t\tconst requests = this.handoffRequests.get(toolCallId) ?? new Set<() => void>();\n\t\trequests.add(request);\n\t\tthis.handoffRequests.set(toolCallId, requests);\n\t\treturn () => {\n\t\t\trequests.delete(request);\n\t\t\tif (requests.size === 0) this.handoffRequests.delete(toolCallId);\n\t\t};\n\t}\n\n\trequestHandoff(toolCallId?: string): number {\n\t\tif (this.disposed) return 0;\n\t\tconst requested = toolCallId\n\t\t\t? [...(this.handoffRequests.get(toolCallId) ?? [])]\n\t\t\t: [...this.handoffRequests.values()].flatMap((requests) => [...requests]);\n\t\tfor (const request of requested) request();\n\t\treturn requested.length;\n\t}\n\n\tasync waitForNotifications(): Promise<void> {\n\t\t// A just-resolved tool completion settles through its promise continuation before it can enqueue\n\t\t// the notification drain. Yield once so this event-driven barrier observes that enqueue.\n\t\tawait Promise.resolve();\n\t\tfor (;;) {\n\t\t\tconst drain = this.notificationDrain;\n\t\t\tif (drain) {\n\t\t\t\tawait drain;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.queuedNotifications.length === 0) return;\n\t\t\tconst retry = this.notificationRetryCompletion;\n\t\t\tif (retry) {\n\t\t\t\tawait retry;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.disposed) return;\n\t\t\tthis.scheduleNotificationDrain();\n\t\t}\n\t}\n\n\tasync shutdown(): Promise<void> {\n\t\tif (!this.disposed) {\n\t\t\tthis.disposed = true;\n\t\t\tthis.handoffRequests.clear();\n\t\t\tfor (const state of this.tasks.values()) {\n\t\t\t\tif (state.record.status !== \"running\") continue;\n\t\t\t\tstate.cancellationRequested = true;\n\t\t\t\ttry {\n\t\t\t\t\tstate.cancel();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.deps.onError?.(`Failed to cancel background tool task ${state.record.taskId}`, error);\n\t\t\t\t}\n\t\t\t\tthis.finishState(\n\t\t\t\t\tstate,\n\t\t\t\t\t\"canceled\",\n\t\t\t\t\t\"Session ended before the background tool completed.\",\n\t\t\t\t\tundefined,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tawait this.waitForNotifications();\n\t}\n\n\tprivate settle(state: BackgroundToolTaskState, completion: BackgroundToolCallCompletion): void {\n\t\tif (state.record.status !== \"running\") return;\n\t\tconst status = state.cancellationRequested ? \"canceled\" : completion.isError ? \"failed\" : \"completed\";\n\t\tconst output = renderCompletionOutput(completion);\n\t\tthis.finishState(state, status, output, completion.result.usage, true);\n\t}\n\n\tprivate settleRejected(state: BackgroundToolTaskState, error: unknown): void {\n\t\tif (state.record.status !== \"running\") return;\n\t\tconst status = state.cancellationRequested ? \"canceled\" : \"failed\";\n\t\tconst output = error instanceof Error ? error.message : String(error);\n\t\tthis.finishState(state, status, output, undefined, true);\n\t}\n\n\tprivate restorePersistedTasks(): void {\n\t\tconst load = this.deps.loadPersistedRecordsNewestFirst;\n\t\tif (!load) return;\n\t\tlet values: readonly unknown[];\n\t\ttry {\n\t\t\tvalues = load();\n\t\t} catch (error) {\n\t\t\tthis.deps.onError?.(\"Failed to load persisted background tool tasks\", error);\n\t\t\treturn;\n\t\t}\n\t\tconst sessionId = this.deps.getSessionId();\n\t\tconst sessionIds = new Set(this.deps.getSessionLineageIds?.() ?? [sessionId]);\n\t\tsessionIds.add(sessionId);\n\t\tconst seenTaskIds = new Set<string>();\n\t\tconst latestRecords: BackgroundToolTaskRecord[] = [];\n\t\tlet highestTaskNumber = 0;\n\t\tfor (const value of values) {\n\t\t\tif (\n\t\t\t\t!isPlainRecord(value) ||\n\t\t\t\ttypeof value.sessionId !== \"string\" ||\n\t\t\t\t!sessionIds.has(value.sessionId) ||\n\t\t\t\ttypeof value.taskId !== \"string\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst numericTaskId = taskNumber(value.taskId);\n\t\t\tif (numericTaskId === undefined) continue;\n\t\t\thighestTaskNumber = Math.max(highestTaskNumber, numericTaskId);\n\t\t\tif (seenTaskIds.has(value.taskId)) continue;\n\t\t\tseenTaskIds.add(value.taskId);\n\t\t\tconst record = decodeRecord(value, sessionIds);\n\t\t\tif (record) latestRecords.push(record);\n\t\t}\n\t\tthis.nextTaskId = highestTaskNumber + 1;\n\t\tlatestRecords.sort((left, right) => taskNumber(left.taskId)! - taskNumber(right.taskId)!);\n\t\tfor (const record of latestRecords) {\n\t\t\tconst state = this.createState(record, () => {});\n\t\t\tthis.tasks.set(record.taskId, state);\n\t\t\tif (record.status !== \"running\") {\n\t\t\t\tstate.resolveTerminal(record);\n\t\t\t\tif (record.terminalDelivery === \"pending\") this.notify(record, true);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.finishState(\n\t\t\t\tstate,\n\t\t\t\t\"failed\",\n\t\t\t\t\"The session resumed after the owning process ended; the original tool completion is unavailable.\",\n\t\t\t\tundefined,\n\t\t\t\tfalse,\n\t\t\t);\n\t\t}\n\t\tthis.pruneTerminalTasks();\n\t\tthis.emitLiveTasks();\n\t}\n\n\tprivate createState(record: BackgroundToolTaskRecord, cancel: () => void): BackgroundToolTaskState {\n\t\tlet resolveTerminal: ((terminalRecord: BackgroundToolTaskRecord) => void) | undefined;\n\t\tconst terminal = new Promise<BackgroundToolTaskRecord>((resolve) => {\n\t\t\tresolveTerminal = resolve;\n\t\t});\n\t\treturn {\n\t\t\trecord: { ...record },\n\t\t\tcancel,\n\t\t\tcancellationRequested: record.cancellationRequested ?? false,\n\t\t\twaitingConsumers: 0,\n\t\t\tterminal,\n\t\t\tresolveTerminal: resolveTerminal!,\n\t\t\tartifactHolderId: `background-tool-task:${record.sessionId}:${record.taskId}`,\n\t\t};\n\t}\n\n\tprivate finishState(\n\t\tstate: BackgroundToolTaskState,\n\t\tstatus: Exclude<BackgroundToolTaskStatus, \"running\">,\n\t\trawOutput: string,\n\t\tusage: Usage | undefined,\n\t\tnotify: boolean,\n\t): void {\n\t\tconst packed = packToolOutput(\n\t\t\t{\n\t\t\t\ttoolName: state.record.toolName,\n\t\t\t\trawContent: rawOutput,\n\t\t\t\tsessionEntryId: state.record.taskId,\n\t\t\t\tcreatedAtTurn: 0,\n\t\t\t\treproducible: false,\n\t\t\t\ttruncation: { maxBytes: MAX_INLINE_OUTPUT_BYTES, maxLines: MAX_INLINE_OUTPUT_LINES },\n\t\t\t},\n\t\t\tthis.deps.getArtifactStore(),\n\t\t\tstate.artifactHolderId,\n\t\t);\n\t\tconst output = packed.artifactId\n\t\t\t? `${packed.content}\\n\\n[${formatArtifactNotice(packed.artifactId)}]`\n\t\t\t: packed.content;\n\t\tconst record: BackgroundToolTaskRecord = {\n\t\t\t...state.record,\n\t\t\tstatus,\n\t\t\tcompletedAt: this.now().toISOString(),\n\t\t\tsummary: summaryFor(status, state.record.toolName, output),\n\t\t\toutput,\n\t\t\t...(packed.artifactId ? { artifactId: packed.artifactId } : {}),\n\t\t\t...(usage ? { usage } : {}),\n\t\t\t...(state.cancellationRequested ? { cancellationRequested: true } : {}),\n\t\t\tterminalDelivery: notify ? \"pending\" : \"delivered\",\n\t\t};\n\t\tconst persisted = this.persist(record);\n\t\tconst terminalRecord = persisted\n\t\t\t? record\n\t\t\t: {\n\t\t\t\t\t...record,\n\t\t\t\t\tstatus: \"failed\" as const,\n\t\t\t\t\tsummary: `${record.toolName} failed: terminal result could not be persisted`,\n\t\t\t\t\toutput: \"Background tool result could not be persisted; treat it as unavailable.\",\n\t\t\t\t};\n\t\tstate.record = terminalRecord;\n\t\tif (usage) this.deps.recordUsage?.(record.taskId, usage);\n\t\tstate.resolveTerminal(terminalRecord);\n\t\tthis.emitLiveTasks();\n\t\tthis.pruneTerminalTasks();\n\t\tif (notify) this.notify(terminalRecord, state.waitingConsumers === 0);\n\t}\n\n\tprivate persist(record: BackgroundToolTaskRecord): boolean {\n\t\ttry {\n\t\t\tconst durableRecord = { ...record };\n\t\t\tdelete durableRecord.observedAt;\n\t\t\tthis.deps.persist(durableRecord);\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tthis.deps.onError?.(`Failed to persist background tool task ${record.taskId}`, error);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate notify(record: BackgroundToolTaskRecord, wakeParent: boolean): void {\n\t\tconst notificationRecord = {\n\t\t\t...record,\n\t\t\t...(!wakeParent && !record.observedAt ? { observedAt: this.now().toISOString() } : {}),\n\t\t};\n\t\tthis.activeNotificationRecords.add(notificationRecord);\n\t\tthis.queuedNotifications.push({ record: notificationRecord, wakeParent });\n\t\tthis.scheduleNotificationDrain();\n\t}\n\n\tprivate markNotificationDelivered(record: BackgroundToolTaskRecord): void {\n\t\tif (record.terminalDelivery !== \"pending\") return;\n\t\tconst delivered = { ...record, terminalDelivery: \"delivered\" as const };\n\t\tif (this.persist(delivered)) {\n\t\t\tconst state = this.tasks.get(record.taskId);\n\t\t\tif (state && state.record.completedAt === record.completedAt) state.record = delivered;\n\t\t}\n\t}\n\n\tprivate observeState(state: BackgroundToolTaskState): void {\n\t\tif (state.record.status === \"running\" || state.record.observedAt) return;\n\t\tconst observedAt = this.now().toISOString();\n\t\tstate.record = { ...state.record, observedAt };\n\t\tfor (const record of this.activeNotificationRecords) {\n\t\t\tif (record.taskId === state.record.taskId && record.completedAt === state.record.completedAt) {\n\t\t\t\trecord.observedAt = observedAt;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate scheduleNotificationDrain(): void {\n\t\tif (this.disposed || this.notificationDrain || this.notificationRetryTimer) return;\n\t\tthis.notificationDrain = this.drainNotifications().finally(() => {\n\t\t\tthis.notificationDrain = undefined;\n\t\t\tif (this.queuedNotifications.length > 0 && !this.notificationRetryTimer) this.scheduleNotificationDrain();\n\t\t});\n\t}\n\n\tprivate scheduleNotificationRetry(): void {\n\t\tif (this.disposed || this.notificationRetryTimer) return;\n\t\tconst delayMs = Math.min(100 * 2 ** Math.min(this.notificationRetryCount, 5), 5_000);\n\t\tthis.notificationRetryCount++;\n\t\tthis.notificationRetryCompletion = new Promise<void>((resolve) => {\n\t\t\tthis.resolveNotificationRetry = resolve;\n\t\t});\n\t\tthis.notificationRetryTimer = setTimeout(() => {\n\t\t\tthis.notificationRetryTimer = undefined;\n\t\t\tconst resolve = this.resolveNotificationRetry;\n\t\t\tthis.resolveNotificationRetry = undefined;\n\t\t\tthis.notificationRetryCompletion = undefined;\n\t\t\tresolve?.();\n\t\t\tthis.scheduleNotificationDrain();\n\t\t}, delayMs);\n\t\tthis.notificationRetryTimer.unref?.();\n\t}\n\n\tprivate async drainNotifications(): Promise<void> {\n\t\t// Allow completions released by the same event to reach this queue before forming the batch.\n\t\tawait Promise.resolve();\n\t\twhile (this.queuedNotifications.length > 0) {\n\t\t\tawait Promise.resolve();\n\t\t\tconst batch = this.queuedNotifications.splice(0);\n\t\t\tconst records = batch.map((notification) => notification.record);\n\t\t\ttry {\n\t\t\t\tawait this.deps.notifyTerminal(records, {\n\t\t\t\t\twakeParent: batch.some((notification) => notification.wakeParent),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\t// A rejected handoff is not a delivery receipt. Put the exact records back ahead of\n\t\t\t\t// newer completions and retry on an event-driven backoff; persistence already contains\n\t\t\t\t// the terminal, so a transient notifier failure must not make it disappear.\n\t\t\t\tthis.queuedNotifications.unshift(...batch);\n\t\t\t\tconst includedIds = records.slice(0, MAX_TERMINAL_HANDOFF_RECORDS).map((record) => record.taskId);\n\t\t\t\tconst omitted = records.length - includedIds.length;\n\t\t\t\tconst suffix = omitted > 0 ? ` (+${omitted} more)` : \"\";\n\t\t\t\ttry {\n\t\t\t\t\tthis.deps.onError?.(\n\t\t\t\t\t\t`Failed to notify terminal background tool task batch ${includedIds.join(\", \")}${suffix}`,\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t// Diagnostics cannot consume the pending terminal handoff.\n\t\t\t\t}\n\t\t\t\tthis.scheduleNotificationRetry();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.notificationRetryCount = 0;\n\t\t\tfor (const record of records) this.markNotificationDelivered(record);\n\t\t\tfor (const record of records) {\n\t\t\t\tthis.activeNotificationRecords.delete(record);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate emitLiveTasks(): void {\n\t\tconst tasks = [...this.tasks.values()]\n\t\t\t.filter((state) => state.record.status === \"running\")\n\t\t\t.map((state) => ({\n\t\t\t\ttaskId: state.record.taskId,\n\t\t\t\ttoolCallId: state.record.toolCallId,\n\t\t\t\ttoolName: state.record.toolName,\n\t\t\t\tdescription: state.record.summary,\n\t\t\t}));\n\t\ttry {\n\t\t\tthis.deps.onLiveTasksChanged?.(tasks);\n\t\t} catch (error) {\n\t\t\tthis.deps.onError?.(\"Failed to emit background tool task level signal\", error);\n\t\t}\n\t}\n\n\tprivate pruneTerminalTasks(): void {\n\t\tconst terminal = [...this.tasks.values()].filter((state) => state.record.status !== \"running\");\n\t\tfor (const state of terminal.slice(0, Math.max(0, terminal.length - MAX_RETAINED_TERMINAL_TASKS))) {\n\t\t\tthis.tasks.delete(state.record.taskId);\n\t\t\tif (!state.record.artifactId) continue;\n\t\t\tconst store = this.deps.getArtifactStore();\n\t\t\tstore?.removeReference(state.record.artifactId, state.artifactHolderId);\n\t\t\tstore?.cleanup();\n\t\t}\n\t}\n\n\tprivate now(): Date {\n\t\treturn this.deps.now?.() ?? new Date();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"background-tool-task-controller.js","sourceRoot":"","sources":["../../src/core/background-tool-task-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tBackgroundToolCallCompletion,\n\tBackgroundToolCallContext,\n\tBackgroundToolCallHandoff,\n} from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Usage } from \"@caupulican/pi-ai\";\nimport type { ArtifactStore } from \"./context/context-artifacts.ts\";\nimport { formatArtifactNotice, packToolOutput } from \"./context/tool-output-packer.ts\";\nimport { hasOnlyKeys, isPlainRecord } from \"./util/value-guards.ts\";\n\nexport const DEFAULT_BACKGROUND_TOOL_CALL_AFTER_MS = 15_000;\nexport const DEFAULT_BACKGROUND_TOOL_TASK_WAIT_TIMEOUT_MS = 30_000;\nexport const BACKGROUND_TOOL_TASK_CUSTOM_TYPE = \"background_tool_task\";\n\nconst MAX_RETAINED_TERMINAL_TASKS = 64;\nconst MAX_INLINE_OUTPUT_BYTES = 32 * 1024;\nconst MAX_INLINE_OUTPUT_LINES = 400;\nconst MAX_SUMMARY_CHARS = 200;\nconst MAX_TERMINAL_HANDOFF_RECORDS = 8;\nconst TASK_ID_PATTERN = /^tool-task-([1-9]\\d*)$/;\nconst RECORD_KEYS = [\n\t\"sessionId\",\n\t\"taskId\",\n\t\"toolCallId\",\n\t\"toolName\",\n\t\"goalId\",\n\t\"status\",\n\t\"startedAt\",\n\t\"completedAt\",\n\t\"elapsedBeforeHandoffMs\",\n\t\"summary\",\n\t\"output\",\n\t\"artifactId\",\n\t\"usage\",\n\t\"cancellationRequested\",\n\t\"terminalDelivery\",\n] as const;\n\nexport type BackgroundToolTaskStatus = \"running\" | \"completed\" | \"failed\" | \"canceled\";\nexport type BackgroundToolTerminalDelivery = \"pending\" | \"delivered\";\n\nexport type BackgroundToolTaskRef = Pick<BackgroundToolTaskRecord, \"taskId\" | \"toolCallId\" | \"goalId\" | \"status\">;\n\n/** Match a goal/task_steps evidence uri to a session background tool task by task id or toolCallId. */\nexport function findBackgroundToolTask<T extends BackgroundToolTaskRef>(\n\trecords: readonly T[],\n\turi: string,\n): T | undefined {\n\tconst id = uri.trim();\n\tif (!id) return undefined;\n\treturn records.find((record) => record.taskId === id || record.toolCallId === id);\n}\n\n/** True only when the cited background task finished successfully. Undefined when no task matches. */\nexport function isCompletedBackgroundToolEvidence(\n\trecords: readonly BackgroundToolTaskRef[],\n\turi: string,\n): boolean | undefined {\n\tconst task = findBackgroundToolTask(records, uri);\n\tif (!task) return undefined;\n\treturn task.status === \"completed\";\n}\n\nexport function collectCitedRunningToolTaskIds(args: {\n\trecords: readonly BackgroundToolTaskRef[];\n\turis: readonly string[];\n}): string[] {\n\tconst running = new Set<string>();\n\tfor (const uri of args.uris) {\n\t\tconst task = findBackgroundToolTask(args.records, uri);\n\t\tif (task?.status === \"running\") running.add(task.taskId);\n\t}\n\treturn [...running];\n}\n\nexport interface BackgroundToolTaskRecord {\n\tsessionId: string;\n\ttaskId: string;\n\ttoolCallId: string;\n\ttoolName: string;\n\t/** Goal execution that owned the foreground tool call when it was handed off. */\n\tgoalId?: string;\n\tstatus: BackgroundToolTaskStatus;\n\tstartedAt: string;\n\tcompletedAt?: string;\n\telapsedBeforeHandoffMs: number;\n\tsummary: string;\n\toutput: string;\n\tartifactId?: string;\n\tusage?: Usage;\n\tcancellationRequested?: boolean;\n\t/** Durable terminal handoff state. Undefined on legacy records, which are treated as delivered. */\n\tterminalDelivery?: BackgroundToolTerminalDelivery;\n\t/** Runtime-only receipt; never serialized into the durable task record. */\n\tobservedAt?: string;\n}\n\nexport interface BackgroundToolTaskLiveView {\n\ttaskId: string;\n\ttoolCallId: string;\n\ttoolName: string;\n\tdescription: string;\n}\n\nexport interface BackgroundToolTerminalMessage {\n\tcustomType: \"background-tool-completion\";\n\tcontent: string;\n\tdisplay: true;\n\tdetails: {\n\t\trecords: Array<{\n\t\t\ttaskId: string;\n\t\t\tstatus: BackgroundToolTaskStatus;\n\t\t\ttoolName: string;\n\t\t\tartifactId?: string;\n\t\t}>;\n\t};\n}\n\nexport interface BackgroundToolTaskControllerDeps {\n\tgetSessionId(): string;\n\t/** Authoritative goal execution attribution at the tool handoff boundary. */\n\tgetGoalId?(): string | undefined;\n\t/** Current session followed by the authoritative fork ancestry whose branch records remain visible. */\n\tgetSessionLineageIds?(): readonly string[];\n\tgetArtifactStore(): ArtifactStore | undefined;\n\t/** Durable task records on the active branch, newest first, without rebuilding full model context. */\n\tloadPersistedRecordsNewestFirst?(): readonly unknown[];\n\tpersist(record: BackgroundToolTaskRecord): void;\n\tnotifyTerminal(records: readonly BackgroundToolTaskRecord[], options: { wakeParent: boolean }): Promise<void> | void;\n\tonLiveTasksChanged?(tasks: readonly BackgroundToolTaskLiveView[]): void;\n\trecordUsage?(taskId: string, usage: Usage): void;\n\tonError?(message: string, error: unknown): void;\n\tnow?(): Date;\n\t/** Event-wait watchdog; completion still arrives through the terminal handoff after this bound. */\n\twaitTimeoutMs?: number;\n}\n\ninterface BackgroundToolTaskState {\n\trecord: BackgroundToolTaskRecord;\n\tcancel: () => void;\n\tcancellationRequested: boolean;\n\twaitingConsumers: number;\n\tterminal: Promise<BackgroundToolTaskRecord>;\n\tresolveTerminal: (record: BackgroundToolTaskRecord) => void;\n\tartifactHolderId: string;\n}\n\n/** Read only task records on the active branch without allocating or hydrating the full branch context. */\nexport function loadBackgroundToolTaskRecordsNewestFirst(\n\tsessionManager: Pick<SessionManager, \"getLatestCustomEntryOnBranch\">,\n): unknown[] {\n\tconst records: unknown[] = [];\n\tlet fromId: string | undefined;\n\tfor (;;) {\n\t\tconst entry = sessionManager.getLatestCustomEntryOnBranch(BACKGROUND_TOOL_TASK_CUSTOM_TYPE, fromId);\n\t\tif (!entry) return records;\n\t\trecords.push(entry.data);\n\t\tif (entry.parentId === null) return records;\n\t\tfromId = entry.parentId;\n\t}\n}\n\nexport function createBackgroundToolTerminalMessage(\n\trecords: readonly BackgroundToolTaskRecord[],\n\toptions?: { wakeParent?: boolean },\n): BackgroundToolTerminalMessage {\n\tif (records.length === 0) throw new TypeError(\"Background tool terminal handoff requires at least one record\");\n\tconst included = records.slice(0, MAX_TERMINAL_HANDOFF_RECORDS);\n\tconst omitted = records.length - included.length;\n\tconst wakeParent = options?.wakeParent ?? true;\n\treturn {\n\t\tcustomType: \"background-tool-completion\",\n\t\tcontent: [\n\t\t\t\"Background tool terminal handoff:\",\n\t\t\t...included.map((record) => `- ${record.taskId}: ${record.status} tool=${record.toolName}`),\n\t\t\t...(omitted > 0 ? [`- ${omitted} additional terminal tool task(s) omitted.`] : []),\n\t\t\t...(wakeParent\n\t\t\t\t? [\"Parent woke. Need result: tool_task action=wait once; never poll.\"]\n\t\t\t\t: [\"Parent was not woken because the owning goal is no longer active. Wait for explicit user input.\"]),\n\t\t].join(\"\\n\"),\n\t\tdisplay: true,\n\t\tdetails: {\n\t\t\trecords: included.map((record) => ({\n\t\t\t\ttaskId: record.taskId,\n\t\t\t\tstatus: record.status,\n\t\t\t\ttoolName: record.toolName,\n\t\t\t\t...(record.artifactId ? { artifactId: record.artifactId } : {}),\n\t\t\t})),\n\t\t},\n\t};\n}\n\nfunction renderCompletionOutput(completion: BackgroundToolCallCompletion): string {\n\tconst blocks = completion.result.content.map((block) =>\n\t\tblock.type === \"text\" ? block.text : \"[Image output retained outside the foreground transcript]\",\n\t);\n\treturn blocks.join(\"\\n\") || \"Tool completed without text output.\";\n}\n\nfunction oneLine(value: string): string {\n\treturn value\n\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nfunction summaryFor(status: BackgroundToolTaskStatus, toolName: string, output: string): string {\n\tconst prefix = `${toolName} ${status}`;\n\tconst firstLine = oneLine(output);\n\tif (!firstLine) return prefix;\n\tconst remaining = Math.max(0, MAX_SUMMARY_CHARS - prefix.length - 2);\n\treturn `${prefix}: ${firstLine.slice(0, remaining)}`;\n}\n\nfunction taskNumber(taskId: string): number | undefined {\n\tconst match = TASK_ID_PATTERN.exec(taskId);\n\tif (!match) return undefined;\n\tconst value = Number(match[1]);\n\treturn Number.isSafeInteger(value) && value > 0 ? value : undefined;\n}\n\nfunction cloneUsage(value: unknown): Usage | undefined {\n\tif (!isPlainRecord(value)) return undefined;\n\tconst cost = value.cost;\n\tif (!isPlainRecord(cost)) return undefined;\n\tconst fields = [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"totalTokens\"] as const;\n\tconst costFields = [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"total\"] as const;\n\tif (\n\t\tfields.some((field) => typeof value[field] !== \"number\" || !Number.isFinite(value[field])) ||\n\t\tcostFields.some((field) => typeof cost[field] !== \"number\" || !Number.isFinite(cost[field]))\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tinput: value.input as number,\n\t\toutput: value.output as number,\n\t\tcacheRead: value.cacheRead as number,\n\t\tcacheWrite: value.cacheWrite as number,\n\t\ttotalTokens: value.totalTokens as number,\n\t\tcost: {\n\t\t\tinput: cost.input as number,\n\t\t\toutput: cost.output as number,\n\t\t\tcacheRead: cost.cacheRead as number,\n\t\t\tcacheWrite: cost.cacheWrite as number,\n\t\t\ttotal: cost.total as number,\n\t\t},\n\t};\n}\n\nfunction decodeRecord(value: unknown, sessionIds: ReadonlySet<string>): BackgroundToolTaskRecord | undefined {\n\tif (!isPlainRecord(value) || !hasOnlyKeys(value, RECORD_KEYS)) return undefined;\n\tif (\n\t\ttypeof value.sessionId !== \"string\" ||\n\t\tvalue.sessionId.length === 0 ||\n\t\t!sessionIds.has(value.sessionId) ||\n\t\ttypeof value.taskId !== \"string\" ||\n\t\ttaskNumber(value.taskId) === undefined ||\n\t\ttypeof value.toolCallId !== \"string\" ||\n\t\tvalue.toolCallId.length === 0 ||\n\t\ttypeof value.toolName !== \"string\" ||\n\t\tvalue.toolName.length === 0 ||\n\t\t(value.status !== \"running\" &&\n\t\t\tvalue.status !== \"completed\" &&\n\t\t\tvalue.status !== \"failed\" &&\n\t\t\tvalue.status !== \"canceled\") ||\n\t\ttypeof value.startedAt !== \"string\" ||\n\t\t!Number.isFinite(Date.parse(value.startedAt)) ||\n\t\t(value.completedAt !== undefined &&\n\t\t\t(typeof value.completedAt !== \"string\" || !Number.isFinite(Date.parse(value.completedAt)))) ||\n\t\t(value.status !== \"running\" && value.completedAt === undefined) ||\n\t\t(value.goalId !== undefined && (typeof value.goalId !== \"string\" || value.goalId.length === 0)) ||\n\t\ttypeof value.elapsedBeforeHandoffMs !== \"number\" ||\n\t\t!Number.isFinite(value.elapsedBeforeHandoffMs) ||\n\t\tvalue.elapsedBeforeHandoffMs < 0 ||\n\t\ttypeof value.summary !== \"string\" ||\n\t\ttypeof value.output !== \"string\" ||\n\t\t(value.artifactId !== undefined &&\n\t\t\t(typeof value.artifactId !== \"string\" || !/^[0-9a-f]{1,64}$/.test(value.artifactId))) ||\n\t\t(value.cancellationRequested !== undefined && typeof value.cancellationRequested !== \"boolean\") ||\n\t\t(value.terminalDelivery !== undefined &&\n\t\t\tvalue.terminalDelivery !== \"pending\" &&\n\t\t\tvalue.terminalDelivery !== \"delivered\")\n\t) {\n\t\treturn undefined;\n\t}\n\tconst usage = value.usage === undefined ? undefined : cloneUsage(value.usage);\n\tif (value.usage !== undefined && !usage) return undefined;\n\treturn {\n\t\tsessionId: value.sessionId,\n\t\ttaskId: value.taskId,\n\t\ttoolCallId: value.toolCallId,\n\t\ttoolName: value.toolName,\n\t\t...(value.goalId ? { goalId: value.goalId } : {}),\n\t\tstatus: value.status,\n\t\tstartedAt: value.startedAt,\n\t\t...(value.completedAt ? { completedAt: value.completedAt } : {}),\n\t\telapsedBeforeHandoffMs: value.elapsedBeforeHandoffMs,\n\t\tsummary: value.summary,\n\t\toutput: value.output,\n\t\t...(value.artifactId ? { artifactId: value.artifactId } : {}),\n\t\t...(usage ? { usage } : {}),\n\t\t...(value.cancellationRequested !== undefined ? { cancellationRequested: value.cancellationRequested } : {}),\n\t\t...(value.terminalDelivery !== undefined ? { terminalDelivery: value.terminalDelivery } : {}),\n\t};\n}\n\n/**\n * Session-owned registry for foreground tool calls transferred into background execution.\n * It emits edge records for durability and a replace-style live-task signal for UI consumers.\n */\nexport class BackgroundToolTaskController {\n\tprivate readonly deps: BackgroundToolTaskControllerDeps;\n\tprivate readonly tasks = new Map<string, BackgroundToolTaskState>();\n\tprivate readonly handoffRequests = new Map<string, Set<() => void>>();\n\tprivate readonly queuedNotifications: Array<{ record: BackgroundToolTaskRecord; wakeParent: boolean }> = [];\n\tprivate readonly activeNotificationRecords = new Set<BackgroundToolTaskRecord>();\n\tprivate notificationDrain: Promise<void> | undefined;\n\tprivate notificationRetryTimer: ReturnType<typeof setTimeout> | undefined;\n\tprivate notificationRetryCompletion: Promise<void> | undefined;\n\tprivate resolveNotificationRetry: (() => void) | undefined;\n\tprivate notificationRetryCount = 0;\n\tprivate readonly waitTimeoutMs: number;\n\tprivate nextTaskId = 1;\n\tprivate disposed = false;\n\n\tconstructor(deps: BackgroundToolTaskControllerDeps) {\n\t\tthis.deps = deps;\n\t\tthis.waitTimeoutMs = deps.waitTimeoutMs ?? DEFAULT_BACKGROUND_TOOL_TASK_WAIT_TIMEOUT_MS;\n\t\tif (!Number.isSafeInteger(this.waitTimeoutMs) || this.waitTimeoutMs < 1) {\n\t\t\tthrow new TypeError(\"Background tool task wait timeout must be a positive safe integer.\");\n\t\t}\n\t\tthis.restorePersistedTasks();\n\t}\n\n\thandoff(context: BackgroundToolCallContext): BackgroundToolCallHandoff | undefined {\n\t\tif (this.disposed || context.toolCall.name === \"tool_task\") return undefined;\n\t\tconst sessionId = this.deps.getSessionId();\n\t\tconst taskId = `tool-task-${this.nextTaskId++}`;\n\t\tconst startedAt = this.now().toISOString();\n\t\tconst goalId = this.deps.getGoalId?.();\n\t\tconst record: BackgroundToolTaskRecord = {\n\t\t\tsessionId,\n\t\t\ttaskId,\n\t\t\ttoolCallId: context.toolCall.id,\n\t\t\ttoolName: context.toolCall.name,\n\t\t\t...(goalId ? { goalId } : {}),\n\t\t\tstatus: \"running\",\n\t\t\tstartedAt,\n\t\t\telapsedBeforeHandoffMs: context.elapsedMs,\n\t\t\tsummary: `${context.toolCall.name} running in the background`,\n\t\t\toutput: \"\",\n\t\t};\n\t\tconst state = this.createState(record, context.cancel);\n\t\tthis.tasks.set(taskId, state);\n\t\tif (!this.persist(record)) {\n\t\t\tthis.tasks.delete(taskId);\n\t\t\treturn undefined;\n\t\t}\n\t\tthis.emitLiveTasks();\n\t\tcontext.completion.then(\n\t\t\t(completion) => this.settle(state, completion),\n\t\t\t(error) => this.settleRejected(state, error),\n\t\t);\n\n\t\treturn {\n\t\t\tresult: {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: [\n\t\t\t\t\t\t\t`Tool ${context.toolCall.name} exceeded ${Math.max(1, Math.round(context.elapsedMs / 1000))}s; running as session task ${taskId}.`,\n\t\t\t\t\t\t\t\"Continue independent work. Dependency: tool_task action=wait once with taskId; event-driven, never poll.\",\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { sessionId, taskId, status: \"running\" as const },\n\t\t\t},\n\t\t};\n\t}\n\n\tlist(): BackgroundToolTaskRecord[] {\n\t\treturn [...this.tasks.values()].map((state) => ({ ...state.record }));\n\t}\n\n\t/** Model-facing read that consumes terminal delivery without approving its outcome. */\n\tobserve(taskIds?: string | readonly string[]): BackgroundToolTaskRecord[] {\n\t\tconst ids = typeof taskIds === \"string\" ? [taskIds] : taskIds;\n\t\tconst states = ids\n\t\t\t? ids.flatMap((taskId) => {\n\t\t\t\t\tconst state = this.tasks.get(taskId);\n\t\t\t\t\treturn state === undefined ? [] : [state];\n\t\t\t\t})\n\t\t\t: [...this.tasks.values()];\n\t\tfor (const state of states) this.observeState(state);\n\t\treturn states.map((state) => ({ ...state.record }));\n\t}\n\n\twait(taskId: string, signal?: AbortSignal): Promise<BackgroundToolTaskRecord> {\n\t\tconst state = this.tasks.get(taskId);\n\t\tif (!state) return Promise.reject(new Error(`Unknown background tool task: ${taskId}`));\n\t\tif (state.record.status !== \"running\") {\n\t\t\tthis.observeState(state);\n\t\t\treturn Promise.resolve({ ...state.record });\n\t\t}\n\t\tif (signal?.aborted) return Promise.resolve({ ...state.record });\n\t\tstate.waitingConsumers++;\n\t\tlet waiting = true;\n\t\tconst releaseWaiter = (): void => {\n\t\t\tif (!waiting) return;\n\t\t\twaiting = false;\n\t\t\tstate.waitingConsumers--;\n\t\t};\n\t\treturn new Promise<BackgroundToolTaskRecord>((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst finishWait = (record: BackgroundToolTaskRecord): void => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tclearTimeout(watchdog);\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\treleaseWaiter();\n\t\t\t\tif (record.status !== \"running\") this.observeState(state);\n\t\t\t\tresolve({ ...state.record });\n\t\t\t};\n\t\t\tconst onAbort = (): void => {\n\t\t\t\tfinishWait(state.record);\n\t\t\t};\n\t\t\tconst watchdog = setTimeout(() => finishWait(state.record), this.waitTimeoutMs);\n\t\t\twatchdog.unref?.();\n\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tstate.terminal.then(finishWait);\n\t\t});\n\t}\n\n\tcancel(taskId: string): boolean {\n\t\tconst state = this.tasks.get(taskId);\n\t\tif (!state || state.record.status !== \"running\") return false;\n\t\tstate.cancellationRequested = true;\n\t\tstate.record = { ...state.record, cancellationRequested: true };\n\t\ttry {\n\t\t\tstate.cancel();\n\t\t} catch (error) {\n\t\t\tthis.deps.onError?.(`Failed to cancel background tool task ${taskId}`, error);\n\t\t}\n\t\treturn true;\n\t}\n\n\tsubscribeHandoffRequest(toolCallId: string, request: () => void): () => void {\n\t\tif (this.disposed) return () => {};\n\t\tconst requests = this.handoffRequests.get(toolCallId) ?? new Set<() => void>();\n\t\trequests.add(request);\n\t\tthis.handoffRequests.set(toolCallId, requests);\n\t\treturn () => {\n\t\t\trequests.delete(request);\n\t\t\tif (requests.size === 0) this.handoffRequests.delete(toolCallId);\n\t\t};\n\t}\n\n\trequestHandoff(toolCallId?: string): number {\n\t\tif (this.disposed) return 0;\n\t\tconst requested = toolCallId\n\t\t\t? [...(this.handoffRequests.get(toolCallId) ?? [])]\n\t\t\t: [...this.handoffRequests.values()].flatMap((requests) => [...requests]);\n\t\tfor (const request of requested) request();\n\t\treturn requested.length;\n\t}\n\n\tasync waitForNotifications(): Promise<void> {\n\t\t// A just-resolved tool completion settles through its promise continuation before it can enqueue\n\t\t// the notification drain. Yield once so this event-driven barrier observes that enqueue.\n\t\tawait Promise.resolve();\n\t\tfor (;;) {\n\t\t\tconst drain = this.notificationDrain;\n\t\t\tif (drain) {\n\t\t\t\tawait drain;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.queuedNotifications.length === 0) return;\n\t\t\tconst retry = this.notificationRetryCompletion;\n\t\t\tif (retry) {\n\t\t\t\tawait retry;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.disposed) return;\n\t\t\tthis.scheduleNotificationDrain();\n\t\t}\n\t}\n\n\tasync shutdown(): Promise<void> {\n\t\tif (!this.disposed) {\n\t\t\tthis.disposed = true;\n\t\t\tthis.handoffRequests.clear();\n\t\t\tfor (const state of this.tasks.values()) {\n\t\t\t\tif (state.record.status !== \"running\") continue;\n\t\t\t\tstate.cancellationRequested = true;\n\t\t\t\ttry {\n\t\t\t\t\tstate.cancel();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.deps.onError?.(`Failed to cancel background tool task ${state.record.taskId}`, error);\n\t\t\t\t}\n\t\t\t\tthis.finishState(\n\t\t\t\t\tstate,\n\t\t\t\t\t\"canceled\",\n\t\t\t\t\t\"Session ended before the background tool completed.\",\n\t\t\t\t\tundefined,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tawait this.waitForNotifications();\n\t}\n\n\tprivate settle(state: BackgroundToolTaskState, completion: BackgroundToolCallCompletion): void {\n\t\tif (state.record.status !== \"running\") return;\n\t\tconst status = state.cancellationRequested ? \"canceled\" : completion.isError ? \"failed\" : \"completed\";\n\t\tconst output = renderCompletionOutput(completion);\n\t\tthis.finishState(state, status, output, completion.result.usage, true);\n\t}\n\n\tprivate settleRejected(state: BackgroundToolTaskState, error: unknown): void {\n\t\tif (state.record.status !== \"running\") return;\n\t\tconst status = state.cancellationRequested ? \"canceled\" : \"failed\";\n\t\tconst output = error instanceof Error ? error.message : String(error);\n\t\tthis.finishState(state, status, output, undefined, true);\n\t}\n\n\tprivate restorePersistedTasks(): void {\n\t\tconst load = this.deps.loadPersistedRecordsNewestFirst;\n\t\tif (!load) return;\n\t\tlet values: readonly unknown[];\n\t\ttry {\n\t\t\tvalues = load();\n\t\t} catch (error) {\n\t\t\tthis.deps.onError?.(\"Failed to load persisted background tool tasks\", error);\n\t\t\treturn;\n\t\t}\n\t\tconst sessionId = this.deps.getSessionId();\n\t\tconst sessionIds = new Set(this.deps.getSessionLineageIds?.() ?? [sessionId]);\n\t\tsessionIds.add(sessionId);\n\t\tconst seenTaskIds = new Set<string>();\n\t\tconst latestRecords: BackgroundToolTaskRecord[] = [];\n\t\tlet highestTaskNumber = 0;\n\t\tfor (const value of values) {\n\t\t\tif (\n\t\t\t\t!isPlainRecord(value) ||\n\t\t\t\ttypeof value.sessionId !== \"string\" ||\n\t\t\t\t!sessionIds.has(value.sessionId) ||\n\t\t\t\ttypeof value.taskId !== \"string\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst numericTaskId = taskNumber(value.taskId);\n\t\t\tif (numericTaskId === undefined) continue;\n\t\t\thighestTaskNumber = Math.max(highestTaskNumber, numericTaskId);\n\t\t\tif (seenTaskIds.has(value.taskId)) continue;\n\t\t\tseenTaskIds.add(value.taskId);\n\t\t\tconst record = decodeRecord(value, sessionIds);\n\t\t\tif (record) latestRecords.push(record);\n\t\t}\n\t\tthis.nextTaskId = highestTaskNumber + 1;\n\t\tlatestRecords.sort((left, right) => taskNumber(left.taskId)! - taskNumber(right.taskId)!);\n\t\tfor (const record of latestRecords) {\n\t\t\tconst state = this.createState(record, () => {});\n\t\t\tthis.tasks.set(record.taskId, state);\n\t\t\tif (record.status !== \"running\") {\n\t\t\t\tstate.resolveTerminal(record);\n\t\t\t\tif (record.terminalDelivery === \"pending\") this.notify(record, true);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.finishState(\n\t\t\t\tstate,\n\t\t\t\t\"failed\",\n\t\t\t\t\"The session resumed after the owning process ended; the original tool completion is unavailable.\",\n\t\t\t\tundefined,\n\t\t\t\tfalse,\n\t\t\t);\n\t\t}\n\t\tthis.pruneTerminalTasks();\n\t\tthis.emitLiveTasks();\n\t}\n\n\tprivate createState(record: BackgroundToolTaskRecord, cancel: () => void): BackgroundToolTaskState {\n\t\tlet resolveTerminal: ((terminalRecord: BackgroundToolTaskRecord) => void) | undefined;\n\t\tconst terminal = new Promise<BackgroundToolTaskRecord>((resolve) => {\n\t\t\tresolveTerminal = resolve;\n\t\t});\n\t\treturn {\n\t\t\trecord: { ...record },\n\t\t\tcancel,\n\t\t\tcancellationRequested: record.cancellationRequested ?? false,\n\t\t\twaitingConsumers: 0,\n\t\t\tterminal,\n\t\t\tresolveTerminal: resolveTerminal!,\n\t\t\tartifactHolderId: `background-tool-task:${record.sessionId}:${record.taskId}`,\n\t\t};\n\t}\n\n\tprivate finishState(\n\t\tstate: BackgroundToolTaskState,\n\t\tstatus: Exclude<BackgroundToolTaskStatus, \"running\">,\n\t\trawOutput: string,\n\t\tusage: Usage | undefined,\n\t\tnotify: boolean,\n\t): void {\n\t\tconst packed = packToolOutput(\n\t\t\t{\n\t\t\t\ttoolName: state.record.toolName,\n\t\t\t\trawContent: rawOutput,\n\t\t\t\tsessionEntryId: state.record.taskId,\n\t\t\t\tcreatedAtTurn: 0,\n\t\t\t\treproducible: false,\n\t\t\t\ttruncation: { maxBytes: MAX_INLINE_OUTPUT_BYTES, maxLines: MAX_INLINE_OUTPUT_LINES },\n\t\t\t},\n\t\t\tthis.deps.getArtifactStore(),\n\t\t\tstate.artifactHolderId,\n\t\t);\n\t\tconst output = packed.artifactId\n\t\t\t? `${packed.content}\\n\\n[${formatArtifactNotice(packed.artifactId)}]`\n\t\t\t: packed.content;\n\t\tconst record: BackgroundToolTaskRecord = {\n\t\t\t...state.record,\n\t\t\tstatus,\n\t\t\tcompletedAt: this.now().toISOString(),\n\t\t\tsummary: summaryFor(status, state.record.toolName, output),\n\t\t\toutput,\n\t\t\t...(packed.artifactId ? { artifactId: packed.artifactId } : {}),\n\t\t\t...(usage ? { usage } : {}),\n\t\t\t...(state.cancellationRequested ? { cancellationRequested: true } : {}),\n\t\t\tterminalDelivery: notify ? \"pending\" : \"delivered\",\n\t\t};\n\t\tconst persisted = this.persist(record);\n\t\tconst terminalRecord = persisted\n\t\t\t? record\n\t\t\t: {\n\t\t\t\t\t...record,\n\t\t\t\t\tstatus: \"failed\" as const,\n\t\t\t\t\tsummary: `${record.toolName} failed: terminal result could not be persisted`,\n\t\t\t\t\toutput: \"Background tool result could not be persisted; treat it as unavailable.\",\n\t\t\t\t};\n\t\tstate.record = terminalRecord;\n\t\tif (usage) this.deps.recordUsage?.(record.taskId, usage);\n\t\tstate.resolveTerminal(terminalRecord);\n\t\tthis.emitLiveTasks();\n\t\tthis.pruneTerminalTasks();\n\t\tif (notify) this.notify(terminalRecord, state.waitingConsumers === 0);\n\t}\n\n\tprivate persist(record: BackgroundToolTaskRecord): boolean {\n\t\ttry {\n\t\t\tconst durableRecord = { ...record };\n\t\t\tdelete durableRecord.observedAt;\n\t\t\tthis.deps.persist(durableRecord);\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tthis.deps.onError?.(`Failed to persist background tool task ${record.taskId}`, error);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate notify(record: BackgroundToolTaskRecord, wakeParent: boolean): void {\n\t\tconst notificationRecord = {\n\t\t\t...record,\n\t\t\t...(!wakeParent && !record.observedAt ? { observedAt: this.now().toISOString() } : {}),\n\t\t};\n\t\tthis.activeNotificationRecords.add(notificationRecord);\n\t\tthis.queuedNotifications.push({ record: notificationRecord, wakeParent });\n\t\tthis.scheduleNotificationDrain();\n\t}\n\n\tprivate markNotificationDelivered(record: BackgroundToolTaskRecord): void {\n\t\tif (record.terminalDelivery !== \"pending\") return;\n\t\tconst delivered = { ...record, terminalDelivery: \"delivered\" as const };\n\t\tif (this.persist(delivered)) {\n\t\t\tconst state = this.tasks.get(record.taskId);\n\t\t\tif (state && state.record.completedAt === record.completedAt) state.record = delivered;\n\t\t}\n\t}\n\n\tprivate observeState(state: BackgroundToolTaskState): void {\n\t\tif (state.record.status === \"running\" || state.record.observedAt) return;\n\t\tconst observedAt = this.now().toISOString();\n\t\tstate.record = { ...state.record, observedAt };\n\t\tfor (const record of this.activeNotificationRecords) {\n\t\t\tif (record.taskId === state.record.taskId && record.completedAt === state.record.completedAt) {\n\t\t\t\trecord.observedAt = observedAt;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate scheduleNotificationDrain(): void {\n\t\tif (this.disposed || this.notificationDrain || this.notificationRetryTimer) return;\n\t\tthis.notificationDrain = this.drainNotifications().finally(() => {\n\t\t\tthis.notificationDrain = undefined;\n\t\t\tif (this.queuedNotifications.length > 0 && !this.notificationRetryTimer) this.scheduleNotificationDrain();\n\t\t});\n\t}\n\n\tprivate scheduleNotificationRetry(): void {\n\t\tif (this.disposed || this.notificationRetryTimer) return;\n\t\tconst delayMs = Math.min(100 * 2 ** Math.min(this.notificationRetryCount, 5), 5_000);\n\t\tthis.notificationRetryCount++;\n\t\tthis.notificationRetryCompletion = new Promise<void>((resolve) => {\n\t\t\tthis.resolveNotificationRetry = resolve;\n\t\t});\n\t\tthis.notificationRetryTimer = setTimeout(() => {\n\t\t\tthis.notificationRetryTimer = undefined;\n\t\t\tconst resolve = this.resolveNotificationRetry;\n\t\t\tthis.resolveNotificationRetry = undefined;\n\t\t\tthis.notificationRetryCompletion = undefined;\n\t\t\tresolve?.();\n\t\t\tthis.scheduleNotificationDrain();\n\t\t}, delayMs);\n\t\tthis.notificationRetryTimer.unref?.();\n\t}\n\n\tprivate async drainNotifications(): Promise<void> {\n\t\t// Allow completions released by the same event to reach this queue before forming the batch.\n\t\tawait Promise.resolve();\n\t\twhile (this.queuedNotifications.length > 0) {\n\t\t\tawait Promise.resolve();\n\t\t\tconst batch = this.queuedNotifications.splice(0);\n\t\t\tconst records = batch.map((notification) => notification.record);\n\t\t\ttry {\n\t\t\t\tawait this.deps.notifyTerminal(records, {\n\t\t\t\t\twakeParent: batch.some((notification) => notification.wakeParent),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\t// A rejected handoff is not a delivery receipt. Put the exact records back ahead of\n\t\t\t\t// newer completions and retry on an event-driven backoff; persistence already contains\n\t\t\t\t// the terminal, so a transient notifier failure must not make it disappear.\n\t\t\t\tthis.queuedNotifications.unshift(...batch);\n\t\t\t\tconst includedIds = records.slice(0, MAX_TERMINAL_HANDOFF_RECORDS).map((record) => record.taskId);\n\t\t\t\tconst omitted = records.length - includedIds.length;\n\t\t\t\tconst suffix = omitted > 0 ? ` (+${omitted} more)` : \"\";\n\t\t\t\ttry {\n\t\t\t\t\tthis.deps.onError?.(\n\t\t\t\t\t\t`Failed to notify terminal background tool task batch ${includedIds.join(\", \")}${suffix}`,\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t// Diagnostics cannot consume the pending terminal handoff.\n\t\t\t\t}\n\t\t\t\tthis.scheduleNotificationRetry();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.notificationRetryCount = 0;\n\t\t\tfor (const record of records) this.markNotificationDelivered(record);\n\t\t\tfor (const record of records) {\n\t\t\t\tthis.activeNotificationRecords.delete(record);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate emitLiveTasks(): void {\n\t\tconst tasks = [...this.tasks.values()]\n\t\t\t.filter((state) => state.record.status === \"running\")\n\t\t\t.map((state) => ({\n\t\t\t\ttaskId: state.record.taskId,\n\t\t\t\ttoolCallId: state.record.toolCallId,\n\t\t\t\ttoolName: state.record.toolName,\n\t\t\t\tdescription: state.record.summary,\n\t\t\t}));\n\t\ttry {\n\t\t\tthis.deps.onLiveTasksChanged?.(tasks);\n\t\t} catch (error) {\n\t\t\tthis.deps.onError?.(\"Failed to emit background tool task level signal\", error);\n\t\t}\n\t}\n\n\tprivate pruneTerminalTasks(): void {\n\t\tconst terminal = [...this.tasks.values()].filter((state) => state.record.status !== \"running\");\n\t\tfor (const state of terminal.slice(0, Math.max(0, terminal.length - MAX_RETAINED_TERMINAL_TASKS))) {\n\t\t\tthis.tasks.delete(state.record.taskId);\n\t\t\tif (!state.record.artifactId) continue;\n\t\t\tconst store = this.deps.getArtifactStore();\n\t\t\tstore?.removeReference(state.record.artifactId, state.artifactHolderId);\n\t\t\tstore?.cleanup();\n\t\t}\n\t}\n\n\tprivate now(): Date {\n\t\treturn this.deps.now?.() ?? new Date();\n\t}\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stateful foreground cost-guard owner.
|
|
3
|
+
*
|
|
4
|
+
* The controller brackets each ordinary foreground turn, projects the exact provider request once
|
|
5
|
+
* routing and context shaping are complete, and retains only the latest UI decision. AgentSession
|
|
6
|
+
* coordinates the turn; it does not own cost accounting or request-reasoning policy.
|
|
7
|
+
*/
|
|
8
|
+
import type { Api, Context, Model, SimpleStreamOptions } from "@caupulican/pi-ai";
|
|
9
|
+
import { type CostGuardDecision, type CostGuardSettings } from "./cost-guard.ts";
|
|
10
|
+
export interface CostGuardControllerDeps {
|
|
11
|
+
getSettings(): CostGuardSettings;
|
|
12
|
+
getCompactionReserveTokens(): number;
|
|
13
|
+
getSpawnedUsageCost(): number;
|
|
14
|
+
isUnmeteredSubscription(model: Model<Api>): boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare class CostGuardController {
|
|
17
|
+
private readonly deps;
|
|
18
|
+
private lastDecision;
|
|
19
|
+
private turnBaselineUsd;
|
|
20
|
+
constructor(deps: CostGuardControllerDeps);
|
|
21
|
+
/** Snapshot cumulative spawned spend before any work in a new foreground turn begins. */
|
|
22
|
+
beginForegroundTurn(): void;
|
|
23
|
+
/** Latest decision for the host UI. Disabled settings hide and invalidate prior projections. */
|
|
24
|
+
getLastDecision(): CostGuardDecision | undefined;
|
|
25
|
+
/** A settings transition invalidates the prior decision before another request is projected. */
|
|
26
|
+
invalidateDecision(): void;
|
|
27
|
+
/** Active threshold projected into the foreground capability envelope. */
|
|
28
|
+
getEnabledMaxTurnUsd(): number | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve cost policy after routing/context conversion reveals the real request. This projection
|
|
31
|
+
* is not an output cap; warning mode preserves capability and downgrade changes only this request.
|
|
32
|
+
* Background spend is turn-local: cumulative spawned usage minus the baseline captured by
|
|
33
|
+
* {@link beginForegroundTurn}. Per-lane dollar caps remain independent. Best-effort: never throws.
|
|
34
|
+
*/
|
|
35
|
+
resolveRequestReasoning(model: Model<Api>, context: Context, reasoning: SimpleStreamOptions["reasoning"], requestMaxTokens: number | undefined): SimpleStreamOptions["reasoning"];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=cost-guard-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-guard-controller.d.ts","sourceRoot":"","sources":["../../src/core/cost-guard-controller.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAElF,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAItB,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,uBAAuB;IACvC,WAAW,IAAI,iBAAiB,CAAC;IACjC,0BAA0B,IAAI,MAAM,CAAC;IACrC,mBAAmB,IAAI,MAAM,CAAC;IAC9B,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;CACpD;AAED,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,eAAe,CAAK;IAE5B,YAAY,IAAI,EAAE,uBAAuB,EAExC;IAED,yFAAyF;IACzF,mBAAmB,IAAI,IAAI,CAE1B;IAED,gGAAgG;IAChG,eAAe,IAAI,iBAAiB,GAAG,SAAS,CAE/C;IAED,gGAAgG;IAChG,kBAAkB,IAAI,IAAI,CAEzB;IAED,0EAA0E;IAC1E,oBAAoB,IAAI,MAAM,GAAG,SAAS,CAGzC;IAED;;;;;OAKG;IACH,uBAAuB,CACtB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,EAC3C,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAClC,mBAAmB,CAAC,WAAW,CAAC,CAiClC;CACD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stateful foreground cost-guard owner.
|
|
3
|
+
*
|
|
4
|
+
* The controller brackets each ordinary foreground turn, projects the exact provider request once
|
|
5
|
+
* routing and context shaping are complete, and retains only the latest UI decision. AgentSession
|
|
6
|
+
* coordinates the turn; it does not own cost accounting or request-reasoning policy.
|
|
7
|
+
*/
|
|
8
|
+
import { getSupportedThinkingLevels } from "@caupulican/pi-ai/models";
|
|
9
|
+
import { downgradeReasoning, estimateTurnCostUsd, evaluateCostGuard, } from "./cost-guard.js";
|
|
10
|
+
import { estimateContextPromptTokens } from "./models/perf-profile.js";
|
|
11
|
+
export class CostGuardController {
|
|
12
|
+
constructor(deps) {
|
|
13
|
+
this.turnBaselineUsd = 0;
|
|
14
|
+
this.deps = deps;
|
|
15
|
+
}
|
|
16
|
+
/** Snapshot cumulative spawned spend before any work in a new foreground turn begins. */
|
|
17
|
+
beginForegroundTurn() {
|
|
18
|
+
this.turnBaselineUsd = this.deps.getSpawnedUsageCost();
|
|
19
|
+
}
|
|
20
|
+
/** Latest decision for the host UI. Disabled settings hide and invalidate prior projections. */
|
|
21
|
+
getLastDecision() {
|
|
22
|
+
return this.deps.getSettings().enabled ? this.lastDecision : undefined;
|
|
23
|
+
}
|
|
24
|
+
/** A settings transition invalidates the prior decision before another request is projected. */
|
|
25
|
+
invalidateDecision() {
|
|
26
|
+
this.lastDecision = undefined;
|
|
27
|
+
}
|
|
28
|
+
/** Active threshold projected into the foreground capability envelope. */
|
|
29
|
+
getEnabledMaxTurnUsd() {
|
|
30
|
+
const settings = this.deps.getSettings();
|
|
31
|
+
return settings.enabled ? settings.maxTurnUsd : undefined;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolve cost policy after routing/context conversion reveals the real request. This projection
|
|
35
|
+
* is not an output cap; warning mode preserves capability and downgrade changes only this request.
|
|
36
|
+
* Background spend is turn-local: cumulative spawned usage minus the baseline captured by
|
|
37
|
+
* {@link beginForegroundTurn}. Per-lane dollar caps remain independent. Best-effort: never throws.
|
|
38
|
+
*/
|
|
39
|
+
resolveRequestReasoning(model, context, reasoning, requestMaxTokens) {
|
|
40
|
+
try {
|
|
41
|
+
const guard = this.deps.getSettings();
|
|
42
|
+
if (!guard.enabled || guard.maxTurnUsd <= 0 || !model.cost || this.deps.isUnmeteredSubscription(model)) {
|
|
43
|
+
this.lastDecision = undefined;
|
|
44
|
+
return reasoning;
|
|
45
|
+
}
|
|
46
|
+
const inputTokens = estimateContextPromptTokens(context);
|
|
47
|
+
// Use an explicit request cap when present; otherwise project against the session response
|
|
48
|
+
// reserve instead of a frontier model's theoretical output maximum.
|
|
49
|
+
const maxOutputTokens = Math.min(model.maxTokens ?? 4096, requestMaxTokens ?? this.deps.getCompactionReserveTokens());
|
|
50
|
+
const estUsd = estimateTurnCostUsd({
|
|
51
|
+
inputTokens,
|
|
52
|
+
maxOutputTokens,
|
|
53
|
+
cost: model.cost,
|
|
54
|
+
longContextPricing: model.longContextPricing,
|
|
55
|
+
});
|
|
56
|
+
// A dedup/rollup correction may move the cumulative total backward transiently; it must never
|
|
57
|
+
// turn background spend negative or lower the request projection.
|
|
58
|
+
const cumulativeBackgroundUsd = Math.max(0, this.deps.getSpawnedUsageCost() - this.turnBaselineUsd);
|
|
59
|
+
const decision = evaluateCostGuard(estUsd, guard, cumulativeBackgroundUsd);
|
|
60
|
+
this.lastDecision = decision;
|
|
61
|
+
if (!decision.over || guard.action !== "downgrade" || reasoning === undefined)
|
|
62
|
+
return reasoning;
|
|
63
|
+
return downgradeReasoning(reasoning, getSupportedThinkingLevels(model), model.thinkingLevelMap);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Cost policy is advisory/request-local and must never disrupt the foreground provider call.
|
|
67
|
+
return reasoning;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=cost-guard-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-guard-controller.js","sourceRoot":"","sources":["../../src/core/cost-guard-controller.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAGN,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AASvE,MAAM,OAAO,mBAAmB;IAK/B,YAAY,IAA6B;QAFjC,oBAAe,GAAG,CAAC,CAAC;QAG3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,yFAAyF;IACzF,mBAAmB;QAClB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;IACxD,CAAC;IAED,gGAAgG;IAChG,eAAe;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,CAAC;IAED,gGAAgG;IAChG,kBAAkB;QACjB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED,0EAA0E;IAC1E,oBAAoB;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACH,uBAAuB,CACtB,KAAiB,EACjB,OAAgB,EAChB,SAA2C,EAC3C,gBAAoC;QAEpC,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxG,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;gBAC9B,OAAO,SAAS,CAAC;YAClB,CAAC;YACD,MAAM,WAAW,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;YACzD,2FAA2F;YAC3F,oEAAoE;YACpE,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAC/B,KAAK,CAAC,SAAS,IAAI,IAAI,EACvB,gBAAgB,IAAI,IAAI,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAC1D,CAAC;YACF,MAAM,MAAM,GAAG,mBAAmB,CAAC;gBAClC,WAAW;gBACX,eAAe;gBACf,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;aAC5C,CAAC,CAAC;YACH,8FAA8F;YAC9F,kEAAkE;YAClE,MAAM,uBAAuB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;YACpG,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC;YAC3E,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;YAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,SAAS,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAChG,OAAO,kBAAkB,CAAC,SAAS,EAAE,0BAA0B,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAE7F,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,6FAA6F;YAC7F,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;CACD","sourcesContent":["/**\n * Stateful foreground cost-guard owner.\n *\n * The controller brackets each ordinary foreground turn, projects the exact provider request once\n * routing and context shaping are complete, and retains only the latest UI decision. AgentSession\n * coordinates the turn; it does not own cost accounting or request-reasoning policy.\n */\n\nimport type { Api, Context, Model, SimpleStreamOptions } from \"@caupulican/pi-ai\";\nimport { getSupportedThinkingLevels } from \"@caupulican/pi-ai/models\";\nimport {\n\ttype CostGuardDecision,\n\ttype CostGuardSettings,\n\tdowngradeReasoning,\n\testimateTurnCostUsd,\n\tevaluateCostGuard,\n} from \"./cost-guard.ts\";\nimport { estimateContextPromptTokens } from \"./models/perf-profile.ts\";\n\nexport interface CostGuardControllerDeps {\n\tgetSettings(): CostGuardSettings;\n\tgetCompactionReserveTokens(): number;\n\tgetSpawnedUsageCost(): number;\n\tisUnmeteredSubscription(model: Model<Api>): boolean;\n}\n\nexport class CostGuardController {\n\tprivate readonly deps: CostGuardControllerDeps;\n\tprivate lastDecision: CostGuardDecision | undefined;\n\tprivate turnBaselineUsd = 0;\n\n\tconstructor(deps: CostGuardControllerDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\t/** Snapshot cumulative spawned spend before any work in a new foreground turn begins. */\n\tbeginForegroundTurn(): void {\n\t\tthis.turnBaselineUsd = this.deps.getSpawnedUsageCost();\n\t}\n\n\t/** Latest decision for the host UI. Disabled settings hide and invalidate prior projections. */\n\tgetLastDecision(): CostGuardDecision | undefined {\n\t\treturn this.deps.getSettings().enabled ? this.lastDecision : undefined;\n\t}\n\n\t/** A settings transition invalidates the prior decision before another request is projected. */\n\tinvalidateDecision(): void {\n\t\tthis.lastDecision = undefined;\n\t}\n\n\t/** Active threshold projected into the foreground capability envelope. */\n\tgetEnabledMaxTurnUsd(): number | undefined {\n\t\tconst settings = this.deps.getSettings();\n\t\treturn settings.enabled ? settings.maxTurnUsd : undefined;\n\t}\n\n\t/**\n\t * Resolve cost policy after routing/context conversion reveals the real request. This projection\n\t * is not an output cap; warning mode preserves capability and downgrade changes only this request.\n\t * Background spend is turn-local: cumulative spawned usage minus the baseline captured by\n\t * {@link beginForegroundTurn}. Per-lane dollar caps remain independent. Best-effort: never throws.\n\t */\n\tresolveRequestReasoning(\n\t\tmodel: Model<Api>,\n\t\tcontext: Context,\n\t\treasoning: SimpleStreamOptions[\"reasoning\"],\n\t\trequestMaxTokens: number | undefined,\n\t): SimpleStreamOptions[\"reasoning\"] {\n\t\ttry {\n\t\t\tconst guard = this.deps.getSettings();\n\t\t\tif (!guard.enabled || guard.maxTurnUsd <= 0 || !model.cost || this.deps.isUnmeteredSubscription(model)) {\n\t\t\t\tthis.lastDecision = undefined;\n\t\t\t\treturn reasoning;\n\t\t\t}\n\t\t\tconst inputTokens = estimateContextPromptTokens(context);\n\t\t\t// Use an explicit request cap when present; otherwise project against the session response\n\t\t\t// reserve instead of a frontier model's theoretical output maximum.\n\t\t\tconst maxOutputTokens = Math.min(\n\t\t\t\tmodel.maxTokens ?? 4096,\n\t\t\t\trequestMaxTokens ?? this.deps.getCompactionReserveTokens(),\n\t\t\t);\n\t\t\tconst estUsd = estimateTurnCostUsd({\n\t\t\t\tinputTokens,\n\t\t\t\tmaxOutputTokens,\n\t\t\t\tcost: model.cost,\n\t\t\t\tlongContextPricing: model.longContextPricing,\n\t\t\t});\n\t\t\t// A dedup/rollup correction may move the cumulative total backward transiently; it must never\n\t\t\t// turn background spend negative or lower the request projection.\n\t\t\tconst cumulativeBackgroundUsd = Math.max(0, this.deps.getSpawnedUsageCost() - this.turnBaselineUsd);\n\t\t\tconst decision = evaluateCostGuard(estUsd, guard, cumulativeBackgroundUsd);\n\t\t\tthis.lastDecision = decision;\n\t\t\tif (!decision.over || guard.action !== \"downgrade\" || reasoning === undefined) return reasoning;\n\t\t\treturn downgradeReasoning(reasoning, getSupportedThinkingLevels(model), model.thinkingLevelMap) as NonNullable<\n\t\t\t\tSimpleStreamOptions[\"reasoning\"]\n\t\t\t>;\n\t\t} catch {\n\t\t\t// Cost policy is advisory/request-local and must never disrupt the foreground provider call.\n\t\t\treturn reasoning;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -35,14 +35,18 @@ export declare function estimateTurnCostUsd(args: {
|
|
|
35
35
|
/** What to do when a turn's projected cost exceeds the threshold. */
|
|
36
36
|
export type CostGuardAction = "warn" | "downgrade";
|
|
37
37
|
export interface CostGuardSettings {
|
|
38
|
-
/**
|
|
38
|
+
/** Explicit opt-in. A stored threshold without this flag is dormant legacy configuration. */
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
/** Per-turn projected USD threshold. Must also be explicitly enabled to activate the guard. */
|
|
39
41
|
maxTurnUsd: number;
|
|
40
42
|
/** Over the ceiling: `warn` (surface a notice) or `downgrade` (also reduce reasoning effort). */
|
|
41
43
|
action: CostGuardAction;
|
|
42
44
|
}
|
|
43
45
|
export declare const DEFAULT_COST_GUARD_SETTINGS: CostGuardSettings;
|
|
46
|
+
/** Threshold offered when the user enables an unconfigured guard from `/settings`. */
|
|
47
|
+
export declare const DEFAULT_ENABLED_COST_GUARD_MAX_TURN_USD = 0.5;
|
|
44
48
|
export interface CostGuardDecision {
|
|
45
|
-
/** True
|
|
49
|
+
/** True only after explicit opt-in and when projected TOTAL (estUsd + backgroundUsd) exceeds the ceiling. */
|
|
46
50
|
over: boolean;
|
|
47
51
|
/** Projected USD cost of the next foreground call alone (unchanged meaning — what the footer's "/turn" label shows). */
|
|
48
52
|
estUsd: number;
|
|
@@ -54,7 +58,8 @@ export interface CostGuardDecision {
|
|
|
54
58
|
action: CostGuardAction;
|
|
55
59
|
}
|
|
56
60
|
/**
|
|
57
|
-
* Decide whether the projected turn cost trips the guard.
|
|
61
|
+
* Decide whether the projected turn cost trips the guard. `enabled: true` is mandatory; a positive
|
|
62
|
+
* legacy threshold by itself stays dormant.
|
|
58
63
|
*
|
|
59
64
|
* `cumulativeBackgroundUsd` (default 0) is spawned/background-lane spend (research, worker delegation,
|
|
60
65
|
* reflection, model-fitness probes — see {@link SpawnedUsageTotals}) folded into the same ceiling as the
|
|
@@ -63,7 +68,7 @@ export interface CostGuardDecision {
|
|
|
63
68
|
* baseline snapshotted at the top of the turn, subtracted from the live cumulative total), not the
|
|
64
69
|
* session's entire lifetime, so a turn that is cheap in the foreground but has quietly spent a lot in
|
|
65
70
|
* background lanes THIS turn still trips the guard, without a prior turn's spend keeping it stuck over
|
|
66
|
-
* forever (still warn-only by default).
|
|
71
|
+
* forever (still warn-only by default). `cost-guard-controller.ts` owns that bracketing convention.
|
|
67
72
|
*/
|
|
68
73
|
export declare function evaluateCostGuard(estUsd: number, settings: CostGuardSettings, cumulativeBackgroundUsd?: number): CostGuardDecision;
|
|
69
74
|
/** Reasoning levels in descending cost order, used to pick the next-cheaper level on a downgrade. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost-guard.d.ts","sourceRoot":"","sources":["../../src/core/cost-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,gEAAgE;AAChE,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CACpG,GAAG,MAAM,CAaT;AAED,qEAAqE;AACrE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,WAAW,CAAC;AAEnD,MAAM,WAAW,iBAAiB;IACjC,
|
|
1
|
+
{"version":3,"file":"cost-guard.d.ts","sourceRoot":"","sources":["../../src/core/cost-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,gEAAgE;AAChE,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CACpG,GAAG,MAAM,CAaT;AAED,qEAAqE;AACrE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,WAAW,CAAC;AAEnD,MAAM,WAAW,iBAAiB;IACjC,6FAA6F;IAC7F,OAAO,EAAE,OAAO,CAAC;IACjB,+FAA+F;IAC/F,UAAU,EAAE,MAAM,CAAC;IACnB,iGAAiG;IACjG,MAAM,EAAE,eAAe,CAAC;CACxB;AAED,eAAO,MAAM,2BAA2B,EAAE,iBAIzC,CAAC;AAEF,sFAAsF;AACtF,eAAO,MAAM,uCAAuC,MAAM,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IACjC,6GAA6G;IAC7G,IAAI,EAAE,OAAO,CAAC;IACd,wHAAwH;IACxH,MAAM,EAAE,MAAM,CAAC;IACf,4KAA4K;IAC5K,aAAa,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,iBAAiB,EAC3B,uBAAuB,SAAI,GACzB,iBAAiB,CAYnB;AAED,qGAAqG;AACrG,QAAA,MAAM,gBAAgB,YAAI,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAU,CAAC;AACvG,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC/D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAO1F;;;;;GAKG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,EACf,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,EAC3C,SAAS,CAAC,EAAE,kBAAkB,GAC5B,cAAc,GAAG,MAAM,CAczB"}
|
package/dist/core/cost-guard.js
CHANGED
|
@@ -29,11 +29,15 @@ export function estimateTurnCostUsd(args) {
|
|
|
29
29
|
return inputUsd + outputUsd;
|
|
30
30
|
}
|
|
31
31
|
export const DEFAULT_COST_GUARD_SETTINGS = {
|
|
32
|
+
enabled: false,
|
|
32
33
|
maxTurnUsd: 0,
|
|
33
34
|
action: "warn",
|
|
34
35
|
};
|
|
36
|
+
/** Threshold offered when the user enables an unconfigured guard from `/settings`. */
|
|
37
|
+
export const DEFAULT_ENABLED_COST_GUARD_MAX_TURN_USD = 0.5;
|
|
35
38
|
/**
|
|
36
|
-
* Decide whether the projected turn cost trips the guard.
|
|
39
|
+
* Decide whether the projected turn cost trips the guard. `enabled: true` is mandatory; a positive
|
|
40
|
+
* legacy threshold by itself stays dormant.
|
|
37
41
|
*
|
|
38
42
|
* `cumulativeBackgroundUsd` (default 0) is spawned/background-lane spend (research, worker delegation,
|
|
39
43
|
* reflection, model-fitness probes — see {@link SpawnedUsageTotals}) folded into the same ceiling as the
|
|
@@ -42,10 +46,10 @@ export const DEFAULT_COST_GUARD_SETTINGS = {
|
|
|
42
46
|
* baseline snapshotted at the top of the turn, subtracted from the live cumulative total), not the
|
|
43
47
|
* session's entire lifetime, so a turn that is cheap in the foreground but has quietly spent a lot in
|
|
44
48
|
* background lanes THIS turn still trips the guard, without a prior turn's spend keeping it stuck over
|
|
45
|
-
* forever (still warn-only by default).
|
|
49
|
+
* forever (still warn-only by default). `cost-guard-controller.ts` owns that bracketing convention.
|
|
46
50
|
*/
|
|
47
51
|
export function evaluateCostGuard(estUsd, settings, cumulativeBackgroundUsd = 0) {
|
|
48
|
-
const enabled = settings.maxTurnUsd > 0;
|
|
52
|
+
const enabled = settings.enabled && settings.maxTurnUsd > 0;
|
|
49
53
|
const backgroundUsd = Math.max(0, cumulativeBackgroundUsd);
|
|
50
54
|
const totalUsd = estUsd + backgroundUsd;
|
|
51
55
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost-guard.js","sourceRoot":"","sources":["../../src/core/cost-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAMnC;IACA,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/E,MAAM,UAAU,GAAG,WAAW,GAAG,MAAM,CAAC;IACxC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC;IACnD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3E,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,CAAC;IACnD,MAAM,kBAAkB,GAAG,kBAAkB,IAAI,WAAW,GAAG,kBAAkB,CAAC,eAAe,CAAC;IAClG,MAAM,eAAe,GAAG,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,GAAG,cAAc,GAAG,MAAM,GAAG,aAAa,CAAC,GAAG,eAAe,CAAC,GAAG,SAAS,CAAC;IACxG,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,eAAe,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,gBAAgB,CAAC,GAAG,SAAS,CAAC;IAC9F,OAAO,QAAQ,GAAG,SAAS,CAAC;AAC7B,CAAC;
|
|
1
|
+
{"version":3,"file":"cost-guard.js","sourceRoot":"","sources":["../../src/core/cost-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAMnC;IACA,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/E,MAAM,UAAU,GAAG,WAAW,GAAG,MAAM,CAAC;IACxC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC;IACnD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3E,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,CAAC;IACnD,MAAM,kBAAkB,GAAG,kBAAkB,IAAI,WAAW,GAAG,kBAAkB,CAAC,eAAe,CAAC;IAClG,MAAM,eAAe,GAAG,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,GAAG,cAAc,GAAG,MAAM,GAAG,aAAa,CAAC,GAAG,eAAe,CAAC,GAAG,SAAS,CAAC;IACxG,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,eAAe,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,gBAAgB,CAAC,GAAG,SAAS,CAAC;IAC9F,OAAO,QAAQ,GAAG,SAAS,CAAC;AAC7B,CAAC;AAcD,MAAM,CAAC,MAAM,2BAA2B,GAAsB;IAC7D,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,CAAC;IACb,MAAM,EAAE,MAAM;CACd,CAAC;AAEF,sFAAsF;AACtF,MAAM,CAAC,MAAM,uCAAuC,GAAG,GAAG,CAAC;AAe3D;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAChC,MAAc,EACd,QAA2B,EAC3B,uBAAuB,GAAG,CAAC;IAE3B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;IACxC,OAAO;QACN,IAAI,EAAE,OAAO,IAAI,QAAQ,GAAG,QAAQ,CAAC,UAAU;QAC/C,MAAM;QACN,aAAa;QACb,QAAQ;QACR,YAAY,EAAE,QAAQ,CAAC,UAAU;QACjC,MAAM,EAAE,QAAQ,CAAC,MAAM;KACvB,CAAC;AACH,CAAC;AAED,qGAAqG;AACrG,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAU,CAAC;AAIvG,SAAS,wBAAwB,CAAC,KAAqB,EAAE,SAAyC;IACjG,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CACjC,OAAe,EACf,eAA2C,EAC3C,SAA8B;IAE9B,MAAM,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,OAAyB,CAAC,CAAC;IAC9D,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1B,IAAI,CAAC,eAAe,EAAE,CAAC;QACtB,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAiB,eAAe,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,wBAAwB,CAAC,OAAyB,EAAE,SAAS,CAAC,CAAC;IACrF,KAAK,IAAI,SAAS,GAAG,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;QAC9E,MAAM,SAAS,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,wBAAwB,CAAC,SAAS,EAAE,SAAS,CAAC,KAAK,aAAa;YAC/F,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["/**\n * Proactive per-turn token cost guard (Hermes-parity superiority item #34).\n *\n * Hermes (and pi today) only react to context growth by compressing AFTER it's expensive. This estimates\n * the dollar cost of the NEXT LLM call BEFORE it is submitted, so the agent can warn the user or\n * automatically reduce reasoning effort before a runaway billing spike — a proactive ceiling, not a\n * reactive cleanup. Pure functions: no I/O, fully testable.\n */\n\n/** Per-million-token USD prices, as carried on `Model.cost`. */\nexport interface ModelTokenCost {\n\tinput: number;\n\toutput: number;\n\tcacheRead?: number;\n\tcacheWrite?: number;\n}\n\n/**\n * Estimate the USD cost of one turn: the whole current context is billed as input, plus up to\n * `maxOutputTokens` of output. `cachedInputTokens` (prefix-cache hits) are billed at the cheaper\n * cache-read rate. Fresh input is billed once at the higher of the uncached-input and cache-write\n * rates because a provider may select that prefix for a new cache write. This is an UPPER bound on\n * the turn (it also assumes the model emits its full output budget), which is what a spending ceiling\n * should bound against.\n */\nexport function estimateTurnCostUsd(args: {\n\tinputTokens: number;\n\tmaxOutputTokens: number;\n\tcost: ModelTokenCost;\n\tcachedInputTokens?: number;\n\tlongContextPricing?: { thresholdTokens: number; inputMultiplier: number; outputMultiplier: number };\n}): number {\n\tconst { inputTokens, maxOutputTokens, cost } = args;\n\tconst cached = Math.max(0, Math.min(args.cachedInputTokens ?? 0, inputTokens));\n\tconst freshInput = inputTokens - cached;\n\tconst cacheReadRate = cost.cacheRead ?? cost.input;\n\tconst freshInputRate = Math.max(cost.input, cost.cacheWrite ?? cost.input);\n\tconst longContextPricing = args.longContextPricing;\n\tconst useLongContextTier = longContextPricing && inputTokens > longContextPricing.thresholdTokens;\n\tconst inputMultiplier = useLongContextTier ? longContextPricing.inputMultiplier : 1;\n\tconst outputMultiplier = useLongContextTier ? longContextPricing.outputMultiplier : 1;\n\tconst inputUsd = ((freshInput * freshInputRate + cached * cacheReadRate) * inputMultiplier) / 1_000_000;\n\tconst outputUsd = (Math.max(0, maxOutputTokens) * cost.output * outputMultiplier) / 1_000_000;\n\treturn inputUsd + outputUsd;\n}\n\n/** What to do when a turn's projected cost exceeds the threshold. */\nexport type CostGuardAction = \"warn\" | \"downgrade\";\n\nexport interface CostGuardSettings {\n\t/** Explicit opt-in. A stored threshold without this flag is dormant legacy configuration. */\n\tenabled: boolean;\n\t/** Per-turn projected USD threshold. Must also be explicitly enabled to activate the guard. */\n\tmaxTurnUsd: number;\n\t/** Over the ceiling: `warn` (surface a notice) or `downgrade` (also reduce reasoning effort). */\n\taction: CostGuardAction;\n}\n\nexport const DEFAULT_COST_GUARD_SETTINGS: CostGuardSettings = {\n\tenabled: false,\n\tmaxTurnUsd: 0,\n\taction: \"warn\",\n};\n\n/** Threshold offered when the user enables an unconfigured guard from `/settings`. */\nexport const DEFAULT_ENABLED_COST_GUARD_MAX_TURN_USD = 0.5;\n\nexport interface CostGuardDecision {\n\t/** True only after explicit opt-in and when projected TOTAL (estUsd + backgroundUsd) exceeds the ceiling. */\n\tover: boolean;\n\t/** Projected USD cost of the next foreground call alone (unchanged meaning — what the footer's \"/turn\" label shows). */\n\testUsd: number;\n\t/** Background/spawned-lane USD spend (research/worker/reflection/fitness) folded into this decision — the caller decides the window (e.g. since the current turn began). */\n\tbackgroundUsd: number;\n\t/** `estUsd + backgroundUsd` — the value actually compared against `thresholdUsd`. */\n\ttotalUsd: number;\n\tthresholdUsd: number;\n\taction: CostGuardAction;\n}\n\n/**\n * Decide whether the projected turn cost trips the guard. `enabled: true` is mandatory; a positive\n * legacy threshold by itself stays dormant.\n *\n * `cumulativeBackgroundUsd` (default 0) is spawned/background-lane spend (research, worker delegation,\n * reflection, model-fitness probes — see {@link SpawnedUsageTotals}) folded into the same ceiling as the\n * next foreground call. This function is window-agnostic — it just sums whatever the caller passes — but\n * the intended caller convention (agent-session.ts) is spend attributed to the CURRENT turn only (a\n * baseline snapshotted at the top of the turn, subtracted from the live cumulative total), not the\n * session's entire lifetime, so a turn that is cheap in the foreground but has quietly spent a lot in\n * background lanes THIS turn still trips the guard, without a prior turn's spend keeping it stuck over\n * forever (still warn-only by default). `cost-guard-controller.ts` owns that bracketing convention.\n */\nexport function evaluateCostGuard(\n\testUsd: number,\n\tsettings: CostGuardSettings,\n\tcumulativeBackgroundUsd = 0,\n): CostGuardDecision {\n\tconst enabled = settings.enabled && settings.maxTurnUsd > 0;\n\tconst backgroundUsd = Math.max(0, cumulativeBackgroundUsd);\n\tconst totalUsd = estUsd + backgroundUsd;\n\treturn {\n\t\tover: enabled && totalUsd > settings.maxTurnUsd,\n\t\testUsd,\n\t\tbackgroundUsd,\n\t\ttotalUsd,\n\t\tthresholdUsd: settings.maxTurnUsd,\n\t\taction: settings.action,\n\t};\n}\n\n/** Reasoning levels in descending cost order, used to pick the next-cheaper level on a downgrade. */\nconst REASONING_LADDER = [\"ultra\", \"max\", \"xhigh\", \"high\", \"medium\", \"low\", \"minimal\", \"off\"] as const;\nexport type ReasoningLevel = (typeof REASONING_LADDER)[number];\nexport type ReasoningEffortMap = Readonly<Partial<Record<ReasoningLevel, string | null>>>;\n\nfunction effectiveReasoningEffort(level: ReasoningLevel, effortMap: ReasoningEffortMap | undefined): string | null {\n\tconst mapped = effortMap?.[level];\n\treturn mapped === undefined ? level : mapped;\n}\n\n/**\n * One supported step down the reasoning ladder (cost reduction) from `current`. When\n * `supportedLevels` is provided, unsupported intermediate levels are skipped instead of relying on a\n * provider clamp that may move back upward. Returns `current` unchanged when already at the model's\n * floor or unrecognized — the guard never raises effort, only lowers it.\n */\nexport function downgradeReasoning(\n\tcurrent: string,\n\tsupportedLevels?: readonly ReasoningLevel[],\n\teffortMap?: ReasoningEffortMap,\n): ReasoningLevel | string {\n\tconst i = REASONING_LADDER.indexOf(current as ReasoningLevel);\n\tif (i < 0) return current;\n\tif (!supportedLevels) {\n\t\treturn REASONING_LADDER[Math.min(i + 1, REASONING_LADDER.length - 1)];\n\t}\n\tconst supported = new Set<ReasoningLevel>(supportedLevels);\n\tconst currentEffort = effectiveReasoningEffort(current as ReasoningLevel, effortMap);\n\tfor (let nextIndex = i + 1; nextIndex < REASONING_LADDER.length; nextIndex++) {\n\t\tconst candidate = REASONING_LADDER[nextIndex];\n\t\tif (supported.has(candidate) && effectiveReasoningEffort(candidate, effortMap) !== currentEffort)\n\t\t\treturn candidate;\n\t}\n\treturn current;\n}\n"]}
|
|
@@ -42,7 +42,7 @@ export declare function runProviderCompletionWithBackoff(args: {
|
|
|
42
42
|
* The provider/tool-loop portion of a prepared worker attempt.
|
|
43
43
|
*
|
|
44
44
|
* Admission, durable leasing, grant compilation, terminalization, notification, verification, and
|
|
45
|
-
* scheduling remain outside this boundary. This unit owns only the ordered
|
|
45
|
+
* scheduling remain outside this boundary. This unit owns only the ordered worker conversation:
|
|
46
46
|
* persist assistant tool requests before execution, append messages before mailbox acknowledgements,
|
|
47
47
|
* checkpoint cumulative usage before later boundaries, and compact only the provider projection.
|
|
48
48
|
*/
|