mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
Add per-turn prompt cache TTL options (#59480)
## What changed - Expose `PromptCacheTtl` through `TurnStartOptions` and `RecoverTurnRequest`, supporting `30m` and `12h` minimum cache lifetimes. - Carry the selected TTL through turn execution and compaction into `prompt_cache_options.ttl` on Responses HTTP and WebSocket requests. Omit the field when unset and keep the selection scoped to the turn. - Include prompt cache options in WebSocket request reuse checks. ## Testing Add coverage for both TTL values and omission on a subsequent turn without an override, and extend WebSocket serialization coverage to include prompt cache options. GitOrigin-RevId: 8529306e6ad6030fe77c5e6bf19f3810717c0c5e
This commit is contained in:
@@ -10,6 +10,7 @@ use codex_protocol::protocol::TokenUsage;
|
||||
use codex_protocol::protocol::TurnModerationMetadataEvent;
|
||||
use codex_protocol::protocol::W3cTraceContext;
|
||||
use codex_protocol::turn_input::CyberAccessProgram;
|
||||
use codex_protocol::turn_input::PromptCacheTtl;
|
||||
use futures::Stream;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
@@ -277,6 +278,11 @@ impl Serialize for ResponsesApiTools {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
|
||||
pub struct PromptCacheOptions {
|
||||
pub ttl: PromptCacheTtl,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone, PartialEq)]
|
||||
pub struct ResponsesApiRequest {
|
||||
// Keep routing fields first: serde serializes struct fields in declaration order, and
|
||||
@@ -298,6 +304,8 @@ pub struct ResponsesApiRequest {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub prompt_cache_key: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub prompt_cache_options: Option<PromptCacheOptions>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub text: Option<TextControls>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub client_metadata: Option<HashMap<String, String>>,
|
||||
@@ -321,6 +329,7 @@ impl<'a> From<&'a ResponsesApiRequest> for ResponseCreateWsRequest<'a> {
|
||||
include: &request.include,
|
||||
service_tier: request.service_tier.as_deref(),
|
||||
prompt_cache_key: request.prompt_cache_key.as_deref(),
|
||||
prompt_cache_options: request.prompt_cache_options,
|
||||
text: request.text.as_ref(),
|
||||
generate: None,
|
||||
client_metadata: request.client_metadata.clone(),
|
||||
@@ -352,6 +361,8 @@ pub struct ResponseCreateWsRequest<'a> {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub prompt_cache_key: Option<&'a str>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub prompt_cache_options: Option<PromptCacheOptions>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub text: Option<&'a TextControls>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub generate: Option<bool>,
|
||||
|
||||
@@ -1117,6 +1117,9 @@ mod tests {
|
||||
include: vec!["reasoning.encrypted_content".to_string()],
|
||||
service_tier: Some("priority".to_string()),
|
||||
prompt_cache_key: Some("cache-key".to_string()),
|
||||
prompt_cache_options: Some(crate::PromptCacheOptions {
|
||||
ttl: codex_protocol::turn_input::PromptCacheTtl::TwelveHours,
|
||||
}),
|
||||
text: None,
|
||||
access_programs: Some(
|
||||
codex_protocol::turn_input::CyberAccessProgram::DaybreakBlue.into(),
|
||||
|
||||
@@ -37,6 +37,7 @@ pub use crate::common::AccessPrograms;
|
||||
pub use crate::common::MemorySummarizeInput;
|
||||
pub use crate::common::MemorySummarizeOutput;
|
||||
pub use crate::common::OpenAiVerbosity;
|
||||
pub use crate::common::PromptCacheOptions;
|
||||
pub use crate::common::RawMemory;
|
||||
pub use crate::common::RawMemoryMetadata;
|
||||
pub use crate::common::Reasoning;
|
||||
|
||||
Reference in New Issue
Block a user