@convex-dev/agent 0.2.7 → 0.2.8-alpha.0

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.
Files changed (99) hide show
  1. package/dist/UIMessages.d.ts +43 -0
  2. package/dist/UIMessages.d.ts.map +1 -0
  3. package/dist/{react/toUIMessages.js → UIMessages.js} +97 -4
  4. package/dist/UIMessages.js.map +1 -0
  5. package/dist/client/index.d.ts +9 -9
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/index.js +22 -19
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/client/search.d.ts.map +1 -1
  10. package/dist/client/search.js +2 -0
  11. package/dist/client/search.js.map +1 -1
  12. package/dist/client/start.d.ts.map +1 -1
  13. package/dist/client/start.js +0 -1
  14. package/dist/client/start.js.map +1 -1
  15. package/dist/client/streaming.d.ts +23 -4
  16. package/dist/client/streaming.d.ts.map +1 -1
  17. package/dist/client/streaming.js +32 -6
  18. package/dist/client/streaming.js.map +1 -1
  19. package/dist/component/_generated/api.d.ts +2 -0
  20. package/dist/component/messages.js +1 -1
  21. package/dist/component/messages.js.map +1 -1
  22. package/dist/component/schema.d.ts +10 -4
  23. package/dist/component/schema.d.ts.map +1 -1
  24. package/dist/component/schema.js +4 -0
  25. package/dist/component/schema.js.map +1 -1
  26. package/dist/component/streams.d.ts +2 -4
  27. package/dist/component/streams.d.ts.map +1 -1
  28. package/dist/component/streams.js +42 -43
  29. package/dist/component/streams.js.map +1 -1
  30. package/dist/deltas.d.ts +48 -0
  31. package/dist/deltas.d.ts.map +1 -0
  32. package/dist/deltas.js +468 -0
  33. package/dist/deltas.js.map +1 -0
  34. package/dist/react/index.d.ts +4 -77
  35. package/dist/react/index.d.ts.map +1 -1
  36. package/dist/react/index.js +4 -178
  37. package/dist/react/index.js.map +1 -1
  38. package/dist/react/optimisticallySendMessage.d.ts +36 -3
  39. package/dist/react/optimisticallySendMessage.d.ts.map +1 -1
  40. package/dist/react/optimisticallySendMessage.js +37 -5
  41. package/dist/react/optimisticallySendMessage.js.map +1 -1
  42. package/dist/react/types.d.ts +4 -18
  43. package/dist/react/types.d.ts.map +1 -1
  44. package/dist/react/useStreamingUIMessages.d.ts +22 -0
  45. package/dist/react/useStreamingUIMessages.d.ts.map +1 -0
  46. package/dist/react/useStreamingUIMessages.js +204 -0
  47. package/dist/react/useStreamingUIMessages.js.map +1 -0
  48. package/dist/react/useThreadMessages.d.ts +103 -0
  49. package/dist/react/useThreadMessages.d.ts.map +1 -0
  50. package/dist/react/useThreadMessages.js +139 -0
  51. package/dist/react/useThreadMessages.js.map +1 -0
  52. package/dist/react/useUIMessages.d.ts +91 -0
  53. package/dist/react/useUIMessages.d.ts.map +1 -0
  54. package/dist/react/useUIMessages.js +115 -0
  55. package/dist/react/useUIMessages.js.map +1 -0
  56. package/dist/validators.d.ts +3 -1
  57. package/dist/validators.d.ts.map +1 -1
  58. package/dist/validators.js +1 -0
  59. package/dist/validators.js.map +1 -1
  60. package/package.json +1 -1
  61. package/src/{react/toUIMessages.ts → UIMessages.ts} +132 -15
  62. package/src/client/index.ts +30 -24
  63. package/src/client/search.ts +2 -0
  64. package/src/client/start.ts +0 -1
  65. package/src/client/streaming.test.ts +186 -0
  66. package/src/client/streaming.ts +50 -9
  67. package/src/component/_generated/api.d.ts +2 -0
  68. package/src/component/messages.ts +1 -1
  69. package/src/component/schema.ts +6 -0
  70. package/src/component/streams.ts +49 -66
  71. package/src/{react/deltas.test.ts → deltas.test.ts} +57 -46
  72. package/src/deltas.ts +589 -0
  73. package/src/{react/fromUIMessages.test.ts → fromUIMessages.test.ts} +69 -44
  74. package/src/react/index.ts +8 -250
  75. package/src/react/optimisticallySendMessage.ts +57 -8
  76. package/src/react/types.ts +6 -39
  77. package/src/react/useStreamingUIMessages.ts +294 -0
  78. package/src/react/useThreadMessages.ts +251 -0
  79. package/src/react/useUIMessages.ts +206 -0
  80. package/src/{react/toUIMessages.test.ts → toUIMessages.test.ts} +3 -3
  81. package/src/validators.ts +3 -0
  82. package/dist/client/textStreamParts.d.ts +0 -5
  83. package/dist/client/textStreamParts.d.ts.map +0 -1
  84. package/dist/client/textStreamParts.js +0 -44
  85. package/dist/client/textStreamParts.js.map +0 -1
  86. package/dist/react/deltas.d.ts +0 -27
  87. package/dist/react/deltas.d.ts.map +0 -1
  88. package/dist/react/deltas.js +0 -627
  89. package/dist/react/deltas.js.map +0 -1
  90. package/dist/react/fromUIMessages.d.ts +0 -13
  91. package/dist/react/fromUIMessages.d.ts.map +0 -1
  92. package/dist/react/fromUIMessages.js +0 -75
  93. package/dist/react/fromUIMessages.js.map +0 -1
  94. package/dist/react/toUIMessages.d.ts +0 -19
  95. package/dist/react/toUIMessages.d.ts.map +0 -1
  96. package/dist/react/toUIMessages.js.map +0 -1
  97. package/src/client/textStreamParts.ts +0 -62
  98. package/src/react/deltas.ts +0 -774
  99. package/src/react/fromUIMessages.ts +0 -90
