Files
YiemAgent/test/toolTest.jl
T
2026-08-09 12:31:57 +07:00

117 lines
4.7 KiB
Julia

using Test
using YiemAgent
using YiemAgent.toolRegistry
using YiemAgent.type
TOOLS_DIR = joinpath(@__DIR__, "..", "src", "tools")
@testset "loadTools" begin
# ------------------------------------------------------------------ #
# 1. loadTools throws on non-existent directory #
# ------------------------------------------------------------------ #
@test_throws ArgumentError loadTools("/nonexistent/dir/that/does/not/exist")
# ------------------------------------------------------------------ #
# 2. loadTools throws if a .jl file does not define getTool() #
# ------------------------------------------------------------------ #
bad_dir = mktempdir()
write(joinpath(bad_dir, "noTool.jl"), "x = 42\n")
@test_throws ArgumentError loadTools(bad_dir)
# ------------------------------------------------------------------ #
# 3. Load all tools from src/tools/ #
# ------------------------------------------------------------------ #
clearTools()
loaded = loadTools(TOOLS_DIR)
@test !isempty(loaded)
@test length(loaded) == 3 # getTime.jl, getWeather.jl, writeTool.jl
# ------------------------------------------------------------------ #
# 4. Each loaded tool has an isolated _tool_module #
# ------------------------------------------------------------------ #
for tool in loaded
@test tool._tool_module isa Module
end
# Verify modules are unique (not shared)
modules = [t._tool_module for t in loaded]
@test length(unique(modules)) == length(modules)
# ------------------------------------------------------------------ #
# 5. Each tool's executeTool is callable #
# ------------------------------------------------------------------ #
function run_all_execution_tests(loaded)
sig = nothing
op = x -> x # no-op partial result callback
for tool in loaded
@test tool.execute !== nothing
@test tool._tool_module isa Module
# Verify the module actually defines executeTool
@test isdefined(tool._tool_module, :executeTool)
# Execute the tool — must return agentToolResult without throwing
result = try
tool.execute("call-$(tool.name)", Dict{String,Any}("city" => "Tokyo"), sig, op)
catch err
tool.execute("call-$(tool.name)", Dict{String,Any}(), sig, op)
end
@test result isa agentToolResult
@test result.content[1] isa textContent
end
end
run_all_execution_tests(loaded)
# ------------------------------------------------------------------ #
# 6. Specific tool assertions based on known tool names #
# ------------------------------------------------------------------ #
time_tool = filter(t -> t.name == "getTime", loaded)
@test !isempty(time_tool)
@test time_tool[1].validateRequiredArgs !== nothing
getWeather_tool = filter(t -> t.name == "getWeather", loaded)
@test !isempty(getWeather_tool)
@test getWeather_tool[1].inputSchema["required"] == ["city"]
write_tool = filter(t -> t.name == "writeTool", loaded)
@test !isempty(write_tool)
@test "name" in write_tool[1].inputSchema["required"]
# ------------------------------------------------------------------ #
# 7. getTools / registerTool / clearTools #
# ------------------------------------------------------------------ #
registry_tools = getTools()
@test !isempty(registry_tools)
@test length(registry_tools) == 3 # only the loaded tools
clearTools()
@test isempty(getTools())
test_tool = agentTool(
name = "manualTool",
label = "Manual Tool",
description = "Registered manually",
inputSchema = Dict{String,Any}("type" => "object", "properties" => Dict{String,Any}(), "required" => Any[]),
execute = (toolCallId, args, signal, onPartialResult) ->
agentToolResult([textContent("manual")], Dict{Any,Any}(), nothing, false),
prepareArguments = nothing,
validateRequiredArgs = nothing,
parallelToolExecute = true,
_tool_module = nothing
)
registerTool(test_tool)
reg = getTools()
@test any(t -> t.name == "manualTool", reg)
@test count(t -> t.name == "manualTool", reg) == 1
@test reg[1].parallelToolExecute == true
@test reg[1]._tool_module === nothing
# ------------------------------------------------------------------ #
# 8. getTools returns new vector (mutations don't affect registry) #
# ------------------------------------------------------------------ #
clearTools()
@test isempty(getTools())
end