mirror of
https://github.com/openai/codex.git
synced 2026-09-11 20:36:49 +00:00
## What changed - Consolidate v2 rollout summaries into `memory_summary.md` without generating `raw_memories.md` or requiring `MEMORY.md`. Validate the summary's required sections and size below 10,000 UTF-8 bytes. - Add v2 read instructions for selective history retrieval, evidence-grounded preferences, citations, and explicit memory edits. Split injected instructions into fragments to preserve the complete summary within fragment byte limits. - Record memory citation usage in the store selected by `memories.version`. ## Testing Add coverage for v2 consolidation without a handbook, summary validation, version-isolated memory reads, and resetting both memory versions while preserving threads. GitOrigin-RevId: 1d895fb4a23a973f1a45ba03be07a1f480c10227
90 lines
3.4 KiB
Rust
90 lines
3.4 KiB
Rust
//! Exercises version selection through app-server and the model request boundary.
|
|
|
|
use anyhow::Result;
|
|
use app_test_support::MockResponsesConfig;
|
|
use app_test_support::TestAppServer;
|
|
use codex_app_server_protocol::ThreadStartParams;
|
|
use codex_app_server_protocol::ThreadStartResponse;
|
|
use codex_app_server_protocol::TurnCompletedNotification;
|
|
use codex_app_server_protocol::TurnStartParams;
|
|
use codex_app_server_protocol::TurnStatus;
|
|
use codex_app_server_protocol::UserInput;
|
|
use codex_features::Feature;
|
|
use core_test_support::responses::ev_assistant_message;
|
|
use core_test_support::responses::ev_completed;
|
|
use core_test_support::responses::ev_response_created;
|
|
use core_test_support::responses::mount_sse_once;
|
|
use core_test_support::responses::sse;
|
|
use core_test_support::responses::start_mock_server;
|
|
use pretty_assertions::assert_eq;
|
|
use serde_json::json;
|
|
use tempfile::TempDir;
|
|
|
|
#[tokio::test]
|
|
async fn memory_read_version_selects_only_its_own_context() -> Result<()> {
|
|
for (version, expected, excluded) in [
|
|
("v1", "legacy-only-marker", "v2-only-marker"),
|
|
("v2", "v2-only-marker", "legacy-only-marker"),
|
|
] {
|
|
let server = start_mock_server().await;
|
|
let home = TempDir::new()?;
|
|
MockResponsesConfig::new(&server.uri())
|
|
.enable_feature(Feature::MemoryTool)
|
|
.write(home.path())?;
|
|
for (directory, marker) in [
|
|
("memories", "legacy-only-marker"),
|
|
("memories_v2", "v2-only-marker"),
|
|
] {
|
|
tokio::fs::create_dir_all(home.path().join(directory)).await?;
|
|
tokio::fs::write(
|
|
home.path().join(directory).join("memory_summary.md"),
|
|
format!("v1\n{marker}\n"),
|
|
)
|
|
.await?;
|
|
}
|
|
let mock = mount_sse_once(
|
|
&server,
|
|
sse(vec![
|
|
ev_response_created("response"),
|
|
ev_assistant_message("message", "Done"),
|
|
ev_completed("response"),
|
|
]),
|
|
)
|
|
.await;
|
|
let mut app = TestAppServer::builder()
|
|
.with_codex_home(home.path())
|
|
.build_initialized()
|
|
.await?;
|
|
let start = app
|
|
.send_thread_start_request_with_auto_env(ThreadStartParams {
|
|
// Skip background consolidation so it cannot consume the read test's response.
|
|
ephemeral: Some(true),
|
|
config: Some(
|
|
[
|
|
("memories.version".to_string(), json!(version)),
|
|
("memories.generate_memories".to_string(), json!(false)),
|
|
]
|
|
.into(),
|
|
),
|
|
..Default::default()
|
|
})
|
|
.await?;
|
|
let response: ThreadStartResponse = app.read_response(start).await?;
|
|
app.send_turn_start_request(TurnStartParams {
|
|
thread_id: response.thread.id,
|
|
input: vec![UserInput::Text {
|
|
text: "Use my memory preferences".to_string(),
|
|
text_elements: Vec::new(),
|
|
}],
|
|
..Default::default()
|
|
})
|
|
.await?;
|
|
let completed: TurnCompletedNotification = app.read_notification("turn/completed").await?;
|
|
assert_eq!(completed.turn.status, TurnStatus::Completed);
|
|
let request = mock.single_request();
|
|
assert!(request.body_contains_text(expected));
|
|
assert!(!request.body_contains_text(excluded));
|
|
}
|
|
Ok(())
|
|
}
|