From 2a438b2bb372aaeb6833105c016e5b842fd80ccd Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Thu, 19 Feb 2026 18:09:16 +0000 Subject: [PATCH] feat(ui): toggle tool call input yaml --- package-lock.json | 3 +- packages/ui/package.json | 3 +- packages/ui/src/components/tool-call.tsx | 79 ++++++++++++++++++- .../ui/src/lib/i18n/messages/en/toolCall.ts | 5 ++ .../ui/src/lib/i18n/messages/es/toolCall.ts | 5 ++ .../ui/src/lib/i18n/messages/fr/toolCall.ts | 5 ++ .../ui/src/lib/i18n/messages/ja/toolCall.ts | 5 ++ .../ui/src/lib/i18n/messages/ru/toolCall.ts | 5 ++ .../src/lib/i18n/messages/zh-Hans/toolCall.ts | 5 ++ .../ui/src/styles/messaging/tool-call.css | 19 +++++ 10 files changed, 130 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 71bff3c9..8f529449 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12092,7 +12092,8 @@ "shiki": "^3.13.0", "solid-js": "^1.8.0", "solid-toast": "^0.5.0", - "tauri-plugin-keepawake-api": "^0.1.0" + "tauri-plugin-keepawake-api": "^0.1.0", + "yaml": "^2.4.2" }, "devDependencies": { "@vite-pwa/assets-generator": "^1.0.2", diff --git a/packages/ui/package.json b/packages/ui/package.json index a6235618..42aae094 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -30,7 +30,8 @@ "shiki": "^3.13.0", "solid-js": "^1.8.0", "solid-toast": "^0.5.0", - "tauri-plugin-keepawake-api": "^0.1.0" + "tauri-plugin-keepawake-api": "^0.1.0", + "yaml": "^2.4.2" }, "devDependencies": { "@vite-pwa/assets-generator": "^1.0.2", diff --git a/packages/ui/src/components/tool-call.tsx b/packages/ui/src/components/tool-call.tsx index 9b9e5c01..bd2ffae5 100644 --- a/packages/ui/src/components/tool-call.tsx +++ b/packages/ui/src/components/tool-call.tsx @@ -1,5 +1,6 @@ import { createSignal, Show, createEffect, createMemo, onCleanup } from "solid-js" -import { Copy } from "lucide-solid" +import { AlignJustify, Copy } from "lucide-solid" +import { stringify as stringifyYaml } from "yaml" import { messageStoreBus } from "../stores/message-v2/bus" import { useTheme } from "../lib/theme" import { useGlobalCache } from "../lib/hooks/use-global-cache" @@ -27,7 +28,17 @@ import type { ToolRendererContext, ToolScrollHelpers, } from "./tool-call/types" -import { getRelativePath, getToolIcon, getToolName, isToolStateCompleted, isToolStateError, isToolStateRunning, getDefaultToolAction } from "./tool-call/utils" +import { + ensureMarkdownContent, + getRelativePath, + getToolIcon, + getToolName, + isToolStateCompleted, + isToolStateError, + isToolStateRunning, + getDefaultToolAction, + readToolStatePayload, +} from "./tool-call/utils" import { resolveTitleForTool } from "./tool-call/tool-title" import { getLogger } from "../lib/logger" @@ -161,6 +172,7 @@ export default function ToolCall(props: ToolCallProps) { }) const [userExpanded, setUserExpanded] = createSignal(null) + const [inputExpanded, setInputExpanded] = createSignal(false) const isPermissionActive = createMemo(() => { const pending = pendingPermission() @@ -183,6 +195,35 @@ export default function ToolCall(props: ToolCallProps) { return defaultExpandedForTool() } + const toolInput = createMemo(() => { + const state = toolState() + return readToolStatePayload(state).input + }) + + const hasToolInput = createMemo(() => { + const input = toolInput() + return input && Object.keys(input).length > 0 + }) + + const toolInputMarkdown = createMemo(() => { + const input = toolInput() + if (!input || Object.keys(input).length === 0) return null + + try { + const yamlText = stringifyYaml(input) + return ensureMarkdownContent(yamlText, "yaml", true) + } catch (error) { + log.error("Failed to convert tool call input to YAML", error) + try { + const jsonText = JSON.stringify(input, null, 2) + return ensureMarkdownContent(jsonText, "json", true) + } catch (nestedError) { + log.error("Failed to stringify tool call input", nestedError) + return null + } + } + }) + const permissionDetails = createMemo(() => pendingPermission()?.permission) const questionDetails = createMemo(() => pendingQuestion()?.request) @@ -548,6 +589,15 @@ export default function ToolCall(props: ToolCallProps) { }) } + const handleToggleInput = (event: MouseEvent) => { + event.preventDefault() + event.stopPropagation() + if (!expanded()) { + toggle() + } + setInputExpanded((prev) => !prev) + } + const renderer = createMemo(() => resolveToolRenderer(toolName())) const { renderAnsiContent } = createAnsiContentRenderer({ @@ -789,6 +839,23 @@ export default function ToolCall(props: ToolCallProps) { + + + +