ai-chatbot/lib/video-canvas/video-task-lifecycle.ts

61 lines
2.1 KiB
TypeScript

import { z } from "zod";
export const videoCheckpointSchema = z.object({
operation: z.literal("video"),
provider: z.enum(["aliyun", "vip98k", "volcano", "atlascloud", "agnes"]),
taskId: z.string().trim().min(1).max(500),
modelRef: z.string().min(1),
modelId: z.string().min(1),
providerId: z.string().min(1),
baseUrl: z.string(),
resultPath: z.string().optional(),
videoId: z.string().optional(),
});
export type VideoTaskCheckpoint = z.infer<typeof videoCheckpointSchema>;
export type ProviderTaskReference = Pick<VideoTaskCheckpoint, "taskId" | "resultPath" | "videoId">;
export type ProviderTaskLifecycle = {
resume?: ProviderTaskReference;
accepted: (reference: ProviderTaskReference) => Promise<void>;
assertActive: () => Promise<void>;
};
export type VideoTaskLifecycle = {
resume?: VideoTaskCheckpoint | null;
save: (checkpoint: VideoTaskCheckpoint) => Promise<void>;
assertActive: () => Promise<void>;
};
export class ProviderTaskFailedError extends Error {}
export class ProviderTaskUncertainError extends Error {}
export function bindVideoTaskLifecycle(
lifecycle: VideoTaskLifecycle | undefined,
selected: any,
provider: VideoTaskCheckpoint["provider"],
): ProviderTaskLifecycle | undefined {
if (!lifecycle) return undefined;
const identity = {
operation: "video" as const,
provider,
modelRef: String(selected.model.id),
modelId: String(selected.model.modelId),
providerId: String(selected.provider.id),
baseUrl: String(selected.provider.baseUrl || "").replace(/\/+$/, ""),
};
const resume = lifecycle.resume;
if (
resume &&
Object.entries(identity).some(
([key, value]) => resume[key as keyof VideoTaskCheckpoint] !== value,
)
)
throw new ProviderTaskUncertainError(
"原视频任务的模型或服务线路已变更,已停止自动查询,请恢复原配置后重试",
);
return {
resume: resume || undefined,
assertActive: lifecycle.assertActive,
accepted: async (reference) => {
await lifecycle.assertActive();
await lifecycle.save({ ...identity, ...reference });
},
};
}