mod render;
mod sdm;
use crate::tool_parser::ToolDefinition;
pub fn compile_tools(tools: &[ToolDefinition]) -> String {
let mut out = String::new();
for (i, tool) in tools.iter().enumerate() {
if i > 0 {
out.push('\n');
}
out.push_str(&render::compile_one(tool));
}
out
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tool_parser::{FunctionDefinition, ToolDefinition};
fn tool(name: &str, desc: &str, params: serde_json::Value) -> ToolDefinition {
ToolDefinition {
tool_type: "function".to_string(),
function: FunctionDefinition {
name: name.to_string(),
description: Some(desc.to_string()),
parameters: Some(params),
},
}
}
#[test]
fn compiles_basic_signature() {
let t = tool(
"search_files",
"Search project files by content or filename pattern",
serde_json::json!({
"type": "object",
"properties": {
"query": {"type": "string", "description": "The search query string"},
"path": {"type": "string", "description": "Optional directory path"}
},
"required": ["query"]
}),
);
let out = compile_tools(std::slice::from_ref(&t));
assert!(
out.starts_with("search_files(query:str path?:str)"),
"got: {out}"
);
assert!(out.contains("\n|"), "got: {out}");
assert!(out.len() < serde_json::to_string(&t).unwrap().len());
}
#[test]
fn empty_tool_list_is_empty() {
assert_eq!(compile_tools(&[]), "");
}
#[test]
fn a_default_model_does_not_compile_its_schemas() {
assert!(!crate::tool_parser::PromptLevers::default().tscg);
}
}