Skip to content

fix(memory): run extended-memory predictor concurrently with rerank - #100

Merged
jkyberneees merged 1 commit into
mainfrom
fix/predictor-deadline-starvation
Jul 25, 2026
Merged

fix(memory): run extended-memory predictor concurrently with rerank#100
jkyberneees merged 1 commit into
mainfrom
fix/predictor-deadline-starvation

Conversation

@jkyberneees

Copy link
Copy Markdown
Contributor

Problem

Every turn, extended-memory recall runs under a hard 5-second budget (FormatExtendedContext). Inside that window, queryAtomsWithPrediction executed two LLM calls sequentially:

  1. the paid rerank of literal-query results
  2. predictor.Predict for follow-up intent generation

When the memory LLM is slow (by default it reuses the main reasoning model), the rerank consumed most of the 5s window, so Predict inherited a nearly-expired context and failed before its LLM call could complete:

extended memory: predictor LLM failed: context deadline exceeded
extended memory: predicted-intent generation failed: predictor: context deadline exceeded

Fix

Run the predictor concurrently with the literal query + rerank, so both LLM calls share the full window in parallel instead of splitting it sequentially.

  • The predictor only calls the LLM (no shared state); the atom store and vector index are mutex-guarded — race-safe (verified with -race).
  • The result channel is buffered (cap 1), so the early-return error path cannot leak the goroutine.
  • Error handling, stats tracking (trackErr), and the follow-up sink behavior are unchanged.

Testing

  • go test -race ./internal/memory/... -count=1 — all pass
  • New regression test TestPredictionRunsConcurrentWithRerank: the rerank mock blocks until the predictor starts; under the old sequential behavior this deadlocks and fails the test.

Note

If a single memory LLM call exceeds the 5s per-turn budget on its own, prediction still degrades gracefully to literal-query recall (intended latency cap). Operators hitting that should configure a cheaper dedicated model via memory.extended.llm, as already recommended in docs/EXTENDED_MEMORY.md.

The per-turn recall has a hard 5s budget, and queryAtomsWithPrediction
ran two LLM calls sequentially: the paid rerank of literal-query results
followed by predictor.Predict. A slow memory LLM (by default the main
reasoning model) let the rerank consume most of the window, so Predict
inherited a nearly-expired context and failed immediately:

  extended memory: predictor LLM failed: context deadline exceeded
  extended memory: predicted-intent generation failed: predictor: context deadline exceeded

Run the predictor concurrently with the literal query instead, so both
LLM calls share the full window in parallel. The predictor only touches
the LLM (no shared state) and the store/index are mutex-guarded; the
result channel is buffered so the early-error path cannot leak the
goroutine.

Adds TestPredictionRunsConcurrentWithRerank, which deadlocks under the
old sequential behavior.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
odek 37c025e Commit Preview URL

Branch Preview URL
Jul 25 2026, 02:21 PM

@jkyberneees
jkyberneees merged commit 27c6299 into main Jul 25, 2026
8 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