@convex-dev/agent 0.2.0-alpha.2 → 0.2.1

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 (100) hide show
  1. package/dist/client/createTool.d.ts +4 -6
  2. package/dist/client/createTool.d.ts.map +1 -1
  3. package/dist/client/createTool.js +0 -1
  4. package/dist/client/createTool.js.map +1 -1
  5. package/dist/client/definePlaygroundAPI.d.ts +28 -28
  6. package/dist/client/files.d.ts +9 -2
  7. package/dist/client/files.d.ts.map +1 -1
  8. package/dist/client/files.js +61 -6
  9. package/dist/client/files.js.map +1 -1
  10. package/dist/client/index.d.ts +232 -242
  11. package/dist/client/index.d.ts.map +1 -1
  12. package/dist/client/index.js +375 -383
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/client/messages.d.ts +91 -373
  15. package/dist/client/messages.d.ts.map +1 -1
  16. package/dist/client/messages.js +7 -1
  17. package/dist/client/messages.js.map +1 -1
  18. package/dist/client/search.d.ts +15 -15
  19. package/dist/client/search.d.ts.map +1 -1
  20. package/dist/client/search.js +3 -3
  21. package/dist/client/search.js.map +1 -1
  22. package/dist/client/streaming.d.ts +30 -22
  23. package/dist/client/streaming.d.ts.map +1 -1
  24. package/dist/client/streaming.js +36 -40
  25. package/dist/client/streaming.js.map +1 -1
  26. package/dist/client/types.d.ts +148 -61
  27. package/dist/client/types.d.ts.map +1 -1
  28. package/dist/component/_generated/api.d.ts +47 -357
  29. package/dist/component/messages.d.ts +157 -150
  30. package/dist/component/messages.d.ts.map +1 -1
  31. package/dist/component/messages.js +124 -70
  32. package/dist/component/messages.js.map +1 -1
  33. package/dist/component/schema.d.ts +1147 -2687
  34. package/dist/component/schema.d.ts.map +1 -1
  35. package/dist/component/schema.js +5 -4
  36. package/dist/component/schema.js.map +1 -1
  37. package/dist/component/streams.d.ts +29 -323
  38. package/dist/component/streams.d.ts.map +1 -1
  39. package/dist/component/streams.js +104 -60
  40. package/dist/component/streams.js.map +1 -1
  41. package/dist/component/threads.d.ts +4 -4
  42. package/dist/component/users.d.ts +3 -3
  43. package/dist/mapping.d.ts +4 -1
  44. package/dist/mapping.d.ts.map +1 -1
  45. package/dist/mapping.js +17 -1
  46. package/dist/mapping.js.map +1 -1
  47. package/dist/parts.d.ts +3 -0
  48. package/dist/parts.d.ts.map +1 -0
  49. package/dist/parts.js +34 -0
  50. package/dist/parts.js.map +1 -0
  51. package/dist/react/SmoothText.d.ts +5 -0
  52. package/dist/react/SmoothText.d.ts.map +1 -0
  53. package/dist/react/SmoothText.js +6 -0
  54. package/dist/react/SmoothText.js.map +1 -0
  55. package/dist/react/deltas.d.ts +3 -2
  56. package/dist/react/deltas.d.ts.map +1 -1
  57. package/dist/react/deltas.js +19 -79
  58. package/dist/react/deltas.js.map +1 -1
  59. package/dist/react/index.d.ts +1 -0
  60. package/dist/react/index.d.ts.map +1 -1
  61. package/dist/react/index.js +31 -11
  62. package/dist/react/index.js.map +1 -1
  63. package/dist/react/optimisticallySendMessage.d.ts.map +1 -1
  64. package/dist/react/optimisticallySendMessage.js +2 -8
  65. package/dist/react/optimisticallySendMessage.js.map +1 -1
  66. package/dist/react/useSmoothText.d.ts +13 -12
  67. package/dist/react/useSmoothText.d.ts.map +1 -1
  68. package/dist/react/useSmoothText.js +1 -1
  69. package/dist/react/useSmoothText.js.map +1 -1
  70. package/dist/shared.d.ts +3 -3
  71. package/dist/shared.d.ts.map +1 -1
  72. package/dist/shared.js.map +1 -1
  73. package/dist/validators.d.ts +109 -1590
  74. package/dist/validators.d.ts.map +1 -1
  75. package/dist/validators.js +4 -81
  76. package/dist/validators.js.map +1 -1
  77. package/package.json +3 -3
  78. package/src/client/createTool.ts +5 -10
  79. package/src/client/files.ts +89 -11
  80. package/src/client/index.test.ts +25 -35
  81. package/src/client/index.ts +686 -652
  82. package/src/client/messages.ts +16 -2
  83. package/src/client/search.ts +10 -7
  84. package/src/client/streaming.ts +62 -57
  85. package/src/client/types.ts +227 -97
  86. package/src/component/_generated/api.d.ts +47 -357
  87. package/src/component/messages.ts +157 -96
  88. package/src/component/schema.ts +4 -4
  89. package/src/component/streams.ts +180 -69
  90. package/src/mapping.ts +23 -2
  91. package/src/parts.ts +39 -0
  92. package/src/react/SmoothText.tsx +9 -0
  93. package/src/react/deltas.test.ts +38 -42
  94. package/src/react/deltas.ts +24 -86
  95. package/src/react/index.ts +35 -13
  96. package/src/react/optimisticallySendMessage.ts +2 -8
  97. package/src/react/useSmoothText.ts +14 -15
  98. package/src/shared.ts +3 -3
  99. package/src/validators.test.ts +0 -17
  100. package/src/validators.ts +8 -101
