fix: preserve interaction replies across chat recovery
This commit is contained in:
@@ -5,6 +5,8 @@ import { type Router } from "express";
|
||||
import { z } from "zod";
|
||||
|
||||
import { type ChatSessionBridge } from "../chat/sessionBridge.js";
|
||||
import { projectInteractionReplyMessages } from "../chat/interaction-message-presentation.js";
|
||||
import type { InteractionRequestStore } from "../sessions/interaction-request-store.js";
|
||||
import { agentModelOptions } from "../chat/models.js";
|
||||
import { config } from "../config.js";
|
||||
import {
|
||||
@@ -76,6 +78,7 @@ const forkPayloadSchema = z.object({
|
||||
});
|
||||
|
||||
type RegisterChatSessionRoutesOptions = {
|
||||
interactionRequestStore?: InteractionRequestStore;
|
||||
learningOrchestrator: LearningOrchestrator;
|
||||
frontendActionCoordinator: FrontendActionCoordinator;
|
||||
runState: ChatRunState;
|
||||
@@ -100,6 +103,7 @@ export const registerChatSessionRoutes = (
|
||||
options: RegisterChatSessionRoutesOptions,
|
||||
) => {
|
||||
const {
|
||||
interactionRequestStore,
|
||||
frontendActionCoordinator,
|
||||
learningOrchestrator,
|
||||
runState,
|
||||
@@ -113,6 +117,17 @@ export const registerChatSessionRoutes = (
|
||||
const { activeRuns, lastRunStatuses } = runState;
|
||||
const getSessionRunStatus = runState.getStatus;
|
||||
|
||||
const withInteractionReplies = async (record: SessionRecord, messages: unknown[]) => {
|
||||
if (!interactionRequestStore) return messages;
|
||||
const ids = new Set(messages.flatMap((message) => {
|
||||
if (!message || typeof message !== "object") return [];
|
||||
const value = message as Record<string, unknown>;
|
||||
return value.role === "user" && typeof value.id === "string" ? [value.id] : [];
|
||||
}));
|
||||
const replies = await interactionRequestStore.forMessages(toSessionUiStateContext(record), ids);
|
||||
return projectInteractionReplyMessages(messages, replies);
|
||||
};
|
||||
|
||||
const refreshCollaborationTitle = async (record: SessionRecord, credential: ProductCredential | null, knownTaskTitle?: string, signal?: AbortSignal) => {
|
||||
if (readPurpose(record) !== "task_collaboration" || !record.taskId
|
||||
|| !isGenericTaskCollaborationTitle(record.title)) return record;
|
||||
@@ -603,8 +618,8 @@ export const registerChatSessionRoutes = (
|
||||
const messages = readPurpose(record) === "task_collaboration" ? state?.messages ?? []
|
||||
: activeRuns.get(record.sessionId)?.messages ?? state?.messages ?? [];
|
||||
try {
|
||||
res.json(sessionMessagePage(messages, { scope: historyScope([record.actorKey, record.projectKey, record.sessionId]),
|
||||
...query.data }));
|
||||
const page = sessionMessagePage(messages, { scope: historyScope([record.actorKey, record.projectKey, record.sessionId]), ...query.data });
|
||||
res.json({ ...page, messages: await withInteractionReplies(record, page.messages) });
|
||||
} catch (error) {
|
||||
if (!(error instanceof HistoryCursorError)) throw error;
|
||||
res.status(400).json({ message: error.message });
|
||||
@@ -659,6 +674,7 @@ export const registerChatSessionRoutes = (
|
||||
status: sessionRecord.status,
|
||||
session_id: sessionRecord.sessionId,
|
||||
...messagePayload,
|
||||
messages: await withInteractionReplies(sessionRecord, messagePayload.messages),
|
||||
execution_plans: state?.executionPlans ?? [],
|
||||
parent_session_id: sessionRecord.parentSessionId,
|
||||
is_streaming: activeRuns.get(sessionRecord.sessionId)?.status === "running",
|
||||
@@ -709,6 +725,7 @@ export const registerChatSessionRoutes = (
|
||||
toSse("state", {
|
||||
session_id: sessionRecord.sessionId,
|
||||
...messagePayload,
|
||||
messages: await withInteractionReplies(sessionRecord, messagePayload.messages),
|
||||
execution_plans: run ? undefined : state?.executionPlans,
|
||||
is_streaming: run?.status === "running",
|
||||
run_status: getSessionRunStatus(sessionRecord.sessionId),
|
||||
|
||||
Reference in New Issue
Block a user