@imenam/unified-llm-client 1.2.0 → 1.4.1
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/adapters/anthropic/AnthropicPromptAdapter.d.ts +2 -2
- package/dist/adapters/anthropic/AnthropicPromptAdapter.d.ts.map +1 -1
- package/dist/adapters/anthropic/AnthropicPromptAdapter.js +4 -4
- package/dist/adapters/gemini/GeminiPromptAdapter.d.ts.map +1 -1
- package/dist/adapters/gemini/GeminiPromptAdapter.js +17 -21
- package/dist/adapters/openai/OpenAIPromptAdapter.d.ts +2 -2
- package/dist/adapters/openai/OpenAIPromptAdapter.d.ts.map +1 -1
- package/dist/adapters/openai/OpenAIPromptAdapter.js +5 -9
- package/dist/adapters/qwen/QwenPromptAdapter.d.ts +3 -3
- package/dist/adapters/qwen/QwenPromptAdapter.d.ts.map +1 -1
- package/dist/adapters/qwen/QwenPromptAdapter.js +47 -18
- package/dist/core/LLMAdapter.d.ts +2 -1
- package/dist/core/LLMAdapter.d.ts.map +1 -1
- package/dist/core/LLMAdapter.js +8 -8
- package/dist/core/UnifiedLLMClient.d.ts +3 -1
- package/dist/core/UnifiedLLMClient.d.ts.map +1 -1
- package/dist/core/UnifiedLLMClient.js +13 -8
- package/dist/examples/chat-abort-example.d.ts +11 -0
- package/dist/examples/chat-abort-example.d.ts.map +1 -0
- package/dist/examples/chat-abort-example.js +154 -0
- package/dist/examples/example.js +25 -20
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -6,7 +6,7 @@ export declare class AnthropicPromptAdapter implements PromptAdapter {
|
|
|
6
6
|
constructor(opts: PromptAdapterOptions);
|
|
7
7
|
formatMessage(message: ChatMessage): Promise<any>;
|
|
8
8
|
private buildRequestParams;
|
|
9
|
-
sendToProvider(messages: any[], tools?: ToolDefinition[], toolChoice?: "auto" | "none" | string, _attachedFile?: string | string[], model?: string,
|
|
10
|
-
streamFromProvider({ messages, tools, toolChoice, model, onChunk, onFinalResponse, }: ChatStreamOptions): Promise<ChatResponse>;
|
|
9
|
+
sendToProvider(messages: any[], tools?: ToolDefinition[], toolChoice?: "auto" | "none" | string, _attachedFile?: string | string[], model?: string, config?: ChatOptionalConfig): Promise<ChatResponse>;
|
|
10
|
+
streamFromProvider({ messages, tools, toolChoice, model, onChunk, onFinalResponse, config, }: ChatStreamOptions): Promise<ChatResponse>;
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=AnthropicPromptAdapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnthropicPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/anthropic/AnthropicPromptAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAY,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAqB,MAAM,uBAAuB,CAAC;AA4BtI,qBAAa,sBAAuB,YAAW,aAAa;IAC1D,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,IAAI,CAAuB;gBAEvB,IAAI,EAAE,oBAAoB;IAKhC,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAsEvD,OAAO,CAAC,kBAAkB;IAmCpB,cAAc,CAClB,QAAQ,EAAE,GAAG,EAAE,EACf,KAAK,GAAE,cAAc,EAAO,EAC5B,UAAU,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,EAC7C,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EACjC,KAAK,CAAC,EAAE,MAAM,EACd,
|
|
1
|
+
{"version":3,"file":"AnthropicPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/anthropic/AnthropicPromptAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAY,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAqB,MAAM,uBAAuB,CAAC;AA4BtI,qBAAa,sBAAuB,YAAW,aAAa;IAC1D,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,IAAI,CAAuB;gBAEvB,IAAI,EAAE,oBAAoB;IAKhC,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAsEvD,OAAO,CAAC,kBAAkB;IAmCpB,cAAc,CAClB,QAAQ,EAAE,GAAG,EAAE,EACf,KAAK,GAAE,cAAc,EAAO,EAC5B,UAAU,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,EAC7C,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EACjC,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IAmDlB,kBAAkB,CAAC,EACvB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,eAAe,EACf,MAAM,GACP,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;CAiE7C"}
|
|
@@ -167,10 +167,10 @@ class AnthropicPromptAdapter {
|
|
|
167
167
|
return { systemPrompt, nonSystemMessages, sdkTools, sdkToolChoice, model: model || this.opts.model };
|
|
168
168
|
}
|
|
169
169
|
sendToProvider(messages_1) {
|
|
170
|
-
return __awaiter(this, arguments, void 0, function* (messages, tools = [], toolChoice = "auto", _attachedFile, model,
|
|
170
|
+
return __awaiter(this, arguments, void 0, function* (messages, tools = [], toolChoice = "auto", _attachedFile, model, config) {
|
|
171
171
|
var _a, _b;
|
|
172
172
|
const { systemPrompt, nonSystemMessages, sdkTools, sdkToolChoice, model: resolvedModel } = this.buildRequestParams(messages, tools, toolChoice, model);
|
|
173
|
-
const response = yield this.client.messages.create(Object.assign(Object.assign(Object.assign({ model: resolvedModel, max_tokens: 8096, messages: nonSystemMessages }, (systemPrompt ? { system: systemPrompt } : {})), (sdkTools ? { tools: sdkTools } : {})), (sdkToolChoice ? { tool_choice: sdkToolChoice } : {})));
|
|
173
|
+
const response = yield this.client.messages.create(Object.assign(Object.assign(Object.assign({ model: resolvedModel, max_tokens: 8096, messages: nonSystemMessages }, (systemPrompt ? { system: systemPrompt } : {})), (sdkTools ? { tools: sdkTools } : {})), (sdkToolChoice ? { tool_choice: sdkToolChoice } : {})), (config === null || config === void 0 ? void 0 : config.signal) ? { signal: config.signal } : undefined);
|
|
174
174
|
let textContent = null;
|
|
175
175
|
const toolCalls = [];
|
|
176
176
|
for (const block of response.content) {
|
|
@@ -202,10 +202,10 @@ class AnthropicPromptAdapter {
|
|
|
202
202
|
});
|
|
203
203
|
}
|
|
204
204
|
streamFromProvider(_a) {
|
|
205
|
-
return __awaiter(this, arguments, void 0, function* ({ messages, tools, toolChoice, model, onChunk, onFinalResponse, }) {
|
|
205
|
+
return __awaiter(this, arguments, void 0, function* ({ messages, tools, toolChoice, model, onChunk, onFinalResponse, config, }) {
|
|
206
206
|
var _b, _c;
|
|
207
207
|
const { systemPrompt, nonSystemMessages, sdkTools, sdkToolChoice, model: resolvedModel } = this.buildRequestParams(messages, tools !== null && tools !== void 0 ? tools : [], toolChoice !== null && toolChoice !== void 0 ? toolChoice : "auto", model);
|
|
208
|
-
const stream = this.client.messages.stream(Object.assign(Object.assign(Object.assign({ model: resolvedModel, max_tokens: 8096, messages: nonSystemMessages }, (systemPrompt ? { system: systemPrompt } : {})), (sdkTools ? { tools: sdkTools } : {})), (sdkToolChoice ? { tool_choice: sdkToolChoice } : {})));
|
|
208
|
+
const stream = this.client.messages.stream(Object.assign(Object.assign(Object.assign({ model: resolvedModel, max_tokens: 8096, messages: nonSystemMessages }, (systemPrompt ? { system: systemPrompt } : {})), (sdkTools ? { tools: sdkTools } : {})), (sdkToolChoice ? { tool_choice: sdkToolChoice } : {})), (config === null || config === void 0 ? void 0 : config.signal) ? { signal: config.signal } : undefined);
|
|
209
209
|
const toolCalls = [];
|
|
210
210
|
stream.on("text", (text) => {
|
|
211
211
|
onChunk === null || onChunk === void 0 ? void 0 : onChunk({ contentChunk: text });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeminiPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/gemini/GeminiPromptAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,OAAO,EAUR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAY,cAAc,EAAE,MAAM,OAAO,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAA0C,MAAM,uBAAuB,CAAC;AAGrI,qBAAa,mBAAoB,YAAW,aAAa;IACvD,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,IAAI,CAAuB;gBACvB,IAAI,EAAE,oBAAoB;IAQzB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAmE5D,cAAc,CAClB,QAAQ,EAAE,GAAG,EACb,KAAK,GAAE,cAAc,EAAO,EAC5B,UAAU,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,EAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAChC,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"GeminiPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/gemini/GeminiPromptAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,OAAO,EAUR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAY,cAAc,EAAE,MAAM,OAAO,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAA0C,MAAM,uBAAuB,CAAC;AAGrI,qBAAa,mBAAoB,YAAW,aAAa;IACvD,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,IAAI,CAAuB;gBACvB,IAAI,EAAE,oBAAoB;IAQzB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAmE5D,cAAc,CAClB,QAAQ,EAAE,GAAG,EACb,KAAK,GAAE,cAAc,EAAO,EAC5B,UAAU,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,EAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAChC,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IA8DxB;;;;;;;;;;;;;OAaG;IACG,kBAAkB,CAAC,CAAC,EACxB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,eAAe,EACf,MAAM,GACP,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;CAuI7C"}
|
|
@@ -156,14 +156,9 @@ class GeminiPromptAdapter {
|
|
|
156
156
|
const result = yield this.genAI.models.generateContent({
|
|
157
157
|
model: model || this.opts.model,
|
|
158
158
|
contents,
|
|
159
|
-
config: {
|
|
160
|
-
thinkingConfig: {
|
|
159
|
+
config: Object.assign({ thinkingConfig: {
|
|
161
160
|
thinkingBudget: (_a = config === null || config === void 0 ? void 0 : config.thinkingBudget) !== null && _a !== void 0 ? _a : 128,
|
|
162
|
-
},
|
|
163
|
-
maxOutputTokens: 65535,
|
|
164
|
-
tools: sdkTools,
|
|
165
|
-
toolConfig,
|
|
166
|
-
},
|
|
161
|
+
}, maxOutputTokens: 65535, tools: sdkTools, toolConfig }, ((config === null || config === void 0 ? void 0 : config.signal) ? { abortSignal: config.signal } : {})),
|
|
167
162
|
});
|
|
168
163
|
const sdkResponse = result;
|
|
169
164
|
const responseCandidate = (_b = sdkResponse.candidates) === null || _b === void 0 ? void 0 : _b[0];
|
|
@@ -198,7 +193,7 @@ class GeminiPromptAdapter {
|
|
|
198
193
|
streamFromProvider(_a) {
|
|
199
194
|
return __awaiter(this, arguments, void 0, function* ({ messages, tools, toolChoice, model, onChunk, onFinalResponse, config, }) {
|
|
200
195
|
var _b, e_1, _c, _d;
|
|
201
|
-
var _e, _f, _g, _h, _j, _k;
|
|
196
|
+
var _e, _f, _g, _h, _j, _k, _l;
|
|
202
197
|
if (!this.genAI) {
|
|
203
198
|
throw new Error("Gemini API not configured");
|
|
204
199
|
}
|
|
@@ -244,28 +239,29 @@ class GeminiPromptAdapter {
|
|
|
244
239
|
const streamResult = yield this.genAI.models.generateContentStream({
|
|
245
240
|
model: model || this.opts.model,
|
|
246
241
|
contents: formattedContents,
|
|
247
|
-
config: {
|
|
248
|
-
tools: sdkTools,
|
|
249
|
-
toolConfig: toolConfigValue,
|
|
250
|
-
thinkingConfig: {
|
|
242
|
+
config: Object.assign({ tools: sdkTools, toolConfig: toolConfigValue, thinkingConfig: {
|
|
251
243
|
thinkingBudget: (config === null || config === void 0 ? void 0 : config.thinkingBudget) || 0,
|
|
252
|
-
}
|
|
253
|
-
},
|
|
244
|
+
} }, ((config === null || config === void 0 ? void 0 : config.signal) ? { abortSignal: config.signal } : {})),
|
|
254
245
|
});
|
|
255
246
|
let aggregatedContent = "";
|
|
256
247
|
const aggregatedToolCalls = [];
|
|
257
248
|
let lastChunk = null;
|
|
258
249
|
try {
|
|
259
|
-
for (var
|
|
250
|
+
for (var _m = true, streamResult_1 = __asyncValues(streamResult), streamResult_1_1; streamResult_1_1 = yield streamResult_1.next(), _b = streamResult_1_1.done, !_b; _m = true) {
|
|
260
251
|
_d = streamResult_1_1.value;
|
|
261
|
-
|
|
252
|
+
_m = false;
|
|
262
253
|
const chunk = _d;
|
|
254
|
+
if ((_e = config === null || config === void 0 ? void 0 : config.signal) === null || _e === void 0 ? void 0 : _e.aborted) {
|
|
255
|
+
const err = new Error("The operation was aborted");
|
|
256
|
+
err.name = "AbortError";
|
|
257
|
+
throw err;
|
|
258
|
+
}
|
|
263
259
|
lastChunk = chunk; // Keep track of the last chunk
|
|
264
|
-
const candidate = (
|
|
260
|
+
const candidate = (_f = chunk.candidates) === null || _f === void 0 ? void 0 : _f[0];
|
|
265
261
|
if (!candidate)
|
|
266
262
|
continue;
|
|
267
263
|
let contentChunkText = "";
|
|
268
|
-
if ((
|
|
264
|
+
if ((_g = candidate.content) === null || _g === void 0 ? void 0 : _g.parts) {
|
|
269
265
|
for (const part of candidate.content.parts) {
|
|
270
266
|
if (part.text) {
|
|
271
267
|
contentChunkText += part.text;
|
|
@@ -285,7 +281,7 @@ class GeminiPromptAdapter {
|
|
|
285
281
|
aggregatedContent += contentChunkText;
|
|
286
282
|
onChunk === null || onChunk === void 0 ? void 0 : onChunk({ contentChunk: contentChunkText, rawChunk: chunk });
|
|
287
283
|
}
|
|
288
|
-
if (((
|
|
284
|
+
if (((_j = (_h = candidate.content) === null || _h === void 0 ? void 0 : _h.parts) === null || _j === void 0 ? void 0 : _j.some((p) => p.functionCall)) && aggregatedToolCalls.length > 0) {
|
|
289
285
|
}
|
|
290
286
|
if (chunk.usageMetadata) {
|
|
291
287
|
finalResponseData.usage = {
|
|
@@ -304,14 +300,14 @@ class GeminiPromptAdapter {
|
|
|
304
300
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
305
301
|
finally {
|
|
306
302
|
try {
|
|
307
|
-
if (!
|
|
303
|
+
if (!_m && !_b && (_c = streamResult_1.return)) yield _c.call(streamResult_1);
|
|
308
304
|
}
|
|
309
305
|
finally { if (e_1) throw e_1.error; }
|
|
310
306
|
}
|
|
311
307
|
// If streamResult is the generator, there's no separate .response object.
|
|
312
308
|
// We derive final data from the stream's completion and the last chunk seen.
|
|
313
309
|
finalResponseData.raw = lastChunk; // The last chunk might contain some aggregated data or be the closest to a "final response"
|
|
314
|
-
if ((
|
|
310
|
+
if ((_l = (_k = lastChunk === null || lastChunk === void 0 ? void 0 : lastChunk.candidates) === null || _k === void 0 ? void 0 : _k[0]) === null || _l === void 0 ? void 0 : _l.finishReason) {
|
|
315
311
|
finalResponseData.finishReason = lastChunk.candidates[0].finishReason;
|
|
316
312
|
}
|
|
317
313
|
if (lastChunk === null || lastChunk === void 0 ? void 0 : lastChunk.usageMetadata) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PromptAdapterOptions, PromptAdapter } from "../../core/LLMAdapter";
|
|
1
|
+
import { PromptAdapterOptions, PromptAdapter, ChatOptionalConfig } from "../../core/LLMAdapter";
|
|
2
2
|
import { ChatMessage, ToolDefinition, ChatResponse } from "../../common/types";
|
|
3
3
|
export declare class OpenAIPromptAdapter implements PromptAdapter {
|
|
4
4
|
private readonly opts;
|
|
@@ -6,7 +6,7 @@ export declare class OpenAIPromptAdapter implements PromptAdapter {
|
|
|
6
6
|
private messages;
|
|
7
7
|
constructor(opts: PromptAdapterOptions);
|
|
8
8
|
formatMessage(message: ChatMessage): any;
|
|
9
|
-
sendToProvider(messages: any, tools?: ToolDefinition[], toolChoice?: "auto" | "none" | string, attachedFile?: string | string[], model?: string): Promise<ChatResponse>;
|
|
9
|
+
sendToProvider(messages: any, tools?: ToolDefinition[], toolChoice?: "auto" | "none" | string, attachedFile?: string | string[], model?: string, config?: ChatOptionalConfig): Promise<ChatResponse>;
|
|
10
10
|
private processFiles;
|
|
11
11
|
private request;
|
|
12
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenAIPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/openai/OpenAIPromptAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"OpenAIPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/openai/OpenAIPromptAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,EAAE,WAAW,EAAY,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKzF,qBAAa,mBAAoB,YAAW,aAAa;IAI3C,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAa;gBAEA,IAAI,EAAE,oBAAoB;IAMhD,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,GAAG;IA4CzC,cAAc,CAClB,QAAQ,EAAE,GAAG,EACb,KAAK,GAAE,cAAc,EAAO,EAC5B,UAAU,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,EAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAChC,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IAmDxB,OAAO,CAAC,YAAY;YAmCN,OAAO;CAgBtB"}
|
|
@@ -111,7 +111,7 @@ class OpenAIPromptAdapter {
|
|
|
111
111
|
return Object.assign(Object.assign({}, rest), { content: content.length > 0 ? content : message.content });
|
|
112
112
|
}
|
|
113
113
|
sendToProvider(messages_1) {
|
|
114
|
-
return __awaiter(this, arguments, void 0, function* (messages, tools = [], toolChoice = "auto", attachedFile, model) {
|
|
114
|
+
return __awaiter(this, arguments, void 0, function* (messages, tools = [], toolChoice = "auto", attachedFile, model, config) {
|
|
115
115
|
var _a;
|
|
116
116
|
// If attachedFile is provided separately, attach it to the last user message
|
|
117
117
|
if (attachedFile) {
|
|
@@ -143,7 +143,7 @@ class OpenAIPromptAdapter {
|
|
|
143
143
|
? "none"
|
|
144
144
|
: { type: "function", function: { name: toolChoice } };
|
|
145
145
|
}
|
|
146
|
-
const response = yield this.request(body);
|
|
146
|
+
const response = yield this.request(body, config);
|
|
147
147
|
const responseMessage = response.choices[0].message;
|
|
148
148
|
const calls = (responseMessage.tool_calls || []).map((c) => {
|
|
149
149
|
var _a;
|
|
@@ -195,16 +195,12 @@ class OpenAIPromptAdapter {
|
|
|
195
195
|
}
|
|
196
196
|
return parts;
|
|
197
197
|
}
|
|
198
|
-
request(body) {
|
|
198
|
+
request(body, config) {
|
|
199
199
|
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
-
const res = yield (0, node_fetch_1.default)(this.endpoint, {
|
|
201
|
-
method: "POST",
|
|
202
|
-
headers: {
|
|
200
|
+
const res = yield (0, node_fetch_1.default)(this.endpoint, Object.assign({ method: "POST", headers: {
|
|
203
201
|
"Content-Type": "application/json",
|
|
204
202
|
Authorization: `Bearer ${this.opts.apiKey}`,
|
|
205
|
-
},
|
|
206
|
-
body: JSON.stringify(body),
|
|
207
|
-
});
|
|
203
|
+
}, body: JSON.stringify(body) }, ((config === null || config === void 0 ? void 0 : config.signal) ? { signal: config.signal } : {})));
|
|
208
204
|
if (!res.ok) {
|
|
209
205
|
throw new Error(`OpenAI API ${res.status}: ${yield res.text()}`);
|
|
210
206
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PromptAdapterOptions, PromptAdapter, ChatStreamOptions } from "../../core/LLMAdapter";
|
|
1
|
+
import { PromptAdapterOptions, PromptAdapter, ChatStreamOptions, ChatOptionalConfig } from "../../core/LLMAdapter";
|
|
2
2
|
import { ChatMessage, ToolDefinition, ChatResponse } from "../../common/types";
|
|
3
3
|
export declare class QwenPromptAdapter implements PromptAdapter {
|
|
4
4
|
private readonly opts;
|
|
@@ -6,8 +6,8 @@ export declare class QwenPromptAdapter implements PromptAdapter {
|
|
|
6
6
|
private messages;
|
|
7
7
|
constructor(opts: PromptAdapterOptions);
|
|
8
8
|
formatMessage(message: ChatMessage): any;
|
|
9
|
-
sendToProvider(messages: any, tools?: ToolDefinition[], toolChoice?: "auto" | "none" | string, attachedFile?: string | string[], model?: string): Promise<ChatResponse>;
|
|
10
|
-
streamFromProvider?({ messages, tools, toolChoice, model, onChunk, onFinalResponse, }: ChatStreamOptions): Promise<ChatResponse>;
|
|
9
|
+
sendToProvider(messages: any, tools?: ToolDefinition[], toolChoice?: "auto" | "none" | string, attachedFile?: string | string[], model?: string, config?: ChatOptionalConfig): Promise<ChatResponse>;
|
|
10
|
+
streamFromProvider?({ messages, tools, toolChoice, model, onChunk, onFinalResponse, config, }: ChatStreamOptions): Promise<ChatResponse>;
|
|
11
11
|
private request;
|
|
12
12
|
}
|
|
13
13
|
//# sourceMappingURL=QwenPromptAdapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QwenPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/qwen/QwenPromptAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,iBAAiB,EAAqB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"QwenPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/qwen/QwenPromptAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAqB,MAAM,uBAAuB,CAAC;AACtI,OAAO,EAAE,WAAW,EAAY,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIzF,qBAAa,iBAAkB,YAAW,aAAa;IAIzC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAa;gBAEA,IAAI,EAAE,oBAAoB;IAMhD,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,GAAG;IA8EzC,cAAc,CAClB,QAAQ,EAAE,GAAG,EACb,KAAK,GAAE,cAAc,EAAO,EAC5B,UAAU,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,EAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAChC,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IAiClB,kBAAkB,CAAC,CAAC,EACxB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,eAAe,EACf,MAAM,GACP,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;YA6K9B,OAAO;CAgBtB"}
|
|
@@ -136,7 +136,7 @@ class QwenPromptAdapter {
|
|
|
136
136
|
return message;
|
|
137
137
|
}
|
|
138
138
|
sendToProvider(messages_1) {
|
|
139
|
-
return __awaiter(this, arguments, void 0, function* (messages, tools = [], toolChoice = "auto", attachedFile, model) {
|
|
139
|
+
return __awaiter(this, arguments, void 0, function* (messages, tools = [], toolChoice = "auto", attachedFile, model, config) {
|
|
140
140
|
var _a;
|
|
141
141
|
const body = {
|
|
142
142
|
model: model || this.opts.model,
|
|
@@ -152,7 +152,7 @@ class QwenPromptAdapter {
|
|
|
152
152
|
? "none"
|
|
153
153
|
: { type: "function", function: { name: toolChoice } };
|
|
154
154
|
}
|
|
155
|
-
const response = yield this.request(body);
|
|
155
|
+
const response = yield this.request(body, config);
|
|
156
156
|
const responseMessage = response.choices[0].message;
|
|
157
157
|
const calls = (responseMessage.tool_calls || []).map((c) => {
|
|
158
158
|
var _a;
|
|
@@ -170,7 +170,7 @@ class QwenPromptAdapter {
|
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
172
|
streamFromProvider(_a) {
|
|
173
|
-
return __awaiter(this, arguments, void 0, function* ({ messages, tools, toolChoice, model, onChunk, onFinalResponse, }) {
|
|
173
|
+
return __awaiter(this, arguments, void 0, function* ({ messages, tools, toolChoice, model, onChunk, onFinalResponse, config, }) {
|
|
174
174
|
const body = {
|
|
175
175
|
model: model || this.opts.model,
|
|
176
176
|
messages,
|
|
@@ -185,14 +185,11 @@ class QwenPromptAdapter {
|
|
|
185
185
|
? "none"
|
|
186
186
|
: { type: "function", function: { name: toolChoice } };
|
|
187
187
|
}
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
headers: {
|
|
188
|
+
const signal = config === null || config === void 0 ? void 0 : config.signal;
|
|
189
|
+
const response = yield (0, node_fetch_1.default)(this.endpoint, Object.assign({ method: "POST", headers: {
|
|
191
190
|
"Content-Type": "application/json",
|
|
192
191
|
Authorization: `Bearer ${this.opts.apiKey}`,
|
|
193
|
-
},
|
|
194
|
-
body: JSON.stringify(body),
|
|
195
|
-
});
|
|
192
|
+
}, body: JSON.stringify(body) }, (signal ? { signal } : {})));
|
|
196
193
|
if (!response.ok) {
|
|
197
194
|
throw new Error(`Qwen API ${response.status}: ${yield response.text()}`);
|
|
198
195
|
}
|
|
@@ -201,11 +198,45 @@ class QwenPromptAdapter {
|
|
|
201
198
|
throw new Error("Response body is not available for streaming");
|
|
202
199
|
}
|
|
203
200
|
return new Promise((resolve, reject) => {
|
|
201
|
+
let settled = false;
|
|
202
|
+
let abortHandler;
|
|
203
|
+
const finish = (fn) => {
|
|
204
|
+
if (settled)
|
|
205
|
+
return;
|
|
206
|
+
settled = true;
|
|
207
|
+
if (signal && abortHandler) {
|
|
208
|
+
signal.removeEventListener("abort", abortHandler);
|
|
209
|
+
}
|
|
210
|
+
fn();
|
|
211
|
+
};
|
|
212
|
+
if (signal) {
|
|
213
|
+
abortHandler = () => {
|
|
214
|
+
var _a, _b;
|
|
215
|
+
try {
|
|
216
|
+
const b = response.body;
|
|
217
|
+
(_a = b === null || b === void 0 ? void 0 : b.destroy) === null || _a === void 0 ? void 0 : _a.call(b);
|
|
218
|
+
void ((_b = b === null || b === void 0 ? void 0 : b.cancel) === null || _b === void 0 ? void 0 : _b.call(b));
|
|
219
|
+
}
|
|
220
|
+
catch (_c) {
|
|
221
|
+
/* ignore */
|
|
222
|
+
}
|
|
223
|
+
const err = new Error("The operation was aborted");
|
|
224
|
+
err.name = "AbortError";
|
|
225
|
+
finish(() => reject(err));
|
|
226
|
+
};
|
|
227
|
+
if (signal.aborted) {
|
|
228
|
+
abortHandler();
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
232
|
+
}
|
|
204
233
|
let aggregatedContent = "";
|
|
205
234
|
const aggregatedToolCalls = [];
|
|
206
235
|
let buffer = "";
|
|
207
236
|
response.body.on('data', (chunk) => {
|
|
208
237
|
var _a, _b;
|
|
238
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
239
|
+
return;
|
|
209
240
|
// Convertir le buffer en string
|
|
210
241
|
buffer += chunk.toString('utf8');
|
|
211
242
|
// Traiter les lignes complètes
|
|
@@ -245,6 +276,8 @@ class QwenPromptAdapter {
|
|
|
245
276
|
});
|
|
246
277
|
response.body.on('end', () => {
|
|
247
278
|
var _a, _b;
|
|
279
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
280
|
+
return;
|
|
248
281
|
// Traiter tout ce qui reste dans le buffer
|
|
249
282
|
if (buffer.trim()) {
|
|
250
283
|
const lines = buffer.split('\n');
|
|
@@ -284,25 +317,21 @@ class QwenPromptAdapter {
|
|
|
284
317
|
raw: null,
|
|
285
318
|
};
|
|
286
319
|
onFinalResponse === null || onFinalResponse === void 0 ? void 0 : onFinalResponse(finalResponse);
|
|
287
|
-
resolve(finalResponse);
|
|
320
|
+
finish(() => resolve(finalResponse));
|
|
288
321
|
});
|
|
289
322
|
response.body.on('error', (error) => {
|
|
290
|
-
reject(new Error(`Stream error: ${error.message}`));
|
|
323
|
+
finish(() => reject(new Error(`Stream error: ${error.message}`)));
|
|
291
324
|
});
|
|
292
325
|
});
|
|
293
326
|
});
|
|
294
327
|
}
|
|
295
328
|
//--------------------------------------------------
|
|
296
|
-
request(body) {
|
|
329
|
+
request(body, config) {
|
|
297
330
|
return __awaiter(this, void 0, void 0, function* () {
|
|
298
|
-
const res = yield (0, node_fetch_1.default)(this.endpoint, {
|
|
299
|
-
method: "POST",
|
|
300
|
-
headers: {
|
|
331
|
+
const res = yield (0, node_fetch_1.default)(this.endpoint, Object.assign({ method: "POST", headers: {
|
|
301
332
|
"Content-Type": "application/json",
|
|
302
333
|
Authorization: `Bearer ${this.opts.apiKey}`,
|
|
303
|
-
},
|
|
304
|
-
body: JSON.stringify(body),
|
|
305
|
-
});
|
|
334
|
+
}, body: JSON.stringify(body) }, ((config === null || config === void 0 ? void 0 : config.signal) ? { signal: config.signal } : {})));
|
|
306
335
|
if (!res.ok) {
|
|
307
336
|
throw new Error(`Qwen API ${res.status}: ${yield res.text()}`);
|
|
308
337
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChatMessage, ToolDefinition, ChatResponse, ToolCall, AudioGenerationOptions, AudioGenerationResponse, UnifiedLog, Provider } from "../common/types";
|
|
2
|
-
export declare const PROVIDERS_CONFIG: Record<Provider, ProviderOptions>;
|
|
2
|
+
export declare const PROVIDERS_CONFIG: Record<Provider, () => ProviderOptions>;
|
|
3
3
|
export type StreamedChatChunk = {
|
|
4
4
|
contentChunk?: string;
|
|
5
5
|
toolCallChunk?: ToolCall[];
|
|
@@ -27,6 +27,7 @@ export interface ChatStreamOptions {
|
|
|
27
27
|
export type ChatOptionalConfig = {
|
|
28
28
|
thinkingBudget?: number;
|
|
29
29
|
metadata?: Record<string, any>;
|
|
30
|
+
signal?: AbortSignal;
|
|
30
31
|
};
|
|
31
32
|
export interface LogData {
|
|
32
33
|
model: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LLMAdapter.d.ts","sourceRoot":"","sources":["../../src/core/LLMAdapter.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAM7J,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE,eAAe,
|
|
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
|
@@ -24,7 +24,7 @@ const AnthropicLogAdapter_1 = require("../adapters/anthropic/AnthropicLogAdapter
|
|
|
24
24
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
25
25
|
dotenv_1.default.config();
|
|
26
26
|
exports.PROVIDERS_CONFIG = {
|
|
27
|
-
gemini: {
|
|
27
|
+
gemini: () => ({
|
|
28
28
|
promptAdapter: new GeminiPromptAdapter_1.GeminiPromptAdapter({
|
|
29
29
|
apiKey: process.env.GOOGLE_API_KEY,
|
|
30
30
|
model: "gemini-2.5-flash",
|
|
@@ -36,8 +36,8 @@ exports.PROVIDERS_CONFIG = {
|
|
|
36
36
|
model: "gemini-2.5-pro-preview-tts",
|
|
37
37
|
}),
|
|
38
38
|
logAdapter: new GeminiLogAdapter_1.GeminiLogAdapter(),
|
|
39
|
-
},
|
|
40
|
-
openai: {
|
|
39
|
+
}),
|
|
40
|
+
openai: () => ({
|
|
41
41
|
promptAdapter: new OpenAIPromptAdapter_1.OpenAIPromptAdapter({
|
|
42
42
|
apiKey: process.env.OPENAI_API_KEY,
|
|
43
43
|
model: "gpt-4o-mini",
|
|
@@ -46,8 +46,8 @@ exports.PROVIDERS_CONFIG = {
|
|
|
46
46
|
outputAdapter: new OpenAIOutputAdapter_1.OpenAIOutputAdapter(),
|
|
47
47
|
logAdapter: new OpenAiLogAdapter_1.OpenAiLogAdapter(),
|
|
48
48
|
// Note: OpenAI n'a pas encore d'audioAdapter - peut être ajouté plus tard
|
|
49
|
-
},
|
|
50
|
-
qwen: {
|
|
49
|
+
}),
|
|
50
|
+
qwen: () => ({
|
|
51
51
|
promptAdapter: new QwenPromptAdapter_1.QwenPromptAdapter({
|
|
52
52
|
apiKey: process.env.ALIBABA_CLOUD_API_KEY,
|
|
53
53
|
model: "qwen3-vl-235b-a22b-instruct",
|
|
@@ -57,8 +57,8 @@ exports.PROVIDERS_CONFIG = {
|
|
|
57
57
|
outputAdapter: new QwenOutputAdapter_1.QwenOutputAdapter(),
|
|
58
58
|
logAdapter: new QwenLogAdapter_1.QwenLogAdapter(),
|
|
59
59
|
// Note: Qwen n'a pas d'audioAdapter pour le moment
|
|
60
|
-
},
|
|
61
|
-
anthropic: {
|
|
60
|
+
}),
|
|
61
|
+
anthropic: () => ({
|
|
62
62
|
promptAdapter: new AnthropicPromptAdapter_1.AnthropicPromptAdapter({
|
|
63
63
|
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
64
64
|
model: "claude-sonnet-4-5-20250929",
|
|
@@ -66,5 +66,5 @@ exports.PROVIDERS_CONFIG = {
|
|
|
66
66
|
outputAdapter: new AnthropicOutputAdapter_1.AnthropicOutputAdapter(),
|
|
67
67
|
toolAdapter: new AnthropicToolAdapter_1.AnthropicToolAdapter(),
|
|
68
68
|
logAdapter: new AnthropicLogAdapter_1.AnthropicLogAdapter(),
|
|
69
|
-
},
|
|
69
|
+
}),
|
|
70
70
|
};
|
|
@@ -15,12 +15,14 @@ export type ChatOptions = {
|
|
|
15
15
|
onLog?: (log: UnifiedLog) => void;
|
|
16
16
|
stream?: boolean;
|
|
17
17
|
config?: ChatOptionalConfig;
|
|
18
|
+
signal?: AbortSignal;
|
|
18
19
|
};
|
|
19
20
|
export declare class UnifiedLLMClient {
|
|
20
21
|
private promptAdapter;
|
|
21
22
|
private outputAdapter;
|
|
22
23
|
private toolAdapter;
|
|
23
24
|
private audioAdapter?;
|
|
25
|
+
private logAdapter?;
|
|
24
26
|
private rawMessages;
|
|
25
27
|
private model;
|
|
26
28
|
private logger?;
|
|
@@ -29,7 +31,7 @@ export declare class UnifiedLLMClient {
|
|
|
29
31
|
logger?: (log: UnifiedLog) => any | Promise<any>;
|
|
30
32
|
});
|
|
31
33
|
private checkNotImplementedFeatures;
|
|
32
|
-
chat({ message, tools, toolChoice, onChunk, onFinalResponse, onLog, stream, config }: ChatOptions): Promise<ChatResponse>;
|
|
34
|
+
chat({ message, tools, toolChoice, onChunk, onFinalResponse, onLog, stream, config, signal }: ChatOptions): Promise<ChatResponse>;
|
|
33
35
|
private handleLogging;
|
|
34
36
|
/**
|
|
35
37
|
* Vérifie si la génération d'audio est supportée pour le provider actuel
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnifiedLLMClient.d.ts","sourceRoot":"","sources":["../../src/core/UnifiedLLMClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAY,cAAc,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnJ,OAAO,EAAiB,oBAAoB,EAAqE,iBAAiB,EAAgB,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE3L,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACrD,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,EAAE,CAAC;IAC9C,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7C,eAAe,CAAC,EAAE,CAAC,aAAa,EAAE,YAAY,KAAK,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"UnifiedLLMClient.d.ts","sourceRoot":"","sources":["../../src/core/UnifiedLLMClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,10 +18,12 @@ class UnifiedLLMClient {
|
|
|
18
18
|
constructor(model, options) {
|
|
19
19
|
this.rawMessages = [];
|
|
20
20
|
this.model = model;
|
|
21
|
-
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
21
|
+
const config = LLMAdapter_1.PROVIDERS_CONFIG[model.provider]();
|
|
22
|
+
this.promptAdapter = config.promptAdapter;
|
|
23
|
+
this.outputAdapter = config.outputAdapter;
|
|
24
|
+
this.toolAdapter = config.toolAdapter;
|
|
25
|
+
this.audioAdapter = config.audioAdapter;
|
|
26
|
+
this.logAdapter = config.logAdapter;
|
|
25
27
|
this.logger = (options === null || options === void 0 ? void 0 : options.logger) || global._unifiedLlmDefaultLogger;
|
|
26
28
|
}
|
|
27
29
|
checkNotImplementedFeatures(message) {
|
|
@@ -30,7 +32,9 @@ class UnifiedLLMClient {
|
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
34
|
chat(_a) {
|
|
33
|
-
return __awaiter(this, arguments, void 0, function* ({ message, tools, toolChoice = "auto", onChunk, onFinalResponse, onLog, stream = false, config }) {
|
|
35
|
+
return __awaiter(this, arguments, void 0, function* ({ message, tools, toolChoice = "auto", onChunk, onFinalResponse, onLog, stream = false, config, signal }) {
|
|
36
|
+
const effectiveConfig = config !== undefined || signal !== undefined
|
|
37
|
+
? Object.assign(Object.assign({}, config), (signal !== undefined ? { signal } : {})) : undefined;
|
|
34
38
|
const startTime = Date.now();
|
|
35
39
|
const messageArray = Array.isArray(message)
|
|
36
40
|
? message
|
|
@@ -49,6 +53,7 @@ class UnifiedLLMClient {
|
|
|
49
53
|
tools,
|
|
50
54
|
toolChoice,
|
|
51
55
|
model: this.model.modelName,
|
|
56
|
+
config: effectiveConfig,
|
|
52
57
|
onChunk: (chunk) => {
|
|
53
58
|
aggregatedContent += chunk.contentChunk || "";
|
|
54
59
|
if (onChunk) {
|
|
@@ -65,17 +70,17 @@ class UnifiedLLMClient {
|
|
|
65
70
|
finalResponse.content = aggregatedContent;
|
|
66
71
|
}
|
|
67
72
|
else {
|
|
68
|
-
const providerResponse = yield this.promptAdapter.sendToProvider(messages, tools, toolChoice, undefined, this.model.modelName,
|
|
73
|
+
const providerResponse = yield this.promptAdapter.sendToProvider(messages, tools, toolChoice, undefined, this.model.modelName, effectiveConfig);
|
|
69
74
|
finalResponse = this.outputAdapter.parse(providerResponse);
|
|
70
75
|
}
|
|
71
76
|
const latencyMs = Date.now() - startTime;
|
|
72
|
-
yield this.handleLogging(messageArray, finalResponse, latencyMs,
|
|
77
|
+
yield this.handleLogging(messageArray, finalResponse, latencyMs, effectiveConfig === null || effectiveConfig === void 0 ? void 0 : effectiveConfig.metadata, onLog);
|
|
73
78
|
return finalResponse;
|
|
74
79
|
});
|
|
75
80
|
}
|
|
76
81
|
handleLogging(messages, response, latencyMs, metadata, onLog) {
|
|
77
82
|
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
-
const logAdapter =
|
|
83
|
+
const logAdapter = this.logAdapter;
|
|
79
84
|
if (logAdapter) {
|
|
80
85
|
try {
|
|
81
86
|
const unifiedLog = logAdapter.toUnifiedLog({
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test manuel de l’annulation `chat()` via `AbortSignal` (stream + non-stream).
|
|
3
|
+
*
|
|
4
|
+
* 1. Changez `PROVIDER` ci-dessous pour tester chaque fournisseur.
|
|
5
|
+
* 2. Streaming : seuls gemini, anthropic et qwen ont `streamFromProvider` dans ce package ;
|
|
6
|
+
* avec **openai**, le test streaming est ignoré (l’annulation non-stream reste testée).
|
|
7
|
+
* 3. Assurez-vous que la clé API correspondante est dans `.env` (voir README / LLMAdapter).
|
|
8
|
+
* 4. `npm run build` puis `npm run example:abort`
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=chat-abort-example.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-abort-example.d.ts","sourceRoot":"","sources":["../../src/examples/chat-abort-example.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Test manuel de l’annulation `chat()` via `AbortSignal` (stream + non-stream).
|
|
4
|
+
*
|
|
5
|
+
* 1. Changez `PROVIDER` ci-dessous pour tester chaque fournisseur.
|
|
6
|
+
* 2. Streaming : seuls gemini, anthropic et qwen ont `streamFromProvider` dans ce package ;
|
|
7
|
+
* avec **openai**, le test streaming est ignoré (l’annulation non-stream reste testée).
|
|
8
|
+
* 3. Assurez-vous que la clé API correspondante est dans `.env` (voir README / LLMAdapter).
|
|
9
|
+
* 4. `npm run build` puis `npm run example:abort`
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
const __1 = require("..");
|
|
22
|
+
// ─── Choisir le fournisseur à tester ───
|
|
23
|
+
const PROVIDER = "qwen";
|
|
24
|
+
const MODEL_BY_PROVIDER = {
|
|
25
|
+
gemini: __1.MODELS.GEMINI_FLASH_2_5,
|
|
26
|
+
openai: __1.MODELS.GPT_4O_MINI,
|
|
27
|
+
anthropic: __1.MODELS.CLAUDE_SONNET_4_6,
|
|
28
|
+
qwen: __1.MODELS.QWEN_VL_FLASH,
|
|
29
|
+
};
|
|
30
|
+
/** Aligné sur les adaptateurs : OpenAI n’expose pas encore `streamFromProvider`. */
|
|
31
|
+
const STREAMING_SUPPORTED = {
|
|
32
|
+
gemini: true,
|
|
33
|
+
openai: false,
|
|
34
|
+
anthropic: true,
|
|
35
|
+
qwen: true,
|
|
36
|
+
};
|
|
37
|
+
/** Délai avant `abort()` sur le test streaming (ms). Baisser si la réponse arrive trop vite. */
|
|
38
|
+
const ABORT_STREAM_AFTER_MS = 450;
|
|
39
|
+
/** Délai avant `abort()` sur le test non-stream (ms). Très court pour tenter d’annuler avant la fin. */
|
|
40
|
+
const ABORT_NON_STREAM_AFTER_MS = 5;
|
|
41
|
+
const LONG_STREAM_PROMPT = "Write a very long answer: at least 30 short paragraphs on the history of printing presses. " +
|
|
42
|
+
"Number each paragraph. Do not stop early.";
|
|
43
|
+
function isAbortLike(err) {
|
|
44
|
+
if (!(err instanceof Error)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (err.name === "AbortError") {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
if (typeof DOMException !== "undefined" && err instanceof DOMException && err.name === "AbortError") {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
// @anthropic-ai/sdk : `APIUserAbortError` garde souvent `name === "Error"` sur l’instance
|
|
54
|
+
const ctor = err.constructor.name;
|
|
55
|
+
if (ctor === "APIUserAbortError" || ctor === "APIAbortError") {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
if (err.name === "APIUserAbortError" || err.name === "APIAbortError") {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
function logUnexpected(provider, label, err) {
|
|
64
|
+
console.error(`[${provider}] ${label} — erreur inattendue:`, err);
|
|
65
|
+
if (err instanceof Error) {
|
|
66
|
+
console.error(` name: ${err.name}, message: ${err.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function testStreamingAbort() {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
if (!STREAMING_SUPPORTED[PROVIDER]) {
|
|
72
|
+
console.log(`[${PROVIDER}] (stream) ignoré — ce package n’implémente pas le streaming pour ce provider. ` +
|
|
73
|
+
`Testez gemini, anthropic ou qwen pour l’annulation en stream.`);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const model = MODEL_BY_PROVIDER[PROVIDER];
|
|
77
|
+
const client = new __1.UnifiedLLMClient(model);
|
|
78
|
+
const ac = new AbortController();
|
|
79
|
+
const timer = setTimeout(() => {
|
|
80
|
+
console.log(`\n[${PROVIDER}] (stream) abort() après ${ABORT_STREAM_AFTER_MS} ms\n`);
|
|
81
|
+
ac.abort();
|
|
82
|
+
}, ABORT_STREAM_AFTER_MS);
|
|
83
|
+
try {
|
|
84
|
+
let chunkCount = 0;
|
|
85
|
+
yield client.chat({
|
|
86
|
+
message: LONG_STREAM_PROMPT,
|
|
87
|
+
stream: true,
|
|
88
|
+
signal: ac.signal,
|
|
89
|
+
onChunk: (c) => {
|
|
90
|
+
if (c.contentChunk) {
|
|
91
|
+
chunkCount++;
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
clearTimeout(timer);
|
|
96
|
+
console.warn(`[${PROVIDER}] (stream) la requête s’est terminée sans annulation (chunks: ${chunkCount}). ` +
|
|
97
|
+
`Augmentez le délai ou utilisez un modèle plus lent.`);
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
clearTimeout(timer);
|
|
101
|
+
if (isAbortLike(err)) {
|
|
102
|
+
console.log(`[${PROVIDER}] (stream) OK — annulation reconnue (${err instanceof Error ? err.name : "?"}).`);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
logUnexpected(PROVIDER, "stream", err);
|
|
106
|
+
process.exitCode = 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function testNonStreamingAbort() {
|
|
112
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
const model = MODEL_BY_PROVIDER[PROVIDER];
|
|
114
|
+
const client = new __1.UnifiedLLMClient(model);
|
|
115
|
+
const ac = new AbortController();
|
|
116
|
+
const timer = setTimeout(() => {
|
|
117
|
+
ac.abort();
|
|
118
|
+
}, ABORT_NON_STREAM_AFTER_MS);
|
|
119
|
+
try {
|
|
120
|
+
yield client.chat({
|
|
121
|
+
message: LONG_STREAM_PROMPT,
|
|
122
|
+
stream: false,
|
|
123
|
+
signal: ac.signal,
|
|
124
|
+
});
|
|
125
|
+
clearTimeout(timer);
|
|
126
|
+
console.warn(`[${PROVIDER}] (non-stream) la réponse est revenue avant l’annulation — normal si le réseau / le modèle est très rapide.`);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
clearTimeout(timer);
|
|
130
|
+
if (isAbortLike(err)) {
|
|
131
|
+
console.log(`[${PROVIDER}] (non-stream) OK — annulation reconnue (${err instanceof Error ? err.name : "?"}).`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
logUnexpected(PROVIDER, "non-stream", err);
|
|
135
|
+
process.exitCode = 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function main() {
|
|
141
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
const model = MODEL_BY_PROVIDER[PROVIDER];
|
|
143
|
+
console.log("=== Test AbortSignal — UnifiedLLMClient.chat ===\n");
|
|
144
|
+
console.log(`Provider : ${PROVIDER}`);
|
|
145
|
+
console.log(`Modèle : ${model.modelName}\n`);
|
|
146
|
+
yield testStreamingAbort();
|
|
147
|
+
console.log();
|
|
148
|
+
yield testNonStreamingAbort();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
main().catch((e) => {
|
|
152
|
+
console.error(e);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
});
|
package/dist/examples/example.js
CHANGED
|
@@ -74,28 +74,29 @@ const tools = [
|
|
|
74
74
|
function basicUsage() {
|
|
75
75
|
return __awaiter(this, void 0, void 0, function* () {
|
|
76
76
|
const client = new __1.UnifiedLLMClient(__1.MODELS.GEMINI_FLASH_2_5);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
77
|
+
const tools = [
|
|
78
|
+
{
|
|
79
|
+
name: "get_weather",
|
|
80
|
+
description: "Retrieve weather for a given city",
|
|
81
|
+
parameters: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
city: { type: "string", description: "City name" },
|
|
85
|
+
},
|
|
86
|
+
required: ["city"],
|
|
87
|
+
},
|
|
88
|
+
executor: (_a) => __awaiter(this, [_a], void 0, function* ({ city }) {
|
|
89
|
+
// fetch weather data from API and then
|
|
90
|
+
return `Weather in ${city}... `; // Placeholder
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
];
|
|
94
94
|
const res = yield client.chat({
|
|
95
|
-
message: "
|
|
96
|
-
//
|
|
95
|
+
message: "Quelle est la météo à Paris ?",
|
|
96
|
+
// message: "Quel modèle es-tu ? 2.5-flash ou 2.5-pro ? Répond l'un ou l'autre, soit '2.5-flash' ou '2.5-pro', rien d'autre.",
|
|
97
|
+
tools
|
|
97
98
|
});
|
|
98
|
-
console.log("response", JSON.stringify(res.
|
|
99
|
+
console.log("response", JSON.stringify(res.toolCalls));
|
|
99
100
|
});
|
|
100
101
|
}
|
|
101
102
|
function basicUsageWithAudio() {
|
|
@@ -364,6 +365,10 @@ function multiFileSend() {
|
|
|
364
365
|
});
|
|
365
366
|
}
|
|
366
367
|
basicUsage();
|
|
368
|
+
// Annulation d'une requête chat (côté app consommatrice) :
|
|
369
|
+
// const ac = new AbortController();
|
|
370
|
+
// setTimeout(() => ac.abort(), 500);
|
|
371
|
+
// await client.chat({ message: "...", stream: true, signal: ac.signal });
|
|
367
372
|
// basicStreamUsage();
|
|
368
373
|
// basicUsageWithAudio();
|
|
369
374
|
// basicAudioGeneration();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ChatMessage, ToolDefinition, ToolCall, ChatResponse, AudioGenerationOptions, AudioGenerationResponse, VoiceConfig, SpeakerConfig } from "./common/types";
|
|
2
|
-
import { PromptAdapter, PromptAdapterOptions, OutputAdapter, AudioAdapter } from "./core/LLMAdapter";
|
|
3
|
-
import { UnifiedLLMClient } from "./core/UnifiedLLMClient";
|
|
2
|
+
import { PromptAdapter, PromptAdapterOptions, OutputAdapter, AudioAdapter, ChatOptionalConfig } from "./core/LLMAdapter";
|
|
3
|
+
import { UnifiedLLMClient, ChatOptions } from "./core/UnifiedLLMClient";
|
|
4
4
|
import { MODELS } from "./core/Models";
|
|
5
5
|
export { UnifiedLLMClient, MODELS };
|
|
6
|
-
export type { ChatMessage, ToolDefinition, ToolCall, ChatResponse, PromptAdapter, PromptAdapterOptions, OutputAdapter, AudioAdapter, AudioGenerationOptions, AudioGenerationResponse, VoiceConfig, SpeakerConfig };
|
|
6
|
+
export type { ChatMessage, ToolDefinition, ToolCall, ChatResponse, PromptAdapter, PromptAdapterOptions, OutputAdapter, AudioAdapter, AudioGenerationOptions, AudioGenerationResponse, VoiceConfig, SpeakerConfig, ChatOptionalConfig, ChatOptions, };
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAClK,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAClK,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzH,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAC;AACpC,YAAY,EACV,WAAW,EACX,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,sBAAsB,EACtB,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,WAAW,GACZ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imenam/unified-llm-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "A unified interface for multiple LLM providers (OpenAI, Gemini, Anthropic, Qwen) with tool-calling, streaming, and audio support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"example": "node dist/examples/example.js",
|
|
20
20
|
"example:audio": "node dist/examples/audio-example.js",
|
|
21
21
|
"example:qwen": "node dist/examples/qwen-vl-example.js",
|
|
22
|
-
"example:anthropic": "node dist/examples/anthropic-example.js"
|
|
22
|
+
"example:anthropic": "node dist/examples/anthropic-example.js",
|
|
23
|
+
"example:abort": "node dist/examples/chat-abort-example.js"
|
|
23
24
|
},
|
|
24
25
|
"keywords": [
|
|
25
26
|
"llm",
|