fix(ui): stop repeating tool names in expanded activity (#100606)

* fix(ui): stop repeating tool names in expanded activity

* fix(ui): stop repeating tool names in expanded activity
This commit is contained in:
Peter Steinberger
2026-07-06 07:17:23 +01:00
committed by GitHub
parent 2559c92a25
commit 98ca8c945e
5 changed files with 71 additions and 70 deletions
@@ -1532,6 +1532,9 @@ describe("grouped chat rendering", () => {
});
expect(container.querySelector(".chat-tool-msg-summary__label")?.textContent?.trim()).toBe(
"presentation_create",
);
expect(container.querySelector(".chat-tool-msg-summary__names")?.textContent?.trim()).toBe(
"Example Deck",
);
expect(container.querySelector(".chat-tool-msg-summary")?.textContent).not.toContain(
@@ -1542,6 +1545,9 @@ describe("grouped chat rendering", () => {
isToolMessageExpanded: () => true,
});
expect(container.querySelector(".chat-tool-msg-body")?.textContent).not.toContain(
"presentation_create",
);
expect(container.querySelector(".chat-tool-card__block code")?.textContent).toBe(
"with Example Deck",
);
+8 -8
View File
@@ -1977,20 +1977,20 @@ function renderGroupedMessage(
? toolNames.join(", ")
: `${toolNames.slice(0, 2).join(", ")} +${toolNames.length - 2} more`
: singleToolDisplayDetail
? singleToolCard?.outputText?.trim()
? "output"
: undefined
? !markdown && !hasImages
? singleToolDisplayDetail
: singleToolCard?.outputText?.trim()
? "output"
: undefined
: toolNames.length <= 3
? toolNames.join(", ")
: `${toolNames.slice(0, 2).join(", ")} +${toolNames.length - 2} more`;
const toolPreview = markdown ? (formatCollapsedToolPreviewText(markdown) ?? "") : "";
const toolMessageLabelRaw = toolMessageHasError
? "Tool error"
: singleToolDisplayDetail && !markdown && !hasImages
? singleToolDisplayDetail
: singleToolDisplay && !markdown && !hasImages
? singleToolDisplay.label
: "Tool output";
: singleToolDisplay && !markdown && !hasImages
? singleToolDisplay.label
: "Tool output";
const toolMessageLabel =
formatCollapsedToolSummaryText(toolMessageLabelRaw) ?? toolMessageLabelRaw;
const toolSummaryLabel = formatDistinctCollapsedToolSummaryText(
@@ -121,6 +121,36 @@ describe("tool-cards", () => {
]);
});
it("does not repeat the tool identity in expanded details", () => {
const container = document.createElement("div");
render(
renderToolCard(
{
id: "msg:4a:call-4a",
name: "skill_workshop",
args: { action: "create" },
inputText: '{\n "action": "create"\n}',
outputText: "Proposal created",
},
{
expanded: true,
onOpenSidebar: vi.fn(),
onToggleExpanded: vi.fn(),
},
),
container,
);
expect(container.textContent?.match(/Skill Workshop/g)).toHaveLength(1);
expect(container.querySelector(".chat-tool-msg-body")?.textContent).not.toContain(
"Skill Workshop",
);
expect(container.querySelector(".chat-tool-card__detail")?.textContent).toContain("create");
expect(container.querySelector(".chat-tool-card__action-btn")).toBeInstanceOf(
HTMLButtonElement,
);
});
it("renders expanded tool calls without an inline output block when no output is present", () => {
const container = document.createElement("div");
render(
+23 -23
View File
@@ -423,29 +423,29 @@ export function renderExpandedToolCardContent(
return html`
<div class="chat-tool-card ${isError ? "chat-tool-card--error" : ""}">
<div class="chat-tool-card__header">
<div class="chat-tool-card__title">
<span class="chat-tool-card__icon">${renderToolIcon(display.icon)}</span>
<span>${display.label}</span>
</div>
${canOpenSidebar
? html`
<div class="chat-tool-card__actions">
<openclaw-tooltip content="Open in the side panel">
<button
class="chat-tool-card__action-btn"
type="button"
@click=${() => onOpenSidebar?.(sidebarActionContent)}
aria-label="Open tool details in side panel"
>
<span class="chat-tool-card__action-icon">${icons.panelRightOpen}</span>
</button>
</openclaw-tooltip>
</div>
`
: nothing}
</div>
${detail ? html`<div class="chat-tool-card__detail">${detail}</div>` : nothing}
${detail || canOpenSidebar
? html`
<div class="chat-tool-card__header">
${detail ? html`<div class="chat-tool-card__detail">${detail}</div>` : nothing}
${canOpenSidebar
? html`
<div class="chat-tool-card__actions">
<openclaw-tooltip content="Open in the side panel">
<button
class="chat-tool-card__action-btn"
type="button"
@click=${() => onOpenSidebar?.(sidebarActionContent)}
aria-label="Open tool details in side panel"
>
<span class="chat-tool-card__action-icon">${icons.panelRightOpen}</span>
</button>
</openclaw-tooltip>
</div>
`
: nothing}
</div>
`
: nothing}
${hasInput
? renderToolDataBlock({
label: "Tool input",
+4 -39
View File
@@ -151,49 +151,17 @@
.chat-tool-card__header {
display: flex;
justify-content: space-between;
align-items: center;
align-items: flex-start;
gap: 10px;
min-width: 0;
}
.chat-tool-card__title {
display: inline-flex;
align-items: center;
gap: 6px;
flex: 1 1 auto;
font-weight: 600;
font-size: var(--control-ui-text-sm);
line-height: 1.2;
min-width: 0;
max-width: 100%;
overflow-wrap: anywhere;
}
.chat-tool-card__icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
color: var(--muted);
flex-shrink: 0;
}
.chat-tool-card__icon svg {
width: 14px;
height: 14px;
stroke: currentColor;
fill: none;
stroke-width: 1.5px;
stroke-linecap: round;
stroke-linejoin: round;
}
.chat-tool-card__actions {
display: inline-flex;
align-items: center;
gap: 6px;
justify-content: flex-end;
margin-left: auto;
}
.chat-tool-card__action-btn {
@@ -236,14 +204,11 @@
stroke-linejoin: round;
}
.chat-tool-card--error .chat-tool-card__icon {
color: var(--destructive, var(--danger, #c0392b));
}
.chat-tool-card__detail {
flex: 1 1 auto;
min-width: 0;
font-size: var(--control-ui-text-sm);
color: var(--muted);
margin-top: 4px;
}
.chat-tool-card__block {