diff --git a/internal/cloud/workbench-projection-writer.test.ts b/internal/cloud/workbench-projection-writer.test.ts index 8bf74f22..f6d0aade 100644 --- a/internal/cloud/workbench-projection-writer.test.ts +++ b/internal/cloud/workbench-projection-writer.test.ts @@ -90,6 +90,74 @@ test("workbench projection writer commits terminal owner evidence as sealed dura assert.equal(facts.checkpoints[0].timing.finishedAt, "2026-06-20T11:00:00.000Z"); }); +test("workbench projection writer does not rewrite prior-turn messages from merged owner session", async () => { + const factWrites = []; + const runtimeStore = { + async writeWorkbenchFacts(params, requestMeta) { + factWrites.push({ params, requestMeta }); + return { written: true, facts: params.facts }; + } + }; + const accessController = { + async recordAgentSessionOwner(input) { + return { + id: input.sessionId, + projectId: input.projectId, + ownerUserId: input.ownerUserId, + conversationId: input.conversationId, + threadId: input.threadId, + lastTraceId: input.traceId, + status: input.status, + updatedAt: "2026-06-20T11:10:00.000Z", + session: { + sessionStatus: "completed", + lastTraceId: input.traceId, + messages: [ + { messageId: "msg_writer_r1_user", role: "user", text: "round1 prompt", status: "sent", turnId: "trc_writer_r1", traceId: "trc_writer_r1" }, + { messageId: "msg_writer_r1_agent", role: "agent", text: "WRONG_ROUND2_TEXT", status: "completed", turnId: "trc_writer_r1", traceId: "trc_writer_r1" }, + ...input.session.messages + ] + } + }; + } + }; + + await writeWorkbenchProjectionSession({ + accessController, + runtimeStore, + traceId: "trc_writer_r2", + ownerUserId: "usr_writer", + ownerRole: "user", + sessionId: "ses_writer_multi_turn", + projectId: "prj_writer", + conversationId: "cnv_writer_multi_turn", + threadId: "thread-writer-multi-turn", + status: "completed", + payload: { + traceId: "trc_writer_r2", + status: "completed", + finalResponse: { text: "ROUND2_DONE", status: "completed", traceId: "trc_writer_r2" }, + agentRun: { runId: "run_writer_r2", commandId: "cmd_writer_r2", status: "completed", terminalStatus: "completed", lastSeq: 9 }, + updatedAt: "2026-06-20T11:10:00.000Z" + }, + session: { + sessionStatus: "completed", + messages: [ + { messageId: "msg_writer_r2_user", role: "user", text: "round2 prompt", status: "sent", turnId: "trc_writer_r2", traceId: "trc_writer_r2" }, + { messageId: "msg_writer_r2_agent", role: "agent", text: "ROUND2_DONE", status: "completed", turnId: "trc_writer_r2", traceId: "trc_writer_r2" } + ] + } + }); + + assert.equal(factWrites.length, 1); + const facts = factWrites[0].params.facts; + assert.deepEqual(facts.messages.map((message) => message.messageId), ["msg_writer_r2_user", "msg_writer_r2_agent"]); + assert.equal(facts.messages.some((message) => message.traceId === "trc_writer_r1"), false); + assert.equal(facts.messages.find((message) => message.messageId === "msg_writer_r2_agent").text, "ROUND2_DONE"); + assert.equal(facts.turns[0].traceId, "trc_writer_r2"); + assert.equal(facts.turns[0].finalResponse.text, "ROUND2_DONE"); +}); + test("workbench projection writer seals canceled AgentRun turns with canonical cancel final response", async () => { const factWrites = []; const runtimeStore = { diff --git a/internal/cloud/workbench-projection-writer.ts b/internal/cloud/workbench-projection-writer.ts index f4ddfdd2..0e8e4b6e 100644 --- a/internal/cloud/workbench-projection-writer.ts +++ b/internal/cloud/workbench-projection-writer.ts @@ -35,7 +35,7 @@ export async function writeWorkbenchProjectionSession({ accessController, runtim conversationId: ownerRecord?.conversationId ?? conversationId, threadId: ownerRecord?.threadId ?? threadId, status: ownerRecord?.status ?? status, - session: ownerRecord?.session ?? session, + session, payload, params });