@dxos/plugin-transcription 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (375) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/neutral/TranscriptionArticle-L6XANBH5.mjs +54 -0
  4. package/dist/lib/neutral/TranscriptionArticle-L6XANBH5.mjs.map +7 -0
  5. package/dist/lib/neutral/TranscriptionPlugin.mjs +34 -0
  6. package/dist/lib/neutral/TranscriptionPlugin.mjs.map +7 -0
  7. package/dist/lib/neutral/TranscriptionPlugin.node.mjs +25 -0
  8. package/dist/lib/neutral/TranscriptionPlugin.node.mjs.map +7 -0
  9. package/dist/lib/neutral/TranscriptionPlugin.workerd.mjs +21 -0
  10. package/dist/lib/neutral/TranscriptionPlugin.workerd.mjs.map +7 -0
  11. package/dist/lib/neutral/blueprint-definition-HOXDG5QP.mjs +15 -0
  12. package/dist/lib/neutral/blueprint-definition-HOXDG5QP.mjs.map +7 -0
  13. package/dist/lib/neutral/blueprints/index.mjs +8 -0
  14. package/dist/lib/neutral/capabilities/index.mjs +17 -0
  15. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  16. package/dist/lib/neutral/chunk-2O3ONPRZ.mjs +298 -0
  17. package/dist/lib/neutral/chunk-2O3ONPRZ.mjs.map +7 -0
  18. package/dist/lib/neutral/chunk-5FXU36PN.mjs +120 -0
  19. package/dist/lib/neutral/chunk-5FXU36PN.mjs.map +7 -0
  20. package/dist/lib/{browser/chunk-VBUIO677.mjs → neutral/chunk-GL4RS533.mjs} +2 -9
  21. package/dist/lib/neutral/chunk-GL4RS533.mjs.map +7 -0
  22. package/dist/lib/{browser/chunk-WH36ENNE.mjs → neutral/chunk-ILSA3DU7.mjs} +102 -133
  23. package/dist/lib/neutral/chunk-ILSA3DU7.mjs.map +7 -0
  24. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  25. package/dist/lib/neutral/chunk-KAEXRX3Y.mjs +35 -0
  26. package/dist/lib/neutral/chunk-KAEXRX3Y.mjs.map +7 -0
  27. package/dist/lib/neutral/chunk-MLRJWAQH.mjs +179 -0
  28. package/dist/lib/neutral/chunk-MLRJWAQH.mjs.map +7 -0
  29. package/dist/lib/neutral/chunk-Y5EQAFFR.mjs +8 -0
  30. package/dist/lib/neutral/chunk-Y5EQAFFR.mjs.map +7 -0
  31. package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs +30 -0
  32. package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs.map +7 -0
  33. package/dist/lib/neutral/components/index.mjs +272 -0
  34. package/dist/lib/neutral/components/index.mjs.map +7 -0
  35. package/dist/lib/neutral/containers/index.mjs +9 -0
  36. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  37. package/dist/lib/neutral/create-RRWRIUSR.mjs +21 -0
  38. package/dist/lib/neutral/create-RRWRIUSR.mjs.map +7 -0
  39. package/dist/lib/neutral/hooks/index.mjs +19 -0
  40. package/dist/lib/neutral/index.mjs +44 -0
  41. package/dist/lib/neutral/meta.json +1 -0
  42. package/dist/lib/neutral/meta.mjs +8 -0
  43. package/dist/lib/neutral/meta.mjs.map +7 -0
  44. package/dist/lib/neutral/open-CVMX5KXZ.mjs +27 -0
  45. package/dist/lib/neutral/open-CVMX5KXZ.mjs.map +7 -0
  46. package/dist/lib/neutral/operation-handler-NXMOAXFP.mjs +13 -0
  47. package/dist/lib/neutral/operation-handler-NXMOAXFP.mjs.map +7 -0
  48. package/dist/lib/neutral/operations/index.mjs +8 -0
  49. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  50. package/dist/lib/neutral/plugin.mjs +16 -0
  51. package/dist/lib/neutral/plugin.mjs.map +7 -0
  52. package/dist/lib/neutral/react-surface-YMZRO242.mjs +26 -0
  53. package/dist/lib/neutral/react-surface-YMZRO242.mjs.map +7 -0
  54. package/dist/lib/neutral/summarize-LA7TRW7A.mjs +78 -0
  55. package/dist/lib/neutral/summarize-LA7TRW7A.mjs.map +7 -0
  56. package/dist/lib/neutral/text-content-F4ASMITB.mjs +30 -0
  57. package/dist/lib/neutral/text-content-F4ASMITB.mjs.map +7 -0
  58. package/dist/lib/{node-esm/transcriber-UGB7ECX6.mjs → neutral/transcriber-ABHATBVH.mjs} +20 -18
  59. package/dist/lib/neutral/transcriber-ABHATBVH.mjs.map +7 -0
  60. package/dist/lib/neutral/translations.mjs +24 -0
  61. package/dist/lib/neutral/translations.mjs.map +7 -0
  62. package/dist/lib/neutral/types/index.mjs +10 -0
  63. package/dist/lib/neutral/types/index.mjs.map +7 -0
  64. package/dist/types/src/TranscriptionPlugin.d.ts +3 -1
  65. package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
  66. package/dist/types/src/TranscriptionPlugin.node.d.ts +4 -0
  67. package/dist/types/src/TranscriptionPlugin.node.d.ts.map +1 -0
  68. package/dist/types/src/TranscriptionPlugin.test.d.ts +2 -0
  69. package/dist/types/src/TranscriptionPlugin.test.d.ts.map +1 -0
  70. package/dist/types/src/TranscriptionPlugin.workerd.d.ts +4 -0
  71. package/dist/types/src/TranscriptionPlugin.workerd.d.ts.map +1 -0
  72. package/dist/types/src/blueprints/index.d.ts +2 -0
  73. package/dist/types/src/blueprints/index.d.ts.map +1 -0
  74. package/dist/types/src/blueprints/transcription-blueprint.d.ts +4 -0
  75. package/dist/types/src/blueprints/transcription-blueprint.d.ts.map +1 -0
  76. package/dist/types/src/capabilities/blueprint-definition.d.ts +5 -4
  77. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -1
  78. package/dist/types/src/capabilities/index.d.ts +10 -5
  79. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  80. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  81. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  82. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  83. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  84. package/dist/types/src/capabilities/text-content.d.ts +8 -0
  85. package/dist/types/src/capabilities/text-content.d.ts.map +1 -0
  86. package/dist/types/src/capabilities/transcriber.d.ts +4 -3
  87. package/dist/types/src/capabilities/transcriber.d.ts.map +1 -1
  88. package/dist/types/src/components/Oracle/Oracle.d.ts +24 -0
  89. package/dist/types/src/components/Oracle/Oracle.d.ts.map +1 -0
  90. package/dist/types/src/components/Oracle/Oracle.stories.d.ts +32 -0
  91. package/dist/types/src/components/Oracle/Oracle.stories.d.ts.map +1 -0
  92. package/dist/types/src/components/Oracle/index.d.ts +2 -0
  93. package/dist/types/src/components/Oracle/index.d.ts.map +1 -0
  94. package/dist/types/src/components/Transcription/Transcription.d.ts +13 -0
  95. package/dist/types/src/components/Transcription/Transcription.d.ts.map +1 -0
  96. package/dist/types/src/components/Transcription/Transcription.stories.d.ts +37 -0
  97. package/dist/types/src/components/Transcription/Transcription.stories.d.ts.map +1 -0
  98. package/dist/types/src/components/Transcription/index.d.ts +2 -0
  99. package/dist/types/src/components/Transcription/index.d.ts.map +1 -0
  100. package/dist/types/src/components/Transcription/transcription-extension.d.ts +15 -0
  101. package/dist/types/src/components/Transcription/transcription-extension.d.ts.map +1 -0
  102. package/dist/types/src/components/index.d.ts +2 -3
  103. package/dist/types/src/components/index.d.ts.map +1 -1
  104. package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.d.ts +6 -0
  105. package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.d.ts.map +1 -0
  106. package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.stories.d.ts +28 -0
  107. package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.stories.d.ts.map +1 -0
  108. package/dist/types/src/containers/TranscriptionArticle/index.d.ts +2 -0
  109. package/dist/types/src/containers/TranscriptionArticle/index.d.ts.map +1 -0
  110. package/dist/types/src/containers/index.d.ts +3 -0
  111. package/dist/types/src/containers/index.d.ts.map +1 -0
  112. package/dist/types/src/enrichment/conversation.test.d.ts +2 -0
  113. package/dist/types/src/enrichment/conversation.test.d.ts.map +1 -0
  114. package/dist/types/src/enrichment/operations.d.ts +200 -0
  115. package/dist/types/src/enrichment/operations.d.ts.map +1 -0
  116. package/dist/types/src/enrichment/parser.d.ts +26 -0
  117. package/dist/types/src/enrichment/parser.d.ts.map +1 -0
  118. package/dist/types/src/enrichment/stream-simulator.d.ts +38 -0
  119. package/dist/types/src/enrichment/stream-simulator.d.ts.map +1 -0
  120. package/dist/types/src/hooks/index.d.ts +2 -1
  121. package/dist/types/src/hooks/index.d.ts.map +1 -1
  122. package/dist/types/src/hooks/useAudioFile.d.ts.map +1 -1
  123. package/dist/types/src/hooks/useAudioTrack.d.ts.map +1 -1
  124. package/dist/types/src/hooks/useFeedModelAdapter.d.ts +12 -0
  125. package/dist/types/src/hooks/useFeedModelAdapter.d.ts.map +1 -0
  126. package/dist/types/src/hooks/useTranscriber.d.ts +2 -2
  127. package/dist/types/src/hooks/useTranscriber.d.ts.map +1 -1
  128. package/dist/types/src/hooks/useTranscriptionRecording.d.ts +12 -0
  129. package/dist/types/src/hooks/useTranscriptionRecording.d.ts.map +1 -0
  130. package/dist/types/src/hooks/useVoiceInput.d.ts.map +1 -1
  131. package/dist/types/src/index.d.ts +2 -3
  132. package/dist/types/src/index.d.ts.map +1 -1
  133. package/dist/types/src/meta.d.ts +2 -2
  134. package/dist/types/src/meta.d.ts.map +1 -1
  135. package/dist/types/src/model/model.d.ts +2 -2
  136. package/dist/types/src/model/model.d.ts.map +1 -1
  137. package/dist/types/src/{segments-normalization → normalization}/index.d.ts +1 -1
  138. package/dist/types/src/normalization/index.d.ts.map +1 -0
  139. package/dist/types/src/{segments-normalization → normalization}/message-normalizer.d.ts +9 -7
  140. package/dist/types/src/normalization/message-normalizer.d.ts.map +1 -0
  141. package/dist/types/src/normalization/normalization.d.ts +543 -0
  142. package/dist/types/src/normalization/normalization.d.ts.map +1 -0
  143. package/dist/types/src/normalization/normalization.test.d.ts.map +1 -0
  144. package/dist/types/src/normalization/utils.d.ts +3 -0
  145. package/dist/types/src/normalization/utils.d.ts.map +1 -0
  146. package/dist/types/src/operations/create.d.ts +5 -0
  147. package/dist/types/src/operations/create.d.ts.map +1 -0
  148. package/dist/types/src/operations/index.d.ts +3 -0
  149. package/dist/types/src/operations/index.d.ts.map +1 -0
  150. package/dist/types/src/operations/open.d.ts +5 -0
  151. package/dist/types/src/operations/open.d.ts.map +1 -0
  152. package/dist/types/src/operations/summarize.d.ts +8 -0
  153. package/dist/types/src/operations/summarize.d.ts.map +1 -0
  154. package/dist/types/src/plugin.d.ts +4 -0
  155. package/dist/types/src/plugin.d.ts.map +1 -0
  156. package/dist/types/src/stories/FileTranscription.stories.d.ts +20 -0
  157. package/dist/types/src/stories/FileTranscription.stories.d.ts.map +1 -0
  158. package/dist/types/src/{components/stories → stories}/KeyWordRecognition.stories.d.ts +2 -2
  159. package/dist/types/src/stories/KeyWordRecognition.stories.d.ts.map +1 -0
  160. package/dist/types/src/{components/stories/MicrophoneTranscription.stories.d.ts → stories/LiveTranscription.stories.d.ts} +7 -7
  161. package/dist/types/src/stories/LiveTranscription.stories.d.ts.map +1 -0
  162. package/dist/types/src/stories/TranscriptionStory.d.ts +21 -0
  163. package/dist/types/src/stories/TranscriptionStory.d.ts.map +1 -0
  164. package/dist/types/src/stories/common.d.ts +46 -0
  165. package/dist/types/src/stories/common.d.ts.map +1 -0
  166. package/dist/types/src/testing/testing.d.ts +13 -14
  167. package/dist/types/src/testing/testing.d.ts.map +1 -1
  168. package/dist/types/src/transcriber/index.d.ts +1 -1
  169. package/dist/types/src/transcriber/index.d.ts.map +1 -1
  170. package/dist/types/src/transcriber/media-stream-recorder.d.ts +2 -2
  171. package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
  172. package/dist/types/src/transcriber/transcriber.d.ts +61 -6
  173. package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
  174. package/dist/types/src/transcriber/transcriber.test.d.ts +2 -0
  175. package/dist/types/src/transcriber/transcriber.test.d.ts.map +1 -0
  176. package/dist/types/src/transcriber/transcription-manager.d.ts +14 -9
  177. package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
  178. package/dist/types/src/translations.d.ts +9 -8
  179. package/dist/types/src/translations.d.ts.map +1 -1
  180. package/dist/types/src/types/TranscriptOperation.d.ts +917 -0
  181. package/dist/types/src/types/TranscriptOperation.d.ts.map +1 -0
  182. package/dist/types/src/types/TranscriptionCapabilities.d.ts +17 -0
  183. package/dist/types/src/types/TranscriptionCapabilities.d.ts.map +1 -0
  184. package/dist/types/src/types/index.d.ts +2 -3
  185. package/dist/types/src/types/index.d.ts.map +1 -1
  186. package/dist/types/src/util/array.d.ts.map +1 -1
  187. package/dist/types/src/util/get-time-str.d.ts.map +1 -1
  188. package/dist/types/src/util/index.d.ts +1 -0
  189. package/dist/types/src/util/index.d.ts.map +1 -1
  190. package/dist/types/src/util/monitor-audio-level.d.ts.map +1 -1
  191. package/dist/types/src/util/render-byline.d.ts +4 -0
  192. package/dist/types/src/util/render-byline.d.ts.map +1 -0
  193. package/dist/types/tsconfig.tsbuildinfo +1 -1
  194. package/package.json +157 -82
  195. package/src/TranscriptionPlugin.node.ts +20 -0
  196. package/src/TranscriptionPlugin.test.ts +31 -0
  197. package/src/TranscriptionPlugin.tsx +20 -64
  198. package/src/TranscriptionPlugin.workerd.ts +18 -0
  199. package/src/blueprints/index.ts +5 -0
  200. package/src/blueprints/transcription-blueprint.ts +29 -0
  201. package/src/capabilities/blueprint-definition.ts +12 -24
  202. package/src/capabilities/index.ts +11 -7
  203. package/src/capabilities/operation-handler.ts +16 -0
  204. package/src/capabilities/react-surface.tsx +23 -14
  205. package/src/capabilities/text-content.ts +33 -0
  206. package/src/capabilities/transcriber.ts +53 -42
  207. package/src/components/Oracle/Oracle.stories.tsx +147 -0
  208. package/src/components/Oracle/Oracle.tsx +141 -0
  209. package/src/components/Oracle/index.ts +5 -0
  210. package/src/components/Transcription/Transcription.stories.tsx +213 -0
  211. package/src/components/Transcription/Transcription.tsx +58 -0
  212. package/src/components/{Transcript → Transcription}/index.ts +1 -1
  213. package/src/components/{Transcript/transcript-extension.ts → Transcription/transcription-extension.ts} +13 -9
  214. package/src/components/index.ts +2 -6
  215. package/src/containers/TranscriptionArticle/TranscriptionArticle.stories.tsx +61 -0
  216. package/src/containers/TranscriptionArticle/TranscriptionArticle.tsx +62 -0
  217. package/src/containers/TranscriptionArticle/index.ts +5 -0
  218. package/src/containers/index.ts +7 -0
  219. package/src/enrichment/conversation.test.ts +162 -0
  220. package/src/enrichment/conversation.txt +23 -0
  221. package/src/enrichment/operations.ts +268 -0
  222. package/src/enrichment/parser.ts +101 -0
  223. package/src/enrichment/stream-simulator.ts +125 -0
  224. package/src/hooks/index.ts +2 -1
  225. package/src/hooks/useFeedModelAdapter.ts +46 -0
  226. package/src/hooks/useTranscriber.ts +12 -4
  227. package/src/hooks/useTranscriptionRecording.ts +87 -0
  228. package/src/hooks/useVoiceInput.ts +2 -3
  229. package/src/index.ts +4 -5
  230. package/src/meta.ts +3 -3
  231. package/src/model/model.test.ts +20 -14
  232. package/src/model/model.ts +3 -3
  233. package/src/{segments-normalization → normalization}/message-normalizer.ts +37 -24
  234. package/src/{segments-normalization → normalization}/normalization.test.ts +8 -47
  235. package/src/normalization/normalization.ts +76 -0
  236. package/src/{segments-normalization → normalization}/utils.ts +2 -2
  237. package/src/operations/create.ts +24 -0
  238. package/src/operations/index.ts +11 -0
  239. package/src/operations/open.ts +28 -0
  240. package/src/operations/summarize.ts +101 -0
  241. package/src/plugin.ts +11 -0
  242. package/src/stories/FileTranscription.stories.tsx +143 -0
  243. package/src/{components/stories → stories}/KeyWordRecognition.stories.tsx +40 -40
  244. package/src/stories/LiveTranscription.stories.tsx +153 -0
  245. package/src/stories/TranscriptionStory.tsx +101 -0
  246. package/src/stories/common.ts +233 -0
  247. package/src/testing/testing.ts +49 -56
  248. package/src/transcriber/index.ts +1 -1
  249. package/src/transcriber/media-stream-recorder.ts +3 -3
  250. package/src/transcriber/transcriber.browser.test.ts +4 -5
  251. package/src/transcriber/transcriber.test.ts +104 -0
  252. package/src/transcriber/transcriber.ts +105 -60
  253. package/src/transcriber/transcription-manager.ts +33 -22
  254. package/src/translations.ts +10 -7
  255. package/src/types/TranscriptOperation.ts +103 -0
  256. package/src/types/TranscriptionCapabilities.ts +39 -0
  257. package/src/types/index.ts +2 -3
  258. package/src/util/index.ts +1 -0
  259. package/src/util/render-byline.ts +33 -0
  260. package/dist/lib/browser/TranscriptContainer-2GSL2XB5.mjs +0 -11
  261. package/dist/lib/browser/blueprint-definition-UAAJYVLZ.mjs +0 -150
  262. package/dist/lib/browser/blueprint-definition-UAAJYVLZ.mjs.map +0 -7
  263. package/dist/lib/browser/chunk-3MKZ2MNQ.mjs +0 -16
  264. package/dist/lib/browser/chunk-3MKZ2MNQ.mjs.map +0 -7
  265. package/dist/lib/browser/chunk-535OJKFO.mjs +0 -8
  266. package/dist/lib/browser/chunk-535OJKFO.mjs.map +0 -7
  267. package/dist/lib/browser/chunk-7DR6HZEF.mjs +0 -732
  268. package/dist/lib/browser/chunk-7DR6HZEF.mjs.map +0 -7
  269. package/dist/lib/browser/chunk-VBUIO677.mjs.map +0 -7
  270. package/dist/lib/browser/chunk-W7WKZTM4.mjs +0 -63
  271. package/dist/lib/browser/chunk-W7WKZTM4.mjs.map +0 -7
  272. package/dist/lib/browser/chunk-WH36ENNE.mjs.map +0 -7
  273. package/dist/lib/browser/index.mjs +0 -130
  274. package/dist/lib/browser/index.mjs.map +0 -7
  275. package/dist/lib/browser/intent-resolver-ZTKTEAQX.mjs +0 -25
  276. package/dist/lib/browser/intent-resolver-ZTKTEAQX.mjs.map +0 -7
  277. package/dist/lib/browser/meta.json +0 -1
  278. package/dist/lib/browser/react-surface-KA32A72I.mjs +0 -34
  279. package/dist/lib/browser/react-surface-KA32A72I.mjs.map +0 -7
  280. package/dist/lib/browser/transcriber-LWOLYQHC.mjs +0 -56
  281. package/dist/lib/browser/transcriber-LWOLYQHC.mjs.map +0 -7
  282. package/dist/lib/browser/types/index.mjs +0 -12
  283. package/dist/lib/node-esm/TranscriptContainer-GRLDCESB.mjs +0 -12
  284. package/dist/lib/node-esm/blueprint-definition-Z3LTZ3ID.mjs +0 -151
  285. package/dist/lib/node-esm/blueprint-definition-Z3LTZ3ID.mjs.map +0 -7
  286. package/dist/lib/node-esm/chunk-K4AZOB5Y.mjs +0 -733
  287. package/dist/lib/node-esm/chunk-K4AZOB5Y.mjs.map +0 -7
  288. package/dist/lib/node-esm/chunk-OLMSTF3M.mjs +0 -64
  289. package/dist/lib/node-esm/chunk-OLMSTF3M.mjs.map +0 -7
  290. package/dist/lib/node-esm/chunk-Q6WD7L2J.mjs +0 -10
  291. package/dist/lib/node-esm/chunk-Q6WD7L2J.mjs.map +0 -7
  292. package/dist/lib/node-esm/chunk-SWUVPFKR.mjs +0 -17
  293. package/dist/lib/node-esm/chunk-SWUVPFKR.mjs.map +0 -7
  294. package/dist/lib/node-esm/chunk-YFN4FJFK.mjs +0 -467
  295. package/dist/lib/node-esm/chunk-YFN4FJFK.mjs.map +0 -7
  296. package/dist/lib/node-esm/chunk-YVNQN2J6.mjs +0 -30
  297. package/dist/lib/node-esm/chunk-YVNQN2J6.mjs.map +0 -7
  298. package/dist/lib/node-esm/index.mjs +0 -131
  299. package/dist/lib/node-esm/index.mjs.map +0 -7
  300. package/dist/lib/node-esm/intent-resolver-55WH2GY6.mjs +0 -26
  301. package/dist/lib/node-esm/intent-resolver-55WH2GY6.mjs.map +0 -7
  302. package/dist/lib/node-esm/meta.json +0 -1
  303. package/dist/lib/node-esm/react-surface-GU7LW2JO.mjs +0 -35
  304. package/dist/lib/node-esm/react-surface-GU7LW2JO.mjs.map +0 -7
  305. package/dist/lib/node-esm/transcriber-UGB7ECX6.mjs.map +0 -7
  306. package/dist/lib/node-esm/types/index.mjs +0 -13
  307. package/dist/types/src/capabilities/capabilities.d.ts +0 -17
  308. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  309. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  310. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  311. package/dist/types/src/components/Transcript/Transcript.d.ts +0 -20
  312. package/dist/types/src/components/Transcript/Transcript.d.ts.map +0 -1
  313. package/dist/types/src/components/Transcript/Transcript.stories.d.ts +0 -39
  314. package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +0 -1
  315. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +0 -28
  316. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +0 -1
  317. package/dist/types/src/components/Transcript/index.d.ts +0 -2
  318. package/dist/types/src/components/Transcript/index.d.ts.map +0 -1
  319. package/dist/types/src/components/Transcript/transcript-extension.d.ts +0 -15
  320. package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +0 -1
  321. package/dist/types/src/components/TranscriptContainer.d.ts +0 -9
  322. package/dist/types/src/components/TranscriptContainer.d.ts.map +0 -1
  323. package/dist/types/src/components/stories/FileTranscription.stories.d.ts +0 -18
  324. package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +0 -1
  325. package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +0 -1
  326. package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +0 -1
  327. package/dist/types/src/components/stories/TranscriptionStory.d.ts +0 -12
  328. package/dist/types/src/components/stories/TranscriptionStory.d.ts.map +0 -1
  329. package/dist/types/src/components/stories/useIsSpeaking.d.ts +0 -3
  330. package/dist/types/src/components/stories/useIsSpeaking.d.ts.map +0 -1
  331. package/dist/types/src/functions/index.d.ts +0 -3
  332. package/dist/types/src/functions/index.d.ts.map +0 -1
  333. package/dist/types/src/functions/open.d.ts +0 -7
  334. package/dist/types/src/functions/open.d.ts.map +0 -1
  335. package/dist/types/src/functions/summarize.d.ts +0 -11
  336. package/dist/types/src/functions/summarize.d.ts.map +0 -1
  337. package/dist/types/src/hooks/useQueueModelAdapter.d.ts +0 -8
  338. package/dist/types/src/hooks/useQueueModelAdapter.d.ts.map +0 -1
  339. package/dist/types/src/segments-normalization/index.d.ts.map +0 -1
  340. package/dist/types/src/segments-normalization/message-normalizer.d.ts.map +0 -1
  341. package/dist/types/src/segments-normalization/normalization.d.ts +0 -476
  342. package/dist/types/src/segments-normalization/normalization.d.ts.map +0 -1
  343. package/dist/types/src/segments-normalization/normalization.test.d.ts.map +0 -1
  344. package/dist/types/src/segments-normalization/utils.d.ts +0 -3
  345. package/dist/types/src/segments-normalization/utils.d.ts.map +0 -1
  346. package/dist/types/src/types/Transcript.d.ts +0 -30
  347. package/dist/types/src/types/Transcript.d.ts.map +0 -1
  348. package/dist/types/src/types/TranscriptAction.d.ts +0 -23
  349. package/dist/types/src/types/TranscriptAction.d.ts.map +0 -1
  350. package/dist/types/src/types/types.d.ts +0 -5
  351. package/dist/types/src/types/types.d.ts.map +0 -1
  352. package/src/capabilities/capabilities.ts +0 -33
  353. package/src/capabilities/intent-resolver.ts +0 -18
  354. package/src/components/Transcript/Transcript.stories.tsx +0 -245
  355. package/src/components/Transcript/Transcript.tsx +0 -93
  356. package/src/components/Transcript/deprecated/OldTranscript.tsx +0 -260
  357. package/src/components/TranscriptContainer.tsx +0 -36
  358. package/src/components/stories/FileTranscription.stories.tsx +0 -256
  359. package/src/components/stories/MicrophoneTranscription.stories.tsx +0 -285
  360. package/src/components/stories/TranscriptionStory.tsx +0 -45
  361. package/src/components/stories/useIsSpeaking.tsx +0 -40
  362. package/src/functions/index.ts +0 -6
  363. package/src/functions/open.ts +0 -39
  364. package/src/functions/summarize.ts +0 -103
  365. package/src/hooks/useQueueModelAdapter.ts +0 -66
  366. package/src/segments-normalization/normalization.ts +0 -115
  367. package/src/types/Transcript.ts +0 -44
  368. package/src/types/TranscriptAction.ts +0 -24
  369. package/src/types/types.ts +0 -9
  370. package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
  371. package/dist/lib/{browser/TranscriptContainer-2GSL2XB5.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  372. package/dist/lib/{node-esm/types → neutral/hooks}/index.mjs.map +0 -0
  373. package/dist/lib/{node-esm/TranscriptContainer-GRLDCESB.mjs.map → neutral/index.mjs.map} +0 -0
  374. package/dist/types/src/{segments-normalization → normalization}/normalization.test.d.ts +0 -0
  375. package/src/{segments-normalization → normalization}/index.ts +1 -1
@@ -6,24 +6,23 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { useEffect, useMemo, useState } from 'react';
7
7
 
8
8
  import { log } from '@dxos/log';
9
- import { Toolbar } from '@dxos/react-ui';
9
+ import { Panel, Toolbar } from '@dxos/react-ui';
10
10
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
- import { mx } from '@dxos/react-ui-theme';
11
+ import { mx } from '@dxos/ui-theme';
12
12
 
13
13
  type Word = {
14
14
  text: string;
15
15
  matched: boolean;
16
16
  };
17
17
 
18
- type StoryProps = {
18
+ type DefaultStoryProps = {
19
19
  keywords: string[];
20
20
  };
21
21
 
22
- const DefaultStory = ({ keywords }: StoryProps) => {
22
+ const DefaultStory = ({ keywords }: DefaultStoryProps) => {
23
23
  const [running, setRunning] = useState(false);
24
24
  const [matchingWords, setMatchingWords] = useState<Word[]>(keywords.map((word) => ({ text: word, matched: false })));
25
25
 
26
- const [transcript, setTranscript] = useState('');
27
26
  const recognition = useMemo(() => {
28
27
  // TODO(mykola): Fix types
29
28
  const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;
@@ -38,16 +37,16 @@ const DefaultStory = ({ keywords }: StoryProps) => {
38
37
  recognition.interimResults = true;
39
38
  recognition.lang = 'en-US';
40
39
  recognition.maxAlternatives = 1;
41
- // Add this line to enable punctuation
40
+ // Add this line to enable punctuation.
42
41
  recognition.grammars = new SpeechGrammarList();
43
42
 
44
- // TODO(mykola): Fix types
43
+ // TODO(mykola): Fix types.
45
44
  recognition.onresult = (event: any) => {
46
45
  log.info('recognition result', { event });
47
46
  const current = event.resultIndex;
48
47
  const transcript = event.results[current][0].transcript;
49
48
 
50
- // Remove punctuation and normalize whitespace for comparison
49
+ // Remove punctuation and normalize whitespace for comparison.
51
50
  const normalizeText = (text: string) =>
52
51
  text
53
52
  .toLowerCase()
@@ -57,7 +56,7 @@ const DefaultStory = ({ keywords }: StoryProps) => {
57
56
 
58
57
  const normalizedTranscript = normalizeText(transcript);
59
58
 
60
- // Check each keyword and update matching words
59
+ // Check each keyword and update matching words.
61
60
  const updatedWords = matchingWords.map((word) => {
62
61
  const normalizedKeyword = normalizeText(word.text);
63
62
  const matched = normalizedTranscript.includes(normalizedKeyword);
@@ -65,10 +64,9 @@ const DefaultStory = ({ keywords }: StoryProps) => {
65
64
  });
66
65
 
67
66
  setMatchingWords(updatedWords);
68
- setTranscript(transcript);
69
67
  };
70
68
 
71
- // TODO(mykola): Fix types
69
+ // TODO(mykola): Fix types.
72
70
  recognition.onerror = (event: any) => {
73
71
  log.error('Speech recognition error:', { error: event.error });
74
72
  setRunning(false);
@@ -86,39 +84,41 @@ const DefaultStory = ({ keywords }: StoryProps) => {
86
84
  }, [running, recognition]);
87
85
 
88
86
  return (
89
- <div className={mx('flex flex-col gap-2 w-[30rem]')}>
90
- <Toolbar.Root>
91
- <Toolbar.IconButton
92
- iconOnly
93
- icon={running ? 'ph--pause--regular' : 'ph--play--regular'}
94
- label={running ? 'Pause' : 'Play'}
95
- onClick={() => setRunning((running) => !running)}
96
- />
97
- </Toolbar.Root>
98
-
99
- <div className='flex flex-wrap'>
100
- {matchingWords.map((word, index) => (
101
- <span
102
- key={index}
103
- className={mx(
104
- 'px-3 py-1 m-2 rounded border',
105
- word.matched ? 'bg-red-200 text-red-800 border-red-300' : 'bg-gray-200 text-gray-600 border-gray-300',
106
- )}
107
- >
108
- {word.text}
109
- </span>
110
- ))}
111
- </div>
112
-
113
- <span>{transcript || (running ? 'Listening...' : 'Click play to start speech recognition')}</span>
114
- </div>
87
+ <Panel.Root>
88
+ <Panel.Toolbar asChild>
89
+ <Toolbar.Root>
90
+ <Toolbar.IconButton
91
+ iconOnly
92
+ icon={running ? 'ph--pause--regular' : 'ph--play--regular'}
93
+ label={running ? 'Pause' : 'Play'}
94
+ onClick={() => setRunning((running) => !running)}
95
+ />
96
+ </Toolbar.Root>
97
+ </Panel.Toolbar>
98
+
99
+ <Panel.Content>
100
+ <div className='p-2 grid grid-cols-[repeat(auto-fill,minmax(6rem,1fr))] gap-2'>
101
+ {matchingWords.map((word, index) => (
102
+ <span
103
+ key={index}
104
+ className={mx(
105
+ 'grid place-items-center p-2 aspect-square rounded-sm border border-separator',
106
+ word.matched && 'border-red-300',
107
+ )}
108
+ >
109
+ {word.text}
110
+ </span>
111
+ ))}
112
+ </div>
113
+ </Panel.Content>
114
+ </Panel.Root>
115
115
  );
116
116
  };
117
117
 
118
118
  const meta = {
119
- title: 'plugins/plugin-transcription/KeyWordDetection',
119
+ title: 'plugins/plugin-transcription/stories/KeyWordDetection',
120
120
  render: DefaultStory,
121
- decorators: [withTheme, withLayout({ container: 'column' })],
121
+ decorators: [withTheme(), withLayout({ layout: 'column' })],
122
122
  } satisfies Meta<typeof DefaultStory>;
123
123
 
124
124
  export default meta;
@@ -127,6 +127,6 @@ type Story = StoryObj<typeof meta>;
127
127
 
128
128
  export const SpeechRecognitionAPI: Story = {
129
129
  args: {
130
- keywords: ['kai', 'computer', 'hello'],
130
+ keywords: ['kai', 'computer', 'hello', 'dxos'],
131
131
  },
132
132
  };
@@ -0,0 +1,153 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useCallback, useMemo, useState } from 'react';
7
+
8
+ import {
9
+ type ExtractionFunction,
10
+ extractionAnthropicFunction,
11
+ extractionNerFunction,
12
+ getNer,
13
+ processTranscriptMessage,
14
+ } from '@dxos/assistant/extraction';
15
+ import { Filter, type Obj } from '@dxos/echo';
16
+ import { invariant } from '@dxos/invariant';
17
+ import { useSpaces } from '@dxos/react-client/echo';
18
+ import { Message, Organization, Person } from '@dxos/types';
19
+
20
+ import { useAudioTrack } from '#hooks';
21
+
22
+ import { type MediaStreamRecorderProps, type TranscriberProps } from '../transcriber';
23
+ import { useIsSpeaking, createStoryDecorators, useStoryMessageModel, useStoryTranscriber } from './common';
24
+ import { TranscriptionStory } from './TranscriptionStory';
25
+
26
+ const DEFAULT_TRANSCRIBER_CONFIG = {
27
+ transcribeAfterChunksAmount: 50,
28
+ prefixBufferChunksAmount: 10,
29
+ };
30
+
31
+ const DEFAULT_RECORDER_CONFIG = {
32
+ interval: 200,
33
+ };
34
+
35
+ type DefaultStoryProps = {
36
+ detectSpeaking?: boolean;
37
+ transcriberConfig?: TranscriberProps['config'];
38
+ recorderConfig?: MediaStreamRecorderProps['config'];
39
+ audioConstraints?: MediaTrackConstraints;
40
+ entityExtraction?: 'ner' | 'llm';
41
+ };
42
+
43
+ const DefaultStory = ({
44
+ detectSpeaking,
45
+ entityExtraction,
46
+ transcriberConfig = DEFAULT_TRANSCRIBER_CONFIG,
47
+ recorderConfig = DEFAULT_RECORDER_CONFIG,
48
+ audioConstraints,
49
+ }: DefaultStoryProps) => {
50
+ const [running, setRunning] = useState(false);
51
+ const track = useAudioTrack(running, audioConstraints);
52
+ const isSpeaking = detectSpeaking ? useIsSpeaking(track) : true;
53
+ const { model, appendMessage } = useStoryMessageModel();
54
+ const [space] = useSpaces();
55
+
56
+ // Resolve the entity-extraction function + nearby objects once per `entityExtraction` toggle.
57
+ const { extractionFunction, objects } = useMemo(() => {
58
+ if (!space || !entityExtraction) {
59
+ return {};
60
+ }
61
+
62
+ let extractionFunction: ExtractionFunction | undefined;
63
+ let objects: Promise<Obj.Unknown[]> | undefined;
64
+ if (entityExtraction === 'ner') {
65
+ void getNer(); // Init model loading. Takes time.
66
+ extractionFunction = extractionNerFunction;
67
+ } else if (entityExtraction === 'llm') {
68
+ extractionFunction = extractionAnthropicFunction;
69
+ objects = space.db.query(Filter.or(Filter.type(Person.Person), Filter.type(Organization.Organization))).run();
70
+ }
71
+ return { extractionFunction, objects };
72
+ }, [entityExtraction, space]);
73
+
74
+ // Build a Message from each transcribed batch; optionally enrich via entity extraction.
75
+ const handleSegments = useCallback<TranscriberProps['onSegments']>(
76
+ async (blocks) => {
77
+ const message = Message.make({
78
+ sender: { name: 'You' },
79
+ created: new Date().toISOString(),
80
+ blocks,
81
+ });
82
+
83
+ if (entityExtraction && space) {
84
+ invariant(extractionFunction, 'extractionFunction is required');
85
+ const result = await processTranscriptMessage({
86
+ function: extractionFunction,
87
+ input: { message, objects: await objects },
88
+ options: { fallbackToRaw: true, timeout: 30_000 },
89
+ });
90
+ appendMessage(result.message);
91
+ } else {
92
+ appendMessage(message);
93
+ }
94
+ },
95
+ [appendMessage, space, entityExtraction, extractionFunction, objects],
96
+ );
97
+
98
+ useStoryTranscriber({
99
+ audioStreamTrack: track,
100
+ running,
101
+ isSpeaking,
102
+ transcriberConfig,
103
+ recorderConfig,
104
+ onSegments: handleSegments,
105
+ });
106
+
107
+ return <TranscriptionStory model={model} running={running} onRunningChange={setRunning} />;
108
+ };
109
+
110
+ const meta = {
111
+ title: 'plugins/plugin-transcription/stories/LiveTranscription',
112
+ render: DefaultStory,
113
+ decorators: createStoryDecorators({ enableVectorIndex: true }),
114
+ } satisfies Meta<typeof DefaultStory>;
115
+
116
+ export default meta;
117
+
118
+ type Story = StoryObj<typeof meta>;
119
+
120
+ export const Default: Story = {
121
+ args: {
122
+ detectSpeaking: false,
123
+ audioConstraints: {
124
+ echoCancellation: false,
125
+ noiseSuppression: false,
126
+ autoGainControl: false,
127
+ },
128
+ },
129
+ };
130
+
131
+ export const SpeechDetection: Story = {
132
+ args: {
133
+ detectSpeaking: true,
134
+ audioConstraints: {
135
+ echoCancellation: true,
136
+ noiseSuppression: true,
137
+ autoGainControl: true,
138
+ },
139
+ },
140
+ };
141
+
142
+ // TODO(mykola): Fix hugging face quota issues.
143
+ // export const EntityExtraction: Story = {
144
+ // args: {
145
+ // detectSpeaking: true,
146
+ // entityExtraction: 'ner',
147
+ // audioConstraints: {
148
+ // echoCancellation: true,
149
+ // noiseSuppression: true,
150
+ // autoGainControl: true,
151
+ // },
152
+ // },
153
+ // };
@@ -0,0 +1,101 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React, {
6
+ type ChangeEvent,
7
+ type Dispatch,
8
+ type RefObject,
9
+ type SetStateAction,
10
+ useCallback,
11
+ useRef,
12
+ } from 'react';
13
+
14
+ import { IconButton, ScrollContainer, Toolbar } from '@dxos/react-ui';
15
+ import { type Message } from '@dxos/types';
16
+
17
+ import { Transcription } from '../components';
18
+ import { type SerializationModel } from '../model';
19
+
20
+ export type TranscriptionStoryProps = {
21
+ audioRef?: RefObject<HTMLAudioElement | null>;
22
+ model: SerializationModel<Message.Message>;
23
+ running: boolean;
24
+ disabled?: boolean;
25
+ uploadAccept?: string;
26
+ onRunningChange: Dispatch<SetStateAction<boolean>>;
27
+ onUpload?: (file: File) => void;
28
+ };
29
+
30
+ /**
31
+ * Story wrapper that renders a transcript with playback controls, an optional audio file
32
+ * upload affordance, and a toolbar slot for additional controls.
33
+ *
34
+ * @param onUpload - Callback fired when the user picks a local audio file via the upload button.
35
+ * @param uploadAccept - HTML `accept` filter for the hidden file input. Defaults to `audio/*`.
36
+ */
37
+ export const TranscriptionStory = ({
38
+ audioRef,
39
+ model,
40
+ running,
41
+ disabled,
42
+ uploadAccept = 'audio/*',
43
+ onRunningChange,
44
+ onUpload,
45
+ }: TranscriptionStoryProps) => {
46
+ const fileInputRef = useRef<HTMLInputElement>(null);
47
+
48
+ const handleFileChange = useCallback(
49
+ (event: ChangeEvent<HTMLInputElement>) => {
50
+ const file = event.target.files?.[0];
51
+ if (file && onUpload) {
52
+ onUpload(file);
53
+ }
54
+
55
+ // Reset so the same file can be re-selected.
56
+ event.target.value = '';
57
+ },
58
+ [onUpload],
59
+ );
60
+
61
+ return (
62
+ <>
63
+ {audioRef && <audio ref={audioRef} autoPlay />}
64
+ <Toolbar.Root>
65
+ <IconButton
66
+ iconOnly
67
+ disabled={disabled}
68
+ icon={running ? 'ph--pause--regular' : 'ph--play--regular'}
69
+ label={running ? 'Pause' : 'Play'}
70
+ onClick={() => onRunningChange((running) => !running)}
71
+ />
72
+ {onUpload && (
73
+ <>
74
+ <input
75
+ ref={fileInputRef}
76
+ type='file'
77
+ accept={uploadAccept}
78
+ disabled={disabled}
79
+ className='hidden'
80
+ onChange={handleFileChange}
81
+ />
82
+ <IconButton
83
+ iconOnly
84
+ disabled={disabled}
85
+ icon='ph--upload--regular'
86
+ label='Upload audio'
87
+ onClick={() => fileInputRef.current?.click()}
88
+ />
89
+ </>
90
+ )}
91
+ </Toolbar.Root>
92
+ <ScrollContainer.Root pin>
93
+ <ScrollContainer.Content>
94
+ <ScrollContainer.Viewport>
95
+ <Transcription model={model} />
96
+ </ScrollContainer.Viewport>
97
+ </ScrollContainer.Content>
98
+ </ScrollContainer.Root>
99
+ </>
100
+ );
101
+ };
@@ -0,0 +1,233 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ // Helpers shared between LiveTranscription / FileTranscription stories.
6
+ // Each "live" story differs only in its *audio source* (mic vs file); everything else —
7
+ // the local in-memory message buffer, the transcriber lifecycle, and the plugin-manager
8
+ // decorator stack — is identical and lives here.
9
+
10
+ import { type Decorator } from '@storybook/react-vite';
11
+ import * as Effect from 'effect/Effect';
12
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
13
+
14
+ import { withPluginManager } from '@dxos/app-framework/testing';
15
+ import { AppActivationEvents } from '@dxos/app-toolkit';
16
+ import { scheduleTask } from '@dxos/async';
17
+ import { Context } from '@dxos/context';
18
+ import { Obj } from '@dxos/echo';
19
+ import { SpeakingMonitor } from '@dxos/plugin-calls';
20
+ import { ClientPlugin, initializeIdentity } from '@dxos/plugin-client/testing';
21
+ import { PreviewPlugin } from '@dxos/plugin-preview/testing';
22
+ import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
23
+ import { IndexKind } from '@dxos/react-client/echo';
24
+ import { withLayout } from '@dxos/react-ui/testing';
25
+ import { Message, Organization, Person } from '@dxos/types';
26
+ import { seedTestData } from '@dxos/types/testing';
27
+
28
+ import { useFeedModelAdapter, useTranscriber } from '#hooks';
29
+ import { TestItem } from '#testing';
30
+ import { type TranscriptionCapabilities } from '#types';
31
+
32
+ import { type Transcriber, type TranscriberProps } from '../transcriber';
33
+ import { TranscriptionPlugin } from '../TranscriptionPlugin';
34
+ import { renderByline } from '../util';
35
+
36
+ export const useIsSpeaking = (track?: MediaStreamTrack) => {
37
+ const [isSpeaking, setIsSpeaking] = useState(false);
38
+ const speakingMonitor = useMemo(() => {
39
+ if (!track) {
40
+ return;
41
+ }
42
+
43
+ return new SpeakingMonitor(track);
44
+ }, [track]);
45
+
46
+ useEffect(() => {
47
+ if (!speakingMonitor) {
48
+ return;
49
+ }
50
+
51
+ const ctx = new Context();
52
+ scheduleTask(ctx, async () => {
53
+ speakingMonitor.speakingChanged.on(ctx, () => setIsSpeaking(speakingMonitor.isSpeaking));
54
+ await speakingMonitor.open();
55
+ ctx.onDispose(() => speakingMonitor.close());
56
+ });
57
+
58
+ return () => {
59
+ void ctx.dispose();
60
+ };
61
+ }, [speakingMonitor]);
62
+
63
+ return isSpeaking;
64
+ };
65
+
66
+ //
67
+ // Message model.
68
+ //
69
+
70
+ /**
71
+ * In-memory message buffer + model adapter for storybook use (production wires up a real
72
+ * space-backed `Feed`). Returns the renderable `model` plus an `appendMessage` callback.
73
+ */
74
+ export const useStoryMessageModel = () => {
75
+ const [messages, setMessages] = useState<Message.Message[]>([]);
76
+ const appendMessage = useCallback((message: Message.Message) => setMessages((prev) => [...prev, message]), []);
77
+ const model = useFeedModelAdapter(renderByline([]), messages);
78
+ return { model, appendMessage };
79
+ };
80
+
81
+ /**
82
+ * Wraps blocks in a `Message.Message` with the given sender and appends it to the local buffer.
83
+ * Provided as a convenience for stories that don't need entity-extraction or custom enrichment.
84
+ */
85
+ export const useStoryAppendSegments = (
86
+ appendMessage: (message: Message.Message) => void,
87
+ sender: Message.Message['sender'] = {},
88
+ ): TranscriberProps['onSegments'] =>
89
+ useCallback<TranscriberProps['onSegments']>(
90
+ async (blocks) => {
91
+ appendMessage(
92
+ Obj.make(Message.Message, {
93
+ created: new Date().toISOString(),
94
+ sender,
95
+ blocks,
96
+ }),
97
+ );
98
+ },
99
+ [appendMessage, sender],
100
+ );
101
+
102
+ //
103
+ // Transcriber lifecycle.
104
+ //
105
+
106
+ export type UseStoryTranscriberOptions = Pick<
107
+ TranscriptionCapabilities.GetTranscriberProps,
108
+ 'transcriberConfig' | 'recorderConfig' | 'onSegments'
109
+ > & {
110
+ audioStreamTrack?: MediaStreamTrack;
111
+ /** Whether the user has the toolbar toggle on. */
112
+ running: boolean;
113
+ /** Voice-activity flag — chunks recording only fires while `true`. */
114
+ isSpeaking: boolean;
115
+ };
116
+
117
+ /**
118
+ * Drives the transcriber's open/close + chunk-recording lifecycle off `running`,
119
+ * the open flag, and an `isSpeaking` voice-activity gate. Returns the transcriber instance
120
+ * (`undefined` until the capability resolves and an audio track is available).
121
+ */
122
+ export const useStoryTranscriber = ({
123
+ audioStreamTrack,
124
+ running,
125
+ isSpeaking,
126
+ transcriberConfig,
127
+ recorderConfig,
128
+ onSegments,
129
+ }: UseStoryTranscriberOptions): Transcriber | undefined => {
130
+ const transcriber = useTranscriber({
131
+ audioStreamTrack,
132
+ onSegments,
133
+ transcriberConfig,
134
+ recorderConfig,
135
+ });
136
+
137
+ // Open the transcriber when it becomes available; close on teardown.
138
+ // `tokenRef` is a per-effect identity so a late `close()` completion from a stale
139
+ // transcriber instance can't clobber `isOpen` after a newer instance has opened.
140
+ const [isOpen, setIsOpen] = useState(false);
141
+ const tokenRef = useRef<symbol | null>(null);
142
+ useEffect(() => {
143
+ if (!transcriber) {
144
+ return;
145
+ }
146
+ const token = Symbol();
147
+ tokenRef.current = token;
148
+ void transcriber.open().then(
149
+ () => tokenRef.current === token && setIsOpen(true),
150
+ () => tokenRef.current === token && setIsOpen(false),
151
+ );
152
+ return () => {
153
+ void transcriber.close().then(() => {
154
+ if (tokenRef.current === token) {
155
+ setIsOpen(false);
156
+ }
157
+ });
158
+ };
159
+ }, [transcriber]);
160
+
161
+ // Start/stop chunk recording based on running + open + isSpeaking.
162
+ useEffect(() => {
163
+ if (!transcriber || !isOpen) {
164
+ return;
165
+ }
166
+ if (running && isSpeaking) {
167
+ transcriber.startChunksRecording();
168
+ } else {
169
+ transcriber.stopChunksRecording();
170
+ }
171
+ }, [transcriber, isOpen, running, isSpeaking]);
172
+
173
+ return transcriber;
174
+ };
175
+
176
+ //
177
+ // Plugin manager decorator.
178
+ //
179
+
180
+ export type StoryDecoratorsOptions = {
181
+ /**
182
+ * Enable schema/graph/vector indexes after the client boots; needed for entity-extraction
183
+ * queries over seeded `Person` / `Organization` objects.
184
+ * @default false
185
+ */
186
+ enableVectorIndex?: boolean;
187
+ };
188
+
189
+ /**
190
+ * Standard plugin-manager decorator for transcription stories: core plugins,
191
+ * `ClientPlugin` with `Person`/`Organization`/`TestItem` schemas + seeded test data, plus
192
+ * the `PreviewPlugin` and `TranscriptionPlugin`. Toggle `enableVectorIndex` for entity-extraction.
193
+ */
194
+ export const createStoryDecorators = ({ enableVectorIndex = false }: StoryDecoratorsOptions = {}): Decorator[] => [
195
+ withLayout({ layout: 'column' }),
196
+ withPluginManager({
197
+ plugins: [
198
+ ...corePlugins(),
199
+ StorybookPlugin({}),
200
+ ClientPlugin({
201
+ types: [TestItem, Person.Person, Organization.Organization],
202
+ onClientInitialized: ({ client }) =>
203
+ Effect.gen(function* () {
204
+ const { personalSpace } = yield* initializeIdentity(client);
205
+ if (enableVectorIndex) {
206
+ yield* enableQueryIndexes(client.services.services);
207
+ }
208
+ yield* Effect.promise(() => seedTestData(personalSpace));
209
+ }),
210
+ }),
211
+ PreviewPlugin(),
212
+ TranscriptionPlugin(),
213
+ ],
214
+ fireEvents: [AppActivationEvents.SetupAppGraph],
215
+ }),
216
+ ];
217
+
218
+ // TODO(mykola): Make API easier to use.
219
+ // TODO(mykola): Delete after enabling vector indexing by default.
220
+ const enableQueryIndexes = (services: { QueryService?: any }) =>
221
+ Effect.gen(function* () {
222
+ yield* Effect.promise(() =>
223
+ services.QueryService!.setConfig({
224
+ enabled: true,
225
+ indexes: [
226
+ { kind: IndexKind.Kind.SCHEMA_MATCH },
227
+ { kind: IndexKind.Kind.GRAPH },
228
+ { kind: IndexKind.Kind.VECTOR },
229
+ ],
230
+ }),
231
+ );
232
+ yield* Effect.promise(() => services.QueryService!.reindex());
233
+ });