@convex-dev/agent 0.2.6-alpha.0 → 0.2.6
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/dist/client/definePlaygroundAPI.d.ts +6 -4
- package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/client/definePlaygroundAPI.js +15 -6
- package/dist/client/definePlaygroundAPI.js.map +1 -1
- package/dist/client/index.d.ts +26 -120
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +48 -373
- package/dist/client/index.js.map +1 -1
- package/dist/client/messages.d.ts +1 -1
- package/dist/client/messages.d.ts.map +1 -1
- package/dist/client/mockModel.d.ts +3 -3
- package/dist/client/mockModel.d.ts.map +1 -1
- package/dist/client/mockModel.js +22 -17
- package/dist/client/mockModel.js.map +1 -1
- package/dist/client/saveInputMessages.d.ts +20 -0
- package/dist/client/saveInputMessages.d.ts.map +1 -0
- package/dist/client/saveInputMessages.js +57 -0
- package/dist/client/saveInputMessages.js.map +1 -0
- package/dist/client/search.d.ts +110 -9
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +271 -39
- package/dist/client/search.js.map +1 -1
- package/dist/client/start.d.ts +83 -0
- package/dist/client/start.d.ts.map +1 -0
- package/dist/client/start.js +171 -0
- package/dist/client/start.js.map +1 -0
- package/dist/client/streaming.d.ts +8 -8
- package/dist/client/streaming.d.ts.map +1 -1
- package/dist/client/streaming.js +2 -1
- package/dist/client/streaming.js.map +1 -1
- package/dist/client/textStreamParts.d.ts.map +1 -1
- package/dist/client/textStreamParts.js +2 -9
- package/dist/client/textStreamParts.js.map +1 -1
- package/dist/client/threads.d.ts +1 -1
- package/dist/client/threads.d.ts.map +1 -1
- package/dist/client/types.d.ts +137 -5
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/api.d.ts +11 -3
- package/dist/component/messages.d.ts +13 -4
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +67 -25
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +2 -1643
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +0 -24
- package/dist/component/schema.js.map +1 -1
- package/dist/mapping.d.ts +7 -9
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +73 -7
- package/dist/mapping.js.map +1 -1
- package/dist/react/deltas.d.ts.map +1 -1
- package/dist/react/deltas.js +15 -5
- package/dist/react/deltas.js.map +1 -1
- package/dist/react/fromUIMessages.d.ts +13 -0
- package/dist/react/fromUIMessages.d.ts.map +1 -0
- package/dist/react/fromUIMessages.js +70 -0
- package/dist/react/fromUIMessages.js.map +1 -0
- package/dist/react/toUIMessages.d.ts +5 -2
- package/dist/react/toUIMessages.d.ts.map +1 -1
- package/dist/react/toUIMessages.js +3 -0
- package/dist/react/toUIMessages.js.map +1 -1
- package/dist/shared.d.ts +10 -0
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +26 -0
- package/dist/shared.js.map +1 -1
- package/dist/validators.d.ts +1640 -0
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +41 -0
- package/dist/validators.js.map +1 -1
- package/package.json +1 -1
- package/src/client/definePlaygroundAPI.ts +16 -7
- package/src/client/index.test.ts +11 -46
- package/src/client/index.ts +99 -558
- package/src/client/messages.ts +1 -1
- package/src/client/mock.json +68 -0
- package/src/client/mockModel.ts +34 -23
- package/src/client/saveInputMessages.test.ts +576 -0
- package/src/client/saveInputMessages.ts +100 -0
- package/src/client/search.test.ts +1017 -0
- package/src/client/search.ts +446 -68
- package/src/client/start.ts +313 -0
- package/src/client/stream.json +48 -0
- package/src/client/streaming.ts +3 -3
- package/src/client/textStreamParts.ts +2 -11
- package/src/client/threads.ts +1 -1
- package/src/client/types.ts +143 -3
- package/src/component/_generated/api.d.ts +11 -3
- package/src/component/messages.ts +73 -27
- package/src/component/schema.ts +1 -29
- package/src/mapping.ts +84 -7
- package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/src/react/deltas.ts +18 -5
- package/src/react/fromUIMessages.test.ts +427 -0
- package/src/react/fromUIMessages.ts +85 -0
- package/src/react/toUIMessages.ts +21 -13
- package/src/shared.ts +33 -0
- package/src/validators.test.ts +13 -2
- package/src/validators.ts +48 -0
|
@@ -13,10 +13,12 @@ import {
|
|
|
13
13
|
sorted,
|
|
14
14
|
} from "../shared.js";
|
|
15
15
|
import {
|
|
16
|
+
vMessageDoc,
|
|
16
17
|
vMessageEmbeddingsWithDimension,
|
|
17
18
|
vMessageStatus,
|
|
18
19
|
vMessageWithMetadataInternal,
|
|
19
20
|
vPaginationResult,
|
|
21
|
+
type MessageDoc,
|
|
20
22
|
} from "../validators.js";
|
|
21
23
|
import { api, internal } from "./_generated/api.js";
|
|
22
24
|
import type { Doc, Id } from "./_generated/dataModel.js";
|
|
@@ -28,12 +30,10 @@ import {
|
|
|
28
30
|
query,
|
|
29
31
|
type QueryCtx,
|
|
30
32
|
} from "./_generated/server.js";
|
|
31
|
-
import
|
|
32
|
-
import { schema, v, vMessageDoc } from "./schema.js";
|
|
33
|
+
import { schema, v } from "./schema.js";
|
|
33
34
|
import { insertVector, searchVectors } from "./vector/index.js";
|
|
34
35
|
import {
|
|
35
|
-
|
|
36
|
-
VectorDimensions,
|
|
36
|
+
validateVectorDimension,
|
|
37
37
|
type VectorTableId,
|
|
38
38
|
vVectorId,
|
|
39
39
|
} from "./vector/tables.js";
|
|
@@ -504,10 +504,12 @@ export const searchMessages = action({
|
|
|
504
504
|
args: {
|
|
505
505
|
threadId: v.optional(v.id("threads")),
|
|
506
506
|
searchAllMessagesForUserId: v.optional(v.string()),
|
|
507
|
-
|
|
507
|
+
targetMessageId: v.optional(v.id("messages")),
|
|
508
508
|
embedding: v.optional(v.array(v.number())),
|
|
509
509
|
embeddingModel: v.optional(v.string()),
|
|
510
510
|
text: v.optional(v.string()),
|
|
511
|
+
textSearch: v.optional(v.boolean()),
|
|
512
|
+
vectorSearch: v.optional(v.boolean()),
|
|
511
513
|
limit: v.number(),
|
|
512
514
|
vectorScoreThreshold: v.optional(v.number()),
|
|
513
515
|
messageRange: v.optional(
|
|
@@ -522,24 +524,38 @@ export const searchMessages = action({
|
|
|
522
524
|
);
|
|
523
525
|
const limit = args.limit;
|
|
524
526
|
let textSearchMessages: MessageDoc[] | undefined;
|
|
525
|
-
if (args.
|
|
527
|
+
if (args.textSearch) {
|
|
526
528
|
textSearchMessages = await ctx.runQuery(api.messages.textSearch, {
|
|
527
529
|
searchAllMessagesForUserId: args.searchAllMessagesForUserId,
|
|
528
530
|
threadId: args.threadId,
|
|
531
|
+
targetMessageId: args.targetMessageId,
|
|
529
532
|
text: args.text,
|
|
530
533
|
limit,
|
|
531
|
-
beforeMessageId: args.beforeMessageId,
|
|
532
534
|
});
|
|
533
535
|
}
|
|
534
|
-
if (args.
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
536
|
+
if (args.vectorSearch) {
|
|
537
|
+
let embedding = args.embedding;
|
|
538
|
+
let model = args.embeddingModel;
|
|
539
|
+
if (!embedding) {
|
|
540
|
+
if (args.targetMessageId) {
|
|
541
|
+
const target = await ctx.runQuery(
|
|
542
|
+
api.messages.getMessageSearchFields,
|
|
543
|
+
{
|
|
544
|
+
messageId: args.targetMessageId,
|
|
545
|
+
},
|
|
546
|
+
);
|
|
547
|
+
assert(target, "Target message embedding not found.");
|
|
548
|
+
embedding = target.embedding;
|
|
549
|
+
model = target.embeddingModel;
|
|
550
|
+
}
|
|
538
551
|
}
|
|
552
|
+
assert(embedding && model, "Embedding missing");
|
|
553
|
+
const dimension = embedding.length;
|
|
554
|
+
validateVectorDimension(dimension);
|
|
539
555
|
const vectors = (
|
|
540
|
-
await searchVectors(ctx,
|
|
556
|
+
await searchVectors(ctx, embedding, {
|
|
541
557
|
dimension,
|
|
542
|
-
model
|
|
558
|
+
model,
|
|
543
559
|
table: "messages",
|
|
544
560
|
searchAllMessagesForUserId: args.searchAllMessagesForUserId,
|
|
545
561
|
threadId: args.threadId,
|
|
@@ -568,7 +584,7 @@ export const searchMessages = action({
|
|
|
568
584
|
(m) => !embeddingIds.includes(m.embeddingId! as VectorTableId),
|
|
569
585
|
),
|
|
570
586
|
messageRange: args.messageRange ?? DEFAULT_MESSAGE_RANGE,
|
|
571
|
-
beforeMessageId: args.
|
|
587
|
+
beforeMessageId: args.targetMessageId,
|
|
572
588
|
limit,
|
|
573
589
|
},
|
|
574
590
|
);
|
|
@@ -699,26 +715,29 @@ export const textSearch = query({
|
|
|
699
715
|
args: {
|
|
700
716
|
threadId: v.optional(v.id("threads")),
|
|
701
717
|
searchAllMessagesForUserId: v.optional(v.string()),
|
|
702
|
-
text: v.string(),
|
|
718
|
+
text: v.optional(v.string()),
|
|
719
|
+
targetMessageId: v.optional(v.id("messages")),
|
|
703
720
|
limit: v.number(),
|
|
704
|
-
beforeMessageId: v.optional(v.id("messages")),
|
|
705
721
|
},
|
|
706
722
|
handler: async (ctx, args) => {
|
|
707
723
|
assert(
|
|
708
724
|
args.searchAllMessagesForUserId || args.threadId,
|
|
709
725
|
"Specify userId or threadId",
|
|
710
726
|
);
|
|
711
|
-
const
|
|
712
|
-
args.
|
|
713
|
-
const order =
|
|
727
|
+
const targetMessage =
|
|
728
|
+
args.targetMessageId && (await ctx.db.get(args.targetMessageId));
|
|
729
|
+
const order = targetMessage?.order;
|
|
730
|
+
const text = args.text || targetMessage?.text;
|
|
731
|
+
if (!text) {
|
|
732
|
+
console.warn("No text to search", targetMessage, args.text);
|
|
733
|
+
return [];
|
|
734
|
+
}
|
|
714
735
|
const messages = await ctx.db
|
|
715
736
|
.query("messages")
|
|
716
737
|
.withSearchIndex("text_search", (q) =>
|
|
717
738
|
args.searchAllMessagesForUserId
|
|
718
|
-
? q
|
|
719
|
-
|
|
720
|
-
.eq("userId", args.searchAllMessagesForUserId)
|
|
721
|
-
: q.search("text", args.text).eq("threadId", args.threadId!),
|
|
739
|
+
? q.search("text", text).eq("userId", args.searchAllMessagesForUserId)
|
|
740
|
+
: q.search("text", text).eq("threadId", args.threadId!),
|
|
722
741
|
)
|
|
723
742
|
// Just in case tool messages slip through
|
|
724
743
|
.filter((q) => {
|
|
@@ -732,12 +751,39 @@ export const textSearch = query({
|
|
|
732
751
|
return messages
|
|
733
752
|
.filter(
|
|
734
753
|
(m) =>
|
|
735
|
-
!
|
|
736
|
-
m.order <
|
|
737
|
-
(m.order ===
|
|
738
|
-
m.stepOrder <
|
|
754
|
+
!targetMessage ||
|
|
755
|
+
m.order < targetMessage.order ||
|
|
756
|
+
(m.order === targetMessage.order &&
|
|
757
|
+
m.stepOrder < targetMessage.stepOrder),
|
|
739
758
|
)
|
|
740
759
|
.map(publicMessage);
|
|
741
760
|
},
|
|
742
761
|
returns: v.array(vMessageDoc),
|
|
743
762
|
});
|
|
763
|
+
|
|
764
|
+
export const getMessageSearchFields = query({
|
|
765
|
+
args: {
|
|
766
|
+
messageId: v.id("messages"),
|
|
767
|
+
},
|
|
768
|
+
returns: v.object({
|
|
769
|
+
text: v.optional(v.string()),
|
|
770
|
+
embedding: v.optional(v.array(v.number())),
|
|
771
|
+
embeddingModel: v.optional(v.string()),
|
|
772
|
+
}),
|
|
773
|
+
handler: async (ctx, args) => {
|
|
774
|
+
const message = await ctx.db.get(args.messageId);
|
|
775
|
+
const text = message?.text;
|
|
776
|
+
let embedding = undefined;
|
|
777
|
+
let embeddingModel = undefined;
|
|
778
|
+
if (message?.embeddingId) {
|
|
779
|
+
const target = await ctx.db.get(message.embeddingId);
|
|
780
|
+
embedding = target?.vector;
|
|
781
|
+
embeddingModel = target?.model;
|
|
782
|
+
}
|
|
783
|
+
return {
|
|
784
|
+
text,
|
|
785
|
+
embedding,
|
|
786
|
+
embeddingModel,
|
|
787
|
+
};
|
|
788
|
+
},
|
|
789
|
+
});
|
package/src/component/schema.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineSchema, defineTable } from "convex/server";
|
|
2
|
-
import {
|
|
2
|
+
import { v } from "convex/values";
|
|
3
3
|
import {
|
|
4
4
|
vThreadStatus,
|
|
5
5
|
vMessage,
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
} from "../validators.js";
|
|
15
15
|
import { typedV } from "convex-helpers/validators";
|
|
16
16
|
import vectorTables, { vVectorId } from "./vector/tables.js";
|
|
17
|
-
import { omit } from "convex-helpers";
|
|
18
17
|
|
|
19
18
|
export const schema = defineSchema({
|
|
20
19
|
threads: defineTable({
|
|
@@ -164,31 +163,4 @@ export const schema = defineSchema({
|
|
|
164
163
|
export const vv = typedV(schema);
|
|
165
164
|
export { vv as v };
|
|
166
165
|
|
|
167
|
-
// Public
|
|
168
|
-
export const vThreadDoc = v.object({
|
|
169
|
-
_id: v.string(),
|
|
170
|
-
_creationTime: v.number(),
|
|
171
|
-
userId: v.optional(v.string()), // Unset for anonymous
|
|
172
|
-
title: v.optional(v.string()),
|
|
173
|
-
summary: v.optional(v.string()),
|
|
174
|
-
status: vThreadStatus,
|
|
175
|
-
});
|
|
176
|
-
export type ThreadDoc = Infer<typeof vThreadDoc>;
|
|
177
|
-
|
|
178
|
-
export const vMessageDoc = v.object({
|
|
179
|
-
_id: v.string(),
|
|
180
|
-
_creationTime: v.number(),
|
|
181
|
-
...omit(schema.tables.messages.validator.fields, [
|
|
182
|
-
"parentMessageId",
|
|
183
|
-
"stepId",
|
|
184
|
-
"files",
|
|
185
|
-
]),
|
|
186
|
-
// Overwrite all the types that have a v.id validator
|
|
187
|
-
// Outside of the component, they are strings
|
|
188
|
-
threadId: v.string(),
|
|
189
|
-
embeddingId: v.optional(v.string()),
|
|
190
|
-
fileIds: v.optional(v.array(v.string())),
|
|
191
|
-
});
|
|
192
|
-
export type MessageDoc = Infer<typeof vMessageDoc>;
|
|
193
|
-
|
|
194
166
|
export default schema;
|
package/src/mapping.ts
CHANGED
|
@@ -46,6 +46,11 @@ import {
|
|
|
46
46
|
type ReasoningPart,
|
|
47
47
|
} from "@ai-sdk/provider-utils";
|
|
48
48
|
import { parse, validate } from "convex-helpers/validators";
|
|
49
|
+
import {
|
|
50
|
+
getModelName,
|
|
51
|
+
getProviderName,
|
|
52
|
+
type ModelOrMetadata,
|
|
53
|
+
} from "./shared.js";
|
|
49
54
|
export type AIMessageWithoutId = Omit<AIMessage, "id">;
|
|
50
55
|
|
|
51
56
|
export type SerializeUrlsAndUint8Arrays<T> = T extends URL
|
|
@@ -86,6 +91,21 @@ export async function serializeMessage(
|
|
|
86
91
|
};
|
|
87
92
|
}
|
|
88
93
|
|
|
94
|
+
// Similar to serializeMessage, but doesn't save any files and is looser
|
|
95
|
+
// For use on the frontend / in synchronous environments.
|
|
96
|
+
export function fromModelMessage(
|
|
97
|
+
message: ModelMessage,
|
|
98
|
+
): Message {
|
|
99
|
+
const content = fromModelMessageContent(message.content);
|
|
100
|
+
return {
|
|
101
|
+
role: message.role,
|
|
102
|
+
content,
|
|
103
|
+
...(message.providerOptions
|
|
104
|
+
? { providerOptions: message.providerOptions }
|
|
105
|
+
: {}),
|
|
106
|
+
} as SerializedMessage;
|
|
107
|
+
}
|
|
108
|
+
|
|
89
109
|
export async function serializeOrThrow(
|
|
90
110
|
message: ModelMessage | Message,
|
|
91
111
|
): Promise<SerializedMessage> {
|
|
@@ -159,13 +179,13 @@ export async function serializeNewMessagesInStep<TOOLS extends ToolSet>(
|
|
|
159
179
|
ctx: ActionCtx,
|
|
160
180
|
component: AgentComponent,
|
|
161
181
|
step: StepResult<TOOLS>,
|
|
162
|
-
|
|
182
|
+
model: ModelOrMetadata | undefined,
|
|
163
183
|
): Promise<{ messages: MessageWithMetadata[] }> {
|
|
164
184
|
// If there are tool results, there's another message with the tool results
|
|
165
185
|
// ref: https://github.com/vercel/ai/blob/main/packages/ai/core/generate-text/to-response-messages.ts
|
|
166
186
|
const assistantFields = {
|
|
167
|
-
model:
|
|
168
|
-
provider:
|
|
187
|
+
model: model ? getModelName(model) : undefined,
|
|
188
|
+
provider: model ? getProviderName(model) : undefined,
|
|
169
189
|
providerMetadata: step.providerMetadata,
|
|
170
190
|
reasoning: step.reasoningText,
|
|
171
191
|
reasoningDetails: step.reasoning,
|
|
@@ -198,7 +218,7 @@ export async function serializeObjectResult(
|
|
|
198
218
|
ctx: ActionCtx,
|
|
199
219
|
component: AgentComponent,
|
|
200
220
|
result: GenerateObjectResult<unknown>,
|
|
201
|
-
|
|
221
|
+
model: ModelOrMetadata | undefined,
|
|
202
222
|
): Promise<{ messages: MessageWithMetadata[] }> {
|
|
203
223
|
const text = JSON.stringify(result.object);
|
|
204
224
|
|
|
@@ -210,8 +230,8 @@ export async function serializeObjectResult(
|
|
|
210
230
|
messages: [
|
|
211
231
|
{
|
|
212
232
|
message,
|
|
213
|
-
model:
|
|
214
|
-
provider:
|
|
233
|
+
model: model ? getModelName(model) : undefined,
|
|
234
|
+
provider: model ? getProviderName(model) : undefined,
|
|
215
235
|
providerMetadata: result.providerMetadata,
|
|
216
236
|
finishReason: result.finishReason,
|
|
217
237
|
text,
|
|
@@ -347,6 +367,63 @@ export async function serializeContent(
|
|
|
347
367
|
};
|
|
348
368
|
}
|
|
349
369
|
|
|
370
|
+
export function fromModelMessageContent(content: Content): Message["content"] {
|
|
371
|
+
if (typeof content === "string") {
|
|
372
|
+
return content;
|
|
373
|
+
}
|
|
374
|
+
const metadata: {
|
|
375
|
+
providerOptions?: ProviderOptions;
|
|
376
|
+
providerMetadata?: ProviderMetadata;
|
|
377
|
+
} = {};
|
|
378
|
+
if ("providerOptions" in content) {
|
|
379
|
+
metadata.providerOptions = content.providerOptions as ProviderOptions;
|
|
380
|
+
}
|
|
381
|
+
if ("providerMetadata" in content) {
|
|
382
|
+
metadata.providerMetadata = content.providerMetadata as ProviderMetadata;
|
|
383
|
+
}
|
|
384
|
+
return content.map((part) => {
|
|
385
|
+
switch (part.type) {
|
|
386
|
+
case "text":
|
|
387
|
+
return part satisfies Infer<typeof vTextPart>;
|
|
388
|
+
case "image":
|
|
389
|
+
return {
|
|
390
|
+
type: part.type,
|
|
391
|
+
mimeType: getMimeOrMediaType(part),
|
|
392
|
+
...metadata,
|
|
393
|
+
image: serializeDataOrUrl(part.image),
|
|
394
|
+
} satisfies Infer<typeof vImagePart>;
|
|
395
|
+
case "file":
|
|
396
|
+
return {
|
|
397
|
+
type: part.type,
|
|
398
|
+
data: serializeDataOrUrl(part.data),
|
|
399
|
+
filename: part.filename,
|
|
400
|
+
mimeType: getMimeOrMediaType(part)!,
|
|
401
|
+
...metadata,
|
|
402
|
+
} satisfies Infer<typeof vFilePart>;
|
|
403
|
+
case "tool-call":
|
|
404
|
+
return {
|
|
405
|
+
type: part.type,
|
|
406
|
+
args: part.input ?? null,
|
|
407
|
+
toolCallId: part.toolCallId,
|
|
408
|
+
toolName: part.toolName,
|
|
409
|
+
providerExecuted: part.providerExecuted,
|
|
410
|
+
...metadata,
|
|
411
|
+
} satisfies Infer<typeof vToolCallPart>;
|
|
412
|
+
case "tool-result":
|
|
413
|
+
return normalizeToolResult(part, metadata);
|
|
414
|
+
case "reasoning":
|
|
415
|
+
return {
|
|
416
|
+
type: part.type,
|
|
417
|
+
text: part.text,
|
|
418
|
+
...metadata,
|
|
419
|
+
} satisfies Infer<typeof vReasoningPart>;
|
|
420
|
+
// Not in current generation output, but could be in historical messages
|
|
421
|
+
default:
|
|
422
|
+
return part satisfies Infer<typeof vContent>;
|
|
423
|
+
}
|
|
424
|
+
}) as Message["content"];
|
|
425
|
+
}
|
|
426
|
+
|
|
350
427
|
export function deserializeContent(
|
|
351
428
|
content: SerializedContent | ModelMessage["content"],
|
|
352
429
|
): Content {
|
|
@@ -433,7 +510,7 @@ export function deserializeContent(
|
|
|
433
510
|
}) as Content;
|
|
434
511
|
}
|
|
435
512
|
|
|
436
|
-
function normalizeToolOutput(
|
|
513
|
+
export function normalizeToolOutput(
|
|
437
514
|
result: string | JSONValue | undefined,
|
|
438
515
|
): ToolResultPart["output"] {
|
|
439
516
|
if (typeof result === "string") {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"3.2.4","results":[[":client/index.test.ts",{"duration":129.9694999999997,"failed":false}],[":component/messages.test.ts",{"duration":191.73391600000014,"failed":false}],[":component/users.test.ts",{"duration":545.7272500000001,"failed":false}],[":mapping.test.ts",{"duration":9.238791999999876,"failed":false}],[":react/deltas.test.ts",{"duration":5.8497500000000855,"failed":false}],[":react/toUIMessages.test.ts",{"duration":6.495208000000048,"failed":false}],[":validators.test.ts",{"duration":1.0037499999999682,"failed":false}],[":deltas.test.ts",{"duration":0,"failed":false}]]}
|
package/src/react/deltas.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
JSONValue,
|
|
2
3
|
ProviderMetadata,
|
|
3
4
|
TextStreamPart,
|
|
4
5
|
ToolSet,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
type vToolResultPart,
|
|
19
20
|
} from "../validators.js";
|
|
20
21
|
import type { Infer } from "convex/values";
|
|
21
|
-
import { serializeWarnings } from "../mapping.js";
|
|
22
|
+
import { normalizeToolOutput, serializeWarnings } from "../mapping.js";
|
|
22
23
|
import { parse } from "convex-helpers/validators";
|
|
23
24
|
import { sorted } from "../shared.js";
|
|
24
25
|
|
|
@@ -267,7 +268,9 @@ export function applyDeltasToStreamMessage(
|
|
|
267
268
|
lastContent?.type === "tool-result" &&
|
|
268
269
|
lastContent.toolCallId === part.toolCallId
|
|
269
270
|
) {
|
|
270
|
-
lastContent.
|
|
271
|
+
lastContent.output = normalizeToolOutput(
|
|
272
|
+
part.output as string | JSONValue | undefined,
|
|
273
|
+
);
|
|
271
274
|
lastContent.providerExecuted = part.providerExecuted;
|
|
272
275
|
} else {
|
|
273
276
|
console.warn(
|
|
@@ -376,7 +379,10 @@ export function applyDeltasToStreamMessage(
|
|
|
376
379
|
lastContent.toolCallId === part.toolCallId
|
|
377
380
|
) {
|
|
378
381
|
lastContent.isError = true;
|
|
379
|
-
lastContent.
|
|
382
|
+
lastContent.output = {
|
|
383
|
+
type: "error-text",
|
|
384
|
+
value: part.errorText,
|
|
385
|
+
};
|
|
380
386
|
lastContent.providerExecuted = part.providerExecuted;
|
|
381
387
|
} else if (
|
|
382
388
|
lastContent?.type === "tool-call" &&
|
|
@@ -391,7 +397,10 @@ export function applyDeltasToStreamMessage(
|
|
|
391
397
|
toolCallId: part.toolCallId,
|
|
392
398
|
toolName: lastContent.toolName,
|
|
393
399
|
args: lastContent.args,
|
|
394
|
-
|
|
400
|
+
output: {
|
|
401
|
+
type: "error-text",
|
|
402
|
+
value: part.errorText,
|
|
403
|
+
},
|
|
395
404
|
providerExecuted: part.providerExecuted,
|
|
396
405
|
isError: true,
|
|
397
406
|
} satisfies Infer<typeof vToolResultPart>;
|
|
@@ -408,7 +417,10 @@ export function applyDeltasToStreamMessage(
|
|
|
408
417
|
lastContent.toolCallId === part.toolCallId
|
|
409
418
|
) {
|
|
410
419
|
lastContent.isError = true;
|
|
411
|
-
lastContent.
|
|
420
|
+
lastContent.output = {
|
|
421
|
+
type: "error-json",
|
|
422
|
+
value: part.error,
|
|
423
|
+
};
|
|
412
424
|
lastContent.providerExecuted = part.providerExecuted;
|
|
413
425
|
} else {
|
|
414
426
|
if (
|
|
@@ -571,6 +583,7 @@ export function createStreamingMessage(
|
|
|
571
583
|
_id: `${streamId}-${index}`,
|
|
572
584
|
_creationTime: Date.now(),
|
|
573
585
|
status: statusFromStreamStatus(message.status),
|
|
586
|
+
stepOrder: message.stepOrder + index,
|
|
574
587
|
threadId,
|
|
575
588
|
tool: false,
|
|
576
589
|
};
|