Files
kandev/apps/web/lib/threads/thread-session-selection.ts
Jérémy Coatelen 538813de02 feat(web): add Threads view for live agent conversations (#3112)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
2026-09-03 08:07:16 +00:00

55 lines
2.0 KiB
TypeScript

import type { TaskSession } from "@/lib/types/http";
import { sortSessions } from "@/components/task/session-sort";
export type ThreadSessionSelectionOptions = {
/** Session requested by the Threads URL, if the task owns it. */
requestedSessionId?: string | null;
/** Session already selected by this task column. */
currentSessionId?: string | null;
};
function firstPendingSession(
sessions: readonly TaskSession[],
pendingAction: TaskSession["pending_action"],
): TaskSession | undefined {
return sessions.find((session) => session.pending_action === pendingAction);
}
/**
* Selects the conversation that a task column should show.
*
* The current selection is checked before attention and activity so a status
* update in a sibling session never steals the reader's conversation. The
* caller can pass a URL selection only during the column's initial resolve.
*/
export function selectThreadSessionId(
sessions: readonly TaskSession[],
options: ThreadSessionSelectionOptions = {},
): string | null {
if (sessions.length === 0) return null;
const sessionIds = new Set(sessions.map((session) => String(session.id)));
if (options.requestedSessionId && sessionIds.has(options.requestedSessionId)) {
return options.requestedSessionId;
}
if (options.currentSessionId && sessionIds.has(options.currentSessionId)) {
return options.currentSessionId;
}
const sorted = sortSessions(sessions);
const permission = firstPendingSession(sorted, "permission");
if (permission) return permission.id;
const clarification = firstPendingSession(sorted, "clarification");
if (clarification) return clarification.id;
const active = sorted.find(
(session) => session.state === "STARTING" || session.state === "RUNNING",
);
if (active) return active.id;
const primary = sorted.find((session) => session.is_primary);
return primary?.id ?? sorted[0]?.id ?? null;
}
/** Alias that reads naturally at call sites resolving a replacement choice. */
export const resolveThreadSessionId = selectThreadSessionId;