export type ChatSummary = { id: string; title: string | null; createdAt: string; updatedAt: string; }; export type Message = { id: string; createdAt: string; role: "system" | "user" | "assistant" | "tool"; content: string; name: string | null; }; export type ChatDetail = { id: string; title: string | null; createdAt: string; updatedAt: string; messages: Message[]; }; export type CompletionRequestMessage = { role: "system" | "user" | "assistant" | "tool"; content: string; name?: string; }; type CompletionResponse = { chatId: string | null; message: { role: "assistant"; content: string; }; }; const API_BASE_URL = import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8787"; const ENV_ADMIN_TOKEN = (import.meta.env.VITE_ADMIN_TOKEN as string | undefined)?.trim() || null; let authToken: string | null = ENV_ADMIN_TOKEN; export function getConfiguredToken() { return ENV_ADMIN_TOKEN; } export function setAuthToken(token: string | null) { authToken = token?.trim() || null; } async function api(path: string, init?: RequestInit): Promise { const headers = new Headers(init?.headers ?? {}); headers.set("Content-Type", "application/json"); if (authToken) { headers.set("Authorization", `Bearer ${authToken}`); } const response = await fetch(`${API_BASE_URL}${path}`, { ...init, headers, }); if (!response.ok) { const fallback = `${response.status} ${response.statusText}`; let message = fallback; try { const body = (await response.json()) as { message?: string }; if (body.message) message = body.message; } catch { // keep fallback message } throw new Error(message); } return (await response.json()) as T; } export async function listChats() { const data = await api<{ chats: ChatSummary[] }>("/v1/chats"); return data.chats; } export async function verifySession() { return api<{ authenticated: true; mode: "open" | "token" }>("/v1/auth/session"); } export async function createChat(title?: string) { const data = await api<{ chat: ChatSummary }>("/v1/chats", { method: "POST", body: JSON.stringify({ title }), }); return data.chat; } export async function getChat(chatId: string) { const data = await api<{ chat: ChatDetail }>(`/v1/chats/${chatId}`); return data.chat; } export async function runCompletion(body: { chatId: string; provider: "openai" | "anthropic" | "xai"; model: string; messages: CompletionRequestMessage[]; }) { return api("/v1/chat-completions", { method: "POST", body: JSON.stringify(body), }); }