@@ -1,186 +1,12 @@
1
1
  "use client";
2
- import { omit } from "convex-helpers";
3
- import { useQuery, } from "convex/react";
4
- import { usePaginatedQuery } from "convex-helpers/react";
5
2
  import { useMemo, useState } from "react";
6
- import { toUIMessages } from "./toUIMessages.js";
7
- import { mergeDeltas } from "./deltas.js";
3
+ export { toUIMessages } from "../UIMessages.js";
8
4
  export { optimisticallySendMessage } from "./optimisticallySendMessage.js";
9
5
  export { useSmoothText } from "./useSmoothText.js";
10
6
  export { SmoothText } from "./SmoothText.js";
11
- export { toUIMessages };
12
- /**
13
- * A hook that fetches messages from a thread.
14
- *
15
- * This hook is a wrapper around `usePaginatedQuery` and `useStreamingThreadMessages`.
16
- * It will fetch both full messages and streaming messages, and merge them together.
17
- *
18
- * The query must take as arguments `{ threadId, paginationOpts }` and return a
19
- * pagination result of objects that extend `MessageDoc`.
20
- *
21
- * For streaming, it should look like this:
22
- * ```ts
23
- * export const listThreadMessages = query({
24
- * args: {
25
- * threadId: v.string(),
26
- * paginationOpts: paginationOptsValidator,
27
- * streamArgs: vStreamArgs,
28
- * ... other arguments you want
29
- * },
30
- * handler: async (ctx, { threadId, paginationOpts, streamArgs }) => {
31
- * // await authorizeThreadAccess(ctx, threadId);
32
- * const paginated = await agent.listMessages(ctx, { threadId, paginationOpts });
33
- * const streams = await agent.syncStreams(ctx, { threadId, streamArgs });
34
- * // Here you could filter out / modify the documents & stream deltas.
35
- * return { ...paginated, streams };
36
- * },
37
- * });
38
- * ```
39
- *
40
- * Then the hook can be used like this:
41
- * ```ts
42
- * const messages = useThreadMessages(
43
- * api.myModule.listThreadMessages,
44
- * { threadId },
45
- * { initialNumItems: 10, stream: true }
46
- * );
47
- * ```
48
- *
49
- * @param query The query to use to fetch messages.
50
- * It must take as arguments `{ threadId, paginationOpts }` and return a
51
- * pagination result of objects that extend `MessageDoc`.
52
- * To support streaming, it must also take in `streamArgs: vStreamArgs` and
53
- * return a `streams` object returned from `agent.syncStreams`.
54
- * @param args The arguments to pass to the query other than `paginationOpts`
55
- * and `streamArgs`. So `{ threadId }` at minimum, plus any other arguments that
56
- * you want to pass to the query.
57
- * @param options The options for the query. Similar to usePaginatedQuery.
58
- * To enable streaming, pass `stream: true`.
59
- * @returns The messages. If stream is true, it will return a list of messages
60
- * that includes both full messages and streaming messages.
61
- */
62
- export function useThreadMessages(query, args, options) {
63
- // These are full messages
64
- const paginated = usePaginatedQuery(query, args, { initialNumItems: options.initialNumItems });
65
- let startOrder = paginated.results.at(-1)?.order ?? 0;
66
- for (let i = paginated.results.length - 1; i >= 0; i--) {
67
- const m = paginated.results[i];
68
- if (!m.streaming && m.status === "pending") {
69
- // round down to the nearest 10 for some cache benefits
70
- startOrder = m.order - (m.order % 10);
71
- break;
72
- }
73
- }
74
- // These are streaming messages that will not include full messages.
75
- const streamMessages = useStreamingThreadMessages(query, !options.stream ||
76
- args === "skip" ||
77
- paginated.status === "LoadingFirstPage"
78
- ? "skip"
79
- : { ...args, startOrder });
80
- const merged = useMemo(() => {
81
- const streamListMessages = streamMessages?.map((m) => ({
82
- ...m,
83
- streaming: !m.status || m.status === "pending",
84
- })) ?? [];
85
- return {
86
- ...paginated,
87
- results: paginated.results
88
- .map((m) => ({ ...m, streaming: false }))
89
- // Note: this is intentionally after paginated results.
90
- .concat(streamListMessages)
91
- .sort((a, b) => a.order === b.order ? a.stepOrder - b.stepOrder : a.order - b.order)
92
- .reduce((msgs, msg) => {
93
- const last = msgs.at(-1);
94
- if (!last) {
95
- return [msg];
96
- }
97
- if (last.order !== msg.order || last.stepOrder !== msg.stepOrder) {
98
- return [...msgs, msg];
99
- }
100
- if (last.status === "pending" &&
101
- (msg.streaming || msg.status !== "pending")) {
102
- // Let's prefer a streaming or finalized message over a pending
103
- // one.
104
- return [...msgs.slice(0, -1), msg];
105
- }
106
- // skip the new one if the previous one (listed) was finalized
107
- return msgs;
108
- }, []),
109
- };
110
- }, [paginated, streamMessages]);
111
- return merged;
112
- }
113
- /**
114
- * A hook that fetches streaming messages from a thread.
115
- * This ONLY returns streaming messages. To get both, use `useThreadMessages`.
116
- *
117
- * @param query The query to use to fetch messages.
118
- * It must take as arguments `{ threadId, paginationOpts, streamArgs }` and
119
- * return a `streams` object returned from `agent.syncStreams`.
120
- * @param args The arguments to pass to the query other than `paginationOpts`
121
- * and `streamArgs`. So `{ threadId }` at minimum, plus any other arguments that
122
- * you want to pass to the query.
123
- * @returns The streaming messages.
124
- */
125
- export function useStreamingThreadMessages(query, args) {
126
- // Invariant: streamMessages[streamId] is comprised of all deltas up to the
127
- // cursor. There can be multiple messages in the same stream, e.g. for tool
128
- // calls.
129
- const [streams, setStreams] = useState([]);
130
- const queryArgs = args === "skip" ? args : omit(args, ["startOrder"]);
131
- // Get all the active streams
132
- const streamList = useQuery(query, queryArgs === "skip"
133
- ? queryArgs
134
- : {
135
- ...queryArgs,
136
- paginationOpts: { cursor: null, numItems: 0 },
137
- streamArgs: {
138
- kind: "list",
139
- startOrder: queryArgs.startOrder ?? 0,
140
- },
141
- });
142
- // Get the cursors for all the active streams
143
- const cursors = useMemo(() => {
144
- if (!streamList?.streams)
145
- return [];
146
- if (streamList.streams.kind !== "list") {
147
- throw new Error("Expected list streams");
148
- }
149
- return streamList.streams.messages.map(({ streamId }) => {
150
- const stream = streams.find((s) => s.streamId === streamId);
151
- const cursor = stream?.cursor ?? 0;
152
- return { streamId, cursor };
153
- });
154
- }, [streamList, streams]);
155
- // Get the deltas for all the active streams, if any.
156
- const cursorQuery = useQuery(query, queryArgs === "skip" || !streamList
157
- ? "skip"
158
- : {
159
- ...queryArgs,
160
- paginationOpts: { cursor: null, numItems: 0 },
161
- streamArgs: { kind: "deltas", cursors },
162
- });
163
- // Merge any deltas into the streamChunks, keeping it unmodified if unchanged.
164
- const threadId = args === "skip" ? undefined : args.threadId;
165
- const [messages, newStreams, changed] = useMemo(() => {
166
- if (!threadId)
167
- return [undefined, [], false];
168
- if (!streamList)
169
- return [undefined, [], false];
170
- if (cursorQuery && cursorQuery.streams?.kind !== "deltas") {
171
- throw new Error("Expected deltas streams");
172
- }
173
- return mergeDeltas(threadId, streamList.streams.messages, streams, cursorQuery?.streams?.deltas ?? []);
174
- }, [threadId, cursorQuery, streams, streamList]);
175
- // Now assemble the chunks into messages
176
- if (!threadId) {
177
- return undefined;
178
- }
179
- if (changed) {
180
- setStreams(newStreams);
181
- }
182
- return messages;
183
- }
7
+ export { useThreadMessages, useStreamingThreadMessages, } from "./useThreadMessages.js";
8
+ export { useUIMessages } from "./useUIMessages.js";
9
+ export { useStreamingUIMessages } from "./useStreamingUIMessages.js";
184
10
  /**
185
11
  * @deprecated use useThreadMessages or useStreamingThreadMessages instead
186
12
  * Use this hook to stream text from a server action, using the
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,40 @@
1
- import type { MessageDoc } from "../client/index.js";
1
+ import type { MessageDoc, StreamArgs } from "../validators.js";
2
2
  import type { OptimisticLocalStore } from "convex/browser";
3
- import type { ThreadQuery } from "./types.js";
4
- export declare function optimisticallySendMessage(query: ThreadQuery<unknown, MessageDoc>): (store: OptimisticLocalStore, args: {
3
+ import type { UIMessage } from "../UIMessages.js";
4
+ import type { FunctionReference, PaginationOptions, PaginationResult } from "convex/server";
5
+ import type { SyncStreamsReturnValue } from "@convex-dev/agent";
6
+ /**
7
+ * Adds a sent message to the end of a list of messages, so it shows up until
8
+ * the message is saved on the server and arrives in the query.
9
+ * It generates a message with fields that match both MessageDoc and UIMessage,
10
+ * for convenience. It will not include any other fields you might have in your
11
+ * regular query, however.
12
+ *
13
+ * @param query The query used to fetch messages, typically with
14
+ * useThreadMessages or useUIMessages.
15
+ * @returns A function that can be used to optimistically send a message.
16
+ * If your mutation takes different arguments than { threadId, prompt }, you can
17
+ * use it as a helper function in your optimistic update:
18
+ * ```ts
19
+ * const sendMessage = useMutation(
20
+ * api.chatStreaming.streamStoryAsynchronously,
21
+ * ).withOptimisticUpdate(
22
+ * (store, args) => {
23
+ * optimisticallySendMessage(api.chatStreaming.listThreadMessages)(store, {
24
+ * threadId:
25
+ * prompt: whatever you would have passed to the mutation,
26
+ * })
27
+ * }
28
+ * );
29
+ * ```
30
+ */
31
+ export declare function optimisticallySendMessage(query: FunctionReference<"query", "public", {
32
+ threadId: string;
33
+ paginationOpts: PaginationOptions;
34
+ streamArgs?: StreamArgs;
35
+ }, PaginationResult<MessageDoc | UIMessage> & {
36
+ streams?: SyncStreamsReturnValue;
37
+ }>): (store: OptimisticLocalStore, args: {
5
38
  threadId: string;
6
39
  prompt: string;
7
40
  }) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"optimisticallySendMessage.d.ts","sourceRoot":"","sources":["../../src/react/optimisticallySendMessage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,GACtC,CACD,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,KACvC,IAAI,CA6BR;AAED,wBAAgB,UAAU,WAWzB"}
