72 lines
3.2 KiB
TypeScript
72 lines
3.2 KiB
TypeScript
import { z } from "zod";
|
|
|
|
const boundedText = z.string().max(12_000);
|
|
const timestamp = z.number().int().nonnegative().max(8_640_000_000_000_000);
|
|
const referenceSchema = z.object({
|
|
id: z.string().max(200), title: z.string().max(256), url: z.string().max(4096),
|
|
type: z.enum(["image", "video"]), duration: z.number().optional(),
|
|
});
|
|
const nodeContextSchema = z.object({
|
|
id: z.string().max(200), title: z.string().max(256), type: z.string().max(100), description: boundedText,
|
|
});
|
|
const shotSchema = z.object({
|
|
shot: boundedText.default(""), duration: boundedText.default(""), scene: boundedText.default(""), sceneDescription: boundedText,
|
|
shotSize: boundedText.default(""), lighting: boundedText.default(""), dialogue: boundedText.default(""), backgroundMusic: boundedText.default(""),
|
|
voiceAndSfx: boundedText.default(""), cameraMovement: boundedText.default(""), imagePrompt: boundedText.default(""),
|
|
motionPrompt: boundedText.default(""), keyframeUrl: z.string().max(4096).default(""),
|
|
});
|
|
|
|
export const tvstarSessionSchema = z.object({
|
|
id: z.string().uuid(),
|
|
title: z.string().min(1).max(256),
|
|
goal: boundedText,
|
|
mode: z.enum(["full", "brainstorm", "script", "storyboard", "edit"]),
|
|
plan: z.object({
|
|
summary: boundedText, agentPlan: z.array(boundedText).max(30),
|
|
deliverables: z.array(boundedText).max(30), recommendedNodes: z.array(boundedText).max(30),
|
|
model: z.string().max(256).optional(),
|
|
}).optional(),
|
|
shots: z.array(shotSchema).max(12).optional(),
|
|
references: z.array(referenceSchema).max(6).optional(),
|
|
nodeContexts: z.array(nodeContextSchema).max(6).optional(),
|
|
messages: z.array(z.object({
|
|
id: z.string().max(200), role: z.enum(["user", "assistant"]),
|
|
content: boundedText, createdAt: timestamp,
|
|
})).max(500).optional(),
|
|
imageModelRef: z.string().max(256).optional(),
|
|
videoModelRef: z.string().max(256).optional(),
|
|
autoGenerate: z.boolean().optional(),
|
|
createdAt: timestamp,
|
|
updatedAt: timestamp,
|
|
pendingStage: z.enum(["plan", "shots", "submit"]).optional(),
|
|
runSubmitted: z.boolean().optional(),
|
|
preparedOnly: z.boolean().optional(),
|
|
groupId: z.string().max(200).optional(),
|
|
});
|
|
|
|
export type StoredTVstarSession = z.infer<typeof tvstarSessionSchema>;
|
|
|
|
export function mergeTVstarSessions<T extends { id: string; createdAt: number; updatedAt?: number }>(
|
|
local: T[], remote: T[]
|
|
): T[] {
|
|
const byId = new Map<string, T>();
|
|
for (const item of [...remote, ...local]) {
|
|
const previous = byId.get(item.id);
|
|
if (!previous || (item.updatedAt || item.createdAt) >= (previous.updatedAt || previous.createdAt)) {
|
|
byId.set(item.id, item);
|
|
}
|
|
}
|
|
return [...byId.values()].sort((a, b) => (b.updatedAt || b.createdAt) - (a.updatedAt || a.createdAt)).slice(0, 20);
|
|
}
|
|
|
|
export function publicTVstarSnapshot(session: StoredTVstarSession) {
|
|
return {
|
|
title: session.title,
|
|
goal: session.goal,
|
|
createdAt: session.createdAt,
|
|
messages: (session.messages || []).map(({ role, content, createdAt }) => ({ role, content, createdAt })),
|
|
plan: session.plan ? { summary: session.plan.summary, deliverables: session.plan.deliverables } : null,
|
|
shots: (session.shots || []).map(({ shot, duration, sceneDescription }) => ({ shot, duration, sceneDescription })),
|
|
};
|
|
}
|