| 7823 | &r->tool_orders); |
| 7824 | wrote = true; |
| 7825 | } |
| 7826 | } |
| 7827 | buf_putc(&b, ']'); |
| 7828 | buf_puts(&b, ",\"usage\":"); |
| 7829 | append_responses_usage_json(&b, r, prompt_tokens, completion_tokens); |
| 7830 | buf_puts(&b, "}}"); |
| 7831 | bool ok = responses_sse_emit_event(fd, st, b.ptr); |
| 7832 | buf_free(&b); |
| 7833 | return ok; |
| 7834 | } |
| 7835 | |
| 7836 | /* Responses streaming consumes the same raw token text the OpenAI live stream |
| 7837 | * consumes: <think>...</think> is reasoning, anything before the tool-call |
| 7838 | * marker is output text. Tool-call argument deltas are not surfaced because |
| 7839 | * Codex' SSE parser only ingests function_call items via output_item.done. */ |
| 7840 | static bool responses_sse_stream_update(int fd, const request *r, |
| 7841 | responses_stream *st, |
| 7842 | const char *raw, size_t raw_len, |
| 7843 | bool final) { |
| 7844 | if (!st->active || !raw) return true; |
| 7845 | |
| 7846 | /* The client only sees reasoning if it explicitly opted in via |
no test coverage detected