36 lines
2.1 KiB
TypeScript
36 lines
2.1 KiB
TypeScript
import { nanoid } from "nanoid";
|
|
import { creationRuns, type CreationSubmission } from "./api/creation-runs";
|
|
import type { CreateTaskInput } from "./api/task-center";
|
|
|
|
// Both the node composer and Agent submit the same quoted professional task.
|
|
export async function submitStoryboardTask(request: CreateTaskInput, options: {
|
|
signal: AbortSignal;
|
|
assertCurrent: () => void;
|
|
confirm: (submission: CreationSubmission) => Promise<boolean>;
|
|
}, api = creationRuns) {
|
|
const { signal, assertCurrent } = options;
|
|
const detail = await api.create({ clientKey: `storyboard:${nanoid()}`, canvasId: request.projectId, state: { kind: "storyboard" } }, signal);
|
|
const run = await api.claim(detail.run.id, { expectedEpoch: detail.run.executionEpoch, owner: `storyboard:${nanoid()}` }, signal);
|
|
const guard = { executionEpoch: run.executionEpoch, owner: run.executionOwner };
|
|
let connectionError: unknown;
|
|
const heartbeat = setInterval(() => {
|
|
void api.heartbeat(run.id, guard, signal).catch((error) => { connectionError = error; });
|
|
}, 15_000);
|
|
try {
|
|
const submission = await api.prepare(run.id, { ...guard, itemKey: "storyboard", request }, signal);
|
|
if (!await options.confirm(submission)) return undefined;
|
|
signal.throwIfAborted();
|
|
if (connectionError) throw connectionError;
|
|
assertCurrent();
|
|
if (Date.parse(submission.quote.expiresAt) <= Date.now()) throw new Error("分镜报价已过期,请重新发起拆镜并确认最新费用");
|
|
const approved = await api.approve(run.id, { ...guard, submissionIds: [submission.id] }, signal);
|
|
if (!approved.submissions.some((item) => item.id === submission.id && item.approvedAt)) throw new Error("费用确认回执不完整,尚未提交拆镜任务");
|
|
signal.throwIfAborted();
|
|
assertCurrent();
|
|
return await api.execute(run.id, { ...guard, submissionId: submission.id }, signal);
|
|
} finally {
|
|
clearInterval(heartbeat);
|
|
void api.release(run.id, guard).catch(() => { /* Offline leases expire on the server. */ });
|
|
}
|
|
}
|