diff --git a/web/src/routes/gateway/provider-dialogs.test.tsx b/web/src/routes/gateway/provider-dialogs.test.tsx index 8b255375..eaba99f4 100644 --- a/web/src/routes/gateway/provider-dialogs.test.tsx +++ b/web/src/routes/gateway/provider-dialogs.test.tsx @@ -78,9 +78,41 @@ describe('CreateProviderDialog', () => { provider_type: 'bedrock', base_url: 'us-east-1', headers: [{ key: 'Authorization', value: 'Bearer ABSK-test' }], + min_speed_tokens_per_sec: null, + min_speed_window_secs: 20, }) }) + it('creates a provider with the slowest generation its streams may keep up', async () => { + const user = userEvent.setup() + renderCreate() + + await user.type(screen.getByLabelText('Name'), 'local-vllm') + const rate = screen.getByLabelText('Generation speed (tokens/s)') + const window = screen.getByLabelText('Window (seconds)') + expect(rate).toHaveValue('') + expect(window).toHaveValue('20') + await user.type(rate, '15') + await user.clear(window) + await user.type(window, '30') + await user.click(screen.getByRole('button', { name: 'Create Provider' })) + + expect(apiPost).toHaveBeenCalledWith( + '/api/admin/providers', + expect.objectContaining({ name: 'local-vllm', min_speed_tokens_per_sec: 15, min_speed_window_secs: 30 }), + ) + }) + + it('will not create a provider with a speed or window out of range', async () => { + const user = userEvent.setup() + renderCreate() + + await user.clear(screen.getByLabelText('Window (seconds)')) + await user.type(screen.getByLabelText('Window (seconds)'), '121') + expect(screen.getByText(/whole number from 1 to 1000/)).toBeInTheDocument() + expect(screen.getByRole('button', { name: 'Create Provider' })).toBeDisabled() + }) + it('tests a Bedrock provider with the access keys typed into the form', async () => { const user = userEvent.setup() renderCreate() diff --git a/web/src/routes/gateway/provider-dialogs.tsx b/web/src/routes/gateway/provider-dialogs.tsx index 64f32def..da770d84 100644 --- a/web/src/routes/gateway/provider-dialogs.tsx +++ b/web/src/routes/gateway/provider-dialogs.tsx @@ -179,6 +179,53 @@ const headerPresets = (t: (key: string) => string) => [ // Create Provider Dialog // --------------------------------------------------------------------------- +/** + * "Stop when generation is slower than [ ] tokens/s for [20] s": the + * provider's minimum generation speed, checked as it is typed. + */ +function MinSpeedRow({ id, rate, window, onRateChange, onWindowChange }: { + id: string; + rate: string; + window: string; + onRateChange: (v: string) => void; + onWindowChange: (v: string) => void; +}) { + const { t } = useTranslation(); + const valid = minSpeedFields(rate, window) !== null; + return ( +
{t('providers.minSpeedHint')}
+ ) : ( +{t('providers.minSpeedInvalid')}
+ )} +