claudish 7.18.1 → 7.19.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.
Files changed (2) hide show
  1. package/dist/index.js +89 -23
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -651,7 +651,7 @@ var init_onepassword_config = __esm(() => {
651
651
  });
652
652
 
653
653
  // src/version.ts
654
- var VERSION = "7.18.1";
654
+ var VERSION = "7.19.1";
655
655
 
656
656
  // src/logger.ts
657
657
  var exports_logger = {};
@@ -27650,6 +27650,9 @@ function loadConfig() {
27650
27650
  if (config2.onepasswordEnvironments !== undefined) {
27651
27651
  merged.onepasswordEnvironments = config2.onepasswordEnvironments;
27652
27652
  }
27653
+ if (config2.anthropicApiBilling !== undefined) {
27654
+ merged.anthropicApiBilling = config2.anthropicApiBilling;
27655
+ }
27653
27656
  if (config2.localProviders !== undefined) {
27654
27657
  merged.localProviders = Array.from(new Set(config2.localProviders)).sort();
27655
27658
  }
@@ -31742,6 +31745,14 @@ var init_web_search_detector = __esm(() => {
31742
31745
  WEB_SEARCH_NAMES = new Set(["web_search", "brave_web_search", "tavily_search"]);
31743
31746
  });
31744
31747
 
31748
+ // src/handlers/shared/stream-parsers/message-start-usage.ts
31749
+ function messageStartUsage(priorInputTokens) {
31750
+ return {
31751
+ input_tokens: priorInputTokens && priorInputTokens > 0 ? priorInputTokens : 100,
31752
+ output_tokens: 1
31753
+ };
31754
+ }
31755
+
31745
31756
  // src/handlers/shared/stream-parsers/openai-sse.ts
31746
31757
  function validateToolArguments(toolName, argsStr, toolSchemas, textContent) {
31747
31758
  const result = validateAndRepairToolCall(toolName, argsStr, toolSchemas, textContent);
@@ -31771,7 +31782,7 @@ function createStreamingState() {
31771
31782
  accumulatedText: ""
31772
31783
  };
31773
31784
  }
31774
- function createStreamingResponseHandler(c, response, adapter, target, middlewareManager, onTokenUpdate, toolSchemas, toolNameMap) {
31785
+ function createStreamingResponseHandler(c, response, adapter, target, middlewareManager, onTokenUpdate, toolSchemas, toolNameMap, priorInputTokens) {
31775
31786
  log(`[Streaming] ===== HANDLER STARTED for ${target} =====`);
31776
31787
  let isClosed = false;
31777
31788
  let ping = null;
@@ -31800,7 +31811,7 @@ data: ${JSON.stringify(d)}
31800
31811
  model: target,
31801
31812
  stop_reason: null,
31802
31813
  stop_sequence: null,
31803
- usage: { input_tokens: 100, output_tokens: 1 }
31814
+ usage: messageStartUsage(priorInputTokens)
31804
31815
  }
31805
31816
  });
31806
31817
  send("ping", { type: "ping" });
@@ -31913,7 +31924,10 @@ data: ${JSON.stringify(d)}
31913
31924
  send("message_delta", {
31914
31925
  type: "message_delta",
31915
31926
  delta: { stop_reason: stopReason, stop_sequence: null },
31916
- usage: { output_tokens: state.usage?.completion_tokens || 0 }
31927
+ usage: {
31928
+ ...state.usage?.prompt_tokens ? { input_tokens: state.usage.prompt_tokens } : {},
31929
+ output_tokens: state.usage?.completion_tokens || 0
31930
+ }
31917
31931
  });
31918
31932
  send("message_stop", { type: "message_stop" });
31919
31933
  }
@@ -31924,7 +31938,7 @@ data: ${JSON.stringify(d)}
31924
31938
  } else {
31925
31939
  const estimatedOutputTokens = Math.ceil(state.accumulatedText.length / 4);
31926
31940
  log(`[Streaming] No usage data from provider, estimating: ~${estimatedOutputTokens} output tokens`);
31927
- onTokenUpdate(100, estimatedOutputTokens);
31941
+ onTokenUpdate(priorInputTokens || 100, estimatedOutputTokens);
31928
31942
  }
