diff --git a/agent/auxiliary_client.py b/agent/auxiliary_client.py index 7cb8f9f52e..8052d020ed 100644 --- a/agent/auxiliary_client.py +++ b/agent/auxiliary_client.py @@ -260,11 +260,44 @@ class _CodexCompletionsAdapter: usage = None try: + # Collect output items and text deltas during streaming — + # the Codex backend can return empty response.output from + # get_final_response() even when items were streamed. + collected_output_items: List[Any] = [] + collected_text_deltas: List[str] = [] with self._client.responses.stream(**resp_kwargs) as stream: for _event in stream: - pass + _etype = getattr(_event, "type", "") + if _etype == "response.output_item.done": + _done = getattr(_event, "item", None) + if _done is not None: + collected_output_items.append(_done) + elif "output_text.delta" in _etype: + _delta = getattr(_event, "delta", "") + if _delta: + collected_text_deltas.append(_delta) final = stream.get_final_response() + # Backfill empty output from collected stream events + _output = getattr(final, "output", None) + if isinstance(_output, list) and not _output: + if collected_output_items: + final.output = list(collected_output_items) + logger.debug( + "Codex auxiliary: backfilled %d output items from stream events", + len(collected_output_items), + ) + elif collected_text_deltas: + assembled = "".join(collected_text_deltas) + final.output = [SimpleNamespace( + type="message", role="assistant", status="completed", + content=[SimpleNamespace(type="output_text", text=assembled)], + )] + logger.debug( + "Codex auxiliary: synthesized from %d deltas (%d chars)", + len(collected_text_deltas), len(assembled), + ) + # Extract text and tool calls from the Responses output for item in getattr(final, "output", []): item_type = getattr(item, "type", None)