Skip to content

Commit 1ed877f

Browse files
authored
feat: add mistral and phi4 tool parser (#2510)
1 parent c5d9d26 commit 1ed877f

File tree

2 files changed

+361
-9
lines changed

2 files changed

+361
-9
lines changed

lib/llm/src/postprocessor/tool_calling/json_parser.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,26 @@ fn handle_single_token_tool_calls(input: &str, start_token: &str) -> String {
7474
continue;
7575
}
7676
// Only consider segments that start like JSON
77-
if s.starts_with('{') || s.starts_with('[') {
77+
if s.starts_with('{') {
7878
// Trim trailing non-JSON by cutting at the last closing brace/bracket
79-
if let Some(pos) = s.rfind(['}', ']']) {
80-
let candidate = &s[..=pos];
79+
if let Some(pos) = s.rfind('}') {
80+
let candidate = &s[..=pos].trim();
8181
// Keep only valid JSON candidates
8282
if serde_json::from_str::<serde_json::Value>(candidate).is_ok() {
8383
items.push(candidate.to_string());
8484
}
8585
}
8686
}
8787
}
88-
8988
if items.is_empty() {
90-
return input.to_string();
89+
// Remove everything up to and including the first occurrence of the start token
90+
if let Some(idx) = input.find(start_token) {
91+
let rest = &input[idx + start_token.len()..];
92+
return rest.trim_start().to_string();
93+
} else {
94+
// Shouldn't happen because we checked contains() above, but be defensive
95+
return input.to_string();
96+
}
9197
}
9298
format!("[{}]", items.join(","))
9399
}
@@ -167,7 +173,7 @@ pub fn try_tool_call_parse_json(
167173
};
168174
}
169175

170-
// Convert json to &str if it's a String, otherwise keep as &str
176+
// Convert json (String) to &str
171177
let json = json.as_str();
172178

173179
// Anonymous function to attempt deserialization into a known representation

0 commit comments

Comments
 (0)