feat: 统一 AI 设计 Workspace 与生成任务链路

需求:以设计项目组织固定设计 Agent 对话、方向确认和图片视频任务。

实现:新增 Works Square 云端适配与开发态本地适配,统一 Host API、Quote 确认、任务轮询及私有媒体 Range 代理。
This commit is contained in:
2026-07-31 13:56:55 +08:00
parent 80e8386fa6
commit 3d9dd14918
22 changed files with 2506 additions and 1707 deletions

View File

@@ -1,96 +1,120 @@
export const IMAGE_WORKSPACE_UNAVAILABLE_CODE = 'IMAGE_WORKSPACE_UNAVAILABLE';
export const IMAGE_WORKSPACE_UNAVAILABLE_MESSAGE = '创作空间暂不可用';
export const IMAGE_WORKSPACE_UNAVAILABLE_MESSAGE = 'AI 设计暂不可用';
export const IMAGE_WORKSPACE_API_PATH = '/api/works/image-workspace';
export type ImageWorkspaceOption = {
id: string;
label: string;
description?: string;
export type DesignMedium = 'image' | 'video';
export type DesignWorkspacePhase = 'shaping' | 'awaiting_confirmation' | 'blocked';
export type DesignTaskStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';
export type DesignQuoteStatus = 'active' | 'consumed' | 'expired' | 'superseded';
export type DesignCapabilities = {
conversation: boolean;
generation: boolean;
image: boolean;
video: boolean;
};
export type ImageWorkspaceCapabilities = {
modes: ImageWorkspaceOption[];
models: ImageWorkspaceOption[];
aspectRatios: ImageWorkspaceOption[];
resolutions: ImageWorkspaceOption[];
outputCounts: ImageWorkspaceOption[];
defaultModeId?: string;
defaultModelId?: string;
defaultAspectRatioId?: string;
defaultResolutionId?: string;
defaultOutputCountId?: string;
maxReferenceImages: number;
referenceUpload: {
enabled: boolean;
acceptedMimeTypes: string[];
maxBytes?: number;
};
export type DesignBrief = {
version: number;
status: 'draft' | 'ready' | 'confirmed';
medium: DesignMedium | null;
summary: string;
ready: boolean;
missingDecision: string | null;
};
export type ImageWorkspaceAgent = {
id: string;
name: string;
avatarUrl?: string | null;
export type DesignGenerationQuote = {
quoteId: string;
status: DesignQuoteStatus;
medium: DesignMedium;
briefVersion: number;
briefSummary: string;
quotedDesignPoints: number;
expiresAt: string;
};
export type ImageWorkspaceImage = {
export type DesignMessage = {
id: string;
url: string;
thumbnailUrl?: string | null;
alt?: string | null;
};
export type ImageWorkspaceMessageStatus = 'queued' | 'running' | 'succeeded' | 'failed';
export type ImageWorkspaceMessage = {
id: string;
role: 'user' | 'assistant' | 'system';
agentId?: string | null;
text?: string | null;
images: ImageWorkspaceImage[];
status?: ImageWorkspaceMessageStatus;
error?: string | null;
role: 'user' | 'assistant';
kind: 'user' | 'reply' | 'choice' | 'confirmation' | 'safety_redirect' | 'failure';
text: string;
quickReplies: string[];
generationQuote: DesignGenerationQuote | null;
turnRevision: number;
createdAt: string;
};
export type ImageWorkspaceProject = {
id: string;
name: string;
agents: ImageWorkspaceAgent[];
activeAgentId?: string | null;
messages: ImageWorkspaceMessage[];
updatedAt?: string | null;
export type DesignWorkspaceSummary = {
workspaceId: string;
title: string;
turnRevision: number;
viewRevision: number;
phase: DesignWorkspacePhase;
brief: DesignBrief;
updatedAt: string;
};
export type ImageWorkspaceSnapshot = {
capabilities: ImageWorkspaceCapabilities;
projects: ImageWorkspaceProject[];
activeProjectId?: string | null;
export type DesignWorkspace = DesignWorkspaceSummary & {
messages: DesignMessage[];
};
export type ImageWorkspaceGenerationSettings = {
modeId?: string;
modelId?: string;
aspectRatioId?: string;
resolutionId?: string;
outputCountId?: string;
};
export type ImageWorkspaceSendMessageInput = {
projectId: string;
agentId: string;
prompt: string;
referenceImageIds: string[];
settings: ImageWorkspaceGenerationSettings;
};
export type ImageWorkspaceReferenceUploadInput = {
projectId: string;
fileName: string;
export type DesignAsset = {
assetId: string;
workspaceId: string;
mediaType: DesignMedium;
mimeType: string;
contentBase64: string;
width: number;
height: number;
durationMilliseconds: number | null;
createdAt: string;
contentPath: string;
};
export type ImageWorkspaceReferenceUploadResult = {
workspace: ImageWorkspaceSnapshot;
reference: ImageWorkspaceImage;
export type DesignGenerationTask = {
taskId: string;
workspaceId: string;
medium: DesignMedium;
status: DesignTaskStatus;
briefVersion: number;
briefSummary: string;
quoteId: string | null;
quotedDesignPoints: number | null;
failureCode: string | null;
resultAssets: DesignAsset[];
createdAt: string;
updatedAt: string;
};
export type DesignWorkspaceBootstrap = {
capabilities: DesignCapabilities;
workspaces: DesignWorkspaceSummary[];
};
export type DesignCreateWorkspaceInput = {
clientWorkspaceId: string;
title: string;
};
export type DesignRenameWorkspaceInput = {
workspaceId: string;
title: string;
};
export type DesignSubmitMessageInput = {
workspaceId: string;
clientTurnId: string;
expectedTurnRevision: number;
message: string;
attachmentAssetIds?: string[];
};
export type DesignConfirmGenerationInput = {
workspaceId: string;
clientTurnId: string;
expectedTurnRevision: number;
quoteId: string;
};
export function designAssetContentPath(workspaceId: string, assetId: string): string {
return `${IMAGE_WORKSPACE_API_PATH}/workspaces/${encodeURIComponent(workspaceId)}/assets/${encodeURIComponent(assetId)}/content`;
}