@pwshub/aisdk 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -42
- package/index.d.ts +18 -8
- package/package.json +8 -6
- package/src/coerce.test.js +142 -0
- package/src/config.js +30 -0
- package/src/config.test.js +142 -0
- package/src/errors.js +1 -1
- package/src/index.js +26 -14
- package/src/models.js +401 -0
- package/src/providers.js +109 -11
- package/src/registry.js +114 -37
- package/src/registry.test.js +314 -0
- package/src/validation.js +9 -3
- package/src/validation.test.js +410 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tests for config module.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
describe, it,
|
|
7
|
+
} from 'node:test'
|
|
8
|
+
import assert from 'node:assert'
|
|
9
|
+
import {
|
|
10
|
+
normalizeConfig, getWireMap,
|
|
11
|
+
} from '../src/config.js'
|
|
12
|
+
|
|
13
|
+
describe('config', () => {
|
|
14
|
+
describe('getWireMap', () => {
|
|
15
|
+
it('should return wire map for openai', () => {
|
|
16
|
+
const wireMap = getWireMap('openai')
|
|
17
|
+
assert.ok(wireMap)
|
|
18
|
+
assert.ok(wireMap.temperature)
|
|
19
|
+
assert.strictEqual(wireMap.temperature.wireKey, 'temperature')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('should return wire map for anthropic', () => {
|
|
23
|
+
const wireMap = getWireMap('anthropic')
|
|
24
|
+
assert.ok(wireMap)
|
|
25
|
+
assert.ok(wireMap.temperature)
|
|
26
|
+
assert.strictEqual(wireMap.temperature.wireKey, 'temperature')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('should return wire map for google', () => {
|
|
30
|
+
const wireMap = getWireMap('google')
|
|
31
|
+
assert.ok(wireMap)
|
|
32
|
+
assert.ok(wireMap.temperature)
|
|
33
|
+
assert.strictEqual(wireMap.temperature.wireKey, 'temperature')
|
|
34
|
+
assert.strictEqual(wireMap.temperature.scope, 'generationConfig')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('should return wire map for dashscope', () => {
|
|
38
|
+
const wireMap = getWireMap('dashscope')
|
|
39
|
+
assert.ok(wireMap)
|
|
40
|
+
assert.ok(wireMap.temperature)
|
|
41
|
+
assert.strictEqual(wireMap.temperature.wireKey, 'temperature')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should return wire map for deepseek', () => {
|
|
45
|
+
const wireMap = getWireMap('deepseek')
|
|
46
|
+
assert.ok(wireMap)
|
|
47
|
+
assert.ok(wireMap.temperature)
|
|
48
|
+
assert.strictEqual(wireMap.temperature.wireKey, 'temperature')
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('should return undefined for unknown provider', () => {
|
|
52
|
+
const wireMap = getWireMap('unknown')
|
|
53
|
+
assert.strictEqual(wireMap, undefined)
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
describe('normalizeConfig', () => {
|
|
58
|
+
it('should normalize openai config', () => {
|
|
59
|
+
const config = {
|
|
60
|
+
temperature: 0.5,
|
|
61
|
+
maxTokens: 100,
|
|
62
|
+
topP: 0.9,
|
|
63
|
+
}
|
|
64
|
+
const supportedParams = ['temperature', 'maxTokens', 'topP']
|
|
65
|
+
const result = normalizeConfig(config, 'openai', supportedParams, 'gpt-4o')
|
|
66
|
+
|
|
67
|
+
assert.strictEqual(result.temperature, 0.5)
|
|
68
|
+
assert.strictEqual(result.max_completion_tokens, 100)
|
|
69
|
+
assert.strictEqual(result.top_p, 0.9)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('should normalize anthropic config', () => {
|
|
73
|
+
const config = {
|
|
74
|
+
temperature: 0.5,
|
|
75
|
+
maxTokens: 100,
|
|
76
|
+
topK: 50,
|
|
77
|
+
}
|
|
78
|
+
const supportedParams = ['temperature', 'maxTokens', 'topK']
|
|
79
|
+
const result = normalizeConfig(config, 'anthropic', supportedParams, 'claude-sonnet')
|
|
80
|
+
|
|
81
|
+
assert.strictEqual(result.temperature, 0.5)
|
|
82
|
+
assert.strictEqual(result.max_tokens, 100)
|
|
83
|
+
assert.strictEqual(result.top_k, 50)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('should normalize google config with generationConfig nesting', () => {
|
|
87
|
+
const config = {
|
|
88
|
+
temperature: 0.5,
|
|
89
|
+
maxTokens: 100,
|
|
90
|
+
topP: 0.9,
|
|
91
|
+
}
|
|
92
|
+
const supportedParams = ['temperature', 'maxTokens', 'topP']
|
|
93
|
+
const result = normalizeConfig(config, 'google', supportedParams, 'gemini-2.0-flash')
|
|
94
|
+
|
|
95
|
+
assert.strictEqual(result.temperature, undefined)
|
|
96
|
+
assert.strictEqual(result.maxTokens, undefined)
|
|
97
|
+
assert.strictEqual(result.topP, undefined)
|
|
98
|
+
assert.ok(result.generationConfig)
|
|
99
|
+
assert.strictEqual(result.generationConfig.temperature, 0.5)
|
|
100
|
+
assert.strictEqual(result.generationConfig.maxOutputTokens, 100)
|
|
101
|
+
assert.strictEqual(result.generationConfig.topP, 0.9)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('should skip unsupported params', () => {
|
|
105
|
+
const config = {
|
|
106
|
+
temperature: 0.5,
|
|
107
|
+
topK: 50, // openai doesn't support topK
|
|
108
|
+
}
|
|
109
|
+
const supportedParams = ['temperature']
|
|
110
|
+
const result = normalizeConfig(config, 'openai', supportedParams, 'gpt-4o')
|
|
111
|
+
|
|
112
|
+
assert.strictEqual(result.temperature, 0.5)
|
|
113
|
+
assert.strictEqual(result.top_k, undefined)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('should skip null/undefined values', () => {
|
|
117
|
+
const config = {
|
|
118
|
+
temperature: 0.5,
|
|
119
|
+
maxTokens: null,
|
|
120
|
+
topP: undefined,
|
|
121
|
+
}
|
|
122
|
+
const supportedParams = ['temperature', 'maxTokens', 'topP']
|
|
123
|
+
const result = normalizeConfig(config, 'openai', supportedParams, 'gpt-4o')
|
|
124
|
+
|
|
125
|
+
assert.strictEqual(result.temperature, 0.5)
|
|
126
|
+
assert.strictEqual(result.max_completion_tokens, undefined)
|
|
127
|
+
assert.strictEqual(result.top_p, undefined)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('should return empty object when no config provided', () => {
|
|
131
|
+
const result = normalizeConfig({}, 'openai', ['temperature'], 'gpt-4o')
|
|
132
|
+
assert.deepStrictEqual(result, {})
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('should return empty object when no supported params match', () => {
|
|
136
|
+
const config = { unknownParam: 123 }
|
|
137
|
+
const supportedParams = ['temperature']
|
|
138
|
+
const result = normalizeConfig(config, 'openai', supportedParams, 'gpt-4o')
|
|
139
|
+
assert.deepStrictEqual(result, {})
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
})
|
package/src/errors.js
CHANGED
|
@@ -35,7 +35,7 @@ export class ProviderError extends Error {
|
|
|
35
35
|
* @param {object} meta
|
|
36
36
|
* @param {number} meta.status - HTTP status code
|
|
37
37
|
* @param {string} meta.provider - Provider ID
|
|
38
|
-
* @param {string} meta.model - Model
|
|
38
|
+
* @param {string} meta.model - Model name that was called
|
|
39
39
|
* @param {string} [meta.raw] - Raw response body from provider
|
|
40
40
|
*/
|
|
41
41
|
constructor(message, {
|
package/src/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* const ai = createAi()
|
|
8
8
|
* const result = await ai.ask({
|
|
9
|
-
* model: 'claude-sonnet-4-20250514',
|
|
9
|
+
* model: 'anthropic/claude-sonnet-4-20250514',
|
|
10
10
|
* apikey: 'your-api-key',
|
|
11
11
|
* prompt: 'What is the capital of Vietnam?',
|
|
12
12
|
* temperature: 0.5,
|
|
@@ -16,18 +16,18 @@
|
|
|
16
16
|
*
|
|
17
17
|
* @example With fallbacks
|
|
18
18
|
* const result = await ai.ask({
|
|
19
|
-
* model: 'gpt-4o',
|
|
19
|
+
* model: 'openai/gpt-4o',
|
|
20
20
|
* apikey: 'your-openai-key',
|
|
21
21
|
* prompt: '...',
|
|
22
|
-
* fallbacks: ['gpt-4o-mini', 'claude-haiku-4-5-20251001'],
|
|
22
|
+
* fallbacks: ['openai/gpt-4o-mini', 'anthropic/claude-haiku-4-5-20251001'],
|
|
23
23
|
* })
|
|
24
|
-
* if (result.model !== 'gpt-4o') {
|
|
24
|
+
* if (result.model !== 'openai/gpt-4o') {
|
|
25
25
|
* console.warn('Fell back to', result.model)
|
|
26
26
|
* }
|
|
27
27
|
*
|
|
28
28
|
* @example Google provider-specific options
|
|
29
29
|
* const result = await ai.ask({
|
|
30
|
-
* model: 'gemini-2.0-flash',
|
|
30
|
+
* model: 'google/gemini-2.0-flash',
|
|
31
31
|
* apikey: 'your-google-key',
|
|
32
32
|
* prompt: '...',
|
|
33
33
|
* providerOptions: {
|
|
@@ -38,10 +38,21 @@
|
|
|
38
38
|
* },
|
|
39
39
|
* })
|
|
40
40
|
*
|
|
41
|
+
* @example Using messages array for multi-turn conversations
|
|
42
|
+
* const result = await ai.ask({
|
|
43
|
+
* model: 'anthropic/claude-sonnet-4-20250514',
|
|
44
|
+
* apikey: 'your-api-key',
|
|
45
|
+
* messages: [
|
|
46
|
+
* { role: 'user', content: 'What is the capital of Vietnam?' },
|
|
47
|
+
* { role: 'assistant', content: 'The capital of Vietnam is Hanoi.' },
|
|
48
|
+
* { role: 'user', content: 'What is its population?' },
|
|
49
|
+
* ],
|
|
50
|
+
* })
|
|
51
|
+
*
|
|
41
52
|
*/
|
|
42
53
|
|
|
43
54
|
import {
|
|
44
|
-
getModel, listModels, setModels,
|
|
55
|
+
getModel, listModels, setModels, addModels,
|
|
45
56
|
} from './registry.js'
|
|
46
57
|
import { normalizeConfig } from './config.js'
|
|
47
58
|
import { coerceConfig } from './coerce.js'
|
|
@@ -62,11 +73,12 @@ export {
|
|
|
62
73
|
|
|
63
74
|
/**
|
|
64
75
|
* @typedef {Object} AskParams
|
|
65
|
-
* @property {string} model - Model
|
|
76
|
+
* @property {string} model - Model name or 'provider/name' format (e.g., 'gpt-4o', 'ollama/llama3.2')
|
|
66
77
|
* @property {string} apikey - API key for the provider
|
|
67
|
-
* @property {string} prompt
|
|
68
|
-
* @property {string} [system] - Optional system prompt
|
|
69
|
-
* @property {
|
|
78
|
+
* @property {string} [prompt] - The user message (alternative to messages)
|
|
79
|
+
* @property {string} [system] - Optional system prompt (used with prompt)
|
|
80
|
+
* @property {import('./providers.js').Message[]} [messages] - Array of messages with role and content (alternative to prompt)
|
|
81
|
+
* @property {string[]} [fallbacks] - Ordered list of fallback models (same format as model)
|
|
70
82
|
* @property {Record<string, unknown>} [providerOptions] - Provider-specific options merged into body
|
|
71
83
|
* @property {number} [temperature]
|
|
72
84
|
* @property {number} [maxTokens]
|
|
@@ -152,11 +164,11 @@ const callModel = async (modelId, params, gatewayUrl) => {
|
|
|
152
164
|
const normalizedConfig = normalizeConfig(coerced, providerId, supportedParams, modelId)
|
|
153
165
|
|
|
154
166
|
const {
|
|
155
|
-
prompt, system, providerOptions = {},
|
|
167
|
+
prompt, system, messages, providerOptions = {},
|
|
156
168
|
} = params
|
|
157
169
|
|
|
158
170
|
/** @type {import('./providers.js').Message[]} */
|
|
159
|
-
const
|
|
171
|
+
const messageList = messages ?? [
|
|
160
172
|
...(system ? [{
|
|
161
173
|
role: 'system', content: system,
|
|
162
174
|
}] : []),
|
|
@@ -166,7 +178,7 @@ const callModel = async (modelId, params, gatewayUrl) => {
|
|
|
166
178
|
]
|
|
167
179
|
|
|
168
180
|
const url = gatewayUrl ?? adapter.url(modelName, apikey)
|
|
169
|
-
const body = adapter.buildBody(modelName,
|
|
181
|
+
const body = adapter.buildBody(modelName, messageList, normalizedConfig, providerOptions)
|
|
170
182
|
|
|
171
183
|
let res
|
|
172
184
|
try {
|
|
@@ -267,4 +279,4 @@ export const createAi = (opts = {}) => {
|
|
|
267
279
|
}
|
|
268
280
|
}
|
|
269
281
|
|
|
270
|
-
export { setModels }
|
|
282
|
+
export { addModels, setModels, listModels }
|
package/src/models.js
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Default model registry for @pwshub/aisdk.
|
|
3
|
+
*
|
|
4
|
+
* This module exports a default list of models that are loaded automatically
|
|
5
|
+
* when the library is imported. Users can modify this list via addModels()
|
|
6
|
+
* and setModels() from the main export.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import('./registry.js').ModelRecord} ModelRecord
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** @type {ModelRecord[]} */
|
|
14
|
+
export const DEFAULT_MODELS = [
|
|
15
|
+
{
|
|
16
|
+
id: 'claude-haiku-4-5',
|
|
17
|
+
name: 'claude-haiku-4-5',
|
|
18
|
+
provider: 'anthropic',
|
|
19
|
+
input_price: 1,
|
|
20
|
+
output_price: 5,
|
|
21
|
+
cache_price: 0,
|
|
22
|
+
max_in: 200000,
|
|
23
|
+
max_out: 64000,
|
|
24
|
+
enable: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'claude-sonnet-4-6',
|
|
28
|
+
name: 'claude-sonnet-4-6',
|
|
29
|
+
provider: 'anthropic',
|
|
30
|
+
input_price: 3,
|
|
31
|
+
output_price: 15,
|
|
32
|
+
cache_price: 0,
|
|
33
|
+
max_in: 200000,
|
|
34
|
+
max_out: 64000,
|
|
35
|
+
enable: true,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'claude-sonnet-4-5',
|
|
39
|
+
name: 'claude-sonnet-4-5',
|
|
40
|
+
provider: 'anthropic',
|
|
41
|
+
input_price: 3,
|
|
42
|
+
output_price: 15,
|
|
43
|
+
cache_price: 0,
|
|
44
|
+
max_in: 200000,
|
|
45
|
+
max_out: 1000000,
|
|
46
|
+
enable: true,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'claude-opus-4-6',
|
|
50
|
+
name: 'claude-opus-4-6',
|
|
51
|
+
provider: 'anthropic',
|
|
52
|
+
input_price: 5,
|
|
53
|
+
output_price: 25,
|
|
54
|
+
cache_price: 0,
|
|
55
|
+
max_in: 200000,
|
|
56
|
+
max_out: 128000,
|
|
57
|
+
enable: true,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'gemini-2.5-flash',
|
|
61
|
+
name: 'gemini-2.5-flash',
|
|
62
|
+
provider: 'google',
|
|
63
|
+
input_price: 0.3,
|
|
64
|
+
output_price: 2.5,
|
|
65
|
+
cache_price: 0.03,
|
|
66
|
+
max_in: 1048576,
|
|
67
|
+
max_out: 65536,
|
|
68
|
+
enable: true,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'gemini-2.5-flash-lite',
|
|
72
|
+
name: 'gemini-2.5-flash-lite',
|
|
73
|
+
provider: 'google',
|
|
74
|
+
input_price: 0.1,
|
|
75
|
+
output_price: 0.4,
|
|
76
|
+
cache_price: 0.01,
|
|
77
|
+
max_in: 1048576,
|
|
78
|
+
max_out: 65536,
|
|
79
|
+
enable: true,
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: 'gemini-2.5-pro',
|
|
83
|
+
name: 'gemini-2.5-pro',
|
|
84
|
+
provider: 'google',
|
|
85
|
+
input_price: 1.25,
|
|
86
|
+
output_price: 10,
|
|
87
|
+
cache_price: 0.125,
|
|
88
|
+
max_in: 1048576,
|
|
89
|
+
max_out: 65536,
|
|
90
|
+
enable: true,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'gemini-3.1-pro-preview',
|
|
94
|
+
name: 'gemini-3.1-pro-preview',
|
|
95
|
+
provider: 'google',
|
|
96
|
+
input_price: 2,
|
|
97
|
+
output_price: 12,
|
|
98
|
+
cache_price: 0.2,
|
|
99
|
+
max_in: 1048576,
|
|
100
|
+
max_out: 65536,
|
|
101
|
+
enable: true,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: 'gemini-3.1-flash-lite-preview',
|
|
105
|
+
name: 'gemini-3.1-flash-lite-preview',
|
|
106
|
+
provider: 'google',
|
|
107
|
+
input_price: 0.25,
|
|
108
|
+
output_price: 1.5,
|
|
109
|
+
cache_price: 0.025,
|
|
110
|
+
max_in: 1048576,
|
|
111
|
+
max_out: 65536,
|
|
112
|
+
enable: true,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: 'gpt-4.1-nano',
|
|
116
|
+
name: 'gpt-4.1-nano',
|
|
117
|
+
provider: 'openai',
|
|
118
|
+
input_price: 0.1,
|
|
119
|
+
output_price: 0.4,
|
|
120
|
+
cache_price: 0.025,
|
|
121
|
+
max_in: 1047576,
|
|
122
|
+
max_out: 32768,
|
|
123
|
+
enable: true,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: 'gpt-4.1-mini',
|
|
127
|
+
name: 'gpt-4.1-mini',
|
|
128
|
+
provider: 'openai',
|
|
129
|
+
input_price: 0.4,
|
|
130
|
+
output_price: 1.6,
|
|
131
|
+
cache_price: 0.1,
|
|
132
|
+
max_in: 1047576,
|
|
133
|
+
max_out: 32768,
|
|
134
|
+
enable: true,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: 'gpt-4.1',
|
|
138
|
+
name: 'gpt-4.1',
|
|
139
|
+
provider: 'openai',
|
|
140
|
+
input_price: 2,
|
|
141
|
+
output_price: 8,
|
|
142
|
+
cache_price: 0.5,
|
|
143
|
+
max_in: 1047576,
|
|
144
|
+
max_out: 32768,
|
|
145
|
+
enable: true,
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: 'gpt-4o',
|
|
149
|
+
name: 'gpt-4o',
|
|
150
|
+
provider: 'openai',
|
|
151
|
+
input_price: 2.5,
|
|
152
|
+
output_price: 10,
|
|
153
|
+
cache_price: 1.25,
|
|
154
|
+
max_in: 128000,
|
|
155
|
+
max_out: 16384,
|
|
156
|
+
enable: true,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: 'gpt-4o-mini',
|
|
160
|
+
name: 'gpt-4o-mini',
|
|
161
|
+
provider: 'openai',
|
|
162
|
+
input_price: 0.15,
|
|
163
|
+
output_price: 0.6,
|
|
164
|
+
cache_price: 0.075,
|
|
165
|
+
max_in: 128000,
|
|
166
|
+
max_out: 16384,
|
|
167
|
+
enable: true,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: 'gpt-5',
|
|
171
|
+
name: 'gpt-5',
|
|
172
|
+
provider: 'openai',
|
|
173
|
+
input_price: 1.25,
|
|
174
|
+
output_price: 10,
|
|
175
|
+
cache_price: 0.125,
|
|
176
|
+
max_in: 400000,
|
|
177
|
+
max_out: 128000,
|
|
178
|
+
enable: true,
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: 'gpt-5-mini',
|
|
182
|
+
name: 'gpt-5-mini',
|
|
183
|
+
provider: 'openai',
|
|
184
|
+
input_price: 0.25,
|
|
185
|
+
output_price: 2,
|
|
186
|
+
cache_price: 0.025,
|
|
187
|
+
max_in: 400000,
|
|
188
|
+
max_out: 128000,
|
|
189
|
+
enable: true,
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: 'gpt-5-nano',
|
|
193
|
+
name: 'gpt-5-nano',
|
|
194
|
+
provider: 'openai',
|
|
195
|
+
input_price: 0.05,
|
|
196
|
+
output_price: 0.4,
|
|
197
|
+
cache_price: 0.005,
|
|
198
|
+
max_in: 400000,
|
|
199
|
+
max_out: 128000,
|
|
200
|
+
enable: true,
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
id: 'gpt-5.1',
|
|
204
|
+
name: 'gpt-5.1',
|
|
205
|
+
provider: 'openai',
|
|
206
|
+
input_price: 1.25,
|
|
207
|
+
output_price: 10,
|
|
208
|
+
cache_price: 0.125,
|
|
209
|
+
max_in: 400000,
|
|
210
|
+
max_out: 128000,
|
|
211
|
+
enable: true,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
id: 'gpt-5.2',
|
|
215
|
+
name: 'gpt-5.2',
|
|
216
|
+
provider: 'openai',
|
|
217
|
+
input_price: 1.75,
|
|
218
|
+
output_price: 14,
|
|
219
|
+
cache_price: 0.175,
|
|
220
|
+
max_in: 400000,
|
|
221
|
+
max_out: 128000,
|
|
222
|
+
enable: true,
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
id: 'gpt-5.4',
|
|
226
|
+
name: 'gpt-5.4',
|
|
227
|
+
provider: 'openai',
|
|
228
|
+
input_price: 2.5,
|
|
229
|
+
output_price: 15,
|
|
230
|
+
cache_price: 0.25,
|
|
231
|
+
max_in: 1050000,
|
|
232
|
+
max_out: 128000,
|
|
233
|
+
enable: true,
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
id: 'o3-mini',
|
|
237
|
+
name: 'o3-mini',
|
|
238
|
+
provider: 'openai',
|
|
239
|
+
input_price: 1.1,
|
|
240
|
+
output_price: 4.4,
|
|
241
|
+
cache_price: 0.55,
|
|
242
|
+
max_in: 200000,
|
|
243
|
+
max_out: 100000,
|
|
244
|
+
enable: true,
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
id: 'o4-mini',
|
|
248
|
+
name: 'o4-mini',
|
|
249
|
+
provider: 'openai',
|
|
250
|
+
input_price: 1.1,
|
|
251
|
+
output_price: 4.4,
|
|
252
|
+
cache_price: 0.275,
|
|
253
|
+
max_in: 200000,
|
|
254
|
+
max_out: 100000,
|
|
255
|
+
enable: true,
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
id: 'deepseek-chat',
|
|
259
|
+
name: 'deepseek-chat',
|
|
260
|
+
provider: 'deepseek',
|
|
261
|
+
input_price: 0.28,
|
|
262
|
+
output_price: 0.42,
|
|
263
|
+
cache_price: 0.028,
|
|
264
|
+
max_in: 128000,
|
|
265
|
+
max_out: 8000,
|
|
266
|
+
enable: true,
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
id: 'deepseek-reasoner',
|
|
270
|
+
name: 'deepseek-reasoner',
|
|
271
|
+
provider: 'deepseek',
|
|
272
|
+
input_price: 0.28,
|
|
273
|
+
output_price: 0.42,
|
|
274
|
+
cache_price: 0.028,
|
|
275
|
+
max_in: 128000,
|
|
276
|
+
max_out: 64000,
|
|
277
|
+
enable: true,
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
id: 'qwen-flash',
|
|
281
|
+
name: 'qwen-flash',
|
|
282
|
+
provider: 'dashscope',
|
|
283
|
+
input_price: 0.05,
|
|
284
|
+
output_price: 0.4,
|
|
285
|
+
cache_price: 0,
|
|
286
|
+
max_in: 995904,
|
|
287
|
+
max_out: 32768,
|
|
288
|
+
enable: true,
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
id: 'qwen3.5-flash',
|
|
292
|
+
name: 'qwen3.5-flash',
|
|
293
|
+
provider: 'dashscope',
|
|
294
|
+
input_price: 0.1,
|
|
295
|
+
output_price: 0.4,
|
|
296
|
+
cache_price: 0,
|
|
297
|
+
max_in: 983616,
|
|
298
|
+
max_out: 65536,
|
|
299
|
+
enable: true,
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: 'qwen-plus',
|
|
303
|
+
name: 'qwen-plus',
|
|
304
|
+
provider: 'dashscope',
|
|
305
|
+
input_price: 0.4,
|
|
306
|
+
output_price: 1.2,
|
|
307
|
+
cache_price: 0,
|
|
308
|
+
max_in: 997952,
|
|
309
|
+
max_out: 32768,
|
|
310
|
+
enable: true,
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
id: 'qwen3.5-plus',
|
|
314
|
+
name: 'qwen3.5-plus',
|
|
315
|
+
provider: 'dashscope',
|
|
316
|
+
input_price: 0.4,
|
|
317
|
+
output_price: 2.4,
|
|
318
|
+
cache_price: 0,
|
|
319
|
+
max_in: 991808,
|
|
320
|
+
max_out: 65536,
|
|
321
|
+
enable: true,
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
id: 'qwen-max',
|
|
325
|
+
name: 'qwen-max',
|
|
326
|
+
provider: 'dashscope',
|
|
327
|
+
input_price: 1.6,
|
|
328
|
+
output_price: 6.4,
|
|
329
|
+
cache_price: 0,
|
|
330
|
+
max_in: 30720,
|
|
331
|
+
max_out: 8192,
|
|
332
|
+
enable: true,
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
id: 'qwen3-max',
|
|
336
|
+
name: 'qwen3-max',
|
|
337
|
+
provider: 'dashscope',
|
|
338
|
+
input_price: 1.2,
|
|
339
|
+
output_price: 6,
|
|
340
|
+
cache_price: 0,
|
|
341
|
+
max_in: 258048,
|
|
342
|
+
max_out: 65536,
|
|
343
|
+
enable: true,
|
|
344
|
+
},
|
|
345
|
+
// Mistral models
|
|
346
|
+
{
|
|
347
|
+
id: 'mistral-large-latest',
|
|
348
|
+
name: 'mistral-large-latest',
|
|
349
|
+
provider: 'mistral',
|
|
350
|
+
input_price: 0.5,
|
|
351
|
+
output_price: 1.5,
|
|
352
|
+
cache_price: 0,
|
|
353
|
+
max_in: 128000,
|
|
354
|
+
max_out: 128000,
|
|
355
|
+
enable: true,
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
id: 'mistral-medium-latest',
|
|
359
|
+
name: 'mistral-medium-latest',
|
|
360
|
+
provider: 'mistral',
|
|
361
|
+
input_price: 0.4,
|
|
362
|
+
output_price: 2,
|
|
363
|
+
cache_price: 0,
|
|
364
|
+
max_in: 64000,
|
|
365
|
+
max_out: 64000,
|
|
366
|
+
enable: true,
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
id: 'mistral-small-latest',
|
|
370
|
+
name: 'mistral-small-latest',
|
|
371
|
+
provider: 'mistral',
|
|
372
|
+
input_price: 0.15,
|
|
373
|
+
output_price: 0.6,
|
|
374
|
+
cache_price: 0,
|
|
375
|
+
max_in: 128000,
|
|
376
|
+
max_out: 128000,
|
|
377
|
+
enable: true,
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
id: 'magistral-medium-latest',
|
|
381
|
+
name: 'magistral-medium-latest',
|
|
382
|
+
provider: 'mistral',
|
|
383
|
+
input_price: 2,
|
|
384
|
+
output_price: 5,
|
|
385
|
+
cache_price: 0,
|
|
386
|
+
max_in: 64000,
|
|
387
|
+
max_out: 64000,
|
|
388
|
+
enable: true,
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
id: 'magistral-small-latest',
|
|
392
|
+
name: 'magistral-small-latest',
|
|
393
|
+
provider: 'mistral',
|
|
394
|
+
input_price: 0.5,
|
|
395
|
+
output_price: 1.5,
|
|
396
|
+
cache_price: 0,
|
|
397
|
+
max_in: 64000,
|
|
398
|
+
max_out: 64000,
|
|
399
|
+
enable: true,
|
|
400
|
+
},
|
|
401
|
+
]
|