@vfarcic/dot-ai 1.15.0 → 1.15.2
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/core/circuit-breaker.d.ts +4 -0
- package/dist/core/circuit-breaker.d.ts.map +1 -1
- package/dist/core/circuit-breaker.js +34 -11
- package/dist/core/embedding-service.d.ts +3 -0
- package/dist/core/embedding-service.d.ts.map +1 -1
- package/dist/core/embedding-service.js +16 -2
- package/dist/core/providers/vercel-provider.d.ts.map +1 -1
- package/dist/core/providers/vercel-provider.js +20 -8
- package/package.json +1 -1
|
@@ -80,6 +80,10 @@ export declare class CircuitBreaker {
|
|
|
80
80
|
private openedAt?;
|
|
81
81
|
private halfOpenAttempts;
|
|
82
82
|
private lastCircuitOpenLogTime?;
|
|
83
|
+
private lastFailureLogTime?;
|
|
84
|
+
private suppressedFailureLogCount;
|
|
85
|
+
/** Minimum interval between failure WARN logs (ms) */
|
|
86
|
+
private static readonly FAILURE_LOG_INTERVAL_MS;
|
|
83
87
|
constructor(name: string, config?: CircuitBreakerConfig, logger?: Logger);
|
|
84
88
|
/**
|
|
85
89
|
* Execute an operation through the circuit breaker
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/core/circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AAEzD;;GAEG;AACH,oBAAY,YAAY;IACtB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,SAAS,cAAc;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kFAAkF;IAClF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kCAAkC;IAClC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9E;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,YAAY,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,SAAgB,WAAW,EAAE,MAAM,CAAC;IACpC,SAAgB,mBAAmB,EAAE,MAAM,CAAC;IAC5C,SAAgB,KAAK,EAAE,YAAY,CAAC;gBAExB,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/core/circuit-breaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -65,13 +65,17 @@ class CircuitBreaker {
|
|
|
65
65
|
openedAt;
|
|
66
66
|
halfOpenAttempts = 0;
|
|
67
67
|
lastCircuitOpenLogTime;
|
|
68
|
+
lastFailureLogTime;
|
|
69
|
+
suppressedFailureLogCount = 0;
|
|
70
|
+
/** Minimum interval between failure WARN logs (ms) */
|
|
71
|
+
static FAILURE_LOG_INTERVAL_MS = 30000;
|
|
68
72
|
constructor(name, config, logger) {
|
|
69
73
|
this.name = name;
|
|
70
74
|
this.config = {
|
|
71
75
|
failureThreshold: config?.failureThreshold ?? 3,
|
|
72
76
|
cooldownPeriodMs: config?.cooldownPeriodMs ?? 30000,
|
|
73
77
|
halfOpenMaxAttempts: config?.halfOpenMaxAttempts ?? 1,
|
|
74
|
-
onStateChange: config?.onStateChange
|
|
78
|
+
onStateChange: config?.onStateChange,
|
|
75
79
|
};
|
|
76
80
|
this.logger = logger ?? new error_handling_1.ConsoleLogger('CircuitBreaker');
|
|
77
81
|
}
|
|
@@ -89,7 +93,7 @@ class CircuitBreaker {
|
|
|
89
93
|
this.lastCircuitOpenLogTime < this.openedAt) {
|
|
90
94
|
this.logger.warn(`Circuit '${this.name}' is open, blocking requests`, {
|
|
91
95
|
remainingCooldownMs: remainingCooldown,
|
|
92
|
-
willRetryAt: new Date(Date.now() + remainingCooldown).toISOString()
|
|
96
|
+
willRetryAt: new Date(Date.now() + remainingCooldown).toISOString(),
|
|
93
97
|
});
|
|
94
98
|
this.lastCircuitOpenLogTime = new Date();
|
|
95
99
|
}
|
|
@@ -100,7 +104,7 @@ class CircuitBreaker {
|
|
|
100
104
|
this.halfOpenAttempts++;
|
|
101
105
|
this.logger.info(`Circuit '${this.name}' attempting request in half-open state`, {
|
|
102
106
|
attempt: this.halfOpenAttempts,
|
|
103
|
-
maxAttempts: this.config.halfOpenMaxAttempts
|
|
107
|
+
maxAttempts: this.config.halfOpenMaxAttempts,
|
|
104
108
|
});
|
|
105
109
|
}
|
|
106
110
|
try {
|
|
@@ -125,7 +129,7 @@ class CircuitBreaker {
|
|
|
125
129
|
this.transitionTo(CircuitState.CLOSED);
|
|
126
130
|
this.halfOpenAttempts = 0;
|
|
127
131
|
this.logger.info(`Circuit '${this.name}' recovered, transitioning to closed`, {
|
|
128
|
-
totalSuccesses: this.totalSuccesses
|
|
132
|
+
totalSuccesses: this.totalSuccesses,
|
|
129
133
|
});
|
|
130
134
|
}
|
|
131
135
|
}
|
|
@@ -136,11 +140,27 @@ class CircuitBreaker {
|
|
|
136
140
|
this.consecutiveFailures++;
|
|
137
141
|
this.totalFailures++;
|
|
138
142
|
this.lastFailureTime = new Date();
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
// Rate-limit failure WARN logs to avoid log spam during sustained outages
|
|
144
|
+
const now = Date.now();
|
|
145
|
+
const shouldLogFailure = !this.lastFailureLogTime ||
|
|
146
|
+
now - this.lastFailureLogTime.getTime() >=
|
|
147
|
+
CircuitBreaker.FAILURE_LOG_INTERVAL_MS;
|
|
148
|
+
if (shouldLogFailure) {
|
|
149
|
+
const logData = {
|
|
150
|
+
consecutiveFailures: this.consecutiveFailures,
|
|
151
|
+
threshold: this.config.failureThreshold,
|
|
152
|
+
error: error?.message,
|
|
153
|
+
};
|
|
154
|
+
if (this.suppressedFailureLogCount > 0) {
|
|
155
|
+
logData.suppressedLogCount = this.suppressedFailureLogCount;
|
|
156
|
+
}
|
|
157
|
+
this.logger.warn(`Circuit '${this.name}' recorded failure`, logData);
|
|
158
|
+
this.lastFailureLogTime = new Date(now);
|
|
159
|
+
this.suppressedFailureLogCount = 0;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
this.suppressedFailureLogCount++;
|
|
163
|
+
}
|
|
144
164
|
if (this.state === CircuitState.HALF_OPEN) {
|
|
145
165
|
// Failure in half-open state opens the circuit again
|
|
146
166
|
this.transitionTo(CircuitState.OPEN);
|
|
@@ -148,7 +168,8 @@ class CircuitBreaker {
|
|
|
148
168
|
this.halfOpenAttempts = 0;
|
|
149
169
|
this.logger.warn(`Circuit '${this.name}' failed in half-open state, reopening`);
|
|
150
170
|
}
|
|
151
|
-
else if (this.state === CircuitState.CLOSED &&
|
|
171
|
+
else if (this.state === CircuitState.CLOSED &&
|
|
172
|
+
this.consecutiveFailures >= this.config.failureThreshold) {
|
|
152
173
|
// Threshold reached, open the circuit
|
|
153
174
|
this.transitionTo(CircuitState.OPEN);
|
|
154
175
|
this.openedAt = new Date();
|
|
@@ -165,6 +186,8 @@ class CircuitBreaker {
|
|
|
165
186
|
this.halfOpenAttempts = 0;
|
|
166
187
|
this.openedAt = undefined;
|
|
167
188
|
this.lastCircuitOpenLogTime = undefined;
|
|
189
|
+
this.lastFailureLogTime = undefined;
|
|
190
|
+
this.suppressedFailureLogCount = 0;
|
|
168
191
|
if (previousState !== CircuitState.CLOSED) {
|
|
169
192
|
this.logger.info(`Circuit '${this.name}' manually reset to closed`);
|
|
170
193
|
this.config.onStateChange?.(previousState, CircuitState.CLOSED, this.name);
|
|
@@ -194,7 +217,7 @@ class CircuitBreaker {
|
|
|
194
217
|
lastFailureTime: this.lastFailureTime,
|
|
195
218
|
lastSuccessTime: this.lastSuccessTime,
|
|
196
219
|
openedAt: this.openedAt,
|
|
197
|
-
halfOpenAttempts: this.halfOpenAttempts
|
|
220
|
+
halfOpenAttempts: this.halfOpenAttempts,
|
|
198
221
|
};
|
|
199
222
|
}
|
|
200
223
|
/**
|
|
@@ -50,6 +50,9 @@ export declare class VercelEmbeddingProvider implements EmbeddingProvider {
|
|
|
50
50
|
*/
|
|
51
51
|
export declare class EmbeddingService {
|
|
52
52
|
private provider;
|
|
53
|
+
private lastBatchFailureLogTime?;
|
|
54
|
+
private suppressedBatchFailureCount;
|
|
55
|
+
private static readonly BATCH_FAILURE_LOG_INTERVAL_MS;
|
|
53
56
|
constructor(config?: EmbeddingConfig);
|
|
54
57
|
/**
|
|
55
58
|
* Generate embedding for text
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedding-service.d.ts","sourceRoot":"","sources":["../../src/core/embedding-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAEL,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAc3B;;GAEG;AACH,eAAO,MAAM,mBAAmB,iDAItB,CAAC;AACX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,MAAM,CAAC;IACxB,QAAQ,IAAI,MAAM,CAAC;CACpB;AAgBD;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,iBAAiB;IAC/D,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,aAAa,CAA6B;gBAEtC,MAAM,EAAE,eAAe,GAAG;QAAE,QAAQ,EAAE,qBAAqB,CAAA;KAAE;IAmFnE,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAgElD,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IA2E9D,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,MAAM;IAIvB,QAAQ,IAAI,MAAM;IAIlB,eAAe,IAAI,MAAM;CAG1B;AAqCD;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAA2B;
|
|
1
|
+
{"version":3,"file":"embedding-service.d.ts","sourceRoot":"","sources":["../../src/core/embedding-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAEL,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAc3B;;GAEG;AACH,eAAO,MAAM,mBAAmB,iDAItB,CAAC;AACX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,MAAM,CAAC;IACxB,QAAQ,IAAI,MAAM,CAAC;CACpB;AAgBD;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,iBAAiB;IAC/D,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,aAAa,CAA6B;gBAEtC,MAAM,EAAE,eAAe,GAAG;QAAE,QAAQ,EAAE,qBAAqB,CAAA;KAAE;IAmFnE,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAgElD,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IA2E9D,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,MAAM;IAIvB,QAAQ,IAAI,MAAM;IAIlB,eAAe,IAAI,MAAM;CAG1B;AAqCD;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,uBAAuB,CAAC,CAAS;IACzC,OAAO,CAAC,2BAA2B,CAAa;IAChD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,6BAA6B,CAAS;gBAElD,MAAM,GAAE,eAAoB;IAKxC;;;OAGG;IACG,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAgBxD;;;OAGG;IACG,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IA8B9D;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,SAAS,IAAI;QACX,SAAS,EAAE,OAAO,CAAC;QACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAqCD;;OAEG;IACH,uBAAuB,CAAC,OAAO,EAAE;QAC/B,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,MAAM;IAYV;;;OAGG;IACH,sBAAsB,IAAI,mBAAmB,GAAG,IAAI;CAGrD"}
|
|
@@ -272,6 +272,9 @@ function createEmbeddingProvider(config = {}) {
|
|
|
272
272
|
*/
|
|
273
273
|
class EmbeddingService {
|
|
274
274
|
provider;
|
|
275
|
+
lastBatchFailureLogTime;
|
|
276
|
+
suppressedBatchFailureCount = 0;
|
|
277
|
+
static BATCH_FAILURE_LOG_INTERVAL_MS = 30000;
|
|
275
278
|
constructor(config = {}) {
|
|
276
279
|
// Use factory to initialize appropriate provider
|
|
277
280
|
this.provider = createEmbeddingProvider(config);
|
|
@@ -304,8 +307,19 @@ class EmbeddingService {
|
|
|
304
307
|
return await this.provider.generateEmbeddings(texts);
|
|
305
308
|
}
|
|
306
309
|
catch (error) {
|
|
307
|
-
//
|
|
308
|
-
|
|
310
|
+
// Rate-limit fallback warnings to avoid log spam during sustained outages
|
|
311
|
+
const now = Date.now();
|
|
312
|
+
if (!this.lastBatchFailureLogTime ||
|
|
313
|
+
now - this.lastBatchFailureLogTime >=
|
|
314
|
+
EmbeddingService.BATCH_FAILURE_LOG_INTERVAL_MS) {
|
|
315
|
+
const suppressed = this.suppressedBatchFailureCount;
|
|
316
|
+
this.suppressedBatchFailureCount = 0;
|
|
317
|
+
this.lastBatchFailureLogTime = now;
|
|
318
|
+
console.warn('Batch embedding generation failed, falling back to keyword search:', error instanceof Error ? error.message : String(error), suppressed > 0 ? `(${suppressed} similar warnings suppressed)` : '');
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
this.suppressedBatchFailureCount++;
|
|
322
|
+
}
|
|
309
323
|
return [];
|
|
310
324
|
}
|
|
311
325
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vercel-provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/vercel-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,0BAA0B,CAAC;AA4DlC,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,aAAa,CAAC,CAAyB;IAC/C,OAAO,CAAC,aAAa,CAAiB;gBAE1B,MAAM,EAAE,gBAAgB;IAYpC,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,eAAe;
|
|
1
|
+
{"version":3,"file":"vercel-provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/vercel-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,0BAA0B,CAAC;AA4DlC,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,aAAa,CAAC,CAAyB;IAC/C,OAAO,CAAC,aAAa,CAAiB;gBAE1B,MAAM,EAAE,gBAAgB;IAYpC,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,eAAe;IAyJvB,eAAe,IAAI,MAAM;IAIzB,eAAe,IAAI,MAAM;IAIzB,YAAY,IAAI,MAAM;IAItB,aAAa,IAAI,OAAO;IAIxB,OAAO,CAAC,iBAAiB;IAyBnB,WAAW,CACf,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAkB,EAC7B,iBAAiB,CAAC,EAAE;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GACA,OAAO,CAAC,UAAU,CAAC;IAsJtB;;;;;;;;;;;;OAYG;IACG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CA6b/D"}
|
|
@@ -83,18 +83,30 @@ class VercelProvider {
|
|
|
83
83
|
break;
|
|
84
84
|
case 'anthropic':
|
|
85
85
|
case 'anthropic_opus':
|
|
86
|
-
case 'anthropic_haiku':
|
|
86
|
+
case 'anthropic_haiku': {
|
|
87
|
+
// Detect Authorization header in custom headers (case-insensitive).
|
|
88
|
+
// Corporate proxies expect Authorization: Bearer auth, but apiKey sends x-api-key.
|
|
89
|
+
// When Authorization is present, extract the Bearer token and pass it as authToken
|
|
90
|
+
// so the SDK sends Authorization: Bearer instead of x-api-key.
|
|
91
|
+
const authHeaderKey = this.customHeaders
|
|
92
|
+
? Object.keys(this.customHeaders).find(key => key.toLowerCase() === 'authorization')
|
|
93
|
+
: undefined;
|
|
94
|
+
const authOpt = authHeaderKey
|
|
95
|
+
? {
|
|
96
|
+
authToken: this.customHeaders[authHeaderKey].replace(/^Bearer\s+/i, ''),
|
|
97
|
+
}
|
|
98
|
+
: { apiKey: this.apiKey };
|
|
99
|
+
// Strip Authorization from custom headers when using authToken (SDK generates it)
|
|
100
|
+
const filteredCustomHeaders = authHeaderKey && this.customHeaders
|
|
101
|
+
? Object.fromEntries(Object.entries(this.customHeaders).filter(([key]) => key.toLowerCase() !== 'authorization'))
|
|
102
|
+
: this.customHeaders;
|
|
87
103
|
provider = (0, anthropic_1.createAnthropic)({
|
|
88
|
-
|
|
104
|
+
...authOpt,
|
|
89
105
|
...baseURLOpt,
|
|
90
|
-
|
|
91
|
-
// Required for models like claude-sonnet-4-5-20250929
|
|
92
|
-
// PRD #443: Custom headers merge with (and can override) the anthropic-beta default
|
|
93
|
-
headers: mergeHeaders({
|
|
94
|
-
'anthropic-beta': 'context-1m-2025-08-07',
|
|
95
|
-
}),
|
|
106
|
+
...(filteredCustomHeaders && { headers: filteredCustomHeaders }),
|
|
96
107
|
});
|
|
97
108
|
break;
|
|
109
|
+
}
|
|
98
110
|
case 'xai':
|
|
99
111
|
provider = (0, xai_1.createXai)({
|
|
100
112
|
apiKey: this.apiKey,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vfarcic/dot-ai",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.2",
|
|
4
4
|
"description": "AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance",
|
|
5
5
|
"mcpName": "io.github.vfarcic/dot-ai",
|
|
6
6
|
"main": "dist/index.js",
|