fix(design): connect video preparation and playable history

This commit is contained in:
2026-09-16 15:42:39 +08:00
parent 4321c77613
commit 1acca836fe
21 changed files with 900 additions and 115 deletions

View File

@@ -94,6 +94,15 @@ function decodeUserInput(value: unknown): DesignUserInput {
}
return { kind: 'direct_edit', operations: input.operations.map(decodeFieldOperation) };
}
if (input.kind === 'prepare_generation') {
if (input.operations !== undefined && !Array.isArray(input.operations)) {
invalidCommand('制作方案整理的字段操作无效');
}
return {
kind: 'prepare_generation',
operations: input.operations?.map(decodeFieldOperation) ?? [],
};
}
if (input.kind === 'chat') {
return { kind: 'chat', message: requiredString(input.message, '消息') };
}

View File

@@ -18,8 +18,10 @@ import {
type DesignDirectionUpdatedEvent,
type DesignForm,
type DesignGenerationQuote,
type DesignGenerationOptions,
type DesignGenerationTask,
type DesignInteractionOutcome,
type DesignMedium,
type DesignQuoteBlockedEvent,
type DesignQuoteOutputSummary,
type DesignRenameWorkspaceInput,
@@ -134,6 +136,49 @@ function arrayValue(value: unknown, field: string): unknown[] {
return value;
}
function booleanValue(value: unknown, field: string): boolean {
if (typeof value !== 'boolean') {
throw new DesignWorkspaceModuleError(502, 'DESIGN_WORKSPACE_RESPONSE_INVALID', `${field} 无效`);
}
return value;
}
function mapGenerationOptions(value: unknown, medium: DesignMedium): DesignGenerationOptions {
const options = record(value);
return {
available: booleanValue(options.available, `${medium} generation availability`),
supportedAspectRatios: arrayValue(
options.supported_aspect_ratios,
`${medium} aspect ratios`,
).map((ratio) => stringValue(ratio, `${medium} aspect ratio`)),
supportedDurationSeconds: arrayValue(
options.supported_duration_seconds,
`${medium} durations`,
).map((duration) => numberValue(duration, `${medium} duration`)),
maxOutputCount: numberValue(options.max_output_count, `${medium} output count`),
requiresFirstFrame: booleanValue(options.requires_first_frame, `${medium} first frame flag`),
supportedReferenceRoles: arrayValue(
options.supported_reference_roles,
`${medium} reference roles`,
).map((role) => stringValue(role, `${medium} reference role`)),
};
}
function mapCapabilities(value: unknown): DesignCapabilities {
const capabilities = record(value);
const generationOptions = record(capabilities.generation_options);
return {
conversation: booleanValue(capabilities.conversation, 'Conversation capability'),
generation: booleanValue(capabilities.generation, 'Generation capability'),
image: booleanValue(capabilities.image, 'Image capability'),
video: booleanValue(capabilities.video, 'Video capability'),
generationOptions: {
image: mapGenerationOptions(generationOptions.image, 'image'),
video: mapGenerationOptions(generationOptions.video, 'video'),
},
};
}
function nullableString(value: unknown): string | null {
return value === null || value === undefined ? null : stringValue(value, '可选文本');
}
@@ -546,6 +591,12 @@ function normalizeWorkspaceEvent(
function mapUserInput(input: DesignUserInput): Record<string, unknown> {
if (input.kind === 'direct_edit') return input;
if (input.kind === 'prepare_generation') {
return {
kind: input.kind,
operations: input.operations ?? [],
};
}
if (input.kind === 'chat') return input;
if (input.kind === 'restore') {
return { kind: input.kind, specification_revision_id: input.specificationRevisionId };
@@ -677,7 +728,7 @@ function userFacingErrorMessage(code: string): string {
const messages: Record<string, string> = {
design_direction_revision_conflict: '设计表单已更新,正在重新同步',
design_idempotency_conflict: '这次操作与已经受理的请求冲突',
design_quote_blocked: '当前设计信息还不足以生成,请先补全表单',
design_quote_blocked: '制作方案还没整理好,请检查提示后重试',
design_quote_expired: '当前报价已过期,请重新获取报价',
design_quote_consumed: '当前报价已经生成过',
budget_denied: '当前设计点不足,无法开始生成',
@@ -789,11 +840,14 @@ export class WorksSquareDesignWorkspace implements DesignWorkspaceModule {
async bootstrap(): Promise<DesignWorkspaceBootstrap> {
const [capabilities, workspaces] = await Promise.all([
this.requestJson<DesignCapabilities>('/api/design/capabilities'),
this.requestJson<unknown>('/api/design/capabilities'),
this.requestJson<unknown[]>('/api/design/workspaces?limit=100&offset=0'),
]);
this.eventSessionsEnabled = true;
return { capabilities, workspaces: workspaces.map(mapWorkspaceSummary) };
return {
capabilities: mapCapabilities(capabilities),
workspaces: workspaces.map(mapWorkspaceSummary),
};
}
async createWorkspace(input: DesignCreateWorkspaceInput): Promise<DesignWorkspace> {