mirror of
https://github.com/openai/codex.git
synced 2026-10-22 17:58:46 +00:00
Support client Responses API metadata in thread/sample (#56031)
## What changed Add optional `responsesapiClientMetadata` to `ThreadSampleParams` and forward it to the sample turn's Responses API metadata. Update the experimental protocol schema. ## Testing Extend the thread sample integration test to verify that client metadata appears in both the request header and body, preserves the explicit `turn_trigger` when client metadata supplies a conflicting value, and does not carry over to the next parent turn. GitOrigin-RevId: eb1f80824d476fc6c584a2b35d97e59d51fd4273
This commit is contained in:
BIN
Binary file not shown.
@@ -6,6 +6,7 @@ use crate::TS;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -21,6 +22,9 @@ pub struct ThreadSampleParams {
|
||||
pub effort: Option<ReasoningEffort>,
|
||||
#[ts(optional = nullable)]
|
||||
pub turn_trigger: Option<String>,
|
||||
/// Optional metadata to enrich Codex's ResponsesAPI turn metadata.
|
||||
#[ts(optional = nullable)]
|
||||
pub responsesapi_client_metadata: Option<HashMap<String, String>>,
|
||||
/// Disable MCP servers when the inherited window uses incremental tools on Responses Lite.
|
||||
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||
pub disable_mcp: bool,
|
||||
|
||||
@@ -259,6 +259,7 @@ impl SampleTask {
|
||||
turn_trigger: params.turn_trigger,
|
||||
..Default::default()
|
||||
})
|
||||
.with_responses_metadata(params.responsesapi_client_metadata)
|
||||
.with_trace(trace);
|
||||
if !matches!(
|
||||
fork.thread
|
||||
|
||||
@@ -40,6 +40,7 @@ use core_test_support::skip_if_remote;
|
||||
use pretty_assertions::assert_eq;
|
||||
use serde_json::Value;
|
||||
use serde_json::json;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tempfile::TempDir;
|
||||
@@ -304,6 +305,13 @@ async fn sample_preserves_context_and_keeps_source_unchanged(
|
||||
prompt: "Continue identically".to_string(),
|
||||
effort: Some(ReasoningEffort::Medium),
|
||||
turn_trigger: Some("composer_predictions".to_string()),
|
||||
responsesapi_client_metadata: Some(HashMap::from([
|
||||
(
|
||||
"generation_trigger".to_string(),
|
||||
"composer_prediction".to_string(),
|
||||
),
|
||||
("turn_trigger".to_string(), "client-supplied".to_string()),
|
||||
])),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@@ -383,6 +391,19 @@ async fn sample_preserves_context_and_keeps_source_unchanged(
|
||||
.expect("turn metadata"),
|
||||
)?;
|
||||
assert_eq!(metadata["turn_trigger"], "composer_predictions");
|
||||
assert_eq!(metadata["generation_trigger"], "composer_prediction");
|
||||
let body_metadata: Value = serde_json::from_str(
|
||||
prediction.body_json()["client_metadata"]["x-codex-turn-metadata"]
|
||||
.as_str()
|
||||
.expect("body turn metadata"),
|
||||
)?;
|
||||
assert_eq!(body_metadata, metadata);
|
||||
let parent_metadata: Value = serde_json::from_str(
|
||||
&requests[sample_index + 2]
|
||||
.header("x-codex-turn-metadata")
|
||||
.expect("parent turn metadata"),
|
||||
)?;
|
||||
assert!(parent_metadata.get("generation_trigger").is_none());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user