From 60f8bbe1b640ee8a1be0b68c5b976b1533c9b9ff Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 20 Jan 2026 01:30:03 +0000 Subject: [PATCH] feat(tools): add getToolExplanation() method with XML examples for LLM tool calling Each tool now provides comprehensive documentation including parameter schemas and concrete XML examples. This helps smaller LLMs understand the exact format required for tool invocation. --- ts/smartagent.tools.base.ts | 15 +-- ts/smartagent.tools.browser.ts | 53 ++++++++++ ts/smartagent.tools.deno.ts | 39 +++++++ ts/smartagent.tools.filesystem.ts | 164 ++++++++++++++++++++++++++++++ ts/smartagent.tools.http.ts | 78 ++++++++++++++ ts/smartagent.tools.json.ts | 31 ++++++ ts/smartagent.tools.shell.ts | 48 +++++++++ 7 files changed, 422 insertions(+), 6 deletions(-) diff --git a/ts/smartagent.tools.base.ts b/ts/smartagent.tools.base.ts index e78e096..690dac7 100644 --- a/ts/smartagent.tools.base.ts +++ b/ts/smartagent.tools.base.ts @@ -35,6 +35,13 @@ export abstract class BaseToolWrapper implements interfaces.IAgentToolWrapper { */ abstract getCallSummary(action: string, params: Record): string; + /** + * Get a comprehensive explanation of this tool for LLM consumption. + * Tools should implement this to provide detailed usage instructions with examples. + * This includes parameter schemas and concrete XML examples. + */ + abstract getToolExplanation(): string; + /** * Validate that an action exists for this tool * @throws Error if the action is not valid @@ -60,14 +67,10 @@ export abstract class BaseToolWrapper implements interfaces.IAgentToolWrapper { /** * Get the full tool description including all actions - * Used for Driver's tool awareness + * Used for Driver's tool awareness - now delegates to getToolExplanation() */ public getFullDescription(): string { - const actionDescriptions = this.actions - .map((a) => ` - ${a.name}: ${a.description}`) - .join('\n'); - - return `${this.name}: ${this.description}\nActions:\n${actionDescriptions}`; + return this.getToolExplanation(); } /** diff --git a/ts/smartagent.tools.browser.ts b/ts/smartagent.tools.browser.ts index f521a70..4b30ebf 100644 --- a/ts/smartagent.tools.browser.ts +++ b/ts/smartagent.tools.browser.ts @@ -176,6 +176,59 @@ export class BrowserTool extends BaseToolWrapper { } } + public getToolExplanation(): string { + return `## Tool: browser +Interact with web pages - take screenshots, generate PDFs, and execute JavaScript on pages. + +### Actions: + +**screenshot** - Take a screenshot of a webpage +Parameters: + - url (required): URL of the page to screenshot + +Example: + + browser + screenshot + {"url": "https://example.com"} + + +**pdf** - Generate a PDF from a webpage +Parameters: + - url (required): URL of the page to convert to PDF + +Example: + + browser + pdf + {"url": "https://example.com/report"} + + +**evaluate** - Execute JavaScript code on a webpage and return the result +Parameters: + - url (required): URL of the page to run the script on + - script (required): JavaScript code to execute (must return a value) + +Example: + + browser + evaluate + {"url": "https://example.com", "script": "document.querySelectorAll('a').length"} + + +**getPageContent** - Get the text content and title of a webpage +Parameters: + - url (required): URL of the page to get content from + +Example: + + browser + getPageContent + {"url": "https://example.com"} + +`; + } + public getCallSummary(action: string, params: Record): string { switch (action) { case 'screenshot': diff --git a/ts/smartagent.tools.deno.ts b/ts/smartagent.tools.deno.ts index 1320fde..c77aae9 100644 --- a/ts/smartagent.tools.deno.ts +++ b/ts/smartagent.tools.deno.ts @@ -164,6 +164,45 @@ export class DenoTool extends BaseToolWrapper { } } + public getToolExplanation(): string { + return `## Tool: deno +Execute TypeScript/JavaScript code in a sandboxed Deno environment with fine-grained permission control. + +### Actions: + +**execute** - Execute TypeScript/JavaScript code and return stdout/stderr +Parameters: + - code (required): TypeScript/JavaScript code to execute + - permissions (optional): Array of Deno permissions to grant. Options: "all", "env", "net", "read", "write", "run", "sys", "ffi", "hrtime". Default: none (fully sandboxed) + +Example - Simple execution: + + deno + execute + {"code": "console.log('Hello from Deno!');"} + + +Example - With network permission: + + deno + execute + {"code": "const resp = await fetch('https://api.example.com/data');\\nconsole.log(await resp.text());", "permissions": ["net"]} + + +**executeWithResult** - Execute code that outputs JSON on the last line of stdout +Parameters: + - code (required): Code that console.logs a JSON value on the final line + - permissions (optional): Array of Deno permissions to grant + +Example: + + deno + executeWithResult + {"code": "const result = { sum: 1 + 2, product: 2 * 3 };\\nconsole.log(JSON.stringify(result));"} + +`; + } + public getCallSummary(action: string, params: Record): string { const code = params.code as string; const permissions = (params.permissions as string[]) || []; diff --git a/ts/smartagent.tools.filesystem.ts b/ts/smartagent.tools.filesystem.ts index 5284a16..27673c1 100644 --- a/ts/smartagent.tools.filesystem.ts +++ b/ts/smartagent.tools.filesystem.ts @@ -666,6 +666,170 @@ export class FilesystemTool extends BaseToolWrapper { } } + public getToolExplanation(): string { + return `## Tool: filesystem +Read, write, list, and delete files and directories. + +### Actions: + +**read** - Read file contents (full or specific line range) +Parameters: + - path (required): Path to the file + - encoding (optional): File encoding - "utf8" (default), "binary", or "base64" + - startLine (optional): First line to read (1-indexed, inclusive) + - endLine (optional): Last line to read (1-indexed, inclusive) + +Example: + + filesystem + read + {"path": "/path/to/file.txt"} + + +Example with line range: + + filesystem + read + {"path": "/path/to/file.txt", "startLine": 10, "endLine": 20} + + +**write** - Write content to a file (creates or overwrites) +Parameters: + - path (required): Absolute path to the file + - content (required): Content to write + - encoding (optional): File encoding - "utf8" (default), "binary", or "base64" + +Example: + + filesystem + write + {"path": "/path/to/output.txt", "content": "Hello, World!"} + + +**list** - List files and directories in a path +Parameters: + - path (required): Directory path to list + - recursive (optional): List recursively (default: false) + - filter (optional): Glob pattern to filter results (e.g., "*.ts") + +Example: + + filesystem + list + {"path": "/path/to/dir", "recursive": true, "filter": "*.ts"} + + +**exists** - Check if a file or directory exists +Parameters: + - path (required): Path to check + +Example: + + filesystem + exists + {"path": "/path/to/check"} + + +**mkdir** - Create a directory +Parameters: + - path (required): Directory path to create + - recursive (optional): Create parent directories if needed (default: true) + +Example: + + filesystem + mkdir + {"path": "/path/to/new/dir"} + + +**delete** - Delete a file or directory +Parameters: + - path (required): Path to delete + - recursive (optional): For directories, delete recursively (default: false) + +Example: + + filesystem + delete + {"path": "/path/to/delete", "recursive": true} + + +**copy** - Copy a file to a new location +Parameters: + - source (required): Source file path + - destination (required): Destination file path + +Example: + + filesystem + copy + {"source": "/path/to/source.txt", "destination": "/path/to/dest.txt"} + + +**move** - Move a file to a new location +Parameters: + - source (required): Source file path + - destination (required): Destination file path + +Example: + + filesystem + move + {"source": "/path/to/old.txt", "destination": "/path/to/new.txt"} + + +**stat** - Get file or directory statistics (size, dates, etc.) +Parameters: + - path (required): Path to get stats for + +Example: + + filesystem + stat + {"path": "/path/to/file.txt"} + + +**append** - Append content to a file +Parameters: + - path (required): Absolute path to the file + - content (required): Content to append + +Example: + + filesystem + append + {"path": "/path/to/log.txt", "content": "New log entry\\n"} + + +**tree** - Show directory structure as a tree +Parameters: + - path (required): Root directory path + - maxDepth (optional): Maximum depth to traverse (default: 3) + - filter (optional): Glob pattern to filter files + - showSizes (optional): Include file sizes in output (default: false) + - format (optional): Output format - "string" (default) or "json" + +Example: + + filesystem + tree + {"path": "/path/to/dir", "maxDepth": 2} + + +**glob** - Find files matching a glob pattern +Parameters: + - pattern (required): Glob pattern (e.g., "**/*.ts", "src/**/*.js") + - path (optional): Base path to search from + +Example: + + filesystem + glob + {"pattern": "**/*.ts", "path": "/path/to/project"} + +`; + } + public getCallSummary(action: string, params: Record): string { switch (action) { case 'read': { diff --git a/ts/smartagent.tools.http.ts b/ts/smartagent.tools.http.ts index 1155aa0..9e2f2ba 100644 --- a/ts/smartagent.tools.http.ts +++ b/ts/smartagent.tools.http.ts @@ -180,6 +180,84 @@ export class HttpTool extends BaseToolWrapper { } } + public getToolExplanation(): string { + return `## Tool: http +Make HTTP requests to web APIs and services. + +### Actions: + +**get** - Make a GET request +Parameters: + - url (required): URL to request + - headers (optional): Request headers (key-value object) + - query (optional): Query parameters (key-value object) + - timeout (optional): Timeout in milliseconds + +Example: + + http + get + {"url": "https://api.example.com/data", "headers": {"Authorization": "Bearer token123"}} + + +**post** - Make a POST request with JSON body +Parameters: + - url (required): URL to request + - body (optional): JSON body to send + - headers (optional): Request headers (key-value object) + - query (optional): Query parameters (key-value object) + - timeout (optional): Timeout in milliseconds + +Example: + + http + post + {"url": "https://api.example.com/submit", "body": {"name": "test", "value": 123}} + + +**put** - Make a PUT request with JSON body +Parameters: + - url (required): URL to request + - body (required): JSON body to send + - headers (optional): Request headers (key-value object) + - timeout (optional): Timeout in milliseconds + +Example: + + http + put + {"url": "https://api.example.com/resource/1", "body": {"name": "updated"}} + + +**patch** - Make a PATCH request with JSON body +Parameters: + - url (required): URL to request + - body (required): JSON body to send + - headers (optional): Request headers (key-value object) + - timeout (optional): Timeout in milliseconds + +Example: + + http + patch + {"url": "https://api.example.com/resource/1", "body": {"status": "active"}} + + +**delete** - Make a DELETE request +Parameters: + - url (required): URL to request + - headers (optional): Request headers (key-value object) + - timeout (optional): Timeout in milliseconds + +Example: + + http + delete + {"url": "https://api.example.com/resource/1"} + +`; + } + public getCallSummary(action: string, params: Record): string { const method = action.toUpperCase(); let summary = `${method} request to "${params.url}"`; diff --git a/ts/smartagent.tools.json.ts b/ts/smartagent.tools.json.ts index 496770a..510aaeb 100644 --- a/ts/smartagent.tools.json.ts +++ b/ts/smartagent.tools.json.ts @@ -175,6 +175,37 @@ export class JsonValidatorTool extends BaseToolWrapper { } } + public getToolExplanation(): string { + return `## Tool: json +Validate and format JSON data. Use this to verify your JSON output is valid before completing a task. + +### Actions: + +**validate** - Validate that a string is valid JSON and optionally check required fields +Parameters: + - jsonString (required): The JSON string to validate + - requiredFields (optional): Array of field names that must be present + +Example: + + json + validate + {"jsonString": "{\\"invoice_number\\":\\"INV-001\\",\\"total\\":99.99}", "requiredFields": ["invoice_number", "total"]} + + +**format** - Parse and pretty-print JSON string +Parameters: + - jsonString (required): The JSON string to format + +Example: + + json + format + {"jsonString": "{\\"name\\":\\"test\\",\\"value\\":123}"} + +`; + } + getCallSummary(action: string, params: Record): string { const jsonStr = (params.jsonString as string) || ''; const preview = jsonStr.length > 50 ? jsonStr.substring(0, 50) + '...' : jsonStr; diff --git a/ts/smartagent.tools.shell.ts b/ts/smartagent.tools.shell.ts index c15f735..bbabb8a 100644 --- a/ts/smartagent.tools.shell.ts +++ b/ts/smartagent.tools.shell.ts @@ -148,6 +148,54 @@ export class ShellTool extends BaseToolWrapper { } } + public getToolExplanation(): string { + return `## Tool: shell +Execute shell commands securely. Uses execSpawn (shell:false) to prevent command injection. + +### Actions: + +**execute** - Execute a command with arguments (secure, no shell injection possible) +Parameters: + - command (required): The command to execute (e.g., "ls", "cat", "grep", "node") + - args (optional): Array of arguments (each argument is properly escaped) + - cwd (optional): Working directory for the command + - timeout (optional): Timeout in milliseconds + - env (optional): Additional environment variables (key-value object) + +Example - List files: + + shell + execute + {"command": "ls", "args": ["-la", "/path/to/dir"]} + + +Example - Run Node script: + + shell + execute + {"command": "node", "args": ["script.js"], "cwd": "/path/to/project"} + + +Example - Search in files: + + shell + execute + {"command": "grep", "args": ["-r", "pattern", "src/"]} + + +**which** - Check if a command exists and get its path +Parameters: + - command (required): Command name to look up (e.g., "node", "git") + +Example: + + shell + which + {"command": "node"} + +`; + } + public getCallSummary(action: string, params: Record): string { switch (action) { case 'execute': {