@convex-dev/agent 0.0.17-alpha.2 → 0.1.0-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 (49) hide show
  1. package/README.md +25 -7
  2. package/dist/commonjs/client/index.d.ts +229 -756
  3. package/dist/commonjs/client/index.d.ts.map +1 -1
  4. package/dist/commonjs/client/index.js +135 -140
  5. package/dist/commonjs/client/index.js.map +1 -1
  6. package/dist/commonjs/component/messages.d.ts +208 -896
  7. package/dist/commonjs/component/messages.d.ts.map +1 -1
  8. package/dist/commonjs/component/messages.js +117 -109
  9. package/dist/commonjs/component/messages.js.map +1 -1
  10. package/dist/commonjs/component/schema.d.ts +1278 -580
  11. package/dist/commonjs/component/schema.d.ts.map +1 -1
  12. package/dist/commonjs/component/schema.js +28 -21
  13. package/dist/commonjs/component/schema.js.map +1 -1
  14. package/dist/commonjs/component/users.d.ts +5 -2
  15. package/dist/commonjs/component/users.d.ts.map +1 -1
  16. package/dist/commonjs/component/users.js +57 -27
  17. package/dist/commonjs/component/users.js.map +1 -1
  18. package/dist/commonjs/validators.d.ts +44 -59
  19. package/dist/commonjs/validators.d.ts.map +1 -1
  20. package/dist/commonjs/validators.js +10 -12
  21. package/dist/commonjs/validators.js.map +1 -1
  22. package/dist/esm/client/index.d.ts +229 -756
  23. package/dist/esm/client/index.d.ts.map +1 -1
  24. package/dist/esm/client/index.js +135 -140
  25. package/dist/esm/client/index.js.map +1 -1
  26. package/dist/esm/component/messages.d.ts +208 -896
  27. package/dist/esm/component/messages.d.ts.map +1 -1
  28. package/dist/esm/component/messages.js +117 -109
  29. package/dist/esm/component/messages.js.map +1 -1
  30. package/dist/esm/component/schema.d.ts +1278 -580
  31. package/dist/esm/component/schema.d.ts.map +1 -1
  32. package/dist/esm/component/schema.js +28 -21
  33. package/dist/esm/component/schema.js.map +1 -1
  34. package/dist/esm/component/users.d.ts +5 -2
  35. package/dist/esm/component/users.d.ts.map +1 -1
  36. package/dist/esm/component/users.js +57 -27
  37. package/dist/esm/component/users.js.map +1 -1
  38. package/dist/esm/validators.d.ts +44 -59
  39. package/dist/esm/validators.d.ts.map +1 -1
  40. package/dist/esm/validators.js +10 -12
  41. package/dist/esm/validators.js.map +1 -1
  42. package/package.json +2 -2
  43. package/src/client/index.ts +215 -199
  44. package/src/component/_generated/api.d.ts +19 -94
  45. package/src/component/messages.test.ts +110 -3
  46. package/src/component/messages.ts +176 -154
  47. package/src/component/schema.ts +34 -21
  48. package/src/component/users.ts +57 -32
  49. package/src/validators.ts +12 -15
@@ -14,6 +14,7 @@ import { deleteMessage } from "./messages.js";
14
14
  import { paginationOptsValidator } from "convex/server";
15
15
  import { stream } from "convex-helpers/server/stream";
16
16
  import { paginationResultValidator } from "../validators.js";
17
+ import { Id } from "./_generated/dataModel.js";
17
18
 
18
19
  // Note: it only searches for users with threads
