fix(run): preserve last known response_id on conversation resume (#3245)
This commit is contained in:
@@ -189,8 +189,14 @@ class OpenAIServerConversationTracker:
|
||||
self.sent_initial_input = True
|
||||
self.remaining_initial_input = None
|
||||
|
||||
latest_response = model_responses[-1] if model_responses else None
|
||||
# Pick the most recent response that actually carries an id; live runs preserve the
|
||||
# last-known id via track_server_items, so resume must mirror that behavior instead of
|
||||
# blindly using model_responses[-1] (which may have response_id=None for non-Responses
|
||||
# providers and would silently break the chain).
|
||||
latest_response_id: str | None = None
|
||||
for response in model_responses:
|
||||
if response.response_id is not None:
|
||||
latest_response_id = response.response_id
|
||||
for output_item in response.output:
|
||||
if output_item is None:
|
||||
continue
|
||||
@@ -207,8 +213,8 @@ class OpenAIServerConversationTracker:
|
||||
if isinstance(call_id, str) and has_output_payload:
|
||||
self.server_tool_call_ids.add(call_id)
|
||||
|
||||
if self.conversation_id is None and latest_response and latest_response.response_id:
|
||||
self.previous_response_id = latest_response.response_id
|
||||
if self.conversation_id is None and latest_response_id is not None:
|
||||
self.previous_response_id = latest_response_id
|
||||
|
||||
if session_items:
|
||||
for item in session_items:
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
"""Tests for OpenAIServerConversationTracker.hydrate_from_state response_id seeding."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from agents.items import ModelResponse
|
||||
from agents.run_internal.oai_conversation import OpenAIServerConversationTracker
|
||||
from agents.usage import Usage
|
||||
|
||||
|
||||
def _make_response(response_id: str | None) -> ModelResponse:
|
||||
response = object.__new__(ModelResponse)
|
||||
response.output = []
|
||||
response.usage = Usage()
|
||||
response.response_id = response_id
|
||||
return response
|
||||
|
||||
|
||||
def test_hydrate_from_state_uses_latest_non_none_response_id() -> None:
|
||||
"""Resume should chain to the most recent response_id, not None when last response lacks id.
|
||||
|
||||
A run might produce model responses across providers where some have no `response_id`
|
||||
(e.g., a non-Responses fallback). `track_server_items` skips updates when response_id is
|
||||
None, so live runs preserve the last known id. Resume hydration should match that
|
||||
behavior — falling back to the last id-bearing response instead of forgetting the chain.
|
||||
"""
|
||||
tracker = OpenAIServerConversationTracker(
|
||||
conversation_id=None,
|
||||
previous_response_id=None,
|
||||
auto_previous_response_id=True,
|
||||
)
|
||||
|
||||
responses: list[Any] = [
|
||||
_make_response("resp_first"),
|
||||
_make_response("resp_second"),
|
||||
_make_response(None),
|
||||
]
|
||||
|
||||
tracker.hydrate_from_state(
|
||||
original_input=[],
|
||||
generated_items=[],
|
||||
model_responses=responses,
|
||||
)
|
||||
|
||||
assert tracker.previous_response_id == "resp_second"
|
||||
Reference in New Issue
Block a user