/** * Gradio Server provider adapter — uses @gradio/client to call any * deployed Gradio app (e.g. a HuggingFace Space). * * Model ID format: gradio::: * e.g. gradio:https://my-user-my-space.hf.space::/chat * * Reference: https://huggingface.co/blog/introducing-gradio-server */ import { client } from "@gradio/client"; export async function callGradio({ model, prompt, systemPrompt = "", history = [], apiKey, }) { const spec = model.replace(/^gradio:/, ""); const [url, apiName] = spec.split("::"); if (!url) throw new Error("Gradio model spec must include a URL"); const app = await client(url, { hfToken: apiKey?.startsWith("hf_") ? apiKey : undefined, }); const firstEndpoint = apiName || "/predict"; const gradioHistory = history.map((m) => [ m.role === "user" ? m.content : null, m.role === "assistant" ? m.content : null, ]); const attempts = [ { fn_index_or_api_name: firstEndpoint, data: [prompt, gradioHistory, systemPrompt] }, { fn_index_or_api_name: firstEndpoint, data: [prompt, gradioHistory] }, { fn_index_or_api_name: firstEndpoint, data: [{ text: prompt, history: gradioHistory, system: systemPrompt }] }, { fn_index_or_api_name: firstEndpoint, data: [prompt] }, ]; let result = null; let lastErr = null; for (const attempt of attempts) { try { result = await app.predict(attempt.fn_index_or_api_name, attempt.data); break; } catch (e) { lastErr = e; } } if (!result) { throw new Error(`Gradio call failed. Last error: ${lastErr?.message || "unknown"}`); } const data = result?.data || result; let text = ""; if (Array.isArray(data)) { const first = data[0]; if (typeof first === "string") { text = first; } else if (first?.text) { text = first.text; } else if (Array.isArray(first)) { const lastAssistant = [...first].reverse().find((pair) => pair?.[1]); text = lastAssistant?.[1] || ""; } else if (typeof first === "object") { text = JSON.stringify(first); } } else if (typeof data === "string") { text = data; } return { text, usage: null }; }