Repository navigation
会话页:AI 过程折叠改为按正文分段的过程卡片 - #10
Merged
Merged
Conversation
A process card now covers one run — the thinking and tool steps between two
reply texts — instead of one hairline bar per round that kept its last two
steps. Reply text ends the current card on arrival and the next steps start a
new one; a tool-only round settles into a single card when the round ends.
Copy splits by state. While running and collapsed the card leads with what it
is doing ("思考中" / "调用工具 ××") plus the step counts and a ticking
duration; expanded, the header is only the current state because the steps are
on screen; settled, it reads "✅ · 思考 N · 工具 M · 时长". "输出中" is
intentionally absent — reply text closes the card immediately, so that state
would flash for one frame.
Expansion is two independent layers. A running card auto-expands, and a manual
collapse suppresses that for the rest of THIS card only; the next card
auto-expands again. A streaming thinking block auto-expands while its card is
open and collapses 500ms after it finishes, and a block the user collapsed (or
that already settled) does not reopen when the card does.
…r onto the process-card branch The two branches only collided in ChatScreen.kt, where each added a block right after expandedProcessIds. Both survive: the process card's auto-expand (running cards open unless the user collapsed that card by hand) followed by the pill's floatingOverlayBlocks mount gate and its 34dp reserve. The stale hasFloatingTools predicate the merge duplicated is dropped — the pill's gate is the one that honours the floating-bar pref and the streaming state.
…Class package, positional args on function-type call - ChatScreen.kt: add the MinisMenuSectionHeader import (4 call sites referenced it with only MinisMenu/MinisMenuDivider imported). - ChatScreenHelpers.kt: WindowSizeClass lives in androidx.window.core.layout, not androidx.compose.material3.adaptive (matches the import ChatSplitScaffold already uses). - ChatSplitScaffold.kt: the listPane slot is a function TYPE; named arguments are prohibited on its call sites. Pass `embedded` positionally (true in the drawer, false in the pane/sidebar).
…r through the detailPane slot - ChatAssistantMessageUI.kt: TextOverflow was imported twice (lines 25 and 92) — ambiguous import error. - ChatSplitScaffold.kt: openSessionDrawer is a LOCAL of ChatSplitScaffold, but the Route-level detailPane lambda referenced it (unresolved). Add onOpenSessionDrawer as the 7th parameter of the detailPane function TYPE; the scaffold passes `if (twoPane) null else openSessionDrawer` at its internal call site, and the Route lambda forwards it to ChatScreen unchanged.
…returns FlatChatItem list, outer expects ChatMessage list)
The per-segment process card built its messageId as
"${round.key}#${segment.firstBlockId}", but FlatKeys.of requires the
messageId to be ':'/'#'-free (parse() treats a trailing '#...' as the
dedupe suffix). Every folded-session build threw
IllegalArgumentException at the card construction site.
Join the segment discriminator with '--' instead. Consumers (ChatScreen's
toggle, runningCardKeys auto-expand) read item.messageId verbatim, so the
separator is internal to the key.
splitRounds treated RUNNING/PENDING/STREAMING tools as non-process, so a live run of "thinking + the tool it just started" stayed under SEGMENT_MIN_STEPS. The card never formed and the steps leaked back into the list, which is what the 11 process-fold tests assert against. A running tool is part of its run: stepRunning already records it and the row loop drops every id the segment owns. shouldShowProcessToolRow now only keeps an in-flight tool inline when folding produced no card. ask_user_question stays outside the card.
The card model (one card per run of ≥ 2 steps, closed the moment reply text arrives, expanded by the card's own key) landed with tests still asserting the old round rules: ≤ 2 steps never fold, a streaming message keeps its card running after the reply, and expansion is keyed by the bare message id. Those assertions could not pass against the card projection, which is why pr-check stayed red. Pin the card rules instead: a two-step run cards and a single step stays inline, reply text settles the card even while the message streams, and expansion uses the card key the toggle actually stores.
…t on reply text
Two contract gaps behind the remaining pr-check failures:
1. A card was emitted only where the run's FIRST message met its LAST
block, so a run spanning two messages (resume continuation, tool-only
round) produced no card at all — its steps stayed folded out of the
list and anything keyed by the card (expansion) broke with it.
2. A run closed by reply text still reported running when one of its
steps carried an in-flight status. The card contract says the reply
text ends the card on arrival ("输出中" was dropped for exactly this
reason), so the card settles there; a run the round closed instead
stays live while the round does.
Tests now pin the card contract and name it. pr-check prints full
assertion output (Gradle's condensed console hides expected/actual), so
the next red build is actionable from the job log alone.
Co-Authored-By: Minis Ultra <noreply@minis.app>
The fixture mixed a running tool with reply text in the same run, then asserted the card stays live — the opposite of the card contract the same file pins (reply text ends the card). The test only needs to prove the running tool lives in the card and not in the list twice. Co-Authored-By: Minis Ultra <noreply@minis.app>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
做了什么
AI 过程折叠从「一轮一条居中发丝线、保留最后两步」改成「一段过程一张描边卡片」。
测试
ChatFlatItemsProcessFoldTest、ChatFlatItemsToolOnlyFoldTest按新契约重写,并新增卡片三态文案测试。