@imenam/unified-llm-client 2.1.2 → 2.3.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/LICENSE +21 -21
- package/README.md +383 -359
- package/dist/adapters/openrouter/OpenRouterLogAdapter.d.ts +11 -0
- package/dist/adapters/openrouter/OpenRouterLogAdapter.d.ts.map +1 -0
- package/dist/adapters/openrouter/OpenRouterLogAdapter.js +51 -0
- package/dist/adapters/openrouter/OpenRouterOutputAdapter.d.ts +6 -0
- package/dist/adapters/openrouter/OpenRouterOutputAdapter.d.ts.map +1 -0
- package/dist/adapters/openrouter/OpenRouterOutputAdapter.js +9 -0
- package/dist/adapters/openrouter/OpenRouterPromptAdapter.d.ts +15 -0
- package/dist/adapters/openrouter/OpenRouterPromptAdapter.d.ts.map +1 -0
- package/dist/adapters/openrouter/OpenRouterPromptAdapter.js +374 -0
- package/dist/adapters/openrouter/OpenRouterToolAdapter.d.ts +6 -0
- package/dist/adapters/openrouter/OpenRouterToolAdapter.d.ts.map +1 -0
- package/dist/adapters/openrouter/OpenRouterToolAdapter.js +16 -0
- package/dist/adapters/qwen/QwenLogAdapter.d.ts +5 -0
- package/dist/adapters/qwen/QwenLogAdapter.d.ts.map +1 -1
- package/dist/adapters/qwen/QwenLogAdapter.js +18 -9
- package/dist/adapters/qwen/QwenPromptAdapter.d.ts.map +1 -1
- package/dist/adapters/qwen/QwenPromptAdapter.js +136 -79
- package/dist/common/types.d.ts +10 -1
- package/dist/common/types.d.ts.map +1 -1
- package/dist/core/LLMAdapter.d.ts.map +1 -1
- package/dist/core/LLMAdapter.js +16 -0
- package/dist/core/Models.d.ts +7 -0
- package/dist/core/Models.d.ts.map +1 -1
- package/dist/core/Models.js +21 -0
- package/dist/core/UnifiedLLMClient.d.ts +2 -2
- package/dist/core/UnifiedLLMClient.d.ts.map +1 -1
- package/dist/core/UnifiedLLMClient.js +1 -1
- package/dist/examples/audio-example.js +1 -1
- package/dist/examples/example.js +16 -16
- package/dist/examples/qwen-omni-audio-example.d.ts +2 -0
- package/dist/examples/qwen-omni-audio-example.d.ts.map +1 -0
- package/dist/examples/qwen-omni-audio-example.js +324 -0
- package/dist/examples/qwen-vl-example.js +7 -7
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/package.json +71 -70
|
@@ -49,6 +49,75 @@ exports.QwenPromptAdapter = void 0;
|
|
|
49
49
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
50
50
|
const fs = __importStar(require("fs"));
|
|
51
51
|
const path = __importStar(require("path"));
|
|
52
|
+
const IMAGE_MIME_TYPES = {
|
|
53
|
+
".jpg": "image/jpeg",
|
|
54
|
+
".jpeg": "image/jpeg",
|
|
55
|
+
".png": "image/png",
|
|
56
|
+
".gif": "image/gif",
|
|
57
|
+
".webp": "image/webp",
|
|
58
|
+
".pdf": "application/pdf",
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Extensions audio acceptées par les modèles Qwen-Omni, associées à la valeur
|
|
62
|
+
* attendue dans `input_audio.format`.
|
|
63
|
+
*/
|
|
64
|
+
const AUDIO_FORMATS = {
|
|
65
|
+
".mp3": "mp3",
|
|
66
|
+
".wav": "wav",
|
|
67
|
+
".aac": "aac",
|
|
68
|
+
".amr": "amr",
|
|
69
|
+
".3gp": "3gp",
|
|
70
|
+
".3gpp": "3gpp",
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Extensions audio refusées par Qwen : un fichier de ce type lève une erreur
|
|
74
|
+
* au lieu d'être envoyé comme une image.
|
|
75
|
+
*/
|
|
76
|
+
const UNSUPPORTED_AUDIO_EXTENSIONS = [".m4a", ".ogg", ".oga", ".opus", ".flac", ".wma", ".webm"];
|
|
77
|
+
/** Taille maximale d'un audio envoyé en base64, mesurée après encodage. */
|
|
78
|
+
const MAX_INLINE_AUDIO_BYTES = 10 * 1024 * 1024;
|
|
79
|
+
function base64Length(byteLength) {
|
|
80
|
+
return Math.ceil(byteLength / 3) * 4;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Regroupe par `index` les fragments de tool calls reçus en streaming : le
|
|
84
|
+
* premier fragment porte l'identifiant et le nom, les suivants complètent
|
|
85
|
+
* `arguments`.
|
|
86
|
+
*/
|
|
87
|
+
function accumulateToolCalls(deltaToolCalls, parts) {
|
|
88
|
+
deltaToolCalls.forEach((toolCall, position) => {
|
|
89
|
+
var _a, _b, _c;
|
|
90
|
+
const index = typeof toolCall.index === "number" ? toolCall.index : position;
|
|
91
|
+
const current = (_a = parts.get(index)) !== null && _a !== void 0 ? _a : { name: "", arguments: "" };
|
|
92
|
+
if (toolCall.id)
|
|
93
|
+
current.id = toolCall.id;
|
|
94
|
+
if ((_b = toolCall.function) === null || _b === void 0 ? void 0 : _b.name)
|
|
95
|
+
current.name = toolCall.function.name;
|
|
96
|
+
if (typeof ((_c = toolCall.function) === null || _c === void 0 ? void 0 : _c.arguments) === "string") {
|
|
97
|
+
current.arguments += toolCall.function.arguments;
|
|
98
|
+
}
|
|
99
|
+
parts.set(index, current);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function finalizeToolCalls(parts) {
|
|
103
|
+
return [...parts.entries()]
|
|
104
|
+
.sort(([a], [b]) => a - b)
|
|
105
|
+
.map(([, part]) => {
|
|
106
|
+
let parsed = {};
|
|
107
|
+
try {
|
|
108
|
+
parsed = JSON.parse(part.arguments || "{}");
|
|
109
|
+
}
|
|
110
|
+
catch (_a) {
|
|
111
|
+
// Arguments non parsables : le texte brut est renvoyé sous `_raw`.
|
|
112
|
+
parsed = { _raw: part.arguments };
|
|
113
|
+
}
|
|
114
|
+
return { id: part.id, name: part.name, arguments: parsed };
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/** Indique si le modèle est un modèle Omni, qui requiert le paramètre `modalities`. */
|
|
118
|
+
function isOmniModel(model) {
|
|
119
|
+
return !!model && /omni/i.test(model);
|
|
120
|
+
}
|
|
52
121
|
class QwenPromptAdapter {
|
|
53
122
|
constructor(opts) {
|
|
54
123
|
var _a, _b;
|
|
@@ -59,7 +128,7 @@ class QwenPromptAdapter {
|
|
|
59
128
|
this.endpoint += "/chat/completions";
|
|
60
129
|
}
|
|
61
130
|
formatMessage(message) {
|
|
62
|
-
var _a;
|
|
131
|
+
var _a, _b;
|
|
63
132
|
// Assistant message with tool calls → OpenAI-compatible format
|
|
64
133
|
if (message.role === "assistant" && message.tool_calls && message.tool_calls.length > 0) {
|
|
65
134
|
return {
|
|
@@ -78,55 +147,57 @@ class QwenPromptAdapter {
|
|
|
78
147
|
}),
|
|
79
148
|
};
|
|
80
149
|
}
|
|
81
|
-
// Si le message contient des attachedFile, les convertir au format Qwen VL
|
|
150
|
+
// Si le message contient des attachedFile, les convertir au format Qwen VL / Omni
|
|
82
151
|
if (message.attachedFile) {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
content.push({
|
|
87
|
-
type: "text",
|
|
88
|
-
text: message.content
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
// Ajouter les fichiers attachés
|
|
152
|
+
const textPart = message.content && typeof message.content === 'string'
|
|
153
|
+
? { type: "text", text: message.content }
|
|
154
|
+
: null;
|
|
92
155
|
const files = Array.isArray(message.attachedFile) ? message.attachedFile : [message.attachedFile];
|
|
156
|
+
const fileParts = [];
|
|
93
157
|
for (const file of files) {
|
|
94
|
-
if (typeof file
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
mimeType = 'image/png';
|
|
108
|
-
}
|
|
109
|
-
else if (ext === '.gif') {
|
|
110
|
-
mimeType = 'image/gif';
|
|
111
|
-
}
|
|
112
|
-
else if (ext === '.webp') {
|
|
113
|
-
mimeType = 'image/webp';
|
|
114
|
-
}
|
|
115
|
-
else if (ext === '.pdf') {
|
|
116
|
-
mimeType = 'application/pdf';
|
|
117
|
-
}
|
|
118
|
-
content.push({
|
|
119
|
-
type: "image_url",
|
|
120
|
-
image_url: {
|
|
121
|
-
url: `data:${mimeType};base64,${base64Data}`
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
console.warn(`Failed to read attached file ${file}:`, error);
|
|
158
|
+
if (typeof file !== 'string')
|
|
159
|
+
continue;
|
|
160
|
+
const filePath = path.resolve(file);
|
|
161
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
162
|
+
const audioFormat = AUDIO_FORMATS[ext];
|
|
163
|
+
// Les erreurs de lecture et de taille d'un audio sont propagées.
|
|
164
|
+
if (UNSUPPORTED_AUDIO_EXTENSIONS.includes(ext)) {
|
|
165
|
+
throw new Error(`Audio format ${ext} is not supported by Qwen. Transcode ${file} to one of: ${Object.keys(AUDIO_FORMATS).join(", ")}.`);
|
|
166
|
+
}
|
|
167
|
+
if (audioFormat) {
|
|
168
|
+
const encodedSize = base64Length(fs.statSync(filePath).size);
|
|
169
|
+
if (encodedSize > MAX_INLINE_AUDIO_BYTES) {
|
|
170
|
+
throw new Error(`Audio file ${file} is ${(encodedSize / 1024 / 1024).toFixed(1)} MB once Base64-encoded, above the ${MAX_INLINE_AUDIO_BYTES / 1024 / 1024} MB limit of the Qwen API. Split it or lower the bitrate.`);
|
|
127
171
|
}
|
|
172
|
+
fileParts.push({
|
|
173
|
+
type: "input_audio",
|
|
174
|
+
input_audio: {
|
|
175
|
+
// DashScope attend le préfixe `data:;base64,`.
|
|
176
|
+
data: `data:;base64,${fs.readFileSync(filePath).toString('base64')}`,
|
|
177
|
+
format: audioFormat,
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const base64Data = fs.readFileSync(filePath).toString('base64');
|
|
184
|
+
const mimeType = (_b = IMAGE_MIME_TYPES[ext]) !== null && _b !== void 0 ? _b : 'application/octet-stream';
|
|
185
|
+
fileParts.push({
|
|
186
|
+
type: "image_url",
|
|
187
|
+
image_url: {
|
|
188
|
+
url: `data:${mimeType};base64,${base64Data}`
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
console.warn(`Failed to read attached file ${file}:`, error);
|
|
128
194
|
}
|
|
129
195
|
}
|
|
196
|
+
// L'audio précède le texte ; les images le suivent.
|
|
197
|
+
const hasAudio = fileParts.some(part => part.type === "input_audio");
|
|
198
|
+
const content = hasAudio
|
|
199
|
+
? [...fileParts, ...(textPart ? [textPart] : [])]
|
|
200
|
+
: [...(textPart ? [textPart] : []), ...fileParts];
|
|
130
201
|
return {
|
|
131
202
|
role: message.role,
|
|
132
203
|
content: content
|
|
@@ -138,11 +209,8 @@ class QwenPromptAdapter {
|
|
|
138
209
|
sendToProvider(messages_1) {
|
|
139
210
|
return __awaiter(this, arguments, void 0, function* (messages, tools = [], toolChoice = "auto", attachedFile, model, config) {
|
|
140
211
|
var _a;
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
messages,
|
|
144
|
-
stream: false,
|
|
145
|
-
};
|
|
212
|
+
const resolvedModel = model || this.opts.model;
|
|
213
|
+
const body = Object.assign({ model: resolvedModel, messages, stream: false }, (isOmniModel(resolvedModel) ? { modalities: ["text"] } : {}));
|
|
146
214
|
if (tools.length) {
|
|
147
215
|
body.tools = tools.map((fn) => ({ type: "function", function: fn }));
|
|
148
216
|
body.tool_choice =
|
|
@@ -171,11 +239,10 @@ class QwenPromptAdapter {
|
|
|
171
239
|
}
|
|
172
240
|
streamFromProvider(_a) {
|
|
173
241
|
return __awaiter(this, arguments, void 0, function* ({ messages, tools, toolChoice, model, onChunk, onFinalResponse, config, }) {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
};
|
|
242
|
+
const resolvedModel = model || this.opts.model;
|
|
243
|
+
const body = Object.assign({ model: resolvedModel, messages, stream: true,
|
|
244
|
+
// Demande le décompte des tokens dans le dernier chunk du stream.
|
|
245
|
+
stream_options: { include_usage: true } }, (isOmniModel(resolvedModel) ? { modalities: ["text"] } : {}));
|
|
179
246
|
if (tools === null || tools === void 0 ? void 0 : tools.length) {
|
|
180
247
|
body.tools = tools.map((fn) => ({ type: "function", function: fn }));
|
|
181
248
|
body.tool_choice =
|
|
@@ -231,10 +298,14 @@ class QwenPromptAdapter {
|
|
|
231
298
|
signal.addEventListener("abort", abortHandler, { once: true });
|
|
232
299
|
}
|
|
233
300
|
let aggregatedContent = "";
|
|
234
|
-
const
|
|
301
|
+
const toolCallParts = new Map();
|
|
235
302
|
let buffer = "";
|
|
303
|
+
// Usage, motif d'arrêt et dernier chunk, restitués dans la réponse finale.
|
|
304
|
+
let streamUsage = null;
|
|
305
|
+
let finishReason = null;
|
|
306
|
+
let lastChunk = null;
|
|
236
307
|
response.body.on('data', (chunk) => {
|
|
237
|
-
var _a, _b;
|
|
308
|
+
var _a, _b, _c, _d;
|
|
238
309
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
239
310
|
return;
|
|
240
311
|
// Convertir le buffer en string
|
|
@@ -251,20 +322,17 @@ class QwenPromptAdapter {
|
|
|
251
322
|
try {
|
|
252
323
|
const parsed = JSON.parse(data);
|
|
253
324
|
const delta = (_b = (_a = parsed.choices) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.delta;
|
|
325
|
+
lastChunk = parsed;
|
|
326
|
+
if (parsed.usage)
|
|
327
|
+
streamUsage = parsed.usage;
|
|
328
|
+
if ((_d = (_c = parsed.choices) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.finish_reason)
|
|
329
|
+
finishReason = parsed.choices[0].finish_reason;
|
|
254
330
|
if (delta === null || delta === void 0 ? void 0 : delta.content) {
|
|
255
331
|
aggregatedContent += delta.content;
|
|
256
332
|
onChunk === null || onChunk === void 0 ? void 0 : onChunk({ contentChunk: delta.content, rawChunk: parsed });
|
|
257
333
|
}
|
|
258
334
|
if (delta === null || delta === void 0 ? void 0 : delta.tool_calls) {
|
|
259
|
-
|
|
260
|
-
if (toolCall.function) {
|
|
261
|
-
aggregatedToolCalls.push({
|
|
262
|
-
id: toolCall.id,
|
|
263
|
-
name: toolCall.function.name,
|
|
264
|
-
arguments: JSON.parse(toolCall.function.arguments || "{}"),
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
}
|
|
335
|
+
accumulateToolCalls(delta.tool_calls, toolCallParts);
|
|
268
336
|
}
|
|
269
337
|
}
|
|
270
338
|
catch (e) {
|
|
@@ -293,15 +361,7 @@ class QwenPromptAdapter {
|
|
|
293
361
|
onChunk === null || onChunk === void 0 ? void 0 : onChunk({ contentChunk: delta.content, rawChunk: parsed });
|
|
294
362
|
}
|
|
295
363
|
if (delta === null || delta === void 0 ? void 0 : delta.tool_calls) {
|
|
296
|
-
|
|
297
|
-
if (toolCall.function) {
|
|
298
|
-
aggregatedToolCalls.push({
|
|
299
|
-
id: toolCall.id,
|
|
300
|
-
name: toolCall.function.name,
|
|
301
|
-
arguments: JSON.parse(toolCall.function.arguments || "{}"),
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
}
|
|
364
|
+
accumulateToolCalls(delta.tool_calls, toolCallParts);
|
|
305
365
|
}
|
|
306
366
|
}
|
|
307
367
|
catch (e) {
|
|
@@ -311,11 +371,8 @@ class QwenPromptAdapter {
|
|
|
311
371
|
}
|
|
312
372
|
}
|
|
313
373
|
}
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
toolCalls: aggregatedToolCalls.length > 0 ? aggregatedToolCalls : undefined,
|
|
317
|
-
raw: null,
|
|
318
|
-
};
|
|
374
|
+
const aggregatedToolCalls = finalizeToolCalls(toolCallParts);
|
|
375
|
+
const finalResponse = Object.assign({ content: aggregatedContent, toolCalls: aggregatedToolCalls.length > 0 ? aggregatedToolCalls : undefined, raw: lastChunk ? Object.assign(Object.assign({}, lastChunk), { usage: streamUsage }) : null }, (finishReason ? { finishReason } : {}));
|
|
319
376
|
onFinalResponse === null || onFinalResponse === void 0 ? void 0 : onFinalResponse(finalResponse);
|
|
320
377
|
finish(() => resolve(finalResponse));
|
|
321
378
|
});
|
package/dist/common/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type Provider = "openai" | "gemini" | "qwen" | "anthropic";
|
|
1
|
+
export type Provider = "openai" | "gemini" | "qwen" | "anthropic" | "openrouter";
|
|
2
2
|
/**
|
|
3
3
|
* Resolves the API key for an LLM call.
|
|
4
4
|
*
|
|
@@ -25,6 +25,9 @@ export interface ChatMessage {
|
|
|
25
25
|
/** Tool calls declared by the assistant (for multi-turn conversations).
|
|
26
26
|
* For Gemini tool results (role: "tool"), set tool_call_id to the function name. */
|
|
27
27
|
tool_calls?: ToolCall[];
|
|
28
|
+
/** OpenRouter : blocs de raisonnement renvoyés avec un appel d'outil. Ils doivent
|
|
29
|
+
* revenir tels quels sur le message assistant du tour suivant (Gemini 3, Claude…). */
|
|
30
|
+
reasoningDetails?: unknown[];
|
|
28
31
|
}
|
|
29
32
|
export interface ToolDefinition {
|
|
30
33
|
name: string;
|
|
@@ -49,8 +52,12 @@ export interface ChatResponse {
|
|
|
49
52
|
totalTokens: number;
|
|
50
53
|
promptTokensDetails: any;
|
|
51
54
|
thoughtsToken: number;
|
|
55
|
+
/** Coût réel de l'appel en USD, quand le provider le fournit (OpenRouter). */
|
|
56
|
+
cost?: number;
|
|
52
57
|
};
|
|
53
58
|
finishReason?: string;
|
|
59
|
+
/** OpenRouter : blocs de raisonnement à recopier dans `ChatMessage.reasoningDetails`. */
|
|
60
|
+
reasoningDetails?: unknown[];
|
|
54
61
|
requestId?: string;
|
|
55
62
|
llmLogId?: number;
|
|
56
63
|
error?: string;
|
|
@@ -84,6 +91,8 @@ export interface UnifiedUsage {
|
|
|
84
91
|
audioTokens?: number;
|
|
85
92
|
thinkingTokens?: number;
|
|
86
93
|
};
|
|
94
|
+
/** Coût réel de l'appel en USD, quand le provider le fournit (OpenRouter). */
|
|
95
|
+
cost?: number;
|
|
87
96
|
}
|
|
88
97
|
export interface UnifiedLog {
|
|
89
98
|
requestId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC;AAEjF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC7E,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEnF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEpF,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC;yFACqF;IACrF,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;IACxB;2FACuF;IACvF,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,mBAAmB,EAAE,GAAG,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,8EAA8E;QAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,iBAAiB,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;CAC3C;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAA;AAID,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IAEpB,aAAa,CAAC,EAAE;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IAEF,iBAAiB,CAAC,EAAE;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IAEF,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAID,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,GAAG,CAAC;CACV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LLMAdapter.d.ts","sourceRoot":"","sources":["../../src/core/LLMAdapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LLMAdapter.d.ts","sourceRoot":"","sources":["../../src/core/LLMAdapter.ts"],"names":[],"mappings":"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"}
|
package/dist/core/LLMAdapter.js
CHANGED
|
@@ -21,6 +21,10 @@ const AnthropicPromptAdapter_1 = require("../adapters/anthropic/AnthropicPromptA
|
|
|
21
21
|
const AnthropicOutputAdapter_1 = require("../adapters/anthropic/AnthropicOutputAdapter");
|
|
22
22
|
const AnthropicToolAdapter_1 = require("../adapters/anthropic/AnthropicToolAdapter");
|
|
23
23
|
const AnthropicLogAdapter_1 = require("../adapters/anthropic/AnthropicLogAdapter");
|
|
24
|
+
const OpenRouterPromptAdapter_1 = require("../adapters/openrouter/OpenRouterPromptAdapter");
|
|
25
|
+
const OpenRouterOutputAdapter_1 = require("../adapters/openrouter/OpenRouterOutputAdapter");
|
|
26
|
+
const OpenRouterToolAdapter_1 = require("../adapters/openrouter/OpenRouterToolAdapter");
|
|
27
|
+
const OpenRouterLogAdapter_1 = require("../adapters/openrouter/OpenRouterLogAdapter");
|
|
24
28
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
25
29
|
dotenv_1.default.config();
|
|
26
30
|
exports.PROVIDERS_CONFIG = {
|
|
@@ -67,4 +71,16 @@ exports.PROVIDERS_CONFIG = {
|
|
|
67
71
|
toolAdapter: new AnthropicToolAdapter_1.AnthropicToolAdapter(),
|
|
68
72
|
logAdapter: new AnthropicLogAdapter_1.AnthropicLogAdapter(),
|
|
69
73
|
}),
|
|
74
|
+
openrouter: (apiKey) => {
|
|
75
|
+
var _a;
|
|
76
|
+
return ({
|
|
77
|
+
promptAdapter: new OpenRouterPromptAdapter_1.OpenRouterPromptAdapter({
|
|
78
|
+
apiKey: (_a = apiKey !== null && apiKey !== void 0 ? apiKey : process.env.OPEN_ROUTER_API_KEY) !== null && _a !== void 0 ? _a : process.env.OPENROUTER_API_KEY,
|
|
79
|
+
model: "google/gemini-2.5-flash",
|
|
80
|
+
}),
|
|
81
|
+
outputAdapter: new OpenRouterOutputAdapter_1.OpenRouterOutputAdapter(),
|
|
82
|
+
toolAdapter: new OpenRouterToolAdapter_1.OpenRouterToolAdapter(),
|
|
83
|
+
logAdapter: new OpenRouterLogAdapter_1.OpenRouterLogAdapter(),
|
|
84
|
+
});
|
|
85
|
+
},
|
|
70
86
|
};
|
package/dist/core/Models.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare const MODELS: {
|
|
|
7
7
|
QWEN_VL_3: Model;
|
|
8
8
|
QWEN_VL_FLASH: Model;
|
|
9
9
|
QWEN_VL_3_FLASH: Model;
|
|
10
|
+
QWEN_OMNI_FLASH: Model;
|
|
10
11
|
GEMINI_3_PRO: Model;
|
|
11
12
|
GEMINI_3_1_PRO: Model;
|
|
12
13
|
GEMINI_3_FLASH: Model;
|
|
@@ -14,4 +15,10 @@ export declare const MODELS: {
|
|
|
14
15
|
CLAUDE_SONNET_4_6: Model;
|
|
15
16
|
CLAUDE_OPUS_4_6: Model;
|
|
16
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Construit un modèle OpenRouter à partir de son identifiant (ex.
|
|
20
|
+
* `google/gemini-3-flash-preview`). Les coûts sont facultatifs : OpenRouter
|
|
21
|
+
* renvoie le coût réel de chaque appel dans `usage.cost`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function openRouterModel(modelName: string, costsPer1MTokens?: Model["costsPer1MTokens"]): Model;
|
|
17
24
|
//# sourceMappingURL=Models.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Models.d.ts","sourceRoot":"","sources":["../../src/core/Models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC,eAAO,MAAM,MAAM;sBAWZ,KAAK;oBAYL,KAAK;iBAYL,KAAK;WAWL,KAAK;eAWL,KAAK;mBAWL,KAAK;qBAWL,KAAK;kBAWL,KAAK;oBAWL,KAAK;oBAaL,KAAK;sBAWL,KAAK;uBAKL,KAAK;qBAKL,KAAK;CACX,CAAC"}
|
|
1
|
+
{"version":3,"file":"Models.d.ts","sourceRoot":"","sources":["../../src/core/Models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC,eAAO,MAAM,MAAM;sBAWZ,KAAK;oBAYL,KAAK;iBAYL,KAAK;WAWL,KAAK;eAWL,KAAK;mBAWL,KAAK;qBAWL,KAAK;qBAaL,KAAK;kBAWL,KAAK;oBAWL,KAAK;oBAaL,KAAK;sBAWL,KAAK;uBAKL,KAAK;qBAKL,KAAK;CACX,CAAC;AAGF;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,gBAAgB,GAAE,KAAK,CAAC,kBAAkB,CAA4B,GACrE,KAAK,CAEP"}
|
package/dist/core/Models.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MODELS = void 0;
|
|
4
|
+
exports.openRouterModel = openRouterModel;
|
|
4
5
|
exports.MODELS = {
|
|
5
6
|
GEMINI_FLASH_2_5: {
|
|
6
7
|
provider: "gemini",
|
|
@@ -75,6 +76,18 @@ exports.MODELS = {
|
|
|
75
76
|
},
|
|
76
77
|
currency: "USD",
|
|
77
78
|
},
|
|
79
|
+
// Omnimodal (audio/vidéo/image/texte), tarifs du déploiement international (Singapour).
|
|
80
|
+
QWEN_OMNI_FLASH: {
|
|
81
|
+
provider: "qwen",
|
|
82
|
+
modelName: "qwen3.8-omni-flash",
|
|
83
|
+
costsPer1MTokens: {
|
|
84
|
+
prompt: 0.15,
|
|
85
|
+
prompt_cache: 0.016,
|
|
86
|
+
prompt_audio: 0.15,
|
|
87
|
+
output: 0.47,
|
|
88
|
+
},
|
|
89
|
+
currency: "USD",
|
|
90
|
+
},
|
|
78
91
|
GEMINI_3_PRO: {
|
|
79
92
|
provider: "gemini",
|
|
80
93
|
modelName: "gemini-3-pro-preview",
|
|
@@ -126,3 +139,11 @@ exports.MODELS = {
|
|
|
126
139
|
modelName: "claude-opus-4-6",
|
|
127
140
|
},
|
|
128
141
|
};
|
|
142
|
+
/**
|
|
143
|
+
* Construit un modèle OpenRouter à partir de son identifiant (ex.
|
|
144
|
+
* `google/gemini-3-flash-preview`). Les coûts sont facultatifs : OpenRouter
|
|
145
|
+
* renvoie le coût réel de chaque appel dans `usage.cost`.
|
|
146
|
+
*/
|
|
147
|
+
function openRouterModel(modelName, costsPer1MTokens = { prompt: 0, output: 0 }) {
|
|
148
|
+
return { provider: "openrouter", modelName, costsPer1MTokens, currency: "USD" };
|
|
149
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ApiKeyResolver, ChatMessage, ChatResponse, ToolDefinition, AudioGenerationOptions, AudioGenerationResponse, UnifiedLog } from "../common/types";
|
|
2
2
|
import { PromptAdapterOptions, StreamedChatChunk, ChatOptionalConfig } from "./LLMAdapter";
|
|
3
|
-
import { Model } from "../common/types";
|
|
3
|
+
import { Model, Provider } from "../common/types";
|
|
4
4
|
export type UnifiedLLMClientOptions = {
|
|
5
|
-
provider:
|
|
5
|
+
provider: Provider;
|
|
6
6
|
adapterOptions?: PromptAdapterOptions;
|
|
7
7
|
logger?: (log: UnifiedLog) => any | Promise<any>;
|
|
8
8
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnifiedLLMClient.d.ts","sourceRoot":"","sources":["../../src/core/UnifiedLLMClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAY,cAAc,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnK,OAAO,EAAiB,oBAAoB,EAAqE,iBAAiB,EAAgB,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAG3L,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"UnifiedLLMClient.d.ts","sourceRoot":"","sources":["../../src/core/UnifiedLLMClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -45,7 +45,7 @@ class UnifiedLLMClient {
|
|
|
45
45
|
this.logger = (options === null || options === void 0 ? void 0 : options.logger) || global._unifiedLlmDefaultLogger;
|
|
46
46
|
}
|
|
47
47
|
checkNotImplementedFeatures(message) {
|
|
48
|
-
if (message.attachedFile &&
|
|
48
|
+
if (message.attachedFile && !LLMAdapter_1.PROVIDERS_CONFIG[this.model.provider]) {
|
|
49
49
|
throw new Error("Attached files are not supported for this provider");
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -81,7 +81,7 @@ function generateSimpleAudio(client) {
|
|
|
81
81
|
}
|
|
82
82
|
function generateMultiVoiceAudio(client) {
|
|
83
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
-
const podcastText = `Speaker 1: Bienvenue dans notre podcast technologique !
|
|
84
|
+
const podcastText = `Speaker 1: Bienvenue dans notre podcast technologique !
|
|
85
85
|
Speaker 2: Aujourd'hui, nous parlons d'intelligence artificielle et de génération de voix.`;
|
|
86
86
|
const multiOutputPath = path.join(AUDIO_OUTPUT_DIR, "podcast-example.wav");
|
|
87
87
|
const multiResponse = yield client.generateMultiVoiceAudio(podcastText, [
|
package/dist/examples/example.js
CHANGED
|
@@ -183,8 +183,8 @@ function basicAudioGeneration() {
|
|
|
183
183
|
console.log(voices.join(', '));
|
|
184
184
|
// Exemple 3: Génération multi-voix simple
|
|
185
185
|
console.log('\n🎙️ Génération multi-voix...');
|
|
186
|
-
const dialogText = `Speaker 1: Salut ! content ça va ?
|
|
187
|
-
Speaker 2: Très bien, merci ! Et toi ?
|
|
186
|
+
const dialogText = `Speaker 1: Salut ! content ça va ?
|
|
187
|
+
Speaker 2: Très bien, merci ! Et toi ?
|
|
188
188
|
Speaker 1: Ça va super bien, merci de demander !`;
|
|
189
189
|
const multiAudioResponse = yield client.generateMultiVoiceAudio(dialogText, [
|
|
190
190
|
{ speaker: "Speaker 1", voiceName: "Kore" },
|
|
@@ -326,20 +326,20 @@ function parseSubject() {
|
|
|
326
326
|
const res = yield client.chat({
|
|
327
327
|
message: {
|
|
328
328
|
role: "user",
|
|
329
|
-
content: `Voila le sujet du devoir. Peux-tu le parser en respectant la structure suivante ?
|
|
330
|
-
{
|
|
331
|
-
questions: [
|
|
332
|
-
{
|
|
333
|
-
number: "1",
|
|
334
|
-
content: "Question 1" or "Exercie N", etc...,
|
|
335
|
-
type: "Title" or "Question",
|
|
336
|
-
marking_scheme: "X" or "", // if type is "Question", X can be a float - 3.5, 4, etc...
|
|
337
|
-
sub_questions: [
|
|
338
|
-
...same structure
|
|
339
|
-
]
|
|
340
|
-
}
|
|
341
|
-
]
|
|
342
|
-
}
|
|
329
|
+
content: `Voila le sujet du devoir. Peux-tu le parser en respectant la structure suivante ?
|
|
330
|
+
{
|
|
331
|
+
questions: [
|
|
332
|
+
{
|
|
333
|
+
number: "1",
|
|
334
|
+
content: "Question 1" or "Exercie N", etc...,
|
|
335
|
+
type: "Title" or "Question",
|
|
336
|
+
marking_scheme: "X" or "", // if type is "Question", X can be a float - 3.5, 4, etc...
|
|
337
|
+
sub_questions: [
|
|
338
|
+
...same structure
|
|
339
|
+
]
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
}
|
|
343
343
|
`,
|
|
344
344
|
attachedFile: "./media/nested_subject.pdf"
|
|
345
345
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qwen-omni-audio-example.d.ts","sourceRoot":"","sources":["../../src/examples/qwen-omni-audio-example.ts"],"names":[],"mappings":""}
|