Skip to content

Commit 6736d18

Browse files
authored
fix: sse for chat (#7594)
1 parent 073a853 commit 6736d18

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

codex-rs/codex-api/src/sse/chat.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,10 @@ pub async fn process_chat_sse<S>(
161161
}
162162

163163
if let Some(func) = tool_call.get("function") {
164-
if let Some(fname) = func.get("name").and_then(|n| n.as_str()) {
165-
call_state.name = Some(fname.to_string());
164+
if let Some(fname) = func.get("name").and_then(|n| n.as_str())
165+
&& !fname.is_empty()
166+
{
167+
call_state.name.get_or_insert_with(|| fname.to_string());
166168
}
167169
if let Some(arguments) = func.get("arguments").and_then(|a| a.as_str())
168170
{
@@ -432,6 +434,47 @@ mod tests {
432434
);
433435
}
434436

437+
#[tokio::test]
438+
async fn preserves_tool_call_name_when_empty_deltas_arrive() {
439+
let delta_with_name = json!({
440+
"choices": [{
441+
"delta": {
442+
"tool_calls": [{
443+
"id": "call_a",
444+
"function": { "name": "do_a" }
445+
}]
446+
}
447+
}]
448+
});
449+
450+
let delta_with_empty_name = json!({
451+
"choices": [{
452+
"delta": {
453+
"tool_calls": [{
454+
"id": "call_a",
455+
"function": { "name": "", "arguments": "{}" }
456+
}]
457+
}
458+
}]
459+
});
460+
461+
let finish = json!({
462+
"choices": [{
463+
"finish_reason": "tool_calls"
464+
}]
465+
});
466+
467+
let body = build_body(&[delta_with_name, delta_with_empty_name, finish]);
468+
let events = collect_events(&body).await;
469+
assert_matches!(
470+
&events[..],
471+
[
472+
ResponseEvent::OutputItemDone(ResponseItem::FunctionCall { name, arguments, .. }),
473+
ResponseEvent::Completed { .. }
474+
] if name == "do_a" && arguments == "{}"
475+
);
476+
}
477+
435478
#[tokio::test]
436479
async fn emits_tool_calls_even_when_content_and_reasoning_present() {
437480
let delta_content_and_tools = json!({

0 commit comments

Comments
 (0)