ai 6.0.0-beta.161 → 6.0.0-beta.163

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # ai
2
2
 
3
+ ## 6.0.0-beta.163
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [9549c9e]
8
+ - @ai-sdk/provider@3.0.0-beta.29
9
+ - @ai-sdk/gateway@2.0.0-beta.89
10
+ - @ai-sdk/provider-utils@4.0.0-beta.56
11
+
12
+ ## 6.0.0-beta.162
13
+
14
+ ### Patch Changes
15
+
16
+ - 50b70d6: feat(anthropic): add programmatic tool calling
17
+ - Updated dependencies [50b70d6]
18
+ - @ai-sdk/provider-utils@4.0.0-beta.55
19
+ - @ai-sdk/gateway@2.0.0-beta.88
20
+
3
21
  ## 6.0.0-beta.161
4
22
 
5
23
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { GatewayModelId } from '@ai-sdk/gateway';
2
2
  export { GatewayModelId, createGateway, gateway } from '@ai-sdk/gateway';
3
3
  import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
4
- import { Tool, InferToolInput, InferToolOutput, FlexibleSchema, InferSchema, AssistantModelMessage, ToolModelMessage, ReasoningPart, SystemModelMessage, ModelMessage, UserModelMessage, ProviderOptions, IdGenerator, ToolCall, MaybePromiseLike, TextPart, FilePart, Resolvable, FetchFunction, DataContent } from '@ai-sdk/provider-utils';
4
+ import { Tool, InferToolInput, InferToolOutput, FlexibleSchema, InferSchema, AssistantModelMessage, ToolModelMessage, ReasoningPart, SystemModelMessage, ModelMessage, ProviderOptions, UserModelMessage, IdGenerator, ToolCall, MaybePromiseLike, TextPart, FilePart, Resolvable, FetchFunction, DataContent } from '@ai-sdk/provider-utils';
5
5
  export { AssistantContent, AssistantModelMessage, DataContent, DownloadError, FilePart, FlexibleSchema, IdGenerator, ImagePart, InferSchema, InferToolInput, InferToolOutput, ModelMessage, Schema, SystemModelMessage, TextPart, Tool, ToolApprovalRequest, ToolApprovalResponse, ToolCallOptions, ToolCallPart, ToolContent, ToolExecuteFunction, ToolExecutionOptions, ToolModelMessage, ToolResultPart, UserContent, UserModelMessage, asSchema, createIdGenerator, dynamicTool, generateId, jsonSchema, parseJsonEventStream, tool, zodSchema } from '@ai-sdk/provider-utils';
6
6
  import * as _ai_sdk_provider from '@ai-sdk/provider';
7
7
  import { EmbeddingModelV3, EmbeddingModelV2, EmbeddingModelV3Embedding, EmbeddingModelV3Middleware, ImageModelV3, ImageModelV2, ImageModelV3ProviderMetadata, ImageModelV2ProviderMetadata, JSONValue as JSONValue$1, LanguageModelV3, LanguageModelV2, LanguageModelV3FinishReason, SharedV3Warning, LanguageModelV3Source, LanguageModelV3Middleware, RerankingModelV3, SharedV3ProviderMetadata, SpeechModelV3, SpeechModelV2, TranscriptionModelV3, TranscriptionModelV2, JSONObject, ImageModelV3Usage, LanguageModelV3CallOptions, AISDKError, LanguageModelV3ToolCall, JSONSchema7, JSONParseError, TypeValidationError, EmbeddingModelCallOptions, ProviderV3, ProviderV2, NoSuchModelError } from '@ai-sdk/provider';
@@ -1169,6 +1169,13 @@ type PrepareStepResult<TOOLS extends Record<string, Tool> = Record<string, Tool>
1169
1169
  * and all subsequent steps.
1170
1170
  */
1171
1171
  experimental_context?: unknown;
1172
+ /**
1173
+ * Additional provider-specific options for this step.
1174
+ *
1175
+ * Can be used to pass provider-specific configuration such as
1176
+ * container IDs for Anthropic's code execution.
1177
+ */
1178
+ providerOptions?: ProviderOptions;
1172
1179
  } | undefined;
1173
1180
 
