claudish 7.67.0 → 7.67.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 +42 -8
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -731,7 +731,7 @@ var init_onepassword_config = __esm(() => {
731
731
  });
732
732
 
733
733
  // src/version.ts
734
- var VERSION = "7.67.0";
734
+ var VERSION = "7.67.1";
735
735
 
736
736
  // src/logger.ts
737
737
  var exports_logger = {};
@@ -28268,8 +28268,10 @@ function truncateToolName(name, maxLength) {
28268
28268
  log(`[ToolName] Truncated: "${name}" -> "${truncated}" (${name.length} -> ${truncated.length} chars)`);
28269
28269
  return truncated;
28270
28270
  }
28271
+ var TOOL_NAME_SOURCE = "[A-Za-z_][A-Za-z0-9_.-]{0,63}", TOOL_NAME_SHAPE;
28271
28272
  var init_tool_name_utils = __esm(() => {
28272
28273
  init_logger();
28274
+ TOOL_NAME_SHAPE = new RegExp(`^${TOOL_NAME_SOURCE}$`);
28273
28275
  });
28274
28276
 
28275
28277
  // src/handlers/shared/format/openai-messages.ts
@@ -29589,9 +29591,32 @@ function filterIdentity(content) {
29589
29591
  }
29590
29592
 
29591
29593
  // src/handlers/shared/tool-call-recovery.ts
29592
- function extractToolCallsFromText(text) {
29594
+ function hasExtractableFunctionTag(text) {
29595
+ return FUNCTION_TAG_PRESENT.test(text);
29596
+ }
29597
+ function keepOnlyRealTools(extracted, knownToolNames) {
29598
+ const kept = [];
29599
+ for (const call of extracted) {
29600
+ if (!TOOL_NAME_SHAPE.test(call.name)) {
29601
+ log(`[ToolRecovery] Dropped extracted call: name is not an identifier: ${JSON.stringify(call.name.slice(0, 120))}`);
29602
+ continue;
29603
+ }
29604
+ if (!knownToolNames || knownToolNames.length === 0) {
29605
+ kept.push(call);
29606
+ continue;
29607
+ }
29608
+ const canonical = knownToolNames.find((t) => t.toLowerCase() === call.name.toLowerCase());
29609
+ if (!canonical) {
29610
+ log(`[ToolRecovery] Dropped extracted call for unadvertised tool: ${call.name}`);
29611
+ continue;
29612
+ }
29613
+ kept.push(canonical === call.name ? call : { ...call, name: canonical });
29614
+ }
29615
+ return kept;
29616
+ }
29617
+ function extractToolCallsFromText(text, knownToolNames) {
29593
29618
  const extracted = [];
29594
- const qwenPattern = /<function=([^>]+)>([\s\S]*?)(?=<function=|$)/gi;
29619
+ const qwenPattern = new RegExp(FUNCTION_TAG_SOURCE, "gi");
29595
29620
  let match;
29596
29621
  while ((match = qwenPattern.exec(text)) !== null) {
29597
29622
  const funcName = match[1];
@@ -29685,7 +29710,7 @@ function extractToolCallsFromText(text) {
29685
29710
  }
29686
29711
  } catch (e) {}
29687
29712
  }
29688
- const knownTools = [
29713
+ const knownTools = knownToolNames && knownToolNames.length > 0 ? knownToolNames : [
29689
29714
  "Task",
29690
29715
  "Read",
29691
29716
  "Write",
@@ -29793,7 +29818,7 @@ function extractToolCallsFromText(text) {
29793
29818
  }
29794
29819
  }
29795
29820
  }
29796
- return extracted;
29821
+ return keepOnlyRealTools(extracted, knownToolNames);
29797
29822
  }
29798
29823
  function inferMissingParameters(toolName2, args, missingParams, context) {
29799
29824
  const inferred = { ...args };
@@ -29958,8 +29983,12 @@ function validateAndRepairToolCall(toolName2, argsStr, toolSchemas, textContent)
29958
29983
  }
29959
29984
  return { valid: false, args: repairedArgs, repaired: false, missingParams: stillMissing };
29960
29985
  }
