mirror of
https://github.com/openai/codex.git
synced 2026-11-02 19:43:24 +00:00
## Why Clients need a per-thread Daybreak toggle that survives restarts and can be restored on resume without changing the access program of an active or future turn. ## What changed - Add experimental `daybreakEnabled` support to `thread/metadata/update` and expose the saved value on thread responses. - Store the preference in SQLite, including for threads without a first turn, and preserve it through reads, resumes, reconciliation, and restarts. - Copy the preference when forking a thread while keeping subsequent updates independent. - Keep `daybreakEnabled` separate from the per-turn `cyberAccessProgram` field; app-server does not derive one from the other. ## Testing - Cover persistence across restarts, cold reads, reconciliation, and forks. - Verify metadata updates do not alter the access program of active or later turns. GitOrigin-RevId: bcf987a9fcd7b0ac8a88b1c8f0df06b33ed8ad6e
83 lines
2.3 KiB
Rust
83 lines
2.3 KiB
Rust
#[cfg(test)]
|
|
use chrono::DateTime;
|
|
#[cfg(test)]
|
|
use chrono::Utc;
|
|
#[cfg(test)]
|
|
use codex_protocol::ThreadId;
|
|
#[cfg(test)]
|
|
use codex_protocol::openai_models::ReasoningEffort;
|
|
#[cfg(test)]
|
|
use codex_protocol::protocol::AskForApproval;
|
|
#[cfg(test)]
|
|
use codex_protocol::protocol::SandboxPolicy;
|
|
#[cfg(test)]
|
|
use codex_protocol::protocol::ThreadHistoryMode;
|
|
#[cfg(test)]
|
|
use std::path::Path;
|
|
#[cfg(test)]
|
|
use std::path::PathBuf;
|
|
#[cfg(test)]
|
|
use std::time::SystemTime;
|
|
#[cfg(test)]
|
|
use std::time::UNIX_EPOCH;
|
|
#[cfg(test)]
|
|
use uuid::Uuid;
|
|
|
|
#[cfg(test)]
|
|
use crate::ThreadMetadata;
|
|
|
|
#[cfg(test)]
|
|
pub(crate) fn unique_temp_dir() -> PathBuf {
|
|
let nanos = SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.map_or(0, |duration| duration.as_nanos());
|
|
std::env::temp_dir().join(format!(
|
|
"codex-state-runtime-test-{nanos}-{}",
|
|
Uuid::new_v4()
|
|
))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub(super) fn test_thread_metadata(
|
|
codex_home: &Path,
|
|
thread_id: ThreadId,
|
|
cwd: PathBuf,
|
|
) -> ThreadMetadata {
|
|
let now = DateTime::<Utc>::from_timestamp(1_700_000_000, 0).expect("timestamp");
|
|
ThreadMetadata {
|
|
originator: None,
|
|
id: thread_id,
|
|
rollout_path: codex_home.join(format!("rollout-{thread_id}.jsonl")),
|
|
created_at: now,
|
|
updated_at: now,
|
|
recency_at: now,
|
|
source: "cli".to_string(),
|
|
history_mode: ThreadHistoryMode::Legacy,
|
|
thread_source: None,
|
|
agent_nickname: None,
|
|
agent_role: None,
|
|
agent_path: None,
|
|
model_provider: "test-provider".to_string(),
|
|
model: Some("gpt-5".to_string()),
|
|
reasoning_effort: Some(ReasoningEffort::Medium),
|
|
cwd,
|
|
cli_version: "0.0.0".to_string(),
|
|
title: String::new(),
|
|
name: None,
|
|
preview: Some("hello".to_string()),
|
|
sandbox_policy: crate::extract::enum_to_string(&SandboxPolicy::new_read_only_policy()),
|
|
approval_mode: crate::extract::enum_to_string(&AskForApproval::OnRequest),
|
|
tokens_used: 0,
|
|
first_user_message: Some("hello".to_string()),
|
|
archived_at: None,
|
|
section: None,
|
|
section_position: None,
|
|
section_entered_at: None,
|
|
project_id: None,
|
|
daybreak_enabled: None,
|
|
git_sha: None,
|
|
git_branch: None,
|
|
git_origin_url: None,
|
|
}
|
|
}
|