codeep 3.0.0 → 3.1.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.
@@ -22,6 +22,7 @@ const MODEL_CONTEXT_WINDOWS = {
22
22
  'gpt-5.4': 1_050_000,
23
23
  'gpt-5.4-mini': 400_000,
24
24
  // Anthropic
25
+ 'claude-fable-5-1': 1_000_000,
25
26
  'claude-fable-5': 1_000_000,
26
27
  'claude-opus-5': 1_000_000,
27
28
  'claude-sonnet-4-6': 1_000_000,
@@ -97,10 +98,11 @@ const MODEL_PRICING = {
97
98
  'gpt-5.4': { inputPer1M: 2.50, outputPer1M: 15.00 },
98
99
  'gpt-5.4-mini': { inputPer1M: 0.75, outputPer1M: 4.50 },
99
100
  // Anthropic
101
+ 'claude-fable-5-1': { inputPer1M: 10.00, outputPer1M: 50.00 },
100
102
  'claude-fable-5': { inputPer1M: 10.00, outputPer1M: 50.00 },
101
103
  'claude-opus-5': { inputPer1M: 5.00, outputPer1M: 25.00 },
102
104
  'claude-sonnet-4-6': { inputPer1M: 3.00, outputPer1M: 15.00 },
103
- 'claude-sonnet-5': { inputPer1M: 3.00, outputPer1M: 15.00 },
105
+ 'claude-sonnet-5': { inputPer1M: 2.00, outputPer1M: 10.00 },
104
106
  'claude-haiku-4-5-20251001': { inputPer1M: 1.00, outputPer1M: 5.00 },
105
107
  // DeepSeek (cache-miss input pricing)
106
108
  // DeepSeek moved to peak / off-peak billing on 2026-08-16, with off-peak at
@@ -206,11 +208,18 @@ export function recordTokenUsage(usage, model, provider, actualCostUsd) {
206
208
  */
207
209
  export function extractOpenAIUsage(data) {
208
210
  if (data?.usage) {
209
- // OpenAI-protocol `prompt_tokens` is INCLUSIVE of cached prompt tokens
210
- // (DeepSeek/OpenAI report cache hits in prompt_tokens_details.cached_tokens).
211
+ // OpenAI-protocol `prompt_tokens` is INCLUSIVE of cached prompt tokens.
211
212
  // Surface them so getCostBreakdown bills cache reads at the discounted
212
213
  // rate instead of the full cache-miss input rate.
213
- const cached = data.usage.prompt_tokens_details?.cached_tokens || 0;
214
+ //
215
+ // Two shapes are in the wild. OpenAI, DeepSeek and Qwen's text models nest
216
+ // it under prompt_tokens_details; Kimi returns it at the top level, and
217
+ // Alibaba's own docs say some Qwen models still do and will be migrated
218
+ // later. Reading only the nested form zeroed every Kimi cache hit, so the
219
+ // cached portion of a run billed at the full cache-miss rate — five times
220
+ // what it costs — with nothing anywhere to say so.
221
+ const nested = data.usage.prompt_tokens_details?.cached_tokens;
222
+ const cached = (typeof nested === 'number' ? nested : data.usage.cached_tokens) || 0;
214
223
  return {
215
224
  promptTokens: data.usage.prompt_tokens || 0,
216
225
  completionTokens: data.usage.completion_tokens || 0,
@@ -242,6 +251,36 @@ export function extractAnthropicUsage(data) {
242
251
  }
243
252
  return null;
244
253
  }
254
+ /**
255
+ * What a provider charges to read a cached token, as a fraction of its own
256
+ * cache-miss input rate.
257
+ *
258
+ * 0.1 is Anthropic's ratio and used to be applied to everyone. Kimi lists
259
+ * $0.19 against a $0.95 cache-miss rate, and Alibaba prices Qwen's implicit
260
+ * cache at 20% of input — both 0.2, so every cached token on those two was
261
+ * billed at half what it actually costs.
262
+ */
263
+ /**
264
+ * Models whose cache-read rate is not their provider's usual one.
265
+ *
266
+ * Fable 5.1 reads a cached token at 0.025× the base input price, where every
267
+ * other Anthropic model charges 0.1×. Checked before the provider map, because
268
+ * this is a property of the model and not of the account it runs under.
269
+ */
270
+ const MODEL_CACHE_READ_RATE = {
271
+ 'claude-fable-5-1': 0.025,
272
+ };
273
+ const CACHE_READ_RATE = {
274
+ 'kimi': 0.2,
275
+ 'kimi-api': 0.2,
276
+ 'qwen': 0.2,
277
+ 'qwen-api': 0.2,
278
+ 'qwen-cn': 0.2,
279
+ 'qwen-cn-api': 0.2,
280
+ 'qwen-token-plan': 0.2,
281
+ };
282
+ /** Anthropic's ratio, and the safest guess for a provider we have not priced. */
283
+ const DEFAULT_CACHE_READ_RATE = 0.1;
245
284
  /**
246
285
  * Get cost breakdown grouped by provider/model.
247
286
  *
@@ -269,16 +308,20 @@ export function getCostBreakdown(startIndex = 0) {
269
308
  else {
270
309
  const pricing = MODEL_PRICING[record.model];
271
310
  if (pricing) {
272
- // Anthropic prompt caching: cache_creation_input is billed at 1.25×
273
- // the base input rate, cache_read_input at 0.1×. The remaining
274
- // (uncached) prompt tokens bill at the standard 1.0× rate.
311
+ // Cache writes bill at 1.25× the base input rate (Anthropic's, and the
312
+ // only provider here that charges for them at all); cache reads bill
313
+ // at whatever fraction the provider charges. The remaining (uncached)
314
+ // prompt tokens bill at the standard 1.0× rate.
275
315
  const cacheCreate = record.cacheCreationTokens ?? 0;
276
316
  const cacheRead = record.cacheReadTokens ?? 0;
317
+ const cacheReadRate = MODEL_CACHE_READ_RATE[record.model]
318
+ ?? CACHE_READ_RATE[record.provider?.trim().toLowerCase()]
319
+ ?? DEFAULT_CACHE_READ_RATE;
277
320
  const uncachedPrompt = Math.max(0, record.promptTokens - cacheCreate - cacheRead);
278
321
  existing.estimatedCost +=
279
322
  (uncachedPrompt / 1_000_000) * pricing.inputPer1M
280
323
  + (cacheCreate / 1_000_000) * pricing.inputPer1M * 1.25
281
- + (cacheRead / 1_000_000) * pricing.inputPer1M * 0.1
324
+ + (cacheRead / 1_000_000) * pricing.inputPer1M * cacheReadRate
282
325
  + (record.completionTokens / 1_000_000) * pricing.outputPer1M;
283
326
  }
284
327
  }
@@ -57,7 +57,12 @@ export const AGENT_TOOLS = {
57
57
  },
58
58
  execute_command: {
59
59
  name: 'execute_command',
60
- description: 'Execute a shell command. Use for npm, git, build tools, tests, etc.',
60
+ // Naming a few examples read as an exhaustive list: the agent refused
61
+ // `sleep`, which IS on the allowlist, explaining that its tool was
62
+ // "limited to package managers and version control". It believed the
63
+ // description over its own capability. Say the shape instead, and let
64
+ // the runtime refuse — it already answers with a specific reason.
65
+ description: 'Execute a shell command. A safety allowlist applies and covers far more than build tooling — package managers, git, test runners, and ordinary utilities such as ls, cat, grep, find, echo, date, sleep and curl. Do not assume a command is forbidden: try it, and a refusal will say so.',
61
66
  parameters: {
62
67
  command: { type: 'string', description: 'The command to run (e.g., npm, git, node)', required: true },
63
68
  args: { type: 'array', description: 'Command arguments as array (e.g., ["install", "lodash"])', required: false },
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "3.0.0";
1
+ export declare const VERSION = "3.1.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 = '3.0.0';
4
+ export const VERSION = '3.1.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "3.0.0",
3
+ "version": "3.1.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",