mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(site): move thinking settings to provider configuration (#27287)
This commit is contained in:
@@ -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,
|
||||
});
|
||||
|
||||
@@ -240,12 +240,6 @@ export const ModelFormFields: FC<{
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</div>
|
||||
<ReasoningEffortConfigFields
|
||||
provider={selectedProviderState.provider}
|
||||
form={form}
|
||||
fieldErrors={modelConfigFormBuildResult.fieldErrors}
|
||||
disabled={isSaving}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="overflow-hidden rounded-lg border border-solid border-border">
|
||||
@@ -278,7 +272,14 @@ export const ModelFormFields: FC<{
|
||||
form={form}
|
||||
fieldErrors={modelConfigFormBuildResult.fieldErrors}
|
||||
disabled={isSaving}
|
||||
/>
|
||||
>
|
||||
<ReasoningEffortConfigFields
|
||||
provider={selectedProviderState.provider}
|
||||
form={form}
|
||||
fieldErrors={modelConfigFormBuildResult.fieldErrors}
|
||||
disabled={isSaving}
|
||||
/>
|
||||
</ModelConfigFields>
|
||||
</CollapsibleSection>
|
||||
)}
|
||||
|
||||
|
||||
@@ -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<
|
||||
>
|
||||
<SelectTrigger
|
||||
id={fieldKey}
|
||||
className={cn("min-w-0", fieldError && "border-content-destructive")}
|
||||
className={cn(
|
||||
"min-w-0 shadow-none",
|
||||
fieldError && "border-content-destructive",
|
||||
)}
|
||||
aria-invalid={Boolean(fieldError)}
|
||||
aria-describedby={fieldError ? errorId : undefined}
|
||||
>
|
||||
@@ -542,6 +545,7 @@ interface ModelConfigFieldsProps {
|
||||
form: FormikContextType<ModelFormValues>;
|
||||
fieldErrors: ModelConfigFormBuildResult["fieldErrors"];
|
||||
disabled: boolean;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -556,6 +560,7 @@ export const ModelConfigFields: FC<ModelConfigFieldsProps> = ({
|
||||
form,
|
||||
fieldErrors,
|
||||
disabled,
|
||||
children,
|
||||
}) => {
|
||||
const normalized = normalizeProvider(provider);
|
||||
const resolved = resolveProvider(normalized);
|
||||
@@ -583,20 +588,25 @@ export const ModelConfigFields: FC<ModelConfigFieldsProps> = ({
|
||||
const fieldKey = `config.${toFormFieldKey(resolved, field.json_name)}`;
|
||||
const errorKey = toFormFieldKey(resolved, field.json_name);
|
||||
return (
|
||||
<div key={fieldKey} className={colSpanClass[colSpan(field)]}>
|
||||
<SchemaField
|
||||
field={field}
|
||||
fieldKey={fieldKey}
|
||||
errorKey={errorKey}
|
||||
form={form}
|
||||
fieldErrors={fieldErrors}
|
||||
disabled={
|
||||
disabled || isFieldConflictDisabled(field, fieldValueByName)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Fragment key={fieldKey}>
|
||||
<div className={colSpanClass[colSpan(field)]}>
|
||||
<SchemaField
|
||||
field={field}
|
||||
fieldKey={fieldKey}
|
||||
errorKey={errorKey}
|
||||
form={form}
|
||||
fieldErrors={fieldErrors}
|
||||
disabled={
|
||||
disabled || isFieldConflictDisabled(field, fieldValueByName)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
{field.json_name === "thinking.budget_tokens" && children}
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
{!sorted.some((field) => field.json_name === "thinking.budget_tokens") &&
|
||||
children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -668,9 +678,9 @@ export const ReasoningEffortConfigFields: FC<ModelConfigFieldsProps> = ({
|
||||
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 (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user