@convex-dev/agent 0.1.8-alpha.0 → 0.1.8-alpha.1

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 +2 -0
  2. package/dist/commonjs/client/index.d.ts +65 -51
  3. package/dist/commonjs/client/index.d.ts.map +1 -1
  4. package/dist/commonjs/client/index.js +70 -4
  5. package/dist/commonjs/client/index.js.map +1 -1
  6. package/dist/commonjs/component/_generated/api.d.ts +235 -0
  7. package/dist/commonjs/component/messages.d.ts +361 -155
  8. package/dist/commonjs/component/messages.d.ts.map +1 -1
  9. package/dist/commonjs/component/messages.js +25 -0
  10. package/dist/commonjs/component/messages.js.map +1 -1
  11. package/dist/commonjs/component/schema.d.ts +670 -670
  12. package/dist/commonjs/component/streams.d.ts +18 -18
  13. package/dist/commonjs/component/threads.d.ts +6 -6
  14. package/dist/commonjs/component/vector/index.d.ts +12 -12
  15. package/dist/commonjs/component/vector/index.d.ts.map +1 -1
  16. package/dist/commonjs/component/vector/index.js +4 -0
  17. package/dist/commonjs/component/vector/index.js.map +1 -1
  18. package/dist/commonjs/component/vector/tables.d.ts +6 -6
  19. package/dist/commonjs/react/index.d.ts.map +1 -1
  20. package/dist/commonjs/react/index.js +1 -1
  21. package/dist/commonjs/react/index.js.map +1 -1
  22. package/dist/commonjs/validators.d.ts +161 -161
  23. package/dist/commonjs.tsbuildinfo +1 -1
  24. package/dist/esm/client/index.d.ts +31 -17
  25. package/dist/esm/client/index.d.ts.map +1 -1
  26. package/dist/esm/client/index.js +70 -4
  27. package/dist/esm/client/index.js.map +1 -1
  28. package/dist/esm/component/_generated/api.d.ts +235 -0
  29. package/dist/esm/component/messages.d.ts +233 -27
  30. package/dist/esm/component/messages.d.ts.map +1 -1
  31. package/dist/esm/component/messages.js +25 -0
  32. package/dist/esm/component/messages.js.map +1 -1
  33. package/dist/esm/component/schema.d.ts +48 -48
  34. package/dist/esm/component/threads.d.ts +8 -8
  35. package/dist/esm/component/vector/index.d.ts.map +1 -1
  36. package/dist/esm/component/vector/index.js +4 -0
  37. package/dist/esm/component/vector/index.js.map +1 -1
  38. package/dist/esm/react/index.d.ts.map +1 -1
  39. package/dist/esm/react/index.js +1 -1
  40. package/dist/esm/react/index.js.map +1 -1
  41. package/dist/esm/validators.d.ts +19 -19
  42. package/dist/esm.tsbuildinfo +1 -1
  43. package/package.json +4 -5
  44. package/src/client/index.ts +94 -4
  45. package/src/client/setup.test.ts +2 -2
  46. package/src/component/_generated/api.d.ts +235 -0
  47. package/src/component/messages.test.ts +140 -0
  48. package/src/component/messages.ts +30 -0
  49. package/src/component/vector/index.ts +4 -0
  50. package/src/react/index.ts +1 -2
  51. package/dist/commonjs/react/usePaginatedQuery.d.ts +0 -241
  52. package/dist/commonjs/react/usePaginatedQuery.d.ts.map +0 -1
  53. package/dist/commonjs/react/usePaginatedQuery.js +0 -627
  54. package/dist/commonjs/react/usePaginatedQuery.js.map +0 -1
  55. package/dist/esm/react/usePaginatedQuery.d.ts +0 -241
  56. package/dist/esm/react/usePaginatedQuery.d.ts.map +0 -1
  57. package/dist/esm/react/usePaginatedQuery.js +0 -627
  58. package/dist/esm/react/usePaginatedQuery.js.map +0 -1
  59. package/react/package.json +0 -5
  60. package/src/react/usePaginatedQuery.ts +0 -901
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "email": "support@convex.dev",
8
8
  "url": "https://github.com/get-convex/agent/issues"
9
9
  },
10
- "version": "0.1.8-alpha.0",
10
+ "version": "0.1.8-alpha.1",
11
11
  "license": "Apache-2.0",
12
12
  "keywords": [
13
13
  "convex",
@@ -39,8 +39,7 @@
39
39
  },
