fix(bazel): replace askama templates with include_str! in memories (#11778)

## Summary

- The experimental Bazel CI builds fail on all platforms because askama
resolves template paths relative to `CARGO_MANIFEST_DIR`, which points
outside the Bazel sandbox. This produces errors like:
  ```
error: couldn't read
`codex-rs/core/src/memories/../../../../../../../../../../../work/codex/codex/codex-rs/core/templates/memories/consolidation.md`:
No such file or directory
  ```
- Replaced `#[derive(Template)]` + `#[template(path = "...")]` with
`include_str!` + `str::replace()` for the three affected templates
(`consolidation.md`, `stage_one_input.md`, `read_path.md`).
`include_str!` resolves paths relative to the source file, which works
correctly in both Cargo and Bazel builds.
- The templates only use simple `{{ variable }}` substitution with no
control flow or filters, so no askama functionality is lost.
- Removes the `askama` dependency from `codex-core` since it was the
only crate using it. The workspace-level dependency definition is left
in place.
- This matches the existing pattern used throughout the codebase — e.g.
`codex-rs/core/src/memories/mod.rs` already uses
`include_str!("../../templates/memories/stage_one_system.md")` for the
fourth template file.

## Test plan

- [ ] Verify Bazel (experimental) CI passes on all platforms
- [ ] Verify rust-ci (Cargo) builds and tests continue to pass
- [ ] Verify `cargo test -p codex-core` passes locally
This commit is contained in:
Alex Kwiatkowski
2026-02-19 13:29:26 -08:00
committed by GitHub
Unverified
parent 429cc4860e
commit fe7054a346
4 changed files with 13 additions and 95 deletions
+13 -40
View File
@@ -2,43 +2,18 @@ use crate::memories::memory_root;
use crate::memories::phase_one;
use crate::truncate::TruncationPolicy;
use crate::truncate::truncate_text;
use askama::Template;
use codex_protocol::openai_models::ModelInfo;
use std::path::Path;
use tokio::fs;
use tracing::warn;
#[derive(Template)]
#[template(path = "memories/consolidation.md", escape = "none")]
struct ConsolidationPromptTemplate<'a> {
memory_root: &'a str,
}
#[derive(Template)]
#[template(path = "memories/stage_one_input.md", escape = "none")]
struct StageOneInputTemplate<'a> {
rollout_path: &'a str,
rollout_cwd: &'a str,
rollout_contents: &'a str,
}
#[derive(Template)]
#[template(path = "memories/read_path.md", escape = "none")]
struct MemoryToolDeveloperInstructionsTemplate<'a> {
base_path: &'a str,
memory_summary: &'a str,
}
const CONSOLIDATION_TEMPLATE: &str = include_str!("../../templates/memories/consolidation.md");
const STAGE_ONE_INPUT_TEMPLATE: &str = include_str!("../../templates/memories/stage_one_input.md");
const READ_PATH_TEMPLATE: &str = include_str!("../../templates/memories/read_path.md");
/// Builds the consolidation subagent prompt for a specific memory root.
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,
};
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}")
})
CONSOLIDATION_TEMPLATE.replace("{{ memory_root }}", &memory_root)
}
/// Builds the stage-1 user message containing rollout metadata and content.
@@ -65,12 +40,10 @@ pub(super) fn build_stage_one_input_message(
let rollout_path = rollout_path.display().to_string();
let rollout_cwd = rollout_cwd.display().to_string();
Ok(StageOneInputTemplate {
rollout_path: &rollout_path,
rollout_cwd: &rollout_cwd,
rollout_contents: &truncated_rollout_contents,
}
.render()?)
Ok(STAGE_ONE_INPUT_TEMPLATE
.replace("{{ rollout_path }}", &rollout_path)
.replace("{{ rollout_cwd }}", &rollout_cwd)
.replace("{{ rollout_contents }}", &truncated_rollout_contents))
}
/// Build prompt used for read path. This prompt must be added to the developer instructions. In
@@ -92,11 +65,11 @@ pub(crate) async fn build_memory_tool_developer_instructions(codex_home: &Path)
return None;
}
let base_path = base_path.display().to_string();
let template = MemoryToolDeveloperInstructionsTemplate {
base_path: &base_path,
memory_summary: &memory_summary,
};
template.render().ok()
Some(
READ_PATH_TEMPLATE
.replace("{{ base_path }}", &base_path)
.replace("{{ memory_summary }}", &memory_summary),
)
}
#[cfg(test)]