language-models 0.1.0 → 0.2.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.
Files changed (51) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/.turbo/turbo-test.log +18 -0
  3. package/README.md +56 -142
  4. package/data/models.json +18805 -0
  5. package/dist/aliases.d.ts +5 -1
  6. package/dist/aliases.d.ts.map +1 -0
  7. package/dist/aliases.js +40 -4
  8. package/dist/aliases.js.map +1 -0
  9. package/dist/data/models.json +18805 -0
  10. package/dist/index.d.ts +10 -7
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +10 -7
  13. package/dist/index.js.map +1 -0
  14. package/dist/models.d.ts +94 -167
  15. package/dist/models.d.ts.map +1 -0
  16. package/dist/models.js +109 -69803
  17. package/dist/models.js.map +1 -0
  18. package/package.json +25 -23
  19. package/scripts/fetch-models.ts +115 -0
  20. package/src/aliases.test.ts +319 -0
  21. package/src/aliases.ts +48 -4
  22. package/src/index.test.ts +400 -0
  23. package/src/index.ts +20 -9
  24. package/src/models.test.ts +392 -0
  25. package/src/models.ts +174 -0
  26. package/tsconfig.json +5 -15
  27. package/vitest.config.ts +4 -14
  28. package/.editorconfig +0 -10
  29. package/.gitattributes +0 -4
  30. package/.releaserc.js +0 -129
  31. package/LICENSE +0 -21
  32. package/dist/parser.d.ts +0 -86
  33. package/dist/parser.js +0 -390
  34. package/dist/providers.d.ts +0 -1
  35. package/dist/providers.js +0 -76
  36. package/dist/types.d.ts +0 -127
  37. package/dist/types.js +0 -1
  38. package/eslint.config.js +0 -3
  39. package/generate/build-models.ts +0 -150
  40. package/generate/overwrites.ts +0 -12
  41. package/publish.js +0 -32
  42. package/roadmap.md +0 -54
  43. package/src/models.d.ts +0 -170
  44. package/src/models.js +0 -70434
  45. package/src/parser.ts +0 -485
  46. package/src/providers.ts +0 -79
  47. package/src/types.ts +0 -135
  48. package/tests/parser.test.ts +0 -11
  49. package/tests/regex.test.ts +0 -42
  50. package/tests/selector.test.ts +0 -53
  51. package/tests/setup.ts +0 -0
