@jaypie/llm 1.2.21 → 1.2.22

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.
@@ -557,7 +557,7 @@ const log$1 = getLogger$5();
557
557
 
558
558
  // Turn policy constants
559
559
  const MAX_TURNS_ABSOLUTE_LIMIT = 72;
560
- const MAX_TURNS_DEFAULT_LIMIT = 12;
560
+ const MAX_TURNS_DEFAULT_LIMIT = 24;
561
561
  /**
562
562
  * Determines the maximum number of turns based on the provided options
563
563
  *
@@ -4149,6 +4149,7 @@ class RetryExecutor {
4149
4149
  const ERROR$1 = {
4150
4150
  BAD_FUNCTION_CALL: "Bad Function Call",
4151
4151
  };
4152
+ const MAX_CONSECUTIVE_TOOL_ERRORS = 6;
4152
4153
  //
4153
4154
  //
4154
4155
  // Helpers
@@ -4271,6 +4272,7 @@ class OperateLoop {
4271
4272
  }
4272
4273
  }
4273
4274
  return {
4275
+ consecutiveToolErrors: 0,
4274
4276
  currentInput: processedInput.history,
4275
4277
  currentTurn: 0,
4276
4278
  formattedFormat,
@@ -4395,6 +4397,8 @@ class OperateLoop {
4395
4397
  output: JSON.stringify(result),
4396
4398
  success: true,
4397
4399
  };
4400
+ // Reset consecutive error counter on success
4401
+ state.consecutiveToolErrors = 0;
4398
4402
  // Update provider request with tool result
4399
4403
  currentProviderRequest = this.adapter.appendToolResult(currentProviderRequest, toolCall, formattedResult);
4400
4404
  // Sync state from updated request
@@ -4436,6 +4440,19 @@ class OperateLoop {
4436
4440
  state.responseBuilder.appendToHistory(toolResultFormatted);
4437
4441
  log$1.error(`Error executing function call ${toolCall.name}`);
4438
4442
  log$1.var({ error });
4443
+ // Track consecutive errors and stop if threshold reached
4444
+ state.consecutiveToolErrors++;
4445
+ if (state.consecutiveToolErrors >= MAX_CONSECUTIVE_TOOL_ERRORS) {
4446
+ const detail = `Stopped after ${MAX_CONSECUTIVE_TOOL_ERRORS} consecutive tool errors`;
4447
+ log$1.warn(detail);
4448
+ state.responseBuilder.setError({
4449
+ detail,
4450
+ status: 502,
4451
+ title: ERROR$1.BAD_FUNCTION_CALL,
4452
+ });
4453
+ state.responseBuilder.incomplete();
4454
+ return false; // Stop loop
4455
+ }
4439
4456
  }
4440
4457
  }
4441
4458
  // Check if we've reached max turns
@@ -4683,6 +4700,7 @@ class StreamLoop {
4683
4700
  ? this.adapter.formatTools(toolkit, formattedFormat)
4684
4701
  : undefined;
4685
4702
  return {
4703
+ consecutiveToolErrors: 0,
4686
4704
  currentInput: processedInput.history,
4687
4705
  currentTurn: 0,
4688
4706
  formattedFormat,
@@ -4876,6 +4894,8 @@ class StreamLoop {
4876
4894
  result,
4877
4895
  toolName: toolCall.name,
4878
4896
  });
4897
+ // Reset consecutive error counter on success
4898
+ state.consecutiveToolErrors = 0;
4879
4899
  // Yield tool result chunk
4880
4900
  yield {
4881
4901
  type: exports.LlmStreamChunkType.ToolResult,
@@ -4928,6 +4948,21 @@ class StreamLoop {
4928
4948
  });
4929
4949
  log$1.error(`Error executing function call ${toolCall.name}`);
4930
4950
  log$1.var({ error });
4951
+ // Track consecutive errors and stop if threshold reached
4952
+ state.consecutiveToolErrors++;
4953
+ if (state.consecutiveToolErrors >= MAX_CONSECUTIVE_TOOL_ERRORS) {
4954
+ const stopDetail = `Stopped after ${MAX_CONSECUTIVE_TOOL_ERRORS} consecutive tool errors`;
4955
+ log$1.warn(stopDetail);
4956
+ yield {
4957
+ type: exports.LlmStreamChunkType.Error,
4958
+ error: {
4959
+ detail: stopDetail,
4960
+ status: 502,
4961
+ title: ERROR.BAD_FUNCTION_CALL,
4962
+ },
4963
+ };
4964
+ return; // Stop processing tools
4965
+ }
4931
4966
  }
4932
4967
  }
4933
4968
  }