// ─── Types ──────────────────────────────────────────────────────────────────── export interface LoginResponse { status: string; message: string; data: { id: string; fullname: string; email: string; company: string; company_size: string; function: string; site: string; role: string; status: string; created_at: string; }; } export interface Room { id: string; title: string; user_id?: string; status?: string; created_at: string; updated_at: string | null; } export interface CreateRoomResponse { status: string; message: string; data: Room; } export interface ChatSource { id?: string; message_id?: string; document_id: string; filename: string; page_label: string | null; created_at?: string; } export interface RoomMessage { id: string; role: "user" | "assistant"; content: string; created_at: string; sources?: ChatSource[]; } export interface RoomDetail extends Room { messages: RoomMessage[]; } export type DocumentStatus = "uploaded" | "processing" | "completed" | "failed"; export interface ApiDocument { id: string; filename: string; status: DocumentStatus; file_size: number; file_type: string; created_at: string; } export interface UploadDocumentResponse { status: string; message: string; data: { id: string; filename: string; status: DocumentStatus }; } export interface DocTypeInfo { doc_type: string; max_size: number; status: "active" | "inactive"; message: string | null; } export interface DataCatalogSource { source_id: string; source_type: "schema" | "tabular" | "unstructured"; name: string; location_ref: string; } export interface DataCatalog { user_id: string; schema_version: string; generated_at: string; sources: DataCatalogSource[]; } // ─── Base Clients ───────────────────────────────────────────────────────────── const ORCHESTRATION_BASE_URL = ((import.meta as unknown as { env: Record }).env .VITE_ORCHESTRATION_API_BASE_URL) ?? ""; const AGENTIC_BASE_URL = ((import.meta as unknown as { env: Record }).env .VITE_AGENTIC_API_BASE_URL) ?? ""; async function request(baseUrl: string, path: string, options?: RequestInit): Promise { const res = await fetch(`${baseUrl}${path}`, { headers: { "Content-Type": "application/json", ...options?.headers }, ...options, }); if (!res.ok) { const err = await res .json() .catch(() => ({ detail: `HTTP ${res.status}` })); throw new Error(err.detail ?? `HTTP ${res.status}`); } return res.json() as Promise; } // ─── Auth ───────────────────────────────────────────────────────────────────── export const login = (email: string, password: string) => request(ORCHESTRATION_BASE_URL, "/api/login", { method: "POST", body: JSON.stringify({ email, password }), }); // ─── Rooms ──────────────────────────────────────────────────────────────────── export const getRooms = (userId: string): Promise => request<{ status: string; message: string; data: Room[] | null }>(ORCHESTRATION_BASE_URL, `/api/v1/rooms/${userId}`) .then(res => res.data ?? []); export const getRoom = (roomId: string): Promise => request<{ status: string; message: string; data: RoomDetail }>(ORCHESTRATION_BASE_URL, `/api/v1/room/${roomId}`) .then(res => res.data); export const deleteRoom = (roomId: string, userId: string) => request<{ status: string; message: string }>( ORCHESTRATION_BASE_URL, `/api/v1/room/${roomId}?user_id=${userId}`, { method: "DELETE" } ); export const createRoom = (userId: string, title?: string) => request(ORCHESTRATION_BASE_URL, "/api/v1/room/create", { method: "POST", body: JSON.stringify({ user_id: userId, title }), }); // ─── Documents ──────────────────────────────────────────────────────────────── export const getDocuments = (userId: string): Promise => request<{ status: string; message: string; data: ApiDocument[] | null }>(ORCHESTRATION_BASE_URL, `/api/v1/documents/${userId}`) .then(res => res.data ?? []); export const uploadDocument = async ( userId: string, file: File ): Promise => { const form = new FormData(); form.append("user_id", userId); form.append("file", file); const res = await fetch( `${ORCHESTRATION_BASE_URL}/api/v1/document/upload`, { method: "POST", body: form } ); if (!res.ok) { const err = await res .json() .catch(() => ({ detail: `HTTP ${res.status}` })); throw new Error(err.detail ?? `HTTP ${res.status}`); } return res.json() as Promise; }; export const processDocument = (_userId: string, documentId: string) => request<{ status: string; message: string }>( ORCHESTRATION_BASE_URL, `/api/v1/document/process`, { method: "POST", body: JSON.stringify({ document_id: documentId }) } ); export const deleteDocument = (_userId: string, documentId: string) => request<{ status: string; message: string }>( ORCHESTRATION_BASE_URL, `/api/v1/document/delete`, { method: "DELETE", body: JSON.stringify({ document_id: documentId }) } ); export const getDocumentTypes = (): Promise => request<{ status: string; data: DocTypeInfo[] }>(ORCHESTRATION_BASE_URL, "/api/v1/documents/doctypes").then( (res) => res.data ); // ─── Database Clients ───────────────────────────────────────────────────────── export type DbType = "postgres" | "mysql" | "sqlserver" | "supabase" | "bigquery" | "snowflake"; export interface DbTypeField { name: string; type: "string" | "integer" | "select" | "boolean"; required: boolean; default: string | number | boolean | null; description: string; options?: string[]; sensitive?: boolean; } export interface DbTypeInfo { db_type: DbType; display_name: string; logo: string; status: "active" | "inactive"; message: string | null; fields: DbTypeField[]; } export interface DatabaseClient { id: string; user_id: string; name: string; db_type: DbType; status: "active" | "inactive"; created_at: string; updated_at: string | null; } export interface IngestResponse { status: string; client_id: string; chunks_ingested: number; } export const getDatabaseClientTypes = (): Promise => request<{ status: string; message: string; data: DbTypeInfo[] | null }>(ORCHESTRATION_BASE_URL, "/api/v1/database-clients/dbtypes") .then(res => res.data ?? []); export const connectDatabase = ( userId: string, dbType: DbType, name: string, credentials: Record ): Promise => request<{ status: string; message: string; data: DatabaseClient }>(ORCHESTRATION_BASE_URL, `/api/v1/database-clients`, { method: "POST", body: JSON.stringify({ user_id: userId, name, db_type: dbType, credentials }), }).then(res => res.data); export const getDatabaseClients = (userId: string): Promise => request<{ status: string; message: string; data: DatabaseClient[] | null }>(ORCHESTRATION_BASE_URL, `/api/v1/database-clients/${userId}`) .then(res => res.data ?? []); export const deleteDatabaseClient = (clientId: string, userId: string) => request<{ status: string; message: string }>( ORCHESTRATION_BASE_URL, `/api/v1/database-clients/${clientId}?user_id=${userId}`, { method: "DELETE" } ); export const ingestDatabaseClient = (clientId: string, _userId: string): Promise => request<{ status: string; message: string; data: IngestResponse }>( ORCHESTRATION_BASE_URL, `/api/v1/database-clients/${clientId}/ingest`, { method: "POST" } ).then(res => res.data); // ─── Data Catalog ───────────────────────────────────────────────────────────── export const getDataCatalog = (userId: string): Promise => request<{ status: string; message: string; data: DataCatalog }>( ORCHESTRATION_BASE_URL, `/api/v1/data-catalog/${userId}` ).then((res) => res.data); export const rebuildDataCatalog = (userId: string): Promise => request<{ status: string; message: string; data: DataCatalog }>( ORCHESTRATION_BASE_URL, "/api/v1/data-catalog/rebuild", { method: "POST", body: JSON.stringify({ user_id: userId }) } ).then((res) => res.data); // ─── Chat ───────────────────────────────────────────────────────────────────── export const streamChat = ( userId: string, roomId: string, message: string ): Promise => fetch(`${AGENTIC_BASE_URL}/api/v1/chat/stream`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ user_id: userId, room_id: roomId, message }), });