fix(workbench): persist user message through event projection (#2045)

This commit is contained in:
Lyon
2026-06-24 15:01:46 +08:00
committed by GitHub
parent 8bdab4ac56
commit fbc23d20a9
+24 -17
View File
@@ -144,6 +144,7 @@ export async function writeWorkbenchProjectionEvent({ runtimeStore = null, event
const previousFinalText = finalResponseTextValue(previousCheckpoint?.finalResponse, previousCheckpoint?.assistantText, previousCheckpoint?.finalText);
const messageFinalText = finalResponseTextValue(event.finalResponse, event.assistantText, event.reply, previousFinalText);
const checkpointFinalResponse = messageFinalText ? { text: messageFinalText, status, traceId, valuesPrinted: false } : null;
const userMessageFact = sessionId && !suppressedAfterSeal && previousCheckpoint?.userMessage ? normalizeMessageFact(previousCheckpoint.userMessage, 0, { traceId, sessionId, turnId, terminal: false, terminalStatus: "sent", finalText: null, timestamp: projectedAt, timing }) : null;
const messageFact = sessionId && !suppressedAfterSeal ? normalizeMessageFact({
messageId: eventProjectionAssistantMessageId(traceId, event),
role: "agent",
@@ -164,7 +165,7 @@ export async function writeWorkbenchProjectionEvent({ runtimeStore = null, event
createdAt: occurredAt,
updatedAt: projectedAt,
source: "workbench-event-projection"
}, 0, { traceId, sessionId, turnId, terminal, terminalStatus: status, finalText: messageFinalText, timestamp: projectedAt, timing }) : null;
}, userMessageFact ? 1 : 0, { traceId, sessionId, turnId, terminal, terminalStatus: status, finalText: messageFinalText, timestamp: projectedAt, timing }) : null;
const facts = {
sessions: sessionId && !suppressedAfterSeal ? [{
sessionId,
@@ -204,7 +205,7 @@ export async function writeWorkbenchProjectionEvent({ runtimeStore = null, event
occurredAt,
updatedAt: projectedAt
}],
messages: messageFact ? [messageFact] : [],
messages: [userMessageFact, messageFact].filter(Boolean),
checkpoints: !suppressedAfterSeal ? [{
traceId,
sessionId,
@@ -363,6 +364,7 @@ function buildWorkbenchProjectionFacts({ traceId = null, ownerUserId = null, own
diagnostic,
finalResponse: checkpointFinalResponse,
assistantText: messageFinalText,
userMessage: previousCheckpoint?.userMessage ?? null,
timing,
startedAt: timing.startedAt,
lastEventAt: timing.lastEventAt,
@@ -386,6 +388,7 @@ function buildWorkbenchProjectionFacts({ traceId = null, ownerUserId = null, own
diagnostic,
finalResponse: projectedFinalResponse,
assistantText: finalText,
userMessage: messages.find((message) => message.role === "user") ?? null,
timing,
startedAt: timing.startedAt,
lastEventAt: timing.lastEventAt,
@@ -401,24 +404,11 @@ function workbenchProjectionInputMessages({ session = {}, payload = {}, params =
if (Array.isArray(payload?.messages) && payload.messages.length > 0) return payload.messages;
if (!traceId) return [];
const turnId = textValue(payload?.turnId) || traceId;
const userText = textValue(params?.message ?? params?.prompt ?? payload?.prompt ?? payload?.message);
const userMessageId = textValue(payload?.userMessageId ?? payload?.userMessage?.messageId) || stableFactId("msg", { traceId, role: "user" });
const assistantMessageId = textValue(payload?.assistantMessageId ?? payload?.messageId ?? payload?.assistantMessage?.messageId) || stableFactId("msg", { traceId, role: "agent" });
const createdAt = timestampValue(timestamp ?? payload?.createdAt ?? payload?.updatedAt);
const messages = [];
if (userText) {
messages.push({
messageId: userMessageId,
role: "user",
status: "sent",
text: userText,
traceId,
turnId,
createdAt,
updatedAt: createdAt,
valuesPrinted: false
});
}
const userMessage = workbenchProjectionUserMessage({ payload, params, traceId, turnId, timestamp: createdAt });
if (userMessage) messages.push(userMessage);
messages.push({
messageId: assistantMessageId,
role: "agent",
@@ -438,6 +428,23 @@ function workbenchProjectionInputMessages({ session = {}, payload = {}, params =
return messages;
}
function workbenchProjectionUserMessage({ payload = {}, params = {}, traceId = null, turnId = null, timestamp = null } = {}) {
const userText = textValue(params?.message ?? params?.prompt ?? payload?.prompt ?? payload?.message);
if (!traceId || !userText) return null;
const createdAt = timestampValue(timestamp ?? payload?.createdAt ?? payload?.updatedAt);
return {
messageId: textValue(payload?.userMessageId ?? payload?.userMessage?.messageId) || stableFactId("msg", { traceId, role: "user" }),
role: "user",
status: "sent",
text: userText,
traceId,
turnId: textValue(turnId) || traceId,
createdAt,
updatedAt: createdAt,
valuesPrinted: false
};
}
function normalizeMessages(messages, context) {
const normalized = Array.isArray(messages) ? messages.map((message, index) => normalizeMessageFact(message, index, context)).filter(Boolean) : [];
if (context?.terminal && context?.finalText && context?.traceId && !normalized.some((message) => message.role !== "user" && message.traceId === context.traceId)) {