19
20
  export const listUsersWithThreads = query({
@@ -38,22 +39,18 @@ export const listUsersWithThreads = query({
38
39
  export const deleteAllForUserId = action({
39
40
  args: { userId: v.string() },
40
41
  handler: async (ctx, args) => {
41
- let messagesCursor = null;
42
42
  let threadsCursor = null;
43
+ let threadInProgress = null;
44
+ let messagesCursor = null;
43
45
  let isDone = false;
44
46
  while (!isDone) {
45
- const result: {
46
- messagesCursor: string;
47
- threadsCursor: string | null;
48
- isDone: boolean;
49
- } = await ctx.runMutation(internal.users._deletePageForUserId, {
50
- userId: args.userId,
51
- messagesCursor,
52
- threadsCursor,
53
- });
54
- messagesCursor = result.messagesCursor;
55
- threadsCursor = result.threadsCursor;
56
- isDone = result.isDone;
47
+ ({ messagesCursor, threadInProgress, threadsCursor, isDone } =
48
+ await ctx.runMutation(internal.users._deletePageForUserId, {
49
+ userId: args.userId,
50
+ messagesCursor,
51
+ threadInProgress,
52
+ threadsCursor,
53
+ }));
57
54
  }
58
55
  },
59
56
  returns: v.null(),
@@ -68,6 +65,7 @@ export const deleteAllForUserIdAsync = mutation({
68
65
  userId: args.userId,
69
66
  messagesCursor: null,
70
67
  threadsCursor: null,
68
+ threadInProgress: null,
71
69
  });
72
70
  return isDone;
73
71
  },
@@ -78,11 +76,13 @@ const deleteAllArgs = {
78
76
  userId: v.string(),
79
77
  messagesCursor: nullable(v.string()),
80
78
  threadsCursor: nullable(v.string()),
79
+ threadInProgress: nullable(v.id("threads")),
81
80
  };
82
81
  type DeleteAllArgs = ObjectType<typeof deleteAllArgs>;
83
82
  const deleteAllReturns = {
84
- messagesCursor: v.string(),
85
- threadsCursor: nullable(v.string()),
83
+ threadsCursor: v.string(),
84
+ threadInProgress: nullable(v.id("threads")),
85
+ messagesCursor: nullable(v.string()),
86
86
  isDone: v.boolean(),
87
87
  };
88
88
  type DeleteAllReturns = ObjectType<typeof deleteAllReturns>;
@@ -101,8 +101,7 @@ async function deleteAllForUserIdAsyncHandler(
101
101
  if (!result.isDone) {
102
102
  await ctx.scheduler.runAfter(0, internal.users._deleteAllForUserIdAsync, {
103
103
  userId: args.userId,
104
- messagesCursor: result.messagesCursor,
105
- threadsCursor: result.threadsCursor,
104
+ ...result,
106
105
  });
107
106
  }
108
107
  return result.isDone;
@@ -117,29 +116,55 @@ async function deletePageForUserId(
117
116
  ctx: MutationCtx,
118
117
  args: DeleteAllArgs
119
118
  ): Promise<DeleteAllReturns> {
120
- const threads = await paginator(ctx.db, schema)
121
- .query("threads")
122
- .withIndex("userId", (q) => q.eq("userId", args.userId))
123
- .order("desc")
124
- .paginate({
125
- numItems: 100,
126
- cursor: args.threadsCursor ?? null,
127
- });
128
- await Promise.all(threads.page.map((c) => ctx.db.delete(c._id)));
119
+ let threadInProgress: Id<"threads"> | null = args.threadInProgress;
120
+ let threadsCursor: string | null = args.threadsCursor;
121
+ let messagesCursor: string | null = args.messagesCursor;
122
+ if (!threadsCursor || !threadInProgress) {
123
+ const threads = await paginator(ctx.db, schema)
124
+ .query("threads")
125
+ .withIndex("userId", (q) => q.eq("userId", args.userId))
126
+ .order("desc")
127
+ .paginate({
128
+ numItems: 1,
129
+ cursor: args.threadsCursor ?? null,
130
+ });
131
+ threadsCursor = threads.continueCursor;
132
+ if (threads.page.length > 0) {
133
+ threadInProgress = threads.page[0]._id;
134
+ messagesCursor = null;
135
+ } else {
136
+ return {
137
+ isDone: true,
138
+ threadsCursor,
139
+ threadInProgress,
140
+ messagesCursor,
141
+ };
142
+ }
143
+ }
144
+ // TODO: make a stream of thread queries and delete those in pages
145
+ // then get rid of the "userId" index.
129
146
  const messages = await paginator(ctx.db, schema)
130
147
  .query("messages")
131
- .withIndex("userId_status_tool_order_stepOrder", (q) =>
132
- q.eq("userId", args.userId)
148
+ .withIndex("threadId_status_tool_order_stepOrder", (q) =>
149
+ q.eq("threadId", threadInProgress!)
133
150
  )
134
151
  .order("desc")
135
152
  .paginate({
136
153
  numItems: 100,
137
- cursor: args.messagesCursor ?? null,
154
+ cursor: args.messagesCursor,
138
155
  });
139
156
  await Promise.all(messages.page.map((m) => deleteMessage(ctx, m)));
157
+ if (messages.isDone) {
158
+ await ctx.db.delete(threadInProgress);
159
+ threadInProgress = null;
160
+ messagesCursor = null;
161
+ } else {
162
+ messagesCursor = messages.continueCursor;
163
+ }
140
164
  return {
141
- messagesCursor: messages.continueCursor,
142
- threadsCursor: threads.continueCursor,
143
- isDone: messages.isDone,
165
+ messagesCursor,
166
+ threadsCursor,
167
+ threadInProgress,
168
+ isDone: false,
144
169
  };
145
170
  }
package/src/validators.ts CHANGED
@@ -59,6 +59,11 @@ export const vFile = v.object({
59
59
  fileId: v.optional(v.id("files")),
60
60
  });
61
61
 
62
+ export const vFileWithStringId = v.object({
63
+ ...vFile.fields,
64
+ fileId: v.optional(v.string()),
65
+ });
66
+
62
67
  export const vUserContent = v.union(
63
68
  v.string(),
64
69
  v.array(v.union(vTextPart, vImagePart, vFilePart))
@@ -71,13 +76,6 @@ export const vReasoningPart = v.object({
71
76
  providerOptions,
72
77
  });
73
78
 
74
- export const vFileWithStringId = v.object({
75
- bytes: v.optional(v.bytes()),
76
- url: v.optional(v.string()),
77
- mimeType: v.string(),
78
- fileId: v.optional(v.string()),
79
- });
80
-
81
79
  export const vRedactedReasoningPart = v.object({
82
80
  type: v.literal("redacted-reasoning"),
83
81
  data: v.string(),
@@ -271,17 +269,15 @@ export const vMessageWithMetadata = v.object({
271
269
  usage: v.optional(vUsage),
272
270
  warnings: v.optional(v.array(vLanguageModelV1CallWarning)),
273
271
  error: v.optional(v.string()),
274
- // TODO: move this back out to passed alongside message
275
- embedding: v.optional(
276
- v.object({
277
- model: v.string(),
278
- dimension: vVectorDimension,
279
- vector: v.array(v.number()),
280
- })
281
- ),
282
272
  });
283
273
  export type MessageWithMetadata = Infer<typeof vMessageWithMetadata>;
284
274
 
275
+ export const vMessageEmbeddings = v.object({
276
+ model: v.string(),
277
+ dimension: vVectorDimension,
278
+ vectors: v.array(v.union(v.array(v.number()), v.null())),
279
+ });
280
+
285
281
  export const vStep = v.object({
286
282
  files: v.optional(v.array(v.any())),
287
283
  finishReason: vFinishReason,
@@ -310,6 +306,7 @@ export type Step = Infer<typeof vStep>;
310
306
  export const vStepWithMessages = v.object({
311
307
  step: vStep,
312
308
  messages: v.array(vMessageWithMetadata),
309
+ embeddings: v.optional(vMessageEmbeddings),
313
310
  });
314
311
  export type StepWithMessagesWithMetadata = Infer<typeof vStepWithMessages>;
315
312