@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.
- package/README.md +159 -98
- package/dist/commonjs/client/index.d.ts +806 -189
- package/dist/commonjs/client/index.d.ts.map +1 -1
- package/dist/commonjs/client/index.js +178 -28
- package/dist/commonjs/client/index.js.map +1 -1
- package/dist/commonjs/client/playground.d.ts +609 -0
- package/dist/commonjs/client/playground.d.ts.map +1 -0
- package/dist/commonjs/client/playground.js +200 -0
- package/dist/commonjs/client/playground.js.map +1 -0
- package/dist/commonjs/component/apiKeys.d.ts +11 -0
- package/dist/commonjs/component/apiKeys.d.ts.map +1 -0
- package/dist/commonjs/component/apiKeys.js +69 -0
- package/dist/commonjs/component/apiKeys.js.map +1 -0
- package/dist/commonjs/component/files.d.ts +31 -0
- package/dist/commonjs/component/files.d.ts.map +1 -0
- package/dist/commonjs/component/files.js +61 -0
- package/dist/commonjs/component/files.js.map +1 -0
- package/dist/commonjs/component/messages.d.ts +720 -676
- package/dist/commonjs/component/messages.d.ts.map +1 -1
- package/dist/commonjs/component/messages.js +99 -287
- package/dist/commonjs/component/messages.js.map +1 -1
- package/dist/commonjs/component/schema.d.ts +1124 -1324
- package/dist/commonjs/component/schema.d.ts.map +1 -1
- package/dist/commonjs/component/schema.js +26 -14
- package/dist/commonjs/component/schema.js.map +1 -1
- package/dist/commonjs/component/threads.d.ts +95 -0
- package/dist/commonjs/component/threads.d.ts.map +1 -0
- package/dist/commonjs/component/threads.js +151 -0
- package/dist/commonjs/component/threads.js.map +1 -0
- package/dist/commonjs/component/users.d.ts +37 -0
- package/dist/commonjs/component/users.d.ts.map +1 -0
- package/dist/commonjs/component/users.js +118 -0
- package/dist/commonjs/component/users.js.map +1 -0
- package/dist/commonjs/component/vector/index.d.ts.map +1 -1
- package/dist/commonjs/component/vector/index.js +4 -6
- package/dist/commonjs/component/vector/index.js.map +1 -1
- package/dist/commonjs/component/vector/tables.d.ts +10 -10
- package/dist/commonjs/component/vector/tables.d.ts.map +1 -1
- package/dist/commonjs/component/vector/tables.js.map +1 -1
- package/dist/commonjs/mapping.d.ts +7 -1
- package/dist/commonjs/mapping.d.ts.map +1 -1
- package/dist/commonjs/mapping.js +39 -18
- package/dist/commonjs/mapping.js.map +1 -1
- package/dist/commonjs/validators.d.ts +1669 -2340
- package/dist/commonjs/validators.d.ts.map +1 -1
- package/dist/commonjs/validators.js +35 -26
- package/dist/commonjs/validators.js.map +1 -1
- package/dist/esm/client/index.d.ts +806 -189
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +178 -28
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/client/playground.d.ts +609 -0
- package/dist/esm/client/playground.d.ts.map +1 -0
- package/dist/esm/client/playground.js +200 -0
- package/dist/esm/client/playground.js.map +1 -0
- package/dist/esm/component/apiKeys.d.ts +11 -0
- package/dist/esm/component/apiKeys.d.ts.map +1 -0
- package/dist/esm/component/apiKeys.js +69 -0
- package/dist/esm/component/apiKeys.js.map +1 -0
- package/dist/esm/component/files.d.ts +31 -0
- package/dist/esm/component/files.d.ts.map +1 -0
- package/dist/esm/component/files.js +61 -0
- package/dist/esm/component/files.js.map +1 -0
- package/dist/esm/component/messages.d.ts +720 -676
- package/dist/esm/component/messages.d.ts.map +1 -1
- package/dist/esm/component/messages.js +99 -287
- package/dist/esm/component/messages.js.map +1 -1
- package/dist/esm/component/schema.d.ts +1124 -1324
- package/dist/esm/component/schema.d.ts.map +1 -1
- package/dist/esm/component/schema.js +26 -14
- package/dist/esm/component/schema.js.map +1 -1
- package/dist/esm/component/threads.d.ts +95 -0
- package/dist/esm/component/threads.d.ts.map +1 -0
- package/dist/esm/component/threads.js +151 -0
- package/dist/esm/component/threads.js.map +1 -0
- package/dist/esm/component/users.d.ts +37 -0
- package/dist/esm/component/users.d.ts.map +1 -0
- package/dist/esm/component/users.js +118 -0
- package/dist/esm/component/users.js.map +1 -0
- package/dist/esm/component/vector/index.d.ts.map +1 -1
- package/dist/esm/component/vector/index.js +4 -6
- package/dist/esm/component/vector/index.js.map +1 -1
- package/dist/esm/component/vector/tables.d.ts +10 -10
- package/dist/esm/component/vector/tables.d.ts.map +1 -1
- package/dist/esm/component/vector/tables.js.map +1 -1
- package/dist/esm/mapping.d.ts +7 -1
- package/dist/esm/mapping.d.ts.map +1 -1
- package/dist/esm/mapping.js +39 -18
- package/dist/esm/mapping.js.map +1 -1
- package/dist/esm/validators.d.ts +1669 -2340
- package/dist/esm/validators.d.ts.map +1 -1
- package/dist/esm/validators.js +35 -26
- package/dist/esm/validators.js.map +1 -1
- package/package.json +8 -1
- package/src/client/index.ts +220 -59
- package/src/client/playground.ts +257 -0
- package/src/component/_generated/api.d.ts +601 -400
- package/src/component/apiKeys.ts +74 -0
- package/src/component/files.ts +72 -0
- package/src/component/messages.test.ts +23 -0
- package/src/component/messages.ts +127 -341
- package/src/component/schema.ts +32 -13
- package/src/component/threads.ts +184 -0
- package/src/component/users.ts +145 -0
- package/src/component/vector/index.ts +5 -6
- package/src/component/vector/tables.ts +15 -15
- package/src/mapping.ts +65 -32
- package/src/validators.ts +47 -28
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/component/messages.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/component/messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,251 +1,34 @@
|
|
|
1
|
-
import { assert
|
|
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,
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
167
|
-
|
|
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(
|
|
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
|
-
|
|
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,
|
|
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 (
|
|
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
|
-
|
|
106
|
+
files,
|
|
319
107
|
status: pending ? "pending" : "success",
|
|
320
|
-
stepOrder
|
|
108
|
+
stepOrder,
|
|
321
109
|
});
|
|
322
|
-
if (
|
|
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
|
-
|
|
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",
|
|
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
|
-
|
|
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",
|
|
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
|
-
|
|
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.
|
|
375
|
-
assert(parentMessage, `Message ${args.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
261
|
+
export const listMessagesByThreadId = query({
|
|
479
262
|
args: {
|
|
480
263
|
threadId: v.id("threads"),
|
|
481
|
-
|
|
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
|
-
|
|
270
|
+
beforeMessageId: v.optional(v.id("messages")),
|
|
486
271
|
},
|
|
487
272
|
handler: async (ctx, args) => {
|
|
488
|
-
const statuses = args.statuses ??
|
|
489
|
-
const
|
|
490
|
-
const toolOptions = args.
|
|
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 (
|
|
500
|
-
return qq.lte("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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
(!
|
|
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) =>
|
|
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
|
});
|