40
40
  "files": [
41
41
  "dist",
42
- "src",
43
- "react"
42
+ "src"
44
43
  ],
45
44
  "exports": {
46
45
  "./package.json": "./package.json",
@@ -91,7 +90,7 @@
91
90
  "peerDependencies": {
92
91
  "ai": "^4.3.16",
93
92
  "convex": "^1.23.0",
94
- "convex-helpers": "^0.1.91",
93
+ "convex-helpers": "^0.1.93",
95
94
  "react": "^18.3.1 || ^19.0.0"
96
95
  },
97
96
  "peerDependenciesMeta": {
@@ -106,7 +105,7 @@
106
105
  "@types/react": "^19.1.1",
107
106
  "chokidar-cli": "^3.0.0",
108
107
  "convex": "^1.24.8",
109
- "convex-helpers": "^0.1.92",
108
+ "convex-helpers": "^0.1.93",
110
109
  "convex-test": "^0.0.37",
111
110
  "cpy-cli": "^5.0.0",
112
111
  "eslint": "^9.24.0",
@@ -2,11 +2,14 @@ import type { EmbeddingModelV1, LanguageModelV1 } from "@ai-sdk/provider";
2
2
  import type {
3
3
  CoreMessage,
4
4
  DeepPartial,
5
+ FilePart,
5
6
  GenerateObjectResult,
6
7
  GenerateTextResult,
8
+ ImagePart,
7
9
  StepResult,
8
10
  StreamObjectResult,
9
11
  StreamTextResult,
12
+ TextPart,
10
13
  ToolSet,
11
14
  } from "ai";
12
15
  import { generateObject, generateText, streamObject, streamText } from "ai";
@@ -1495,6 +1498,17 @@ export class Agent<AgentTools extends ToolSet> {
1495
1498
  order = saved.messages.at(-1)?.order;
1496
1499
  stepOrder = saved.messages.at(-1)?.stepOrder;
1497
1500
  }
1501
+
1502
+ let processedMessages = [
1503
+ ...contextMessages.map((m) => deserializeMessage(m.message!)),
1504
+ ...messages,
1505
+ ];
1506
+
1507
+ // Process messages to inline localhost files (if not, file urls pointing to localhost will be sent to LLM providers)
1508
+ if (process.env.CONVEX_CLOUD_URL?.startsWith("http://127.0.0.1")) {
1509
+ processedMessages = await this._inlineMessagesFiles(processedMessages);
1510
+ }
1511
+
1498
1512
  const { prompt: _, model, ...rest } = args;
1499
1513
  return {
1500
1514
  args: {
@@ -1502,10 +1516,7 @@ export class Agent<AgentTools extends ToolSet> {
1502
1516
  maxRetries: args.maxRetries ?? this.options.maxRetries,
1503
1517
  model: model ?? this.options.chat,
1504
1518
  system: args.system ?? this.options.instructions,
1505
- messages: [
1506
- ...contextMessages.map((m) => deserializeMessage(m.message!)),
1507
- ...messages,
1508
- ],
1519
+ messages: processedMessages,
1509
1520
  } as T & { model: LanguageModelV1 },
1510
1521
  userId,
1511
1522
  messageId,
@@ -1608,6 +1619,85 @@ export class Agent<AgentTools extends ToolSet> {
1608
1619
  return { embeddings: result.embeddings };
1609
1620
  }
1610
1621
 
1622
+ /**
1623
+ * Process messages to inline file and image URLs that point to localhost
1624
+ * by converting them to base64. This solves the problem of LLMs not being
1625
+ * able to access localhost URLs.
1626
+ */
1627
+ private async _inlineMessagesFiles(
1628
+ messages: CoreMessage[]
1629
+ ): Promise<CoreMessage[]> {
1630
+ // Process each message to convert localhost URLs to base64
1631
+ return Promise.all(
1632
+ messages.map(async (message): Promise<CoreMessage> => {
1633
+ if (
1634
+ message.role !== "user" ||
1635
+ typeof message.content === "string" ||
1636
+ !Array.isArray(message.content)
1637
+ ) {
1638
+ return message;
1639
+ }
1640
+
1641
+ const processedContent = await Promise.all(
1642
+ message.content.map(async (part) => {
1643
+ if (part.type === "image" && part.image instanceof URL) {
1644
+ if (this._isLocalhostUrl(part.image)) {
1645
+ const imageData = await this._downloadFile(part.image);
1646
+ return {
1647
+ ...part,
1648
+ image: imageData,
1649
+ } as ImagePart;
1650
+ }
1651
+ }
1652
+
1653
+ // Handle file parts
1654
+ if (part.type === "file" && part.data instanceof URL) {
1655
+ if (this._isLocalhostUrl(part.data)) {
1656
+ const fileData = await this._downloadFile(part.data);
1657
+ return {
1658
+ ...part,
1659
+ data: fileData,
1660
+ } as FilePart;
1661
+ }
1662
+ }
1663
+
1664
+ return part;
1665
+ })
1666
+ );
1667
+
1668
+ return {
1669
+ ...message,
1670
+ content: processedContent,
1671
+ };
1672
+ })
1673
+ );
1674
+ }
1675
+
1676
+ /**
1677
+ * Check if a URL points to localhost
1678
+ */
1679
+ private _isLocalhostUrl(url: URL): boolean {
1680
+ return (
1681
+ url.hostname === "localhost" ||
1682
+ url.hostname === "127.0.0.1" ||
1683
+ url.hostname === "::1" ||
1684
+ url.hostname === "0.0.0.0"
1685
+ );
1686
+ }
1687
+
1688
+ /**
1689
+ * Download a file from a URL
1690
+ */
1691
+ private async _downloadFile(url: URL): Promise<ArrayBuffer> {
1692
+ // Fetch the file
1693
+ const response = await fetch(url);
1694
+ if (!response.ok) {
1695
+ throw new Error(`Failed to fetch ${url}: ${response.statusText}`);
1696
+ }
1697
+
1698
+ return await response.arrayBuffer();
1699
+ }
1700
+
1611
1701
  /**
1612
1702
  * WORKFLOW UTILITIES
1613
1703
  */
@@ -3,13 +3,13 @@ import { test } from "vitest";
3
3
  import { convexTest } from "convex-test";
4
4
  export const modules = import.meta.glob("./**/*.*s");
5
5
 
6
- import componentSchema from "../component/schema";
6
+ import componentSchema from "../component/schema.js";
7
7
  import {
8
8
  defineSchema,
9
9
  type GenericSchema,
10
10
  type SchemaDefinition,
11
11
  } from "convex/server";
12
- import { type AgentComponent } from ".";
12
+ import { type AgentComponent } from "./index.js";
13
13
  import { componentsGeneric } from "convex/server";
14
14
  export { componentSchema };
15
15
  export const componentModules = import.meta.glob("../component/**/*.ts");
@@ -1177,6 +1177,241 @@ export type Mounts = {
1177
1177
  >;
1178
1178
  }>
1179
1179
  >;
1180
+ updateMessage: FunctionReference<
1181
+ "mutation",
1182
+ "public",
1183
+ {
1184
+ messageId: string;
1185
+ patch: {
1186
+ error?: string;
1187
+ message?:
1188
+ | {
1189
+ content:
1190
+ | string
1191
+ | Array<
1192
+ | {
1193
+ providerOptions?: Record<string, Record<string, any>>;
1194
+ text: string;
1195
+ type: "text";
1196
+ }
1197
+ | {
1198
+ image: string | ArrayBuffer;
1199
+ mimeType?: string;
1200
+ providerOptions?: Record<string, Record<string, any>>;
1201
+ type: "image";
1202
+ }
1203
+ | {
1204
+ data: string | ArrayBuffer;
1205
+ filename?: string;
1206
+ mimeType: string;
1207
+ providerOptions?: Record<string, Record<string, any>>;
1208
+ type: "file";
1209
+ }
1210
+ >;
1211
+ providerOptions?: Record<string, Record<string, any>>;
1212
+ role: "user";
1213
+ }
1214
+ | {
1215
+ content:
1216
+ | string
1217
+ | Array<
1218
+ | {
1219
+ providerOptions?: Record<string, Record<string, any>>;
1220
+ text: string;
1221
+ type: "text";
1222
+ }
1223
+ | {
1224
+ data: string | ArrayBuffer;
1225
+ filename?: string;
1226
+ mimeType: string;
1227
+ providerOptions?: Record<string, Record<string, any>>;
1228
+ type: "file";
1229
+ }
1230
+ | {
1231
+ providerOptions?: Record<string, Record<string, any>>;
1232
+ signature?: string;
1233
+ text: string;
1234
+ type: "reasoning";
1235
+ }
1236
+ | {
1237
+ data: string;
1238
+ providerOptions?: Record<string, Record<string, any>>;
1239
+ type: "redacted-reasoning";
1240
+ }
1241
+ | {
1242
+ args: any;
1243
+ providerOptions?: Record<string, Record<string, any>>;
1244
+ toolCallId: string;
1245
+ toolName: string;
1246
+ type: "tool-call";
1247
+ }
1248
+ >;
1249
+ providerOptions?: Record<string, Record<string, any>>;
1250
+ role: "assistant";
1251
+ }
1252
+ | {
1253
+ content: Array<{
1254
+ args?: any;
1255
+ experimental_content?: Array<
1256
+ | { text: string; type: "text" }
1257
+ | { data: string; mimeType?: string; type: "image" }
1258
+ >;
1259
+ isError?: boolean;
1260
+ providerOptions?: Record<string, Record<string, any>>;
1261
+ result: any;
1262
+ toolCallId: string;
1263
+ toolName: string;
1264
+ type: "tool-result";
1265
+ }>;
1266
+ providerOptions?: Record<string, Record<string, any>>;
1267
+ role: "tool";
1268
+ }
1269
+ | {
1270
+ content: string;
1271
+ providerOptions?: Record<string, Record<string, any>>;
1272
+ role: "system";
1273
+ };
1274
+ status?: "pending" | "success" | "failed";
1275
+ };
1276
+ },
1277
+ {
1278
+ _creationTime: number;
1279
+ _id: string;
1280
+ agentName?: string;
1281
+ embeddingId?: string;
1282
+ error?: string;
1283
+ fileIds?: Array<string>;
1284
+ finishReason?:
1285
+ | "stop"
1286
+ | "length"
1287
+ | "content-filter"
1288
+ | "tool-calls"
1289
+ | "error"
1290
+ | "other"
1291
+ | "unknown";
1292
+ id?: string;
1293
+ message?:
1294
+ | {
1295
+ content:
1296
+ | string
1297
+ | Array<
1298
+ | {
1299
+ providerOptions?: Record<string, Record<string, any>>;
1300
+ text: string;
1301
+ type: "text";
1302
+ }
1303
+ | {
1304
+ image: string | ArrayBuffer;
1305
+ mimeType?: string;
1306
+ providerOptions?: Record<string, Record<string, any>>;
1307
+ type: "image";
1308
+ }
1309
+ | {
1310
+ data: string | ArrayBuffer;
1311
+ filename?: string;
1312
+ mimeType: string;
1313
+ providerOptions?: Record<string, Record<string, any>>;
1314
+ type: "file";
1315
+ }
1316
+ >;
1317
+ providerOptions?: Record<string, Record<string, any>>;
1318
+ role: "user";
1319
+ }
1320
+ | {
1321
+ content:
1322
+ | string
1323
+ | Array<
1324
+ | {
1325
+ providerOptions?: Record<string, Record<string, any>>;
1326
+ text: string;
1327
+ type: "text";
1328
+ }
1329
+ | {
1330
+ data: string | ArrayBuffer;
1331
+ filename?: string;
1332
+ mimeType: string;
1333
+ providerOptions?: Record<string, Record<string, any>>;
1334
+ type: "file";
1335
+ }
1336
+ | {
1337
+ providerOptions?: Record<string, Record<string, any>>;
1338
+ signature?: string;
1339
+ text: string;
1340
+ type: "reasoning";
1341
+ }
1342
+ | {
1343
+ data: string;
1344
+ providerOptions?: Record<string, Record<string, any>>;
1345
+ type: "redacted-reasoning";
1346
+ }
1347
+ | {
1348
+ args: any;
1349
+ providerOptions?: Record<string, Record<string, any>>;
1350
+ toolCallId: string;
1351
+ toolName: string;
1352
+ type: "tool-call";
1353
+ }
1354
+ >;
1355
+ providerOptions?: Record<string, Record<string, any>>;
1356
+ role: "assistant";
1357
+ }
1358
+ | {
1359
+ content: Array<{
1360
+ args?: any;
1361
+ experimental_content?: Array<
1362
+ | { text: string; type: "text" }
1363
+ | { data: string; mimeType?: string; type: "image" }
1364
+ >;
1365
+ isError?: boolean;
1366
+ providerOptions?: Record<string, Record<string, any>>;
1367
+ result: any;
1368
+ toolCallId: string;
1369
+ toolName: string;
1370
+ type: "tool-result";
1371
+ }>;
1372
+ providerOptions?: Record<string, Record<string, any>>;
1373
+ role: "tool";
1374
+ }
1375
+ | {
1376
+ content: string;
1377
+ providerOptions?: Record<string, Record<string, any>>;
1378
+ role: "system";
1379
+ };
1380
+ model?: string;
1381
+ order: number;
1382
+ provider?: string;
1383
+ providerMetadata?: Record<string, Record<string, any>>;
1384
+ providerOptions?: Record<string, Record<string, any>>;
1385
+ reasoning?: string;
1386
+ reasoningDetails?: Array<
1387
+ | { signature?: string; text: string; type: "text" }
1388
+ | { data: string; type: "redacted" }
1389
+ >;
1390
+ sources?: Array<{
1391
+ id: string;
1392
+ providerOptions?: Record<string, Record<string, any>>;
1393
+ sourceType: "url";
1394
+ title?: string;
1395
+ url: string;
1396
+ }>;
1397
+ status: "pending" | "success" | "failed";
1398
+ stepOrder: number;
1399
+ text?: string;
1400
+ threadId: string;
1401
+ tool: boolean;
1402
+ usage?: {
1403
+ completionTokens: number;
1404
+ promptTokens: number;
1405
+ totalTokens: number;
1406
+ };
1407
+ userId?: string;
1408
+ warnings?: Array<
1409
+ | { details?: string; setting: string; type: "unsupported-setting" }
1410
+ | { details?: string; tool: any; type: "unsupported-tool" }
1411
+ | { message: string; type: "other" }
1412
+ >;
1413
+ }
1414
+ >;
1180
1415
  };
1181
1416
  streams: {
1182
1417
  addDelta: FunctionReference<
@@ -141,4 +141,144 @@ describe("agent", () => {
141
141
  stepOrder: 1,
142
142
  });
143
143
  });
144
+
145
+ test("updateMessage updates message content", async () => {
146
+ const t = convexTest(schema, modules);
147
+ const thread = await t.mutation(api.threads.createThread, {
148
+ userId: "test",
149
+ });
150
+ const { messages } = await t.mutation(api.messages.addMessages, {
151
+ threadId: thread._id as Id<"threads">,
152
+ messages: [{ message: { role: "user", content: "hello" } }],
153
+ });
154
+ const messageId = messages[0]._id as Id<"messages">;
155
+
156
+ const updatedMessage = await t.mutation(api.messages.updateMessage, {
157
+ messageId,
158
+ patch: {
159
+ message: { role: "user", content: "updated content" },
160
+ },
161
+ });
162
+
163
+ expect(updatedMessage.message).toEqual({
164
+ role: "user",
165
+ content: "updated content",
166
+ });
167
+ });
168
+
169
+ test("updateMessage updates message status", async () => {
170
+ const t = convexTest(schema, modules);
171
+ const thread = await t.mutation(api.threads.createThread, {
172
+ userId: "test",
173
+ });
174
+ const { messages } = await t.mutation(api.messages.addMessages, {
175
+ threadId: thread._id as Id<"threads">,
176
+ messages: [{ message: { role: "assistant", content: "hello" } }],
177
+ pending: true,
178
+ });
179
+ const messageId = messages[0]._id as Id<"messages">;
180
+
181
+ // Initial status should be pending
182
+ expect(messages[0].status).toBe("pending");
183
+
184
+ // Update to success
185
+ const updatedMessage = await t.mutation(api.messages.updateMessage, {
186
+ messageId,
187
+ patch: {
188
+ status: "success",
189
+ },
190
+ });
191
+
192
+ expect(updatedMessage.status).toBe("success");
193
+ });
194
+
195
+ test("updateMessage updates error field", async () => {
196
+ const t = convexTest(schema, modules);
197
+ const thread = await t.mutation(api.threads.createThread, {
198
+ userId: "test",
199
+ });
200
+ const { messages } = await t.mutation(api.messages.addMessages, {
201
+ threadId: thread._id as Id<"threads">,
202
+ messages: [{ message: { role: "assistant", content: "hello" } }],
203
+ pending: true,
204
+ });
205
+ const messageId = messages[0]._id as Id<"messages">;
206
+
207
+ const updatedMessage = await t.mutation(api.messages.updateMessage, {
208
+ messageId,
209
+ patch: {
210
+ status: "failed",
211
+ error: "Something went wrong",
212
+ },
213
+ });
214
+
215
+ expect(updatedMessage.status).toBe("failed");
216
+ expect(updatedMessage.error).toBe("Something went wrong");
217
+ });
218
+
219
+ test("updateMessage correctly updates tool messages", async () => {
220
+ const t = convexTest(schema, modules);
221
+ const thread = await t.mutation(api.threads.createThread, {
222
+ userId: "test",
223
+ });
224
+ const { messages } = await t.mutation(api.messages.addMessages, {
225
+ threadId: thread._id as Id<"threads">,
226
+ messages: [{
227
+ message: {
228
+ role: "assistant",
229
+ content: [
230
+ {
231
+ type: "tool-call",
232
+ args: { a: 1 },
233
+ toolCallId: "1",
234
+ toolName: "tool",
235
+ },
236
+ ],
237
+ },
238
+ }],
239
+ });
240
+ const messageId = messages[0]._id as Id<"messages">;
241
+
242
+ const updatedMessage = await t.mutation(api.messages.updateMessage, {
243
+ messageId,
244
+ patch: {
245
+ message: {
246
+ role: "assistant",
247
+ content: [
248
+ {
249
+ type: "tool-call",
250
+ args: { a: 2, b: 3 },
251
+ toolCallId: "1",
252
+ toolName: "tool",
253
+ },
254
+ ],
255
+ },
256
+ },
257
+ });
258
+
259
+ expect(updatedMessage.message).toEqual({
260
+ role: "assistant",
261
+ content: [
262
+ {
263
+ type: "tool-call",
264
+ args: { a: 2, b: 3 },
265
+ toolCallId: "1",
266
+ toolName: "tool",
267
+ },
268
+ ],
269
+ });
270
+ });
271
+
272
+ test("updateMessage throws error for non-existent message", async () => {
273
+ const t = convexTest(schema, modules);
274
+
275
+ await expect(
276
+ t.mutation(api.messages.updateMessage, {
277
+ messageId: "invalidId" as Id<"messages">,
278
+ patch: {
279
+ message: { role: "user", content: "test" },
280
+ },
281
+ })
282
+ ).rejects.toThrow();
283
+ });
144
284
  });
