37cea5a8c2
Co-authored-by: nova28 <17953305+nova28@users.noreply.github.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
109 lines
3.9 KiB
TypeScript
109 lines
3.9 KiB
TypeScript
import type {
|
|
ForegroundActivity,
|
|
TaskPendingAction,
|
|
TaskSession,
|
|
TaskState,
|
|
WorkflowReviewStatus,
|
|
} from "@/lib/types/http";
|
|
|
|
export type ThreadSessionStatusKind =
|
|
| "permission"
|
|
| "clarification"
|
|
| "starting"
|
|
| "working"
|
|
| "failed"
|
|
| "cancelled"
|
|
| "finished"
|
|
| "waiting"
|
|
| "completed"
|
|
| "created";
|
|
|
|
export type ThreadColumnStatusKind = ThreadSessionStatusKind | "needs-you" | "review-ready";
|
|
|
|
export type ThreadStatus = {
|
|
kind: ThreadColumnStatusKind;
|
|
labelKey: string;
|
|
hasAttention: boolean;
|
|
};
|
|
|
|
type ThreadSessionStatusInput = Pick<TaskSession, "state"> & {
|
|
pending_action?: TaskPendingAction | null;
|
|
foreground_activity?: ForegroundActivity | null;
|
|
};
|
|
|
|
const STATUS = {
|
|
permission: {
|
|
kind: "permission",
|
|
labelKey: "threads:statusPermissionNeeded",
|
|
hasAttention: true,
|
|
},
|
|
clarification: {
|
|
kind: "clarification",
|
|
labelKey: "threads:statusQuestionFromAgent",
|
|
hasAttention: true,
|
|
},
|
|
starting: { kind: "starting", labelKey: "threads:statusStarting", hasAttention: false },
|
|
working: { kind: "working", labelKey: "threads:statusWorking", hasAttention: false },
|
|
failed: { kind: "failed", labelKey: "threads:statusFailed", hasAttention: false },
|
|
cancelled: { kind: "cancelled", labelKey: "threads:statusCancelled", hasAttention: false },
|
|
finished: { kind: "finished", labelKey: "threads:statusTurnFinished", hasAttention: false },
|
|
waiting: { kind: "waiting", labelKey: "threads:statusWaiting", hasAttention: false },
|
|
completed: { kind: "completed", labelKey: "threads:statusCompleted", hasAttention: false },
|
|
created: { kind: "created", labelKey: "threads:statusNotStarted", hasAttention: false },
|
|
} satisfies Record<ThreadSessionStatusKind, ThreadStatus>;
|
|
|
|
// The Inbox Failed tab has no session to resolve status from -- every row is
|
|
// defined by the task's own terminal failed state (AC-UI-INBOX-FAILED-001.6,
|
|
// .20). Exporting the existing `failed` entry lets that tab reach it
|
|
// directly instead of fabricating a stand-in session for
|
|
// resolveThreadSessionStatus, which would reintroduce the
|
|
// pending_action-first precedence AC-UI-INBOX-FAILED-001.20a excludes. This
|
|
// is a wider export of an existing entry, not a new or duplicated one.
|
|
export const FAILED_TASK_STATUS: ThreadStatus = STATUS.failed;
|
|
|
|
const REVIEW_READY: ThreadStatus = {
|
|
kind: "review-ready",
|
|
labelKey: "threads:statusReadyForReview",
|
|
hasAttention: false,
|
|
};
|
|
|
|
const NEEDS_YOU: ThreadStatus = {
|
|
kind: "needs-you",
|
|
labelKey: "threads:statusNeedsYou",
|
|
hasAttention: true,
|
|
};
|
|
|
|
export function resolveThreadSessionStatus(session: ThreadSessionStatusInput): ThreadStatus {
|
|
if (session.pending_action === "permission") return STATUS.permission;
|
|
if (session.pending_action === "clarification") return STATUS.clarification;
|
|
if (session.state === "STARTING") return STATUS.starting;
|
|
if (session.state === "RUNNING" || session.foreground_activity) return STATUS.working;
|
|
if (session.state === "FAILED") return STATUS.failed;
|
|
if (session.state === "CANCELLED") return STATUS.cancelled;
|
|
if (session.state === "IDLE") return STATUS.finished;
|
|
if (session.state === "WAITING_FOR_INPUT") return STATUS.waiting;
|
|
if (session.state === "COMPLETED") return STATUS.completed;
|
|
return STATUS.created;
|
|
}
|
|
|
|
export function resolveThreadColumnStatus({
|
|
taskState,
|
|
reviewStatus,
|
|
taskPendingAction,
|
|
session,
|
|
}: {
|
|
taskState?: TaskState | null;
|
|
reviewStatus?: WorkflowReviewStatus | null;
|
|
taskPendingAction?: TaskPendingAction | null;
|
|
session?: ThreadSessionStatusInput | null;
|
|
}): ThreadStatus {
|
|
const sessionStatus = session ? resolveThreadSessionStatus(session) : null;
|
|
if (sessionStatus?.hasAttention) return sessionStatus;
|
|
if (taskPendingAction) return NEEDS_YOU;
|
|
if (sessionStatus?.kind === "starting" || sessionStatus?.kind === "working") {
|
|
return sessionStatus;
|
|
}
|
|
if (taskState === "REVIEW" || reviewStatus === "pending") return REVIEW_READY;
|
|
return sessionStatus ?? STATUS.created;
|
|
}
|