mirror of
https://github.com/skills-shell/superpowers.git
synced 2026-09-18 09:07:07 +08:00
d91c4376f2
Restructure the repository for better organization: - tools/ - App & model running skills - image/ (ai-image-generation, flux-image, nano-banana, qwen-image-2, etc.) - video/ (ai-video-generation, google-veo, ai-avatar-video, etc.) - audio/ (text-to-speech, speech-to-text, ai-music-generation, etc.) - llm/ (llm-models, web-search, ai-rag-pipeline) - social/ (twitter-automation) - utilities/ (agentic-browser, python-executor, related-skill) - agent-tools/ - sdk/ - SDK documentation - javascript-sdk/ - python-sdk/ - ui/ - UI components - agent-ui, chat-ui, tools-ui, widgets-ui - guides/ - How-to guides & workflows - content/, design/, photo/, product/ - prompting/, social/, video/, writing/ Update README to reflect new structure.
10 KiB
10 KiB
Tool Builder Reference
Complete guide to building tools with the JavaScript SDK.
Parameter Types
Basic Types
import { string, number, integer, boolean } from '@inferencesh/sdk';
// String parameter
const name = string('The user\'s full name');
// Number (float)
const score = number('Score between 0 and 1');
// Integer
const count = integer('Number of items');
// Boolean
const enabled = boolean('Whether feature is enabled');
Enum Type
import { enumOf } from '@inferencesh/sdk';
const priority = enumOf(
['low', 'medium', 'high', 'critical'],
'Task priority level'
);
Array Type
import { array, string, obj, integer } from '@inferencesh/sdk';
// Array of strings
const tags = array(string('Tag name'), 'List of tags');
// Array of objects
const items = array(
obj({
name: string('Item name'),
qty: integer('Quantity')
}),
'List of items'
);
Object Type
import { obj, string, integer, optional } from '@inferencesh/sdk';
const address = obj({
street: string('Street address'),
city: string('City name'),
state: string('State code'),
zip: optional(string('ZIP code'))
}, 'Mailing address');
Optional Parameters
import { optional, string } from '@inferencesh/sdk';
// Optional string
const nickname = optional(string('User\'s nickname'));
Tool Types
Client Tools
Tools that execute in your code:
import { tool, string, integer } from '@inferencesh/sdk';
// Basic tool
const greet = tool('greet')
.describe('Greets a user')
.param('name', string('Name to greet'))
.build();
// Tool with multiple parameters
const sendEmail = tool('send_email')
.display('Send Email')
.describe('Sends an email to a recipient')
.param('to', string('Recipient email'))
.param('subject', string('Email subject'))
.param('body', string('Email body'))
.param('priority', integer('Priority 1-5'), 3) // default value
.requireApproval()
.build();
App Tools
Tools that call inference.sh apps:
import { appTool, string } from '@inferencesh/sdk';
// Basic app tool
const generate = appTool('generate_image', 'infsh/flux-schnell@latest')
.describe('Generate an image from a text prompt')
.param('prompt', string('Image description'))
.build();
// App tool with setup and defaults
const translate = appTool('translate', 'infsh/translator@latest')
.describe('Translate text between languages')
.param('text', string('Text to translate'))
.param('targetLang', string('Target language code'))
.setup({
model: 'advanced',
preserveFormatting: true
})
.input({
sourceLang: 'auto'
})
.build();
Agent Tools
Tools that delegate to other agents:
import { agentTool, string } from '@inferencesh/sdk';
const researcher = agentTool('research', 'my-org/researcher@v1')
.describe('Research a topic in depth')
.param('topic', string('Topic to research'))
.param('depth', string('Research depth: brief, moderate, comprehensive'))
.build();
const coder = agentTool('write_code', 'my-org/coder@latest')
.describe('Write code to solve a problem')
.param('task', string('Coding task description'))
.param('language', string('Programming language'))
.build();
Webhook Tools
Tools that call external HTTP endpoints:
import { webhookTool, string } from '@inferencesh/sdk';
// Slack notification
const slack = webhookTool('notify_slack', 'https://hooks.slack.com/services/...')
.describe('Send a message to Slack')
.param('channel', string('Channel name'))
.param('message', string('Message text'))
.build();
// Webhook with secret
const github = webhookTool('create_issue', 'https://api.github.com/repos/org/repo/issues')
.describe('Create a GitHub issue')
.secret('GITHUB_TOKEN') // Uses stored secret
.param('title', string('Issue title'))
.param('body', string('Issue description'))
.build();
Tool Builder Methods
Common Methods
| Method | Description |
|---|---|
.describe(text) |
Set tool description |
.display(name) |
Set display name |
.param(name, type, default?) |
Add parameter |
.requireApproval() |
Require human approval |
.build() |
Build the tool |
App Tool Methods
| Method | Description |
|---|---|
.setup(config) |
Hidden setup configuration |
.input(defaults) |
Default input values |
Webhook Tool Methods
| Method | Description |
|---|---|
.secret(name) |
Use stored secret for auth |
Internal Tools
Built-in capabilities you can enable:
import { internalTools } from '@inferencesh/sdk';
const config = internalTools()
.plan() // Task planning
.memory() // Information storage
.webSearch(true) // Web search capability
.codeExecution(true) // Run code
.imageGeneration({
enabled: true,
appRef: 'infsh/flux@latest'
})
.build();
Internal Tool Options
| Tool | Description |
|---|---|
.plan() |
Enable task breakdown and planning |
.memory() |
Enable information storage |
.webSearch(enabled) |
Enable/disable web search |
.codeExecution(enabled) |
Enable/disable code running |
.imageGeneration(config) |
Configure image generation |
Handling Tool Calls
Basic Handler
const response = await agent.sendMessage('Greet John', {
onToolCall: async (call) => {
let result;
if (call.name === 'greet') {
result = `Hello, ${call.args.name}!`;
} else if (call.name === 'calculate') {
result = eval(call.args.expression);
} else {
result = { error: `Unknown tool: ${call.name}` };
}
agent.submitToolResult(call.id, result);
}
});
With Approval
import * as readline from 'readline';
async function promptUser(question: string): Promise<boolean> {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise(resolve => {
rl.question(question, answer => {
rl.close();
resolve(answer.toLowerCase() === 'y');
});
});
}
const response = await agent.sendMessage('Delete temp files', {
onToolCall: async (call) => {
if (call.requiresApproval) {
console.log(`Tool: ${call.name}`);
console.log(`Args: ${JSON.stringify(call.args)}`);
const approved = await promptUser('Approve? (y/n): ');
if (!approved) {
agent.submitToolResult(call.id, { error: 'Denied by user' });
return;
}
}
const result = await executeTool(call.name, call.args);
agent.submitToolResult(call.id, result);
}
});
Widget Results
Return structured data for UI widgets:
const response = await agent.sendMessage('Show order confirmation', {
onToolCall: async (call) => {
if (call.name === 'confirm_order') {
// Return widget data
agent.submitToolResult(call.id, {
action: { type: 'confirm' },
formData: {
orderId: '12345',
items: ['Widget A', 'Widget B'],
total: 99.99
}
});
}
}
});
TypeScript Types
import type {
AgentTool,
ToolCall,
ToolResult,
ParamType
} from '@inferencesh/sdk';
// Type-safe tool definition
const typedTool: AgentTool = tool('my_tool')
.describe('A typed tool')
.param('input', string('Input value'))
.build();
// Type-safe handler
function handleToolCall(call: ToolCall): ToolResult {
return { success: true, data: call.args };
}
Complete Example
import {
inference, tool, appTool, webhookTool,
string, number, integer, boolean, enumOf,
array, obj, optional, internalTools
} from '@inferencesh/sdk';
const client = inference({ apiKey: 'inf_...' });
// Calculator tool
const calculator = tool('calculate')
.display('Calculator')
.describe('Perform mathematical calculations')
.param('expression', string('Math expression to evaluate'))
.build();
// Image generation tool
const imageGen = appTool('generate_image', 'infsh/flux-schnell@latest')
.describe('Generate an image from text')
.param('prompt', string('Image description'))
.param('style', enumOf(['realistic', 'artistic', 'cartoon'], 'Image style'))
.setup({ quality: 'high' })
.input({ steps: 20 })
.requireApproval()
.build();
// Slack notification tool
const slack = webhookTool('notify', 'https://hooks.slack.com/...')
.describe('Send Slack notification')
.param('message', string('Message to send'))
.build();
// Built-in tools
const internals = internalTools()
.webSearch(true)
.codeExecution(true)
.build();
// Create agent with all tools
const agent = client.agent({
core_app: { ref: 'infsh/claude-sonnet-4@latest' },
system_prompt: 'You are a helpful assistant with various capabilities.',
tools: [calculator, imageGen, slack],
internal_tools: internals,
temperature: 0.7
});
// Handle tool calls
const response = await agent.sendMessage(
'Calculate 15% tip on $85, then notify Slack',
{
onToolCall: async (call) => {
if (call.name === 'calculate') {
try {
const result = eval(call.args.expression);
agent.submitToolResult(call.id, { result });
} catch (e) {
agent.submitToolResult(call.id, { error: String(e) });
}
} else if (call.requiresApproval) {
const approved = await promptUser(`Allow ${call.name}? (y/n): `);
if (!approved) {
agent.submitToolResult(call.id, { error: 'Denied' });
}
// App/webhook tools execute automatically if approved
}
}
}
);
Server Proxy Tools
When using the SDK in the browser, tools that require API keys should use webhooks with secrets stored server-side:
// Browser-safe tool definition
const apiTool = webhookTool('call_api', '/api/my-endpoint')
.describe('Call server-side API')
.param('data', obj({
action: string('Action to perform'),
payload: optional(string('Optional payload'))
}))
.build();
// Server-side handler (e.g., Next.js API route)
// app/api/my-endpoint/route.ts
export async function POST(req: Request) {
const { data } = await req.json();
// Access secrets safely on server
const result = await fetch(process.env.EXTERNAL_API_URL, {
headers: { Authorization: `Bearer ${process.env.API_SECRET}` },
body: JSON.stringify(data)
});
return Response.json(await result.json());
}