ai 3.4.3 → 3.4.4

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/dist/index.mjs CHANGED
@@ -2915,6 +2915,19 @@ function prepareToolsAndToolChoice({
2915
2915
  };
2916
2916
  }
2917
2917
 
2918
+ // core/util/split-on-last-whitespace.ts
2919
+ var lastWhitespaceRegexp = /^([\s\S]*?)(\s+)(\S*)$/;
2920
+ function splitOnLastWhitespace(text) {
2921
+ const match = text.match(lastWhitespaceRegexp);
2922
+ return match ? { prefix: match[1], whitespace: match[2], suffix: match[3] } : void 0;
2923
+ }
2924
+
2925
+ // core/util/remove-text-after-last-whitespace.ts
2926
+ function removeTextAfterLastWhitespace(text) {
2927
+ const match = splitOnLastWhitespace(text);
2928
+ return match ? match.prefix + match.whitespace : text;
2929
+ }
2930
+
2918
2931
  // core/generate-text/parse-tool-call.ts
2919
2932
  import { safeParseJSON as safeParseJSON2, safeValidateTypes as safeValidateTypes3 } from "@ai-sdk/provider-utils";
2920
2933
  import { asSchema as asSchema3 } from "@ai-sdk/ui-utils";
@@ -3035,7 +3048,7 @@ async function generateText({
3035
3048
  }),
3036
3049
  tracer,
