@uipath/apollo-wind 2.55.0 → 2.57.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/dist/components/ui/combobox.cjs +33 -15
- package/dist/components/ui/combobox.js +33 -15
- package/dist/components/ui/date-picker.cjs +62 -26
- package/dist/components/ui/date-picker.js +62 -26
- package/dist/components/ui/datetime-picker.cjs +29 -12
- package/dist/components/ui/datetime-picker.js +29 -12
- package/dist/components/ui/dropdown-menu.cjs +12 -8
- package/dist/components/ui/dropdown-menu.js +12 -8
- package/dist/components/ui/field-actions/ai-assist-action.cjs +121 -0
- package/dist/components/ui/field-actions/ai-assist-action.d.ts +21 -0
- package/dist/components/ui/field-actions/ai-assist-action.js +84 -0
- package/dist/components/ui/field-actions/collapse.cjs +44 -0
- package/dist/components/ui/field-actions/collapse.d.ts +6 -0
- package/dist/components/ui/field-actions/collapse.js +4 -0
- package/dist/components/ui/field-actions/index.cjs +46 -0
- package/dist/components/ui/field-actions/index.d.ts +2 -0
- package/dist/components/ui/field-actions/index.js +3 -0
- package/dist/components/ui/field-actions/insert-variable-action.cjs +94 -0
- package/dist/components/ui/field-actions/insert-variable-action.d.ts +22 -0
- package/dist/components/ui/field-actions/insert-variable-action.js +57 -0
- package/dist/components/ui/field-addons/index.cjs +50 -0
- package/dist/components/ui/field-addons/index.d.ts +3 -0
- package/dist/components/ui/field-addons/index.js +4 -0
- package/dist/components/ui/field-addons/value-mode-indicator.cjs +57 -0
- package/dist/components/ui/field-addons/value-mode-indicator.d.ts +13 -0
- package/dist/components/ui/field-addons/value-mode-indicator.js +23 -0
- package/dist/components/ui/field-addons/value-mode-menu.cjs +149 -0
- package/dist/components/ui/field-addons/value-mode-menu.d.ts +69 -0
- package/dist/components/ui/field-addons/value-mode-menu.js +112 -0
- package/dist/components/ui/field-addons/value-mode-strings.cjs +69 -0
- package/dist/components/ui/field-addons/value-mode-strings.d.ts +32 -0
- package/dist/components/ui/field-addons/value-mode-strings.js +29 -0
- package/dist/components/ui/form-field.cjs +42 -5
- package/dist/components/ui/form-field.d.ts +21 -1
- package/dist/components/ui/form-field.js +36 -2
- package/dist/components/ui/index.cjs +156 -126
- package/dist/components/ui/index.d.ts +3 -0
- package/dist/components/ui/index.js +3 -0
- package/dist/components/ui/input-group-context.cjs +91 -0
- package/dist/components/ui/input-group-context.d.ts +69 -0
- package/dist/components/ui/input-group-context.js +42 -0
- package/dist/components/ui/input-group.cjs +303 -56
- package/dist/components/ui/input-group.d.ts +70 -3
- package/dist/components/ui/input-group.js +285 -56
- package/dist/components/ui/input.cjs +28 -17
- package/dist/components/ui/input.js +28 -17
- package/dist/components/ui/lockable-value-field/components/field-header.cjs +16 -114
- package/dist/components/ui/lockable-value-field/components/field-header.js +14 -112
- package/dist/components/ui/lockable-value-field/lockable-value-field.cjs +4 -12
- package/dist/components/ui/lockable-value-field/lockable-value-field.js +4 -12
- package/dist/components/ui/model-picker/ModelPicker.cjs +495 -0
- package/dist/components/ui/model-picker/ModelPicker.d.ts +304 -0
- package/dist/components/ui/model-picker/ModelPicker.js +451 -0
- package/dist/components/ui/model-picker/ModelTagChip.cjs +101 -0
- package/dist/components/ui/model-picker/ModelTagChip.d.ts +29 -0
- package/dist/components/ui/model-picker/ModelTagChip.js +67 -0
- package/dist/components/ui/model-picker/badges.cjs +52 -0
- package/dist/components/ui/model-picker/badges.d.ts +41 -0
- package/dist/components/ui/model-picker/badges.js +18 -0
- package/dist/components/ui/model-picker/index.cjs +117 -0
- package/dist/components/ui/model-picker/index.d.ts +27 -0
- package/dist/components/ui/model-picker/index.js +14 -0
- package/dist/components/ui/model-picker/labels.cjs +107 -0
- package/dist/components/ui/model-picker/labels.d.ts +81 -0
- package/dist/components/ui/model-picker/labels.js +67 -0
- package/dist/components/ui/model-picker/primitives/FolderSwitcher.cjs +108 -0
- package/dist/components/ui/model-picker/primitives/FolderSwitcher.d.ts +38 -0
- package/dist/components/ui/model-picker/primitives/FolderSwitcher.js +74 -0
- package/dist/components/ui/model-picker/primitives/GroupHeader.cjs +84 -0
- package/dist/components/ui/model-picker/primitives/GroupHeader.d.ts +64 -0
- package/dist/components/ui/model-picker/primitives/GroupHeader.js +50 -0
- package/dist/components/ui/model-picker/primitives/ModelOptionRow.cjs +178 -0
- package/dist/components/ui/model-picker/primitives/ModelOptionRow.d.ts +95 -0
- package/dist/components/ui/model-picker/primitives/ModelOptionRow.js +135 -0
- package/dist/components/ui/model-picker/primitives/OptionList.cjs +295 -0
- package/dist/components/ui/model-picker/primitives/OptionList.d.ts +87 -0
- package/dist/components/ui/model-picker/primitives/OptionList.js +242 -0
- package/dist/components/ui/{lockable-value-field/components/mode-menu-item.cjs → model-picker/primitives/PickerPopup.cjs} +25 -24
- package/dist/components/ui/model-picker/primitives/PickerPopup.d.ts +39 -0
- package/dist/components/ui/model-picker/primitives/PickerPopup.js +30 -0
- package/dist/components/ui/model-picker/primitives/PickerSearchInput.cjs +77 -0
- package/dist/components/ui/model-picker/primitives/PickerSearchInput.d.ts +43 -0
- package/dist/components/ui/model-picker/primitives/PickerSearchInput.js +43 -0
- package/dist/components/ui/model-picker/primitives/PickerTrigger.cjs +112 -0
- package/dist/components/ui/model-picker/primitives/PickerTrigger.d.ts +73 -0
- package/dist/components/ui/model-picker/primitives/PickerTrigger.js +78 -0
- package/dist/components/ui/model-picker/types.cjs +18 -0
- package/dist/components/ui/model-picker/types.d.ts +154 -0
- package/dist/components/ui/model-picker/types.js +0 -0
- package/dist/components/ui/model-picker/useModelPickerState.cjs +250 -0
- package/dist/components/ui/model-picker/useModelPickerState.d.ts +135 -0
- package/dist/components/ui/model-picker/useModelPickerState.js +216 -0
- package/dist/components/ui/model-picker/utils.cjs +327 -0
- package/dist/components/ui/model-picker/utils.d.ts +121 -0
- package/dist/components/ui/model-picker/utils.js +272 -0
- package/dist/components/ui/multi-select.cjs +82 -58
- package/dist/components/ui/multi-select.js +84 -60
- package/dist/components/ui/popover.cjs +13 -9
- package/dist/components/ui/popover.js +13 -9
- package/dist/components/ui/select.cjs +89 -27
- package/dist/components/ui/select.d.ts +4 -0
- package/dist/components/ui/select.js +90 -28
- package/dist/components/ui/textarea.cjs +16 -11
- package/dist/components/ui/textarea.js +16 -11
- package/dist/index.cjs +144 -21
- package/dist/index.d.ts +10 -4
- package/dist/index.js +6 -3
- package/dist/styles.css +350 -5
- package/package.json +2 -1
- package/dist/components/ui/lockable-value-field/components/mode-menu-item.d.ts +0 -9
- package/dist/components/ui/lockable-value-field/components/mode-menu-item.js +0 -29
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { ModelPickerLabels } from './labels';
|
|
2
|
+
import { type AnnotatedModel } from './primitives/OptionList';
|
|
3
|
+
import type { DiscoveryModel } from './types';
|
|
4
|
+
import { type GroupStrategy } from './utils';
|
|
5
|
+
export interface UseModelPickerStateOptions {
|
|
6
|
+
models: DiscoveryModel[];
|
|
7
|
+
value?: string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Connection id of the selected BYO model, when the host persists one.
|
|
10
|
+
* Disambiguates two BYO configurations that serve the same model name
|
|
11
|
+
* under different connections: `value` alone matches the first row,
|
|
12
|
+
* so the wrong one highlights. When provided, `matchesValue` also
|
|
13
|
+
* requires `byomDetails.integrationServiceConnectionId` to equal this.
|
|
14
|
+
* Omit for non-BYO selections.
|
|
15
|
+
*/
|
|
16
|
+
valueConnectionId?: string | null;
|
|
17
|
+
/**
|
|
18
|
+
* Selection callback. New shape: `(model)`. Legacy `(modelId, model)`
|
|
19
|
+
* callers can wrap at the call site — see `ModelPickerChangeHandler`
|
|
20
|
+
* in ModelPicker.tsx for the migration note.
|
|
21
|
+
*/
|
|
22
|
+
onChange?: (model: DiscoveryModel) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Initial grouping strategy. The hook stores this as internal state so
|
|
25
|
+
* consumers can let the user switch view (Category ⇆ Provider) without
|
|
26
|
+
* lifting the value into the host. Pass a fresh `groupBy` to reset.
|
|
27
|
+
*/
|
|
28
|
+
groupBy?: GroupStrategy;
|
|
29
|
+
/**
|
|
30
|
+
* Authoritative recommended/preview model IDs sourced from Model_hub
|
|
31
|
+
* configs in gitops-centralized-cluster. Passed through to
|
|
32
|
+
* `groupModels` so grouping aligns with chip rendering.
|
|
33
|
+
*/
|
|
34
|
+
recommendedModelIds?: readonly string[];
|
|
35
|
+
previewModelIds?: readonly string[];
|
|
36
|
+
/**
|
|
37
|
+
* Whether sections may collapse at all. A host that hides the group
|
|
38
|
+
* headers has removed the only visible expand control, so collapsing
|
|
39
|
+
* must be off too or rows can vanish with no way back. Default true;
|
|
40
|
+
* flat grouping disables it regardless.
|
|
41
|
+
*/
|
|
42
|
+
collapsibleGroups?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Optional per-product filter applied to the catalog *before* grouping
|
|
45
|
+
* and search. Runs once per `models` array via `useMemo`; pass a
|
|
46
|
+
* stable function reference if `models` is large.
|
|
47
|
+
*/
|
|
48
|
+
filter?: (model: DiscoveryModel) => boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Group keys to render as collapsed when the picker first mounts.
|
|
51
|
+
* The hook keeps the collapse map as internal state so the parent
|
|
52
|
+
* doesn't have to. A non-empty search query temporarily forces every
|
|
53
|
+
* group open so matches always show.
|
|
54
|
+
*/
|
|
55
|
+
initiallyCollapsedGroups?: readonly string[];
|
|
56
|
+
/**
|
|
57
|
+
* Translator instance. Forwarded to `groupModels` so group labels +
|
|
58
|
+
* hints render in the host's active locale. Omit only when the host
|
|
59
|
+
* supplies no translator (tests, isolated primitives).
|
|
60
|
+
*/
|
|
61
|
+
labels?: ModelPickerLabels;
|
|
62
|
+
}
|
|
63
|
+
export interface UseModelPickerStateResult {
|
|
64
|
+
open: boolean;
|
|
65
|
+
setOpen: (next: boolean) => void;
|
|
66
|
+
query: string;
|
|
67
|
+
setQuery: (next: string) => void;
|
|
68
|
+
/** Current grouping strategy. Initially seeded from `opts.groupBy`. */
|
|
69
|
+
groupBy: GroupStrategy;
|
|
70
|
+
setGroupBy: (next: GroupStrategy) => void;
|
|
71
|
+
/**
|
|
72
|
+
* `models` after the host's `filter` ran. Use this for downstream
|
|
73
|
+
* counts and side effects — `annotated`/`filtered` already include
|
|
74
|
+
* this filter, so most consumers won't need it.
|
|
75
|
+
*/
|
|
76
|
+
visibleModels: DiscoveryModel[];
|
|
77
|
+
/** All models, annotated with groupKey/groupLabel, sorted into group order. */
|
|
78
|
+
annotated: AnnotatedModel[];
|
|
79
|
+
/** annotated filtered by `query`. */
|
|
80
|
+
filtered: AnnotatedModel[];
|
|
81
|
+
/** Per-group counts (post-filter, pre-query). */
|
|
82
|
+
groupCounts: Record<string, number>;
|
|
83
|
+
/**
|
|
84
|
+
* Group keys currently collapsed. While `query` is non-empty every
|
|
85
|
+
* group is forced open (returns an empty set) so search results stay
|
|
86
|
+
* visible.
|
|
87
|
+
*/
|
|
88
|
+
collapsedGroups: ReadonlySet<string>;
|
|
89
|
+
/** Toggle the collapsed state of a single group. */
|
|
90
|
+
toggleGroup: (groupKey: string) => void;
|
|
91
|
+
/** The currently selected model, or null. */
|
|
92
|
+
selected: DiscoveryModel | null;
|
|
93
|
+
/**
|
|
94
|
+
* Raw `value` that couldn't be resolved against `models`. `null` when
|
|
95
|
+
* the selection resolved cleanly, when no `value` was passed, or
|
|
96
|
+
* while the catalog is still loading (empty `models`). Used by the
|
|
97
|
+
* trigger to render an explicit error-state fallback (raw id +
|
|
98
|
+
* red border) instead of silently dropping the value — which would
|
|
99
|
+
* look identical to "nothing selected" and risk accidental
|
|
100
|
+
* overwrites of a stored config.
|
|
101
|
+
*/
|
|
102
|
+
unknownValue: string | null;
|
|
103
|
+
activeIndex: number;
|
|
104
|
+
setActiveIndex: (i: number) => void;
|
|
105
|
+
/**
|
|
106
|
+
* False when the highlighted row is inside a collapsed section (or the
|
|
107
|
+
* list is empty). The combobox must not publish an active descendant
|
|
108
|
+
* that is not in the DOM.
|
|
109
|
+
*/
|
|
110
|
+
activeVisible: boolean;
|
|
111
|
+
/** Bind to the search input's onKeyDown. */
|
|
112
|
+
onSearchKeyDown: (e: React.KeyboardEvent) => void;
|
|
113
|
+
/** Programmatically pick a model. Closes the popup. */
|
|
114
|
+
choose: (m: DiscoveryModel) => void;
|
|
115
|
+
/** Stable id prefix unique to this picker instance. */
|
|
116
|
+
id: string;
|
|
117
|
+
/** Ref to attach to the trigger button so keyboard focus can return there. */
|
|
118
|
+
triggerRef: React.RefObject<HTMLButtonElement | null>;
|
|
119
|
+
/** Ref to attach to the search input. */
|
|
120
|
+
searchRef: React.RefObject<HTMLInputElement | null>;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Shared state controller for ModelPicker (and any custom picker a
|
|
124
|
+
* team builds on top of the primitives). Owns:
|
|
125
|
+
* - open/close state of the popup
|
|
126
|
+
* - search query + filtering
|
|
127
|
+
* - grouped + annotated option list
|
|
128
|
+
* - keyboard navigation index
|
|
129
|
+
* - collapsed-group bookkeeping
|
|
130
|
+
* - selection callback
|
|
131
|
+
*
|
|
132
|
+
* Consumers can use this hook directly to assemble their own picker from
|
|
133
|
+
* the exported primitives — see ModelPicker.tsx for the canonical example.
|
|
134
|
+
*/
|
|
135
|
+
export declare function useModelPickerState(opts: UseModelPickerStateOptions): UseModelPickerStateResult;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { isCollapsibleGroup } from "./primitives/OptionList.js";
|
|
3
|
+
import { filterModels, groupModels, isByoModel } from "./utils.js";
|
|
4
|
+
function useModelPickerState(opts) {
|
|
5
|
+
const { models, value, valueConnectionId, onChange, groupBy: initialGroupBy = "subscription", collapsibleGroups = true, recommendedModelIds, previewModelIds, filter, initiallyCollapsedGroups, labels } = opts;
|
|
6
|
+
const reactId = useId().replace(/[^A-Za-z0-9_-]/g, '');
|
|
7
|
+
const id = `apollo-model-picker-${reactId}`;
|
|
8
|
+
const triggerRef = useRef(null);
|
|
9
|
+
const searchRef = useRef(null);
|
|
10
|
+
const [open, setOpen] = useState(false);
|
|
11
|
+
const [query, setQuery] = useState('');
|
|
12
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
13
|
+
const [groupBy, setGroupBy] = useState(initialGroupBy);
|
|
14
|
+
const lastInitialGroupBy = useRef(initialGroupBy);
|
|
15
|
+
useEffect(()=>{
|
|
16
|
+
if (lastInitialGroupBy.current === initialGroupBy) return;
|
|
17
|
+
lastInitialGroupBy.current = initialGroupBy;
|
|
18
|
+
setGroupBy(initialGroupBy);
|
|
19
|
+
}, [
|
|
20
|
+
initialGroupBy
|
|
21
|
+
]);
|
|
22
|
+
const [collapsedSet, setCollapsedSet] = useState(()=>new Set(initiallyCollapsedGroups ?? []));
|
|
23
|
+
const visibleModels = useMemo(()=>filter ? models.filter(filter) : models, [
|
|
24
|
+
models,
|
|
25
|
+
filter
|
|
26
|
+
]);
|
|
27
|
+
const annotated = useMemo(()=>{
|
|
28
|
+
const groups = groupModels(visibleModels, groupBy, {
|
|
29
|
+
recommendedModelIds,
|
|
30
|
+
previewModelIds,
|
|
31
|
+
labels
|
|
32
|
+
});
|
|
33
|
+
return groups.flatMap((g)=>g.models.map((m)=>({
|
|
34
|
+
...m,
|
|
35
|
+
groupKey: g.key,
|
|
36
|
+
groupLabel: g.label
|
|
37
|
+
})));
|
|
38
|
+
}, [
|
|
39
|
+
visibleModels,
|
|
40
|
+
groupBy,
|
|
41
|
+
recommendedModelIds,
|
|
42
|
+
previewModelIds,
|
|
43
|
+
labels
|
|
44
|
+
]);
|
|
45
|
+
const filtered = useMemo(()=>filterModels(annotated, query), [
|
|
46
|
+
annotated,
|
|
47
|
+
query
|
|
48
|
+
]);
|
|
49
|
+
const groupCounts = useMemo(()=>{
|
|
50
|
+
const out = {};
|
|
51
|
+
for (const m of annotated)out[m.groupKey] = (out[m.groupKey] ?? 0) + 1;
|
|
52
|
+
return out;
|
|
53
|
+
}, [
|
|
54
|
+
annotated
|
|
55
|
+
]);
|
|
56
|
+
const matchesValue = useCallback((m)=>{
|
|
57
|
+
if (valueConnectionId) {
|
|
58
|
+
const connId = m.byomDetails?.integrationServiceConnectionId;
|
|
59
|
+
if (connId !== valueConnectionId) return false;
|
|
60
|
+
}
|
|
61
|
+
return m.modelId === value || m.modelName === value;
|
|
62
|
+
}, [
|
|
63
|
+
value,
|
|
64
|
+
valueConnectionId
|
|
65
|
+
]);
|
|
66
|
+
const pickMatch = useCallback((list)=>{
|
|
67
|
+
const hits = list.filter(matchesValue);
|
|
68
|
+
if (0 === hits.length) return null;
|
|
69
|
+
if (valueConnectionId) return hits[0] ?? null;
|
|
70
|
+
return hits.find((m)=>!isByoModel(m)) ?? hits[0] ?? null;
|
|
71
|
+
}, [
|
|
72
|
+
matchesValue,
|
|
73
|
+
valueConnectionId
|
|
74
|
+
]);
|
|
75
|
+
const selected = useMemo(()=>pickMatch(annotated) ?? pickMatch(models), [
|
|
76
|
+
annotated,
|
|
77
|
+
models,
|
|
78
|
+
pickMatch
|
|
79
|
+
]);
|
|
80
|
+
const unknownValue = useMemo(()=>{
|
|
81
|
+
if (!value) return null;
|
|
82
|
+
if (selected) return null;
|
|
83
|
+
if (0 === models.length) return null;
|
|
84
|
+
return value;
|
|
85
|
+
}, [
|
|
86
|
+
models,
|
|
87
|
+
selected,
|
|
88
|
+
value
|
|
89
|
+
]);
|
|
90
|
+
const canCollapse = collapsibleGroups && 'flat' !== groupBy && !query.trim();
|
|
91
|
+
const collapsedGroups = useMemo(()=>canCollapse ? collapsedSet : new Set(), [
|
|
92
|
+
canCollapse,
|
|
93
|
+
collapsedSet
|
|
94
|
+
]);
|
|
95
|
+
const toggleGroup = useCallback((groupKey)=>{
|
|
96
|
+
setCollapsedSet((prev)=>{
|
|
97
|
+
const next = new Set(prev);
|
|
98
|
+
if (next.has(groupKey)) next.delete(groupKey);
|
|
99
|
+
else next.add(groupKey);
|
|
100
|
+
return next;
|
|
101
|
+
});
|
|
102
|
+
}, []);
|
|
103
|
+
useEffect(()=>{
|
|
104
|
+
if (open) {
|
|
105
|
+
const sel = filtered.findIndex(matchesValue);
|
|
106
|
+
setActiveIndex(sel >= 0 ? sel : 0);
|
|
107
|
+
requestAnimationFrame(()=>searchRef.current?.focus());
|
|
108
|
+
} else setQuery('');
|
|
109
|
+
}, [
|
|
110
|
+
open
|
|
111
|
+
]);
|
|
112
|
+
const isHiddenAt = useCallback((i)=>{
|
|
113
|
+
const g = filtered[i]?.groupKey;
|
|
114
|
+
return void 0 !== g && isCollapsibleGroup(g) && collapsedGroups.has(g);
|
|
115
|
+
}, [
|
|
116
|
+
filtered,
|
|
117
|
+
collapsedGroups
|
|
118
|
+
]);
|
|
119
|
+
const isCollapsedStop = useCallback((i)=>isHiddenAt(i) && (0 === i || filtered[i - 1]?.groupKey !== filtered[i]?.groupKey), [
|
|
120
|
+
filtered,
|
|
121
|
+
isHiddenAt
|
|
122
|
+
]);
|
|
123
|
+
const nearestStop = useCallback((from, dir)=>{
|
|
124
|
+
for(let i = from; i >= 0 && i < filtered.length; i += dir)if (!isHiddenAt(i) || isCollapsedStop(i)) return i;
|
|
125
|
+
return -1;
|
|
126
|
+
}, [
|
|
127
|
+
filtered.length,
|
|
128
|
+
isHiddenAt,
|
|
129
|
+
isCollapsedStop
|
|
130
|
+
]);
|
|
131
|
+
useEffect(()=>{
|
|
132
|
+
if (activeIndex >= filtered.length) return void setActiveIndex(0);
|
|
133
|
+
if (!isHiddenAt(activeIndex) || isCollapsedStop(activeIndex)) return;
|
|
134
|
+
let i = activeIndex;
|
|
135
|
+
while(i > 0 && filtered[i - 1]?.groupKey === filtered[i]?.groupKey)i -= 1;
|
|
136
|
+
setActiveIndex(i);
|
|
137
|
+
}, [
|
|
138
|
+
filtered,
|
|
139
|
+
activeIndex,
|
|
140
|
+
isHiddenAt,
|
|
141
|
+
isCollapsedStop
|
|
142
|
+
]);
|
|
143
|
+
const activeVisible = filtered.length > 0 && !isHiddenAt(activeIndex);
|
|
144
|
+
const choose = useCallback((m)=>{
|
|
145
|
+
onChange?.(m);
|
|
146
|
+
setOpen(false);
|
|
147
|
+
triggerRef.current?.focus();
|
|
148
|
+
}, [
|
|
149
|
+
onChange
|
|
150
|
+
]);
|
|
151
|
+
const onSearchKeyDown = useCallback((e)=>{
|
|
152
|
+
if ('ArrowDown' === e.key) {
|
|
153
|
+
e.preventDefault();
|
|
154
|
+
setActiveIndex((i)=>{
|
|
155
|
+
const next = nearestStop(i + 1, 1);
|
|
156
|
+
return -1 === next ? i : next;
|
|
157
|
+
});
|
|
158
|
+
} else if ('ArrowUp' === e.key) {
|
|
159
|
+
e.preventDefault();
|
|
160
|
+
setActiveIndex((i)=>{
|
|
161
|
+
const prev = nearestStop(i - 1, -1);
|
|
162
|
+
return -1 === prev ? i : prev;
|
|
163
|
+
});
|
|
164
|
+
} else if ('Enter' === e.key) {
|
|
165
|
+
e.preventDefault();
|
|
166
|
+
const m = filtered[activeIndex];
|
|
167
|
+
if (m && !isHiddenAt(activeIndex)) choose(m);
|
|
168
|
+
} else if ('ArrowLeft' === e.key || 'ArrowRight' === e.key) {
|
|
169
|
+
const groupKey = filtered[activeIndex]?.groupKey;
|
|
170
|
+
if (!groupKey || !isCollapsibleGroup(groupKey) || !canCollapse) return;
|
|
171
|
+
const collapsed = collapsedGroups.has(groupKey);
|
|
172
|
+
if ('ArrowLeft' === e.key ? !collapsed : collapsed) {
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
toggleGroup(groupKey);
|
|
175
|
+
}
|
|
176
|
+
} else if ('Escape' === e.key) {
|
|
177
|
+
e.preventDefault();
|
|
178
|
+
setOpen(false);
|
|
179
|
+
triggerRef.current?.focus();
|
|
180
|
+
}
|
|
181
|
+
}, [
|
|
182
|
+
filtered,
|
|
183
|
+
activeIndex,
|
|
184
|
+
choose,
|
|
185
|
+
collapsedGroups,
|
|
186
|
+
canCollapse,
|
|
187
|
+
toggleGroup,
|
|
188
|
+
nearestStop,
|
|
189
|
+
isHiddenAt
|
|
190
|
+
]);
|
|
191
|
+
return {
|
|
192
|
+
open,
|
|
193
|
+
setOpen,
|
|
194
|
+
query,
|
|
195
|
+
setQuery,
|
|
196
|
+
groupBy,
|
|
197
|
+
setGroupBy,
|
|
198
|
+
visibleModels,
|
|
199
|
+
annotated,
|
|
200
|
+
filtered,
|
|
201
|
+
groupCounts,
|
|
202
|
+
collapsedGroups,
|
|
203
|
+
toggleGroup,
|
|
204
|
+
selected,
|
|
205
|
+
unknownValue,
|
|
206
|
+
activeIndex,
|
|
207
|
+
setActiveIndex,
|
|
208
|
+
onSearchKeyDown,
|
|
209
|
+
choose,
|
|
210
|
+
id,
|
|
211
|
+
triggerRef,
|
|
212
|
+
searchRef,
|
|
213
|
+
activeVisible
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
export { useModelPickerState };
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
resolveHomeGeography: ()=>resolveHomeGeography,
|
|
28
|
+
isTextGenerationModel: ()=>isTextGenerationModel,
|
|
29
|
+
getSubstitutionTarget: ()=>getSubstitutionTarget,
|
|
30
|
+
filterModels: ()=>filterModels,
|
|
31
|
+
deriveModelTags: ()=>deriveModelTags,
|
|
32
|
+
isByoModel: ()=>isByoModel,
|
|
33
|
+
groupModels: ()=>groupModels,
|
|
34
|
+
defaultCostTier: ()=>defaultCostTier
|
|
35
|
+
});
|
|
36
|
+
const external_badges_cjs_namespaceObject = require("./badges.cjs");
|
|
37
|
+
const external_labels_cjs_namespaceObject = require("./labels.cjs");
|
|
38
|
+
const RECOMMENDED_SUBSCRIPTION = 'UiPathOwned';
|
|
39
|
+
const isByoModel = (m)=>'BYOMAdded' === m.modelSubscriptionType || 'BYOMReplacedAlternative' === m.modelSubscriptionType || 'BYOMReplacedLikeForLike' === m.modelSubscriptionType || !!m.byomDetails || !!m.byoConnectionLabel;
|
|
40
|
+
function isTextGenerationModel(m) {
|
|
41
|
+
if ('Realtime' === m.modelType) return false;
|
|
42
|
+
return !(m.apiFlavor ?? '').includes('Embeddings');
|
|
43
|
+
}
|
|
44
|
+
const OMS_REGION_TO_GEOGRAPHY = {
|
|
45
|
+
europe: 'EU',
|
|
46
|
+
unitedstates: 'US',
|
|
47
|
+
japan: 'JA',
|
|
48
|
+
canada: 'CA',
|
|
49
|
+
australia: 'AU',
|
|
50
|
+
india: 'IN',
|
|
51
|
+
unitedkingdom: 'UK',
|
|
52
|
+
singapore: 'SI',
|
|
53
|
+
switzerland: 'CH',
|
|
54
|
+
unitedarabemirates: 'UAE',
|
|
55
|
+
southkorea: 'SK'
|
|
56
|
+
};
|
|
57
|
+
const GEOGRAPHY_CODES = new Set([
|
|
58
|
+
'EU',
|
|
59
|
+
'CA',
|
|
60
|
+
'US',
|
|
61
|
+
'SI',
|
|
62
|
+
'JA',
|
|
63
|
+
'AU',
|
|
64
|
+
'IN',
|
|
65
|
+
'UK',
|
|
66
|
+
'CH',
|
|
67
|
+
'UAE',
|
|
68
|
+
'SK',
|
|
69
|
+
'GLOBAL'
|
|
70
|
+
]);
|
|
71
|
+
function resolveHomeGeography(homeRegion) {
|
|
72
|
+
const raw = homeRegion?.trim();
|
|
73
|
+
if (!raw) return;
|
|
74
|
+
const upper = raw.toUpperCase();
|
|
75
|
+
if ('GLOBAL' === upper) return;
|
|
76
|
+
if (GEOGRAPHY_CODES.has(upper)) return upper;
|
|
77
|
+
return OMS_REGION_TO_GEOGRAPHY[raw.toLowerCase().replace(/[\s_-]/g, '')];
|
|
78
|
+
}
|
|
79
|
+
function listMatchesModel(ids, model) {
|
|
80
|
+
return ids.includes(model.modelId) || ids.includes(model.modelName);
|
|
81
|
+
}
|
|
82
|
+
function deriveModelTags(model, context = {}) {
|
|
83
|
+
const tags = [];
|
|
84
|
+
const labels = context.labels ?? external_labels_cjs_namespaceObject.DEFAULT_MODEL_PICKER_LABELS;
|
|
85
|
+
const isByo = isByoModel(model);
|
|
86
|
+
const isRecommended = void 0 !== context.recommendedModelIds ? listMatchesModel(context.recommendedModelIds, model) : model.isRecommended ?? (model.modelSubscriptionType === RECOMMENDED_SUBSCRIPTION && !model.isPreview && !model.deprecationDetails?.usageEndDate);
|
|
87
|
+
if (isRecommended) tags.push({
|
|
88
|
+
kind: 'recommended',
|
|
89
|
+
label: labels.recommendedTag,
|
|
90
|
+
tooltip: labels.recommendedTagTooltip
|
|
91
|
+
});
|
|
92
|
+
const isPreview = void 0 !== context.previewModelIds ? listMatchesModel(context.previewModelIds, model) : !!model.isPreview;
|
|
93
|
+
if (!isByo && isPreview) tags.push({
|
|
94
|
+
kind: 'preview',
|
|
95
|
+
label: labels.previewTag
|
|
96
|
+
});
|
|
97
|
+
const substitutionTarget = getSubstitutionTarget(model);
|
|
98
|
+
if (substitutionTarget) tags.push({
|
|
99
|
+
kind: 'substituted',
|
|
100
|
+
label: labels.substitutedTag(substitutionTarget),
|
|
101
|
+
tooltip: labels.substitutedTagTooltip(substitutionTarget)
|
|
102
|
+
});
|
|
103
|
+
else if (model.deprecationDetails?.usageEndDate) {
|
|
104
|
+
const date = formatDate(model.deprecationDetails.usageEndDate);
|
|
105
|
+
tags.push({
|
|
106
|
+
kind: 'deprecating',
|
|
107
|
+
label: labels.deprecatingTag(date),
|
|
108
|
+
tooltip: model.deprecationDetails.replacedBy ? labels.deprecatingTagTooltip(model.deprecationDetails.replacedBy) : void 0
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (isByo) tags.push({
|
|
112
|
+
kind: 'custom',
|
|
113
|
+
label: labels.customTag
|
|
114
|
+
});
|
|
115
|
+
if (!isByo) {
|
|
116
|
+
const geo = model.routingDetails?.geography;
|
|
117
|
+
const home = 'GLOBAL' === context.homeRegion ? void 0 : context.homeRegion;
|
|
118
|
+
if (geo && home && 'GLOBAL' !== geo && geo !== home) tags.push({
|
|
119
|
+
kind: 'out-of-region',
|
|
120
|
+
label: labels.outOfRegionTag(geo),
|
|
121
|
+
tooltip: labels.outOfRegionTagTooltip(home)
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const poolBadges = context.badgesFor?.(model) ?? (()=>{
|
|
125
|
+
const tier = defaultCostTier(model);
|
|
126
|
+
return tier ? [
|
|
127
|
+
`cost-${tier}`
|
|
128
|
+
] : [];
|
|
129
|
+
})();
|
|
130
|
+
for (const kind of poolBadges){
|
|
131
|
+
const def = external_badges_cjs_namespaceObject.MODEL_BADGES[kind];
|
|
132
|
+
if (def) tags.push({
|
|
133
|
+
kind,
|
|
134
|
+
label: labels[def.label],
|
|
135
|
+
tooltip: def.tooltip ? labels[def.tooltip] : void 0,
|
|
136
|
+
variant: def.variant
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
if (context.customTagsFor) {
|
|
140
|
+
const extra = context.customTagsFor(model);
|
|
141
|
+
if (extra?.length) tags.push(...extra);
|
|
142
|
+
}
|
|
143
|
+
return tags;
|
|
144
|
+
}
|
|
145
|
+
const DEFAULT_BASIC_THRESHOLD = 100;
|
|
146
|
+
const DEFAULT_PREMIUM_THRESHOLD = 500;
|
|
147
|
+
function defaultCostTier(model) {
|
|
148
|
+
const costDetails = model.modelDetails?.costDetails;
|
|
149
|
+
const inputCost = costDetails?.flatCosts?.inputTokenCost ?? costDetails?.tieredCosts?.[0]?.inputTokenCost;
|
|
150
|
+
if (null == inputCost) return null;
|
|
151
|
+
if (inputCost < DEFAULT_BASIC_THRESHOLD) return 'basic';
|
|
152
|
+
if (inputCost < DEFAULT_PREMIUM_THRESHOLD) return 'standard';
|
|
153
|
+
return 'premium';
|
|
154
|
+
}
|
|
155
|
+
function getSubstitutionTarget(model) {
|
|
156
|
+
const effective = model.effectiveModel;
|
|
157
|
+
if (effective && effective !== model.modelName && effective !== model.modelId) return model.deprecationDetails?.replacedBy ?? effective;
|
|
158
|
+
const routed = model.routingDetails?.model;
|
|
159
|
+
if (routed && routed !== model.modelName && routed !== model.modelId) return model.deprecationDetails?.replacedBy ?? routed;
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const VENDOR_LABELS = {
|
|
163
|
+
AnthropicClaude: 'Anthropic',
|
|
164
|
+
OpenAi: 'OpenAI',
|
|
165
|
+
AzureOpenAi: 'Azure OpenAI',
|
|
166
|
+
VertexAi: 'Google Vertex',
|
|
167
|
+
AwsBedrock: 'AWS Bedrock'
|
|
168
|
+
};
|
|
169
|
+
function vendorLabel(vendor) {
|
|
170
|
+
return VENDOR_LABELS[vendor] ?? vendor;
|
|
171
|
+
}
|
|
172
|
+
function formatDate(iso) {
|
|
173
|
+
const date = new Date(iso);
|
|
174
|
+
if (Number.isNaN(date.getTime())) return iso;
|
|
175
|
+
const dateOnly = /^\d{4}-\d{2}-\d{2}$/.test(iso);
|
|
176
|
+
return date.toLocaleDateString(void 0, {
|
|
177
|
+
month: 'short',
|
|
178
|
+
year: 'numeric',
|
|
179
|
+
...dateOnly ? {
|
|
180
|
+
timeZone: 'UTC'
|
|
181
|
+
} : {}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function buildSubscriptionMatchers(ctx) {
|
|
185
|
+
const isRecommended = (m)=>void 0 !== ctx.recommendedModelIds ? listMatchesModel(ctx.recommendedModelIds, m) : m.isRecommended ?? (m.modelSubscriptionType === RECOMMENDED_SUBSCRIPTION && !m.isPreview && !m.deprecationDetails?.usageEndDate);
|
|
186
|
+
const isPreview = (m)=>void 0 !== ctx.previewModelIds ? listMatchesModel(ctx.previewModelIds, m) : !!m.isPreview;
|
|
187
|
+
const labels = ctx.labels ?? external_labels_cjs_namespaceObject.DEFAULT_MODEL_PICKER_LABELS;
|
|
188
|
+
return [
|
|
189
|
+
{
|
|
190
|
+
key: 'byo',
|
|
191
|
+
label: labels.byoGroup,
|
|
192
|
+
hint: labels.byoGroupHint,
|
|
193
|
+
match: (m)=>isByoModel(m)
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
key: 'recommended',
|
|
197
|
+
label: labels.recommendedGroup,
|
|
198
|
+
hint: labels.recommendedGroupHint,
|
|
199
|
+
match: (m)=>isRecommended(m) && !m.deprecationDetails?.usageEndDate
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
key: 'preview',
|
|
203
|
+
label: labels.previewGroup,
|
|
204
|
+
hint: labels.previewGroupHint,
|
|
205
|
+
match: (m)=>isPreview(m) && !isByoModel(m) && !m.deprecationDetails?.usageEndDate
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
key: 'more',
|
|
209
|
+
label: labels.moreGroup,
|
|
210
|
+
hint: labels.moreGroupHint,
|
|
211
|
+
match: (m)=>!isByoModel(m) && !m.deprecationDetails?.usageEndDate
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
key: 'deprecating',
|
|
215
|
+
label: labels.deprecatingGroup,
|
|
216
|
+
hint: labels.deprecatingGroupHint,
|
|
217
|
+
match: (m)=>!!m.deprecationDetails?.usageEndDate
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
key: 'shared',
|
|
221
|
+
label: labels.otherGroup,
|
|
222
|
+
match: ()=>true
|
|
223
|
+
}
|
|
224
|
+
];
|
|
225
|
+
}
|
|
226
|
+
function groupModels(models, strategy = "subscription", context = {}) {
|
|
227
|
+
const labels = context.labels ?? external_labels_cjs_namespaceObject.DEFAULT_MODEL_PICKER_LABELS;
|
|
228
|
+
if ('flat' === strategy) return [
|
|
229
|
+
{
|
|
230
|
+
key: 'all',
|
|
231
|
+
label: labels.allModelsGroup,
|
|
232
|
+
models
|
|
233
|
+
}
|
|
234
|
+
];
|
|
235
|
+
if ('vendor' === strategy) {
|
|
236
|
+
const byVendor = new Map();
|
|
237
|
+
const byo = [];
|
|
238
|
+
for (const m of models){
|
|
239
|
+
if (isByoModel(m)) {
|
|
240
|
+
byo.push(m);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
const k = m.vendor || 'Other';
|
|
244
|
+
if (!byVendor.has(k)) byVendor.set(k, []);
|
|
245
|
+
byVendor.get(k).push(m);
|
|
246
|
+
}
|
|
247
|
+
const groups = [];
|
|
248
|
+
if (byo.length) groups.push({
|
|
249
|
+
key: 'byo',
|
|
250
|
+
label: labels.byoGroup,
|
|
251
|
+
models: byo
|
|
252
|
+
});
|
|
253
|
+
const matchers = buildSubscriptionMatchers(context);
|
|
254
|
+
const ranks = new Map();
|
|
255
|
+
const lifecycleRank = (m)=>{
|
|
256
|
+
let r = ranks.get(m);
|
|
257
|
+
if (void 0 === r) {
|
|
258
|
+
const i = matchers.findIndex((g)=>g.match(m));
|
|
259
|
+
r = -1 === i ? matchers.length : i;
|
|
260
|
+
ranks.set(m, r);
|
|
261
|
+
}
|
|
262
|
+
return r;
|
|
263
|
+
};
|
|
264
|
+
for (const [key, list] of byVendor.entries())groups.push({
|
|
265
|
+
key,
|
|
266
|
+
label: vendorLabel(key),
|
|
267
|
+
models: list.sort((a, b)=>lifecycleRank(a) - lifecycleRank(b))
|
|
268
|
+
});
|
|
269
|
+
return groups;
|
|
270
|
+
}
|
|
271
|
+
const matchers = buildSubscriptionMatchers(context);
|
|
272
|
+
const buckets = {};
|
|
273
|
+
for (const m of models){
|
|
274
|
+
const bucket = matchers.find((g)=>g.match(m));
|
|
275
|
+
if (!bucket) continue;
|
|
276
|
+
const list = buckets[bucket.key] ?? (buckets[bucket.key] = []);
|
|
277
|
+
list.push(m);
|
|
278
|
+
}
|
|
279
|
+
const out = [];
|
|
280
|
+
for (const g of matchers){
|
|
281
|
+
const list = buckets[g.key];
|
|
282
|
+
if (list?.length) out.push({
|
|
283
|
+
key: g.key,
|
|
284
|
+
label: g.label,
|
|
285
|
+
hint: g.hint,
|
|
286
|
+
models: list
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
return out;
|
|
290
|
+
}
|
|
291
|
+
function filterModels(models, query) {
|
|
292
|
+
const q = query.trim().toLowerCase();
|
|
293
|
+
if (!q) return models;
|
|
294
|
+
return models.filter((m)=>{
|
|
295
|
+
const haystack = [
|
|
296
|
+
m.modelName,
|
|
297
|
+
m.displayName,
|
|
298
|
+
m.modelId,
|
|
299
|
+
m.vendor,
|
|
300
|
+
m.modelFamily,
|
|
301
|
+
m.effectiveModel,
|
|
302
|
+
m.byoConnectionLabel
|
|
303
|
+
].filter(Boolean).join(' ').toLowerCase();
|
|
304
|
+
return haystack.includes(q);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
exports.defaultCostTier = __webpack_exports__.defaultCostTier;
|
|
308
|
+
exports.deriveModelTags = __webpack_exports__.deriveModelTags;
|
|
309
|
+
exports.filterModels = __webpack_exports__.filterModels;
|
|
310
|
+
exports.getSubstitutionTarget = __webpack_exports__.getSubstitutionTarget;
|
|
311
|
+
exports.groupModels = __webpack_exports__.groupModels;
|
|
312
|
+
exports.isByoModel = __webpack_exports__.isByoModel;
|
|
313
|
+
exports.isTextGenerationModel = __webpack_exports__.isTextGenerationModel;
|
|
314
|
+
exports.resolveHomeGeography = __webpack_exports__.resolveHomeGeography;
|
|
315
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
316
|
+
"defaultCostTier",
|
|
317
|
+
"deriveModelTags",
|
|
318
|
+
"filterModels",
|
|
319
|
+
"getSubstitutionTarget",
|
|
320
|
+
"groupModels",
|
|
321
|
+
"isByoModel",
|
|
322
|
+
"isTextGenerationModel",
|
|
323
|
+
"resolveHomeGeography"
|
|
324
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
325
|
+
Object.defineProperty(exports, '__esModule', {
|
|
326
|
+
value: true
|
|
327
|
+
});
|