diff --git a/web/app/components/base/features/new-feature-panel/__tests__/follow-up-setting-modal.spec.tsx b/web/app/components/base/features/new-feature-panel/__tests__/follow-up-setting-modal.spec.tsx index e975ff2a5b5..99268826c01 100644 --- a/web/app/components/base/features/new-feature-panel/__tests__/follow-up-setting-modal.spec.tsx +++ b/web/app/components/base/features/new-feature-panel/__tests__/follow-up-setting-modal.spec.tsx @@ -1,4 +1,6 @@ import type { SuggestedQuestionsAfterAnswer } from '@/app/components/base/features/types' +import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations' +import type { CompletionParams } from '@/types/app' import { fireEvent, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import FollowUpSettingModal from '../follow-up-setting-modal' @@ -17,9 +19,36 @@ vi.mock('@/app/components/header/account-setting/model-provider-page/hooks', () vi.mock( '@/app/components/header/account-setting/model-provider-page/model-parameter-modal', () => ({ - default: ({ provider, modelId }: { provider: string; modelId: string }) => ( -
{`${provider}:${modelId}`}
- ), + default: ({ + provider, + modelId, + completionParams, + onCompletionParamsChange, + }: { + provider: string + modelId: string + completionParams: FormValue + onCompletionParamsChange: (newParams: FormValue) => void + }) => { + const hasMaxTokens = 'max_tokens' in completionParams + + return ( +
+ {`${provider}:${modelId}`} + +
+ ) + }, }), ) @@ -40,6 +69,54 @@ describe('FollowUpSettingModal', () => { vi.clearAllMocks() }) + // Covers optional model parameters staying disabled across edits and subsequent opens. + describe('Model Parameters', () => { + it('should keep max tokens disabled after its switch is turned off', async () => { + const user = userEvent.setup() + renderModal({ + enabled: true, + model: { + provider: 'openai', + name: 'gpt-4o-mini', + mode: 'chat', + completion_params: { + temperature: 0.7, + max_tokens: 0, + top_p: 0, + echo: false, + stop: [], + presence_penalty: 0, + frequency_penalty: 0, + }, + }, + }) + + const maxTokensSwitch = screen.getByRole('switch', { name: 'Max Tokens' }) + await user.click(maxTokensSwitch) + + expect(maxTokensSwitch).toHaveAttribute('aria-checked', 'false') + }) + + it('should keep max tokens disabled when saved model parameters omit it', () => { + renderModal({ + enabled: true, + model: { + provider: 'openai', + name: 'gpt-4o-mini', + mode: 'chat', + completion_params: { + temperature: 0.7, + } as CompletionParams, + }, + }) + + expect(screen.getByRole('switch', { name: 'Max Tokens' })).toHaveAttribute( + 'aria-checked', + 'false', + ) + }) + }) + describe('Default Prompt', () => { it('should show the system default prompt and save without a custom prompt when no custom prompt is configured', async () => { const user = userEvent.setup() diff --git a/web/app/components/base/features/new-feature-panel/follow-up-setting-modal.tsx b/web/app/components/base/features/new-feature-panel/follow-up-setting-modal.tsx index 529eb42f805..b67b753c6f1 100644 --- a/web/app/components/base/features/new-feature-panel/follow-up-setting-modal.tsx +++ b/web/app/components/base/features/new-feature-panel/follow-up-setting-modal.tsx @@ -40,8 +40,7 @@ const getInitialModel = (model?: Model): Model => ({ name: model?.name || '', mode: model?.mode || ModelModeTypeEnum.chat, completion_params: { - ...DEFAULT_COMPLETION_PARAMS, - ...(model?.completion_params || {}), + ...(model?.completion_params ?? DEFAULT_COMPLETION_PARAMS), }, }) @@ -90,10 +89,7 @@ const FollowUpSettingModal = ({ data, onSave, onCancel }: FollowUpSettingModalPr (newParams: FormValue) => { setModel({ ...selectedModel, - completion_params: { - ...DEFAULT_COMPLETION_PARAMS, - ...(newParams as Partial), - }, + completion_params: newParams as CompletionParams, }) }, [selectedModel],