| |
| |
| |
| |
| |
| |
|
|
| import { useMemo, useState } from 'react' |
| import { useAgenticCatalog } from '../../agentic/useAgenticCatalog' |
| import type { CapabilityItem } from '../../agentic/types' |
| import { deriveStatus } from './ToolStatusBadge' |
|
|
| type Args = { |
| backendUrl: string |
| apiKey?: string |
| } |
|
|
| export type TypeFilter = 'all' | 'tool' | 'a2a' |
|
|
| export function useToolsInventory({ backendUrl, apiKey }: Args) { |
| const { catalog, loading, error, refresh } = useAgenticCatalog({ |
| backendUrl, |
| apiKey, |
| enabled: true, |
| }) |
|
|
| const [search, setSearch] = useState('') |
| const [statusFilter, setStatusFilter] = useState<'all' | 'active' | 'inactive'>('all') |
| const [typeFilter, setTypeFilter] = useState<TypeFilter>('all') |
|
|
| |
| const allItems: CapabilityItem[] = useMemo(() => { |
| const toolItems: CapabilityItem[] = (catalog?.tools || []) |
| .filter((t) => t.id && t.name) |
| .map((t) => ({ kind: 'tool', data: t })) |
|
|
| const a2aItems: CapabilityItem[] = (catalog?.a2a_agents || []) |
| .filter((a) => a.id && a.name) |
| .map((a) => ({ kind: 'a2a_agent', data: a })) |
|
|
| return [...toolItems, ...a2aItems] |
| }, [catalog?.tools, catalog?.a2a_agents]) |
|
|
| |
| const items = useMemo(() => { |
| let filtered = allItems |
|
|
| |
| if (typeFilter !== 'all') { |
| const kind = typeFilter === 'a2a' ? 'a2a_agent' : 'tool' |
| filtered = filtered.filter((item) => item.kind === kind) |
| } |
|
|
| |
| if (search.trim()) { |
| const q = search.toLowerCase() |
| filtered = filtered.filter((item) => { |
| const d = item.data |
| const searchable = `${d.name} ${d.description || ''} ${d.id} ${ |
| item.kind === 'a2a_agent' && 'endpoint_url' in d ? d.endpoint_url || '' : '' |
| }` |
| return searchable.toLowerCase().includes(q) |
| }) |
| } |
|
|
| |
| if (statusFilter !== 'all') { |
| filtered = filtered.filter((item) => deriveStatus(item.data.enabled) === statusFilter) |
| } |
|
|
| return filtered |
| }, [allItems, search, statusFilter, typeFilter]) |
|
|
| |
| const counts = useMemo(() => { |
| const tools = (catalog?.tools || []) |
| const a2a = (catalog?.a2a_agents || []) |
|
|
| return { |
| total: tools.length + a2a.length, |
| tools: { |
| total: tools.length, |
| active: tools.filter((t) => t.enabled === true).length, |
| inactive: tools.filter((t) => t.enabled === false).length, |
| }, |
| a2a: { |
| total: a2a.length, |
| active: a2a.filter((a) => a.enabled === true).length, |
| inactive: a2a.filter((a) => a.enabled === false).length, |
| }, |
| active: tools.filter((t) => t.enabled === true).length + a2a.filter((a) => a.enabled === true).length, |
| inactive: tools.filter((t) => t.enabled === false).length + a2a.filter((a) => a.enabled === false).length, |
| } |
| }, [catalog?.tools, catalog?.a2a_agents]) |
|
|
| return { |
| items, |
| counts, |
| loading, |
| error, |
| refresh, |
| search, |
| setSearch, |
| statusFilter, |
| setStatusFilter, |
| typeFilter, |
| setTypeFilter, |
| forgeHealthy: catalog?.forge?.healthy ?? null, |
| } |
| } |
|
|