Files
Genarrative/src/components/platform-entry/platformExternalGenerationQueueStatusModel.ts
T
kdletters 071faa482c 统一 Rust 与 TypeScript 格式化门禁
纳入 AGC Cargo workspace 的统一 rustfmt 检查与格式化入口

完成项目 TypeScript/Prettier 与 Rust 全量格式化

修复 Pingora expected executable 门禁的空白敏感误报

同步开发运维文档与 AGC skill pack 格式化忽略规则
2026-09-01 16:28:34 +08:00

226 lines
6.1 KiB
TypeScript

import type {
ExternalGenerationJobStatusRecord,
ExternalGenerationQueueOverview,
ExternalGenerationTaskRecord,
} from '../../../packages/shared/src/contracts/externalGeneration';
export type ExternalGenerationQueueStatus = {
currentStatus?: 'queued' | 'running' | 'completed' | 'failed' | null;
currentProgress?: number | null;
pendingCount?: number | null;
runningCount?: number | null;
tasks?: ExternalGenerationTaskRecord[] | null;
unacknowledgedTerminalCount?: number | null;
};
export type ExternalGenerationQueueTaskPresentation = {
id: string;
title: string;
statusLabel: string;
priceLabel: string;
detail: string;
tone: 'profile' | 'danger' | 'success';
};
export type ExternalGenerationQueuePresentation = {
statusLabel: string | null;
progressLabel: string | null;
pendingLabel: string;
runningLabel: string;
pendingCount: number;
runningCount: number;
unacknowledgedTerminalCount: number;
progress: number | null;
tasks: ExternalGenerationQueueTaskPresentation[];
shouldShow: boolean;
};
export function buildExternalGenerationQueueStatus(
overview: ExternalGenerationQueueOverview | null,
job: ExternalGenerationJobStatusRecord | null,
tasks: ExternalGenerationTaskRecord[] | null = null,
): ExternalGenerationQueueStatus | null {
if (!overview && !job && !tasks?.length) {
return null;
}
return {
currentStatus: job?.status ?? null,
currentProgress: job?.progress ?? null,
pendingCount: overview?.pendingCount ?? null,
runningCount: overview?.runningCount ?? null,
unacknowledgedTerminalCount: overview?.unacknowledgedTerminalCount ?? null,
tasks,
};
}
function isActiveExternalGenerationStatus(
status: ExternalGenerationQueueStatus['currentStatus'],
) {
return status === 'queued' || status === 'running';
}
function isUnacknowledgedExternalGenerationTerminalTask(
task: ExternalGenerationTaskRecord,
) {
return (
(task.status === 'completed' || task.status === 'failed') &&
!task.notificationAcknowledgedAt
);
}
export function shouldUseFastExternalGenerationTaskPolling(
status: ExternalGenerationQueueStatus | null | undefined,
) {
const pendingCount = normalizeExternalGenerationQueueCount(
status?.pendingCount,
);
const runningCount = normalizeExternalGenerationQueueCount(
status?.runningCount,
);
const unacknowledgedTerminalCount = normalizeExternalGenerationQueueCount(
status?.unacknowledgedTerminalCount,
);
return Boolean(
isActiveExternalGenerationStatus(status?.currentStatus ?? null) ||
pendingCount > 0 ||
runningCount > 0 ||
unacknowledgedTerminalCount > 0 ||
(status?.tasks ?? []).some(
(task) =>
task.status === 'queued' ||
task.status === 'running' ||
isUnacknowledgedExternalGenerationTerminalTask(task),
),
);
}
export function resolveExternalGenerationQueueStatusLabel(
status: ExternalGenerationQueueStatus['currentStatus'],
) {
if (status === 'queued') {
return '排队中';
}
if (status === 'running') {
return '生成中';
}
if (status === 'failed') {
return '生成失败';
}
if (status === 'completed') {
return '已完成';
}
return null;
}
function resolveExternalGenerationQueueOverviewLabel(
pendingCount: number,
runningCount: number,
) {
if (runningCount > 0) {
return '生成中';
}
if (pendingCount > 0) {
return '排队中';
}
return null;
}
export function normalizeExternalGenerationQueueCount(
value: number | null | undefined,
) {
if (typeof value !== 'number' || !Number.isFinite(value)) {
return 0;
}
return Math.max(0, Math.round(value));
}
export function normalizeExternalGenerationQueueProgress(
value: number | null | undefined,
) {
if (typeof value !== 'number' || !Number.isFinite(value)) {
return null;
}
return Math.max(0, Math.min(100, Math.round(value)));
}
export function buildExternalGenerationTaskPresentation(
task: ExternalGenerationTaskRecord,
): ExternalGenerationQueueTaskPresentation {
const statusLabel =
resolveExternalGenerationQueueStatusLabel(task.status) ?? '待处理';
return {
id: task.jobId,
title: task.requestLabel.trim() || task.jobKind,
statusLabel,
priceLabel:
task.priceMudPoints > 0 ? `${task.priceMudPoints}泥点` : '未计费',
detail: task.error?.trim() || task.phaseDetail || task.updatedAt,
tone:
task.status === 'failed'
? 'danger'
: task.status === 'completed'
? 'success'
: 'profile',
};
}
export function buildExternalGenerationQueuePresentation(
status: ExternalGenerationQueueStatus | null | undefined,
): ExternalGenerationQueuePresentation {
const pendingCount = normalizeExternalGenerationQueueCount(
status?.pendingCount,
);
const runningCount = normalizeExternalGenerationQueueCount(
status?.runningCount,
);
const unacknowledgedTerminalCount = normalizeExternalGenerationQueueCount(
status?.unacknowledgedTerminalCount,
);
const progress = normalizeExternalGenerationQueueProgress(
status?.currentProgress,
);
const isCompletedCurrentJob = status?.currentStatus === 'completed';
const currentStatusLabel = resolveExternalGenerationQueueStatusLabel(
status?.currentStatus ?? null,
);
const overviewStatusLabel = resolveExternalGenerationQueueOverviewLabel(
pendingCount,
runningCount,
);
const statusLabel = isCompletedCurrentJob
? overviewStatusLabel
: (currentStatusLabel ?? overviewStatusLabel);
const progressValue = isCompletedCurrentJob ? null : progress;
return {
statusLabel,
progressLabel: progressValue == null ? null : `${progressValue}%`,
pendingLabel: pendingCount.toString(),
runningLabel: runningCount.toString(),
pendingCount,
runningCount,
unacknowledgedTerminalCount,
progress: progressValue,
tasks: (status?.tasks ?? [])
.slice(0, 5)
.map(buildExternalGenerationTaskPresentation),
shouldShow: Boolean(
statusLabel ||
pendingCount > 0 ||
runningCount > 0 ||
unacknowledgedTerminalCount > 0 ||
(status?.tasks?.length ?? 0) > 0,
),
};
}