@convex-dev/agent 0.6.4 → 0.7.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +60 -116
- package/dist/client/messages.d.ts +1 -398
- package/dist/client/messages.d.ts.map +1 -1
- package/dist/client/messages.js +3 -47
- package/dist/client/messages.js.map +1 -1
- package/dist/client/types.d.ts +1 -455
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/component.d.ts +805 -45
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/messages.d.ts +1252 -201
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +49 -23
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +2593 -332
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/streams.d.ts +7 -1
- package/dist/component/streams.d.ts.map +1 -1
- package/dist/component/streams.js +24 -30
- package/dist/component/streams.js.map +1 -1
- package/dist/component/threads.d.ts.map +1 -1
- package/dist/component/threads.js +1 -2
- package/dist/component/threads.js.map +1 -1
- package/dist/react/index.d.ts +5 -5
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -5
- package/dist/react/index.js.map +1 -1
- package/dist/shared.d.ts +19 -7
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +4 -4
- package/dist/shared.js.map +1 -1
- package/dist/streaming/materializePersistedUIMessageChunks.d.ts +16 -0
- package/dist/streaming/materializePersistedUIMessageChunks.d.ts.map +1 -0
- package/dist/streaming/materializePersistedUIMessageChunks.js +302 -0
- package/dist/streaming/materializePersistedUIMessageChunks.js.map +1 -0
- package/dist/streaming/persistedUIMessageChunks.d.ts +106 -0
- package/dist/streaming/persistedUIMessageChunks.d.ts.map +1 -0
- package/dist/streaming/persistedUIMessageChunks.js +475 -0
- package/dist/streaming/persistedUIMessageChunks.js.map +1 -0
- package/dist/validators.d.ts +10026 -1055
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +71 -9
- package/dist/validators.js.map +1 -1
- package/dist/{UIMessages.d.ts → vercel/UIMessages.d.ts} +1 -1
- package/dist/vercel/UIMessages.d.ts.map +1 -0
- package/dist/{UIMessages.js → vercel/UIMessages.js} +63 -1
- package/dist/vercel/UIMessages.js.map +1 -0
- package/dist/{client → vercel/client}/createTool.d.ts +23 -16
- package/dist/vercel/client/createTool.d.ts.map +1 -0
- package/dist/{client → vercel/client}/createTool.js +2 -0
- package/dist/vercel/client/createTool.js.map +1 -0
- package/dist/{client → vercel/client}/definePlaygroundAPI.d.ts +533 -79
- package/dist/{client → vercel/client}/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/{client → vercel/client}/definePlaygroundAPI.js +8 -7
- package/dist/vercel/client/definePlaygroundAPI.js.map +1 -0
- package/dist/{client → vercel/client}/files.d.ts +2 -2
- package/dist/vercel/client/files.d.ts.map +1 -0
- package/dist/vercel/client/files.js.map +1 -0
- package/dist/vercel/client/messages.d.ts +542 -0
- package/dist/vercel/client/messages.d.ts.map +1 -0
- package/dist/vercel/client/messages.js +66 -0
- package/dist/vercel/client/messages.js.map +1 -0
- package/dist/{client → vercel/client}/mockModel.d.ts +17 -17
- package/dist/vercel/client/mockModel.d.ts.map +1 -0
- package/dist/{client → vercel/client}/mockModel.js +12 -13
- package/dist/vercel/client/mockModel.js.map +1 -0
- package/dist/{client → vercel/client}/saveInputMessages.d.ts +2 -2
- package/dist/vercel/client/saveInputMessages.d.ts.map +1 -0
- package/dist/vercel/client/saveInputMessages.js.map +1 -0
- package/dist/{client → vercel/client}/search.d.ts +119 -22
- package/dist/vercel/client/search.d.ts.map +1 -0
- package/dist/{client → vercel/client}/search.js +2 -2
- package/dist/vercel/client/search.js.map +1 -0
- package/dist/{client → vercel/client}/start.d.ts +26 -11
- package/dist/vercel/client/start.d.ts.map +1 -0
- package/dist/{client → vercel/client}/start.js +64 -22
- package/dist/vercel/client/start.js.map +1 -0
- package/dist/{client → vercel/client}/streamText.d.ts +13 -12
- package/dist/vercel/client/streamText.d.ts.map +1 -0
- package/dist/{client → vercel/client}/streamText.js +43 -9
- package/dist/vercel/client/streamText.js.map +1 -0
- package/dist/{client → vercel/client}/streaming.d.ts +1410 -183
- package/dist/vercel/client/streaming.d.ts.map +1 -0
- package/dist/{client → vercel/client}/streaming.js +120 -52
- package/dist/vercel/client/streaming.js.map +1 -0
- package/dist/vercel/client/types.d.ts +456 -0
- package/dist/vercel/client/types.d.ts.map +1 -0
- package/dist/vercel/client/types.js +3 -0
- package/dist/vercel/client/types.js.map +1 -0
- package/dist/{client → vercel/client}/utils.d.ts +3 -2
- package/dist/vercel/client/utils.d.ts.map +1 -0
- package/dist/{client → vercel/client}/utils.js +2 -2
- package/dist/vercel/client/utils.js.map +1 -0
- package/dist/{deltas.d.ts → vercel/deltas.d.ts} +3 -4
- package/dist/vercel/deltas.d.ts.map +1 -0
- package/dist/{deltas.js → vercel/deltas.js} +195 -99
- package/dist/vercel/deltas.js.map +1 -0
- package/dist/{client → vercel}/index.d.ts +482 -106
- package/dist/vercel/index.d.ts.map +1 -0
- package/dist/{client → vercel}/index.js +64 -46
- package/dist/vercel/index.js.map +1 -0
- package/dist/{mapping.d.ts → vercel/mapping.d.ts} +5 -19
- package/dist/vercel/mapping.d.ts.map +1 -0
- package/dist/{mapping.js → vercel/mapping.js} +411 -114
- package/dist/vercel/mapping.js.map +1 -0
- package/dist/{react → vercel/react}/optimisticallySendMessage.d.ts +2 -2
- package/dist/vercel/react/optimisticallySendMessage.d.ts.map +1 -0
- package/dist/vercel/react/optimisticallySendMessage.js.map +1 -0
- package/dist/{react → vercel/react}/types.d.ts +1 -1
- package/dist/vercel/react/types.d.ts.map +1 -0
- package/dist/{react → vercel/react}/types.js.map +1 -1
- package/dist/{react → vercel/react}/useDeltaStreams.d.ts +1 -1
- package/dist/vercel/react/useDeltaStreams.d.ts.map +1 -0
- package/dist/{react → vercel/react}/useDeltaStreams.js +1 -1
- package/dist/vercel/react/useDeltaStreams.js.map +1 -0
- package/dist/{react → vercel/react}/useStreamingUIMessages.d.ts +1 -1
- package/dist/vercel/react/useStreamingUIMessages.d.ts.map +1 -0
- package/dist/{react → vercel/react}/useStreamingUIMessages.js +7 -3
- package/dist/vercel/react/useStreamingUIMessages.js.map +1 -0
- package/dist/{react → vercel/react}/useThreadMessages.d.ts +1 -1
- package/dist/vercel/react/useThreadMessages.d.ts.map +1 -0
- package/dist/{react → vercel/react}/useThreadMessages.js +1 -1
- package/dist/vercel/react/useThreadMessages.js.map +1 -0
- package/dist/{react → vercel/react}/useUIMessages.d.ts +1 -1
- package/dist/vercel/react/useUIMessages.d.ts.map +1 -0
- package/dist/{react → vercel/react}/useUIMessages.js +1 -1
- package/dist/vercel/react/useUIMessages.js.map +1 -0
- package/package.json +29 -22
- package/src/client/messages.ts +5 -107
- package/src/client/types.ts +0 -608
- package/src/component/_generated/component.ts +1089 -48
- package/src/component/messages.test.ts +273 -1
- package/src/component/messages.ts +62 -32
- package/src/component/streams.ts +47 -47
- package/src/component/threads.ts +5 -2
- package/src/eslintConfig.test.ts +44 -0
- package/src/react/index.ts +8 -5
- package/src/shared.ts +26 -36
- package/src/streaming/materializePersistedUIMessageChunks.test.ts +513 -0
- package/src/streaming/materializePersistedUIMessageChunks.ts +398 -0
- package/src/streaming/persistedUIMessageChunks.test.ts +205 -0
- package/src/streaming/persistedUIMessageChunks.ts +658 -0
- package/src/validators.test.ts +4 -1
- package/src/validators.ts +89 -8
- package/src/{UIMessages.combineUIMessages.test.ts → vercel/UIMessages.combineUIMessages.test.ts} +4 -1
- package/src/{UIMessages.ts → vercel/UIMessages.ts} +95 -3
- package/src/{client → vercel/client}/approval.test.ts +23 -13
- package/src/{client → vercel/client}/createTool.ts +62 -22
- package/src/{client → vercel/client}/definePlaygroundAPI.ts +15 -16
- package/src/{client → vercel/client}/files.ts +2 -2
- package/src/{client → vercel/client}/index.test.ts +99 -31
- package/src/vercel/client/messages.ts +182 -0
- package/src/{client → vercel/client}/mockModel.ts +38 -39
- package/src/{client → vercel/client}/saveInputMessages.test.ts +1 -1
- package/src/{client → vercel/client}/saveInputMessages.ts +3 -3
- package/src/{client → vercel/client}/search.test.ts +3 -3
- package/src/{client → vercel/client}/search.ts +4 -4
- package/src/{client → vercel/client}/setup.test.ts +6 -3
- package/src/vercel/client/start.test.ts +14 -0
- package/src/{client → vercel/client}/start.ts +147 -36
- package/src/vercel/client/streamText.test.ts +223 -0
- package/src/{client → vercel/client}/streamText.ts +102 -31
- package/src/{client → vercel/client}/streaming.integration.test.ts +6 -3
- package/src/{client → vercel/client}/streaming.test.ts +178 -4
- package/src/{client → vercel/client}/streaming.ts +114 -52
- package/src/vercel/client/types.test.ts +13 -0
- package/src/vercel/client/types.ts +679 -0
- package/src/{client → vercel/client}/utils.ts +13 -7
- package/src/{deltas.test.ts → vercel/deltas.test.ts} +384 -93
- package/src/{deltas.ts → vercel/deltas.ts} +218 -115
- package/src/{fromUIMessages.test.ts → vercel/fromUIMessages.test.ts} +17 -1
- package/src/{client → vercel}/index.ts +167 -84
- package/src/{mapping.test.ts → vercel/mapping.test.ts} +377 -92
- package/src/{mapping.ts → vercel/mapping.ts} +501 -137
- package/src/{react → vercel/react}/optimisticallySendMessage.ts +2 -2
- package/src/{react → vercel/react}/types.ts +1 -1
- package/src/{react → vercel/react}/useDeltaStreams.ts +6 -2
- package/src/{react → vercel/react}/useStreamingUIMessages.ts +7 -3
- package/src/{react → vercel/react}/useThreadMessages.ts +2 -2
- package/src/{react → vercel/react}/useUIMessages.ts +2 -2
- package/src/{toUIMessages.test.ts → vercel/toUIMessages.test.ts} +49 -2
- package/dist/UIMessages.d.ts.map +0 -1
- package/dist/UIMessages.js.map +0 -1
- package/dist/client/createTool.d.ts.map +0 -1
- package/dist/client/createTool.js.map +0 -1
- package/dist/client/definePlaygroundAPI.js.map +0 -1
- package/dist/client/files.d.ts.map +0 -1
- package/dist/client/files.js.map +0 -1
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js.map +0 -1
- package/dist/client/mockModel.d.ts.map +0 -1
- package/dist/client/mockModel.js.map +0 -1
- package/dist/client/saveInputMessages.d.ts.map +0 -1
- package/dist/client/saveInputMessages.js.map +0 -1
- package/dist/client/search.d.ts.map +0 -1
- package/dist/client/search.js.map +0 -1
- package/dist/client/start.d.ts.map +0 -1
- package/dist/client/start.js.map +0 -1
- package/dist/client/streamText.d.ts.map +0 -1
- package/dist/client/streamText.js.map +0 -1
- package/dist/client/streaming.d.ts.map +0 -1
- package/dist/client/streaming.js.map +0 -1
- package/dist/client/utils.d.ts.map +0 -1
- package/dist/client/utils.js.map +0 -1
- package/dist/deltas.d.ts.map +0 -1
- package/dist/deltas.js.map +0 -1
- package/dist/mapping.d.ts.map +0 -1
- package/dist/mapping.js.map +0 -1
- package/dist/react/optimisticallySendMessage.d.ts.map +0 -1
- package/dist/react/optimisticallySendMessage.js.map +0 -1
- package/dist/react/types.d.ts.map +0 -1
- package/dist/react/useDeltaStreams.d.ts.map +0 -1
- package/dist/react/useDeltaStreams.js.map +0 -1
- package/dist/react/useStreamingUIMessages.d.ts.map +0 -1
- package/dist/react/useStreamingUIMessages.js.map +0 -1
- package/dist/react/useThreadMessages.d.ts.map +0 -1
- package/dist/react/useThreadMessages.js.map +0 -1
- package/dist/react/useUIMessages.d.ts.map +0 -1
- package/dist/react/useUIMessages.js.map +0 -1
- package/src/client/streamText.test.ts +0 -102
- /package/dist/{client → vercel/client}/files.js +0 -0
- /package/dist/{client → vercel/client}/saveInputMessages.js +0 -0
- /package/dist/{react → vercel/react}/optimisticallySendMessage.js +0 -0
- /package/dist/{react → vercel/react}/types.js +0 -0
- /package/src/{UIMessages.test.ts → vercel/UIMessages.test.ts} +0 -0
- /package/src/{react → vercel/react}/useUIMessages.test.ts +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { ModelMessage } from "ai";
|
|
2
|
+
import type { PaginationOptions, PaginationResult } from "convex/server";
|
|
3
|
+
import type { MessageDoc } from "../../validators.js";
|
|
4
|
+
import {
|
|
5
|
+
type Message,
|
|
6
|
+
type MessageEmbeddings,
|
|
7
|
+
type MessageWithMetadata,
|
|
8
|
+
} from "../../validators.js";
|
|
9
|
+
import { serializeMessage } from "../mapping.js";
|
|
10
|
+
import { toUIMessages, type UIMessage } from "../UIMessages.js";
|
|
11
|
+
import {
|
|
12
|
+
listMessages,
|
|
13
|
+
saveMessages as saveCanonicalMessages,
|
|
14
|
+
} from "../../client/messages.js";
|
|
15
|
+
import type {
|
|
16
|
+
AgentComponent,
|
|
17
|
+
MutationCtx,
|
|
18
|
+
QueryCtx,
|
|
19
|
+
ActionCtx,
|
|
20
|
+
} from "./types.js";
|
|
21
|
+
|
|
22
|
+
export { listMessages } from "../../client/messages.js";
|
|
23
|
+
|
|
24
|
+
export async function listUIMessages(
|
|
25
|
+
ctx: QueryCtx | MutationCtx | ActionCtx,
|
|
26
|
+
component: AgentComponent,
|
|
27
|
+
args: {
|
|
28
|
+
threadId: string;
|
|
29
|
+
paginationOpts: PaginationOptions;
|
|
30
|
+
},
|
|
31
|
+
): Promise<PaginationResult<UIMessage>> {
|
|
32
|
+
const result = await listMessages(ctx, component, args);
|
|
33
|
+
return { ...result, page: toUIMessages(result.page) };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type SaveMessagesArgs = {
|
|
37
|
+
threadId: string;
|
|
38
|
+
userId?: string | null;
|
|
39
|
+
/**
|
|
40
|
+
* The message that these messages are in response to. They will be
|
|
41
|
+
* the same "order" as this message, at increasing stepOrder(s).
|
|
42
|
+
*/
|
|
43
|
+
promptMessageId?: string;
|
|
44
|
+
/**
|
|
45
|
+
* The messages to save.
|
|
46
|
+
*/
|
|
47
|
+
messages: (ModelMessage | Message)[];
|
|
48
|
+
/**
|
|
49
|
+
* Metadata to save with the messages. Each element corresponds to the
|
|
50
|
+
* message at the same index.
|
|
51
|
+
*/
|
|
52
|
+
metadata?: Omit<MessageWithMetadata, "message">[];
|
|
53
|
+
/**
|
|
54
|
+
* If true, it will fail any pending steps.
|
|
55
|
+
* Defaults to false.
|
|
56
|
+
*/
|
|
57
|
+
failPendingSteps?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* The embeddings to save with the messages.
|
|
60
|
+
*/
|
|
61
|
+
embeddings?: MessageEmbeddings;
|
|
62
|
+
/**
|
|
63
|
+
* A pending message ID to replace when adding messages.
|
|
64
|
+
*/
|
|
65
|
+
pendingMessageId?: string;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Explicitly save messages associated with the thread (& user if provided)
|
|
70
|
+
*/
|
|
71
|
+
export async function saveMessages(
|
|
72
|
+
ctx: MutationCtx | ActionCtx,
|
|
73
|
+
component: AgentComponent,
|
|
74
|
+
args: SaveMessagesArgs & {
|
|
75
|
+
/**
|
|
76
|
+
* The agent name to associate with the messages.
|
|
77
|
+
*/
|
|
78
|
+
agentName?: string;
|
|
79
|
+
},
|
|
80
|
+
): Promise<{ messages: MessageDoc[] }> {
|
|
81
|
+
const serialized = await Promise.all(
|
|
82
|
+
args.messages.map((message) => serializeMessage(ctx, component, message)),
|
|
83
|
+
);
|
|
84
|
+
return saveCanonicalMessages(ctx, component, {
|
|
85
|
+
threadId: args.threadId,
|
|
86
|
+
userId: args.userId ?? undefined,
|
|
87
|
+
agentName: args.agentName,
|
|
88
|
+
promptMessageId: args.promptMessageId,
|
|
89
|
+
pendingMessageId: args.pendingMessageId,
|
|
90
|
+
embeddings: args.embeddings,
|
|
91
|
+
messages: serialized.map(({ message }) => message),
|
|
92
|
+
metadata: serialized.map(({ fileIds }, i) => {
|
|
93
|
+
const base = args.metadata?.[i];
|
|
94
|
+
const allFileIds = [...(base?.fileIds ?? [])];
|
|
95
|
+
if (fileIds) allFileIds.push(...fileIds);
|
|
96
|
+
return {
|
|
97
|
+
...base,
|
|
98
|
+
...(allFileIds.length > 0 ? { fileIds: allFileIds } : {}),
|
|
99
|
+
};
|
|
100
|
+
}),
|
|
101
|
+
failPendingSteps: args.failPendingSteps ?? false,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type SaveMessageArgs = {
|
|
106
|
+
threadId: string;
|
|
107
|
+
userId?: string | null;
|
|
108
|
+
/**
|
|
109
|
+
* The message that these messages are in response to. They will be
|
|
110
|
+
* the same "order" as this message, at increasing stepOrder(s).
|
|
111
|
+
*/
|
|
112
|
+
promptMessageId?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Metadata to save with the messages. Each element corresponds to the
|
|
115
|
+
* message at the same index.
|
|
116
|
+
*/
|
|
117
|
+
metadata?: Omit<MessageWithMetadata, "message">;
|
|
118
|
+
/**
|
|
119
|
+
* The embedding to save with the message.
|
|
120
|
+
*/
|
|
121
|
+
embedding?: { vector: number[]; model: string };
|
|
122
|
+
/**
|
|
123
|
+
* A pending message ID to replace with this message.
|
|
124
|
+
*/
|
|
125
|
+
pendingMessageId?: string;
|
|
126
|
+
} & (
|
|
127
|
+
| {
|
|
128
|
+
prompt?: undefined;
|
|
129
|
+
/**
|
|
130
|
+
* The message to save.
|
|
131
|
+
*/
|
|
132
|
+
message: ModelMessage | Message;
|
|
133
|
+
}
|
|
134
|
+
| {
|
|
135
|
+
/*
|
|
136
|
+
* The prompt to save with the message.
|
|
137
|
+
*/
|
|
138
|
+
prompt: string;
|
|
139
|
+
message?: undefined;
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Save a message to the thread.
|
|
145
|
+
* @param ctx A ctx object from a mutation or action.
|
|
146
|
+
* @param args The message and what to associate it with (user / thread)
|
|
147
|
+
* You can pass extra metadata alongside the message, e.g. associated fileIds.
|
|
148
|
+
* @returns The messageId of the saved message.
|
|
149
|
+
*/
|
|
150
|
+
export async function saveMessage(
|
|
151
|
+
ctx: MutationCtx | ActionCtx,
|
|
152
|
+
component: AgentComponent,
|
|
153
|
+
args: SaveMessageArgs & {
|
|
154
|
+
/**
|
|
155
|
+
* The agent name to associate with the message.
|
|
156
|
+
*/
|
|
157
|
+
agentName?: string;
|
|
158
|
+
},
|
|
159
|
+
) {
|
|
160
|
+
let embeddings: { vectors: number[][]; model: string } | undefined;
|
|
161
|
+
if (args.embedding && args.embedding.vector) {
|
|
162
|
+
embeddings = {
|
|
163
|
+
model: args.embedding.model,
|
|
164
|
+
vectors: [args.embedding.vector],
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const { messages } = await saveMessages(ctx, component, {
|
|
168
|
+
threadId: args.threadId,
|
|
169
|
+
userId: args.userId ?? undefined,
|
|
170
|
+
agentName: args.agentName,
|
|
171
|
+
promptMessageId: args.promptMessageId,
|
|
172
|
+
pendingMessageId: args.pendingMessageId,
|
|
173
|
+
messages:
|
|
174
|
+
args.prompt !== undefined
|
|
175
|
+
? [{ role: "user", content: args.prompt }]
|
|
176
|
+
: [args.message],
|
|
177
|
+
metadata: args.metadata ? [args.metadata] : undefined,
|
|
178
|
+
embeddings,
|
|
179
|
+
});
|
|
180
|
+
const message = messages.at(-1)!;
|
|
181
|
+
return { messageId: message._id, message };
|
|
182
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
LanguageModelV4,
|
|
3
|
+
LanguageModelV4Content,
|
|
4
|
+
LanguageModelV4StreamPart,
|
|
5
5
|
} from "@ai-sdk/provider";
|
|
6
6
|
import { simulateReadableStream, type ProviderMetadata } from "ai";
|
|
7
7
|
import { assert, pick } from "convex-helpers";
|
|
@@ -13,26 +13,25 @@ C C C C C C C C C C C C C C C
|
|
|
13
13
|
D D D D D D D D D D D D D D D
|
|
14
14
|
`;
|
|
15
15
|
const DEFAULT_USAGE = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
cacheReadTokens: 0,
|
|
22
|
-
cacheWriteTokens: 0,
|
|
16
|
+
inputTokens: {
|
|
17
|
+
total: 3,
|
|
18
|
+
noCache: 3,
|
|
19
|
+
cacheRead: 0,
|
|
20
|
+
cacheWrite: 0,
|
|
23
21
|
},
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
outputTokens: {
|
|
23
|
+
total: 10,
|
|
24
|
+
text: 10,
|
|
25
|
+
reasoning: 0,
|
|
27
26
|
},
|
|
28
27
|
};
|
|
29
28
|
|
|
30
29
|
export type MockModelArgs = {
|
|
31
|
-
provider?:
|
|
32
|
-
modelId?:
|
|
30
|
+
provider?: LanguageModelV4["provider"];
|
|
31
|
+
modelId?: LanguageModelV4["modelId"];
|
|
33
32
|
supportedUrls?:
|
|
34
|
-
|
|
|
35
|
-
| (() =>
|
|
33
|
+
| LanguageModelV4["supportedUrls"]
|
|
34
|
+
| (() => LanguageModelV4["supportedUrls"]);
|
|
36
35
|
chunkDelayInMs?: number;
|
|
37
36
|
initialDelayInMs?: number;
|
|
38
37
|
/** A list of the responses for multiple steps.
|
|
@@ -40,15 +39,15 @@ export type MockModelArgs = {
|
|
|
40
39
|
* then the next list would be after the tool response or another tool call.
|
|
41
40
|
* Tool responses come from actual tool calls!
|
|
42
41
|
*/
|
|
43
|
-
contentSteps?:
|
|
42
|
+
contentSteps?: LanguageModelV4Content[][];
|
|
44
43
|
/** A single list of content responded from each step.
|
|
45
44
|
* Provide contentSteps instead if you want to do multi-step responses with
|
|
46
45
|
* tool calls.
|
|
47
46
|
*/
|
|
48
|
-
content?:
|
|
47
|
+
content?: LanguageModelV4Content[];
|
|
49
48
|
// provide either content, contentResponses or doGenerate & doStream
|
|
50
|
-
doGenerate?:
|
|
51
|
-
doStream?:
|
|
49
|
+
doGenerate?: LanguageModelV4["doGenerate"];
|
|
50
|
+
doStream?: LanguageModelV4["doStream"];
|
|
52
51
|
providerMetadata?: ProviderMetadata;
|
|
53
52
|
fail?:
|
|
54
53
|
| boolean
|
|
@@ -62,23 +61,23 @@ function atMostOneOf(...args: unknown[]) {
|
|
|
62
61
|
return args.filter(Boolean).length <= 1;
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
export function mockModel(args?: MockModelArgs):
|
|
64
|
+
export function mockModel(args?: MockModelArgs): LanguageModelV4 {
|
|
66
65
|
return new MockLanguageModel(args ?? {});
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
export class MockLanguageModel implements
|
|
70
|
-
readonly specificationVersion = "
|
|
68
|
+
export class MockLanguageModel implements LanguageModelV4 {
|
|
69
|
+
readonly specificationVersion = "v4";
|
|
71
70
|
|
|
72
|
-
private _supportedUrls: () =>
|
|
71
|
+
private _supportedUrls: () => LanguageModelV4["supportedUrls"];
|
|
73
72
|
|
|
74
|
-
readonly provider:
|
|
75
|
-
readonly modelId:
|
|
73
|
+
readonly provider: LanguageModelV4["provider"];
|
|
74
|
+
readonly modelId: LanguageModelV4["modelId"];
|
|
76
75
|
|
|
77
|
-
doGenerate:
|
|
78
|
-
doStream:
|
|
76
|
+
doGenerate: LanguageModelV4["doGenerate"];
|
|
77
|
+
doStream: LanguageModelV4["doStream"];
|
|
79
78
|
|
|
80
|
-
doGenerateCalls: Parameters<
|
|
81
|
-
doStreamCalls: Parameters<
|
|
79
|
+
doGenerateCalls: Parameters<LanguageModelV4["doGenerate"]>[0][] = [];
|
|
80
|
+
doStreamCalls: Parameters<LanguageModelV4["doStream"]>[0][] = [];
|
|
82
81
|
|
|
83
82
|
constructor(args: MockModelArgs) {
|
|
84
83
|
assert(
|
|
@@ -108,19 +107,19 @@ export class MockLanguageModel implements LanguageModelV3 {
|
|
|
108
107
|
"Mock error message";
|
|
109
108
|
const metadata = pick(args, ["providerMetadata"]);
|
|
110
109
|
|
|
111
|
-
const chunkResponses:
|
|
110
|
+
const chunkResponses: LanguageModelV4StreamPart[][] = contentSteps.map(
|
|
112
111
|
(content) => {
|
|
113
|
-
const chunks:
|
|
112
|
+
const chunks: LanguageModelV4StreamPart[] = [
|
|
114
113
|
{ type: "stream-start", warnings: [] },
|
|
115
114
|
];
|
|
116
115
|
chunks.push(
|
|
117
|
-
...content.flatMap((c, ci):
|
|
116
|
+
...content.flatMap((c, ci): LanguageModelV4StreamPart[] => {
|
|
118
117
|
if (c.type !== "text" && c.type !== "reasoning") {
|
|
119
118
|
return [c];
|
|
120
119
|
}
|
|
121
120
|
const metadata = pick(c, ["providerMetadata"]);
|
|
122
121
|
const deltas = c.text.split(" ");
|
|
123
|
-
const parts:
|
|
122
|
+
const parts: LanguageModelV4StreamPart[] = [];
|
|
124
123
|
if (c.type === "reasoning") {
|
|
125
124
|
parts.push({
|
|
126
125
|
type: "reasoning-start",
|
|
@@ -135,7 +134,7 @@ export class MockLanguageModel implements LanguageModelV3 {
|
|
|
135
134
|
delta: (di ? " " : "") + delta,
|
|
136
135
|
id: `reasoning-${ci}`,
|
|
137
136
|
...metadata,
|
|
138
|
-
}) satisfies
|
|
137
|
+
}) satisfies LanguageModelV4StreamPart,
|
|
139
138
|
),
|
|
140
139
|
);
|
|
141
140
|
parts.push({
|
|
@@ -157,7 +156,7 @@ export class MockLanguageModel implements LanguageModelV3 {
|
|
|
157
156
|
delta: (di ? " " : "") + delta,
|
|
158
157
|
id: `txt-${ci}`,
|
|
159
158
|
...metadata,
|
|
160
|
-
}) satisfies
|
|
159
|
+
}) satisfies LanguageModelV4StreamPart,
|
|
161
160
|
),
|
|
162
161
|
);
|
|
163
162
|
parts.push({
|
|
@@ -177,7 +176,7 @@ export class MockLanguageModel implements LanguageModelV3 {
|
|
|
177
176
|
}
|
|
178
177
|
chunks.push({
|
|
179
178
|
type: "finish",
|
|
180
|
-
finishReason: fail ? "error" : "stop",
|
|
179
|
+
finishReason: { unified: fail ? "error" : "stop", raw: undefined },
|
|
181
180
|
usage: DEFAULT_USAGE,
|
|
182
181
|
...(metadata as any),
|
|
183
182
|
});
|
|
@@ -198,7 +197,7 @@ export class MockLanguageModel implements LanguageModelV3 {
|
|
|
198
197
|
} else if (contentSteps.length) {
|
|
199
198
|
const result = {
|
|
200
199
|
content: contentSteps[callIndex % contentSteps.length],
|
|
201
|
-
finishReason: "stop" as const,
|
|
200
|
+
finishReason: { unified: "stop" as const, raw: undefined },
|
|
202
201
|
usage: DEFAULT_USAGE,
|
|
203
202
|
...(metadata as any),
|
|
204
203
|
warnings: [],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
2
|
import { saveInputMessages } from "./saveInputMessages.js";
|
|
3
|
-
import type { MessageDoc } from "
|
|
3
|
+
import type { MessageDoc } from "../../validators.js";
|
|
4
4
|
import type { ActionCtx } from "./types.js";
|
|
5
5
|
import {
|
|
6
6
|
defineSchema,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ModelMessage } from "ai";
|
|
2
|
-
import type { MessageDoc } from "
|
|
2
|
+
import type { MessageDoc } from "../../validators.js";
|
|
3
3
|
import { embedMessages, getPromptArray } from "./search.js";
|
|
4
4
|
import type {
|
|
5
5
|
ActionCtx,
|
|
@@ -8,9 +8,9 @@ import type {
|
|
|
8
8
|
MutationCtx,
|
|
9
9
|
} from "./types.js";
|
|
10
10
|
import { saveMessages } from "./messages.js";
|
|
11
|
-
import type { Message } from "
|
|
11
|
+
import type { Message } from "../../validators.js";
|
|
12
12
|
import { assert } from "convex-helpers";
|
|
13
|
-
import type { VectorDimension } from "
|
|
13
|
+
import type { VectorDimension } from "../../component/vector/tables.js";
|
|
14
14
|
|
|
15
15
|
export async function saveInputMessages(
|
|
16
16
|
ctx: MutationCtx | ActionCtx,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
type StorageActionWriter,
|
|
14
14
|
type StorageReader,
|
|
15
15
|
} from "convex/server";
|
|
16
|
-
import type { MessageDoc } from "
|
|
16
|
+
import type { MessageDoc } from "../../validators.js";
|
|
17
17
|
import type { ActionCtx, QueryCtx } from "./types.js";
|
|
18
18
|
import {
|
|
19
19
|
fetchContextWithPrompt,
|
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
getPromptArray,
|
|
23
23
|
} from "./search.js";
|
|
24
24
|
import { components, initConvexTest } from "./setup.test.js";
|
|
25
|
-
import { createThread } from "
|
|
26
|
-
import { saveMessages } from "
|
|
25
|
+
import { createThread } from "../../client/threads.js";
|
|
26
|
+
import { saveMessages } from "../../client/messages.js";
|
|
27
27
|
|
|
28
28
|
// Helper to create mock MessageDoc
|
|
29
29
|
const createMockMessageDoc = (
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
type ModelMessage,
|
|
5
5
|
} from "ai";
|
|
6
6
|
import { assert } from "convex-helpers";
|
|
7
|
-
import type { MessageDoc } from "
|
|
7
|
+
import type { MessageDoc } from "../../validators.js";
|
|
8
8
|
import {
|
|
9
9
|
validateVectorDimension,
|
|
10
10
|
type VectorDimension,
|
|
11
|
-
} from "
|
|
11
|
+
} from "../../component/vector/tables.js";
|
|
12
12
|
import {
|
|
13
13
|
DEFAULT_MESSAGE_RANGE,
|
|
14
14
|
DEFAULT_RECENT_MESSAGES,
|
|
@@ -17,8 +17,8 @@ import {
|
|
|
17
17
|
getProviderName,
|
|
18
18
|
isTool,
|
|
19
19
|
sorted,
|
|
20
|
-
} from "
|
|
21
|
-
import type { Message } from "
|
|
20
|
+
} from "../../shared.js";
|
|
21
|
+
import type { Message } from "../../validators.js";
|
|
22
22
|
import type {
|
|
23
23
|
AgentComponent,
|
|
24
24
|
Config,
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
/// <reference types="vite/client" />
|
|
2
2
|
import { test } from "vitest";
|
|
3
3
|
import { convexTest } from "convex-test";
|
|
4
|
-
export const modules =
|
|
4
|
+
export const modules = {
|
|
5
|
+
...import.meta.glob("./**/*.*s"),
|
|
6
|
+
"./_generated/api.ts": () => import("../../component/_generated/api.js"),
|
|
7
|
+
};
|
|
5
8
|
|
|
6
9
|
import {
|
|
7
10
|
defineSchema,
|
|
8
11
|
type GenericSchema,
|
|
9
12
|
type SchemaDefinition,
|
|
10
13
|
} from "convex/server";
|
|
11
|
-
import { type AgentComponent } from "./
|
|
14
|
+
import { type AgentComponent } from "./types.js";
|
|
12
15
|
import { componentsGeneric } from "convex/server";
|
|
13
|
-
import component from "
|
|
16
|
+
import component from "../../test.js";
|
|
14
17
|
|
|
15
18
|
export function initConvexTest<
|
|
16
19
|
Schema extends SchemaDefinition<GenericSchema, boolean>,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { resolveUsageModel } from "./start.js";
|
|
3
|
+
|
|
4
|
+
describe("resolveUsageModel", () => {
|
|
5
|
+
it("prefers a step model while object results retain the active model", () => {
|
|
6
|
+
const activeModel = { provider: "fallback", model: "fallback-model" };
|
|
7
|
+
const stepModel = { provider: "router", model: "routed-model" };
|
|
8
|
+
|
|
9
|
+
expect(resolveUsageModel({ step: { model: stepModel } }, activeModel)).toBe(
|
|
10
|
+
stepModel,
|
|
11
|
+
);
|
|
12
|
+
expect(resolveUsageModel({ object: {} }, activeModel)).toBe(activeModel);
|
|
13
|
+
});
|
|
14
|
+
});
|