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
+19
View File
@@ -1,5 +1,8 @@
import { type Router } from "express";
import { z } from "zod";
import type { InteractionRequestStore } from "../sessions/interaction-request-store.js";
import type { OpencodeRuntimeAdapter } from "../runtime/opencode.js";
import { getRuntimeSessionContext, setRuntimeSessionContext } from "../runtime/sessionContext.js";
import { getLocalAgentContext } from "../context/localContext.js";
import { type ChatSessionBridge } from "../chat/sessionBridge.js";
@@ -20,6 +23,8 @@ const abortPayloadSchema = z.object({
});
type RegisterAuxiliaryRoutesOptions = {
interactionRequestStore?: InteractionRequestStore;
runtime?: OpencodeRuntimeAdapter;
activeRuns: Map<string, ActiveRun>;
lastRunStatuses: Map<string, RunStatus>;
sessionBridge: ChatSessionBridge;
@@ -37,6 +42,8 @@ const toSessionUiStateContext = (record: { sessionId: string; actorKey: string;
export const registerChatAuxiliaryRoutes = (
chatRouter: Router,
{
interactionRequestStore,
runtime,
activeRuns,
lastRunStatuses,
sessionBridge,
@@ -70,6 +77,18 @@ export const registerChatAuxiliaryRoutes = (
return;
}
frontendActionCoordinator.cancelSession(sessionRecord.sessionId);
const runtimeContext = getRuntimeSessionContext(sessionRecord.sessionId);
if (runtimeContext) setRuntimeSessionContext({ ...runtimeContext, hostQuestionClosed: true });
activeRuns.get(sessionRecord.sessionId)?.controller.abort();
await interactionRequestStore?.cancelPending(toSessionUiStateContext(sessionRecord));
const pendingInteraction = await interactionRequestStore?.getBlocking(toSessionUiStateContext(sessionRecord));
if (pendingInteraction?.delivery && runtime && interactionRequestStore) {
const status = await runtime.stopInteractionInput(sessionRecord.sessionId, pendingInteraction.delivery.native_message_id);
const latest = await interactionRequestStore.get(toSessionUiStateContext(sessionRecord), pendingInteraction.interaction_id);
if (latest?.delivery && !["delivered", "cancelled"].includes(latest.delivery.status)) await interactionRequestStore.updateDelivery(toSessionUiStateContext(sessionRecord), latest.interaction_id, {
expected_revision: latest.delivery.revision, status,
});
}
activeRuns.get(sessionRecord.sessionId)?.inputs?.close();
const binding = await sessionBridge.abort({
clientSessionId: sessionRecord.sessionId,