@mastra/react 1.13.0-alpha.2 → 1.13.0-alpha.4

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 (141) hide show
  1. package/dist/{accumulator-BmD8-x9I.cjs → accumulator-Bjfckb5t.cjs} +5 -9
  2. package/dist/{accumulator-BmD8-x9I.cjs.map → accumulator-Bjfckb5t.cjs.map} +1 -1
  3. package/dist/{accumulator-D9jAph99.js → accumulator-DysrPe6U.js} +5 -9
  4. package/dist/{accumulator-D9jAph99.js.map → accumulator-DysrPe6U.js.map} +1 -1
  5. package/dist/chat/index.cjs +1 -1
  6. package/dist/chat/index.js +1 -1
  7. package/dist/{combine-by-ids-CcaZKGT9.js → combine-by-ids-C-0oe4eH.js} +2 -3
  8. package/dist/{combine-by-ids-CcaZKGT9.js.map → combine-by-ids-C-0oe4eH.js.map} +1 -1
  9. package/dist/{combine-by-ids-D_lp6Dvq.cjs → combine-by-ids-ERVPXXBi.cjs} +2 -3
  10. package/dist/{combine-by-ids-D_lp6Dvq.cjs.map → combine-by-ids-ERVPXXBi.cjs.map} +1 -1
  11. package/dist/{experiments-CJw1N3FB.cjs → experiments-Duv0RgkM.cjs} +12 -19
  12. package/dist/{experiments-CJw1N3FB.cjs.map → experiments-Duv0RgkM.cjs.map} +1 -1
  13. package/dist/{experiments-B7vRMK5T.js → experiments-DyecjEut.js} +12 -19
  14. package/dist/{experiments-B7vRMK5T.js.map → experiments-DyecjEut.js.map} +1 -1
  15. package/dist/{feedback-refetch-interval-XD5FVc2k.cjs → feedback-refetch-interval-BBcT9r8s.cjs} +3 -4
  16. package/dist/{feedback-refetch-interval-XD5FVc2k.cjs.map → feedback-refetch-interval-BBcT9r8s.cjs.map} +1 -1
  17. package/dist/{feedback-refetch-interval-DLHzQoVV.js → feedback-refetch-interval-C12Nzb2r.js} +3 -4
  18. package/dist/{feedback-refetch-interval-DLHzQoVV.js.map → feedback-refetch-interval-C12Nzb2r.js.map} +1 -1
  19. package/dist/hooks/agents/index.cjs +19 -37
  20. package/dist/hooks/agents/index.cjs.map +1 -1
  21. package/dist/hooks/agents/index.js +19 -37
  22. package/dist/hooks/agents/index.js.map +1 -1
  23. package/dist/hooks/auth/index.cjs +11 -21
  24. package/dist/hooks/auth/index.cjs.map +1 -1
  25. package/dist/hooks/auth/index.js +11 -21
  26. package/dist/hooks/auth/index.js.map +1 -1
  27. package/dist/hooks/capabilities/index.cjs +11 -21
  28. package/dist/hooks/capabilities/index.cjs.map +1 -1
  29. package/dist/hooks/capabilities/index.js +11 -21
  30. package/dist/hooks/capabilities/index.js.map +1 -1
  31. package/dist/hooks/configuration/index.cjs +2 -3
  32. package/dist/hooks/configuration/index.js +2 -3
  33. package/dist/hooks/datasets/index.cjs +12 -21
  34. package/dist/hooks/datasets/index.cjs.map +1 -1
  35. package/dist/hooks/datasets/index.js +12 -21
  36. package/dist/hooks/datasets/index.js.map +1 -1
  37. package/dist/hooks/embedders/index.cjs +2 -3
  38. package/dist/hooks/embedders/index.js +2 -3
  39. package/dist/hooks/experiments/index.cjs +1 -1
  40. package/dist/hooks/experiments/index.js +1 -1
  41. package/dist/hooks/feedback/index.cjs +3 -4
  42. package/dist/hooks/feedback/index.js +3 -4
  43. package/dist/hooks/llm/index.cjs +2 -3
  44. package/dist/hooks/llm/index.js +2 -3
  45. package/dist/hooks/logs/index.cjs +4 -5
  46. package/dist/hooks/logs/index.js +4 -5
  47. package/dist/hooks/mcps/index.cjs +8 -15
  48. package/dist/hooks/mcps/index.cjs.map +1 -1
  49. package/dist/hooks/mcps/index.js +8 -15
  50. package/dist/hooks/mcps/index.js.map +1 -1
  51. package/dist/hooks/memory/index.cjs +5 -9
  52. package/dist/hooks/memory/index.cjs.map +1 -1
  53. package/dist/hooks/memory/index.js +5 -9
  54. package/dist/hooks/memory/index.js.map +1 -1
  55. package/dist/hooks/metrics/index.cjs +19 -36
  56. package/dist/hooks/metrics/index.cjs.map +1 -1
  57. package/dist/hooks/metrics/index.js +19 -36
  58. package/dist/hooks/metrics/index.js.map +1 -1
  59. package/dist/hooks/processors/index.cjs +2 -3
  60. package/dist/hooks/processors/index.js +2 -3
  61. package/dist/hooks/prompt-blocks/index.cjs +3 -5
  62. package/dist/hooks/prompt-blocks/index.cjs.map +1 -1
  63. package/dist/hooks/prompt-blocks/index.js +3 -5
  64. package/dist/hooks/prompt-blocks/index.js.map +1 -1
  65. package/dist/hooks/query/index.cjs +2 -3
  66. package/dist/hooks/query/index.js +2 -3
  67. package/dist/hooks/review/index.cjs +4 -6
  68. package/dist/hooks/review/index.cjs.map +1 -1
  69. package/dist/hooks/review/index.js +4 -6
  70. package/dist/hooks/review/index.js.map +1 -1
  71. package/dist/hooks/schedules/index.cjs +6 -10
  72. package/dist/hooks/schedules/index.cjs.map +1 -1
  73. package/dist/hooks/schedules/index.js +6 -10
  74. package/dist/hooks/schedules/index.js.map +1 -1
  75. package/dist/hooks/scores/index.cjs +8 -13
  76. package/dist/hooks/scores/index.cjs.map +1 -1
  77. package/dist/hooks/scores/index.js +8 -13
  78. package/dist/hooks/scores/index.js.map +1 -1
  79. package/dist/hooks/templates/index.cjs +2 -3
  80. package/dist/hooks/templates/index.js +2 -3
  81. package/dist/hooks/tool-providers/index.cjs +10 -19
  82. package/dist/hooks/tool-providers/index.cjs.map +1 -1
  83. package/dist/hooks/tool-providers/index.js +10 -19
  84. package/dist/hooks/tool-providers/index.js.map +1 -1
  85. package/dist/hooks/tools/index.cjs +3 -5
  86. package/dist/hooks/tools/index.cjs.map +1 -1
  87. package/dist/hooks/tools/index.js +3 -5
  88. package/dist/hooks/tools/index.js.map +1 -1
  89. package/dist/hooks/traces/index.cjs +28 -51
  90. package/dist/hooks/traces/index.cjs.map +1 -1
  91. package/dist/hooks/traces/index.js +28 -51
  92. package/dist/hooks/traces/index.js.map +1 -1
  93. package/dist/hooks/vectors/index.cjs +2 -3
  94. package/dist/hooks/vectors/index.js +2 -3
  95. package/dist/hooks/voice/index.cjs +3 -4
  96. package/dist/hooks/voice/index.js +3 -4
  97. package/dist/hooks/workflows/index.cjs +7 -11
  98. package/dist/hooks/workflows/index.cjs.map +1 -1
  99. package/dist/hooks/workflows/index.js +7 -11
  100. package/dist/hooks/workflows/index.js.map +1 -1
  101. package/dist/hooks/workspace/index.cjs +12 -22
  102. package/dist/hooks/workspace/index.cjs.map +1 -1
  103. package/dist/hooks/workspace/index.js +12 -22
  104. package/dist/hooks/workspace/index.js.map +1 -1
  105. package/dist/{hooks-XYsmqFCz.cjs → hooks-Bt15IwzP.cjs} +6 -9
  106. package/dist/{hooks-XYsmqFCz.cjs.map → hooks-Bt15IwzP.cjs.map} +1 -1
  107. package/dist/{hooks-DG-Y1KFe.js → hooks-Btt7PyI-.js} +6 -9
  108. package/dist/{hooks-DG-Y1KFe.js.map → hooks-Btt7PyI-.js.map} +1 -1
  109. package/dist/{hooks-BfysjY_K.js → hooks-CEikbhrN.js} +9 -15
  110. package/dist/{hooks-BfysjY_K.js.map → hooks-CEikbhrN.js.map} +1 -1
  111. package/dist/{hooks-BbUMSab8.cjs → hooks-D6LDSEcm.cjs} +9 -15
  112. package/dist/{hooks-BbUMSab8.cjs.map → hooks-D6LDSEcm.cjs.map} +1 -1
  113. package/dist/index.cjs +7 -9
  114. package/dist/index.cjs.map +1 -1
  115. package/dist/index.js +7 -9
  116. package/dist/index.js.map +1 -1
  117. package/dist/{map-CDv4fbu4.js → map-5-4U5rwA.js} +2 -3
  118. package/dist/{map-CDv4fbu4.js.map → map-5-4U5rwA.js.map} +1 -1
  119. package/dist/{map-wjmL1y5O.cjs → map-BGoWBTGy.cjs} +2 -3
  120. package/dist/{map-wjmL1y5O.cjs.map → map-BGoWBTGy.cjs.map} +1 -1
  121. package/dist/{mastra-client-context-Bx_g84YB.js → mastra-client-context-DQ5z_ze9.js} +2 -3
  122. package/dist/{mastra-client-context-Bx_g84YB.js.map → mastra-client-context-DQ5z_ze9.js.map} +1 -1
  123. package/dist/{mastra-client-context-DzX3f0RF.cjs → mastra-client-context-DX8wJM9p.cjs} +2 -3
  124. package/dist/{mastra-client-context-DzX3f0RF.cjs.map → mastra-client-context-DX8wJM9p.cjs.map} +1 -1
  125. package/dist/{query-utils-CcrChYgz.cjs → query-utils-BVgE_xxj.cjs} +2 -3
  126. package/dist/{query-utils-CcrChYgz.cjs.map → query-utils-BVgE_xxj.cjs.map} +1 -1
  127. package/dist/{query-utils-D1NgFnWU.js → query-utils-DvMERIwf.js} +2 -3
  128. package/dist/{query-utils-D1NgFnWU.js.map → query-utils-DvMERIwf.js.map} +1 -1
  129. package/dist/ui/index.cjs +15 -30
  130. package/dist/ui/index.cjs.map +1 -1
  131. package/dist/ui/index.js +14 -28
  132. package/dist/ui/index.js.map +1 -1
  133. package/dist/{use-in-view-B6eJO9Zi.cjs → use-in-view-BxdrrnCw.cjs} +2 -3
  134. package/dist/{use-in-view-B6eJO9Zi.cjs.map → use-in-view-BxdrrnCw.cjs.map} +1 -1
  135. package/dist/{use-in-view-C9sYPGRm.js → use-in-view-CyjKdplM.js} +2 -3
  136. package/dist/{use-in-view-C9sYPGRm.js.map → use-in-view-CyjKdplM.js.map} +1 -1
  137. package/dist/{voice-BOtUdMi8.cjs → voice-Didej2E1.cjs} +5 -8
  138. package/dist/{voice-BOtUdMi8.cjs.map → voice-Didej2E1.cjs.map} +1 -1
  139. package/dist/{voice-DgirjEyH.js → voice-ugGu7VyA.js} +5 -8
  140. package/dist/{voice-DgirjEyH.js.map → voice-ugGu7VyA.js.map} +1 -1
  141. package/package.json +17 -17