3037
3050
  fn: async (span) => {
3038
- var _a12, _b, _c, _d, _e, _f, _g;
3051
+ var _a12, _b, _c, _d, _e;
3039
3052
  const retry = retryWithExponentialBackoff({ maxRetries });
3040
3053
  const validatedPrompt = validatePrompt({
3041
3054
  system,
@@ -3095,7 +3108,7 @@ async function generateText({
3095
3108
  }),
3096
3109
  tracer,
3097
3110
  fn: async (span2) => {
3098
- var _a13, _b2, _c2, _d2, _e2, _f2;
3111
+ var _a13, _b2, _c2, _d2, _e2, _f;
3099
3112
  const result = await model.doGenerate({
3100
3113
  mode,
3101
3114
  ...callSettings,
@@ -3108,7 +3121,7 @@ async function generateText({
3108
3121
  const responseData = {
3109
3122
  id: (_b2 = (_a13 = result.response) == null ? void 0 : _a13.id) != null ? _b2 : generateId3(),
3110
3123
  timestamp: (_d2 = (_c2 = result.response) == null ? void 0 : _c2.timestamp) != null ? _d2 : currentDate(),
3111
- modelId: (_f2 = (_e2 = result.response) == null ? void 0 : _e2.modelId) != null ? _f2 : model.modelId
3124
+ modelId: (_f = (_e2 = result.response) == null ? void 0 : _e2.modelId) != null ? _f : model.modelId
3112
3125
  };
3113
3126
  span2.setAttributes(
3114
3127
  selectTelemetryAttributes({
@@ -3162,14 +3175,24 @@ async function generateText({
3162
3175
  usage.completionTokens += currentUsage.completionTokens;
3163
3176
  usage.promptTokens += currentUsage.promptTokens;
3164
3177
  usage.totalTokens += currentUsage.totalTokens;
3165
- if (stepType === "continue") {
3166
- text += (_b = currentModelResponse.text) != null ? _b : "";
3167
- } else {
3168
- text = (_c = currentModelResponse.text) != null ? _c : "";
3178
+ let nextStepType = "done";
3179
+ if (++stepCount < maxSteps) {
3180
+ if (continueSteps && currentModelResponse.finishReason === "length" && // only use continue when there are no tool calls:
3181
+ currentToolCalls.length === 0) {
3182
+ nextStepType = "continue";
3183
+ } else if (
3184
+ // there are tool calls:
3185
+ currentToolCalls.length > 0 && // all current tool calls have results:
3186
+ currentToolResults.length === currentToolCalls.length
3187
+ ) {
3188
+ nextStepType = "tool-result";
3189
+ }
3169
3190
  }
3191
+ const stepText = nextStepType === "continue" ? removeTextAfterLastWhitespace((_b = currentModelResponse.text) != null ? _b : "") : (_c = currentModelResponse.text) != null ? _c : "";
3192
+ text = nextStepType === "continue" || stepType === "continue" ? text + stepText : stepText;
3170
3193
  const currentStep = {
3171
3194
  stepType,
3172
- text: (_d = currentModelResponse.text) != null ? _d : "",
3195
+ text: stepText,
3173
3196
  toolCalls: currentToolCalls,
3174
3197
  toolResults: currentToolResults,
3175
3198
  finishReason: currentModelResponse.finishReason,
@@ -3178,7 +3201,7 @@ async function generateText({
3178
3201
  logprobs: currentModelResponse.logprobs,
3179
3202
  response: {
3180
3203
  ...currentModelResponse.response,
3181
- headers: (_e = currentModelResponse.rawResponse) == null ? void 0 : _e.headers
3204
+ headers: (_d = currentModelResponse.rawResponse) == null ? void 0 : _d.headers
3182
3205
  },
3183
3206
  experimental_providerMetadata: currentModelResponse.providerMetadata
3184
3207
  };
@@ -3191,7 +3214,7 @@ async function generateText({
3191
3214
  lastResponseMessage.content = text;
3192
3215
  } else {
3193
3216
  lastResponseMessage.content.push({
3194
- text: (_f = currentModelResponse.text) != null ? _f : "",
3217
+ text: stepText,
3195
3218
  type: "text"
3196
3219
  });
3197
3220
  }
@@ -3199,6 +3222,18 @@ async function generateText({
3199
3222
  promptMessages.push(
3200
3223
  convertToLanguageModelMessage(lastResponseMessage, null)
3201
3224
  );
3225
+ } else if (nextStepType === "continue") {
3226
+ const newResponseMessages = toResponseMessages({
3227
+ text,
3228
+ toolCalls: currentToolCalls,
3229
+ toolResults: currentToolResults
3230
+ });
3231
+ responseMessages.push(...newResponseMessages);
3232
+ promptMessages.push(
3233
+ ...newResponseMessages.map(
3234
+ (message) => convertToLanguageModelMessage(message, null)
3235
+ )
3236
+ );
3202
3237
  } else {
3203
3238
  const newResponseMessages = toResponseMessages({
3204
3239
  text: currentModelResponse.text,
@@ -3212,20 +3247,7 @@ async function generateText({
3212
3247
  )
3213
3248
  );
3214
3249
  }
3215
- if (++stepCount >= maxSteps) {
3216
- stepType = "done";
3217
- } else if (continueSteps && currentStep.finishReason === "length" && // only use continue when there are no tool calls:
3218
- currentToolCalls.length === 0) {
3219
- stepType = "continue";
3220
- } else if (
3221
- // there are tool calls:
3222
- currentToolCalls.length > 0 && // all current tool calls have results:
3223
- currentToolResults.length === currentToolCalls.length
3224
- ) {
3225
- stepType = "tool-result";
3226
- } else {
3227
- stepType = "done";
3228
- }
3250
+ stepType = nextStepType;
3229
3251
  } while (stepType !== "done");
3230
3252
  span.setAttributes(
3231
3253
  selectTelemetryAttributes({
@@ -3260,7 +3282,7 @@ async function generateText({
3260
3282
  warnings: currentModelResponse.warnings,
3261
3283
  response: {
3262
3284
  ...currentModelResponse.response,
3263
- headers: (_g = currentModelResponse.rawResponse) == null ? void 0 : _g.headers
3285
+ headers: (_e = currentModelResponse.rawResponse) == null ? void 0 : _e.headers
3264
3286
  },
3265
3287
  logprobs: currentModelResponse.logprobs,
3266
3288
  responseMessages,
@@ -3949,6 +3971,18 @@ var DefaultStreamTextResult = class {
3949
3971
  timestamp: currentDate(),
3950
3972
  modelId
3951
3973
  };
3974
+ let chunkBuffer = "";
3975
+ let chunkTextPublished = false;
3976
+ async function publishTextChunk({
3977
+ controller,
3978
+ chunk
3979
+ }) {
3980
+ controller.enqueue(chunk);
3981
+ stepText += chunk.textDelta;
3982
+ fullStepText += chunk.textDelta;
3983
+ chunkTextPublished = true;
3984
+ await (onChunk == null ? void 0 : onChunk({ chunk }));
3985
+ }
3952
3986
  addStream(
3953
3987
  stream2.pipeThrough(
3954
3988
  new TransformStream({
@@ -3974,10 +4008,22 @@ var DefaultStreamTextResult = class {
3974
4008
  const chunkType = chunk.type;
3975
4009
  switch (chunkType) {
3976
4010
  case "text-delta": {
3977
- controller.enqueue(chunk);
3978
- stepText += chunk.textDelta;
3979
- fullStepText += chunk.textDelta;
3980
- await (onChunk == null ? void 0 : onChunk({ chunk }));
4011
+ if (continueSteps) {
4012
+ chunkBuffer += chunk.textDelta;
4013
+ const split = splitOnLastWhitespace(chunkBuffer);
4014
+ if (split != null) {
4015
+ chunkBuffer = split.suffix;
4016
+ await publishTextChunk({
4017
+ controller,
4018
+ chunk: {
4019
+ type: "text-delta",
4020
+ textDelta: split.prefix + split.whitespace
4021
+ }
4022
+ });
4023
+ }
4024
+ } else {
4025
+ await publishTextChunk({ controller, chunk });
4026
+ }
3981
4027
  break;
3982
4028
  }
3983
4029
  case "tool-call": {
@@ -4033,6 +4079,30 @@ var DefaultStreamTextResult = class {
4033
4079
  // invoke onFinish callback and resolve toolResults promise when the stream is about to close:
4034
4080
  async flush(controller) {
4035
4081
  const stepToolCallsJson = stepToolCalls.length > 0 ? JSON.stringify(stepToolCalls) : void 0;
4082
+ let nextStepType = "done";
4083
+ if (currentStep + 1 < maxSteps) {
4084
+ if (continueSteps && stepFinishReason === "length" && // only use continue when there are no tool calls:
4085
+ stepToolCalls.length === 0) {
4086
+ nextStepType = "continue";
4087
+ } else if (
4088
+ // there are tool calls:
4089
+ stepToolCalls.length > 0 && // all current tool calls have results:
4090
+ stepToolResults.length === stepToolCalls.length
4091
+ ) {
4092
+ nextStepType = "tool-result";
4093
+ }
4094
+ }
4095
+ if (continueSteps && chunkBuffer.length > 0 && (nextStepType !== "continue" || // when the next step is a regular step, publish the buffer
4096
+ stepType === "continue" && !chunkTextPublished)) {
4097
+ await publishTextChunk({
4098
+ controller,
4099
+ chunk: {
4100
+ type: "text-delta",
4101
+ textDelta: chunkBuffer
4102
+ }
4103
+ });
4104
+ chunkBuffer = "";
4105
+ }
4036
4106
  try {
4037
4107
  doStreamSpan2.setAttributes(
4038
4108
  selectTelemetryAttributes({
@@ -4095,19 +4165,6 @@ var DefaultStreamTextResult = class {
4095
4165
  completionTokens: usage.completionTokens + stepUsage.completionTokens,
4096
4166
  totalTokens: usage.totalTokens + stepUsage.totalTokens
4097
4167
  };
4098
- let nextStepType = "done";
4099
- if (currentStep + 1 < maxSteps) {
4100
- if (continueSteps && stepFinishReason === "length" && // only use continue when there are no tool calls:
4101
- stepToolCalls.length === 0) {
4102
- nextStepType = "continue";
4103
- } else if (
4104
- // there are tool calls:
4105
- stepToolCalls.length > 0 && // all current tool calls have results:
4106
- stepToolResults.length === stepToolCalls.length
4107
- ) {
4108
- nextStepType = "tool-result";
4109
- }
4110
- }
4111
4168
  if (nextStepType !== "done") {
4112
4169
  if (stepType === "continue") {
4113
4170
  const lastPromptMessage = promptMessages2[promptMessages2.length - 1];