mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat: memory read path (#11459)
This commit is contained in:
@@ -2295,6 +2295,14 @@ impl Session {
|
||||
DeveloperInstructions::new(SEARCH_TOOL_DEVELOPER_INSTRUCTIONS.to_string()).into(),
|
||||
);
|
||||
}
|
||||
// Add developer instructions for memories.
|
||||
if let Some(memory_prompt) =
|
||||
memories::build_memory_tool_developer_instructions(&turn_context.config.codex_home)
|
||||
.await
|
||||
&& turn_context.features.enabled(Feature::MemoryTool)
|
||||
{
|
||||
items.push(DeveloperInstructions::new(memory_prompt).into());
|
||||
}
|
||||
// Add developer instructions from collaboration_mode if they exist and are non-empty
|
||||
let (collaboration_mode, base_instructions) = {
|
||||
let state = self.state.lock().await;
|
||||
|
||||
@@ -61,7 +61,7 @@ struct StageOneOutput {
|
||||
_rollout_slug: Option<String>,
|
||||
}
|
||||
|
||||
fn memory_root(codex_home: &Path) -> PathBuf {
|
||||
pub fn memory_root(codex_home: &Path) -> PathBuf {
|
||||
codex_home.join("memories")
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ async fn ensure_layout(root: &Path) -> std::io::Result<()> {
|
||||
tokio::fs::create_dir_all(rollout_summaries_dir(root)).await
|
||||
}
|
||||
|
||||
pub(crate) use prompts::build_memory_tool_developer_instructions;
|
||||
/// Starts the memory startup pipeline for eligible root sessions.
|
||||
///
|
||||
/// This is the single entrypoint that `codex` uses to trigger memory startup.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use askama::Template;
|
||||
use std::path::Path;
|
||||
use tracing::warn;
|
||||
|
||||
use super::text::prefix_at_char_boundary;
|
||||
use super::text::suffix_at_char_boundary;
|
||||
use crate::memories::memory_root;
|
||||
use askama::Template;
|
||||
use std::path::Path;
|
||||
use tokio::fs;
|
||||
use tracing::warn;
|
||||
|
||||
// TODO(jif) use proper truncation
|
||||
const MAX_ROLLOUT_BYTES_FOR_PROMPT: usize = 100_000;
|
||||
@@ -22,22 +23,24 @@ struct StageOneInputTemplate<'a> {
|
||||
rollout_contents: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "memory_tool/developer_instructions.md", escape = "none")]
|
||||
struct MemoryToolDeveloperInstructionsTemplate<'a> {
|
||||
base_path: &'a str,
|
||||
memory_summary: &'a str,
|
||||
}
|
||||
|
||||
/// Builds the consolidation subagent prompt for a specific memory root.
|
||||
///
|
||||
/// Falls back to a simple string replacement if Askama rendering fails.
|
||||
pub(super) fn build_consolidation_prompt(memory_root: &Path) -> String {
|
||||
let memory_root = memory_root.display().to_string();
|
||||
let template = ConsolidationPromptTemplate {
|
||||
memory_root: &memory_root,
|
||||
};
|
||||
match template.render() {
|
||||
Ok(prompt) => prompt,
|
||||
Err(err) => {
|
||||
warn!("failed to render memories consolidation prompt template: {err}");
|
||||
include_str!("../../templates/memories/consolidation.md")
|
||||
.replace("{{ memory_root }}", &memory_root)
|
||||
}
|
||||
}
|
||||
template.render().unwrap_or_else(|err| {
|
||||
warn!("failed to render memories consolidation prompt template: {err}");
|
||||
format!("## Memory Phase 2 (Consolidation)\nConsolidate Codex memories in: {memory_root}")
|
||||
})
|
||||
}
|
||||
|
||||
/// Builds the stage-1 user message containing rollout metadata and content.
|
||||
@@ -65,17 +68,31 @@ pub(super) fn build_stage_one_input_message(
|
||||
rollout_cwd: &rollout_cwd,
|
||||
rollout_contents: &rollout_contents,
|
||||
};
|
||||
// TODO(jif) use askama
|
||||
match template.render() {
|
||||
Ok(prompt) => prompt,
|
||||
Err(err) => {
|
||||
warn!("failed to render memories stage-one input template: {err}");
|
||||
include_str!("../../templates/memories/stage_one_input.md")
|
||||
.replace("{{ rollout_path }}", &rollout_path)
|
||||
.replace("{{ rollout_cwd }}", &rollout_cwd)
|
||||
.replace("{{ rollout_contents }}", &rollout_contents)
|
||||
}
|
||||
template.render().unwrap_or_else(|err| {
|
||||
warn!("failed to render memories stage-one input template: {err}");
|
||||
format!(
|
||||
"Analyze this rollout and produce JSON with `raw_memory`, `rollout_summary`, and optional `rollout_slug`.\n\nrollout_context:\n- rollout_path: {rollout_path}\n- rollout_cwd: {rollout_cwd}\n\nrendered conversation:\n{rollout_contents}"
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) async fn build_memory_tool_developer_instructions(codex_home: &Path) -> Option<String> {
|
||||
let base_path = memory_root(codex_home);
|
||||
let memory_summary_path = base_path.join("memory_summary.md");
|
||||
let memory_summary = fs::read_to_string(&memory_summary_path)
|
||||
.await
|
||||
.ok()?
|
||||
.trim()
|
||||
.to_string();
|
||||
if memory_summary.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let base_path = base_path.display().to_string();
|
||||
let template = MemoryToolDeveloperInstructionsTemplate {
|
||||
base_path: &base_path,
|
||||
memory_summary: &memory_summary,
|
||||
};
|
||||
template.render().ok()
|
||||
}
|
||||
|
||||
fn truncate_rollout_for_prompt(input: &str) -> (String, bool) {
|
||||
|
||||
Reference in New Issue
Block a user