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
+18 -1
View File
@@ -9,7 +9,7 @@ import {
import { atomicWriteJson, listJsonFiles, readJsonFile } from "../utils/fileStore.js";
import { SessionContextMismatchError, type SessionRecord } from "./metadataStore.js";
type ChatRecordName = "messages.json" | "transcript.json" | "learning.json";
type ChatRecordName = "messages.json" | "transcript.json" | "learning.json" | "interaction-requests.json";
type LegacySources = { metadataDir: string; uiStateDir: string; transcriptDir: string; learningStateDir?: string };
const exists = async (path: string) => {
try { await lstat(path); return true; }
@@ -104,6 +104,23 @@ export class SessionWorkspaceStore {
});
}
/** Read, compare and replace under the same queue as message writes and deletion. */
async updateRecord<T>(
context: SessionWorkspaceContext,
name: ChatRecordName,
operation: (records: { messages: unknown; current: unknown }) => Promise<{ result: T; value?: object }>,
): Promise<T> {
return this.serialize(context, async () => {
if (!await this.validate(context, "messages.json") || !await this.validate(context, name)) throw new SessionContextMismatchError();
const messages = await readJsonFile<unknown>(this.path(context, "messages.json"));
const current = await readJsonFile<unknown>(this.path(context, name));
const update = await operation({ messages, current });
if (!await this.validate(context, "messages.json") || !await this.validate(context, name)) throw new SessionContextMismatchError();
if (update.value !== undefined) await atomicWriteJson(this.path(context, name), update.value as Record<string, unknown>, 0o600);
return update.result;
});
}
async markDeleted(context: SessionWorkspaceContext) {
return this.serialize(context, async () => {
const directory = await this.ensure(context, true);