Show running tool glow at full strength when a transcript opens
This commit is contained in:
@@ -66,6 +66,8 @@ final class ChatModel {
|
|||||||
@ObservationIgnored private var activeObserver: NotificationCenter.ObservationToken?
|
@ObservationIgnored private var activeObserver: NotificationCenter.ObservationToken?
|
||||||
@ObservationIgnored private var keyObserver: NotificationCenter.ObservationToken?
|
@ObservationIgnored private var keyObserver: NotificationCenter.ObservationToken?
|
||||||
@ObservationIgnored private var started = false
|
@ObservationIgnored private var started = false
|
||||||
|
@ObservationIgnored private var opened = 0
|
||||||
|
@ObservationIgnored private var settled = false
|
||||||
@ObservationIgnored private var cursors: [String: Int] = [:]
|
@ObservationIgnored private var cursors: [String: Int] = [:]
|
||||||
|
|
||||||
init(_ kind: ChatKind, _ store: Store) {
|
init(_ kind: ChatKind, _ store: Store) {
|
||||||
@@ -185,6 +187,10 @@ final class ChatModel {
|
|||||||
row.pending && (running || subagents && row.inActive || row.inReview) || row.holdsActive && (running || subagents)
|
row.pending && (running || subagents && row.inActive || row.inReview) || row.holdsActive && (running || subagents)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fades(_ row: Row) -> Bool {
|
||||||
|
row.firstId > opened
|
||||||
|
}
|
||||||
|
|
||||||
var hasOlder: Bool {
|
var hasOlder: Bool {
|
||||||
kind == .lead && store.leadHasOlder()
|
kind == .lead && store.leadHasOlder()
|
||||||
}
|
}
|
||||||
@@ -246,6 +252,10 @@ final class ChatModel {
|
|||||||
|
|
||||||
private func appended(_ all: [ByreEvent]) {
|
private func appended(_ all: [ByreEvent]) {
|
||||||
_ = builder.append(all.filter(shows))
|
_ = builder.append(all.filter(shows))
|
||||||
|
if !settled {
|
||||||
|
opened = Row.newest
|
||||||
|
settled = feed?.ready == true
|
||||||
|
}
|
||||||
jump()
|
jump()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1117,6 +1127,7 @@ struct DetailsBox<Summary: View, Content: View>: View {
|
|||||||
var boxed = true
|
var boxed = true
|
||||||
var nested = false
|
var nested = false
|
||||||
var working = false
|
var working = false
|
||||||
|
var fade = false
|
||||||
var status: (text: String, color: Color)? = nil
|
var status: (text: String, color: Color)? = nil
|
||||||
@ViewBuilder let summary: Summary
|
@ViewBuilder let summary: Summary
|
||||||
@ViewBuilder let content: Content
|
@ViewBuilder let content: Content
|
||||||
@@ -1153,8 +1164,9 @@ struct DetailsBox<Summary: View, Content: View>: View {
|
|||||||
.background(boxed ? (nested ? Palette.raised : Palette.surface) : .clear, in: RoundedRectangle(cornerRadius: 8))
|
.background(boxed ? (nested ? Palette.raised : Palette.surface) : .clear, in: RoundedRectangle(cornerRadius: 8))
|
||||||
.overlay {
|
.overlay {
|
||||||
if boxed {
|
if boxed {
|
||||||
RoundedRectangle(cornerRadius: 8).stroke(working && shown ? accent : Palette.border)
|
let lit = working && (shown || !fade)
|
||||||
.animation(.easeInOut(duration: 0.6), value: working && shown)
|
RoundedRectangle(cornerRadius: 8).stroke(lit ? accent : Palette.border)
|
||||||
|
.animation(.easeInOut(duration: 0.6), value: lit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
@@ -1276,7 +1288,7 @@ struct RowView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case .tool(let name, let brief, let input):
|
case .tool(let name, let brief, let input):
|
||||||
DetailsBox(nested: nested, working: model.working(row)) {
|
DetailsBox(nested: nested, working: model.working(row), fade: model.fades(row)) {
|
||||||
SubagentTag(show: row.tag)
|
SubagentTag(show: row.tag)
|
||||||
Text(styled([(name, 600, nil), (" ", 400, nil), (brief, 400, Palette.muted)]))
|
Text(styled([(name, 600, nil), (" ", 400, nil), (brief, 400, Palette.muted)]))
|
||||||
} content: {
|
} content: {
|
||||||
@@ -1288,7 +1300,7 @@ struct RowView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case .subagent(let title, let description, let prompt):
|
case .subagent(let title, let description, let prompt):
|
||||||
DetailsBox(nested: nested, working: model.working(row), status: (row.status, row.statusState == .done ? Palette.muted : row.statusState == .error ? Palette.danger : Palette.accent)) {
|
DetailsBox(nested: nested, working: model.working(row), fade: model.fades(row), status: (row.status, row.statusState == .done ? Palette.muted : row.statusState == .error ? Palette.danger : Palette.accent)) {
|
||||||
SubagentTag(show: row.tag)
|
SubagentTag(show: row.tag)
|
||||||
Text(styled([(title, 600, nil), (" ", 400, nil), (description, 400, Palette.muted)]))
|
Text(styled([(title, 600, nil), (" ", 400, nil), (description, 400, Palette.muted)]))
|
||||||
} content: {
|
} content: {
|
||||||
@@ -1303,7 +1315,7 @@ struct RowView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case .reviewer(let agentModel):
|
case .reviewer(let agentModel):
|
||||||
DetailsBox(nested: nested, working: row.active, status: (row.status, row.statusState == .done ? Palette.muted : row.statusState == .error ? Palette.danger : Palette.accent)) {
|
DetailsBox(nested: nested, working: row.active, fade: model.fades(row), status: (row.status, row.statusState == .done ? Palette.muted : row.statusState == .error ? Palette.danger : Palette.accent)) {
|
||||||
Text(styled([(row.review?.stage ?? "review", 600, nil), (agentModel.isEmpty ? "" : " · \(agentModel)", 400, Palette.muted), (row.text.isEmpty ? "" : " \(row.text)", 400, Palette.muted)]))
|
Text(styled([(row.review?.stage ?? "review", 600, nil), (agentModel.isEmpty ? "" : " · \(agentModel)", 400, Palette.muted), (row.text.isEmpty ? "" : " \(row.text)", 400, Palette.muted)]))
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
} content: {
|
} content: {
|
||||||
@@ -1317,7 +1329,7 @@ struct RowView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case .group:
|
case .group:
|
||||||
DetailsBox(nested: nested, working: model.working(row)) {
|
DetailsBox(nested: nested, working: model.working(row), fade: model.fades(row)) {
|
||||||
SubagentTag(show: row.tag)
|
SubagentTag(show: row.tag)
|
||||||
RunSummary(calls: row.calls)
|
RunSummary(calls: row.calls)
|
||||||
} content: {
|
} content: {
|
||||||
|
|||||||
@@ -145,6 +145,17 @@ final class Row: Identifiable {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var newest: Int {
|
||||||
|
rowIds
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstId: Int {
|
||||||
|
if case .group = kind {
|
||||||
|
return body!.rows.first?.id ?? id
|
||||||
|
}
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
init(_ kind: RowKind, taskId: String?, body: Bool = false) {
|
init(_ kind: RowKind, taskId: String?, body: Bool = false) {
|
||||||
rowIds += 1
|
rowIds += 1
|
||||||
id = rowIds
|
id = rowIds
|
||||||
|
|||||||
Reference in New Issue
Block a user