import { agentNativePath } from "@agent-native/core/client/api-path"; import { useT } from "@agent-native/core/client/i18n"; import { IconCheck, IconLoader2, IconCircleCheck, IconAlertCircle, IconPlayerPlay, IconCpu, } from "@tabler/icons-react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Skeleton } from "@/components/ui/skeleton"; import { cn } from "@/lib/utils"; // ─── Types ──────────────────────────────────────────────────────────────────── interface EngineCapabilities { thinking: boolean; promptCaching: boolean; vision: boolean; computerUse: boolean; parallelToolCalls: boolean; } interface EngineEntry { name: string; label: string; description: string; defaultModel: string; supportedModels: readonly string[]; capabilities: EngineCapabilities; requiredEnvVars: string[]; installPackage?: string; } interface EnginesResponse { engines: EngineEntry[]; current: { engine: string; model: string }; } // ─── API helpers ────────────────────────────────────────────────────────────── async function manageAgentEngine(body: Record): Promise { const res = await fetch( agentNativePath("/_agent-native/actions/manage-agent-engine"), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }, ); if (!res.ok) { const err = await res.json().catch(() => null); throw new Error(err?.error || `Request failed (${res.status})`); } const text = await res.text(); try { // The script returns a JSON string as the result const outer = JSON.parse(text); if (typeof outer === "string") return JSON.parse(outer) as T; return outer as T; } catch { return text as unknown as T; } } // ─── Capability badge ───────────────────────────────────────────────────────── function CapBadge({ label, enabled }: { label: string; enabled: boolean }) { return ( {label} ); } // ─── Engine card ────────────────────────────────────────────────────────────── function EngineCard({ engine, isSelected, selectedModel, onSelect, }: { engine: EngineEntry; isSelected: boolean; selectedModel: string; onSelect: (model: string) => void; }) { const caps = engine.capabilities; return ( ); } // ─── AgentEnginePicker ──────────────────────────────────────────────────────── export function AgentEnginePicker() { const t = useT(); const qc = useQueryClient(); const [localEngine, setLocalEngine] = useState(null); const [localModel, setLocalModel] = useState(null); const [testResult, setTestResult] = useState<{ ok: boolean; latencyMs?: number; error?: string; } | null>(null); // Fetch engine list const { data, isLoading, error } = useQuery({ queryKey: ["agent-engines"], queryFn: () => manageAgentEngine({ action: "list" }), staleTime: 30_000, }); // Set engine mutation const setEngine = useMutation({ mutationFn: ({ engine, model }: { engine: string; model: string }) => manageAgentEngine({ action: "set", engine, model }), onSuccess: () => { qc.invalidateQueries({ queryKey: ["agent-engines"] }); setLocalEngine(null); setLocalModel(null); setTestResult(null); }, }); // Test engine mutation const testEngine = useMutation({ mutationFn: ({ engine, model }: { engine: string; model: string }) => manageAgentEngine<{ ok: boolean; latencyMs?: number; error?: string }>({ action: "test", engine, model, }), onSuccess: (result) => { setTestResult(result); }, onError: (err: Error) => { setTestResult({ ok: false, error: err.message }); }, }); if (isLoading) { return (
); } if (error || !data) { return (
{t("mail.agentEngine.loadFailed")}
); } const { engines, current } = data; const activeEngine = localEngine ?? current.engine; const engineEntry = engines.find((e) => e.name === activeEngine); const activeModel = localModel ?? (activeEngine === current.engine ? current.model : (engineEntry?.defaultModel ?? "")); const isDirty = activeEngine !== current.engine || activeModel !== current.model; const handleEngineSelect = (name: string, model?: string) => { const entry = engines.find((e) => e.name === name); setLocalEngine(name); setLocalModel(model ?? entry?.defaultModel ?? ""); setTestResult(null); }; const handleSave = () => { setEngine.mutate({ engine: activeEngine, model: activeModel }); }; const handleTest = () => { testEngine.mutate({ engine: activeEngine, model: activeModel }); }; return (
{/* Current status */}

{t("mail.agentEngine.activeEngine")}

{current.engine} / {current.model}

{isDirty && ( unsaved )}
{/* Engine cards */}

{t("mail.agentEngine.selectEngine")}

{engines.map((engine) => ( handleEngineSelect(engine.name, model)} /> ))}
{/* Model picker */} {engineEntry && (

Model

)} {/* Test result */} {testResult && (
{testResult.ok ? ( ) : ( )}
{testResult.ok ? (

Connected — {testResult.latencyMs}ms response time

) : (

{testResult.error ?? "Connection failed"}

)}
)} {/* Actions */}
{setEngine.isSuccess && !isDirty && (

{t("mail.agentEngine.engineSaved")}

)} {setEngine.error && (

{(setEngine.error as Error).message}

)}
); }