ai 3.0.5 → 3.0.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "3.0.5",
3
+ "version": "3.0.7",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -20,44 +20,37 @@
20
20
  ".": {
21
21
  "types": "./dist/index.d.ts",
22
22
  "import": "./dist/index.mjs",
23
- "module": "./dist/index.mjs",
24
23
  "require": "./dist/index.js"
25
24
  },
26
25
  "./rsc": {
27
- "types": "./rsc/dist/index.d.mts",
26
+ "types": "./rsc/dist/index.d.ts",
28
27
  "react-server": "./rsc/dist/rsc-server.mjs",
29
- "import": "./rsc/dist/rsc-client.mjs",
30
- "module": "./rsc/dist/rsc-client.mjs"
28
+ "import": "./rsc/dist/rsc-client.mjs"
31
29
  },
32
30
  "./prompts": {
33
31
  "types": "./prompts/dist/index.d.ts",
34
32
  "import": "./prompts/dist/index.mjs",
35
- "module": "./prompts/dist/index.mjs",
36
33
  "require": "./prompts/dist/index.js"
37
34
  },
38
35
  "./react": {
39
36
  "types": "./react/dist/index.d.ts",
40
37
  "react-server": "./react/dist/index.server.mjs",
41
38
  "import": "./react/dist/index.mjs",
42
- "module": "./react/dist/index.mjs",
43
39
  "require": "./react/dist/index.js"
44
40
  },
45
41
  "./svelte": {
46
42
  "types": "./svelte/dist/index.d.ts",
47
43
  "import": "./svelte/dist/index.mjs",
48
- "module": "./svelte/dist/index.mjs",
49
44
  "require": "./svelte/dist/index.js"
50
45
  },
51
46
  "./vue": {
52
47
  "types": "./vue/dist/index.d.ts",
53
48
  "import": "./vue/dist/index.mjs",
54
- "module": "./vue/dist/index.mjs",
55
49
  "require": "./vue/dist/index.js"
56
50
  },
57
51
  "./solid": {
58
52
  "types": "./solid/dist/index.d.ts",
59
53
  "import": "./solid/dist/index.mjs",
60
- "module": "./solid/dist/index.mjs",
61
54
  "require": "./solid/dist/index.js"
62
55
  }
63
56
  },
