diff --git a/docs/loadtools.md b/docs/loadtools.md index 8dfe6be..42f446c 100644 --- a/docs/loadtools.md +++ b/docs/loadtools.md @@ -5,7 +5,7 @@ Tools can be loaded dynamically from `.jl` files in the `src/tools/` directory w ## How It Works 1. `src/tools/registry.jl` defines a `loadTools(dir::String)` function that scans a directory for `.jl` files -2. Each tool file must define a single function: `getTool() :: agentTool` +2. Each tool file must define a single function: `getTool()::agentTool` 3. `loadTools()` sorts files alphabetically, includes each one, calls `getTool()`, and registers the result 4. Loaded tools are returned as `Vector{agentTool}` for use when constructing a `yiemAgent` @@ -15,7 +15,7 @@ Tools can be loaded dynamically from `.jl` files in the `src/tools/` directory w src/ ├── tools/ │ ├── registry.jl # Tool loader (do not edit) -│ ├── get_weather.jl # Your tool +│ ├── getWeather.jl # Your tool │ └── query_db.jl # Another tool ├── type.jl ├── utils.jl @@ -29,10 +29,10 @@ src/ Each `.jl` file in `src/tools/` must define `getTool()` returning an `agentTool`: ```julia -# src/tools/get_weather.jl -function getTool() :: agentTool +# src/tools/getWeather.jl +function getTool()::agentTool return agentTool( - name = "get_weather", + name = "getWeather", label = "Weather Lookup", description = "Fetch current weather and forecast for a given city.", inputSchema = Dict{String,Any}( diff --git a/src/tools/getTime.jl b/src/tools/getTime.jl new file mode 100644 index 0000000..d100f9b --- /dev/null +++ b/src/tools/getTime.jl @@ -0,0 +1,49 @@ +""" +Execute the get_time tool. + +# Arguments +- `toolCallId::String`: Unique identifier for this tool call +- `args::Dict{String,Any}`: Parsed arguments from the LLM +- `signal::Union{Nothing,abortSignal}`: Optional abort signal +- `onPartialResult::Function`: Callback for streaming partial results + +# Returns +- `agentToolResult`: Result content with current time +""" +function executeTool(toolCallId::String, args::Dict{String,Any}, signal::Union{Nothing,abortSignal}, onPartialResult::Function)::agentToolResult + tz = get(args, "timezone", "local") + + t = now() + + if tz == "local" + timeStr = string(t) + else + timeStr = string(t) + end + + return agentToolResult( + [textContent("Current time: $(timeStr)")], + Dict{Any,Any}(), nothing, false + ) +end + +""" +Define and return the get_time agentTool. +""" +function getTool()::agentTool + return agentTool( + name = "get_time", + label = "Get Current Time", + description = "Get the current date and time.", + inputSchema = Dict{String,Any}( + "type" => "object", + "properties" => Dict( + "timezone" => Dict("type" => "string", "description" => "Timezone (currently only 'local' is supported)") + ), + "required" => [] + ), + execute = executeTool, + prepareArguments = nothing, + parallelToolExecute = false + ) +end diff --git a/src/tools/get_weather.jl b/src/tools/getWeather.jl similarity index 89% rename from src/tools/get_weather.jl rename to src/tools/getWeather.jl index 9b23aef..f62cb80 100644 --- a/src/tools/get_weather.jl +++ b/src/tools/getWeather.jl @@ -1,5 +1,5 @@ """ -Execute the get_weather tool. +Execute the getWeather tool. # Arguments - `toolCallId::String`: Unique identifier for this tool call @@ -10,7 +10,7 @@ Execute the get_weather tool. # Returns - `agentToolResult`: Result content with weather data """ -function executeTool(toolCallId::String, args::Dict{String,Any}, signal::Union{Nothing,abortSignal}, onPartialResult::Function) :: agentToolResult +function executeTool(toolCallId::String, args::Dict{String,Any}, signal::Union{Nothing,abortSignal}, onPartialResult::Function)::agentToolResult city = get(args, "city", "") units = get(args, "units", "celsius") @@ -37,11 +37,11 @@ function executeTool(toolCallId::String, args::Dict{String,Any}, signal::Union{N end """ -Define and return the get_weather agentTool. +Define and return the getWeather agentTool. """ -function getTool() :: agentTool +function getTool()::agentTool return agentTool( - name = "get_weather", + name = "getWeather", label = "Weather Lookup", description = "Fetch current weather and forecast for a given city.", inputSchema = Dict{String,Any}( diff --git a/src/tools/registry.jl b/src/tools/registry.jl index b4cb46a..5ce045f 100644 --- a/src/tools/registry.jl +++ b/src/tools/registry.jl @@ -11,17 +11,17 @@ const _registry = Vector{agentTool}() Load all tool modules from a directory. Scans `dir` for `.jl` files. Each file must define a function named -`getTool() :: agentTool`. Files are sorted alphabetically so tool +`getTool()::agentTool`. Files are sorted alphabetically so tool registration order is deterministic. # Tool file format Each `.jl` file defines one function `getTool()` that returns an `agentTool`: ```julia -# src/tools/get_weather.jl -function getTool() :: agentTool +# src/tools/getWeather.jl +function getTool()::agentTool return agentTool( - name = "get_weather", + name = "getWeather", label = "Weather Lookup", description = "Fetch current weather and forecast for a given city.", inputSchema = Dict{String,Any}( @@ -72,10 +72,10 @@ function loadTools(dir::String)::Vector{agentTool} include(filepath) # Validate that getTool was defined (include() places it in current module scope) - if !isdefined(:getTool) + if !isdefined(@__MODULE__, :getTool) throw(ArgumentError( "Tool file $(filepath) does not define a `getTool()` function. " * - "Each tool file must define: function getTool() :: agentTool ... end" + "Each tool file must define: function getTool()::agentTool ... end" )) end diff --git a/src/type.jl b/src/type.jl index 66d4cda..5146870 100644 --- a/src/type.jl +++ b/src/type.jl @@ -215,7 +215,7 @@ Maps MCP server tool definitions to an executable Julia tool. # MCP Tool Example ``` { - "name": "get_weather", + "name": "getWeather", "title": "Weather Lookup", "description": "Fetch current weather and forecast for a given city.", "inputSchema": { @@ -232,7 +232,7 @@ Maps MCP server tool definitions to an executable Julia tool. # Example ```julia tool = agentTool( - name="get_weather", + name="getWeather", label="Weather Lookup", description="Fetch current weather and forecast for a given city.", inputSchema=Dict( diff --git a/src_OLD/OLD_interface.jl b/src_OLD/OLD_interface.jl index 8c1ca5c..5e375d6 100644 --- a/src_OLD/OLD_interface.jl +++ b/src_OLD/OLD_interface.jl @@ -140,14 +140,14 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=3 }, "action_name": { "type": "string", - "enum": ["search_web", "get_weather", "calculate_math"], + "enum": ["search_web", "getWeather", "calculate_math"], "description": "The exact name of the tool to execute." }, "action_input": { "type": "object", "properties": { "query": { "type": ["string", "null"], "description": "For search_web" }, - "location": { "type": ["string", "null"], "description": "For get_weather" }, + "location": { "type": ["string", "null"], "description": "For getWeather" }, "equation": { "type": ["string", "null"], "description": "For calculate_math" } }, "required": ["query", "location", "equation"],