fix: preserve interaction replies across chat recovery

This commit is contained in:
2026-10-29 17:53:33 +08:00
parent fbe273e90a
commit 52681a8451
38 changed files with 1623 additions and 314 deletions
+35
View File
@@ -0,0 +1,35 @@
import type { Plugin } from "@opencode/plugin";
import { getInternalBridgeConfig } from "./internalBridge.js";
export async function hostQuestionBridge(operation: string, body: Record<string, unknown>, signal?: AbortSignal): Promise<unknown> {
const { baseUrl, internalToken } = getInternalBridgeConfig();
const response = await fetch(`${baseUrl}/internal/chat-interactions/${operation}`, {
method: "POST", headers: { "content-type": "application/json", "x-agent-internal-token": internalToken },
body: JSON.stringify(body), signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(10000)]) : AbortSignal.timeout(10000),
});
if (!response.ok) throw new Error("Interaction gate rejected the operation. Finish existing tools before asking, then wait for the user.");
return response.json();
}
export async function registerHostQuestionPolicy(ctx: Parameters<Plugin.Plugin["setup"]>[0]) {
await ctx.session.hook("context", async (event) => {
const policy = await hostQuestionBridge("policy", { session_id: event.sessionID }) as { enabled: boolean; waiting: boolean };
if (!policy.enabled) delete event.tools.ask_user;
else {
delete event.tools.question;
if (policy.waiting) for (const name of Object.keys(event.tools)) delete event.tools[name];
}
});
// Wrap native, MCP and custom executors, including calls via Code Mode.
await ctx.tool.transform((editor) => {
for (const definition of editor.list()) editor.update(definition.id, (draft) => {
const execute = draft.execute;
draft.execute = async (input, context) => {
const identity = { session_id: context.sessionID, call_id: context.id, tool: definition.id };
await hostQuestionBridge("enter", identity, context.signal);
try { return await execute(input, context); }
finally { await hostQuestionBridge("leave", identity).catch(() => undefined); }
};
});
});
}