@personaai/react 0.10.0 → 0.14.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/README.md +210 -210
- package/dist/docs/.nojekyll +1 -0
- package/dist/index.cjs +1176 -183
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +801 -57
- package/dist/index.d.ts +801 -57
- package/dist/index.js +1169 -180
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -35,10 +35,14 @@ __export(index_exports, {
|
|
|
35
35
|
useChat: () => useChat,
|
|
36
36
|
useConnection: () => useConnection,
|
|
37
37
|
useFiles: () => useFiles,
|
|
38
|
+
useKnowledgeBases: () => useKnowledgeBases,
|
|
38
39
|
useMcp: () => useMcp,
|
|
40
|
+
useMcpAdmin: () => useMcpAdmin,
|
|
39
41
|
useMcpConnections: () => useMcpConnections,
|
|
40
42
|
useMemory: () => useMemory,
|
|
41
43
|
usePersonaContext: () => usePersonaContext,
|
|
44
|
+
useRcpSources: () => useRcpSources,
|
|
45
|
+
useSkills: () => useSkills,
|
|
42
46
|
useThreads: () => useThreads,
|
|
43
47
|
useVoice: () => useVoice,
|
|
44
48
|
useWorkflow: () => useWorkflow,
|
|
@@ -2503,20 +2507,38 @@ function useFiles(autoFetch = true) {
|
|
|
2503
2507
|
|
|
2504
2508
|
// src/hooks/useAgents.ts
|
|
2505
2509
|
var import_react8 = require("react");
|
|
2506
|
-
function useAgents(
|
|
2510
|
+
function useAgents(options = true) {
|
|
2511
|
+
const opts = typeof options === "boolean" ? { autoFetch: options } : options;
|
|
2512
|
+
const { autoFetch = true, page, limit, search, category, scope } = opts;
|
|
2507
2513
|
const { fetchWithAuth } = usePersonaContext();
|
|
2508
2514
|
const [agents, setAgents] = (0, import_react8.useState)([]);
|
|
2515
|
+
const [pagination, setPagination] = (0, import_react8.useState)({
|
|
2516
|
+
total: 0,
|
|
2517
|
+
page: page ?? 1,
|
|
2518
|
+
limit: limit ?? 20,
|
|
2519
|
+
pages: 0
|
|
2520
|
+
});
|
|
2509
2521
|
const [isLoading, setIsLoading] = (0, import_react8.useState)(false);
|
|
2510
2522
|
const [error, setError] = (0, import_react8.useState)(null);
|
|
2511
2523
|
const fetchAgents = (0, import_react8.useCallback)(async () => {
|
|
2512
2524
|
setIsLoading(true);
|
|
2513
2525
|
setError(null);
|
|
2514
2526
|
try {
|
|
2515
|
-
const
|
|
2527
|
+
const query = new URLSearchParams();
|
|
2528
|
+
if (page) query.set("page", String(page));
|
|
2529
|
+
if (limit) query.set("limit", String(limit));
|
|
2530
|
+
if (search) query.set("search", search);
|
|
2531
|
+
if (category) query.set("category", category);
|
|
2532
|
+
if (scope) query.set("scope", scope);
|
|
2533
|
+
const queryStr = query.toString() ? `?${query.toString()}` : "";
|
|
2534
|
+
const res = await fetchWithAuth(`/agents${queryStr}`);
|
|
2516
2535
|
if (!res.ok) throw new Error(`Failed to list agents: ${res.statusText}`);
|
|
2517
2536
|
const data = await res.json();
|
|
2518
|
-
const items = Array.isArray(data) ? data : data?.items
|
|
2537
|
+
const items = Array.isArray(data) ? data : data?.items ?? [];
|
|
2519
2538
|
setAgents(items);
|
|
2539
|
+
setPagination(
|
|
2540
|
+
data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
|
|
2541
|
+
);
|
|
2520
2542
|
return items;
|
|
2521
2543
|
} catch (err) {
|
|
2522
2544
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
@@ -2525,83 +2547,929 @@ function useAgents(autoFetch = true) {
|
|
|
2525
2547
|
} finally {
|
|
2526
2548
|
setIsLoading(false);
|
|
2527
2549
|
}
|
|
2528
|
-
}, [fetchWithAuth]);
|
|
2550
|
+
}, [fetchWithAuth, page, limit, search, category, scope]);
|
|
2551
|
+
const getAgent = (0, import_react8.useCallback)(
|
|
2552
|
+
async (agentId) => {
|
|
2553
|
+
const res = await fetchWithAuth(`/agents/${agentId}`);
|
|
2554
|
+
if (!res.ok) throw new Error(`Failed to fetch agent: ${res.statusText}`);
|
|
2555
|
+
return res.json();
|
|
2556
|
+
},
|
|
2557
|
+
[fetchWithAuth]
|
|
2558
|
+
);
|
|
2559
|
+
const createAgent = (0, import_react8.useCallback)(
|
|
2560
|
+
async (input) => {
|
|
2561
|
+
setError(null);
|
|
2562
|
+
try {
|
|
2563
|
+
const res = await fetchWithAuth("/agents", {
|
|
2564
|
+
method: "POST",
|
|
2565
|
+
headers: { "Content-Type": "application/json" },
|
|
2566
|
+
body: JSON.stringify(input)
|
|
2567
|
+
});
|
|
2568
|
+
if (!res.ok) {
|
|
2569
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
2570
|
+
throw new Error(`Failed to create agent (${res.status}): ${errText}`);
|
|
2571
|
+
}
|
|
2572
|
+
const created = await res.json();
|
|
2573
|
+
setAgents((prev) => [created, ...prev]);
|
|
2574
|
+
return created;
|
|
2575
|
+
} catch (err) {
|
|
2576
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2577
|
+
setError(errorObj);
|
|
2578
|
+
throw errorObj;
|
|
2579
|
+
}
|
|
2580
|
+
},
|
|
2581
|
+
[fetchWithAuth]
|
|
2582
|
+
);
|
|
2583
|
+
const updateAgent = (0, import_react8.useCallback)(
|
|
2584
|
+
async (agentId, input) => {
|
|
2585
|
+
setError(null);
|
|
2586
|
+
try {
|
|
2587
|
+
const res = await fetchWithAuth(`/agents/${agentId}`, {
|
|
2588
|
+
method: "PATCH",
|
|
2589
|
+
headers: { "Content-Type": "application/json" },
|
|
2590
|
+
body: JSON.stringify(input)
|
|
2591
|
+
});
|
|
2592
|
+
if (!res.ok) {
|
|
2593
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
2594
|
+
throw new Error(`Failed to update agent (${res.status}): ${errText}`);
|
|
2595
|
+
}
|
|
2596
|
+
const updated = await res.json();
|
|
2597
|
+
setAgents((prev) => prev.map((a) => a._id === agentId ? updated : a));
|
|
2598
|
+
return updated;
|
|
2599
|
+
} catch (err) {
|
|
2600
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2601
|
+
setError(errorObj);
|
|
2602
|
+
throw errorObj;
|
|
2603
|
+
}
|
|
2604
|
+
},
|
|
2605
|
+
[fetchWithAuth]
|
|
2606
|
+
);
|
|
2607
|
+
const deleteAgent = (0, import_react8.useCallback)(
|
|
2608
|
+
async (agentId) => {
|
|
2609
|
+
setError(null);
|
|
2610
|
+
try {
|
|
2611
|
+
const res = await fetchWithAuth(`/agents/${agentId}`, { method: "DELETE" });
|
|
2612
|
+
if (!res.ok) {
|
|
2613
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
2614
|
+
throw new Error(`Failed to delete agent (${res.status}): ${errText}`);
|
|
2615
|
+
}
|
|
2616
|
+
setAgents((prev) => prev.filter((a) => a._id !== agentId));
|
|
2617
|
+
} catch (err) {
|
|
2618
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2619
|
+
setError(errorObj);
|
|
2620
|
+
throw errorObj;
|
|
2621
|
+
}
|
|
2622
|
+
},
|
|
2623
|
+
[fetchWithAuth]
|
|
2624
|
+
);
|
|
2625
|
+
const bulkDeleteAgents = (0, import_react8.useCallback)(
|
|
2626
|
+
async (ids) => {
|
|
2627
|
+
setError(null);
|
|
2628
|
+
try {
|
|
2629
|
+
const res = await fetchWithAuth("/agents/bulk-delete", {
|
|
2630
|
+
method: "POST",
|
|
2631
|
+
headers: { "Content-Type": "application/json" },
|
|
2632
|
+
body: JSON.stringify({ ids })
|
|
2633
|
+
});
|
|
2634
|
+
if (!res.ok) {
|
|
2635
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
2636
|
+
throw new Error(`Failed to bulk-delete agents (${res.status}): ${errText}`);
|
|
2637
|
+
}
|
|
2638
|
+
const result = await res.json();
|
|
2639
|
+
const deletedSet = new Set(result.deleted);
|
|
2640
|
+
setAgents((prev) => prev.filter((a) => !deletedSet.has(a._id)));
|
|
2641
|
+
return result;
|
|
2642
|
+
} catch (err) {
|
|
2643
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2644
|
+
setError(errorObj);
|
|
2645
|
+
throw errorObj;
|
|
2646
|
+
}
|
|
2647
|
+
},
|
|
2648
|
+
[fetchWithAuth]
|
|
2649
|
+
);
|
|
2529
2650
|
(0, import_react8.useEffect)(() => {
|
|
2530
|
-
if (autoFetch)
|
|
2531
|
-
void fetchAgents();
|
|
2532
|
-
}
|
|
2651
|
+
if (autoFetch) void fetchAgents();
|
|
2533
2652
|
}, [autoFetch, fetchAgents]);
|
|
2534
2653
|
return {
|
|
2535
|
-
agents,
|
|
2654
|
+
agents,
|
|
2655
|
+
pagination,
|
|
2656
|
+
isLoading,
|
|
2657
|
+
error,
|
|
2658
|
+
refetch: fetchAgents,
|
|
2659
|
+
getAgent,
|
|
2660
|
+
createAgent,
|
|
2661
|
+
updateAgent,
|
|
2662
|
+
deleteAgent,
|
|
2663
|
+
bulkDeleteAgents
|
|
2664
|
+
};
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
// src/hooks/useConnection.ts
|
|
2668
|
+
var import_react9 = require("react");
|
|
2669
|
+
function useConnection(autoCheck = true) {
|
|
2670
|
+
const { fetchWithAuth } = usePersonaContext();
|
|
2671
|
+
const [health, setHealth] = (0, import_react9.useState)(null);
|
|
2672
|
+
const [isConnected, setIsConnected] = (0, import_react9.useState)(false);
|
|
2673
|
+
const [isLoading, setIsLoading] = (0, import_react9.useState)(false);
|
|
2674
|
+
const checkHealth = (0, import_react9.useCallback)(async () => {
|
|
2675
|
+
setIsLoading(true);
|
|
2676
|
+
try {
|
|
2677
|
+
const res = await fetchWithAuth("/health");
|
|
2678
|
+
if (res.ok) {
|
|
2679
|
+
const data = await res.json();
|
|
2680
|
+
setHealth(data);
|
|
2681
|
+
setIsConnected(true);
|
|
2682
|
+
return data;
|
|
2683
|
+
}
|
|
2684
|
+
setIsConnected(false);
|
|
2685
|
+
return null;
|
|
2686
|
+
} catch {
|
|
2687
|
+
setIsConnected(false);
|
|
2688
|
+
return null;
|
|
2689
|
+
} finally {
|
|
2690
|
+
setIsLoading(false);
|
|
2691
|
+
}
|
|
2692
|
+
}, [fetchWithAuth]);
|
|
2693
|
+
(0, import_react9.useEffect)(() => {
|
|
2694
|
+
if (autoCheck) {
|
|
2695
|
+
void checkHealth();
|
|
2696
|
+
}
|
|
2697
|
+
}, [autoCheck, checkHealth]);
|
|
2698
|
+
return {
|
|
2699
|
+
isConnected,
|
|
2700
|
+
health,
|
|
2701
|
+
isLoading,
|
|
2702
|
+
checkHealth
|
|
2703
|
+
};
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
// src/hooks/useMcpConnections.ts
|
|
2707
|
+
var import_react10 = require("react");
|
|
2708
|
+
function useMcpConnections(options = {}) {
|
|
2709
|
+
const { defaultAgentId, fetchWithAuth } = usePersonaContext();
|
|
2710
|
+
const agentId = options.agentId ?? defaultAgentId;
|
|
2711
|
+
const autoFetch = options.autoFetch ?? true;
|
|
2712
|
+
const [connections, setConnections] = (0, import_react10.useState)([]);
|
|
2713
|
+
const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
|
|
2714
|
+
const [error, setError] = (0, import_react10.useState)(null);
|
|
2715
|
+
const fetchConnections = (0, import_react10.useCallback)(async () => {
|
|
2716
|
+
if (!agentId) return [];
|
|
2717
|
+
setIsLoading(true);
|
|
2718
|
+
setError(null);
|
|
2719
|
+
try {
|
|
2720
|
+
const returnTo = options.returnTo ?? (typeof window !== "undefined" ? window.location.href : void 0);
|
|
2721
|
+
const query = returnTo ? `?returnTo=${encodeURIComponent(returnTo)}` : "";
|
|
2722
|
+
const res = await fetchWithAuth(
|
|
2723
|
+
`/agents/${agentId}/mcp-connections${query}`
|
|
2724
|
+
);
|
|
2725
|
+
if (!res.ok)
|
|
2726
|
+
throw new Error(`Failed to load MCP connections: ${res.statusText}`);
|
|
2727
|
+
const data = await res.json();
|
|
2728
|
+
const items = Array.isArray(data) ? data : data?.items || [];
|
|
2729
|
+
setConnections(items);
|
|
2730
|
+
return items;
|
|
2731
|
+
} catch (err) {
|
|
2732
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2733
|
+
setError(errorObj);
|
|
2734
|
+
return [];
|
|
2735
|
+
} finally {
|
|
2736
|
+
setIsLoading(false);
|
|
2737
|
+
}
|
|
2738
|
+
}, [agentId, fetchWithAuth, options.returnTo]);
|
|
2739
|
+
const [isDisconnecting, setIsDisconnecting] = (0, import_react10.useState)(false);
|
|
2740
|
+
const disconnect = (0, import_react10.useCallback)(
|
|
2741
|
+
async (mcpId) => {
|
|
2742
|
+
setIsDisconnecting(true);
|
|
2743
|
+
setError(null);
|
|
2744
|
+
try {
|
|
2745
|
+
const res = await fetchWithAuth(`/mcps/${mcpId}/oauth/user/connection`, {
|
|
2746
|
+
method: "DELETE"
|
|
2747
|
+
});
|
|
2748
|
+
if (!res.ok)
|
|
2749
|
+
throw new Error(`Failed to disconnect MCP: ${res.statusText}`);
|
|
2750
|
+
setConnections(
|
|
2751
|
+
(prev) => prev.map(
|
|
2752
|
+
(c) => c.mcpId === mcpId ? { ...c, connected: false, authorizeUrl: null } : c
|
|
2753
|
+
)
|
|
2754
|
+
);
|
|
2755
|
+
void fetchConnections();
|
|
2756
|
+
} catch (err) {
|
|
2757
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2758
|
+
setError(errorObj);
|
|
2759
|
+
throw errorObj;
|
|
2760
|
+
} finally {
|
|
2761
|
+
setIsDisconnecting(false);
|
|
2762
|
+
}
|
|
2763
|
+
},
|
|
2764
|
+
[fetchWithAuth, fetchConnections]
|
|
2765
|
+
);
|
|
2766
|
+
(0, import_react10.useEffect)(() => {
|
|
2767
|
+
if (autoFetch) void fetchConnections();
|
|
2768
|
+
}, [autoFetch, fetchConnections]);
|
|
2769
|
+
return {
|
|
2770
|
+
connections,
|
|
2771
|
+
/** Convenience filter for the common "show a banner for what's missing" case. */
|
|
2772
|
+
unconnected: connections.filter((c) => !c.connected),
|
|
2773
|
+
isLoading,
|
|
2774
|
+
error,
|
|
2775
|
+
refetch: fetchConnections,
|
|
2776
|
+
disconnect,
|
|
2777
|
+
isDisconnecting
|
|
2778
|
+
};
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
// src/hooks/useMcp.ts
|
|
2782
|
+
var import_react11 = require("react");
|
|
2783
|
+
function useMcp(options = {}) {
|
|
2784
|
+
const { fetchWithAuth } = usePersonaContext();
|
|
2785
|
+
const defaultMcpId = options.mcpId;
|
|
2786
|
+
const readResource = (0, import_react11.useCallback)(
|
|
2787
|
+
async (uri, mcpId) => {
|
|
2788
|
+
const id = mcpId ?? defaultMcpId;
|
|
2789
|
+
if (!id) throw new Error("MCP server ID is required to read resource");
|
|
2790
|
+
const res = await fetchWithAuth(
|
|
2791
|
+
`/mcps/${id}/resource?uri=${encodeURIComponent(uri)}`
|
|
2792
|
+
);
|
|
2793
|
+
if (!res.ok) {
|
|
2794
|
+
throw new Error(`Failed to read MCP resource: ${res.statusText}`);
|
|
2795
|
+
}
|
|
2796
|
+
return await res.json();
|
|
2797
|
+
},
|
|
2798
|
+
[fetchWithAuth, defaultMcpId]
|
|
2799
|
+
);
|
|
2800
|
+
const callTool = (0, import_react11.useCallback)(
|
|
2801
|
+
async (name, args, mcpId) => {
|
|
2802
|
+
const id = mcpId ?? defaultMcpId;
|
|
2803
|
+
if (!id) throw new Error("MCP server ID is required to call tool");
|
|
2804
|
+
const res = await fetchWithAuth(`/mcps/${id}/call-tool`, {
|
|
2805
|
+
method: "POST",
|
|
2806
|
+
headers: { "Content-Type": "application/json" },
|
|
2807
|
+
body: JSON.stringify({ name, arguments: args })
|
|
2808
|
+
});
|
|
2809
|
+
if (!res.ok) {
|
|
2810
|
+
throw new Error(`Failed to call MCP tool: ${res.statusText}`);
|
|
2811
|
+
}
|
|
2812
|
+
return await res.json();
|
|
2813
|
+
},
|
|
2814
|
+
[fetchWithAuth, defaultMcpId]
|
|
2815
|
+
);
|
|
2816
|
+
return {
|
|
2817
|
+
readResource,
|
|
2818
|
+
callTool
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
// src/hooks/useSkills.ts
|
|
2823
|
+
var import_react12 = require("react");
|
|
2824
|
+
function useSkills(options = {}) {
|
|
2825
|
+
const { autoFetch = true, page, limit, search, scope } = options;
|
|
2826
|
+
const { fetchWithAuth } = usePersonaContext();
|
|
2827
|
+
const [skills, setSkills] = (0, import_react12.useState)([]);
|
|
2828
|
+
const [pagination, setPagination] = (0, import_react12.useState)({
|
|
2829
|
+
total: 0,
|
|
2830
|
+
page: page ?? 1,
|
|
2831
|
+
limit: limit ?? 20,
|
|
2832
|
+
pages: 0
|
|
2833
|
+
});
|
|
2834
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
|
|
2835
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
2836
|
+
const fetchSkills = (0, import_react12.useCallback)(async () => {
|
|
2837
|
+
setIsLoading(true);
|
|
2838
|
+
setError(null);
|
|
2839
|
+
try {
|
|
2840
|
+
const query = new URLSearchParams();
|
|
2841
|
+
if (page) query.set("page", String(page));
|
|
2842
|
+
if (limit) query.set("limit", String(limit));
|
|
2843
|
+
if (search) query.set("search", search);
|
|
2844
|
+
if (scope) query.set("scope", scope);
|
|
2845
|
+
const queryStr = query.toString() ? `?${query.toString()}` : "";
|
|
2846
|
+
const res = await fetchWithAuth(`/skills${queryStr}`);
|
|
2847
|
+
if (!res.ok) throw new Error(`Failed to list skills: ${res.statusText}`);
|
|
2848
|
+
const data = await res.json();
|
|
2849
|
+
const items = Array.isArray(data) ? data : data?.items ?? [];
|
|
2850
|
+
setSkills(items);
|
|
2851
|
+
setPagination(
|
|
2852
|
+
data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
|
|
2853
|
+
);
|
|
2854
|
+
return items;
|
|
2855
|
+
} catch (err) {
|
|
2856
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2857
|
+
setError(errorObj);
|
|
2858
|
+
return [];
|
|
2859
|
+
} finally {
|
|
2860
|
+
setIsLoading(false);
|
|
2861
|
+
}
|
|
2862
|
+
}, [fetchWithAuth, page, limit, search, scope]);
|
|
2863
|
+
const getSkill = (0, import_react12.useCallback)(
|
|
2864
|
+
async (skillId) => {
|
|
2865
|
+
const res = await fetchWithAuth(`/skills/${skillId}`);
|
|
2866
|
+
if (!res.ok) throw new Error(`Failed to fetch skill: ${res.statusText}`);
|
|
2867
|
+
return res.json();
|
|
2868
|
+
},
|
|
2869
|
+
[fetchWithAuth]
|
|
2870
|
+
);
|
|
2871
|
+
const createSkill = (0, import_react12.useCallback)(
|
|
2872
|
+
async (input) => {
|
|
2873
|
+
setError(null);
|
|
2874
|
+
try {
|
|
2875
|
+
const res = await fetchWithAuth("/skills", {
|
|
2876
|
+
method: "POST",
|
|
2877
|
+
headers: { "Content-Type": "application/json" },
|
|
2878
|
+
body: JSON.stringify(input)
|
|
2879
|
+
});
|
|
2880
|
+
if (!res.ok) {
|
|
2881
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
2882
|
+
throw new Error(`Failed to create skill (${res.status}): ${errText}`);
|
|
2883
|
+
}
|
|
2884
|
+
const created = await res.json();
|
|
2885
|
+
setSkills((prev) => [created, ...prev]);
|
|
2886
|
+
return created;
|
|
2887
|
+
} catch (err) {
|
|
2888
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2889
|
+
setError(errorObj);
|
|
2890
|
+
throw errorObj;
|
|
2891
|
+
}
|
|
2892
|
+
},
|
|
2893
|
+
[fetchWithAuth]
|
|
2894
|
+
);
|
|
2895
|
+
const updateSkill = (0, import_react12.useCallback)(
|
|
2896
|
+
async (skillId, input) => {
|
|
2897
|
+
setError(null);
|
|
2898
|
+
try {
|
|
2899
|
+
const res = await fetchWithAuth(`/skills/${skillId}`, {
|
|
2900
|
+
method: "PATCH",
|
|
2901
|
+
headers: { "Content-Type": "application/json" },
|
|
2902
|
+
body: JSON.stringify(input)
|
|
2903
|
+
});
|
|
2904
|
+
if (!res.ok) {
|
|
2905
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
2906
|
+
throw new Error(`Failed to update skill (${res.status}): ${errText}`);
|
|
2907
|
+
}
|
|
2908
|
+
const updated = await res.json();
|
|
2909
|
+
setSkills((prev) => prev.map((s) => s._id === skillId ? updated : s));
|
|
2910
|
+
return updated;
|
|
2911
|
+
} catch (err) {
|
|
2912
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2913
|
+
setError(errorObj);
|
|
2914
|
+
throw errorObj;
|
|
2915
|
+
}
|
|
2916
|
+
},
|
|
2917
|
+
[fetchWithAuth]
|
|
2918
|
+
);
|
|
2919
|
+
const deleteSkill = (0, import_react12.useCallback)(
|
|
2920
|
+
async (skillId) => {
|
|
2921
|
+
setError(null);
|
|
2922
|
+
try {
|
|
2923
|
+
const res = await fetchWithAuth(`/skills/${skillId}`, { method: "DELETE" });
|
|
2924
|
+
if (!res.ok) {
|
|
2925
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
2926
|
+
throw new Error(`Failed to delete skill (${res.status}): ${errText}`);
|
|
2927
|
+
}
|
|
2928
|
+
setSkills((prev) => prev.filter((s) => s._id !== skillId));
|
|
2929
|
+
} catch (err) {
|
|
2930
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2931
|
+
setError(errorObj);
|
|
2932
|
+
throw errorObj;
|
|
2933
|
+
}
|
|
2934
|
+
},
|
|
2935
|
+
[fetchWithAuth]
|
|
2936
|
+
);
|
|
2937
|
+
const bulkDeleteSkills = (0, import_react12.useCallback)(
|
|
2938
|
+
async (ids) => {
|
|
2939
|
+
setError(null);
|
|
2940
|
+
try {
|
|
2941
|
+
const res = await fetchWithAuth("/skills/bulk-delete", {
|
|
2942
|
+
method: "POST",
|
|
2943
|
+
headers: { "Content-Type": "application/json" },
|
|
2944
|
+
body: JSON.stringify({ ids })
|
|
2945
|
+
});
|
|
2946
|
+
if (!res.ok) {
|
|
2947
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
2948
|
+
throw new Error(`Failed to bulk-delete skills (${res.status}): ${errText}`);
|
|
2949
|
+
}
|
|
2950
|
+
const result = await res.json();
|
|
2951
|
+
const deletedSet = new Set(result.deleted);
|
|
2952
|
+
setSkills((prev) => prev.filter((s) => !deletedSet.has(s._id)));
|
|
2953
|
+
return result;
|
|
2954
|
+
} catch (err) {
|
|
2955
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2956
|
+
setError(errorObj);
|
|
2957
|
+
throw errorObj;
|
|
2958
|
+
}
|
|
2959
|
+
},
|
|
2960
|
+
[fetchWithAuth]
|
|
2961
|
+
);
|
|
2962
|
+
const getSkillUsage = (0, import_react12.useCallback)(
|
|
2963
|
+
async (skillId) => {
|
|
2964
|
+
const res = await fetchWithAuth(`/skills/${skillId}/usage`);
|
|
2965
|
+
if (!res.ok) throw new Error(`Failed to fetch skill usage: ${res.statusText}`);
|
|
2966
|
+
return res.json();
|
|
2967
|
+
},
|
|
2968
|
+
[fetchWithAuth]
|
|
2969
|
+
);
|
|
2970
|
+
(0, import_react12.useEffect)(() => {
|
|
2971
|
+
if (autoFetch) void fetchSkills();
|
|
2972
|
+
}, [autoFetch, fetchSkills]);
|
|
2973
|
+
return {
|
|
2974
|
+
skills,
|
|
2975
|
+
pagination,
|
|
2976
|
+
isLoading,
|
|
2977
|
+
error,
|
|
2978
|
+
refetch: fetchSkills,
|
|
2979
|
+
getSkill,
|
|
2980
|
+
createSkill,
|
|
2981
|
+
updateSkill,
|
|
2982
|
+
deleteSkill,
|
|
2983
|
+
bulkDeleteSkills,
|
|
2984
|
+
getSkillUsage
|
|
2985
|
+
};
|
|
2986
|
+
}
|
|
2987
|
+
|
|
2988
|
+
// src/hooks/useRcpSources.ts
|
|
2989
|
+
var import_react13 = require("react");
|
|
2990
|
+
function useRcpSources(options = {}) {
|
|
2991
|
+
const { autoFetch = true, page, limit, search } = options;
|
|
2992
|
+
const { fetchWithAuth } = usePersonaContext();
|
|
2993
|
+
const [rcpSources, setRcpSources] = (0, import_react13.useState)([]);
|
|
2994
|
+
const [pagination, setPagination] = (0, import_react13.useState)({
|
|
2995
|
+
total: 0,
|
|
2996
|
+
page: page ?? 1,
|
|
2997
|
+
limit: limit ?? 20,
|
|
2998
|
+
pages: 0
|
|
2999
|
+
});
|
|
3000
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
|
|
3001
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
3002
|
+
const fetchRcpSources = (0, import_react13.useCallback)(async () => {
|
|
3003
|
+
setIsLoading(true);
|
|
3004
|
+
setError(null);
|
|
3005
|
+
try {
|
|
3006
|
+
const query = new URLSearchParams();
|
|
3007
|
+
if (page) query.set("page", String(page));
|
|
3008
|
+
if (limit) query.set("limit", String(limit));
|
|
3009
|
+
if (search) query.set("search", search);
|
|
3010
|
+
const queryStr = query.toString() ? `?${query.toString()}` : "";
|
|
3011
|
+
const res = await fetchWithAuth(`/rcp-sources${queryStr}`);
|
|
3012
|
+
if (!res.ok) throw new Error(`Failed to list RCP sources: ${res.statusText}`);
|
|
3013
|
+
const data = await res.json();
|
|
3014
|
+
const items = Array.isArray(data) ? data : data?.items ?? [];
|
|
3015
|
+
setRcpSources(items);
|
|
3016
|
+
setPagination(
|
|
3017
|
+
data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
|
|
3018
|
+
);
|
|
3019
|
+
return items;
|
|
3020
|
+
} catch (err) {
|
|
3021
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3022
|
+
setError(errorObj);
|
|
3023
|
+
return [];
|
|
3024
|
+
} finally {
|
|
3025
|
+
setIsLoading(false);
|
|
3026
|
+
}
|
|
3027
|
+
}, [fetchWithAuth, page, limit, search]);
|
|
3028
|
+
const getRcpSource = (0, import_react13.useCallback)(
|
|
3029
|
+
async (sourceId) => {
|
|
3030
|
+
const res = await fetchWithAuth(`/rcp-sources/${sourceId}`);
|
|
3031
|
+
if (!res.ok) throw new Error(`Failed to fetch RCP source: ${res.statusText}`);
|
|
3032
|
+
return res.json();
|
|
3033
|
+
},
|
|
3034
|
+
[fetchWithAuth]
|
|
3035
|
+
);
|
|
3036
|
+
const createRcpSource = (0, import_react13.useCallback)(
|
|
3037
|
+
async (input) => {
|
|
3038
|
+
setError(null);
|
|
3039
|
+
try {
|
|
3040
|
+
const res = await fetchWithAuth("/rcp-sources", {
|
|
3041
|
+
method: "POST",
|
|
3042
|
+
headers: { "Content-Type": "application/json" },
|
|
3043
|
+
body: JSON.stringify(input)
|
|
3044
|
+
});
|
|
3045
|
+
if (!res.ok) {
|
|
3046
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3047
|
+
throw new Error(`Failed to create RCP source (${res.status}): ${errText}`);
|
|
3048
|
+
}
|
|
3049
|
+
const created = await res.json();
|
|
3050
|
+
setRcpSources((prev) => [created, ...prev]);
|
|
3051
|
+
return created;
|
|
3052
|
+
} catch (err) {
|
|
3053
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3054
|
+
setError(errorObj);
|
|
3055
|
+
throw errorObj;
|
|
3056
|
+
}
|
|
3057
|
+
},
|
|
3058
|
+
[fetchWithAuth]
|
|
3059
|
+
);
|
|
3060
|
+
const updateRcpSource = (0, import_react13.useCallback)(
|
|
3061
|
+
async (sourceId, input) => {
|
|
3062
|
+
setError(null);
|
|
3063
|
+
try {
|
|
3064
|
+
const res = await fetchWithAuth(`/rcp-sources/${sourceId}`, {
|
|
3065
|
+
method: "PATCH",
|
|
3066
|
+
headers: { "Content-Type": "application/json" },
|
|
3067
|
+
body: JSON.stringify(input)
|
|
3068
|
+
});
|
|
3069
|
+
if (!res.ok) {
|
|
3070
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3071
|
+
throw new Error(`Failed to update RCP source (${res.status}): ${errText}`);
|
|
3072
|
+
}
|
|
3073
|
+
const updated = await res.json();
|
|
3074
|
+
setRcpSources((prev) => prev.map((s) => s._id === sourceId ? updated : s));
|
|
3075
|
+
return updated;
|
|
3076
|
+
} catch (err) {
|
|
3077
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3078
|
+
setError(errorObj);
|
|
3079
|
+
throw errorObj;
|
|
3080
|
+
}
|
|
3081
|
+
},
|
|
3082
|
+
[fetchWithAuth]
|
|
3083
|
+
);
|
|
3084
|
+
const deleteRcpSource = (0, import_react13.useCallback)(
|
|
3085
|
+
async (sourceId) => {
|
|
3086
|
+
setError(null);
|
|
3087
|
+
try {
|
|
3088
|
+
const res = await fetchWithAuth(`/rcp-sources/${sourceId}`, { method: "DELETE" });
|
|
3089
|
+
if (!res.ok) {
|
|
3090
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3091
|
+
throw new Error(`Failed to delete RCP source (${res.status}): ${errText}`);
|
|
3092
|
+
}
|
|
3093
|
+
setRcpSources((prev) => prev.filter((s) => s._id !== sourceId));
|
|
3094
|
+
} catch (err) {
|
|
3095
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3096
|
+
setError(errorObj);
|
|
3097
|
+
throw errorObj;
|
|
3098
|
+
}
|
|
3099
|
+
},
|
|
3100
|
+
[fetchWithAuth]
|
|
3101
|
+
);
|
|
3102
|
+
const bulkDeleteRcpSources = (0, import_react13.useCallback)(
|
|
3103
|
+
async (ids) => {
|
|
3104
|
+
setError(null);
|
|
3105
|
+
try {
|
|
3106
|
+
const res = await fetchWithAuth("/rcp-sources/bulk-delete", {
|
|
3107
|
+
method: "POST",
|
|
3108
|
+
headers: { "Content-Type": "application/json" },
|
|
3109
|
+
body: JSON.stringify({ ids })
|
|
3110
|
+
});
|
|
3111
|
+
if (!res.ok) {
|
|
3112
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3113
|
+
throw new Error(`Failed to bulk-delete RCP sources (${res.status}): ${errText}`);
|
|
3114
|
+
}
|
|
3115
|
+
const result = await res.json();
|
|
3116
|
+
const deletedSet = new Set(result.deleted);
|
|
3117
|
+
setRcpSources((prev) => prev.filter((s) => !deletedSet.has(s._id)));
|
|
3118
|
+
return result;
|
|
3119
|
+
} catch (err) {
|
|
3120
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3121
|
+
setError(errorObj);
|
|
3122
|
+
throw errorObj;
|
|
3123
|
+
}
|
|
3124
|
+
},
|
|
3125
|
+
[fetchWithAuth]
|
|
3126
|
+
);
|
|
3127
|
+
const getRcpSourceUsage = (0, import_react13.useCallback)(
|
|
3128
|
+
async (sourceId) => {
|
|
3129
|
+
const res = await fetchWithAuth(`/rcp-sources/${sourceId}/usage`);
|
|
3130
|
+
if (!res.ok) throw new Error(`Failed to fetch RCP source usage: ${res.statusText}`);
|
|
3131
|
+
return res.json();
|
|
3132
|
+
},
|
|
3133
|
+
[fetchWithAuth]
|
|
3134
|
+
);
|
|
3135
|
+
const testRcpSourceConnection = (0, import_react13.useCallback)(
|
|
3136
|
+
async (sourceId) => {
|
|
3137
|
+
setError(null);
|
|
3138
|
+
try {
|
|
3139
|
+
const res = await fetchWithAuth(`/rcp-sources/${sourceId}/test`, { method: "POST" });
|
|
3140
|
+
if (!res.ok) {
|
|
3141
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3142
|
+
throw new Error(`Failed to test RCP source connection (${res.status}): ${errText}`);
|
|
3143
|
+
}
|
|
3144
|
+
const result = await res.json();
|
|
3145
|
+
setRcpSources(
|
|
3146
|
+
(prev) => prev.map(
|
|
3147
|
+
(s) => s._id === sourceId ? { ...s, tools: result.tools, lastTestedAt: (/* @__PURE__ */ new Date()).toISOString() } : s
|
|
3148
|
+
)
|
|
3149
|
+
);
|
|
3150
|
+
return result;
|
|
3151
|
+
} catch (err) {
|
|
3152
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3153
|
+
setError(errorObj);
|
|
3154
|
+
throw errorObj;
|
|
3155
|
+
}
|
|
3156
|
+
},
|
|
3157
|
+
[fetchWithAuth]
|
|
3158
|
+
);
|
|
3159
|
+
(0, import_react13.useEffect)(() => {
|
|
3160
|
+
if (autoFetch) void fetchRcpSources();
|
|
3161
|
+
}, [autoFetch, fetchRcpSources]);
|
|
3162
|
+
return {
|
|
3163
|
+
rcpSources,
|
|
3164
|
+
pagination,
|
|
3165
|
+
isLoading,
|
|
3166
|
+
error,
|
|
3167
|
+
refetch: fetchRcpSources,
|
|
3168
|
+
getRcpSource,
|
|
3169
|
+
createRcpSource,
|
|
3170
|
+
updateRcpSource,
|
|
3171
|
+
deleteRcpSource,
|
|
3172
|
+
bulkDeleteRcpSources,
|
|
3173
|
+
getRcpSourceUsage,
|
|
3174
|
+
testRcpSourceConnection
|
|
3175
|
+
};
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
// src/hooks/useKnowledgeBases.ts
|
|
3179
|
+
var import_react14 = require("react");
|
|
3180
|
+
function useKnowledgeBases(options = {}) {
|
|
3181
|
+
const { autoFetch = true, page, limit, search, scope } = options;
|
|
3182
|
+
const { fetchWithAuth } = usePersonaContext();
|
|
3183
|
+
const [knowledgeBases, setKnowledgeBases] = (0, import_react14.useState)([]);
|
|
3184
|
+
const [pagination, setPagination] = (0, import_react14.useState)({
|
|
3185
|
+
total: 0,
|
|
3186
|
+
page: page ?? 1,
|
|
3187
|
+
limit: limit ?? 20,
|
|
3188
|
+
pages: 0
|
|
3189
|
+
});
|
|
3190
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
|
|
3191
|
+
const [isUploading, setIsUploading] = (0, import_react14.useState)(false);
|
|
3192
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
3193
|
+
const fetchKnowledgeBases = (0, import_react14.useCallback)(async () => {
|
|
3194
|
+
setIsLoading(true);
|
|
3195
|
+
setError(null);
|
|
3196
|
+
try {
|
|
3197
|
+
const query = new URLSearchParams();
|
|
3198
|
+
if (page) query.set("page", String(page));
|
|
3199
|
+
if (limit) query.set("limit", String(limit));
|
|
3200
|
+
if (search) query.set("search", search);
|
|
3201
|
+
if (scope) query.set("scope", scope);
|
|
3202
|
+
const queryStr = query.toString() ? `?${query.toString()}` : "";
|
|
3203
|
+
const res = await fetchWithAuth(`/knowledge${queryStr}`);
|
|
3204
|
+
if (!res.ok) throw new Error(`Failed to list knowledge bases: ${res.statusText}`);
|
|
3205
|
+
const data = await res.json();
|
|
3206
|
+
const items = Array.isArray(data) ? data : data?.items ?? [];
|
|
3207
|
+
setKnowledgeBases(items);
|
|
3208
|
+
setPagination(
|
|
3209
|
+
data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
|
|
3210
|
+
);
|
|
3211
|
+
return items;
|
|
3212
|
+
} catch (err) {
|
|
3213
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3214
|
+
setError(errorObj);
|
|
3215
|
+
return [];
|
|
3216
|
+
} finally {
|
|
3217
|
+
setIsLoading(false);
|
|
3218
|
+
}
|
|
3219
|
+
}, [fetchWithAuth, page, limit, search, scope]);
|
|
3220
|
+
const getKnowledgeBase = (0, import_react14.useCallback)(
|
|
3221
|
+
async (kbId) => {
|
|
3222
|
+
const res = await fetchWithAuth(`/knowledge/${kbId}`);
|
|
3223
|
+
if (!res.ok) throw new Error(`Failed to fetch knowledge base: ${res.statusText}`);
|
|
3224
|
+
return res.json();
|
|
3225
|
+
},
|
|
3226
|
+
[fetchWithAuth]
|
|
3227
|
+
);
|
|
3228
|
+
const createKnowledgeBase = (0, import_react14.useCallback)(
|
|
3229
|
+
async (input) => {
|
|
3230
|
+
setError(null);
|
|
3231
|
+
try {
|
|
3232
|
+
const res = await fetchWithAuth("/knowledge", {
|
|
3233
|
+
method: "POST",
|
|
3234
|
+
headers: { "Content-Type": "application/json" },
|
|
3235
|
+
body: JSON.stringify(input)
|
|
3236
|
+
});
|
|
3237
|
+
if (!res.ok) {
|
|
3238
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3239
|
+
throw new Error(`Failed to create knowledge base (${res.status}): ${errText}`);
|
|
3240
|
+
}
|
|
3241
|
+
const created = await res.json();
|
|
3242
|
+
setKnowledgeBases((prev) => [created, ...prev]);
|
|
3243
|
+
return created;
|
|
3244
|
+
} catch (err) {
|
|
3245
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3246
|
+
setError(errorObj);
|
|
3247
|
+
throw errorObj;
|
|
3248
|
+
}
|
|
3249
|
+
},
|
|
3250
|
+
[fetchWithAuth]
|
|
3251
|
+
);
|
|
3252
|
+
const updateKnowledgeBase = (0, import_react14.useCallback)(
|
|
3253
|
+
async (kbId, input) => {
|
|
3254
|
+
setError(null);
|
|
3255
|
+
try {
|
|
3256
|
+
const res = await fetchWithAuth(`/knowledge/${kbId}`, {
|
|
3257
|
+
method: "PATCH",
|
|
3258
|
+
headers: { "Content-Type": "application/json" },
|
|
3259
|
+
body: JSON.stringify(input)
|
|
3260
|
+
});
|
|
3261
|
+
if (!res.ok) {
|
|
3262
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3263
|
+
throw new Error(`Failed to update knowledge base (${res.status}): ${errText}`);
|
|
3264
|
+
}
|
|
3265
|
+
const updated = await res.json();
|
|
3266
|
+
setKnowledgeBases((prev) => prev.map((kb) => kb._id === kbId ? updated : kb));
|
|
3267
|
+
return updated;
|
|
3268
|
+
} catch (err) {
|
|
3269
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3270
|
+
setError(errorObj);
|
|
3271
|
+
throw errorObj;
|
|
3272
|
+
}
|
|
3273
|
+
},
|
|
3274
|
+
[fetchWithAuth]
|
|
3275
|
+
);
|
|
3276
|
+
const deleteKnowledgeBase = (0, import_react14.useCallback)(
|
|
3277
|
+
async (kbId) => {
|
|
3278
|
+
setError(null);
|
|
3279
|
+
try {
|
|
3280
|
+
const res = await fetchWithAuth(`/knowledge/${kbId}`, { method: "DELETE" });
|
|
3281
|
+
if (!res.ok) {
|
|
3282
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3283
|
+
throw new Error(`Failed to delete knowledge base (${res.status}): ${errText}`);
|
|
3284
|
+
}
|
|
3285
|
+
setKnowledgeBases((prev) => prev.filter((kb) => kb._id !== kbId));
|
|
3286
|
+
} catch (err) {
|
|
3287
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3288
|
+
setError(errorObj);
|
|
3289
|
+
throw errorObj;
|
|
3290
|
+
}
|
|
3291
|
+
},
|
|
3292
|
+
[fetchWithAuth]
|
|
3293
|
+
);
|
|
3294
|
+
const bulkDeleteKnowledgeBases = (0, import_react14.useCallback)(
|
|
3295
|
+
async (ids) => {
|
|
3296
|
+
setError(null);
|
|
3297
|
+
try {
|
|
3298
|
+
const res = await fetchWithAuth("/knowledge/bulk-delete", {
|
|
3299
|
+
method: "POST",
|
|
3300
|
+
headers: { "Content-Type": "application/json" },
|
|
3301
|
+
body: JSON.stringify({ ids })
|
|
3302
|
+
});
|
|
3303
|
+
if (!res.ok) {
|
|
3304
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3305
|
+
throw new Error(`Failed to bulk-delete knowledge bases (${res.status}): ${errText}`);
|
|
3306
|
+
}
|
|
3307
|
+
const result = await res.json();
|
|
3308
|
+
const deletedSet = new Set(result.deleted);
|
|
3309
|
+
setKnowledgeBases((prev) => prev.filter((kb) => !deletedSet.has(kb._id)));
|
|
3310
|
+
return result;
|
|
3311
|
+
} catch (err) {
|
|
3312
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3313
|
+
setError(errorObj);
|
|
3314
|
+
throw errorObj;
|
|
3315
|
+
}
|
|
3316
|
+
},
|
|
3317
|
+
[fetchWithAuth]
|
|
3318
|
+
);
|
|
3319
|
+
const getKnowledgeBaseUsage = (0, import_react14.useCallback)(
|
|
3320
|
+
async (kbId) => {
|
|
3321
|
+
const res = await fetchWithAuth(`/knowledge/${kbId}/usage`);
|
|
3322
|
+
if (!res.ok) throw new Error(`Failed to fetch knowledge base usage: ${res.statusText}`);
|
|
3323
|
+
return res.json();
|
|
3324
|
+
},
|
|
3325
|
+
[fetchWithAuth]
|
|
3326
|
+
);
|
|
3327
|
+
const uploadDocuments = (0, import_react14.useCallback)(
|
|
3328
|
+
async (kbId, files) => {
|
|
3329
|
+
setIsUploading(true);
|
|
3330
|
+
setError(null);
|
|
3331
|
+
try {
|
|
3332
|
+
const body = new FormData();
|
|
3333
|
+
for (const file of files) {
|
|
3334
|
+
if (file.content instanceof Blob) {
|
|
3335
|
+
body.append("files", file.content, file.filename);
|
|
3336
|
+
} else {
|
|
3337
|
+
body.append("files", {
|
|
3338
|
+
uri: file.content.uri,
|
|
3339
|
+
name: file.content.name ?? file.filename,
|
|
3340
|
+
type: file.content.type ?? file.contentType
|
|
3341
|
+
});
|
|
3342
|
+
}
|
|
3343
|
+
}
|
|
3344
|
+
const res = await fetchWithAuth(`/knowledge/${kbId}/documents`, {
|
|
3345
|
+
method: "POST",
|
|
3346
|
+
body
|
|
3347
|
+
});
|
|
3348
|
+
if (!res.ok) {
|
|
3349
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3350
|
+
throw new Error(`Failed to upload documents (${res.status}): ${errText}`);
|
|
3351
|
+
}
|
|
3352
|
+
const result = await res.json();
|
|
3353
|
+
setKnowledgeBases(
|
|
3354
|
+
(prev) => prev.map(
|
|
3355
|
+
(kb) => kb._id === kbId ? { ...kb, documentCount: result.documentCount, chunkCount: result.chunkCount } : kb
|
|
3356
|
+
)
|
|
3357
|
+
);
|
|
3358
|
+
return result;
|
|
3359
|
+
} catch (err) {
|
|
3360
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3361
|
+
setError(errorObj);
|
|
3362
|
+
throw errorObj;
|
|
3363
|
+
} finally {
|
|
3364
|
+
setIsUploading(false);
|
|
3365
|
+
}
|
|
3366
|
+
},
|
|
3367
|
+
[fetchWithAuth]
|
|
3368
|
+
);
|
|
3369
|
+
const listDocuments = (0, import_react14.useCallback)(
|
|
3370
|
+
async (kbId) => {
|
|
3371
|
+
const res = await fetchWithAuth(`/knowledge/${kbId}/documents`);
|
|
3372
|
+
if (!res.ok) throw new Error(`Failed to list documents: ${res.statusText}`);
|
|
3373
|
+
return res.json();
|
|
3374
|
+
},
|
|
3375
|
+
[fetchWithAuth]
|
|
3376
|
+
);
|
|
3377
|
+
const deleteDocument = (0, import_react14.useCallback)(
|
|
3378
|
+
async (kbId, sourceName) => {
|
|
3379
|
+
setError(null);
|
|
3380
|
+
try {
|
|
3381
|
+
const res = await fetchWithAuth(
|
|
3382
|
+
`/knowledge/${kbId}/documents/${encodeURIComponent(sourceName)}`,
|
|
3383
|
+
{ method: "DELETE" }
|
|
3384
|
+
);
|
|
3385
|
+
if (!res.ok) {
|
|
3386
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3387
|
+
throw new Error(`Failed to delete document (${res.status}): ${errText}`);
|
|
3388
|
+
}
|
|
3389
|
+
const result = await res.json();
|
|
3390
|
+
setKnowledgeBases(
|
|
3391
|
+
(prev) => prev.map(
|
|
3392
|
+
(kb) => kb._id === kbId ? { ...kb, documentCount: result.remainingDocuments, chunkCount: result.remainingChunks } : kb
|
|
3393
|
+
)
|
|
3394
|
+
);
|
|
3395
|
+
return result;
|
|
3396
|
+
} catch (err) {
|
|
3397
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3398
|
+
setError(errorObj);
|
|
3399
|
+
throw errorObj;
|
|
3400
|
+
}
|
|
3401
|
+
},
|
|
3402
|
+
[fetchWithAuth]
|
|
3403
|
+
);
|
|
3404
|
+
const searchKnowledgeBase = (0, import_react14.useCallback)(
|
|
3405
|
+
async (kbId, query, opts) => {
|
|
3406
|
+
const res = await fetchWithAuth(`/knowledge/${kbId}/search`, {
|
|
3407
|
+
method: "POST",
|
|
3408
|
+
headers: { "Content-Type": "application/json" },
|
|
3409
|
+
body: JSON.stringify({ query, topK: opts?.topK })
|
|
3410
|
+
});
|
|
3411
|
+
if (!res.ok) {
|
|
3412
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3413
|
+
throw new Error(`Failed to search knowledge base (${res.status}): ${errText}`);
|
|
3414
|
+
}
|
|
3415
|
+
return res.json();
|
|
3416
|
+
},
|
|
3417
|
+
[fetchWithAuth]
|
|
3418
|
+
);
|
|
3419
|
+
(0, import_react14.useEffect)(() => {
|
|
3420
|
+
if (autoFetch) void fetchKnowledgeBases();
|
|
3421
|
+
}, [autoFetch, fetchKnowledgeBases]);
|
|
3422
|
+
return {
|
|
3423
|
+
knowledgeBases,
|
|
3424
|
+
pagination,
|
|
2536
3425
|
isLoading,
|
|
3426
|
+
isUploading,
|
|
2537
3427
|
error,
|
|
2538
|
-
refetch:
|
|
3428
|
+
refetch: fetchKnowledgeBases,
|
|
3429
|
+
getKnowledgeBase,
|
|
3430
|
+
createKnowledgeBase,
|
|
3431
|
+
updateKnowledgeBase,
|
|
3432
|
+
deleteKnowledgeBase,
|
|
3433
|
+
bulkDeleteKnowledgeBases,
|
|
3434
|
+
getKnowledgeBaseUsage,
|
|
3435
|
+
uploadDocuments,
|
|
3436
|
+
listDocuments,
|
|
3437
|
+
deleteDocument,
|
|
3438
|
+
search: searchKnowledgeBase
|
|
2539
3439
|
};
|
|
2540
3440
|
}
|
|
2541
3441
|
|
|
2542
|
-
// src/hooks/
|
|
2543
|
-
var
|
|
2544
|
-
function
|
|
3442
|
+
// src/hooks/useMcpAdmin.ts
|
|
3443
|
+
var import_react15 = require("react");
|
|
3444
|
+
function useMcpAdmin(options = {}) {
|
|
3445
|
+
const { autoFetch = true, page, limit, search } = options;
|
|
2545
3446
|
const { fetchWithAuth } = usePersonaContext();
|
|
2546
|
-
const [
|
|
2547
|
-
const [
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
setIsConnected(true);
|
|
2557
|
-
return data;
|
|
2558
|
-
}
|
|
2559
|
-
setIsConnected(false);
|
|
2560
|
-
return null;
|
|
2561
|
-
} catch {
|
|
2562
|
-
setIsConnected(false);
|
|
2563
|
-
return null;
|
|
2564
|
-
} finally {
|
|
2565
|
-
setIsLoading(false);
|
|
2566
|
-
}
|
|
2567
|
-
}, [fetchWithAuth]);
|
|
2568
|
-
(0, import_react9.useEffect)(() => {
|
|
2569
|
-
if (autoCheck) {
|
|
2570
|
-
void checkHealth();
|
|
2571
|
-
}
|
|
2572
|
-
}, [autoCheck, checkHealth]);
|
|
2573
|
-
return {
|
|
2574
|
-
isConnected,
|
|
2575
|
-
health,
|
|
2576
|
-
isLoading,
|
|
2577
|
-
checkHealth
|
|
2578
|
-
};
|
|
2579
|
-
}
|
|
2580
|
-
|
|
2581
|
-
// src/hooks/useMcpConnections.ts
|
|
2582
|
-
var import_react10 = require("react");
|
|
2583
|
-
function useMcpConnections(options = {}) {
|
|
2584
|
-
const { defaultAgentId, fetchWithAuth } = usePersonaContext();
|
|
2585
|
-
const agentId = options.agentId ?? defaultAgentId;
|
|
2586
|
-
const autoFetch = options.autoFetch ?? true;
|
|
2587
|
-
const [connections, setConnections] = (0, import_react10.useState)([]);
|
|
2588
|
-
const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
|
|
2589
|
-
const [error, setError] = (0, import_react10.useState)(null);
|
|
2590
|
-
const fetchConnections = (0, import_react10.useCallback)(async () => {
|
|
2591
|
-
if (!agentId) return [];
|
|
3447
|
+
const [mcps, setMcps] = (0, import_react15.useState)([]);
|
|
3448
|
+
const [pagination, setPagination] = (0, import_react15.useState)({
|
|
3449
|
+
total: 0,
|
|
3450
|
+
page: page ?? 1,
|
|
3451
|
+
limit: limit ?? 20,
|
|
3452
|
+
pages: 0
|
|
3453
|
+
});
|
|
3454
|
+
const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
|
|
3455
|
+
const [error, setError] = (0, import_react15.useState)(null);
|
|
3456
|
+
const fetchMcps = (0, import_react15.useCallback)(async () => {
|
|
2592
3457
|
setIsLoading(true);
|
|
2593
3458
|
setError(null);
|
|
2594
3459
|
try {
|
|
2595
|
-
const
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
);
|
|
2600
|
-
|
|
2601
|
-
|
|
3460
|
+
const query = new URLSearchParams();
|
|
3461
|
+
if (page) query.set("page", String(page));
|
|
3462
|
+
if (limit) query.set("limit", String(limit));
|
|
3463
|
+
if (search) query.set("search", search);
|
|
3464
|
+
query.set("scope", "mine");
|
|
3465
|
+
const res = await fetchWithAuth(`/mcps?${query.toString()}`);
|
|
3466
|
+
if (!res.ok) throw new Error(`Failed to list MCPs: ${res.statusText}`);
|
|
2602
3467
|
const data = await res.json();
|
|
2603
|
-
const items = Array.isArray(data) ? data : data?.items
|
|
2604
|
-
|
|
3468
|
+
const items = Array.isArray(data) ? data : data?.items ?? [];
|
|
3469
|
+
setMcps(items);
|
|
3470
|
+
setPagination(
|
|
3471
|
+
data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
|
|
3472
|
+
);
|
|
2605
3473
|
return items;
|
|
2606
3474
|
} catch (err) {
|
|
2607
3475
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
@@ -2610,83 +3478,172 @@ function useMcpConnections(options = {}) {
|
|
|
2610
3478
|
} finally {
|
|
2611
3479
|
setIsLoading(false);
|
|
2612
3480
|
}
|
|
2613
|
-
}, [
|
|
2614
|
-
(0,
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
)
|
|
2639
|
-
|
|
2640
|
-
|
|
3481
|
+
}, [fetchWithAuth, page, limit, search]);
|
|
3482
|
+
const getMcp = (0, import_react15.useCallback)(
|
|
3483
|
+
async (mcpId) => {
|
|
3484
|
+
const res = await fetchWithAuth(`/mcps/${mcpId}`);
|
|
3485
|
+
if (!res.ok) throw new Error(`Failed to fetch MCP: ${res.statusText}`);
|
|
3486
|
+
return res.json();
|
|
3487
|
+
},
|
|
3488
|
+
[fetchWithAuth]
|
|
3489
|
+
);
|
|
3490
|
+
const createMcp = (0, import_react15.useCallback)(
|
|
3491
|
+
async (input) => {
|
|
3492
|
+
setError(null);
|
|
3493
|
+
try {
|
|
3494
|
+
const res = await fetchWithAuth("/mcps", {
|
|
3495
|
+
method: "POST",
|
|
3496
|
+
headers: { "Content-Type": "application/json" },
|
|
3497
|
+
body: JSON.stringify(input)
|
|
3498
|
+
});
|
|
3499
|
+
if (!res.ok) {
|
|
3500
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3501
|
+
throw new Error(`Failed to create MCP (${res.status}): ${errText}`);
|
|
3502
|
+
}
|
|
3503
|
+
const created = await res.json();
|
|
3504
|
+
setMcps((prev) => [created, ...prev]);
|
|
3505
|
+
return created;
|
|
3506
|
+
} catch (err) {
|
|
3507
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3508
|
+
setError(errorObj);
|
|
3509
|
+
throw errorObj;
|
|
2641
3510
|
}
|
|
2642
|
-
return await res.json();
|
|
2643
3511
|
},
|
|
2644
|
-
[fetchWithAuth
|
|
3512
|
+
[fetchWithAuth]
|
|
2645
3513
|
);
|
|
2646
|
-
const
|
|
2647
|
-
async (
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
3514
|
+
const updateMcp = (0, import_react15.useCallback)(
|
|
3515
|
+
async (mcpId, input) => {
|
|
3516
|
+
setError(null);
|
|
3517
|
+
try {
|
|
3518
|
+
const res = await fetchWithAuth(`/mcps/${mcpId}`, {
|
|
3519
|
+
method: "PATCH",
|
|
3520
|
+
headers: { "Content-Type": "application/json" },
|
|
3521
|
+
body: JSON.stringify(input)
|
|
3522
|
+
});
|
|
3523
|
+
if (!res.ok) {
|
|
3524
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3525
|
+
throw new Error(`Failed to update MCP (${res.status}): ${errText}`);
|
|
3526
|
+
}
|
|
3527
|
+
const updated = await res.json();
|
|
3528
|
+
setMcps((prev) => prev.map((m) => m._id === mcpId ? updated : m));
|
|
3529
|
+
return updated;
|
|
3530
|
+
} catch (err) {
|
|
3531
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3532
|
+
setError(errorObj);
|
|
3533
|
+
throw errorObj;
|
|
2657
3534
|
}
|
|
2658
|
-
return await res.json();
|
|
2659
3535
|
},
|
|
2660
|
-
[fetchWithAuth
|
|
3536
|
+
[fetchWithAuth]
|
|
3537
|
+
);
|
|
3538
|
+
const deleteMcp = (0, import_react15.useCallback)(
|
|
3539
|
+
async (mcpId) => {
|
|
3540
|
+
setError(null);
|
|
3541
|
+
try {
|
|
3542
|
+
const res = await fetchWithAuth(`/mcps/${mcpId}`, { method: "DELETE" });
|
|
3543
|
+
if (!res.ok) {
|
|
3544
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3545
|
+
throw new Error(`Failed to delete MCP (${res.status}): ${errText}`);
|
|
3546
|
+
}
|
|
3547
|
+
setMcps((prev) => prev.filter((m) => m._id !== mcpId));
|
|
3548
|
+
} catch (err) {
|
|
3549
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3550
|
+
setError(errorObj);
|
|
3551
|
+
throw errorObj;
|
|
3552
|
+
}
|
|
3553
|
+
},
|
|
3554
|
+
[fetchWithAuth]
|
|
3555
|
+
);
|
|
3556
|
+
const bulkDeleteMcps = (0, import_react15.useCallback)(
|
|
3557
|
+
async (ids) => {
|
|
3558
|
+
setError(null);
|
|
3559
|
+
try {
|
|
3560
|
+
const res = await fetchWithAuth("/mcps/bulk-delete", {
|
|
3561
|
+
method: "POST",
|
|
3562
|
+
headers: { "Content-Type": "application/json" },
|
|
3563
|
+
body: JSON.stringify({ ids })
|
|
3564
|
+
});
|
|
3565
|
+
if (!res.ok) {
|
|
3566
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3567
|
+
throw new Error(`Failed to bulk-delete MCPs (${res.status}): ${errText}`);
|
|
3568
|
+
}
|
|
3569
|
+
const result = await res.json();
|
|
3570
|
+
const deletedSet = new Set(result.deleted);
|
|
3571
|
+
setMcps((prev) => prev.filter((m) => !deletedSet.has(m._id)));
|
|
3572
|
+
return result;
|
|
3573
|
+
} catch (err) {
|
|
3574
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3575
|
+
setError(errorObj);
|
|
3576
|
+
throw errorObj;
|
|
3577
|
+
}
|
|
3578
|
+
},
|
|
3579
|
+
[fetchWithAuth]
|
|
3580
|
+
);
|
|
3581
|
+
const testConnection = (0, import_react15.useCallback)(
|
|
3582
|
+
async (mcpId) => {
|
|
3583
|
+
setError(null);
|
|
3584
|
+
try {
|
|
3585
|
+
const res = await fetchWithAuth(`/mcps/${mcpId}/test`, { method: "POST" });
|
|
3586
|
+
if (!res.ok) {
|
|
3587
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3588
|
+
throw new Error(`Failed to test MCP connection (${res.status}): ${errText}`);
|
|
3589
|
+
}
|
|
3590
|
+
const result = await res.json();
|
|
3591
|
+
setMcps(
|
|
3592
|
+
(prev) => prev.map(
|
|
3593
|
+
(m) => m._id === mcpId ? { ...m, tools: result.tools, resources: result.resources, resourceTemplates: result.resourceTemplates } : m
|
|
3594
|
+
)
|
|
3595
|
+
);
|
|
3596
|
+
return result;
|
|
3597
|
+
} catch (err) {
|
|
3598
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3599
|
+
setError(errorObj);
|
|
3600
|
+
throw errorObj;
|
|
3601
|
+
}
|
|
3602
|
+
},
|
|
3603
|
+
[fetchWithAuth]
|
|
2661
3604
|
);
|
|
3605
|
+
(0, import_react15.useEffect)(() => {
|
|
3606
|
+
if (autoFetch) void fetchMcps();
|
|
3607
|
+
}, [autoFetch, fetchMcps]);
|
|
2662
3608
|
return {
|
|
2663
|
-
|
|
2664
|
-
|
|
3609
|
+
mcps,
|
|
3610
|
+
pagination,
|
|
3611
|
+
isLoading,
|
|
3612
|
+
error,
|
|
3613
|
+
refetch: fetchMcps,
|
|
3614
|
+
getMcp,
|
|
3615
|
+
createMcp,
|
|
3616
|
+
updateMcp,
|
|
3617
|
+
deleteMcp,
|
|
3618
|
+
bulkDeleteMcps,
|
|
3619
|
+
testConnection
|
|
2665
3620
|
};
|
|
2666
3621
|
}
|
|
2667
3622
|
|
|
2668
3623
|
// src/hooks/useWorkflows.ts
|
|
2669
|
-
var
|
|
3624
|
+
var import_react16 = require("react");
|
|
2670
3625
|
function useWorkflows(options) {
|
|
2671
3626
|
const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
|
|
2672
|
-
const { autoFetch = true, search,
|
|
3627
|
+
const { autoFetch = true, search, scope, visibility, isEnabled, page, limit } = opts;
|
|
2673
3628
|
const { fetchWithAuth } = usePersonaContext();
|
|
2674
|
-
const [workflows, setWorkflows] = (0,
|
|
2675
|
-
const [pagination, setPagination] = (0,
|
|
3629
|
+
const [workflows, setWorkflows] = (0, import_react16.useState)([]);
|
|
3630
|
+
const [pagination, setPagination] = (0, import_react16.useState)({
|
|
2676
3631
|
page: page ?? 1,
|
|
2677
3632
|
limit: limit ?? 20,
|
|
2678
3633
|
total: 0,
|
|
2679
3634
|
totalPages: 0
|
|
2680
3635
|
});
|
|
2681
|
-
const [isLoading, setIsLoading] = (0,
|
|
2682
|
-
const [error, setError] = (0,
|
|
2683
|
-
const fetchWorkflows = (0,
|
|
3636
|
+
const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
|
|
3637
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
3638
|
+
const fetchWorkflows = (0, import_react16.useCallback)(async () => {
|
|
2684
3639
|
setIsLoading(true);
|
|
2685
3640
|
setError(null);
|
|
2686
3641
|
try {
|
|
2687
3642
|
const params = new URLSearchParams();
|
|
2688
3643
|
if (search) params.set("search", search);
|
|
2689
|
-
if (
|
|
3644
|
+
if (scope) params.set("scope", scope);
|
|
3645
|
+
if (visibility) params.set("visibility", visibility);
|
|
3646
|
+
if (isEnabled !== void 0) params.set("isEnabled", String(isEnabled));
|
|
2690
3647
|
if (page) params.set("page", String(page));
|
|
2691
3648
|
if (limit) params.set("limit", String(limit));
|
|
2692
3649
|
const queryStr = params.toString() ? `?${params.toString()}` : "";
|
|
@@ -2695,14 +3652,17 @@ function useWorkflows(options) {
|
|
|
2695
3652
|
throw new Error(`Failed to list workflows: ${res.statusText}`);
|
|
2696
3653
|
}
|
|
2697
3654
|
const data = await res.json();
|
|
2698
|
-
const items = Array.isArray(data) ? data : data?.items
|
|
3655
|
+
const items = Array.isArray(data) ? data : data?.items ?? [];
|
|
2699
3656
|
setWorkflows(items);
|
|
2700
3657
|
if (data?.pagination) {
|
|
2701
3658
|
setPagination({
|
|
2702
3659
|
page: data.pagination.page ?? 1,
|
|
2703
3660
|
limit: data.pagination.limit ?? items.length,
|
|
2704
3661
|
total: data.pagination.total ?? items.length,
|
|
2705
|
-
|
|
3662
|
+
// Backend's paginationEnvelope() names this field `pages`, not
|
|
3663
|
+
// `totalPages` — this used to always fall through to the `?? 1`
|
|
3664
|
+
// default.
|
|
3665
|
+
totalPages: data.pagination.pages ?? 1
|
|
2706
3666
|
});
|
|
2707
3667
|
} else {
|
|
2708
3668
|
setPagination({
|
|
@@ -2720,8 +3680,8 @@ function useWorkflows(options) {
|
|
|
2720
3680
|
} finally {
|
|
2721
3681
|
setIsLoading(false);
|
|
2722
3682
|
}
|
|
2723
|
-
}, [fetchWithAuth, search,
|
|
2724
|
-
const createWorkflow = (0,
|
|
3683
|
+
}, [fetchWithAuth, search, scope, visibility, isEnabled, page, limit]);
|
|
3684
|
+
const createWorkflow = (0, import_react16.useCallback)(
|
|
2725
3685
|
async (input) => {
|
|
2726
3686
|
setError(null);
|
|
2727
3687
|
try {
|
|
@@ -2745,7 +3705,7 @@ function useWorkflows(options) {
|
|
|
2745
3705
|
},
|
|
2746
3706
|
[fetchWithAuth]
|
|
2747
3707
|
);
|
|
2748
|
-
(0,
|
|
3708
|
+
(0, import_react16.useEffect)(() => {
|
|
2749
3709
|
if (autoFetch) {
|
|
2750
3710
|
void fetchWorkflows();
|
|
2751
3711
|
}
|
|
@@ -2761,17 +3721,17 @@ function useWorkflows(options) {
|
|
|
2761
3721
|
}
|
|
2762
3722
|
|
|
2763
3723
|
// src/hooks/useWorkflow.ts
|
|
2764
|
-
var
|
|
3724
|
+
var import_react17 = require("react");
|
|
2765
3725
|
function useWorkflow(workflowId, options) {
|
|
2766
3726
|
const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
|
|
2767
3727
|
const { autoFetch = true } = opts;
|
|
2768
3728
|
const { fetchWithAuth } = usePersonaContext();
|
|
2769
|
-
const [workflow, setWorkflow] = (0,
|
|
2770
|
-
const [versions, setVersions] = (0,
|
|
2771
|
-
const [mermaid, setMermaid] = (0,
|
|
2772
|
-
const [isLoading, setIsLoading] = (0,
|
|
2773
|
-
const [error, setError] = (0,
|
|
2774
|
-
const fetchWorkflow = (0,
|
|
3729
|
+
const [workflow, setWorkflow] = (0, import_react17.useState)(null);
|
|
3730
|
+
const [versions, setVersions] = (0, import_react17.useState)([]);
|
|
3731
|
+
const [mermaid, setMermaid] = (0, import_react17.useState)(null);
|
|
3732
|
+
const [isLoading, setIsLoading] = (0, import_react17.useState)(false);
|
|
3733
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
3734
|
+
const fetchWorkflow = (0, import_react17.useCallback)(async () => {
|
|
2775
3735
|
if (!workflowId) return null;
|
|
2776
3736
|
setIsLoading(true);
|
|
2777
3737
|
setError(null);
|
|
@@ -2791,20 +3751,31 @@ function useWorkflow(workflowId, options) {
|
|
|
2791
3751
|
setIsLoading(false);
|
|
2792
3752
|
}
|
|
2793
3753
|
}, [fetchWithAuth, workflowId]);
|
|
2794
|
-
const fetchVersions = (0,
|
|
3754
|
+
const fetchVersions = (0, import_react17.useCallback)(async () => {
|
|
2795
3755
|
if (!workflowId) return [];
|
|
2796
3756
|
try {
|
|
2797
3757
|
const res = await fetchWithAuth(`/workflows/${workflowId}/versions`);
|
|
2798
3758
|
if (!res.ok) return [];
|
|
2799
3759
|
const data = await res.json();
|
|
2800
|
-
const items = Array.isArray(data) ? data : data?.items
|
|
3760
|
+
const items = Array.isArray(data) ? data : data?.items ?? [];
|
|
2801
3761
|
setVersions(items);
|
|
2802
3762
|
return items;
|
|
2803
3763
|
} catch {
|
|
2804
3764
|
return [];
|
|
2805
3765
|
}
|
|
2806
3766
|
}, [fetchWithAuth, workflowId]);
|
|
2807
|
-
const
|
|
3767
|
+
const getVersion = (0, import_react17.useCallback)(
|
|
3768
|
+
async (version) => {
|
|
3769
|
+
if (!workflowId) throw new Error("Workflow ID is required");
|
|
3770
|
+
const res = await fetchWithAuth(`/workflows/${workflowId}/versions/${version}`);
|
|
3771
|
+
if (!res.ok) {
|
|
3772
|
+
throw new Error(`Failed to fetch workflow version (${res.status}): ${res.statusText}`);
|
|
3773
|
+
}
|
|
3774
|
+
return await res.json();
|
|
3775
|
+
},
|
|
3776
|
+
[fetchWithAuth, workflowId]
|
|
3777
|
+
);
|
|
3778
|
+
const fetchMermaid = (0, import_react17.useCallback)(async () => {
|
|
2808
3779
|
if (!workflowId) return "";
|
|
2809
3780
|
try {
|
|
2810
3781
|
const res = await fetchWithAuth(`/workflows/${workflowId}/mermaid`);
|
|
@@ -2817,18 +3788,18 @@ function useWorkflow(workflowId, options) {
|
|
|
2817
3788
|
return "";
|
|
2818
3789
|
}
|
|
2819
3790
|
}, [fetchWithAuth, workflowId]);
|
|
2820
|
-
const
|
|
2821
|
-
async (
|
|
3791
|
+
const updateWorkflow = (0, import_react17.useCallback)(
|
|
3792
|
+
async (input) => {
|
|
2822
3793
|
if (!workflowId) throw new Error("Workflow ID is required");
|
|
2823
3794
|
setError(null);
|
|
2824
|
-
const res = await fetchWithAuth(`/workflows/${workflowId}
|
|
2825
|
-
method: "
|
|
3795
|
+
const res = await fetchWithAuth(`/workflows/${workflowId}`, {
|
|
3796
|
+
method: "PATCH",
|
|
2826
3797
|
headers: { "Content-Type": "application/json" },
|
|
2827
|
-
body: JSON.stringify(
|
|
3798
|
+
body: JSON.stringify(input)
|
|
2828
3799
|
});
|
|
2829
3800
|
if (!res.ok) {
|
|
2830
3801
|
const errText = await res.text().catch(() => res.statusText);
|
|
2831
|
-
throw new Error(`Failed to
|
|
3802
|
+
throw new Error(`Failed to update workflow (${res.status}): ${errText}`);
|
|
2832
3803
|
}
|
|
2833
3804
|
const updated = await res.json();
|
|
2834
3805
|
setWorkflow(updated);
|
|
@@ -2836,27 +3807,41 @@ function useWorkflow(workflowId, options) {
|
|
|
2836
3807
|
},
|
|
2837
3808
|
[fetchWithAuth, workflowId]
|
|
2838
3809
|
);
|
|
2839
|
-
const
|
|
2840
|
-
async (
|
|
3810
|
+
const saveDraft = (0, import_react17.useCallback)(
|
|
3811
|
+
async (draft) => {
|
|
2841
3812
|
if (!workflowId) throw new Error("Workflow ID is required");
|
|
2842
3813
|
setError(null);
|
|
2843
|
-
const res = await fetchWithAuth(`/workflows/${workflowId}/
|
|
2844
|
-
method: "
|
|
3814
|
+
const res = await fetchWithAuth(`/workflows/${workflowId}/draft`, {
|
|
3815
|
+
method: "PUT",
|
|
2845
3816
|
headers: { "Content-Type": "application/json" },
|
|
2846
|
-
body: JSON.stringify(
|
|
3817
|
+
body: JSON.stringify(draft)
|
|
2847
3818
|
});
|
|
2848
3819
|
if (!res.ok) {
|
|
2849
3820
|
const errText = await res.text().catch(() => res.statusText);
|
|
2850
|
-
throw new Error(`Failed to
|
|
3821
|
+
throw new Error(`Failed to save draft (${res.status}): ${errText}`);
|
|
2851
3822
|
}
|
|
2852
|
-
const
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
return versionResult;
|
|
3823
|
+
const updated = await res.json();
|
|
3824
|
+
setWorkflow(updated);
|
|
3825
|
+
return updated;
|
|
2856
3826
|
},
|
|
2857
|
-
[fetchWithAuth, workflowId
|
|
3827
|
+
[fetchWithAuth, workflowId]
|
|
2858
3828
|
);
|
|
2859
|
-
const
|
|
3829
|
+
const publish = (0, import_react17.useCallback)(async () => {
|
|
3830
|
+
if (!workflowId) throw new Error("Workflow ID is required");
|
|
3831
|
+
setError(null);
|
|
3832
|
+
const res = await fetchWithAuth(`/workflows/${workflowId}/publish`, {
|
|
3833
|
+
method: "POST"
|
|
3834
|
+
});
|
|
3835
|
+
if (!res.ok) {
|
|
3836
|
+
const errText = await res.text().catch(() => res.statusText);
|
|
3837
|
+
throw new Error(`Failed to publish workflow (${res.status}): ${errText}`);
|
|
3838
|
+
}
|
|
3839
|
+
const versionResult = await res.json();
|
|
3840
|
+
void fetchWorkflow();
|
|
3841
|
+
void fetchVersions();
|
|
3842
|
+
return versionResult;
|
|
3843
|
+
}, [fetchWithAuth, workflowId, fetchWorkflow, fetchVersions]);
|
|
3844
|
+
const deleteWorkflow = (0, import_react17.useCallback)(async () => {
|
|
2860
3845
|
if (!workflowId) throw new Error("Workflow ID is required");
|
|
2861
3846
|
setError(null);
|
|
2862
3847
|
const res = await fetchWithAuth(`/workflows/${workflowId}`, {
|
|
@@ -2867,7 +3852,7 @@ function useWorkflow(workflowId, options) {
|
|
|
2867
3852
|
}
|
|
2868
3853
|
setWorkflow(null);
|
|
2869
3854
|
}, [fetchWithAuth, workflowId]);
|
|
2870
|
-
(0,
|
|
3855
|
+
(0, import_react17.useEffect)(() => {
|
|
2871
3856
|
if (autoFetch && workflowId) {
|
|
2872
3857
|
void fetchWorkflow();
|
|
2873
3858
|
}
|
|
@@ -2880,7 +3865,9 @@ function useWorkflow(workflowId, options) {
|
|
|
2880
3865
|
error,
|
|
2881
3866
|
refetch: fetchWorkflow,
|
|
2882
3867
|
fetchVersions,
|
|
3868
|
+
getVersion,
|
|
2883
3869
|
fetchMermaid,
|
|
3870
|
+
updateWorkflow,
|
|
2884
3871
|
saveDraft,
|
|
2885
3872
|
publish,
|
|
2886
3873
|
deleteWorkflow
|
|
@@ -2888,25 +3875,25 @@ function useWorkflow(workflowId, options) {
|
|
|
2888
3875
|
}
|
|
2889
3876
|
|
|
2890
3877
|
// src/hooks/useWorkflowStream.ts
|
|
2891
|
-
var
|
|
3878
|
+
var import_react18 = require("react");
|
|
2892
3879
|
function useWorkflowStream(workflowId, options) {
|
|
2893
3880
|
const { baseUrl, getAuthToken, fetchWithAuth, logger } = usePersonaContext();
|
|
2894
|
-
const [status, setStatus] = (0,
|
|
2895
|
-
const [runId, setRunId] = (0,
|
|
2896
|
-
const [activeNodeId, setActiveNodeId] = (0,
|
|
2897
|
-
const [nodeRuns, setNodeRuns] = (0,
|
|
3881
|
+
const [status, setStatus] = (0, import_react18.useState)("idle");
|
|
3882
|
+
const [runId, setRunId] = (0, import_react18.useState)(null);
|
|
3883
|
+
const [activeNodeId, setActiveNodeId] = (0, import_react18.useState)(null);
|
|
3884
|
+
const [nodeRuns, setNodeRuns] = (0, import_react18.useState)(
|
|
2898
3885
|
{}
|
|
2899
3886
|
);
|
|
2900
|
-
const [text, setText] = (0,
|
|
2901
|
-
const [output, setOutput] = (0,
|
|
2902
|
-
const [error, setError] = (0,
|
|
2903
|
-
const [events, setEvents] = (0,
|
|
2904
|
-
const abortControllerRef = (0,
|
|
2905
|
-
const currentRunIdRef = (0,
|
|
3887
|
+
const [text, setText] = (0, import_react18.useState)("");
|
|
3888
|
+
const [output, setOutput] = (0, import_react18.useState)(null);
|
|
3889
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
3890
|
+
const [events, setEvents] = (0, import_react18.useState)([]);
|
|
3891
|
+
const abortControllerRef = (0, import_react18.useRef)(null);
|
|
3892
|
+
const currentRunIdRef = (0, import_react18.useRef)(null);
|
|
2906
3893
|
currentRunIdRef.current = runId;
|
|
2907
|
-
const optionsRef = (0,
|
|
3894
|
+
const optionsRef = (0, import_react18.useRef)(options);
|
|
2908
3895
|
optionsRef.current = options;
|
|
2909
|
-
const cancel = (0,
|
|
3896
|
+
const cancel = (0, import_react18.useCallback)(async () => {
|
|
2910
3897
|
if (abortControllerRef.current) {
|
|
2911
3898
|
abortControllerRef.current.abort();
|
|
2912
3899
|
abortControllerRef.current = null;
|
|
@@ -2927,7 +3914,7 @@ function useWorkflowStream(workflowId, options) {
|
|
|
2927
3914
|
setStatus("cancelled");
|
|
2928
3915
|
setActiveNodeId(null);
|
|
2929
3916
|
}, [fetchWithAuth, logger]);
|
|
2930
|
-
const reset = (0,
|
|
3917
|
+
const reset = (0, import_react18.useCallback)(() => {
|
|
2931
3918
|
if (abortControllerRef.current) {
|
|
2932
3919
|
abortControllerRef.current.abort();
|
|
2933
3920
|
abortControllerRef.current = null;
|
|
@@ -2941,7 +3928,7 @@ function useWorkflowStream(workflowId, options) {
|
|
|
2941
3928
|
setError(null);
|
|
2942
3929
|
setEvents([]);
|
|
2943
3930
|
}, []);
|
|
2944
|
-
const processStream = (0,
|
|
3931
|
+
const processStream = (0, import_react18.useCallback)(
|
|
2945
3932
|
async (url, method, body, targetRunId) => {
|
|
2946
3933
|
if (abortControllerRef.current) {
|
|
2947
3934
|
abortControllerRef.current.abort();
|
|
@@ -3106,7 +4093,7 @@ function useWorkflowStream(workflowId, options) {
|
|
|
3106
4093
|
},
|
|
3107
4094
|
[getAuthToken]
|
|
3108
4095
|
);
|
|
3109
|
-
const start = (0,
|
|
4096
|
+
const start = (0, import_react18.useCallback)(
|
|
3110
4097
|
async (input, opts) => {
|
|
3111
4098
|
const targetWfId = opts?.workflowId || workflowId;
|
|
3112
4099
|
if (!targetWfId) {
|
|
@@ -3127,7 +4114,7 @@ function useWorkflowStream(workflowId, options) {
|
|
|
3127
4114
|
},
|
|
3128
4115
|
[workflowId, baseUrl, processStream]
|
|
3129
4116
|
);
|
|
3130
|
-
const resume = (0,
|
|
4117
|
+
const resume = (0, import_react18.useCallback)(
|
|
3131
4118
|
async (targetRunId, sinceSeq) => {
|
|
3132
4119
|
if (!targetRunId) {
|
|
3133
4120
|
throw new Error("Run ID is required to resume stream");
|
|
@@ -3140,7 +4127,7 @@ function useWorkflowStream(workflowId, options) {
|
|
|
3140
4127
|
},
|
|
3141
4128
|
[baseUrl, processStream]
|
|
3142
4129
|
);
|
|
3143
|
-
(0,
|
|
4130
|
+
(0, import_react18.useEffect)(() => {
|
|
3144
4131
|
return () => {
|
|
3145
4132
|
if (abortControllerRef.current) {
|
|
3146
4133
|
abortControllerRef.current.abort();
|
|
@@ -3165,21 +4152,21 @@ function useWorkflowStream(workflowId, options) {
|
|
|
3165
4152
|
}
|
|
3166
4153
|
|
|
3167
4154
|
// src/hooks/useWorkflowRuns.ts
|
|
3168
|
-
var
|
|
4155
|
+
var import_react19 = require("react");
|
|
3169
4156
|
function useWorkflowRuns(workflowId, options) {
|
|
3170
4157
|
const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
|
|
3171
4158
|
const { autoFetch = true, page = 1, limit = 20 } = opts;
|
|
3172
4159
|
const { fetchWithAuth } = usePersonaContext();
|
|
3173
|
-
const [runs, setRuns] = (0,
|
|
3174
|
-
const [pagination, setPagination] = (0,
|
|
4160
|
+
const [runs, setRuns] = (0, import_react19.useState)([]);
|
|
4161
|
+
const [pagination, setPagination] = (0, import_react19.useState)({
|
|
3175
4162
|
page,
|
|
3176
4163
|
limit,
|
|
3177
4164
|
total: 0,
|
|
3178
4165
|
totalPages: 0
|
|
3179
4166
|
});
|
|
3180
|
-
const [isLoading, setIsLoading] = (0,
|
|
3181
|
-
const [error, setError] = (0,
|
|
3182
|
-
const fetchRuns = (0,
|
|
4167
|
+
const [isLoading, setIsLoading] = (0, import_react19.useState)(false);
|
|
4168
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
4169
|
+
const fetchRuns = (0, import_react19.useCallback)(async () => {
|
|
3183
4170
|
if (!workflowId) return [];
|
|
3184
4171
|
setIsLoading(true);
|
|
3185
4172
|
setError(null);
|
|
@@ -3190,14 +4177,16 @@ function useWorkflowRuns(workflowId, options) {
|
|
|
3190
4177
|
throw new Error(`Failed to list workflow runs: ${res.statusText}`);
|
|
3191
4178
|
}
|
|
3192
4179
|
const data = await res.json();
|
|
3193
|
-
const items = Array.isArray(data) ? data : data?.items
|
|
4180
|
+
const items = Array.isArray(data) ? data : data?.items ?? [];
|
|
3194
4181
|
setRuns(items);
|
|
3195
4182
|
if (data?.pagination) {
|
|
3196
4183
|
setPagination({
|
|
3197
4184
|
page: data.pagination.page ?? page,
|
|
3198
4185
|
limit: data.pagination.limit ?? limit,
|
|
3199
4186
|
total: data.pagination.total ?? items.length,
|
|
3200
|
-
|
|
4187
|
+
// Backend's paginationEnvelope() names this field `pages`, not
|
|
4188
|
+
// `totalPages`.
|
|
4189
|
+
totalPages: data.pagination.pages ?? 1
|
|
3201
4190
|
});
|
|
3202
4191
|
}
|
|
3203
4192
|
return items;
|
|
@@ -3209,7 +4198,7 @@ function useWorkflowRuns(workflowId, options) {
|
|
|
3209
4198
|
setIsLoading(false);
|
|
3210
4199
|
}
|
|
3211
4200
|
}, [fetchWithAuth, workflowId, page, limit]);
|
|
3212
|
-
const getRun = (0,
|
|
4201
|
+
const getRun = (0, import_react19.useCallback)(
|
|
3213
4202
|
async (runId) => {
|
|
3214
4203
|
if (!runId) throw new Error("Run ID is required");
|
|
3215
4204
|
const res = await fetchWithAuth(`/workflows/runs/${runId}`);
|
|
@@ -3220,7 +4209,7 @@ function useWorkflowRuns(workflowId, options) {
|
|
|
3220
4209
|
},
|
|
3221
4210
|
[fetchWithAuth]
|
|
3222
4211
|
);
|
|
3223
|
-
const cancelRun = (0,
|
|
4212
|
+
const cancelRun = (0, import_react19.useCallback)(
|
|
3224
4213
|
async (runId) => {
|
|
3225
4214
|
if (!runId) throw new Error("Run ID is required");
|
|
3226
4215
|
const res = await fetchWithAuth(`/workflows/runs/${runId}/cancel`, {
|
|
@@ -3235,7 +4224,7 @@ function useWorkflowRuns(workflowId, options) {
|
|
|
3235
4224
|
},
|
|
3236
4225
|
[fetchWithAuth]
|
|
3237
4226
|
);
|
|
3238
|
-
(0,
|
|
4227
|
+
(0, import_react19.useEffect)(() => {
|
|
3239
4228
|
if (autoFetch && workflowId) {
|
|
3240
4229
|
void fetchRuns();
|
|
3241
4230
|
}
|
|
@@ -3271,10 +4260,14 @@ var VERSION = "0.10.0";
|
|
|
3271
4260
|
useChat,
|
|
3272
4261
|
useConnection,
|
|
3273
4262
|
useFiles,
|
|
4263
|
+
useKnowledgeBases,
|
|
3274
4264
|
useMcp,
|
|
4265
|
+
useMcpAdmin,
|
|
3275
4266
|
useMcpConnections,
|
|
3276
4267
|
useMemory,
|
|
3277
4268
|
usePersonaContext,
|
|
4269
|
+
useRcpSources,
|
|
4270
|
+
useSkills,
|
|
3278
4271
|
useThreads,
|
|
3279
4272
|
useVoice,
|
|
3280
4273
|
useWorkflow,
|