@convex-dev/agent 0.0.16 → 0.0.17-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +159 -98
  2. package/dist/commonjs/client/index.d.ts +806 -189
  3. package/dist/commonjs/client/index.d.ts.map +1 -1
  4. package/dist/commonjs/client/index.js +178 -28
  5. package/dist/commonjs/client/index.js.map +1 -1
  6. package/dist/commonjs/client/playground.d.ts +609 -0
  7. package/dist/commonjs/client/playground.d.ts.map +1 -0
  8. package/dist/commonjs/client/playground.js +200 -0
  9. package/dist/commonjs/client/playground.js.map +1 -0
  10. package/dist/commonjs/component/apiKeys.d.ts +11 -0
  11. package/dist/commonjs/component/apiKeys.d.ts.map +1 -0
  12. package/dist/commonjs/component/apiKeys.js +69 -0
  13. package/dist/commonjs/component/apiKeys.js.map +1 -0
  14. package/dist/commonjs/component/files.d.ts +31 -0
  15. package/dist/commonjs/component/files.d.ts.map +1 -0
  16. package/dist/commonjs/component/files.js +61 -0
  17. package/dist/commonjs/component/files.js.map +1 -0
  18. package/dist/commonjs/component/messages.d.ts +720 -676
  19. package/dist/commonjs/component/messages.d.ts.map +1 -1
  20. package/dist/commonjs/component/messages.js +99 -287
  21. package/dist/commonjs/component/messages.js.map +1 -1
  22. package/dist/commonjs/component/schema.d.ts +1124 -1324
  23. package/dist/commonjs/component/schema.d.ts.map +1 -1
  24. package/dist/commonjs/component/schema.js +26 -14
  25. package/dist/commonjs/component/schema.js.map +1 -1
  26. package/dist/commonjs/component/threads.d.ts +95 -0
  27. package/dist/commonjs/component/threads.d.ts.map +1 -0
  28. package/dist/commonjs/component/threads.js +151 -0
  29. package/dist/commonjs/component/threads.js.map +1 -0
  30. package/dist/commonjs/component/users.d.ts +37 -0
  31. package/dist/commonjs/component/users.d.ts.map +1 -0
  32. package/dist/commonjs/component/users.js +118 -0
  33. package/dist/commonjs/component/users.js.map +1 -0
  34. package/dist/commonjs/component/vector/index.d.ts.map +1 -1
  35. package/dist/commonjs/component/vector/index.js +4 -6
  36. package/dist/commonjs/component/vector/index.js.map +1 -1
  37. package/dist/commonjs/component/vector/tables.d.ts +10 -10
  38. package/dist/commonjs/component/vector/tables.d.ts.map +1 -1
  39. package/dist/commonjs/component/vector/tables.js.map +1 -1
  40. package/dist/commonjs/mapping.d.ts +7 -1
  41. package/dist/commonjs/mapping.d.ts.map +1 -1
  42. package/dist/commonjs/mapping.js +39 -18
  43. package/dist/commonjs/mapping.js.map +1 -1
  44. package/dist/commonjs/validators.d.ts +1669 -2340
  45. package/dist/commonjs/validators.d.ts.map +1 -1
  46. package/dist/commonjs/validators.js +35 -26
  47. package/dist/commonjs/validators.js.map +1 -1
  48. package/dist/esm/client/index.d.ts +806 -189
  49. package/dist/esm/client/index.d.ts.map +1 -1
  50. package/dist/esm/client/index.js +178 -28
  51. package/dist/esm/client/index.js.map +1 -1
  52. package/dist/esm/client/playground.d.ts +609 -0
  53. package/dist/esm/client/playground.d.ts.map +1 -0
  54. package/dist/esm/client/playground.js +200 -0
  55. package/dist/esm/client/playground.js.map +1 -0
  56. package/dist/esm/component/apiKeys.d.ts +11 -0
  57. package/dist/esm/component/apiKeys.d.ts.map +1 -0
  58. package/dist/esm/component/apiKeys.js +69 -0
  59. package/dist/esm/component/apiKeys.js.map +1 -0
  60. package/dist/esm/component/files.d.ts +31 -0
  61. package/dist/esm/component/files.d.ts.map +1 -0
  62. package/dist/esm/component/files.js +61 -0
  63. package/dist/esm/component/files.js.map +1 -0
  64. package/dist/esm/component/messages.d.ts +720 -676
  65. package/dist/esm/component/messages.d.ts.map +1 -1
  66. package/dist/esm/component/messages.js +99 -287
  67. package/dist/esm/component/messages.js.map +1 -1
  68. package/dist/esm/component/schema.d.ts +1124 -1324
  69. package/dist/esm/component/schema.d.ts.map +1 -1
  70. package/dist/esm/component/schema.js +26 -14
  71. package/dist/esm/component/schema.js.map +1 -1
  72. package/dist/esm/component/threads.d.ts +95 -0
  73. package/dist/esm/component/threads.d.ts.map +1 -0
  74. package/dist/esm/component/threads.js +151 -0
  75. package/dist/esm/component/threads.js.map +1 -0
  76. package/dist/esm/component/users.d.ts +37 -0
  77. package/dist/esm/component/users.d.ts.map +1 -0
  78. package/dist/esm/component/users.js +118 -0
  79. package/dist/esm/component/users.js.map +1 -0
  80. package/dist/esm/component/vector/index.d.ts.map +1 -1
  81. package/dist/esm/component/vector/index.js +4 -6
  82. package/dist/esm/component/vector/index.js.map +1 -1
  83. package/dist/esm/component/vector/tables.d.ts +10 -10
  84. package/dist/esm/component/vector/tables.d.ts.map +1 -1
  85. package/dist/esm/component/vector/tables.js.map +1 -1
  86. package/dist/esm/mapping.d.ts +7 -1
  87. package/dist/esm/mapping.d.ts.map +1 -1
  88. package/dist/esm/mapping.js +39 -18
  89. package/dist/esm/mapping.js.map +1 -1
  90. package/dist/esm/validators.d.ts +1669 -2340
  91. package/dist/esm/validators.d.ts.map +1 -1
  92. package/dist/esm/validators.js +35 -26
  93. package/dist/esm/validators.js.map +1 -1
  94. package/package.json +8 -1
  95. package/src/client/index.ts +220 -59
  96. package/src/client/playground.ts +257 -0
  97. package/src/component/_generated/api.d.ts +601 -400
  98. package/src/component/apiKeys.ts +74 -0
  99. package/src/component/files.ts +72 -0
  100. package/src/component/messages.test.ts +23 -0
  101. package/src/component/messages.ts +127 -341
  102. package/src/component/schema.ts +32 -13
  103. package/src/component/threads.ts +184 -0
  104. package/src/component/users.ts +145 -0
  105. package/src/component/vector/index.ts +5 -6
  106. package/src/component/vector/tables.ts +15 -15
  107. package/src/mapping.ts +65 -32
  108. package/src/validators.ts +47 -28
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/component/messages.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/component/messages.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAIL,WAAW,EAEX,QAAQ,EACT,MAAM,wBAAwB,CAAC;AAiBhC,gEAAgE;AAChE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;GAAsB,CAAA;AAEtD,0CAA0C;AAC1C,eAAO,MAAM,SAAS;;;;;;;;;UAAa,CAAC;AAEpC,qDAAqD;AACrD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;GAAe,CAAC;AAEzC,wBAAsB,aAAa,CACjC,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,iBAa5B;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ikBAAmC,CAAC;AAC5D,eAAO,MAAM,eAAe,sCAE3B,CAAC;AAYF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAOtB,CAAC;AAsFH,wBAAsB,aAAa,CACjC,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,SAAS,EACnC,MAAM,EAAE,MAAM,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgC3B;AAUD,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAIlB,CAAC;AAoDH,eAAO,MAAM,eAAe;;;iBA4B1B,CAAC;AAEH,eAAO,MAAM,aAAa;eASI,EAAE,CAAC,UAAU,CAAC;iBAH1C,CAAC;AAwCH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAqDjC,CAAC;AAEH,sDAAsD;AACtD,eAAO,MAAM,iBAAiB;;kBAM5B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkEzB,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyH/B,CAAC;AAIH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsCrB,CAAC"}
@@ -1,251 +1,34 @@
1
- import { assert, omit, pick } from "convex-helpers";
2
- import { paginator } from "convex-helpers/server/pagination";
1
+ import { assert } from "convex-helpers";
3
2
  import { mergedStream, stream } from "convex-helpers/server/stream";
