Preserve running session replay state

This commit is contained in:
武阳
2026-05-07 16:49:42 +08:00
parent 2ba67ead00
commit 61a0a0a648
5 changed files with 213 additions and 31 deletions
@@ -50,6 +50,7 @@ export type ClawRunStatus = {
session_id?: string;
status?: "idle" | "queued" | "running" | "completed" | "failed" | "cancelled";
current_stage?: string;
started_at?: number;
};
type ClawStoredToolCall = {
@@ -431,7 +432,11 @@ export function toReplayRepository(
id,
role: "assistant",
parts,
metadata: { sessionId: session.session_id ?? fallbackSessionId },
metadata: {
sessionId: session.session_id ?? fallbackSessionId,
runId: runStatus.run_id,
runStartedAtMs: normalizeRunTimestampMs(runStatus.started_at),
},
} as UIMessage;
const threadMessage = {
id,
@@ -444,7 +449,11 @@ export function toReplayRepository(
unstable_annotations: [],
unstable_data: [],
steps: [],
custom: { sessionId: session.session_id ?? fallbackSessionId },
custom: {
sessionId: session.session_id ?? fallbackSessionId,
runId: runStatus.run_id,
runStartedAtMs: normalizeRunTimestampMs(runStatus.started_at),
},
},
} as ThreadMessage;
bindExternalStoreMessage(threadMessage, uiMessage);
@@ -463,6 +472,11 @@ function isActiveRunStatus(
return runStatus?.status === "queued" || runStatus?.status === "running";
}
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);
}
function findLastAssistantContentIndex(messages: readonly ClawStoredMessage[]) {
for (let index = messages.length - 1; index >= 0; index -= 1) {
const message = messages[index];