Tool Architecture & Execution
1. Overview and Core Principles
The tool architecture is a cornerstone of the VibeX framework, designed to safely provide agents with the capabilities they need to perform meaningful work. It directly supports the Vibe-X philosophy by enabling a secure, observable, and extensible system where a human expert can confidently delegate tasks to an AI partner.
The core principles are:
- Security First: Untrusted, LLM-generated code or commands must never execute directly on a host machine. All tool execution is centralized, validated, and sandboxed.
- Robust Self-Correction: LLM-generated tool calls can be malformed. The system is designed to detect this, provide clear, corrective feedback to the agent, and enable the agent to fix its own mistakes.
- Extensible by Design: The framework is built to be easily extended. Adding new tools follows a consistent pattern, and the architecture supports advanced integrations like the Model Context Protocol (MCP).
2. Tool Definition and Registration
A “tool” is a capability that an agent can call. Tools are defined using the AI SDK pattern with Zod schemas.
2.1. Tool Definition
Tools are defined with a name, description, parameter schema, and execute function:
import { z } from "zod";
import type { CoreTool } from "@vibex/core";
const writeFileTool: CoreTool = {
name: "write_file",
description: "Writes content to a file at the specified path.",
parameters: z.object({
path: z.string().describe("The file path to write to"),
content: z.string().describe("The content to write"),
}),
execute: async ({ path, content }) => {
// Implementation
return { success: true, message: `File '${path}' written successfully.` };
},
};2.2. Tool Registration
Tools are registered with agents through configuration:
import { createVibexAgent } from "vibex";
const agent = createVibexAgent({
name: "Developer",
llm: { provider: "openai", model: "gpt-4o" },
tools: ["write_file", "read_file", "execute_code"],
requireApproval: ["write_file", "execute_code"], // Human-in-the-loop
});3. The Tool Call Lifecycle
The following diagram and steps describe the end-to-end flow of a tool call, from the XAgent’s task assignment to the final result.
Step-by-Step Flow:
-
Task Assignment (
XAgent): The process begins when theXAgent, following the project’s plan, assigns a specific task to a specialistAgent(e.g., “Write ‘hello world’ tohello.txt”). -
Tool Call Generation (
Agent’s LLM): The Agent’s LLM receives the instruction. It determines that the task can be accomplished with a tool and generates the corresponding structured tool call. -
Execution Request: The Agent’s core logic receives the generated tool call and passes it to the Tool Manager for secure execution.
-
Validation: The Tool Manager validates the call against the tool’s registered schema.
- If Validation Fails: The Tool Manager returns a structured error to the Agent. The Agent’s LLM receives the error context and generates a corrected call. This self-correction loop is a key feature of the framework’s robustness.
- If Validation Succeeds: The Tool Manager proceeds to execution.
-
Secure Execution: The Tool Manager securely runs the tool with validated parameters.
-
Result Capturing: The Tool Manager captures the tool’s output and packages it into a structured result object, which is returned to the Agent.
-
Task Completion: The Agent has now completed its assigned task. It reports the result back to the XAgent, which updates the project plan and proceeds to the next step in the workflow.
4. Human-in-the-Loop Tool Approval
VibeX supports native tool approval through AI SDK v6’s approval mechanism:
// Agent configuration with approval requirements
const agent = createVibexAgent({
name: "Developer",
tools: ["write_file", "execute_code", "read_file"],
requireApproval: ["write_file", "execute_code"],
});
// Frontend handles approval
const { messages, approveToolCall, status } = useXChat({
spaceId: "my-space",
});
// When status is "awaiting-approval"
if (status === "awaiting-approval") {
const pendingApprovals = getPendingApprovals(messages[messages.length - 1]);
// Show UI for approval
await approveToolCall(pendingApprovals[0].toolCallId, true);
}5. Security Architecture
Executing arbitrary, LLM-generated commands is a major security risk. VibeX mitigates this through multiple layers:
Space-Scoped Execution
All tool executions are scoped to the Space’s workspace directory:
- Tools can only read from and write to the Space’s artifact directory
- Path traversal attacks are mitigated by resolving all paths relative to the Space root
- Each Space has complete data isolation from other Spaces
Tool Permissions
// Tools can specify their permission requirements
const webBrowseTool: CoreTool = {
name: "browse_web",
description: "Browse a webpage and extract content",
parameters: z.object({
url: z.string().url(),
}),
permissions: ["network"], // Requires network access
execute: async ({ url }) => {
// Implementation with Playwright
},
};6. Built-in Tools
VibeX provides a core set of tools in @vibex/tools:
| Tool | Description | Category |
|---|---|---|
read_file | Read file contents | File |
write_file | Write content to file | File |
list_files | List directory contents | File |
web_search | Search the web | Search |
browse_web | Browse and extract web pages | Web |
execute_sql | Execute database queries | Database |
7. Custom Tools
Users can define custom tools following the same pattern:
import { z } from "zod";
import type { CoreTool } from "@vibex/core";
export const customTool: CoreTool = {
name: "my_custom_tool",
description: "Does something custom",
parameters: z.object({
input: z.string(),
}),
execute: async ({ input }) => {
// Custom implementation
return { result: `Processed: ${input}` };
},
};
// Register with agent
const agent = createVibexAgent({
name: "CustomAgent",
tools: [customTool], // Pass tool object directly
});8. MCP Integration
VibeX supports the Model Context Protocol (MCP) for integrating external tool servers:
import { createMCPToolProvider } from "@vibex/tools";
// Connect to an MCP server
const mcpTools = await createMCPToolProvider({
server: "mcp://localhost:3000",
});
// Use MCP tools with agents
const agent = createVibexAgent({
name: "MCPAgent",
tools: [...mcpTools.getTools()],
});This enables agents to access a vast ecosystem of third-party capabilities without requiring custom code for each integration.