1
+ {"version":3,"file":"optimisticallySendMessage.d.ts","sourceRoot":"","sources":["../../src/react/optimisticallySendMessage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,iBAAiB,CACtB,OAAO,EACP,QAAQ,EACR;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,iBAAiB,CAAC;IAClC,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,EACD,gBAAgB,CAAC,UAAU,GAAG,SAAS,CAAC,GAAG;IACzC,OAAO,CAAC,EAAE,sBAAsB,CAAC;CAClC,CACF,GACA,CACD,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,KACvC,IAAI,CAoCR;AAED,wBAAgB,UAAU,WAWzB"}
@@ -1,4 +1,29 @@
1
1
  import { insertAtTop } from "convex/react";
2
+ /**
3
+ * Adds a sent message to the end of a list of messages, so it shows up until
4
+ * the message is saved on the server and arrives in the query.
5
+ * It generates a message with fields that match both MessageDoc and UIMessage,
6
+ * for convenience. It will not include any other fields you might have in your
7
+ * regular query, however.
8
+ *
9
+ * @param query The query used to fetch messages, typically with
10
+ * useThreadMessages or useUIMessages.
11
+ * @returns A function that can be used to optimistically send a message.
12
+ * If your mutation takes different arguments than { threadId, prompt }, you can
13
+ * use it as a helper function in your optimistic update:
14
+ * ```ts
15
+ * const sendMessage = useMutation(
16
+ * api.chatStreaming.streamStoryAsynchronously,
17
+ * ).withOptimisticUpdate(
18
+ * (store, args) => {
19
+ * optimisticallySendMessage(api.chatStreaming.listThreadMessages)(store, {
20
+ * threadId:
21
+ * prompt: whatever you would have passed to the mutation,
22
+ * })
23
+ * }
24
+ * );
25
+ * ```
26
+ */
2
27
  export function optimisticallySendMessage(query) {
3
28
  return (store, args) => {
4
29
  const queries = store.getAllQueries(query);
@@ -13,19 +38,26 @@ export function optimisticallySendMessage(query) {
13
38
  }
14
39
  }
15
40
  const order = maxOrder + 1;
41
+ const stepOrder = 0;
42
+ const id = randomUUID();
43
+ const { prompt, ...rest } = args;
16
44
  insertAtTop({
17
45
  paginatedQuery: query,
18
46
  argsToMatch: { threadId: args.threadId, streamArgs: undefined },
19
47
  item: {
48
+ ...rest,
20
49
  _creationTime: Date.now(),
21
- _id: randomUUID(),
50
+ _id: id,
51
+ id,
52
+ key: `${args.threadId}-${order}-${stepOrder}`,
22
53
  order,
23
- stepOrder: 0,
54
+ stepOrder,
24
55
  status: "pending",
25
- threadId: args.threadId,
26
56
  tool: false,
27
- message: { role: "user", content: args.prompt },
28
- text: args.prompt,
57
+ message: { role: "user", content: prompt },
58
+ parts: [{ type: "text", text: prompt }],
59
+ role: "user",
60
+ text: prompt,
29
61
  },
30
62
  localQueryStore: store,
31
63
  });
@@ -1 +1 @@
1
- {"version":3,"file":"optimisticallySendMessage.js","sourceRoot":"","sources":["../../src/react/optimisticallySendMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAK3C,MAAM,UAAU,yBAAyB,CACvC,KAAuC;IAKvC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACjD,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU;gBAAE,SAAS;YAChC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;gBACpC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,GAAG,CAAC,CAAC;QAC3B,WAAW,CAAC;YACV,cAAc,EAAE,KAAK;YACrB,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE;YAC/D,IAAI,EAAE;gBACJ,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE;gBACzB,GAAG,EAAE,UAAU,EAAE;gBACjB,KAAK;gBACL,SAAS,EAAE,CAAC;gBACZ,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,IAAI,EAAE,KAAK;gBACX,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,MAAM;aAClB;YACD,eAAe,EAAE,KAAK;SACvB,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IACE,OAAO,MAAM,KAAK,WAAW;QAC7B,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EACvC,CAAC;QACD,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,CACL,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAC5C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"optimisticallySendMessage.js","sourceRoot":"","sources":["../../src/react/optimisticallySendMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAW3C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAWC;IAKD,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACjD,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU;gBAAE,SAAS;YAChC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;gBACpC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,GAAG,CAAC,CAAC;QAC3B,MAAM,SAAS,GAAG,CAAC,CAAC;QACpB,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;QACjC,WAAW,CAAC;YACV,cAAc,EAAE,KAAK;YACrB,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE;YAC/D,IAAI,EAAE;gBACJ,GAAG,IAAI;gBACP,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE;gBACzB,GAAG,EAAE,EAAE;gBACP,EAAE;gBACF,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,IAAI,SAAS,EAAE;gBAC7C,KAAK;gBACL,SAAS;gBACT,MAAM,EAAE,SAAS;gBACjB,IAAI,EAAE,KAAK;gBACX,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;gBAC1C,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gBACvC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,MAAM;aACb;YACD,eAAe,EAAE,KAAK;SACvB,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IACE,OAAO,MAAM,KAAK,WAAW;QAC7B,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EACvC,CAAC;QACD,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,CACL,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAC5C,CAAC;AACJ,CAAC"}
@@ -1,26 +1,12 @@
1
1
  import type { BetterOmit, Expand } from "convex-helpers";
2
- import type { FunctionArgs, FunctionReference, PaginationOptions, PaginationResult } from "convex/server";
3
- import type { MessageDoc } from "../client/index.js";
2
+ import type { FunctionArgs, FunctionReference } from "convex/server";
4
3
  import type { SyncStreamsReturnValue } from "../client/types.js";
5
4
  import type { StreamArgs } from "../validators.js";
6
- export type ThreadQuery<Args = unknown, M extends MessageDoc = MessageDoc> = FunctionReference<"query", "public", {
5
+ export type StreamQuery<Args = Record<string, unknown>> = FunctionReference<"query", "public", {
7
6
  threadId: string;
8
- paginationOpts: PaginationOptions;
9
- /**
10
- * If { stream: true } is passed, it will also query for stream deltas.
11
- * In order for this to work, the query must take as an argument streamArgs.
12
- */
13
7
  streamArgs?: StreamArgs;
14
- } & Args, PaginationResult<M> & {
15
- streams?: SyncStreamsReturnValue;
16
- }>;
17
- export type ThreadStreamQuery<Args = Record<string, unknown>, M extends MessageDoc = MessageDoc> = FunctionReference<"query", "public", {
18
- threadId: string;
19
- paginationOpts: PaginationOptions;
20
- streamArgs?: StreamArgs;
21
- } & Args, PaginationResult<M> & {
8
+ } & Args, {
22
9
  streams: SyncStreamsReturnValue;
23
10
  }>;
24
- export type ThreadMessagesArgs<Query extends ThreadQuery<unknown, MessageDoc>> = Query extends ThreadQuery<unknown, MessageDoc> ? Expand<BetterOmit<FunctionArgs<Query>, "paginationOpts" | "streamArgs">> : never;
25
- export type ThreadMessagesResult<Query extends ThreadQuery<unknown, MessageDoc>> = Query extends ThreadQuery<unknown, infer M> ? M : never;
11
+ export type StreamMessagesArgs<Query extends StreamQuery<unknown>> = Query extends StreamQuery<unknown> ? Expand<BetterOmit<FunctionArgs<Query>, "streamArgs">> : never;
26
12
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,WAAW,CACrB,IAAI,GAAG,OAAO,EACd,CAAC,SAAS,UAAU,GAAG,UAAU,IAC/B,iBAAiB,CACnB,OAAO,EACP,QAAQ,EACR;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,iBAAiB,CAAC;IAElC;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,GAAG,IAAI,EACR,gBAAgB,CAAC,CAAC,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,sBAAsB,CAAA;CAAE,CAC3D,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAC3B,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,CAAC,SAAS,UAAU,GAAG,UAAU,IAC/B,iBAAiB,CACnB,OAAO,EACP,QAAQ,EACR;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,iBAAiB,CAAC;IAClC,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,GAAG,IAAI,EACR,gBAAgB,CAAC,CAAC,CAAC,GAAG;IAAE,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAC1D,CAAC;AAEF,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,IAC3E,KAAK,SAAS,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,GAC1C,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,YAAY,CAAC,CAAC,GACxE,KAAK,CAAC;AAEZ,MAAM,MAAM,oBAAoB,CAC9B,KAAK,SAAS,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,IAC5C,KAAK,SAAS,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,WAAW,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,iBAAiB,CACzE,OAAO,EACP,QAAQ,EACR;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,GAAG,IAAI,EACR;IAAE,OAAO,EAAE,sBAAsB,CAAA;CAAE,CACpC,CAAC;AAEF,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,WAAW,CAAC,OAAO,CAAC,IAC/D,KAAK,SAAS,WAAW,CAAC,OAAO,CAAC,GAC9B,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC,GACrD,KAAK,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type UIDataTypes, type UITools } from "ai";
2
+ import type { StreamQuery, StreamMessagesArgs } from "./types.js";
3
+ import { type UIMessage } from "../UIMessages.js";
4
+ /**
5
+ * A hook that fetches streaming messages from a thread and converts them to UIMessages
6
+ * using AI SDK's readUIMessageStream.
7
+ * This ONLY returns streaming UIMessages. To get both full and streaming messages,
8
+ * use `useUIMessages`.
9
+ *
10
+ * @param query The query to use to fetch messages.
11
+ * It must take as arguments `{ threadId, paginationOpts, streamArgs }` and
12
+ * return a `streams` object returned from `agent.syncStreams`.
13
+ * @param args The arguments to pass to the query other than `paginationOpts`
14
+ * and `streamArgs`. So `{ threadId }` at minimum, plus any other arguments that
15
+ * you want to pass to the query.
16
+ * @returns The streaming UIMessages.
17
+ */
18
+ export declare function useStreamingUIMessages<METADATA = unknown, DATA_PARTS extends UIDataTypes = UIDataTypes, TOOLS extends UITools = UITools, Query extends StreamQuery<any> = StreamQuery<object>>(query: Query, args: StreamMessagesArgs<Query> | "skip", options?: {
19
+ startOrder?: number;
20
+ skipStreamIds?: string[];
21
+ }): UIMessage<METADATA, DATA_PARTS, TOOLS>[] | undefined;
22
+ //# sourceMappingURL=useStreamingUIMessages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStreamingUIMessages.d.ts","sourceRoot":"","sources":["../../src/react/useStreamingUIMessages.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,WAAW,EAEhB,KAAK,OAAO,EACb,MAAM,IAAI,CAAC;AAGZ,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AASlD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,GAAG,OAAO,EAClB,UAAU,SAAS,WAAW,GAAG,WAAW,EAC5C,KAAK,SAAS,OAAO,GAAG,OAAO,EAE/B,KAAK,SAAS,WAAW,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,EAEpD,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAAG,MAAM,EACxC,OAAO,CAAC,EAAE;IACR,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,GAEA,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,GAAG,SAAS,CAiPtD"}
@@ -0,0 +1,204 @@
1
+ "use client";
2
+ import { omit } from "convex-helpers";
3
+ import { useQuery } from "convex/react";
4
+ import { useMemo, useState, useEffect, useRef } from "react";
5
+ import { readUIMessageStream, } from "ai";
6
+ import {} from "../UIMessages.js";
7
+ import { blankUIMessage, getParts, deriveUIMessagesFromTextStreamParts, statusFromStreamStatus, } from "../deltas.js";
8
+ import { sorted } from "../shared.js";
9
+ /**
10
+ * A hook that fetches streaming messages from a thread and converts them to UIMessages
11
+ * using AI SDK's readUIMessageStream.
12
+ * This ONLY returns streaming UIMessages. To get both full and streaming messages,
13
+ * use `useUIMessages`.
14
+ *
15
+ * @param query The query to use to fetch messages.
16
+ * It must take as arguments `{ threadId, paginationOpts, streamArgs }` and
17
+ * return a `streams` object returned from `agent.syncStreams`.
18
+ * @param args The arguments to pass to the query other than `paginationOpts`
19
+ * and `streamArgs`. So `{ threadId }` at minimum, plus any other arguments that
20
+ * you want to pass to the query.
21
+ * @returns The streaming UIMessages.
22
+ */
23
+ export function useStreamingUIMessages(query, args, options) {
24
+ const [uiMessages, setUIMessages] = useState({});
25
+ const [streamCursors, setStreamCursors] = useState({});
26
+ const uiMessageStreamControllers = useRef(new Map());
27
+ // Get all the active streams
28
+ const streamList = useQuery(query, args === "skip"
29
+ ? args
30
+ : {
31
+ ...args,
32
+ streamArgs: {
33
+ kind: "list",
34
+ startOrder: options?.startOrder ?? 0,
35
+ },
36
+ });
37
+ // Get the cursors for all the active streams
38
+ const cursors = useMemo(() => {
39
+ if (!streamList?.streams)
40
+ return [];
41
+ if (streamList.streams.kind !== "list") {
42
+ throw new Error("Expected list streams");
43
+ }
44
+ return streamList.streams.messages
45
+ .filter(({ streamId }) => !options?.skipStreamIds?.includes(streamId))
46
+ .map(({ streamId }) => {
47
+ const cursor = streamCursors[streamId] ?? 0;
48
+ return { streamId, cursor };
49
+ });
50
+ }, [streamList, streamCursors, options?.skipStreamIds]);
51
+ // Get the deltas for all the active streams, if any.
52
+ const cursorQuery = useQuery(query, args === "skip" || !streamList
53
+ ? "skip"
54
+ : {
55
+ ...args,
56
+ paginationOpts: { cursor: null, numItems: 0 },
57
+ streamArgs: { kind: "deltas", cursors },
58
+ });
59
+ const threadId = args === "skip" ? undefined : args.threadId;
60
+ // Process new deltas and convert to UIMessageChunks, then use readUIMessageStream
61
+ useEffect(() => {
62
+ if (!cursorQuery?.streams?.deltas || !threadId)
63
+ return;
64
+ const deltasByStream = new Map();
65
+ // Group deltas by streamId
66
+ for (const delta of cursorQuery.streams.deltas) {
67
+ if (!deltasByStream.has(delta.streamId)) {
68
+ deltasByStream.set(delta.streamId, []);
69
+ }
70
+ deltasByStream.get(delta.streamId).push(delta);
71
+ }
72
+ // Process each stream's deltas
73
+ for (const [streamId, deltas] of deltasByStream.entries()) {
74
+ const streamMessage = streamList?.streams?.messages.find((m) => m.streamId === streamId);
75
+ if (!streamMessage)
76
+ continue;
77
+ if (streamMessage.format === "UIMessageChunk") {
78
+ setStreamCursors((streamCursors) => {
79
+ const currentCursor = streamCursors[streamId] ?? 0;
80
+ const { parts, cursor } = getParts(deltas, currentCursor);
81
+ const newStreamCursors = cursor === currentCursor
82
+ ? streamCursors
83
+ : { ...streamCursors, [streamId]: cursor };
84
+ if (parts.length === 0)
85
+ return newStreamCursors;
86
+ // Get existing message for this stream as starting point
87
+ const existingStream = uiMessageStreamControllers.current.get(streamId);
88
+ if (existingStream) {
89
+ for (const part of parts) {
90
+ existingStream.enqueue(part);
91
+ }
92
+ }
93
+ else {
94
+ const stream = new ReadableStream({
95
+ start(controller) {
96
+ uiMessageStreamControllers.current.set(streamId, controller);
97
+ for (const part of parts) {
98
+ controller.enqueue(part);
99
+ }
100
+ },
101
+ });
102
+ const initialMessage = blankUIMessage(streamMessage, threadId);
103
+ setUIMessages((prev) => ({
104
+ ...prev,
105
+ [streamId]: initialMessage,
106
+ }));
107
+ const messageStream = readUIMessageStream({
108
+ message: initialMessage,
109
+ stream,
110
+ onError: (error) => {
111
+ setUIMessages((prev) => ({
112
+ ...prev,
113
+ [streamId]: {
114
+ ...prev[streamId],
115
+ status: "failed",
116
+ },
117
+ }));
118
+ console.error(`Error in stream ${streamId}:`, error);
119
+ },
120
+ terminateOnError: false,
121
+ });
122
+ // Process the async iterator
123
+ void (async () => {
124
+ for await (const message of messageStream) {
125
+ message.text = message.parts
126
+ .filter((p) => p.type === "text")
127
+ .map((p) => p.text)
128
+ .join("");
129
+ setUIMessages((prev) =>
130
+ // If we don't have a ui message assume we've aborted.
131
+ prev[streamId]
132
+ ? {
133
+ ...prev,
134
+ [streamId]: message,
135
+ }
136
+ : prev);
137
+ }
138
+ })().catch((error) => {
139
+ console.error(`Error processing stream ${streamId}:`, error);
140
+ });
141
+ }
142
+ return newStreamCursors;
143
+ });
144
+ }
145
+ else {
146
+ setUIMessages((uiMessages) => {
147
+ const existingUIMessage = uiMessages[streamId];
148
+ const [[uiMessage], [streamMetadata], changed] = deriveUIMessagesFromTextStreamParts(threadId, [streamMessage], existingUIMessage
149
+ ? [
150
+ {
151
+ streamId,
152
+ cursor: streamCursors[streamId] ?? 0,
153
+ message: existingUIMessage,
154
+ },
155
+ ]
156
+ : [], deltas);
157
+ if (changed) {
158
+ setStreamCursors((prev) => ({
159
+ ...prev,
160
+ [streamId]: streamMetadata.cursor,
161
+ }));
162
+ return {
163
+ ...uiMessages,
164
+ [streamId]: uiMessage,
165
+ };
166
+ }
167
+ return uiMessages;
168
+ });
169
+ }
170
+ }
171
+ }, [cursorQuery, streamCursors, threadId, streamList?.streams?.messages]);
172
+ // Clean up finished streams
173
+ useEffect(() => {
174
+ const activeStreamIds = new Set(streamList?.streams.messages.map((m) => m.streamId) ?? []);
175
+ setUIMessages((prev) => {
176
+ const toRemove = Object.keys(prev).filter((streamId) => !activeStreamIds.has(streamId));
177
+ return toRemove.length ? omit(prev, toRemove) : prev;
178
+ });
179
+ for (const [streamId, controller,] of uiMessageStreamControllers.current.entries()) {
180
+ if (!activeStreamIds.has(streamId)) {
181
+ controller.close();
182
+ uiMessageStreamControllers.current.delete(streamId);
183
+ }
184
+ }
185
+ }, [streamList]);
186
+ return useMemo(() => {
187
+ if (!streamList)
188
+ return undefined;
189
+ return sorted(Array.from(Object.entries(uiMessages)
190
+ .map(([streamId, uiMessage]) => {
191
+ const streamMessage = streamList?.streams.messages.find((m) => m.streamId === streamId);
192
+ if (!streamMessage)
193
+ return undefined;
194
+ uiMessage.status = statusFromStreamStatus(streamMessage?.status ?? "finished");
195
+ uiMessage.text = uiMessage.parts
196
+ .filter((p) => p.type === "text")
197
+ .map((p) => p.text)
198
+ .join("");
199
+ return uiMessage;
200
+ })
201
+ .filter((uiMessage) => uiMessage !== undefined)));
202
+ }, [uiMessages, streamList]);
203
+ }
204
+ //# sourceMappingURL=useStreamingUIMessages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStreamingUIMessages.js","sourceRoot":"","sources":["../../src/react/useStreamingUIMessages.ts"],"names":[],"mappings":"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"}