@personaai/react 0.11.0 → 0.15.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.
package/dist/index.js CHANGED
@@ -1889,8 +1889,110 @@ function useThreads(autoFetch = true) {
1889
1889
  };
1890
1890
  }
1891
1891
 
1892
+ // src/hooks/useWorkspaceFiles.ts
1893
+ import { useCallback as useCallback5, useEffect as useEffect5, useState as useState5 } from "react";
1894
+ function useWorkspaceFiles(threadId, autoFetch = true) {
1895
+ const { fetchWithAuth } = usePersonaContext();
1896
+ const [files, setFiles] = useState5({});
1897
+ const [isLoading, setIsLoading] = useState5(false);
1898
+ const [isSaving, setIsSaving] = useState5(false);
1899
+ const [error, setError] = useState5(null);
1900
+ const fetchFiles = useCallback5(async () => {
1901
+ if (!threadId) return {};
1902
+ setIsLoading(true);
1903
+ setError(null);
1904
+ try {
1905
+ const res = await fetchWithAuth(`/threads/${threadId}/files`);
1906
+ if (!res.ok) throw new Error(`Failed to list workspace files: ${res.statusText}`);
1907
+ const data = await res.json();
1908
+ const normalized = normalizeWorkspaceFiles(data?.data ?? data ?? {});
1909
+ setFiles(normalized);
1910
+ return normalized;
1911
+ } catch (err) {
1912
+ const errorObj = err instanceof Error ? err : new Error(String(err));
1913
+ setError(errorObj);
1914
+ return {};
1915
+ } finally {
1916
+ setIsLoading(false);
1917
+ }
1918
+ }, [fetchWithAuth, threadId]);
1919
+ const getFile = useCallback5(
1920
+ async (path) => {
1921
+ if (!threadId) throw new Error("useWorkspaceFiles: no threadId set");
1922
+ const res = await fetchWithAuth(
1923
+ `/threads/${threadId}/file?path=${encodeURIComponent(path)}`
1924
+ );
1925
+ if (!res.ok) throw new Error(`Failed to read workspace file: ${res.statusText}`);
1926
+ const data = await res.json();
1927
+ const raw = data?.data ?? data;
1928
+ return normalizeWorkspaceFiles({ [path]: raw })[path];
1929
+ },
1930
+ [fetchWithAuth, threadId]
1931
+ );
1932
+ const writeFile = useCallback5(
1933
+ async (path, content) => {
1934
+ if (!threadId) throw new Error("useWorkspaceFiles: no threadId set");
1935
+ setIsSaving(true);
1936
+ setError(null);
1937
+ try {
1938
+ const res = await fetchWithAuth(`/threads/${threadId}/file`, {
1939
+ method: "PUT",
1940
+ headers: { "Content-Type": "application/json" },
1941
+ body: JSON.stringify({ path, content })
1942
+ });
1943
+ if (!res.ok) throw new Error(`Failed to write workspace file: ${res.statusText}`);
1944
+ const data = await res.json();
1945
+ const raw = data?.data ?? data;
1946
+ const file = normalizeWorkspaceFiles({ [path]: raw })[path];
1947
+ setFiles((prev) => ({ ...prev, [path]: file }));
1948
+ return file;
1949
+ } catch (err) {
1950
+ const errorObj = err instanceof Error ? err : new Error(String(err));
1951
+ setError(errorObj);
1952
+ throw errorObj;
1953
+ } finally {
1954
+ setIsSaving(false);
1955
+ }
1956
+ },
1957
+ [fetchWithAuth, threadId]
1958
+ );
1959
+ const deleteFile = useCallback5(
1960
+ async (path) => {
1961
+ if (!threadId) throw new Error("useWorkspaceFiles: no threadId set");
1962
+ const res = await fetchWithAuth(
1963
+ `/threads/${threadId}/file?path=${encodeURIComponent(path)}`,
1964
+ { method: "DELETE" }
1965
+ );
1966
+ if (!res.ok) throw new Error(`Failed to delete workspace file: ${res.statusText}`);
1967
+ setFiles((prev) => {
1968
+ const next = { ...prev };
1969
+ delete next[path];
1970
+ return next;
1971
+ });
1972
+ },
1973
+ [fetchWithAuth, threadId]
1974
+ );
1975
+ useEffect5(() => {
1976
+ if (autoFetch && threadId) {
1977
+ void fetchFiles();
1978
+ } else if (!threadId) {
1979
+ setFiles({});
1980
+ }
1981
+ }, [autoFetch, threadId, fetchFiles]);
1982
+ return {
1983
+ files,
1984
+ isLoading,
1985
+ isSaving,
1986
+ error,
1987
+ refetch: fetchFiles,
1988
+ getFile,
1989
+ writeFile,
1990
+ deleteFile
1991
+ };
1992
+ }
1993
+
1892
1994
  // src/hooks/useVoice.ts
1893
- import { useCallback as useCallback5, useEffect as useEffect5, useMemo as useMemo4, useRef as useRef3, useState as useState5 } from "react";
1995
+ import { useCallback as useCallback6, useEffect as useEffect6, useMemo as useMemo4, useRef as useRef3, useState as useState6 } from "react";
1894
1996
 
1895
1997
  // src/hooks/voiceWorklets.ts
