Restore pending user message during active replay

This commit is contained in:
wuyang6
2026-05-12 10:58:25 +08:00
parent 26fe0f6a9d
commit 1bd80db2db
2 changed files with 59 additions and 5 deletions
@@ -69,6 +69,7 @@ export type ClawRunStatus = {
| "interrupted";
current_stage?: string;
started_at?: number;
pending_prompt?: string;
events?: ClawRunEvent[];
};
@@ -502,6 +503,32 @@ export function toReplayRepository(
previousId = id;
}
if (isActiveRunStatus(runStatus)) {
const pendingPrompt = resolvePendingPrompt(replayMessages, runStatus);
if (pendingPrompt) {
const id = `${fallbackSessionId}-pending-${runStatus.run_id ?? "active"}`;
const parts = [
{ type: "text", text: pendingPrompt },
] as UIMessage["parts"];
const uiMessage: UIMessage = {
id,
role: "user",
parts,
metadata: { sessionId: session.session_id ?? fallbackSessionId },
} as UIMessage;
const threadMessage = {
id,
role: "user",
createdAt: new Date(),
content: toThreadMessageContent(parts),
attachments: [],
metadata: {
custom: { sessionId: session.session_id ?? fallbackSessionId },
},
} as ThreadMessage;
bindExternalStoreMessage(threadMessage, uiMessage);
messages.push({ message: threadMessage, parentId: previousId });
previousId = id;
}
const id = `${fallbackSessionId}-run-${runStatus.run_id ?? "active"}`;
const runStartedAtMs = resolveRunStartedAtMs(runStatus);
const parts = buildActiveRunParts(runStatus) as UIMessage["parts"];
@@ -717,6 +744,29 @@ function isRunStatusMessage(message?: ClawStoredMessage) {
return message?.metadata?.kind === "run_status";
}
function resolvePendingPrompt(
messages: readonly ClawStoredMessage[],
runStatus: ClawRunStatus,
) {
const pendingPrompt =
typeof runStatus.pending_prompt === "string"
? runStatus.pending_prompt.trim()
: "";
if (!pendingPrompt) return null;
for (let index = messages.length - 1; index >= 0; index -= 1) {
const message = messages[index];
if (!message || message.role === "system" || message.role === "tool")
continue;
const content = cleanStoredContent(message.content ?? "").trim();
if (!content || content.trimStart().startsWith("<system-reminder>"))
continue;
return message.role === "user" && content === pendingPrompt
? null
: pendingPrompt;
}
return pendingPrompt;
}
function normalizeRunTimestampMs(value: unknown) {
if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
return value < 10_000_000_000 ? Math.round(value * 1000) : Math.round(value);