@flare-ai-sdk/server 1.0.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.mjs ADDED
@@ -0,0 +1,2447 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
8
+ var __typeError = (msg) => {
9
+ throw TypeError(msg);
10
+ };
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __spreadValues = (a, b) => {
13
+ for (var prop in b || (b = {}))
14
+ if (__hasOwnProp.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ if (__getOwnPropSymbols)
17
+ for (var prop of __getOwnPropSymbols(b)) {
18
+ if (__propIsEnum.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ }
21
+ return a;
22
+ };
23
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
25
+ var __async = (__this, __arguments, generator) => {
26
+ return new Promise((resolve, reject) => {
27
+ var fulfilled = (value) => {
28
+ try {
29
+ step(generator.next(value));
30
+ } catch (e) {
31
+ reject(e);
32
+ }
33
+ };
34
+ var rejected = (value) => {
35
+ try {
36
+ step(generator.throw(value));
37
+ } catch (e) {
38
+ reject(e);
39
+ }
40
+ };
41
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
42
+ step((generator = generator.apply(__this, __arguments)).next());
43
+ });
44
+ };
45
+ var __await = function(promise, isYieldStar) {
46
+ this[0] = promise;
47
+ this[1] = isYieldStar;
48
+ };
49
+ var __asyncGenerator = (__this, __arguments, generator) => {
50
+ var resume = (k, v, yes, no) => {
51
+ try {
52
+ var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done;
53
+ Promise.resolve(isAwait ? v[0] : v).then((y) => isAwait ? resume(k === "return" ? k : "next", v[1] ? { done: y.done, value: y.value } : y, yes, no) : yes({ value: y, done })).catch((e) => resume("throw", e, yes, no));
54
+ } catch (e) {
55
+ no(e);
56
+ }
57
+ }, method = (k) => it[k] = (x) => new Promise((yes, no) => resume(k, x, yes, no)), it = {};
58
+ return generator = generator.apply(__this, __arguments), it[__knownSymbol("asyncIterator")] = () => it, method("next"), method("throw"), method("return"), it;
59
+ };
60
+ var __yieldStar = (value) => {
61
+ var obj = value[__knownSymbol("asyncIterator")], isAwait = false, method, it = {};
62
+ if (obj == null) {
63
+ obj = value[__knownSymbol("iterator")]();
64
+ method = (k) => it[k] = (x) => obj[k](x);
65
+ } else {
66
+ obj = obj.call(value);
67
+ method = (k) => it[k] = (v) => {
68
+ if (isAwait) {
69
+ isAwait = false;
70
+ if (k === "throw") throw v;
71
+ return v;
72
+ }
73
+ isAwait = true;
74
+ return {
75
+ done: false,
76
+ value: new __await(new Promise((resolve) => {
77
+ var x = obj[k](v);
78
+ if (!(x instanceof Object)) __typeError("Object expected");
79
+ resolve(x);
80
+ }), 1)
81
+ };
82
+ };
83
+ }
84
+ return it[__knownSymbol("iterator")] = () => it, method("next"), "throw" in obj ? method("throw") : it.throw = (x) => {
85
+ throw x;
86
+ }, "return" in obj && method("return"), it;
87
+ };
88
+ var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
89
+
90
+ // src/utils/errors.ts
91
+ var FlareError = class extends Error {
92
+ constructor(message, code, statusCode, retryable = false, details) {
93
+ super(message);
94
+ __publicField(this, "code");
95
+ __publicField(this, "statusCode");
96
+ __publicField(this, "retryable");
97
+ __publicField(this, "details");
98
+ this.name = "FlareError";
99
+ this.code = code;
100
+ this.statusCode = statusCode;
101
+ this.retryable = retryable;
102
+ this.details = details;
103
+ Error.captureStackTrace(this, this.constructor);
104
+ }
105
+ };
106
+ var NetworkError = class extends FlareError {
107
+ constructor(message, details) {
108
+ super(message, "NETWORK_ERROR", void 0, true, details);
109
+ this.name = "NetworkError";
110
+ }
111
+ };
112
+ var TimeoutError = class extends FlareError {
113
+ constructor(message, details) {
114
+ super(message, "TIMEOUT_ERROR", 408, true, details);
115
+ this.name = "TimeoutError";
116
+ }
117
+ };
118
+ var RateLimitError = class extends FlareError {
119
+ constructor(message, retryAfter, details) {
120
+ super(message, "RATE_LIMIT_ERROR", 429, true, details);
121
+ __publicField(this, "retryAfter");
122
+ this.name = "RateLimitError";
123
+ this.retryAfter = retryAfter;
124
+ }
125
+ };
126
+ var AuthenticationError = class extends FlareError {
127
+ constructor(message, details) {
128
+ super(message, "AUTHENTICATION_ERROR", 401, false, details);
129
+ this.name = "AuthenticationError";
130
+ }
131
+ };
132
+ var ValidationError = class extends FlareError {
133
+ constructor(message, details) {
134
+ super(message, "VALIDATION_ERROR", 400, false, details);
135
+ this.name = "ValidationError";
136
+ }
137
+ };
138
+ var CircuitBreakerError = class extends FlareError {
139
+ constructor(message, details) {
140
+ super(message, "CIRCUIT_BREAKER_OPEN", 503, true, details);
141
+ this.name = "CircuitBreakerError";
142
+ }
143
+ };
144
+ var ProviderError = class extends FlareError {
145
+ constructor(provider, message, statusCode, details) {
146
+ super(message, "PROVIDER_ERROR", statusCode, true, details);
147
+ __publicField(this, "provider");
148
+ this.name = "ProviderError";
149
+ this.provider = provider;
150
+ }
151
+ };
152
+ var StreamError = class extends FlareError {
153
+ constructor(message, details) {
154
+ super(message, "STREAM_ERROR", void 0, false, details);
155
+ this.name = "StreamError";
156
+ }
157
+ };
158
+ var ParseError = class extends FlareError {
159
+ constructor(message, details) {
160
+ super(message, "PARSE_ERROR", void 0, false, details);
161
+ this.name = "ParseError";
162
+ }
163
+ };
164
+ var ContentFilterError = class extends FlareError {
165
+ constructor(message, details) {
166
+ super(message, "CONTENT_FILTER_ERROR", 400, false, details);
167
+ this.name = "ContentFilterError";
168
+ }
169
+ };
170
+ function isRetryableError(error) {
171
+ if (error instanceof FlareError) {
172
+ return error.retryable;
173
+ }
174
+ if (error.message.includes("ECONNREFUSED") || error.message.includes("ETIMEDOUT") || error.message.includes("ENOTFOUND")) {
175
+ return true;
176
+ }
177
+ return false;
178
+ }
179
+ function getErrorStatusCode(error) {
180
+ if (error instanceof FlareError) {
181
+ return error.statusCode;
182
+ }
183
+ return void 0;
184
+ }
185
+
186
+ // src/utils/metrics.ts
187
+ var LatencyHistogram = class {
188
+ constructor() {
189
+ __publicField(this, "samples", []);
190
+ __publicField(this, "maxSamples", 1e3);
191
+ }
192
+ add(latency) {
193
+ this.samples.push(latency);
194
+ if (this.samples.length > this.maxSamples) {
195
+ this.samples.shift();
196
+ }
197
+ }
198
+ getPercentile(p) {
199
+ if (this.samples.length === 0) return 0;
200
+ const sorted = [...this.samples].sort((a, b) => a - b);
201
+ const index = Math.ceil(p / 100 * sorted.length) - 1;
202
+ return sorted[Math.max(0, index)];
203
+ }
204
+ getAverage() {
205
+ if (this.samples.length === 0) return 0;
206
+ return this.samples.reduce((a, b) => a + b, 0) / this.samples.length;
207
+ }
208
+ clear() {
209
+ this.samples = [];
210
+ }
211
+ };
212
+ var MetricsCollector = class {
213
+ constructor() {
214
+ __publicField(this, "totalRequests", 0);
215
+ __publicField(this, "successfulRequests", 0);
216
+ __publicField(this, "failedRequests", 0);
217
+ __publicField(this, "latencyHistogram", new LatencyHistogram());
218
+ __publicField(this, "startTime", Date.now());
219
+ __publicField(this, "windowStart", Date.now());
220
+ __publicField(this, "windowRequests", 0);
221
+ __publicField(this, "windowDuration", 6e4);
222
+ }
223
+ // 1 minute window
224
+ /**
225
+ * Record successful request
226
+ * @param latency - Request latency in milliseconds
227
+ */
228
+ recordSuccess(latency) {
229
+ this.totalRequests++;
230
+ this.successfulRequests++;
231
+ this.latencyHistogram.add(latency);
232
+ this.updateWindow();
233
+ }
234
+ /**
235
+ * Record failed request
236
+ * @param latency - Request latency in milliseconds
237
+ */
238
+ recordFailure(latency) {
239
+ this.totalRequests++;
240
+ this.failedRequests++;
241
+ this.latencyHistogram.add(latency);
242
+ this.updateWindow();
243
+ }
244
+ /**
245
+ * Update rolling window for RPS calculation
246
+ */
247
+ updateWindow() {
248
+ const now = Date.now();
249
+ if (now - this.windowStart >= this.windowDuration) {
250
+ this.windowRequests = 0;
251
+ this.windowStart = now;
252
+ }
253
+ this.windowRequests++;
254
+ }
255
+ /**
256
+ * Get current metrics
257
+ */
258
+ getMetrics() {
259
+ const elapsed = (Date.now() - this.windowStart) / 1e3;
260
+ const rps = elapsed > 0 ? this.windowRequests / elapsed : 0;
261
+ return {
262
+ totalRequests: this.totalRequests,
263
+ successfulRequests: this.successfulRequests,
264
+ failedRequests: this.failedRequests,
265
+ avgLatency: this.latencyHistogram.getAverage(),
266
+ p95Latency: this.latencyHistogram.getPercentile(95),
267
+ p99Latency: this.latencyHistogram.getPercentile(99),
268
+ rps
269
+ };
270
+ }
271
+ /**
272
+ * Get success rate as percentage
273
+ */
274
+ getSuccessRate() {
275
+ if (this.totalRequests === 0) return 100;
276
+ return this.successfulRequests / this.totalRequests * 100;
277
+ }
278
+ /**
279
+ * Get uptime in milliseconds
280
+ */
281
+ getUptime() {
282
+ return Date.now() - this.startTime;
283
+ }
284
+ /**
285
+ * Reset all metrics
286
+ */
287
+ reset() {
288
+ this.totalRequests = 0;
289
+ this.successfulRequests = 0;
290
+ this.failedRequests = 0;
291
+ this.latencyHistogram.clear();
292
+ this.windowStart = Date.now();
293
+ this.windowRequests = 0;
294
+ }
295
+ /**
296
+ * Get detailed statistics
297
+ */
298
+ getDetailedStats() {
299
+ return __spreadProps(__spreadValues({}, this.getMetrics()), {
300
+ successRate: this.getSuccessRate(),
301
+ uptime: this.getUptime(),
302
+ timestamp: Date.now()
303
+ });
304
+ }
305
+ };
306
+ var globalMetrics = null;
307
+ function getGlobalMetrics() {
308
+ if (!globalMetrics) {
309
+ globalMetrics = new MetricsCollector();
310
+ }
311
+ return globalMetrics;
312
+ }
313
+ function createMetricsCollector() {
314
+ return new MetricsCollector();
315
+ }
316
+ function measureLatency(_0) {
317
+ return __async(this, arguments, function* (fn, collector = getGlobalMetrics()) {
318
+ const start = Date.now();
319
+ try {
320
+ const result = yield fn();
321
+ collector.recordSuccess(Date.now() - start);
322
+ return result;
323
+ } catch (error) {
324
+ collector.recordFailure(Date.now() - start);
325
+ throw error;
326
+ }
327
+ });
328
+ }
329
+
330
+ // src/utils/rate-limiter.ts
331
+ var DEFAULT_CONFIG = {
332
+ maxRequests: 100,
333
+ windowMs: 6e4,
334
+ // 1 minute
335
+ clientId: "default"
336
+ };
337
+ var RateLimiter = class {
338
+ constructor(config = {}) {
339
+ __publicField(this, "buckets", /* @__PURE__ */ new Map());
340
+ __publicField(this, "config");
341
+ __publicField(this, "cleanupInterval");
342
+ this.config = __spreadValues(__spreadValues({}, DEFAULT_CONFIG), config);
343
+ this.startCleanup();
344
+ }
345
+ /**
346
+ * Acquire a token for rate limiting
347
+ * @param clientId - Client identifier
348
+ * @throws RateLimitError if rate limit exceeded
349
+ */
350
+ acquire(clientId) {
351
+ return __async(this, null, function* () {
352
+ const id = clientId || this.config.clientId;
353
+ const bucket = this.getBucket(id);
354
+ this.refillBucket(bucket);
355
+ if (bucket.tokens <= 0) {
356
+ const retryAfter = this.calculateRetryAfter(bucket);
357
+ throw new RateLimitError(
358
+ `Rate limit exceeded. Try again in ${Math.ceil(retryAfter / 1e3)}s`,
359
+ retryAfter,
360
+ { clientId: id, limit: this.config.maxRequests, window: this.config.windowMs }
361
+ );
362
+ }
363
+ bucket.tokens--;
364
+ });
365
+ }
366
+ /**
367
+ * Check if request would be allowed without consuming token
368
+ * @param clientId - Client identifier
369
+ * @returns true if request would be allowed
370
+ */
371
+ check(clientId) {
372
+ const id = clientId || this.config.clientId;
373
+ const bucket = this.getBucket(id);
374
+ this.refillBucket(bucket);
375
+ return bucket.tokens > 0;
376
+ }
377
+ /**
378
+ * Get remaining tokens for client
379
+ * @param clientId - Client identifier
380
+ * @returns Number of remaining requests
381
+ */
382
+ getRemaining(clientId) {
383
+ const id = clientId || this.config.clientId;
384
+ const bucket = this.getBucket(id);
385
+ this.refillBucket(bucket);
386
+ return Math.floor(bucket.tokens);
387
+ }
388
+ /**
389
+ * Reset rate limit for client
390
+ * @param clientId - Client identifier
391
+ */
392
+ reset(clientId) {
393
+ const id = clientId || this.config.clientId;
394
+ this.buckets.delete(id);
395
+ }
396
+ /**
397
+ * Get or create bucket for client
398
+ */
399
+ getBucket(clientId) {
400
+ let bucket = this.buckets.get(clientId);
401
+ if (!bucket) {
402
+ bucket = {
403
+ tokens: this.config.maxRequests,
404
+ lastRefill: Date.now()
405
+ };
406
+ this.buckets.set(clientId, bucket);
407
+ }
408
+ return bucket;
409
+ }
410
+ /**
411
+ * Refill tokens based on elapsed time
412
+ */
413
+ refillBucket(bucket) {
414
+ const now = Date.now();
415
+ const elapsed = now - bucket.lastRefill;
416
+ if (elapsed <= 0) return;
417
+ const tokensToAdd = elapsed / this.config.windowMs * this.config.maxRequests;
418
+ bucket.tokens = Math.min(this.config.maxRequests, bucket.tokens + tokensToAdd);
419
+ bucket.lastRefill = now;
420
+ }
421
+ /**
422
+ * Calculate retry-after time in milliseconds
423
+ */
424
+ calculateRetryAfter(bucket) {
425
+ const tokensNeeded = 1 - bucket.tokens;
426
+ return tokensNeeded / this.config.maxRequests * this.config.windowMs;
427
+ }
428
+ /**
429
+ * Start periodic cleanup of old buckets
430
+ */
431
+ startCleanup() {
432
+ this.cleanupInterval = setInterval(() => {
433
+ const now = Date.now();
434
+ const maxAge = this.config.windowMs * 2;
435
+ for (const [clientId, bucket] of this.buckets.entries()) {
436
+ if (now - bucket.lastRefill > maxAge) {
437
+ this.buckets.delete(clientId);
438
+ }
439
+ }
440
+ }, this.config.windowMs);
441
+ if (this.cleanupInterval.unref) {
442
+ this.cleanupInterval.unref();
443
+ }
444
+ }
445
+ /**
446
+ * Get statistics for monitoring
447
+ */
448
+ getStats() {
449
+ return {
450
+ totalClients: this.buckets.size,
451
+ config: this.config
452
+ };
453
+ }
454
+ /**
455
+ * Clean up resources
456
+ */
457
+ destroy() {
458
+ if (this.cleanupInterval) {
459
+ clearInterval(this.cleanupInterval);
460
+ }
461
+ this.buckets.clear();
462
+ }
463
+ };
464
+ function createRateLimiter(config) {
465
+ return new RateLimiter(config);
466
+ }
467
+
468
+ // src/utils/request-queue.ts
469
+ import EventEmitter from "eventemitter3";
470
+ var DEFAULT_CONFIG2 = {
471
+ concurrency: 10,
472
+ maxQueueSize: 1e3,
473
+ timeout: 3e4
474
+ };
475
+ var RequestQueue = class extends EventEmitter {
476
+ constructor(config = {}) {
477
+ super();
478
+ __publicField(this, "queue", []);
479
+ __publicField(this, "running", 0);
480
+ __publicField(this, "config");
481
+ __publicField(this, "requestCounter", 0);
482
+ this.config = __spreadValues(__spreadValues({}, DEFAULT_CONFIG2), config);
483
+ }
484
+ /**
485
+ * Add request to queue
486
+ * @param fn - Async function to execute
487
+ * @param priority - Request priority (higher = processed first)
488
+ * @returns Promise resolving to function result
489
+ */
490
+ add(fn, priority = 0) {
491
+ return new Promise((resolve, reject) => {
492
+ if (this.queue.length >= this.config.maxQueueSize) {
493
+ reject(new Error("Queue is full"));
494
+ return;
495
+ }
496
+ const item = {
497
+ id: `req_${++this.requestCounter}`,
498
+ priority,
499
+ fn,
500
+ resolve,
501
+ reject,
502
+ timestamp: Date.now()
503
+ };
504
+ const insertIndex = this.queue.findIndex((q) => q.priority < priority);
505
+ if (insertIndex === -1) {
506
+ this.queue.push(item);
507
+ } else {
508
+ this.queue.splice(insertIndex, 0, item);
509
+ }
510
+ this.emit("enqueue", { id: item.id, priority, queueSize: this.queue.length });
511
+ this.process();
512
+ });
513
+ }
514
+ /**
515
+ * Process queue items
516
+ */
517
+ process() {
518
+ return __async(this, null, function* () {
519
+ while (this.running < this.config.concurrency && this.queue.length > 0) {
520
+ const item = this.queue.shift();
521
+ this.running++;
522
+ this.emit("start", { id: item.id, running: this.running });
523
+ this.executeItem(item).finally(() => {
524
+ this.running--;
525
+ this.emit("complete", { id: item.id, running: this.running });
526
+ if (this.running === 0 && this.queue.length === 0) {
527
+ this.emit("drain");
528
+ }
529
+ this.process();
530
+ });
531
+ }
532
+ });
533
+ }
534
+ /**
535
+ * Execute queue item with timeout
536
+ */
537
+ executeItem(item) {
538
+ return __async(this, null, function* () {
539
+ const timeoutPromise = new Promise((_, reject) => {
540
+ setTimeout(() => {
541
+ reject(new Error(`Request timeout after ${this.config.timeout}ms`));
542
+ }, this.config.timeout);
543
+ });
544
+ try {
545
+ const result = yield Promise.race([item.fn(), timeoutPromise]);
546
+ item.resolve(result);
547
+ } catch (error) {
548
+ item.reject(error instanceof Error ? error : new Error(String(error)));
549
+ }
550
+ });
551
+ }
552
+ /**
553
+ * Get queue size
554
+ */
555
+ size() {
556
+ return this.queue.length;
557
+ }
558
+ /**
559
+ * Get number of running requests
560
+ */
561
+ getRunning() {
562
+ return this.running;
563
+ }
564
+ /**
565
+ * Check if queue is empty
566
+ */
567
+ isEmpty() {
568
+ return this.queue.length === 0 && this.running === 0;
569
+ }
570
+ /**
571
+ * Clear all pending requests
572
+ */
573
+ clear() {
574
+ const error = new Error("Queue cleared");
575
+ for (const item of this.queue) {
576
+ item.reject(error);
577
+ }
578
+ this.queue = [];
579
+ this.emit("clear");
580
+ }
581
+ /**
582
+ * Wait for queue to drain
583
+ */
584
+ drain() {
585
+ return __async(this, null, function* () {
586
+ if (this.isEmpty()) return;
587
+ return new Promise((resolve) => {
588
+ this.once("drain", resolve);
589
+ });
590
+ });
591
+ }
592
+ /**
593
+ * Get queue statistics
594
+ */
595
+ getStats() {
596
+ return {
597
+ queueSize: this.queue.length,
598
+ running: this.running,
599
+ concurrency: this.config.concurrency,
600
+ maxQueueSize: this.config.maxQueueSize
601
+ };
602
+ }
603
+ /**
604
+ * Update configuration
605
+ */
606
+ updateConfig(config) {
607
+ this.config = __spreadValues(__spreadValues({}, this.config), config);
608
+ this.process();
609
+ }
610
+ };
611
+ function createRequestQueue(config) {
612
+ return new RequestQueue(config);
613
+ }
614
+
615
+ // src/utils/retry.ts
616
+ var DEFAULT_RETRY_CONFIG = {
617
+ maxRetries: 3,
618
+ initialDelay: 1e3,
619
+ maxDelay: 3e4,
620
+ backoffMultiplier: 2,
621
+ jitter: true
622
+ };
623
+ function calculateDelay(attempt, config) {
624
+ const exponentialDelay = Math.min(
625
+ config.initialDelay * Math.pow(config.backoffMultiplier, attempt),
626
+ config.maxDelay
627
+ );
628
+ if (config.jitter) {
629
+ return Math.random() * exponentialDelay;
630
+ }
631
+ return exponentialDelay;
632
+ }
633
+ function sleep(ms) {
634
+ return new Promise((resolve) => setTimeout(resolve, ms));
635
+ }
636
+ function withRetry(_0) {
637
+ return __async(this, arguments, function* (fn, config = {}, onRetry) {
638
+ const retryConfig = __spreadValues(__spreadValues({}, DEFAULT_RETRY_CONFIG), config);
639
+ let lastError;
640
+ for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
641
+ try {
642
+ return yield fn();
643
+ } catch (error) {
644
+ lastError = error instanceof Error ? error : new Error(String(error));
645
+ if (!isRetryableError(lastError) || attempt === retryConfig.maxRetries) {
646
+ throw lastError;
647
+ }
648
+ const delay = calculateDelay(attempt, retryConfig);
649
+ if (onRetry) {
650
+ onRetry(attempt + 1, lastError, delay);
651
+ }
652
+ yield sleep(delay);
653
+ }
654
+ }
655
+ throw lastError;
656
+ });
657
+ }
658
+ var RetryHandler = class {
659
+ constructor(config = {}) {
660
+ __publicField(this, "config");
661
+ this.config = __spreadValues(__spreadValues({}, DEFAULT_RETRY_CONFIG), config);
662
+ }
663
+ /**
664
+ * Execute function with retry logic
665
+ */
666
+ execute(fn, onRetry) {
667
+ return __async(this, null, function* () {
668
+ return withRetry(fn, this.config, onRetry);
669
+ });
670
+ }
671
+ /**
672
+ * Update retry configuration
673
+ */
674
+ updateConfig(config) {
675
+ this.config = __spreadValues(__spreadValues({}, this.config), config);
676
+ }
677
+ /**
678
+ * Get current configuration
679
+ */
680
+ getConfig() {
681
+ return __spreadValues({}, this.config);
682
+ }
683
+ };
684
+ function createRetryHandler(config) {
685
+ return new RetryHandler(config);
686
+ }
687
+
688
+ // src/utils/circuit-breaker.ts
689
+ import EventEmitter2 from "eventemitter3";
690
+ var CircuitState = /* @__PURE__ */ ((CircuitState2) => {
691
+ CircuitState2["CLOSED"] = "closed";
692
+ CircuitState2["OPEN"] = "open";
693
+ CircuitState2["HALF_OPEN"] = "half-open";
694
+ return CircuitState2;
695
+ })(CircuitState || {});
696
+ var DEFAULT_CONFIG3 = {
697
+ failureThreshold: 5,
698
+ resetTimeout: 6e4,
699
+ halfOpenRequests: 1
700
+ };
701
+ var CircuitBreaker = class extends EventEmitter2 {
702
+ constructor(config = {}) {
703
+ super();
704
+ __publicField(this, "state", "closed" /* CLOSED */);
705
+ __publicField(this, "failureCount", 0);
706
+ __publicField(this, "successCount", 0);
707
+ __publicField(this, "lastFailureTime");
708
+ __publicField(this, "resetTimer");
709
+ __publicField(this, "config");
710
+ this.config = __spreadValues(__spreadValues({}, DEFAULT_CONFIG3), config);
711
+ }
712
+ /**
713
+ * Execute a function with circuit breaker protection
714
+ * @param fn - Async function to execute
715
+ * @returns Promise resolving to function result
716
+ * @throws CircuitBreakerError if circuit is open
717
+ */
718
+ execute(fn) {
719
+ return __async(this, null, function* () {
720
+ if (this.state === "open" /* OPEN */) {
721
+ throw new CircuitBreakerError("Circuit breaker is open", {
722
+ state: this.state,
723
+ failureCount: this.failureCount,
724
+ lastFailureTime: this.lastFailureTime
725
+ });
726
+ }
727
+ try {
728
+ const result = yield fn();
729
+ this.onSuccess();
730
+ return result;
731
+ } catch (error) {
732
+ this.onFailure();
733
+ throw error;
734
+ }
735
+ });
736
+ }
737
+ /**
738
+ * Handle successful execution
739
+ */
740
+ onSuccess() {
741
+ this.failureCount = 0;
742
+ if (this.state === "half-open" /* HALF_OPEN */) {
743
+ this.successCount++;
744
+ if (this.successCount >= this.config.halfOpenRequests) {
745
+ this.close();
746
+ }
747
+ }
748
+ }
749
+ /**
750
+ * Handle failed execution
751
+ */
752
+ onFailure() {
753
+ this.failureCount++;
754
+ this.lastFailureTime = Date.now();
755
+ this.successCount = 0;
756
+ if (this.failureCount >= this.config.failureThreshold) {
757
+ this.open();
758
+ }
759
+ }
760
+ /**
761
+ * Open the circuit (block requests)
762
+ */
763
+ open() {
764
+ if (this.state === "open" /* OPEN */) return;
765
+ this.state = "open" /* OPEN */;
766
+ this.emit("open", { failureCount: this.failureCount });
767
+ this.resetTimer = setTimeout(() => {
768
+ this.halfOpen();
769
+ }, this.config.resetTimeout);
770
+ }
771
+ /**
772
+ * Enter half-open state (test if service recovered)
773
+ */
774
+ halfOpen() {
775
+ if (this.state === "closed" /* CLOSED */) return;
776
+ this.state = "half-open" /* HALF_OPEN */;
777
+ this.successCount = 0;
778
+ this.emit("half-open");
779
+ }
780
+ /**
781
+ * Close the circuit (allow requests)
782
+ */
783
+ close() {
784
+ if (this.state === "closed" /* CLOSED */) return;
785
+ this.state = "closed" /* CLOSED */;
786
+ this.failureCount = 0;
787
+ this.successCount = 0;
788
+ this.lastFailureTime = void 0;
789
+ if (this.resetTimer) {
790
+ clearTimeout(this.resetTimer);
791
+ this.resetTimer = void 0;
792
+ }
793
+ this.emit("close");
794
+ }
795
+ /**
796
+ * Get current circuit state
797
+ */
798
+ getState() {
799
+ return this.state;
800
+ }
801
+ /**
802
+ * Get circuit statistics
803
+ */
804
+ getStats() {
805
+ return {
806
+ state: this.state,
807
+ failureCount: this.failureCount,
808
+ successCount: this.successCount,
809
+ lastFailureTime: this.lastFailureTime
810
+ };
811
+ }
812
+ /**
813
+ * Manually reset the circuit breaker
814
+ */
815
+ reset() {
816
+ this.close();
817
+ }
818
+ /**
819
+ * Clean up resources
820
+ */
821
+ destroy() {
822
+ if (this.resetTimer) {
823
+ clearTimeout(this.resetTimer);
824
+ }
825
+ this.removeAllListeners();
826
+ }
827
+ };
828
+ function createCircuitBreaker(config) {
829
+ return new CircuitBreaker(config);
830
+ }
831
+
832
+ // src/providers/base.ts
833
+ var BaseProvider = class {
834
+ constructor(config) {
835
+ __publicField(this, "config");
836
+ this.config = config;
837
+ }
838
+ makeRequest(url, options, stream = false) {
839
+ return __async(this, null, function* () {
840
+ const headers = __spreadValues({
841
+ "Content-Type": "application/json"
842
+ }, options.headers || {});
843
+ if (this.config.apiKey) {
844
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
845
+ }
846
+ const response = yield fetch(url, __spreadProps(__spreadValues({}, options), {
847
+ headers
848
+ }));
849
+ if (!response.ok && !stream) {
850
+ const errorText = yield response.text();
851
+ throw new Error(`Provider request failed: ${response.status} ${errorText}`);
852
+ }
853
+ return response;
854
+ });
855
+ }
856
+ formatMessages(request) {
857
+ const messages = [];
858
+ if (request.systemPrompt) {
859
+ messages.push({ role: "system", content: request.systemPrompt });
860
+ }
861
+ messages.push(...request.messages);
862
+ return messages;
863
+ }
864
+ getEndpoint(path) {
865
+ const baseUrl = this.config.baseUrl || this.getDefaultBaseUrl();
866
+ return `${baseUrl}${path}`;
867
+ }
868
+ };
869
+
870
+ // src/providers/anthropic/anthropic.ts
871
+ var AnthropicProvider = class extends BaseProvider {
872
+ getDefaultBaseUrl() {
873
+ return "https://api.anthropic.com/v1";
874
+ }
875
+ generateText(request) {
876
+ return __async(this, null, function* () {
877
+ var _a;
878
+ const messages = this.formatMessages(request);
879
+ const systemPrompt = (_a = messages.find((m) => m.role === "system")) == null ? void 0 : _a.content;
880
+ const userMessages = messages.filter((m) => m.role !== "system");
881
+ const response = yield this.makeRequest(
882
+ this.getEndpoint("/messages"),
883
+ {
884
+ method: "POST",
885
+ headers: {
886
+ "anthropic-version": "2023-06-01"
887
+ },
888
+ body: JSON.stringify({
889
+ model: this.config.model,
890
+ messages: userMessages,
891
+ system: systemPrompt,
892
+ max_tokens: this.config.maxTokens || 1024,
893
+ temperature: this.config.temperature
894
+ })
895
+ }
896
+ );
897
+ const data = yield response.json();
898
+ return {
899
+ text: data.content[0].text,
900
+ usage: {
901
+ promptTokens: data.usage.input_tokens,
902
+ completionTokens: data.usage.output_tokens,
903
+ totalTokens: data.usage.input_tokens + data.usage.output_tokens
904
+ },
905
+ finishReason: data.stop_reason
906
+ };
907
+ });
908
+ }
909
+ streamText(request) {
910
+ return __asyncGenerator(this, null, function* () {
911
+ var _a;
912
+ const messages = this.formatMessages(request);
913
+ const systemPrompt = (_a = messages.find((m) => m.role === "system")) == null ? void 0 : _a.content;
914
+ const userMessages = messages.filter((m) => m.role !== "system");
915
+ const response = yield new __await(this.makeRequest(
916
+ this.getEndpoint("/messages"),
917
+ {
918
+ method: "POST",
919
+ headers: {
920
+ "anthropic-version": "2023-06-01"
921
+ },
922
+ body: JSON.stringify({
923
+ model: this.config.model,
924
+ messages: userMessages,
925
+ system: systemPrompt,
926
+ max_tokens: this.config.maxTokens || 1024,
927
+ stream: true
928
+ })
929
+ },
930
+ true
931
+ ));
932
+ const reader = response.body.getReader();
933
+ const decoder = new TextDecoder();
934
+ let buffer = "";
935
+ try {
936
+ while (true) {
937
+ const { done, value } = yield new __await(reader.read());
938
+ if (done) break;
939
+ buffer += decoder.decode(value, { stream: true });
940
+ const lines = buffer.split("\n");
941
+ buffer = lines.pop() || "";
942
+ for (const line of lines) {
943
+ if (line.startsWith("data: ")) {
944
+ try {
945
+ const data = JSON.parse(line.slice(6));
946
+ if (data.type === "content_block_delta") {
947
+ yield { type: "content", content: data.delta.text };
948
+ }
949
+ } catch (e) {
950
+ }
951
+ }
952
+ }
953
+ }
954
+ } finally {
955
+ reader.releaseLock();
956
+ }
957
+ });
958
+ }
959
+ generateObject(request) {
960
+ return __async(this, null, function* () {
961
+ const textResponse = yield this.generateText(__spreadProps(__spreadValues({}, request), {
962
+ messages: [
963
+ ...request.messages,
964
+ {
965
+ role: "user",
966
+ content: `Respond with valid JSON matching this schema: ${JSON.stringify(request.schema)}`
967
+ }
968
+ ]
969
+ }));
970
+ const object = JSON.parse(textResponse.text);
971
+ return {
972
+ object,
973
+ text: textResponse.text,
974
+ usage: textResponse.usage
975
+ };
976
+ });
977
+ }
978
+ streamObject(request) {
979
+ return __asyncGenerator(this, null, function* () {
980
+ let accumulatedText = "";
981
+ try {
982
+ for (var iter = __forAwait(this.streamText(request)), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
983
+ const chunk = temp.value;
984
+ if (chunk.type === "content") {
985
+ accumulatedText += chunk.content;
986
+ try {
987
+ const partial = JSON.parse(accumulatedText);
988
+ yield { type: "partial", partial, text: accumulatedText };
989
+ } catch (e) {
990
+ }
991
+ }
992
+ }
993
+ } catch (temp) {
994
+ error = [temp];
995
+ } finally {
996
+ try {
997
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
998
+ } finally {
999
+ if (error)
1000
+ throw error[0];
1001
+ }
1002
+ }
1003
+ try {
1004
+ const object = JSON.parse(accumulatedText);
1005
+ yield { type: "complete", object, text: accumulatedText };
1006
+ } catch (e) {
1007
+ yield { type: "error", error: new Error("Invalid JSON in response") };
1008
+ }
1009
+ });
1010
+ }
1011
+ };
1012
+
1013
+ // src/providers/custom/custom.ts
1014
+ var CustomProvider = class extends BaseProvider {
1015
+ constructor() {
1016
+ super(...arguments);
1017
+ /**
1018
+ * Request format for custom provider
1019
+ */
1020
+ __publicField(this, "requestFormat", "openai");
1021
+ }
1022
+ getDefaultBaseUrl() {
1023
+ return this.config.baseUrl || "http://localhost:8000/v1";
1024
+ }
1025
+ /**
1026
+ * Set request format for custom provider
1027
+ */
1028
+ setRequestFormat(format) {
1029
+ this.requestFormat = format;
1030
+ }
1031
+ generateText(request) {
1032
+ return __async(this, null, function* () {
1033
+ const messages = this.formatMessages(request);
1034
+ try {
1035
+ const requestBody = this.formatRequestBody(messages, false);
1036
+ const response = yield this.makeRequest(this.getEndpoint("/chat/completions"), {
1037
+ method: "POST",
1038
+ body: JSON.stringify(requestBody)
1039
+ });
1040
+ const data = yield response.json();
1041
+ return this.parseTextResponse(data);
1042
+ } catch (error) {
1043
+ throw new ProviderError(
1044
+ "custom",
1045
+ error instanceof Error ? error.message : "Unknown error",
1046
+ void 0,
1047
+ { originalError: error }
1048
+ );
1049
+ }
1050
+ });
1051
+ }
1052
+ streamText(request) {
1053
+ return __asyncGenerator(this, null, function* () {
1054
+ const messages = this.formatMessages(request);
1055
+ try {
1056
+ const requestBody = this.formatRequestBody(messages, true);
1057
+ const response = yield new __await(this.makeRequest(
1058
+ this.getEndpoint("/chat/completions"),
1059
+ {
1060
+ method: "POST",
1061
+ body: JSON.stringify(requestBody)
1062
+ },
1063
+ true
1064
+ ));
1065
+ yield* __yieldStar(this.parseStreamResponse(response));
1066
+ } catch (error) {
1067
+ yield {
1068
+ type: "error",
1069
+ error: new ProviderError(
1070
+ "custom",
1071
+ error instanceof Error ? error.message : "Streaming error",
1072
+ void 0,
1073
+ { originalError: error }
1074
+ )
1075
+ };
1076
+ }
1077
+ });
1078
+ }
1079
+ generateObject(request) {
1080
+ return __async(this, null, function* () {
1081
+ const enhancedRequest = __spreadProps(__spreadValues({}, request), {
1082
+ messages: [
1083
+ ...request.messages,
1084
+ {
1085
+ role: "user",
1086
+ content: `Respond with valid JSON matching this schema: ${JSON.stringify(request.schema)}. Only return the JSON object.`
1087
+ }
1088
+ ]
1089
+ });
1090
+ const textResponse = yield this.generateText(enhancedRequest);
1091
+ let jsonText = textResponse.text.trim();
1092
+ const codeBlockMatch = jsonText.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
1093
+ if (codeBlockMatch) {
1094
+ jsonText = codeBlockMatch[1];
1095
+ }
1096
+ try {
1097
+ const object = JSON.parse(jsonText);
1098
+ return {
1099
+ object,
1100
+ text: textResponse.text,
1101
+ usage: textResponse.usage
1102
+ };
1103
+ } catch (error) {
1104
+ throw new ProviderError(
1105
+ "custom",
1106
+ `Failed to parse JSON response: ${error instanceof Error ? error.message : "Unknown error"}`,
1107
+ void 0,
1108
+ { responseText: textResponse.text }
1109
+ );
1110
+ }
1111
+ });
1112
+ }
1113
+ streamObject(request) {
1114
+ return __asyncGenerator(this, null, function* () {
1115
+ let accumulatedText = "";
1116
+ try {
1117
+ for (var iter = __forAwait(this.streamText(request)), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
1118
+ const chunk = temp.value;
1119
+ if (chunk.type === "content") {
1120
+ accumulatedText += chunk.content;
1121
+ let jsonText2 = accumulatedText.trim();
1122
+ const codeBlockMatch2 = jsonText2.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
1123
+ if (codeBlockMatch2) {
1124
+ jsonText2 = codeBlockMatch2[1];
1125
+ }
1126
+ try {
1127
+ const partial = JSON.parse(jsonText2);
1128
+ yield { type: "partial", partial, text: accumulatedText };
1129
+ } catch (e) {
1130
+ }
1131
+ }
1132
+ }
1133
+ } catch (temp) {
1134
+ error = [temp];
1135
+ } finally {
1136
+ try {
1137
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
1138
+ } finally {
1139
+ if (error)
1140
+ throw error[0];
1141
+ }
1142
+ }
1143
+ let jsonText = accumulatedText.trim();
1144
+ const codeBlockMatch = jsonText.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
1145
+ if (codeBlockMatch) {
1146
+ jsonText = codeBlockMatch[1];
1147
+ }
1148
+ try {
1149
+ const object = JSON.parse(jsonText);
1150
+ yield { type: "complete", object, text: accumulatedText };
1151
+ } catch (e) {
1152
+ yield { type: "error", error: new Error("Invalid JSON in response") };
1153
+ }
1154
+ });
1155
+ }
1156
+ /**
1157
+ * Format request body based on provider format
1158
+ */
1159
+ formatRequestBody(messages, stream) {
1160
+ var _a;
1161
+ if (this.requestFormat === "anthropic") {
1162
+ const systemPrompt = (_a = messages.find((m) => m.role === "system")) == null ? void 0 : _a.content;
1163
+ const userMessages = messages.filter((m) => m.role !== "system");
1164
+ return {
1165
+ model: this.config.model,
1166
+ messages: userMessages,
1167
+ system: systemPrompt,
1168
+ max_tokens: this.config.maxTokens || 1024,
1169
+ temperature: this.config.temperature,
1170
+ top_p: this.config.topP,
1171
+ stream
1172
+ };
1173
+ }
1174
+ return {
1175
+ model: this.config.model,
1176
+ messages,
1177
+ max_tokens: this.config.maxTokens,
1178
+ temperature: this.config.temperature,
1179
+ top_p: this.config.topP,
1180
+ frequency_penalty: this.config.frequencyPenalty,
1181
+ presence_penalty: this.config.presencePenalty,
1182
+ stop: this.config.stop,
1183
+ stream
1184
+ };
1185
+ }
1186
+ /**
1187
+ * Parse text response based on provider format
1188
+ */
1189
+ parseTextResponse(data) {
1190
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1191
+ if (data.choices && ((_a = data.choices[0]) == null ? void 0 : _a.message)) {
1192
+ return {
1193
+ text: data.choices[0].message.content,
1194
+ usage: {
1195
+ promptTokens: ((_b = data.usage) == null ? void 0 : _b.prompt_tokens) || 0,
1196
+ completionTokens: ((_c = data.usage) == null ? void 0 : _c.completion_tokens) || 0,
1197
+ totalTokens: ((_d = data.usage) == null ? void 0 : _d.total_tokens) || 0
1198
+ },
1199
+ finishReason: data.choices[0].finish_reason || "stop"
1200
+ };
1201
+ }
1202
+ if (data.content && Array.isArray(data.content)) {
1203
+ return {
1204
+ text: ((_e = data.content[0]) == null ? void 0 : _e.text) || "",
1205
+ usage: {
1206
+ promptTokens: ((_f = data.usage) == null ? void 0 : _f.input_tokens) || 0,
1207
+ completionTokens: ((_g = data.usage) == null ? void 0 : _g.output_tokens) || 0,
1208
+ totalTokens: (((_h = data.usage) == null ? void 0 : _h.input_tokens) || 0) + (((_i = data.usage) == null ? void 0 : _i.output_tokens) || 0)
1209
+ },
1210
+ finishReason: data.stop_reason || "stop"
1211
+ };
1212
+ }
1213
+ return {
1214
+ text: data.text || data.response || JSON.stringify(data),
1215
+ usage: {
1216
+ promptTokens: 0,
1217
+ completionTokens: 0,
1218
+ totalTokens: 0
1219
+ },
1220
+ finishReason: "stop"
1221
+ };
1222
+ }
1223
+ /**
1224
+ * Parse streaming response
1225
+ */
1226
+ parseStreamResponse(response) {
1227
+ return __asyncGenerator(this, null, function* () {
1228
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
1229
+ const reader = response.body.getReader();
1230
+ const decoder = new TextDecoder();
1231
+ let buffer = "";
1232
+ try {
1233
+ while (true) {
1234
+ const { done, value } = yield new __await(reader.read());
1235
+ if (done) break;
1236
+ buffer += decoder.decode(value, { stream: true });
1237
+ const lines = buffer.split("\n");
1238
+ buffer = lines.pop() || "";
1239
+ for (const line of lines) {
1240
+ if (line.startsWith("data: ")) {
1241
+ const data = line.slice(6);
1242
+ if (data === "[DONE]") continue;
1243
+ try {
1244
+ const parsed = JSON.parse(data);
1245
+ if ((_c = (_b = (_a = parsed.choices) == null ? void 0 : _a[0]) == null ? void 0 : _b.delta) == null ? void 0 : _c.content) {
1246
+ yield { type: "content", content: parsed.choices[0].delta.content };
1247
+ }
1248
+ if (parsed.type === "content_block_delta" && ((_d = parsed.delta) == null ? void 0 : _d.text)) {
1249
+ yield { type: "content", content: parsed.delta.text };
1250
+ }
1251
+ if (parsed.content && !parsed.choices) {
1252
+ yield { type: "content", content: parsed.content };
1253
+ }
1254
+ if (((_f = (_e = parsed.choices) == null ? void 0 : _e[0]) == null ? void 0 : _f.finish_reason) || parsed.stop_reason) {
1255
+ yield {
1256
+ type: "done",
1257
+ done: {
1258
+ finishReason: ((_h = (_g = parsed.choices) == null ? void 0 : _g[0]) == null ? void 0 : _h.finish_reason) || parsed.stop_reason || "stop",
1259
+ usage: {
1260
+ promptTokens: ((_i = parsed.usage) == null ? void 0 : _i.prompt_tokens) || ((_j = parsed.usage) == null ? void 0 : _j.input_tokens) || 0,
1261
+ completionTokens: ((_k = parsed.usage) == null ? void 0 : _k.completion_tokens) || ((_l = parsed.usage) == null ? void 0 : _l.output_tokens) || 0,
1262
+ totalTokens: ((_m = parsed.usage) == null ? void 0 : _m.total_tokens) || 0
1263
+ }
1264
+ }
1265
+ };
1266
+ }
1267
+ } catch (e) {
1268
+ console.error("Failed to parse streaming chunk:", e);
1269
+ }
1270
+ }
1271
+ }
1272
+ }
1273
+ } finally {
1274
+ reader.releaseLock();
1275
+ }
1276
+ });
1277
+ }
1278
+ };
1279
+
1280
+ // src/providers/google/google.ts
1281
+ var GoogleProvider = class extends BaseProvider {
1282
+ getDefaultBaseUrl() {
1283
+ return "https://generativelanguage.googleapis.com/v1beta";
1284
+ }
1285
+ /**
1286
+ * Format messages for Google's API format
1287
+ */
1288
+ formatGoogleMessages(messages) {
1289
+ return messages.map((msg) => ({
1290
+ role: msg.role === "assistant" ? "model" : msg.role,
1291
+ parts: [{ text: msg.content }]
1292
+ }));
1293
+ }
1294
+ generateText(request) {
1295
+ return __async(this, null, function* () {
1296
+ var _a, _b, _c, _d;
1297
+ const messages = this.formatMessages(request);
1298
+ const systemPrompt = (_a = messages.find((m) => m.role === "system")) == null ? void 0 : _a.content;
1299
+ const conversationMessages = messages.filter((m) => m.role !== "system");
1300
+ const endpoint = this.getEndpoint(
1301
+ `/models/${this.config.model}:generateContent?key=${this.config.apiKey}`
1302
+ );
1303
+ try {
1304
+ const response = yield this.makeRequest(endpoint, {
1305
+ method: "POST",
1306
+ body: JSON.stringify({
1307
+ contents: this.formatGoogleMessages(conversationMessages),
1308
+ systemInstruction: systemPrompt ? {
1309
+ parts: [{ text: systemPrompt }]
1310
+ } : void 0,
1311
+ generationConfig: {
1312
+ maxOutputTokens: this.config.maxTokens,
1313
+ temperature: this.config.temperature,
1314
+ topP: this.config.topP,
1315
+ stopSequences: this.config.stop
1316
+ }
1317
+ })
1318
+ });
1319
+ const data = yield response.json();
1320
+ if (!data.candidates || data.candidates.length === 0) {
1321
+ throw new ProviderError(
1322
+ "google",
1323
+ "No candidates returned from Google API",
1324
+ response.status,
1325
+ { response: data }
1326
+ );
1327
+ }
1328
+ const candidate = data.candidates[0];
1329
+ const text = candidate.content.parts.map((p) => p.text).join("");
1330
+ return {
1331
+ text,
1332
+ usage: {
1333
+ promptTokens: ((_b = data.usageMetadata) == null ? void 0 : _b.promptTokenCount) || 0,
1334
+ completionTokens: ((_c = data.usageMetadata) == null ? void 0 : _c.candidatesTokenCount) || 0,
1335
+ totalTokens: ((_d = data.usageMetadata) == null ? void 0 : _d.totalTokenCount) || 0
1336
+ },
1337
+ finishReason: this.mapGoogleFinishReason(candidate.finishReason),
1338
+ metadata: {
1339
+ safetyRatings: candidate.safetyRatings
1340
+ }
1341
+ };
1342
+ } catch (error) {
1343
+ throw new ProviderError(
1344
+ "google",
1345
+ error instanceof Error ? error.message : "Unknown error",
1346
+ void 0,
1347
+ { originalError: error }
1348
+ );
1349
+ }
1350
+ });
1351
+ }
1352
+ streamText(request) {
1353
+ return __asyncGenerator(this, null, function* () {
1354
+ var _a, _b, _c, _d, _e, _f, _g;
1355
+ const messages = this.formatMessages(request);
1356
+ const systemPrompt = (_a = messages.find((m) => m.role === "system")) == null ? void 0 : _a.content;
1357
+ const conversationMessages = messages.filter((m) => m.role !== "system");
1358
+ const endpoint = this.getEndpoint(
1359
+ `/models/${this.config.model}:streamGenerateContent?key=${this.config.apiKey}`
1360
+ );
1361
+ try {
1362
+ const response = yield new __await(this.makeRequest(
1363
+ endpoint,
1364
+ {
1365
+ method: "POST",
1366
+ body: JSON.stringify({
1367
+ contents: this.formatGoogleMessages(conversationMessages),
1368
+ systemInstruction: systemPrompt ? {
1369
+ parts: [{ text: systemPrompt }]
1370
+ } : void 0,
1371
+ generationConfig: {
1372
+ maxOutputTokens: this.config.maxTokens,
1373
+ temperature: this.config.temperature,
1374
+ topP: this.config.topP
1375
+ }
1376
+ })
1377
+ },
1378
+ true
1379
+ ));
1380
+ const reader = response.body.getReader();
1381
+ const decoder = new TextDecoder();
1382
+ let buffer = "";
1383
+ while (true) {
1384
+ const { done, value } = yield new __await(reader.read());
1385
+ if (done) break;
1386
+ buffer += decoder.decode(value, { stream: true });
1387
+ const lines = buffer.split("\n");
1388
+ buffer = lines.pop() || "";
1389
+ for (const line of lines) {
1390
+ if (!line.trim() || !line.startsWith("data: ")) continue;
1391
+ try {
1392
+ const jsonStr = line.slice(6).trim();
1393
+ if (!jsonStr) continue;
1394
+ const data = JSON.parse(jsonStr);
1395
+ if (data.candidates && ((_c = (_b = data.candidates[0]) == null ? void 0 : _b.content) == null ? void 0 : _c.parts)) {
1396
+ const text = data.candidates[0].content.parts.map((p) => p.text).join("");
1397
+ if (text) {
1398
+ yield { type: "content", content: text };
1399
+ }
1400
+ }
1401
+ if (data.candidates && ((_d = data.candidates[0]) == null ? void 0 : _d.finishReason)) {
1402
+ yield {
1403
+ type: "done",
1404
+ done: {
1405
+ finishReason: this.mapGoogleFinishReason(data.candidates[0].finishReason),
1406
+ usage: {
1407
+ promptTokens: ((_e = data.usageMetadata) == null ? void 0 : _e.promptTokenCount) || 0,
1408
+ completionTokens: ((_f = data.usageMetadata) == null ? void 0 : _f.candidatesTokenCount) || 0,
1409
+ totalTokens: ((_g = data.usageMetadata) == null ? void 0 : _g.totalTokenCount) || 0
1410
+ }
1411
+ }
1412
+ };
1413
+ }
1414
+ } catch (e) {
1415
+ console.error("Failed to parse Google streaming response:", e);
1416
+ }
1417
+ }
1418
+ }
1419
+ } catch (error) {
1420
+ yield {
1421
+ type: "error",
1422
+ error: new ProviderError(
1423
+ "google",
1424
+ error instanceof Error ? error.message : "Streaming error",
1425
+ void 0,
1426
+ { originalError: error }
1427
+ )
1428
+ };
1429
+ }
1430
+ });
1431
+ }
1432
+ generateObject(request) {
1433
+ return __async(this, null, function* () {
1434
+ const enhancedRequest = __spreadProps(__spreadValues({}, request), {
1435
+ messages: [
1436
+ ...request.messages,
1437
+ {
1438
+ role: "user",
1439
+ content: `Respond with valid JSON matching this schema: ${JSON.stringify(request.schema)}. Only return the JSON object, no other text.`
1440
+ }
1441
+ ]
1442
+ });
1443
+ const textResponse = yield this.generateText(enhancedRequest);
1444
+ let jsonText = textResponse.text.trim();
1445
+ const jsonMatch = jsonText.match(/```json\s*([\s\S]*?)\s*```/);
1446
+ if (jsonMatch) {
1447
+ jsonText = jsonMatch[1];
1448
+ }
1449
+ try {
1450
+ const object = JSON.parse(jsonText);
1451
+ return {
1452
+ object,
1453
+ text: textResponse.text,
1454
+ usage: textResponse.usage
1455
+ };
1456
+ } catch (error) {
1457
+ throw new ProviderError(
1458
+ "google",
1459
+ `Failed to parse JSON response: ${error instanceof Error ? error.message : "Unknown error"}`,
1460
+ void 0,
1461
+ { responseText: textResponse.text }
1462
+ );
1463
+ }
1464
+ });
1465
+ }
1466
+ streamObject(request) {
1467
+ return __asyncGenerator(this, null, function* () {
1468
+ let accumulatedText = "";
1469
+ try {
1470
+ for (var iter = __forAwait(this.streamText(request)), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
1471
+ const chunk = temp.value;
1472
+ if (chunk.type === "content") {
1473
+ accumulatedText += chunk.content;
1474
+ let jsonText2 = accumulatedText.trim();
1475
+ const jsonMatch2 = jsonText2.match(/```json\s*([\s\S]*?)\s*```/);
1476
+ if (jsonMatch2) {
1477
+ jsonText2 = jsonMatch2[1];
1478
+ }
1479
+ try {
1480
+ const partial = JSON.parse(jsonText2);
1481
+ yield { type: "partial", partial, text: accumulatedText };
1482
+ } catch (e) {
1483
+ }
1484
+ }
1485
+ }
1486
+ } catch (temp) {
1487
+ error = [temp];
1488
+ } finally {
1489
+ try {
1490
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
1491
+ } finally {
1492
+ if (error)
1493
+ throw error[0];
1494
+ }
1495
+ }
1496
+ let jsonText = accumulatedText.trim();
1497
+ const jsonMatch = jsonText.match(/```json\s*([\s\S]*?)\s*```/);
1498
+ if (jsonMatch) {
1499
+ jsonText = jsonMatch[1];
1500
+ }
1501
+ try {
1502
+ const object = JSON.parse(jsonText);
1503
+ yield { type: "complete", object, text: accumulatedText };
1504
+ } catch (e) {
1505
+ yield {
1506
+ type: "error",
1507
+ error: new Error(`Invalid JSON in response: ${accumulatedText.substring(0, 100)}...`)
1508
+ };
1509
+ }
1510
+ });
1511
+ }
1512
+ /**
1513
+ * Map Google's finish reason to standard format
1514
+ */
1515
+ mapGoogleFinishReason(reason) {
1516
+ const mapping = {
1517
+ "STOP": "stop",
1518
+ "MAX_TOKENS": "length",
1519
+ "SAFETY": "content_filter",
1520
+ "RECITATION": "content_filter",
1521
+ "OTHER": "stop"
1522
+ };
1523
+ return mapping[reason] || "stop";
1524
+ }
1525
+ };
1526
+
1527
+ // src/providers/openai/openai.ts
1528
+ var OpenAIProvider = class extends BaseProvider {
1529
+ getDefaultBaseUrl() {
1530
+ return "https://api.openai.com/v1";
1531
+ }
1532
+ generateText(request) {
1533
+ return __async(this, null, function* () {
1534
+ const response = yield this.makeRequest(
1535
+ this.getEndpoint("/chat/completions"),
1536
+ {
1537
+ method: "POST",
1538
+ body: JSON.stringify({
1539
+ model: this.config.model,
1540
+ messages: this.formatMessages(request),
1541
+ max_tokens: this.config.maxTokens,
1542
+ temperature: this.config.temperature,
1543
+ top_p: this.config.topP,
1544
+ frequency_penalty: this.config.frequencyPenalty,
1545
+ presence_penalty: this.config.presencePenalty,
1546
+ stop: this.config.stop
1547
+ })
1548
+ }
1549
+ );
1550
+ const data = yield response.json();
1551
+ return {
1552
+ text: data.choices[0].message.content,
1553
+ usage: {
1554
+ promptTokens: data.usage.prompt_tokens,
1555
+ completionTokens: data.usage.completion_tokens,
1556
+ totalTokens: data.usage.total_tokens
1557
+ },
1558
+ finishReason: data.choices[0].finish_reason
1559
+ };
1560
+ });
1561
+ }
1562
+ streamText(request) {
1563
+ return __asyncGenerator(this, null, function* () {
1564
+ var _a, _b;
1565
+ const response = yield new __await(this.makeRequest(
1566
+ this.getEndpoint("/chat/completions"),
1567
+ {
1568
+ method: "POST",
1569
+ body: JSON.stringify({
1570
+ model: this.config.model,
1571
+ messages: this.formatMessages(request),
1572
+ max_tokens: this.config.maxTokens,
1573
+ temperature: this.config.temperature,
1574
+ stream: true
1575
+ })
1576
+ },
1577
+ true
1578
+ ));
1579
+ const reader = response.body.getReader();
1580
+ const decoder = new TextDecoder();
1581
+ let buffer = "";
1582
+ try {
1583
+ while (true) {
1584
+ const { done, value } = yield new __await(reader.read());
1585
+ if (done) break;
1586
+ buffer += decoder.decode(value, { stream: true });
1587
+ const lines = buffer.split("\n");
1588
+ buffer = lines.pop() || "";
1589
+ for (const line of lines) {
1590
+ if (line.startsWith("data: ")) {
1591
+ const data = line.slice(6);
1592
+ if (data === "[DONE]") continue;
1593
+ try {
1594
+ const parsed = JSON.parse(data);
1595
+ const content = (_b = (_a = parsed.choices[0]) == null ? void 0 : _a.delta) == null ? void 0 : _b.content;
1596
+ if (content) {
1597
+ yield { type: "content", content };
1598
+ }
1599
+ } catch (e) {
1600
+ }
1601
+ }
1602
+ }
1603
+ }
1604
+ } finally {
1605
+ reader.releaseLock();
1606
+ }
1607
+ });
1608
+ }
1609
+ generateObject(request) {
1610
+ return __async(this, null, function* () {
1611
+ const textResponse = yield this.generateText(__spreadProps(__spreadValues({}, request), {
1612
+ messages: [
1613
+ ...request.messages,
1614
+ {
1615
+ role: "system",
1616
+ content: `Respond with valid JSON matching this schema: ${JSON.stringify(request.schema)}`
1617
+ }
1618
+ ]
1619
+ }));
1620
+ const object = JSON.parse(textResponse.text);
1621
+ return {
1622
+ object,
1623
+ text: textResponse.text,
1624
+ usage: textResponse.usage
1625
+ };
1626
+ });
1627
+ }
1628
+ streamObject(request) {
1629
+ return __asyncGenerator(this, null, function* () {
1630
+ let accumulatedText = "";
1631
+ try {
1632
+ for (var iter = __forAwait(this.streamText(request)), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
1633
+ const chunk = temp.value;
1634
+ if (chunk.type === "content") {
1635
+ accumulatedText += chunk.content;
1636
+ try {
1637
+ const partial = JSON.parse(accumulatedText);
1638
+ yield { type: "partial", partial, text: accumulatedText };
1639
+ } catch (e) {
1640
+ }
1641
+ }
1642
+ }
1643
+ } catch (temp) {
1644
+ error = [temp];
1645
+ } finally {
1646
+ try {
1647
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
1648
+ } finally {
1649
+ if (error)
1650
+ throw error[0];
1651
+ }
1652
+ }
1653
+ try {
1654
+ const object = JSON.parse(accumulatedText);
1655
+ yield { type: "complete", object, text: accumulatedText };
1656
+ } catch (e) {
1657
+ yield { type: "error", error: new Error("Invalid JSON in response") };
1658
+ }
1659
+ });
1660
+ }
1661
+ };
1662
+
1663
+ // src/providers/sarvam/sarvam.ts
1664
+ var SarvamProvider = class extends BaseProvider {
1665
+ getDefaultBaseUrl() {
1666
+ return "https://api.sarvam.ai/v1";
1667
+ }
1668
+ generateText(request) {
1669
+ return __async(this, null, function* () {
1670
+ var _a, _b, _c;
1671
+ const messages = this.formatMessages(request);
1672
+ try {
1673
+ const response = yield this.makeRequest(this.getEndpoint("/chat/completions"), {
1674
+ method: "POST",
1675
+ body: JSON.stringify({
1676
+ model: this.config.model,
1677
+ messages: messages.map((m) => ({
1678
+ role: m.role,
1679
+ content: m.content
1680
+ })),
1681
+ max_tokens: this.config.maxTokens,
1682
+ temperature: this.config.temperature,
1683
+ top_p: this.config.topP,
1684
+ stop: this.config.stop
1685
+ })
1686
+ });
1687
+ const data = yield response.json();
1688
+ if (!data.choices || data.choices.length === 0) {
1689
+ throw new ProviderError(
1690
+ "sarvam",
1691
+ "No choices returned from Sarvam API",
1692
+ response.status,
1693
+ { response: data }
1694
+ );
1695
+ }
1696
+ return {
1697
+ text: data.choices[0].message.content,
1698
+ usage: {
1699
+ promptTokens: ((_a = data.usage) == null ? void 0 : _a.prompt_tokens) || 0,
1700
+ completionTokens: ((_b = data.usage) == null ? void 0 : _b.completion_tokens) || 0,
1701
+ totalTokens: ((_c = data.usage) == null ? void 0 : _c.total_tokens) || 0
1702
+ },
1703
+ finishReason: this.mapSarvamFinishReason(data.choices[0].finish_reason)
1704
+ };
1705
+ } catch (error) {
1706
+ throw new ProviderError(
1707
+ "sarvam",
1708
+ error instanceof Error ? error.message : "Unknown error",
1709
+ void 0,
1710
+ { originalError: error }
1711
+ );
1712
+ }
1713
+ });
1714
+ }
1715
+ streamText(request) {
1716
+ return __asyncGenerator(this, null, function* () {
1717
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1718
+ const messages = this.formatMessages(request);
1719
+ try {
1720
+ const response = yield new __await(this.makeRequest(
1721
+ this.getEndpoint("/chat/completions"),
1722
+ {
1723
+ method: "POST",
1724
+ body: JSON.stringify({
1725
+ model: this.config.model,
1726
+ messages: messages.map((m) => ({
1727
+ role: m.role,
1728
+ content: m.content
1729
+ })),
1730
+ max_tokens: this.config.maxTokens,
1731
+ temperature: this.config.temperature,
1732
+ stream: true
1733
+ })
1734
+ },
1735
+ true
1736
+ ));
1737
+ const reader = response.body.getReader();
1738
+ const decoder = new TextDecoder();
1739
+ let buffer = "";
1740
+ while (true) {
1741
+ const { done, value } = yield new __await(reader.read());
1742
+ if (done) break;
1743
+ buffer += decoder.decode(value, { stream: true });
1744
+ const lines = buffer.split("\n");
1745
+ buffer = lines.pop() || "";
1746
+ for (const line of lines) {
1747
+ if (line.startsWith("data: ")) {
1748
+ const data = line.slice(6);
1749
+ if (data === "[DONE]") continue;
1750
+ try {
1751
+ const parsed = JSON.parse(data);
1752
+ const content = (_c = (_b = (_a = parsed.choices) == null ? void 0 : _a[0]) == null ? void 0 : _b.delta) == null ? void 0 : _c.content;
1753
+ if (content) {
1754
+ yield { type: "content", content };
1755
+ }
1756
+ if ((_e = (_d = parsed.choices) == null ? void 0 : _d[0]) == null ? void 0 : _e.finish_reason) {
1757
+ yield {
1758
+ type: "done",
1759
+ done: {
1760
+ finishReason: this.mapSarvamFinishReason(parsed.choices[0].finish_reason),
1761
+ usage: {
1762
+ promptTokens: ((_f = parsed.usage) == null ? void 0 : _f.prompt_tokens) || 0,
1763
+ completionTokens: ((_g = parsed.usage) == null ? void 0 : _g.completion_tokens) || 0,
1764
+ totalTokens: ((_h = parsed.usage) == null ? void 0 : _h.total_tokens) || 0
1765
+ }
1766
+ }
1767
+ };
1768
+ }
1769
+ } catch (e) {
1770
+ }
1771
+ }
1772
+ }
1773
+ }
1774
+ } catch (error) {
1775
+ yield {
1776
+ type: "error",
1777
+ error: new ProviderError(
1778
+ "sarvam",
1779
+ error instanceof Error ? error.message : "Streaming error",
1780
+ void 0,
1781
+ { originalError: error }
1782
+ )
1783
+ };
1784
+ }
1785
+ });
1786
+ }
1787
+ generateObject(request) {
1788
+ return __async(this, null, function* () {
1789
+ const enhancedRequest = __spreadProps(__spreadValues({}, request), {
1790
+ messages: [
1791
+ ...request.messages,
1792
+ {
1793
+ role: "user",
1794
+ content: `Respond with valid JSON matching this schema: ${JSON.stringify(request.schema)}`
1795
+ }
1796
+ ]
1797
+ });
1798
+ const textResponse = yield this.generateText(enhancedRequest);
1799
+ try {
1800
+ const object = JSON.parse(textResponse.text);
1801
+ return {
1802
+ object,
1803
+ text: textResponse.text,
1804
+ usage: textResponse.usage
1805
+ };
1806
+ } catch (error) {
1807
+ throw new ProviderError(
1808
+ "sarvam",
1809
+ `Failed to parse JSON response: ${error instanceof Error ? error.message : "Unknown error"}`,
1810
+ void 0,
1811
+ { responseText: textResponse.text }
1812
+ );
1813
+ }
1814
+ });
1815
+ }
1816
+ streamObject(request) {
1817
+ return __asyncGenerator(this, null, function* () {
1818
+ let accumulatedText = "";
1819
+ try {
1820
+ for (var iter = __forAwait(this.streamText(request)), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
1821
+ const chunk = temp.value;
1822
+ if (chunk.type === "content") {
1823
+ accumulatedText += chunk.content;
1824
+ try {
1825
+ const partial = JSON.parse(accumulatedText);
1826
+ yield { type: "partial", partial, text: accumulatedText };
1827
+ } catch (e) {
1828
+ }
1829
+ }
1830
+ }
1831
+ } catch (temp) {
1832
+ error = [temp];
1833
+ } finally {
1834
+ try {
1835
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
1836
+ } finally {
1837
+ if (error)
1838
+ throw error[0];
1839
+ }
1840
+ }
1841
+ try {
1842
+ const object = JSON.parse(accumulatedText);
1843
+ yield { type: "complete", object, text: accumulatedText };
1844
+ } catch (e) {
1845
+ yield { type: "error", error: new Error("Invalid JSON in response") };
1846
+ }
1847
+ });
1848
+ }
1849
+ /**
1850
+ * Map Sarvam's finish reason to standard format
1851
+ */
1852
+ mapSarvamFinishReason(reason) {
1853
+ const mapping = {
1854
+ "stop": "stop",
1855
+ "length": "length",
1856
+ "max_tokens": "length",
1857
+ "content_filter": "content_filter"
1858
+ };
1859
+ return mapping[reason] || "stop";
1860
+ }
1861
+ };
1862
+
1863
+ // src/providers/factory.ts
1864
+ function createProvider(config) {
1865
+ switch (config.provider) {
1866
+ case "openai":
1867
+ return new OpenAIProvider(config);
1868
+ case "anthropic":
1869
+ return new AnthropicProvider(config);
1870
+ case "google":
1871
+ return new GoogleProvider(config);
1872
+ case "sarvam":
1873
+ return new SarvamProvider(config);
1874
+ case "custom":
1875
+ return new CustomProvider(config);
1876
+ default:
1877
+ throw new Error(`Unknown extended provider: ${config.provider}`);
1878
+ }
1879
+ }
1880
+
1881
+ // src/stream/stream-reader.ts
1882
+ var TransformStream = class {
1883
+ constructor(transformer) {
1884
+ __publicField(this, "transformer");
1885
+ this.transformer = transformer;
1886
+ }
1887
+ transform(source) {
1888
+ return __asyncGenerator(this, null, function* () {
1889
+ try {
1890
+ for (var iter = __forAwait(source), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
1891
+ const chunk = temp.value;
1892
+ yield yield new __await(this.transformer(chunk));
1893
+ }
1894
+ } catch (temp) {
1895
+ error = [temp];
1896
+ } finally {
1897
+ try {
1898
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
1899
+ } finally {
1900
+ if (error)
1901
+ throw error[0];
1902
+ }
1903
+ }
1904
+ });
1905
+ }
1906
+ };
1907
+ var FlareStreamReader = class {
1908
+ constructor(source) {
1909
+ __publicField(this, "source");
1910
+ __publicField(this, "done", false);
1911
+ this.source = source[Symbol.asyncIterator]();
1912
+ }
1913
+ read() {
1914
+ return __async(this, null, function* () {
1915
+ if (this.done) {
1916
+ return { value: void 0, done: true };
1917
+ }
1918
+ const result = yield this.source.next();
1919
+ this.done = result.done || false;
1920
+ return { value: result.value, done: this.done };
1921
+ });
1922
+ }
1923
+ cancel() {
1924
+ this.done = true;
1925
+ if (this.source.return) {
1926
+ this.source.return();
1927
+ }
1928
+ }
1929
+ [Symbol.asyncIterator]() {
1930
+ return __asyncGenerator(this, null, function* () {
1931
+ while (!this.done) {
1932
+ const { value, done } = yield new __await(this.read());
1933
+ if (done) break;
1934
+ yield value;
1935
+ }
1936
+ });
1937
+ }
1938
+ };
1939
+ function createDataStreamWriter() {
1940
+ let controller = null;
1941
+ const encoder = new TextEncoder();
1942
+ const readable = new ReadableStream({
1943
+ start(ctrl) {
1944
+ controller = ctrl;
1945
+ },
1946
+ cancel() {
1947
+ controller = null;
1948
+ }
1949
+ });
1950
+ const write = (data) => {
1951
+ if (controller) {
1952
+ controller.enqueue(encoder.encode(data));
1953
+ }
1954
+ };
1955
+ return {
1956
+ readable,
1957
+ /**
1958
+ * Write data event
1959
+ */
1960
+ writeData(data) {
1961
+ write(`data: ${JSON.stringify(data)}
1962
+
1963
+ `);
1964
+ },
1965
+ /**
1966
+ * Write error event
1967
+ */
1968
+ writeError(error) {
1969
+ write(`event: error
1970
+ data: ${JSON.stringify({
1971
+ message: error.message,
1972
+ code: error.code
1973
+ })}
1974
+
1975
+ `);
1976
+ },
1977
+ /**
1978
+ * Write custom event
1979
+ */
1980
+ writeEvent(event, data) {
1981
+ write(`event: ${event}
1982
+ data: ${JSON.stringify(data)}
1983
+
1984
+ `);
1985
+ },
1986
+ /**
1987
+ * Close the stream
1988
+ */
1989
+ close() {
1990
+ if (controller) {
1991
+ controller.close();
1992
+ controller = null;
1993
+ }
1994
+ }
1995
+ };
1996
+ }
1997
+ function toUiStreamResponse(stream, headers) {
1998
+ const writer = createDataStreamWriter();
1999
+ (() => __async(null, null, function* () {
2000
+ try {
2001
+ try {
2002
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
2003
+ const chunk = temp.value;
2004
+ writer.writeData(chunk);
2005
+ }
2006
+ } catch (temp) {
2007
+ error = [temp];
2008
+ } finally {
2009
+ try {
2010
+ more && (temp = iter.return) && (yield temp.call(iter));
2011
+ } finally {
2012
+ if (error)
2013
+ throw error[0];
2014
+ }
2015
+ }
2016
+ writer.close();
2017
+ } catch (error2) {
2018
+ writer.writeError(error2 instanceof Error ? error2 : new Error(String(error2)));
2019
+ writer.close();
2020
+ }
2021
+ }))();
2022
+ return new Response(writer.readable, {
2023
+ headers: __spreadValues({
2024
+ "Content-Type": "text/event-stream",
2025
+ "Cache-Control": "no-cache",
2026
+ "Connection": "keep-alive"
2027
+ }, headers)
2028
+ });
2029
+ }
2030
+ function parseSSEStream(response) {
2031
+ return __asyncGenerator(this, null, function* () {
2032
+ if (!response.body) {
2033
+ throw new StreamError("Response body is null");
2034
+ }
2035
+ const reader = response.body.getReader();
2036
+ const decoder = new TextDecoder();
2037
+ let buffer = "";
2038
+ try {
2039
+ while (true) {
2040
+ const { done, value } = yield new __await(reader.read());
2041
+ if (done) break;
2042
+ buffer += decoder.decode(value, { stream: true });
2043
+ const lines = buffer.split("\n\n");
2044
+ buffer = lines.pop() || "";
2045
+ for (const line of lines) {
2046
+ if (!line.trim()) continue;
2047
+ const match = line.match(/^data: (.+)$/m);
2048
+ if (match) {
2049
+ try {
2050
+ yield JSON.parse(match[1]);
2051
+ } catch (e) {
2052
+ console.error("Failed to parse SSE data:", e);
2053
+ }
2054
+ }
2055
+ }
2056
+ }
2057
+ } finally {
2058
+ reader.releaseLock();
2059
+ }
2060
+ });
2061
+ }
2062
+ function mergeStreams(...streams) {
2063
+ return __asyncGenerator(this, null, function* () {
2064
+ const iterators = streams.map((s) => s[Symbol.asyncIterator]());
2065
+ const pending = new Set(iterators);
2066
+ while (pending.size > 0) {
2067
+ const results = yield new __await(Promise.race(
2068
+ Array.from(pending).map((it) => __async(null, null, function* () {
2069
+ return { it, result: yield it.next() };
2070
+ }))
2071
+ ));
2072
+ if (results.result.done) {
2073
+ pending.delete(results.it);
2074
+ } else {
2075
+ yield results.result.value;
2076
+ }
2077
+ }
2078
+ });
2079
+ }
2080
+ function bufferStream(stream, size) {
2081
+ return __asyncGenerator(this, null, function* () {
2082
+ let buffer = [];
2083
+ try {
2084
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
2085
+ const item = temp.value;
2086
+ buffer.push(item);
2087
+ if (buffer.length >= size) {
2088
+ yield buffer;
2089
+ buffer = [];
2090
+ }
2091
+ }
2092
+ } catch (temp) {
2093
+ error = [temp];
2094
+ } finally {
2095
+ try {
2096
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
2097
+ } finally {
2098
+ if (error)
2099
+ throw error[0];
2100
+ }
2101
+ }
2102
+ if (buffer.length > 0) {
2103
+ yield buffer;
2104
+ }
2105
+ });
2106
+ }
2107
+ function throttleStream(stream, delayMs) {
2108
+ return __asyncGenerator(this, null, function* () {
2109
+ try {
2110
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
2111
+ const item = temp.value;
2112
+ yield item;
2113
+ yield new __await(new Promise((resolve) => setTimeout(resolve, delayMs)));
2114
+ }
2115
+ } catch (temp) {
2116
+ error = [temp];
2117
+ } finally {
2118
+ try {
2119
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
2120
+ } finally {
2121
+ if (error)
2122
+ throw error[0];
2123
+ }
2124
+ }
2125
+ });
2126
+ }
2127
+
2128
+ // src/stream/stream-client.ts
2129
+ import EventEmitter3 from "eventemitter3";
2130
+ var DEFAULT_CONFIG4 = {
2131
+ maxTokens: 1024,
2132
+ temperature: 0.7,
2133
+ enableQueueing: true,
2134
+ enablePooling: true,
2135
+ enableMetrics: true,
2136
+ retry: {
2137
+ maxRetries: 3,
2138
+ initialDelay: 1e3,
2139
+ maxDelay: 3e4
2140
+ },
2141
+ circuitBreaker: {
2142
+ failureThreshold: 5,
2143
+ resetTimeout: 6e4
2144
+ },
2145
+ rateLimit: {
2146
+ maxRequests: 100,
2147
+ windowMs: 6e4
2148
+ }
2149
+ };
2150
+ var FlareClient = class extends EventEmitter3 {
2151
+ constructor(config) {
2152
+ super();
2153
+ __publicField(this, "config");
2154
+ __publicField(this, "provider");
2155
+ __publicField(this, "retryHandler");
2156
+ __publicField(this, "circuitBreaker");
2157
+ __publicField(this, "rateLimiter");
2158
+ __publicField(this, "requestQueue");
2159
+ __publicField(this, "metrics");
2160
+ __publicField(this, "startTime", Date.now());
2161
+ this.config = __spreadValues(__spreadValues({}, DEFAULT_CONFIG4), config);
2162
+ this.provider = createProvider(this.config);
2163
+ this.retryHandler = new RetryHandler(this.config.retry);
2164
+ this.circuitBreaker = new CircuitBreaker(this.config.circuitBreaker);
2165
+ this.rateLimiter = new RateLimiter(this.config.rateLimit);
2166
+ this.metrics = new MetricsCollector();
2167
+ if (this.config.enableQueueing) {
2168
+ this.requestQueue = new RequestQueue({
2169
+ concurrency: this.config.poolSize || 10
2170
+ });
2171
+ }
2172
+ this.setupEventListeners();
2173
+ }
2174
+ /**
2175
+ * Setup event listeners for monitoring
2176
+ */
2177
+ setupEventListeners() {
2178
+ this.circuitBreaker.on("open", () => {
2179
+ this.emit("circuit-breaker:open");
2180
+ if (this.config.debug) {
2181
+ console.warn("[FlareClient] Circuit breaker opened");
2182
+ }
2183
+ });
2184
+ this.circuitBreaker.on("close", () => {
2185
+ this.emit("circuit-breaker:close");
2186
+ if (this.config.debug) {
2187
+ console.log("[FlareClient] Circuit breaker closed");
2188
+ }
2189
+ });
2190
+ if (this.requestQueue) {
2191
+ this.requestQueue.on("enqueue", (data) => {
2192
+ this.emit("queue:enqueue", data);
2193
+ });
2194
+ this.requestQueue.on("drain", () => {
2195
+ this.emit("queue:drain");
2196
+ });
2197
+ }
2198
+ }
2199
+ /**
2200
+ * Generate text synchronously
2201
+ * @param request - Text generation request
2202
+ * @returns Generated text response
2203
+ */
2204
+ generateText(request) {
2205
+ return __async(this, null, function* () {
2206
+ var _a, _b;
2207
+ const startTime = Date.now();
2208
+ try {
2209
+ yield this.rateLimiter.acquire((_a = this.config.rateLimit) == null ? void 0 : _a.clientId);
2210
+ const execute = () => __async(this, null, function* () {
2211
+ return yield this.circuitBreaker.execute(() => __async(this, null, function* () {
2212
+ const mergedConfig = __spreadValues(__spreadValues({}, this.config), request.config);
2213
+ return yield this.provider.generateText(__spreadProps(__spreadValues({}, request), {
2214
+ config: mergedConfig
2215
+ }));
2216
+ }));
2217
+ });
2218
+ let result;
2219
+ if (this.requestQueue && this.config.enableQueueing) {
2220
+ result = yield this.requestQueue.add(
2221
+ () => this.retryHandler.execute(execute),
2222
+ ((_b = request.config) == null ? void 0 : _b.queuePriority) || 0
2223
+ );
2224
+ } else {
2225
+ result = yield this.retryHandler.execute(execute);
2226
+ }
2227
+ this.metrics.recordSuccess(Date.now() - startTime);
2228
+ this.emit("request:success", { latency: Date.now() - startTime });
2229
+ return result;
2230
+ } catch (error) {
2231
+ this.metrics.recordFailure(Date.now() - startTime);
2232
+ this.emit("request:error", { error, latency: Date.now() - startTime });
2233
+ throw error;
2234
+ }
2235
+ });
2236
+ }
2237
+ /**
2238
+ * Stream text generation
2239
+ * @param request - Text generation request
2240
+ * @returns Async iterable of text chunks
2241
+ */
2242
+ streamText(request) {
2243
+ return __asyncGenerator(this, null, function* () {
2244
+ var _a;
2245
+ const startTime = Date.now();
2246
+ try {
2247
+ yield new __await(this.rateLimiter.acquire((_a = this.config.rateLimit) == null ? void 0 : _a.clientId));
2248
+ const stream = this.provider.streamText(request);
2249
+ try {
2250
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
2251
+ const chunk = temp.value;
2252
+ yield chunk;
2253
+ }
2254
+ } catch (temp) {
2255
+ error = [temp];
2256
+ } finally {
2257
+ try {
2258
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
2259
+ } finally {
2260
+ if (error)
2261
+ throw error[0];
2262
+ }
2263
+ }
2264
+ this.metrics.recordSuccess(Date.now() - startTime);
2265
+ this.emit("request:success", { latency: Date.now() - startTime, streaming: true });
2266
+ } catch (error2) {
2267
+ this.metrics.recordFailure(Date.now() - startTime);
2268
+ this.emit("request:error", { error: error2, latency: Date.now() - startTime, streaming: true });
2269
+ throw error2;
2270
+ }
2271
+ });
2272
+ }
2273
+ /**
2274
+ * Generate structured object
2275
+ * @param request - Object generation request
2276
+ * @returns Generated object response
2277
+ */
2278
+ generateObject(request) {
2279
+ return __async(this, null, function* () {
2280
+ var _a, _b;
2281
+ const startTime = Date.now();
2282
+ try {
2283
+ yield this.rateLimiter.acquire((_a = this.config.rateLimit) == null ? void 0 : _a.clientId);
2284
+ const execute = () => __async(this, null, function* () {
2285
+ return yield this.circuitBreaker.execute(() => __async(this, null, function* () {
2286
+ return yield this.provider.generateObject(request);
2287
+ }));
2288
+ });
2289
+ let result;
2290
+ if (this.requestQueue && this.config.enableQueueing) {
2291
+ result = yield this.requestQueue.add(
2292
+ () => this.retryHandler.execute(execute),
2293
+ ((_b = request.config) == null ? void 0 : _b.queuePriority) || 0
2294
+ );
2295
+ } else {
2296
+ result = yield this.retryHandler.execute(execute);
2297
+ }
2298
+ this.metrics.recordSuccess(Date.now() - startTime);
2299
+ return result;
2300
+ } catch (error) {
2301
+ this.metrics.recordFailure(Date.now() - startTime);
2302
+ throw error;
2303
+ }
2304
+ });
2305
+ }
2306
+ /**
2307
+ * Stream object generation
2308
+ * @param request - Object generation request
2309
+ * @returns Async iterable of object chunks
2310
+ */
2311
+ streamObject(request) {
2312
+ return __asyncGenerator(this, null, function* () {
2313
+ var _a;
2314
+ const startTime = Date.now();
2315
+ try {
2316
+ yield new __await(this.rateLimiter.acquire((_a = this.config.rateLimit) == null ? void 0 : _a.clientId));
2317
+ const stream = this.provider.streamObject(request);
2318
+ try {
2319
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
2320
+ const chunk = temp.value;
2321
+ yield chunk;
2322
+ }
2323
+ } catch (temp) {
2324
+ error = [temp];
2325
+ } finally {
2326
+ try {
2327
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
2328
+ } finally {
2329
+ if (error)
2330
+ throw error[0];
2331
+ }
2332
+ }
2333
+ this.metrics.recordSuccess(Date.now() - startTime);
2334
+ } catch (error2) {
2335
+ this.metrics.recordFailure(Date.now() - startTime);
2336
+ throw error2;
2337
+ }
2338
+ });
2339
+ }
2340
+ /**
2341
+ * Get health status
2342
+ */
2343
+ getHealth() {
2344
+ var _a, _b;
2345
+ const metrics = this.metrics.getMetrics();
2346
+ let status = "healthy";
2347
+ if (this.circuitBreaker.getState() === "open") {
2348
+ status = "unhealthy";
2349
+ } else if (metrics.failedRequests > metrics.successfulRequests * 0.1) {
2350
+ status = "degraded";
2351
+ }
2352
+ return {
2353
+ status,
2354
+ timestamp: Date.now(),
2355
+ uptime: Date.now() - this.startTime,
2356
+ circuitBreaker: this.circuitBreaker.getState(),
2357
+ activeConnections: (_a = this.requestQueue) == null ? void 0 : _a.getRunning(),
2358
+ queueSize: (_b = this.requestQueue) == null ? void 0 : _b.size(),
2359
+ metrics
2360
+ };
2361
+ }
2362
+ /**
2363
+ * Get performance metrics
2364
+ */
2365
+ getMetrics() {
2366
+ return this.metrics.getDetailedStats();
2367
+ }
2368
+ /**
2369
+ * Update configuration
2370
+ */
2371
+ updateConfig(config) {
2372
+ this.config = __spreadValues(__spreadValues({}, this.config), config);
2373
+ if (config.retry) {
2374
+ this.retryHandler.updateConfig(config.retry);
2375
+ }
2376
+ if (config.rateLimit) {
2377
+ this.rateLimiter = new RateLimiter(config.rateLimit);
2378
+ }
2379
+ }
2380
+ /**
2381
+ * Reset circuit breaker
2382
+ */
2383
+ resetCircuitBreaker() {
2384
+ this.circuitBreaker.reset();
2385
+ }
2386
+ /**
2387
+ * Clean up resources
2388
+ */
2389
+ destroy() {
2390
+ this.circuitBreaker.destroy();
2391
+ this.rateLimiter.destroy();
2392
+ if (this.requestQueue) {
2393
+ this.requestQueue.clear();
2394
+ }
2395
+ this.removeAllListeners();
2396
+ }
2397
+ };
2398
+ function createFlareClient(config) {
2399
+ return new FlareClient(config);
2400
+ }
2401
+ export {
2402
+ AnthropicProvider,
2403
+ AuthenticationError,
2404
+ BaseProvider,
2405
+ CircuitBreaker,
2406
+ CircuitBreakerError,
2407
+ CircuitState,
2408
+ ContentFilterError,
2409
+ CustomProvider,
2410
+ FlareClient,
2411
+ FlareError,
2412
+ FlareStreamReader,
2413
+ GoogleProvider,
2414
+ MetricsCollector,
2415
+ NetworkError,
2416
+ OpenAIProvider,
2417
+ ParseError,
2418
+ ProviderError,
2419
+ RateLimitError,
2420
+ RateLimiter,
2421
+ RequestQueue,
2422
+ RetryHandler,
2423
+ SarvamProvider,
2424
+ StreamError,
2425
+ TimeoutError,
2426
+ TransformStream,
2427
+ ValidationError,
2428
+ bufferStream,
2429
+ createCircuitBreaker,
2430
+ createDataStreamWriter,
2431
+ createFlareClient,
2432
+ createMetricsCollector,
2433
+ createProvider,
2434
+ createRateLimiter,
2435
+ createRequestQueue,
2436
+ createRetryHandler,
2437
+ getErrorStatusCode,
2438
+ getGlobalMetrics,
2439
+ isRetryableError,
2440
+ measureLatency,
2441
+ mergeStreams,
2442
+ parseSSEStream,
2443
+ throttleStream,
2444
+ toUiStreamResponse,
2445
+ withRetry
2446
+ };
2447
+ //# sourceMappingURL=index.mjs.map