@kernel.chat/kbot 3.99.11 → 3.99.13

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/agent.js +31 -3
  2. package/package.json +1 -1
package/dist/agent.js CHANGED
@@ -327,6 +327,21 @@ function tryParseInlineToolCalls(content, knownTools) {
327
327
  if (parsed)
328
328
  calls.push(parsed);
329
329
  }
330
+ if (calls.length > 0)
331
+ return calls;
332
+ // Pattern 3b: ANY fenced code block whose first line starts with a known tool name.
333
+ // Catches ```bash\nread_file "path.json"\n``` and ```\nread_file path.ts\n```,
334
+ // which small local models like gemma4 emit when asked to use tools.
335
+ const anyBlockPattern = /```(?:[a-z_]+)?\s*\n([\s\S]*?)```/g;
336
+ while ((match = anyBlockPattern.exec(content)) !== null) {
337
+ const block = match[1].trim();
338
+ const firstWord = block.split(/\s/)[0];
339
+ if (firstWord && knownTools.includes(firstWord)) {
340
+ const parsed = parseToolCodeBlock(block, knownTools);
341
+ if (parsed)
342
+ calls.push(parsed);
343
+ }
344
+ }
330
345
  if (calls.length > 0)
331
346
  return calls;
332
347
  // Pattern 4: Natural language tool invocations — "I'll use write_file to create..."
@@ -370,14 +385,22 @@ function parseToolCodeBlock(block, knownTools) {
370
385
  }
371
386
  return null;
372
387
  }
388
+ /** Strip surrounding quotes from a CLI-style argument string */
389
+ function unquote(s) {
390
+ const t = s.trim();
391
+ if ((t.startsWith('"') && t.endsWith('"')) || (t.startsWith("'") && t.endsWith("'"))) {
392
+ return t.slice(1, -1);
393
+ }
394
+ return t;
395
+ }
373
396
  /** Build structured args from a tool_code invocation */
374
397
  function buildArgsFromToolCode(tool, argStr, restContent) {
375
398
  switch (tool) {
376
399
  case 'read_file':
377
400
  case 'list_directory':
378
- return { path: argStr || '.' };
401
+ return { path: unquote(argStr) || '.' };
379
402
  case 'write_file':
380
- return { path: argStr, content: restContent };
403
+ return { path: unquote(argStr), content: restContent };
381
404
  case 'bash':
382
405
  return { command: argStr || restContent };
383
406
  case 'grep':
@@ -619,7 +642,12 @@ function isCasualMessage(message) {
619
642
  ];
620
643
  // If it matches a casual pattern AND doesn't contain action words AND doesn't refer to kbot, it's casual
621
644
  const isCasualPattern = casualPatterns.some(p => p.test(lower));
622
- const hasActionWords = /\b(fix|create|build|run|deploy|install|delete|remove|write|edit|make|generate|scaffold|refactor|update|add|implement|set up|configure|debug|test)\b/.test(lower);
645
+ const hasActionWords = /\b(fix|create|build|run|deploy|install|delete|remove|write|edit|make|generate|scaffold|refactor|update|add|implement|set up|configure|debug|test|read|check|show|list|find|search|view|tell|report|count|inspect|look|get|open|cat|grep|ls|dir|cd|diff|log|commit|push|pull|clone|audit|scan|probe|execute|execute|verify|confirm|validate)\b/.test(lower);
646
+ // Any message referencing a file path (*.json, *.ts, src/, ./, etc.) clearly needs tools — not casual.
647
+ const mentionsFileOrPath = /\b[\w./-]+\.(json|ts|tsx|js|jsx|md|py|rs|go|toml|yaml|yml|sh|html|css|sql)\b/.test(lower)
648
+ || /(?:^|\s)(?:\.\/|src\/|packages\/|tools\/|supabase\/|\.kbot\/|\.claude\/|\/users\/|~\/)/.test(lower);
649
+ if (mentionsFileOrPath)
650
+ return false;
623
651
  if (isCasualPattern && !hasActionWords && !refersToKbot)
624
652
  return true;
625
653
  // Questions that end with ? and don't have action words and don't refer to kbot
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kernel.chat/kbot",
3
- "version": "3.99.11",
3
+ "version": "3.99.13",
4
4
  "description": "Open-source terminal AI agent. 787+ tools, 35 agents, 20 providers. Dreams, learns, watches your system. Controls your phone. Fully local, fully sovereign. MIT.",
5
5
  "type": "module",
6
6
  "repository": {