@dxos/plugin-transcription 0.8.3 → 0.8.4-main.03d5cd7b56

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 (344) hide show
  1. package/dist/lib/neutral/TranscriptionContainer-XNGXNGPX.mjs +35 -0
  2. package/dist/lib/neutral/TranscriptionContainer-XNGXNGPX.mjs.map +7 -0
  3. package/dist/lib/neutral/TranscriptionPlugin.mjs +34 -0
  4. package/dist/lib/neutral/TranscriptionPlugin.mjs.map +7 -0
  5. package/dist/lib/neutral/TranscriptionPlugin.node.mjs +25 -0
  6. package/dist/lib/neutral/TranscriptionPlugin.node.mjs.map +7 -0
  7. package/dist/lib/neutral/blueprint-definition-HOXDG5QP.mjs +15 -0
  8. package/dist/lib/neutral/blueprint-definition-HOXDG5QP.mjs.map +7 -0
  9. package/dist/lib/neutral/blueprints/index.mjs +8 -0
  10. package/dist/lib/neutral/capabilities/index.mjs +17 -0
  11. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  12. package/dist/lib/neutral/chunk-GL4RS533.mjs +22 -0
  13. package/dist/lib/neutral/chunk-GL4RS533.mjs.map +7 -0
  14. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  15. package/dist/lib/neutral/chunk-KAEXRX3Y.mjs +35 -0
  16. package/dist/lib/neutral/chunk-KAEXRX3Y.mjs.map +7 -0
  17. package/dist/lib/{browser/chunk-IQ5ZRMHZ.mjs → neutral/chunk-LS3R7EQI.mjs} +130 -195
  18. package/dist/lib/neutral/chunk-LS3R7EQI.mjs.map +7 -0
  19. package/dist/lib/neutral/chunk-MLRJWAQH.mjs +179 -0
  20. package/dist/lib/neutral/chunk-MLRJWAQH.mjs.map +7 -0
  21. package/dist/lib/neutral/chunk-NNR3EYR2.mjs +124 -0
  22. package/dist/lib/neutral/chunk-NNR3EYR2.mjs.map +7 -0
  23. package/dist/lib/neutral/chunk-NQQK7UZQ.mjs +244 -0
  24. package/dist/lib/neutral/chunk-NQQK7UZQ.mjs.map +7 -0
  25. package/dist/lib/neutral/chunk-WVEZMGBT.mjs +8 -0
  26. package/dist/lib/neutral/chunk-WVEZMGBT.mjs.map +7 -0
  27. package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs +30 -0
  28. package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs.map +7 -0
  29. package/dist/lib/neutral/components/index.mjs +207 -0
  30. package/dist/lib/neutral/components/index.mjs.map +7 -0
  31. package/dist/lib/neutral/containers/index.mjs +9 -0
  32. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  33. package/dist/lib/neutral/create-2D6S4IMQ.mjs +21 -0
  34. package/dist/lib/neutral/create-2D6S4IMQ.mjs.map +7 -0
  35. package/dist/lib/neutral/hooks/index.mjs +17 -0
  36. package/dist/lib/neutral/index.mjs +44 -0
  37. package/dist/lib/neutral/meta.json +1 -0
  38. package/dist/lib/neutral/meta.mjs +8 -0
  39. package/dist/lib/neutral/meta.mjs.map +7 -0
  40. package/dist/lib/neutral/open-2QB6IIET.mjs +27 -0
  41. package/dist/lib/neutral/open-2QB6IIET.mjs.map +7 -0
  42. package/dist/lib/neutral/operation-handler-NXMOAXFP.mjs +13 -0
  43. package/dist/lib/neutral/operation-handler-NXMOAXFP.mjs.map +7 -0
  44. package/dist/lib/neutral/operations/index.mjs +8 -0
  45. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  46. package/dist/lib/neutral/plugin.mjs +16 -0
  47. package/dist/lib/neutral/plugin.mjs.map +7 -0
  48. package/dist/lib/neutral/react-surface-QF4MUMWG.mjs +26 -0
  49. package/dist/lib/neutral/react-surface-QF4MUMWG.mjs.map +7 -0
  50. package/dist/lib/neutral/summarize-CJPVKWYZ.mjs +78 -0
  51. package/dist/lib/neutral/summarize-CJPVKWYZ.mjs.map +7 -0
  52. package/dist/lib/neutral/text-content-LHSUG2D2.mjs +30 -0
  53. package/dist/lib/neutral/text-content-LHSUG2D2.mjs.map +7 -0
  54. package/dist/lib/{browser/transcriber-OYPLZFG5.mjs → neutral/transcriber-M3R6HPTZ.mjs} +21 -18
  55. package/dist/lib/neutral/transcriber-M3R6HPTZ.mjs.map +7 -0
  56. package/dist/lib/neutral/translations.mjs +22 -0
  57. package/dist/lib/neutral/translations.mjs.map +7 -0
  58. package/dist/lib/neutral/types/index.mjs +12 -0
  59. package/dist/lib/neutral/types/index.mjs.map +7 -0
  60. package/dist/types/src/TranscriptionPlugin.d.ts +3 -1
  61. package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
  62. package/dist/types/src/TranscriptionPlugin.node.d.ts +4 -0
  63. package/dist/types/src/TranscriptionPlugin.node.d.ts.map +1 -0
  64. package/dist/types/src/TranscriptionPlugin.test.d.ts +2 -0
  65. package/dist/types/src/TranscriptionPlugin.test.d.ts.map +1 -0
  66. package/dist/types/src/blueprints/index.d.ts +2 -0
  67. package/dist/types/src/blueprints/index.d.ts.map +1 -0
  68. package/dist/types/src/blueprints/transcription-blueprint.d.ts +4 -0
  69. package/dist/types/src/blueprints/transcription-blueprint.d.ts.map +1 -0
  70. package/dist/types/src/capabilities/blueprint-definition.d.ts +6 -0
  71. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  72. package/dist/types/src/capabilities/index.d.ts +10 -4
  73. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  74. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  75. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  76. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  77. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  78. package/dist/types/src/capabilities/text-content.d.ts +8 -0
  79. package/dist/types/src/capabilities/text-content.d.ts.map +1 -0
  80. package/dist/types/src/capabilities/transcriber.d.ts +4 -3
  81. package/dist/types/src/capabilities/transcriber.d.ts.map +1 -1
  82. package/dist/types/src/components/Transcription/Transcription.d.ts +18 -0
  83. package/dist/types/src/components/Transcription/Transcription.d.ts.map +1 -0
  84. package/dist/types/src/components/Transcription/Transcription.stories.d.ts +40 -0
  85. package/dist/types/src/components/Transcription/Transcription.stories.d.ts.map +1 -0
  86. package/dist/types/src/components/Transcription/index.d.ts +2 -0
  87. package/dist/types/src/components/Transcription/index.d.ts.map +1 -0
  88. package/dist/types/src/components/Transcription/transcription-extension.d.ts +15 -0
  89. package/dist/types/src/components/Transcription/transcription-extension.d.ts.map +1 -0
  90. package/dist/types/src/components/index.d.ts +1 -6
  91. package/dist/types/src/components/index.d.ts.map +1 -1
  92. package/dist/types/src/containers/TranscriptionContainer/TranscriptionContainer.d.ts +6 -0
  93. package/dist/types/src/containers/TranscriptionContainer/TranscriptionContainer.d.ts.map +1 -0
  94. package/dist/types/src/containers/TranscriptionContainer/index.d.ts +2 -0
  95. package/dist/types/src/containers/TranscriptionContainer/index.d.ts.map +1 -0
  96. package/dist/types/src/containers/index.d.ts +3 -0
  97. package/dist/types/src/containers/index.d.ts.map +1 -0
  98. package/dist/types/src/hooks/useAudioFile.d.ts.map +1 -1
  99. package/dist/types/src/hooks/useAudioTrack.d.ts.map +1 -1
  100. package/dist/types/src/hooks/useQueueModelAdapter.d.ts +1 -1
  101. package/dist/types/src/hooks/useQueueModelAdapter.d.ts.map +1 -1
  102. package/dist/types/src/hooks/useTranscriber.d.ts +2 -2
  103. package/dist/types/src/hooks/useTranscriber.d.ts.map +1 -1
  104. package/dist/types/src/hooks/useVoiceInput.d.ts.map +1 -1
  105. package/dist/types/src/index.d.ts +2 -3
  106. package/dist/types/src/index.d.ts.map +1 -1
  107. package/dist/types/src/meta.d.ts +2 -3
  108. package/dist/types/src/meta.d.ts.map +1 -1
  109. package/dist/types/src/model/model.d.ts +2 -2
  110. package/dist/types/src/model/model.d.ts.map +1 -1
  111. package/dist/types/src/{segments-normalization → normalization}/index.d.ts +1 -1
  112. package/dist/types/src/normalization/index.d.ts.map +1 -0
  113. package/dist/types/src/{segments-normalization → normalization}/message-normalizer.d.ts +5 -5
  114. package/dist/types/src/normalization/message-normalizer.d.ts.map +1 -0
  115. package/dist/types/src/normalization/normalization.d.ts +543 -0
  116. package/dist/types/src/normalization/normalization.d.ts.map +1 -0
  117. package/dist/types/src/normalization/normalization.test.d.ts.map +1 -0
  118. package/dist/types/src/normalization/utils.d.ts +3 -0
  119. package/dist/types/src/normalization/utils.d.ts.map +1 -0
  120. package/dist/types/src/operations/create.d.ts +5 -0
  121. package/dist/types/src/operations/create.d.ts.map +1 -0
  122. package/dist/types/src/operations/index.d.ts +3 -0
  123. package/dist/types/src/operations/index.d.ts.map +1 -0
  124. package/dist/types/src/operations/open.d.ts +5 -0
  125. package/dist/types/src/operations/open.d.ts.map +1 -0
  126. package/dist/types/src/operations/summarize.d.ts +8 -0
  127. package/dist/types/src/operations/summarize.d.ts.map +1 -0
  128. package/dist/types/src/plugin.d.ts +4 -0
  129. package/dist/types/src/plugin.d.ts.map +1 -0
  130. package/dist/types/src/stories/FileTranscription.stories.d.ts +18 -0
  131. package/dist/types/src/stories/FileTranscription.stories.d.ts.map +1 -0
  132. package/dist/types/src/stories/KeyWordRecognition.stories.d.ts +14 -0
  133. package/dist/types/src/stories/KeyWordRecognition.stories.d.ts.map +1 -0
  134. package/dist/types/src/stories/MicrophoneTranscription.stories.d.ts +20 -0
  135. package/dist/types/src/stories/MicrophoneTranscription.stories.d.ts.map +1 -0
  136. package/dist/types/src/stories/TranscriptionStory.d.ts +23 -0
  137. package/dist/types/src/stories/TranscriptionStory.d.ts.map +1 -0
  138. package/dist/types/src/stories/useIsSpeaking.d.ts.map +1 -0
  139. package/dist/types/src/testing/testing.d.ts +10 -10
  140. package/dist/types/src/testing/testing.d.ts.map +1 -1
  141. package/dist/types/src/transcriber/media-stream-recorder.d.ts +3 -3
  142. package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
  143. package/dist/types/src/transcriber/transcriber.d.ts +60 -5
  144. package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
  145. package/dist/types/src/transcriber/transcriber.test.d.ts +2 -0
  146. package/dist/types/src/transcriber/transcriber.test.d.ts.map +1 -0
  147. package/dist/types/src/transcriber/transcription-manager.d.ts +12 -13
  148. package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
  149. package/dist/types/src/translations.d.ts +10 -11
  150. package/dist/types/src/translations.d.ts.map +1 -1
  151. package/dist/types/src/types/TranscriptOperation.d.ts +917 -0
  152. package/dist/types/src/types/TranscriptOperation.d.ts.map +1 -0
  153. package/dist/types/src/types/TranscriptionCapabilities.d.ts +17 -0
  154. package/dist/types/src/types/TranscriptionCapabilities.d.ts.map +1 -0
  155. package/dist/types/src/types/defs.d.ts +5 -0
  156. package/dist/types/src/types/defs.d.ts.map +1 -0
  157. package/dist/types/src/types/index.d.ts +3 -2
  158. package/dist/types/src/types/index.d.ts.map +1 -1
  159. package/dist/types/src/util/array.d.ts.map +1 -1
  160. package/dist/types/src/util/get-time-str.d.ts.map +1 -1
  161. package/dist/types/src/util/index.d.ts +1 -0
  162. package/dist/types/src/util/index.d.ts.map +1 -1
  163. package/dist/types/src/util/monitor-audio-level.d.ts.map +1 -1
  164. package/dist/types/src/util/render-byline.d.ts +4 -0
  165. package/dist/types/src/util/render-byline.d.ts.map +1 -0
  166. package/dist/types/tsconfig.tsbuildinfo +1 -1
  167. package/package.json +152 -84
  168. package/src/TranscriptionPlugin.node.ts +20 -0
  169. package/src/TranscriptionPlugin.test.ts +31 -0
  170. package/src/TranscriptionPlugin.tsx +22 -61
  171. package/src/blueprints/index.ts +5 -0
  172. package/src/blueprints/transcription-blueprint.ts +29 -0
  173. package/src/capabilities/blueprint-definition.ts +19 -0
  174. package/src/capabilities/index.ts +11 -6
  175. package/src/capabilities/operation-handler.ts +16 -0
  176. package/src/capabilities/react-surface.tsx +23 -14
  177. package/src/capabilities/text-content.ts +33 -0
  178. package/src/capabilities/transcriber.ts +53 -41
  179. package/src/components/{Transcript/Transcript.stories.tsx → Transcription/Transcription.stories.tsx} +80 -75
  180. package/src/components/Transcription/Transcription.tsx +64 -0
  181. package/src/components/{Transcript → Transcription}/index.ts +1 -1
  182. package/src/components/{Transcript/transcript-extension.ts → Transcription/transcription-extension.ts} +15 -48
  183. package/src/components/index.ts +1 -6
  184. package/src/containers/TranscriptionContainer/TranscriptionContainer.tsx +35 -0
  185. package/src/containers/TranscriptionContainer/index.ts +5 -0
  186. package/src/containers/index.ts +7 -0
  187. package/src/hooks/useAudioFile.ts +49 -53
  188. package/src/hooks/useQueueModelAdapter.ts +1 -1
  189. package/src/hooks/useTranscriber.ts +15 -7
  190. package/src/hooks/useVoiceInput.ts +3 -3
  191. package/src/index.ts +4 -5
  192. package/src/meta.ts +9 -6
  193. package/src/model/model.test.ts +27 -21
  194. package/src/model/model.ts +3 -3
  195. package/src/{segments-normalization → normalization}/message-normalizer.ts +20 -19
  196. package/src/{segments-normalization → normalization}/normalization.test.ts +26 -33
  197. package/src/normalization/normalization.ts +76 -0
  198. package/src/{segments-normalization → normalization}/utils.ts +2 -2
  199. package/src/operations/create.ts +24 -0
  200. package/src/operations/index.ts +11 -0
  201. package/src/operations/open.ts +28 -0
  202. package/src/operations/summarize.ts +101 -0
  203. package/src/plugin.ts +11 -0
  204. package/src/stories/FileTranscription.stories.tsx +269 -0
  205. package/src/{components/stories → stories}/KeyWordRecognition.stories.tsx +46 -40
  206. package/src/stories/MicrophoneTranscription.stories.tsx +264 -0
  207. package/src/stories/TranscriptionStory.tsx +93 -0
  208. package/src/testing/testing.ts +41 -41
  209. package/src/transcriber/media-stream-recorder.ts +4 -4
  210. package/src/transcriber/transcriber.browser.test.ts +5 -5
  211. package/src/transcriber/transcriber.test.ts +104 -0
  212. package/src/transcriber/transcriber.ts +101 -62
  213. package/src/transcriber/transcription-manager.ts +37 -52
  214. package/src/translations.ts +12 -10
  215. package/src/types/TranscriptOperation.ts +103 -0
  216. package/src/types/TranscriptionCapabilities.ts +39 -0
  217. package/src/types/defs.ts +9 -0
  218. package/src/types/index.ts +4 -2
  219. package/src/util/index.ts +1 -0
  220. package/src/util/render-byline.ts +33 -0
  221. package/dist/lib/browser/TranscriptContainer-H3AZQ4CQ.mjs +0 -11
  222. package/dist/lib/browser/chunk-53AXUEIQ.mjs +0 -764
  223. package/dist/lib/browser/chunk-53AXUEIQ.mjs.map +0 -7
  224. package/dist/lib/browser/chunk-GOF7MJNV.mjs +0 -19
  225. package/dist/lib/browser/chunk-GOF7MJNV.mjs.map +0 -7
  226. package/dist/lib/browser/chunk-IQ5ZRMHZ.mjs.map +0 -7
  227. package/dist/lib/browser/chunk-OSISJM2F.mjs +0 -55
  228. package/dist/lib/browser/chunk-OSISJM2F.mjs.map +0 -7
  229. package/dist/lib/browser/chunk-UDCCT32F.mjs +0 -8
  230. package/dist/lib/browser/chunk-UDCCT32F.mjs.map +0 -7
  231. package/dist/lib/browser/chunk-W2KNYJD6.mjs +0 -16
  232. package/dist/lib/browser/chunk-W2KNYJD6.mjs.map +0 -7
  233. package/dist/lib/browser/index.mjs +0 -125
  234. package/dist/lib/browser/index.mjs.map +0 -7
  235. package/dist/lib/browser/intent-resolver-BGADCHVM.mjs +0 -30
  236. package/dist/lib/browser/intent-resolver-BGADCHVM.mjs.map +0 -7
  237. package/dist/lib/browser/meta.json +0 -1
  238. package/dist/lib/browser/react-surface-HMJS5FSS.mjs +0 -34
  239. package/dist/lib/browser/react-surface-HMJS5FSS.mjs.map +0 -7
  240. package/dist/lib/browser/transcriber-OYPLZFG5.mjs.map +0 -7
  241. package/dist/lib/browser/types/index.mjs +0 -14
  242. package/dist/lib/node/TranscriptContainer-KIG3GMAB.cjs +0 -32
  243. package/dist/lib/node/TranscriptContainer-KIG3GMAB.cjs.map +0 -7
  244. package/dist/lib/node/chunk-3PYT3BDM.cjs +0 -40
  245. package/dist/lib/node/chunk-3PYT3BDM.cjs.map +0 -7
  246. package/dist/lib/node/chunk-6LW5RA3K.cjs +0 -75
  247. package/dist/lib/node/chunk-6LW5RA3K.cjs.map +0 -7
  248. package/dist/lib/node/chunk-AFUZI63A.cjs +0 -42
  249. package/dist/lib/node/chunk-AFUZI63A.cjs.map +0 -7
  250. package/dist/lib/node/chunk-CVUN3UO7.cjs +0 -778
  251. package/dist/lib/node/chunk-CVUN3UO7.cjs.map +0 -7
  252. package/dist/lib/node/chunk-FKDJNJ57.cjs +0 -35
  253. package/dist/lib/node/chunk-FKDJNJ57.cjs.map +0 -7
  254. package/dist/lib/node/chunk-ZFAUMZXE.cjs +0 -518
  255. package/dist/lib/node/chunk-ZFAUMZXE.cjs.map +0 -7
  256. package/dist/lib/node/index.cjs +0 -133
  257. package/dist/lib/node/index.cjs.map +0 -7
  258. package/dist/lib/node/intent-resolver-LL3TTI4H.cjs +0 -45
  259. package/dist/lib/node/intent-resolver-LL3TTI4H.cjs.map +0 -7
  260. package/dist/lib/node/meta.json +0 -1
  261. package/dist/lib/node/react-surface-N25TBBG4.cjs +0 -56
  262. package/dist/lib/node/react-surface-N25TBBG4.cjs.map +0 -7
  263. package/dist/lib/node/transcriber-6J4FVFSZ.cjs +0 -68
  264. package/dist/lib/node/transcriber-6J4FVFSZ.cjs.map +0 -7
  265. package/dist/lib/node/types/index.cjs +0 -36
  266. package/dist/lib/node/types/index.cjs.map +0 -7
  267. package/dist/lib/node-esm/TranscriptContainer-G75LDEO5.mjs +0 -12
  268. package/dist/lib/node-esm/chunk-56QHOX4A.mjs +0 -765
  269. package/dist/lib/node-esm/chunk-56QHOX4A.mjs.map +0 -7
  270. package/dist/lib/node-esm/chunk-FH75X4JC.mjs +0 -56
  271. package/dist/lib/node-esm/chunk-FH75X4JC.mjs.map +0 -7
  272. package/dist/lib/node-esm/chunk-MFJO7EKD.mjs +0 -10
  273. package/dist/lib/node-esm/chunk-MFJO7EKD.mjs.map +0 -7
  274. package/dist/lib/node-esm/chunk-MFJPEIVB.mjs +0 -17
  275. package/dist/lib/node-esm/chunk-MFJPEIVB.mjs.map +0 -7
  276. package/dist/lib/node-esm/chunk-PRL64SRU.mjs +0 -496
  277. package/dist/lib/node-esm/chunk-PRL64SRU.mjs.map +0 -7
  278. package/dist/lib/node-esm/chunk-TXMDLLBR.mjs +0 -21
  279. package/dist/lib/node-esm/chunk-TXMDLLBR.mjs.map +0 -7
  280. package/dist/lib/node-esm/index.mjs +0 -126
  281. package/dist/lib/node-esm/index.mjs.map +0 -7
  282. package/dist/lib/node-esm/intent-resolver-5LVCYSJS.mjs +0 -31
  283. package/dist/lib/node-esm/intent-resolver-5LVCYSJS.mjs.map +0 -7
  284. package/dist/lib/node-esm/meta.json +0 -1
  285. package/dist/lib/node-esm/react-surface-JGQSYGRR.mjs +0 -35
  286. package/dist/lib/node-esm/react-surface-JGQSYGRR.mjs.map +0 -7
  287. package/dist/lib/node-esm/transcriber-TVG2MBBN.mjs +0 -57
  288. package/dist/lib/node-esm/transcriber-TVG2MBBN.mjs.map +0 -7
  289. package/dist/lib/node-esm/types/index.mjs +0 -15
  290. package/dist/types/src/capabilities/capabilities.d.ts +0 -17
  291. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  292. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  293. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  294. package/dist/types/src/components/Transcript/Transcript.d.ts +0 -20
  295. package/dist/types/src/components/Transcript/Transcript.d.ts.map +0 -1
  296. package/dist/types/src/components/Transcript/Transcript.stories.d.ts +0 -24
  297. package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +0 -1
  298. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +0 -28
  299. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +0 -1
  300. package/dist/types/src/components/Transcript/index.d.ts +0 -2
  301. package/dist/types/src/components/Transcript/index.d.ts.map +0 -1
  302. package/dist/types/src/components/Transcript/transcript-extension.d.ts +0 -19
  303. package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +0 -1
  304. package/dist/types/src/components/TranscriptContainer.d.ts +0 -8
  305. package/dist/types/src/components/TranscriptContainer.d.ts.map +0 -1
  306. package/dist/types/src/components/stories/FileTranscription.stories.d.ts +0 -17
  307. package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +0 -1
  308. package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts +0 -10
  309. package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +0 -1
  310. package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts +0 -19
  311. package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +0 -1
  312. package/dist/types/src/components/stories/TranscriptionStory.d.ts +0 -11
  313. package/dist/types/src/components/stories/TranscriptionStory.d.ts.map +0 -1
  314. package/dist/types/src/components/stories/useIsSpeaking.d.ts.map +0 -1
  315. package/dist/types/src/segments-normalization/index.d.ts.map +0 -1
  316. package/dist/types/src/segments-normalization/message-normalizer.d.ts.map +0 -1
  317. package/dist/types/src/segments-normalization/normalization.d.ts +0 -329
  318. package/dist/types/src/segments-normalization/normalization.d.ts.map +0 -1
  319. package/dist/types/src/segments-normalization/normalization.test.d.ts.map +0 -1
  320. package/dist/types/src/segments-normalization/utils.d.ts +0 -3
  321. package/dist/types/src/segments-normalization/utils.d.ts.map +0 -1
  322. package/dist/types/src/types/schema.d.ts +0 -41
  323. package/dist/types/src/types/schema.d.ts.map +0 -1
  324. package/dist/types/src/types/types.d.ts +0 -31
  325. package/dist/types/src/types/types.d.ts.map +0 -1
  326. package/src/capabilities/capabilities.ts +0 -33
  327. package/src/capabilities/intent-resolver.ts +0 -24
  328. package/src/components/Transcript/Transcript.tsx +0 -100
  329. package/src/components/Transcript/deprecated/OldTranscript.tsx +0 -260
  330. package/src/components/TranscriptContainer.tsx +0 -30
  331. package/src/components/stories/FileTranscription.stories.tsx +0 -242
  332. package/src/components/stories/MicrophoneTranscription.stories.tsx +0 -280
  333. package/src/components/stories/TranscriptionStory.tsx +0 -41
  334. package/src/segments-normalization/normalization.ts +0 -105
  335. package/src/types/schema.ts +0 -41
  336. package/src/types/types.ts +0 -32
  337. package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
  338. package/dist/lib/{browser/TranscriptContainer-H3AZQ4CQ.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  339. package/dist/lib/{node-esm/types → neutral/hooks}/index.mjs.map +0 -0
  340. package/dist/lib/{node-esm/TranscriptContainer-G75LDEO5.mjs.map → neutral/index.mjs.map} +0 -0
  341. package/dist/types/src/{segments-normalization → normalization}/normalization.test.d.ts +0 -0
  342. package/dist/types/src/{components/stories → stories}/useIsSpeaking.d.ts +0 -0
  343. package/src/{segments-normalization → normalization}/index.ts +1 -1
  344. /package/src/{components/stories → stories}/useIsSpeaking.tsx +0 -0
@@ -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.lastUsedTimestamp).toBeUndefined();
35
+ });
36
+
37
+ test('absolute-timestamps and deduplicates segments against lastUsedTimestamp', ({ 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.lastUsedTimestamp).toBe(T0 + 1_000);
56
+
57
+ // Same segments, same chunk start: every word's absolute start is < lastUsedTimestamp -> filtered out.
58
+ const second = alignWhisperSegments(segments, [chunk(0)], first.lastUsedTimestamp!);
59
+ expect(second.transcripts).toEqual([]);
60
+ expect(second.lastUsedTimestamp).toBeUndefined();
61
+ });
62
+
63
+ test('keeps later words when earlier words fall before lastUsedTimestamp', ({ 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.lastUsedTimestamp).toBe(T0 + 2_000);
82
+ });
83
+
84
+ test('drops segments that end before lastUsedTimestamp', ({ 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
+ });
@@ -7,14 +7,15 @@ import { WaveFile } from 'wavefile';
7
7
  import { DeferredTask, Trigger } from '@dxos/async';
8
8
  import { type Context, LifecycleState, Resource } from '@dxos/context';
9
9
  import { log } from '@dxos/log';
10
- import { type DataType } from '@dxos/schema';
11
10
  import { trace } from '@dxos/tracing';
11
+ import { type ContentBlock } from '@dxos/types';
12
+
13
+ import { TRANSCRIPTION_URL } from '#types';
12
14
 
13
- import { type AudioRecorder, type AudioChunk } from './audio-recorder';
14
- import { TRANSCRIPTION_URL } from '../types';
15
15
  import { mergeFloat64Arrays } from '../util';
16
+ import { type AudioChunk, type AudioRecorder } from './audio-recorder';
16
17
 
17
- type WhisperWord = {
18
+ export type WhisperWord = {
18
19
  word: string;
19
20
 
20
21
  /**
@@ -28,7 +29,7 @@ type WhisperWord = {
28
29
  end: number;
29
30
  };
30
31
 
31
- type WhisperSegment = {
32
+ export type WhisperSegment = {
32
33
  text: string;
33
34
 
34
35
  /**
@@ -60,16 +61,32 @@ export type TranscribeConfig = {
60
61
  * This is needed to catch the beginning of the user's speech.
61
62
  */
62
63
  prefixBufferChunksAmount: number;
64
+
65
+ /**
66
+ * Override the transcription endpoint base URL.
67
+ * Defaults to the DXOS calls service.
68
+ */
69
+ endpoint?: string;
63
70
  };
64
71
 
65
- export type TranscriberParams = {
72
+ /**
73
+ * Function that converts a base64-encoded WAV payload into Whisper segments.
74
+ * Allows callers to swap in alternative providers or mock the transport.
75
+ */
76
+ export type TranscribeFn = (audio: string) => Promise<WhisperSegment[]>;
77
+
78
+ export type TranscriberProps = {
66
79
  config: TranscribeConfig;
67
80
  recorder: AudioRecorder;
68
81
  /**
69
82
  * Callback to handle the transcribed segments, after all segment transformers are applied.
70
83
  * @param segments - The transcribed segments.
71
84
  */
72
- onSegments: (segments: DataType.MessageBlock.Transcription[]) => Promise<void>;
85
+ onSegments: (segments: ContentBlock.Transcript[]) => Promise<void>;
86
+ /**
87
+ * Optional override of the transcription transport. When provided, supersedes `config.endpoint`.
88
+ */
89
+ transcribe?: TranscribeFn;
73
90
  };
74
91
 
75
92
  /**
@@ -85,16 +102,18 @@ export class Transcriber extends Resource {
85
102
 
86
103
  private readonly _config: TranscribeConfig;
87
104
  private readonly _recorder: AudioRecorder;
88
- private readonly _onSegments: TranscriberParams['onSegments'];
105
+ private readonly _onSegments: TranscriberProps['onSegments'];
106
+ private readonly _transcribeFn?: TranscribeFn;
89
107
 
90
108
  private _recording = false;
91
109
  private _transcribeTask?: DeferredTask = undefined;
92
110
 
93
- constructor({ config, recorder, onSegments }: TranscriberParams) {
111
+ constructor({ config, recorder, onSegments, transcribe }: TranscriberProps) {
94
112
  super();
95
113
  this._config = config;
96
114
  this._recorder = recorder;
97
115
  this._onSegments = onSegments;
116
+ this._transcribeFn = transcribe;
98
117
  }
99
118
 
100
119
  protected override async _open(ctx: Context): Promise<void> {
@@ -191,70 +210,90 @@ export class Transcriber extends Resource {
191
210
  @trace.span({ showInBrowserTimeline: true })
192
211
  private async _fetchTranscription(audio: string): Promise<WhisperSegment[]> {
193
212
  if (audio.length === 0) {
194
- this._audioChunks = [];
195
213
  throw new Error('No audio to send for transcribing');
196
214
  }
197
215
 
198
- const response = await fetch(`${TRANSCRIPTION_URL}/transcribe`, {
199
- method: 'POST',
200
- body: JSON.stringify({ audio }),
201
- headers: {
202
- 'Content-Type': 'application/json',
203
- },
204
- });
205
-
206
- if (!response.ok) {
207
- this._audioChunks = [];
208
- throw new Error(`Transcription failed: ${response.statusText}`);
216
+ let segments: unknown;
217
+ if (this._transcribeFn) {
218
+ segments = await this._transcribeFn(audio);
219
+ } else {
220
+ const endpoint = this._config.endpoint ?? TRANSCRIPTION_URL;
221
+ const response = await fetch(`${endpoint}/transcribe`, {
222
+ method: 'POST',
223
+ body: JSON.stringify({ audio }),
224
+ headers: {
225
+ 'Content-Type': 'application/json',
226
+ },
227
+ });
228
+
229
+ if (!response.ok) {
230
+ throw new Error(`Transcription failed: ${response.statusText}`);
231
+ }
232
+
233
+ ({ segments } = (await response.json()) as { segments?: unknown });
209
234
  }
210
235
 
211
- const { segments } = (await response.json()) as {
212
- segments: WhisperSegment[];
213
- };
236
+ if (!Array.isArray(segments)) {
237
+ throw new Error('Transcription response payload is invalid');
238
+ }
214
239
 
215
- log.info('transcription response', {
216
- segments: segments.length,
217
- string: segments.map((segments) => segments.text).join(' '),
218
- });
240
+ log.info('transcription response', { segments: segments.length });
219
241
 
220
- return segments;
242
+ return segments as WhisperSegment[];
221
243
  }
222
244
 
223
- private _alignSegments(
224
- segments: WhisperSegment[],
225
- originalChunks: AudioChunk[],
226
- ): DataType.MessageBlock.Transcription[] {
227
- // Absolute zero for all relative timestamps in the segments.
228
- const zeroTimestamp = originalChunks.at(0)!.timestamp;
229
-
230
- const filteredSegments = segments
231
- // Use segments that end after the last used timestamp.
232
- // Segments could overlap, so we need to filter words that starts after the last used timestamp.
233
- .filter((segment) => zeroTimestamp + segment.end * 1_000 >= this._lastUsedTimestamp)
234
- // Use words that starts after the last used timestamp.
235
- .map((segment) => {
236
- const words = segment.words.filter((word) => zeroTimestamp + word.start * 1_000 >= this._lastUsedTimestamp);
237
- return {
238
- ...segment,
239
- words,
240
- text: words.map((word) => word.word).join(''),
241
- start: words.at(0)?.start ?? segment.end,
242
- };
243
- })
244
- .filter((segment) => segment.words.length > 0);
245
-
246
- if (filteredSegments.length === 0) {
247
- return [];
245
+ private _alignSegments(segments: WhisperSegment[], originalChunks: AudioChunk[]): ContentBlock.Transcript[] {
246
+ const result = alignWhisperSegments(segments, originalChunks, this._lastUsedTimestamp);
247
+ if (result.lastUsedTimestamp !== undefined) {
248
+ this._lastUsedTimestamp = result.lastUsedTimestamp;
248
249
  }
250
+ return result.transcripts;
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Pure helper that filters and absolute-timestamps Whisper segments against a chunk timeline.
256
+ * Exported for testing.
257
+ *
258
+ * @param segments - Raw segments returned by the Whisper service for `originalChunks`.
259
+ * @param originalChunks - Chunks fed into the transcription request (used for the zero timestamp).
260
+ * @param lastUsedTimestamp - Most recent absolute timestamp already emitted; segments whose end
261
+ * falls strictly before this point are deduped out, as are individual words whose start does.
262
+ */
263
+ export const alignWhisperSegments = (
264
+ segments: WhisperSegment[],
265
+ originalChunks: AudioChunk[],
266
+ lastUsedTimestamp: number,
267
+ ): { transcripts: ContentBlock.Transcript[]; lastUsedTimestamp?: number } => {
268
+ if (originalChunks.length === 0) {
269
+ return { transcripts: [] };
270
+ }
249
271
 
250
- // Update last timestamp.
251
- this._lastUsedTimestamp = zeroTimestamp + filteredSegments.at(-1)!.end * 1_000;
272
+ const zeroTimestamp = originalChunks[0].timestamp;
273
+
274
+ const filteredSegments = segments
275
+ .filter((segment) => zeroTimestamp + segment.end * 1_000 >= lastUsedTimestamp)
276
+ .map((segment) => {
277
+ const words = segment.words.filter((word) => zeroTimestamp + word.start * 1_000 >= lastUsedTimestamp);
278
+ return {
279
+ ...segment,
280
+ words,
281
+ text: words.map((word) => word.word).join(''),
282
+ start: words.at(0)?.start ?? segment.end,
283
+ };
284
+ })
285
+ .filter((segment) => segment.words.length > 0);
286
+
287
+ if (filteredSegments.length === 0) {
288
+ return { transcripts: [] };
289
+ }
252
290
 
253
- // Add absolute timestamp to each segment.
254
- return filteredSegments.map((segment) => ({
255
- type: 'transcription',
291
+ return {
292
+ transcripts: filteredSegments.map((segment) => ({
293
+ _tag: 'transcript',
256
294
  started: new Date(zeroTimestamp + segment.start * 1_000).toISOString(),
257
295
  text: segment.text.trim(),
258
- }));
259
- }
260
- }
296
+ })),
297
+ lastUsedTimestamp: zeroTimestamp + filteredSegments.at(-1)!.end * 1_000,
298
+ };
299
+ };
@@ -2,14 +2,14 @@
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
6
 
7
7
  import { synchronized } from '@dxos/async';
8
8
  import { Resource } from '@dxos/context';
9
9
  import { Obj } from '@dxos/echo';
10
10
  import { type Queue } from '@dxos/echo-db';
11
11
  import { type EdgeHttpClient } from '@dxos/react-edge-client';
12
- import { DataType } from '@dxos/schema';
12
+ import { type ContentBlock, Message } from '@dxos/types';
13
13
 
14
14
  import { MediaStreamRecorder } from './media-stream-recorder';
15
15
  import { Transcriber } from './transcriber';
@@ -30,10 +30,11 @@ const PREFIXED_CHUNKS_AMOUNT = 10;
30
30
  */
31
31
  const TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;
32
32
 
33
- export type TranscriptMessageEnricher = (message: DataType.Message) => Promise<DataType.Message>;
33
+ export type TranscriptMessageEnricher = (message: Message.Message) => Promise<Message.Message>;
34
34
 
35
35
  export type TranscriptionManagerOptions = {
36
36
  edgeClient: EdgeHttpClient;
37
+ registry: Registry.Registry;
37
38
 
38
39
  /**
39
40
  * Enrich the message before it is written to the transcription queue.
@@ -47,25 +48,30 @@ export type TranscriptionManagerOptions = {
47
48
  export class TranscriptionManager extends Resource {
48
49
  private readonly _edgeClient: EdgeHttpClient;
49
50
  private readonly _messageEnricher?: TranscriptMessageEnricher;
51
+ private readonly _registry: Registry.Registry;
50
52
  private _audioStreamTrack?: MediaStreamTrack = undefined;
51
53
  private _identityDid?: string = undefined;
52
54
  private _mediaRecorder?: MediaStreamRecorder = undefined;
53
55
  private _transcriber?: Transcriber = undefined;
54
- private _queue?: Queue<DataType.Message> = undefined;
55
- private _enabled = signal(false);
56
+ private _queue?: Queue<Message.Message> = undefined;
57
+ private _enabledAtom = Atom.make(false);
56
58
 
57
59
  constructor(options: TranscriptionManagerOptions) {
58
60
  super();
59
61
  this._edgeClient = options.edgeClient;
60
62
  this._messageEnricher = options.messageEnricher;
63
+ this._registry = options.registry;
61
64
  }
62
65
 
63
- /** @reactive */
64
- get enabled() {
65
- return this._enabled.value;
66
+ get enabled(): Atom.Atom<boolean> {
67
+ return this._enabledAtom;
66
68
  }
67
69
 
68
- setQueue(queue: Queue<DataType.Message>): this {
70
+ getEnabled(): boolean {
71
+ return this._registry.get(this._enabledAtom);
72
+ }
73
+
74
+ setQueue(queue: Queue<Message.Message>): this {
69
75
  this._queue = queue;
70
76
  return this;
71
77
  }
@@ -78,7 +84,7 @@ export class TranscriptionManager extends Resource {
78
84
  }
79
85
 
80
86
  setRecording(recording?: boolean): this {
81
- if (!this.isOpen || !this._enabled.value) {
87
+ if (!this.isOpen || !this.getEnabled()) {
82
88
  return this;
83
89
  }
84
90
 
@@ -90,19 +96,17 @@ export class TranscriptionManager extends Resource {
90
96
  return this;
91
97
  }
92
98
 
93
- /**
94
- * Enable or disable transcription.
95
- * @param enabled - Whether to enable transcription.
96
- */
97
- @synchronized
98
- async setEnabled(enabled?: boolean): Promise<void> {
99
- if (this._enabled.value === enabled) {
99
+ async setEnabled(enabled: boolean): Promise<void> {
100
+ if (this.getEnabled() === enabled) {
100
101
  return;
101
102
  }
102
103
 
103
- this._enabled.value = enabled ?? false;
104
- // TODO(burdon): Why is toggle called here?
105
- this.isOpen && (await this._toggleTranscriber());
104
+ this._registry.set(this._enabledAtom, enabled ?? false);
105
+ if (enabled) {
106
+ await this._maybeRestartTranscriber();
107
+ } else {
108
+ await this._stopTranscriber();
109
+ }
106
110
  }
107
111
 
108
112
  @synchronized
@@ -112,44 +116,19 @@ export class TranscriptionManager extends Resource {
112
116
  }
113
117
 
114
118
  this._audioStreamTrack = track;
115
- this.isOpen && (await this._toggleTranscriber());
119
+ await this._maybeRestartTranscriber();
116
120
  }
117
121
 
118
122
  protected override async _open(): Promise<void> {
119
- await this._toggleTranscriber();
123
+ await this._maybeRestartTranscriber();
120
124
  }
121
125
 
122
126
  protected override async _close(): Promise<void> {
123
- void this._transcriber?.close();
124
- }
125
-
126
- // TODO(burdon): Change this to setEnables (explicit), not toggle.
127
- private async _toggleTranscriber(): Promise<void> {
128
- await this._maybeReinitTranscriber();
129
-
130
- // Open or close transcriber if transcription is enabled or disabled.
131
- if (this._enabled.value) {
132
- await this._transcriber?.open();
133
- // TODO(burdon): Started and stopped blocks appear twice.
134
- const block = Obj.make(DataType.Message, {
135
- created: new Date().toISOString(),
136
- blocks: [{ type: 'transcription', text: 'Started', started: new Date().toISOString() }],
137
- sender: { role: 'assistant' },
138
- });
139
- await this._queue?.append([block]);
140
- } else {
141
- await this._transcriber?.close();
142
- const block = Obj.make(DataType.Message, {
143
- created: new Date().toISOString(),
144
- blocks: [{ type: 'transcription', text: 'Stopped', started: new Date().toISOString() }],
145
- sender: { role: 'assistant' },
146
- });
147
- await this._queue?.append([block]);
148
- }
127
+ await this._stopTranscriber();
149
128
  }
150
129
 
151
- private async _maybeReinitTranscriber(): Promise<void> {
152
- if (!this._audioStreamTrack || !this._enabled.value) {
130
+ private async _maybeRestartTranscriber(): Promise<void> {
131
+ if (!this._audioStreamTrack || !this.getEnabled() || !this.isOpen) {
153
132
  return;
154
133
  }
155
134
 
@@ -172,15 +151,21 @@ export class TranscriptionManager extends Resource {
172
151
  recorder: this._mediaRecorder,
173
152
  onSegments: (segments) => this._onSegments(segments),
174
153
  });
154
+
155
+ await this._transcriber?.open();
175
156
  }
176
157
  }
177
158
 
178
- private async _onSegments(segments: DataType.MessageBlock.Transcription[]): Promise<void> {
159
+ private async _stopTranscriber(): Promise<void> {
160
+ await this._transcriber?.close();
161
+ }
162
+
163
+ private async _onSegments(segments: ContentBlock.Transcript[]): Promise<void> {
179
164
  if (!this.isOpen || !this._queue) {
180
165
  return;
181
166
  }
182
167
 
183
- let block = Obj.make(DataType.Message, {
168
+ let block = Obj.make(Message.Message, {
184
169
  created: new Date().toISOString(),
185
170
  blocks: segments,
186
171
  sender: { identityDid: this._identityDid },
@@ -2,21 +2,23 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { TRANSCRIPTION_PLUGIN } from './meta';
5
+ import { type Resource } from '@dxos/react-ui';
6
6
 
7
- export default [
7
+ import { meta } from '#meta';
8
+
9
+ export const translations = [
8
10
  {
9
11
  'en-US': {
10
- [TRANSCRIPTION_PLUGIN]: {
11
- 'plugin name': 'Transcription',
12
- 'transcript companion label': 'Transcript',
12
+ [meta.id]: {
13
+ 'plugin.name': 'Transcription',
14
+ 'transcript-companion.label': 'Transcript',
13
15
 
14
- 'delete button': 'Delete',
15
- 'bookmark button': 'Bookmark',
16
- 'scroll to end label': 'Scroll to latest',
16
+ 'delete.button': 'Delete',
17
+ 'bookmark.button': 'Bookmark',
18
+ 'scroll-to-end.label': 'Scroll to latest',
17
19
 
18
- 'settings entity extraction label': 'Entity extraction',
20
+ 'settings.entity-extraction.label': 'Entity extraction',
19
21
  },
20
22
  },
21
23
  },
22
- ];
24
+ ] as const satisfies Resource[];
@@ -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
+ );