@code-yeongyu/senpi 2026.9.7-2 → 2026.9.8
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 +42 -0
- package/dist/core/agent-session.d.ts +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +41 -18
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/dynamic-prompt/working-task.js +1 -1
- package/dist/core/dynamic-prompt/working-task.js.map +1 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.js +3 -2
- package/dist/core/extensions/builtin/cache-keepalive/index.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js +10 -25
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +8 -0
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +110 -28
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +52 -9
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.js +11 -0
- package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm.d.ts +17 -11
- package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm.js +17 -11
- package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts +3 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.js +17 -2
- package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +1 -0
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +6 -4
- package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.d.ts +5 -1
- package/dist/core/extensions/builtin/gpt-account.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.js +9 -26
- package/dist/core/extensions/builtin/gpt-account.js.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.d.ts +18 -0
- package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.js +23 -0
- package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
- package/dist/core/extensions/builtin/oauth-login-interaction.d.ts +24 -0
- package/dist/core/extensions/builtin/oauth-login-interaction.d.ts.map +1 -0
- package/dist/core/extensions/builtin/oauth-login-interaction.js +77 -0
- package/dist/core/extensions/builtin/oauth-login-interaction.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +14 -7
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +34 -13
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +6 -10
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +14 -9
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +15 -15
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +49 -21
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
- package/dist/core/extensions/builtin/service-tier.d.ts +2 -0
- package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
- package/dist/core/extensions/builtin/service-tier.js +17 -1
- package/dist/core/extensions/builtin/service-tier.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.js +3 -0
- package/dist/core/extensions/builtin/terminal/durable-command.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.js +2 -0
- package/dist/core/extensions/builtin/terminal/durable-file.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +14 -2
- package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.js +27 -5
- package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +17 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.js +62 -7
- package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.d.ts +2 -0
- package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.js +6 -1
- package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.d.ts +3 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.js +13 -0
- package/dist/core/extensions/builtin/terminal/session-bundle.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.d.ts +13 -2
- package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.js +15 -2
- package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js +8 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
- package/dist/core/extensions/builtin/tool-search/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/tool-search/index.js +1 -0
- package/dist/core/extensions/builtin/tool-search/index.js.map +1 -1
- package/dist/core/extensions/builtin/tool-search/service.d.ts +4 -0
- package/dist/core/extensions/builtin/tool-search/service.d.ts.map +1 -1
- package/dist/core/extensions/builtin/tool-search/service.js +11 -0
- package/dist/core/extensions/builtin/tool-search/service.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +8 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +9 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/high-reasoning-warning.d.ts.map +1 -1
- package/dist/core/high-reasoning-warning.js +4 -6
- package/dist/core/high-reasoning-warning.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +25 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.js +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-shapes.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/providers.md +5 -1
- package/docs/settings.md +1 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +14 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +17 -24
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +7 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +19 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +24 -16
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +47 -178
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js +260 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts +40 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js +138 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts +2 -3
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js +42 -139
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js +29 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js +20 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js +16 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export function buildWorkingTaskSection() {
|
|
2
2
|
return `## Working the Task
|
|
3
3
|
|
|
4
|
-
Fire independent tool calls as one parallel wave - reads, searches, listings, diagnostics - and bias toward breadth when context is thin: pull in anything even loosely relevant now instead of serially later. Wasted reads cost almost nothing; stale assumptions cost the turn.
|
|
4
|
+
Fire independent tool calls as one parallel wave - reads, searches, listings, diagnostics - and bias toward breadth when context is thin: pull in anything even loosely relevant now instead of serially later. Wasted reads cost almost nothing; stale assumptions cost the turn. Edits and result-dependent calls go one at a time, each compared with the state you meant to produce; when the result must be seen rather than read, render after each change and look before the next. Never fill missing parameters with placeholders.
|
|
5
5
|
|
|
6
6
|
Memory of file contents is unreliable - read before claiming, re-read before editing. Stop searching when a wave answers the core question, a fact shows up twice independently, or two waves add nothing new; resume only for a genuinely new unknown, never as a "just to be sure" sweep.
|
|
7
7
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"working-task.js","sourceRoot":"","sources":["../../../src/core/dynamic-prompt/working-task.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,uBAAuB;IACtC,OAAO;;;;;;waAMga,CAAC;AACza,CAAC","sourcesContent":["export function buildWorkingTaskSection(): string {\n\treturn `## Working the Task\n\nFire independent tool calls as one parallel wave - reads, searches, listings, diagnostics - and bias toward breadth when context is thin: pull in anything even loosely relevant now instead of serially later. Wasted reads cost almost nothing; stale assumptions cost the turn.
|
|
1
|
+
{"version":3,"file":"working-task.js","sourceRoot":"","sources":["../../../src/core/dynamic-prompt/working-task.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,uBAAuB;IACtC,OAAO;;;;;;waAMga,CAAC;AACza,CAAC","sourcesContent":["export function buildWorkingTaskSection(): string {\n\treturn `## Working the Task\n\nFire independent tool calls as one parallel wave - reads, searches, listings, diagnostics - and bias toward breadth when context is thin: pull in anything even loosely relevant now instead of serially later. Wasted reads cost almost nothing; stale assumptions cost the turn. Edits and result-dependent calls go one at a time, each compared with the state you meant to produce; when the result must be seen rather than read, render after each change and look before the next. Never fill missing parameters with placeholders.\n\nMemory of file contents is unreliable - read before claiming, re-read before editing. Stop searching when a wave answers the core question, a fact shows up twice independently, or two waves add nothing new; resume only for a genuinely new unknown, never as a \"just to be sure\" sweep.\n\nMake one reasonable plan and execute it; reopen it only when new evidence contradicts it. Do not re-derive facts already established in the conversation or re-litigate decisions the user has made. When weighing a choice, give a recommendation, not a survey. When a delegation tool is available, hand sizeable independent tracks to subagents and keep working while they run; keep work you can finish in a few calls yourself.`;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cache-keepalive/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,OAAO,EAEZ,KAAK,KAAK,EAGV,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAE1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,aAAa,EAAkC,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGtG,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AAEvD,UAAU,YAAY;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC1B;AAED,UAAU,SAAS;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACxC;AAED,UAAU,YAAY;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACxC;AAED,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,SAAS,GAAG,YAAY,CAAC;AAE9E,KAAK,iBAAiB,GAAG,CACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,sBAAsB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpC,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,uBAAuB,CAS3E,CAAC;AAEH,wBAAgB,6BAA6B,CAC5C,YAAY,GAAE;IAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,iBAAiB,CAAA;CAAO,GACjE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cache-keepalive/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,OAAO,EAEZ,KAAK,KAAK,EAGV,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAE1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,aAAa,EAAkC,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGtG,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AAEvD,UAAU,YAAY;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC1B;AAED,UAAU,SAAS;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACxC;AAED,UAAU,YAAY;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACxC;AAED,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,SAAS,GAAG,YAAY,CAAC;AAE9E,KAAK,iBAAiB,GAAG,CACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,sBAAsB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpC,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,uBAAuB,CAS3E,CAAC;AAEH,wBAAgB,6BAA6B,CAC5C,YAAY,GAAE;IAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,iBAAiB,CAAA;CAAO,GACjE,gBAAgB,CA+MlB;;AAuDD,wBAA+C"}
|
|
@@ -29,8 +29,9 @@ export function createCacheKeepAliveExtension(dependencies = {}) {
|
|
|
29
29
|
let lastMessages = [];
|
|
30
30
|
let lastUsage;
|
|
31
31
|
pi.registerEntryRenderer(CACHE_KEEPALIVE_ENTRY_TYPE, renderCacheKeepAliveEntry);
|
|
32
|
-
// No goal-timer coupling: an armed goal continuation timer
|
|
33
|
-
//
|
|
32
|
+
// No goal-timer coupling: an armed goal continuation timer issues no
|
|
33
|
+
// provider request until it fires, and `promptCache.goalBackstopMaxSeconds`
|
|
34
|
+
// may place that past the TTL, so it cannot be relied on to refresh the
|
|
34
35
|
// prompt cache on this loop's behalf.
|
|
35
36
|
function append(data) {
|
|
36
37
|
pi.appendEntry(CACHE_KEEPALIVE_ENTRY_TYPE, data);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cache-keepalive/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype Context,\n\tisAnthropicApiBaseUrl,\n\ttype Model,\n\tresolvePromptCacheTtlSeconds,\n\ttype Tool,\n\ttype WarmPromptCacheOptions,\n\ttype WarmPromptCacheResult,\n\twarmPromptCache,\n} from \"@earendil-works/pi-ai\";\nimport { convertToLlm, filterContextExcludedMessages } from \"../../../messages.ts\";\nimport { noticeEntryRenderer } from \"../../notice/index.ts\";\nimport type { EntryRenderer, ExtensionAPI, ExtensionContext, ExtensionFactory } from \"../../types.ts\";\nimport { formatWarmTokenCount } from \"../goal/cache-warm.ts\";\n\nexport const CACHE_KEEPALIVE_ENTRY_TYPE = \"cache-keepalive\";\nexport const CACHE_WARM_PING_EVENT = \"cache_warm_ping\";\n\ninterface StartedEntry {\n\treadonly phase: \"started\";\n}\n\ninterface PingEntry {\n\treadonly phase: \"ping\";\n\treadonly iteration: number;\n\treadonly cacheRead: number;\n\treadonly cacheWrite: number;\n\treadonly estimatedCostUsd: number;\n\treadonly cumulativeEstimatedUsd: number;\n}\n\ninterface StoppedEntry {\n\treadonly phase: \"stopped\";\n\treadonly iterations: number;\n\treadonly stopReason: string;\n\treadonly cumulativeEstimatedUsd: number;\n}\n\nexport type CacheKeepAliveEntryData = StartedEntry | PingEntry | StoppedEntry;\n\ntype WarmPromptCacheFn = (\n\tmodel: Model<any>,\n\tcontext: Context,\n\toptions?: WarmPromptCacheOptions,\n) => Promise<WarmPromptCacheResult>;\n\nexport const renderCacheKeepAliveEntry: EntryRenderer<CacheKeepAliveEntryData> = noticeEntryRenderer((entry) => {\n\tconst data = entry.data;\n\tif (data?.phase !== \"ping\") return undefined;\n\tconst refreshed = data.cacheRead + data.cacheWrite;\n\treturn {\n\t\ttitle: `⚡ Warm ping #${data.iteration} · ~${formatWarmTokenCount(refreshed)} tokens refreshed · ${formatUsd(data.estimatedCostUsd)}`,\n\t\twhy: \"Refreshed the active Anthropic prompt cache while the session was idle.\",\n\t\texpandedLine: `cache read ${data.cacheRead} · cache write ${data.cacheWrite} · session total ${formatUsd(data.cumulativeEstimatedUsd)}`,\n\t};\n});\n\nexport function createCacheKeepAliveExtension(\n\tdependencies: { readonly warmPromptCache?: WarmPromptCacheFn } = {},\n): ExtensionFactory {\n\tconst warm = dependencies.warmPromptCache ?? warmPromptCache;\n\treturn (pi: ExtensionAPI) => {\n\t\tlet ctx: ExtensionContext | undefined;\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet inFlight = false;\n\t\tlet generation = 0;\n\t\tlet active = false;\n\t\tlet attempts = 0;\n\t\tlet cumulativeEstimatedUsd = 0;\n\t\tlet lastCompletedAtMs: number | undefined;\n\t\tlet lastMessages: AgentMessage[] = [];\n\t\tlet lastUsage: { input: number; cacheRead: number; cacheWrite: number } | undefined;\n\n\t\tpi.registerEntryRenderer(CACHE_KEEPALIVE_ENTRY_TYPE, renderCacheKeepAliveEntry);\n\n\t\t// No goal-timer coupling: an armed goal continuation timer is now a long\n\t\t// stall backstop that issues no provider request, so it cannot refresh the\n\t\t// prompt cache on this loop's behalf.\n\t\tfunction append(data: CacheKeepAliveEntryData): void {\n\t\t\tpi.appendEntry(CACHE_KEEPALIVE_ENTRY_TYPE, data);\n\t\t}\n\n\t\tfunction stop(reason: string, forceEntry = false): void {\n\t\t\tconst shouldAppend = active || inFlight || timer !== undefined || forceEntry;\n\t\t\tgeneration += 1;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tactive = false;\n\t\t\tif (shouldAppend) {\n\t\t\t\tappend({\n\t\t\t\t\tphase: \"stopped\",\n\t\t\t\t\titerations: attempts,\n\t\t\t\t\tstopReason: reason,\n\t\t\t\t\tcumulativeEstimatedUsd,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction arm(): void {\n\t\t\tif (timer !== undefined || inFlight) return;\n\t\t\tconst current = ctx;\n\t\t\tconst settings = current?.getPromptCacheKeepAliveSettings?.();\n\t\t\tif (!settings?.enabled || current?.model === undefined || lastCompletedAtMs === undefined) return;\n\t\t\tif (!isWarmSupportedModel(current.model)) return;\n\t\t\tif (!current.isIdle()) {\n\t\t\t\tstop(\"agent-busy\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (current.hasPendingMessages()) {\n\t\t\t\tstop(\"pending-messages\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst safeWaitSeconds = current.getPromptCacheSafeWaitSeconds?.();\n\t\t\tif (safeWaitSeconds === undefined || !Number.isFinite(safeWaitSeconds)) return;\n\t\t\tif (attempts >= Math.max(0, settings.maxRequestsPerSession)) {\n\t\t\t\tstop(\"max-requests\", true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst projectedUsd = projectedPingCost(current.model, lastUsage);\n\t\t\tif (cumulativeEstimatedUsd + projectedUsd > Math.max(0, settings.maxCostUsdPerSession)) {\n\t\t\t\tstop(\"cost-cap\", true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!active) {\n\t\t\t\tactive = true;\n\t\t\t\tappend({ phase: \"started\" });\n\t\t\t}\n\t\t\tconst intervalMs = Math.max(0, safeWaitSeconds - Math.max(0, settings.marginSeconds)) * 1000;\n\t\t\tconst delayMs = Math.max(0, lastCompletedAtMs + intervalMs - Date.now());\n\t\t\tconst scheduledGeneration = generation;\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\ttimer = undefined;\n\t\t\t\tvoid ping(scheduledGeneration);\n\t\t\t}, delayMs);\n\t\t}\n\n\t\tasync function ping(scheduledGeneration: number): Promise<void> {\n\t\t\tif (scheduledGeneration !== generation) return;\n\t\t\tconst current = ctx;\n\t\t\tconst settings = current?.getPromptCacheKeepAliveSettings?.();\n\t\t\tif (\n\t\t\t\tcurrent === undefined ||\n\t\t\t\tsettings?.enabled !== true ||\n\t\t\t\tcurrent.model === undefined ||\n\t\t\t\t!isWarmSupportedModel(current.model) ||\n\t\t\t\t!current.isIdle() ||\n\t\t\t\tcurrent.hasPendingMessages() ||\n\t\t\t\tattempts >= Math.max(0, settings.maxRequestsPerSession) ||\n\t\t\t\tcumulativeEstimatedUsd + projectedPingCost(current.model, lastUsage) >\n\t\t\t\t\tMath.max(0, settings.maxCostUsdPerSession)\n\t\t\t) {\n\t\t\t\tarm();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tinFlight = true;\n\t\t\tattempts += 1;\n\t\t\tconst iteration = attempts;\n\t\t\tconst pingGeneration = generation;\n\t\t\ttry {\n\t\t\t\tconst preparation = await current.prepareProviderRequest?.(lastMessages);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst preparedMessages = preparation?.messages ?? lastMessages;\n\t\t\t\tconst activeToolNames = new Set(pi.getActiveTools());\n\t\t\t\tconst tools: Tool[] = pi\n\t\t\t\t\t.getAllTools()\n\t\t\t\t\t.filter((tool) => activeToolNames.has(tool.name))\n\t\t\t\t\t.map(({ name, description, parameters }) => ({ name, description, parameters }));\n\t\t\t\tconst auth = await current.modelRegistry.getApiKeyAndHeaders(current.model);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!auth.ok) throw new Error(auth.error);\n\t\t\t\tconst authHeaders = auth.headers ?? {};\n\t\t\t\tconst headers = preparation ? await preparation.transformHeaders(authHeaders) : authHeaders;\n\t\t\t\tconst result = await warm(\n\t\t\t\t\tcurrent.model,\n\t\t\t\t\t{\n\t\t\t\t\t\tsystemPrompt: current.getSystemPrompt(),\n\t\t\t\t\t\tmessages: convertToLlm(filterContextExcludedMessages(preparedMessages)),\n\t\t\t\t\t\t...(tools.length > 0 ? { tools } : {}),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tsessionId: current.sessionManager.getSessionId(),\n\t\t\t\t\t\tcacheRetention: current.model.cacheRetention,\n\t\t\t\t\t\tonPayload: preparation ? async (payload) => await preparation.transformPayload(payload) : undefined,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!result.supported) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tstop(\"unsupported-model\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst estimatedCostUsd = actualPingCost(current.model, result.usage);\n\t\t\t\tcumulativeEstimatedUsd += estimatedCostUsd;\n\t\t\t\tlastCompletedAtMs = Date.now();\n\t\t\t\tconst cachedTokens = result.usage.cacheRead + result.usage.cacheWrite;\n\t\t\t\tconst ttlSeconds = resolvePromptCacheTtlSeconds(current.model) ?? 0;\n\t\t\t\tpi.events?.emit(CACHE_WARM_PING_EVENT, { iteration, cachedTokens, ttlSeconds, estimatedCostUsd });\n\t\t\t\tappend({\n\t\t\t\t\tphase: \"ping\",\n\t\t\t\t\titeration,\n\t\t\t\t\tcacheRead: result.usage.cacheRead,\n\t\t\t\t\tcacheWrite: result.usage.cacheWrite,\n\t\t\t\t\testimatedCostUsd,\n\t\t\t\t\tcumulativeEstimatedUsd,\n\t\t\t\t});\n\t\t\t\tinFlight = false;\n\t\t\t\tarm();\n\t\t\t} catch {\n\t\t\t\tinFlight = false;\n\t\t\t\tif (pingGeneration === generation) stop(\"provider-error\");\n\t\t\t\telse arm();\n\t\t\t}\n\t\t}\n\n\t\tpi.on(\"session_start\", (_event, nextCtx) => {\n\t\t\tstop(\"session-restart\");\n\t\t\tctx = nextCtx;\n\t\t\tattempts = 0;\n\t\t\tcumulativeEstimatedUsd = 0;\n\t\t\tlastMessages = nextCtx.sessionManager.buildSessionContext().messages;\n\t\t\tconst usage = lastAssistantUsage(lastMessages);\n\t\t\tlastUsage = usage;\n\t\t\tlastCompletedAtMs = lastAssistantTimestamp(lastMessages);\n\t\t\tarm();\n\t\t});\n\n\t\tpi.on(\"agent_end\", (event, nextCtx) => {\n\t\t\tctx = nextCtx;\n\t\t\tconst usage = lastAssistantUsage(event.messages);\n\t\t\tif (usage?.stopReason === \"error\") {\n\t\t\t\tstop(\"provider-error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlastMessages = [...event.messages];\n\t\t\tlastUsage = usage;\n\t\t\tlastCompletedAtMs = Date.now();\n\t\t\tarm();\n\t\t});\n\n\t\tpi.on(\"model_select\", (_event, nextCtx) => {\n\t\t\tctx = nextCtx;\n\t\t\tstop(\"model-changed\");\n\t\t\tarm();\n\t\t});\n\t\tpi.on(\"agent_start\", () => stop(\"agent-busy\"));\n\t\tpi.on(\"input\", () => stop(\"user-input\"));\n\t\tpi.on(\"session_shutdown\", () => {\n\t\t\tstop(\"session-dispose\");\n\t\t\tctx = undefined;\n\t\t});\n\t};\n}\n\nfunction isWarmSupportedModel(model: Model<any>): model is Model<\"anthropic-messages\"> {\n\treturn model.api === \"anthropic-messages\" && isAnthropicApiBaseUrl(model.baseUrl);\n}\n\nfunction lastAssistantUsage(\n\tmessages: readonly AgentMessage[],\n): { input: number; cacheRead: number; cacheWrite: number; stopReason?: string } | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message.role !== \"assistant\") continue;\n\t\treturn {\n\t\t\tinput: finiteTokens(message.usage.input),\n\t\t\tcacheRead: finiteTokens(message.usage.cacheRead),\n\t\t\tcacheWrite: finiteTokens(message.usage.cacheWrite),\n\t\t\tstopReason: message.stopReason,\n\t\t};\n\t}\n\treturn undefined;\n}\n\nfunction lastAssistantTimestamp(messages: readonly AgentMessage[]): number | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message.role === \"assistant\" && Number.isFinite(message.timestamp)) return message.timestamp;\n\t}\n\treturn undefined;\n}\n\nfunction projectedPingCost(\n\tmodel: Model<any>,\n\tusage: { input: number; cacheRead: number; cacheWrite: number } | undefined,\n): number {\n\tconst promptTokens = (usage?.input ?? 0) + (usage?.cacheRead ?? 0) + (usage?.cacheWrite ?? 0);\n\treturn (promptTokens * Math.max(model.cost.cacheRead, model.cost.cacheWrite)) / 1_000_000;\n}\n\nfunction actualPingCost(model: Model<any>, usage: { input: number; cacheRead: number; cacheWrite: number }): number {\n\treturn (\n\t\t(usage.cacheRead * model.cost.cacheRead +\n\t\t\tusage.cacheWrite * model.cost.cacheWrite +\n\t\t\tusage.input * model.cost.input) /\n\t\t1_000_000\n\t);\n}\n\nfunction finiteTokens(value: number): number {\n\treturn Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nfunction formatUsd(value: number): string {\n\treturn `$${value.toFixed(3)}`;\n}\n\nexport default createCacheKeepAliveExtension();\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cache-keepalive/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype Context,\n\tisAnthropicApiBaseUrl,\n\ttype Model,\n\tresolvePromptCacheTtlSeconds,\n\ttype Tool,\n\ttype WarmPromptCacheOptions,\n\ttype WarmPromptCacheResult,\n\twarmPromptCache,\n} from \"@earendil-works/pi-ai\";\nimport { convertToLlm, filterContextExcludedMessages } from \"../../../messages.ts\";\nimport { noticeEntryRenderer } from \"../../notice/index.ts\";\nimport type { EntryRenderer, ExtensionAPI, ExtensionContext, ExtensionFactory } from \"../../types.ts\";\nimport { formatWarmTokenCount } from \"../goal/cache-warm.ts\";\n\nexport const CACHE_KEEPALIVE_ENTRY_TYPE = \"cache-keepalive\";\nexport const CACHE_WARM_PING_EVENT = \"cache_warm_ping\";\n\ninterface StartedEntry {\n\treadonly phase: \"started\";\n}\n\ninterface PingEntry {\n\treadonly phase: \"ping\";\n\treadonly iteration: number;\n\treadonly cacheRead: number;\n\treadonly cacheWrite: number;\n\treadonly estimatedCostUsd: number;\n\treadonly cumulativeEstimatedUsd: number;\n}\n\ninterface StoppedEntry {\n\treadonly phase: \"stopped\";\n\treadonly iterations: number;\n\treadonly stopReason: string;\n\treadonly cumulativeEstimatedUsd: number;\n}\n\nexport type CacheKeepAliveEntryData = StartedEntry | PingEntry | StoppedEntry;\n\ntype WarmPromptCacheFn = (\n\tmodel: Model<any>,\n\tcontext: Context,\n\toptions?: WarmPromptCacheOptions,\n) => Promise<WarmPromptCacheResult>;\n\nexport const renderCacheKeepAliveEntry: EntryRenderer<CacheKeepAliveEntryData> = noticeEntryRenderer((entry) => {\n\tconst data = entry.data;\n\tif (data?.phase !== \"ping\") return undefined;\n\tconst refreshed = data.cacheRead + data.cacheWrite;\n\treturn {\n\t\ttitle: `⚡ Warm ping #${data.iteration} · ~${formatWarmTokenCount(refreshed)} tokens refreshed · ${formatUsd(data.estimatedCostUsd)}`,\n\t\twhy: \"Refreshed the active Anthropic prompt cache while the session was idle.\",\n\t\texpandedLine: `cache read ${data.cacheRead} · cache write ${data.cacheWrite} · session total ${formatUsd(data.cumulativeEstimatedUsd)}`,\n\t};\n});\n\nexport function createCacheKeepAliveExtension(\n\tdependencies: { readonly warmPromptCache?: WarmPromptCacheFn } = {},\n): ExtensionFactory {\n\tconst warm = dependencies.warmPromptCache ?? warmPromptCache;\n\treturn (pi: ExtensionAPI) => {\n\t\tlet ctx: ExtensionContext | undefined;\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet inFlight = false;\n\t\tlet generation = 0;\n\t\tlet active = false;\n\t\tlet attempts = 0;\n\t\tlet cumulativeEstimatedUsd = 0;\n\t\tlet lastCompletedAtMs: number | undefined;\n\t\tlet lastMessages: AgentMessage[] = [];\n\t\tlet lastUsage: { input: number; cacheRead: number; cacheWrite: number } | undefined;\n\n\t\tpi.registerEntryRenderer(CACHE_KEEPALIVE_ENTRY_TYPE, renderCacheKeepAliveEntry);\n\n\t\t// No goal-timer coupling: an armed goal continuation timer issues no\n\t\t// provider request until it fires, and `promptCache.goalBackstopMaxSeconds`\n\t\t// may place that past the TTL, so it cannot be relied on to refresh the\n\t\t// prompt cache on this loop's behalf.\n\t\tfunction append(data: CacheKeepAliveEntryData): void {\n\t\t\tpi.appendEntry(CACHE_KEEPALIVE_ENTRY_TYPE, data);\n\t\t}\n\n\t\tfunction stop(reason: string, forceEntry = false): void {\n\t\t\tconst shouldAppend = active || inFlight || timer !== undefined || forceEntry;\n\t\t\tgeneration += 1;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tactive = false;\n\t\t\tif (shouldAppend) {\n\t\t\t\tappend({\n\t\t\t\t\tphase: \"stopped\",\n\t\t\t\t\titerations: attempts,\n\t\t\t\t\tstopReason: reason,\n\t\t\t\t\tcumulativeEstimatedUsd,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction arm(): void {\n\t\t\tif (timer !== undefined || inFlight) return;\n\t\t\tconst current = ctx;\n\t\t\tconst settings = current?.getPromptCacheKeepAliveSettings?.();\n\t\t\tif (!settings?.enabled || current?.model === undefined || lastCompletedAtMs === undefined) return;\n\t\t\tif (!isWarmSupportedModel(current.model)) return;\n\t\t\tif (!current.isIdle()) {\n\t\t\t\tstop(\"agent-busy\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (current.hasPendingMessages()) {\n\t\t\t\tstop(\"pending-messages\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst safeWaitSeconds = current.getPromptCacheSafeWaitSeconds?.();\n\t\t\tif (safeWaitSeconds === undefined || !Number.isFinite(safeWaitSeconds)) return;\n\t\t\tif (attempts >= Math.max(0, settings.maxRequestsPerSession)) {\n\t\t\t\tstop(\"max-requests\", true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst projectedUsd = projectedPingCost(current.model, lastUsage);\n\t\t\tif (cumulativeEstimatedUsd + projectedUsd > Math.max(0, settings.maxCostUsdPerSession)) {\n\t\t\t\tstop(\"cost-cap\", true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!active) {\n\t\t\t\tactive = true;\n\t\t\t\tappend({ phase: \"started\" });\n\t\t\t}\n\t\t\tconst intervalMs = Math.max(0, safeWaitSeconds - Math.max(0, settings.marginSeconds)) * 1000;\n\t\t\tconst delayMs = Math.max(0, lastCompletedAtMs + intervalMs - Date.now());\n\t\t\tconst scheduledGeneration = generation;\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\ttimer = undefined;\n\t\t\t\tvoid ping(scheduledGeneration);\n\t\t\t}, delayMs);\n\t\t}\n\n\t\tasync function ping(scheduledGeneration: number): Promise<void> {\n\t\t\tif (scheduledGeneration !== generation) return;\n\t\t\tconst current = ctx;\n\t\t\tconst settings = current?.getPromptCacheKeepAliveSettings?.();\n\t\t\tif (\n\t\t\t\tcurrent === undefined ||\n\t\t\t\tsettings?.enabled !== true ||\n\t\t\t\tcurrent.model === undefined ||\n\t\t\t\t!isWarmSupportedModel(current.model) ||\n\t\t\t\t!current.isIdle() ||\n\t\t\t\tcurrent.hasPendingMessages() ||\n\t\t\t\tattempts >= Math.max(0, settings.maxRequestsPerSession) ||\n\t\t\t\tcumulativeEstimatedUsd + projectedPingCost(current.model, lastUsage) >\n\t\t\t\t\tMath.max(0, settings.maxCostUsdPerSession)\n\t\t\t) {\n\t\t\t\tarm();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tinFlight = true;\n\t\t\tattempts += 1;\n\t\t\tconst iteration = attempts;\n\t\t\tconst pingGeneration = generation;\n\t\t\ttry {\n\t\t\t\tconst preparation = await current.prepareProviderRequest?.(lastMessages);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst preparedMessages = preparation?.messages ?? lastMessages;\n\t\t\t\tconst activeToolNames = new Set(pi.getActiveTools());\n\t\t\t\tconst tools: Tool[] = pi\n\t\t\t\t\t.getAllTools()\n\t\t\t\t\t.filter((tool) => activeToolNames.has(tool.name))\n\t\t\t\t\t.map(({ name, description, parameters }) => ({ name, description, parameters }));\n\t\t\t\tconst auth = await current.modelRegistry.getApiKeyAndHeaders(current.model);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!auth.ok) throw new Error(auth.error);\n\t\t\t\tconst authHeaders = auth.headers ?? {};\n\t\t\t\tconst headers = preparation ? await preparation.transformHeaders(authHeaders) : authHeaders;\n\t\t\t\tconst result = await warm(\n\t\t\t\t\tcurrent.model,\n\t\t\t\t\t{\n\t\t\t\t\t\tsystemPrompt: current.getSystemPrompt(),\n\t\t\t\t\t\tmessages: convertToLlm(filterContextExcludedMessages(preparedMessages)),\n\t\t\t\t\t\t...(tools.length > 0 ? { tools } : {}),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tsessionId: current.sessionManager.getSessionId(),\n\t\t\t\t\t\tcacheRetention: current.model.cacheRetention,\n\t\t\t\t\t\tonPayload: preparation ? async (payload) => await preparation.transformPayload(payload) : undefined,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!result.supported) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tstop(\"unsupported-model\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst estimatedCostUsd = actualPingCost(current.model, result.usage);\n\t\t\t\tcumulativeEstimatedUsd += estimatedCostUsd;\n\t\t\t\tlastCompletedAtMs = Date.now();\n\t\t\t\tconst cachedTokens = result.usage.cacheRead + result.usage.cacheWrite;\n\t\t\t\tconst ttlSeconds = resolvePromptCacheTtlSeconds(current.model) ?? 0;\n\t\t\t\tpi.events?.emit(CACHE_WARM_PING_EVENT, { iteration, cachedTokens, ttlSeconds, estimatedCostUsd });\n\t\t\t\tappend({\n\t\t\t\t\tphase: \"ping\",\n\t\t\t\t\titeration,\n\t\t\t\t\tcacheRead: result.usage.cacheRead,\n\t\t\t\t\tcacheWrite: result.usage.cacheWrite,\n\t\t\t\t\testimatedCostUsd,\n\t\t\t\t\tcumulativeEstimatedUsd,\n\t\t\t\t});\n\t\t\t\tinFlight = false;\n\t\t\t\tarm();\n\t\t\t} catch {\n\t\t\t\tinFlight = false;\n\t\t\t\tif (pingGeneration === generation) stop(\"provider-error\");\n\t\t\t\telse arm();\n\t\t\t}\n\t\t}\n\n\t\tpi.on(\"session_start\", (_event, nextCtx) => {\n\t\t\tstop(\"session-restart\");\n\t\t\tctx = nextCtx;\n\t\t\tattempts = 0;\n\t\t\tcumulativeEstimatedUsd = 0;\n\t\t\tlastMessages = nextCtx.sessionManager.buildSessionContext().messages;\n\t\t\tconst usage = lastAssistantUsage(lastMessages);\n\t\t\tlastUsage = usage;\n\t\t\tlastCompletedAtMs = lastAssistantTimestamp(lastMessages);\n\t\t\tarm();\n\t\t});\n\n\t\tpi.on(\"agent_end\", (event, nextCtx) => {\n\t\t\tctx = nextCtx;\n\t\t\tconst usage = lastAssistantUsage(event.messages);\n\t\t\tif (usage?.stopReason === \"error\") {\n\t\t\t\tstop(\"provider-error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlastMessages = [...event.messages];\n\t\t\tlastUsage = usage;\n\t\t\tlastCompletedAtMs = Date.now();\n\t\t\tarm();\n\t\t});\n\n\t\tpi.on(\"model_select\", (_event, nextCtx) => {\n\t\t\tctx = nextCtx;\n\t\t\tstop(\"model-changed\");\n\t\t\tarm();\n\t\t});\n\t\tpi.on(\"agent_start\", () => stop(\"agent-busy\"));\n\t\tpi.on(\"input\", () => stop(\"user-input\"));\n\t\tpi.on(\"session_shutdown\", () => {\n\t\t\tstop(\"session-dispose\");\n\t\t\tctx = undefined;\n\t\t});\n\t};\n}\n\nfunction isWarmSupportedModel(model: Model<any>): model is Model<\"anthropic-messages\"> {\n\treturn model.api === \"anthropic-messages\" && isAnthropicApiBaseUrl(model.baseUrl);\n}\n\nfunction lastAssistantUsage(\n\tmessages: readonly AgentMessage[],\n): { input: number; cacheRead: number; cacheWrite: number; stopReason?: string } | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message.role !== \"assistant\") continue;\n\t\treturn {\n\t\t\tinput: finiteTokens(message.usage.input),\n\t\t\tcacheRead: finiteTokens(message.usage.cacheRead),\n\t\t\tcacheWrite: finiteTokens(message.usage.cacheWrite),\n\t\t\tstopReason: message.stopReason,\n\t\t};\n\t}\n\treturn undefined;\n}\n\nfunction lastAssistantTimestamp(messages: readonly AgentMessage[]): number | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message.role === \"assistant\" && Number.isFinite(message.timestamp)) return message.timestamp;\n\t}\n\treturn undefined;\n}\n\nfunction projectedPingCost(\n\tmodel: Model<any>,\n\tusage: { input: number; cacheRead: number; cacheWrite: number } | undefined,\n): number {\n\tconst promptTokens = (usage?.input ?? 0) + (usage?.cacheRead ?? 0) + (usage?.cacheWrite ?? 0);\n\treturn (promptTokens * Math.max(model.cost.cacheRead, model.cost.cacheWrite)) / 1_000_000;\n}\n\nfunction actualPingCost(model: Model<any>, usage: { input: number; cacheRead: number; cacheWrite: number }): number {\n\treturn (\n\t\t(usage.cacheRead * model.cost.cacheRead +\n\t\t\tusage.cacheWrite * model.cost.cacheWrite +\n\t\t\tusage.input * model.cost.input) /\n\t\t1_000_000\n\t);\n}\n\nfunction finiteTokens(value: number): number {\n\treturn Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nfunction formatUsd(value: number): string {\n\treturn `$${value.toFixed(3)}`;\n}\n\nexport default createCacheKeepAliveExtension();\n"]}
|
|
@@ -4,6 +4,8 @@ type CommandEnvironment = (name: string) => string | undefined;
|
|
|
4
4
|
export interface ClaudeAccountCommandDeps {
|
|
5
5
|
loadSettings?: (cwd: string) => ClaudeSdkOauthProviderSettings;
|
|
6
6
|
environment?: CommandEnvironment;
|
|
7
|
+
/** Browser launcher for the OAuth authorize URL; tests inject a recorder. */
|
|
8
|
+
openBrowser?: ((url: string) => void) | undefined;
|
|
7
9
|
}
|
|
8
10
|
export declare function getSessionClaudeAccountPin(sessionId: string | undefined): string | undefined;
|
|
9
11
|
/** CLI pins are request-local overrides; settings and stored pins remain fallback choices. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-command.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/account-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"account-command.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/account-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;AAM5E,OAAO,EAAE,KAAK,8BAA8B,EAA8C,MAAM,eAAe,CAAC;AAIhH,KAAK,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAE/D,MAAM,WAAW,wBAAwB;IACxC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,8BAA8B,CAAC;IAC/D,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,6EAA6E;IAC7E,WAAW,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAClD;AAsCD,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE5F;AAED,8FAA8F;AAC9F,wBAAgB,uBAAuB,CACtC,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,qBAAqB,EAAE,MAAM,GAAG,SAAS,EACzC,mBAAmB,EAAE,MAAM,GAAG,SAAS,GACrC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,GAAE,wBAA6B,GAAG,IAAI,CA8CxG"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { createExtensionLoginInteraction, LOGIN_CANCELLED_MESSAGE } from "../oauth-login-interaction.js";
|
|
1
2
|
import { emitProviderAccountsChanged } from "./account-events.js";
|
|
2
3
|
import { CLAUDE_SDK_OAUTH_PROVIDER_ID, pinProviderAccount, removeProviderAccount } from "./account-management.js";
|
|
3
4
|
import { emptyCredential, listAccounts } from "./accounts.js";
|
|
4
5
|
import { selectAccount } from "./affinity.js";
|
|
5
6
|
import { loadClaudeSdkOauthProviderSettingsFromDisk } from "./settings.js";
|
|
6
7
|
const cliPinsBySession = new Map();
|
|
8
|
+
const CLAUDE_SDK_OAUTH_PROVIDER_LABEL = "Claude SDK OAuth";
|
|
7
9
|
function asCredential(value) {
|
|
8
10
|
return value?.type === "oauth" ? value : undefined;
|
|
9
11
|
}
|
|
@@ -28,18 +30,6 @@ function accountError(ctx, name) {
|
|
|
28
30
|
function parseArgs(rawArgs) {
|
|
29
31
|
return rawArgs.trim().split(/\s+/).filter(Boolean);
|
|
30
32
|
}
|
|
31
|
-
function authEventMessage(event) {
|
|
32
|
-
if (event === null || typeof event !== "object")
|
|
33
|
-
return "Claude SDK OAuth authentication update.";
|
|
34
|
-
const value = event;
|
|
35
|
-
if (value.type === "auth_url" && typeof value.url === "string") {
|
|
36
|
-
return `Open this URL to authorize Claude SDK OAuth:\n${value.url}`;
|
|
37
|
-
}
|
|
38
|
-
if (value.type === "device_code" && typeof value.verificationUri === "string") {
|
|
39
|
-
return `Open this URL to authorize Claude SDK OAuth:\n${value.verificationUri}`;
|
|
40
|
-
}
|
|
41
|
-
return typeof value.message === "string" ? value.message : "Claude SDK OAuth authentication update.";
|
|
42
|
-
}
|
|
43
33
|
export function getSessionClaudeAccountPin(sessionId) {
|
|
44
34
|
return sessionId === undefined ? undefined : cliPinsBySession.get(sessionId);
|
|
45
35
|
}
|
|
@@ -76,7 +66,7 @@ export function registerClaudeAccountCommand(pi, deps = {}) {
|
|
|
76
66
|
return;
|
|
77
67
|
}
|
|
78
68
|
if (action === "add") {
|
|
79
|
-
await addAccount(ctx);
|
|
69
|
+
await addAccount(ctx, deps);
|
|
80
70
|
return;
|
|
81
71
|
}
|
|
82
72
|
if (action === "remove") {
|
|
@@ -128,29 +118,24 @@ function showAccounts(ctx, settings, environment) {
|
|
|
128
118
|
lines.push(`Affinity pick: ${affinityPick ?? (affinityError ? `unavailable - ${affinityError}` : "none")}`);
|
|
129
119
|
ctx.ui.notify(lines.join("\n"), "info");
|
|
130
120
|
}
|
|
131
|
-
async function addAccount(ctx) {
|
|
121
|
+
async function addAccount(ctx, deps) {
|
|
132
122
|
if (!ctx.hasUI) {
|
|
133
123
|
ctx.ui.notify("/claude-account add requires an interactive UI.", "error");
|
|
134
124
|
return;
|
|
135
125
|
}
|
|
136
126
|
try {
|
|
137
|
-
await ctx.modelRegistry.modelRuntime.login(CLAUDE_SDK_OAUTH_PROVIDER_ID, "oauth", {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (answer === undefined)
|
|
142
|
-
throw new Error("Login cancelled");
|
|
143
|
-
return answer;
|
|
144
|
-
},
|
|
145
|
-
notify: (event) => ctx.ui.notify(authEventMessage(event), "info"),
|
|
146
|
-
});
|
|
127
|
+
await ctx.modelRegistry.modelRuntime.login(CLAUDE_SDK_OAUTH_PROVIDER_ID, "oauth", createExtensionLoginInteraction(ctx, {
|
|
128
|
+
providerLabel: CLAUDE_SDK_OAUTH_PROVIDER_LABEL,
|
|
129
|
+
openBrowser: deps.openBrowser,
|
|
130
|
+
}));
|
|
147
131
|
emitProviderAccountsChanged(CLAUDE_SDK_OAUTH_PROVIDER_ID);
|
|
148
132
|
ctx.ui.notify("Claude SDK OAuth account added.", "info");
|
|
149
133
|
}
|
|
150
134
|
catch (error) {
|
|
151
135
|
const message = error instanceof Error ? error.message : String(error);
|
|
152
|
-
if (message !==
|
|
136
|
+
if (message !== LOGIN_CANCELLED_MESSAGE) {
|
|
153
137
|
ctx.ui.notify(`Failed to add Claude SDK OAuth account: ${message}`, "error");
|
|
138
|
+
}
|
|
154
139
|
}
|
|
155
140
|
}
|
|
156
141
|
async function removeNamedAccount(ctx, name, environment) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-command.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/account-command.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\nimport { emitProviderAccountsChanged } from \"./account-events.ts\";\nimport { CLAUDE_SDK_OAUTH_PROVIDER_ID, pinProviderAccount, removeProviderAccount } from \"./account-management.ts\";\nimport { type AccountSlot, type ClaudeSdkOauthCredential, emptyCredential, listAccounts } from \"./accounts.ts\";\nimport { selectAccount } from \"./affinity.ts\";\nimport { type ClaudeSdkOauthProviderSettings, loadClaudeSdkOauthProviderSettingsFromDisk } from \"./settings.ts\";\n\nconst cliPinsBySession = new Map<string, string>();\n\ntype CommandEnvironment = (name: string) => string | undefined;\n\nexport interface ClaudeAccountCommandDeps {\n\tloadSettings?: (cwd: string) => ClaudeSdkOauthProviderSettings;\n\tenvironment?: CommandEnvironment;\n}\n\nfunction asCredential(value: Credential | undefined): ClaudeSdkOauthCredential | undefined {\n\treturn value?.type === \"oauth\" ? (value as ClaudeSdkOauthCredential) : undefined;\n}\n\nfunction slotStatus(slot: AccountSlot): string {\n\tif (slot.blockReason === \"auth_error\") return \"blocked until re-login\";\n\tif (slot.blockedUntil !== undefined && slot.blockedUntil > Date.now()) {\n\t\treturn `blocked until ${new Date(slot.blockedUntil).toISOString()}`;\n\t}\n\treturn \"available\";\n}\n\nfunction readAccounts(\n\tctx: ExtensionCommandContext,\n\tenvironment: CommandEnvironment,\n): {\n\tcredential: ClaudeSdkOauthCredential | undefined;\n\taccounts: AccountSlot[];\n} {\n\tconst credential = asCredential(ctx.modelRegistry.authStorage.get(CLAUDE_SDK_OAUTH_PROVIDER_ID));\n\treturn {\n\t\tcredential,\n\t\taccounts: listAccounts(credential ?? emptyCredential(), environment),\n\t};\n}\n\nfunction accountError(ctx: ExtensionCommandContext, name: string): void {\n\tctx.ui.notify(`Claude SDK OAuth account '${name}' does not exist.`, \"error\");\n}\n\nfunction parseArgs(rawArgs: string): string[] {\n\treturn rawArgs.trim().split(/\\s+/).filter(Boolean);\n}\n\nfunction authEventMessage(event: unknown): string {\n\tif (event === null || typeof event !== \"object\") return \"Claude SDK OAuth authentication update.\";\n\tconst value = event as Record<string, unknown>;\n\tif (value.type === \"auth_url\" && typeof value.url === \"string\") {\n\t\treturn `Open this URL to authorize Claude SDK OAuth:\\n${value.url}`;\n\t}\n\tif (value.type === \"device_code\" && typeof value.verificationUri === \"string\") {\n\t\treturn `Open this URL to authorize Claude SDK OAuth:\\n${value.verificationUri}`;\n\t}\n\treturn typeof value.message === \"string\" ? value.message : \"Claude SDK OAuth authentication update.\";\n}\n\nexport function getSessionClaudeAccountPin(sessionId: string | undefined): string | undefined {\n\treturn sessionId === undefined ? undefined : cliPinsBySession.get(sessionId);\n}\n\n/** CLI pins are request-local overrides; settings and stored pins remain fallback choices. */\nexport function resolveClaudeAccountPin(\n\tcliPinnedAccount: string | undefined,\n\tsettingsPinnedAccount: string | undefined,\n\tstoredPinnedAccount: string | undefined,\n): string | undefined {\n\treturn cliPinnedAccount ?? settingsPinnedAccount ?? storedPinnedAccount;\n}\n\nexport function registerClaudeAccountCommand(pi: ExtensionAPI, deps: ClaudeAccountCommandDeps = {}): void {\n\tconst loadSettings = deps.loadSettings ?? loadClaudeSdkOauthProviderSettingsFromDisk;\n\tconst environment = deps.environment ?? ((name: string) => process.env[name]);\n\n\tpi.registerFlag(\"claude-account\", {\n\t\ttype: \"string\",\n\t\tdescription: \"Pin Claude SDK OAuth account for this session.\",\n\t});\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tconst flag = pi.getFlag(\"claude-account\");\n\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\tif (typeof flag === \"string\" && flag.length > 0) cliPinsBySession.set(sessionId, flag);\n\t\telse cliPinsBySession.delete(sessionId);\n\t});\n\tpi.on(\"session_shutdown\", (_event, ctx) => {\n\t\tcliPinsBySession.delete(ctx.sessionManager.getSessionId());\n\t});\n\tpi.registerCommand(\"claude-account\", {\n\t\tdescription: \"List and manage Claude SDK OAuth accounts.\",\n\t\targumentHint: \"[add | remove <name> | pin <name> | unpin]\",\n\t\thandler: async (rawArgs, ctx) => {\n\t\t\tconst args = parseArgs(rawArgs);\n\t\t\tconst action = args[0] ?? \"list\";\n\t\t\tif (action === \"list\") {\n\t\t\t\tshowAccounts(ctx, loadSettings(ctx.cwd), environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"add\") {\n\t\t\t\tawait addAccount(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"remove\") {\n\t\t\t\tawait removeNamedAccount(ctx, args[1], environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"pin\" && args[1] !== \"unpin\") {\n\t\t\t\tawait pinNamedAccount(ctx, args[1], environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"unpin\" || (action === \"pin\" && args[1] === \"unpin\")) {\n\t\t\t\tawait unpinAccount(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tctx.ui.notify(\"Usage: /claude-account [add | remove <name> | pin <name> | unpin]\", \"error\");\n\t\t},\n\t});\n}\n\nfunction showAccounts(\n\tctx: ExtensionCommandContext,\n\tsettings: ClaudeSdkOauthProviderSettings,\n\tenvironment: CommandEnvironment,\n): void {\n\tconst { credential, accounts } = readAccounts(ctx, environment);\n\tconst cliPin = getSessionClaudeAccountPin(ctx.sessionManager.getSessionId());\n\tconst pinned = resolveClaudeAccountPin(cliPin, settings.pinnedAccount, credential?.pinned);\n\tconst pinSource = cliPin !== undefined ? \"CLI\" : settings.pinnedAccount !== undefined ? \"settings\" : \"stored\";\n\tlet affinityPick: string | undefined;\n\tlet affinityError: string | undefined;\n\tif (accounts.length > 0) {\n\t\ttry {\n\t\t\taffinityPick = selectAccount(accounts, {\n\t\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\t\tpinnedAccount: pinned,\n\t\t\t}).name;\n\t\t} catch (error) {\n\t\t\taffinityError = error instanceof Error ? error.message : String(error);\n\t\t}\n\t}\n\tconst lines = [\"Claude SDK OAuth accounts:\"];\n\tif (accounts.length === 0) lines.push(\" (none)\");\n\tfor (const account of accounts) {\n\t\tconst states = [account.name, account.source, slotStatus(account)];\n\t\tif (account.name === pinned) states.push(\"pinned\");\n\t\tif (account.name === affinityPick) states.push(\"affinity pick\");\n\t\tlines.push(` ${states.join(\" | \")}`);\n\t}\n\tlines.push(`Pinned account: ${pinned === undefined ? \"none\" : `${pinned} (${pinSource.toLowerCase()})`}`);\n\tlines.push(`Affinity pick: ${affinityPick ?? (affinityError ? `unavailable - ${affinityError}` : \"none\")}`);\n\tctx.ui.notify(lines.join(\"\\n\"), \"info\");\n}\n\nasync function addAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/claude-account add requires an interactive UI.\", \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait ctx.modelRegistry.modelRuntime.login(CLAUDE_SDK_OAUTH_PROVIDER_ID, \"oauth\", {\n\t\t\tsignal: ctx.signal,\n\t\t\tprompt: async (prompt) => {\n\t\t\t\tconst answer = await ctx.ui.input(prompt.message);\n\t\t\t\tif (answer === undefined) throw new Error(\"Login cancelled\");\n\t\t\t\treturn answer;\n\t\t\t},\n\t\t\tnotify: (event) => ctx.ui.notify(authEventMessage(event), \"info\"),\n\t\t});\n\t\temitProviderAccountsChanged(CLAUDE_SDK_OAUTH_PROVIDER_ID);\n\t\tctx.ui.notify(\"Claude SDK OAuth account added.\", \"info\");\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message !== \"Login cancelled\") ctx.ui.notify(`Failed to add Claude SDK OAuth account: ${message}`, \"error\");\n\t}\n}\n\nasync function removeNamedAccount(\n\tctx: ExtensionCommandContext,\n\tname: string | undefined,\n\tenvironment: CommandEnvironment,\n): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /claude-account remove <name>\", \"error\");\n\t\treturn;\n\t}\n\tconst { accounts } = readAccounts(ctx, environment);\n\tconst target = accounts.find((account) => account.name === name);\n\tif (!target) return accountError(ctx, name);\n\tif (target.source === \"env\") {\n\t\tctx.ui.notify(`Claude SDK OAuth account '${name}' comes from the environment and cannot be removed.`, \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait removeProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, name);\n\t\tctx.ui.notify(`Removed Claude SDK OAuth account: ${name}.`, \"info\");\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t}\n}\n\nasync function pinNamedAccount(\n\tctx: ExtensionCommandContext,\n\tname: string | undefined,\n\tenvironment: CommandEnvironment,\n): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /claude-account pin <name>\", \"error\");\n\t\treturn;\n\t}\n\tif (!readAccounts(ctx, environment).accounts.some((account) => account.name === name)) {\n\t\treturn accountError(ctx, name);\n\t}\n\ttry {\n\t\tawait pinProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, name);\n\t\tctx.ui.notify(`Pinned Claude SDK OAuth account: ${name}.`, \"info\");\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t}\n}\n\nasync function unpinAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tconst credential = asCredential(ctx.modelRegistry.authStorage.get(CLAUDE_SDK_OAUTH_PROVIDER_ID));\n\tif (!credential?.pinned) {\n\t\tctx.ui.notify(\"No stored Claude SDK OAuth account pin is set.\", \"info\");\n\t\treturn;\n\t}\n\tawait pinProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, null);\n\tctx.ui.notify(\"Unpinned Claude SDK OAuth account.\", \"info\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"account-command.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/account-command.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\nimport { createExtensionLoginInteraction, LOGIN_CANCELLED_MESSAGE } from \"../oauth-login-interaction.ts\";\nimport { emitProviderAccountsChanged } from \"./account-events.ts\";\nimport { CLAUDE_SDK_OAUTH_PROVIDER_ID, pinProviderAccount, removeProviderAccount } from \"./account-management.ts\";\nimport { type AccountSlot, type ClaudeSdkOauthCredential, emptyCredential, listAccounts } from \"./accounts.ts\";\nimport { selectAccount } from \"./affinity.ts\";\nimport { type ClaudeSdkOauthProviderSettings, loadClaudeSdkOauthProviderSettingsFromDisk } from \"./settings.ts\";\n\nconst cliPinsBySession = new Map<string, string>();\n\ntype CommandEnvironment = (name: string) => string | undefined;\n\nexport interface ClaudeAccountCommandDeps {\n\tloadSettings?: (cwd: string) => ClaudeSdkOauthProviderSettings;\n\tenvironment?: CommandEnvironment;\n\t/** Browser launcher for the OAuth authorize URL; tests inject a recorder. */\n\topenBrowser?: ((url: string) => void) | undefined;\n}\n\nconst CLAUDE_SDK_OAUTH_PROVIDER_LABEL = \"Claude SDK OAuth\";\n\nfunction asCredential(value: Credential | undefined): ClaudeSdkOauthCredential | undefined {\n\treturn value?.type === \"oauth\" ? (value as ClaudeSdkOauthCredential) : undefined;\n}\n\nfunction slotStatus(slot: AccountSlot): string {\n\tif (slot.blockReason === \"auth_error\") return \"blocked until re-login\";\n\tif (slot.blockedUntil !== undefined && slot.blockedUntil > Date.now()) {\n\t\treturn `blocked until ${new Date(slot.blockedUntil).toISOString()}`;\n\t}\n\treturn \"available\";\n}\n\nfunction readAccounts(\n\tctx: ExtensionCommandContext,\n\tenvironment: CommandEnvironment,\n): {\n\tcredential: ClaudeSdkOauthCredential | undefined;\n\taccounts: AccountSlot[];\n} {\n\tconst credential = asCredential(ctx.modelRegistry.authStorage.get(CLAUDE_SDK_OAUTH_PROVIDER_ID));\n\treturn {\n\t\tcredential,\n\t\taccounts: listAccounts(credential ?? emptyCredential(), environment),\n\t};\n}\n\nfunction accountError(ctx: ExtensionCommandContext, name: string): void {\n\tctx.ui.notify(`Claude SDK OAuth account '${name}' does not exist.`, \"error\");\n}\n\nfunction parseArgs(rawArgs: string): string[] {\n\treturn rawArgs.trim().split(/\\s+/).filter(Boolean);\n}\n\nexport function getSessionClaudeAccountPin(sessionId: string | undefined): string | undefined {\n\treturn sessionId === undefined ? undefined : cliPinsBySession.get(sessionId);\n}\n\n/** CLI pins are request-local overrides; settings and stored pins remain fallback choices. */\nexport function resolveClaudeAccountPin(\n\tcliPinnedAccount: string | undefined,\n\tsettingsPinnedAccount: string | undefined,\n\tstoredPinnedAccount: string | undefined,\n): string | undefined {\n\treturn cliPinnedAccount ?? settingsPinnedAccount ?? storedPinnedAccount;\n}\n\nexport function registerClaudeAccountCommand(pi: ExtensionAPI, deps: ClaudeAccountCommandDeps = {}): void {\n\tconst loadSettings = deps.loadSettings ?? loadClaudeSdkOauthProviderSettingsFromDisk;\n\tconst environment = deps.environment ?? ((name: string) => process.env[name]);\n\n\tpi.registerFlag(\"claude-account\", {\n\t\ttype: \"string\",\n\t\tdescription: \"Pin Claude SDK OAuth account for this session.\",\n\t});\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tconst flag = pi.getFlag(\"claude-account\");\n\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\tif (typeof flag === \"string\" && flag.length > 0) cliPinsBySession.set(sessionId, flag);\n\t\telse cliPinsBySession.delete(sessionId);\n\t});\n\tpi.on(\"session_shutdown\", (_event, ctx) => {\n\t\tcliPinsBySession.delete(ctx.sessionManager.getSessionId());\n\t});\n\tpi.registerCommand(\"claude-account\", {\n\t\tdescription: \"List and manage Claude SDK OAuth accounts.\",\n\t\targumentHint: \"[add | remove <name> | pin <name> | unpin]\",\n\t\thandler: async (rawArgs, ctx) => {\n\t\t\tconst args = parseArgs(rawArgs);\n\t\t\tconst action = args[0] ?? \"list\";\n\t\t\tif (action === \"list\") {\n\t\t\t\tshowAccounts(ctx, loadSettings(ctx.cwd), environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"add\") {\n\t\t\t\tawait addAccount(ctx, deps);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"remove\") {\n\t\t\t\tawait removeNamedAccount(ctx, args[1], environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"pin\" && args[1] !== \"unpin\") {\n\t\t\t\tawait pinNamedAccount(ctx, args[1], environment);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (action === \"unpin\" || (action === \"pin\" && args[1] === \"unpin\")) {\n\t\t\t\tawait unpinAccount(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tctx.ui.notify(\"Usage: /claude-account [add | remove <name> | pin <name> | unpin]\", \"error\");\n\t\t},\n\t});\n}\n\nfunction showAccounts(\n\tctx: ExtensionCommandContext,\n\tsettings: ClaudeSdkOauthProviderSettings,\n\tenvironment: CommandEnvironment,\n): void {\n\tconst { credential, accounts } = readAccounts(ctx, environment);\n\tconst cliPin = getSessionClaudeAccountPin(ctx.sessionManager.getSessionId());\n\tconst pinned = resolveClaudeAccountPin(cliPin, settings.pinnedAccount, credential?.pinned);\n\tconst pinSource = cliPin !== undefined ? \"CLI\" : settings.pinnedAccount !== undefined ? \"settings\" : \"stored\";\n\tlet affinityPick: string | undefined;\n\tlet affinityError: string | undefined;\n\tif (accounts.length > 0) {\n\t\ttry {\n\t\t\taffinityPick = selectAccount(accounts, {\n\t\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\t\tpinnedAccount: pinned,\n\t\t\t}).name;\n\t\t} catch (error) {\n\t\t\taffinityError = error instanceof Error ? error.message : String(error);\n\t\t}\n\t}\n\tconst lines = [\"Claude SDK OAuth accounts:\"];\n\tif (accounts.length === 0) lines.push(\" (none)\");\n\tfor (const account of accounts) {\n\t\tconst states = [account.name, account.source, slotStatus(account)];\n\t\tif (account.name === pinned) states.push(\"pinned\");\n\t\tif (account.name === affinityPick) states.push(\"affinity pick\");\n\t\tlines.push(` ${states.join(\" | \")}`);\n\t}\n\tlines.push(`Pinned account: ${pinned === undefined ? \"none\" : `${pinned} (${pinSource.toLowerCase()})`}`);\n\tlines.push(`Affinity pick: ${affinityPick ?? (affinityError ? `unavailable - ${affinityError}` : \"none\")}`);\n\tctx.ui.notify(lines.join(\"\\n\"), \"info\");\n}\n\nasync function addAccount(ctx: ExtensionCommandContext, deps: ClaudeAccountCommandDeps): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/claude-account add requires an interactive UI.\", \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait ctx.modelRegistry.modelRuntime.login(\n\t\t\tCLAUDE_SDK_OAUTH_PROVIDER_ID,\n\t\t\t\"oauth\",\n\t\t\tcreateExtensionLoginInteraction(ctx, {\n\t\t\t\tproviderLabel: CLAUDE_SDK_OAUTH_PROVIDER_LABEL,\n\t\t\t\topenBrowser: deps.openBrowser,\n\t\t\t}),\n\t\t);\n\t\temitProviderAccountsChanged(CLAUDE_SDK_OAUTH_PROVIDER_ID);\n\t\tctx.ui.notify(\"Claude SDK OAuth account added.\", \"info\");\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message !== LOGIN_CANCELLED_MESSAGE) {\n\t\t\tctx.ui.notify(`Failed to add Claude SDK OAuth account: ${message}`, \"error\");\n\t\t}\n\t}\n}\n\nasync function removeNamedAccount(\n\tctx: ExtensionCommandContext,\n\tname: string | undefined,\n\tenvironment: CommandEnvironment,\n): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /claude-account remove <name>\", \"error\");\n\t\treturn;\n\t}\n\tconst { accounts } = readAccounts(ctx, environment);\n\tconst target = accounts.find((account) => account.name === name);\n\tif (!target) return accountError(ctx, name);\n\tif (target.source === \"env\") {\n\t\tctx.ui.notify(`Claude SDK OAuth account '${name}' comes from the environment and cannot be removed.`, \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait removeProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, name);\n\t\tctx.ui.notify(`Removed Claude SDK OAuth account: ${name}.`, \"info\");\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t}\n}\n\nasync function pinNamedAccount(\n\tctx: ExtensionCommandContext,\n\tname: string | undefined,\n\tenvironment: CommandEnvironment,\n): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /claude-account pin <name>\", \"error\");\n\t\treturn;\n\t}\n\tif (!readAccounts(ctx, environment).accounts.some((account) => account.name === name)) {\n\t\treturn accountError(ctx, name);\n\t}\n\ttry {\n\t\tawait pinProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, name);\n\t\tctx.ui.notify(`Pinned Claude SDK OAuth account: ${name}.`, \"info\");\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t}\n}\n\nasync function unpinAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tconst credential = asCredential(ctx.modelRegistry.authStorage.get(CLAUDE_SDK_OAUTH_PROVIDER_ID));\n\tif (!credential?.pinned) {\n\t\tctx.ui.notify(\"No stored Claude SDK OAuth account pin is set.\", \"info\");\n\t\treturn;\n\t}\n\tawait pinProviderAccount(ctx.modelRegistry.authStorage, CLAUDE_SDK_OAUTH_PROVIDER_ID, null);\n\tctx.ui.notify(\"Unpinned Claude SDK OAuth account.\", \"info\");\n}\n"]}
|
|
@@ -19,10 +19,18 @@ export interface DeterministicFallbackDiagnostic {
|
|
|
19
19
|
candidateRejections?: Array<{
|
|
20
20
|
firstKeptEntryId: string;
|
|
21
21
|
rejectionReason: DeterministicFallbackRejectionReason;
|
|
22
|
+
estimatedTokens?: number;
|
|
23
|
+
unsafeMessageIndex?: number;
|
|
24
|
+
unsafeEntryId?: string;
|
|
25
|
+
unsafeMessageRole?: string;
|
|
22
26
|
}>;
|
|
23
27
|
candidatesChecked?: number;
|
|
24
28
|
budgetExceeded?: boolean;
|
|
29
|
+
contextWindow?: number;
|
|
30
|
+
reserveTokens?: number;
|
|
31
|
+
budgetTokens?: number;
|
|
25
32
|
}
|
|
33
|
+
export declare function formatRequiredCompactionFallbackRejection(diagnostics: DeterministicFallbackDiagnostic): string;
|
|
26
34
|
export declare function classifyRequiredCompactionFallbackFailure(error: unknown): RequiredCompactionFallbackFailure | undefined;
|
|
27
35
|
export declare function createRequiredCompactionFallback(preparation: CompactionPreparation, contextWindow: number, failureKind: RequiredCompactionFallbackFailure, metadata: RecoveryMetadata, branchEntries?: SessionEntry[], diagnostics?: DeterministicFallbackDiagnostic): CompactionResult<DeterministicFallbackDetails> | undefined;
|
|
28
36
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deterministic-fallback.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/deterministic-fallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,gBAAgB,EAAkB,MAAM,8BAA8B,CAAC;AAGjH,OAAO,EAIN,KAAK,YAAY,EACjB,MAAM,6BAA6B,CAAC;AAQrC,MAAM,MAAM,iCAAiC,GAC1C,uBAAuB,GACvB,2BAA2B,GAC3B,kCAAkC,GAClC,6BAA6B,CAAC;AAEjC,UAAU,gBAAgB;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,oCAAoC,GAC7C,8BAA8B,GAC9B,yBAAyB,GACzB,gCAAgC,GAChC,uBAAuB,GACvB,+BAA+B,CAAC;AAEnC,UAAU,4BAA4B;IACrC,MAAM,EAAE,4CAA4C,CAAC;IACrD,MAAM,EAAE,8BAA8B,CAAC;IACvC,WAAW,EAAE,iCAAiC,CAAC;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,UAAU,GAAG,kBAAkB,GAAG,uBAAuB,CAAC;CAC3E;AAED,MAAM,WAAW,+BAA+B;IAC/C,eAAe,CAAC,EAAE,oCAAoC,CAAC;IACvD,mBAAmB,CAAC,EAAE,KAAK,CAAC;QAC3B,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"deterministic-fallback.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/deterministic-fallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,gBAAgB,EAAkB,MAAM,8BAA8B,CAAC;AAGjH,OAAO,EAIN,KAAK,YAAY,EACjB,MAAM,6BAA6B,CAAC;AAQrC,MAAM,MAAM,iCAAiC,GAC1C,uBAAuB,GACvB,2BAA2B,GAC3B,kCAAkC,GAClC,6BAA6B,CAAC;AAEjC,UAAU,gBAAgB;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,oCAAoC,GAC7C,8BAA8B,GAC9B,yBAAyB,GACzB,gCAAgC,GAChC,uBAAuB,GACvB,+BAA+B,CAAC;AAEnC,UAAU,4BAA4B;IACrC,MAAM,EAAE,4CAA4C,CAAC;IACrD,MAAM,EAAE,8BAA8B,CAAC;IACvC,WAAW,EAAE,iCAAiC,CAAC;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,UAAU,GAAG,kBAAkB,GAAG,uBAAuB,CAAC;CAC3E;AAED,MAAM,WAAW,+BAA+B;IAC/C,eAAe,CAAC,EAAE,oCAAoC,CAAC;IACvD,mBAAmB,CAAC,EAAE,KAAK,CAAC;QAC3B,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,oCAAoC,CAAC;QACtD,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC,CAAC;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,yCAAyC,CAAC,WAAW,EAAE,+BAA+B,GAAG,MAAM,CAoC9G;AA8CD,wBAAgB,yCAAyC,CACxD,KAAK,EAAE,OAAO,GACZ,iCAAiC,GAAG,SAAS,CAc/C;AAED,wBAAgB,gCAAgC,CAC/C,WAAW,EAAE,qBAAqB,EAClC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,iCAAiC,EAC9C,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,GAAE,YAAY,EAAO,EAClC,WAAW,CAAC,EAAE,+BAA+B,GAC3C,gBAAgB,CAAC,4BAA4B,CAAC,GAAG,SAAS,CAiS5D"}
|
|
@@ -8,6 +8,38 @@ import { resolveEffectiveReserveTokens } from "./policy.js";
|
|
|
8
8
|
import { hasUnsafeRetainedContent } from "./retained-message-safety.js";
|
|
9
9
|
import { SummaryGenerationError, SummaryRequestError } from "./speculative.js";
|
|
10
10
|
import { capUtf8Bytes } from "./task-intent.js";
|
|
11
|
+
export function formatRequiredCompactionFallbackRejection(diagnostics) {
|
|
12
|
+
const candidate = diagnostics.candidateRejections?.at(-1);
|
|
13
|
+
const reason = diagnostics.rejectionReason ?? "context-reconstruction-failed";
|
|
14
|
+
const recovery = {
|
|
15
|
+
"retained-token-budget-exceeded": "The retained turn exceeds the usable context. Select a model with a larger context and run /compact, or start a new session with an explicit checkpoint.",
|
|
16
|
+
"atomic-tool-chain-cut": "The retained tool calls and results do not form complete pairs. Finish the pending tool operation before /compact; if the transcript is damaged, start a new session with an explicit checkpoint.",
|
|
17
|
+
"unsafe-retained-content": "The retained message cannot be replayed safely. Inspect the identified entry; start a new session with an explicit checkpoint if it cannot be repaired.",
|
|
18
|
+
"missing-preparation-boundary": "The prepared boundary is absent from the branch. Reload the session and run /compact.",
|
|
19
|
+
"context-reconstruction-failed": "The retained context could not be reconstructed. Reload the session and run /compact.",
|
|
20
|
+
};
|
|
21
|
+
const diagnostic = {
|
|
22
|
+
rejectionReason: reason,
|
|
23
|
+
contextWindow: diagnostics.contextWindow,
|
|
24
|
+
reserveTokens: diagnostics.reserveTokens,
|
|
25
|
+
budgetTokens: diagnostics.budgetTokens,
|
|
26
|
+
budgetExceeded: diagnostics.budgetExceeded ?? false,
|
|
27
|
+
candidatesChecked: diagnostics.candidatesChecked ?? 0,
|
|
28
|
+
...(candidate
|
|
29
|
+
? {
|
|
30
|
+
candidate: {
|
|
31
|
+
...candidate,
|
|
32
|
+
firstKeptEntryId: capUtf8Bytes(candidate.firstKeptEntryId, 128),
|
|
33
|
+
...(candidate.unsafeEntryId ? { unsafeEntryId: capUtf8Bytes(candidate.unsafeEntryId, 128) } : {}),
|
|
34
|
+
...(candidate.unsafeMessageRole
|
|
35
|
+
? { unsafeMessageRole: capUtf8Bytes(candidate.unsafeMessageRole, 32) }
|
|
36
|
+
: {}),
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
: {}),
|
|
40
|
+
};
|
|
41
|
+
return `deterministic compaction fallback could not retain a safe suffix\n${JSON.stringify(diagnostic)}\n${recovery[reason]} The original transcript has not been changed.`;
|
|
42
|
+
}
|
|
11
43
|
const NON_VISIBLE_USER_TEXT = /[\p{White_Space}\p{Default_Ignorable_Code_Point}]/gu;
|
|
12
44
|
function isRecord(value) {
|
|
13
45
|
return typeof value === "object" && value !== null;
|
|
@@ -77,10 +109,18 @@ export function classifyRequiredCompactionFallbackFailure(error) {
|
|
|
77
109
|
return undefined;
|
|
78
110
|
}
|
|
79
111
|
export function createRequiredCompactionFallback(preparation, contextWindow, failureKind, metadata, branchEntries = [], diagnostics) {
|
|
112
|
+
const reserveTokens = resolveEffectiveReserveTokens(contextWindow, preparation.settings);
|
|
113
|
+
const budget = contextWindow - reserveTokens;
|
|
80
114
|
const preparedBoundaryIndex = branchEntries.findIndex((entry) => entry.id === preparation.firstKeptEntryId);
|
|
81
115
|
if (!preparation.firstKeptEntryId || preparedBoundaryIndex === -1) {
|
|
82
|
-
if (diagnostics)
|
|
83
|
-
diagnostics
|
|
116
|
+
if (diagnostics) {
|
|
117
|
+
Object.assign(diagnostics, {
|
|
118
|
+
rejectionReason: "missing-preparation-boundary",
|
|
119
|
+
contextWindow,
|
|
120
|
+
reserveTokens,
|
|
121
|
+
budgetTokens: budget,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
84
124
|
return undefined;
|
|
85
125
|
}
|
|
86
126
|
const marker = [
|
|
@@ -124,8 +164,14 @@ export function createRequiredCompactionFallback(preparation, contextWindow, fai
|
|
|
124
164
|
projectedMessages = filterContextExcludedMessages(buildSessionContext([...branchEntries, syntheticCompaction]).messages);
|
|
125
165
|
}
|
|
126
166
|
catch {
|
|
127
|
-
if (diagnostics)
|
|
128
|
-
diagnostics
|
|
167
|
+
if (diagnostics) {
|
|
168
|
+
Object.assign(diagnostics, {
|
|
169
|
+
rejectionReason: "context-reconstruction-failed",
|
|
170
|
+
contextWindow,
|
|
171
|
+
reserveTokens,
|
|
172
|
+
budgetTokens: budget,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
129
175
|
return undefined;
|
|
130
176
|
}
|
|
131
177
|
// Evaluate the candidate the provider would actually receive: `convertToLlm`
|
|
@@ -142,12 +188,14 @@ export function createRequiredCompactionFallback(preparation, contextWindow, fai
|
|
|
142
188
|
}
|
|
143
189
|
const summaryIndex = messageIndexesByEntryId.get(syntheticCompaction.id);
|
|
144
190
|
const unsafeSuffix = new Array(projectedMessages.length + 1).fill(false);
|
|
191
|
+
const unsafeIndexSuffix = new Int32Array(projectedMessages.length + 1).fill(-1);
|
|
145
192
|
const tokenSuffix = new Array(projectedMessages.length + 1).fill(0);
|
|
146
193
|
const toolCalls = new Map();
|
|
147
194
|
const toolResults = new Map();
|
|
148
195
|
for (let index = projectedMessages.length - 1; index >= 0; index--) {
|
|
149
196
|
const message = projectedMessages[index];
|
|
150
197
|
tokenSuffix[index] = tokenSuffix[index + 1];
|
|
198
|
+
unsafeIndexSuffix[index] = unsafeIndexSuffix[index + 1];
|
|
151
199
|
if (droppedByFailedTurnNormalization[index]) {
|
|
152
200
|
unsafeSuffix[index] = unsafeSuffix[index + 1];
|
|
153
201
|
continue;
|
|
@@ -156,29 +204,35 @@ export function createRequiredCompactionFallback(preparation, contextWindow, fai
|
|
|
156
204
|
let serialized;
|
|
157
205
|
try {
|
|
158
206
|
messageUnsafe = hasUnsafeRetainedContent([message]);
|
|
159
|
-
|
|
160
|
-
|
|
207
|
+
const bounded = isSafeBoundedValue(message);
|
|
208
|
+
messageUnsafe ||= !bounded;
|
|
161
209
|
let imageTokens = 0;
|
|
162
|
-
if (!messageUnsafe &&
|
|
163
|
-
|
|
210
|
+
if (!messageUnsafe && message.role === "toolResult") {
|
|
211
|
+
const content = message.content.map((block) => {
|
|
164
212
|
if (block.type !== "image")
|
|
165
|
-
|
|
166
|
-
// Keep the JSON delimiters and metadata charged, but replace only
|
|
167
|
-
// this validated image's escaped payload bytes with its token cost.
|
|
168
|
-
imagePayloadBytes += Buffer.byteLength(JSON.stringify(block.data)) - 2;
|
|
213
|
+
return block;
|
|
169
214
|
imageTokens += estimateTokens({ ...message, content: [block] });
|
|
170
|
-
|
|
215
|
+
return { ...block, data: "" };
|
|
216
|
+
});
|
|
217
|
+
serialized = JSON.stringify({ ...message, content });
|
|
171
218
|
}
|
|
219
|
+
else {
|
|
220
|
+
serialized = bounded ? JSON.stringify(message) : undefined;
|
|
221
|
+
}
|
|
222
|
+
// Apply the shared weighted chars/4 estimator to the envelope too.
|
|
223
|
+
// Storage bytes are not tokens; opaque text and image costs still count.
|
|
172
224
|
tokenSuffix[index] +=
|
|
173
225
|
serialized === undefined
|
|
174
226
|
? Number.POSITIVE_INFINITY
|
|
175
|
-
: Math.max(estimateTokens(message),
|
|
227
|
+
: Math.max(estimateTokens(message), estimateTokens({ role: "user", content: serialized, timestamp: 0 }) + imageTokens);
|
|
176
228
|
}
|
|
177
229
|
catch {
|
|
178
230
|
messageUnsafe = true;
|
|
179
231
|
tokenSuffix[index] = Number.POSITIVE_INFINITY;
|
|
180
232
|
}
|
|
181
233
|
unsafeSuffix[index] = unsafeSuffix[index + 1] || messageUnsafe;
|
|
234
|
+
if (messageUnsafe)
|
|
235
|
+
unsafeIndexSuffix[index] = index;
|
|
182
236
|
if (!isRecord(message))
|
|
183
237
|
continue;
|
|
184
238
|
if (message.role === "toolResult" && typeof message.toolCallId === "string") {
|
|
@@ -190,9 +244,8 @@ export function createRequiredCompactionFallback(preparation, contextWindow, fai
|
|
|
190
244
|
for (const block of message.content) {
|
|
191
245
|
if (!isRecord(block) || block.type !== "toolCall" || typeof block.id !== "string")
|
|
192
246
|
continue;
|
|
193
|
-
const call = toolCalls.get(block.id) ?? { indexes: [],
|
|
247
|
+
const call = toolCalls.get(block.id) ?? { indexes: [], newestIncomplete: block.incomplete === true };
|
|
194
248
|
call.indexes.push(index);
|
|
195
|
-
call.incomplete ||= block.incomplete === true;
|
|
196
249
|
toolCalls.set(block.id, call);
|
|
197
250
|
}
|
|
198
251
|
}
|
|
@@ -208,18 +261,21 @@ export function createRequiredCompactionFallback(preparation, contextWindow, fai
|
|
|
208
261
|
};
|
|
209
262
|
for (const [id, call] of toolCalls) {
|
|
210
263
|
const results = toolResults.get(id) ?? [];
|
|
211
|
-
if (
|
|
264
|
+
if (results.length === 0) {
|
|
212
265
|
markInvalidRange(0, Math.max(call.indexes[0] ?? -1, results[0] ?? -1) + 1);
|
|
213
266
|
continue;
|
|
214
267
|
}
|
|
215
268
|
const callIndex = call.indexes[0];
|
|
216
269
|
const resultIndex = results[0];
|
|
217
|
-
|
|
270
|
+
// Indexes are newest-first. Older duplicate IDs matter only while retained;
|
|
271
|
+
// dropping an entire historical pair leaves the newest pair valid.
|
|
272
|
+
markInvalidRange(0, Math.max(call.indexes[1] ?? -1, results[1] ?? -1) + 1);
|
|
273
|
+
if (call.newestIncomplete || callIndex >= resultIndex) {
|
|
218
274
|
markInvalidRange(0, Math.max(callIndex, resultIndex) + 1);
|
|
219
|
-
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
220
277
|
markInvalidRange(callIndex + 1, resultIndex + 1);
|
|
221
|
-
|
|
222
|
-
markInvalidRange(0, Math.max(callIndex, resultIndex) + 1);
|
|
278
|
+
}
|
|
223
279
|
}
|
|
224
280
|
for (const [id, results] of toolResults) {
|
|
225
281
|
if (toolCalls.has(id))
|
|
@@ -235,11 +291,14 @@ export function createRequiredCompactionFallback(preparation, contextWindow, fai
|
|
|
235
291
|
const projectCandidate = (firstKeptEntryId, retainedSuffix) => {
|
|
236
292
|
candidateCount++;
|
|
237
293
|
const details = { ...baseDetails, retainedSuffix };
|
|
238
|
-
const reject = (rejectionReason) => {
|
|
294
|
+
const reject = (rejectionReason, detail = {}) => {
|
|
239
295
|
if (diagnostics) {
|
|
240
296
|
diagnostics.rejectionReason = rejectionReason;
|
|
297
|
+
diagnostics.contextWindow = contextWindow;
|
|
298
|
+
diagnostics.reserveTokens = reserveTokens;
|
|
299
|
+
diagnostics.budgetTokens = budget;
|
|
241
300
|
diagnostics.candidateRejections ??= [];
|
|
242
|
-
diagnostics.candidateRejections.push({ firstKeptEntryId, rejectionReason });
|
|
301
|
+
diagnostics.candidateRejections.push({ firstKeptEntryId, rejectionReason, ...detail });
|
|
243
302
|
}
|
|
244
303
|
return undefined;
|
|
245
304
|
};
|
|
@@ -253,21 +312,31 @@ export function createRequiredCompactionFallback(preparation, contextWindow, fai
|
|
|
253
312
|
if (startIndex === undefined)
|
|
254
313
|
return reject("context-reconstruction-failed");
|
|
255
314
|
const retainedStart = Math.min(startIndex, projectedMessages.length);
|
|
256
|
-
if (unsafeSuffix[retainedStart])
|
|
257
|
-
|
|
315
|
+
if (unsafeSuffix[retainedStart]) {
|
|
316
|
+
const unsafeMessageIndex = unsafeIndexSuffix[retainedStart];
|
|
317
|
+
const unsafeMessage = projectedMessages[unsafeMessageIndex];
|
|
318
|
+
return reject("unsafe-retained-content", {
|
|
319
|
+
unsafeMessageIndex,
|
|
320
|
+
unsafeEntryId: getSessionContextEntryId(unsafeMessage),
|
|
321
|
+
unsafeMessageRole: unsafeMessage.role,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
258
324
|
if (!toolChainValidAt[retainedStart])
|
|
259
325
|
return reject("atomic-tool-chain-cut");
|
|
260
326
|
// The hard-limit valve reserves the scaled budget, so accepting against the raw
|
|
261
327
|
// configured reserve would admit a context that valve immediately compacts again.
|
|
262
|
-
const budget = contextWindow - resolveEffectiveReserveTokens(contextWindow, preparation.settings);
|
|
263
328
|
const summaryTokens = summaryIndex === undefined
|
|
264
329
|
? Number.POSITIVE_INFINITY
|
|
265
|
-
: Math.max(estimateTokens(projectedMessages[summaryIndex]),
|
|
330
|
+
: Math.max(estimateTokens(projectedMessages[summaryIndex]), estimateTokens({
|
|
331
|
+
role: "user",
|
|
332
|
+
content: JSON.stringify(projectedMessages[summaryIndex]),
|
|
333
|
+
timestamp: 0,
|
|
334
|
+
}));
|
|
266
335
|
const retainedTokens = (tokenSuffix[retainedStart] ?? Number.POSITIVE_INFINITY) + summaryTokens;
|
|
267
336
|
if (retainedTokens > budget) {
|
|
268
337
|
if (diagnostics)
|
|
269
338
|
diagnostics.budgetExceeded = true;
|
|
270
|
-
return reject("retained-token-budget-exceeded");
|
|
339
|
+
return reject("retained-token-budget-exceeded", { estimatedTokens: retainedTokens });
|
|
271
340
|
}
|
|
272
341
|
return { ...result, estimatedTokensAfter: retainedTokens };
|
|
273
342
|
};
|
|
@@ -303,6 +372,19 @@ export function createRequiredCompactionFallback(preparation, contextWindow, fai
|
|
|
303
372
|
diagnostics.candidatesChecked = candidateCount;
|
|
304
373
|
return latestUser;
|
|
305
374
|
}
|
|
375
|
+
// A steering user message can occur inside a tool chain. Keep that request
|
|
376
|
+
// and walk back to its declaring assistant instead of orphaning the result.
|
|
377
|
+
for (let earlierIndex = index - 1; earlierIndex > preparedBoundaryIndex; earlierIndex--) {
|
|
378
|
+
const earlierEntry = branchEntries[earlierIndex];
|
|
379
|
+
if (earlierEntry.type === "compaction")
|
|
380
|
+
break;
|
|
381
|
+
const earlier = projectCandidate(earlierEntry.id, "earlier-safe-boundary");
|
|
382
|
+
if (earlier) {
|
|
383
|
+
if (diagnostics)
|
|
384
|
+
diagnostics.candidatesChecked = candidateCount;
|
|
385
|
+
return earlier;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
306
388
|
break;
|
|
307
389
|
}
|
|
308
390
|
if (diagnostics)
|