@trustgraph/react-state 1.7.2 → 2.0.3
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.
- package/dist/index.cjs +767 -480
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +752 -480
- package/dist/index.esm.js.map +1 -1
- package/dist/model/schema-types.d.ts +16 -0
- package/dist/model/schema-types.d.ts.map +1 -0
- package/dist/state/agent-tools.d.ts +1 -1
- package/dist/state/agent-tools.d.ts.map +1 -1
- package/dist/state/auth.d.ts +36 -0
- package/dist/state/auth.d.ts.map +1 -0
- package/dist/state/chunked-download.d.ts.map +1 -1
- package/dist/state/chunked-upload.d.ts.map +1 -1
- package/dist/state/collections.d.ts.map +1 -1
- package/dist/state/document-embeddings-query.d.ts.map +1 -1
- package/dist/state/document-metadata.d.ts +1 -1
- package/dist/state/document-metadata.d.ts.map +1 -1
- package/dist/state/embeddings.d.ts +1 -1
- package/dist/state/embeddings.d.ts.map +1 -1
- package/dist/state/explainability.d.ts +1 -1
- package/dist/state/explainability.d.ts.map +1 -1
- package/dist/state/flow-blueprints.d.ts +1 -1
- package/dist/state/flow-blueprints.d.ts.map +1 -1
- package/dist/state/flow-parameters.d.ts.map +1 -1
- package/dist/state/flows.d.ts +1 -1
- package/dist/state/flows.d.ts.map +1 -1
- package/dist/state/graph-query.d.ts +1 -1
- package/dist/state/knowledge-cores.d.ts +2 -2
- package/dist/state/knowledge-cores.d.ts.map +1 -1
- package/dist/state/library.d.ts.map +1 -1
- package/dist/state/llm-models.d.ts +2 -2
- package/dist/state/llm-models.d.ts.map +1 -1
- package/dist/state/mcp-tools.d.ts +1 -1
- package/dist/state/mcp-tools.d.ts.map +1 -1
- package/dist/state/nlp-query.d.ts.map +1 -1
- package/dist/state/ontologies.d.ts.map +1 -1
- package/dist/state/processing.d.ts.map +1 -1
- package/dist/state/prompts.d.ts.map +1 -1
- package/dist/state/provenance.d.ts +3 -2
- package/dist/state/provenance.d.ts.map +1 -1
- package/dist/state/row-embeddings-query.d.ts.map +1 -1
- package/dist/state/rows-query.d.ts.map +1 -1
- package/dist/state/schemas.d.ts.map +1 -1
- package/dist/state/settings.d.ts +1 -1
- package/dist/state/structured-query.d.ts.map +1 -1
- package/dist/state/token-costs.d.ts +2 -2
- package/dist/state/token-costs.d.ts.map +1 -1
- package/dist/state/triples.d.ts +5 -10
- package/dist/state/triples.d.ts.map +1 -1
- package/dist/state/workspace.d.ts +32 -0
- package/dist/state/workspace.d.ts.map +1 -0
- package/dist/utils/explainability.d.ts +22 -24
- package/dist/utils/explainability.d.ts.map +1 -1
- package/package.json +8 -7
package/dist/index.cjs
CHANGED
|
@@ -150,148 +150,6 @@ const useSessionStore = zustand.create()((set) => ({
|
|
|
150
150
|
})),
|
|
151
151
|
}));
|
|
152
152
|
|
|
153
|
-
const useConversation = zustand.create()((set) => ({
|
|
154
|
-
messages: [],
|
|
155
|
-
input: "",
|
|
156
|
-
chatMode: "graph-rag",
|
|
157
|
-
setMessages: (v) => set(() => ({
|
|
158
|
-
messages: v,
|
|
159
|
-
})),
|
|
160
|
-
addMessage: (role, text, type, explainSessionId) => set((state) => ({
|
|
161
|
-
messages: [
|
|
162
|
-
...state.messages,
|
|
163
|
-
{
|
|
164
|
-
role: role,
|
|
165
|
-
text: text,
|
|
166
|
-
type: type || "normal",
|
|
167
|
-
explainSessionId,
|
|
168
|
-
},
|
|
169
|
-
],
|
|
170
|
-
})),
|
|
171
|
-
updateLastMessage: (text, explainSessionId) => set((state) => {
|
|
172
|
-
if (state.messages.length === 0)
|
|
173
|
-
return state;
|
|
174
|
-
const messages = [...state.messages];
|
|
175
|
-
messages[messages.length - 1] = {
|
|
176
|
-
...messages[messages.length - 1],
|
|
177
|
-
text: text,
|
|
178
|
-
...(explainSessionId !== undefined && { explainSessionId }),
|
|
179
|
-
};
|
|
180
|
-
return { messages };
|
|
181
|
-
}),
|
|
182
|
-
setInput: (v) => set(() => ({
|
|
183
|
-
input: v,
|
|
184
|
-
})),
|
|
185
|
-
setChatMode: (mode) => set(() => ({
|
|
186
|
-
chatMode: mode,
|
|
187
|
-
})),
|
|
188
|
-
}));
|
|
189
|
-
|
|
190
|
-
// Zustand state management library for creating stores
|
|
191
|
-
/**
|
|
192
|
-
* Zustand store for managing the main workbench application state
|
|
193
|
-
* Provides centralized state management for tool navigation and entity selection
|
|
194
|
-
*/
|
|
195
|
-
const useWorkbenchStateStore = zustand.create()((set) => ({
|
|
196
|
-
// Initial state values
|
|
197
|
-
selected: undefined, // No entity selected by default
|
|
198
|
-
tool: "chat", // Default tool is the chat interface
|
|
199
|
-
entities: [], // Empty entities list by default
|
|
200
|
-
// Entity selection functions
|
|
201
|
-
setSelected: (e) => set(() => ({
|
|
202
|
-
selected: e,
|
|
203
|
-
})),
|
|
204
|
-
// Clear the current entity selection
|
|
205
|
-
unsetSelected: () => set(() => ({
|
|
206
|
-
selected: undefined,
|
|
207
|
-
})),
|
|
208
|
-
// Tool/page navigation function
|
|
209
|
-
setTool: (v) => set(() => ({
|
|
210
|
-
tool: v,
|
|
211
|
-
})),
|
|
212
|
-
// Update the list of available entities
|
|
213
|
-
setEntities: (v) => set(() => ({
|
|
214
|
-
entities: v,
|
|
215
|
-
})),
|
|
216
|
-
}));
|
|
217
|
-
|
|
218
|
-
// Zustand state management library for creating stores
|
|
219
|
-
/**
|
|
220
|
-
* Zustand store for managing document loading state
|
|
221
|
-
* Provides centralized state management for the document upload/loading workflow
|
|
222
|
-
*/
|
|
223
|
-
const useLoadStateStore = zustand.create()((set) => ({
|
|
224
|
-
// Initial state values
|
|
225
|
-
title: "", // Empty title by default
|
|
226
|
-
comments: "", // Empty comments by default
|
|
227
|
-
url: "", // Empty URL by default
|
|
228
|
-
keywords: [], // No keywords by default
|
|
229
|
-
operation: "upload-pdf", // Default operation is PDF upload
|
|
230
|
-
files: [], // No files selected by default
|
|
231
|
-
uploaded: [], // No files uploaded yet
|
|
232
|
-
text: "", // Empty text content by default
|
|
233
|
-
// Setter functions for document metadata
|
|
234
|
-
setTitle: (v) => set(() => ({
|
|
235
|
-
title: v,
|
|
236
|
-
})),
|
|
237
|
-
setComments: (v) => set(() => ({
|
|
238
|
-
comments: v,
|
|
239
|
-
})),
|
|
240
|
-
setUrl: (v) => set(() => ({
|
|
241
|
-
url: v,
|
|
242
|
-
})),
|
|
243
|
-
setKeywords: (v) => set(() => ({
|
|
244
|
-
keywords: v,
|
|
245
|
-
})),
|
|
246
|
-
// Setter function for processing operation type
|
|
247
|
-
setOperation: (v) => set(() => ({
|
|
248
|
-
operation: v,
|
|
249
|
-
})),
|
|
250
|
-
// Setter functions for file management
|
|
251
|
-
setFiles: (v) => set(() => ({
|
|
252
|
-
files: v,
|
|
253
|
-
})),
|
|
254
|
-
setUploaded: (v) => set(() => ({
|
|
255
|
-
uploaded: v,
|
|
256
|
-
})),
|
|
257
|
-
// Add a single file to the uploaded list (preserving existing uploads)
|
|
258
|
-
addUploaded: (v) => set((state) => ({
|
|
259
|
-
uploaded: [...state.uploaded, v],
|
|
260
|
-
})),
|
|
261
|
-
setText: (v) => set(() => ({
|
|
262
|
-
text: v,
|
|
263
|
-
})),
|
|
264
|
-
// Remove a specific file from the selected files list
|
|
265
|
-
removeFile: (v) => set((state) => ({
|
|
266
|
-
files: Array.from(state.files).filter((f) => f != v),
|
|
267
|
-
})),
|
|
268
|
-
// Text upload counter management
|
|
269
|
-
textUploads: 0, // Initial counter value
|
|
270
|
-
setTextUploads: (v) => set(() => ({
|
|
271
|
-
textUploads: v,
|
|
272
|
-
})),
|
|
273
|
-
// Increment the text upload counter (useful for generating unique IDs)
|
|
274
|
-
incTextUploads: () => set((state) => ({
|
|
275
|
-
textUploads: state.textUploads + 1,
|
|
276
|
-
})),
|
|
277
|
-
}));
|
|
278
|
-
|
|
279
|
-
// Zustand store for managing search functionality state
|
|
280
|
-
const useSearchStateStore = zustand.create()((set) => ({
|
|
281
|
-
// Initial state: no search results and empty search input
|
|
282
|
-
rows: [],
|
|
283
|
-
input: "",
|
|
284
|
-
// Replace the entire rows array with new search results
|
|
285
|
-
// Note: This completely overwrites the previous results
|
|
286
|
-
setRows: (v) => set(() => ({
|
|
287
|
-
rows: v,
|
|
288
|
-
})),
|
|
289
|
-
// Update the search input string (typically bound to search input field)
|
|
290
|
-
setInput: (v) => set(() => ({
|
|
291
|
-
input: v,
|
|
292
|
-
})),
|
|
293
|
-
}));
|
|
294
|
-
|
|
295
153
|
const DEFAULT_SETTINGS = {
|
|
296
154
|
user: "trustgraph", // Default user ID
|
|
297
155
|
collection: "default", // Default collection ID
|
|
@@ -477,38 +335,485 @@ const useSettings = () => {
|
|
|
477
335
|
const exportSettings = () => {
|
|
478
336
|
return JSON.stringify(settings, null, 2);
|
|
479
337
|
};
|
|
480
|
-
// Helper function to import settings from JSON
|
|
481
|
-
const importSettings = (jsonString) => {
|
|
338
|
+
// Helper function to import settings from JSON
|
|
339
|
+
const importSettings = (jsonString) => {
|
|
340
|
+
try {
|
|
341
|
+
const imported = JSON.parse(jsonString);
|
|
342
|
+
const validatedSettings = mergeWithDefaults(imported);
|
|
343
|
+
saveSettings(validatedSettings);
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
notify.error("Failed to import settings: Invalid JSON format");
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
// Return the public API for the hook
|
|
351
|
+
return {
|
|
352
|
+
// Settings data and state
|
|
353
|
+
settings,
|
|
354
|
+
isLoaded: !settingsQuery.isLoading,
|
|
355
|
+
isLoading: settingsQuery.isLoading,
|
|
356
|
+
error: settingsQuery.error,
|
|
357
|
+
// Settings operations
|
|
358
|
+
updateSetting,
|
|
359
|
+
saveSettings,
|
|
360
|
+
resetSettings,
|
|
361
|
+
exportSettings,
|
|
362
|
+
importSettings,
|
|
363
|
+
// Loading states for individual operations
|
|
364
|
+
isSaving: updateSettingsMutation.isPending,
|
|
365
|
+
isResetting: resetSettingsMutation.isPending,
|
|
366
|
+
// Manual refetch function
|
|
367
|
+
refetch: settingsQuery.refetch,
|
|
368
|
+
};
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
// Active workspace is tied to the authenticated session, so it lives in
|
|
372
|
+
// sessionStorage alongside the auth token rather than localStorage.
|
|
373
|
+
const WORKSPACE_STORAGE_KEY = "tg.workspace.active";
|
|
374
|
+
const readSession$1 = () => {
|
|
375
|
+
try {
|
|
376
|
+
return sessionStorage.getItem(WORKSPACE_STORAGE_KEY);
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
const writeSession$1 = (value) => {
|
|
383
|
+
try {
|
|
384
|
+
if (value === null)
|
|
385
|
+
sessionStorage.removeItem(WORKSPACE_STORAGE_KEY);
|
|
386
|
+
else
|
|
387
|
+
sessionStorage.setItem(WORKSPACE_STORAGE_KEY, value);
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
/* ignore */
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
const useWorkspaceStore = zustand.create((set) => ({
|
|
394
|
+
activeWorkspace: readSession$1(),
|
|
395
|
+
generation: 0,
|
|
396
|
+
initActiveWorkspace: (id) => set((s) => {
|
|
397
|
+
if (s.activeWorkspace)
|
|
398
|
+
return s;
|
|
399
|
+
writeSession$1(id);
|
|
400
|
+
return { activeWorkspace: id };
|
|
401
|
+
}),
|
|
402
|
+
setActiveWorkspace: (id) => {
|
|
403
|
+
writeSession$1(id);
|
|
404
|
+
set((s) => ({ activeWorkspace: id, generation: s.generation + 1 }));
|
|
405
|
+
},
|
|
406
|
+
bumpGeneration: () => set((s) => ({ generation: s.generation + 1 })),
|
|
407
|
+
clearActiveWorkspace: () => {
|
|
408
|
+
writeSession$1(null);
|
|
409
|
+
set({ activeWorkspace: null });
|
|
410
|
+
},
|
|
411
|
+
}));
|
|
412
|
+
// Discover the workspaces the caller can access (one for an ordinary
|
|
413
|
+
// user, all for an admin — driven entirely by what the gateway returns).
|
|
414
|
+
const useWorkspaces = () => {
|
|
415
|
+
const socket = reactProvider.useSocket();
|
|
416
|
+
const connectionState = reactProvider.useConnectionState();
|
|
417
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
418
|
+
const query = reactQuery.useQuery({
|
|
419
|
+
queryKey: ["workspaces"],
|
|
420
|
+
enabled: isSocketReady,
|
|
421
|
+
queryFn: () => socket.iam().listMyWorkspaces(),
|
|
422
|
+
});
|
|
423
|
+
return {
|
|
424
|
+
workspaces: query.data || [],
|
|
425
|
+
isLoading: query.isLoading,
|
|
426
|
+
isError: query.isError,
|
|
427
|
+
error: query.error,
|
|
428
|
+
refetch: query.refetch,
|
|
429
|
+
};
|
|
430
|
+
};
|
|
431
|
+
// The caller's own user record, including their home/default workspace.
|
|
432
|
+
const useWhoami = () => {
|
|
433
|
+
const socket = reactProvider.useSocket();
|
|
434
|
+
const connectionState = reactProvider.useConnectionState();
|
|
435
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
436
|
+
const query = reactQuery.useQuery({
|
|
437
|
+
queryKey: ["whoami"],
|
|
438
|
+
enabled: isSocketReady,
|
|
439
|
+
queryFn: () => socket.iam().whoami(),
|
|
440
|
+
});
|
|
441
|
+
return {
|
|
442
|
+
whoami: query.data,
|
|
443
|
+
isLoading: query.isLoading,
|
|
444
|
+
isError: query.isError,
|
|
445
|
+
error: query.error,
|
|
446
|
+
refetch: query.refetch,
|
|
447
|
+
};
|
|
448
|
+
};
|
|
449
|
+
// Bootstrap + keep the socket's outbound workspace in sync. Mount once,
|
|
450
|
+
// high in the tree (e.g. in the authenticated app shell).
|
|
451
|
+
const useWorkspaceSync = () => {
|
|
452
|
+
const socket = reactProvider.useSocket();
|
|
453
|
+
const activeWorkspace = useWorkspaceStore((s) => s.activeWorkspace);
|
|
454
|
+
const initActiveWorkspace = useWorkspaceStore((s) => s.initActiveWorkspace);
|
|
455
|
+
const setActiveWorkspace = useWorkspaceStore((s) => s.setActiveWorkspace);
|
|
456
|
+
const { whoami } = useWhoami();
|
|
457
|
+
const { workspaces } = useWorkspaces();
|
|
458
|
+
// Until we know the stored workspace is valid, don't stamp it on the
|
|
459
|
+
// socket — use empty string so the gateway falls back to the token's
|
|
460
|
+
// default. This prevents a stale/deleted workspace in sessionStorage
|
|
461
|
+
// from poisoning every request (including the whoami/list calls we
|
|
462
|
+
// need to detect the problem).
|
|
463
|
+
const validated = workspaces.length > 0 && activeWorkspace
|
|
464
|
+
? workspaces.some((w) => w.id === activeWorkspace)
|
|
465
|
+
: false;
|
|
466
|
+
// Adopt the user's default workspace when we have no active one yet.
|
|
467
|
+
react.useEffect(() => {
|
|
468
|
+
if (!activeWorkspace && whoami?.default_workspace) {
|
|
469
|
+
initActiveWorkspace(whoami.default_workspace);
|
|
470
|
+
}
|
|
471
|
+
}, [activeWorkspace, whoami, initActiveWorkspace]);
|
|
472
|
+
// If the stored workspace no longer exists, fall back to the user's
|
|
473
|
+
// default workspace.
|
|
474
|
+
react.useEffect(() => {
|
|
475
|
+
if (!activeWorkspace || !whoami?.default_workspace || workspaces.length === 0)
|
|
476
|
+
return;
|
|
477
|
+
if (!validated) {
|
|
478
|
+
setActiveWorkspace(whoami.default_workspace);
|
|
479
|
+
}
|
|
480
|
+
}, [activeWorkspace, workspaces, whoami, validated, setActiveWorkspace]);
|
|
481
|
+
// Only stamp a validated workspace onto the socket.
|
|
482
|
+
// Bump generation so hooks that depend on it re-fire with the
|
|
483
|
+
// workspace now set on the socket.
|
|
484
|
+
const bumpGeneration = useWorkspaceStore((s) => s.bumpGeneration);
|
|
485
|
+
react.useEffect(() => {
|
|
486
|
+
socket.workspace = validated ? activeWorkspace : "";
|
|
487
|
+
if (validated)
|
|
488
|
+
bumpGeneration();
|
|
489
|
+
}, [socket, activeWorkspace, validated, bumpGeneration]);
|
|
490
|
+
};
|
|
491
|
+
// Active workspace + the switcher action for components.
|
|
492
|
+
const useWorkspace = () => {
|
|
493
|
+
const socket = reactProvider.useSocket();
|
|
494
|
+
const queryClient = reactQuery.useQueryClient();
|
|
495
|
+
const activeWorkspace = useWorkspaceStore((s) => s.activeWorkspace);
|
|
496
|
+
const generation = useWorkspaceStore((s) => s.generation);
|
|
497
|
+
const setActiveWorkspace = useWorkspaceStore((s) => s.setActiveWorkspace);
|
|
498
|
+
const setFlowId = useSessionStore((s) => s.setFlowId);
|
|
499
|
+
const { updateSetting } = useSettings();
|
|
500
|
+
const { workspaces } = useWorkspaces();
|
|
501
|
+
const { whoami } = useWhoami();
|
|
502
|
+
// Switching workspace is a full context reset: collections, flows,
|
|
503
|
+
// documents and config all re-scope. Reset the inner context (flow +
|
|
504
|
+
// collection) to defaults and invalidate every cache so all pages
|
|
505
|
+
// refetch under the new workspace.
|
|
506
|
+
const switchWorkspace = react.useCallback((id) => {
|
|
507
|
+
if (!id || id === activeWorkspace)
|
|
508
|
+
return;
|
|
509
|
+
// Set synchronously so refetches triggered below already carry it.
|
|
510
|
+
socket.workspace = id;
|
|
511
|
+
setActiveWorkspace(id);
|
|
512
|
+
setFlowId("default");
|
|
513
|
+
updateSetting("collection", "default");
|
|
514
|
+
// Wipe workspace-scoped caches so stale data from the previous
|
|
515
|
+
// workspace can't bleed through, then invalidate to trigger refetches.
|
|
516
|
+
const keep = ["workspaces", "whoami", "settings"];
|
|
517
|
+
queryClient.removeQueries({
|
|
518
|
+
predicate: (q) => !keep.includes(q.queryKey[0]),
|
|
519
|
+
});
|
|
520
|
+
queryClient.invalidateQueries();
|
|
521
|
+
}, [
|
|
522
|
+
activeWorkspace,
|
|
523
|
+
socket,
|
|
524
|
+
setActiveWorkspace,
|
|
525
|
+
setFlowId,
|
|
526
|
+
updateSetting,
|
|
527
|
+
queryClient,
|
|
528
|
+
]);
|
|
529
|
+
return {
|
|
530
|
+
activeWorkspace,
|
|
531
|
+
workspaces,
|
|
532
|
+
defaultWorkspace: whoami?.default_workspace ?? null,
|
|
533
|
+
generation,
|
|
534
|
+
switchWorkspace,
|
|
535
|
+
};
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
const useConversation = zustand.create()((set) => ({
|
|
539
|
+
messages: [],
|
|
540
|
+
input: "",
|
|
541
|
+
chatMode: "graph-rag",
|
|
542
|
+
setMessages: (v) => set(() => ({
|
|
543
|
+
messages: v,
|
|
544
|
+
})),
|
|
545
|
+
addMessage: (role, text, type, explainSessionId) => set((state) => ({
|
|
546
|
+
messages: [
|
|
547
|
+
...state.messages,
|
|
548
|
+
{
|
|
549
|
+
role: role,
|
|
550
|
+
text: text,
|
|
551
|
+
type: type || "normal",
|
|
552
|
+
explainSessionId,
|
|
553
|
+
},
|
|
554
|
+
],
|
|
555
|
+
})),
|
|
556
|
+
updateLastMessage: (text, explainSessionId) => set((state) => {
|
|
557
|
+
if (state.messages.length === 0)
|
|
558
|
+
return state;
|
|
559
|
+
const messages = [...state.messages];
|
|
560
|
+
messages[messages.length - 1] = {
|
|
561
|
+
...messages[messages.length - 1],
|
|
562
|
+
text: text,
|
|
563
|
+
...(explainSessionId !== undefined && { explainSessionId }),
|
|
564
|
+
};
|
|
565
|
+
return { messages };
|
|
566
|
+
}),
|
|
567
|
+
setInput: (v) => set(() => ({
|
|
568
|
+
input: v,
|
|
569
|
+
})),
|
|
570
|
+
setChatMode: (mode) => set(() => ({
|
|
571
|
+
chatMode: mode,
|
|
572
|
+
})),
|
|
573
|
+
}));
|
|
574
|
+
|
|
575
|
+
// Zustand state management library for creating stores
|
|
576
|
+
/**
|
|
577
|
+
* Zustand store for managing the main workbench application state
|
|
578
|
+
* Provides centralized state management for tool navigation and entity selection
|
|
579
|
+
*/
|
|
580
|
+
const useWorkbenchStateStore = zustand.create()((set) => ({
|
|
581
|
+
// Initial state values
|
|
582
|
+
selected: undefined, // No entity selected by default
|
|
583
|
+
tool: "chat", // Default tool is the chat interface
|
|
584
|
+
entities: [], // Empty entities list by default
|
|
585
|
+
// Entity selection functions
|
|
586
|
+
setSelected: (e) => set(() => ({
|
|
587
|
+
selected: e,
|
|
588
|
+
})),
|
|
589
|
+
// Clear the current entity selection
|
|
590
|
+
unsetSelected: () => set(() => ({
|
|
591
|
+
selected: undefined,
|
|
592
|
+
})),
|
|
593
|
+
// Tool/page navigation function
|
|
594
|
+
setTool: (v) => set(() => ({
|
|
595
|
+
tool: v,
|
|
596
|
+
})),
|
|
597
|
+
// Update the list of available entities
|
|
598
|
+
setEntities: (v) => set(() => ({
|
|
599
|
+
entities: v,
|
|
600
|
+
})),
|
|
601
|
+
}));
|
|
602
|
+
|
|
603
|
+
// Zustand state management library for creating stores
|
|
604
|
+
/**
|
|
605
|
+
* Zustand store for managing document loading state
|
|
606
|
+
* Provides centralized state management for the document upload/loading workflow
|
|
607
|
+
*/
|
|
608
|
+
const useLoadStateStore = zustand.create()((set) => ({
|
|
609
|
+
// Initial state values
|
|
610
|
+
title: "", // Empty title by default
|
|
611
|
+
comments: "", // Empty comments by default
|
|
612
|
+
url: "", // Empty URL by default
|
|
613
|
+
keywords: [], // No keywords by default
|
|
614
|
+
operation: "upload-pdf", // Default operation is PDF upload
|
|
615
|
+
files: [], // No files selected by default
|
|
616
|
+
uploaded: [], // No files uploaded yet
|
|
617
|
+
text: "", // Empty text content by default
|
|
618
|
+
// Setter functions for document metadata
|
|
619
|
+
setTitle: (v) => set(() => ({
|
|
620
|
+
title: v,
|
|
621
|
+
})),
|
|
622
|
+
setComments: (v) => set(() => ({
|
|
623
|
+
comments: v,
|
|
624
|
+
})),
|
|
625
|
+
setUrl: (v) => set(() => ({
|
|
626
|
+
url: v,
|
|
627
|
+
})),
|
|
628
|
+
setKeywords: (v) => set(() => ({
|
|
629
|
+
keywords: v,
|
|
630
|
+
})),
|
|
631
|
+
// Setter function for processing operation type
|
|
632
|
+
setOperation: (v) => set(() => ({
|
|
633
|
+
operation: v,
|
|
634
|
+
})),
|
|
635
|
+
// Setter functions for file management
|
|
636
|
+
setFiles: (v) => set(() => ({
|
|
637
|
+
files: v,
|
|
638
|
+
})),
|
|
639
|
+
setUploaded: (v) => set(() => ({
|
|
640
|
+
uploaded: v,
|
|
641
|
+
})),
|
|
642
|
+
// Add a single file to the uploaded list (preserving existing uploads)
|
|
643
|
+
addUploaded: (v) => set((state) => ({
|
|
644
|
+
uploaded: [...state.uploaded, v],
|
|
645
|
+
})),
|
|
646
|
+
setText: (v) => set(() => ({
|
|
647
|
+
text: v,
|
|
648
|
+
})),
|
|
649
|
+
// Remove a specific file from the selected files list
|
|
650
|
+
removeFile: (v) => set((state) => ({
|
|
651
|
+
files: Array.from(state.files).filter((f) => f != v),
|
|
652
|
+
})),
|
|
653
|
+
// Text upload counter management
|
|
654
|
+
textUploads: 0, // Initial counter value
|
|
655
|
+
setTextUploads: (v) => set(() => ({
|
|
656
|
+
textUploads: v,
|
|
657
|
+
})),
|
|
658
|
+
// Increment the text upload counter (useful for generating unique IDs)
|
|
659
|
+
incTextUploads: () => set((state) => ({
|
|
660
|
+
textUploads: state.textUploads + 1,
|
|
661
|
+
})),
|
|
662
|
+
}));
|
|
663
|
+
|
|
664
|
+
// Zustand store for managing search functionality state
|
|
665
|
+
const useSearchStateStore = zustand.create()((set) => ({
|
|
666
|
+
// Initial state: no search results and empty search input
|
|
667
|
+
rows: [],
|
|
668
|
+
input: "",
|
|
669
|
+
// Replace the entire rows array with new search results
|
|
670
|
+
// Note: This completely overwrites the previous results
|
|
671
|
+
setRows: (v) => set(() => ({
|
|
672
|
+
rows: v,
|
|
673
|
+
})),
|
|
674
|
+
// Update the search input string (typically bound to search input field)
|
|
675
|
+
setInput: (v) => set(() => ({
|
|
676
|
+
input: v,
|
|
677
|
+
})),
|
|
678
|
+
}));
|
|
679
|
+
|
|
680
|
+
const TOKEN_STORAGE_KEY = "tg.auth.token";
|
|
681
|
+
const EXPIRES_STORAGE_KEY = "tg.auth.expires";
|
|
682
|
+
const readSession = (key) => {
|
|
683
|
+
try {
|
|
684
|
+
return sessionStorage.getItem(key);
|
|
685
|
+
}
|
|
686
|
+
catch {
|
|
687
|
+
return null;
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
const writeSession = (key, value) => {
|
|
691
|
+
try {
|
|
692
|
+
if (value === null)
|
|
693
|
+
sessionStorage.removeItem(key);
|
|
694
|
+
else
|
|
695
|
+
sessionStorage.setItem(key, value);
|
|
696
|
+
}
|
|
697
|
+
catch {
|
|
698
|
+
/* ignore */
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
const initialToken = readSession(TOKEN_STORAGE_KEY);
|
|
702
|
+
const initialExpires = readSession(EXPIRES_STORAGE_KEY);
|
|
703
|
+
const useAuthStore = zustand.create((set) => ({
|
|
704
|
+
token: initialToken,
|
|
705
|
+
jwtExpires: initialExpires,
|
|
706
|
+
status: initialToken ? "authenticated" : "idle",
|
|
707
|
+
error: null,
|
|
708
|
+
setToken: (token, expires) => {
|
|
709
|
+
writeSession(TOKEN_STORAGE_KEY, token);
|
|
710
|
+
writeSession(EXPIRES_STORAGE_KEY, expires ?? null);
|
|
711
|
+
set({
|
|
712
|
+
token,
|
|
713
|
+
jwtExpires: expires ?? null,
|
|
714
|
+
status: "authenticated",
|
|
715
|
+
error: null,
|
|
716
|
+
});
|
|
717
|
+
},
|
|
718
|
+
clearToken: () => {
|
|
719
|
+
writeSession(TOKEN_STORAGE_KEY, null);
|
|
720
|
+
writeSession(EXPIRES_STORAGE_KEY, null);
|
|
721
|
+
set({
|
|
722
|
+
token: null,
|
|
723
|
+
jwtExpires: null,
|
|
724
|
+
status: "idle",
|
|
725
|
+
error: null,
|
|
726
|
+
});
|
|
727
|
+
},
|
|
728
|
+
setStatus: (status, error) => set({ status, error: error ?? null }),
|
|
729
|
+
}));
|
|
730
|
+
// Module-level AuthApi singleton. Configurable via configureAuthApi() — the
|
|
731
|
+
// demo (or any consumer) can override URLs / fetchImpl before any hook
|
|
732
|
+
// runs.
|
|
733
|
+
let authApiSingleton = client.createAuthApi();
|
|
734
|
+
const configureAuthApi = (options) => {
|
|
735
|
+
authApiSingleton = client.createAuthApi(options);
|
|
736
|
+
};
|
|
737
|
+
const getAuthApi = () => authApiSingleton;
|
|
738
|
+
const useAuth = () => {
|
|
739
|
+
const token = useAuthStore((s) => s.token);
|
|
740
|
+
const jwtExpires = useAuthStore((s) => s.jwtExpires);
|
|
741
|
+
const status = useAuthStore((s) => s.status);
|
|
742
|
+
const error = useAuthStore((s) => s.error);
|
|
743
|
+
return {
|
|
744
|
+
token,
|
|
745
|
+
jwtExpires,
|
|
746
|
+
status,
|
|
747
|
+
error,
|
|
748
|
+
isAuthenticated: status === "authenticated" && !!token,
|
|
749
|
+
};
|
|
750
|
+
};
|
|
751
|
+
const useLogin = () => {
|
|
752
|
+
const setToken = useAuthStore((s) => s.setToken);
|
|
753
|
+
const setStatus = useAuthStore((s) => s.setStatus);
|
|
754
|
+
const status = useAuthStore((s) => s.status);
|
|
755
|
+
const error = useAuthStore((s) => s.error);
|
|
756
|
+
const login = react.useCallback(async (username, password, default_workspace) => {
|
|
757
|
+
setStatus("logging-in", null);
|
|
482
758
|
try {
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
759
|
+
const result = await getAuthApi().login(username, password, default_workspace);
|
|
760
|
+
setToken(result.jwt, result.jwtExpires);
|
|
761
|
+
return true;
|
|
486
762
|
}
|
|
487
|
-
catch (
|
|
488
|
-
|
|
489
|
-
|
|
763
|
+
catch (e) {
|
|
764
|
+
const message = e instanceof client.AuthError
|
|
765
|
+
? e.message
|
|
766
|
+
: e instanceof Error
|
|
767
|
+
? e.message
|
|
768
|
+
: "login failed";
|
|
769
|
+
setStatus("auth-failed", message);
|
|
770
|
+
return false;
|
|
490
771
|
}
|
|
491
|
-
};
|
|
492
|
-
// Return the public API for the hook
|
|
772
|
+
}, [setToken, setStatus]);
|
|
493
773
|
return {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
isLoading: settingsQuery.isLoading,
|
|
498
|
-
error: settingsQuery.error,
|
|
499
|
-
// Settings operations
|
|
500
|
-
updateSetting,
|
|
501
|
-
saveSettings,
|
|
502
|
-
resetSettings,
|
|
503
|
-
exportSettings,
|
|
504
|
-
importSettings,
|
|
505
|
-
// Loading states for individual operations
|
|
506
|
-
isSaving: updateSettingsMutation.isPending,
|
|
507
|
-
isResetting: resetSettingsMutation.isPending,
|
|
508
|
-
// Manual refetch function
|
|
509
|
-
refetch: settingsQuery.refetch,
|
|
774
|
+
login,
|
|
775
|
+
isLoading: status === "logging-in",
|
|
776
|
+
error,
|
|
510
777
|
};
|
|
511
778
|
};
|
|
779
|
+
const useLogout = () => {
|
|
780
|
+
const clearToken = useAuthStore((s) => s.clearToken);
|
|
781
|
+
return react.useCallback(() => clearToken(), [clearToken]);
|
|
782
|
+
};
|
|
783
|
+
const useBootstrapStatus = () => {
|
|
784
|
+
const [phase, setPhase] = react.useState("checking");
|
|
785
|
+
const [error, setError] = react.useState(null);
|
|
786
|
+
const cancelled = react.useRef(false);
|
|
787
|
+
const check = react.useCallback(async () => {
|
|
788
|
+
setPhase("checking");
|
|
789
|
+
setError(null);
|
|
790
|
+
try {
|
|
791
|
+
const result = await getAuthApi().bootstrapStatus();
|
|
792
|
+
if (cancelled.current)
|
|
793
|
+
return;
|
|
794
|
+
setPhase(result.bootstrapAvailable ? "needs-bootstrap" : "normal");
|
|
795
|
+
}
|
|
796
|
+
catch (e) {
|
|
797
|
+
if (cancelled.current)
|
|
798
|
+
return;
|
|
799
|
+
const message = e instanceof Error ? e.message : "bootstrap-status failed";
|
|
800
|
+
// Distinguish "service unreachable" (likely pre-bootstrap or down)
|
|
801
|
+
// from other errors. The IAM spec doesn't define a separate signal
|
|
802
|
+
// for pre-bootstrap, so we treat any failure to reach the endpoint
|
|
803
|
+
// as pre-bootstrap territory and let the operator interpret.
|
|
804
|
+
setError(message);
|
|
805
|
+
setPhase("pre-bootstrap");
|
|
806
|
+
}
|
|
807
|
+
}, []);
|
|
808
|
+
react.useEffect(() => {
|
|
809
|
+
cancelled.current = false;
|
|
810
|
+
check();
|
|
811
|
+
return () => {
|
|
812
|
+
cancelled.current = true;
|
|
813
|
+
};
|
|
814
|
+
}, [check]);
|
|
815
|
+
return { phase, error, refetch: check };
|
|
816
|
+
};
|
|
512
817
|
|
|
513
818
|
/**
|
|
514
819
|
* Custom hook for managing flow operations
|
|
@@ -524,8 +829,7 @@ const useFlows = () => {
|
|
|
524
829
|
// Hook for displaying user notifications
|
|
525
830
|
const notify = useNotification();
|
|
526
831
|
// Only enable queries when socket is connected and ready
|
|
527
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
528
|
-
connectionState?.status === "unauthenticated";
|
|
832
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
529
833
|
/**
|
|
530
834
|
* Query for fetching all flows
|
|
531
835
|
* Uses React Query for caching and background refetching
|
|
@@ -746,8 +1050,7 @@ const useLibrary = () => {
|
|
|
746
1050
|
// Hook for displaying user notifications
|
|
747
1051
|
const notify = useNotification();
|
|
748
1052
|
// Only enable queries when socket is connected and ready
|
|
749
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
750
|
-
connectionState?.status === "unauthenticated";
|
|
1053
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
751
1054
|
/**
|
|
752
1055
|
* Query for fetching all documents from the library
|
|
753
1056
|
* Uses React Query for caching and background refetching
|
|
@@ -916,57 +1219,35 @@ const useLibrary = () => {
|
|
|
916
1219
|
};
|
|
917
1220
|
};
|
|
918
1221
|
|
|
919
|
-
// @ts-nocheck
|
|
920
|
-
/**
|
|
921
|
-
* Custom hook for managing token cost operations
|
|
922
|
-
* Provides functionality for fetching, deleting, and updating token costs
|
|
923
|
-
* for AI models
|
|
924
|
-
* @returns {Object} Token cost state and operations
|
|
925
|
-
*/
|
|
926
1222
|
const useTriples = ({ flow, s, p, o, limit, collection }) => {
|
|
927
|
-
// WebSocket connection for communicating with the configuration service
|
|
928
1223
|
const socket = reactProvider.useSocket();
|
|
929
|
-
// Hook for displaying user notifications
|
|
930
1224
|
const notify = useNotification();
|
|
931
|
-
// Settings for default collection
|
|
932
1225
|
const { settings } = useSettings();
|
|
933
|
-
|
|
1226
|
+
const connectionState = reactProvider.useConnectionState();
|
|
1227
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
934
1228
|
const sessionFlowId = useSessionStore((state) => state.flowId);
|
|
935
|
-
// Use explicit param if provided, otherwise fall back to session state
|
|
936
1229
|
const effectiveFlow = flow ?? sessionFlowId;
|
|
937
|
-
|
|
938
|
-
* Query for fetching all token costs
|
|
939
|
-
* Uses React Query for caching and background refetching
|
|
940
|
-
*/
|
|
1230
|
+
const effectiveCollection = collection || settings.collection;
|
|
941
1231
|
const query = reactQuery.useQuery({
|
|
942
|
-
queryKey: ["triples", { flow: effectiveFlow, s, p, o, limit }],
|
|
1232
|
+
queryKey: ["triples", { flow: effectiveFlow, s, p, o, limit, collection: effectiveCollection }],
|
|
1233
|
+
enabled: isSocketReady,
|
|
943
1234
|
queryFn: () => {
|
|
944
1235
|
return socket
|
|
945
1236
|
.flow(effectiveFlow)
|
|
946
|
-
.triplesQuery(s, p, o, limit,
|
|
947
|
-
.then((x) => {
|
|
948
|
-
if (x["error"]) {
|
|
949
|
-
console.log("Error:", x);
|
|
950
|
-
throw x.error.message;
|
|
951
|
-
}
|
|
952
|
-
return x;
|
|
953
|
-
})
|
|
1237
|
+
.triplesQuery(s, p, o, limit, effectiveCollection)
|
|
954
1238
|
.catch((err) => {
|
|
955
|
-
|
|
956
|
-
notify.error(
|
|
1239
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1240
|
+
notify.error(message);
|
|
1241
|
+
throw err;
|
|
957
1242
|
});
|
|
958
1243
|
},
|
|
959
1244
|
});
|
|
960
|
-
// Show loading indicators for long-running operations
|
|
961
1245
|
useActivity(query.isLoading, "Loading triples");
|
|
962
|
-
// Return token cost state and operations for use in components
|
|
963
1246
|
return {
|
|
964
|
-
|
|
965
|
-
triples: query.data,
|
|
1247
|
+
triples: (query.data ?? []),
|
|
966
1248
|
isLoading: query.isLoading,
|
|
967
1249
|
isError: query.isError,
|
|
968
1250
|
error: query.error,
|
|
969
|
-
// Manual refetch function
|
|
970
1251
|
refetch: query.refetch,
|
|
971
1252
|
};
|
|
972
1253
|
};
|
|
@@ -1922,11 +2203,13 @@ const useExplainabilityStore = zustand.create()((set, get) => ({
|
|
|
1922
2203
|
/**
|
|
1923
2204
|
* Explainability utilities for parsing and structuring explain events
|
|
1924
2205
|
*/
|
|
1925
|
-
//
|
|
2206
|
+
// Predicates not yet in client library
|
|
1926
2207
|
const TG_ACTION = client.TG + "action";
|
|
1927
2208
|
const TG_ARGUMENTS = client.TG + "arguments";
|
|
1928
2209
|
const TG_SUBAGENT_GOAL = client.TG + "subagentGoal";
|
|
1929
|
-
|
|
2210
|
+
const TG_CONCEPT = client.TG_CONCEPT;
|
|
2211
|
+
const TG_ENTITY = client.TG + "entity";
|
|
2212
|
+
// RDF type URIs
|
|
1930
2213
|
const TG_AGENT_QUESTION = client.TG + "AgentQuestion";
|
|
1931
2214
|
const TG_ANALYSIS = client.TG + "Analysis";
|
|
1932
2215
|
const TG_TOOL_USE = client.TG + "ToolUse";
|
|
@@ -1934,13 +2217,14 @@ const TG_OBSERVATION = client.TG + "Observation";
|
|
|
1934
2217
|
const TG_THOUGHT_TYPE = client.TG + "Thought";
|
|
1935
2218
|
const TG_REFLECTION_TYPE = client.TG + "Reflection";
|
|
1936
2219
|
const TG_CONCLUSION = client.TG + "Conclusion";
|
|
1937
|
-
const TG_ANSWER = client.TG + "Answer";
|
|
1938
2220
|
const TG_FINDING = client.TG + "Finding";
|
|
1939
|
-
const TG_SYNTHESIS_TYPE = client.TG + "Synthesis";
|
|
1940
2221
|
const TG_DECOMPOSITION = client.TG + "Decomposition";
|
|
2222
|
+
const TG_GROUNDING = client.TG + "Grounding";
|
|
2223
|
+
const TG_EXPLORATION_TYPE = client.TG + "Exploration";
|
|
2224
|
+
const TG_FOCUS_TYPE = client.TG + "Focus";
|
|
1941
2225
|
// ── Helpers ─────────────────────────────────────────────────────────
|
|
1942
2226
|
/**
|
|
1943
|
-
* Extract event type from explainId URI (graph-rag
|
|
2227
|
+
* Extract event type from explainId URI (graph-rag fallback)
|
|
1944
2228
|
*/
|
|
1945
2229
|
function getEventType(explainId) {
|
|
1946
2230
|
if (explainId.includes("question"))
|
|
@@ -1953,9 +2237,6 @@ function getEventType(explainId) {
|
|
|
1953
2237
|
return "synthesis";
|
|
1954
2238
|
return "unknown";
|
|
1955
2239
|
}
|
|
1956
|
-
/**
|
|
1957
|
-
* Get term value from a Term object
|
|
1958
|
-
*/
|
|
1959
2240
|
function getTermValue$1(term) {
|
|
1960
2241
|
if (!term)
|
|
1961
2242
|
return "";
|
|
@@ -1964,7 +2245,6 @@ function getTermValue$1(term) {
|
|
|
1964
2245
|
if (term.t === "l")
|
|
1965
2246
|
return term.v || "";
|
|
1966
2247
|
if (term.t === "t" && term.tr) {
|
|
1967
|
-
// Quoted triple - return a serialized form
|
|
1968
2248
|
const s = getTermValue$1(term.tr.s);
|
|
1969
2249
|
const p = getTermValue$1(term.tr.p);
|
|
1970
2250
|
const o = getTermValue$1(term.tr.o);
|
|
@@ -1972,9 +2252,6 @@ function getTermValue$1(term) {
|
|
|
1972
2252
|
}
|
|
1973
2253
|
return "";
|
|
1974
2254
|
}
|
|
1975
|
-
/**
|
|
1976
|
-
* Extract quoted triple from a Term
|
|
1977
|
-
*/
|
|
1978
2255
|
function extractQuotedTriple(term) {
|
|
1979
2256
|
if (term.t === "t" && term.tr) {
|
|
1980
2257
|
return {
|
|
@@ -1985,9 +2262,15 @@ function extractQuotedTriple(term) {
|
|
|
1985
2262
|
}
|
|
1986
2263
|
return null;
|
|
1987
2264
|
}
|
|
1988
|
-
// ──
|
|
1989
|
-
/**
|
|
1990
|
-
|
|
2265
|
+
// ── RDF type detection ──────────────────────────────────────────────
|
|
2266
|
+
/**
|
|
2267
|
+
* Map RDF type URI → event type (first match wins).
|
|
2268
|
+
* Agent-specific types only — shared types like tg:Synthesis and
|
|
2269
|
+
* tg:Answer are excluded to avoid catching graph-rag events.
|
|
2270
|
+
* Grounding, Exploration, Focus are included since they now carry
|
|
2271
|
+
* embedded triples with their RDF type.
|
|
2272
|
+
*/
|
|
2273
|
+
const RDF_TYPE_CHECKS = [
|
|
1991
2274
|
[TG_AGENT_QUESTION, "agent-question"],
|
|
1992
2275
|
[TG_DECOMPOSITION, "decomposition"],
|
|
1993
2276
|
[TG_ANALYSIS, "analysis"],
|
|
@@ -1997,12 +2280,12 @@ const AGENT_TYPE_CHECKS = [
|
|
|
1997
2280
|
[TG_REFLECTION_TYPE, "reflection"],
|
|
1998
2281
|
[TG_CONCLUSION, "conclusion"],
|
|
1999
2282
|
[TG_FINDING, "conclusion"],
|
|
2000
|
-
[
|
|
2001
|
-
[
|
|
2283
|
+
[TG_GROUNDING, "grounding"],
|
|
2284
|
+
[TG_EXPLORATION_TYPE, "exploration"],
|
|
2285
|
+
[TG_FOCUS_TYPE, "focus"],
|
|
2002
2286
|
];
|
|
2003
2287
|
/**
|
|
2004
2288
|
* Detect event type from RDF types in embedded triples.
|
|
2005
|
-
* Returns an agent event type if matched, "unknown" otherwise.
|
|
2006
2289
|
*/
|
|
2007
2290
|
function getEventTypeFromTriples(triples) {
|
|
2008
2291
|
const types = new Set();
|
|
@@ -2011,7 +2294,7 @@ function getEventTypeFromTriples(triples) {
|
|
|
2011
2294
|
types.add(getTermValue$1(t.o));
|
|
2012
2295
|
}
|
|
2013
2296
|
}
|
|
2014
|
-
for (const [typeUri, eventType] of
|
|
2297
|
+
for (const [typeUri, eventType] of RDF_TYPE_CHECKS) {
|
|
2015
2298
|
if (types.has(typeUri))
|
|
2016
2299
|
return eventType;
|
|
2017
2300
|
}
|
|
@@ -2031,38 +2314,69 @@ function extractCommonFields(triples) {
|
|
|
2031
2314
|
}
|
|
2032
2315
|
return { label, derivedFrom };
|
|
2033
2316
|
}
|
|
2034
|
-
|
|
2317
|
+
/**
|
|
2318
|
+
* Extract inline edges from triples (tg:edge quoted triples + concept/score).
|
|
2319
|
+
* Groups by edge selection subject URI to associate edge, concept, and score.
|
|
2320
|
+
* Returns SelectedEdge objects with URIs — labels resolved later.
|
|
2321
|
+
*/
|
|
2322
|
+
function extractInlineEdges(triples) {
|
|
2323
|
+
const bySubject = new Map();
|
|
2324
|
+
for (const t of triples) {
|
|
2325
|
+
const s = getTermValue$1(t.s);
|
|
2326
|
+
const p = getTermValue$1(t.p);
|
|
2327
|
+
if (p === client.TG_EDGE && t.o.t === "t" && t.o.tr) {
|
|
2328
|
+
const edge = extractQuotedTriple(t.o);
|
|
2329
|
+
if (edge) {
|
|
2330
|
+
const existing = bySubject.get(s) || { edge };
|
|
2331
|
+
existing.edge = edge;
|
|
2332
|
+
bySubject.set(s, existing);
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
else if (p === TG_CONCEPT) {
|
|
2336
|
+
const concept = getTermValue$1(t.o);
|
|
2337
|
+
if (concept) {
|
|
2338
|
+
const existing = bySubject.get(s) || { edge: { s: "", p: "", o: "" } };
|
|
2339
|
+
existing.concept = concept;
|
|
2340
|
+
bySubject.set(s, existing);
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
else if (p === client.TG_SCORE) {
|
|
2344
|
+
const scoreStr = getTermValue$1(t.o);
|
|
2345
|
+
if (scoreStr) {
|
|
2346
|
+
const existing = bySubject.get(s) || { edge: { s: "", p: "", o: "" } };
|
|
2347
|
+
existing.score = parseFloat(scoreStr);
|
|
2348
|
+
bySubject.set(s, existing);
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
return Array.from(bySubject.values()).filter(se => se.edge.s !== "");
|
|
2353
|
+
}
|
|
2354
|
+
// ── Parsers ─────────────────────────────────────────────────────────
|
|
2035
2355
|
function parseQuestionTriples(explainId, explainGraph, triples) {
|
|
2036
|
-
const event = {
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
for (const triple of triples) {
|
|
2042
|
-
const p = getTermValue$1(triple.p);
|
|
2043
|
-
const o = getTermValue$1(triple.o);
|
|
2044
|
-
if (p === client.TG_QUERY) {
|
|
2356
|
+
const event = { type: "question", explainId, explainGraph };
|
|
2357
|
+
for (const t of triples) {
|
|
2358
|
+
const p = getTermValue$1(t.p);
|
|
2359
|
+
const o = getTermValue$1(t.o);
|
|
2360
|
+
if (p === client.TG_QUERY)
|
|
2045
2361
|
event.query = o;
|
|
2046
|
-
|
|
2047
|
-
else if (p === client.PROV_STARTED_AT_TIME) {
|
|
2362
|
+
else if (p === client.PROV_STARTED_AT_TIME)
|
|
2048
2363
|
event.timestamp = o;
|
|
2049
|
-
}
|
|
2050
2364
|
}
|
|
2051
2365
|
return event;
|
|
2052
2366
|
}
|
|
2053
2367
|
function parseExplorationTriples(explainId, explainGraph, triples) {
|
|
2054
|
-
const event = {
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
const p = getTermValue$1(triple.p);
|
|
2061
|
-
const o = getTermValue$1(triple.o);
|
|
2062
|
-
if (p === client.TG_EDGE_COUNT) {
|
|
2368
|
+
const event = { type: "exploration", explainId, explainGraph };
|
|
2369
|
+
const entities = [];
|
|
2370
|
+
for (const t of triples) {
|
|
2371
|
+
const p = getTermValue$1(t.p);
|
|
2372
|
+
const o = getTermValue$1(t.o);
|
|
2373
|
+
if (p === client.TG_EDGE_COUNT)
|
|
2063
2374
|
event.edgeCount = parseInt(o, 10);
|
|
2064
|
-
|
|
2375
|
+
if (p === TG_ENTITY && o)
|
|
2376
|
+
entities.push(o);
|
|
2065
2377
|
}
|
|
2378
|
+
if (entities.length > 0)
|
|
2379
|
+
event.entities = entities;
|
|
2066
2380
|
return event;
|
|
2067
2381
|
}
|
|
2068
2382
|
function parseFocusTriples(explainId, explainGraph, triples) {
|
|
@@ -2072,53 +2386,64 @@ function parseFocusTriples(explainId, explainGraph, triples) {
|
|
|
2072
2386
|
explainGraph,
|
|
2073
2387
|
edgeSelectionUris: [],
|
|
2074
2388
|
};
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
const
|
|
2389
|
+
// Collect edge selection URIs (old format)
|
|
2390
|
+
for (const t of triples) {
|
|
2391
|
+
const p = getTermValue$1(t.p);
|
|
2392
|
+
const o = getTermValue$1(t.o);
|
|
2078
2393
|
if (p === client.TG_SELECTED_EDGE && typeof o === "string") {
|
|
2079
2394
|
event.edgeSelectionUris.push(o);
|
|
2080
2395
|
}
|
|
2081
2396
|
}
|
|
2397
|
+
// Extract inline edges (new format: tg:edge with quoted triples)
|
|
2398
|
+
const inlineEdges = extractInlineEdges(triples);
|
|
2399
|
+
if (inlineEdges.length > 0) {
|
|
2400
|
+
event.selectedEdges = inlineEdges;
|
|
2401
|
+
}
|
|
2082
2402
|
return event;
|
|
2083
2403
|
}
|
|
2084
2404
|
function parseSynthesisTriples(explainId, explainGraph, triples) {
|
|
2085
|
-
const event = {
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
for (const triple of triples) {
|
|
2091
|
-
const p = getTermValue$1(triple.p);
|
|
2092
|
-
const o = getTermValue$1(triple.o);
|
|
2093
|
-
if (p === client.TG_CONTENT) {
|
|
2405
|
+
const event = { type: "synthesis", explainId, explainGraph };
|
|
2406
|
+
for (const t of triples) {
|
|
2407
|
+
const p = getTermValue$1(t.p);
|
|
2408
|
+
const o = getTermValue$1(t.o);
|
|
2409
|
+
if (p === client.TG_CONTENT)
|
|
2094
2410
|
event.contentLength = o.length;
|
|
2095
|
-
}
|
|
2096
2411
|
}
|
|
2097
2412
|
return event;
|
|
2098
2413
|
}
|
|
2099
2414
|
function parseEdgeSelectionTriples(triples) {
|
|
2100
2415
|
let edge = null;
|
|
2101
|
-
let
|
|
2416
|
+
let concept = null;
|
|
2417
|
+
let score = null;
|
|
2102
2418
|
for (const triple of triples) {
|
|
2103
2419
|
const p = getTermValue$1(triple.p);
|
|
2104
|
-
if (p === client.TG_EDGE)
|
|
2420
|
+
if (p === client.TG_EDGE)
|
|
2105
2421
|
edge = extractQuotedTriple(triple.o);
|
|
2422
|
+
else if (p === TG_CONCEPT)
|
|
2423
|
+
concept = getTermValue$1(triple.o);
|
|
2424
|
+
else if (p === client.TG_SCORE) {
|
|
2425
|
+
const v = getTermValue$1(triple.o);
|
|
2426
|
+
if (v)
|
|
2427
|
+
score = parseFloat(v);
|
|
2106
2428
|
}
|
|
2107
|
-
else if (p === client.TG_REASONING) {
|
|
2108
|
-
reasoning = getTermValue$1(triple.o);
|
|
2109
|
-
}
|
|
2110
2429
|
}
|
|
2111
|
-
return { edge,
|
|
2430
|
+
return { edge, concept, score };
|
|
2431
|
+
}
|
|
2432
|
+
function parseGroundingTriples(explainId, explainGraph, triples) {
|
|
2433
|
+
const { label, derivedFrom } = extractCommonFields(triples);
|
|
2434
|
+
const concepts = [];
|
|
2435
|
+
for (const t of triples) {
|
|
2436
|
+
const p = getTermValue$1(t.p);
|
|
2437
|
+
const o = getTermValue$1(t.o);
|
|
2438
|
+
if (p === TG_CONCEPT && o)
|
|
2439
|
+
concepts.push(o);
|
|
2440
|
+
}
|
|
2441
|
+
return { type: "grounding", explainId, explainGraph, label, concepts, derivedFrom };
|
|
2112
2442
|
}
|
|
2113
|
-
// ── Agent parsers (new) ─────────────────────────────────────────────
|
|
2114
2443
|
function parseAgentQuestionTriples(explainId, explainGraph, triples) {
|
|
2115
2444
|
const { label, derivedFrom } = extractCommonFields(triples);
|
|
2116
2445
|
const event = {
|
|
2117
|
-
type: "agent-question",
|
|
2118
|
-
explainId,
|
|
2119
|
-
explainGraph,
|
|
2120
|
-
label,
|
|
2121
|
-
derivedFrom,
|
|
2446
|
+
type: "agent-question", explainId, explainGraph, label, derivedFrom,
|
|
2122
2447
|
};
|
|
2123
2448
|
for (const t of triples) {
|
|
2124
2449
|
const p = getTermValue$1(t.p);
|
|
@@ -2139,23 +2464,12 @@ function parseDecompositionTriples(explainId, explainGraph, triples) {
|
|
|
2139
2464
|
if (p === TG_SUBAGENT_GOAL && o)
|
|
2140
2465
|
goals.push(o);
|
|
2141
2466
|
}
|
|
2142
|
-
return {
|
|
2143
|
-
type: "decomposition",
|
|
2144
|
-
explainId,
|
|
2145
|
-
explainGraph,
|
|
2146
|
-
label,
|
|
2147
|
-
goals,
|
|
2148
|
-
derivedFrom,
|
|
2149
|
-
};
|
|
2467
|
+
return { type: "decomposition", explainId, explainGraph, label, goals, derivedFrom };
|
|
2150
2468
|
}
|
|
2151
2469
|
function parseAnalysisTriples(explainId, explainGraph, triples) {
|
|
2152
2470
|
const { label, derivedFrom } = extractCommonFields(triples);
|
|
2153
2471
|
const event = {
|
|
2154
|
-
type: "analysis",
|
|
2155
|
-
explainId,
|
|
2156
|
-
explainGraph,
|
|
2157
|
-
label,
|
|
2158
|
-
derivedFrom,
|
|
2472
|
+
type: "analysis", explainId, explainGraph, label, derivedFrom,
|
|
2159
2473
|
};
|
|
2160
2474
|
for (const t of triples) {
|
|
2161
2475
|
const p = getTermValue$1(t.p);
|
|
@@ -2169,34 +2483,22 @@ function parseAnalysisTriples(explainId, explainGraph, triples) {
|
|
|
2169
2483
|
}
|
|
2170
2484
|
function parseReflectionTriples(explainId, explainGraph, triples) {
|
|
2171
2485
|
const { label, derivedFrom } = extractCommonFields(triples);
|
|
2172
|
-
return {
|
|
2173
|
-
type: "reflection",
|
|
2174
|
-
explainId,
|
|
2175
|
-
explainGraph,
|
|
2176
|
-
label,
|
|
2177
|
-
derivedFrom,
|
|
2178
|
-
};
|
|
2486
|
+
return { type: "reflection", explainId, explainGraph, label, derivedFrom };
|
|
2179
2487
|
}
|
|
2180
2488
|
function parseConclusionTriples(explainId, explainGraph, triples) {
|
|
2181
2489
|
const { label, derivedFrom } = extractCommonFields(triples);
|
|
2182
|
-
return {
|
|
2183
|
-
type: "conclusion",
|
|
2184
|
-
explainId,
|
|
2185
|
-
explainGraph,
|
|
2186
|
-
label,
|
|
2187
|
-
derivedFrom,
|
|
2188
|
-
};
|
|
2490
|
+
return { type: "conclusion", explainId, explainGraph, label, derivedFrom };
|
|
2189
2491
|
}
|
|
2190
2492
|
// ── Unified parser ──────────────────────────────────────────────────
|
|
2191
2493
|
/**
|
|
2192
2494
|
* Parse triples into a structured event.
|
|
2193
|
-
* Tries RDF type detection first
|
|
2194
|
-
* Returns null for events with no triples
|
|
2495
|
+
* Tries RDF type detection first, then URI patterns as fallback.
|
|
2496
|
+
* Returns null for events with no triples.
|
|
2195
2497
|
*/
|
|
2196
2498
|
function parseExplainTriples(explainId, explainGraph, triples) {
|
|
2197
2499
|
if (triples.length === 0)
|
|
2198
2500
|
return null;
|
|
2199
|
-
// Try RDF type detection first
|
|
2501
|
+
// Try RDF type detection first
|
|
2200
2502
|
const rdfEventType = getEventTypeFromTriples(triples);
|
|
2201
2503
|
if (rdfEventType !== "unknown") {
|
|
2202
2504
|
switch (rdfEventType) {
|
|
@@ -2210,6 +2512,12 @@ function parseExplainTriples(explainId, explainGraph, triples) {
|
|
|
2210
2512
|
return parseReflectionTriples(explainId, explainGraph, triples);
|
|
2211
2513
|
case "conclusion":
|
|
2212
2514
|
return parseConclusionTriples(explainId, explainGraph, triples);
|
|
2515
|
+
case "grounding":
|
|
2516
|
+
return parseGroundingTriples(explainId, explainGraph, triples);
|
|
2517
|
+
case "exploration":
|
|
2518
|
+
return parseExplorationTriples(explainId, explainGraph, triples);
|
|
2519
|
+
case "focus":
|
|
2520
|
+
return parseFocusTriples(explainId, explainGraph, triples);
|
|
2213
2521
|
}
|
|
2214
2522
|
}
|
|
2215
2523
|
// Fall back to URI pattern detection (graph-rag events)
|
|
@@ -2230,8 +2538,10 @@ function parseExplainTriples(explainId, explainGraph, triples) {
|
|
|
2230
2538
|
|
|
2231
2539
|
/**
|
|
2232
2540
|
* Hook for tracing provenance chains in the knowledge graph
|
|
2233
|
-
* Follows
|
|
2541
|
+
* Follows tg:contains to find subgraphs, then prov:wasDerivedFrom
|
|
2542
|
+
* to trace chunk → page → document chains
|
|
2234
2543
|
*/
|
|
2544
|
+
const TG_CONTAINS = client.TG + "contains";
|
|
2235
2545
|
/**
|
|
2236
2546
|
* Hook for tracing provenance chains
|
|
2237
2547
|
*/
|
|
@@ -2248,8 +2558,7 @@ const useProvenance = (options = {}) => {
|
|
|
2248
2558
|
* Check if connected
|
|
2249
2559
|
*/
|
|
2250
2560
|
const isConnected = react.useCallback(() => {
|
|
2251
|
-
return (connectionState?.status === "authenticated"
|
|
2252
|
-
connectionState?.status === "unauthenticated");
|
|
2561
|
+
return (connectionState?.status === "authenticated");
|
|
2253
2562
|
}, [connectionState]);
|
|
2254
2563
|
/**
|
|
2255
2564
|
* Query for rdfs:label of a URI
|
|
@@ -2328,13 +2637,13 @@ const useProvenance = (options = {}) => {
|
|
|
2328
2637
|
}
|
|
2329
2638
|
}, [maxDepth, resolveLabel, queryDerivedFrom]);
|
|
2330
2639
|
/**
|
|
2331
|
-
*
|
|
2640
|
+
* Find subgraphs that contain an edge via tg:contains with a quoted triple
|
|
2332
2641
|
*/
|
|
2333
|
-
const
|
|
2642
|
+
const queryContainingSubgraphs = react.useCallback(async (s, p, o) => {
|
|
2334
2643
|
if (!isConnected())
|
|
2335
2644
|
return [];
|
|
2336
2645
|
try {
|
|
2337
|
-
// Build the quoted triple term
|
|
2646
|
+
// Build the quoted triple term for the edge
|
|
2338
2647
|
const quotedTriple = {
|
|
2339
2648
|
t: "t",
|
|
2340
2649
|
tr: {
|
|
@@ -2347,7 +2656,7 @@ const useProvenance = (options = {}) => {
|
|
|
2347
2656
|
};
|
|
2348
2657
|
const triples = await socket
|
|
2349
2658
|
.flow(effectiveFlow)
|
|
2350
|
-
.triplesQuery(undefined, { t: "i", i:
|
|
2659
|
+
.triplesQuery(undefined, { t: "i", i: TG_CONTAINS }, quotedTriple, 10, collection);
|
|
2351
2660
|
return triples.map((t) => getTermValue$1(t.s));
|
|
2352
2661
|
}
|
|
2353
2662
|
catch {
|
|
@@ -2355,20 +2664,21 @@ const useProvenance = (options = {}) => {
|
|
|
2355
2664
|
}
|
|
2356
2665
|
}, [socket, effectiveFlow, collection, isConnected]);
|
|
2357
2666
|
/**
|
|
2358
|
-
* Trace provenance for an edge
|
|
2667
|
+
* Trace provenance for an edge — find containing subgraph, then follow
|
|
2668
|
+
* wasDerivedFrom chain: subgraph → chunk → page → document
|
|
2359
2669
|
*/
|
|
2360
2670
|
const traceEdgeProvenance = react.useCallback(async (s, p, o) => {
|
|
2361
2671
|
setIsTracing(true);
|
|
2362
2672
|
try {
|
|
2363
|
-
// Find
|
|
2364
|
-
const
|
|
2365
|
-
// For each reifying statement, trace its provenance chain
|
|
2673
|
+
// Find subgraphs containing this edge
|
|
2674
|
+
const subgraphUris = await queryContainingSubgraphs(s, p, o);
|
|
2366
2675
|
const chains = [];
|
|
2367
|
-
for (const
|
|
2368
|
-
//
|
|
2369
|
-
const
|
|
2370
|
-
if (
|
|
2371
|
-
|
|
2676
|
+
for (const subgraphUri of subgraphUris) {
|
|
2677
|
+
// Follow wasDerivedFrom from the subgraph to the chunk
|
|
2678
|
+
const chunkUri = await queryDerivedFrom(subgraphUri);
|
|
2679
|
+
if (chunkUri) {
|
|
2680
|
+
// Trace the full chain from chunk upward
|
|
2681
|
+
const chain = await traceChain(chunkUri);
|
|
2372
2682
|
chains.push(chain);
|
|
2373
2683
|
}
|
|
2374
2684
|
}
|
|
@@ -2377,7 +2687,7 @@ const useProvenance = (options = {}) => {
|
|
|
2377
2687
|
finally {
|
|
2378
2688
|
setIsTracing(false);
|
|
2379
2689
|
}
|
|
2380
|
-
}, [
|
|
2690
|
+
}, [queryContainingSubgraphs, queryDerivedFrom, traceChain]);
|
|
2381
2691
|
/**
|
|
2382
2692
|
* Clear the label cache
|
|
2383
2693
|
*/
|
|
@@ -2434,12 +2744,13 @@ const useExplainability = (options = {}) => {
|
|
|
2434
2744
|
const resolveEdge = react.useCallback(async (edgeSelUri, allTriples) => {
|
|
2435
2745
|
// Filter embedded triples for this edge selection URI
|
|
2436
2746
|
const edgeTriples = allTriples.filter((t) => getTermValue$1(t.s) === edgeSelUri);
|
|
2437
|
-
const { edge,
|
|
2747
|
+
const { edge, concept, score } = parseEdgeSelectionTriples(edgeTriples);
|
|
2438
2748
|
if (!edge)
|
|
2439
2749
|
return null;
|
|
2440
2750
|
const selectedEdge = {
|
|
2441
2751
|
edge,
|
|
2442
|
-
|
|
2752
|
+
concept: concept || undefined,
|
|
2753
|
+
score: score ?? undefined,
|
|
2443
2754
|
};
|
|
2444
2755
|
// Kick off label resolution and provenance in parallel
|
|
2445
2756
|
const [labels, provenanceChains] = await Promise.all([
|
|
@@ -2479,56 +2790,82 @@ const useExplainability = (options = {}) => {
|
|
|
2479
2790
|
setSession(updater);
|
|
2480
2791
|
onUpdateRef.current?.(sessionRef.current);
|
|
2481
2792
|
}, []);
|
|
2482
|
-
const
|
|
2793
|
+
const AGENT_STEP_TYPES = new Set([
|
|
2483
2794
|
"agent-question", "decomposition", "analysis", "reflection", "conclusion",
|
|
2795
|
+
"grounding",
|
|
2484
2796
|
]);
|
|
2797
|
+
/**
|
|
2798
|
+
* Resolve labels for inline edges (edges already extracted, just need labels)
|
|
2799
|
+
*/
|
|
2800
|
+
const resolveEdgeLabels = react.useCallback(async (focusEvent) => {
|
|
2801
|
+
if (!focusEvent.selectedEdges || focusEvent.selectedEdges.length === 0) {
|
|
2802
|
+
return focusEvent;
|
|
2803
|
+
}
|
|
2804
|
+
const resolved = await Promise.all(focusEvent.selectedEdges.map(async (se) => {
|
|
2805
|
+
const [sLabel, pLabel, oLabel] = await Promise.all([
|
|
2806
|
+
resolveLabel(se.edge.s),
|
|
2807
|
+
resolveLabel(se.edge.p),
|
|
2808
|
+
resolveLabel(se.edge.o),
|
|
2809
|
+
]);
|
|
2810
|
+
let sources;
|
|
2811
|
+
if (traceProvenance) {
|
|
2812
|
+
const chains = await traceEdgeProvenance(se.edge.s, se.edge.p, se.edge.o);
|
|
2813
|
+
if (chains.length > 0) {
|
|
2814
|
+
sources = chains.map((c) => c.chain).flat();
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
return {
|
|
2818
|
+
...se,
|
|
2819
|
+
labels: { s: sLabel, p: pLabel, o: oLabel },
|
|
2820
|
+
sources,
|
|
2821
|
+
};
|
|
2822
|
+
}));
|
|
2823
|
+
return { ...focusEvent, selectedEdges: resolved };
|
|
2824
|
+
}, [resolveLabel, traceProvenance, traceEdgeProvenance]);
|
|
2485
2825
|
/**
|
|
2486
2826
|
* Process a single explain event
|
|
2487
2827
|
*/
|
|
2488
2828
|
const processEvent = react.useCallback(async (event) => {
|
|
2489
|
-
// Use embedded triples directly from the event
|
|
2490
2829
|
const triples = event.explainTriples ?? [];
|
|
2491
|
-
// Parse into structured data
|
|
2492
2830
|
const parsed = parseExplainTriples(event.explainId, event.explainGraph, triples);
|
|
2493
2831
|
if (!parsed)
|
|
2494
2832
|
return;
|
|
2495
|
-
if (
|
|
2496
|
-
// Agent
|
|
2833
|
+
if (AGENT_STEP_TYPES.has(parsed.type)) {
|
|
2834
|
+
// Agent step — append to timeline
|
|
2497
2835
|
updateSession((prev) => ({
|
|
2498
2836
|
...prev,
|
|
2499
2837
|
agentSteps: [...(prev.agentSteps || []), parsed],
|
|
2500
2838
|
}));
|
|
2501
2839
|
}
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
break;
|
|
2840
|
+
// Graph-RAG fields — populate regardless (agent produces these too)
|
|
2841
|
+
switch (parsed.type) {
|
|
2842
|
+
case "question":
|
|
2843
|
+
updateSession((prev) => ({ ...prev, question: parsed }));
|
|
2844
|
+
break;
|
|
2845
|
+
case "exploration":
|
|
2846
|
+
updateSession((prev) => ({ ...prev, exploration: parsed }));
|
|
2847
|
+
break;
|
|
2848
|
+
case "focus": {
|
|
2849
|
+
updateSession((prev) => ({ ...prev, focus: parsed }));
|
|
2850
|
+
// Resolve labels for inline edges, or unpack old-format edges
|
|
2851
|
+
const focusEvent = parsed;
|
|
2852
|
+
if (focusEvent.selectedEdges && focusEvent.selectedEdges.length > 0) {
|
|
2853
|
+
// New format: edges already extracted, resolve labels
|
|
2854
|
+
const resolved = await resolveEdgeLabels(focusEvent);
|
|
2855
|
+
updateSession((prev) => ({ ...prev, focus: resolved }));
|
|
2519
2856
|
}
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
...prev,
|
|
2527
|
-
focus: unpackedFocus,
|
|
2528
|
-
}));
|
|
2857
|
+
else if (focusEvent.edgeSelectionUris.length > 0) {
|
|
2858
|
+
// Old format: unpack edge selection URIs
|
|
2859
|
+
const unpacked = await unpackFocusEvent(focusEvent, triples);
|
|
2860
|
+
updateSession((prev) => ({ ...prev, focus: unpacked }));
|
|
2861
|
+
}
|
|
2862
|
+
break;
|
|
2529
2863
|
}
|
|
2864
|
+
case "synthesis":
|
|
2865
|
+
updateSession((prev) => ({ ...prev, synthesis: parsed }));
|
|
2866
|
+
break;
|
|
2530
2867
|
}
|
|
2531
|
-
}, [unpackFocusEvent, updateSession]);
|
|
2868
|
+
}, [unpackFocusEvent, resolveEdgeLabels, updateSession]);
|
|
2532
2869
|
/**
|
|
2533
2870
|
* Process the unpack queue
|
|
2534
2871
|
*/
|
|
@@ -2893,8 +3230,7 @@ const useStructuredQuery = () => {
|
|
|
2893
3230
|
// Settings for default collection
|
|
2894
3231
|
const { settings } = useSettings();
|
|
2895
3232
|
// Only enable operations when socket is connected and ready
|
|
2896
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
2897
|
-
connectionState?.status === "unauthenticated";
|
|
3233
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
2898
3234
|
// Mutation for executing structured queries from natural language
|
|
2899
3235
|
const structuredQueryMutation = reactQuery.useMutation({
|
|
2900
3236
|
mutationFn: async ({ question, collection, }) => {
|
|
@@ -2950,8 +3286,7 @@ const useRowEmbeddingsQuery = ({ flow } = {}) => {
|
|
|
2950
3286
|
const sessionFlowId = useSessionStore((state) => state.flowId);
|
|
2951
3287
|
const { settings } = useSettings();
|
|
2952
3288
|
const effectiveFlow = flow ?? sessionFlowId;
|
|
2953
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
2954
|
-
connectionState?.status === "unauthenticated";
|
|
3289
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
2955
3290
|
const mutation = reactQuery.useMutation({
|
|
2956
3291
|
mutationFn: async ({ vectors, schemaName, collection, indexName, limit = 10, }) => {
|
|
2957
3292
|
if (!isSocketReady) {
|
|
@@ -2991,8 +3326,7 @@ const useDocumentEmbeddingsQuery = ({ flow } = {}) => {
|
|
|
2991
3326
|
const sessionFlowId = useSessionStore((state) => state.flowId);
|
|
2992
3327
|
const { settings } = useSettings();
|
|
2993
3328
|
const effectiveFlow = flow ?? sessionFlowId;
|
|
2994
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
2995
|
-
connectionState?.status === "unauthenticated";
|
|
3329
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
2996
3330
|
const mutation = reactQuery.useMutation({
|
|
2997
3331
|
mutationFn: async ({ vectors, user, collection, limit = 10, }) => {
|
|
2998
3332
|
if (!isSocketReady) {
|
|
@@ -3038,8 +3372,7 @@ const useRowsQuery = ({ flow } = {}) => {
|
|
|
3038
3372
|
// Settings for default collection
|
|
3039
3373
|
const { settings } = useSettings();
|
|
3040
3374
|
// Only enable operations when socket is connected and ready
|
|
3041
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
3042
|
-
connectionState?.status === "unauthenticated";
|
|
3375
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
3043
3376
|
// Mutation for executing GraphQL rows queries
|
|
3044
3377
|
const rowsQueryMutation = reactQuery.useMutation({
|
|
3045
3378
|
mutationFn: async ({ query, collection, variables, operationName, }) => {
|
|
@@ -3088,8 +3421,7 @@ const useEmbeddings = ({ flow, term }) => {
|
|
|
3088
3421
|
const socket = reactProvider.useSocket();
|
|
3089
3422
|
const connectionState = reactProvider.useConnectionState();
|
|
3090
3423
|
// Only enable queries when socket is connected and ready
|
|
3091
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
3092
|
-
connectionState?.status === "unauthenticated";
|
|
3424
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
3093
3425
|
// Hook for displaying user notifications
|
|
3094
3426
|
const notify = useNotification();
|
|
3095
3427
|
// Session state for default flow ID
|
|
@@ -3147,8 +3479,7 @@ const useCollections = () => {
|
|
|
3147
3479
|
// Hook for displaying user notifications
|
|
3148
3480
|
const notify = useNotification();
|
|
3149
3481
|
// Only enable queries when socket is connected and ready
|
|
3150
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
3151
|
-
connectionState?.status === "unauthenticated";
|
|
3482
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
3152
3483
|
/**
|
|
3153
3484
|
* Query for fetching all collections from the collection management service
|
|
3154
3485
|
* Uses React Query for caching and background refetching
|
|
@@ -3252,8 +3583,7 @@ const useNlpQuery = ({ flow } = {}) => {
|
|
|
3252
3583
|
// Use explicit param if provided, otherwise fall back to session state
|
|
3253
3584
|
const effectiveFlow = flow ?? sessionFlowId;
|
|
3254
3585
|
// Only enable operations when socket is connected and ready
|
|
3255
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
3256
|
-
connectionState?.status === "unauthenticated";
|
|
3586
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
3257
3587
|
// Mutation for converting natural language to GraphQL
|
|
3258
3588
|
const nlpQueryMutation = reactQuery.useMutation({
|
|
3259
3589
|
mutationFn: async ({ question, maxResults, }) => {
|
|
@@ -3303,8 +3633,7 @@ const useProcessing = () => {
|
|
|
3303
3633
|
const socket = reactProvider.useSocket();
|
|
3304
3634
|
const connectionState = reactProvider.useConnectionState();
|
|
3305
3635
|
// Only enable queries when socket is connected and ready
|
|
3306
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
3307
|
-
connectionState?.status === "unauthenticated";
|
|
3636
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
3308
3637
|
/**
|
|
3309
3638
|
* Query for fetching all processing
|
|
3310
3639
|
* Uses React Query for caching and background refetching
|
|
@@ -3347,8 +3676,7 @@ const useAgentTools = () => {
|
|
|
3347
3676
|
// Notification system for user feedback
|
|
3348
3677
|
const notify = useNotification();
|
|
3349
3678
|
// Only enable queries when socket is connected and ready
|
|
3350
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
3351
|
-
connectionState?.status === "unauthenticated";
|
|
3679
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
3352
3680
|
// Query to fetch all agent tools
|
|
3353
3681
|
// Gets all tools directly from the 'tool' configuration type
|
|
3354
3682
|
const toolsQuery = reactQuery.useQuery({
|
|
@@ -3510,8 +3838,7 @@ const useMcpTools = () => {
|
|
|
3510
3838
|
// Notification system for user feedback
|
|
3511
3839
|
const notify = useNotification();
|
|
3512
3840
|
// Only enable queries when socket is connected and ready
|
|
3513
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
3514
|
-
connectionState?.status === "unauthenticated";
|
|
3841
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
3515
3842
|
// Query to fetch all MCP tools
|
|
3516
3843
|
// Uses the list operation to get all MCP tools directly
|
|
3517
3844
|
const toolsQuery = reactQuery.useQuery({
|
|
@@ -3670,8 +3997,7 @@ const usePrompts = () => {
|
|
|
3670
3997
|
// Notification system for user feedback
|
|
3671
3998
|
const notify = useNotification();
|
|
3672
3999
|
// Only enable queries when socket is connected and ready
|
|
3673
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
3674
|
-
connectionState?.status === "unauthenticated";
|
|
4000
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
3675
4001
|
// Query to fetch the system prompt configuration
|
|
3676
4002
|
// System prompt defines the AI assistant's behavior and instructions
|
|
3677
4003
|
const systemPromptQuery = reactQuery.useQuery({
|
|
@@ -3691,22 +4017,21 @@ const usePrompts = () => {
|
|
|
3691
4017
|
},
|
|
3692
4018
|
});
|
|
3693
4019
|
// Query to fetch all prompt templates
|
|
3694
|
-
//
|
|
4020
|
+
// Lists prompt config keys, filters for template.* prefix, then fetches each template's configuration
|
|
3695
4021
|
const promptsQuery = reactQuery.useQuery({
|
|
3696
4022
|
queryKey: ["prompts"],
|
|
3697
4023
|
enabled: isSocketReady,
|
|
3698
4024
|
queryFn: () => {
|
|
3699
|
-
// Step 1: Get the template index (array of template IDs)
|
|
3700
4025
|
return socket
|
|
3701
4026
|
.config()
|
|
3702
|
-
.
|
|
4027
|
+
.list("prompt")
|
|
3703
4028
|
.then((res) => {
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
4029
|
+
const keys = res?.directory || [];
|
|
4030
|
+
const promptIds = keys
|
|
4031
|
+
.filter((k) => k.startsWith("template."))
|
|
4032
|
+
.map((k) => k.slice("template.".length));
|
|
4033
|
+
if (promptIds.length === 0)
|
|
4034
|
+
return [];
|
|
3710
4035
|
return socket
|
|
3711
4036
|
.config()
|
|
3712
4037
|
.getConfig(promptIds.map((id) => ({
|
|
@@ -3718,7 +4043,6 @@ const usePrompts = () => {
|
|
|
3718
4043
|
console.log("Error:", r);
|
|
3719
4044
|
throw r.error.message;
|
|
3720
4045
|
}
|
|
3721
|
-
// Parse template configurations and pair them with their IDs
|
|
3722
4046
|
const config = r.values.map((c) => JSON.parse(c.value));
|
|
3723
4047
|
return promptIds.map((id, ix) => [id, config[ix]]);
|
|
3724
4048
|
});
|
|
@@ -3791,41 +4115,24 @@ const usePrompts = () => {
|
|
|
3791
4115
|
},
|
|
3792
4116
|
});
|
|
3793
4117
|
// Mutation for creating a new prompt template
|
|
3794
|
-
// Updates both the template index and creates the template configuration
|
|
3795
4118
|
const createPromptMutation = reactQuery.useMutation({
|
|
3796
4119
|
mutationFn: ({ id, prompt, onSuccess }) => {
|
|
3797
|
-
// Step 1: Get current template index
|
|
3798
4120
|
return socket
|
|
3799
4121
|
.config()
|
|
3800
|
-
.
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
{
|
|
3815
|
-
type: "prompt",
|
|
3816
|
-
key: "template." + id,
|
|
3817
|
-
value: JSON.stringify(prompt),
|
|
3818
|
-
},
|
|
3819
|
-
])
|
|
3820
|
-
.then((x) => {
|
|
3821
|
-
if (x["error"]) {
|
|
3822
|
-
console.log("Error:", x);
|
|
3823
|
-
throw x.error.message;
|
|
3824
|
-
}
|
|
3825
|
-
// Execute callback if provided
|
|
3826
|
-
if (onSuccess)
|
|
3827
|
-
onSuccess();
|
|
3828
|
-
});
|
|
4122
|
+
.putConfig([
|
|
4123
|
+
{
|
|
4124
|
+
type: "prompt",
|
|
4125
|
+
key: "template." + id,
|
|
4126
|
+
value: JSON.stringify(prompt),
|
|
4127
|
+
},
|
|
4128
|
+
])
|
|
4129
|
+
.then((x) => {
|
|
4130
|
+
if (x["error"]) {
|
|
4131
|
+
console.log("Error:", x);
|
|
4132
|
+
throw x.error.message;
|
|
4133
|
+
}
|
|
4134
|
+
if (onSuccess)
|
|
4135
|
+
onSuccess();
|
|
3829
4136
|
});
|
|
3830
4137
|
},
|
|
3831
4138
|
onError: (err) => {
|
|
@@ -3839,45 +4146,21 @@ const usePrompts = () => {
|
|
|
3839
4146
|
},
|
|
3840
4147
|
});
|
|
3841
4148
|
// Mutation for deleting a prompt template
|
|
3842
|
-
// Removes the template from both the index and deletes its configuration
|
|
3843
4149
|
const deletePromptMutation = reactQuery.useMutation({
|
|
3844
4150
|
mutationFn: ({ id, onSuccess }) => {
|
|
3845
|
-
// Step 1: Get current template index
|
|
3846
4151
|
return socket
|
|
3847
4152
|
.config()
|
|
3848
|
-
.
|
|
3849
|
-
|
|
3850
|
-
.
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
.
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
key: "template-index",
|
|
3860
|
-
value: JSON.stringify(newIds),
|
|
3861
|
-
},
|
|
3862
|
-
])
|
|
3863
|
-
.then(() => {
|
|
3864
|
-
// Step 4: Delete the template configuration
|
|
3865
|
-
return socket.config().deleteConfig([
|
|
3866
|
-
{
|
|
3867
|
-
type: "prompt",
|
|
3868
|
-
key: "template." + id,
|
|
3869
|
-
},
|
|
3870
|
-
]);
|
|
3871
|
-
})
|
|
3872
|
-
.then((x) => {
|
|
3873
|
-
if (x["error"]) {
|
|
3874
|
-
console.log("Error:", x);
|
|
3875
|
-
throw x.error.message;
|
|
3876
|
-
}
|
|
3877
|
-
// Execute callback if provided
|
|
3878
|
-
if (onSuccess)
|
|
3879
|
-
onSuccess();
|
|
3880
|
-
});
|
|
4153
|
+
.deleteConfig({
|
|
4154
|
+
type: "prompt",
|
|
4155
|
+
key: "template." + id,
|
|
4156
|
+
})
|
|
4157
|
+
.then((x) => {
|
|
4158
|
+
if (x["error"]) {
|
|
4159
|
+
console.log("Error:", x);
|
|
4160
|
+
throw x.error.message;
|
|
4161
|
+
}
|
|
4162
|
+
if (onSuccess)
|
|
4163
|
+
onSuccess();
|
|
3881
4164
|
});
|
|
3882
4165
|
},
|
|
3883
4166
|
onError: (err) => {
|
|
@@ -3932,8 +4215,7 @@ const useSchemas = () => {
|
|
|
3932
4215
|
const queryClient = reactQuery.useQueryClient();
|
|
3933
4216
|
const notify = useNotification();
|
|
3934
4217
|
// Only enable queries when socket is connected and ready
|
|
3935
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
3936
|
-
connectionState?.status === "unauthenticated";
|
|
4218
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
3937
4219
|
const schemasQuery = reactQuery.useQuery({
|
|
3938
4220
|
queryKey: ["schemas"],
|
|
3939
4221
|
enabled: isSocketReady,
|
|
@@ -4063,8 +4345,7 @@ const useOntologies = () => {
|
|
|
4063
4345
|
const queryClient = reactQuery.useQueryClient();
|
|
4064
4346
|
const notify = useNotification();
|
|
4065
4347
|
// Only enable queries when socket is connected and ready
|
|
4066
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
4067
|
-
connectionState?.status === "unauthenticated";
|
|
4348
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
4068
4349
|
const ontologiesQuery = reactQuery.useQuery({
|
|
4069
4350
|
queryKey: ["ontologies"],
|
|
4070
4351
|
enabled: isSocketReady,
|
|
@@ -4202,8 +4483,7 @@ const useKnowledgeCores = () => {
|
|
|
4202
4483
|
// Hook for displaying user notifications
|
|
4203
4484
|
const notify = useNotification();
|
|
4204
4485
|
// Only enable queries when socket is connected and ready
|
|
4205
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
4206
|
-
connectionState?.status === "unauthenticated";
|
|
4486
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
4207
4487
|
/**
|
|
4208
4488
|
* Query for fetching all knowledge cores
|
|
4209
4489
|
* Uses React Query for caching and background refetching
|
|
@@ -4305,8 +4585,7 @@ const useTokenCosts = () => {
|
|
|
4305
4585
|
// Hook for displaying user notifications
|
|
4306
4586
|
const notify = useNotification();
|
|
4307
4587
|
// Only enable queries when socket is connected and ready
|
|
4308
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
4309
|
-
connectionState?.status === "unauthenticated";
|
|
4588
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
4310
4589
|
/**
|
|
4311
4590
|
* Query for fetching all token costs
|
|
4312
4591
|
* Uses React Query for caching and background refetching
|
|
@@ -4437,8 +4716,7 @@ const useLLMModels = () => {
|
|
|
4437
4716
|
const connectionState = reactProvider.useConnectionState();
|
|
4438
4717
|
const queryClient = reactQuery.useQueryClient();
|
|
4439
4718
|
const notify = useNotification();
|
|
4440
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
4441
|
-
connectionState?.status === "unauthenticated";
|
|
4719
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
4442
4720
|
// Fetch the llm-model parameter type
|
|
4443
4721
|
const paramTypesQuery = reactQuery.useQuery({
|
|
4444
4722
|
queryKey: ["llm-models"],
|
|
@@ -4524,8 +4802,7 @@ const useFlowBlueprints = () => {
|
|
|
4524
4802
|
// Hook for displaying user notifications
|
|
4525
4803
|
const notify = useNotification();
|
|
4526
4804
|
// Only enable queries when socket is connected and ready
|
|
4527
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
4528
|
-
connectionState?.status === "unauthenticated";
|
|
4805
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
4529
4806
|
/**
|
|
4530
4807
|
* Query for fetching all flow blueprintes
|
|
4531
4808
|
* Uses React Query for caching and background refetching
|
|
@@ -4798,8 +5075,7 @@ const generateFlowBlueprintId = (baseName = "flow-class") => {
|
|
|
4798
5075
|
const useFlowParameters = (flowBlueprintName) => {
|
|
4799
5076
|
const socket = reactProvider.useSocket();
|
|
4800
5077
|
const connectionState = reactProvider.useConnectionState();
|
|
4801
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
4802
|
-
connectionState?.status === "unauthenticated";
|
|
5078
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
4803
5079
|
/**
|
|
4804
5080
|
* Query for fetching parameter definitions for a flow blueprint
|
|
4805
5081
|
*/
|
|
@@ -5428,8 +5704,9 @@ const useNodeDetails = (nodeId, flowId) => {
|
|
|
5428
5704
|
};
|
|
5429
5705
|
};
|
|
5430
5706
|
|
|
5431
|
-
// Default chunk size:
|
|
5432
|
-
|
|
5707
|
+
// Default chunk size: 2MB (base64 + JSON encoding inflates ~4x on the wire,
|
|
5708
|
+
// Pulsar message limit is around 3MB raw)
|
|
5709
|
+
const DEFAULT_CHUNK_SIZE$1 = 2 * 1024 * 1024;
|
|
5433
5710
|
// Maximum parallel chunk uploads
|
|
5434
5711
|
const DEFAULT_PARALLEL_UPLOADS = 3;
|
|
5435
5712
|
/**
|
|
@@ -5546,8 +5823,7 @@ const useChunkedUpload = (options = {}) => {
|
|
|
5546
5823
|
const upload = react.useCallback(async (params) => {
|
|
5547
5824
|
const { file, title, comments = "", tags = [], collection, documentId } = params;
|
|
5548
5825
|
// Validate connection
|
|
5549
|
-
if (connectionState?.status !== "authenticated"
|
|
5550
|
-
connectionState?.status !== "unauthenticated") {
|
|
5826
|
+
if (connectionState?.status !== "authenticated") {
|
|
5551
5827
|
const error = "Not connected to server";
|
|
5552
5828
|
updateProgress({ status: "error", error });
|
|
5553
5829
|
onError?.(error);
|
|
@@ -5638,8 +5914,7 @@ const useChunkedUpload = (options = {}) => {
|
|
|
5638
5914
|
const resume = react.useCallback(async (params) => {
|
|
5639
5915
|
const { uploadId, file } = params;
|
|
5640
5916
|
// Validate connection
|
|
5641
|
-
if (connectionState?.status !== "authenticated"
|
|
5642
|
-
connectionState?.status !== "unauthenticated") {
|
|
5917
|
+
if (connectionState?.status !== "authenticated") {
|
|
5643
5918
|
const error = "Not connected to server";
|
|
5644
5919
|
updateProgress({ status: "error", error });
|
|
5645
5920
|
onError?.(error);
|
|
@@ -5858,8 +6133,7 @@ const useChunkedDownload = (options = {}) => {
|
|
|
5858
6133
|
const download = react.useCallback((params) => {
|
|
5859
6134
|
const { documentId, mimeType = "application/octet-stream", filename } = params;
|
|
5860
6135
|
// Validate connection
|
|
5861
|
-
if (connectionState?.status !== "authenticated"
|
|
5862
|
-
connectionState?.status !== "unauthenticated") {
|
|
6136
|
+
if (connectionState?.status !== "authenticated") {
|
|
5863
6137
|
const error = "Not connected to server";
|
|
5864
6138
|
updateProgress({ status: "error", error });
|
|
5865
6139
|
onError?.(error);
|
|
@@ -5984,8 +6258,7 @@ const useDocumentMetadata = (options = {}) => {
|
|
|
5984
6258
|
const { documentId, enabled } = options;
|
|
5985
6259
|
const socket = reactProvider.useSocket();
|
|
5986
6260
|
const connectionState = reactProvider.useConnectionState();
|
|
5987
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
5988
|
-
connectionState?.status === "unauthenticated";
|
|
6261
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
5989
6262
|
const query = reactQuery.useQuery({
|
|
5990
6263
|
queryKey: ["document-metadata", documentId],
|
|
5991
6264
|
enabled: isSocketReady && !!documentId && (enabled !== false),
|
|
@@ -6010,8 +6283,7 @@ const useDocumentsMetadata = (documentIds = []) => {
|
|
|
6010
6283
|
const socket = reactProvider.useSocket();
|
|
6011
6284
|
const connectionState = reactProvider.useConnectionState();
|
|
6012
6285
|
const queryClient = reactQuery.useQueryClient();
|
|
6013
|
-
const isSocketReady = connectionState?.status === "authenticated"
|
|
6014
|
-
connectionState?.status === "unauthenticated";
|
|
6286
|
+
const isSocketReady = connectionState?.status === "authenticated";
|
|
6015
6287
|
const query = reactQuery.useQuery({
|
|
6016
6288
|
queryKey: ["documents-metadata", documentIds],
|
|
6017
6289
|
enabled: isSocketReady && documentIds.length > 0,
|
|
@@ -6125,6 +6397,10 @@ Object.defineProperty(exports, "TG", {
|
|
|
6125
6397
|
enumerable: true,
|
|
6126
6398
|
get: function () { return client.TG; }
|
|
6127
6399
|
});
|
|
6400
|
+
Object.defineProperty(exports, "TG_CONCEPT", {
|
|
6401
|
+
enumerable: true,
|
|
6402
|
+
get: function () { return client.TG_CONCEPT; }
|
|
6403
|
+
});
|
|
6128
6404
|
Object.defineProperty(exports, "TG_CONTENT", {
|
|
6129
6405
|
enumerable: true,
|
|
6130
6406
|
get: function () { return client.TG_CONTENT; }
|
|
@@ -6145,14 +6421,14 @@ Object.defineProperty(exports, "TG_QUERY", {
|
|
|
6145
6421
|
enumerable: true,
|
|
6146
6422
|
get: function () { return client.TG_QUERY; }
|
|
6147
6423
|
});
|
|
6148
|
-
Object.defineProperty(exports, "TG_REASONING", {
|
|
6149
|
-
enumerable: true,
|
|
6150
|
-
get: function () { return client.TG_REASONING; }
|
|
6151
|
-
});
|
|
6152
6424
|
Object.defineProperty(exports, "TG_REIFIES", {
|
|
6153
6425
|
enumerable: true,
|
|
6154
6426
|
get: function () { return client.TG_REIFIES; }
|
|
6155
6427
|
});
|
|
6428
|
+
Object.defineProperty(exports, "TG_SCORE", {
|
|
6429
|
+
enumerable: true,
|
|
6430
|
+
get: function () { return client.TG_SCORE; }
|
|
6431
|
+
});
|
|
6156
6432
|
Object.defineProperty(exports, "TG_SELECTED_EDGE", {
|
|
6157
6433
|
enumerable: true,
|
|
6158
6434
|
get: function () { return client.TG_SELECTED_EDGE; }
|
|
@@ -6161,6 +6437,7 @@ exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
|
|
6161
6437
|
exports.NotificationProvider = NotificationProvider;
|
|
6162
6438
|
exports.RDFS_LABEL = RDFS_LABEL;
|
|
6163
6439
|
exports.SETTINGS_STORAGE_KEY = SETTINGS_STORAGE_KEY;
|
|
6440
|
+
exports.configureAuthApi = configureAuthApi;
|
|
6164
6441
|
exports.createDocId = createDocId;
|
|
6165
6442
|
exports.extractQuotedTriple = extractQuotedTriple;
|
|
6166
6443
|
exports.fileToBase64 = fileToBase64;
|
|
@@ -6180,6 +6457,9 @@ exports.prepareMetadata = prepareMetadata;
|
|
|
6180
6457
|
exports.textToBase64 = textToBase64;
|
|
6181
6458
|
exports.useActivity = useActivity;
|
|
6182
6459
|
exports.useAgentTools = useAgentTools;
|
|
6460
|
+
exports.useAuth = useAuth;
|
|
6461
|
+
exports.useAuthStore = useAuthStore;
|
|
6462
|
+
exports.useBootstrapStatus = useBootstrapStatus;
|
|
6183
6463
|
exports.useChat = useChat;
|
|
6184
6464
|
exports.useChatSession = useChatSession;
|
|
6185
6465
|
exports.useChunkedDownload = useChunkedDownload;
|
|
@@ -6203,6 +6483,8 @@ exports.useKnowledgeCores = useKnowledgeCores;
|
|
|
6203
6483
|
exports.useLLMModels = useLLMModels;
|
|
6204
6484
|
exports.useLibrary = useLibrary;
|
|
6205
6485
|
exports.useLoadStateStore = useLoadStateStore;
|
|
6486
|
+
exports.useLogin = useLogin;
|
|
6487
|
+
exports.useLogout = useLogout;
|
|
6206
6488
|
exports.useMcpTools = useMcpTools;
|
|
6207
6489
|
exports.useNlpQuery = useNlpQuery;
|
|
6208
6490
|
exports.useNodeDetails = useNodeDetails;
|
|
@@ -6223,6 +6505,11 @@ exports.useStructuredQuery = useStructuredQuery;
|
|
|
6223
6505
|
exports.useTokenCosts = useTokenCosts;
|
|
6224
6506
|
exports.useTriples = useTriples;
|
|
6225
6507
|
exports.useVectorSearch = useVectorSearch;
|
|
6508
|
+
exports.useWhoami = useWhoami;
|
|
6226
6509
|
exports.useWorkbenchStateStore = useWorkbenchStateStore;
|
|
6510
|
+
exports.useWorkspace = useWorkspace;
|
|
6511
|
+
exports.useWorkspaceStore = useWorkspaceStore;
|
|
6512
|
+
exports.useWorkspaceSync = useWorkspaceSync;
|
|
6513
|
+
exports.useWorkspaces = useWorkspaces;
|
|
6227
6514
|
exports.vectorSearch = vectorSearch;
|
|
6228
6515
|
//# sourceMappingURL=index.cjs.map
|