Skip to content

Implement Codex-style memory system - #35

Merged
trotsky1997 merged 2 commits into
mainfrom
agent/codex-wsl-gpt5-5/e07a3fb1
Jun 2, 2026
Merged

Implement Codex-style memory system#35
trotsky1997 merged 2 commits into
mainfrom
agent/codex-wsl-gpt5-5/e07a3fb1

Conversation

@trotsky1997

Copy link
Copy Markdown
Owner

Summary

  • add disabled-by-default Codex-style memory config, schema, docs, and OpenSpec spec/archive
  • add local generated memory storage, redaction, prompt rendering, and lifecycle-gated generation scheduling
  • wire memory context/generation through CLI, resume, TUI, ACP, and A2A session paths with thread-level controls

Validation

  • cargo fmt
  • cargo test
  • openspec validate --all --strict

Co-authored-by: multica-agent <github@multica.ai>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @trotsky1997, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 34adf1c6a5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/memory.rs
Comment on lines +646 to +647
r"(?i)(api[_ -]?key|access[_ -]?token|auth[_ -]?token|token|secret|password)\s*[:=]\s*([^\s,;]+)",
"$1=<redacted>",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Redact natural-language secrets before persisting memories

When a user says a secret in prose such as password is hunter2 or token abc123, the extractor selects that line because it contains password/token, but this regex only redacts :/= assignments (plus a couple of provider-shaped tokens). With memory enabled, those lines are then written to the local memory JSON in plaintext, which defeats the secret-redaction guarantee for common user wording.

Useful? React with 👍 / 👎.

Comment thread src/memory.rs
Comment on lines +179 to +183
if let Some(GenerationDecision::Pending { remaining_idle, .. }) = outcome {
let system = system.clone();
let session = session.clone();
tokio::spawn(async move {
tokio::time::sleep(remaining_idle).await;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep delayed memory generation alive for one-shot commands

With the default min_idle_before_generation_secs of 600, generate_for_session reaches this branch, spawns a delayed task, and returns immediately. In the ra one-shot run_print/resume paths that call it just before returning from main, the Tokio runtime shuts down before the sleep completes, so enabled memories are never generated unless users override the idle delay to zero.

Useful? React with 👍 / 👎.

Comment thread src/session.rs
Comment on lines +398 to +400
{
*self.active.lock().await = true;
*self.last_activity_at.lock().await = Instant::now();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear memory activity state on prompt errors

If run_loop() later returns an error (for example a model stream or tool failure), res? exits prompt_unlocked before the cleanup block clears this newly-added active flag and refreshes last_activity_at. Any subsequent save/generation pass for that session will continue to see is_active = true and skip memory generation as SessionActive, even though the prompt has already ended with an error.

Useful? React with 👍 / 👎.

Comment thread src/memory.rs
Comment on lines +292 to +295
UseDecision::Active => rendered.push(render_artifact(artifact)),
UseDecision::Suppressed { .. } => {}
}
if rendered.len() >= self.max_entries {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor a zero prompt-memory limit

When max_prompt_memories = 0, this loop still pushes the first active artifact before checking the limit, so setting the documented maximum to zero renders one memory instead of suppressing memory context. This makes the config unable to fully disable prompt injection via the prompt limit alone.

Useful? React with 👍 / 👎.

Comment thread src/acp_server.rs
Comment on lines +262 to +263
if let Some(prompt) = crate::memory::load_prompt_for_cwd(Some(&self.memory), &cwd).await {
s.set_memory_prompt(Some(prompt)).await;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve memory controls when forking ACP sessions

When an ACP user disables memory_use or memory_generate on a session and then forks it, create_session builds the child with default memory controls and immediately loads the memory prompt; the fork handler only copies the transcript. The fork can therefore start using or generating memories that the parent explicitly opted out of, even though ACP fork is supposed to carry the same conversation context forward.

Useful? React with 👍 / 👎.

Co-authored-by: multica-agent <github@multica.ai>
@trotsky1997
trotsky1997 merged commit 61bf899 into main Jun 2, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant