@convex-dev/agent 0.0.1-alpha.2 → 0.0.1-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.
Files changed (60) hide show
  1. package/README.md +91 -95
  2. package/dist/commonjs/client/index.d.ts +60 -60
  3. package/dist/commonjs/client/index.d.ts.map +1 -1
  4. package/dist/commonjs/client/index.js +80 -77
  5. package/dist/commonjs/client/index.js.map +1 -1
  6. package/dist/commonjs/client/types.d.ts +1 -1
  7. package/dist/commonjs/client/types.d.ts.map +1 -1
  8. package/dist/commonjs/component/messages.d.ts +56 -56
  9. package/dist/commonjs/component/messages.d.ts.map +1 -1
  10. package/dist/commonjs/component/messages.js +128 -134
  11. package/dist/commonjs/component/messages.js.map +1 -1
  12. package/dist/commonjs/component/schema.d.ts +256 -256
  13. package/dist/commonjs/component/schema.d.ts.map +1 -1
  14. package/dist/commonjs/component/schema.js +18 -18
  15. package/dist/commonjs/component/schema.js.map +1 -1
  16. package/dist/commonjs/component/vector/index.d.ts +4 -4
  17. package/dist/commonjs/component/vector/index.d.ts.map +1 -1
  18. package/dist/commonjs/component/vector/index.js +12 -10
  19. package/dist/commonjs/component/vector/index.js.map +1 -1
  20. package/dist/commonjs/component/vector/tables.d.ts +3 -3
  21. package/dist/commonjs/component/vector/tables.js +6 -6
  22. package/dist/commonjs/component/vector/tables.js.map +1 -1
  23. package/dist/commonjs/validators.d.ts +5 -5
  24. package/dist/commonjs/validators.d.ts.map +1 -1
  25. package/dist/commonjs/validators.js +3 -3
  26. package/dist/commonjs/validators.js.map +1 -1
  27. package/dist/esm/client/index.d.ts +60 -60
  28. package/dist/esm/client/index.d.ts.map +1 -1
  29. package/dist/esm/client/index.js +80 -77
  30. package/dist/esm/client/index.js.map +1 -1
  31. package/dist/esm/client/types.d.ts +1 -1
  32. package/dist/esm/client/types.d.ts.map +1 -1
  33. package/dist/esm/component/messages.d.ts +56 -56
  34. package/dist/esm/component/messages.d.ts.map +1 -1
  35. package/dist/esm/component/messages.js +128 -134
  36. package/dist/esm/component/messages.js.map +1 -1
  37. package/dist/esm/component/schema.d.ts +256 -256
  38. package/dist/esm/component/schema.d.ts.map +1 -1
  39. package/dist/esm/component/schema.js +18 -18
  40. package/dist/esm/component/schema.js.map +1 -1
  41. package/dist/esm/component/vector/index.d.ts +4 -4
  42. package/dist/esm/component/vector/index.d.ts.map +1 -1
  43. package/dist/esm/component/vector/index.js +12 -10
  44. package/dist/esm/component/vector/index.js.map +1 -1
  45. package/dist/esm/component/vector/tables.d.ts +3 -3
  46. package/dist/esm/component/vector/tables.js +6 -6
  47. package/dist/esm/component/vector/tables.js.map +1 -1
  48. package/dist/esm/validators.d.ts +5 -5
  49. package/dist/esm/validators.d.ts.map +1 -1
  50. package/dist/esm/validators.js +3 -3
  51. package/dist/esm/validators.js.map +1 -1
  52. package/package.json +2 -2
  53. package/src/client/index.ts +133 -127
  54. package/src/client/types.ts +1 -1
  55. package/src/component/_generated/api.d.ts +53 -53
  56. package/src/component/messages.ts +139 -145
  57. package/src/component/schema.ts +18 -18
  58. package/src/component/vector/index.ts +13 -11
  59. package/src/component/vector/tables.ts +6 -6
  60. package/src/validators.ts +6 -3
@@ -5,7 +5,7 @@ import { nullable, partial } from "convex-helpers/validators";
5
5
  import { ObjectType } from "convex/values";
6
6
  import { DEFAULT_MESSAGE_RANGE, extractText, isTool } from "../shared.js";
