Skip to content

fix(plugin): add session instruction injection and consolidation pipeline (closes #233)#239

Closed
cl0ckt0wer wants to merge 4 commits into
rohitg00:mainfrom
cl0ckt0wer:fix/opencode-clco-parity
Closed

fix(plugin): add session instruction injection and consolidation pipeline (closes #233)#239
cl0ckt0wer wants to merge 4 commits into
rohitg00:mainfrom
cl0ckt0wer:fix/opencode-clco-parity

Conversation

@cl0ckt0wer
Copy link
Copy Markdown
Contributor

@cl0ckt0wer cl0ckt0wer commented May 8, 2026

Summary

Three gaps from the clco→oco port sweep:

  1. Session instruction injection — Injects agentmemory usage instructions (covering memory_save, memory_recall, memory_smart_search, memory_file_history, memory_lesson_save/recall, etc.) into the system prompt on the first turn of every session via experimental.chat.system.transform. Replaces the Claude Code skills mechanism (SKILL.md files) which OpenCode has no equivalent for.

  2. Consolidation pipeline on session end — Calls /crystals/auto and /consolidate-pipeline on session.deleted, mirroring Claude's CONSOLIDATION_ENABLED=true behavior. Both are best-effort with 5s timeout.

  3. MEMORY.md vs AGENTS.md docs — Detailed architecture comparison in README explaining the two-hop (agentmemory → MEMORY.md → system prompt) vs one-hop (agentmemory → system prompt) approaches.

Cannot fix

  • SubagentStop — OpenCode's SubtaskPart type has no completion/result fields
  • Claude MEMORY.md bridge — OpenCode-specific (OpenCode uses AGENTS.md as static config, not a writable memory file)

Files changed

  • plugin/opencode/agentmemory-capture.ts — +43 lines (instruction block + consolidation calls)
  • plugin/opencode/README.md — +49 lines (architecture comparison + updated gap table)

Summary by CodeRabbit

  • New Features

    • Added an OpenCode plugin to capture rich session, message, file, and command events and augment prompts with fetched context
    • Added /recall command to retrieve grouped session insights and lessons
    • Added /remember command to persist insights for future recall
    • Published plugin manifest (versioned) for installation
  • Documentation

    • Expanded compatibility table and setup instructions for OpenCode
    • Added plugin README, slash-command usage, and roadmap entry detailing hook coverage and planned integration

xuli500177 and others added 3 commits May 7, 2026 22:01
- 22 hook handlers across session lifecycle, messages, tool lifecycle, parts, files, permissions, tasks, commands, and config
- Two-layer enrichment pipeline: /context + /enrich via system.transform
- Two slash commands: /recall and /remember
- Full Claude Code hook parity documented with gap analysis
mem::observe checks hookType === "prompt_submit" to extract raw.userPrompt
and set session.firstPrompt. The plugin was using "user_prompt_submit" which
didn't match, so sessions were never named.
…line (closes rohitg00#233)

Three gaps from the Claude Code plugin port sweep:

- Inject agentmemory usage instructions (memory_save, memory_recall, etc.) into the system prompt on first turn via experimental.chat.system.transform, replacing the skills mechanism that OpenCode lacks
- Call /crystals/auto and /consolidate-pipeline on session.deleted, mirroring Claude's CONSOLIDATION_ENABLED behavior
- Document MEMORY.md vs AGENTS.md architecture comparison (two-hop file bridge vs one-hop direct injection)

Gap A (SubagentStop) is unfixable — OpenCode's SubtaskPart type has no completion/result fields.
Gap C (Claude MEMORY.md bridge) is intentionally skipped — OpenCode uses direct injection.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 8, 2026

@cl0ckt0wer 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
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b19616d4-e233-41dd-b4cf-0205a21cdb6a

📥 Commits

Reviewing files that changed from the base of the PR and between 1dc6848 and 0aeab27.

📒 Files selected for processing (4)
  • plugin/opencode/README.md
  • plugin/opencode/agentmemory-capture.ts
  • plugin/opencode/commands/recall.md
  • plugin/opencode/commands/remember.md
✅ Files skipped from review due to trivial changes (2)
  • plugin/opencode/commands/remember.md
  • plugin/opencode/commands/recall.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugin/opencode/agentmemory-capture.ts

📝 Walkthrough

Walkthrough

Adds an OpenCode plugin (agentmemory-capture), manifest, command docs (/recall, /remember), README/ROADMAP updates, and a capture implementation that posts observations to agentmemory and injects session/file context via /context and /enrich during system transform and compaction.

Changes

OpenCode Plugin for Agentmemory

Layer / File(s) Summary
Plugin Manifest
plugin/opencode/plugin.json
Plugin metadata defines agentmemory-capture v0.9.4 with author, license, and repository links.
Plugin Documentation
plugin/opencode/README.md, README.md
Quick start and install steps; MCP config example updated to include plugin entry and instructions to copy plugin and command files; agents table updated to "22 hooks + MCP + plugin".
Capture Matrix & Comparison
plugin/opencode/README.md
Enumerates captured OpenCode hooks, file enrichment pipeline, two-layer context injection (/context then /enrich), and comparison to Claude Code MEMORY.md approach.
Network Initialization
plugin/opencode/agentmemory-capture.ts (lines 1–47)
HTTP helpers (post, postJson) with timeout and error handling; observe(...) wrapper sending structured observations.
Session State & Prompt
plugin/opencode/agentmemory-capture.ts (lines 48–135)
Per-session state for active session/project, file stash, dedupe sets; AGENTMEMORY_INSTRUCTIONS system-prompt block.
Event Handler & Hooks
plugin/opencode/agentmemory-capture.ts (lines 137–486)
Main event handler for session/message/part lifecycle; captures tool calls, subtasks, file edits, permissions, todos, command execution, and emits deduplicated observations.
chat.message / chat.params hooks
plugin/opencode/agentmemory-capture.ts (lines 488–527)
chat.message posts prompt_submit observations with parts and model/agent info; chat.params emits LLM telemetry and cost estimates.
Tool File Stash
plugin/opencode/agentmemory-capture.ts (lines 529–545)
tool.execute.before extracts and stashes file-path-like args for whitelisted file tools.
System Transform Injection
plugin/opencode/agentmemory-capture.ts (lines 546–577)
experimental.chat.system.transform injects instructions, fetches /context, clears stash and fetches /enrich when files exist, and appends returned context to the system prompt.
Session Compacting
plugin/opencode/agentmemory-capture.ts (lines 579–591)
experimental.session.compacting fetches /context and appends returned entries into compaction output.
Config Events
plugin/opencode/agentmemory-capture.ts (lines 593–606)
Emits config_loaded observations when a session is active.
Slash Commands (docs)
plugin/opencode/commands/recall.md, plugin/opencode/commands/remember.md
/recall wraps memory search tools and formats grouped results; /remember wraps memory_save to persist insights with concepts and file refs.
Integration & Roadmap
README.md, ROADMAP.md
Roadmap adds Q2 2026 OpenCode hook bus entry enumerating covered hook types and points to plugin/opencode/.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 I hop through hooks and stash a file,

I call /context to save a while,
Then /enrich returns its timely lore,
/recall and /remember open memory's door,
A rabbit's notes persist forevermore.

🚥 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%. 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 PR title clearly and specifically describes the main change: adding session instruction injection and consolidation pipeline to the OpenCode plugin, directly matching the core objectives of filling gaps in the Claude Code → OpenCode port.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugin/opencode/agentmemory-capture.ts`:
- Around line 48-54: The global session state (stashedFiles, seenSubtaskIds,
seenToolCallIds, plus activeSessionId/projectPath) risks cross-session leakage;
convert these process-level Sets into session-keyed maps (e.g., Map<string,
Set<string>> keyed by sessionId) and update all accesses in this file to
read/write via the current sessionId (replace direct uses of stashedFiles,
seenSubtaskIds, seenToolCallIds with sessionScoped getters/creators and
clearers). Ensure you update all affected locations (the reads/writes/clears
referenced around lines ~371-375, ~413-418, ~521-525, ~529-557 and the
enrichment logic at line ~545) to use the session-scoped collections, and add
cleanup logic on session.deleted to remove the session key and free its Sets;
also ensure any uses of activeSessionId/projectPath are session-scoped or passed
explicitly to avoid relying on process-global state.
- Around line 19-30: The postJson function currently returns res.json() without
awaiting it, which lets JSON parse rejections escape the try/catch; update
postJson (the async function postJson) to await the JSON parsing result (i.e.,
await res.json()) so any parsing errors are caught by the existing try/catch and
the function returns null on failure, ensuring callers (those awaiting postJson)
do not receive unhandled rejections.

In `@plugin/opencode/commands/recall.md`:
- Around line 5-7: The usage code fence in the markdown snippet for the recall
command lacks a language tag; update the fenced code block that contains
"/recall [query]" in recall.md to use a language tag (e.g., add ```text at the
opening fence) so the block becomes a labeled text code fence and satisfies
markdownlint MD040.

In `@plugin/opencode/commands/remember.md`:
- Around line 5-7: The Markdown usage code fence for the /remember command is
missing a language tag; update the fenced block that contains "/remember [what
to remember]" to use a language tag (e.g., text) so the block becomes ```text
... ```, which will satisfy markdownlint MD040 and keep the docs lint-clean.

In `@plugin/opencode/README.md`:
- Around line 153-157: The three fenced code blocks containing the examples
starting with "System prompt = [OpenCode instructions]..." and the two diagram
blocks beginning "agentmemory  ──write──▶  MEMORY.md..." and "agentmemory 
──push──▶  OpenCode system prompt" are missing language identifiers; add a
language tag (e.g., ```text) to each opening fence so the blocks become ```text
... ``` to satisfy the MD040 lint rule and reduce markdown-lint noise.
- Around line 216-217: Update the session-instruction docs to use the correct
tool prefix: replace the incorrect `agentmemory_memory_*` with `agentmemory_*`
in the sentence that describes injection via
`experimental.chat.system.transform` (the system prompt /context memory
description), ensuring the text now reads that the agent learns which
`agentmemory_*` tools to use and when.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 237f5710-67f7-432c-a8c9-30ed80b77135

