diff --git a/internal/cloud/access-control.ts b/internal/cloud/access-control.ts index 6fbc999f..16ceaba4 100644 --- a/internal/cloud/access-control.ts +++ b/internal/cloud/access-control.ts @@ -2757,7 +2757,8 @@ function resolvedConversationLastTraceId(storedTraceId, status, messages = [], s const snapshotTraceId = textOr(snapshot.lastTraceId, ""); const stored = textOr(storedTraceId, ""); const snapshotStatus = textOr(snapshot.sessionStatus ?? snapshot.status, "").toLowerCase(); - if (latestTraceId && (isActiveConversationStatus(latestStatus) || isActiveConversationStatus(status))) return latestTraceId; + const latestTurnTraceId = latestConversationTurnTraceId(messages); + if (latestTurnTraceId && (latestTurnTraceId !== stored || isActiveConversationStatus(status))) return latestTurnTraceId; if (stored && snapshotStatus && !isActiveConversationStatus(snapshotStatus)) return stored; if (!isActiveConversationStatus(status)) { return latestTraceId || snapshotTraceId || stored; @@ -2773,6 +2774,23 @@ function isTerminalConversationStatus(value) { return ["completed", "failed", "blocked", "timeout", "canceled", "cancelled", "stale", "thread-resume-failed", "interrupted", "expired"].includes(textOr(value, "").toLowerCase().replace(/_/gu, "-")); } +function latestConversationTurnTraceId(messages = []) { + if (!Array.isArray(messages)) return ""; + for (let index = messages.length - 1; index >= 0; index -= 1) { + const message = messages[index]; + if (String(message?.role ?? "").toLowerCase() !== "agent") continue; + const traceId = textOr(message?.traceId, ""); + if (!traceId) return ""; + for (let prev = index - 1; prev >= 0; prev -= 1) { + const previous = messages[prev]; + if (String(previous?.role ?? "").toLowerCase() !== "user") continue; + return textOr(previous?.traceId, "") === traceId ? traceId : ""; + } + return ""; + } + return ""; +} + function latestAgentConversationMessage(messages = []) { if (!Array.isArray(messages)) return null; for (const message of [...messages].reverse()) {