@imenam/unified-llm-client 1.2.0 → 1.4.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.
@@ -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, _config?: ChatOptionalConfig): 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
  }
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,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC;IAgDlB,kBAAkB,CAAC,EACvB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,eAAe,GAChB,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;CA8D7C"}
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, _config) {
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;IA6DxB;;;;;;;;;;;;;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;CAiI7C"}
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 _l = true, streamResult_1 = __asyncValues(streamResult), streamResult_1_1; streamResult_1_1 = yield streamResult_1.next(), _b = streamResult_1_1.done, !_b; _l = true) {
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
- _l = false;
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 = (_e = chunk.candidates) === null || _e === void 0 ? void 0 : _e[0];
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 ((_f = candidate.content) === null || _f === void 0 ? void 0 : _f.parts) {
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 (((_h = (_g = candidate.content) === null || _g === void 0 ? void 0 : _g.parts) === null || _h === void 0 ? void 0 : _h.some((p) => p.functionCall)) && aggregatedToolCalls.length > 0) {
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 (!_l && !_b && (_c = streamResult_1.return)) yield _c.call(streamResult_1);
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 ((_k = (_j = lastChunk === null || lastChunk === void 0 ? void 0 : lastChunk.candidates) === null || _j === void 0 ? void 0 : _j[0]) === null || _k === void 0 ? void 0 : _k.finishReason) {
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;AAC5E,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,GACb,OAAO,CAAC,YAAY,CAAC;IAmDxB,OAAO,CAAC,YAAY;YAmCN,OAAO;CAetB"}
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;AAClH,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,GACb,OAAO,CAAC,YAAY,CAAC;IAiClB,kBAAkB,CAAC,CAAC,EACxB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,eAAe,GAChB,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;YA0I9B,OAAO;CAetB"}
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 response = yield (0, node_fetch_1.default)(this.endpoint, {
189
- method: "POST",
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
  }
@@ -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":"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"}
1
+ {"version":3,"file":"LLMAdapter.d.ts","sourceRoot":"","sources":["../../src/core/LLMAdapter.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@ 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;
@@ -29,7 +30,7 @@ export declare class UnifiedLLMClient {
29
30
  logger?: (log: UnifiedLog) => any | Promise<any>;
30
31
  });
31
32
  private checkNotImplementedFeatures;
32
- chat({ message, tools, toolChoice, onChunk, onFinalResponse, onLog, stream, config }: ChatOptions): Promise<ChatResponse>;
33
+ chat({ message, tools, toolChoice, onChunk, onFinalResponse, onLog, stream, config, signal }: ChatOptions): Promise<ChatResponse>;
33
34
  private handleLogging;
34
35
  /**
35
36
  * 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":"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"}
1
+ {"version":3,"file":"UnifiedLLMClient.d.ts","sourceRoot":"","sources":["../../src/core/UnifiedLLMClient.ts"],"names":[],"mappings":"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"}
@@ -30,7 +30,9 @@ class UnifiedLLMClient {
30
30
  }
31
31
  }
32
32
  chat(_a) {
33
- return __awaiter(this, arguments, void 0, function* ({ message, tools, toolChoice = "auto", onChunk, onFinalResponse, onLog, stream = false, config }) {
33
+ return __awaiter(this, arguments, void 0, function* ({ message, tools, toolChoice = "auto", onChunk, onFinalResponse, onLog, stream = false, config, signal }) {
34
+ const effectiveConfig = config !== undefined || signal !== undefined
35
+ ? Object.assign(Object.assign({}, config), (signal !== undefined ? { signal } : {})) : undefined;
34
36
  const startTime = Date.now();
35
37
  const messageArray = Array.isArray(message)
36
38
  ? message
@@ -49,6 +51,7 @@ class UnifiedLLMClient {
49
51
  tools,
50
52
  toolChoice,
51
53
  model: this.model.modelName,
54
+ config: effectiveConfig,
52
55
  onChunk: (chunk) => {
53
56
  aggregatedContent += chunk.contentChunk || "";
54
57
  if (onChunk) {
@@ -65,11 +68,11 @@ class UnifiedLLMClient {
65
68
  finalResponse.content = aggregatedContent;
66
69
  }
67
70
  else {
68
- const providerResponse = yield this.promptAdapter.sendToProvider(messages, tools, toolChoice, undefined, this.model.modelName, config);
71
+ const providerResponse = yield this.promptAdapter.sendToProvider(messages, tools, toolChoice, undefined, this.model.modelName, effectiveConfig);
69
72
  finalResponse = this.outputAdapter.parse(providerResponse);
70
73
  }
71
74
  const latencyMs = Date.now() - startTime;
72
- yield this.handleLogging(messageArray, finalResponse, latencyMs, config === null || config === void 0 ? void 0 : config.metadata, onLog);
75
+ yield this.handleLogging(messageArray, finalResponse, latencyMs, effectiveConfig === null || effectiveConfig === void 0 ? void 0 : effectiveConfig.metadata, onLog);
73
76
  return finalResponse;
74
77
  });
75
78
  }
@@ -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
+ });
@@ -364,6 +364,10 @@ function multiFileSend() {
364
364
  });
365
365
  }
366
366
  basicUsage();
367
+ // Annulation d'une requête chat (côté app consommatrice) :
368
+ // const ac = new AbortController();
369
+ // setTimeout(() => ac.abort(), 500);
370
+ // await client.chat({ message: "...", stream: true, signal: ac.signal });
367
371
  // basicStreamUsage();
368
372
  // basicUsageWithAudio();
369
373
  // 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
@@ -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;AACrG,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,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,EACd,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.2.0",
3
+ "version": "1.4.0",
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",