ai 2.2.17 → 2.2.19

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.d.ts CHANGED
@@ -42,6 +42,7 @@ interface Message {
42
42
  id: string;
43
43
  createdAt?: Date;
44
44
  content: string;
45
+ ui?: string | JSX.Element | JSX.Element[] | null | undefined;
45
46
  role: 'system' | 'user' | 'assistant' | 'function';
46
47
  /**
47
48
  * If the message has a role of `function`, the `name` field is the name of the function.
@@ -550,7 +551,16 @@ interface Prediction {
550
551
  declare function ReplicateStream(res: Prediction, cb?: AIStreamCallbacksAndOptions): Promise<ReadableStream>;
551
552
 
552
553
  declare const nanoid: (size?: number | undefined) => string;
553
- declare function createChunkDecoder(complex?: boolean): (chunk: Uint8Array | undefined) => any;
554
+ declare function createChunkDecoder(): (chunk: Uint8Array | undefined) => string;
555
+ declare function createChunkDecoder(complex: false): (chunk: Uint8Array | undefined) => string;
556
+ declare function createChunkDecoder(complex: true): (chunk: Uint8Array | undefined) => {
557
+ type: keyof typeof StreamStringPrefixes;
558
+ value: string;
559
+ }[];
560
+ declare function createChunkDecoder(complex?: boolean): (chunk: Uint8Array | undefined) => {
561
+ type: keyof typeof StreamStringPrefixes;
562
+ value: string;
563
+ }[] | string;
554
564
 
555
565
  /**
556
566
  * The map of prefixes for data in the stream
@@ -592,4 +602,32 @@ declare const getStreamStringTypeAndValue: (line: string) => {
592
602
  */
593
603
  declare const COMPLEX_HEADER = "X-Experimental-Stream-Data";
594
604
 
595
- export { AIStream, AIStreamCallbacksAndOptions, AIStreamParser, AnthropicStream, COMPLEX_HEADER, ChatRequest, ChatRequestOptions, CohereStream, CompletionUsage, CreateMessage, FunctionCall, FunctionCallHandler, FunctionCallPayload, HuggingFaceStream, JSONValue, LangChainStream, Message, OpenAIStream, OpenAIStreamCallbacks, ReplicateStream, RequestOptions, StreamString, StreamStringPrefixes, StreamingTextResponse, UseChatOptions, UseCompletionOptions, createCallbacksTransformer, createChunkDecoder, createEventStreamTransformer, createStreamDataTransformer, experimental_StreamData, getStreamString, getStreamStringTypeAndValue, isStreamStringEqualToType, nanoid, readableFromAsyncIterable, streamToResponse, trimStartOfStreamHelper };
605
+ /**
606
+ * This is a naive implementation of the streaming React response API.
607
+ * Currently, it can carry the original raw content, data payload and a special
608
+ * UI payload and stream them via "rows" (nested promises).
609
+ * It must be used inside Server Actions so Flight can encode the React elements.
610
+ *
611
+ * It is naive as unlike the StreamingTextResponse, it does not send the diff
612
+ * between the rows, but flushing the full payload on each row.
613
+ */
614
+ type UINode = string | JSX.Element | JSX.Element[] | null | undefined;
615
+ type Payload = {
616
+ ui: UINode | Promise<UINode>;
617
+ content: string;
618
+ };
619
+ type ReactResponseRow = Payload & {
620
+ next: null | Promise<ReactResponseRow>;
621
+ };
622
+ /**
623
+ * A utility class for streaming React responses.
624
+ */
625
+ declare class experimental_StreamingReactResponse {
626
+ constructor(res: ReadableStream, options?: {
627
+ ui?: (message: {
628
+ content: string;
629
+ }) => UINode | Promise<UINode>;
630
+ });
631
+ }
632
+
633
+ export { AIStream, AIStreamCallbacksAndOptions, AIStreamParser, AnthropicStream, COMPLEX_HEADER, ChatRequest, ChatRequestOptions, CohereStream, CompletionUsage, CreateMessage, FunctionCall, FunctionCallHandler, FunctionCallPayload, HuggingFaceStream, JSONValue, LangChainStream, Message, OpenAIStream, OpenAIStreamCallbacks, ReactResponseRow, ReplicateStream, RequestOptions, StreamString, StreamStringPrefixes, StreamingTextResponse, UseChatOptions, UseCompletionOptions, createCallbacksTransformer, createChunkDecoder, createEventStreamTransformer, createStreamDataTransformer, experimental_StreamData, experimental_StreamingReactResponse, getStreamString, getStreamStringTypeAndValue, isStreamStringEqualToType, nanoid, readableFromAsyncIterable, streamToResponse, trimStartOfStreamHelper };
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ __export(streams_exports, {
35
35
  createEventStreamTransformer: () => createEventStreamTransformer,
36
36
  createStreamDataTransformer: () => createStreamDataTransformer,
37
37
  experimental_StreamData: () => experimental_StreamData,
38
+ experimental_StreamingReactResponse: () => experimental_StreamingReactResponse,
38
39
  getStreamString: () => getStreamString,
39
40
  getStreamStringTypeAndValue: () => getStreamStringTypeAndValue,
40
41
  isStreamStringEqualToType: () => isStreamStringEqualToType,
@@ -231,7 +232,6 @@ var experimental_StreamData = class {
231
232
  self.controller = controller;
232
233
  },
233
234
  transform: async (chunk, controller) => {
234
- controller.enqueue(chunk);
235
235
  if (self.data.length > 0) {
236
236
  const encodedData = self.encoder.encode(
237
237
  getStreamString("data", JSON.stringify(self.data))
@@ -239,6 +239,7 @@ var experimental_StreamData = class {
239
239
  self.data = [];
240
240
  controller.enqueue(encodedData);
241
241
  }
242
+ controller.enqueue(chunk);
242
243
  },
243
244
  async flush(controller) {
244
245
  const warningTimeout = process.env.NODE_ENV === "development" ? setTimeout(() => {
@@ -713,6 +714,46 @@ async function ReplicateStream(res, cb) {
713
714
  createStreamDataTransformer(cb == null ? void 0 : cb.experimental_streamData)
714
715
  );
715
716
  }
717
+
718
+ // streams/streaming-react-response.ts
719
+ var experimental_StreamingReactResponse = class {
720
+ constructor(res, options) {
721
+ let resolveFunc = () => {
722
+ };
723
+ let next = new Promise((resolve) => {
724
+ resolveFunc = resolve;
725
+ });
726
+ let content = "";
727
+ const decode = createChunkDecoder();
728
+ const reader = res.getReader();
729
+ async function readChunk() {
730
+ var _a;
731
+ const { done, value } = await reader.read();
732
+ if (!done) {
733
+ content += decode(value);
734
+ }
735
+ const ui = ((_a = options == null ? void 0 : options.ui) == null ? void 0 : _a.call(options, { content })) || content;
736
+ const payload = {
737
+ ui,
738
+ content
739
+ };
740
+ const resolvePrevious = resolveFunc;
741
+ const nextRow = done ? null : new Promise((resolve) => {
742
+ resolveFunc = resolve;
743
+ });
744
+ resolvePrevious({
745
+ next: nextRow,
746
+ ...payload
747
+ });
748
+ if (done) {
749
+ return;
750
+ }
751
+ await readChunk();
752
+ }
753
+ readChunk();
754
+ return next;
755
+ }
756
+ };
716
757
  // Annotate the CommonJS export names for ESM import in node:
717
758
  0 && (module.exports = {
718
759
  AIStream,
@@ -730,6 +771,7 @@ async function ReplicateStream(res, cb) {
730
771
  createEventStreamTransformer,
731
772
  createStreamDataTransformer,
732
773
  experimental_StreamData,
774
+ experimental_StreamingReactResponse,
733
775
  getStreamString,
734
776
  getStreamStringTypeAndValue,
735
777
  isStreamStringEqualToType,
package/dist/index.mjs CHANGED
@@ -186,7 +186,6 @@ var experimental_StreamData = class {
186
186
  self.controller = controller;
187
187
  },
188
188
  transform: async (chunk, controller) => {
189
- controller.enqueue(chunk);
190
189
  if (self.data.length > 0) {
191
190
  const encodedData = self.encoder.encode(
192
191
  getStreamString("data", JSON.stringify(self.data))
@@ -194,6 +193,7 @@ var experimental_StreamData = class {
194
193
  self.data = [];
195
194
  controller.enqueue(encodedData);
196
195
  }
196
+ controller.enqueue(chunk);
197
197
  },
198
198
  async flush(controller) {
199
199
  const warningTimeout = process.env.NODE_ENV === "development" ? setTimeout(() => {
@@ -668,6 +668,46 @@ async function ReplicateStream(res, cb) {
668
668
  createStreamDataTransformer(cb == null ? void 0 : cb.experimental_streamData)
669
669
  );
670
670
  }
671
+
672
+ // streams/streaming-react-response.ts
673
+ var experimental_StreamingReactResponse = class {
674
+ constructor(res, options) {
675
+ let resolveFunc = () => {
676
+ };
677
+ let next = new Promise((resolve) => {
678
+ resolveFunc = resolve;
679
+ });
680
+ let content = "";
681
+ const decode = createChunkDecoder();
682
+ const reader = res.getReader();
683
+ async function readChunk() {
684
+ var _a;
685
+ const { done, value } = await reader.read();
686
+ if (!done) {
687
+ content += decode(value);
688
+ }
689
+ const ui = ((_a = options == null ? void 0 : options.ui) == null ? void 0 : _a.call(options, { content })) || content;
690
+ const payload = {
691
+ ui,
692
+ content
693
+ };
694
+ const resolvePrevious = resolveFunc;
695
+ const nextRow = done ? null : new Promise((resolve) => {
696
+ resolveFunc = resolve;
697
+ });
698
+ resolvePrevious({
699
+ next: nextRow,
700
+ ...payload
701
+ });
702
+ if (done) {
703
+ return;
704
+ }
705
+ await readChunk();
706
+ }
707
+ readChunk();
708
+ return next;
709
+ }
710
+ };
671
711
  export {
672
712
  AIStream,
673
713
  AnthropicStream,
@@ -684,6 +724,7 @@ export {
684
724
  createEventStreamTransformer,
685
725
  createStreamDataTransformer,
686
726
  experimental_StreamData,
727
+ experimental_StreamingReactResponse,
687
728
  getStreamString,
688
729
  getStreamStringTypeAndValue,
689
730
  isStreamStringEqualToType,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "2.2.17",
3
+ "version": "2.2.19",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -18,6 +18,7 @@ interface Message {
18
18
  id: string;
19
19
  createdAt?: Date;
20
20
  content: string;
21
+ ui?: string | JSX.Element | JSX.Element[] | null | undefined;
21
22
  role: 'system' | 'user' | 'assistant' | 'function';
22
23
  /**
23
24
  * If the message has a role of `function`, the `name` field is the name of the function.
@@ -40,6 +40,7 @@ interface Message {
40
40
  id: string;
41
41
  createdAt?: Date;
42
42
  content: string;
43
+ ui?: string | JSX.Element | JSX.Element[] | null | undefined;
43
44
  role: 'system' | 'user' | 'assistant' | 'function';
44
45
  /**
45
46
  * If the message has a role of `function`, the `name` field is the name of the function.
@@ -197,6 +198,27 @@ type UseCompletionOptions = {
197
198
  body?: object;
198
199
  };
199
200
 
201
+ /**
202
+ * This is a naive implementation of the streaming React response API.
203
+ * Currently, it can carry the original raw content, data payload and a special
204
+ * UI payload and stream them via "rows" (nested promises).
205
+ * It must be used inside Server Actions so Flight can encode the React elements.
206
+ *
207
+ * It is naive as unlike the StreamingTextResponse, it does not send the diff
208
+ * between the rows, but flushing the full payload on each row.
209
+ */
210
+ type UINode = string | JSX.Element | JSX.Element[] | null | undefined;
211
+ /**
212
+ * A utility class for streaming React responses.
213
+ */
214
+ declare class experimental_StreamingReactResponse {
215
+ constructor(res: ReadableStream, options?: {
216
+ ui?: (message: {
217
+ content: string;
218
+ }) => UINode | Promise<UINode>;
219
+ });
220
+ }
221
+
200
222
  type UseChatHelpers = {
201
223
  /** Current messages in the chat */
202
224
  messages: Message[];
@@ -239,7 +261,12 @@ type UseChatHelpers = {
239
261
  /** Additional data added on the server via StreamData */
240
262
  data?: any;
241
263
  };
242
- declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, experimental_onFunctionCall, onResponse, onFinish, onError, credentials, headers, body, }?: UseChatOptions): UseChatHelpers;
264
+ type StreamingReactResponseAction = (payload: {
265
+ messages: Message[];
266
+ }) => Promise<experimental_StreamingReactResponse>;
267
+ declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, experimental_onFunctionCall, onResponse, onFinish, onError, credentials, headers, body, }?: Omit<UseChatOptions, 'api'> & {
268
+ api?: string | StreamingReactResponseAction;
269
+ }): UseChatHelpers;
243
270
 
244
271
  type UseCompletionHelpers = {
245
272
  /** The current completion result */
@@ -91,19 +91,50 @@ var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, exi
91
91
  var _a, _b;
92
92
  const previousMessages = messagesRef.current;
93
93
  mutate(chatRequest.messages, false);
94
+ const constructedMessagesPayload = sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(({ role, content, name, function_call }) => ({
95
+ role,
96
+ content,
97
+ ...name !== void 0 && { name },
98
+ ...function_call !== void 0 && {
99
+ function_call
100
+ }
101
+ }));
102
+ if (typeof api !== "string") {
103
+ const replyId = nanoid();
104
+ const createdAt2 = /* @__PURE__ */ new Date();
105
+ let responseMessage = {
106
+ id: replyId,
107
+ createdAt: createdAt2,
108
+ content: "",
109
+ role: "assistant"
110
+ };
111
+ async function readRow(promise) {
112
+ const { content, ui, next } = await promise;
113
+ responseMessage["content"] = content;
114
+ responseMessage["ui"] = await ui;
115
+ mutate([...chatRequest.messages, { ...responseMessage }], false);
116
+ if (next) {
117
+ await readRow(next);
118
+ }
119
+ }
120
+ try {
121
+ const promise = api({
122
+ messages: constructedMessagesPayload
123
+ });
124
+ await readRow(promise);
125
+ } catch (e) {
126
+ mutate(previousMessages, false);
127
+ throw e;
128
+ }
129
+ if (onFinish) {
130
+ onFinish(responseMessage);
131
+ }
132
+ return responseMessage;
133
+ }
94
134
  const res = await fetch(api, {
95
135
  method: "POST",
96
136
  body: JSON.stringify({
97
- messages: sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
98
- ({ role, content, name, function_call }) => ({
99
- role,
100
- content,
101
- ...name !== void 0 && { name },
102
- ...function_call !== void 0 && {
103
- function_call
104
- }
105
- })
106
- ),
137
+ messages: constructedMessagesPayload,
107
138
  ...extraMetadataRef.current.body,
108
139
  ...(_a = chatRequest.options) == null ? void 0 : _a.body,
109
140
  ...chatRequest.functions !== void 0 && {
@@ -359,8 +390,10 @@ function useChat({
359
390
  messagesRef.current,
360
391
  functionCall
361
392
  );
362
- if (functionCallResponse === void 0)
393
+ if (functionCallResponse === void 0) {
394
+ hasFollowingResponse = false;
363
395
  break;
396
+ }
364
397
  chatRequest = functionCallResponse;
365
398
  }
366
399
  }
@@ -55,19 +55,50 @@ var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, exi
55
55
  var _a, _b;
56
56
  const previousMessages = messagesRef.current;
57
57
  mutate(chatRequest.messages, false);
58
+ const constructedMessagesPayload = sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(({ role, content, name, function_call }) => ({
59
+ role,
60
+ content,
61
+ ...name !== void 0 && { name },
62
+ ...function_call !== void 0 && {
63
+ function_call
64
+ }
65
+ }));
66
+ if (typeof api !== "string") {
67
+ const replyId = nanoid();
68
+ const createdAt2 = /* @__PURE__ */ new Date();
69
+ let responseMessage = {
70
+ id: replyId,
71
+ createdAt: createdAt2,
72
+ content: "",
73
+ role: "assistant"
74
+ };
75
+ async function readRow(promise) {
76
+ const { content, ui, next } = await promise;
77
+ responseMessage["content"] = content;
78
+ responseMessage["ui"] = await ui;
79
+ mutate([...chatRequest.messages, { ...responseMessage }], false);
80
+ if (next) {
81
+ await readRow(next);
82
+ }
83
+ }
84
+ try {
85
+ const promise = api({
86
+ messages: constructedMessagesPayload
87
+ });
88
+ await readRow(promise);
89
+ } catch (e) {
90
+ mutate(previousMessages, false);
91
+ throw e;
92
+ }
93
+ if (onFinish) {
94
+ onFinish(responseMessage);
95
+ }
96
+ return responseMessage;
97
+ }
58
98
  const res = await fetch(api, {
59
99
  method: "POST",
60
100
  body: JSON.stringify({
61
- messages: sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
62
- ({ role, content, name, function_call }) => ({
63
- role,
64
- content,
65
- ...name !== void 0 && { name },
66
- ...function_call !== void 0 && {
67
- function_call
68
- }
69
- })
70
- ),
101
+ messages: constructedMessagesPayload,
71
102
  ...extraMetadataRef.current.body,
72
103
  ...(_a = chatRequest.options) == null ? void 0 : _a.body,
73
104
  ...chatRequest.functions !== void 0 && {
@@ -323,8 +354,10 @@ function useChat({
323
354
  messagesRef.current,
324
355
  functionCall
325
356
  );
326
- if (functionCallResponse === void 0)
357
+ if (functionCallResponse === void 0) {
358
+ hasFollowingResponse = false;
327
359
  break;
360
+ }
328
361
  chatRequest = functionCallResponse;
329
362
  }
330
363
  }
@@ -42,6 +42,7 @@ interface Message {
42
42
  id: string;
43
43
  createdAt?: Date;
44
44
  content: string;
45
+ ui?: string | JSX.Element | JSX.Element[] | null | undefined;
45
46
  role: 'system' | 'user' | 'assistant' | 'function';
46
47
  /**
47
48
  * If the message has a role of `function`, the `name` field is the name of the function.
@@ -42,6 +42,7 @@ interface Message {
42
42
  id: string;
43
43
  createdAt?: Date;
44
44
  content: string;
45
+ ui?: string | JSX.Element | JSX.Element[] | null | undefined;
45
46
  role: 'system' | 'user' | 'assistant' | 'function';
46
47
  /**
47
48
  * If the message has a role of `function`, the `name` field is the name of the function.
@@ -42,6 +42,7 @@ interface Message {
42
42
  id: string;
43
43
  createdAt?: Date;
44
44
  content: string;
45
+ ui?: string | JSX.Element | JSX.Element[] | null | undefined;
45
46
  role: 'system' | 'user' | 'assistant' | 'function';
46
47
  /**
47
48
  * If the message has a role of `function`, the `name` field is the name of the function.