Repository navigation
fix(memory): support the OpenCode V2 plugin API and session_v2 schema - #655
kristhianmanue1 wants to merge 1 commit into
Conversation
OpenCode V2 renamed its conversation tables (session/message/part -> session_v2/session_message, parts inlined into data.content) and replaced the V1 plugin API, so the installed plugin failed to load and both the hook capture path and the desktop scan ignored the V2 database entirely. - AgentSourceCore: new opencode-v2-source mappers project V2 rows onto the shared turn parser (sequential parent grouping, inline content parts, completion-timestamp finish signal) - opencode db-readers (Memory + App/backend): fall back to the V2 tables when the V1 tables are absent, in both the scan reader and the bridge hook reader - plugin template: dual entrypoint. The V1 helper import is now lazy so the file loads under V2, and a default export carries setup() for V2 (tools via ctx.tool.transform, prompt-hook recall injection, event stream capture) plus server() for V1 (>= 1.18.29) - tests: mapper unit tests plus V2-schema SQLite reader cases Verified live against OpenCode V2 + Memory 2.1.4 (see MemTensor#654). Closes MemTensor#654
|
Follow-up from live V2 testing: compaction detection won't fire (event name is V1) Two findings relevant to this PR:
Suggested adjustment (small): register Side note: the lazy first-prompt L3 preload ( |
|
Closing as superseded by the official OpenCode V2 support shipped in v1.2.4 — leaving this record for traceability. The ideas in this PR converged into the official implementation:
Verified live after upgrading 1.2.2 → 1.2.401 on macOS: the installer regenerated the plugin automatically and recall/capture work end-to-end on OpenCode v2.0.30. Thanks for the review consideration — happy to rebase any residual deltas if maintainers see value, otherwise this can rest. 🫡 TL;DR(中文):v1.2.4 已官方实现 OpenCode V2 支持,与本 PR 思路一致(免 SDK 插件、双入口、session_v2 读取、compaction 边界);已在 v1.2.401 实测,故关闭本 PR,感谢审阅。 |
Problem
Closes #654. Two independent breaks make the Memmy × OpenCode integration dead on OpenCode V2:
{ tool } from "@opencode-ai/plugin"statically and exports a V1-style hooks function. OpenCode V2 requires a default-exported{ id, setup(ctx) }definition and never invokes V1 entrypoints — the file fails at import resolution (Cannot find package '@opencode-ai/plugin'). Per the official migration guide: "V1 plugin implementations do not run in V2."session/message/partwithsession_v2/session_message(message parts inlined indata.content[], assistantparentIDdropped). Both readers — the desktop scan (db-reader.ts) and the plugin hook capture path (readOpencodeHookSourceTurn) — require the V1 tables and silently ignore a V2 database.Consequence: no recall injection, no turn capture, no
memmy_memory_*tools, no/memmy-resume, and nothing from OpenCode V2 reaches the viewer.Changes
AgentSourceCore/src/opencode-v2-source.ts(new)toOpencodeV2Session,toOpencodeV2MessageView(sequential parent grouping replacesparentID, completion timestamp becomes thefinishstop signal, bookkeeping row types dropped),toOpencodeV2MessageParts(userdata.text→ text part; inlinecontent[]→ text/tool/compaction parts; reasoning dropped)AgentSourceCore/src/index.tsMemory/src/agent-source/adapters/opencode/db-reader.ts,App/backend/.../opencode/db-reader.tscreateSourcetries V1 tables first, then falls back to a V2 source built from the shared mappers (per-session message query + O(1) message-by-id part lookup)workspace-bridge/runtime.tsreadOpencodeHookSourceTurngains the same V1/V2 dispatch viacreateOpencodeHookSource, so plugin capture and offline scan keep resolving one turn to one identitytemplates/memmy-opencode-plugin.ts@opencode-ai/pluginimport moved inside the V1 function (V1 provides the package at runtime; V2 never runs that path), and a default export carriessetup()for V2 plusserver()for V1 (object entrypoints supported since OpenCode 1.18.29). V2 setup: threememmy_memory_*tools viactx.tool.transform, recall injection through theprompthook (persisted text stays unwrappable by the existing<current_user_request>convention), capture onsession.idlewith a flush-on-next-prompt fallback, L3 preload, compaction boundaries, session cleanup,/memmy-resumeflow. Every Memmy failure degrades to a log line so a turn is never interrupted.AgentSourceCore/src/tests/opencode-v2-source.test.ts(new),Memory/tests/agent-source-opencode-reader.test.tssession_v2/session_messagedatabase (capture, subagent skip, open-ended turn left incomplete)The duplicated Memory/App-backend copies of the reader, bridge runtime, and template are kept byte-identical, matching the existing layout.
Validation
AgentSourceCore:vitest run src→ 67/67 (6 pre-existing files unaffected + new file)Memory:vitest run tests/agent-source-opencode-reader.test.ts→ 3/3 (1 pre-existing + 2 new V2 cases)tsc --noEmitclean forAgentSourceCoreandMemory(App/backend shows only pre-existing unresolved@memmy/local-api-contractsworkspace types in the local sandbox)node --check; template invariants hold (no backticks / interpolation inside the raw string)messageID== usersession_message.id), stored queries unwrapped, tool calls paired with status, parallel sessions captured,/memmy-resumeand the three memory tools working. The POC this PR formalizes is linked in [Bug] OpenCode V2 integration broken: plugin ships the V1 plugin API and both DB readers target the V1 schema #654.Compatibility
Happy to adjust to any house conventions (MEMMY-XXX tracking, commit scoping, test placement).