238 lines
6.3 KiB
TypeScript
238 lines
6.3 KiB
TypeScript
import * as interfaces from './smartagent.interfaces.js';
|
|
import { BaseToolWrapper } from './smartagent.tools.base.js';
|
|
import { ToolRegistry } from './smartagent.classes.toolregistry.js';
|
|
|
|
/**
|
|
* ToolSearchTool - AI-facing interface for discovering and activating tools
|
|
*
|
|
* This tool enables the Driver to:
|
|
* - Search for tools by capability
|
|
* - List all available tools
|
|
* - Activate on-demand tools
|
|
* - Get detailed information about specific tools
|
|
*/
|
|
export class ToolSearchTool extends BaseToolWrapper {
|
|
public name = 'tools';
|
|
public description =
|
|
'Search for and activate available tools and experts. Use this to discover specialized capabilities.';
|
|
|
|
public actions: interfaces.IToolAction[] = [
|
|
{
|
|
name: 'search',
|
|
description: 'Search for tools by name, description, tags, or capabilities',
|
|
parameters: {
|
|
type: 'object',
|
|
properties: {
|
|
query: { type: 'string', description: 'Search query' },
|
|
},
|
|
required: ['query'],
|
|
},
|
|
},
|
|
{
|
|
name: 'list',
|
|
description: 'List all available tools grouped by visibility',
|
|
parameters: { type: 'object', properties: {} },
|
|
},
|
|
{
|
|
name: 'activate',
|
|
description: 'Activate an on-demand tool to make it available for use',
|
|
parameters: {
|
|
type: 'object',
|
|
properties: {
|
|
name: { type: 'string', description: 'Name of the tool to activate' },
|
|
},
|
|
required: ['name'],
|
|
},
|
|
},
|
|
{
|
|
name: 'details',
|
|
description: 'Get detailed information about a specific tool',
|
|
parameters: {
|
|
type: 'object',
|
|
properties: {
|
|
name: { type: 'string', description: 'Name of the tool' },
|
|
},
|
|
required: ['name'],
|
|
},
|
|
},
|
|
];
|
|
|
|
private registry: ToolRegistry;
|
|
private onToolActivated?: (tool: BaseToolWrapper) => void;
|
|
|
|
constructor(registry: ToolRegistry, onToolActivated?: (tool: BaseToolWrapper) => void) {
|
|
super();
|
|
this.registry = registry;
|
|
this.onToolActivated = onToolActivated;
|
|
}
|
|
|
|
async initialize(): Promise<void> {
|
|
this.isInitialized = true;
|
|
}
|
|
|
|
async cleanup(): Promise<void> {
|
|
this.isInitialized = false;
|
|
}
|
|
|
|
async execute(
|
|
action: string,
|
|
params: Record<string, unknown>
|
|
): Promise<interfaces.IToolExecutionResult> {
|
|
this.validateAction(action);
|
|
|
|
switch (action) {
|
|
case 'search':
|
|
return this.handleSearch(params.query as string);
|
|
case 'list':
|
|
return this.handleList();
|
|
case 'activate':
|
|
return this.handleActivate(params.name as string);
|
|
case 'details':
|
|
return this.handleDetails(params.name as string);
|
|
default:
|
|
return { success: false, error: `Unknown action: ${action}` };
|
|
}
|
|
}
|
|
|
|
private handleSearch(query: string): interfaces.IToolExecutionResult {
|
|
const results = this.registry.search(query);
|
|
return {
|
|
success: true,
|
|
result: results.map((m) => ({
|
|
name: m.name,
|
|
description: m.description,
|
|
visibility: m.visibility,
|
|
isActivated: m.isActivated,
|
|
category: m.category,
|
|
tags: m.tags,
|
|
actionCount: m.actions.length,
|
|
})),
|
|
summary: `Found ${results.length} tools matching "${query}"`,
|
|
};
|
|
}
|
|
|
|
private handleList(): interfaces.IToolExecutionResult {
|
|
const all = this.registry.getAllMetadata();
|
|
const initial = all.filter((m) => m.visibility === 'initial');
|
|
const onDemand = all.filter((m) => m.visibility === 'on-demand');
|
|
|
|
return {
|
|
success: true,
|
|
result: {
|
|
initial: initial.map((m) => ({
|
|
name: m.name,
|
|
description: m.description,
|
|
category: m.category,
|
|
})),
|
|
onDemand: onDemand.map((m) => ({
|
|
name: m.name,
|
|
description: m.description,
|
|
category: m.category,
|
|
isActivated: m.isActivated,
|
|
})),
|
|
summary: `${initial.length} initial, ${onDemand.length} on-demand`,
|
|
},
|
|
};
|
|
}
|
|
|
|
private async handleActivate(name: string): Promise<interfaces.IToolExecutionResult> {
|
|
const result = await this.registry.activate(name);
|
|
|
|
if (result.success && this.onToolActivated) {
|
|
const tool = this.registry.getTool(name);
|
|
if (tool) {
|
|
this.onToolActivated(tool);
|
|
}
|
|
}
|
|
|
|
return {
|
|
success: result.success,
|
|
result: result.success ? { name, message: `Tool "${name}" is now available` } : undefined,
|
|
error: result.error,
|
|
summary: result.success ? `Activated: ${name}` : result.error,
|
|
};
|
|
}
|
|
|
|
private handleDetails(name: string): interfaces.IToolExecutionResult {
|
|
const tool = this.registry.getTool(name);
|
|
const meta = this.registry.getMetadata(name);
|
|
|
|
if (!tool || !meta) {
|
|
return { success: false, error: `Tool "${name}" not found` };
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
result: {
|
|
name: meta.name,
|
|
description: meta.description,
|
|
visibility: meta.visibility,
|
|
isActivated: meta.isActivated,
|
|
category: meta.category,
|
|
tags: meta.tags,
|
|
actions: meta.actions,
|
|
fullExplanation: tool.getToolExplanation(),
|
|
},
|
|
};
|
|
}
|
|
|
|
getCallSummary(action: string, params: Record<string, unknown>): string {
|
|
switch (action) {
|
|
case 'search':
|
|
return `Search tools: "${params.query}"`;
|
|
case 'list':
|
|
return 'List all tools';
|
|
case 'activate':
|
|
return `Activate tool: ${params.name}`;
|
|
case 'details':
|
|
return `Get details: ${params.name}`;
|
|
default:
|
|
return `tools.${action}`;
|
|
}
|
|
}
|
|
|
|
getToolExplanation(): string {
|
|
return `## Tool: tools
|
|
Search for and manage available tools and experts.
|
|
|
|
### Actions:
|
|
|
|
**search** - Find tools by capability
|
|
\`\`\`
|
|
<tool_call>
|
|
<tool>tools</tool>
|
|
<action>search</action>
|
|
<params>{"query": "database"}</params>
|
|
</tool_call>
|
|
\`\`\`
|
|
|
|
**list** - List all tools grouped by visibility
|
|
\`\`\`
|
|
<tool_call>
|
|
<tool>tools</tool>
|
|
<action>list</action>
|
|
<params>{}</params>
|
|
</tool_call>
|
|
\`\`\`
|
|
|
|
**activate** - Activate an on-demand tool
|
|
\`\`\`
|
|
<tool_call>
|
|
<tool>tools</tool>
|
|
<action>activate</action>
|
|
<params>{"name": "database_expert"}</params>
|
|
</tool_call>
|
|
\`\`\`
|
|
|
|
**details** - Get full information about a tool
|
|
\`\`\`
|
|
<tool_call>
|
|
<tool>tools</tool>
|
|
<action>details</action>
|
|
<params>{"name": "filesystem"}</params>
|
|
</tool_call>
|
|
\`\`\`
|
|
`;
|
|
}
|
|
}
|