///|
pub trait ToToolResult {
fn to_tool_result(Self) -> @tool.ToolResult
}
///|
pub impl ToToolResult for String with fn to_tool_result(self : String) -> @tool.ToolResult {
@tool.ToolResult::text(self)
}
///|
pub impl ToToolResult for Int with fn to_tool_result(self : Int) -> @tool.ToolResult {
@tool.ToolResult::text(self.to_string())
}
///|
pub impl ToToolResult for Bool with fn to_tool_result(self : Bool) -> @tool.ToolResult {
@tool.ToolResult::text(self.to_string())
}
///|
pub impl ToToolResult for Double with fn to_tool_result(self : Double) -> @tool.ToolResult {
@tool.ToolResult::text(self.to_string())
}
///|
pub impl ToToolResult for @tool.ToolResult with fn to_tool_result(
self : @tool.ToolResult,
) -> @tool.ToolResult {
self
}
///|
pub impl ToToolResult for Unit with fn to_tool_result(_self : Unit) -> @tool.ToolResult {
@tool.ToolResult::text("ok")
}
///|
pub(all) struct ToolWrapper {
name_impl : () -> String
description_impl : () -> String
params_impl : () -> Array[@tool.ParamDef]
execute_impl : (Json) -> @tool.ToolResult
}
///|
pub impl @tool.Tool for ToolWrapper with fn name(self) -> String {
(self.name_impl)()
}
///|
pub impl @tool.Tool for ToolWrapper with fn description(self) -> String {
(self.description_impl)()
}
///|
pub impl @tool.Tool for ToolWrapper with fn params(self) -> Array[
@tool.ParamDef,
] {
(self.params_impl)()
}
///|
pub impl @tool.Tool for ToolWrapper with fn execute(self, json) -> @tool.ToolCallOutcome {
// ToolWrapper wraps a simple complete-or-error handler; it never triggers
// MRTR input_required on its own.
@tool.ToolCallOutcome::Complete((self.execute_impl)(json))
}
///|
pub fn[Args : Params, Ret : ToToolResult] tool_fn(
handler : (Args) -> Ret,
name~ : String,
description~ : String,
) -> ToolWrapper {
let arg_schema = Args::schema()
{
name_impl: fn() -> String { name },
description_impl: fn() -> String { description },
params_impl: fn() -> Array[@tool.ParamDef] {
let mut params : Array[@tool.ParamDef] = []
match arg_schema.properties {
Some(props) => {
let required = match arg_schema.required {
Some(r) => r
None => []
}
for name, prop_schema in props {
let type_str = prop_schema.type_name
let is_required = required.contains(name)
params = params +
[
{
name,
description: prop_schema.description,
type_: type_str,
required: is_required,
},
]
}
}
None => ()
}
params
},
execute_impl: fn(json) -> @tool.ToolResult {
try {
let args = Args::from_json(json)
let result = handler(args)
result.to_tool_result()
} catch {
ToolError(msg) => @tool.ToolResult::error("Parameter error: " + msg)
}
},
}
}
///|
pub fn simple_tool(
name : String,
description : String,
handler : (Json) -> @tool.ToolResult,
) -> ToolWrapper {
{
name_impl: fn() -> String { name },
description_impl: fn() -> String { description },
params_impl: fn() -> Array[@tool.ParamDef] { [] },
execute_impl: handler,
}
}