agim-cli 1.2.152 → 1.2.153
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/web/public/assets/{a2a-DZL1sgVk.js → a2a-CIxNaIdE.js} +2 -2
- package/dist/web/public/assets/{a2a-DZL1sgVk.js.map → a2a-CIxNaIdE.js.map} +1 -1
- package/dist/web/public/assets/{activity-BsCuSHQd.js → activity-CrnWHC2j.js} +2 -2
- package/dist/web/public/assets/{activity-BsCuSHQd.js.map → activity-CrnWHC2j.js.map} +1 -1
- package/dist/web/public/assets/{admins-CyG_mVaa.js → admins-5BTRCU9u.js} +2 -2
- package/dist/web/public/assets/{admins-CyG_mVaa.js.map → admins-5BTRCU9u.js.map} +1 -1
- package/dist/web/public/assets/{agents-D2wSzcVZ.js → agents-B-s9gngh.js} +2 -2
- package/dist/web/public/assets/{agents-D2wSzcVZ.js.map → agents-B-s9gngh.js.map} +1 -1
- package/dist/web/public/assets/{approvals-C3uNQTdL.js → approvals-BSX2lsqu.js} +2 -2
- package/dist/web/public/assets/{approvals-C3uNQTdL.js.map → approvals-BSX2lsqu.js.map} +1 -1
- package/dist/web/public/assets/{arrow-down-CppegASc.js → arrow-down-D3lWOftw.js} +2 -2
- package/dist/web/public/assets/{arrow-down-CppegASc.js.map → arrow-down-D3lWOftw.js.map} +1 -1
- package/dist/web/public/assets/{arrow-up-8NH41ZQX.js → arrow-up-BGsin7FN.js} +2 -2
- package/dist/web/public/assets/{arrow-up-8NH41ZQX.js.map → arrow-up-BGsin7FN.js.map} +1 -1
- package/dist/web/public/assets/{asks-DiT_eq2x.js → asks-DfLaW3gA.js} +2 -2
- package/dist/web/public/assets/{asks-DiT_eq2x.js.map → asks-DfLaW3gA.js.map} +1 -1
- package/dist/web/public/assets/{audit-0T4jT2G0.js → audit-BWlwMCTk.js} +2 -2
- package/dist/web/public/assets/{audit-0T4jT2G0.js.map → audit-BWlwMCTk.js.map} +1 -1
- package/dist/web/public/assets/{bell-BoZsoN58.js → bell-Bf-FDztO.js} +2 -2
- package/dist/web/public/assets/{bell-BoZsoN58.js.map → bell-Bf-FDztO.js.map} +1 -1
- package/dist/web/public/assets/{bgjobs-DbHdPyhE.js → bgjobs-6dDxfEi7.js} +2 -2
- package/dist/web/public/assets/{bgjobs-DbHdPyhE.js.map → bgjobs-6dDxfEi7.js.map} +1 -1
- package/dist/web/public/assets/{brain-D-zbPJ7o.js → brain-Dl0NIztX.js} +2 -2
- package/dist/web/public/assets/{brain-D-zbPJ7o.js.map → brain-Dl0NIztX.js.map} +1 -1
- package/dist/web/public/assets/{briefcase-D3jWpfeB.js → briefcase-Bl6rZAmJ.js} +2 -2
- package/dist/web/public/assets/{briefcase-D3jWpfeB.js.map → briefcase-Bl6rZAmJ.js.map} +1 -1
- package/dist/web/public/assets/{chat-DrYeCiFH.js → chat-Cu8-EeJt.js} +2 -2
- package/dist/web/public/assets/{chat-DrYeCiFH.js.map → chat-Cu8-EeJt.js.map} +1 -1
- package/dist/web/public/assets/{chevron-left-D6-MKmUs.js → chevron-left-BtG3MZQX.js} +2 -2
- package/dist/web/public/assets/{chevron-left-D6-MKmUs.js.map → chevron-left-BtG3MZQX.js.map} +1 -1
- package/dist/web/public/assets/{chevron-right-CHtA6f0-.js → chevron-right-FytmF5Sd.js} +2 -2
- package/dist/web/public/assets/{chevron-right-CHtA6f0-.js.map → chevron-right-FytmF5Sd.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-B9adx56J.js → circle-check-DggvG9Xs.js} +2 -2
- package/dist/web/public/assets/{circle-check-B9adx56J.js.map → circle-check-DggvG9Xs.js.map} +1 -1
- package/dist/web/public/assets/{circle-check-big-E1qhYcsu.js → circle-check-big-J5lVPTDz.js} +2 -2
- package/dist/web/public/assets/{circle-check-big-E1qhYcsu.js.map → circle-check-big-J5lVPTDz.js.map} +1 -1
- package/dist/web/public/assets/{circle-x-xB2tQMGw.js → circle-x-pYYyY1z2.js} +2 -2
- package/dist/web/public/assets/{circle-x-xB2tQMGw.js.map → circle-x-pYYyY1z2.js.map} +1 -1
- package/dist/web/public/assets/{clock-DFU9E0F0.js → clock-CQy6p5uP.js} +2 -2
- package/dist/web/public/assets/{clock-DFU9E0F0.js.map → clock-CQy6p5uP.js.map} +1 -1
- package/dist/web/public/assets/{confirm-dialog-C1w1040N.js → confirm-dialog-B3jno5Pb.js} +2 -2
- package/dist/web/public/assets/{confirm-dialog-C1w1040N.js.map → confirm-dialog-B3jno5Pb.js.map} +1 -1
- package/dist/web/public/assets/{copy-UOTkO-2l.js → copy-BK_JexVU.js} +2 -2
- package/dist/web/public/assets/{copy-UOTkO-2l.js.map → copy-BK_JexVU.js.map} +1 -1
- package/dist/web/public/assets/{data-table-CBTDQyFx.js → data-table-C3oIPQ_B.js} +2 -2
- package/dist/web/public/assets/{data-table-CBTDQyFx.js.map → data-table-C3oIPQ_B.js.map} +1 -1
- package/dist/web/public/assets/dialog-nb4ANHd4.js +2 -0
- package/dist/web/public/assets/dialog-nb4ANHd4.js.map +1 -0
- package/dist/web/public/assets/{download-BzDp4OCu.js → download-DtvF6Ngb.js} +2 -2
- package/dist/web/public/assets/{download-BzDp4OCu.js.map → download-DtvF6Ngb.js.map} +1 -1
- package/dist/web/public/assets/{email-BDd0tUm1.js → email-6PldVxPe.js} +2 -2
- package/dist/web/public/assets/{email-BDd0tUm1.js.map → email-6PldVxPe.js.map} +1 -1
- package/dist/web/public/assets/{empty-state-CKPzKsI5.js → empty-state-esNZG4Xa.js} +2 -2
- package/dist/web/public/assets/{empty-state-CKPzKsI5.js.map → empty-state-esNZG4Xa.js.map} +1 -1
- package/dist/web/public/assets/{external-link-Cx0ulEkb.js → external-link-Bzl-4lM6.js} +2 -2
- package/dist/web/public/assets/{external-link-Cx0ulEkb.js.map → external-link-Bzl-4lM6.js.map} +1 -1
- package/dist/web/public/assets/{eye-D9PD2xVj.js → eye-Cpc4c8vR.js} +2 -2
- package/dist/web/public/assets/{eye-D9PD2xVj.js.map → eye-Cpc4c8vR.js.map} +1 -1
- package/dist/web/public/assets/{facts-CRpGEODt.js → facts-CAc-sdKE.js} +2 -2
- package/dist/web/public/assets/{facts-CRpGEODt.js.map → facts-CAc-sdKE.js.map} +1 -1
- package/dist/web/public/assets/{goals-pyF71sFT.js → goals-iarR52LZ.js} +2 -2
- package/dist/web/public/assets/{goals-pyF71sFT.js.map → goals-iarR52LZ.js.map} +1 -1
- package/dist/web/public/assets/{health-_YLm7LIW.js → health-DPiNRwJP.js} +2 -2
- package/dist/web/public/assets/{health-_YLm7LIW.js.map → health-DPiNRwJP.js.map} +1 -1
- package/dist/web/public/assets/{heart-pulse-DyxG9jqH.js → heart-pulse-DTcvh4ER.js} +2 -2
- package/dist/web/public/assets/{heart-pulse-DyxG9jqH.js.map → heart-pulse-DTcvh4ER.js.map} +1 -1
- package/dist/web/public/assets/{heartbeat-bZfXp6Vm.js → heartbeat-B8tcKFzJ.js} +2 -2
- package/dist/web/public/assets/{heartbeat-bZfXp6Vm.js.map → heartbeat-B8tcKFzJ.js.map} +1 -1
- package/dist/web/public/assets/{hot-CSwCgYXw.js → hot-CqLT7AGh.js} +2 -2
- package/dist/web/public/assets/{hot-CSwCgYXw.js.map → hot-CqLT7AGh.js.map} +1 -1
- package/dist/web/public/assets/{index-D5DvetP5.js → index-BjUyDXLb.js} +30 -30
- package/dist/web/public/assets/index-BjUyDXLb.js.map +1 -0
- package/dist/web/public/assets/{injection-CYjttllI.js → injection-U1ms-Jjs.js} +2 -2
- package/dist/web/public/assets/{injection-CYjttllI.js.map → injection-U1ms-Jjs.js.map} +1 -1
- package/dist/web/public/assets/{installed-C6eNPXLl.js → installed-8FN6LLKG.js} +2 -2
- package/dist/web/public/assets/{installed-C6eNPXLl.js.map → installed-8FN6LLKG.js.map} +1 -1
- package/dist/web/public/assets/{jobs-CKQvijeH.js → jobs-B-MU_dkD.js} +2 -2
- package/dist/web/public/assets/{jobs-CKQvijeH.js.map → jobs-B-MU_dkD.js.map} +1 -1
- package/dist/web/public/assets/{layout-2S0YMTH_.js → layout-BVI4tkRG.js} +2 -2
- package/dist/web/public/assets/{layout-2S0YMTH_.js.map → layout-BVI4tkRG.js.map} +1 -1
- package/dist/web/public/assets/{layout-C9vch6up.js → layout-BgmJrSOb.js} +2 -2
- package/dist/web/public/assets/{layout-C9vch6up.js.map → layout-BgmJrSOb.js.map} +1 -1
- package/dist/web/public/assets/{layout-BQGP-bci.js → layout-CnddsqFT.js} +2 -2
- package/dist/web/public/assets/{layout-BQGP-bci.js.map → layout-CnddsqFT.js.map} +1 -1
- package/dist/web/public/assets/{layout-Y4GA9SyV.js → layout-DMOpWAPw.js} +2 -2
- package/dist/web/public/assets/{layout-Y4GA9SyV.js.map → layout-DMOpWAPw.js.map} +1 -1
- package/dist/web/public/assets/{layout-C4RTH7Mc.js → layout-DfE74Z47.js} +2 -2
- package/dist/web/public/assets/{layout-C4RTH7Mc.js.map → layout-DfE74Z47.js.map} +1 -1
- package/dist/web/public/assets/{llm-CJvopUnt.js → llm-5HpT83y2.js} +2 -2
- package/dist/web/public/assets/{llm-CJvopUnt.js.map → llm-5HpT83y2.js.map} +1 -1
- package/dist/web/public/assets/{loader-circle-CgLbYd3g.js → loader-circle-MnTMknNl.js} +2 -2
- package/dist/web/public/assets/{loader-circle-CgLbYd3g.js.map → loader-circle-MnTMknNl.js.map} +1 -1
- package/dist/web/public/assets/{map-pin-CdHDC52F.js → map-pin-BA0GTiIe.js} +2 -2
- package/dist/web/public/assets/{map-pin-CdHDC52F.js.map → map-pin-BA0GTiIe.js.map} +1 -1
- package/dist/web/public/assets/{mcp-SI73JwZR.js → mcp-C71xI5JH.js} +2 -2
- package/dist/web/public/assets/{mcp-SI73JwZR.js.map → mcp-C71xI5JH.js.map} +1 -1
- package/dist/web/public/assets/memos-BAuv2jwD.js +12 -0
- package/dist/web/public/assets/memos-BAuv2jwD.js.map +1 -0
- package/dist/web/public/assets/{messengers-CUz9DXB5.js → messengers-CmW1ts2s.js} +2 -2
- package/dist/web/public/assets/{messengers-CUz9DXB5.js.map → messengers-CmW1ts2s.js.map} +1 -1
- package/dist/web/public/assets/{mobile-CrdzyGXr.js → mobile-DpxLpRIf.js} +2 -2
- package/dist/web/public/assets/{mobile-CrdzyGXr.js.map → mobile-DpxLpRIf.js.map} +1 -1
- package/dist/web/public/assets/{native-agent-g8BpqzAo.js → native-agent-CNUBixLm.js} +2 -2
- package/dist/web/public/assets/{native-agent-g8BpqzAo.js.map → native-agent-CNUBixLm.js.map} +1 -1
- package/dist/web/public/assets/{network-DcpeRx8a.js → network-DVRgX5Mm.js} +2 -2
- package/dist/web/public/assets/{network-DcpeRx8a.js.map → network-DVRgX5Mm.js.map} +1 -1
- package/dist/web/public/assets/{outbox-uR6crgVJ.js → outbox-C8Gc0aa0.js} +2 -2
- package/dist/web/public/assets/{outbox-uR6crgVJ.js.map → outbox-C8Gc0aa0.js.map} +1 -1
- package/dist/web/public/assets/{pagination-CxK3lTYb.js → pagination-BWgXaluu.js} +2 -2
- package/dist/web/public/assets/{pagination-CxK3lTYb.js.map → pagination-BWgXaluu.js.map} +1 -1
- package/dist/web/public/assets/{persona-B1k5tc4U.js → persona--zQXx4oA.js} +2 -2
- package/dist/web/public/assets/{persona-B1k5tc4U.js.map → persona--zQXx4oA.js.map} +1 -1
- package/dist/web/public/assets/{plans-BWQSahSt.js → plans-mluEj2nt.js} +2 -2
- package/dist/web/public/assets/{plans-BWQSahSt.js.map → plans-mluEj2nt.js.map} +1 -1
- package/dist/web/public/assets/{play-D2VxB3QN.js → play-BLIwYTvQ.js} +2 -2
- package/dist/web/public/assets/{play-D2VxB3QN.js.map → play-BLIwYTvQ.js.map} +1 -1
- package/dist/web/public/assets/{plus-_XZVk5F_.js → plus-BOfhZkjh.js} +2 -2
- package/dist/web/public/assets/{plus-_XZVk5F_.js.map → plus-BOfhZkjh.js.map} +1 -1
- package/dist/web/public/assets/{policy-D77IdVzS.js → policy-C8CPYuH5.js} +2 -2
- package/dist/web/public/assets/{policy-D77IdVzS.js.map → policy-C8CPYuH5.js.map} +1 -1
- package/dist/web/public/assets/{qr-code-glvcd_3g.js → qr-code-CfdRXZZD.js} +2 -2
- package/dist/web/public/assets/{qr-code-glvcd_3g.js.map → qr-code-CfdRXZZD.js.map} +1 -1
- package/dist/web/public/assets/{refresh-ccw-MfejQvU6.js → refresh-ccw--XT-lrCo.js} +2 -2
- package/dist/web/public/assets/{refresh-ccw-MfejQvU6.js.map → refresh-ccw--XT-lrCo.js.map} +1 -1
- package/dist/web/public/assets/{reminders-CtKa3ECr.js → reminders-DJkMBSTZ.js} +2 -2
- package/dist/web/public/assets/{reminders-CtKa3ECr.js.map → reminders-DJkMBSTZ.js.map} +1 -1
- package/dist/web/public/assets/{save-Cha8EnUJ.js → save-9sLkRauh.js} +2 -2
- package/dist/web/public/assets/{save-Cha8EnUJ.js.map → save-9sLkRauh.js.map} +1 -1
- package/dist/web/public/assets/{schedules-CuQgG6hz.js → schedules-BEqyQYLb.js} +2 -2
- package/dist/web/public/assets/{schedules-CuQgG6hz.js.map → schedules-BEqyQYLb.js.map} +1 -1
- package/dist/web/public/assets/{search-BpyL8Spy.js → search-D4CzBwIp.js} +2 -2
- package/dist/web/public/assets/{search-BpyL8Spy.js.map → search-D4CzBwIp.js.map} +1 -1
- package/dist/web/public/assets/{search-BJqFnKP5.js → search-aWQWrzh3.js} +2 -2
- package/dist/web/public/assets/{search-BJqFnKP5.js.map → search-aWQWrzh3.js.map} +1 -1
- package/dist/web/public/assets/{security-Cw_yJiDX.js → security-B7KXMgM3.js} +2 -2
- package/dist/web/public/assets/{security-Cw_yJiDX.js.map → security-B7KXMgM3.js.map} +1 -1
- package/dist/web/public/assets/{service-CgSHzzZ2.js → service-1ZeT0cRY.js} +2 -2
- package/dist/web/public/assets/{service-CgSHzzZ2.js.map → service-1ZeT0cRY.js.map} +1 -1
- package/dist/web/public/assets/{shield-alert-C_TX7BBD.js → shield-alert-BJKgUDEG.js} +2 -2
- package/dist/web/public/assets/{shield-alert-C_TX7BBD.js.map → shield-alert-BJKgUDEG.js.map} +1 -1
- package/dist/web/public/assets/{status-badge-CLMCkv6R.js → status-badge-DJgvgFQk.js} +2 -2
- package/dist/web/public/assets/{status-badge-CLMCkv6R.js.map → status-badge-DJgvgFQk.js.map} +1 -1
- package/dist/web/public/assets/{subtasks-BpXUesU9.js → subtasks-Cq0R4U6Z.js} +2 -2
- package/dist/web/public/assets/{subtasks-BpXUesU9.js.map → subtasks-Cq0R4U6Z.js.map} +1 -1
- package/dist/web/public/assets/{table-B-dheE8t.js → table-CVYTRwUs.js} +2 -2
- package/dist/web/public/assets/{table-B-dheE8t.js.map → table-CVYTRwUs.js.map} +1 -1
- package/dist/web/public/assets/{topn-CIXROr87.js → topn--vv790Oy.js} +2 -2
- package/dist/web/public/assets/{topn-CIXROr87.js.map → topn--vv790Oy.js.map} +1 -1
- package/dist/web/public/assets/{trash-2-CiJPCsGG.js → trash-2-CeN2btBl.js} +2 -2
- package/dist/web/public/assets/{trash-2-CiJPCsGG.js.map → trash-2-CeN2btBl.js.map} +1 -1
- package/dist/web/public/assets/{use-agim-skills-DDOG9Vno.js → use-agim-skills-D5JvyrxB.js} +2 -2
- package/dist/web/public/assets/{use-agim-skills-DDOG9Vno.js.map → use-agim-skills-D5JvyrxB.js.map} +1 -1
- package/dist/web/public/assets/{use-background-tasks-BT6BkFMM.js → use-background-tasks-C6zGANI5.js} +2 -2
- package/dist/web/public/assets/{use-background-tasks-BT6BkFMM.js.map → use-background-tasks-C6zGANI5.js.map} +1 -1
- package/dist/web/public/assets/{use-llm-admin-C5QwblGu.js → use-llm-admin-CdqRAs0I.js} +2 -2
- package/dist/web/public/assets/{use-llm-admin-C5QwblGu.js.map → use-llm-admin-CdqRAs0I.js.map} +1 -1
- package/dist/web/public/assets/{use-memory-BaQLelYY.js → use-memory-Bg-C6FxV.js} +2 -2
- package/dist/web/public/assets/{use-memory-BaQLelYY.js.map → use-memory-Bg-C6FxV.js.map} +1 -1
- package/dist/web/public/assets/{use-observability-DiJjq_81.js → use-observability-CiyMLYeG.js} +2 -2
- package/dist/web/public/assets/{use-observability-DiJjq_81.js.map → use-observability-CiyMLYeG.js.map} +1 -1
- package/dist/web/public/assets/{use-settings-CTuwZEdY.js → use-settings-S6mSC9nP.js} +2 -2
- package/dist/web/public/assets/{use-settings-CTuwZEdY.js.map → use-settings-S6mSC9nP.js.map} +1 -1
- package/dist/web/public/assets/{use-workspace-42B5n8Aa.js → use-workspace-DRkCOO8P.js} +2 -2
- package/dist/web/public/assets/{use-workspace-42B5n8Aa.js.map → use-workspace-DRkCOO8P.js.map} +1 -1
- package/dist/web/public/assets/{useQuery-BLyYPRRA.js → useQuery-CvEVNuvH.js} +2 -2
- package/dist/web/public/assets/{useQuery-BLyYPRRA.js.map → useQuery-CvEVNuvH.js.map} +1 -1
- package/dist/web/public/assets/{vector-BlyEjpL_.js → vector-BlXq3jJE.js} +2 -2
- package/dist/web/public/assets/{vector-BlyEjpL_.js.map → vector-BlXq3jJE.js.map} +1 -1
- package/dist/web/public/assets/{viewer-nKB1rvkV.js → viewer-Daxh0dV4.js} +2 -2
- package/dist/web/public/assets/{viewer-nKB1rvkV.js.map → viewer-Daxh0dV4.js.map} +1 -1
- package/dist/web/public/assets/{workspace-C5xO2uoT.js → workspace-BO51vrkT.js} +2 -2
- package/dist/web/public/assets/{workspace-C5xO2uoT.js.map → workspace-BO51vrkT.js.map} +1 -1
- package/dist/web/public/assets/{workspaces-BncBOneY.js → workspaces-Chonjr-v.js} +2 -2
- package/dist/web/public/assets/{workspaces-BncBOneY.js.map → workspaces-Chonjr-v.js.map} +1 -1
- package/dist/web/public/assets/{x-De6HR8Q5.js → x-Dv1gbRhw.js} +2 -2
- package/dist/web/public/assets/{x-De6HR8Q5.js.map → x-Dv1gbRhw.js.map} +1 -1
- package/dist/web/public/index.html +1 -1
- package/dist/web/server.d.ts +2 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +11 -1
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/web/public/assets/dialog-CqBNfrYQ.js +0 -6
- package/dist/web/public/assets/dialog-CqBNfrYQ.js.map +0 -1
- package/dist/web/public/assets/index-D5DvetP5.js.map +0 -1
- package/dist/web/public/assets/memos-B-5cdUp2.js +0 -12
- package/dist/web/public/assets/memos-B-5cdUp2.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as a,j as e,T as i,N as r,c as n,O as m}from"./index-
|
|
2
|
-
//# sourceMappingURL=layout-
|
|
1
|
+
import{u as a,j as e,T as i,N as r,c as n,O as m}from"./index-BjUyDXLb.js";import"./react-DlP5eolq.js";const u=[{to:"messengers",i18nKey:"tabs.messengers",mounted:!0},{to:"email",i18nKey:"tabs.email",mounted:!0},{to:"viewer",i18nKey:"tabs.viewer",mounted:!0},{to:"agents",i18nKey:"tabs.agents",mounted:!0},{to:"llm",i18nKey:"tabs.llm",mounted:!0},{to:"mcp",i18nKey:"tabs.mcp",mounted:!0},{to:"native-agent",i18nKey:"tabs.nativeAgent",mounted:!0},{to:"search",i18nKey:"tabs.search",mounted:!0},{to:"mobile",i18nKey:"tabs.mobile",mounted:!0},{to:"agim-skills",i18nKey:"tabs.agimSkills",mounted:!0},{to:"policy",i18nKey:"tabs.policy",mounted:!0},{to:"security",i18nKey:"tabs.security",mounted:!0},{to:"workspaces",i18nKey:"tabs.workspaces",mounted:!0},{to:"admins",i18nKey:"tabs.admins",mounted:!0},{to:"service",i18nKey:"tabs.service",mounted:!0}];function d(){const{t:s}=a("settings");return e.jsxs("div",{className:"flex min-h-dvh flex-col bg-bg",children:[e.jsx(i,{}),e.jsx("nav",{className:n("sticky top-0 z-10","flex items-center gap-1","border-b border-border bg-surface","px-3 sm:px-4 py-1","overflow-x-auto"),"aria-label":s("pageTitle"),children:u.filter(t=>t.mounted).map(t=>e.jsx(r,{to:t.to,className:({isActive:o})=>n("shrink-0 rounded-md px-3 py-1.5 text-sm no-underline","transition-colors tap-target",o?"bg-accent-bg text-accent font-medium":"text-text-dim hover:bg-surface-hover hover:text-text"),children:s(t.i18nKey)},t.to))}),e.jsx("main",{className:"flex-1 px-3 sm:px-4 py-4 pb-safe",children:e.jsx(m,{})})]})}export{d as default};
|
|
2
|
+
//# sourceMappingURL=layout-CnddsqFT.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-
|
|
1
|
+
{"version":3,"file":"layout-CnddsqFT.js","sources":["../../src/routes/settings/layout.tsx"],"sourcesContent":["/**\n * /settings — layout shell with sub-tab nav (environment / service).\n *\n * Workspaces / WeChat QR / Admin allowlist will land as additional\n * sub-tabs in PR-19b/c. The `mounted` flag gates their nav links.\n */\n\nimport { NavLink, Outlet } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Topbar } from '@/components/shell/topbar'\nimport { cn } from '@/lib/utils'\n\ninterface SubTab {\n to: string\n i18nKey: string\n mounted: boolean\n}\n\nconst SUB_TABS: SubTab[] = [\n { to: 'messengers', i18nKey: 'tabs.messengers', mounted: true },\n { to: 'email', i18nKey: 'tabs.email', mounted: true },\n { to: 'viewer', i18nKey: 'tabs.viewer', mounted: true },\n { to: 'agents', i18nKey: 'tabs.agents', mounted: true },\n // Stage 6 — native LLM stack. Three tabs in a logical group:\n // LLM backends (config + secrets) -> MCP external servers ->\n // native agent / evaluator / heartbeat behavior knobs.\n { to: 'llm', i18nKey: 'tabs.llm', mounted: true },\n { to: 'mcp', i18nKey: 'tabs.mcp', mounted: true },\n { to: 'native-agent', i18nKey: 'tabs.nativeAgent', mounted: true },\n // v1.2.126 — web_search provider chain + per-provider keys.\n { to: 'search', i18nKey: 'tabs.search', mounted: true },\n // v1.2.129 — mobile QR generator (open /m/chat from a phone).\n { to: 'mobile', i18nKey: 'tabs.mobile', mounted: true },\n // P1 follow-up — agim SKILL.md editor.\n { to: 'agim-skills', i18nKey: 'tabs.agimSkills', mounted: true },\n { to: 'policy', i18nKey: 'tabs.policy', mounted: true },\n { to: 'security', i18nKey: 'tabs.security', mounted: true },\n { to: 'workspaces', i18nKey: 'tabs.workspaces', mounted: true },\n { to: 'admins', i18nKey: 'tabs.admins', mounted: true },\n // R13 follow-up — /settings/env catch-all editor removed; raw env-var\n // editing belongs in `~/.agim/env` on the host, not in a web form.\n { to: 'service', i18nKey: 'tabs.service', mounted: true },\n]\n\nexport default function SettingsLayout(): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <div className=\"flex min-h-dvh flex-col bg-bg\">\n <Topbar />\n\n <nav\n className={cn(\n 'sticky top-0 z-10',\n 'flex items-center gap-1',\n 'border-b border-border bg-surface',\n 'px-3 sm:px-4 py-1',\n 'overflow-x-auto',\n )}\n aria-label={t('pageTitle')}\n >\n {SUB_TABS.filter((tab) => tab.mounted).map((tab) => (\n <NavLink\n key={tab.to}\n to={tab.to}\n className={({ isActive }) =>\n cn(\n 'shrink-0 rounded-md px-3 py-1.5 text-sm no-underline',\n 'transition-colors tap-target',\n isActive\n ? 'bg-accent-bg text-accent font-medium'\n : 'text-text-dim hover:bg-surface-hover hover:text-text',\n )\n }\n >\n {t(tab.i18nKey)}\n </NavLink>\n ))}\n </nav>\n\n <main className=\"flex-1 px-3 sm:px-4 py-4 pb-safe\">\n <Outlet />\n </main>\n </div>\n )\n}\n"],"names":["SUB_TABS","SettingsLayout","t","useTranslation","jsxs","jsx","Topbar","cn","tab","NavLink","isActive","Outlet"],"mappings":"uGAkBA,MAAMA,EAAqB,CACzB,CAAE,GAAI,aAAgB,QAAS,kBAAqB,QAAS,EAAA,EAC7D,CAAE,GAAI,QAAgB,QAAS,aAAqB,QAAS,EAAA,EAC7D,CAAE,GAAI,SAAgB,QAAS,cAAqB,QAAS,EAAA,EAC7D,CAAE,GAAI,SAAgB,QAAS,cAAqB,QAAS,EAAA,EAI7D,CAAE,GAAI,MAAgB,QAAS,WAAqB,QAAS,EAAA,EAC7D,CAAE,GAAI,MAAgB,QAAS,WAAqB,QAAS,EAAA,EAC7D,CAAE,GAAI,eAAgB,QAAS,mBAAqB,QAAS,EAAA,EAE7D,CAAE,GAAI,SAAgB,QAAS,cAAqB,QAAS,EAAA,EAE7D,CAAE,GAAI,SAAgB,QAAS,cAAqB,QAAS,EAAA,EAE7D,CAAE,GAAI,cAAgB,QAAS,kBAAqB,QAAS,EAAA,EAC7D,CAAE,GAAI,SAAgB,QAAS,cAAqB,QAAS,EAAA,EAC7D,CAAE,GAAI,WAAgB,QAAS,gBAAqB,QAAS,EAAA,EAC7D,CAAE,GAAI,aAAgB,QAAS,kBAAqB,QAAS,EAAA,EAC7D,CAAE,GAAI,SAAgB,QAAS,cAAqB,QAAS,EAAA,EAG7D,CAAE,GAAI,UAAgB,QAAS,eAAqB,QAAS,EAAA,CAC/D,EAEA,SAAwBC,GAA8B,CACpD,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAe,UAAU,EACvC,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,gCACb,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAO,EAERD,EAAAA,IAAC,MAAA,CACC,UAAWE,EACT,oBACA,0BACA,oCACA,oBACA,iBAAA,EAEF,aAAYL,EAAE,WAAW,EAExB,SAAAF,EAAS,OAAQQ,GAAQA,EAAI,OAAO,EAAE,IAAKA,GAC1CH,EAAAA,IAACI,EAAA,CAEC,GAAID,EAAI,GACR,UAAW,CAAC,CAAE,SAAAE,CAAA,IACZH,EACE,uDACA,+BACAG,EACI,uCACA,sDAAA,EAIP,SAAAR,EAAEM,EAAI,OAAO,CAAA,EAZTA,EAAI,EAAA,CAcZ,CAAA,CAAA,QAGF,OAAA,CAAK,UAAU,mCACd,SAAAH,EAAAA,IAACM,IAAO,CAAA,CACV,CAAA,EACF,CAEJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as n,j as t,N as o,c as s,O as l}from"./index-
|
|
2
|
-
//# sourceMappingURL=layout-
|
|
1
|
+
import{u as n,j as t,N as o,c as s,O as l}from"./index-BjUyDXLb.js";import"./react-DlP5eolq.js";const r=[{to:"installed",i18nKey:"agimSkills.tab.installed"},{to:"hot",i18nKey:"agimSkills.tab.hot"},{to:"injection",i18nKey:"agimSkills.tab.injection"}];function c(){const{t:i}=n(["settings"]);return t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsx("nav",{className:s("flex items-center gap-1","border-b border-border","-mx-3 sm:-mx-4 px-3 sm:px-4 pb-2","overflow-x-auto"),"aria-label":i("agimSkills.title"),children:r.map(e=>t.jsx(o,{to:e.to,className:({isActive:a})=>s("shrink-0 rounded-md px-3 py-1.5 text-sm no-underline","transition-colors tap-target",a?"bg-accent-bg text-accent font-medium":"text-text-dim hover:bg-surface-hover hover:text-text"),children:i(e.i18nKey)},e.to))}),t.jsx(l,{})]})}export{c as default};
|
|
2
|
+
//# sourceMappingURL=layout-DMOpWAPw.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-
|
|
1
|
+
{"version":3,"file":"layout-DMOpWAPw.js","sources":["../../src/routes/settings/agim-skills/layout.tsx"],"sourcesContent":["/**\n * /settings/agim-skills — combined skill management.\n *\n * 2026-05 consolidation: the v2 SPA briefly had two skill entry points\n * (top-level /skills + this settings route) which duplicated 95% of\n * the data after multi-root scanning landed. We merged both flows here:\n *\n * installed — agim's own loader view; CRUD against the writable\n * workspace dir, read-only for builtins and skills\n * inherited from ~/.claude/skills + opencode + codex.\n * hot — skillhub.cn 热门 (moved from /skills/hot).\n *\n * Old URLs under /skills still resolve via redirects in router.tsx\n * so bookmarks keep working.\n */\n\nimport { NavLink, Outlet } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { cn } from '@/lib/utils'\n\ninterface SubTab {\n to: string\n i18nKey: string\n}\n\nconst SUB_TABS: SubTab[] = [\n { to: 'installed', i18nKey: 'agimSkills.tab.installed' },\n { to: 'hot', i18nKey: 'agimSkills.tab.hot' },\n // v1.2.151 — system-prompt skill block editor (operator override).\n { to: 'injection', i18nKey: 'agimSkills.tab.injection' },\n]\n\nexport default function SettingsAgimSkillsLayout(): JSX.Element {\n const { t } = useTranslation(['settings'])\n return (\n <div className=\"flex flex-col gap-4\">\n <nav\n className={cn(\n 'flex items-center gap-1',\n 'border-b border-border',\n '-mx-3 sm:-mx-4 px-3 sm:px-4 pb-2',\n 'overflow-x-auto',\n )}\n aria-label={t('agimSkills.title')}\n >\n {SUB_TABS.map((tab) => (\n <NavLink\n key={tab.to}\n to={tab.to}\n className={({ isActive }) =>\n cn(\n 'shrink-0 rounded-md px-3 py-1.5 text-sm no-underline',\n 'transition-colors tap-target',\n isActive\n ? 'bg-accent-bg text-accent font-medium'\n : 'text-text-dim hover:bg-surface-hover hover:text-text',\n )\n }\n >\n {t(tab.i18nKey)}\n </NavLink>\n ))}\n </nav>\n <Outlet />\n </div>\n )\n}\n"],"names":["SUB_TABS","SettingsAgimSkillsLayout","t","useTranslation","jsxs","jsx","cn","tab","NavLink","isActive","Outlet"],"mappings":"gGAyBA,MAAMA,EAAqB,CACzB,CAAE,GAAI,YAAa,QAAS,0BAAA,EAC5B,CAAE,GAAI,MAAa,QAAS,oBAAA,EAE5B,CAAE,GAAI,YAAa,QAAS,0BAAA,CAC9B,EAEA,SAAwBC,GAAwC,CAC9D,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAe,CAAC,UAAU,CAAC,EACzC,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACb,SAAA,CAAAC,EAAAA,IAAC,MAAA,CACC,UAAWC,EACT,0BACA,yBACA,mCACA,iBAAA,EAEF,aAAYJ,EAAE,kBAAkB,EAE/B,SAAAF,EAAS,IAAKO,GACbF,EAAAA,IAACG,EAAA,CAEC,GAAID,EAAI,GACR,UAAW,CAAC,CAAE,SAAAE,CAAA,IACZH,EACE,uDACA,+BACAG,EACI,uCACA,sDAAA,EAIP,SAAAP,EAAEK,EAAI,OAAO,CAAA,EAZTA,EAAI,EAAA,CAcZ,CAAA,CAAA,QAEFG,EAAA,CAAA,CAAO,CAAA,EACV,CAEJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as c,e as x,j as e,T as d,S as m,f as p,g as u,h,i as b,N as g,c as n,O as y}from"./index-
|
|
2
|
-
//# sourceMappingURL=layout-
|
|
1
|
+
import{u as c,e as x,j as e,T as d,S as m,f as p,g as u,h,i as b,N as g,c as n,O as y}from"./index-BjUyDXLb.js";import"./react-DlP5eolq.js";const f=[{to:"health",i18nKey:"tabs.health"},{to:"topn",i18nKey:"tabs.topn"},{to:"audit",i18nKey:"tabs.audit"}],j=[1,7,30,90];function N(){const{t}=c("observability"),[r,i]=x(),l=Math.max(1,Number(r.get("days"))||7);function o(s){const a=new URLSearchParams(r);s===7?a.delete("days"):a.set("days",String(s)),i(a,{replace:!0})}return e.jsxs("div",{className:"flex min-h-dvh flex-col bg-bg",children:[e.jsx(d,{}),e.jsx("div",{className:"border-b border-border bg-surface px-3 sm:px-4 py-2",children:e.jsxs("div",{className:"mx-auto flex max-w-7xl items-center gap-3",children:[e.jsx("span",{className:"text-sm text-text-dim shrink-0",children:t("window.label")}),e.jsxs(m,{value:String(l),onValueChange:s=>o(Number(s)),children:[e.jsx(p,{className:"w-32",children:e.jsx(u,{})}),e.jsx(h,{children:j.map(s=>e.jsx(b,{value:String(s),children:t("window.days",{count:s})},s))})]})]})}),e.jsx("nav",{className:n("sticky top-0 z-10","flex items-center gap-1","border-b border-border bg-surface","px-3 sm:px-4 py-1","overflow-x-auto"),"aria-label":t("pageTitle"),children:f.map(s=>e.jsx(g,{to:s.to,className:({isActive:a})=>n("shrink-0 rounded-md px-3 py-1.5 text-sm no-underline","transition-colors tap-target",a?"bg-accent-bg text-accent font-medium":"text-text-dim hover:bg-surface-hover hover:text-text"),children:t(s.i18nKey)},s.to))}),e.jsx("main",{className:"flex-1 px-3 sm:px-4 py-4 pb-safe",children:e.jsx(y,{})})]})}export{N as default};
|
|
2
|
+
//# sourceMappingURL=layout-DfE74Z47.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-
|
|
1
|
+
{"version":3,"file":"layout-DfE74Z47.js","sources":["../../src/routes/observability/layout.tsx"],"sourcesContent":["/**\n * /observability — layout shell with sub-tab nav (health / topn /\n * audit) + a global time-window selector that every sub-tab reads\n * via useSearchParams (?days=).\n */\n\nimport { NavLink, Outlet, useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Topbar } from '@/components/shell/topbar'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { cn } from '@/lib/utils'\n\nconst SUB_TABS = [\n { to: 'health', i18nKey: 'tabs.health' },\n { to: 'topn', i18nKey: 'tabs.topn' },\n { to: 'audit', i18nKey: 'tabs.audit' },\n]\n\nconst DAY_WINDOWS = [1, 7, 30, 90]\n\nexport default function ObservabilityLayout(): JSX.Element {\n const { t } = useTranslation('observability')\n const [params, setParams] = useSearchParams()\n const days = Math.max(1, Number(params.get('days')) || 7)\n\n function setDays(next: number): void {\n const p = new URLSearchParams(params)\n if (next === 7) p.delete('days')\n else p.set('days', String(next))\n setParams(p, { replace: true })\n }\n\n return (\n <div className=\"flex min-h-dvh flex-col bg-bg\">\n <Topbar />\n\n <div className=\"border-b border-border bg-surface px-3 sm:px-4 py-2\">\n <div className=\"mx-auto flex max-w-7xl items-center gap-3\">\n <span className=\"text-sm text-text-dim shrink-0\">{t('window.label')}</span>\n <Select value={String(days)} onValueChange={(v) => setDays(Number(v))}>\n <SelectTrigger className=\"w-32\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DAY_WINDOWS.map((n) => (\n <SelectItem key={n} value={String(n)}>\n {t('window.days', { count: n })}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <nav\n className={cn(\n 'sticky top-0 z-10',\n 'flex items-center gap-1',\n 'border-b border-border bg-surface',\n 'px-3 sm:px-4 py-1',\n 'overflow-x-auto',\n )}\n aria-label={t('pageTitle')}\n >\n {SUB_TABS.map((tab) => (\n <NavLink\n key={tab.to}\n to={tab.to}\n className={({ isActive }) =>\n cn(\n 'shrink-0 rounded-md px-3 py-1.5 text-sm no-underline',\n 'transition-colors tap-target',\n isActive\n ? 'bg-accent-bg text-accent font-medium'\n : 'text-text-dim hover:bg-surface-hover hover:text-text',\n )\n }\n >\n {t(tab.i18nKey)}\n </NavLink>\n ))}\n </nav>\n\n <main className=\"flex-1 px-3 sm:px-4 py-4 pb-safe\">\n <Outlet />\n </main>\n </div>\n )\n}\n"],"names":["SUB_TABS","DAY_WINDOWS","ObservabilityLayout","useTranslation","params","setParams","useSearchParams","days","setDays","next","p","jsxs","jsx","Topbar","Select","v","SelectTrigger","SelectValue","SelectContent","n","SelectItem","cn","tab","NavLink","isActive","Outlet"],"mappings":"4IAkBA,MAAMA,EAAW,CACf,CAAE,GAAI,SAAU,QAAS,aAAA,EACzB,CAAE,GAAI,OAAU,QAAS,WAAA,EACzB,CAAE,GAAI,QAAU,QAAS,YAAA,CAC3B,EAEMC,EAAc,CAAC,EAAG,EAAG,GAAI,EAAE,EAEjC,SAAwBC,GAAmC,CACzD,KAAM,CAAE,CAAA,EAAMC,EAAe,eAAe,EACtC,CAACC,EAAQC,CAAS,EAAIC,EAAA,EACtBC,EAAO,KAAK,IAAI,EAAG,OAAOH,EAAO,IAAI,MAAM,CAAC,GAAK,CAAC,EAExD,SAASI,EAAQC,EAAoB,CACnC,MAAMC,EAAI,IAAI,gBAAgBN,CAAM,EAChCK,IAAS,EAAGC,EAAE,OAAO,MAAM,EAC1BA,EAAE,IAAI,OAAQ,OAAOD,CAAI,CAAC,EAC/BJ,EAAUK,EAAG,CAAE,QAAS,EAAA,CAAM,CAChC,CAEA,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,gCACb,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAO,QAEP,MAAA,CAAI,UAAU,sDACb,SAAAF,EAAAA,KAAC,MAAA,CAAI,UAAU,4CACb,SAAA,CAAAC,MAAC,OAAA,CAAK,UAAU,iCAAkC,SAAA,EAAE,cAAc,EAAE,EACpED,EAAAA,KAACG,EAAA,CAAO,MAAO,OAAOP,CAAI,EAAG,cAAgBQ,GAAMP,EAAQ,OAAOO,CAAC,CAAC,EAClE,SAAA,CAAAH,MAACI,EAAA,CAAc,UAAU,OACvB,SAAAJ,MAACK,IAAY,EACf,EACAL,MAACM,GACE,SAAAjB,EAAY,IAAKkB,GAChBP,EAAAA,IAACQ,GAAmB,MAAO,OAAOD,CAAC,EAChC,SAAA,EAAE,cAAe,CAAE,MAAOA,EAAG,CAAA,EADfA,CAEjB,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,EAEAP,EAAAA,IAAC,MAAA,CACC,UAAWS,EACT,oBACA,0BACA,oCACA,oBACA,iBAAA,EAEF,aAAY,EAAE,WAAW,EAExB,SAAArB,EAAS,IAAKsB,GACbV,EAAAA,IAACW,EAAA,CAEC,GAAID,EAAI,GACR,UAAW,CAAC,CAAE,SAAAE,CAAA,IACZH,EACE,uDACA,+BACAG,EACI,uCACA,sDAAA,EAIP,SAAA,EAAEF,EAAI,OAAO,CAAA,EAZTA,EAAI,EAAA,CAcZ,CAAA,CAAA,QAGF,OAAA,CAAK,UAAU,mCACd,SAAAV,EAAAA,IAACa,IAAO,CAAA,CACV,CAAA,EACF,CAEJ"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{n as I,u as k,j as e,B as y,k as T,L as f,S as L,f as B,g as H,h as E,i as R,I as N,l as m}from"./index-
|
|
1
|
+
import{n as I,u as k,j as e,B as y,k as T,L as f,S as L,f as B,g as H,h as E,i as R,I as N,l as m}from"./index-BjUyDXLb.js";import{r as b}from"./react-DlP5eolq.js";import{T as _,a as $,b as U,c as j,d as z,e as g}from"./table-CVYTRwUs.js";import{u as q,a as F,b as M,c as O,d as V}from"./use-llm-admin-CdqRAs0I.js";import{L as K}from"./loader-circle-MnTMknNl.js";import{R as D}from"./refresh-ccw--XT-lrCo.js";import{T as W}from"./trash-2-CeN2btBl.js";import{P as Z}from"./plus-BOfhZkjh.js";import"./useQuery-CvEVNuvH.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/const Q=I("Zap",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]]),Y=["cheap","evaluator","native-chat"],P="__unbind__",w=["deepseek","moonshot","zhipu","openai","anthropic","custom"],v=[{provider:"openai-compat",baseUrl:"https://api.deepseek.com/v1",modelHint:"deepseek-chat"},{provider:"openai-compat",baseUrl:"https://api.moonshot.cn/v1",modelHint:"moonshot-v1-8k"},{provider:"openai-compat",baseUrl:"https://open.bigmodel.cn/api/paas/v4",modelHint:"glm-4-air"},{provider:"openai-compat",baseUrl:"https://api.openai.com/v1",modelHint:"gpt-4o-mini"},{provider:"anthropic",baseUrl:"https://api.anthropic.com",modelHint:"claude-3-5-sonnet-20241022"},{provider:"openai-compat",baseUrl:"",modelHint:""}];function ce(){const{t:a}=k(["settings","common"]),s=q();return e.jsxs("div",{className:"mx-auto flex max-w-5xl flex-col gap-6",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:a("llm.title")}),e.jsxs(y,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void s.refetch(),disabled:s.isFetching,"aria-label":a("actions.refresh",{ns:"common"}),children:[s.isFetching?e.jsx(K,{className:"h-4 w-4 animate-spin"}):e.jsx(D,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:a("llm.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:a("llm.subtitle")}),s.isLoading?e.jsx("div",{className:"h-64 rounded-md bg-surface-2 animate-pulse"}):e.jsxs(e.Fragment,{children:[e.jsx(G,{data:s.data}),e.jsx(J,{data:s.data}),e.jsx(X,{})]})]})}function G({data:a}){const{t:s}=k(["settings","common"]),x=F(),p=M(),[i,h]=b.useState({});async function r(t){if(confirm(s("llm.removeConfirm",{name:t})))try{const l=await x.mutateAsync(t);m.success(s("llm.removedToast",{count:l.removedRoles}))}catch(l){m.error(l?.message??String(l))}}async function o(t){h(l=>({...l,[t]:s("llm.pinging")}));try{const l=await p.mutateAsync(t),u=l.ok?`✓ ${l.durationMs}ms · tokens ${l.tokensIn}→${l.tokensOut}`:`✗ ${l.error}`;h(S=>({...S,[t]:u}))}catch(l){h(u=>({...u,[t]:`✗ ${l?.message??String(l)}`}))}}const d=a?.backends??[];return d.length===0?e.jsx("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:s("llm.backendsEmpty")}):e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsx("header",{className:"border-b border-border px-4 py-3",children:e.jsx("h2",{className:"text-sm font-semibold",children:s("llm.backendsTitle",{count:d.length})})}),e.jsxs(_,{children:[e.jsx($,{children:e.jsxs(U,{children:[e.jsx(j,{children:s("llm.col.name")}),e.jsx(j,{children:s("llm.col.provider")}),e.jsx(j,{children:s("llm.col.model")}),e.jsx(j,{children:s("llm.col.baseUrl")}),e.jsx(j,{children:s("llm.col.apiKey")}),e.jsx(j,{children:s("llm.col.actions")})]})}),e.jsx(z,{children:d.map(t=>{const l=t.secret.source==="none"?e.jsx(T,{variant:"outline",children:s("llm.secretMissing")}):e.jsx(T,{variant:"success",children:t.secret.source});return e.jsxs(U,{children:[e.jsx(g,{className:"font-mono text-xs",children:t.name}),e.jsx(g,{children:t.provider}),e.jsx(g,{className:"font-mono text-xs",children:t.model}),e.jsx(g,{className:"break-all font-mono text-[11px] text-text-dim",children:t.baseUrl??"—"}),e.jsx(g,{children:l}),e.jsxs(g,{className:"flex flex-col gap-1 sm:flex-row sm:items-center",children:[e.jsxs(y,{variant:"ghost",size:"sm",onClick:()=>void o(t.name),disabled:p.isPending||t.secret.source==="none",title:t.secret.source==="none"?s("llm.setKeyFirst"):s("llm.pingHint"),children:[e.jsx(Q,{className:"h-4 w-4"}),e.jsx("span",{children:s("llm.ping")})]}),e.jsxs(y,{variant:"ghost",size:"sm",onClick:()=>void r(t.name),disabled:x.isPending,className:"text-danger hover:text-danger",children:[e.jsx(W,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("llm.remove")})]}),i[t.name]&&e.jsx("span",{className:"ml-2 text-[11px] text-text-dim",children:i[t.name]})]})]},t.name)})})]})]})}function J({data:a}){const{t:s}=k(["settings","common"]),x=O(),p=(a?.backends??[]).map(r=>r.name),i=a?.roles??{};async function h(r,o){const d={[r]:o===P?null:o};try{await x.mutateAsync(d),m.success(s("llm.roleUpdated",{role:r}))}catch(t){m.error(t?.message??String(t))}}return e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsx("header",{className:"border-b border-border px-4 py-3",children:e.jsx("h2",{className:"text-sm font-semibold",children:s("llm.rolesTitle")})}),e.jsx("div",{className:"grid grid-cols-1 gap-3 p-4 sm:grid-cols-3",children:Y.map(r=>e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(f,{className:"text-xs font-medium",children:r}),e.jsxs(L,{value:i[r]??P,onValueChange:o=>void h(r,o),disabled:p.length===0||x.isPending,children:[e.jsx(B,{className:"font-mono text-xs",children:e.jsx(H,{placeholder:s("llm.unset")})}),e.jsxs(E,{children:[e.jsx(R,{value:P,children:s("llm.unbound")}),p.map(o=>e.jsx(R,{value:o,children:o},o))]})]}),e.jsx("p",{className:"text-[11px] text-text-dim",children:s(`llm.roleHint.${r}`)})]},r))})]})}function X(){const{t:a}=k(["settings","common"]),s=V(),[x,p]=b.useState(0),[i,h]=b.useState(""),[r,o]=b.useState(v[0]?.baseUrl??""),[d,t]=b.useState(v[0]?.modelHint??""),[l,u]=b.useState("");function S(n){p(n);const c=v[n];c&&(o(c.baseUrl),t(c.modelHint))}async function A(n){n.preventDefault();const c=v[x];if(!c){m.error(a("llm.invalidPreset"));return}if(!i.trim()){m.error(a("llm.nameRequired"));return}if(!r.trim()){m.error(a("llm.baseUrlRequired"));return}if(!d.trim()){m.error(a("llm.modelRequired"));return}try{await s.mutateAsync({name:i.trim(),provider:c.provider,baseUrl:r.trim(),model:d.trim(),...l.trim()?{apiKey:l.trim()}:{}}),m.success(l.trim()?a("llm.addedWithKey",{name:i.trim()}):a("llm.addedNoKey",{name:i.trim()})),h(""),u("")}catch(C){m.error(C?.message??String(C))}}return e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsx("header",{className:"border-b border-border px-4 py-3",children:e.jsx("h2",{className:"text-sm font-semibold",children:a("llm.addTitle")})}),e.jsxs("form",{onSubmit:n=>void A(n),className:"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(f,{className:"text-xs font-medium",children:a("llm.preset")}),e.jsxs(L,{value:String(x),onValueChange:n=>S(Number(n)),children:[e.jsx(B,{children:e.jsx(H,{})}),e.jsx(E,{children:v.map((n,c)=>e.jsx(R,{value:String(c),children:a(`llm.presets.${w[c]}`)},w[c]))})]})]}),e.jsxs("div",{children:[e.jsx(f,{className:"text-xs font-medium",children:a("llm.name")}),e.jsx(N,{value:i,onChange:n=>h(n.target.value),placeholder:a("llm.namePlaceholder"),className:"font-mono text-xs"})]}),e.jsxs("div",{className:"sm:col-span-2",children:[e.jsx(f,{className:"text-xs font-medium",children:a("llm.baseUrl")}),e.jsx(N,{value:r,onChange:n=>o(n.target.value),placeholder:a("llm.baseUrlPlaceholder"),className:"font-mono text-xs"})]}),e.jsxs("div",{children:[e.jsx(f,{className:"text-xs font-medium",children:a("llm.model")}),e.jsx(N,{value:d,onChange:n=>t(n.target.value),placeholder:a("llm.modelPlaceholder"),className:"font-mono text-xs"})]}),e.jsxs("div",{children:[e.jsx(f,{className:"text-xs font-medium",children:a("llm.apiKeyOptional")}),e.jsx(N,{type:"password",value:l,onChange:n=>u(n.target.value),placeholder:a("llm.apiKeyPlaceholder"),className:"font-mono text-xs",autoComplete:"off"})]}),e.jsx("div",{className:"sm:col-span-2 flex",children:e.jsxs(y,{type:"submit",disabled:s.isPending,className:"ml-auto",children:[s.isPending?e.jsx(K,{className:"h-4 w-4 animate-spin"}):e.jsx(Z,{className:"h-4 w-4"}),a("llm.addBackend")]})})]})]})}export{ce as default};
|
|
7
|
-
//# sourceMappingURL=llm-
|
|
7
|
+
//# sourceMappingURL=llm-5HpT83y2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-CJvopUnt.js","sources":["../../node_modules/lucide-react/dist/esm/icons/zap.js","../../src/routes/settings/llm.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Zap = createLucideIcon(\"Zap\", [\n [\n \"path\",\n {\n d: \"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z\",\n key: \"1xq2db\"\n }\n ]\n]);\n\nexport { Zap as default };\n//# sourceMappingURL=zap.js.map\n","/**\n * /settings/llm — native LLM backends + role bindings (Stage 6).\n *\n * Front-end for the `/api/llm/*` REST surface that landed in Stage 4.\n * Operators add an OpenAI-compatible or Anthropic backend, paste an\n * API key, bind it to a role (cheap / evaluator / native-chat), and\n * ping-test the connection — all without hand-editing\n * ~/.agim/config.json.\n *\n * Intentionally minimal styling — focused on doing the job; matches\n * the existing settings pages' shadcn look without bespoke chrome.\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, Loader2, Plus, RefreshCcw, Trash2, Zap } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select, SelectContent, SelectItem, SelectTrigger, SelectValue,\n} from '@/components/ui/select'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useLlmList, useLlmAddBackend, useLlmRemoveBackend, useLlmPutRoles, useLlmPing,\n} from '@/hooks/use-llm-admin'\n\nconst KNOWN_ROLES = ['cheap', 'evaluator', 'native-chat'] as const\nconst UNBIND_SENTINEL = '__unbind__'\n\ninterface ProviderPreset {\n provider: 'openai-compat' | 'anthropic'\n baseUrl: string\n modelHint: string\n}\n\nconst PRESET_KEYS = ['deepseek', 'moonshot', 'zhipu', 'openai', 'anthropic', 'custom'] as const\n\nconst PRESETS: ProviderPreset[] = [\n { provider: 'openai-compat',\n baseUrl: 'https://api.deepseek.com/v1', modelHint: 'deepseek-chat' },\n { provider: 'openai-compat',\n baseUrl: 'https://api.moonshot.cn/v1', modelHint: 'moonshot-v1-8k' },\n { provider: 'openai-compat',\n baseUrl: 'https://open.bigmodel.cn/api/paas/v4', modelHint: 'glm-4-air' },\n { provider: 'openai-compat',\n baseUrl: 'https://api.openai.com/v1', modelHint: 'gpt-4o-mini' },\n { provider: 'anthropic',\n // No trailing /v1: the Anthropic provider appends `/v1/messages` itself.\n baseUrl: 'https://api.anthropic.com', modelHint: 'claude-3-5-sonnet-20241022' },\n { provider: 'openai-compat',\n baseUrl: '', modelHint: '' },\n]\n\nexport default function SettingsLlmRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const listQuery = useLlmList()\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-6\">\n <header className=\"flex items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('llm.title')}</h1>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('llm.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('llm.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-64 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <BackendsCard data={listQuery.data} />\n <RolesCard data={listQuery.data} />\n <AddBackendCard />\n </>\n )}\n </div>\n )\n}\n\n/* ─────────────── Backends list ─────────────── */\n\nfunction BackendsCard({ data }: { data: ReturnType<typeof useLlmList>['data'] }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const removeBackend = useLlmRemoveBackend()\n const ping = useLlmPing()\n const [pingResults, setPingResults] = useState<Record<string, string>>({})\n\n async function onRemove(name: string): Promise<void> {\n if (!confirm(t('llm.removeConfirm', { name }))) return\n try {\n const r = await removeBackend.mutateAsync(name)\n toast.success(t('llm.removedToast', { count: r.removedRoles }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n async function onPing(name: string): Promise<void> {\n setPingResults((m) => ({ ...m, [name]: t('llm.pinging') }))\n try {\n const r = await ping.mutateAsync(name)\n const msg = r.ok\n ? `✓ ${r.durationMs}ms · tokens ${r.tokensIn}→${r.tokensOut}`\n : `✗ ${r.error}`\n setPingResults((m) => ({ ...m, [name]: msg }))\n } catch (err) {\n setPingResults((m) => ({ ...m, [name]: `✗ ${((err as Error)?.message ?? String(err))}` }))\n }\n }\n\n const rows = data?.backends ?? []\n if (rows.length === 0) {\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('llm.backendsEmpty')}\n </section>\n )\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.backendsTitle', { count: rows.length })}</h2>\n </header>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('llm.col.name')}</TableHead>\n <TableHead>{t('llm.col.provider')}</TableHead>\n <TableHead>{t('llm.col.model')}</TableHead>\n <TableHead>{t('llm.col.baseUrl')}</TableHead>\n <TableHead>{t('llm.col.apiKey')}</TableHead>\n <TableHead>{t('llm.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((b) => {\n const keyBadge = b.secret.source === 'none'\n ? <Badge variant=\"outline\">{t('llm.secretMissing')}</Badge>\n : <Badge variant=\"success\">{b.secret.source}</Badge>\n return (\n <TableRow key={b.name}>\n <TableCell className=\"font-mono text-xs\">{b.name}</TableCell>\n <TableCell>{b.provider}</TableCell>\n <TableCell className=\"font-mono text-xs\">{b.model}</TableCell>\n <TableCell className=\"break-all font-mono text-[11px] text-text-dim\">{b.baseUrl ?? '—'}</TableCell>\n <TableCell>{keyBadge}</TableCell>\n <TableCell className=\"flex flex-col gap-1 sm:flex-row sm:items-center\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onPing(b.name)}\n disabled={ping.isPending || b.secret.source === 'none'}\n title={b.secret.source === 'none' ? t('llm.setKeyFirst') : t('llm.pingHint')}\n >\n <Zap className=\"h-4 w-4\" />\n <span>{t('llm.ping')}</span>\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onRemove(b.name)}\n disabled={removeBackend.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <Trash2 className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('llm.remove')}</span>\n </Button>\n {pingResults[b.name] && (\n <span className=\"ml-2 text-[11px] text-text-dim\">{pingResults[b.name]}</span>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )\n}\n\n/* ─────────────── Role bindings ─────────────── */\n\nfunction RolesCard({ data }: { data: ReturnType<typeof useLlmList>['data'] }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const putRoles = useLlmPutRoles()\n const backendNames = (data?.backends ?? []).map((b) => b.name)\n const current = data?.roles ?? {}\n\n async function onChangeRole(role: string, value: string): Promise<void> {\n const next: Record<string, string | null> = {\n [role]: value === UNBIND_SENTINEL ? null : value,\n }\n try {\n await putRoles.mutateAsync(next)\n toast.success(t('llm.roleUpdated', { role }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.rolesTitle')}</h2>\n </header>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-3\">\n {KNOWN_ROLES.map((role) => (\n <div key={role} className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">{role}</Label>\n <Select\n value={current[role] ?? UNBIND_SENTINEL}\n onValueChange={(v) => void onChangeRole(role, v)}\n disabled={backendNames.length === 0 || putRoles.isPending}\n >\n <SelectTrigger className=\"font-mono text-xs\">\n <SelectValue placeholder={t('llm.unset')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={UNBIND_SENTINEL}>{t('llm.unbound')}</SelectItem>\n {backendNames.map((n) => (\n <SelectItem key={n} value={n}>{n}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-[11px] text-text-dim\">\n {t(`llm.roleHint.${role}`)}\n </p>\n </div>\n ))}\n </div>\n </section>\n )\n}\n\n/* ─────────────── Add backend form ─────────────── */\n\nfunction AddBackendCard(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const addBackend = useLlmAddBackend()\n const [presetIdx, setPresetIdx] = useState(0)\n const [name, setName] = useState('')\n const [baseUrl, setBaseUrl] = useState(PRESETS[0]?.baseUrl ?? '')\n const [model, setModel] = useState(PRESETS[0]?.modelHint ?? '')\n const [apiKey, setApiKey] = useState('')\n\n function onPickPreset(idx: number): void {\n setPresetIdx(idx)\n const p = PRESETS[idx]\n if (!p) return\n setBaseUrl(p.baseUrl)\n setModel(p.modelHint)\n }\n\n async function onSubmit(e: React.FormEvent): Promise<void> {\n e.preventDefault()\n const p = PRESETS[presetIdx]\n if (!p) { toast.error(t('llm.invalidPreset')); return }\n if (!name.trim()) { toast.error(t('llm.nameRequired')); return }\n if (!baseUrl.trim()) { toast.error(t('llm.baseUrlRequired')); return }\n if (!model.trim()) { toast.error(t('llm.modelRequired')); return }\n try {\n await addBackend.mutateAsync({\n name: name.trim(),\n provider: p.provider,\n baseUrl: baseUrl.trim(),\n model: model.trim(),\n ...(apiKey.trim() ? { apiKey: apiKey.trim() } : {}),\n })\n toast.success(\n apiKey.trim()\n ? t('llm.addedWithKey', { name: name.trim() })\n : t('llm.addedNoKey', { name: name.trim() }),\n )\n setName(''); setApiKey('')\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.addTitle')}</h2>\n </header>\n <form onSubmit={(e) => void onSubmit(e)} className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.preset')}</Label>\n <Select value={String(presetIdx)} onValueChange={(v) => onPickPreset(Number(v))}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {PRESETS.map((_p, i) => (\n <SelectItem key={PRESET_KEYS[i]} value={String(i)}>\n {t(`llm.presets.${PRESET_KEYS[i]}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.name')}</Label>\n <Input\n value={name} onChange={(e) => setName(e.target.value)}\n placeholder={t('llm.namePlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div className=\"sm:col-span-2\">\n <Label className=\"text-xs font-medium\">{t('llm.baseUrl')}</Label>\n <Input\n value={baseUrl} onChange={(e) => setBaseUrl(e.target.value)}\n placeholder={t('llm.baseUrlPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.model')}</Label>\n <Input\n value={model} onChange={(e) => setModel(e.target.value)}\n placeholder={t('llm.modelPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.apiKeyOptional')}</Label>\n <Input\n type=\"password\"\n value={apiKey} onChange={(e) => setApiKey(e.target.value)}\n placeholder={t('llm.apiKeyPlaceholder')}\n className=\"font-mono text-xs\"\n autoComplete=\"off\"\n />\n </div>\n <div className=\"sm:col-span-2 flex\">\n <Button\n type=\"submit\"\n disabled={addBackend.isPending}\n className=\"ml-auto\"\n >\n {addBackend.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Plus className=\"h-4 w-4\" />}\n {t('llm.addBackend')}\n </Button>\n </div>\n </form>\n </section>\n )\n}\n\n/* helper — toast tag passthrough */\nfunction _unused(): typeof CheckCircle2 { return CheckCircle2 }\nvoid _unused\n"],"names":["Zap","createLucideIcon","KNOWN_ROLES","UNBIND_SENTINEL","PRESET_KEYS","PRESETS","SettingsLlmRoute","t","useTranslation","listQuery","useLlmList","jsxs","jsx","Button","Loader2","RefreshCcw","Fragment","BackendsCard","RolesCard","AddBackendCard","data","removeBackend","useLlmRemoveBackend","ping","useLlmPing","pingResults","setPingResults","useState","onRemove","name","r","toast","err","onPing","m","msg","rows","Table","TableHeader","TableRow","TableHead","TableBody","b","keyBadge","Badge","TableCell","Trash2","putRoles","useLlmPutRoles","backendNames","current","onChangeRole","role","value","next","Label","Select","v","SelectTrigger","SelectValue","SelectContent","SelectItem","n","addBackend","useLlmAddBackend","presetIdx","setPresetIdx","setName","baseUrl","setBaseUrl","model","setModel","apiKey","setApiKey","onPickPreset","idx","p","onSubmit","e","_p","i","Input","Plus"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"llm-5HpT83y2.js","sources":["../../node_modules/lucide-react/dist/esm/icons/zap.js","../../src/routes/settings/llm.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Zap = createLucideIcon(\"Zap\", [\n [\n \"path\",\n {\n d: \"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z\",\n key: \"1xq2db\"\n }\n ]\n]);\n\nexport { Zap as default };\n//# sourceMappingURL=zap.js.map\n","/**\n * /settings/llm — native LLM backends + role bindings (Stage 6).\n *\n * Front-end for the `/api/llm/*` REST surface that landed in Stage 4.\n * Operators add an OpenAI-compatible or Anthropic backend, paste an\n * API key, bind it to a role (cheap / evaluator / native-chat), and\n * ping-test the connection — all without hand-editing\n * ~/.agim/config.json.\n *\n * Intentionally minimal styling — focused on doing the job; matches\n * the existing settings pages' shadcn look without bespoke chrome.\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, Loader2, Plus, RefreshCcw, Trash2, Zap } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select, SelectContent, SelectItem, SelectTrigger, SelectValue,\n} from '@/components/ui/select'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useLlmList, useLlmAddBackend, useLlmRemoveBackend, useLlmPutRoles, useLlmPing,\n} from '@/hooks/use-llm-admin'\n\nconst KNOWN_ROLES = ['cheap', 'evaluator', 'native-chat'] as const\nconst UNBIND_SENTINEL = '__unbind__'\n\ninterface ProviderPreset {\n provider: 'openai-compat' | 'anthropic'\n baseUrl: string\n modelHint: string\n}\n\nconst PRESET_KEYS = ['deepseek', 'moonshot', 'zhipu', 'openai', 'anthropic', 'custom'] as const\n\nconst PRESETS: ProviderPreset[] = [\n { provider: 'openai-compat',\n baseUrl: 'https://api.deepseek.com/v1', modelHint: 'deepseek-chat' },\n { provider: 'openai-compat',\n baseUrl: 'https://api.moonshot.cn/v1', modelHint: 'moonshot-v1-8k' },\n { provider: 'openai-compat',\n baseUrl: 'https://open.bigmodel.cn/api/paas/v4', modelHint: 'glm-4-air' },\n { provider: 'openai-compat',\n baseUrl: 'https://api.openai.com/v1', modelHint: 'gpt-4o-mini' },\n { provider: 'anthropic',\n // No trailing /v1: the Anthropic provider appends `/v1/messages` itself.\n baseUrl: 'https://api.anthropic.com', modelHint: 'claude-3-5-sonnet-20241022' },\n { provider: 'openai-compat',\n baseUrl: '', modelHint: '' },\n]\n\nexport default function SettingsLlmRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const listQuery = useLlmList()\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-6\">\n <header className=\"flex items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('llm.title')}</h1>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('llm.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('llm.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-64 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <BackendsCard data={listQuery.data} />\n <RolesCard data={listQuery.data} />\n <AddBackendCard />\n </>\n )}\n </div>\n )\n}\n\n/* ─────────────── Backends list ─────────────── */\n\nfunction BackendsCard({ data }: { data: ReturnType<typeof useLlmList>['data'] }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const removeBackend = useLlmRemoveBackend()\n const ping = useLlmPing()\n const [pingResults, setPingResults] = useState<Record<string, string>>({})\n\n async function onRemove(name: string): Promise<void> {\n if (!confirm(t('llm.removeConfirm', { name }))) return\n try {\n const r = await removeBackend.mutateAsync(name)\n toast.success(t('llm.removedToast', { count: r.removedRoles }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n async function onPing(name: string): Promise<void> {\n setPingResults((m) => ({ ...m, [name]: t('llm.pinging') }))\n try {\n const r = await ping.mutateAsync(name)\n const msg = r.ok\n ? `✓ ${r.durationMs}ms · tokens ${r.tokensIn}→${r.tokensOut}`\n : `✗ ${r.error}`\n setPingResults((m) => ({ ...m, [name]: msg }))\n } catch (err) {\n setPingResults((m) => ({ ...m, [name]: `✗ ${((err as Error)?.message ?? String(err))}` }))\n }\n }\n\n const rows = data?.backends ?? []\n if (rows.length === 0) {\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('llm.backendsEmpty')}\n </section>\n )\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.backendsTitle', { count: rows.length })}</h2>\n </header>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('llm.col.name')}</TableHead>\n <TableHead>{t('llm.col.provider')}</TableHead>\n <TableHead>{t('llm.col.model')}</TableHead>\n <TableHead>{t('llm.col.baseUrl')}</TableHead>\n <TableHead>{t('llm.col.apiKey')}</TableHead>\n <TableHead>{t('llm.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((b) => {\n const keyBadge = b.secret.source === 'none'\n ? <Badge variant=\"outline\">{t('llm.secretMissing')}</Badge>\n : <Badge variant=\"success\">{b.secret.source}</Badge>\n return (\n <TableRow key={b.name}>\n <TableCell className=\"font-mono text-xs\">{b.name}</TableCell>\n <TableCell>{b.provider}</TableCell>\n <TableCell className=\"font-mono text-xs\">{b.model}</TableCell>\n <TableCell className=\"break-all font-mono text-[11px] text-text-dim\">{b.baseUrl ?? '—'}</TableCell>\n <TableCell>{keyBadge}</TableCell>\n <TableCell className=\"flex flex-col gap-1 sm:flex-row sm:items-center\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onPing(b.name)}\n disabled={ping.isPending || b.secret.source === 'none'}\n title={b.secret.source === 'none' ? t('llm.setKeyFirst') : t('llm.pingHint')}\n >\n <Zap className=\"h-4 w-4\" />\n <span>{t('llm.ping')}</span>\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onRemove(b.name)}\n disabled={removeBackend.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <Trash2 className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('llm.remove')}</span>\n </Button>\n {pingResults[b.name] && (\n <span className=\"ml-2 text-[11px] text-text-dim\">{pingResults[b.name]}</span>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )\n}\n\n/* ─────────────── Role bindings ─────────────── */\n\nfunction RolesCard({ data }: { data: ReturnType<typeof useLlmList>['data'] }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const putRoles = useLlmPutRoles()\n const backendNames = (data?.backends ?? []).map((b) => b.name)\n const current = data?.roles ?? {}\n\n async function onChangeRole(role: string, value: string): Promise<void> {\n const next: Record<string, string | null> = {\n [role]: value === UNBIND_SENTINEL ? null : value,\n }\n try {\n await putRoles.mutateAsync(next)\n toast.success(t('llm.roleUpdated', { role }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.rolesTitle')}</h2>\n </header>\n <div className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-3\">\n {KNOWN_ROLES.map((role) => (\n <div key={role} className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">{role}</Label>\n <Select\n value={current[role] ?? UNBIND_SENTINEL}\n onValueChange={(v) => void onChangeRole(role, v)}\n disabled={backendNames.length === 0 || putRoles.isPending}\n >\n <SelectTrigger className=\"font-mono text-xs\">\n <SelectValue placeholder={t('llm.unset')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={UNBIND_SENTINEL}>{t('llm.unbound')}</SelectItem>\n {backendNames.map((n) => (\n <SelectItem key={n} value={n}>{n}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-[11px] text-text-dim\">\n {t(`llm.roleHint.${role}`)}\n </p>\n </div>\n ))}\n </div>\n </section>\n )\n}\n\n/* ─────────────── Add backend form ─────────────── */\n\nfunction AddBackendCard(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const addBackend = useLlmAddBackend()\n const [presetIdx, setPresetIdx] = useState(0)\n const [name, setName] = useState('')\n const [baseUrl, setBaseUrl] = useState(PRESETS[0]?.baseUrl ?? '')\n const [model, setModel] = useState(PRESETS[0]?.modelHint ?? '')\n const [apiKey, setApiKey] = useState('')\n\n function onPickPreset(idx: number): void {\n setPresetIdx(idx)\n const p = PRESETS[idx]\n if (!p) return\n setBaseUrl(p.baseUrl)\n setModel(p.modelHint)\n }\n\n async function onSubmit(e: React.FormEvent): Promise<void> {\n e.preventDefault()\n const p = PRESETS[presetIdx]\n if (!p) { toast.error(t('llm.invalidPreset')); return }\n if (!name.trim()) { toast.error(t('llm.nameRequired')); return }\n if (!baseUrl.trim()) { toast.error(t('llm.baseUrlRequired')); return }\n if (!model.trim()) { toast.error(t('llm.modelRequired')); return }\n try {\n await addBackend.mutateAsync({\n name: name.trim(),\n provider: p.provider,\n baseUrl: baseUrl.trim(),\n model: model.trim(),\n ...(apiKey.trim() ? { apiKey: apiKey.trim() } : {}),\n })\n toast.success(\n apiKey.trim()\n ? t('llm.addedWithKey', { name: name.trim() })\n : t('llm.addedNoKey', { name: name.trim() }),\n )\n setName(''); setApiKey('')\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('llm.addTitle')}</h2>\n </header>\n <form onSubmit={(e) => void onSubmit(e)} className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.preset')}</Label>\n <Select value={String(presetIdx)} onValueChange={(v) => onPickPreset(Number(v))}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {PRESETS.map((_p, i) => (\n <SelectItem key={PRESET_KEYS[i]} value={String(i)}>\n {t(`llm.presets.${PRESET_KEYS[i]}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.name')}</Label>\n <Input\n value={name} onChange={(e) => setName(e.target.value)}\n placeholder={t('llm.namePlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div className=\"sm:col-span-2\">\n <Label className=\"text-xs font-medium\">{t('llm.baseUrl')}</Label>\n <Input\n value={baseUrl} onChange={(e) => setBaseUrl(e.target.value)}\n placeholder={t('llm.baseUrlPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.model')}</Label>\n <Input\n value={model} onChange={(e) => setModel(e.target.value)}\n placeholder={t('llm.modelPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('llm.apiKeyOptional')}</Label>\n <Input\n type=\"password\"\n value={apiKey} onChange={(e) => setApiKey(e.target.value)}\n placeholder={t('llm.apiKeyPlaceholder')}\n className=\"font-mono text-xs\"\n autoComplete=\"off\"\n />\n </div>\n <div className=\"sm:col-span-2 flex\">\n <Button\n type=\"submit\"\n disabled={addBackend.isPending}\n className=\"ml-auto\"\n >\n {addBackend.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Plus className=\"h-4 w-4\" />}\n {t('llm.addBackend')}\n </Button>\n </div>\n </form>\n </section>\n )\n}\n\n/* helper — toast tag passthrough */\nfunction _unused(): typeof CheckCircle2 { return CheckCircle2 }\nvoid _unused\n"],"names":["Zap","createLucideIcon","KNOWN_ROLES","UNBIND_SENTINEL","PRESET_KEYS","PRESETS","SettingsLlmRoute","t","useTranslation","listQuery","useLlmList","jsxs","jsx","Button","Loader2","RefreshCcw","Fragment","BackendsCard","RolesCard","AddBackendCard","data","removeBackend","useLlmRemoveBackend","ping","useLlmPing","pingResults","setPingResults","useState","onRemove","name","r","toast","err","onPing","m","msg","rows","Table","TableHeader","TableRow","TableHead","TableBody","b","keyBadge","Badge","TableCell","Trash2","putRoles","useLlmPutRoles","backendNames","current","onChangeRole","role","value","next","Label","Select","v","SelectTrigger","SelectValue","SelectContent","SelectItem","n","addBackend","useLlmAddBackend","presetIdx","setPresetIdx","setName","baseUrl","setBaseUrl","model","setModel","apiKey","setApiKey","onPickPreset","idx","p","onSubmit","e","_p","i","Input","Plus"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{n as e}from"./index-
|
|
1
|
+
import{n as e}from"./index-BjUyDXLb.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/const r=e("LoaderCircle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);export{r as L};
|
|
7
|
-
//# sourceMappingURL=loader-circle-
|
|
7
|
+
//# sourceMappingURL=loader-circle-MnTMknNl.js.map
|
package/dist/web/public/assets/{loader-circle-CgLbYd3g.js.map → loader-circle-MnTMknNl.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-circle-
|
|
1
|
+
{"version":3,"file":"loader-circle-MnTMknNl.js","sources":["../../node_modules/lucide-react/dist/esm/icons/loader-circle.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst LoaderCircle = createLucideIcon(\"LoaderCircle\", [\n [\"path\", { d: \"M21 12a9 9 0 1 1-6.219-8.56\", key: \"13zald\" }]\n]);\n\nexport { LoaderCircle as default };\n//# sourceMappingURL=loader-circle.js.map\n"],"names":["LoaderCircle","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAeC,EAAiB,eAAgB,CACpD,CAAC,OAAQ,CAAE,EAAG,8BAA+B,IAAK,QAAQ,CAAE,CAC9D,CAAC","x_google_ignoreList":[0]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{n as c}from"./index-
|
|
1
|
+
import{n as c}from"./index-BjUyDXLb.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/const r=c("MapPin",[["path",{d:"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0",key:"1r0f0z"}],["circle",{cx:"12",cy:"10",r:"3",key:"ilqhr7"}]]);export{r as M};
|
|
7
|
-
//# sourceMappingURL=map-pin-
|
|
7
|
+
//# sourceMappingURL=map-pin-BA0GTiIe.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-pin-
|
|
1
|
+
{"version":3,"file":"map-pin-BA0GTiIe.js","sources":["../../node_modules/lucide-react/dist/esm/icons/map-pin.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst MapPin = createLucideIcon(\"MapPin\", [\n [\n \"path\",\n {\n d: \"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\",\n key: \"1r0f0z\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"10\", r: \"3\", key: \"ilqhr7\" }]\n]);\n\nexport { MapPin as default };\n//# sourceMappingURL=map-pin.js.map\n"],"names":["MapPin","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CACE,OACA,CACE,EAAG,uGACH,IAAK,QACX,CACA,EACE,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAQ,CAAE,CAC1D,CAAC","x_google_ignoreList":[0]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{n as A,u as L,j as e,B as k,k as C,L as x,I as v,S as M,f as q,g as z,h as B,i as R,l as o}from"./index-
|
|
1
|
+
import{n as A,u as L,j as e,B as k,k as C,L as x,I as v,S as M,f as q,g as z,h as B,i as R,l as o}from"./index-BjUyDXLb.js";import{r as l}from"./react-DlP5eolq.js";import{T as F,a as I,b as H,c as b,d as O,e as N}from"./table-CVYTRwUs.js";import{e as $,f as E,g as D,h as J}from"./use-llm-admin-CdqRAs0I.js";import{L as P}from"./loader-circle-MnTMknNl.js";import{R as V}from"./refresh-ccw--XT-lrCo.js";import{A as U}from"./activity-CrnWHC2j.js";import{T as Q}from"./trash-2-CeN2btBl.js";import{P as W}from"./plus-BOfhZkjh.js";import"./useQuery-CvEVNuvH.js";/**
|
|
2
2
|
* @license lucide-react v0.469.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/const G=A("ServerCog",[["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}],["path",{d:"M4.5 10H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-.5",key:"tn8das"}],["path",{d:"M4.5 14H4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2h-.5",key:"1g2pve"}],["path",{d:"M6 6h.01",key:"1utrut"}],["path",{d:"M6 18h.01",key:"uhywen"}],["path",{d:"m15.7 13.4-.9-.3",key:"1jwmzr"}],["path",{d:"m9.2 10.9-.9-.3",key:"qapnim"}],["path",{d:"m10.6 15.7.3-.9",key:"quwk0k"}],["path",{d:"m13.6 15.7-.4-1",key:"cb9xp7"}],["path",{d:"m10.8 9.3-.4-1",key:"1uaiz5"}],["path",{d:"m8.3 13.6 1-.4",key:"s6srou"}],["path",{d:"m14.7 10.8 1-.4",key:"4d31cq"}],["path",{d:"m13.4 8.3-.3.9",key:"1bm987"}]]);function me(){const{t}=L(["settings","common"]),s=$();return e.jsxs("div",{className:"mx-auto flex max-w-5xl flex-col gap-6",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(G,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:t("mcp.title")}),e.jsxs(k,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void s.refetch(),disabled:s.isFetching,"aria-label":t("actions.refresh",{ns:"common"}),children:[s.isFetching?e.jsx(P,{className:"h-4 w-4 animate-spin"}):e.jsx(V,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:t("mcp.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:t("mcp.subtitle")}),s.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):e.jsxs(e.Fragment,{children:[e.jsx(K,{data:s.data}),e.jsx(Y,{})]})]})}function K({data:t}){const{t:s}=L(["settings","common"]),m=E(),p=D(),[i,u]=l.useState({});async function j(r){if(confirm(s("mcp.removeConfirm",{name:r})))try{await m.mutateAsync(r),o.success(s("mcp.removedToast",{name:r}))}catch(a){o.error(a?.message??String(a))}}async function y(r){u(a=>({...a,[r]:s("mcp.probing")}));try{const a=await p.mutateAsync(r),c=a.connected?`✓ ${a.toolCount===1?s("mcp.runtimeConnectedOne",{count:a.toolCount}):s("mcp.runtimeConnected",{count:a.toolCount})}`:`✗ ${a.lastError??s("mcp.runtimeDisconnected")}`;u(h=>({...h,[r]:c}))}catch(a){u(c=>({...c,[r]:`✗ ${a?.message??String(a)}`}))}}const d=t?.servers??[],S=t?.runtime?.servers??[];return d.length===0?e.jsx("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:s("mcp.serversEmpty")}):e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsxs("header",{className:"flex items-center gap-2 border-b border-border px-4 py-3",children:[e.jsx("h2",{className:"text-sm font-semibold",children:s("mcp.serversTitle",{count:d.length})}),t?.runtime&&e.jsx(C,{variant:"info",children:s("mcp.totalTools",{count:t.runtime.totalTools})})]}),e.jsxs(F,{children:[e.jsx(I,{children:e.jsxs(H,{children:[e.jsx(b,{children:s("mcp.col.name")}),e.jsx(b,{children:s("mcp.col.transport")}),e.jsx(b,{children:s("mcp.col.target")}),e.jsx(b,{children:s("mcp.col.runtime")}),e.jsx(b,{children:s("mcp.col.actions")})]})}),e.jsx(O,{children:d.map(r=>{const a=S.find(n=>n.name===r.name),c=X(r,s),h=r.command?`${r.command} ${(r.args??[]).join(" ")}`.trim():r.url??"—",w=a?a.connected?e.jsx(C,{variant:"success",children:a.toolCount===1?s("mcp.runtimeConnectedOne",{count:a.toolCount}):s("mcp.runtimeConnected",{count:a.toolCount})}):e.jsx(C,{variant:"danger",children:s("mcp.runtimeDisconnected")}):e.jsx(C,{variant:"outline",children:s("mcp.runtimeUnknown")});return e.jsxs(H,{children:[e.jsx(N,{className:"font-mono text-xs",children:r.name}),e.jsx(N,{children:c}),e.jsx(N,{className:"break-all font-mono text-[11px] text-text-dim",children:h}),e.jsx(N,{children:w}),e.jsxs(N,{className:"flex flex-col gap-1 sm:flex-row sm:items-center",children:[e.jsxs(k,{variant:"ghost",size:"sm",onClick:()=>void y(r.name),disabled:p.isPending,children:[e.jsx(U,{className:"h-4 w-4"}),e.jsx("span",{children:s("mcp.health")})]}),e.jsxs(k,{variant:"ghost",size:"sm",onClick:()=>void j(r.name),disabled:m.isPending,className:"text-danger hover:text-danger",children:[e.jsx(Q,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("mcp.remove")})]}),i[r.name]&&e.jsx("span",{className:"ml-2 text-[11px] text-text-dim",children:i[r.name]})]})]},r.name)})})]})]})}function X(t,s){return t.command?s("mcp.transportStdio"):t.url?t.url.endsWith("/sse")?s("mcp.transportSse"):s("mcp.transportHttp"):"—"}function Y(){const{t}=L(["settings","common"]),s=J(),[m,p]=l.useState(""),[i,u]=l.useState("stdio"),[j,y]=l.useState(""),[d,S]=l.useState(""),[r,a]=l.useState(""),[c,h]=l.useState("");async function w(n){if(n.preventDefault(),!m.trim()){o.error(t("mcp.nameRequired"));return}let T;if(c.trim())try{T=JSON.parse(c)}catch{o.error(t("mcp.headersInvalid"));return}const g={name:m.trim()};if(i==="stdio"){if(!j.trim()){o.error(t("mcp.commandRequired"));return}g.command=j.trim();const f=d.split(/\s+/).filter(Boolean);f.length>0&&(g.args=f)}else{if(!r.trim()){o.error(t("mcp.urlRequired"));return}g.url=r.trim(),T&&(g.headers=T)}try{await s.mutateAsync(g),o.success(t("mcp.addedToast",{name:m.trim()})),p(""),y(""),S(""),a(""),h("")}catch(f){o.error(f?.message??String(f))}}return e.jsxs("section",{className:"rounded-md border border-border bg-surface",children:[e.jsx("header",{className:"border-b border-border px-4 py-3",children:e.jsx("h2",{className:"text-sm font-semibold",children:t("mcp.addTitle")})}),e.jsxs("form",{onSubmit:n=>void w(n),className:"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(x,{className:"text-xs font-medium",children:t("mcp.nameLabel")}),e.jsx(v,{value:m,onChange:n=>p(n.target.value),placeholder:t("mcp.namePlaceholder"),className:"font-mono text-xs"})]}),e.jsxs("div",{children:[e.jsx(x,{className:"text-xs font-medium",children:t("mcp.transportLabel")}),e.jsxs(M,{value:i,onValueChange:n=>u(n),children:[e.jsx(q,{children:e.jsx(z,{})}),e.jsxs(B,{children:[e.jsx(R,{value:"stdio",children:t("mcp.transportStdioOption")}),e.jsx(R,{value:"http",children:t("mcp.transportHttpOption")})]})]})]}),i==="stdio"?e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx(x,{className:"text-xs font-medium",children:t("mcp.commandLabel")}),e.jsx(v,{value:j,onChange:n=>y(n.target.value),placeholder:t("mcp.commandPlaceholder"),className:"font-mono text-xs"})]}),e.jsxs("div",{children:[e.jsx(x,{className:"text-xs font-medium",children:t("mcp.argsLabel")}),e.jsx(v,{value:d,onChange:n=>S(n.target.value),placeholder:"-y @modelcontextprotocol/server-filesystem /data",className:"font-mono text-xs"})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"sm:col-span-2",children:[e.jsx(x,{className:"text-xs font-medium",children:t("mcp.urlLabel")}),e.jsx(v,{value:r,onChange:n=>a(n.target.value),placeholder:t("mcp.urlPlaceholder"),className:"font-mono text-xs"})]}),e.jsxs("div",{className:"sm:col-span-2",children:[e.jsx(x,{className:"text-xs font-medium",children:t("mcp.headersLabel")}),e.jsx(v,{value:c,onChange:n=>h(n.target.value),placeholder:t("mcp.headersPlaceholder"),className:"font-mono text-xs"})]})]}),e.jsx("div",{className:"sm:col-span-2 flex",children:e.jsxs(k,{type:"submit",disabled:s.isPending,className:"ml-auto",children:[s.isPending?e.jsx(P,{className:"h-4 w-4 animate-spin"}):e.jsx(W,{className:"h-4 w-4"}),t("mcp.addServer")]})})]})]})}export{me as default};
|
|
7
|
-
//# sourceMappingURL=mcp-
|
|
7
|
+
//# sourceMappingURL=mcp-C71xI5JH.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-SI73JwZR.js","sources":["../../node_modules/lucide-react/dist/esm/icons/server-cog.js","../../src/routes/settings/mcp.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ServerCog = createLucideIcon(\"ServerCog\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }],\n [\n \"path\",\n {\n d: \"M4.5 10H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-.5\",\n key: \"tn8das\"\n }\n ],\n [\n \"path\",\n {\n d: \"M4.5 14H4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2h-.5\",\n key: \"1g2pve\"\n }\n ],\n [\"path\", { d: \"M6 6h.01\", key: \"1utrut\" }],\n [\"path\", { d: \"M6 18h.01\", key: \"uhywen\" }],\n [\"path\", { d: \"m15.7 13.4-.9-.3\", key: \"1jwmzr\" }],\n [\"path\", { d: \"m9.2 10.9-.9-.3\", key: \"qapnim\" }],\n [\"path\", { d: \"m10.6 15.7.3-.9\", key: \"quwk0k\" }],\n [\"path\", { d: \"m13.6 15.7-.4-1\", key: \"cb9xp7\" }],\n [\"path\", { d: \"m10.8 9.3-.4-1\", key: \"1uaiz5\" }],\n [\"path\", { d: \"m8.3 13.6 1-.4\", key: \"s6srou\" }],\n [\"path\", { d: \"m14.7 10.8 1-.4\", key: \"4d31cq\" }],\n [\"path\", { d: \"m13.4 8.3-.3.9\", key: \"1bm987\" }]\n]);\n\nexport { ServerCog as default };\n//# sourceMappingURL=server-cog.js.map\n","/**\n * /settings/mcp — external MCP servers admin (Stage 6).\n *\n * Front-end for the `/api/mcp/*` REST surface. List configured servers,\n * see their connection status + tool count, add stdio / HTTP / SSE\n * servers, probe per-server health, remove.\n *\n * The native agent loop consumes any tools advertised here; CLI agents\n * have their own MCP configs and ignore this list. See\n * docs/llm-backends.md § External MCP servers.\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Loader2, Plus, RefreshCcw, ServerCog, Trash2, Activity } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select, SelectContent, SelectItem, SelectTrigger, SelectValue,\n} from '@/components/ui/select'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useMcpList, useMcpAddServer, useMcpRemoveServer, useMcpHealth,\n type McpServerRow,\n} from '@/hooks/use-llm-admin'\n\nexport default function SettingsMcpRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const listQuery = useMcpList()\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-6\">\n <header className=\"flex items-center gap-3\">\n <ServerCog className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('mcp.title')}</h1>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('mcp.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('mcp.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <ServersCard data={listQuery.data} />\n <AddServerCard />\n </>\n )}\n </div>\n )\n}\n\n/* ─────────────── Servers list ─────────────── */\n\nfunction ServersCard({ data }: { data: ReturnType<typeof useMcpList>['data'] }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const removeServer = useMcpRemoveServer()\n const health = useMcpHealth()\n const [healthResults, setHealthResults] = useState<Record<string, string>>({})\n\n async function onRemove(name: string): Promise<void> {\n if (!confirm(t('mcp.removeConfirm', { name }))) return\n try {\n await removeServer.mutateAsync(name)\n toast.success(t('mcp.removedToast', { name }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n async function onHealth(name: string): Promise<void> {\n setHealthResults((m) => ({ ...m, [name]: t('mcp.probing') }))\n try {\n const r = await health.mutateAsync(name)\n const msg = r.connected\n ? `✓ ${r.toolCount === 1\n ? t('mcp.runtimeConnectedOne', { count: r.toolCount })\n : t('mcp.runtimeConnected', { count: r.toolCount })}`\n : `✗ ${r.lastError ?? t('mcp.runtimeDisconnected')}`\n setHealthResults((m) => ({ ...m, [name]: msg }))\n } catch (err) {\n setHealthResults((m) => ({ ...m, [name]: `✗ ${((err as Error)?.message ?? String(err))}` }))\n }\n }\n\n const rows = data?.servers ?? []\n const runtime = data?.runtime?.servers ?? []\n if (rows.length === 0) {\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('mcp.serversEmpty')}\n </section>\n )\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('mcp.serversTitle', { count: rows.length })}</h2>\n {data?.runtime && (\n <Badge variant=\"info\">{t('mcp.totalTools', { count: data.runtime.totalTools })}</Badge>\n )}\n </header>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('mcp.col.name')}</TableHead>\n <TableHead>{t('mcp.col.transport')}</TableHead>\n <TableHead>{t('mcp.col.target')}</TableHead>\n <TableHead>{t('mcp.col.runtime')}</TableHead>\n <TableHead>{t('mcp.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((s) => {\n const rt = runtime.find((r) => r.name === s.name)\n const transport = transportLabel(s, t)\n const target = s.command\n ? `${s.command} ${(s.args ?? []).join(' ')}`.trim()\n : (s.url ?? '—')\n const runtimeBadge = !rt\n ? <Badge variant=\"outline\">{t('mcp.runtimeUnknown')}</Badge>\n : rt.connected\n ? <Badge variant=\"success\">\n {rt.toolCount === 1\n ? t('mcp.runtimeConnectedOne', { count: rt.toolCount })\n : t('mcp.runtimeConnected', { count: rt.toolCount })}\n </Badge>\n : <Badge variant=\"danger\">{t('mcp.runtimeDisconnected')}</Badge>\n return (\n <TableRow key={s.name}>\n <TableCell className=\"font-mono text-xs\">{s.name}</TableCell>\n <TableCell>{transport}</TableCell>\n <TableCell className=\"break-all font-mono text-[11px] text-text-dim\">{target}</TableCell>\n <TableCell>{runtimeBadge}</TableCell>\n <TableCell className=\"flex flex-col gap-1 sm:flex-row sm:items-center\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onHealth(s.name)}\n disabled={health.isPending}\n >\n <Activity className=\"h-4 w-4\" />\n <span>{t('mcp.health')}</span>\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onRemove(s.name)}\n disabled={removeServer.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <Trash2 className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('mcp.remove')}</span>\n </Button>\n {healthResults[s.name] && (\n <span className=\"ml-2 text-[11px] text-text-dim\">{healthResults[s.name]}</span>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )\n}\n\nfunction transportLabel(\n s: McpServerRow,\n t: (key: string) => string,\n): string {\n if (s.command) return t('mcp.transportStdio')\n if (s.url) return s.url.endsWith('/sse') ? t('mcp.transportSse') : t('mcp.transportHttp')\n return '—'\n}\n\n/* ─────────────── Add server form ─────────────── */\n\nfunction AddServerCard(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const addServer = useMcpAddServer()\n const [name, setName] = useState('')\n const [transport, setTransport] = useState<'stdio' | 'http'>('stdio')\n const [command, setCommand] = useState('')\n const [args, setArgs] = useState('')\n const [url, setUrl] = useState('')\n const [headersJson, setHeadersJson] = useState('')\n\n async function onSubmit(e: React.FormEvent): Promise<void> {\n e.preventDefault()\n if (!name.trim()) { toast.error(t('mcp.nameRequired')); return }\n let headers: Record<string, string> | undefined\n if (headersJson.trim()) {\n try { headers = JSON.parse(headersJson) }\n catch { toast.error(t('mcp.headersInvalid')); return }\n }\n const body: Parameters<typeof addServer.mutateAsync>[0] = { name: name.trim() }\n if (transport === 'stdio') {\n if (!command.trim()) { toast.error(t('mcp.commandRequired')); return }\n body.command = command.trim()\n const splitArgs = args.split(/\\s+/).filter(Boolean)\n if (splitArgs.length > 0) body.args = splitArgs\n } else {\n if (!url.trim()) { toast.error(t('mcp.urlRequired')); return }\n body.url = url.trim()\n if (headers) body.headers = headers\n }\n try {\n await addServer.mutateAsync(body)\n toast.success(t('mcp.addedToast', { name: name.trim() }))\n setName(''); setCommand(''); setArgs(''); setUrl(''); setHeadersJson('')\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('mcp.addTitle')}</h2>\n </header>\n <form onSubmit={(e) => void onSubmit(e)} className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <div>\n <Label className=\"text-xs font-medium\">{t('mcp.nameLabel')}</Label>\n <Input\n value={name} onChange={(e) => setName(e.target.value)}\n placeholder={t('mcp.namePlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('mcp.transportLabel')}</Label>\n <Select value={transport} onValueChange={(v) => setTransport(v as 'stdio' | 'http')}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"stdio\">{t('mcp.transportStdioOption')}</SelectItem>\n <SelectItem value=\"http\">{t('mcp.transportHttpOption')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n {transport === 'stdio' ? (\n <>\n <div>\n <Label className=\"text-xs font-medium\">{t('mcp.commandLabel')}</Label>\n <Input\n value={command} onChange={(e) => setCommand(e.target.value)}\n placeholder={t('mcp.commandPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('mcp.argsLabel')}</Label>\n <Input\n value={args} onChange={(e) => setArgs(e.target.value)}\n placeholder=\"-y @modelcontextprotocol/server-filesystem /data\"\n className=\"font-mono text-xs\"\n />\n </div>\n </>\n ) : (\n <>\n <div className=\"sm:col-span-2\">\n <Label className=\"text-xs font-medium\">{t('mcp.urlLabel')}</Label>\n <Input\n value={url} onChange={(e) => setUrl(e.target.value)}\n placeholder={t('mcp.urlPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div className=\"sm:col-span-2\">\n <Label className=\"text-xs font-medium\">{t('mcp.headersLabel')}</Label>\n <Input\n value={headersJson} onChange={(e) => setHeadersJson(e.target.value)}\n placeholder={t('mcp.headersPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n </>\n )}\n <div className=\"sm:col-span-2 flex\">\n <Button type=\"submit\" disabled={addServer.isPending} className=\"ml-auto\">\n {addServer.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Plus className=\"h-4 w-4\" />}\n {t('mcp.addServer')}\n </Button>\n </div>\n </form>\n </section>\n )\n}\n"],"names":["ServerCog","createLucideIcon","SettingsMcpRoute","useTranslation","listQuery","useMcpList","jsxs","jsx","Button","Loader2","RefreshCcw","Fragment","ServersCard","AddServerCard","data","t","removeServer","useMcpRemoveServer","health","useMcpHealth","healthResults","setHealthResults","useState","onRemove","name","toast","err","onHealth","m","r","msg","rows","runtime","Badge","Table","TableHeader","TableRow","TableHead","TableBody","s","rt","transport","transportLabel","target","runtimeBadge","TableCell","Activity","Trash2","addServer","useMcpAddServer","setName","setTransport","command","setCommand","args","setArgs","url","setUrl","headersJson","setHeadersJson","onSubmit","e","headers","body","splitArgs","Label","Input","Select","v","SelectTrigger","SelectValue","SelectContent","SelectItem","Plus"],"mappings":"6iBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAYC,EAAiB,YAAa,CAC9C,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,SAAU,EACxD,CACE,OACA,CACE,EAAG,+EACH,IAAK,QACX,CACA,EACE,CACE,OACA,CACE,EAAG,gFACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,EAAG,mBAAoB,IAAK,QAAQ,CAAE,EACjD,CAAC,OAAQ,CAAE,EAAG,kBAAmB,IAAK,QAAQ,CAAE,EAChD,CAAC,OAAQ,CAAE,EAAG,kBAAmB,IAAK,QAAQ,CAAE,EAChD,CAAC,OAAQ,CAAE,EAAG,kBAAmB,IAAK,QAAQ,CAAE,EAChD,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAQ,CAAE,EAC/C,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAQ,CAAE,EAC/C,CAAC,OAAQ,CAAE,EAAG,kBAAmB,IAAK,QAAQ,CAAE,EAChD,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAQ,CAAE,CACjD,CAAC,ECHD,SAAwBC,IAAgC,CACtD,KAAM,CAAE,CAAA,EAAMC,EAAe,CAAC,WAAY,QAAQ,CAAC,EAC7CC,EAAYC,EAAA,EAClB,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,0BAChB,SAAA,CAAAC,EAAAA,IAACP,EAAA,CAAU,UAAU,uBAAA,CAAwB,QAC5C,KAAA,CAAG,UAAU,wBAAyB,SAAA,EAAE,WAAW,EAAE,EACtDM,EAAAA,KAACE,EAAA,CACC,QAAQ,QAAQ,KAAK,KAAK,UAAU,UACpC,QAAS,IAAM,KAAKJ,EAAU,QAAA,EAC9B,SAAUA,EAAU,WACpB,aAAY,EAAE,kBAAmB,CAAE,GAAI,SAAU,EAEhD,SAAA,CAAAA,EAAU,iBACNK,EAAA,CAAQ,UAAU,uBAAuB,EAC1CF,EAAAA,IAACG,EAAA,CAAW,UAAU,SAAA,CAAU,QACnC,OAAA,CAAK,UAAU,mBAAoB,SAAA,EAAE,aAAa,CAAA,CAAE,CAAA,CAAA,CAAA,CACvD,EACF,QACC,IAAA,CAAE,UAAU,wBAAyB,SAAA,EAAE,cAAc,EAAE,EAEvDN,EAAU,UACTG,MAAC,OAAI,UAAU,4CAAA,CAA6C,EAE5DD,EAAAA,KAAAK,EAAAA,SAAA,CACE,SAAA,CAAAJ,EAAAA,IAACK,EAAA,CAAY,KAAMR,EAAU,IAAA,CAAM,QAClCS,EAAA,CAAA,CAAc,CAAA,CAAA,CACjB,CAAA,EAEJ,CAEJ,CAIA,SAASD,EAAY,CAAE,KAAAE,GAAsE,CAC3F,KAAM,CAAE,EAAAC,CAAA,EAAMZ,EAAe,CAAC,WAAY,QAAQ,CAAC,EAC7Ca,EAAeC,EAAA,EACfC,EAASC,EAAA,EACT,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SAAiC,CAAA,CAAE,EAE7E,eAAeC,EAASC,EAA6B,CACnD,GAAK,QAAQT,EAAE,oBAAqB,CAAE,KAAAS,CAAA,CAAM,CAAC,EAC7C,GAAI,CACF,MAAMR,EAAa,YAAYQ,CAAI,EACnCC,EAAM,QAAQV,EAAE,mBAAoB,CAAE,KAAAS,CAAA,CAAM,CAAC,CAC/C,OAASE,EAAK,CACZD,EAAM,MAAQC,GAAe,SAAW,OAAOA,CAAG,CAAE,CACtD,CACF,CAEA,eAAeC,EAASH,EAA6B,CACnDH,EAAkBO,IAAO,CAAE,GAAGA,EAAG,CAACJ,CAAI,EAAGT,EAAE,aAAa,CAAA,EAAI,EAC5D,GAAI,CACF,MAAMc,EAAI,MAAMX,EAAO,YAAYM,CAAI,EACjCM,EAAMD,EAAE,UACV,KAAKA,EAAE,YAAc,EACnBd,EAAE,0BAA2B,CAAE,MAAOc,EAAE,SAAA,CAAW,EACnDd,EAAE,uBAAwB,CAAE,MAAOc,EAAE,SAAA,CAAW,CAAC,GACnD,KAAKA,EAAE,WAAad,EAAE,yBAAyB,CAAC,GACpDM,EAAkBO,IAAO,CAAE,GAAGA,EAAG,CAACJ,CAAI,EAAGM,CAAA,EAAM,CACjD,OAASJ,EAAK,CACZL,EAAkBO,IAAO,CAAE,GAAGA,EAAG,CAACJ,CAAI,EAAG,KAAOE,GAAe,SAAW,OAAOA,CAAG,CAAE,IAAK,CAC7F,CACF,CAEA,MAAMK,EAAOjB,GAAM,SAAW,CAAA,EACxBkB,EAAUlB,GAAM,SAAS,SAAW,CAAA,EAC1C,OAAIiB,EAAK,SAAW,QAEf,UAAA,CAAQ,UAAU,mFAChB,SAAAhB,EAAE,kBAAkB,EACvB,EAKFT,EAAAA,KAAC,UAAA,CAAQ,UAAU,6CACjB,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,2DAChB,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,wBAAyB,SAAAQ,EAAE,mBAAoB,CAAE,MAAOgB,EAAK,MAAA,CAAQ,CAAA,CAAE,EACpFjB,GAAM,SACLP,EAAAA,IAAC0B,EAAA,CAAM,QAAQ,OAAQ,SAAAlB,EAAE,iBAAkB,CAAE,MAAOD,EAAK,QAAQ,UAAA,CAAY,CAAA,CAAE,CAAA,EAEnF,SACCoB,EAAA,CACC,SAAA,CAAA3B,EAAAA,IAAC4B,EAAA,CACC,gBAACC,EAAA,CACC,SAAA,CAAA7B,EAAAA,IAAC8B,EAAA,CAAW,SAAAtB,EAAE,cAAc,CAAA,CAAE,EAC9BR,EAAAA,IAAC8B,EAAA,CAAW,SAAAtB,EAAE,mBAAmB,CAAA,CAAE,EACnCR,EAAAA,IAAC8B,EAAA,CAAW,SAAAtB,EAAE,gBAAgB,CAAA,CAAE,EAChCR,EAAAA,IAAC8B,EAAA,CAAW,SAAAtB,EAAE,iBAAiB,CAAA,CAAE,EACjCR,EAAAA,IAAC8B,EAAA,CAAW,SAAAtB,EAAE,iBAAiB,CAAA,CAAE,CAAA,CAAA,CACnC,CAAA,CACF,EACAR,EAAAA,IAAC+B,EAAA,CACE,SAAAP,EAAK,IAAKQ,GAAM,CACf,MAAMC,EAAKR,EAAQ,KAAMH,GAAMA,EAAE,OAASU,EAAE,IAAI,EAC1CE,EAAYC,EAAeH,EAAGxB,CAAC,EAC/B4B,EAASJ,EAAE,QACb,GAAGA,EAAE,OAAO,KAAKA,EAAE,MAAQ,IAAI,KAAK,GAAG,CAAC,GAAG,OAC1CA,EAAE,KAAO,IACRK,EAAgBJ,EAElBA,EAAG,UACDjC,EAAAA,IAAC0B,EAAA,CAAM,QAAQ,UACZ,SAAAO,EAAG,YAAc,EACdzB,EAAE,0BAA2B,CAAE,MAAOyB,EAAG,UAAW,EACpDzB,EAAE,uBAAwB,CAAE,MAAOyB,EAAG,UAAW,EACvD,EACAjC,MAAC0B,EAAA,CAAM,QAAQ,SAAU,SAAAlB,EAAE,yBAAyB,EAAE,QAPvDkB,EAAA,CAAM,QAAQ,UAAW,SAAAlB,EAAE,oBAAoB,EAAE,EAQtD,cACGqB,EAAA,CACC,SAAA,CAAA7B,EAAAA,IAACsC,EAAA,CAAU,UAAU,oBAAqB,SAAAN,EAAE,KAAK,EACjDhC,EAAAA,IAACsC,GAAW,SAAAJ,CAAA,CAAU,EACtBlC,EAAAA,IAACsC,EAAA,CAAU,UAAU,gDAAiD,SAAAF,EAAO,EAC7EpC,EAAAA,IAACsC,GAAW,SAAAD,CAAA,CAAa,EACzBtC,EAAAA,KAACuC,EAAA,CAAU,UAAU,kDACnB,SAAA,CAAAvC,EAAAA,KAACE,EAAA,CACC,QAAQ,QAAQ,KAAK,KACrB,QAAS,IAAM,KAAKmB,EAASY,EAAE,IAAI,EACnC,SAAUrB,EAAO,UAEjB,SAAA,CAAAX,EAAAA,IAACuC,EAAA,CAAS,UAAU,SAAA,CAAU,EAC9BvC,EAAAA,IAAC,OAAA,CAAM,SAAAQ,EAAE,YAAY,CAAA,CAAE,CAAA,CAAA,CAAA,EAEzBT,EAAAA,KAACE,EAAA,CACC,QAAQ,QAAQ,KAAK,KACrB,QAAS,IAAM,KAAKe,EAASgB,EAAE,IAAI,EACnC,SAAUvB,EAAa,UACvB,UAAU,gCAEV,SAAA,CAAAT,EAAAA,IAACwC,EAAA,CAAO,UAAU,SAAA,CAAU,QAC3B,OAAA,CAAK,UAAU,mBAAoB,SAAAhC,EAAE,YAAY,CAAA,CAAE,CAAA,CAAA,CAAA,EAErDK,EAAcmB,EAAE,IAAI,GACnBhC,EAAAA,IAAC,OAAA,CAAK,UAAU,iCAAkC,SAAAa,EAAcmB,EAAE,IAAI,CAAA,CAAE,CAAA,CAAA,CAE5E,CAAA,CAAA,EA1BaA,EAAE,IA2BjB,CAEJ,CAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EACF,CAEJ,CAEA,SAASG,EACPH,EACAxB,EACQ,CACR,OAAIwB,EAAE,QAAgBxB,EAAE,oBAAoB,EACxCwB,EAAE,IAAYA,EAAE,IAAI,SAAS,MAAM,EAAIxB,EAAE,kBAAkB,EAAIA,EAAE,mBAAmB,EACjF,GACT,CAIA,SAASF,GAA6B,CACpC,KAAM,CAAE,CAAA,EAAMV,EAAe,CAAC,WAAY,QAAQ,CAAC,EAC7C6C,EAAYC,EAAA,EACZ,CAACzB,EAAM0B,CAAO,EAAI5B,EAAAA,SAAS,EAAE,EAC7B,CAACmB,EAAWU,CAAY,EAAI7B,EAAAA,SAA2B,OAAO,EAC9D,CAAC8B,EAASC,CAAU,EAAI/B,EAAAA,SAAS,EAAE,EACnC,CAACgC,EAAMC,CAAO,EAAIjC,EAAAA,SAAS,EAAE,EAC7B,CAACkC,EAAKC,CAAM,EAAInC,EAAAA,SAAS,EAAE,EAC3B,CAACoC,EAAaC,CAAc,EAAIrC,EAAAA,SAAS,EAAE,EAEjD,eAAesC,EAASC,EAAmC,CAEzD,GADAA,EAAE,eAAA,EACE,CAACrC,EAAK,OAAQ,CAAEC,EAAM,MAAM,EAAE,kBAAkB,CAAC,EAAG,MAAO,CAC/D,IAAIqC,EACJ,GAAIJ,EAAY,OACd,GAAI,CAAEI,EAAU,KAAK,MAAMJ,CAAW,CAAE,MAClC,CAAEjC,EAAM,MAAM,EAAE,oBAAoB,CAAC,EAAG,MAAO,CAEvD,MAAMsC,EAAoD,CAAE,KAAMvC,EAAK,MAAK,EAC5E,GAAIiB,IAAc,QAAS,CACzB,GAAI,CAACW,EAAQ,OAAQ,CAAE3B,EAAM,MAAM,EAAE,qBAAqB,CAAC,EAAG,MAAO,CACrEsC,EAAK,QAAUX,EAAQ,KAAA,EACvB,MAAMY,EAAYV,EAAK,MAAM,KAAK,EAAE,OAAO,OAAO,EAC9CU,EAAU,OAAS,IAAGD,EAAK,KAAOC,EACxC,KAAO,CACL,GAAI,CAACR,EAAI,OAAQ,CAAE/B,EAAM,MAAM,EAAE,iBAAiB,CAAC,EAAG,MAAO,CAC7DsC,EAAK,IAAMP,EAAI,KAAA,EACXM,MAAc,QAAUA,EAC9B,CACA,GAAI,CACF,MAAMd,EAAU,YAAYe,CAAI,EAChCtC,EAAM,QAAQ,EAAE,iBAAkB,CAAE,KAAMD,EAAK,KAAA,CAAK,CAAG,CAAC,EACxD0B,EAAQ,EAAE,EAAGG,EAAW,EAAE,EAAGE,EAAQ,EAAE,EAAGE,EAAO,EAAE,EAAGE,EAAe,EAAE,CACzE,OAASjC,EAAK,CACZD,EAAM,MAAQC,GAAe,SAAW,OAAOA,CAAG,CAAE,CACtD,CACF,CAEA,OACEpB,EAAAA,KAAC,UAAA,CAAQ,UAAU,6CACjB,SAAA,CAAAC,EAAAA,IAAC,SAAA,CAAO,UAAU,mCAChB,SAAAA,EAAAA,IAAC,KAAA,CAAG,UAAU,wBAAyB,SAAA,EAAE,cAAc,CAAA,CAAE,EAC3D,EACAD,EAAAA,KAAC,OAAA,CAAK,SAAWuD,GAAM,KAAKD,EAASC,CAAC,EAAG,UAAU,4CACjD,SAAA,CAAAvD,OAAC,MAAA,CACC,SAAA,CAAAC,MAAC0D,EAAA,CAAM,UAAU,sBAAuB,SAAA,EAAE,eAAe,EAAE,EAC3D1D,EAAAA,IAAC2D,EAAA,CACC,MAAO1C,EAAM,SAAWqC,GAAMX,EAAQW,EAAE,OAAO,KAAK,EACpD,YAAa,EAAE,qBAAqB,EACpC,UAAU,mBAAA,CAAA,CACZ,EACF,SACC,MAAA,CACC,SAAA,CAAAtD,MAAC0D,EAAA,CAAM,UAAU,sBAAuB,SAAA,EAAE,oBAAoB,EAAE,EAChE3D,EAAAA,KAAC6D,GAAO,MAAO1B,EAAW,cAAgB2B,GAAMjB,EAAaiB,CAAqB,EAChF,SAAA,CAAA7D,EAAAA,IAAC8D,EAAA,CAAc,SAAA9D,EAAAA,IAAC+D,EAAA,CAAA,CAAY,EAAE,SAC7BC,EAAA,CACC,SAAA,CAAAhE,MAACiE,EAAA,CAAW,MAAM,QAAS,SAAA,EAAE,0BAA0B,EAAE,QACxDA,EAAA,CAAW,MAAM,OAAQ,SAAA,EAAE,yBAAyB,CAAA,CAAE,CAAA,CAAA,CACzD,CAAA,CAAA,CACF,CAAA,EACF,EACC/B,IAAc,QACbnC,EAAAA,KAAAK,EAAAA,SAAA,CACE,SAAA,CAAAL,OAAC,MAAA,CACC,SAAA,CAAAC,MAAC0D,EAAA,CAAM,UAAU,sBAAuB,SAAA,EAAE,kBAAkB,EAAE,EAC9D1D,EAAAA,IAAC2D,EAAA,CACC,MAAOd,EAAS,SAAWS,GAAMR,EAAWQ,EAAE,OAAO,KAAK,EAC1D,YAAa,EAAE,wBAAwB,EACvC,UAAU,mBAAA,CAAA,CACZ,EACF,SACC,MAAA,CACC,SAAA,CAAAtD,MAAC0D,EAAA,CAAM,UAAU,sBAAuB,SAAA,EAAE,eAAe,EAAE,EAC3D1D,EAAAA,IAAC2D,EAAA,CACC,MAAOZ,EAAM,SAAWO,GAAMN,EAAQM,EAAE,OAAO,KAAK,EACpD,YAAY,mDACZ,UAAU,mBAAA,CAAA,CACZ,CAAA,CACF,CAAA,CAAA,CACF,EAEAvD,EAAAA,KAAAK,EAAAA,SAAA,CACE,SAAA,CAAAL,EAAAA,KAAC,MAAA,CAAI,UAAU,gBACb,SAAA,CAAAC,MAAC0D,EAAA,CAAM,UAAU,sBAAuB,SAAA,EAAE,cAAc,EAAE,EAC1D1D,EAAAA,IAAC2D,EAAA,CACC,MAAOV,EAAK,SAAWK,GAAMJ,EAAOI,EAAE,OAAO,KAAK,EAClD,YAAa,EAAE,oBAAoB,EACnC,UAAU,mBAAA,CAAA,CACZ,EACF,EACAvD,EAAAA,KAAC,MAAA,CAAI,UAAU,gBACb,SAAA,CAAAC,MAAC0D,EAAA,CAAM,UAAU,sBAAuB,SAAA,EAAE,kBAAkB,EAAE,EAC9D1D,EAAAA,IAAC2D,EAAA,CACC,MAAOR,EAAa,SAAWG,GAAMF,EAAeE,EAAE,OAAO,KAAK,EAClE,YAAa,EAAE,wBAAwB,EACvC,UAAU,mBAAA,CAAA,CACZ,CAAA,CACF,CAAA,EACF,EAEFtD,EAAAA,IAAC,MAAA,CAAI,UAAU,qBACb,SAAAD,EAAAA,KAACE,EAAA,CAAO,KAAK,SAAS,SAAUwC,EAAU,UAAW,UAAU,UAC5D,SAAA,CAAAA,EAAU,gBAAavC,EAAA,CAAQ,UAAU,uBAAuB,EAAKF,EAAAA,IAACkE,EAAA,CAAK,UAAU,SAAA,CAAU,EAC/F,EAAE,eAAe,CAAA,CAAA,CACpB,CAAA,CACF,CAAA,CAAA,CACF,CAAA,EACF,CAEJ","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"mcp-C71xI5JH.js","sources":["../../node_modules/lucide-react/dist/esm/icons/server-cog.js","../../src/routes/settings/mcp.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ServerCog = createLucideIcon(\"ServerCog\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }],\n [\n \"path\",\n {\n d: \"M4.5 10H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-.5\",\n key: \"tn8das\"\n }\n ],\n [\n \"path\",\n {\n d: \"M4.5 14H4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2h-.5\",\n key: \"1g2pve\"\n }\n ],\n [\"path\", { d: \"M6 6h.01\", key: \"1utrut\" }],\n [\"path\", { d: \"M6 18h.01\", key: \"uhywen\" }],\n [\"path\", { d: \"m15.7 13.4-.9-.3\", key: \"1jwmzr\" }],\n [\"path\", { d: \"m9.2 10.9-.9-.3\", key: \"qapnim\" }],\n [\"path\", { d: \"m10.6 15.7.3-.9\", key: \"quwk0k\" }],\n [\"path\", { d: \"m13.6 15.7-.4-1\", key: \"cb9xp7\" }],\n [\"path\", { d: \"m10.8 9.3-.4-1\", key: \"1uaiz5\" }],\n [\"path\", { d: \"m8.3 13.6 1-.4\", key: \"s6srou\" }],\n [\"path\", { d: \"m14.7 10.8 1-.4\", key: \"4d31cq\" }],\n [\"path\", { d: \"m13.4 8.3-.3.9\", key: \"1bm987\" }]\n]);\n\nexport { ServerCog as default };\n//# sourceMappingURL=server-cog.js.map\n","/**\n * /settings/mcp — external MCP servers admin (Stage 6).\n *\n * Front-end for the `/api/mcp/*` REST surface. List configured servers,\n * see their connection status + tool count, add stdio / HTTP / SSE\n * servers, probe per-server health, remove.\n *\n * The native agent loop consumes any tools advertised here; CLI agents\n * have their own MCP configs and ignore this list. See\n * docs/llm-backends.md § External MCP servers.\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Loader2, Plus, RefreshCcw, ServerCog, Trash2, Activity } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select, SelectContent, SelectItem, SelectTrigger, SelectValue,\n} from '@/components/ui/select'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useMcpList, useMcpAddServer, useMcpRemoveServer, useMcpHealth,\n type McpServerRow,\n} from '@/hooks/use-llm-admin'\n\nexport default function SettingsMcpRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const listQuery = useMcpList()\n return (\n <div className=\"mx-auto flex max-w-5xl flex-col gap-6\">\n <header className=\"flex items-center gap-3\">\n <ServerCog className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('mcp.title')}</h1>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('mcp.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('mcp.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <>\n <ServersCard data={listQuery.data} />\n <AddServerCard />\n </>\n )}\n </div>\n )\n}\n\n/* ─────────────── Servers list ─────────────── */\n\nfunction ServersCard({ data }: { data: ReturnType<typeof useMcpList>['data'] }): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const removeServer = useMcpRemoveServer()\n const health = useMcpHealth()\n const [healthResults, setHealthResults] = useState<Record<string, string>>({})\n\n async function onRemove(name: string): Promise<void> {\n if (!confirm(t('mcp.removeConfirm', { name }))) return\n try {\n await removeServer.mutateAsync(name)\n toast.success(t('mcp.removedToast', { name }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n async function onHealth(name: string): Promise<void> {\n setHealthResults((m) => ({ ...m, [name]: t('mcp.probing') }))\n try {\n const r = await health.mutateAsync(name)\n const msg = r.connected\n ? `✓ ${r.toolCount === 1\n ? t('mcp.runtimeConnectedOne', { count: r.toolCount })\n : t('mcp.runtimeConnected', { count: r.toolCount })}`\n : `✗ ${r.lastError ?? t('mcp.runtimeDisconnected')}`\n setHealthResults((m) => ({ ...m, [name]: msg }))\n } catch (err) {\n setHealthResults((m) => ({ ...m, [name]: `✗ ${((err as Error)?.message ?? String(err))}` }))\n }\n }\n\n const rows = data?.servers ?? []\n const runtime = data?.runtime?.servers ?? []\n if (rows.length === 0) {\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('mcp.serversEmpty')}\n </section>\n )\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"flex items-center gap-2 border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('mcp.serversTitle', { count: rows.length })}</h2>\n {data?.runtime && (\n <Badge variant=\"info\">{t('mcp.totalTools', { count: data.runtime.totalTools })}</Badge>\n )}\n </header>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('mcp.col.name')}</TableHead>\n <TableHead>{t('mcp.col.transport')}</TableHead>\n <TableHead>{t('mcp.col.target')}</TableHead>\n <TableHead>{t('mcp.col.runtime')}</TableHead>\n <TableHead>{t('mcp.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((s) => {\n const rt = runtime.find((r) => r.name === s.name)\n const transport = transportLabel(s, t)\n const target = s.command\n ? `${s.command} ${(s.args ?? []).join(' ')}`.trim()\n : (s.url ?? '—')\n const runtimeBadge = !rt\n ? <Badge variant=\"outline\">{t('mcp.runtimeUnknown')}</Badge>\n : rt.connected\n ? <Badge variant=\"success\">\n {rt.toolCount === 1\n ? t('mcp.runtimeConnectedOne', { count: rt.toolCount })\n : t('mcp.runtimeConnected', { count: rt.toolCount })}\n </Badge>\n : <Badge variant=\"danger\">{t('mcp.runtimeDisconnected')}</Badge>\n return (\n <TableRow key={s.name}>\n <TableCell className=\"font-mono text-xs\">{s.name}</TableCell>\n <TableCell>{transport}</TableCell>\n <TableCell className=\"break-all font-mono text-[11px] text-text-dim\">{target}</TableCell>\n <TableCell>{runtimeBadge}</TableCell>\n <TableCell className=\"flex flex-col gap-1 sm:flex-row sm:items-center\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onHealth(s.name)}\n disabled={health.isPending}\n >\n <Activity className=\"h-4 w-4\" />\n <span>{t('mcp.health')}</span>\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onRemove(s.name)}\n disabled={removeServer.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <Trash2 className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{t('mcp.remove')}</span>\n </Button>\n {healthResults[s.name] && (\n <span className=\"ml-2 text-[11px] text-text-dim\">{healthResults[s.name]}</span>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )\n}\n\nfunction transportLabel(\n s: McpServerRow,\n t: (key: string) => string,\n): string {\n if (s.command) return t('mcp.transportStdio')\n if (s.url) return s.url.endsWith('/sse') ? t('mcp.transportSse') : t('mcp.transportHttp')\n return '—'\n}\n\n/* ─────────────── Add server form ─────────────── */\n\nfunction AddServerCard(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const addServer = useMcpAddServer()\n const [name, setName] = useState('')\n const [transport, setTransport] = useState<'stdio' | 'http'>('stdio')\n const [command, setCommand] = useState('')\n const [args, setArgs] = useState('')\n const [url, setUrl] = useState('')\n const [headersJson, setHeadersJson] = useState('')\n\n async function onSubmit(e: React.FormEvent): Promise<void> {\n e.preventDefault()\n if (!name.trim()) { toast.error(t('mcp.nameRequired')); return }\n let headers: Record<string, string> | undefined\n if (headersJson.trim()) {\n try { headers = JSON.parse(headersJson) }\n catch { toast.error(t('mcp.headersInvalid')); return }\n }\n const body: Parameters<typeof addServer.mutateAsync>[0] = { name: name.trim() }\n if (transport === 'stdio') {\n if (!command.trim()) { toast.error(t('mcp.commandRequired')); return }\n body.command = command.trim()\n const splitArgs = args.split(/\\s+/).filter(Boolean)\n if (splitArgs.length > 0) body.args = splitArgs\n } else {\n if (!url.trim()) { toast.error(t('mcp.urlRequired')); return }\n body.url = url.trim()\n if (headers) body.headers = headers\n }\n try {\n await addServer.mutateAsync(body)\n toast.success(t('mcp.addedToast', { name: name.trim() }))\n setName(''); setCommand(''); setArgs(''); setUrl(''); setHeadersJson('')\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n return (\n <section className=\"rounded-md border border-border bg-surface\">\n <header className=\"border-b border-border px-4 py-3\">\n <h2 className=\"text-sm font-semibold\">{t('mcp.addTitle')}</h2>\n </header>\n <form onSubmit={(e) => void onSubmit(e)} className=\"grid grid-cols-1 gap-3 p-4 sm:grid-cols-2\">\n <div>\n <Label className=\"text-xs font-medium\">{t('mcp.nameLabel')}</Label>\n <Input\n value={name} onChange={(e) => setName(e.target.value)}\n placeholder={t('mcp.namePlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('mcp.transportLabel')}</Label>\n <Select value={transport} onValueChange={(v) => setTransport(v as 'stdio' | 'http')}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"stdio\">{t('mcp.transportStdioOption')}</SelectItem>\n <SelectItem value=\"http\">{t('mcp.transportHttpOption')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n {transport === 'stdio' ? (\n <>\n <div>\n <Label className=\"text-xs font-medium\">{t('mcp.commandLabel')}</Label>\n <Input\n value={command} onChange={(e) => setCommand(e.target.value)}\n placeholder={t('mcp.commandPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div>\n <Label className=\"text-xs font-medium\">{t('mcp.argsLabel')}</Label>\n <Input\n value={args} onChange={(e) => setArgs(e.target.value)}\n placeholder=\"-y @modelcontextprotocol/server-filesystem /data\"\n className=\"font-mono text-xs\"\n />\n </div>\n </>\n ) : (\n <>\n <div className=\"sm:col-span-2\">\n <Label className=\"text-xs font-medium\">{t('mcp.urlLabel')}</Label>\n <Input\n value={url} onChange={(e) => setUrl(e.target.value)}\n placeholder={t('mcp.urlPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n <div className=\"sm:col-span-2\">\n <Label className=\"text-xs font-medium\">{t('mcp.headersLabel')}</Label>\n <Input\n value={headersJson} onChange={(e) => setHeadersJson(e.target.value)}\n placeholder={t('mcp.headersPlaceholder')}\n className=\"font-mono text-xs\"\n />\n </div>\n </>\n )}\n <div className=\"sm:col-span-2 flex\">\n <Button type=\"submit\" disabled={addServer.isPending} className=\"ml-auto\">\n {addServer.isPending ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Plus className=\"h-4 w-4\" />}\n {t('mcp.addServer')}\n </Button>\n </div>\n </form>\n </section>\n )\n}\n"],"names":["ServerCog","createLucideIcon","SettingsMcpRoute","useTranslation","listQuery","useMcpList","jsxs","jsx","Button","Loader2","RefreshCcw","Fragment","ServersCard","AddServerCard","data","t","removeServer","useMcpRemoveServer","health","useMcpHealth","healthResults","setHealthResults","useState","onRemove","name","toast","err","onHealth","m","r","msg","rows","runtime","Badge","Table","TableHeader","TableRow","TableHead","TableBody","s","rt","transport","transportLabel","target","runtimeBadge","TableCell","Activity","Trash2","addServer","useMcpAddServer","setName","setTransport","command","setCommand","args","setArgs","url","setUrl","headersJson","setHeadersJson","onSubmit","e","headers","body","splitArgs","Label","Input","Select","v","SelectTrigger","SelectValue","SelectContent","SelectItem","Plus"],"mappings":"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","x_google_ignoreList":[0]}
|