@convex-dev/agent 0.0.16 → 0.0.17-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -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/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/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 +1 -1
- package/src/client/index.ts +220 -59
- 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
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,13 +52,15 @@ 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,
|
|
63
|
+
vThreadStatus,
|
|
59
64
|
} from "../validators.js";
|
|
60
65
|
import type {
|
|
61
66
|
OpaqueIds,
|
|
@@ -66,38 +71,33 @@ import type {
|
|
|
66
71
|
} from "./types.js";
|
|
67
72
|
import schema from "../component/schema.js";
|
|
68
73
|
|
|
74
|
+
export { extractText, isTool };
|
|
69
75
|
export type { Usage, ProviderMetadata };
|
|
70
76
|
export {
|
|
77
|
+
paginationResultValidator,
|
|
78
|
+
vContextOptions,
|
|
71
79
|
vUsage,
|
|
72
80
|
vProviderMetadata,
|
|
73
81
|
vUserMessage,
|
|
74
82
|
vAssistantMessage,
|
|
75
83
|
vToolMessage,
|
|
84
|
+
vStorageOptions,
|
|
76
85
|
vSystemMessage,
|
|
77
86
|
vMessage,
|
|
78
87
|
} from "../validators.js";
|
|
79
88
|
|
|
80
|
-
export type ThreadDoc = OpaqueIds<
|
|
81
|
-
{ _id: string; _creationTime: number } & Infer<
|
|
82
|
-
typeof schema.tables.threads.validator
|
|
83
|
-
>
|
|
84
|
-
>;
|
|
85
|
-
export type MessageDoc = OpaqueIds<
|
|
86
|
-
{ _id: string; _creationTime: number } & Infer<
|
|
87
|
-
typeof schema.tables.messages.validator
|
|
88
|
-
>
|
|
89
|
-
>;
|
|
90
|
-
|
|
91
89
|
/**
|
|
92
90
|
* Options to configure what messages are fetched as context,
|
|
93
91
|
* automatically with thread.generateText, or directly via search.
|
|
94
92
|
*/
|
|
95
93
|
export type ContextOptions = {
|
|
94
|
+
/** @deprecated Use excludeToolMessages instead. */
|
|
95
|
+
includeToolCalls?: boolean;
|
|
96
96
|
/**
|
|
97
97
|
* Whether to include tool messages in the context.
|
|
98
98
|
* By default, tool calls and results are not included.
|
|
99
99
|
*/
|
|
100
|
-
|
|
100
|
+
excludeToolMessages?: boolean;
|
|
101
101
|
/**
|
|
102
102
|
* How many recent messages to include. These are added after the search
|
|
103
103
|
* messages, and do not count against the search limit.
|
|
@@ -172,9 +172,11 @@ export type UsageHandler = (
|
|
|
172
172
|
}
|
|
173
173
|
) => void | Promise<void>;
|
|
174
174
|
|
|
175
|
+
export type AgentComponent = UseApi<Mounts>;
|
|
176
|
+
|
|
175
177
|
export class Agent<AgentTools extends ToolSet> {
|
|
176
178
|
constructor(
|
|
177
|
-
public component:
|
|
179
|
+
public component: AgentComponent,
|
|
178
180
|
public options: {
|
|
179
181
|
/**
|
|
180
182
|
* The name for the agent. This will be attributed on each message
|
|
@@ -334,7 +336,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
334
336
|
thread?: Thread<ThreadTools extends undefined ? AgentTools : ThreadTools>;
|
|
335
337
|
}> {
|
|
336
338
|
const threadDoc = await ctx.runMutation(
|
|
337
|
-
this.component.
|
|
339
|
+
this.component.threads.createThread,
|
|
338
340
|
{
|
|
339
341
|
userId: args?.userId,
|
|
340
342
|
title: args?.title,
|
|
@@ -415,10 +417,15 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
415
417
|
userId: string | undefined;
|
|
416
418
|
threadId: string | undefined;
|
|
417
419
|
messages: CoreMessage[];
|
|
418
|
-
|
|
420
|
+
/**
|
|
421
|
+
* If provided, it will search for messages before this message.
|
|
422
|
+
* Note: if this is far in the past, the search results may be more
|
|
423
|
+
* limited, as it's post-filtering the results.
|
|
424
|
+
*/
|
|
425
|
+
beforeMessageId?: string;
|
|
419
426
|
contextOptions: ContextOptions | undefined;
|
|
420
427
|
}
|
|
421
|
-
): Promise<
|
|
428
|
+
): Promise<MessageDoc[]> {
|
|
422
429
|
assert(args.userId || args.threadId, "Specify userId or threadId");
|
|
423
430
|
// Fetch the latest messages from the thread
|
|
424
431
|
const contextMessages: MessageDoc[] = [];
|
|
@@ -431,11 +438,9 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
431
438
|
const searchMessages = await ctx.runAction(
|
|
432
439
|
this.component.messages.searchMessages,
|
|
433
440
|
{
|
|
434
|
-
userId: args.
|
|
435
|
-
? args.userId
|
|
436
|
-
: undefined,
|
|
441
|
+
userId: opts?.searchOtherThreads ? args.userId : undefined,
|
|
437
442
|
threadId: args.threadId,
|
|
438
|
-
|
|
443
|
+
beforeMessageId: args.beforeMessageId,
|
|
439
444
|
...(await this.searchOptionsWithDefaults(opts, args.messages)),
|
|
440
445
|
}
|
|
441
446
|
);
|
|
@@ -445,15 +450,16 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
445
450
|
}
|
|
446
451
|
if (args.threadId && opts.recentMessages !== 0) {
|
|
447
452
|
const { page } = await ctx.runQuery(
|
|
448
|
-
this.component.messages.
|
|
453
|
+
this.component.messages.listMessagesByThreadId,
|
|
449
454
|
{
|
|
450
455
|
threadId: args.threadId,
|
|
451
|
-
|
|
456
|
+
excludeToolMessages:
|
|
457
|
+
opts.includeToolCalls === true ? false : opts.excludeToolMessages,
|
|
452
458
|
paginationOpts: {
|
|
453
459
|
numItems: opts.recentMessages ?? DEFAULT_RECENT_MESSAGES,
|
|
454
460
|
cursor: null,
|
|
455
461
|
},
|
|
456
|
-
|
|
462
|
+
beforeMessageId: args.beforeMessageId,
|
|
457
463
|
order: "desc",
|
|
458
464
|
statuses: ["success"],
|
|
459
465
|
}
|
|
@@ -463,15 +469,12 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
463
469
|
...page.filter((m) => !included?.has(m._id)).reverse()
|
|
464
470
|
);
|
|
465
471
|
}
|
|
466
|
-
|
|
467
|
-
// Sort the raw MessageDocs by order and stepOrder
|
|
468
|
-
const sortedDocs = contextMessages.sort((a, b) =>
|
|
469
|
-
a.order === b.order ? a.stepOrder - b.stepOrder : a.order - b.order
|
|
470
|
-
);
|
|
471
|
-
|
|
472
472
|
// Ensure we don't include tool messages without a corresponding tool call
|
|
473
|
-
return filterOutOrphanedToolMessages(
|
|
474
|
-
|
|
473
|
+
return filterOutOrphanedToolMessages(
|
|
474
|
+
contextMessages.sort((a, b) =>
|
|
475
|
+
// Sort the raw MessageDocs by order and stepOrder
|
|
476
|
+
a.order === b.order ? a.stepOrder - b.stepOrder : a.order - b.order
|
|
477
|
+
)
|
|
475
478
|
);
|
|
476
479
|
}
|
|
477
480
|
|
|
@@ -544,13 +547,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
544
547
|
*/
|
|
545
548
|
pending?: boolean;
|
|
546
549
|
/**
|
|
547
|
-
*
|
|
548
|
-
|
|
549
|
-
parentMessageId?: string;
|
|
550
|
-
/**
|
|
551
|
-
* Whether to mark all pending messages in the thread as failed.
|
|
552
|
-
* This is used to recover from a failure via a retry that wipes the slate clean.
|
|
553
|
-
* Defaults to true.
|
|
550
|
+
* If true, it will fail any pending steps.
|
|
551
|
+
* Defaults to false.
|
|
554
552
|
*/
|
|
555
553
|
failPendingSteps?: boolean;
|
|
556
554
|
}
|
|
@@ -575,9 +573,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
575
573
|
message: serializeMessage(m),
|
|
576
574
|
}) as MessageWithMetadata
|
|
577
575
|
),
|
|
578
|
-
failPendingSteps: args.failPendingSteps ??
|
|
576
|
+
failPendingSteps: args.failPendingSteps ?? false,
|
|
579
577
|
pending: args.pending ?? false,
|
|
580
|
-
parentMessageId: args.parentMessageId,
|
|
581
578
|
});
|
|
582
579
|
return {
|
|
583
580
|
lastMessageId: result.messages.at(-1)!._id,
|
|
@@ -598,7 +595,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
598
595
|
/**
|
|
599
596
|
* The message this step is in response to.
|
|
600
597
|
*/
|
|
601
|
-
|
|
598
|
+
parentMessageId: string;
|
|
602
599
|
/**
|
|
603
600
|
* The step to save, possibly including multiple tool calls.
|
|
604
601
|
*/
|
|
@@ -635,7 +632,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
635
632
|
await ctx.runMutation(this.component.messages.addStep, {
|
|
636
633
|
userId: args.userId,
|
|
637
634
|
threadId: args.threadId,
|
|
638
|
-
|
|
635
|
+
parentMessageId: args.parentMessageId,
|
|
639
636
|
step: { step, messages },
|
|
640
637
|
failPendingSteps: false,
|
|
641
638
|
});
|
|
@@ -741,7 +738,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
741
738
|
await this.saveStep(ctx, {
|
|
742
739
|
userId,
|
|
743
740
|
threadId,
|
|
744
|
-
messageId,
|
|
741
|
+
parentMessageId: messageId,
|
|
745
742
|
step,
|
|
746
743
|
});
|
|
747
744
|
}
|
|
@@ -863,7 +860,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
863
860
|
await this.saveStep(ctx, {
|
|
864
861
|
userId,
|
|
865
862
|
threadId,
|
|
866
|
-
messageId,
|
|
863
|
+
parentMessageId: messageId,
|
|
867
864
|
step,
|
|
868
865
|
});
|
|
869
866
|
}
|
|
@@ -902,7 +899,6 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
902
899
|
{
|
|
903
900
|
userId,
|
|
904
901
|
threadId,
|
|
905
|
-
parentMessageId,
|
|
906
902
|
contextOptions,
|
|
907
903
|
storageOptions,
|
|
908
904
|
}: {
|
|
@@ -920,7 +916,6 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
920
916
|
userId,
|
|
921
917
|
threadId,
|
|
922
918
|
messages,
|
|
923
|
-
parentMessageId,
|
|
924
919
|
contextOptions,
|
|
925
920
|
});
|
|
926
921
|
let messageId: string | undefined;
|
|
@@ -933,9 +928,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
933
928
|
messages: coreMessages,
|
|
934
929
|
metadata: coreMessages.length === 1 ? [{ id: args.id }] : undefined,
|
|
935
930
|
pending: true,
|
|
936
|
-
|
|
937
|
-
// failPendingSteps: true,
|
|
938
|
-
parentMessageId,
|
|
931
|
+
failPendingSteps: true,
|
|
939
932
|
});
|
|
940
933
|
messageId = saved.lastMessageId;
|
|
941
934
|
}
|
|
@@ -944,7 +937,10 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
944
937
|
args: {
|
|
945
938
|
...rest,
|
|
946
939
|
system: args.system ?? this.options.instructions,
|
|
947
|
-
messages: [
|
|
940
|
+
messages: [
|
|
941
|
+
...contextMessages.map((m) => deserializeMessage(m.message!)),
|
|
942
|
+
...messages,
|
|
943
|
+
],
|
|
948
944
|
} as T,
|
|
949
945
|
messageId,
|
|
950
946
|
};
|
|
@@ -993,7 +989,12 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
993
989
|
} as any)) as GenerateObjectResult<T> & GenerationOutputMetadata;
|
|
994
990
|
|
|
995
991
|
if (threadId && messageId && saveOutputMessages !== false) {
|
|
996
|
-
await this.saveObject(ctx, {
|
|
992
|
+
await this.saveObject(ctx, {
|
|
993
|
+
threadId,
|
|
994
|
+
parentMessageId: messageId,
|
|
995
|
+
result,
|
|
996
|
+
userId,
|
|
997
|
+
});
|
|
997
998
|
}
|
|
998
999
|
result.messageId = messageId;
|
|
999
1000
|
if (trackUsage && result.usage) {
|
|
@@ -1070,7 +1071,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1070
1071
|
await this.saveObject(ctx, {
|
|
1071
1072
|
userId,
|
|
1072
1073
|
threadId,
|
|
1073
|
-
messageId,
|
|
1074
|
+
parentMessageId: messageId,
|
|
1074
1075
|
result: {
|
|
1075
1076
|
object: result.object,
|
|
1076
1077
|
finishReason: "stop",
|
|
@@ -1118,7 +1119,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1118
1119
|
args: {
|
|
1119
1120
|
userId: string | undefined;
|
|
1120
1121
|
threadId: string;
|
|
1121
|
-
|
|
1122
|
+
parentMessageId: string;
|
|
1122
1123
|
result: GenerateObjectResult<unknown>;
|
|
1123
1124
|
metadata?: Omit<MessageWithMetadata, "message">;
|
|
1124
1125
|
}
|
|
@@ -1147,7 +1148,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1147
1148
|
await ctx.runMutation(this.component.messages.addStep, {
|
|
1148
1149
|
userId: args.userId,
|
|
1149
1150
|
threadId: args.threadId,
|
|
1150
|
-
|
|
1151
|
+
parentMessageId: args.parentMessageId,
|
|
1151
1152
|
failPendingSteps: false,
|
|
1152
1153
|
step: { step, messages },
|
|
1153
1154
|
});
|
|
@@ -1442,10 +1443,6 @@ function wrapTools(
|
|
|
1442
1443
|
}
|
|
1443
1444
|
|
|
1444
1445
|
type Options = {
|
|
1445
|
-
/**
|
|
1446
|
-
* The parent message id to use for the tool calls.
|
|
1447
|
-
*/
|
|
1448
|
-
parentMessageId?: string;
|
|
1449
1446
|
/**
|
|
1450
1447
|
* The context options to use for passing in message history to the LLM.
|
|
1451
1448
|
*/
|
|
@@ -1726,3 +1723,167 @@ interface Thread<DefaultTools extends ToolSet> {
|
|
|
1726
1723
|
StreamObjectResult<DeepPartial<T>, T, never> & ThreadOutputMetadata
|
|
1727
1724
|
>;
|
|
1728
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
|
+
}
|