












@@ -294,6 +294,74 @@ describe("rewriteTranscriptEntriesInSessionManager", () => {
294294});
295295296296describe("rewriteTranscriptEntriesInSessionFile", () => {
297+it("aborts under the write lock when the active suffix contains an unexpected entry", async () => {
298+const dir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-transcript-rewrite-guard-"));
299+const sessionManager = SessionManager.create(dir, dir);
300+const entryIds = appendSessionMessages(sessionManager, [
301+asAppendMessage({
302+role: "user",
303+content: "start",
304+timestamp: 1,
305+}),
306+asAppendMessage({
307+role: "assistant",
308+content: createTextContent("source reply media"),
309+timestamp: 2,
310+}),
311+asAppendMessage({
312+role: "assistant",
313+content: createTextContent("source reply text"),
314+timestamp: 3,
315+}),
316+asAppendMessage({
317+role: "user",
318+content: "concurrent append",
319+timestamp: 4,
320+}),
321+]);
322+const sessionFile = requireString(sessionManager.getSessionFile(), "persisted session file");
323+const mediaEntryId = entryIds[1];
324+const textEntryId = entryIds[2];
325+const listener = vi.fn();
326+const cleanup = onSessionTranscriptUpdate(listener);
327+328+try {
329+const result = await rewriteTranscriptEntriesInSessionFile({
330+ sessionFile,
331+sessionKey: "agent:main:test",
332+request: {
333+allowedRewriteSuffixEntryIds: [mediaEntryId, textEntryId],
334+replacements: [
335+{
336+entryId: mediaEntryId,
337+message: asAppendMessage({
338+role: "assistant",
339+content: createTextContent("rewritten source reply media"),
340+timestamp: 2,
341+}) as AgentMessage,
342+},
343+],
344+},
345+});
346+347+expect(result).toMatchObject({
348+changed: false,
349+reason: "rewrite suffix guard failed",
350+});
351+expect(listener).not.toHaveBeenCalled();
352+353+const unchangedSession = SessionManager.open(sessionFile);
354+expect(getBranchMessages(unchangedSession).map((message) => message.content)).toEqual([
355+"start",
356+createTextContent("source reply media"),
357+createTextContent("source reply text"),
358+"concurrent append",
359+]);
360+} finally {
361+cleanup();
362+}
363+});
364+297365it("emits transcript updates when the active branch changes without opening a manager", async () => {
298366const dir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-transcript-rewrite-"));
299367const sessionManager = SessionManager.create(dir, dir);
此內容由慣性聚合(RSS閱讀器)自動聚合整理,僅供閱讀參考。 原文來自 — 版權歸原作者所有。