Files
codex/codex-rs/external-agent-migration/src/detect/memory.rs
T
jif e6ebdfe00b Support memory v2 in external-agent memory imports (#56414)
## Why

External-agent memory imports previously wrote only to the v1 workspace and queued only v1 consolidation, leaving the v2 pipeline without imported resources.

## What changed

- Always import selected resources into `memories_v2`. Also update `memories` when v1 is selected or a legacy workspace exists.
- Read `memories.version` for detection and import, detect pending changes across the applicable namespaces, and enqueue consolidation separately for each updated namespace.
- Combine project results across namespaces so cleanup in either can succeed while failures in either are reported.
- Adapt imported-memory consolidation instructions to the active pipeline's output format.

## Testing

Expand app-server integration coverage for v2 profiles, explicit v1 selection, default profiles, and existing legacy workspaces. Verify resource copies, consolidation queues, repeat detection, and cleanup of deleted or unscoped projects.

GitOrigin-RevId: 7e9206942d63fd55b7f2a7f5f9210b687da6a973
2026-10-23 09:06:13 +00:00

44 lines
1.5 KiB
Rust

use crate::discover_external_memory_files;
use crate::memory_import::memory_versions;
use crate::memory_import::projects_needing_import;
use crate::memory_import::resources_root;
use crate::model::ExternalAgentConfigMigrationItem;
use crate::model::ExternalAgentConfigMigrationItemType;
use crate::model::MigrationDetails;
use codex_protocol::MemoryVersion;
use std::collections::BTreeSet;
use std::io;
use std::path::Path;
pub(super) fn detect(
codex_home: &Path,
external_agent_home: &Path,
selection: MemoryVersion,
) -> io::Result<Option<ExternalAgentConfigMigrationItem>> {
let memory_files = discover_external_memory_files(external_agent_home)?;
let mut memory = BTreeSet::new();
for version in memory_versions(codex_home, selection)? {
memory.extend(projects_needing_import(
&codex_home.join(version.directory_name()),
&memory_files,
)?);
}
if memory.is_empty() {
return Ok(None);
}
Ok(Some(ExternalAgentConfigMigrationItem {
item_type: ExternalAgentConfigMigrationItemType::Memory,
description: format!(
"Import memory files from {} to {}",
external_agent_home.join("projects").display(),
resources_root(&codex_home.join(MemoryVersion::V2.directory_name())).display()
),
cwd: None,
details: Some(MigrationDetails {
memory: memory.into_iter().collect(),
..Default::default()
}),
}))
}