📥 Commits

Reviewing files that changed from the base of the PR and between 1effa2c and 1dc6848.

📒 Files selected for processing (7)
  • README.md
  • ROADMAP.md
  • plugin/opencode/README.md
  • plugin/opencode/agentmemory-capture.ts
  • plugin/opencode/commands/recall.md
  • plugin/opencode/commands/remember.md
  • plugin/opencode/plugin.json

Comment thread plugin/opencode/agentmemory-capture.ts
Comment thread plugin/opencode/agentmemory-capture.ts
Comment thread plugin/opencode/commands/recall.md Outdated
Comment thread plugin/opencode/commands/remember.md Outdated
Comment thread plugin/opencode/README.md Outdated
Comment thread plugin/opencode/README.md Outdated
@cl0ckt0wer
Copy link
Copy Markdown
Contributor Author

Fixed all 6 CodeRabbit review findings:

  1. postJson unhandled rejections (agentmemory-capture.ts:27) — added await before res.json() so JSON parse errors are caught by the try/catch instead of escaping as unhandled promise rejections.

  2. Cross-session state leakage (agentmemory-capture.ts:48-65) — converted stashedFiles, seenSubtaskIds, seenToolCallIds from process-level Set<string> to Map<string, Set<string>> keyed by sessionId. Added stashFor(), subtasksFor(), toolCallsFor() getter helpers. Cleanup on session.deleted deletes the Map entries to free memory. Added null guard in tool.execute.before since it doesn't receive sessionId directly.

  3. Markdownlint MD040 in recall.md — added text language tag: ```text

  4. Markdownlint MD040 in remember.md — added text language tag: ```text

  5. Markdownlint MD040 in plugin/opencode/README.md — added text language tags to all 3 unnamed code fences (system prompt example and two diagram blocks).

  6. Wrong tool prefix in README.md line 216agentmemory_memory_*agentmemory_* (consistent with the injected instructions).

