@qredence/fleet 0.6.0 → 0.6.1
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 +7 -0
- package/dist/web/client/assets/action-swap-roll-COzQ86wm.js +1 -0
- package/dist/web/client/assets/agent-activity-svETLf_5.js +1 -0
- package/dist/web/client/assets/agent-disclosure-DAMuuGcM.js +1 -0
- package/dist/web/client/assets/analytics-stub-B6zGMuSV.js +1 -0
- package/dist/web/client/assets/{artifacts-panel-CJ75gQub.js → artifacts-panel-HVjqBMyx.js} +1 -1
- package/dist/web/client/assets/button-C5wFDY5_.js +1 -0
- package/dist/web/client/assets/card-DA3Vnqay.js +1 -0
- package/dist/web/client/assets/chat-BhYseKd6.js +52 -0
- package/dist/web/client/assets/{chat-command-palette-CkISHfKE.js → chat-command-palette-LILDO_vG.js} +1 -1
- package/dist/web/client/assets/{citations-C_tPOJE_.js → citations-BPv8HIpf.js} +2 -2
- package/dist/web/client/assets/command-PhicLCoO.js +1 -0
- package/dist/web/client/assets/dialog-pBGUjAQ7.js +1 -0
- package/dist/web/client/assets/{fleet-message-queue-BCno4XP-.js → fleet-message-queue-fbYYwMj0.js} +1 -1
- package/dist/web/client/assets/{fleet-pi-tool-renderer-BEDIO3al.js → fleet-pi-tool-renderer-BRgNnmaJ.js} +28 -28
- package/dist/web/client/assets/fleet-reasoning-panel-CjA2dwUJ.js +1 -0
- package/dist/web/client/assets/{fork-picker-dialog-ByBOGVsa.js → fork-picker-dialog-B7NNpVmW.js} +1 -1
- package/dist/web/client/assets/globals-CuIiqOTg.css +2 -0
- package/dist/web/client/assets/horizontal-resize-Cp3iHMH7.js +1 -0
- package/dist/web/client/assets/index-CSGplyr_.js +12 -0
- package/dist/web/client/assets/{input-0wwjWjKq.js → input-PcdubeKn.js} +1 -1
- package/dist/web/client/assets/input-group-C2HJEZvl.js +1 -0
- package/dist/web/client/assets/ipython-tool-CyuMOxz1.js +3 -0
- package/dist/web/client/assets/{markdown-code-CuQcR3UO.js → markdown-code-xNyjdZ4g.js} +1 -1
- package/dist/web/client/assets/{markdown-DInPmRUG.js → markdown-lvexwooo.js} +2 -2
- package/dist/web/client/assets/{model-selector-list-Ch05B2nZ.js → model-selector-list-CoXX358G.js} +1 -1
- package/dist/web/client/assets/{notify-DgMKgZZW.js → notify-DxL0VD7Z.js} +1 -1
- package/dist/web/client/assets/openui-renderer-TLNe5e_Q.js +378 -0
- package/dist/web/client/assets/prompt-input-fwP8TsgQ.js +1 -0
- package/dist/web/client/assets/{prompt-suggestions-Cc--lSNR.js → prompt-suggestions-BlGXmWS7.js} +1 -1
- package/dist/web/client/assets/provider-catalog-DYMFdbKc.js +1 -0
- package/dist/web/client/assets/provider-label-B4q5mI65.js +1 -0
- package/dist/web/client/assets/{repl-panel-DsPX04Xr.js → repl-panel-C5om8MGU.js} +1 -1
- package/dist/web/client/assets/{right-panel-registry-Dp8yX-oL.js → right-panel-registry-BBlxLxnx.js} +2 -2
- package/dist/web/client/assets/routes-XGsAIqBJ.js +16 -0
- package/dist/web/client/assets/settings-dialog-BSBasR3o.js +2 -0
- package/dist/web/client/assets/{subagent-chat-panel-Yujplxpb.js → subagent-chat-panel-oeLDPDAK.js} +1 -1
- package/dist/web/client/assets/{subagent-transcript-CnI-mqN0.js → subagent-transcript-DaVHjNUH.js} +1 -1
- package/dist/web/client/assets/{subagents-panel-CjXEdimj.js → subagents-panel-D_aVgSCi.js} +1 -1
- package/dist/web/client/assets/surfaces-BhAXz9So.js +1 -0
- package/dist/web/client/assets/{switch-9rTeg6J6.js → switch-WhXeJNNY.js} +1 -1
- package/dist/web/client/assets/{toast-Bt9p2OL4.js → toast-D3c9XeGe.js} +1 -1
- package/dist/web/client/assets/{tool-result-DfnPN0FQ.js → tool-result-Cki8WUNc.js} +3 -3
- package/dist/web/client/assets/virtualized-turn-list-CdMa-ydT.js +6 -0
- package/dist/web/client/assets/workspace-panel-77bDbprs.js +1 -0
- package/dist/web/client/bundle-budget.json +5 -5
- package/dist/web/launcher.mjs +10 -1
- package/dist/web/server/{_tanstack-start-manifest_v-DS_CSIFQ-WB3VTKF3.js → _tanstack-start-manifest_v-0L7fqnH4-KMVGUFE4.js} +24 -24
- package/dist/web/server/{agent-activity-CS2rbF_C-A3R26CYH.js → agent-activity-BuEE6iVw-CDZLK4D2.js} +4 -4
- package/dist/web/server/{artifacts-panel-CaKrX2XC-R37I4BHF.js → artifacts-panel-D3ySO--V-XSL53CXL.js} +18 -18
- package/dist/web/server/{chat-command-palette-7gbqEnm9-6XICQZN7.js → chat-command-palette-kAbXhWVg-TJWXH2WW.js} +9 -9
- package/dist/web/server/{chunk-CNXJN5HN.js → chunk-2DDWXTVG.js} +5 -5
- package/dist/web/server/{chunk-TWYHHG5N.js → chunk-2JHTYWD5.js} +15 -15
- package/dist/web/server/{chunk-EAE2QXRK.js → chunk-3TIMGWWI.js} +1 -2
- package/dist/web/server/{chunk-AGFRJQZ7.js → chunk-4WBFCB4O.js} +257 -257
- package/dist/web/server/{chunk-P6UMR32I.js → chunk-5UCAJBAH.js} +4 -4
- package/dist/web/server/{chunk-DZ2IC3FH.js → chunk-D27LRYVT.js} +42 -42
- package/dist/web/server/{chunk-YXXRP3NS.js → chunk-DLUZFOG3.js} +5 -5
- package/dist/web/server/{chunk-K3BXQG3N.js → chunk-EBG3XFGQ.js} +60 -60
- package/dist/web/server/{chunk-2ATMSG7U.js → chunk-EJEPDVK6.js} +3 -3
- package/dist/web/server/{chunk-IJPCV6DH.js → chunk-FYDQK6UX.js} +1 -1
- package/dist/web/server/{chunk-WHBVQJ4K.js → chunk-HF7DG7PC.js} +73 -73
- package/dist/web/server/{chunk-WYL2DW5R.js → chunk-JTCCQZLN.js} +2 -2
- package/dist/web/server/{chunk-UAPNEWCA.js → chunk-KP2PNDGL.js} +6 -6
- package/dist/web/server/{chunk-7SR6WDM2.js → chunk-MNBGB2SP.js} +2 -2
- package/dist/web/server/{chunk-HSJMLO36.js → chunk-MNPHMZU7.js} +3 -3
- package/dist/web/server/{chunk-JQDLJ7KI.js → chunk-NGCQJ33Y.js} +1134 -1134
- package/dist/web/server/{chunk-7SD2ZSEA.js → chunk-NIDBN7BQ.js} +1 -1
- package/dist/web/server/{chunk-ZJFA4F5X.js → chunk-NIZBFVJF.js} +2 -2
- package/dist/web/server/{chunk-PIOFZUOU.js → chunk-NJ4QEZHK.js} +3 -4
- package/dist/web/server/{chunk-WM4PUT6M.js → chunk-NNKJTKOQ.js} +234 -234
- package/dist/web/server/{chunk-N6NOTURM.js → chunk-NWDI3OWB.js} +4 -4
- package/dist/web/server/{chunk-KELEYPVK.js → chunk-O3HDELZ2.js} +74826 -74825
- package/dist/web/server/{chunk-YNUWKMNQ.js → chunk-PLYZ7P2Y.js} +1 -152
- package/dist/web/server/{chunk-LXJD6IGW.js → chunk-QFRCJWQQ.js} +7 -7
- package/dist/web/server/{chunk-NXJ32VFR.js → chunk-QIULBRTU.js} +13 -13
- package/dist/web/server/{chunk-DI7XRK2H.js → chunk-RIP3PBWT.js} +3 -3
- package/dist/web/server/{chunk-YKVGQBZA.js → chunk-S5LFXXDY.js} +625 -622
- package/dist/web/server/{chunk-XLNCWZMZ.js → chunk-UCUFC553.js} +3 -1
- package/dist/web/server/{chunk-KOUEJ3NU.js → chunk-UL2725KQ.js} +3 -3
- package/dist/web/server/{chunk-HFQTI7AX.js → chunk-VPKX7QRU.js} +3 -3
- package/dist/web/server/{chunk-LZ4Q5KUJ.js → chunk-WNCAL4HN.js} +133 -133
- package/dist/web/server/{chunk-C5X6G26O.js → chunk-XIB6XNUX.js} +436 -436
- package/dist/web/server/{chunk-EH4BZ6QM.js → chunk-YGYOBX7G.js} +2 -2
- package/dist/web/server/{chunk-BBBS5AS7.js → chunk-ZIFSJ3HQ.js} +626 -626
- package/dist/web/server/{fleet-message-queue-BS-cZ56r-GLZXUKDF.js → fleet-message-queue-D_w8lSeY-T3HB7HVQ.js} +5 -5
- package/dist/web/server/{fleet-pi-tool-renderer-umKunT3K-O4GBH35V.js → fleet-pi-tool-renderer-qwc-qZFq-4U556N5Q.js} +12 -12
- package/dist/web/server/{fleet-reasoning-panel-BxC2COxi-GPLMQSTT.js → fleet-reasoning-panel-DG_vuvv0-NCZWEEIT.js} +26 -26
- package/dist/web/server/{fleet-subagent-list-CpSYzCIq-JDH2LHSS.js → fleet-subagent-list-BGb0PjhF-2X67FMUV.js} +1 -1
- package/dist/web/server/{fleet-tool-timeline-IB36_PB2-XJENTO6I.js → fleet-tool-timeline-D6yM4ZMz-ZSFVRRRI.js} +1 -1
- package/dist/web/server/{fork-picker-dialog-DlINz9UQ-UWIXFDJX.js → fork-picker-dialog-Ds6Tgtu3-DIBWN7MV.js} +5 -5
- package/dist/web/server/{model-selector-list-jBTZc2Mu-OXJOS5NA.js → model-selector-list-DxeGZoD2-P6S6FSJH.js} +9 -9
- package/dist/web/server/{openui-renderer-Biyyjhjn-SJOEKPTJ.js → openui-renderer-MKFv6LlH-MDRSVFEY.js} +11 -11
- package/dist/web/server/{prompt-suggestions-D4AEEY7K-RZSP7PWV.js → prompt-suggestions-BOItmGnD-YQA7RHLG.js} +2 -2
- package/dist/web/server/{repl-panel-D5KsoJik-BQKO53JO.js → repl-panel-CuyF8wt5-CHDT2Q3N.js} +2 -2
- package/dist/web/server/{router-DWALoX_M-I5CBL7FQ.js → router-Dg72SESP-PCWKLFRG.js} +16 -16
- package/dist/web/server/{routes-BBVirYfL-5WXMOT7M.js → routes-BGrVtPYF-SURPAJN6.js} +6432 -6413
- package/dist/web/server/server.js +2 -2
- package/dist/web/server/{settings-dialog-DndPbM-v-RFNXXEAN.js → settings-dialog-CK0FJlTg-HZRBAXDZ.js} +1392 -1402
- package/dist/web/server/{subagent-chat-panel-C0RpnXav-J7VYO7QY.js → subagent-chat-panel-gzamnTgK-PQ2TLLJF.js} +21 -21
- package/dist/web/server/{subagents-panel-jDqIn9Nh-YEV6QLUY.js → subagents-panel-Berjd7HJ-EI5ZKC6V.js} +20 -20
- package/dist/web/server/{workspace-panel-CX_Vo6As-EWO6AMPI.js → workspace-panel-CBBa_3UO-B4PPFPMA.js} +45 -20
- package/package.json +1 -1
- package/dist/web/client/assets/action-swap-roll-BB8DFMuf.js +0 -1
- package/dist/web/client/assets/agent-activity-CwMDU7aP.js +0 -1
- package/dist/web/client/assets/agent-disclosure-B8SnhQXL.js +0 -1
- package/dist/web/client/assets/analytics-stub-Cas1He0w.js +0 -1
- package/dist/web/client/assets/button-BR2WWrFo.js +0 -1
- package/dist/web/client/assets/card-BKl76a3R.js +0 -1
- package/dist/web/client/assets/chat-Ci2cEQrR.js +0 -52
- package/dist/web/client/assets/command-_WjnervL.js +0 -1
- package/dist/web/client/assets/dialog-BEZuZhzk.js +0 -1
- package/dist/web/client/assets/fleet-reasoning-panel-CbkO7u-v.js +0 -1
- package/dist/web/client/assets/globals-B_I1Eq1u.css +0 -2
- package/dist/web/client/assets/horizontal-resize-CwoDojST.js +0 -1
- package/dist/web/client/assets/index-DJ1fFbQu.js +0 -12
- package/dist/web/client/assets/input-group-Tb5TYbzi.js +0 -1
- package/dist/web/client/assets/ipython-tool-ldJ9F1Cw.js +0 -3
- package/dist/web/client/assets/openui-renderer-Bf60nxNi.js +0 -378
- package/dist/web/client/assets/prompt-input-qPIXZ-Rb.js +0 -1
- package/dist/web/client/assets/provider-catalog-D8G66gwc.js +0 -1
- package/dist/web/client/assets/provider-label-DDLRnZyC.js +0 -1
- package/dist/web/client/assets/routes-DpgMJZ5n.js +0 -16
- package/dist/web/client/assets/settings-dialog-YJkvt5EB.js +0 -2
- package/dist/web/client/assets/surfaces-DI-U-_2a.js +0 -1
- package/dist/web/client/assets/virtualized-turn-list--Vynre4D.js +0 -6
- package/dist/web/client/assets/workspace-panel-CPPIznT9.js +0 -1
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
useHoverInteractionSharedState,
|
|
25
25
|
useHoverReferenceInteraction,
|
|
26
26
|
usePopupHandleStore
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-2JHTYWD5.js";
|
|
28
28
|
import {
|
|
29
29
|
UI_PREFERENCES_KEY,
|
|
30
30
|
isModelPatternEnabled,
|
|
@@ -56,11 +56,11 @@ import {
|
|
|
56
56
|
} from "./chunk-OKL5ZRVB.js";
|
|
57
57
|
import {
|
|
58
58
|
notify
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-JTCCQZLN.js";
|
|
60
60
|
import {
|
|
61
61
|
FloatingPortalLite,
|
|
62
62
|
Info
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-UL2725KQ.js";
|
|
64
64
|
import "./chunk-UCA4WN66.js";
|
|
65
65
|
import {
|
|
66
66
|
Eye
|
|
@@ -84,7 +84,7 @@ import {
|
|
|
84
84
|
InputGroupButton,
|
|
85
85
|
InputGroupInput,
|
|
86
86
|
Textarea
|
|
87
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-NJ4QEZHK.js";
|
|
88
88
|
import {
|
|
89
89
|
Search
|
|
90
90
|
} from "./chunk-JIULUYHT.js";
|
|
@@ -105,7 +105,7 @@ import {
|
|
|
105
105
|
FieldGroup,
|
|
106
106
|
FieldLabel,
|
|
107
107
|
Switch
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-KP2PNDGL.js";
|
|
109
109
|
import {
|
|
110
110
|
Select,
|
|
111
111
|
clamp,
|
|
@@ -117,7 +117,7 @@ import {
|
|
|
117
117
|
useDirection,
|
|
118
118
|
usePositioner,
|
|
119
119
|
useRender
|
|
120
|
-
} from "./chunk-
|
|
120
|
+
} from "./chunk-NNKJTKOQ.js";
|
|
121
121
|
import {
|
|
122
122
|
isCustomProviderId,
|
|
123
123
|
isNamedOccInstanceId,
|
|
@@ -126,7 +126,7 @@ import {
|
|
|
126
126
|
import "./chunk-WWJF4RO2.js";
|
|
127
127
|
import {
|
|
128
128
|
Input
|
|
129
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-5UCAJBAH.js";
|
|
130
130
|
import {
|
|
131
131
|
Dialog,
|
|
132
132
|
DialogBackdrop,
|
|
@@ -160,7 +160,7 @@ import {
|
|
|
160
160
|
usePopupRootStore,
|
|
161
161
|
useSurface,
|
|
162
162
|
useTriggerDataForwarding
|
|
163
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-4WBFCB4O.js";
|
|
164
164
|
import {
|
|
165
165
|
Button,
|
|
166
166
|
POPUP_COLLISION_AVOIDANCE,
|
|
@@ -181,7 +181,7 @@ import {
|
|
|
181
181
|
ownerDocument,
|
|
182
182
|
useTimeout,
|
|
183
183
|
webkit
|
|
184
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-WNCAL4HN.js";
|
|
185
185
|
import {
|
|
186
186
|
Check
|
|
187
187
|
} from "./chunk-4QD4PCVP.js";
|
|
@@ -189,7 +189,7 @@ import "./chunk-S3PQ6HKH.js";
|
|
|
189
189
|
import {
|
|
190
190
|
useBaseUiId,
|
|
191
191
|
useValueAsRef
|
|
192
|
-
} from "./chunk-
|
|
192
|
+
} from "./chunk-MNBGB2SP.js";
|
|
193
193
|
import {
|
|
194
194
|
X
|
|
195
195
|
} from "./chunk-JBLHIEVG.js";
|
|
@@ -212,7 +212,7 @@ import {
|
|
|
212
212
|
useOpenChangeComplete,
|
|
213
213
|
useRenderElement,
|
|
214
214
|
useStableCallback
|
|
215
|
-
} from "./chunk-
|
|
215
|
+
} from "./chunk-XIB6XNUX.js";
|
|
216
216
|
import {
|
|
217
217
|
Plug
|
|
218
218
|
} from "./chunk-AHTO6GDS.js";
|
|
@@ -228,7 +228,7 @@ import "./chunk-JDCCC7A7.js";
|
|
|
228
228
|
import "./chunk-L547YHC4.js";
|
|
229
229
|
import "./chunk-MLKGABMK.js";
|
|
230
230
|
|
|
231
|
-
// web/app/dist/server/assets/settings-dialog-
|
|
231
|
+
// web/app/dist/server/assets/settings-dialog-CK0FJlTg.js
|
|
232
232
|
import * as React$1 from "react";
|
|
233
233
|
import { useCallback as useCallback2, useEffect as useEffect2, useId, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
234
234
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -722,6 +722,46 @@ function useFocus(context, props = {}) {
|
|
|
722
722
|
trigger: reference
|
|
723
723
|
} : {}, [enabled, reference]);
|
|
724
724
|
}
|
|
725
|
+
function Breadcrumb({ className, ...props }) {
|
|
726
|
+
return /* @__PURE__ */ jsx("nav", {
|
|
727
|
+
"aria-label": "breadcrumb",
|
|
728
|
+
"data-slot": "breadcrumb",
|
|
729
|
+
className: cn(className),
|
|
730
|
+
...props
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
function BreadcrumbList({ className, ...props }) {
|
|
734
|
+
return /* @__PURE__ */ jsx("ol", {
|
|
735
|
+
"data-slot": "breadcrumb-list",
|
|
736
|
+
className: cn("flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-muted-foreground", className),
|
|
737
|
+
...props
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
function BreadcrumbItem({ className, ...props }) {
|
|
741
|
+
return /* @__PURE__ */ jsx("li", {
|
|
742
|
+
"data-slot": "breadcrumb-item",
|
|
743
|
+
className: cn("inline-flex items-center gap-1", className),
|
|
744
|
+
...props
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
function BreadcrumbPage({ className, ...props }) {
|
|
748
|
+
return /* @__PURE__ */ jsx("span", {
|
|
749
|
+
"data-slot": "breadcrumb-page",
|
|
750
|
+
"aria-current": "page",
|
|
751
|
+
className: cn("font-normal text-foreground", className),
|
|
752
|
+
...props
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
function BreadcrumbSeparator({ children, className, ...props }) {
|
|
756
|
+
return /* @__PURE__ */ jsx("li", {
|
|
757
|
+
"data-slot": "breadcrumb-separator",
|
|
758
|
+
role: "presentation",
|
|
759
|
+
"aria-hidden": "true",
|
|
760
|
+
className: cn("[&>svg]:size-3.5", className),
|
|
761
|
+
...props,
|
|
762
|
+
children: children ?? /* @__PURE__ */ jsx(ChevronRight, {})
|
|
763
|
+
});
|
|
764
|
+
}
|
|
725
765
|
var ScrollAreaRootContext = /* @__PURE__ */ React$1.createContext(void 0);
|
|
726
766
|
function useScrollAreaRootContext() {
|
|
727
767
|
const context = React$1.useContext(ScrollAreaRootContext);
|
|
@@ -1414,46 +1454,6 @@ function ScrollBar({ className, orientation = "vertical", ...props }) {
|
|
|
1414
1454
|
})
|
|
1415
1455
|
});
|
|
1416
1456
|
}
|
|
1417
|
-
function Breadcrumb({ className, ...props }) {
|
|
1418
|
-
return /* @__PURE__ */ jsx("nav", {
|
|
1419
|
-
"aria-label": "breadcrumb",
|
|
1420
|
-
"data-slot": "breadcrumb",
|
|
1421
|
-
className: cn(className),
|
|
1422
|
-
...props
|
|
1423
|
-
});
|
|
1424
|
-
}
|
|
1425
|
-
function BreadcrumbList({ className, ...props }) {
|
|
1426
|
-
return /* @__PURE__ */ jsx("ol", {
|
|
1427
|
-
"data-slot": "breadcrumb-list",
|
|
1428
|
-
className: cn("flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-muted-foreground", className),
|
|
1429
|
-
...props
|
|
1430
|
-
});
|
|
1431
|
-
}
|
|
1432
|
-
function BreadcrumbItem({ className, ...props }) {
|
|
1433
|
-
return /* @__PURE__ */ jsx("li", {
|
|
1434
|
-
"data-slot": "breadcrumb-item",
|
|
1435
|
-
className: cn("inline-flex items-center gap-1", className),
|
|
1436
|
-
...props
|
|
1437
|
-
});
|
|
1438
|
-
}
|
|
1439
|
-
function BreadcrumbPage({ className, ...props }) {
|
|
1440
|
-
return /* @__PURE__ */ jsx("span", {
|
|
1441
|
-
"data-slot": "breadcrumb-page",
|
|
1442
|
-
"aria-current": "page",
|
|
1443
|
-
className: cn("font-normal text-foreground", className),
|
|
1444
|
-
...props
|
|
1445
|
-
});
|
|
1446
|
-
}
|
|
1447
|
-
function BreadcrumbSeparator({ children, className, ...props }) {
|
|
1448
|
-
return /* @__PURE__ */ jsx("li", {
|
|
1449
|
-
"data-slot": "breadcrumb-separator",
|
|
1450
|
-
role: "presentation",
|
|
1451
|
-
"aria-hidden": "true",
|
|
1452
|
-
className: cn("[&>svg]:size-3.5", className),
|
|
1453
|
-
...props,
|
|
1454
|
-
children: children ?? /* @__PURE__ */ jsx(ChevronRight, {})
|
|
1455
|
-
});
|
|
1456
|
-
}
|
|
1457
1457
|
var MOBILE_BREAKPOINT = 768;
|
|
1458
1458
|
function useIsMobile() {
|
|
1459
1459
|
const [isMobile, setIsMobile] = React$1.useState(void 0);
|
|
@@ -2253,42 +2253,6 @@ function SidebarMenuButton({ render, isActive = false, variant = "default", size
|
|
|
2253
2253
|
...tooltip
|
|
2254
2254
|
})] });
|
|
2255
2255
|
}
|
|
2256
|
-
var THEME_OPTIONS = [
|
|
2257
|
-
{
|
|
2258
|
-
value: "system",
|
|
2259
|
-
label: "System",
|
|
2260
|
-
icon: Monitor
|
|
2261
|
-
},
|
|
2262
|
-
{
|
|
2263
|
-
value: "light",
|
|
2264
|
-
label: "Light",
|
|
2265
|
-
icon: Sun
|
|
2266
|
-
},
|
|
2267
|
-
{
|
|
2268
|
-
value: "dark",
|
|
2269
|
-
label: "Dark",
|
|
2270
|
-
icon: Moon
|
|
2271
|
-
}
|
|
2272
|
-
];
|
|
2273
|
-
function PersonalizationSection({ onThemePreferenceChange, themePreference }) {
|
|
2274
|
-
return /* @__PURE__ */ jsxs(Field, {
|
|
2275
|
-
orientation: "horizontal",
|
|
2276
|
-
className: "items-center justify-between gap-6 rounded-xl border p-4",
|
|
2277
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
2278
|
-
className: "min-w-0",
|
|
2279
|
-
children: [/* @__PURE__ */ jsx(FieldLabel, { children: "Theme" }), /* @__PURE__ */ jsx(FieldDescription, { children: "Match the system theme or pick light or dark." })]
|
|
2280
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
2281
|
-
className: "shrink-0",
|
|
2282
|
-
children: /* @__PURE__ */ jsx(Select, {
|
|
2283
|
-
"aria-label": "Theme",
|
|
2284
|
-
className: "w-[160px]",
|
|
2285
|
-
onValueChange: (value) => onThemePreferenceChange(value),
|
|
2286
|
-
options: [...THEME_OPTIONS],
|
|
2287
|
-
value: themePreference
|
|
2288
|
-
})
|
|
2289
|
-
})]
|
|
2290
|
-
});
|
|
2291
|
-
}
|
|
2292
2256
|
function RowSurface({ className, interactive, padding, tone, ...props }) {
|
|
2293
2257
|
return /* @__PURE__ */ jsx("div", {
|
|
2294
2258
|
className: cn(fleetPiRowSurface({
|
|
@@ -2589,14 +2553,10 @@ function ProviderOAuthSignIn({ onConfigured, onOAuthLogin, provider }) {
|
|
|
2589
2553
|
}),
|
|
2590
2554
|
userCode ? /* @__PURE__ */ jsxs("p", {
|
|
2591
2555
|
className: "text-sm",
|
|
2592
|
-
children: [
|
|
2593
|
-
"
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
className: "font-mono text-foreground",
|
|
2597
|
-
children: userCode
|
|
2598
|
-
})
|
|
2599
|
-
]
|
|
2556
|
+
children: ["Enter this code: ", /* @__PURE__ */ jsx("span", {
|
|
2557
|
+
className: "font-mono text-foreground",
|
|
2558
|
+
children: userCode
|
|
2559
|
+
})]
|
|
2600
2560
|
}) : null,
|
|
2601
2561
|
instructions && !userCode ? /* @__PURE__ */ jsx("p", {
|
|
2602
2562
|
className: "text-xs text-pretty text-muted-foreground",
|
|
@@ -2980,1374 +2940,1299 @@ function McpConnectionsSection({ connections, isLoading, isPending, onOAuth, onR
|
|
|
2980
2940
|
]
|
|
2981
2941
|
});
|
|
2982
2942
|
}
|
|
2983
|
-
function
|
|
2984
|
-
return
|
|
2943
|
+
function customModelKey(provider, model) {
|
|
2944
|
+
return `${provider}/${model}`;
|
|
2985
2945
|
}
|
|
2986
|
-
function
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
children: label
|
|
2994
|
-
}), /* @__PURE__ */ jsxs(InputGroup, { children: [
|
|
2995
|
-
/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
2996
|
-
align: "inline-start",
|
|
2997
|
-
children: /* @__PURE__ */ jsx(Lock, {})
|
|
2998
|
-
}),
|
|
2999
|
-
/* @__PURE__ */ jsx(InputGroupInput, {
|
|
3000
|
-
id: controlId,
|
|
3001
|
-
type: showPassword ? "text" : "password",
|
|
3002
|
-
placeholder,
|
|
3003
|
-
value,
|
|
3004
|
-
onChange: (event) => onChange(event.target.value),
|
|
3005
|
-
"aria-label": label,
|
|
3006
|
-
"aria-invalid": invalid || void 0
|
|
3007
|
-
}),
|
|
3008
|
-
/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
3009
|
-
align: "inline-end",
|
|
3010
|
-
children: /* @__PURE__ */ jsx(InputGroupButton, {
|
|
3011
|
-
size: "icon-xs",
|
|
3012
|
-
className: cn(HIT_AREA_EXPAND_CLASS, "transition-[background-color,transform] duration-150 active:scale-[0.96]"),
|
|
3013
|
-
"aria-label": showPassword ? "Hide value" : "Show value",
|
|
3014
|
-
onClick: onToggleVisibility,
|
|
3015
|
-
children: showPassword ? /* @__PURE__ */ jsx(EyeOff, {}) : /* @__PURE__ */ jsx(Eye, {})
|
|
3016
|
-
})
|
|
3017
|
-
})
|
|
3018
|
-
] })]
|
|
3019
|
-
});
|
|
2946
|
+
function isModelEnabled(model, patterns) {
|
|
2947
|
+
return isModelPatternEnabled({
|
|
2948
|
+
id: model.id,
|
|
2949
|
+
name: model.name,
|
|
2950
|
+
provider: model.provider,
|
|
2951
|
+
modelId: model.modelId
|
|
2952
|
+
}, patterns);
|
|
3020
2953
|
}
|
|
3021
|
-
function
|
|
3022
|
-
|
|
3023
|
-
const
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
id: controlId,
|
|
3034
|
-
type: inputType,
|
|
3035
|
-
placeholder,
|
|
3036
|
-
value,
|
|
3037
|
-
onChange: (event) => onChange(event.target.value),
|
|
3038
|
-
"aria-label": label,
|
|
3039
|
-
"aria-invalid": invalid || void 0
|
|
3040
|
-
})] })]
|
|
3041
|
-
});
|
|
2954
|
+
function nextEnabledModelPatterns({ currentPatterns, enabled, model, models }) {
|
|
2955
|
+
if (currentPatterns === void 0 && enabled) return void 0;
|
|
2956
|
+
const current = currentPatterns ?? [];
|
|
2957
|
+
const knownModelPatterns = new Set(models.map((item) => modelPatternFor(item)));
|
|
2958
|
+
const activeKnown = /* @__PURE__ */ new Set();
|
|
2959
|
+
for (const item of models) if (isModelEnabled(item, currentPatterns)) activeKnown.add(modelPatternFor(item));
|
|
2960
|
+
if (enabled) activeKnown.add(modelPatternFor(model));
|
|
2961
|
+
else activeKnown.delete(modelPatternFor(model));
|
|
2962
|
+
return [...current.filter((pattern) => {
|
|
2963
|
+
if (knownModelPatterns.has(pattern)) return false;
|
|
2964
|
+
return enabled || !modelMatchesPattern(model, pattern);
|
|
2965
|
+
}), ...activeKnown];
|
|
3042
2966
|
}
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
var OPENAI_CHAT_NAME_PLACEHOLDER = "e.g. OpenCode Zen, Nebius, Groq\u2026";
|
|
3046
|
-
var CUSTOM_MODELS_PLACEHOLDER = "model-a, model-b (comma-separated)";
|
|
3047
|
-
var CUSTOM_PROVIDER_API_OPTIONS = [
|
|
3048
|
-
{
|
|
3049
|
-
value: "openai-completions",
|
|
3050
|
-
label: "OpenAI Chat Completions"
|
|
3051
|
-
},
|
|
3052
|
-
{
|
|
3053
|
-
value: "openai-responses",
|
|
3054
|
-
label: "OpenAI Responses"
|
|
3055
|
-
},
|
|
3056
|
-
{
|
|
3057
|
-
value: "anthropic-messages",
|
|
3058
|
-
label: "Anthropic Messages"
|
|
3059
|
-
},
|
|
3060
|
-
{
|
|
3061
|
-
value: "google-genai",
|
|
3062
|
-
label: "Google Generative AI"
|
|
3063
|
-
}
|
|
3064
|
-
];
|
|
3065
|
-
function ProviderCredentialFields({ attemptedSave, apiKey, api, baseUrl, modelId, models, displayName, isCustom, onApiKeyChange, onApiChange, onBaseUrlChange, onModelIdChange, onModelsChange, onDisplayNameChange, onTogglePassword, openAiChat, placeholder, showPassword }) {
|
|
3066
|
-
const showApiSelector = isCustom && onApiChange;
|
|
3067
|
-
const showMultiModels = isCustom && onModelsChange;
|
|
3068
|
-
return /* @__PURE__ */ jsxs(FieldGroup, {
|
|
3069
|
-
className: "gap-2",
|
|
3070
|
-
children: [
|
|
3071
|
-
(openAiChat || isCustom) && onDisplayNameChange ? /* @__PURE__ */ jsx(TextCredentialField, {
|
|
3072
|
-
attemptedSave,
|
|
3073
|
-
icon: Tag,
|
|
3074
|
-
label: "Provider name",
|
|
3075
|
-
placeholder: OPENAI_CHAT_NAME_PLACEHOLDER,
|
|
3076
|
-
value: displayName ?? "",
|
|
3077
|
-
onChange: onDisplayNameChange
|
|
3078
|
-
}) : null,
|
|
3079
|
-
showApiSelector ? /* @__PURE__ */ jsx(ApiSelector, {
|
|
3080
|
-
value: api ?? "openai-completions",
|
|
3081
|
-
onChange: onApiChange
|
|
3082
|
-
}) : null,
|
|
3083
|
-
/* @__PURE__ */ jsx(SecretCredentialField, {
|
|
3084
|
-
attemptedSave,
|
|
3085
|
-
label: "API key",
|
|
3086
|
-
placeholder,
|
|
3087
|
-
value: apiKey,
|
|
3088
|
-
showPassword,
|
|
3089
|
-
onChange: onApiKeyChange,
|
|
3090
|
-
onToggleVisibility: onTogglePassword
|
|
3091
|
-
}),
|
|
3092
|
-
openAiChat || isCustom ? /* @__PURE__ */ jsx(TextCredentialField, {
|
|
3093
|
-
attemptedSave,
|
|
3094
|
-
icon: Globe,
|
|
3095
|
-
inputType: "url",
|
|
3096
|
-
label: "Base URL",
|
|
3097
|
-
placeholder: OPENAI_CHAT_BASE_URL_PLACEHOLDER,
|
|
3098
|
-
value: baseUrl,
|
|
3099
|
-
onChange: onBaseUrlChange
|
|
3100
|
-
}) : null,
|
|
3101
|
-
showMultiModels ? /* @__PURE__ */ jsx(TextCredentialField, {
|
|
3102
|
-
attemptedSave,
|
|
3103
|
-
icon: Layers,
|
|
3104
|
-
label: "Model ids",
|
|
3105
|
-
placeholder: CUSTOM_MODELS_PLACEHOLDER,
|
|
3106
|
-
value: models ?? "",
|
|
3107
|
-
onChange: onModelsChange
|
|
3108
|
-
}) : null,
|
|
3109
|
-
openAiChat && !showMultiModels ? /* @__PURE__ */ jsx(TextCredentialField, {
|
|
3110
|
-
attemptedSave,
|
|
3111
|
-
icon: Box,
|
|
3112
|
-
label: "Model name",
|
|
3113
|
-
placeholder: OPENAI_CHAT_MODEL_PLACEHOLDER,
|
|
3114
|
-
value: modelId,
|
|
3115
|
-
onChange: onModelIdChange
|
|
3116
|
-
}) : null
|
|
3117
|
-
]
|
|
3118
|
-
});
|
|
3119
|
-
}
|
|
3120
|
-
function ApiSelector({ value, onChange }) {
|
|
3121
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
3122
|
-
className: "flex flex-col gap-1",
|
|
3123
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3124
|
-
className: "text-xs font-medium text-muted-foreground",
|
|
3125
|
-
children: "API family"
|
|
3126
|
-
}), /* @__PURE__ */ jsx(Select, {
|
|
3127
|
-
"aria-label": "API family",
|
|
3128
|
-
value,
|
|
3129
|
-
options: CUSTOM_PROVIDER_API_OPTIONS,
|
|
3130
|
-
placeholder: "Select API family",
|
|
3131
|
-
onValueChange: (next) => onChange(next)
|
|
3132
|
-
})]
|
|
3133
|
-
});
|
|
3134
|
-
}
|
|
3135
|
-
function isOAuthProvider(provider) {
|
|
3136
|
-
return provider.authType === "oauth";
|
|
3137
|
-
}
|
|
3138
|
-
function supportsOAuth(provider) {
|
|
3139
|
-
return provider.supportsOAuth === true;
|
|
2967
|
+
function modelPatternFor(model) {
|
|
2968
|
+
return modelPattern(model.provider, model.modelId);
|
|
3140
2969
|
}
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
function parseCustomProviderModels(raw) {
|
|
3149
|
-
return raw.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
2970
|
+
function searchableModelText(model) {
|
|
2971
|
+
return [
|
|
2972
|
+
model.name,
|
|
2973
|
+
model.modelId,
|
|
2974
|
+
model.provider,
|
|
2975
|
+
model.id
|
|
2976
|
+
].join(" ").toLowerCase();
|
|
3150
2977
|
}
|
|
3151
|
-
function
|
|
3152
|
-
const [
|
|
3153
|
-
const [
|
|
3154
|
-
const
|
|
3155
|
-
const
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
if (!query) return activeProviders;
|
|
3174
|
-
return activeProviders.filter((provider) => providerMatchesQuery(provider, query));
|
|
3175
|
-
}, [activeProviders, searchQuery]);
|
|
3176
|
-
const filteredPickerAvailable = useMemo2(() => {
|
|
3177
|
-
const query = addPickerQuery.trim().toLowerCase();
|
|
3178
|
-
return unconfiguredProviders.filter((provider) => providerMatchesQuery(provider, query));
|
|
3179
|
-
}, [addPickerQuery, unconfiguredProviders]);
|
|
3180
|
-
const filteredPickerConfigured = useMemo2(() => {
|
|
3181
|
-
const query = addPickerQuery.trim().toLowerCase();
|
|
3182
|
-
return activeProviders.filter((provider) => providerMatchesQuery(provider, query));
|
|
3183
|
-
}, [activeProviders, addPickerQuery]);
|
|
3184
|
-
const pickerHasResults = filteredPickerAvailable.length > 0 || filteredPickerConfigured.length > 0;
|
|
3185
|
-
const editingUnconfiguredProvider = editingProvider && !activeProviders.some((provider) => provider.id === editingProvider) ? credentialProviders.find((entry) => entry.id === editingProvider) ?? null : null;
|
|
3186
|
-
const resetEditor = () => {
|
|
3187
|
-
setApiKey("");
|
|
3188
|
-
setBaseUrl("");
|
|
3189
|
-
setModelId("");
|
|
3190
|
-
setModels("");
|
|
3191
|
-
setApi("openai-completions");
|
|
3192
|
-
setDisplayName("");
|
|
3193
|
-
setShowPassword(false);
|
|
3194
|
-
setAttemptedSave(false);
|
|
3195
|
-
};
|
|
3196
|
-
const closeEditor = () => {
|
|
3197
|
-
setEditingProvider(null);
|
|
3198
|
-
setEditingIsNewOccInstance(false);
|
|
3199
|
-
resetEditor();
|
|
3200
|
-
};
|
|
3201
|
-
const openEditor = (providerId, opts) => {
|
|
3202
|
-
setAddPickerOpen(false);
|
|
3203
|
-
setAddPickerQuery("");
|
|
3204
|
-
setEditingProvider(providerId);
|
|
3205
|
-
setEditingIsNewOccInstance(opts?.newOccInstance === true);
|
|
3206
|
-
resetEditor();
|
|
3207
|
-
const existing = providers.find((provider) => provider.id === providerId);
|
|
3208
|
-
setBaseUrl(existing?.baseUrl ?? "");
|
|
3209
|
-
setDisplayName(existing?.displayName ?? (isCustomProviderId(providerId) ? existing?.name ?? "" : ""));
|
|
3210
|
-
setApi(existing?.api ?? "openai-completions");
|
|
3211
|
-
setModels((existing?.modelIds ?? []).join(", "));
|
|
3212
|
-
setModelId(existing?.modelIds?.[0] ?? "");
|
|
3213
|
-
};
|
|
3214
|
-
const openAddPicker = () => {
|
|
3215
|
-
closeEditor();
|
|
3216
|
-
setAddPickerQuery("");
|
|
3217
|
-
setAddPickerOpen(true);
|
|
3218
|
-
};
|
|
3219
|
-
const closeAddPicker = () => {
|
|
3220
|
-
setAddPickerOpen(false);
|
|
3221
|
-
setAddPickerQuery("");
|
|
3222
|
-
};
|
|
3223
|
-
const selectProviderFromPicker = (providerId) => {
|
|
3224
|
-
openEditor(providerId, { newOccInstance: isOccProviderId(providerId) });
|
|
3225
|
-
};
|
|
3226
|
-
const handleSave = async (providerId) => {
|
|
3227
|
-
if (!onUpdateProvider) return;
|
|
3228
|
-
setAttemptedSave(true);
|
|
3229
|
-
const isCustomEditor = providerId === "custom" || isCustomProviderId(providerId);
|
|
3230
|
-
const openAiChat = isOccProviderId(providerId);
|
|
3231
|
-
if (isCustomEditor) {
|
|
3232
|
-
const modelList = parseCustomProviderModels(models);
|
|
3233
|
-
if (!apiKey.trim() || !baseUrl.trim() || !displayName.trim()) return;
|
|
3234
|
-
if (modelList.length === 0) return;
|
|
3235
|
-
try {
|
|
3236
|
-
await onUpdateProvider({
|
|
3237
|
-
providerId,
|
|
3238
|
-
apiKey: apiKey.trim(),
|
|
3239
|
-
baseUrl: baseUrl.trim(),
|
|
3240
|
-
displayName: displayName.trim(),
|
|
3241
|
-
api,
|
|
3242
|
-
models: modelList,
|
|
3243
|
-
...providerId === "custom" ? { createOccInstance: true } : {}
|
|
3244
|
-
});
|
|
3245
|
-
notify.success("Provider credentials applied to your active sessions.");
|
|
3246
|
-
closeEditor();
|
|
3247
|
-
closeAddPicker();
|
|
3248
|
-
} catch (error) {
|
|
3249
|
-
notify.error(error instanceof Error ? error.message : "Failed to update provider");
|
|
3250
|
-
}
|
|
3251
|
-
return;
|
|
3252
|
-
}
|
|
3253
|
-
const isNamedOcc = openAiChat && isNamedOccInstanceId(providerId);
|
|
3254
|
-
const isOccLike = openAiChat && (isNamedOcc || editingIsNewOccInstance);
|
|
3255
|
-
if (!apiKey.trim()) return;
|
|
3256
|
-
if (openAiChat && (!baseUrl.trim() || !modelId.trim())) return;
|
|
3257
|
-
if (isOccLike && !displayName.trim()) return;
|
|
3258
|
-
try {
|
|
3259
|
-
await onUpdateProvider({
|
|
3260
|
-
providerId,
|
|
3261
|
-
apiKey: apiKey.trim(),
|
|
3262
|
-
...openAiChat ? {
|
|
3263
|
-
baseUrl: baseUrl.trim(),
|
|
3264
|
-
modelId: modelId.trim(),
|
|
3265
|
-
...isOccLike ? { displayName: displayName.trim() } : {},
|
|
3266
|
-
...editingIsNewOccInstance ? { createOccInstance: true } : {}
|
|
3267
|
-
} : {}
|
|
3268
|
-
});
|
|
3269
|
-
notify.success("Provider credentials applied to your active sessions.");
|
|
3270
|
-
closeEditor();
|
|
3271
|
-
closeAddPicker();
|
|
3272
|
-
} catch (error) {
|
|
3273
|
-
notify.error(error instanceof Error ? error.message : "Failed to update provider");
|
|
2978
|
+
function AddModelsDialog({ configuredProviderIds, discoverableProviderIds, discoveringProviderId, enabledModels, modelOptions, onAddModels, onDiscoverProvider, onOpenChange, open, providerLabel = formatProviderLabel }) {
|
|
2979
|
+
const [filter, setFilter] = useState2("");
|
|
2980
|
+
const [selectedKeys, setSelectedKeys] = useState2(/* @__PURE__ */ new Set());
|
|
2981
|
+
const normalizedFilter = filter.trim().toLowerCase();
|
|
2982
|
+
const candidateModels = useMemo2(() => {
|
|
2983
|
+
return modelOptions.filter((model) => {
|
|
2984
|
+
if (!configuredProviderIds.has(model.provider)) return false;
|
|
2985
|
+
if (isModelEnabled(model, enabledModels)) return false;
|
|
2986
|
+
return !normalizedFilter || searchableModelText(model).includes(normalizedFilter);
|
|
2987
|
+
});
|
|
2988
|
+
}, [
|
|
2989
|
+
configuredProviderIds,
|
|
2990
|
+
enabledModels,
|
|
2991
|
+
modelOptions,
|
|
2992
|
+
normalizedFilter
|
|
2993
|
+
]);
|
|
2994
|
+
const groupedCandidates = useMemo2(() => {
|
|
2995
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2996
|
+
for (const model of candidateModels) {
|
|
2997
|
+
const existing = groups.get(model.provider);
|
|
2998
|
+
if (existing) existing.push(model);
|
|
2999
|
+
else groups.set(model.provider, [model]);
|
|
3274
3000
|
}
|
|
3001
|
+
return [...groups.entries()];
|
|
3002
|
+
}, [candidateModels]);
|
|
3003
|
+
const discoverableProviders = useMemo2(() => {
|
|
3004
|
+
const ids = discoverableProviderIds ?? configuredProviderIds;
|
|
3005
|
+
return Array.from(ids).filter((id) => configuredProviderIds.has(id)).sort((a, b) => providerLabel(a).localeCompare(providerLabel(b)));
|
|
3006
|
+
}, [
|
|
3007
|
+
configuredProviderIds,
|
|
3008
|
+
discoverableProviderIds,
|
|
3009
|
+
providerLabel
|
|
3010
|
+
]);
|
|
3011
|
+
const activeCountByProvider = useMemo2(() => {
|
|
3012
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3013
|
+
for (const model of modelOptions) if (isModelEnabled(model, enabledModels)) counts.set(model.provider, (counts.get(model.provider) ?? 0) + 1);
|
|
3014
|
+
return counts;
|
|
3015
|
+
}, [enabledModels, modelOptions]);
|
|
3016
|
+
const toggleSelected = (model) => {
|
|
3017
|
+
setSelectedKeys((current) => {
|
|
3018
|
+
const next = new Set(current);
|
|
3019
|
+
if (next.has(model.id)) next.delete(model.id);
|
|
3020
|
+
else next.add(model.id);
|
|
3021
|
+
return next;
|
|
3022
|
+
});
|
|
3275
3023
|
};
|
|
3276
|
-
const
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
if (editingProvider === provider.id) closeEditor();
|
|
3281
|
-
notify.success(`${provider.name} removed from your configured providers.`);
|
|
3282
|
-
setConfirmRemoveProvider(null);
|
|
3283
|
-
} catch (error) {
|
|
3284
|
-
notify.error(error instanceof Error ? error.message : "Failed to remove provider");
|
|
3285
|
-
}
|
|
3024
|
+
const confirmAdd = () => {
|
|
3025
|
+
const selected = candidateModels.filter((model) => selectedKeys.has(model.id));
|
|
3026
|
+
if (selected.length > 0) onAddModels(selected);
|
|
3027
|
+
onOpenChange(false);
|
|
3286
3028
|
};
|
|
3287
|
-
return {
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3029
|
+
return /* @__PURE__ */ jsx(Dialog, {
|
|
3030
|
+
open,
|
|
3031
|
+
onOpenChange,
|
|
3032
|
+
children: /* @__PURE__ */ jsxs(DialogContent, {
|
|
3033
|
+
className: "max-w-lg",
|
|
3034
|
+
children: [
|
|
3035
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Add models" }), /* @__PURE__ */ jsxs(DialogDescription, { children: [
|
|
3036
|
+
"Pick models discovered from your configured providers. For OpenAI Chat Completions, refresh runs",
|
|
3037
|
+
" ",
|
|
3038
|
+
/* @__PURE__ */ jsxs("span", {
|
|
3039
|
+
className: "font-medium",
|
|
3040
|
+
children: ["GET ", "{baseUrl}/models"]
|
|
3041
|
+
}),
|
|
3042
|
+
"."
|
|
3043
|
+
] })] }),
|
|
3044
|
+
/* @__PURE__ */ jsx("div", {
|
|
3045
|
+
className: "flex flex-wrap gap-1.5",
|
|
3046
|
+
children: discoverableProviders.map((providerId) => {
|
|
3047
|
+
const discovering = discoveringProviderId === providerId;
|
|
3048
|
+
const activeCount = activeCountByProvider.get(providerId) ?? 0;
|
|
3049
|
+
return /* @__PURE__ */ jsxs(Button, {
|
|
3050
|
+
type: "button",
|
|
3051
|
+
variant: "outline",
|
|
3052
|
+
size: "sm",
|
|
3053
|
+
disabled: discoveringProviderId !== null,
|
|
3054
|
+
onClick: () => {
|
|
3055
|
+
onDiscoverProvider(providerId);
|
|
3056
|
+
},
|
|
3057
|
+
children: [
|
|
3058
|
+
discovering ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : /* @__PURE__ */ jsx(RefreshCw, { "data-icon": "inline-start" }),
|
|
3059
|
+
providerLabel(providerId),
|
|
3060
|
+
activeCount > 0 ? /* @__PURE__ */ jsxs("span", {
|
|
3061
|
+
className: "tabular-nums text-muted-foreground",
|
|
3062
|
+
children: [
|
|
3063
|
+
"\xB7 ",
|
|
3064
|
+
activeCount,
|
|
3065
|
+
" active"
|
|
3066
|
+
]
|
|
3067
|
+
}) : null
|
|
3068
|
+
]
|
|
3069
|
+
}, providerId);
|
|
3070
|
+
})
|
|
3071
|
+
}),
|
|
3072
|
+
/* @__PURE__ */ jsxs(InputGroup, { children: [/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
3073
|
+
align: "inline-start",
|
|
3074
|
+
children: /* @__PURE__ */ jsx(Search, {})
|
|
3075
|
+
}), /* @__PURE__ */ jsx(InputGroupInput, {
|
|
3076
|
+
"aria-label": "Search discovered models",
|
|
3077
|
+
value: filter,
|
|
3078
|
+
onChange: (event) => setFilter(event.target.value),
|
|
3079
|
+
placeholder: "Search discovered models\u2026"
|
|
3080
|
+
})] }),
|
|
3081
|
+
/* @__PURE__ */ jsx("div", {
|
|
3082
|
+
className: "max-h-72 overflow-y-auto",
|
|
3083
|
+
children: groupedCandidates.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
3084
|
+
className: "py-6 text-center text-xs text-pretty text-muted-foreground",
|
|
3085
|
+
children: candidateModels.length === 0 && !normalizedFilter ? "All discovered models are already in your list, or none are available yet." : "No models match your search."
|
|
3086
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
3087
|
+
className: "flex flex-col gap-3",
|
|
3088
|
+
children: groupedCandidates.map(([provider, models]) => /* @__PURE__ */ jsxs("div", {
|
|
3089
|
+
className: "flex flex-col gap-1",
|
|
3090
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
3091
|
+
className: "px-2 text-[0.6875rem] font-medium tracking-wide text-muted-foreground uppercase",
|
|
3092
|
+
children: [providerLabel(provider), (activeCountByProvider.get(provider) ?? 0) > 0 ? /* @__PURE__ */ jsxs("span", {
|
|
3093
|
+
className: "ml-1 font-normal normal-case tabular-nums",
|
|
3094
|
+
children: [
|
|
3095
|
+
"\xB7 ",
|
|
3096
|
+
activeCountByProvider.get(provider),
|
|
3097
|
+
" active"
|
|
3098
|
+
]
|
|
3099
|
+
}) : null]
|
|
3100
|
+
}), models.map((model) => {
|
|
3101
|
+
const checked = selectedKeys.has(model.id);
|
|
3102
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
3103
|
+
type: "button",
|
|
3104
|
+
className: cn("flex w-full items-center gap-3 rounded-lg px-2 py-2 text-left transition-[background-color,transform] duration-150", "hover:bg-muted/60 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none active:scale-[0.96]", checked && "bg-muted/70"),
|
|
3105
|
+
"aria-pressed": checked,
|
|
3106
|
+
onClick: () => toggleSelected(model),
|
|
3107
|
+
children: [
|
|
3108
|
+
/* @__PURE__ */ jsx("div", {
|
|
3109
|
+
className: "flex size-8 shrink-0 items-center justify-center rounded-[4px] border border-border/40 bg-background/60",
|
|
3110
|
+
children: /* @__PURE__ */ jsx(ProviderBrandIcon, {
|
|
3111
|
+
provider: model.provider,
|
|
3112
|
+
className: "text-foreground/70"
|
|
3113
|
+
})
|
|
3114
|
+
}),
|
|
3115
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3116
|
+
className: "min-w-0 flex-1",
|
|
3117
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
3118
|
+
className: "truncate text-sm font-medium",
|
|
3119
|
+
children: model.name
|
|
3120
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
3121
|
+
className: "truncate text-xs text-muted-foreground",
|
|
3122
|
+
children: model.modelId
|
|
3123
|
+
})]
|
|
3124
|
+
}),
|
|
3125
|
+
/* @__PURE__ */ jsx("span", {
|
|
3126
|
+
className: cn("size-4 rounded border border-border/60", checked && "border-foreground bg-foreground"),
|
|
3127
|
+
"aria-hidden": true
|
|
3128
|
+
})
|
|
3129
|
+
]
|
|
3130
|
+
}, model.id);
|
|
3131
|
+
})]
|
|
3132
|
+
}, provider))
|
|
3133
|
+
})
|
|
3134
|
+
}),
|
|
3135
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3136
|
+
className: "flex items-center justify-end gap-1.5",
|
|
3137
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
3138
|
+
type: "button",
|
|
3139
|
+
variant: "ghost",
|
|
3140
|
+
size: "sm",
|
|
3141
|
+
onClick: () => onOpenChange(false),
|
|
3142
|
+
children: "Cancel"
|
|
3143
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
3144
|
+
type: "button",
|
|
3145
|
+
size: "sm",
|
|
3146
|
+
disabled: selectedKeys.size === 0,
|
|
3147
|
+
onClick: confirmAdd,
|
|
3148
|
+
children: ["Add ", selectedKeys.size > 0 ? /* @__PURE__ */ jsxs("span", {
|
|
3149
|
+
className: "tabular-nums",
|
|
3150
|
+
children: [
|
|
3151
|
+
"(",
|
|
3152
|
+
selectedKeys.size,
|
|
3153
|
+
")"
|
|
3154
|
+
]
|
|
3155
|
+
}) : null]
|
|
3386
3156
|
})]
|
|
3387
|
-
})]
|
|
3388
|
-
}),
|
|
3389
|
-
/* @__PURE__ */ jsxs(InputGroup, { children: [/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
3390
|
-
align: "inline-start",
|
|
3391
|
-
children: /* @__PURE__ */ jsx(Search, {})
|
|
3392
|
-
}), /* @__PURE__ */ jsx(InputGroupInput, {
|
|
3393
|
-
type: "text",
|
|
3394
|
-
placeholder: "Search providers\u2026",
|
|
3395
|
-
value: addPickerQuery,
|
|
3396
|
-
onChange: (event) => onQueryChange(event.target.value),
|
|
3397
|
-
"aria-label": "Search providers to add"
|
|
3398
|
-
})] }),
|
|
3399
|
-
/* @__PURE__ */ jsx("div", {
|
|
3400
|
-
className: "max-h-[min(24rem,50vh)] overflow-y-auto",
|
|
3401
|
-
children: !pickerHasResults ? /* @__PURE__ */ jsx("p", {
|
|
3402
|
-
className: "py-6 text-center text-xs text-pretty text-muted-foreground",
|
|
3403
|
-
children: credentialProvidersLength === 0 ? "No providers available." : "No matching providers found."
|
|
3404
|
-
}) : /* @__PURE__ */ jsxs("div", {
|
|
3405
|
-
className: "flex flex-col gap-3",
|
|
3406
|
-
children: [filteredPickerAvailable.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
3407
|
-
className: "flex flex-col gap-1",
|
|
3408
|
-
children: filteredPickerAvailable.map((provider) => /* @__PURE__ */ jsx(ProviderPickerRow, {
|
|
3409
|
-
provider,
|
|
3410
|
-
configured: false,
|
|
3411
|
-
onSelect: () => onSelect(provider.id)
|
|
3412
|
-
}, provider.id))
|
|
3413
|
-
}) : null, filteredPickerConfigured.length > 0 ? /* @__PURE__ */ jsxs("div", {
|
|
3414
|
-
className: "flex flex-col gap-1",
|
|
3415
|
-
children: [filteredPickerAvailable.length > 0 ? /* @__PURE__ */ jsx("p", {
|
|
3416
|
-
className: "px-2 pt-1 text-[0.6875rem] font-medium tracking-wide text-muted-foreground uppercase",
|
|
3417
|
-
children: "Already configured"
|
|
3418
|
-
}) : null, filteredPickerConfigured.map((provider) => /* @__PURE__ */ jsx(ProviderPickerRow, {
|
|
3419
|
-
provider,
|
|
3420
|
-
configured: true,
|
|
3421
|
-
onSelect: () => onSelect(provider.id)
|
|
3422
|
-
}, provider.id))]
|
|
3423
|
-
}) : null]
|
|
3424
3157
|
})
|
|
3425
|
-
|
|
3426
|
-
|
|
3158
|
+
]
|
|
3159
|
+
})
|
|
3427
3160
|
});
|
|
3428
3161
|
}
|
|
3429
|
-
function
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3162
|
+
function ModelDefaultsSection({ draft, discoveringProviderId, modelDirty, modelFilter, modelOptions, onAddModels, onDiscoverProvider, onModelFilterChange, onRemoveModel, onSetDefaultModel, onRevert, onSave, providers, saving, settingsLoading }) {
|
|
3163
|
+
const [addOpen, setAddOpen] = useState2(false);
|
|
3164
|
+
const disabled2 = !draft || settingsLoading;
|
|
3165
|
+
const normalizedFilter = modelFilter.trim().toLowerCase();
|
|
3166
|
+
const configuredProviderIds = useMemo2(() => {
|
|
3167
|
+
const ids = /* @__PURE__ */ new Set();
|
|
3168
|
+
for (const provider of providers) if (provider.isConfigured) ids.add(provider.id);
|
|
3169
|
+
for (const model of modelOptions) if (isModelEnabled(model, draft?.enabledModels)) ids.add(model.provider);
|
|
3170
|
+
return ids;
|
|
3171
|
+
}, [
|
|
3172
|
+
draft?.enabledModels,
|
|
3173
|
+
modelOptions,
|
|
3174
|
+
providers
|
|
3175
|
+
]);
|
|
3176
|
+
const discoverableProviderIds = useMemo2(() => {
|
|
3177
|
+
const ids = /* @__PURE__ */ new Set();
|
|
3178
|
+
for (const provider of providers) if (provider.discoverable === true && configuredProviderIds.has(provider.id)) ids.add(provider.id);
|
|
3179
|
+
return ids;
|
|
3180
|
+
}, [configuredProviderIds, providers]);
|
|
3181
|
+
const isDefaultModel = useMemo2(() => {
|
|
3182
|
+
return (model) => !!draft?.defaultProvider && !!draft?.defaultModel && model.provider === draft.defaultProvider && model.modelId === draft.defaultModel;
|
|
3183
|
+
}, [draft?.defaultModel, draft?.defaultProvider]);
|
|
3184
|
+
const providerLabel = useMemo2(() => {
|
|
3185
|
+
const labels = /* @__PURE__ */ new Map();
|
|
3186
|
+
for (const provider of providers) if (provider.displayName || provider.name) labels.set(provider.id, provider.displayName ?? provider.name ?? provider.id);
|
|
3187
|
+
return (providerId) => labels.get(providerId) ?? formatProviderLabel(providerId);
|
|
3188
|
+
}, [providers]);
|
|
3189
|
+
const listedModels = useMemo2(() => {
|
|
3190
|
+
return modelOptions.filter((model) => {
|
|
3191
|
+
if (!isModelEnabled(model, draft?.enabledModels)) return false;
|
|
3192
|
+
if (!normalizedFilter) return true;
|
|
3193
|
+
return [
|
|
3194
|
+
model.name,
|
|
3195
|
+
model.modelId,
|
|
3196
|
+
model.provider,
|
|
3197
|
+
model.id
|
|
3198
|
+
].join(" ").toLowerCase().includes(normalizedFilter);
|
|
3199
|
+
});
|
|
3200
|
+
}, [
|
|
3201
|
+
draft?.enabledModels,
|
|
3202
|
+
modelOptions,
|
|
3203
|
+
normalizedFilter
|
|
3204
|
+
]);
|
|
3205
|
+
const groupedListed = useMemo2(() => {
|
|
3206
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3207
|
+
for (const model of listedModels) {
|
|
3208
|
+
const existing = groups.get(model.provider);
|
|
3209
|
+
if (existing) existing.push(model);
|
|
3210
|
+
else groups.set(model.provider, [model]);
|
|
3211
|
+
}
|
|
3212
|
+
return [...groups.entries()];
|
|
3213
|
+
}, [listedModels]);
|
|
3214
|
+
const emptyMessage = (() => {
|
|
3215
|
+
if (modelOptions.length === 0) return "No models discovered yet. Configure a provider, then add models.";
|
|
3216
|
+
if (listedModels.length === 0 && !normalizedFilter) return "Add models from your configured providers to make them available in chat.";
|
|
3217
|
+
if (listedModels.length === 0) return "No models match your search.";
|
|
3218
|
+
return null;
|
|
3219
|
+
})();
|
|
3220
|
+
const openAddDialog = () => {
|
|
3221
|
+
setAddOpen(true);
|
|
3222
|
+
};
|
|
3223
|
+
return /* @__PURE__ */ jsxs(SettingsPane, {
|
|
3224
|
+
title: "LLM Models",
|
|
3225
|
+
description: /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3226
|
+
"Models available in chat. Discover from configured providers, add the ones you want, and remove any you do not need \u2014 changes save automatically. ",
|
|
3227
|
+
/* @__PURE__ */ jsx("span", {
|
|
3228
|
+
className: "tabular-nums",
|
|
3229
|
+
children: listedModels.length
|
|
3230
|
+
}),
|
|
3231
|
+
" in list",
|
|
3232
|
+
modelOptions.length > 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3233
|
+
" ",
|
|
3234
|
+
"\xB7 ",
|
|
3235
|
+
/* @__PURE__ */ jsx("span", {
|
|
3236
|
+
className: "tabular-nums",
|
|
3237
|
+
children: modelOptions.length
|
|
3238
|
+
}),
|
|
3239
|
+
" discovered"
|
|
3240
|
+
] }) : null,
|
|
3241
|
+
"."
|
|
3242
|
+
] }),
|
|
3243
|
+
actions: /* @__PURE__ */ jsx(SettingsCommitActions, {
|
|
3244
|
+
dirty: modelDirty,
|
|
3245
|
+
disabled: disabled2,
|
|
3246
|
+
onRevert,
|
|
3247
|
+
onSave,
|
|
3248
|
+
saving
|
|
3249
|
+
}),
|
|
3468
3250
|
children: [
|
|
3469
3251
|
/* @__PURE__ */ jsxs("div", {
|
|
3470
3252
|
className: "flex items-center gap-2",
|
|
3471
|
-
children: [/* @__PURE__ */
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
children: ["Configure ", provider.name]
|
|
3483
|
-
}), /* @__PURE__ */ jsx("p", {
|
|
3484
|
-
className: "text-xs text-pretty text-muted-foreground",
|
|
3485
|
-
children: isCustomTemplate ? "Name this custom provider, pick its API family, then enter its API key, https base URL, and model ids." : openAiChat ? "Name this OpenAI-compatible provider, then enter its API key, base URL, and model name." : `Stored as ${provider.envVarName} for this account.`
|
|
3253
|
+
children: [/* @__PURE__ */ jsxs(InputGroup, {
|
|
3254
|
+
className: "flex-1",
|
|
3255
|
+
children: [/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
3256
|
+
align: "inline-start",
|
|
3257
|
+
children: /* @__PURE__ */ jsx(Search, {})
|
|
3258
|
+
}), /* @__PURE__ */ jsx(InputGroupInput, {
|
|
3259
|
+
"aria-label": "Search listed models",
|
|
3260
|
+
value: modelFilter,
|
|
3261
|
+
onChange: (event) => onModelFilterChange(event.target.value),
|
|
3262
|
+
placeholder: "Search listed models\u2026",
|
|
3263
|
+
disabled: disabled2 || listedModels.length === 0
|
|
3486
3264
|
})]
|
|
3487
|
-
})]
|
|
3488
|
-
}),
|
|
3489
|
-
/* @__PURE__ */ jsx(ProviderCredentialFields, {
|
|
3490
|
-
attemptedSave,
|
|
3491
|
-
api,
|
|
3492
|
-
apiKey,
|
|
3493
|
-
baseUrl,
|
|
3494
|
-
modelId,
|
|
3495
|
-
models,
|
|
3496
|
-
displayName,
|
|
3497
|
-
isCustom: isCustomTemplate,
|
|
3498
|
-
openAiChat,
|
|
3499
|
-
placeholder: meta.placeholder,
|
|
3500
|
-
showPassword,
|
|
3501
|
-
onApiKeyChange,
|
|
3502
|
-
onApiChange,
|
|
3503
|
-
onBaseUrlChange,
|
|
3504
|
-
onModelIdChange,
|
|
3505
|
-
onModelsChange,
|
|
3506
|
-
onDisplayNameChange,
|
|
3507
|
-
onTogglePassword
|
|
3508
|
-
}),
|
|
3509
|
-
/* @__PURE__ */ jsxs(Alert, {
|
|
3510
|
-
className: "px-3 py-2",
|
|
3511
|
-
children: [/* @__PURE__ */ jsx(Info, {}), /* @__PURE__ */ jsx(AlertDescription, {
|
|
3512
|
-
className: "text-xs text-pretty",
|
|
3513
|
-
children: meta.help
|
|
3514
|
-
})]
|
|
3515
|
-
}),
|
|
3516
|
-
/* @__PURE__ */ jsxs("div", {
|
|
3517
|
-
className: "flex items-center justify-end gap-1.5",
|
|
3518
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
3519
|
-
type: "button",
|
|
3520
|
-
variant: "ghost",
|
|
3521
|
-
size: "sm",
|
|
3522
|
-
onClick: onCancel,
|
|
3523
|
-
children: "Cancel"
|
|
3524
3265
|
}), /* @__PURE__ */ jsxs(Button, {
|
|
3525
3266
|
type: "button",
|
|
3267
|
+
variant: "outline",
|
|
3526
3268
|
size: "sm",
|
|
3527
|
-
disabled:
|
|
3528
|
-
onClick:
|
|
3529
|
-
children: [
|
|
3269
|
+
disabled: disabled2,
|
|
3270
|
+
onClick: openAddDialog,
|
|
3271
|
+
children: [/* @__PURE__ */ jsx(Plus, { "data-icon": "inline-start" }), "Add models"]
|
|
3530
3272
|
})]
|
|
3531
3273
|
}),
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3274
|
+
/* @__PURE__ */ jsx("div", {
|
|
3275
|
+
className: "flex flex-col gap-3",
|
|
3276
|
+
"data-testid": "runtime-models-list",
|
|
3277
|
+
children: emptyMessage ? /* @__PURE__ */ jsxs("div", {
|
|
3278
|
+
className: "flex flex-col items-center gap-3 py-8",
|
|
3279
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
3280
|
+
className: "px-1 text-center text-xs text-pretty text-muted-foreground",
|
|
3281
|
+
children: emptyMessage
|
|
3282
|
+
}), !normalizedFilter ? /* @__PURE__ */ jsxs(Button, {
|
|
3283
|
+
type: "button",
|
|
3284
|
+
variant: "outline",
|
|
3285
|
+
size: "sm",
|
|
3286
|
+
disabled: disabled2,
|
|
3287
|
+
onClick: openAddDialog,
|
|
3288
|
+
children: [/* @__PURE__ */ jsx(Plus, { "data-icon": "inline-start" }), "Add models"]
|
|
3289
|
+
}) : null]
|
|
3290
|
+
}) : groupedListed.map(([provider, models]) => /* @__PURE__ */ jsxs("div", {
|
|
3291
|
+
className: "flex flex-col gap-1.5",
|
|
3292
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
3293
|
+
className: "px-1 text-xs font-medium text-muted-foreground",
|
|
3294
|
+
children: providerLabel(provider)
|
|
3295
|
+
}), models.map((model) => /* @__PURE__ */ jsx(ItemRow, {
|
|
3296
|
+
icon: /* @__PURE__ */ jsx(ProviderBrandIcon, { provider: model.provider }),
|
|
3297
|
+
title: model.name,
|
|
3298
|
+
subtitle: `${providerLabel(model.provider)} \xB7 ${model.modelId}`,
|
|
3299
|
+
trailing: /* @__PURE__ */ jsxs("div", {
|
|
3300
|
+
className: "flex items-center",
|
|
3301
|
+
children: [isDefaultModel(model) ? /* @__PURE__ */ jsx("span", {
|
|
3302
|
+
className: "px-2 text-xs font-medium text-muted-foreground",
|
|
3303
|
+
children: "Default"
|
|
3304
|
+
}) : onSetDefaultModel ? /* @__PURE__ */ jsxs(Button, {
|
|
3305
|
+
type: "button",
|
|
3306
|
+
variant: "ghost",
|
|
3307
|
+
size: "sm",
|
|
3308
|
+
className: cn(HIT_AREA_EXPAND_DENSE_CLASS, "h-7 px-2 text-xs text-muted-foreground transition-[background-color,color,transform] duration-150 active:scale-[0.96]"),
|
|
3309
|
+
disabled: disabled2,
|
|
3310
|
+
"aria-label": `Set ${model.name} as default`,
|
|
3311
|
+
onClick: () => onSetDefaultModel(model),
|
|
3312
|
+
children: [/* @__PURE__ */ jsx(Star, { "data-icon": "inline-start" }), "Set default"]
|
|
3313
|
+
}) : null, /* @__PURE__ */ jsxs(Button, {
|
|
3314
|
+
type: "button",
|
|
3315
|
+
variant: "ghost",
|
|
3316
|
+
size: "sm",
|
|
3317
|
+
className: cn(HIT_AREA_EXPAND_DENSE_CLASS, "h-7 px-2 text-xs text-muted-foreground transition-[background-color,color,transform] duration-150 hover:text-destructive active:scale-[0.96]"),
|
|
3318
|
+
disabled: disabled2,
|
|
3319
|
+
"aria-label": `Remove ${model.name}`,
|
|
3320
|
+
onClick: () => onRemoveModel(model),
|
|
3321
|
+
children: [/* @__PURE__ */ jsx(Trash2, { "data-icon": "inline-start" }), "Remove"]
|
|
3322
|
+
})]
|
|
3323
|
+
})
|
|
3324
|
+
}, model.id))]
|
|
3325
|
+
}, provider))
|
|
3326
|
+
}),
|
|
3327
|
+
/* @__PURE__ */ jsx(AddModelsDialog, {
|
|
3328
|
+
open: addOpen,
|
|
3329
|
+
configuredProviderIds,
|
|
3330
|
+
discoverableProviderIds,
|
|
3331
|
+
discoveringProviderId,
|
|
3332
|
+
enabledModels: draft?.enabledModels,
|
|
3333
|
+
modelOptions,
|
|
3334
|
+
onAddModels,
|
|
3335
|
+
onDiscoverProvider,
|
|
3336
|
+
onOpenChange: setAddOpen,
|
|
3337
|
+
providerLabel
|
|
3338
|
+
})
|
|
3537
3339
|
]
|
|
3538
3340
|
});
|
|
3539
3341
|
}
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
}
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
className: cn("flex w-full items-center gap-3 rounded-lg px-2 py-2 text-left transition-[background-color,transform] duration-150", "hover:bg-muted/60 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none active:scale-[0.96]"),
|
|
3573
|
-
onClick: onSelect,
|
|
3574
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
3575
|
-
className: "flex size-8 shrink-0 items-center justify-center rounded-[4px] border border-border/40 bg-background/60",
|
|
3576
|
-
children: /* @__PURE__ */ jsx(ProviderBrandIcon, {
|
|
3577
|
-
provider: isCustomTemplate ? "custom" : provider.id,
|
|
3578
|
-
api: provider.api,
|
|
3579
|
-
className: "text-foreground/70"
|
|
3342
|
+
var THEME_OPTIONS = [
|
|
3343
|
+
{
|
|
3344
|
+
value: "system",
|
|
3345
|
+
label: "System",
|
|
3346
|
+
icon: Monitor
|
|
3347
|
+
},
|
|
3348
|
+
{
|
|
3349
|
+
value: "light",
|
|
3350
|
+
label: "Light",
|
|
3351
|
+
icon: Sun
|
|
3352
|
+
},
|
|
3353
|
+
{
|
|
3354
|
+
value: "dark",
|
|
3355
|
+
label: "Dark",
|
|
3356
|
+
icon: Moon
|
|
3357
|
+
}
|
|
3358
|
+
];
|
|
3359
|
+
function PersonalizationSection({ onThemePreferenceChange, themePreference }) {
|
|
3360
|
+
return /* @__PURE__ */ jsxs(Field, {
|
|
3361
|
+
orientation: "horizontal",
|
|
3362
|
+
className: "items-center justify-between gap-6 rounded-xl border p-4",
|
|
3363
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
3364
|
+
className: "min-w-0",
|
|
3365
|
+
children: [/* @__PURE__ */ jsx(FieldLabel, { children: "Theme" }), /* @__PURE__ */ jsx(FieldDescription, { children: "Match the system theme or pick light or dark." })]
|
|
3366
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
3367
|
+
className: "shrink-0",
|
|
3368
|
+
children: /* @__PURE__ */ jsx(Select, {
|
|
3369
|
+
"aria-label": "Theme",
|
|
3370
|
+
className: "w-[160px]",
|
|
3371
|
+
onValueChange: (value) => onThemePreferenceChange(value),
|
|
3372
|
+
options: [...THEME_OPTIONS],
|
|
3373
|
+
value: themePreference
|
|
3580
3374
|
})
|
|
3581
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
3582
|
-
className: "min-w-0 flex-1",
|
|
3583
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
3584
|
-
className: "truncate text-sm font-medium",
|
|
3585
|
-
children: provider.name
|
|
3586
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
3587
|
-
className: "truncate text-xs text-muted-foreground",
|
|
3588
|
-
children: [oauthOnly ? "OAuth sign-in" : oauthAvailable ? "API key or OAuth" : isCustomTemplate ? "API family + key + https base URL + models" : openAiChat ? "API key + base URL + model name" : provider.envVarName, configured ? " \xB7 Update" : ""]
|
|
3589
|
-
})]
|
|
3590
3375
|
})]
|
|
3591
3376
|
});
|
|
3592
3377
|
}
|
|
3593
|
-
function
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
type: "button",
|
|
3630
|
-
variant: "ghost",
|
|
3631
|
-
size: "sm",
|
|
3632
|
-
className: cn(HIT_AREA_EXPAND_DENSE_CLASS, "h-7 px-2 text-xs transition-[background-color,transform] duration-150 active:scale-[0.96]"),
|
|
3633
|
-
disabled: isPending,
|
|
3634
|
-
onClick: () => {
|
|
3635
|
-
if (isEditing) {
|
|
3636
|
-
onCancelEdit();
|
|
3637
|
-
return;
|
|
3638
|
-
}
|
|
3639
|
-
onEdit(provider.id);
|
|
3640
|
-
},
|
|
3641
|
-
children: [!isEditing ? /* @__PURE__ */ jsx(Pencil, { "data-icon": "inline-start" }) : null, isEditing ? "Cancel" : "Update"]
|
|
3642
|
-
})]
|
|
3643
|
-
})
|
|
3644
|
-
}), isEditing ? /* @__PURE__ */ jsx(RowSurface, {
|
|
3645
|
-
tone: "inset",
|
|
3646
|
-
padding: "md",
|
|
3647
|
-
className: "flex flex-col gap-2 border-t border-border/30",
|
|
3648
|
-
children: oauthOnly ? /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
|
|
3649
|
-
provider,
|
|
3650
|
-
onConfigured,
|
|
3651
|
-
onOAuthLogin
|
|
3652
|
-
}, provider.id) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3653
|
-
/* @__PURE__ */ jsx(ProviderCredentialFields, {
|
|
3654
|
-
attemptedSave,
|
|
3655
|
-
api: provider.api ?? api,
|
|
3656
|
-
apiKey,
|
|
3657
|
-
baseUrl,
|
|
3658
|
-
modelId,
|
|
3659
|
-
models,
|
|
3660
|
-
displayName,
|
|
3661
|
-
isCustom,
|
|
3662
|
-
openAiChat,
|
|
3663
|
-
placeholder: meta.placeholder,
|
|
3664
|
-
showPassword,
|
|
3665
|
-
onApiKeyChange,
|
|
3666
|
-
onApiChange,
|
|
3667
|
-
onBaseUrlChange,
|
|
3668
|
-
onModelIdChange,
|
|
3669
|
-
onModelsChange,
|
|
3670
|
-
onDisplayNameChange: isCustom || provider.providerFamily !== void 0 ? onDisplayNameChange : void 0,
|
|
3671
|
-
onTogglePassword
|
|
3672
|
-
}),
|
|
3673
|
-
/* @__PURE__ */ jsxs(Alert, {
|
|
3674
|
-
className: "px-3 py-2",
|
|
3675
|
-
children: [/* @__PURE__ */ jsx(Info, {}), /* @__PURE__ */ jsx(AlertDescription, {
|
|
3676
|
-
className: "text-xs text-pretty",
|
|
3677
|
-
children: meta.help
|
|
3678
|
-
})]
|
|
3679
|
-
}),
|
|
3680
|
-
/* @__PURE__ */ jsx("div", {
|
|
3681
|
-
className: "flex items-center justify-end",
|
|
3682
|
-
children: /* @__PURE__ */ jsxs(Button, {
|
|
3683
|
-
type: "button",
|
|
3684
|
-
size: "sm",
|
|
3685
|
-
disabled: isPending || !canSave,
|
|
3686
|
-
onClick: () => onSave(provider.id),
|
|
3687
|
-
children: [isPending ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : null, "Save"]
|
|
3688
|
-
})
|
|
3689
|
-
}),
|
|
3690
|
-
oauthAvailable ? /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
|
|
3691
|
-
provider,
|
|
3692
|
-
onConfigured,
|
|
3693
|
-
onOAuthLogin
|
|
3694
|
-
}, `${provider.id}-oauth`) : null
|
|
3695
|
-
] })
|
|
3696
|
-
}) : null]
|
|
3697
|
-
}, provider.id);
|
|
3698
|
-
})
|
|
3378
|
+
function isFieldInvalid(value, attemptedSave, required = true) {
|
|
3379
|
+
return attemptedSave && required && value.trim().length === 0;
|
|
3380
|
+
}
|
|
3381
|
+
function SecretCredentialField({ attemptedSave, label, onChange, onToggleVisibility, placeholder, required = true, showPassword, value }) {
|
|
3382
|
+
const controlId = useId();
|
|
3383
|
+
const invalid = isFieldInvalid(value, attemptedSave, required);
|
|
3384
|
+
return /* @__PURE__ */ jsxs(Field, {
|
|
3385
|
+
"data-invalid": invalid || void 0,
|
|
3386
|
+
children: [/* @__PURE__ */ jsx(FieldLabel, {
|
|
3387
|
+
htmlFor: controlId,
|
|
3388
|
+
children: label
|
|
3389
|
+
}), /* @__PURE__ */ jsxs(InputGroup, { children: [
|
|
3390
|
+
/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
3391
|
+
align: "inline-start",
|
|
3392
|
+
children: /* @__PURE__ */ jsx(Lock, {})
|
|
3393
|
+
}),
|
|
3394
|
+
/* @__PURE__ */ jsx(InputGroupInput, {
|
|
3395
|
+
id: controlId,
|
|
3396
|
+
type: showPassword ? "text" : "password",
|
|
3397
|
+
placeholder,
|
|
3398
|
+
value,
|
|
3399
|
+
onChange: (event) => onChange(event.target.value),
|
|
3400
|
+
"aria-label": label,
|
|
3401
|
+
"aria-invalid": invalid || void 0
|
|
3402
|
+
}),
|
|
3403
|
+
/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
3404
|
+
align: "inline-end",
|
|
3405
|
+
children: /* @__PURE__ */ jsx(InputGroupButton, {
|
|
3406
|
+
size: "icon-xs",
|
|
3407
|
+
className: cn(HIT_AREA_EXPAND_CLASS, "transition-[background-color,transform] duration-150 active:scale-[0.96]"),
|
|
3408
|
+
"aria-label": showPassword ? "Hide value" : "Show value",
|
|
3409
|
+
onClick: onToggleVisibility,
|
|
3410
|
+
children: showPassword ? /* @__PURE__ */ jsx(EyeOff, {}) : /* @__PURE__ */ jsx(Eye, {})
|
|
3411
|
+
})
|
|
3412
|
+
})
|
|
3413
|
+
] })]
|
|
3699
3414
|
});
|
|
3700
3415
|
}
|
|
3701
|
-
function
|
|
3702
|
-
const
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
};
|
|
3722
|
-
const actions = {
|
|
3723
|
-
onApiKeyChange: setApiKey,
|
|
3724
|
-
onApiChange: setApi,
|
|
3725
|
-
onBaseUrlChange: setBaseUrl,
|
|
3726
|
-
onModelIdChange: setModelId,
|
|
3727
|
-
onModelsChange: setModels,
|
|
3728
|
-
onDisplayNameChange: setDisplayName,
|
|
3729
|
-
onTogglePassword: () => setShowPassword((current) => !current)
|
|
3730
|
-
};
|
|
3731
|
-
return /* @__PURE__ */ jsxs(SettingsPane, {
|
|
3732
|
-
title: "Providers",
|
|
3733
|
-
description: "Locally, API keys are stored in `.env.local`. When deployed, they are stored encrypted in your account.",
|
|
3734
|
-
children: [addPickerOpen ? /* @__PURE__ */ jsx(AddProviderPickerPanel, {
|
|
3735
|
-
addPickerQuery,
|
|
3736
|
-
credentialProvidersLength: credentialProviders.length,
|
|
3737
|
-
filteredPickerAvailable,
|
|
3738
|
-
filteredPickerConfigured,
|
|
3739
|
-
pickerHasResults,
|
|
3740
|
-
onClose: closeAddPicker,
|
|
3741
|
-
onQueryChange: setAddPickerQuery,
|
|
3742
|
-
onSelect: selectProviderFromPicker
|
|
3743
|
-
}) : editingUnconfiguredProvider && isOAuthProvider(editingUnconfiguredProvider) ? /* @__PURE__ */ jsx(AddProviderOAuthPanel, {
|
|
3744
|
-
provider: editingUnconfiguredProvider,
|
|
3745
|
-
onBack: openAddPicker,
|
|
3746
|
-
onConfigured: closeEditor,
|
|
3747
|
-
onOAuthLogin
|
|
3748
|
-
}, editingUnconfiguredProvider.id) : editingUnconfiguredProvider ? /* @__PURE__ */ jsx(AddProviderEditorPanel, {
|
|
3749
|
-
provider: editingUnconfiguredProvider,
|
|
3750
|
-
api,
|
|
3751
|
-
apiKey,
|
|
3752
|
-
baseUrl,
|
|
3753
|
-
modelId,
|
|
3754
|
-
models,
|
|
3755
|
-
displayName,
|
|
3756
|
-
showPassword,
|
|
3757
|
-
attemptedSave,
|
|
3758
|
-
isPending,
|
|
3759
|
-
canSave,
|
|
3760
|
-
onApiKeyChange: setApiKey,
|
|
3761
|
-
onApiChange: setApi,
|
|
3762
|
-
onBaseUrlChange: setBaseUrl,
|
|
3763
|
-
onModelIdChange: setModelId,
|
|
3764
|
-
onModelsChange: setModels,
|
|
3765
|
-
onDisplayNameChange: setDisplayName,
|
|
3766
|
-
onTogglePassword: () => setShowPassword((current) => !current),
|
|
3767
|
-
onBack: openAddPicker,
|
|
3768
|
-
onCancel: closeEditor,
|
|
3769
|
-
onConfigured: closeEditor,
|
|
3770
|
-
onOAuthLogin,
|
|
3771
|
-
onSave: () => {
|
|
3772
|
-
if (editingProvider) handleSave(editingProvider);
|
|
3773
|
-
}
|
|
3774
|
-
}) : /* @__PURE__ */ jsxs("div", {
|
|
3775
|
-
className: "flex flex-col gap-3",
|
|
3776
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
3777
|
-
className: "flex items-center gap-2",
|
|
3778
|
-
children: [/* @__PURE__ */ jsxs(InputGroup, {
|
|
3779
|
-
className: "flex-1",
|
|
3780
|
-
children: [/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
3781
|
-
align: "inline-start",
|
|
3782
|
-
children: /* @__PURE__ */ jsx(Search, {})
|
|
3783
|
-
}), /* @__PURE__ */ jsx(InputGroupInput, {
|
|
3784
|
-
type: "text",
|
|
3785
|
-
placeholder: "Search credentials\u2026",
|
|
3786
|
-
value: searchQuery,
|
|
3787
|
-
onChange: (event) => setSearchQuery(event.target.value),
|
|
3788
|
-
"aria-label": "Search credentials",
|
|
3789
|
-
disabled: isLoading || activeProviders.length === 0
|
|
3790
|
-
})]
|
|
3791
|
-
}), /* @__PURE__ */ jsxs(Button, {
|
|
3792
|
-
type: "button",
|
|
3793
|
-
variant: "outline",
|
|
3794
|
-
size: "sm",
|
|
3795
|
-
disabled: isLoading || credentialProviders.length === 0,
|
|
3796
|
-
onClick: openAddPicker,
|
|
3797
|
-
children: [/* @__PURE__ */ jsx(Plus, { "data-icon": "inline-start" }), "Add provider"]
|
|
3798
|
-
})]
|
|
3799
|
-
}), isLoading ? /* @__PURE__ */ jsxs("div", {
|
|
3800
|
-
className: "flex items-center justify-center gap-2 py-6 text-xs text-muted-foreground",
|
|
3801
|
-
children: [/* @__PURE__ */ jsx(Spinner, { className: "size-3" }), /* @__PURE__ */ jsx("span", { children: "Loading\u2026" })]
|
|
3802
|
-
}) : activeProviders.length === 0 ? /* @__PURE__ */ jsxs("div", {
|
|
3803
|
-
className: "flex flex-col items-center gap-3 py-8",
|
|
3804
|
-
children: [/* @__PURE__ */ jsx("p", {
|
|
3805
|
-
className: "text-center text-xs text-pretty text-muted-foreground",
|
|
3806
|
-
children: "No providers configured"
|
|
3807
|
-
}), /* @__PURE__ */ jsxs(Button, {
|
|
3808
|
-
type: "button",
|
|
3809
|
-
variant: "outline",
|
|
3810
|
-
size: "sm",
|
|
3811
|
-
disabled: credentialProviders.length === 0,
|
|
3812
|
-
onClick: openAddPicker,
|
|
3813
|
-
children: [/* @__PURE__ */ jsx(Plus, { "data-icon": "inline-start" }), "Add provider"]
|
|
3814
|
-
})]
|
|
3815
|
-
}) : filteredActiveProviders.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
3816
|
-
className: "py-6 text-center text-xs text-pretty text-muted-foreground",
|
|
3817
|
-
children: "No matching providers found."
|
|
3818
|
-
}) : /* @__PURE__ */ jsx(ActiveProviderList, {
|
|
3819
|
-
providers: filteredActiveProviders,
|
|
3820
|
-
editingProvider,
|
|
3821
|
-
form,
|
|
3822
|
-
operation,
|
|
3823
|
-
actions,
|
|
3824
|
-
onEdit: openEditor,
|
|
3825
|
-
onCancelEdit: closeEditor,
|
|
3826
|
-
onSave: (providerId) => void handleSave(providerId),
|
|
3827
|
-
onRemove: setConfirmRemoveProvider,
|
|
3828
|
-
onOAuthLogin,
|
|
3829
|
-
onConfigured: closeEditor
|
|
3830
|
-
})]
|
|
3831
|
-
}), /* @__PURE__ */ jsx(RemoveProviderConfirmDialog, {
|
|
3832
|
-
confirmRemoveProvider,
|
|
3833
|
-
isPending,
|
|
3834
|
-
onClose: () => setConfirmRemoveProvider(null),
|
|
3835
|
-
onConfirm: (provider) => {
|
|
3836
|
-
handleRemove(provider);
|
|
3837
|
-
}
|
|
3838
|
-
})]
|
|
3416
|
+
function TextCredentialField({ attemptedSave, icon: Icon, inputType = "text", label, onChange, placeholder, required = true, value }) {
|
|
3417
|
+
const controlId = useId();
|
|
3418
|
+
const invalid = isFieldInvalid(value, attemptedSave, required);
|
|
3419
|
+
return /* @__PURE__ */ jsxs(Field, {
|
|
3420
|
+
"data-invalid": invalid || void 0,
|
|
3421
|
+
children: [/* @__PURE__ */ jsx(FieldLabel, {
|
|
3422
|
+
htmlFor: controlId,
|
|
3423
|
+
children: label
|
|
3424
|
+
}), /* @__PURE__ */ jsxs(InputGroup, { children: [/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
3425
|
+
align: "inline-start",
|
|
3426
|
+
children: /* @__PURE__ */ jsx(Icon, {})
|
|
3427
|
+
}), /* @__PURE__ */ jsx(InputGroupInput, {
|
|
3428
|
+
id: controlId,
|
|
3429
|
+
type: inputType,
|
|
3430
|
+
placeholder,
|
|
3431
|
+
value,
|
|
3432
|
+
onChange: (event) => onChange(event.target.value),
|
|
3433
|
+
"aria-label": label,
|
|
3434
|
+
"aria-invalid": invalid || void 0
|
|
3435
|
+
})] })]
|
|
3839
3436
|
});
|
|
3840
3437
|
}
|
|
3841
|
-
|
|
3842
|
-
|
|
3438
|
+
var OPENAI_CHAT_BASE_URL_PLACEHOLDER = "https://opencode.ai/zen/v1";
|
|
3439
|
+
var OPENAI_CHAT_MODEL_PLACEHOLDER = "qwen35-122b-a10b";
|
|
3440
|
+
var OPENAI_CHAT_NAME_PLACEHOLDER = "e.g. OpenCode Zen, Nebius, Groq\u2026";
|
|
3441
|
+
var CUSTOM_MODELS_PLACEHOLDER = "model-a, model-b (comma-separated)";
|
|
3442
|
+
var CUSTOM_PROVIDER_API_OPTIONS = [
|
|
3443
|
+
{
|
|
3444
|
+
value: "openai-completions",
|
|
3445
|
+
label: "OpenAI Chat Completions"
|
|
3446
|
+
},
|
|
3447
|
+
{
|
|
3448
|
+
value: "openai-responses",
|
|
3449
|
+
label: "OpenAI Responses"
|
|
3450
|
+
},
|
|
3451
|
+
{
|
|
3452
|
+
value: "anthropic-messages",
|
|
3453
|
+
label: "Anthropic Messages"
|
|
3454
|
+
},
|
|
3455
|
+
{
|
|
3456
|
+
value: "google-genai",
|
|
3457
|
+
label: "Google Generative AI"
|
|
3458
|
+
}
|
|
3459
|
+
];
|
|
3460
|
+
function ProviderCredentialFields({ attemptedSave, apiKey, api, baseUrl, modelId, models, displayName, isCustom, onApiKeyChange, onApiChange, onBaseUrlChange, onModelIdChange, onModelsChange, onDisplayNameChange, onTogglePassword, openAiChat, placeholder, showPassword }) {
|
|
3461
|
+
const showApiSelector = isCustom && onApiChange;
|
|
3462
|
+
const showMultiModels = isCustom && onModelsChange;
|
|
3463
|
+
return /* @__PURE__ */ jsxs(FieldGroup, {
|
|
3464
|
+
className: "gap-2",
|
|
3465
|
+
children: [
|
|
3466
|
+
(openAiChat || isCustom) && onDisplayNameChange ? /* @__PURE__ */ jsx(TextCredentialField, {
|
|
3467
|
+
attemptedSave,
|
|
3468
|
+
icon: Tag,
|
|
3469
|
+
label: "Provider name",
|
|
3470
|
+
placeholder: OPENAI_CHAT_NAME_PLACEHOLDER,
|
|
3471
|
+
value: displayName ?? "",
|
|
3472
|
+
onChange: onDisplayNameChange
|
|
3473
|
+
}) : null,
|
|
3474
|
+
showApiSelector ? /* @__PURE__ */ jsx(ApiSelector, {
|
|
3475
|
+
value: api ?? "openai-completions",
|
|
3476
|
+
onChange: onApiChange
|
|
3477
|
+
}) : null,
|
|
3478
|
+
/* @__PURE__ */ jsx(SecretCredentialField, {
|
|
3479
|
+
attemptedSave,
|
|
3480
|
+
label: "API key",
|
|
3481
|
+
placeholder,
|
|
3482
|
+
value: apiKey,
|
|
3483
|
+
showPassword,
|
|
3484
|
+
onChange: onApiKeyChange,
|
|
3485
|
+
onToggleVisibility: onTogglePassword
|
|
3486
|
+
}),
|
|
3487
|
+
openAiChat || isCustom ? /* @__PURE__ */ jsx(TextCredentialField, {
|
|
3488
|
+
attemptedSave,
|
|
3489
|
+
icon: Globe,
|
|
3490
|
+
inputType: "url",
|
|
3491
|
+
label: "Base URL",
|
|
3492
|
+
placeholder: OPENAI_CHAT_BASE_URL_PLACEHOLDER,
|
|
3493
|
+
value: baseUrl,
|
|
3494
|
+
onChange: onBaseUrlChange
|
|
3495
|
+
}) : null,
|
|
3496
|
+
showMultiModels ? /* @__PURE__ */ jsx(TextCredentialField, {
|
|
3497
|
+
attemptedSave,
|
|
3498
|
+
icon: Layers,
|
|
3499
|
+
label: "Model ids",
|
|
3500
|
+
placeholder: CUSTOM_MODELS_PLACEHOLDER,
|
|
3501
|
+
value: models ?? "",
|
|
3502
|
+
onChange: onModelsChange
|
|
3503
|
+
}) : null,
|
|
3504
|
+
openAiChat && !showMultiModels ? /* @__PURE__ */ jsx(TextCredentialField, {
|
|
3505
|
+
attemptedSave,
|
|
3506
|
+
icon: Box,
|
|
3507
|
+
label: "Model name",
|
|
3508
|
+
placeholder: OPENAI_CHAT_MODEL_PLACEHOLDER,
|
|
3509
|
+
value: modelId,
|
|
3510
|
+
onChange: onModelIdChange
|
|
3511
|
+
}) : null
|
|
3512
|
+
]
|
|
3513
|
+
});
|
|
3843
3514
|
}
|
|
3844
|
-
function
|
|
3845
|
-
return
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3515
|
+
function ApiSelector({ value, onChange }) {
|
|
3516
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3517
|
+
className: "flex flex-col gap-1",
|
|
3518
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
3519
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
3520
|
+
children: "API family"
|
|
3521
|
+
}), /* @__PURE__ */ jsx(Select, {
|
|
3522
|
+
"aria-label": "API family",
|
|
3523
|
+
value,
|
|
3524
|
+
options: CUSTOM_PROVIDER_API_OPTIONS,
|
|
3525
|
+
placeholder: "Select API family",
|
|
3526
|
+
onValueChange: (next) => onChange(next)
|
|
3527
|
+
})]
|
|
3528
|
+
});
|
|
3851
3529
|
}
|
|
3852
|
-
function
|
|
3853
|
-
|
|
3854
|
-
const current = currentPatterns ?? [];
|
|
3855
|
-
const knownModelPatterns = new Set(models.map((item) => modelPatternFor(item)));
|
|
3856
|
-
const activeKnown = /* @__PURE__ */ new Set();
|
|
3857
|
-
for (const item of models) if (isModelEnabled(item, currentPatterns)) activeKnown.add(modelPatternFor(item));
|
|
3858
|
-
if (enabled) activeKnown.add(modelPatternFor(model));
|
|
3859
|
-
else activeKnown.delete(modelPatternFor(model));
|
|
3860
|
-
return [...current.filter((pattern) => {
|
|
3861
|
-
if (knownModelPatterns.has(pattern)) return false;
|
|
3862
|
-
return enabled || !modelMatchesPattern(model, pattern);
|
|
3863
|
-
}), ...activeKnown];
|
|
3530
|
+
function isOAuthProvider(provider) {
|
|
3531
|
+
return provider.authType === "oauth";
|
|
3864
3532
|
}
|
|
3865
|
-
function
|
|
3866
|
-
return
|
|
3533
|
+
function supportsOAuth(provider) {
|
|
3534
|
+
return provider.supportsOAuth === true;
|
|
3867
3535
|
}
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3536
|
+
var CUSTOM_PROVIDER_PICKER_ROW = {
|
|
3537
|
+
id: "custom",
|
|
3538
|
+
name: "Custom provider",
|
|
3539
|
+
isConfigured: false,
|
|
3540
|
+
envVarName: "CUSTOM_PROVIDER_API_KEY",
|
|
3541
|
+
displayName: "Custom provider"
|
|
3542
|
+
};
|
|
3543
|
+
function parseCustomProviderModels(raw) {
|
|
3544
|
+
return raw.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
3875
3545
|
}
|
|
3876
|
-
function
|
|
3877
|
-
const [
|
|
3878
|
-
const [
|
|
3879
|
-
const
|
|
3880
|
-
const
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
return
|
|
3900
|
-
}, [
|
|
3901
|
-
const
|
|
3902
|
-
const
|
|
3903
|
-
return
|
|
3904
|
-
}, [
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
]);
|
|
3909
|
-
const
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
});
|
|
3546
|
+
function useProviderCredentialsController({ onRemoveProvider, onUpdateProvider, providers }) {
|
|
3547
|
+
const [editingProvider, setEditingProvider] = useState2(null);
|
|
3548
|
+
const [editingIsNewOccInstance, setEditingIsNewOccInstance] = useState2(false);
|
|
3549
|
+
const [apiKey, setApiKey] = useState2("");
|
|
3550
|
+
const [baseUrl, setBaseUrl] = useState2("");
|
|
3551
|
+
const [modelId, setModelId] = useState2("");
|
|
3552
|
+
const [models, setModels] = useState2("");
|
|
3553
|
+
const [api, setApi] = useState2("openai-completions");
|
|
3554
|
+
const [displayName, setDisplayName] = useState2("");
|
|
3555
|
+
const [showPassword, setShowPassword] = useState2(false);
|
|
3556
|
+
const [attemptedSave, setAttemptedSave] = useState2(false);
|
|
3557
|
+
const [searchQuery, setSearchQuery] = useState2("");
|
|
3558
|
+
const [addPickerOpen, setAddPickerOpen] = useState2(false);
|
|
3559
|
+
const [addPickerQuery, setAddPickerQuery] = useState2("");
|
|
3560
|
+
const [confirmRemoveProvider, setConfirmRemoveProvider] = useState2(null);
|
|
3561
|
+
const credentialProviders = useMemo2(() => {
|
|
3562
|
+
return [...providers.filter((provider) => provider.id !== CUSTOM_PROVIDER_PICKER_ROW.id), CUSTOM_PROVIDER_PICKER_ROW];
|
|
3563
|
+
}, [providers]);
|
|
3564
|
+
const activeProviders = useMemo2(() => credentialProviders.filter((provider) => provider.isConfigured), [credentialProviders]);
|
|
3565
|
+
const unconfiguredProviders = useMemo2(() => credentialProviders.filter((provider) => !provider.isConfigured || provider.id === "openai-chat-completions" && provider.providerFamily === void 0), [credentialProviders]);
|
|
3566
|
+
const filteredActiveProviders = useMemo2(() => {
|
|
3567
|
+
const query = searchQuery.trim().toLowerCase();
|
|
3568
|
+
if (!query) return activeProviders;
|
|
3569
|
+
return activeProviders.filter((provider) => providerMatchesQuery(provider, query));
|
|
3570
|
+
}, [activeProviders, searchQuery]);
|
|
3571
|
+
const filteredPickerAvailable = useMemo2(() => {
|
|
3572
|
+
const query = addPickerQuery.trim().toLowerCase();
|
|
3573
|
+
return unconfiguredProviders.filter((provider) => providerMatchesQuery(provider, query));
|
|
3574
|
+
}, [addPickerQuery, unconfiguredProviders]);
|
|
3575
|
+
const filteredPickerConfigured = useMemo2(() => {
|
|
3576
|
+
const query = addPickerQuery.trim().toLowerCase();
|
|
3577
|
+
return activeProviders.filter((provider) => providerMatchesQuery(provider, query));
|
|
3578
|
+
}, [activeProviders, addPickerQuery]);
|
|
3579
|
+
const pickerHasResults = filteredPickerAvailable.length > 0 || filteredPickerConfigured.length > 0;
|
|
3580
|
+
const editingUnconfiguredProvider = editingProvider && !activeProviders.some((provider) => provider.id === editingProvider) ? credentialProviders.find((entry) => entry.id === editingProvider) ?? null : null;
|
|
3581
|
+
const resetEditor = () => {
|
|
3582
|
+
setApiKey("");
|
|
3583
|
+
setBaseUrl("");
|
|
3584
|
+
setModelId("");
|
|
3585
|
+
setModels("");
|
|
3586
|
+
setApi("openai-completions");
|
|
3587
|
+
setDisplayName("");
|
|
3588
|
+
setShowPassword(false);
|
|
3589
|
+
setAttemptedSave(false);
|
|
3921
3590
|
};
|
|
3922
|
-
const
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3591
|
+
const closeEditor = () => {
|
|
3592
|
+
setEditingProvider(null);
|
|
3593
|
+
setEditingIsNewOccInstance(false);
|
|
3594
|
+
resetEditor();
|
|
3926
3595
|
};
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
return /* @__PURE__ */ jsxs("button", {
|
|
4001
|
-
type: "button",
|
|
4002
|
-
className: cn("flex w-full items-center gap-3 rounded-lg px-2 py-2 text-left transition-[background-color,transform] duration-150", "hover:bg-muted/60 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none active:scale-[0.96]", checked && "bg-muted/70"),
|
|
4003
|
-
"aria-pressed": checked,
|
|
4004
|
-
onClick: () => toggleSelected(model),
|
|
4005
|
-
children: [
|
|
4006
|
-
/* @__PURE__ */ jsx("div", {
|
|
4007
|
-
className: "flex size-8 shrink-0 items-center justify-center rounded-[4px] border border-border/40 bg-background/60",
|
|
4008
|
-
children: /* @__PURE__ */ jsx(ProviderBrandIcon, {
|
|
4009
|
-
provider: model.provider,
|
|
4010
|
-
className: "text-foreground/70"
|
|
4011
|
-
})
|
|
4012
|
-
}),
|
|
4013
|
-
/* @__PURE__ */ jsxs("div", {
|
|
4014
|
-
className: "min-w-0 flex-1",
|
|
4015
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
4016
|
-
className: "truncate text-sm font-medium",
|
|
4017
|
-
children: model.name
|
|
4018
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
4019
|
-
className: "truncate text-xs text-muted-foreground",
|
|
4020
|
-
children: model.modelId
|
|
4021
|
-
})]
|
|
4022
|
-
}),
|
|
4023
|
-
/* @__PURE__ */ jsx("span", {
|
|
4024
|
-
className: cn("size-4 rounded border border-border/60", checked && "border-foreground bg-foreground"),
|
|
4025
|
-
"aria-hidden": true
|
|
4026
|
-
})
|
|
4027
|
-
]
|
|
4028
|
-
}, model.id);
|
|
4029
|
-
})]
|
|
4030
|
-
}, provider))
|
|
4031
|
-
})
|
|
4032
|
-
}),
|
|
4033
|
-
/* @__PURE__ */ jsxs("div", {
|
|
4034
|
-
className: "flex items-center justify-end gap-1.5",
|
|
4035
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
4036
|
-
type: "button",
|
|
4037
|
-
variant: "ghost",
|
|
4038
|
-
size: "sm",
|
|
4039
|
-
onClick: () => onOpenChange(false),
|
|
4040
|
-
children: "Cancel"
|
|
4041
|
-
}), /* @__PURE__ */ jsxs(Button, {
|
|
4042
|
-
type: "button",
|
|
4043
|
-
size: "sm",
|
|
4044
|
-
disabled: selectedKeys.size === 0,
|
|
4045
|
-
onClick: confirmAdd,
|
|
4046
|
-
children: [
|
|
4047
|
-
"Add",
|
|
4048
|
-
" ",
|
|
4049
|
-
selectedKeys.size > 0 ? /* @__PURE__ */ jsxs("span", {
|
|
4050
|
-
className: "tabular-nums",
|
|
4051
|
-
children: [
|
|
4052
|
-
"(",
|
|
4053
|
-
selectedKeys.size,
|
|
4054
|
-
")"
|
|
4055
|
-
]
|
|
4056
|
-
}) : null
|
|
4057
|
-
]
|
|
4058
|
-
})]
|
|
4059
|
-
})
|
|
4060
|
-
]
|
|
4061
|
-
})
|
|
4062
|
-
});
|
|
4063
|
-
}
|
|
4064
|
-
function ModelDefaultsSection({ draft, discoveringProviderId, modelDirty, modelFilter, modelOptions, onAddModels, onDiscoverProvider, onModelFilterChange, onRemoveModel, onSetDefaultModel, onRevert, onSave, providers, saving, settingsLoading }) {
|
|
4065
|
-
const [addOpen, setAddOpen] = useState2(false);
|
|
4066
|
-
const disabled2 = !draft || settingsLoading;
|
|
4067
|
-
const normalizedFilter = modelFilter.trim().toLowerCase();
|
|
4068
|
-
const configuredProviderIds = useMemo2(() => {
|
|
4069
|
-
const ids = /* @__PURE__ */ new Set();
|
|
4070
|
-
for (const provider of providers) if (provider.isConfigured) ids.add(provider.id);
|
|
4071
|
-
for (const model of modelOptions) if (isModelEnabled(model, draft?.enabledModels)) ids.add(model.provider);
|
|
4072
|
-
return ids;
|
|
4073
|
-
}, [
|
|
4074
|
-
draft?.enabledModels,
|
|
4075
|
-
modelOptions,
|
|
4076
|
-
providers
|
|
4077
|
-
]);
|
|
4078
|
-
const discoverableProviderIds = useMemo2(() => {
|
|
4079
|
-
const ids = /* @__PURE__ */ new Set();
|
|
4080
|
-
for (const provider of providers) if (provider.discoverable === true && configuredProviderIds.has(provider.id)) ids.add(provider.id);
|
|
4081
|
-
return ids;
|
|
4082
|
-
}, [configuredProviderIds, providers]);
|
|
4083
|
-
const isDefaultModel = useMemo2(() => {
|
|
4084
|
-
return (model) => !!draft?.defaultProvider && !!draft?.defaultModel && model.provider === draft.defaultProvider && model.modelId === draft.defaultModel;
|
|
4085
|
-
}, [draft?.defaultModel, draft?.defaultProvider]);
|
|
4086
|
-
const providerLabel = useMemo2(() => {
|
|
4087
|
-
const labels = /* @__PURE__ */ new Map();
|
|
4088
|
-
for (const provider of providers) if (provider.displayName || provider.name) labels.set(provider.id, provider.displayName ?? provider.name ?? provider.id);
|
|
4089
|
-
return (providerId) => labels.get(providerId) ?? formatProviderLabel(providerId);
|
|
4090
|
-
}, [providers]);
|
|
4091
|
-
const listedModels = useMemo2(() => {
|
|
4092
|
-
return modelOptions.filter((model) => {
|
|
4093
|
-
if (!isModelEnabled(model, draft?.enabledModels)) return false;
|
|
4094
|
-
if (!normalizedFilter) return true;
|
|
4095
|
-
return [
|
|
4096
|
-
model.name,
|
|
4097
|
-
model.modelId,
|
|
4098
|
-
model.provider,
|
|
4099
|
-
model.id
|
|
4100
|
-
].join(" ").toLowerCase().includes(normalizedFilter);
|
|
4101
|
-
});
|
|
4102
|
-
}, [
|
|
4103
|
-
draft?.enabledModels,
|
|
4104
|
-
modelOptions,
|
|
4105
|
-
normalizedFilter
|
|
4106
|
-
]);
|
|
4107
|
-
const groupedListed = useMemo2(() => {
|
|
4108
|
-
const groups = /* @__PURE__ */ new Map();
|
|
4109
|
-
for (const model of listedModels) {
|
|
4110
|
-
const existing = groups.get(model.provider);
|
|
4111
|
-
if (existing) existing.push(model);
|
|
4112
|
-
else groups.set(model.provider, [model]);
|
|
3596
|
+
const openEditor = (providerId, opts) => {
|
|
3597
|
+
setAddPickerOpen(false);
|
|
3598
|
+
setAddPickerQuery("");
|
|
3599
|
+
setEditingProvider(providerId);
|
|
3600
|
+
setEditingIsNewOccInstance(opts?.newOccInstance === true);
|
|
3601
|
+
resetEditor();
|
|
3602
|
+
const existing = providers.find((provider) => provider.id === providerId);
|
|
3603
|
+
setBaseUrl(existing?.baseUrl ?? "");
|
|
3604
|
+
setDisplayName(existing?.displayName ?? (isCustomProviderId(providerId) ? existing?.name ?? "" : ""));
|
|
3605
|
+
setApi(existing?.api ?? "openai-completions");
|
|
3606
|
+
setModels((existing?.modelIds ?? []).join(", "));
|
|
3607
|
+
setModelId(existing?.modelIds?.[0] ?? "");
|
|
3608
|
+
};
|
|
3609
|
+
const openAddPicker = () => {
|
|
3610
|
+
closeEditor();
|
|
3611
|
+
setAddPickerQuery("");
|
|
3612
|
+
setAddPickerOpen(true);
|
|
3613
|
+
};
|
|
3614
|
+
const closeAddPicker = () => {
|
|
3615
|
+
setAddPickerOpen(false);
|
|
3616
|
+
setAddPickerQuery("");
|
|
3617
|
+
};
|
|
3618
|
+
const selectProviderFromPicker = (providerId) => {
|
|
3619
|
+
openEditor(providerId, { newOccInstance: isOccProviderId(providerId) });
|
|
3620
|
+
};
|
|
3621
|
+
const handleSave = async (providerId) => {
|
|
3622
|
+
if (!onUpdateProvider) return;
|
|
3623
|
+
setAttemptedSave(true);
|
|
3624
|
+
const isCustomEditor = providerId === "custom" || isCustomProviderId(providerId);
|
|
3625
|
+
const openAiChat = isOccProviderId(providerId);
|
|
3626
|
+
if (isCustomEditor) {
|
|
3627
|
+
const modelList = parseCustomProviderModels(models);
|
|
3628
|
+
if (!apiKey.trim() || !baseUrl.trim() || !displayName.trim()) return;
|
|
3629
|
+
if (modelList.length === 0) return;
|
|
3630
|
+
try {
|
|
3631
|
+
await onUpdateProvider({
|
|
3632
|
+
providerId,
|
|
3633
|
+
apiKey: apiKey.trim(),
|
|
3634
|
+
baseUrl: baseUrl.trim(),
|
|
3635
|
+
displayName: displayName.trim(),
|
|
3636
|
+
api,
|
|
3637
|
+
models: modelList,
|
|
3638
|
+
...providerId === "custom" ? { createOccInstance: true } : {}
|
|
3639
|
+
});
|
|
3640
|
+
notify.success("Provider credentials applied to your active sessions.");
|
|
3641
|
+
closeEditor();
|
|
3642
|
+
closeAddPicker();
|
|
3643
|
+
} catch (error) {
|
|
3644
|
+
notify.error(error instanceof Error ? error.message : "Failed to update provider");
|
|
3645
|
+
}
|
|
3646
|
+
return;
|
|
3647
|
+
}
|
|
3648
|
+
const isNamedOcc = openAiChat && isNamedOccInstanceId(providerId);
|
|
3649
|
+
const isOccLike = openAiChat && (isNamedOcc || editingIsNewOccInstance);
|
|
3650
|
+
if (!apiKey.trim()) return;
|
|
3651
|
+
if (openAiChat && (!baseUrl.trim() || !modelId.trim())) return;
|
|
3652
|
+
if (isOccLike && !displayName.trim()) return;
|
|
3653
|
+
try {
|
|
3654
|
+
await onUpdateProvider({
|
|
3655
|
+
providerId,
|
|
3656
|
+
apiKey: apiKey.trim(),
|
|
3657
|
+
...openAiChat ? {
|
|
3658
|
+
baseUrl: baseUrl.trim(),
|
|
3659
|
+
modelId: modelId.trim(),
|
|
3660
|
+
...isOccLike ? { displayName: displayName.trim() } : {},
|
|
3661
|
+
...editingIsNewOccInstance ? { createOccInstance: true } : {}
|
|
3662
|
+
} : {}
|
|
3663
|
+
});
|
|
3664
|
+
notify.success("Provider credentials applied to your active sessions.");
|
|
3665
|
+
closeEditor();
|
|
3666
|
+
closeAddPicker();
|
|
3667
|
+
} catch (error) {
|
|
3668
|
+
notify.error(error instanceof Error ? error.message : "Failed to update provider");
|
|
4113
3669
|
}
|
|
4114
|
-
return [...groups.entries()];
|
|
4115
|
-
}, [listedModels]);
|
|
4116
|
-
const emptyMessage = (() => {
|
|
4117
|
-
if (modelOptions.length === 0) return "No models discovered yet. Configure a provider, then add models.";
|
|
4118
|
-
if (listedModels.length === 0 && !normalizedFilter) return "Add models from your configured providers to make them available in chat.";
|
|
4119
|
-
if (listedModels.length === 0) return "No models match your search.";
|
|
4120
|
-
return null;
|
|
4121
|
-
})();
|
|
4122
|
-
const openAddDialog = () => {
|
|
4123
|
-
setAddOpen(true);
|
|
4124
3670
|
};
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
3671
|
+
const handleRemove = async (provider) => {
|
|
3672
|
+
if (!onRemoveProvider) return;
|
|
3673
|
+
try {
|
|
3674
|
+
await onRemoveProvider({ providerId: provider.id });
|
|
3675
|
+
if (editingProvider === provider.id) closeEditor();
|
|
3676
|
+
notify.success(`${provider.name} removed from your configured providers.`);
|
|
3677
|
+
setConfirmRemoveProvider(null);
|
|
3678
|
+
} catch (error) {
|
|
3679
|
+
notify.error(error instanceof Error ? error.message : "Failed to remove provider");
|
|
3680
|
+
}
|
|
3681
|
+
};
|
|
3682
|
+
return {
|
|
3683
|
+
activeProviders,
|
|
3684
|
+
addPickerOpen,
|
|
3685
|
+
addPickerQuery,
|
|
3686
|
+
api,
|
|
3687
|
+
apiKey,
|
|
3688
|
+
attemptedSave,
|
|
3689
|
+
baseUrl,
|
|
3690
|
+
canSave: useMemo2(() => {
|
|
3691
|
+
if (apiKey.trim().length === 0) return false;
|
|
3692
|
+
if (!editingProvider) return true;
|
|
3693
|
+
if (editingProvider === "custom" || isCustomProviderId(editingProvider)) {
|
|
3694
|
+
if (baseUrl.trim().length === 0) return false;
|
|
3695
|
+
if (parseCustomProviderModels(models).length === 0) return false;
|
|
3696
|
+
return displayName.trim().length > 0;
|
|
3697
|
+
}
|
|
3698
|
+
if (!isOccProviderId(editingProvider)) return true;
|
|
3699
|
+
if (baseUrl.trim().length === 0 || modelId.trim().length === 0) return false;
|
|
3700
|
+
if (isNamedOccInstanceId(editingProvider) || editingIsNewOccInstance) return displayName.trim().length > 0;
|
|
3701
|
+
return true;
|
|
3702
|
+
}, [
|
|
3703
|
+
apiKey,
|
|
3704
|
+
baseUrl,
|
|
3705
|
+
modelId,
|
|
3706
|
+
models,
|
|
3707
|
+
displayName,
|
|
3708
|
+
editingProvider,
|
|
3709
|
+
editingIsNewOccInstance
|
|
3710
|
+
]),
|
|
3711
|
+
closeAddPicker,
|
|
3712
|
+
closeEditor,
|
|
3713
|
+
confirmRemoveProvider,
|
|
3714
|
+
credentialProviders,
|
|
3715
|
+
displayName,
|
|
3716
|
+
editingIsNewOccInstance,
|
|
3717
|
+
editingProvider,
|
|
3718
|
+
editingUnconfiguredProvider,
|
|
3719
|
+
filteredActiveProviders,
|
|
3720
|
+
filteredPickerAvailable,
|
|
3721
|
+
filteredPickerConfigured,
|
|
3722
|
+
handleRemove,
|
|
3723
|
+
handleSave,
|
|
3724
|
+
modelId,
|
|
3725
|
+
models,
|
|
3726
|
+
openAddPicker,
|
|
3727
|
+
openEditor,
|
|
3728
|
+
pickerHasResults,
|
|
3729
|
+
resetEditor,
|
|
3730
|
+
searchQuery,
|
|
3731
|
+
selectProviderFromPicker,
|
|
3732
|
+
setAddPickerOpen,
|
|
3733
|
+
setAddPickerQuery,
|
|
3734
|
+
setApi,
|
|
3735
|
+
setApiKey,
|
|
3736
|
+
setAttemptedSave,
|
|
3737
|
+
setBaseUrl,
|
|
3738
|
+
setConfirmRemoveProvider,
|
|
3739
|
+
setDisplayName,
|
|
3740
|
+
setEditingIsNewOccInstance,
|
|
3741
|
+
setEditingProvider,
|
|
3742
|
+
setModelId,
|
|
3743
|
+
setModels,
|
|
3744
|
+
setSearchQuery,
|
|
3745
|
+
setShowPassword,
|
|
3746
|
+
showPassword,
|
|
3747
|
+
unconfiguredProviders
|
|
3748
|
+
};
|
|
3749
|
+
}
|
|
3750
|
+
function providerMatchesQuery(provider, query) {
|
|
3751
|
+
if (!query) return true;
|
|
3752
|
+
const keywords = supportsOAuth(provider) ? isOAuthProvider(provider) ? "oauth sign-in login" : "api key oauth sign-in login" : provider.id === "custom" || isCustomProviderId(provider.id) ? "custom provider endpoint openai anthropic google compatible" : isOccProviderId(provider.id) ? "api key base url model name chat completions" : "";
|
|
3753
|
+
return [
|
|
3754
|
+
provider.name,
|
|
3755
|
+
provider.envVarName,
|
|
3756
|
+
provider.id,
|
|
3757
|
+
keywords
|
|
3758
|
+
].join(" ").toLowerCase().includes(query);
|
|
3759
|
+
}
|
|
3760
|
+
function AddProviderPickerPanel({ addPickerQuery, credentialProvidersLength, filteredPickerAvailable, filteredPickerConfigured, pickerHasResults, onClose, onQueryChange, onSelect }) {
|
|
3761
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3762
|
+
className: "flex flex-col gap-3",
|
|
4154
3763
|
children: [
|
|
4155
3764
|
/* @__PURE__ */ jsxs("div", {
|
|
4156
3765
|
className: "flex items-center gap-2",
|
|
4157
|
-
children: [/* @__PURE__ */
|
|
4158
|
-
className: "flex-1",
|
|
4159
|
-
children: [/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
4160
|
-
align: "inline-start",
|
|
4161
|
-
children: /* @__PURE__ */ jsx(Search, {})
|
|
4162
|
-
}), /* @__PURE__ */ jsx(InputGroupInput, {
|
|
4163
|
-
"aria-label": "Search listed models",
|
|
4164
|
-
value: modelFilter,
|
|
4165
|
-
onChange: (event) => onModelFilterChange(event.target.value),
|
|
4166
|
-
placeholder: "Search listed models\u2026",
|
|
4167
|
-
disabled: disabled2 || listedModels.length === 0
|
|
4168
|
-
})]
|
|
4169
|
-
}), /* @__PURE__ */ jsxs(Button, {
|
|
3766
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
4170
3767
|
type: "button",
|
|
4171
|
-
variant: "
|
|
4172
|
-
size: "sm",
|
|
4173
|
-
|
|
4174
|
-
onClick:
|
|
4175
|
-
children:
|
|
3768
|
+
variant: "ghost",
|
|
3769
|
+
size: "icon-sm",
|
|
3770
|
+
"aria-label": "Back to providers",
|
|
3771
|
+
onClick: onClose,
|
|
3772
|
+
children: /* @__PURE__ */ jsx(ArrowLeft, {})
|
|
3773
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3774
|
+
className: "min-w-0 flex-1",
|
|
3775
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
3776
|
+
className: "text-sm font-medium",
|
|
3777
|
+
children: "Add provider"
|
|
3778
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
3779
|
+
className: "text-xs text-pretty text-muted-foreground",
|
|
3780
|
+
children: "Choose a provider to store encrypted credentials for this account."
|
|
3781
|
+
})]
|
|
4176
3782
|
})]
|
|
4177
3783
|
}),
|
|
3784
|
+
/* @__PURE__ */ jsxs(InputGroup, { children: [/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
3785
|
+
align: "inline-start",
|
|
3786
|
+
children: /* @__PURE__ */ jsx(Search, {})
|
|
3787
|
+
}), /* @__PURE__ */ jsx(InputGroupInput, {
|
|
3788
|
+
type: "text",
|
|
3789
|
+
placeholder: "Search providers\u2026",
|
|
3790
|
+
value: addPickerQuery,
|
|
3791
|
+
onChange: (event) => onQueryChange(event.target.value),
|
|
3792
|
+
"aria-label": "Search providers to add"
|
|
3793
|
+
})] }),
|
|
4178
3794
|
/* @__PURE__ */ jsx("div", {
|
|
4179
|
-
className: "
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
3795
|
+
className: "max-h-[min(24rem,50vh)] overflow-y-auto",
|
|
3796
|
+
children: !pickerHasResults ? /* @__PURE__ */ jsx("p", {
|
|
3797
|
+
className: "py-6 text-center text-xs text-pretty text-muted-foreground",
|
|
3798
|
+
children: credentialProvidersLength === 0 ? "No providers available." : "No matching providers found."
|
|
3799
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
3800
|
+
className: "flex flex-col gap-3",
|
|
3801
|
+
children: [filteredPickerAvailable.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
3802
|
+
className: "flex flex-col gap-1",
|
|
3803
|
+
children: filteredPickerAvailable.map((provider) => /* @__PURE__ */ jsx(ProviderPickerRow, {
|
|
3804
|
+
provider,
|
|
3805
|
+
configured: false,
|
|
3806
|
+
onSelect: () => onSelect(provider.id)
|
|
3807
|
+
}, provider.id))
|
|
3808
|
+
}) : null, filteredPickerConfigured.length > 0 ? /* @__PURE__ */ jsxs("div", {
|
|
3809
|
+
className: "flex flex-col gap-1",
|
|
3810
|
+
children: [filteredPickerAvailable.length > 0 ? /* @__PURE__ */ jsx("p", {
|
|
3811
|
+
className: "px-2 pt-1 text-[0.6875rem] font-medium tracking-wide text-muted-foreground uppercase",
|
|
3812
|
+
children: "Already configured"
|
|
3813
|
+
}) : null, filteredPickerConfigured.map((provider) => /* @__PURE__ */ jsx(ProviderPickerRow, {
|
|
3814
|
+
provider,
|
|
3815
|
+
configured: true,
|
|
3816
|
+
onSelect: () => onSelect(provider.id)
|
|
3817
|
+
}, provider.id))]
|
|
4193
3818
|
}) : null]
|
|
4194
|
-
})
|
|
4195
|
-
className: "flex flex-col gap-1.5",
|
|
4196
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
4197
|
-
className: "px-1 text-xs font-medium text-muted-foreground",
|
|
4198
|
-
children: providerLabel(provider)
|
|
4199
|
-
}), models.map((model) => /* @__PURE__ */ jsx(ItemRow, {
|
|
4200
|
-
icon: /* @__PURE__ */ jsx(ProviderBrandIcon, { provider: model.provider }),
|
|
4201
|
-
title: model.name,
|
|
4202
|
-
subtitle: `${providerLabel(model.provider)} \xB7 ${model.modelId}`,
|
|
4203
|
-
trailing: /* @__PURE__ */ jsxs("div", {
|
|
4204
|
-
className: "flex items-center",
|
|
4205
|
-
children: [isDefaultModel(model) ? /* @__PURE__ */ jsx("span", {
|
|
4206
|
-
className: "px-2 text-xs font-medium text-muted-foreground",
|
|
4207
|
-
children: "Default"
|
|
4208
|
-
}) : onSetDefaultModel ? /* @__PURE__ */ jsxs(Button, {
|
|
4209
|
-
type: "button",
|
|
4210
|
-
variant: "ghost",
|
|
4211
|
-
size: "sm",
|
|
4212
|
-
className: cn(HIT_AREA_EXPAND_DENSE_CLASS, "h-7 px-2 text-xs text-muted-foreground transition-[background-color,color,transform] duration-150 active:scale-[0.96]"),
|
|
4213
|
-
disabled: disabled2,
|
|
4214
|
-
"aria-label": `Set ${model.name} as default`,
|
|
4215
|
-
onClick: () => onSetDefaultModel(model),
|
|
4216
|
-
children: [/* @__PURE__ */ jsx(Star, { "data-icon": "inline-start" }), "Set default"]
|
|
4217
|
-
}) : null, /* @__PURE__ */ jsxs(Button, {
|
|
4218
|
-
type: "button",
|
|
4219
|
-
variant: "ghost",
|
|
4220
|
-
size: "sm",
|
|
4221
|
-
className: cn(HIT_AREA_EXPAND_DENSE_CLASS, "h-7 px-2 text-xs text-muted-foreground transition-[background-color,color,transform] duration-150 hover:text-destructive active:scale-[0.96]"),
|
|
4222
|
-
disabled: disabled2,
|
|
4223
|
-
"aria-label": `Remove ${model.name}`,
|
|
4224
|
-
onClick: () => onRemoveModel(model),
|
|
4225
|
-
children: [/* @__PURE__ */ jsx(Trash2, { "data-icon": "inline-start" }), "Remove"]
|
|
4226
|
-
})]
|
|
4227
|
-
})
|
|
4228
|
-
}, model.id))]
|
|
4229
|
-
}, provider))
|
|
4230
|
-
}),
|
|
4231
|
-
/* @__PURE__ */ jsx(AddModelsDialog, {
|
|
4232
|
-
open: addOpen,
|
|
4233
|
-
configuredProviderIds,
|
|
4234
|
-
discoverableProviderIds,
|
|
4235
|
-
discoveringProviderId,
|
|
4236
|
-
enabledModels: draft?.enabledModels,
|
|
4237
|
-
modelOptions,
|
|
4238
|
-
onAddModels,
|
|
4239
|
-
onDiscoverProvider,
|
|
4240
|
-
onOpenChange: setAddOpen,
|
|
4241
|
-
providerLabel
|
|
3819
|
+
})
|
|
4242
3820
|
})
|
|
4243
3821
|
]
|
|
4244
3822
|
});
|
|
4245
3823
|
}
|
|
4246
|
-
|
|
4247
|
-
{
|
|
4248
|
-
value: "auto",
|
|
4249
|
-
label: "Auto"
|
|
4250
|
-
},
|
|
4251
|
-
{
|
|
4252
|
-
value: "sse",
|
|
4253
|
-
label: "SSE"
|
|
4254
|
-
},
|
|
4255
|
-
{
|
|
4256
|
-
value: "websocket",
|
|
4257
|
-
label: "WebSocket"
|
|
4258
|
-
}
|
|
4259
|
-
];
|
|
4260
|
-
var DELIVERY_OPTIONS = [{
|
|
4261
|
-
value: "all",
|
|
4262
|
-
label: "All"
|
|
4263
|
-
}, {
|
|
4264
|
-
value: "one-at-a-time",
|
|
4265
|
-
label: "One at a time"
|
|
4266
|
-
}];
|
|
4267
|
-
function HarnessRuntimeSection({ draft, updateDraft }) {
|
|
4268
|
-
const disabled2 = !draft;
|
|
3824
|
+
function AddProviderOAuthPanel({ onBack, onConfigured, onOAuthLogin, provider }) {
|
|
4269
3825
|
return /* @__PURE__ */ jsxs("div", {
|
|
4270
|
-
className: "flex flex-col gap-
|
|
3826
|
+
className: "flex flex-col gap-3",
|
|
3827
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
3828
|
+
className: "flex items-center gap-2",
|
|
3829
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
3830
|
+
type: "button",
|
|
3831
|
+
variant: "ghost",
|
|
3832
|
+
size: "icon-sm",
|
|
3833
|
+
"aria-label": "Back to provider list",
|
|
3834
|
+
onClick: onBack,
|
|
3835
|
+
children: /* @__PURE__ */ jsx(ArrowLeft, {})
|
|
3836
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3837
|
+
className: "min-w-0 flex-1",
|
|
3838
|
+
children: [/* @__PURE__ */ jsxs("p", {
|
|
3839
|
+
className: "text-sm font-medium",
|
|
3840
|
+
children: ["Configure ", provider.name]
|
|
3841
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
3842
|
+
className: "text-xs text-pretty text-muted-foreground",
|
|
3843
|
+
children: "OAuth sign-in. Credentials are stored in auth.json for this account."
|
|
3844
|
+
})]
|
|
3845
|
+
})]
|
|
3846
|
+
}), /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
|
|
3847
|
+
provider,
|
|
3848
|
+
onConfigured,
|
|
3849
|
+
onOAuthLogin
|
|
3850
|
+
}, provider.id)]
|
|
3851
|
+
});
|
|
3852
|
+
}
|
|
3853
|
+
function AddProviderEditorPanel({ provider, api, apiKey, baseUrl, modelId, models, displayName, showPassword, attemptedSave, isPending, canSave, onApiKeyChange, onApiChange, onBaseUrlChange, onModelIdChange, onModelsChange, onDisplayNameChange, onTogglePassword, onBack, onCancel, onConfigured, onOAuthLogin, onSave }) {
|
|
3854
|
+
const isCustomTemplate = provider.id === "custom" || isCustomProviderId(provider.id);
|
|
3855
|
+
const meta = PROVIDER_METADATA[provider.id] ?? (isCustomTemplate ? PROVIDER_METADATA["custom"] : {
|
|
3856
|
+
placeholder: "Enter credentials\u2026",
|
|
3857
|
+
help: "Stored securely in your local environment overrides."
|
|
3858
|
+
});
|
|
3859
|
+
const openAiChat = isOccProviderId(provider.id) && !isCustomTemplate;
|
|
3860
|
+
const oauthAvailable = supportsOAuth(provider);
|
|
3861
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3862
|
+
className: "flex flex-col gap-3",
|
|
4271
3863
|
children: [
|
|
4272
|
-
/* @__PURE__ */
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
3864
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3865
|
+
className: "flex items-center gap-2",
|
|
3866
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
3867
|
+
type: "button",
|
|
3868
|
+
variant: "ghost",
|
|
3869
|
+
size: "icon-sm",
|
|
3870
|
+
"aria-label": "Back to provider list",
|
|
3871
|
+
onClick: onBack,
|
|
3872
|
+
children: /* @__PURE__ */ jsx(ArrowLeft, {})
|
|
3873
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3874
|
+
className: "min-w-0 flex-1",
|
|
3875
|
+
children: [/* @__PURE__ */ jsxs("p", {
|
|
3876
|
+
className: "text-sm font-medium",
|
|
3877
|
+
children: ["Configure ", provider.name]
|
|
3878
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
3879
|
+
className: "text-xs text-pretty text-muted-foreground",
|
|
3880
|
+
children: isCustomTemplate ? "Name this custom provider, pick its API family, then enter its API key, https base URL, and model ids." : openAiChat ? "Name this OpenAI-compatible provider, then enter its API key, base URL, and model name." : `Stored as ${provider.envVarName} for this account.`
|
|
3881
|
+
})]
|
|
3882
|
+
})]
|
|
4287
3883
|
}),
|
|
4288
|
-
/* @__PURE__ */ jsx(
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
3884
|
+
/* @__PURE__ */ jsx(ProviderCredentialFields, {
|
|
3885
|
+
attemptedSave,
|
|
3886
|
+
api,
|
|
3887
|
+
apiKey,
|
|
3888
|
+
baseUrl,
|
|
3889
|
+
modelId,
|
|
3890
|
+
models,
|
|
3891
|
+
displayName,
|
|
3892
|
+
isCustom: isCustomTemplate,
|
|
3893
|
+
openAiChat,
|
|
3894
|
+
placeholder: meta.placeholder,
|
|
3895
|
+
showPassword,
|
|
3896
|
+
onApiKeyChange,
|
|
3897
|
+
onApiChange,
|
|
3898
|
+
onBaseUrlChange,
|
|
3899
|
+
onModelIdChange,
|
|
3900
|
+
onModelsChange,
|
|
3901
|
+
onDisplayNameChange,
|
|
3902
|
+
onTogglePassword
|
|
4303
3903
|
}),
|
|
4304
|
-
/* @__PURE__ */
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
"
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
onValueChange: (value) => updateDraft((current) => ({
|
|
4311
|
-
...current,
|
|
4312
|
-
transport: value
|
|
4313
|
-
})),
|
|
4314
|
-
options: [...TRANSPORT_OPTIONS],
|
|
4315
|
-
value: draft?.transport ?? "auto"
|
|
4316
|
-
})
|
|
3904
|
+
/* @__PURE__ */ jsxs(Alert, {
|
|
3905
|
+
className: "px-3 py-2",
|
|
3906
|
+
children: [/* @__PURE__ */ jsx(Info, {}), /* @__PURE__ */ jsx(AlertDescription, {
|
|
3907
|
+
className: "text-xs text-pretty",
|
|
3908
|
+
children: meta.help
|
|
3909
|
+
})]
|
|
4317
3910
|
}),
|
|
4318
|
-
/* @__PURE__ */
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
3911
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3912
|
+
className: "flex items-center justify-end gap-1.5",
|
|
3913
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
3914
|
+
type: "button",
|
|
3915
|
+
variant: "ghost",
|
|
3916
|
+
size: "sm",
|
|
3917
|
+
onClick: onCancel,
|
|
3918
|
+
children: "Cancel"
|
|
3919
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
3920
|
+
type: "button",
|
|
3921
|
+
size: "sm",
|
|
3922
|
+
disabled: isPending || !canSave,
|
|
3923
|
+
onClick: onSave,
|
|
3924
|
+
children: [isPending ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : null, "Save"]
|
|
3925
|
+
})]
|
|
4332
3926
|
}),
|
|
4333
|
-
/* @__PURE__ */ jsx(
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
className: "w-[160px]",
|
|
4339
|
-
disabled: disabled2,
|
|
4340
|
-
onValueChange: (value) => updateDraft((current) => ({
|
|
4341
|
-
...current,
|
|
4342
|
-
followUpMode: value
|
|
4343
|
-
})),
|
|
4344
|
-
options: [...DELIVERY_OPTIONS],
|
|
4345
|
-
value: draft?.followUpMode ?? "all"
|
|
4346
|
-
})
|
|
4347
|
-
})
|
|
3927
|
+
oauthAvailable ? /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
|
|
3928
|
+
provider,
|
|
3929
|
+
onConfigured: onConfigured ?? onCancel,
|
|
3930
|
+
onOAuthLogin
|
|
3931
|
+
}, `${provider.id}-oauth`) : null
|
|
4348
3932
|
]
|
|
4349
3933
|
});
|
|
4350
3934
|
}
|
|
3935
|
+
function RemoveProviderConfirmDialog({ confirmRemoveProvider, isPending, onClose, onConfirm }) {
|
|
3936
|
+
return /* @__PURE__ */ jsx(AlertDialog, {
|
|
3937
|
+
open: confirmRemoveProvider !== null,
|
|
3938
|
+
onOpenChange: (open) => {
|
|
3939
|
+
if (!open) onClose();
|
|
3940
|
+
},
|
|
3941
|
+
children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [/* @__PURE__ */ jsxs("div", {
|
|
3942
|
+
className: "flex flex-col gap-2",
|
|
3943
|
+
children: [/* @__PURE__ */ jsxs(AlertDialogTitle, { children: [
|
|
3944
|
+
"Remove ",
|
|
3945
|
+
confirmRemoveProvider?.name ?? "provider",
|
|
3946
|
+
"?"
|
|
3947
|
+
] }), /* @__PURE__ */ jsx(AlertDialogDescription, { children: "This clears stored credentials for this provider from your workspace settings. Active sessions will stop using it immediately." })]
|
|
3948
|
+
}), /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [/* @__PURE__ */ jsx(AlertDialogCancel, {
|
|
3949
|
+
disabled: isPending,
|
|
3950
|
+
children: "Cancel"
|
|
3951
|
+
}), /* @__PURE__ */ jsxs(AlertDialogAction, {
|
|
3952
|
+
disabled: isPending || !confirmRemoveProvider,
|
|
3953
|
+
onClick: () => {
|
|
3954
|
+
if (confirmRemoveProvider) onConfirm(confirmRemoveProvider);
|
|
3955
|
+
},
|
|
3956
|
+
children: [isPending ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : null, "Remove provider"]
|
|
3957
|
+
})] })] })
|
|
3958
|
+
});
|
|
3959
|
+
}
|
|
3960
|
+
function ProviderPickerRow({ configured, onSelect, provider }) {
|
|
3961
|
+
const openAiChat = isOccProviderId(provider.id);
|
|
3962
|
+
const isCustomTemplate = provider.id === "custom" || isCustomProviderId(provider.id);
|
|
3963
|
+
const oauthOnly = isOAuthProvider(provider);
|
|
3964
|
+
const oauthAvailable = supportsOAuth(provider);
|
|
3965
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
3966
|
+
type: "button",
|
|
3967
|
+
className: cn("flex w-full items-center gap-3 rounded-lg px-2 py-2 text-left transition-[background-color,transform] duration-150", "hover:bg-muted/60 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none active:scale-[0.96]"),
|
|
3968
|
+
onClick: onSelect,
|
|
3969
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
3970
|
+
className: "flex size-8 shrink-0 items-center justify-center rounded-[4px] border border-border/40 bg-background/60",
|
|
3971
|
+
children: /* @__PURE__ */ jsx(ProviderBrandIcon, {
|
|
3972
|
+
provider: isCustomTemplate ? "custom" : provider.id,
|
|
3973
|
+
api: provider.api,
|
|
3974
|
+
className: "text-foreground/70"
|
|
3975
|
+
})
|
|
3976
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3977
|
+
className: "min-w-0 flex-1",
|
|
3978
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
3979
|
+
className: "truncate text-sm font-medium",
|
|
3980
|
+
children: provider.name
|
|
3981
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3982
|
+
className: "truncate text-xs text-muted-foreground",
|
|
3983
|
+
children: [oauthOnly ? "OAuth sign-in" : oauthAvailable ? "API key or OAuth" : isCustomTemplate ? "API family + key + https base URL + models" : openAiChat ? "API key + base URL + model name" : provider.envVarName, configured ? " \xB7 Update" : ""]
|
|
3984
|
+
})]
|
|
3985
|
+
})]
|
|
3986
|
+
});
|
|
3987
|
+
}
|
|
3988
|
+
function ActiveProviderList({ providers, editingProvider, form, operation, actions, onEdit, onCancelEdit, onSave, onRemove, onOAuthLogin, onConfigured }) {
|
|
3989
|
+
const { api, apiKey, baseUrl, modelId, models, displayName, showPassword, attemptedSave, canSave } = form;
|
|
3990
|
+
const { isPending, canRemove } = operation;
|
|
3991
|
+
const { onApiKeyChange, onApiChange, onBaseUrlChange, onModelIdChange, onModelsChange, onDisplayNameChange, onTogglePassword } = actions;
|
|
3992
|
+
return /* @__PURE__ */ jsx("div", {
|
|
3993
|
+
className: "flex flex-col gap-1.5",
|
|
3994
|
+
children: providers.map((provider) => {
|
|
3995
|
+
const isEditing = editingProvider === provider.id;
|
|
3996
|
+
const isCustom = isCustomProviderId(provider.id);
|
|
3997
|
+
const meta = PROVIDER_METADATA[provider.id] ?? PROVIDER_METADATA[isCustom ? "custom" : "openai-chat-completions"];
|
|
3998
|
+
const openAiChat = isOccProviderId(provider.id);
|
|
3999
|
+
const oauthOnly = isOAuthProvider(provider);
|
|
4000
|
+
const oauthAvailable = supportsOAuth(provider);
|
|
4001
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4002
|
+
className: "flex flex-col",
|
|
4003
|
+
children: [/* @__PURE__ */ jsx(ItemRow, {
|
|
4004
|
+
interactive: false,
|
|
4005
|
+
icon: /* @__PURE__ */ jsx(ProviderBrandIcon, {
|
|
4006
|
+
provider: provider.id,
|
|
4007
|
+
api: provider.api,
|
|
4008
|
+
className: "text-foreground/80"
|
|
4009
|
+
}),
|
|
4010
|
+
title: provider.name,
|
|
4011
|
+
subtitle: oauthOnly ? "OAuth sign-in" : oauthAvailable ? "API key or OAuth" : isCustom ? "Custom provider \xB7 API key + base URL + models" : openAiChat ? "OpenAI-compatible \xB7 API key + base URL + model name" : provider.envVarName,
|
|
4012
|
+
trailing: /* @__PURE__ */ jsxs("div", {
|
|
4013
|
+
className: "flex items-center gap-0.5",
|
|
4014
|
+
children: [/* @__PURE__ */ jsxs(Button, {
|
|
4015
|
+
type: "button",
|
|
4016
|
+
variant: "ghost",
|
|
4017
|
+
size: "sm",
|
|
4018
|
+
className: cn(HIT_AREA_EXPAND_DENSE_CLASS, "h-7 px-2 text-xs text-muted-foreground transition-[background-color,color,transform] duration-150 hover:text-destructive active:scale-[0.96]"),
|
|
4019
|
+
disabled: isPending || !canRemove,
|
|
4020
|
+
"aria-label": `Remove ${provider.name}`,
|
|
4021
|
+
onClick: () => onRemove(provider),
|
|
4022
|
+
children: [/* @__PURE__ */ jsx(Trash2, { "data-icon": "inline-start" }), "Remove"]
|
|
4023
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
4024
|
+
type: "button",
|
|
4025
|
+
variant: "ghost",
|
|
4026
|
+
size: "sm",
|
|
4027
|
+
className: cn(HIT_AREA_EXPAND_DENSE_CLASS, "h-7 px-2 text-xs transition-[background-color,transform] duration-150 active:scale-[0.96]"),
|
|
4028
|
+
disabled: isPending,
|
|
4029
|
+
onClick: () => {
|
|
4030
|
+
if (isEditing) {
|
|
4031
|
+
onCancelEdit();
|
|
4032
|
+
return;
|
|
4033
|
+
}
|
|
4034
|
+
onEdit(provider.id);
|
|
4035
|
+
},
|
|
4036
|
+
children: [!isEditing ? /* @__PURE__ */ jsx(Pencil, { "data-icon": "inline-start" }) : null, isEditing ? "Cancel" : "Update"]
|
|
4037
|
+
})]
|
|
4038
|
+
})
|
|
4039
|
+
}), isEditing ? /* @__PURE__ */ jsx(RowSurface, {
|
|
4040
|
+
tone: "inset",
|
|
4041
|
+
padding: "md",
|
|
4042
|
+
className: "flex flex-col gap-2 border-t border-border/30",
|
|
4043
|
+
children: oauthOnly ? /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
|
|
4044
|
+
provider,
|
|
4045
|
+
onConfigured,
|
|
4046
|
+
onOAuthLogin
|
|
4047
|
+
}, provider.id) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
4048
|
+
/* @__PURE__ */ jsx(ProviderCredentialFields, {
|
|
4049
|
+
attemptedSave,
|
|
4050
|
+
api: provider.api ?? api,
|
|
4051
|
+
apiKey,
|
|
4052
|
+
baseUrl,
|
|
4053
|
+
modelId,
|
|
4054
|
+
models,
|
|
4055
|
+
displayName,
|
|
4056
|
+
isCustom,
|
|
4057
|
+
openAiChat,
|
|
4058
|
+
placeholder: meta.placeholder,
|
|
4059
|
+
showPassword,
|
|
4060
|
+
onApiKeyChange,
|
|
4061
|
+
onApiChange,
|
|
4062
|
+
onBaseUrlChange,
|
|
4063
|
+
onModelIdChange,
|
|
4064
|
+
onModelsChange,
|
|
4065
|
+
onDisplayNameChange: isCustom || provider.providerFamily !== void 0 ? onDisplayNameChange : void 0,
|
|
4066
|
+
onTogglePassword
|
|
4067
|
+
}),
|
|
4068
|
+
/* @__PURE__ */ jsxs(Alert, {
|
|
4069
|
+
className: "px-3 py-2",
|
|
4070
|
+
children: [/* @__PURE__ */ jsx(Info, {}), /* @__PURE__ */ jsx(AlertDescription, {
|
|
4071
|
+
className: "text-xs text-pretty",
|
|
4072
|
+
children: meta.help
|
|
4073
|
+
})]
|
|
4074
|
+
}),
|
|
4075
|
+
/* @__PURE__ */ jsx("div", {
|
|
4076
|
+
className: "flex items-center justify-end",
|
|
4077
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
4078
|
+
type: "button",
|
|
4079
|
+
size: "sm",
|
|
4080
|
+
disabled: isPending || !canSave,
|
|
4081
|
+
onClick: () => onSave(provider.id),
|
|
4082
|
+
children: [isPending ? /* @__PURE__ */ jsx(Spinner, { "data-icon": "inline-start" }) : null, "Save"]
|
|
4083
|
+
})
|
|
4084
|
+
}),
|
|
4085
|
+
oauthAvailable ? /* @__PURE__ */ jsx(ProviderOAuthSignIn, {
|
|
4086
|
+
provider,
|
|
4087
|
+
onConfigured,
|
|
4088
|
+
onOAuthLogin
|
|
4089
|
+
}, `${provider.id}-oauth`) : null
|
|
4090
|
+
] })
|
|
4091
|
+
}) : null]
|
|
4092
|
+
}, provider.id);
|
|
4093
|
+
})
|
|
4094
|
+
});
|
|
4095
|
+
}
|
|
4096
|
+
function ProviderCredentialsSection({ isLoading, isPending, onOAuthLogin, onRemoveProvider, onUpdateProvider, providers }) {
|
|
4097
|
+
const { activeProviders, addPickerOpen, addPickerQuery, api, apiKey, attemptedSave, baseUrl, canSave, closeAddPicker, closeEditor, confirmRemoveProvider, credentialProviders, displayName, editingProvider, editingUnconfiguredProvider, filteredActiveProviders, filteredPickerAvailable, filteredPickerConfigured, handleRemove, handleSave, modelId, models, openAddPicker, openEditor, pickerHasResults, searchQuery, selectProviderFromPicker, setAddPickerQuery, setApi, setApiKey, setBaseUrl, setConfirmRemoveProvider, setDisplayName, setModelId, setModels, setSearchQuery, setShowPassword, showPassword } = useProviderCredentialsController({
|
|
4098
|
+
onRemoveProvider,
|
|
4099
|
+
onUpdateProvider,
|
|
4100
|
+
providers
|
|
4101
|
+
});
|
|
4102
|
+
const form = {
|
|
4103
|
+
api,
|
|
4104
|
+
apiKey,
|
|
4105
|
+
baseUrl,
|
|
4106
|
+
modelId,
|
|
4107
|
+
models,
|
|
4108
|
+
displayName,
|
|
4109
|
+
showPassword,
|
|
4110
|
+
attemptedSave,
|
|
4111
|
+
canSave
|
|
4112
|
+
};
|
|
4113
|
+
const operation = {
|
|
4114
|
+
isPending,
|
|
4115
|
+
canRemove: Boolean(onRemoveProvider)
|
|
4116
|
+
};
|
|
4117
|
+
const actions = {
|
|
4118
|
+
onApiKeyChange: setApiKey,
|
|
4119
|
+
onApiChange: setApi,
|
|
4120
|
+
onBaseUrlChange: setBaseUrl,
|
|
4121
|
+
onModelIdChange: setModelId,
|
|
4122
|
+
onModelsChange: setModels,
|
|
4123
|
+
onDisplayNameChange: setDisplayName,
|
|
4124
|
+
onTogglePassword: () => setShowPassword((current) => !current)
|
|
4125
|
+
};
|
|
4126
|
+
return /* @__PURE__ */ jsxs(SettingsPane, {
|
|
4127
|
+
title: "Providers",
|
|
4128
|
+
description: "Locally, API keys are stored in `.env.local`. When deployed, they are stored encrypted in your account.",
|
|
4129
|
+
children: [addPickerOpen ? /* @__PURE__ */ jsx(AddProviderPickerPanel, {
|
|
4130
|
+
addPickerQuery,
|
|
4131
|
+
credentialProvidersLength: credentialProviders.length,
|
|
4132
|
+
filteredPickerAvailable,
|
|
4133
|
+
filteredPickerConfigured,
|
|
4134
|
+
pickerHasResults,
|
|
4135
|
+
onClose: closeAddPicker,
|
|
4136
|
+
onQueryChange: setAddPickerQuery,
|
|
4137
|
+
onSelect: selectProviderFromPicker
|
|
4138
|
+
}) : editingUnconfiguredProvider && isOAuthProvider(editingUnconfiguredProvider) ? /* @__PURE__ */ jsx(AddProviderOAuthPanel, {
|
|
4139
|
+
provider: editingUnconfiguredProvider,
|
|
4140
|
+
onBack: openAddPicker,
|
|
4141
|
+
onConfigured: closeEditor,
|
|
4142
|
+
onOAuthLogin
|
|
4143
|
+
}, editingUnconfiguredProvider.id) : editingUnconfiguredProvider ? /* @__PURE__ */ jsx(AddProviderEditorPanel, {
|
|
4144
|
+
provider: editingUnconfiguredProvider,
|
|
4145
|
+
api,
|
|
4146
|
+
apiKey,
|
|
4147
|
+
baseUrl,
|
|
4148
|
+
modelId,
|
|
4149
|
+
models,
|
|
4150
|
+
displayName,
|
|
4151
|
+
showPassword,
|
|
4152
|
+
attemptedSave,
|
|
4153
|
+
isPending,
|
|
4154
|
+
canSave,
|
|
4155
|
+
onApiKeyChange: setApiKey,
|
|
4156
|
+
onApiChange: setApi,
|
|
4157
|
+
onBaseUrlChange: setBaseUrl,
|
|
4158
|
+
onModelIdChange: setModelId,
|
|
4159
|
+
onModelsChange: setModels,
|
|
4160
|
+
onDisplayNameChange: setDisplayName,
|
|
4161
|
+
onTogglePassword: () => setShowPassword((current) => !current),
|
|
4162
|
+
onBack: openAddPicker,
|
|
4163
|
+
onCancel: closeEditor,
|
|
4164
|
+
onConfigured: closeEditor,
|
|
4165
|
+
onOAuthLogin,
|
|
4166
|
+
onSave: () => {
|
|
4167
|
+
if (editingProvider) handleSave(editingProvider);
|
|
4168
|
+
}
|
|
4169
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
4170
|
+
className: "flex flex-col gap-3",
|
|
4171
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
4172
|
+
className: "flex items-center gap-2",
|
|
4173
|
+
children: [/* @__PURE__ */ jsxs(InputGroup, {
|
|
4174
|
+
className: "flex-1",
|
|
4175
|
+
children: [/* @__PURE__ */ jsx(InputGroupAddon, {
|
|
4176
|
+
align: "inline-start",
|
|
4177
|
+
children: /* @__PURE__ */ jsx(Search, {})
|
|
4178
|
+
}), /* @__PURE__ */ jsx(InputGroupInput, {
|
|
4179
|
+
type: "text",
|
|
4180
|
+
placeholder: "Search credentials\u2026",
|
|
4181
|
+
value: searchQuery,
|
|
4182
|
+
onChange: (event) => setSearchQuery(event.target.value),
|
|
4183
|
+
"aria-label": "Search credentials",
|
|
4184
|
+
disabled: isLoading || activeProviders.length === 0
|
|
4185
|
+
})]
|
|
4186
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
4187
|
+
type: "button",
|
|
4188
|
+
variant: "outline",
|
|
4189
|
+
size: "sm",
|
|
4190
|
+
disabled: isLoading || credentialProviders.length === 0,
|
|
4191
|
+
onClick: openAddPicker,
|
|
4192
|
+
children: [/* @__PURE__ */ jsx(Plus, { "data-icon": "inline-start" }), "Add provider"]
|
|
4193
|
+
})]
|
|
4194
|
+
}), isLoading ? /* @__PURE__ */ jsxs("div", {
|
|
4195
|
+
className: "flex items-center justify-center gap-2 py-6 text-xs text-muted-foreground",
|
|
4196
|
+
children: [/* @__PURE__ */ jsx(Spinner, { className: "size-3" }), /* @__PURE__ */ jsx("span", { children: "Loading\u2026" })]
|
|
4197
|
+
}) : activeProviders.length === 0 ? /* @__PURE__ */ jsxs("div", {
|
|
4198
|
+
className: "flex flex-col items-center gap-3 py-8",
|
|
4199
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
4200
|
+
className: "text-center text-xs text-pretty text-muted-foreground",
|
|
4201
|
+
children: "No providers configured"
|
|
4202
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
4203
|
+
type: "button",
|
|
4204
|
+
variant: "outline",
|
|
4205
|
+
size: "sm",
|
|
4206
|
+
disabled: credentialProviders.length === 0,
|
|
4207
|
+
onClick: openAddPicker,
|
|
4208
|
+
children: [/* @__PURE__ */ jsx(Plus, { "data-icon": "inline-start" }), "Add provider"]
|
|
4209
|
+
})]
|
|
4210
|
+
}) : filteredActiveProviders.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
4211
|
+
className: "py-6 text-center text-xs text-pretty text-muted-foreground",
|
|
4212
|
+
children: "No matching providers found."
|
|
4213
|
+
}) : /* @__PURE__ */ jsx(ActiveProviderList, {
|
|
4214
|
+
providers: filteredActiveProviders,
|
|
4215
|
+
editingProvider,
|
|
4216
|
+
form,
|
|
4217
|
+
operation,
|
|
4218
|
+
actions,
|
|
4219
|
+
onEdit: openEditor,
|
|
4220
|
+
onCancelEdit: closeEditor,
|
|
4221
|
+
onSave: (providerId) => void handleSave(providerId),
|
|
4222
|
+
onRemove: setConfirmRemoveProvider,
|
|
4223
|
+
onOAuthLogin,
|
|
4224
|
+
onConfigured: closeEditor
|
|
4225
|
+
})]
|
|
4226
|
+
}), /* @__PURE__ */ jsx(RemoveProviderConfirmDialog, {
|
|
4227
|
+
confirmRemoveProvider,
|
|
4228
|
+
isPending,
|
|
4229
|
+
onClose: () => setConfirmRemoveProvider(null),
|
|
4230
|
+
onConfirm: (provider) => {
|
|
4231
|
+
handleRemove(provider);
|
|
4232
|
+
}
|
|
4233
|
+
})]
|
|
4234
|
+
});
|
|
4235
|
+
}
|
|
4351
4236
|
var PROVENANCE_SOURCES = /* @__PURE__ */ new Set([
|
|
4352
4237
|
"auto",
|
|
4353
4238
|
"global",
|
|
@@ -4464,6 +4349,111 @@ function CatalogValueList({ addLabel, catalog, onChange, placeholder, values })
|
|
|
4464
4349
|
})] })]
|
|
4465
4350
|
});
|
|
4466
4351
|
}
|
|
4352
|
+
var TRANSPORT_OPTIONS = [
|
|
4353
|
+
{
|
|
4354
|
+
value: "auto",
|
|
4355
|
+
label: "Auto"
|
|
4356
|
+
},
|
|
4357
|
+
{
|
|
4358
|
+
value: "sse",
|
|
4359
|
+
label: "SSE"
|
|
4360
|
+
},
|
|
4361
|
+
{
|
|
4362
|
+
value: "websocket",
|
|
4363
|
+
label: "WebSocket"
|
|
4364
|
+
}
|
|
4365
|
+
];
|
|
4366
|
+
var DELIVERY_OPTIONS = [{
|
|
4367
|
+
value: "all",
|
|
4368
|
+
label: "All"
|
|
4369
|
+
}, {
|
|
4370
|
+
value: "one-at-a-time",
|
|
4371
|
+
label: "One at a time"
|
|
4372
|
+
}];
|
|
4373
|
+
function HarnessRuntimeSection({ draft, updateDraft }) {
|
|
4374
|
+
const disabled2 = !draft;
|
|
4375
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4376
|
+
className: "flex flex-col gap-2",
|
|
4377
|
+
children: [
|
|
4378
|
+
/* @__PURE__ */ jsx(ItemRow, {
|
|
4379
|
+
title: "Compaction",
|
|
4380
|
+
subtitle: "Summarize old turns when context fills up",
|
|
4381
|
+
trailing: /* @__PURE__ */ jsx(Switch, {
|
|
4382
|
+
"aria-label": "Compaction",
|
|
4383
|
+
checked: draft?.compaction.enabled ?? false,
|
|
4384
|
+
disabled: disabled2,
|
|
4385
|
+
onCheckedChange: (enabled) => updateDraft((current) => ({
|
|
4386
|
+
...current,
|
|
4387
|
+
compaction: {
|
|
4388
|
+
...current.compaction,
|
|
4389
|
+
enabled
|
|
4390
|
+
}
|
|
4391
|
+
}))
|
|
4392
|
+
})
|
|
4393
|
+
}),
|
|
4394
|
+
/* @__PURE__ */ jsx(ItemRow, {
|
|
4395
|
+
title: "Auto-retry",
|
|
4396
|
+
subtitle: "Retry failed provider requests",
|
|
4397
|
+
trailing: /* @__PURE__ */ jsx(Switch, {
|
|
4398
|
+
"aria-label": "Auto-retry",
|
|
4399
|
+
checked: draft?.retry.enabled ?? false,
|
|
4400
|
+
disabled: disabled2,
|
|
4401
|
+
onCheckedChange: (enabled) => updateDraft((current) => ({
|
|
4402
|
+
...current,
|
|
4403
|
+
retry: {
|
|
4404
|
+
...current.retry,
|
|
4405
|
+
enabled
|
|
4406
|
+
}
|
|
4407
|
+
}))
|
|
4408
|
+
})
|
|
4409
|
+
}),
|
|
4410
|
+
/* @__PURE__ */ jsx(ItemRow, {
|
|
4411
|
+
title: "Transport",
|
|
4412
|
+
trailing: /* @__PURE__ */ jsx(Select, {
|
|
4413
|
+
"aria-label": "Transport",
|
|
4414
|
+
className: "w-[160px]",
|
|
4415
|
+
disabled: disabled2,
|
|
4416
|
+
onValueChange: (value) => updateDraft((current) => ({
|
|
4417
|
+
...current,
|
|
4418
|
+
transport: value
|
|
4419
|
+
})),
|
|
4420
|
+
options: [...TRANSPORT_OPTIONS],
|
|
4421
|
+
value: draft?.transport ?? "auto"
|
|
4422
|
+
})
|
|
4423
|
+
}),
|
|
4424
|
+
/* @__PURE__ */ jsx(ItemRow, {
|
|
4425
|
+
title: "Steering",
|
|
4426
|
+
subtitle: "How queued steers are delivered mid-turn",
|
|
4427
|
+
trailing: /* @__PURE__ */ jsx(Select, {
|
|
4428
|
+
"aria-label": "Steering",
|
|
4429
|
+
className: "w-[160px]",
|
|
4430
|
+
disabled: disabled2,
|
|
4431
|
+
onValueChange: (value) => updateDraft((current) => ({
|
|
4432
|
+
...current,
|
|
4433
|
+
steeringMode: value
|
|
4434
|
+
})),
|
|
4435
|
+
options: [...DELIVERY_OPTIONS],
|
|
4436
|
+
value: draft?.steeringMode ?? "all"
|
|
4437
|
+
})
|
|
4438
|
+
}),
|
|
4439
|
+
/* @__PURE__ */ jsx(ItemRow, {
|
|
4440
|
+
title: "Follow-up",
|
|
4441
|
+
subtitle: "How queued follow-ups run after the turn",
|
|
4442
|
+
trailing: /* @__PURE__ */ jsx(Select, {
|
|
4443
|
+
"aria-label": "Follow-up",
|
|
4444
|
+
className: "w-[160px]",
|
|
4445
|
+
disabled: disabled2,
|
|
4446
|
+
onValueChange: (value) => updateDraft((current) => ({
|
|
4447
|
+
...current,
|
|
4448
|
+
followUpMode: value
|
|
4449
|
+
})),
|
|
4450
|
+
options: [...DELIVERY_OPTIONS],
|
|
4451
|
+
value: draft?.followUpMode ?? "all"
|
|
4452
|
+
})
|
|
4453
|
+
})
|
|
4454
|
+
]
|
|
4455
|
+
});
|
|
4456
|
+
}
|
|
4467
4457
|
function ResourcesSection({ draft, onEnableSkillCommandsChange, onExtensionsChange, onPackageRowsChange, onPromptsChange, onRevert, onSave, onSkillsChange, onThemesChange, packageError, packageRows, resourceDirty, resources, resourceSummary, saving, scope = "harness", settingsLoading, updateDraft }) {
|
|
4468
4458
|
const disabled2 = !draft || settingsLoading || !!packageError;
|
|
4469
4459
|
const catalogSubtitle = resourceSummary.total === 0 ? "Empty" : resourceSummary.reloadRequired > 0 ? `${resourceSummary.total} \xB7 ${resourceSummary.reloadRequired} reload` : `${resourceSummary.total}`;
|