Skip to content

Commit 79e0c06

Browse files
Merge branch 'main' into fix/duplicate-react-query-devtools
2 parents a2bbf59 + 565c289 commit 79e0c06

File tree

12 files changed

+260
-64
lines changed

12 files changed

+260
-64
lines changed

.github/actions/setup/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ runs:
1313

1414
- name: Cache dependencies
1515
id: cache
16-
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4
16+
uses: actions/cache@v4.2.2
1717
with:
1818
path: ./node_modules
1919
key: modules-${{ hashFiles('package-lock.json') }}

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## [0.18.1](https://github.com/stacklok/codegate-ui/compare/v0.18.0...v0.18.1) (2025-03-03)
4+
5+
6+
### Bug Fixes
7+
8+
* id separator for provider, model muxing rule ([#360](https://github.com/stacklok/codegate-ui/issues/360)) ([3cff061](https://github.com/stacklok/codegate-ui/commit/3cff0613a57f4c9c69add80f63d072238e797656))
9+
10+
## [0.18.0](https://github.com/stacklok/codegate-ui/compare/v0.17.0...v0.18.0) (2025-02-21)
11+
12+
13+
### Features
14+
15+
* support muxing fim and chat ([#343](https://github.com/stacklok/codegate-ui/issues/343)) ([14b1b2d](https://github.com/stacklok/codegate-ui/commit/14b1b2d470889957ca836de4a26a179fb6c56e5c))
16+
317
## [0.17.0](https://github.com/stacklok/codegate-ui/compare/v0.16.0...v0.17.0) (2025-02-20)
418

519

package-lock.json

Lines changed: 39 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vite-project",
33
"private": true,
4-
"version": "0.17.0",
4+
"version": "0.18.1",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",
@@ -31,7 +31,7 @@
3131
"@radix-ui/react-dialog": "^1.1.4",
3232
"@radix-ui/react-separator": "^1.1.0",
3333
"@radix-ui/react-slot": "^1.1.0",
34-
"@stacklok/ui-kit": "^1.0.1-4",
34+
"@stacklok/ui-kit": "^1.0.1-9",
3535
"@tanstack/react-query": "^5.64.1",
3636
"@tanstack/react-query-devtools": "^5.66.0",
3737
"@types/lodash": "^4.17.15",

src/api/generated/types.gen.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,23 @@ export type ModelByProvider = {
144144

145145
/**
146146
* Represents the different types of matchers we support.
147+
*
148+
* The 3 rules present match filenames and request types. They're used in conjunction with the
149+
* matcher field in the MuxRule model.
150+
* E.g.
151+
* - catch_all-> Always match
152+
* - filename_match and match: requests.py -> Match the request if the filename is requests.py
153+
* - fim_filename and match: main.py -> Match the request if the request type is fim
154+
* and the filename is main.py
155+
*
156+
* NOTE: Removing or updating fields from this enum will require a migration.
157+
* Adding new fields is safe.
147158
*/
148159
export enum MuxMatcherType {
149160
CATCH_ALL = 'catch_all',
150161
FILENAME_MATCH = 'filename_match',
151-
REQUEST_TYPE_MATCH = 'request_type_match',
162+
FIM_FILENAME = 'fim_filename',
163+
CHAT_FILENAME = 'chat_filename',
152164
}
153165

154166
/**

src/api/openapi.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,10 +1642,11 @@
16421642
"enum": [
16431643
"catch_all",
16441644
"filename_match",
1645-
"request_type_match"
1645+
"fim_filename",
1646+
"chat_filename"
16461647
],
16471648
"title": "MuxMatcherType",
1648-
"description": "Represents the different types of matchers we support."
1649+
"description": "Represents the different types of matchers we support.\n\nThe 3 rules present match filenames and request types. They're used in conjunction with the\nmatcher field in the MuxRule model.\nE.g.\n- catch_all-> Always match\n- filename_match and match: requests.py -> Match the request if the filename is requests.py\n- fim_filename and match: main.py -> Match the request if the request type is fim\nand the filename is main.py\n\nNOTE: Removing or updating fields from this enum will require a migration.\nAdding new fields is safe."
16491650
},
16501651
"MuxRule": {
16511652
"properties": {

src/features/providers/components/workspaces-by-provider.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ export function WorkspacesByProvider({
1010
if (workspaces.length === 0) return null
1111
return (
1212
<div className="mb-6 flex flex-col gap-1">
13-
<p>The following workspaces will be impacted by this action</p>
13+
<p>
14+
The following workspaces are currently using this provider and will need
15+
to be updated:
16+
</p>
1417
<div className="flex flex-wrap gap-1">
1518
{uniqBy(workspaces, 'name').map((item, index) => {
1619
return (

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

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ test('renders muxing model', async () => {
77
render(
88
<WorkspaceMuxingModel isArchived={false} workspaceName="fake-workspace" />
99
)
10+
11+
expect(
12+
screen.getByRole('button', {
13+
name: /all types/i,
14+
})
15+
).toBeVisible()
1016
expect(screen.getByText(/model muxing/i)).toBeVisible()
1117
expect(
1218
screen.getByText(
@@ -46,6 +52,11 @@ test('disabled muxing fields and buttons for archived workspace', async () => {
4652

4753
expect(await screen.findByRole('button', { name: /save/i })).toBeDisabled()
4854
expect(screen.getByTestId(/workspace-models-dropdown/i)).toBeDisabled()
55+
expect(
56+
screen.getByRole('button', {
57+
name: /all types/i,
58+
})
59+
).toBeDisabled()
4960
expect(
5061
await screen.findByRole('button', { name: /add filter/i })
5162
).toBeDisabled()
@@ -75,12 +86,27 @@ test('submit additional model overrides', async () => {
7586
name: /filter by/i,
7687
})
7788
expect(textFields.length).toEqual(2)
89+
90+
const requestTypeSelect = screen.getAllByRole('button', {
91+
name: /fim & chat/i,
92+
})[0]
93+
await userEvent.click(requestTypeSelect as HTMLFormElement)
94+
await userEvent.click(
95+
screen.getByRole('option', {
96+
name: 'FIM',
97+
})
98+
)
99+
expect(
100+
screen.getByRole('button', {
101+
name: 'FIM',
102+
})
103+
).toBeVisible()
78104
const modelsButton = await screen.findAllByTestId(
79105
/workspace-models-dropdown/i
80106
)
81107
expect(modelsButton.length).toEqual(2)
82108

83-
await userEvent.type(textFields[1] as HTMLFormElement, '.ts')
109+
await userEvent.type(textFields[0] as HTMLFormElement, '.tsx')
84110

85111
await userEvent.click(
86112
(await screen.findByRole('button', {
@@ -94,6 +120,37 @@ test('submit additional model overrides', async () => {
94120
})
95121
)
96122

123+
await userEvent.click(screen.getByRole('button', { name: /add filter/i }))
124+
await userEvent.click(
125+
screen.getAllByRole('button', {
126+
name: /chat/i,
127+
})[1] as HTMLFormElement
128+
)
129+
130+
await userEvent.click(
131+
screen.getByRole('option', {
132+
name: 'Chat',
133+
})
134+
)
135+
136+
await userEvent.type(
137+
screen.getAllByRole('textbox', {
138+
name: /filter by/i,
139+
})[1] as HTMLFormElement,
140+
'.ts'
141+
)
142+
143+
await userEvent.click(
144+
(await screen.findByRole('button', {
145+
name: /select a model/i,
146+
})) as HTMLFormElement
147+
)
148+
149+
await userEvent.click(
150+
screen.getByRole('option', {
151+
name: /chatgpt-4o/i,
152+
})
153+
)
97154
await userEvent.click(screen.getByRole('button', { name: /save/i }))
98155

99156
await waitFor(() => {

src/features/workspace/components/workspace-models-dropdown.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function groupModelsByProviderName(
3737
id: providerName,
3838
textValue: providerName,
3939
items: items.map((item) => ({
40-
id: `${item.provider_id}/${item.name}`,
40+
id: `${item.provider_id}@${item.name}`,
4141
textValue: item.name,
4242
})),
4343
}))
@@ -116,8 +116,10 @@ export function WorkspaceModelsDropdown({
116116
const selectedValue = v.values().next().value
117117
if (!selectedValue && typeof selectedValue !== 'string') return
118118
if (typeof selectedValue === 'string') {
119-
const [provider_id, modelName] = selectedValue.split('/')
120-
if (!provider_id || !modelName) return
119+
const atIndex = selectedValue.indexOf('@')
120+
const provider_id = selectedValue.slice(0, atIndex)
121+
const modelName = selectedValue.slice(atIndex + 1)
122+
if (atIndex === -1 && (!provider_id || !modelName)) return
121123
onChange({
122124
model: modelName,
123125
provider_id,

0 commit comments

Comments
 (0)