Merge pull request #1385 from pikasTech/codex/1374-message-lifecycle-reload

fix(workbench): preserve message lifecycle on reload
This commit is contained in:
Lyon
2026-06-17 12:53:19 +08:00
committed by GitHub
2 changed files with 23 additions and 5 deletions
+13 -3
View File
@@ -1544,6 +1544,8 @@ test("access controller preserves user message when owner evidence updates with
const conversationId = "cnv_issue853_owner_merge";
const sessionId = "ses_issue853_owner_merge";
const traceId = "trc_issue853_owner_merge";
const userMessageId = "msg_issue853_owner_merge_user";
const assistantMessageId = "msg_issue853_owner_merge_agent";
const threadId = "thread-issue-853-owner-merge";
const nowValue = "2026-06-04T10:45:00.000Z";
const userText = "请执行 hwpod inspect,并在最终回复里原样包含 HWLAB-853-FINAL-owner-merge";
@@ -1563,8 +1565,8 @@ test("access controller preserves user message when owner evidence updates with
sessionStatus: "running",
lastTraceId: traceId,
messages: [
{ id: "msg_issue853_owner_user", role: "user", title: "用户", text: userText, status: "sent", traceId, conversationId, sessionId, threadId, createdAt: nowValue },
{ id: "msg_issue853_owner_agent_pending", role: "agent", title: "Code Agent 处理中", text: "Code Agent 仍在处理,可以继续 steer 或等待 trace 完成。", status: "running", traceId, conversationId, sessionId, threadId, createdAt: nowValue }
{ id: userMessageId, messageId: userMessageId, role: "user", title: "用户", text: userText, status: "sent", traceId, turnId: traceId, conversationId, sessionId, threadId, createdAt: nowValue },
{ id: assistantMessageId, messageId: assistantMessageId, role: "agent", title: "Code Agent 处理中", text: "Code Agent 仍在处理,可以继续 steer 或等待 trace 完成。", status: "running", traceId, turnId: traceId, conversationId, sessionId, threadId, createdAt: nowValue }
],
messageCount: 2,
firstUserMessagePreview: userText,
@@ -1587,7 +1589,7 @@ test("access controller preserves user message when owner evidence updates with
status: "failed",
sessionStatus: "failed",
messages: [
{ id: "msg_issue853_owner_agent_result", role: "agent", title: "Code Agent result", text: "HyueAPI 403 INSUFFICIENT_BALANCE", status: "failed", traceId, conversationId, sessionId, threadId, createdAt: nowValue }
{ id: assistantMessageId, messageId: assistantMessageId, role: "agent", title: "Code Agent result", text: "HyueAPI 403 INSUFFICIENT_BALANCE", status: "failed", traceId, turnId: traceId, conversationId, sessionId, threadId, createdAt: nowValue }
],
messageCount: 1,
firstUserMessagePreview: userText,
@@ -1604,6 +1606,14 @@ test("access controller preserves user message when owner evidence updates with
assert.equal(conversation.messages[0].text, userText);
assert.equal(session.session.messages[0].traceId, traceId);
assert.equal(conversation.messages[0].traceId, traceId);
assert.equal(session.session.messages[0].messageId, userMessageId);
assert.equal(session.session.messages[0].turnId, traceId);
assert.equal(conversation.messages[0].messageId, userMessageId);
assert.equal(conversation.messages[0].turnId, traceId);
assert.equal(session.session.messages[1].messageId, assistantMessageId);
assert.equal(session.session.messages[1].turnId, traceId);
assert.equal(conversation.messages[1].messageId, assistantMessageId);
assert.equal(conversation.messages[1].turnId, traceId);
assert.equal(session.session.messages[1].text, "HyueAPI 403 INSUFFICIENT_BALANCE");
assert.equal(conversation.messages[1].status, "failed");
assert.equal(session.session.messageCount, 2);
+10 -2
View File
@@ -2549,13 +2549,16 @@ function mergeTerminalConversationMessages(existingMessages = [], result = {}, c
}).filter(Boolean);
let addedAgentMessage = false;
if (traceId && !next.some((message) => message.traceId === traceId && message.role === "agent")) {
const messageId = result.reply?.messageId ?? result.messageId ?? `msg_${traceId.slice(4)}_agent`;
next.push(redactConversationMessage({
id: result.reply?.messageId ?? result.messageId ?? `msg_${traceId.slice(4)}`,
id: messageId,
messageId,
role: "agent",
title: "Code Agent result",
text: assistantText,
status: terminalStatus,
traceId,
turnId: traceId,
conversationId: context.conversationId,
sessionId: context.sessionId,
threadId: context.threadId,
@@ -2577,13 +2580,16 @@ function ensureTerminalUserMessage(messages = [], context = {}) {
const userText = conversationText(context.firstUserPreview, 12000);
if (!userText) return messages;
const traceId = safeTraceIdLocal(context.traceId);
const messageId = traceId ? `msg_${traceId.slice(4)}_user` : `msg_terminal_user_${messages.length}`;
const userMessage = redactConversationMessage({
id: traceId ? `msg_${traceId.slice(4)}_user` : `msg_terminal_user_${messages.length}`,
id: messageId,
messageId,
role: "user",
title: "用户",
text: userText,
status: "sent",
traceId,
turnId: traceId,
conversationId: context.conversationId,
sessionId: context.sessionId,
threadId: context.threadId,
@@ -2617,11 +2623,13 @@ function redactConversationMessage(message) {
const text = conversationText(message.text ?? message.content ?? message.message, 12000);
return pruneEmpty({
id: textOr(message.id, ""),
messageId: textOr(message.messageId ?? message.id, ""),
role: textOr(message.role, ""),
title: textOr(message.title, ""),
text,
status: textOr(message.status, ""),
traceId: textOr(message.traceId, ""),
turnId: textOr(message.turnId ?? message.traceId, ""),
conversationId: textOr(message.conversationId, ""),
sessionId: textOr(message.sessionId, ""),
threadId: textOr(message.threadId, ""),