update
This commit is contained in:
+5
-5
@@ -5,7 +5,7 @@ Tools can be loaded dynamically from `.jl` files in the `src/tools/` directory w
|
|||||||
## How It Works
|
## How It Works
|
||||||
|
|
||||||
1. `src/tools/registry.jl` defines a `loadTools(dir::String)` function that scans a directory for `.jl` files
|
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
|
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`
|
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/
|
src/
|
||||||
├── tools/
|
├── tools/
|
||||||
│ ├── registry.jl # Tool loader (do not edit)
|
│ ├── registry.jl # Tool loader (do not edit)
|
||||||
│ ├── get_weather.jl # Your tool
|
│ ├── getWeather.jl # Your tool
|
||||||
│ └── query_db.jl # Another tool
|
│ └── query_db.jl # Another tool
|
||||||
├── type.jl
|
├── type.jl
|
||||||
├── utils.jl
|
├── utils.jl
|
||||||
@@ -29,10 +29,10 @@ src/
|
|||||||
Each `.jl` file in `src/tools/` must define `getTool()` returning an `agentTool`:
|
Each `.jl` file in `src/tools/` must define `getTool()` returning an `agentTool`:
|
||||||
|
|
||||||
```julia
|
```julia
|
||||||
# src/tools/get_weather.jl
|
# src/tools/getWeather.jl
|
||||||
function getTool() :: agentTool
|
function getTool()::agentTool
|
||||||
return agentTool(
|
return agentTool(
|
||||||
name = "get_weather",
|
name = "getWeather",
|
||||||
label = "Weather Lookup",
|
label = "Weather Lookup",
|
||||||
description = "Fetch current weather and forecast for a given city.",
|
description = "Fetch current weather and forecast for a given city.",
|
||||||
inputSchema = Dict{String,Any}(
|
inputSchema = Dict{String,Any}(
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Execute the get_weather tool.
|
Execute the getWeather tool.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `toolCallId::String`: Unique identifier for this tool call
|
- `toolCallId::String`: Unique identifier for this tool call
|
||||||
@@ -10,7 +10,7 @@ Execute the get_weather tool.
|
|||||||
# Returns
|
# Returns
|
||||||
- `agentToolResult`: Result content with weather data
|
- `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", "")
|
city = get(args, "city", "")
|
||||||
units = get(args, "units", "celsius")
|
units = get(args, "units", "celsius")
|
||||||
|
|
||||||
@@ -37,11 +37,11 @@ function executeTool(toolCallId::String, args::Dict{String,Any}, signal::Union{N
|
|||||||
end
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Define and return the get_weather agentTool.
|
Define and return the getWeather agentTool.
|
||||||
"""
|
"""
|
||||||
function getTool() :: agentTool
|
function getTool()::agentTool
|
||||||
return agentTool(
|
return agentTool(
|
||||||
name = "get_weather",
|
name = "getWeather",
|
||||||
label = "Weather Lookup",
|
label = "Weather Lookup",
|
||||||
description = "Fetch current weather and forecast for a given city.",
|
description = "Fetch current weather and forecast for a given city.",
|
||||||
inputSchema = Dict{String,Any}(
|
inputSchema = Dict{String,Any}(
|
||||||
@@ -11,17 +11,17 @@ const _registry = Vector{agentTool}()
|
|||||||
Load all tool modules from a directory.
|
Load all tool modules from a directory.
|
||||||
|
|
||||||
Scans `dir` for `.jl` files. Each file must define a function named
|
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.
|
registration order is deterministic.
|
||||||
|
|
||||||
# Tool file format
|
# Tool file format
|
||||||
Each `.jl` file defines one function `getTool()` that returns an `agentTool`:
|
Each `.jl` file defines one function `getTool()` that returns an `agentTool`:
|
||||||
|
|
||||||
```julia
|
```julia
|
||||||
# src/tools/get_weather.jl
|
# src/tools/getWeather.jl
|
||||||
function getTool() :: agentTool
|
function getTool()::agentTool
|
||||||
return agentTool(
|
return agentTool(
|
||||||
name = "get_weather",
|
name = "getWeather",
|
||||||
label = "Weather Lookup",
|
label = "Weather Lookup",
|
||||||
description = "Fetch current weather and forecast for a given city.",
|
description = "Fetch current weather and forecast for a given city.",
|
||||||
inputSchema = Dict{String,Any}(
|
inputSchema = Dict{String,Any}(
|
||||||
@@ -72,10 +72,10 @@ function loadTools(dir::String)::Vector{agentTool}
|
|||||||
include(filepath)
|
include(filepath)
|
||||||
|
|
||||||
# Validate that getTool was defined (include() places it in current module scope)
|
# Validate that getTool was defined (include() places it in current module scope)
|
||||||
if !isdefined(:getTool)
|
if !isdefined(@__MODULE__, :getTool)
|
||||||
throw(ArgumentError(
|
throw(ArgumentError(
|
||||||
"Tool file $(filepath) does not define a `getTool()` function. " *
|
"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
|
end
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -215,7 +215,7 @@ Maps MCP server tool definitions to an executable Julia tool.
|
|||||||
# MCP Tool Example
|
# MCP Tool Example
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"name": "get_weather",
|
"name": "getWeather",
|
||||||
"title": "Weather Lookup",
|
"title": "Weather Lookup",
|
||||||
"description": "Fetch current weather and forecast for a given city.",
|
"description": "Fetch current weather and forecast for a given city.",
|
||||||
"inputSchema": {
|
"inputSchema": {
|
||||||
@@ -232,7 +232,7 @@ Maps MCP server tool definitions to an executable Julia tool.
|
|||||||
# Example
|
# Example
|
||||||
```julia
|
```julia
|
||||||
tool = agentTool(
|
tool = agentTool(
|
||||||
name="get_weather",
|
name="getWeather",
|
||||||
label="Weather Lookup",
|
label="Weather Lookup",
|
||||||
description="Fetch current weather and forecast for a given city.",
|
description="Fetch current weather and forecast for a given city.",
|
||||||
inputSchema=Dict(
|
inputSchema=Dict(
|
||||||
|
|||||||
@@ -140,14 +140,14 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=3
|
|||||||
},
|
},
|
||||||
"action_name": {
|
"action_name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["search_web", "get_weather", "calculate_math"],
|
"enum": ["search_web", "getWeather", "calculate_math"],
|
||||||
"description": "The exact name of the tool to execute."
|
"description": "The exact name of the tool to execute."
|
||||||
},
|
},
|
||||||
"action_input": {
|
"action_input": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"query": { "type": ["string", "null"], "description": "For search_web" },
|
"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" }
|
"equation": { "type": ["string", "null"], "description": "For calculate_math" }
|
||||||
},
|
},
|
||||||
"required": ["query", "location", "equation"],
|
"required": ["query", "location", "equation"],
|
||||||
|
|||||||
Reference in New Issue
Block a user