@convex-dev/agent 0.2.7 → 0.2.8-alpha.1
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/UIMessages.d.ts +43 -0
- package/dist/UIMessages.d.ts.map +1 -0
- package/dist/{react/toUIMessages.js → UIMessages.js} +97 -4
- package/dist/UIMessages.js.map +1 -0
- package/dist/client/index.d.ts +10 -10
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +23 -20
- package/dist/client/index.js.map +1 -1
- package/dist/client/messages.d.ts +5 -0
- package/dist/client/messages.d.ts.map +1 -1
- package/dist/client/messages.js +6 -1
- package/dist/client/messages.js.map +1 -1
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +2 -0
- package/dist/client/search.js.map +1 -1
- package/dist/client/start.d.ts.map +1 -1
- package/dist/client/start.js +0 -1
- package/dist/client/start.js.map +1 -1
- package/dist/client/streaming.d.ts +23 -4
- package/dist/client/streaming.d.ts.map +1 -1
- package/dist/client/streaming.js +32 -6
- package/dist/client/streaming.js.map +1 -1
- package/dist/component/_generated/api.d.ts +2 -0
- package/dist/component/messages.js +1 -1
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +10 -4
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +4 -0
- package/dist/component/schema.js.map +1 -1
- package/dist/component/streams.d.ts +2 -4
- package/dist/component/streams.d.ts.map +1 -1
- package/dist/component/streams.js +42 -43
- package/dist/component/streams.js.map +1 -1
- package/dist/deltas.d.ts +48 -0
- package/dist/deltas.d.ts.map +1 -0
- package/dist/deltas.js +468 -0
- package/dist/deltas.js.map +1 -0
- package/dist/react/index.d.ts +4 -77
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +4 -178
- package/dist/react/index.js.map +1 -1
- package/dist/react/optimisticallySendMessage.d.ts +36 -3
- package/dist/react/optimisticallySendMessage.d.ts.map +1 -1
- package/dist/react/optimisticallySendMessage.js +37 -5
- package/dist/react/optimisticallySendMessage.js.map +1 -1
- package/dist/react/types.d.ts +4 -18
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/useStreamingUIMessages.d.ts +22 -0
- package/dist/react/useStreamingUIMessages.d.ts.map +1 -0
- package/dist/react/useStreamingUIMessages.js +204 -0
- package/dist/react/useStreamingUIMessages.js.map +1 -0
- package/dist/react/useThreadMessages.d.ts +104 -0
- package/dist/react/useThreadMessages.d.ts.map +1 -0
- package/dist/react/useThreadMessages.js +140 -0
- package/dist/react/useThreadMessages.js.map +1 -0
- package/dist/react/useUIMessages.d.ts +92 -0
- package/dist/react/useUIMessages.d.ts.map +1 -0
- package/dist/react/useUIMessages.js +116 -0
- package/dist/react/useUIMessages.js.map +1 -0
- package/dist/validators.d.ts +3 -1
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +1 -0
- package/dist/validators.js.map +1 -1
- package/package.json +1 -1
- package/src/{react/toUIMessages.ts → UIMessages.ts} +132 -15
- package/src/client/index.ts +31 -24
- package/src/client/messages.ts +14 -1
- package/src/client/search.ts +2 -0
- package/src/client/start.ts +0 -1
- package/src/client/streaming.test.ts +186 -0
- package/src/client/streaming.ts +50 -9
- package/src/component/_generated/api.d.ts +2 -0
- package/src/component/messages.ts +1 -1
- package/src/component/schema.ts +6 -0
- package/src/component/streams.ts +49 -66
- package/src/{react/deltas.test.ts → deltas.test.ts} +57 -46
- package/src/deltas.ts +589 -0
- package/src/{react/fromUIMessages.test.ts → fromUIMessages.test.ts} +69 -44
- package/src/react/index.ts +8 -250
- package/src/react/optimisticallySendMessage.ts +57 -8
- package/src/react/types.ts +6 -39
- package/src/react/useStreamingUIMessages.ts +294 -0
- package/src/react/useThreadMessages.ts +252 -0
- package/src/react/useUIMessages.ts +207 -0
- package/src/{react/toUIMessages.test.ts → toUIMessages.test.ts} +3 -3
- package/src/validators.ts +3 -0
- package/dist/client/textStreamParts.d.ts +0 -5
- package/dist/client/textStreamParts.d.ts.map +0 -1
- package/dist/client/textStreamParts.js +0 -44
- package/dist/client/textStreamParts.js.map +0 -1
- package/dist/react/deltas.d.ts +0 -27
- package/dist/react/deltas.d.ts.map +0 -1
- package/dist/react/deltas.js +0 -627
- package/dist/react/deltas.js.map +0 -1
- package/dist/react/fromUIMessages.d.ts +0 -13
- package/dist/react/fromUIMessages.d.ts.map +0 -1
- package/dist/react/fromUIMessages.js +0 -75
- package/dist/react/fromUIMessages.js.map +0 -1
- package/dist/react/toUIMessages.d.ts +0 -19
- package/dist/react/toUIMessages.d.ts.map +0 -1
- package/dist/react/toUIMessages.js.map +0 -1
- package/src/client/textStreamParts.ts +0 -62
- package/src/react/deltas.ts +0 -774
- package/src/react/fromUIMessages.ts +0 -90
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
deriveUIMessagesFromTextStreamParts,
|
|
4
|
+
updateFromTextStreamParts,
|
|
5
|
+
} from "./deltas.js";
|
|
6
|
+
import type { StreamMessage, StreamDelta } from "./validators.js";
|
|
4
7
|
import { omit } from "convex-helpers";
|
|
5
|
-
import type { TextStreamPart, ToolSet } from "ai";
|
|
8
|
+
import type { TextStreamPart, ToolSet, ToolUIPart } from "ai";
|
|
6
9
|
|
|
7
10
|
function makeStreamMessage(
|
|
8
11
|
streamId: string,
|
|
@@ -30,7 +33,7 @@ describe("mergeDeltas", () => {
|
|
|
30
33
|
{ type: "text-delta", id: "1", text: "Hello" },
|
|
31
34
|
]),
|
|
32
35
|
];
|
|
33
|
-
const [messages, newStreams, changed] =
|
|
36
|
+
const [messages, newStreams, changed] = deriveUIMessagesFromTextStreamParts(
|
|
34
37
|
"thread1",
|
|
35
38
|
streamMessages,
|
|
36
39
|
[],
|
|
@@ -38,7 +41,7 @@ describe("mergeDeltas", () => {
|
|
|
38
41
|
);
|
|
39
42
|
expect(messages).toHaveLength(1);
|
|
40
43
|
expect(messages[0].text).toBe("Hello");
|
|
41
|
-
expect(messages[0].
|
|
44
|
+
expect(messages[0].role).toBe("assistant");
|
|
42
45
|
expect(changed).toBe(true);
|
|
43
46
|
expect(newStreams[0].cursor).toBe(5);
|
|
44
47
|
});
|
|
@@ -54,7 +57,7 @@ describe("mergeDeltas", () => {
|
|
|
54
57
|
{ type: "text-delta", id: "2", text: " World!" },
|
|
55
58
|
]),
|
|
56
59
|
];
|
|
57
|
-
const [messages, newStreams, changed] =
|
|
60
|
+
const [messages, newStreams, changed] = deriveUIMessagesFromTextStreamParts(
|
|
58
61
|
"thread1",
|
|
59
62
|
streamMessages,
|
|
60
63
|
[],
|
|
@@ -75,7 +78,7 @@ describe("mergeDeltas", () => {
|
|
|
75
78
|
type: "tool-call",
|
|
76
79
|
toolCallId: "call1",
|
|
77
80
|
toolName: "myTool",
|
|
78
|
-
input: "",
|
|
81
|
+
input: "What's the meaning of life?",
|
|
79
82
|
},
|
|
80
83
|
]),
|
|
81
84
|
makeDelta(streamId, 1, 2, [
|
|
@@ -88,28 +91,23 @@ describe("mergeDeltas", () => {
|
|
|
88
91
|
},
|
|
89
92
|
]),
|
|
90
93
|
];
|
|
91
|
-
const [
|
|
94
|
+
const [[message], _, changed] = deriveUIMessagesFromTextStreamParts(
|
|
92
95
|
"thread1",
|
|
93
96
|
streamMessages,
|
|
94
97
|
[],
|
|
95
98
|
deltas,
|
|
96
99
|
);
|
|
97
|
-
expect(
|
|
98
|
-
expect(
|
|
99
|
-
|
|
100
|
-
const content = messages[0].message?.content;
|
|
100
|
+
expect(message).toBeDefined();
|
|
101
|
+
expect(message.role).toBe("assistant");
|
|
102
|
+
const content = message.parts;
|
|
101
103
|
expect(content).toEqual([
|
|
102
|
-
{ type: "tool-call", toolCallId: "call1", toolName: "myTool", args: "" },
|
|
103
|
-
]);
|
|
104
|
-
expect(messages[1].message?.role).toBe("tool");
|
|
105
|
-
expect(messages[1].tool).toBe(true);
|
|
106
|
-
expect(messages[1].message?.content).toEqual([
|
|
107
104
|
{
|
|
108
|
-
type: "tool-
|
|
105
|
+
type: "tool-myTool",
|
|
109
106
|
toolCallId: "call1",
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
input: "What's the meaning of life?",
|
|
108
|
+
output: "42",
|
|
109
|
+
state: "output-available",
|
|
110
|
+
} satisfies ToolUIPart,
|
|
113
111
|
]);
|
|
114
112
|
expect(changed).toBe(true);
|
|
115
113
|
});
|
|
@@ -118,13 +116,12 @@ describe("mergeDeltas", () => {
|
|
|
118
116
|
const streamId = "s3";
|
|
119
117
|
const streamMessages = [makeStreamMessage(streamId, 3, 0)];
|
|
120
118
|
const deltas: StreamDelta[] = [];
|
|
121
|
-
const [
|
|
119
|
+
const [, newStreams, changed] = deriveUIMessagesFromTextStreamParts(
|
|
122
120
|
"thread1",
|
|
123
121
|
streamMessages,
|
|
124
122
|
[],
|
|
125
123
|
deltas,
|
|
126
124
|
);
|
|
127
|
-
expect(messages).toHaveLength(0);
|
|
128
125
|
expect(changed).toBe(false);
|
|
129
126
|
expect(newStreams[0].cursor).toBe(0);
|
|
130
127
|
});
|
|
@@ -136,7 +133,12 @@ describe("mergeDeltas", () => {
|
|
|
136
133
|
makeDelta("s2", 0, 3, [{ type: "text-delta", id: "1", text: "B" }]),
|
|
137
134
|
makeDelta("s1", 0, 3, [{ type: "text-delta", id: "2", text: "A" }]),
|
|
138
135
|
];
|
|
139
|
-
const [messages, _, changed] =
|
|
136
|
+
const [messages, _, changed] = deriveUIMessagesFromTextStreamParts(
|
|
137
|
+
"thread1",
|
|
138
|
+
[s2, s1],
|
|
139
|
+
[],
|
|
140
|
+
deltas,
|
|
141
|
+
);
|
|
140
142
|
expect(messages).toHaveLength(2);
|
|
141
143
|
expect(messages[0].text).toBe("A");
|
|
142
144
|
expect(messages[1].text).toBe("B");
|
|
@@ -158,11 +160,16 @@ describe("mergeDeltas", () => {
|
|
|
158
160
|
]),
|
|
159
161
|
makeDelta(streamId, 11, 12, [{ type: "text-delta", id: "3", text: "!" }]),
|
|
160
162
|
];
|
|
161
|
-
const [messages] =
|
|
163
|
+
const [messages] = deriveUIMessagesFromTextStreamParts(
|
|
164
|
+
"thread1",
|
|
165
|
+
streamMessages,
|
|
166
|
+
[],
|
|
167
|
+
deltas,
|
|
168
|
+
);
|
|
162
169
|
expect(messages).toHaveLength(1);
|
|
163
170
|
expect(messages[0].text).toBe("Hello World!!");
|
|
164
171
|
// There should only be one text part per message
|
|
165
|
-
const content = messages[0].
|
|
172
|
+
const content = messages[0].parts;
|
|
166
173
|
if (Array.isArray(content)) {
|
|
167
174
|
const textParts = content.filter((p) => p.type === "text");
|
|
168
175
|
expect(textParts).toHaveLength(1);
|
|
@@ -175,20 +182,28 @@ describe("mergeDeltas", () => {
|
|
|
175
182
|
const streamMessages = [makeStreamMessage(streamId, 6, 0)];
|
|
176
183
|
const deltas = [
|
|
177
184
|
makeDelta(streamId, 0, 1, [
|
|
185
|
+
{ type: "reasoning-start", id: "1" },
|
|
178
186
|
{ type: "reasoning-delta", id: "1", text: "I'm thinking..." },
|
|
179
187
|
]),
|
|
180
188
|
makeDelta(streamId, 1, 2, [
|
|
181
|
-
{ type: "reasoning-delta", id: "
|
|
189
|
+
{ type: "reasoning-delta", id: "1", text: " Still thinking..." },
|
|
182
190
|
]),
|
|
191
|
+
makeDelta(streamId, 2, 3, [{ type: "reasoning-end", id: "1" }]),
|
|
183
192
|
];
|
|
184
|
-
const [messages] =
|
|
193
|
+
const [messages] = deriveUIMessagesFromTextStreamParts(
|
|
194
|
+
"thread1",
|
|
195
|
+
streamMessages,
|
|
196
|
+
[],
|
|
197
|
+
deltas,
|
|
198
|
+
);
|
|
185
199
|
expect(messages).toHaveLength(1);
|
|
186
|
-
if (Array.isArray(messages[0].
|
|
187
|
-
const reasoningParts = messages[0].
|
|
200
|
+
if (Array.isArray(messages[0].parts)) {
|
|
201
|
+
const reasoningParts = messages[0].parts.filter(
|
|
188
202
|
(p) => p.type === "reasoning",
|
|
189
203
|
);
|
|
190
204
|
expect(reasoningParts).toHaveLength(1);
|
|
191
205
|
expect(reasoningParts[0].text).toBe("I'm thinking... Still thinking...");
|
|
206
|
+
expect(reasoningParts[0].state).toBe("done");
|
|
192
207
|
}
|
|
193
208
|
});
|
|
194
209
|
|
|
@@ -204,47 +219,43 @@ describe("mergeDeltas", () => {
|
|
|
204
219
|
]),
|
|
205
220
|
];
|
|
206
221
|
// First call: apply both deltas
|
|
207
|
-
let [result, changed] =
|
|
222
|
+
let [result, changed] = updateFromTextStreamParts(
|
|
208
223
|
"thread1",
|
|
209
224
|
streamMessage,
|
|
210
225
|
undefined,
|
|
211
226
|
deltas,
|
|
212
227
|
);
|
|
213
|
-
expect(result.
|
|
214
|
-
expect(result.messages[0].text).toBe("Hello World!");
|
|
228
|
+
expect(result.message.text).toBe("Hello World!");
|
|
215
229
|
// Second call: re-apply the same deltas (should not duplicate)
|
|
216
|
-
[result, changed] =
|
|
230
|
+
[result, changed] = updateFromTextStreamParts(
|
|
217
231
|
"thread1",
|
|
218
232
|
streamMessage,
|
|
219
233
|
result,
|
|
220
234
|
deltas,
|
|
221
235
|
);
|
|
222
|
-
expect(result.
|
|
223
|
-
expect(result.messages[0].text).toBe("Hello World!");
|
|
236
|
+
expect(result.message.text).toBe("Hello World!");
|
|
224
237
|
// Third call: add a new delta
|
|
225
238
|
const moreDeltas = [
|
|
226
239
|
...deltas,
|
|
227
240
|
makeDelta(streamId, 11, 12, [{ type: "text-delta", id: "3", text: "!" }]),
|
|
228
241
|
];
|
|
229
|
-
[result, changed] =
|
|
242
|
+
[result, changed] = updateFromTextStreamParts(
|
|
230
243
|
"thread1",
|
|
231
244
|
streamMessage,
|
|
232
245
|
result,
|
|
233
246
|
moreDeltas,
|
|
234
247
|
);
|
|
235
248
|
expect(changed).toBe(true);
|
|
236
|
-
expect(result.
|
|
237
|
-
expect(result.messages[0].text).toBe("Hello World!!");
|
|
249
|
+
expect(result.message.text).toBe("Hello World!!");
|
|
238
250
|
// Re-apply all deltas again (should still not duplicate)
|
|
239
|
-
[result, changed] =
|
|
251
|
+
[result, changed] = updateFromTextStreamParts(
|
|
240
252
|
"thread1",
|
|
241
253
|
streamMessage,
|
|
242
254
|
result,
|
|
243
255
|
moreDeltas,
|
|
244
256
|
);
|
|
245
257
|
expect(changed).toBe(false);
|
|
246
|
-
expect(result.
|
|
247
|
-
expect(result.messages[0].text).toBe("Hello World!!");
|
|
258
|
+
expect(result.message.text).toBe("Hello World!!");
|
|
248
259
|
});
|
|
249
260
|
|
|
250
261
|
it("mergeDeltas is pure and does not mutate inputs", () => {
|
|
@@ -270,13 +281,13 @@ describe("mergeDeltas", () => {
|
|
|
270
281
|
}
|
|
271
282
|
deepFreeze(streamMessages);
|
|
272
283
|
deepFreeze(deltas);
|
|
273
|
-
const [messages1, streams1, changed1] =
|
|
284
|
+
const [messages1, streams1, changed1] = deriveUIMessagesFromTextStreamParts(
|
|
274
285
|
"thread1",
|
|
275
286
|
streamMessages,
|
|
276
287
|
[],
|
|
277
288
|
deltas,
|
|
278
289
|
);
|
|
279
|
-
const [messages2, streams2, changed2] =
|
|
290
|
+
const [messages2, streams2, changed2] = deriveUIMessagesFromTextStreamParts(
|
|
280
291
|
"thread1",
|
|
281
292
|
streamMessages,
|
|
282
293
|
[],
|
|
@@ -288,12 +299,12 @@ describe("mergeDeltas", () => {
|
|
|
288
299
|
expect(
|
|
289
300
|
streams1.map((s) => ({
|
|
290
301
|
...s,
|
|
291
|
-
|
|
302
|
+
message: omit(s.message, ["_creationTime"]),
|
|
292
303
|
})),
|
|
293
304
|
).toEqual(
|
|
294
305
|
streams2.map((s) => ({
|
|
295
306
|
...s,
|
|
296
|
-
|
|
307
|
+
message: omit(s.message, ["_creationTime"]),
|
|
297
308
|
})),
|
|
298
309
|
);
|
|
299
310
|
expect(changed1).toBe(changed2);
|