1174
1181
  type StopCondition<TOOLS extends ToolSet> = (options: {
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { GatewayModelId } from '@ai-sdk/gateway';
2
2
  export { GatewayModelId, createGateway, gateway } from '@ai-sdk/gateway';
3
3
  import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
4
- import { Tool, InferToolInput, InferToolOutput, FlexibleSchema, InferSchema, AssistantModelMessage, ToolModelMessage, ReasoningPart, SystemModelMessage, ModelMessage, UserModelMessage, ProviderOptions, IdGenerator, ToolCall, MaybePromiseLike, TextPart, FilePart, Resolvable, FetchFunction, DataContent } from '@ai-sdk/provider-utils';
4
+ import { Tool, InferToolInput, InferToolOutput, FlexibleSchema, InferSchema, AssistantModelMessage, ToolModelMessage, ReasoningPart, SystemModelMessage, ModelMessage, ProviderOptions, UserModelMessage, IdGenerator, ToolCall, MaybePromiseLike, TextPart, FilePart, Resolvable, FetchFunction, DataContent } from '@ai-sdk/provider-utils';
5
5
  export { AssistantContent, AssistantModelMessage, DataContent, DownloadError, FilePart, FlexibleSchema, IdGenerator, ImagePart, InferSchema, InferToolInput, InferToolOutput, ModelMessage, Schema, SystemModelMessage, TextPart, Tool, ToolApprovalRequest, ToolApprovalResponse, ToolCallOptions, ToolCallPart, ToolContent, ToolExecuteFunction, ToolExecutionOptions, ToolModelMessage, ToolResultPart, UserContent, UserModelMessage, asSchema, createIdGenerator, dynamicTool, generateId, jsonSchema, parseJsonEventStream, tool, zodSchema } from '@ai-sdk/provider-utils';
6
6
  import * as _ai_sdk_provider from '@ai-sdk/provider';
7
7
  import { EmbeddingModelV3, EmbeddingModelV2, EmbeddingModelV3Embedding, EmbeddingModelV3Middleware, ImageModelV3, ImageModelV2, ImageModelV3ProviderMetadata, ImageModelV2ProviderMetadata, JSONValue as JSONValue$1, LanguageModelV3, LanguageModelV2, LanguageModelV3FinishReason, SharedV3Warning, LanguageModelV3Source, LanguageModelV3Middleware, RerankingModelV3, SharedV3ProviderMetadata, SpeechModelV3, SpeechModelV2, TranscriptionModelV3, TranscriptionModelV2, JSONObject, ImageModelV3Usage, LanguageModelV3CallOptions, AISDKError, LanguageModelV3ToolCall, JSONSchema7, JSONParseError, TypeValidationError, EmbeddingModelCallOptions, ProviderV3, ProviderV2, NoSuchModelError } from '@ai-sdk/provider';
@@ -1169,6 +1169,13 @@ type PrepareStepResult<TOOLS extends Record<string, Tool> = Record<string, Tool>
1169
1169
  * and all subsequent steps.
1170
1170
  */
1171
1171
  experimental_context?: unknown;
1172
+ /**
1173
+ * Additional provider-specific options for this step.
1174
+ *
1175
+ * Can be used to pass provider-specific configuration such as
1176
+ * container IDs for Anthropic's code execution.
1177
+ */
1178
+ providerOptions?: ProviderOptions;
1172
1179
  } | undefined;
1173
1180
 
1174
1181
  type StopCondition<TOOLS extends ToolSet> = (options: {
package/dist/index.js CHANGED
@@ -142,68 +142,6 @@ var import_provider_utils38 = require("@ai-sdk/provider-utils");
142
142
  // src/generate-text/generate-text.ts
143
143
  var import_provider_utils15 = require("@ai-sdk/provider-utils");
144
144
 
145
- // src/logger/log-warnings.ts
146
- function formatWarning({
147
- warning,
148
- provider,
149
- model
150
- }) {
151
- const prefix = `AI SDK Warning (${provider} / ${model}):`;
152
- switch (warning.type) {
153
- case "unsupported": {
154
- let message = `${prefix} The feature "${warning.feature}" is not supported.`;
155
- if (warning.details) {
156
- message += ` ${warning.details}`;
157
- }
158
- return message;
159
- }
160
- case "compatibility": {
161
- let message = `${prefix} The feature "${warning.feature}" is used in a compatibility mode.`;
162
- if (warning.details) {
163
- message += ` ${warning.details}`;
164
- }
165
- return message;
166
- }
167
- case "other": {
168
- return `${prefix} ${warning.message}`;
169
- }
170
- default: {
171
- return `${prefix} ${JSON.stringify(warning, null, 2)}`;
172
- }
173
- }
174
- }
175
- var FIRST_WARNING_INFO_MESSAGE = "AI SDK Warning System: To turn off warning logging, set the AI_SDK_LOG_WARNINGS global to false.";
176
- var hasLoggedBefore = false;
177
- var logWarnings = (options) => {
178
- if (options.warnings.length === 0) {
179
- return;
180
- }
181
- const logger = globalThis.AI_SDK_LOG_WARNINGS;
182
- if (logger === false) {
183
- return;
184
- }
185
- if (typeof logger === "function") {
186
- logger(options);
187
- return;
188
- }
189
- if (!hasLoggedBefore) {
190
- hasLoggedBefore = true;
191
- console.info(FIRST_WARNING_INFO_MESSAGE);
192
- }
193
- for (const warning of options.warnings) {
194
- console.warn(
195
- formatWarning({
196
- warning,
197
- provider: options.provider,
198
- model: options.model
199
- })
200
- );
201
- }
202
- };
203
-
204
- // src/model/resolve-model.ts
205
- var import_gateway = require("@ai-sdk/gateway");
206
-
207
145
  // src/error/index.ts
208
146
  var import_provider15 = require("@ai-sdk/provider");
209
147
 
@@ -511,6 +449,68 @@ var RetryError = class extends import_provider14.AISDKError {
511
449
  };
512
450
  _a12 = symbol12;
513
451
 
452
+ // src/logger/log-warnings.ts
453
+ function formatWarning({
454
+ warning,
455
+ provider,
456
+ model
457
+ }) {
458
+ const prefix = `AI SDK Warning (${provider} / ${model}):`;
459
+ switch (warning.type) {
460
+ case "unsupported": {
461
+ let message = `${prefix} The feature "${warning.feature}" is not supported.`;
462
+ if (warning.details) {
463
+ message += ` ${warning.details}`;
464
+ }
465
+ return message;
466
+ }
467
+ case "compatibility": {
468
+ let message = `${prefix} The feature "${warning.feature}" is used in a compatibility mode.`;
469
+ if (warning.details) {
470
+ message += ` ${warning.details}`;
471
+ }
472
+ return message;
473
+ }
474
+ case "other": {
475
+ return `${prefix} ${warning.message}`;
476
+ }
477
+ default: {
478
+ return `${prefix} ${JSON.stringify(warning, null, 2)}`;
479
+ }
480
+ }
481
+ }
482
+ var FIRST_WARNING_INFO_MESSAGE = "AI SDK Warning System: To turn off warning logging, set the AI_SDK_LOG_WARNINGS global to false.";
483
+ var hasLoggedBefore = false;
484
+ var logWarnings = (options) => {
485
+ if (options.warnings.length === 0) {
486
+ return;
487
+ }
488
+ const logger = globalThis.AI_SDK_LOG_WARNINGS;
489
+ if (logger === false) {
490
+ return;
491
+ }
492
+ if (typeof logger === "function") {
493
+ logger(options);
494
+ return;
495
+ }
496
+ if (!hasLoggedBefore) {
497
+ hasLoggedBefore = true;
498
+ console.info(FIRST_WARNING_INFO_MESSAGE);
499
+ }
500
+ for (const warning of options.warnings) {
501
+ console.warn(
502
+ formatWarning({
503
+ warning,
504
+ provider: options.provider,
505
+ model: options.model
506
+ })
507
+ );
508
+ }
509
+ };
510
+
511
+ // src/model/resolve-model.ts
512
+ var import_gateway = require("@ai-sdk/gateway");
513
+
514
514
  // src/util/log-v2-compatibility-warning.ts
515
515
  function logV2CompatibilityWarning({
516
516
  provider,
@@ -943,7 +943,7 @@ var import_provider_utils3 = require("@ai-sdk/provider-utils");
943
943
  var import_provider_utils4 = require("@ai-sdk/provider-utils");
944
944
 
945
945
  // src/version.ts
946
- var VERSION = true ? "6.0.0-beta.161" : "0.0.0-test";
946
+ var VERSION = true ? "6.0.0-beta.163" : "0.0.0-test";
947
947
 
948
948
  // src/util/download/download.ts
949
949
  var download = async ({ url }) => {
@@ -2138,6 +2138,39 @@ function addImageModelUsage(usage1, usage2) {
2138
2138
  };
2139
2139
  }
2140
2140
 
2141
+ // src/util/merge-objects.ts
2142
+ function mergeObjects(base, overrides) {
2143
+ if (base === void 0 && overrides === void 0) {
2144
+ return void 0;
2145
+ }
2146
+ if (base === void 0) {
2147
+ return overrides;
2148
+ }
2149
+ if (overrides === void 0) {
2150
+ return base;
2151
+ }
2152
+ const result = { ...base };
2153
+ for (const key in overrides) {
2154
+ if (Object.prototype.hasOwnProperty.call(overrides, key)) {
2155
+ const overridesValue = overrides[key];
2156
+ if (overridesValue === void 0)
2157
+ continue;
2158
+ const baseValue = key in base ? base[key] : void 0;
2159
+ const isSourceObject = overridesValue !== null && typeof overridesValue === "object" && !Array.isArray(overridesValue) && !(overridesValue instanceof Date) && !(overridesValue instanceof RegExp);
2160
+ const isTargetObject = baseValue !== null && baseValue !== void 0 && typeof baseValue === "object" && !Array.isArray(baseValue) && !(baseValue instanceof Date) && !(baseValue instanceof RegExp);
2161
+ if (isSourceObject && isTargetObject) {
2162
+ result[key] = mergeObjects(
2163
+ baseValue,
2164
+ overridesValue
2165
+ );
2166
+ } else {
2167
+ result[key] = overridesValue;
2168
+ }
2169
+ }
2170
+ }
2171
+ return result;
2172
+ }
2173
+
2141
2174
  // src/util/retry-with-exponential-backoff.ts
2142
2175
  var import_provider20 = require("@ai-sdk/provider");
2143
2176
  var import_provider_utils9 = require("@ai-sdk/provider-utils");
@@ -3587,6 +3620,7 @@ async function generateText({
3587
3620
  let clientToolCalls = [];
3588
3621
  let clientToolOutputs = [];
3589
3622
  const steps = [];
3623
+ const pendingDeferredToolCalls = /* @__PURE__ */ new Map();
3590
3624
  do {
3591
3625
  const stepInputMessages = [...initialMessages, ...responseMessages];
3592
3626
  const prepareStepResult = await (prepareStep == null ? void 0 : prepareStep({
@@ -3655,13 +3689,17 @@ async function generateText({
3655
3689
  tracer,
3656
3690
  fn: async (span2) => {
3657
3691
  var _a16, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
3692
+ const stepProviderOptions = mergeObjects(
3693
+ providerOptions,
3694
+ prepareStepResult == null ? void 0 : prepareStepResult.providerOptions
3695
+ );
3658
3696
  const result = await stepModel.doGenerate({
3659
3697
  ...callSettings2,
3660
3698
  tools: stepTools,
3661
3699
  toolChoice: stepToolChoice,
3662
3700
  responseFormat: await (output == null ? void 0 : output.responseFormat),
3663
3701
  prompt: promptMessages,
3664
- providerOptions,
3702
+ providerOptions: stepProviderOptions,
3665
3703
  abortSignal,
3666
3704
  headers: headersWithUserAgent
3667
3705
  });
@@ -3785,11 +3823,32 @@ async function generateText({
3785
3823
  })
3786
3824
  );
3787
3825
  }
3826
+ for (const toolCall of stepToolCalls) {
3827
+ if (!toolCall.providerExecuted)
3828
+ continue;
3829
+ const tool2 = tools == null ? void 0 : tools[toolCall.toolName];
3830
+ if ((tool2 == null ? void 0 : tool2.type) === "provider" && tool2.supportsDeferredResults) {
3831
+ const hasResultInResponse = currentModelResponse.content.some(
3832
+ (part) => part.type === "tool-result" && part.toolCallId === toolCall.toolCallId
3833
+ );
3834
+ if (!hasResultInResponse) {
3835
+ pendingDeferredToolCalls.set(toolCall.toolCallId, {
3836
+ toolName: toolCall.toolName
3837
+ });
3838
+ }
3839
+ }
3840
+ }
3841
+ for (const part of currentModelResponse.content) {
3842
+ if (part.type === "tool-result") {
3843
+ pendingDeferredToolCalls.delete(part.toolCallId);
3844
+ }
3845
+ }
3788
3846
  const stepContent = asContent({
3789
3847
  content: currentModelResponse.content,
3790
3848
  toolCalls: stepToolCalls,
3791
3849
  toolOutputs: clientToolOutputs,
3792
- toolApprovalRequests: Object.values(toolApprovalRequests)
3850
+ toolApprovalRequests: Object.values(toolApprovalRequests),
3851
+ tools
3793
3852
  });
3794
3853
  responseMessages.push(
3795
3854
  ...await toResponseMessages({
@@ -3818,9 +3877,10 @@ async function generateText({
3818
3877
  steps.push(currentStepResult);
3819
3878
  await (onStepFinish == null ? void 0 : onStepFinish(currentStepResult));
3820
3879
  } while (
3821
- // there are tool calls:
3822
- clientToolCalls.length > 0 && // all current tool calls have outputs (incl. execution errors):
3823
- clientToolOutputs.length === clientToolCalls.length && // continue until a stop condition is met:
3880
+ // Continue if:
3881
+ // 1. There are client tool calls that have all been executed, OR
3882
+ // 2. There are pending deferred results from provider-executed tools
3883
+ (clientToolCalls.length > 0 && clientToolOutputs.length === clientToolCalls.length || pendingDeferredToolCalls.size > 0) && // continue until a stop condition is met:
3824
3884
  !await isStopConditionMet({ stopConditions, steps })
3825
3885
  );
3826
3886
  span.setAttributes(
@@ -4021,7 +4081,8 @@ function asContent({
4021
4081
  content,
4022
4082
  toolCalls,
4023
4083
  toolOutputs,
4024
- toolApprovalRequests
4084
+ toolApprovalRequests,
4085
+ tools
4025
4086
  }) {
4026
4087
  return [
4027
4088
  ...content.map((part) => {
@@ -4047,7 +4108,31 @@ function asContent({
4047
4108
  (toolCall2) => toolCall2.toolCallId === part.toolCallId
4048
4109
  );
4049
4110
  if (toolCall == null) {
4050
- throw new Error(`Tool call ${part.toolCallId} not found.`);
4111
+ const tool2 = tools == null ? void 0 : tools[part.toolName];
4112
+ const supportsDeferredResults = (tool2 == null ? void 0 : tool2.type) === "provider" && tool2.supportsDeferredResults;
4113
+ if (!supportsDeferredResults) {
4114
+ throw new Error(`Tool call ${part.toolCallId} not found.`);
4115
+ }
4116
+ if (part.isError) {
4117
+ return {
4118
+ type: "tool-error",
4119
+ toolCallId: part.toolCallId,
4120
+ toolName: part.toolName,
4121
+ input: void 0,
4122
+ error: part.result,
4123
+ providerExecuted: true,
4124
+ dynamic: part.dynamic
4125
+ };
4126
+ }
4127
+ return {
4128
+ type: "tool-result",
4129
+ toolCallId: part.toolCallId,
4130
+ toolName: part.toolName,
4131
+ input: void 0,
4132
+ output: part.result,
4133
+ providerExecuted: true,
4134
+ dynamic: part.dynamic
4135
+ };
4051
4136
  }
4052
4137
  if (part.isError) {
4053
4138
  return {
@@ -4396,39 +4481,6 @@ function isDataUIMessageChunk(chunk) {
4396
4481
  return chunk.type.startsWith("data-");
4397
4482
  }
4398
4483
 
4399
- // src/util/merge-objects.ts
4400
- function mergeObjects(base, overrides) {
4401
- if (base === void 0 && overrides === void 0) {
4402
- return void 0;
4403
- }
4404
- if (base === void 0) {
4405
- return overrides;
4406
- }
4407
- if (overrides === void 0) {
4408
- return base;
4409
- }
4410
- const result = { ...base };
4411
- for (const key in overrides) {
4412
- if (Object.prototype.hasOwnProperty.call(overrides, key)) {
4413
- const overridesValue = overrides[key];
4414
- if (overridesValue === void 0)
4415
- continue;
4416
- const baseValue = key in base ? base[key] : void 0;
4417
- const isSourceObject = overridesValue !== null && typeof overridesValue === "object" && !Array.isArray(overridesValue) && !(overridesValue instanceof Date) && !(overridesValue instanceof RegExp);
4418
- const isTargetObject = baseValue !== null && baseValue !== void 0 && typeof baseValue === "object" && !Array.isArray(baseValue) && !(baseValue instanceof Date) && !(baseValue instanceof RegExp);
4419
- if (isSourceObject && isTargetObject) {
4420
- result[key] = mergeObjects(
4421
- baseValue,
4422
- overridesValue
4423
- );
4424
- } else {
4425
- result[key] = overridesValue;
4426
- }
4427
- }
4428
- }
4429
- return result;
4430
- }
4431
-
4432
4484
  // src/ui/ui-messages.ts
4433
4485
  function isDataUIPart(part) {
4434
4486
  return part.type.startsWith("data-");
@@ -5610,6 +5662,7 @@ var DefaultStreamTextResult = class {
5610
5662
  let recordedRequest = {};
5611
5663
  let recordedWarnings = [];
5612
5664
  const recordedSteps = [];
5665
+ const pendingDeferredToolCalls = /* @__PURE__ */ new Map();
5613
5666
  let rootSpan;
5614
5667
  let activeTextContent = {};
5615
5668
  let activeReasoningContent = {};
@@ -6018,6 +6071,10 @@ var DefaultStreamTextResult = class {
6018
6071
  activeTools: (_e = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _e : activeTools
6019
6072
  });
6020
6073
  experimental_context = (_f = prepareStepResult == null ? void 0 : prepareStepResult.experimental_context) != null ? _f : experimental_context;
6074
+ const stepProviderOptions = mergeObjects(
6075
+ providerOptions,
6076
+ prepareStepResult == null ? void 0 : prepareStepResult.providerOptions
6077
+ );
6021
6078
  const {
6022
6079
  result: { stream: stream2, response, request },
6023
6080
  doStreamSpan,
@@ -6071,7 +6128,7 @@ var DefaultStreamTextResult = class {
6071
6128
  toolChoice: stepToolChoice,
6072
6129
  responseFormat: await (output == null ? void 0 : output.responseFormat),
6073
6130
  prompt: promptMessages,
6074
- providerOptions,
6131
+ providerOptions: stepProviderOptions,
6075
6132
  abortSignal,
6076
6133
  headers,
6077
6134
  includeRawChunks: includeRawChunks2
@@ -6319,12 +6376,36 @@ var DefaultStreamTextResult = class {
6319
6376
  const clientToolOutputs = stepToolOutputs.filter(
6320
6377
  (toolOutput) => toolOutput.providerExecuted !== true
6321
6378
  );
6322
- if (clientToolCalls.length > 0 && // all current tool calls have outputs (incl. execution errors):
6323
- clientToolOutputs.length === clientToolCalls.length && // continue until a stop condition is met:
6324
- !await isStopConditionMet({
6325
- stopConditions,
6326
- steps: recordedSteps
6327
- })) {
6379
+ for (const toolCall of stepToolCalls) {
6380
+ if (toolCall.providerExecuted !== true)
6381
+ continue;
6382
+ const tool2 = tools == null ? void 0 : tools[toolCall.toolName];
6383
+ if ((tool2 == null ? void 0 : tool2.type) === "provider" && tool2.supportsDeferredResults) {
6384
+ const hasResultInStep = stepToolOutputs.some(
6385
+ (output2) => output2.type === "tool-result" && output2.toolCallId === toolCall.toolCallId
6386
+ );
6387
+ if (!hasResultInStep) {
6388
+ pendingDeferredToolCalls.set(toolCall.toolCallId, {
6389
+ toolName: toolCall.toolName
6390
+ });
6391
+ }
6392
+ }
6393
+ }
6394
+ for (const output2 of stepToolOutputs) {
6395
+ if (output2.type === "tool-result") {
6396
+ pendingDeferredToolCalls.delete(output2.toolCallId);
6397
+ }
6398
+ }
6399
+ if (
6400
+ // Continue if:
6401
+ // 1. There are client tool calls that have all been executed, OR
6402
+ // 2. There are pending deferred results from provider-executed tools
6403
+ (clientToolCalls.length > 0 && clientToolOutputs.length === clientToolCalls.length || pendingDeferredToolCalls.size > 0) && // continue until a stop condition is met:
6404
+ !await isStopConditionMet({
6405
+ stopConditions,
6406
+ steps: recordedSteps
6407
+ })
6408
+ ) {
6328
6409
  responseMessages.push(
6329
6410
  ...await toResponseMessages({
6330
6411
  content: (