Spaces:
Running
Running
| import type { | |
| ClusterTaskKind, | |
| CompleteTaskBody, | |
| DescribeTaskResult, | |
| TaskErrorResult, | |
| } from '../shared/completeTask.js'; | |
| import type {DetectionResultJson, DetectionTask} from './types.js'; | |
| export type TaskCompleteOutcome = | |
| | {status: 'done'; kind: 'detect'; results: DetectionResultJson[]} | |
| | {status: 'done'; kind: 'describe'; description: string} | |
| | {status: 'error'; error: string}; | |
| function parseErrorResult(result: unknown): string { | |
| if (result === null || typeof result !== 'object') { | |
| throw new Error("Error tasks must include result: { error: string }"); | |
| } | |
| const error = (result as TaskErrorResult).error; | |
| if (typeof error !== 'string' || !error.trim()) { | |
| throw new Error("Error tasks must include a non-empty result.error"); | |
| } | |
| return error.trim(); | |
| } | |
| function parseDescribeResult(result: unknown): string { | |
| if (result === null || typeof result !== 'object') { | |
| throw new Error("Describe tasks must include result: { description: string }"); | |
| } | |
| const description = (result as DescribeTaskResult).description; | |
| if (typeof description !== 'string' || !description.trim()) { | |
| throw new Error("Describe tasks must include a non-empty result.description"); | |
| } | |
| return description.trim(); | |
| } | |
| function parseDetectResult(result: unknown): DetectionResultJson[] { | |
| if (!Array.isArray(result)) { | |
| throw new Error("Detect tasks must include result as a detection array"); | |
| } | |
| return result as DetectionResultJson[]; | |
| } | |
| export function parseCompleteTaskBody( | |
| task: DetectionTask, | |
| body: CompleteTaskBody, | |
| hostModel?: string, | |
| ): TaskCompleteOutcome { | |
| if (!body.kind) { | |
| throw new Error("Complete payload must include 'kind'"); | |
| } | |
| if (body.kind !== task.kind) { | |
| throw new Error( | |
| `Task ${task.id} is '${task.kind}' but complete payload kind is '${body.kind}'`, | |
| ); | |
| } | |
| if (body.status === 'error') { | |
| return {status: 'error', error: parseErrorResult(body.result)}; | |
| } | |
| const model = body.model?.trim() || hostModel; | |
| if (!model) { | |
| throw new Error("Complete payload must include a 'model' field"); | |
| } | |
| return parseDoneResult(body.kind, body.result); | |
| } | |
| function parseDoneResult( | |
| kind: ClusterTaskKind, | |
| result: unknown, | |
| ): Extract<TaskCompleteOutcome, {status: 'done'}> { | |
| if (kind === 'describe') { | |
| return {status: 'done', kind: 'describe', description: parseDescribeResult(result)}; | |
| } | |
| if (kind === 'detect') { | |
| return {status: 'done', kind: 'detect', results: parseDetectResult(result)}; | |
| } | |
| throw new Error(`Unsupported task kind '${kind as string}'`); | |
| } | |