rafcode 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +19 -4
- package/RAF/ahtahs-token-reaper/decisions.md +37 -0
- package/RAF/ahtahs-token-reaper/input.md +20 -0
- package/RAF/ahtahs-token-reaper/outcomes/01-extend-token-tracker-data-model.md +42 -0
- package/RAF/ahtahs-token-reaper/outcomes/02-accumulate-usage-in-retry-loop.md +31 -0
- package/RAF/ahtahs-token-reaper/outcomes/03-per-attempt-display-formatting.md +60 -0
- package/RAF/ahtahs-token-reaper/outcomes/04-add-model-name-to-claude-call-logs.md +57 -0
- package/RAF/ahtahs-token-reaper/outcomes/05-handle-invalid-config-in-raf-config.md +46 -0
- package/RAF/ahtahs-token-reaper/outcomes/06-fix-verbose-toggle-timer-display.md +38 -0
- package/RAF/ahtahs-token-reaper/plans/01-extend-token-tracker-data-model.md +36 -0
- package/RAF/ahtahs-token-reaper/plans/02-accumulate-usage-in-retry-loop.md +36 -0
- package/RAF/ahtahs-token-reaper/plans/03-per-attempt-display-formatting.md +43 -0
- package/RAF/ahtahs-token-reaper/plans/04-add-model-name-to-claude-call-logs.md +38 -0
- package/RAF/ahtahs-token-reaper/plans/05-handle-invalid-config-in-raf-config.md +36 -0
- package/RAF/ahtahs-token-reaper/plans/06-fix-verbose-toggle-timer-display.md +40 -0
- package/RAF/ahvrih-rate-forge/decisions.md +70 -0
- package/RAF/ahvrih-rate-forge/input.md +44 -0
- package/RAF/ahvrih-rate-forge/outcomes/01-remove-claude-command-config.md +58 -0
- package/RAF/ahvrih-rate-forge/outcomes/02-fix-mixed-attempt-cost.md +46 -0
- package/RAF/ahvrih-rate-forge/outcomes/03-rate-limit-estimation.md +82 -0
- package/RAF/ahvrih-rate-forge/outcomes/04-show-version-in-do-logs.md +45 -0
- package/RAF/ahvrih-rate-forge/outcomes/05-sync-main-before-worktree.md +96 -0
- package/RAF/ahvrih-rate-forge/outcomes/06-sync-readme-with-codebase.md +45 -0
- package/RAF/ahvrih-rate-forge/outcomes/07-no-session-persistence.md +26 -0
- package/RAF/ahvrih-rate-forge/outcomes/08-plan-execution-metadata.md +130 -0
- package/RAF/ahvrih-rate-forge/plans/01-remove-claude-command-config.md +36 -0
- package/RAF/ahvrih-rate-forge/plans/02-fix-mixed-attempt-cost.md +33 -0
- package/RAF/ahvrih-rate-forge/plans/03-rate-limit-estimation.md +82 -0
- package/RAF/ahvrih-rate-forge/plans/04-show-version-in-do-logs.md +32 -0
- package/RAF/ahvrih-rate-forge/plans/05-sync-main-before-worktree.md +40 -0
- package/RAF/ahvrih-rate-forge/plans/06-sync-readme-with-codebase.md +61 -0
- package/RAF/ahvrih-rate-forge/plans/07-no-session-persistence.md +28 -0
- package/RAF/ahvrih-rate-forge/plans/08-plan-execution-metadata.md +123 -0
- package/README.md +27 -7
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +24 -7
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/do.d.ts.map +1 -1
- package/dist/commands/do.js +122 -27
- package/dist/commands/do.js.map +1 -1
- package/dist/commands/plan.d.ts.map +1 -1
- package/dist/commands/plan.js +79 -3
- package/dist/commands/plan.js.map +1 -1
- package/dist/core/claude-runner.d.ts +6 -6
- package/dist/core/claude-runner.d.ts.map +1 -1
- package/dist/core/claude-runner.js +9 -10
- package/dist/core/claude-runner.js.map +1 -1
- package/dist/core/failure-analyzer.d.ts.map +1 -1
- package/dist/core/failure-analyzer.js +3 -3
- package/dist/core/failure-analyzer.js.map +1 -1
- package/dist/core/pull-request.d.ts.map +1 -1
- package/dist/core/pull-request.js +5 -3
- package/dist/core/pull-request.js.map +1 -1
- package/dist/core/state-derivation.d.ts +5 -0
- package/dist/core/state-derivation.d.ts.map +1 -1
- package/dist/core/state-derivation.js +14 -4
- package/dist/core/state-derivation.js.map +1 -1
- package/dist/core/worktree.d.ts +32 -0
- package/dist/core/worktree.d.ts.map +1 -1
- package/dist/core/worktree.js +215 -0
- package/dist/core/worktree.js.map +1 -1
- package/dist/prompts/amend.d.ts.map +1 -1
- package/dist/prompts/amend.js +26 -11
- package/dist/prompts/amend.js.map +1 -1
- package/dist/prompts/planning.d.ts.map +1 -1
- package/dist/prompts/planning.js +26 -11
- package/dist/prompts/planning.js.map +1 -1
- package/dist/types/config.d.ts +30 -13
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +14 -10
- package/dist/types/config.js.map +1 -1
- package/dist/utils/config.d.ts +53 -4
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +197 -30
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +43 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +85 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/name-generator.d.ts.map +1 -1
- package/dist/utils/name-generator.js +2 -3
- package/dist/utils/name-generator.js.map +1 -1
- package/dist/utils/session-parser.d.ts +44 -0
- package/dist/utils/session-parser.d.ts.map +1 -0
- package/dist/utils/session-parser.js +122 -0
- package/dist/utils/session-parser.js.map +1 -0
- package/dist/utils/terminal-symbols.d.ts +28 -5
- package/dist/utils/terminal-symbols.d.ts.map +1 -1
- package/dist/utils/terminal-symbols.js +77 -18
- package/dist/utils/terminal-symbols.js.map +1 -1
- package/dist/utils/token-tracker.d.ts +31 -1
- package/dist/utils/token-tracker.d.ts.map +1 -1
- package/dist/utils/token-tracker.js +94 -4
- package/dist/utils/token-tracker.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/config.ts +26 -7
- package/src/commands/do.ts +157 -29
- package/src/commands/plan.ts +89 -2
- package/src/core/claude-runner.ts +16 -17
- package/src/core/failure-analyzer.ts +3 -3
- package/src/core/pull-request.ts +5 -3
- package/src/core/state-derivation.ts +20 -4
- package/src/core/worktree.ts +230 -0
- package/src/prompts/amend.ts +26 -11
- package/src/prompts/config-docs.md +91 -29
- package/src/prompts/planning.ts +26 -11
- package/src/types/config.ts +46 -21
- package/src/utils/config.ts +222 -33
- package/src/utils/frontmatter.ts +110 -0
- package/src/utils/name-generator.ts +2 -3
- package/src/utils/session-parser.ts +161 -0
- package/src/utils/terminal-symbols.ts +105 -18
- package/src/utils/token-tracker.ts +109 -4
- package/tests/unit/claude-runner-interactive.test.ts +8 -6
- package/tests/unit/claude-runner.test.ts +5 -66
- package/tests/unit/config-command.test.ts +84 -5
- package/tests/unit/config.test.ts +292 -45
- package/tests/unit/frontmatter.test.ts +182 -0
- package/tests/unit/post-execution-picker.test.ts +5 -0
- package/tests/unit/session-parser.test.ts +301 -0
- package/tests/unit/terminal-symbols.test.ts +263 -33
- package/tests/unit/timer-verbose-integration.test.ts +170 -0
- package/tests/unit/token-tracker.test.ts +653 -17
- package/tests/unit/validation.test.ts +6 -4
- package/tests/unit/worktree.test.ts +242 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"name-generator.js","sourceRoot":"","sources":["../../src/utils/name-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"name-generator.js","sourceRoot":"","sources":["../../src/utils/name-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for parsing Claude CLI session files to extract token usage data.
|
|
3
|
+
* Claude CLI saves session data to ~/.claude/projects/<escaped-path>/<session-id>.jsonl
|
|
4
|
+
*/
|
|
5
|
+
import type { UsageData } from '../types/config.js';
|
|
6
|
+
/** Result of parsing a session file. */
|
|
7
|
+
export interface SessionParseResult {
|
|
8
|
+
/** Accumulated usage data from all assistant messages. */
|
|
9
|
+
usage: UsageData;
|
|
10
|
+
/** Whether parsing was successful. */
|
|
11
|
+
success: boolean;
|
|
12
|
+
/** Error message if parsing failed. */
|
|
13
|
+
error?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Escape a path for use in Claude's project directory naming scheme.
|
|
17
|
+
* Claude escapes `/` to `-` in project paths.
|
|
18
|
+
*/
|
|
19
|
+
export declare function escapeProjectPath(projectPath: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Compute the expected session file path for a given session ID and working directory.
|
|
22
|
+
*
|
|
23
|
+
* @param sessionId - The UUID session ID passed to --session-id
|
|
24
|
+
* @param cwd - The working directory where Claude was run (project path)
|
|
25
|
+
* @returns The expected path to the session JSONL file
|
|
26
|
+
*/
|
|
27
|
+
export declare function getSessionFilePath(sessionId: string, cwd: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Parse a Claude session JSONL file and extract accumulated token usage data.
|
|
30
|
+
*
|
|
31
|
+
* @param sessionFilePath - Path to the session JSONL file
|
|
32
|
+
* @returns Parsed usage data or error information
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseSessionFile(sessionFilePath: string): SessionParseResult;
|
|
35
|
+
/**
|
|
36
|
+
* Parse a Claude session by session ID and working directory.
|
|
37
|
+
* Convenience wrapper around getSessionFilePath + parseSessionFile.
|
|
38
|
+
*
|
|
39
|
+
* @param sessionId - The UUID session ID passed to --session-id
|
|
40
|
+
* @param cwd - The working directory where Claude was run
|
|
41
|
+
* @returns Parsed usage data or error information
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseSessionById(sessionId: string, cwd: string): SessionParseResult;
|
|
44
|
+
//# sourceMappingURL=session-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-parser.d.ts","sourceRoot":"","sources":["../../src/utils/session-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAoBpD,wCAAwC;AACxC,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,KAAK,EAAE,SAAS,CAAC;IACjB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAIzE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,kBAAkB,CAiF5E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAGnF"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for parsing Claude CLI session files to extract token usage data.
|
|
3
|
+
* Claude CLI saves session data to ~/.claude/projects/<escaped-path>/<session-id>.jsonl
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'node:fs';
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
import * as os from 'node:os';
|
|
8
|
+
/**
|
|
9
|
+
* Escape a path for use in Claude's project directory naming scheme.
|
|
10
|
+
* Claude escapes `/` to `-` in project paths.
|
|
11
|
+
*/
|
|
12
|
+
export function escapeProjectPath(projectPath) {
|
|
13
|
+
// Remove leading slash and replace remaining slashes with dashes
|
|
14
|
+
return projectPath.replace(/^\//, '').replace(/\//g, '-');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Compute the expected session file path for a given session ID and working directory.
|
|
18
|
+
*
|
|
19
|
+
* @param sessionId - The UUID session ID passed to --session-id
|
|
20
|
+
* @param cwd - The working directory where Claude was run (project path)
|
|
21
|
+
* @returns The expected path to the session JSONL file
|
|
22
|
+
*/
|
|
23
|
+
export function getSessionFilePath(sessionId, cwd) {
|
|
24
|
+
const claudeDir = path.join(os.homedir(), '.claude', 'projects');
|
|
25
|
+
const escapedPath = escapeProjectPath(cwd);
|
|
26
|
+
return path.join(claudeDir, escapedPath, `${sessionId}.jsonl`);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parse a Claude session JSONL file and extract accumulated token usage data.
|
|
30
|
+
*
|
|
31
|
+
* @param sessionFilePath - Path to the session JSONL file
|
|
32
|
+
* @returns Parsed usage data or error information
|
|
33
|
+
*/
|
|
34
|
+
export function parseSessionFile(sessionFilePath) {
|
|
35
|
+
const emptyUsage = {
|
|
36
|
+
inputTokens: 0,
|
|
37
|
+
outputTokens: 0,
|
|
38
|
+
cacheReadInputTokens: 0,
|
|
39
|
+
cacheCreationInputTokens: 0,
|
|
40
|
+
modelUsage: {},
|
|
41
|
+
};
|
|
42
|
+
if (!fs.existsSync(sessionFilePath)) {
|
|
43
|
+
return {
|
|
44
|
+
usage: emptyUsage,
|
|
45
|
+
success: false,
|
|
46
|
+
error: `Session file not found: ${sessionFilePath}`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const content = fs.readFileSync(sessionFilePath, 'utf-8');
|
|
51
|
+
const lines = content.trim().split('\n').filter(line => line.trim());
|
|
52
|
+
const accumulated = { ...emptyUsage, modelUsage: {} };
|
|
53
|
+
for (const line of lines) {
|
|
54
|
+
try {
|
|
55
|
+
const entry = JSON.parse(line);
|
|
56
|
+
// Only process assistant message entries
|
|
57
|
+
if (entry.type !== 'assistant')
|
|
58
|
+
continue;
|
|
59
|
+
const assistantEntry = entry;
|
|
60
|
+
const usage = assistantEntry.message?.usage;
|
|
61
|
+
const model = assistantEntry.message?.model;
|
|
62
|
+
if (!usage)
|
|
63
|
+
continue;
|
|
64
|
+
const inputTokens = usage.input_tokens ?? 0;
|
|
65
|
+
const outputTokens = usage.output_tokens ?? 0;
|
|
66
|
+
const cacheReadTokens = usage.cache_read_input_tokens ?? 0;
|
|
67
|
+
const cacheCreateTokens = usage.cache_creation_input_tokens ?? 0;
|
|
68
|
+
// Accumulate aggregate totals
|
|
69
|
+
accumulated.inputTokens += inputTokens;
|
|
70
|
+
accumulated.outputTokens += outputTokens;
|
|
71
|
+
accumulated.cacheReadInputTokens += cacheReadTokens;
|
|
72
|
+
accumulated.cacheCreationInputTokens += cacheCreateTokens;
|
|
73
|
+
// Accumulate per-model usage
|
|
74
|
+
if (model) {
|
|
75
|
+
const existing = accumulated.modelUsage[model];
|
|
76
|
+
if (existing) {
|
|
77
|
+
existing.inputTokens += inputTokens;
|
|
78
|
+
existing.outputTokens += outputTokens;
|
|
79
|
+
existing.cacheReadInputTokens += cacheReadTokens;
|
|
80
|
+
existing.cacheCreationInputTokens += cacheCreateTokens;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
accumulated.modelUsage[model] = {
|
|
84
|
+
inputTokens,
|
|
85
|
+
outputTokens,
|
|
86
|
+
cacheReadInputTokens: cacheReadTokens,
|
|
87
|
+
cacheCreationInputTokens: cacheCreateTokens,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Skip malformed lines
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
usage: accumulated,
|
|
99
|
+
success: true,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
return {
|
|
104
|
+
usage: emptyUsage,
|
|
105
|
+
success: false,
|
|
106
|
+
error: `Failed to parse session file: ${error}`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Parse a Claude session by session ID and working directory.
|
|
112
|
+
* Convenience wrapper around getSessionFilePath + parseSessionFile.
|
|
113
|
+
*
|
|
114
|
+
* @param sessionId - The UUID session ID passed to --session-id
|
|
115
|
+
* @param cwd - The working directory where Claude was run
|
|
116
|
+
* @returns Parsed usage data or error information
|
|
117
|
+
*/
|
|
118
|
+
export function parseSessionById(sessionId, cwd) {
|
|
119
|
+
const filePath = getSessionFilePath(sessionId, cwd);
|
|
120
|
+
return parseSessionFile(filePath);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=session-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-parser.js","sourceRoot":"","sources":["../../src/utils/session-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,16 @@
|
|
|
3
3
|
* All functions are pure and testable - no side effects.
|
|
4
4
|
*/
|
|
5
5
|
import type { UsageData } from '../types/config.js';
|
|
6
|
-
import type { CostBreakdown } from './token-tracker.js';
|
|
6
|
+
import type { CostBreakdown, TaskUsageEntry } from './token-tracker.js';
|
|
7
|
+
/** Options for token summary formatting. */
|
|
8
|
+
export interface TokenSummaryOptions {
|
|
9
|
+
/** Whether to show cache token counts. Default: true */
|
|
10
|
+
showCacheTokens?: boolean;
|
|
11
|
+
/** Whether to show rate limit percentage. Default: true */
|
|
12
|
+
showRateLimitEstimate?: boolean;
|
|
13
|
+
/** Rate limit percentage to display (requires showRateLimitEstimate: true) */
|
|
14
|
+
rateLimitPercentage?: number;
|
|
15
|
+
}
|
|
7
16
|
/**
|
|
8
17
|
* Visual symbols for terminal output using dots/symbols style.
|
|
9
18
|
*/
|
|
@@ -60,13 +69,27 @@ export declare function formatNumber(n: number): string;
|
|
|
60
69
|
*/
|
|
61
70
|
export declare function formatCost(cost: number): string;
|
|
62
71
|
/**
|
|
63
|
-
* Formats a
|
|
64
|
-
*
|
|
72
|
+
* Formats a rate limit percentage for display.
|
|
73
|
+
* Uses tilde (~) prefix to indicate estimate.
|
|
65
74
|
*/
|
|
66
|
-
export declare function
|
|
75
|
+
export declare function formatRateLimitPercentage(percentage: number): string;
|
|
76
|
+
/**
|
|
77
|
+
* Formats a per-task token usage summary.
|
|
78
|
+
* For single-attempt tasks: " Tokens: 5,234 in / 1,023 out | Cache: 18,500 read | Est. cost: $0.42 | ~2% of 5h window"
|
|
79
|
+
* For multi-attempt tasks: shows per-attempt breakdown plus total.
|
|
80
|
+
*
|
|
81
|
+
* @param entry - The TaskUsageEntry containing accumulated usage, cost, and attempts array
|
|
82
|
+
* @param calculateAttemptCost - Optional function to calculate cost for a single attempt's UsageData
|
|
83
|
+
* @param options - Display options for showing cache tokens and rate limit percentage
|
|
84
|
+
*/
|
|
85
|
+
export declare function formatTaskTokenSummary(entry: TaskUsageEntry, calculateAttemptCost?: (usage: UsageData) => CostBreakdown, options?: TokenSummaryOptions): string;
|
|
67
86
|
/**
|
|
68
87
|
* Formats the grand total token usage summary block.
|
|
69
88
|
* Displayed after all tasks complete.
|
|
89
|
+
*
|
|
90
|
+
* @param usage - Total usage data
|
|
91
|
+
* @param cost - Total cost breakdown
|
|
92
|
+
* @param options - Display options for cache tokens and rate limit
|
|
70
93
|
*/
|
|
71
|
-
export declare function formatTokenTotalSummary(usage: UsageData, cost: CostBreakdown): string;
|
|
94
|
+
export declare function formatTokenTotalSummary(usage: UsageData, cost: CostBreakdown, options?: TokenSummaryOptions): string;
|
|
72
95
|
//# sourceMappingURL=terminal-symbols.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-symbols.d.ts","sourceRoot":"","sources":["../../src/utils/terminal-symbols.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"terminal-symbols.d.ts","sourceRoot":"","sources":["../../src/utils/terminal-symbols.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAExE,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAClC,wDAAwD;IACxD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,2DAA2D;IAC3D,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,8EAA8E;IAC9E,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,eAAO,MAAM,OAAO;;;;;;;CAOV,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAYpF;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAYR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAI3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,MAAU,GAClB,MAAM,CAwBR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,CAM7D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKpE;AAwCD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EACrB,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,aAAa,EAC1D,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAuBR;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAyBR"}
|
|
@@ -114,37 +114,93 @@ export function formatCost(cost) {
|
|
|
114
114
|
return `$${cost.toFixed(2)}`;
|
|
115
115
|
}
|
|
116
116
|
/**
|
|
117
|
-
* Formats a
|
|
118
|
-
*
|
|
117
|
+
* Formats a rate limit percentage for display.
|
|
118
|
+
* Uses tilde (~) prefix to indicate estimate.
|
|
119
119
|
*/
|
|
120
|
-
export function
|
|
120
|
+
export function formatRateLimitPercentage(percentage) {
|
|
121
|
+
if (percentage === 0)
|
|
122
|
+
return '~0% of 5h window';
|
|
123
|
+
if (percentage < 0.1)
|
|
124
|
+
return `~${percentage.toFixed(2)}% of 5h window`;
|
|
125
|
+
if (percentage < 1)
|
|
126
|
+
return `~${percentage.toFixed(1)}% of 5h window`;
|
|
127
|
+
return `~${Math.round(percentage)}% of 5h window`;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Formats a single line of token usage (for a single attempt or total).
|
|
131
|
+
* Used internally by formatTaskTokenSummary.
|
|
132
|
+
*/
|
|
133
|
+
function formatTokenLine(usage, costValue, prefix = '', indent = ' ', options = {}) {
|
|
134
|
+
const { showCacheTokens = true, showRateLimitEstimate = false, rateLimitPercentage } = options;
|
|
121
135
|
const parts = [];
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
136
|
+
const tokenPart = `${formatNumber(usage.inputTokens)} in / ${formatNumber(usage.outputTokens)} out`;
|
|
137
|
+
parts.push(prefix ? `${prefix}: ${tokenPart}` : `Tokens: ${tokenPart}`);
|
|
138
|
+
if (showCacheTokens) {
|
|
139
|
+
const cacheTotal = usage.cacheReadInputTokens + usage.cacheCreationInputTokens;
|
|
140
|
+
if (cacheTotal > 0) {
|
|
141
|
+
if (usage.cacheReadInputTokens > 0 && usage.cacheCreationInputTokens > 0) {
|
|
142
|
+
parts.push(`Cache: ${formatNumber(usage.cacheReadInputTokens)} read / ${formatNumber(usage.cacheCreationInputTokens)} created`);
|
|
143
|
+
}
|
|
144
|
+
else if (usage.cacheReadInputTokens > 0) {
|
|
145
|
+
parts.push(`Cache: ${formatNumber(usage.cacheReadInputTokens)} read`);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
parts.push(`Cache: ${formatNumber(usage.cacheCreationInputTokens)} created`);
|
|
149
|
+
}
|
|
133
150
|
}
|
|
134
151
|
}
|
|
135
|
-
parts.push(`Est. cost: ${formatCost(
|
|
136
|
-
|
|
152
|
+
parts.push(`Est. cost: ${formatCost(costValue)}`);
|
|
153
|
+
if (showRateLimitEstimate && rateLimitPercentage !== undefined) {
|
|
154
|
+
parts.push(formatRateLimitPercentage(rateLimitPercentage));
|
|
155
|
+
}
|
|
156
|
+
return `${indent}${parts.join(' | ')}`;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Formats a per-task token usage summary.
|
|
160
|
+
* For single-attempt tasks: " Tokens: 5,234 in / 1,023 out | Cache: 18,500 read | Est. cost: $0.42 | ~2% of 5h window"
|
|
161
|
+
* For multi-attempt tasks: shows per-attempt breakdown plus total.
|
|
162
|
+
*
|
|
163
|
+
* @param entry - The TaskUsageEntry containing accumulated usage, cost, and attempts array
|
|
164
|
+
* @param calculateAttemptCost - Optional function to calculate cost for a single attempt's UsageData
|
|
165
|
+
* @param options - Display options for showing cache tokens and rate limit percentage
|
|
166
|
+
*/
|
|
167
|
+
export function formatTaskTokenSummary(entry, calculateAttemptCost, options = {}) {
|
|
168
|
+
// Single-attempt: render exactly as before (no per-attempt breakdown)
|
|
169
|
+
if (entry.attempts.length <= 1) {
|
|
170
|
+
return formatTokenLine(entry.usage, entry.cost.totalCost, '', ' ', options);
|
|
171
|
+
}
|
|
172
|
+
// Multi-attempt: show per-attempt lines plus total
|
|
173
|
+
// Per-attempt lines don't show rate limit (only show on total)
|
|
174
|
+
const perAttemptOptions = {
|
|
175
|
+
...options,
|
|
176
|
+
showRateLimitEstimate: false,
|
|
177
|
+
rateLimitPercentage: undefined,
|
|
178
|
+
};
|
|
179
|
+
const lines = [];
|
|
180
|
+
entry.attempts.forEach((attemptUsage, i) => {
|
|
181
|
+
const attemptCost = calculateAttemptCost
|
|
182
|
+
? calculateAttemptCost(attemptUsage).totalCost
|
|
183
|
+
: 0;
|
|
184
|
+
lines.push(formatTokenLine(attemptUsage, attemptCost, `Attempt ${i + 1}`, ' ', perAttemptOptions));
|
|
185
|
+
});
|
|
186
|
+
lines.push(formatTokenLine(entry.usage, entry.cost.totalCost, 'Total', ' ', options));
|
|
187
|
+
return lines.join('\n');
|
|
137
188
|
}
|
|
138
189
|
/**
|
|
139
190
|
* Formats the grand total token usage summary block.
|
|
140
191
|
* Displayed after all tasks complete.
|
|
192
|
+
*
|
|
193
|
+
* @param usage - Total usage data
|
|
194
|
+
* @param cost - Total cost breakdown
|
|
195
|
+
* @param options - Display options for cache tokens and rate limit
|
|
141
196
|
*/
|
|
142
|
-
export function formatTokenTotalSummary(usage, cost) {
|
|
197
|
+
export function formatTokenTotalSummary(usage, cost, options = {}) {
|
|
198
|
+
const { showCacheTokens = true, showRateLimitEstimate = false, rateLimitPercentage } = options;
|
|
143
199
|
const lines = [];
|
|
144
200
|
const divider = '── Token Usage Summary ──────────────────';
|
|
145
201
|
lines.push(divider);
|
|
146
202
|
lines.push(`Total tokens: ${formatNumber(usage.inputTokens)} in / ${formatNumber(usage.outputTokens)} out`);
|
|
147
|
-
if (usage.cacheReadInputTokens > 0 || usage.cacheCreationInputTokens > 0) {
|
|
203
|
+
if (showCacheTokens && (usage.cacheReadInputTokens > 0 || usage.cacheCreationInputTokens > 0)) {
|
|
148
204
|
const cacheParts = [];
|
|
149
205
|
if (usage.cacheReadInputTokens > 0) {
|
|
150
206
|
cacheParts.push(`${formatNumber(usage.cacheReadInputTokens)} read`);
|
|
@@ -155,6 +211,9 @@ export function formatTokenTotalSummary(usage, cost) {
|
|
|
155
211
|
lines.push(`Cache: ${cacheParts.join(' / ')}`);
|
|
156
212
|
}
|
|
157
213
|
lines.push(`Estimated cost: ${formatCost(cost.totalCost)}`);
|
|
214
|
+
if (showRateLimitEstimate && rateLimitPercentage !== undefined) {
|
|
215
|
+
lines.push(formatRateLimitPercentage(rateLimitPercentage));
|
|
216
|
+
}
|
|
158
217
|
lines.push('─────────────────────────────────────────');
|
|
159
218
|
return lines.join('\n');
|
|
160
219
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-symbols.js","sourceRoot":"","sources":["../../src/utils/terminal-symbols.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"terminal-symbols.js","sourceRoot":"","sources":["../../src/utils/terminal-symbols.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,9 +10,22 @@ export interface CostBreakdown {
|
|
|
10
10
|
/** Per-task usage snapshot stored by the tracker. */
|
|
11
11
|
export interface TaskUsageEntry {
|
|
12
12
|
taskId: string;
|
|
13
|
+
/** Accumulated usage across all attempts. */
|
|
13
14
|
usage: UsageData;
|
|
15
|
+
/** Cost breakdown for accumulated usage. */
|
|
14
16
|
cost: CostBreakdown;
|
|
17
|
+
/** Raw per-attempt usage data (for display breakdowns). */
|
|
18
|
+
attempts: UsageData[];
|
|
15
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Sum multiple CostBreakdown objects into a single total.
|
|
22
|
+
*/
|
|
23
|
+
export declare function sumCostBreakdowns(costs: CostBreakdown[]): CostBreakdown;
|
|
24
|
+
/**
|
|
25
|
+
* Merge multiple UsageData objects into a single accumulated UsageData.
|
|
26
|
+
* Sums all token fields and merges modelUsage maps.
|
|
27
|
+
*/
|
|
28
|
+
export declare function accumulateUsage(attempts: UsageData[]): UsageData;
|
|
16
29
|
/**
|
|
17
30
|
* Accumulates token usage across multiple task executions and calculates costs
|
|
18
31
|
* using configurable per-model pricing.
|
|
@@ -23,8 +36,11 @@ export declare class TokenTracker {
|
|
|
23
36
|
constructor(pricingConfig?: PricingConfig);
|
|
24
37
|
/**
|
|
25
38
|
* Record usage data from a completed task.
|
|
39
|
+
* Accepts an array of UsageData (one per attempt) and accumulates them.
|
|
40
|
+
* Cost is calculated per-attempt to avoid underreporting when some attempts
|
|
41
|
+
* have modelUsage and others only have aggregate fields.
|
|
26
42
|
*/
|
|
27
|
-
addTask(taskId: string,
|
|
43
|
+
addTask(taskId: string, attempts: UsageData[]): TaskUsageEntry;
|
|
28
44
|
/**
|
|
29
45
|
* Get all recorded task entries.
|
|
30
46
|
*/
|
|
@@ -41,5 +57,19 @@ export declare class TokenTracker {
|
|
|
41
57
|
* Uses per-model breakdown when available, falls back to aggregate with sonnet pricing.
|
|
42
58
|
*/
|
|
43
59
|
calculateCost(usage: UsageData): CostBreakdown;
|
|
60
|
+
/**
|
|
61
|
+
* Calculate the 5h rate limit window percentage for a given cost.
|
|
62
|
+
* Converts cost to Sonnet-equivalent tokens using the configured Sonnet pricing,
|
|
63
|
+
* then divides by the configured cap.
|
|
64
|
+
*
|
|
65
|
+
* @param totalCost - The total cost in dollars
|
|
66
|
+
* @param sonnetTokenCap - Optional override for the Sonnet-equivalent token cap (defaults to config value)
|
|
67
|
+
* @returns The percentage of the 5h window consumed (0-100+)
|
|
68
|
+
*/
|
|
69
|
+
calculateRateLimitPercentage(totalCost: number, sonnetTokenCap?: number): number;
|
|
70
|
+
/**
|
|
71
|
+
* Get the cumulative 5h window percentage across all recorded tasks.
|
|
72
|
+
*/
|
|
73
|
+
getCumulativeRateLimitPercentage(sonnetTokenCap?: number): number;
|
|
44
74
|
}
|
|
45
75
|
//# sourceMappingURL=token-tracker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-tracker.d.ts","sourceRoot":"","sources":["../../src/utils/token-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG9D,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"token-tracker.d.ts","sourceRoot":"","sources":["../../src/utils/token-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG9D,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,KAAK,EAAE,SAAS,CAAC;IACjB,4CAA4C;IAC5C,IAAI,EAAE,aAAa,CAAC;IACpB,2DAA2D;IAC3D,QAAQ,EAAE,SAAS,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,CAkBvE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,CA8BhE;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,aAAa,CAAgB;gBAEzB,aAAa,CAAC,EAAE,aAAa;IAIzC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc;IAW9D;;OAEG;IACH,UAAU,IAAI,SAAS,cAAc,EAAE;IAIvC;;OAEG;IACH,SAAS,IAAI;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,aAAa,CAAA;KAAE;IA6CtD;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa;IAmC9C;;;;;;;;OAQG;IACH,4BAA4B,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM;IAkBhF;;OAEG;IACH,gCAAgC,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM;CAIlE"}
|
|
@@ -1,4 +1,57 @@
|
|
|
1
|
-
import { resolveModelPricingCategory, getPricingConfig } from './config.js';
|
|
1
|
+
import { resolveModelPricingCategory, getPricingConfig, getRateLimitWindowConfig } from './config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Sum multiple CostBreakdown objects into a single total.
|
|
4
|
+
*/
|
|
5
|
+
export function sumCostBreakdowns(costs) {
|
|
6
|
+
const result = {
|
|
7
|
+
inputCost: 0,
|
|
8
|
+
outputCost: 0,
|
|
9
|
+
cacheReadCost: 0,
|
|
10
|
+
cacheCreateCost: 0,
|
|
11
|
+
totalCost: 0,
|
|
12
|
+
};
|
|
13
|
+
for (const cost of costs) {
|
|
14
|
+
result.inputCost += cost.inputCost;
|
|
15
|
+
result.outputCost += cost.outputCost;
|
|
16
|
+
result.cacheReadCost += cost.cacheReadCost;
|
|
17
|
+
result.cacheCreateCost += cost.cacheCreateCost;
|
|
18
|
+
result.totalCost += cost.totalCost;
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Merge multiple UsageData objects into a single accumulated UsageData.
|
|
24
|
+
* Sums all token fields and merges modelUsage maps.
|
|
25
|
+
*/
|
|
26
|
+
export function accumulateUsage(attempts) {
|
|
27
|
+
const result = {
|
|
28
|
+
inputTokens: 0,
|
|
29
|
+
outputTokens: 0,
|
|
30
|
+
cacheReadInputTokens: 0,
|
|
31
|
+
cacheCreationInputTokens: 0,
|
|
32
|
+
modelUsage: {},
|
|
33
|
+
};
|
|
34
|
+
for (const attempt of attempts) {
|
|
35
|
+
result.inputTokens += attempt.inputTokens;
|
|
36
|
+
result.outputTokens += attempt.outputTokens;
|
|
37
|
+
result.cacheReadInputTokens += attempt.cacheReadInputTokens;
|
|
38
|
+
result.cacheCreationInputTokens += attempt.cacheCreationInputTokens;
|
|
39
|
+
// Merge per-model usage
|
|
40
|
+
for (const [modelId, modelUsage] of Object.entries(attempt.modelUsage)) {
|
|
41
|
+
const existing = result.modelUsage[modelId];
|
|
42
|
+
if (existing) {
|
|
43
|
+
existing.inputTokens += modelUsage.inputTokens;
|
|
44
|
+
existing.outputTokens += modelUsage.outputTokens;
|
|
45
|
+
existing.cacheReadInputTokens += modelUsage.cacheReadInputTokens;
|
|
46
|
+
existing.cacheCreationInputTokens += modelUsage.cacheCreationInputTokens;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
result.modelUsage[modelId] = { ...modelUsage };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
2
55
|
/**
|
|
3
56
|
* Accumulates token usage across multiple task executions and calculates costs
|
|
4
57
|
* using configurable per-model pricing.
|
|
@@ -11,10 +64,17 @@ export class TokenTracker {
|
|
|
11
64
|
}
|
|
12
65
|
/**
|
|
13
66
|
* Record usage data from a completed task.
|
|
67
|
+
* Accepts an array of UsageData (one per attempt) and accumulates them.
|
|
68
|
+
* Cost is calculated per-attempt to avoid underreporting when some attempts
|
|
69
|
+
* have modelUsage and others only have aggregate fields.
|
|
14
70
|
*/
|
|
15
|
-
addTask(taskId,
|
|
16
|
-
const
|
|
17
|
-
|
|
71
|
+
addTask(taskId, attempts) {
|
|
72
|
+
const usage = accumulateUsage(attempts);
|
|
73
|
+
// Calculate cost per-attempt, then sum. This ensures attempts with only
|
|
74
|
+
// aggregate fields use sonnet fallback pricing independently.
|
|
75
|
+
const perAttemptCosts = attempts.map((attempt) => this.calculateCost(attempt));
|
|
76
|
+
const cost = sumCostBreakdowns(perAttemptCosts);
|
|
77
|
+
const entry = { taskId, usage, cost, attempts };
|
|
18
78
|
this.entries.push(entry);
|
|
19
79
|
return entry;
|
|
20
80
|
}
|
|
@@ -103,5 +163,35 @@ export class TokenTracker {
|
|
|
103
163
|
result.totalCost = result.inputCost + result.outputCost + result.cacheReadCost + result.cacheCreateCost;
|
|
104
164
|
return result;
|
|
105
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Calculate the 5h rate limit window percentage for a given cost.
|
|
168
|
+
* Converts cost to Sonnet-equivalent tokens using the configured Sonnet pricing,
|
|
169
|
+
* then divides by the configured cap.
|
|
170
|
+
*
|
|
171
|
+
* @param totalCost - The total cost in dollars
|
|
172
|
+
* @param sonnetTokenCap - Optional override for the Sonnet-equivalent token cap (defaults to config value)
|
|
173
|
+
* @returns The percentage of the 5h window consumed (0-100+)
|
|
174
|
+
*/
|
|
175
|
+
calculateRateLimitPercentage(totalCost, sonnetTokenCap) {
|
|
176
|
+
if (totalCost === 0)
|
|
177
|
+
return 0;
|
|
178
|
+
// Get the configured cap or use the provided override
|
|
179
|
+
const cap = sonnetTokenCap ?? getRateLimitWindowConfig().sonnetTokenCap;
|
|
180
|
+
// Calculate the average Sonnet cost per token
|
|
181
|
+
// Using the average of input and output pricing (simplified approach)
|
|
182
|
+
const sonnetPricing = this.pricingConfig.sonnet;
|
|
183
|
+
const avgSonnetCostPerToken = (sonnetPricing.inputPerMTok + sonnetPricing.outputPerMTok) / 2 / 1_000_000;
|
|
184
|
+
// Convert cost to Sonnet-equivalent tokens
|
|
185
|
+
const sonnetEquivalentTokens = totalCost / avgSonnetCostPerToken;
|
|
186
|
+
// Calculate percentage
|
|
187
|
+
return (sonnetEquivalentTokens / cap) * 100;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get the cumulative 5h window percentage across all recorded tasks.
|
|
191
|
+
*/
|
|
192
|
+
getCumulativeRateLimitPercentage(sonnetTokenCap) {
|
|
193
|
+
const totals = this.getTotals();
|
|
194
|
+
return this.calculateRateLimitPercentage(totals.cost.totalCost, sonnetTokenCap);
|
|
195
|
+
}
|
|
106
196
|
}
|
|
107
197
|
//# sourceMappingURL=token-tracker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-tracker.js","sourceRoot":"","sources":["../../src/utils/token-tracker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,2BAA2B,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"token-tracker.js","sourceRoot":"","sources":["../../src/utils/token-tracker.ts"],"names":[],"mappings":"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"}
|