// packages/core/src/tools/my-tool.ts
import { BaseDeclarativeTool, BaseToolInvocation, Kind } from './tools.js';
import type { ToolInvocation, ToolResult } from './tools.js';
import { ToolNames, ToolDisplayNames } from './tool-names.js';
import type { Config } from '../config/config.js';
// 1. Define parameter interface
export interface MyToolParams {
requiredParam: string;
optionalParam?: number;
}
// 2. Create invocation class
class MyToolInvocation extends BaseToolInvocation<
MyToolParams,
ToolResult
> {
constructor(
private config: Config,
params: MyToolParams,
) {
super(params);
}
getDescription(): string {
return `My tool: ${this.params.requiredParam}`;
}
async execute(signal: AbortSignal): Promise<ToolResult> {
// Implement tool logic
try {
const result = await this.doSomething();
return {
llmContent: `Success: ${result}`,
returnDisplay: result,
};
} catch (error) {
return {
llmContent: `Error: ${error.message}`,
error: {
message: error.message,
type: 'EXECUTION_ERROR',
},
};
}
}
private async doSomething(): Promise<string> {
// Tool implementation
return 'result';
}
}
// 3. Create tool class
export class MyTool extends BaseDeclarativeTool<
MyToolParams,
ToolResult
> {
static readonly Name = 'my_tool';
constructor(private config: Config) {
super(
MyTool.Name,
'MyTool', // Display name
'Description of what my tool does',
Kind.Other, // or Kind.Read, Kind.Edit
{
type: 'object',
properties: {
requiredParam: {
type: 'string',
description: 'Description for the model',
},
optionalParam: {
type: 'number',
description: 'Optional parameter',
},
},
required: ['requiredParam'],
},
);
}
protected override validateToolParamValues(
params: MyToolParams,
): string | null {
// Add custom validation
if (params.requiredParam.length === 0) {
return 'requiredParam must not be empty';
}
return null;
}
protected createInvocation(
params: MyToolParams,
): ToolInvocation<MyToolParams, ToolResult> {
return new MyToolInvocation(this.config, params);
}
}