@convex-dev/agent 0.6.3 → 0.6.4
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.map +1 -1
- package/dist/UIMessages.js.map +1 -1
- package/dist/client/definePlaygroundAPI.d.ts +69 -64
- package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/client/definePlaygroundAPI.js +8 -5
- package/dist/client/definePlaygroundAPI.js.map +1 -1
- package/dist/client/index.d.ts +12 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +11 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/saveInputMessages.d.ts.map +1 -1
- package/dist/client/saveInputMessages.js.map +1 -1
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/apiKeys.js +5 -5
- package/dist/component/apiKeys.js.map +1 -1
- package/dist/component/files.d.ts.map +1 -1
- package/dist/component/files.js +13 -11
- package/dist/component/files.js.map +1 -1
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +37 -27
- package/dist/component/messages.js.map +1 -1
- package/dist/component/streams.d.ts.map +1 -1
- package/dist/component/streams.js +22 -17
- package/dist/component/streams.js.map +1 -1
- package/dist/component/threads.js +7 -7
- package/dist/component/threads.js.map +1 -1
- package/dist/component/users.js +2 -2
- package/dist/component/users.js.map +1 -1
- package/dist/component/vector/index.d.ts.map +1 -1
- package/dist/component/vector/index.js +14 -8
- package/dist/component/vector/index.js.map +1 -1
- package/dist/deltas.d.ts +16 -27
- package/dist/deltas.d.ts.map +1 -1
- package/dist/deltas.js +269 -286
- package/dist/deltas.js.map +1 -1
- package/dist/mapping.d.ts +9 -3
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +16 -14
- package/dist/mapping.js.map +1 -1
- package/dist/react/useStreamingUIMessages.d.ts.map +1 -1
- package/dist/react/useStreamingUIMessages.js +42 -26
- package/dist/react/useStreamingUIMessages.js.map +1 -1
- package/dist/react/useUIMessages.d.ts +1 -0
- package/dist/react/useUIMessages.d.ts.map +1 -1
- package/dist/react/useUIMessages.js +7 -3
- package/dist/react/useUIMessages.js.map +1 -1
- package/package.json +2 -1
- package/src/UIMessages.ts +1 -2
- package/src/client/approval.test.ts +25 -6
- package/src/client/createTool.ts +1 -1
- package/src/client/definePlaygroundAPI.ts +33 -17
- package/src/client/index.test.ts +91 -0
- package/src/client/index.ts +25 -1
- package/src/client/saveInputMessages.ts +4 -1
- package/src/client/streaming.integration.test.ts +39 -117
- package/src/client/types.ts +4 -17
- package/src/component/apiKeys.ts +5 -5
- package/src/component/files.test.ts +1 -1
- package/src/component/files.ts +14 -12
- package/src/component/messages.ts +40 -28
- package/src/component/streams.ts +33 -17
- package/src/component/threads.ts +7 -7
- package/src/component/users.ts +2 -2
- package/src/component/vector/index.ts +14 -7
- package/src/deltas.test.ts +373 -392
- package/src/deltas.ts +339 -378
- package/src/mapping.test.ts +296 -18
- package/src/mapping.ts +17 -11
- package/src/react/useStreamingUIMessages.ts +62 -34
- package/src/react/useUIMessages.test.ts +80 -1
- package/src/react/useUIMessages.ts +11 -3
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
import { schema, v } from "./schema.js";
|
|
35
35
|
import { insertVector, searchVectors } from "./vector/index.js";
|
|
36
36
|
import {
|
|
37
|
+
getVectorIdInfo,
|
|
37
38
|
validateVectorDimension,
|
|
38
39
|
type VectorTableId,
|
|
39
40
|
vVectorId,
|
|
@@ -50,9 +51,10 @@ export async function deleteMessage(
|
|
|
50
51
|
ctx: MutationCtx,
|
|
51
52
|
messageDoc: Doc<"messages">,
|
|
52
53
|
) {
|
|
53
|
-
await ctx.db.delete(messageDoc._id);
|
|
54
|
+
await ctx.db.delete("messages", messageDoc._id);
|
|
54
55
|
if (messageDoc.embeddingId) {
|
|
55
|
-
|
|
56
|
+
const { tableName } = getVectorIdInfo(ctx, messageDoc.embeddingId);
|
|
57
|
+
await ctx.db.delete(tableName, messageDoc.embeddingId);
|
|
56
58
|
}
|
|
57
59
|
if (messageDoc.fileIds) {
|
|
58
60
|
await changeRefcount(ctx, messageDoc.fileIds, []);
|
|
@@ -65,7 +67,7 @@ export const deleteByIds = mutation({
|
|
|
65
67
|
handler: async (ctx, args) => {
|
|
66
68
|
const deletedMessageIds = await Promise.all(
|
|
67
69
|
args.messageIds.map(async (id) => {
|
|
68
|
-
const message = await ctx.db.get(id);
|
|
70
|
+
const message = await ctx.db.get("messages", id);
|
|
69
71
|
if (message) {
|
|
70
72
|
await deleteMessage(ctx, message);
|
|
71
73
|
return id;
|
|
@@ -157,7 +159,7 @@ async function addMessagesHandler(
|
|
|
157
159
|
let userId = args.userId;
|
|
158
160
|
const threadId = args.threadId;
|
|
159
161
|
if (!userId && args.threadId) {
|
|
160
|
-
const thread = await ctx.db.get(args.threadId);
|
|
162
|
+
const thread = await ctx.db.get("threads", args.threadId);
|
|
161
163
|
assert(thread, `Thread ${args.threadId} not found`);
|
|
162
164
|
userId = thread.userId;
|
|
163
165
|
}
|
|
@@ -172,7 +174,8 @@ async function addMessagesHandler(
|
|
|
172
174
|
hideFromUserIdSearch,
|
|
173
175
|
...rest
|
|
174
176
|
} = args;
|
|
175
|
-
const promptMessage =
|
|
177
|
+
const promptMessage =
|
|
178
|
+
promptMessageId && (await ctx.db.get("messages", promptMessageId));
|
|
176
179
|
if (failPendingSteps) {
|
|
177
180
|
assert(args.threadId, "threadId is required to fail pending steps");
|
|
178
181
|
const pendingMessages = await ctx.db
|
|
@@ -188,9 +191,10 @@ async function addMessagesHandler(
|
|
|
188
191
|
.filter((m) => !pendingMessageId || m._id !== pendingMessageId)
|
|
189
192
|
.map(async (m) => {
|
|
190
193
|
if (m.embeddingId) {
|
|
191
|
-
|
|
194
|
+
const { tableName } = getVectorIdInfo(ctx, m.embeddingId);
|
|
195
|
+
await ctx.db.delete(tableName, m.embeddingId);
|
|
192
196
|
}
|
|
193
|
-
await ctx.db.patch(m._id, {
|
|
197
|
+
await ctx.db.patch("messages", m._id, {
|
|
194
198
|
status: "failed",
|
|
195
199
|
error: "Restarting",
|
|
196
200
|
embeddingId: undefined,
|
|
@@ -257,7 +261,7 @@ async function addMessagesHandler(
|
|
|
257
261
|
// If there is a pending message, we replace that one with the first message
|
|
258
262
|
// and subsequent ones will follow the regular order/subOrder advancement.
|
|
259
263
|
if (i === 0 && pendingMessageId) {
|
|
260
|
-
const pendingMessage = await ctx.db.get(pendingMessageId);
|
|
264
|
+
const pendingMessage = await ctx.db.get("messages", pendingMessageId);
|
|
261
265
|
assert(pendingMessage, `Pending msg ${pendingMessageId} not found`);
|
|
262
266
|
if (pendingMessage.status === "failed") {
|
|
263
267
|
fail = true;
|
|
@@ -274,12 +278,12 @@ async function addMessagesHandler(
|
|
|
274
278
|
message.fileIds,
|
|
275
279
|
);
|
|
276
280
|
}
|
|
277
|
-
await ctx.db.replace(pendingMessage._id, {
|
|
281
|
+
await ctx.db.replace("messages", pendingMessage._id, {
|
|
278
282
|
...messageDoc,
|
|
279
283
|
order: pendingMessage.order,
|
|
280
284
|
stepOrder: pendingMessage.stepOrder,
|
|
281
285
|
});
|
|
282
|
-
toReturn.push((await ctx.db.get(pendingMessage._id))!);
|
|
286
|
+
toReturn.push((await ctx.db.get("messages", pendingMessage._id))!);
|
|
283
287
|
continue;
|
|
284
288
|
}
|
|
285
289
|
if (message.message.role === "user") {
|
|
@@ -306,7 +310,7 @@ async function addMessagesHandler(
|
|
|
306
310
|
await changeRefcount(ctx, [], message.fileIds);
|
|
307
311
|
}
|
|
308
312
|
// TODO: delete the associated stream data for the order/stepOrder
|
|
309
|
-
toReturn.push((await ctx.db.get(messageId))!);
|
|
313
|
+
toReturn.push((await ctx.db.get("messages", messageId))!);
|
|
310
314
|
}
|
|
311
315
|
// Atomically finish the stream if requested, preventing UI flickering
|
|
312
316
|
// from separate mutations for message save and stream finish (issue #181).
|
|
@@ -375,7 +379,7 @@ export const finalizeMessage = mutation({
|
|
|
375
379
|
},
|
|
376
380
|
returns: v.null(),
|
|
377
381
|
handler: async (ctx, { messageId, result }) => {
|
|
378
|
-
const message = await ctx.db.get(messageId);
|
|
382
|
+
const message = await ctx.db.get("messages", messageId);
|
|
379
383
|
assert(message, `Message ${messageId} not found`);
|
|
380
384
|
if (message.status !== "pending") {
|
|
381
385
|
console.debug(
|
|
@@ -406,15 +410,16 @@ export const finalizeMessage = mutation({
|
|
|
406
410
|
}
|
|
407
411
|
if (result.status === "failed") {
|
|
408
412
|
if (message.embeddingId) {
|
|
409
|
-
|
|
413
|
+
const { tableName } = getVectorIdInfo(ctx, message.embeddingId);
|
|
414
|
+
await ctx.db.delete(tableName, message.embeddingId);
|
|
410
415
|
}
|
|
411
|
-
await ctx.db.patch(messageId, {
|
|
416
|
+
await ctx.db.patch("messages", messageId, {
|
|
412
417
|
status: "failed",
|
|
413
418
|
error: result.error,
|
|
414
419
|
embeddingId: undefined,
|
|
415
420
|
});
|
|
416
421
|
} else {
|
|
417
|
-
await ctx.db.patch(messageId, { status: "success" });
|
|
422
|
+
await ctx.db.patch("messages", messageId, { status: "success" });
|
|
418
423
|
}
|
|
419
424
|
},
|
|
420
425
|
});
|
|
@@ -439,7 +444,7 @@ export const updateMessage = mutation({
|
|
|
439
444
|
},
|
|
440
445
|
returns: vMessageDoc,
|
|
441
446
|
handler: async (ctx, args) => {
|
|
442
|
-
const message = await ctx.db.get(args.messageId);
|
|
447
|
+
const message = await ctx.db.get("messages", args.messageId);
|
|
443
448
|
assert(message, `Message ${args.messageId} not found`);
|
|
444
449
|
|
|
445
450
|
if (args.patch.fileIds) {
|
|
@@ -456,13 +461,14 @@ export const updateMessage = mutation({
|
|
|
456
461
|
|
|
457
462
|
if (args.patch.status === "failed") {
|
|
458
463
|
if (message.embeddingId) {
|
|
459
|
-
|
|
464
|
+
const { tableName } = getVectorIdInfo(ctx, message.embeddingId);
|
|
465
|
+
await ctx.db.delete(tableName, message.embeddingId);
|
|
460
466
|
}
|
|
461
467
|
patch.embeddingId = undefined;
|
|
462
468
|
}
|
|
463
469
|
|
|
464
|
-
await ctx.db.patch(args.messageId, patch);
|
|
465
|
-
return publicMessage((await ctx.db.get(args.messageId))!);
|
|
470
|
+
await ctx.db.patch("messages", args.messageId, patch);
|
|
471
|
+
return publicMessage((await ctx.db.get("messages", args.messageId))!);
|
|
466
472
|
},
|
|
467
473
|
});
|
|
468
474
|
|
|
@@ -540,7 +546,8 @@ export const cloneMessageBatch = internalMutation({
|
|
|
540
546
|
}
|
|
541
547
|
let embeddingId: VectorTableId | undefined = undefined;
|
|
542
548
|
if (m.embeddingId) {
|
|
543
|
-
const
|
|
549
|
+
const { tableName } = getVectorIdInfo(ctx, m.embeddingId);
|
|
550
|
+
const vector = await ctx.db.get(tableName, m.embeddingId);
|
|
544
551
|
assert(vector, `Vector ${m.embeddingId} not found`);
|
|
545
552
|
const dimension = vector.vector.length;
|
|
546
553
|
validateVectorDimension(dimension);
|
|
@@ -636,7 +643,7 @@ async function listMessagesByThreadIdHandler(
|
|
|
636
643
|
const statuses = args.statuses ?? vMessageStatus.members.map((m) => m.value);
|
|
637
644
|
const last =
|
|
638
645
|
args.upToAndIncludingMessageId &&
|
|
639
|
-
(await ctx.db.get(args.upToAndIncludingMessageId));
|
|
646
|
+
(await ctx.db.get("messages", args.upToAndIncludingMessageId));
|
|
640
647
|
assert(
|
|
641
648
|
!last || last.threadId === args.threadId,
|
|
642
649
|
"upToAndIncludingMessageId must be a message in the thread",
|
|
@@ -679,9 +686,9 @@ async function listMessagesByThreadIdHandler(
|
|
|
679
686
|
export const getMessagesByIds = query({
|
|
680
687
|
args: { messageIds: v.array(v.id("messages")) },
|
|
681
688
|
handler: async (ctx, args) => {
|
|
682
|
-
return (
|
|
683
|
-
(
|
|
684
|
-
);
|
|
689
|
+
return (
|
|
690
|
+
await Promise.all(args.messageIds.map((id) => ctx.db.get("messages", id)))
|
|
691
|
+
).map((m) => (m ? publicMessage(m) : null));
|
|
685
692
|
},
|
|
686
693
|
returns: v.array(v.union(v.null(), vMessageDoc)),
|
|
687
694
|
});
|
|
@@ -793,7 +800,8 @@ export const _fetchSearchMessages = internalQuery({
|
|
|
793
800
|
returns: v.array(vMessageDoc),
|
|
794
801
|
handler: async (ctx, args): Promise<MessageDoc[]> => {
|
|
795
802
|
const beforeMessage =
|
|
796
|
-
args.beforeMessageId &&
|
|
803
|
+
args.beforeMessageId &&
|
|
804
|
+
(await ctx.db.get("messages", args.beforeMessageId));
|
|
797
805
|
const { searchAllMessagesForUserId, threadId } = args;
|
|
798
806
|
assert(
|
|
799
807
|
searchAllMessagesForUserId || threadId,
|
|
@@ -809,6 +817,7 @@ export const _fetchSearchMessages = internalQuery({
|
|
|
809
817
|
? q.eq("embeddingId", embeddingId)
|
|
810
818
|
: q.eq("embeddingId", embeddingId).eq("threadId", threadId!),
|
|
811
819
|
)
|
|
820
|
+
// eslint-disable-next-line @convex-dev/no-filter-in-query -- We do not expect many messages with the same embeddingId for different users / threads
|
|
812
821
|
.filter((q) =>
|
|
813
822
|
q.and(
|
|
814
823
|
q.eq(q.field("status"), "success"),
|
|
@@ -911,7 +920,8 @@ export const textSearch = query({
|
|
|
911
920
|
"Specify userId or threadId",
|
|
912
921
|
);
|
|
913
922
|
const targetMessage =
|
|
914
|
-
args.targetMessageId &&
|
|
923
|
+
args.targetMessageId &&
|
|
924
|
+
(await ctx.db.get("messages", args.targetMessageId));
|
|
915
925
|
const order = targetMessage?.order;
|
|
916
926
|
const text = args.text || targetMessage?.text;
|
|
917
927
|
if (!text) {
|
|
@@ -926,6 +936,7 @@ export const textSearch = query({
|
|
|
926
936
|
: q.search("text", text).eq("threadId", args.threadId!),
|
|
927
937
|
)
|
|
928
938
|
// Just in case tool messages slip through
|
|
939
|
+
// eslint-disable-next-line @convex-dev/no-filter-in-query -- we can't do this in the search index, but text search ideally isn't for really old orders
|
|
929
940
|
.filter((q) => {
|
|
930
941
|
const qq = q.eq(q.field("tool"), false);
|
|
931
942
|
if (order) {
|
|
@@ -964,12 +975,13 @@ export const getMessageSearchFields = query({
|
|
|
964
975
|
embedding?: number[] | undefined;
|
|
965
976
|
embeddingModel?: string | undefined;
|
|
966
977
|
}> => {
|
|
967
|
-
const message = await ctx.db.get(args.messageId);
|
|
978
|
+
const message = await ctx.db.get("messages", args.messageId);
|
|
968
979
|
const text = message?.text;
|
|
969
980
|
let embedding = undefined;
|
|
970
981
|
let embeddingModel = undefined;
|
|
971
982
|
if (message?.embeddingId) {
|
|
972
|
-
const
|
|
983
|
+
const { tableName } = getVectorIdInfo(ctx, message.embeddingId);
|
|
984
|
+
const target = await ctx.db.get(tableName, message.embeddingId);
|
|
973
985
|
embedding = target?.vector;
|
|
974
986
|
embeddingModel = target?.model;
|
|
975
987
|
}
|
package/src/component/streams.ts
CHANGED
|
@@ -38,7 +38,7 @@ export const addDelta = mutation({
|
|
|
38
38
|
args: deltaValidator,
|
|
39
39
|
returns: v.boolean(),
|
|
40
40
|
handler: async (ctx, args) => {
|
|
41
|
-
const stream = await ctx.db.get(args.streamId);
|
|
41
|
+
const stream = await ctx.db.get("streamingMessages", args.streamId);
|
|
42
42
|
if (!stream) {
|
|
43
43
|
console.warn("Stream not found", args.streamId);
|
|
44
44
|
return false;
|
|
@@ -101,7 +101,9 @@ export const create = mutation({
|
|
|
101
101
|
internal.streams.timeoutStream,
|
|
102
102
|
{ streamId },
|
|
103
103
|
);
|
|
104
|
-
await ctx.db.patch(streamId, {
|
|
104
|
+
await ctx.db.patch("streamingMessages", streamId, {
|
|
105
|
+
state: { ...state, timeoutFnId },
|
|
106
|
+
});
|
|
105
107
|
return streamId;
|
|
106
108
|
},
|
|
107
109
|
});
|
|
@@ -197,7 +199,7 @@ async function abortById(
|
|
|
197
199
|
finalDelta?: WithoutSystemFields<Doc<"streamDeltas">>;
|
|
198
200
|
},
|
|
199
201
|
) {
|
|
200
|
-
const stream = await ctx.db.get(args.streamId);
|
|
202
|
+
const stream = await ctx.db.get("streamingMessages", args.streamId);
|
|
201
203
|
if (!stream) {
|
|
202
204
|
throw new Error(`Stream not found: ${args.streamId}`);
|
|
203
205
|
}
|
|
@@ -208,7 +210,7 @@ async function abortById(
|
|
|
208
210
|
return false;
|
|
209
211
|
}
|
|
210
212
|
await cleanupTimeoutFn(ctx, stream);
|
|
211
|
-
await ctx.db.patch(args.streamId, {
|
|
213
|
+
await ctx.db.patch("streamingMessages", args.streamId, {
|
|
212
214
|
state: { kind: "aborted", reason: args.reason },
|
|
213
215
|
});
|
|
214
216
|
return true;
|
|
@@ -219,7 +221,10 @@ async function cleanupTimeoutFn(
|
|
|
219
221
|
stream: Doc<"streamingMessages">,
|
|
220
222
|
) {
|
|
221
223
|
if (stream.state.kind === "streaming" && stream.state.timeoutFnId) {
|
|
222
|
-
const timeoutFn = await ctx.db.system.get(
|
|
224
|
+
const timeoutFn = await ctx.db.system.get(
|
|
225
|
+
"_scheduled_functions",
|
|
226
|
+
stream.state.timeoutFnId,
|
|
227
|
+
);
|
|
223
228
|
if (timeoutFn?.state.kind === "pending") {
|
|
224
229
|
await ctx.scheduler.cancel(stream.state.timeoutFnId);
|
|
225
230
|
}
|
|
@@ -246,7 +251,7 @@ export async function finishHandler(
|
|
|
246
251
|
if (args.finalDelta) {
|
|
247
252
|
await ctx.db.insert("streamDeltas", args.finalDelta);
|
|
248
253
|
}
|
|
249
|
-
const stream = await ctx.db.get(args.streamId);
|
|
254
|
+
const stream = await ctx.db.get("streamingMessages", args.streamId);
|
|
250
255
|
if (!stream) {
|
|
251
256
|
throw new Error(`Stream not found: ${args.streamId}`);
|
|
252
257
|
}
|
|
@@ -262,7 +267,7 @@ export async function finishHandler(
|
|
|
262
267
|
api.streams.deleteStreamAsync,
|
|
263
268
|
{ streamId: args.streamId },
|
|
264
269
|
);
|
|
265
|
-
await ctx.db.patch(args.streamId, {
|
|
270
|
+
await ctx.db.patch("streamingMessages", args.streamId, {
|
|
266
271
|
state: { kind: "finished", endedAt: Date.now(), cleanupFnId },
|
|
267
272
|
});
|
|
268
273
|
}
|
|
@@ -279,7 +284,7 @@ async function heartbeatStream(
|
|
|
279
284
|
ctx: MutationCtx,
|
|
280
285
|
args: { streamId: Id<"streamingMessages"> },
|
|
281
286
|
): Promise<void> {
|
|
282
|
-
const stream = await ctx.db.get(args.streamId);
|
|
287
|
+
const stream = await ctx.db.get("streamingMessages", args.streamId);
|
|
283
288
|
if (!stream) {
|
|
284
289
|
console.warn("Stream not found", args.streamId);
|
|
285
290
|
return;
|
|
@@ -294,7 +299,10 @@ async function heartbeatStream(
|
|
|
294
299
|
if (!stream.state.timeoutFnId) {
|
|
295
300
|
throw new Error("Stream has no timeout function");
|
|
296
301
|
}
|
|
297
|
-
const timeoutFn = await ctx.db.system.get(
|
|
302
|
+
const timeoutFn = await ctx.db.system.get(
|
|
303
|
+
"_scheduled_functions",
|
|
304
|
+
stream.state.timeoutFnId,
|
|
305
|
+
);
|
|
298
306
|
if (!timeoutFn) {
|
|
299
307
|
throw new Error("Timeout function not found");
|
|
300
308
|
}
|
|
@@ -307,7 +315,7 @@ async function heartbeatStream(
|
|
|
307
315
|
internal.streams.timeoutStream,
|
|
308
316
|
{ streamId: args.streamId },
|
|
309
317
|
);
|
|
310
|
-
await ctx.db.patch(args.streamId, {
|
|
318
|
+
await ctx.db.patch("streamingMessages", args.streamId, {
|
|
311
319
|
state: { kind: "streaming", lastHeartbeat: Date.now(), timeoutFnId },
|
|
312
320
|
});
|
|
313
321
|
}
|
|
@@ -316,12 +324,12 @@ export const timeoutStream = internalMutation({
|
|
|
316
324
|
args: { streamId: v.id("streamingMessages") },
|
|
317
325
|
returns: v.null(),
|
|
318
326
|
handler: async (ctx, args) => {
|
|
319
|
-
const stream = await ctx.db.get(args.streamId);
|
|
327
|
+
const stream = await ctx.db.get("streamingMessages", args.streamId);
|
|
320
328
|
if (!stream || stream.state.kind !== "streaming") {
|
|
321
329
|
console.warn("Stream not found", args.streamId);
|
|
322
330
|
return;
|
|
323
331
|
}
|
|
324
|
-
await ctx.db.patch(args.streamId, {
|
|
332
|
+
await ctx.db.patch("streamingMessages", args.streamId, {
|
|
325
333
|
state: { kind: "aborted", reason: "timeout" },
|
|
326
334
|
});
|
|
327
335
|
},
|
|
@@ -338,15 +346,23 @@ async function deletePageForStreamId(
|
|
|
338
346
|
numItems: MAX_DELTAS_PER_REQUEST,
|
|
339
347
|
cursor: args.cursor ?? null,
|
|
340
348
|
});
|
|
341
|
-
await Promise.all(
|
|
349
|
+
await Promise.all(
|
|
350
|
+
deltas.page.map((d) => ctx.db.delete("streamDeltas", d._id)),
|
|
351
|
+
);
|
|
342
352
|
if (deltas.isDone) {
|
|
343
|
-
const stream = await ctx.db.get(args.streamId);
|
|
353
|
+
const stream = await ctx.db.get("streamingMessages", args.streamId);
|
|
344
354
|
if (stream) {
|
|
345
355
|
await cleanupTimeoutFn(ctx, stream);
|
|
346
356
|
if (stream.state.kind === "finished" && stream.state.cleanupFnId) {
|
|
347
|
-
await ctx.
|
|
357
|
+
const scheduledFunction = await ctx.db.system.get(
|
|
358
|
+
"_scheduled_functions",
|
|
359
|
+
stream.state.cleanupFnId,
|
|
360
|
+
);
|
|
361
|
+
if (scheduledFunction?.state.kind === "pending") {
|
|
362
|
+
await ctx.scheduler.cancel(stream.state.cleanupFnId);
|
|
363
|
+
}
|
|
348
364
|
}
|
|
349
|
-
await ctx.db.delete(args.streamId);
|
|
365
|
+
await ctx.db.delete("streamingMessages", args.streamId);
|
|
350
366
|
}
|
|
351
367
|
}
|
|
352
368
|
return deltas;
|
|
@@ -434,7 +450,7 @@ export const deleteAllStreamsForThreadIdAsync = mutation({
|
|
|
434
450
|
},
|
|
435
451
|
);
|
|
436
452
|
} else {
|
|
437
|
-
await ctx.db.delete(args.threadId);
|
|
453
|
+
await ctx.db.delete("threads", args.threadId);
|
|
438
454
|
}
|
|
439
455
|
return result;
|
|
440
456
|
},
|
package/src/component/threads.ts
CHANGED
|
@@ -32,7 +32,7 @@ function publicThread(thread: Doc<"threads">): ThreadDoc {
|
|
|
32
32
|
export const getThread = query({
|
|
33
33
|
args: { threadId: v.id("threads") },
|
|
34
34
|
handler: async (ctx, args) => {
|
|
35
|
-
return publicThreadOrNull(await ctx.db.get(args.threadId));
|
|
35
|
+
return publicThreadOrNull(await ctx.db.get("threads", args.threadId));
|
|
36
36
|
},
|
|
37
37
|
returns: v.union(vThreadDoc, v.null()),
|
|
38
38
|
});
|
|
@@ -66,7 +66,7 @@ export const createThread = mutation({
|
|
|
66
66
|
...args,
|
|
67
67
|
status: "active",
|
|
68
68
|
});
|
|
69
|
-
return publicThread((await ctx.db.get(threadId))!);
|
|
69
|
+
return publicThread((await ctx.db.get("threads", threadId))!);
|
|
70
70
|
},
|
|
71
71
|
returns: vThreadDoc,
|
|
72
72
|
});
|
|
@@ -84,10 +84,10 @@ export const updateThread = mutation({
|
|
|
84
84
|
patch: v.object(partial(pick(vThread.fields, threadFieldsSupportingPatch))),
|
|
85
85
|
},
|
|
86
86
|
handler: async (ctx, args) => {
|
|
87
|
-
const thread = await ctx.db.get(args.threadId);
|
|
87
|
+
const thread = await ctx.db.get("threads", args.threadId);
|
|
88
88
|
assert(thread, `Thread ${args.threadId} not found`);
|
|
89
|
-
await ctx.db.patch(args.threadId, args.patch);
|
|
90
|
-
return publicThread((await ctx.db.get(args.threadId))!);
|
|
89
|
+
await ctx.db.patch("threads", args.threadId, args.patch);
|
|
90
|
+
return publicThread((await ctx.db.get("threads", args.threadId))!);
|
|
91
91
|
},
|
|
92
92
|
returns: vThreadDoc,
|
|
93
93
|
});
|
|
@@ -231,9 +231,9 @@ async function deletePageForThreadIdHandler(
|
|
|
231
231
|
});
|
|
232
232
|
await Promise.all(messages.page.map((m) => deleteMessage(ctx, m)));
|
|
233
233
|
if (messages.isDone) {
|
|
234
|
-
const thread = await ctx.db.get(args.threadId);
|
|
234
|
+
const thread = await ctx.db.get("threads", args.threadId);
|
|
235
235
|
if (thread) {
|
|
236
|
-
await ctx.db.delete(args.threadId);
|
|
236
|
+
await ctx.db.delete("threads", args.threadId);
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
return {
|
package/src/component/users.ts
CHANGED
|
@@ -227,7 +227,7 @@ async function deletePageForUserId(
|
|
|
227
227
|
|
|
228
228
|
if (streamResult.isDone) {
|
|
229
229
|
// Streams are done, delete the thread and reset for next thread
|
|
230
|
-
await ctx.db.delete(threadInProgress);
|
|
230
|
+
await ctx.db.delete("threads", threadInProgress);
|
|
231
231
|
threadInProgress = null;
|
|
232
232
|
messagesCursor = null;
|
|
233
233
|
streamsInProgress = false;
|
|
@@ -256,7 +256,7 @@ export const getThreadUserId = internalQuery({
|
|
|
256
256
|
},
|
|
257
257
|
returns: v.union(v.string(), v.null()),
|
|
258
258
|
handler: async (ctx, args) => {
|
|
259
|
-
const thread = await ctx.db.get(args.threadId);
|
|
259
|
+
const thread = await ctx.db.get("threads", args.threadId);
|
|
260
260
|
return thread?.userId ?? null;
|
|
261
261
|
},
|
|
262
262
|
});
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import schema from "../schema.js";
|
|
12
12
|
import {
|
|
13
13
|
type EmbeddingsWithoutDenormalizedFields,
|
|
14
|
+
getVectorIdInfo,
|
|
14
15
|
getVectorTableName,
|
|
15
16
|
type VectorDimension,
|
|
16
17
|
vEmbeddingsWithoutDenormalizedFields,
|
|
@@ -84,7 +85,7 @@ export const deleteBatchForThread = mutation({
|
|
|
84
85
|
numItems: args.limit,
|
|
85
86
|
maximumRowsRead: 300,
|
|
86
87
|
});
|
|
87
|
-
await Promise.all(vectors.page.map((v) => ctx.db.delete(v._id)));
|
|
88
|
+
await Promise.all(vectors.page.map((v) => ctx.db.delete(tableName, v._id)));
|
|
88
89
|
return {
|
|
89
90
|
isDone: vectors.isDone,
|
|
90
91
|
continueCursor: vectors.continueCursor,
|
|
@@ -108,7 +109,7 @@ export const insertBatch = mutation({
|
|
|
108
109
|
args.vectors.map(async ({ messageId, ...v }) => {
|
|
109
110
|
const embeddingId = await insertVector(ctx, args.vectorDimension, v);
|
|
110
111
|
if (messageId) {
|
|
111
|
-
await ctx.db.patch(messageId, { embeddingId });
|
|
112
|
+
await ctx.db.patch("messages", messageId, { embeddingId });
|
|
112
113
|
}
|
|
113
114
|
return embeddingId;
|
|
114
115
|
}),
|
|
@@ -180,12 +181,13 @@ export const updateBatch = mutation({
|
|
|
180
181
|
returns: v.null(),
|
|
181
182
|
handler: async (ctx, args) => {
|
|
182
183
|
await Promise.all(
|
|
183
|
-
args.vectors.map((embedding) =>
|
|
184
|
-
ctx
|
|
184
|
+
args.vectors.map((embedding) => {
|
|
185
|
+
const { tableName } = getVectorIdInfo(ctx, embedding.id);
|
|
186
|
+
return ctx.db.patch(tableName, embedding.id, {
|
|
185
187
|
model: embedding.model,
|
|
186
188
|
vector: embedding.vector,
|
|
187
|
-
})
|
|
188
|
-
),
|
|
189
|
+
});
|
|
190
|
+
}),
|
|
189
191
|
);
|
|
190
192
|
},
|
|
191
193
|
});
|
|
@@ -196,6 +198,11 @@ export const deleteBatch = mutation({
|
|
|
196
198
|
},
|
|
197
199
|
returns: v.null(),
|
|
198
200
|
handler: async (ctx, args) => {
|
|
199
|
-
await Promise.all(
|
|
201
|
+
await Promise.all(
|
|
202
|
+
args.ids.map((id) => {
|
|
203
|
+
const { tableName } = getVectorIdInfo(ctx, id);
|
|
204
|
+
return ctx.db.delete(tableName, id);
|
|
205
|
+
}),
|
|
206
|
+
);
|
|
200
207
|
},
|
|
201
208
|
});
|