mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-16 13:34:04 +08:00
fix(codex): restore cached tool call fields (#4160)
* fix(codex): restore cached tool call fields * refactor(codex): merge duplicate enrich loops in chat history enrich_call_item_from_cache copied the fill-if-empty loop for reasoning_content/reasoning. The two loops are identical and key order is irrelevant, so fold both key sets into a single loop. Pure refactor, no behavior change; codex_chat_history tests pass. --------- Co-authored-by: Jason <farion1231@gmail.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
3e38889ccc
commit
36b557b2e6
@@ -1350,7 +1350,7 @@ impl RequestForwarder {
|
||||
.await;
|
||||
if restored > 0 {
|
||||
log::debug!(
|
||||
"[Codex] Restored {restored} cached function call(s) for Chat upstream"
|
||||
"[Codex] Restored or enriched {restored} cached function call item(s) for Chat upstream"
|
||||
);
|
||||
}
|
||||
super::providers::apply_codex_chat_upstream_model(provider, &mut mapped_body);
|
||||
|
||||
@@ -150,7 +150,7 @@ impl CodexChatHistoryStore {
|
||||
Some(item_type) if is_call_item_type(item_type) => {
|
||||
if let Some(call_id) = response_item_call_id(&item) {
|
||||
if let Some(cached) = lookup.call(&call_id) {
|
||||
if enrich_call_item_reasoning(&mut item, cached) {
|
||||
if enrich_call_item_from_cache(&mut item, cached) {
|
||||
enriched += 1;
|
||||
}
|
||||
}
|
||||
@@ -466,17 +466,26 @@ fn is_call_output_item_type(item_type: &str) -> bool {
|
||||
)
|
||||
}
|
||||
|
||||
fn enrich_call_item_reasoning(item: &mut Value, cached: &Value) -> bool {
|
||||
fn enrich_call_item_from_cache(item: &mut Value, cached: &Value) -> bool {
|
||||
let mut changed = false;
|
||||
for key in ["reasoning_content", "reasoning"] {
|
||||
for key in [
|
||||
"name",
|
||||
"namespace",
|
||||
"arguments",
|
||||
"input",
|
||||
"status",
|
||||
"execution",
|
||||
"reasoning_content",
|
||||
"reasoning",
|
||||
] {
|
||||
if item.get(key).is_some_and(|value| !is_empty_value(value)) {
|
||||
continue;
|
||||
}
|
||||
let Some(reasoning) = cached.get(key).filter(|value| !is_empty_value(value)) else {
|
||||
let Some(value) = cached.get(key).filter(|value| !is_empty_value(value)) else {
|
||||
continue;
|
||||
};
|
||||
if let Some(object) = item.as_object_mut() {
|
||||
object.insert(key.to_string(), reasoning.clone());
|
||||
object.insert(key.to_string(), value.clone());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -675,6 +684,48 @@ mod tests {
|
||||
assert_eq!(input.len(), 2);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn enriches_existing_function_call_missing_name_and_arguments() {
|
||||
let history = CodexChatHistoryStore::default();
|
||||
history
|
||||
.record_response(&json!({
|
||||
"id": "resp_1",
|
||||
"output": [
|
||||
{
|
||||
"type": "function_call",
|
||||
"call_id": "call_1",
|
||||
"name": "read_file",
|
||||
"arguments": "{\"path\":\"README.md\"}",
|
||||
"reasoning_content": "Need to inspect the file."
|
||||
}
|
||||
]
|
||||
}))
|
||||
.await;
|
||||
|
||||
let mut request = json!({
|
||||
"previous_response_id": "resp_1",
|
||||
"input": [
|
||||
{
|
||||
"type": "function_call",
|
||||
"call_id": "call_1"
|
||||
},
|
||||
{
|
||||
"type": "function_call_output",
|
||||
"call_id": "call_1",
|
||||
"output": "ok"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
assert_eq!(history.enrich_request(&mut request).await, 1);
|
||||
let input = request["input"].as_array().unwrap();
|
||||
assert_eq!(input[0]["type"], "function_call");
|
||||
assert_eq!(input[0]["name"], "read_file");
|
||||
assert_eq!(input[0]["arguments"], "{\"path\":\"README.md\"}");
|
||||
assert_eq!(input[0]["reasoning_content"], "Need to inspect the file.");
|
||||
assert_eq!(input[1]["type"], "function_call_output");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn restores_parallel_tool_calls_as_one_assistant_group() {
|
||||
let history = CodexChatHistoryStore::default();
|
||||
|
||||
Reference in New Issue
Block a user