@miphamai/cli 0.16.4 β 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/ui/app.tsx +11 -25
- package/src/ui/chat.tsx +55 -2
package/package.json
CHANGED
package/src/ui/app.tsx
CHANGED
|
@@ -353,18 +353,10 @@ export function App({
|
|
|
353
353
|
|
|
354
354
|
try {
|
|
355
355
|
for await (const chunk of engine.process(input, controller.signal)) {
|
|
356
|
-
//
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const last = updated[updated.length - 1]
|
|
361
|
-
if (last?.role === 'assistant' && last.content === '') {
|
|
362
|
-
last.content = 'π ζθδΈβ¦'
|
|
363
|
-
} else if (!last || last.role !== 'assistant' || last.content !== 'π ζθδΈβ¦') {
|
|
364
|
-
updated.push({ role: 'assistant', content: 'π ζθδΈβ¦' })
|
|
365
|
-
}
|
|
366
|
-
return updated
|
|
367
|
-
})
|
|
356
|
+
// Reasoning content (DeepSeek V4 thinking mode) β silently consumed,
|
|
357
|
+
// not shown to user to avoid noise.
|
|
358
|
+
if (chunk.reasoning_content) {
|
|
359
|
+
continue
|
|
368
360
|
}
|
|
369
361
|
|
|
370
362
|
if (chunk.type === 'text' && chunk.content) {
|
|
@@ -372,17 +364,10 @@ export function App({
|
|
|
372
364
|
if (isNewTurn) {
|
|
373
365
|
turnContent = chunk.content
|
|
374
366
|
isNewTurn = false
|
|
375
|
-
setMessages((prev) =>
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (last?.role === 'assistant' && last.content === 'π ζθδΈβ¦') {
|
|
380
|
-
last.content = turnContent
|
|
381
|
-
} else {
|
|
382
|
-
updated.push({ role: 'assistant', content: turnContent })
|
|
383
|
-
}
|
|
384
|
-
return updated
|
|
385
|
-
})
|
|
367
|
+
setMessages((prev) => [
|
|
368
|
+
...prev,
|
|
369
|
+
{ role: 'assistant', content: turnContent },
|
|
370
|
+
])
|
|
386
371
|
} else {
|
|
387
372
|
turnContent += chunk.content
|
|
388
373
|
setMessages((prev) => {
|
|
@@ -430,9 +415,10 @@ export function App({
|
|
|
430
415
|
setAgentProgress(null)
|
|
431
416
|
// Sync background agents (e.g. Agent tool may have spawned them)
|
|
432
417
|
syncBgAgents()
|
|
433
|
-
//
|
|
418
|
+
// Only show tool results with meaningful content.
|
|
419
|
+
// Skip empty results, "(no matches)", and other noise.
|
|
434
420
|
const output = chunk.content ? String(chunk.content).trim() : ''
|
|
435
|
-
if (output) {
|
|
421
|
+
if (output && output !== '(no matches)' && output.length > 20) {
|
|
436
422
|
const firstLine = output.split('\n')[0]!.slice(0, 200)
|
|
437
423
|
const preview = firstLine.length < output.length ? `${firstLine}...` : firstLine
|
|
438
424
|
setMessages((prev) => [
|
package/src/ui/chat.tsx
CHANGED
|
@@ -93,8 +93,11 @@ const MessageRow = React.memo(
|
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
export function ChatPanel({ messages, focusMode }: ChatPanelProps) {
|
|
96
|
-
//
|
|
97
|
-
|
|
96
|
+
// Group consecutive tool calls into compact summaries to reduce visual noise.
|
|
97
|
+
// In focus mode, use the more aggressive compactForFocus.
|
|
98
|
+
const displayMessages = focusMode
|
|
99
|
+
? compactForFocus(messages)
|
|
100
|
+
: compactToolGroups(messages)
|
|
98
101
|
|
|
99
102
|
return (
|
|
100
103
|
<Box flexDirection="column" marginY={1} flexGrow={1}>
|
|
@@ -141,6 +144,56 @@ export function ChatPanel({ messages, focusMode }: ChatPanelProps) {
|
|
|
141
144
|
)
|
|
142
145
|
}
|
|
143
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Group consecutive tool calls into compact one-liners for the normal view.
|
|
149
|
+
* Single tools show normally; 2+ consecutive tools get folded:
|
|
150
|
+
* βΊ Read Β· Glob Β· Bash (3 tools)
|
|
151
|
+
*/
|
|
152
|
+
function compactToolGroups(messages: ChatMessage[]): ChatMessage[] {
|
|
153
|
+
const result: ChatMessage[] = []
|
|
154
|
+
let toolGroup: ChatMessage[] = []
|
|
155
|
+
|
|
156
|
+
const flush = () => {
|
|
157
|
+
if (toolGroup.length === 0) return
|
|
158
|
+
if (toolGroup.length === 1) {
|
|
159
|
+
result.push(toolGroup[0]!)
|
|
160
|
+
} else {
|
|
161
|
+
const names = toolGroup
|
|
162
|
+
.filter((t) => t.toolMeta?.name && !t.toolMeta.name.startsWith('tools ('))
|
|
163
|
+
.map((t) => t.toolMeta!.name)
|
|
164
|
+
const uniqueNames = [...new Set(names)]
|
|
165
|
+
result.push({
|
|
166
|
+
role: 'system',
|
|
167
|
+
content: `βΊ ${uniqueNames.join(' Β· ')} (${names.length} tools)`,
|
|
168
|
+
toolMeta: {
|
|
169
|
+
name: `tools (${names.length})`,
|
|
170
|
+
input: uniqueNames.join(', '),
|
|
171
|
+
collapsed: true,
|
|
172
|
+
},
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
toolGroup = []
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
for (const msg of messages) {
|
|
179
|
+
// Tool results (no name, has output) get folded into the preceding tool group
|
|
180
|
+
if (msg.toolMeta && !msg.toolMeta.name && msg.toolMeta.output) {
|
|
181
|
+
toolGroup.push(msg)
|
|
182
|
+
continue
|
|
183
|
+
}
|
|
184
|
+
// Tool calls with a name
|
|
185
|
+
if (msg.toolMeta?.name && !msg.toolMeta.name.startsWith('tools (')) {
|
|
186
|
+
toolGroup.push(msg)
|
|
187
|
+
continue
|
|
188
|
+
}
|
|
189
|
+
// Already-grouped or non-tool message
|
|
190
|
+
flush()
|
|
191
|
+
result.push(msg)
|
|
192
|
+
}
|
|
193
|
+
flush()
|
|
194
|
+
return result
|
|
195
|
+
}
|
|
196
|
+
|
|
144
197
|
/**
|
|
145
198
|
* Compact messages for focus view:
|
|
146
199
|
* - Groups consecutive tool calls into [βΆ N tools] β³ name1 β³ name2 summary lines
|