@devilsdev/rag-connectors 3.3.0 → 3.5.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.cjs +109 -15
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -363,6 +363,7 @@ var require_anthropic_connector = __commonJS({
|
|
|
363
363
|
var loadAxios = () => require("axios");
|
|
364
364
|
var { BaseConnector } = require_base_connector();
|
|
365
365
|
var {
|
|
366
|
+
cleanAxiosErrors,
|
|
366
367
|
missingApiKeyError,
|
|
367
368
|
raceAbort,
|
|
368
369
|
resolveApiKey,
|
|
@@ -374,6 +375,38 @@ var require_anthropic_connector = __commonJS({
|
|
|
374
375
|
var { componentCacheKey } = require_component_keys();
|
|
375
376
|
var API_KEY_ENV = "ANTHROPIC_API_KEY";
|
|
376
377
|
var API_DEFAULT_TEMPERATURE = 1;
|
|
378
|
+
var NO_TEMPERATURE = /* @__PURE__ */ new Set();
|
|
379
|
+
var warnedTemperature = /* @__PURE__ */ new Set();
|
|
380
|
+
function isTemperatureRejection(error) {
|
|
381
|
+
const response = error && error.response;
|
|
382
|
+
if (!response || response.status !== 400) return false;
|
|
383
|
+
const data = response.data;
|
|
384
|
+
if (!data || typeof data.pipe === "function") return true;
|
|
385
|
+
const message = data.error && data.error.message || (typeof data === "string" ? data : "");
|
|
386
|
+
return /temperature/i.test(message);
|
|
387
|
+
}
|
|
388
|
+
function warnTemperatureDropped(model, temperature) {
|
|
389
|
+
if (warnedTemperature.has(model)) return;
|
|
390
|
+
warnedTemperature.add(model);
|
|
391
|
+
process.emitWarning(
|
|
392
|
+
`${model} does not accept temperature ${temperature}; sent without it (the API default). Claude 4.7 and later models accept only the default.`,
|
|
393
|
+
{ code: "RAG_ANTHROPIC_TEMPERATURE" }
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
function responseText(data) {
|
|
397
|
+
const blocks = Array.isArray(data && data.content) ? data.content : [];
|
|
398
|
+
const text = blocks.filter(
|
|
399
|
+
(b) => b && typeof b.text === "string" && (b.type === "text" || b.type === void 0)
|
|
400
|
+
).map((b) => b.text).join("");
|
|
401
|
+
if (text) return text;
|
|
402
|
+
const stop = data && data.stop_reason;
|
|
403
|
+
const error = new Error(
|
|
404
|
+
stop === "refusal" ? "Claude declined to answer (stop_reason: refusal)" : stop === "max_tokens" ? "Claude reached maxTokens before writing an answer (stop_reason: max_tokens); raise maxTokens" : `Claude returned no text (stop_reason: ${stop || "unknown"})`
|
|
405
|
+
);
|
|
406
|
+
error.code = stop === "refusal" ? "MODEL_REFUSED" : "NO_TEXT";
|
|
407
|
+
error.stopReason = stop || null;
|
|
408
|
+
throw error;
|
|
409
|
+
}
|
|
377
410
|
var DEFAULT_CONFIG = {
|
|
378
411
|
model: "claude-sonnet-5-5",
|
|
379
412
|
baseURL: "https://api.anthropic.com",
|
|
@@ -431,6 +464,7 @@ var require_anthropic_connector = __commonJS({
|
|
|
431
464
|
"content-type": "application/json"
|
|
432
465
|
}
|
|
433
466
|
});
|
|
467
|
+
cleanAxiosErrors(this.client, "Anthropic");
|
|
434
468
|
}
|
|
435
469
|
/**
|
|
436
470
|
* @throws {Error} code MISSING_API_KEY when no key is configured
|
|
@@ -466,7 +500,7 @@ var require_anthropic_connector = __commonJS({
|
|
|
466
500
|
messages: [{ role: "user", content: prompt.user }]
|
|
467
501
|
};
|
|
468
502
|
const temperature = options.temperature ?? this.config.temperature;
|
|
469
|
-
if (temperature !== void 0 && temperature !== API_DEFAULT_TEMPERATURE) {
|
|
503
|
+
if (temperature !== void 0 && temperature !== API_DEFAULT_TEMPERATURE && !NO_TEMPERATURE.has(body.model)) {
|
|
470
504
|
body.temperature = temperature;
|
|
471
505
|
}
|
|
472
506
|
if (prompt.system) body.system = prompt.system;
|
|
@@ -479,26 +513,69 @@ var require_anthropic_connector = __commonJS({
|
|
|
479
513
|
* @param {Array<Object|string>} [context=[]] - Retrieved documents for RAG
|
|
480
514
|
* @param {Object} [options={}] - Override model, temperature, maxTokens per-call
|
|
481
515
|
* @param {AbortSignal} [options.signal] - Cancels the request
|
|
482
|
-
* @returns {Promise<string>} The
|
|
516
|
+
* @returns {Promise<string>} The answer: every text block of the reply,
|
|
517
|
+
* joined. Rejects (code MODEL_REFUSED or NO_TEXT) when the reply has no
|
|
518
|
+
* text, such as a refusal or a reply that ran out of maxTokens while
|
|
519
|
+
* thinking.
|
|
483
520
|
*/
|
|
484
521
|
async generate(query, context = [], options = {}) {
|
|
522
|
+
return (await this.generateWithUsage(query, context, options)).text;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Like generate(), with the reply's token usage. The LLM judge uses it so
|
|
526
|
+
* `check.judge.usage` reports what the judge cost.
|
|
527
|
+
*
|
|
528
|
+
* @param {string} query
|
|
529
|
+
* @param {Array<Object|string>} [context=[]]
|
|
530
|
+
* @param {Object} [options={}] - As for generate()
|
|
531
|
+
* @returns {Promise<{text: string, usage: {inputTokens: number, outputTokens: number, totalTokens: number}}>}
|
|
532
|
+
*/
|
|
533
|
+
async generateWithUsage(query, context = [], options = {}) {
|
|
485
534
|
const { signal } = options;
|
|
486
535
|
throwIfAborted(signal);
|
|
487
536
|
this._requireApiKey();
|
|
488
537
|
const body = this._buildBody(query, context, options);
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
538
|
+
const data = await this._post(body, signal);
|
|
539
|
+
const text = responseText(data);
|
|
540
|
+
const u = data.usage || {};
|
|
541
|
+
const inputTokens = (u.input_tokens || 0) + (u.cache_creation_input_tokens || 0) + (u.cache_read_input_tokens || 0);
|
|
542
|
+
const outputTokens = u.output_tokens || 0;
|
|
543
|
+
return {
|
|
544
|
+
text,
|
|
545
|
+
usage: {
|
|
546
|
+
inputTokens,
|
|
547
|
+
outputTokens,
|
|
548
|
+
totalTokens: inputTokens + outputTokens
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* POST a Messages request with retries; a model that rejects
|
|
554
|
+
* `temperature` gets the request again without it.
|
|
555
|
+
* @private
|
|
556
|
+
*/
|
|
557
|
+
async _post(body, signal) {
|
|
558
|
+
const send = (b) => this.withRetry(
|
|
559
|
+
async () => (await this.client.post(
|
|
560
|
+
"/v1/messages",
|
|
561
|
+
b,
|
|
562
|
+
signal ? { signal } : void 0
|
|
563
|
+
)).data,
|
|
498
564
|
this.config.maxRetries,
|
|
499
565
|
this.config.retryDelay,
|
|
500
566
|
{ signal }
|
|
501
567
|
);
|
|
568
|
+
try {
|
|
569
|
+
return await send(body);
|
|
570
|
+
} catch (error) {
|
|
571
|
+
if (body.temperature === void 0 || !isTemperatureRejection(error)) {
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
574
|
+
NO_TEMPERATURE.add(body.model);
|
|
575
|
+
warnTemperatureDropped(body.model, body.temperature);
|
|
576
|
+
const { temperature: _t, ...rest } = body;
|
|
577
|
+
return send(rest);
|
|
578
|
+
}
|
|
502
579
|
}
|
|
503
580
|
/**
|
|
504
581
|
* Stream a response from Claude token-by-token via SSE.
|
|
@@ -513,14 +590,27 @@ var require_anthropic_connector = __commonJS({
|
|
|
513
590
|
const { signal } = options;
|
|
514
591
|
throwIfAborted(signal);
|
|
515
592
|
this._requireApiKey();
|
|
516
|
-
|
|
517
|
-
const
|
|
518
|
-
this.client.post("/v1/messages",
|
|
593
|
+
let body = { ...this._buildBody(query, context, options), stream: true };
|
|
594
|
+
const open = (b) => raceAbort(
|
|
595
|
+
this.client.post("/v1/messages", b, {
|
|
519
596
|
responseType: "stream",
|
|
520
597
|
...signalOptions(signal)
|
|
521
598
|
}),
|
|
522
599
|
signal
|
|
523
600
|
);
|
|
601
|
+
let response;
|
|
602
|
+
try {
|
|
603
|
+
response = await open(body);
|
|
604
|
+
} catch (error) {
|
|
605
|
+
if (body.temperature === void 0 || !isTemperatureRejection(error)) {
|
|
606
|
+
throw error;
|
|
607
|
+
}
|
|
608
|
+
NO_TEMPERATURE.add(body.model);
|
|
609
|
+
warnTemperatureDropped(body.model, body.temperature);
|
|
610
|
+
const { temperature: _t, ...rest } = body;
|
|
611
|
+
body = rest;
|
|
612
|
+
response = await open(body);
|
|
613
|
+
}
|
|
524
614
|
let buffer = "";
|
|
525
615
|
for await (const text of textChunks(response.data)) {
|
|
526
616
|
throwIfAborted(signal);
|
|
@@ -560,7 +650,7 @@ var require_anthropic_connector = __commonJS({
|
|
|
560
650
|
return buildRagPrompt(query, context).user;
|
|
561
651
|
}
|
|
562
652
|
};
|
|
563
|
-
module2.exports = { AnthropicConnector, DEFAULT_CONFIG };
|
|
653
|
+
module2.exports = { AnthropicConnector, DEFAULT_CONFIG, responseText };
|
|
564
654
|
}
|
|
565
655
|
});
|
|
566
656
|
|
|
@@ -572,6 +662,7 @@ var require_cohere_connector = __commonJS({
|
|
|
572
662
|
var { componentCacheKey } = require_component_keys();
|
|
573
663
|
var { BaseConnector } = require_base_connector();
|
|
574
664
|
var {
|
|
665
|
+
cleanAxiosErrors,
|
|
575
666
|
missingApiKeyError,
|
|
576
667
|
resolveApiKey,
|
|
577
668
|
throwIfAborted
|
|
@@ -627,6 +718,7 @@ var require_cohere_connector = __commonJS({
|
|
|
627
718
|
"Content-Type": "application/json"
|
|
628
719
|
}
|
|
629
720
|
});
|
|
721
|
+
cleanAxiosErrors(this.client, "Cohere");
|
|
630
722
|
}
|
|
631
723
|
/**
|
|
632
724
|
* @throws {Error} code MISSING_API_KEY when no key is configured
|
|
@@ -764,6 +856,7 @@ var require_ollama_connector = __commonJS({
|
|
|
764
856
|
var loadAxios = () => require("axios");
|
|
765
857
|
var { BaseConnector } = require_base_connector();
|
|
766
858
|
var {
|
|
859
|
+
cleanAxiosErrors,
|
|
767
860
|
raceAbort,
|
|
768
861
|
signalOptions,
|
|
769
862
|
textChunks,
|
|
@@ -822,6 +915,7 @@ var require_ollama_connector = __commonJS({
|
|
|
822
915
|
baseURL: this.config.baseURL,
|
|
823
916
|
timeout: this.config.timeout
|
|
824
917
|
});
|
|
918
|
+
cleanAxiosErrors(this.client, "Ollama");
|
|
825
919
|
}
|
|
826
920
|
/**
|
|
827
921
|
* Connect to the Ollama server by verifying it is reachable.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devilsdev/rag-connectors",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "Embedders, LLMs and vector stores for @devilsdev/rag-core: OpenAI, Anthropic, Cohere, Ollama, the AI SDK, Qdrant and pgvector.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rag",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@devilsdev/rag-core": "3.
|
|
46
|
+
"@devilsdev/rag-core": "3.5.0",
|
|
47
47
|
"axios": "^1.21.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|