Add persistent local agent tools

This commit is contained in:
Georg Bauer
2026-07-25 14:57:17 +02:00
parent 668d8b787e
commit 4a45735072
20 changed files with 3139 additions and 37 deletions

View File

@@ -312,6 +312,49 @@ impl Drop for ConnectionSlot {
}
}
pub(crate) fn parse_dsml_tool_calls(text: &str) -> Result<(String, Vec<(String, Value)>), String> {
let has_tool_marker = TOOL_SYNTAXES
.iter()
.any(|syntax| text.contains(syntax.tool_start));
let mut projector = ToolProjector::new();
let events = projector.push(text, true, "");
let mut content = String::new();
let mut calls = Vec::<(String, String, bool)>::new();
for event in events {
match event {
ToolProjectionEvent::Text(text) => content.push_str(&text),
ToolProjectionEvent::Start { index, name, .. } => {
if calls.len() == index {
calls.push((name, String::new(), false));
}
}
ToolProjectionEvent::Arguments { index, fragment } => {
if let Some((_, arguments, _)) = calls.get_mut(index) {
arguments.push_str(&fragment);
}
}
ToolProjectionEvent::End { index } => {
if let Some((_, _, complete)) = calls.get_mut(index) {
*complete = true;
}
}
}
}
let calls = calls
.into_iter()
.filter(|(_, _, complete)| *complete)
.map(|(name, arguments, _)| {
serde_json::from_str(&arguments)
.map(|arguments| (name, arguments))
.map_err(|error| format!("invalid DSML tool arguments: {error}"))
})
.collect::<Result<Vec<_>, _>>()?;
if has_tool_marker && calls.is_empty() {
return Err("invalid or incomplete DSML tool call".into());
}
Ok((content, calls))
}
fn handle(mut stream: TcpStream, state: &State) {
let _ = stream.set_write_timeout(Some(HTTP_IO_TIMEOUT));
let started = Instant::now();