Skip to content

Commit 669468b

Browse files
committed
feat: set the default muxing rule as catch all
1 parent 29fa4bd commit 669468b

File tree

2 files changed

+60
-23
lines changed

2 files changed

+60
-23
lines changed

src/components/SortableArea.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,34 @@ type Props<T> = {
2222
children: (item: T, index: number) => React.ReactNode;
2323
setItems: (items: T[]) => void;
2424
items: T[];
25+
disableDragByIndex?: number;
2526
};
2627

2728
function ItemWrapper({
2829
children,
2930
id,
31+
disabledDrag,
3032
}: {
3133
children: React.ReactNode;
3234
id: UniqueIdentifier;
35+
disabledDrag: boolean;
3336
}) {
3437
const { attributes, listeners, setNodeRef, transform, transition } =
3538
useSortable({ id });
3639
const style = {
3740
transform: CSS.Transform.toString(transform),
3841
transition,
3942
};
43+
4044
return (
4145
<div style={style} className="flex items-center w-full">
42-
<div ref={setNodeRef} {...attributes} {...listeners} className="size-8">
43-
<Drag />
44-
</div>
46+
{disabledDrag ? (
47+
<div className="size-8" />
48+
) : (
49+
<div ref={setNodeRef} {...attributes} {...listeners} className="size-8">
50+
<Drag />
51+
</div>
52+
)}
4553
<div className="grow">{children}</div>
4654
</div>
4755
);
@@ -51,6 +59,7 @@ export function SortableArea<T extends { id: UniqueIdentifier }>({
5159
children,
5260
setItems,
5361
items,
62+
disableDragByIndex,
5463
}: Props<T>) {
5564
const sensors = useSensors(
5665
useSensor(PointerSensor),
@@ -82,7 +91,11 @@ export function SortableArea<T extends { id: UniqueIdentifier }>({
8291
>
8392
<SortableContext items={items} strategy={verticalListSortingStrategy}>
8493
{items.map((item, index) => (
85-
<ItemWrapper key={index} id={item.id}>
94+
<ItemWrapper
95+
key={index}
96+
id={item.id}
97+
disabledDrag={disableDragByIndex === index}
98+
>
8699
{children(item, index)}
87100
</ItemWrapper>
88101
))}

src/features/workspace/components/workspace-muxing-model.tsx

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import {
1111
LinkButton,
1212
Text,
1313
TextField,
14+
Tooltip,
15+
TooltipInfoButton,
16+
TooltipTrigger,
1417
} from "@stacklok/ui-kit";
1518
import { twMerge } from "tailwind-merge";
1619
import { useMutationPreferredModelWorkspace } from "../hooks/use-mutation-preferred-model-workspace";
@@ -59,6 +62,7 @@ type SortableItemProps = {
5962
models: V1ListAllModelsForAllProvidersResponse;
6063
isArchived: boolean;
6164
showRemoveButton: boolean;
65+
isDefaultRule: boolean;
6266
setRuleItem: (rule: PreferredMuxRule) => void;
6367
removeRule: (index: number) => void;
6468
};
@@ -71,21 +75,23 @@ function SortableItem({
7175
models,
7276
showRemoveButton,
7377
isArchived,
78+
isDefaultRule,
7479
}: SortableItemProps) {
80+
const placeholder = isDefaultRule ? "Catch All" : "eg file type, file name";
7581
return (
7682
<div className="flex items-center gap-2" key={rule.id}>
7783
<div className="flex w-full justify-between">
7884
<TextField
7985
aria-labelledby="filter-by-label-id"
8086
onFocus={(event) => event.preventDefault()}
8187
value={rule?.matcher ?? ""}
82-
isDisabled={isArchived}
88+
isDisabled={isArchived || isDefaultRule}
8389
name="matcher"
8490
onChange={(matcher) => {
8591
setRuleItem({ ...rule, matcher });
8692
}}
8793
>
88-
<Input placeholder="eg file type, file name" />
94+
<Input placeholder={placeholder} />
8995
</TextField>
9096
</div>
9197
<div className="flex w-3/5 gap-2">
@@ -97,7 +103,7 @@ function SortableItem({
97103
setRuleItem({ ...rule, provider_id, model })
98104
}
99105
/>
100-
{showRemoveButton && (
106+
{showRemoveButton && !isDefaultRule && (
101107
<Button
102108
aria-label="remove mux rule"
103109
isIcon
@@ -177,8 +183,8 @@ export function WorkspaceMuxingModel({
177183
<div className="flex flex-col justify-start">
178184
<Text className="text-primary">Model Muxing</Text>
179185
<Text className="flex items-center gap-1 text-secondary mb-0 text-balance">
180-
Filters will be applied in order (top to bottom), empty filters
181-
will apply to all.
186+
Select the model you would like to use in this workspace. This
187+
section applies only if you are using the MUX endpoint.
182188
<Link
183189
variant="primary"
184190
className="flex items-center gap-1 no-underline"
@@ -194,25 +200,43 @@ export function WorkspaceMuxingModel({
194200
<div className="flex gap-2">
195201
<div className="w-12">&nbsp;</div>
196202
<div className="w-full">
197-
<Label id="filter-by-label-id">Filter by</Label>
203+
<Label id="filter-by-label-id" className="flex items-center">
204+
Filter by
205+
<TooltipTrigger delay={0}>
206+
<TooltipInfoButton aria-label="Filter by description" />
207+
<Tooltip>
208+
Filters are applied in top-down order. The first rule that
209+
matches each prompt determines the chosen model. An empty
210+
filter applies to all prompts.
211+
</Tooltip>
212+
</TooltipTrigger>
213+
</Label>
198214
</div>
199215
<div className="w-3/5">
200216
<Label id="preferred-model-id">Preferred Model</Label>
201217
</div>
202218
</div>
203-
<SortableArea items={rules} setItems={setRules}>
204-
{(rule, index) => (
205-
<SortableItem
206-
key={rule.id}
207-
index={index}
208-
rule={rule}
209-
setRuleItem={setRuleItem}
210-
removeRule={removeRule}
211-
models={providerModels}
212-
showRemoveButton={showRemoveButton}
213-
isArchived={!!isArchived}
214-
/>
215-
)}
219+
<SortableArea
220+
items={rules}
221+
setItems={setRules}
222+
disableDragByIndex={rules.length - 1}
223+
>
224+
{(rule, index) => {
225+
const isDefaultRule = rules.length - 1 === index;
226+
return (
227+
<SortableItem
228+
key={rule.id}
229+
index={index}
230+
rule={rule}
231+
setRuleItem={setRuleItem}
232+
removeRule={removeRule}
233+
models={providerModels}
234+
showRemoveButton={showRemoveButton}
235+
isArchived={!!isArchived}
236+
isDefaultRule={isDefaultRule}
237+
/>
238+
);
239+
}}
216240
</SortableArea>
217241
</div>
218242
</CardBody>

0 commit comments

Comments
 (0)