@em3odme/agentic 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.
package/dist/index.js ADDED
@@ -0,0 +1,751 @@
1
+ // src/providers/cloudflare.ts
2
+ var cloudflareAIModel = (model) => ({
3
+ provider: "cloudflare",
4
+ model
5
+ });
6
+
7
+ // src/providers/groq.ts
8
+ var groqAIModel = (model) => ({
9
+ provider: "groq",
10
+ model
11
+ });
12
+
13
+ // src/types.ts
14
+ var ProviderError = class extends Error {
15
+ constructor(message, provider, statusCode, originalError) {
16
+ super(message);
17
+ this.provider = provider;
18
+ this.statusCode = statusCode;
19
+ this.originalError = originalError;
20
+ this.name = "ProviderError";
21
+ }
22
+ };
23
+ var ConfigurationError = class extends Error {
24
+ constructor(message, provider) {
25
+ super(message);
26
+ this.provider = provider;
27
+ this.name = "ConfigurationError";
28
+ }
29
+ };
30
+
31
+ // src/providers/BaseModelProvider.ts
32
+ var BaseModelProvider = class {
33
+ constructor(environment) {
34
+ this.environment = environment;
35
+ }
36
+ validateRequiredKeys(envKeys) {
37
+ const missing = envKeys.filter((key) => !this.environment[key]);
38
+ if (missing.length > 0) {
39
+ throw new ConfigurationError(
40
+ `Missing required environment variables: ${missing.join(", ")}`,
41
+ this.providerType
42
+ );
43
+ }
44
+ }
45
+ createError(message, statusCode, originalError) {
46
+ return new ProviderError(
47
+ message,
48
+ this.providerType,
49
+ statusCode,
50
+ originalError
51
+ );
52
+ }
53
+ buildUsageObject(promptTokens, completionTokens, totalTokens) {
54
+ return {
55
+ promptTokens,
56
+ completionTokens,
57
+ totalTokens
58
+ };
59
+ }
60
+ filterDuplicateToolCalls(toolCalls) {
61
+ const seen = /* @__PURE__ */ new Set();
62
+ return toolCalls.filter((toolCall) => {
63
+ const key = toolCall.function.name;
64
+ if (seen.has(key)) {
65
+ return false;
66
+ }
67
+ seen.add(key);
68
+ return true;
69
+ });
70
+ }
71
+ };
72
+
73
+ // src/providers/utils.ts
74
+ var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
75
+ async function runWithRetry(fn, maxRetries = 3, delayMs = 1e3, info) {
76
+ for (let i = 0; i < maxRetries; i++) {
77
+ try {
78
+ return await fn();
79
+ } catch (error) {
80
+ const isRetryable = error instanceof Error && (error.message?.includes("1031") || error.toString().includes("1031") || error.message?.includes("500"));
81
+ if (isRetryable && i < maxRetries - 1) {
82
+ if (info)
83
+ info(`AI Error (1031/500). Retrying ${i + 1}/${maxRetries}...`);
84
+ await delay(delayMs * (i + 1));
85
+ continue;
86
+ }
87
+ throw error;
88
+ }
89
+ }
90
+ }
91
+
92
+ // src/providers/CloudflareProvider.ts
93
+ var CloudflareProvider = class extends BaseModelProvider {
94
+ constructor(environment) {
95
+ super(environment);
96
+ this.providerType = "cloudflare";
97
+ this.validateRequiredKeys(["AI"]);
98
+ }
99
+ supportsJsonMode() {
100
+ return true;
101
+ }
102
+ supportsTools() {
103
+ return true;
104
+ }
105
+ async execute(request) {
106
+ const payload = {
107
+ messages: request.messages,
108
+ ...request.options
109
+ };
110
+ if (request.jsonMode) {
111
+ payload.response_format = { type: "json_object" };
112
+ }
113
+ try {
114
+ const response = await runWithRetry(
115
+ async () => {
116
+ return this.environment.AI.run(
117
+ request.model,
118
+ payload
119
+ );
120
+ },
121
+ 3,
122
+ 1e3
123
+ );
124
+ return this.parseResponse(response);
125
+ } catch (error) {
126
+ throw this.createError(
127
+ `Cloudflare AI execution failed: ${error instanceof Error ? error.message : "Unknown error"}`,
128
+ void 0,
129
+ error
130
+ );
131
+ }
132
+ }
133
+ parseResponse(response) {
134
+ const content = this.extractContent(response);
135
+ const toolCalls = this.extractToolCalls(response);
136
+ const usage = this.buildUsageObject(0, 0, 0);
137
+ return {
138
+ content,
139
+ toolCalls,
140
+ raw: response,
141
+ usage
142
+ };
143
+ }
144
+ extractContent(response) {
145
+ if (typeof response === "string") {
146
+ return response;
147
+ }
148
+ if (response && typeof response === "object") {
149
+ if ("response" in response) {
150
+ return String(response.response || "");
151
+ }
152
+ }
153
+ return "";
154
+ }
155
+ extractToolCalls(response) {
156
+ if (!response || typeof response !== "object") {
157
+ return [];
158
+ }
159
+ const toolCalls = response.tool_calls;
160
+ if (!Array.isArray(toolCalls) || toolCalls.length === 0) {
161
+ return [];
162
+ }
163
+ return toolCalls.map((toolCall, index) => {
164
+ const tc = toolCall;
165
+ const args = tc.arguments;
166
+ const argsString = typeof args === "string" ? args : JSON.stringify(args);
167
+ return {
168
+ id: `tool-call-${index}`,
169
+ type: "function",
170
+ function: {
171
+ name: String(tc.name || ""),
172
+ arguments: argsString
173
+ }
174
+ };
175
+ });
176
+ }
177
+ };
178
+
179
+ // src/providers/GroqProvider.ts
180
+ var GroqProvider = class extends BaseModelProvider {
181
+ constructor(environment) {
182
+ super(environment);
183
+ this.providerType = "groq";
184
+ this.apiEndpoint = "https://api.groq.com/openai/v1/chat/completions";
185
+ this.validateRequiredKeys(["GROQ_API_KEY"]);
186
+ }
187
+ supportsJsonMode() {
188
+ return true;
189
+ }
190
+ supportsTools() {
191
+ return true;
192
+ }
193
+ async execute(request) {
194
+ const payload = this.buildPayload(request);
195
+ try {
196
+ const response = await this.makeRequest(payload);
197
+ return this.parseResponse(response);
198
+ } catch (error) {
199
+ if (error instanceof Response) {
200
+ const errorText = await error.text();
201
+ throw this.createError(
202
+ `Groq API Error (${error.status}): ${errorText}. Model: ${request.model}`,
203
+ error.status,
204
+ errorText
205
+ );
206
+ }
207
+ throw this.createError(
208
+ `Groq execution failed: ${error instanceof Error ? error.message : "Unknown error"}`,
209
+ void 0,
210
+ error
211
+ );
212
+ }
213
+ }
214
+ buildPayload(request) {
215
+ const payload = {
216
+ model: request.model,
217
+ messages: request.messages,
218
+ ...request.options
219
+ };
220
+ if (request.options?.tools) {
221
+ payload.tool_choice = "auto";
222
+ }
223
+ if (request.jsonMode && !request.options?.tools) {
224
+ payload.response_format = { type: "json_object" };
225
+ }
226
+ return payload;
227
+ }
228
+ async makeRequest(payload) {
229
+ const response = await runWithRetry(
230
+ async () => {
231
+ return fetch(this.apiEndpoint, {
232
+ method: "POST",
233
+ headers: {
234
+ Authorization: `Bearer ${this.environment.GROQ_API_KEY}`,
235
+ "Content-Type": "application/json"
236
+ },
237
+ body: JSON.stringify(payload)
238
+ });
239
+ },
240
+ 3,
241
+ 1e3
242
+ );
243
+ if (!response) {
244
+ throw this.createError(
245
+ `Groq execution failed: No response from Groq API`,
246
+ void 0,
247
+ void 0
248
+ );
249
+ }
250
+ return response?.json();
251
+ }
252
+ extractContent(data) {
253
+ return data.choices?.[0]?.message?.content || "";
254
+ }
255
+ extractToolCalls(data) {
256
+ return data.choices?.[0]?.message?.tool_calls || [];
257
+ }
258
+ parseResponse(data) {
259
+ const content = this.extractContent(data);
260
+ const toolCalls = this.filterDuplicateToolCalls(
261
+ this.extractToolCalls(data)
262
+ );
263
+ const usage = data.usage ? this.buildUsageObject(
264
+ data.usage.prompt_tokens,
265
+ data.usage.completion_tokens,
266
+ data.usage.total_tokens
267
+ ) : this.buildUsageObject(0, 0, 0);
268
+ return {
269
+ content,
270
+ toolCalls,
271
+ raw: data,
272
+ usage
273
+ };
274
+ }
275
+ };
276
+
277
+ // src/providers/ProviderFactory.ts
278
+ var ProviderFactory = class {
279
+ static createProvider(providerType, environment) {
280
+ const ProviderClass = this.providers.get(providerType);
281
+ if (!ProviderClass) {
282
+ throw new ConfigurationError(
283
+ `Unknown provider: ${providerType}. Supported providers: ${Array.from(this.providers.keys()).join(", ")}`,
284
+ providerType
285
+ );
286
+ }
287
+ return new ProviderClass(environment);
288
+ }
289
+ static getSupportedProviders() {
290
+ return Array.from(this.providers.keys());
291
+ }
292
+ static registerProvider(providerType, providerClass) {
293
+ this.providers.set(providerType, providerClass);
294
+ }
295
+ static isProviderSupported(providerType) {
296
+ return this.providers.has(providerType);
297
+ }
298
+ };
299
+ ProviderFactory.providers = /* @__PURE__ */ new Map([
300
+ ["cloudflare", CloudflareProvider],
301
+ ["groq", GroqProvider]
302
+ ]);
303
+
304
+ // src/response/JsonParser.ts
305
+ var JsonParser = class {
306
+ /**
307
+ * Enhanced JSON parsing with multiple fallback strategies
308
+ */
309
+ static parse(input, expectJson = false) {
310
+ if (!input || typeof input !== "string") {
311
+ return null;
312
+ }
313
+ if (expectJson && !this.looksLikeJson(input)) {
314
+ return null;
315
+ }
316
+ try {
317
+ return JSON.parse(input);
318
+ } catch {
319
+ const markdownJson = this.extractFromMarkdown(input);
320
+ if (markdownJson) {
321
+ try {
322
+ return JSON.parse(markdownJson);
323
+ } catch {
324
+ }
325
+ }
326
+ const genericCode = this.extractFromCodeBlock(input);
327
+ if (genericCode) {
328
+ try {
329
+ return JSON.parse(genericCode);
330
+ } catch {
331
+ }
332
+ }
333
+ const braceMatch = this.extractByBraces(input);
334
+ if (braceMatch) {
335
+ try {
336
+ return JSON.parse(braceMatch);
337
+ } catch {
338
+ }
339
+ }
340
+ const fixedJson = this.attemptJsonFixes(input);
341
+ if (fixedJson) {
342
+ try {
343
+ return JSON.parse(fixedJson);
344
+ } catch {
345
+ }
346
+ }
347
+ return null;
348
+ }
349
+ }
350
+ static looksLikeJson(input) {
351
+ const trimmed = input.trim();
352
+ return trimmed.startsWith("{") || trimmed.startsWith("[") || trimmed.includes('"');
353
+ }
354
+ static extractFromMarkdown(input) {
355
+ const match = input.match(/```json\s*(\{[\s\S]*?\})\s*```/);
356
+ return match ? match[1] : null;
357
+ }
358
+ static extractFromCodeBlock(input) {
359
+ const match = input.match(/```\s*(\{[\s\S]*?\})\s*```/);
360
+ return match ? match[1] : null;
361
+ }
362
+ static extractByBraces(input) {
363
+ const match = input.match(/\{[\s\S]*\}/);
364
+ return match ? match[0] : null;
365
+ }
366
+ static attemptJsonFixes(input) {
367
+ let fixed = input.trim();
368
+ fixed = fixed.replace(/,(\s*[}\]])/g, "$1");
369
+ fixed = fixed.replace(/'/g, '"');
370
+ fixed = fixed.replace(/"\s*:\s*"([^"]*?)"/g, (match, content) => {
371
+ const escaped = content.replace(/"/g, '\\"');
372
+ return `: "${escaped}"`;
373
+ });
374
+ fixed = fixed.replace(/\/\/.*$/gm, "");
375
+ fixed = fixed.replace(/\/\*[\s\S]*?\*\//g, "");
376
+ if (this.looksLikeJson(fixed)) {
377
+ return fixed;
378
+ }
379
+ return null;
380
+ }
381
+ /**
382
+ * Safely stringify any value to JSON
383
+ */
384
+ static stringify(value, pretty = false) {
385
+ try {
386
+ return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);
387
+ } catch {
388
+ return String(value);
389
+ }
390
+ }
391
+ };
392
+
393
+ // src/response/ResponseBuilder.ts
394
+ var ResponseBuilder = class _ResponseBuilder {
395
+ constructor() {
396
+ this.content = "";
397
+ this.toolCalls = [];
398
+ this.rawResponse = null;
399
+ this.usage = {
400
+ promptTokens: 0,
401
+ completionTokens: 0,
402
+ totalTokens: 0
403
+ };
404
+ this.jsonMode = false;
405
+ }
406
+ setContent(content) {
407
+ this.content = content;
408
+ return this;
409
+ }
410
+ setToolCalls(toolCalls) {
411
+ this.toolCalls = toolCalls;
412
+ return this;
413
+ }
414
+ setRawResponse(raw) {
415
+ this.rawResponse = raw;
416
+ return this;
417
+ }
418
+ setUsage(usage) {
419
+ this.usage = usage;
420
+ return this;
421
+ }
422
+ setJsonMode(jsonMode) {
423
+ this.jsonMode = jsonMode;
424
+ return this;
425
+ }
426
+ build() {
427
+ const isJson = this.toolCalls.length === 0 && (this.jsonMode || this.content.trim().startsWith("{"));
428
+ return {
429
+ content: this.content,
430
+ isJson,
431
+ tool_calls: this.toolCalls,
432
+ raw: this.rawResponse,
433
+ usage: this.usage,
434
+ json: () => JsonParser.parse(this.content, isJson)
435
+ };
436
+ }
437
+ static create() {
438
+ return new _ResponseBuilder();
439
+ }
440
+ };
441
+
442
+ // src/config/Configuration.ts
443
+ var ConfigurationValidator = class {
444
+ static validateProvider(provider, environment) {
445
+ const config = this.providerConfigs.get(provider);
446
+ if (!config) {
447
+ throw new Error(`Unknown provider: ${provider}`);
448
+ }
449
+ this.validateEnvironmentVariables(provider, config, environment);
450
+ }
451
+ static validateModel(provider, model) {
452
+ const config = this.providerConfigs.get(provider);
453
+ if (!config || !config.modelValidation) {
454
+ return;
455
+ }
456
+ const validation = config.modelValidation;
457
+ if (validation.minLength && model.length < validation.minLength) {
458
+ throw new Error(
459
+ `Model name must be at least ${validation.minLength} characters long`
460
+ );
461
+ }
462
+ if (validation.maxLength && model.length > validation.maxLength) {
463
+ throw new Error(
464
+ `Model name must not exceed ${validation.maxLength} characters`
465
+ );
466
+ }
467
+ if (validation.pattern && !validation.pattern.test(model)) {
468
+ throw new Error(
469
+ `Model name does not match required pattern: ${validation.pattern}`
470
+ );
471
+ }
472
+ }
473
+ static validateOptions(provider, options) {
474
+ const config = this.providerConfigs.get(provider);
475
+ if (!config) {
476
+ return;
477
+ }
478
+ if ("temperature" in options) {
479
+ const temp = options.temperature;
480
+ if (typeof temp !== "number" || temp < 0 || temp > 2) {
481
+ throw new Error("Temperature must be a number between 0 and 2");
482
+ }
483
+ }
484
+ if ("max_tokens" in options) {
485
+ const tokens = options.max_tokens;
486
+ if (typeof tokens !== "number" || tokens <= 0) {
487
+ throw new Error("Max tokens must be a positive number");
488
+ }
489
+ }
490
+ }
491
+ static getProviderConfig(provider) {
492
+ return this.providerConfigs.get(provider);
493
+ }
494
+ static registerProviderConfig(provider, config) {
495
+ this.providerConfigs.set(provider, config);
496
+ }
497
+ static validateEnvironmentVariables(provider, config, environment) {
498
+ const missing = config.requiredEnvVars.filter((key) => !environment[key]);
499
+ if (missing.length > 0) {
500
+ throw new Error(
501
+ `Missing required environment variables for ${provider}: ${missing.join(", ")}`
502
+ );
503
+ }
504
+ }
505
+ };
506
+ ConfigurationValidator.providerConfigs = /* @__PURE__ */ new Map([
507
+ [
508
+ "cloudflare",
509
+ {
510
+ requiredEnvVars: ["AI"],
511
+ optionalEnvVars: [],
512
+ defaultOptions: {},
513
+ supportedFeatures: {
514
+ jsonMode: true,
515
+ tools: true,
516
+ streaming: false
517
+ }
518
+ }
519
+ ],
520
+ [
521
+ "groq",
522
+ {
523
+ requiredEnvVars: ["GROQ_API_KEY"],
524
+ optionalEnvVars: [],
525
+ defaultOptions: {
526
+ temperature: 0.7,
527
+ max_tokens: 1024
528
+ },
529
+ supportedFeatures: {
530
+ jsonMode: true,
531
+ tools: true,
532
+ streaming: true
533
+ }
534
+ }
535
+ ]
536
+ ]);
537
+ var RuntimeConfigManager = class {
538
+ static getConfig() {
539
+ return { ...this.defaultConfig };
540
+ }
541
+ static updateConfig(updates) {
542
+ this.defaultConfig = this.deepMerge(this.defaultConfig, updates);
543
+ }
544
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
545
+ static deepMerge(target, source) {
546
+ const result = { ...target };
547
+ for (const key in source) {
548
+ if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
549
+ result[key] = this.deepMerge(result[key] || {}, source[key]);
550
+ } else {
551
+ result[key] = source[key];
552
+ }
553
+ }
554
+ return result;
555
+ }
556
+ };
557
+ RuntimeConfigManager.defaultConfig = {
558
+ timeout: 3e4,
559
+ retries: {
560
+ maxAttempts: 3,
561
+ baseDelay: 1e3,
562
+ maxDelay: 1e4
563
+ },
564
+ caching: {
565
+ enabled: false,
566
+ ttl: 3e5
567
+ // 5 minutes
568
+ },
569
+ logging: {
570
+ enabled: true,
571
+ level: "info"
572
+ }
573
+ };
574
+
575
+ // src/errors/RetryHandler.ts
576
+ var RetryHandler = class {
577
+ static async executeWithRetry(operation, config = {}, context) {
578
+ const fullConfig = { ...this.defaultConfig, ...config };
579
+ let lastError;
580
+ for (let attempt = 0; attempt <= fullConfig.maxRetries; attempt++) {
581
+ try {
582
+ return await operation();
583
+ } catch (error) {
584
+ lastError = error;
585
+ if (attempt === fullConfig.maxRetries) {
586
+ break;
587
+ }
588
+ if (!this.shouldRetry(error, fullConfig)) {
589
+ break;
590
+ }
591
+ const delay2 = this.calculateDelay(attempt, fullConfig);
592
+ if (context) {
593
+ console.warn(
594
+ `${context} - Attempt ${attempt + 1}/${fullConfig.maxRetries + 1} failed. Retrying in ${delay2}ms...`
595
+ );
596
+ }
597
+ await this.sleep(delay2);
598
+ }
599
+ }
600
+ throw lastError;
601
+ }
602
+ static shouldRetry(error, config) {
603
+ const errorMessage = error instanceof Error ? error.message : String(error);
604
+ const errorString = errorMessage.toLowerCase();
605
+ if (config.retryableErrors.some(
606
+ (retryableError) => errorString.includes(retryableError.toLowerCase())
607
+ )) {
608
+ return true;
609
+ }
610
+ if (error && typeof error === "object" && "status" in error && typeof error.status === "number") {
611
+ return config.retryableStatusCodes.includes(error.status);
612
+ }
613
+ if (error instanceof TypeError && error.message.includes("fetch")) {
614
+ return true;
615
+ }
616
+ return false;
617
+ }
618
+ static calculateDelay(attempt, config) {
619
+ const exponentialDelay = config.baseDelay * Math.pow(config.backoffFactor, attempt);
620
+ const jitter = Math.random() * 0.1 * exponentialDelay;
621
+ return Math.min(exponentialDelay + jitter, config.maxDelay);
622
+ }
623
+ static sleep(ms) {
624
+ return new Promise((resolve) => setTimeout(resolve, ms));
625
+ }
626
+ };
627
+ RetryHandler.defaultConfig = {
628
+ maxRetries: 3,
629
+ baseDelay: 1e3,
630
+ maxDelay: 1e4,
631
+ backoffFactor: 2,
632
+ retryableErrors: ["1031", "500", "502", "503", "504", "timeout", "network"],
633
+ retryableStatusCodes: [500, 502, 503, 504, 429]
634
+ };
635
+ var ErrorHandler = class {
636
+ static wrapProviderError(error, provider, context) {
637
+ const contextMessage = context ? ` (${context})` : "";
638
+ if (error instanceof Error) {
639
+ return new Error(
640
+ `[${provider.toUpperCase()}]${contextMessage} ${error.message}`
641
+ );
642
+ }
643
+ if (typeof error === "string") {
644
+ return new Error(`[${provider.toUpperCase()}]${contextMessage} ${error}`);
645
+ }
646
+ return new Error(
647
+ `[${provider.toUpperCase()}]${contextMessage} Unknown error occurred`
648
+ );
649
+ }
650
+ static isNetworkError(error) {
651
+ return error instanceof TypeError && (error.message.includes("fetch") || error.message.includes("network") || error.message.includes("ECONNREFUSED"));
652
+ }
653
+ static isTimeoutError(error) {
654
+ const errorMessage = error instanceof Error ? error.message : String(error);
655
+ return errorMessage.toLowerCase().includes("timeout");
656
+ }
657
+ static isRateLimitError(error) {
658
+ const errorMessage = error instanceof Error ? error.message : String(error);
659
+ return errorMessage.toLowerCase().includes("rate limit") || Boolean(
660
+ error && typeof error === "object" && "status" in error && error.status === 429
661
+ );
662
+ }
663
+ };
664
+
665
+ // src/ModelRunner.ts
666
+ var ModelRunner = class {
667
+ constructor(environment) {
668
+ this.environment = environment;
669
+ }
670
+ async run({
671
+ messages,
672
+ model,
673
+ jsonMode = false,
674
+ options = {}
675
+ }) {
676
+ const { provider, model: modelName } = model;
677
+ try {
678
+ this.validateInputs(provider, modelName, options);
679
+ const providerInstance = ProviderFactory.createProvider(
680
+ provider,
681
+ this.environment
682
+ );
683
+ this.validateCapabilities(providerInstance, jsonMode, options);
684
+ const response = await RetryHandler.executeWithRetry(
685
+ () => providerInstance.execute({
686
+ messages,
687
+ jsonMode,
688
+ options,
689
+ model: modelName
690
+ }),
691
+ RuntimeConfigManager.getConfig().retries,
692
+ `ModelRunner execution with ${provider}`
693
+ );
694
+ return ResponseBuilder.create().setContent(response.content).setToolCalls(response.toolCalls).setRawResponse(response.raw).setUsage(response.usage).setJsonMode(jsonMode).build();
695
+ } catch (error) {
696
+ throw ErrorHandler.wrapProviderError(error, provider, "ModelRunner.run");
697
+ }
698
+ }
699
+ /**
700
+ * Get supported providers
701
+ */
702
+ static getSupportedProviders() {
703
+ return ProviderFactory.getSupportedProviders();
704
+ }
705
+ /**
706
+ * Check if a provider supports specific features
707
+ */
708
+ static getProviderCapabilities(provider) {
709
+ const config = ConfigurationValidator.getProviderConfig(provider);
710
+ return config?.supportedFeatures;
711
+ }
712
+ /**
713
+ * Update runtime configuration
714
+ */
715
+ static updateRuntimeConfig(config) {
716
+ RuntimeConfigManager.updateConfig(config);
717
+ }
718
+ /**
719
+ * Validate inputs before processing
720
+ */
721
+ validateInputs(provider, model, options) {
722
+ ConfigurationValidator.validateProvider(provider, this.environment);
723
+ ConfigurationValidator.validateModel(provider, model);
724
+ ConfigurationValidator.validateOptions(provider, options);
725
+ }
726
+ /**
727
+ * Validate that the provider supports the requested features
728
+ */
729
+ validateCapabilities(provider, jsonMode, options) {
730
+ if (jsonMode && !provider.supportsJsonMode()) {
731
+ throw new ConfigurationError(
732
+ `Provider ${provider.providerType} does not support JSON mode`,
733
+ provider.providerType
734
+ );
735
+ }
736
+ if (options?.tools && !provider.supportsTools()) {
737
+ throw new ConfigurationError(
738
+ `Provider ${provider.providerType} does not support tools`,
739
+ provider.providerType
740
+ );
741
+ }
742
+ }
743
+ };
744
+ export {
745
+ ConfigurationError,
746
+ ModelRunner,
747
+ ProviderError,
748
+ cloudflareAIModel,
749
+ groqAIModel
750
+ };
751
+ //# sourceMappingURL=index.js.map