bazilion 0.12.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cli.js +795 -240
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +4555 -1280
- package/dist/daemon.js.map +1 -1
- package/dist/migrations/0001_init.sql +21 -0
- package/dist/web/client/assets/AgentTabs-BcmmwYJc.js +1 -0
- package/dist/web/client/assets/ConfigPage-BCLp-FUC.js +1 -0
- package/dist/web/client/assets/ConfirmDialog-CyL9A20V.js +1 -0
- package/dist/web/client/assets/FieldRow-D6REbYUa.js +1 -0
- package/dist/web/client/assets/Page-NV96O47A.js +1 -0
- package/dist/web/client/assets/ProductionTeamPolicyEditor-DBKnOezm.js +7 -0
- package/dist/web/client/assets/{ProfileCommunicationEditor-C43HvUe-.js → ProfileCommunicationEditor-4RK2laqO.js} +1 -1
- package/dist/web/client/assets/SectionTabs-4kCQXuFY.js +1 -0
- package/dist/web/client/assets/TeamTabs-CdtNEqt4.js +1 -0
- package/dist/web/client/assets/{TemplatesTabs-6Jd_xQj7.js → TemplatesTabs-CZyss2Y0.js} +1 -1
- package/dist/web/client/assets/UnsavedChangesGuard-CEoK-ZcN.js +1 -0
- package/dist/web/client/assets/_id-4ZS-w_Aj.js +1 -0
- package/dist/web/client/assets/{_id-AOAT0H_5.js → _id-DIqtdQij.js} +1 -1
- package/dist/web/client/assets/_id-DbcC2E7F.js +1 -0
- package/dist/web/client/assets/_id-f_r5M0p3.js +1 -0
- package/dist/web/client/assets/activity-CB9Ufth-.js +1 -0
- package/dist/web/client/assets/agents-D-JGXVg9.js +1 -0
- package/dist/web/client/assets/agents-DS2XafoA.js +1 -0
- package/dist/web/client/assets/approvals-Cke_mrJv.js +1 -0
- package/dist/web/client/assets/attention-PYwRM2wC.js +1 -0
- package/dist/web/client/assets/chevron-right-BG4OeFRQ.js +1 -0
- package/dist/web/client/assets/config-DF9Gqmfa.js +3 -0
- package/dist/web/client/assets/dm-sans-latin-400-normal-BwCSEQnW.woff +0 -0
- package/dist/web/client/assets/dm-sans-latin-400-normal-CW0RaeGs.woff2 +0 -0
- package/dist/web/client/assets/dm-sans-latin-500-normal-B9HHJjqV.woff2 +0 -0
- package/dist/web/client/assets/dm-sans-latin-500-normal-Dr3UlScf.woff +0 -0
- package/dist/web/client/assets/dm-sans-latin-600-normal-Aqo67rzb.woff2 +0 -0
- package/dist/web/client/assets/dm-sans-latin-600-normal-BmdmIIQ2.woff +0 -0
- package/dist/web/client/assets/dm-sans-latin-700-normal-CUSSCpQX.woff +0 -0
- package/dist/web/client/assets/dm-sans-latin-700-normal-DvUfVpUG.woff2 +0 -0
- package/dist/web/client/assets/dm-serif-display-latin-400-normal-C5_t9oOD.woff2 +0 -0
- package/dist/web/client/assets/dm-serif-display-latin-400-normal-_kVFYEpx.woff +0 -0
- package/dist/web/client/assets/{inbox-Bn1GbUsJ.js → inbox-DC_HdOfI.js} +1 -1
- package/dist/web/client/assets/index-Cofc7zhl.css +1 -0
- package/dist/web/client/assets/index-Cp6UHWr2.js +52 -0
- package/dist/web/client/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- package/dist/web/client/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/dist/web/client/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- package/dist/web/client/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
- package/dist/web/client/assets/learning-BfrQ4YZY.js +1 -0
- package/dist/web/client/assets/login-D4n3AcBR.js +1 -0
- package/dist/web/client/assets/mcp-CnjQc_JJ.js +1 -0
- package/dist/web/client/assets/members-wxsVTJdW.js +1 -0
- package/dist/web/client/assets/memory-Du60O3pE.js +1 -0
- package/dist/web/client/assets/{policy-DaijITy7.js → policy-BOfnkJsL.js} +1 -1
- package/dist/web/client/assets/{preload-helper-mNuBjNXU.js → preload-helper-bztXdkDj.js} +1 -1
- package/dist/web/client/assets/routes-B9CuhzUW.js +1 -0
- package/dist/web/client/assets/services-DyvqJqM2.js +1 -0
- package/dist/web/client/assets/skills-DQo7ioW7.js +1 -0
- package/dist/web/client/assets/styles-B5vcgXln.css +2 -0
- package/dist/web/client/assets/{teams-D92R9Pb7.js → teams-DPggy97H.js} +1 -1
- package/dist/web/client/assets/teams-DdawcfNR.js +1 -0
- package/dist/web/client/assets/telegram-DcTeDpP5.js +1 -0
- package/dist/web/client/assets/tokens-CIEKwZXc.js +1 -0
- package/dist/web/client/assets/triggers-Bc2RrUPm.js +1 -0
- package/dist/web/client/assets/utils-B6KiDbIe.js +1 -0
- package/dist/web/client/assets/welcome-DlhNXUIa.js +1 -0
- package/dist/web/client/assets/wire-constants-BzdHSc6A.js +74 -0
- package/dist/web/client/assets/x-DAXGIe_Q.js +1 -0
- package/dist/web/server/assets/{AgentTabs-aXdsiiMp.js → AgentTabs-Dq8hDM2Q.js} +9 -2
- package/dist/web/server/assets/{ChatPane-Ba5wTsVk.js → ChatPane-CgSe7tsy.js} +81 -43
- package/dist/web/server/assets/{ConfigPage-BKlh5vOU.js → ConfigPage-CiQ-gxmJ.js} +3 -2
- package/dist/web/server/assets/ConfirmDialog-C-MPYYSU.js +99 -0
- package/dist/web/server/assets/FieldRow-DCOF07kl.js +160 -0
- package/dist/web/server/assets/{Page-LENulSXY.js → Page-Bz-ydB8j.js} +4 -10
- package/dist/web/server/assets/{ProductionTeamPolicyEditor-Y4mzFFvR.js → ProductionTeamPolicyEditor-DQSdP7Yx.js} +140 -123
- package/dist/web/server/assets/{SectionTabs-BJTPr5nU.js → SectionTabs-B2Yw81XN.js} +2 -2
- package/dist/web/server/assets/{Sidebar-DsRVCszF.js → Sidebar-DKyk7oIo.js} +563 -283
- package/dist/web/server/assets/{TeamTabs-zZzbP1t_.js → TeamTabs-Co3n2exj.js} +2 -6
- package/dist/web/server/assets/{TemplatesTabs-CcRxZhJe.js → TemplatesTabs-B0fA361R.js} +1 -1
- package/dist/web/server/assets/UnsavedChangesGuard-CiStXyBI.js +40 -0
- package/dist/web/server/assets/{_id-Dj1yZ3zJ.js → _id-BAA9KJBU.js} +4 -4
- package/dist/web/server/assets/{_id-LrvXU4Nr.js → _id-BM5m2FLT.js} +4 -4
- package/dist/web/server/assets/{_id-CwyGjJeP.js → _id-BYKpT2Tu.js} +4 -5
- package/dist/web/server/assets/{_id-BHYLL8M-.js → _id-BeKhPKw3.js} +350 -185
- package/dist/web/server/assets/{_id-C3HY4lWg.js → _id-BqWTB8Wl.js} +188 -86
- package/dist/web/server/assets/{_id-DinTp_7X.js → _id-BwvCtzlD.js} +3 -3
- package/dist/web/server/assets/{_id-D27T85mU.js → _id-DYU6uIBx.js} +4 -5
- package/dist/web/server/assets/{_id-IzadFZV9.js → _id-DvlDkk04.js} +4 -4
- package/dist/web/server/assets/{_id-BhOB8Umi.js → _id-DxCnEFpm.js} +4 -4
- package/dist/web/server/assets/{_id-tB47Vsfp.js → _id-HMy7jM3P.js} +3 -3
- package/dist/web/server/assets/{_id-D3Ap7zZA.js → _id-ndxFHx0t.js} +75 -71
- package/dist/web/server/assets/{_id-FcHdSocl.js → _id-sNu5aXZt.js} +5 -4
- package/dist/web/server/assets/{_tanstack-start-manifest_v-BGDBdnUs.js → _tanstack-start-manifest_v-C-OiOZeM.js} +118 -94
- package/dist/web/server/assets/{activity-DohitgwW.js → activity-9VP6QDTH.js} +3 -3
- package/dist/web/server/assets/{activity-BCI4mfNS.js → activity-BWv1goK6.js} +3 -3
- package/dist/web/server/assets/{activity-D9SMqBhy.js → activity-LjpblbDL.js} +3 -3
- package/dist/web/server/assets/{agents-C9xlWK0Z.js → agents-BDFGrU3o.js} +4 -4
- package/dist/web/server/assets/{agents-BY74v7fM.js → agents-BJAv919x.js} +3 -3
- package/dist/web/server/assets/{agents-BvttypqB.js → agents-CJk4pxKu.js} +3 -3
- package/dist/web/server/assets/{agents-CgZMHj80.js → agents-CYw1xHoY.js} +138 -16
- package/dist/web/server/assets/{agents-DZuFEj0D.js → agents-DfNKc_Q7.js} +52 -8
- package/dist/web/server/assets/{agents-BPKOshR5.js → agents-DjyQk94u.js} +4 -4
- package/dist/web/server/assets/{approvals-CWcFHlor.js → approvals-7JOoBchn.js} +3 -3
- package/dist/web/server/assets/{approvals-BGU-XGIO.js → approvals-BYi84gwl.js} +3 -3
- package/dist/web/server/assets/{approvals-DCaVw1Mz.js → approvals-Bz123liE.js} +59 -21
- package/dist/web/server/assets/{attention-BxkTf337.js → attention-B35JvhOL.js} +3 -3
- package/dist/web/server/assets/{attention-w21GQIGH.js → attention-C1pPWSXw.js} +3 -3
- package/dist/web/server/assets/{attention-CM-Ks1N9.js → attention-UhqPK_Ro.js} +3 -3
- package/dist/web/server/assets/{auth-byfSx6Ja.js → auth-7BHTH-KS.js} +5 -5
- package/dist/web/server/assets/{config-BDCJdtj2.js → config-BMiajTZP.js} +10 -5
- package/dist/web/server/assets/{config-1w2GiJUn.js → config-BlMkHStx.js} +3 -3
- package/dist/web/server/assets/config-ExacOzHX.js +958 -0
- package/dist/web/server/assets/{createServerRpc-pU-IQV2Y.js → createServerRpc-B7Yr1K8i.js} +1 -1
- package/dist/web/server/assets/{createSsrRpc-DFsIAfFd.js → createSsrRpc-6LHNEsSK.js} +1 -1
- package/dist/web/server/assets/{daemon-client-2NRMzlTr.js → daemon-client-CI5NHwNC.js} +16 -4
- package/dist/web/server/assets/{inbox-CzlKT9Wg.js → inbox-Dv55rGYq.js} +4 -4
- package/dist/web/server/assets/{inbox-BLUzA5sQ.js → inbox-RweGCV3D.js} +3 -3
- package/dist/web/server/assets/{inbox-ZvDNAjaM.js → inbox-cu3jLzNP.js} +4 -4
- package/dist/web/server/assets/{learning-B7PBkvER.js → learning-BaKM6qaw.js} +4 -4
- package/dist/web/server/assets/{learning-8zav4pIT.js → learning-C2upa1CE.js} +4 -4
- package/dist/web/server/assets/{learning-Cq7K2heb.js → learning-CbtNlqYo.js} +76 -23
- package/dist/web/server/assets/{login-CmWvxfTK.js → login-BNj3U6ok.js} +22 -12
- package/dist/web/server/assets/{login-Bx5LEyGP.js → login-Be8eP4Jp.js} +2 -2
- package/dist/web/server/assets/{mcp-DIWTogHM.js → mcp-B0goWO8Q.js} +3 -3
- package/dist/web/server/assets/{mcp-2pwT9HU8.js → mcp-BvnvlVFd.js} +3 -3
- package/dist/web/server/assets/mcp-CiBs8unU.js +332 -0
- package/dist/web/server/assets/members-BP3UTqu1.js +12 -0
- package/dist/web/server/assets/members-DHYTVgwb.js +100 -0
- package/dist/web/server/assets/members-DiYtr-zm.js +12 -0
- package/dist/web/server/assets/{memory-Dngc13Nw.js → memory-BqV-Afy1.js} +4 -4
- package/dist/web/server/assets/{memory-a8Kz57Kh.js → memory-CkXUgf5s.js} +150 -48
- package/dist/web/server/assets/{memory-pZ4pZT7p.js → memory-DTFEmfF3.js} +4 -4
- package/dist/web/server/assets/{policy-Bb-vEgqg.js → policy-18fdTFO4.js} +3 -3
- package/dist/web/server/assets/{policy-C30AeFIb.js → policy-BddK4xom.js} +3 -3
- package/dist/web/server/assets/{policy-BcGELcc9.js → policy-Bvvav8fh.js} +4 -4
- package/dist/web/server/assets/public-origin-xV0lm0Ty.js +25 -0
- package/dist/web/server/assets/router-pjH2t8Rl.js +813 -0
- package/dist/web/server/assets/{routes-B6cMLIPk.js → routes-BgHisAxH.js} +22 -5
- package/dist/web/server/assets/{routes-BrA-U_Hm.js → routes-COtkyZG1.js} +5 -5
- package/dist/web/server/assets/{routes-C19CMLZt.js → routes-DAU2g7Uz.js} +4 -4
- package/dist/web/server/assets/services-ClyGBU7W.js +83 -0
- package/dist/web/server/assets/{services-C4szdhPx.js → services-DgoU1udp.js} +3 -3
- package/dist/web/server/assets/{services-wG8I06oS.js → services-DozuJtzX.js} +3 -3
- package/dist/web/server/assets/{skills-BZdqiDig.js → skills-CYih9TJw.js} +47 -6
- package/dist/web/server/assets/{skills-a9VSWHWq.js → skills-DfGSJTCB.js} +3 -3
- package/dist/web/server/assets/{skills-C-UgkuCW.js → skills-Dw3cI3si.js} +3 -3
- package/dist/web/server/assets/start-D4Wq9iTa.js +70 -0
- package/dist/web/server/assets/{teams-OIkHuxy1.js → teams-BJuoNOTB.js} +3 -3
- package/dist/web/server/assets/{teams-CpQ0YgWf.js → teams-DF3RViAg.js} +3 -3
- package/dist/web/server/assets/{teams-DEpQR2QA.js → teams-DFnuc660.js} +3 -3
- package/dist/web/server/assets/{teams-DqfrEoH6.js → teams-DPnAX4wD.js} +4 -4
- package/dist/web/server/assets/{teams-jBtvnk59.js → teams-TV6nbEN_.js} +101 -10
- package/dist/web/server/assets/{teams-MjqgsmC3.js → teams-be05ci17.js} +3 -3
- package/dist/web/server/assets/{telegram-DNgCWebD.js → telegram-1AWL6lFw.js} +3 -3
- package/dist/web/server/assets/{telegram-XwyKSEtj.js → telegram-DbOFpTFm.js} +3 -3
- package/dist/web/server/assets/{telegram-CBF8SJzB.js → telegram-Dj4Wwhd6.js} +262 -43
- package/dist/web/server/assets/tokens-DDwtO15P.js +359 -0
- package/dist/web/server/assets/tokens-DjM8GsgS.js +19 -0
- package/dist/web/server/assets/{tokens-BnwFbV7T.js → tokens-_2hptHP6.js} +4 -4
- package/dist/web/server/assets/{triggers-BZPl5CHs.js → triggers-BvjYNmmY.js} +4 -4
- package/dist/web/server/assets/triggers-CHk9O3rU.js +367 -0
- package/dist/web/server/assets/{triggers-D79NoSXk.js → triggers-Nezfw-Bd.js} +4 -4
- package/dist/web/server/assets/utils-C_uf36nf.js +8 -0
- package/dist/web/server/assets/{welcome-DDB11L5j.js → welcome-B8nchXdF.js} +9 -8
- package/dist/web/server/server.js +29 -33
- package/dist/web-server.js +4 -0
- package/dist/web-server.js.map +1 -1
- package/dist/worker.js +1744 -362
- package/dist/worker.js.map +1 -1
- package/package.json +7 -6
- package/dist/web/client/assets/AgentTabs-R6gSjIj3.js +0 -1
- package/dist/web/client/assets/ConfigPage-BCwfgyjD.js +0 -1
- package/dist/web/client/assets/FieldRow-avAFLgYW.js +0 -1
- package/dist/web/client/assets/Page-CwNuDhWz.js +0 -1
- package/dist/web/client/assets/ProductionTeamPolicyEditor-CsWpTsy6.js +0 -7
- package/dist/web/client/assets/SectionTabs-DZzy01az.js +0 -1
- package/dist/web/client/assets/TeamTabs-DvqWieCq.js +0 -1
- package/dist/web/client/assets/_id-BUuz7Drv.js +0 -1
- package/dist/web/client/assets/_id-BegmVRmT.js +0 -1
- package/dist/web/client/assets/_id-BrA4Crh_.js +0 -1
- package/dist/web/client/assets/activity-n0Fw9_w3.js +0 -1
- package/dist/web/client/assets/agents-B33VQtbl.js +0 -1
- package/dist/web/client/assets/agents-C50pdxp7.js +0 -1
- package/dist/web/client/assets/approvals-DVW0hX8h.js +0 -1
- package/dist/web/client/assets/attention-B2490jcN.js +0 -1
- package/dist/web/client/assets/chevron-down-B0aNNOyn.js +0 -1
- package/dist/web/client/assets/config-CMMxxeX2.js +0 -3
- package/dist/web/client/assets/context-DcFzsfZ3.js +0 -1
- package/dist/web/client/assets/index-3nrK5iFr.js +0 -12
- package/dist/web/client/assets/learning-BUX1MFu2.js +0 -1
- package/dist/web/client/assets/login-CMWpGDKv.js +0 -1
- package/dist/web/client/assets/mcp-lZV08dqc.js +0 -1
- package/dist/web/client/assets/members-DAeaY2Cy.js +0 -1
- package/dist/web/client/assets/memory-HmMWxxdF.js +0 -1
- package/dist/web/client/assets/plus-CPzRJg1V.js +0 -1
- package/dist/web/client/assets/routes-BNk270AM.js +0 -1
- package/dist/web/client/assets/services-DtrpJrdo.js +0 -1
- package/dist/web/client/assets/skills-Cv93A3P3.js +0 -1
- package/dist/web/client/assets/styles-DMltY3su.css +0 -2
- package/dist/web/client/assets/teams-CCFnSNKi.js +0 -1
- package/dist/web/client/assets/telegram-BF1vdgDB.js +0 -1
- package/dist/web/client/assets/tokens-BXj6hWW-.js +0 -1
- package/dist/web/client/assets/triggers-NT24i4hZ.js +0 -1
- package/dist/web/client/assets/welcome-D0cy68eZ.js +0 -1
- package/dist/web/client/assets/wire-constants-BhVKOCQa.js +0 -74
- package/dist/web/server/assets/FieldRow-B4eTegH9.js +0 -94
- package/dist/web/server/assets/config-BmixCpz-.js +0 -372
- package/dist/web/server/assets/context-B-XDf6Ym.js +0 -12
- package/dist/web/server/assets/context-BXGo5Vfi.js +0 -12
- package/dist/web/server/assets/context-DrkrIWun.js +0 -47
- package/dist/web/server/assets/mcp-BJjLIdP0.js +0 -261
- package/dist/web/server/assets/members-CCv17cjQ.js +0 -46
- package/dist/web/server/assets/members-CW5aBe81.js +0 -12
- package/dist/web/server/assets/members-VdPwD6CE.js +0 -12
- package/dist/web/server/assets/router-CIVjTgNp.js +0 -537
- package/dist/web/server/assets/services-B9yBWDX0.js +0 -79
- package/dist/web/server/assets/start-WH8WzTL_.js +0 -4
- package/dist/web/server/assets/tokens-DPDMSN5O.js +0 -12
- package/dist/web/server/assets/tokens-yyTSfBSN.js +0 -186
- package/dist/web/server/assets/triggers-CSNNzRIi.js +0 -216
|
@@ -0,0 +1,958 @@
|
|
|
1
|
+
import { t as Route } from "./config-BlMkHStx.js";
|
|
2
|
+
import { a as StatusBadge$1, t as EmptyState } from "./Page-Bz-ydB8j.js";
|
|
3
|
+
import { t as Button } from "./Button-Dsnw22OF.js";
|
|
4
|
+
import { t as ConfirmDialog } from "./ConfirmDialog-C-MPYYSU.js";
|
|
5
|
+
import { t as ConfigPage } from "./ConfigPage-CiQ-gxmJ.js";
|
|
6
|
+
import { t as FieldRow } from "./FieldRow-DCOF07kl.js";
|
|
7
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { useRouter } from "@tanstack/react-router";
|
|
9
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { CheckCircle2, ChevronDown, ChevronRight, Search, Server, ShieldCheck } from "lucide-react";
|
|
11
|
+
//#region src/components/ExecutionSecurityCard.tsx
|
|
12
|
+
function ExecutionSecurityCard({ status }) {
|
|
13
|
+
const configured = status.configuredOperatorHttp;
|
|
14
|
+
const protectedTurns = status.protectedUnattendedTurns;
|
|
15
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
16
|
+
className: "overflow-hidden rounded-lg border bg-card",
|
|
17
|
+
children: [/* @__PURE__ */ jsxs("header", {
|
|
18
|
+
className: "border-b px-4 py-3",
|
|
19
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
20
|
+
className: "font-semibold",
|
|
21
|
+
children: "Execution security"
|
|
22
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
23
|
+
className: "mt-1 text-xs text-muted-foreground",
|
|
24
|
+
children: "Operator HTTP requests keep their configured compatibility behavior. Unattended sources use a separate mandatory protected baseline."
|
|
25
|
+
})]
|
|
26
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
27
|
+
className: "grid gap-4 p-4 lg:grid-cols-2",
|
|
28
|
+
children: [/* @__PURE__ */ jsxs("section", {
|
|
29
|
+
className: "rounded-md border bg-muted/20 p-3",
|
|
30
|
+
children: [
|
|
31
|
+
/* @__PURE__ */ jsxs("div", {
|
|
32
|
+
className: "mb-3 flex flex-wrap items-center justify-between gap-2",
|
|
33
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
34
|
+
className: "font-semibold",
|
|
35
|
+
children: "Configured operator HTTP"
|
|
36
|
+
}), /* @__PURE__ */ jsx(StatusBadge, {
|
|
37
|
+
ok: false,
|
|
38
|
+
children: "legacy · unprotected"
|
|
39
|
+
})]
|
|
40
|
+
}),
|
|
41
|
+
/* @__PURE__ */ jsxs("dl", {
|
|
42
|
+
className: "space-y-2 text-sm",
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
45
|
+
label: "Coding surface",
|
|
46
|
+
value: codingSurfaceLabel(configured.codingSurface)
|
|
47
|
+
}),
|
|
48
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
49
|
+
label: "Docker image",
|
|
50
|
+
value: configured.dockerImage,
|
|
51
|
+
mono: true
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
54
|
+
label: "Browser",
|
|
55
|
+
value: configured.browser
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
58
|
+
label: "MCP",
|
|
59
|
+
value: configured.mcp
|
|
60
|
+
})
|
|
61
|
+
]
|
|
62
|
+
}),
|
|
63
|
+
/* @__PURE__ */ jsx("p", {
|
|
64
|
+
className: "mt-3 text-xs text-muted-foreground",
|
|
65
|
+
children: "This compatibility branch is for operator requests; Telegram and unattended delivery never select it."
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
}), /* @__PURE__ */ jsxs("section", {
|
|
69
|
+
className: `rounded-md border p-3 ${protectedTurns.baseRuntimeReady ? "border-success/25 bg-success/5" : "border-warning/25 bg-warning/10"}`,
|
|
70
|
+
children: [
|
|
71
|
+
/* @__PURE__ */ jsxs("div", {
|
|
72
|
+
className: "mb-3 flex flex-wrap items-center justify-between gap-2",
|
|
73
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
74
|
+
className: "font-semibold",
|
|
75
|
+
children: "Protected unattended turns"
|
|
76
|
+
}), /* @__PURE__ */ jsx(StatusBadge, {
|
|
77
|
+
ok: protectedTurns.baseRuntimeReady,
|
|
78
|
+
children: protectedTurns.baseRuntimeReady ? "base runtime ready" : "base runtime unavailable"
|
|
79
|
+
})]
|
|
80
|
+
}),
|
|
81
|
+
/* @__PURE__ */ jsx("p", {
|
|
82
|
+
className: "mb-3 text-xs text-muted-foreground",
|
|
83
|
+
children: "Telegram, schedules, inbox wake-ups, and approval delivery cannot select the legacy surface."
|
|
84
|
+
}),
|
|
85
|
+
/* @__PURE__ */ jsxs("dl", {
|
|
86
|
+
className: "space-y-2 text-sm",
|
|
87
|
+
children: [
|
|
88
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
89
|
+
label: "Coding surface",
|
|
90
|
+
value: "Docker only"
|
|
91
|
+
}),
|
|
92
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
93
|
+
label: "Docker",
|
|
94
|
+
value: protectedTurns.docker.ready ? "ready" : "unavailable",
|
|
95
|
+
ok: protectedTurns.docker.ready
|
|
96
|
+
}),
|
|
97
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
98
|
+
label: "Docker image",
|
|
99
|
+
value: protectedTurns.docker.image,
|
|
100
|
+
mono: true
|
|
101
|
+
}),
|
|
102
|
+
protectedTurns.docker.reason && /* @__PURE__ */ jsx(StatusRow, {
|
|
103
|
+
label: "Docker reason",
|
|
104
|
+
value: protectedTurns.docker.reason
|
|
105
|
+
}),
|
|
106
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
107
|
+
label: "OpenAI Codex enabled",
|
|
108
|
+
value: yesNo(protectedTurns.openaiCodex.enabled),
|
|
109
|
+
ok: protectedTurns.openaiCodex.enabled
|
|
110
|
+
}),
|
|
111
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
112
|
+
label: "ChatGPT connected",
|
|
113
|
+
value: yesNo(protectedTurns.openaiCodex.connected),
|
|
114
|
+
ok: protectedTurns.openaiCodex.connected
|
|
115
|
+
}),
|
|
116
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
117
|
+
label: "OpenAI access",
|
|
118
|
+
value: openAIAccessLabel(protectedTurns.openaiCodex),
|
|
119
|
+
ok: protectedTurns.openaiCodex.accessCurrent || protectedTurns.openaiCodex.refreshOnNextTurn
|
|
120
|
+
}),
|
|
121
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
122
|
+
label: "OpenAI Codex baseline eligible",
|
|
123
|
+
value: yesNo(protectedTurns.openaiCodex.baselineEligible),
|
|
124
|
+
ok: protectedTurns.openaiCodex.baselineEligible
|
|
125
|
+
}),
|
|
126
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
127
|
+
label: "Browser",
|
|
128
|
+
value: protectedTurns.browser,
|
|
129
|
+
ok: true
|
|
130
|
+
}),
|
|
131
|
+
/* @__PURE__ */ jsx(StatusRow, {
|
|
132
|
+
label: "MCP",
|
|
133
|
+
value: protectedTurns.mcp,
|
|
134
|
+
ok: true
|
|
135
|
+
})
|
|
136
|
+
]
|
|
137
|
+
}),
|
|
138
|
+
protectedTurns.remediation && /* @__PURE__ */ jsxs("p", {
|
|
139
|
+
className: "mt-3 rounded-md border border-warning/25 bg-background/60 px-3 py-2 text-xs text-warning",
|
|
140
|
+
children: [
|
|
141
|
+
/* @__PURE__ */ jsx("strong", { children: "Remediation:" }),
|
|
142
|
+
" ",
|
|
143
|
+
protectedTurns.remediation
|
|
144
|
+
]
|
|
145
|
+
}),
|
|
146
|
+
/* @__PURE__ */ jsx("p", {
|
|
147
|
+
className: "mt-3 text-xs text-muted-foreground",
|
|
148
|
+
children: "Every turn separately validates its selected normal/review model, bound OAuth refresh, and Team/input/memory/skill mounts and paths before execution."
|
|
149
|
+
})
|
|
150
|
+
]
|
|
151
|
+
})]
|
|
152
|
+
})]
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function StatusBadge({ ok, children }) {
|
|
156
|
+
return /* @__PURE__ */ jsx("span", {
|
|
157
|
+
className: `rounded-full px-2 py-0.5 text-xs font-semibold uppercase ${ok ? "bg-success/10 text-success" : "bg-warning/10 text-warning"}`,
|
|
158
|
+
children
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
function StatusRow({ label, value, ok, mono = false }) {
|
|
162
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
163
|
+
className: "flex items-start justify-between gap-3",
|
|
164
|
+
children: [/* @__PURE__ */ jsx("dt", {
|
|
165
|
+
className: "text-muted-foreground",
|
|
166
|
+
children: label
|
|
167
|
+
}), /* @__PURE__ */ jsx("dd", {
|
|
168
|
+
className: `${mono ? "font-mono" : "font-medium"} text-right ${ok === void 0 ? "" : ok ? "text-success" : "text-warning"}`,
|
|
169
|
+
children: value
|
|
170
|
+
})]
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function codingSurfaceLabel(surface) {
|
|
174
|
+
if (surface === "host") return "Host tools";
|
|
175
|
+
if (surface === "docker") return "Docker only";
|
|
176
|
+
return "Unavailable";
|
|
177
|
+
}
|
|
178
|
+
function yesNo(value) {
|
|
179
|
+
return value ? "yes" : "no";
|
|
180
|
+
}
|
|
181
|
+
function openAIAccessLabel(status) {
|
|
182
|
+
if (status.accessCurrent) return "current";
|
|
183
|
+
if (status.refreshOnNextTurn) return "refresh on next turn";
|
|
184
|
+
return "unavailable";
|
|
185
|
+
}
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/lib/provider-presentation.ts
|
|
188
|
+
var RECOMMENDED = new Set([
|
|
189
|
+
"openai-codex",
|
|
190
|
+
"openai",
|
|
191
|
+
"anthropic",
|
|
192
|
+
"google"
|
|
193
|
+
]);
|
|
194
|
+
var LOCAL = new Set([
|
|
195
|
+
"ollama",
|
|
196
|
+
"lmstudio",
|
|
197
|
+
"llamacpp"
|
|
198
|
+
]);
|
|
199
|
+
function providerHasConfiguration(provider) {
|
|
200
|
+
return provider.enabled || provider.curated.length > 0 || provider.fields.some((field) => field.set);
|
|
201
|
+
}
|
|
202
|
+
function providerMatches(provider, query) {
|
|
203
|
+
const needle = query.trim().toLocaleLowerCase();
|
|
204
|
+
if (!needle) return true;
|
|
205
|
+
return [
|
|
206
|
+
provider.id,
|
|
207
|
+
provider.displayName,
|
|
208
|
+
provider.hint ?? "",
|
|
209
|
+
provider.envHint,
|
|
210
|
+
...provider.fields.flatMap((field) => [field.label, field.envVar]),
|
|
211
|
+
...provider.curated,
|
|
212
|
+
...provider.catalog
|
|
213
|
+
].some((value) => value.toLocaleLowerCase().includes(needle));
|
|
214
|
+
}
|
|
215
|
+
function groupProviders(providers, query = "") {
|
|
216
|
+
const visible = providers.filter((provider) => providerMatches(provider, query));
|
|
217
|
+
const configured = visible.filter(providerHasConfiguration);
|
|
218
|
+
const configuredIds = new Set(configured.map((provider) => provider.id));
|
|
219
|
+
const remaining = visible.filter((provider) => !configuredIds.has(provider.id));
|
|
220
|
+
return [
|
|
221
|
+
{
|
|
222
|
+
key: "configured",
|
|
223
|
+
title: "Configured",
|
|
224
|
+
description: "Providers you enabled, added models to, or saved credentials for.",
|
|
225
|
+
providers: configured
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
key: "recommended",
|
|
229
|
+
title: "Recommended starting points",
|
|
230
|
+
description: "The simplest hosted options for a first Bazilion conversation.",
|
|
231
|
+
providers: remaining.filter((provider) => RECOMMENDED.has(provider.id))
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
key: "local",
|
|
235
|
+
title: "Local models",
|
|
236
|
+
description: "Use a model server on the same machine without exposing the daemon.",
|
|
237
|
+
providers: remaining.filter((provider) => LOCAL.has(provider.id))
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
key: "more",
|
|
241
|
+
title: "More providers",
|
|
242
|
+
description: "Specialist, regional, enterprise, and subscription endpoints.",
|
|
243
|
+
providers: remaining.filter((provider) => !RECOMMENDED.has(provider.id) && !LOCAL.has(provider.id))
|
|
244
|
+
}
|
|
245
|
+
].filter((section) => section.providers.length > 0);
|
|
246
|
+
}
|
|
247
|
+
function providerReadiness(provider) {
|
|
248
|
+
if (!provider.enabled) return providerHasConfiguration(provider) ? {
|
|
249
|
+
label: "Saved, disabled",
|
|
250
|
+
tone: "neutral"
|
|
251
|
+
} : {
|
|
252
|
+
label: "Not configured",
|
|
253
|
+
tone: "neutral"
|
|
254
|
+
};
|
|
255
|
+
if (provider.curated.length === 0) return {
|
|
256
|
+
label: "Needs a model",
|
|
257
|
+
tone: "warning"
|
|
258
|
+
};
|
|
259
|
+
return {
|
|
260
|
+
label: "Configured, unverified",
|
|
261
|
+
tone: "warning"
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
//#endregion
|
|
265
|
+
//#region src/routes/config/index.tsx?tsr-split=component
|
|
266
|
+
function ProvidersPage() {
|
|
267
|
+
const { providers, openaiCodex, executionSecurity } = Route.useLoaderData();
|
|
268
|
+
const setupComplete = providers.some((p) => p.enabled && p.curated.length > 0);
|
|
269
|
+
const startedComplete = useRef(setupComplete);
|
|
270
|
+
const [showCompletion, setShowCompletion] = useState(false);
|
|
271
|
+
const [query, setQuery] = useState("");
|
|
272
|
+
const sections = useMemo(() => groupProviders(providers, query), [providers, query]);
|
|
273
|
+
const configured = providers.filter(providerHasConfiguration).length;
|
|
274
|
+
const enabled = providers.filter((provider) => provider.enabled).length;
|
|
275
|
+
useEffect(() => {
|
|
276
|
+
if (!startedComplete.current && setupComplete) setShowCompletion(true);
|
|
277
|
+
}, [setupComplete]);
|
|
278
|
+
return /* @__PURE__ */ jsxs(ConfigPage, {
|
|
279
|
+
active: "providers",
|
|
280
|
+
title: "Providers",
|
|
281
|
+
description: /* @__PURE__ */ jsx(Fragment, { children: "Connect the model services your agents may use. Credentials stay encrypted; advanced endpoint and environment names remain available inside each provider." }),
|
|
282
|
+
children: [
|
|
283
|
+
/* @__PURE__ */ jsxs("div", {
|
|
284
|
+
className: "grid gap-3 sm:grid-cols-3",
|
|
285
|
+
"aria-label": "Provider summary",
|
|
286
|
+
children: [
|
|
287
|
+
/* @__PURE__ */ jsx(SummaryStat, {
|
|
288
|
+
label: "Configured",
|
|
289
|
+
value: configured,
|
|
290
|
+
detail: "credentials, models, or toggle"
|
|
291
|
+
}),
|
|
292
|
+
/* @__PURE__ */ jsx(SummaryStat, {
|
|
293
|
+
label: "Enabled",
|
|
294
|
+
value: enabled,
|
|
295
|
+
detail: "available to agent runtime"
|
|
296
|
+
}),
|
|
297
|
+
/* @__PURE__ */ jsx(SummaryStat, {
|
|
298
|
+
label: "Selected models",
|
|
299
|
+
value: providers.reduce((count, provider) => count + (provider.enabled ? provider.curated.length : 0), 0),
|
|
300
|
+
detail: "configured; test connectivity separately"
|
|
301
|
+
})
|
|
302
|
+
]
|
|
303
|
+
}),
|
|
304
|
+
/* @__PURE__ */ jsxs("details", {
|
|
305
|
+
className: "rounded-2xl border border-border bg-card shadow-baziu-sm",
|
|
306
|
+
children: [/* @__PURE__ */ jsxs("summary", {
|
|
307
|
+
className: "flex min-h-12 cursor-pointer list-none items-center gap-3 px-4 py-3 text-sm font-semibold text-foreground marker:hidden sm:px-5",
|
|
308
|
+
children: [
|
|
309
|
+
/* @__PURE__ */ jsx(ShieldCheck, {
|
|
310
|
+
className: "size-4 text-primary",
|
|
311
|
+
"aria-hidden": "true"
|
|
312
|
+
}),
|
|
313
|
+
"Execution security",
|
|
314
|
+
/* @__PURE__ */ jsx("span", {
|
|
315
|
+
className: "ml-auto text-xs font-normal text-muted-foreground",
|
|
316
|
+
children: "Inspect host and protected-turn posture"
|
|
317
|
+
}),
|
|
318
|
+
/* @__PURE__ */ jsx(ChevronDown, {
|
|
319
|
+
className: "size-4 text-muted-foreground",
|
|
320
|
+
"aria-hidden": "true"
|
|
321
|
+
})
|
|
322
|
+
]
|
|
323
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
324
|
+
className: "border-t border-border p-3 sm:p-4",
|
|
325
|
+
children: /* @__PURE__ */ jsx(ExecutionSecurityCard, { status: executionSecurity })
|
|
326
|
+
})]
|
|
327
|
+
}),
|
|
328
|
+
!setupComplete && /* @__PURE__ */ jsx(SetupBlockerBanner, {
|
|
329
|
+
providers,
|
|
330
|
+
openaiCodex
|
|
331
|
+
}),
|
|
332
|
+
showCompletion && /* @__PURE__ */ jsx("section", {
|
|
333
|
+
role: "status",
|
|
334
|
+
className: "rounded-2xl border border-success/30 bg-success/10 p-5 text-sm",
|
|
335
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
336
|
+
className: "flex items-start gap-3",
|
|
337
|
+
children: [/* @__PURE__ */ jsx(CheckCircle2, {
|
|
338
|
+
className: "mt-0.5 size-5 shrink-0 text-success",
|
|
339
|
+
"aria-hidden": "true"
|
|
340
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
341
|
+
className: "min-w-0 flex-1",
|
|
342
|
+
children: [
|
|
343
|
+
/* @__PURE__ */ jsx("h2", {
|
|
344
|
+
className: "m-0 font-body text-base font-semibold text-foreground",
|
|
345
|
+
children: "Your default workspace is ready"
|
|
346
|
+
}),
|
|
347
|
+
/* @__PURE__ */ jsx("p", {
|
|
348
|
+
className: "mt-1 text-muted-foreground",
|
|
349
|
+
children: "Bazilion created the default Agent template and Team. Test the selected model below before relying on it, or continue to spawn your first agent."
|
|
350
|
+
}),
|
|
351
|
+
/* @__PURE__ */ jsxs("div", {
|
|
352
|
+
className: "mt-3 flex flex-wrap gap-2",
|
|
353
|
+
children: [/* @__PURE__ */ jsxs("a", {
|
|
354
|
+
href: "/agents",
|
|
355
|
+
className: "btn-primary no-underline",
|
|
356
|
+
children: ["Spawn your first agent", /* @__PURE__ */ jsx(ChevronRight, {
|
|
357
|
+
className: "size-4",
|
|
358
|
+
"aria-hidden": "true"
|
|
359
|
+
})]
|
|
360
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
361
|
+
variant: "ghost",
|
|
362
|
+
onClick: () => setShowCompletion(false),
|
|
363
|
+
children: "Keep configuring"
|
|
364
|
+
})]
|
|
365
|
+
})
|
|
366
|
+
]
|
|
367
|
+
})]
|
|
368
|
+
})
|
|
369
|
+
}),
|
|
370
|
+
/* @__PURE__ */ jsxs("div", {
|
|
371
|
+
className: "rounded-2xl border border-border bg-card p-4 shadow-baziu-sm sm:p-5",
|
|
372
|
+
children: [
|
|
373
|
+
/* @__PURE__ */ jsx("label", {
|
|
374
|
+
htmlFor: "provider-search",
|
|
375
|
+
className: "m-0 text-sm font-semibold text-foreground",
|
|
376
|
+
children: "Find a provider"
|
|
377
|
+
}),
|
|
378
|
+
/* @__PURE__ */ jsxs("div", {
|
|
379
|
+
className: "relative mt-2",
|
|
380
|
+
children: [/* @__PURE__ */ jsx(Search, {
|
|
381
|
+
className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground",
|
|
382
|
+
"aria-hidden": "true"
|
|
383
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
384
|
+
id: "provider-search",
|
|
385
|
+
type: "search",
|
|
386
|
+
value: query,
|
|
387
|
+
onChange: (event) => setQuery(event.target.value),
|
|
388
|
+
placeholder: "Search by service, model, or advanced key",
|
|
389
|
+
className: "pl-9"
|
|
390
|
+
})]
|
|
391
|
+
}),
|
|
392
|
+
/* @__PURE__ */ jsx("p", {
|
|
393
|
+
className: "mt-2 text-xs leading-5 text-muted-foreground",
|
|
394
|
+
children: "Start with one provider. Everything else stays collapsed until you need it."
|
|
395
|
+
})
|
|
396
|
+
]
|
|
397
|
+
}),
|
|
398
|
+
sections.length === 0 ? /* @__PURE__ */ jsx(EmptyState, {
|
|
399
|
+
icon: /* @__PURE__ */ jsx(Search, {
|
|
400
|
+
className: "size-4",
|
|
401
|
+
"aria-hidden": "true"
|
|
402
|
+
}),
|
|
403
|
+
title: "No providers match",
|
|
404
|
+
description: `Try another search instead of “${query}”.`,
|
|
405
|
+
actions: /* @__PURE__ */ jsx(Button, {
|
|
406
|
+
variant: "ghost",
|
|
407
|
+
onClick: () => setQuery(""),
|
|
408
|
+
children: "Clear search"
|
|
409
|
+
})
|
|
410
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
411
|
+
className: "space-y-4",
|
|
412
|
+
children: sections.map((section) => /* @__PURE__ */ jsxs("details", {
|
|
413
|
+
open: Boolean(query) || section.key === "configured" || !setupComplete && section.key === "recommended",
|
|
414
|
+
className: "group/providers overflow-hidden rounded-2xl border border-border bg-card shadow-baziu-sm",
|
|
415
|
+
children: [/* @__PURE__ */ jsxs("summary", {
|
|
416
|
+
className: "flex cursor-pointer list-none items-center gap-3 px-4 py-4 marker:hidden sm:px-5",
|
|
417
|
+
children: [
|
|
418
|
+
/* @__PURE__ */ jsx("span", {
|
|
419
|
+
className: "flex size-9 shrink-0 items-center justify-center rounded-xl bg-accent text-accent-foreground",
|
|
420
|
+
children: /* @__PURE__ */ jsx(Server, {
|
|
421
|
+
className: "size-4",
|
|
422
|
+
"aria-hidden": "true"
|
|
423
|
+
})
|
|
424
|
+
}),
|
|
425
|
+
/* @__PURE__ */ jsxs("span", {
|
|
426
|
+
className: "min-w-0 flex-1",
|
|
427
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
428
|
+
className: "block text-sm font-semibold text-foreground",
|
|
429
|
+
children: section.title
|
|
430
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
431
|
+
className: "mt-0.5 block text-xs leading-5 text-muted-foreground",
|
|
432
|
+
children: section.description
|
|
433
|
+
})]
|
|
434
|
+
}),
|
|
435
|
+
/* @__PURE__ */ jsx("span", {
|
|
436
|
+
className: "rounded-full border border-border bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground",
|
|
437
|
+
children: section.providers.length
|
|
438
|
+
}),
|
|
439
|
+
/* @__PURE__ */ jsx(ChevronDown, {
|
|
440
|
+
className: "size-4 shrink-0 text-muted-foreground transition-transform group-open/providers:rotate-180",
|
|
441
|
+
"aria-hidden": "true"
|
|
442
|
+
})
|
|
443
|
+
]
|
|
444
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
445
|
+
className: "space-y-2 border-t border-border bg-muted/20 p-2 sm:p-3",
|
|
446
|
+
children: section.providers.map((provider) => /* @__PURE__ */ jsx(ProviderCard, {
|
|
447
|
+
p: provider,
|
|
448
|
+
initiallyOpen: provider.enabled || Boolean(query) || !setupComplete && provider.id === "openai-codex",
|
|
449
|
+
openaiCodexStatus: provider.id === "openai-codex" ? openaiCodex : void 0
|
|
450
|
+
}, provider.id))
|
|
451
|
+
})]
|
|
452
|
+
}, `${section.key}:${query}`))
|
|
453
|
+
})
|
|
454
|
+
]
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
function SummaryStat({ label, value, detail }) {
|
|
458
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
459
|
+
className: "min-w-0 rounded-2xl border border-border bg-card p-4 shadow-baziu-sm",
|
|
460
|
+
children: [
|
|
461
|
+
/* @__PURE__ */ jsx("div", {
|
|
462
|
+
className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground",
|
|
463
|
+
children: label
|
|
464
|
+
}),
|
|
465
|
+
/* @__PURE__ */ jsx("div", {
|
|
466
|
+
className: "mt-1 text-2xl font-semibold text-foreground",
|
|
467
|
+
children: value
|
|
468
|
+
}),
|
|
469
|
+
/* @__PURE__ */ jsx("div", {
|
|
470
|
+
className: "mt-0.5 text-xs leading-5 text-muted-foreground",
|
|
471
|
+
children: detail
|
|
472
|
+
})
|
|
473
|
+
]
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function SetupBlockerBanner({ providers, openaiCodex }) {
|
|
477
|
+
const issues = [];
|
|
478
|
+
for (const p of providers) {
|
|
479
|
+
if (!p.enabled) continue;
|
|
480
|
+
if (p.id === "openai-codex" && !openaiCodex.connected) issues.push(`${p.id}: enabled but ChatGPT is not connected — click "Connect ChatGPT" below`);
|
|
481
|
+
if (p.curated.length === 0) issues.push(`${p.id}: enabled but no curated models — add at least one name in the "curated models" box below and save`);
|
|
482
|
+
}
|
|
483
|
+
const enabledCount = providers.filter((p) => p.enabled).length;
|
|
484
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
485
|
+
role: "status",
|
|
486
|
+
className: "rounded-2xl border border-warning/30 bg-warning/10 p-5 text-sm",
|
|
487
|
+
children: [
|
|
488
|
+
/* @__PURE__ */ jsx("div", {
|
|
489
|
+
className: "font-semibold text-foreground mb-1",
|
|
490
|
+
children: "Finish your first provider"
|
|
491
|
+
}),
|
|
492
|
+
/* @__PURE__ */ jsx("p", {
|
|
493
|
+
className: "text-muted-foreground mb-2",
|
|
494
|
+
children: "Enable one provider, save at least one exact model id, then send the small test request. Saving the model creates your default resources; a successful test confirms that the credential and model actually work."
|
|
495
|
+
}),
|
|
496
|
+
issues.length > 0 ? /* @__PURE__ */ jsx("ul", {
|
|
497
|
+
className: "list-disc space-y-1 pl-5 text-warning",
|
|
498
|
+
children: issues.map((i) => /* @__PURE__ */ jsx("li", { children: i }, i))
|
|
499
|
+
}) : enabledCount === 0 ? /* @__PURE__ */ jsx("p", {
|
|
500
|
+
className: "text-warning",
|
|
501
|
+
children: "No provider is enabled. Open a recommended option below and follow its steps."
|
|
502
|
+
}) : null
|
|
503
|
+
]
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
function ProviderCard({ p, openaiCodexStatus, initiallyOpen }) {
|
|
507
|
+
const router = useRouter();
|
|
508
|
+
const [enabled, setEnabled] = useState(p.enabled);
|
|
509
|
+
const [expanded, setExpanded] = useState(initiallyOpen);
|
|
510
|
+
const [models, setModels] = useState(p.curated.join("\n"));
|
|
511
|
+
const [savingModels, setSavingModels] = useState(false);
|
|
512
|
+
const [modelStatus, setModelStatus] = useState(null);
|
|
513
|
+
const [toggleError, setToggleError] = useState(null);
|
|
514
|
+
const [testModel, setTestModel] = useState(p.curated[0] ?? "");
|
|
515
|
+
const [testing, setTesting] = useState(false);
|
|
516
|
+
const [testResult, setTestResult] = useState(null);
|
|
517
|
+
const readiness = providerReadiness({
|
|
518
|
+
...p,
|
|
519
|
+
enabled
|
|
520
|
+
});
|
|
521
|
+
async function toggle(next) {
|
|
522
|
+
setEnabled(next);
|
|
523
|
+
setToggleError(null);
|
|
524
|
+
try {
|
|
525
|
+
const response = await fetch(`/api/config/providers/${encodeURIComponent(p.id)}/enabled`, {
|
|
526
|
+
method: "PUT",
|
|
527
|
+
headers: { "content-type": "application/json" },
|
|
528
|
+
body: JSON.stringify({ enabled: next })
|
|
529
|
+
});
|
|
530
|
+
if (!response.ok) {
|
|
531
|
+
const body = await response.json().catch(() => null);
|
|
532
|
+
throw new Error(body?.error ?? `Could not update provider (${response.status})`);
|
|
533
|
+
}
|
|
534
|
+
if (next) setExpanded(true);
|
|
535
|
+
await router.invalidate();
|
|
536
|
+
} catch (error) {
|
|
537
|
+
setEnabled(!next);
|
|
538
|
+
setToggleError(error instanceof Error ? error.message : String(error));
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
async function saveModels(e) {
|
|
542
|
+
e.preventDefault();
|
|
543
|
+
setSavingModels(true);
|
|
544
|
+
setModelStatus(null);
|
|
545
|
+
try {
|
|
546
|
+
const list = models.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
547
|
+
const res = await fetch(`/api/config/providers/${encodeURIComponent(p.id)}/models`, {
|
|
548
|
+
method: "PUT",
|
|
549
|
+
headers: { "content-type": "application/json" },
|
|
550
|
+
body: JSON.stringify({ models: list })
|
|
551
|
+
});
|
|
552
|
+
if (!res.ok) {
|
|
553
|
+
const j = await res.json().catch(() => ({}));
|
|
554
|
+
throw new Error(j.error ?? `${res.status} ${res.statusText}`);
|
|
555
|
+
}
|
|
556
|
+
setModelStatus({
|
|
557
|
+
kind: "success",
|
|
558
|
+
message: "Models saved. Run the connection test before relying on them."
|
|
559
|
+
});
|
|
560
|
+
setTestModel(list[0] ?? "");
|
|
561
|
+
setTestResult(null);
|
|
562
|
+
await router.invalidate();
|
|
563
|
+
} catch (e) {
|
|
564
|
+
setModelStatus({
|
|
565
|
+
kind: "error",
|
|
566
|
+
message: e.message
|
|
567
|
+
});
|
|
568
|
+
} finally {
|
|
569
|
+
setSavingModels(false);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
async function testConnection() {
|
|
573
|
+
if (!testModel) return;
|
|
574
|
+
setTesting(true);
|
|
575
|
+
setTestResult(null);
|
|
576
|
+
try {
|
|
577
|
+
const response = await fetch("/api/providers/test", {
|
|
578
|
+
method: "POST",
|
|
579
|
+
headers: { "content-type": "application/json" },
|
|
580
|
+
body: JSON.stringify({
|
|
581
|
+
model: `${p.id}:${testModel}`,
|
|
582
|
+
message: "Reply with exactly: Bazilion connection verified."
|
|
583
|
+
})
|
|
584
|
+
});
|
|
585
|
+
const body = await response.json().catch(() => null);
|
|
586
|
+
if (!response.ok) throw new Error(body?.error ?? `Connection test failed (${response.status})`);
|
|
587
|
+
setTestResult({
|
|
588
|
+
kind: "success",
|
|
589
|
+
message: `Verified ${p.displayName} with ${testModel}.`
|
|
590
|
+
});
|
|
591
|
+
await router.invalidate();
|
|
592
|
+
} catch (error) {
|
|
593
|
+
setTestResult({
|
|
594
|
+
kind: "error",
|
|
595
|
+
message: error instanceof Error ? error.message : String(error)
|
|
596
|
+
});
|
|
597
|
+
} finally {
|
|
598
|
+
setTesting(false);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
602
|
+
className: "overflow-hidden rounded-xl border border-border bg-card",
|
|
603
|
+
children: [
|
|
604
|
+
/* @__PURE__ */ jsxs("header", {
|
|
605
|
+
className: "flex min-w-0 flex-wrap items-center gap-2 px-3 py-3 sm:px-4",
|
|
606
|
+
children: [
|
|
607
|
+
/* @__PURE__ */ jsxs("button", {
|
|
608
|
+
type: "button",
|
|
609
|
+
className: "unstyled flex min-w-0 flex-1 items-center gap-2 rounded-lg text-left",
|
|
610
|
+
"aria-expanded": expanded,
|
|
611
|
+
"aria-controls": `provider-${p.id}`,
|
|
612
|
+
onClick: () => setExpanded((value) => !value),
|
|
613
|
+
children: [/* @__PURE__ */ jsx(ChevronRight, {
|
|
614
|
+
className: `size-4 shrink-0 text-muted-foreground transition-transform ${expanded ? "rotate-90" : ""}`,
|
|
615
|
+
"aria-hidden": "true"
|
|
616
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
617
|
+
className: "min-w-0",
|
|
618
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
619
|
+
className: "block truncate text-sm font-semibold text-foreground",
|
|
620
|
+
children: p.displayName
|
|
621
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
622
|
+
className: "block truncate font-mono text-xs text-muted-foreground",
|
|
623
|
+
children: p.id
|
|
624
|
+
})]
|
|
625
|
+
})]
|
|
626
|
+
}),
|
|
627
|
+
/* @__PURE__ */ jsx(StatusBadge$1, {
|
|
628
|
+
variant: readiness.tone === "success" ? "success" : readiness.tone === "warning" ? "warning" : "neutral",
|
|
629
|
+
children: readiness.label
|
|
630
|
+
}),
|
|
631
|
+
/* @__PURE__ */ jsxs("label", {
|
|
632
|
+
className: "m-0 flex cursor-pointer items-center gap-1.5 rounded-lg px-1 text-xs font-semibold",
|
|
633
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
634
|
+
type: "checkbox",
|
|
635
|
+
checked: enabled,
|
|
636
|
+
onChange: (e) => toggle(e.target.checked),
|
|
637
|
+
className: "size-4",
|
|
638
|
+
"aria-label": `${enabled ? "Disable" : "Enable"} ${p.displayName}`
|
|
639
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
640
|
+
className: enabled ? "text-success" : "text-muted-foreground",
|
|
641
|
+
children: enabled ? "enabled" : "disabled"
|
|
642
|
+
})]
|
|
643
|
+
}),
|
|
644
|
+
/* @__PURE__ */ jsxs("span", {
|
|
645
|
+
className: "w-full pl-6 text-xs text-muted-foreground sm:w-auto sm:pl-0",
|
|
646
|
+
children: [
|
|
647
|
+
p.curated.length > 0 && /* @__PURE__ */ jsxs("span", { children: [p.curated.length, " curated"] }),
|
|
648
|
+
p.catalog.length > 0 && /* @__PURE__ */ jsxs("span", { children: [
|
|
649
|
+
" · ",
|
|
650
|
+
p.catalog.length,
|
|
651
|
+
" catalog"
|
|
652
|
+
] }),
|
|
653
|
+
p.live && !p.live.error && /* @__PURE__ */ jsxs("span", { children: [
|
|
654
|
+
" · ",
|
|
655
|
+
p.live.models.length,
|
|
656
|
+
" live"
|
|
657
|
+
] })
|
|
658
|
+
]
|
|
659
|
+
})
|
|
660
|
+
]
|
|
661
|
+
}),
|
|
662
|
+
toggleError && /* @__PURE__ */ jsx("p", {
|
|
663
|
+
role: "alert",
|
|
664
|
+
className: "mx-4 mb-3 text-sm text-danger",
|
|
665
|
+
children: toggleError
|
|
666
|
+
}),
|
|
667
|
+
expanded && /* @__PURE__ */ jsxs("div", {
|
|
668
|
+
id: `provider-${p.id}`,
|
|
669
|
+
className: "border-t border-dashed px-3 py-4 sm:px-4",
|
|
670
|
+
children: [
|
|
671
|
+
p.hint && /* @__PURE__ */ jsx("p", {
|
|
672
|
+
className: "text-xs text-muted-foreground mb-2",
|
|
673
|
+
children: p.hint
|
|
674
|
+
}),
|
|
675
|
+
p.id === "openai-codex" && openaiCodexStatus && /* @__PURE__ */ jsx(OpenAICodexCard, { status: openaiCodexStatus }),
|
|
676
|
+
p.fields.length === 0 && p.envHint && p.id !== "openai-codex" && /* @__PURE__ */ jsxs("p", {
|
|
677
|
+
className: "text-xs text-muted-foreground",
|
|
678
|
+
children: ["Credentials come from the process env: ", /* @__PURE__ */ jsx("code", {
|
|
679
|
+
className: "font-mono",
|
|
680
|
+
children: p.envHint
|
|
681
|
+
})]
|
|
682
|
+
}),
|
|
683
|
+
p.fields.map((f) => /* @__PURE__ */ jsx(FieldRow, { field: f }, f.envVar)),
|
|
684
|
+
/* @__PURE__ */ jsx("h4", {
|
|
685
|
+
id: `provider-${p.id}-models-label`,
|
|
686
|
+
className: "mt-4 mb-1 font-body text-xs font-semibold uppercase tracking-wide text-muted-foreground",
|
|
687
|
+
children: "Models available to agents"
|
|
688
|
+
}),
|
|
689
|
+
p.curated.length === 0 && /* @__PURE__ */ jsxs("p", {
|
|
690
|
+
className: "mb-2 text-xs font-medium text-warning",
|
|
691
|
+
children: [
|
|
692
|
+
"First-run setup needs at least one model name here — type one (e.g.",
|
|
693
|
+
" ",
|
|
694
|
+
/* @__PURE__ */ jsx("code", {
|
|
695
|
+
className: "font-mono",
|
|
696
|
+
children: exampleModelFor(p.id)
|
|
697
|
+
}),
|
|
698
|
+
") and click",
|
|
699
|
+
" ",
|
|
700
|
+
/* @__PURE__ */ jsx("em", { children: "save models" }),
|
|
701
|
+
". Catalog chips below are the safest source when available."
|
|
702
|
+
]
|
|
703
|
+
}),
|
|
704
|
+
/* @__PURE__ */ jsxs("form", {
|
|
705
|
+
onSubmit: saveModels,
|
|
706
|
+
children: [/* @__PURE__ */ jsx("textarea", {
|
|
707
|
+
id: `provider-${p.id}-models`,
|
|
708
|
+
"aria-labelledby": `provider-${p.id}-models-label`,
|
|
709
|
+
value: models,
|
|
710
|
+
onChange: (e) => setModels(e.target.value),
|
|
711
|
+
rows: Math.max(3, Math.min(8, models.split("\n").length)),
|
|
712
|
+
className: "w-full rounded-md border bg-background px-2 py-1.5 font-mono text-sm outline-none focus:ring-2 focus:ring-ring/30",
|
|
713
|
+
placeholder: p.catalog.length === 0 && !p.live ? "Type model names one per line, e.g. qwen3-coder-30b" : "Click catalog chips below, or type names one per line"
|
|
714
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
715
|
+
className: "flex items-center gap-3 mt-2",
|
|
716
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
717
|
+
type: "submit",
|
|
718
|
+
disabled: savingModels,
|
|
719
|
+
className: "rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground disabled:opacity-50",
|
|
720
|
+
children: savingModels ? "Saving…" : "Save models"
|
|
721
|
+
}), modelStatus && /* @__PURE__ */ jsx("span", {
|
|
722
|
+
role: modelStatus.kind === "error" ? "alert" : "status",
|
|
723
|
+
className: `text-xs ${modelStatus.kind === "error" ? "text-danger" : "text-success"}`,
|
|
724
|
+
children: modelStatus.message
|
|
725
|
+
})]
|
|
726
|
+
})]
|
|
727
|
+
}),
|
|
728
|
+
p.catalog.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("h4", {
|
|
729
|
+
className: "mt-4 mb-1 text-xs uppercase tracking-wide text-muted-foreground",
|
|
730
|
+
children: "catalog"
|
|
731
|
+
}), /* @__PURE__ */ jsx(ChipList, {
|
|
732
|
+
items: p.catalog,
|
|
733
|
+
onPick: (name) => setModels((m) => m.includes(name) ? m : `${m}\n${name}`.trim())
|
|
734
|
+
})] }),
|
|
735
|
+
p.live && !p.live.error && p.live.models.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("h4", {
|
|
736
|
+
className: "mt-4 mb-1 text-xs uppercase tracking-wide text-muted-foreground",
|
|
737
|
+
children: "live"
|
|
738
|
+
}), /* @__PURE__ */ jsx(ChipList, {
|
|
739
|
+
items: p.live.models,
|
|
740
|
+
onPick: (name) => setModels((m) => m.includes(name) ? m : `${m}\n${name}`.trim())
|
|
741
|
+
})] }),
|
|
742
|
+
p.live?.error && /* @__PURE__ */ jsxs("p", {
|
|
743
|
+
role: "alert",
|
|
744
|
+
className: "text-xs text-danger mt-2",
|
|
745
|
+
children: ["Could not fetch live models: ", p.live.error]
|
|
746
|
+
}),
|
|
747
|
+
enabled && p.curated.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
748
|
+
className: "mt-4 rounded-xl border border-border bg-muted/30 p-3",
|
|
749
|
+
children: [
|
|
750
|
+
/* @__PURE__ */ jsx("h4", {
|
|
751
|
+
className: "m-0 font-body text-sm font-semibold text-foreground",
|
|
752
|
+
children: "Test the connection"
|
|
753
|
+
}),
|
|
754
|
+
/* @__PURE__ */ jsx("p", {
|
|
755
|
+
className: "mt-1 text-xs leading-5 text-muted-foreground",
|
|
756
|
+
children: "Sends one short real request. Your provider may charge its normal token cost."
|
|
757
|
+
}),
|
|
758
|
+
/* @__PURE__ */ jsxs("div", {
|
|
759
|
+
className: "mt-3 flex flex-col gap-2 sm:flex-row sm:items-end",
|
|
760
|
+
children: [/* @__PURE__ */ jsxs("label", {
|
|
761
|
+
className: "m-0 min-w-0 flex-1 text-xs font-semibold text-foreground",
|
|
762
|
+
children: ["Model", /* @__PURE__ */ jsx("select", {
|
|
763
|
+
className: "mt-1",
|
|
764
|
+
value: testModel,
|
|
765
|
+
onChange: (event) => setTestModel(event.target.value),
|
|
766
|
+
children: p.curated.map((model) => /* @__PURE__ */ jsx("option", {
|
|
767
|
+
value: model,
|
|
768
|
+
children: model
|
|
769
|
+
}, model))
|
|
770
|
+
})]
|
|
771
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
772
|
+
variant: "ghost",
|
|
773
|
+
disabled: testing || !testModel,
|
|
774
|
+
onClick: () => void testConnection(),
|
|
775
|
+
children: testing ? "Testing…" : "Send test request"
|
|
776
|
+
})]
|
|
777
|
+
}),
|
|
778
|
+
testResult && /* @__PURE__ */ jsx("p", {
|
|
779
|
+
role: testResult.kind === "error" ? "alert" : "status",
|
|
780
|
+
className: `mt-3 rounded-lg px-3 py-2 text-sm ${testResult.kind === "error" ? "bg-danger/10 text-danger" : "bg-success/10 text-success"}`,
|
|
781
|
+
children: testResult.message
|
|
782
|
+
})
|
|
783
|
+
]
|
|
784
|
+
})
|
|
785
|
+
]
|
|
786
|
+
})
|
|
787
|
+
]
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
function exampleModelFor(providerId) {
|
|
791
|
+
switch (providerId) {
|
|
792
|
+
case "openai-codex": return "gpt-5.6-luna";
|
|
793
|
+
case "openai": return "gpt-5.6-luna";
|
|
794
|
+
case "anthropic": return "claude-opus-5";
|
|
795
|
+
case "google": return "gemini-3.6-flash";
|
|
796
|
+
case "google-vertex": return "gemini-3.6-flash";
|
|
797
|
+
case "xai": return "grok-4.5";
|
|
798
|
+
case "groq": return "llama-3.3-70b-versatile";
|
|
799
|
+
case "cerebras": return "gpt-oss-120b";
|
|
800
|
+
case "mistral": return "mistral-large-latest";
|
|
801
|
+
case "zai": return "glm-5.2";
|
|
802
|
+
case "huggingface": return "Qwen/Qwen3.5-397B-A17B";
|
|
803
|
+
case "openrouter": return "anthropic/claude-opus-5";
|
|
804
|
+
case "vercel-ai-gateway": return "anthropic/claude-opus-5";
|
|
805
|
+
case "deepseek": return "deepseek-v4-pro";
|
|
806
|
+
case "fireworks": return "accounts/fireworks/models/kimi-k3";
|
|
807
|
+
case "together": return "moonshotai/Kimi-K3";
|
|
808
|
+
case "baseten": return "moonshotai/Kimi-K3";
|
|
809
|
+
case "moonshotai": return "kimi-k3";
|
|
810
|
+
case "moonshotai-cn": return "kimi-k3";
|
|
811
|
+
case "kimi-coding": return "kimi-for-coding";
|
|
812
|
+
case "minimax": return "MiniMax-M2.7";
|
|
813
|
+
case "minimax-cn": return "MiniMax-M3";
|
|
814
|
+
case "qwen-token-plan": return "qwen3.8-max";
|
|
815
|
+
case "qwen-token-plan-cn":
|
|
816
|
+
case "qwen-token-plan-individual": return "qwen3.8-max";
|
|
817
|
+
case "ant-ling": return "Ling-2.6-1T";
|
|
818
|
+
case "nvidia": return "nvidia/nemotron-3-super-120b-a12b";
|
|
819
|
+
case "cloudflare-workers-ai": return "@cf/moonshotai/kimi-k2.6";
|
|
820
|
+
case "cloudflare-ai-gateway": return "claude-opus-5";
|
|
821
|
+
case "github-copilot": return "claude-opus-5";
|
|
822
|
+
case "xiaomi": return "mimo-v2.5";
|
|
823
|
+
case "xiaomi-token-plan-ams":
|
|
824
|
+
case "xiaomi-token-plan-cn":
|
|
825
|
+
case "xiaomi-token-plan-sgp": return "mimo-v2.5-pro";
|
|
826
|
+
case "opencode": return "claude-opus-5";
|
|
827
|
+
case "opencode-go": return "kimi-k2.7-code";
|
|
828
|
+
case "zai-coding-cn": return "glm-5.2";
|
|
829
|
+
case "azure-openai": return "gpt-5.6-luna";
|
|
830
|
+
case "bedrock": return "global.anthropic.claude-opus-5";
|
|
831
|
+
case "ollama": return "llama3.3";
|
|
832
|
+
case "lmstudio": return "qwen3-coder-30b";
|
|
833
|
+
case "llamacpp": return "unsloth/Qwen3.6-35B-A3B-MTP-GGUF:MXFP4_MOE";
|
|
834
|
+
default: return "model-name";
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
function ChipList({ items, onPick }) {
|
|
838
|
+
return /* @__PURE__ */ jsx("div", {
|
|
839
|
+
className: "flex flex-wrap gap-1.5 max-h-40 overflow-y-auto rounded-md border bg-background p-1.5",
|
|
840
|
+
children: items.map((m) => /* @__PURE__ */ jsx("button", {
|
|
841
|
+
type: "button",
|
|
842
|
+
onClick: () => onPick(m),
|
|
843
|
+
"aria-label": `Add ${m} to selected models`,
|
|
844
|
+
className: "rounded border bg-card px-2 py-0.5 font-mono text-xs hover:border-primary hover:bg-accent",
|
|
845
|
+
children: m
|
|
846
|
+
}, m))
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
function OpenAICodexCard({ status }) {
|
|
850
|
+
const router = useRouter();
|
|
851
|
+
const [busy, setBusy] = useState(false);
|
|
852
|
+
const [err, setErr] = useState(null);
|
|
853
|
+
const [confirmDisconnect, setConfirmDisconnect] = useState(false);
|
|
854
|
+
async function connect() {
|
|
855
|
+
setBusy(true);
|
|
856
|
+
setErr(null);
|
|
857
|
+
try {
|
|
858
|
+
const res = await fetch("/api/auth/openai/login", { method: "POST" });
|
|
859
|
+
if (!res.ok) {
|
|
860
|
+
const j = await res.json().catch(() => ({}));
|
|
861
|
+
throw new Error(j.error ?? `${res.status} ${res.statusText}`);
|
|
862
|
+
}
|
|
863
|
+
await router.invalidate();
|
|
864
|
+
} catch (e) {
|
|
865
|
+
setErr(e.message);
|
|
866
|
+
} finally {
|
|
867
|
+
setBusy(false);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
async function disconnect() {
|
|
871
|
+
setBusy(true);
|
|
872
|
+
setErr(null);
|
|
873
|
+
try {
|
|
874
|
+
const response = await fetch("/api/auth/openai", { method: "DELETE" });
|
|
875
|
+
if (!response.ok && response.status !== 204) {
|
|
876
|
+
const body = await response.json().catch(() => null);
|
|
877
|
+
throw new Error(body?.error ?? `Could not disconnect ChatGPT (${response.status})`);
|
|
878
|
+
}
|
|
879
|
+
await router.invalidate();
|
|
880
|
+
} catch (e) {
|
|
881
|
+
setErr(e instanceof Error ? e.message : String(e));
|
|
882
|
+
throw e;
|
|
883
|
+
} finally {
|
|
884
|
+
setBusy(false);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
888
|
+
className: "rounded-md border bg-muted/30 p-3 mb-3",
|
|
889
|
+
children: [status.connected ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
890
|
+
className: "flex flex-wrap gap-2 items-center mb-2",
|
|
891
|
+
children: [
|
|
892
|
+
/* @__PURE__ */ jsx("span", {
|
|
893
|
+
className: "rounded-full bg-success/10 text-success px-2 py-0.5 text-xs font-semibold uppercase",
|
|
894
|
+
children: "connected"
|
|
895
|
+
}),
|
|
896
|
+
status.accountId && /* @__PURE__ */ jsxs("span", {
|
|
897
|
+
className: "text-xs text-muted-foreground",
|
|
898
|
+
children: ["account ", /* @__PURE__ */ jsx("code", {
|
|
899
|
+
className: "font-mono",
|
|
900
|
+
children: status.accountId
|
|
901
|
+
})]
|
|
902
|
+
}),
|
|
903
|
+
status.expiresAt && /* @__PURE__ */ jsxs("span", {
|
|
904
|
+
className: "text-xs text-muted-foreground",
|
|
905
|
+
children: [
|
|
906
|
+
"token expires",
|
|
907
|
+
" ",
|
|
908
|
+
new Date(status.expiresAt).toISOString().replace(/\.\d+Z$/, "Z")
|
|
909
|
+
]
|
|
910
|
+
})
|
|
911
|
+
]
|
|
912
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
913
|
+
variant: "danger",
|
|
914
|
+
onClick: () => setConfirmDisconnect(true),
|
|
915
|
+
disabled: busy,
|
|
916
|
+
children: "Disconnect ChatGPT"
|
|
917
|
+
})] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("p", {
|
|
918
|
+
className: "text-xs text-muted-foreground mb-2",
|
|
919
|
+
children: [
|
|
920
|
+
"Sign in with your ChatGPT account — the OAuth flow opens a new browser tab. The loopback callback at ",
|
|
921
|
+
/* @__PURE__ */ jsx("code", {
|
|
922
|
+
className: "font-mono",
|
|
923
|
+
children: "localhost:1455"
|
|
924
|
+
}),
|
|
925
|
+
" only works when you're using the web UI on the same machine as the daemon. For remote setups, run ",
|
|
926
|
+
/* @__PURE__ */ jsx("code", {
|
|
927
|
+
className: "font-mono",
|
|
928
|
+
children: "bazilion auth openai login"
|
|
929
|
+
}),
|
|
930
|
+
" on the client."
|
|
931
|
+
]
|
|
932
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
933
|
+
type: "button",
|
|
934
|
+
onClick: connect,
|
|
935
|
+
disabled: busy,
|
|
936
|
+
className: "rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground disabled:opacity-50",
|
|
937
|
+
children: busy ? "opening browser…" : "Connect ChatGPT →"
|
|
938
|
+
})] }), err && /* @__PURE__ */ jsx("p", {
|
|
939
|
+
role: "alert",
|
|
940
|
+
className: "text-sm text-danger mt-2",
|
|
941
|
+
children: err
|
|
942
|
+
})]
|
|
943
|
+
}), /* @__PURE__ */ jsx(ConfirmDialog, {
|
|
944
|
+
open: confirmDisconnect,
|
|
945
|
+
onOpenChange: setConfirmDisconnect,
|
|
946
|
+
title: "Disconnect ChatGPT?",
|
|
947
|
+
description: /* @__PURE__ */ jsxs("p", { children: [
|
|
948
|
+
"This removes the saved OpenAI Codex OAuth credentials. Agents using an",
|
|
949
|
+
" ",
|
|
950
|
+
/* @__PURE__ */ jsx("code", { children: "openai-codex" }),
|
|
951
|
+
" model will stop working until you connect again."
|
|
952
|
+
] }),
|
|
953
|
+
confirmLabel: "Disconnect ChatGPT",
|
|
954
|
+
onConfirm: disconnect
|
|
955
|
+
})] });
|
|
956
|
+
}
|
|
957
|
+
//#endregion
|
|
958
|
+
export { ProvidersPage as component };
|