@rohitg00
Copy link
Copy Markdown
Owner

rohitg00 commented May 8, 2026

Thanks @cl0ckt0wer — the three gaps you identified (session-instruction injection via experimental.chat.system.transform, consolidation pipeline on session.deleted, etc.) are real and the fixes look right.

Coordination — see also #237. Both PRs touch the exact same files (plugin/opencode/*, README.md, ROADMAP.md) and were opened ~1.5h apart from the same author. They'll conflict if landed independently.

I've asked over on #237 to either fold these gap-fixes into that PR (preferred — single OpenCode plugin PR), or land #237 first and rebase this one to be a clean diff of just the three gap fixes. Either way the underlying work lands with full attribution to you.

Holding both for now until the consolidation strategy is clear. Once that's done I'll review the merged version straight through — the per-gap reasoning is well documented in the body, so once the diff isolates just those gaps it'll be a fast review.

Also: I noticed the plugin badge here says "44 MCP tools" but in #237 it says "51". The current tools-registry.ts ships 51. Either the count needs to match the actual exposed-by-plugin number, or — preferred — derive it from getVisibleTools() length so it doesn't go stale.

@cl0ckt0wer
Copy link
Copy Markdown
Contributor Author

Folded into #237 per Option A. The three gap fixes are now on feature/opencode-plugin:

  • Session instruction injection via AGENTMEMORY_INSTRUCTIONS constant + experimental.chat.system.transform
  • Consolidation pipeline calls on session.deleted (/crystals/auto + /consolidate-pipeline)
  • await res.json() fix for proper error handling

Cherry-picked the unique commit onto #237's branch and resolved conflicts. Ready for consolidated review on #237.

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.

3 participants