feat: simplify AI design for young creators

This commit is contained in:
2026-09-02 17:48:03 +08:00
parent 7552cf5952
commit 756638a28a
17 changed files with 3595 additions and 297 deletions

View File

@@ -142,6 +142,11 @@ function isDirectionConflict(error: unknown): boolean {
|| error.code === 'DIRECTION_REVISION_CONFLICT');
}
function isQuoteBlocked(error: unknown): boolean {
return error instanceof ImageWorkspaceApiError
&& error.code.toLowerCase() === 'design_quote_blocked';
}
function parseWorkspaceEvent(event: Event): DesignWorkspaceEvent | null {
const data = (event as MessageEvent<unknown>).data;
if (typeof data !== 'string') return null;
@@ -184,6 +189,8 @@ function withWorkspace(
workspace: DesignWorkspace,
): Partial<ImageWorkspaceState> {
updateBackgroundLease(workspace.tasks);
const sameSpecification = state.workspace?.workspace.workspaceId === workspace.workspace.workspaceId
&& state.workspace.form.specificationRevision === workspace.form.specificationRevision;
return {
status: 'ready',
activeWorkspaceId: workspace.workspace.workspaceId,
@@ -195,6 +202,7 @@ function withWorkspace(
}
: state.bootstrap,
error: null,
quoteBlockers: sameSpecification ? state.quoteBlockers : [],
};
}
@@ -304,6 +312,12 @@ export const useImageWorkspaceStore = create<ImageWorkspaceState>((set, get) =>
delete pendingOperations[operation.id];
return { pendingOperations, status: 'auth-required', error: message };
});
} else if (isQuoteBlocked(error)) {
set((state) => {
const pendingOperations = { ...state.pendingOperations };
delete pendingOperations[operation.id];
return { pendingOperations, error: null };
});
} else {
set((state) => ({
pendingOperations: {
@@ -512,9 +526,16 @@ export const useImageWorkspaceStore = create<ImageWorkspaceState>((set, get) =>
set((state) => {
if (!state.workspace) return { lastEventId: event.id };
const nextWorkspace = applyEventToWorkspace(state.workspace, event);
const specificationChanged = nextWorkspace.form.specificationRevision
!== state.workspace.form.specificationRevision;
const pendingOperations = { ...state.pendingOperations };
if (event.type === 'design.quote.blocked') {
delete pendingOperations[event.clientOperationId];
}
updateBackgroundLease(nextWorkspace.tasks);
return {
workspace: nextWorkspace,
pendingOperations,
bootstrap: state.bootstrap
? {
...state.bootstrap,
@@ -524,7 +545,10 @@ export const useImageWorkspaceStore = create<ImageWorkspaceState>((set, get) =>
lastEventId: event.id,
quoteBlockers: event.type === 'design.quote.blocked'
? event.blockers
: state.quoteBlockers,
: specificationChanged
? []
: state.quoteBlockers,
error: event.type === 'design.quote.blocked' ? null : state.error,
};
});
if (event.type === 'design.workspace.updated' && event.changedDirection) {
@@ -574,7 +598,7 @@ export const useImageWorkspaceStore = create<ImageWorkspaceState>((set, get) =>
input: { kind: 'direct_edit', operations },
};
return executeCommand(command, {
label: '保存设计字段',
label: '保存你的调整',
clearDraftPaths,
});
},
@@ -592,7 +616,7 @@ export const useImageWorkspaceStore = create<ImageWorkspaceState>((set, get) =>
clientOperationId: createImageWorkspaceOperationId(),
input: { kind: 'chat', message },
};
return executeCommand(command, { label: '发送设计对话', clearChatDraft: true });
return executeCommand(command, { label: '发送消息', clearChatDraft: true });
},
resolveDecisionPrompt: async (promptId, action, optionId) => {
@@ -611,7 +635,7 @@ export const useImageWorkspaceStore = create<ImageWorkspaceState>((set, get) =>
...(optionId ? { optionId } : {}),
},
};
return executeCommand(command, { label: '确认设计决策' });
return executeCommand(command, { label: '保存你的选择' });
},
requestQuote: async () => {
@@ -625,7 +649,7 @@ export const useImageWorkspaceStore = create<ImageWorkspaceState>((set, get) =>
specificationRevision: workspace.form.specificationRevision,
clientOperationId: createImageWorkspaceOperationId(),
};
return executeCommand(command, { label: '编译生成方案' });
return executeCommand(command, { label: '准备制作方案' });
},
confirmGeneration: async (quoteId) => {
@@ -639,7 +663,7 @@ export const useImageWorkspaceStore = create<ImageWorkspaceState>((set, get) =>
expectedDirectionRevision: workspace.form.directionRevision,
clientOperationId: createImageWorkspaceOperationId(),
};
return executeCommand(command, { label: '确认生成' });
return executeCommand(command, { label: '开始制作' });
},
retryOperation: async (clientOperationId) => {