@@ -265,6 +265,36 @@ export const commitMessage = mutation({
265
265
  returns: v.null(),
266
266
  handler: commitMessageHandler,
267
267
  });
268
+
269
+ export const updateMessage = mutation({
270
+ args: {
271
+ messageId: v.id("messages"),
272
+ patch: v.object({
273
+ message: v.optional(vMessageDoc.fields.message),
274
+ status: v.optional(vMessageStatus),
275
+ error: v.optional(v.string()),
276
+ }),
277
+ },
278
+ returns: vMessageDoc,
279
+ handler: async (ctx, args) => {
280
+ const message = await ctx.db.get(args.messageId);
281
+ assert(message, `Message ${args.messageId} not found`);
282
+
283
+ const patch: Partial<Doc<"messages">> = {
284
+ ...args.patch,
285
+ };
286
+
287
+ if (args.patch.message !== undefined) {
288
+ patch.message = args.patch.message;
289
+ patch.tool = isTool(args.patch.message);
290
+ patch.text = extractText(args.patch.message);
291
+ }
292
+
293
+ await ctx.db.patch(args.messageId, patch);
294
+ return publicMessage((await ctx.db.get(args.messageId))!);
295
+ },
296
+ });
297
+
268
298
  async function commitMessageHandler(
269
299
  ctx: MutationCtx,
270
300
  { messageId }: { messageId: Id<"messages"> }
@@ -172,6 +172,10 @@ export const updateBatch = mutation({
172
172
  model: v.string(),
173
173
  id: vVectorId,
174
174
  vector: v.array(v.number()),
175
+ // TODO: support changing the vector length by
176
+ // deleting from one table and inserting into another.
177
+ // However this requires updating all the messages that reference
178
+ // the vector.
175
179
  })
176
180
  ),
177
181
  },
@@ -2,11 +2,10 @@
2
2
  import type { ErrorMessage } from "convex-helpers";
3
3
  import {
4
4
  type PaginatedQueryArgs,
5
- // usePaginatedQuery,
6
5
  type UsePaginatedQueryResult,
7
6
  useQuery,
8
7
  } from "convex/react";
9
- import { usePaginatedQuery } from "./usePaginatedQuery.js";
8
+ import { usePaginatedQuery } from "convex-helpers/react";
10
9
  import type { FunctionArgs } from "convex/server";
11
10
  import { useMemo, useState } from "react";
12
11
  import type { MessageDoc } from "../client/index.js";