memoryos / src /api /client.ts
Deeraj
initial deploy
ebab9b7
Raw
History Blame Contribute Delete
6.1 kB
/**
* MemoryOS β€” Frontend API Client
*
* Typed fetch wrapper for all backend endpoints.
*/
const API_BASE = import.meta.env.VITE_API_URL || '/api/v1';
// ── Types ────────────────────────────────────────────────────────────────
export interface User {
id: string;
external_id: string;
created_at: string;
}
export interface Session {
id: string;
user_id: string;
started_at: string;
ended_at: string | null;
metadata: Record<string, unknown>;
}
export interface MemoryItem {
id: string;
user_id: string;
session_id: string | null;
memory_type: 'episodic' | 'semantic' | 'procedural';
content: string;
summary: string | null;
metadata: Record<string, unknown>;
importance: number;
recency_score: number;
access_count: number;
created_at: string;
last_accessed: string | null;
}
export interface ScoredMemory {
memory: MemoryItem;
score: number;
cosine_similarity: number;
}
export interface IngestResponse {
memory_id: string;
message: string;
}
export interface ChatResponse {
assistant_message: string;
retrieved_memories: {
id: string;
type: string;
content: string;
score: number;
}[];
}
export interface ContradictionItem {
id: string;
memory_a: string;
memory_b: string;
detected_at: string;
resolved: boolean;
memory_a_content: string | null;
memory_b_content: string | null;
}
export interface StatsOverview {
total_memories: number;
type_counts: {
episodic: number;
semantic: number;
procedural: number;
};
avg_importance: number;
avg_recency_score: number;
total_users: number;
total_sessions: number;
recent_contradictions: ContradictionItem[];
}
export interface GraphNode {
id: string;
memory_type: 'episodic' | 'semantic' | 'procedural';
content: string;
importance: number;
created_at: string;
}
export interface GraphEdge {
source: string;
target: string;
similarity: number;
}
export interface GraphData {
nodes: GraphNode[];
edges: GraphEdge[];
}
export interface SessionWithMemories extends Session {
memories: MemoryItem[];
}
// ── Fetch helper ─────────────────────────────────────────────────────────
async function apiFetch<T>(
path: string,
options: RequestInit = {}
): Promise<T> {
const url = `${API_BASE}${path}`;
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...(options.headers as Record<string, string> || {}),
};
const response = await fetch(url, { ...options, headers });
if (!response.ok) {
const body = await response.json().catch(() => ({ detail: response.statusText }));
throw new Error(body.detail || `API error: ${response.status}`);
}
return response.json();
}
// ── API functions ────────────────────────────────────────────────────────
export async function createUser(externalId: string): Promise<User> {
return apiFetch<User>('/users', {
method: 'POST',
body: JSON.stringify({ external_id: externalId }),
});
}
export async function getUser(userId: string): Promise<User> {
return apiFetch<User>(`/users/${userId}`);
}
export async function getUserContext(
userId: string,
query: string,
topK: number = 10
): Promise<ScoredMemory[]> {
const params = new URLSearchParams({ query, top_k: String(topK) });
return apiFetch<ScoredMemory[]>(`/users/${userId}/context?${params}`);
}
export async function createSession(
userId: string,
metadata: Record<string, unknown> = {}
): Promise<Session> {
return apiFetch<Session>('/sessions', {
method: 'POST',
body: JSON.stringify({ user_id: userId, metadata }),
});
}
export async function getSession(sessionId: string): Promise<SessionWithMemories> {
return apiFetch<SessionWithMemories>(`/sessions/${sessionId}`);
}
export async function endSession(sessionId: string): Promise<Session> {
return apiFetch<Session>(`/sessions/${sessionId}`, { method: 'DELETE' });
}
export async function sendChatMessage(
sessionId: string,
userMessage: string
): Promise<ChatResponse> {
return apiFetch<ChatResponse>(`/sessions/${sessionId}/chat`, {
method: 'POST',
body: JSON.stringify({ user_message: userMessage }),
});
}
export async function ingestMemory(
userId: string,
sessionId: string,
userMessage: string,
assistantMessage: string
): Promise<IngestResponse> {
return apiFetch<IngestResponse>('/memories/ingest', {
method: 'POST',
body: JSON.stringify({
user_id: userId,
session_id: sessionId,
user_message: userMessage,
assistant_message: assistantMessage,
}),
});
}
export async function searchMemories(
userId: string,
query: string,
memoryType?: string,
topK: number = 10
): Promise<ScoredMemory[]> {
const params = new URLSearchParams({
user_id: userId,
query,
top_k: String(topK),
});
if (memoryType) params.append('memory_type', memoryType);
return apiFetch<ScoredMemory[]>(`/memories/search?${params}`);
}
export async function getMemory(memoryId: string): Promise<MemoryItem> {
return apiFetch<MemoryItem>(`/memories/${memoryId}`);
}
export async function deleteMemory(memoryId: string): Promise<MemoryItem> {
return apiFetch<MemoryItem>(`/memories/${memoryId}`, { method: 'DELETE' });
}
export async function getContradictions(memoryId: string): Promise<ContradictionItem[]> {
return apiFetch<ContradictionItem[]>(`/memories/${memoryId}/contradictions`);
}
export async function getStatsOverview(): Promise<StatsOverview> {
return apiFetch<StatsOverview>('/stats/overview');
}
export async function getGraphData(userId?: string): Promise<GraphData> {
const params = userId ? `?user_id=${userId}` : '';
return apiFetch<GraphData>(`/stats/graph${params}`);
}