1896
1998
  var RECORDER_WORKLET_SOURCE = `
@@ -1998,17 +2100,17 @@ function useVoice(options = {}) {
1998
2100
  const threadId = options.threadId;
1999
2101
  const contextOverride = options.contextOverride;
2000
2102
  const context = options.context;
2001
- const [state, setState] = useState5("idle");
2002
- const [isMuted, setIsMuted] = useState5(false);
2003
- const [transcript, setTranscript] = useState5(
2103
+ const [state, setState] = useState6("idle");
2104
+ const [isMuted, setIsMuted] = useState6(false);
2105
+ const [transcript, setTranscript] = useState6(
2004
2106
  []
2005
2107
  );
2006
- const [partial, setPartial] = useState5(
2108
+ const [partial, setPartial] = useState6(
2007
2109
  null
2008
2110
  );
2009
- const [toolCalls, setToolCalls] = useState5([]);
2010
- const [error, setError] = useState5(null);
2011
- const [endReason, setEndReason] = useState5(
2111
+ const [toolCalls, setToolCalls] = useState6([]);
2112
+ const [error, setError] = useState6(null);
2113
+ const [endReason, setEndReason] = useState6(
2012
2114
  null
2013
2115
  );
2014
2116
  const wsRef = useRef3(null);
@@ -2022,13 +2124,13 @@ function useVoice(options = {}) {
2022
2124
  const lastFinalTurnRef = useRef3(
2023
2125
  null
2024
2126
  );
2025
- useEffect5(() => {
2127
+ useEffect6(() => {
2026
2128
  mountedRef.current = true;
2027
2129
  return () => {
2028
2130
  mountedRef.current = false;
2029
2131
  };
2030
2132
  }, []);
2031
- const teardownAudio = useCallback5(() => {
2133
+ const teardownAudio = useCallback6(() => {
2032
2134
  try {
2033
2135
  streamRef.current?.getTracks().forEach((track) => track.stop());
2034
2136
  } catch {
@@ -2055,7 +2157,7 @@ function useVoice(options = {}) {
2055
2157
  }
2056
2158
  outputCtxRef.current = null;
2057
2159
  }, []);
2058
- const stop = useCallback5(() => {
2160
+ const stop = useCallback6(() => {
2059
2161
  voiceLogger.debug("stop() called");
2060
2162
  try {
2061
2163
  wsRef.current?.close(1e3, "client_stop");
@@ -2065,8 +2167,8 @@ function useVoice(options = {}) {
2065
2167
  teardownAudio();
2066
2168
  if (mountedRef.current) setState("idle");
2067
2169
  }, [teardownAudio, voiceLogger]);
2068
- useEffect5(() => stop, [stop]);
2069
- const startCapture = useCallback5(async (inputSampleRate) => {
2170
+ useEffect6(() => stop, [stop]);
2171
+ const startCapture = useCallback6(async (inputSampleRate) => {
2070
2172
  const stream = await navigator.mediaDevices.getUserMedia({
2071
2173
  audio: {
2072
2174
  echoCancellation: true,
@@ -2092,7 +2194,7 @@ function useVoice(options = {}) {
2092
2194
  recorderNodeRef.current = recorderNode;
2093
2195
  source.connect(recorderNode);
2094
2196
  }, []);
2095
- const setupPlayback = useCallback5(async (outputSampleRate) => {
2197
+ const setupPlayback = useCallback6(async (outputSampleRate) => {
2096
2198
  const outputCtx = new AudioContext({ sampleRate: outputSampleRate });
2097
2199
  outputCtxRef.current = outputCtx;
2098
2200
  await outputCtx.audioWorklet.addModule(playerWorkletUrl());
@@ -2100,7 +2202,7 @@ function useVoice(options = {}) {
2100
2202
  playerNode.connect(outputCtx.destination);
2101
2203
  playerNodeRef.current = playerNode;
2102
2204
  }, []);
2103
- const upsertToolCall = useCallback5(
2205
+ const upsertToolCall = useCallback6(
2104
2206
  (id, patch) => {
2105
2207
  setToolCalls((prev) => {
2106
2208
  const idx = prev.findIndex((t) => t.id === id);
@@ -2112,7 +2214,7 @@ function useVoice(options = {}) {
2112
2214
  },
2113
2215
  []
2114
2216
  );
2115
- const handleTranscript = useCallback5((value) => {
2217
+ const handleTranscript = useCallback6((value) => {
2116
2218
  const { speaker, text, isFinal, turnSeq } = value;
2117
2219
  if (!isFinal) {
2118
2220
  setPartial({ id: "partial", speaker, text });
@@ -2135,7 +2237,7 @@ function useVoice(options = {}) {
2135
2237
  });
2136
2238
  lastFinalTurnRef.current = { speaker, turnSeq };
2137
2239
  }, []);
2138
- const handleCustomEvent = useCallback5(
2240
+ const handleCustomEvent = useCallback6(
2139
2241
  (name, value) => {
2140
2242
  switch (name) {
2141
2243
  case "voice_session_ready":
@@ -2193,7 +2295,7 @@ function useVoice(options = {}) {
2193
2295
  },
2194
2296
  [handleTranscript, setupPlayback, startCapture, teardownAudio, voiceLogger]
2195
2297
  );
2196
- const handleMessage = useCallback5(
2298
+ const handleMessage = useCallback6(
2197
2299
  (event) => {
2198
2300
  if (typeof event.data !== "string") {
2199
2301
  const buf = event.data;
@@ -2251,7 +2353,7 @@ function useVoice(options = {}) {
2251
2353
  },
2252
2354
  [handleCustomEvent, upsertToolCall, voiceLogger]
2253
2355
  );
2254
- const start = useCallback5(async () => {
2356
+ const start = useCallback6(async () => {
2255
2357
  if (!agentId) {
2256
2358
  const err = new Error(
2257
2359
  "useVoice: no agentId provided and no defaultAgentId set on PersonaProvider"
@@ -2318,17 +2420,17 @@ function useVoice(options = {}) {
2318
2420
  teardownAudio();
2319
2421
  }
2320
2422
  }, [agentId, threadId, contextOverride, context, fetchWithAuth, handleMessage, teardownAudio, voiceLogger]);
2321
- const mute = useCallback5((muted) => {
2423
+ const mute = useCallback6((muted) => {
2322
2424
  setIsMuted(muted);
2323
2425
  streamRef.current?.getAudioTracks().forEach((track) => {
2324
2426
  track.enabled = !muted;
2325
2427
  });
2326
2428
  }, []);
2327
- const sendText = useCallback5((text) => {
2429
+ const sendText = useCallback6((text) => {
2328
2430
  if (!text?.trim() || wsRef.current?.readyState !== WebSocket.OPEN) return;
2329
2431
  wsRef.current.send(JSON.stringify({ type: "voice.text", text }));
2330
2432
  }, []);
2331
- const updateContext = useCallback5((newContext) => {
2433
+ const updateContext = useCallback6((newContext) => {
2332
2434
  if (wsRef.current?.readyState !== WebSocket.OPEN) return;
2333
2435
  wsRef.current.send(JSON.stringify({ type: "voice.context", context: newContext }));
2334
2436
  }, []);
@@ -2349,14 +2451,14 @@ function useVoice(options = {}) {
2349
2451
  }
2350
2452
 
2351
2453
  // src/hooks/useFiles.ts
2352
- import { useCallback as useCallback6, useEffect as useEffect6, useState as useState6 } from "react";
2454
+ import { useCallback as useCallback7, useEffect as useEffect7, useState as useState7 } from "react";
2353
2455
  function useFiles(autoFetch = true) {
2354
2456
  const { fetchWithAuth } = usePersonaContext();
2355
- const [files, setFiles] = useState6([]);
2356
- const [isLoading, setIsLoading] = useState6(false);
2357
- const [isUploading, setIsUploading] = useState6(false);
2358
- const [error, setError] = useState6(null);
2359
- const fetchFiles = useCallback6(async () => {
2457
+ const [files, setFiles] = useState7([]);
2458
+ const [isLoading, setIsLoading] = useState7(false);
2459
+ const [isUploading, setIsUploading] = useState7(false);
2460
+ const [error, setError] = useState7(null);
2461
+ const fetchFiles = useCallback7(async () => {
2360
2462
  setIsLoading(true);
2361
2463
  setError(null);
2362
2464
  try {
@@ -2374,7 +2476,7 @@ function useFiles(autoFetch = true) {
2374
2476
  setIsLoading(false);
2375
2477
  }
2376
2478
  }, [fetchWithAuth]);
2377
- const uploadFile = useCallback6(
2479
+ const uploadFile = useCallback7(
2378
2480
  async (fileOrFormData) => {
2379
2481
  setIsUploading(true);
2380
2482
  setError(null);
@@ -2407,7 +2509,7 @@ function useFiles(autoFetch = true) {
2407
2509
  },
2408
2510
  [fetchWithAuth, fetchFiles]
2409
2511
  );
2410
- const deleteFile = useCallback6(
2512
+ const deleteFile = useCallback7(
2411
2513
  async (fileId) => {
2412
2514
  const res = await fetchWithAuth(`/files/${fileId}`, { method: "DELETE" });
2413
2515
  if (!res.ok) throw new Error(`Failed to delete file: ${res.statusText}`);
@@ -2415,7 +2517,7 @@ function useFiles(autoFetch = true) {
2415
2517
  },
2416
2518
  [fetchWithAuth]
2417
2519
  );
2418
- const bulkDeleteFiles = useCallback6(
2520
+ const bulkDeleteFiles = useCallback7(
2419
2521
  async (fileIds) => {
2420
2522
  const res = await fetchWithAuth("/files/bulk-delete", {
2421
2523
  method: "POST",
@@ -2430,10 +2532,10 @@ function useFiles(autoFetch = true) {
2430
2532
  },
2431
2533
  [fetchWithAuth]
2432
2534
  );
2433
- const getDownloadUrl = useCallback6((fileId) => {
2535
+ const getDownloadUrl = useCallback7((fileId) => {
2434
2536
  return `/files/${fileId}`;
2435
2537
  }, []);
2436
- useEffect6(() => {
2538
+ useEffect7(() => {
2437
2539
  if (autoFetch) {
2438
2540
  void fetchFiles();
2439
2541
  }
@@ -2452,21 +2554,21 @@ function useFiles(autoFetch = true) {
2452
2554
  }
2453
2555
 
2454
2556
  // src/hooks/useAgents.ts
2455
- import { useCallback as useCallback7, useEffect as useEffect7, useState as useState7 } from "react";
2557
+ import { useCallback as useCallback8, useEffect as useEffect8, useState as useState8 } from "react";
2456
2558
  function useAgents(options = true) {
2457
2559
  const opts = typeof options === "boolean" ? { autoFetch: options } : options;
2458
2560
  const { autoFetch = true, page, limit, search, category, scope } = opts;
2459
2561
  const { fetchWithAuth } = usePersonaContext();
2460
- const [agents, setAgents] = useState7([]);
2461
- const [pagination, setPagination] = useState7({
2562
+ const [agents, setAgents] = useState8([]);
2563
+ const [pagination, setPagination] = useState8({
2462
2564
  total: 0,
2463
2565
  page: page ?? 1,
2464
2566
  limit: limit ?? 20,
2465
2567
  pages: 0
2466
2568
  });
2467
- const [isLoading, setIsLoading] = useState7(false);
2468
- const [error, setError] = useState7(null);
2469
- const fetchAgents = useCallback7(async () => {
2569
+ const [isLoading, setIsLoading] = useState8(false);
2570
+ const [error, setError] = useState8(null);
2571
+ const fetchAgents = useCallback8(async () => {
2470
2572
  setIsLoading(true);
2471
2573
  setError(null);
2472
2574
  try {
@@ -2494,7 +2596,7 @@ function useAgents(options = true) {
2494
2596
  setIsLoading(false);
2495
2597
  }
2496
2598
  }, [fetchWithAuth, page, limit, search, category, scope]);
2497
- const getAgent = useCallback7(
2599
+ const getAgent = useCallback8(
2498
2600
  async (agentId) => {
2499
2601
  const res = await fetchWithAuth(`/agents/${agentId}`);
2500
2602
  if (!res.ok) throw new Error(`Failed to fetch agent: ${res.statusText}`);
@@ -2502,7 +2604,7 @@ function useAgents(options = true) {
2502
2604
  },
2503
2605
  [fetchWithAuth]
2504
2606
  );
2505
- const createAgent = useCallback7(
2607
+ const createAgent = useCallback8(
2506
2608
  async (input) => {
2507
2609
  setError(null);
2508
2610
  try {
@@ -2526,7 +2628,7 @@ function useAgents(options = true) {
2526
2628
  },
2527
2629
  [fetchWithAuth]
2528
2630
  );
2529
- const updateAgent = useCallback7(
2631
+ const updateAgent = useCallback8(
2530
2632
  async (agentId, input) => {
2531
2633
  setError(null);
2532
2634
  try {
@@ -2550,7 +2652,7 @@ function useAgents(options = true) {
2550
2652
  },
2551
2653
  [fetchWithAuth]
2552
2654
  );
2553
- const deleteAgent = useCallback7(
2655
+ const deleteAgent = useCallback8(
2554
2656
  async (agentId) => {
2555
2657
  setError(null);
2556
2658
  try {
@@ -2568,7 +2670,7 @@ function useAgents(options = true) {
2568
2670
  },
2569
2671
  [fetchWithAuth]
2570
2672
  );
2571
- const bulkDeleteAgents = useCallback7(
2673
+ const bulkDeleteAgents = useCallback8(
2572
2674
  async (ids) => {
2573
2675
  setError(null);
2574
2676
  try {
@@ -2593,7 +2695,7 @@ function useAgents(options = true) {
2593
2695
  },
2594
2696
  [fetchWithAuth]
2595
2697
  );
2596
- useEffect7(() => {
2698
+ useEffect8(() => {
2597
2699
  if (autoFetch) void fetchAgents();
2598
2700
  }, [autoFetch, fetchAgents]);
2599
2701
  return {
@@ -2611,13 +2713,13 @@ function useAgents(options = true) {
2611
2713
  }
2612
2714
 
2613
2715
  // src/hooks/useConnection.ts
2614
- import { useCallback as useCallback8, useEffect as useEffect8, useState as useState8 } from "react";
2716
+ import { useCallback as useCallback9, useEffect as useEffect9, useState as useState9 } from "react";
2615
2717
  function useConnection(autoCheck = true) {
2616
2718
  const { fetchWithAuth } = usePersonaContext();
2617
- const [health, setHealth] = useState8(null);
2618
- const [isConnected, setIsConnected] = useState8(false);
2619
- const [isLoading, setIsLoading] = useState8(false);
2620
- const checkHealth = useCallback8(async () => {
2719
+ const [health, setHealth] = useState9(null);
2720
+ const [isConnected, setIsConnected] = useState9(false);
2721
+ const [isLoading, setIsLoading] = useState9(false);
2722
+ const checkHealth = useCallback9(async () => {
2621
2723
  setIsLoading(true);
2622
2724
  try {
2623
2725
  const res = await fetchWithAuth("/health");
@@ -2636,7 +2738,7 @@ function useConnection(autoCheck = true) {
2636
2738
  setIsLoading(false);
2637
2739
  }
2638
2740
  }, [fetchWithAuth]);
2639
- useEffect8(() => {
2741
+ useEffect9(() => {
2640
2742
  if (autoCheck) {
2641
2743
  void checkHealth();
2642
2744
  }
@@ -2650,15 +2752,15 @@ function useConnection(autoCheck = true) {
2650
2752
  }
2651
2753
 
2652
2754
  // src/hooks/useMcpConnections.ts
2653
- import { useCallback as useCallback9, useEffect as useEffect9, useState as useState9 } from "react";
2755
+ import { useCallback as useCallback10, useEffect as useEffect10, useState as useState10 } from "react";
2654
2756
  function useMcpConnections(options = {}) {
2655
2757
  const { defaultAgentId, fetchWithAuth } = usePersonaContext();
2656
2758
  const agentId = options.agentId ?? defaultAgentId;
2657
2759
  const autoFetch = options.autoFetch ?? true;
2658
- const [connections, setConnections] = useState9([]);
2659
- const [isLoading, setIsLoading] = useState9(false);
2660
- const [error, setError] = useState9(null);
2661
- const fetchConnections = useCallback9(async () => {
2760
+ const [connections, setConnections] = useState10([]);
2761
+ const [isLoading, setIsLoading] = useState10(false);
2762
+ const [error, setError] = useState10(null);
2763
+ const fetchConnections = useCallback10(async () => {
2662
2764
  if (!agentId) return [];
2663
2765
  setIsLoading(true);
2664
2766
  setError(null);
@@ -2682,8 +2784,8 @@ function useMcpConnections(options = {}) {
2682
2784
  setIsLoading(false);
2683
2785
  }
2684
2786
  }, [agentId, fetchWithAuth, options.returnTo]);
2685
- const [isDisconnecting, setIsDisconnecting] = useState9(false);
2686
- const disconnect = useCallback9(
2787
+ const [isDisconnecting, setIsDisconnecting] = useState10(false);
2788
+ const disconnect = useCallback10(
2687
2789
  async (mcpId) => {
2688
2790
  setIsDisconnecting(true);
2689
2791
  setError(null);
@@ -2709,7 +2811,7 @@ function useMcpConnections(options = {}) {
2709
2811
  },
2710
2812
  [fetchWithAuth, fetchConnections]
2711
2813
  );
2712
- useEffect9(() => {
2814
+ useEffect10(() => {
2713
2815
  if (autoFetch) void fetchConnections();
2714
2816
  }, [autoFetch, fetchConnections]);
2715
2817
  return {
@@ -2725,11 +2827,11 @@ function useMcpConnections(options = {}) {
2725
2827
  }
2726
2828
 
2727
2829
  // src/hooks/useMcp.ts
2728
- import { useCallback as useCallback10 } from "react";
2830
+ import { useCallback as useCallback11 } from "react";
2729
2831
  function useMcp(options = {}) {
2730
2832
  const { fetchWithAuth } = usePersonaContext();
2731
2833
  const defaultMcpId = options.mcpId;
2732
- const readResource = useCallback10(
2834
+ const readResource = useCallback11(
2733
2835
  async (uri, mcpId) => {
2734
2836
  const id = mcpId ?? defaultMcpId;
2735
2837
  if (!id) throw new Error("MCP server ID is required to read resource");
@@ -2743,7 +2845,7 @@ function useMcp(options = {}) {
2743
2845
  },
2744
2846
  [fetchWithAuth, defaultMcpId]
2745
2847
  );
2746
- const callTool = useCallback10(
2848
+ const callTool = useCallback11(
2747
2849
  async (name, args, mcpId) => {
2748
2850
  const id = mcpId ?? defaultMcpId;
2749
2851
  if (!id) throw new Error("MCP server ID is required to call tool");
@@ -2766,20 +2868,20 @@ function useMcp(options = {}) {
2766
2868
  }
2767
2869
 
2768
2870
  // src/hooks/useSkills.ts
2769
- import { useCallback as useCallback11, useEffect as useEffect10, useState as useState10 } from "react";
2871
+ import { useCallback as useCallback12, useEffect as useEffect11, useState as useState11 } from "react";
2770
2872
  function useSkills(options = {}) {
2771
2873
  const { autoFetch = true, page, limit, search, scope } = options;
2772
2874
  const { fetchWithAuth } = usePersonaContext();
2773
- const [skills, setSkills] = useState10([]);
2774
- const [pagination, setPagination] = useState10({
2875
+ const [skills, setSkills] = useState11([]);
2876
+ const [pagination, setPagination] = useState11({
2775
2877
  total: 0,
2776
2878
  page: page ?? 1,
2777
2879
  limit: limit ?? 20,
2778
2880
  pages: 0
2779
2881
  });
2780
- const [isLoading, setIsLoading] = useState10(false);
2781
- const [error, setError] = useState10(null);
2782
- const fetchSkills = useCallback11(async () => {
2882
+ const [isLoading, setIsLoading] = useState11(false);
2883
+ const [error, setError] = useState11(null);
2884
+ const fetchSkills = useCallback12(async () => {
2783
2885
  setIsLoading(true);
2784
2886
  setError(null);
2785
2887
  try {
@@ -2806,7 +2908,7 @@ function useSkills(options = {}) {
2806
2908
  setIsLoading(false);
2807
2909
  }
2808
2910
  }, [fetchWithAuth, page, limit, search, scope]);
2809
- const getSkill = useCallback11(
2911
+ const getSkill = useCallback12(
2810
2912
  async (skillId) => {
2811
2913
  const res = await fetchWithAuth(`/skills/${skillId}`);
2812
2914
  if (!res.ok) throw new Error(`Failed to fetch skill: ${res.statusText}`);
@@ -2814,7 +2916,7 @@ function useSkills(options = {}) {
2814
2916
  },
2815
2917
  [fetchWithAuth]
2816
2918
  );
2817
- const createSkill = useCallback11(
2919
+ const createSkill = useCallback12(
2818
2920
  async (input) => {
2819
2921
  setError(null);
2820
2922
  try {
@@ -2838,7 +2940,7 @@ function useSkills(options = {}) {
2838
2940
  },
2839
2941
  [fetchWithAuth]
2840
2942
  );
2841
- const updateSkill = useCallback11(
2943
+ const updateSkill = useCallback12(
2842
2944
  async (skillId, input) => {
2843
2945
  setError(null);
2844
2946
  try {
@@ -2862,7 +2964,7 @@ function useSkills(options = {}) {
2862
2964
  },
2863
2965
  [fetchWithAuth]
2864
2966
  );
2865
- const deleteSkill = useCallback11(
2967
+ const deleteSkill = useCallback12(
2866
2968
  async (skillId) => {
2867
2969
  setError(null);
2868
2970
  try {
@@ -2880,7 +2982,7 @@ function useSkills(options = {}) {
2880
2982
  },
2881
2983
  [fetchWithAuth]
2882
2984
  );
2883
- const bulkDeleteSkills = useCallback11(
2985
+ const bulkDeleteSkills = useCallback12(
2884
2986
  async (ids) => {
2885
2987
  setError(null);
2886
2988
  try {
@@ -2905,7 +3007,7 @@ function useSkills(options = {}) {
2905
3007
  },
2906
3008
  [fetchWithAuth]
2907
3009
  );
2908
- const getSkillUsage = useCallback11(
3010
+ const getSkillUsage = useCallback12(
2909
3011
  async (skillId) => {
2910
3012
  const res = await fetchWithAuth(`/skills/${skillId}/usage`);
2911
3013
  if (!res.ok) throw new Error(`Failed to fetch skill usage: ${res.statusText}`);
@@ -2913,7 +3015,7 @@ function useSkills(options = {}) {
2913
3015
  },
2914
3016
  [fetchWithAuth]
2915
3017
  );
2916
- useEffect10(() => {
3018
+ useEffect11(() => {
2917
3019
  if (autoFetch) void fetchSkills();
2918
3020
  }, [autoFetch, fetchSkills]);
2919
3021
  return {
@@ -2932,20 +3034,20 @@ function useSkills(options = {}) {
2932
3034
  }
2933
3035
 
2934
3036
  // src/hooks/useRcpSources.ts
2935
- import { useCallback as useCallback12, useEffect as useEffect11, useState as useState11 } from "react";
3037
+ import { useCallback as useCallback13, useEffect as useEffect12, useState as useState12 } from "react";
2936
3038
  function useRcpSources(options = {}) {
2937
3039
  const { autoFetch = true, page, limit, search } = options;
2938
3040
  const { fetchWithAuth } = usePersonaContext();
2939
- const [rcpSources, setRcpSources] = useState11([]);
2940
- const [pagination, setPagination] = useState11({
3041
+ const [rcpSources, setRcpSources] = useState12([]);
3042
+ const [pagination, setPagination] = useState12({
2941
3043
  total: 0,
2942
3044
  page: page ?? 1,
2943
3045
  limit: limit ?? 20,
2944
3046
  pages: 0
2945
3047
  });
2946
- const [isLoading, setIsLoading] = useState11(false);
2947
- const [error, setError] = useState11(null);
2948
- const fetchRcpSources = useCallback12(async () => {
3048
+ const [isLoading, setIsLoading] = useState12(false);
3049
+ const [error, setError] = useState12(null);
3050
+ const fetchRcpSources = useCallback13(async () => {
2949
3051
  setIsLoading(true);
2950
3052
  setError(null);
2951
3053
  try {
@@ -2971,7 +3073,7 @@ function useRcpSources(options = {}) {
2971
3073
  setIsLoading(false);
2972
3074
  }
2973
3075
  }, [fetchWithAuth, page, limit, search]);
2974
- const getRcpSource = useCallback12(
3076
+ const getRcpSource = useCallback13(
2975
3077
  async (sourceId) => {
2976
3078
  const res = await fetchWithAuth(`/rcp-sources/${sourceId}`);
2977
3079
  if (!res.ok) throw new Error(`Failed to fetch RCP source: ${res.statusText}`);
@@ -2979,7 +3081,7 @@ function useRcpSources(options = {}) {
2979
3081
  },
2980
3082
  [fetchWithAuth]
2981
3083
  );
2982
- const createRcpSource = useCallback12(
3084
+ const createRcpSource = useCallback13(
2983
3085
  async (input) => {
2984
3086
  setError(null);
2985
3087
  try {
@@ -3003,7 +3105,7 @@ function useRcpSources(options = {}) {
3003
3105
  },
3004
3106
  [fetchWithAuth]
3005
3107
  );
3006
- const updateRcpSource = useCallback12(
3108
+ const updateRcpSource = useCallback13(
3007
3109
  async (sourceId, input) => {
3008
3110
  setError(null);
3009
3111
  try {
@@ -3027,7 +3129,7 @@ function useRcpSources(options = {}) {
3027
3129
  },
3028
3130
  [fetchWithAuth]
3029
3131
  );
3030
- const deleteRcpSource = useCallback12(
3132
+ const deleteRcpSource = useCallback13(
3031
3133
  async (sourceId) => {
3032
3134
  setError(null);
3033
3135
  try {
@@ -3045,7 +3147,7 @@ function useRcpSources(options = {}) {
3045
3147
  },
3046
3148
  [fetchWithAuth]
3047
3149
  );
3048
- const bulkDeleteRcpSources = useCallback12(
3150
+ const bulkDeleteRcpSources = useCallback13(
3049
3151
  async (ids) => {
3050
3152
  setError(null);
3051
3153
  try {
@@ -3070,7 +3172,7 @@ function useRcpSources(options = {}) {
3070
3172
  },
3071
3173
  [fetchWithAuth]
3072
3174
  );
3073
- const getRcpSourceUsage = useCallback12(
3175
+ const getRcpSourceUsage = useCallback13(
3074
3176
  async (sourceId) => {
3075
3177
  const res = await fetchWithAuth(`/rcp-sources/${sourceId}/usage`);
3076
3178
  if (!res.ok) throw new Error(`Failed to fetch RCP source usage: ${res.statusText}`);
@@ -3078,7 +3180,7 @@ function useRcpSources(options = {}) {
3078
3180
  },
3079
3181
  [fetchWithAuth]
3080
3182
  );
3081
- const testRcpSourceConnection = useCallback12(
3183
+ const testRcpSourceConnection = useCallback13(
3082
3184
  async (sourceId) => {
3083
3185
  setError(null);
3084
3186
  try {
@@ -3102,7 +3204,7 @@ function useRcpSources(options = {}) {
3102
3204
  },
3103
3205
  [fetchWithAuth]
3104
3206
  );
3105
- useEffect11(() => {
3207
+ useEffect12(() => {
3106
3208
  if (autoFetch) void fetchRcpSources();
3107
3209
  }, [autoFetch, fetchRcpSources]);
3108
3210
  return {
@@ -3121,28 +3223,475 @@ function useRcpSources(options = {}) {
3121
3223
  };
3122
3224
  }
3123
3225
 
3226
+ // src/hooks/useKnowledgeBases.ts
3227
+ import { useCallback as useCallback14, useEffect as useEffect13, useState as useState13 } from "react";
3228
+ function useKnowledgeBases(options = {}) {
3229
+ const { autoFetch = true, page, limit, search, scope } = options;
3230
+ const { fetchWithAuth } = usePersonaContext();
3231
+ const [knowledgeBases, setKnowledgeBases] = useState13([]);
3232
+ const [pagination, setPagination] = useState13({
3233
+ total: 0,
3234
+ page: page ?? 1,
3235
+ limit: limit ?? 20,
3236
+ pages: 0
3237
+ });
3238
+ const [isLoading, setIsLoading] = useState13(false);
3239
+ const [isUploading, setIsUploading] = useState13(false);
3240
+ const [error, setError] = useState13(null);
3241
+ const fetchKnowledgeBases = useCallback14(async () => {
3242
+ setIsLoading(true);
3243
+ setError(null);
3244
+ try {
3245
+ const query = new URLSearchParams();
3246
+ if (page) query.set("page", String(page));
3247
+ if (limit) query.set("limit", String(limit));
3248
+ if (search) query.set("search", search);
3249
+ if (scope) query.set("scope", scope);
3250
+ const queryStr = query.toString() ? `?${query.toString()}` : "";
3251
+ const res = await fetchWithAuth(`/knowledge${queryStr}`);
3252
+ if (!res.ok) throw new Error(`Failed to list knowledge bases: ${res.statusText}`);
3253
+ const data = await res.json();
3254
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3255
+ setKnowledgeBases(items);
3256
+ setPagination(
3257
+ data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
3258
+ );
3259
+ return items;
3260
+ } catch (err) {
3261
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3262
+ setError(errorObj);
3263
+ return [];
3264
+ } finally {
3265
+ setIsLoading(false);
3266
+ }
3267
+ }, [fetchWithAuth, page, limit, search, scope]);
3268
+ const getKnowledgeBase = useCallback14(
3269
+ async (kbId) => {
3270
+ const res = await fetchWithAuth(`/knowledge/${kbId}`);
3271
+ if (!res.ok) throw new Error(`Failed to fetch knowledge base: ${res.statusText}`);
3272
+ return res.json();
3273
+ },
3274
+ [fetchWithAuth]
3275
+ );
3276
+ const createKnowledgeBase = useCallback14(
3277
+ async (input) => {
3278
+ setError(null);
3279
+ try {
3280
+ const res = await fetchWithAuth("/knowledge", {
3281
+ method: "POST",
3282
+ headers: { "Content-Type": "application/json" },
3283
+ body: JSON.stringify(input)
3284
+ });
3285
+ if (!res.ok) {
3286
+ const errText = await res.text().catch(() => res.statusText);
3287
+ throw new Error(`Failed to create knowledge base (${res.status}): ${errText}`);
3288
+ }
3289
+ const created = await res.json();
3290
+ setKnowledgeBases((prev) => [created, ...prev]);
3291
+ return created;
3292
+ } catch (err) {
3293
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3294
+ setError(errorObj);
3295
+ throw errorObj;
3296
+ }
3297
+ },
3298
+ [fetchWithAuth]
3299
+ );
3300
+ const updateKnowledgeBase = useCallback14(
3301
+ async (kbId, input) => {
3302
+ setError(null);
3303
+ try {
3304
+ const res = await fetchWithAuth(`/knowledge/${kbId}`, {
3305
+ method: "PATCH",
3306
+ headers: { "Content-Type": "application/json" },
3307
+ body: JSON.stringify(input)
3308
+ });
3309
+ if (!res.ok) {
3310
+ const errText = await res.text().catch(() => res.statusText);
3311
+ throw new Error(`Failed to update knowledge base (${res.status}): ${errText}`);
3312
+ }
3313
+ const updated = await res.json();
3314
+ setKnowledgeBases((prev) => prev.map((kb) => kb._id === kbId ? updated : kb));
3315
+ return updated;
3316
+ } catch (err) {
3317
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3318
+ setError(errorObj);
3319
+ throw errorObj;
3320
+ }
3321
+ },
3322
+ [fetchWithAuth]
3323
+ );
3324
+ const deleteKnowledgeBase = useCallback14(
3325
+ async (kbId) => {
3326
+ setError(null);
3327
+ try {
3328
+ const res = await fetchWithAuth(`/knowledge/${kbId}`, { method: "DELETE" });
3329
+ if (!res.ok) {
3330
+ const errText = await res.text().catch(() => res.statusText);
3331
+ throw new Error(`Failed to delete knowledge base (${res.status}): ${errText}`);
3332
+ }
3333
+ setKnowledgeBases((prev) => prev.filter((kb) => kb._id !== kbId));
3334
+ } catch (err) {
3335
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3336
+ setError(errorObj);
3337
+ throw errorObj;
3338
+ }
3339
+ },
3340
+ [fetchWithAuth]
3341
+ );
3342
+ const bulkDeleteKnowledgeBases = useCallback14(
3343
+ async (ids) => {
3344
+ setError(null);
3345
+ try {
3346
+ const res = await fetchWithAuth("/knowledge/bulk-delete", {
3347
+ method: "POST",
3348
+ headers: { "Content-Type": "application/json" },
3349
+ body: JSON.stringify({ ids })
3350
+ });
3351
+ if (!res.ok) {
3352
+ const errText = await res.text().catch(() => res.statusText);
3353
+ throw new Error(`Failed to bulk-delete knowledge bases (${res.status}): ${errText}`);
3354
+ }
3355
+ const result = await res.json();
3356
+ const deletedSet = new Set(result.deleted);
3357
+ setKnowledgeBases((prev) => prev.filter((kb) => !deletedSet.has(kb._id)));
3358
+ return result;
3359
+ } catch (err) {
3360
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3361
+ setError(errorObj);
3362
+ throw errorObj;
3363
+ }
3364
+ },
3365
+ [fetchWithAuth]
3366
+ );
3367
+ const getKnowledgeBaseUsage = useCallback14(
3368
+ async (kbId) => {
3369
+ const res = await fetchWithAuth(`/knowledge/${kbId}/usage`);
3370
+ if (!res.ok) throw new Error(`Failed to fetch knowledge base usage: ${res.statusText}`);
3371
+ return res.json();
3372
+ },
3373
+ [fetchWithAuth]
3374
+ );
3375
+ const uploadDocuments = useCallback14(
3376
+ async (kbId, files) => {
3377
+ setIsUploading(true);
3378
+ setError(null);
3379
+ try {
3380
+ const body = new FormData();
3381
+ for (const file of files) {
3382
+ if (file.content instanceof Blob) {
3383
+ body.append("files", file.content, file.filename);
3384
+ } else {
3385
+ body.append("files", {
3386
+ uri: file.content.uri,
3387
+ name: file.content.name ?? file.filename,
3388
+ type: file.content.type ?? file.contentType
3389
+ });
3390
+ }
3391
+ }
3392
+ const res = await fetchWithAuth(`/knowledge/${kbId}/documents`, {
3393
+ method: "POST",
3394
+ body
3395
+ });
3396
+ if (!res.ok) {
3397
+ const errText = await res.text().catch(() => res.statusText);
3398
+ throw new Error(`Failed to upload documents (${res.status}): ${errText}`);
3399
+ }
3400
+ const result = await res.json();
3401
+ setKnowledgeBases(
3402
+ (prev) => prev.map(
3403
+ (kb) => kb._id === kbId ? { ...kb, documentCount: result.documentCount, chunkCount: result.chunkCount } : kb
3404
+ )
3405
+ );
3406
+ return result;
3407
+ } catch (err) {
3408
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3409
+ setError(errorObj);
3410
+ throw errorObj;
3411
+ } finally {
3412
+ setIsUploading(false);
3413
+ }
3414
+ },
3415
+ [fetchWithAuth]
3416
+ );
3417
+ const listDocuments = useCallback14(
3418
+ async (kbId) => {
3419
+ const res = await fetchWithAuth(`/knowledge/${kbId}/documents`);
3420
+ if (!res.ok) throw new Error(`Failed to list documents: ${res.statusText}`);
3421
+ return res.json();
3422
+ },
3423
+ [fetchWithAuth]
3424
+ );
3425
+ const deleteDocument = useCallback14(
3426
+ async (kbId, sourceName) => {
3427
+ setError(null);
3428
+ try {
3429
+ const res = await fetchWithAuth(
3430
+ `/knowledge/${kbId}/documents/${encodeURIComponent(sourceName)}`,
3431
+ { method: "DELETE" }
3432
+ );
3433
+ if (!res.ok) {
3434
+ const errText = await res.text().catch(() => res.statusText);
3435
+ throw new Error(`Failed to delete document (${res.status}): ${errText}`);
3436
+ }
3437
+ const result = await res.json();
3438
+ setKnowledgeBases(
3439
+ (prev) => prev.map(
3440
+ (kb) => kb._id === kbId ? { ...kb, documentCount: result.remainingDocuments, chunkCount: result.remainingChunks } : kb
3441
+ )
3442
+ );
3443
+ return result;
3444
+ } catch (err) {
3445
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3446
+ setError(errorObj);
3447
+ throw errorObj;
3448
+ }
3449
+ },
3450
+ [fetchWithAuth]
3451
+ );
3452
+ const searchKnowledgeBase = useCallback14(
3453
+ async (kbId, query, opts) => {
3454
+ const res = await fetchWithAuth(`/knowledge/${kbId}/search`, {
3455
+ method: "POST",
3456
+ headers: { "Content-Type": "application/json" },
3457
+ body: JSON.stringify({ query, topK: opts?.topK })
3458
+ });
3459
+ if (!res.ok) {
3460
+ const errText = await res.text().catch(() => res.statusText);
3461
+ throw new Error(`Failed to search knowledge base (${res.status}): ${errText}`);
3462
+ }
3463
+ return res.json();
3464
+ },
3465
+ [fetchWithAuth]
3466
+ );
3467
+ useEffect13(() => {
3468
+ if (autoFetch) void fetchKnowledgeBases();
3469
+ }, [autoFetch, fetchKnowledgeBases]);
3470
+ return {
3471
+ knowledgeBases,
3472
+ pagination,
3473
+ isLoading,
3474
+ isUploading,
3475
+ error,
3476
+ refetch: fetchKnowledgeBases,
3477
+ getKnowledgeBase,
3478
+ createKnowledgeBase,
3479
+ updateKnowledgeBase,
3480
+ deleteKnowledgeBase,
3481
+ bulkDeleteKnowledgeBases,
3482
+ getKnowledgeBaseUsage,
3483
+ uploadDocuments,
3484
+ listDocuments,
3485
+ deleteDocument,
3486
+ search: searchKnowledgeBase
3487
+ };
3488
+ }
3489
+
3490
+ // src/hooks/useMcpAdmin.ts
3491
+ import { useCallback as useCallback15, useEffect as useEffect14, useState as useState14 } from "react";
3492
+ function useMcpAdmin(options = {}) {
3493
+ const { autoFetch = true, page, limit, search } = options;
3494
+ const { fetchWithAuth } = usePersonaContext();
3495
+ const [mcps, setMcps] = useState14([]);
3496
+ const [pagination, setPagination] = useState14({
3497
+ total: 0,
3498
+ page: page ?? 1,
3499
+ limit: limit ?? 20,
3500
+ pages: 0
3501
+ });
3502
+ const [isLoading, setIsLoading] = useState14(false);
3503
+ const [error, setError] = useState14(null);
3504
+ const fetchMcps = useCallback15(async () => {
3505
+ setIsLoading(true);
3506
+ setError(null);
3507
+ try {
3508
+ const query = new URLSearchParams();
3509
+ if (page) query.set("page", String(page));
3510
+ if (limit) query.set("limit", String(limit));
3511
+ if (search) query.set("search", search);
3512
+ query.set("scope", "mine");
3513
+ const res = await fetchWithAuth(`/mcps?${query.toString()}`);
3514
+ if (!res.ok) throw new Error(`Failed to list MCPs: ${res.statusText}`);
3515
+ const data = await res.json();
3516
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3517
+ setMcps(items);
3518
+ setPagination(
3519
+ data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
3520
+ );
3521
+ return items;
3522
+ } catch (err) {
3523
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3524
+ setError(errorObj);
3525
+ return [];
3526
+ } finally {
3527
+ setIsLoading(false);
3528
+ }
3529
+ }, [fetchWithAuth, page, limit, search]);
3530
+ const getMcp = useCallback15(
3531
+ async (mcpId) => {
3532
+ const res = await fetchWithAuth(`/mcps/${mcpId}`);
3533
+ if (!res.ok) throw new Error(`Failed to fetch MCP: ${res.statusText}`);
3534
+ return res.json();
3535
+ },
3536
+ [fetchWithAuth]
3537
+ );
3538
+ const createMcp = useCallback15(
3539
+ async (input) => {
3540
+ setError(null);
3541
+ try {
3542
+ const res = await fetchWithAuth("/mcps", {
3543
+ method: "POST",
3544
+ headers: { "Content-Type": "application/json" },
3545
+ body: JSON.stringify(input)
3546
+ });
3547
+ if (!res.ok) {
3548
+ const errText = await res.text().catch(() => res.statusText);
3549
+ throw new Error(`Failed to create MCP (${res.status}): ${errText}`);
3550
+ }
3551
+ const created = await res.json();
3552
+ setMcps((prev) => [created, ...prev]);
3553
+ return created;
3554
+ } catch (err) {
3555
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3556
+ setError(errorObj);
3557
+ throw errorObj;
3558
+ }
3559
+ },
3560
+ [fetchWithAuth]
3561
+ );
3562
+ const updateMcp = useCallback15(
3563
+ async (mcpId, input) => {
3564
+ setError(null);
3565
+ try {
3566
+ const res = await fetchWithAuth(`/mcps/${mcpId}`, {
3567
+ method: "PATCH",
3568
+ headers: { "Content-Type": "application/json" },
3569
+ body: JSON.stringify(input)
3570
+ });
3571
+ if (!res.ok) {
3572
+ const errText = await res.text().catch(() => res.statusText);
3573
+ throw new Error(`Failed to update MCP (${res.status}): ${errText}`);
3574
+ }
3575
+ const updated = await res.json();
3576
+ setMcps((prev) => prev.map((m) => m._id === mcpId ? updated : m));
3577
+ return updated;
3578
+ } catch (err) {
3579
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3580
+ setError(errorObj);
3581
+ throw errorObj;
3582
+ }
3583
+ },
3584
+ [fetchWithAuth]
3585
+ );
3586
+ const deleteMcp = useCallback15(
3587
+ async (mcpId) => {
3588
+ setError(null);
3589
+ try {
3590
+ const res = await fetchWithAuth(`/mcps/${mcpId}`, { method: "DELETE" });
3591
+ if (!res.ok) {
3592
+ const errText = await res.text().catch(() => res.statusText);
3593
+ throw new Error(`Failed to delete MCP (${res.status}): ${errText}`);
3594
+ }
3595
+ setMcps((prev) => prev.filter((m) => m._id !== mcpId));
3596
+ } catch (err) {
3597
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3598
+ setError(errorObj);
3599
+ throw errorObj;
3600
+ }
3601
+ },
3602
+ [fetchWithAuth]
3603
+ );
3604
+ const bulkDeleteMcps = useCallback15(
3605
+ async (ids) => {
3606
+ setError(null);
3607
+ try {
3608
+ const res = await fetchWithAuth("/mcps/bulk-delete", {
3609
+ method: "POST",
3610
+ headers: { "Content-Type": "application/json" },
3611
+ body: JSON.stringify({ ids })
3612
+ });
3613
+ if (!res.ok) {
3614
+ const errText = await res.text().catch(() => res.statusText);
3615
+ throw new Error(`Failed to bulk-delete MCPs (${res.status}): ${errText}`);
3616
+ }
3617
+ const result = await res.json();
3618
+ const deletedSet = new Set(result.deleted);
3619
+ setMcps((prev) => prev.filter((m) => !deletedSet.has(m._id)));
3620
+ return result;
3621
+ } catch (err) {
3622
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3623
+ setError(errorObj);
3624
+ throw errorObj;
3625
+ }
3626
+ },
3627
+ [fetchWithAuth]
3628
+ );
3629
+ const testConnection = useCallback15(
3630
+ async (mcpId) => {
3631
+ setError(null);
3632
+ try {
3633
+ const res = await fetchWithAuth(`/mcps/${mcpId}/test`, { method: "POST" });
3634
+ if (!res.ok) {
3635
+ const errText = await res.text().catch(() => res.statusText);
3636
+ throw new Error(`Failed to test MCP connection (${res.status}): ${errText}`);
3637
+ }
3638
+ const result = await res.json();
3639
+ setMcps(
3640
+ (prev) => prev.map(
3641
+ (m) => m._id === mcpId ? { ...m, tools: result.tools, resources: result.resources, resourceTemplates: result.resourceTemplates } : m
3642
+ )
3643
+ );
3644
+ return result;
3645
+ } catch (err) {
3646
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3647
+ setError(errorObj);
3648
+ throw errorObj;
3649
+ }
3650
+ },
3651
+ [fetchWithAuth]
3652
+ );
3653
+ useEffect14(() => {
3654
+ if (autoFetch) void fetchMcps();
3655
+ }, [autoFetch, fetchMcps]);
3656
+ return {
3657
+ mcps,
3658
+ pagination,
3659
+ isLoading,
3660
+ error,
3661
+ refetch: fetchMcps,
3662
+ getMcp,
3663
+ createMcp,
3664
+ updateMcp,
3665
+ deleteMcp,
3666
+ bulkDeleteMcps,
3667
+ testConnection
3668
+ };
3669
+ }
3670
+
3124
3671
  // src/hooks/useWorkflows.ts
3125
- import { useCallback as useCallback13, useEffect as useEffect12, useState as useState12 } from "react";
3672
+ import { useCallback as useCallback16, useEffect as useEffect15, useState as useState15 } from "react";
3126
3673
  function useWorkflows(options) {
3127
3674
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
3128
- const { autoFetch = true, search, status, page, limit } = opts;
3675
+ const { autoFetch = true, search, scope, visibility, isEnabled, page, limit } = opts;
3129
3676
  const { fetchWithAuth } = usePersonaContext();
3130
- const [workflows, setWorkflows] = useState12([]);
3131
- const [pagination, setPagination] = useState12({
3677
+ const [workflows, setWorkflows] = useState15([]);
3678
+ const [pagination, setPagination] = useState15({
3132
3679
  page: page ?? 1,
3133
3680
  limit: limit ?? 20,
3134
3681
  total: 0,
3135
3682
  totalPages: 0
3136
3683
  });
3137
- const [isLoading, setIsLoading] = useState12(false);
3138
- const [error, setError] = useState12(null);
3139
- const fetchWorkflows = useCallback13(async () => {
3684
+ const [isLoading, setIsLoading] = useState15(false);
3685
+ const [error, setError] = useState15(null);
3686
+ const fetchWorkflows = useCallback16(async () => {
3140
3687
  setIsLoading(true);
3141
3688
  setError(null);
3142
3689
  try {
3143
3690
  const params = new URLSearchParams();
3144
3691
  if (search) params.set("search", search);
3145
- if (status) params.set("status", status);
3692
+ if (scope) params.set("scope", scope);
3693
+ if (visibility) params.set("visibility", visibility);
3694
+ if (isEnabled !== void 0) params.set("isEnabled", String(isEnabled));
3146
3695
  if (page) params.set("page", String(page));
3147
3696
  if (limit) params.set("limit", String(limit));
3148
3697
  const queryStr = params.toString() ? `?${params.toString()}` : "";
@@ -3151,7 +3700,7 @@ function useWorkflows(options) {
3151
3700
  throw new Error(`Failed to list workflows: ${res.statusText}`);
3152
3701
  }
3153
3702
  const data = await res.json();
3154
- const items = Array.isArray(data) ? data : data?.items || data?.workflows || [];
3703
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3155
3704
  setWorkflows(items);
3156
3705
  if (data?.pagination) {
3157
3706
  setPagination({
@@ -3179,8 +3728,8 @@ function useWorkflows(options) {
3179
3728
  } finally {
3180
3729
  setIsLoading(false);
3181
3730
  }
3182
- }, [fetchWithAuth, search, status, page, limit]);
3183
- const createWorkflow = useCallback13(
3731
+ }, [fetchWithAuth, search, scope, visibility, isEnabled, page, limit]);
3732
+ const createWorkflow = useCallback16(
3184
3733
  async (input) => {
3185
3734
  setError(null);
3186
3735
  try {
@@ -3204,7 +3753,7 @@ function useWorkflows(options) {
3204
3753
  },
3205
3754
  [fetchWithAuth]
3206
3755
  );
3207
- useEffect12(() => {
3756
+ useEffect15(() => {
3208
3757
  if (autoFetch) {
3209
3758
  void fetchWorkflows();
3210
3759
  }
@@ -3220,17 +3769,17 @@ function useWorkflows(options) {
3220
3769
  }
3221
3770
 
3222
3771
  // src/hooks/useWorkflow.ts
3223
- import { useCallback as useCallback14, useEffect as useEffect13, useState as useState13 } from "react";
3772
+ import { useCallback as useCallback17, useEffect as useEffect16, useState as useState16 } from "react";
3224
3773
  function useWorkflow(workflowId, options) {
3225
3774
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
3226
3775
  const { autoFetch = true } = opts;
3227
3776
  const { fetchWithAuth } = usePersonaContext();
3228
- const [workflow, setWorkflow] = useState13(null);
3229
- const [versions, setVersions] = useState13([]);
3230
- const [mermaid, setMermaid] = useState13(null);
3231
- const [isLoading, setIsLoading] = useState13(false);
3232
- const [error, setError] = useState13(null);
3233
- const fetchWorkflow = useCallback14(async () => {
3777
+ const [workflow, setWorkflow] = useState16(null);
3778
+ const [versions, setVersions] = useState16([]);
3779
+ const [mermaid, setMermaid] = useState16(null);
3780
+ const [isLoading, setIsLoading] = useState16(false);
3781
+ const [error, setError] = useState16(null);
3782
+ const fetchWorkflow = useCallback17(async () => {
3234
3783
  if (!workflowId) return null;
3235
3784
  setIsLoading(true);
3236
3785
  setError(null);
@@ -3250,20 +3799,31 @@ function useWorkflow(workflowId, options) {
3250
3799
  setIsLoading(false);
3251
3800
  }
3252
3801
  }, [fetchWithAuth, workflowId]);
3253
- const fetchVersions = useCallback14(async () => {
3802
+ const fetchVersions = useCallback17(async () => {
3254
3803
  if (!workflowId) return [];
3255
3804
  try {
3256
3805
  const res = await fetchWithAuth(`/workflows/${workflowId}/versions`);
3257
3806
  if (!res.ok) return [];
3258
3807
  const data = await res.json();
3259
- const items = Array.isArray(data) ? data : data?.items || [];
3808
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3260
3809
  setVersions(items);
3261
3810
  return items;
3262
3811
  } catch {
3263
3812
  return [];
3264
3813
  }
3265
3814
  }, [fetchWithAuth, workflowId]);
3266
- const fetchMermaid = useCallback14(async () => {
3815
+ const getVersion = useCallback17(
3816
+ async (version) => {
3817
+ if (!workflowId) throw new Error("Workflow ID is required");
3818
+ const res = await fetchWithAuth(`/workflows/${workflowId}/versions/${version}`);
3819
+ if (!res.ok) {
3820
+ throw new Error(`Failed to fetch workflow version (${res.status}): ${res.statusText}`);
3821
+ }
3822
+ return await res.json();
3823
+ },
3824
+ [fetchWithAuth, workflowId]
3825
+ );
3826
+ const fetchMermaid = useCallback17(async () => {
3267
3827
  if (!workflowId) return "";
3268
3828
  try {
3269
3829
  const res = await fetchWithAuth(`/workflows/${workflowId}/mermaid`);
@@ -3276,18 +3836,18 @@ function useWorkflow(workflowId, options) {
3276
3836
  return "";
3277
3837
  }
3278
3838
  }, [fetchWithAuth, workflowId]);
3279
- const saveDraft = useCallback14(
3280
- async (draft) => {
3839
+ const updateWorkflow = useCallback17(
3840
+ async (input) => {
3281
3841
  if (!workflowId) throw new Error("Workflow ID is required");
3282
3842
  setError(null);
3283
- const res = await fetchWithAuth(`/workflows/${workflowId}/draft`, {
3284
- method: "POST",
3843
+ const res = await fetchWithAuth(`/workflows/${workflowId}`, {
3844
+ method: "PATCH",
3285
3845
  headers: { "Content-Type": "application/json" },
3286
- body: JSON.stringify({ draft })
3846
+ body: JSON.stringify(input)
3287
3847
  });
3288
3848
  if (!res.ok) {
3289
3849
  const errText = await res.text().catch(() => res.statusText);
3290
- throw new Error(`Failed to save draft (${res.status}): ${errText}`);
3850
+ throw new Error(`Failed to update workflow (${res.status}): ${errText}`);
3291
3851
  }
3292
3852
  const updated = await res.json();
3293
3853
  setWorkflow(updated);
@@ -3295,27 +3855,41 @@ function useWorkflow(workflowId, options) {
3295
3855
  },
3296
3856
  [fetchWithAuth, workflowId]
3297
3857
  );
3298
- const publish = useCallback14(
3299
- async (summary) => {
3858
+ const saveDraft = useCallback17(
3859
+ async (draft) => {
3300
3860
  if (!workflowId) throw new Error("Workflow ID is required");
3301
3861
  setError(null);
3302
- const res = await fetchWithAuth(`/workflows/${workflowId}/publish`, {
3303
- method: "POST",
3862
+ const res = await fetchWithAuth(`/workflows/${workflowId}/draft`, {
3863
+ method: "PUT",
3304
3864
  headers: { "Content-Type": "application/json" },
3305
- body: JSON.stringify(summary ? { summary } : {})
3865
+ body: JSON.stringify(draft)
3306
3866
  });
3307
3867
  if (!res.ok) {
3308
3868
  const errText = await res.text().catch(() => res.statusText);
3309
- throw new Error(`Failed to publish workflow (${res.status}): ${errText}`);
3869
+ throw new Error(`Failed to save draft (${res.status}): ${errText}`);
3310
3870
  }
3311
- const versionResult = await res.json();
3312
- void fetchWorkflow();
3313
- void fetchVersions();
3314
- return versionResult;
3871
+ const updated = await res.json();
3872
+ setWorkflow(updated);
3873
+ return updated;
3315
3874
  },
3316
- [fetchWithAuth, workflowId, fetchWorkflow, fetchVersions]
3875
+ [fetchWithAuth, workflowId]
3317
3876
  );
3318
- const deleteWorkflow = useCallback14(async () => {
3877
+ const publish = useCallback17(async () => {
3878
+ if (!workflowId) throw new Error("Workflow ID is required");
3879
+ setError(null);
3880
+ const res = await fetchWithAuth(`/workflows/${workflowId}/publish`, {
3881
+ method: "POST"
3882
+ });
3883
+ if (!res.ok) {
3884
+ const errText = await res.text().catch(() => res.statusText);
3885
+ throw new Error(`Failed to publish workflow (${res.status}): ${errText}`);
3886
+ }
3887
+ const versionResult = await res.json();
3888
+ void fetchWorkflow();
3889
+ void fetchVersions();
3890
+ return versionResult;
3891
+ }, [fetchWithAuth, workflowId, fetchWorkflow, fetchVersions]);
3892
+ const deleteWorkflow = useCallback17(async () => {
3319
3893
  if (!workflowId) throw new Error("Workflow ID is required");
3320
3894
  setError(null);
3321
3895
  const res = await fetchWithAuth(`/workflows/${workflowId}`, {
@@ -3326,7 +3900,7 @@ function useWorkflow(workflowId, options) {
3326
3900
  }
3327
3901
  setWorkflow(null);
3328
3902
  }, [fetchWithAuth, workflowId]);
3329
- useEffect13(() => {
3903
+ useEffect16(() => {
3330
3904
  if (autoFetch && workflowId) {
3331
3905
  void fetchWorkflow();
3332
3906
  }
@@ -3339,7 +3913,9 @@ function useWorkflow(workflowId, options) {
3339
3913
  error,
3340
3914
  refetch: fetchWorkflow,
3341
3915
  fetchVersions,
3916
+ getVersion,
3342
3917
  fetchMermaid,
3918
+ updateWorkflow,
3343
3919
  saveDraft,
3344
3920
  publish,
3345
3921
  deleteWorkflow
@@ -3347,25 +3923,25 @@ function useWorkflow(workflowId, options) {
3347
3923
  }
3348
3924
 
3349
3925
  // src/hooks/useWorkflowStream.ts
3350
- import { useCallback as useCallback15, useEffect as useEffect14, useRef as useRef4, useState as useState14 } from "react";
3926
+ import { useCallback as useCallback18, useEffect as useEffect17, useRef as useRef4, useState as useState17 } from "react";
3351
3927
  function useWorkflowStream(workflowId, options) {
3352
3928
  const { baseUrl, getAuthToken, fetchWithAuth, logger } = usePersonaContext();
3353
- const [status, setStatus] = useState14("idle");
3354
- const [runId, setRunId] = useState14(null);
3355
- const [activeNodeId, setActiveNodeId] = useState14(null);
3356
- const [nodeRuns, setNodeRuns] = useState14(
3929
+ const [status, setStatus] = useState17("idle");
3930
+ const [runId, setRunId] = useState17(null);
3931
+ const [activeNodeId, setActiveNodeId] = useState17(null);
3932
+ const [nodeRuns, setNodeRuns] = useState17(
3357
3933
  {}
3358
3934
  );
3359
- const [text, setText] = useState14("");
3360
- const [output, setOutput] = useState14(null);
3361
- const [error, setError] = useState14(null);
3362
- const [events, setEvents] = useState14([]);
3935
+ const [text, setText] = useState17("");
3936
+ const [output, setOutput] = useState17(null);
3937
+ const [error, setError] = useState17(null);
3938
+ const [events, setEvents] = useState17([]);
3363
3939
  const abortControllerRef = useRef4(null);
3364
3940
  const currentRunIdRef = useRef4(null);
3365
3941
  currentRunIdRef.current = runId;
3366
3942
  const optionsRef = useRef4(options);
3367
3943
  optionsRef.current = options;
3368
- const cancel = useCallback15(async () => {
3944
+ const cancel = useCallback18(async () => {
3369
3945
  if (abortControllerRef.current) {
3370
3946
  abortControllerRef.current.abort();
3371
3947
  abortControllerRef.current = null;
@@ -3386,7 +3962,7 @@ function useWorkflowStream(workflowId, options) {
3386
3962
  setStatus("cancelled");
3387
3963
  setActiveNodeId(null);
3388
3964
  }, [fetchWithAuth, logger]);
3389
- const reset = useCallback15(() => {
3965
+ const reset = useCallback18(() => {
3390
3966
  if (abortControllerRef.current) {
3391
3967
  abortControllerRef.current.abort();
3392
3968
  abortControllerRef.current = null;
@@ -3400,7 +3976,7 @@ function useWorkflowStream(workflowId, options) {
3400
3976
  setError(null);
3401
3977
  setEvents([]);
3402
3978
  }, []);
3403
- const processStream = useCallback15(
3979
+ const processStream = useCallback18(
3404
3980
  async (url, method, body, targetRunId) => {
3405
3981
  if (abortControllerRef.current) {
3406
3982
  abortControllerRef.current.abort();
@@ -3565,7 +4141,7 @@ function useWorkflowStream(workflowId, options) {
3565
4141
  },
3566
4142
  [getAuthToken]
3567
4143
  );
3568
- const start = useCallback15(
4144
+ const start = useCallback18(
3569
4145
  async (input, opts) => {
3570
4146
  const targetWfId = opts?.workflowId || workflowId;
3571
4147
  if (!targetWfId) {
@@ -3586,7 +4162,7 @@ function useWorkflowStream(workflowId, options) {
3586
4162
  },
3587
4163
  [workflowId, baseUrl, processStream]
3588
4164
  );
3589
- const resume = useCallback15(
4165
+ const resume = useCallback18(
3590
4166
  async (targetRunId, sinceSeq) => {
3591
4167
  if (!targetRunId) {
3592
4168
  throw new Error("Run ID is required to resume stream");
@@ -3599,7 +4175,7 @@ function useWorkflowStream(workflowId, options) {
3599
4175
  },
3600
4176
  [baseUrl, processStream]
3601
4177
  );
3602
- useEffect14(() => {
4178
+ useEffect17(() => {
3603
4179
  return () => {
3604
4180
  if (abortControllerRef.current) {
3605
4181
  abortControllerRef.current.abort();
@@ -3624,21 +4200,21 @@ function useWorkflowStream(workflowId, options) {
3624
4200
  }
3625
4201
 
3626
4202
  // src/hooks/useWorkflowRuns.ts
3627
- import { useCallback as useCallback16, useEffect as useEffect15, useState as useState15 } from "react";
4203
+ import { useCallback as useCallback19, useEffect as useEffect18, useState as useState18 } from "react";
3628
4204
  function useWorkflowRuns(workflowId, options) {
3629
4205
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
3630
4206
  const { autoFetch = true, page = 1, limit = 20 } = opts;
3631
4207
  const { fetchWithAuth } = usePersonaContext();
3632
- const [runs, setRuns] = useState15([]);
3633
- const [pagination, setPagination] = useState15({
4208
+ const [runs, setRuns] = useState18([]);
4209
+ const [pagination, setPagination] = useState18({
3634
4210
  page,
3635
4211
  limit,
3636
4212
  total: 0,
3637
4213
  totalPages: 0
3638
4214
  });
3639
- const [isLoading, setIsLoading] = useState15(false);
3640
- const [error, setError] = useState15(null);
3641
- const fetchRuns = useCallback16(async () => {
4215
+ const [isLoading, setIsLoading] = useState18(false);
4216
+ const [error, setError] = useState18(null);
4217
+ const fetchRuns = useCallback19(async () => {
3642
4218
  if (!workflowId) return [];
3643
4219
  setIsLoading(true);
3644
4220
  setError(null);
@@ -3649,14 +4225,16 @@ function useWorkflowRuns(workflowId, options) {
3649
4225
  throw new Error(`Failed to list workflow runs: ${res.statusText}`);
3650
4226
  }
3651
4227
  const data = await res.json();
3652
- const items = Array.isArray(data) ? data : data?.items || data?.runs || [];
4228
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3653
4229
  setRuns(items);
3654
4230
  if (data?.pagination) {
3655
4231
  setPagination({
3656
4232
  page: data.pagination.page ?? page,
3657
4233
  limit: data.pagination.limit ?? limit,
3658
4234
  total: data.pagination.total ?? items.length,
3659
- totalPages: data.pagination.totalPages ?? 1
4235
+ // Backend's paginationEnvelope() names this field `pages`, not
4236
+ // `totalPages`.
4237
+ totalPages: data.pagination.pages ?? 1
3660
4238
  });
3661
4239
  }
3662
4240
  return items;
@@ -3668,7 +4246,7 @@ function useWorkflowRuns(workflowId, options) {
3668
4246
  setIsLoading(false);
3669
4247
  }
3670
4248
  }, [fetchWithAuth, workflowId, page, limit]);
3671
- const getRun = useCallback16(
4249
+ const getRun = useCallback19(
3672
4250
  async (runId) => {
3673
4251
  if (!runId) throw new Error("Run ID is required");
3674
4252
  const res = await fetchWithAuth(`/workflows/runs/${runId}`);
@@ -3679,7 +4257,7 @@ function useWorkflowRuns(workflowId, options) {
3679
4257
  },
3680
4258
  [fetchWithAuth]
3681
4259
  );
3682
- const cancelRun = useCallback16(
4260
+ const cancelRun = useCallback19(
3683
4261
  async (runId) => {
3684
4262
  if (!runId) throw new Error("Run ID is required");
3685
4263
  const res = await fetchWithAuth(`/workflows/runs/${runId}/cancel`, {
@@ -3694,7 +4272,7 @@ function useWorkflowRuns(workflowId, options) {
3694
4272
  },
3695
4273
  [fetchWithAuth]
3696
4274
  );
3697
- useEffect15(() => {
4275
+ useEffect18(() => {
3698
4276
  if (autoFetch && workflowId) {
3699
4277
  void fetchRuns();
3700
4278
  }
@@ -3735,7 +4313,9 @@ export {
3735
4313
  useChat,
3736
4314
  useConnection,
3737
4315
  useFiles,
4316
+ useKnowledgeBases,
3738
4317
  useMcp,
4318
+ useMcpAdmin,
3739
4319
  useMcpConnections,
3740
4320
  useMemory,
3741
4321
  usePersonaContext,
@@ -3746,6 +4326,7 @@ export {
3746
4326
  useWorkflow,
3747
4327
  useWorkflowRuns,
3748
4328
  useWorkflowStream,
3749
- useWorkflows
4329
+ useWorkflows,
4330
+ useWorkspaceFiles
3750
4331
  };
3751
4332
  //# sourceMappingURL=index.js.map