diff --git a/webclient/src/components/messages/AssistantMessage.vue b/webclient/src/components/messages/AssistantMessage.vue index 2d3c89c..ab02c3c 100644 --- a/webclient/src/components/messages/AssistantMessage.vue +++ b/webclient/src/components/messages/AssistantMessage.vue @@ -10,24 +10,34 @@ /> - + +
+
+ {{ entry.total }} tools + +
+ + +
+ + + Plan + + +
+
+ +
+
renderMarkdown(props.msg.text)) const tsRef = computed(() => props.msg.done ? props.msg.time : null) @@ -183,6 +195,38 @@ return tool.name } +function isCountableTool(item) { + return item.kind === 'tool' && item.name !== 'content_publish' +} + +const displayItems = computed(() => { + const items = props.msg.tools || [] + const toolOnly = items + .map((item, i) => ({ item, i })) + .filter(({ item }) => isCountableTool(item)) + + if (toolOnly.length === 0 || toolOnly.length < 4) { + return items.map((item, i) => ({ type: 'item', item, i, key: i })) + } + + const showAll = showAllTools.value + const visibleSet = new Set( + showAll + ? toolOnly.map(({ i }) => i) + : toolOnly.slice(-3).map(({ i }) => i) + ) + + const result = [] + for (let i = 0; i < items.length; i++) { + const item = items[i] + if (isCountableTool(item) && !visibleSet.has(i)) continue + result.push({ type: 'item', item, i, key: i }) + } + + result.push({ type: 'summary', total: toolOnly.length, key: 'summary-end' }) + return result +}) + // Attach copy buttons after render — only when message is done to avoid // repeated DOM queries on every streaming delta. watch( diff --git a/webclient/src/components/messages/SubagentStep.vue b/webclient/src/components/messages/SubagentStep.vue index 0ee2138..20a3761 100644 --- a/webclient/src/components/messages/SubagentStep.vue +++ b/webclient/src/components/messages/SubagentStep.vue @@ -1,12 +1,11 @@