Skip to content

🤖 fix: invalidate cached memory context on memory changes and context reset - #3764

Open
ibetitsmike wants to merge 1 commit into
mike/fix-tool-papercutsfrom
mike/fix-memory-cache-invalidation
Open

🤖 fix: invalidate cached memory context on memory changes and context reset#3764
ibetitsmike wants to merge 1 commit into
mike/fix-tool-papercutsfrom
mike/fix-memory-cache-invalidation

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Invalidates the per-session cached memory context (memory index snapshot + <hot_memories> block) whenever memory files change or the workspace context is reset, so agents stop seeing index entries for files that no longer exist.

Stack position 2 of 3 (base: #3763; child: #3765).

Background

AgentSession.memoryContextByModelString was cleared only when a pending compaction boundary was consumed. MemoryService emits change events, but only the ORPC UI layer subscribed, and WorkspaceService.resetContext did not clear the cache either. A deleted or renamed memory file therefore stayed in the advertised memory index for the rest of the session segment.

Implementation

  • AgentSession.invalidateMemoryContext() clears the cache and bumps a generation counter; a build that races an invalidation is rebuilt before returning, so the current request also sees the post-invalidation state (bounded at 3 attempts so invalidation churn cannot livelock a stream; the final snapshot is then served uncached).
  • AIService.streamMessage re-resolves the context immediately before tool assembly and once more after it (a cache hit is the identical reference; an invalidation during any async preparation window forces a rebuild). A post-assembly change refreshes the already-created memory tool's description and feeds the fresh snapshot into the final system-prompt rebuild; the hot-set upgrade await is covered the same way, so a change landing during it cannot pair a fresh system block with a stale tool index; the refusal-fallback prepare() resolves a fresh context for the fallback model (the hot-set experiment only chooses whether the hot block is included, so renames since the original assembly are picked up even with hot preloading off) and refreshes its rebuilt toolset's description the same way. A final bounded revalidation runs at the request boundary, after the last awaited preparation stage (system-prompt rebuild, tokenizer loading, message preparation, history append): if the snapshot moved, the memory tool description and system prompt are reassembled before startStream, which is reached synchronously from there. The refusal-fallback prepare() runs the same bounded boundary revalidation after its own awaited stages. resetContext's busy guard also covers transient startup-recovery sessions and re-checks after the history read, so a recovery retry that turns busy mid-reset rejects the reset instead of getting a boundary appended into its active turn. If a boundary-revalidation rebuild fails after the assistant placeholder was persisted, the placeholder is deleted (like the abort path) so history is not left with an empty trailing assistant turn. startStream additionally invokes a refresh hook after its own awaited setup (workspace mutex, stream safety, temp-dir creation) and immediately before atomic registration, so a memory change during those awaits still reaches the provider request; a failed rebuild there keeps the request-boundary snapshot instead of failing the stream. Every refresh site rebuilds the memory tool description through one shared helper that re-appends configured Tool: memory instructions, so custom instructions survive description refreshes instead of being replaced by the bare index. Once a stream is registered, prepareStep re-runs the bounded revalidation before every tool-loop step (each step is its own provider request): on change the memory tool description is updated in place (the SDK re-reads descriptions from the same reference per step; there is no per-step tools override) and the system prompt is swapped via a per-step instructions override or an exact-match replacement of the cached system message, so a memory change during a long tool execution reaches the next step instead of waiting for the next turn. The refusal-fallback prepare() returns the same hook bound to the fallback toolset. A failed per-step rebuild keeps the current snapshot instead of failing the tool loop. Structured system messages (OpenAI explicit prompt-cache breakpoint) keep their providerOptions across refreshes, and each applied refresh writes the recomputed system token count into the live stream metadata so stream-end attribution matches what was sent.
  • WorkspaceService.invalidateMemoryContexts() fans out to all live sessions, including transient startup-recovery sessions, and is wired to MemoryService change events in coreServices. Invalidation is not filtered per mutation type, but it is scoped by the change event: global changes fan out to all sessions, workspace/project changes only to matching sessions. Project matching resolves each session's memory project identity synchronously from its config entry (the same identity the event's projectPath is built from), so scratch chats, whose identity is their scratch directory rather than a config bucket key, match correctly. Invalidation runs synchronously inside the change emit, so a mutation route cannot return with a stale cache still in place.
  • WorkspaceService.resetContext() invalidates immediately after the reset boundary is appended and emitted, before awaiting goal acknowledgment, covering transient startup-recovery sessions tracked outside the normal session map; a recovery retry firing during that await cannot build from the pre-reset snapshot. The reset also refuses to run while a turn is active, a startup-recovery auto-retry is queued or merely scheduled, or a startup-recovery check is still mid-decision: the guard resolves transient recovery sessions too and runs both at entry and again after the history read, before the boundary append, so a retry timer firing during that append cannot capture pre-reset history. The recovery check is symmetric: at its retry decision it compares a per-workspace reset-boundary epoch against the value from before its history reads and defers when a reset overlapped them, so the re-run reads post-boundary history.
  • Pin/unpin updates flow through a new MemoryService.setPinned that writes the meta sidecar and emits the same change event, since pins feed hot-set selection.

