Files
cortex/portal/src/api.ts
omigamedev 661325a235 Add AI prompt tool for natural language graph operations
New MCP tool and portal UI for executing natural language instructions
against the memory graph via Ollama (qwen3-coder:30b). Single LLM call
generates a JSON action plan which is executed sequentially.

Supports 8 action types: add_node, update_node, remove_node, add_edge,
remove_edge, bulk_tag, reorganize, query. Actions can reference previous
results via $result[N].field interpolation. Uses /api/chat with few-shot
assistant example, format:json, and temperature:0 for reliable output.
2026-02-03 02:40:01 +01:00

57 lines
2.1 KiB
TypeScript

import type { CortexNode, CortexEdge, GraphData, NodeWithConnections, SearchResult, NodeKind, EdgeType, GroupedQueryResult, PromptResult } from './types';
const BASE = '/api';
async function request<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${BASE}${path}`, {
headers: { 'Content-Type': 'application/json' },
...init,
});
if (!res.ok) {
const body = await res.json().catch(() => ({}));
throw new Error(body.error || `HTTP ${res.status}`);
}
return res.json();
}
export const api = {
listNodes: (params?: { kind?: string; status?: string; tags?: string }) =>
request<CortexNode[]>(`/nodes?${new URLSearchParams(params as any || {})}`),
getNode: (id: string) =>
request<NodeWithConnections>(`/nodes/${id}`),
addNode: (body: { kind: NodeKind; title: string; content?: string; status?: string; tags?: string[] }) =>
request<CortexNode>('/nodes', { method: 'POST', body: JSON.stringify(body) }),
updateNode: (id: string, body: Record<string, any>) =>
request<CortexNode>(`/nodes/${id}`, { method: 'PATCH', body: JSON.stringify(body) }),
deleteNode: (id: string, hard = false) =>
request<{ ok: boolean }>(`/nodes/${id}?hard=${hard}`, { method: 'DELETE' }),
addEdge: (body: { fromId: string; toId: string; type: EdgeType }) =>
request<CortexEdge>('/edges', { method: 'POST', body: JSON.stringify(body) }),
deleteEdge: (id: string) =>
request<{ ok: boolean }>(`/edges/${id}`, { method: 'DELETE' }),
getGraph: () =>
request<GraphData>('/graph'),
search: (text: string, options?: Record<string, any>) =>
request<SearchResult[]>('/search', { method: 'POST', body: JSON.stringify({ text, options }) }),
queryOrganized: (text: string) =>
request<GroupedQueryResult>('/query/organize', { method: 'POST', body: JSON.stringify({ text }) }),
getMaintenanceStatus: () =>
request<Record<string, any>>('/maintenance/status'),
runMaintenance: () =>
request<Record<string, any>>('/maintenance/run', { method: 'POST' }),
prompt: (prompt: string) =>
request<PromptResult>('/prompt', { method: 'POST', body: JSON.stringify({ prompt }) }),
};