Documentation Index
Fetch the complete documentation index at: https://docs.agentfront.dev/llms.txt
Use this file to discover all available pages before exploring further.
The tool system allows scripts to interact with external systems through controlled callTool() invocations. Tools are the primary way for sandboxed code to perform actions and retrieve data.
import { Enclave } from '@enclave-vm/core';
const enclave = new Enclave({
timeout: 10000,
toolHandler: async (toolName, args) => {
console.log(`Tool called: ${toolName}`, args);
switch (toolName) {
case 'users:list':
return { items: [{ id: 1, name: 'Alice' }] };
case 'users:get':
return { id: args.id, name: 'Alice' };
default:
throw new Error(`Unknown tool: ${toolName}`);
}
},
});
const result = await enclave.run(`
const users = await callTool('users:list', {});
return users.items.length;
`);
type ToolHandler = (
toolName: string, // Tool identifier (e.g., 'users:list')
args: unknown // Arguments passed from the script
) => Promise<unknown>;
Connect enclave to your existing tool system:
import { Enclave } from '@enclave-vm/core';
import { ToolRegistry } from './tools';
const enclave = new Enclave({
timeout: 10000,
toolHandler: async (toolName, args) => {
// Look up tool in registry
const tool = ToolRegistry.get(toolName);
if (!tool) {
throw new Error(`Unknown tool: ${toolName}`);
}
// Validate input schema
const validatedArgs = tool.inputSchema.parse(args);
// Execute with your pipeline (auth, logging, etc.)
return tool.execute(validatedArgs);
},
});
Prevent runaway scripts with tool call limits:
const enclave = new Enclave({
maxToolCalls: 50, // Maximum tool calls per execution
toolHandler: async (name, args) => { /* ... */ },
});
When the limit is exceeded, execution fails with error code MAX_TOOL_CALLS.
Custom Globals
Provide custom globals for scripts to access:
const enclave = new Enclave({
toolHandler: async (name, args) => { /* ... */ },
globals: {
// Custom read-only context
context: {
userId: 'user-123',
tenantId: 'tenant-456',
},
// Custom utility function
formatDate: (date: Date) => date.toISOString(),
},
});
const code = `
const userId = context.userId;
const timestamp = formatDate(new Date());
return { userId, timestamp };
`;
const result = await enclave.run(code);
One-Shot Execution
For simple cases without a persistent enclave instance:
import { runAgentScript } from '@enclave-vm/core';
const result = await runAgentScript(`
return Math.max(1, 2, 3);
`, {
timeout: 1000,
});
console.log(result.value); // 3
Handle tool errors gracefully:
const enclave = new Enclave({
toolHandler: async (name, args) => {
try {
return await executeToolSafely(name, args);
} catch (error) {
// Return structured error that script can handle
return {
error: true,
code: error.code || 'TOOL_ERROR',
message: error.message,
};
}
},
});
const code = `
const result = await callTool('risky:operation', {});
if (result.error) {
return { success: false, reason: result.message };
}
return { success: true, data: result };
`;
Limit which tools are available based on context:
const enclave = new Enclave({
toolHandler: async (name, args) => {
// Allowlist of permitted tools
const allowedTools = ['users:list', 'users:get', 'data:read'];
if (!allowedTools.includes(name)) {
throw new Error(`Tool not allowed: ${name}`);
}
return ToolRegistry.execute(name, args);
},
});
Tools are always async, allowing for external API calls:
const enclave = new Enclave({
toolHandler: async (name, args) => {
if (name === 'api:fetch') {
const response = await fetch(args.url);
return response.json();
}
// ...
},
});
Track tool usage in execution stats:
const result = await enclave.run(code);
console.log('Tool calls made:', result.stats.toolCallCount);
console.log('Execution time:', result.stats.duration);