@auto-engineer/model-factory 1.58.0 → 1.60.0
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +5 -5
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +22 -0
- package/dist/src/index.d.ts +1 -8
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +12 -32
- package/dist/src/index.js.map +1 -1
- package/dist/src/index.specs.js +43 -135
- package/dist/src/index.specs.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/index.specs.ts +43 -162
- package/src/index.ts +12 -42
package/package.json
CHANGED
package/src/index.specs.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
2
|
|
|
3
|
-
const stubModel = (provider: string) => (model: string) => ({
|
|
4
|
-
specificationVersion: 'v3',
|
|
5
|
-
modelId: model,
|
|
6
|
-
provider,
|
|
7
|
-
});
|
|
8
|
-
|
|
9
3
|
vi.mock('@ai-sdk/openai-compatible', () => ({
|
|
10
4
|
createOpenAICompatible: ({ name, baseURL, apiKey }: { name: string; baseURL: string; apiKey: string }) => ({
|
|
11
5
|
chatModel: (model: string) => ({
|
|
@@ -16,11 +10,6 @@ vi.mock('@ai-sdk/openai-compatible', () => ({
|
|
|
16
10
|
}),
|
|
17
11
|
}));
|
|
18
12
|
|
|
19
|
-
vi.mock('@ai-sdk/openai', () => ({ createOpenAI: () => stubModel('openai') }));
|
|
20
|
-
vi.mock('@ai-sdk/anthropic', () => ({ createAnthropic: () => stubModel('anthropic') }));
|
|
21
|
-
vi.mock('@ai-sdk/google', () => ({ createGoogleGenerativeAI: () => stubModel('google') }));
|
|
22
|
-
vi.mock('@ai-sdk/xai', () => ({ createXai: () => stubModel('xai') }));
|
|
23
|
-
|
|
24
13
|
const savedEnv = { ...process.env };
|
|
25
14
|
|
|
26
15
|
beforeEach(() => {
|
|
@@ -31,169 +20,61 @@ afterEach(() => {
|
|
|
31
20
|
process.env = { ...savedEnv };
|
|
32
21
|
});
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('uses options.model override', async () => {
|
|
53
|
-
process.env.CUSTOM_PROVIDER_BASE_URL = 'https://gw.example.com/v1';
|
|
54
|
-
|
|
55
|
-
const { createModelFromEnv } = await import('./index.js');
|
|
56
|
-
const model = createModelFromEnv({ model: 'my-custom-model' });
|
|
57
|
-
|
|
58
|
-
expect(model).toEqual({
|
|
59
|
-
specificationVersion: 'v3',
|
|
60
|
-
modelId: 'my-custom-model',
|
|
61
|
-
provider: 'custom:https://gw.example.com/v1:',
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('uses DEFAULT_AI_MODEL env var when options.model is unset', async () => {
|
|
66
|
-
process.env.CUSTOM_PROVIDER_BASE_URL = 'https://gw.example.com/v1';
|
|
67
|
-
process.env.DEFAULT_AI_MODEL = 'env-override-model';
|
|
68
|
-
|
|
69
|
-
const { createModelFromEnv } = await import('./index.js');
|
|
70
|
-
const model = createModelFromEnv();
|
|
23
|
+
function setRequiredEnv(overrides?: Partial<Record<string, string>>) {
|
|
24
|
+
process.env.CUSTOM_PROVIDER_NAME = 'litellm';
|
|
25
|
+
process.env.CUSTOM_PROVIDER_BASE_URL = 'https://gateway.example.com/v1';
|
|
26
|
+
process.env.CUSTOM_PROVIDER_API_KEY = 'sk-test';
|
|
27
|
+
process.env.CUSTOM_PROVIDER_DEFAULT_MODEL = 'xai/grok-code-fast-1';
|
|
28
|
+
if (overrides) {
|
|
29
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
30
|
+
if (value === undefined) {
|
|
31
|
+
delete process.env[key];
|
|
32
|
+
} else {
|
|
33
|
+
process.env[key] = value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
71
38
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
provider: 'custom:https://gw.example.com/v1:',
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('defaults to custom provider when DEFAULT_AI_PROVIDER is unset', async () => {
|
|
80
|
-
process.env.CUSTOM_PROVIDER_BASE_URL = 'https://gw.example.com/v1';
|
|
81
|
-
delete process.env.DEFAULT_AI_PROVIDER;
|
|
82
|
-
|
|
83
|
-
const { createModelFromEnv } = await import('./index.js');
|
|
84
|
-
const model = createModelFromEnv();
|
|
85
|
-
|
|
86
|
-
expect(model).toEqual(
|
|
87
|
-
expect.objectContaining({
|
|
88
|
-
specificationVersion: 'v3',
|
|
89
|
-
provider: 'custom:https://gw.example.com/v1:',
|
|
90
|
-
}),
|
|
91
|
-
);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('throws when CUSTOM_PROVIDER_BASE_URL is missing', async () => {
|
|
95
|
-
process.env.DEFAULT_AI_PROVIDER = 'custom';
|
|
96
|
-
delete process.env.CUSTOM_PROVIDER_BASE_URL;
|
|
39
|
+
describe('createModelFromEnv', () => {
|
|
40
|
+
it('creates model from all 4 env vars', async () => {
|
|
41
|
+
setRequiredEnv();
|
|
97
42
|
|
|
98
|
-
|
|
43
|
+
const { createModelFromEnv } = await import('./index.js');
|
|
44
|
+
const model = createModelFromEnv();
|
|
99
45
|
|
|
100
|
-
|
|
46
|
+
expect(model).toEqual({
|
|
47
|
+
specificationVersion: 'v3',
|
|
48
|
+
modelId: 'xai/grok-code-fast-1',
|
|
49
|
+
provider: 'litellm:https://gateway.example.com/v1:sk-test',
|
|
101
50
|
});
|
|
102
51
|
});
|
|
103
52
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const { createModelFromEnv, DEFAULT_MODELS } = await import('./index.js');
|
|
107
|
-
const model = createModelFromEnv({ provider: 'openai' });
|
|
108
|
-
|
|
109
|
-
expect(model).toEqual({
|
|
110
|
-
specificationVersion: 'v3',
|
|
111
|
-
modelId: DEFAULT_MODELS.openai,
|
|
112
|
-
provider: 'openai',
|
|
113
|
-
});
|
|
114
|
-
});
|
|
53
|
+
it('throws when CUSTOM_PROVIDER_NAME is missing', async () => {
|
|
54
|
+
setRequiredEnv({ CUSTOM_PROVIDER_NAME: undefined });
|
|
115
55
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
expect(model).toEqual({
|
|
121
|
-
specificationVersion: 'v3',
|
|
122
|
-
modelId: DEFAULT_MODELS.anthropic,
|
|
123
|
-
provider: 'anthropic',
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it('creates google model with default model name', async () => {
|
|
128
|
-
const { createModelFromEnv, DEFAULT_MODELS } = await import('./index.js');
|
|
129
|
-
const model = createModelFromEnv({ provider: 'google' });
|
|
130
|
-
|
|
131
|
-
expect(model).toEqual({
|
|
132
|
-
specificationVersion: 'v3',
|
|
133
|
-
modelId: DEFAULT_MODELS.google,
|
|
134
|
-
provider: 'google',
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('creates xai model with default model name', async () => {
|
|
139
|
-
const { createModelFromEnv, DEFAULT_MODELS } = await import('./index.js');
|
|
140
|
-
const model = createModelFromEnv({ provider: 'xai' });
|
|
141
|
-
|
|
142
|
-
expect(model).toEqual({
|
|
143
|
-
specificationVersion: 'v3',
|
|
144
|
-
modelId: DEFAULT_MODELS.xai,
|
|
145
|
-
provider: 'xai',
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('reads provider from DEFAULT_AI_PROVIDER env var', async () => {
|
|
150
|
-
process.env.DEFAULT_AI_PROVIDER = 'anthropic';
|
|
151
|
-
|
|
152
|
-
const { createModelFromEnv, DEFAULT_MODELS } = await import('./index.js');
|
|
153
|
-
const model = createModelFromEnv();
|
|
154
|
-
|
|
155
|
-
expect(model).toEqual({
|
|
156
|
-
specificationVersion: 'v3',
|
|
157
|
-
modelId: DEFAULT_MODELS.anthropic,
|
|
158
|
-
provider: 'anthropic',
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('options.provider overrides DEFAULT_AI_PROVIDER env var', async () => {
|
|
163
|
-
process.env.DEFAULT_AI_PROVIDER = 'openai';
|
|
164
|
-
|
|
165
|
-
const { createModelFromEnv, DEFAULT_MODELS } = await import('./index.js');
|
|
166
|
-
const model = createModelFromEnv({ provider: 'xai' });
|
|
56
|
+
const { createModelFromEnv } = await import('./index.js');
|
|
57
|
+
expect(() => createModelFromEnv()).toThrow('Missing required environment variable: CUSTOM_PROVIDER_NAME');
|
|
58
|
+
});
|
|
167
59
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
modelId: DEFAULT_MODELS.xai,
|
|
171
|
-
provider: 'xai',
|
|
172
|
-
});
|
|
173
|
-
});
|
|
60
|
+
it('throws when CUSTOM_PROVIDER_BASE_URL is missing', async () => {
|
|
61
|
+
setRequiredEnv({ CUSTOM_PROVIDER_BASE_URL: undefined });
|
|
174
62
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
63
|
+
const { createModelFromEnv } = await import('./index.js');
|
|
64
|
+
expect(() => createModelFromEnv()).toThrow('Missing required environment variable: CUSTOM_PROVIDER_BASE_URL');
|
|
65
|
+
});
|
|
178
66
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
modelId: 'gpt-4-turbo',
|
|
182
|
-
provider: 'openai',
|
|
183
|
-
});
|
|
184
|
-
});
|
|
67
|
+
it('throws when CUSTOM_PROVIDER_API_KEY is missing', async () => {
|
|
68
|
+
setRequiredEnv({ CUSTOM_PROVIDER_API_KEY: undefined });
|
|
185
69
|
|
|
186
|
-
|
|
187
|
-
|
|
70
|
+
const { createModelFromEnv } = await import('./index.js');
|
|
71
|
+
expect(() => createModelFromEnv()).toThrow('Missing required environment variable: CUSTOM_PROVIDER_API_KEY');
|
|
72
|
+
});
|
|
188
73
|
|
|
189
|
-
|
|
190
|
-
|
|
74
|
+
it('throws when CUSTOM_PROVIDER_DEFAULT_MODEL is missing', async () => {
|
|
75
|
+
setRequiredEnv({ CUSTOM_PROVIDER_DEFAULT_MODEL: undefined });
|
|
191
76
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
modelId: 'custom-model-name',
|
|
195
|
-
provider: 'openai',
|
|
196
|
-
});
|
|
197
|
-
});
|
|
77
|
+
const { createModelFromEnv } = await import('./index.js');
|
|
78
|
+
expect(() => createModelFromEnv()).toThrow('Missing required environment variable: CUSTOM_PROVIDER_DEFAULT_MODEL');
|
|
198
79
|
});
|
|
199
80
|
});
|
package/src/index.ts
CHANGED
|
@@ -1,49 +1,19 @@
|
|
|
1
|
-
import { createAnthropic } from '@ai-sdk/anthropic';
|
|
2
|
-
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
3
|
-
import { createOpenAI } from '@ai-sdk/openai';
|
|
4
1
|
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
|
|
5
|
-
import { createXai } from '@ai-sdk/xai';
|
|
6
2
|
import type { LanguageModel } from 'ai';
|
|
7
3
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
xai: 'grok-3',
|
|
15
|
-
custom: 'claude-sonnet-4-20250514',
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
interface CreateModelOptions {
|
|
19
|
-
provider?: Provider;
|
|
20
|
-
model?: string;
|
|
4
|
+
function requireEnv(name: string): string {
|
|
5
|
+
const value = process.env[name];
|
|
6
|
+
if (!value) {
|
|
7
|
+
throw new Error(`Missing required environment variable: ${name}`);
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
21
10
|
}
|
|
22
11
|
|
|
23
|
-
export function createModelFromEnv(
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const name = process.env.CUSTOM_PROVIDER_NAME ?? 'custom';
|
|
29
|
-
const baseURL = process.env.CUSTOM_PROVIDER_BASE_URL;
|
|
30
|
-
const apiKey = process.env.CUSTOM_PROVIDER_API_KEY ?? '';
|
|
12
|
+
export function createModelFromEnv(): LanguageModel {
|
|
13
|
+
const name = requireEnv('CUSTOM_PROVIDER_NAME');
|
|
14
|
+
const baseURL = requireEnv('CUSTOM_PROVIDER_BASE_URL');
|
|
15
|
+
const apiKey = requireEnv('CUSTOM_PROVIDER_API_KEY');
|
|
16
|
+
const model = requireEnv('CUSTOM_PROVIDER_DEFAULT_MODEL');
|
|
31
17
|
|
|
32
|
-
|
|
33
|
-
throw new Error('CUSTOM_PROVIDER_BASE_URL is required when using the custom provider');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return createOpenAICompatible({ name, baseURL, apiKey }).chatModel(modelName) as unknown as LanguageModel;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
switch (provider) {
|
|
40
|
-
case 'openai':
|
|
41
|
-
return createOpenAI()(modelName) as unknown as LanguageModel;
|
|
42
|
-
case 'anthropic':
|
|
43
|
-
return createAnthropic()(modelName) as unknown as LanguageModel;
|
|
44
|
-
case 'google':
|
|
45
|
-
return createGoogleGenerativeAI()(modelName) as unknown as LanguageModel;
|
|
46
|
-
case 'xai':
|
|
47
|
-
return createXai()(modelName) as unknown as LanguageModel;
|
|
48
|
-
}
|
|
18
|
+
return createOpenAICompatible({ name, baseURL, apiKey }).chatModel(model) as unknown as LanguageModel;
|
|
49
19
|
}
|