4
- import { nullable, partial } from "convex-helpers/validators";
5
3
  import { DEFAULT_MESSAGE_RANGE, DEFAULT_RECENT_MESSAGES, extractText, isTool, } from "../shared.js";
6
4
  import { paginationResultValidator, vMessageStatus, vMessageWithMetadata, vSearchOptions, vStepWithMessages, } from "../validators.js";
7
5
  import { api, internal } from "./_generated/api.js";
8
- import { action, internalMutation, internalQuery, mutation, query, } from "./_generated/server.js";
6
+ import { action, internalQuery, mutation, query, } from "./_generated/server.js";
9
7
  import { schema, v } from "./schema.js";
10
8
  import { insertVector, searchVectors } from "./vector/index.js";
11
9
  import { VectorDimensions, vVectorId, } from "./vector/tables.js";
10
+ import { listThreadsByUserId as _listThreadsByUserId, getThread as _getThread, updateThread as _updateThread, } from "./threads.js";
12
11
  import { paginationOptsValidator } from "convex/server";
13
- export const getThread = query({
14
- args: { threadId: v.id("threads") },
15
- handler: async (ctx, args) => {
16
- return ctx.db.get(args.threadId);
17
- },
18
- returns: v.union(v.doc("threads"), v.null()),
19
- });
20
- export const getThreadsByUserId = query({
21
- args: {
22
- userId: v.string(),
23
- order: v.optional(v.union(v.literal("asc"), v.literal("desc"))),
24
- paginationOpts: v.optional(paginationOptsValidator),
25
- },
26
- handler: async (ctx, args) => {
27
- const threads = await paginator(ctx.db, schema)
28
- .query("threads")
29
- .withIndex("userId", (q) => q.eq("userId", args.userId))
30
- .order(args.order ?? "desc")
31
- .paginate(args.paginationOpts ?? { cursor: null, numItems: 100 });
32
- return threads;
33
- },
34
- returns: paginationResultValidator(v.doc("threads")),
35
- });
36
- const vThread = schema.tables.threads.validator;
37
- export const createThread = mutation({
38
- args: omit(vThread.fields, ["order", "status"]),
39
- handler: async (ctx, args) => {
40
- const threadId = await ctx.db.insert("threads", {
41
- ...args,
42
- status: "active",
43
- });
44
- return (await ctx.db.get(threadId));
45
- },
46
- returns: v.doc("threads"),
47
- });
48
- export const updateThread = mutation({
49
- args: {
50
- threadId: v.id("threads"),
51
- patch: v.object(partial(pick(vThread.fields, ["title", "summary", "status"]))),
52
- },
53
- handler: async (ctx, args) => {
54
- const thread = await ctx.db.get(args.threadId);
55
- assert(thread, `Thread ${args.threadId} not found`);
56
- await ctx.db.patch(args.threadId, args.patch);
57
- return (await ctx.db.get(args.threadId));
58
- },
59
- returns: v.doc("threads"),
60
- });
61
- // When we expose this, we need to also hide all the messages and steps
62
- // export const archiveThread = mutation({
63
- // args: { threadId: v.id("threads") },
64
- // handler: async (ctx, args) => {
65
- // const thread = await ctx.db.get(args.threadId);
66
- // assert(thread, `Thread ${args.threadId} not found`);
67
- // await ctx.db.patch(args.threadId, { status: "archived" });
68
- // return (await ctx.db.get(args.threadId))!;
69
- // },
70
- // returns: v.doc("threads"),
71
- // });
72
- export const deleteAllForUserId = action({
73
- args: { userId: v.string() },
74
- handler: async (ctx, args) => {
75
- let messagesCursor = null;
76
- let threadsCursor = null;
77
- let isDone = false;
78
- while (!isDone) {
79
- const result = await ctx.runMutation(internal.messages._deletePageForUserId, {
80
- userId: args.userId,
81
- messagesCursor,
82
- threadsCursor,
83
- });
84
- messagesCursor = result.messagesCursor;
85
- threadsCursor = result.threadsCursor;
86
- isDone = result.isDone;
87
- }
88
- },
89
- returns: v.null(),
90
- });
91
- export const deleteAllForUserIdAsync = mutation({
92
- args: {
93
- userId: v.string(),
94
- },
95
- handler: async (ctx, args) => {
96
- const isDone = await deleteAllForUserIdAsyncHandler(ctx, {
97
- userId: args.userId,
98
- messagesCursor: null,
99
- threadsCursor: null,
100
- });
101
- return isDone;
102
- },
103
- returns: v.boolean(),
104
- });
105
- const deleteAllArgs = {
106
- userId: v.string(),
107
- messagesCursor: nullable(v.string()),
108
- threadsCursor: nullable(v.string()),
109
- };
110
- const deleteAllReturns = {
111
- messagesCursor: v.string(),
112
- threadsCursor: nullable(v.string()),
113
- isDone: v.boolean(),
114
- };
115
- export const _deleteAllForUserIdAsync = internalMutation({
116
- args: deleteAllArgs,
117
- handler: deleteAllForUserIdAsyncHandler,
118
- returns: v.boolean(),
119
- });
120
- async function deleteAllForUserIdAsyncHandler(ctx, args) {
121
- const result = await deletePageForUserId(ctx, args);
122
- if (!result.isDone) {
123
- await ctx.scheduler.runAfter(0, internal.messages._deleteAllForUserIdAsync, {
124
- userId: args.userId,
125
- messagesCursor: result.messagesCursor,
126
- threadsCursor: result.threadsCursor,
127
- });
128
- }
129
- return result.isDone;
130
- }
131
- export const _deletePageForUserId = internalMutation({
132
- args: deleteAllArgs,
133
- handler: deletePageForUserId,
134
- returns: deleteAllReturns,
135
- });
136
- async function deletePageForUserId(ctx, args) {
137
- const threads = await paginator(ctx.db, schema)
138
- .query("threads")
139
- .withIndex("userId", (q) => q.eq("userId", args.userId))
140
- .order("desc")
141
- .paginate({
142
- numItems: 100,
143
- cursor: args.threadsCursor ?? null,
144
- });
145
- await Promise.all(threads.page.map((c) => ctx.db.delete(c._id)));
146
- const messages = await paginator(ctx.db, schema)
147
- .query("messages")
148
- .withIndex("userId_status_tool_order_stepOrder", (q) => q.eq("userId", args.userId))
149
- .order("desc")
150
- .paginate({
151
- numItems: 100,
152
- cursor: args.messagesCursor ?? null,
153
- });
154
- await Promise.all(messages.page.map((m) => deleteMessage(ctx, m)));
155
- return {
156
- messagesCursor: messages.continueCursor,
157
- threadsCursor: threads.continueCursor,
158
- isDone: messages.isDone,
159
- };
160
- }
161
- async function deleteMessage(ctx, messageDoc) {
12
+ /** @deprecated Use *.threads.listMessagesByThreadId instead. */
13
+ export const listThreadsByUserId = _listThreadsByUserId;
14
+ /** @deprecated Use *.threads.getThread */
15
+ export const getThread = _getThread;
16
+ /** @deprecated Use *.threads.updateThread instead */
17
+ export const updateThread = _updateThread;
18
+ export async function deleteMessage(ctx, messageDoc) {
162
19
  await ctx.db.delete(messageDoc._id);
163
20
  if (messageDoc.embeddingId) {
164
21
  await ctx.db.delete(messageDoc.embeddingId);
165
22
  }
166
- if (messageDoc.fileId) {
167
- const file = await ctx.db.get(messageDoc.fileId);
23
+ for (const { fileId } of messageDoc.files ?? []) {
24
+ if (!fileId)
25
+ continue;
26
+ const file = await ctx.db.get(fileId);
168
27
  if (file) {
169
- await ctx.db.patch(messageDoc.fileId, { refcount: file.refcount - 1 });
28
+ await ctx.db.patch(fileId, { refcount: file.refcount - 1 });
170
29
  }
171
30
  }
172
31
  }
173
- const deleteThreadArgs = {
174
- threadId: v.id("threads"),
175
- cursor: v.optional(v.string()),
176
- limit: v.optional(v.number()),
177
- };
178
- const deleteThreadReturns = {
179
- cursor: v.string(),
180
- isDone: v.boolean(),
181
- };
182
- export const deleteAllForThreadIdSync = action({
183
- args: deleteThreadArgs,
184
- handler: async (ctx, args) => {
185
- const result = await ctx.runMutation(internal.messages._deletePageForThreadId, { threadId: args.threadId, cursor: args.cursor, limit: args.limit });
186
- return result;
187
- },
188
- returns: deleteThreadReturns,
189
- });
190
- export const deleteAllForThreadIdAsync = mutation({
191
- args: deleteThreadArgs,
192
- handler: async (ctx, args) => {
193
- const result = await deletePageForThreadIdHandler(ctx, args);
194
- if (!result.isDone) {
195
- await ctx.scheduler.runAfter(0, api.messages.deleteAllForThreadIdAsync, {
196
- threadId: args.threadId,
197
- cursor: result.cursor,
198
- });
199
- }
200
- return result;
201
- },
202
- returns: deleteThreadReturns,
203
- });
204
- export const _deletePageForThreadId = internalMutation({
205
- args: deleteThreadArgs,
206
- handler: deletePageForThreadIdHandler,
207
- returns: deleteThreadReturns,
208
- });
209
- async function deletePageForThreadIdHandler(ctx, args) {
210
- const messages = await paginator(ctx.db, schema)
211
- .query("messages")
212
- .withIndex("threadId_status_tool_order_stepOrder", (q) => q.eq("threadId", args.threadId))
213
- .paginate({
214
- numItems: args.limit ?? 100,
215
- cursor: args.cursor ?? null,
216
- });
217
- await Promise.all(messages.page.map((m) => deleteMessage(ctx, m)));
218
- await ctx.db.delete(args.threadId);
219
- return {
220
- cursor: messages.continueCursor,
221
- isDone: messages.isDone,
222
- };
223
- }
224
- export const getFilesToDelete = query({
225
- args: {
226
- cursor: v.optional(v.string()),
227
- limit: v.optional(v.number()),
228
- },
229
- handler: async (ctx, args) => {
230
- const files = await paginator(ctx.db, schema)
231
- .query("files")
232
- .withIndex("refcount", (q) => q.eq("refcount", 0))
233
- .paginate({
234
- numItems: args.limit ?? 100,
235
- cursor: args.cursor ?? null,
236
- });
237
- return {
238
- files: files.page,
239
- continueCursor: files.continueCursor,
240
- isDone: files.isDone,
241
- };
242
- },
243
- returns: v.object({
244
- files: v.array(v.doc("files")),
245
- continueCursor: v.string(),
246
- isDone: v.boolean(),
247
- }),
248
- });
249
32
  export const vMessageDoc = schema.tables.messages.validator;
250
33
  export const messageStatuses = vMessageDoc.fields.status.members.map((m) => m.value);
251
34
  const addMessagesArgs = {
@@ -275,9 +58,7 @@ async function addMessagesHandler(ctx, args) {
275
58
  userId = thread.userId;
276
59
  }
277
60
  const { failPendingSteps, pending, messages, parentMessageId, ...rest } = args;
278
- const parent = parentMessageId && (await ctx.db.get(parentMessageId));
279
- // TODO: I think this is a bug - parent will be pending always?
280
- if (failPendingSteps && parent?.status !== "pending") {
61
+ if (failPendingSteps) {
281
62
  assert(args.threadId, "threadId is required to fail pending steps");
282
63
  const pendingMessages = await ctx.db
283
64
  .query("messages")
@@ -287,9 +68,11 @@ async function addMessagesHandler(ctx, args) {
287
68
  }
288
69
  const maxMessage = await getMaxMessage(ctx, threadId, userId);
289
70
  let order = maxMessage?.order ?? -1;
71
+ let stepOrder = maxMessage?.stepOrder ?? 0;
72
+ let lastMessageIsTool = maxMessage?.tool ?? false;
290
73
  const toReturn = [];
291
74
  if (messages.length > 0) {
292
- for (const { message, fileId, embedding, ...fields } of messages) {
75
+ for (const { message, files, embedding, ...fields } of messages) {
293
76
  let embeddingId;
294
77
  if (embedding) {
295
78
  embeddingId = await insertVector(ctx, embedding.dimension, {
@@ -301,9 +84,14 @@ async function addMessagesHandler(ctx, args) {
301
84
  });
302
85
  }
303
86
  const tool = isTool(message);
304
- if (!tool) {
87
+ if (lastMessageIsTool) {
88
+ stepOrder++;
89
+ }
90
+ else {
305
91
  order++;
92
+ stepOrder = 0;
306
93
  }
94
+ lastMessageIsTool = tool;
307
95
  const text = extractText(message);
308
96
  const messageId = await ctx.db.insert("messages", {
309
97
  ...rest,
@@ -315,11 +103,18 @@ async function addMessagesHandler(ctx, args) {
315
103
  order,
316
104
  tool,
317
105
  text,
318
- fileId,
106
+ files,
319
107
  status: pending ? "pending" : "success",
320
- stepOrder: 0,
108
+ stepOrder,
321
109
  });
322
- if (fileId) {
110
+ if (!fields.id) {
111
+ await ctx.db.patch(messageId, {
112
+ id: messageId,
113
+ });
114
+ }
115
+ for (const { fileId } of files ?? []) {
116
+ if (!fileId)
117
+ continue;
323
118
  await ctx.db.patch(fileId, {
324
119
  refcount: (await ctx.db.get(fileId)).refcount + 1,
325
120
  });
@@ -329,39 +124,26 @@ async function addMessagesHandler(ctx, args) {
329
124
  }
330
125
  return { messages: toReturn };
331
126
  }
332
- async function getMaxMessage(ctx, threadId, userId) {
127
+ // exported for tests
128
+ export async function getMaxMessage(ctx, threadId, userId) {
333
129
  assert(threadId || userId, "One of threadId or userId is required");
334
130
  if (threadId) {
335
- return mergedStream(["success", "pending"].map((status) => stream(ctx.db, schema)
131
+ return mergedStream([true, false].flatMap((tool) => ["success", "pending"].map((status) => stream(ctx.db, schema)
336
132
  .query("messages")
337
- .withIndex("threadId_status_tool_order_stepOrder", (q) => q.eq("threadId", threadId).eq("status", status).eq("tool", false))
338
- .order("desc")), ["order", "stepOrder"]).first();
133
+ .withIndex("threadId_status_tool_order_stepOrder", (q) => q.eq("threadId", threadId).eq("status", status).eq("tool", tool))
134
+ .order("desc"))), ["order", "stepOrder"]).first();
339
135
  }
340
136
  else {
341
- // DO explicitly
342
- const maxPending = await ctx.db
137
+ return mergedStream([true, false].flatMap((tool) => ["success", "pending"].map((status) => stream(ctx.db, schema)
343
138
  .query("messages")
344
- .withIndex("userId_status_tool_order_stepOrder", (q) => q.eq("userId", userId).eq("status", "pending").eq("tool", false))
345
- .order("desc")
346
- .first();
347
- const maxSuccess = await ctx.db
348
- .query("messages")
349
- .withIndex("userId_status_tool_order_stepOrder", (q) => q.eq("userId", userId).eq("status", "success").eq("tool", false))
350
- .order("desc")
351
- .first();
352
- return maxPending
353
- ? maxSuccess
354
- ? maxPending.order > maxSuccess.order
355
- ? maxPending
356
- : maxSuccess
357
- : maxPending
358
- : maxSuccess ?? null;
139
+ .withIndex("userId_status_tool_order_stepOrder", (q) => q.eq("userId", userId).eq("status", status).eq("tool", tool))
140
+ .order("desc"))), ["order", "stepOrder"]).first();
359
141
  }
360
142
  }
361
143
  const addStepArgs = {
362
144
  userId: v.optional(v.string()),
363
145
  threadId: v.id("threads"),
364
- messageId: v.id("messages"),
146
+ parentMessageId: v.id("messages"),
365
147
  step: vStepWithMessages,
366
148
  failPendingSteps: v.optional(v.boolean()),
367
149
  };
@@ -371,15 +153,16 @@ export const addStep = mutation({
371
153
  handler: addStepHandler,
372
154
  });
373
155
  async function addStepHandler(ctx, args) {
374
- const parentMessage = await ctx.db.get(args.messageId);
375
- assert(parentMessage, `Message ${args.messageId} not found`);
156
+ const parentMessage = await ctx.db.get(args.parentMessageId);
157
+ assert(parentMessage, `Message ${args.parentMessageId} not found`);
376
158
  const order = parentMessage.order;
377
- assert(order !== undefined, `${args.messageId} has no order`);
159
+ assert(order !== undefined, `${args.parentMessageId} has no order`);
160
+ // TODO: only fetch the last one if we aren't failing pending steps
378
161
  let steps = await ctx.db
379
162
  .query("steps")
380
163
  .withIndex("parentMessageId_order_stepOrder", (q) =>
381
164
  // TODO: fetch pending, and commit later
382
- q.eq("parentMessageId", args.messageId))
165
+ q.eq("parentMessageId", args.parentMessageId))
383
166
  .collect();
384
167
  if (args.failPendingSteps) {
385
168
  for (const step of steps) {
@@ -392,7 +175,7 @@ async function addStepHandler(ctx, args) {
392
175
  const { step, messages } = args.step;
393
176
  const stepId = await ctx.db.insert("steps", {
394
177
  threadId: args.threadId,
395
- parentMessageId: args.messageId,
178
+ parentMessageId: args.parentMessageId,
396
179
  order,
397
180
  stepOrder: (steps.at(-1)?.stepOrder ?? -1) + 1,
398
181
  status: step.finishReason === "stop" ? "success" : "pending",
@@ -402,7 +185,7 @@ async function addStepHandler(ctx, args) {
402
185
  userId: args.userId,
403
186
  threadId: args.threadId,
404
187
  stepId,
405
- parentMessageId: args.messageId,
188
+ parentMessageId: args.parentMessageId,
406
189
  agentName: parentMessage.agentName,
407
190
  messages,
408
191
  pending: step.finishReason === "stop" ? false : true,
@@ -410,7 +193,7 @@ async function addStepHandler(ctx, args) {
410
193
  });
411
194
  // We don't commit if the parent is still pending.
412
195
  if (step.finishReason === "stop") {
413
- await commitMessageHandler(ctx, { messageId: args.messageId });
196
+ await commitMessageHandler(ctx, { messageId: args.parentMessageId });
414
197
  }
415
198
  steps.push((await ctx.db.get(stepId)));
416
199
  return steps;
@@ -475,19 +258,21 @@ async function commitMessageHandler(ctx, { messageId }) {
475
258
  // TODO: recursively commit steps & messages that might depend on this one.
476
259
  }
477
260
  }
478
- export const getThreadMessages = query({
261
+ export const listMessagesByThreadId = query({
479
262
  args: {
480
263
  threadId: v.id("threads"),
481
- isTool: v.optional(v.boolean()),
264
+ excludeToolMessages: v.optional(v.boolean()),
265
+ /** @deprecated Use excludeToolMessages instead. */
266
+ isTool: v.optional(v.literal("use excludeToolMessages instead of this")),
482
267
  order: v.optional(v.union(v.literal("asc"), v.literal("desc"))),
483
268
  paginationOpts: v.optional(paginationOptsValidator),
484
269
  statuses: v.optional(v.array(vMessageStatus)),
485
- parentMessageId: v.optional(v.id("messages")),
270
+ beforeMessageId: v.optional(v.id("messages")),
486
271
  },
487
272
  handler: async (ctx, args) => {
488
- const statuses = args.statuses ?? ["success"];
489
- const parent = args.parentMessageId && (await ctx.db.get(args.parentMessageId));
490
- const toolOptions = args.isTool === undefined ? [true, false] : [args.isTool];
273
+ const statuses = args.statuses ?? vMessageStatus.members.map((m) => m.value);
274
+ const before = args.beforeMessageId && (await ctx.db.get(args.beforeMessageId));
275
+ const toolOptions = args.excludeToolMessages ? [false] : [true, false];
491
276
  const order = args.order ?? "desc";
492
277
  const streams = toolOptions.flatMap((tool) => statuses.map((status) => stream(ctx.db, schema)
493
278
  .query("messages")
@@ -496,12 +281,15 @@ export const getThreadMessages = query({
496
281
  .eq("threadId", args.threadId)
497
282
  .eq("status", status)
498
283
  .eq("tool", tool);
499
- if (parent) {
500
- return qq.lte("order", parent.order);
284
+ if (before) {
285
+ return qq.lte("order", before.order);
501
286
  }
502
287
  return qq;
503
288
  })
504
- .order(order)));
289
+ .order(order)
290
+ .filterWith(async (m) => !before ||
291
+ m.order < before.order ||
292
+ (m.order === before.order && m.stepOrder < before.stepOrder))));
505
293
  const messages = await mergedStream(streams, [
506
294
  "order",
507
295
  "stepOrder",
@@ -513,11 +301,19 @@ export const getThreadMessages = query({
513
301
  },
514
302
  returns: paginationResultValidator(v.doc("messages")),
515
303
  });
304
+ /** @deprecated Use listMessagesByThreadId instead. */
305
+ export const getThreadMessages = query({
306
+ args: { deprecated: v.literal("Use listMessagesByThreadId instead") },
307
+ handler: async () => {
308
+ throw new Error("Use listMessagesByThreadId instead of getThreadMessages");
309
+ },
310
+ returns: paginationResultValidator(v.doc("messages")),
311
+ });
516
312
  export const searchMessages = action({
517
313
  args: {
518
314
  userId: v.optional(v.string()),
519
315
  threadId: v.optional(v.id("threads")),
520
- parentMessageId: v.optional(v.id("messages")),
316
+ beforeMessageId: v.optional(v.id("messages")),
521
317
  ...vSearchOptions.fields,
522
318
  },
523
319
  returns: v.array(v.doc("messages")),
@@ -531,6 +327,7 @@ export const searchMessages = action({
531
327
  threadId: args.threadId,
532
328
  text: args.text,
533
329
  limit,
330
+ beforeMessageId: args.beforeMessageId,
534
331
  });
535
332
  }
536
333
  if (args.vector) {
@@ -557,13 +354,13 @@ export const searchMessages = action({
557
354
  }))
558
355
  .sort((a, b) => b.score - a.score);
559
356
  const vectorIds = vectorScores.slice(0, limit).map((v) => v.id);
560
- const messages = await ctx.runQuery(internal.messages._fetchVectorMessages, {
357
+ const messages = await ctx.runQuery(internal.messages._fetchSearchMessages, {
561
358
  userId: args.userId,
562
359
  threadId: args.threadId,
563
360
  vectorIds,
564
361
  textSearchMessages: textSearchMessages?.filter((m) => !vectorIds.includes(m.embeddingId)),
565
362
  messageRange: args.messageRange ?? DEFAULT_MESSAGE_RANGE,
566
- parentMessageId: args.parentMessageId,
363
+ beforeMessageId: args.beforeMessageId,
567
364
  limit,
568
365
  });
569
366
  return messages;
@@ -571,19 +368,19 @@ export const searchMessages = action({
571
368
  return textSearchMessages?.flat() ?? [];
572
369
  },
573
370
  });
574
- export const _fetchVectorMessages = internalQuery({
371
+ export const _fetchSearchMessages = internalQuery({
575
372
  args: {
576
373
  userId: v.optional(v.string()),
577
374
  threadId: v.optional(v.id("threads")),
578
375
  vectorIds: v.array(vVectorId),
579
376
  textSearchMessages: v.optional(v.array(v.doc("messages"))),
580
377
  messageRange: v.object({ before: v.number(), after: v.number() }),
581
- parentMessageId: v.optional(v.id("messages")),
378
+ beforeMessageId: v.optional(v.id("messages")),
582
379
  limit: v.number(),
583
380
  },
584
381
  returns: v.array(v.doc("messages")),
585
382
  handler: async (ctx, args) => {
586
- const parent = args.parentMessageId && (await ctx.db.get(args.parentMessageId));
383
+ const beforeMessage = args.beforeMessageId && (await ctx.db.get(args.beforeMessageId));
587
384
  const { userId, threadId } = args;
588
385
  assert(userId || threadId, "Specify userId or threadId to search");
589
386
  let messages = (await Promise.all(args.vectorIds.map((embeddingId) => ctx.db
@@ -597,7 +394,10 @@ export const _fetchVectorMessages = internalQuery({
597
394
  .first()))).filter((m) => m !== undefined &&
598
395
  m !== null &&
599
396
  !m.tool &&
600
- (!parent || m.order <= parent.order));
397
+ (!beforeMessage ||
398
+ m.order < beforeMessage.order ||
399
+ (m.order === beforeMessage.order &&
400
+ m.stepOrder < beforeMessage.stepOrder)));
601
401
  messages.push(...(args.textSearchMessages ?? []));
602
402
  // TODO: prioritize more recent messages
603
403
  messages.sort((a, b) => a.order - b.order);
@@ -683,18 +483,30 @@ export const textSearch = query({
683
483
  userId: v.optional(v.string()),
684
484
  text: v.string(),
685
485
  limit: v.number(),
486
+ beforeMessageId: v.optional(v.id("messages")),
686
487
  },
687
488
  handler: async (ctx, args) => {
688
489
  assert(args.userId || args.threadId, "Specify userId or threadId");
490
+ const beforeMessage = args.beforeMessageId && (await ctx.db.get(args.beforeMessageId));
491
+ const order = beforeMessage?.order;
689
492
  const messages = await ctx.db
690
493
  .query("messages")
691
494
  .withSearchIndex("text_search", (q) => args.userId
692
495
  ? q.search("text", args.text).eq("userId", args.userId)
693
496
  : q.search("text", args.text).eq("threadId", args.threadId))
694
497
  // Just in case tool messages slip through
695
- .filter((q) => q.eq(q.field("tool"), false))
498
+ .filter((q) => {
499
+ const qq = q.eq(q.field("tool"), false);
500
+ if (order) {
501
+ return q.and(qq, q.lte(q.field("order"), order));
502
+ }
503
+ return qq;
504
+ })
696
505
  .take(args.limit);
697
- return messages;
506
+ return messages.filter((m) => !beforeMessage ||
507
+ m.order < beforeMessage.order ||
508
+ (m.order === beforeMessage.order &&
509
+ m.stepOrder < beforeMessage.stepOrder));
698
510
  },
699
511
  returns: v.array(v.doc("messages")),
700
512
  });