Skip to content

Commit 094e880

Browse files
committed
feat(ui): show dynamic output summary in tool call bubble
Display tool output in the timeline bubble header, truncating with ellipsis and falling back to params if output is unavailable. UI now handles overflow without fixed truncation.
1 parent b149c51 commit 094e880

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/components/timeline/IdeaToolCallBubble.kt

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ import androidx.compose.foundation.shape.RoundedCornerShape
1313
import androidx.compose.runtime.*
1414
import androidx.compose.ui.Alignment
1515
import androidx.compose.ui.Modifier
16+
import androidx.compose.ui.draw.clipToBounds
1617
import androidx.compose.ui.text.font.FontFamily
1718
import androidx.compose.ui.text.font.FontWeight
19+
import androidx.compose.ui.text.style.TextOverflow
1820
import androidx.compose.ui.unit.dp
1921
import androidx.compose.ui.unit.sp
2022
import cc.unitmesh.agent.render.TimelineItem
@@ -68,7 +70,7 @@ fun IdeaToolCallBubble(
6870
.padding(8.dp)
6971
) {
7072
Column {
71-
// Header row: Status + Tool name + Summary + Expand icon
73+
// Header row: Status + Tool name + Output (dynamic) + Time + Expand icon
7274
Row(
7375
modifier = Modifier
7476
.fillMaxWidth()
@@ -99,17 +101,17 @@ fun IdeaToolCallBubble(
99101
}
100102
)
101103

102-
// Tool name
104+
// Tool name (fixed width, no shrink)
103105
Text(
104106
text = item.toolName,
105107
style = JewelTheme.defaultTextStyle.copy(fontWeight = FontWeight.Bold),
106-
modifier = Modifier.weight(1f)
108+
maxLines = 1
107109
)
108110

109-
// Summary (truncated params as summary)
110-
if (hasParams && !expanded) {
111+
// Output summary (dynamic width, fills remaining space)
112+
if (hasOutput && !expanded) {
111113
Text(
112-
text = "-> ${item.params.take(40)}${if (item.params.length > 40) "..." else ""}",
114+
text = "-> ${item.output?.replace("\n", " ")?.trim() ?: ""}",
113115
style = JewelTheme.defaultTextStyle.copy(
114116
fontSize = 12.sp,
115117
color = when {
@@ -118,8 +120,32 @@ fun IdeaToolCallBubble(
118120
else -> JewelTheme.globalColors.text.info
119121
}
120122
),
121-
maxLines = 1
123+
maxLines = 1,
124+
overflow = TextOverflow.Ellipsis,
125+
modifier = Modifier
126+
.weight(1f)
127+
.clipToBounds()
122128
)
129+
} else if (!expanded) {
130+
// Show params as fallback when no output
131+
if (hasParams) {
132+
Text(
133+
text = "-> ${item.params.replace("\n", " ").trim()}",
134+
style = JewelTheme.defaultTextStyle.copy(
135+
fontSize = 12.sp,
136+
color = JewelTheme.globalColors.text.info
137+
),
138+
maxLines = 1,
139+
overflow = TextOverflow.Ellipsis,
140+
modifier = Modifier
141+
.weight(1f)
142+
.clipToBounds()
143+
)
144+
} else {
145+
Spacer(modifier = Modifier.weight(1f))
146+
}
147+
} else {
148+
Spacer(modifier = Modifier.weight(1f))
123149
}
124150

125151
// Execution time (if available)
@@ -376,14 +402,8 @@ private fun copyToClipboard(text: String) {
376402

377403
/**
378404
* Format tool output for better readability.
379-
* Returns output as-is to avoid breaking valid JSON/table formats.
405+
* Returns output as-is to preserve valid JSON/table formats.
406+
* No fixed truncation - UI handles overflow dynamically.
380407
*/
381-
private fun formatToolOutput(output: String): String {
382-
return when {
383-
output.contains("|") -> output // Table format
384-
output.contains("\n") -> output // Already formatted
385-
output.length > 100 -> "${output.take(100)}..." // Truncate long single-line output
386-
else -> output
387-
}
388-
}
408+
private fun formatToolOutput(output: String): String = output
389409

0 commit comments

Comments
 (0)