agent-webui 2.7.1__tar.gz → 2.8.0__tar.gz
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.
- {agent_webui-2.7.1 → agent_webui-2.8.0}/PKG-INFO +9 -4
- {agent_webui-2.7.1 → agent_webui-2.8.0}/README.md +4 -2
- agent_webui-2.8.0/agent/agent_webui/__tests__/test_run_identity.py +218 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_security_boundaries.py +1 -1
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_served_operations.py +2 -2
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/api_extensions.py +5 -9
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/router.py +2 -3
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/contact_delivery.py +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/AdminView-CLxZUrrN.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/AgentLibraryView-CN9epMHd.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/AgentLibraryView-CZyRIfU4.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/ArboraReadinessView-BTsg6Fpb.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/AtlasView-BtiImHa3.js +5 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/Availability-Den2CaKK.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/Availability-BrYyobNN.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/BrokerView-BNol9w6Q.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/CatalogueView-B4K-jYbP.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/CatalogueView-CB5KV7m6.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/ChartPage-C6n1i1q1.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/CodeGraphView-CUlMGeog.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/CodeGraphView-0XqAlYvs.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ConfigurationView-QQbmt8FI.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/ConfigurationView-Ct3GcuZX.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ConsoleConfirmView-DGgSpeYr.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/ConsoleConfirmView-I58gtaRX.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ContactPage-DVqe4ojO.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/ContactPage-Df5Nf_M6.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/CypherReplView-B90s64iv.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/DashboardView-Bq821GJ3.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/DashboardsView-Cawhi2Ib.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/DataAnalystView-D2rDgmTE.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/DataAnalystView-B5w5WNFe.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/EcosystemView-Bkg8UWAG.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/ExploreQueryWorkspace-LtdPd2d7.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ExtractionView-SIs5t7-2.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/ExtractionView-4djMtTbg.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/FilesView-ZDVKqWlc.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/FleetView-CqZBn2Gb.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/FleetView-CEVui43g.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/GoalsView-qftV4zVF.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/GoalsView-DR5C4EET.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/Graph3DLodView-BiX8STys.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/Graph3DView-DvrfNH4Y.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/Graph3DView-DUg2qkja.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/GraphCanvas-D5Tfn0o0.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/GraphView-CGxazgvr.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ImportExportModal-3aJofrNe.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/ImportExportModal-B47Vn5vL.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/IntegrationsView-D5NB1qHT.js +2 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/KnowledgeBaseView-DJzbVXf_.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/KnowledgeBaseView-NCg2M6dz.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/KnowledgeView-DPWInTRP.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/LLMTemplatesView-CiZKNyGY.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/LearnView-CyFpsc5N.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/LearnView-C41QyeM6.js +2 -2
- agent_webui-2.8.0/agent/agent_webui/dist/assets/LiveDashboardsView-DV3ftpBl.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/MagmaView-DeUYSUus.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/MagmaView-LyoA2b3c.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/MarketsCalendar-BJ4xSyWw.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/MarketsCalendar-m2jwkM8j.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/MarketsHome-CbspJWR4.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/MarketsHome-Dp_RXeiT.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/MarketsMenu-DHt2G1_0.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/MarketsMenu-hS7CIyA5.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/MarketsNews-DZwg_as1.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/MarketsNews-D_aOZixQ.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/MarketsPortfolio-DMM4Yl1Q.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/MarketsPortfolio-C2wiw20j.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/MarketsShell-C1x1kWh-.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/MarketsShell-Zc2AkZJr.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/McpAppsView-l-sCScNo.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/McpAppsView-DKdvG0_N.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/MemoryView-Chrf2JTU.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/NodeTypeBreakdown-Aede8Ovl.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/NodeTypeBreakdown-Bhew4z65.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/NotFoundPage-y3NN-QVf.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/NotFoundPage-CHybKkb0.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/Notices-D17hdIJE.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/Notices-3oonQvay.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/ObjectExplorerView-CNfy-XSe.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ObjectView-DG1Z_OYW.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/ObjectView-BG5s55p1.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/ObservabilityView-CUoyLm-2.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/OperateWorkspace-dpSRUomJ.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/OpsPanelView-BxpmxYT-.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/PrivacyPage-ChMvnVOD.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/PromptsView-FmBCUric.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/PublicPageLayout-1ji-4LZL.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/PublicPageLayout-BciWikRQ.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/SDDView-B0meX0p3.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/SDDView-DQZMtOwV.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/SchedulingView-DvwK95G0.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/SchedulingView-BSDgR7Lw.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/SchemaView-o5YEfujF.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/SchemaView-jq-D6LQZ.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/SessionsView-C_OXIDrS.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/SharePage-5sxMYGoz.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/SharePage-BYM0uX1S.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/SkillsView-DqpuikQo.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/SparqlView-XZqeQ_DV.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/SystemStatusView-CdXpGKS-.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/TableExplorerView-D3RFqPwg.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/TemporalGraphView-bgJHyEhh.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/TermsPage-CDnQDbgV.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/TermsPage-DZPwiIny.js +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ThankYouPage-BvFj5K9A.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/ThankYouPage-Cjq0FQ5v.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/TrendBadge-DQ4zgWWk.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/UsageView-CEyf-VpZ.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/UserManagementView-Ct4n0QDr.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/VertexView-E0vs0cRH.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/VertexView-DnYc5KSf.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/VizDemoView-PGvBvN2G.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/WorkWorkspace-Drgs9R6s.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/WorkflowEditorView-BazGYxiT.js +7 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/WorkspaceIDEView-BY6TA4da.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/arrow-up-DpBEFU1W.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/circle-dot-In4UilqT.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/identity-Cp486guQ.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/index-B3Hz4lzB.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/index-C2uiGu8Z.js +17 -17
- agent_webui-2.8.0/agent/agent_webui/dist/assets/index-UXCYeqCs.css +2 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/loaded-workspace-commands-CXfB1eT-.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/model-C4AzLQrj.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/model-Oxh121Y0.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/queries-Cx8lZa--.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/status-message-ovrDYMYX.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/status-message-CFnPiTvw.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/tabs-aIrzMOIb.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/undo-2-D4EYZLW8.js +1 -0
- agent_webui-2.8.0/agent/agent_webui/dist/assets/uql-H85wtqTc.js +1 -0
- agent_webui-2.7.1/agent/agent_webui/dist/assets/useMutation-Bjdc9UtI.js → agent_webui-2.8.0/agent/agent_webui/dist/assets/useMutation-BXe25F6O.js +1 -1
- agent_webui-2.8.0/agent/agent_webui/dist/assets/useQuery-BCV_z3lS.js +1 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/index.html +3 -3
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/spa-routes.json +4 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/oidc_session.py +1 -1
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/orchestrator_model.py +93 -29
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/server.py +1 -1
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui.egg-info/PKG-INFO +9 -4
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui.egg-info/SOURCES.txt +88 -78
- {agent_webui-2.7.1 → agent_webui-2.8.0}/pyproject.toml +5 -5
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_release_publication.py +1 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/AdminView-BdhlXNuH.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ArboraReadinessView-BkGEkah-.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/AtlasView-De6w_9WH.js +0 -5
- agent_webui-2.7.1/agent/agent_webui/dist/assets/BrokerView-DHE8-a7g.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ChartPage-CajmeMxT.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/CypherReplView-BFVNSbHf.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/DashboardView-JHHk8nfw.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/EcosystemView-BxdVgmYl.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/FilesView-B4kygc4_.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/Graph3DLodView-CNt0ZZ1f.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/GraphCanvas-CvF9sWHU.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/GraphView-DtSYTFIU.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/IntegrationsView-DanxQx4E.js +0 -2
- agent_webui-2.7.1/agent/agent_webui/dist/assets/KnowledgeView-0lzdQNlj.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/LLMTemplatesView-DpYhR3Rz.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/LiveDashboardsView-ESAfLAEw.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/MemoryView-Dghm1rMT.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ObjectExplorerView-DdPfSjOg.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/ObservabilityView-Ce5o66gv.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/OpsPanelView-CDke42HU.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/PrivacyPage-DypYppFK.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/PromptsView-C0soAhv5.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/SessionsView-DSoZk_Lz.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/SkillsView-CL-inq1F.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/SparqlView-Duik6wYZ.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/SystemStatusView-D7PxxotJ.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/TableExplorerView-Jt0S_NKW.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/TemporalGraphView-DF-se9oo.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/TrendBadge-DFvlzJv5.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/UsageView-exhd6ewz.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/UserManagementView-DFsbzkZb.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/VizDemoView-Bt3r5KAC.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/WorkflowEditorView-6bMv23QZ.js +0 -7
- agent_webui-2.7.1/agent/agent_webui/dist/assets/WorkspaceIDEView-BXzXC4zp.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/identity-C3qnrvHo.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/index-BRlMMQsQ.css +0 -2
- agent_webui-2.7.1/agent/agent_webui/dist/assets/queries-PjkfUoGJ.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/tabs-BxSTPadT.js +0 -1
- agent_webui-2.7.1/agent/agent_webui/dist/assets/useQuery-BGefm_dX.js +0 -1
- {agent_webui-2.7.1 → agent_webui-2.8.0}/LICENSE +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__init__.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/conftest.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_api_extensions.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_bound_sweep_regressions.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_browser_control.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_bug_012_github_gitlab_contract.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_chat_resource_routes.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_contact_delivery.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_files_endpoints.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_host.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_markets_app.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_observability.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_oidc_session.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_parity_contract.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_pydantic_ai_compat.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_rbac.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_spa_http_status.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_workspace_helpers_chokepoint.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/__init__.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/__init__.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/catalog.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/chart.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/gateway.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/scanner.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/series.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/session.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/snapshots.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/apps/markets/timeframes.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/browser_control.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/browser_control_canonical.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/apple-touch-icon.png +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/ChartPanel-Cxpkw3a6.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/InterVariable-DiVDrmQJ.woff2 +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/LegalPageContent-BmhwYoKV.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/SessionExpiredNotice-CMttDxWl.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/WorkflowEditorView-DLioOiRN.css +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/activity-DupAOJCR.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/api-jtHn_WxH.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/api-validation-CCoR_LRu.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/app-window-KMAPJoaW.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/badge-nQZ87mVE.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/braces-BNz2iAeD.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/bundle-mjs-DIyOrgL5.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/check-CPVKKX8l.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/chevron-down-DYWnPQti.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/chevron-left-BaGXvfgm.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/chevron-right-gs8WU8XT.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/chevron-up-C-rjGU5C.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/chunk-D32TOXHM-KueescCg.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/circle-alert-ByZ-1ERr.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/contact-C94LhKRg.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/createLucideIcon-DTQSidPf.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-2txhAIHO.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-BHmo3Yb6.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-BKkt828_.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-BLRfKgTy.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-BjAObXUn.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-Bq6o2UDR.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-CWmwEm73.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-DMVqwVuR.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-DcreYulP.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/dist-mp1aFJDC.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/es2015-CgZynitj.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/external-link-Dyd5OsGm.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/eye-D0gCj30e.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/file-text-DqorJKDA.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/folder-open-BrzeUmMg.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/format-DHsGNrOH.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/funnel-Y4IuN8Q7.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/graphology-layout-forceatlas2-CF_uOjtN.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/hard-drive-9fR5RFS9.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/highlighted-body-KQOG7T2V-qSdnQsR5.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/hourglass-1ui486hR.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/layout-grid-B4IFpzLD.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/layout.worker-CnC9u5pP.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/link-2-a9RZxW2S.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/mermaid-MCJ5UELQ-F6vEfdbO.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/play-D3mjq--Q.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/plus-s20KYBeu.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/preload-helper-CRzLMJPS.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/react-dom-DAxA-E-a.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/refresh-cw-BVhl5aJX.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/save-CuEdPPgC.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/scan-search-GrqJngl3.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/scroll-area-srEWz9Q3.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/server-CE-xbAAj.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/sliders-vertical-Cr4E50uY.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/sparkles-Bae0tRI0.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/switch-B9Yml2pU.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/tag-D1RiwxuF.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/theme-colors-DKGWsgC0.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/transport-Din6U5N9.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/unavailable-notice-B7WdWNor.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/upload-DcybBZCN.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/utils-C0okervd.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/wifi-off-Dz91unNp.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/assets/x-BdA_yxUR.js +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/favicon-16x16.png +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/favicon-32x32.png +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/favicon-48x48.png +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/favicon.ico +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/favicon.png +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/favicon.svg +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/icon-192x192.png +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/icon-512x512.png +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/og-image-v1.png +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/og-image-v1.svg +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/robots.txt +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/site.webmanifest +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/dist/sitemap.xml +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/host.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/icon.png +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/observability.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/public_shell.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/rbac.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/skills/__init__.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/skills/agent-webui-development/SKILL.md +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/skills/kg-webui-admin/SKILL.md +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/skills/kg-webui-dashboards/SKILL.md +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/skills/kg-webui-extraction/SKILL.md +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/skills/kg-webui-graphviz/SKILL.md +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/skills/kg-webui-ontology-operator/SKILL.md +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/skills/kg-webui-swe/SKILL.md +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui.egg-info/dependency_links.txt +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui.egg-info/entry_points.txt +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui.egg-info/requires.txt +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui.egg-info/top_level.txt +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/setup.cfg +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_dashboard_entrypoint.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_eslint_hook_contract.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_gate_wrappers.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_graph_visualization.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_health_liveness_endpoint.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_identity_boundary.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_init.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_log_failure_error_code.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_package_author_privacy.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_privacy_boundaries.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_release_concurrency.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_release_gate_order.py +0 -0
- {agent_webui-2.7.1 → agent_webui-2.8.0}/tests/test_startup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-webui
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.8.0
|
|
4
4
|
Summary: Agent Web Interface for Pydantic AI Agents
|
|
5
5
|
Author-email: Repository Maintainers <maintainers@knuckles.team>
|
|
6
6
|
License: MIT
|
|
@@ -9,7 +9,10 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
9
9
|
Classifier: Environment :: Console
|
|
10
10
|
Classifier: Operating System :: POSIX :: Linux
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Requires-Python: >=3.12
|
|
13
16
|
Description-Content-Type: text/markdown
|
|
14
17
|
License-File: LICENSE
|
|
15
18
|
Requires-Dist: agent-utilities<4.0.0,>=3.0.0
|
|
@@ -97,7 +100,7 @@ credentials and gateway delegation on the server side.
|
|
|
97
100
|
|---|---|
|
|
98
101
|
| Browser presentation, local interaction state, accessible route composition, and the FastAPI boundary | Arbora owns public routing, identity, policy, and fleet supervision; Agent Utilities owns agent behavior; Epistemic Graph owns durable knowledge; connector services own external-system effects |
|
|
99
102
|
|
|
100
|
-
Current package Version: 2.
|
|
103
|
+
Current package Version: 2.8.0.
|
|
101
104
|
|
|
102
105
|
## Key capabilities
|
|
103
106
|
|
|
@@ -126,7 +129,9 @@ then use the shared platform map to move between components:
|
|
|
126
129
|
|
|
127
130
|
## Architecture
|
|
128
131
|
|
|
129
|
-

