mirror of
https://github.com/openai/codex.git
synced 2026-11-05 08:28:29 +00:00
[codex] Support sequential cutoff reasoning summaries (#31306)
## Summary When enabled for the OpenAI provider, Codex sends `stream_options.reasoning_summary_delivery = "sequential_cutoff"` on HTTP and WebSocket requests, including prewarm, and renders completed summary sections from `reasoning_summary_text.done`. Flag-off and non-OpenAI behavior is unchanged. ## Expected rollout ```text reasoning 0 added summary 0 done summary 1 done summary 2 starts summary 2 cancelled / incomplete reasoning 0 done <-- cancel summary 2 work and mark it incomplete message 1 added message 1 text streams message 1 completed ``` Depends on [openai/openai#1096660](https://github.com/openai/openai/pull/1096660).
This commit is contained in:
1 parent
831c14fc39
commit
775ef7dcc7
20 files changed
+352
-6
No files matched your search
@@ -56,6 +56,7 @@ use codex_api::ResponsesWebsocketConnection as ApiWebSocketConnection;
|
||||
use codex_api::ResponsesWsRequest;
|
||||
use codex_api::SharedAuthProvider;
|
||||
use codex_api::SseTelemetry;
|
||||
use codex_api::StreamOptions;
|
||||
use codex_api::TransportError;
|
||||
use codex_api::WebsocketTelemetry;
|
||||
use codex_api::auth_header_telemetry;
|
||||
@@ -203,6 +204,7 @@ struct ModelClientState {
|
||||
include_timing_metrics: bool,
|
||||
beta_features_header: Option<String>,
|
||||
item_ids_enabled: bool,
|
||||
concurrent_reasoning_summaries_enabled: bool,
|
||||
include_attestation: bool,
|
||||
attestation_provider: Option<Arc<dyn AttestationProvider>>,
|
||||
disable_websockets: AtomicBool,
|
||||
@@ -311,6 +313,7 @@ fn responses_request_properties_match(
|
||||
reasoning: previous_reasoning,
|
||||
store: previous_store,
|
||||
stream: previous_stream,
|
||||
stream_options: _,
|
||||
include: previous_include,
|
||||
service_tier: previous_service_tier,
|
||||
prompt_cache_key: previous_prompt_cache_key,
|
||||
@@ -327,6 +330,7 @@ fn responses_request_properties_match(
|
||||
reasoning: current_reasoning,
|
||||
store: current_store,
|
||||
stream: current_stream,
|
||||
stream_options: _,
|
||||
include: current_include,
|
||||
service_tier: current_service_tier,
|
||||
prompt_cache_key: current_prompt_cache_key,
|
||||
@@ -342,6 +346,8 @@ fn responses_request_properties_match(
|
||||
&& previous_reasoning == current_reasoning
|
||||
&& previous_store == current_store
|
||||
&& previous_stream == current_stream
|
||||
// Stream options control delivery for this response, not the context
|
||||
// referenced by `previous_response_id`.
|
||||
&& previous_include == current_include
|
||||
&& previous_service_tier == current_service_tier
|
||||
&& previous_prompt_cache_key == current_prompt_cache_key
|
||||
@@ -409,6 +415,7 @@ impl ModelClient {
|
||||
include_timing_metrics: bool,
|
||||
beta_features_header: Option<String>,
|
||||
item_ids_enabled: bool,
|
||||
concurrent_reasoning_summaries_enabled: bool,
|
||||
attestation_provider: Option<Arc<dyn AttestationProvider>>,
|
||||
) -> Self {
|
||||
let model_provider = create_model_provider(provider_info, auth_manager);
|
||||
@@ -431,6 +438,7 @@ impl ModelClient {
|
||||
include_timing_metrics,
|
||||
beta_features_header,
|
||||
item_ids_enabled,
|
||||
concurrent_reasoning_summaries_enabled,
|
||||
include_attestation,
|
||||
attestation_provider,
|
||||
disable_websockets: AtomicBool::new(false),
|
||||
@@ -820,7 +828,8 @@ impl ModelClient {
|
||||
responses_metadata: &CodexResponsesMetadata,
|
||||
) -> Result<ResponsesApiRequest> {
|
||||
let mut input = prompt.get_formatted_input_for_request(model_info.use_responses_lite);
|
||||
if !self.state.provider.info().is_openai() {
|
||||
let is_openai = self.state.provider.info().is_openai();
|
||||
if !is_openai {
|
||||
input
|
||||
.iter_mut()
|
||||
.for_each(ResponseItem::clear_internal_chat_message_metadata_passthrough);
|
||||
@@ -848,6 +857,10 @@ impl ModelClient {
|
||||
} else {
|
||||
(prompt.base_instructions.text.clone(), Some(tools))
|
||||
};
|
||||
let stream_options = (self.state.concurrent_reasoning_summaries_enabled && is_openai)
|
||||
.then_some(StreamOptions {
|
||||
reasoning_summary_delivery: codex_api::ReasoningSummaryDelivery::SequentialCutoff,
|
||||
});
|
||||
let reasoning = Self::build_reasoning(model_info, effort, summary);
|
||||
let include = if reasoning.is_some() {
|
||||
vec!["reasoning.encrypted_content".to_string()]
|
||||
@@ -882,6 +895,7 @@ impl ModelClient {
|
||||
reasoning,
|
||||
store: provider.is_azure_responses_endpoint(),
|
||||
stream: true,
|
||||
stream_options,
|
||||
include,
|
||||
service_tier,
|
||||
prompt_cache_key,
|
||||
|
||||
Reference in new issue
Block a user