add action type to responses header

This commit is contained in:
kevin zhao
2025-10-07 17:20:27 -07:00
parent b8b04514bc
commit c1a2be732e
5 changed files with 25 additions and 1 deletions

View File

@@ -244,7 +244,12 @@ impl ModelClient {
let max_attempts = self.provider.request_max_retries();
for attempt in 0..=max_attempts {
match self
.attempt_stream_responses(attempt, &payload_json, &auth_manager)
.attempt_stream_responses(
attempt,
&payload_json,
&auth_manager,
prompt.is_review_turn,
)
.await
{
Ok(stream) => {
@@ -272,6 +277,7 @@ impl ModelClient {
attempt: u64,
payload_json: &Value,
auth_manager: &Option<Arc<AuthManager>>,
is_review_turn: bool,
) -> std::result::Result<ResponseStream, StreamAttemptError> {
// Always fetch the latest auth in case a prior attempt refreshed the token.
let auth = auth_manager.as_ref().and_then(|m| m.auth());
@@ -293,6 +299,10 @@ impl ModelClient {
// Send session_id for compatibility.
.header("conversation_id", self.conversation_id.to_string())
.header("session_id", self.conversation_id.to_string())
.header(
"action_kind",
if is_review_turn { "review" } else { "turn" },
)
.header(reqwest::header::ACCEPT, "text/event-stream")
.json(payload_json);

View File

@@ -41,6 +41,9 @@ pub struct Prompt {
/// Optional the output schema for the model's response.
pub output_schema: Option<Value>,
/// Marks whether this prompt is part of a review turn.
pub is_review_turn: bool,
}
impl Prompt {

View File

@@ -1950,6 +1950,7 @@ async fn run_turn(
parallel_tool_calls,
base_instructions_override: turn_context.base_instructions.clone(),
output_schema: turn_context.final_output_json_schema.clone(),
is_review_turn: turn_context.is_review_mode,
};
let mut retries = 0;

View File

@@ -349,12 +349,14 @@ async fn includes_conversation_id_and_model_headers_in_request() {
let request_conversation_id = request.headers.get("conversation_id").unwrap();
let request_authorization = request.headers.get("authorization").unwrap();
let request_originator = request.headers.get("originator").unwrap();
let turn_kind = request.headers.get("action_kind").unwrap();
assert_eq!(
request_conversation_id.to_str().unwrap(),
conversation_id.to_string()
);
assert_eq!(request_originator.to_str().unwrap(), "codex_cli_rs");
assert_eq!(turn_kind.to_str().unwrap(), "turn");
assert_eq!(
request_authorization.to_str().unwrap(),
"Bearer Test API Key"

View File

@@ -118,6 +118,14 @@ async fn review_op_emits_lifecycle_and_review_output() {
assert_eq!(expected, review);
let _complete = wait_for_event(&codex, |ev| matches!(ev, EventMsg::TaskComplete(_))).await;
// Assert header marks this as a review turn.
let request = &server.received_requests().await.unwrap()[0];
let turn_kind = request
.headers
.get("action_kind")
.expect("missing action_kind header");
assert_eq!(turn_kind.to_str().unwrap(), "review");
// Also verify that a user message with the header and a formatted finding
// was recorded back in the parent session's rollout.
codex.submit(Op::GetPath).await.unwrap();