diff --git a/site/src/pages/AISettingsPage/ModelsPage/components/ModelForm.stories.tsx b/site/src/pages/AISettingsPage/ModelsPage/components/ModelForm.stories.tsx index 4ee792c719..91b9de7462 100644 --- a/site/src/pages/AISettingsPage/ModelsPage/components/ModelForm.stories.tsx +++ b/site/src/pages/AISettingsPage/ModelsPage/components/ModelForm.stories.tsx @@ -218,18 +218,31 @@ export const EditUpdateDisabledUntilDirty: Story = { }, }; -export const ReasoningEffortVisibleWithoutExpanding: Story = { +export const ReasoningEffortInProviderConfiguration: Story = { + args: { + selectedProviderState: MockAnthropicProviderState, + }, play: async ({ canvasElement, args }) => { const canvas = within(canvasElement); - const defaultSelect = canvas.getByRole("combobox", { - name: /default reasoning effort/i, - }); + await userEvent.click( + canvas.getByRole("button", { name: /provider configuration/i }), + ); + const thinkingBudget = canvas.getByLabelText(/thinking budget tokens/i); const maxSelect = canvas.getByRole("combobox", { name: /max reasoning effort/i, }); - await expect(defaultSelect).toBeVisible(); + const defaultSelect = canvas.getByRole("combobox", { + name: /default reasoning effort/i, + }); await expect(maxSelect).toBeVisible(); + await expect(defaultSelect).toBeVisible(); + await expect(thinkingBudget.compareDocumentPosition(maxSelect)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); + await expect(maxSelect.compareDocumentPosition(defaultSelect)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); await expect(defaultSelect).toHaveTextContent("Not set"); await expect(maxSelect).toHaveTextContent("Not set"); @@ -271,6 +284,9 @@ export const ReasoningEffortVisibleWithoutExpanding: Story = { export const ReasoningEffortValidationError: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); + await userEvent.click( + canvas.getByRole("button", { name: /provider configuration/i }), + ); const defaultSelect = canvas.getByRole("combobox", { name: /default reasoning effort/i, }); diff --git a/site/src/pages/AISettingsPage/ModelsPage/components/ModelFormFields.tsx b/site/src/pages/AISettingsPage/ModelsPage/components/ModelFormFields.tsx index 9a36d6e421..cb464de7e8 100644 --- a/site/src/pages/AISettingsPage/ModelsPage/components/ModelFormFields.tsx +++ b/site/src/pages/AISettingsPage/ModelsPage/components/ModelFormFields.tsx @@ -240,12 +240,6 @@ export const ModelFormFields: FC<{ -
@@ -278,7 +272,14 @@ export const ModelFormFields: FC<{ form={form} fieldErrors={modelConfigFormBuildResult.fieldErrors} disabled={isSaving} - /> + > + + )} diff --git a/site/src/pages/AgentsPage/components/ChatModelAdminPanel/ModelConfigFields.tsx b/site/src/pages/AgentsPage/components/ChatModelAdminPanel/ModelConfigFields.tsx index ab4cc4d912..2e26deb12a 100644 --- a/site/src/pages/AgentsPage/components/ChatModelAdminPanel/ModelConfigFields.tsx +++ b/site/src/pages/AgentsPage/components/ChatModelAdminPanel/ModelConfigFields.tsx @@ -1,6 +1,6 @@ import { type FormikContextType, getIn } from "formik"; import { InfoIcon } from "lucide-react"; -import type { FC } from "react"; +import { type FC, Fragment, type ReactNode } from "react"; import { type FieldSchema, getVisibleGeneralFields, @@ -275,7 +275,10 @@ const SelectField: FC< > @@ -542,6 +545,7 @@ interface ModelConfigFieldsProps { form: FormikContextType; fieldErrors: ModelConfigFormBuildResult["fieldErrors"]; disabled: boolean; + children?: ReactNode; } /** @@ -556,6 +560,7 @@ export const ModelConfigFields: FC = ({ form, fieldErrors, disabled, + children, }) => { const normalized = normalizeProvider(provider); const resolved = resolveProvider(normalized); @@ -583,20 +588,25 @@ export const ModelConfigFields: FC = ({ const fieldKey = `config.${toFormFieldKey(resolved, field.json_name)}`; const errorKey = toFormFieldKey(resolved, field.json_name); return ( -
- -
+ +
+ +
+ {field.json_name === "thinking.budget_tokens" && children} +
); })} + {!sorted.some((field) => field.json_name === "thinking.budget_tokens") && + children}
); }; @@ -668,9 +678,9 @@ export const ReasoningEffortConfigFields: FC = ({ disabled, }) => { const ctx: FieldRenderContext = { form, fieldErrors, disabled }; - const fields = getVisibleGeneralFields().filter(({ json_name }) => - isReasoningEffortField(json_name), - ); + const fields = getVisibleGeneralFields() + .filter(({ json_name }) => isReasoningEffortField(json_name)) + .reverse(); return ( <>