31929
31943
  }
31930
31944
  if (!isClosed) {
@@ -37542,7 +37556,7 @@ data: ${JSON.stringify(data)}
37542
37556
  model: opts.modelName,
37543
37557
  stop_reason: null,
37544
37558
  stop_sequence: null,
37545
- usage: { input_tokens: 100, output_tokens: 1 }
37559
+ usage: messageStartUsage(opts.priorInputTokens)
37546
37560
  }
37547
37561
  });
37548
37562
  send("ping", { type: "ping" });
@@ -37586,7 +37600,10 @@ data: ${JSON.stringify(data)}
37586
37600
  send("message_delta", {
37587
37601
  type: "message_delta",
37588
37602
  delta: { stop_reason: hasToolCalls ? "tool_use" : "end_turn", stop_sequence: null },
37589
- usage: { output_tokens: outputTokens }
37603
+ usage: {
37604
+ ...inputTokens > 0 ? { input_tokens: inputTokens } : {},
37605
+ output_tokens: outputTokens
37606
+ }
37590
37607
  });
37591
37608
  send("message_stop", { type: "message_stop" });
37592
37609
  }
@@ -37789,7 +37806,7 @@ data: ${JSON.stringify(data)}
37789
37806
  model: opts.modelName,
37790
37807
  stop_reason: null,
37791
37808
  stop_sequence: null,
37792
- usage: { input_tokens: 100, output_tokens: 1 }
37809
+ usage: messageStartUsage(opts.priorInputTokens)
37793
37810
  }
37794
37811
  });
37795
37812
  send("ping", { type: "ping" });
@@ -37810,7 +37827,10 @@ data: ${JSON.stringify(data)}
37810
37827
  send("message_delta", {
37811
37828
  type: "message_delta",
37812
37829
  delta: { stop_reason: "end_turn", stop_sequence: null },
37813
- usage: { output_tokens: completionTokens }
37830
+ usage: {
37831
+ ...promptTokens > 0 ? { input_tokens: promptTokens } : {},
37832
+ output_tokens: completionTokens
37833
+ }
37814
37834
  });
37815
37835
  send("message_stop", { type: "message_stop" });
37816
37836
  }
@@ -37962,7 +37982,7 @@ data: ${JSON.stringify(data)}
37962
37982
  model: opts.modelName,
37963
37983
  stop_reason: null,
37964
37984
  stop_sequence: null,
37965
- usage: { input_tokens: 100, output_tokens: 1 }
37985
+ usage: messageStartUsage(opts.priorInputTokens)
37966
37986
  }
37967
37987
  });
37968
37988
  send("ping", { type: "ping" });
