diff --git a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/SectionTenantConfigReport.tsx b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/SectionTenantConfigReport.tsx index d41ad011..5f8eaf04 100644 --- a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/SectionTenantConfigReport.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/SectionTenantConfigReport.tsx @@ -6,6 +6,7 @@ import { api } from '@/lib/api'; import { apiErrorText, fetchJson } from "@/lib/apiClient"; import type { AgentConfigResponse, + McpClientRegistrationListResponse, TenantConfiguration, TenantFeatureFlagsResponse, } from "@/utils/wire-types.generated"; @@ -205,6 +206,31 @@ function ChannelRows({ config }: { config: TenantConfiguration }) { ); } +// ── Self-hosted AI clients (separate table, not part of TenantConfiguration) ── + +function SelfHostedAiClientRows({ list }: { list: McpClientRegistrationListResponse }) { + return ( + <> + + {list.registrations.length === 0 && } + {list.registrations.map((r) => ( + + + + + + + + + +
+ + + ))} + + ); +} + // ── Main component ─────────────────────────────────────────────────────────── export function SectionTenantConfigReport() { @@ -215,6 +241,7 @@ export function SectionTenantConfigReport() { const [config, setConfig] = useState(null); const [flags, setFlags] = useState(null); const [effective, setEffective] = useState(null); + const [aiClients, setAiClients] = useState(null); const [loading, setLoading] = useState(false); const [loadingTenants, setLoadingTenants] = useState(true); const [error, setError] = useState(null); @@ -242,27 +269,31 @@ export function SectionTenantConfigReport() { fetchTenants(); }, [user?.isGlobalAdmin, getAccessToken]); - // Fetch the stored config plus the two backend-resolved views of it. The stored config is - // the report; feature-flags (effective entitlement, header) and the effective agent config - // (runtime column) are fail-soft — a notice replaces them instead of blocking the page. + // Fetch the stored config plus the two backend-resolved views of it and the self-hosted AI + // client registrations (own table). The stored config is the report; feature-flags (effective + // entitlement, header), the effective agent config (runtime column) and the registrations are + // fail-soft — a notice replaces them instead of blocking the page. const fetchConfig = useCallback(async () => { if (!selectedTenantId) return; try { setLoading(true); setError(null); setSideError(null); - const [configResult, flagsResult, effectiveResult] = await Promise.allSettled([ + const [configResult, flagsResult, effectiveResult, aiClientsResult] = await Promise.allSettled([ fetchJson(api.config.tenant(selectedTenantId), getAccessToken), fetchJson(api.config.featureFlags(selectedTenantId), getAccessToken), fetchJson(api.config.effectiveAgentConfig(selectedTenantId), getAccessToken), + fetchJson(api.tenants.mcpClientRegistrations(selectedTenantId), getAccessToken), ]); if (configResult.status === 'rejected') throw configResult.reason; setConfig(configResult.value); setFlags(flagsResult.status === 'fulfilled' ? flagsResult.value : null); setEffective(effectiveResult.status === 'fulfilled' ? effectiveResult.value : null); + setAiClients(aiClientsResult.status === 'fulfilled' ? aiClientsResult.value : null); const sideFailures = [ flagsResult.status === 'rejected' ? `feature flags: ${apiErrorText(flagsResult.reason)}` : null, effectiveResult.status === 'rejected' ? `effective agent config: ${apiErrorText(effectiveResult.reason)}` : null, + aiClientsResult.status === 'rejected' ? `self-hosted AI clients: ${apiErrorText(aiClientsResult.reason)}` : null, ].filter((s): s is string => s !== null); setSideError(sideFailures.length ? `Backend-resolved views unavailable — ${sideFailures.join('; ')}` : null); } catch (err) { @@ -270,6 +301,7 @@ export function SectionTenantConfigReport() { setConfig(null); setFlags(null); setEffective(null); + setAiClients(null); } finally { setLoading(false); } @@ -433,6 +465,7 @@ export function SectionTenantConfigReport() { /> ); })} + {section === 'Tenant Status' && aiClients && } ))} diff --git a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/tenantConfigReportCatalog.ts b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/tenantConfigReportCatalog.ts index 9c13524f..b99c22d0 100644 --- a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/tenantConfigReportCatalog.ts +++ b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/tenantConfigReportCatalog.ts @@ -98,7 +98,7 @@ export const TENANT_FIELDS: Record