language-models 0.1.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.
@@ -0,0 +1,86 @@
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 ADDED
@@ -0,0 +1,390 @@
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
+ ];
@@ -0,0 +1 @@
1
+ export declare const getProviderName: (provider: string) => string | undefined;
@@ -0,0 +1,76 @@
1
+ import camelCase from 'camelcase';
2
+ const allProviders = [
3
+ 'OpenAI',
4
+ 'Anthropic',
5
+ 'Google',
6
+ 'Google AI Studio',
7
+ 'Amazon Bedrock',
8
+ 'Groq',
9
+ 'SambaNova',
10
+ 'Cohere',
11
+ 'Mistral',
12
+ 'Together',
13
+ 'Together 2',
14
+ 'Fireworks',
15
+ 'DeepInfra',
16
+ 'Lepton',
17
+ 'Novita',
18
+ 'Avian',
19
+ 'Lambda',
20
+ 'Azure',
21
+ 'Modal',
22
+ 'AnyScale',
23
+ 'Replicate',
24
+ 'Perplexity',
25
+ 'Recursal',
26
+ 'OctoAI',
27
+ 'DeepSeek',
28
+ 'Infermatic',
29
+ 'AI21',
30
+ 'Featherless',
31
+ 'Inflection',
32
+ 'xAI',
33
+ 'Cloudflare',
34
+ 'SF Compute',
35
+ 'Minimax',
36
+ 'Nineteen',
37
+ 'Liquid',
38
+ 'Stealth',
39
+ 'NCompass',
40
+ 'InferenceNet',
41
+ 'Friendli',
42
+ 'AionLabs',
43
+ 'Alibaba',
44
+ 'Nebius',
45
+ 'Chutes',
46
+ 'Kluster',
47
+ 'Crusoe',
48
+ 'Targon',
49
+ 'Ubicloud',
50
+ 'Parasail',
51
+ 'Phala',
52
+ 'Cent-ML',
53
+ 'Venice',
54
+ 'OpenInference',
55
+ 'Atoma',
56
+ '01.AI',
57
+ 'HuggingFace',
58
+ 'Mancer',
59
+ 'Mancer 2',
60
+ 'Hyperbolic',
61
+ 'Hyperbolic 2',
62
+ 'Lynn 2',
63
+ 'Lynn',
64
+ 'Reflection',
65
+ ];
66
+ export const getProviderName = (provider) => {
67
+ // Reverse a camelCase string into the provider's name
68
+ switch (provider) {
69
+ case 'vertex':
70
+ return 'Google';
71
+ case 'google':
72
+ return 'Google AI Studio';
73
+ default:
74
+ return allProviders.find((p) => camelCase(p) === provider);
75
+ }
76
+ };
@@ -0,0 +1,127 @@
1
+ export type Endpoint = {
2
+ id: string;
3
+ name: string;
4
+ contextLength: number;
5
+ model: Model;
6
+ modelVariantSlug: string;
7
+ modelVariantPermaslug: string;
8
+ providerName: string;
9
+ providerInfo: ProviderInfo;
10
+ providerDisplayName: string;
11
+ providerModelId: string;
12
+ providerGroup: string;
13
+ isCloaked: boolean;
14
+ quantization: null;
15
+ variant: string;
16
+ isSelfHosted: boolean;
17
+ canAbort: boolean;
18
+ maxPromptTokens: null;
19
+ maxCompletionTokens: number;
20
+ maxPromptImages: null;
21
+ maxTokensPerImage: null;
22
+ supportedParameters: string[];
23
+ isByok: boolean;
24
+ moderationRequired: boolean;
25
+ dataPolicy: DataPolicy;
26
+ pricing: Pricing;
27
+ isHidden: boolean;
28
+ isDeranked: boolean;
29
+ isDisabled: boolean;
30
+ supportsToolParameters: boolean;
31
+ supportsReasoning: boolean;
32
+ supportsMultipart: boolean;
33
+ limitRpm: number;
34
+ limitRpd: null;
35
+ hasCompletions: boolean;
36
+ hasChatCompletions: boolean;
37
+ features: Features;
38
+ providerRegion: null;
39
+ };
40
+ export type Model = {
41
+ slug: string;
42
+ hfSlug?: string | null;
43
+ updatedAt: string;
44
+ createdAt: string;
45
+ hfUpdatedAt: null;
46
+ name: string;
47
+ shortName: string;
48
+ author: string;
49
+ description: string;
50
+ modelVersionGroupId: string;
51
+ contextLength: number;
52
+ inputModalities: string[];
53
+ outputModalities: string[];
54
+ hasTextOutput: boolean;
55
+ group: string;
56
+ instructType: null;
57
+ defaultSystem: null;
58
+ defaultStops: any[];
59
+ hidden: boolean;
60
+ router: null;
61
+ warningMessage: null;
62
+ permaslug: string;
63
+ reasoningConfig: null;
64
+ endpoint?: Endpoint | Provider;
65
+ sorting?: Sorting;
66
+ providers?: Provider[];
67
+ provider?: Provider;
68
+ };
69
+ export type DataPolicy = {
70
+ termsOfServiceUrl: string;
71
+ privacyPolicyUrl: string;
72
+ training: boolean;
73
+ };
74
+ export type Features = {};
75
+ export type Pricing = {
76
+ prompt: string;
77
+ completion: string;
78
+ image: string;
79
+ request: string;
80
+ inputCacheRead: string;
81
+ inputCacheWrite: string;
82
+ webSearch: string;
83
+ internalReasoning: string;
84
+ };
85
+ export type ProviderInfo = {
86
+ name: string;
87
+ displayName: string;
88
+ baseUrl: string;
89
+ dataPolicy: DataPolicy;
90
+ headquarters: string;
91
+ hasChatCompletions: boolean;
92
+ hasCompletions: boolean;
93
+ isAbortable: boolean;
94
+ moderationRequired: boolean;
95
+ group: string;
96
+ editors: any[];
97
+ owners: any[];
98
+ isMultipartSupported: boolean;
99
+ statusPageUrl: null;
100
+ byokEnabled: boolean;
101
+ isPrimaryProvider: boolean;
102
+ icon: Icon;
103
+ };
104
+ export type Icon = {
105
+ url: string;
106
+ };
107
+ export type Provider = {
108
+ name: string;
109
+ slug: string;
110
+ quantization: string | null;
111
+ context: number;
112
+ maxCompletionTokens: number;
113
+ pricing: Pricing;
114
+ supportedParameters: string[];
115
+ inputCost: number;
116
+ outputCost: number;
117
+ throughput: number;
118
+ latency: number;
119
+ };
120
+ export type Sorting = {
121
+ topWeekly: number;
122
+ newest: number;
123
+ throughputHighToLow: number;
124
+ latencyLowToHigh: number;
125
+ pricingLowToHigh: number;
126
+ pricingHighToLow: number;
127
+ };
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import tsConfig from 'eslint-config/typescript'
2
+
3
+ export default tsConfig