From 6b9b3df64d5ef999270109a414e8de33dfcfa460 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Fri, 13 Mar 2026 11:43:56 -0600 Subject: [PATCH] fix: disable phantom tool injection when proxying for opencode opencode validates tool calls against its own registry and rejects unknown tools like memory_query. The opencode plugin provides mnemosyne_query/mnemosyne_status as registered MCP tools instead. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/mnemosyne/gateway.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/mnemosyne/gateway.py b/src/mnemosyne/gateway.py index 0428e08..070763c 100644 --- a/src/mnemosyne/gateway.py +++ b/src/mnemosyne/gateway.py @@ -1610,21 +1610,25 @@ def create_app( # 4. Build ephemeral outbound view — never mutate the physical store payload["messages"] = copy.deepcopy(ms.messages) - # 4a. Inject phantom tool definitions and resolve pending calls - from mnemosyne.phantom import inject_tools, inject_phantom_results, extract_phantom_calls - - observe_only = inject_tools(payload) - # Check for pending phantom calls from the previous assistant turn - pending_calls = extract_phantom_calls(payload.get("messages", [])) - if pending_calls: - inject_phantom_results( - payload["messages"], - pending_calls, - ps, - observe_only, - context_assembler=session.context_assembler, - session_id=session.id, - ) + # 4a. Phantom tool injection — DISABLED when proxying for opencode. + # opencode validates tool calls against its own registry and rejects + # unknown tools like memory_query. Phantom tools require SSE stream + # interception + auto-continue which the gateway doesn't implement + # for the pass-through streaming path. The opencode plugin provides + # mnemosyne_query/mnemosyne_status as registered MCP tools instead. + # + # from mnemosyne.phantom import inject_tools, inject_phantom_results, extract_phantom_calls + # observe_only = inject_tools(payload) + # pending_calls = extract_phantom_calls(payload.get("messages", [])) + # if pending_calls: + # inject_phantom_results( + # payload["messages"], + # pending_calls, + # ps, + # observe_only, + # context_assembler=session.context_assembler, + # session_id=session.id, + # ) # 4b. Apply fidelity-based content replacement _apply_fidelity(payload, session)