codeep 2.16.0 → 2.18.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.
@@ -2,13 +2,16 @@
2
2
  * Token and cost tracking for API usage
3
3
  */
4
4
  import { AsyncLocalStorage } from 'node:async_hooks';
5
- // Context window sizes per model (in tokens).
6
- // Keep this table in lockstep with `providers.ts` — entries for models that
7
- // aren't in the provider catalogue only show up if a user types an id by hand
8
- // and produce phantom estimates against the wrong context size.
5
+ import { isFlatFeeProvider } from '../config/providers.js';
6
+ import { formatResourceImpactReport } from './resourceImpact.js';
7
+ // Context window sizes per model (in tokens). Primarily mirrors providers.ts;
8
+ // retired aliases remain only where restored historical sessions still need a
9
+ // meaningful context/cost display.
9
10
  const MODEL_CONTEXT_WINDOWS = {
10
11
  // Z.AI / ZhipuAI
11
- 'glm-5.2': 200_000,
12
+ 'glm-5.3': 1_000_000,
13
+ 'glm-5.2': 1_000_000,
14
+ 'glm-5.1': 200_000,
12
15
  'glm-5-turbo': 202_752,
13
16
  // OpenAI
14
17
  'gpt-5.6-sol': 1_050_000,
@@ -28,31 +31,36 @@ const MODEL_CONTEXT_WINDOWS = {
28
31
  'deepseek-v4-flash': 1_000_000,
29
32
  // Google
30
33
  'gemini-3.1-pro-preview': 1_048_576,
31
- 'gemini-3.5-flash': 1_000_000,
32
- 'gemini-3.1-flash-lite': 1_048_576,
34
+ 'gemini-3.7-flash': 1_048_576,
35
+ 'gemini-3.6-flash': 1_048_576,
36
+ 'gemini-3.5-flash': 1_048_576,
37
+ 'gemini-3.5-flash-lite': 1_048_576,
33
38
  'gemini-3-flash-preview': 1_000_000,
34
39
  // MiniMax
35
- 'MiniMax-M3': 524_288,
36
- // Kimi (Moonshot) — 1M on the K3 line, 256K across K2.x
37
- 'kimi-k3-code': 1_000_000,
38
- 'kimi-k3-code-highspeed': 1_000_000,
39
- 'kimi-k3-thinking': 1_000_000,
40
+ 'MiniMax-M3': 1_000_000,
41
+ // Kimi (Moonshot) — 1M on K3, 256K across K2.x
42
+ 'kimi-k3': 1_000_000,
40
43
  'kimi-k2.7-code': 262_144,
41
44
  'kimi-k2.7-code-highspeed': 262_144,
42
45
  'kimi-k2.6': 262_144,
43
- 'kimi-k2.5': 262_144,
44
46
  'kimi-for-coding': 262_144,
47
+ 'kimi-for-coding-highspeed': 262_144,
48
+ 'k3': 1_000_000,
49
+ 'k3-256k': 262_144,
45
50
  // Grok (xAI)
51
+ 'grok-4.6': 500_000,
46
52
  'grok-4.5': 500_000,
47
53
  'grok-build-0.1': 256_000,
48
54
  'grok-4.3': 1_000_000,
49
55
  'grok-code-fast-1': 256_000,
50
56
  'grok-4-fast-reasoning': 2_000_000,
51
- // Qwen (Alibaba) — 256K native (1M with extrapolation)
52
- 'qwen3-coder-plus': 262_144,
53
- 'qwen3-coder-next': 262_144,
54
- 'qwen3-coder-flash': 262_144,
57
+ // Qwen (Alibaba) — current hosted generation
55
58
  'qwen3.7-max': 1_000_000,
59
+ 'qwen3.8-max-preview': 1_000_000,
60
+ 'qwen3.7-plus': 1_000_000,
61
+ 'qwen3.6-plus': 1_000_000,
62
+ 'qwen3.5-plus': 1_000_000,
63
+ 'qwen3.6-flash': 1_000_000,
56
64
  'Qwen/Qwen3-Coder-480B-A35B-Instruct': 262_144,
57
65
  };
58
66
  const DEFAULT_CONTEXT_WINDOW = 128_000;
@@ -63,20 +71,21 @@ export function getModelContextWindow(model) {
63
71
  return MODEL_CONTEXT_WINDOWS[model] ?? DEFAULT_CONTEXT_WINDOW;
64
72
  }
65
73
  // Pricing table — USD per 1M tokens. Same rule as MODEL_CONTEXT_WINDOWS:
66
- // only list model ids that exist in `providers.ts`, otherwise typing an id
67
- // by hand can produce phantom cost estimates against stale rates.
74
+ // Primarily mirrors `providers.ts`. A few retired aliases remain so restored
75
+ // historical sessions still show the rate that applied when they were created.
68
76
  const MODEL_PRICING = {
69
77
  // Z.AI / ZhipuAI
70
- // GLM-5.2 per-token pricing isn't published yet — mirror GLM-5.1 (same tier,
71
- // its successor) provisionally so /cost stays sane; update when z.ai posts it.
72
- // Note: on the GLM Coding Plan (the default `z.ai` provider) billing is a flat
73
- // subscription, so this only affects the pay-per-use estimate.
74
- 'glm-5.2': { inputPer1M: 1.00, outputPer1M: 3.20 },
78
+ // Coding Plan is flat-fee; these official rates apply to pay-per-use.
79
+ // `glm-5.3` is GLM Coding Plan only — Z.AI publishes no per-token rate for it
80
+ // (the standalone model API is still "coming soon"), so it stays unpriced
81
+ // rather than borrowing GLM-5.2's.
82
+ 'glm-5.2': { inputPer1M: 1.40, outputPer1M: 4.40 },
83
+ 'glm-5.1': { inputPer1M: 1.40, outputPer1M: 4.40 },
75
84
  'glm-5-turbo': { inputPer1M: 1.20, outputPer1M: 4.00 },
76
85
  // OpenAI
77
86
  'gpt-5.6-sol': { inputPer1M: 5.00, outputPer1M: 30.00 },
78
- 'gpt-5.6-terra': { inputPer1M: 2.50, outputPer1M: 15.00 },
79
- 'gpt-5.6-luna': { inputPer1M: 1.00, outputPer1M: 6.00 },
87
+ 'gpt-5.6-terra': { inputPer1M: 2.00, outputPer1M: 12.00 },
88
+ 'gpt-5.6-luna': { inputPer1M: 0.20, outputPer1M: 1.20 },
80
89
  'gpt-5.5': { inputPer1M: 5.00, outputPer1M: 30.00 },
81
90
  'gpt-5.4': { inputPer1M: 2.50, outputPer1M: 15.00 },
82
91
  'gpt-5.4-mini': { inputPer1M: 0.75, outputPer1M: 4.50 },
@@ -87,37 +96,48 @@ const MODEL_PRICING = {
87
96
  'claude-sonnet-5': { inputPer1M: 3.00, outputPer1M: 15.00 },
88
97
  'claude-haiku-4-5-20251001': { inputPer1M: 1.00, outputPer1M: 5.00 },
89
98
  // DeepSeek (cache-miss input pricing)
90
- 'deepseek-v4-pro': { inputPer1M: 1.74, outputPer1M: 3.48 },
99
+ 'deepseek-v4-pro': { inputPer1M: 0.435, outputPer1M: 0.87 },
91
100
  'deepseek-v4-flash': { inputPer1M: 0.14, outputPer1M: 0.28 },
92
101
  // Google
102
+ // Gemini 3.6/3.7 Flash carry PROMOTIONAL rates that run through 2026-12-31 and
103
+ // step up to 1.50/7.50 on 2027-01-01 — revisit both rows on that date.
93
104
  'gemini-3.1-pro-preview': { inputPer1M: 2.00, outputPer1M: 12.00 },
105
+ 'gemini-3.7-flash': { inputPer1M: 0.75, outputPer1M: 3.75 },
106
+ 'gemini-3.6-flash': { inputPer1M: 0.75, outputPer1M: 3.75 },
94
107
  'gemini-3.5-flash': { inputPer1M: 1.50, outputPer1M: 9.00 },
95
- 'gemini-3.1-flash-lite': { inputPer1M: 0.25, outputPer1M: 1.50 },
108
+ 'gemini-3.5-flash-lite': { inputPer1M: 0.30, outputPer1M: 2.50 },
96
109
  'gemini-3-flash-preview': { inputPer1M: 0.50, outputPer1M: 3.00 },
97
110
  // MiniMax
98
111
  'MiniMax-M3': { inputPer1M: 0.60, outputPer1M: 2.40 },
99
112
  // Kimi (Moonshot) — pay-per-use cache-miss rates; `kimi-for-coding` is the
100
113
  // subscription alias (flat-fee in reality, priced notionally like K2.7 Code).
101
- 'kimi-k3-code': { inputPer1M: 0.60, outputPer1M: 2.50 },
102
- 'kimi-k3-code-highspeed': { inputPer1M: 0.60, outputPer1M: 2.50 },
103
- 'kimi-k3-thinking': { inputPer1M: 0.60, outputPer1M: 2.50 },
104
- 'kimi-k2.7-code': { inputPer1M: 0.60, outputPer1M: 2.50 },
105
- 'kimi-k2.7-code-highspeed': { inputPer1M: 0.60, outputPer1M: 2.50 },
106
- 'kimi-k2.6': { inputPer1M: 0.55, outputPer1M: 2.20 },
107
- 'kimi-k2.5': { inputPer1M: 0.40, outputPer1M: 1.90 },
108
- 'kimi-for-coding': { inputPer1M: 0.60, outputPer1M: 2.50 },
109
- // Grok (xAI)
114
+ 'kimi-k3': { inputPer1M: 3.00, outputPer1M: 15.00 },
115
+ 'kimi-k2.7-code': { inputPer1M: 0.95, outputPer1M: 4.00 },
116
+ // Kimi doesn't publish a distinct high-speed price in its main table.
117
+ // Leave that variant unpriced rather than presenting an invented estimate.
118
+ 'kimi-k2.6': { inputPer1M: 0.95, outputPer1M: 4.00 },
119
+ 'kimi-for-coding': { inputPer1M: 0.95, outputPer1M: 4.00 },
120
+ 'kimi-for-coding-highspeed': { inputPer1M: 0.95, outputPer1M: 4.00 },
121
+ 'k3': { inputPer1M: 3.00, outputPer1M: 15.00 },
122
+ 'k3-256k': { inputPer1M: 3.00, outputPer1M: 15.00 },
123
+ // Grok (xAI) — base-tier rates. xAI doubles Grok 4.5/4.6 at prompts ≥200K;
124
+ // this table stores one flat rate per model, so the base tier is what we show.
125
+ 'grok-4.6': { inputPer1M: 2.00, outputPer1M: 6.00 },
110
126
  'grok-4.5': { inputPer1M: 2.00, outputPer1M: 6.00 },
111
127
  'grok-build-0.1': { inputPer1M: 1.00, outputPer1M: 2.00 },
112
128
  'grok-4.3': { inputPer1M: 1.25, outputPer1M: 2.50 },
113
129
  'grok-code-fast-1': { inputPer1M: 0.20, outputPer1M: 1.50 },
114
130
  'grok-4-fast-reasoning': { inputPer1M: 0.20, outputPer1M: 0.50 },
115
- // Qwen (Alibaba) — qwen3-coder-* 0–256K tier; the Coding Plan is flat-fee so
116
- // this only affects the pay-per-use estimate.
117
- 'qwen3-coder-plus': { inputPer1M: 0.28, outputPer1M: 1.65 },
118
- 'qwen3-coder-next': { inputPer1M: 0.28, outputPer1M: 1.65 },
119
- 'qwen3-coder-flash': { inputPer1M: 0.10, outputPer1M: 0.50 },
131
+ // Qwen (Alibaba) — list prices for the first context tier. Coding Plan
132
+ // variants are flat-fee; these rates describe pay-per-use calls.
133
+ // `qwen3.8-max-preview` is Token-Plan-only (credit-metered, promotional
134
+ // preview rate); Alibaba publishes no pay-per-use per-token price for it.
135
+ // Leave it unpriced rather than borrowing the GA qwen3.8-max rate.
120
136
  'qwen3.7-max': { inputPer1M: 2.50, outputPer1M: 7.50 },
137
+ 'qwen3.7-plus': { inputPer1M: 0.40, outputPer1M: 1.60 },
138
+ 'qwen3.6-plus': { inputPer1M: 0.40, outputPer1M: 2.40 },
139
+ 'qwen3.5-plus': { inputPer1M: 0.40, outputPer1M: 2.40 },
140
+ 'qwen3.6-flash': { inputPer1M: 0.25, outputPer1M: 1.50 },
121
141
  // ModelScope free tier — no per-token charge.
122
142
  'Qwen/Qwen3-Coder-480B-A35B-Instruct': { inputPer1M: 0, outputPer1M: 0 },
123
143
  };
@@ -285,13 +305,20 @@ export function getSessionStats() {
285
305
  totalCacheCreationTokens += record.cacheCreationTokens ?? 0;
286
306
  totalCacheReadTokens += record.cacheReadTokens ?? 0;
287
307
  }
288
- const estimatedCost = getCostBreakdown().reduce((s, b) => s + b.estimatedCost, 0);
308
+ const breakdown = getCostBreakdown();
309
+ const estimatedCost = breakdown.reduce((s, b) => s + b.estimatedCost, 0);
310
+ const billableCost = breakdown
311
+ .filter(b => !isFlatFeeProvider(b.provider))
312
+ .reduce((s, b) => s + b.estimatedCost, 0);
313
+ const hasFlatFeeUsage = breakdown.some(b => isFlatFeeProvider(b.provider));
289
314
  return {
290
315
  totalPromptTokens,
291
316
  totalCompletionTokens,
292
317
  totalTokens,
293
318
  requestCount: currentRecords().length,
294
319
  estimatedCost,
320
+ billableCost,
321
+ hasFlatFeeUsage,
295
322
  totalCacheCreationTokens,
296
323
  totalCacheReadTokens,
297
324
  };
@@ -342,18 +369,26 @@ export function formatCostReport() {
342
369
  return '_No API requests in this session yet._';
343
370
  }
344
371
  const breakdown = getCostBreakdown();
372
+ // Flat-fee providers (subscriptions / free tiers) bill nothing per token, so
373
+ // their notional cost is never shown and never folded into the total. A
374
+ // session can mix them with pay-per-use models, so decide per entry.
375
+ const planEntries = breakdown.filter(b => isFlatFeeProvider(b.provider));
376
+ const costLine = planEntries.length === breakdown.length
377
+ ? '**Estimated cost:** included in plan'
378
+ : `**Estimated cost:** $${stats.billableCost.toFixed(4)}${planEntries.length > 0 ? ' + usage included in plan' : ''}`;
345
379
  const lines = [
346
380
  '## Session Cost',
347
381
  '',
348
382
  `**Requests:** ${stats.requestCount} · **Input:** ${formatTokenCount(stats.totalPromptTokens)} · **Output:** ${formatTokenCount(stats.totalCompletionTokens)} · **Total:** ${formatTokenCount(stats.totalTokens)}`,
349
- `**Estimated cost:** $${stats.estimatedCost.toFixed(4)}`,
383
+ costLine,
350
384
  '',
351
385
  ];
352
- if (breakdown.length > 1 || (breakdown.length === 1 && breakdown[0].estimatedCost > 0)) {
386
+ if (breakdown.length > 1 || (breakdown.length === 1 && (breakdown[0].estimatedCost > 0 || planEntries.length > 0))) {
353
387
  lines.push('| Provider / Model | Input | Output | Cost |');
354
388
  lines.push('|---|---:|---:|---:|');
355
389
  for (const b of breakdown) {
356
- lines.push(`| \`${b.provider}\` / \`${b.model}\` | ${formatTokenCount(b.promptTokens)} | ${formatTokenCount(b.completionTokens)} | $${b.estimatedCost.toFixed(4)} |`);
390
+ const cost = isFlatFeeProvider(b.provider) ? 'included in plan' : `$${b.estimatedCost.toFixed(4)}`;
391
+ lines.push(`| \`${b.provider}\` / \`${b.model}\` | ${formatTokenCount(b.promptTokens)} | ${formatTokenCount(b.completionTokens)} | ${cost} |`);
357
392
  }
358
393
  }
359
394
  // Prompt caching summary — only shown if at least one cached call landed.
@@ -368,9 +403,10 @@ export function formatCostReport() {
368
403
  lines.push(`**Estimated savings vs no caching:** $${cache.estimatedSavingsUsd.toFixed(4)}`);
369
404
  }
370
405
  }
406
+ lines.push('', ...formatResourceImpactReport(stats.totalTokens));
371
407
  // Models with no pricing entry don't contribute to cost — flag so users
372
408
  // aren't surprised the total looks low.
373
- const untracked = breakdown.filter(b => b.estimatedCost === 0 && (b.promptTokens + b.completionTokens) > 0);
409
+ const untracked = breakdown.filter(b => b.estimatedCost === 0 && (b.promptTokens + b.completionTokens) > 0 && !isFlatFeeProvider(b.provider));
374
410
  if (untracked.length > 0) {
375
411
  lines.push('', `_Note: ${untracked.length} model${untracked.length === 1 ? '' : 's'} (${untracked.map(u => `\`${u.model}\``).join(', ')}) have no pricing entry — token counts are tracked but not priced._`);
376
412
  }
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "2.16.0";
1
+ export declare const VERSION = "2.18.0";
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // AUTO-GENERATED by scripts/gen-version.js — do not edit by hand.
2
2
  // Baked from package.json at build time so the bun-compiled binary reports
3
3
  // the right version (it has no package.json on disk to read at runtime).
4
- export const VERSION = '2.16.0';
4
+ export const VERSION = '2.18.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "2.16.0",
3
+ "version": "2.18.0",
4
4
  "description": "AI-powered coding assistant built for the terminal. Multiple LLM providers, project-aware context, and a seamless development workflow.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,6 +15,7 @@
15
15
  "test": "vitest run",
16
16
  "test:watch": "vitest",
17
17
  "test:coverage": "vitest run --coverage",
18
+ "version": "node scripts/gen-version.js && git add src/version.ts",
18
19
  "release": "node scripts/release.js"
19
20
  },
20
21
  "repository": {