@jaypie/llm 1.2.5 → 1.2.6
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/cjs/Llm.d.ts +15 -3
- package/dist/cjs/index.cjs +102 -21
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/types/LlmProvider.interface.d.ts +21 -0
- package/dist/esm/Llm.d.ts +15 -3
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +87 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/LlmProvider.interface.d.ts +21 -0
- package/package.json +1 -1
package/dist/cjs/Llm.d.ts
CHANGED
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
import { JsonObject } from "@jaypie/types";
|
|
2
2
|
import { LlmProviderName } from "./constants.js";
|
|
3
|
-
import { LlmHistory, LlmInputMessage, LlmMessageOptions, LlmOperateInput, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProvider } from "./types/LlmProvider.interface.js";
|
|
3
|
+
import { LlmFallbackConfig, LlmHistory, LlmInputMessage, LlmMessageOptions, LlmOperateInput, LlmOperateOptions, LlmOperateResponse, LlmOptions, LlmProvider } from "./types/LlmProvider.interface.js";
|
|
4
4
|
import { LlmStreamChunk } from "./types/LlmStreamChunk.interface.js";
|
|
5
5
|
declare class Llm implements LlmProvider {
|
|
6
|
-
private
|
|
6
|
+
private _fallbackConfig?;
|
|
7
7
|
private _llm;
|
|
8
8
|
private _options;
|
|
9
|
+
private _provider;
|
|
9
10
|
constructor(providerName?: LlmProviderName | string, options?: LlmOptions);
|
|
10
11
|
private createProvider;
|
|
11
12
|
send(message: string, options?: LlmMessageOptions): Promise<string | JsonObject>;
|
|
13
|
+
/**
|
|
14
|
+
* Resolves the fallback chain from instance config and per-call options.
|
|
15
|
+
* Per-call options take precedence over instance config.
|
|
16
|
+
* Returns empty array if fallback is disabled.
|
|
17
|
+
*/
|
|
18
|
+
private resolveFallbackChain;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a fallback Llm instance lazily when needed.
|
|
21
|
+
*/
|
|
22
|
+
private createFallbackInstance;
|
|
12
23
|
operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions): Promise<LlmOperateResponse>;
|
|
13
24
|
stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions): AsyncIterable<LlmStreamChunk>;
|
|
14
25
|
static send(message: string, options?: LlmMessageOptions & {
|
|
@@ -17,8 +28,9 @@ declare class Llm implements LlmProvider {
|
|
|
17
28
|
model?: string;
|
|
18
29
|
}): Promise<string | JsonObject>;
|
|
19
30
|
static operate(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions & {
|
|
20
|
-
llm?: LlmProviderName;
|
|
21
31
|
apiKey?: string;
|
|
32
|
+
fallback?: LlmFallbackConfig[] | false;
|
|
33
|
+
llm?: LlmProviderName;
|
|
22
34
|
model?: string;
|
|
23
35
|
}): Promise<LlmOperateResponse>;
|
|
24
36
|
static stream(input: string | LlmHistory | LlmInputMessage | LlmOperateInput, options?: LlmOperateOptions & {
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var errors = require('@jaypie/errors');
|
|
4
|
+
var log$2 = require('@jaypie/logger');
|
|
4
5
|
var v4 = require('zod/v4');
|
|
5
6
|
var kit = require('@jaypie/kit');
|
|
6
|
-
var logger = require('@jaypie/logger');
|
|
7
7
|
var RandomLib = require('random');
|
|
8
8
|
var openai = require('openai');
|
|
9
9
|
var zod = require('openai/helpers/zod');
|
|
@@ -481,7 +481,7 @@ function formatOperateInput(input, options) {
|
|
|
481
481
|
return [input];
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
-
const getLogger$4 = () =>
|
|
484
|
+
const getLogger$4 = () => log$2.log.lib({ lib: kit.JAYPIE.LIB.LLM });
|
|
485
485
|
const log$1 = getLogger$4();
|
|
486
486
|
|
|
487
487
|
// Turn policy constants
|
|
@@ -2368,16 +2368,16 @@ function convertContentToOpenRouter(content) {
|
|
|
2368
2368
|
}
|
|
2369
2369
|
// Image content - warn and discard
|
|
2370
2370
|
if (item.type === exports.LlmMessageType.InputImage) {
|
|
2371
|
-
|
|
2371
|
+
log$2.log.warn("OpenRouter does not support image uploads; image discarded");
|
|
2372
2372
|
continue;
|
|
2373
2373
|
}
|
|
2374
2374
|
// File/Document content - warn and discard
|
|
2375
2375
|
if (item.type === exports.LlmMessageType.InputFile) {
|
|
2376
|
-
|
|
2376
|
+
log$2.log.warn({ filename: item.filename }, "OpenRouter does not support file uploads; file discarded");
|
|
2377
2377
|
continue;
|
|
2378
2378
|
}
|
|
2379
2379
|
// Unknown type - warn and skip
|
|
2380
|
-
|
|
2380
|
+
log$2.log.warn({ item }, "Unknown content type for OpenRouter; discarded");
|
|
2381
2381
|
}
|
|
2382
2382
|
// If no text parts remain, return empty string to avoid empty array
|
|
2383
2383
|
if (parts.length === 0) {
|
|
@@ -2893,7 +2893,7 @@ class OpenRouterAdapter extends BaseProviderAdapter {
|
|
|
2893
2893
|
const openRouterAdapter = new OpenRouterAdapter();
|
|
2894
2894
|
|
|
2895
2895
|
const DEFAULT_TOOL_TYPE = "function";
|
|
2896
|
-
const log =
|
|
2896
|
+
const log = log$2.log.lib({ lib: kit.JAYPIE.LIB.LLM });
|
|
2897
2897
|
function logToolMessage(message, context) {
|
|
2898
2898
|
log.trace.var({ [context.name]: message });
|
|
2899
2899
|
}
|
|
@@ -4495,7 +4495,7 @@ async function loadSdk$2() {
|
|
|
4495
4495
|
}
|
|
4496
4496
|
}
|
|
4497
4497
|
// Logger
|
|
4498
|
-
const getLogger$3 = () =>
|
|
4498
|
+
const getLogger$3 = () => log$2.log.lib({ lib: kit.JAYPIE.LIB.LLM });
|
|
4499
4499
|
// Client initialization
|
|
4500
4500
|
async function initializeClient$3({ apiKey, } = {}) {
|
|
4501
4501
|
const logger = getLogger$3();
|
|
@@ -4534,7 +4534,7 @@ function prepareMessages$3(message, { data, placeholders } = {}) {
|
|
|
4534
4534
|
}
|
|
4535
4535
|
// Basic text completion
|
|
4536
4536
|
async function createTextCompletion$1(client, messages, model, systemMessage) {
|
|
4537
|
-
|
|
4537
|
+
log$2.log.trace("Using text output (unstructured)");
|
|
4538
4538
|
const params = {
|
|
4539
4539
|
model,
|
|
4540
4540
|
messages,
|
|
@@ -4543,17 +4543,17 @@ async function createTextCompletion$1(client, messages, model, systemMessage) {
|
|
|
4543
4543
|
// Add system instruction if provided
|
|
4544
4544
|
if (systemMessage) {
|
|
4545
4545
|
params.system = systemMessage;
|
|
4546
|
-
|
|
4546
|
+
log$2.log.trace(`System message: ${systemMessage.length} characters`);
|
|
4547
4547
|
}
|
|
4548
4548
|
const response = await client.messages.create(params);
|
|
4549
4549
|
const firstContent = response.content[0];
|
|
4550
4550
|
const text = firstContent && "text" in firstContent ? firstContent.text : "";
|
|
4551
|
-
|
|
4551
|
+
log$2.log.trace(`Assistant reply: ${text.length} characters`);
|
|
4552
4552
|
return text;
|
|
4553
4553
|
}
|
|
4554
4554
|
// Structured output completion
|
|
4555
4555
|
async function createStructuredCompletion$1(client, messages, model, responseSchema, systemMessage) {
|
|
4556
|
-
|
|
4556
|
+
log$2.log.trace("Using structured output");
|
|
4557
4557
|
// Get the JSON schema for the response
|
|
4558
4558
|
const schema = responseSchema instanceof v4.z.ZodType
|
|
4559
4559
|
? responseSchema
|
|
@@ -4586,7 +4586,7 @@ async function createStructuredCompletion$1(client, messages, model, responseSch
|
|
|
4586
4586
|
if (!schema.parse(result)) {
|
|
4587
4587
|
throw new Error(`JSON response from Anthropic does not match schema: ${responseText}`);
|
|
4588
4588
|
}
|
|
4589
|
-
|
|
4589
|
+
log$2.log.trace("Received structured response", { result });
|
|
4590
4590
|
return result;
|
|
4591
4591
|
}
|
|
4592
4592
|
catch {
|
|
@@ -4597,7 +4597,7 @@ async function createStructuredCompletion$1(client, messages, model, responseSch
|
|
|
4597
4597
|
throw new Error("Failed to parse structured response from Anthropic");
|
|
4598
4598
|
}
|
|
4599
4599
|
catch (error) {
|
|
4600
|
-
|
|
4600
|
+
log$2.log.error("Error creating structured completion", { error });
|
|
4601
4601
|
throw error;
|
|
4602
4602
|
}
|
|
4603
4603
|
}
|
|
@@ -4711,7 +4711,7 @@ async function loadSdk$1() {
|
|
|
4711
4711
|
}
|
|
4712
4712
|
}
|
|
4713
4713
|
// Logger
|
|
4714
|
-
const getLogger$2 = () =>
|
|
4714
|
+
const getLogger$2 = () => log$2.log.lib({ lib: kit.JAYPIE.LIB.LLM });
|
|
4715
4715
|
// Client initialization
|
|
4716
4716
|
async function initializeClient$2({ apiKey, } = {}) {
|
|
4717
4717
|
const logger = getLogger$2();
|
|
@@ -4851,7 +4851,7 @@ class GeminiProvider {
|
|
|
4851
4851
|
}
|
|
4852
4852
|
|
|
4853
4853
|
// Logger
|
|
4854
|
-
const getLogger$1 = () =>
|
|
4854
|
+
const getLogger$1 = () => log$2.log.lib({ lib: kit.JAYPIE.LIB.LLM });
|
|
4855
4855
|
// Client initialization
|
|
4856
4856
|
async function initializeClient$1({ apiKey, } = {}) {
|
|
4857
4857
|
const logger = getLogger$1();
|
|
@@ -5035,7 +5035,7 @@ async function loadSdk() {
|
|
|
5035
5035
|
}
|
|
5036
5036
|
}
|
|
5037
5037
|
// Logger
|
|
5038
|
-
const getLogger = () =>
|
|
5038
|
+
const getLogger = () => log$2.log.lib({ lib: kit.JAYPIE.LIB.LLM });
|
|
5039
5039
|
// Client initialization
|
|
5040
5040
|
async function initializeClient({ apiKey, } = {}) {
|
|
5041
5041
|
const logger = getLogger();
|
|
@@ -5185,7 +5185,7 @@ class OpenRouterProvider {
|
|
|
5185
5185
|
|
|
5186
5186
|
class Llm {
|
|
5187
5187
|
constructor(providerName = DEFAULT.PROVIDER.NAME, options = {}) {
|
|
5188
|
-
const { model } = options;
|
|
5188
|
+
const { fallback, model } = options;
|
|
5189
5189
|
let finalProvider = providerName;
|
|
5190
5190
|
let finalModel = model;
|
|
5191
5191
|
if (model) {
|
|
@@ -5214,6 +5214,7 @@ class Llm {
|
|
|
5214
5214
|
finalModel = undefined;
|
|
5215
5215
|
}
|
|
5216
5216
|
}
|
|
5217
|
+
this._fallbackConfig = fallback;
|
|
5217
5218
|
this._provider = finalProvider;
|
|
5218
5219
|
this._options = { ...options, model: finalModel };
|
|
5219
5220
|
this._llm = this.createProvider(finalProvider, this._options);
|
|
@@ -5242,11 +5243,81 @@ class Llm {
|
|
|
5242
5243
|
async send(message, options) {
|
|
5243
5244
|
return this._llm.send(message, options);
|
|
5244
5245
|
}
|
|
5246
|
+
/**
|
|
5247
|
+
* Resolves the fallback chain from instance config and per-call options.
|
|
5248
|
+
* Per-call options take precedence over instance config.
|
|
5249
|
+
* Returns empty array if fallback is disabled.
|
|
5250
|
+
*/
|
|
5251
|
+
resolveFallbackChain(options) {
|
|
5252
|
+
// Per-call `fallback: false` disables fallback entirely
|
|
5253
|
+
if (options.fallback === false) {
|
|
5254
|
+
return [];
|
|
5255
|
+
}
|
|
5256
|
+
// Per-call fallback array overrides instance config
|
|
5257
|
+
if (Array.isArray(options.fallback)) {
|
|
5258
|
+
return options.fallback;
|
|
5259
|
+
}
|
|
5260
|
+
// Use instance config if available
|
|
5261
|
+
return this._fallbackConfig || [];
|
|
5262
|
+
}
|
|
5263
|
+
/**
|
|
5264
|
+
* Creates a fallback Llm instance lazily when needed.
|
|
5265
|
+
*/
|
|
5266
|
+
createFallbackInstance(config) {
|
|
5267
|
+
return new Llm(config.provider, {
|
|
5268
|
+
apiKey: config.apiKey,
|
|
5269
|
+
model: config.model,
|
|
5270
|
+
});
|
|
5271
|
+
}
|
|
5245
5272
|
async operate(input, options = {}) {
|
|
5246
5273
|
if (!this._llm.operate) {
|
|
5247
5274
|
throw new errors.NotImplementedError(`Provider ${this._provider} does not support operate method`);
|
|
5248
5275
|
}
|
|
5249
|
-
|
|
5276
|
+
const fallbackChain = this.resolveFallbackChain(options);
|
|
5277
|
+
const optionsWithoutFallback = { ...options, fallback: false };
|
|
5278
|
+
let lastError;
|
|
5279
|
+
let attempts = 0;
|
|
5280
|
+
// Try primary provider first
|
|
5281
|
+
attempts++;
|
|
5282
|
+
try {
|
|
5283
|
+
const response = await this._llm.operate(input, optionsWithoutFallback);
|
|
5284
|
+
return {
|
|
5285
|
+
...response,
|
|
5286
|
+
fallbackAttempts: attempts,
|
|
5287
|
+
fallbackUsed: false,
|
|
5288
|
+
provider: response.provider || this._provider,
|
|
5289
|
+
};
|
|
5290
|
+
}
|
|
5291
|
+
catch (error) {
|
|
5292
|
+
lastError = error;
|
|
5293
|
+
log$2.warn(`Provider ${this._provider} failed`, {
|
|
5294
|
+
error: lastError.message,
|
|
5295
|
+
fallbacksRemaining: fallbackChain.length,
|
|
5296
|
+
});
|
|
5297
|
+
}
|
|
5298
|
+
// Try fallback providers
|
|
5299
|
+
for (const fallbackConfig of fallbackChain) {
|
|
5300
|
+
attempts++;
|
|
5301
|
+
try {
|
|
5302
|
+
const fallbackInstance = this.createFallbackInstance(fallbackConfig);
|
|
5303
|
+
const response = await fallbackInstance.operate(input, optionsWithoutFallback);
|
|
5304
|
+
return {
|
|
5305
|
+
...response,
|
|
5306
|
+
fallbackAttempts: attempts,
|
|
5307
|
+
fallbackUsed: true,
|
|
5308
|
+
provider: response.provider || fallbackConfig.provider,
|
|
5309
|
+
};
|
|
5310
|
+
}
|
|
5311
|
+
catch (error) {
|
|
5312
|
+
lastError = error;
|
|
5313
|
+
log$2.warn(`Fallback provider ${fallbackConfig.provider} failed`, {
|
|
5314
|
+
error: lastError.message,
|
|
5315
|
+
fallbacksRemaining: fallbackChain.length - attempts + 1,
|
|
5316
|
+
});
|
|
5317
|
+
}
|
|
5318
|
+
}
|
|
5319
|
+
// All providers failed, throw the last error
|
|
5320
|
+
throw lastError;
|
|
5250
5321
|
}
|
|
5251
5322
|
async *stream(input, options = {}) {
|
|
5252
5323
|
if (!this._llm.stream) {
|
|
@@ -5260,7 +5331,7 @@ class Llm {
|
|
|
5260
5331
|
return instance.send(message, messageOptions);
|
|
5261
5332
|
}
|
|
5262
5333
|
static async operate(input, options) {
|
|
5263
|
-
const {
|
|
5334
|
+
const { apiKey, fallback, llm, model, ...operateOptions } = options || {};
|
|
5264
5335
|
let finalLlm = llm;
|
|
5265
5336
|
let finalModel = model;
|
|
5266
5337
|
if (!llm && model) {
|
|
@@ -5277,8 +5348,18 @@ class Llm {
|
|
|
5277
5348
|
finalModel = undefined;
|
|
5278
5349
|
}
|
|
5279
5350
|
}
|
|
5280
|
-
|
|
5281
|
-
|
|
5351
|
+
// Resolve fallback for static method: pass to instance if array, pass to operate options if false
|
|
5352
|
+
const instanceFallback = Array.isArray(fallback) ? fallback : undefined;
|
|
5353
|
+
const operateFallback = fallback === false ? false : undefined;
|
|
5354
|
+
const instance = new Llm(finalLlm, {
|
|
5355
|
+
apiKey,
|
|
5356
|
+
fallback: instanceFallback,
|
|
5357
|
+
model: finalModel,
|
|
5358
|
+
});
|
|
5359
|
+
return instance.operate(input, {
|
|
5360
|
+
...operateOptions,
|
|
5361
|
+
...(operateFallback !== undefined && { fallback: operateFallback }),
|
|
5362
|
+
});
|
|
5282
5363
|
}
|
|
5283
5364
|
static stream(input, options) {
|
|
5284
5365
|
const { llm, apiKey, model, ...streamOptions } = options || {};
|