@@ -1 +1 @@
1
- {"version":3,"file":"use-in-view-B6eJO9Zi.cjs","names":["useState"],"sources":["../src/hooks/shared/use-in-view.ts"],"sourcesContent":["import type { RefObject } from 'react';\nimport { useEffect, useState } from 'react';\n\nexport type UseInViewOptions = {\n /**\n * Scroll container to observe against. When omitted, the browser viewport is used.\n * Pass the list's own scroll viewport so the sentinel only fires when scrolled\n * into view inside that container.\n */\n root?: RefObject<HTMLElement | null>;\n};\n\n/**\n * Tracks whether or not the given element is currently in view.\n * This is to replace framer-motion's `useInView` which has issues\n * tracking a ref that is set at a time other than mount.\n *\n * The observer is created in an effect (not in the callback ref) so that an\n * ancestor `root` ref, which React assigns after descendant refs, is already\n * populated when the observer is constructed.\n */\nexport const useInView = ({ root }: UseInViewOptions = {}) => {\n const [inView, setInView] = useState(false);\n const [node, setRef] = useState<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (!node) return;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (!entry) return;\n setInView(entry.isIntersecting);\n },\n { root: root?.current ?? null },\n );\n observer.observe(node);\n return () => observer.disconnect();\n }, [node, root]);\n\n return { inView, setRef };\n};\n"],"mappings":";;;;;;;;;;;AAqBA,MAAa,aAAa,EAAE,SAA2B,CAAC,MAAM;CAC5D,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAS,KAAK;CAC1C,MAAM,CAAC,MAAM,WAAA,GAAUA,MAAAA,SAAAA,CAAgC,IAAI;CAE3D,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,CAAC,MAAM;EAEX,MAAM,WAAW,IAAI,sBAClB,CAAC,WAAW;GACX,IAAI,CAAC,OAAO;GACZ,UAAU,MAAM,cAAc;EAChC,GACA,EAAE,MAAM,MAAM,WAAW,KAAK,CAChC;EACA,SAAS,QAAQ,IAAI;EACrB,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,MAAM,IAAI,CAAC;CAEf,OAAO;EAAE;EAAQ;CAAO;AAC1B"}
1
+ {"version":3,"file":"use-in-view-BxdrrnCw.cjs","names":["useState"],"sources":["../src/hooks/shared/use-in-view.ts"],"sourcesContent":["import type { RefObject } from 'react';\nimport { useEffect, useState } from 'react';\n\nexport type UseInViewOptions = {\n /**\n * Scroll container to observe against. When omitted, the browser viewport is used.\n * Pass the list's own scroll viewport so the sentinel only fires when scrolled\n * into view inside that container.\n */\n root?: RefObject<HTMLElement | null>;\n};\n\n/**\n * Tracks whether or not the given element is currently in view.\n * This is to replace framer-motion's `useInView` which has issues\n * tracking a ref that is set at a time other than mount.\n *\n * The observer is created in an effect (not in the callback ref) so that an\n * ancestor `root` ref, which React assigns after descendant refs, is already\n * populated when the observer is constructed.\n */\nexport const useInView = ({ root }: UseInViewOptions = {}) => {\n const [inView, setInView] = useState(false);\n const [node, setRef] = useState<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (!node) return;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (!entry) return;\n setInView(entry.isIntersecting);\n },\n { root: root?.current ?? null },\n );\n observer.observe(node);\n return () => observer.disconnect();\n }, [node, root]);\n\n return { inView, setRef };\n};\n"],"mappings":";;;;;;;;;;;AAqBA,MAAa,aAAa,EAAE,SAA2B,CAAC,MAAM;CAC5D,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAS,KAAK;CAC1C,MAAM,CAAC,MAAM,WAAA,GAAUA,MAAAA,SAAAA,CAAgC,IAAI;CAE3D,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,CAAC,MAAM;EAEX,MAAM,WAAW,IAAI,sBAClB,CAAC,WAAW;GACX,IAAI,CAAC,OAAO;GACZ,UAAU,MAAM,cAAc;EAChC,GACA,EAAE,MAAM,MAAM,WAAW,KAAK,CAChC;EACA,SAAS,QAAQ,IAAI;EACrB,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,MAAM,IAAI,CAAC;CAEf,OAAO;EAAE;EAAQ;CAAO;AAC1B"}
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useState } from "react";
2
- //#region src/hooks/shared/use-in-view.ts
2
+ // src/hooks/shared/use-in-view.ts
3
3
  /**
4
4
  * Tracks whether or not the given element is currently in view.
5
5
  * This is to replace framer-motion's `useInView` which has issues
@@ -26,7 +26,6 @@ const useInView = ({ root } = {}) => {
26
26
  setRef
27
27
  };
28
28
  };
29
- //#endregion
30
29
  export { useInView as t };
31
30
 
32
- //# sourceMappingURL=use-in-view-C9sYPGRm.js.map
31
+ //# sourceMappingURL=use-in-view-CyjKdplM.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-in-view-C9sYPGRm.js","names":[],"sources":["../src/hooks/shared/use-in-view.ts"],"sourcesContent":["import type { RefObject } from 'react';\nimport { useEffect, useState } from 'react';\n\nexport type UseInViewOptions = {\n /**\n * Scroll container to observe against. When omitted, the browser viewport is used.\n * Pass the list's own scroll viewport so the sentinel only fires when scrolled\n * into view inside that container.\n */\n root?: RefObject<HTMLElement | null>;\n};\n\n/**\n * Tracks whether or not the given element is currently in view.\n * This is to replace framer-motion's `useInView` which has issues\n * tracking a ref that is set at a time other than mount.\n *\n * The observer is created in an effect (not in the callback ref) so that an\n * ancestor `root` ref, which React assigns after descendant refs, is already\n * populated when the observer is constructed.\n */\nexport const useInView = ({ root }: UseInViewOptions = {}) => {\n const [inView, setInView] = useState(false);\n const [node, setRef] = useState<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (!node) return;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (!entry) return;\n setInView(entry.isIntersecting);\n },\n { root: root?.current ?? null },\n );\n observer.observe(node);\n return () => observer.disconnect();\n }, [node, root]);\n\n return { inView, setRef };\n};\n"],"mappings":";;;;;;;;;;;AAqBA,MAAa,aAAa,EAAE,SAA2B,CAAC,MAAM;CAC5D,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,CAAC,MAAM,UAAU,SAAgC,IAAI;CAE3D,gBAAgB;EACd,IAAI,CAAC,MAAM;EAEX,MAAM,WAAW,IAAI,sBAClB,CAAC,WAAW;GACX,IAAI,CAAC,OAAO;GACZ,UAAU,MAAM,cAAc;EAChC,GACA,EAAE,MAAM,MAAM,WAAW,KAAK,CAChC;EACA,SAAS,QAAQ,IAAI;EACrB,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,MAAM,IAAI,CAAC;CAEf,OAAO;EAAE;EAAQ;CAAO;AAC1B"}
1
+ {"version":3,"file":"use-in-view-CyjKdplM.js","names":[],"sources":["../src/hooks/shared/use-in-view.ts"],"sourcesContent":["import type { RefObject } from 'react';\nimport { useEffect, useState } from 'react';\n\nexport type UseInViewOptions = {\n /**\n * Scroll container to observe against. When omitted, the browser viewport is used.\n * Pass the list's own scroll viewport so the sentinel only fires when scrolled\n * into view inside that container.\n */\n root?: RefObject<HTMLElement | null>;\n};\n\n/**\n * Tracks whether or not the given element is currently in view.\n * This is to replace framer-motion's `useInView` which has issues\n * tracking a ref that is set at a time other than mount.\n *\n * The observer is created in an effect (not in the callback ref) so that an\n * ancestor `root` ref, which React assigns after descendant refs, is already\n * populated when the observer is constructed.\n */\nexport const useInView = ({ root }: UseInViewOptions = {}) => {\n const [inView, setInView] = useState(false);\n const [node, setRef] = useState<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (!node) return;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (!entry) return;\n setInView(entry.isIntersecting);\n },\n { root: root?.current ?? null },\n );\n observer.observe(node);\n return () => observer.disconnect();\n }, [node, root]);\n\n return { inView, setRef };\n};\n"],"mappings":";;;;;;;;;;;AAqBA,MAAa,aAAa,EAAE,SAA2B,CAAC,MAAM;CAC5D,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,CAAC,MAAM,UAAU,SAAgC,IAAI;CAE3D,gBAAgB;EACd,IAAI,CAAC,MAAM;EAEX,MAAM,WAAW,IAAI,sBAClB,CAAC,WAAW;GACX,IAAI,CAAC,OAAO;GACZ,UAAU,MAAM,cAAc;EAChC,GACA,EAAE,MAAM,MAAM,WAAW,KAAK,CAChC;EACA,SAAS,QAAQ,IAAI;EACrB,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,MAAM,IAAI,CAAC;CAEf,OAAO;EAAE;EAAQ;CAAO;AAC1B"}
@@ -1,6 +1,6 @@
1
- const require_mastra_client_context = require("./mastra-client-context-DzX3f0RF.cjs");
1
+ const require_mastra_client_context = require("./mastra-client-context-DX8wJM9p.cjs");
2
2
  let react = require("react");
