Repository navigation
Route Codex memory extract and consolidation to a chosen model #5982
Description
Area
Proxy and routing
What are you trying to accomplish?
I want Codex's memory pipeline to run on a provider I choose, next to the normal turns that already run there.
Codex writes memories in two background phases. Phase 1 ("extract") summarizes one finished thread per call and asks for gpt-5.6-luna at effort low. Phase 2 ("consolidation") is one agent run that merges those summaries into the files under $CODEX_HOME/memories and asks for gpt-5.6-terra at effort medium. Both ask for a bare native model id, so on a setup whose ordinary traffic is routed to another provider they resolve through the canonical OpenAI route, and they fail there as soon as that account is out of quota.
What prevents this today?
- Both phase models and efforts are hard-coded in Codex (
codex-rs/memories/write/src/lib.rs). The only OpenCodex-side knob that can catch them today isshadowCallIntercept, and that one has a single target, no effort control, and cannot tell the extract phase apart from the app's title/commit helper calls, which use the same model id. - Phase 2 does not share the helper model id, so an intercept configured for the helpers leaves consolidation on the native route.
- Nothing in the request log names a memory phase, so a failing memory request is hard to attribute.
What should OpenCodex do?
Add a memoryModels setting with one entry per phase (extract, consolidation), each holding a model and an optional reasoningEffort, plus a dashboard panel that edits it. A configured phase is routed to that model; an unconfigured phase keeps Codex's own choice.
The phase has to be recognized from Codex's own markers rather than from the model id:
request_kind: "memory"in thex-codex-turn-metadataheader marks an extract pass.thread_source: "memory_consolidation"marks the consolidation thread; that pass also carriesx-openai-subagent: memory_consolidation.
A configured phase should win when shadowCallIntercept matches the same request, while a phase left off keeps its current routing. A target that stopped resolving should fail the memory call with a clear error instead of silently falling back to the native model the operator routed away from.
Example usage or interface
{
"memoryModels": {
"extract": { "model": "opencode-go/glm-5.3-flash", "reasoningEffort": "low" },
"consolidation": { "model": "opencode-go/glm-5.3-flash", "reasoningEffort": "medium" }
}
}Dashboard → Overview → Memory routing shows the same two rows, each with a model picker and an effort picker.
Alternatives or workarounds
shadowCallInterceptcovers the extract phase by accident, because that phase shares the helper model id. It cannot cover consolidation, cannot set an effort, and cannot be limited to memory traffic.- Codex itself can retarget the phase models through
[memories] extract_model/consolidation_model, but that only changes the model id, not the provider it resolves through.
Additional context
- Codex-side defaults live in
codex-rs/model-provider/src/provider.rs. - Local observation on a routed setup with
[features] memories = true: extract traffic reached the intercept target, consolidation kept going to OpenAI.
Checks
- I searched existing issues and documentation.
- This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
- I removed secrets and personal data.
Activity
lidge-jun commentedon Sep 27, 2026
Resolved on dev by #6124 (merge commit 296f0ce): Codex memory-phase model routing is now available. It ships with the next release.