mirror of
https://github.com/openai/codex.git
synced 2026-11-08 20:40:33 +00:00
codex: split rollout response id events
Replace the rollout-only response metadata event with separate ResponsesApiRequestId and ResponsesApiResponseId events so persisted logs do not carry unrelated null fields. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
co-authored by
Codex
parent
21c1cf6a60
commit
4530a28269
@@ -5838,7 +5838,11 @@ impl CodexMessageProcessor {
|
||||
}
|
||||
};
|
||||
let event = event.clone();
|
||||
if matches!(event.msg, EventMsg::ResponseMetadata(_)) {
|
||||
if matches!(
|
||||
event.msg,
|
||||
EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ impl ResponsesWebsocketConnection {
|
||||
rx_event,
|
||||
// Websocket upgrade response headers are scoped to the connection, not
|
||||
// individual `stream_request` calls, so they cannot be used as per-turn
|
||||
// request IDs in rollout `ResponseMetadata`.
|
||||
// request IDs in rollout `ResponsesApiRequestId` events.
|
||||
request_id_for_rollout_log: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -89,7 +89,8 @@ use codex_protocol::protocol::HasLegacyEvent;
|
||||
use codex_protocol::protocol::ItemCompletedEvent;
|
||||
use codex_protocol::protocol::ItemStartedEvent;
|
||||
use codex_protocol::protocol::RawResponseItemEvent;
|
||||
use codex_protocol::protocol::ResponseMetadataEvent;
|
||||
use codex_protocol::protocol::ResponsesApiRequestIdEvent;
|
||||
use codex_protocol::protocol::ResponsesApiResponseIdEvent;
|
||||
use codex_protocol::protocol::ReviewRequest;
|
||||
use codex_protocol::protocol::RolloutItem;
|
||||
use codex_protocol::protocol::SessionSource;
|
||||
@@ -5987,7 +5988,8 @@ fn realtime_text_for_event(msg: &EventMsg) -> Option<String> {
|
||||
| EventMsg::ShutdownComplete
|
||||
| EventMsg::EnteredReviewMode(_)
|
||||
| EventMsg::ExitedReviewMode(_)
|
||||
| EventMsg::ResponseMetadata(_)
|
||||
| EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
| EventMsg::RawResponseItem(_)
|
||||
| EventMsg::ItemStarted(_)
|
||||
| EventMsg::AgentMessageContentDelta(_)
|
||||
@@ -6329,9 +6331,8 @@ async fn try_run_sampling_request(
|
||||
if let Some(request_id) = err.request_id() {
|
||||
sess.send_event(
|
||||
&turn_context,
|
||||
EventMsg::ResponseMetadata(ResponseMetadataEvent {
|
||||
request_id: Some(request_id.to_string()),
|
||||
response_id: None,
|
||||
EventMsg::ResponsesApiRequestId(ResponsesApiRequestIdEvent {
|
||||
request_id: request_id.to_string(),
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
@@ -6343,10 +6344,7 @@ async fn try_run_sampling_request(
|
||||
if let Some(request_id) = stream.request_id_for_rollout_log.clone() {
|
||||
sess.send_event(
|
||||
&turn_context,
|
||||
EventMsg::ResponseMetadata(ResponseMetadataEvent {
|
||||
request_id: Some(request_id),
|
||||
response_id: None,
|
||||
}),
|
||||
EventMsg::ResponsesApiRequestId(ResponsesApiRequestIdEvent { request_id }),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
@@ -6405,9 +6403,8 @@ async fn try_run_sampling_request(
|
||||
if let Some(response_id) = response_id {
|
||||
sess.send_event(
|
||||
&turn_context,
|
||||
EventMsg::ResponseMetadata(ResponseMetadataEvent {
|
||||
request_id: None,
|
||||
response_id: Some(response_id),
|
||||
EventMsg::ResponsesApiResponseId(ResponsesApiResponseIdEvent {
|
||||
response_id,
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -91,7 +91,8 @@ fn event_msg_persistence_mode(ev: &EventMsg) -> Option<EventPersistenceMode> {
|
||||
match ev {
|
||||
EventMsg::UserMessage(_)
|
||||
| EventMsg::AgentMessage(_)
|
||||
| EventMsg::ResponseMetadata(_)
|
||||
| EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
| EventMsg::AgentReasoning(_)
|
||||
| EventMsg::AgentReasoningRawContent(_)
|
||||
| EventMsg::TokenCount(_)
|
||||
|
||||
@@ -180,29 +180,25 @@ async fn rollout_persists_responses_request_and_response_ids() {
|
||||
assert!(lines.iter().any(|line| {
|
||||
matches!(
|
||||
&line.item,
|
||||
RolloutItem::EventMsg(EventMsg::ResponseMetadata(event))
|
||||
if event.request_id.as_deref() == Some("req_123")
|
||||
&& event.response_id.is_none()
|
||||
RolloutItem::EventMsg(EventMsg::ResponsesApiRequestId(event))
|
||||
if event.request_id == "req_123"
|
||||
)
|
||||
}));
|
||||
assert!(lines.iter().any(|line| {
|
||||
matches!(
|
||||
&line.item,
|
||||
RolloutItem::EventMsg(EventMsg::ResponseMetadata(event))
|
||||
if event.request_id.is_none()
|
||||
&& event.response_id.as_deref() == Some("resp_123")
|
||||
RolloutItem::EventMsg(EventMsg::ResponsesApiResponseId(event))
|
||||
if event.response_id == "resp_123"
|
||||
)
|
||||
}));
|
||||
assert!(json_lines.iter().any(|line| {
|
||||
line["type"] == "event_msg"
|
||||
&& line["payload"]["type"] == "response_metadata"
|
||||
&& line["payload"]["type"] == "responses_api_request_id"
|
||||
&& line["payload"]["request_id"] == "req_123"
|
||||
&& line["payload"]["response_id"].is_null()
|
||||
}));
|
||||
assert!(json_lines.iter().any(|line| {
|
||||
line["type"] == "event_msg"
|
||||
&& line["payload"]["type"] == "response_metadata"
|
||||
&& line["payload"]["request_id"].is_null()
|
||||
&& line["payload"]["type"] == "responses_api_response_id"
|
||||
&& line["payload"]["response_id"] == "resp_123"
|
||||
}));
|
||||
}
|
||||
@@ -242,23 +238,21 @@ async fn rollout_persists_request_id_when_responses_request_errors() -> anyhow::
|
||||
})
|
||||
.await?;
|
||||
|
||||
let response_metadata = wait_for_event(&codex, |event| {
|
||||
let request_id_event = wait_for_event(&codex, |event| {
|
||||
matches!(
|
||||
event,
|
||||
EventMsg::ResponseMetadata(metadata)
|
||||
if metadata.request_id.as_deref() == Some("req_error_123")
|
||||
&& metadata.response_id.is_none()
|
||||
EventMsg::ResponsesApiRequestId(metadata)
|
||||
if metadata.request_id == "req_error_123"
|
||||
)
|
||||
})
|
||||
.await;
|
||||
assert!(
|
||||
matches!(
|
||||
&response_metadata,
|
||||
EventMsg::ResponseMetadata(metadata)
|
||||
if metadata.request_id.as_deref() == Some("req_error_123")
|
||||
&& metadata.response_id.is_none()
|
||||
&request_id_event,
|
||||
EventMsg::ResponsesApiRequestId(metadata)
|
||||
if metadata.request_id == "req_error_123"
|
||||
),
|
||||
"expected response metadata with request id; got {response_metadata:?}"
|
||||
"expected request id event; got {request_id_event:?}"
|
||||
);
|
||||
|
||||
let error_event = wait_for_event(&codex, |event| matches!(event, EventMsg::Error(_))).await;
|
||||
@@ -285,16 +279,14 @@ async fn rollout_persists_request_id_when_responses_request_errors() -> anyhow::
|
||||
assert!(lines.iter().any(|line| {
|
||||
matches!(
|
||||
&line.item,
|
||||
RolloutItem::EventMsg(EventMsg::ResponseMetadata(event))
|
||||
if event.request_id.as_deref() == Some("req_error_123")
|
||||
&& event.response_id.is_none()
|
||||
RolloutItem::EventMsg(EventMsg::ResponsesApiRequestId(event))
|
||||
if event.request_id == "req_error_123"
|
||||
)
|
||||
}));
|
||||
assert!(json_lines.iter().any(|line| {
|
||||
line["type"] == "event_msg"
|
||||
&& line["payload"]["type"] == "response_metadata"
|
||||
&& line["payload"]["type"] == "responses_api_request_id"
|
||||
&& line["payload"]["request_id"] == "req_error_123"
|
||||
&& line["payload"]["response_id"].is_null()
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -848,7 +848,8 @@ impl EventProcessor for EventProcessorWithHumanOutput {
|
||||
| EventMsg::ListRemoteSkillsResponse(_)
|
||||
| EventMsg::RemoteSkillDownloaded(_)
|
||||
| EventMsg::RawResponseItem(_)
|
||||
| EventMsg::ResponseMetadata(_)
|
||||
| EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
| EventMsg::UserMessage(_)
|
||||
| EventMsg::EnteredReviewMode(_)
|
||||
| EventMsg::ExitedReviewMode(_)
|
||||
@@ -930,7 +931,8 @@ impl EventProcessorWithHumanOutput {
|
||||
| EventMsg::ListRemoteSkillsResponse(_)
|
||||
| EventMsg::RemoteSkillDownloaded(_)
|
||||
| EventMsg::RawResponseItem(_)
|
||||
| EventMsg::ResponseMetadata(_)
|
||||
| EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
| EventMsg::UserMessage(_)
|
||||
| EventMsg::EnteredReviewMode(_)
|
||||
| EventMsg::ExitedReviewMode(_)
|
||||
|
||||
@@ -789,7 +789,8 @@ fn should_suppress_agent_job_event(msg: &EventMsg) -> bool {
|
||||
| EventMsg::RequestUserInput(_)
|
||||
| EventMsg::DynamicToolCallRequest(_)
|
||||
| EventMsg::DynamicToolCallResponse(_)
|
||||
| EventMsg::ResponseMetadata(_)
|
||||
| EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
| EventMsg::ElicitationRequest(_)
|
||||
| EventMsg::Error(_)
|
||||
| EventMsg::Warning(_)
|
||||
|
||||
@@ -355,7 +355,8 @@ async fn run_codex_tool_session_inner(
|
||||
| EventMsg::ImageGenerationBegin(_)
|
||||
| EventMsg::ImageGenerationEnd(_)
|
||||
| EventMsg::RawResponseItem(_)
|
||||
| EventMsg::ResponseMetadata(_)
|
||||
| EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
| EventMsg::EnteredReviewMode(_)
|
||||
| EventMsg::ItemStarted(_)
|
||||
| EventMsg::ItemCompleted(_)
|
||||
|
||||
@@ -1178,7 +1178,11 @@ pub enum EventMsg {
|
||||
|
||||
#[schemars(skip)]
|
||||
#[ts(skip)]
|
||||
ResponseMetadata(ResponseMetadataEvent),
|
||||
ResponsesApiRequestId(ResponsesApiRequestIdEvent),
|
||||
|
||||
#[schemars(skip)]
|
||||
#[ts(skip)]
|
||||
ResponsesApiResponseId(ResponsesApiResponseIdEvent),
|
||||
|
||||
RawResponseItem(RawResponseItemEvent),
|
||||
|
||||
@@ -1361,11 +1365,13 @@ impl CodexErrorInfo {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, TS, JsonSchema)]
|
||||
pub struct ResponseMetadataEvent {
|
||||
#[serde(default)]
|
||||
pub request_id: Option<String>,
|
||||
#[serde(default)]
|
||||
pub response_id: Option<String>,
|
||||
pub struct ResponsesApiRequestIdEvent {
|
||||
pub request_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, TS, JsonSchema)]
|
||||
pub struct ResponsesApiResponseIdEvent {
|
||||
pub response_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, TS, JsonSchema)]
|
||||
@@ -1980,7 +1986,11 @@ impl InitialHistory {
|
||||
.iter()
|
||||
.filter_map(|ri| match ri {
|
||||
RolloutItem::EventMsg(ev)
|
||||
if !matches!(ev, EventMsg::ResponseMetadata(_)) =>
|
||||
if !matches!(
|
||||
ev,
|
||||
EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
) =>
|
||||
{
|
||||
Some(ev.clone())
|
||||
}
|
||||
@@ -1993,7 +2003,11 @@ impl InitialHistory {
|
||||
.iter()
|
||||
.filter_map(|ri| match ri {
|
||||
RolloutItem::EventMsg(ev)
|
||||
if !matches!(ev, EventMsg::ResponseMetadata(_)) =>
|
||||
if !matches!(
|
||||
ev,
|
||||
EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
) =>
|
||||
{
|
||||
Some(ev.clone())
|
||||
}
|
||||
|
||||
@@ -4830,7 +4830,8 @@ impl ChatWidget {
|
||||
}
|
||||
}
|
||||
EventMsg::RawResponseItem(_)
|
||||
| EventMsg::ResponseMetadata(_)
|
||||
| EventMsg::ResponsesApiRequestId(_)
|
||||
| EventMsg::ResponsesApiResponseId(_)
|
||||
| EventMsg::ItemStarted(_)
|
||||
| EventMsg::AgentMessageContentDelta(_)
|
||||
| EventMsg::ReasoningContentDelta(_)
|
||||
|
||||
Reference in New Issue
Block a user