From 9241970b02ac54d3df08fb9e73b86c23c217f8dd Mon Sep 17 00:00:00 2001 From: iliya Date: Mon, 30 Mar 2026 16:00:34 +0300 Subject: [PATCH] =?UTF-8?q?fix(graph):=20format=20recent=20tools=20?= =?UTF-8?q?=E2=80=94=20clean=20names=20+=20extract=20readable=20preview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Tool names: "mcp__agent-teams__task_create" → "Task Create" (strip MCP prefixes, snake_case → Title Case) - Tool preview: raw JSON → extract subject/name/path field (was showing { "id": "19ebbdd5-...", "displayId": ... }) - Compact single-line layout with status dot + name + preview --- .../agent-graph/ui/GraphNodePopover.tsx | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/renderer/features/agent-graph/ui/GraphNodePopover.tsx b/src/renderer/features/agent-graph/ui/GraphNodePopover.tsx index b861d6ea..ea4ee1e8 100644 --- a/src/renderer/features/agent-graph/ui/GraphNodePopover.tsx +++ b/src/renderer/features/agent-graph/ui/GraphNodePopover.tsx @@ -11,6 +11,37 @@ import { Loader2, MessageSquare, ExternalLink, User, Plus } from 'lucide-react'; import type { GraphNode } from '@claude-teams/agent-graph'; +// ─── Tool name/preview formatters ─────────────────────────────────────────── + +/** Clean up tool names: "mcp__agent-teams__task_create" → "Task Create" */ +function formatToolName(raw: string): string { + // Strip MCP prefixes (mcp__serverName__toolName → toolName) + const parts = raw.split('__'); + const name = parts[parts.length - 1] ?? raw; + // snake_case → Title Case + return name.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()); +} + +/** Clean up tool preview: strip raw JSON, extract meaningful part */ +function formatToolPreview(preview: string | undefined): string | undefined { + if (!preview) return undefined; + // If it looks like raw JSON object, try to extract a readable field + if (preview.startsWith('{') || preview.startsWith('[')) { + try { + const obj = JSON.parse(preview.length > 200 ? preview.slice(0, 200) : preview); + // Common readable fields + return ( + obj.subject ?? obj.name ?? obj.label ?? obj.file_path ?? obj.path ?? obj.query ?? undefined + ); + } catch { + // Truncated JSON — extract first quoted value + const match = preview.match(/"(?:subject|name|label|path|query)":\s*"([^"]{1,60})"/); + if (match) return match[1]; + } + } + return preview.length > 50 ? preview.slice(0, 50) + '...' : preview; +} + interface GraphNodePopoverProps { node: GraphNode; onClose: () => void;