fix(providers): support OpenAI models requiring max_completion_tokens (#2251)
This commit is contained in:
@@ -62,6 +62,7 @@ export const providerOpenAI = defineProvider<OpenAICompatibleConfig>({
|
||||
validators: {
|
||||
...createOpenAICompatibleValidators({
|
||||
checks: [ProviderValidationCheck.Connectivity, ProviderValidationCheck.ModelList, ProviderValidationCheck.ChatCompletions],
|
||||
chatCompletionTokenParameter: 'max_completion_tokens',
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { ProviderExtraMethods, ProviderInstance } from '../types'
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { providerOpenAI } from '../providers/openai'
|
||||
import { ProviderValidationCheck } from '../types'
|
||||
import { createOpenAICompatibleValidators } from './openai-compatible'
|
||||
|
||||
@@ -34,10 +35,10 @@ async function getProviderValidators(options?: Parameters<typeof createOpenAICom
|
||||
interface TestConfig { apiKey?: string, baseUrl?: string }
|
||||
|
||||
describe('createOpenAICompatibleValidators', () => {
|
||||
const config: TestConfig = {
|
||||
const config = {
|
||||
apiKey: 'test-key',
|
||||
baseUrl: 'https://example.com/v1/',
|
||||
}
|
||||
} satisfies TestConfig
|
||||
const provider: ProviderInstance = {
|
||||
model: () => ({
|
||||
apiKey: config.apiKey,
|
||||
@@ -143,6 +144,7 @@ describe('createOpenAICompatibleValidators', () => {
|
||||
expect(result.valid).toBe(true)
|
||||
expect(generateTextMock).toHaveBeenCalledWith(expect.objectContaining({
|
||||
model: 'seed-2-0-pro-260328',
|
||||
max_tokens: 16,
|
||||
}))
|
||||
})
|
||||
|
||||
@@ -171,4 +173,42 @@ describe('createOpenAICompatibleValidators', () => {
|
||||
max_tokens: 16,
|
||||
}))
|
||||
})
|
||||
|
||||
it('uses max_completion_tokens when the provider requires the newer parameter', async () => {
|
||||
listModelsMock.mockResolvedValue([
|
||||
{ id: 'gpt-5' },
|
||||
])
|
||||
|
||||
const [, chatValidator] = await getProviderValidators({
|
||||
checks: [ProviderValidationCheck.Connectivity, ProviderValidationCheck.ChatCompletions],
|
||||
chatCompletionTokenParameter: 'max_completion_tokens',
|
||||
})
|
||||
|
||||
const result = await chatValidator.validator(config, provider, providerExtra, { t: mockT })
|
||||
|
||||
expect(result.valid).toBe(true)
|
||||
expect(generateTextMock).toHaveBeenCalledWith(expect.objectContaining({
|
||||
model: 'gpt-5',
|
||||
max_completion_tokens: 16,
|
||||
}))
|
||||
expect(generateTextMock.mock.calls[0][0]).not.toHaveProperty('max_tokens')
|
||||
})
|
||||
|
||||
it('configures the OpenAI provider validation with max_completion_tokens', async () => {
|
||||
listModelsMock.mockResolvedValue([
|
||||
{ id: 'gpt-5' },
|
||||
])
|
||||
|
||||
const validators = await Promise.all((providerOpenAI.validators?.validateProvider || []).map(create => create({ t: mockT })))
|
||||
const chatValidator = validators.find(validator => validator.id === 'openai-compatible:check-chat-completions')
|
||||
|
||||
expect(chatValidator).toBeDefined()
|
||||
const result = await chatValidator!.validator(config, provider, providerExtra, { t: mockT })
|
||||
|
||||
expect(result.valid).toBe(true)
|
||||
expect(generateTextMock).toHaveBeenCalledWith(expect.objectContaining({
|
||||
max_completion_tokens: 16,
|
||||
}))
|
||||
expect(generateTextMock.mock.calls[0][0]).not.toHaveProperty('max_tokens')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -22,6 +22,7 @@ interface OpenAICompatibleValidationOptions<TConfig extends { apiKey?: string, b
|
||||
skipApiKeyCheck?: boolean
|
||||
connectivityFailureReason?: (input: { config: TConfig, error: unknown, errorMessage: string }) => string
|
||||
modelListFailureReason?: (input: { config: TConfig, error: unknown, errorMessage: string }) => string
|
||||
chatCompletionTokenParameter?: 'max_tokens' | 'max_completion_tokens'
|
||||
}
|
||||
|
||||
function extractStatusCode(error: unknown): number | null {
|
||||
@@ -145,7 +146,9 @@ export function createOpenAICompatibleValidators<TConfig extends { apiKey?: stri
|
||||
// OpenRouter documents this minimum for some upstream providers.
|
||||
// Source/context: https://openrouter.ai/docs/api/api-reference/chat/send-chat-completion-request
|
||||
// Removal condition: All supported providers accept lower limits, or the probe learns each model's minimum.
|
||||
max_tokens: 16,
|
||||
...(options?.chatCompletionTokenParameter === 'max_completion_tokens'
|
||||
? { max_completion_tokens: 16 }
|
||||
: { max_tokens: 16 }),
|
||||
})
|
||||
|
||||
return { connectivityOk: true, chatOk: true }
|
||||
|
||||
Reference in New Issue
Block a user