29986
+ var FUNCTION_TAG_SOURCE, FUNCTION_TAG_PRESENT;
29961
29987
  var init_tool_call_recovery = __esm(() => {
29988
+ init_tool_name_utils();
29962
29989
  init_logger();
29990
+ FUNCTION_TAG_SOURCE = `<function=(${TOOL_NAME_SOURCE})>([\\s\\S]*?)(?=<function=|$)`;
29991
+ FUNCTION_TAG_PRESENT = new RegExp(`<function=${TOOL_NAME_SOURCE}>`);
29963
29992
  });
29964
29993
 
29965
29994
  // src/handlers/shared/web-search-detector.ts
@@ -30102,7 +30131,10 @@ data: ${JSON.stringify(d)}
30102
30131
  const preview = state.accumulatedText.slice(0, 500).replace(/\n/g, "\\n");
30103
30132
  log(`[Streaming] Accumulated text (${state.accumulatedText.length} chars): ${preview}...`);
30104
30133
  }
30105
- const textToolCalls = extractToolCallsFromText(state.accumulatedText);
30134
+ const textToolCalls = state.tools.size > 0 ? [] : extractToolCallsFromText(state.accumulatedText, toolSchemas?.map((t) => t?.name).filter((n) => !!n));
30135
+ if (state.tools.size > 0 && state.accumulatedText.length > 0) {
30136
+ log(`[Streaming] Skipping text-based tool extraction: ${state.tools.size} structured tool call(s) already present`);
30137
+ }
30106
30138
  log(`[Streaming] Text-based tool calls found: ${textToolCalls.length}`);
30107
30139
  if (textToolCalls.length > 0) {
30108
30140
  log(`[Streaming] Found ${textToolCalls.length} text-based tool call(s), converting to structured format`);
@@ -30309,7 +30341,7 @@ data: ${JSON.stringify(d)}
30309
30341
  }
30310
30342
  if (res.cleanedText) {
30311
30343
  state.accumulatedText += res.cleanedText;
30312
- const hasStructuredToolPattern = /<function=[^>]+>/.test(state.accumulatedText) || /\{\s*"(?:name|tool)"\s*:\s*"(?:Task|Read|Write|Edit|Bash|Grep|Glob)"/i.test(state.accumulatedText) || /<tool_call>/.test(state.accumulatedText);
30344
+ const hasStructuredToolPattern = hasExtractableFunctionTag(state.accumulatedText) || /\{\s*"(?:name|tool)"\s*:\s*"(?:Task|Read|Write|Edit|Bash|Grep|Glob)"/i.test(state.accumulatedText) || /<tool_call>/.test(state.accumulatedText);
30313
30345
  const shouldHoldBack = hasStructuredToolPattern && state.accumulatedText.length < 1000;
30314
30346
  if (shouldHoldBack) {
30315
30347
  log(`[Streaming] Text held back (structured tool pattern): ${state.accumulatedText.length} chars accumulated`);
@@ -43030,7 +43062,8 @@ class TokenTracker {
43030
43062
  this.config = config2;
43031
43063
  }
43032
43064
  recordToolUse(name) {
43033
- const key = name.trim() || "unknown";
43065
+ const trimmed2 = name.trim();
43066
+ const key = !trimmed2 ? "unknown" : TOOL_NAME_SHAPE.test(trimmed2) ? trimmed2 : "malformed";
43034
43067
  this.toolCallsByName.set(key, (this.toolCallsByName.get(key) ?? 0) + 1);
43035
43068
  }
43036
43069
  getToolCallCount() {
@@ -43203,6 +43236,7 @@ class TokenTracker {
43203
43236
  }
43204
43237
  }
43205
43238
  var init_token_tracker = __esm(() => {
43239
+ init_tool_name_utils();
43206
43240
  init_types2();
43207
43241
  init_logger();
43208
43242
  init_remote_provider_types();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "7.67.0",
3
+ "version": "7.67.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.67.0",
64
- "@claudish/magmux-darwin-x64": "7.67.0",
65
- "@claudish/magmux-linux-arm64": "7.67.0",
66
- "@claudish/magmux-linux-x64": "7.67.0"
63
+ "@claudish/magmux-darwin-arm64": "7.67.1",
64
+ "@claudish/magmux-darwin-x64": "7.67.1",
65
+ "@claudish/magmux-linux-arm64": "7.67.1",
66
+ "@claudish/magmux-linux-x64": "7.67.1"
67
67
  },
68
68
  "author": "Jack Rudenko <i@madappgang.com>",
69
69
  "license": "MIT",