@@ -0,0 +1,190 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import OpenAI from 'openai';
4
+ import { z } from 'zod';
5
+
6
+ declare const STREAMABLE_VALUE_TYPE: unique symbol;
7
+
8
+ type AIAction<T = any, R = any> = (...args: T[]) => Promise<R>;
9
+ type AIActions<T = any, R = any> = Record<string, AIAction<T, R>>;
10
+ type AIProviderProps<AIState = any, UIState = any, Actions = any> = {
11
+ children: React.ReactNode;
12
+ initialAIState?: AIState;
13
+ initialUIState?: UIState;
14
+ /** $ActionTypes is only added for type inference and is never used at runtime **/
15
+ $ActionTypes?: Actions;
16
+ };
17
+ type AIProvider<AIState = any, UIState = any, Actions = any> = (props: AIProviderProps<AIState, UIState, Actions>) => Promise<React.ReactElement>;
18
+ type InferAIState<T, Fallback> = T extends AIProvider<infer AIState, any, any> ? AIState : Fallback;
19
+ type InferUIState<T, Fallback> = T extends AIProvider<any, infer UIState, any> ? UIState : Fallback;
20
+ type InferActions<T, Fallback> = T extends AIProvider<any, any, infer Actions> ? Actions : Fallback;
21
+ type OnSetAIState<S> = ({ key, state, done, }: {
22
+ key: string | number | symbol | undefined;
23
+ state: S;
24
+ done: boolean;
25
+ }) => void | Promise<void>;
26
+ type OnGetUIState<S> = AIAction<void, S | undefined>;
27
+ type ValueOrUpdater<T> = T | ((current: T) => T);
28
+ type MutableAIState<AIState> = {
29
+ get: () => AIState;
30
+ update: (newState: ValueOrUpdater<AIState>) => void;
31
+ done: ((newState: AIState) => void) | (() => void);
32
+ };
33
+ type StreamableValue<T = any, E = any> = {
34
+ type?: typeof STREAMABLE_VALUE_TYPE;
35
+ curr?: T;
36
+ error?: E;
37
+ next?: Promise<StreamableValue<T, E>>;
38
+ };
39
+
40
+ /**
41
+ * Get the current AI state.
42
+ * If `key` is provided, it will return the value of the specified key in the
43
+ * AI state, if it's an object. If it's not an object, it will throw an error.
44
+ *
45
+ * @example const state = getAIState() // Get the entire AI state
46
+ * @example const field = getAIState('key') // Get the value of the key
47
+ */
48
+ declare function getAIState<AI extends AIProvider = any>(): InferAIState<AI, any>;
49
+ declare function getAIState<AI extends AIProvider = any>(key: keyof InferAIState<AI, any>): InferAIState<AI, any>[typeof key];
50
+ /**
51
+ * Get the mutable AI state. Note that you must call `.close()` when finishing
52
+ * updating the AI state.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * const state = getMutableAIState()
57
+ * state.update({ ...state.get(), key: 'value' })
58
+ * state.update((currentState) => ({ ...currentState, key: 'value' }))
59
+ * state.done()
60
+ * ```
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * const state = getMutableAIState()
65
+ * state.done({ ...state.get(), key: 'value' }) // Done with a new state
66
+ * ```
67
+ */
68
+ declare function getMutableAIState<AI extends AIProvider = any>(): MutableAIState<InferAIState<AI, any>>;
69
+ declare function getMutableAIState<AI extends AIProvider = any>(key: keyof InferAIState<AI, any>): MutableAIState<InferAIState<AI, any>[typeof key]>;
70
+
71
+ /**
72
+ * Create a piece of changable UI that can be streamed to the client.
73
+ * On the client side, it can be rendered as a normal React node.
74
+ */
75
+ declare function createStreamableUI(initialValue?: React.ReactNode): {
76
+ value: react_jsx_runtime.JSX.Element;
77
+ update(value: React.ReactNode): void;
78
+ append(value: React.ReactNode): void;
79
+ error(error: any): void;
80
+ done(...args: any): void;
81
+ };
82
+ /**
83
+ * Create a wrapped, changable value that can be streamed to the client.
84
+ * On the client side, the value can be accessed via the readStreamableValue() API.
85
+ */
86
+ declare function createStreamableValue<T = any, E = any>(initialValue?: T): {
87
+ value: StreamableValue<T, E>;
88
+ update(value: T): void;
89
+ error(error: any): void;
90
+ done(...args: any): void;
91
+ };
92
+ type Streamable = ReactNode | Promise<ReactNode>;
93
+ type Renderer<T> = (props: T) => Streamable | Generator<Streamable, Streamable, void> | AsyncGenerator<Streamable, Streamable, void>;
94
+ /**
95
+ * `render` is a helper function to create a streamable UI from some LLMs.
96
+ * Currently, it only supports OpenAI's GPT models with Function Calling and Assistants Tools.
97
+ */
98
+ declare function render<TS extends {
99
+ [name: string]: z.Schema;
100
+ } = {}, FS extends {
101
+ [name: string]: z.Schema;
102
+ } = {}>(options: {
103
+ /**
104
+ * The model name to use. Must be OpenAI SDK compatible. Tools and Functions are only supported
105
+ * GPT models (3.5/4), OpenAI Assistants, Mistral small and large, and Fireworks firefunction-v1.
106
+ *
107
+ * @example "gpt-3.5-turbo"
108
+ */
109
+ model: string;
110
+ /**
111
+ * The provider instance to use. Currently the only provider available is OpenAI.
112
+ * This needs to match the model name.
113
+ */
114
+ provider: OpenAI;
115
+ messages: Parameters<typeof OpenAI.prototype.chat.completions.create>[0]['messages'];
116
+ text?: Renderer<{
117
+ content: string;
118
+ done: boolean;
119
+ }>;
120
+ tools?: {
121
+ [name in keyof TS]: {
122
+ description?: string;
123
+ parameters: TS[name];
124
+ render: Renderer<z.infer<TS[name]>>;
125
+ };
126
+ };
127
+ functions?: {
128
+ [name in keyof FS]: {
129
+ description?: string;
130
+ parameters: FS[name];
131
+ render: Renderer<z.infer<FS[name]>>;
132
+ };
133
+ };
134
+ initial?: ReactNode;
135
+ temperature?: number;
136
+ }): ReactNode;
137
+
138
+ declare function createAI<AIState = any, UIState = any, Actions extends AIActions = {}>({ actions, initialAIState, initialUIState, unstable_onSetAIState: onSetAIState, unstable_onGetUIState: onGetUIState, }: {
139
+ actions: Actions;
140
+ initialAIState?: AIState;
141
+ initialUIState?: UIState;
142
+ unstable_onSetAIState?: OnSetAIState<AIState>;
143
+ unstable_onGetUIState?: OnGetUIState<UIState>;
144
+ }): AIProvider<AIState, UIState, Actions>;
145
+
146
+ /**
147
+ * `readStreamableValue` takes a streamable value created via the `createStreamableValue().value` API,
148
+ * and returns an async iterator.
149
+ *
150
+ * ```js
151
+ * // Inside your AI action:
152
+ *
153
+ * async function action() {
154
+ * 'use server'
155
+ * const streamable = createStreamableValue();
156
+ *
157
+ * streamable.update(1);
158
+ * streamable.update(2);
159
+ * streamable.done(3);
160
+ * // ...
161
+ * return streamable.value;
162
+ * }
163
+ * ```
164
+ *
165
+ * And to read the value:
166
+ *
167
+ * ```js
168
+ * const streamableValue = await action()
169
+ * for await (const v of readStreamableValue(streamableValue)) {
170
+ * console.log(v)
171
+ * }
172
+ * ```
173
+ *
174
+ * This logs out 1, 2, 3 on console.
175
+ */
176
+ declare function readStreamableValue<T = unknown>(streamableValue: StreamableValue<T>): AsyncIterable<T | undefined>;
177
+
178
+ declare function useUIState<AI extends AIProvider = any>(): [InferUIState<AI, any>, (v: InferUIState<AI, any> | ((v_: InferUIState<AI, any>) => InferUIState<AI, any>)) => void];
179
+ declare function useAIState<AI extends AIProvider = any>(): [
180
+ InferAIState<AI, any>,
181
+ (newState: ValueOrUpdater<InferAIState<AI, any>>) => void
182
+ ];
183
+ declare function useAIState<AI extends AIProvider = any>(key: keyof InferAIState<AI, any>): [
184
+ InferAIState<AI, any>[typeof key],
185
+ (newState: ValueOrUpdater<InferAIState<AI, any>[typeof key]>) => void
186
+ ];
187
+ declare function useActions<AI extends AIProvider = any>(): InferActions<AI, any>;
188
+ declare function useSyncUIState(): () => Promise<void>;
189
+
190
+ export { createAI, createStreamableUI, createStreamableValue, getAIState, getMutableAIState, readStreamableValue, render, useAIState, useActions, useSyncUIState, useUIState };
@@ -1 +1,18 @@
1
- //# sourceMappingURL=index.mjs.map
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // rsc/index.ts
17
+ var rsc_exports = {};
18
+ module.exports = __toCommonJS(rsc_exports);
@@ -1 +1 @@
1
- export { useAIState, useActions, useStreamableValue, useSyncUIState, useUIState } from './rsc-shared.mjs';
1
+ export { readStreamableValue, useAIState, useActions, useSyncUIState, useUIState } from './rsc-shared.mjs';
@@ -1,15 +1,15 @@
1
1
  // rsc/rsc-client.ts
