/** * Minimal gateway REST API client for the TUI and CLI commands. */ export interface ModelInfo { id: string; provider: string; name: string; } export interface ProviderInfo { id: string; name: string; available: boolean; models: ModelInfo[]; } export interface SessionInfo { id: string; provider: string; modelId: string; createdAt: string; promptCount: number; channels: string[]; durationMs: number; } export interface SessionListResult { sessions: SessionInfo[]; total: number; } // ── Agent Config types ── export interface AgentConfigInfo { id: string; name: string; provider: string; model: string; status: string; projectId: string | null; ownerId: string | null; systemPrompt: string | null; allowedTools: string[] | null; skills: string[] | null; isSystem: boolean; config: Record | null; createdAt: string; updatedAt: string; } // ── Project types ── export interface ProjectInfo { id: string; name: string; description: string | null; status: string; ownerId: string | null; createdAt: string; updatedAt: string; } // ── Mission types ── export interface MissionInfo { id: string; name: string; description: string | null; status: string; projectId: string | null; userId: string | null; phase: string | null; milestones: Record[] | null; config: Record | null; createdAt: string; updatedAt: string; } // ── Mission Task types ── export interface MissionTaskInfo { id: string; missionId: string; taskId: string | null; userId: string; status: string; description: string | null; notes: string | null; pr: string | null; createdAt: string; updatedAt: string; } // ── Helpers ── function headers(sessionCookie: string, gatewayUrl: string) { return { Cookie: sessionCookie, Origin: gatewayUrl }; } function jsonHeaders(sessionCookie: string, gatewayUrl: string) { return { ...headers(sessionCookie, gatewayUrl), 'Content-Type': 'application/json' }; } async function handleResponse(res: Response, errorPrefix: string): Promise { if (!res.ok) { const body = await res.text().catch(() => ''); throw new Error(`${errorPrefix} (${res.status}): ${body}`); } return (await res.json()) as T; } // ── Conversation types ── export interface ConversationInfo { id: string; title: string | null; archived: boolean; createdAt: string; updatedAt: string; } // ── Conversation endpoints ── export async function createConversation( gatewayUrl: string, sessionCookie: string, data: { title?: string; projectId?: string } = {}, ): Promise { const res = await fetch(`${gatewayUrl}/api/conversations`, { method: 'POST', headers: jsonHeaders(sessionCookie, gatewayUrl), body: JSON.stringify(data), }); return handleResponse(res, 'Failed to create conversation'); } // ── Provider / Model endpoints ── export async function fetchAvailableModels( gatewayUrl: string, sessionCookie?: string, ): Promise { try { const res = await fetch(`${gatewayUrl}/api/providers/models`, { headers: { ...(sessionCookie ? { Cookie: sessionCookie } : {}), Origin: gatewayUrl, }, }); if (!res.ok) return []; const data = (await res.json()) as ModelInfo[]; return Array.isArray(data) ? data : []; } catch { return []; } } export async function fetchProviders( gatewayUrl: string, sessionCookie?: string, ): Promise { try { const res = await fetch(`${gatewayUrl}/api/providers`, { headers: { ...(sessionCookie ? { Cookie: sessionCookie } : {}), Origin: gatewayUrl, }, }); if (!res.ok) return []; const data = (await res.json()) as ProviderInfo[]; return Array.isArray(data) ? data : []; } catch { return []; } } // ── Session endpoints ── export async function fetchSessions( gatewayUrl: string, sessionCookie: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/sessions`, { headers: headers(sessionCookie, gatewayUrl), }); return handleResponse(res, 'Failed to list sessions'); } export async function deleteSession( gatewayUrl: string, sessionCookie: string, sessionId: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/sessions/${encodeURIComponent(sessionId)}`, { method: 'DELETE', headers: headers(sessionCookie, gatewayUrl), }); if (!res.ok && res.status !== 204) { const body = await res.text().catch(() => ''); throw new Error(`Failed to destroy session (${res.status}): ${body}`); } } // ── Agent Config endpoints ── export async function fetchAgentConfigs( gatewayUrl: string, sessionCookie: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/agents`, { headers: headers(sessionCookie, gatewayUrl), }); return handleResponse(res, 'Failed to list agents'); } export async function fetchAgentConfig( gatewayUrl: string, sessionCookie: string, id: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/agents/${encodeURIComponent(id)}`, { headers: headers(sessionCookie, gatewayUrl), }); return handleResponse(res, 'Failed to get agent'); } export async function createAgentConfig( gatewayUrl: string, sessionCookie: string, data: { name: string; provider: string; model: string; projectId?: string; systemPrompt?: string; allowedTools?: string[]; skills?: string[]; config?: Record; }, ): Promise { const res = await fetch(`${gatewayUrl}/api/agents`, { method: 'POST', headers: jsonHeaders(sessionCookie, gatewayUrl), body: JSON.stringify(data), }); return handleResponse(res, 'Failed to create agent'); } export async function updateAgentConfig( gatewayUrl: string, sessionCookie: string, id: string, data: Record, ): Promise { const res = await fetch(`${gatewayUrl}/api/agents/${encodeURIComponent(id)}`, { method: 'PATCH', headers: jsonHeaders(sessionCookie, gatewayUrl), body: JSON.stringify(data), }); return handleResponse(res, 'Failed to update agent'); } export async function deleteAgentConfig( gatewayUrl: string, sessionCookie: string, id: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/agents/${encodeURIComponent(id)}`, { method: 'DELETE', headers: headers(sessionCookie, gatewayUrl), }); if (!res.ok && res.status !== 204) { const body = await res.text().catch(() => ''); throw new Error(`Failed to delete agent (${res.status}): ${body}`); } } // ── Project endpoints ── export async function fetchProjects( gatewayUrl: string, sessionCookie: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/projects`, { headers: headers(sessionCookie, gatewayUrl), }); return handleResponse(res, 'Failed to list projects'); } // ── Mission endpoints ── export async function fetchMissions( gatewayUrl: string, sessionCookie: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/missions`, { headers: headers(sessionCookie, gatewayUrl), }); return handleResponse(res, 'Failed to list missions'); } export async function fetchMission( gatewayUrl: string, sessionCookie: string, id: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/missions/${encodeURIComponent(id)}`, { headers: headers(sessionCookie, gatewayUrl), }); return handleResponse(res, 'Failed to get mission'); } export async function createMission( gatewayUrl: string, sessionCookie: string, data: { name: string; description?: string; projectId?: string; status?: string; phase?: string; milestones?: Record[]; config?: Record; }, ): Promise { const res = await fetch(`${gatewayUrl}/api/missions`, { method: 'POST', headers: jsonHeaders(sessionCookie, gatewayUrl), body: JSON.stringify(data), }); return handleResponse(res, 'Failed to create mission'); } export async function updateMission( gatewayUrl: string, sessionCookie: string, id: string, data: Record, ): Promise { const res = await fetch(`${gatewayUrl}/api/missions/${encodeURIComponent(id)}`, { method: 'PATCH', headers: jsonHeaders(sessionCookie, gatewayUrl), body: JSON.stringify(data), }); return handleResponse(res, 'Failed to update mission'); } export async function deleteMission( gatewayUrl: string, sessionCookie: string, id: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/missions/${encodeURIComponent(id)}`, { method: 'DELETE', headers: headers(sessionCookie, gatewayUrl), }); if (!res.ok && res.status !== 204) { const body = await res.text().catch(() => ''); throw new Error(`Failed to delete mission (${res.status}): ${body}`); } } // ── Conversation Message types ── export interface ConversationMessage { id: string; role: 'user' | 'assistant' | 'system' | 'tool'; content: string; createdAt: string; } // ── Conversation Message endpoints ── export async function fetchConversationMessages( gatewayUrl: string, sessionCookie: string, conversationId: string, ): Promise { const res = await fetch( `${gatewayUrl}/api/conversations/${encodeURIComponent(conversationId)}/messages`, { headers: headers(sessionCookie, gatewayUrl), }, ); return handleResponse(res, 'Failed to fetch conversation messages'); } // ── Mission Task endpoints ── export async function fetchMissionTasks( gatewayUrl: string, sessionCookie: string, missionId: string, ): Promise { const res = await fetch(`${gatewayUrl}/api/missions/${encodeURIComponent(missionId)}/tasks`, { headers: headers(sessionCookie, gatewayUrl), }); return handleResponse(res, 'Failed to list mission tasks'); } export async function createMissionTask( gatewayUrl: string, sessionCookie: string, missionId: string, data: { description?: string; status?: string; notes?: string; pr?: string; taskId?: string; }, ): Promise { const res = await fetch(`${gatewayUrl}/api/missions/${encodeURIComponent(missionId)}/tasks`, { method: 'POST', headers: jsonHeaders(sessionCookie, gatewayUrl), body: JSON.stringify(data), }); return handleResponse(res, 'Failed to create mission task'); } export async function updateMissionTask( gatewayUrl: string, sessionCookie: string, missionId: string, taskId: string, data: Record, ): Promise { const res = await fetch( `${gatewayUrl}/api/missions/${encodeURIComponent(missionId)}/tasks/${encodeURIComponent(taskId)}`, { method: 'PATCH', headers: jsonHeaders(sessionCookie, gatewayUrl), body: JSON.stringify(data), }, ); return handleResponse(res, 'Failed to update mission task'); }