@@ -1,12 +1,11 @@
1
+ import type { TextStreamPart, ToolSet } from "ai";
1
2
  import type { MessageDoc } from "../client/index.js";
2
3
  import type {
3
4
  Message,
4
5
  MessageStatus,
5
6
  StreamDelta,
6
7
  StreamMessage,
7
- TextStreamPart,
8
8
  vReasoningPart,
9
- vSource,
10
9
  vTextPart,
11
10
  vToolCallPart,
12
11
  vToolResultPart,
@@ -74,7 +73,7 @@ export function applyDeltasToStreamMessage(
74
73
  ): [{ streamId: string; cursor: number; messages: MessageDoc[] }, boolean] {
75
74
  let changed = false;
76
75
  let cursor = existing?.cursor ?? 0;
77
- let parts: TextStreamPart[] = [];
76
+ let parts: TextStreamPart<ToolSet>[] = [];
78
77
  for (const delta of deltas.sort((a, b) => a.start - b.start)) {
79
78
  if (delta.parts.length === 0) {
80
79
  console.warn(`Got delta with no parts: ${JSON.stringify(delta)}`);
@@ -162,7 +161,7 @@ export function applyDeltasToStreamMessage(
162
161
  }
163
162
  switch (part.type) {
164
163
  case "text-delta": {
165
- const text = "text" in part ? part.text : part.textDelta;
164
+ const text = part.text;
166
165
  currentMessage.text = (currentMessage.text ?? "") + text;
167
166
  if (lastContent?.type === "text") {
168
167
  lastContent.text = (lastContent.text ?? "") + text;
@@ -173,9 +172,8 @@ export function applyDeltasToStreamMessage(
173
172
  }
174
173
  break;
175
174
  }
176
- case "tool-input-start":
177
- case "tool-call-streaming-start": {
178
- const toolCallId = "toolCallId" in part ? part.toolCallId : part.id;
175
+ case "tool-input-start": {
176
+ const toolCallId = part.id;
179
177
  currentMessage.tool = true;
180
178
  contentToAdd = {
181
179
  type: "tool-call",
@@ -189,7 +187,6 @@ export function applyDeltasToStreamMessage(
189
187
  } satisfies Infer<typeof vToolCallPart>;
190
188
  break;
191
189
  }
192
- case "tool-call-delta":
193
190
  case "tool-input-delta":
194
191
  {
195
192
  currentMessage.tool = true;
@@ -213,18 +210,6 @@ export function applyDeltasToStreamMessage(
213
210
  contentToAdd = toolResultContent(part);
214
211
  break;
215
212
  }
216
- case "reasoning":
217
- currentMessage.reasoning =
218
- (currentMessage.reasoning ?? "") + part.textDelta;
219
- if (lastContent?.type === "reasoning") {
220
- lastContent.text = (lastContent.text ?? "") + part.textDelta;
221
- } else {
222
- contentToAdd = {
223
- type: "reasoning",
224
- text: part.textDelta,
225
- };
226
- }
227
- break;
228
213
  case "reasoning-delta": {
229
214
  currentMessage.reasoning = (currentMessage.reasoning ?? "") + part.text;
230
215
  if (lastContent?.type === "reasoning") {
@@ -244,17 +229,10 @@ export function applyDeltasToStreamMessage(
244
229
  if (!currentMessage.sources) {
245
230
  currentMessage.sources = [];
246
231
  }
247
- if ("source" in part) {
248
- currentMessage.sources.push({
249
- type: "source",
250
- ...part.source,
251
- } satisfies Infer<typeof vSource>);
252
- } else {
253
- currentMessage.sources.push(part);
254
- }
232
+ currentMessage.sources.push(part);
255
233
  break;
256
234
  case "raw":
257
- contentToAdd = part.rawValue;
235
+ // ignore
258
236
  break;
259
237
  default:
260
238
  console.warn(`Received unexpected part: ${JSON.stringify(part)}`);
@@ -276,7 +254,7 @@ export function applyDeltasToStreamMessage(
276
254
  }
277
255
 
278
256
  function toolCallContent(
279
- part: Extract<TextStreamPart, { type: "tool-call" }>,
257
+ part: Extract<TextStreamPart<ToolSet>, { type: "tool-call" }>,
280
258
  ): Infer<typeof vToolCallPart> {
281
259
  const args = "args" in part ? part.args : part.input;
282
260
  return {
@@ -289,18 +267,14 @@ function toolCallContent(
289
267
  }
290
268
 
291
269
  function toolResultContent(
292
- part: Extract<TextStreamPart, { type: "tool-result" }>,
270
+ part: Extract<TextStreamPart<ToolSet>, { type: "tool-result" }>,
293
271
  ): Infer<typeof vToolResultPart> {
294
- const result =
295
- "output" in part ? part.output : "result" in part ? part.result : undefined;
296
- const args =
297
- "input" in part ? part.input : "args" in part ? part.args : undefined;
298
272
  return {
299
273
  type: "tool-result",
300
274
  toolCallId: part.toolCallId,
301
275
  toolName: part.toolName,
302
- result,
303
- args,
276
+ result: part.output,
277
+ args: part.input,
304
278
  providerExecuted: part.providerExecuted,
305
279
  } satisfies Infer<typeof vToolResultPart>;
306
280
  }
@@ -344,7 +318,7 @@ function statusFromStreamStatus(
344
318
  export function createStreamingMessage(
345
319
  threadId: string,
346
320
  message: StreamMessage,
347
- part: TextStreamPart,
321
+ part: TextStreamPart<ToolSet>,
348
322
  index: number,
349
323
  ): MessageDoc {
350
324
  const { streamId, ...rest } = message;
@@ -358,19 +332,14 @@ export function createStreamingMessage(
358
332
  };
359
333
  switch (part.type) {
360
334
  case "text-delta": {
361
- const text = "text" in part ? part.text : part.textDelta;
335
+ const text = part.text || "";
362
336
  return {
363
337
  ...metadata,
364
- message: {
365
- role: "assistant",
366
- content: [{ type: "text", text }],
367
- },
338
+ message: { role: "assistant", content: [{ type: "text", text }] },
368
339
  text,
369
340
  };
370
341
  }
371
- case "tool-input-start":
372
- case "tool-call-streaming-start": {
373
- const toolCallId = "toolCallId" in part ? part.toolCallId : part.id;
342
+ case "tool-input-start": {
374
343
  return {
375
344
  ...metadata,
376
345
  tool: true,
@@ -380,7 +349,7 @@ export function createStreamingMessage(
380
349
  {
381
350
  type: "tool-call",
382
351
  toolName: part.toolName,
383
- toolCallId,
352
+ toolCallId: part.id,
384
353
  args: "", // when it's a string, it's a partial call
385
354
  providerExecuted:
386
355
  "providerExecuted" in part ? part.providerExecuted : undefined,
@@ -391,26 +360,17 @@ export function createStreamingMessage(
391
360
  },
392
361
  };
393
362
  }
394
- case "tool-input-delta":
395
- case "tool-call-delta": {
363
+ case "tool-input-delta": {
396
364
  console.warn("Received tool call delta part first??");
397
- const delta = "argsTextDelta" in part ? part.argsTextDelta : part.delta;
398
- const toolCallId = "toolCallId" in part ? part.toolCallId : part.id;
399
- const toolName =
400
- "toolName" in part ? part.toolName : part.type.slice("tool-".length);
365
+ const delta = part.delta;
366
+ const toolCallId = part.id;
367
+ const toolName = part.type.slice("tool-".length);
401
368
  return {
402
369
  ...metadata,
403
370
  tool: true,
404
371
  message: {
405
372
  role: "assistant",
406
- content: [
407
- {
408
- type: "tool-call",
409
- toolCallId,
410
- toolName,
411
- args: delta,
412
- },
413
- ],
373
+ content: [{ type: "tool-call", toolCallId, toolName, args: delta }],
414
374
  },
415
375
  };
416
376
  }
@@ -418,29 +378,14 @@ export function createStreamingMessage(
418
378
  return {
419
379
  ...metadata,
420
380
  tool: true,
421
- message: {
422
- role: "assistant",
423
- content: [toolCallContent(part)],
424
- },
381
+ message: { role: "assistant", content: [toolCallContent(part)] },
425
382
  };
426
383
  }
427
384
  case "tool-result":
428
385
  return {
429
386
  ...metadata,
430
387
  tool: true,
431
- message: {
432
- role: "tool",
433
- content: [toolResultContent(part)],
434
- },
435
- };
436
- case "reasoning":
437
- return {
438
- ...metadata,
439
- message: {
440
- role: "assistant",
441
- content: [{ type: "reasoning", text: part.textDelta }],
442
- },
443
- reasoning: part.textDelta,
388
+ message: { role: "tool", content: [toolResultContent(part)] },
444
389
  };
445
390
  case "reasoning-delta": {
446
391
  return {
@@ -458,14 +403,7 @@ export function createStreamingMessage(
458
403
  ...metadata,
459
404
  tool: true,
460
405
  message: { role: "tool", content: [] },
461
- sources: [
462
- "source" in part
463
- ? {
464
- ...part.source,
465
- type: "source",
466
- }
467
- : part,
468
- ],
406
+ sources: [part],
469
407
  };
470
408
  // case "raw":
471
409
  // return {
@@ -7,7 +7,7 @@ import {
7
7
  } from "convex/react";
8
8
  import { usePaginatedQuery } from "convex-helpers/react";
9
9
  import type { FunctionArgs } from "convex/server";
10
- import { useMemo, useRef, useState } from "react";
10
+ import { useMemo, useState } from "react";
11
11
  import type { MessageDoc } from "../client/index.js";
12
12
  import type { SyncStreamsReturnValue } from "../client/types.js";
13
13
  import type { StreamArgs } from "../validators.js";
@@ -23,6 +23,7 @@ import type {
23
23
 
24
24
  export { optimisticallySendMessage } from "./optimisticallySendMessage.js";
25
25
  export { useSmoothText } from "./useSmoothText.js";
26
+ export { SmoothText } from "./SmoothText.js";
26
27
  export { toUIMessages, type UIMessage, type ThreadQuery };
27
28
 
28
29
  /**
@@ -97,6 +98,15 @@ export function useThreadMessages<
97
98
  { initialNumItems: options.initialNumItems },
98
99
  );
99
100
 
101
+ let startOrder = paginated.results.at(-1)?.order ?? 0;
102
+ for (let i = paginated.results.length - 1; i >= 0; i--) {
103
+ const m = paginated.results[i];
104
+ if (!m.streaming && m.status === "pending") {
105
+ // round down to the nearest 10 for some cache benefits
106
+ startOrder = m.order - (m.order % 10);
107
+ break;
108
+ }
109
+ }
100
110
  // These are streaming messages that will not include full messages.
101
111
  const streamMessages = useStreamingThreadMessages(
102
112
  query as ThreadStreamQuery<
@@ -107,7 +117,7 @@ export function useThreadMessages<
107
117
  args === "skip" ||
108
118
  paginated.status === "LoadingFirstPage"
109
119
  ? "skip"
110
- : { ...args, startOrder: paginated.results.at(-1)?.order },
120
+ : { ...args, startOrder },
111
121
  );
112
122
 
113
123
  const merged = useMemo(() => {
@@ -120,16 +130,32 @@ export function useThreadMessages<
120
130
  ...paginated,
121
131
  results: paginated.results
122
132
  .map((m) => ({ ...m, streaming: false }))
133
+ // Note: this is intentionally after paginated results.
123
134
  .concat(streamListMessages)
124
135
  .sort((a, b) =>
125
136
  a.order === b.order ? a.stepOrder - b.stepOrder : a.order - b.order,
126
137
  )
127
- // They shouldn't overlap, but check for duplicates just in case.
128
- .filter(
129
- (m, i, arr) =>
130
- !arr[i - 1] ||
131
- m.order !== arr[i - 1].order ||
132
- m.stepOrder !== arr[i - 1].stepOrder,
138
+ .reduce(
139
+ (msgs, msg) => {
140
+ const last = msgs.at(-1);
141
+ if (!last) {
142
+ return [msg];
143
+ }
144
+ if (last.order !== msg.order || last.stepOrder !== msg.stepOrder) {
145
+ return [...msgs, msg];
146
+ }
147
+ if (
148
+ last.status === "pending" &&
149
+ (msg.streaming || msg.status !== "pending")
150
+ ) {
151
+ // Let's prefer a streaming or finalized message over a pending
152
+ // one.
153
+ return [...msgs.slice(0, -1), msg];
154
+ }
155
+ // skip the new one if the previous one (listed) was finalized
156
+ return msgs;
157
+ },
158
+ [] as (ThreadMessagesResult<Query> & { streaming: boolean })[],
133
159
  ),
134
160
  };
135
161
  }, [paginated, streamMessages]);
@@ -162,11 +188,7 @@ export function useStreamingThreadMessages<
162
188
  const [streams, setStreams] = useState<
163
189
  Array<{ streamId: string; cursor: number; messages: MessageDoc[] }>
164
190
  >([]);
165
- const startOrderRef = useRef<number>(0);
166
191
  const queryArgs = args === "skip" ? args : omit(args, ["startOrder"]);
167
- if (args !== "skip" && !startOrderRef.current && args.startOrder) {
168
- startOrderRef.current = args.startOrder;
169
- }
170
192
  // Get all the active streams
171
193
  const streamList = useQuery(
172
194
  query,
@@ -177,7 +199,7 @@ export function useStreamingThreadMessages<
177
199
  paginationOpts: { cursor: null, numItems: 0 },
178
200
  streamArgs: {
179
201
  kind: "list",
180
- startOrder: startOrderRef.current,
202
+ startOrder: queryArgs.startOrder ?? 0,
181
203
  } as StreamArgs,
182
204
  } as FunctionArgs<Query>),
183
205
  ) as
@@ -12,17 +12,14 @@ export function optimisticallySendMessage(
12
12
  return (store, args) => {
13
13
  const queries = store.getAllQueries(query);
14
14
  let maxOrder = -1;
15
- let maxStepOrder = 0;
16
15
  for (const q of queries) {
17
16
  if (q.args?.threadId !== args.threadId) continue;
18
17
  if (q.args.streamArgs) continue;
19
18
  for (const m of q.value?.page ?? []) {
20
19
  maxOrder = Math.max(maxOrder, m.order);
21
- maxStepOrder = Math.max(maxStepOrder, m.stepOrder);
22
20
  }
23
21
  }
24
22
  const order = maxOrder + 1;
25
- const stepOrder = 0;
26
23
  insertAtTop({
27
24
  paginatedQuery: query,
28
25
  argsToMatch: { threadId: args.threadId, streamArgs: undefined },
@@ -30,14 +27,11 @@ export function optimisticallySendMessage(
30
27
  _creationTime: Date.now(),
31
28
  _id: randomUUID(),
32
29
  order,
33
- stepOrder,
30
+ stepOrder: 0,
34
31
  status: "pending",
35
32
  threadId: args.threadId,
36
33
  tool: false,
37
- message: {
38
- role: "user",
39
- content: args.prompt,
40
- },
34
+ message: { role: "user", content: args.prompt },
41
35
  text: args.prompt,
42
36
  },
43
37
  localQueryStore: store,
@@ -3,6 +3,19 @@ import { useEffect, useRef, useState } from "react";
3
3
  const FPS = 20;
4
4
  const MS_PER_FRAME = 1000 / FPS;
5
5
  const MAX_TIME_JUMP_MS = 250;
6
+
7
+ export type SmoothTextOptions = {
8
+ /**
9
+ * The number of characters to display per second.
10
+ */
11
+ charsPerSec?: number;
12
+ /**
13
+ * Whether to initially start streaming.
14
+ * If this later turns to false, it'll continue streaming.
15
+ * This will start streaming the first value it sees.
16
+ */
17
+ startStreaming?: boolean;
18
+ };
6
19
  /**
7
20
  * A hook that smoothly displays text as it is streamed.
8
21
  *
@@ -15,21 +28,7 @@ const MAX_TIME_JUMP_MS = 250;
15
28
  */
16
29
  export function useSmoothText(
17
30
  text: string,
18
- {
19
- charsPerSec = 256,
20
- startStreaming = false,
21
- }: {
22
- /**
23
- * The number of characters to display per second.
24
- */
25
- charsPerSec?: number;
26
- /**
27
- * Whether to initially start streaming.
28
- * If this later turns to false, it'll continue streaming.
29
- * This will start streaming the first value it sees.
30
- */
31
- startStreaming?: boolean;
32
- } = {},
31
+ { charsPerSec = 256, startStreaming = false }: SmoothTextOptions = {},
33
32
  ): [string, { cursor: number; isStreaming: boolean }] {
34
33
  const [visibleText, setVisibleText] = useState(startStreaming ? "" : text);
35
34
  const smoothState = useRef({
package/src/shared.ts CHANGED
@@ -1,9 +1,9 @@
1
- import type { CoreMessage } from "ai";
1
+ import type { ModelMessage } from "ai";
2
2
  import type { Message } from "./validators.js";
3
3
 
4
4
  export const DEFAULT_RECENT_MESSAGES = 100;
5
5
 
6
- export function isTool(message: Message | CoreMessage) {
6
+ export function isTool(message: Message | ModelMessage) {
7
7
  return (
8
8
  message.role === "tool" ||
9
9
  (message.role === "assistant" &&
@@ -12,7 +12,7 @@ export function isTool(message: Message | CoreMessage) {
12
12
  );
13
13
  }
14
14
 
15
- export function extractText(message: Message | CoreMessage) {
15
+ export function extractText(message: Message | ModelMessage) {
16
16
  switch (message.role) {
17
17
  case "user":
18
18
  if (typeof message.content === "string") {
@@ -1,8 +1,6 @@
1
- import type { TextStreamPart as AITextStreamPart, ToolSet } from "ai";
2
1
  import type { Infer } from "convex/values";
3
2
  import { expectTypeOf, test } from "vitest";
4
3
  import type { ContextOptions, StorageOptions } from "./client/types.js";
5
- import type { TextStreamPart } from "./validators.js";
6
4
  import { vContextOptions, vStorageOptions } from "./validators.js";
7
5
 
8
6
  expectTypeOf<Infer<typeof vContextOptions>>().toExtend<ContextOptions>();
@@ -11,19 +9,4 @@ expectTypeOf<ContextOptions>().toExtend<Infer<typeof vContextOptions>>();
11
9
  expectTypeOf<Infer<typeof vStorageOptions>>().toExtend<StorageOptions>();
12
10
  expectTypeOf<StorageOptions>().toExtend<Infer<typeof vStorageOptions>>();
13
11
 
14
- type StreamPart = Extract<
15
- AITextStreamPart<ToolSet>,
16
- {
17
- type:
18
- | "text-delta"
19
- | "reasoning"
20
- | "source"
21
- | "tool-call"
22
- | "tool-call-streaming-start"
23
- | "tool-call-delta"
24
- | "tool-result";
25
- }
26
- >;
27
- expectTypeOf<StreamPart>().toExtend<TextStreamPart>();
28
-
29
12
  test("noop", () => {});
package/src/validators.ts CHANGED
@@ -180,7 +180,7 @@ export const vSource = v.union(
180
180
  type: v.optional(v.literal("source")),
181
181
  sourceType: v.literal("url"),
182
182
  id: v.string(),
183
- url: v.optional(v.string()),
183
+ url: v.string(),
184
184
  title: v.optional(v.string()),
185
185
  providerOptions,
186
186
  }),
@@ -253,6 +253,9 @@ export const vMessageWithMetadataInternal = v.object({
253
253
  warnings: v.optional(v.array(vLanguageModelCallWarning)),
254
254
  error: v.optional(v.string()),
255
255
  });
256
+ export type MessageWithMetadataInternal = Infer<
257
+ typeof vMessageWithMetadataInternal
258
+ >;
256
259
  export const vMessageWithMetadata = v.object({
257
260
  ...vMessageWithMetadataInternal.fields,
258
261
  fileIds: v.optional(v.array(v.string())),
@@ -334,10 +337,7 @@ export const vTextArgs = v.object({
334
337
  v.literal("auto"),
335
338
  v.literal("none"),
336
339
  v.literal("required"),
337
- v.object({
338
- type: v.literal("tool"),
339
- toolName: v.string(),
340
- }),
340
+ v.object({ type: v.literal("tool"), toolName: v.string() }),
341
341
  ),
342
342
  ),
343
343
  maxSteps: v.optional(v.number()),
@@ -373,93 +373,6 @@ export function vPaginationResult<
373
373
  });
374
374
  }
375
375
 
376
- export const vTextStreamPartV4 = v.union(
377
- v.object({
378
- type: v.literal("text-delta"),
379
- textDelta: v.string(),
380
- }),
381
- v.object({
382
- type: v.literal("reasoning"),
383
- textDelta: v.string(),
384
- }),
385
- v.object({
386
- type: v.literal("source"),
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
- }),
394
- }),
395
- vToolCallPart,
396
- vToolResultPart,
397
- v.object({
398
- type: v.literal("tool-call-streaming-start"),
399
- toolCallId: v.string(),
400
- toolName: v.string(),
401
- }),
402
- v.object({
403
- type: v.literal("tool-call-delta"),
404
- toolCallId: v.string(),
405
- toolName: v.string(),
406
- argsTextDelta: v.string(),
407
- }),
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);
461
- export type TextStreamPart = Infer<typeof vTextStreamPart>;
462
-
463
376
  export const vStreamCursor = v.object({
464
377
  streamId: v.string(),
465
378
  cursor: v.number(),
@@ -468,14 +381,8 @@ export type StreamCursor = Infer<typeof vStreamCursor>;
468
381
 
469
382
  export const vStreamArgs = v.optional(
470
383
  v.union(
471
- v.object({
472
- kind: v.literal("list"),
473
- startOrder: v.optional(v.number()),
474
- }),
475
- v.object({
476
- kind: v.literal("deltas"),
477
- cursors: v.array(vStreamCursor),
478
- }),
384
+ v.object({ kind: v.literal("list"), startOrder: v.optional(v.number()) }),
385
+ v.object({ kind: v.literal("deltas"), cursors: v.array(vStreamCursor) }),
479
386
  ),
480
387
  );
481
388
  export type StreamArgs = Infer<typeof vStreamArgs>;
@@ -502,6 +409,6 @@ export const vStreamDelta = v.object({
502
409
  streamId: v.string(),
503
410
  start: v.number(), // inclusive
504
411
  end: v.number(), // exclusive
505
- parts: v.array(vTextStreamPart),
412
+ parts: v.array(v.any()),
506
413
  });
507
414
  export type StreamDelta = Infer<typeof vStreamDelta>;