@contractspec/lib.ai-providers 2.9.0 → 3.1.1
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 +19 -9
- package/dist/browser/factory.js +107 -85
- package/dist/browser/index.js +276 -85
- package/dist/browser/legacy.js +107 -85
- package/dist/browser/models.js +49 -1
- package/dist/browser/selector-types.js +0 -0
- package/dist/browser/selector.js +693 -0
- package/dist/browser/validation.js +107 -85
- package/dist/factory.js +107 -85
- package/dist/index.d.ts +3 -0
- package/dist/index.js +276 -85
- package/dist/legacy.js +107 -85
- package/dist/models.js +49 -1
- package/dist/models.test.d.ts +1 -0
- package/dist/node/factory.js +107 -85
- package/dist/node/index.js +276 -85
- package/dist/node/legacy.js +107 -85
- package/dist/node/models.js +49 -1
- package/dist/node/selector-types.js +0 -0
- package/dist/node/selector.js +693 -0
- package/dist/node/validation.js +107 -85
- package/dist/selector-types.d.ts +50 -0
- package/dist/selector-types.js +1 -0
- package/dist/selector.d.ts +16 -0
- package/dist/selector.js +694 -0
- package/dist/types.d.ts +13 -1
- package/dist/validation.js +107 -85
- package/package.json +37 -8
package/dist/types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type ProviderName = 'ollama' | 'openai' | 'anthropic' | 'mistral' | 'gemi
|
|
|
9
9
|
/**
|
|
10
10
|
* Legacy provider names (for backwards compatibility)
|
|
11
11
|
*/
|
|
12
|
-
export type LegacyProviderName = 'claude' | 'openai' | 'ollama' | 'custom';
|
|
12
|
+
export type LegacyProviderName = 'claude' | 'openai' | 'ollama' | 'custom' | 'mistral';
|
|
13
13
|
/**
|
|
14
14
|
* Provider mode determines how API keys are resolved
|
|
15
15
|
*/
|
|
@@ -30,6 +30,14 @@ export interface ProviderConfig {
|
|
|
30
30
|
proxyUrl?: string;
|
|
31
31
|
/** Organization/tenant ID for managed mode */
|
|
32
32
|
organizationId?: string;
|
|
33
|
+
/** Transport mode for the provider connection. */
|
|
34
|
+
transport?: 'rest' | 'mcp' | 'sdk';
|
|
35
|
+
/** Auth method used for this provider connection. */
|
|
36
|
+
authMethod?: 'api-key' | 'oauth2' | 'bearer';
|
|
37
|
+
/** Provider API version to target. */
|
|
38
|
+
apiVersion?: string;
|
|
39
|
+
/** Custom headers to include in requests. */
|
|
40
|
+
customHeaders?: Record<string, string>;
|
|
33
41
|
}
|
|
34
42
|
/**
|
|
35
43
|
* Model capability flags
|
|
@@ -98,6 +106,10 @@ export interface ProviderAvailability {
|
|
|
98
106
|
available: boolean;
|
|
99
107
|
mode: ProviderMode;
|
|
100
108
|
reason?: string;
|
|
109
|
+
/** Transports available for this provider. */
|
|
110
|
+
transports?: ('rest' | 'mcp' | 'sdk')[];
|
|
111
|
+
/** Auth methods available for this provider. */
|
|
112
|
+
authMethods?: ('api-key' | 'oauth2' | 'bearer')[];
|
|
101
113
|
}
|
|
102
114
|
/**
|
|
103
115
|
* Legacy Config type for backwards compatibility
|
package/dist/validation.js
CHANGED
|
@@ -160,11 +160,23 @@ var MODELS = [
|
|
|
160
160
|
},
|
|
161
161
|
costPerMillion: { input: 2, output: 6 }
|
|
162
162
|
},
|
|
163
|
+
{
|
|
164
|
+
id: "mistral-medium-latest",
|
|
165
|
+
name: "Mistral Medium",
|
|
166
|
+
provider: "mistral",
|
|
167
|
+
contextWindow: 128000,
|
|
168
|
+
capabilities: {
|
|
169
|
+
vision: false,
|
|
170
|
+
tools: true,
|
|
171
|
+
reasoning: false,
|
|
172
|
+
streaming: true
|
|
173
|
+
}
|
|
174
|
+
},
|
|
163
175
|
{
|
|
164
176
|
id: "codestral-latest",
|
|
165
177
|
name: "Codestral",
|
|
166
178
|
provider: "mistral",
|
|
167
|
-
contextWindow:
|
|
179
|
+
contextWindow: 256000,
|
|
168
180
|
capabilities: {
|
|
169
181
|
vision: false,
|
|
170
182
|
tools: true,
|
|
@@ -173,6 +185,42 @@ var MODELS = [
|
|
|
173
185
|
},
|
|
174
186
|
costPerMillion: { input: 0.2, output: 0.6 }
|
|
175
187
|
},
|
|
188
|
+
{
|
|
189
|
+
id: "devstral-small-latest",
|
|
190
|
+
name: "Devstral Small",
|
|
191
|
+
provider: "mistral",
|
|
192
|
+
contextWindow: 128000,
|
|
193
|
+
capabilities: {
|
|
194
|
+
vision: false,
|
|
195
|
+
tools: true,
|
|
196
|
+
reasoning: true,
|
|
197
|
+
streaming: true
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
id: "magistral-medium-latest",
|
|
202
|
+
name: "Magistral Medium",
|
|
203
|
+
provider: "mistral",
|
|
204
|
+
contextWindow: 128000,
|
|
205
|
+
capabilities: {
|
|
206
|
+
vision: false,
|
|
207
|
+
tools: true,
|
|
208
|
+
reasoning: true,
|
|
209
|
+
streaming: true
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: "pixtral-large-latest",
|
|
214
|
+
name: "Pixtral Large",
|
|
215
|
+
provider: "mistral",
|
|
216
|
+
contextWindow: 128000,
|
|
217
|
+
capabilities: {
|
|
218
|
+
vision: true,
|
|
219
|
+
tools: true,
|
|
220
|
+
reasoning: false,
|
|
221
|
+
streaming: true
|
|
222
|
+
}
|
|
223
|
+
},
|
|
176
224
|
{
|
|
177
225
|
id: "mistral-small-latest",
|
|
178
226
|
name: "Mistral Small",
|
|
@@ -241,22 +289,30 @@ function getDefaultModel(provider) {
|
|
|
241
289
|
}
|
|
242
290
|
|
|
243
291
|
// src/factory.ts
|
|
244
|
-
import {
|
|
245
|
-
import {
|
|
246
|
-
import {
|
|
247
|
-
import {
|
|
248
|
-
import {
|
|
292
|
+
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
293
|
+
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
294
|
+
import { createMistral } from "@ai-sdk/mistral";
|
|
295
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
296
|
+
import { createOllama } from "ollama-ai-provider";
|
|
249
297
|
class BaseProvider {
|
|
250
298
|
name;
|
|
251
299
|
model;
|
|
252
300
|
mode;
|
|
253
301
|
config;
|
|
302
|
+
transport;
|
|
303
|
+
authMethod;
|
|
304
|
+
apiVersion;
|
|
305
|
+
customHeaders;
|
|
254
306
|
cachedModel = null;
|
|
255
307
|
constructor(config) {
|
|
256
308
|
this.name = config.provider;
|
|
257
309
|
this.model = config.model ?? DEFAULT_MODELS[config.provider];
|
|
258
310
|
this.mode = this.determineMode(config);
|
|
259
311
|
this.config = config;
|
|
312
|
+
this.transport = config.transport;
|
|
313
|
+
this.authMethod = config.authMethod;
|
|
314
|
+
this.apiVersion = config.apiVersion;
|
|
315
|
+
this.customHeaders = config.customHeaders;
|
|
260
316
|
}
|
|
261
317
|
getModel() {
|
|
262
318
|
if (!this.cachedModel) {
|
|
@@ -296,81 +352,33 @@ class BaseProvider {
|
|
|
296
352
|
return "managed";
|
|
297
353
|
}
|
|
298
354
|
createModel() {
|
|
299
|
-
const { baseUrl, proxyUrl } = this.config;
|
|
355
|
+
const { baseUrl, proxyUrl, apiKey } = this.config;
|
|
356
|
+
const headers = this.customHeaders;
|
|
357
|
+
if (this.name === "ollama") {
|
|
358
|
+
const provider = createOllama({ baseURL: baseUrl, headers });
|
|
359
|
+
return provider(this.model);
|
|
360
|
+
}
|
|
361
|
+
if (this.mode === "managed" && proxyUrl) {
|
|
362
|
+
const provider = createOpenAI({ baseURL: proxyUrl, apiKey, headers });
|
|
363
|
+
return provider(this.model);
|
|
364
|
+
}
|
|
300
365
|
switch (this.name) {
|
|
301
|
-
case "
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
366
|
+
case "openai": {
|
|
367
|
+
const provider = createOpenAI({ apiKey, headers });
|
|
368
|
+
return provider(this.model);
|
|
369
|
+
}
|
|
370
|
+
case "anthropic": {
|
|
371
|
+
const provider = createAnthropic({ apiKey, headers });
|
|
372
|
+
return provider(this.model);
|
|
373
|
+
}
|
|
374
|
+
case "mistral": {
|
|
375
|
+
const provider = createMistral({ apiKey, headers });
|
|
376
|
+
return provider(this.model);
|
|
377
|
+
}
|
|
378
|
+
case "gemini": {
|
|
379
|
+
const provider = createGoogleGenerativeAI({ apiKey, headers });
|
|
380
|
+
return provider(this.model);
|
|
313
381
|
}
|
|
314
|
-
case "openai":
|
|
315
|
-
if (this.mode === "managed") {
|
|
316
|
-
const originalBaseUrl = process.env.OPENAI_BASE_URL;
|
|
317
|
-
if (proxyUrl) {
|
|
318
|
-
process.env.OPENAI_BASE_URL = proxyUrl;
|
|
319
|
-
}
|
|
320
|
-
const model = openai(this.model);
|
|
321
|
-
if (originalBaseUrl !== undefined) {
|
|
322
|
-
process.env.OPENAI_BASE_URL = originalBaseUrl;
|
|
323
|
-
} else if (proxyUrl) {
|
|
324
|
-
delete process.env.OPENAI_BASE_URL;
|
|
325
|
-
}
|
|
326
|
-
return model;
|
|
327
|
-
}
|
|
328
|
-
return openai(this.model);
|
|
329
|
-
case "anthropic":
|
|
330
|
-
if (this.mode === "managed") {
|
|
331
|
-
const originalBaseUrl = process.env.OPENAI_BASE_URL;
|
|
332
|
-
if (proxyUrl) {
|
|
333
|
-
process.env.OPENAI_BASE_URL = proxyUrl;
|
|
334
|
-
}
|
|
335
|
-
const model = openai(this.model);
|
|
336
|
-
if (originalBaseUrl !== undefined) {
|
|
337
|
-
process.env.OPENAI_BASE_URL = originalBaseUrl;
|
|
338
|
-
} else if (proxyUrl) {
|
|
339
|
-
delete process.env.OPENAI_BASE_URL;
|
|
340
|
-
}
|
|
341
|
-
return model;
|
|
342
|
-
}
|
|
343
|
-
return anthropic(this.model);
|
|
344
|
-
case "mistral":
|
|
345
|
-
if (this.mode === "managed") {
|
|
346
|
-
const originalBaseUrl = process.env.OPENAI_BASE_URL;
|
|
347
|
-
if (proxyUrl) {
|
|
348
|
-
process.env.OPENAI_BASE_URL = proxyUrl;
|
|
349
|
-
}
|
|
350
|
-
const model = openai(this.model);
|
|
351
|
-
if (originalBaseUrl !== undefined) {
|
|
352
|
-
process.env.OPENAI_BASE_URL = originalBaseUrl;
|
|
353
|
-
} else if (proxyUrl) {
|
|
354
|
-
delete process.env.OPENAI_BASE_URL;
|
|
355
|
-
}
|
|
356
|
-
return model;
|
|
357
|
-
}
|
|
358
|
-
return mistral(this.model);
|
|
359
|
-
case "gemini":
|
|
360
|
-
if (this.mode === "managed") {
|
|
361
|
-
const originalBaseUrl = process.env.OPENAI_BASE_URL;
|
|
362
|
-
if (proxyUrl) {
|
|
363
|
-
process.env.OPENAI_BASE_URL = proxyUrl;
|
|
364
|
-
}
|
|
365
|
-
const model = openai(this.model);
|
|
366
|
-
if (originalBaseUrl !== undefined) {
|
|
367
|
-
process.env.OPENAI_BASE_URL = originalBaseUrl;
|
|
368
|
-
} else if (proxyUrl) {
|
|
369
|
-
delete process.env.OPENAI_BASE_URL;
|
|
370
|
-
}
|
|
371
|
-
return model;
|
|
372
|
-
}
|
|
373
|
-
return google(this.model);
|
|
374
382
|
default:
|
|
375
383
|
throw new Error(`Unknown provider: ${this.name}`);
|
|
376
384
|
}
|
|
@@ -452,13 +460,17 @@ function createProviderFromEnv() {
|
|
|
452
460
|
case "ollama":
|
|
453
461
|
break;
|
|
454
462
|
}
|
|
463
|
+
const transport = process.env.CONTRACTSPEC_AI_TRANSPORT;
|
|
464
|
+
const apiVersion = process.env.CONTRACTSPEC_AI_API_VERSION;
|
|
455
465
|
return createProvider({
|
|
456
466
|
provider,
|
|
457
467
|
model,
|
|
458
468
|
apiKey,
|
|
459
469
|
baseUrl: process.env.OLLAMA_BASE_URL,
|
|
460
470
|
proxyUrl: process.env.CONTRACTSPEC_AI_PROXY_URL,
|
|
461
|
-
organizationId: process.env.CONTRACTSPEC_ORG_ID
|
|
471
|
+
organizationId: process.env.CONTRACTSPEC_ORG_ID,
|
|
472
|
+
transport,
|
|
473
|
+
apiVersion
|
|
462
474
|
});
|
|
463
475
|
}
|
|
464
476
|
function getAvailableProviders() {
|
|
@@ -466,35 +478,45 @@ function getAvailableProviders() {
|
|
|
466
478
|
providers.push({
|
|
467
479
|
provider: "ollama",
|
|
468
480
|
available: true,
|
|
469
|
-
mode: "local"
|
|
481
|
+
mode: "local",
|
|
482
|
+
transports: ["rest", "sdk"],
|
|
483
|
+
authMethods: []
|
|
470
484
|
});
|
|
471
485
|
const openaiKey = process.env.OPENAI_API_KEY;
|
|
472
486
|
providers.push({
|
|
473
487
|
provider: "openai",
|
|
474
488
|
available: Boolean(openaiKey) || Boolean(process.env.CONTRACTSPEC_AI_PROXY_URL),
|
|
475
489
|
mode: openaiKey ? "byok" : "managed",
|
|
476
|
-
reason: !openaiKey ? "Set OPENAI_API_KEY for BYOK mode" : undefined
|
|
490
|
+
reason: !openaiKey ? "Set OPENAI_API_KEY for BYOK mode" : undefined,
|
|
491
|
+
transports: ["rest", "sdk"],
|
|
492
|
+
authMethods: ["api-key"]
|
|
477
493
|
});
|
|
478
494
|
const anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
479
495
|
providers.push({
|
|
480
496
|
provider: "anthropic",
|
|
481
497
|
available: Boolean(anthropicKey) || Boolean(process.env.CONTRACTSPEC_AI_PROXY_URL),
|
|
482
498
|
mode: anthropicKey ? "byok" : "managed",
|
|
483
|
-
reason: !anthropicKey ? "Set ANTHROPIC_API_KEY for BYOK mode" : undefined
|
|
499
|
+
reason: !anthropicKey ? "Set ANTHROPIC_API_KEY for BYOK mode" : undefined,
|
|
500
|
+
transports: ["rest", "sdk"],
|
|
501
|
+
authMethods: ["api-key"]
|
|
484
502
|
});
|
|
485
503
|
const mistralKey = process.env.MISTRAL_API_KEY;
|
|
486
504
|
providers.push({
|
|
487
505
|
provider: "mistral",
|
|
488
506
|
available: Boolean(mistralKey) || Boolean(process.env.CONTRACTSPEC_AI_PROXY_URL),
|
|
489
507
|
mode: mistralKey ? "byok" : "managed",
|
|
490
|
-
reason: !mistralKey ? "Set MISTRAL_API_KEY for BYOK mode" : undefined
|
|
508
|
+
reason: !mistralKey ? "Set MISTRAL_API_KEY for BYOK mode" : undefined,
|
|
509
|
+
transports: ["rest", "sdk"],
|
|
510
|
+
authMethods: ["api-key"]
|
|
491
511
|
});
|
|
492
512
|
const geminiKey = process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;
|
|
493
513
|
providers.push({
|
|
494
514
|
provider: "gemini",
|
|
495
515
|
available: Boolean(geminiKey) || Boolean(process.env.CONTRACTSPEC_AI_PROXY_URL),
|
|
496
516
|
mode: geminiKey ? "byok" : "managed",
|
|
497
|
-
reason: !geminiKey ? "Set GOOGLE_API_KEY for BYOK mode" : undefined
|
|
517
|
+
reason: !geminiKey ? "Set GOOGLE_API_KEY for BYOK mode" : undefined,
|
|
518
|
+
transports: ["rest", "sdk"],
|
|
519
|
+
authMethods: ["api-key"]
|
|
498
520
|
});
|
|
499
521
|
return providers;
|
|
500
522
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractspec/lib.ai-providers",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "Unified AI provider abstraction layer",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contractspec",
|
|
@@ -33,18 +33,19 @@
|
|
|
33
33
|
"typecheck": "tsc --noEmit"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@ai-sdk/anthropic": "3.0.
|
|
37
|
-
"@ai-sdk/google": "3.0.
|
|
38
|
-
"@ai-sdk/mistral": "3.0.
|
|
39
|
-
"@ai-sdk/openai": "3.0.
|
|
40
|
-
"
|
|
36
|
+
"@ai-sdk/anthropic": "3.0.58",
|
|
37
|
+
"@ai-sdk/google": "3.0.43",
|
|
38
|
+
"@ai-sdk/mistral": "3.0.24",
|
|
39
|
+
"@ai-sdk/openai": "3.0.41",
|
|
40
|
+
"@contractspec/lib.provider-ranking": "0.1.1",
|
|
41
|
+
"ai": "6.0.116",
|
|
41
42
|
"ollama-ai-provider": "^1.2.0",
|
|
42
43
|
"zod": "^4.3.5"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"@contractspec/tool.typescript": "
|
|
46
|
+
"@contractspec/tool.typescript": "3.1.0",
|
|
46
47
|
"typescript": "^5.9.3",
|
|
47
|
-
"@contractspec/tool.bun": "
|
|
48
|
+
"@contractspec/tool.bun": "3.1.0"
|
|
48
49
|
},
|
|
49
50
|
"exports": {
|
|
50
51
|
".": {
|
|
@@ -75,6 +76,20 @@
|
|
|
75
76
|
"browser": "./dist/browser/models.js",
|
|
76
77
|
"default": "./dist/models.js"
|
|
77
78
|
},
|
|
79
|
+
"./selector": {
|
|
80
|
+
"types": "./dist/selector.d.ts",
|
|
81
|
+
"bun": "./dist/selector.js",
|
|
82
|
+
"node": "./dist/node/selector.js",
|
|
83
|
+
"browser": "./dist/browser/selector.js",
|
|
84
|
+
"default": "./dist/selector.js"
|
|
85
|
+
},
|
|
86
|
+
"./selector-types": {
|
|
87
|
+
"types": "./dist/selector-types.d.ts",
|
|
88
|
+
"bun": "./dist/selector-types.js",
|
|
89
|
+
"node": "./dist/node/selector-types.js",
|
|
90
|
+
"browser": "./dist/browser/selector-types.js",
|
|
91
|
+
"default": "./dist/selector-types.js"
|
|
92
|
+
},
|
|
78
93
|
"./types": {
|
|
79
94
|
"types": "./dist/types.d.ts",
|
|
80
95
|
"bun": "./dist/types.js",
|
|
@@ -121,6 +136,20 @@
|
|
|
121
136
|
"browser": "./dist/browser/models.js",
|
|
122
137
|
"default": "./dist/models.js"
|
|
123
138
|
},
|
|
139
|
+
"./selector": {
|
|
140
|
+
"types": "./dist/selector.d.ts",
|
|
141
|
+
"bun": "./dist/selector.js",
|
|
142
|
+
"node": "./dist/node/selector.js",
|
|
143
|
+
"browser": "./dist/browser/selector.js",
|
|
144
|
+
"default": "./dist/selector.js"
|
|
145
|
+
},
|
|
146
|
+
"./selector-types": {
|
|
147
|
+
"types": "./dist/selector-types.d.ts",
|
|
148
|
+
"bun": "./dist/selector-types.js",
|
|
149
|
+
"node": "./dist/node/selector-types.js",
|
|
150
|
+
"browser": "./dist/browser/selector-types.js",
|
|
151
|
+
"default": "./dist/selector-types.js"
|
|
152
|
+
},
|
|
124
153
|
"./types": {
|
|
125
154
|
"types": "./dist/types.d.ts",
|
|
126
155
|
"bun": "./dist/types.js",
|