@convex-dev/agent 0.0.16-alpha.0 → 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 +92 -71
- package/dist/commonjs/client/index.d.ts +1012 -920
- package/dist/commonjs/client/index.d.ts.map +1 -1
- package/dist/commonjs/client/index.js +188 -31
- package/dist/commonjs/client/index.js.map +1 -1
- package/dist/commonjs/client/playground.d.ts +251 -116
- package/dist/commonjs/client/playground.d.ts.map +1 -1
- package/dist/commonjs/client/playground.js +33 -11
- package/dist/commonjs/client/playground.js.map +1 -1
- package/dist/commonjs/component/messages.d.ts +683 -571
- package/dist/commonjs/component/messages.d.ts.map +1 -1
- package/dist/commonjs/component/messages.js +56 -33
- package/dist/commonjs/component/messages.js.map +1 -1
- package/dist/commonjs/component/schema.d.ts +1080 -1324
- package/dist/commonjs/component/schema.d.ts.map +1 -1
- package/dist/commonjs/component/schema.js +20 -14
- package/dist/commonjs/component/schema.js.map +1 -1
- 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 -2336
- package/dist/commonjs/validators.d.ts.map +1 -1
- package/dist/commonjs/validators.js +35 -25
- package/dist/commonjs/validators.js.map +1 -1
- package/dist/esm/client/index.d.ts +1012 -920
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +188 -31
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/client/playground.d.ts +251 -116
- package/dist/esm/client/playground.d.ts.map +1 -1
- package/dist/esm/client/playground.js +33 -11
- package/dist/esm/client/playground.js.map +1 -1
- package/dist/esm/component/messages.d.ts +683 -571
- package/dist/esm/component/messages.d.ts.map +1 -1
- package/dist/esm/component/messages.js +56 -33
- package/dist/esm/component/messages.js.map +1 -1
- package/dist/esm/component/schema.d.ts +1080 -1324
- package/dist/esm/component/schema.d.ts.map +1 -1
- package/dist/esm/component/schema.js +20 -14
- package/dist/esm/component/schema.js.map +1 -1
- 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 -2336
- package/dist/esm/validators.d.ts.map +1 -1
- package/dist/esm/validators.js +35 -25
- package/dist/esm/validators.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.test.ts +68 -0
- package/src/client/index.ts +219 -35
- package/src/client/playground.ts +49 -23
- package/src/component/_generated/api.d.ts +311 -323
- package/src/component/messages.test.ts +23 -0
- package/src/component/messages.ts +75 -42
- package/src/component/schema.ts +26 -13
- 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 -27
package/src/client/index.ts
CHANGED
|
@@ -15,7 +15,9 @@ import type {
|
|
|
15
15
|
ToolChoice,
|
|
16
16
|
ToolExecutionOptions,
|
|
17
17
|
ToolSet,
|
|
18
|
+
UIMessage,
|
|
18
19
|
} from "ai";
|
|
20
|
+
import type { ToolInvocationUIPart } from "@ai-sdk/ui-utils";
|
|
19
21
|
import {
|
|
20
22
|
generateObject,
|
|
21
23
|
generateText,
|
|
@@ -40,6 +42,7 @@ import {
|
|
|
40
42
|
serializeNewMessagesInStep,
|
|
41
43
|
serializeObjectResult,
|
|
42
44
|
serializeStep,
|
|
45
|
+
toUIFilePart,
|
|
43
46
|
} from "../mapping.js";
|
|
44
47
|
import {
|
|
45
48
|
DEFAULT_MESSAGE_RANGE,
|
|
@@ -49,16 +52,18 @@ import {
|
|
|
49
52
|
} from "../shared.js";
|
|
50
53
|
import {
|
|
51
54
|
type CallSettings,
|
|
52
|
-
MessageWithMetadata,
|
|
55
|
+
type MessageWithMetadata as InnerMessageWithMetadata,
|
|
53
56
|
type ProviderMetadata,
|
|
54
57
|
type ProviderOptions,
|
|
55
58
|
type SearchOptions,
|
|
56
59
|
type Usage,
|
|
60
|
+
vFileWithStringId,
|
|
57
61
|
vSafeObjectArgs,
|
|
58
62
|
vTextArgs,
|
|
59
63
|
vThreadStatus,
|
|
60
64
|
} from "../validators.js";
|
|
61
65
|
import type {
|
|
66
|
+
OpaqueIds,
|
|
62
67
|
RunActionCtx,
|
|
63
68
|
RunMutationCtx,
|
|
64
69
|
RunQueryCtx,
|
|
@@ -69,39 +74,18 @@ import schema from "../component/schema.js";
|
|
|
69
74
|
export { extractText, isTool };
|
|
70
75
|
export type { Usage, ProviderMetadata };
|
|
71
76
|
export {
|
|
77
|
+
paginationResultValidator,
|
|
78
|
+
vContextOptions,
|
|
72
79
|
vUsage,
|
|
73
80
|
vProviderMetadata,
|
|
74
81
|
vUserMessage,
|
|
75
82
|
vAssistantMessage,
|
|
76
83
|
vToolMessage,
|
|
84
|
+
vStorageOptions,
|
|
77
85
|
vSystemMessage,
|
|
78
86
|
vMessage,
|
|
79
87
|
} from "../validators.js";
|
|
80
88
|
|
|
81
|
-
export const vThreadDoc = v.object({
|
|
82
|
-
_id: v.string(),
|
|
83
|
-
_creationTime: v.number(),
|
|
84
|
-
userId: v.optional(v.string()), // Unset for anonymous
|
|
85
|
-
title: v.optional(v.string()),
|
|
86
|
-
summary: v.optional(v.string()),
|
|
87
|
-
status: vThreadStatus,
|
|
88
|
-
});
|
|
89
|
-
export type ThreadDoc = Infer<typeof vThreadDoc>;
|
|
90
|
-
|
|
91
|
-
export const vMessageDoc = v.object({
|
|
92
|
-
_id: v.string(),
|
|
93
|
-
_creationTime: v.number(),
|
|
94
|
-
...schema.tables.messages.validator.fields,
|
|
95
|
-
// Overwrite all the types that have a v.id validator
|
|
96
|
-
// Outside of the component, they are strings
|
|
97
|
-
threadId: v.string(),
|
|
98
|
-
parentMessageId: v.optional(v.string()),
|
|
99
|
-
stepId: v.optional(v.string()),
|
|
100
|
-
embeddingId: v.optional(v.string()),
|
|
101
|
-
fileId: v.optional(v.string()),
|
|
102
|
-
});
|
|
103
|
-
export type MessageDoc = Infer<typeof vMessageDoc>;
|
|
104
|
-
|
|
105
89
|
/**
|
|
106
90
|
* Options to configure what messages are fetched as context,
|
|
107
91
|
* automatically with thread.generateText, or directly via search.
|
|
@@ -188,9 +172,11 @@ export type UsageHandler = (
|
|
|
188
172
|
}
|
|
189
173
|
) => void | Promise<void>;
|
|
190
174
|
|
|
175
|
+
export type AgentComponent = UseApi<Mounts>;
|
|
176
|
+
|
|
191
177
|
export class Agent<AgentTools extends ToolSet> {
|
|
192
178
|
constructor(
|
|
193
|
-
public component:
|
|
179
|
+
public component: AgentComponent,
|
|
194
180
|
public options: {
|
|
195
181
|
/**
|
|
196
182
|
* The name for the agent. This will be attributed on each message
|
|
@@ -439,7 +425,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
439
425
|
beforeMessageId?: string;
|
|
440
426
|
contextOptions: ContextOptions | undefined;
|
|
441
427
|
}
|
|
442
|
-
): Promise<
|
|
428
|
+
): Promise<MessageDoc[]> {
|
|
443
429
|
assert(args.userId || args.threadId, "Specify userId or threadId");
|
|
444
430
|
// Fetch the latest messages from the thread
|
|
445
431
|
const contextMessages: MessageDoc[] = [];
|
|
@@ -452,9 +438,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
452
438
|
const searchMessages = await ctx.runAction(
|
|
453
439
|
this.component.messages.searchMessages,
|
|
454
440
|
{
|
|
455
|
-
userId: args.
|
|
456
|
-
? args.userId
|
|
457
|
-
: undefined,
|
|
441
|
+
userId: opts?.searchOtherThreads ? args.userId : undefined,
|
|
458
442
|
threadId: args.threadId,
|
|
459
443
|
beforeMessageId: args.beforeMessageId,
|
|
460
444
|
...(await this.searchOptionsWithDefaults(opts, args.messages)),
|
|
@@ -480,13 +464,18 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
480
464
|
statuses: ["success"],
|
|
481
465
|
}
|
|
482
466
|
);
|
|
483
|
-
contextMessages.push(
|
|
467
|
+
contextMessages.push(
|
|
468
|
+
// Reverse since we fetched in descending order
|
|
469
|
+
...page.filter((m) => !included?.has(m._id)).reverse()
|
|
470
|
+
);
|
|
484
471
|
}
|
|
485
|
-
|
|
486
|
-
|
|
472
|
+
// Ensure we don't include tool messages without a corresponding tool call
|
|
473
|
+
return filterOutOrphanedToolMessages(
|
|
474
|
+
contextMessages.sort((a, b) =>
|
|
475
|
+
// Sort the raw MessageDocs by order and stepOrder
|
|
487
476
|
a.order === b.order ? a.stepOrder - b.stepOrder : a.order - b.order
|
|
488
477
|
)
|
|
489
|
-
|
|
478
|
+
);
|
|
490
479
|
}
|
|
491
480
|
|
|
492
481
|
/**
|
|
@@ -948,7 +937,10 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
948
937
|
args: {
|
|
949
938
|
...rest,
|
|
950
939
|
system: args.system ?? this.options.instructions,
|
|
951
|
-
messages: [
|
|
940
|
+
messages: [
|
|
941
|
+
...contextMessages.map((m) => deserializeMessage(m.message!)),
|
|
942
|
+
...messages,
|
|
943
|
+
],
|
|
952
944
|
} as T,
|
|
953
945
|
messageId,
|
|
954
946
|
};
|
|
@@ -1322,6 +1314,34 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1322
1314
|
}
|
|
1323
1315
|
}
|
|
1324
1316
|
|
|
1317
|
+
export function filterOutOrphanedToolMessages(docs: MessageDoc[]) {
|
|
1318
|
+
const toolCallIds = new Set<string>();
|
|
1319
|
+
const result: MessageDoc[] = [];
|
|
1320
|
+
for (const doc of docs) {
|
|
1321
|
+
if (
|
|
1322
|
+
doc.message?.role === "assistant" &&
|
|
1323
|
+
Array.isArray(doc.message.content)
|
|
1324
|
+
) {
|
|
1325
|
+
for (const content of doc.message.content) {
|
|
1326
|
+
if (content.type === "tool-call") {
|
|
1327
|
+
toolCallIds.add(content.toolCallId);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
result.push(doc);
|
|
1331
|
+
} else if (doc.message?.role === "tool") {
|
|
1332
|
+
if (doc.message.content.every((c) => toolCallIds.has(c.toolCallId))) {
|
|
1333
|
+
result.push(doc);
|
|
1334
|
+
} else {
|
|
1335
|
+
console.debug("Filtering out orphaned tool message", doc);
|
|
1336
|
+
}
|
|
1337
|
+
} else {
|
|
1338
|
+
result.push(doc);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
return result;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
|
|
1325
1345
|
export type ToolCtx = RunActionCtx & {
|
|
1326
1346
|
userId?: string;
|
|
1327
1347
|
threadId?: string;
|
|
@@ -1703,3 +1723,167 @@ interface Thread<DefaultTools extends ToolSet> {
|
|
|
1703
1723
|
StreamObjectResult<DeepPartial<T>, T, never> & ThreadOutputMetadata
|
|
1704
1724
|
>;
|
|
1705
1725
|
}
|
|
1726
|
+
|
|
1727
|
+
export const vThreadDoc = v.object({
|
|
1728
|
+
_id: v.string(),
|
|
1729
|
+
_creationTime: v.number(),
|
|
1730
|
+
userId: v.optional(v.string()), // Unset for anonymous
|
|
1731
|
+
title: v.optional(v.string()),
|
|
1732
|
+
summary: v.optional(v.string()),
|
|
1733
|
+
status: vThreadStatus,
|
|
1734
|
+
});
|
|
1735
|
+
export type ThreadDoc = Infer<typeof vThreadDoc>;
|
|
1736
|
+
|
|
1737
|
+
export const vMessageDoc = v.object({
|
|
1738
|
+
_id: v.string(),
|
|
1739
|
+
_creationTime: v.number(),
|
|
1740
|
+
...schema.tables.messages.validator.fields,
|
|
1741
|
+
// Overwrite all the types that have a v.id validator
|
|
1742
|
+
// Outside of the component, they are strings
|
|
1743
|
+
threadId: v.string(),
|
|
1744
|
+
parentMessageId: v.optional(v.string()),
|
|
1745
|
+
stepId: v.optional(v.string()),
|
|
1746
|
+
embeddingId: v.optional(v.string()),
|
|
1747
|
+
files: v.optional(v.array(vFileWithStringId)),
|
|
1748
|
+
});
|
|
1749
|
+
export type MessageDoc = Infer<typeof vMessageDoc>;
|
|
1750
|
+
|
|
1751
|
+
type MessageWithMetadata = OpaqueIds<InnerMessageWithMetadata>;
|
|
1752
|
+
|
|
1753
|
+
export function toUIMessages(messages: MessageDoc[]): UIMessage[] {
|
|
1754
|
+
const uiMessages: UIMessage[] = [];
|
|
1755
|
+
let assistantMessage: UIMessage | undefined;
|
|
1756
|
+
for (const message of messages) {
|
|
1757
|
+
const coreMessage = message.message && deserializeMessage(message.message);
|
|
1758
|
+
const text = message.text ?? "";
|
|
1759
|
+
const content = coreMessage?.content;
|
|
1760
|
+
const nonStringContent =
|
|
1761
|
+
content && typeof content !== "string" ? content : [];
|
|
1762
|
+
if (!coreMessage) continue;
|
|
1763
|
+
if (coreMessage.role === "system") {
|
|
1764
|
+
uiMessages.push({
|
|
1765
|
+
id: message.id ?? message._id,
|
|
1766
|
+
createdAt: new Date(message._creationTime),
|
|
1767
|
+
role: "system",
|
|
1768
|
+
content: text,
|
|
1769
|
+
parts: [{ type: "text", text }],
|
|
1770
|
+
});
|
|
1771
|
+
} else if (coreMessage.role === "user") {
|
|
1772
|
+
const parts: UIMessage["parts"] = [];
|
|
1773
|
+
if (text) {
|
|
1774
|
+
parts.push({ type: "text", text });
|
|
1775
|
+
}
|
|
1776
|
+
if (message.files) {
|
|
1777
|
+
parts.push(...message.files.map(toUIFilePart));
|
|
1778
|
+
}
|
|
1779
|
+
uiMessages.push({
|
|
1780
|
+
id: message.id ?? message._id,
|
|
1781
|
+
createdAt: new Date(message._creationTime),
|
|
1782
|
+
role: "user",
|
|
1783
|
+
content: message.text ?? "",
|
|
1784
|
+
parts,
|
|
1785
|
+
});
|
|
1786
|
+
} else {
|
|
1787
|
+
if (coreMessage.role === "tool" && !assistantMessage) {
|
|
1788
|
+
console.warn(
|
|
1789
|
+
"Tool message without preceding assistant message.. skipping",
|
|
1790
|
+
message
|
|
1791
|
+
);
|
|
1792
|
+
continue;
|
|
1793
|
+
}
|
|
1794
|
+
if (!assistantMessage) {
|
|
1795
|
+
assistantMessage = {
|
|
1796
|
+
id: message.id ?? message._id,
|
|
1797
|
+
createdAt: new Date(message._creationTime),
|
|
1798
|
+
role: "assistant",
|
|
1799
|
+
content: message.text ?? "",
|
|
1800
|
+
parts: [],
|
|
1801
|
+
};
|
|
1802
|
+
uiMessages.push(assistantMessage);
|
|
1803
|
+
}
|
|
1804
|
+
// update it to the last message's id
|
|
1805
|
+
assistantMessage.id = message.id ?? message._id;
|
|
1806
|
+
if (message.text) {
|
|
1807
|
+
assistantMessage.parts.push({
|
|
1808
|
+
type: "text",
|
|
1809
|
+
text: message.text,
|
|
1810
|
+
});
|
|
1811
|
+
assistantMessage.content += message.text;
|
|
1812
|
+
}
|
|
1813
|
+
if (message.reasoning) {
|
|
1814
|
+
assistantMessage.parts.push({
|
|
1815
|
+
type: "reasoning",
|
|
1816
|
+
reasoning: message.reasoning,
|
|
1817
|
+
details: message.reasoningDetails ?? [],
|
|
1818
|
+
});
|
|
1819
|
+
}
|
|
1820
|
+
for (const source of message.sources ?? []) {
|
|
1821
|
+
assistantMessage.parts.push({
|
|
1822
|
+
type: "source",
|
|
1823
|
+
source,
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
1826
|
+
for (const file of message.files ?? []) {
|
|
1827
|
+
assistantMessage.parts.push(toUIFilePart(file));
|
|
1828
|
+
}
|
|
1829
|
+
for (const contentPart of nonStringContent) {
|
|
1830
|
+
switch (contentPart.type) {
|
|
1831
|
+
case "tool-call":
|
|
1832
|
+
assistantMessage.parts.push({
|
|
1833
|
+
type: "step-start",
|
|
1834
|
+
});
|
|
1835
|
+
assistantMessage.parts.push({
|
|
1836
|
+
type: "tool-invocation",
|
|
1837
|
+
toolInvocation: {
|
|
1838
|
+
state: "call",
|
|
1839
|
+
step: assistantMessage.parts.filter(
|
|
1840
|
+
(part) => part.type === "tool-invocation"
|
|
1841
|
+
).length,
|
|
1842
|
+
toolCallId: contentPart.toolCallId,
|
|
1843
|
+
toolName: contentPart.toolName,
|
|
1844
|
+
args: contentPart.args,
|
|
1845
|
+
},
|
|
1846
|
+
});
|
|
1847
|
+
break;
|
|
1848
|
+
case "tool-result": {
|
|
1849
|
+
const call = assistantMessage.parts.find(
|
|
1850
|
+
(part) =>
|
|
1851
|
+
part.type === "tool-invocation" &&
|
|
1852
|
+
part.toolInvocation.toolCallId === contentPart.toolCallId
|
|
1853
|
+
) as ToolInvocationUIPart | undefined;
|
|
1854
|
+
const toolInvocation: ToolInvocationUIPart["toolInvocation"] = {
|
|
1855
|
+
state: "result",
|
|
1856
|
+
toolCallId: contentPart.toolCallId,
|
|
1857
|
+
toolName: contentPart.toolName,
|
|
1858
|
+
args: call?.toolInvocation.args,
|
|
1859
|
+
result: contentPart.result,
|
|
1860
|
+
step:
|
|
1861
|
+
call?.toolInvocation.step ??
|
|
1862
|
+
assistantMessage.parts.filter(
|
|
1863
|
+
(part) => part.type === "tool-invocation"
|
|
1864
|
+
).length,
|
|
1865
|
+
};
|
|
1866
|
+
if (call) {
|
|
1867
|
+
(call as ToolInvocationUIPart).toolInvocation = toolInvocation;
|
|
1868
|
+
} else {
|
|
1869
|
+
console.warn(
|
|
1870
|
+
"Tool result without preceding tool call.. adding anyways",
|
|
1871
|
+
contentPart
|
|
1872
|
+
);
|
|
1873
|
+
assistantMessage.parts.push({
|
|
1874
|
+
type: "tool-invocation",
|
|
1875
|
+
toolInvocation,
|
|
1876
|
+
});
|
|
1877
|
+
}
|
|
1878
|
+
break;
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
if (!message.tool) {
|
|
1883
|
+
// Reset it so the next set of tool calls will create a new assistant message
|
|
1884
|
+
assistantMessage = undefined;
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
return uiMessages;
|
|
1889
|
+
}
|
package/src/client/playground.ts
CHANGED
|
@@ -5,35 +5,34 @@ import {
|
|
|
5
5
|
actionGeneric,
|
|
6
6
|
GenericDataModel,
|
|
7
7
|
GenericQueryCtx,
|
|
8
|
-
FilterApi,
|
|
9
|
-
FunctionReference,
|
|
10
8
|
ApiFromModules,
|
|
11
9
|
} from "convex/server";
|
|
12
|
-
import { vThreadDoc, type Agent } from "./index";
|
|
13
|
-
import type { RunQueryCtx, UseApi } from "./types";
|
|
14
|
-
import type { ToolSet } from "ai";
|
|
15
|
-
import { v } from "convex/values";
|
|
16
|
-
import { Mounts } from "../component/_generated/api";
|
|
17
10
|
import {
|
|
11
|
+
vMessageDoc,
|
|
12
|
+
vThreadDoc,
|
|
18
13
|
paginationResultValidator,
|
|
19
|
-
vContextOptions,
|
|
20
14
|
vMessage,
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
vContextOptions,
|
|
16
|
+
vStorageOptions,
|
|
17
|
+
type AgentComponent,
|
|
18
|
+
type Agent,
|
|
19
|
+
} from "./index";
|
|
20
|
+
import type { ToolSet } from "ai";
|
|
21
|
+
import { v } from "convex/values";
|
|
23
22
|
|
|
24
23
|
export type PlaygroundAPI = ApiFromModules<{
|
|
25
|
-
playground: ReturnType<typeof definePlaygroundAPI
|
|
24
|
+
playground: ReturnType<typeof definePlaygroundAPI>;
|
|
26
25
|
}>["playground"];
|
|
27
26
|
|
|
28
27
|
// Playground API definition
|
|
29
|
-
export function definePlaygroundAPI
|
|
30
|
-
component:
|
|
28
|
+
export function definePlaygroundAPI(
|
|
29
|
+
component: AgentComponent,
|
|
31
30
|
{
|
|
32
31
|
agents,
|
|
33
32
|
userNameLookup,
|
|
34
33
|
}: {
|
|
35
34
|
agents: Agent<ToolSet>[];
|
|
36
|
-
userNameLookup?: (
|
|
35
|
+
userNameLookup?: <DataModel extends GenericDataModel>(
|
|
37
36
|
ctx: GenericQueryCtx<DataModel>,
|
|
38
37
|
userId: string
|
|
39
38
|
) => string | Promise<string>;
|
|
@@ -48,6 +47,22 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
48
47
|
await ctx.runQuery(component.apiKeys.validate, { apiKey });
|
|
49
48
|
}
|
|
50
49
|
|
|
50
|
+
const isApiKeyValid = queryGeneric({
|
|
51
|
+
args: {
|
|
52
|
+
apiKey: v.string(),
|
|
53
|
+
},
|
|
54
|
+
handler: async (ctx, args) => {
|
|
55
|
+
try {
|
|
56
|
+
await validateApiKey(ctx, args.apiKey);
|
|
57
|
+
return true;
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
59
|
+
} catch (e) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
returns: v.boolean(),
|
|
64
|
+
});
|
|
65
|
+
|
|
51
66
|
// List all agents
|
|
52
67
|
const listAgents = queryGeneric({
|
|
53
68
|
args: {
|
|
@@ -74,7 +89,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
74
89
|
...users,
|
|
75
90
|
page: await Promise.all(
|
|
76
91
|
users.page.map(async (userId) => ({
|
|
77
|
-
|
|
92
|
+
_id: userId,
|
|
78
93
|
name: userNameLookup ? await userNameLookup(ctx, userId) : userId,
|
|
79
94
|
}))
|
|
80
95
|
),
|
|
@@ -82,7 +97,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
82
97
|
},
|
|
83
98
|
returns: paginationResultValidator(
|
|
84
99
|
v.object({
|
|
85
|
-
|
|
100
|
+
_id: v.string(),
|
|
86
101
|
name: v.string(),
|
|
87
102
|
})
|
|
88
103
|
),
|
|
@@ -128,6 +143,13 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
128
143
|
),
|
|
129
144
|
};
|
|
130
145
|
},
|
|
146
|
+
returns: paginationResultValidator(
|
|
147
|
+
v.object({
|
|
148
|
+
...vThreadDoc.fields,
|
|
149
|
+
latestMessage: v.optional(v.string()),
|
|
150
|
+
lastMessageAt: v.optional(v.number()),
|
|
151
|
+
})
|
|
152
|
+
),
|
|
131
153
|
});
|
|
132
154
|
|
|
133
155
|
// List messages for a thread (query)
|
|
@@ -146,6 +168,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
146
168
|
statuses: ["success", "failed", "pending"],
|
|
147
169
|
});
|
|
148
170
|
},
|
|
171
|
+
returns: paginationResultValidator(vMessageDoc),
|
|
149
172
|
});
|
|
150
173
|
|
|
151
174
|
// Create a thread (mutation)
|
|
@@ -167,6 +190,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
167
190
|
summary: args.summary,
|
|
168
191
|
});
|
|
169
192
|
},
|
|
193
|
+
returns: v.object({ threadId: v.string() }),
|
|
170
194
|
});
|
|
171
195
|
|
|
172
196
|
// Send a message (action)
|
|
@@ -176,20 +200,19 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
176
200
|
agentName: v.string(),
|
|
177
201
|
userId: v.string(),
|
|
178
202
|
threadId: v.string(),
|
|
203
|
+
// Args passed through to generateText
|
|
179
204
|
prompt: v.optional(v.string()),
|
|
180
205
|
messages: v.optional(v.array(vMessage)),
|
|
181
|
-
|
|
206
|
+
contextOptions: v.optional(vContextOptions),
|
|
207
|
+
storageOptions: v.optional(vStorageOptions),
|
|
182
208
|
},
|
|
183
209
|
handler: async (ctx, args) => {
|
|
184
|
-
|
|
185
|
-
|
|
210
|
+
const { apiKey, agentName, userId, threadId, ...rest } = args;
|
|
211
|
+
await validateApiKey(ctx, apiKey);
|
|
186
212
|
const agent = agentMap[agentName];
|
|
187
213
|
if (!agent) throw new Error(`Unknown agent: ${agentName}`);
|
|
188
214
|
const { thread } = await agent.continueThread(ctx, { threadId, userId });
|
|
189
|
-
|
|
190
|
-
assert(messages || prompt, "Must provide either messages or prompt");
|
|
191
|
-
assert(!messages || !prompt, "Provide messages or prompt, not both");
|
|
192
|
-
const result = await thread.generateText({ prompt, messages });
|
|
215
|
+
const result = await thread.generateText(rest);
|
|
193
216
|
return result;
|
|
194
217
|
},
|
|
195
218
|
});
|
|
@@ -220,6 +243,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
220
243
|
});
|
|
221
244
|
|
|
222
245
|
return {
|
|
246
|
+
isApiKeyValid,
|
|
223
247
|
listUsers,
|
|
224
248
|
listThreads,
|
|
225
249
|
listMessages,
|
|
@@ -229,3 +253,5 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
229
253
|
fetchPromptContext,
|
|
230
254
|
};
|
|
231
255
|
}
|
|
256
|
+
|
|
257
|
+
type RunQueryCtx = { runQuery: GenericQueryCtx<GenericDataModel>["runQuery"] };
|