fix: unify claude cli imported tool messages

This commit is contained in:
Peter Steinberger
2026-03-26 22:01:27 +00:00
parent 3d0050c306
commit 672a24cbde
6 changed files with 249 additions and 11 deletions

View File

@@ -112,6 +112,15 @@ describe("message-normalizer", () => {
expect(result.content[0].args).toEqual({ foo: "bar" });
});
it("handles input field for anthropic tool_use blocks", () => {
const result = normalizeMessage({
role: "assistant",
content: [{ type: "tool_use", name: "Bash", input: { command: "pwd" } }],
});
expect(result.content[0].args).toEqual({ command: "pwd" });
});
it("preserves top-level sender labels", () => {
const result = normalizeMessage({
role: "user",

View File

@@ -42,7 +42,7 @@ export function normalizeMessage(message: unknown): NormalizedMessage {
type: (item.type as MessageContentItem["type"]) || "text",
text: item.text as string | undefined,
name: item.name as string | undefined,
args: item.args || item.arguments,
args: item.args || item.arguments || item.input,
}));
} else if (typeof m.text === "string") {
content = [{ type: "text", text: m.text }];

View File

@@ -16,12 +16,13 @@ export function extractToolCards(message: unknown): ToolCard[] {
const kind = (typeof item.type === "string" ? item.type : "").toLowerCase();
const isToolCall =
["toolcall", "tool_call", "tooluse", "tool_use"].includes(kind) ||
(typeof item.name === "string" && item.arguments != null);
(typeof item.name === "string" &&
(item.arguments != null || item.args != null || item.input != null));
if (isToolCall) {
cards.push({
kind: "call",
name: (item.name as string) ?? "tool",
args: coerceArgs(item.arguments ?? item.args),
args: coerceArgs(item.arguments ?? item.args ?? item.input),
});
}
}

View File

@@ -453,6 +453,46 @@ describe("chat view", () => {
expect(groupedLogo?.getAttribute("src")).toBe("/openclaw/favicon.svg");
});
it("renders anthropic tool_use input details in tool cards", () => {
const container = document.createElement("div");
render(
renderChat(
createProps({
messages: [
{
role: "assistant",
content: [
{
type: "tool_use",
id: "toolu_123",
name: "Bash",
input: { command: 'time claude -p "say ok"' },
},
],
timestamp: 1000,
},
{
role: "user",
content: [
{
type: "tool_result",
name: "Bash",
tool_use_id: "toolu_123",
content: "ok",
},
],
timestamp: 1001,
},
],
}),
),
container,
);
expect(container.textContent).toContain('time claude -p "say ok"');
expect(container.textContent).toContain("Bash");
});
it("keeps the persisted overview locale selected before i18n hydration finishes", async () => {
const container = document.createElement("div");
const props = createOverviewProps({