Skip to content

fix(opencode): inject agentmemory context on every turn, not just turn 1 - #1325

Open
Chewji9875 wants to merge 2 commits into
rohitg00:mainfrom
Chewji9875:fix/opencode-context-multiturn
Open

fix(opencode): inject agentmemory context on every turn, not just turn 1#1325
Chewji9875 wants to merge 2 commits into
rohitg00:mainfrom
Chewji9875:fix/opencode-context-multiturn

Conversation

@Chewji9875

@Chewji9875 Chewji9875 commented Sep 2, 2026

Copy link
Copy Markdown

Problem

OpenCode's <agentmemory-context> injection only lands on turn 1 step 0; every subsequent step/turn in the session silently loses memory context.

Live call-log analysis across all sessions (OmniRoute gateway):

  • Request 1: sysInst=true | sysCtx=true
  • Requests 2..N (100%): sysInst=false | sysCtx=false

Root cause: OpenCode builds a fresh output.system array on every LLM step. The plugin gated injection on contextInjectedSessions.has(sid) + startContextCache.delete(sid) after first use — so step 0 consumes the injection and all later turns get nothing.

Fix (plugin/opencode/agentmemory-capture.ts)

  1. Robust internal-request skip — check (input as any)?.agent === "title" | "compaction" and input?.small === true, keeping the brittle title-regex as fallback. (Supersedes the fragile string-match-only guard.)
  2. Inject on EVERY regular chat step — push AGENTMEMORY_INSTRUCTIONS + cached startContext (fall back to /context and re-cache, don't delete). Identical bytes per turn → prefix cache 100% preserved (Token input cache rate dropped ~10pp due to per-turn system prompt mutation #720).
  3. Volatile file enrichment stays in messages.transform (message tail) — never touches output.system.

Validation

Live E2E (fresh session, opencode run):

  • Title generator call: context skipped (correct)
  • Turn 1: inst=true | ctx=true
  • Turn 2: inst=true | ctx=true (previously impossible)
  • Turn 2 token usage: cache.read=60672 — prefix cache hit confirmed
  • Compression calls: no context (correct)

npm test: 159 files, 1,718 tests pass.

Summary by CodeRabbit

  • Bug Fixes
    • Chat context is now refreshed on every regular conversation turn, preserving context across multi-turn sessions.
    • Resumed sessions can recover context when cached data is unavailable.
    • Internal utility requests and title-generation prompts no longer receive regular chat memory instructions.
    • Automatic file enrichment during context injection has been removed.

OpenCode builds a fresh output.system array on each LLM step. The old
one-time gate (contextInjectedSessions.add(sid) + startContextCache
delete after first use) meant only step 0 of turn 1 received
<agentmemory-instructions>/<agentmemory-context>; every subsequent
step/turn in the session lost memory context entirely. Live call logs
showed sysCtx=false on 100% of requests after the first.

- skip internal requests via (input as any)?.agent === 'title' |
  'compaction' or input?.small === true (robust; keeps brittle
  regex as fallback)
- push AGENTMEMORY_INSTRUCTIONS + cached startContext on EVERY regular
  chat step; identical bytes per turn → prefix cache 100% preserved (rohitg00#720)
- keep volatile file enrichment in messages.transform (message-tail)
@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown

@Chewji9875 is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 34831adc-ac22-4342-b513-7c3a932d29e7

📥 Commits

Reviewing files that changed from the base of the PR and between 8c05f16 and 6a2a381.

📒 Files selected for processing (2)
  • plugin/opencode/agentmemory-capture.ts
  • test/opencode-auto-context.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The OpenCode system transform now injects memory instructions and start context on every regular chat step. It skips internal utility requests and title-generation prompts. Tests cover cache reuse and resumed-session refetch.

Changes

OpenCode context injection

Layer / File(s) Summary
Per-turn transform and test validation
plugin/opencode/agentmemory-capture.ts, test/opencode-auto-context.test.ts
The transform uses typed input and context shapes, skips internal requests, injects cached or freshly fetched context on regular steps, and removes the session injection gate and file enrichment. Source assertions verify the updated transform and session cleanup behavior.
Behavioral transform coverage
test/opencode-auto-context.test.ts
Tests verify identical context injection across multiple turns, filtering for title, compaction, small-model, and legacy title prompts, and cache population and reuse for resumed sessions.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 6a2a3

OpenCode chat steps now consistently receive cached memory context while internal title, compaction, and small-model requests remain unchanged. The covered behavior is ready to merge.

Suggested reviewers: rohitg00

Sequence Diagram(s)

sequenceDiagram
  participant OpenCodeChat
  participant TransformHook
  participant StartContextSource
  OpenCodeChat->>TransformHook: system transform request
  alt Internal utility request or title-generation prompt
    TransformHook-->>OpenCodeChat: return without injection
  else Regular chat step
    TransformHook->>StartContextSource: read cached or fresh start context
    StartContextSource-->>TransformHook: start context
    TransformHook-->>OpenCodeChat: memory instructions and start context
  end
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: injecting AgentMemory context on every OpenCode chat turn instead of only the first turn.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…te, and add multi-turn tests

- Remove unused contextInjectedSessions dead state from module and cleanup hooks
- Typecast transform input via OpenCodeChatTransformInput interface with justification comment
- Replace raw any in /context response parsing with OpenCodeContextResponse interface
- Remove redundant consecutive Array.isArray(output.system) guards
- Add comprehensive multi-turn behavioral test cases verifying context persistence across turns, prefix cache preservation (rohitg00#720), and internal agent skipping (rohitg00#1184)

Signed-off-by: Choti Wongbussakorn <126886556+Chewji9875@users.noreply.github.com>
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