initial
This commit is contained in:
98
apps/web/src/api/client.ts
Normal file
98
apps/web/src/api/client.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import type {
|
||||
Project,
|
||||
AvailableProject,
|
||||
Session,
|
||||
Message,
|
||||
ModelInfo,
|
||||
} from './types';
|
||||
|
||||
export class ApiError extends Error {
|
||||
constructor(
|
||||
public status: number,
|
||||
public body: unknown
|
||||
) {
|
||||
super(typeof body === 'object' && body && 'error' in body ? String((body as { error: unknown }).error) : `HTTP ${status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function request<T>(
|
||||
path: string,
|
||||
init: RequestInit = {}
|
||||
): Promise<T> {
|
||||
const res = await fetch(path, {
|
||||
...init,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(init.headers ?? {}),
|
||||
},
|
||||
});
|
||||
if (res.status === 204) return undefined as T;
|
||||
const text = await res.text();
|
||||
const data = text ? JSON.parse(text) : undefined;
|
||||
if (!res.ok) throw new ApiError(res.status, data);
|
||||
return data as T;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
health: () => request<{ status: string; db: boolean }>('/api/health'),
|
||||
|
||||
projects: {
|
||||
list: () => request<Project[]>('/api/projects'),
|
||||
available: () => request<AvailableProject[]>('/api/projects/available'),
|
||||
add: (body: { path: string; name?: string }) =>
|
||||
request<Project>('/api/projects', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
}),
|
||||
remove: (id: string) =>
|
||||
request<void>(`/api/projects/${id}`, { method: 'DELETE' }),
|
||||
},
|
||||
|
||||
sessions: {
|
||||
listForProject: (projectId: string) =>
|
||||
request<Session[]>(`/api/projects/${projectId}/sessions`),
|
||||
create: (
|
||||
projectId: string,
|
||||
body: { name?: string; model?: string; system_prompt?: string }
|
||||
) =>
|
||||
request<Session>(`/api/projects/${projectId}/sessions`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
}),
|
||||
get: (id: string) => request<Session>(`/api/sessions/${id}`),
|
||||
update: (
|
||||
id: string,
|
||||
body: Partial<Pick<Session, 'name' | 'model' | 'system_prompt'>>
|
||||
) =>
|
||||
request<Session>(`/api/sessions/${id}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(body),
|
||||
}),
|
||||
remove: (id: string) =>
|
||||
request<void>(`/api/sessions/${id}`, { method: 'DELETE' }),
|
||||
},
|
||||
|
||||
messages: {
|
||||
list: (sessionId: string) =>
|
||||
request<Message[]>(`/api/sessions/${sessionId}/messages`),
|
||||
send: (sessionId: string, content: string) =>
|
||||
request<{ user_message_id: string; assistant_message_id: string }>(
|
||||
`/api/sessions/${sessionId}/messages`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ content }),
|
||||
}
|
||||
),
|
||||
},
|
||||
|
||||
models: () => request<ModelInfo[]>('/api/models'),
|
||||
|
||||
settings: {
|
||||
get: () => request<Record<string, unknown>>('/api/settings'),
|
||||
patch: (body: Record<string, unknown>) =>
|
||||
request<Record<string, unknown>>('/api/settings', {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(body),
|
||||
}),
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user