Agent Tools
What is a Agent Tool?
In the Eko framework, Tools are the core capability of an agent, the component that truly executes the calls, and an agent must contain one or more tools to complete its work.
How to Custom Tools in Agent?
Each Tool needs to implement the following core elements:
name
: Unique identifier for the Tooldescription
: Functional description of the Toolparameters
: Input parameter structure definitionexecute
: Specific execution logic
To create custom Tools in Eko agent, you need to follow these steps:
- Define input and output structures: Clearly specify the Tool’s input parameters and output results.
- Implement Tool interface: Inherit or implement the
Tool
interface and define related properties and methods. - Handle parameters: Write implementation logic for specific functionality in the
execute
method.
interface Tool { name: string; // tool name description: string; // A functional description explaining the tool's purpose and usage scenarios parameters: InputSchema; // A functional description explaining the tool's purpose and usage scenarios execute: (args: Record<string, unknown>, agentContext: AgentContext, toolCall: LanguageModelV1ToolCallPart) => Promise<ToolResult>; // Execute function}
Creating a Agent Tool
Let’s explain how to create a custom Tool through a simple example.
Suppose we want to create an email sending Tool:
import { AgentContext } from "@eko-ai/eko";import { Tool, ToolResult, LanguageModelV1ToolCallPart } from "@eko-ai/eko/types";
class SendEmail implements Tool { name: string; description: string; parameters: any;
constructor() { this.name = "send_email"; this.description = "Send email to specified recipient"; this.parameters = { type: "object", properties: { to: { type: "string", description: "Email address of the recipient", }, subject: { type: "string", description: "Email subject", }, content: { type: "string", description: "Email content", }, }, required: ["to", "subject", "content"], }; }
async execute( args: Record<string, unknown>, agentContext: AgentContext, toolCall: LanguageModelV1ToolCallPart ): Promise<ToolResult> { // Implement specific email sending logic // This is just an example let emailService: any; const result = await emailService.send({ to: args.to, subject: args.subject, content: args.content, }); return { content: [ { type: "text", text: JSON.stringify({ messageId: result.id }) }, ], }; }}
Advanced Features
Session state (variable)
In the tool execute function, it supports reading or saving variable information across tools or across agents.
async execute( args: Record<string, unknown>, agentContext: AgentContext, toolCall: LanguageModelV1ToolCallPart): Promise<ToolResult> { // Example: Reading and writing variables (effective within the current agent execution process during the current task, Cross-tool) let id1 = agentContext.variables.get("id1"); if (!id1) { agentContext.variables.set("id1", "xxxx"); }
// Example: Reading and writing variables (the lifecycle is effective during the current task's execution process, Cross-agent) let id2 = agentContext.context.variables.get("id2"); if (!id2) { agentContext.context.variables.set("id2", "xxxx"); }
return { content: [ { type: "text", text: "Successful" }, ], };}
callback tool_running
event
Supports callback events during tool invocation. For example, some tools take longer to execute and generate logs or streaming output data during execution that need to be exposed in real-time through callbacks, such as real-time logs generated by Python code execution tools.
async execute( args: Record<string, unknown>, agentContext: AgentContext, toolCall: LanguageModelV1ToolCallPart): Promise<ToolResult> { // Real-time logs generated during the execution of the simulation tool const logs = ["Simulation log1", "Simulation log2", "Simulation log3"]; // Callback function const callback = agentContext.context.config.callback || { onMessage: async (message: StreamCallbackMessage) => {}, }; // Streaming Message ID const streamId = uuidv4(); for (let i = 0; i < logs.length; i++) { let log = logs[i]; // Callback streaming tool_running message await callback.onMessage({ taskId: agentContext.context.taskId, agentName: agentContext.agent.Name, nodeId: agentContext.agentChain.agent.id, type: "tool_running", toolName: toolCall.toolName, toolId: toolCall.toolCallId, text: log, streamId: streamId, streamDone: false, }); } // Final tool_running message await callback.onMessage({ taskId: agentContext.context.taskId, agentName: agentContext.agent.Name, nodeId: agentContext.agentChain.agent.id, type: "tool_running", toolName: toolCall.toolName, toolId: toolCall.toolCallId, text: logs.join("\n"), streamId: streamId, streamDone: true, }); return { content: [{ type: "text", text: "Successful" }], };}
Specific hook descriptions please refer to: Hook system.