105 lines
3.8 KiB
TypeScript
105 lines
3.8 KiB
TypeScript
const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? '';
|
|
|
|
async function request<T>(path: string, options?: RequestInit): Promise<T> {
|
|
const url = API_BASE ? `${API_BASE}${path}` : `/api${path}`;
|
|
const res = await fetch(url, {
|
|
credentials: 'include',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
...options,
|
|
});
|
|
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
return res.json();
|
|
}
|
|
|
|
export const api = {
|
|
getSettings: () => request<Settings>('/settings'),
|
|
updateSettings: (s: Partial<Settings>) =>
|
|
request<Settings>('/settings', { method: 'POST', body: JSON.stringify(s) }),
|
|
getConversations: () => request<Conversation[]>('/conversations'),
|
|
newConversation: (title = 'New conversation') =>
|
|
request<Conversation>('/conversations', { method: 'POST', body: JSON.stringify({ title }) }),
|
|
getMessages: (id: string) => request<Message[]>(`/conversations/${id}/messages`),
|
|
renameConversation: (id: string, title: string) =>
|
|
request<Conversation>(`/conversations/${id}`, { method: 'PATCH', body: JSON.stringify({ title }) }),
|
|
deleteConversation: (id: string) =>
|
|
request<{ deleted: string }>(`/conversations/${id}`, { method: 'DELETE' }),
|
|
clearAllConversations: () =>
|
|
request<{ cleared: boolean }>('/conversations', { method: 'DELETE' }),
|
|
sendMessage: (message: string, conversation_id: string) =>
|
|
request<ChatResponse>('/chat', { method: 'POST', body: JSON.stringify({ message, conversation_id }) }),
|
|
getMemory: () => request<{ content: string }>('/memory'),
|
|
updateMemory: (content: string) =>
|
|
request<{ saved: boolean }>('/memory', { method: 'POST', body: JSON.stringify({ content }) }),
|
|
getStatus: () => request<Status>('/status'),
|
|
reindex: () => request<{ started: boolean }>('/reindex', { method: 'POST' }),
|
|
transcribe: async (audio: Blob): Promise<{ text: string }> => {
|
|
const form = new FormData();
|
|
form.append('audio', audio, 'recording.webm');
|
|
const url = '/api/transcribe';
|
|
const res = await fetch(url, { method: 'POST', credentials: 'include', body: form });
|
|
if (!res.ok) throw new Error(`Transcribe error: ${res.status}`);
|
|
return res.json();
|
|
},
|
|
capture: async (data: CapturePayload): Promise<{ saved: boolean }> => {
|
|
const form = new FormData();
|
|
if (data.audio) form.append('audio', data.audio, 'capture.webm');
|
|
if (data.image) form.append('image', data.image);
|
|
if (data.text) form.append('text', data.text);
|
|
if (data.project) form.append('project', data.project);
|
|
const url = '/api/capture';
|
|
const res = await fetch(url, { method: 'POST', credentials: 'include', body: form });
|
|
if (!res.ok) throw new Error(`Capture error: ${res.status}`);
|
|
return res.json();
|
|
},
|
|
};
|
|
|
|
export const auth = {
|
|
login: (password: string) =>
|
|
request<{ ok: boolean }>('/auth/login', { method: 'POST', body: JSON.stringify({ password }) }),
|
|
logout: () =>
|
|
request<{ ok: boolean }>('/auth/logout', { method: 'POST' }),
|
|
check: () =>
|
|
request<{ authenticated: boolean }>('/auth/check'),
|
|
};
|
|
|
|
export interface Settings {
|
|
theme: 'light' | 'dark';
|
|
font_size: 'small' | 'medium' | 'large';
|
|
web_search: boolean;
|
|
show_sources: boolean;
|
|
}
|
|
export interface Conversation {
|
|
id: string;
|
|
title: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
message_count: number;
|
|
}
|
|
export interface Message {
|
|
role: 'user' | 'assistant';
|
|
content: string;
|
|
sources: string[];
|
|
timestamp: string;
|
|
}
|
|
export interface ChatResponse {
|
|
response: string;
|
|
sources: string[];
|
|
conversation_id: string;
|
|
}
|
|
export interface Status {
|
|
aaron_ai: string;
|
|
watcher: string;
|
|
chunk_count: number;
|
|
file_count: number;
|
|
last_indexed: string;
|
|
conversation_count: number;
|
|
model: string;
|
|
nextcloud_path: string;
|
|
}
|
|
export interface CapturePayload {
|
|
audio?: Blob;
|
|
image?: File;
|
|
text?: string;
|
|
project?: string;
|
|
}
|