/** * Nearle Buddy. * * Two calls: is this switched on, and here is a question. The tenant is not one * of them — the server reads it from the session token, which is the whole * point. A request body that carried a tenant would be a request body somebody * could edit. */ import { api, WEB } from './client'; /** One tool the assistant ran, so an answer can show its working. */ export interface AssistantStep { tool: string; /** `ok` or `refused`. Refusals are shown, not hidden — an answer that quietly dropped one would look like Buddy chose not to look. */ outcome: string; rows?: number; detail?: string; scope?: string; } export interface AssistantAnswer { reply: string; used?: AssistantStep[]; model?: string; /** Console routes showing the rows the answer came from. */ sources?: string[]; /** * True when the loop hit its own limits, or the model's reply was cut off * mid-sentence. The answer is still worth showing — a partial answer beats a * spinner — but it must not be presented as the whole story. */ incomplete?: boolean; } /** * Is the assistant switched on for this deployment? * * Asked once when the panel mounts, and the answer decides whether the composer * is enabled. The panel has said "Not connected yet" since it was built; this is * what finally answers that at runtime rather than at build time. * * Never throws. A console that cannot reach this endpoint should show a * disabled field, not an error page — the panel is beside the work, not the * work itself. */ export async function assistantAvailable(): Promise { try { const status = await api.get<{ available?: boolean }>(`${WEB}/assistant/status`); return status?.available === true; } catch { return false; } } /** * Ask a question. * * `agent` names which assistant answers — the console sends the one matching the * page the panel sits beside. Phase 2 ships one, so an unknown name is refused * rather than silently answered by the wrong agent. */ export async function askAssistant(agent: string, question: string): Promise { return api.post(`${WEB}/assistant/ask`, { agent, question }); }