diff --git a/web-ui/src/app/settings/_components/tool-detail-drawer.tsx b/web-ui/src/app/settings/_components/tool-detail-drawer.tsx new file mode 100644 index 0000000..7f74e14 --- /dev/null +++ b/web-ui/src/app/settings/_components/tool-detail-drawer.tsx @@ -0,0 +1,65 @@ +"use client"; + +import { + Sheet, + SheetContent, + SheetHeader, + SheetTitle, + SheetDescription, +} from "@/components/ui/sheet"; +import { Badge } from "@/components/ui/badge"; +import type { McpTool } from "@/lib/api/settings"; + +type Props = { + tool: McpTool | null; + open: boolean; + onOpenChange: (o: boolean) => void; +}; + +export function ToolDetailDrawer({ tool, open, onOpenChange }: Props) { + return ( + + + {tool && ( + <> + + + {tool.name} + + {tool.description || "—"} + +
+
+
+ Module +
+ + {tool.module} + +
+
+
+ Source +
+ + {tool.source_location || "—"} + +
+
+
+ Parameters Schema +
+
+                  {JSON.stringify(tool.params_schema, null, 2)}
+                
+
+
+ + )} +
+
+ ); +} diff --git a/web-ui/src/app/settings/_components/tools-tab.tsx b/web-ui/src/app/settings/_components/tools-tab.tsx index 7a69e44..ef082a9 100644 --- a/web-ui/src/app/settings/_components/tools-tab.tsx +++ b/web-ui/src/app/settings/_components/tools-tab.tsx @@ -1 +1,83 @@ -export function ToolsTab() { return
Tools tab — coming soon
; } +"use client"; + +import { useState, useMemo } from "react"; +import { Wrench, AlertCircle } from "lucide-react"; +import { Card, CardContent } from "@/components/ui/card"; +import { Skeleton } from "@/components/ui/skeleton"; +import { Badge } from "@/components/ui/badge"; +import { useMcpTools, type McpTool } from "@/lib/api/settings"; +import { ToolDetailDrawer } from "./tool-detail-drawer"; + +export function ToolsTab() { + const { data, isPending, error } = useMcpTools(); + const [selected, setSelected] = useState(null); + const [open, setOpen] = useState(false); + + const grouped = useMemo(() => { + if (!data?.tools) return new Map(); + const m = new Map(); + for (const t of data.tools) { + const mod = t.module.split(".").pop() || "other"; + const arr = m.get(mod) ?? []; + arr.push(t); + m.set(mod, arr); + } + return m; + }, [data]); + + if (isPending) return ; + if (error) { + return ( + + + + שגיאה בטעינת tools: {error.message} + + + ); + } + if (!data) return null; + + return ( +
+
+ + סה"כ {data.count} tools +
+ {[...grouped.entries()].sort().map(([mod, tools]) => ( + + +

+ {mod} + + {tools.length} + +

+
+ {tools.map((t) => ( + + ))} +
+
+
+ ))} + +
+ ); +}