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.
57 lines
2.1 KiB
TypeScript
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 }) }),
|
|
};
|