ai 4.1.18 → 4.1.20

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,22 @@
1
1
  # ai
2
2
 
3
+ ## 4.1.20
4
+
5
+ ### Patch Changes
6
+
7
+ - bcc61d4: feat (ui): introduce message parts for useChat
8
+ - Updated dependencies [bcc61d4]
9
+ - @ai-sdk/ui-utils@1.1.10
10
+ - @ai-sdk/react@1.1.10
11
+
12
+ ## 4.1.19
13
+
14
+ ### Patch Changes
15
+
16
+ - Updated dependencies [6b8cc14]
17
+ - @ai-sdk/ui-utils@1.1.9
18
+ - @ai-sdk/react@1.1.9
19
+
3
20
  ## 4.1.18
4
21
 
5
22
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IDGenerator } from '@ai-sdk/provider-utils';
2
2
  export { CoreToolCall, CoreToolResult, IDGenerator, ToolCall, ToolResult, createIdGenerator, generateId } from '@ai-sdk/provider-utils';
3
- import { DataStreamString, ToolInvocation, Attachment, Schema, DeepPartial, Message, JSONValue as JSONValue$1, AssistantMessage, DataMessage } from '@ai-sdk/ui-utils';
3
+ import { DataStreamString, Message, Schema, DeepPartial, JSONValue as JSONValue$1, AssistantMessage, DataMessage } from '@ai-sdk/ui-utils';
4
4
  export { AssistantMessage, AssistantStatus, Attachment, ChatRequest, ChatRequestOptions, CreateMessage, DataMessage, DataStreamPart, DeepPartial, IdGenerator, JSONValue, Message, RequestOptions, Schema, ToolInvocation, UseAssistantOptions, formatAssistantStreamPart, formatDataStreamPart, jsonSchema, parseAssistantStreamPart, parseDataStreamPart, processDataStream, processTextStream } from '@ai-sdk/ui-utils';
5
5
  import { JSONValue, EmbeddingModelV1, EmbeddingModelV1Embedding, ImageModelV1, ImageModelV1CallWarning, LanguageModelV1, LanguageModelV1FinishReason, LanguageModelV1LogProbs, LanguageModelV1CallWarning, LanguageModelV1ProviderMetadata, LanguageModelV1CallOptions, AISDKError, LanguageModelV1FunctionToolCall, JSONSchema7, ProviderV1, NoSuchModelError } from '@ai-sdk/provider';
6
6
  export { AISDKError, APICallError, EmptyResponseBodyError, InvalidPromptError, InvalidResponseDataError, JSONParseError, LanguageModelV1, LanguageModelV1CallOptions, LanguageModelV1Prompt, LanguageModelV1StreamPart, LoadAPIKeyError, NoContentGeneratedError, NoSuchModelError, TypeValidationError, UnsupportedFunctionalityError } from '@ai-sdk/provider';
@@ -838,13 +838,6 @@ It can be a user message, an assistant message, or a tool message.
838
838
  type CoreMessage = CoreSystemMessage | CoreUserMessage | CoreAssistantMessage | CoreToolMessage;
839
839
  declare const coreMessageSchema: z.ZodType<CoreMessage>;
840
840
 
841
- type UIMessage = {
842
- role: 'system' | 'user' | 'assistant' | 'data';
843
- content: string;
844
- toolInvocations?: ToolInvocation[];
845
- experimental_attachments?: Attachment[];
846
- };
847
-
848
841
  /**
849
842
  Prompt part of the AI function options.
850
843
  It contains a system message, a simple text prompt, or a list of messages.
@@ -861,7 +854,7 @@ type Prompt = {
861
854
  /**
862
855
  A list of messages. You can either use `prompt` or `messages` but not both.
863
856
  */
864
- messages?: Array<CoreMessage> | Array<UIMessage>;
857
+ messages?: Array<CoreMessage> | Array<Omit<Message, 'id'>>;
865
858
  };
866
859
 
867
860
  /**
@@ -1711,16 +1704,22 @@ type StepResult<TOOLS extends ToolSet> = {
1711
1704
  *
1712
1705
  * @returns A new Message[] with the response messages appended.
1713
1706
  */
