ltcai 7.9.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +35 -49
  2. package/docs/CHANGELOG.md +35 -0
  3. package/docs/V3_FRONTEND.md +11 -5
  4. package/lattice_brain/__init__.py +1 -1
  5. package/lattice_brain/embeddings.py +9 -1
  6. package/lattice_brain/graph/projection.py +19 -5
  7. package/lattice_brain/graph/provenance.py +26 -4
  8. package/lattice_brain/graph/write_master.py +30 -3
  9. package/lattice_brain/runtime/multi_agent.py +1 -1
  10. package/latticeai/__init__.py +1 -1
  11. package/latticeai/app_factory.py +13 -134
  12. package/latticeai/core/local_embeddings.py +8 -0
  13. package/latticeai/core/marketplace.py +1 -1
  14. package/latticeai/core/mcp_registry.py +140 -1
  15. package/latticeai/core/tool_registry.py +7 -0
  16. package/latticeai/core/workspace_os.py +1 -1
  17. package/latticeai/services/architecture_readiness.py +50 -6
  18. package/latticeai/services/model_runtime.py +36 -2
  19. package/latticeai/services/product_readiness.py +19 -17
  20. package/package.json +2 -2
  21. package/scripts/build_frontend_assets.mjs +11 -2
  22. package/src-tauri/Cargo.lock +1 -1
  23. package/src-tauri/Cargo.toml +1 -1
  24. package/src-tauri/tauri.conf.json +1 -1
  25. package/static/app/asset-manifest.json +11 -102
  26. package/static/app/assets/Act-BOO66G-c.js +1 -0
  27. package/static/app/assets/Brain-C6lEYiD7.js +321 -0
  28. package/static/app/assets/{Capture-B9Tlhzqr.js → Capture-TATXBRDw.js} +1 -2
  29. package/static/app/assets/Library-DK4FIp8a.js +1 -0
  30. package/static/app/assets/System-Bgs6Ql7x.js +1 -0
  31. package/static/app/assets/core-CwxXejkd.js +1 -2
  32. package/static/app/assets/index-Bvv79nre.js +16 -0
  33. package/static/app/assets/index-Dslqglia.css +2 -0
  34. package/static/app/assets/primitives-B70WOra0.js +1 -0
  35. package/static/app/assets/{textarea-BZk6ybp5.js → textarea-Czrd9gwM.js} +1 -2
  36. package/static/app/index.html +3 -10
  37. package/static/app/theme-boot.js +8 -0
  38. package/static/sw.js +1 -1
  39. package/frontend/index.html +0 -24
  40. package/frontend/openapi.json +0 -15425
  41. package/frontend/src/App.tsx +0 -243
  42. package/frontend/src/api/client.ts +0 -580
  43. package/frontend/src/api/openapi.ts +0 -17892
  44. package/frontend/src/components/AdminAccessGate.tsx +0 -70
  45. package/frontend/src/components/FeedbackState.tsx +0 -45
  46. package/frontend/src/components/LanguageSwitcher.tsx +0 -23
  47. package/frontend/src/components/LivingBrain.tsx +0 -220
  48. package/frontend/src/components/ProductFlow.tsx +0 -171
  49. package/frontend/src/components/WorkspaceProfileSwitcher.tsx +0 -176
  50. package/frontend/src/components/onboarding/AnalysisScreen.tsx +0 -135
  51. package/frontend/src/components/onboarding/DownloadConsentPanel.tsx +0 -29
  52. package/frontend/src/components/onboarding/InstallScreen.tsx +0 -263
  53. package/frontend/src/components/onboarding/LanguageChooser.tsx +0 -23
  54. package/frontend/src/components/onboarding/LoginScreen.tsx +0 -131
  55. package/frontend/src/components/onboarding/ProductFlowScreens.tsx +0 -13
  56. package/frontend/src/components/onboarding/RecommendationScreen.tsx +0 -116
  57. package/frontend/src/components/onboarding/recommendationModel.ts +0 -189
  58. package/frontend/src/components/primitives.tsx +0 -392
  59. package/frontend/src/components/ui/badge.tsx +0 -27
  60. package/frontend/src/components/ui/button.tsx +0 -37
  61. package/frontend/src/components/ui/card.tsx +0 -22
  62. package/frontend/src/components/ui/input.tsx +0 -16
  63. package/frontend/src/components/ui/textarea.tsx +0 -16
  64. package/frontend/src/features/admin/AdminConsole.tsx +0 -334
  65. package/frontend/src/features/brain/BrainCarePanel.tsx +0 -254
  66. package/frontend/src/features/brain/BrainComposer.tsx +0 -85
  67. package/frontend/src/features/brain/BrainConversation.tsx +0 -688
  68. package/frontend/src/features/brain/BrainGraphLayer.tsx +0 -365
  69. package/frontend/src/features/brain/BrainHome.tsx +0 -624
  70. package/frontend/src/features/brain/BrainMemoryLayer.tsx +0 -45
  71. package/frontend/src/features/brain/BrainOverviewPanel.tsx +0 -149
  72. package/frontend/src/features/brain/BrainRelationshipLayer.tsx +0 -43
  73. package/frontend/src/features/brain/DepthEmergence.tsx +0 -53
  74. package/frontend/src/features/brain/brainData.ts +0 -246
  75. package/frontend/src/features/brain/graphLayout.ts +0 -37
  76. package/frontend/src/features/brain/types.ts +0 -150
  77. package/frontend/src/features/review/ReviewCard.tsx +0 -100
  78. package/frontend/src/features/review/ReviewInbox.tsx +0 -127
  79. package/frontend/src/features/review/reviewHelpers.ts +0 -69
  80. package/frontend/src/i18n.ts +0 -1303
  81. package/frontend/src/lib/utils.ts +0 -33
  82. package/frontend/src/main.tsx +0 -23
  83. package/frontend/src/pages/Act.tsx +0 -458
  84. package/frontend/src/pages/Ask.tsx +0 -14
  85. package/frontend/src/pages/Brain.tsx +0 -914
  86. package/frontend/src/pages/Capture.tsx +0 -258
  87. package/frontend/src/pages/Library.tsx +0 -486
  88. package/frontend/src/pages/System.tsx +0 -621
  89. package/frontend/src/routes.ts +0 -92
  90. package/frontend/src/store/appStore.ts +0 -94
  91. package/frontend/src/styles.css +0 -6579
  92. package/static/app/assets/Act-DOvf59ru.js +0 -2
  93. package/static/app/assets/Act-DOvf59ru.js.map +0 -1
  94. package/static/app/assets/Brain-C7_0mEiI.js +0 -322
  95. package/static/app/assets/Brain-C7_0mEiI.js.map +0 -1
  96. package/static/app/assets/Capture-B9Tlhzqr.js.map +0 -1
  97. package/static/app/assets/Library-BJPEEm5O.js +0 -2
  98. package/static/app/assets/Library-BJPEEm5O.js.map +0 -1
  99. package/static/app/assets/System-D6t9jo9V.js +0 -2
  100. package/static/app/assets/System-D6t9jo9V.js.map +0 -1
  101. package/static/app/assets/core-CwxXejkd.js.map +0 -1
  102. package/static/app/assets/index-C7g26IF6.css +0 -2
  103. package/static/app/assets/index-DbcEYJQ2.js +0 -17
  104. package/static/app/assets/index-DbcEYJQ2.js.map +0 -1
  105. package/static/app/assets/primitives-CD38lt4n.js +0 -2
  106. package/static/app/assets/primitives-CD38lt4n.js.map +0 -1
  107. package/static/app/assets/textarea-BZk6ybp5.js.map +0 -1
