@convex-dev/agent 0.1.16-alpha.1 → 0.1.16-alpha.3
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/README.md +26 -15
- package/dist/client/createTool.d.ts +2 -2
- package/dist/client/createTool.d.ts.map +1 -1
- package/dist/client/createTool.js.map +1 -1
- package/dist/client/files.js +2 -2
- package/dist/client/files.js.map +1 -1
- package/dist/client/index.d.ts +12 -11
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +58 -36
- package/dist/client/index.js.map +1 -1
- package/dist/client/search.d.ts +2 -3
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +2 -1
- package/dist/client/search.js.map +1 -1
- package/dist/client/types.d.ts +7 -9
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/messages.d.ts +1 -1
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +5 -5
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +3 -1
- package/dist/mapping.js.map +1 -1
- package/dist/validators.js +1 -2
- package/dist/validators.js.map +1 -1
- package/package.json +1 -1
- package/src/client/createTool.ts +9 -6
- package/src/client/files.ts +8 -8
- package/src/client/index.test.ts +14 -12
- package/src/client/index.ts +156 -116
- package/src/client/listMessages.ts +1 -1
- package/src/client/search.ts +14 -14
- package/src/client/streaming.ts +7 -7
- package/src/client/types.ts +29 -23
- package/src/component/apiKeys.ts +1 -1
- package/src/component/files.test.ts +1 -1
- package/src/component/files.ts +6 -6
- package/src/component/messages.test.ts +6 -6
- package/src/component/messages.ts +44 -43
- package/src/component/schema.ts +1 -2
- package/src/component/streams.ts +27 -27
- package/src/component/threads.test.ts +4 -4
- package/src/component/threads.ts +4 -4
- package/src/component/users.test.ts +2 -2
- package/src/component/users.ts +4 -4
- package/src/component/vector/index.ts +11 -11
- package/src/component/vector/tables.ts +6 -6
- package/src/mapping.test.ts +4 -4
- package/src/mapping.ts +18 -17
- package/src/react/deltas.test.ts +16 -16
- package/src/react/deltas.ts +13 -13
- package/src/react/index.ts +11 -11
- package/src/react/optimisticallySendMessage.ts +2 -2
- package/src/react/toUIMessages.test.ts +10 -10
- package/src/react/toUIMessages.ts +6 -6
- package/src/react/useSmoothText.ts +6 -6
- package/src/validators.ts +24 -24
|
@@ -46,7 +46,7 @@ function publicMessage(message: Doc<"messages">): MessageDoc {
|
|
|
46
46
|
|
|
47
47
|
export async function deleteMessage(
|
|
48
48
|
ctx: MutationCtx,
|
|
49
|
-
messageDoc: Doc<"messages"
|
|
49
|
+
messageDoc: Doc<"messages">,
|
|
50
50
|
) {
|
|
51
51
|
await ctx.db.delete(messageDoc._id);
|
|
52
52
|
if (messageDoc.embeddingId) {
|
|
@@ -71,14 +71,14 @@ export const deleteByIds = mutation({
|
|
|
71
71
|
return id;
|
|
72
72
|
}
|
|
73
73
|
return null;
|
|
74
|
-
})
|
|
74
|
+
}),
|
|
75
75
|
);
|
|
76
76
|
return deletedMessageIds.filter((id) => id !== null);
|
|
77
77
|
},
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
export const messageStatuses = vMessageDoc.fields.status.members.map(
|
|
81
|
-
(m) => m.value
|
|
81
|
+
(m) => m.value,
|
|
82
82
|
);
|
|
83
83
|
|
|
84
84
|
export const deleteByOrder = mutation({
|
|
@@ -99,7 +99,7 @@ export const deleteByOrder = mutation({
|
|
|
99
99
|
ctx,
|
|
100
100
|
args.threadId,
|
|
101
101
|
"asc",
|
|
102
|
-
args.startOrder
|
|
102
|
+
args.startOrder,
|
|
103
103
|
)
|
|
104
104
|
.narrow({
|
|
105
105
|
lowerBound: args.startStepOrder
|
|
@@ -140,7 +140,7 @@ export const addMessages = mutation({
|
|
|
140
140
|
});
|
|
141
141
|
async function addMessagesHandler(
|
|
142
142
|
ctx: MutationCtx,
|
|
143
|
-
args: ObjectType<typeof addMessagesArgs
|
|
143
|
+
args: ObjectType<typeof addMessagesArgs>,
|
|
144
144
|
) {
|
|
145
145
|
let userId = args.userId;
|
|
146
146
|
const threadId = args.threadId;
|
|
@@ -163,15 +163,15 @@ async function addMessagesHandler(
|
|
|
163
163
|
const pendingMessages = await ctx.db
|
|
164
164
|
.query("messages")
|
|
165
165
|
.withIndex("threadId_status_tool_order_stepOrder", (q) =>
|
|
166
|
-
q.eq("threadId", threadId).eq("status", "pending")
|
|
166
|
+
q.eq("threadId", threadId).eq("status", "pending"),
|
|
167
167
|
)
|
|
168
168
|
.collect();
|
|
169
169
|
await Promise.all(
|
|
170
170
|
pendingMessages
|
|
171
171
|
.filter((m) => !parentMessage || m.order === parentMessage.order)
|
|
172
172
|
.map((m) =>
|
|
173
|
-
ctx.db.patch(m._id, { status: "failed", error: "Restarting" })
|
|
174
|
-
)
|
|
173
|
+
ctx.db.patch(m._id, { status: "failed", error: "Restarting" }),
|
|
174
|
+
),
|
|
175
175
|
);
|
|
176
176
|
}
|
|
177
177
|
let order, stepOrder;
|
|
@@ -194,7 +194,7 @@ async function addMessagesHandler(
|
|
|
194
194
|
if (embeddings) {
|
|
195
195
|
assert(
|
|
196
196
|
embeddings.vectors.length === messages.length,
|
|
197
|
-
"embeddings.vectors.length must match messages.length"
|
|
197
|
+
"embeddings.vectors.length must match messages.length",
|
|
198
198
|
);
|
|
199
199
|
}
|
|
200
200
|
for (let i = 0; i < messages.length; i++) {
|
|
@@ -242,7 +242,7 @@ async function addMessagesHandler(
|
|
|
242
242
|
export async function getMaxMessage(
|
|
243
243
|
ctx: QueryCtx,
|
|
244
244
|
threadId: Id<"threads">,
|
|
245
|
-
order?: number
|
|
245
|
+
order?: number,
|
|
246
246
|
) {
|
|
247
247
|
return orderedMessagesStream(ctx, threadId, "desc", order).first();
|
|
248
248
|
}
|
|
@@ -251,7 +251,7 @@ function orderedMessagesStream(
|
|
|
251
251
|
ctx: QueryCtx,
|
|
252
252
|
threadId: Id<"threads">,
|
|
253
253
|
sortOrder: "asc" | "desc",
|
|
254
|
-
order?: number
|
|
254
|
+
order?: number,
|
|
255
255
|
) {
|
|
256
256
|
return mergedStream(
|
|
257
257
|
[true, false].flatMap((tool) =>
|
|
@@ -268,10 +268,10 @@ function orderedMessagesStream(
|
|
|
268
268
|
}
|
|
269
269
|
return qq;
|
|
270
270
|
})
|
|
271
|
-
.order(sortOrder)
|
|
272
|
-
)
|
|
271
|
+
.order(sortOrder),
|
|
272
|
+
),
|
|
273
273
|
),
|
|
274
|
-
["order", "stepOrder"]
|
|
274
|
+
["order", "stepOrder"],
|
|
275
275
|
);
|
|
276
276
|
}
|
|
277
277
|
|
|
@@ -288,7 +288,7 @@ export const rollbackMessage = mutation({
|
|
|
288
288
|
ctx,
|
|
289
289
|
message.threadId,
|
|
290
290
|
"asc",
|
|
291
|
-
message.order
|
|
291
|
+
message.order,
|
|
292
292
|
).collect();
|
|
293
293
|
for (const m of messages) {
|
|
294
294
|
if (m.status === "pending") {
|
|
@@ -347,7 +347,7 @@ export const updateMessage = mutation({
|
|
|
347
347
|
|
|
348
348
|
async function commitMessageHandler(
|
|
349
349
|
ctx: MutationCtx,
|
|
350
|
-
{ messageId }: { messageId: Id<"messages"> }
|
|
350
|
+
{ messageId }: { messageId: Id<"messages"> },
|
|
351
351
|
) {
|
|
352
352
|
const message = await ctx.db.get(messageId);
|
|
353
353
|
assert(message, `Message ${messageId} not found`);
|
|
@@ -362,10 +362,10 @@ async function commitMessageHandler(
|
|
|
362
362
|
.eq("threadId", message.threadId)
|
|
363
363
|
.eq("status", "pending")
|
|
364
364
|
.eq("tool", tool)
|
|
365
|
-
.eq("order", order)
|
|
366
|
-
)
|
|
365
|
+
.eq("order", order),
|
|
366
|
+
),
|
|
367
367
|
),
|
|
368
|
-
["order", "stepOrder"]
|
|
368
|
+
["order", "stepOrder"],
|
|
369
369
|
).collect();
|
|
370
370
|
for (const message of messages) {
|
|
371
371
|
await ctx.db.patch(message._id, { status: "success" });
|
|
@@ -390,7 +390,7 @@ export const listMessagesByThreadId = query({
|
|
|
390
390
|
(await ctx.db.get(args.upToAndIncludingMessageId));
|
|
391
391
|
assert(
|
|
392
392
|
!last || last.threadId === args.threadId,
|
|
393
|
-
"upToAndIncludingMessageId must be a message in the thread"
|
|
393
|
+
"upToAndIncludingMessageId must be a message in the thread",
|
|
394
394
|
);
|
|
395
395
|
const toolOptions = args.excludeToolMessages ? [false] : [true, false];
|
|
396
396
|
const order = args.order ?? "desc";
|
|
@@ -411,9 +411,10 @@ export const listMessagesByThreadId = query({
|
|
|
411
411
|
.order(order)
|
|
412
412
|
.filterWith(
|
|
413
413
|
// We allow all messages on the same order.
|
|
414
|
-
async (m) =>
|
|
415
|
-
|
|
416
|
-
|
|
414
|
+
async (m) =>
|
|
415
|
+
!last || m.order < last.order || m.order === last.order,
|
|
416
|
+
),
|
|
417
|
+
),
|
|
417
418
|
);
|
|
418
419
|
const messages = await mergedStream(streams, [
|
|
419
420
|
"order",
|
|
@@ -422,7 +423,7 @@ export const listMessagesByThreadId = query({
|
|
|
422
423
|
args.paginationOpts ?? {
|
|
423
424
|
numItems: DEFAULT_RECENT_MESSAGES,
|
|
424
425
|
cursor: null,
|
|
425
|
-
}
|
|
426
|
+
},
|
|
426
427
|
);
|
|
427
428
|
return { ...messages, page: messages.page.map(publicMessage) };
|
|
428
429
|
},
|
|
@@ -450,14 +451,14 @@ export const searchMessages = action({
|
|
|
450
451
|
limit: v.number(),
|
|
451
452
|
vectorScoreThreshold: v.optional(v.number()),
|
|
452
453
|
messageRange: v.optional(
|
|
453
|
-
v.object({ before: v.number(), after: v.number() })
|
|
454
|
+
v.object({ before: v.number(), after: v.number() }),
|
|
454
455
|
),
|
|
455
456
|
},
|
|
456
457
|
returns: v.array(vMessageDoc),
|
|
457
458
|
handler: async (ctx, args): Promise<MessageDoc[]> => {
|
|
458
459
|
assert(
|
|
459
460
|
args.searchAllMessagesForUserId || args.threadId,
|
|
460
|
-
"Specify userId or threadId"
|
|
461
|
+
"Specify userId or threadId",
|
|
461
462
|
);
|
|
462
463
|
const limit = args.limit;
|
|
463
464
|
let textSearchMessages: MessageDoc[] | undefined;
|
|
@@ -496,20 +497,20 @@ export const searchMessages = action({
|
|
|
496
497
|
1 / ((textEmbeddingIds?.indexOf(v._id) ?? Infinity) + k),
|
|
497
498
|
}))
|
|
498
499
|
.sort((a, b) => b.score - a.score);
|
|
499
|
-
const
|
|
500
|
+
const embeddingIds = vectorScores.slice(0, limit).map((v) => v.id);
|
|
500
501
|
const messages: MessageDoc[] = await ctx.runQuery(
|
|
501
502
|
internal.messages._fetchSearchMessages,
|
|
502
503
|
{
|
|
503
504
|
searchAllMessagesForUserId: args.searchAllMessagesForUserId,
|
|
504
505
|
threadId: args.threadId,
|
|
505
|
-
|
|
506
|
+
embeddingIds,
|
|
506
507
|
textSearchMessages: textSearchMessages?.filter(
|
|
507
|
-
(m) => !
|
|
508
|
+
(m) => !embeddingIds.includes(m.embeddingId! as VectorTableId),
|
|
508
509
|
),
|
|
509
510
|
messageRange: args.messageRange ?? DEFAULT_MESSAGE_RANGE,
|
|
510
511
|
beforeMessageId: args.beforeMessageId,
|
|
511
512
|
limit,
|
|
512
|
-
}
|
|
513
|
+
},
|
|
513
514
|
);
|
|
514
515
|
return messages;
|
|
515
516
|
}
|
|
@@ -520,7 +521,7 @@ export const searchMessages = action({
|
|
|
520
521
|
export const _fetchSearchMessages = internalQuery({
|
|
521
522
|
args: {
|
|
522
523
|
threadId: v.optional(v.id("threads")),
|
|
523
|
-
|
|
524
|
+
embeddingIds: v.array(vVectorId),
|
|
524
525
|
searchAllMessagesForUserId: v.optional(v.string()),
|
|
525
526
|
textSearchMessages: v.optional(v.array(vMessageDoc)),
|
|
526
527
|
messageRange: v.object({ before: v.number(), after: v.number() }),
|
|
@@ -534,28 +535,28 @@ export const _fetchSearchMessages = internalQuery({
|
|
|
534
535
|
const { searchAllMessagesForUserId, threadId } = args;
|
|
535
536
|
assert(
|
|
536
537
|
searchAllMessagesForUserId || threadId,
|
|
537
|
-
"Specify searchAllMessagesForUserId or threadId to search"
|
|
538
|
+
"Specify searchAllMessagesForUserId or threadId to search",
|
|
538
539
|
);
|
|
539
540
|
let messages: MessageDoc[] = (
|
|
540
541
|
await Promise.all(
|
|
541
|
-
args.
|
|
542
|
+
args.embeddingIds.map((embeddingId) =>
|
|
542
543
|
ctx.db
|
|
543
544
|
.query("messages")
|
|
544
545
|
.withIndex("embeddingId_threadId", (q) =>
|
|
545
546
|
searchAllMessagesForUserId
|
|
546
547
|
? q.eq("embeddingId", embeddingId)
|
|
547
|
-
: q.eq("embeddingId", embeddingId).eq("threadId", threadId!)
|
|
548
|
+
: q.eq("embeddingId", embeddingId).eq("threadId", threadId!),
|
|
548
549
|
)
|
|
549
550
|
.filter((q) =>
|
|
550
551
|
q.and(
|
|
551
552
|
q.eq(q.field("status"), "success"),
|
|
552
553
|
searchAllMessagesForUserId
|
|
553
554
|
? q.eq(q.field("userId"), searchAllMessagesForUserId)
|
|
554
|
-
: q.eq(q.field("threadId"), threadId)
|
|
555
|
-
)
|
|
555
|
+
: q.eq(q.field("threadId"), threadId),
|
|
556
|
+
),
|
|
556
557
|
)
|
|
557
|
-
.first()
|
|
558
|
-
)
|
|
558
|
+
.first(),
|
|
559
|
+
),
|
|
559
560
|
)
|
|
560
561
|
)
|
|
561
562
|
.filter(
|
|
@@ -566,7 +567,7 @@ export const _fetchSearchMessages = internalQuery({
|
|
|
566
567
|
(!beforeMessage ||
|
|
567
568
|
m.order < beforeMessage.order ||
|
|
568
569
|
(m.order === beforeMessage.order &&
|
|
569
|
-
m.stepOrder < beforeMessage.stepOrder))
|
|
570
|
+
m.stepOrder < beforeMessage.stepOrder)),
|
|
570
571
|
)
|
|
571
572
|
.map(publicMessage);
|
|
572
573
|
messages.push(...(args.textSearchMessages ?? []));
|
|
@@ -614,7 +615,7 @@ export const _fetchSearchMessages = internalQuery({
|
|
|
614
615
|
.eq("status", "success")
|
|
615
616
|
.eq("tool", false)
|
|
616
617
|
.gte("order", earliest)
|
|
617
|
-
.lte("order", latest)
|
|
618
|
+
.lte("order", latest),
|
|
618
619
|
)
|
|
619
620
|
.collect();
|
|
620
621
|
if (!ranges[searchId]) {
|
|
@@ -645,7 +646,7 @@ export const textSearch = query({
|
|
|
645
646
|
handler: async (ctx, args) => {
|
|
646
647
|
assert(
|
|
647
648
|
args.searchAllMessagesForUserId || args.threadId,
|
|
648
|
-
"Specify userId or threadId"
|
|
649
|
+
"Specify userId or threadId",
|
|
649
650
|
);
|
|
650
651
|
const beforeMessage =
|
|
651
652
|
args.beforeMessageId && (await ctx.db.get(args.beforeMessageId));
|
|
@@ -657,7 +658,7 @@ export const textSearch = query({
|
|
|
657
658
|
? q
|
|
658
659
|
.search("text", args.text)
|
|
659
660
|
.eq("userId", args.searchAllMessagesForUserId)
|
|
660
|
-
: q.search("text", args.text).eq("threadId", args.threadId!)
|
|
661
|
+
: q.search("text", args.text).eq("threadId", args.threadId!),
|
|
661
662
|
)
|
|
662
663
|
// Just in case tool messages slip through
|
|
663
664
|
.filter((q) => {
|
|
@@ -674,7 +675,7 @@ export const textSearch = query({
|
|
|
674
675
|
!beforeMessage ||
|
|
675
676
|
m.order < beforeMessage.order ||
|
|
676
677
|
(m.order === beforeMessage.order &&
|
|
677
|
-
m.stepOrder < beforeMessage.stepOrder)
|
|
678
|
+
m.stepOrder < beforeMessage.stepOrder),
|
|
678
679
|
)
|
|
679
680
|
.map(publicMessage);
|
|
680
681
|
},
|
package/src/component/schema.ts
CHANGED
|
@@ -118,7 +118,7 @@ export const schema = defineSchema({
|
|
|
118
118
|
v.object({
|
|
119
119
|
kind: v.literal("aborted"),
|
|
120
120
|
reason: v.string(),
|
|
121
|
-
})
|
|
121
|
+
}),
|
|
122
122
|
),
|
|
123
123
|
})
|
|
124
124
|
// There should only be one per "order" index
|
|
@@ -197,5 +197,4 @@ export const vMessageDoc = v.object({
|
|
|
197
197
|
});
|
|
198
198
|
export type MessageDoc = Infer<typeof vMessageDoc>;
|
|
199
199
|
|
|
200
|
-
|
|
201
200
|
export default schema;
|
package/src/component/streams.ts
CHANGED
|
@@ -51,7 +51,7 @@ export const listDeltas = query({
|
|
|
51
51
|
v.object({
|
|
52
52
|
streamId: v.id("streamingMessages"),
|
|
53
53
|
cursor: v.number(),
|
|
54
|
-
})
|
|
54
|
+
}),
|
|
55
55
|
),
|
|
56
56
|
},
|
|
57
57
|
returns: v.array(vStreamDelta),
|
|
@@ -62,16 +62,16 @@ export const listDeltas = query({
|
|
|
62
62
|
const streamDeltas = await ctx.db
|
|
63
63
|
.query("streamDeltas")
|
|
64
64
|
.withIndex("streamId_start_end", (q) =>
|
|
65
|
-
q.eq("streamId", cursor.streamId).gte("start", cursor.cursor)
|
|
65
|
+
q.eq("streamId", cursor.streamId).gte("start", cursor.cursor),
|
|
66
66
|
)
|
|
67
67
|
.take(
|
|
68
|
-
Math.min(MAX_DELTAS_PER_STREAM, MAX_DELTAS_PER_REQUEST - totalDeltas)
|
|
68
|
+
Math.min(MAX_DELTAS_PER_STREAM, MAX_DELTAS_PER_REQUEST - totalDeltas),
|
|
69
69
|
);
|
|
70
70
|
totalDeltas += streamDeltas.length;
|
|
71
71
|
deltas.push(
|
|
72
72
|
...streamDeltas.map((d) =>
|
|
73
|
-
pick(d, ["streamId", "start", "end", "parts"])
|
|
74
|
-
)
|
|
73
|
+
pick(d, ["streamId", "start", "end", "parts"]),
|
|
74
|
+
),
|
|
75
75
|
);
|
|
76
76
|
if (totalDeltas >= MAX_DELTAS_PER_REQUEST) {
|
|
77
77
|
break;
|
|
@@ -96,7 +96,7 @@ export const create = mutation({
|
|
|
96
96
|
const timeoutFnId = await ctx.scheduler.runAfter(
|
|
97
97
|
TIMEOUT_INTERVAL,
|
|
98
98
|
internal.streams.timeoutStream,
|
|
99
|
-
{ streamId }
|
|
99
|
+
{ streamId },
|
|
100
100
|
);
|
|
101
101
|
await ctx.db.patch(streamId, { state: { ...state, timeoutFnId } });
|
|
102
102
|
return streamId;
|
|
@@ -112,9 +112,9 @@ export const list = query({
|
|
|
112
112
|
v.union(
|
|
113
113
|
v.literal("streaming"),
|
|
114
114
|
v.literal("finished"),
|
|
115
|
-
v.literal("aborted")
|
|
116
|
-
)
|
|
117
|
-
)
|
|
115
|
+
v.literal("aborted"),
|
|
116
|
+
),
|
|
117
|
+
),
|
|
118
118
|
),
|
|
119
119
|
},
|
|
120
120
|
returns: v.array(vStreamMessage),
|
|
@@ -128,11 +128,11 @@ export const list = query({
|
|
|
128
128
|
q
|
|
129
129
|
.eq("threadId", args.threadId)
|
|
130
130
|
.eq("state.kind", status)
|
|
131
|
-
.gte("order", args.startOrder ?? 0)
|
|
131
|
+
.gte("order", args.startOrder ?? 0),
|
|
132
132
|
)
|
|
133
|
-
.order("desc")
|
|
133
|
+
.order("desc"),
|
|
134
134
|
),
|
|
135
|
-
["order", "stepOrder"]
|
|
135
|
+
["order", "stepOrder"],
|
|
136
136
|
).take(100);
|
|
137
137
|
|
|
138
138
|
return messages.map((m) => ({
|
|
@@ -165,7 +165,7 @@ export const abortByOrder = mutation({
|
|
|
165
165
|
q
|
|
166
166
|
.eq("threadId", args.threadId)
|
|
167
167
|
.eq("state.kind", "streaming")
|
|
168
|
-
.eq("order", args.order)
|
|
168
|
+
.eq("order", args.order),
|
|
169
169
|
)
|
|
170
170
|
.take(100);
|
|
171
171
|
for (const stream of streams) {
|
|
@@ -189,7 +189,7 @@ export const abort = mutation({
|
|
|
189
189
|
|
|
190
190
|
async function abortById(
|
|
191
191
|
ctx: MutationCtx,
|
|
192
|
-
args: { streamId: Id<"streamingMessages">; reason: string }
|
|
192
|
+
args: { streamId: Id<"streamingMessages">; reason: string },
|
|
193
193
|
) {
|
|
194
194
|
const stream = await ctx.db.get(args.streamId);
|
|
195
195
|
if (!stream) {
|
|
@@ -197,7 +197,7 @@ async function abortById(
|
|
|
197
197
|
}
|
|
198
198
|
if (stream.state.kind !== "streaming") {
|
|
199
199
|
console.warn(
|
|
200
|
-
`Stream trying to abort but not currently streaming (${stream.state.kind}): ${args.streamId}
|
|
200
|
+
`Stream trying to abort but not currently streaming (${stream.state.kind}): ${args.streamId}`,
|
|
201
201
|
);
|
|
202
202
|
return false;
|
|
203
203
|
}
|
|
@@ -210,7 +210,7 @@ async function abortById(
|
|
|
210
210
|
|
|
211
211
|
async function cleanupTimeoutFn(
|
|
212
212
|
ctx: MutationCtx,
|
|
213
|
-
stream: Doc<"streamingMessages"
|
|
213
|
+
stream: Doc<"streamingMessages">,
|
|
214
214
|
) {
|
|
215
215
|
if (stream.state.kind === "streaming" && stream.state.timeoutFnId) {
|
|
216
216
|
const timeoutFn = await ctx.db.system.get(stream.state.timeoutFnId);
|
|
@@ -236,7 +236,7 @@ export const finish = mutation({
|
|
|
236
236
|
}
|
|
237
237
|
if (stream.state.kind !== "streaming") {
|
|
238
238
|
console.warn(
|
|
239
|
-
`Stream trying to finish but not currently streaming: ${args.streamId}
|
|
239
|
+
`Stream trying to finish but not currently streaming: ${args.streamId}`,
|
|
240
240
|
);
|
|
241
241
|
return;
|
|
242
242
|
}
|
|
@@ -244,7 +244,7 @@ export const finish = mutation({
|
|
|
244
244
|
const cleanupFnId = await ctx.scheduler.runAfter(
|
|
245
245
|
DELETE_STREAM_DELAY,
|
|
246
246
|
api.streams.deleteStreamAsync,
|
|
247
|
-
{ streamId: args.streamId }
|
|
247
|
+
{ streamId: args.streamId },
|
|
248
248
|
);
|
|
249
249
|
await ctx.db.patch(args.streamId, {
|
|
250
250
|
state: { kind: "finished", endedAt: Date.now(), cleanupFnId },
|
|
@@ -254,7 +254,7 @@ export const finish = mutation({
|
|
|
254
254
|
|
|
255
255
|
async function heartbeatStream(
|
|
256
256
|
ctx: MutationCtx,
|
|
257
|
-
args: { streamId: Id<"streamingMessages"> }
|
|
257
|
+
args: { streamId: Id<"streamingMessages"> },
|
|
258
258
|
) {
|
|
259
259
|
const stream = await ctx.db.get(args.streamId);
|
|
260
260
|
if (!stream) {
|
|
@@ -283,7 +283,7 @@ async function heartbeatStream(
|
|
|
283
283
|
const timeoutFnId = await ctx.scheduler.runAfter(
|
|
284
284
|
TIMEOUT_INTERVAL,
|
|
285
285
|
internal.streams.timeoutStream,
|
|
286
|
-
{ streamId: args.streamId }
|
|
286
|
+
{ streamId: args.streamId },
|
|
287
287
|
);
|
|
288
288
|
await ctx.db.patch(args.streamId, {
|
|
289
289
|
state: {
|
|
@@ -314,7 +314,7 @@ export const timeoutStream = internalMutation({
|
|
|
314
314
|
|
|
315
315
|
async function deletePageForStreamId(
|
|
316
316
|
ctx: MutationCtx,
|
|
317
|
-
args: { streamId: Id<"streamingMessages">; cursor?: string }
|
|
317
|
+
args: { streamId: Id<"streamingMessages">; cursor?: string },
|
|
318
318
|
) {
|
|
319
319
|
const deltas = await paginator(ctx.db, schema)
|
|
320
320
|
.query("streamDeltas")
|
|
@@ -339,7 +339,7 @@ async function deletePageForStreamId(
|
|
|
339
339
|
|
|
340
340
|
export async function deleteStreamsPageForThreadId(
|
|
341
341
|
ctx: MutationCtx,
|
|
342
|
-
args: { threadId: Id<"threads">; streamOrder?: number; deltaCursor?: string }
|
|
342
|
+
args: { threadId: Id<"threads">; streamOrder?: number; deltaCursor?: string },
|
|
343
343
|
) {
|
|
344
344
|
const allStreamMessages =
|
|
345
345
|
schema.tables.streamingMessages.validator.fields.state.members
|
|
@@ -351,8 +351,8 @@ export async function deleteStreamsPageForThreadId(
|
|
|
351
351
|
q
|
|
352
352
|
.eq("threadId", args.threadId)
|
|
353
353
|
.eq("state.kind", stateKind)
|
|
354
|
-
.gte("order", args.streamOrder ?? 0)
|
|
355
|
-
)
|
|
354
|
+
.gte("order", args.streamOrder ?? 0),
|
|
355
|
+
),
|
|
356
356
|
);
|
|
357
357
|
let deltaCursor = args.deltaCursor;
|
|
358
358
|
const streamMessage = await mergedStream(allStreamMessages, [
|
|
@@ -417,7 +417,7 @@ export const deleteAllStreamsForThreadIdAsync = mutation({
|
|
|
417
417
|
threadId: args.threadId,
|
|
418
418
|
streamOrder: result.streamOrder,
|
|
419
419
|
deltaCursor: result.deltaCursor,
|
|
420
|
-
}
|
|
420
|
+
},
|
|
421
421
|
);
|
|
422
422
|
} else {
|
|
423
423
|
await ctx.db.delete(args.threadId);
|
|
@@ -460,7 +460,7 @@ export const deleteAllStreamsForThreadIdSync = action({
|
|
|
460
460
|
handler: async (ctx, args) => {
|
|
461
461
|
let result = await ctx.runMutation(
|
|
462
462
|
internal.streams.deleteStreamsPageForThreadIdMutation,
|
|
463
|
-
args
|
|
463
|
+
args,
|
|
464
464
|
);
|
|
465
465
|
while (!result.isDone) {
|
|
466
466
|
result = await ctx.runMutation(
|
|
@@ -469,7 +469,7 @@ export const deleteAllStreamsForThreadIdSync = action({
|
|
|
469
469
|
...args,
|
|
470
470
|
streamOrder: result.streamOrder,
|
|
471
471
|
deltaCursor: result.deltaCursor,
|
|
472
|
-
}
|
|
472
|
+
},
|
|
473
473
|
);
|
|
474
474
|
}
|
|
475
475
|
},
|
|
@@ -225,7 +225,7 @@ describe("threads", () => {
|
|
|
225
225
|
t.mutation(api.threads.updateThread, {
|
|
226
226
|
threadId: thread._id as Id<"threads">,
|
|
227
227
|
patch: { title: "New Title" },
|
|
228
|
-
})
|
|
228
|
+
}),
|
|
229
229
|
).rejects.toThrow();
|
|
230
230
|
});
|
|
231
231
|
|
|
@@ -368,7 +368,7 @@ describe("threads", () => {
|
|
|
368
368
|
{
|
|
369
369
|
threadId: thread._id as Id<"threads">,
|
|
370
370
|
cursor: currentResult.cursor,
|
|
371
|
-
}
|
|
371
|
+
},
|
|
372
372
|
);
|
|
373
373
|
iterations++;
|
|
374
374
|
}
|
|
@@ -471,7 +471,7 @@ describe("threads", () => {
|
|
|
471
471
|
await expect(
|
|
472
472
|
t.action(api.threads.deleteAllForThreadIdSync, {
|
|
473
473
|
threadId: thread._id as Id<"threads">,
|
|
474
|
-
})
|
|
474
|
+
}),
|
|
475
475
|
).resolves.not.toThrow();
|
|
476
476
|
|
|
477
477
|
// Thread should be deleted
|
|
@@ -499,7 +499,7 @@ describe("threads", () => {
|
|
|
499
499
|
await expect(
|
|
500
500
|
t.action(api.threads.deleteAllForThreadIdSync, {
|
|
501
501
|
threadId: thread._id as Id<"threads">,
|
|
502
|
-
})
|
|
502
|
+
}),
|
|
503
503
|
).resolves.not.toThrow();
|
|
504
504
|
});
|
|
505
505
|
|
package/src/component/threads.ts
CHANGED
|
@@ -104,7 +104,7 @@ export const searchThreadTitles = query({
|
|
|
104
104
|
.withSearchIndex("title", (q) =>
|
|
105
105
|
args.userId
|
|
106
106
|
? q.search("title", args.query).eq("userId", args.userId ?? undefined)
|
|
107
|
-
: q.search("title", args.query)
|
|
107
|
+
: q.search("title", args.query),
|
|
108
108
|
)
|
|
109
109
|
.take(args.limit);
|
|
110
110
|
return threads.map(publicThread);
|
|
@@ -138,7 +138,7 @@ export const deleteAllForThreadIdSync = action({
|
|
|
138
138
|
while (true) {
|
|
139
139
|
const result: DeleteThreadReturns = await ctx.runMutation(
|
|
140
140
|
internal.threads._deletePageForThreadId,
|
|
141
|
-
{ threadId: args.threadId, cursor, limit: args.limit }
|
|
141
|
+
{ threadId: args.threadId, cursor, limit: args.limit },
|
|
142
142
|
);
|
|
143
143
|
if (result.isDone) {
|
|
144
144
|
break;
|
|
@@ -218,12 +218,12 @@ export const deleteAllForThreadIdAsync = mutation({
|
|
|
218
218
|
|
|
219
219
|
async function deletePageForThreadIdHandler(
|
|
220
220
|
ctx: MutationCtx,
|
|
221
|
-
args: DeleteThreadArgs
|
|
221
|
+
args: DeleteThreadArgs,
|
|
222
222
|
): Promise<DeleteThreadReturns> {
|
|
223
223
|
const messages = await paginator(ctx.db, schema)
|
|
224
224
|
.query("messages")
|
|
225
225
|
.withIndex("threadId_status_tool_order_stepOrder", (q) =>
|
|
226
|
-
q.eq("threadId", args.threadId)
|
|
226
|
+
q.eq("threadId", args.threadId),
|
|
227
227
|
)
|
|
228
228
|
.paginate({
|
|
229
229
|
numItems: args.limit ?? 100,
|
|
@@ -60,7 +60,7 @@ describe("users", () => {
|
|
|
60
60
|
// Should not have duplicate users
|
|
61
61
|
console.log(firstPage.page, secondPage.page);
|
|
62
62
|
expect(
|
|
63
|
-
firstPage.page.every((user) => !secondPage.page.includes(user))
|
|
63
|
+
firstPage.page.every((user) => !secondPage.page.includes(user)),
|
|
64
64
|
).toBe(true);
|
|
65
65
|
});
|
|
66
66
|
|
|
@@ -470,7 +470,7 @@ describe("users", () => {
|
|
|
470
470
|
|
|
471
471
|
// Try to delete for a user that doesn't exist
|
|
472
472
|
await expect(
|
|
473
|
-
t.action(api.users.deleteAllForUserId, { userId: "nonexistentUser" })
|
|
473
|
+
t.action(api.users.deleteAllForUserId, { userId: "nonexistentUser" }),
|
|
474
474
|
).resolves.not.toThrow();
|
|
475
475
|
|
|
476
476
|
// Should complete successfully without errors
|
package/src/component/users.ts
CHANGED
|
@@ -59,7 +59,7 @@ export const deleteAllForUserId = action({
|
|
|
59
59
|
streamsInProgress,
|
|
60
60
|
streamOrder,
|
|
61
61
|
deltaCursor,
|
|
62
|
-
}
|
|
62
|
+
},
|
|
63
63
|
);
|
|
64
64
|
messagesCursor = result.messagesCursor;
|
|
65
65
|
threadInProgress = result.threadInProgress;
|
|
@@ -121,7 +121,7 @@ export const _deleteAllForUserIdAsync = internalMutation({
|
|
|
121
121
|
|
|
122
122
|
async function deleteAllForUserIdAsyncHandler(
|
|
123
123
|
ctx: MutationCtx,
|
|
124
|
-
args: DeleteAllArgs
|
|
124
|
+
args: DeleteAllArgs,
|
|
125
125
|
): Promise<boolean> {
|
|
126
126
|
const result = await deletePageForUserId(ctx, args);
|
|
127
127
|
if (!result.isDone) {
|
|
@@ -145,7 +145,7 @@ export const _deletePageForUserId = internalMutation({
|
|
|
145
145
|
});
|
|
146
146
|
async function deletePageForUserId(
|
|
147
147
|
ctx: MutationCtx,
|
|
148
|
-
args: DeleteAllArgs
|
|
148
|
+
args: DeleteAllArgs,
|
|
149
149
|
): Promise<DeleteAllReturns> {
|
|
150
150
|
let threadInProgress: Id<"threads"> | null = args.threadInProgress;
|
|
151
151
|
let threadsCursor: string | null = args.threadsCursor;
|
|
@@ -189,7 +189,7 @@ async function deletePageForUserId(
|
|
|
189
189
|
const messages = await paginator(ctx.db, schema)
|
|
190
190
|
.query("messages")
|
|
191
191
|
.withIndex("threadId_status_tool_order_stepOrder", (q) =>
|
|
192
|
-
q.eq("threadId", threadInProgress!)
|
|
192
|
+
q.eq("threadId", threadInProgress!),
|
|
193
193
|
)
|
|
194
194
|
.order("desc")
|
|
195
195
|
.paginate({
|