@jaypie/llm 1.2.10 → 1.2.11

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.
@@ -2673,7 +2673,7 @@ class OpenRouterAdapter extends BaseProviderAdapter {
2673
2673
  //
2674
2674
  // API Execution
2675
2675
  //
2676
- async executeRequest(client, request) {
2676
+ async executeRequest(client, request, signal) {
2677
2677
  const openRouter = client;
2678
2678
  const openRouterRequest = request;
2679
2679
  const response = await openRouter.chat.send({
@@ -2682,10 +2682,10 @@ class OpenRouterAdapter extends BaseProviderAdapter {
2682
2682
  tools: openRouterRequest.tools,
2683
2683
  toolChoice: openRouterRequest.tool_choice,
2684
2684
  user: openRouterRequest.user,
2685
- });
2685
+ }, signal ? { signal } : undefined);
2686
2686
  return response;
2687
2687
  }
2688
- async *executeStreamRequest(client, request) {
2688
+ async *executeStreamRequest(client, request, signal) {
2689
2689
  const openRouter = client;
2690
2690
  const openRouterRequest = request;
2691
2691
  // Use chat.send with stream: true for streaming responses
@@ -2696,7 +2696,7 @@ class OpenRouterAdapter extends BaseProviderAdapter {
2696
2696
  toolChoice: openRouterRequest.tool_choice,
2697
2697
  user: openRouterRequest.user,
2698
2698
  stream: true,
2699
- });
2699
+ }, signal ? { signal } : undefined);
2700
2700
  // Track current tool call being built
2701
2701
  let currentToolCall = null;
2702
2702
  // Track usage for final chunk
@@ -3907,9 +3907,12 @@ class RetryExecutor {
3907
3907
  this.errorClassifier = config.errorClassifier;
3908
3908
  }
3909
3909
  /**
3910
- * Execute an operation with retry logic
3910
+ * Execute an operation with retry logic.
3911
+ * Each attempt receives an AbortSignal. On failure, the signal is aborted
3912
+ * before sleeping — this kills lingering socket callbacks from the previous
3913
+ * request and prevents stale async errors from escaping the retry loop.
3911
3914
  *
3912
- * @param operation - The async operation to execute
3915
+ * @param operation - The async operation to execute (receives AbortSignal)
3913
3916
  * @param options - Execution options including context and hooks
3914
3917
  * @returns The result of the operation
3915
3918
  * @throws BadGatewayError if all retries are exhausted or error is not retryable
@@ -3917,14 +3920,17 @@ class RetryExecutor {
3917
3920
  async execute(operation, options) {
3918
3921
  let attempt = 0;
3919
3922
  while (true) {
3923
+ const controller = new AbortController();
3920
3924
  try {
3921
- const result = await operation();
3925
+ const result = await operation(controller.signal);
3922
3926
  if (attempt > 0) {
3923
3927
  log$1.debug(`API call succeeded after ${attempt} retries`);
3924
3928
  }
3925
3929
  return result;
3926
3930
  }
3927
3931
  catch (error) {
3932
+ // Abort the previous request to kill lingering socket callbacks
3933
+ controller.abort("retry");
3928
3934
  // Check if we've exhausted retries
3929
3935
  if (!this.policy.shouldRetry(attempt)) {
3930
3936
  log$1.error(`API call failed after ${this.policy.maxRetries} retries`);
@@ -4149,7 +4155,7 @@ class OperateLoop {
4149
4155
  providerRequest,
4150
4156
  });
4151
4157
  // Execute with retry (RetryExecutor handles error hooks and throws appropriate errors)
4152
- const response = await retryExecutor.execute(() => this.adapter.executeRequest(this.client, providerRequest), {
4158
+ const response = await retryExecutor.execute((signal) => this.adapter.executeRequest(this.client, providerRequest, signal), {
4153
4159
  context: {
4154
4160
  input: state.currentInput,
4155
4161
  options,
@@ -4542,9 +4548,10 @@ class StreamLoop {
4542
4548
  let attempt = 0;
4543
4549
  let chunksYielded = false;
4544
4550
  while (true) {
4551
+ const controller = new AbortController();
4545
4552
  try {
4546
4553
  // Execute streaming request
4547
- const streamGenerator = this.adapter.executeStreamRequest(this.client, providerRequest);
4554
+ const streamGenerator = this.adapter.executeStreamRequest(this.client, providerRequest, controller.signal);
4548
4555
  for await (const chunk of streamGenerator) {
4549
4556
  // Pass through text chunks
4550
4557
  if (chunk.type === exports.LlmStreamChunkType.Text) {
@@ -4579,6 +4586,8 @@ class StreamLoop {
4579
4586
  break;
4580
4587
  }
4581
4588
  catch (error) {
4589
+ // Abort the previous request to kill lingering socket callbacks
4590
+ controller.abort("retry");
4582
4591
  // If chunks were already yielded, we can't transparently retry
4583
4592
  if (chunksYielded) {
4584
4593
  const errorMessage = error instanceof Error ? error.message : String(error);