@convex-dev/agent 0.1.8-alpha.0 → 0.1.8-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/commonjs/client/index.d.ts +65 -51
- package/dist/commonjs/client/index.d.ts.map +1 -1
- package/dist/commonjs/client/index.js +70 -4
- package/dist/commonjs/client/index.js.map +1 -1
- package/dist/commonjs/component/_generated/api.d.ts +235 -0
- package/dist/commonjs/component/messages.d.ts +361 -155
- package/dist/commonjs/component/messages.d.ts.map +1 -1
- package/dist/commonjs/component/messages.js +25 -0
- package/dist/commonjs/component/messages.js.map +1 -1
- package/dist/commonjs/component/schema.d.ts +670 -670
- package/dist/commonjs/component/streams.d.ts +65 -18
- package/dist/commonjs/component/streams.d.ts.map +1 -1
- package/dist/commonjs/component/streams.js +120 -2
- package/dist/commonjs/component/streams.js.map +1 -1
- package/dist/commonjs/component/threads.d.ts +6 -6
- package/dist/commonjs/component/threads.d.ts.map +1 -1
- package/dist/commonjs/component/threads.js +9 -0
- package/dist/commonjs/component/threads.js.map +1 -1
- package/dist/commonjs/component/users.d.ts.map +1 -1
- package/dist/commonjs/component/users.js +1 -0
- package/dist/commonjs/component/users.js.map +1 -1
- package/dist/commonjs/component/vector/index.d.ts +12 -12
- package/dist/commonjs/component/vector/index.d.ts.map +1 -1
- package/dist/commonjs/component/vector/index.js +4 -0
- package/dist/commonjs/component/vector/index.js.map +1 -1
- package/dist/commonjs/component/vector/tables.d.ts +6 -6
- package/dist/commonjs/react/index.d.ts.map +1 -1
- package/dist/commonjs/react/index.js +1 -1
- package/dist/commonjs/react/index.js.map +1 -1
- package/dist/commonjs/validators.d.ts +161 -161
- package/dist/commonjs.tsbuildinfo +1 -1
- package/dist/esm/client/index.d.ts +31 -17
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +70 -4
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/component/_generated/api.d.ts +235 -0
- package/dist/esm/component/messages.d.ts +233 -27
- package/dist/esm/component/messages.d.ts.map +1 -1
- package/dist/esm/component/messages.js +25 -0
- package/dist/esm/component/messages.js.map +1 -1
- package/dist/esm/component/schema.d.ts +48 -48
- package/dist/esm/component/streams.d.ts +47 -0
- package/dist/esm/component/streams.d.ts.map +1 -1
- package/dist/esm/component/streams.js +120 -2
- package/dist/esm/component/streams.js.map +1 -1
- package/dist/esm/component/threads.d.ts +8 -8
- package/dist/esm/component/threads.d.ts.map +1 -1
- package/dist/esm/component/threads.js +9 -0
- package/dist/esm/component/threads.js.map +1 -1
- package/dist/esm/component/users.d.ts.map +1 -1
- package/dist/esm/component/users.js +1 -0
- package/dist/esm/component/users.js.map +1 -1
- package/dist/esm/component/vector/index.d.ts.map +1 -1
- package/dist/esm/component/vector/index.js +4 -0
- package/dist/esm/component/vector/index.js.map +1 -1
- package/dist/esm/react/index.d.ts.map +1 -1
- package/dist/esm/react/index.js +1 -1
- package/dist/esm/react/index.js.map +1 -1
- package/dist/esm/validators.d.ts +19 -19
- package/dist/esm.tsbuildinfo +1 -1
- package/package.json +4 -5
- package/src/client/index.ts +94 -4
- package/src/client/setup.test.ts +2 -2
- package/src/component/_generated/api.d.ts +235 -0
- package/src/component/messages.test.ts +140 -0
- package/src/component/messages.ts +30 -0
- package/src/component/streams.ts +148 -2
- package/src/component/threads.ts +8 -0
- package/src/component/users.ts +1 -0
- package/src/component/vector/index.ts +4 -0
- package/src/react/index.ts +1 -2
- package/dist/commonjs/react/usePaginatedQuery.d.ts +0 -241
- package/dist/commonjs/react/usePaginatedQuery.d.ts.map +0 -1
- package/dist/commonjs/react/usePaginatedQuery.js +0 -627
- package/dist/commonjs/react/usePaginatedQuery.js.map +0 -1
- package/dist/esm/react/usePaginatedQuery.d.ts +0 -241
- package/dist/esm/react/usePaginatedQuery.d.ts.map +0 -1
- package/dist/esm/react/usePaginatedQuery.js +0 -627
- package/dist/esm/react/usePaginatedQuery.js.map +0 -1
- package/react/package.json +0 -5
- package/src/react/usePaginatedQuery.ts +0 -901
|
@@ -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"> }
|
package/src/component/streams.ts
CHANGED
|
@@ -5,15 +5,20 @@ import {
|
|
|
5
5
|
vStreamDelta,
|
|
6
6
|
vStreamMessage,
|
|
7
7
|
} from "../validators.js";
|
|
8
|
-
import { internal } from "./_generated/api.js";
|
|
9
|
-
import type { Id } from "./_generated/dataModel.js";
|
|
8
|
+
import { api, internal } from "./_generated/api.js";
|
|
9
|
+
import type { Doc, Id } from "./_generated/dataModel.js";
|
|
10
10
|
import {
|
|
11
11
|
internalMutation,
|
|
12
12
|
mutation,
|
|
13
13
|
type MutationCtx,
|
|
14
14
|
query,
|
|
15
|
+
action,
|
|
15
16
|
} from "./_generated/server.js";
|
|
16
17
|
import schema from "./schema.js";
|
|
18
|
+
import type { PaginationResult } from "convex/server";
|
|
19
|
+
import { paginator } from "convex-helpers/server/pagination";
|
|
20
|
+
import { stream } from "convex-helpers/server/stream";
|
|
21
|
+
import { mergedStream } from "convex-helpers/server/stream";
|
|
17
22
|
|
|
18
23
|
const MAX_DELTAS_PER_REQUEST = 1000;
|
|
19
24
|
const MAX_DELTAS_PER_STREAM = 100;
|
|
@@ -207,3 +212,144 @@ export const timeoutStream = internalMutation({
|
|
|
207
212
|
});
|
|
208
213
|
},
|
|
209
214
|
});
|
|
215
|
+
|
|
216
|
+
async function deletePageForStreamId(
|
|
217
|
+
ctx: MutationCtx,
|
|
218
|
+
args: { streamId: Id<"streamingMessages">; cursor?: string }
|
|
219
|
+
) {
|
|
220
|
+
const deltas = await ctx.db
|
|
221
|
+
.query("streamDeltas")
|
|
222
|
+
.withIndex("streamId_start_end", (q) => q.eq("streamId", args.streamId))
|
|
223
|
+
.paginate({
|
|
224
|
+
numItems: MAX_DELTAS_PER_REQUEST,
|
|
225
|
+
cursor: args.cursor ?? null,
|
|
226
|
+
});
|
|
227
|
+
await Promise.all(deltas.page.map((d) => ctx.db.delete(d._id)));
|
|
228
|
+
return deltas;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export async function deleteStreamsPageForThreadId(
|
|
232
|
+
ctx: MutationCtx,
|
|
233
|
+
args: { threadId: Id<"threads">; streamOrder?: number; deltaCursor?: string }
|
|
234
|
+
) {
|
|
235
|
+
const allStreamMessages =
|
|
236
|
+
schema.tables.streamingMessages.validator.fields.state.members
|
|
237
|
+
.flatMap((state) => state.fields.kind.value)
|
|
238
|
+
.map((stateKind) =>
|
|
239
|
+
stream(ctx.db, schema)
|
|
240
|
+
.query("streamingMessages")
|
|
241
|
+
.withIndex("threadId_state_order_stepOrder", (q) =>
|
|
242
|
+
q
|
|
243
|
+
.eq("threadId", args.threadId)
|
|
244
|
+
.eq("state.kind", stateKind)
|
|
245
|
+
.gte("order", args.streamOrder ?? 0)
|
|
246
|
+
)
|
|
247
|
+
);
|
|
248
|
+
let deltaCursor = args.deltaCursor;
|
|
249
|
+
const streamMessage = await mergedStream(allStreamMessages, [
|
|
250
|
+
"threadId",
|
|
251
|
+
"state.kind",
|
|
252
|
+
"order",
|
|
253
|
+
"stepOrder",
|
|
254
|
+
]).first();
|
|
255
|
+
if (!streamMessage) {
|
|
256
|
+
return {
|
|
257
|
+
isDone: true,
|
|
258
|
+
streamOrder: undefined,
|
|
259
|
+
deltaCursor: undefined,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
const result = await deletePageForStreamId(ctx, {
|
|
263
|
+
streamId: streamMessage._id,
|
|
264
|
+
cursor: deltaCursor,
|
|
265
|
+
});
|
|
266
|
+
if (result.isDone) {
|
|
267
|
+
await ctx.db.delete(streamMessage._id);
|
|
268
|
+
deltaCursor = undefined;
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
isDone: false,
|
|
272
|
+
streamOrder: streamMessage.order,
|
|
273
|
+
deltaCursor: result.continueCursor,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export const deleteStreamsPageForThreadIdMutation = internalMutation({
|
|
278
|
+
args: {
|
|
279
|
+
threadId: v.id("threads"),
|
|
280
|
+
streamOrder: v.optional(v.number()),
|
|
281
|
+
deltaCursor: v.optional(v.string()),
|
|
282
|
+
},
|
|
283
|
+
returns: v.object({
|
|
284
|
+
isDone: v.boolean(),
|
|
285
|
+
streamOrder: v.optional(v.number()),
|
|
286
|
+
deltaCursor: v.optional(v.string()),
|
|
287
|
+
}),
|
|
288
|
+
handler: deleteStreamsPageForThreadId,
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
export const deleteAllStreamsForThreadIdAsync = mutation({
|
|
292
|
+
args: {
|
|
293
|
+
threadId: v.id("threads"),
|
|
294
|
+
streamOrder: v.optional(v.number()),
|
|
295
|
+
deltaCursor: v.optional(v.string()),
|
|
296
|
+
},
|
|
297
|
+
returns: v.object({
|
|
298
|
+
isDone: v.boolean(),
|
|
299
|
+
streamOrder: v.optional(v.number()),
|
|
300
|
+
deltaCursor: v.optional(v.string()),
|
|
301
|
+
}),
|
|
302
|
+
handler: async (ctx, args) => {
|
|
303
|
+
const result = await deleteStreamsPageForThreadId(ctx, args);
|
|
304
|
+
if (!result.isDone) {
|
|
305
|
+
await ctx.scheduler.runAfter(
|
|
306
|
+
0,
|
|
307
|
+
api.streams.deleteAllStreamsForThreadIdAsync,
|
|
308
|
+
{
|
|
309
|
+
threadId: args.threadId,
|
|
310
|
+
streamOrder: result.streamOrder,
|
|
311
|
+
deltaCursor: result.deltaCursor,
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
} else {
|
|
315
|
+
await ctx.db.delete(args.threadId);
|
|
316
|
+
}
|
|
317
|
+
return result;
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
export const deleteStreamSync = mutation({
|
|
322
|
+
args: { streamId: v.id("streamingMessages") },
|
|
323
|
+
returns: v.null(),
|
|
324
|
+
handler: async (ctx, args) => {
|
|
325
|
+
let deltas = await deletePageForStreamId(ctx, args);
|
|
326
|
+
while (!deltas.isDone) {
|
|
327
|
+
deltas = await deletePageForStreamId(ctx, {
|
|
328
|
+
...args,
|
|
329
|
+
cursor: deltas.continueCursor,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
await ctx.db.delete(args.streamId);
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
export const deleteAllStreamsForThreadIdSync = action({
|
|
337
|
+
args: { threadId: v.id("threads") },
|
|
338
|
+
returns: v.null(),
|
|
339
|
+
handler: async (ctx, args) => {
|
|
340
|
+
let result = await ctx.runMutation(
|
|
341
|
+
internal.streams.deleteStreamsPageForThreadIdMutation,
|
|
342
|
+
args
|
|
343
|
+
);
|
|
344
|
+
while (!result.isDone) {
|
|
345
|
+
result = await ctx.runMutation(
|
|
346
|
+
internal.streams.deleteStreamsPageForThreadIdMutation,
|
|
347
|
+
{
|
|
348
|
+
...args,
|
|
349
|
+
streamOrder: result.streamOrder,
|
|
350
|
+
deltaCursor: result.deltaCursor,
|
|
351
|
+
}
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
});
|
package/src/component/threads.ts
CHANGED
|
@@ -131,6 +131,9 @@ export const deleteAllForThreadIdSync = action({
|
|
|
131
131
|
}
|
|
132
132
|
cursor = result.cursor;
|
|
133
133
|
}
|
|
134
|
+
await ctx.runAction(api.streams.deleteAllStreamsForThreadIdSync, {
|
|
135
|
+
threadId: args.threadId,
|
|
136
|
+
});
|
|
134
137
|
},
|
|
135
138
|
returns: v.null(),
|
|
136
139
|
});
|
|
@@ -154,6 +157,11 @@ export const deleteAllForThreadIdAsync = mutation({
|
|
|
154
157
|
threadId: args.threadId,
|
|
155
158
|
cursor: result.cursor,
|
|
156
159
|
});
|
|
160
|
+
} else {
|
|
161
|
+
// Kick off the streams deletion
|
|
162
|
+
await ctx.scheduler.runAfter(0, api.threads.deleteAllForThreadIdSync, {
|
|
163
|
+
threadId: args.threadId,
|
|
164
|
+
});
|
|
157
165
|
}
|
|
158
166
|
return result;
|
|
159
167
|
},
|
package/src/component/users.ts
CHANGED
|
@@ -156,6 +156,7 @@ async function deletePageForUserId(
|
|
|
156
156
|
});
|
|
157
157
|
await Promise.all(messages.page.map((m) => deleteMessage(ctx, m)));
|
|
158
158
|
if (messages.isDone) {
|
|
159
|
+
// TODO: delete streams - maybe use workpool?
|
|
159
160
|
await ctx.db.delete(threadInProgress);
|
|
160
161
|
threadInProgress = null;
|
|
161
162
|
messagesCursor = null;
|
|
@@ -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
|
},
|
package/src/react/index.ts
CHANGED
|
@@ -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 "
|
|
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";
|