@dxos/plugin-transcription 0.8.4-main.7ace549 → 0.8.4-main.8baae0fced

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 (370) 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-7GNN7E3U.mjs → neutral/chunk-ILSA3DU7.mjs} +100 -131
  21. package/dist/lib/neutral/chunk-ILSA3DU7.mjs.map +7 -0
  22. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  23. package/dist/lib/neutral/chunk-KAEXRX3Y.mjs +35 -0
  24. package/dist/lib/neutral/chunk-KAEXRX3Y.mjs.map +7 -0
  25. package/dist/lib/neutral/chunk-MLRJWAQH.mjs +179 -0
  26. package/dist/lib/neutral/chunk-MLRJWAQH.mjs.map +7 -0
  27. package/dist/lib/neutral/chunk-Y5EQAFFR.mjs +8 -0
  28. package/dist/lib/neutral/chunk-Y5EQAFFR.mjs.map +7 -0
  29. package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs +30 -0
  30. package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs.map +7 -0
  31. package/dist/lib/{browser/chunk-VBUIO677.mjs → neutral/chunk-ZWOWQAFX.mjs} +3 -9
  32. package/dist/lib/neutral/chunk-ZWOWQAFX.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-CPD3FZ7M.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/{Transcript/transcript-extension.d.ts → Transcription/transcription-extension.d.ts} +3 -3
  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 +8 -6
  140. package/dist/types/src/normalization/message-normalizer.d.ts.map +1 -0
  141. package/dist/types/src/normalization/normalization.d.ts +549 -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.map +1 -0
  145. package/dist/types/src/operations/create.d.ts +5 -0
  146. package/dist/types/src/operations/create.d.ts.map +1 -0
  147. package/dist/types/src/operations/index.d.ts +3 -0
  148. package/dist/types/src/operations/index.d.ts.map +1 -0
  149. package/dist/types/src/operations/open.d.ts +5 -0
  150. package/dist/types/src/operations/open.d.ts.map +1 -0
  151. package/dist/types/src/operations/summarize.d.ts +8 -0
  152. package/dist/types/src/operations/summarize.d.ts.map +1 -0
  153. package/dist/types/src/plugin.d.ts +4 -0
  154. package/dist/types/src/plugin.d.ts.map +1 -0
  155. package/dist/types/src/stories/FileTranscription.stories.d.ts +20 -0
  156. package/dist/types/src/stories/FileTranscription.stories.d.ts.map +1 -0
  157. package/dist/types/src/{components/stories → stories}/KeyWordRecognition.stories.d.ts +2 -2
  158. package/dist/types/src/stories/KeyWordRecognition.stories.d.ts.map +1 -0
  159. package/dist/types/src/{components/stories/MicrophoneTranscription.stories.d.ts → stories/LiveTranscription.stories.d.ts} +7 -7
  160. package/dist/types/src/stories/LiveTranscription.stories.d.ts.map +1 -0
  161. package/dist/types/src/stories/TranscriptionStory.d.ts +21 -0
  162. package/dist/types/src/stories/TranscriptionStory.d.ts.map +1 -0
  163. package/dist/types/src/stories/common.d.ts +46 -0
  164. package/dist/types/src/stories/common.d.ts.map +1 -0
  165. package/dist/types/src/testing/testing.d.ts +9 -10
  166. package/dist/types/src/testing/testing.d.ts.map +1 -1
  167. package/dist/types/src/transcriber/index.d.ts +1 -1
  168. package/dist/types/src/transcriber/index.d.ts.map +1 -1
  169. package/dist/types/src/transcriber/media-stream-recorder.d.ts +2 -2
  170. package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
  171. package/dist/types/src/transcriber/transcriber.d.ts +59 -4
  172. package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
  173. package/dist/types/src/transcriber/transcriber.test.d.ts +2 -0
  174. package/dist/types/src/transcriber/transcriber.test.d.ts.map +1 -0
  175. package/dist/types/src/transcriber/transcription-manager.d.ts +12 -7
  176. package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
  177. package/dist/types/src/translations.d.ts +9 -8
  178. package/dist/types/src/translations.d.ts.map +1 -1
  179. package/dist/types/src/types/TranscriptOperation.d.ts +927 -0
  180. package/dist/types/src/types/TranscriptOperation.d.ts.map +1 -0
  181. package/dist/types/src/types/TranscriptionCapabilities.d.ts +17 -0
  182. package/dist/types/src/types/TranscriptionCapabilities.d.ts.map +1 -0
  183. package/dist/types/src/types/index.d.ts +2 -2
  184. package/dist/types/src/types/index.d.ts.map +1 -1
  185. package/dist/types/src/util/array.d.ts.map +1 -1
  186. package/dist/types/src/util/get-time-str.d.ts.map +1 -1
  187. package/dist/types/src/util/index.d.ts +1 -0
  188. package/dist/types/src/util/index.d.ts.map +1 -1
  189. package/dist/types/src/util/monitor-audio-level.d.ts.map +1 -1
  190. package/dist/types/src/util/render-byline.d.ts +4 -0
  191. package/dist/types/src/util/render-byline.d.ts.map +1 -0
  192. package/dist/types/tsconfig.tsbuildinfo +1 -1
  193. package/package.json +157 -84
  194. package/src/TranscriptionPlugin.node.ts +20 -0
  195. package/src/TranscriptionPlugin.test.ts +31 -0
  196. package/src/TranscriptionPlugin.tsx +20 -63
  197. package/src/TranscriptionPlugin.workerd.ts +18 -0
  198. package/src/blueprints/index.ts +5 -0
  199. package/src/blueprints/transcription-blueprint.ts +29 -0
  200. package/src/capabilities/blueprint-definition.ts +12 -24
  201. package/src/capabilities/index.ts +11 -7
  202. package/src/capabilities/operation-handler.ts +16 -0
  203. package/src/capabilities/react-surface.tsx +22 -13
  204. package/src/capabilities/text-content.ts +33 -0
  205. package/src/capabilities/transcriber.ts +53 -42
  206. package/src/components/Oracle/Oracle.stories.tsx +147 -0
  207. package/src/components/Oracle/Oracle.tsx +141 -0
  208. package/src/components/Oracle/index.ts +5 -0
  209. package/src/components/Transcription/Transcription.stories.tsx +213 -0
  210. package/src/components/Transcription/Transcription.tsx +58 -0
  211. package/src/components/{Transcript → Transcription}/index.ts +1 -1
  212. package/src/components/{Transcript/transcript-extension.ts → Transcription/transcription-extension.ts} +4 -4
  213. package/src/components/index.ts +2 -6
  214. package/src/containers/TranscriptionArticle/TranscriptionArticle.stories.tsx +61 -0
  215. package/src/containers/TranscriptionArticle/TranscriptionArticle.tsx +62 -0
  216. package/src/containers/TranscriptionArticle/index.ts +5 -0
  217. package/src/containers/index.ts +7 -0
  218. package/src/enrichment/conversation.test.ts +162 -0
  219. package/src/enrichment/conversation.txt +23 -0
  220. package/src/enrichment/operations.ts +268 -0
  221. package/src/enrichment/parser.ts +101 -0
  222. package/src/enrichment/stream-simulator.ts +125 -0
  223. package/src/hooks/index.ts +2 -1
  224. package/src/hooks/useFeedModelAdapter.ts +46 -0
  225. package/src/hooks/useTranscriber.ts +6 -3
  226. package/src/hooks/useTranscriptionRecording.ts +87 -0
  227. package/src/hooks/useVoiceInput.ts +2 -3
  228. package/src/index.ts +4 -5
  229. package/src/meta.ts +4 -3
  230. package/src/model/model.test.ts +9 -3
  231. package/src/model/model.ts +3 -3
  232. package/src/{segments-normalization → normalization}/message-normalizer.ts +34 -21
  233. package/src/{segments-normalization → normalization}/normalization.test.ts +4 -43
  234. package/src/normalization/normalization.ts +76 -0
  235. package/src/operations/create.ts +24 -0
  236. package/src/operations/index.ts +11 -0
  237. package/src/operations/open.ts +28 -0
  238. package/src/operations/summarize.ts +101 -0
  239. package/src/plugin.ts +11 -0
  240. package/src/stories/FileTranscription.stories.tsx +143 -0
  241. package/src/{components/stories → stories}/KeyWordRecognition.stories.tsx +40 -40
  242. package/src/stories/LiveTranscription.stories.tsx +153 -0
  243. package/src/stories/TranscriptionStory.tsx +101 -0
  244. package/src/stories/common.ts +233 -0
  245. package/src/testing/testing.ts +35 -47
  246. package/src/transcriber/index.ts +1 -1
  247. package/src/transcriber/media-stream-recorder.ts +3 -3
  248. package/src/transcriber/transcriber.browser.test.ts +1 -2
  249. package/src/transcriber/transcriber.test.ts +104 -0
  250. package/src/transcriber/transcriber.ts +102 -57
  251. package/src/transcriber/transcription-manager.ts +29 -18
  252. package/src/translations.ts +10 -7
  253. package/src/types/TranscriptOperation.ts +103 -0
  254. package/src/types/TranscriptionCapabilities.ts +39 -0
  255. package/src/types/index.ts +2 -2
  256. package/src/util/index.ts +1 -0
  257. package/src/util/render-byline.ts +33 -0
  258. package/dist/lib/browser/TranscriptContainer-OQFBAGSP.mjs +0 -11
  259. package/dist/lib/browser/blueprint-definition-GZ7NOODS.mjs +0 -147
  260. package/dist/lib/browser/blueprint-definition-GZ7NOODS.mjs.map +0 -7
  261. package/dist/lib/browser/chunk-3MKZ2MNQ.mjs +0 -16
  262. package/dist/lib/browser/chunk-3MKZ2MNQ.mjs.map +0 -7
  263. package/dist/lib/browser/chunk-7GNN7E3U.mjs.map +0 -7
  264. package/dist/lib/browser/chunk-C5YV3JZF.mjs +0 -738
  265. package/dist/lib/browser/chunk-C5YV3JZF.mjs.map +0 -7
  266. package/dist/lib/browser/chunk-O33THH53.mjs +0 -8
  267. package/dist/lib/browser/chunk-O33THH53.mjs.map +0 -7
  268. package/dist/lib/browser/chunk-QOSZIUE2.mjs +0 -32
  269. package/dist/lib/browser/chunk-QOSZIUE2.mjs.map +0 -7
  270. package/dist/lib/browser/chunk-VBUIO677.mjs.map +0 -7
  271. package/dist/lib/browser/index.mjs +0 -128
  272. package/dist/lib/browser/index.mjs.map +0 -7
  273. package/dist/lib/browser/intent-resolver-5CGCLOXB.mjs +0 -25
  274. package/dist/lib/browser/intent-resolver-5CGCLOXB.mjs.map +0 -7
  275. package/dist/lib/browser/meta.json +0 -1
  276. package/dist/lib/browser/react-surface-OK55WK7J.mjs +0 -32
  277. package/dist/lib/browser/react-surface-OK55WK7J.mjs.map +0 -7
  278. package/dist/lib/browser/transcriber-6YDM5ZDT.mjs +0 -56
  279. package/dist/lib/browser/transcriber-6YDM5ZDT.mjs.map +0 -7
  280. package/dist/lib/browser/types/index.mjs +0 -10
  281. package/dist/lib/node-esm/TranscriptContainer-GM47P6WH.mjs +0 -12
  282. package/dist/lib/node-esm/blueprint-definition-GAHQBYTF.mjs +0 -148
  283. package/dist/lib/node-esm/blueprint-definition-GAHQBYTF.mjs.map +0 -7
  284. package/dist/lib/node-esm/chunk-5JN2MHYA.mjs +0 -467
  285. package/dist/lib/node-esm/chunk-5JN2MHYA.mjs.map +0 -7
  286. package/dist/lib/node-esm/chunk-IKGUNN3Z.mjs +0 -739
  287. package/dist/lib/node-esm/chunk-IKGUNN3Z.mjs.map +0 -7
  288. package/dist/lib/node-esm/chunk-SSYFSLB7.mjs +0 -10
  289. package/dist/lib/node-esm/chunk-SSYFSLB7.mjs.map +0 -7
  290. package/dist/lib/node-esm/chunk-SWUVPFKR.mjs +0 -17
  291. package/dist/lib/node-esm/chunk-SWUVPFKR.mjs.map +0 -7
  292. package/dist/lib/node-esm/chunk-U4YPUD2F.mjs +0 -33
  293. package/dist/lib/node-esm/chunk-U4YPUD2F.mjs.map +0 -7
  294. package/dist/lib/node-esm/chunk-YVNQN2J6.mjs +0 -30
  295. package/dist/lib/node-esm/chunk-YVNQN2J6.mjs.map +0 -7
  296. package/dist/lib/node-esm/index.mjs +0 -129
  297. package/dist/lib/node-esm/index.mjs.map +0 -7
  298. package/dist/lib/node-esm/intent-resolver-4H4CXIAL.mjs +0 -26
  299. package/dist/lib/node-esm/intent-resolver-4H4CXIAL.mjs.map +0 -7
  300. package/dist/lib/node-esm/meta.json +0 -1
  301. package/dist/lib/node-esm/react-surface-EK6K2MMD.mjs +0 -33
  302. package/dist/lib/node-esm/react-surface-EK6K2MMD.mjs.map +0 -7
  303. package/dist/lib/node-esm/transcriber-CPD3FZ7M.mjs.map +0 -7
  304. package/dist/lib/node-esm/types/index.mjs +0 -11
  305. package/dist/types/src/capabilities/capabilities.d.ts +0 -17
  306. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  307. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  308. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  309. package/dist/types/src/components/Transcript/Transcript.d.ts +0 -19
  310. package/dist/types/src/components/Transcript/Transcript.d.ts.map +0 -1
  311. package/dist/types/src/components/Transcript/Transcript.stories.d.ts +0 -39
  312. package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +0 -1
  313. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +0 -28
  314. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +0 -1
  315. package/dist/types/src/components/Transcript/index.d.ts +0 -2
  316. package/dist/types/src/components/Transcript/index.d.ts.map +0 -1
  317. package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +0 -1
  318. package/dist/types/src/components/TranscriptContainer.d.ts +0 -9
  319. package/dist/types/src/components/TranscriptContainer.d.ts.map +0 -1
  320. package/dist/types/src/components/stories/FileTranscription.stories.d.ts +0 -18
  321. package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +0 -1
  322. package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +0 -1
  323. package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +0 -1
  324. package/dist/types/src/components/stories/TranscriptionStory.d.ts +0 -12
  325. package/dist/types/src/components/stories/TranscriptionStory.d.ts.map +0 -1
  326. package/dist/types/src/components/stories/useIsSpeaking.d.ts +0 -3
  327. package/dist/types/src/components/stories/useIsSpeaking.d.ts.map +0 -1
  328. package/dist/types/src/functions/index.d.ts +0 -3
  329. package/dist/types/src/functions/index.d.ts.map +0 -1
  330. package/dist/types/src/functions/open.d.ts +0 -7
  331. package/dist/types/src/functions/open.d.ts.map +0 -1
  332. package/dist/types/src/functions/summarize.d.ts +0 -11
  333. package/dist/types/src/functions/summarize.d.ts.map +0 -1
  334. package/dist/types/src/hooks/useQueueModelAdapter.d.ts +0 -8
  335. package/dist/types/src/hooks/useQueueModelAdapter.d.ts.map +0 -1
  336. package/dist/types/src/segments-normalization/index.d.ts.map +0 -1
  337. package/dist/types/src/segments-normalization/message-normalizer.d.ts.map +0 -1
  338. package/dist/types/src/segments-normalization/normalization.d.ts +0 -461
  339. package/dist/types/src/segments-normalization/normalization.d.ts.map +0 -1
  340. package/dist/types/src/segments-normalization/normalization.test.d.ts.map +0 -1
  341. package/dist/types/src/segments-normalization/utils.d.ts.map +0 -1
  342. package/dist/types/src/types/TranscriptAction.d.ts +0 -23
  343. package/dist/types/src/types/TranscriptAction.d.ts.map +0 -1
  344. package/dist/types/src/types/types.d.ts +0 -5
  345. package/dist/types/src/types/types.d.ts.map +0 -1
  346. package/src/capabilities/capabilities.ts +0 -33
  347. package/src/capabilities/intent-resolver.ts +0 -19
  348. package/src/components/Transcript/Transcript.stories.tsx +0 -245
  349. package/src/components/Transcript/Transcript.tsx +0 -93
  350. package/src/components/Transcript/deprecated/OldTranscript.tsx +0 -260
  351. package/src/components/TranscriptContainer.tsx +0 -36
  352. package/src/components/stories/FileTranscription.stories.tsx +0 -257
  353. package/src/components/stories/MicrophoneTranscription.stories.tsx +0 -288
  354. package/src/components/stories/TranscriptionStory.tsx +0 -44
  355. package/src/components/stories/useIsSpeaking.tsx +0 -40
  356. package/src/functions/index.ts +0 -6
  357. package/src/functions/open.ts +0 -38
  358. package/src/functions/summarize.ts +0 -103
  359. package/src/hooks/useQueueModelAdapter.ts +0 -66
  360. package/src/segments-normalization/normalization.ts +0 -115
  361. package/src/types/TranscriptAction.ts +0 -23
  362. package/src/types/types.ts +0 -9
  363. package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
  364. package/dist/lib/{browser/TranscriptContainer-OQFBAGSP.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  365. package/dist/lib/{node-esm/types → neutral/hooks}/index.mjs.map +0 -0
  366. package/dist/lib/{node-esm/TranscriptContainer-GM47P6WH.mjs.map → neutral/index.mjs.map} +0 -0
  367. package/dist/types/src/{segments-normalization → normalization}/normalization.test.d.ts +0 -0
  368. package/dist/types/src/{segments-normalization → normalization}/utils.d.ts +0 -0
  369. package/src/{segments-normalization → normalization}/index.ts +1 -1
  370. /package/src/{segments-normalization → normalization}/utils.ts +0 -0
@@ -19,7 +19,7 @@ const initializeExtendableMediaRecorder = async () => {
19
19
  await register(await connect());
20
20
  };
21
21
 
22
- export type MediaStreamRecorderParams = {
22
+ export type MediaStreamRecorderProps = {
23
23
  mediaStreamTrack: MediaStreamTrack;
24
24
  config: {
25
25
  interval: number;
@@ -37,12 +37,12 @@ export class MediaStreamRecorder implements AudioRecorder {
37
37
  /**
38
38
  * Default MediaRecorder implementation do not support wav encoding.
39
39
  */
40
- private readonly _config: MediaStreamRecorderParams['config'];
40
+ private readonly _config: MediaStreamRecorderProps['config'];
41
41
  private _mediaRecorder?: IMediaRecorder = undefined;
42
42
  private _header?: Uint8Array = undefined;
43
43
  private _onChunk?: (chunk: AudioChunk) => void;
44
44
 
45
- constructor({ mediaStreamTrack, config }: MediaStreamRecorderParams) {
45
+ constructor({ mediaStreamTrack, config }: MediaStreamRecorderProps) {
46
46
  this._mediaStreamTrack = mediaStreamTrack;
47
47
  this._config = config;
48
48
  }
@@ -4,7 +4,6 @@
4
4
 
5
5
  import fs from 'node:fs';
6
6
  import path from 'node:path';
7
-
8
7
  import { describe, expect, test } from 'vitest';
9
8
  import { WaveFile } from 'wavefile';
10
9
 
@@ -213,7 +212,7 @@ class MockAudioRecorder implements AudioRecorder {
213
212
 
214
213
  @trace.span()
215
214
  async start(): Promise<void> {
216
- log.info('start mock audio recorder', { wavParams: this.wav.fmt });
215
+ log.info('start mock audio recorder', { wavProps: this.wav.fmt });
217
216
  const now = Date.now();
218
217
  const samples = this.wav.getSamples();
219
218
  const sampleRate = this.wavConfig.sampleRate;
@@ -0,0 +1,104 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { describe, test } from 'vitest';
6
+
7
+ import { type AudioChunk } from './audio-recorder';
8
+ import { alignWhisperSegments, type WhisperSegment } from './transcriber';
9
+
10
+ const T0 = Date.parse('2026-01-01T00:00:00.000Z');
11
+
12
+ const chunk = (offsetMs = 0, samples = 16): AudioChunk => ({
13
+ timestamp: T0 + offsetMs,
14
+ data: new Float64Array(samples),
15
+ });
16
+
17
+ const segment = (overrides: Partial<WhisperSegment>): WhisperSegment => ({
18
+ text: '',
19
+ start: 0,
20
+ end: 0,
21
+ no_speech_prob: 0,
22
+ words: [],
23
+ ...overrides,
24
+ });
25
+
26
+ describe('alignWhisperSegments', () => {
27
+ test('returns empty when no chunks were transcribed', ({ expect }) => {
28
+ const result = alignWhisperSegments(
29
+ [segment({ text: 'x', end: 1, words: [{ word: 'x', start: 0, end: 1 }] })],
30
+ [],
31
+ 0,
32
+ );
33
+ expect(result.transcripts).toEqual([]);
34
+ expect(result.lastTimestamp).toBeUndefined();
35
+ });
36
+
37
+ test('absolute-timestamps and deduplicates segments against lastTimestamp', ({ expect }) => {
38
+ const segments: WhisperSegment[] = [
39
+ segment({
40
+ text: 'hello world',
41
+ start: 0,
42
+ end: 1,
43
+ words: [
44
+ { word: 'hello ', start: 0, end: 0.5 },
45
+ { word: 'world', start: 0.5, end: 1 },
46
+ ],
47
+ }),
48
+ ];
49
+
50
+ const first = alignWhisperSegments(segments, [chunk(0)], 0);
51
+ expect(first.transcripts).toHaveLength(1);
52
+ expect(first.transcripts[0]._tag).toBe('transcript');
53
+ expect(first.transcripts[0].text).toBe('hello world');
54
+ expect(new Date(first.transcripts[0].started).getTime()).toBe(T0);
55
+ expect(first.lastTimestamp).toBe(T0 + 1_000);
56
+
57
+ // Same segments, same chunk start: every word's absolute start is < lastTimestamp -> filtered out.
58
+ const second = alignWhisperSegments(segments, [chunk(0)], first.lastTimestamp!);
59
+ expect(second.transcripts).toEqual([]);
60
+ expect(second.lastTimestamp).toBeUndefined();
61
+ });
62
+
63
+ test('keeps later words when earlier words fall before lastTimestamp', ({ expect }) => {
64
+ const segments: WhisperSegment[] = [
65
+ segment({
66
+ text: 'old new',
67
+ start: 0,
68
+ end: 2,
69
+ words: [
70
+ { word: 'old ', start: 0, end: 1 },
71
+ { word: 'new', start: 1.5, end: 2 },
72
+ ],
73
+ }),
74
+ ];
75
+
76
+ // First word starts at T0, second at T0+1500 — only the second survives a cursor at T0+1000.
77
+ const result = alignWhisperSegments(segments, [chunk(0)], T0 + 1_000);
78
+ expect(result.transcripts).toHaveLength(1);
79
+ expect(result.transcripts[0].text).toBe('new');
80
+ expect(new Date(result.transcripts[0].started).getTime()).toBe(T0 + 1_500);
81
+ expect(result.lastTimestamp).toBe(T0 + 2_000);
82
+ });
83
+
84
+ test('drops segments that end before lastTimestamp', ({ expect }) => {
85
+ const segments: WhisperSegment[] = [
86
+ segment({
87
+ text: 'stale',
88
+ start: 0,
89
+ end: 0.5,
90
+ words: [{ word: 'stale', start: 0, end: 0.5 }],
91
+ }),
92
+ segment({
93
+ text: 'fresh',
94
+ start: 1,
95
+ end: 2,
96
+ words: [{ word: 'fresh', start: 1.5, end: 2 }],
97
+ }),
98
+ ];
99
+
100
+ const result = alignWhisperSegments(segments, [chunk(0)], T0 + 1_000);
101
+ expect(result.transcripts).toHaveLength(1);
102
+ expect(result.transcripts[0].text).toBe('fresh');
103
+ });
104
+ });
@@ -10,12 +10,15 @@ import { log } from '@dxos/log';
10
10
  import { trace } from '@dxos/tracing';
11
11
  import { type ContentBlock } from '@dxos/types';
12
12
 
13
- import { TRANSCRIPTION_URL } from '../types';
14
13
  import { mergeFloat64Arrays } from '../util';
15
-
16
14
  import { type AudioChunk, type AudioRecorder } from './audio-recorder';
17
15
 
18
- type WhisperWord = {
16
+ /**
17
+ * Endpoint to the calls service.
18
+ */
19
+ const DEFAULT_TRANSCRIPTION_URL = 'https://calls-service.dxos.workers.dev';
20
+
21
+ export type WhisperWord = {
19
22
  word: string;
20
23
 
21
24
  /**
@@ -29,7 +32,7 @@ type WhisperWord = {
29
32
  end: number;
30
33
  };
31
34
 
32
- type WhisperSegment = {
35
+ export type WhisperSegment = {
33
36
  text: string;
34
37
 
35
38
  /**
@@ -61,9 +64,21 @@ export type TranscribeConfig = {
61
64
  * This is needed to catch the beginning of the user's speech.
62
65
  */
63
66
  prefixBufferChunksAmount: number;
67
+
68
+ /**
69
+ * Override the transcription endpoint base URL.
70
+ * Defaults to the DXOS calls service.
71
+ */
72
+ endpoint?: string;
64
73
  };
65
74
 
66
- export type TranscriberParams = {
75
+ /**
76
+ * Function that converts a base64-encoded WAV payload into Whisper segments.
77
+ * Allows callers to swap in alternative providers or mock the transport.
78
+ */
79
+ export type TranscribeFn = (audio: string) => Promise<WhisperSegment[]>;
80
+
81
+ export type TranscriberProps = {
67
82
  config: TranscribeConfig;
68
83
  recorder: AudioRecorder;
69
84
  /**
@@ -71,6 +86,10 @@ export type TranscriberParams = {
71
86
  * @param segments - The transcribed segments.
72
87
  */
73
88
  onSegments: (segments: ContentBlock.Transcript[]) => Promise<void>;
89
+ /**
90
+ * Optional override of the transcription transport. When provided, supersedes `config.endpoint`.
91
+ */
92
+ transcribe?: TranscribeFn;
74
93
  };
75
94
 
76
95
  /**
@@ -80,22 +99,24 @@ export type TranscriberParams = {
80
99
  */
81
100
  export class Transcriber extends Resource {
82
101
  private _audioChunks: AudioChunk[] = [];
83
- private _lastUsedTimestamp = 0;
102
+ private _lastTimestamp = 0;
84
103
 
85
104
  private readonly _openTrigger = new Trigger({ autoReset: true });
86
105
 
87
106
  private readonly _config: TranscribeConfig;
88
107
  private readonly _recorder: AudioRecorder;
89
- private readonly _onSegments: TranscriberParams['onSegments'];
108
+ private readonly _onSegments: TranscriberProps['onSegments'];
109
+ private readonly _transcribeFn?: TranscribeFn;
90
110
 
91
111
  private _recording = false;
92
112
  private _transcribeTask?: DeferredTask = undefined;
93
113
 
94
- constructor({ config, recorder, onSegments }: TranscriberParams) {
114
+ constructor({ config, recorder, onSegments, transcribe }: TranscriberProps) {
95
115
  super();
96
116
  this._config = config;
97
117
  this._recorder = recorder;
98
118
  this._onSegments = onSegments;
119
+ this._transcribeFn = transcribe;
99
120
  }
100
121
 
101
122
  protected override async _open(ctx: Context): Promise<void> {
@@ -192,67 +213,91 @@ export class Transcriber extends Resource {
192
213
  @trace.span({ showInBrowserTimeline: true })
193
214
  private async _fetchTranscription(audio: string): Promise<WhisperSegment[]> {
194
215
  if (audio.length === 0) {
195
- this._audioChunks = [];
196
216
  throw new Error('No audio to send for transcribing');
197
217
  }
198
218
 
199
- const response = await fetch(`${TRANSCRIPTION_URL}/transcribe`, {
200
- method: 'POST',
201
- body: JSON.stringify({ audio }),
202
- headers: {
203
- 'Content-Type': 'application/json',
204
- },
205
- });
206
-
207
- if (!response.ok) {
208
- this._audioChunks = [];
209
- throw new Error(`Transcription failed: ${response.statusText}`);
219
+ let segments: unknown;
220
+ if (this._transcribeFn) {
221
+ segments = await this._transcribeFn(audio);
222
+ } else {
223
+ // TODO(burdon): Create separate endpoint?
224
+ const endpoint = this._config.endpoint ?? DEFAULT_TRANSCRIPTION_URL;
225
+ const response = await fetch(`${endpoint}/transcribe`, {
226
+ method: 'POST',
227
+ body: JSON.stringify({ audio }),
228
+ headers: {
229
+ 'Content-Type': 'application/json',
230
+ },
231
+ });
232
+
233
+ if (!response.ok) {
234
+ throw new Error(`Transcription failed: ${response.statusText}`);
235
+ }
236
+
237
+ ({ segments } = (await response.json()) as { segments?: unknown });
210
238
  }
211
239
 
212
- const { segments } = (await response.json()) as {
213
- segments: WhisperSegment[];
214
- };
215
-
216
- log.info('transcription response', {
217
- segments: segments.length,
218
- string: segments.map((segments) => segments.text).join(' '),
219
- });
240
+ if (!Array.isArray(segments)) {
241
+ throw new Error('Transcription response payload is invalid');
242
+ }
220
243
 
221
- return segments;
244
+ log.info('transcription response', { segments: segments.length });
245
+ return segments as WhisperSegment[];
222
246
  }
223
247
 
224
248
  private _alignSegments(segments: WhisperSegment[], originalChunks: AudioChunk[]): ContentBlock.Transcript[] {
225
- // Absolute zero for all relative timestamps in the segments.
226
- const zeroTimestamp = originalChunks.at(0)!.timestamp;
227
-
228
- const filteredSegments = segments
229
- // Use segments that end after the last used timestamp.
230
- // Segments could overlap, so we need to filter words that starts after the last used timestamp.
231
- .filter((segment) => zeroTimestamp + segment.end * 1_000 >= this._lastUsedTimestamp)
232
- // Use words that starts after the last used timestamp.
233
- .map((segment) => {
234
- const words = segment.words.filter((word) => zeroTimestamp + word.start * 1_000 >= this._lastUsedTimestamp);
235
- return {
236
- ...segment,
237
- words,
238
- text: words.map((word) => word.word).join(''),
239
- start: words.at(0)?.start ?? segment.end,
240
- };
241
- })
242
- .filter((segment) => segment.words.length > 0);
243
-
244
- if (filteredSegments.length === 0) {
245
- return [];
249
+ const result = alignWhisperSegments(segments, originalChunks, this._lastTimestamp);
250
+ if (result.lastTimestamp !== undefined) {
251
+ this._lastTimestamp = result.lastTimestamp;
246
252
  }
247
253
 
248
- // Update last timestamp.
249
- this._lastUsedTimestamp = zeroTimestamp + filteredSegments.at(-1)!.end * 1_000;
254
+ return result.transcripts;
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Pure helper that filters and absolute-timestamps Whisper segments against a chunk timeline.
260
+ * Exported for testing.
261
+ *
262
+ * @param segments - Raw segments returned by the Whisper service for `originalChunks`.
263
+ * @param originalChunks - Chunks fed into the transcription request (used for the zero timestamp).
264
+ * @param lastTimestamp - Most recent absolute timestamp already emitted; segments whose end
265
+ * falls strictly before this point are deduped out, as are individual words whose start does.
266
+ */
267
+ export const alignWhisperSegments = (
268
+ segments: WhisperSegment[],
269
+ originalChunks: AudioChunk[],
270
+ lastTimestamp: number,
271
+ ): { transcripts: ContentBlock.Transcript[]; lastTimestamp?: number } => {
272
+ if (originalChunks.length === 0) {
273
+ return { transcripts: [] };
274
+ }
275
+
276
+ const zeroTimestamp = originalChunks[0].timestamp;
277
+
278
+ const filteredSegments = segments
279
+ .filter((segment) => zeroTimestamp + segment.end * 1_000 >= lastTimestamp)
280
+ .map((segment) => {
281
+ const words = segment.words.filter((word) => zeroTimestamp + word.start * 1_000 >= lastTimestamp);
282
+ return {
283
+ ...segment,
284
+ words,
285
+ text: words.map((word) => word.word).join(''),
286
+ start: words.at(0)?.start ?? segment.end,
287
+ };
288
+ })
289
+ .filter((segment) => segment.words.length > 0);
290
+
291
+ if (filteredSegments.length === 0) {
292
+ return { transcripts: [] };
293
+ }
250
294
 
251
- // Add absolute timestamp to each segment.
252
- return filteredSegments.map((segment) => ({
295
+ return {
296
+ lastTimestamp: zeroTimestamp + filteredSegments.at(-1)!.end * 1_000,
297
+ transcripts: filteredSegments.map((segment) => ({
253
298
  _tag: 'transcript',
254
299
  started: new Date(zeroTimestamp + segment.start * 1_000).toISOString(),
255
300
  text: segment.text.trim(),
256
- }));
257
- }
258
- }
301
+ })),
302
+ };
303
+ };
@@ -2,12 +2,15 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { signal } from '@preact/signals-core';
5
+ import { Atom, type Registry } from '@effect-atom/atom-react';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
6
8
 
7
9
  import { synchronized } from '@dxos/async';
10
+ import { createFeedServiceLayer, type Space } from '@dxos/client/echo';
8
11
  import { Resource } from '@dxos/context';
9
- import { Obj } from '@dxos/echo';
10
- import { type Queue } from '@dxos/echo-db';
12
+ import { Feed, Obj } from '@dxos/echo';
13
+ import { runAndForwardErrors } from '@dxos/effect';
11
14
  import { type EdgeHttpClient } from '@dxos/react-edge-client';
12
15
  import { type ContentBlock, Message } from '@dxos/types';
13
16
 
@@ -34,9 +37,10 @@ export type TranscriptMessageEnricher = (message: Message.Message) => Promise<Me
34
37
 
35
38
  export type TranscriptionManagerOptions = {
36
39
  edgeClient: EdgeHttpClient;
40
+ registry: Registry.Registry;
37
41
 
38
42
  /**
39
- * Enrich the message before it is written to the transcription queue.
43
+ * Enrich the message before it is written to the transcription feed.
40
44
  */
41
45
  messageEnricher?: TranscriptMessageEnricher;
42
46
  };
@@ -47,26 +51,33 @@ export type TranscriptionManagerOptions = {
47
51
  export class TranscriptionManager extends Resource {
48
52
  private readonly _edgeClient: EdgeHttpClient;
49
53
  private readonly _messageEnricher?: TranscriptMessageEnricher;
54
+ private readonly _registry: Registry.Registry;
50
55
  private _audioStreamTrack?: MediaStreamTrack = undefined;
51
56
  private _identityDid?: string = undefined;
52
57
  private _mediaRecorder?: MediaStreamRecorder = undefined;
53
58
  private _transcriber?: Transcriber = undefined;
54
- private _queue?: Queue<Message.Message> = undefined;
55
- private _enabled = signal(false);
59
+ private _feed?: Feed.Feed = undefined;
60
+ private _feedServiceLayer?: Layer.Layer<Feed.FeedService> = undefined;
61
+ private _enabledAtom = Atom.make(false);
56
62
 
57
63
  constructor(options: TranscriptionManagerOptions) {
58
64
  super();
59
65
  this._edgeClient = options.edgeClient;
60
66
  this._messageEnricher = options.messageEnricher;
67
+ this._registry = options.registry;
61
68
  }
62
69
 
63
- /** @reactive */
64
- get enabled() {
65
- return this._enabled.value;
70
+ get enabled(): Atom.Atom<boolean> {
71
+ return this._enabledAtom;
66
72
  }
67
73
 
68
- setQueue(queue: Queue<Message.Message>): this {
69
- this._queue = queue;
74
+ getEnabled(): boolean {
75
+ return this._registry.get(this._enabledAtom);
76
+ }
77
+
78
+ setFeed(space: Space, feed: Feed.Feed): this {
79
+ this._feed = feed;
80
+ this._feedServiceLayer = createFeedServiceLayer(space.queues);
70
81
  return this;
71
82
  }
72
83
 
@@ -78,7 +89,7 @@ export class TranscriptionManager extends Resource {
78
89
  }
79
90
 
80
91
  setRecording(recording?: boolean): this {
81
- if (!this.isOpen || !this._enabled.value) {
92
+ if (!this.isOpen || !this.getEnabled()) {
82
93
  return this;
83
94
  }
84
95
 
@@ -91,11 +102,11 @@ export class TranscriptionManager extends Resource {
91
102
  }
92
103
 
93
104
  async setEnabled(enabled: boolean): Promise<void> {
94
- if (this._enabled.value === enabled) {
105
+ if (this.getEnabled() === enabled) {
95
106
  return;
96
107
  }
97
108
 
98
- this._enabled.value = enabled ?? false;
109
+ this._registry.set(this._enabledAtom, enabled ?? false);
99
110
  if (enabled) {
100
111
  await this._maybeRestartTranscriber();
101
112
  } else {
@@ -122,11 +133,11 @@ export class TranscriptionManager extends Resource {
122
133
  }
123
134
 
124
135
  private async _maybeRestartTranscriber(): Promise<void> {
125
- if (!this._audioStreamTrack || !this._enabled.value || !this.isOpen) {
136
+ if (!this._audioStreamTrack || !this.getEnabled() || !this.isOpen) {
126
137
  return;
127
138
  }
128
139
 
129
- // Reinitialize transcriber if queue or media stream track has changed.
140
+ // Reinitialize transcriber if feed or media stream track has changed.
130
141
  let needReinit = false;
131
142
  if (this._audioStreamTrack !== this._mediaRecorder?.mediaStreamTrack) {
132
143
  this._mediaRecorder = new MediaStreamRecorder({
@@ -155,7 +166,7 @@ export class TranscriptionManager extends Resource {
155
166
  }
156
167
 
157
168
  private async _onSegments(segments: ContentBlock.Transcript[]): Promise<void> {
158
- if (!this.isOpen || !this._queue) {
169
+ if (!this.isOpen || !this._feed || !this._feedServiceLayer) {
159
170
  return;
160
171
  }
161
172
 
@@ -169,6 +180,6 @@ export class TranscriptionManager extends Resource {
169
180
  block = await this._messageEnricher(block);
170
181
  }
171
182
 
172
- await this._queue.append([block]);
183
+ await Feed.append(this._feed, [block]).pipe(Effect.provide(this._feedServiceLayer), runAndForwardErrors);
173
184
  }
174
185
  }
@@ -4,20 +4,23 @@
4
4
 
5
5
  import { type Resource } from '@dxos/react-ui';
6
6
 
7
- import { meta } from './meta';
7
+ import { meta } from '#meta';
8
8
 
9
9
  export const translations = [
10
10
  {
11
11
  'en-US': {
12
12
  [meta.id]: {
13
- 'plugin name': 'Transcription',
14
- 'transcript companion label': 'Transcript',
13
+ 'plugin.name': 'Transcription',
14
+ 'transcript-companion.label': 'Transcript',
15
15
 
16
- 'delete button': 'Delete',
17
- 'bookmark button': 'Bookmark',
18
- 'scroll to end label': 'Scroll to latest',
16
+ 'delete.button': 'Delete',
17
+ 'bookmark.button': 'Bookmark',
18
+ 'scroll-to-end.label': 'Scroll to latest',
19
19
 
20
- 'settings entity extraction label': 'Entity extraction',
20
+ 'start-recording.label': 'Start recording',
21
+ 'stop-recording.label': 'Stop recording',
22
+
23
+ 'settings.entity-extraction.label': 'Entity extraction',
21
24
  },
22
25
  },
23
26
  },
@@ -0,0 +1,103 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ // @import-as-namespace
6
+
7
+ import * as Schema from 'effect/Schema';
8
+
9
+ import { AiService } from '@dxos/ai';
10
+ import { SpaceSchema } from '@dxos/client/echo';
11
+ import { Operation } from '@dxos/compute';
12
+ import { Database, Feed, Ref } from '@dxos/echo';
13
+ import { Message, Transcript } from '@dxos/types';
14
+
15
+ import { meta } from '#meta';
16
+
17
+ const TRANSCRIPT_OPERATION = `${meta.id}.operation`;
18
+
19
+ export const Create = Operation.make({
20
+ meta: { key: `${TRANSCRIPT_OPERATION}.create`, name: 'Create Transcript' },
21
+ input: Schema.Struct({
22
+ name: Schema.optional(Schema.String),
23
+ space: SpaceSchema,
24
+ }),
25
+ output: Schema.Struct({
26
+ object: Transcript.Transcript,
27
+ }),
28
+ });
29
+
30
+ export const MessageWithRangeId = Schema.extend(
31
+ Message.Message,
32
+ Schema.Struct({
33
+ rangeId: Schema.optional(Schema.Array(Schema.String)).annotations({
34
+ description: 'The IDs of the messages that contain the sentences.',
35
+ }),
36
+ }),
37
+ );
38
+
39
+ export type MessageWithRangeIdType = Schema.Schema.Type<typeof MessageWithRangeId>;
40
+
41
+ export const Open = Operation.make({
42
+ meta: {
43
+ key: 'org.dxos.function.transcription.open',
44
+ name: 'Open',
45
+ description: 'Opens and reads the contents of a transcription object.',
46
+ },
47
+ input: Schema.Struct({
48
+ transcript: Ref.Ref(Transcript.Transcript).annotations({
49
+ description: 'The ID of the transcription object.',
50
+ }),
51
+ }),
52
+ output: Schema.Struct({
53
+ content: Schema.String,
54
+ }),
55
+ services: [Database.Service, Feed.FeedService],
56
+ });
57
+
58
+ export const Summarize = Operation.make({
59
+ meta: {
60
+ key: 'org.dxos.function.transcription.summarize',
61
+ name: 'Summarize',
62
+ description: 'Summarize a transcript of a meeting.',
63
+ },
64
+ input: Schema.Struct({
65
+ transcript: Schema.String.annotations({
66
+ description: 'The transcript of the meeting.',
67
+ }),
68
+ notes: Schema.optional(Schema.String).annotations({
69
+ description: 'Additional notes from the participants.',
70
+ }),
71
+ }),
72
+ output: Schema.Struct({
73
+ summary: Schema.String.annotations({
74
+ description: 'The summary of the transcript.',
75
+ }),
76
+ }),
77
+ services: [AiService.AiService],
78
+ });
79
+
80
+ export const SentenceNormalizationInput = Schema.Struct({
81
+ messages: Schema.Array(MessageWithRangeId).annotations({
82
+ description: 'Messages to normalize into sentences.',
83
+ }),
84
+ });
85
+
86
+ export type SentenceNormalizationInputType = Schema.Schema.Type<typeof SentenceNormalizationInput>;
87
+
88
+ export const SentenceNormalizationOutput = Schema.Struct({
89
+ sentences: Schema.Array(MessageWithRangeId.pipe(Schema.mutable)).pipe(Schema.mutable).annotations({
90
+ description: 'The sentences of the transcript.',
91
+ }),
92
+ });
93
+
94
+ export const SentenceNormalization = Operation.make({
95
+ meta: {
96
+ key: 'org.dxos.function.transcription.sentence-normalization',
97
+ name: 'Sentence Normalization',
98
+ description: 'Post process of transcription for sentence normalization',
99
+ },
100
+ input: SentenceNormalizationInput,
101
+ output: SentenceNormalizationOutput,
102
+ services: [],
103
+ });
@@ -0,0 +1,39 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ // @import-as-namespace
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+
9
+ import { meta } from '#meta';
10
+
11
+ import {
12
+ type MediaStreamRecorderProps,
13
+ type Transcriber as TranscriberType,
14
+ type TranscriberProps,
15
+ type TranscriptMessageEnricher,
16
+ type TranscriptionManager as TranscriptionManagerType,
17
+ } from '../transcriber';
18
+
19
+ export type GetTranscriberProps = {
20
+ audioStreamTrack: MediaStreamTrack;
21
+ recorderConfig?: Partial<MediaStreamRecorderProps['config']>;
22
+ transcriberConfig?: Partial<TranscriberProps['config']>;
23
+ onSegments: TranscriberProps['onSegments'];
24
+ transcribe?: TranscriberProps['transcribe'];
25
+ };
26
+
27
+ export type GetTranscriber = (props: GetTranscriberProps) => TranscriberType;
28
+
29
+ export type GetTranscriptionManagerProps = {
30
+ messageEnricher?: TranscriptMessageEnricher;
31
+ };
32
+
33
+ export type GetTranscriptionManager = (props: GetTranscriptionManagerProps) => TranscriptionManagerType;
34
+
35
+ export const Transcriber = Capability.make<GetTranscriber>(`${meta.id}.capability.transcriber`);
36
+
37
+ export const TranscriptionManager = Capability.make<GetTranscriptionManager>(
38
+ `${meta.id}.capability.transcription-manager`,
39
+ );
@@ -2,5 +2,5 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export * as TranscriptAction from './TranscriptAction';
6
- export * from './types';
5
+ export * as TranscriptionCapabilities from './TranscriptionCapabilities';
6
+ export * as TranscriptOperation from './TranscriptOperation';