@convex-dev/agent 0.1.18-alpha.1 → 0.2.0-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.
Files changed (96) hide show
  1. package/dist/client/createTool.d.ts +31 -10
  2. package/dist/client/createTool.d.ts.map +1 -1
  3. package/dist/client/createTool.js +25 -10
  4. package/dist/client/createTool.js.map +1 -1
  5. package/dist/client/defaultComponent.d.ts +11 -0
  6. package/dist/client/defaultComponent.d.ts.map +1 -0
  7. package/dist/client/defaultComponent.js +7 -0
  8. package/dist/client/defaultComponent.js.map +1 -0
  9. package/dist/client/definePlaygroundAPI.d.ts +174 -199
  10. package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
  11. package/dist/client/definePlaygroundAPI.js +17 -35
  12. package/dist/client/definePlaygroundAPI.js.map +1 -1
  13. package/dist/client/files.d.ts +6 -3
  14. package/dist/client/files.d.ts.map +1 -1
  15. package/dist/client/files.js +7 -7
  16. package/dist/client/files.js.map +1 -1
  17. package/dist/client/index.d.ts +152 -589
  18. package/dist/client/index.d.ts.map +1 -1
  19. package/dist/client/index.js +138 -222
  20. package/dist/client/index.js.map +1 -1
  21. package/dist/client/messages.d.ts +538 -0
  22. package/dist/client/messages.d.ts.map +1 -0
  23. package/dist/client/messages.js +91 -0
  24. package/dist/client/messages.js.map +1 -0
  25. package/dist/client/search.d.ts +30 -7
  26. package/dist/client/search.d.ts.map +1 -1
  27. package/dist/client/search.js +20 -3
  28. package/dist/client/search.js.map +1 -1
  29. package/dist/client/streaming.d.ts +3 -2
  30. package/dist/client/streaming.d.ts.map +1 -1
  31. package/dist/client/streaming.js.map +1 -1
  32. package/dist/client/threads.d.ts +46 -0
  33. package/dist/client/threads.d.ts.map +1 -0
  34. package/dist/client/threads.js +49 -0
  35. package/dist/client/threads.js.map +1 -0
  36. package/dist/client/types.d.ts +39 -42
  37. package/dist/client/types.d.ts.map +1 -1
  38. package/dist/component/_generated/api.d.ts +437 -75
  39. package/dist/component/messages.d.ts +254 -55
  40. package/dist/component/messages.d.ts.map +1 -1
  41. package/dist/component/messages.js +29 -25
  42. package/dist/component/messages.js.map +1 -1
  43. package/dist/component/schema.d.ts +1459 -158
  44. package/dist/component/schema.d.ts.map +1 -1
  45. package/dist/component/schema.js +8 -14
  46. package/dist/component/schema.js.map +1 -1
  47. package/dist/component/streams.d.ts +180 -6
  48. package/dist/component/streams.d.ts.map +1 -1
  49. package/dist/mapping.d.ts +11 -15
  50. package/dist/mapping.d.ts.map +1 -1
  51. package/dist/mapping.js +191 -61
  52. package/dist/mapping.js.map +1 -1
  53. package/dist/react/deltas.d.ts +0 -3
  54. package/dist/react/deltas.d.ts.map +1 -1
  55. package/dist/react/deltas.js +140 -44
  56. package/dist/react/deltas.js.map +1 -1
  57. package/dist/react/optimisticallySendMessage.d.ts.map +1 -1
  58. package/dist/react/optimisticallySendMessage.js +2 -1
  59. package/dist/react/optimisticallySendMessage.js.map +1 -1
  60. package/dist/react/toUIMessages.d.ts +5 -4
  61. package/dist/react/toUIMessages.d.ts.map +1 -1
  62. package/dist/react/toUIMessages.js +103 -40
  63. package/dist/react/toUIMessages.js.map +1 -1
  64. package/dist/validators.d.ts +1978 -1210
  65. package/dist/validators.d.ts.map +1 -1
  66. package/dist/validators.js +90 -54
  67. package/dist/validators.js.map +1 -1
  68. package/package.json +32 -28
  69. package/src/client/createTool.ts +69 -38
  70. package/src/client/defaultComponent.ts +17 -0
  71. package/src/client/definePlaygroundAPI.ts +29 -43
  72. package/src/client/files.ts +7 -8
  73. package/src/client/index.test.ts +20 -18
  74. package/src/client/index.ts +228 -434
  75. package/src/client/messages.ts +191 -0
  76. package/src/client/search.ts +30 -6
  77. package/src/client/streaming.ts +4 -3
  78. package/src/client/threads.ts +78 -0
  79. package/src/client/types.ts +50 -72
  80. package/src/component/_generated/api.d.ts +437 -75
  81. package/src/component/messages.test.ts +182 -40
  82. package/src/component/messages.ts +30 -32
  83. package/src/component/schema.ts +8 -14
  84. package/src/mapping.ts +230 -94
  85. package/src/react/deltas.ts +165 -52
  86. package/src/react/optimisticallySendMessage.ts +4 -1
  87. package/src/react/toUIMessages.test.ts +154 -36
  88. package/src/react/toUIMessages.ts +136 -57
  89. package/src/validators.test.ts +2 -101
  90. package/src/validators.ts +111 -68
  91. package/dist/client/listMessages.d.ts +0 -22
  92. package/dist/client/listMessages.d.ts.map +0 -1
  93. package/dist/client/listMessages.js +0 -25
  94. package/dist/client/listMessages.js.map +0 -1
  95. package/src/client/listMessages.ts +0 -38
  96. package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
