mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Fix compressed rollout search path matching (#27407)
## Why `thread/search` found content inside compressed rollouts but could drop the result when joining it with SQLite-backed thread metadata. Search returned the physical `.jsonl.zst` path while SQLite retained the logical `.jsonl` path, so exact path matching failed. ## What changed - Key rollout search matches by their canonical logical `.jsonl` path, independent of the on-disk representation. - Canonicalize thread-list paths before joining them with content-search matches. - Update compressed-rollout coverage to assert the logical-path contract. ## Validation - Ran `just fmt`. - Ran `git diff --check`. - Tests and Clippy were intentionally left to CI.
This commit is contained in:
@@ -106,14 +106,13 @@ async fn append_rollout_item_materializes_compressed_rollout() -> anyhow::Result
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn search_rollout_matches_returns_compressed_snippet() -> anyhow::Result<()> {
|
||||
async fn search_rollout_matches_uses_logical_path_for_compressed_rollout() -> anyhow::Result<()> {
|
||||
let home = TempDir::new()?;
|
||||
let uuid = Uuid::from_u128(15);
|
||||
let thread_id = ThreadId::from_string(&uuid.to_string())?;
|
||||
let rollout_path = rollout_path(home.path(), "2025-01-03T12-00-00", uuid);
|
||||
write_rollout(&rollout_path, thread_id, "targeted search term")?;
|
||||
compress_now(&rollout_path)?;
|
||||
let compressed_path = compressed_rollout_path(&rollout_path);
|
||||
|
||||
let matches = search_rollout_matches(
|
||||
std::path::Path::new("missing-rg-for-test"),
|
||||
@@ -124,7 +123,7 @@ async fn search_rollout_matches_returns_compressed_snippet() -> anyhow::Result<(
|
||||
.await?;
|
||||
|
||||
assert_eq!(
|
||||
matches.get(compressed_path.as_path()),
|
||||
matches.get(rollout_path.as_path()),
|
||||
Some(&Some("targeted search term".to_string()))
|
||||
);
|
||||
Ok(())
|
||||
|
||||
@@ -21,6 +21,7 @@ use super::compression;
|
||||
const MATCH_CONTEXT_BEFORE_CHARS: usize = 48;
|
||||
const MATCH_CONTEXT_AFTER_CHARS: usize = 96;
|
||||
|
||||
/// Search matches keyed by the canonical `.jsonl` path for each rollout.
|
||||
pub type RolloutSearchMatches = HashMap<PathBuf, Option<String>>;
|
||||
|
||||
pub async fn search_rollout_paths(
|
||||
@@ -145,7 +146,10 @@ async fn scan_rollout_matches(
|
||||
if let Some(snippet) =
|
||||
first_rollout_content_match_snippet(rollout_file.path(), search_term).await?
|
||||
{
|
||||
matches.insert(rollout_file.into_path(), Some(snippet));
|
||||
matches.insert(
|
||||
compression::plain_rollout_path(rollout_file.path()),
|
||||
Some(snippet),
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -217,7 +221,10 @@ async fn scan_compressed_rollout_matches(
|
||||
if let Some(snippet) =
|
||||
first_rollout_content_match_snippet(rollout_file.path(), search_term).await?
|
||||
{
|
||||
matches.insert(rollout_file.into_path(), Some(snippet));
|
||||
matches.insert(
|
||||
compression::plain_rollout_path(rollout_file.path()),
|
||||
Some(snippet),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,8 @@ pub(super) async fn search_threads(
|
||||
)
|
||||
.await?;
|
||||
for item in page.items {
|
||||
let Some(snippet) = (match remaining_rollouts.remove(item.path.as_path()) {
|
||||
let logical_path = codex_rollout::plain_rollout_path(item.path.as_path());
|
||||
let Some(snippet) = (match remaining_rollouts.remove(logical_path.as_path()) {
|
||||
Some(Some(snippet)) => Some(snippet),
|
||||
Some(None) => first_rollout_content_match_snippet(item.path.as_path(), search_term)
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user