#Tool Package

    The tool package provides the core abstractions for defining and executing tools that the AI agent can call.

    #Core Types

    #ToolDesc

    Describes a tool's interface for the AI model.

    ///|
    pub struct ToolDesc {
    description : String
    name : String
    schema : JsonSchema
    } derive(ToJson, Eq, Show)

    Fields:
    • description: Human-readable description for the AI
    • name: Unique identifier for the tool
    • schema: JSON Schema defining the expected parameters

    #Tool[Output]

    A tool with its execution function.

    ///|
    pub struct Tool[Output] {
    desc : ToolDesc
    // private: f : ToolFn[Output]
    }

    #ToolFn[Output]

    The function type for tool execution.

    ///|
    pub(all) struct ToolFn[Output](async (Json) -> ToolResult[Output] noraise)

    #ToolResult[Output]

    Result of a tool execution.

    ///|
    pub enum ToolResult[Output] {
    Ok(Output)
    Error(Error, String)
    } derive(ToJson)

    #AgentTool

    A tool adapted for agent use (output is JSON + rendered string).

    ///|
    type AgentTool // Wraps Tool[(Json, String)]

    #JsonSchema

    Wrapper for JSON Schema validation.

    ///|
    pub(all) struct JsonSchema(Json)

    #Key APIs

    #Tool Creation

    pub fn[Output] Tool::new(
    description~ : String,
    name~ : String,
    schema~ : JsonSchema,
    f : ToolFn[Output],
    ) -> Tool[Output]

    #Tool Execution

    pub async fn[Output] Tool::call(
    tool : Tool[Output],
    args : Json,
    ) -> ToolResult[Output] noraise

    #Result Constructors

    pub fn[Output] ToolResult::ok(output : Output) -> ToolResult[Output]
    pub fn[Output] ToolResult::error(
    output : String,
    error? : Error,
    ) -> ToolResult[Output]

    #Conversion to AgentTool

    pub fn[Output : ToJson + Show] Tool::to_agent_tool(
    self : Tool[Output],
    ) -> AgentTool

    #OpenAI Conversion

    pub fn ToolDesc::to_openai(
    tool_desc : ToolDesc,
    ) -> @openai.ChatCompletionToolParam

    #Creating a Custom Tool

    // Define the output type

    ///|
    struct WeatherOutput {
    temperature : Double
    conditions : String
    } derive(ToJson, Show)

    // Define the JSON schema

    ///|
    let weather_schema : @tool.JsonSchema = {
    "type": "object",
    "properties": { "location": { "type": "string", "description": "City name" } },
    "required": ["location"],
    }

    // Create the tool

    ///|
    let weather_tool : @tool.Tool[WeatherOutput] = @tool.new(
    description="Get current weather for a location",
    name="get_weather",
    schema=weather_schema,
    @tool.ToolFn(async fn(args) -> @tool.ToolResult[WeatherOutput] noraise {
    guard args is { "location": String(location), .. } else {
    return @tool.error("Missing 'location' parameter")
    }

    // Simulate weather API call
    @tool.ok({ temperature: 72.5, conditions: "Sunny" })
    }),
    )

    // Convert for agent use

    ///|
    let agent_tool = weather_tool.to_agent_tool()

    #Tool Execution Flow

    AI Model │ ▼ Tool Call Request (JSON arguments) │ ▼ Tool::call(args) │ ├─► Validate args against schema │ ├─► Execute ToolFn │ ▼ ToolResult │ ├─► Ok(Output) ──► to_json() ──► Return to AI │ └─► Error(Error, String) ──► Return error message

    #AgentTool vs Tool[Output]

    • Tool[Output]: Generic tool with custom output type
    • AgentTool: Tool adapted for agent use with (Json, String) output
      • Json: Structured result for AI consumption
      • String: Human-readable rendering

    The to_agent_tool() method handles this conversion automatically.

    #Usage with Agent

    // Create tools
    let cmd_tool = @execute_command.new(job_manager).to_agent_tool()
    let file_tool = @read_file.new(file_manager).to_agent_tool()

    // Add to agent
    agent.add_tools([cmd_tool, file_tool])

    #Dependencies

    • openai: OpenAI API types for conversion
    • json: JSON handling

    AgentTool

    type AgentTool

    AgentTool::call

    async fn AgentTool::call(self : AgentTool, args : Json) -> ToolResult[(Json, String)] noraise

    AgentTool::desc

    fn AgentTool::desc(self : AgentTool) -> ToolDesc

    JsonSchema

    pub(all) struct JsonSchema(Json) derive(Eq,
    Debug
    )

    JsonSchema::from_json

    fn JsonSchema::from_json(schema : Json) -> JsonSchema

    Tool

    pub struct Tool[Output] {
    desc : ToolDesc
    // private fields
    }

    Tool::call

    #as_free_fn
    async fn[Output] Tool::call(tool : Tool[Output], args : Json) -> ToolResult[Output] noraise

    Tool::new

    #as_free_fn
    fn[Output] Tool::new(description~ : String, name~ : String, schema~ : JsonSchema, f : ToolFn[Output]) -> Tool[Output]

    • description: Tool description that can be read by the LLM.
    • name: Tool name used by the LLM to call the tool.
    • schema: JSON schema to validate LLM-generated output and provide type information to the LLM. schema should be an object type. Related issue: #258
    • f: Function whose input must conform to the schema defined above.

    Tool::to_agent_tool

    fn[Output : ToJson] Tool::to_agent_tool(self : Tool[Output]) -> AgentTool

    Convert a Tool[Output] to Tool[Json] by converting outputs to Json

    ToolDesc

    pub struct ToolDesc {
    description : String
    name : String
    schema : JsonSchema
    } derive(Eq, ToJson,
    Debug
    )

    ToolFn

    pub(all) struct ToolFn[Output](async (Json) -> ToolResult[Output] noraise)

    ToolResult

    pub enum ToolResult[Output] {
    Ok(Output)
    Error(Error, String)
    } derive(ToJson)

    impl Show for ToolResult[Output]

    ToolResult::error

    #as_free_fn
    fn[Output] ToolResult::error(output : String, error? : Error) -> ToolResult[Output]

    ToolResult::ok

    #as_free_fn
    fn[Output] ToolResult::ok(output : Output) -> ToolResult[Output]

    tool_desc

    fn tool_desc(description~ : String, name~ : String, schema~ : JsonSchema) -> ToolDesc