diff --git a/.project-docs/20-architecture/system-overview.md b/.project-docs/20-architecture/system-overview.md index dd25c8e3..63e5e82e 100644 --- a/.project-docs/20-architecture/system-overview.md +++ b/.project-docs/20-architecture/system-overview.md @@ -25,7 +25,7 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展 | Pi Extension, Subagents & Lifecycle | 必需的生成式 Makelore extension、Main 显式选定的已安装 extensions、UI interaction、ephemeral child、write lease 与 background run lease | Makelore bridge 固定为首个 extension,其余选定 extension 全部经 Pi 的 explicit additional paths 加载且 ambient discovery 关闭;child 并发 4、单次最多 8、禁止递归;active/uncertain run 不因页面隐藏或 confirmation timeout 被停止,replacement/stop 必须可解释并清理所有 ownership | | Official Hosted Plugins | Acquired code-owned bundled Game Resource package → effective parent snapshot → code-owned Main adapter → fixed Works Square hosted route | 无设备下载、更新、Beta 或签名步骤;Renderer/Package/Pi 不持有 Provider key、model 或 URL。每次计费操作要求显式确认,child 不继承 hosted tool。历史 Hosted Web Search 不再进入当前客户端。 | | Device Packages | Conversation install tools → Main-owned inspect/preview/confirm/commit → immutable local generation → parent Skill/Pi-extension resources | 支持 npm、Git、绝对本地 Plugin 目录与 loose `SKILL.md`;没有可见安装入口、Account Library、Release、Admission 或 Marketplace Package Store。可执行 extension 拥有桌面用户权限且生命周期脚本禁用。每个 generation 包含所有显式安装且当前启用的 Skill/extension;新/idle parent 自动刷新,active parent 在 turn settled 后刷新,child 始终为空。 | -| AI Design Workspace & Living Form | 一个 Workspace 的当前 Direction、Current Specification、持久 Agent Session、conversation timeline、Tasks 与 Assets | Living Form 是服务端 Current Specification 的投影;Renderer 只持有草稿和已接受投影 | +| AI Design Workspace & Living Form | 一个 Workspace 的当前 Direction、Current Specification、持久 Agent Session、conversation timeline、Tasks 与 Assets | 自然对话是主创作面;Living Form 仅以“AI 已理解”的紧凑辅助摘要与可选手动调整投影服务端 Current Specification,Renderer 只持有草稿和已接受投影 | | AI Design Input & Reconciliation | Chat、字段/集合编辑、decision、proposal、lock、Asset binding 与 restore | 全部进入同一 `design.input.apply` reducer;稳定 command/operation ID 支持 unknown-result 重放,revision conflict 刷新权威状态 | | AI Design Gateway Routing | Main-owned Works Square V2 adapter 与 Direction event stream | Main 持有 Works Token、stream ticket、WebSocket、重试分类和错误脱敏;事件顺序与 Task progress 不构成 Specification 真值 | | AI Design Quote & Task Controls | 精确 Specification revision 编译出的不可变 Quote 与 Workspace Tasks | 客户端只展示 public output summary、warnings、expiry 与 Token Points,并以 Quote ID 确认;Provider Prompt/model/route/storage/billing atoms 不下发 | @@ -84,6 +84,7 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展 - 落盘文件名 `works-cloud-deploy.json` 仅为已安装客户端的数据兼容;领域模型和代码接口是 submission binding,不表示仍存在 cloud deployment coordinator。 - AI Design 的一个 Workspace 公开一个当前 Direction、一个持久 Agent Session 和一个 Current Specification;conversation timeline 是交互历史,不是独立创建或选择的语义权威。 - Living Form 与 chat、direct edit、decision、proposal、lock、Asset binding、restore 共用同一服务端 reducer。Renderer 草稿在 accepted 前不进入 canonical state。 +- AI Design Renderer 必须把自由描述与 Agent 的自然追问放在主交互面。Specification 投影只复述当前理解并提供默认收起的细节和可选手动调整;普通 Decision Prompt 不得自动渲染成要求青少年逐项完成的表单。 - Main 通过 `design.input.apply`、`design.quote.request` 和 `design.generation.confirm` 访问 V2。unknown transport result 必须复用原 command/operation identity;结构化业务错误不得重放,未知上游文本不得穿透安全投影。 - Main-owned Canvas Workspace JSON 请求和 shared Works token refresh 的完整生命周期最多 30 秒,超时 abort transport 并以固定 `504 DESIGN_WORKSPACE_REQUEST_TIMEOUT` 结束 Renderer 等待。Electron `net.fetch` 失败后的 Node fetch 透明回退只允许 `GET`、`HEAD`、`OPTIONS`;PATCH/POST 等 mutation 只允许由持有显式幂等身份的上层协议决定重试,不能由底层 transport 隐式重放。该边界不改变上面的 WebSocket→REST 幂等 fallback。 - Renderer 的异步与流式结果必须核对 Workspace、Direction、revision 和 operation identity;Direction snapshot 是 Specification 真值,Task/Asset 事件只更新 Workspace resource projection。 @@ -100,4 +101,4 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展 ## Last Updated -2026-09-03 +2026-09-04 diff --git a/.project-docs/30-worklog/current-state.md b/.project-docs/30-worklog/current-state.md index 1cf3d278..e1a1872c 100644 --- a/.project-docs/30-worklog/current-state.md +++ b/.project-docs/30-worklog/current-state.md @@ -4,6 +4,24 @@ This file is the integrated default-branch snapshot. Feature tasks record progre ## Integrated Through +- Conversation-first AI Design client source + `fe50e4ba198649a07c5c9443f15edf7dfa2a47e6` from task + `20260903-design-guided-conversation-client-8b4e1c72` is integrated onto local + `main` by task `20260904-integrate-guided-design-6a3f9c82`. ImageCanvas now makes + free-form conversation the dominant creation surface: first-use guidance invites + creators aged 8–16 to describe a subject, scene, or feeling in their own words, + the Agent-facing examples only prefill the composer, and ordinary persisted + Decision Prompts no longer appear as required option-card forms. The secondary + surface is now a compact “AI 听懂的想法” projection whose constraints, + references, and video details are collapsed by default; manual field editing is + explicitly optional. ADR-007 remains intact: Current Specification is still the + server semantic authority, Quote confirmation still submits only immutable Quote + identity, and Main transport/operation certainty is unchanged. Focused/adjacent + 45-test, typecheck, scoped lint, production build, pressure 1/1, and Electron E2E + 2/2 passed. The ordinary full suite passed 1,866 tests with 2 conditional skips + and one unrelated Pi real-process 2-second timing assertion at 2,232 ms; that + exact file passed 5/5 in isolation. No server contract, paid generation, package, + deployment, publication, or remote push is claimed. - AI Design command-outcome source `83f3f134a6779251aaa18f3290308cd9221b038f` from task `20260903-design-message-send-client-8d3f2a71` is integrated on `main` as @@ -670,6 +688,7 @@ Robot 绑定设备默认先显示“引导配网 / 已有激活码”路径选 - 本地构建必须使用安装版 Electron Node、固定 npm 11.6.2 和项目 `package-lock.json` 锁定的 Vite,不得回退到全局 PATH、已有 `node_modules` 或未验证的 npm 闭包;依赖安装需要网络。 - 项目 Vite config/plugins 以桌面用户权限执行,不能称为 sandbox;此风险边界必须在发布说明中保留。 - AI Design 的 Current Specification 是唯一语义权威。Direction events 必须按 Workspace/Direction/revision/operation identity 收敛;assistant delta、event cursor、Task progress 和 Asset updates 不得改写 Living Form。 +- AI Design 的用户交互以自然对话为主:先理解并复述用户已经说清楚的内容,再一次只推进一个关键问题。Current Specification 的客户端投影只作为“AI 已理解”的辅助摘要和可选手动调整面板;新增字段不得自动变成必填问题或选项卡表单。 - Design unknown-result replay 必须复用原 stable command 与 semantic operation ID;业务错误不得重复提交。Immutable Quote confirmation 只提交 Quote ID,Task recovery 不授权新的生成 intent。 - AI 绘画 Main-owned Workspace JSON 请求和共享 Works token refresh 必须在 30 秒内结束并释放共同等待者;只允许 `GET`/`HEAD`/`OPTIONS` 在 Electron transport 失败后透明改走 Node fetch,PATCH/POST 等 mutation 必须由具有显式幂等身份的上层协议决定是否重试。临时 `disable-http2` 只用于安装包诊断,不能替代该有限生命周期与非重放边界。 - 服务端 current Direction Session 与 semantic history 不由客户端在注销或退出时删除;Main 只关闭本地流、清除 drafts/pending state 和本机凭据。 @@ -683,4 +702,4 @@ Robot 绑定设备默认先显示“引导配网 / 已有激活码”路径选 ## Last Updated -2026-09-03 +2026-09-04 diff --git a/.project-docs/30-worklog/tasks/20260903-design-guided-conversation-client-8b4e1c72.md b/.project-docs/30-worklog/tasks/20260903-design-guided-conversation-client-8b4e1c72.md new file mode 100644 index 00000000..45810be7 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260903-design-guided-conversation-client-8b4e1c72.md @@ -0,0 +1,133 @@ +# Task: Make AI Design conversation primary + +## Identity + +- Task ID: 20260903-design-guided-conversation-client-8b4e1c72 +- Mode: Feature +- Branch: codex/20260903-design-guided-conversation-client-8b4e1c72-design-guided-conversation-client +- Worktree: D:\Datas\OthersProjects\.codex-worktrees\makelore\20260903-design-guided-conversation-client-8b4e1c72 +- Base commit: 14efa99f0ca7a02d6ae4e08311f125c56b9399a6 +- Owner: codex-root +- Status: Ready for Integration + +## Scope + +- Make the AI Design conversation the primary creation surface and remove the + impression that a young creator must complete a design form before the Agent can + help. +- Reframe the canonical Specification projection as a compact, secondary “current + understanding” summary with optional detail editing; keep Quote, Task, Asset, and + typed reducer behavior unchanged. +- Add clear first-use guidance that invites a free description and gives a few + example starting points without turning them into required choices. +- Own only the ImageCanvas Renderer presentation and focused unit/Electron tests. + Do not change Electron Main transport, server DTOs, Plugin navigation, packaging, + deployment, publication, or paid generation. + +## Intent And Constraints + +- Preserve ADR-007: the server Current Specification remains the single semantic + authority, Renderer drafts stay local until accepted, and generation still uses + an immutable Quote ID. +- Conversation must remain visually and behaviorally usable when the Specification + is sparse. The interface should invite the user to describe subject, scene, and + feeling in their own words, not enumerate professional fields or force option + cards. +- The compact summary may show what the Agent currently understands and expose an + optional detail drawer, but it must not compete with the composer for attention or + claim readiness before server validation. +- Keep Chinese-only copy, the existing light visual language, keyboard behavior, + reduced-motion support, 40–44 px interactive targets, and current responsive + single-mount rules. +- Preserve the prior definitive-failure versus transport-unknown behavior and all + stable operation identities. + +## Concurrent Task Gate + +- Task ID: `20260903-design-guided-conversation-client-8b4e1c72`. +- Mode: Feature. +- Branch/worktree: + `codex/20260903-design-guided-conversation-client-8b4e1c72-design-guided-conversation-client` / + `D:\Datas\OthersProjects\.codex-worktrees\makelore\20260903-design-guided-conversation-client-8b4e1c72`. +- Base commit: `14efa99f0ca7a02d6ae4e08311f125c56b9399a6`. +- Ownership result: isolated and exclusively claimed by `codex-root`; the root + `main` worktree and its three foreign untracked task records remain untouched. +- Peer assessment: the only planning Design peers are an old test-only Enter change + on an August baseline and an undefined historical assessment task. Neither owns + the current ImageCanvas production surface. Plugin navigation and other active + tasks use separate worktrees and have no path overlap. +- Gate result: Passed. + +## Project Context Loaded + +- Read the startup memory set, active task, integrated state, decision index, + ADR-007, system overview, module/data flow, Design business rules and success + criteria, evidence/reflection/commitment/stale indexes, the integrated youth Design + source, the command-outcome source, and relevant peer scopes. +- Confirmed that the existing “我的创作” card is a projection, not semantic + authority. Making it secondary is compatible with ADR-007 and does not require a + DTO or reducer change. +- `project-positioning.md` and the top-level project success placeholder remain + incomplete; concrete product constraints come from `AGENTS.md`, current state, + ADR-007, architecture, domain rules, and the previous integrated Design tasks. +- Planning Gate result: Passed. + +## Outcome + +- The conversation is now the dominant creation surface on desktop and mobile. Its + first-use copy teaches creators to describe a subject, scene, or feeling in their + own words, and example sentences only prefill the composer. +- Ordinary server Decision Prompts are no longer rendered as option-card forms or + allowed to hold the youth-facing projection in an artificial “choice” phase. +- The secondary panel is now “AI 听懂的想法”: it states that it updates from the + conversation, keeps the concise summary and production readiness visible, and + places constraints, references, and video details behind an optional disclosure. +- Manual field editing remains available as an explicitly optional action. Quote, + Task, Asset, typed reducer, stable operation identity, and Main transport behavior + are unchanged. +- The desktop layout gives materially more width to conversation while preserving a + single mounted summary/production surface at each responsive breakpoint. + +## Verification + +- Red baseline: the two initial component files produced `8 failed / 7 passed`, + confirming the old headings, mobile entry, and Decision Prompt cards still drove + the experience. +- Focused conversation/card/projection tests: `22 passed`. +- Adjacent ImageCanvas, Fine Tune, issue-copy, and store regression: `45 passed`. +- TypeScript `tsc --noEmit`: passed. +- Changed-file ESLint: passed. +- Production Vite/Electron build: passed; only existing browserslist, dynamic-import, + and chunk-size warnings were emitted. +- Electron/Playwright Design workspace flow: `2 passed`, covering desktop/mobile + responsive mounts, optional manual adjustment, conversation, Quote, and generation + confirmation. +- Full unit run reached `1866 passed / 2 skipped / 1 failed`; the sole failure was an + unrelated Pi real-process timing assertion (2.232 seconds against a 2-second + threshold) under parallel load. Its isolated rerun passed `5/5`. +- Coding chat pressure test, which the package script runs separately: `1 passed`. +- `git diff --check`: passed. + +## Follow-ups + +- None recorded. + +## Promotion Candidates + +- Target: `.project-docs/30-worklog/current-state.md` and the canonical AI Design UX + description. +- Proposal: record the MakeLore AI Design surface as conversation-primary. The + persistent Specification projection is a compact “AI understood” summary and + optional manual-edit surface, never a prerequisite form for beginning or + continuing creation. +- Evidence: explicit user direction, red tests demonstrating the former form-led + behavior, 45 focused/adjacent passing tests, production build, and 2/2 Electron + end-to-end flow. +- Future impact: new Specification fields must not automatically become visible + questions or controls; Agent guidance should remain natural language and request + only one consequential clarification at a time. +- Semantic conflicts: this supersedes the earlier “persistent Creation Card as the + primary co-authored form” presentation while preserving ADR-007 authority, + reducer, Quote, and production boundaries. +- Human confirmation: already supplied by the user in this task; no additional + product-direction confirmation is required during integration. diff --git a/.project-docs/30-worklog/tasks/20260904-integrate-guided-design-6a3f9c82.md b/.project-docs/30-worklog/tasks/20260904-integrate-guided-design-6a3f9c82.md new file mode 100644 index 00000000..8510e7f2 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260904-integrate-guided-design-6a3f9c82.md @@ -0,0 +1,93 @@ +# Task: Integrate conversation-first AI Design client + +## Identity + +- Task ID: 20260904-integrate-guided-design-6a3f9c82 +- Mode: Integration +- Branch: main +- Worktree: D:\Datas\OthersProjects\makelore +- Base commit: 14efa99f0ca7a02d6ae4e08311f125c56b9399a6 +- Owner: codex-root +- Status: Ready for Integration + +## Scope + +- Integrate completed client source `fe50e4b` from task + `20260903-design-guided-conversation-client-8b4e1c72` onto exact `main` + baseline `14efa99f0ca7a02d6ae4e08311f125c56b9399a6`. +- Promote the accepted conversation-first AI Design presentation into canonical + current state, system overview, and business rules. +- Preserve the three explicitly adopted foreign untracked task records byte-for-byte; + do not add, move, edit, stash, reset, or clean them. +- Do not change server, Electron Main, DTO/API, generation, billing, plugins, + package, deployment, publication, or remote history. + +## Intent And Constraints + +- The user explicitly replaced the former form-led presentation with a natural + conversation that helps young creators describe a clear need. This is the + human-confirmed product direction for the integration decision. +- ADR-007 remains accepted: Current Specification is still server authority, + Renderer drafts remain local until accepted, and generation confirmation still + submits only an immutable Quote identity. +- Integrate the source task record unchanged. Canonical documents may summarize its + accepted promotion candidate but must not overstate local automation as production + deployment or real paid generation evidence. +- The completed source task passed focused, adjacent, typecheck, lint, production + build, and Electron end-to-end verification. One unrelated Pi real-process timing + assertion failed only under full parallel load and passed 5/5 in isolation. + +## Project Context Loaded + +- Concurrent Task Gate: passed in Integration mode on root `main`; the worktree is + exclusively owned by this task and its three known foreign task records were + adopted by exact fingerprint under prior user authorization. +- Planning Gate: passed after reading the active and source tasks, integrated current + state, ADR-007, system overview, business rules, success criteria, and the evidence, + reflection, commitment, and stale indexes. +- Other active tasks are isolated in separate worktrees. The completed Design source + owns the exact ImageCanvas changes being integrated; plugin navigation is already + present in the base; no active peer owns or semantically conflicts with this scope. +- `project-positioning.md` remains a project-wide placeholder. Concrete constraints + come from accepted ADR-007 and the populated architecture/domain/current-state + records. + +## Outcome + +- Applied source `fe50e4ba198649a07c5c9443f15edf7dfa2a47e6` without + conflicts onto its exact parent baseline. The source task record remained + byte-identical to the committed source blob. +- `main` now contains the conversation-first ImageCanvas: natural description and + one-at-a-time Agent questions are primary, persisted option cards are not rendered + as a form, the “AI 听懂的想法” projection is secondary, detailed constraints are + collapsed by default, and manual field adjustment is explicitly optional. +- Promoted the accepted behavior to `current-state.md`, `system-overview.md`, and + `business-rules.md` without changing ADR-007's authority or Quote boundary. +- The three adopted foreign untracked task records remain unmodified and excluded + from the integration commit. + +## Verification + +- Source product paths match source commit `fe50e4b` exactly. +- Root-main focused/adjacent unit regression: `45 passed`. +- Root-main TypeScript `tsc --noEmit`: passed. +- Root-main changed-file ESLint: passed. +- Root-main production Vite/Electron build: passed with only existing browserslist, + dynamic-import, and chunk-size warnings. +- Root-main Electron/Playwright AI Design flow: `2 passed` across desktop/mobile, + optional manual adjustment, conversation, Quote, and generation confirmation. +- Source full-unit evidence: `1866 passed / 2 skipped / 1 unrelated timing failure`; + the Pi real-process timing file passed `5/5` in isolation, and pressure passed + `1/1`. +- Source task record blob equality, `git diff --check`, project-doc completeness, + and task-aware integration drift: passed. + +## Follow-ups + +- None recorded. + +## Promotion Candidates + +- Applied the source task's conversation-first presentation candidate to canonical + current state, system architecture, and business rules. No unresolved promotion + candidate remains. diff --git a/.project-docs/40-domain/business-rules.md b/.project-docs/40-domain/business-rules.md index 62d3773d..c6f35413 100644 --- a/.project-docs/40-domain/business-rules.md +++ b/.project-docs/40-domain/business-rules.md @@ -96,6 +96,7 @@ - 客户端更新检查由 Electron Main 持有。缺少当前平台正式稳定 manifest 必须保持错误并提示稍后重试或从官网下载,不得宣称“已是最新版”;设置页只显示一条中文用户提示,原始堆栈、URL、路径和错误码只保留在 Main 日志。 - 一个 AI Design Workspace 公开一个 current Direction、一个 persistent Agent Session 和一个 Current Specification;conversation timeline 不是独立创建或选择的权威对象。 - Living Form 只能投影服务端 Current Specification。Chat、direct edit、decision、proposal、lock、Asset binding 与 restore 必须通过同一 V2 reducer;Renderer drafts 在 accepted 前保持本地。 +- AI Design 必须以自然对话帮助用户描述清楚需求:先提取和复述已明确内容,每次最多推进一个真正影响作品的问题。客户端 Current Specification 投影是辅助摘要和可选手动调整,不得把内部字段、缺项或普通 Decision Prompt 变成用户必须逐项填写的表单。 - 每个 mutation 使用稳定 command 与 semantic operation identity。transport-unknown 只能重放原命令;business rejection、timeout 或用户再次点击不能自动生成新的业务意图。 - Direction projection 是 Specification 真值。event cursor、assistant delta、Task progress 与 Asset event 只用于传输/资源收敛,不得推进或覆盖 canonical specification revision。 - Main 只向 Renderer 投影已知错误码的固定中文提示,未知上游错误文本必须脱敏为通用提示;Works Token、stream ticket、provider internals 留在 Main/服务端。 @@ -142,4 +143,4 @@ ## Last Reviewed -2026-09-03 +2026-09-04 diff --git a/src/pages/ImageCanvas/CreativeChoiceGrid.tsx b/src/pages/ImageCanvas/CreativeChoiceGrid.tsx deleted file mode 100644 index 23e0bebe..00000000 --- a/src/pages/ImageCanvas/CreativeChoiceGrid.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Check, Sparkles, X } from 'lucide-react'; -import { cn } from '@/lib/utils'; -import type { YouthActiveChoice } from './youth-form-projection'; - -export type CreativeChoiceGridProps = { - choice: YouthActiveChoice; - disabled?: boolean; - onSelect: (optionId: string) => void; - onReject?: () => void; -}; - -/** - * A small, keyboard-friendly surface for the one decision the creator needs - * to make next. The server-provided option label stays visible verbatim (so - * options such as “你帮我选” remain useful), while the first option gets a - * gentle recommendation marker. - */ -export function CreativeChoiceGrid({ - choice, - disabled = false, - onSelect, - onReject, -}: CreativeChoiceGridProps) { - if (choice.options.length === 0) return null; - - return ( -
-
-
-
-
-

