import type { StudioApiEnvelope } from '../protocol/studio-agent-types' const STUDIO_API_BASE = '/api/studio-agent' export class StudioApiRequestError extends Error { readonly code: string readonly details?: unknown constructor(message: string, code = 'STUDIO_REQUEST_FAILED', details?: unknown) { super(message) this.name = 'StudioApiRequestError' this.code = code this.details = details } } export function getStudioApiBase(): string { return STUDIO_API_BASE } export function getStudioAuthHeaders(contentType?: string): HeadersInit { const headers: HeadersInit = {} if (contentType) { headers['Content-Type'] = contentType } const apiKey = localStorage.getItem('manimcat_api_key') if (apiKey) { headers.Authorization = `Bearer ${apiKey}` } return headers } export async function studioRequest(path: string, init?: RequestInit): Promise { const response = await fetch(`${STUDIO_API_BASE}${path}`, init) const payload = await parseStudioEnvelope(response) if (!response.ok || !payload.ok) { if (payload.ok) { throw new StudioApiRequestError(`Studio request failed with status ${response.status}`) } throw new StudioApiRequestError(payload.error.message, payload.error.code, payload.error.details) } return payload.data } async function parseStudioEnvelope(response: Response): Promise> { const raw = await response.text() try { return JSON.parse(raw) as StudioApiEnvelope } catch { const snippet = raw.trim().slice(0, 240) throw new StudioApiRequestError( snippet ? `Studio API returned invalid JSON (${response.status}): ${snippet}` : `Studio API returned invalid JSON (${response.status})` ) } }