This commit is contained in:
jif-oai
2026-05-28 18:45:20 +01:00
parent d97837a9a0
commit 6d523bbaec
4 changed files with 26 additions and 26 deletions

View File

@@ -89,7 +89,12 @@ pub(crate) async fn file_modified_time(path: &Path) -> io::Result<Option<time::O
Ok(modified.map(time::OffsetDateTime::from))
}
pub(crate) async fn open_rollout_line_reader(path: &Path) -> io::Result<RolloutLineReader> {
/// Opens a rollout line reader that transparently handles plain `.jsonl` and `.jsonl.zst` files.
///
/// If the requested path disappears during a compression or decompression transition, this retries
/// the matching plain/compressed sibling once so readers do not need to know which representation is
/// currently stored on disk.
pub async fn open_rollout_line_reader(path: &Path) -> io::Result<RolloutLineReader> {
match open_rollout_line_reader_once(path).await {
Ok(reader) => Ok(reader),
Err(err) if err.kind() == io::ErrorKind::NotFound => {
@@ -191,7 +196,8 @@ pub(crate) fn should_skip_compressed_sibling(path: &Path) -> bool {
is_compressed_rollout_path(path) && plain_rollout_path(path).exists()
}
pub(crate) struct RolloutLineReader {
/// Line-oriented rollout reader returned by [`open_rollout_line_reader`].
pub struct RolloutLineReader {
inner: RolloutLineReaderInner,
}
@@ -201,7 +207,8 @@ enum RolloutLineReaderInner {
}
impl RolloutLineReader {
pub(crate) async fn next_line(&mut self) -> io::Result<Option<String>> {
/// Reads the next JSONL record from the rollout.
pub async fn next_line(&mut self) -> io::Result<Option<String>> {
match &mut self.inner {
RolloutLineReaderInner::Plain(lines) => lines.next_line().await,
RolloutLineReaderInner::Memory(lines) => lines.next().transpose(),

View File

@@ -33,7 +33,9 @@ pub static INTERACTIVE_SESSION_SOURCES: LazyLock<Vec<SessionSource>> = LazyLock:
});
pub use codex_protocol::protocol::SessionMeta;
pub use compression::RolloutLineReader;
pub use compression::existing_rollout_path;
pub use compression::open_rollout_line_reader;
pub use compression::spawn_rollout_compression_worker;
pub use config::Config;
pub use config::RolloutConfig;

View File

@@ -225,22 +225,11 @@ impl App {
current_cwd: &Path,
resume_cwd: PathBuf,
) -> Result<Config> {
match self.rebuild_config_for_cwd(resume_cwd.clone()).await {
Ok(config) => Ok(config),
Err(err) => {
if crate::session_resume::cwds_differ(current_cwd, &resume_cwd) {
Err(err)
} else {
let resume_cwd_display = resume_cwd.display().to_string();
tracing::warn!(
error = %err,
cwd = %resume_cwd_display,
"failed to rebuild config for same-cwd resume; using current in-memory config"
);
Ok(self.config.clone())
}
}
if !crate::session_resume::cwds_differ(current_cwd, &resume_cwd) {
return Ok(self.config.clone());
}
self.rebuild_config_for_cwd(resume_cwd).await
}
pub(super) fn apply_runtime_policy_overrides(&mut self, config: &mut Config) {
@@ -1220,12 +1209,16 @@ terminal_resize_reflow_max_rows = 9000
}
#[tokio::test]
async fn rebuild_config_for_resume_or_fallback_uses_current_config_on_same_cwd_error()
-> Result<()> {
async fn rebuild_config_for_resume_or_fallback_reuses_current_config_on_same_cwd() -> Result<()>
{
let mut app = make_test_app().await;
let codex_home = tempdir()?;
app.config.codex_home = codex_home.path().to_path_buf().abs();
std::fs::write(codex_home.path().join("config.toml"), "[broken")?;
app.config.model = Some("already-loaded-model".to_string());
std::fs::write(
codex_home.path().join("config.toml"),
"model = \"freshly-loaded-model\"",
)?;
let current_config = app.config.clone();
let current_cwd = current_config.cwd.clone();

View File

@@ -14,11 +14,11 @@ use crate::cwd_prompt::CwdPromptOutcome;
use crate::cwd_prompt::CwdSelection;
use crate::tui::Tui;
use codex_protocol::ThreadId;
use codex_rollout::open_rollout_line_reader;
use codex_state::StateRuntime;
use codex_utils_path as path_utils;
use serde::Deserialize;
use serde_json::Value;
use tokio::io::AsyncBufReadExt;
#[derive(Default)]
struct RolloutResumeState {
@@ -142,13 +142,11 @@ pub(crate) fn cwds_differ(current_cwd: &Path, session_cwd: &Path) -> bool {
}
async fn read_rollout_resume_state(path: &Path) -> io::Result<RolloutResumeState> {
let file = tokio::fs::File::open(path).await?;
let reader = tokio::io::BufReader::new(file);
let mut lines = reader.lines();
let mut reader = open_rollout_line_reader(path).await?;
let mut state = RolloutResumeState::default();
let mut saw_record = false;
while let Some(line) = lines.next_line().await? {
while let Some(line) = reader.next_line().await? {
let trimmed = line.trim();
if trimmed.is_empty() {
continue;