7
7
  import {
8
- vChatStatus,
8
+ vThreadStatus,
9
9
  vMessageStatus,
10
10
  vMessageWithFileAndId,
11
11
  vSearchOptions,
@@ -30,27 +30,27 @@ import {
30
30
  vVectorId,
31
31
  } from "./vector/tables.js";
32
32
 
33
- export const getChat = query({
34
- args: { chatId: v.id("chats") },
33
+ export const getThread = query({
34
+ args: { threadId: v.id("threads") },
35
35
  handler: async (ctx, args) => {
36
- return ctx.db.get(args.chatId);
36
+ return ctx.db.get(args.threadId);
37
37
  },
38
- returns: v.union(v.doc("chats"), v.null()),
38
+ returns: v.union(v.doc("threads"), v.null()),
39
39
  });
40
40
 
41
- export const getChatsByUserId = query({
41
+ export const getThreadsByUserId = query({
42
42
  args: {
43
43
  userId: v.string(),
44
44
  // Note: the other arguments cannot change from when the cursor was created.
45
45
  cursor: v.optional(v.union(v.string(), v.null())),
46
46
  limit: v.optional(v.number()),
47
47
  offset: v.optional(v.number()),
48
- statuses: v.optional(v.array(vChatStatus)),
48
+ statuses: v.optional(v.array(vThreadStatus)),
49
49
  },
50
50
  handler: async (ctx, args) => {
51
51
  const streams = (args.statuses ?? ["active"]).map((status) =>
52
52
  stream(ctx.db, schema)
53
- .query("chats")
53
+ .query("threads")
54
54
  .withIndex("status_userId_order", (q) =>
55
55
  q
56
56
  .eq("status", status)
@@ -58,55 +58,55 @@ export const getChatsByUserId = query({
58
58
  .gte("order", args.offset ?? 0)
59
59
  )
60
60
  );
61
- const chats = await mergedStream(streams, ["order"]).paginate({
61
+ const threads = await mergedStream(streams, ["order"]).paginate({
62
62
  numItems: args.limit ?? 100,
63
63
  cursor: args.cursor ?? null,
64
64
  });
65
65
  return {
66
- chats: chats.page,
67
- continueCursor: chats.continueCursor,
68
- isDone: chats.isDone,
66
+ threads: threads.page,
67
+ continueCursor: threads.continueCursor,
68
+ isDone: threads.isDone,
69
69
  };
70
70
  },
71
71
  returns: v.object({
72
- chats: v.array(v.doc("chats")),
72
+ threads: v.array(v.doc("threads")),
73
73
  continueCursor: v.string(),
74
74
  isDone: v.boolean(),
75
75
  }),
76
76
  });
77
77
 
78
- const vChat = schema.tables.chats.validator;
79
- const statuses = vChat.fields.status.members.map((m) => m.value);
78
+ const vThread = schema.tables.threads.validator;
79
+ const statuses = vThread.fields.status.members.map((m) => m.value);
80
80
 
81
- export const createChat = mutation({
82
- args: omit(vChat.fields, ["order", "status"]),
81
+ export const createThread = mutation({
82
+ args: omit(vThread.fields, ["order", "status"]),
83
83
  handler: async (ctx, args) => {
84
84
  const streams = statuses.map((status) =>
85
85
  stream(ctx.db, schema)
86
- .query("chats")
86
+ .query("threads")
87
87
  .withIndex("status_userId_order", (q) =>
88
88
  q.eq("status", status).eq("userId", args.userId)
89
89
  )
90
90
  .order("desc")
91
91
  );
92
- const latestChat = await mergedStream(streams, ["order"]).first();
93
- const order = (latestChat?.order ?? -1) + 1;
94
- const chatId = await ctx.db.insert("chats", {
92
+ const latestThread = await mergedStream(streams, ["order"]).first();
93
+ const order = (latestThread?.order ?? -1) + 1;
94
+ const threadId = await ctx.db.insert("threads", {
95
95
  ...args,
96
96
  order,
97
97
  status: "active",
98
98
  });
99
- return (await ctx.db.get(chatId))!;
99
+ return (await ctx.db.get(threadId))!;
100
100
  },
101
- returns: v.doc("chats"),
101
+ returns: v.doc("threads"),
102
102
  });
103
103
 
104
- export const updateChat = mutation({
104
+ export const updateThread = mutation({
105
105
  args: {
106
- chatId: v.id("chats"),
106
+ threadId: v.id("threads"),
107
107
  patch: v.object(
108
108
  partial(
109
- pick(vChat.fields, [
109
+ pick(vThread.fields, [
110
110
  "title",
111
111
  "summary",
112
112
  "defaultSystemPrompt",
@@ -116,43 +116,43 @@ export const updateChat = mutation({
116
116
  ),
117
117
  },
118
118
  handler: async (ctx, args) => {
119
- const chat = await ctx.db.get(args.chatId);
120
- assert(chat, `Chat ${args.chatId} not found`);
121
- await ctx.db.patch(args.chatId, args.patch);
122
- return (await ctx.db.get(args.chatId))!;
119
+ const thread = await ctx.db.get(args.threadId);
120
+ assert(thread, `Thread ${args.threadId} not found`);
121
+ await ctx.db.patch(args.threadId, args.patch);
122
+ return (await ctx.db.get(args.threadId))!;
123
123
  },
124
- returns: v.doc("chats"),
124
+ returns: v.doc("threads"),
125
125
  });
126
126
 
127
- export const archiveChat = mutation({
128
- args: { chatId: v.id("chats") },
127
+ export const archiveThread = mutation({
128
+ args: { threadId: v.id("threads") },
129
129
  handler: async (ctx, args) => {
130
- const chat = await ctx.db.get(args.chatId);
131
- assert(chat, `Chat ${args.chatId} not found`);
132
- await ctx.db.patch(args.chatId, { status: "archived" });
133
- return (await ctx.db.get(args.chatId))!;
130
+ const thread = await ctx.db.get(args.threadId);
131
+ assert(thread, `Thread ${args.threadId} not found`);
132
+ await ctx.db.patch(args.threadId, { status: "archived" });
133
+ return (await ctx.db.get(args.threadId))!;
134
134
  },
135
- returns: v.doc("chats"),
135
+ returns: v.doc("threads"),
136
136
  });
137
137
 
138
138
  export const deleteAllForUserId = action({
139
139
  args: { userId: v.string() },
140
140
  handler: async (ctx, args) => {
141
141
  let messagesCursor = null;
142
- let chatsCursor = null;
142
+ let threadsCursor = null;
143
143
  let isDone = false;
144
144
  while (!isDone) {
145
145
  const result: {
146
146
  messagesCursor: string;
147
- chatsCursor: string | null;
147
+ threadsCursor: string | null;
148
148
  isDone: boolean;
149
149
  } = await ctx.runMutation(internal.messages._deletePageForUserId, {
150
150
  userId: args.userId,
151
151
  messagesCursor,
152
- chatsCursor,
152
+ threadsCursor,
153
153
  });
154
154
  messagesCursor = result.messagesCursor;
155
- chatsCursor = result.chatsCursor;
155
+ threadsCursor = result.threadsCursor;
156
156
  isDone = result.isDone;
157
157
  }
158
158
  },
@@ -167,7 +167,7 @@ export const deleteAllForUserIdAsync = mutation({
167
167
  const isDone = await deleteAllFroUserIdAsyncHandler(ctx, {
168
168
  userId: args.userId,
169
169
  messagesCursor: null,
170
- chatsCursor: null,
170
+ threadsCursor: null,
171
171
  });
172
172
  return isDone;
173
173
  },
@@ -177,12 +177,12 @@ export const deleteAllForUserIdAsync = mutation({
177
177
  const deleteAllArgs = {
178
178
  userId: v.string(),
179
179
  messagesCursor: nullable(v.string()),
180
- chatsCursor: nullable(v.string()),
180
+ threadsCursor: nullable(v.string()),
181
181
  };
182
182
  type DeleteAllArgs = ObjectType<typeof deleteAllArgs>;
183
183
  const deleteAllReturns = {
184
184
  messagesCursor: v.string(),
185
- chatsCursor: nullable(v.string()),
185
+ threadsCursor: nullable(v.string()),
186
186
  isDone: v.boolean(),
187
187
  };
188
188
  type DeleteAllReturns = ObjectType<typeof deleteAllReturns>;
@@ -205,7 +205,7 @@ async function deleteAllFroUserIdAsyncHandler(
205
205
  {
206
206
  userId: args.userId,
207
207
  messagesCursor: result.messagesCursor,
208
- chatsCursor: result.chatsCursor,
208
+ threadsCursor: result.threadsCursor,
209
209
  }
210
210
  );
211
211
  }
@@ -223,20 +223,20 @@ async function deletePageForUserId(
223
223
  ): Promise<DeleteAllReturns> {
224
224
  const streams = statuses.map((status) =>
225
225
  stream(ctx.db, schema)
226
- .query("chats")
226
+ .query("threads")
227
227
  .withIndex("status_userId_order", (q) =>
228
228
  q.eq("status", status).eq("userId", args.userId)
229
229
  )
230
230
  .order("desc")
231
231
  );
232
- const chatStreams = mergedStream(streams, ["order"]);
233
- const messages = await chatStreams
232
+ const threadStreams = mergedStream(streams, ["order"]);
233
+ const messages = await threadStreams
234
234
  .flatMap(
235
235
  async (c) =>
236
236
  stream(ctx.db, schema)
237
237
  .query("messages")
238
- .withIndex("chatId_status_tool_order_stepOrder", (q) =>
239
- q.eq("chatId", c._id).eq("status", "success")
238
+ .withIndex("threadId_status_tool_order_stepOrder", (q) =>
239
+ q.eq("threadId", c._id).eq("status", "success")
240
240
  ),
241
241
  ["tool", "order", "stepOrder"]
242
242
  )
@@ -246,20 +246,20 @@ async function deletePageForUserId(
246
246
  });
247
247
  await Promise.all(messages.page.map((m) => deleteMessage(ctx, m)));
248
248
  if (messages.isDone) {
249
- const chats = await chatStreams.paginate({
249
+ const threads = await threadStreams.paginate({
250
250
  numItems: 100,
251
- cursor: args.chatsCursor ?? null,
251
+ cursor: args.threadsCursor ?? null,
252
252
  });
253
- await Promise.all(chats.page.map((c) => ctx.db.delete(c._id)));
253
+ await Promise.all(threads.page.map((c) => ctx.db.delete(c._id)));
254
254
  return {
255
255
  messagesCursor: messages.continueCursor,
256
- chatsCursor: chats.continueCursor,
257
- isDone: chats.isDone,
256
+ threadsCursor: threads.continueCursor,
257
+ isDone: threads.isDone,
258
258
  };
259
259
  }
260
260
  return {
261
261
  messagesCursor: messages.continueCursor,
262
- chatsCursor: null,
262
+ threadsCursor: null,
263
263
  isDone: messages.isDone,
264
264
  };
265
265
  }
@@ -274,66 +274,66 @@ async function deleteMessage(ctx: MutationCtx, messageDoc: Doc<"messages">) {
274
274
  }
275
275
  }
276
276
 
277
- const deleteChatArgs = {
278
- chatId: v.id("chats"),
277
+ const deleteThreadArgs = {
278
+ threadId: v.id("threads"),
279
279
  cursor: v.optional(v.string()),
280
280
  limit: v.optional(v.number()),
281
281
  };
282
- type DeleteChatArgs = ObjectType<typeof deleteChatArgs>;
283
- const deleteChatReturns = {
282
+ type DeleteThreadArgs = ObjectType<typeof deleteThreadArgs>;
283
+ const deleteThreadReturns = {
284
284
  cursor: v.string(),
285
285
  isDone: v.boolean(),
286
286
  };
287
- type DeleteChatReturns = ObjectType<typeof deleteChatReturns>;
287
+ type DeleteThreadReturns = ObjectType<typeof deleteThreadReturns>;
288
288
 
289
- export const deleteAllForChatIdSync = action({
290
- args: deleteChatArgs,
289
+ export const deleteAllForThreadIdSync = action({
290
+ args: deleteThreadArgs,
291
291
  handler: async (ctx, args) => {
292
- const result: DeleteChatReturns = await ctx.runMutation(
293
- internal.messages._deletePageForChatId,
294
- { chatId: args.chatId, cursor: args.cursor, limit: args.limit }
292
+ const result: DeleteThreadReturns = await ctx.runMutation(
293
+ internal.messages._deletePageForThreadId,
294
+ { threadId: args.threadId, cursor: args.cursor, limit: args.limit }
295
295
  );
296
296
  return result;
297
297
  },
298
- returns: deleteChatReturns,
298
+ returns: deleteThreadReturns,
299
299
  });
300
300
 
301
- export const deleteAllForChatIdAsync = mutation({
302
- args: deleteChatArgs,
301
+ export const deleteAllForThreadIdAsync = mutation({
302
+ args: deleteThreadArgs,
303
303
  handler: async (ctx, args) => {
304
- const result = await deletePageForChatIdHandler(ctx, args);
304
+ const result = await deletePageForThreadIdHandler(ctx, args);
305
305
  if (!result.isDone) {
306
- await ctx.scheduler.runAfter(0, api.messages.deleteAllForChatIdAsync, {
307
- chatId: args.chatId,
306
+ await ctx.scheduler.runAfter(0, api.messages.deleteAllForThreadIdAsync, {
307
+ threadId: args.threadId,
308
308
  cursor: result.cursor,
309
309
  });
310
310
  }
311
311
  return result;
312
312
  },
313
- returns: deleteChatReturns,
313
+ returns: deleteThreadReturns,
314
314
  });
315
315
 
316
- export const _deletePageForChatId = internalMutation({
317
- args: deleteChatArgs,
318
- handler: deletePageForChatIdHandler,
319
- returns: deleteChatReturns,
316
+ export const _deletePageForThreadId = internalMutation({
317
+ args: deleteThreadArgs,
318
+ handler: deletePageForThreadIdHandler,
319
+ returns: deleteThreadReturns,
320
320
  });
321
321
 
322
- async function deletePageForChatIdHandler(
322
+ async function deletePageForThreadIdHandler(
323
323
  ctx: MutationCtx,
324
- args: DeleteChatArgs
325
- ): Promise<DeleteChatReturns> {
324
+ args: DeleteThreadArgs
325
+ ): Promise<DeleteThreadReturns> {
326
326
  const messages = await stream(ctx.db, schema)
327
327
  .query("messages")
328
- .withIndex("chatId_status_tool_order_stepOrder", (q) =>
329
- q.eq("chatId", args.chatId).eq("status", "success")
328
+ .withIndex("threadId_status_tool_order_stepOrder", (q) =>
329
+ q.eq("threadId", args.threadId).eq("status", "success")
330
330
  )
331
331
  .paginate({
332
332
  numItems: args.limit ?? 100,
333
333
  cursor: args.cursor ?? null,
334
334
  });
335
335
  await Promise.all(messages.page.map((m) => deleteMessage(ctx, m)));
336
- await ctx.db.delete(args.chatId);
336
+ await ctx.db.delete(args.threadId);
337
337
  return {
338
338
  cursor: messages.continueCursor,
339
339
  isDone: messages.isDone,
@@ -373,7 +373,7 @@ export const messageStatuses = vMessageDoc.fields.status.members.map(
373
373
 
374
374
  const addMessagesArgs = {
375
375
  userId: v.optional(v.string()),
376
- chatId: v.optional(v.id("chats")),
376
+ threadId: v.optional(v.id("threads")),
377
377
  stepId: v.optional(v.id("steps")),
378
378
  parentMessageId: v.optional(v.id("messages")),
379
379
  messages: v.array(vMessageWithFileAndId),
@@ -395,21 +395,21 @@ async function addMessagesHandler(
395
395
  args: ObjectType<typeof addMessagesArgs>
396
396
  ) {
397
397
  let userId = args.userId;
398
- const chatId = args.chatId;
399
- if (!userId && args.chatId) {
400
- const chat = await ctx.db.get(args.chatId);
401
- assert(chat, `Chat ${args.chatId} not found`);
402
- userId = chat._id;
398
+ const threadId = args.threadId;
399
+ if (!userId && args.threadId) {
400
+ const thread = await ctx.db.get(args.threadId);
401
+ assert(thread, `Thread ${args.threadId} not found`);
402
+ userId = thread._id;
403
403
  }
404
404
  const { failPendingSteps, pending, messages, parentMessageId, ...rest } =
405
405
  args;
406
406
  const parent = parentMessageId && (await ctx.db.get(parentMessageId));
407
407
  if (failPendingSteps && parent?.status !== "pending") {
408
- assert(args.chatId, "chatId is required to fail pending steps");
408
+ assert(args.threadId, "threadId is required to fail pending steps");
409
409
  const pendingMessages = await ctx.db
410
410
  .query("messages")
411
- .withIndex("chatId_status_tool_order_stepOrder", (q) =>
412
- q.eq("chatId", chatId).eq("status", "pending")
411
+ .withIndex("threadId_status_tool_order_stepOrder", (q) =>
412
+ q.eq("threadId", threadId).eq("status", "pending")
413
413
  )
414
414
  .collect();
415
415
  await Promise.all(
@@ -418,13 +418,7 @@ async function addMessagesHandler(
418
418
  )
419
419
  );
420
420
  }
421
- let threadId = parentMessageId;
422
- const maxMessage = await getMaxMessage(ctx, chatId, userId);
423
- // If the previous message isn't our parent, we make a new thread.
424
- threadId =
425
- parentMessageId && maxMessage?._id === parentMessageId
426
- ? maxMessage.threadId ?? parentMessageId
427
- : parentMessageId;
421
+ const maxMessage = await getMaxMessage(ctx, threadId, userId);
428
422
  let order = maxMessage?.order ?? -1;
429
423
  const toReturn: Doc<"messages">[] = [];
430
424
  if (messages.length > 0) {
@@ -436,7 +430,7 @@ async function addMessagesHandler(
436
430
  const text = extractText(message);
437
431
  const messageId = await ctx.db.insert("messages", {
438
432
  ...rest,
439
- threadId,
433
+ parentMessageId,
440
434
  userId,
441
435
  message,
442
436
  id,
@@ -454,17 +448,17 @@ async function addMessagesHandler(
454
448
 
455
449
  async function getMaxMessage(
456
450
  ctx: QueryCtx,
457
- chatId: Id<"chats"> | undefined,
451
+ threadId: Id<"threads"> | undefined,
458
452
  userId: string | undefined
459
453
  ) {
460
- assert(chatId || userId, "One of chatId or userId is required");
461
- if (chatId) {
454
+ assert(threadId || userId, "One of threadId or userId is required");
455
+ if (threadId) {
462
456
  return mergedStream(
463
457
  ["success" as const, "pending" as const].map((status) =>
464
458
  stream(ctx.db, schema)
465
459
  .query("messages")
466
- .withIndex("chatId_status_tool_order_stepOrder", (q) =>
467
- q.eq("chatId", chatId).eq("status", status).eq("tool", false)
460
+ .withIndex("threadId_status_tool_order_stepOrder", (q) =>
461
+ q.eq("threadId", threadId).eq("status", status).eq("tool", false)
468
462
  )
469
463
  .order("desc")
470
464
  ),
@@ -486,7 +480,7 @@ async function getMaxMessage(
486
480
  }
487
481
 
488
482
  const addStepsArgs = {
489
- chatId: v.id("chats"),
483
+ threadId: v.id("threads"),
490
484
  messageId: v.id("messages"),
491
485
  steps: v.array(vStepWithMessagesWithFileAndId),
492
486
  failPendingSteps: v.optional(v.boolean()),
@@ -523,7 +517,7 @@ async function addStepsHandler(
523
517
  let nextStepOrder = (steps.at(-1)?.stepOrder ?? -1) + 1;
524
518
  for (const { step, messages } of args.steps) {
525
519
  const stepId = await ctx.db.insert("steps", {
526
- chatId: args.chatId,
520
+ threadId: args.threadId,
527
521
  parentMessageId: args.messageId,
528
522
  order,
529
523
  stepOrder: nextStepOrder,
@@ -531,7 +525,7 @@ async function addStepsHandler(
531
525
  step,
532
526
  });
533
527
  await addMessagesHandler(ctx, {
534
- chatId: args.chatId,
528
+ threadId: args.threadId,
535
529
  parentMessageId: args.messageId,
536
530
  stepId,
537
531
  messages,
@@ -596,9 +590,9 @@ async function commitMessageHandler(
596
590
  [true, false].map((tool) =>
597
591
  stream(ctx.db, schema)
598
592
  .query("messages")
599
- .withIndex("chatId_status_tool_order_stepOrder", (q) =>
593
+ .withIndex("threadId_status_tool_order_stepOrder", (q) =>
600
594
  q
601
- .eq("chatId", message.chatId)
595
+ .eq("threadId", message.threadId)
602
596
  .eq("status", "pending")
603
597
  .eq("tool", tool)
604
598
  .eq("order", order)
@@ -612,9 +606,9 @@ async function commitMessageHandler(
612
606
  }
613
607
  }
614
608
 
615
- export const getChatMessages = query({
609
+ export const getThreadMessages = query({
616
610
  args: {
617
- chatId: v.id("chats"),
611
+ threadId: v.id("threads"),
618
612
  isTool: v.optional(v.boolean()),
619
613
  order: v.optional(v.union(v.literal("asc"), v.literal("desc"))),
620
614
  limit: v.optional(v.number()),
@@ -634,9 +628,9 @@ export const getChatMessages = query({
634
628
  statuses.map((status) =>
635
629
  stream(ctx.db, schema)
636
630
  .query("messages")
637
- .withIndex("chatId_status_tool_order_stepOrder", (q) => {
631
+ .withIndex("threadId_status_tool_order_stepOrder", (q) => {
638
632
  const qq = q
639
- .eq("chatId", args.chatId)
633
+ .eq("threadId", args.threadId)
640
634
  .eq("status", status)
641
635
  .eq("tool", tool);
642
636
  if (parent) {
@@ -670,19 +664,19 @@ export const getChatMessages = query({
670
664
  export const searchMessages = action({
671
665
  args: {
672
666
  userId: v.optional(v.string()),
673
- chatId: v.optional(v.id("chats")),
667
+ threadId: v.optional(v.id("threads")),
674
668
  parentMessageId: v.optional(v.id("messages")),
675
669
  ...vSearchOptions.fields,
676
670
  },
677
671
  returns: v.array(v.doc("messages")),
678
672
  handler: async (ctx, args): Promise<Doc<"messages">[]> => {
679
- assert(args.userId || args.chatId, "Specify userId or chatId");
673
+ assert(args.userId || args.threadId, "Specify userId or threadId");
680
674
  const limit = args.limit;
681
675
  let textSearchMessages: Doc<"messages">[] | undefined;
682
676
  if (args.text) {
683
677
  textSearchMessages = await ctx.runQuery(api.messages.textSearch, {
684
678
  userId: args.userId,
685
- chatId: args.chatId,
679
+ threadId: args.threadId,
686
680
  text: args.text,
687
681
  limit,
688
682
  });
@@ -699,8 +693,8 @@ export const searchMessages = action({
699
693
  vector: args.vector,
700
694
  filter: (q) =>
701
695
  args.userId
702
- ? q.eq("model_kind_userId", [model, "chat", args.userId])
703
- : q.eq("model_kind_chatId", [model, "chat", args.chatId!]),
696
+ ? q.eq("model_kind_userId", [model, "thread", args.userId])
697
+ : q.eq("model_kind_threadId", [model, "thread", args.threadId!]),
704
698
  limit,
705
699
  })
706
700
  ).filter((v) => v._score > 0.5);
@@ -721,7 +715,7 @@ export const searchMessages = action({
721
715
  internal.messages._fetchVectorMessages,
722
716
  {
723
717
  userId: args.userId,
724
- chatId: args.chatId,
718
+ threadId: args.threadId,
725
719
  vectorIds,
726
720
  textSearchMessages: textSearchMessages?.filter(
727
721
  (m) => !vectorIds.includes(m.embeddingId!)
@@ -740,7 +734,7 @@ export const searchMessages = action({
740
734
  export const _fetchVectorMessages = internalQuery({
741
735
  args: {
742
736
  userId: v.optional(v.string()),
743
- chatId: v.optional(v.id("chats")),
737
+ threadId: v.optional(v.id("threads")),
744
738
  vectorIds: v.array(vVectorId),
745
739
  textSearchMessages: v.optional(v.array(v.doc("messages"))),
746
740
  messageRange: v.object({ before: v.number(), after: v.number() }),
@@ -751,8 +745,8 @@ export const _fetchVectorMessages = internalQuery({
751
745
  handler: async (ctx, args): Promise<Doc<"messages">[]> => {
752
746
  const parent =
753
747
  args.parentMessageId && (await ctx.db.get(args.parentMessageId));
754
- const { userId, chatId } = args;
755
- assert(userId || chatId, "Specify userId or chatId to search");
748
+ const { userId, threadId } = args;
749
+ assert(userId || threadId, "Specify userId or threadId to search");
756
750
  let messages = (
757
751
  await Promise.all(
758
752
  args.vectorIds.map((embeddingId) =>
@@ -763,7 +757,7 @@ export const _fetchVectorMessages = internalQuery({
763
757
  userId
764
758
  ? q.eq("userId", userId)
765
759
  : // eslint-disable-next-line @typescript-eslint/no-explicit-any
766
- q.eq("chatId", chatId as any)
760
+ q.eq("threadId", threadId as any)
767
761
  )
768
762
  .first()
769
763
  )
@@ -777,12 +771,12 @@ export const _fetchVectorMessages = internalQuery({
777
771
  messages.sort((a, b) => a.order! - b.order!);
778
772
  messages = messages.slice(0, args.limit);
779
773
  // Fetch the surrounding messages
780
- if (!chatId) {
774
+ if (!threadId) {
781
775
  return messages.sort((a, b) => a.order - b.order);
782
776
  }
783
777
  const included: Record<string, Set<number>> = {};
784
778
  for (const m of messages) {
785
- const searchId = m.chatId ?? m.userId!;
779
+ const searchId = m.threadId ?? m.userId!;
786
780
  if (!included[searchId]) {
787
781
  included[searchId] = new Set();
788
782
  }
@@ -791,7 +785,7 @@ export const _fetchVectorMessages = internalQuery({
791
785
  const ranges: Record<string, Doc<"messages">[]> = {};
792
786
  const { before, after } = args.messageRange;
793
787
  for (const m of messages) {
794
- const searchId = m.chatId ?? m.userId!;
788
+ const searchId = m.threadId ?? m.userId!;
795
789
  const order = m.order!;
796
790
  let earliest = order - before;
797
791
  let latest = order + after;
@@ -809,12 +803,12 @@ export const _fetchVectorMessages = internalQuery({
809
803
  included[searchId].add(i);
810
804
  }
811
805
  if (earliest !== latest) {
812
- if (m.chatId) {
806
+ if (m.threadId) {
813
807
  const surrounding = await ctx.db
814
808
  .query("messages")
815
- .withIndex("chatId_status_tool_order_stepOrder", (q) =>
809
+ .withIndex("threadId_status_tool_order_stepOrder", (q) =>
816
810
  q
817
- .eq("chatId", m.chatId)
811
+ .eq("threadId", m.threadId)
818
812
  .eq("status", "success")
819
813
  .eq("tool", false)
820
814
  .gt("order", earliest)
@@ -854,19 +848,19 @@ export const _fetchVectorMessages = internalQuery({
854
848
  // excluding duplicates in later ranges.
855
849
  export const textSearch = query({
856
850
  args: {
857
- chatId: v.optional(v.id("chats")),
851
+ threadId: v.optional(v.id("threads")),
858
852
  userId: v.optional(v.string()),
859
853
  text: v.string(),
860
854
  limit: v.number(),
861
855
  },
862
856
  handler: async (ctx, args) => {
863
- assert(args.userId || args.chatId, "Specify userId or chatId");
857
+ assert(args.userId || args.threadId, "Specify userId or threadId");
864
858
  const messages = await ctx.db
865
859
  .query("messages")
866
860
  .withSearchIndex("text_search", (q) =>
867
861
  args.userId
868
862
  ? q.search("text", args.text).eq("userId", args.userId)
869
- : q.search("text", args.text).eq("chatId", args.chatId!)
863
+ : q.search("text", args.text).eq("threadId", args.threadId!)
870
864
  )
871
865
  .take(args.limit);
872
866
  return messages;
@@ -919,9 +913,9 @@ export const textSearch = query({
919
913
 
920
914
  // const DEFAULT_MESSAGES_LIMIT = 40; // What pg & upstash do too.
921
915
 
922
- // export const getChatMessagesPage = query({
916
+ // export const getThreadMessagesPage = query({
923
917
  // args: {
924
- // threadId: v.string(),
918
+ // parentMessageId: v.string(),
925
919
  // selectBy: v.optional(vSelectBy),
926
920
  // // Unimplemented and as far I can tell no storage provider has either.
927
921
  // // memoryConfig: v.optional(vMemoryConfig),
@@ -929,7 +923,7 @@ export const textSearch = query({
929
923
  // handler: async (ctx, args): Promise<SerializedMessage[]> => {
930
924
  // const messages = await ctx.db
931
925
  // .query("messages")
932
- // .withIndex("threadId", (q) => q.eq("threadId", args.threadId))
926
+ // .withIndex("parentMessageId", (q) => q.eq("parentMessageId", args.parentMessageId))
933
927
  // .order("desc")
934
928
  // .take(args.selectBy?.last ? args.selectBy.last : DEFAULT_MESSAGES_LIMIT);
935
929
 
@@ -983,9 +977,9 @@ export const textSearch = query({
983
977
  // ranges.map(async (range) => {
984
978
  // return await ctx.db
985
979
  // .query("messages")
986
- // .withIndex("threadId", (q) =>
980
+ // .withIndex("parentMessageId", (q) =>
987
981
  // q
988
- // .eq("threadId", args.threadId)
982
+ // .eq("parentMessageId", args.parentMessageId)
989
983
  // .gte("threadOrder", range.start)
990
984
  // .lte("threadOrder", range.end)
991
985
  // )
@@ -1002,21 +996,21 @@ export const textSearch = query({
1002
996
  // export const saveMessages = mutation({
1003
997
  // args: { messages: v.array(vSerializedMessage) },
1004
998
  // handler: async (ctx, args) => {
1005
- // const messagesByThreadId: Record<string, SerializedMessage[]> = {};
999
+ // const messagesByParentMessageId: Record<string, SerializedMessage[]> = {};
1006
1000
  // for (const message of args.messages) {
1007
- // messagesByThreadId[message.threadId] = [
1008
- // ...(messagesByThreadId[message.threadId] ?? []),
1001
+ // messagesByParentMessageId[message.parentMessageId] = [
1002
+ // ...(messagesByParentMessageId[message.parentMessageId] ?? []),
1009
1003
  // message,
1010
1004
  // ];
1011
1005
  // }
1012
- // for (const threadId in messagesByThreadId) {
1006
+ // for (const parentMessageId in messagesByParentMessageId) {
1013
1007
  // const lastMessage = await ctx.db
1014
1008
  // .query("messages")
1015
- // .withIndex("threadId", (q) => q.eq("threadId", threadId))
1009
+ // .withIndex("parentMessageId", (q) => q.eq("parentMessageId", parentMessageId))
1016
1010
  // .order("desc")
1017
1011
  // .first();
1018
1012
  // let threadOrder = lastMessage?.threadOrder ?? 0;
1019
- // for (const message of messagesByThreadId[threadId]) {
1013
+ // for (const message of messagesByParentMessageId[parentMessageId]) {
1020
1014
  // threadOrder++;
1021
1015
  // await ctx.db.insert("messages", {
1022
1016
  // ...message,