Merge nucleic/gentle-breezy-egret into dev
This commit is contained in:
@@ -42,15 +42,27 @@ struct TranscriptItem: Identifiable, Equatable {
|
||||
}
|
||||
|
||||
/// A row that draws nothing visible — an empty/redacted `.thinking` block (the agent streams
|
||||
/// a finalized empty thinking item whenever the reasoning itself is redacted). Held aside
|
||||
/// during tool-run coalescing so it doesn't split an otherwise-contiguous run of calls into
|
||||
/// two cards with a gap. Mirrors the desktop projection's `rendersNothing`.
|
||||
var rendersNothing: Bool {
|
||||
/// a finalized empty thinking item whenever the reasoning itself is redacted). `ThinkingRow`
|
||||
/// renders no content for it, so `flatItems` drops it outright rather than carrying a phantom
|
||||
/// row into the transcript.
|
||||
///
|
||||
/// It has to be dropped, not merely rendered as an empty view: the transcript is a
|
||||
/// `VStack(spacing: 14)` over `TranscriptRow`s, and a row whose body resolves to nothing is
|
||||
/// still a *child* of that stack — SwiftUI can't elide an opaque `View` struct the way it
|
||||
/// elides a literal `EmptyView`, so it still claims its 14pt inter-row gap. A long tool run
|
||||
/// interleaved with redacted thinking (one empty block per call) held them all aside and
|
||||
/// re-emitted them after the block, stacking one gap each into a large band of blank space
|
||||
/// between the card and the next row. Mirrors the desktop projection's `isEmptyThinking`.
|
||||
var isEmptyThinking: Bool {
|
||||
if case .thinking(let text) = kind {
|
||||
return text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/// Items that draw no visible row. They must not break a run of tool calls when coalescing:
|
||||
/// an invisible row sitting between two calls would otherwise split them into two cards.
|
||||
var rendersNothing: Bool { isEmptyThinking }
|
||||
}
|
||||
|
||||
/// One tool call's coalesced lifecycle: start → input deltas → complete → result → file changes.
|
||||
@@ -409,10 +421,13 @@ enum TranscriptProjection {
|
||||
|
||||
/// Collapses maximal runs of adjacent `.tool` items (length ≥2) into one `.toolBlock`.
|
||||
///
|
||||
/// Items that draw nothing (empty `.thinking` blocks — see `rendersNothing`) never break a
|
||||
/// run: an invisible row landing between two tool calls must not split them into two cards
|
||||
/// with a gap. Such items are held aside and re-emitted right after the block, so they still
|
||||
/// render in place while the calls stay one contiguous block. Mirrors the desktop projection.
|
||||
/// Items that draw nothing (see `rendersNothing`) never break a run: an invisible row landing
|
||||
/// between two tool calls must not split them into two cards with a gap. Such items are held
|
||||
/// aside and re-emitted right after the block, so the calls stay one contiguous block.
|
||||
/// Mirrors the desktop projection.
|
||||
///
|
||||
/// `flatItems` already drops the only kind the phone has (empty redacted thinking), so the
|
||||
/// hold path is a guard for a caller passing unfiltered items — not a live case.
|
||||
static func coalesceToolRuns(_ flat: [TranscriptItem]) -> [TranscriptItem] {
|
||||
var out: [TranscriptItem] = []
|
||||
var run: [TranscriptItem] = [] // consecutive `.tool` items
|
||||
@@ -510,7 +525,12 @@ enum TranscriptProjection {
|
||||
kind: .raw(type: event.nativeType ?? "raw", body: raw.native.compactSummary)))
|
||||
}
|
||||
}
|
||||
return items
|
||||
// A redacted (empty) thinking block draws no row but would still cost one inter-row gap
|
||||
// in the transcript's spaced VStack — see `isEmptyThinking`. Drop it here, after the
|
||||
// coalescing upserts, so a *streaming* thinking item is judged on its accumulated text
|
||||
// rather than on the empty first delta. A thinking message never straddles a segment
|
||||
// seam (`buildSegment`'s precondition), so this stays fold-equivalent per segment.
|
||||
return items.filter { !$0.isEmptyThinking }
|
||||
}
|
||||
|
||||
// MARK: - Coalescing helpers
|
||||
|
||||
Reference in New Issue
Block a user