Skip to content

Commit 0aee843

Browse files
rm extra array
1 parent c29db4b commit 0aee843

1 file changed

Lines changed: 82 additions & 125 deletions

File tree

packages/openops/src/lib/ai/sync-models.ts

Lines changed: 82 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -14,98 +14,96 @@ import { AiProviderEnum } from '@openops/shared';
1414
import fs from 'node:fs';
1515
import path from 'node:path';
1616

17-
interface AiSdkConfig {
18-
package: string;
17+
interface TypeSource {
1918
typeName: string;
20-
providerFile: string;
2119
distPath?: string;
22-
arrayName?: string;
2320
excludedModels?: string[];
24-
additionalArrays?: Array<{
25-
distPath: string;
26-
typeName: string;
27-
arrayName: string;
28-
excludedModels?: string[];
29-
}>;
21+
}
22+
23+
interface AiSdkConfig {
24+
package: string;
25+
providerFile: string;
26+
typeSources: TypeSource[];
3027
}
3128

3229
export const AI_SDK_CONFIGS: Partial<Record<AiProviderEnum, AiSdkConfig>> = {
3330
[AiProviderEnum.ANTHROPIC]: {
3431
package: 'anthropic',
35-
typeName: 'AnthropicMessagesModelId',
3632
providerFile: 'anthropic',
33+
typeSources: [{ typeName: 'AnthropicMessagesModelId' }],
3734
},
3835
[AiProviderEnum.CEREBRAS]: {
3936
package: 'cerebras',
40-
typeName: 'CerebrasChatModelId',
4137
providerFile: 'cerebras',
38+
typeSources: [{ typeName: 'CerebrasChatModelId' }],
4239
},
4340
[AiProviderEnum.COHERE]: {
4441
package: 'cohere',
45-
typeName: 'CohereChatModelId',
4642
providerFile: 'cohere',
43+
typeSources: [{ typeName: 'CohereChatModelId' }],
4744
},
4845
[AiProviderEnum.DEEPSEEK]: {
4946
package: 'deepseek',
50-
typeName: 'DeepSeekChatModelId',
5147
providerFile: 'deep-seek',
48+
typeSources: [{ typeName: 'DeepSeekChatModelId' }],
5249
},
5350
[AiProviderEnum.GOOGLE]: {
5451
package: 'google',
55-
typeName: 'GoogleGenerativeAIModelId',
5652
providerFile: 'google',
53+
typeSources: [{ typeName: 'GoogleGenerativeAIModelId' }],
5754
},
5855
[AiProviderEnum.GOOGLE_VERTEX]: {
5956
package: 'google-vertex',
60-
typeName: 'GoogleVertexModelId',
6157
providerFile: 'google-vertex',
62-
excludedModels: [
63-
'gemini-1.0-pro',
64-
'gemini-1.0-pro-001',
65-
'gemini-1.0-pro-002',
66-
'gemini-1.0-pro-vision-001',
67-
'gemini-1.5-flash-001',
68-
'gemini-1.5-flash-002',
69-
'gemini-1.5-pro-001',
70-
'gemini-1.5-pro-002',
71-
],
72-
additionalArrays: [
58+
typeSources: [
59+
{
60+
typeName: 'GoogleVertexModelId',
61+
excludedModels: [
62+
'gemini-1.0-pro',
63+
'gemini-1.0-pro-001',
64+
'gemini-1.0-pro-002',
65+
'gemini-1.0-pro-vision-001',
66+
'gemini-1.5-flash-001',
67+
'gemini-1.5-flash-002',
68+
'gemini-1.5-pro-001',
69+
'gemini-1.5-pro-002',
70+
],
71+
},
7372
{
74-
distPath: 'dist/anthropic/index.d.ts',
7573
typeName: 'GoogleVertexAnthropicMessagesModelId',
76-
arrayName: 'googleVertexClaudeModels',
74+
distPath: 'dist/anthropic/index.d.ts',
7775
},
7876
],
7977
},
8078
[AiProviderEnum.GROQ]: {
8179
package: 'groq',
82-
typeName: 'GroqChatModelId',
8380
providerFile: 'groq',
81+
typeSources: [{ typeName: 'GroqChatModelId' }],
8482
},
8583
[AiProviderEnum.MISTRAL]: {
8684
package: 'mistral',
87-
typeName: 'MistralChatModelId',
8885
providerFile: 'mistral',
86+
typeSources: [{ typeName: 'MistralChatModelId' }],
8987
},
9088
[AiProviderEnum.OPENAI]: {
9189
package: 'openai',
92-
typeName: 'OpenAIChatModelId',
9390
providerFile: 'openai',
91+
typeSources: [{ typeName: 'OpenAIChatModelId' }],
9492
},
9593
[AiProviderEnum.PERPLEXITY]: {
9694
package: 'perplexity',
97-
typeName: 'PerplexityLanguageModelId',
9895
providerFile: 'perplexity',
96+
typeSources: [{ typeName: 'PerplexityLanguageModelId' }],
9997
},
10098
[AiProviderEnum.TOGETHER_AI]: {
10199
package: 'togetherai',
102-
typeName: 'TogetherAIChatModelId',
103100
providerFile: 'together-ai',
101+
typeSources: [{ typeName: 'TogetherAIChatModelId' }],
104102
},
105103
[AiProviderEnum.XAI]: {
106104
package: 'xai',
107-
typeName: 'XaiChatModelId',
108105
providerFile: 'xai',
106+
typeSources: [{ typeName: 'XaiChatModelId' }],
109107
},
110108
};
111109

@@ -127,10 +125,9 @@ const NON_CHAT_KEYWORDS = [
127125

128126
async function fetchAiSdkModels(
129127
pkg: string,
130-
typeName: string,
131-
distPath = 'dist/index.d.ts',
132-
excludedModels: string[] = [],
128+
source: TypeSource,
133129
): Promise<string[]> {
130+
const distPath = source.distPath ?? 'dist/index.d.ts';
134131
const url = `https://unpkg.com/@ai-sdk/${pkg}@latest/${distPath}`;
135132
const response = await fetch(url);
136133
if (!response.ok) {
@@ -140,31 +137,31 @@ async function fetchAiSdkModels(
140137
}
141138

142139
const dts = await response.text();
143-
const pattern = new RegExp(`type\\s+${typeName}\\s*=\\s*([^;]+);`, 's');
140+
const pattern = new RegExp(
141+
`type\\s+${source.typeName}\\s*=\\s*([^;]+);`,
142+
's',
143+
);
144144
const match = dts.match(pattern);
145145
if (!match) {
146-
throw new Error(`Could not find type ${typeName} in @ai-sdk/${pkg}`);
146+
throw new Error(`Could not find type ${source.typeName} in @ai-sdk/${pkg}`);
147147
}
148148

149+
const excluded = source.excludedModels ?? [];
149150
return [...match[1].matchAll(/'([^']+)'/g)]
150151
.map((m) => m[1])
151152
.filter(
152153
(id) =>
153154
!NON_CHAT_KEYWORDS.some((kw) => id.toLowerCase().includes(kw)) &&
154-
!excludedModels.includes(id),
155-
)
156-
.sort((a, b) => a.localeCompare(b));
155+
!excluded.includes(id),
156+
);
157157
}
158158

159-
function getCurrentModels(providerFile: string, arrayName?: string): string[] {
159+
function getCurrentModels(providerFile: string): string[] {
160160
const filePath = path.join(__dirname, 'providers', `${providerFile}.ts`);
161161
if (!fs.existsSync(filePath)) return [];
162162

163163
const content = fs.readFileSync(filePath, 'utf-8');
164-
const pattern = arrayName
165-
? new RegExp(`const\\s+${arrayName}\\s*=\\s*\\[([\\s\\S]*?)\\];`)
166-
: /const\s+\w+Models\s*=\s*\[([\s\S]*?)\];/;
167-
const match = content.match(pattern);
164+
const match = content.match(/const\s+\w+Models\s*=\s*\[([\s\S]*?)\];/);
168165
if (!match) return [];
169166

170167
return match[1]
@@ -174,69 +171,23 @@ function getCurrentModels(providerFile: string, arrayName?: string): string[] {
174171
.sort();
175172
}
176173

177-
function updateProviderFile(
178-
providerFile: string,
179-
models: string[],
180-
arrayName?: string,
181-
): void {
174+
function updateProviderFile(providerFile: string, models: string[]): void {
182175
const filePath = path.join(__dirname, 'providers', `${providerFile}.ts`);
183176
const content = fs.readFileSync(filePath, 'utf-8');
184-
const pattern = arrayName
185-
? new RegExp(`const\\s+(${arrayName})\\s*=\\s*\\[([\\s\\S]*?)\\];`)
186-
: /const\s+(\w+Models)\s*=\s*\[([\s\S]*?)\];/;
187-
const match = content.match(pattern);
177+
const match = content.match(/const\s+(\w+Models)\s*=\s*\[([\s\S]*?)\];/);
188178
if (!match) return;
189179

190-
const resolvedArrayName = match[1];
180+
const arrayName = match[1];
191181
const formattedModels = models.map((model) => ` '${model}',`).join('\n');
192-
const newArray = `const ${resolvedArrayName} = [\n${formattedModels}\n];`;
193-
const updatedContent = content.replace(pattern, newArray);
182+
const newArray = `const ${arrayName} = [\n${formattedModels}\n];`;
183+
const updatedContent = content.replace(
184+
/const\s+\w+Models\s*=\s*\[([\s\S]*?)\];/,
185+
newArray,
186+
);
194187

195188
fs.writeFileSync(filePath, updatedContent, 'utf-8');
196189
}
197190

198-
async function syncConfig(
199-
label: string,
200-
pkg: string,
201-
typeName: string,
202-
providerFile: string,
203-
distPath: string | undefined,
204-
arrayName: string | undefined,
205-
excludedModels: string[] | undefined,
206-
shouldUpdate: boolean,
207-
): Promise<boolean> {
208-
let latestModels: string[];
209-
try {
210-
latestModels = await fetchAiSdkModels(
211-
pkg,
212-
typeName,
213-
distPath,
214-
excludedModels,
215-
);
216-
} catch (error) {
217-
console.error(`Skipping ${label}: ${(error as Error).message}`);
218-
return false;
219-
}
220-
221-
const currentModels = getCurrentModels(providerFile, arrayName);
222-
const added = latestModels.filter((m) => !currentModels.includes(m));
223-
const removed = currentModels.filter((m) => !latestModels.includes(m));
224-
225-
if (added.length === 0 && removed.length === 0) {
226-
return false;
227-
}
228-
229-
console.log(`${label}:`);
230-
if (added.length > 0) console.log(` +${added.length}`);
231-
if (removed.length > 0) console.log(` -${removed.length}`);
232-
233-
if (shouldUpdate) {
234-
updateProviderFile(providerFile, latestModels, arrayName);
235-
}
236-
237-
return true;
238-
}
239-
240191
async function main() {
241192
const shouldUpdate = process.argv.includes('--update');
242193

@@ -245,30 +196,36 @@ async function main() {
245196
for (const [provider, config] of Object.entries(AI_SDK_CONFIGS)) {
246197
if (!config) continue;
247198

248-
const changed = await syncConfig(
249-
provider,
250-
config.package,
251-
config.typeName,
252-
config.providerFile,
253-
config.distPath,
254-
config.arrayName,
255-
config.excludedModels,
256-
shouldUpdate,
257-
);
258-
if (changed) hasChanges = true;
259-
260-
for (const extra of config.additionalArrays ?? []) {
261-
const extraChanged = await syncConfig(
262-
`${provider} (${extra.arrayName})`,
263-
config.package,
264-
extra.typeName,
265-
config.providerFile,
266-
extra.distPath,
267-
extra.arrayName,
268-
extra.excludedModels,
269-
shouldUpdate,
199+
let latestModels: string[];
200+
try {
201+
const results = await Promise.all(
202+
config.typeSources.map((source) =>
203+
fetchAiSdkModels(config.package, source),
204+
),
205+
);
206+
latestModels = [...new Set(results.flat())].sort((a, b) =>
207+
a.localeCompare(b),
270208
);
271-
if (extraChanged) hasChanges = true;
209+
} catch (error) {
210+
console.error(`Skipping ${provider}: ${(error as Error).message}`);
211+
continue;
212+
}
213+
214+
const currentModels = getCurrentModels(config.providerFile);
215+
const added = latestModels.filter((m) => !currentModels.includes(m));
216+
const removed = currentModels.filter((m) => !latestModels.includes(m));
217+
218+
if (added.length === 0 && removed.length === 0) {
219+
continue;
220+
}
221+
222+
hasChanges = true;
223+
console.log(`${provider}:`);
224+
if (added.length > 0) console.log(` +${added.length}`);
225+
if (removed.length > 0) console.log(` -${removed.length}`);
226+
227+
if (shouldUpdate) {
228+
updateProviderFile(config.providerFile, latestModels);
272229
}
273230
}
274231

0 commit comments

Comments
 (0)