@opengeni/react 0.36.1 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/{chunk-J2RVJ6JX.js → chunk-4IJCL7YO.js} +13 -2
- package/dist/chunk-4IJCL7YO.js.map +1 -0
- package/dist/{chunk-OKKMZDQF.js → chunk-FSPDND3P.js} +2 -2
- package/dist/{chunk-FT2TXNGZ.js → chunk-HJ4OQVGW.js} +174 -14
- package/dist/chunk-HJ4OQVGW.js.map +1 -0
- package/dist/{chunk-N4XEBE23.js → chunk-IP22SLO6.js} +432 -10
- package/dist/chunk-IP22SLO6.js.map +1 -0
- package/dist/{chunk-22RM4GMO.js → chunk-SJKT4TKW.js} +26 -2
- package/dist/chunk-SJKT4TKW.js.map +1 -0
- package/dist/{chunk-Z5FV355Z.js → chunk-UCZPNXV3.js} +91 -14
- package/dist/chunk-UCZPNXV3.js.map +1 -0
- package/dist/components/chat-composer.d.ts +3 -1
- package/dist/components/model-policy-picker.d.ts +78 -0
- package/dist/components/session-chrome.d.ts +1 -1
- package/dist/composer.d.ts +2 -0
- package/dist/composer.js +17 -3
- package/dist/hooks/use-composer.d.ts +9 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +30 -9
- package/dist/index.js.map +1 -1
- package/dist/model-policy.d.ts +12 -4
- package/dist/model-policy.js +5 -1
- package/dist/session-ui.js +2 -2
- package/dist/session.js +3 -3
- package/dist/timeline/types.d.ts +5 -0
- package/package.json +2 -2
- package/src/components/chat-composer.tsx +8 -3
- package/src/components/model-policy-picker.tsx +582 -0
- package/src/components/session-chrome.tsx +138 -14
- package/src/composer.ts +13 -0
- package/src/hooks/use-composer.ts +213 -16
- package/src/index.ts +15 -0
- package/src/model-policy.ts +51 -7
- package/src/timeline/projection.ts +21 -1
- package/src/timeline/types.ts +5 -0
- package/dist/chunk-22RM4GMO.js.map +0 -1
- package/dist/chunk-FT2TXNGZ.js.map +0 -1
- package/dist/chunk-J2RVJ6JX.js.map +0 -1
- package/dist/chunk-N4XEBE23.js.map +0 -1
- package/dist/chunk-Z5FV355Z.js.map +0 -1
- /package/dist/{chunk-OKKMZDQF.js.map → chunk-FSPDND3P.js.map} +0 -0
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shouldSteerOnKey,
|
|
3
3
|
shouldSubmitOnKey
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HJ4OQVGW.js";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
coerceReasoningEffortForModel,
|
|
7
|
+
effortOptionsForModel,
|
|
8
|
+
findPickerRow,
|
|
9
|
+
groupPickerRowsByBillingClass,
|
|
10
|
+
labelReasoningEffort,
|
|
11
|
+
projectClientModelRows,
|
|
12
|
+
runnableLatencyModesForModel
|
|
13
|
+
} from "./chunk-SJKT4TKW.js";
|
|
8
14
|
import {
|
|
9
15
|
Tooltip,
|
|
10
16
|
TooltipContent,
|
|
@@ -1291,17 +1297,17 @@ function ModelPicker({
|
|
|
1291
1297
|
codexOnly = false
|
|
1292
1298
|
}) {
|
|
1293
1299
|
const selectId = useId();
|
|
1294
|
-
const
|
|
1300
|
+
const effectiveRows2 = useMemo3(
|
|
1295
1301
|
() => rows && rows.length > 0 ? applyCodexOnlyRows(rows, codexOnly) : [],
|
|
1296
1302
|
[rows, codexOnly]
|
|
1297
1303
|
);
|
|
1298
1304
|
const billingGroups = useMemo3(
|
|
1299
|
-
() =>
|
|
1300
|
-
[
|
|
1305
|
+
() => effectiveRows2.length > 0 ? groupPickerRowsByBillingClass(effectiveRows2) : [],
|
|
1306
|
+
[effectiveRows2]
|
|
1301
1307
|
);
|
|
1302
1308
|
const providerGroupList = useMemo3(() => providerGroups(models, codexOnly), [models, codexOnly]);
|
|
1303
|
-
const useBillingGroups = Boolean(
|
|
1304
|
-
if (models.length === 0 &&
|
|
1309
|
+
const useBillingGroups = Boolean(effectiveRows2.length);
|
|
1310
|
+
if (models.length === 0 && effectiveRows2.length === 0) {
|
|
1305
1311
|
return null;
|
|
1306
1312
|
}
|
|
1307
1313
|
return /* @__PURE__ */ jsxs2("span", { className: cn("relative inline-flex items-center", className), children: [
|
|
@@ -2770,6 +2776,415 @@ function transcriptionErrorMessage(code, messages) {
|
|
|
2770
2776
|
}
|
|
2771
2777
|
}
|
|
2772
2778
|
|
|
2779
|
+
// src/components/model-policy-picker.tsx
|
|
2780
|
+
import {
|
|
2781
|
+
CheckIcon,
|
|
2782
|
+
ChevronDownIcon as ChevronDownIcon3,
|
|
2783
|
+
ChevronLeftIcon,
|
|
2784
|
+
ChevronRightIcon,
|
|
2785
|
+
KeyRoundIcon,
|
|
2786
|
+
ZapIcon
|
|
2787
|
+
} from "lucide-react";
|
|
2788
|
+
import { motion as motion4, useReducedMotion } from "motion/react";
|
|
2789
|
+
import { DropdownMenu } from "radix-ui";
|
|
2790
|
+
import { useEffect as useEffect5, useMemo as useMemo5, useState as useState6 } from "react";
|
|
2791
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2792
|
+
var defaultModelPolicyPickerMessages = {
|
|
2793
|
+
label: "Model and effort",
|
|
2794
|
+
loading: "Loading model catalog\u2026",
|
|
2795
|
+
noModels: "No models available.",
|
|
2796
|
+
thinking: "Thinking",
|
|
2797
|
+
fast: "Fast",
|
|
2798
|
+
fastRateHint: "2\xD7 rate",
|
|
2799
|
+
codexOnly: "Codex-only session",
|
|
2800
|
+
billingHints: {
|
|
2801
|
+
opengeni_credits: "Will use credits",
|
|
2802
|
+
codex_subscription: "ChatGPT / Codex plan",
|
|
2803
|
+
byok: "Billed to your AI Gateway"
|
|
2804
|
+
}
|
|
2805
|
+
};
|
|
2806
|
+
var SLIDE_EASE = [0.22, 1, 0.36, 1];
|
|
2807
|
+
function OpenGeniMark(props) {
|
|
2808
|
+
return /* @__PURE__ */ jsx5(
|
|
2809
|
+
"svg",
|
|
2810
|
+
{
|
|
2811
|
+
viewBox: "0 0 140 133",
|
|
2812
|
+
fill: "none",
|
|
2813
|
+
stroke: "currentColor",
|
|
2814
|
+
strokeWidth: 1.2,
|
|
2815
|
+
strokeLinejoin: "round",
|
|
2816
|
+
"aria-hidden": "true",
|
|
2817
|
+
...props,
|
|
2818
|
+
children: /* @__PURE__ */ jsx5("g", { transform: "translate(-17.5,-20.999893188476562) scale(1.75)", children: /* @__PURE__ */ jsx5("g", { transform: "translate(0,-952.36218)", children: /* @__PURE__ */ jsx5("path", { d: "m 60.7828,964.36215 27.1809,0.8834 -27.1809,25.9958 z m -1.9745,1.4513 0,26.7845 -25.2681,0 c 8.6166,-8.7334 16.8796,-17.8103 25.2681,-26.7845 z m 27.7053,3.628 3.4864,1.1989 -12.5877,7.4768 z m -68.1835,2.9656 5.5226,0 12.8654,14.0705 -5.9854,6.1204 -12.4026,0 c 9e-4,-6.7347 0,-13.4597 0,-20.1909 z m -1.9746,1.2304 0,5.8364 -6.3555,0 z m 3.363,20.9796 38.627,0 -10.7675,29.43465 z m 39.0898,4.54286 0,41.20229 -12.5878,-6.8775 c 4.1972,-11.443 8.3886,-22.879 12.5878,-34.32479 z" }) }) })
|
|
2819
|
+
}
|
|
2820
|
+
);
|
|
2821
|
+
}
|
|
2822
|
+
function ChatGptMark(props) {
|
|
2823
|
+
return /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", ...props, children: /* @__PURE__ */ jsx5("path", { d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3653-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8414 3.3698-2.02 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.783-2.7622a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" }) });
|
|
2824
|
+
}
|
|
2825
|
+
function BillingClassMark(props) {
|
|
2826
|
+
const labels = {
|
|
2827
|
+
opengeni_credits: "OpenGeni",
|
|
2828
|
+
codex_subscription: "Codex",
|
|
2829
|
+
byok: "Bring your own key"
|
|
2830
|
+
};
|
|
2831
|
+
const label = props["aria-label"] ?? labels[props.billingClass];
|
|
2832
|
+
const accessibility = label.length === 0 ? { "aria-hidden": true } : { role: "img", "aria-label": label };
|
|
2833
|
+
const shell = cn(
|
|
2834
|
+
"inline-flex size-3.5 shrink-0 items-center justify-center overflow-hidden text-og-fg-subtle",
|
|
2835
|
+
props.className
|
|
2836
|
+
);
|
|
2837
|
+
const mark = "size-3.5";
|
|
2838
|
+
return /* @__PURE__ */ jsx5(
|
|
2839
|
+
"span",
|
|
2840
|
+
{
|
|
2841
|
+
className: shell,
|
|
2842
|
+
"data-testid": `billing-class-icon-${props.billingClass}`,
|
|
2843
|
+
...accessibility,
|
|
2844
|
+
children: props.billingClass === "opengeni_credits" ? /* @__PURE__ */ jsx5(OpenGeniMark, { className: mark }) : props.billingClass === "codex_subscription" ? /* @__PURE__ */ jsx5(ChatGptMark, { className: mark }) : /* @__PURE__ */ jsx5(KeyRoundIcon, { className: mark, "aria-hidden": true })
|
|
2845
|
+
}
|
|
2846
|
+
);
|
|
2847
|
+
}
|
|
2848
|
+
function isCodexModel(model) {
|
|
2849
|
+
return model.id.startsWith("codex/") || model.source === "codex";
|
|
2850
|
+
}
|
|
2851
|
+
function applyCodexOnly(rows, codexOnly, unavailableReason) {
|
|
2852
|
+
if (!codexOnly) return rows;
|
|
2853
|
+
return rows.map(
|
|
2854
|
+
(row) => isCodexModel(row.catalog) ? row : {
|
|
2855
|
+
...row,
|
|
2856
|
+
selectable: false,
|
|
2857
|
+
unavailableReason: row.unavailableReason ?? unavailableReason
|
|
2858
|
+
}
|
|
2859
|
+
);
|
|
2860
|
+
}
|
|
2861
|
+
function effectiveRows(props) {
|
|
2862
|
+
const rows = props.rows !== void 0 ? props.rows : projectClientModelRows(props.models ?? []);
|
|
2863
|
+
const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };
|
|
2864
|
+
return applyCodexOnly(rows, props.codexOnly === true, messages.codexOnly);
|
|
2865
|
+
}
|
|
2866
|
+
function defaultNavState(rows, modelId) {
|
|
2867
|
+
const selected = findPickerRow(rows, modelId);
|
|
2868
|
+
if (!selected) {
|
|
2869
|
+
const rails = new Set(rows.map((row) => row.billingClass));
|
|
2870
|
+
const onlyRail = rails.size === 1 ? rows[0]?.billingClass : null;
|
|
2871
|
+
return onlyRail ? { level: "models", rail: onlyRail, modelId: null } : { level: "providers", rail: null, modelId: null };
|
|
2872
|
+
}
|
|
2873
|
+
return { level: "thinking", rail: selected.billingClass, modelId: selected.id };
|
|
2874
|
+
}
|
|
2875
|
+
function usePickerNavState(sessionKey, rows, model) {
|
|
2876
|
+
const [state, setState] = useState6(() => defaultNavState(rows, model));
|
|
2877
|
+
useEffect5(() => {
|
|
2878
|
+
setState(defaultNavState(rows, model));
|
|
2879
|
+
}, [sessionKey]);
|
|
2880
|
+
return [state, setState];
|
|
2881
|
+
}
|
|
2882
|
+
function PickerNavRow(props) {
|
|
2883
|
+
return /* @__PURE__ */ jsxs5(
|
|
2884
|
+
"button",
|
|
2885
|
+
{
|
|
2886
|
+
type: "button",
|
|
2887
|
+
disabled: props.disabled,
|
|
2888
|
+
title: props.title,
|
|
2889
|
+
onClick: props.onClick,
|
|
2890
|
+
"data-testid": props.testId,
|
|
2891
|
+
className: cn(
|
|
2892
|
+
"flex w-full cursor-pointer items-center gap-2 rounded-og-sm px-2.5 py-2 text-left text-og-fg outline-none transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40",
|
|
2893
|
+
props.disabled && "cursor-not-allowed opacity-50"
|
|
2894
|
+
),
|
|
2895
|
+
children: [
|
|
2896
|
+
props.icon,
|
|
2897
|
+
/* @__PURE__ */ jsxs5("span", { className: "min-w-0 flex-1", children: [
|
|
2898
|
+
/* @__PURE__ */ jsx5("span", { className: cn("block truncate text-sm", props.active && "font-medium"), children: props.label }),
|
|
2899
|
+
props.hint ? /* @__PURE__ */ jsx5("span", { className: "mt-0.5 block truncate text-xs text-og-fg-subtle", children: props.hint }) : null
|
|
2900
|
+
] }),
|
|
2901
|
+
props.trailing ? /* @__PURE__ */ jsx5("span", { className: "ml-auto shrink-0", children: props.trailing }) : null,
|
|
2902
|
+
props.showChevron === false ? null : /* @__PURE__ */ jsx5(ChevronRightIcon, { className: "size-3.5 shrink-0 text-og-fg-subtle" })
|
|
2903
|
+
]
|
|
2904
|
+
}
|
|
2905
|
+
);
|
|
2906
|
+
}
|
|
2907
|
+
function PickerBackHeader(props) {
|
|
2908
|
+
return /* @__PURE__ */ jsxs5("div", { className: "mb-1 flex items-center gap-0.5 border-b border-og-border/70 px-0.5 pb-1.5", children: [
|
|
2909
|
+
/* @__PURE__ */ jsxs5(
|
|
2910
|
+
"button",
|
|
2911
|
+
{
|
|
2912
|
+
type: "button",
|
|
2913
|
+
onClick: props.onBack,
|
|
2914
|
+
"data-testid": "model-picker-back",
|
|
2915
|
+
className: "flex min-w-0 flex-1 cursor-pointer items-center gap-1.5 rounded-og-sm px-1.5 py-1.5 text-left text-og-fg outline-none transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40",
|
|
2916
|
+
children: [
|
|
2917
|
+
/* @__PURE__ */ jsx5(ChevronLeftIcon, { className: "size-3.5 shrink-0 text-og-fg-subtle" }),
|
|
2918
|
+
props.icon,
|
|
2919
|
+
/* @__PURE__ */ jsx5("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: props.label })
|
|
2920
|
+
]
|
|
2921
|
+
}
|
|
2922
|
+
),
|
|
2923
|
+
props.trailing ? /* @__PURE__ */ jsx5("div", { className: "relative z-10 shrink-0", children: props.trailing }) : null
|
|
2924
|
+
] });
|
|
2925
|
+
}
|
|
2926
|
+
function PickerAnimatedPage(props) {
|
|
2927
|
+
const reduceMotion = useReducedMotion();
|
|
2928
|
+
return /* @__PURE__ */ jsx5(
|
|
2929
|
+
motion4.div,
|
|
2930
|
+
{
|
|
2931
|
+
initial: reduceMotion ? false : { x: props.direction * 14, opacity: 0 },
|
|
2932
|
+
animate: { x: 0, opacity: 1 },
|
|
2933
|
+
transition: { duration: reduceMotion ? 0 : 0.18, ease: SLIDE_EASE },
|
|
2934
|
+
className: "w-full",
|
|
2935
|
+
children: props.children
|
|
2936
|
+
},
|
|
2937
|
+
props.pageKey
|
|
2938
|
+
);
|
|
2939
|
+
}
|
|
2940
|
+
function ModelPolicyPickerMenu(props) {
|
|
2941
|
+
const messages = useMemo5(
|
|
2942
|
+
() => ({ ...defaultModelPolicyPickerMessages, ...props.messages }),
|
|
2943
|
+
[props.messages]
|
|
2944
|
+
);
|
|
2945
|
+
const rows = effectiveRows(props);
|
|
2946
|
+
const groups = useMemo5(() => groupPickerRowsByBillingClass(rows), [rows]);
|
|
2947
|
+
const [localNav, setLocalNav] = usePickerNavState(
|
|
2948
|
+
props.nav === void 0 ? props.sessionKey : void 0,
|
|
2949
|
+
rows,
|
|
2950
|
+
props.model
|
|
2951
|
+
);
|
|
2952
|
+
const nav = props.nav ?? localNav;
|
|
2953
|
+
const setNav = props.onNavChange ?? setLocalNav;
|
|
2954
|
+
const [direction, setDirection] = useState6(1);
|
|
2955
|
+
const effectiveNav = nav.level === "providers" && groups.length === 1 ? { level: "models", rail: groups[0].billingClass, modelId: null } : nav;
|
|
2956
|
+
const activeGroup = effectiveNav.rail === null ? void 0 : groups.find((group) => group.billingClass === effectiveNav.rail);
|
|
2957
|
+
const focusModel = effectiveNav.modelId === null ? void 0 : findPickerRow(rows, effectiveNav.modelId);
|
|
2958
|
+
const selectedRow = findPickerRow(rows, props.model);
|
|
2959
|
+
const { latencyMode, loading, onLatencyModeChange } = props;
|
|
2960
|
+
useEffect5(() => {
|
|
2961
|
+
if (loading || !selectedRow?.selectable) return;
|
|
2962
|
+
const supportsCurrentMode = runnableLatencyModesForModel(selectedRow.catalog).includes(
|
|
2963
|
+
latencyMode
|
|
2964
|
+
);
|
|
2965
|
+
if (!supportsCurrentMode && latencyMode !== "standard") {
|
|
2966
|
+
onLatencyModeChange("standard");
|
|
2967
|
+
}
|
|
2968
|
+
}, [latencyMode, loading, onLatencyModeChange, selectedRow]);
|
|
2969
|
+
const go = (next, nextDirection) => {
|
|
2970
|
+
setDirection(nextDirection);
|
|
2971
|
+
setNav(next);
|
|
2972
|
+
};
|
|
2973
|
+
const selectEffort = (row, effort) => {
|
|
2974
|
+
if (!row.selectable) return;
|
|
2975
|
+
if (row.id !== props.model) props.onModelChange(row.id);
|
|
2976
|
+
props.onEffortChange(coerceReasoningEffortForModel(row.catalog, effort));
|
|
2977
|
+
};
|
|
2978
|
+
const pageKey = effectiveNav.level === "providers" ? "providers" : effectiveNav.level === "models" ? `models:${effectiveNav.rail ?? ""}` : `thinking:${effectiveNav.modelId ?? ""}`;
|
|
2979
|
+
let body;
|
|
2980
|
+
if (props.loading) {
|
|
2981
|
+
body = /* @__PURE__ */ jsx5("p", { className: "px-2 py-3 text-xs text-og-fg-subtle", children: messages.loading });
|
|
2982
|
+
} else if (groups.length === 0) {
|
|
2983
|
+
body = /* @__PURE__ */ jsx5("p", { className: "px-2 py-3 text-xs text-og-fg-subtle", children: messages.noModels });
|
|
2984
|
+
} else if (effectiveNav.level === "providers") {
|
|
2985
|
+
body = /* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-0.5", "data-testid": "model-picker-providers", children: groups.map((group) => /* @__PURE__ */ jsx5(
|
|
2986
|
+
PickerNavRow,
|
|
2987
|
+
{
|
|
2988
|
+
label: group.label,
|
|
2989
|
+
hint: messages.billingHints[group.billingClass],
|
|
2990
|
+
icon: /* @__PURE__ */ jsx5(BillingClassMark, { billingClass: group.billingClass }),
|
|
2991
|
+
active: selectedRow?.billingClass === group.billingClass,
|
|
2992
|
+
testId: `model-picker-rail-${group.billingClass}`,
|
|
2993
|
+
onClick: () => go({ level: "models", rail: group.billingClass, modelId: null }, 1)
|
|
2994
|
+
},
|
|
2995
|
+
group.billingClass
|
|
2996
|
+
)) });
|
|
2997
|
+
} else if (effectiveNav.level === "models" && activeGroup) {
|
|
2998
|
+
body = /* @__PURE__ */ jsxs5("div", { "data-testid": "model-picker-models", children: [
|
|
2999
|
+
groups.length > 1 ? /* @__PURE__ */ jsx5(
|
|
3000
|
+
PickerBackHeader,
|
|
3001
|
+
{
|
|
3002
|
+
label: activeGroup.label,
|
|
3003
|
+
icon: /* @__PURE__ */ jsx5(BillingClassMark, { billingClass: activeGroup.billingClass }),
|
|
3004
|
+
onBack: () => go({ level: "providers", rail: null, modelId: null }, -1)
|
|
3005
|
+
}
|
|
3006
|
+
) : null,
|
|
3007
|
+
/* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-0.5", children: activeGroup.rows.map((row) => /* @__PURE__ */ jsx5(
|
|
3008
|
+
PickerNavRow,
|
|
3009
|
+
{
|
|
3010
|
+
label: row.label,
|
|
3011
|
+
hint: row.unavailableReason ?? void 0,
|
|
3012
|
+
disabled: !row.selectable,
|
|
3013
|
+
title: row.unavailableReason ?? void 0,
|
|
3014
|
+
active: row.id === props.model,
|
|
3015
|
+
testId: `model-picker-choice-${row.id}`,
|
|
3016
|
+
onClick: () => {
|
|
3017
|
+
if (row.selectable) {
|
|
3018
|
+
go({ level: "thinking", rail: row.billingClass, modelId: row.id }, 1);
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
},
|
|
3022
|
+
`${row.billingClass}:${row.id}`
|
|
3023
|
+
)) })
|
|
3024
|
+
] });
|
|
3025
|
+
} else if (effectiveNav.level === "thinking" && focusModel) {
|
|
3026
|
+
const activeModel = focusModel.id === props.model;
|
|
3027
|
+
const supportsFast = runnableLatencyModesForModel(focusModel.catalog).includes("fast");
|
|
3028
|
+
body = /* @__PURE__ */ jsxs5("div", { "data-testid": "model-picker-reasoning", children: [
|
|
3029
|
+
/* @__PURE__ */ jsx5(
|
|
3030
|
+
PickerBackHeader,
|
|
3031
|
+
{
|
|
3032
|
+
label: focusModel.label,
|
|
3033
|
+
icon: /* @__PURE__ */ jsx5(BillingClassMark, { billingClass: focusModel.billingClass }),
|
|
3034
|
+
onBack: () => go({ level: "models", rail: focusModel.billingClass, modelId: null }, -1),
|
|
3035
|
+
trailing: supportsFast ? /* @__PURE__ */ jsx5(
|
|
3036
|
+
"button",
|
|
3037
|
+
{
|
|
3038
|
+
type: "button",
|
|
3039
|
+
disabled: !focusModel.selectable,
|
|
3040
|
+
"aria-pressed": activeModel && props.latencyMode === "fast",
|
|
3041
|
+
"aria-label": activeModel && props.latencyMode === "fast" ? `Disable ${messages.fast}` : `Enable ${messages.fast}`,
|
|
3042
|
+
title: `${messages.fast} \xB7 ${messages.fastRateHint}`,
|
|
3043
|
+
"data-testid": "model-picker-fast",
|
|
3044
|
+
onClick: () => {
|
|
3045
|
+
if (!activeModel) {
|
|
3046
|
+
props.onModelChange(focusModel.id);
|
|
3047
|
+
props.onEffortChange(
|
|
3048
|
+
coerceReasoningEffortForModel(focusModel.catalog, props.effort)
|
|
3049
|
+
);
|
|
3050
|
+
}
|
|
3051
|
+
props.onLatencyModeChange(
|
|
3052
|
+
activeModel && props.latencyMode === "fast" ? "standard" : "fast"
|
|
3053
|
+
);
|
|
3054
|
+
},
|
|
3055
|
+
className: cn(
|
|
3056
|
+
"flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-og-sm text-og-fg-subtle outline-none transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:cursor-not-allowed disabled:opacity-50",
|
|
3057
|
+
activeModel && props.latencyMode === "fast" && "text-og-fg"
|
|
3058
|
+
),
|
|
3059
|
+
children: /* @__PURE__ */ jsx5(
|
|
3060
|
+
ZapIcon,
|
|
3061
|
+
{
|
|
3062
|
+
className: cn(
|
|
3063
|
+
"size-3.5",
|
|
3064
|
+
activeModel && props.latencyMode === "fast" && "fill-current"
|
|
3065
|
+
)
|
|
3066
|
+
}
|
|
3067
|
+
)
|
|
3068
|
+
}
|
|
3069
|
+
) : null
|
|
3070
|
+
}
|
|
3071
|
+
),
|
|
3072
|
+
/* @__PURE__ */ jsx5("p", { className: "px-2.5 pt-1 pb-1 text-xs font-medium tracking-wide text-og-fg-subtle uppercase", children: messages.thinking }),
|
|
3073
|
+
/* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-0.5", children: effortOptionsForModel(focusModel.catalog).map((effort) => {
|
|
3074
|
+
const selected = activeModel && effort === props.effort;
|
|
3075
|
+
return /* @__PURE__ */ jsxs5(
|
|
3076
|
+
"button",
|
|
3077
|
+
{
|
|
3078
|
+
type: "button",
|
|
3079
|
+
disabled: !focusModel.selectable,
|
|
3080
|
+
onClick: () => selectEffort(focusModel, effort),
|
|
3081
|
+
className: cn(
|
|
3082
|
+
"flex h-8 w-full cursor-pointer items-center rounded-og-sm px-2.5 text-left text-sm text-og-fg outline-none transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:cursor-not-allowed disabled:opacity-50",
|
|
3083
|
+
selected && "bg-og-surface-2"
|
|
3084
|
+
),
|
|
3085
|
+
children: [
|
|
3086
|
+
/* @__PURE__ */ jsx5("span", { className: "min-w-0 flex-1 truncate", children: labelReasoningEffort(effort) }),
|
|
3087
|
+
selected ? /* @__PURE__ */ jsx5(
|
|
3088
|
+
CheckIcon,
|
|
3089
|
+
{
|
|
3090
|
+
className: "ml-auto size-3.5 shrink-0",
|
|
3091
|
+
"data-testid": "model-picker-effort-check"
|
|
3092
|
+
}
|
|
3093
|
+
) : null
|
|
3094
|
+
]
|
|
3095
|
+
},
|
|
3096
|
+
effort
|
|
3097
|
+
);
|
|
3098
|
+
}) })
|
|
3099
|
+
] });
|
|
3100
|
+
} else {
|
|
3101
|
+
body = /* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-0.5", "data-testid": "model-picker-providers", children: groups.map((group) => /* @__PURE__ */ jsx5(
|
|
3102
|
+
PickerNavRow,
|
|
3103
|
+
{
|
|
3104
|
+
label: group.label,
|
|
3105
|
+
hint: messages.billingHints[group.billingClass],
|
|
3106
|
+
icon: /* @__PURE__ */ jsx5(BillingClassMark, { billingClass: group.billingClass }),
|
|
3107
|
+
testId: `model-picker-rail-${group.billingClass}`,
|
|
3108
|
+
onClick: () => go({ level: "models", rail: group.billingClass, modelId: null }, 1)
|
|
3109
|
+
},
|
|
3110
|
+
group.billingClass
|
|
3111
|
+
)) });
|
|
3112
|
+
}
|
|
3113
|
+
return /* @__PURE__ */ jsxs5("div", { "data-testid": "model-picker-menu", className: "relative overflow-hidden", children: [
|
|
3114
|
+
props.error ? /* @__PURE__ */ jsx5("p", { className: "px-2 py-1 text-xs text-og-status-failed", role: "alert", children: props.error }) : null,
|
|
3115
|
+
/* @__PURE__ */ jsx5(PickerAnimatedPage, { pageKey, direction, children: body })
|
|
3116
|
+
] });
|
|
3117
|
+
}
|
|
3118
|
+
function ModelPolicyPicker(props) {
|
|
3119
|
+
const [open, setOpen] = useState6(false);
|
|
3120
|
+
const messages = useMemo5(
|
|
3121
|
+
() => ({ ...defaultModelPolicyPickerMessages, ...props.messages }),
|
|
3122
|
+
[props.messages]
|
|
3123
|
+
);
|
|
3124
|
+
const rows = effectiveRows(props);
|
|
3125
|
+
const [nav, setNav] = usePickerNavState(props.sessionKey, rows, props.model);
|
|
3126
|
+
const selected = findPickerRow(rows, props.model);
|
|
3127
|
+
if (props.loading) {
|
|
3128
|
+
return /* @__PURE__ */ jsx5(
|
|
3129
|
+
"span",
|
|
3130
|
+
{
|
|
3131
|
+
className: cn(
|
|
3132
|
+
"inline-flex h-8 w-40 shrink-0 animate-pulse rounded-full bg-og-surface-2",
|
|
3133
|
+
props.className
|
|
3134
|
+
),
|
|
3135
|
+
"aria-label": messages.loading,
|
|
3136
|
+
"data-testid": "model-picker-loading"
|
|
3137
|
+
}
|
|
3138
|
+
);
|
|
3139
|
+
}
|
|
3140
|
+
return /* @__PURE__ */ jsxs5(DropdownMenu.Root, { open, onOpenChange: setOpen, children: [
|
|
3141
|
+
/* @__PURE__ */ jsx5(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs5(
|
|
3142
|
+
"button",
|
|
3143
|
+
{
|
|
3144
|
+
type: "button",
|
|
3145
|
+
disabled: props.disabled,
|
|
3146
|
+
"aria-label": messages.label,
|
|
3147
|
+
className: cn(
|
|
3148
|
+
"inline-flex h-8 max-w-64 items-center gap-1 rounded-full border border-transparent px-2.5 text-xs text-og-fg-muted outline-none transition-colors hover:border-og-border hover:bg-og-surface-2 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:cursor-not-allowed disabled:opacity-50",
|
|
3149
|
+
props.className
|
|
3150
|
+
),
|
|
3151
|
+
children: [
|
|
3152
|
+
/* @__PURE__ */ jsx5(
|
|
3153
|
+
BillingClassMark,
|
|
3154
|
+
{
|
|
3155
|
+
billingClass: selected?.billingClass ?? (props.model.startsWith("codex/") ? "codex_subscription" : "opengeni_credits"),
|
|
3156
|
+
className: "text-og-fg"
|
|
3157
|
+
}
|
|
3158
|
+
),
|
|
3159
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate font-medium text-og-fg", children: selected?.label ?? props.model }),
|
|
3160
|
+
/* @__PURE__ */ jsx5("span", { children: labelReasoningEffort(props.effort) }),
|
|
3161
|
+
props.latencyMode === "fast" ? /* @__PURE__ */ jsx5(
|
|
3162
|
+
ZapIcon,
|
|
3163
|
+
{
|
|
3164
|
+
className: "size-3.5 shrink-0 text-og-fg",
|
|
3165
|
+
"aria-label": messages.fast,
|
|
3166
|
+
"data-testid": "model-picker-fast-icon"
|
|
3167
|
+
}
|
|
3168
|
+
) : null,
|
|
3169
|
+
/* @__PURE__ */ jsx5(ChevronDownIcon3, { className: "size-3 shrink-0" })
|
|
3170
|
+
]
|
|
3171
|
+
}
|
|
3172
|
+
) }),
|
|
3173
|
+
/* @__PURE__ */ jsx5(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx5(
|
|
3174
|
+
DropdownMenu.Content,
|
|
3175
|
+
{
|
|
3176
|
+
align: "start",
|
|
3177
|
+
side: props.menuSide ?? "bottom",
|
|
3178
|
+
sideOffset: 8,
|
|
3179
|
+
collisionPadding: 12,
|
|
3180
|
+
onCloseAutoFocus: (event) => event.preventDefault(),
|
|
3181
|
+
className: "z-50 flex max-h-[min(20rem,var(--radix-dropdown-menu-content-available-height))] w-72 max-w-[calc(100vw-16px)] flex-col overflow-hidden rounded-og-lg border border-og-border bg-og-surface-1 p-1.5 text-og-fg shadow-og-lg",
|
|
3182
|
+
children: /* @__PURE__ */ jsx5("div", { className: "min-h-0 flex-1 overflow-y-auto overscroll-contain", children: /* @__PURE__ */ jsx5(ModelPolicyPickerMenu, { ...props, nav, onNavChange: setNav }) })
|
|
3183
|
+
}
|
|
3184
|
+
) })
|
|
3185
|
+
] });
|
|
3186
|
+
}
|
|
3187
|
+
|
|
2773
3188
|
export {
|
|
2774
3189
|
INITIAL_TRANSCRIPTION_CONTROL_STATE,
|
|
2775
3190
|
transitionTranscriptionControl,
|
|
@@ -2809,6 +3224,13 @@ export {
|
|
|
2809
3224
|
SendButton,
|
|
2810
3225
|
Help,
|
|
2811
3226
|
Status,
|
|
2812
|
-
ComposerTranscriptionControl
|
|
3227
|
+
ComposerTranscriptionControl,
|
|
3228
|
+
defaultModelPolicyPickerMessages,
|
|
3229
|
+
BillingClassMark,
|
|
3230
|
+
PickerNavRow,
|
|
3231
|
+
PickerBackHeader,
|
|
3232
|
+
PickerAnimatedPage,
|
|
3233
|
+
ModelPolicyPickerMenu,
|
|
3234
|
+
ModelPolicyPicker
|
|
2813
3235
|
};
|
|
2814
|
-
//# sourceMappingURL=chunk-
|
|
3236
|
+
//# sourceMappingURL=chunk-IP22SLO6.js.map
|