Cut transcript noise: fold grey boxes, drop duplicate review rows

This commit is contained in:
Ian Gulliver
2026-10-20 13:04:17 -07:00
parent 0f33ad4524
commit a7b2333535
14 changed files with 312 additions and 290 deletions
+1 -1
View File
@@ -146,7 +146,7 @@ final class ChatModel {
}
func working(_ row: Row) -> Bool {
row.pending && (running || subagents && row.inActive) || row.active && (running || subagents)
row.pending && (running || subagents && row.inActive) || row.holdsActive && (running || subagents)
}
var hasOlder: Bool {
+13 -22
View File
@@ -300,19 +300,27 @@ private struct CardBody: View {
var body: some View {
let p = model.payload
let item = model.item
let split = model.context.firstIndex(where: choiceList) ?? model.context.count
VStack(alignment: .leading, spacing: 0) {
MarkdownView(blocks: model.context, ctx: contextCtx)
.onGeometryChange(for: Bool.self) { $0.size.width > 480 } action: { wide = $0 }
.padding(.vertical, 10)
MarkdownView(blocks: Array(model.context[..<split]), ctx: contextCtx)
.padding(.top, 10)
if question {
MarkdownView(blocks: parseMarkdown(jsString(p["question"] ?? "")), ctx: MDContext(taskId: item.taskId))
.padding(.top, 10)
.padding(.bottom, 4)
}
WhyLine(text: jsString(p["why_blocked"] ?? ""), taskId: item.taskId)
MarkdownView(blocks: Array(model.context[split...]), ctx: contextCtx)
.padding(.top, 10)
.padding(.bottom, 8)
Attachments(list: attachments(p["attachments"] ?? nil), taskId: item.taskId)
}
.onGeometryChange(for: Bool.self) { $0.size.width > 480 } action: { wide = $0 }
}
private func choiceList(_ block: MDBlock) -> Bool {
if case .list(_, _, let items, _) = block {
return items.contains { $0.choice != nil }
}
return false
}
private func attachments(_ v: (any Sendable)?) -> [Attachment] {
@@ -328,23 +336,6 @@ private struct CardBody: View {
}
}
private struct WhyLine: View {
let text: String
let taskId: String
@Environment(Store.self) private var store
var body: some View {
var out = AttributedString("Blocked on: ")
out.foregroundColor = Palette.text
var rest = InlineRenderer(store: store, size: 13, taskId: taskId).text(parseInline(text))
rest.foregroundColor = rest.foregroundColor ?? Palette.muted
return Text(out + rest)
.foregroundStyle(Palette.muted)
.textSelection(.enabled)
.fixedSize(horizontal: false, vertical: true)
}
}
private struct ChoiceBox: View {
let model: CardModel
let item: MDItem
+42 -15
View File
@@ -105,6 +105,13 @@ final class Row: Identifiable {
}
}
var holdsActive: Bool {
if case .group = kind {
return body!.rows.contains { $0.active }
}
return active
}
var inActive: Bool {
var o = owner
while let r = o {
@@ -300,7 +307,7 @@ final class TranscriptBuilder {
!parent.isEmpty && ctx.subagents[parent] == nil
}
private func addToRun(_ row: Row, _ call: Call, _ parent: String) {
private func addToRun(_ row: Row, _ call: Call?, _ parent: String) {
if let sub = ctx.subagents[parent] {
sub.run = extendRun(sub.run, row, call, parent) { r in
sub.row.body!.rows.append(r)
@@ -313,12 +320,14 @@ final class TranscriptBuilder {
}
}
private func extendRun(_ run: Run?, _ row: Row, _ call: Call, _ parent: String, _ place: (Row) -> RowList) -> Run {
private func extendRun(_ run: Run?, _ row: Row, _ call: Call?, _ parent: String, _ place: (Row) -> RowList) -> Run {
guard let run, run.parent == parent else {
let list = place(row)
return Run(first: row, container: list, calls: [call], parent: parent)
return Run(first: row, container: list, calls: call.map { [$0] } ?? [], parent: parent)
}
if let call {
run.calls.append(call)
}
run.calls.append(call)
if run.group == nil {
let group = Row(.group, taskId: rowTask, body: true)
group.owner = ctx.subagents[parent]?.row
@@ -383,6 +392,7 @@ final class TranscriptBuilder {
private func openHandoff() {
let row = Row(.handoff, taskId: rowTask, body: true)
row.summary = Note(parts: [.text("writing a handoff…")])
ctx.run = nil
put(row)
ctx.handoff = row
}
@@ -497,8 +507,11 @@ final class TranscriptBuilder {
row.review = r
}
if ev.kind == "review.finished" {
ctx.run = nil
for row in renderReview(r, ev.createdAt) {
let rows = renderReview(r, ev.createdAt)
if !rows.isEmpty {
ctx.run = nil
}
for row in rows {
put(row)
}
continue
@@ -518,8 +531,7 @@ final class TranscriptBuilder {
sub.row.body!.rows.append(row)
continue
}
ctx.run = nil
put(row, keepHeld: true)
addToRun(row, Call(name: jsString(p["name"]), target: ""), parent)
continue
}
if ev.kind == "agent.tool_call" && sub == nil && str(p, "name") == "mcp__byre__respond_to_finding" {
@@ -540,6 +552,9 @@ final class TranscriptBuilder {
let name = toolLabel(jsString(p["name"]))
let row = renderToolCall(p)
row.started = ev.createdAt
if name == "ToolSearch" {
continue
}
addToRun(row, Call(name: name, target: toolTarget(p["input"] ?? nil, worktree())), parent)
continue
}
@@ -551,7 +566,11 @@ final class TranscriptBuilder {
sub.row.body!.rows.append(row)
continue
}
ctx.run = nil
let prompt = if case .byrePrompt = row.kind { true } else { false }
let agentNote = if case .note = row.kind, ev.actor == "agent" { true } else { false }
if !prompt && !agentNote {
ctx.run = nil
}
if ev.kind == "agent.message" && parent.isEmpty {
ctx.drawn = nil
ctx.reply = row
@@ -577,6 +596,7 @@ final class TranscriptBuilder {
ctx.drawn = nil
}
if ev.kind == "user.message" && ev.actor == "byre" && !(ev.owner ?? "").isEmpty && !bool(p, "mid_turn") && !bool(p, "handoff") {
ctx.run = nil
ctx.held = RowList()
ctx.open = false
ctx.drawn = []
@@ -597,6 +617,11 @@ final class TranscriptBuilder {
if (ev.kind == "inbox.created" || ev.kind == "task.ready_cleared") && sink == nil && own {
lastReady = nil
}
if prompt && !row.hidden || agentNote {
release()
addToRun(row, agentNote ? nil : Call(name: "byre", target: ""), parent)
continue
}
put(row, keepHeld: ev.kind == "agent.thinking")
}
return contextChanged
@@ -659,9 +684,12 @@ final class TranscriptBuilder {
}
private func renderReview(_ r: Review, _ when: Date) -> [Row] {
let outcome = r.state == .failed ? "failed: \(r.error)" : r.state == .skipped ? "skipped: no changes" : reviewCounts(r)
let parts: [NotePart] = [.text("review of snapshot #\(r.snapshotN): \(outcome)")]
let fs = findings(r)
if fs.isEmpty && r.state != .failed {
return []
}
let outcome = r.state == .failed ? "failed: \(r.error)" : reviewCounts(r)
let parts: [NotePart] = [.text("review of snapshot #\(r.snapshotN): \(outcome)")]
let head = fs.isEmpty
? Row(.note(Note(parts: parts, when: when, style: r.state == .failed ? .error : .plain)), taskId: rowTask)
: Row(.review(note: Note(parts: parts, when: when), md: parseMarkdown(str(r.result?.value ?? [:], "summary") ?? "")), taskId: rowTask)
@@ -692,7 +720,7 @@ final class TranscriptBuilder {
let first = text.components(separatedBy: "\n").first ?? ""
let brief = first.count > 120 ? "\(first.prefix(120))…" : first
let row = Row(.byrePrompt(brief: brief, when: when, md: parseMarkdown(text)), taskId: rowTask)
row.hidden = bool(p, "continuation")
row.hidden = bool(p, "continuation") || bool(p, "findings")
return row
}
let images = (p["images"] as? [(any Sendable)?] ?? []).map { jsString($0) }
@@ -886,11 +914,10 @@ private func isSubagentCall(_ p: JSONDict) -> Bool {
}
func toolLabel(_ name: String) -> String {
let prefix = "mcp__byre__"
if !name.hasPrefix(prefix) {
guard name.hasPrefix("mcp__"), let sep = name.dropFirst(5).range(of: "__") else {
return name
}
return name.dropFirst(prefix.count).split(separator: "_", omittingEmptySubsequences: false).map { $0.prefix(1).uppercased() + $0.dropFirst() }.joined(separator: " ")
return name[sep.upperBound...].split(separator: "_", omittingEmptySubsequences: false).map { $0.prefix(1).uppercased() + $0.dropFirst() }.joined(separator: " ")
}
private func toolBrief(_ input: (any Sendable)?, _ root: String) -> String {