package/.releaserc.js DELETED
@@ -1,129 +0,0 @@
1
-
2
- export default {
3
- branches: [
4
- {name: 'next', prerelease: 'next', channel: 'next'}
5
- ],
6
- repositoryUrl: 'https://github.com/drivly/ai.git',
7
- tagFormat: '${name}@${version}',
8
- initialVersion: '0.1.0',
9
- npmPublish: true,
10
- pkgRoot: '.',
11
- plugins: [
12
- {
13
- verifyConditions: (pluginConfig, context) => {
14
- console.log('Verifying conditions for semantic-release...');
15
-
16
- if (context.nextRelease && context.nextRelease.version) {
17
- if (!context.nextRelease.version.startsWith('0.')) {
18
- console.log(`Forcing version to start with 0: ${context.nextRelease.version} -> 0.${context.nextRelease.version}`);
19
- context.nextRelease.version = '0.' + context.nextRelease.version;
20
- }
21
- }
22
-
23
- const pkgPath = path.join(process.cwd(), 'package.json');
24
- if (fs.existsSync(pkgPath)) {
25
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
26
- if (!pkg.version.startsWith('0.')) {
27
- console.log(`Fixing package.json version: ${pkg.version} -> 0.1.0`);
28
- pkg.version = '0.1.0';
29
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
30
- }
31
- }
32
- },
33
- analyzeCommits: (pluginConfig, context) => {
34
- if (!context.lastRelease.version) {
35
- console.log('No previous version found, starting at 0.1.0-next.1');
36
- return '0.1.0-next.1'; // Start new packages at 0.1.0-next.1
37
- }
38
-
39
- console.log('Forcing patch release regardless of commit types');
40
- return 'patch';
41
- },
42
- prepare: (pluginConfig, context) => {
43
- console.log('Preparing for release...');
44
-
45
- const pkgPath = path.join(process.cwd(), 'package.json');
46
- if (fs.existsSync(pkgPath)) {
47
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
48
- let modified = false;
49
-
50
- const packageVersions = {};
51
- for (const pkgDir of ["/home/runner/work/ai/ai/sdks/actions.do","/home/runner/work/ai/ai/sdks/agents.do","/home/runner/work/ai/ai/sdks/analytics.do","/home/runner/work/ai/ai/sdks/apis.do","/home/runner/work/ai/ai/sdks/database.do","/home/runner/work/ai/ai/sdks/evals.do","/home/runner/work/ai/ai/sdks/experiments.do","/home/runner/work/ai/ai/sdks/functions.do","/home/runner/work/ai/ai/sdks/goals.do","/home/runner/work/ai/ai/sdks/gpt.do","/home/runner/work/ai/ai/sdks/integrations.do","/home/runner/work/ai/ai/sdks/llm.do","/home/runner/work/ai/ai/sdks/mcp.do","/home/runner/work/ai/ai/sdks/models.do","/home/runner/work/ai/ai/sdks/plans.do","/home/runner/work/ai/ai/sdks/projects.do","/home/runner/work/ai/ai/sdks/sdk.do","/home/runner/work/ai/ai/sdks/searches.do","/home/runner/work/ai/ai/sdks/tasks.do","/home/runner/work/ai/ai/sdks/triggers.do","/home/runner/work/ai/ai/sdks/workflows.do","/home/runner/work/ai/ai/pkgs/ai-business","/home/runner/work/ai/ai/pkgs/ai-database","/home/runner/work/ai/ai/pkgs/ai-functions","/home/runner/work/ai/ai/pkgs/ai-models","/home/runner/work/ai/ai/pkgs/ai-providers","/home/runner/work/ai/ai/pkgs/ai-workflows","/home/runner/work/ai/ai/pkgs/apis-do-searches","/home/runner/work/ai/ai/pkgs/apis-do-zapier","/home/runner/work/ai/ai/pkgs/business-as-code","/home/runner/work/ai/ai/pkgs/clickable-apis","/home/runner/work/ai/ai/pkgs/deploy-worker","/home/runner/work/ai/ai/pkgs/durable-objects-cron","/home/runner/work/ai/ai/pkgs/durable-objects-nosql","/home/runner/work/ai/ai/pkgs/eslint-config","/home/runner/work/ai/ai/pkgs/exec-symbols","/home/runner/work/ai/ai/pkgs/language-models","/home/runner/work/ai/ai/pkgs/mdxdb","/home/runner/work/ai/ai/pkgs/mdxld","/home/runner/work/ai/ai/pkgs/motion.md","/home/runner/work/ai/ai/pkgs/payload-agent","/home/runner/work/ai/ai/pkgs/payload-commandbar","/home/runner/work/ai/ai/pkgs/payload-hooks-queue","/home/runner/work/ai/ai/pkgs/payload-theme","/home/runner/work/ai/ai/pkgs/payload-utils","/home/runner/work/ai/ai/pkgs/payload-vscode","/home/runner/work/ai/ai/pkgs/payload-workos","/home/runner/work/ai/ai/pkgs/payload-zapier-apps","/home/runner/work/ai/ai/pkgs/services-as-software","/home/runner/work/ai/ai/pkgs/simple-payload","/home/runner/work/ai/ai/pkgs/tsconfig","/home/runner/work/ai/ai/pkgs/zapier-apis-do"]) {
52
- const pkgJsonPath = path.join(pkgDir, 'package.json');
53
- if (fs.existsSync(pkgJsonPath)) {
54
- const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
55
- packageVersions[pkgJson.name] = pkgJson.version || '0.1.0';
56
- }
57
- }
58
-
59
- if (pkg.dependencies) {
60
- for (const [dep, version] of Object.entries(pkg.dependencies)) {
61
- if (version.startsWith('workspace:')) {
62
- if (packageVersions[dep]) {
63
- console.log(`Converting workspace dependency ${dep} from ${version} to ${packageVersions[dep]}`);
64
- pkg.dependencies[dep] = packageVersions[dep];
65
- modified = true;
66
- }
67
- }
68
- }
69
- }
70
-
71
- if (pkg.devDependencies) {
72
- for (const [dep, version] of Object.entries(pkg.devDependencies)) {
73
- if (version.startsWith('workspace:')) {
74
- if (packageVersions[dep]) {
75
- console.log(`Converting workspace devDependency ${dep} from ${version} to ${packageVersions[dep]}`);
76
- pkg.devDependencies[dep] = packageVersions[dep];
77
- modified = true;
78
- }
79
- }
80
- }
81
- }
82
-
83
- if (pkg.peerDependencies) {
84
- for (const [dep, version] of Object.entries(pkg.peerDependencies)) {
85
- if (version.startsWith('workspace:')) {
86
- if (packageVersions[dep]) {
87
- console.log(`Converting workspace peerDependency ${dep} from ${version} to ${packageVersions[dep]}`);
88
- pkg.peerDependencies[dep] = packageVersions[dep];
89
- modified = true;
90
- }
91
- }
92
- }
93
- }
94
-
95
- if (modified) {
96
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
97
- console.log('Updated package.json with converted workspace dependencies before publishing');
98
- }
99
- }
100
- }
101
- },
102
- ['@semantic-release/commit-analyzer', {
103
- preset: 'angular',
104
- releaseRules: [
105
- {type: 'feat', release: 'patch'},
106
- {type: 'fix', release: 'patch'},
107
- {type: 'docs', release: 'patch'},
108
- {type: 'style', release: 'patch'},
109
- {type: 'refactor', release: 'patch'},
110
- {type: 'perf', release: 'patch'},
111
- {type: 'test', release: 'patch'},
112
- {type: 'build', release: 'patch'},
113
- {type: 'ci', release: 'patch'},
114
- {type: 'chore', release: 'patch'}
115
- ]
116
- }],
117
- ['@semantic-release/release-notes-generator', {
118
- writerOpts: {
119
- commitLimit: 100,
120
- }
121
- }],
122
- ['@semantic-release/npm', {
123
- npmPublish: true,
124
- pkgRoot: '.',
125
- npmTag: 'next'
126
- }],
127
- '@semantic-release/github'
128
- ]
129
- }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Driv.ly
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/dist/parser.d.ts DELETED
@@ -1,86 +0,0 @@
1
- import { Model, Provider } from './types';
2
- type InternalModel = Model;
3
- type ParsedModelIdentifier = {
4
- provider?: string;
5
- author?: string;
6
- model?: string;
7
- systemConfig?: Record<string, string | number>;
8
- alias?: string;
9
- priorities?: string[];
10
- providerConstraints?: {
11
- field: string;
12
- value: string;
13
- type: 'gt' | 'lt' | 'eq';
14
- }[];
15
- tools?: Record<string, string | number | boolean | Record<string, unknown>>;
16
- capabilities?: Record<string, string | number | boolean>;
17
- outputFormat?: string;
18
- outputSchema?: string;
19
- unasignedParameters?: Record<string, string | number | boolean>;
20
- };
21
- export declare function parse(modelIdentifier: string): ParsedModelIdentifier;
22
- export declare function constructModelIdentifier(parsed: ParsedModelIdentifier): string;
23
- export declare function modelToIdentifier(model: Model): string;
24
- type ResolvedModel = Model & {
25
- provider: Provider;
26
- };
27
- export declare function filterModels(modelIdentifier: string, modelsToFilter?: InternalModel[]): {
28
- models: ResolvedModel[];
29
- parsed: ParsedModelIdentifier;
30
- };
31
- /**
32
- * Helper function to get the first model that matches a model identifier
33
- * @param modelIdentifier
34
- * @returns ResolvedModel
35
- */
36
- export declare function getModel(modelIdentifier: string, augments?: Record<string, string | number | boolean | string[]>): {
37
- parsed: {
38
- provider?: string;
39
- author?: string;
40
- model?: string;
41
- systemConfig?: Record<string, string | number>;
42
- alias?: string;
43
- priorities?: string[];
44
- providerConstraints?: {
45
- field: string;
46
- value: string;
47
- type: "gt" | "lt" | "eq";
48
- }[];
49
- tools?: Record<string, string | number | boolean | Record<string, unknown>>;
50
- capabilities?: Record<string, string | number | boolean>;
51
- outputFormat?: string;
52
- outputSchema?: string;
53
- unasignedParameters?: Record<string, string | number | boolean>;
54
- };
55
- slug: string;
56
- hfSlug?: string | null;
57
- updatedAt: string;
58
- createdAt: string;
59
- hfUpdatedAt: null;
60
- name: string;
61
- shortName: string;
62
- author: string;
63
- description: string;
64
- modelVersionGroupId: string;
65
- contextLength: number;
66
- inputModalities: string[];
67
- outputModalities: string[];
68
- hasTextOutput: boolean;
69
- group: string;
70
- instructType: null;
71
- defaultSystem: null;
72
- defaultStops: any[];
73
- hidden: boolean;
74
- router: null;
75
- warningMessage: null;
76
- permaslug: string;
77
- reasoningConfig: null;
78
- endpoint?: import("./types").Endpoint | Provider;
79
- sorting?: import("./types").Sorting;
80
- providers?: Provider[];
81
- provider: Provider;
82
- };
83
- export declare function getModels(modelIdentifier: string): (Model & {
84
- parsed: ParsedModelIdentifier;
85
- })[];
86
- export {};
package/dist/parser.js DELETED
@@ -1,390 +0,0 @@
1
- import camelCase from 'camelcase';
2
- import { aliases } from './aliases';
3
- import rawModels from './models';
4
- const allModels = rawModels;
5
- // Priorities may be on its own, which indicates to just find the best value for that priority
6
- // or it may be in one of the following formats:
7
- // cost:<1 -> A model that has a cost of less than $1 per million tokens
8
- // latency:<50 -> A model with a latency of less than 50ms
9
- // throughput:>250 -> A model with a throughput higher than 250 tokens per second
10
- // Additional notes: if just cost is specified, then it will be treated as outputCost
11
- const priorities = ['cost', 'latency', 'throughput', 'inputCost', 'outputCost'];
12
- const capabilities = ['reasoning', 'thinking', 'tools', 'structuredOutput', 'responseFormat', 'pdf'];
13
- const defaultTools = ['exec', 'online'];
14
- const systemConfiguration = ['seed', 'thread', 'temperature', 'topP', 'topK'];
15
- // Any of the following is an output format, anything else that starts with a capital letter is an output *schema*
16
- const outputFormats = ['Object', 'ObjectArray', 'Text', 'TextArray', 'Markdown', 'Code'];
17
- export function parse(modelIdentifier) {
18
- const output = {
19
- model: '',
20
- };
21
- // Locate all paratheses, even nested ones
22
- const parentheses = modelIdentifier.match(/\(([^)]+)\)/g);
23
- output.model = modelIdentifier.split('(')[0];
24
- const modelName = output.model.includes('/') ? output.model.split('/')[1] : output.model;
25
- if (aliases[modelName]) {
26
- output.model = aliases[modelName];
27
- }
28
- if (output.model.includes('/')) {
29
- const [author, model] = output.model.split('/');
30
- output.author = author;
31
- output.model = model;
32
- }
33
- if (output.model.includes('@')) {
34
- // @ indicates a specific provider
35
- const [model, provider] = output.model.split('@');
36
- output.model = model;
37
- output.provider = provider;
38
- }
39
- // If there are no parentheses, then we can just return the model identifier
40
- if (!parentheses) {
41
- return output;
42
- }
43
- // Defaults storage allows us to set defaults for settings if they are missing from the input
44
- // The main use case is for output formats, where we want to set the format based on the schema
45
- // but only if the format isnt already set. Since we only have access to a single expression at once,
46
- // we need to store the defaults and apply them later.
47
- const defaultStorage = {};
48
- // Split by comma, each part is a new parameter that needs to be stored in the right
49
- // place in the output object
50
- // For each parathesis, we need to parse the contents
51
- for (const parenthesis of parentheses) {
52
- const contents = parenthesis.slice(1, -1);
53
- const parts = contents.split(',');
54
- for (const part of parts) {
55
- // Not all parts will have a colon, if not, treat it as a boolean with a value of true.
56
- const [key, value] = part
57
- // Cheat we can do to make the parsing easier
58
- .replace('<', ':<')
59
- .replace('>', ':>')
60
- .split(':');
61
- if (!key) {
62
- continue;
63
- }
64
- let notAKnownParameter = false;
65
- switch (true) {
66
- case defaultTools.includes(key):
67
- output.tools = output.tools || {};
68
- output.tools[key] = value || true;
69
- break;
70
- case systemConfiguration.includes(key):
71
- output.systemConfig = {
72
- ...output.systemConfig,
73
- [key]: value,
74
- };
75
- break;
76
- case priorities.includes(key):
77
- if (value) {
78
- output.providerConstraints = output.providerConstraints || [];
79
- output.providerConstraints.push({
80
- field: key,
81
- value: value.replace('>', '').replace('<', ''),
82
- type: value.startsWith('>') ? 'gt' : value.startsWith('<') ? 'lt' : 'eq',
83
- });
84
- }
85
- else {
86
- output.priorities = [...(output.priorities || []), key];
87
- }
88
- break;
89
- case capabilities.includes(key):
90
- output.capabilities = {
91
- ...output.capabilities,
92
- [key]: value || true,
93
- };
94
- break;
95
- case outputFormats.includes(key):
96
- output.outputFormat = key == 'Code' && !!value ? `Code:${value}` : key;
97
- break;
98
- default:
99
- notAKnownParameter = true;
100
- break;
101
- }
102
- if (!notAKnownParameter) {
103
- // No need to process any further
104
- continue;
105
- }
106
- // If it starts with a capital letter, then it is a Schema
107
- if (key[0] === key[0].toUpperCase()) {
108
- const schema = key;
109
- if (schema.includes('[]')) {
110
- defaultStorage.outputFormat = 'ObjectArray';
111
- }
112
- else {
113
- defaultStorage.outputFormat = 'Object';
114
- }
115
- output.outputSchema = schema.replace('[]', '');
116
- }
117
- else if (value?.includes('>') || value?.includes('<')) {
118
- // This is most likely a benchmark constraint
119
- output.providerConstraints = output.providerConstraints || [];
120
- output.providerConstraints.push({
121
- field: key,
122
- value: value.replace('>', '').replace('<', ''),
123
- type: value.startsWith('>') ? 'gt' : 'lt',
124
- });
125
- }
126
- else {
127
- output.tools = output.tools || {};
128
- output.tools = {
129
- ...output.tools,
130
- [key]: value || true,
131
- };
132
- }
133
- }
134
- }
135
- // Custom rules / requirements
136
- // If someone has tools, they need to have the tools capability
137
- if (Object.values(output.tools || {}).length > 0) {
138
- if (!output.capabilities?.tools) {
139
- output.capabilities = {
140
- ...output.capabilities,
141
- tools: true,
142
- };
143
- }
144
- }
145
- // Finally, apply the defaults
146
- Object.entries(defaultStorage).forEach(([key, value]) => {
147
- const keyToCheck = key;
148
- if (output[keyToCheck] === undefined) {
149
- // @ts-expect-error - We know these assignments are safe based on our defaultStorage logic
150
- output[keyToCheck] = value;
151
- }
152
- });
153
- return output;
154
- }
155
- export function constructModelIdentifier(parsed) {
156
- const modelAlias = aliases[parsed.model || ''] || parsed.model || '';
157
- let identifier = `${modelAlias}`;
158
- if (parsed.provider) {
159
- identifier += `@${parsed.provider}`;
160
- }
161
- const args = [];
162
- const formatArgument = (key, value) => {
163
- // If the value is a boolean, then we can just return the key
164
- if (typeof value === 'boolean') {
165
- return value ? key : '';
166
- }
167
- console.log(key, value);
168
- // Otherwise, we need to format the value
169
- return `${key}:${value}`;
170
- };
171
- const keysToFormat = ['capabilities', 'tools', 'systemConfig'];
172
- keysToFormat.forEach((key) => {
173
- if (parsed[key]) {
174
- Object.entries(parsed[key]).forEach(([key, value]) => {
175
- args.push(formatArgument(key, value));
176
- });
177
- }
178
- });
179
- if (parsed.priorities) {
180
- parsed.priorities.forEach((priority) => {
181
- args.push(priority);
182
- });
183
- }
184
- // Provider constraints are a bit more complex as they are stored as { field: string, value: string }[]
185
- if (parsed.providerConstraints) {
186
- parsed.providerConstraints.forEach((constraint) => {
187
- args.push(`${constraint.field}${constraint.type === 'gt' ? '>' : constraint.type === 'lt' ? '<' : ':'}${constraint.value}`);
188
- });
189
- }
190
- if (args.length) {
191
- identifier += `(${args.join(',')})`;
192
- }
193
- return identifier;
194
- }
195
- export function modelToIdentifier(model) {
196
- return constructModelIdentifier({
197
- model: model.slug.split('/')[1],
198
- provider: model.slug.split('/')[0],
199
- });
200
- }
201
- export function filterModels(modelIdentifier, modelsToFilter) {
202
- const parsed = parse(modelIdentifier);
203
- const modelAndProviders = [];
204
- let modelsToFilterMixin = modelsToFilter;
205
- if (metaModels.find((m) => m.name === parsed.model) && !modelsToFilter?.length) {
206
- const metaModelChildren = metaModels.find((m) => m.name === parsed.model)?.models;
207
- modelsToFilterMixin = allModels.models.filter((m) => metaModelChildren?.includes(m.slug.split('/')[1]));
208
- // Because the parser has no model knowledge, it thinks the meta model name is the model name
209
- // Which will always return false.
210
- delete parsed.model;
211
- }
212
- else if (modelsToFilter?.length) {
213
- modelsToFilterMixin = modelsToFilter;
214
- }
215
- else {
216
- modelsToFilterMixin = allModels.models;
217
- }
218
- const filterChain = [];
219
- if (parsed.model) {
220
- filterChain.push(function modelFilter(model) {
221
- // Wildcard search for any model that matches everything else.
222
- if (parsed.model == '*') {
223
- return true;
224
- }
225
- // Return true if we're looking for claude-3.7-sonnet
226
- // Fixes the issue where we need :thinking to be supported
227
- if (parsed.model === 'claude-3.7-sonnet' && model.slug.includes('claude-3.7-sonnet') && !model.slug.includes('beta')) {
228
- return true;
229
- }
230
- return model.slug.split('/')[1] === parsed.model;
231
- });
232
- }
233
- // We're using named functions here so we can console.log the filter chain
234
- // and see what filter is being applied and when
235
- if (parsed.provider) {
236
- filterChain.push(function providerFilter(model, provider) {
237
- return provider?.slug === parsed.provider;
238
- });
239
- }
240
- if (parsed?.providerConstraints?.length) {
241
- // Since the provider isnt defined, we need to filter based on the provider constraints
242
- filterChain.push(function providerConstraintFilter(model, provider) {
243
- return (parsed?.providerConstraints?.every((constraint) => {
244
- if (!provider) {
245
- return false;
246
- }
247
- let fieldToCheck = constraint.field;
248
- if (constraint.field === 'cost') {
249
- fieldToCheck = 'outputCost';
250
- }
251
- switch (constraint.type) {
252
- case 'gt':
253
- return Number(provider[fieldToCheck]) > parseFloat(constraint.value);
254
- case 'lt':
255
- return Number(provider[fieldToCheck]) < parseFloat(constraint.value);
256
- case 'eq':
257
- return Number(provider[fieldToCheck]) === parseFloat(constraint.value);
258
- default:
259
- return false;
260
- }
261
- }) || false);
262
- });
263
- }
264
- if (parsed.capabilities) {
265
- filterChain.push(function capabilitiesFilter(model, provider) {
266
- return Object.entries(parsed?.capabilities || {}).every(([key, value]) => {
267
- return provider?.supportedParameters?.includes(camelCase(key));
268
- });
269
- });
270
- }
271
- for (const model of modelsToFilterMixin) {
272
- for (const provider of model.providers || []) {
273
- if (filterChain.every((f) => f(model, provider))) {
274
- modelAndProviders.push({
275
- model,
276
- provider: provider,
277
- });
278
- }
279
- }
280
- }
281
- const orderBy = (fields) => (a, b) => fields
282
- .map((o) => {
283
- let dir = 1;
284
- if (o[0] === '-') {
285
- dir = -1;
286
- o = o.substring(1);
287
- }
288
- // Support for dot notation to access nested properties
289
- const getNestedValue = (obj, path) => {
290
- return path.split('.').reduce((prev, curr) => (prev && prev[curr] !== undefined ? prev[curr] : undefined), obj);
291
- };
292
- const aVal = getNestedValue(a, o);
293
- const bVal = getNestedValue(b, o);
294
- return aVal > bVal ? dir : aVal < bVal ? -dir : 0;
295
- })
296
- .reduce((p, n) => (p ? p : n), 0);
297
- let sortingStrategy = orderBy(parsed?.priorities?.map((f) => `provider.${f}`) || []);
298
- // Re-join back on model, replacing the providers with the filtered providers
299
- return {
300
- models: modelAndProviders
301
- .map((x) => ({
302
- ...x.model,
303
- provider: x.provider,
304
- }))
305
- .map((x) => {
306
- delete x.providers;
307
- delete x.endpoint;
308
- return x;
309
- })
310
- .sort(sortingStrategy),
311
- parsed,
312
- };
313
- }
314
- /**
315
- * Helper function to get the first model that matches a model identifier
316
- * @param modelIdentifier
317
- * @returns ResolvedModel
318
- */
319
- export function getModel(modelIdentifier, augments = {}) {
320
- // Inject the augments into the model string inside the parentheses
321
- // Keeping the content of the parentheses intact
322
- const parentheses = modelIdentifier.match(/\(([^)]+)\)/);
323
- const augmentsString = [];
324
- Object.entries(augments).forEach(([key, value]) => {
325
- if (key == 'seed')
326
- augmentsString.push(`seed:${value}`);
327
- else if (key == 'temperature')
328
- augmentsString.push(`temperature:${value}`);
329
- else if (key == 'topP')
330
- augmentsString.push(`topP:${value}`);
331
- else if (key == 'topK')
332
- augmentsString.push(`topK:${value}`);
333
- else if (key == 'thread')
334
- augmentsString.push(`thread:${value}`);
335
- else if (key == 'requiredCapabilities') {
336
- for (const capability of value) {
337
- augmentsString.push(capability);
338
- }
339
- }
340
- else
341
- augmentsString.push(`${key}:${value}`);
342
- });
343
- if (parentheses) {
344
- modelIdentifier = modelIdentifier.replace(parentheses[0], `(${parentheses[1]},${augmentsString.filter(Boolean).join(',')})`);
345
- }
346
- else {
347
- if (augmentsString.length) {
348
- modelIdentifier += `(${augmentsString.join(',')})`;
349
- }
350
- }
351
- const parsed = parse(modelIdentifier);
352
- const { models } = filterModels(modelIdentifier);
353
- return {
354
- ...models[0],
355
- parsed: {
356
- ...parsed,
357
- ...augments,
358
- },
359
- };
360
- }
361
- export function getModels(modelIdentifier) {
362
- // Split the modelIdentifier by comma, ignoring commas inside parentheses
363
- let result = [];
364
- let segment = '';
365
- let depth = 0;
366
- for (const char of modelIdentifier) {
367
- if (char === '(')
368
- depth++;
369
- else if (char === ')')
370
- depth--;
371
- else if (char === ',' && depth === 0) {
372
- result.push(segment.trim());
373
- segment = '';
374
- continue;
375
- }
376
- segment += char;
377
- }
378
- if (segment.trim())
379
- result.push(segment.trim());
380
- // Resolve each segment
381
- return result.map((r) => getModel(r));
382
- }
383
- // TODO: Move this to a database or another source of truth
384
- // This isnt a good place for this data.
385
- const metaModels = [
386
- {
387
- name: 'frontier',
388
- models: ['gemini-2.0-flash-001', 'deepseek-r1'],
389
- },
390
- ];
@@ -1 +0,0 @@
1
- export declare const getProviderName: (provider: string) => string | undefined;