@oh-my-pi/pi-coding-agent 17.0.9 → 17.1.1
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 +78 -0
- package/README.md +1 -1
- package/dist/cli.js +4685 -4614
- package/dist/types/async/job-manager.d.ts +37 -1
- package/dist/types/cli/args.d.ts +2 -0
- package/dist/types/cli/bench-cli.d.ts +41 -0
- package/dist/types/commands/bench.d.ts +15 -3
- package/dist/types/commands/launch.d.ts +4 -0
- package/dist/types/config/model-registry.d.ts +3 -1
- package/dist/types/config/models-config-schema.d.ts +18 -6
- package/dist/types/config/models-config.d.ts +14 -5
- package/dist/types/config/provider-globals.d.ts +2 -2
- package/dist/types/config/service-tier.d.ts +5 -1
- package/dist/types/config/settings-schema.d.ts +374 -47
- package/dist/types/config/settings.d.ts +7 -0
- package/dist/types/dap/client.d.ts +20 -0
- package/dist/types/exec/bash-executor.d.ts +38 -0
- package/dist/types/exec/direnv.d.ts +33 -0
- package/dist/types/export/html/args.d.ts +15 -0
- package/dist/types/export/html/index.d.ts +11 -26
- package/dist/types/export/html/web-palette.d.ts +55 -116
- package/dist/types/extensibility/extensions/loader.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +17 -2
- package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +3 -0
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +13 -0
- package/dist/types/live/attestation.d.ts +2 -0
- package/dist/types/live/controller.d.ts +48 -0
- package/dist/types/live/protocol.d.ts +85 -0
- package/dist/types/live/protocol.test.d.ts +1 -0
- package/dist/types/live/transport.d.ts +35 -0
- package/dist/types/live/visualizer.d.ts +30 -0
- package/dist/types/lsp/client.d.ts +16 -1
- package/dist/types/mcp/config-writer.test.d.ts +1 -0
- package/dist/types/mcp/oauth-discovery.d.ts +2 -0
- package/dist/types/mcp/smithery-auth.d.ts +1 -1
- package/dist/types/mcp/smithery-auth.test.d.ts +1 -0
- package/dist/types/memory-backend/tool-names.d.ts +2 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -0
- package/dist/types/modes/components/custom-message.d.ts +1 -1
- package/dist/types/modes/components/login-dialog.d.ts +2 -2
- package/dist/types/modes/components/message-frame.d.ts +8 -4
- package/dist/types/modes/components/plan-review-overlay.d.ts +26 -0
- package/dist/types/modes/components/session-account-selector.d.ts +11 -0
- package/dist/types/modes/components/settings-defs.d.ts +7 -1
- package/dist/types/modes/components/status-line/component.jj-cache.test.d.ts +1 -0
- package/dist/types/modes/components/tool-execution.d.ts +9 -1
- package/dist/types/modes/controllers/command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/event-controller.d.ts +6 -1
- package/dist/types/modes/controllers/live-command-controller.d.ts +14 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +6 -0
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/modes/types.d.ts +4 -1
- package/dist/types/modes/utils/context-usage.d.ts +12 -2
- package/dist/types/plan-mode/plan-files.d.ts +10 -0
- package/dist/types/registry/agent-lifecycle.d.ts +21 -9
- package/dist/types/registry/agent-registry.d.ts +11 -4
- package/dist/types/sdk.d.ts +15 -1
- package/dist/types/secrets/index.d.ts +15 -2
- package/dist/types/secrets/obfuscator.d.ts +113 -15
- package/dist/types/session/acp-permission-gate.d.ts +19 -0
- package/dist/types/session/agent-session-events.d.ts +84 -0
- package/dist/types/session/agent-session-types.d.ts +321 -0
- package/dist/types/session/agent-session.d.ts +135 -753
- package/dist/types/session/async-job-delivery.d.ts +28 -0
- package/dist/types/session/auth-storage.d.ts +1 -1
- package/dist/types/session/bash-runner.d.ts +75 -0
- package/dist/types/session/blob-store.d.ts +11 -1
- package/dist/types/session/blob-store.test.d.ts +1 -0
- package/dist/types/session/checkpoint-entries.d.ts +28 -0
- package/dist/types/session/eval-runner.d.ts +51 -0
- package/dist/types/session/irc-bridge.d.ts +46 -0
- package/dist/types/session/messages.d.ts +24 -0
- package/dist/types/session/model-controls.d.ts +180 -0
- package/dist/types/session/prewalk.d.ts +46 -0
- package/dist/types/session/queued-messages.d.ts +22 -0
- package/dist/types/session/redis-session-storage.d.ts +1 -0
- package/dist/types/session/retry-fallback-chains.d.ts +74 -0
- package/dist/types/session/role-models.d.ts +15 -0
- package/dist/types/session/session-advisors.d.ts +228 -0
- package/dist/types/session/session-entries.d.ts +8 -0
- package/dist/types/session/session-handoff.d.ts +70 -0
- package/dist/types/session/session-history-format.d.ts +6 -1
- package/dist/types/session/session-maintenance.d.ts +246 -0
- package/dist/types/session/session-manager.d.ts +41 -0
- package/dist/types/session/session-memory.d.ts +56 -0
- package/dist/types/session/session-provider-boundary.d.ts +62 -0
- package/dist/types/session/session-stats.d.ts +48 -0
- package/dist/types/session/session-tools.d.ts +158 -0
- package/dist/types/session/session-workspace.d.ts +32 -0
- package/dist/types/session/stream-guards.d.ts +44 -0
- package/dist/types/session/streaming-output.d.ts +8 -0
- package/dist/types/session/todo-tracker.d.ts +56 -0
- package/dist/types/session/ttsr-coordinator.d.ts +51 -0
- package/dist/types/session/turn-recovery.d.ts +225 -0
- package/dist/types/slash-commands/helpers/session-pin.d.ts +9 -0
- package/dist/types/stt/index.d.ts +0 -2
- package/dist/types/stt/stt-controller.d.ts +7 -0
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +4 -1
- package/dist/types/task/output-manager.d.ts +3 -1
- package/dist/types/tiny/title-client.d.ts +10 -0
- package/dist/types/tools/approval.d.ts +1 -0
- package/dist/types/tools/browser/launch.d.ts +5 -0
- package/dist/types/tools/builtin-names.d.ts +1 -1
- package/dist/types/tools/computer/protocol.d.ts +43 -0
- package/dist/types/tools/computer/supervisor.d.ts +32 -0
- package/dist/types/tools/computer/worker-entry.d.ts +1 -0
- package/dist/types/tools/computer/worker.d.ts +15 -0
- package/dist/types/tools/computer-renderer.d.ts +22 -0
- package/dist/types/tools/computer.d.ts +71 -0
- package/dist/types/tools/context.d.ts +2 -0
- package/dist/types/tools/default-renderer.d.ts +21 -0
- package/dist/types/tools/image-gen.d.ts +4 -4
- package/dist/types/tools/image-providers.d.ts +38 -0
- package/dist/types/tools/index.d.ts +7 -0
- package/dist/types/tools/path-utils.d.ts +8 -0
- package/dist/types/tools/todo.d.ts +10 -4
- package/dist/types/tools/xdev.d.ts +5 -1
- package/dist/types/tts/streaming-player.d.ts +10 -29
- package/dist/types/tts/vocalizer.d.ts +5 -0
- package/dist/types/utils/jj.d.ts +29 -0
- package/dist/types/utils/lang-from-path.d.ts +1 -0
- package/dist/types/utils/title-generator.d.ts +30 -0
- package/dist/types/utils/tools-manager.d.ts +1 -2
- package/dist/types/vibe/runtime.d.ts +36 -8
- package/dist/types/web/search/index.d.ts +1 -1
- package/dist/types/web/search/provider.d.ts +15 -5
- package/dist/types/web/search/types.d.ts +94 -0
- package/package.json +12 -12
- package/scripts/generate-share-viewer.ts +4 -6
- package/src/advisor/__tests__/advisor.test.ts +643 -0
- package/src/advisor/runtime.ts +144 -43
- package/src/async/job-manager.ts +90 -2
- package/src/cli/args.ts +3 -0
- package/src/cli/auth-gateway-cli.ts +18 -3
- package/src/cli/bench-cli.ts +395 -29
- package/src/cli/flag-tables.ts +3 -0
- package/src/cli/gc-cli.ts +2 -2
- package/src/cli/setup-cli.ts +2 -14
- package/src/cli/usage-cli.ts +10 -1
- package/src/cli.ts +8 -0
- package/src/collab/host.ts +3 -2
- package/src/commands/bench.ts +18 -4
- package/src/commands/launch.ts +4 -0
- package/src/config/model-registry.ts +16 -2
- package/src/config/models-config-schema.ts +15 -4
- package/src/config/provider-globals.ts +9 -9
- package/src/config/service-tier.ts +26 -1
- package/src/config/settings-schema.ts +270 -51
- package/src/config/settings.ts +81 -2
- package/src/dap/client.ts +37 -4
- package/src/edit/index.ts +49 -12
- package/src/eval/executor-base.ts +1 -0
- package/src/eval/js/executor.ts +2 -0
- package/src/eval/py/executor.ts +103 -33
- package/src/exec/bash-executor.ts +90 -6
- package/src/exec/direnv.ts +145 -0
- package/src/export/html/args.ts +20 -0
- package/src/export/html/index.ts +45 -47
- package/src/export/html/template.css +19 -1
- package/src/export/html/template.html +6 -0
- package/src/export/html/template.js +21 -0
- package/src/export/html/tool-views.generated.js +31 -31
- package/src/export/html/web-palette.ts +116 -132
- package/src/export/share.ts +249 -49
- package/src/extensibility/extensions/loader.ts +29 -1
- package/src/extensibility/extensions/runner.ts +6 -0
- package/src/extensibility/extensions/types.ts +33 -2
- package/src/extensibility/extensions/wrapper.ts +68 -12
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +7 -1
- package/src/extensibility/plugins/legacy-pi-compat.ts +19 -1
- package/src/hindsight/state.ts +64 -6
- package/src/internal-urls/local-protocol.ts +2 -1
- package/src/internal-urls/memory-protocol.ts +2 -2
- package/src/internal-urls/skill-protocol.ts +2 -2
- package/src/internal-urls/ssh-protocol.ts +2 -1
- package/src/internal-urls/vault-protocol.ts +2 -1
- package/src/live/attestation.ts +91 -0
- package/src/live/controller.ts +517 -0
- package/src/live/prompts/agent-final-message.md +3 -0
- package/src/live/prompts/live-instructions.md +23 -0
- package/src/live/protocol.test.ts +140 -0
- package/src/live/protocol.ts +233 -0
- package/src/live/transport.ts +422 -0
- package/src/live/visualizer.ts +214 -0
- package/src/lsp/client.ts +29 -9
- package/src/lsp/index.ts +19 -4
- package/src/main.ts +8 -1
- package/src/mcp/config-writer.test.ts +43 -0
- package/src/mcp/config-writer.ts +109 -82
- package/src/mcp/oauth-discovery.ts +10 -2
- package/src/mcp/smithery-auth.test.ts +29 -0
- package/src/mcp/smithery-auth.ts +3 -2
- package/src/memories/index.ts +40 -20
- package/src/memory-backend/tool-names.ts +2 -0
- package/src/mnemopi/backend.ts +24 -7
- package/src/modes/acp/acp-agent.ts +56 -10
- package/src/modes/acp/acp-event-mapper.ts +8 -1
- package/src/modes/components/agent-hub.ts +1 -1
- package/src/modes/components/assistant-message.ts +7 -2
- package/src/modes/components/custom-message.ts +4 -1
- package/src/modes/components/login-dialog.ts +14 -4
- package/src/modes/components/message-frame.ts +14 -8
- package/src/modes/components/plan-review-overlay.ts +350 -35
- package/src/modes/components/session-account-selector.ts +62 -0
- package/src/modes/components/settings-defs.ts +23 -1
- package/src/modes/components/settings-selector.ts +169 -1
- package/src/modes/components/status-line/component.jj-cache.test.ts +229 -0
- package/src/modes/components/status-line/component.ts +123 -2
- package/src/modes/components/tool-execution.ts +28 -112
- package/src/modes/controllers/command-controller.ts +56 -15
- package/src/modes/controllers/event-controller.ts +111 -16
- package/src/modes/controllers/extension-ui-controller.test.ts +1 -0
- package/src/modes/controllers/extension-ui-controller.ts +20 -4
- package/src/modes/controllers/input-controller.ts +47 -39
- package/src/modes/controllers/live-command-controller.ts +255 -0
- package/src/modes/controllers/mcp-command-controller.ts +10 -1
- package/src/modes/controllers/omfg-controller.ts +44 -40
- package/src/modes/controllers/selector-controller.ts +80 -10
- package/src/modes/controllers/session-focus-controller.ts +6 -1
- package/src/modes/interactive-mode.ts +176 -38
- package/src/modes/runtime-init.ts +2 -0
- package/src/modes/setup-wizard/scenes/web-search.ts +17 -9
- package/src/modes/theme/theme.ts +1 -1
- package/src/modes/types.ts +4 -1
- package/src/modes/utils/context-usage.ts +23 -7
- package/src/modes/utils/ui-helpers.ts +10 -5
- package/src/plan-mode/plan-files.ts +40 -0
- package/src/prompts/bench/cache-prefix-chunk.md +1 -0
- package/src/prompts/bench/cache-prefix.md +3 -0
- package/src/prompts/bench/cache-suffix.md +1 -0
- package/src/prompts/system/computer-safety.md +14 -0
- package/src/prompts/system/custom-system-prompt.md +1 -1
- package/src/prompts/system/project-prompt.md +8 -1
- package/src/prompts/system/subagent-async-pending.md +6 -0
- package/src/prompts/system/system-prompt.md +1 -1
- package/src/prompts/system/workflow-notice.md +48 -40
- package/src/prompts/system/xdev-mount-notice.md +4 -0
- package/src/prompts/tools/computer.md +26 -0
- package/src/prompts/tools/todo.md +3 -1
- package/src/registry/agent-lifecycle.ts +116 -46
- package/src/registry/agent-registry.ts +35 -8
- package/src/registry/persisted-agents.ts +26 -2
- package/src/sdk.ts +215 -136
- package/src/secrets/index.ts +127 -4
- package/src/secrets/obfuscator.ts +2328 -105
- package/src/session/acp-permission-gate.ts +165 -0
- package/src/session/agent-session-error-log.test.ts +1 -1
- package/src/session/agent-session-events.ts +66 -0
- package/src/session/agent-session-types.ts +343 -0
- package/src/session/agent-session.ts +1940 -12218
- package/src/session/artifacts.ts +6 -5
- package/src/session/async-job-delivery.ts +74 -0
- package/src/session/auth-storage.ts +1 -0
- package/src/session/bash-runner.ts +326 -0
- package/src/session/blob-store.test.ts +56 -0
- package/src/session/blob-store.ts +18 -2
- package/src/session/checkpoint-entries.ts +81 -0
- package/src/session/eval-runner.ts +217 -0
- package/src/session/indexed-session-storage.ts +9 -2
- package/src/session/irc-bridge.ts +203 -0
- package/src/session/messages.ts +266 -1
- package/src/session/model-controls.ts +714 -0
- package/src/session/prewalk.ts +252 -0
- package/src/session/queued-messages.ts +93 -0
- package/src/session/redis-session-storage.ts +51 -11
- package/src/session/retry-fallback-chains.ts +455 -0
- package/src/session/role-models.ts +85 -0
- package/src/session/session-advisors.ts +1679 -0
- package/src/session/session-context.ts +6 -3
- package/src/session/session-entries.ts +8 -0
- package/src/session/session-handoff.ts +308 -0
- package/src/session/session-history-format.ts +20 -9
- package/src/session/session-loader.ts +0 -46
- package/src/session/session-maintenance.ts +2983 -0
- package/src/session/session-manager.ts +390 -30
- package/src/session/session-memory.ts +222 -0
- package/src/session/session-provider-boundary.ts +307 -0
- package/src/session/session-stats.ts +293 -0
- package/src/session/session-tools.ts +980 -0
- package/src/session/session-workspace.ts +53 -0
- package/src/session/stream-guards.ts +417 -0
- package/src/session/streaming-output.ts +52 -5
- package/src/session/todo-tracker.ts +380 -0
- package/src/session/ttsr-coordinator.ts +496 -0
- package/src/session/turn-recovery.ts +1629 -0
- package/src/slash-commands/builtin-registry.ts +257 -20
- package/src/slash-commands/helpers/session-pin.ts +44 -0
- package/src/slash-commands/helpers/usage-report.ts +22 -3
- package/src/stt/downloader.ts +0 -2
- package/src/stt/index.ts +0 -2
- package/src/stt/stt-controller.ts +57 -146
- package/src/system-prompt.ts +45 -17
- package/src/task/executor.ts +285 -70
- package/src/task/index.ts +98 -105
- package/src/task/output-manager.ts +25 -3
- package/src/task/persisted-revive.ts +4 -3
- package/src/task/structured-subagent.ts +1 -0
- package/src/tiny/title-client.ts +22 -0
- package/src/tools/approval.ts +55 -10
- package/src/tools/bash-interactive.ts +116 -86
- package/src/tools/bash-skill-urls.ts +28 -2
- package/src/tools/bash.ts +339 -123
- package/src/tools/browser/launch.ts +9 -1
- package/src/tools/browser/tab-supervisor.ts +8 -5
- package/src/tools/browser.ts +94 -47
- package/src/tools/builtin-names.ts +1 -0
- package/src/tools/computer/protocol.ts +28 -0
- package/src/tools/computer/supervisor.ts +258 -0
- package/src/tools/computer/worker-entry.ts +25 -0
- package/src/tools/computer/worker.ts +135 -0
- package/src/tools/computer-renderer.ts +108 -0
- package/src/tools/computer.ts +433 -0
- package/src/tools/context.ts +2 -0
- package/src/tools/default-renderer.ts +139 -0
- package/src/tools/essential-tools.ts +1 -0
- package/src/tools/image-gen.ts +20 -28
- package/src/tools/image-providers.ts +50 -0
- package/src/tools/index.ts +14 -0
- package/src/tools/path-utils.ts +49 -2
- package/src/tools/read.ts +156 -88
- package/src/tools/renderers.ts +9 -1
- package/src/tools/todo.ts +101 -11
- package/src/tools/vibe.ts +1 -2
- package/src/tools/write.ts +51 -1
- package/src/tools/xdev.ts +121 -29
- package/src/tts/streaming-player.ts +82 -283
- package/src/tts/vocalizer.ts +18 -1
- package/src/utils/clipboard.ts +1 -30
- package/src/utils/jj.ts +125 -4
- package/src/utils/lang-from-path.ts +7 -0
- package/src/utils/mac-file-urls.applescript +37 -0
- package/src/utils/title-generator.ts +137 -1
- package/src/utils/tool-choice.ts +14 -0
- package/src/utils/tools-manager.ts +1 -19
- package/src/vibe/runtime.ts +852 -72
- package/src/web/search/index.ts +3 -6
- package/src/web/search/provider.ts +31 -16
- package/src/web/search/providers/xai.ts +7 -1
- package/src/web/search/types.ts +3 -0
- package/dist/types/stt/recorder.d.ts +0 -30
- package/dist/types/stt/transcriber.d.ts +0 -14
- package/dist/types/stt/wav.d.ts +0 -29
- package/dist/types/tts/player.d.ts +0 -32
- package/src/stt/recorder.ts +0 -551
- package/src/stt/transcriber.ts +0 -60
- package/src/stt/wav.ts +0 -173
- package/src/tts/player.ts +0 -137
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import type { Agent, AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
import { calculatePromptTokens, estimateTokens, type SessionMessageEntry } from "@oh-my-pi/pi-agent-core/compaction";
|
|
3
|
+
import type { AssistantMessage, Model, ProviderResponseMetadata, Usage } from "@oh-my-pi/pi-ai";
|
|
4
|
+
import { isRecord } from "@oh-my-pi/pi-utils";
|
|
5
|
+
import type { ModelRegistry } from "../config/model-registry";
|
|
6
|
+
import type { ContextUsage } from "../extensibility/extensions/types";
|
|
7
|
+
import {
|
|
8
|
+
computeNonMessageBreakdown,
|
|
9
|
+
computeNonMessageTokens,
|
|
10
|
+
type NonMessageTokenSource,
|
|
11
|
+
} from "../modes/utils/context-usage";
|
|
12
|
+
import type { ContextUsageBreakdown, SessionStats } from "./agent-session-types";
|
|
13
|
+
import { getLatestCompactionEntry } from "./session-context";
|
|
14
|
+
import type { SessionManager } from "./session-manager";
|
|
15
|
+
|
|
16
|
+
interface PendingContextSnapshot {
|
|
17
|
+
promptTokens: number;
|
|
18
|
+
nonMessageTokens: number;
|
|
19
|
+
cutoffCount: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Capabilities the stats tracker borrows from its owning session. */
|
|
23
|
+
export interface SessionStatsTrackerHost {
|
|
24
|
+
session: NonMessageTokenSource;
|
|
25
|
+
agent: Agent;
|
|
26
|
+
sessionManager: SessionManager;
|
|
27
|
+
modelRegistry: ModelRegistry;
|
|
28
|
+
model(): Model | undefined;
|
|
29
|
+
sessionId(): string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Computes session totals and tracks the in-flight context estimate. */
|
|
33
|
+
export class SessionStatsTracker {
|
|
34
|
+
readonly #host: SessionStatsTrackerHost;
|
|
35
|
+
#pendingContextSnapshot: PendingContextSnapshot | undefined;
|
|
36
|
+
#contextUsageRevision = 0;
|
|
37
|
+
|
|
38
|
+
constructor(host: SessionStatsTrackerHost) {
|
|
39
|
+
this.#host = host;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Returns aggregate message, token, and cost statistics for the session. */
|
|
43
|
+
getSessionStats(): SessionStats {
|
|
44
|
+
const state = this.#host.agent.state;
|
|
45
|
+
const userMessages = state.messages.filter(message => message.role === "user").length;
|
|
46
|
+
const assistantMessages = state.messages.filter(message => message.role === "assistant").length;
|
|
47
|
+
const toolResults = state.messages.filter(message => message.role === "toolResult").length;
|
|
48
|
+
let toolCalls = 0;
|
|
49
|
+
let totalInput = 0;
|
|
50
|
+
let totalOutput = 0;
|
|
51
|
+
let totalCacheRead = 0;
|
|
52
|
+
let totalReasoning = 0;
|
|
53
|
+
let totalCacheWrite = 0;
|
|
54
|
+
let totalTokens = 0;
|
|
55
|
+
let totalCost = 0;
|
|
56
|
+
let totalPremiumRequests = 0;
|
|
57
|
+
for (const message of state.messages) {
|
|
58
|
+
if (message.role === "assistant") {
|
|
59
|
+
const assistant = message;
|
|
60
|
+
toolCalls += assistant.content.filter(content => content.type === "toolCall").length;
|
|
61
|
+
totalInput += assistant.usage.input;
|
|
62
|
+
totalOutput += assistant.usage.output;
|
|
63
|
+
totalReasoning += assistant.usage.reasoningTokens ?? 0;
|
|
64
|
+
totalCacheRead += assistant.usage.cacheRead;
|
|
65
|
+
totalCacheWrite += assistant.usage.cacheWrite;
|
|
66
|
+
totalTokens += assistant.usage.totalTokens;
|
|
67
|
+
totalPremiumRequests += assistant.usage.premiumRequests ?? 0;
|
|
68
|
+
totalCost += assistant.usage.cost.total;
|
|
69
|
+
}
|
|
70
|
+
if (message.role === "toolResult" && message.toolName === "task") {
|
|
71
|
+
const usage = taskToolUsage(message.details);
|
|
72
|
+
if (!usage) continue;
|
|
73
|
+
totalInput += usage.input;
|
|
74
|
+
totalOutput += usage.output;
|
|
75
|
+
totalReasoning += usage.reasoningTokens ?? 0;
|
|
76
|
+
totalCacheRead += usage.cacheRead;
|
|
77
|
+
totalCacheWrite += usage.cacheWrite;
|
|
78
|
+
totalTokens += usage.totalTokens;
|
|
79
|
+
totalPremiumRequests += usage.premiumRequests ?? 0;
|
|
80
|
+
totalCost += usage.cost.total;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
sessionFile: this.#host.sessionManager.getSessionFile(),
|
|
85
|
+
sessionId: this.#host.sessionId(),
|
|
86
|
+
userMessages,
|
|
87
|
+
assistantMessages,
|
|
88
|
+
toolCalls,
|
|
89
|
+
toolResults,
|
|
90
|
+
totalMessages: state.messages.length,
|
|
91
|
+
tokens: {
|
|
92
|
+
input: totalInput,
|
|
93
|
+
output: totalOutput,
|
|
94
|
+
reasoning: totalReasoning,
|
|
95
|
+
cacheRead: totalCacheRead,
|
|
96
|
+
cacheWrite: totalCacheWrite,
|
|
97
|
+
total: totalTokens,
|
|
98
|
+
},
|
|
99
|
+
cost: totalCost,
|
|
100
|
+
premiumRequests: totalPremiumRequests,
|
|
101
|
+
contextUsage: this.getContextUsage(),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Returns the current provider-context token breakdown. */
|
|
106
|
+
getContextBreakdown(options?: {
|
|
107
|
+
contextWindow?: number;
|
|
108
|
+
pendingMessages?: AgentMessage[];
|
|
109
|
+
}): ContextUsageBreakdown | undefined {
|
|
110
|
+
const rawContextWindow = options?.contextWindow ?? this.#host.model()?.contextWindow ?? 0;
|
|
111
|
+
const contextWindow = Number.isFinite(rawContextWindow) && rawContextWindow > 0 ? rawContextWindow : 0;
|
|
112
|
+
const { skillsTokens, toolsTokens, systemContextTokens, systemPromptTokens } = computeNonMessageBreakdown(
|
|
113
|
+
this.#host.session,
|
|
114
|
+
);
|
|
115
|
+
const categoryNonMessageTokens = skillsTokens + toolsTokens + systemContextTokens + systemPromptTokens;
|
|
116
|
+
const currentNonMessageTokens = computeNonMessageTokens(this.#host.session);
|
|
117
|
+
const branchEntries = this.#host.sessionManager.getBranch();
|
|
118
|
+
const latestCompaction = getLatestCompactionEntry(branchEntries);
|
|
119
|
+
const compactionIndex = latestCompaction ? branchEntries.lastIndexOf(latestCompaction) : -1;
|
|
120
|
+
let usedTokens = 0;
|
|
121
|
+
let anchored = false;
|
|
122
|
+
const pendingMessages = options?.pendingMessages ?? [];
|
|
123
|
+
const pending = this.#pendingContextSnapshot;
|
|
124
|
+
|
|
125
|
+
let anchorEntry: SessionMessageEntry | undefined;
|
|
126
|
+
for (let index = branchEntries.length - 1; index > compactionIndex; index--) {
|
|
127
|
+
const entry = branchEntries[index];
|
|
128
|
+
if (entry.type !== "message" || entry.message.role !== "assistant") continue;
|
|
129
|
+
const assistant = entry.message;
|
|
130
|
+
if (assistant.stopReason !== "aborted" && assistant.stopReason !== "error" && assistant.usage) {
|
|
131
|
+
anchorEntry = entry;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const activeMessages = this.#host.agent.state.messages;
|
|
137
|
+
let anchorIndex = -1;
|
|
138
|
+
let anchorAssistant: AssistantMessage | undefined;
|
|
139
|
+
if (anchorEntry?.message.role === "assistant") {
|
|
140
|
+
const assistant = anchorEntry.message;
|
|
141
|
+
anchorAssistant = assistant;
|
|
142
|
+
anchorIndex = activeMessages.indexOf(assistant);
|
|
143
|
+
if (anchorIndex === -1) {
|
|
144
|
+
anchorIndex = activeMessages.findIndex(
|
|
145
|
+
message => message.role === "assistant" && message.timestamp === assistant.timestamp,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const useAnchor =
|
|
151
|
+
anchorAssistant !== undefined && anchorIndex !== -1 && (!pending || anchorIndex >= pending.cutoffCount);
|
|
152
|
+
if (useAnchor && anchorAssistant) {
|
|
153
|
+
const promptTokens =
|
|
154
|
+
anchorAssistant.contextSnapshot?.promptTokens ?? calculatePromptTokens(anchorAssistant.usage);
|
|
155
|
+
const nonMessageTokens =
|
|
156
|
+
anchorAssistant.contextSnapshot?.nonMessageTokens ?? computeNonMessageTokens(this.#host.session);
|
|
157
|
+
anchored = true;
|
|
158
|
+
let tailTokens = 0;
|
|
159
|
+
for (let index = anchorIndex + 1; index < activeMessages.length; index++) {
|
|
160
|
+
tailTokens += estimateTokens(activeMessages[index]);
|
|
161
|
+
}
|
|
162
|
+
usedTokens =
|
|
163
|
+
promptTokens +
|
|
164
|
+
Math.max(0, currentNonMessageTokens - nonMessageTokens) +
|
|
165
|
+
tailTokens +
|
|
166
|
+
pendingMessages.reduce((sum, message) => sum + estimateTokens(message), 0);
|
|
167
|
+
} else if (pending) {
|
|
168
|
+
anchored = true;
|
|
169
|
+
let tailTokens = 0;
|
|
170
|
+
for (let index = pending.cutoffCount; index < activeMessages.length; index++) {
|
|
171
|
+
tailTokens += estimateTokens(activeMessages[index]);
|
|
172
|
+
}
|
|
173
|
+
usedTokens =
|
|
174
|
+
pending.promptTokens +
|
|
175
|
+
Math.max(0, currentNonMessageTokens - pending.nonMessageTokens) +
|
|
176
|
+
tailTokens +
|
|
177
|
+
pendingMessages.reduce((sum, message) => sum + estimateTokens(message), 0);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (!anchored && !pending && branchEntries.length === 0) {
|
|
181
|
+
for (let index = activeMessages.length - 1; index >= 0; index--) {
|
|
182
|
+
const message = activeMessages[index];
|
|
183
|
+
if (
|
|
184
|
+
message.role !== "assistant" ||
|
|
185
|
+
message.stopReason === "aborted" ||
|
|
186
|
+
message.stopReason === "error" ||
|
|
187
|
+
!message.usage
|
|
188
|
+
) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
const promptTokens = message.contextSnapshot?.promptTokens ?? calculatePromptTokens(message.usage);
|
|
192
|
+
const nonMessageTokens =
|
|
193
|
+
message.contextSnapshot?.nonMessageTokens ?? computeNonMessageTokens(this.#host.session);
|
|
194
|
+
let tailTokens = 0;
|
|
195
|
+
for (let tailIndex = index + 1; tailIndex < activeMessages.length; tailIndex++) {
|
|
196
|
+
tailTokens += estimateTokens(activeMessages[tailIndex]);
|
|
197
|
+
}
|
|
198
|
+
usedTokens =
|
|
199
|
+
promptTokens +
|
|
200
|
+
Math.max(0, currentNonMessageTokens - nonMessageTokens) +
|
|
201
|
+
tailTokens +
|
|
202
|
+
pendingMessages.reduce((sum, pendingMessage) => sum + estimateTokens(pendingMessage), 0);
|
|
203
|
+
anchored = true;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (!anchored) {
|
|
208
|
+
let messagesTokens = 0;
|
|
209
|
+
for (const message of activeMessages) messagesTokens += estimateTokens(message);
|
|
210
|
+
usedTokens =
|
|
211
|
+
currentNonMessageTokens +
|
|
212
|
+
messagesTokens +
|
|
213
|
+
pendingMessages.reduce((sum, message) => sum + estimateTokens(message), 0);
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
contextWindow,
|
|
217
|
+
anchored,
|
|
218
|
+
usedTokens,
|
|
219
|
+
systemPromptTokens,
|
|
220
|
+
systemToolsTokens: toolsTokens,
|
|
221
|
+
systemContextTokens,
|
|
222
|
+
skillsTokens,
|
|
223
|
+
messagesTokens: Math.max(0, usedTokens - categoryNonMessageTokens),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Returns current context tokens, capacity, and percentage. */
|
|
228
|
+
getContextUsage(options?: { contextWindow?: number }): ContextUsage | undefined {
|
|
229
|
+
const breakdown = this.getContextBreakdown(options);
|
|
230
|
+
if (!breakdown) return undefined;
|
|
231
|
+
return {
|
|
232
|
+
tokens: breakdown.usedTokens,
|
|
233
|
+
contextWindow: breakdown.contextWindow,
|
|
234
|
+
percent: breakdown.contextWindow > 0 ? (breakdown.usedTokens / breakdown.contextWindow) * 100 : 0,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Monotonic revision for in-flight context snapshot changes. */
|
|
239
|
+
get revision(): number {
|
|
240
|
+
return this.#contextUsageRevision;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Non-message token count captured for the active provider request. */
|
|
244
|
+
get pendingNonMessageTokens(): number | undefined {
|
|
245
|
+
return this.#pendingContextSnapshot?.nonMessageTokens;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** Sets or clears the in-flight context snapshot. */
|
|
249
|
+
setPendingSnapshot(snapshot: PendingContextSnapshot | undefined): void {
|
|
250
|
+
this.#pendingContextSnapshot = snapshot;
|
|
251
|
+
this.#contextUsageRevision++;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Recomputes an in-flight snapshot after history is compacted or rewritten. */
|
|
255
|
+
rebaseAfterCompaction(): void {
|
|
256
|
+
if (!this.#pendingContextSnapshot) return;
|
|
257
|
+
const nonMessageTokens = computeNonMessageTokens(this.#host.session);
|
|
258
|
+
const messages = this.#host.agent.state.messages;
|
|
259
|
+
this.setPendingSnapshot({
|
|
260
|
+
promptTokens: nonMessageTokens + messages.reduce((sum, message) => sum + estimateTokens(message), 0),
|
|
261
|
+
nonMessageTokens,
|
|
262
|
+
cutoffCount: messages.length,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Records provider usage headers against the active session account. */
|
|
267
|
+
ingestProviderUsageHeaders(response: ProviderResponseMetadata, model?: Model): void {
|
|
268
|
+
const provider = model?.provider;
|
|
269
|
+
if (!provider) return;
|
|
270
|
+
this.#host.modelRegistry.authStorage.ingestUsageHeaders(provider, response.headers, {
|
|
271
|
+
sessionId: this.#host.agent.sessionId,
|
|
272
|
+
baseUrl: this.#host.modelRegistry.getProviderBaseUrl?.(provider),
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function taskToolUsage(details: unknown): Usage | undefined {
|
|
278
|
+
if (!details || typeof details !== "object") return undefined;
|
|
279
|
+
const usage = Reflect.get(details, "usage");
|
|
280
|
+
return isUsage(usage) ? usage : undefined;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function isUsage(value: unknown): value is Usage {
|
|
284
|
+
if (!isRecord(value) || !isRecord(value.cost)) return false;
|
|
285
|
+
return (
|
|
286
|
+
typeof value.input === "number" &&
|
|
287
|
+
typeof value.output === "number" &&
|
|
288
|
+
typeof value.cacheRead === "number" &&
|
|
289
|
+
typeof value.cacheWrite === "number" &&
|
|
290
|
+
typeof value.totalTokens === "number" &&
|
|
291
|
+
typeof value.cost.total === "number"
|
|
292
|
+
);
|
|
293
|
+
}
|