@@ -1,22 +1,41 @@
1
- import type { ToolInvocationUIPart } from "@ai-sdk/ui-utils";
2
- import type { UIMessage as AIUIMessage } from "ai";
1
+ import type {
2
+ UIMessage as AIUIMessage,
3
+ DeepPartial,
4
+ ReasoningUIPart,
5
+ SourceDocumentUIPart,
6
+ SourceUrlUIPart,
7
+ StepStartUIPart,
8
+ TextUIPart,
9
+ ToolUIPart,
10
+ UIDataTypes,
11
+ UITools,
12
+ } from "ai";
3
13
  import type { MessageDoc } from "../client/index.js";
4
14
  import { deserializeMessage, toUIFilePart } from "../mapping.js";
5
15
  import type { MessageStatus } from "../validators.js";
6
16
 
7
- export type UIMessage = AIUIMessage & {
17
+ export type UIMessage<
18
+ METADATA = unknown,
19
+ DATA_PARTS extends UIDataTypes = UIDataTypes,
20
+ TOOLS extends UITools = UITools,
21
+ > = AIUIMessage<METADATA, DATA_PARTS, TOOLS> & {
8
22
  key: string;
9
23
  order: number;
10
24
  stepOrder: number;
11
25
  status: "streaming" | MessageStatus;
12
26
  agentName?: string;
27
+ text: string;
13
28
  };
14
29
 
15
- export function toUIMessages(
30
+ export function toUIMessages<
31
+ METADATA = unknown,
32
+ DATA_PARTS extends UIDataTypes = UIDataTypes,
33
+ TOOLS extends UITools = UITools,
34
+ >(
16
35
  messages: (MessageDoc & { streaming?: boolean })[],
17
- ): UIMessage[] {
18
- const uiMessages: UIMessage[] = [];
19
- let assistantMessage: UIMessage | undefined;
36
+ ): UIMessage<METADATA, DATA_PARTS, TOOLS>[] {
37
+ const uiMessages: UIMessage<METADATA, DATA_PARTS, TOOLS>[] = [];
38
+ let assistantMessage: UIMessage<METADATA, DATA_PARTS, TOOLS> | undefined;
20
39
  for (const message of messages) {
21
40
  const coreMessage = message.message && deserializeMessage(message.message);
22
41
  const text = message.text ?? "";
@@ -31,17 +50,23 @@ export function toUIMessages(
31
50
  stepOrder: message.stepOrder,
32
51
  status: message.streaming ? ("streaming" as const) : message.status,
33
52
  key: `${message.threadId}-${message.order}-${message.stepOrder}`,
53
+ text,
54
+ };
55
+ const partCommon = {
56
+ state: message.streaming ? ("streaming" as const) : ("done" as const),
57
+ ...(message.providerMetadata
58
+ ? { providerMetadata: message.providerMetadata }
59
+ : {}),
34
60
  };
35
61
  if (coreMessage.role === "system") {
36
62
  uiMessages.push({
37
63
  ...common,
38
64
  role: "system",
39
- content: text,
40
65
  agentName: message.agentName,
41
- parts: [{ type: "text", text }],
66
+ parts: [{ type: "text", text, ...partCommon } satisfies TextUIPart],
42
67
  });
43
68
  } else if (coreMessage.role === "user") {
44
- const parts: UIMessage["parts"] = [];
69
+ const parts: UIMessage<METADATA, DATA_PARTS, TOOLS>["parts"] = [];
45
70
  if (text) {
46
71
  parts.push({ type: "text", text });
47
72
  }
@@ -56,7 +81,6 @@ export function toUIMessages(
56
81
  uiMessages.push({
57
82
  ...common,
58
83
  role: "user",
59
- content: message.text ?? "",
60
84
  parts,
61
85
  });
62
86
  } else {
@@ -72,7 +96,6 @@ export function toUIMessages(
72
96
  ...common,
73
97
  role: "assistant",
74
98
  agentName: message.agentName,
75
- content: "",
76
99
  parts: [],
77
100
  };
78
101
  uiMessages.push(assistantMessage);
@@ -83,78 +106,134 @@ export function toUIMessages(
83
106
  }
84
107
  // update it to the last message's id
85
108
  assistantMessage.id = message._id;
86
- if (message.reasoning) {
109
+ if (
110
+ message.reasoning &&
111
+ !nonStringContent.some((c) => c.type === "reasoning")
112
+ ) {
87
113
  assistantMessage.parts.push({
88
114
  type: "reasoning",
89
- reasoning: message.reasoning,
90
- details: message.reasoningDetails ?? [],
91
- });
115
+ text: message.reasoning,
116
+ ...partCommon,
117
+ } satisfies ReasoningUIPart);
92
118
  }
93
- if (message.text) {
119
+ if (message.text && !nonStringContent.length) {
94
120
  assistantMessage.parts.push({
95
121
  type: "text",
96
122
  text: message.text,
97
- });
98
- assistantMessage.content += message.text;
123
+ ...partCommon,
124
+ } satisfies TextUIPart);
99
125
  }
100
126
  for (const source of message.sources ?? []) {
101
- assistantMessage.parts.push({
102
- type: "source",
103
- source,
104
- });
127
+ if (source.sourceType === "url") {
128
+ assistantMessage.parts.push({
129
+ type: "source-url",
130
+ url: source.url!,
131
+ sourceId: source.id,
132
+ providerMetadata: message.providerMetadata,
133
+ title: source.title,
134
+ } satisfies SourceUrlUIPart);
135
+ } else {
136
+ assistantMessage.parts.push({
137
+ type: "source-document",
138
+ mediaType: source.mediaType,
139
+ sourceId: source.id,
140
+ title: source.title,
141
+ filename: source.filename,
142
+ providerMetadata: message.providerMetadata,
143
+ } satisfies SourceDocumentUIPart);
144
+ }
105
145
  }
106
146
  for (const contentPart of nonStringContent) {
107
147
  switch (contentPart.type) {
148
+ case "text":
149
+ assistantMessage.parts.push({
150
+ ...partCommon,
151
+ ...contentPart,
152
+ } satisfies TextUIPart);
153
+ break;
154
+ case "reasoning":
155
+ assistantMessage.parts.push({
156
+ ...partCommon,
157
+ ...contentPart,
158
+ } satisfies ReasoningUIPart);
159
+ break;
108
160
  case "file":
109
161
  case "image":
110
162
  assistantMessage.parts.push(toUIFilePart(contentPart));
111
163
  break;
112
- case "tool-call":
164
+ case "tool-call": {
113
165
  assistantMessage.parts.push({
114
166
  type: "step-start",
115
- });
116
- assistantMessage.parts.push({
117
- type: "tool-invocation",
118
- toolInvocation: {
119
- state: "call",
120
- step: assistantMessage.parts.filter(
121
- (part) => part.type === "tool-invocation",
122
- ).length,
123
- toolCallId: contentPart.toolCallId,
124
- toolName: contentPart.toolName,
125
- args: contentPart.args,
126
- },
127
- });
167
+ } satisfies StepStartUIPart);
168
+ const toolPart: ToolUIPart<TOOLS> = {
169
+ type: `tool-${contentPart.toolName as keyof TOOLS & string}`,
170
+ toolCallId: contentPart.toolCallId,
171
+ input: contentPart.input as DeepPartial<
172
+ TOOLS[keyof TOOLS & string]["input"]
173
+ >,
174
+ providerExecuted: contentPart.providerExecuted,
175
+ ...(message.streaming
176
+ ? { state: "input-streaming" }
177
+ : {
178
+ state: "input-available",
179
+ callProviderMetadata: message.providerMetadata,
180
+ }),
181
+ };
182
+ assistantMessage.parts.push(toolPart);
128
183
  break;
184
+ }
129
185
  case "tool-result": {
130
186
  const call = assistantMessage.parts.find(
131
187
  (part) =>
132
- part.type === "tool-invocation" &&
133
- part.toolInvocation.toolCallId === contentPart.toolCallId,
134
- ) as ToolInvocationUIPart | undefined;
135
- const toolInvocation: ToolInvocationUIPart["toolInvocation"] = {
136
- state: "result",
137
- toolCallId: contentPart.toolCallId,
138
- toolName: contentPart.toolName,
139
- args: call?.toolInvocation.args,
140
- result: contentPart.result,
141
- step:
142
- call?.toolInvocation.step ??
143
- assistantMessage.parts.filter(
144
- (part) => part.type === "tool-invocation",
145
- ).length,
146
- };
188
+ part.type === `tool-${contentPart.toolName}` &&
189
+ "toolCallId" in part &&
190
+ part.toolCallId === contentPart.toolCallId,
191
+ ) as ToolUIPart | undefined;
147
192
  if (call) {
148
- (call as ToolInvocationUIPart).toolInvocation = toolInvocation;
193
+ if (message.error) {
194
+ call.state = "output-error";
195
+ call.errorText = message.error;
196
+ call.output = contentPart.output;
197
+ } else {
198
+ call.state = "output-available";
199
+ call.output =
200
+ contentPart.output?.type === "json"
201
+ ? contentPart.output.value
202
+ : contentPart.output;
203
+ // Technically we could pull this from the doc.message
204
+ // but the ModelMessage doesn't have it
205
+ // call.providerExecuted = contentPart.providerExecuted;
206
+ }
149
207
  } else {
150
208
  console.warn(
151
209
  "Tool result without preceding tool call.. adding anyways",
152
210
  contentPart,
153
211
  );
154
- assistantMessage.parts.push({
155
- type: "tool-invocation",
156
- toolInvocation,
157
- });
212
+ if (message.error) {
213
+ assistantMessage.parts.push({
214
+ type: `tool-${contentPart.toolName}`,
215
+ toolCallId: contentPart.toolCallId,
216
+ state: "output-error",
217
+ input: undefined,
218
+ errorText: message.error,
219
+ // Technically we could pull this from the doc.message
220
+ // but the ModelMessage doesn't have it
221
+ // providerExecuted: contentPart.providerExecuted,
222
+ callProviderMetadata: message.providerMetadata,
223
+ } satisfies ToolUIPart<TOOLS>);
224
+ } else {
225
+ assistantMessage.parts.push({
226
+ type: `tool-${contentPart.toolName}`,
227
+ toolCallId: contentPart.toolCallId,
228
+ state: "output-available",
229
+ input: undefined,
230
+ output:
231
+ contentPart.output?.type === "json"
232
+ ? contentPart.output.value
233
+ : contentPart.output,
234
+ callProviderMetadata: message.providerMetadata,
235
+ } satisfies ToolUIPart<TOOLS>);
236
+ }
158
237
  }
159
238
  break;
160
239
  }
@@ -1,108 +1,9 @@
1
- import type {
2
- TextStreamPart as AITextStreamPart,
3
- AssistantContent,
4
- CoreAssistantMessage,
5
- CoreMessage,
6
- CoreSystemMessage,
7
- CoreToolMessage,
8
- CoreUserMessage,
9
- FilePart,
10
- ImagePart,
11
- TextPart,
12
- ToolCallPart,
13
- ToolContent,
14
- ToolSet,
15
- UserContent,
16
- } from "ai";
1
+ import type { TextStreamPart as AITextStreamPart, ToolSet } from "ai";
17
2
  import type { Infer } from "convex/values";
18
3
  import { expectTypeOf, test } from "vitest";
19
4
  import type { ContextOptions, StorageOptions } from "./client/types.js";
20
- import type { SerializeUrlsAndUint8Arrays } from "./mapping.js";
21
5
  import type { TextStreamPart } from "./validators.js";
22
- import {
23
- vAssistantContent,
24
- vAssistantMessage,
25
- vContextOptions,
26
- vFilePart,
27
- vImagePart,
28
- vMessage,
29
- vReasoningPart,
30
- vRedactedReasoningPart,
31
- vStorageOptions,
32
- vSystemMessage,
33
- vTextPart,
34
- vToolCallPart,
35
- vToolContent,
36
- vToolMessage,
37
- vUserContent,
38
- vUserMessage,
39
- } from "./validators.js";
40
-
41
- // type assertion
42
- type OurUserContent = SerializeUrlsAndUint8Arrays<UserContent>;
43
- expectTypeOf<OurUserContent>().toExtend<Infer<typeof vUserContent>>();
44
- expectTypeOf<Infer<typeof vUserContent>>().toExtend<OurUserContent>();
45
-
46
- type OurAssistantContent = SerializeUrlsAndUint8Arrays<AssistantContent>;
47
- expectTypeOf<OurAssistantContent>().toExtend<Infer<typeof vAssistantContent>>();
48
- expectTypeOf<Infer<typeof vAssistantContent>>().toExtend<OurAssistantContent>();
49
-
50
- type OurToolContent = SerializeUrlsAndUint8Arrays<ToolContent>;
51
- expectTypeOf<OurToolContent>().toExtend<Infer<typeof vToolContent>>();
52
- expectTypeOf<Infer<typeof vToolContent>>().toExtend<OurToolContent>();
53
-
54
- expectTypeOf<Infer<typeof vToolCallPart>>().toExtend<ToolCallPart>();
55
- expectTypeOf<ToolCallPart>().toExtend<Infer<typeof vToolCallPart>>();
56
-
57
- type OurTextPart = SerializeUrlsAndUint8Arrays<TextPart>;
58
- expectTypeOf<OurTextPart>().toExtend<Infer<typeof vTextPart>>();
59
- expectTypeOf<Infer<typeof vTextPart>>().toExtend<OurTextPart>();
60
-
61
- type OurImagePart = SerializeUrlsAndUint8Arrays<ImagePart>;
62
- expectTypeOf<OurImagePart>().toExtend<Infer<typeof vImagePart>>();
63
- expectTypeOf<Infer<typeof vImagePart>>().toExtend<OurImagePart>();
64
-
65
- type OurFilePart = SerializeUrlsAndUint8Arrays<FilePart>;
66
- expectTypeOf<OurFilePart>().toExtend<Infer<typeof vFilePart>>();
67
- expectTypeOf<Infer<typeof vFilePart>>().toExtend<OurFilePart>();
68
-
69
- // narrow to the type
70
- type ReasoningPart = AssistantContent[number] & { type: "reasoning" } & object;
71
- type OurReasoningPart = SerializeUrlsAndUint8Arrays<ReasoningPart>;
72
- expectTypeOf<OurReasoningPart>().toExtend<Infer<typeof vReasoningPart>>();
73
- expectTypeOf<Infer<typeof vReasoningPart>>().toExtend<OurReasoningPart>();
74
-
75
- // narrow to the type
76
- type RedactedReasoningPart = AssistantContent[number] & {
77
- type: "redacted-reasoning";
78
- } & object;
79
- type OurRedactedReasoningPart =
80
- SerializeUrlsAndUint8Arrays<RedactedReasoningPart>;
81
- expectTypeOf<OurRedactedReasoningPart>().toExtend<
82
- Infer<typeof vRedactedReasoningPart>
83
- >();
84
- expectTypeOf<
85
- Infer<typeof vRedactedReasoningPart>
86
- >().toExtend<OurRedactedReasoningPart>();
87
-
88
- // test("noop", () => {
89
- type OurUserMessage = SerializeUrlsAndUint8Arrays<CoreUserMessage>;
90
- expectTypeOf<OurUserMessage>().toExtend<Infer<typeof vUserMessage>>();
91
- expectTypeOf<Infer<typeof vUserMessage>>().toExtend<OurUserMessage>();
92
-
93
- type OurAssistantMessage = SerializeUrlsAndUint8Arrays<CoreAssistantMessage>;
94
- expectTypeOf<OurAssistantMessage>().toExtend<Infer<typeof vAssistantMessage>>();
95
- expectTypeOf<Infer<typeof vAssistantMessage>>().toExtend<OurAssistantMessage>();
96
-
97
- expectTypeOf<Infer<typeof vToolMessage>>().toExtend<CoreToolMessage>();
98
- expectTypeOf<CoreToolMessage>().toExtend<Infer<typeof vToolMessage>>();
99
-
100
- expectTypeOf<Infer<typeof vSystemMessage>>().toExtend<CoreSystemMessage>();
101
- expectTypeOf<CoreSystemMessage>().toExtend<Infer<typeof vSystemMessage>>();
102
-
103
- type OurMessage = SerializeUrlsAndUint8Arrays<CoreMessage>;
104
- expectTypeOf<OurMessage>().toExtend<Infer<typeof vMessage>>();
105
- expectTypeOf<Infer<typeof vMessage>>().toExtend<OurMessage>();
6
+ import { vContextOptions, vStorageOptions } from "./validators.js";
106
7
 
107
8
  expectTypeOf<Infer<typeof vContextOptions>>().toExtend<ContextOptions>();
108
9
  expectTypeOf<ContextOptions>().toExtend<Infer<typeof vContextOptions>>();
package/src/validators.ts CHANGED
@@ -1,10 +1,4 @@
1
- import {
2
- v,
3
- type Infer,
4
- type ObjectType,
5
- type Validator,
6
- type Value,
7
- } from "convex/values";
1
+ import { v, type Infer, type Validator, type Value } from "convex/values";
8
2
  import { vVectorDimension } from "./component/vector/tables.js";
9
3
 
10
4
  // const deprecated = v.optional(v.any()) as unknown as VNull<unknown, "optional">;
@@ -69,6 +63,7 @@ export const vReasoningPart = v.object({
69
63
  text: v.string(),
70
64
  signature: v.optional(v.string()),
71
65
  providerOptions,
66
+ state: v.optional(v.union(v.literal("streaming"), v.literal("done"))),
72
67
  });
73
68
 
74
69
  export const vRedactedReasoningPart = v.object({
@@ -79,6 +74,7 @@ export const vRedactedReasoningPart = v.object({
79
74
 
80
75
  export const vReasoningDetails = v.array(
81
76
  v.union(
77
+ vReasoningPart,
82
78
  v.object({
83
79
  type: v.literal("text"),
84
80
  text: v.string(),
@@ -97,6 +93,7 @@ export const vToolCallPart = v.object({
97
93
  toolName: v.string(),
98
94
  args: v.any(),
99
95
  providerOptions,
96
+ providerExecuted: v.optional(v.boolean()),
100
97
  });
101
98
 
102
99
  export const vAssistantContent = v.union(
@@ -126,17 +123,20 @@ const vToolResultContent = v.array(
126
123
  ),
127
124
  );
128
125
 
129
- const vToolResultPart = v.object({
126
+ export const vToolResultPart = v.object({
130
127
  type: v.literal("tool-result"),
131
128
  toolCallId: v.string(),
132
129
  toolName: v.string(),
133
130
  result: v.any(),
131
+ providerOptions,
132
+ providerExecuted: v.optional(v.boolean()),
133
+
134
+ // Deprecated in ai v5
135
+ isError: v.optional(v.boolean()),
134
136
  // This is only here b/c steps include it in toolResults
135
- // Normal CoreMessage doesn't have this
137
+ // Normal ModelMessage doesn't have this
136
138
  args: v.optional(v.any()),
137
139
  experimental_content: v.optional(vToolResultContent),
138
- isError: v.optional(v.boolean()),
139
- providerOptions,
140
140
  });
141
141
  export const vToolContent = v.array(vToolResultPart);
142
142
 
@@ -175,13 +175,25 @@ export const vMessage = v.union(
175
175
  );
176
176
  export type Message = Infer<typeof vMessage>;
177
177
 
178
- export const vSource = v.object({
179
- sourceType: v.literal("url"),
180
- id: v.string(),
181
- url: v.string(),
182
- title: v.optional(v.string()),
183
- providerOptions,
184
- });
178
+ export const vSource = v.union(
179
+ v.object({
180
+ type: v.optional(v.literal("source")),
181
+ sourceType: v.literal("url"),
182
+ id: v.string(),
183
+ url: v.optional(v.string()),
184
+ title: v.optional(v.string()),
185
+ providerOptions,
186
+ }),
187
+ v.object({
188
+ type: v.literal("source"),
189
+ sourceType: v.literal("document"),
190
+ id: v.string(),
191
+ mediaType: v.string(),
192
+ title: v.string(),
193
+ filename: v.optional(v.string()),
194
+ providerMetadata,
195
+ }),
196
+ );
185
197
 
186
198
  export const vRequest = v.object({
187
199
  body: v.optional(v.any()),
@@ -191,29 +203,6 @@ export const vRequest = v.object({
191
203
  url: v.optional(v.string()),
192
204
  });
193
205
 
194
- const vMessageWithFileAndId = v.object({
195
- id: v.optional(v.string()),
196
- message: vMessage,
197
- fileId: v.optional(v.id("files")),
198
- });
199
-
200
- export const vResponse = v.object({
201
- id: v.string(),
202
- timestamp: v.number(),
203
- modelId: v.string(),
204
- headers: v.optional(v.record(v.string(), v.string())), // clear these?
205
- messages: v.array(vMessageWithFileAndId),
206
- body: v.optional(v.any()),
207
- });
208
-
209
- export const vResponseWithoutMessages = v.object({
210
- id: v.string(),
211
- timestamp: v.number(),
212
- modelId: v.string(),
213
- headers: v.optional(v.record(v.string(), v.string())), // clear these?
214
- body: v.optional(v.any()),
215
- });
216
-
217
206
  export const vFinishReason = v.union(
218
207
  v.literal("stop"),
219
208
  v.literal("length"),
@@ -228,10 +217,12 @@ export const vUsage = v.object({
228
217
  promptTokens: v.number(),
229
218
  completionTokens: v.number(),
230
219
  totalTokens: v.number(),
220
+ reasoningTokens: v.optional(v.number()),
221
+ cachedInputTokens: v.optional(v.number()),
231
222
  });
232
223
  export type Usage = Infer<typeof vUsage>;
233
224
 
234
- export const vLanguageModelV1CallWarning = v.union(
225
+ export const vLanguageModelCallWarning = v.union(
235
226
  v.object({
236
227
  type: v.literal("unsupported-setting"),
237
228
  setting: v.string(),
@@ -242,17 +233,14 @@ export const vLanguageModelV1CallWarning = v.union(
242
233
  tool: v.any(),
243
234
  details: v.optional(v.string()),
244
235
  }),
245
- v.object({
246
- type: v.literal("other"),
247
- message: v.string(),
248
- }),
236
+ v.object({ type: v.literal("other"), message: v.string() }),
249
237
  );
250
238
 
251
239
  export const vMessageWithMetadataInternal = v.object({
252
- id: v.optional(v.string()), // external id, e.g. from Vercel AI SDK
253
240
  message: vMessage,
254
241
  text: v.optional(v.string()),
255
242
  fileIds: v.optional(v.array(v.id("files"))),
243
+ status: v.optional(vMessageStatus),
256
244
  // metadata
257
245
  finishReason: v.optional(vFinishReason),
258
246
  model: v.optional(v.string()),
@@ -262,7 +250,7 @@ export const vMessageWithMetadataInternal = v.object({
262
250
  reasoning: v.optional(v.string()),
263
251
  reasoningDetails: v.optional(vReasoningDetails),
264
252
  usage: v.optional(vUsage),
265
- warnings: v.optional(v.array(vLanguageModelV1CallWarning)),
253
+ warnings: v.optional(v.array(vLanguageModelCallWarning)),
266
254
  error: v.optional(v.string()),
267
255
  });
268
256
  export const vMessageWithMetadata = v.object({
@@ -271,24 +259,20 @@ export const vMessageWithMetadata = v.object({
271
259
  });
272
260
  export type MessageWithMetadata = Infer<typeof vMessageWithMetadata>;
273
261
 
274
- export const vMessageEmbeddings = v.object({
262
+ export const vMessageEmbeddingsWithDimension = v.object({
275
263
  model: v.string(),
276
264
  dimension: vVectorDimension,
277
265
  vectors: v.array(v.union(v.array(v.number()), v.null())),
278
266
  });
279
- export type MessageEmbeddings = Infer<typeof vMessageEmbeddings>;
267
+ export type MessageEmbeddingsWithDimension = Infer<
268
+ typeof vMessageEmbeddingsWithDimension
269
+ >;
280
270
 
281
- export const vObjectResult = v.object({
282
- request: vRequest,
283
- response: vResponseWithoutMessages,
284
- finishReason: vFinishReason,
285
- usage: v.optional(v.any()),
286
- object: v.any(),
287
- error: v.optional(v.string()),
288
- warnings: v.optional(v.array(vLanguageModelV1CallWarning)),
289
- providerMetadata,
271
+ export const vMessageEmbeddings = v.object({
272
+ model: v.string(),
273
+ vectors: v.array(v.union(v.array(v.number()), v.null())),
290
274
  });
291
- export type ObjectResult = Infer<typeof vObjectResult>;
275
+ export type MessageEmbeddings = Infer<typeof vMessageEmbeddings>;
292
276
 
293
277
  export const vContextOptionsSearchOptions = v.object({
294
278
  limit: v.number(),
@@ -318,18 +302,19 @@ const vPromptFields = {
318
302
  promptMessageId: v.optional(v.string()),
319
303
  };
320
304
 
321
- export const vCallSettingsFields = {
322
- maxTokens: v.optional(v.number()),
305
+ export const vCallSettings = v.object({
306
+ maxOutputTokens: v.optional(v.number()),
323
307
  temperature: v.optional(v.number()),
324
308
  topP: v.optional(v.number()),
325
309
  topK: v.optional(v.number()),
326
310
  presencePenalty: v.optional(v.number()),
327
311
  frequencyPenalty: v.optional(v.number()),
312
+ stopSequences: v.optional(v.array(v.string())),
328
313
  seed: v.optional(v.number()),
329
314
  maxRetries: v.optional(v.number()),
330
315
  headers: v.optional(v.record(v.string(), v.string())),
331
- };
332
- export type CallSettings = ObjectType<typeof vCallSettingsFields>;
316
+ });
317
+ export type CallSettings = Infer<typeof vCallSettings>;
333
318
 
334
319
  const vCommonArgs = {
335
320
  userId: v.optional(v.string()),
@@ -337,7 +322,7 @@ const vCommonArgs = {
337
322
  contextOptions: v.optional(vContextOptions),
338
323
  storageOptions: v.optional(vStorageOptions),
339
324
  providerOptions,
340
- ...vCallSettingsFields,
325
+ callSettings: v.optional(vCallSettings),
341
326
  ...vPromptFields,
342
327
  };
343
328
 
@@ -388,7 +373,7 @@ export function vPaginationResult<
388
373
  });
389
374
  }
390
375
 
391
- export const vTextStreamPart = v.union(
376
+ export const vTextStreamPartV4 = v.union(
392
377
  v.object({
393
378
  type: v.literal("text-delta"),
394
379
  textDelta: v.string(),
@@ -399,9 +384,16 @@ export const vTextStreamPart = v.union(
399
384
  }),
400
385
  v.object({
401
386
  type: v.literal("source"),
402
- source: vSource,
387
+ source: v.object({
388
+ sourceType: v.literal("url"),
389
+ id: v.string(),
390
+ url: v.optional(v.string()),
391
+ title: v.optional(v.string()),
392
+ providerOptions,
393
+ }),
403
394
  }),
404
395
  vToolCallPart,
396
+ vToolResultPart,
405
397
  v.object({
406
398
  type: v.literal("tool-call-streaming-start"),
407
399
  toolCallId: v.string(),
@@ -413,8 +405,59 @@ export const vTextStreamPart = v.union(
413
405
  toolName: v.string(),
414
406
  argsTextDelta: v.string(),
415
407
  }),
416
- vToolResultPart,
417
408
  );
409
+ export const vTextStreamPartV5 = v.union(
410
+ v.object({
411
+ type: v.literal("text-delta"),
412
+ id: v.string(),
413
+ text: v.string(),
414
+ providerMetadata,
415
+ }),
416
+ v.object({
417
+ type: v.literal("reasoning-delta"),
418
+ id: v.string(),
419
+ text: v.string(),
420
+ providerMetadata,
421
+ }),
422
+ vSource,
423
+ v.object({
424
+ type: v.literal("tool-call"),
425
+ toolCallId: v.string(),
426
+ toolName: v.string(),
427
+ input: v.any(),
428
+ providerExecuted: v.optional(v.boolean()),
429
+ dynamic: v.optional(v.boolean()),
430
+ providerMetadata,
431
+ }),
432
+ v.object({
433
+ type: v.literal("tool-input-start"),
434
+ id: v.string(),
435
+ toolName: v.string(),
436
+ providerMetadata,
437
+ providerExecuted: v.optional(v.boolean()),
438
+ dynamic: v.optional(v.boolean()),
439
+ }),
440
+ v.object({
441
+ type: v.literal("tool-input-delta"),
442
+ id: v.string(),
443
+ delta: v.string(),
444
+ providerMetadata,
445
+ }),
446
+ v.object({
447
+ type: v.literal("tool-result"),
448
+ toolCallId: v.string(),
449
+ toolName: v.string(),
450
+ input: v.optional(v.any()),
451
+ output: v.optional(v.any()),
452
+ providerExecuted: v.optional(v.boolean()),
453
+ dynamic: v.optional(v.boolean()),
454
+ }),
455
+ v.object({
456
+ type: v.literal("raw"),
457
+ rawValue: v.any(),
458
+ }),
459
+ );
460
+ export const vTextStreamPart = v.union(vTextStreamPartV4, vTextStreamPartV5);
418
461
  export type TextStreamPart = Infer<typeof vTextStreamPart>;
419
462
 
420
463
  export const vStreamCursor = v.object({