fix(design): restore streamed replies and quote handoff

This commit is contained in:
2026-09-04 11:37:03 +08:00
parent 229b1b1ce3
commit 23f96a523e
9 changed files with 362 additions and 19 deletions

View File

@@ -0,0 +1,149 @@
# Task: Restore AI Design reply streaming and generation CTA
## Identity
- Task ID: 20260904-fix-design-stream-4f7b91c2
- Mode: Feature
- Branch: codex/20260904-diagnose-design-stream-6a4e9c21-diagnose-design-stream
- Worktree: D:\Datas\OthersProjects\.codex-worktrees\makelore\20260904-diagnose-design-stream-6a4e9c21
- Base commit: 229b1b1ce39b7f1541a93ea3c980ab82b6d6266c
- Owner: codex-root
- Status: Ready for Integration
## Scope
- Restore a visible, explicitly unfinished assistant reply in the AI Design
conversation from the existing `design.assistant.delta` / `assistantStreams`
transport, and remove it when the canonical assistant turn settles.
- Add a youth-readable inline “看看制作方案” action at the end of a ready
conversation. Reuse the existing Quote request and reveal the offered Quote after
success; preserve the separate explicit Design Point confirmation before Task
creation.
- Own only `DesignConversationPane`, the ImageCanvas composition, the smallest
necessary Quote/Card/store settlement seams, focused Renderer/Electron tests, and
this task record.
- Do not modify the Works Square server, reasoner contract, database/API DTOs,
billing semantics, Plugin navigation, packaging, publication, or the three foreign
untracked task records in the client root.
## Intent And Constraints
- The user confirmed the preferred interaction: the conversation should paint the
assistant's reply incrementally again, but must not restore the removed generic
“AI 正在整理你的想法” progress banner or present the right-side Specification
summary as a second completed chat reply.
- A streamed fragment is provisional presentation only. `workspace.turns` remains
canonical history; canonical settlement replaces the provisional bubble and must
not leave duplicate or permanently pulsing text.
- The existing transport is post-validation chunk projection, not provider-native
time-to-first-token streaming. This task restores honest incremental painting from
that supported contract and does not broaden the server work.
- Readiness may invite the user to inspect a Quote, but ordinary chat never authorizes
a paid generation Task. Quote request, offered Quote, explicit Quote-ID confirmation,
and Task projection remain separate boundaries.
- Preserve provisional user-message immediacy, stable operation identity, unknown
outcome recovery, and youth-readable failure copy.
## Project Context Loaded
- Concurrent Task Gate passed for task `20260904-fix-design-stream-4f7b91c2`, mode
Feature, on branch
`codex/20260904-diagnose-design-stream-6a4e9c21-diagnose-design-stream` in isolated
worktree
`D:\Datas\OthersProjects\.codex-worktrees\makelore\20260904-diagnose-design-stream-6a4e9c21`
at exact base `229b1b1ce39b7f1541a93ea3c980ab82b6d6266c`; ownership is claimed by
`codex-root`.
- Loaded the startup memory set, current state, ADR-007, system overview, business
rules, success criteria, evidence/reflection/commitment indexes, and the completed
diagnosis task that reproduced the missing streamed presentation while proving the
Quote-confirm-Task source path still works.
- Relevant peer tasks are historical/stale or already integrated. This scope does not
overlap the Plugin navigation planner, the older Enter-submission test task, or the
three foreign untracked root records.
- The current canonical docs intentionally keep raw deltas out of completed history
and prohibit a separate progress banner. The user's explicit product decision adds
a narrower distinction: a delta may be shown as one visibly unfinished assistant
bubble that is replaced by the canonical turn. Record this as a promotion candidate
rather than editing canonical docs in Feature mode.
- Planning Gate result: Passed.
## Plan
1. Add failing Renderer regressions for provisional assistant visibility,
canonical replacement, and the ready-conversation Quote action.
2. Implement the minimal presentation and settlement changes, then make both the
conversation CTA and right-side CTA reveal the offered Quote.
3. Run focused unit/Electron checks plus typecheck, scoped lint, build, diff, and
project-document gates; document the exact outcome and remaining architectural
limitation.
## Outcome
- Restored the existing `assistantStreams` presentation as one assistant-shaped,
visibly unfinished reply beneath its matching pending chat operation. New chunks
update that same bubble and its pulse cursor; the removed generic “AI 正在整理你的
想法” status banner remains absent.
- Kept provisional output out of canonical history. Per-command success or definitive
failure clears that operation's stream, and the conversation only renders a stream
while its original pending chat identity still exists, so the later canonical
`workspace.turns` reply replaces rather than duplicates it. Direction events do not
globally clear unrelated streams because they expose no client operation identity;
unknown outcomes retain their original pending identity and partial reply.
- Added an inline ready-state handoff at the end of the conversation. It explains that
the next step only calculates Design Point cost and requests a Quote; it never calls
generation confirmation.
- After a Quote request succeeds from either the conversation action or the right-side
Creation Card, desktop scrolls the offered Quote into view and mobile opens the
Current Idea/Works sheet before locating it. The existing explicit
“花 N 设计点开始制作” Quote-ID confirmation remains the only Task-creation action.
- No Works Square server, reasoner, database/API DTO, billing, Plugin navigation,
packaging, or publication code changed.
## Verification
- Red phase: the focused Renderer suite failed exactly because no streamed assistant
bubble and no conversation Quote action existed (2 failed / 26 passed).
- Focused final suite:
`pnpm exec vitest run tests/unit/image-canvas-page.test.tsx tests/unit/image-workspace-store.test.ts tests/unit/youth-creation-card.test.tsx`
-> 3 files / 35 tests passed.
- The focused regressions include two simultaneous stream identities, an unknown Quote
that disables both Quote entry points and retries the original operation, and the
mobile inline action opening the Sheet with its offered Quote.
- Electron production flow:
`node ./node_modules/@playwright/test/cli.js test tests/e2e/image-workspace-v2.spec.ts -g "keeps conversation and youth-friendly direct edits"`
-> 1 passed; it used the new conversation action, verified the Quote was in the
viewport, explicitly confirmed 12 Design Points, and observed the queued Task.
- `pnpm exec tsc --noEmit`, scoped ESLint for every changed TypeScript/test file,
`pnpm run build:vite`, and `git diff --check` passed. Vite reported only existing
Browserslist, chunk-size, and dynamic/static-import warnings.
- Full ordinary suite reached 224 passing files / 1,873 passing tests / 2 declared
skips. Its only failure was an unrelated real Pi subprocess latency assertion
(2,310 ms versus a 2,000 ms threshold); the exact process test passed 1/1 when
immediately rerun alone. The separately gated pressure test passed 1/1.
- Independent read-only review found and then verified fixes for the two concrete P2
gaps above (global stream cleanup and duplicate unknown Quote submission); final
verdict: PASS with no remaining P1/P2 blocker.
## Follow-ups
- The current server does not provide provider-native time-to-first-token streaming:
it validates the complete structured reasoner response, then projects the final
assistant message in short chunks. Genuine earlier first-visible-text would require
a separately designed server conversational-stream contract; this client task does
not pretend otherwise.
## Promotion Candidates
- Target canonical documents: `.project-docs/20-architecture/system-overview.md` and
`.project-docs/40-domain/business-rules.md`. Proposal: distinguish completed
canonical assistant turns, a single provisional assistant bubble backed by
`design.assistant.delta`, and the prohibited generic progress/summary banner; also
record that ready conversation UI may request/reveal a Quote but only explicit
Quote-ID confirmation can create a paid Task. Evidence: the red-to-green Renderer
regressions and passing Electron Quote-confirm-Task flow in this task. Future impact:
prevents another presentation cleanup from accidentally removing supported
incremental feedback or collapsing Quote review into generation authorization.
Semantic conflict: current wording says raw delta must not be displayed as a
completed reply and forbids a separate progress bar; the new behavior preserves
both constraints by displaying exactly one explicitly unfinished reply. Human
confirmation was required and was supplied by the user before implementation.