Collapse tool-call chat rows into a single live status line
Each round of a multi-tool-call chain used to append a new "Calling: X"
message, so a long tool chain stacked up a growing list of rows in the
transcript. Replaced with a transient status line under the thinking
indicator that updates in place each round; once the response
completes, the whole chain collapses into one expandable summary
message ("Used N tool calls") instead of N separate ones.
This commit is contained in:
@@ -53,7 +53,7 @@ struct ChatView: View {
|
||||
|
||||
// Processing indicator
|
||||
if viewModel.isGenerating && viewModel.messages.last?.isStreaming != true {
|
||||
ProcessingIndicator()
|
||||
ProcessingIndicator(toolActivity: viewModel.currentToolActivity)
|
||||
.padding(.horizontal)
|
||||
}
|
||||
|
||||
@@ -156,30 +156,43 @@ struct ChatView: View {
|
||||
}
|
||||
|
||||
struct ProcessingIndicator: View {
|
||||
/// Current tool round's status (e.g. "🔧 Calling: read_file"), replaced in place each round
|
||||
/// rather than the chat accumulating a new row per round — see ChatViewModel.currentToolActivity.
|
||||
let toolActivity: String?
|
||||
@State private var animating = false
|
||||
@State private var thinkingText = ThinkingVerbs.random()
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 8) {
|
||||
Text(thinkingText)
|
||||
.font(.system(size: 14, weight: .medium))
|
||||
.foregroundColor(.confabSecondary)
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(spacing: 8) {
|
||||
Text(thinkingText)
|
||||
.font(.system(size: 14, weight: .medium))
|
||||
.foregroundColor(.confabSecondary)
|
||||
|
||||
HStack(spacing: 4) {
|
||||
ForEach(0..<3) { index in
|
||||
Circle()
|
||||
.fill(Color.confabSecondary)
|
||||
.frame(width: 6, height: 6)
|
||||
.scaleEffect(animating ? 1.0 : 0.5)
|
||||
.animation(
|
||||
.easeInOut(duration: 0.6)
|
||||
.repeatForever()
|
||||
.delay(Double(index) * 0.2),
|
||||
value: animating
|
||||
)
|
||||
HStack(spacing: 4) {
|
||||
ForEach(0..<3) { index in
|
||||
Circle()
|
||||
.fill(Color.confabSecondary)
|
||||
.frame(width: 6, height: 6)
|
||||
.scaleEffect(animating ? 1.0 : 0.5)
|
||||
.animation(
|
||||
.easeInOut(duration: 0.6)
|
||||
.repeatForever()
|
||||
.delay(Double(index) * 0.2),
|
||||
value: animating
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let toolActivity {
|
||||
Text(toolActivity)
|
||||
.font(.system(size: 12))
|
||||
.foregroundColor(.confabSecondary.opacity(0.75))
|
||||
.transition(.opacity)
|
||||
}
|
||||
}
|
||||
.animation(.easeInOut(duration: 0.15), value: toolActivity)
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.vertical, 12)
|
||||
.background(Color.confabSecondary.opacity(0.05))
|
||||
|
||||
Reference in New Issue
Block a user