@mastra/react 1.2.5-alpha.9 → 1.2.6-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # @mastra/react
2
2
 
3
+ ## 1.2.6-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed binary file attachments missing during live streaming in `useChat` when `enableThreadSignals` is enabled. Attachments sent as `Uint8Array` or `ArrayBuffer` now render in the optimistic pending bubble and stay visible after the signal echo, without requiring a page refresh. ([#19439](https://github.com/mastra-ai/mastra/pull/19439))
8
+
9
+ - Updated dependencies [[`8a0d145`](https://github.com/mastra-ai/mastra/commit/8a0d145aadbdf7278665aceaaec364b35dd9bd94), [`bd2f1d2`](https://github.com/mastra-ai/mastra/commit/bd2f1d274d05e60e2366f005ea0d94d5cea0d5ff), [`21a0eb8`](https://github.com/mastra-ai/mastra/commit/21a0eb86746ba0b703acea360d4f84c6a5a493f2), [`de86fd7`](https://github.com/mastra-ai/mastra/commit/de86fd7119f0438381d1a642e3d258143c0b9c29), [`2745031`](https://github.com/mastra-ai/mastra/commit/2745031d1d4a4978f037092da371428c32e2842a), [`db650ce`](https://github.com/mastra-ai/mastra/commit/db650ce490348914e85b93651d83acdf8f2a4c31), [`6354eeb`](https://github.com/mastra-ai/mastra/commit/6354eeb32efa9f5f68f51dda394e90e2ee76f1fb)]:
10
+ - @mastra/core@1.51.1-alpha.0
11
+ - @mastra/client-js@1.32.1-alpha.0
12
+
13
+ ## 1.2.5
14
+
15
+ ### Patch Changes
16
+
17
+ - Fixed attachment rendering crash in `useChat` when `enableThreadSignals` is enabled. File attachments now display correctly during live streaming without requiring a page refresh. ([#19362](https://github.com/mastra-ai/mastra/pull/19362))
18
+
19
+ - Updated dependencies [[`bd6d240`](https://github.com/mastra-ai/mastra/commit/bd6d2402db93dddaef0721667e7e8a030e7c6e16), [`0111486`](https://github.com/mastra-ai/mastra/commit/01114867612593eef5cfa2fda6a1194dfedda841), [`96a3749`](https://github.com/mastra-ai/mastra/commit/96a37492235f5b8076b3e3177d83ed5a5e44a640), [`fe1bda0`](https://github.com/mastra-ai/mastra/commit/fe1bda06f6af92a694a51712db747cda1e7185f0), [`25e7c12`](https://github.com/mastra-ai/mastra/commit/25e7c126a770069ae7fb7ecf1d2adb40e017b009), [`1ce5121`](https://github.com/mastra-ai/mastra/commit/1ce512155d122bb21f47d98383e82ffbf84b39e8), [`fb8aea3`](https://github.com/mastra-ai/mastra/commit/fb8aea384291e77311be3a64ee1717320d5c3c73), [`4adc391`](https://github.com/mastra-ai/mastra/commit/4adc3911075249c352bb4832d2471922826344de), [`a5c6337`](https://github.com/mastra-ai/mastra/commit/a5c6337d23c7686c81a32ce62f550f610543a240), [`3cfc47a`](https://github.com/mastra-ai/mastra/commit/3cfc47a6b89940aadd0f46fb01ae9624a73a865d), [`2bb7817`](https://github.com/mastra-ai/mastra/commit/2bb78176112fde628483de2830528f7eee911e56), [`e2d5f37`](https://github.com/mastra-ai/mastra/commit/e2d5f373bd289be534d5f8694d34465010533df6), [`51d9870`](https://github.com/mastra-ai/mastra/commit/51d987032c689c2855374d0f244f5d654da809d1), [`5cab274`](https://github.com/mastra-ai/mastra/commit/5cab2744250e22d12fefa7b32637dce224233cee), [`7fa27d3`](https://github.com/mastra-ai/mastra/commit/7fa27d3b6f5ed68cd34e454a4d3ad9c482a0cfbc), [`8b97958`](https://github.com/mastra-ai/mastra/commit/8b979589f9aa59ba67cac565949475f2ffeb4ac3), [`8410541`](https://github.com/mastra-ai/mastra/commit/84105412c60ecd3bb33a9838146f59c4b588228f), [`a58dcbb`](https://github.com/mastra-ai/mastra/commit/a58dcbb546d7e1d65ebdc1f39e55f0908fcd9391), [`aa38805`](https://github.com/mastra-ai/mastra/commit/aa38805b878b827403be785eb90688d7172f5a40), [`fd13f8e`](https://github.com/mastra-ai/mastra/commit/fd13f8e21990f9904c3eedba3a626bb4a929cdb8), [`153bd3b`](https://github.com/mastra-ai/mastra/commit/153bd3b396bdfed6b74cf43de12db8fd2d83c04a), [`45a8e65`](https://github.com/mastra-ai/mastra/commit/45a8e65e1556d1362cb3f25187023c36de26661d), [`e955965`](https://github.com/mastra-ai/mastra/commit/e955965dce575a903e37cf054d28ea99aa48785e), [`2d22570`](https://github.com/mastra-ai/mastra/commit/2d22570c7dfdd02123d0ecc529efb05ccba2d9fc), [`07bb863`](https://github.com/mastra-ai/mastra/commit/07bb8631919c6f7cf377dccd45b096e0f17fbed0), [`c8ed116`](https://github.com/mastra-ai/mastra/commit/c8ed11699f62bcac70102ab4ec84d80d20541da6), [`01b338c`](https://github.com/mastra-ai/mastra/commit/01b338c56271f0219606710e3e8b26dee27ac6c2), [`a99eae8`](https://github.com/mastra-ai/mastra/commit/a99eae8908e500c1b2d12f9d277be616b98617a5), [`860ef7e`](https://github.com/mastra-ai/mastra/commit/860ef7e77d92b63469cbe5857aa1e626197e43e9), [`17e818c`](https://github.com/mastra-ai/mastra/commit/17e818c51a958ba90641b1a959dc38faf8c034e9), [`edce8d2`](https://github.com/mastra-ai/mastra/commit/edce8d2769f19e27a05737c627af2d765472a4f8), [`8a586ec`](https://github.com/mastra-ai/mastra/commit/8a586eca9a4914f31dff6140d0d45ac375b00669), [`4451dfe`](https://github.com/mastra-ai/mastra/commit/4451dfe857428e7abcc0261a507a2e186dae6d47), [`8b7361d`](https://github.com/mastra-ai/mastra/commit/8b7361d35de68b80d05d30a74e0c69e7218fd612), [`1d39058`](https://github.com/mastra-ai/mastra/commit/1d39058e548efd691799985d5c8af2737f1c3bd2), [`3927473`](https://github.com/mastra-ai/mastra/commit/392747323ddb10c643d12be7b9ae913159dfaeed), [`25e7c12`](https://github.com/mastra-ai/mastra/commit/25e7c126a770069ae7fb7ecf1d2adb40e017b009), [`dce50dc`](https://github.com/mastra-ai/mastra/commit/dce50dc9a1c1fcd0f427bb5f6250ec74910cb04b), [`02c2bd9`](https://github.com/mastra-ai/mastra/commit/02c2bd906b145ab806287712e1796d92bfc32c2a), [`fd13f8e`](https://github.com/mastra-ai/mastra/commit/fd13f8e21990f9904c3eedba3a626bb4a929cdb8), [`634caff`](https://github.com/mastra-ai/mastra/commit/634caff29a9200ad058b67d53f96d9e5832fb8a2), [`f703f87`](https://github.com/mastra-ai/mastra/commit/f703f878de072d51fda557f9c50867d8252bef05), [`3e26c87`](https://github.com/mastra-ai/mastra/commit/3e26c87de0c5bc2583b795ce6ca5889b6b161acb), [`33f2b88`](https://github.com/mastra-ai/mastra/commit/33f2b88842c09a567f906fac4cb61cd5277ced59), [`177010f`](https://github.com/mastra-ai/mastra/commit/177010ff096d2e4b28d89803be5b1a4cad2a0d6b), [`0ad646f`](https://github.com/mastra-ai/mastra/commit/0ad646f71a530f2454664299e5e01bfd13fa12e5), [`b486abf`](https://github.com/mastra-ai/mastra/commit/b486abfa2a7528c6f527e4015c819ea9fa54aaad), [`54a51e0`](https://github.com/mastra-ai/mastra/commit/54a51e0a484fe1ebad3fb1f7ef5282a075709eb7), [`c43f3a9`](https://github.com/mastra-ai/mastra/commit/c43f3a9d1efde99b38789364ba4d0ba670f430e3), [`a5008f2`](https://github.com/mastra-ai/mastra/commit/a5008f22ae710ad9402ea9f2547d8c02f74d384b), [`e2d5f37`](https://github.com/mastra-ai/mastra/commit/e2d5f373bd289be534d5f8694d34465010533df6), [`25e7c12`](https://github.com/mastra-ai/mastra/commit/25e7c126a770069ae7fb7ecf1d2adb40e017b009), [`4ce0163`](https://github.com/mastra-ai/mastra/commit/4ce0163dc86e675a86809685c8ce6c49f1aeb87e), [`4378341`](https://github.com/mastra-ai/mastra/commit/43783412df5ea3dd35f5b1f6e4851e79c346fc89)]:
20
+ - @mastra/core@1.51.0
21
+ - @mastra/client-js@1.32.0
22
+
23
+ ## 1.2.5-alpha.13
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies [[`fd13f8e`](https://github.com/mastra-ai/mastra/commit/fd13f8e21990f9904c3eedba3a626bb4a929cdb8), [`a99eae8`](https://github.com/mastra-ai/mastra/commit/a99eae8908e500c1b2d12f9d277be616b98617a5), [`fd13f8e`](https://github.com/mastra-ai/mastra/commit/fd13f8e21990f9904c3eedba3a626bb4a929cdb8), [`f703f87`](https://github.com/mastra-ai/mastra/commit/f703f878de072d51fda557f9c50867d8252bef05), [`0ad646f`](https://github.com/mastra-ai/mastra/commit/0ad646f71a530f2454664299e5e01bfd13fa12e5)]:
28
+ - @mastra/client-js@1.32.0-alpha.13
29
+ - @mastra/core@1.51.0-alpha.13
30
+
31
+ ## 1.2.5-alpha.12
32
+
33
+ ### Patch Changes
34
+
35
+ - Updated dependencies [[`aa38805`](https://github.com/mastra-ai/mastra/commit/aa38805b878b827403be785eb90688d7172f5a40), [`2d22570`](https://github.com/mastra-ai/mastra/commit/2d22570c7dfdd02123d0ecc529efb05ccba2d9fc), [`4378341`](https://github.com/mastra-ai/mastra/commit/43783412df5ea3dd35f5b1f6e4851e79c346fc89)]:
36
+ - @mastra/core@1.51.0-alpha.12
37
+ - @mastra/client-js@1.32.0-alpha.12
38
+
39
+ ## 1.2.5-alpha.11
40
+
41
+ ### Patch Changes
42
+
43
+ - Fixed attachment rendering crash in `useChat` when `enableThreadSignals` is enabled. File attachments now display correctly during live streaming without requiring a page refresh. ([#19362](https://github.com/mastra-ai/mastra/pull/19362))
44
+
45
+ - Updated dependencies [[`45a8e65`](https://github.com/mastra-ai/mastra/commit/45a8e65e1556d1362cb3f25187023c36de26661d), [`c8ed116`](https://github.com/mastra-ai/mastra/commit/c8ed11699f62bcac70102ab4ec84d80d20541da6), [`33f2b88`](https://github.com/mastra-ai/mastra/commit/33f2b88842c09a567f906fac4cb61cd5277ced59)]:
46
+ - @mastra/core@1.51.0-alpha.11
47
+ - @mastra/client-js@1.32.0-alpha.11
48
+
49
+ ## 1.2.5-alpha.10
50
+
51
+ ### Patch Changes
52
+
53
+ - Updated dependencies [[`4adc391`](https://github.com/mastra-ai/mastra/commit/4adc3911075249c352bb4832d2471922826344de), [`b486abf`](https://github.com/mastra-ai/mastra/commit/b486abfa2a7528c6f527e4015c819ea9fa54aaad)]:
54
+ - @mastra/core@1.51.0-alpha.10
55
+ - @mastra/client-js@1.32.0-alpha.10
56
+
3
57
  ## 1.2.5-alpha.9
4
58
 
5
59
  ### Patch Changes
@@ -1,2 +1,5 @@
1
+ export declare const uint8ArrayToBase64: (bytes: Uint8Array) => string;
1
2
  export declare function convertSignalDataToBase64String(content: string | ArrayBuffer | Uint8Array): string;
3
+ /** Canonical DB `file` part `data` for optimistic UI and memory-shaped storage. */
4
+ export declare function encodeFilePartDataForStorage(data: string | URL | ArrayBuffer | Uint8Array, mimeType: string): string;
2
5
  //# sourceMappingURL=signal-data.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signal-data.d.ts","sourceRoot":"","sources":["../../src/agent/signal-data.ts"],"names":[],"mappings":"AAAA,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAYlG"}
1
+ {"version":3,"file":"signal-data.d.ts","sourceRoot":"","sources":["../../src/agent/signal-data.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,GAAI,OAAO,UAAU,KAAG,MAOtD,CAAC;AAEF,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAOlG;AAED,mFAAmF;AACnF,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,GAAG,WAAW,GAAG,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgBpH"}
package/dist/index.cjs CHANGED
@@ -70,6 +70,37 @@ var MastraReactProvider = ({
70
70
  );
71
71
  };
72
72
 
73
+ // src/agent/signal-data.ts
74
+ var uint8ArrayToBase64 = (bytes) => {
75
+ const chunkSize = 32768;
76
+ let binary = "";
77
+ for (let i = 0; i < bytes.length; i += chunkSize) {
78
+ binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
79
+ }
80
+ return btoa(binary);
81
+ };
82
+ function convertSignalDataToBase64String(content) {
83
+ if (typeof content === "string") {
84
+ return content;
85
+ }
86
+ const bytes = content instanceof ArrayBuffer ? new Uint8Array(content) : content;
87
+ return uint8ArrayToBase64(bytes);
88
+ }
89
+ function encodeFilePartDataForStorage(data, mimeType) {
90
+ if (typeof data === "string") {
91
+ return data;
92
+ }
93
+ if (data instanceof URL) {
94
+ return data.toString();
95
+ }
96
+ const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
97
+ const base64 = uint8ArrayToBase64(bytes);
98
+ if (base64.startsWith("data:")) {
99
+ return base64;
100
+ }
101
+ return `data:${mimeType};base64,${base64}`;
102
+ }
103
+
73
104
  // src/lib/mastra-db/formatCompletionFeedback.ts
74
105
  var formatBaseCompletionFeedback = (result, maxIterationReached, formatScorerHeading, incompleteMessage) => {
75
106
  const lines = [];
@@ -316,21 +347,37 @@ var signalContentsToUserMessages = (contents, metadata) => {
316
347
  }
317
348
  if (typedPart.type === "image") {
318
349
  const image = typedPart.image;
319
- return [
320
- {
321
- type: "file",
322
- mediaType: typeof typedPart.mediaType === "string" ? typedPart.mediaType : typeof typedPart.mimeType === "string" ? typedPart.mimeType : "image/*",
323
- url: typeof image === "string" ? image : image instanceof URL ? image.toString() : ""
324
- }
325
- ];
350
+ const mimeType = typeof typedPart.mediaType === "string" ? typedPart.mediaType : typeof typedPart.mimeType === "string" ? typedPart.mimeType : "image/*";
351
+ if (typeof image === "string" || image instanceof URL || image instanceof ArrayBuffer || image instanceof Uint8Array) {
352
+ return [
353
+ {
354
+ type: "file",
355
+ mimeType,
356
+ data: encodeFilePartDataForStorage(image, mimeType)
357
+ }
358
+ ];
359
+ }
360
+ return [{ type: "file", mimeType, data: "" }];
326
361
  }
327
362
  if (typedPart.type === "file") {
328
363
  const data = typedPart.data;
364
+ const mimeType = typeof typedPart.mediaType === "string" ? typedPart.mediaType : typeof typedPart.mimeType === "string" ? typedPart.mimeType : "application/octet-stream";
365
+ if (typeof data === "string" || data instanceof URL || data instanceof ArrayBuffer || data instanceof Uint8Array) {
366
+ return [
367
+ {
368
+ type: "file",
369
+ mimeType,
370
+ data: encodeFilePartDataForStorage(data, mimeType),
371
+ ...typeof typedPart.filename === "string" ? { filename: typedPart.filename } : {}
372
+ }
373
+ ];
374
+ }
375
+ const urlFallback = typeof typedPart.url === "string" ? typedPart.url : "";
329
376
  return [
330
377
  {
331
378
  type: "file",
332
- mediaType: typeof typedPart.mediaType === "string" ? typedPart.mediaType : typeof typedPart.mimeType === "string" ? typedPart.mimeType : "application/octet-stream",
333
- url: typeof data === "string" ? data : data instanceof URL ? data.toString() : "",
379
+ mimeType,
380
+ data: urlFallback,
334
381
  ...typeof typedPart.filename === "string" ? { filename: typedPart.filename } : {}
335
382
  }
336
383
  ];
@@ -355,6 +402,15 @@ var signalContentsToUserMessages = (contents, metadata) => {
355
402
  const parts = content.flatMap(toMessagePart);
356
403
  return parts.length ? [makeUserMessage(parts)] : [];
357
404
  };
405
+ var reconcilePendingUserEcho = (message, echoedContents, metadata, options) => {
406
+ const echoedMessages = signalContentsToUserMessages(echoedContents, metadata);
407
+ const echoedParts = echoedMessages[0]?.content.parts;
408
+ let reconciled = typeof options.signalId === "string" ? { ...message, id: options.signalId } : message;
409
+ if (echoedParts?.length) {
410
+ reconciled = { ...reconciled, content: { ...reconciled.content, parts: echoedParts } };
411
+ }
412
+ return options.keepClientMessageId ? clearPendingStatusKeepClientId(reconciled) : clearPendingStatus(reconciled);
413
+ };
358
414
  var makeToolInvocationPart = (invocation) => ({
359
415
  type: "tool-invocation",
360
416
  toolInvocation: invocation
@@ -375,14 +431,19 @@ var accumulateChunk = ({ chunk, conversation, metadata }) => {
375
431
  )) {
376
432
  return finishStreamingAssistantMessage(
377
433
  result.map(
378
- (message) => message.content.metadata?.status === "pending" && message.content.metadata[CLIENT_MESSAGE_ID_KEY] === echoedClientMessageId ? clearPendingStatusKeepClientId(typeof signalId === "string" ? { ...message, id: signalId } : message) : message
434
+ (message) => message.content.metadata?.status === "pending" && message.content.metadata[CLIENT_MESSAGE_ID_KEY] === echoedClientMessageId ? reconcilePendingUserEcho(message, chunk.data.contents, metadata, {
435
+ signalId: typeof signalId === "string" ? signalId : void 0,
436
+ keepClientMessageId: true
437
+ }) : message
379
438
  )
380
439
  );
381
440
  }
382
441
  if (typeof signalId === "string" && result.some((message) => message.id === signalId)) {
383
442
  return finishStreamingAssistantMessage(
384
443
  result.map(
385
- (message) => message.id === signalId && message.content.metadata?.status === "pending" ? clearPendingStatus(message) : message
444
+ (message) => message.id === signalId && message.content.metadata?.status === "pending" ? reconcilePendingUserEcho(message, chunk.data.contents, metadata, {
445
+ keepClientMessageId: false
446
+ }) : message
386
447
  )
387
448
  );
388
449
  }
@@ -989,17 +1050,17 @@ var accumulateChunk = ({ chunk, conversation, metadata }) => {
989
1050
  const lastMessage = result[result.length - 1];
990
1051
  if (!lastMessage || lastMessage.role !== "assistant") return result;
991
1052
  const parts = [...lastMessage.content.parts];
992
- let url;
1053
+ let data;
993
1054
  if (typeof chunk.payload.data === "string") {
994
- url = chunk.payload.base64 ? `data:${chunk.payload.mimeType};base64,${chunk.payload.data}` : `data:${chunk.payload.mimeType},${encodeURIComponent(chunk.payload.data)}`;
1055
+ data = chunk.payload.base64 ? `data:${chunk.payload.mimeType};base64,${chunk.payload.data}` : `data:${chunk.payload.mimeType},${encodeURIComponent(chunk.payload.data)}`;
995
1056
  } else {
996
- const base64 = btoa(String.fromCharCode(...chunk.payload.data));
997
- url = `data:${chunk.payload.mimeType};base64,${base64}`;
1057
+ const base64 = uint8ArrayToBase64(chunk.payload.data);
1058
+ data = `data:${chunk.payload.mimeType};base64,${base64}`;
998
1059
  }
999
1060
  parts.push({
1000
1061
  type: "file",
1001
- mediaType: chunk.payload.mimeType,
1002
- url,
1062
+ mimeType: chunk.payload.mimeType,
1063
+ data,
1003
1064
  providerMetadata: chunk.payload.providerMetadata
1004
1065
  });
1005
1066
  return replaceLast(result, withParts(lastMessage, parts));
@@ -1669,19 +1730,18 @@ var coreUserMessageToParts = (coreUserMessage) => typeof coreUserMessage.content
1669
1730
  return { type: "text", text: part.text };
1670
1731
  }
1671
1732
  case "image": {
1672
- const data = typeof part.image === "string" ? part.image : part.image instanceof URL ? part.image.toString() : "";
1733
+ const mimeType = part.mimeType ?? "image/*";
1673
1734
  return {
1674
1735
  type: "file",
1675
- mimeType: part.mimeType ?? "image/*",
1676
- data
1736
+ mimeType,
1737
+ data: encodeFilePartDataForStorage(part.image, mimeType)
1677
1738
  };
1678
1739
  }
1679
1740
  case "file": {
1680
- const data = typeof part.data === "string" ? part.data : part.data instanceof URL ? part.data.toString() : "";
1681
1741
  return {
1682
1742
  type: "file",
1683
1743
  mimeType: part.mimeType,
1684
- data,
1744
+ data: encodeFilePartDataForStorage(part.data, part.mimeType),
1685
1745
  ...part.filename !== void 0 ? { filename: part.filename } : {}
1686
1746
  };
1687
1747
  }
@@ -1809,19 +1869,6 @@ var extractRunIdFromMessages = (messages) => {
1809
1869
  return void 0;
1810
1870
  };
1811
1871
 
1812
- // src/agent/signal-data.ts
1813
- function convertSignalDataToBase64String(content) {
1814
- if (typeof content === "string") {
1815
- return content;
1816
- }
1817
- const bytes = content instanceof ArrayBuffer ? new Uint8Array(content) : content;
1818
- let binary = "";
1819
- for (const byte of bytes) {
1820
- binary += String.fromCharCode(byte);
1821
- }
1822
- return btoa(binary);
1823
- }
1824
-
1825
1872
  // src/agent/hooks.ts
1826
1873
  var extractPendingToolApprovalIdsFromMessages = (messages) => {
1827
1874
  const pendingToolApprovalIds = /* @__PURE__ */ new Set();