2
2
  import {
3
- useStreamableValue,
3
+ readStreamableValue,
4
4
  useUIState,
5
5
  useAIState,
6
6
  useActions,
7
7
  useSyncUIState
8
8
  } from "./rsc-shared.mjs";
9
9
  export {
10
+ readStreamableValue,
10
11
  useAIState,
11
12
  useActions,
12
- useStreamableValue,
13
13
  useSyncUIState,
14
14
  useUIState
15
15
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../rsc-client.ts"],"sourcesContent":["export {\n useStreamableValue,\n useUIState,\n useAIState,\n useActions,\n useSyncUIState,\n} from './rsc-shared.mjs';\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
1
+ {"version":3,"sources":["../rsc-client.ts"],"sourcesContent":["export {\n readStreamableValue,\n useUIState,\n useAIState,\n useActions,\n useSyncUIState,\n} from './rsc-shared.mjs';\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
@@ -2,7 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
  import OpenAI from 'openai';
4
4
  import { z } from 'zod';
5
- import './rsc-shared.mjs';
5
+
6
+ declare const STREAMABLE_VALUE_TYPE: unique symbol;
6
7
 
7
8
  type AIAction<T = any, R = any> = (...args: T[]) => Promise<R>;
8
9
  type AIActions<T = any, R = any> = Record<string, AIAction<T, R>>;
@@ -27,6 +28,12 @@ type MutableAIState<AIState> = {
27
28
  update: (newState: ValueOrUpdater<AIState>) => void;
28
29
  done: ((newState: AIState) => void) | (() => void);
29
30
  };
31
+ type StreamableValue<T = any, E = any> = {
32
+ type?: typeof STREAMABLE_VALUE_TYPE;
33
+ curr?: T;
34
+ error?: E;
35
+ next?: Promise<StreamableValue<T, E>>;
36
+ };
30
37
 
31
38
  /**
32
39
  * Get the current AI state.
@@ -72,18 +79,10 @@ declare function createStreamableUI(initialValue?: React.ReactNode): {
72
79
  };
73
80
  /**
74
81
  * Create a wrapped, changable value that can be streamed to the client.
75
- * On the client side, the value can be accessed via the useStreamableValue() hook.
82
+ * On the client side, the value can be accessed via the readStreamableValue() API.
76
83
  */
77
- declare function createStreamableValue<T = any>(initialValue?: T): {
78
- value: {
79
- type: symbol;
80
- curr: T | undefined;
81
- next: Promise<any>;
82
- } | {
83
- curr: T | undefined;
84
- next: Promise<any>;
85
- type?: undefined;
86
- };
84
+ declare function createStreamableValue<T = any, E = any>(initialValue?: T): {
85
+ value: StreamableValue<T, E>;
87
86
  update(value: T): void;
88
87
  error(error: any): void;
89
88
  done(...args: any): void;
@@ -745,7 +745,7 @@ function createFunctionCallTransformer(callbacks) {
745
745
  type: "function",
746
746
  func: {
747
747
  name: tool.function.name,
748
- arguments: tool.function.arguments
748
+ arguments: JSON.parse(tool.function.arguments)
749
749
  }
750
750
  });
751
751
  }
@@ -842,6 +842,7 @@ function createFunctionCallTransformer(callbacks) {
842
842
 
843
843
  // rsc/constants.ts
844
844
  var STREAMABLE_VALUE_TYPE = Symbol.for("ui.streamable.value");
845
+ var DEV_DEFAULT_STREAMABLE_WARNING_TIME = 15 * 1e3;
845
846
 
846
847
  // rsc/streamable.tsx
847
848
  import { Fragment as Fragment2, jsxs as jsxs2 } from "react/jsx-runtime";
@@ -849,27 +850,39 @@ function createStreamableUI(initialValue) {
849
850
  let currentValue = initialValue;
850
851
  let closed = false;
851
852
  let { row, resolve, reject } = createSuspensedChunk(initialValue);
852
- function assertStream() {
853
+ function assertStream(method) {
853
854
  if (closed) {
854
- throw new Error("UI stream is already closed.");
855
+ throw new Error(method + ": UI stream is already closed.");
855
856
  }
856
857
  }
858
+ let warningTimeout;
859
+ function warnUnclosedStream() {
860
+ if (process.env.NODE_ENV === "development") {
861
+ if (warningTimeout) {
862
+ clearTimeout(warningTimeout);
863
+ }
864
+ warningTimeout = setTimeout(() => {
865
+ console.warn(
866
+ "The streamable UI has been slow to update. This may be a bug or a performance issue or you forgot to call `.done()`."
867
+ );
868
+ }, DEV_DEFAULT_STREAMABLE_WARNING_TIME);
869
+ }
870
+ }
871
+ warnUnclosedStream();
857
872
  return {
858
873
  value: row,
859
874
  update(value) {
860
- assertStream();
875
+ assertStream(".update()");
861
876
  const resolvable = createResolvablePromise();
862
- resolve({ value, done: false, next: resolvable.promise });
877
+ currentValue = value;
878
+ resolve({ value: currentValue, done: false, next: resolvable.promise });
863
879
  resolve = resolvable.resolve;
864
880
  reject = resolvable.reject;
865
- currentValue = value;
881
+ warnUnclosedStream();
866
882
  },
867
883
  append(value) {
868
- assertStream();
884
+ assertStream(".append()");
869
885
  const resolvable = createResolvablePromise();
870
- resolve({ value, done: false, next: resolvable.promise });
871
- resolve = resolvable.resolve;
872
- reject = resolvable.reject;
873
886
  if (typeof currentValue === "string" && typeof value === "string") {
874
887
  currentValue += value;
875
888
  } else {
@@ -878,14 +891,24 @@ function createStreamableUI(initialValue) {
878
891
  value
879
892
  ] });
880
893
  }
894
+ resolve({ value: currentValue, done: false, next: resolvable.promise });
895
+ resolve = resolvable.resolve;
896
+ reject = resolvable.reject;
897
+ warnUnclosedStream();
881
898
  },
882
899
  error(error) {
883
- assertStream();
900
+ assertStream(".error()");
901
+ if (warningTimeout) {
902
+ clearTimeout(warningTimeout);
903
+ }
884
904
  closed = true;
885
905
  reject(error);
886
906
  },
887
907
  done(...args) {
888
- assertStream();
908
+ assertStream(".done()");
909
+ if (warningTimeout) {
910
+ clearTimeout(warningTimeout);
911
+ }
889
912
  closed = true;
890
913
  if (args.length) {
891
914
  resolve({ value: args[0], done: true });
@@ -897,12 +920,26 @@ function createStreamableUI(initialValue) {
897
920
  }
898
921
  function createStreamableValue(initialValue) {
899
922
  let closed = false;
900
- let { promise, resolve, reject } = createResolvablePromise();
901
- function assertStream() {
923
+ let { promise, resolve } = createResolvablePromise();
924
+ function assertStream(method) {
902
925
  if (closed) {
903
- throw new Error("Value stream is already closed.");
926
+ throw new Error(method + ": Value stream is already closed.");
927
+ }
928
+ }
929
+ let warningTimeout;
930
+ function warnUnclosedStream() {
931
+ if (process.env.NODE_ENV === "development") {
932
+ if (warningTimeout) {
933
+ clearTimeout(warningTimeout);
934
+ }
935
+ warningTimeout = setTimeout(() => {
936
+ console.warn(
937
+ "The streamable UI has been slow to update. This may be a bug or a performance issue or you forgot to call `.done()`."
938
+ );
939
+ }, DEV_DEFAULT_STREAMABLE_WARNING_TIME);
904
940
  }
905
941
  }
942
+ warnUnclosedStream();
906
943
  function createWrapped(val, initial) {
907
944
  if (initial) {
908
945
  return {
@@ -919,21 +956,27 @@ function createStreamableValue(initialValue) {
919
956
  return {
920
957
  value: createWrapped(initialValue, true),
921
958
  update(value) {
922
- assertStream();
959
+ assertStream(".update()");
923
960
  const resolvePrevious = resolve;
924
961
  const resolvable = createResolvablePromise();
925
962
  promise = resolvable.promise;
926
963
  resolve = resolvable.resolve;
927
- reject = resolvable.reject;
928
964
  resolvePrevious(createWrapped(value));
965
+ warnUnclosedStream();
929
966
  },
930
967
  error(error) {
931
- assertStream();
968
+ assertStream(".error()");
969
+ if (warningTimeout) {
970
+ clearTimeout(warningTimeout);
971
+ }
932
972
  closed = true;
933
- reject(error);
973
+ resolve({ error });
934
974
  },
935
975
  done(...args) {
936
- assertStream();
976
+ assertStream(".done()");
977
+ if (warningTimeout) {
978
+ clearTimeout(warningTimeout);
979
+ }
937
980
  closed = true;
938
981
  if (args.length) {
939
982
  resolve({ curr: args[0] });