Tool API
The Tool API provides interfaces for creating, managing, and executing tools that agents can use to interact with external systems and perform various operations.
Tool Class
Base class for all tools in the system.
Constructor
class Tool {
constructor(config) {
this.name = config.name
this.description = config.description
this.parameters = config.parameters
this.handler = config.handler
this.permissions = config.permissions || []
this.timeout = config.timeout || 30000
this.rateLimit = config.rateLimit || null
}
}Properties
name(string): Unique tool namedescription(string): Tool description for LLM understandingparameters(Object): JSON Schema parameter definitionhandler(Function): Tool execution functionpermissions(Array<string>): Required permissionstimeout(number): Execution timeout in millisecondsrateLimit(Object): Rate limiting configuration
Methods
execute(params, context)
Executes the tool with given parameters.
const result = await tool.execute({
query: 'latest AI trends',
maxResults: 10,
timeframe: '2024'
}, {
userId: 'user123',
sessionId: 'session456',
requestId: 'req123'
})Parameters:
params(Object): Tool parameterscontext(Object): Execution context
Returns:
- Promise<Object>: Tool execution result
success(boolean): Whether execution succeededdata(any): Tool result datametadata(Object): Execution metadataerror(string): Error message if failed
validateParameters(params)
Validates tool parameters against the schema.
const validation = await tool.validateParameters({
query: 'AI trends',
maxResults: 10
})Parameters:
params(Object): Parameters to validate
Returns:
- Object: Validation result
valid(boolean): Whether parameters are validerrors(Array<string>): Validation errors if invalid
ToolRegistry
Manages tool registration, discovery, and execution.
Constructor
import { ToolRegistry } from 'skingflow'
const toolRegistry = new ToolRegistry({
enableSandbox: true,
defaultTimeout: 30000,
rateLimit: {
enabled: true,
windowMs: 60000,
maxRequests: 100
}
})Methods
registerTool(tool)
Registers a tool with the registry.
const searchTool = new Tool({
name: 'web_search',
description: 'Search the web for information',
parameters: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'Search query'
},
maxResults: {
type: 'number',
description: 'Maximum number of results',
default: 10
}
},
required: ['query']
},
handler: async (params, context) => {
// Web search implementation
const results = await performWebSearch(params.query, params.maxResults)
return { results }
}
})
await toolRegistry.registerTool(searchTool)Parameters:
tool(Tool): Tool instance to register
Returns:
- Promise<void>
unregisterTool(toolName)
Unregisters a tool from the registry.
await toolRegistry.unregisterTool('web_search')Parameters:
toolName(string): Name of the tool to unregister
Returns:
- Promise<void>
getTool(toolName)
Gets a registered tool by name.
const tool = await toolRegistry.getTool('web_search')Parameters:
toolName(string): Name of the tool to retrieve
Returns:
- Promise<Tool>: Tool instance or null if not found
listTools()
Lists all registered tools.
const tools = await toolRegistry.listTools()
console.log('Available tools:', tools)Returns:
- Promise<Array<Object>>: List of tool information
name(string): Tool namedescription(string): Tool descriptionparameters(Object): Tool parameters schemapermissions(Array<string>): Required permissions
executeTool(toolName, params, context)
Executes a tool with permission checks and error handling.
const result = await toolRegistry.executeTool(
'web_search',
{ query: 'latest AI trends', maxResults: 5 },
{ userId: 'user123', sessionId: 'session456' }
)Parameters:
toolName(string): Name of the tool to executeparams(Object): Tool parameterscontext(Object): Execution context
Returns:
- Promise<Object>: Tool execution result
Built-in Tools
FileSystemTool
File system operations with security restrictions.
import { FileSystemTool } from 'skingflow'
const fileTool = new FileSystemTool({
basePath: './workspace',
allowedPaths: ['./workspace', './temp'],
restrictedPaths: ['/etc', '/system', '~/.ssh'],
maxFileSize: 10485760 // 10MB
})
await toolRegistry.registerTool(fileTool)
// Usage
const result = await toolRegistry.executeTool('file_system', {
operation: 'read',
path: './workspace/data.txt'
}, context)WebSearchTool
Web search functionality.
import { WebSearchTool } from 'skingflow'
const webTool = new WebSearchTool({
provider: 'serpapi', // 'serpapi', 'google', 'bing'
apiKey: process.env.SERPAPI_KEY,
timeout: 10000,
maxResults: 10
})
await toolRegistry.registerTool(webTool)
// Usage
const result = await toolRegistry.executeTool('web_search', {
query: 'latest developments in artificial intelligence',
maxResults: 5
}, context)DataProcessingTool
Data processing and analysis.
import { DataProcessingTool } from 'skingflow'
const dataTool = new DataProcessingTool({
supportedFormats: ['json', 'csv', 'xml'],
maxFileSize: 52428800, // 50MB
allowedOperations: ['filter', 'sort', 'aggregate', 'transform']
})
await toolRegistry.registerTool(dataTool)
// Usage
const result = await toolRegistry.executeTool('data_processing', {
operation: 'aggregate',
data: salesData,
groupBy: 'region',
aggregation: 'sum'
}, context)CodeExecutionTool
Safe code execution in sandboxed environment.
import { CodeExecutionTool } from 'skingflow'
const codeTool = new CodeExecutionTool({
allowedLanguages: ['javascript', 'python'],
timeout: 30000,
memoryLimit: '512MB',
allowedModules: ['lodash', 'axios', 'moment'],
enableNetworking: false
})
await toolRegistry.registerTool(codeTool)
// Usage
const result = await toolRegistry.executeTool('code_execution', {
language: 'javascript',
code: `
const data = [1, 2, 3, 4, 5];
const sum = data.reduce((a, b) => a + b, 0);
return { sum, average: sum / data.length };
`
}, context)Custom Tool Implementation
Create custom tools by extending the base Tool class:
import { Tool } from 'skingflow'
class DatabaseQueryTool extends Tool {
constructor(config) {
super({
name: 'database_query',
description: 'Execute safe database queries',
parameters: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'SQL query to execute'
},
params: {
type: 'array',
items: { type: 'string' },
description: 'Query parameters'
},
maxRows: {
type: 'number',
description: 'Maximum number of rows to return',
default: 1000
}
},
required: ['query']
},
permissions: ['database:read'],
timeout: config.timeout || 30000,
...config
})
this.pool = config.pool // Database connection pool
this.queryValidator = config.queryValidator
}
async execute(params, context) {
try {
// Validate query for security
await this.validateQuery(params.query)
// Execute query with parameterized inputs
const result = await this.executeQuery(params.query, params.params || [], params.maxRows)
return {
success: true,
data: result.rows,
metadata: {
rowCount: result.rowCount,
queryTime: result.queryTime,
fields: result.fields
}
}
} catch (error) {
return {
success: false,
error: error.message,
code: error.code
}
}
}
async validateQuery(query) {
// Check for dangerous operations
const dangerousPatterns = [
/DROP\s+TABLE/i,
/DELETE\s+FROM/i,
/UPDATE\s+.*\s+SET/i,
/INSERT\s+INTO/i,
/CREATE\s+TABLE/i,
/ALTER\s+TABLE/i
]
for (const pattern of dangerousPatterns) {
if (pattern.test(query)) {
throw new Error('Potentially dangerous query detected')
}
}
// Use custom validator if provided
if (this.queryValidator) {
await this.queryValidator.validate(query)
}
}
async executeQuery(query, params, maxRows) {
const startTime = Date.now()
// Add LIMIT clause if not present
let limitedQuery = query
if (!query.toLowerCase().includes('limit') && maxRows) {
limitedQuery = `${query} LIMIT ${maxRows}`
}
const result = await this.pool.query(limitedQuery, params)
const queryTime = Date.now() - startTime
return {
rows: result.rows,
rowCount: result.rowCount,
queryTime,
fields: result.fields
}
}
}
// Register the custom tool
const dbTool = new DatabaseQueryTool({
pool: databasePool,
queryValidator: new SQLValidator(),
timeout: 45000
})
await toolRegistry.registerTool(dbTool)Tool Security
Permission System
// Configure tool permissions
const toolRegistry = new ToolRegistry({
security: {
permissions: {
enabled: true,
defaultPermissions: ['read:basic'],
rolePermissions: {
admin: ['*'],
developer: ['read:basic', 'write:basic', 'execute:tools'],
user: ['read:basic', 'execute:basic_tools'],
guest: ['read:basic']
}
}
}
})
// Check permissions before tool execution
await toolRegistry.checkPermission('file_system', 'write', { userId: 'user123', role: 'user' })Sandboxing
// Configure tool sandboxing
const toolRegistry = new ToolRegistry({
sandbox: {
enabled: true,
timeout: 30000,
memoryLimit: '512MB',
allowedModules: ['fs', 'path', 'crypto'],
blockedModules: ['child_process', 'net', 'dgram'],
fileSystem: {
basePath: './sandbox',
readOnly: true,
allowedPaths: ['./sandbox/public'],
restrictedPaths: ['/etc', '/system']
},
network: {
enabled: false,
allowedHosts: [],
allowedPorts: []
}
}
})Rate Limiting
// Configure rate limiting
const toolRegistry = new ToolRegistry({
rateLimit: {
enabled: true,
windowMs: 60000, // 1 minute
maxRequests: 100,
skipSuccessfulRequests: false,
skipFailedRequests: false,
onLimitReached: (toolName, userId) => {
console.log(`Rate limit reached for ${toolName} by user ${userId}`)
}
}
})Tool Monitoring
Monitor tool usage and performance:
// Get tool usage statistics
const stats = await toolRegistry.getToolStatistics()
console.log('Tool Statistics:', stats)
// Output example:
{
"tools": {
"web_search": {
"totalExecutions": 1234,
"successfulExecutions": 1180,
"failedExecutions": 54,
"averageExecutionTime": 2345,
"lastUsed": "2024-01-15T10:30:00Z",
"topUsers": ["user123", "user456", "user789"]
},
"file_system": {
"totalExecutions": 856,
"successfulExecutions": 834,
"failedExecutions": 22,
"averageExecutionTime": 1234,
"lastUsed": "2024-01-15T10:25:00Z",
"topUsers": ["user123", "user789", "user456"]
}
},
"summary": {
"totalExecutions": 2090,
"successRate": 0.964,
"averageExecutionTime": 1890
}
}Tool Chaining
Chain multiple tools together for complex operations:
// Execute a tool chain
const chainResult = await toolRegistry.executeToolChain([
{
tool: 'web_search',
params: { query: 'latest AI research papers', maxResults: 5 },
saveTo: 'search_results'
},
{
tool: 'data_processing',
params: {
operation: 'filter',
data: '${search_results.results}',
condition: 'year >= 2023'
},
saveTo: 'filtered_results'
},
{
tool: 'file_system',
params: {
operation: 'write',
path: './research_summary.json',
content: '${filtered_results}'
}
}
], context)Error Handling and Recovery
Implement comprehensive error handling:
class RobustTool extends Tool {
async execute(params, context) {
try {
// Validate parameters
const validation = await this.validateParameters(params)
if (!validation.valid) {
throw new Error(`Invalid parameters: ${validation.errors.join(', ')}`)
}
// Check rate limits
await this.checkRateLimit(context.userId)
// Execute with timeout
const result = await this.executeWithTimeout(params, context, this.timeout)
return {
success: true,
data: result,
metadata: {
executionTime: Date.now() - context.startTime,
toolVersion: this.version
}
}
} catch (error) {
return await this.handleError(error, params, context)
}
}
async executeWithTimeout(params, context, timeout) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error('Tool execution timeout'))
}, timeout)
this.doExecute(params, context)
.then(result => {
clearTimeout(timer)
resolve(result)
})
.catch(error => {
clearTimeout(timer)
reject(error)
})
})
}
async handleError(error, params, context) {
// Log error for monitoring
await this.logError(error, params, context)
// Attempt recovery if possible
if (await this.isRecoverableError(error)) {
const recoveryResult = await this.attemptRecovery(error, params, context)
if (recoveryResult.success) {
return {
success: true,
data: recoveryResult.data,
recovered: true,
warning: error.message
}
}
}
return {
success: false,
error: error.message,
code: error.code,
retryable: await this.isRetryableError(error)
}
}
}Best Practices
1. Tool Design
- Keep tools focused on single responsibilities
- Use clear, descriptive names and parameter schemas
- Implement proper error handling and validation
- Include comprehensive documentation
2. Security
- Always validate and sanitize inputs
- Implement proper permission checks
- Use sandboxing for potentially dangerous operations
- Monitor tool usage and performance
3. Performance
- Implement appropriate timeouts and rate limiting
- Use connection pooling for external services
- Cache results when appropriate
- Monitor and optimize execution times
4. Reliability
- Implement retry logic for transient failures
- Provide meaningful error messages
- Include detailed logging and monitoring
- Test edge cases and error scenarios
Next Steps
- Memory API - Memory system API documentation
- Framework API - Main framework API documentation
- Agent API - Agent system API documentation
- Examples - Practical implementations