1714
- declare function appendResponseMessages({ messages, responseMessages, }: {
1707
+ declare function appendResponseMessages({ messages, responseMessages, _internal: { currentDate }, }: {
1715
1708
  messages: Message[];
1716
1709
  responseMessages: ResponseMessage[];
1710
+ /**
1711
+ Internal. For test use only. May change without notice.
1712
+ */
1713
+ _internal?: {
1714
+ currentDate?: () => Date;
1715
+ };
1717
1716
  }): Message[];
1718
1717
 
1719
1718
  /**
1720
1719
  Converts an array of messages from useChat into an array of CoreMessages that can be used
1721
1720
  with the AI core functions (e.g. `streamText`).
1722
1721
  */
1723
- declare function convertToCoreMessages<TOOLS extends ToolSet = never>(messages: Array<UIMessage>, options?: {
1722
+ declare function convertToCoreMessages<TOOLS extends ToolSet = never>(messages: Array<Omit<Message, 'id'>>, options?: {
1724
1723
  tools?: TOOLS;
1725
1724
  }): CoreMessage[];
1726
1725
 
@@ -2750,9 +2749,9 @@ declare class InvalidMessageRoleError extends AISDKError {
2750
2749
  declare const symbol$2: unique symbol;
2751
2750
  declare class MessageConversionError extends AISDKError {
2752
2751
  private readonly [symbol$2];
2753
- readonly originalMessage: UIMessage;
2752
+ readonly originalMessage: Omit<Message, 'id'>;
2754
2753
  constructor({ originalMessage, message, }: {
2755
- originalMessage: UIMessage;
2754
+ originalMessage: Omit<Message, 'id'>;
2756
2755
  message: string;
2757
2756
  });
2758
2757
  static isInstance(error: unknown): error is MessageConversionError;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IDGenerator } from '@ai-sdk/provider-utils';
2
2
  export { CoreToolCall, CoreToolResult, IDGenerator, ToolCall, ToolResult, createIdGenerator, generateId } from '@ai-sdk/provider-utils';
3
- import { DataStreamString, ToolInvocation, Attachment, Schema, DeepPartial, Message, JSONValue as JSONValue$1, AssistantMessage, DataMessage } from '@ai-sdk/ui-utils';
3
+ import { DataStreamString, Message, Schema, DeepPartial, JSONValue as JSONValue$1, AssistantMessage, DataMessage } from '@ai-sdk/ui-utils';
4
4
  export { AssistantMessage, AssistantStatus, Attachment, ChatRequest, ChatRequestOptions, CreateMessage, DataMessage, DataStreamPart, DeepPartial, IdGenerator, JSONValue, Message, RequestOptions, Schema, ToolInvocation, UseAssistantOptions, formatAssistantStreamPart, formatDataStreamPart, jsonSchema, parseAssistantStreamPart, parseDataStreamPart, processDataStream, processTextStream } from '@ai-sdk/ui-utils';
5
5
  import { JSONValue, EmbeddingModelV1, EmbeddingModelV1Embedding, ImageModelV1, ImageModelV1CallWarning, LanguageModelV1, LanguageModelV1FinishReason, LanguageModelV1LogProbs, LanguageModelV1CallWarning, LanguageModelV1ProviderMetadata, LanguageModelV1CallOptions, AISDKError, LanguageModelV1FunctionToolCall, JSONSchema7, ProviderV1, NoSuchModelError } from '@ai-sdk/provider';
6
6
  export { AISDKError, APICallError, EmptyResponseBodyError, InvalidPromptError, InvalidResponseDataError, JSONParseError, LanguageModelV1, LanguageModelV1CallOptions, LanguageModelV1Prompt, LanguageModelV1StreamPart, LoadAPIKeyError, NoContentGeneratedError, NoSuchModelError, TypeValidationError, UnsupportedFunctionalityError } from '@ai-sdk/provider';
@@ -838,13 +838,6 @@ It can be a user message, an assistant message, or a tool message.
838
838
  type CoreMessage = CoreSystemMessage | CoreUserMessage | CoreAssistantMessage | CoreToolMessage;
839
839
  declare const coreMessageSchema: z.ZodType<CoreMessage>;
840
840
 
841
- type UIMessage = {
842
- role: 'system' | 'user' | 'assistant' | 'data';
843
- content: string;
844
- toolInvocations?: ToolInvocation[];
845
- experimental_attachments?: Attachment[];
846
- };
847
-
848
841
  /**
849
842
  Prompt part of the AI function options.
850
843
  It contains a system message, a simple text prompt, or a list of messages.
@@ -861,7 +854,7 @@ type Prompt = {
861
854
  /**
862
855
  A list of messages. You can either use `prompt` or `messages` but not both.
863
856
  */
864
- messages?: Array<CoreMessage> | Array<UIMessage>;
857
+ messages?: Array<CoreMessage> | Array<Omit<Message, 'id'>>;
865
858
  };
866
859
 
867
860
  /**
@@ -1711,16 +1704,22 @@ type StepResult<TOOLS extends ToolSet> = {
1711
1704
  *
1712
1705
  * @returns A new Message[] with the response messages appended.
1713
1706
  */
1714
- declare function appendResponseMessages({ messages, responseMessages, }: {
1707
+ declare function appendResponseMessages({ messages, responseMessages, _internal: { currentDate }, }: {
1715
1708
  messages: Message[];
1716
1709
  responseMessages: ResponseMessage[];
1710
+ /**
1711
+ Internal. For test use only. May change without notice.
1712
+ */
1713
+ _internal?: {
1714
+ currentDate?: () => Date;
1715
+ };
1717
1716
  }): Message[];
1718
1717
 
1719
1718
  /**
1720
1719
  Converts an array of messages from useChat into an array of CoreMessages that can be used
1721
1720
  with the AI core functions (e.g. `streamText`).
1722
1721
  */
1723
- declare function convertToCoreMessages<TOOLS extends ToolSet = never>(messages: Array<UIMessage>, options?: {
1722
+ declare function convertToCoreMessages<TOOLS extends ToolSet = never>(messages: Array<Omit<Message, 'id'>>, options?: {
1724
1723
  tools?: TOOLS;
1725
1724
  }): CoreMessage[];
1726
1725
 
@@ -2750,9 +2749,9 @@ declare class InvalidMessageRoleError extends AISDKError {
2750
2749
  declare const symbol$2: unique symbol;
2751
2750
  declare class MessageConversionError extends AISDKError {
2752
2751
  private readonly [symbol$2];
2753
- readonly originalMessage: UIMessage;
2752
+ readonly originalMessage: Omit<Message, 'id'>;
2754
2753
  constructor({ originalMessage, message, }: {
2755
- originalMessage: UIMessage;
2754
+ originalMessage: Omit<Message, 'id'>;
2756
2755
  message: string;
2757
2756
  });
2758
2757
  static isInstance(error: unknown): error is MessageConversionError;
package/dist/index.js CHANGED
@@ -1594,13 +1594,13 @@ _a8 = symbol8;
1594
1594
 
1595
1595
  // core/prompt/convert-to-core-messages.ts
1596
1596
  function convertToCoreMessages(messages, options) {
1597
- var _a15;
1597
+ var _a15, _b;
1598
1598
  const tools = (_a15 = options == null ? void 0 : options.tools) != null ? _a15 : {};
1599
1599
  const coreMessages = [];
1600
1600
  for (let i = 0; i < messages.length; i++) {
1601
1601
  const message = messages[i];
1602
1602
  const isLastMessage = i === messages.length - 1;
1603
- const { role, content, toolInvocations, experimental_attachments } = message;
1603
+ const { role, content, experimental_attachments } = message;
1604
1604
  switch (role) {
1605
1605
  case "system": {
1606
1606
  coreMessages.push({
@@ -1620,6 +1620,92 @@ function convertToCoreMessages(messages, options) {
1620
1620
  break;
1621
1621
  }
1622
1622
  case "assistant": {
1623
+ if (message.parts != null) {
1624
+ let processBlock2 = function() {
1625
+ coreMessages.push({
1626
+ role: "assistant",
1627
+ content: block.map((part) => {
1628
+ switch (part.type) {
1629
+ case "text":
1630
+ return {
1631
+ type: "text",
1632
+ text: part.text
1633
+ };
1634
+ default:
1635
+ return {
1636
+ type: "tool-call",
1637
+ toolCallId: part.toolInvocation.toolCallId,
1638
+ toolName: part.toolInvocation.toolName,
1639
+ args: part.toolInvocation.args
1640
+ };
1641
+ }
1642
+ })
1643
+ });
1644
+ const stepInvocations = block.filter(
1645
+ (part) => part.type === "tool-invocation"
1646
+ ).map((part) => part.toolInvocation);
1647
+ if (stepInvocations.length > 0) {
1648
+ coreMessages.push({
1649
+ role: "tool",
1650
+ content: stepInvocations.map(
1651
+ (toolInvocation) => {
1652
+ if (!("result" in toolInvocation)) {
1653
+ throw new MessageConversionError({
1654
+ originalMessage: message,
1655
+ message: "ToolInvocation must have a result: " + JSON.stringify(toolInvocation)
1656
+ });
1657
+ }
1658
+ const { toolCallId, toolName, result } = toolInvocation;
1659
+ const tool2 = tools[toolName];
1660
+ return (tool2 == null ? void 0 : tool2.experimental_toToolResultContent) != null ? {
1661
+ type: "tool-result",
1662
+ toolCallId,
1663
+ toolName,
1664
+ result: tool2.experimental_toToolResultContent(result),
1665
+ experimental_content: tool2.experimental_toToolResultContent(result)
1666
+ } : {
1667
+ type: "tool-result",
1668
+ toolCallId,
1669
+ toolName,
1670
+ result
1671
+ };
1672
+ }
1673
+ )
1674
+ });
1675
+ }
1676
+ block = [];
1677
+ blockHasToolInvocations = false;
1678
+ currentStep++;
1679
+ };
1680
+ var processBlock = processBlock2;
1681
+ let currentStep = 0;
1682
+ let blockHasToolInvocations = false;
1683
+ let block = [];
1684
+ for (const part of message.parts) {
1685
+ switch (part.type) {
1686
+ case "reasoning":
1687
+ break;
1688
+ case "text": {
1689
+ if (blockHasToolInvocations) {
1690
+ processBlock2();
1691
+ }
1692
+ block.push(part);
1693
+ break;
1694
+ }
1695
+ case "tool-invocation": {
1696
+ if (((_b = part.toolInvocation.step) != null ? _b : 0) !== currentStep) {
1697
+ processBlock2();
1698
+ }
1699
+ block.push(part);
1700
+ blockHasToolInvocations = true;
1701
+ break;
1702
+ }
1703
+ }
1704
+ }
1705
+ processBlock2();
1706
+ break;
1707
+ }
1708
+ const toolInvocations = message.toolInvocations;
1623
1709
  if (toolInvocations == null || toolInvocations.length === 0) {
1624
1710
  coreMessages.push({ role: "assistant", content });
1625
1711
  break;
@@ -5816,16 +5902,17 @@ function appendClientMessage({
5816
5902
  var import_ui_utils9 = require("@ai-sdk/ui-utils");
5817
5903
  function appendResponseMessages({
5818
5904
  messages,
5819
- responseMessages
5905
+ responseMessages,
5906
+ _internal: { currentDate = () => /* @__PURE__ */ new Date() } = {}
5820
5907
  }) {
5821
- var _a15, _b;
5908
+ var _a15, _b, _c, _d;
5822
5909
  const clonedMessages = structuredClone(messages);
5823
5910
  for (const message of responseMessages) {
5824
5911
  const role = message.role;
5825
5912
  const lastMessage = clonedMessages[clonedMessages.length - 1];
5826
5913
  const isLastMessageAssistant = lastMessage.role === "assistant";
5827
5914
  switch (role) {
5828
- case "assistant": {
5915
+ case "assistant":
5829
5916
  let getToolInvocations2 = function(step) {
5830
5917
  return (typeof message.content === "string" ? [] : message.content.filter((part) => part.type === "tool-call")).map((call) => ({
5831
5918
  state: "call",
@@ -5841,40 +5928,71 @@ function appendResponseMessages({
5841
5928
  const maxStep = (0, import_ui_utils9.extractMaxToolInvocationStep)(
5842
5929
  lastMessage.toolInvocations
5843
5930
  );
5931
+ (_a15 = lastMessage.parts) != null ? _a15 : lastMessage.parts = [];
5844
5932
  lastMessage.content = textContent;
5933
+ if (textContent.length > 0) {
5934
+ lastMessage.parts.push({
5935
+ type: "text",
5936
+ text: textContent
5937
+ });
5938
+ }
5845
5939
  lastMessage.toolInvocations = [
5846
- ...(_a15 = lastMessage.toolInvocations) != null ? _a15 : [],
5940
+ ...(_b = lastMessage.toolInvocations) != null ? _b : [],
5847
5941
  ...getToolInvocations2(maxStep === void 0 ? 0 : maxStep + 1)
5848
5942
  ];
5943
+ getToolInvocations2(maxStep === void 0 ? 0 : maxStep + 1).map((call) => ({
5944
+ type: "tool-invocation",
5945
+ toolInvocation: call
5946
+ })).forEach((part) => {
5947
+ lastMessage.parts.push(part);
5948
+ });
5849
5949
  } else {
5850
5950
  clonedMessages.push({
5851
5951
  role: "assistant",
5852
5952
  id: message.id,
5853
- createdAt: /* @__PURE__ */ new Date(),
5953
+ createdAt: currentDate(),
5854
5954
  // generate a createdAt date for the message, will be overridden by the client
5855
5955
  content: textContent,
5856
- toolInvocations: getToolInvocations2(0)
5956
+ toolInvocations: getToolInvocations2(0),
5957
+ parts: [
5958
+ ...textContent.length > 0 ? [{ type: "text", text: textContent }] : [],
5959
+ ...getToolInvocations2(0).map((call) => ({
5960
+ type: "tool-invocation",
5961
+ toolInvocation: call
5962
+ }))
5963
+ ]
5857
5964
  });
5858
5965
  }
5859
5966
  break;
5860
- }
5861
5967
  case "tool": {
5862
- (_b = lastMessage.toolInvocations) != null ? _b : lastMessage.toolInvocations = [];
5968
+ (_c = lastMessage.toolInvocations) != null ? _c : lastMessage.toolInvocations = [];
5863
5969
  if (lastMessage.role !== "assistant") {
5864
5970
  throw new Error(
5865
5971
  `Tool result must follow an assistant message: ${lastMessage.role}`
5866
5972
  );
5867
5973
  }
5868
- for (const part of message.content) {
5974
+ (_d = lastMessage.parts) != null ? _d : lastMessage.parts = [];
5975
+ for (const contentPart of message.content) {
5869
5976
  const toolCall = lastMessage.toolInvocations.find(
5870
- (call) => call.toolCallId === part.toolCallId
5977
+ (call) => call.toolCallId === contentPart.toolCallId
5978
+ );
5979
+ const toolCallPart = lastMessage.parts.find(
5980
+ (part) => part.type === "tool-invocation" && part.toolInvocation.toolCallId === contentPart.toolCallId
5871
5981
  );
5872
5982
  if (!toolCall) {
5873
5983
  throw new Error("Tool call not found in previous message");
5874
5984
  }
5875
5985
  toolCall.state = "result";
5876
5986
  const toolResult = toolCall;
5877
- toolResult.result = part.result;
5987
+ toolResult.result = contentPart.result;
5988
+ if (toolCallPart) {
5989
+ toolCallPart.toolInvocation = toolResult;
5990
+ } else {
5991
+ lastMessage.parts.push({
5992
+ type: "tool-invocation",
5993
+ toolInvocation: toolResult
5994
+ });
5995
+ }
5878
5996
  }
5879
5997
  break;
5880
5998
  }