@@ -38252,6 +38272,7 @@ class TokenTracker {
38252
38272
  sessionTotalCost = 0;
38253
38273
  sessionInputTokens = 0;
38254
38274
  sessionOutputTokens = 0;
38275
+ lastInputTokens = 0;
38255
38276
  modelNameOverride;
38256
38277
  quotaRemaining;
38257
38278
  constructor(port, config2) {
@@ -38268,10 +38289,11 @@ class TokenTracker {
38268
38289
  this.quotaRemaining = fraction;
38269
38290
  }
38270
38291
  rewrite() {
38271
- this.writeFile(this.sessionInputTokens, this.sessionOutputTokens);
38292
+ this.writeFile(this.getLastInputTokens(), this.sessionOutputTokens);
38272
38293
  }
38273
38294
  update(inputTokens, outputTokens) {
38274
38295
  this.sessionInputTokens = inputTokens;
38296
+ this.lastInputTokens = inputTokens;
38275
38297
  this.sessionOutputTokens += outputTokens;
38276
38298
  const pricing = this.getPricing();
38277
38299
  const cost = inputTokens / 1e6 * pricing.inputCostPer1M + outputTokens / 1e6 * pricing.outputCostPer1M;
@@ -38280,6 +38302,7 @@ class TokenTracker {
38280
38302
  }
38281
38303
  accumulateBoth(inputTokens, outputTokens) {
38282
38304
  this.sessionInputTokens += inputTokens;
38305
+ this.lastInputTokens = this.sessionInputTokens;
38283
38306
  this.sessionOutputTokens += outputTokens;
38284
38307
  const pricing = this.getPricing();
38285
38308
  const cost = this.sessionInputTokens / 1e6 * pricing.inputCostPer1M + this.sessionOutputTokens / 1e6 * pricing.outputCostPer1M;
@@ -38288,6 +38311,7 @@ class TokenTracker {
38288
38311
  }
38289
38312
  updateWithDelta(inputTokens, outputTokens) {
38290
38313
  let incrementalInputTokens;
38314
+ this.lastInputTokens = inputTokens;
38291
38315
  if (inputTokens >= this.sessionInputTokens) {
38292
38316
  incrementalInputTokens = inputTokens - this.sessionInputTokens;
38293
38317
  this.sessionInputTokens = inputTokens;
@@ -38303,10 +38327,11 @@ class TokenTracker {
38303
38327
  const pricing = this.getPricing();
38304
38328
  const cost = incrementalInputTokens / 1e6 * pricing.inputCostPer1M + outputTokens / 1e6 * pricing.outputCostPer1M;
38305
38329
  this.sessionTotalCost += cost;
38306
- this.writeFile(Math.max(inputTokens, this.sessionInputTokens), this.sessionOutputTokens, pricing.isEstimate);
38330
+ this.writeFile(inputTokens, this.sessionOutputTokens, pricing.isEstimate);
38307
38331
  }
38308
38332
  updateWithActualCost(inputTokens, outputTokens, actualCost) {
38309
38333
  this.sessionInputTokens = inputTokens;
38334
+ this.lastInputTokens = inputTokens;
38310
38335
  this.sessionOutputTokens += outputTokens;
38311
38336
  if (typeof actualCost === "number" && actualCost > 0) {
38312
38337
  this.sessionTotalCost += actualCost;
@@ -38322,6 +38347,7 @@ class TokenTracker {
38322
38347
  updateLocal(inputTokens, outputTokens) {
38323
38348
  if (inputTokens > 0) {
38324
38349
  this.sessionInputTokens = inputTokens;
38350
+ this.lastInputTokens = inputTokens;
38325
38351
  }
38326
38352
  this.sessionOutputTokens += outputTokens;
38327
38353
  this.writeFile(this.sessionInputTokens, this.sessionOutputTokens);
@@ -38335,6 +38361,9 @@ class TokenTracker {
38335
38361
  getInputTokens() {
38336
38362
  return this.sessionInputTokens;
38337
38363
  }
38364
+ getLastInputTokens() {
38365
+ return this.lastInputTokens || this.sessionInputTokens;
38366
+ }
38338
38367
  getOutputTokens() {
38339
38368
  return this.sessionOutputTokens;
38340
38369
  }
@@ -38876,16 +38905,18 @@ class ComposedHandler {
38876
38905
  }
38877
38906
  };
38878
38907
  const streamFormat = this.provider.overrideStreamFormat?.() ?? this.explicitAdapter?.getStreamFormat() ?? this.modelAdapter?.getStreamFormat() ?? this.getAdapter().getStreamFormat();
38908
+ const priorInputTokens = this.tokenTracker.getLastInputTokens();
38879
38909
  switch (streamFormat) {
38880
38910
  case "openai-sse":
38881
- return createStreamingResponseHandler(c, response, adapter, this.bareModelName, this.middlewareManager, onTokenUpdate, claudeRequest.tools, toolNameMap);
38911
+ return createStreamingResponseHandler(c, response, adapter, this.bareModelName, this.middlewareManager, onTokenUpdate, claudeRequest.tools, toolNameMap, priorInputTokens);
38882
38912
  case "openai-responses-sse":
38883
38913
  return createResponsesStreamHandler(c, response, {
38884
38914
  modelName: this.bareModelName,
38885
38915
  onTokenUpdate,
38886
38916
  toolNameMap: adapter.getToolNameMap(),
38887
38917
  contextWindow: lookupModelForProvider(this.bareModelName, this.provider.name),
38888
- onApiError
38918
+ onApiError,
38919
+ priorInputTokens
38889
38920
  });
38890
38921
  case "anthropic-sse":
38891
38922
  return createAnthropicPassthroughStream(c, response, {
@@ -38905,13 +38936,15 @@ class ComposedHandler {
38905
38936
  middlewareManager: this.middlewareManager,
38906
38937
  onTokenUpdate,
38907
38938
  onToolCall,
38908
- unwrapResponse: this.options.unwrapGeminiResponse
38939
+ unwrapResponse: this.options.unwrapGeminiResponse,
38940
+ priorInputTokens
38909
38941
  });
38910
38942
  }
38911
38943
  case "ollama-jsonl":
38912
38944
  return createOllamaJsonlStream(c, response, {
38913
38945
  modelName: this.bareModelName,
38914
- onTokenUpdate
38946
+ onTokenUpdate,
38947
+ priorInputTokens
38915
38948
  });
38916
38949
  default:
38917
38950
  throw new Error(`Unknown stream format: ${streamFormat}`);
@@ -58386,7 +58419,8 @@ var init_config = __esm(() => {
58386
58419
  OPENAI_BASE_URL: "OPENAI_BASE_URL",
58387
58420
  CLAUDISH_SUMMARIZE_TOOLS: "CLAUDISH_SUMMARIZE_TOOLS",
58388
58421
  CLAUDISH_DIAG_MODE: "CLAUDISH_DIAG_MODE",
58389
- CLAUDISH_DEBUG: "CLAUDISH_DEBUG"
58422
+ CLAUDISH_DEBUG: "CLAUDISH_DEBUG",
58423
+ CLAUDISH_ANTHROPIC_API_BILLING: "CLAUDISH_ANTHROPIC_API_BILLING"
58390
58424
  };
58391
58425
  OPENROUTER_HEADERS = {
58392
58426
  "HTTP-Referer": "https://claudish.com",
@@ -62343,6 +62377,8 @@ async function parseArgs(args) {
62343
62377
  process.exit(1);
62344
62378
  }
62345
62379
  config3.defaultProvider = dpArg;
62380
+ } else if (arg === "--anthropic-api-billing") {
62381
+ config3.anthropicApiBilling = true;
62346
62382
  } else if (arg === "--op-env" || arg.startsWith("--op-env=")) {
62347
62383
  const v = arg.startsWith("--op-env=") ? arg.slice("--op-env=".length) : args[++i];
62348
62384
  if (!v) {
@@ -63392,6 +63428,10 @@ ${h("OPTIONS")}
63392
63428
  ${green("--profile")} ${yellow("<name>")} Use named profile for model mapping (default profile if omitted)
63393
63429
  ${green("--default-provider")} ${yellow("<name>")} Fallback provider for bare model names (builtin or customEndpoints key)
63394
63430
  ${dim("Precedence: this flag > CLAUDISH_DEFAULT_PROVIDER env > config.json")}
63431
+ ${green("--anthropic-api-billing")} Use your real ANTHROPIC_API_KEY for native Claude models
63432
+ ${dim("(metered API billing). Default: the key is hidden so Claude Code")}
63433
+ ${dim("uses your claude.ai subscription. Env: CLAUDISH_ANTHROPIC_API_BILLING")}
63434
+ ${dim("Config: anthropicApiBilling: true")}
63395
63435
  ${green("--config")} ${yellow("<file>")} Use THIS config file for the run, fully replacing the machine
63396
63436
  ${dim("global (~/.claudish/config.json) AND project (.claudish.json).")}
63397
63437
  ${dim("A file naming no op:// source never touches 1Password (no prompt).")}
@@ -63567,6 +63607,7 @@ ${h("ENVIRONMENT VARIABLES")}
63567
63607
  ${blue("CLAUDISH_CONTEXT_WINDOW")} Override context window size
63568
63608
  ${blue("CLAUDISH_DIAG_MODE")} Diagnostic output: auto / logfile / off
63569
63609
  ${blue("CLAUDISH_DEBUG")} Always enable debug logging: 1 / true ${dim("(same as -d)")}
63610
+ ${blue("CLAUDISH_ANTHROPIC_API_BILLING")} Bill native Claude to your API key ${dim("(see --anthropic-api-billing)")}
63570
63611
  ${blue("CLAUDISH_MCP_TOOLS")} MCP tool gating: all / low-level / agentic / channel
63571
63612
  ${blue("CLAUDISH_MODEL_OPUS")} Override model for Opus role
63572
63613
  ${blue("CLAUDISH_MODEL_SONNET")} Override model for Sonnet role
@@ -71136,7 +71177,8 @@ __export(exports_claude_runner, {
71136
71177
  isProxyAuthMode: () => isProxyAuthMode,
71137
71178
  computeMainThreadContextWindow: () => computeMainThreadContextWindow,
71138
71179
  checkClaudeInstalled: () => checkClaudeInstalled,
71139
- buildClaudishSettingsOverlay: () => buildClaudishSettingsOverlay
71180
+ buildClaudishSettingsOverlay: () => buildClaudishSettingsOverlay,
71181
+ MIN_AUTO_COMPACT_WINDOW: () => MIN_AUTO_COMPACT_WINDOW
71140
71182
  });
71141
71183
  import { spawn as spawn4 } from "child_process";
71142
71184
  import {
@@ -71167,6 +71209,18 @@ function hasNativeAnthropicMapping(config3) {
71167
71209
  ];
71168
71210
  return models.some((m) => m && parseModelSpec(m).provider === "native-anthropic");
71169
71211
  }
71212
+ function wantsAnthropicApiBilling(config3) {
71213
+ if (config3.anthropicApiBilling)
71214
+ return true;
71215
+ const raw2 = process.env[ENV.CLAUDISH_ANTHROPIC_API_BILLING];
71216
+ if (raw2 !== undefined && raw2 !== "" && raw2 !== "0" && raw2.toLowerCase() !== "false")
71217
+ return true;
71218
+ try {
71219
+ return loadConfig().anthropicApiBilling === true;
71220
+ } catch {
71221
+ return false;
71222
+ }
71223
+ }
71170
71224
  function isProxyAuthMode(config3) {
71171
71225
  return !config3.monitor && !hasNativeAnthropicMapping(config3);
71172
71226
  }
@@ -71430,6 +71484,7 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
71430
71484
  [ENV.CLAUDISH_ACTIVE_MODEL_NAME]: modelDisplayName,
71431
71485
  CLAUDISH_IS_LOCAL: isLocalModel2 ? "true" : "false"
71432
71486
  };
71487
+ let hidAnthropicApiKey = false;
71433
71488
  delete env.CLAUDECODE;
71434
71489
  if (config3.monitor) {
71435
71490
  delete env.ANTHROPIC_API_KEY;
@@ -71443,16 +71498,23 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
71443
71498
  env[ENV.ANTHROPIC_MODEL] = modelId;
71444
71499
  env[ENV.ANTHROPIC_SMALL_FAST_MODEL] = modelId;
71445
71500
  }
71446
- if (hasNativeAnthropicMapping(config3)) {} else {
71447
- env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx";
71448
- env.ANTHROPIC_AUTH_TOKEN = process.env.ANTHROPIC_AUTH_TOKEN || "placeholder-token-not-used-proxy-handles-auth";
71501
+ if (hasNativeAnthropicMapping(config3)) {
71502
+ if (process.env.ANTHROPIC_API_KEY && !wantsAnthropicApiBilling(config3)) {
71503
+ delete env.ANTHROPIC_API_KEY;
71504
+ hidAnthropicApiKey = true;
71505
+ }
71506
+ } else {
71507
+ env.ANTHROPIC_API_KEY = "sk-ant-api03-placeholder-not-used-proxy-handles-auth-with-openrouter-key-xxxxxxxxxxxxxxxxxxxxx";
71508
+ env.ANTHROPIC_AUTH_TOKEN = "placeholder-token-not-used-proxy-handles-auth";
71449
71509
  if (!process.env[ENV.CLAUDE_CODE_AUTO_COMPACT_WINDOW]) {
71450
71510
  const autoCompactWindow = await computeMainThreadContextWindow(config3);
71451
- if (autoCompactWindow > 0) {
71511
+ if (autoCompactWindow >= MIN_AUTO_COMPACT_WINDOW) {
71452
71512
  env[ENV.CLAUDE_CODE_AUTO_COMPACT_WINDOW] = String(autoCompactWindow);
71453
71513
  if (!config3.quiet) {
71454
71514
  console.error(`[claudish] Auto-compact window: ${autoCompactWindow.toLocaleString()} tokens ` + "(Claude Code compacts before the backend's real limit)");
71455
71515
  }
71516
+ } else if (autoCompactWindow > 0 && !config3.quiet) {
71517
+ console.error(`[claudish] Model's real context window (${autoCompactWindow.toLocaleString()}) is below ` + `Claude Code's ${MIN_AUTO_COMPACT_WINDOW.toLocaleString()}-token auto-compact floor \u2014 ` + "leaving CLAUDE_CODE_AUTO_COMPACT_WINDOW unset so native auto-compaction stays on.");
71456
71518
  }
71457
71519
  }
71458
71520
  }
@@ -71468,6 +71530,9 @@ async function runClaudeWithProxy(config3, proxyUrl, onCleanup) {
71468
71530
  };
71469
71531
  if (!config3.monitor && hasNativeAnthropicMapping(config3)) {
71470
71532
  log2("[claudish] Native Claude model detected \u2014 using Claude Code subscription credentials");
71533
+ if (hidAnthropicApiKey) {
71534
+ log2("[claudish] ANTHROPIC_API_KEY found but hidden so it can't override that subscription \xB7 " + "use --anthropic-api-billing (or anthropicApiBilling: true) to bill the API instead");
71535
+ }
71471
71536
  }
71472
71537
  if (config3.interactive) {
71473
71538
  log2(`
@@ -71634,11 +71699,12 @@ async function checkClaudeInstalled() {
71634
71699
  const binary = await findClaudeBinary();
71635
71700
  return binary !== null;
71636
71701
  }
71637
- var restoreTerminal = null;
71702
+ var restoreTerminal = null, MIN_AUTO_COMPACT_WINDOW = 200000;
71638
71703
  var init_claude_runner = __esm(() => {
71639
71704
  init_model_catalog();
71640
71705
  init_config();
71641
71706
  init_logger();
71707
+ init_profile_config();
71642
71708
  init_model_parser();
71643
71709
  init_routing_rules();
71644
71710
  init_telemetry();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "7.18.1",
3
+ "version": "7.19.1",
4
4
  "description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -60,10 +60,10 @@
60
60
  "ai"
61
61
  ],
62
62
  "optionalDependencies": {
63
- "@claudish/magmux-darwin-arm64": "7.18.1",
64
- "@claudish/magmux-darwin-x64": "7.18.1",
65
- "@claudish/magmux-linux-arm64": "7.18.1",
66
- "@claudish/magmux-linux-x64": "7.18.1"
63
+ "@claudish/magmux-darwin-arm64": "7.19.1",
64
+ "@claudish/magmux-darwin-x64": "7.19.1",
65
+ "@claudish/magmux-linux-arm64": "7.19.1",
66
+ "@claudish/magmux-linux-x64": "7.19.1"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",