fix(ai-formats): preserve OpenAI tool call item ids

This commit is contained in:
zhefox
2026-06-17 04:05:09 +08:00
parent 6ab08f4014
commit 3a3fcbe46a
3 changed files with 15 additions and 1 deletions
@@ -1431,6 +1431,7 @@ mod tests {
assert_eq!(body["input"].as_array().expect("input").len(), 2);
assert_eq!(body["input"][0]["type"], "function_call");
assert_eq!(body["input"][0]["id"], "fc_call_auto_0");
assert_eq!(body["input"][0]["call_id"], "call_auto_0");
assert_eq!(body["input"][0]["name"], "unknown");
assert_eq!(body["input"][0]["arguments"], "{\"q\":\"rust\"}");
@@ -2580,6 +2580,7 @@ mod tests {
.value;
assert_eq!(converted["input"][0]["type"], "function_call");
assert_eq!(converted["input"][0]["id"], "fc_call_lookup_1");
assert_eq!(converted["input"][0]["call_id"], "call_lookup_1");
assert_eq!(converted["input"][1]["type"], "function_call_output");
assert_eq!(converted["input"][1]["call_id"], "call_lookup_1");
@@ -795,15 +795,27 @@ pub(crate) fn canonical_tool_use_to_openai_responses_item(
"input": openai_custom_tool_input_text(input),
});
}
let item_id = openai_responses_function_call_item_id(id);
json!({
"type": "function_call",
"id": id,
"id": item_id,
"call_id": id,
"name": name,
"arguments": canonicalize_tool_arguments(input),
})
}
fn openai_responses_function_call_item_id(call_id: &str) -> String {
let trimmed = call_id.trim();
if trimmed.starts_with("fc") {
trimmed.to_string()
} else if trimmed.is_empty() {
"fc_auto".to_string()
} else {
format!("fc_{trimmed}")
}
}
fn openai_responses_hosted_tool_call_item_type(
extensions: &BTreeMap<String, Value>,
) -> Option<&str> {