"use client" /** * Side-by-side comparison of what each configured adapter returns for one query. * * The ranked list an agent receives is deliberately lossy — dedup, the domain * cap and the limit drop hits, and only the first prose answer survives — so it * cannot answer "is the paid source earning its keep". This runs the adapters * exhaustively and shows each one's own output, which is the only view that can. */ import * as React from 'react' import { Button } from '@open-mercato/ui/primitives/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@open-mercato/ui/primitives/card' import { Input } from '@open-mercato/ui/primitives/input' import { Spinner } from '@open-mercato/ui/primitives/spinner' import { StatusBadge } from '@open-mercato/ui/primitives/status-badge' import { apiCall } from '@open-mercato/ui/backend/utils/apiCall' import { useT } from '@open-mercato/shared/lib/i18n/context' const PREVIEW_URL = '/api/agent_orchestrator/web-search/preview' type PreviewHit = { url: string title: string | null snippet: string | null blockedByGuardrails: boolean } type PreviewAdapter = { adapterId: string weight: number answer: string | null results: PreviewHit[] } type PreviewDiagnostic = { id: string; status: string; latencyMs: number; resultCount: number; reason?: string } type PreviewResponse = { query?: string diagnostics?: { adapters?: PreviewDiagnostic[]; elapsedMs?: number } byAdapter?: PreviewAdapter[] } const VARIANT_BY_STATUS: Readonly> = { ok: 'success', empty: 'neutral', skipped: 'neutral', unavailable: 'neutral', cancelled: 'neutral', blocked: 'warning', timeout: 'warning', error: 'error', } export function WebSearchPreview() { const t = useT() const [query, setQuery] = React.useState('') const [running, setRunning] = React.useState(false) const [error, setError] = React.useState(null) const [preview, setPreview] = React.useState(null) const run = React.useCallback(async () => { const trimmed = query.trim() if (trimmed.length === 0 || running) return setRunning(true) setError(null) try { const call = await apiCall(PREVIEW_URL, { method: 'POST', body: JSON.stringify({ query: trimmed }), }) if (call.ok && call.result) { setPreview(call.result) } else { setError(t('agent_orchestrator.settings.webSearch.preview.failed', 'The comparison run failed.')) } } catch { setError(t('agent_orchestrator.settings.webSearch.preview.failed', 'The comparison run failed.')) } finally { setRunning(false) } }, [query, running, t]) // Diagnostics are the spine, not `byAdapter`. The engine only reports adapters // that produced results, so keying off it would hide exactly the rows an // operator is looking for: the source that ran and came back with nothing. const resultsById = new Map((preview?.byAdapter ?? []).map((entry) => [entry.adapterId, entry])) const rows = (preview?.diagnostics?.adapters ?? []).map((diagnostic) => ({ diagnostic, payload: resultsById.get(diagnostic.id) ?? null, })) return ( {t('agent_orchestrator.settings.webSearch.preview.title', 'Compare adapters')} {t( 'agent_orchestrator.settings.webSearch.preview.description', 'Runs every enabled adapter for one query and shows what each returned on its own. Never cached, and it spends real quota on metered sources.', )}
setQuery(event.target.value)} onKeyDown={(event) => { if (event.key === 'Enter') void run() }} placeholder={t( 'agent_orchestrator.settings.webSearch.preview.placeholder', 'A query to compare, e.g. best CRM for small teams', )} className="min-w-64 flex-1" />
{error ?

{error}

: null} {rows.length > 0 ? (
{preview?.diagnostics?.elapsedMs !== undefined ? (

{t('agent_orchestrator.settings.webSearch.preview.elapsed', 'Finished in {ms}ms', { ms: String(preview.diagnostics.elapsedMs), })}

) : null} {rows.map(({ diagnostic, payload }) => (
{diagnostic.id} {diagnostic.status} {t('agent_orchestrator.settings.webSearch.preview.count', '{count} results', { count: String(payload?.results.length ?? 0), })} {`${diagnostic.latencyMs}ms`}
{diagnostic.reason ? (

{diagnostic.reason}

) : null} {payload?.answer ? (

{payload.answer}

) : null} {payload && payload.results.length > 0 ? (
    {payload.results.map((hit, index) => (
  1. {index + 1} {hit.title ?? hit.url} {hit.blockedByGuardrails ? ( {t('agent_orchestrator.settings.webSearch.preview.blocked', 'Blocked by domain rules')} ) : null}
  2. ))}
) : null}
))}
) : null} {preview && rows.length === 0 && !running ? (

{t( 'agent_orchestrator.settings.webSearch.preview.empty', 'No adapter ran at all. Check the per-adapter health above.', )}

) : null}
) } export default WebSearchPreview