538813de02
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
55 lines
2.0 KiB
TypeScript
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;
|