|
|
132
|
+
[](https://knuckles-team.github.io/.github/architecture/#webui)
|
|
133
|
+
|
|
134
|
+
[Explore the live architecture](https://knuckles-team.github.io/.github/architecture/#webui)
|
|
130
135
|
|
|
131
136
|
People also enter through Agent Terminal UI and Geniusbot or Arbora-hosted
|
|
132
137
|
messaging; Agent Terminal UI exposes REST operations, with no ACP conversational
|
|
@@ -54,7 +54,7 @@ credentials and gateway delegation on the server side.
|
|
|
54
54
|
|---|---|
|
|
55
55
|
| Browser presentation, local interaction state, accessible route composition, and the FastAPI boundary | Arbora owns public routing, identity, policy, and fleet supervision; Agent Utilities owns agent behavior; Epistemic Graph owns durable knowledge; connector services own external-system effects |
|
|
56
56
|
|
|
57
|
-
Current package Version: 2.
|
|
57
|
+
Current package Version: 2.8.0.
|
|
58
58
|
|
|
59
59
|
## Key capabilities
|
|
60
60
|
|
|
@@ -83,7 +83,9 @@ then use the shared platform map to move between components:
|
|
|
83
83
|
|
|
84
84
|
## Architecture
|
|
85
85
|
|
|
86
|
-

|
|
86
|
+
[](https://knuckles-team.github.io/.github/architecture/#webui)
|
|
87
|
+
|
|
88
|
+
[Explore the live architecture](https://knuckles-team.github.io/.github/architecture/#webui)
|
|
87
89
|
|
|
88
90
|
People also enter through Agent Terminal UI and Geniusbot or Arbora-hosted
|
|
89
91
|
messaging; Agent Terminal UI exposes REST operations, with no ACP conversational
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"""WEBUI-API-R011.2: conversation labels and admitted run identity stay distinct."""
|
|
2
|
+
|
|
3
|
+
# spec: WEBUI-API-R011.2.1
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
from agent_webui.orchestrator_model import (
|
|
9
|
+
_conversation_session_id,
|
|
10
|
+
_run_identity,
|
|
11
|
+
build_orchestrator_model,
|
|
12
|
+
)
|
|
13
|
+
from pydantic_ai import Agent
|
|
14
|
+
from pydantic_ai.messages import ModelRequest, UserPromptPart
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def request(text='hello', conversation_id=None):
|
|
18
|
+
return ModelRequest(
|
|
19
|
+
parts=[UserPromptPart(content=text)], conversation_id=conversation_id
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def task_result(task_id, context='owned-context'):
|
|
24
|
+
return {
|
|
25
|
+
'value': {
|
|
26
|
+
'id': task_id,
|
|
27
|
+
'contextId': context,
|
|
28
|
+
'metadata': {
|
|
29
|
+
'arbora': {
|
|
30
|
+
'runId': 'run-' + task_id,
|
|
31
|
+
'runTraceRef': 'opaque-ref-' + task_id,
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
'artifacts': [{'parts': [{'kind': 'text', 'text': 'reply-' + task_id}]}],
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_explicit_identity_is_stable_not_content_derived():
|
|
40
|
+
assert _conversation_session_id([request('one', 'c1')]) == 'webui:c1'
|
|
41
|
+
assert _conversation_session_id([request('two', 'c1')]) == 'webui:c1'
|
|
42
|
+
assert _conversation_session_id([request('one', 'c2')]) == 'webui:c2'
|
|
43
|
+
assert _conversation_session_id([request()]) != _conversation_session_id(
|
|
44
|
+
[request()]
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_conflicting_identity_refused():
|
|
49
|
+
with pytest.raises(ValueError, match='Conflicting'):
|
|
50
|
+
_conversation_session_id(
|
|
51
|
+
[request(conversation_id='a'), request(conversation_id='b')]
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_explicit_references_only_no_guessed_trace():
|
|
56
|
+
metadata = _run_identity(task_result('t1'), 'webui:c1')
|
|
57
|
+
assert metadata is not None
|
|
58
|
+
identity = metadata['arbora_run']
|
|
59
|
+
assert identity == {
|
|
60
|
+
'conversation_context': 'webui:c1',
|
|
61
|
+
'task_id': 't1',
|
|
62
|
+
'context_id': 'owned-context',
|
|
63
|
+
'run_id': 'run-t1',
|
|
64
|
+
'run_trace_ref': 'opaque-ref-t1',
|
|
65
|
+
}
|
|
66
|
+
assert _run_identity({'value': {'status': {}}}, 'webui:c1') is None
|
|
67
|
+
assert _run_identity({'result': task_result('nested')}, 'webui:c1') is None
|
|
68
|
+
assert _run_identity({'value': {'id': 't', 'contextId': 'c'}}, 'webui:c1') == {
|
|
69
|
+
'arbora_run': {
|
|
70
|
+
'conversation_context': 'webui:c1',
|
|
71
|
+
'task_id': 't',
|
|
72
|
+
'context_id': 'c',
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@pytest.mark.parametrize(
|
|
78
|
+
'field,value', [('id', 1), ('contextId', ''), ('contextId', ['c'])]
|
|
79
|
+
)
|
|
80
|
+
def test_invalid_returned_identity_refused(field, value):
|
|
81
|
+
result = task_result('t1')
|
|
82
|
+
result['value'][field] = value
|
|
83
|
+
assert _run_identity(result, 'webui:c1') is None
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async def test_stream_metadata_is_request_local_and_preserves_exact_refs():
|
|
87
|
+
calls = []
|
|
88
|
+
|
|
89
|
+
async def invoke(op, params, *, idempotency_key):
|
|
90
|
+
context = params['message']['contextId']
|
|
91
|
+
calls.append((context, idempotency_key))
|
|
92
|
+
await asyncio.sleep(0)
|
|
93
|
+
return task_result(context)
|
|
94
|
+
|
|
95
|
+
agent = Agent(build_orchestrator_model(invoke=invoke))
|
|
96
|
+
|
|
97
|
+
async def run(conversation):
|
|
98
|
+
async with agent.run_stream('hello', conversation_id=conversation) as result:
|
|
99
|
+
await result.get_output()
|
|
100
|
+
return result.response
|
|
101
|
+
|
|
102
|
+
one, two = await asyncio.gather(run('one'), run('two'))
|
|
103
|
+
assert one.metadata['arbora_run']['task_id'] == 'webui:one'
|
|
104
|
+
assert two.metadata['arbora_run']['task_id'] == 'webui:two'
|
|
105
|
+
assert one.metadata['arbora_run']['run_trace_ref'] == 'opaque-ref-webui:one'
|
|
106
|
+
from pydantic_ai.ui.vercel_ai import VercelAIAdapter
|
|
107
|
+
|
|
108
|
+
wire = VercelAIAdapter.dump_messages([one])[0]
|
|
109
|
+
assert wire.metadata['arbora_run'] == one.metadata['arbora_run']
|
|
110
|
+
# Repeated turns share conversation identity, not a fabricated task/run ID.
|
|
111
|
+
again = await run('one')
|
|
112
|
+
assert again.metadata['arbora_run']['conversation_context'] == 'webui:one'
|
|
113
|
+
assert calls[0][1] != calls[-1][1]
|
|
114
|
+
assert calls[-1][0] == 'webui:one'
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
async def test_failed_stream_does_not_reuse_previous_identity():
|
|
118
|
+
calls = 0
|
|
119
|
+
|
|
120
|
+
async def invoke(op, params, *, idempotency_key):
|
|
121
|
+
nonlocal calls
|
|
122
|
+
calls += 1
|
|
123
|
+
if calls == 2:
|
|
124
|
+
raise RuntimeError('unavailable')
|
|
125
|
+
return task_result('first' if calls == 1 else 'third')
|
|
126
|
+
|
|
127
|
+
agent = Agent(build_orchestrator_model(invoke=invoke))
|
|
128
|
+
first = await agent.run('first', conversation_id='one')
|
|
129
|
+
assert first.response.metadata['arbora_run']['task_id'] == 'first'
|
|
130
|
+
with pytest.raises(RuntimeError, match='unavailable'):
|
|
131
|
+
async with agent.run_stream('second', conversation_id='two') as result:
|
|
132
|
+
await result.get_output()
|
|
133
|
+
async with agent.run_stream('retry', conversation_id='two') as result:
|
|
134
|
+
await result.get_output()
|
|
135
|
+
assert result.response.metadata['arbora_run']['task_id'] == 'third'
|
|
136
|
+
assert (
|
|
137
|
+
result.response.metadata['arbora_run']['conversation_context']
|
|
138
|
+
== 'webui:two'
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@pytest.mark.parametrize('malformed', [False, True])
|
|
143
|
+
async def test_real_vercel_stream_propagates_served_identity_without_repeating_effects(
|
|
144
|
+
malformed,
|
|
145
|
+
):
|
|
146
|
+
import json
|
|
147
|
+
|
|
148
|
+
from pydantic_ai.ui.vercel_ai import VercelAIAdapter
|
|
149
|
+
from starlette.requests import Request
|
|
150
|
+
|
|
151
|
+
calls = []
|
|
152
|
+
|
|
153
|
+
async def invoke(op, params, *, idempotency_key):
|
|
154
|
+
calls.append(params)
|
|
155
|
+
result = task_result('wire-task')
|
|
156
|
+
if malformed:
|
|
157
|
+
result['value']['id'] = 42
|
|
158
|
+
return {'ok': True, 'result': result, 'meta': {'registry_digest': 'test'}}
|
|
159
|
+
|
|
160
|
+
payload = json.dumps(
|
|
161
|
+
{
|
|
162
|
+
'id': '/selected',
|
|
163
|
+
'trigger': 'submit-message',
|
|
164
|
+
'messages': [
|
|
165
|
+
{
|
|
166
|
+
'id': 'u1',
|
|
167
|
+
'role': 'user',
|
|
168
|
+
'parts': [{'type': 'text', 'text': 'hello'}],
|
|
169
|
+
}
|
|
170
|
+
],
|
|
171
|
+
}
|
|
172
|
+
).encode()
|
|
173
|
+
|
|
174
|
+
async def receive():
|
|
175
|
+
return {'type': 'http.request', 'body': payload, 'more_body': False}
|
|
176
|
+
|
|
177
|
+
request = Request(
|
|
178
|
+
{
|
|
179
|
+
'type': 'http',
|
|
180
|
+
'method': 'POST',
|
|
181
|
+
'path': '/api/chats/messages',
|
|
182
|
+
'headers': [(b'content-type', b'application/json')],
|
|
183
|
+
},
|
|
184
|
+
receive,
|
|
185
|
+
)
|
|
186
|
+
response = await VercelAIAdapter.dispatch_request(
|
|
187
|
+
request, agent=Agent(build_orchestrator_model(invoke=invoke)), sdk_version=7
|
|
188
|
+
)
|
|
189
|
+
assert hasattr(response, 'body_iterator'), response.body
|
|
190
|
+
chunks = [chunk async for chunk in response.body_iterator]
|
|
191
|
+
body = ''.join(
|
|
192
|
+
chunk.decode() if isinstance(chunk, bytes) else chunk for chunk in chunks
|
|
193
|
+
)
|
|
194
|
+
assert len(calls) == 1
|
|
195
|
+
assert calls[0]['message']['contextId'] == 'webui:/selected'
|
|
196
|
+
assert 'reply-wire-task' in body
|
|
197
|
+
events = [
|
|
198
|
+
json.loads(line[6:])
|
|
199
|
+
for line in body.splitlines()
|
|
200
|
+
if line.startswith('data: ') and line != 'data: [DONE]'
|
|
201
|
+
]
|
|
202
|
+
metadata = [
|
|
203
|
+
event['messageMetadata']
|
|
204
|
+
for event in events
|
|
205
|
+
if event['type'] == 'message-metadata'
|
|
206
|
+
]
|
|
207
|
+
assert len(metadata) == 1
|
|
208
|
+
if malformed:
|
|
209
|
+
assert 'arbora_run' not in metadata[0]
|
|
210
|
+
else:
|
|
211
|
+
assert metadata[0]['arbora_run']['task_id'] == 'wire-task'
|
|
212
|
+
assert metadata[0]['arbora_run']['run_trace_ref'] == 'opaque-ref-wire-task'
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def test_error_envelope_cannot_supply_identity():
|
|
216
|
+
assert (
|
|
217
|
+
_run_identity({'ok': False, 'result': task_result('fake')}, 'webui:c') is None
|
|
218
|
+
)
|
{agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_security_boundaries.py
RENAMED
|
@@ -270,7 +270,7 @@ def _run_html_document(body_chunks: list[bytes], policy: str | None = None) -> l
|
|
|
270
270
|
return messages
|
|
271
271
|
|
|
272
272
|
|
|
273
|
-
@pytest.mark.spec('
|
|
273
|
+
@pytest.mark.spec('WEBUI-DESIGN-R009')
|
|
274
274
|
def test_html_documents_carry_a_fresh_style_nonce() -> None:
|
|
275
275
|
chunks = [b'<meta property="csp-nonce" nonce="AGENT_WEBUI_', b'CSP_NONCE">']
|
|
276
276
|
first = _run_html_document(chunks)
|
{agent_webui-2.7.1 → agent_webui-2.8.0}/agent/agent_webui/__tests__/test_served_operations.py
RENAMED
|
@@ -185,7 +185,7 @@ def _client(app: Any, scope: str = _ADMIN) -> TestClient:
|
|
|
185
185
|
),
|
|
186
186
|
],
|
|
187
187
|
)
|
|
188
|
-
# spec:
|
|
188
|
+
# spec: WEBUI-API-R011.1
|
|
189
189
|
def test_read_routes_project_the_served_operation(
|
|
190
190
|
app, arbora, method, path, body, op_id, value, sent, expected
|
|
191
191
|
) -> None:
|
|
@@ -272,7 +272,7 @@ def test_a_arbora_refusal_keeps_its_status(app, arbora, code, status) -> None:
|
|
|
272
272
|
('/cron/calendar', 'schedule.tasks.read'),
|
|
273
273
|
],
|
|
274
274
|
)
|
|
275
|
-
# spec:
|
|
275
|
+
# spec: WEBUI-API-R011.1
|
|
276
276
|
def test_routes_without_a_served_operation_answer_not_available(
|
|
277
277
|
app, arbora, path, operation
|
|
278
278
|
) -> None:
|
|
@@ -18,7 +18,7 @@ import uuid
|
|
|
18
18
|
from collections.abc import Awaitable, Callable
|
|
19
19
|
from concurrent import futures as _futures
|
|
20
20
|
from dataclasses import dataclass, replace
|
|
21
|
-
from datetime import
|
|
21
|
+
from datetime import UTC, datetime
|
|
22
22
|
from ipaddress import ip_address
|
|
23
23
|
from pathlib import Path
|
|
24
24
|
from typing import Annotated, Any, Literal
|
|
@@ -1320,9 +1320,7 @@ def _list_files_dir_entry(dir_path: Path, base_path: Path) -> dict[str, Any] | N
|
|
|
1320
1320
|
return {
|
|
1321
1321
|
'name': str(dir_path.relative_to(base_path)),
|
|
1322
1322
|
'size': 0,
|
|
1323
|
-
'modified_iso': datetime.fromtimestamp(
|
|
1324
|
-
st.st_mtime, tz=timezone.utc
|
|
1325
|
-
).isoformat(),
|
|
1323
|
+
'modified_iso': datetime.fromtimestamp(st.st_mtime, tz=UTC).isoformat(),
|
|
1326
1324
|
'is_dir': True,
|
|
1327
1325
|
}
|
|
1328
1326
|
|
|
@@ -1339,9 +1337,7 @@ def _list_files_file_entry(
|
|
|
1339
1337
|
return {
|
|
1340
1338
|
'name': str(file_path.relative_to(base_path)),
|
|
1341
1339
|
'size': st.st_size,
|
|
1342
|
-
'modified_iso': datetime.fromtimestamp(
|
|
1343
|
-
st.st_mtime, tz=timezone.utc
|
|
1344
|
-
).isoformat(),
|
|
1340
|
+
'modified_iso': datetime.fromtimestamp(st.st_mtime, tz=UTC).isoformat(),
|
|
1345
1341
|
'is_dir': False,
|
|
1346
1342
|
}
|
|
1347
1343
|
|
|
@@ -5586,7 +5582,7 @@ def _system_prompt_record(sys_prompt: str) -> dict[str, Any]:
|
|
|
5586
5582
|
'description': 'The default system prompt configured for this agent.',
|
|
5587
5583
|
'author': 'System',
|
|
5588
5584
|
'version': 1,
|
|
5589
|
-
'created_at': datetime.now(
|
|
5585
|
+
'created_at': datetime.now(UTC).isoformat(),
|
|
5590
5586
|
}
|
|
5591
5587
|
|
|
5592
5588
|
|
|
@@ -9921,7 +9917,7 @@ def _atlas_response_body(response: JSONResponse) -> Any | None:
|
|
|
9921
9917
|
|
|
9922
9918
|
|
|
9923
9919
|
def _atlas_observed_at() -> str:
|
|
9924
|
-
return datetime.now(
|
|
9920
|
+
return datetime.now(UTC).isoformat().replace('+00:00', 'Z')
|
|
9925
9921
|
|
|
9926
9922
|
|
|
9927
9923
|
def _atlas_valid_reference(value: Any) -> str | None:
|
|
@@ -11,7 +11,7 @@ from __future__ import annotations
|
|
|
11
11
|
import re
|
|
12
12
|
import time
|
|
13
13
|
from collections.abc import Awaitable, Callable
|
|
14
|
-
from typing import Annotated, Any, Literal
|
|
14
|
+
from typing import Annotated, Any, Literal
|
|
15
15
|
|
|
16
16
|
from fastapi import APIRouter, HTTPException, Query
|
|
17
17
|
from pydantic import AfterValidator, BaseModel, ConfigDict, Field
|
|
@@ -39,7 +39,6 @@ from .snapshots import (
|
|
|
39
39
|
)
|
|
40
40
|
from .timeframes import TIMEFRAMES, range_start
|
|
41
41
|
|
|
42
|
-
T = TypeVar('T')
|
|
43
42
|
Timeframe = Literal['1m', '15m', '1h', '4h', '12h', '1D', '1W', '1M']
|
|
44
43
|
RangeCode = Literal['1M', '3M', '1Y', '5Y', 'all']
|
|
45
44
|
AssetClass = Literal[
|
|
@@ -111,7 +110,7 @@ def _layers(raw: str) -> frozenset[str]:
|
|
|
111
110
|
return chosen
|
|
112
111
|
|
|
113
112
|
|
|
114
|
-
async def _guarded(call: Awaitable[T]) -> T:
|
|
113
|
+
async def _guarded[T](call: Awaitable[T]) -> T:
|
|
115
114
|
try:
|
|
116
115
|
return await call
|
|
117
116
|
except MarketsRefused as error:
|
|
@@ -263,7 +263,7 @@ async def _deliver_with_deadline(
|
|
|
263
263
|
timeout=_DELIVERY_TIMEOUT_SECONDS,
|
|
264
264
|
)
|
|
265
265
|
return ContactDeliveryResult.model_validate(raw_outcome, strict=True)
|
|
266
|
-
except (
|
|
266
|
+
except (TimeoutError, ValidationError) as error:
|
|
267
267
|
logger.error(
|
|
268
268
|
'Contact delivery outcome unknown: error_type=%s',
|
|
269
269
|
type(error).__name__,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,r as t,s as n}from"./bundle-mjs-DIyOrgL5.js";import{t as r}from"./createLucideIcon-DTQSidPf.js";import{t as i}from"./refresh-cw-BVhl5aJX.js";import{t as a}from"./server-CE-xbAAj.js";import{t as o}from"./badge-nQZ87mVE.js";import{E as s,S as c,a as l,c as u,f as d,w as f,x as p}from"./api-validation-CCoR_LRu.js";import{E as m,Jn as h,Nn as g,O as _,T as v,Un as y,Yt as b,Zn as x,ar as S,dn as C,dt as w,fr as ee,ft as te,k as T,mt as ne,or as re,rn as E,rr as ie,w as D,yn as ae,zn as O}from"./index-C2uiGu8Z.js";import{i as oe,n as k,r as se,t as ce}from"./tabs-aIrzMOIb.js";import{n as A}from"./identity-Cp486guQ.js";import{t as j}from"./unavailable-notice-B7WdWNor.js";import M from"./UserManagementView-Ct4n0QDr.js";var N={name:`archive`,size:24,node:[[`rect`,{width:`20`,height:`5`,x:`2`,y:`3`,rx:`1`,key:`1wp1u1`}],[`path`,{d:`M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8`,key:`1s80jp`}],[`path`,{d:`M10 12h4`,key:`a56b0p`}]]};N.node;var le=r(N),P={name:`database-backup`,size:24,node:[[`ellipse`,{cx:`12`,cy:`5`,rx:`9`,ry:`3`,key:`msslwz`}],[`path`,{d:`M3 12a9 3 0 0 0 5 2.69`,key:`1ui2ym`}],[`path`,{d:`M21 9.3V5`,key:`6k6cib`}],[`path`,{d:`M3 5v14a9 3 0 0 0 6.47 2.88`,key:`i62tjy`}],[`path`,{d:`M12 12v4h4`,key:`1bxaet`}],[`path`,{d:`M13 20a5 5 0 0 0 9-3 4.5 4.5 0 0 0-4.5-4.5c-1.33 0-2.54.54-3.41 1.41L12 16`,key:`1f4ei9`}]]};P.node;var ue=r(P),F=n(e(),1),I=c({endpoint:s(),local:d(),reachable:d().optional(),breaker:s().optional()}),L=c({mode:u([`single`,`sharded`]),default_graph:s().optional(),endpoints:l(I)});function R(){return w(`/dashboard/daemon/shards`,L)}function z(){return w(`/dashboard/daemon/status`)}var B=c({total_nodes:p(),total_relationships:p(),available:d().optional(),source_graphs:l(s()).optional(),degraded_graphs:l(s()).optional(),partial:d().optional()}),V=c({by_type:f(s(),p()),type_count:p(),total_typed_nodes:p(),truncated:d(),available:d(),source_graphs:l(s()),degraded_graphs:l(s()),partial:d()}),H=c({source_systems:l(s())});function U(){return w(`/enhanced/graph/stats`,B)}function de(){return w(`/enhanced/graph/node-types`,V)}function fe(){return w(`/enhanced/code/instances`,H)}function pe(){return ne(`/configure`,{action:`backup_status`})}function me(){return te(`/graph/configure`,{action:`backup_create`})}var W=t();function G(e){return e===void 0?`-`:e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function he({stats:e,placement:t}){return(0,W.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-3 gap-4`,children:[(0,W.jsxs)(`div`,{className:`rounded border p-3`,children:[(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Nodes`}),(0,W.jsx)(`p`,{className:`text-2xl font-bold`,children:G(e?.total_nodes)})]}),(0,W.jsxs)(`div`,{className:`rounded border p-3`,children:[(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Relationships`}),(0,W.jsx)(`p`,{className:`text-2xl font-bold`,children:G(e?.total_relationships)})]}),(0,W.jsxs)(`div`,{className:`rounded border p-3`,children:[(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Shard placement`}),(0,W.jsx)(`p`,{className:`text-lg font-semibold`,children:t.length?`${String(t.length)} shard(s)`:`-`})]})]})}function ge({byType:e,nodeTypes:t}){return e.length===0?null:(0,W.jsxs)(`div`,{children:[(0,W.jsxs)(`p`,{className:`text-sm font-medium mb-2 flex items-center gap-1`,children:[(0,W.jsx)(x,{className:`size-3.5`}),`Counts by type`,(0,W.jsxs)(`span`,{className:`text-muted-foreground font-normal`,children:[`(`,G(t?.type_count),` types, `,G(t?.total_typed_nodes),` nodes)`]})]}),t?.partial===!0&&(0,W.jsxs)(`p`,{className:`mb-2 flex items-center gap-1.5 text-xs text-amber-500`,children:[(0,W.jsx)(C,{className:`size-3.5 shrink-0`}),`Partial — excludes `,t.degraded_graphs.join(`, `),`.`]}),(0,W.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:e.map(([e,t])=>(0,W.jsxs)(o,{variant:`outline`,className:`gap-1`,children:[e,(0,W.jsx)(`span`,{className:`text-muted-foreground`,children:G(t)})]},e))})]})}function _e(e){return e?.partial===!0?(0,W.jsxs)(`p`,{className:`flex items-center gap-1.5 text-xs text-amber-500`,children:[(0,W.jsx)(C,{className:`size-3.5 shrink-0`}),`These totals are partial — `,(e.degraded_graphs??[]).join(`, `),` could not be read.`]}):null}function ve(e){return e.length===0?null:(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`p`,{className:`text-sm font-medium mb-2`,children:`Placed on`}),(0,W.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:e.map(e=>(0,W.jsxs)(o,{variant:e.reachable?`default`:`destructive`,className:`font-mono text-xs gap-1`,children:[e.endpoint,e.local&&(0,W.jsx)(`span`,{className:`opacity-70`,children:`· local`})]},e.endpoint))})]})}function ye({defaultGraph:e,stats:t,placement:n,byType:r,nodeTypes:i}){return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsxs)(T,{className:`text-base flex items-center gap-2`,children:[(0,W.jsx)(g,{className:`size-4`}),(0,W.jsx)(`span`,{className:`font-mono`,children:e}),(0,W.jsx)(o,{variant:`secondary`,children:`active`})]}),(0,W.jsx)(m,{children:`The active graph tenant served by this backend.`})]}),(0,W.jsxs)(v,{className:`space-y-4`,children:[he({stats:t,placement:n}),ge({byType:r,nodeTypes:i}),_e(t),ve(n)]})]})}function be({loading:e,sourcesUnavailable:t,sources:n}){return e?(0,W.jsx)(O,{className:`size-4 animate-spin text-muted-foreground`}):t?(0,W.jsx)(j,{what:`Indexed source tenants`}):n.length===0?(0,W.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`No indexed source tenants reported.`}):(0,W.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:n.map(e=>(0,W.jsx)(o,{variant:`secondary`,className:`font-mono text-xs`,children:e},e))})}function xe(){let[e,t]=(0,F.useState)(null),[n,r]=(0,F.useState)(null),[a,o]=(0,F.useState)(null),[s,c]=(0,F.useState)([]),[l,u]=(0,F.useState)(!1),[d,f]=(0,F.useState)(!1),p=async()=>{f(!0);let[e,n,i,a]=await Promise.all([U(),R(),fe(),de()]);t(e.ok?e.data:null),r(a.ok?a.data:null),o(n.ok?n.data:null),c(i.ok&&i.data?i.data.source_systems:[]),u(!i.ok),f(!1)};(0,F.useEffect)(()=>{p()},[]);let g=a?.default_graph??`__commons__`,y=a?.endpoints??[],b=Object.entries(n?.by_type??{}).sort((e,t)=>t[1]-e[1]);return(0,W.jsxs)(`div`,{className:`space-y-6`,"data-testid":`admin-tenants-panel`,children:[(0,W.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsxs)(`h2`,{className:`text-lg font-semibold flex items-center gap-2`,children:[(0,W.jsx)(ee,{className:`size-5`}),`Tenants & Graphs`]}),(0,W.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`Per-tenant node/edge counts and shard placement.`})]}),(0,W.jsxs)(E,{variant:`outline`,size:`sm`,onClick:()=>{p()},disabled:d,children:[(0,W.jsx)(i,{className:d?`size-4 animate-spin`:`size-4`}),(0,W.jsx)(`span`,{className:`ml-2`,children:`Refresh`})]})]}),ye({defaultGraph:g,stats:e,placement:y,byType:b,nodeTypes:n}),(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsxs)(T,{className:`text-base flex items-center gap-2`,children:[(0,W.jsx)(h,{className:`size-4`}),`Indexed source tenants`]}),(0,W.jsx)(m,{children:`Ingested source-systems that carry code in the graph.`})]}),(0,W.jsx)(v,{children:be({loading:d,sourcesUnavailable:l,sources:s})})]}),(0,W.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Note: full multi-tenant enumeration (a per-tenant catalog with per-tenant counts) is not yet exposed over the REST surface — the engine tenant catalog is reachable only over the UDS client. This panel shows the active graph with real statistics and shard placement plus indexed source tenants.`})]})}function Se(e){if(!e)return`outline`;let t=e.toLowerCase();return t===`closed`?`default`:t===`open`?`destructive`:`secondary`}function Ce({topology:e,endpoints:t,reachable:n}){return(0,W.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-4 gap-4`,children:[(0,W.jsx)(D,{children:(0,W.jsxs)(v,{className:`pt-6`,children:[(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Mode`}),(0,W.jsx)(`p`,{className:`text-2xl font-bold capitalize`,children:e?.mode??`-`})]})}),(0,W.jsx)(D,{children:(0,W.jsxs)(v,{className:`pt-6`,children:[(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Shards`}),(0,W.jsx)(`p`,{className:`text-2xl font-bold`,children:t.length||`-`})]})}),(0,W.jsx)(D,{children:(0,W.jsxs)(v,{className:`pt-6`,children:[(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Reachable`}),(0,W.jsx)(`p`,{className:`text-2xl font-bold`,children:t.length?`${String(n)}/${String(t.length)}`:`-`})]})}),(0,W.jsx)(D,{children:(0,W.jsxs)(v,{className:`pt-6`,children:[(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Default graph`}),(0,W.jsx)(`p`,{className:`text-lg font-semibold font-mono truncate`,children:e?.default_graph??`-`})]})})]})}function we(e,t){return(0,W.jsxs)(`div`,{className:`flex items-center justify-between rounded border p-3 text-sm`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0`,children:[(0,W.jsx)(a,{className:`size-4 shrink-0 text-muted-foreground`}),(0,W.jsxs)(`div`,{className:`flex flex-col min-w-0`,children:[(0,W.jsx)(`span`,{className:`font-mono truncate`,children:e.endpoint}),(0,W.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`writer #`,t,` `,e.local?`· local`:`· remote`]})]})]}),(0,W.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.local&&(0,W.jsx)(o,{variant:`outline`,children:`local`}),e.breaker&&(0,W.jsx)(o,{variant:Se(e.breaker),className:`font-mono text-xs`,children:e.breaker}),e.reachable?(0,W.jsxs)(o,{variant:`default`,className:`gap-1`,children:[(0,W.jsx)(re,{className:`size-3`}),`up`]}):(0,W.jsxs)(o,{variant:`destructive`,className:`gap-1`,children:[(0,W.jsx)(S,{className:`size-3`}),`down`]})]})]},e.endpoint)}function Te(e){return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{className:`text-base`,children:`Shards`}),(0,W.jsx)(m,{children:`Each configured engine endpoint and its live health.`})]}),(0,W.jsx)(v,{children:e.length===0?(0,W.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`No shard endpoints reported.`}):(0,W.jsx)(`div`,{className:`space-y-2`,children:e.map(we)})})]})}function Ee(e){return(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2 text-sm`,children:[e.role!==void 0&&(0,W.jsxs)(o,{variant:`secondary`,className:`gap-1`,children:[`role: `,e.role]}),(0,W.jsxs)(o,{variant:e.running?`default`:`outline`,className:`gap-1`,children:[e.running?(0,W.jsx)(O,{className:`size-3 animate-spin`}):(0,W.jsx)(S,{className:`size-3`}),e.running?`running`:`stopped`]}),e.queue_depth!==void 0&&(0,W.jsxs)(o,{variant:`secondary`,children:[`queue: `,String(e.queue_depth)]})]})}function De(e){return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{className:`text-base`,children:`Daemon`}),(0,W.jsx)(m,{children:`The consolidated KG background daemon that hosts the local shard.`})]}),(0,W.jsx)(v,{children:e?Ee(e):(0,W.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`Daemon status unavailable.`})})]})}function Oe({unavailable:e,topologyError:t,topology:n,endpoints:r,reachable:i,daemon:a}){return e?(0,W.jsxs)(`p`,{className:`text-muted-foreground text-sm`,children:[`The `,(0,W.jsx)(`code`,{children:`/api/dashboard/daemon/shards`}),` route is not activated on this backend yet.`]}):t?(0,W.jsx)(j,{what:`Shard topology (${t})`}):(0,W.jsxs)(W.Fragment,{children:[Ce({topology:n,endpoints:r,reachable:i}),Te(r),De(a)]})}function ke(){let[e,t]=(0,F.useState)(null),[n,r]=(0,F.useState)(null),[a,s]=(0,F.useState)(!1),[c,l]=(0,F.useState)(null),[u,d]=(0,F.useState)(!1),f=async()=>{d(!0);let[e,n]=await Promise.all([R(),z()]);s(e.unavailable),l(!e.ok&&!e.unavailable?e.error??`The shard topology request failed.`:null),t(e.ok?e.data:null),r(n.ok?n.data:null),d(!1)};(0,F.useEffect)(()=>{f()},[]);let p=e?.endpoints??[],m=p.filter(e=>e.reachable).length;return(0,W.jsxs)(`div`,{className:`space-y-6`,"data-testid":`admin-shards-panel`,children:[(0,W.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsxs)(`h2`,{className:`text-lg font-semibold flex items-center gap-2`,children:[(0,W.jsx)(y,{className:`size-5`}),`Shard Topology`,e&&(0,W.jsx)(o,{variant:`secondary`,className:`uppercase`,children:e.mode})]}),(0,W.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`K-way writer layout, per-shard reachability and circuit-breaker state.`})]}),(0,W.jsxs)(E,{variant:`outline`,size:`sm`,onClick:()=>{f()},disabled:u,children:[(0,W.jsx)(i,{className:u?`size-4 animate-spin`:`size-4`}),(0,W.jsx)(`span`,{className:`ml-2`,children:`Refresh`})]})]}),Oe({unavailable:a,topologyError:c,topology:e,endpoints:p,reachable:m,daemon:n})]})}function Ae(e){if(e===void 0)return`-`;let t=[`B`,`KB`,`MB`,`GB`,`TB`],n=e,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r++;return`${n.toFixed(1)} ${t[r]}`}function je(){let[e,t]=(0,F.useState)(null),[n,r]=(0,F.useState)(!1),[i,a]=(0,F.useState)(!1),[o,s]=(0,F.useState)(!1),c=async()=>{a(!0);let e=await pe();r(!e.ok),t(e.ok?e.data:null),a(!1)};return(0,F.useEffect)(()=>{c()},[]),{status:e,loading:i,triggering:o,wired:!n,refresh:c,onTrigger:async()=>{s(!0),await me(),await c(),s(!1)}}}function Me({loading:e,triggering:t,wired:n,onRefresh:r,onTrigger:a}){return(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsxs)(E,{variant:`outline`,size:`sm`,onClick:r,disabled:e,children:[(0,W.jsx)(i,{className:e?`size-4 animate-spin`:`size-4`}),(0,W.jsx)(`span`,{className:`ml-2`,children:`Refresh`})]}),(0,W.jsxs)(E,{size:`sm`,onClick:a,disabled:!n||t,title:n?`Trigger an online backup`:`Backup REST twin not wired yet`,children:[t?(0,W.jsx)(O,{className:`size-4 animate-spin`}):(0,W.jsx)(le,{className:`size-4`}),(0,W.jsx)(`span`,{className:`ml-2`,children:`Trigger backup`})]})]})}function Ne(){return(0,W.jsxs)(D,{className:`border-dashed`,children:[(0,W.jsxs)(_,{children:[(0,W.jsxs)(T,{className:`text-base flex items-center gap-2`,children:[(0,W.jsx)(o,{variant:`outline`,children:`read-only · not wired`}),`Backup/PITR not exposed over REST yet`]}),(0,W.jsxs)(m,{children:[`Online backup / restore (EG-090) is reachable today only over the epistemic-graph UDS client (a`,(0,W.jsx)(`code`,{children:` Method::Backup`}),` op streaming a per-shard MVCC snapshot). This panel will list snapshots, show the PITR window, and enable the trigger control as soon as the REST twin is wired; until then it is read-only by design and shows no fabricated backups.`]})]}),(0,W.jsxs)(v,{className:`text-sm text-muted-foreground space-y-2`,children:[(0,W.jsx)(`p`,{className:`font-medium text-foreground`,children:`The engine backup model:`}),(0,W.jsxs)(`ul`,{className:`list-disc pl-5 space-y-1`,children:[(0,W.jsx)(`li`,{children:`Online per-shard MVCC snapshot streamed verbatim (no write-stall).`}),(0,W.jsx)(`li`,{children:`Point-in-time restore to a chosen LSN / timestamp within the retained window.`})]})]})]})}function Pe({status:e,backupCount:t}){return(0,W.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-3 gap-4`,children:[(0,W.jsx)(D,{children:(0,W.jsxs)(v,{className:`pt-6`,children:[(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Snapshots`}),(0,W.jsx)(`p`,{className:`text-2xl font-bold`,children:t})]})}),(0,W.jsx)(D,{children:(0,W.jsxs)(v,{className:`pt-6`,children:[(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Last backup`}),(0,W.jsx)(`p`,{className:`text-lg font-semibold`,children:e?.last_backup_at??`-`})]})}),(0,W.jsx)(D,{children:(0,W.jsxs)(v,{className:`pt-6`,children:[(0,W.jsxs)(`p`,{className:`text-sm text-muted-foreground flex items-center gap-1`,children:[(0,W.jsx)(ie,{className:`size-3.5`}),`PITR window`]}),(0,W.jsxs)(`p`,{className:`text-xs font-mono`,children:[e?.pitr_window?.earliest??`-`,` → `,e?.pitr_window?.latest??`-`]})]})})]})}function Fe({backup:e}){return(0,W.jsxs)(`div`,{className:`flex items-center justify-between rounded border p-2 text-sm`,children:[(0,W.jsxs)(`div`,{className:`flex flex-col min-w-0`,children:[(0,W.jsx)(`span`,{className:`font-mono truncate`,children:e.id}),(0,W.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.created_at??`-`,` `,e.shard?`· ${e.shard}`:``,` `,e.lsn?`· LSN ${e.lsn}`:``]})]}),(0,W.jsx)(o,{variant:`secondary`,children:Ae(e.size_bytes)})]})}function Ie({backups:e}){return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{className:`text-base`,children:`Snapshots`}),(0,W.jsx)(m,{children:`Retained backups available for point-in-time restore.`})]}),(0,W.jsx)(v,{children:e.length===0?(0,W.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`No snapshots yet.`}):(0,W.jsx)(`div`,{className:`space-y-2`,children:e.map(e=>(0,W.jsx)(Fe,{backup:e},e.id))})})]})}function Le({loading:e,wired:t,status:n,backups:r}){return e?(0,W.jsx)(O,{className:`size-5 animate-spin text-muted-foreground`}):t?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(Pe,{status:n,backupCount:r.length}),(0,W.jsx)(Ie,{backups:r})]}):(0,W.jsx)(Ne,{})}function Re(){let e=je(),t=e.status?.backups??[];return(0,W.jsxs)(`div`,{className:`space-y-6`,"data-testid":`admin-backup-panel`,children:[(0,W.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsxs)(`h2`,{className:`text-lg font-semibold flex items-center gap-2`,children:[(0,W.jsx)(ue,{className:`size-5`}),`Backup & PITR`]}),(0,W.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`Online backups and point-in-time restore (CONCEPT:EG-090).`})]}),(0,W.jsx)(Me,{loading:e.loading,triggering:e.triggering,wired:e.wired,onRefresh:()=>{e.refresh()},onTrigger:()=>{e.onTrigger()}})]}),(0,W.jsx)(Le,{loading:e.loading,wired:e.wired,status:e.status,backups:t})]})}var K=[[`idle_ms`,`Idle timeout`],[`absolute_ms`,`Absolute lifetime`],[`privileged_idle_ms`,`Privileged idle timeout`],[`privileged_absolute_ms`,`Privileged absolute lifetime`]];function ze(e){return Object.values(e).every(e=>Number.isInteger(e)&&e>=6e4&&e<=2592e6)}function q(e,t){return e===void 0||t===void 0||e<=t}function Be(e){return ze(e)&&q(e.idle_ms,e.absolute_ms)&&q(e.privileged_idle_ms,e.idle_ms)&&q(e.privileged_absolute_ms,e.absolute_ms)&&q(e.privileged_idle_ms,e.privileged_absolute_ms)}function Ve(e){return Object.fromEntries(K.flatMap(([t])=>e[t]===void 0?[]:[[t,e[t]]]))}function He(e,t){return Object.fromEntries(K.flatMap(([n])=>e[n]===t[n]?[]:[[n,e[n]]]))}function Ue({field:e,label:t,valueMs:n,onChangeMs:r}){return(0,W.jsxs)(`div`,{children:[(0,W.jsxs)(`label`,{className:`block text-sm`,htmlFor:e,children:[t,` (minutes)`]}),(0,W.jsx)(b,{id:e,type:`number`,min:1,max:43200,value:Math.round(n/6e4),onChange:e=>{r(Number(e.target.value)*6e4)}})]})}function We(e,t){return!Number.isInteger(e)||e<8||e>256||!Be(t)}function Ge({registration:e,setRegistration:t,fallback:n,setFallback:r,minimum:i,setMinimum:a,durations:o,setDurations:s,onSave:c}){return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`label`,{className:`block text-sm`,htmlFor:`registration-policy`,children:`Registration`}),(0,W.jsxs)(`select`,{id:`registration-policy`,className:`rounded border bg-background p-2`,value:e,onChange:e=>{t(e.target.value)},children:[(0,W.jsx)(`option`,{value:`disabled`,children:`Disabled`}),(0,W.jsx)(`option`,{value:`admin_only`,children:`Administrator only`}),(0,W.jsx)(`option`,{value:`invite`,children:`Invitation`}),(0,W.jsx)(`option`,{value:`open`,children:`Open`})]}),(0,W.jsx)(`label`,{className:`block text-sm`,htmlFor:`policy-fallback`,children:`Local fallback`}),(0,W.jsxs)(`select`,{id:`policy-fallback`,className:`rounded border bg-background p-2`,value:n,onChange:e=>{r(e.target.value)},children:[(0,W.jsx)(`option`,{value:`off`,children:`Off`}),(0,W.jsx)(`option`,{value:`break_glass`,children:`Break glass only`}),(0,W.jsx)(`option`,{value:`full`,children:`Full`})]}),(0,W.jsx)(`label`,{className:`block text-sm`,htmlFor:`password-minimum`,children:`Minimum password length`}),(0,W.jsx)(b,{id:`password-minimum`,type:`number`,min:8,max:256,value:i,onChange:e=>{a(Number(e.target.value))}}),K.map(([e,t])=>{let n=o[e];return n===void 0?null:(0,W.jsx)(Ue,{field:e,label:t,valueMs:n,onChangeMs:t=>{s(n=>({...n,[e]:t}))}},e)}),(0,W.jsx)(E,{type:`button`,disabled:We(i,o),onClick:c,children:`Save identity policy`})]})}function Ke(){let[e,t]=(0,F.useState)(null),[n,r]=(0,F.useState)(`disabled`),[i,a]=(0,F.useState)(`break_glass`),[o,s]=(0,F.useState)(12),[c,l]=(0,F.useState)({}),[u,d]=(0,F.useState)(null),f=e=>{t(e),e.kind===`ready`&&(r(e.result.registration_policy),a(e.result.local_fallback),s(e.result.password_min_chars),l(Ve(e.result)))};(0,F.useEffect)(()=>{let e=!0;return A(`identity.policy.get`).then(t=>{e&&f(t)}),()=>{e=!1}},[]);let p=async()=>{if(e?.kind!==`ready`)return;let r=await A(`identity.policy.set`,{expected_epoch:e.result.epoch,registration_policy:n,local_fallback:i,password_min_chars:o,...He(c,e.result)});d(r),r.kind===`ready`&&t(r)};return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{children:`Identity policy`}),(0,W.jsx)(m,{children:`Policy changes use the current configuration epoch and require fresh MFA.`})]}),(0,W.jsxs)(v,{className:`space-y-3`,children:[e===null&&(0,W.jsx)(`p`,{role:`status`,children:`Loading identity policy…`}),e!==null&&e.kind!==`ready`&&(0,W.jsx)(`p`,{role:`status`,children:e.message}),e?.kind===`ready`&&(0,W.jsx)(Ge,{registration:n,setRegistration:r,fallback:i,setFallback:a,minimum:o,setMinimum:s,durations:c,setDurations:l,onSave:()=>{p()}}),Object.keys(c).length>0&&(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Changing a session duration revokes existing sessions immediately.`}),(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`MFA policy editing is unavailable until the engine exposes those fields.`}),u&&(0,W.jsx)(`p`,{role:`status`,children:u.kind===`ready`?`Identity policy saved.`:u.message})]})]})}function J(e,t){return(e===`identity.sessions.list`||e===`identity.api_keys.list`)&&!t}function qe(e,t){return e.principal_id??e.id??e.handle??e.key_id??t}function Je(e,t){return e.name??e.username??e.principal_id??e.id??e.handle??e.key_id??`Record ${t+1}`}function Y(e){return e.handle??e.id??e.key_id??``}function Ye({item:e,index:t,revokeOp:n,onRevoke:r}){return(0,W.jsxs)(`li`,{className:`rounded border p-2`,children:[(0,W.jsx)(`strong`,{children:Je(e,t)}),e.status&&(0,W.jsx)(`span`,{className:`ml-2 text-muted-foreground`,children:e.status}),e.description&&(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e.description}),n&&Y(e)&&(0,W.jsx)(E,{type:`button`,size:`sm`,variant:`outline`,className:`ml-2`,onClick:()=>{r(Y(e))},children:`Revoke`})]})}function Xe({state:e,revokeOp:t,loadingHint:n,onRevoke:r,onLoadMore:i}){return e===null?(0,W.jsx)(`p`,{role:`status`,children:n}):e.kind===`ready`?Array.isArray(e.result.items)?e.result.items.length===0?(0,W.jsx)(`p`,{role:`status`,children:`No records reported.`}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`ul`,{className:`space-y-2`,children:e.result.items.map((e,n)=>(0,W.jsx)(Ye,{item:e,index:n,revokeOp:t,onRevoke:r},qe(e,n)))}),e.result.next_cursor&&(0,W.jsx)(E,{type:`button`,variant:`outline`,onClick:i,children:`Load more`})]}):(0,W.jsx)(`p`,{role:`alert`,children:`The identity service returned an invalid list.`}):(0,W.jsx)(`p`,{role:`status`,children:e.message})}function Ze(e,t){let[n,r]=(0,F.useState)(null),[i,a]=(0,F.useState)(0),[o,s]=(0,F.useState)(null);return(0,F.useEffect)(()=>{let n=!0;return J(e,t)?()=>void 0:(A(e,{...e===`identity.audit.list`||e===`identity.api_keys.list`?{limit:50}:{},...t?{principal_id:t}:{}}).then(e=>{n&&r(e)}),()=>{n=!1})},[e,t,i]),{state:n,mutation:o,revoke:async(e,t)=>{if(!e)return;let n=await A(e,{id:t});s(n),n.kind===`ready`&&a(e=>e+1)},loadMore:async()=>{if(n?.kind!==`ready`||!n.result.next_cursor)return;let i=await A(e,{after:n.result.next_cursor,limit:50,...t?{principal_id:t}:{}});i.kind===`ready`?r({kind:`ready`,result:{items:[...n.result.items,...i.result.items],next_cursor:i.result.next_cursor}}):s(i)},refresh:()=>{a(e=>e+1)}}}function X({title:e,op:t,description:n,principalId:r,revokeOp:i}){let a=Ze(t,r),o=J(t,r)?`Enter a principal id to inspect its records.`:`Loading…`;return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{children:e}),(0,W.jsx)(m,{children:n})]}),(0,W.jsxs)(v,{children:[r&&(0,W.jsxs)(`p`,{className:`mb-2 text-xs text-muted-foreground`,children:[`Principal: `,r]}),a.state!==null&&(0,W.jsx)(E,{type:`button`,size:`sm`,variant:`outline`,className:`mb-3`,onClick:a.refresh,children:`Refresh`}),(0,W.jsx)(Xe,{state:a.state,revokeOp:i,loadingHint:o,onRevoke:e=>{a.revoke(i,e)},onLoadMore:()=>{a.loadMore()}}),a.mutation&&(0,W.jsx)(`p`,{role:`status`,children:a.mutation.kind===`ready`?`Revocation confirmed.`:a.mutation.message})]})]})}function Z({kind:e}){let[t,n]=(0,F.useState)(``),[r,i]=(0,F.useState)(``);return(0,W.jsxs)(`div`,{className:`space-y-3`,children:[(0,W.jsxs)(`form`,{className:`flex gap-2`,onSubmit:e=>{e.preventDefault(),i(t.trim())},children:[(0,W.jsx)(b,{"aria-label":`${e===`sessions`?`Session`:`API key`} principal id`,placeholder:`Principal id`,value:t,onChange:e=>{n(e.target.value)}}),(0,W.jsxs)(E,{type:`submit`,disabled:!t.trim(),children:[`Load `,e]})]}),(0,W.jsx)(X,{title:e===`sessions`?`Sessions`:`API keys`,op:e===`sessions`?`identity.sessions.list`:`identity.api_keys.list`,principalId:r,revokeOp:e===`sessions`?`identity.sessions.revoke`:`identity.api_keys.revoke`,description:e===`sessions`?`Sessions for the selected principal.`:`Metadata only; secrets are never displayed.`})]})}function Q({kind:e}){let[t,n]=(0,F.useState)(``),[r,i]=(0,F.useState)(``),[a,o]=(0,F.useState)(``),[s,c]=(0,F.useState)(``),[l,u]=(0,F.useState)(`add`),[d,f]=(0,F.useState)(null),[p,h]=(0,F.useState)(!1),g=e===`group`,y=g?`Group`:`Role`,x=async()=>{h(!0);let e=a.split(`,`).map(e=>e.trim()).filter(Boolean);f(await A(g?`identity.groups.upsert`:`identity.roles.upsert`,g?{group_id:t,name:r,roles:e}:{role_id:t,name:r,scopes:e})),h(!1)},S=async()=>{h(!0),f(await A(g?`identity.groups.change_membership`:`identity.roles.change_user_role`,g?{principal_id:s,group_id:t,change:l}:{principal_id:s,role_id:t,change:l})),h(!1)};return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsxs)(T,{children:[y,` administration`]}),(0,W.jsx)(m,{children:`Writes require administrator authority and fresh MFA.`})]}),(0,W.jsxs)(v,{className:`space-y-3`,children:[(0,W.jsxs)(`div`,{className:`grid gap-2 sm:grid-cols-3`,children:[(0,W.jsx)(b,{"aria-label":`${y} id`,placeholder:`${y} id`,value:t,onChange:e=>{n(e.target.value)}}),(0,W.jsx)(b,{"aria-label":`${y} name`,placeholder:`Display name`,value:r,onChange:e=>{i(e.target.value)}}),(0,W.jsx)(b,{"aria-label":g?`Group roles`:`Role scopes`,placeholder:g?`Roles, comma separated`:`Scopes, comma separated`,value:a,onChange:e=>{o(e.target.value)}})]}),(0,W.jsxs)(E,{type:`button`,disabled:p||!t.trim()||!r.trim(),onClick:()=>{x()},children:[`Save `,y.toLowerCase()]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2 border-t pt-3`,children:[(0,W.jsx)(b,{"aria-label":`Member principal id`,className:`max-w-xs`,placeholder:`Principal id`,value:s,onChange:e=>{c(e.target.value)}}),(0,W.jsxs)(`select`,{"aria-label":`Membership action`,className:`rounded border bg-background p-2`,value:l,onChange:e=>{u(e.target.value)},children:[(0,W.jsx)(`option`,{value:`add`,children:`Add`}),(0,W.jsx)(`option`,{value:`remove`,children:`Remove`})]}),(0,W.jsx)(E,{type:`button`,disabled:p||!t.trim()||!s.trim(),onClick:()=>{S()},children:`Apply membership`})]}),d&&(0,W.jsx)(`p`,{role:`status`,children:d.kind===`ready`?`${y} change confirmed. Refresh the list.`:d.message})]})]})}function Qe(){let[e,t]=(0,F.useState)(``),[n,r]=(0,F.useState)(`{"groups":[]}`),[i,a]=(0,F.useState)(null),o=async()=>{try{let t=JSON.parse(n);if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Claims must be an object`);if(!Object.values(t).every(e=>Array.isArray(e)&&e.every(e=>typeof e==`string`)))throw Error(`Every claim must be a string array`);a(await A(`identity.idps.mapping_dry_run`,{idp_id:e,claims:t}))}catch{a({kind:`error`,message:`Enter a JSON object whose values are string arrays.`})}};return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{children:`Mapping rule dry run`}),(0,W.jsx)(m,{children:`Preview the roles, groups and scopes a sample claim set would receive. This does not change an identity.`})]}),(0,W.jsxs)(v,{className:`space-y-3`,children:[(0,W.jsx)(b,{"aria-label":`Identity provider id`,placeholder:`Identity provider id`,value:e,onChange:e=>{t(e.target.value)}}),(0,W.jsx)(`textarea`,{"aria-label":`Sample claims JSON`,className:`w-full rounded border bg-background p-2 font-mono text-sm`,rows:4,value:n,onChange:e=>{r(e.target.value)}}),(0,W.jsx)(E,{type:`button`,disabled:!e.trim(),onClick:()=>{o()},children:`Evaluate mapping`}),i?.kind!==`ready`&&i!==null&&(0,W.jsx)(`p`,{role:`status`,children:i.message}),i?.kind===`ready`&&(0,W.jsxs)(`dl`,{className:`text-sm space-y-1`,children:[(0,W.jsx)(`dt`,{children:`Roles`}),(0,W.jsx)(`dd`,{children:i.result.roles.join(`, `)||`None`}),(0,W.jsx)(`dt`,{children:`Groups`}),(0,W.jsx)(`dd`,{children:i.result.groups.join(`, `)||`None`}),(0,W.jsx)(`dt`,{children:`Scopes`}),(0,W.jsx)(`dd`,{children:i.result.scopes.join(`, `)||`None`})]})]})]})}function $(){let[e,t]=(0,F.useState)(``),[n,r]=(0,F.useState)(``),[i,a]=(0,F.useState)(`oidc`),[o,s]=(0,F.useState)(`{}`),[c,l]=(0,F.useState)(``),[u,d]=(0,F.useState)(null),f=async()=>{try{let t=JSON.parse(o);if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Invalid configuration`);d(await A(`identity.idps.upsert`,{idp_id:e.trim(),kind:i,display_name:n.trim(),enabled:!1,config_json:o,jit_policy:`deny`,...c.trim()?{secret_ref:c.trim()}:{}}))}catch{d({kind:`error`,message:`Configuration must be a JSON object.`})}};return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{children:`Configure identity provider`}),(0,W.jsx)(m,{children:`Use a secret reference; do not paste credentials. New providers start disabled with just-in-time provisioning denied until mapping rules are reviewed.`})]}),(0,W.jsxs)(v,{className:`space-y-3`,children:[(0,W.jsxs)(`div`,{className:`grid gap-2 sm:grid-cols-2`,children:[(0,W.jsx)(b,{"aria-label":`Provider id`,placeholder:`Provider id`,value:e,onChange:e=>{t(e.target.value)}}),(0,W.jsx)(b,{"aria-label":`Provider display name`,placeholder:`Display name`,value:n,onChange:e=>{r(e.target.value)}})]}),(0,W.jsxs)(`select`,{"aria-label":`Provider kind`,className:`rounded border bg-background p-2`,value:i,onChange:e=>{a(e.target.value)},children:[(0,W.jsx)(`option`,{value:`oidc`,children:`OIDC`}),(0,W.jsx)(`option`,{value:`saml`,children:`SAML`}),(0,W.jsx)(`option`,{value:`ldap`,children:`LDAP`}),(0,W.jsx)(`option`,{value:`scim`,children:`SCIM`})]}),(0,W.jsx)(b,{"aria-label":`Provider secret reference`,placeholder:`Secret reference (optional)`,value:c,onChange:e=>{l(e.target.value)}}),(0,W.jsx)(`textarea`,{"aria-label":`Provider configuration JSON`,className:`w-full rounded border bg-background p-2 font-mono text-sm`,rows:5,value:o,onChange:e=>{s(e.target.value)}}),(0,W.jsx)(E,{type:`button`,disabled:!e.trim()||!n.trim(),onClick:()=>{f()},children:`Save provider`}),u&&(0,W.jsx)(`p`,{role:`status`,children:u.kind===`ready`?`Provider saved. Refresh the list.`:u.message})]})]})}function $e(){let[e,t]=(0,F.useState)(null),[n,r]=(0,F.useState)(``),[i,a]=(0,F.useState)(`break_glass`),[o,s]=(0,F.useState)(!1),[c,l]=(0,F.useState)(null);return(0,F.useEffect)(()=>{let e=!0;return A(`identity.mode.status`).then(n=>{e&&t(n)}),()=>{e=!1}},[]),{state:e,target:n,setTarget:r,fallback:i,setFallback:a,acknowledged:o,setAcknowledged:s,transition:c,submit:async()=>{let e=await A(`identity.mode.transition`,n===`external`?{to:n,local_fallback:i}:{to:n});l(e),e.kind===`ready`&&t(await A(`identity.mode.status`))}}}function et(e,t,n){return!e||!t||n?.kind!==`ready`||t===n.result.mode}function tt(){let e=$e();return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{children:`Security mode`}),(0,W.jsx)(m,{children:`Mode transitions require a fresh MFA administrator session. A successful transition revokes existing sessions.`})]}),(0,W.jsxs)(v,{className:`space-y-3`,children:[e.state===null&&(0,W.jsx)(`p`,{role:`status`,children:`Loading mode…`}),e.state!==null&&e.state.kind!==`ready`&&(0,W.jsx)(`p`,{role:`status`,children:e.state.message}),e.state?.kind===`ready`&&(0,W.jsxs)(`p`,{children:[`Current mode: `,(0,W.jsx)(`strong`,{children:e.state.result.mode})]}),(0,W.jsx)(`label`,{className:`block text-sm`,htmlFor:`target-mode`,children:`Target mode`}),(0,W.jsxs)(`select`,{id:`target-mode`,className:`rounded border bg-background p-2`,value:e.target,onChange:t=>{e.setTarget(t.target.value)},children:[(0,W.jsx)(`option`,{value:``,children:`Select a mode`}),(0,W.jsx)(`option`,{value:`local`,children:`Local`}),(0,W.jsx)(`option`,{value:`external`,children:`External`})]}),e.target===`external`&&(0,W.jsxs)(`select`,{"aria-label":`Local fallback`,className:`rounded border bg-background p-2`,value:e.fallback,onChange:t=>{e.setFallback(t.target.value)},children:[(0,W.jsx)(`option`,{value:`off`,children:`No local fallback`}),(0,W.jsx)(`option`,{value:`break_glass`,children:`Break glass only`}),(0,W.jsx)(`option`,{value:`full`,children:`Full local fallback`})]}),(0,W.jsxs)(`label`,{className:`flex items-center gap-2 text-sm`,children:[(0,W.jsx)(`input`,{type:`checkbox`,checked:e.acknowledged,onChange:t=>{e.setAcknowledged(t.target.checked)}}),`I understand this transition revokes current sessions.`]}),(0,W.jsx)(E,{type:`button`,disabled:et(e.acknowledged,e.target,e.state),onClick:()=>{e.submit()},children:`Request transition`}),e.transition&&(0,W.jsx)(`p`,{role:`status`,children:e.transition.kind===`ready`?`Transition completed. Sign in again.`:e.transition.message})]})]})}function nt(){let[e,t]=(0,F.useState)(!1),[n,r]=(0,F.useState)(null),i=async()=>{r(await A(`identity.issuer.rotate`))};return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{children:`Issuer key rotation`}),(0,W.jsx)(m,{children:`Rotate the Arbora signer with overlap. A fresh administrator MFA confirmation is required.`})]}),(0,W.jsxs)(v,{className:`space-y-3`,children:[(0,W.jsxs)(`label`,{className:`flex items-center gap-2 text-sm`,children:[(0,W.jsx)(`input`,{type:`checkbox`,checked:e,onChange:e=>{t(e.target.checked)}}),`I understand issuer rotation changes the signing key.`]}),(0,W.jsx)(E,{type:`button`,disabled:!e,onClick:()=>{i()},children:`Request issuer rotation`}),n&&(0,W.jsx)(`p`,{role:`status`,children:n.kind===`ready`?`Issuer key rotated (epoch ${n.result.epoch}, key ${n.result.issuer_kid_current}).`:n.message})]})]})}function rt(){let[e,t]=(0,F.useState)(``),[n,r]=(0,F.useState)(``),[i,a]=(0,F.useState)(null),[o,s]=(0,F.useState)(null),c=async()=>{a(await A(`identity.scim_clients.list`))};(0,F.useEffect)(()=>{c()},[]);let l=async()=>{let t=await A(`identity.scim_clients.upsert`,{idp_id:e.trim(),principal_id:n.trim()});s(t),t.kind===`ready`&&c()},u=async e=>{let t=await A(`identity.scim_clients.remove`,{idp_id:e});s(t),t.kind===`ready`&&c()};return(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{children:`SCIM clients`}),(0,W.jsx)(m,{children:`Bind an enabled SCIM provider to an active service principal.`})]}),(0,W.jsxs)(v,{className:`space-y-3`,children:[i===null&&(0,W.jsx)(`p`,{role:`status`,children:`Loading SCIM clients…`}),i&&i.kind!==`ready`&&(0,W.jsx)(`p`,{role:`status`,children:i.message}),i?.kind===`ready`&&(0,W.jsx)(`ul`,{className:`space-y-2`,children:i.result.items.map(e=>(0,W.jsxs)(`li`,{className:`flex items-center justify-between rounded border p-2`,children:[(0,W.jsxs)(`span`,{children:[e.idp_id,`: `,(0,W.jsx)(`code`,{children:e.principal_id}),` (`,e.enabled?`enabled`:`disabled`,`)`]}),(0,W.jsx)(E,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>{u(e.idp_id)},children:`Remove`})]},e.idp_id))}),(0,W.jsx)(b,{"aria-label":`SCIM provider id`,placeholder:`Provider id`,value:e,onChange:e=>{t(e.target.value)}}),(0,W.jsx)(b,{"aria-label":`SCIM service principal id`,placeholder:`Service principal id`,value:n,onChange:e=>{r(e.target.value)}}),(0,W.jsx)(E,{type:`button`,disabled:!e.trim()||!n.trim(),onClick:()=>{l()},children:`Bind SCIM client`}),o&&(0,W.jsx)(`p`,{role:`status`,children:o.kind===`ready`?`SCIM client change confirmed.`:o.message})]})]})}function it(){let[e,t]=(0,F.useState)(null),[n,r]=(0,F.useState)(null),i=async()=>{t(await A(`identity.audit.verify`))},a=async()=>{let e=await A(`identity.audit.export`,{limit:500});if(r(e),e.kind!==`ready`)return;let t=URL.createObjectURL(new Blob([JSON.stringify(e.result,null,2)],{type:`application/json`})),n=document.createElement(`a`);n.href=t,n.download=`identity-audit-page.json`,n.click(),URL.revokeObjectURL(t)};return(0,W.jsxs)(`div`,{className:`space-y-4`,children:[(0,W.jsx)(X,{title:`Identity audit`,op:`identity.audit.list`,description:`Identity administration events.`}),(0,W.jsxs)(D,{children:[(0,W.jsxs)(_,{children:[(0,W.jsx)(T,{children:`Audit integrity and export`}),(0,W.jsx)(m,{children:`Verify the chain or export a bounded page with its continuation cursor.`})]}),(0,W.jsxs)(v,{className:`space-y-2`,children:[(0,W.jsxs)(`div`,{className:`flex gap-2`,children:[(0,W.jsx)(E,{type:`button`,variant:`outline`,onClick:()=>{i()},children:`Verify audit chain`}),(0,W.jsx)(E,{type:`button`,variant:`outline`,onClick:()=>{a()},children:`Export first audit page`})]}),e&&(0,W.jsx)(`p`,{role:`status`,children:e.kind===`ready`?e.result.valid?`Audit chain verified.`:`Audit chain broken at sequence ${e.result.first_broken_seq??`unknown`}.`:e.message}),n&&n.kind!==`ready`&&(0,W.jsx)(`p`,{role:`status`,children:n.message})]})]})]})}function at(){return(0,W.jsxs)(`div`,{className:`space-y-6`,"data-testid":`admin-view`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsxs)(`h1`,{className:`text-2xl font-bold flex items-center gap-2`,children:[(0,W.jsx)(ae,{className:`size-6`}),`Admin Console`]}),(0,W.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Arbora identity, security and engine administration.`})]}),(0,W.jsxs)(ce,{defaultValue:`users`,children:[(0,W.jsx)(se,{className:`flex h-auto flex-wrap justify-start`,children:[`users`,`service-accounts`,`groups`,`roles`,`idps`,`sessions`,`api-keys`,`audit`,`security-mode`,`policy`,`tenants`,`shards`,`backup`].map(e=>(0,W.jsx)(oe,{value:e,children:e.replaceAll(`-`,` `)},e))}),(0,W.jsx)(k,{value:`users`,children:(0,W.jsx)(M,{})}),(0,W.jsx)(k,{value:`service-accounts`,children:(0,W.jsx)(X,{title:`Service accounts`,op:`identity.service_accounts.list`,description:`Active service principals from Arbora identity.`})}),(0,W.jsxs)(k,{value:`groups`,className:`space-y-4`,children:[(0,W.jsx)(X,{title:`Groups`,op:`identity.groups.list`,description:`Groups and memberships from Arbora identity.`}),(0,W.jsx)(Q,{kind:`group`})]}),(0,W.jsxs)(k,{value:`roles`,className:`space-y-4`,children:[(0,W.jsx)(X,{title:`Roles and scopes`,op:`identity.roles.list`,description:`Roles and effective scope grants from Arbora identity.`}),(0,W.jsx)(Q,{kind:`role`})]}),(0,W.jsxs)(k,{value:`idps`,className:`space-y-4`,children:[(0,W.jsx)(X,{title:`Identity providers`,op:`identity.idps.list`,description:`Configured external authorities.`}),(0,W.jsx)($,{}),(0,W.jsx)(Qe,{}),(0,W.jsx)(rt,{})]}),(0,W.jsx)(k,{value:`sessions`,children:(0,W.jsx)(Z,{kind:`sessions`})}),(0,W.jsx)(k,{value:`api-keys`,children:(0,W.jsx)(Z,{kind:`api-keys`})}),(0,W.jsx)(k,{value:`audit`,children:(0,W.jsx)(it,{})}),(0,W.jsxs)(k,{value:`security-mode`,className:`space-y-4`,children:[(0,W.jsx)(tt,{}),(0,W.jsx)(nt,{})]}),(0,W.jsx)(k,{value:`policy`,children:(0,W.jsx)(Ke,{})}),(0,W.jsx)(k,{value:`tenants`,children:(0,W.jsx)(xe,{})}),(0,W.jsx)(k,{value:`shards`,children:(0,W.jsx)(ke,{})}),(0,W.jsx)(k,{value:`backup`,children:(0,W.jsx)(Re,{})})]})]})}export{at as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e,r as t,s as n}from"./bundle-mjs-DIyOrgL5.js";import{t as r}from"./external-link-Dyd5OsGm.js";import{t as i}from"./plus-s20KYBeu.js";import{t as a}from"./refresh-cw-BVhl5aJX.js";import{t as o}from"./sparkles-Bae0tRI0.js";import{t as s}from"./badge-nQZ87mVE.js";import{E as c,S as l,c as u,d,f,i as p,x as m}from"./api-validation-CCoR_LRu.js";import{At as h,Mt as ee,Nn as te,Qt as ne,_ as re,d as g,f as ie,g as ae,kt as _,m as oe,p as se,rt as v,xt as y,yn as ce,zn as le,zt as ue}from"./index-B3Hz4lzB.js";import{i as de,n as b,r as fe,t as pe}from"./tabs-BxSTPadT.js";import{t as x}from"./unavailable-notice-B7WdWNor.js";import{t as S}from"./status-message-ovrDYMYX.js";import{t as me}from"./scroll-area-srEWz9Q3.js";var C=n(e()),w=t();function he(e){return e===`library`||e===`compose`||e===`external`||e===`config`}function ge(e,t,n,r){e!==t&&(n.current+=1,r.current+=1)}var _e=l({id:c().min(1),name:c().min(1),description:c(),kind:u([`local`,`a2a`]),mcp_server:c().nullable().optional(),model_preference:c().nullable().optional(),timestamp:c().nullable().optional(),status:c().optional(),runnable_bound:f().optional(),tools:d(l({id:c().optional(),name:c().optional()})).optional(),endpoint:c().nullable().optional()}),ve=l({id:c().min(1),name:c().min(1),mcp_server:c().nullable().optional(),tags:d(c())}),ye=l({mcp_server:c().min(1),tool_count:m().int().nonnegative(),sample_tools:d(c()),reason:c()}),be=l({id:c().min(1),provider:c().min(1),intelligence_level:c().optional(),vision:f().optional(),reasoning:f().optional(),tools_enabled:f().optional(),can_route:f().optional(),can_kg:f().optional(),context_window:m().int().positive().nullable().optional()}),xe=l({id:c().min(1),provider:c().min(1),chunk_size:m().int().positive().optional(),context_window:m().int().positive().nullable().optional()}),Se=l({app_profile:c(),deployment_profile:c(),chat_models:d(be),embedding_models:d(xe)});function Ce(e){e.controller.current?.abort();let t=new AbortController,n=e.sequence.current+1;return e.sequence.current=n,e.controller.current=t,{id:n,controller:t}}function T(e,t,n){return e.sequence.current===t&&e.controller.current===n&&!n.signal.aborted}function we(e){return e instanceof Error&&e.name===`AbortError`}function Te(e){for(let t of e)t.sequence.current+=1,t.controller.current?.abort(),t.controller.current=null}function Ee(e){window.history.pushState({},``,e),window.dispatchEvent(new Event(`history-state-changed`))}var E=120,D=32e3,O=2048;function k(e){let t=e.trim();if(!t)return`Enter the URL of the external agent`;if(I(t)>O)return`The URL must be 2,048 UTF-8 bytes or fewer`;try{let e=new URL(t);if(e.protocol!==`http:`&&e.protocol!==`https:`)return`Use an http:// or https:// URL`}catch{return`Enter a complete http:// or https:// URL`}return null}function A(e){if(!e.trim())return{value:void 0,error:null};try{let t=JSON.parse(e);return typeof t!=`object`||!t||Array.isArray(t)||Object.keys(t).length===0?{value:void 0,error:`Agent card JSON must be a non-empty JSON object`}:{value:t,error:null}}catch{return{value:void 0,error:`Enter valid JSON for the agent card`}}}function j(e){return e.trim()?k(e):null}function M(e,t,n){return n?`${e} ${t}`:e}function N(e,t){return t?(0,w.jsx)(`p`,{id:e,role:`alert`,className:`mt-1 text-[11px] text-red-400 font-medium`,children:t}):null}function P(e,t,n,r){return[e,!t.trim(),!!n,!!r].some(Boolean)}function De(e){return`${(e.replace(/[^A-Za-z0-9_.:-]/g,`-`).replace(/^[^A-Za-z0-9]+/,``)||`custom`).slice(0,114)}-agent`}function F(e){return Array.from(e).length}function I(e){return new TextEncoder().encode(e).byteLength}function L(){return null}async function Oe(e,t,n){let r=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});return r.ok?{ok:!0}:{ok:!1,error:(await r.json().catch(L))?.detail??n}}function ke(e,t){let n=e.trim(),r=n?k(e):`An agent URL is required`,i=A(t);return{url:n,agentCard:i.value,error:r??i.error}}function Ae(e,t){return!e||!t?`Name and instructions are required`:F(e)>E?`Agent name must be ${E} characters or fewer`:I(t)>D?`Instructions must be ${D.toLocaleString()} bytes or fewer`:null}var je={app_profile:``,deployment_profile:``,chat_models:[],embedding_models:[]};function R(){return(0,w.jsxs)(`div`,{className:`space-y-3`,children:[(0,w.jsxs)(`h3`,{className:`text-xs font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5`,children:[(0,w.jsx)(o,{className:`size-3.5 text-emerald-400`}),` Suggested, from what is installed`]}),(0,w.jsx)(x,{what:`Agent suggestions`})]})}function z(e,t){return(0,w.jsxs)(`div`,{className:`p-3.5 rounded-lg border border-emerald-500/20 bg-emerald-500/5 flex flex-col gap-2`,children:[(0,w.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,w.jsx)(`span`,{className:`font-bold text-sm text-foreground`,children:e.mcp_server}),(0,w.jsxs)(s,{variant:`secondary`,className:`text-[10px]`,children:[e.tool_count,` tool`,e.tool_count===1?``:`s`]})]}),(0,w.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:e.reason}),(0,w.jsxs)(_,{size:`sm`,variant:`outline`,className:`self-start h-7 text-xs`,onClick:t.bind(null,e),children:[(0,w.jsx)(i,{className:`size-3.5 mr-1`}),` Build this agent`]})]},e.mcp_server)}function Me(e,t){return e.length===0?null:(0,w.jsxs)(`div`,{className:`space-y-3`,children:[(0,w.jsxs)(`h3`,{className:`text-xs font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5`,children:[(0,w.jsx)(o,{className:`size-3.5 text-emerald-400`}),` Suggested, from what is installed`]}),(0,w.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-3`,children:e.slice(0,6).map(e=>z(e,t))})]})}function B({loadingSuggestions:e,suggestionsUnavailable:t,suggestions:n,onStartFromSuggestion:r}){return e?null:t?R():Me(n,r)}async function V({refs:e,path:t,schema:n,fallback:r,setData:i,setLoading:a,setUnavailable:o,onFailure:s}){let c=Ce(e);try{a(!0);let r=await p(t,n,{signal:c.controller.signal});if(!T(e,c.id,c.controller))return;i(r),o(!1)}catch(t){if(!T(e,c.id,c.controller)||we(t))return;i(r),o(!0),s?.()}finally{T(e,c.id,c.controller)&&a(!1)}}function Ne(){h.error(`Failed to connect to the Agent Library`)}function H({agent:e,onArchive:t}){return(0,w.jsxs)(`div`,{className:`p-4 rounded-xl border border-border/40 bg-muted/10 backdrop-blur-sm hover:border-emerald-500/30 transition-all flex flex-col justify-between`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsxs)(`div`,{className:`flex items-center justify-between gap-2 mb-2`,children:[(0,w.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[e.kind===`a2a`?(0,w.jsx)(ce,{className:`size-4 text-teal-400 shrink-0`}):(0,w.jsx)(le,{className:`size-4 text-emerald-400 shrink-0`}),(0,w.jsx)(`h4`,{className:`font-bold text-sm text-foreground truncate`,children:e.name})]}),(0,w.jsx)(s,{variant:`outline`,className:`text-[10px] font-semibold shrink-0 ${e.kind===`a2a`?`bg-teal-500/10 border-teal-500/30 text-teal-400`:`bg-emerald-500/10 border-emerald-500/30 text-emerald-400`}`,children:e.kind===`a2a`?`External · A2A`:`Local`})]}),(0,w.jsx)(`p`,{className:`text-xs text-muted-foreground leading-normal line-clamp-3`,children:e.description||`No description.`}),e.mcp_server&&(0,w.jsxs)(`div`,{className:`text-[10px] text-muted-foreground mt-2`,children:[(0,w.jsx)(ee,{className:`size-3 inline mr-1`}),`bound to `,(0,w.jsx)(`code`,{className:`font-mono`,children:e.mcp_server})]})]}),(0,w.jsxs)(`div`,{className:`mt-4 flex items-center justify-between border-t border-border/30 pt-3`,children:[(0,w.jsxs)(`div`,{className:`flex items-center gap-1 text-[10px] text-emerald-400 font-bold`,children:[(0,w.jsx)(te,{className:`size-3`}),e.runnable_bound===!1?`Prompt only`:`Delegatable`]}),(0,w.jsx)(`button`,{type:`button`,onClick:()=>{t(e)},className:`p-1.5 rounded text-muted-foreground hover:text-red-400 hover:bg-red-500/10 transition-all`,"aria-label":`Archive ${e.name}`,children:(0,w.jsx)(ue,{className:`size-3.5`})})]})]},e.id)}function U({loadingAgents:e,agentsUnavailable:t,filteredAgents:n,onArchive:r,onCancelLoading:i}){return e?(0,w.jsx)(`div`,{className:`flex justify-center py-12`,children:(0,w.jsx)(S,{status:`loading`,label:`Querying the graph...`,onCancel:i})}):t?(0,w.jsx)(`div`,{className:`text-center py-12`,children:(0,w.jsx)(x,{what:`The Agent Library`,className:`justify-center`})}):n.length===0?(0,w.jsx)(`div`,{className:`flex justify-center py-12`,children:(0,w.jsx)(S,{status:`empty`,label:`No agents yet. Compose one, or register an external A2A agent.`})}):(0,w.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:n.map(e=>H({agent:e,onArchive:r}))})}function Pe(e){let{loadingSuggestions:t,suggestionsUnavailable:n,suggestions:r,onStartFromSuggestion:o,search:s,onSearchChange:c,onRefresh:l,loadingAgents:u,onNewAgent:d,agentsUnavailable:f,filteredAgents:p,onArchive:m,onCancelLoadingAgents:h}=e;return(0,w.jsxs)(`div`,{className:`space-y-6`,children:[B({loadingSuggestions:t,suggestionsUnavailable:n,suggestions:r,onStartFromSuggestion:o}),(0,w.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,w.jsxs)(`div`,{className:`relative flex-1`,children:[(0,w.jsx)(ne,{className:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),(0,w.jsx)(y,{"aria-label":`Search agents`,placeholder:`Search your agents...`,value:s,onChange:e=>{c(e.target.value)},className:`pl-9 h-9 bg-muted/20`})]}),(0,w.jsx)(_,{variant:`outline`,size:`icon`,className:`h-9 w-9 shrink-0`,onClick:l,disabled:u,"aria-label":`Refresh agents`,children:(0,w.jsx)(a,{className:`size-4 ${u?`animate-spin`:``}`})}),(0,w.jsxs)(_,{size:`sm`,onClick:d,children:[(0,w.jsx)(i,{className:`size-4 mr-1.5`}),` New agent`]})]}),(0,w.jsx)(me,{className:`h-[calc(100vh-32rem)] min-h-[16rem] pr-2`,children:U({loadingAgents:u,agentsUnavailable:f,filteredAgents:p,onArchive:m,onCancelLoading:h})})]})}function W(e,t,n){return(0,w.jsxs)(`label`,{htmlFor:`compose-tool-${e.id}`,className:`flex items-center gap-2 px-2 py-1.5 rounded hover:bg-muted/20 cursor-pointer`,children:[(0,w.jsx)(g,{id:`compose-tool-${e.id}`,"aria-label":`Use ${e.name}${e.mcp_server?` from ${e.mcp_server}`:``}`,checked:t.has(e.id),onCheckedChange:n.bind(null,e.id)}),(0,w.jsx)(`span`,{className:`text-xs font-mono`,children:e.name}),e.mcp_server&&(0,w.jsx)(`span`,{className:`text-[10px] text-muted-foreground ml-auto`,children:e.mcp_server})]},e.id)}function G({loadingTools:e,toolsUnavailable:t,tools:n,selectedToolIds:r,onToggleTool:i}){return e?(0,w.jsx)(`div`,{className:`p-2`,children:(0,w.jsx)(S,{status:`loading`,label:`Loading tools...`,className:`text-xs`})}):t?(0,w.jsx)(`div`,{className:`p-2`,children:(0,w.jsx)(x,{what:`The tool catalog`})}):n.length===0?(0,w.jsx)(`div`,{className:`p-2`,children:(0,w.jsx)(S,{status:`empty`,label:`No tools ingested yet for this filter — the agent can still run prompt-only.`,className:`text-xs`})}):(0,w.jsx)(w.Fragment,{children:n.map(e=>W(e,r,i))})}function Fe(e){let{composeName:t,onComposeNameChange:n,composeDescription:r,onComposeDescriptionChange:i,composeInstructions:a,onComposeInstructionsChange:o,composeServer:s,onComposeServerChange:c,serverNames:l,composeModel:u,onComposeModelChange:d,chatModels:f,composing:p,onCompose:m}=e;return(0,w.jsxs)(`div`,{className:`max-w-2xl space-y-5`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-name`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Name`}),(0,w.jsx)(y,{id:`compose-agent-name`,required:!0,"aria-describedby":`compose-agent-name-help`,value:t,onChange:e=>{n(e.target.value)},placeholder:`e.g. release-notes-writer`,className:`mt-1 bg-muted/20`}),(0,w.jsx)(`p`,{id:`compose-agent-name-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Required. Up to 120 characters; leading and trailing whitespace is removed before saving.`})]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-description`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Description`}),(0,w.jsx)(y,{id:`compose-agent-description`,"aria-describedby":`compose-agent-description-help`,value:r,onChange:e=>{i(e.target.value)},placeholder:`One line: what does this agent do for you?`,className:`mt-1 bg-muted/20`}),(0,w.jsx)(`p`,{id:`compose-agent-description-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Optional one-line summary so you can recognize this agent later.`})]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-instructions`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Instructions (its system prompt)`}),(0,w.jsx)(v,{id:`compose-agent-instructions`,required:!0,maxLength:D,"aria-describedby":`compose-agent-instructions-help`,value:a,onChange:e=>{o(e.target.value)},placeholder:`You are a specialist that...`,className:`mt-1 bg-muted/20 font-mono text-xs leading-relaxed`,rows:8}),(0,w.jsx)(`p`,{id:`compose-agent-instructions-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Required. Describe the agent's role and how it should complete work (up to 32,000 UTF-8 bytes).`})]}),(0,w.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-server`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Bind an entire MCP server's tools (optional)`}),(0,w.jsxs)(`select`,{id:`compose-agent-server`,"aria-describedby":`compose-agent-server-help`,value:s,onChange:e=>{c(e.target.value)},className:`w-full h-9 mt-1 px-3 rounded-md border border-input bg-muted/20 text-xs`,children:[(0,w.jsx)(`option`,{value:``,children:`— none —`}),l.map(e=>(0,w.jsx)(`option`,{value:e,children:e},e))]}),(0,w.jsx)(`p`,{id:`compose-agent-server-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Optional. Select a server to make all of its tools available to this agent.`})]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-model`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Preferred model (optional, advisory)`}),(0,w.jsxs)(`select`,{id:`compose-agent-model`,"aria-describedby":`compose-agent-model-help`,value:u,onChange:e=>{d(e.target.value)},className:`w-full h-9 mt-1 px-3 rounded-md border border-input bg-muted/20 text-xs`,children:[(0,w.jsx)(`option`,{value:``,children:`— default —`}),f.map(e=>(0,w.jsxs)(`option`,{value:e.id,children:[e.id,` (`,e.provider,`)`]},e.id))]}),(0,w.jsx)(`p`,{id:`compose-agent-model-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Optional hint for delegation; the default model is used when this is left unchanged.`})]})]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`h3`,{id:`compose-agent-tools-label`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Or pick individual tools`}),(0,w.jsx)(`p`,{id:`compose-agent-tools-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Choose specific tools when you do not want to grant access to an entire server.`}),(0,w.jsx)(`div`,{role:`group`,"aria-labelledby":`compose-agent-tools-label`,"aria-describedby":`compose-agent-tools-help`,className:`mt-2 max-h-56 overflow-y-auto rounded-lg border border-border/20 bg-muted/5 p-2 space-y-1`,children:G(e)})]}),(0,w.jsx)(_,{onClick:m,disabled:p||!t.trim()||!a.trim(),className:`bg-emerald-600 hover:bg-emerald-700`,children:p?`Saving...`:`Save agent to the Library`})]})}function Ie({a2aUrl:e,onA2aUrlChange:t,a2aCardJson:n,onA2aCardJsonChange:r,registering:i,onRegister:a}){let o=j(e),s=A(n).error;return(0,w.jsxs)(`div`,{className:`max-w-2xl space-y-5`,children:[(0,w.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Register an outside agent that speaks the A2A protocol. Give its URL and, if it doesn't publish a discoverable agent card, paste the card JSON yourself. The URL is used to discover the agent; it is not a secret.`}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`external-agent-url`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Agent URL`}),(0,w.jsx)(y,{id:`external-agent-url`,type:`url`,required:!0,maxLength:O,"aria-describedby":M(`external-agent-url-help`,`external-agent-url-error`,o),"aria-invalid":!!o,value:e,onChange:e=>{t(e.target.value)},placeholder:`https://agent.example.com`,className:`mt-1 bg-muted/20 font-mono text-xs`}),(0,w.jsx)(`p`,{id:`external-agent-url-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Required. Use a complete http:// or https:// URL (up to 2,048 UTF-8 bytes).`}),N(`external-agent-url-error`,o)]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`external-agent-card-json`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Agent card JSON (optional — auto-fetched from the URL if left blank)`}),(0,w.jsx)(v,{id:`external-agent-card-json`,"aria-describedby":M(`external-agent-card-help`,`external-agent-card-error`,s),"aria-invalid":!!s,value:n,onChange:e=>{r(e.target.value)},placeholder:`{"name": "...", "description": "...", "capabilities": []}`,className:`mt-1 bg-muted/20 font-mono text-xs`,rows:8}),(0,w.jsx)(`p`,{id:`external-agent-card-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Optional. Leave blank to let the server fetch the card. If you paste one, it must be a non-empty JSON object.`}),N(`external-agent-card-error`,s)]}),(0,w.jsx)(_,{type:`button`,onClick:a,disabled:P(i,e,o,s),className:`bg-teal-600 hover:bg-teal-700`,children:i?`Registering...`:`Register external agent`})]})}function Le(e){return(0,w.jsxs)(`div`,{className:`p-3 rounded-lg border border-border/30 bg-muted/5 space-y-1.5`,children:[(0,w.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,w.jsx)(`span`,{className:`font-mono font-bold text-xs`,children:e.id}),(0,w.jsx)(s,{variant:`outline`,className:`text-[9px]`,children:e.provider})]}),(0,w.jsxs)(`div`,{className:`flex flex-wrap gap-1`,children:[e.intelligence_level&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:e.intelligence_level}),e.can_route&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`router`}),e.can_kg&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`kg`}),e.vision&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`vision`}),e.reasoning&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`reasoning`}),e.tools_enabled&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`tools`})]}),e.context_window?(0,w.jsxs)(`div`,{className:`text-[10px] text-muted-foreground`,children:[e.context_window.toLocaleString(),` token context`]}):null]},e.id)}function K({configUnavailable:e,chatModels:t}){return(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`h3`,{className:`text-xs font-bold uppercase tracking-wider text-muted-foreground mb-2`,children:`Chat models`}),e?null:t.length===0?(0,w.jsx)(S,{status:`empty`,label:`No chat models configured.`,className:`text-xs`}):(0,w.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-3`,children:t.map(Le)})]})}function q(e){return(0,w.jsxs)(`div`,{className:`p-3 rounded-lg border border-border/30 bg-muted/5 space-y-1`,children:[(0,w.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,w.jsx)(`span`,{className:`font-mono font-bold text-xs`,children:e.id}),(0,w.jsx)(s,{variant:`outline`,className:`text-[9px]`,children:e.provider})]}),(0,w.jsxs)(`div`,{className:`text-[10px] text-muted-foreground`,children:[`chunk `,e.chunk_size??`—`,e.context_window?` · ${e.context_window.toLocaleString()} token context`:``]})]},e.id)}function J({configUnavailable:e,embeddingModels:t}){return(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`h3`,{className:`text-xs font-bold uppercase tracking-wider text-muted-foreground mb-2`,children:`Embedding models`}),e?null:t.length===0?(0,w.jsx)(S,{status:`empty`,label:`No embedding models configured.`,className:`text-xs`}):(0,w.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-3`,children:t.map(q)})]})}function Re({loadingConfig:e,config:t,configUnavailable:n}){return e?(0,w.jsx)(`div`,{className:`space-y-6`,children:(0,w.jsx)(`div`,{className:`flex items-center justify-center py-12`,children:(0,w.jsx)(S,{status:`loading`,label:`Loading model configuration...`})})}):(0,w.jsxs)(`div`,{className:`space-y-6`,children:[(0,w.jsxs)(`div`,{className:`flex flex-wrap gap-4 text-xs`,children:[(0,w.jsxs)(`div`,{className:`rounded-md border border-border/30 bg-muted/10 px-3 py-2`,children:[(0,w.jsx)(`div`,{className:`text-muted-foreground`,children:`App profile`}),(0,w.jsx)(`div`,{className:`font-bold`,children:t.app_profile||`—`})]}),(0,w.jsxs)(`div`,{className:`rounded-md border border-border/30 bg-muted/10 px-3 py-2`,children:[(0,w.jsx)(`div`,{className:`text-muted-foreground`,children:`Deployment profile`}),(0,w.jsx)(`div`,{className:`font-bold`,children:t.deployment_profile||`—`})]})]}),n&&(0,w.jsx)(x,{what:`The model configuration summary`}),K({configUnavailable:n,chatModels:t.chat_models}),J({configUnavailable:n,embeddingModels:t.embedding_models}),(0,w.jsxs)(`p`,{className:`text-[11px] text-muted-foreground`,children:[`Read-only view of the active `,(0,w.jsx)(`code`,{children:`AgentConfig`}),` model registry. Secrets and provider credentials are never sent to the browser.`]})]})}function Y(){let[e,t]=(0,C.useState)(`library`),[n,a]=(0,C.useState)([]),[s,c]=(0,C.useState)(!0),[l,u]=(0,C.useState)(``),[f,p]=(0,C.useState)([]),[m,ee]=(0,C.useState)(!0),[te,ne]=(0,C.useState)(!1),[g,v]=(0,C.useState)([]),[y,ue]=(0,C.useState)(!1),[x,S]=(0,C.useState)(je),[me,be]=(0,C.useState)(!0),[xe,Ce]=(0,C.useState)(!1),[T,we]=(0,C.useState)(!1),[E,D]=(0,C.useState)(!1),[O,k]=(0,C.useState)(``),[A,j]=(0,C.useState)(``),[M,N]=(0,C.useState)(``),[P,F]=(0,C.useState)(``),[I,L]=(0,C.useState)(``),[R,z]=(0,C.useState)(new Set),[Me,B]=(0,C.useState)(!1),[H,U]=(0,C.useState)(``),[W,G]=(0,C.useState)(``),[Le,K]=(0,C.useState)(!1),q=(0,C.useRef)({sequence:{current:0},controller:{current:null}}),J=(0,C.useRef)({sequence:{current:0},controller:{current:null}}),Y=(0,C.useRef)({sequence:{current:0},controller:{current:null}}),ze=(0,C.useRef)({sequence:{current:0},controller:{current:null}}),X=(0,C.useRef)(0),Z=(0,C.useRef)(0),Q=async()=>{await V({refs:q.current,path:`/api/enhanced/agent-library/agents`,schema:d(_e),fallback:[],setData:a,setLoading:c,setUnavailable:Ce,onFailure:Ne})},Be=()=>{Te([q.current]),c(!1)},$=async()=>{await V({refs:J.current,path:`/api/enhanced/agent-library/suggestions`,schema:d(ye),fallback:[],setData:p,setLoading:ee,setUnavailable:ne})},Ve=async e=>{let t=e?`?mcp_server=${encodeURIComponent(e)}`:``;await V({refs:Y.current,path:`/api/enhanced/agent-library/tools${t}`,schema:d(ve),fallback:[],setData:v,setLoading:ue,setUnavailable:we})},He=async()=>{await V({refs:ze.current,path:`/api/enhanced/agent-library/config-summary`,schema:Se,fallback:je,setData:S,setLoading:be,setUnavailable:D})};(0,C.useEffect)(()=>(Q(),$(),Ve(),He(),Te.bind(null,[q.current,J.current,Y.current,ze.current])),[]);let Ue=(0,C.useMemo)(()=>{let e=new Set;for(let t of g)t.mcp_server&&e.add(t.mcp_server);return Array.from(e).sort()},[g]),We=e=>{z(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},Ge=e=>{X.current+=1,t(`compose`),F(e.mcp_server),k(t=>t||De(e.mcp_server)),j(t=>t||`Uses the ${e.mcp_server} tools: ${e.sample_tools.join(`, `)}.`),Ve(e.mcp_server),h.message(`Composing an agent for '${e.mcp_server}'`)},Ke=()=>{X.current+=1,t(`compose`)},qe=async()=>{let n=O.trim(),r=M.trim(),i=Ae(n,r);if(i){h.error(i);return}let a=X.current,o=e;B(!0);try{let i=await Oe(`/api/enhanced/agent-library/agents`,{name:n,description:A.trim(),instructions:r,bind_server:P||void 0,model_preference:I||void 0,tool_ids:Array.from(R)},`Failed to compose the agent`);if(!i.ok){h.error(i.error);return}h.success(`Agent '${n}' saved and ready to delegate to`),X.current===a&&e===o&&(k(``),j(``),N(``),F(``),L(``),z(new Set),t(`library`)),Q(),$()}catch{h.error(`Network error composing the agent`)}finally{B(!1)}},Je=async e=>{try{if(!(await fetch(`/api/enhanced/agent-library/agents/${encodeURIComponent(e.id)}`,{method:`DELETE`})).ok){h.error(`Failed to archive that agent`);return}h.success(`Archived '${e.name}'`),Q()}catch{h.error(`Network error archiving the agent`)}},Ye=async()=>{let t=ke(H,W);if(t.error){h.error(t.error);return}let n=Z.current,r=e;K(!0);try{let i=await Oe(`/api/enhanced/agent-library/a2a`,{url:t.url,agent_card:t.agentCard},`Failed to register that agent`);if(!i.ok){h.error(i.error);return}h.success(`External agent registered`),Z.current===n&&e===r&&(U(``),G(``)),Q()}catch{h.error(`Network error registering the external agent`)}finally{K(!1)}},Xe=n.filter(e=>e.name.toLowerCase().includes(l.toLowerCase())||e.description.toLowerCase().includes(l.toLowerCase())),Ze=[{id:`library`,label:`Library`,icon:le},{id:`compose`,label:`Compose an Agent`,icon:i},{id:`external`,label:`External Agents`,icon:ce},{id:`config`,label:`Model & Config`,icon:o}];return(0,w.jsx)(`div`,{className:`space-y-6`,children:(0,w.jsx)(ie,{className:`border-border/40 bg-card/60 backdrop-blur-md`,children:(0,w.jsxs)(pe,{value:e,onValueChange:n=>{let r=he(n)?n:e;ge(r,e,X,Z),t(r)},className:`w-full`,children:[(0,w.jsxs)(ae,{children:[(0,w.jsxs)(`div`,{className:`flex flex-col md:flex-row justify-between items-start md:items-center gap-4`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsx)(re,{className:`text-2xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-teal-400 via-emerald-400 to-green-500`,children:`Agent Library`}),(0,w.jsx)(oe,{children:`Compose agents from prompts and tools you already have, register outside A2A agents, and call on any of them whenever you need. Saved agents live in the knowledge graph, not in this browser.`})]}),(0,w.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,w.jsxs)(_,{variant:`outline`,size:`sm`,onClick:()=>{Ee(`/prompts`)},children:[`Prompts Registry `,(0,w.jsx)(r,{className:`size-3.5 ml-1.5`})]}),(0,w.jsxs)(_,{variant:`outline`,size:`sm`,onClick:()=>{Ee(`/skills`)},children:[`Tools & Skills `,(0,w.jsx)(r,{className:`size-3.5 ml-1.5`})]})]})]}),(0,w.jsx)(fe,{"aria-label":`Agent library sections`,className:`flex flex-wrap justify-start h-auto gap-2 mt-4 rounded-none border-b border-border/40 bg-transparent p-0 pb-2`,children:Ze.map(e=>(0,w.jsxs)(de,{value:e.id,className:`flex items-center gap-2 rounded-md border border-transparent px-3 py-1.5 text-xs font-semibold data-[state=active]:border-emerald-500/30 data-[state=active]:bg-emerald-500/10 data-[state=active]:font-bold data-[state=active]:text-emerald-400`,children:[(0,w.jsx)(e.icon,{className:`size-3.5`}),(0,w.jsx)(`span`,{children:e.label})]},e.id))})]}),(0,w.jsxs)(se,{children:[(0,w.jsx)(b,{value:`library`,children:Pe({loadingSuggestions:m,suggestionsUnavailable:te,suggestions:f,onStartFromSuggestion:Ge,search:l,onSearchChange:u,onRefresh:()=>{Q(),$()},loadingAgents:s,onNewAgent:Ke,agentsUnavailable:xe,filteredAgents:Xe,onArchive:e=>{Je(e)},onCancelLoadingAgents:Be})}),(0,w.jsx)(b,{value:`compose`,children:Fe({composeName:O,onComposeNameChange:e=>{X.current+=1,k(e)},composeDescription:A,onComposeDescriptionChange:e=>{X.current+=1,j(e)},composeInstructions:M,onComposeInstructionsChange:e=>{X.current+=1,N(e)},composeServer:P,onComposeServerChange:e=>{X.current+=1,F(e),Ve(e||void 0)},serverNames:Ue,composeModel:I,onComposeModelChange:e=>{X.current+=1,L(e)},chatModels:x.chat_models,loadingTools:y,toolsUnavailable:T,tools:g,selectedToolIds:R,onToggleTool:e=>{X.current+=1,We(e)},composing:Me,onCompose:()=>{qe()}})}),(0,w.jsx)(b,{value:`external`,children:Ie({a2aUrl:H,onA2aUrlChange:e=>{Z.current+=1,U(e)},a2aCardJson:W,onA2aCardJsonChange:e=>{Z.current+=1,G(e)},registering:Le,onRegister:()=>{Ye()}})}),(0,w.jsx)(b,{value:`config`,children:Re({loadingConfig:me,config:x,configUnavailable:E})})]})]})})})}export{Y as default};
|
|
1
|
+
import{i as e,r as t,s as n}from"./bundle-mjs-DIyOrgL5.js";import{t as r}from"./external-link-Dyd5OsGm.js";import{t as i}from"./plus-s20KYBeu.js";import{t as a}from"./refresh-cw-BVhl5aJX.js";import{t as o}from"./sparkles-Bae0tRI0.js";import{t as s}from"./badge-nQZ87mVE.js";import{E as c,S as l,c as u,d,f,i as p,x as m}from"./api-validation-CCoR_LRu.js";import{C as h,E as ee,En as te,O as ne,T as re,Yt as g,in as _,jt as v,k as ie,on as ae,pn as oe,pr as se,qn as ce,rn as y,sr as le,w as ue}from"./index-C2uiGu8Z.js";import{i as de,n as b,r as fe,t as pe}from"./tabs-aIrzMOIb.js";import{t as x}from"./unavailable-notice-B7WdWNor.js";import{t as S}from"./status-message-CFnPiTvw.js";import{t as me}from"./scroll-area-srEWz9Q3.js";var C=n(e()),w=t();function he(e){return e===`library`||e===`compose`||e===`external`||e===`config`}function ge(e,t,n,r){e!==t&&(n.current+=1,r.current+=1)}var _e=l({id:c().min(1),name:c().min(1),description:c(),kind:u([`local`,`a2a`]),mcp_server:c().nullable().optional(),model_preference:c().nullable().optional(),timestamp:c().nullable().optional(),status:c().optional(),runnable_bound:f().optional(),tools:d(l({id:c().optional(),name:c().optional()})).optional(),endpoint:c().nullable().optional()}),ve=l({id:c().min(1),name:c().min(1),mcp_server:c().nullable().optional(),tags:d(c())}),ye=l({mcp_server:c().min(1),tool_count:m().int().nonnegative(),sample_tools:d(c()),reason:c()}),be=l({id:c().min(1),provider:c().min(1),intelligence_level:c().optional(),vision:f().optional(),reasoning:f().optional(),tools_enabled:f().optional(),can_route:f().optional(),can_kg:f().optional(),context_window:m().int().positive().nullable().optional()}),xe=l({id:c().min(1),provider:c().min(1),chunk_size:m().int().positive().optional(),context_window:m().int().positive().nullable().optional()}),Se=l({app_profile:c(),deployment_profile:c(),chat_models:d(be),embedding_models:d(xe)});function Ce(e){e.controller.current?.abort();let t=new AbortController,n=e.sequence.current+1;return e.sequence.current=n,e.controller.current=t,{id:n,controller:t}}function T(e,t,n){return e.sequence.current===t&&e.controller.current===n&&!n.signal.aborted}function we(e){return e instanceof Error&&e.name===`AbortError`}function Te(e){for(let t of e)t.sequence.current+=1,t.controller.current?.abort(),t.controller.current=null}function Ee(e){window.history.pushState({},``,e),window.dispatchEvent(new Event(`history-state-changed`))}var E=120,D=32e3,O=2048;function k(e){let t=e.trim();if(!t)return`Enter the URL of the external agent`;if(I(t)>O)return`The URL must be 2,048 UTF-8 bytes or fewer`;try{let e=new URL(t);if(e.protocol!==`http:`&&e.protocol!==`https:`)return`Use an http:// or https:// URL`}catch{return`Enter a complete http:// or https:// URL`}return null}function A(e){if(!e.trim())return{value:void 0,error:null};try{let t=JSON.parse(e);return typeof t!=`object`||!t||Array.isArray(t)||Object.keys(t).length===0?{value:void 0,error:`Agent card JSON must be a non-empty JSON object`}:{value:t,error:null}}catch{return{value:void 0,error:`Enter valid JSON for the agent card`}}}function j(e){return e.trim()?k(e):null}function M(e,t,n){return n?`${e} ${t}`:e}function N(e,t){return t?(0,w.jsx)(`p`,{id:e,role:`alert`,className:`mt-1 text-[11px] text-red-400 font-medium`,children:t}):null}function P(e,t,n,r){return[e,!t.trim(),!!n,!!r].some(Boolean)}function De(e){return`${(e.replace(/[^A-Za-z0-9_.:-]/g,`-`).replace(/^[^A-Za-z0-9]+/,``)||`custom`).slice(0,114)}-agent`}function F(e){return Array.from(e).length}function I(e){return new TextEncoder().encode(e).byteLength}function L(){return null}async function Oe(e,t,n){let r=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});return r.ok?{ok:!0}:{ok:!1,error:(await r.json().catch(L))?.detail??n}}function ke(e,t){let n=e.trim(),r=n?k(e):`An agent URL is required`,i=A(t);return{url:n,agentCard:i.value,error:r??i.error}}function Ae(e,t){return!e||!t?`Name and instructions are required`:F(e)>E?`Agent name must be ${E} characters or fewer`:I(t)>D?`Instructions must be ${D.toLocaleString()} bytes or fewer`:null}var je={app_profile:``,deployment_profile:``,chat_models:[],embedding_models:[]};function R(){return(0,w.jsxs)(`div`,{className:`space-y-3`,children:[(0,w.jsxs)(`h3`,{className:`text-xs font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5`,children:[(0,w.jsx)(o,{className:`size-3.5 text-emerald-400`}),` Suggested, from what is installed`]}),(0,w.jsx)(x,{what:`Agent suggestions`})]})}function z(e,t){return(0,w.jsxs)(`div`,{className:`p-3.5 rounded-lg border border-emerald-500/20 bg-emerald-500/5 flex flex-col gap-2`,children:[(0,w.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,w.jsx)(`span`,{className:`font-bold text-sm text-foreground`,children:e.mcp_server}),(0,w.jsxs)(s,{variant:`secondary`,className:`text-[10px]`,children:[e.tool_count,` tool`,e.tool_count===1?``:`s`]})]}),(0,w.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:e.reason}),(0,w.jsxs)(y,{size:`sm`,variant:`outline`,className:`self-start h-7 text-xs`,onClick:t.bind(null,e),children:[(0,w.jsx)(i,{className:`size-3.5 mr-1`}),` Build this agent`]})]},e.mcp_server)}function Me(e,t){return e.length===0?null:(0,w.jsxs)(`div`,{className:`space-y-3`,children:[(0,w.jsxs)(`h3`,{className:`text-xs font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5`,children:[(0,w.jsx)(o,{className:`size-3.5 text-emerald-400`}),` Suggested, from what is installed`]}),(0,w.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-3`,children:e.slice(0,6).map(e=>z(e,t))})]})}function B({loadingSuggestions:e,suggestionsUnavailable:t,suggestions:n,onStartFromSuggestion:r}){return e?null:t?R():Me(n,r)}async function V({refs:e,path:t,schema:n,fallback:r,setData:i,setLoading:a,setUnavailable:o,onFailure:s}){let c=Ce(e);try{a(!0);let r=await p(t,n,{signal:c.controller.signal});if(!T(e,c.id,c.controller))return;i(r),o(!1)}catch(t){if(!T(e,c.id,c.controller)||we(t))return;i(r),o(!0),s?.()}finally{T(e,c.id,c.controller)&&a(!1)}}function Ne(){_.error(`Failed to connect to the Agent Library`)}function H({agent:e,onArchive:t}){return(0,w.jsxs)(`div`,{className:`p-4 rounded-xl border border-border/40 bg-muted/10 backdrop-blur-sm hover:border-emerald-500/30 transition-all flex flex-col justify-between`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsxs)(`div`,{className:`flex items-center justify-between gap-2 mb-2`,children:[(0,w.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[e.kind===`a2a`?(0,w.jsx)(ce,{className:`size-4 text-teal-400 shrink-0`}):(0,w.jsx)(se,{className:`size-4 text-emerald-400 shrink-0`}),(0,w.jsx)(`h4`,{className:`font-bold text-sm text-foreground truncate`,children:e.name})]}),(0,w.jsx)(s,{variant:`outline`,className:`text-[10px] font-semibold shrink-0 ${e.kind===`a2a`?`bg-teal-500/10 border-teal-500/30 text-teal-400`:`bg-emerald-500/10 border-emerald-500/30 text-emerald-400`}`,children:e.kind===`a2a`?`External · A2A`:`Local`})]}),(0,w.jsx)(`p`,{className:`text-xs text-muted-foreground leading-normal line-clamp-3`,children:e.description||`No description.`}),e.mcp_server&&(0,w.jsxs)(`div`,{className:`text-[10px] text-muted-foreground mt-2`,children:[(0,w.jsx)(ae,{className:`size-3 inline mr-1`}),`bound to `,(0,w.jsx)(`code`,{className:`font-mono`,children:e.mcp_server})]})]}),(0,w.jsxs)(`div`,{className:`mt-4 flex items-center justify-between border-t border-border/30 pt-3`,children:[(0,w.jsxs)(`div`,{className:`flex items-center gap-1 text-[10px] text-emerald-400 font-bold`,children:[(0,w.jsx)(le,{className:`size-3`}),e.runnable_bound===!1?`Prompt only`:`Delegatable`]}),(0,w.jsx)(`button`,{type:`button`,onClick:()=>{t(e)},className:`p-1.5 rounded text-muted-foreground hover:text-red-400 hover:bg-red-500/10 transition-all`,"aria-label":`Archive ${e.name}`,children:(0,w.jsx)(oe,{className:`size-3.5`})})]})]},e.id)}function U({loadingAgents:e,agentsUnavailable:t,filteredAgents:n,onArchive:r,onCancelLoading:i}){return e?(0,w.jsx)(`div`,{className:`flex justify-center py-12`,children:(0,w.jsx)(S,{status:`loading`,label:`Querying the graph...`,onCancel:i})}):t?(0,w.jsx)(`div`,{className:`text-center py-12`,children:(0,w.jsx)(x,{what:`The Agent Library`,className:`justify-center`})}):n.length===0?(0,w.jsx)(`div`,{className:`flex justify-center py-12`,children:(0,w.jsx)(S,{status:`empty`,label:`No agents yet. Compose one, or register an external A2A agent.`})}):(0,w.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:n.map(e=>H({agent:e,onArchive:r}))})}function Pe(e){let{loadingSuggestions:t,suggestionsUnavailable:n,suggestions:r,onStartFromSuggestion:o,search:s,onSearchChange:c,onRefresh:l,loadingAgents:u,onNewAgent:d,agentsUnavailable:f,filteredAgents:p,onArchive:m,onCancelLoadingAgents:h}=e;return(0,w.jsxs)(`div`,{className:`space-y-6`,children:[B({loadingSuggestions:t,suggestionsUnavailable:n,suggestions:r,onStartFromSuggestion:o}),(0,w.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,w.jsxs)(`div`,{className:`relative flex-1`,children:[(0,w.jsx)(te,{className:`absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground`}),(0,w.jsx)(g,{"aria-label":`Search agents`,placeholder:`Search your agents...`,value:s,onChange:e=>{c(e.target.value)},className:`pl-9 h-9 bg-muted/20`})]}),(0,w.jsx)(y,{variant:`outline`,size:`icon`,className:`h-9 w-9 shrink-0`,onClick:l,disabled:u,"aria-label":`Refresh agents`,children:(0,w.jsx)(a,{className:`size-4 ${u?`animate-spin`:``}`})}),(0,w.jsxs)(y,{size:`sm`,onClick:d,children:[(0,w.jsx)(i,{className:`size-4 mr-1.5`}),` New agent`]})]}),(0,w.jsx)(me,{className:`h-[calc(100vh-32rem)] min-h-[16rem] pr-2`,children:U({loadingAgents:u,agentsUnavailable:f,filteredAgents:p,onArchive:m,onCancelLoading:h})})]})}function W(e,t,n){return(0,w.jsxs)(`label`,{htmlFor:`compose-tool-${e.id}`,className:`flex items-center gap-2 px-2 py-1.5 rounded hover:bg-muted/20 cursor-pointer`,children:[(0,w.jsx)(h,{id:`compose-tool-${e.id}`,"aria-label":`Use ${e.name}${e.mcp_server?` from ${e.mcp_server}`:``}`,checked:t.has(e.id),onCheckedChange:n.bind(null,e.id)}),(0,w.jsx)(`span`,{className:`text-xs font-mono`,children:e.name}),e.mcp_server&&(0,w.jsx)(`span`,{className:`text-[10px] text-muted-foreground ml-auto`,children:e.mcp_server})]},e.id)}function G({loadingTools:e,toolsUnavailable:t,tools:n,selectedToolIds:r,onToggleTool:i}){return e?(0,w.jsx)(`div`,{className:`p-2`,children:(0,w.jsx)(S,{status:`loading`,label:`Loading tools...`,className:`text-xs`})}):t?(0,w.jsx)(`div`,{className:`p-2`,children:(0,w.jsx)(x,{what:`The tool catalog`})}):n.length===0?(0,w.jsx)(`div`,{className:`p-2`,children:(0,w.jsx)(S,{status:`empty`,label:`No tools ingested yet for this filter — the agent can still run prompt-only.`,className:`text-xs`})}):(0,w.jsx)(w.Fragment,{children:n.map(e=>W(e,r,i))})}function Fe(e){let{composeName:t,onComposeNameChange:n,composeDescription:r,onComposeDescriptionChange:i,composeInstructions:a,onComposeInstructionsChange:o,composeServer:s,onComposeServerChange:c,serverNames:l,composeModel:u,onComposeModelChange:d,chatModels:f,composing:p,onCompose:m}=e;return(0,w.jsxs)(`div`,{className:`max-w-2xl space-y-5`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-name`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Name`}),(0,w.jsx)(g,{id:`compose-agent-name`,required:!0,"aria-describedby":`compose-agent-name-help`,value:t,onChange:e=>{n(e.target.value)},placeholder:`e.g. release-notes-writer`,className:`mt-1 bg-muted/20`}),(0,w.jsx)(`p`,{id:`compose-agent-name-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Required. Up to 120 characters; leading and trailing whitespace is removed before saving.`})]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-description`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Description`}),(0,w.jsx)(g,{id:`compose-agent-description`,"aria-describedby":`compose-agent-description-help`,value:r,onChange:e=>{i(e.target.value)},placeholder:`One line: what does this agent do for you?`,className:`mt-1 bg-muted/20`}),(0,w.jsx)(`p`,{id:`compose-agent-description-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Optional one-line summary so you can recognize this agent later.`})]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-instructions`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Instructions (its system prompt)`}),(0,w.jsx)(v,{id:`compose-agent-instructions`,required:!0,maxLength:D,"aria-describedby":`compose-agent-instructions-help`,value:a,onChange:e=>{o(e.target.value)},placeholder:`You are a specialist that...`,className:`mt-1 bg-muted/20 font-mono text-xs leading-relaxed`,rows:8}),(0,w.jsx)(`p`,{id:`compose-agent-instructions-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Required. Describe the agent's role and how it should complete work (up to 32,000 UTF-8 bytes).`})]}),(0,w.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-server`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Bind an entire MCP server's tools (optional)`}),(0,w.jsxs)(`select`,{id:`compose-agent-server`,"aria-describedby":`compose-agent-server-help`,value:s,onChange:e=>{c(e.target.value)},className:`w-full h-9 mt-1 px-3 rounded-md border border-input bg-muted/20 text-xs`,children:[(0,w.jsx)(`option`,{value:``,children:`— none —`}),l.map(e=>(0,w.jsx)(`option`,{value:e,children:e},e))]}),(0,w.jsx)(`p`,{id:`compose-agent-server-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Optional. Select a server to make all of its tools available to this agent.`})]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`compose-agent-model`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Preferred model (optional, advisory)`}),(0,w.jsxs)(`select`,{id:`compose-agent-model`,"aria-describedby":`compose-agent-model-help`,value:u,onChange:e=>{d(e.target.value)},className:`w-full h-9 mt-1 px-3 rounded-md border border-input bg-muted/20 text-xs`,children:[(0,w.jsx)(`option`,{value:``,children:`— default —`}),f.map(e=>(0,w.jsxs)(`option`,{value:e.id,children:[e.id,` (`,e.provider,`)`]},e.id))]}),(0,w.jsx)(`p`,{id:`compose-agent-model-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Optional hint for delegation; the default model is used when this is left unchanged.`})]})]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`h3`,{id:`compose-agent-tools-label`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Or pick individual tools`}),(0,w.jsx)(`p`,{id:`compose-agent-tools-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Choose specific tools when you do not want to grant access to an entire server.`}),(0,w.jsx)(`div`,{role:`group`,"aria-labelledby":`compose-agent-tools-label`,"aria-describedby":`compose-agent-tools-help`,className:`mt-2 max-h-56 overflow-y-auto rounded-lg border border-border/20 bg-muted/5 p-2 space-y-1`,children:G(e)})]}),(0,w.jsx)(y,{onClick:m,disabled:p||!t.trim()||!a.trim(),className:`bg-emerald-600 hover:bg-emerald-700`,children:p?`Saving...`:`Save agent to the Library`})]})}function Ie({a2aUrl:e,onA2aUrlChange:t,a2aCardJson:n,onA2aCardJsonChange:r,registering:i,onRegister:a}){let o=j(e),s=A(n).error;return(0,w.jsxs)(`div`,{className:`max-w-2xl space-y-5`,children:[(0,w.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Register an outside agent that speaks the A2A protocol. Give its URL and, if it doesn't publish a discoverable agent card, paste the card JSON yourself. The URL is used to discover the agent; it is not a secret.`}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`external-agent-url`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Agent URL`}),(0,w.jsx)(g,{id:`external-agent-url`,type:`url`,required:!0,maxLength:O,"aria-describedby":M(`external-agent-url-help`,`external-agent-url-error`,o),"aria-invalid":!!o,value:e,onChange:e=>{t(e.target.value)},placeholder:`https://agent.example.com`,className:`mt-1 bg-muted/20 font-mono text-xs`}),(0,w.jsx)(`p`,{id:`external-agent-url-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Required. Use a complete http:// or https:// URL (up to 2,048 UTF-8 bytes).`}),N(`external-agent-url-error`,o)]}),(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`label`,{htmlFor:`external-agent-card-json`,className:`text-[10px] font-bold uppercase tracking-wider text-muted-foreground`,children:`Agent card JSON (optional — auto-fetched from the URL if left blank)`}),(0,w.jsx)(v,{id:`external-agent-card-json`,"aria-describedby":M(`external-agent-card-help`,`external-agent-card-error`,s),"aria-invalid":!!s,value:n,onChange:e=>{r(e.target.value)},placeholder:`{"name": "...", "description": "...", "capabilities": []}`,className:`mt-1 bg-muted/20 font-mono text-xs`,rows:8}),(0,w.jsx)(`p`,{id:`external-agent-card-help`,className:`mt-1 text-[11px] text-muted-foreground`,children:`Optional. Leave blank to let the server fetch the card. If you paste one, it must be a non-empty JSON object.`}),N(`external-agent-card-error`,s)]}),(0,w.jsx)(y,{type:`button`,onClick:a,disabled:P(i,e,o,s),className:`bg-teal-600 hover:bg-teal-700`,children:i?`Registering...`:`Register external agent`})]})}function Le(e){return(0,w.jsxs)(`div`,{className:`p-3 rounded-lg border border-border/30 bg-muted/5 space-y-1.5`,children:[(0,w.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,w.jsx)(`span`,{className:`font-mono font-bold text-xs`,children:e.id}),(0,w.jsx)(s,{variant:`outline`,className:`text-[9px]`,children:e.provider})]}),(0,w.jsxs)(`div`,{className:`flex flex-wrap gap-1`,children:[e.intelligence_level&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:e.intelligence_level}),e.can_route&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`router`}),e.can_kg&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`kg`}),e.vision&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`vision`}),e.reasoning&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`reasoning`}),e.tools_enabled&&(0,w.jsx)(s,{variant:`secondary`,className:`text-[9px]`,children:`tools`})]}),e.context_window?(0,w.jsxs)(`div`,{className:`text-[10px] text-muted-foreground`,children:[e.context_window.toLocaleString(),` token context`]}):null]},e.id)}function K({configUnavailable:e,chatModels:t}){return(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`h3`,{className:`text-xs font-bold uppercase tracking-wider text-muted-foreground mb-2`,children:`Chat models`}),e?null:t.length===0?(0,w.jsx)(S,{status:`empty`,label:`No chat models configured.`,className:`text-xs`}):(0,w.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-3`,children:t.map(Le)})]})}function q(e){return(0,w.jsxs)(`div`,{className:`p-3 rounded-lg border border-border/30 bg-muted/5 space-y-1`,children:[(0,w.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,w.jsx)(`span`,{className:`font-mono font-bold text-xs`,children:e.id}),(0,w.jsx)(s,{variant:`outline`,className:`text-[9px]`,children:e.provider})]}),(0,w.jsxs)(`div`,{className:`text-[10px] text-muted-foreground`,children:[`chunk `,e.chunk_size??`—`,e.context_window?` · ${e.context_window.toLocaleString()} token context`:``]})]},e.id)}function J({configUnavailable:e,embeddingModels:t}){return(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`h3`,{className:`text-xs font-bold uppercase tracking-wider text-muted-foreground mb-2`,children:`Embedding models`}),e?null:t.length===0?(0,w.jsx)(S,{status:`empty`,label:`No embedding models configured.`,className:`text-xs`}):(0,w.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-3`,children:t.map(q)})]})}function Re({loadingConfig:e,config:t,configUnavailable:n}){return e?(0,w.jsx)(`div`,{className:`space-y-6`,children:(0,w.jsx)(`div`,{className:`flex items-center justify-center py-12`,children:(0,w.jsx)(S,{status:`loading`,label:`Loading model configuration...`})})}):(0,w.jsxs)(`div`,{className:`space-y-6`,children:[(0,w.jsxs)(`div`,{className:`flex flex-wrap gap-4 text-xs`,children:[(0,w.jsxs)(`div`,{className:`rounded-md border border-border/30 bg-muted/10 px-3 py-2`,children:[(0,w.jsx)(`div`,{className:`text-muted-foreground`,children:`App profile`}),(0,w.jsx)(`div`,{className:`font-bold`,children:t.app_profile||`—`})]}),(0,w.jsxs)(`div`,{className:`rounded-md border border-border/30 bg-muted/10 px-3 py-2`,children:[(0,w.jsx)(`div`,{className:`text-muted-foreground`,children:`Deployment profile`}),(0,w.jsx)(`div`,{className:`font-bold`,children:t.deployment_profile||`—`})]})]}),n&&(0,w.jsx)(x,{what:`The model configuration summary`}),K({configUnavailable:n,chatModels:t.chat_models}),J({configUnavailable:n,embeddingModels:t.embedding_models}),(0,w.jsxs)(`p`,{className:`text-[11px] text-muted-foreground`,children:[`Read-only view of the active `,(0,w.jsx)(`code`,{children:`AgentConfig`}),` model registry. Secrets and provider credentials are never sent to the browser.`]})]})}function Y(){let[e,t]=(0,C.useState)(`library`),[n,a]=(0,C.useState)([]),[s,c]=(0,C.useState)(!0),[l,u]=(0,C.useState)(``),[f,p]=(0,C.useState)([]),[m,h]=(0,C.useState)(!0),[te,g]=(0,C.useState)(!1),[v,ae]=(0,C.useState)([]),[oe,le]=(0,C.useState)(!1),[x,S]=(0,C.useState)(je),[me,be]=(0,C.useState)(!0),[xe,Ce]=(0,C.useState)(!1),[T,we]=(0,C.useState)(!1),[E,D]=(0,C.useState)(!1),[O,k]=(0,C.useState)(``),[A,j]=(0,C.useState)(``),[M,N]=(0,C.useState)(``),[P,F]=(0,C.useState)(``),[I,L]=(0,C.useState)(``),[R,z]=(0,C.useState)(new Set),[Me,B]=(0,C.useState)(!1),[H,U]=(0,C.useState)(``),[W,G]=(0,C.useState)(``),[Le,K]=(0,C.useState)(!1),q=(0,C.useRef)({sequence:{current:0},controller:{current:null}}),J=(0,C.useRef)({sequence:{current:0},controller:{current:null}}),Y=(0,C.useRef)({sequence:{current:0},controller:{current:null}}),ze=(0,C.useRef)({sequence:{current:0},controller:{current:null}}),X=(0,C.useRef)(0),Z=(0,C.useRef)(0),Q=async()=>{await V({refs:q.current,path:`/api/enhanced/agent-library/agents`,schema:d(_e),fallback:[],setData:a,setLoading:c,setUnavailable:Ce,onFailure:Ne})},Be=()=>{Te([q.current]),c(!1)},Ve=async()=>{await V({refs:J.current,path:`/api/enhanced/agent-library/suggestions`,schema:d(ye),fallback:[],setData:p,setLoading:h,setUnavailable:g})},$=async e=>{let t=e?`?mcp_server=${encodeURIComponent(e)}`:``;await V({refs:Y.current,path:`/api/enhanced/agent-library/tools${t}`,schema:d(ve),fallback:[],setData:ae,setLoading:le,setUnavailable:we})},He=async()=>{await V({refs:ze.current,path:`/api/enhanced/agent-library/config-summary`,schema:Se,fallback:je,setData:S,setLoading:be,setUnavailable:D})};(0,C.useEffect)(()=>(Q(),Ve(),$(),He(),Te.bind(null,[q.current,J.current,Y.current,ze.current])),[]);let Ue=(0,C.useMemo)(()=>{let e=new Set;for(let t of v)t.mcp_server&&e.add(t.mcp_server);return Array.from(e).sort()},[v]),We=e=>{z(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},Ge=e=>{X.current+=1,t(`compose`),F(e.mcp_server),k(t=>t||De(e.mcp_server)),j(t=>t||`Uses the ${e.mcp_server} tools: ${e.sample_tools.join(`, `)}.`),$(e.mcp_server),_.message(`Composing an agent for '${e.mcp_server}'`)},Ke=()=>{X.current+=1,t(`compose`)},qe=async()=>{let n=O.trim(),r=M.trim(),i=Ae(n,r);if(i){_.error(i);return}let a=X.current,o=e;B(!0);try{let i=await Oe(`/api/enhanced/agent-library/agents`,{name:n,description:A.trim(),instructions:r,bind_server:P||void 0,model_preference:I||void 0,tool_ids:Array.from(R)},`Failed to compose the agent`);if(!i.ok){_.error(i.error);return}_.success(`Agent '${n}' saved and ready to delegate to`),X.current===a&&e===o&&(k(``),j(``),N(``),F(``),L(``),z(new Set),t(`library`)),Q(),Ve()}catch{_.error(`Network error composing the agent`)}finally{B(!1)}},Je=async e=>{try{if(!(await fetch(`/api/enhanced/agent-library/agents/${encodeURIComponent(e.id)}`,{method:`DELETE`})).ok){_.error(`Failed to archive that agent`);return}_.success(`Archived '${e.name}'`),Q()}catch{_.error(`Network error archiving the agent`)}},Ye=async()=>{let t=ke(H,W);if(t.error){_.error(t.error);return}let n=Z.current,r=e;K(!0);try{let i=await Oe(`/api/enhanced/agent-library/a2a`,{url:t.url,agent_card:t.agentCard},`Failed to register that agent`);if(!i.ok){_.error(i.error);return}_.success(`External agent registered`),Z.current===n&&e===r&&(U(``),G(``)),Q()}catch{_.error(`Network error registering the external agent`)}finally{K(!1)}},Xe=n.filter(e=>e.name.toLowerCase().includes(l.toLowerCase())||e.description.toLowerCase().includes(l.toLowerCase())),Ze=[{id:`library`,label:`Library`,icon:se},{id:`compose`,label:`Compose an Agent`,icon:i},{id:`external`,label:`External Agents`,icon:ce},{id:`config`,label:`Model & Config`,icon:o}];return(0,w.jsx)(`div`,{className:`space-y-6`,children:(0,w.jsx)(ue,{className:`border-border/40 bg-card/60 backdrop-blur-md`,children:(0,w.jsxs)(pe,{value:e,onValueChange:n=>{let r=he(n)?n:e;ge(r,e,X,Z),t(r)},className:`w-full`,children:[(0,w.jsxs)(ne,{children:[(0,w.jsxs)(`div`,{className:`flex flex-col md:flex-row justify-between items-start md:items-center gap-4`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsx)(ie,{className:`text-2xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-teal-400 via-emerald-400 to-green-500`,children:`Agent Library`}),(0,w.jsx)(ee,{children:`Compose agents from prompts and tools you already have, register outside A2A agents, and call on any of them whenever you need. Saved agents live in the knowledge graph, not in this browser.`})]}),(0,w.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,w.jsxs)(y,{variant:`outline`,size:`sm`,onClick:()=>{Ee(`/prompts`)},children:[`Prompts Registry `,(0,w.jsx)(r,{className:`size-3.5 ml-1.5`})]}),(0,w.jsxs)(y,{variant:`outline`,size:`sm`,onClick:()=>{Ee(`/skills`)},children:[`Tools & Skills `,(0,w.jsx)(r,{className:`size-3.5 ml-1.5`})]})]})]}),(0,w.jsx)(fe,{"aria-label":`Agent library sections`,className:`flex flex-wrap justify-start h-auto gap-2 mt-4 rounded-none border-b border-border/40 bg-transparent p-0 pb-2`,children:Ze.map(e=>(0,w.jsxs)(de,{value:e.id,className:`flex items-center gap-2 rounded-md border border-transparent px-3 py-1.5 text-xs font-semibold data-[state=active]:border-emerald-500/30 data-[state=active]:bg-emerald-500/10 data-[state=active]:font-bold data-[state=active]:text-emerald-400`,children:[(0,w.jsx)(e.icon,{className:`size-3.5`}),(0,w.jsx)(`span`,{children:e.label})]},e.id))})]}),(0,w.jsxs)(re,{children:[(0,w.jsx)(b,{value:`library`,children:Pe({loadingSuggestions:m,suggestionsUnavailable:te,suggestions:f,onStartFromSuggestion:Ge,search:l,onSearchChange:u,onRefresh:()=>{Q(),Ve()},loadingAgents:s,onNewAgent:Ke,agentsUnavailable:xe,filteredAgents:Xe,onArchive:e=>{Je(e)},onCancelLoadingAgents:Be})}),(0,w.jsx)(b,{value:`compose`,children:Fe({composeName:O,onComposeNameChange:e=>{X.current+=1,k(e)},composeDescription:A,onComposeDescriptionChange:e=>{X.current+=1,j(e)},composeInstructions:M,onComposeInstructionsChange:e=>{X.current+=1,N(e)},composeServer:P,onComposeServerChange:e=>{X.current+=1,F(e),$(e||void 0)},serverNames:Ue,composeModel:I,onComposeModelChange:e=>{X.current+=1,L(e)},chatModels:x.chat_models,loadingTools:oe,toolsUnavailable:T,tools:v,selectedToolIds:R,onToggleTool:e=>{X.current+=1,We(e)},composing:Me,onCompose:()=>{qe()}})}),(0,w.jsx)(b,{value:`external`,children:Ie({a2aUrl:H,onA2aUrlChange:e=>{Z.current+=1,U(e)},a2aCardJson:W,onA2aCardJsonChange:e=>{Z.current+=1,G(e)},registering:Le,onRegister:()=>{Ye()}})}),(0,w.jsx)(b,{value:`config`,children:Re({loadingConfig:me,config:x,configUnavailable:E})})]})]})})})}export{Y as default};
|