{choice.title}

-

{choice.body}

-
-
- -
- 选择一个创作方向 - {choice.options.map((option, index) => { - const descriptionId = `${choice.id}-${option.id}-description`; - return ( - - ); - })} -
- - {onReject && ( - - )} -
- ); -} diff --git a/src/pages/ImageCanvas/DesignConversationPane.tsx b/src/pages/ImageCanvas/DesignConversationPane.tsx index d5c1f805..082902b4 100644 --- a/src/pages/ImageCanvas/DesignConversationPane.tsx +++ b/src/pages/ImageCanvas/DesignConversationPane.tsx @@ -7,12 +7,11 @@ import { ImageWorkspaceApiError } from '@/lib/image-workspace'; import { cn } from '@/lib/utils'; import { useImageWorkspaceStore } from '@/stores/image-workspace'; import type { DesignWorkspace } from '../../../shared/image-workspace'; -import { CreativeChoiceGrid } from './CreativeChoiceGrid'; const STARTER_MESSAGES = [ - '画一只会做饭的机器人', - '把我的涂鸦变成一段动画', - '做一张社团活动海报', + '我想做一张热闹的社团招新海报', + '我脑中有一只在月球踢球的熊猫', + '把我的涂鸦变成一段会动的小故事', ]; function chatFailureMessage(error: unknown): string { @@ -23,7 +22,7 @@ function chatFailureMessage(error: unknown): string { : '暂时没能确认这条消息的处理结果,内容还在输入框里'; } const messages: Record = { - design_reasoner_invalid: 'AI 没有整理好这次想法,请再试一次', + design_reasoner_invalid: 'AI 这次没听懂。你的内容还在输入框里,可以补充一个画面细节后再发送', design_reasoner_unavailable: 'AI 现在有点忙,暂时没能整理这次想法,请稍后再试', design_agent_run_failed: 'AI 这次没有整理好,内容还在输入框里,请再试一次', design_agent_run_cancelled: '这次整理已停止,内容还在输入框里', @@ -45,7 +44,6 @@ export function DesignConversationPane({ workspace }: { workspace: DesignWorkspa const chatDraft = useImageWorkspaceStore((state) => state.chatDraft); const setChatDraft = useImageWorkspaceStore((state) => state.setChatDraft); const sendChat = useImageWorkspaceStore((state) => state.sendChat); - const resolveDecisionPrompt = useImageWorkspaceStore((state) => state.resolveDecisionPrompt); const assistantStreams = useImageWorkspaceStore((state) => state.assistantStreams); const pendingOperations = useImageWorkspaceStore((state) => state.pendingOperations); const scrollAnchorRef = useRef(null); @@ -56,17 +54,12 @@ export function DesignConversationPane({ workspace }: { workspace: DesignWorkspa const submittingChat = Object.values(pendingOperations).some( (operation) => operation.status === 'submitting' && operation.command.kind === 'apply_input', ); - const activeDecisionPrompt = workspace.form.decisionPrompts - .find((prompt) => prompt.options.length > 0) - ?? workspace.form.decisionPrompts[0] - ?? null; - useEffect(() => { const scrollAnchor = scrollAnchorRef.current; if (typeof scrollAnchor?.scrollIntoView === 'function') { scrollAnchor.scrollIntoView({ block: 'end' }); } - }, [streams, workspace.form.decisionPrompts.length, workspace.turns.length]); + }, [streams, workspace.turns.length]); const submit = () => { if (!chatDraft.trim() || submittingChat) return; @@ -83,10 +76,10 @@ export function DesignConversationPane({ workspace }: { workspace: DesignWorkspa
-

一起做作品

+

和 AI 聊聊你的想法

- 先说一个想法就好,我会一次只问一个重要问题。 + 像和同学讲故事一样说就好。AI 会先听懂,再一次问一个最重要的问题。

@@ -96,10 +89,11 @@ export function DesignConversationPane({ workspace }: { workspace: DesignWorkspa
-

你想创作什么?

+

先把脑中的画面说出来

- 可以说一个想法,也可以先放一张图片。不用一次想完整。 + 不用懂设计。说说想画什么、发生在哪里,或者希望别人看到后有什么感觉;没有想全也没关系。

+

不知道怎么开头?试试这样说

{STARTER_MESSAGES.map((message) => (
@@ -172,7 +150,7 @@ export function DesignConversationPane({ workspace }: { workspace: DesignWorkspa value={chatDraft} rows={3} disabled={submittingChat} - placeholder="比如:画一只在月球踢球的熊猫……" + placeholder="比如:我想做一张社团招新海报,要热闹、有活力……" className="min-h-[72px] resize-none border-0 bg-transparent px-2 py-1.5 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0" onChange={(event) => setChatDraft(event.currentTarget.value)} onKeyDown={(event) => { diff --git a/src/pages/ImageCanvas/YouthCreationCard.tsx b/src/pages/ImageCanvas/YouthCreationCard.tsx index 6450e7a3..b8c8e53e 100644 --- a/src/pages/ImageCanvas/YouthCreationCard.tsx +++ b/src/pages/ImageCanvas/YouthCreationCard.tsx @@ -1,6 +1,7 @@ import { Ban, Check, + ChevronDown, Film, ImageIcon, Lightbulb, @@ -25,7 +26,6 @@ import { projectYouthCreationCard, type YouthCreationCardModel, } from './youth-form-projection'; -import { CreativeChoiceGrid } from './CreativeChoiceGrid'; export type YouthCreationCardProps = { workspace: DesignWorkspace; @@ -245,20 +245,20 @@ function ActionFooter({ case 'empty': return (
-

不用想得很完整,先说一句就好。

+

先在对话里说说脑中的画面,不用一次想完整。

); case 'exploring': return (
-

你可以继续补充,也可以让 AI 帮你整理。

+

继续描述你想看到的画面,AI 会接着问一个关键问题。

); @@ -336,37 +336,24 @@ export function YouthCreationCard({ onOpenFineTune, onFocusComposer, }: YouthCreationCardProps) { - const resolveDecisionPrompt = useImageWorkspaceStore((state) => state.resolveDecisionPrompt); const requestQuote = useImageWorkspaceStore((state) => state.requestQuote); const pendingOperations = useImageWorkspaceStore((state) => state.pendingOperations); const model = projectYouthCreationCard(workspace, { quoteBlockers }); - const submittingInput = Object.values(pendingOperations).some( - (operation) => operation.status === 'submitting' && operation.command.kind === 'apply_input', - ); const requesting = Object.values(pendingOperations).some( (operation) => operation.status === 'submitting' && operation.command.kind === 'request_quote', ); - const choose = (optionId: string) => { - if (!model.activeChoice || submittingInput) return; - void resolveDecisionPrompt(model.activeChoice.id, 'select', optionId).catch(() => { - toast.error('这个选择没有保存,请再试一次'); - }); - }; - - const rejectChoice = () => { - if (!model.activeChoice || submittingInput) return; - void resolveDecisionPrompt(model.activeChoice.id, 'reject').catch(() => { - toast.error('这个选择没有保存,请再试一次'); - }); - }; - const request = () => { if (!generationAvailable || requesting || !model.canRequestQuote) return; void requestQuote().catch(() => { toast.error('制作方案还没准备好,请稍后再试'); }); }; + const hasMoreDetails = model.mustInclude.length > 0 + || model.mustPreserve.length > 0 + || model.mustAvoid.length > 0 + || model.references.length > 0 + || model.video !== null; return (