3
- //#region src/voice/record-mic-to-file.ts
3
+ // src/voice/record-mic-to-file.ts
4
4
  async function recordMicrophoneToFile(onFinish) {
5
5
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
6
6
  const mediaRecorder = new MediaRecorder(stream);
@@ -19,8 +19,7 @@ async function recordMicrophoneToFile(onFinish) {
19
19
  };
20
20
  return mediaRecorder;
21
21
  }
22
- //#endregion
23
- //#region src/voice/play-stream-with-web-audio.ts
22
+ // src/voice/play-stream-with-web-audio.ts
24
23
  async function playStreamWithWebAudio(stream, onEnded) {
25
24
  const audioContext = new window.AudioContext();
26
25
  const reader = stream.getReader();
@@ -57,8 +56,7 @@ async function playStreamWithWebAudio(stream, onEnded) {
57
56
  reader.releaseLock();
58
57
  }
59
58
  }
60
- //#endregion
61
- //#region src/voice/use-speech-recognition.ts
59
+ // src/voice/use-speech-recognition.ts
62
60
  const useSpeechRecognition = ({ language = "en-US", agentId, requestContext }) => {
63
61
  const client = require_mastra_client_context.useMastraClient();
64
62
  const [agent, setAgent] = (0, react.useState)(null);
@@ -258,7 +256,6 @@ const useMastraSpeechToText = ({ agent, language }) => {
258
256
  stop
259
257
  };
260
258
  };
