Skip to content

Commit 030b165

Browse files
author
DeepSeek Assistant
committed
Add BareToolCallAdapter for natural tool call format
Supports: code/search {"query": "..."} format (no wrapping tags) - Recognizes tool prefixes: code/, data/, ai/, collaboration/, etc. - Parses JSON parameters after tool name - Fallback key-value extraction if JSON malformed This matches how models naturally output tool calls without explicit tags.
1 parent e4a9c9c commit 030b165

File tree

5 files changed

+88
-5
lines changed

5 files changed

+88
-5
lines changed

src/debug/jtag/generated-command-schemas.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"generated": "2026-02-10T02:14:41.861Z",
2+
"generated": "2026-02-10T02:25:11.954Z",
33
"version": "1.0.0",
44
"commands": [
55
{

src/debug/jtag/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/debug/jtag/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@continuum/jtag",
3-
"version": "1.0.7754",
3+
"version": "1.0.7755",
44
"description": "Global CLI debugging system for any Node.js project. Install once globally, use anywhere: npm install -g @continuum/jtag",
55
"config": {
66
"active_example": "widget-ui",

src/debug/jtag/shared/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
* DO NOT EDIT MANUALLY
44
*/
55

6-
export const VERSION = '1.0.7754';
6+
export const VERSION = '1.0.7755';
77
export const PACKAGE_NAME = '@continuum/jtag';

src/debug/jtag/system/user/server/modules/ToolFormatAdapter.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,88 @@ export class FunctionStyleToolAdapter extends ToolFormatAdapter {
482482
}
483483
}
484484

485+
/**
486+
* Adapter for bare tool call format (no wrapping tags)
487+
* Format: tool_name {"param": "value"} or tool_name {json}
488+
*
489+
* This is what models often produce naturally:
490+
* - code/search {"query": "memory clustering", "path": "./src/"}
491+
* - code/tree {"path": "./workers/"}
492+
*/
493+
export class BareToolCallAdapter extends ToolFormatAdapter {
494+
readonly formatName = 'bare-tool-call';
495+
496+
// Known tool prefixes to identify tool calls
497+
private static TOOL_PREFIXES = [
498+
'code/', 'data/', 'collaboration/', 'ai/', 'voice/', 'search/',
499+
'workspace/', 'file/', 'interface/', 'genome/', 'adapter/',
500+
'persona/', 'runtime/', 'session/', 'user/', 'logs/', 'media/'
501+
];
502+
503+
formatToolsForPrompt(tools: ToolDefinition[]): string {
504+
return ''; // Parsing only
505+
}
506+
507+
formatResultsForContext(results: Array<{ toolName: string; success: boolean; content?: string; error?: string }>): string {
508+
return results.map(r => {
509+
if (r.success && r.content) {
510+
return `Tool ${r.toolName} succeeded:\n${r.content}`;
511+
} else {
512+
return `Tool ${r.toolName} failed: ${r.error || 'Unknown error'}`;
513+
}
514+
}).join('\n\n');
515+
}
516+
517+
matches(text: string): ToolCallMatch[] {
518+
const matches: ToolCallMatch[] = [];
519+
520+
// Pattern: tool/name {json} or tool/name {"key": "value"}
521+
// Must start with known prefix to avoid false positives
522+
const prefixPattern = BareToolCallAdapter.TOOL_PREFIXES.map(p => p.replace('/', '\\/')).join('|');
523+
const regex = new RegExp(`((?:${prefixPattern})[a-zA-Z0-9/_-]+)\\s*(\\{[^{}]*(?:\\{[^{}]*\\}[^{}]*)*\\})`, 'g');
524+
525+
let match: RegExpExecArray | null;
526+
while ((match = regex.exec(text)) !== null) {
527+
matches.push({
528+
fullMatch: match[0],
529+
startIndex: match.index,
530+
endIndex: regex.lastIndex
531+
});
532+
}
533+
534+
return matches;
535+
}
536+
537+
parse(match: ToolCallMatch): ToolCall | null {
538+
// Extract tool name and JSON
539+
const prefixPattern = BareToolCallAdapter.TOOL_PREFIXES.map(p => p.replace('/', '\\/')).join('|');
540+
const parseRegex = new RegExp(`((?:${prefixPattern})[a-zA-Z0-9/_-]+)\\s*(\\{.+\\})`, 's');
541+
const parsed = match.fullMatch.match(parseRegex);
542+
543+
if (!parsed) return null;
544+
545+
const toolName = parsed[1].trim();
546+
const jsonStr = parsed[2].trim();
547+
const parameters: Record<string, string> = {};
548+
549+
try {
550+
const parsedJson = JSON.parse(jsonStr);
551+
for (const [key, value] of Object.entries(parsedJson)) {
552+
parameters[key] = typeof value === 'string' ? value : JSON.stringify(value);
553+
}
554+
} catch {
555+
// Fallback: try to extract key-value pairs
556+
const kvRegex = /"([^"]+)":\s*"([^"]*)"/g;
557+
let kvMatch;
558+
while ((kvMatch = kvRegex.exec(jsonStr)) !== null) {
559+
parameters[kvMatch[1]] = kvMatch[2];
560+
}
561+
}
562+
563+
return { toolName, parameters };
564+
}
565+
}
566+
485567
/**
486568
* Registry of all supported tool format adapters
487569
* Add new adapters here to support additional formats
@@ -492,6 +574,7 @@ export function getToolFormatAdapters(): ToolFormatAdapter[] {
492574
return [
493575
new AnthropicStyleToolAdapter(), // Primary/default format
494576
new FunctionStyleToolAdapter(), // OpenAI/Groq/Together function style
577+
new BareToolCallAdapter(), // Bare tool_name {json} format
495578
new MarkdownToolAdapter(), // Local model backtick format
496579
new OldStyleToolAdapter() // Legacy XML support
497580
];

0 commit comments

Comments
 (0)