orquesta-cli 0.2.100 → 0.2.101

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.
@@ -44,7 +44,7 @@ export declare class LLMClient {
44
44
  private model;
45
45
  private modelName;
46
46
  private triedBatutaFallback;
47
- private currentAbortController;
47
+ private activeControllers;
48
48
  private isInterrupted;
49
49
  onStreamingContent: ((token: string) => void) | null;
50
50
  private static readonly DEFAULT_MAX_RETRIES;
@@ -123,7 +123,7 @@ export class LLMClient {
123
123
  model;
124
124
  modelName;
125
125
  triedBatutaFallback = false;
126
- currentAbortController = null;
126
+ activeControllers = new Set();
127
127
  isInterrupted = false;
128
128
  onStreamingContent = null;
129
129
  static DEFAULT_MAX_RETRIES = 3;
@@ -220,6 +220,7 @@ export class LLMClient {
220
220
  maxRetries
221
221
  });
222
222
  const url = '/chat/completions';
223
+ let controller = null;
223
224
  try {
224
225
  logger.flow('Starting message preprocessing');
225
226
  const modelId = options.model || this.model;
@@ -251,13 +252,14 @@ export class LLMClient {
251
252
  logger.llmRequest(processedMessages, modelId, options.tools);
252
253
  }
253
254
  logger.startTimer('llm-api-call');
254
- this.currentAbortController = new AbortController();
255
+ controller = new AbortController();
256
+ this.activeControllers.add(controller);
255
257
  let response;
256
258
  if (this.onStreamingContent) {
257
259
  const streamRequestBody = { ...requestBody, stream: true };
258
260
  const streamResp = await this.axiosInstance.post(url, streamRequestBody, {
259
261
  responseType: 'stream',
260
- signal: this.currentAbortController.signal,
262
+ signal: controller.signal,
261
263
  headers: buildPerRequestHeaders(),
262
264
  });
263
265
  captureBatutaHeaders(streamResp.headers);
@@ -325,7 +327,6 @@ export class LLMClient {
325
327
  catch { }
326
328
  }
327
329
  }
328
- this.currentAbortController = null;
329
330
  const toolCalls = Array.from(toolCallsMap.values())
330
331
  .filter(tc => tc.id && tc.function.name)
331
332
  .map(tc => ({ id: tc.id, type: 'function', function: { name: tc.function.name, arguments: tc.function.arguments } }));
@@ -350,10 +351,9 @@ export class LLMClient {
350
351
  }
351
352
  else {
352
353
  const httpResp = await this.axiosInstance.post(url, requestBody, {
353
- signal: this.currentAbortController.signal,
354
+ signal: controller.signal,
354
355
  headers: buildPerRequestHeaders(),
355
356
  });
356
- this.currentAbortController = null;
357
357
  response = { data: httpResp.data, status: httpResp.status, statusText: httpResp.statusText, headers: httpResp.headers };
358
358
  captureBatutaHeaders(response.headers);
359
359
  }
@@ -397,7 +397,6 @@ export class LLMClient {
397
397
  return response.data;
398
398
  }
399
399
  catch (error) {
400
- this.currentAbortController = null;
401
400
  if (axios.isCancel(error) || (error instanceof Error && error.name === 'CanceledError')) {
402
401
  logger.flow('API call canceled (user interrupt)');
403
402
  logger.exit('chatCompletion', { success: false, aborted: true });
@@ -444,14 +443,21 @@ export class LLMClient {
444
443
  body: options,
445
444
  });
446
445
  }
446
+ finally {
447
+ if (controller)
448
+ this.activeControllers.delete(controller);
449
+ }
447
450
  }
448
451
  abort() {
449
452
  logger.flow('LLM interrupt - Stopping all operations');
450
453
  this.isInterrupted = true;
451
- if (this.currentAbortController) {
452
- this.currentAbortController.abort();
453
- this.currentAbortController = null;
454
+ for (const controller of this.activeControllers) {
455
+ try {
456
+ controller.abort();
457
+ }
458
+ catch { }
454
459
  }
460
+ this.activeControllers.clear();
455
461
  }
456
462
  checkInterrupted() {
457
463
  return this.isInterrupted;
@@ -460,7 +466,7 @@ export class LLMClient {
460
466
  this.isInterrupted = false;
461
467
  }
462
468
  isRequestActive() {
463
- return this.currentAbortController !== null;
469
+ return this.activeControllers.size > 0;
464
470
  }
465
471
  isConnectionError(error) {
466
472
  if (!axios.isAxiosError(error))
@@ -521,6 +527,7 @@ export class LLMClient {
521
527
  }
522
528
  async *chatCompletionStream(options) {
523
529
  const url = '/chat/completions';
530
+ let controller = null;
524
531
  try {
525
532
  const modelId = options.model || this.model;
526
533
  const processedMessages = options.messages ?
@@ -543,10 +550,11 @@ export class LLMClient {
543
550
  max_tokens: requestBody.max_tokens,
544
551
  });
545
552
  logger.verbose('Full Streaming Request Body', requestBody);
546
- this.currentAbortController = new AbortController();
553
+ controller = new AbortController();
554
+ this.activeControllers.add(controller);
547
555
  const response = await this.axiosInstance.post(url, requestBody, {
548
556
  responseType: 'stream',
549
- signal: this.currentAbortController.signal,
557
+ signal: controller.signal,
550
558
  headers: buildPerRequestHeaders(),
551
559
  });
552
560
  captureBatutaHeaders(response.headers);
@@ -594,7 +602,8 @@ export class LLMClient {
594
602
  }
595
603
  }
596
604
  finally {
597
- this.currentAbortController = null;
605
+ if (controller)
606
+ this.activeControllers.delete(controller);
598
607
  }
599
608
  logger.debug('Streaming response completed', { chunkCount });
600
609
  }
@@ -605,6 +614,10 @@ export class LLMClient {
605
614
  body: options,
606
615
  });
607
616
  }
617
+ finally {
618
+ if (controller)
619
+ this.activeControllers.delete(controller);
620
+ }
608
621
  }
609
622
  async sendMessage(userMessage, systemPrompt) {
610
623
  logger.enter('sendMessage', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orquesta-cli",
3
- "version": "0.2.100",
3
+ "version": "0.2.101",
4
4
  "description": "Orquesta CLI - AI-powered coding assistant with team collaboration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",