model.test.ts100 lines · main
1import { openai } from '@ai-sdk/openai'
2import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
3
4import * as bedrockModule from './bedrock'
5import { getModel } from './model'
6import { DEFAULT_COMPLETION_MODEL, openaiModelEntry } from './model.utils'
7
8vi.mock('@ai-sdk/openai', () => ({
9 openai: vi.fn(() => 'openai-model'),
10}))
11
12vi.mock('./bedrock', async () => ({
13 ...(await vi.importActual('./bedrock')),
14 createRoutedBedrock: vi.fn(() => async (_modelId: string) => 'bedrock-model'),
15 checkAwsCredentials: vi.fn(),
16}))
17
18describe('getModel', () => {
19 const originalEnv = { ...process.env }
20
21 beforeEach(() => {
22 vi.resetAllMocks()
23 })
24
25 afterEach(() => {
26 process.env = { ...originalEnv }
27 })
28
29 it('returns bedrock model without systemProviderOptions', async () => {
30 vi.mocked(bedrockModule.checkAwsCredentials).mockResolvedValue(true)
31 vi.stubEnv('AWS_BEDROCK_ROLE_ARN', 'test')
32
33 const { modelParams, error, systemProviderOptions } = await getModel({
34 provider: 'bedrock',
35 routingKey: 'test',
36 })
37
38 expect(modelParams?.model).toEqual('bedrock-model')
39 expect(systemProviderOptions).toBeUndefined()
40 expect(error).toBeUndefined()
41 })
42
43 it('returns error when bedrock credentials are not available', async () => {
44 vi.mocked(bedrockModule.checkAwsCredentials).mockResolvedValue(false)
45
46 const { error } = await getModel({ provider: 'bedrock', routingKey: 'test' })
47 expect(error).toBeDefined()
48 })
49
50 it('returns openai model with default model', async () => {
51 vi.stubEnv('OPENAI_API_KEY', 'test-key')
52
53 const { modelParams, systemProviderOptions } = await getModel({
54 provider: 'openai',
55 modelEntry: openaiModelEntry({ id: 'gpt-5.4-nano' }),
56 })
57
58 expect(modelParams?.model).toEqual('openai-model')
59 expect(openai).toHaveBeenCalledWith('gpt-5.4-nano')
60 expect(systemProviderOptions).toBeUndefined()
61 })
62
63 it('returns error when OPENAI_API_KEY is not available', async () => {
64 vi.stubEnv('OPENAI_API_KEY', '')
65
66 const { error } = await getModel({
67 provider: 'openai',
68 modelEntry: openaiModelEntry({ id: 'gpt-5.4-nano' }),
69 })
70 expect(error).toEqual(new Error('OPENAI_API_KEY not available'))
71 })
72
73 it('returns openai gpt-5.3-codex when hasAccessToAdvanceModel and not throttled', async () => {
74 vi.stubEnv('OPENAI_API_KEY', 'test-key')
75 vi.stubEnv('IS_THROTTLED', 'false')
76
77 const { modelParams, error } = await getModel({
78 provider: 'openai',
79 modelEntry: openaiModelEntry({ id: 'gpt-5.3-codex', reasoningEffort: 'low' }),
80 })
81
82 expect(error).toBeUndefined()
83 expect(modelParams?.model).toEqual('openai-model')
84 expect(openai).toHaveBeenCalledWith('gpt-5.3-codex')
85 expect(modelParams?.providerOptions?.openai?.reasoningEffort).toBe('low')
86 })
87
88 it('applies reasoningEffort from DEFAULT_COMPLETION_MODEL', async () => {
89 vi.stubEnv('OPENAI_API_KEY', 'test-key')
90
91 const { modelParams, error } = await getModel({
92 provider: 'openai',
93 modelEntry: DEFAULT_COMPLETION_MODEL,
94 })
95
96 expect(error).toBeUndefined()
97 expect(openai).toHaveBeenCalledWith('gpt-5.4-nano')
98 expect(modelParams?.providerOptions?.openai?.reasoningEffort).toBe('none')
99 })
100})