@@ -1,580 +0,0 @@
1
- import createClient from "openapi-fetch";
2
- import type { components, operations, paths } from "./openapi";
3
- import { useAppStore } from "@/store/appStore";
4
-
5
- export type ApiResult<T = unknown> = {
6
- ok: boolean;
7
- status: number;
8
- data: T;
9
- source: "live" | "unavailable";
10
- error?: string;
11
- };
12
-
13
- type HttpMethod = "GET" | "POST" | "PATCH" | "DELETE";
14
- type Query = Record<string, string | number | boolean | null | undefined>;
15
- export type AdminAuditFilters = {
16
- q?: string;
17
- actor?: string;
18
- action?: string;
19
- severity?: string;
20
- limit?: number;
21
- };
22
-
23
- const TIMEOUT_MS = 10_000;
24
- type OpenApiClient = ReturnType<typeof createClient<paths>>;
25
- type OperationJson200<Operation> = Operation extends {
26
- responses: { 200: { content: { "application/json": infer Result } } };
27
- } ? Result : never;
28
- type ReviewListOperation = operations["list_items_automation_reviews_get"];
29
- type ReviewItemOperation =
30
- | operations["approve_item_automation_reviews__item_id__approve_post"]
31
- | operations["dismiss_item_automation_reviews__item_id__dismiss_post"]
32
- | operations["run_now_item_automation_reviews__item_id__run_now_post"]
33
- | operations["snooze_item_automation_reviews__item_id__snooze_post"]
34
- | operations["unsnooze_item_automation_reviews__item_id__unsnooze_post"];
35
-
36
- const clients = new Map<string, OpenApiClient>();
37
- let desktopBase: Promise<string | null> | null = null;
38
-
39
- declare global {
40
- interface Window {
41
- __TAURI_INTERNALS__?: unknown;
42
- }
43
- }
44
-
45
- function sameOriginBase() {
46
- return "";
47
- }
48
-
49
- async function tauriBackendOrigin(): Promise<string | null> {
50
- if (!window.__TAURI_INTERNALS__) return null;
51
- if (!desktopBase) {
52
- desktopBase = import("@tauri-apps/api/core")
53
- .then(({ invoke }) => invoke<string>("backend_origin"))
54
- .then((origin) => origin || null)
55
- .catch(() => null);
56
- }
57
- return desktopBase;
58
- }
59
-
60
- async function tauriInvoke<T>(command: string): Promise<T | null> {
61
- if (!window.__TAURI_INTERNALS__) return null;
62
- try {
63
- const { invoke } = await import("@tauri-apps/api/core");
64
- return await invoke<T>(command);
65
- } catch {
66
- return null;
67
- }
68
- }
69
-
70
- async function apiBase() {
71
- const stateBase = useAppStore.getState().apiBase;
72
- if (stateBase) return stateBase;
73
- const desktop = await tauriBackendOrigin();
74
- if (desktop) {
75
- useAppStore.getState().setApiBase(desktop);
76
- return desktop;
77
- }
78
- return sameOriginBase();
79
- }
80
-
81
- function clientFor(baseUrl: string) {
82
- if (!clients.has(baseUrl)) {
83
- clients.set(baseUrl, createClient<paths>({ baseUrl, credentials: "same-origin" }));
84
- }
85
- return clients.get(baseUrl)!;
86
- }
87
-
88
- function emptyFor<T>(shape: T): T {
89
- if (Array.isArray(shape)) return [] as T;
90
- if (shape && typeof shape === "object") return { ...(shape as Record<string, unknown>) } as T;
91
- return shape;
92
- }
93
-
94
- function workspaceHeaders(): Record<string, string> {
95
- const workspaceId = useAppStore.getState().workspaceId;
96
- return workspaceId ? { "X-Workspace-Id": workspaceId } : {};
97
- }
98
-
99
- function friendlyError(error: unknown, fallback: string) {
100
- if (!error) return fallback;
101
- const record = typeof error === "object" && error !== null ? error as Record<string, unknown> : null;
102
- const detail = record?.detail;
103
- if (typeof detail === "string") return detail;
104
- const detailRecord = typeof detail === "object" && detail !== null ? detail as Record<string, unknown> : null;
105
- if (detailRecord) {
106
- const message = detailRecord.user_message || detailRecord.reason || detailRecord.action || detailRecord.status;
107
- if (message) return String(message);
108
- }
109
- const message = record?.message || record?.error;
110
- if (message) return String(message);
111
- return fallback;
112
- }
113
-
114
- function friendlyCaughtError(error: unknown, fallback: string) {
115
- const message = error instanceof Error ? error.message : String(error);
116
- if (/not valid JSON|Unexpected token|JSON/i.test(message)) return fallback;
117
- if (/aborted|abort/i.test(message)) return "Request timed out. Check that the local Lattice service is running.";
118
- return message || fallback;
119
- }
120
-
121
- async function apiJson<T>(
122
- method: HttpMethod,
123
- path: string,
124
- opts: { body?: unknown; query?: Query; headers?: Record<string, string>; shape: T },
125
- ): Promise<ApiResult<T>> {
126
- const base = await apiBase();
127
- const client = clientFor(base);
128
- const ctrl = new AbortController();
129
- const timer = window.setTimeout(() => ctrl.abort(), TIMEOUT_MS);
130
- try {
131
- const request = {
132
- body: opts.body,
133
- params: { query: opts.query || {} },
134
- headers: { ...workspaceHeaders(), ...(opts.headers || {}) },
135
- signal: ctrl.signal,
136
- } as never;
137
- const call =
138
- method === "GET" ? client.GET :
139
- method === "POST" ? client.POST :
140
- method === "PATCH" ? client.PATCH :
141
- client.DELETE;
142
- const result = await (call as unknown as (p: never, r: never) => Promise<{ data?: unknown; error?: unknown; response: Response }>)(path as never, request);
143
- const { data, error, response } = result;
144
- if (response.ok && data !== undefined) {
145
- return { ok: true, status: response.status, data: data as T, source: "live" };
146
- }
147
- return {
148
- ok: false,
149
- status: response.status,
150
- data: emptyFor(opts.shape),
151
- source: "unavailable",
152
- error: friendlyError(error, response.statusText),
153
- };
154
- } catch (err) {
155
- return {
156
- ok: false,
157
- status: 0,
158
- data: emptyFor(opts.shape),
159
- source: "unavailable",
160
- error: friendlyCaughtError(err, "The local Lattice service returned an unavailable response."),
161
- };
162
- } finally {
163
- window.clearTimeout(timer);
164
- }
165
- }
166
-
167
- async function openApiJson<T>(
168
- shape: T,
169
- execute: (client: OpenApiClient, signal: AbortSignal) => Promise<{ data?: T; error?: unknown; response: Response }>,
170
- ): Promise<ApiResult<T>> {
171
- const base = await apiBase();
172
- const client = clientFor(base);
173
- const ctrl = new AbortController();
174
- const timer = window.setTimeout(() => ctrl.abort(), TIMEOUT_MS);
175
- try {
176
- const { data, error, response } = await execute(client, ctrl.signal);
177
- if (response.ok && data !== undefined) {
178
- return { ok: true, status: response.status, data, source: "live" };
179
- }
180
- return {
181
- ok: false,
182
- status: response.status,
183
- data: emptyFor(shape),
184
- source: "unavailable",
185
- error: friendlyError(error, response.statusText),
186
- };
187
- } catch (err) {
188
- return {
189
- ok: false,
190
- status: 0,
191
- data: emptyFor(shape),
192
- source: "unavailable",
193
- error: friendlyCaughtError(err, "The local Lattice service returned an unavailable response."),
194
- };
195
- } finally {
196
- window.clearTimeout(timer);
197
- }
198
- }
199
-
200
- function get<T>(path: string, shape: T, query?: Query) {
201
- return apiJson<T>("GET", path, { query, shape });
202
- }
203
-
204
- function post<T>(path: string, body: unknown, shape: T) {
205
- return apiJson<T>("POST", path, { body, shape });
206
- }
207
-
208
- function patch<T>(path: string, body: unknown, shape: T) {
209
- return apiJson<T>("PATCH", path, { body, shape });
210
- }
211
-
212
- function del<T>(path: string, shape: T) {
213
- return apiJson<T>("DELETE", path, { shape });
214
- }
215
-
216
- export type ReviewItem = components["schemas"]["ReviewItem"];
217
- export type ReviewItemList = components["schemas"]["ReviewItemList"];
218
- export type ReviewStatusFilter = "pending" | "snoozed" | "approved" | "dismissed" | "all";
219
- export type ReviewSourceFilter = "workflow_run" | "trigger" | "kg_change_digest" | "all";
220
-
221
- function reviewItemShape(): ReviewItem {
222
- return {
223
- id: "",
224
- status: "pending",
225
- effective_status: "pending",
226
- title: "",
227
- summary: "",
228
- source: "workflow_run",
229
- kind: "suggestion",
230
- payload: {},
231
- provenance: {},
232
- };
233
- }
234
-
235
- function reviewItemListShape(): ReviewItemList {
236
- return { items: [] };
237
- }
238
-
239
- function reviewList(query?: { status?: Exclude<ReviewStatusFilter, "all">; source?: Exclude<ReviewSourceFilter, "all"> }) {
240
- return openApiJson<OperationJson200<ReviewListOperation>>(
241
- reviewItemListShape(),
242
- (client, signal) => client.GET("/automation/reviews", {
243
- params: { query: query || {} },
244
- headers: workspaceHeaders(),
245
- signal,
246
- }),
247
- );
248
- }
249
-
250
- function reviewAction(
251
- id: string,
252
- action: "approve" | "dismiss" | "run_now" | "unsnooze",
253
- ) {
254
- return openApiJson<OperationJson200<ReviewItemOperation>>(
255
- reviewItemShape(),
256
- (client, signal) => {
257
- const request = {
258
- params: { path: { item_id: id } },
259
- headers: workspaceHeaders(),
260
- signal,
261
- };
262
- if (action === "approve") return client.POST("/automation/reviews/{item_id}/approve", request);
263
- if (action === "dismiss") return client.POST("/automation/reviews/{item_id}/dismiss", request);
264
- if (action === "run_now") return client.POST("/automation/reviews/{item_id}/run_now", request);
265
- return client.POST("/automation/reviews/{item_id}/unsnooze", request);
266
- },
267
- );
268
- }
269
-
270
- function snoozeReview(id: string, until: string) {
271
- return openApiJson<OperationJson200<operations["snooze_item_automation_reviews__item_id__snooze_post"]>>(
272
- reviewItemShape(),
273
- (client, signal) => client.POST("/automation/reviews/{item_id}/snooze", {
274
- params: { path: { item_id: id } },
275
- body: { until },
276
- headers: workspaceHeaders(),
277
- signal,
278
- }),
279
- );
280
- }
281
-
282
- async function uploadDocument(file: File): Promise<ApiResult<Record<string, unknown> | null>> {
283
- const base = await apiBase();
284
- const form = new FormData();
285
- form.append("file", file);
286
- try {
287
- const res = await fetch(`${base}/upload/document`, {
288
- method: "POST",
289
- credentials: "same-origin",
290
- headers: { Accept: "application/json", ...workspaceHeaders() } satisfies HeadersInit,
291
- body: form,
292
- });
293
- const data = await res.json().catch(() => null);
294
- return { ok: res.ok, status: res.status, data, source: res.ok ? "live" : "unavailable" };
295
- } catch (err) {
296
- return { ok: false, status: 0, data: null, source: "unavailable", error: String(err) };
297
- }
298
- }
299
-
300
- export type ChatEventHandlers = {
301
- onChunk?: (delta: string, fullText: string) => void;
302
- onTrace?: (trace: unknown) => void;
303
- signal?: AbortSignal;
304
- };
305
-
306
- export type ModelPrepareHandlers = {
307
- onProgress?: (data: Record<string, unknown>) => void;
308
- onDone?: (data: Record<string, unknown>) => void;
309
- onError?: (data: Record<string, unknown>) => void;
310
- signal?: AbortSignal;
311
- };
312
-
313
- async function streamModelPrepare(
314
- body: { model: string; engine?: string; allow_download?: boolean },
315
- handlers: ModelPrepareHandlers = {},
316
- ) {
317
- const base = await apiBase();
318
- const res = await fetch(`${base}/engines/prepare-model/stream`, {
319
- method: "POST",
320
- credentials: "same-origin",
321
- signal: handlers.signal,
322
- headers: {
323
- "Content-Type": "application/json",
324
- Accept: "text/event-stream",
325
- ...workspaceHeaders(),
326
- } satisfies HeadersInit,
327
- body: JSON.stringify({ engine: null, allow_download: false, ...body }),
328
- });
329
- if (!res.ok || !res.body || !(res.headers.get("content-type") || "").includes("text/event-stream")) {
330
- const payload = await res.json().catch(() => null);
331
- const detail = payload?.detail && typeof payload.detail === "object" ? payload.detail : payload;
332
- const message = friendlyError(payload, res.statusText);
333
- handlers.onError?.({ status: "error", user_message: message, ...(detail || {}) });
334
- return { source: "live" as const, ok: false, status: res.status, data: detail || {}, error: message };
335
- }
336
- const reader = res.body.getReader();
337
- const decoder = new TextDecoder();
338
- let buffer = "";
339
- let eventName = "message";
340
- let finalData: Record<string, unknown> = {};
341
- for (;;) {
342
- const { done, value } = await reader.read();
343
- if (done) break;
344
- buffer += decoder.decode(value, { stream: true });
345
- const parts = buffer.split("\n\n");
346
- buffer = parts.pop() || "";
347
- for (const part of parts) {
348
- const lines = part.split("\n");
349
- eventName = lines.find((item) => item.startsWith("event:"))?.slice(6).trim() || "message";
350
- const dataLine = lines.find((item) => item.startsWith("data:"));
351
- if (!dataLine) continue;
352
- const raw = dataLine.slice(5).trim();
353
- const data = raw ? JSON.parse(raw) as Record<string, unknown> : {};
354
- if (eventName === "progress") handlers.onProgress?.(data);
355
- if (eventName === "error") {
356
- const detail = typeof data.detail === "object" && data.detail !== null ? data.detail as Record<string, unknown> : data;
357
- handlers.onError?.(detail);
358
- return { source: "live" as const, ok: false, status: Number(data.status_code || 500), data: detail, error: friendlyError({ detail }, "Model setup failed") };
359
- }
360
- if (eventName === "done") {
361
- finalData = data;
362
- handlers.onDone?.(data);
363
- }
364
- }
365
- }
366
- return { source: "live" as const, ok: true, status: 200, data: finalData };
367
- }
368
-
369
- async function streamChat(body: Record<string, unknown>, handlers: ChatEventHandlers = {}) {
370
- const base = await apiBase();
371
- const res = await fetch(`${base}/chat`, {
372
- method: "POST",
373
- credentials: "same-origin",
374
- signal: handlers.signal,
375
- headers: {
376
- "Content-Type": "application/json",
377
- Accept: "text/event-stream",
378
- ...workspaceHeaders(),
379
- } satisfies HeadersInit,
380
- body: JSON.stringify({ stream: true, max_tokens: 2048, temperature: 0.2, ...body }),
381
- });
382
- if (!res.ok || !res.body || !(res.headers.get("content-type") || "").includes("text/event-stream")) {
383
- const payload = await res.json().catch(() => null);
384
- return { source: "live", text: "", trace: null, error: payload?.error || payload?.detail || res.statusText };
385
- }
386
- const reader = res.body.getReader();
387
- const decoder = new TextDecoder();
388
- let buffer = "";
389
- let text = "";
390
- let trace: unknown = null;
391
- for (;;) {
392
- const { done, value } = await reader.read();
393
- if (done) break;
394
- buffer += decoder.decode(value, { stream: true });
395
- const parts = buffer.split("\n\n");
396
- buffer = parts.pop() || "";
397
- for (const part of parts) {
398
- const line = part.split("\n").find((item) => item.startsWith("data:"));
399
- if (!line) continue;
400
- const raw = line.slice(5).trim();
401
- if (raw === "[DONE]") return { source: "live", text, trace };
402
- const data = JSON.parse(raw);
403
- const delta = data.chunk || data.text || "";
404
- if (delta) {
405
- text += delta;
406
- handlers.onChunk?.(delta, text);
407
- }
408
- if (data.trace) {
409
- trace = data.trace;
410
- handlers.onTrace?.(trace);
411
- }
412
- }
413
- }
414
- return { source: "live", text, trace };
415
- }
416
-
417
- export const latticeApi = {
418
- raw: get,
419
- desktopBackendStatus: async (): Promise<ApiResult<Record<string, unknown>>> => {
420
- const status = await tauriInvoke<Record<string, unknown>>("backend_status");
421
- if (status) return { ok: true, status: 200, data: status, source: "live" };
422
- return { ok: false, status: 0, data: {}, source: "unavailable", error: "Desktop backend status is available only inside the Tauri shell." };
423
- },
424
- health: () => get("/health", {}),
425
- workspaceOs: () => get("/workspace/os", { counts: {}, models: {}, workspace_registry: { workspaces: [] } }),
426
- workspaceVscodeStatus: () => get("/workspace/vscode/status", {
427
- connected: false,
428
- last_seen_ms: 0,
429
- status: "offline",
430
- index_status: "unknown",
431
- }),
432
- indexStatus: () => get("/api/index/status", {}),
433
- rebuildIndex: () => post("/api/index/rebuild", { full: false, include_nodes: true, include_chunks: true }, {}),
434
- graph: () => get("/knowledge-graph/graph", { nodes: [], edges: [] }),
435
- graphStats: () => get("/knowledge-graph/stats", { nodes: {}, edges: {}, total_nodes: 0, total_edges: 0 }),
436
- graphPortability: () => get("/api/knowledge-graph/portability", {}),
437
- brainStorage: () => get("/api/brain/storage", {}),
438
- backupHealth: () => get("/api/knowledge-graph/backup-health", {}),
439
- dockerPostgres: (body: { consent: boolean; dry_run?: boolean; port?: number }) => post("/api/brain/storage/postgres/docker", body, {}),
440
- migratePostgres: (body: { dsn: string; schema_name?: string; dry_run?: boolean }) => post("/api/brain/storage/migrate-postgres", body, {}),
441
- graphProvenance: (limit = 50) => get("/api/knowledge-graph/provenance", { items: [] }, { limit }),
442
- graphCoverage: () => get("/knowledge-graph/provenance/coverage", {}),
443
- graphExport: () => post("/api/knowledge-graph/export", {}, {}),
444
- graphBackup: () => post("/api/knowledge-graph/backup", {}, {}),
445
- graphImport: (artifact: unknown, dry_run = true) => post("/api/knowledge-graph/import", { artifact, mode: "merge", dry_run }, {}),
446
- brainArchive: (body: { path?: string | null; passphrase: string }) => post("/api/knowledge-graph/archive", body, {}),
447
- brainArchiveInspect: (body: { path: string; passphrase?: string | null }) => post("/api/knowledge-graph/archive/inspect", body, {}),
448
- brainArchiveVerify: (body: { path: string; passphrase: string }) => post("/api/knowledge-graph/archive/verify", body, {}),
449
- brainArchiveRestore: (body: { path: string; passphrase: string; dry_run?: boolean; confirm?: boolean }) => post("/api/knowledge-graph/archive/restore", body, {}),
450
- brainArchiveImport: (body: { path: string; passphrase: string; dry_run?: boolean; confirm?: boolean }) => post("/api/knowledge-graph/archive/import", body, {}),
451
- hybridSearch: async (query: string, weights?: unknown) => {
452
- const res = await post<Record<string, unknown>>("/api/search/hybrid", { query, ...(weights ? { weights } : {}) }, { matches: [] });
453
- const data = res.data as Record<string, unknown>;
454
- if (res.ok && !Array.isArray(data.matches) && Array.isArray(data.results)) {
455
- return { ...res, data: { ...data, matches: data.results } };
456
- }
457
- return res;
458
- },
459
- browserReadUrl: (url: string) => post("/api/browser/read-url", { url }, {}),
460
- ingestNote: (content: string, title = "Brain note") => post(
461
- "/knowledge-graph/ingest",
462
- { type: "note", content, title, source: "brain_home" },
463
- {},
464
- ),
465
- memoryManager: () => get("/api/memory/manager", { sources: [], tiers: [], usage: {} }),
466
- memoryBrainQuality: () => get("/api/memory/brain-quality", {}),
467
- memoryBrainProof: (query = "", limit = 3) => get("/api/memory/brain-proof", { proofs: {}, recall: { items: [] }, model_continuity: {}, claims: {} }, { q: query, limit }),
468
- memoryRecall: (query: string, limit = 20) => post("/api/memory/recall", { query, limit }, { matches: [] }),
469
- memoryCompact: () => post("/api/memory/compact", {}, {}),
470
- memoryRebuild: () => post("/api/memory/rebuild", { target: "vector" }, {}),
471
- chatHistory: () => get("/history/conversations", []),
472
- conversation: (id: string) => get(`/history/conversations/${encodeURIComponent(id)}`, { messages: [] }),
473
- deleteConversation: (id: string) => del(`/history/conversations/${encodeURIComponent(id)}`, {}),
474
- streamChat,
475
- uploadDocument,
476
- documents: (limit = 200) => get("/knowledge-graph/documents", { documents: [] }, { limit }),
477
- localSources: () => get("/knowledge-graph/local/sources", { sources: [], watch: { available: false, active: {} } }),
478
- localAgent: () => get("/api/local-agent/status", { agent: { online: false }, sources: [] }),
479
- connectFolder: (path: string) => post("/knowledge-graph/local/index", { path, approved: true, watch_enabled: true, consent: { approved: true, source: "desktop-spa" } }, {}),
480
- localWatchStop: (source_id: string) => post("/knowledge-graph/local/watch/stop", { source_id }, {}),
481
- models: () => get("/models", { catalog: [], loaded: [], recommended: [] }),
482
- setupScan: () => get("/setup/scan", { environment: {}, recommendations: {}, zero_config: {} }),
483
- modelRecommendations: (engine = "local_mlx") => get("/models/recommendations", { profile: {}, recommendations: { models: [], families: [], counts: {} } }, { engine }),
484
- installEngine: (engine: string) => post("/engines/install", { engine }, {}),
485
- prepareModel: (model: string, engine?: string, allow_download = false) => post("/engines/prepare-model", { model, engine: engine || null, allow_download }, {}),
486
- streamModelPrepare,
487
- loadModel: (model_id: string, engine?: string, allow_download = false) => post("/models/load", { model_id, engine: engine || null, allow_download }, {}),
488
- unloadModel: (model_id: string) => del(`/models/unload/${encodeURIComponent(model_id)}`, {}),
489
- embeddingsStatus: () => get("/api/embeddings/status", {}),
490
- agentRuntime: () => get("/agents/api/runtime/status", { runtime: {}, agents: [], runs: [] }),
491
- agentRunPreview: (goal: string, roles: string[] = []) => post("/agents/api/run/preview", { goal, roles }, { ready: false, blocking_reasons: [] }),
492
- runAgent: (goal: string, roles: string[]) => post("/agents/api/run", { goal, roles }, {}),
493
- toolRegistryDiagnostics: () => get("/tools/registry/diagnostics", { diagnostics: { ready: false } }),
494
- toolRegistry: () => get("/tools/registry", { status: "unavailable", diagnostics: {}, tools: [] }),
495
- agentRun: (id: string) => get(`/agents/api/runs/${encodeURIComponent(id)}`, {}),
496
- stopAgentRun: (id: string) => post(`/agents/api/runs/${encodeURIComponent(id)}/stop`, {}, {}),
497
- agentRegistry: () => get("/agents/api/registry", { agents: [] }),
498
- agentCapabilities: () => get("/agents/api/registry/capabilities", { capabilities: {} }),
499
- registerAgent: (body: unknown) => post("/agents/api/registry", body, {}),
500
- updateAgent: (id: string, body: unknown) => patch(`/agents/api/registry/${encodeURIComponent(id)}`, body, {}),
501
- removeAgent: (id: string) => del(`/agents/api/registry/${encodeURIComponent(id)}`, {}),
502
- workflowDefinitions: () => get("/workflows/api/definitions", { workflows: [] }),
503
- workflowRuns: () => get("/workflows/api/runs", { runs: [] }),
504
- workflowTriggers: () => get("/workflows/api/triggers", { armed: [] }),
505
- automationRecipes: () => get("/workflows/api/automation/recipes", { recipes: [], principles: {} }),
506
- installAutomationRecipe: (recipeId: string, enabled = false) => post(`/workflows/api/automation/recipes/${encodeURIComponent(recipeId)}`, { enabled }, {}),
507
- createWorkflow: (body: { name: string; nodes: Array<Record<string, unknown>>; metadata?: Record<string, unknown> }) => post("/workflows/api/definitions", body, {}),
508
- importWorkflow: (data: Record<string, unknown>) => post("/workflows/api/import", { data }, {}),
509
- exportWorkflow: (id: string) => get(`/workflows/api/export/${encodeURIComponent(id)}`, {}),
510
- runWorkflow: (id: string) => post(`/workflows/api/definitions/${encodeURIComponent(id)}/run`, {}, {}),
511
- updateWorkflow: (id: string, body: unknown) => patch(`/workflows/api/definitions/${encodeURIComponent(id)}`, body, {}),
512
- stopWorkflowRun: (id: string) => post(`/workflows/api/runs/${encodeURIComponent(id)}/stop`, {}, {}),
513
- resumeWorkflowRun: (id: string, approved: boolean) => post(`/workflows/api/runs/${encodeURIComponent(id)}/resume`, { approved }, {}),
514
- hooks: () => get("/api/hooks", { hooks: [] }),
515
- hookRuns: () => get("/api/hooks/runs", { runs: [] }, { limit: 50 }),
516
- hookRun: (body: unknown) => post("/api/hooks/run", body, {}),
517
- automationReviews: reviewList,
518
- approveReviewItem: (id: string) => reviewAction(id, "approve"),
519
- dismissReviewItem: (id: string) => reviewAction(id, "dismiss"),
520
- snoozeReviewItem: snoozeReview,
521
- unsnoozeReviewItem: (id: string) => reviewAction(id, "unsnooze"),
522
- runNowReviewItem: (id: string) => reviewAction(id, "run_now"),
523
- permissionsPending: () => get("/permissions/pending", { pending: {}, count: 0 }),
524
- approvePermission: (token: string) => post(`/permissions/approve/${encodeURIComponent(token)}`, {}, {}),
525
- denyPermission: (token: string) => post(`/permissions/deny/${encodeURIComponent(token)}`, {}, {}),
526
- skills: () => get("/workspace/skills", { skills: [] }),
527
- skillToggle: (skill: string, enabled: boolean) => post(enabled ? "/workspace/skills/disable" : "/workspace/skills/enable", { skill }, {}),
528
- skillsMarketplace: () => get("/skills/marketplace", { skills: [] }),
529
- skillInstall: (skill: string, plugin?: string) => post("/workspace/skills/install", { skill, plugin: plugin || "" }, {}),
530
- mcpTools: () => get("/mcp/tools", { tools: [], installed_mcps: [] }),
531
- mcpRecommend: (query: string) => post("/mcp/recommend", { query, limit: 6 }, {}),
532
- templates: () => get("/marketplace/templates", { templates: [], kinds: [] }),
533
- installTemplate: (data: unknown) => post("/marketplace/templates/install", { data }, {}),
534
- pluginsRegistry: () => get("/plugins/registry", { plugins: [] }),
535
- pluginsDirectory: () => get("/plugins/directory", { plugins: [] }),
536
- profile: () => get("/account/profile", {}),
537
- login: (email: string, password: string) => post("/login", { email, password }, {}),
538
- register: (body: unknown) => post("/register", body, {}),
539
- logout: () => post("/logout", {}, {}),
540
- updateProfile: (body: unknown) => patch("/account/profile", body, {}),
541
- changePassword: (current_password: string, new_password: string) => post("/account/change-password", { current_password, new_password }, {}),
542
- ssoConfig: () => get("/auth/sso/config", { enabled: false, providers: [] }),
543
- workspaceRegistry: () => get("/workspace/registry", { workspaces: [] }),
544
- createOrg: (name: string) => post("/workspace/orgs", { name }, {}),
545
- activateWorkspace: (workspace_id: string) => post("/workspace/activate", { workspace_id }, {}),
546
- archiveWorkspace: (workspace_id: string) => post(`/workspace/orgs/${encodeURIComponent(workspace_id)}/archive`, {}, {}),
547
- addWorkspaceMember: (workspace_id: string, user_id: string, role: string) => post(`/workspace/orgs/${encodeURIComponent(workspace_id)}/members`, { user_id, role }, {}),
548
- removeWorkspaceMember: (workspace_id: string, user_id: string) => del(`/workspace/orgs/${encodeURIComponent(workspace_id)}/members/${encodeURIComponent(user_id)}`, {}),
549
- invitations: () => get("/invitations", { invitations: [] }),
550
- createInvitation: (body: unknown) => post("/invitations", body, {}),
551
- acceptInvitation: (token: string) => post(`/invitations/${encodeURIComponent(token)}/accept`, {}, {}),
552
- snapshots: () => get("/workspace/snapshots", { snapshots: [] }),
553
- createSnapshot: (name: string) => post("/workspace/snapshots", { name }, {}),
554
- compareSnapshots: (before_id: string, after_id: string) => post("/workspace/snapshots/compare", { before_id, after_id }, {}),
555
- restoreSnapshot: (id: string) => post(`/workspace/snapshots/${encodeURIComponent(id)}/restore`, {}, {}),
556
- exportSnapshot: (id: string) => post(`/workspace/snapshots/${encodeURIComponent(id)}/export`, {}, {}),
557
- timeMachine: () => get("/workspace/time-machine", { events: [] }, { limit: 100 }),
558
- realtimeFeed: () => get("/realtime/feed", { events: [] }, { limit: 80 }),
559
- presence: () => get("/realtime/presence", { presence: [] }),
560
- networkIdentity: () => get("/network/identity", {}),
561
- networkPeers: () => get("/network/peers", { peers: [] }),
562
- pairPeer: (body: unknown) => post("/network/peers", body, {}),
563
- unpairPeer: (id: string) => del(`/network/peers/${encodeURIComponent(id)}`, {}),
564
- pushPeer: (id: string, workspace_id?: string | null) => post(`/network/push/${encodeURIComponent(id)}`, { workspace_id }, {}),
565
- sysinfo: () => get("/local/sysinfo", {}),
566
- computerMemory: () => get("/workspace/computer-memory", {}),
567
- setComputerMemory: (enabled: boolean) => post("/workspace/computer-memory", { enabled, consent: { approved: enabled } }, {}),
568
- adminSummary: () => get("/admin/summary", {}),
569
- adminStats: () => get("/admin/stats", {}),
570
- adminUsers: () => get("/admin/users", []),
571
- adminAudit: (filters?: AdminAuditFilters) => get("/admin/audit", { recent_events: [], filters: {} }, filters),
572
- adminRoles: () => get("/admin/roles", { roles: [] }),
573
- adminPolicies: () => get("/admin/policies", { policies: [] }),
574
- adminLogRetention: () => get("/admin/log-retention", {}),
575
- adminProductHardening: () => get("/admin/product-hardening", {}),
576
- adminSecurity: () => get("/admin/security/overview", {}),
577
- adminSecurityEvents: (limit = 50) => get("/admin/security/events", { events: [] }, { limit }),
578
- vpcStatus: () => get("/vpc/status", {}),
579
- toolPermissions: () => get("/tools/permissions", { permissions: [] }),
580
- };