@ramtinj95/opencode-tokenscope 1.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/LICENSE +21 -0
- package/README.md +526 -0
- package/dist/tokenscope-lib/analyzer.d.ts +29 -0
- package/dist/tokenscope-lib/analyzer.d.ts.map +1 -0
- package/dist/tokenscope-lib/analyzer.js +321 -0
- package/dist/tokenscope-lib/analyzer.js.map +1 -0
- package/dist/tokenscope-lib/config.d.ts +10 -0
- package/dist/tokenscope-lib/config.d.ts.map +1 -0
- package/dist/tokenscope-lib/config.js +102 -0
- package/dist/tokenscope-lib/config.js.map +1 -0
- package/dist/tokenscope-lib/context.d.ts +81 -0
- package/dist/tokenscope-lib/context.d.ts.map +1 -0
- package/dist/tokenscope-lib/context.js +453 -0
- package/dist/tokenscope-lib/context.js.map +1 -0
- package/dist/tokenscope-lib/cost.d.ts +9 -0
- package/dist/tokenscope-lib/cost.d.ts.map +1 -0
- package/dist/tokenscope-lib/cost.js +51 -0
- package/dist/tokenscope-lib/cost.js.map +1 -0
- package/dist/tokenscope-lib/formatter.d.ts +26 -0
- package/dist/tokenscope-lib/formatter.d.ts.map +1 -0
- package/dist/tokenscope-lib/formatter.js +415 -0
- package/dist/tokenscope-lib/formatter.js.map +1 -0
- package/dist/tokenscope-lib/subagent.d.ts +13 -0
- package/dist/tokenscope-lib/subagent.d.ts.map +1 -0
- package/dist/tokenscope-lib/subagent.js +134 -0
- package/dist/tokenscope-lib/subagent.js.map +1 -0
- package/dist/tokenscope-lib/tokenizer.d.ts +17 -0
- package/dist/tokenscope-lib/tokenizer.d.ts.map +1 -0
- package/dist/tokenscope-lib/tokenizer.js +117 -0
- package/dist/tokenscope-lib/tokenizer.js.map +1 -0
- package/dist/tokenscope-lib/types.d.ts +252 -0
- package/dist/tokenscope-lib/types.d.ts.map +1 -0
- package/dist/tokenscope-lib/types.js +12 -0
- package/dist/tokenscope-lib/types.js.map +1 -0
- package/dist/tokenscope.d.ts +4 -0
- package/dist/tokenscope.d.ts.map +1 -0
- package/dist/tokenscope.js +98 -0
- package/dist/tokenscope.js.map +1 -0
- package/models.json +290 -0
- package/package.json +54 -0
- package/tokenscope-config.json +6 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
// ContextAnalyzer - analyzes context breakdown from opencode export
|
|
2
|
+
export class ContextAnalyzer {
|
|
3
|
+
tokenizerManager;
|
|
4
|
+
constructor(tokenizerManager) {
|
|
5
|
+
this.tokenizerManager = tokenizerManager;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Main entry point - analyzes a session using opencode export
|
|
9
|
+
*/
|
|
10
|
+
async analyze(sessionID, tokenModel, pricing, config) {
|
|
11
|
+
const result = {};
|
|
12
|
+
try {
|
|
13
|
+
const exported = await this.runExport(sessionID);
|
|
14
|
+
if (!exported)
|
|
15
|
+
return result;
|
|
16
|
+
if (config.enableContextBreakdown) {
|
|
17
|
+
result.contextBreakdown = await this.analyzeContextBreakdown(exported, tokenModel);
|
|
18
|
+
}
|
|
19
|
+
if (config.enableToolSchemaEstimation) {
|
|
20
|
+
result.toolEstimates = this.estimateToolSchemas(exported);
|
|
21
|
+
}
|
|
22
|
+
if (config.enableCacheEfficiency) {
|
|
23
|
+
result.cacheEfficiency = this.calculateCacheEfficiency(exported, pricing);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
console.error(`Context analysis failed for session ${sessionID}:`, error);
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Execute opencode export and parse the JSON output
|
|
33
|
+
*/
|
|
34
|
+
async runExport(sessionID) {
|
|
35
|
+
try {
|
|
36
|
+
const { $ } = await import("bun");
|
|
37
|
+
const result = await $ `opencode export ${sessionID}`.text();
|
|
38
|
+
// Find the start of JSON - the output format is:
|
|
39
|
+
// "Exporting session: <id>{...json...}"
|
|
40
|
+
// Note: There's no newline between the prefix and the JSON
|
|
41
|
+
const jsonStartIndex = result.indexOf("{");
|
|
42
|
+
if (jsonStartIndex === -1) {
|
|
43
|
+
console.error(`No JSON found in opencode export output for session ${sessionID}`);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const jsonContent = result.slice(jsonStartIndex);
|
|
47
|
+
return JSON.parse(jsonContent);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error(`Failed to run opencode export for session ${sessionID}:`, error);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Analyze context breakdown from cache_write tokens.
|
|
56
|
+
*
|
|
57
|
+
* Note: OpenCode's `opencode export` command doesn't include system prompt content
|
|
58
|
+
* in the output, so we estimate the breakdown from the first cache_write token count
|
|
59
|
+
* which represents the total cached context size.
|
|
60
|
+
*
|
|
61
|
+
* If system prompts become available in future versions, we can enhance this
|
|
62
|
+
* to tokenize the actual content for more accurate breakdowns.
|
|
63
|
+
*/
|
|
64
|
+
async analyzeContextBreakdown(exported, tokenModel) {
|
|
65
|
+
const breakdown = {
|
|
66
|
+
baseSystemPrompt: { tokens: 0, identified: false },
|
|
67
|
+
toolDefinitions: { tokens: 0, identified: false, toolCount: 0 },
|
|
68
|
+
environmentContext: { tokens: 0, identified: false, components: [] },
|
|
69
|
+
projectTree: { tokens: 0, identified: false, fileCount: 0 },
|
|
70
|
+
customInstructions: { tokens: 0, identified: false, sources: [] },
|
|
71
|
+
totalCachedContext: 0,
|
|
72
|
+
};
|
|
73
|
+
// Try to get system prompts from export (for future compatibility)
|
|
74
|
+
const systemPrompts = this.extractSystemPrompts(exported);
|
|
75
|
+
// If system prompts are available, analyze them directly
|
|
76
|
+
if (systemPrompts.length > 0) {
|
|
77
|
+
return this.analyzeSystemPromptContent(exported, tokenModel, systemPrompts, breakdown);
|
|
78
|
+
}
|
|
79
|
+
// Default: Estimate from cache_write tokens
|
|
80
|
+
return this.estimateContextFromCacheTokens(exported, breakdown);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Analyze actual system prompt content (for when opencode export includes it)
|
|
84
|
+
*/
|
|
85
|
+
async analyzeSystemPromptContent(exported, tokenModel, systemPrompts, breakdown) {
|
|
86
|
+
for (const prompt of systemPrompts) {
|
|
87
|
+
const promptLower = prompt.toLowerCase();
|
|
88
|
+
const tokens = await this.tokenizerManager.countTokens(prompt, tokenModel);
|
|
89
|
+
// The system prompt typically has multiple parts that may be concatenated.
|
|
90
|
+
// We need to detect different sections within each prompt string.
|
|
91
|
+
// Check for environment context with <env> tags
|
|
92
|
+
if (promptLower.includes("<env>")) {
|
|
93
|
+
// Extract just the env section tokens
|
|
94
|
+
const envMatch = prompt.match(/<env>[\s\S]*?<\/env>/i);
|
|
95
|
+
if (envMatch) {
|
|
96
|
+
const envTokens = await this.tokenizerManager.countTokens(envMatch[0], tokenModel);
|
|
97
|
+
breakdown.environmentContext.tokens += envTokens;
|
|
98
|
+
breakdown.environmentContext.identified = true;
|
|
99
|
+
if (promptLower.includes("working directory:")) {
|
|
100
|
+
breakdown.environmentContext.components.push("working-dir");
|
|
101
|
+
}
|
|
102
|
+
if (promptLower.includes("platform:")) {
|
|
103
|
+
breakdown.environmentContext.components.push("platform");
|
|
104
|
+
}
|
|
105
|
+
if (promptLower.includes("git repo")) {
|
|
106
|
+
breakdown.environmentContext.components.push("git-status");
|
|
107
|
+
}
|
|
108
|
+
if (promptLower.includes("date:")) {
|
|
109
|
+
breakdown.environmentContext.components.push("date");
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Check for project tree with <files> tags
|
|
114
|
+
if (promptLower.includes("<files>")) {
|
|
115
|
+
const filesMatch = prompt.match(/<files>[\s\S]*?<\/files>/i);
|
|
116
|
+
if (filesMatch) {
|
|
117
|
+
const filesTokens = await this.tokenizerManager.countTokens(filesMatch[0], tokenModel);
|
|
118
|
+
breakdown.projectTree.tokens += filesTokens;
|
|
119
|
+
breakdown.projectTree.identified = true;
|
|
120
|
+
// Count file references
|
|
121
|
+
const fileMatches = filesMatch[0].match(/\n\s+[\w\-\.]+\.[a-z]{1,5}/g);
|
|
122
|
+
if (fileMatches) {
|
|
123
|
+
breakdown.projectTree.fileCount += fileMatches.length;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Check for custom instructions
|
|
128
|
+
if (promptLower.includes("instructions from:") || promptLower.includes("agents.md")) {
|
|
129
|
+
// Try to extract just the instructions section
|
|
130
|
+
const instructionMatches = prompt.match(/Instructions from:[\s\S]*?(?=Instructions from:|<env>|<files>|$)/gi);
|
|
131
|
+
if (instructionMatches) {
|
|
132
|
+
for (const match of instructionMatches) {
|
|
133
|
+
const instrTokens = await this.tokenizerManager.countTokens(match, tokenModel);
|
|
134
|
+
breakdown.customInstructions.tokens += instrTokens;
|
|
135
|
+
breakdown.customInstructions.identified = true;
|
|
136
|
+
// Extract source path
|
|
137
|
+
const pathMatch = match.match(/Instructions from:\s*([^\n]+)/i);
|
|
138
|
+
if (pathMatch && pathMatch[1]) {
|
|
139
|
+
const sourcePath = pathMatch[1].trim();
|
|
140
|
+
if (sourcePath && !breakdown.customInstructions.sources.includes(sourcePath)) {
|
|
141
|
+
breakdown.customInstructions.sources.push(sourcePath);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Tool definitions detection (in <functions> tags)
|
|
148
|
+
if (promptLower.includes("<functions>") || promptLower.includes('"type": "object"')) {
|
|
149
|
+
const functionsMatch = prompt.match(/<functions>[\s\S]*?<\/functions>/i);
|
|
150
|
+
if (functionsMatch) {
|
|
151
|
+
const funcTokens = await this.tokenizerManager.countTokens(functionsMatch[0], tokenModel);
|
|
152
|
+
breakdown.toolDefinitions.tokens += funcTokens;
|
|
153
|
+
breakdown.toolDefinitions.identified = true;
|
|
154
|
+
// Count tools from <function> tags
|
|
155
|
+
const toolMatches = functionsMatch[0].match(/<function>/g);
|
|
156
|
+
if (toolMatches) {
|
|
157
|
+
breakdown.toolDefinitions.toolCount += toolMatches.length;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Fallback: count the whole prompt as tool definitions
|
|
162
|
+
breakdown.toolDefinitions.tokens += tokens;
|
|
163
|
+
breakdown.toolDefinitions.identified = true;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Base system prompt detection - the main instructions
|
|
167
|
+
// This is typically the first/longest part without the special tags
|
|
168
|
+
if ((promptLower.includes("you are opencode") ||
|
|
169
|
+
promptLower.includes("you are claude") ||
|
|
170
|
+
promptLower.includes("you are an") ||
|
|
171
|
+
promptLower.includes("you are a ") ||
|
|
172
|
+
(promptLower.includes("assistant") && promptLower.includes("software engineering"))) &&
|
|
173
|
+
!promptLower.includes("<env>") &&
|
|
174
|
+
!promptLower.includes("<files>") &&
|
|
175
|
+
!promptLower.includes("<functions>")) {
|
|
176
|
+
breakdown.baseSystemPrompt.tokens += tokens;
|
|
177
|
+
breakdown.baseSystemPrompt.identified = true;
|
|
178
|
+
}
|
|
179
|
+
// If nothing specific matched but it's substantial text, add to base prompt
|
|
180
|
+
else if (prompt.length > 500 &&
|
|
181
|
+
!promptLower.includes("<env>") &&
|
|
182
|
+
!promptLower.includes("<files>") &&
|
|
183
|
+
!promptLower.includes("<functions>") &&
|
|
184
|
+
!promptLower.includes("instructions from:")) {
|
|
185
|
+
breakdown.baseSystemPrompt.tokens += tokens;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
breakdown.totalCachedContext =
|
|
189
|
+
breakdown.baseSystemPrompt.tokens +
|
|
190
|
+
breakdown.toolDefinitions.tokens +
|
|
191
|
+
breakdown.environmentContext.tokens +
|
|
192
|
+
breakdown.projectTree.tokens +
|
|
193
|
+
breakdown.customInstructions.tokens;
|
|
194
|
+
return breakdown;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Extract system prompts from exported session
|
|
198
|
+
*/
|
|
199
|
+
extractSystemPrompts(exported) {
|
|
200
|
+
const prompts = new Set();
|
|
201
|
+
for (const message of exported.messages) {
|
|
202
|
+
// Assistant messages contain system[] in info
|
|
203
|
+
if (message.info.role === "assistant" && message.info.system) {
|
|
204
|
+
for (const prompt of message.info.system) {
|
|
205
|
+
if (prompt && prompt.trim()) {
|
|
206
|
+
prompts.add(prompt.trim());
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return Array.from(prompts);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Estimate context breakdown from cache token counts when system prompts aren't available.
|
|
215
|
+
*
|
|
216
|
+
* Based on typical OpenCode system prompt structure:
|
|
217
|
+
* - Base System Prompt: ~1,500-2,000 tokens
|
|
218
|
+
* - Tool Definitions: ~350 tokens per tool (typically 12-15 tools = ~4,500-5,500)
|
|
219
|
+
* - Environment Context: ~100-200 tokens
|
|
220
|
+
* - Project Tree: ~300-800 tokens (varies by project)
|
|
221
|
+
* - Custom Instructions: ~100-500 tokens
|
|
222
|
+
*
|
|
223
|
+
* We use the first cache_write value as an estimate of total cached context.
|
|
224
|
+
*/
|
|
225
|
+
estimateContextFromCacheTokens(exported, breakdown) {
|
|
226
|
+
// Find the first assistant message with cache_write to get total context size
|
|
227
|
+
let totalCachedTokens = 0;
|
|
228
|
+
let enabledToolCount = 0;
|
|
229
|
+
for (const message of exported.messages) {
|
|
230
|
+
if (message.info.role === "assistant" && message.info.tokens?.cache?.write) {
|
|
231
|
+
totalCachedTokens = message.info.tokens.cache.write;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Count enabled tools from tool calls
|
|
236
|
+
const enabledTools = this.extractEnabledTools(exported);
|
|
237
|
+
enabledToolCount = Object.keys(enabledTools).length;
|
|
238
|
+
if (totalCachedTokens === 0) {
|
|
239
|
+
return breakdown;
|
|
240
|
+
}
|
|
241
|
+
// Estimate tool definitions (~350 tokens per tool)
|
|
242
|
+
const estimatedToolTokens = enabledToolCount * 350;
|
|
243
|
+
breakdown.toolDefinitions.tokens = estimatedToolTokens;
|
|
244
|
+
breakdown.toolDefinitions.toolCount = enabledToolCount;
|
|
245
|
+
breakdown.toolDefinitions.identified = false; // Mark as estimated
|
|
246
|
+
// Estimate environment context (~150 tokens)
|
|
247
|
+
breakdown.environmentContext.tokens = 150;
|
|
248
|
+
breakdown.environmentContext.components = ["working-dir", "platform", "git-status", "date"];
|
|
249
|
+
breakdown.environmentContext.identified = false;
|
|
250
|
+
// Estimate project tree (~500 tokens average)
|
|
251
|
+
breakdown.projectTree.tokens = 500;
|
|
252
|
+
breakdown.projectTree.identified = false;
|
|
253
|
+
// Remaining tokens go to base system prompt
|
|
254
|
+
const remainingTokens = totalCachedTokens - estimatedToolTokens - 150 - 500;
|
|
255
|
+
breakdown.baseSystemPrompt.tokens = Math.max(0, remainingTokens);
|
|
256
|
+
breakdown.baseSystemPrompt.identified = false;
|
|
257
|
+
breakdown.totalCachedContext = totalCachedTokens;
|
|
258
|
+
return breakdown;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Check if content looks like a file tree
|
|
262
|
+
*/
|
|
263
|
+
looksLikeFileTree(content) {
|
|
264
|
+
const lines = content.split("\n");
|
|
265
|
+
let indentedLines = 0;
|
|
266
|
+
let filePatternLines = 0;
|
|
267
|
+
for (const line of lines) {
|
|
268
|
+
if (/^\s{2,}[\w\-\.]+/.test(line)) {
|
|
269
|
+
indentedLines++;
|
|
270
|
+
}
|
|
271
|
+
if (/\.(ts|js|md|json|py|go|rs|java|c|cpp|h|css|html|tsx|jsx)$/i.test(line)) {
|
|
272
|
+
filePatternLines++;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return indentedLines > 5 && filePatternLines > 3;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Estimate tool schema tokens from tool calls in the session
|
|
279
|
+
*/
|
|
280
|
+
estimateToolSchemas(exported) {
|
|
281
|
+
const enabledTools = this.extractEnabledTools(exported);
|
|
282
|
+
const toolCallData = this.extractToolCallData(exported);
|
|
283
|
+
const estimates = [];
|
|
284
|
+
for (const [toolName, enabled] of Object.entries(enabledTools)) {
|
|
285
|
+
const callData = toolCallData.get(toolName);
|
|
286
|
+
const estimate = this.estimateToolTokens(toolName, callData);
|
|
287
|
+
estimates.push({
|
|
288
|
+
name: toolName,
|
|
289
|
+
enabled,
|
|
290
|
+
estimatedTokens: estimate.tokens,
|
|
291
|
+
argumentCount: estimate.argCount,
|
|
292
|
+
hasComplexArgs: estimate.hasComplex,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
// Sort by estimated tokens descending
|
|
296
|
+
estimates.sort((a, b) => b.estimatedTokens - a.estimatedTokens);
|
|
297
|
+
return estimates;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Extract enabled tools from user messages
|
|
301
|
+
*/
|
|
302
|
+
extractEnabledTools(exported) {
|
|
303
|
+
const tools = {};
|
|
304
|
+
for (const message of exported.messages) {
|
|
305
|
+
// User messages may contain tools map in info
|
|
306
|
+
if (message.info.tools) {
|
|
307
|
+
for (const [name, enabled] of Object.entries(message.info.tools)) {
|
|
308
|
+
tools[name] = enabled;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// Also collect from tool calls if tools map not available
|
|
313
|
+
if (Object.keys(tools).length === 0) {
|
|
314
|
+
for (const message of exported.messages) {
|
|
315
|
+
for (const part of message.parts) {
|
|
316
|
+
if (part.type === "tool" && part.tool) {
|
|
317
|
+
tools[part.tool] = true;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return tools;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Extract tool call argument data for inference
|
|
326
|
+
*/
|
|
327
|
+
extractToolCallData(exported) {
|
|
328
|
+
const data = new Map();
|
|
329
|
+
for (const message of exported.messages) {
|
|
330
|
+
for (const part of message.parts) {
|
|
331
|
+
if (part.type === "tool" && part.tool && part.state?.input) {
|
|
332
|
+
const toolName = part.tool;
|
|
333
|
+
const existing = data.get(toolName) || [];
|
|
334
|
+
existing.push({
|
|
335
|
+
argNames: Object.keys(part.state.input),
|
|
336
|
+
argTypes: this.inferArgTypes(part.state.input),
|
|
337
|
+
});
|
|
338
|
+
data.set(toolName, existing);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return data;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Infer argument types from values
|
|
346
|
+
*/
|
|
347
|
+
inferArgTypes(input) {
|
|
348
|
+
const types = {};
|
|
349
|
+
for (const [key, value] of Object.entries(input)) {
|
|
350
|
+
if (Array.isArray(value)) {
|
|
351
|
+
types[key] = "array";
|
|
352
|
+
}
|
|
353
|
+
else if (typeof value === "object" && value !== null) {
|
|
354
|
+
types[key] = "object";
|
|
355
|
+
}
|
|
356
|
+
else if (typeof value === "number") {
|
|
357
|
+
types[key] = "number";
|
|
358
|
+
}
|
|
359
|
+
else if (typeof value === "boolean") {
|
|
360
|
+
types[key] = "boolean";
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
types[key] = "string";
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return types;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Estimate tokens for a tool schema based on call data
|
|
370
|
+
*
|
|
371
|
+
* Formula from plan:
|
|
372
|
+
* base_tokens = 200 (description + schema overhead)
|
|
373
|
+
* per_simple_arg = 30
|
|
374
|
+
* per_complex_arg = 60 (arrays, objects)
|
|
375
|
+
* description_bonus = 80 (simple) or 120 (complex)
|
|
376
|
+
*/
|
|
377
|
+
estimateToolTokens(toolName, callData) {
|
|
378
|
+
const BASE_TOKENS = 200;
|
|
379
|
+
const PER_SIMPLE_ARG = 30;
|
|
380
|
+
const PER_COMPLEX_ARG = 60;
|
|
381
|
+
const SIMPLE_DESCRIPTION_BONUS = 80;
|
|
382
|
+
const COMPLEX_DESCRIPTION_BONUS = 120;
|
|
383
|
+
// If no call data, use conservative defaults
|
|
384
|
+
if (!callData || callData.length === 0) {
|
|
385
|
+
return {
|
|
386
|
+
tokens: BASE_TOKENS + 3 * PER_SIMPLE_ARG + PER_COMPLEX_ARG + SIMPLE_DESCRIPTION_BONUS,
|
|
387
|
+
argCount: 3,
|
|
388
|
+
hasComplex: true,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
// Aggregate argument info from all calls
|
|
392
|
+
const allArgNames = new Set();
|
|
393
|
+
const complexArgs = new Set();
|
|
394
|
+
for (const call of callData) {
|
|
395
|
+
for (const name of call.argNames) {
|
|
396
|
+
allArgNames.add(name);
|
|
397
|
+
}
|
|
398
|
+
for (const [name, type] of Object.entries(call.argTypes)) {
|
|
399
|
+
if (type === "array" || type === "object") {
|
|
400
|
+
complexArgs.add(name);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
const argCount = allArgNames.size;
|
|
405
|
+
const simpleArgCount = argCount - complexArgs.size;
|
|
406
|
+
const complexArgCount = complexArgs.size;
|
|
407
|
+
const hasComplex = complexArgCount > 0;
|
|
408
|
+
const descBonus = hasComplex ? COMPLEX_DESCRIPTION_BONUS : SIMPLE_DESCRIPTION_BONUS;
|
|
409
|
+
const tokens = BASE_TOKENS + simpleArgCount * PER_SIMPLE_ARG + complexArgCount * PER_COMPLEX_ARG + descBonus;
|
|
410
|
+
return { tokens, argCount, hasComplex };
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Calculate cache efficiency metrics
|
|
414
|
+
*/
|
|
415
|
+
calculateCacheEfficiency(exported, pricing) {
|
|
416
|
+
let totalCacheRead = 0;
|
|
417
|
+
let totalFreshInput = 0;
|
|
418
|
+
let totalCacheWrite = 0;
|
|
419
|
+
for (const message of exported.messages) {
|
|
420
|
+
if (message.info.role === "assistant" && message.info.tokens) {
|
|
421
|
+
const tokens = message.info.tokens;
|
|
422
|
+
totalCacheRead += Number(tokens.cache?.read) || 0;
|
|
423
|
+
totalFreshInput += Number(tokens.input) || 0;
|
|
424
|
+
totalCacheWrite += Number(tokens.cache?.write) || 0;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
const totalInputTokens = totalCacheRead + totalFreshInput;
|
|
428
|
+
// Cache hit rate
|
|
429
|
+
const cacheHitRate = totalInputTokens > 0 ? (totalCacheRead / totalInputTokens) * 100 : 0;
|
|
430
|
+
// Cost calculations
|
|
431
|
+
const costWithoutCaching = (totalInputTokens / 1_000_000) * pricing.input;
|
|
432
|
+
const costWithCaching = (totalFreshInput / 1_000_000) * pricing.input + (totalCacheRead / 1_000_000) * pricing.cacheRead;
|
|
433
|
+
const costSavings = costWithoutCaching - costWithCaching;
|
|
434
|
+
const savingsPercent = costWithoutCaching > 0 ? (costSavings / costWithoutCaching) * 100 : 0;
|
|
435
|
+
// Effective rate (what you're actually paying per token)
|
|
436
|
+
const effectiveRate = totalInputTokens > 0 ? (costWithCaching / totalInputTokens) * 1_000_000 : 0;
|
|
437
|
+
const standardRate = pricing.input;
|
|
438
|
+
return {
|
|
439
|
+
cacheReadTokens: totalCacheRead,
|
|
440
|
+
freshInputTokens: totalFreshInput,
|
|
441
|
+
cacheWriteTokens: totalCacheWrite,
|
|
442
|
+
totalInputTokens,
|
|
443
|
+
cacheHitRate,
|
|
444
|
+
costWithoutCaching,
|
|
445
|
+
costWithCaching,
|
|
446
|
+
costSavings,
|
|
447
|
+
savingsPercent,
|
|
448
|
+
effectiveRate,
|
|
449
|
+
standardRate,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../tokenscope-lib/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TokenAnalysis, CostEstimate, ModelPricing } from "./types";
|
|
2
|
+
export declare class CostCalculator {
|
|
3
|
+
private pricingData;
|
|
4
|
+
constructor(pricingData: Record<string, ModelPricing>);
|
|
5
|
+
calculateCost(analysis: TokenAnalysis): CostEstimate;
|
|
6
|
+
getPricing(modelName: string): ModelPricing;
|
|
7
|
+
private normalizeModelName;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=cost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../tokenscope-lib/cost.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAExE,qBAAa,cAAc;IACb,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC;IAE7D,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,YAAY;IAiCpD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY;IAa3C,OAAO,CAAC,kBAAkB;CAG3B"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// CostCalculator - calculates costs from token analysis
|
|
2
|
+
export class CostCalculator {
|
|
3
|
+
pricingData;
|
|
4
|
+
constructor(pricingData) {
|
|
5
|
+
this.pricingData = pricingData;
|
|
6
|
+
}
|
|
7
|
+
calculateCost(analysis) {
|
|
8
|
+
const pricing = this.getPricing(analysis.model.name);
|
|
9
|
+
const hasActivity = analysis.assistantMessageCount > 0 && (analysis.inputTokens > 0 || analysis.outputTokens > 0);
|
|
10
|
+
const isSubscription = hasActivity && analysis.sessionCost === 0;
|
|
11
|
+
const estimatedInputCost = (analysis.inputTokens / 1_000_000) * pricing.input;
|
|
12
|
+
const estimatedOutputCost = ((analysis.outputTokens + analysis.reasoningTokens) / 1_000_000) * pricing.output;
|
|
13
|
+
const estimatedCacheReadCost = (analysis.cacheReadTokens / 1_000_000) * pricing.cacheRead;
|
|
14
|
+
const estimatedCacheWriteCost = (analysis.cacheWriteTokens / 1_000_000) * pricing.cacheWrite;
|
|
15
|
+
const estimatedSessionCost = estimatedInputCost + estimatedOutputCost + estimatedCacheReadCost + estimatedCacheWriteCost;
|
|
16
|
+
return {
|
|
17
|
+
isSubscription,
|
|
18
|
+
apiSessionCost: analysis.sessionCost,
|
|
19
|
+
apiMostRecentCost: analysis.mostRecentCost,
|
|
20
|
+
estimatedSessionCost,
|
|
21
|
+
estimatedInputCost,
|
|
22
|
+
estimatedOutputCost,
|
|
23
|
+
estimatedCacheReadCost,
|
|
24
|
+
estimatedCacheWriteCost,
|
|
25
|
+
pricePerMillionInput: pricing.input,
|
|
26
|
+
pricePerMillionOutput: pricing.output,
|
|
27
|
+
pricePerMillionCacheRead: pricing.cacheRead,
|
|
28
|
+
pricePerMillionCacheWrite: pricing.cacheWrite,
|
|
29
|
+
inputTokens: analysis.inputTokens,
|
|
30
|
+
outputTokens: analysis.outputTokens,
|
|
31
|
+
reasoningTokens: analysis.reasoningTokens,
|
|
32
|
+
cacheReadTokens: analysis.cacheReadTokens,
|
|
33
|
+
cacheWriteTokens: analysis.cacheWriteTokens,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
getPricing(modelName) {
|
|
37
|
+
const normalizedName = this.normalizeModelName(modelName);
|
|
38
|
+
if (this.pricingData[normalizedName])
|
|
39
|
+
return this.pricingData[normalizedName];
|
|
40
|
+
const lowerModel = normalizedName.toLowerCase();
|
|
41
|
+
for (const [key, pricing] of Object.entries(this.pricingData)) {
|
|
42
|
+
if (lowerModel.startsWith(key.toLowerCase()))
|
|
43
|
+
return pricing;
|
|
44
|
+
}
|
|
45
|
+
return this.pricingData["default"] || { input: 1, output: 3, cacheWrite: 0, cacheRead: 0 };
|
|
46
|
+
}
|
|
47
|
+
normalizeModelName(modelName) {
|
|
48
|
+
return modelName.includes("/") ? modelName.split("/").pop() || modelName : modelName;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=cost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../tokenscope-lib/cost.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAIxD,MAAM,OAAO,cAAc;IACL;IAApB,YAAoB,WAAyC;QAAzC,gBAAW,GAAX,WAAW,CAA8B;IAAG,CAAC;IAEjE,aAAa,CAAC,QAAuB;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACpD,MAAM,WAAW,GAAG,QAAQ,CAAC,qBAAqB,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,IAAI,QAAQ,CAAC,YAAY,GAAG,CAAC,CAAC,CAAA;QACjH,MAAM,cAAc,GAAG,WAAW,IAAI,QAAQ,CAAC,WAAW,KAAK,CAAC,CAAA;QAEhE,MAAM,kBAAkB,GAAG,CAAC,QAAQ,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,KAAK,CAAA;QAC7E,MAAM,mBAAmB,GAAG,CAAC,CAAC,QAAQ,CAAC,YAAY,GAAG,QAAQ,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,MAAM,CAAA;QAC7G,MAAM,sBAAsB,GAAG,CAAC,QAAQ,CAAC,eAAe,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAA;QACzF,MAAM,uBAAuB,GAAG,CAAC,QAAQ,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,UAAU,CAAA;QAC5F,MAAM,oBAAoB,GACxB,kBAAkB,GAAG,mBAAmB,GAAG,sBAAsB,GAAG,uBAAuB,CAAA;QAE7F,OAAO;YACL,cAAc;YACd,cAAc,EAAE,QAAQ,CAAC,WAAW;YACpC,iBAAiB,EAAE,QAAQ,CAAC,cAAc;YAC1C,oBAAoB;YACpB,kBAAkB;YAClB,mBAAmB;YACnB,sBAAsB;YACtB,uBAAuB;YACvB,oBAAoB,EAAE,OAAO,CAAC,KAAK;YACnC,qBAAqB,EAAE,OAAO,CAAC,MAAM;YACrC,wBAAwB,EAAE,OAAO,CAAC,SAAS;YAC3C,yBAAyB,EAAE,OAAO,CAAC,UAAU;YAC7C,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;SAC5C,CAAA;IACH,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAA;QAEzD,IAAI,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAA;QAE7E,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,EAAE,CAAA;QAC/C,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9D,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBAAE,OAAO,OAAO,CAAA;QAC9D,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAA;IAC5F,CAAC;IAEO,kBAAkB,CAAC,SAAiB;QAC1C,OAAO,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IACtF,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { TokenAnalysis, TokenscopeConfig } from "./types";
|
|
2
|
+
import { CostCalculator } from "./cost";
|
|
3
|
+
export declare class OutputFormatter {
|
|
4
|
+
private costCalculator;
|
|
5
|
+
private readonly BAR_WIDTH;
|
|
6
|
+
private readonly TOKEN_SPACING;
|
|
7
|
+
private readonly CATEGORY_LABEL_WIDTH;
|
|
8
|
+
private readonly TOOL_LABEL_WIDTH;
|
|
9
|
+
private readonly TOP_CONTRIBUTOR_LABEL_WIDTH;
|
|
10
|
+
private readonly CONTEXT_LABEL_WIDTH;
|
|
11
|
+
private readonly TOOL_ESTIMATE_LABEL_WIDTH;
|
|
12
|
+
private config;
|
|
13
|
+
constructor(costCalculator: CostCalculator);
|
|
14
|
+
setConfig(config: TokenscopeConfig): void;
|
|
15
|
+
private formatCategoryBar;
|
|
16
|
+
format(analysis: TokenAnalysis): string;
|
|
17
|
+
private formatVisualOutput;
|
|
18
|
+
private formatContextBreakdown;
|
|
19
|
+
private formatContextBar;
|
|
20
|
+
private formatToolEstimates;
|
|
21
|
+
private formatCacheEfficiency;
|
|
22
|
+
private formatEfficiencyBar;
|
|
23
|
+
private collectTopEntries;
|
|
24
|
+
private formatNumber;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../tokenscope-lib/formatter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EAOb,gBAAgB,EACjB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAEvC,qBAAa,eAAe;IAWd,OAAO,CAAC,cAAc;IAVlC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAK;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAK;IACnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAI;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAK;IACtC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAK;IACjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAK;IACzC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAK;IAE/C,OAAO,CAAC,MAAM,CAAgC;gBAE1B,cAAc,EAAE,cAAc;IAElD,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAIzC,OAAO,CAAC,iBAAiB;IA2BzB,MAAM,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM;IAqDvC,OAAO,CAAC,kBAAkB;IAiR1B,OAAO,CAAC,sBAAsB;IAwE9B,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,mBAAmB;IAgC3B,OAAO,CAAC,qBAAqB;IA4C7B,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,YAAY;CAGrB"}
|