fix: preserve interaction replies across chat recovery
This commit is contained in:
@@ -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); }
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user