Accepted tradeoff: a memory write mid-segment now costs one prompt-cache miss on the next request for that session.

Validation

Integration tests drive a real MemoryService end to end: create → cache → delete/rename → change event → next-built context reflects disk. A dedicated test pins the in-flight-build race (invalidation during an awaited build must not repopulate the cache).

Risks

Low-medium. Touches the request-building path for every provider call, but the only behavior change is when the cache is dropped; rebuild code is unchanged. Worst-case regression is extra prompt-cache misses, not incorrect context.


Generated with mux • Model: anthropic:claude-fable-5 • Thinking: xhigh

@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: f7dbb66cdd

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/coreServices.ts Outdated
@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from 384dc95 to bb237d4 Compare July 30, 2026 13:39
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from f7dbb66 to 935a940 Compare July 30, 2026 13:39
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: 935a94074c

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch 3 times, most recently from dd8e248 to 9ed2e61 Compare July 30, 2026 14:11
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 935a940 to c42ef91 Compare July 30, 2026 14:11
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: c42ef91d8e

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/coreServices.ts Outdated
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from 9ed2e61 to bb9d398 Compare July 30, 2026 14:28
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch 2 times, most recently from c42ef91 to a62f7d2 Compare July 30, 2026 14:28
@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from 9ed2e61 to bb9d398 Compare July 30, 2026 14:28

@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: a62f7d22b3

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/workspaceService.ts Outdated
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from a62f7d2 to 6fb63b5 Compare July 30, 2026 14:51
@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from bb9d398 to 061f154 Compare July 30, 2026 14:51
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: 6fb63b5189

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/workspaceService.ts Outdated
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 6fb63b5 to 82282f5 Compare July 30, 2026 15:14
@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from 061f154 to 64b67af Compare July 30, 2026 15:14
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: 82282f5512

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/workspaceService.ts Outdated
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 82282f5 to a93608a Compare July 30, 2026 15:39
@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from 64b67af to 9cd5ca7 Compare July 30, 2026 15:39
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: cc41698824

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from b6c950f to 8aa83ea Compare July 30, 2026 21:52
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: 4753b55db8

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/aiService.ts
@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from 8aa83ea to ae33861 Compare July 30, 2026 22:15
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 4753b55 to 827981c Compare July 30, 2026 22:15
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: 827981c5a8

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/workspaceService.ts
Comment thread src/node/services/aiService.ts
@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from ae33861 to d7693eb Compare July 30, 2026 22:55
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 827981c to 65df018 Compare July 30, 2026 22:56
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 65df018ce2

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from d7693eb to 170e1f3 Compare July 30, 2026 23:18
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 65df018 to 463fb35 Compare July 30, 2026 23:19
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: 463fb352d6

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/aiService.ts Outdated
@ibetitsmike
ibetitsmike force-pushed the mike/fix-tool-papercuts branch from 170e1f3 to 5209d9a Compare July 30, 2026 23:48
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 463fb35 to 22cf298 Compare July 30, 2026 23:48
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: 22cf298193

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/streamManager.ts
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 22cf298 to 825c5cd Compare July 31, 2026 00:36
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: 825c5cd852

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/streamManager.ts Outdated
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 825c5cd to 4211b69 Compare July 31, 2026 00:54
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@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: 4211b69950

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/streamManager.ts Outdated
Comment thread src/node/services/streamManager.ts
…eset

The per-session memory context cache (index snapshot + hot memories) was
cleared only at compaction boundaries, so deleted or renamed memory files
kept appearing in the advertised index for the rest of the segment.

Now any MemoryService change event invalidates all live sessions' caches,
and resetContext invalidates the affected session. Rebuild stays lazy on
the next stream. Tradeoff: a memory write mid-segment costs one prompt
cache miss on the next request; correct index beats cache stability.
@ibetitsmike
ibetitsmike force-pushed the mike/fix-memory-cache-invalidation branch from 4211b69 to fdac4dc Compare July 31, 2026 01:19
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: fdac4dce03

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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