261
- //#endregion
262
259
  Object.defineProperty(exports, "playStreamWithWebAudio", {
263
260
  enumerable: true,
264
261
  get: function() {
@@ -278,4 +275,4 @@ Object.defineProperty(exports, "useSpeechRecognition", {
278
275
  }
279
276
  });
280
277
 
281
- //# sourceMappingURL=voice-BOtUdMi8.cjs.map
278
+ //# sourceMappingURL=voice-Didej2E1.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"voice-BOtUdMi8.cjs","names":["useMastraClient","useState","useRef"],"sources":["../src/voice/record-mic-to-file.ts","../src/voice/play-stream-with-web-audio.ts","../src/voice/use-speech-recognition.ts"],"sourcesContent":["export async function recordMicrophoneToFile(onFinish: (file: File) => void) {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n const mediaRecorder = new MediaRecorder(stream);\n\n let chunks: BlobPart[] = [];\n\n mediaRecorder.ondataavailable = e => {\n chunks.push(e.data);\n };\n\n mediaRecorder.onstop = () => {\n const blob = new Blob(chunks, { type: 'audio/webm' });\n const file = new File([blob], `recording-${Date.now()}.webm`, {\n type: 'audio/webm',\n lastModified: Date.now(),\n });\n\n stream.getTracks().forEach(track => track.stop());\n onFinish(file);\n };\n\n return mediaRecorder;\n}\n","export async function playStreamWithWebAudio(stream: ReadableStream, onEnded?: () => void) {\n const audioContext = new window.AudioContext();\n\n const reader = stream.getReader();\n const chunks = [];\n\n try {\n // Read all chunks\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Combine chunks into single ArrayBuffer\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combinedBuffer = new Uint8Array(totalLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n combinedBuffer.set(chunk, offset);\n offset += chunk.length;\n }\n\n // Decode and play\n const audioBuffer = await audioContext.decodeAudioData(combinedBuffer.buffer);\n const source = audioContext.createBufferSource();\n source.buffer = audioBuffer;\n source.onended = onEnded ?? null;\n source.connect(audioContext.destination);\n source.start();\n\n return () => {\n source.onended = null;\n source.stop();\n void audioContext.close();\n };\n } catch (error) {\n await reader.cancel().catch(() => undefined);\n await audioContext.close().catch(() => undefined);\n throw error;\n } finally {\n reader.releaseLock();\n }\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useEffect, useRef, useState } from 'react';\nimport { useMastraClient } from '../mastra-client-context';\nimport { recordMicrophoneToFile } from './record-mic-to-file';\n\ntype Agent = ReturnType<MastraClient['getAgent']>;\ntype VoiceRequestContext = Parameters<Agent['voice']['getSpeakers']>[0];\n\nexport interface SpeechRecognitionState {\n isListening: boolean;\n transcript: string;\n error: string | null;\n}\n\nexport interface UseSpeechRecognitionArgs {\n language?: string;\n agentId?: string;\n requestContext?: VoiceRequestContext;\n}\n\ntype SpeechRecognitionResult = SpeechRecognitionState & {\n start: () => void;\n stop: () => void;\n};\n\nexport const useSpeechRecognition = ({\n language = 'en-US',\n agentId,\n requestContext,\n}: UseSpeechRecognitionArgs): SpeechRecognitionResult => {\n const client = useMastraClient();\n const [agent, setAgent] = useState<Agent | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!agentId) {\n setAgent(null);\n return () => {\n cancelled = true;\n };\n }\n\n const agent = client.getAgent(agentId);\n\n const check = async () => {\n try {\n const speakers = await agent.voice.getSpeakers(requestContext);\n if (!cancelled) {\n setAgent(speakers.length > 0 ? agent : null);\n }\n } catch {\n if (!cancelled) {\n setAgent(null);\n }\n }\n };\n\n void check();\n\n return () => {\n cancelled = true;\n };\n }, [agentId, client, requestContext]);\n\n const browserSpeechRecognition = useBrowserSpeechRecognition({ language });\n const mastraSpeechRecognition = useMastraSpeechToText({ agent, language });\n\n if (!agent) {\n return browserSpeechRecognition;\n }\n\n return mastraSpeechRecognition;\n};\n\nconst useBrowserSpeechRecognition = ({ language = 'en-US' }: { language?: string }): SpeechRecognitionResult => {\n const speechRecognitionRef = useRef<any>(null);\n const [state, setState] = useState<SpeechRecognitionState>({\n isListening: false,\n transcript: '',\n error: null,\n });\n\n const start = () => {\n if (!speechRecognitionRef.current) return;\n speechRecognitionRef.current.start();\n };\n\n const stop = () => {\n if (!speechRecognitionRef.current) return;\n speechRecognitionRef.current.stop();\n };\n\n useEffect(() => {\n if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {\n setState(prev => ({ ...prev, error: 'Speech Recognition not supported in this browser' }));\n return;\n }\n\n const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n const recognition = new SpeechRecognition();\n speechRecognitionRef.current = recognition;\n\n recognition.continuous = true;\n recognition.lang = language;\n\n recognition.onstart = () => {\n setState(prev => ({ ...prev, isListening: true, error: null, transcript: '' }));\n };\n\n recognition.onresult = (event: any) => {\n let finalTranscript = '';\n\n for (let i = event.resultIndex; i < event.results.length; i++) {\n const transcript = event.results[i][0].transcript;\n if (event.results[i].isFinal) {\n finalTranscript += transcript + ' ';\n }\n }\n\n if (!finalTranscript) return;\n // Continuous mode emits one event per finalized phrase with an advancing\n // resultIndex, so append to the session transcript instead of replacing it.\n setState(prev => ({ ...prev, transcript: prev.transcript + finalTranscript }));\n };\n\n recognition.onerror = (event: any) => {\n setState(prev => ({ ...prev, error: `Error: ${event.error}` }));\n };\n\n recognition.onend = () => setState(prev => ({ ...prev, isListening: false }));\n\n return () => {\n try {\n recognition.stop();\n } catch {\n // ignore: recognition may not be running\n }\n recognition.onstart = null;\n recognition.onresult = null;\n recognition.onerror = null;\n recognition.onend = null;\n speechRecognitionRef.current = null;\n };\n }, [language]);\n\n return {\n ...state,\n start,\n stop,\n };\n};\n\nconst useMastraSpeechToText = ({\n agent,\n language,\n}: {\n agent: Agent | null;\n language: string;\n}): SpeechRecognitionResult => {\n const [state, setState] = useState<SpeechRecognitionState>({\n isListening: false,\n transcript: '',\n error: null,\n });\n const recorderRef = useRef<MediaRecorder | null>(null);\n const sessionRef = useRef(0);\n const startInFlightRef = useRef(false);\n\n useEffect(() => {\n return () => {\n sessionRef.current += 1;\n startInFlightRef.current = false;\n recorderRef.current?.stop();\n recorderRef.current = null;\n };\n }, [agent]);\n\n const handleFinish = (session: number) => (file: File) => {\n if (!agent || session !== sessionRef.current) return;\n\n recorderRef.current = null;\n setState(prev => ({ ...prev, isListening: false }));\n\n void agent.voice\n .listen(file, { language })\n .then(res => {\n if (session !== sessionRef.current) return;\n setState(prev => ({ ...prev, transcript: res.text, error: null }));\n })\n .catch(error => {\n if (session !== sessionRef.current) return;\n const message = error instanceof Error ? error.message : 'Failed to transcribe speech';\n setState(prev => ({ ...prev, error: message }));\n });\n };\n\n const start = () => {\n if (!agent || startInFlightRef.current || recorderRef.current) return;\n\n startInFlightRef.current = true;\n // Bump the session here (not in stop()) so a normal stop's onstop callback\n // still matches sessionRef.current. Only a new start (or unmount) should\n // invalidate a prior in-flight recording's result.\n // See: https://github.com/mastra-ai/mastra/issues/19980\n sessionRef.current += 1;\n const session = sessionRef.current;\n\n void recordMicrophoneToFile(handleFinish(session))\n .then(recorder => {\n startInFlightRef.current = false;\n if (session !== sessionRef.current) {\n try {\n recorder.stop();\n } catch {\n // ignore: recorder was never started\n }\n return;\n }\n recorderRef.current = recorder;\n setState(prev => ({ ...prev, isListening: true, error: null }));\n recorder.start();\n })\n .catch(error => {\n startInFlightRef.current = false;\n if (session !== sessionRef.current) return;\n const message = error instanceof Error ? error.message : 'Failed to start speech recording';\n setState(prev => ({ ...prev, isListening: false, error: message }));\n });\n };\n\n const stop = () => {\n if (recorderRef.current) {\n // An active recording — its session was fixed at start() time and hasn't\n // changed, so its own onstop/handleFinish will complete normally.\n recorderRef.current.stop();\n recorderRef.current = null;\n } else if (startInFlightRef.current) {\n // No recorder yet but a start() is still in-flight. Invalidate the\n // session so that start's resolution knows to abort (stop the recorder\n // instead of assigning/starting it) rather than silently proceeding.\n sessionRef.current += 1;\n }\n // Otherwise the hook is idle, or a finished recording's transcription is\n // still in flight — bumping the session then would silently discard the\n // transcript (the same failure class as #19980, in a narrower window).\n startInFlightRef.current = false;\n setState(prev => ({ ...prev, isListening: false }));\n };\n\n return {\n ...state,\n start,\n stop,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"voice-Didej2E1.cjs","names":["useMastraClient","useState","useRef"],"sources":["../src/voice/record-mic-to-file.ts","../src/voice/play-stream-with-web-audio.ts","../src/voice/use-speech-recognition.ts"],"sourcesContent":["export async function recordMicrophoneToFile(onFinish: (file: File) => void) {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n const mediaRecorder = new MediaRecorder(stream);\n\n let chunks: BlobPart[] = [];\n\n mediaRecorder.ondataavailable = e => {\n chunks.push(e.data);\n };\n\n mediaRecorder.onstop = () => {\n const blob = new Blob(chunks, { type: 'audio/webm' });\n const file = new File([blob], `recording-${Date.now()}.webm`, {\n type: 'audio/webm',\n lastModified: Date.now(),\n });\n\n stream.getTracks().forEach(track => track.stop());\n onFinish(file);\n };\n\n return mediaRecorder;\n}\n","export async function playStreamWithWebAudio(stream: ReadableStream, onEnded?: () => void) {\n const audioContext = new window.AudioContext();\n\n const reader = stream.getReader();\n const chunks = [];\n\n try {\n // Read all chunks\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Combine chunks into single ArrayBuffer\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combinedBuffer = new Uint8Array(totalLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n combinedBuffer.set(chunk, offset);\n offset += chunk.length;\n }\n\n // Decode and play\n const audioBuffer = await audioContext.decodeAudioData(combinedBuffer.buffer);\n const source = audioContext.createBufferSource();\n source.buffer = audioBuffer;\n source.onended = onEnded ?? null;\n source.connect(audioContext.destination);\n source.start();\n\n return () => {\n source.onended = null;\n source.stop();\n void audioContext.close();\n };\n } catch (error) {\n await reader.cancel().catch(() => undefined);\n await audioContext.close().catch(() => undefined);\n throw error;\n } finally {\n reader.releaseLock();\n }\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useEffect, useRef, useState } from 'react';\nimport { useMastraClient } from '../mastra-client-context';\nimport { recordMicrophoneToFile } from './record-mic-to-file';\n\ntype Agent = ReturnType<MastraClient['getAgent']>;\ntype VoiceRequestContext = Parameters<Agent['voice']['getSpeakers']>[0];\n\nexport interface SpeechRecognitionState {\n isListening: boolean;\n transcript: string;\n error: string | null;\n}\n\nexport interface UseSpeechRecognitionArgs {\n language?: string;\n agentId?: string;\n requestContext?: VoiceRequestContext;\n}\n\ntype SpeechRecognitionResult = SpeechRecognitionState & {\n start: () => void;\n stop: () => void;\n};\n\nexport const useSpeechRecognition = ({\n language = 'en-US',\n agentId,\n requestContext,\n}: UseSpeechRecognitionArgs): SpeechRecognitionResult => {\n const client = useMastraClient();\n const [agent, setAgent] = useState<Agent | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!agentId) {\n setAgent(null);\n return () => {\n cancelled = true;\n };\n }\n\n const agent = client.getAgent(agentId);\n\n const check = async () => {\n try {\n const speakers = await agent.voice.getSpeakers(requestContext);\n if (!cancelled) {\n setAgent(speakers.length > 0 ? agent : null);\n }\n } catch {\n if (!cancelled) {\n setAgent(null);\n }\n }\n };\n\n void check();\n\n return () => {\n cancelled = true;\n };\n }, [agentId, client, requestContext]);\n\n const browserSpeechRecognition = useBrowserSpeechRecognition({ language });\n const mastraSpeechRecognition = useMastraSpeechToText({ agent, language });\n\n if (!agent) {\n return browserSpeechRecognition;\n }\n\n return mastraSpeechRecognition;\n};\n\nconst useBrowserSpeechRecognition = ({ language = 'en-US' }: { language?: string }): SpeechRecognitionResult => {\n const speechRecognitionRef = useRef<any>(null);\n const [state, setState] = useState<SpeechRecognitionState>({\n isListening: false,\n transcript: '',\n error: null,\n });\n\n const start = () => {\n if (!speechRecognitionRef.current) return;\n speechRecognitionRef.current.start();\n };\n\n const stop = () => {\n if (!speechRecognitionRef.current) return;\n speechRecognitionRef.current.stop();\n };\n\n useEffect(() => {\n if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {\n setState(prev => ({ ...prev, error: 'Speech Recognition not supported in this browser' }));\n return;\n }\n\n const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n const recognition = new SpeechRecognition();\n speechRecognitionRef.current = recognition;\n\n recognition.continuous = true;\n recognition.lang = language;\n\n recognition.onstart = () => {\n setState(prev => ({ ...prev, isListening: true, error: null, transcript: '' }));\n };\n\n recognition.onresult = (event: any) => {\n let finalTranscript = '';\n\n for (let i = event.resultIndex; i < event.results.length; i++) {\n const transcript = event.results[i][0].transcript;\n if (event.results[i].isFinal) {\n finalTranscript += transcript + ' ';\n }\n }\n\n if (!finalTranscript) return;\n // Continuous mode emits one event per finalized phrase with an advancing\n // resultIndex, so append to the session transcript instead of replacing it.\n setState(prev => ({ ...prev, transcript: prev.transcript + finalTranscript }));\n };\n\n recognition.onerror = (event: any) => {\n setState(prev => ({ ...prev, error: `Error: ${event.error}` }));\n };\n\n recognition.onend = () => setState(prev => ({ ...prev, isListening: false }));\n\n return () => {\n try {\n recognition.stop();\n } catch {\n // ignore: recognition may not be running\n }\n recognition.onstart = null;\n recognition.onresult = null;\n recognition.onerror = null;\n recognition.onend = null;\n speechRecognitionRef.current = null;\n };\n }, [language]);\n\n return {\n ...state,\n start,\n stop,\n };\n};\n\nconst useMastraSpeechToText = ({\n agent,\n language,\n}: {\n agent: Agent | null;\n language: string;\n}): SpeechRecognitionResult => {\n const [state, setState] = useState<SpeechRecognitionState>({\n isListening: false,\n transcript: '',\n error: null,\n });\n const recorderRef = useRef<MediaRecorder | null>(null);\n const sessionRef = useRef(0);\n const startInFlightRef = useRef(false);\n\n useEffect(() => {\n return () => {\n sessionRef.current += 1;\n startInFlightRef.current = false;\n recorderRef.current?.stop();\n recorderRef.current = null;\n };\n }, [agent]);\n\n const handleFinish = (session: number) => (file: File) => {\n if (!agent || session !== sessionRef.current) return;\n\n recorderRef.current = null;\n setState(prev => ({ ...prev, isListening: false }));\n\n void agent.voice\n .listen(file, { language })\n .then(res => {\n if (session !== sessionRef.current) return;\n setState(prev => ({ ...prev, transcript: res.text, error: null }));\n })\n .catch(error => {\n if (session !== sessionRef.current) return;\n const message = error instanceof Error ? error.message : 'Failed to transcribe speech';\n setState(prev => ({ ...prev, error: message }));\n });\n };\n\n const start = () => {\n if (!agent || startInFlightRef.current || recorderRef.current) return;\n\n startInFlightRef.current = true;\n // Bump the session here (not in stop()) so a normal stop's onstop callback\n // still matches sessionRef.current. Only a new start (or unmount) should\n // invalidate a prior in-flight recording's result.\n // See: https://github.com/mastra-ai/mastra/issues/19980\n sessionRef.current += 1;\n const session = sessionRef.current;\n\n void recordMicrophoneToFile(handleFinish(session))\n .then(recorder => {\n startInFlightRef.current = false;\n if (session !== sessionRef.current) {\n try {\n recorder.stop();\n } catch {\n // ignore: recorder was never started\n }\n return;\n }\n recorderRef.current = recorder;\n setState(prev => ({ ...prev, isListening: true, error: null }));\n recorder.start();\n })\n .catch(error => {\n startInFlightRef.current = false;\n if (session !== sessionRef.current) return;\n const message = error instanceof Error ? error.message : 'Failed to start speech recording';\n setState(prev => ({ ...prev, isListening: false, error: message }));\n });\n };\n\n const stop = () => {\n if (recorderRef.current) {\n // An active recording — its session was fixed at start() time and hasn't\n // changed, so its own onstop/handleFinish will complete normally.\n recorderRef.current.stop();\n recorderRef.current = null;\n } else if (startInFlightRef.current) {\n // No recorder yet but a start() is still in-flight. Invalidate the\n // session so that start's resolution knows to abort (stop the recorder\n // instead of assigning/starting it) rather than silently proceeding.\n sessionRef.current += 1;\n }\n // Otherwise the hook is idle, or a finished recording's transcription is\n // still in flight — bumping the session then would silently discard the\n // transcript (the same failure class as #19980, in a narrower window).\n startInFlightRef.current = false;\n setState(prev => ({ ...prev, isListening: false }));\n };\n\n return {\n ...state,\n start,\n stop,\n };\n};\n"],"mappings":";;;AAAA,eAAsB,uBAAuB,UAAgC;CAC3E,MAAM,SAAS,MAAM,UAAU,aAAa,aAAa,EAAE,OAAO,KAAK,CAAC;CACxE,MAAM,gBAAgB,IAAI,cAAc,MAAM;CAE9C,IAAI,SAAqB,CAAC;CAE1B,cAAc,mBAAkB,MAAK;EACnC,OAAO,KAAK,EAAE,IAAI;CACpB;CAEA,cAAc,eAAe;EAC3B,MAAM,OAAO,IAAI,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;EACpD,MAAM,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,aAAa,KAAK,IAAI,EAAE,QAAQ;GAC5D,MAAM;GACN,cAAc,KAAK,IAAI;EACzB,CAAC;EAED,OAAO,UAAU,CAAC,CAAC,SAAQ,UAAS,MAAM,KAAK,CAAC;EAChD,SAAS,IAAI;CACf;CAEA,OAAO;AACT;;ACtBA,eAAsB,uBAAuB,QAAwB,SAAsB;CACzF,MAAM,eAAe,IAAI,OAAO,aAAa;CAE7C,MAAM,SAAS,OAAO,UAAU;CAChC,MAAM,SAAS,CAAC;CAEhB,IAAI;EAEF,OAAO,MAAM;GACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;GAC1C,IAAI,MAAM;GACV,OAAO,KAAK,KAAK;EACnB;EAGA,MAAM,cAAc,OAAO,QAAQ,KAAK,UAAU,MAAM,MAAM,QAAQ,CAAC;EACvE,MAAM,iBAAiB,IAAI,WAAW,WAAW;EACjD,IAAI,SAAS;EAEb,KAAK,MAAM,SAAS,QAAQ;GAC1B,eAAe,IAAI,OAAO,MAAM;GAChC,UAAU,MAAM;EAClB;EAGA,MAAM,cAAc,MAAM,aAAa,gBAAgB,eAAe,MAAM;EAC5E,MAAM,SAAS,aAAa,mBAAmB;EAC/C,OAAO,SAAS;EAChB,OAAO,UAAU,WAAW;EAC5B,OAAO,QAAQ,aAAa,WAAW;EACvC,OAAO,MAAM;EAEb,aAAa;GACX,OAAO,UAAU;GACjB,OAAO,KAAK;GACZ,aAAkB,MAAM;EAC1B;CACF,SAAS,OAAO;EACd,MAAM,OAAO,OAAO,CAAC,CAAC,YAAY,KAAA,CAAS;EAC3C,MAAM,aAAa,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;EAChD,MAAM;CACR,UAAU;EACR,OAAO,YAAY;CACrB;AACF;;ACnBA,MAAa,wBAAwB,EACnC,WAAW,SACX,SACA,qBACuD;CACvD,MAAM,SAASA,8BAAAA,gBAAgB;CAC/B,MAAM,CAAC,OAAO,aAAA,GAAYC,MAAAA,SAAAA,CAAuB,IAAI;CAErD,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,YAAY;EAEhB,IAAI,CAAC,SAAS;GACZ,SAAS,IAAI;GACb,aAAa;IACX,YAAY;GACd;EACF;EAEA,MAAM,QAAQ,OAAO,SAAS,OAAO;EAErC,MAAM,QAAQ,YAAY;GACxB,IAAI;IACF,MAAM,WAAW,MAAM,MAAM,MAAM,YAAY,cAAc;IAC7D,IAAI,CAAC,WACH,SAAS,SAAS,SAAS,IAAI,QAAQ,IAAI;GAE/C,QAAQ;IACN,IAAI,CAAC,WACH,SAAS,IAAI;GAEjB;EACF;EAEA,MAAW;EAEX,aAAa;GACX,YAAY;EACd;CACF,GAAG;EAAC;EAAS;EAAQ;CAAc,CAAC;CAEpC,MAAM,2BAA2B,4BAA4B,EAAE,SAAS,CAAC;CACzE,MAAM,0BAA0B,sBAAsB;EAAE;EAAO;CAAS,CAAC;CAEzE,IAAI,CAAC,OACH,OAAO;CAGT,OAAO;AACT;AAEA,MAAM,+BAA+B,EAAE,WAAW,cAA8D;CAC9G,MAAM,wBAAA,GAAuBC,MAAAA,OAAAA,CAAY,IAAI;CAC7C,MAAM,CAAC,OAAO,aAAA,GAAYD,MAAAA,SAAAA,CAAiC;EACzD,aAAa;EACb,YAAY;EACZ,OAAO;CACT,CAAC;CAED,MAAM,cAAc;EAClB,IAAI,CAAC,qBAAqB,SAAS;EACnC,qBAAqB,QAAQ,MAAM;CACrC;CAEA,MAAM,aAAa;EACjB,IAAI,CAAC,qBAAqB,SAAS;EACnC,qBAAqB,QAAQ,KAAK;CACpC;CAEA,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,EAAE,6BAA6B,WAAW,EAAE,uBAAuB,SAAS;GAC9E,UAAS,UAAS;IAAE,GAAG;IAAM,OAAO;GAAmD,EAAE;GACzF;EACF;EAGA,MAAM,cAAc,KADO,OAAe,qBAAsB,OAAe,yBACrC;EAC1C,qBAAqB,UAAU;EAE/B,YAAY,aAAa;EACzB,YAAY,OAAO;EAEnB,YAAY,gBAAgB;GAC1B,UAAS,UAAS;IAAE,GAAG;IAAM,aAAa;IAAM,OAAO;IAAM,YAAY;GAAG,EAAE;EAChF;EAEA,YAAY,YAAY,UAAe;GACrC,IAAI,kBAAkB;GAEtB,KAAK,IAAI,IAAI,MAAM,aAAa,IAAI,MAAM,QAAQ,QAAQ,KAAK;IAC7D,MAAM,aAAa,MAAM,QAAQ,EAAE,CAAC,EAAE,CAAC;IACvC,IAAI,MAAM,QAAQ,EAAE,CAAC,SACnB,mBAAmB,aAAa;GAEpC;GAEA,IAAI,CAAC,iBAAiB;GAGtB,UAAS,UAAS;IAAE,GAAG;IAAM,YAAY,KAAK,aAAa;GAAgB,EAAE;EAC/E;EAEA,YAAY,WAAW,UAAe;GACpC,UAAS,UAAS;IAAE,GAAG;IAAM,OAAO,UAAU,MAAM;GAAQ,EAAE;EAChE;EAEA,YAAY,cAAc,UAAS,UAAS;GAAE,GAAG;GAAM,aAAa;EAAM,EAAE;EAE5E,aAAa;GACX,IAAI;IACF,YAAY,KAAK;GACnB,QAAQ,CAER;GACA,YAAY,UAAU;GACtB,YAAY,WAAW;GACvB,YAAY,UAAU;GACtB,YAAY,QAAQ;GACpB,qBAAqB,UAAU;EACjC;CACF,GAAG,CAAC,QAAQ,CAAC;CAEb,OAAO;EACL,GAAG;EACH;EACA;CACF;AACF;AAEA,MAAM,yBAAyB,EAC7B,OACA,eAI6B;CAC7B,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAiC;EACzD,aAAa;EACb,YAAY;EACZ,OAAO;CACT,CAAC;CACD,MAAM,eAAA,GAAcC,MAAAA,OAAAA,CAA6B,IAAI;CACrD,MAAM,cAAA,GAAaA,MAAAA,OAAAA,CAAO,CAAC;CAC3B,MAAM,oBAAA,GAAmBA,MAAAA,OAAAA,CAAO,KAAK;CAErC,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,aAAa;GACX,WAAW,WAAW;GACtB,iBAAiB,UAAU;GAC3B,YAAY,SAAS,KAAK;GAC1B,YAAY,UAAU;EACxB;CACF,GAAG,CAAC,KAAK,CAAC;CAEV,MAAM,gBAAgB,aAAqB,SAAe;EACxD,IAAI,CAAC,SAAS,YAAY,WAAW,SAAS;EAE9C,YAAY,UAAU;EACtB,UAAS,UAAS;GAAE,GAAG;GAAM,aAAa;EAAM,EAAE;EAElD,MAAW,MACR,OAAO,MAAM,EAAE,SAAS,CAAC,CAAC,CAC1B,MAAK,QAAO;GACX,IAAI,YAAY,WAAW,SAAS;GACpC,UAAS,UAAS;IAAE,GAAG;IAAM,YAAY,IAAI;IAAM,OAAO;GAAK,EAAE;EACnE,CAAC,CAAC,CACD,OAAM,UAAS;GACd,IAAI,YAAY,WAAW,SAAS;GACpC,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;GACzD,UAAS,UAAS;IAAE,GAAG;IAAM,OAAO;GAAQ,EAAE;EAChD,CAAC;CACL;CAEA,MAAM,cAAc;EAClB,IAAI,CAAC,SAAS,iBAAiB,WAAW,YAAY,SAAS;EAE/D,iBAAiB,UAAU;EAK3B,WAAW,WAAW;EACtB,MAAM,UAAU,WAAW;EAE3B,uBAA4B,aAAa,OAAO,CAAC,CAAC,CAC/C,MAAK,aAAY;GAChB,iBAAiB,UAAU;GAC3B,IAAI,YAAY,WAAW,SAAS;IAClC,IAAI;KACF,SAAS,KAAK;IAChB,QAAQ,CAER;IACA;GACF;GACA,YAAY,UAAU;GACtB,UAAS,UAAS;IAAE,GAAG;IAAM,aAAa;IAAM,OAAO;GAAK,EAAE;GAC9D,SAAS,MAAM;EACjB,CAAC,CAAC,CACD,OAAM,UAAS;GACd,iBAAiB,UAAU;GAC3B,IAAI,YAAY,WAAW,SAAS;GACpC,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;GACzD,UAAS,UAAS;IAAE,GAAG;IAAM,aAAa;IAAO,OAAO;GAAQ,EAAE;EACpE,CAAC;CACL;CAEA,MAAM,aAAa;EACjB,IAAI,YAAY,SAAS;GAGvB,YAAY,QAAQ,KAAK;GACzB,YAAY,UAAU;EACxB,OAAO,IAAI,iBAAiB,SAI1B,WAAW,WAAW;EAKxB,iBAAiB,UAAU;EAC3B,UAAS,UAAS;GAAE,GAAG;GAAM,aAAa;EAAM,EAAE;CACpD;CAEA,OAAO;EACL,GAAG;EACH;EACA;CACF;AACF"}
@@ -1,6 +1,6 @@
1
- import { n as useMastraClient } from "./mastra-client-context-Bx_g84YB.js";
1
+ import { n as useMastraClient } from "./mastra-client-context-DQ5z_ze9.js";
2
2
  import { useEffect, useRef, useState } from "react";
3
- //#region src/voice/record-mic-to-file.ts
3
+ // src/voice/record-mic-to-file.ts
4
4
  async function recordMicrophoneToFile(onFinish) {
5
5
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
6
6
  const mediaRecorder = new MediaRecorder(stream);
@@ -19,8 +19,7 @@ async function recordMicrophoneToFile(onFinish) {
19
19
  };
20
20
  return mediaRecorder;
21
21
  }
22
- //#endregion
23
- //#region src/voice/play-stream-with-web-audio.ts
22
+ // src/voice/play-stream-with-web-audio.ts
24
23
  async function playStreamWithWebAudio(stream, onEnded) {
25
24
  const audioContext = new window.AudioContext();
26
25
  const reader = stream.getReader();
@@ -57,8 +56,7 @@ async function playStreamWithWebAudio(stream, onEnded) {
57
56
  reader.releaseLock();
58
57
  }
59
58
  }
60
- //#endregion
61
- //#region src/voice/use-speech-recognition.ts
59
+ // src/voice/use-speech-recognition.ts
62
60
  const useSpeechRecognition = ({ language = "en-US", agentId, requestContext }) => {
63
61
  const client = useMastraClient();
64
62
  const [agent, setAgent] = useState(null);
@@ -258,7 +256,6 @@ const useMastraSpeechToText = ({ agent, language }) => {
258
256
  stop
259
257
  };
260
258
  };
261
- //#endregion
262
259
  export { playStreamWithWebAudio as n, recordMicrophoneToFile as r, useSpeechRecognition as t };
263
260
 
264
- //# sourceMappingURL=voice-DgirjEyH.js.map
261
+ //# sourceMappingURL=voice-ugGu7VyA.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"voice-DgirjEyH.js","names":[],"sources":["../src/voice/record-mic-to-file.ts","../src/voice/play-stream-with-web-audio.ts","../src/voice/use-speech-recognition.ts"],"sourcesContent":["export async function recordMicrophoneToFile(onFinish: (file: File) => void) {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n const mediaRecorder = new MediaRecorder(stream);\n\n let chunks: BlobPart[] = [];\n\n mediaRecorder.ondataavailable = e => {\n chunks.push(e.data);\n };\n\n mediaRecorder.onstop = () => {\n const blob = new Blob(chunks, { type: 'audio/webm' });\n const file = new File([blob], `recording-${Date.now()}.webm`, {\n type: 'audio/webm',\n lastModified: Date.now(),\n });\n\n stream.getTracks().forEach(track => track.stop());\n onFinish(file);\n };\n\n return mediaRecorder;\n}\n","export async function playStreamWithWebAudio(stream: ReadableStream, onEnded?: () => void) {\n const audioContext = new window.AudioContext();\n\n const reader = stream.getReader();\n const chunks = [];\n\n try {\n // Read all chunks\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Combine chunks into single ArrayBuffer\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combinedBuffer = new Uint8Array(totalLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n combinedBuffer.set(chunk, offset);\n offset += chunk.length;\n }\n\n // Decode and play\n const audioBuffer = await audioContext.decodeAudioData(combinedBuffer.buffer);\n const source = audioContext.createBufferSource();\n source.buffer = audioBuffer;\n source.onended = onEnded ?? null;\n source.connect(audioContext.destination);\n source.start();\n\n return () => {\n source.onended = null;\n source.stop();\n void audioContext.close();\n };\n } catch (error) {\n await reader.cancel().catch(() => undefined);\n await audioContext.close().catch(() => undefined);\n throw error;\n } finally {\n reader.releaseLock();\n }\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useEffect, useRef, useState } from 'react';\nimport { useMastraClient } from '../mastra-client-context';\nimport { recordMicrophoneToFile } from './record-mic-to-file';\n\ntype Agent = ReturnType<MastraClient['getAgent']>;\ntype VoiceRequestContext = Parameters<Agent['voice']['getSpeakers']>[0];\n\nexport interface SpeechRecognitionState {\n isListening: boolean;\n transcript: string;\n error: string | null;\n}\n\nexport interface UseSpeechRecognitionArgs {\n language?: string;\n agentId?: string;\n requestContext?: VoiceRequestContext;\n}\n\ntype SpeechRecognitionResult = SpeechRecognitionState & {\n start: () => void;\n stop: () => void;\n};\n\nexport const useSpeechRecognition = ({\n language = 'en-US',\n agentId,\n requestContext,\n}: UseSpeechRecognitionArgs): SpeechRecognitionResult => {\n const client = useMastraClient();\n const [agent, setAgent] = useState<Agent | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!agentId) {\n setAgent(null);\n return () => {\n cancelled = true;\n };\n }\n\n const agent = client.getAgent(agentId);\n\n const check = async () => {\n try {\n const speakers = await agent.voice.getSpeakers(requestContext);\n if (!cancelled) {\n setAgent(speakers.length > 0 ? agent : null);\n }\n } catch {\n if (!cancelled) {\n setAgent(null);\n }\n }\n };\n\n void check();\n\n return () => {\n cancelled = true;\n };\n }, [agentId, client, requestContext]);\n\n const browserSpeechRecognition = useBrowserSpeechRecognition({ language });\n const mastraSpeechRecognition = useMastraSpeechToText({ agent, language });\n\n if (!agent) {\n return browserSpeechRecognition;\n }\n\n return mastraSpeechRecognition;\n};\n\nconst useBrowserSpeechRecognition = ({ language = 'en-US' }: { language?: string }): SpeechRecognitionResult => {\n const speechRecognitionRef = useRef<any>(null);\n const [state, setState] = useState<SpeechRecognitionState>({\n isListening: false,\n transcript: '',\n error: null,\n });\n\n const start = () => {\n if (!speechRecognitionRef.current) return;\n speechRecognitionRef.current.start();\n };\n\n const stop = () => {\n if (!speechRecognitionRef.current) return;\n speechRecognitionRef.current.stop();\n };\n\n useEffect(() => {\n if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {\n setState(prev => ({ ...prev, error: 'Speech Recognition not supported in this browser' }));\n return;\n }\n\n const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n const recognition = new SpeechRecognition();\n speechRecognitionRef.current = recognition;\n\n recognition.continuous = true;\n recognition.lang = language;\n\n recognition.onstart = () => {\n setState(prev => ({ ...prev, isListening: true, error: null, transcript: '' }));\n };\n\n recognition.onresult = (event: any) => {\n let finalTranscript = '';\n\n for (let i = event.resultIndex; i < event.results.length; i++) {\n const transcript = event.results[i][0].transcript;\n if (event.results[i].isFinal) {\n finalTranscript += transcript + ' ';\n }\n }\n\n if (!finalTranscript) return;\n // Continuous mode emits one event per finalized phrase with an advancing\n // resultIndex, so append to the session transcript instead of replacing it.\n setState(prev => ({ ...prev, transcript: prev.transcript + finalTranscript }));\n };\n\n recognition.onerror = (event: any) => {\n setState(prev => ({ ...prev, error: `Error: ${event.error}` }));\n };\n\n recognition.onend = () => setState(prev => ({ ...prev, isListening: false }));\n\n return () => {\n try {\n recognition.stop();\n } catch {\n // ignore: recognition may not be running\n }\n recognition.onstart = null;\n recognition.onresult = null;\n recognition.onerror = null;\n recognition.onend = null;\n speechRecognitionRef.current = null;\n };\n }, [language]);\n\n return {\n ...state,\n start,\n stop,\n };\n};\n\nconst useMastraSpeechToText = ({\n agent,\n language,\n}: {\n agent: Agent | null;\n language: string;\n}): SpeechRecognitionResult => {\n const [state, setState] = useState<SpeechRecognitionState>({\n isListening: false,\n transcript: '',\n error: null,\n });\n const recorderRef = useRef<MediaRecorder | null>(null);\n const sessionRef = useRef(0);\n const startInFlightRef = useRef(false);\n\n useEffect(() => {\n return () => {\n sessionRef.current += 1;\n startInFlightRef.current = false;\n recorderRef.current?.stop();\n recorderRef.current = null;\n };\n }, [agent]);\n\n const handleFinish = (session: number) => (file: File) => {\n if (!agent || session !== sessionRef.current) return;\n\n recorderRef.current = null;\n setState(prev => ({ ...prev, isListening: false }));\n\n void agent.voice\n .listen(file, { language })\n .then(res => {\n if (session !== sessionRef.current) return;\n setState(prev => ({ ...prev, transcript: res.text, error: null }));\n })\n .catch(error => {\n if (session !== sessionRef.current) return;\n const message = error instanceof Error ? error.message : 'Failed to transcribe speech';\n setState(prev => ({ ...prev, error: message }));\n });\n };\n\n const start = () => {\n if (!agent || startInFlightRef.current || recorderRef.current) return;\n\n startInFlightRef.current = true;\n // Bump the session here (not in stop()) so a normal stop's onstop callback\n // still matches sessionRef.current. Only a new start (or unmount) should\n // invalidate a prior in-flight recording's result.\n // See: https://github.com/mastra-ai/mastra/issues/19980\n sessionRef.current += 1;\n const session = sessionRef.current;\n\n void recordMicrophoneToFile(handleFinish(session))\n .then(recorder => {\n startInFlightRef.current = false;\n if (session !== sessionRef.current) {\n try {\n recorder.stop();\n } catch {\n // ignore: recorder was never started\n }\n return;\n }\n recorderRef.current = recorder;\n setState(prev => ({ ...prev, isListening: true, error: null }));\n recorder.start();\n })\n .catch(error => {\n startInFlightRef.current = false;\n if (session !== sessionRef.current) return;\n const message = error instanceof Error ? error.message : 'Failed to start speech recording';\n setState(prev => ({ ...prev, isListening: false, error: message }));\n });\n };\n\n const stop = () => {\n if (recorderRef.current) {\n // An active recording — its session was fixed at start() time and hasn't\n // changed, so its own onstop/handleFinish will complete normally.\n recorderRef.current.stop();\n recorderRef.current = null;\n } else if (startInFlightRef.current) {\n // No recorder yet but a start() is still in-flight. Invalidate the\n // session so that start's resolution knows to abort (stop the recorder\n // instead of assigning/starting it) rather than silently proceeding.\n sessionRef.current += 1;\n }\n // Otherwise the hook is idle, or a finished recording's transcription is\n // still in flight — bumping the session then would silently discard the\n // transcript (the same failure class as #19980, in a narrower window).\n startInFlightRef.current = false;\n setState(prev => ({ ...prev, isListening: false }));\n };\n\n return {\n ...state,\n start,\n stop,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"voice-ugGu7VyA.js","names":[],"sources":["../src/voice/record-mic-to-file.ts","../src/voice/play-stream-with-web-audio.ts","../src/voice/use-speech-recognition.ts"],"sourcesContent":["export async function recordMicrophoneToFile(onFinish: (file: File) => void) {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n const mediaRecorder = new MediaRecorder(stream);\n\n let chunks: BlobPart[] = [];\n\n mediaRecorder.ondataavailable = e => {\n chunks.push(e.data);\n };\n\n mediaRecorder.onstop = () => {\n const blob = new Blob(chunks, { type: 'audio/webm' });\n const file = new File([blob], `recording-${Date.now()}.webm`, {\n type: 'audio/webm',\n lastModified: Date.now(),\n });\n\n stream.getTracks().forEach(track => track.stop());\n onFinish(file);\n };\n\n return mediaRecorder;\n}\n","export async function playStreamWithWebAudio(stream: ReadableStream, onEnded?: () => void) {\n const audioContext = new window.AudioContext();\n\n const reader = stream.getReader();\n const chunks = [];\n\n try {\n // Read all chunks\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n // Combine chunks into single ArrayBuffer\n const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combinedBuffer = new Uint8Array(totalLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n combinedBuffer.set(chunk, offset);\n offset += chunk.length;\n }\n\n // Decode and play\n const audioBuffer = await audioContext.decodeAudioData(combinedBuffer.buffer);\n const source = audioContext.createBufferSource();\n source.buffer = audioBuffer;\n source.onended = onEnded ?? null;\n source.connect(audioContext.destination);\n source.start();\n\n return () => {\n source.onended = null;\n source.stop();\n void audioContext.close();\n };\n } catch (error) {\n await reader.cancel().catch(() => undefined);\n await audioContext.close().catch(() => undefined);\n throw error;\n } finally {\n reader.releaseLock();\n }\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport { useEffect, useRef, useState } from 'react';\nimport { useMastraClient } from '../mastra-client-context';\nimport { recordMicrophoneToFile } from './record-mic-to-file';\n\ntype Agent = ReturnType<MastraClient['getAgent']>;\ntype VoiceRequestContext = Parameters<Agent['voice']['getSpeakers']>[0];\n\nexport interface SpeechRecognitionState {\n isListening: boolean;\n transcript: string;\n error: string | null;\n}\n\nexport interface UseSpeechRecognitionArgs {\n language?: string;\n agentId?: string;\n requestContext?: VoiceRequestContext;\n}\n\ntype SpeechRecognitionResult = SpeechRecognitionState & {\n start: () => void;\n stop: () => void;\n};\n\nexport const useSpeechRecognition = ({\n language = 'en-US',\n agentId,\n requestContext,\n}: UseSpeechRecognitionArgs): SpeechRecognitionResult => {\n const client = useMastraClient();\n const [agent, setAgent] = useState<Agent | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!agentId) {\n setAgent(null);\n return () => {\n cancelled = true;\n };\n }\n\n const agent = client.getAgent(agentId);\n\n const check = async () => {\n try {\n const speakers = await agent.voice.getSpeakers(requestContext);\n if (!cancelled) {\n setAgent(speakers.length > 0 ? agent : null);\n }\n } catch {\n if (!cancelled) {\n setAgent(null);\n }\n }\n };\n\n void check();\n\n return () => {\n cancelled = true;\n };\n }, [agentId, client, requestContext]);\n\n const browserSpeechRecognition = useBrowserSpeechRecognition({ language });\n const mastraSpeechRecognition = useMastraSpeechToText({ agent, language });\n\n if (!agent) {\n return browserSpeechRecognition;\n }\n\n return mastraSpeechRecognition;\n};\n\nconst useBrowserSpeechRecognition = ({ language = 'en-US' }: { language?: string }): SpeechRecognitionResult => {\n const speechRecognitionRef = useRef<any>(null);\n const [state, setState] = useState<SpeechRecognitionState>({\n isListening: false,\n transcript: '',\n error: null,\n });\n\n const start = () => {\n if (!speechRecognitionRef.current) return;\n speechRecognitionRef.current.start();\n };\n\n const stop = () => {\n if (!speechRecognitionRef.current) return;\n speechRecognitionRef.current.stop();\n };\n\n useEffect(() => {\n if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {\n setState(prev => ({ ...prev, error: 'Speech Recognition not supported in this browser' }));\n return;\n }\n\n const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n const recognition = new SpeechRecognition();\n speechRecognitionRef.current = recognition;\n\n recognition.continuous = true;\n recognition.lang = language;\n\n recognition.onstart = () => {\n setState(prev => ({ ...prev, isListening: true, error: null, transcript: '' }));\n };\n\n recognition.onresult = (event: any) => {\n let finalTranscript = '';\n\n for (let i = event.resultIndex; i < event.results.length; i++) {\n const transcript = event.results[i][0].transcript;\n if (event.results[i].isFinal) {\n finalTranscript += transcript + ' ';\n }\n }\n\n if (!finalTranscript) return;\n // Continuous mode emits one event per finalized phrase with an advancing\n // resultIndex, so append to the session transcript instead of replacing it.\n setState(prev => ({ ...prev, transcript: prev.transcript + finalTranscript }));\n };\n\n recognition.onerror = (event: any) => {\n setState(prev => ({ ...prev, error: `Error: ${event.error}` }));\n };\n\n recognition.onend = () => setState(prev => ({ ...prev, isListening: false }));\n\n return () => {\n try {\n recognition.stop();\n } catch {\n // ignore: recognition may not be running\n }\n recognition.onstart = null;\n recognition.onresult = null;\n recognition.onerror = null;\n recognition.onend = null;\n speechRecognitionRef.current = null;\n };\n }, [language]);\n\n return {\n ...state,\n start,\n stop,\n };\n};\n\nconst useMastraSpeechToText = ({\n agent,\n language,\n}: {\n agent: Agent | null;\n language: string;\n}): SpeechRecognitionResult => {\n const [state, setState] = useState<SpeechRecognitionState>({\n isListening: false,\n transcript: '',\n error: null,\n });\n const recorderRef = useRef<MediaRecorder | null>(null);\n const sessionRef = useRef(0);\n const startInFlightRef = useRef(false);\n\n useEffect(() => {\n return () => {\n sessionRef.current += 1;\n startInFlightRef.current = false;\n recorderRef.current?.stop();\n recorderRef.current = null;\n };\n }, [agent]);\n\n const handleFinish = (session: number) => (file: File) => {\n if (!agent || session !== sessionRef.current) return;\n\n recorderRef.current = null;\n setState(prev => ({ ...prev, isListening: false }));\n\n void agent.voice\n .listen(file, { language })\n .then(res => {\n if (session !== sessionRef.current) return;\n setState(prev => ({ ...prev, transcript: res.text, error: null }));\n })\n .catch(error => {\n if (session !== sessionRef.current) return;\n const message = error instanceof Error ? error.message : 'Failed to transcribe speech';\n setState(prev => ({ ...prev, error: message }));\n });\n };\n\n const start = () => {\n if (!agent || startInFlightRef.current || recorderRef.current) return;\n\n startInFlightRef.current = true;\n // Bump the session here (not in stop()) so a normal stop's onstop callback\n // still matches sessionRef.current. Only a new start (or unmount) should\n // invalidate a prior in-flight recording's result.\n // See: https://github.com/mastra-ai/mastra/issues/19980\n sessionRef.current += 1;\n const session = sessionRef.current;\n\n void recordMicrophoneToFile(handleFinish(session))\n .then(recorder => {\n startInFlightRef.current = false;\n if (session !== sessionRef.current) {\n try {\n recorder.stop();\n } catch {\n // ignore: recorder was never started\n }\n return;\n }\n recorderRef.current = recorder;\n setState(prev => ({ ...prev, isListening: true, error: null }));\n recorder.start();\n })\n .catch(error => {\n startInFlightRef.current = false;\n if (session !== sessionRef.current) return;\n const message = error instanceof Error ? error.message : 'Failed to start speech recording';\n setState(prev => ({ ...prev, isListening: false, error: message }));\n });\n };\n\n const stop = () => {\n if (recorderRef.current) {\n // An active recording — its session was fixed at start() time and hasn't\n // changed, so its own onstop/handleFinish will complete normally.\n recorderRef.current.stop();\n recorderRef.current = null;\n } else if (startInFlightRef.current) {\n // No recorder yet but a start() is still in-flight. Invalidate the\n // session so that start's resolution knows to abort (stop the recorder\n // instead of assigning/starting it) rather than silently proceeding.\n sessionRef.current += 1;\n }\n // Otherwise the hook is idle, or a finished recording's transcription is\n // still in flight — bumping the session then would silently discard the\n // transcript (the same failure class as #19980, in a narrower window).\n startInFlightRef.current = false;\n setState(prev => ({ ...prev, isListening: false }));\n };\n\n return {\n ...state,\n start,\n stop,\n };\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/react",
3
- "version": "1.13.0-alpha.2",
3
+ "version": "1.13.0-alpha.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/mastra-ai/mastra.git",
@@ -64,12 +64,12 @@
64
64
  ],
65
65
  "dependencies": {
66
66
  "@lukeed/uuid": "^2.0.1",
67
- "@radix-ui/react-tooltip": "^1.2.8",
67
+ "@radix-ui/react-tooltip": "^1.4.1",
68
68
  "hast-util-to-jsx-runtime": "^2.3.6",
69
- "lucide-react": "^1.37.0",
69
+ "lucide-react": "^1.61.0",
70
70
  "shiki": "^1.29.2",
71
- "tailwind-merge": "^3.5.0",
72
- "@mastra/client-js": "1.57.0-alpha.2"
71
+ "tailwind-merge": "^3.7.0",
72
+ "@mastra/client-js": "1.57.0-alpha.4"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@mastra/core": ">=1.67.0-0 <2.0.0-0",
@@ -79,30 +79,30 @@
79
79
  "zod": "^3.25.0 || ^4.0.0"
80
80
  },
81
81
  "devDependencies": {
82
- "@storybook/react-vite": "^9.1.20",
82
+ "@storybook/react-vite": "^9.1.21",
83
83
  "@tailwindcss/cli": "^4.3.3",
84
84
  "@tailwindcss/vite": "^4.3.3",
85
- "@tanstack/react-query": "^5.90.21",
86
- "@testing-library/react": "^16.3.2",
87
- "@types/react": "^19.2.14",
88
- "@types/react-dom": "^19.2.3",
85
+ "@tanstack/react-query": "^5.104.5",
86
+ "@testing-library/react": "^16.3.3",
87
+ "@types/react": "^19.3.0",
88
+ "@types/react-dom": "^19.3.0",
89
89
  "@vitejs/plugin-react": "^5.2.0",
90
90
  "@vitest/coverage-v8": "4.1.12",
91
91
  "@vitest/ui": "4.1.12",
92
- "jsdom": "^30.1.1",
93
- "msw": "^2.12.11",
94
- "react": "^19.2.5",
95
- "react-dom": "^19.2.5",
96
- "storybook": "^9.1.20",
92
+ "jsdom": "^30.1.3",
93
+ "msw": "^2.15.0",
94
+ "react": "^19.3.1",
95
+ "react-dom": "^19.3.1",
96
+ "storybook": "^9.1.21",
97
97
  "tailwindcss": "^4.3.3",
98
98
  "tsdown": "0.23.1",
99
99
  "typescript": "^7.0.2",
100
- "vite": "^8.0.0",
100
+ "vite": "^8.3.5",
101
101
  "vitest": "4.1.12",
102
102
  "zod": "^3.25.76",
103
103
  "@internal/lint": "0.0.145",
104
104
  "@internal/types-builder": "0.0.120",
105
- "@mastra/core": "1.80.0-alpha.2"
105
+ "@mastra/core": "1.80.0-alpha.4"
106
106
  },
107
107
  "engines": {
108
108
  "node": ">=22.13.0"