Freeze the shared contracts every Media Studio slice builds on: zod DTOs, EDL, platform profile, brand kit, gate and render plan schemas; the media RPC surface with a scaffold router; provider interfaces for sources, inference, rendering, motion graphics and publishing; media background jobs; the Prisma models and migration; and the @rakazo/media domain package signatures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0138YqDj3ttfayRwuMKKrqVj
212 lines
6.4 KiB
TypeScript
212 lines
6.4 KiB
TypeScript
import type { MediaAnalysisKind } from "@rakazo/contracts";
|
|
import { MediaAnalysisKindSchema } from "@rakazo/contracts";
|
|
import { z } from "zod";
|
|
import type {
|
|
BackgroundJob,
|
|
BackgroundJobHandlers,
|
|
BackgroundJobName,
|
|
BackgroundJobPayloads,
|
|
} from "./types.js";
|
|
|
|
const payloadSchemas = {
|
|
"run.continue": z.object({ runId: z.string().min(1) }),
|
|
"routine.wakeup": z.object({
|
|
routineId: z.string().min(1),
|
|
scheduledFor: z.string().datetime({ offset: true }),
|
|
}),
|
|
"computer.update": z.object({ updateId: z.string().min(1) }),
|
|
"computer.sleep": z.object({ computerId: z.string().min(1) }),
|
|
"computer.control-expire": z.object({
|
|
computerId: z.string().min(1),
|
|
leaseId: z.string().min(1),
|
|
}),
|
|
"skill.teaching-expire": z.object({ skillId: z.string().min(1) }),
|
|
"history.compact": z.object({ threadId: z.string().min(1) }),
|
|
"messaging.deliver": z.object({ runId: z.string().min(1).optional() }),
|
|
"cloud_agent.poll": z.object({ agentId: z.string().min(1) }),
|
|
"profile.consolidate": z.object({ userId: z.string().min(1) }),
|
|
"media.sync": z.object({ sourceId: z.string().min(1) }),
|
|
"media.proxy": z.object({ assetId: z.string().min(1) }),
|
|
"media.analyze": z.object({
|
|
assetId: z.string().min(1),
|
|
kinds: z.array(MediaAnalysisKindSchema).optional(),
|
|
}),
|
|
"media.cluster": z.object({ spaceId: z.string().min(1) }),
|
|
"media.render": z.object({ renderId: z.string().min(1) }),
|
|
"media.publish": z.object({ publicationId: z.string().min(1) }),
|
|
} satisfies { [Name in BackgroundJobName]: z.ZodType<BackgroundJobPayloads[Name]> };
|
|
|
|
export function parseBackgroundJob(name: string, payload: unknown): BackgroundJob {
|
|
if (!(name in payloadSchemas)) throw new Error(`Unknown background job: ${name}`);
|
|
const typedName = name as BackgroundJobName;
|
|
const parsed = payloadSchemas[typedName].parse(payload);
|
|
return { name: typedName, payload: parsed } as BackgroundJob;
|
|
}
|
|
|
|
export async function dispatchBackgroundJob(
|
|
handlers: BackgroundJobHandlers,
|
|
name: string,
|
|
payload: unknown,
|
|
): Promise<void> {
|
|
const job = parseBackgroundJob(name, payload);
|
|
const handler = handlers[job.name] as (payload: typeof job.payload) => Promise<void>;
|
|
await handler(job.payload);
|
|
}
|
|
|
|
export function runJobKey(runId: string): string {
|
|
return `run:${runId}`;
|
|
}
|
|
|
|
export function routineJobKey(routineId: string): string {
|
|
return `routine:${routineId}`;
|
|
}
|
|
|
|
export function computerSleepJobKey(computerId: string): string {
|
|
return `computer.sleep:${computerId}`;
|
|
}
|
|
|
|
export function computerControlExpireJobKey(computerId: string, leaseId?: string): string {
|
|
return leaseId
|
|
? `computer.control-expire:${computerId}:${leaseId}`
|
|
: `computer.control-expire:${computerId}`;
|
|
}
|
|
|
|
export function skillTeachingExpireJobKey(skillId: string): string {
|
|
return `skill.teaching-expire:${skillId}`;
|
|
}
|
|
|
|
export function runContinueJob(runId: string): BackgroundJob {
|
|
return {
|
|
name: "run.continue",
|
|
payload: { runId },
|
|
replaceKey: runJobKey(runId),
|
|
};
|
|
}
|
|
|
|
export function routineWakeupJob(routineId: string, scheduledFor: Date): BackgroundJob {
|
|
return {
|
|
name: "routine.wakeup",
|
|
payload: { routineId, scheduledFor: scheduledFor.toISOString() },
|
|
availableAt: scheduledFor,
|
|
replaceKey: routineJobKey(routineId),
|
|
};
|
|
}
|
|
|
|
export function computerSleepJob(computerId: string, availableAt: Date): BackgroundJob {
|
|
return {
|
|
name: "computer.sleep",
|
|
payload: { computerId },
|
|
availableAt,
|
|
replaceKey: computerSleepJobKey(computerId),
|
|
};
|
|
}
|
|
|
|
export function computerControlExpireJob(
|
|
computerId: string,
|
|
leaseId: string,
|
|
availableAt: Date,
|
|
): BackgroundJob {
|
|
return {
|
|
name: "computer.control-expire",
|
|
payload: { computerId, leaseId },
|
|
availableAt,
|
|
replaceKey: computerControlExpireJobKey(computerId, leaseId),
|
|
};
|
|
}
|
|
|
|
export function skillTeachingExpireJob(skillId: string, availableAt: Date): BackgroundJob {
|
|
return {
|
|
name: "skill.teaching-expire",
|
|
payload: { skillId },
|
|
availableAt,
|
|
replaceKey: skillTeachingExpireJobKey(skillId),
|
|
};
|
|
}
|
|
|
|
export function historyCompactJobKey(threadId: string): string {
|
|
return `history.compact:${threadId}`;
|
|
}
|
|
|
|
export function messagingDeliverJob(runId?: string, availableAt?: Date): BackgroundJob {
|
|
return {
|
|
name: "messaging.deliver",
|
|
payload: runId ? { runId } : {},
|
|
replaceKey: `messaging.deliver:${runId ?? "drain"}`,
|
|
...(availableAt ? { availableAt } : {}),
|
|
};
|
|
}
|
|
|
|
export function historyCompactJob(threadId: string): BackgroundJob {
|
|
return {
|
|
name: "history.compact",
|
|
payload: { threadId },
|
|
replaceKey: historyCompactJobKey(threadId),
|
|
};
|
|
}
|
|
|
|
export function cloudAgentPollJobKey(agentId: string): string {
|
|
return `cloud_agent.poll:${agentId}`;
|
|
}
|
|
|
|
export function cloudAgentPollJob(
|
|
payload: BackgroundJobPayloads["cloud_agent.poll"],
|
|
availableAt?: Date,
|
|
): BackgroundJob {
|
|
return {
|
|
name: "cloud_agent.poll",
|
|
payload,
|
|
replaceKey: cloudAgentPollJobKey(payload.agentId),
|
|
...(availableAt ? { availableAt } : {}),
|
|
};
|
|
}
|
|
|
|
export function profileConsolidateJobKey(userId: string): string {
|
|
return `profile.consolidate:${userId}`;
|
|
}
|
|
|
|
export function profileConsolidateJob(userId: string): BackgroundJob {
|
|
return {
|
|
name: "profile.consolidate",
|
|
payload: { userId },
|
|
replaceKey: profileConsolidateJobKey(userId),
|
|
};
|
|
}
|
|
|
|
export function mediaSyncJob(sourceId: string): BackgroundJob {
|
|
return { name: "media.sync", payload: { sourceId }, replaceKey: `media.sync:${sourceId}` };
|
|
}
|
|
|
|
export function mediaProxyJob(assetId: string): BackgroundJob {
|
|
return { name: "media.proxy", payload: { assetId }, replaceKey: `media.proxy:${assetId}` };
|
|
}
|
|
|
|
export function mediaAnalyzeJob(assetId: string, kinds?: MediaAnalysisKind[]): BackgroundJob {
|
|
return {
|
|
name: "media.analyze",
|
|
payload: kinds ? { assetId, kinds } : { assetId },
|
|
replaceKey: `media.analyze:${assetId}`,
|
|
};
|
|
}
|
|
|
|
export function mediaClusterJob(spaceId: string, availableAt?: Date): BackgroundJob {
|
|
return {
|
|
name: "media.cluster",
|
|
payload: { spaceId },
|
|
replaceKey: `media.cluster:${spaceId}`,
|
|
...(availableAt ? { availableAt } : {}),
|
|
};
|
|
}
|
|
|
|
export function mediaRenderJob(renderId: string): BackgroundJob {
|
|
return { name: "media.render", payload: { renderId }, replaceKey: `media.render:${renderId}` };
|
|
}
|
|
|
|
export function mediaPublishJob(publicationId: string, availableAt?: Date): BackgroundJob {
|
|
return {
|
|
name: "media.publish",
|
|
payload: { publicationId },
|
|
replaceKey: `media.publish:${publicationId}`,
|
|
...(availableAt ? { availableAt } : {}),
|
|
};
|
|
}
|