@dxos/plugin-transcription 0.8.2-staging.7ac8446 → 0.8.2

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 (258) hide show
  1. package/dist/lib/browser/TranscriptContainer-PFKLKRPQ.mjs +11 -0
  2. package/dist/lib/browser/{chunk-YCZISX63.mjs → chunk-4KCUYW2F.mjs} +139 -95
  3. package/dist/lib/browser/chunk-4KCUYW2F.mjs.map +7 -0
  4. package/dist/lib/browser/{chunk-6ZR5MDK3.mjs → chunk-GOF7MJNV.mjs} +3 -3
  5. package/dist/lib/browser/{chunk-6ZR5MDK3.mjs.map → chunk-GOF7MJNV.mjs.map} +1 -1
  6. package/dist/lib/browser/{chunk-K7FOYAXO.mjs → chunk-IGEKO7ZU.mjs} +2 -2
  7. package/dist/lib/browser/chunk-NODIXNQP.mjs +54 -0
  8. package/dist/lib/browser/chunk-NODIXNQP.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-TJPJBE45.mjs +764 -0
  10. package/dist/lib/browser/chunk-TJPJBE45.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-YEPT334A.mjs → chunk-W2KNYJD6.mjs} +4 -4
  12. package/dist/lib/browser/chunk-W2KNYJD6.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +30 -216
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/{intent-resolver-4R66ZCKT.mjs → intent-resolver-I2LJSQDR.mjs} +7 -11
  16. package/dist/lib/browser/intent-resolver-I2LJSQDR.mjs.map +7 -0
  17. package/dist/lib/browser/meta.json +1 -1
  18. package/dist/lib/browser/{react-surface-FQUHU5G7.mjs → react-surface-ID2MLJHZ.mjs} +11 -9
  19. package/dist/lib/browser/react-surface-ID2MLJHZ.mjs.map +7 -0
  20. package/dist/lib/browser/transcriber-NA7CIFIT.mjs +56 -0
  21. package/dist/lib/browser/transcriber-NA7CIFIT.mjs.map +7 -0
  22. package/dist/lib/browser/types/index.mjs +4 -8
  23. package/dist/lib/node/{TranscriptContainer-QEYTTT2V.cjs → TranscriptContainer-LHMC7553.cjs} +9 -8
  24. package/dist/lib/node/TranscriptContainer-LHMC7553.cjs.map +7 -0
  25. package/dist/lib/node/chunk-3GS5UNO5.cjs +778 -0
  26. package/dist/lib/node/chunk-3GS5UNO5.cjs.map +7 -0
  27. package/dist/lib/node/{chunk-LP4FG423.cjs → chunk-5J3FBCON.cjs} +5 -5
  28. package/dist/lib/node/{chunk-NVZWGFJL.cjs → chunk-AFUZI63A.cjs} +6 -6
  29. package/dist/lib/node/{chunk-NVZWGFJL.cjs.map → chunk-AFUZI63A.cjs.map} +1 -1
  30. package/dist/lib/node/chunk-EIMUQYCZ.cjs +74 -0
  31. package/dist/lib/node/chunk-EIMUQYCZ.cjs.map +7 -0
  32. package/dist/lib/node/{chunk-CZMLKKWT.cjs → chunk-FKDJNJ57.cjs} +8 -8
  33. package/dist/lib/node/chunk-FKDJNJ57.cjs.map +7 -0
  34. package/dist/lib/node/{chunk-FCCJALOT.cjs → chunk-ZFTXJZXH.cjs} +138 -95
  35. package/dist/lib/node/chunk-ZFTXJZXH.cjs.map +7 -0
  36. package/dist/lib/node/index.cjs +59 -251
  37. package/dist/lib/node/index.cjs.map +4 -4
  38. package/dist/lib/node/{intent-resolver-WMMCOUEH.cjs → intent-resolver-LLMGF5I5.cjs} +10 -11
  39. package/dist/lib/node/intent-resolver-LLMGF5I5.cjs.map +7 -0
  40. package/dist/lib/node/meta.json +1 -1
  41. package/dist/lib/node/{react-surface-WI2MGWCC.cjs → react-surface-SEQLEL4K.cjs} +13 -11
  42. package/dist/lib/node/react-surface-SEQLEL4K.cjs.map +7 -0
  43. package/dist/lib/node/transcriber-RKKN7LDU.cjs +68 -0
  44. package/dist/lib/node/transcriber-RKKN7LDU.cjs.map +7 -0
  45. package/dist/lib/node/types/index.cjs +7 -11
  46. package/dist/lib/node/types/index.cjs.map +2 -2
  47. package/dist/lib/node-esm/{TranscriptContainer-ZXUCOWGY.mjs → TranscriptContainer-DLNRFVTA.mjs} +4 -3
  48. package/dist/lib/node-esm/chunk-BRPFVRAD.mjs +55 -0
  49. package/dist/lib/node-esm/chunk-BRPFVRAD.mjs.map +7 -0
  50. package/dist/lib/node-esm/{chunk-YQYBLFNI.mjs → chunk-EFIWBQDF.mjs} +139 -95
  51. package/dist/lib/node-esm/chunk-EFIWBQDF.mjs.map +7 -0
  52. package/dist/lib/node-esm/{chunk-J4D2RBBH.mjs → chunk-KUWWHMOA.mjs} +2 -2
  53. package/dist/lib/node-esm/{chunk-PTZHDZ36.mjs → chunk-MFJPEIVB.mjs} +4 -4
  54. package/dist/lib/node-esm/chunk-MFJPEIVB.mjs.map +7 -0
  55. package/dist/lib/node-esm/chunk-PR7EYODX.mjs +765 -0
  56. package/dist/lib/node-esm/chunk-PR7EYODX.mjs.map +7 -0
  57. package/dist/lib/node-esm/{chunk-X4DDJIVL.mjs → chunk-TXMDLLBR.mjs} +3 -3
  58. package/dist/lib/node-esm/{chunk-X4DDJIVL.mjs.map → chunk-TXMDLLBR.mjs.map} +1 -1
  59. package/dist/lib/node-esm/index.mjs +30 -216
  60. package/dist/lib/node-esm/index.mjs.map +4 -4
  61. package/dist/lib/node-esm/{intent-resolver-QN2LO5TX.mjs → intent-resolver-WOZKOEBW.mjs} +7 -11
  62. package/dist/lib/node-esm/intent-resolver-WOZKOEBW.mjs.map +7 -0
  63. package/dist/lib/node-esm/meta.json +1 -1
  64. package/dist/lib/node-esm/{react-surface-PCH6NTVB.mjs → react-surface-7MXUUTAL.mjs} +11 -9
  65. package/dist/lib/node-esm/react-surface-7MXUUTAL.mjs.map +7 -0
  66. package/dist/lib/node-esm/transcriber-5WSI6DYK.mjs +57 -0
  67. package/dist/lib/node-esm/transcriber-5WSI6DYK.mjs.map +7 -0
  68. package/dist/lib/node-esm/types/index.mjs +4 -8
  69. package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
  70. package/dist/types/src/capabilities/capabilities.d.ts +8 -10
  71. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  72. package/dist/types/src/capabilities/index.d.ts +2 -183
  73. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  74. package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
  75. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  76. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  77. package/dist/types/src/capabilities/transcriber.d.ts +2 -1
  78. package/dist/types/src/capabilities/transcriber.d.ts.map +1 -1
  79. package/dist/types/src/components/Transcript/Transcript.d.ts +14 -4
  80. package/dist/types/src/components/Transcript/Transcript.d.ts.map +1 -1
  81. package/dist/types/src/components/Transcript/Transcript.stories.d.ts +19 -4
  82. package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +1 -1
  83. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +27 -0
  84. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +1 -0
  85. package/dist/types/src/components/Transcript/transcript-extension.d.ts +19 -0
  86. package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +1 -0
  87. package/dist/types/src/components/TranscriptContainer.d.ts.map +1 -1
  88. package/dist/types/src/components/stories/FileTranscription.stories.d.ts +17 -0
  89. package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +1 -0
  90. package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts +10 -0
  91. package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +1 -0
  92. package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts +19 -0
  93. package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +1 -0
  94. package/dist/types/src/components/stories/TranscriptionStory.d.ts +11 -0
  95. package/dist/types/src/components/stories/TranscriptionStory.d.ts.map +1 -0
  96. package/dist/types/src/components/stories/useIsSpeaking.d.ts +3 -0
  97. package/dist/types/src/components/stories/useIsSpeaking.d.ts.map +1 -0
  98. package/dist/types/src/hooks/index.d.ts +1 -0
  99. package/dist/types/src/hooks/index.d.ts.map +1 -1
  100. package/dist/types/src/hooks/useAudioFile.d.ts +1 -1
  101. package/dist/types/src/hooks/useAudioFile.d.ts.map +1 -1
  102. package/dist/types/src/hooks/useAudioTrack.d.ts +1 -1
  103. package/dist/types/src/hooks/useAudioTrack.d.ts.map +1 -1
  104. package/dist/types/src/hooks/useQueueModelAdapter.d.ts +7 -0
  105. package/dist/types/src/hooks/useQueueModelAdapter.d.ts.map +1 -0
  106. package/dist/types/src/hooks/useTranscriber.d.ts +1 -1
  107. package/dist/types/src/hooks/useTranscriber.d.ts.map +1 -1
  108. package/dist/types/src/hooks/useVoiceInput.d.ts.map +1 -1
  109. package/dist/types/src/model/index.d.ts +2 -0
  110. package/dist/types/src/model/index.d.ts.map +1 -0
  111. package/dist/types/src/model/model.d.ts +68 -0
  112. package/dist/types/src/model/model.d.ts.map +1 -0
  113. package/dist/types/src/model/model.test.d.ts +2 -0
  114. package/dist/types/src/model/model.test.d.ts.map +1 -0
  115. package/dist/types/src/segments-normalization/index.d.ts +4 -0
  116. package/dist/types/src/segments-normalization/index.d.ts.map +1 -0
  117. package/dist/types/src/segments-normalization/message-normalizer.d.ts +26 -0
  118. package/dist/types/src/segments-normalization/message-normalizer.d.ts.map +1 -0
  119. package/dist/types/src/segments-normalization/normalization.d.ts +520 -0
  120. package/dist/types/src/segments-normalization/normalization.d.ts.map +1 -0
  121. package/dist/types/src/segments-normalization/normalization.test.d.ts +2 -0
  122. package/dist/types/src/segments-normalization/normalization.test.d.ts.map +1 -0
  123. package/dist/types/src/segments-normalization/utils.d.ts +3 -0
  124. package/dist/types/src/segments-normalization/utils.d.ts.map +1 -0
  125. package/dist/types/src/testing/index.d.ts +2 -0
  126. package/dist/types/src/testing/index.d.ts.map +1 -0
  127. package/dist/types/src/testing/testing.d.ts +40 -0
  128. package/dist/types/src/testing/testing.d.ts.map +1 -0
  129. package/dist/types/src/transcriber/media-stream-recorder.d.ts +8 -5
  130. package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
  131. package/dist/types/src/transcriber/transcriber.browser.test.d.ts +2 -0
  132. package/dist/types/src/transcriber/transcriber.browser.test.d.ts.map +1 -0
  133. package/dist/types/src/transcriber/transcriber.d.ts +6 -2
  134. package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
  135. package/dist/types/src/transcriber/transcription-manager.d.ts +19 -15
  136. package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
  137. package/dist/types/src/translations.d.ts +3 -20
  138. package/dist/types/src/translations.d.ts.map +1 -1
  139. package/dist/types/src/types/schema.d.ts +23 -40
  140. package/dist/types/src/types/schema.d.ts.map +1 -1
  141. package/dist/types/src/types/types.d.ts +15 -8
  142. package/dist/types/src/types/types.d.ts.map +1 -1
  143. package/dist/types/src/util/array.d.ts.map +1 -1
  144. package/dist/types/src/util/get-time-str.d.ts.map +1 -1
  145. package/dist/types/src/util/index.d.ts +0 -1
  146. package/dist/types/src/util/index.d.ts.map +1 -1
  147. package/dist/types/src/util/monitor-audio-level.d.ts.map +1 -1
  148. package/dist/types/tsconfig.tsbuildinfo +1 -1
  149. package/package.json +62 -41
  150. package/src/TranscriptionPlugin.tsx +13 -18
  151. package/src/capabilities/capabilities.ts +15 -8
  152. package/src/capabilities/index.ts +0 -2
  153. package/src/capabilities/intent-resolver.ts +7 -8
  154. package/src/capabilities/react-surface.tsx +5 -4
  155. package/src/capabilities/transcriber.ts +34 -6
  156. package/src/components/Transcript/Transcript.stories.tsx +201 -43
  157. package/src/components/Transcript/Transcript.tsx +83 -208
  158. package/src/components/Transcript/deprecated/OldTranscript.tsx +260 -0
  159. package/src/components/Transcript/transcript-extension.ts +236 -0
  160. package/src/components/TranscriptContainer.tsx +11 -6
  161. package/src/components/stories/FileTranscription.stories.tsx +240 -0
  162. package/src/components/stories/KeyWordRecognition.stories.tsx +128 -0
  163. package/src/components/stories/MicrophoneTranscription.stories.tsx +274 -0
  164. package/src/components/stories/TranscriptionStory.tsx +41 -0
  165. package/src/components/stories/useIsSpeaking.tsx +40 -0
  166. package/src/hooks/index.ts +1 -0
  167. package/src/hooks/useAudioFile.ts +39 -9
  168. package/src/hooks/useAudioTrack.ts +2 -2
  169. package/src/hooks/useQueueModelAdapter.ts +65 -0
  170. package/src/hooks/useTranscriber.ts +4 -2
  171. package/src/meta.ts +2 -2
  172. package/src/model/index.ts +5 -0
  173. package/src/model/model.test.ts +169 -0
  174. package/src/model/model.ts +229 -0
  175. package/src/segments-normalization/index.ts +7 -0
  176. package/src/segments-normalization/message-normalizer.ts +108 -0
  177. package/src/segments-normalization/normalization.test.ts +142 -0
  178. package/src/segments-normalization/normalization.ts +103 -0
  179. package/src/segments-normalization/utils.ts +9 -0
  180. package/src/testing/index.ts +5 -0
  181. package/src/testing/testing.ts +216 -0
  182. package/src/transcriber/media-stream-recorder.ts +14 -7
  183. package/src/transcriber/{transcriber.test.ts → transcriber.browser.test.ts} +7 -7
  184. package/src/transcriber/transcriber.ts +33 -20
  185. package/src/transcriber/transcription-manager.ts +87 -71
  186. package/src/translations.ts +2 -3
  187. package/src/types/schema.ts +11 -33
  188. package/src/types/types.ts +8 -12
  189. package/src/util/index.ts +0 -1
  190. package/dist/lib/browser/TranscriptContainer-JQ3HFHLQ.mjs +0 -10
  191. package/dist/lib/browser/app-graph-builder-VDQOVX7P.mjs +0 -191
  192. package/dist/lib/browser/app-graph-builder-VDQOVX7P.mjs.map +0 -7
  193. package/dist/lib/browser/chunk-G4B6CPC2.mjs +0 -253
  194. package/dist/lib/browser/chunk-G4B6CPC2.mjs.map +0 -7
  195. package/dist/lib/browser/chunk-GU2BNYKZ.mjs +0 -35
  196. package/dist/lib/browser/chunk-GU2BNYKZ.mjs.map +0 -7
  197. package/dist/lib/browser/chunk-OGNXNGJB.mjs +0 -73
  198. package/dist/lib/browser/chunk-OGNXNGJB.mjs.map +0 -7
  199. package/dist/lib/browser/chunk-YCZISX63.mjs.map +0 -7
  200. package/dist/lib/browser/chunk-YEPT334A.mjs.map +0 -7
  201. package/dist/lib/browser/intent-resolver-4R66ZCKT.mjs.map +0 -7
  202. package/dist/lib/browser/meeting-transcription-state-DLFHQK72.mjs +0 -18
  203. package/dist/lib/browser/meeting-transcription-state-DLFHQK72.mjs.map +0 -7
  204. package/dist/lib/browser/react-surface-FQUHU5G7.mjs.map +0 -7
  205. package/dist/lib/browser/transcriber-LGMIWDYI.mjs +0 -36
  206. package/dist/lib/browser/transcriber-LGMIWDYI.mjs.map +0 -7
  207. package/dist/lib/node/TranscriptContainer-QEYTTT2V.cjs.map +0 -7
  208. package/dist/lib/node/app-graph-builder-IFSIVNUR.cjs +0 -200
  209. package/dist/lib/node/app-graph-builder-IFSIVNUR.cjs.map +0 -7
  210. package/dist/lib/node/chunk-3KHUSQNW.cjs +0 -55
  211. package/dist/lib/node/chunk-3KHUSQNW.cjs.map +0 -7
  212. package/dist/lib/node/chunk-CZMLKKWT.cjs.map +0 -7
  213. package/dist/lib/node/chunk-FCCJALOT.cjs.map +0 -7
  214. package/dist/lib/node/chunk-P4VVD6ZO.cjs +0 -95
  215. package/dist/lib/node/chunk-P4VVD6ZO.cjs.map +0 -7
  216. package/dist/lib/node/chunk-UOFHT4GZ.cjs +0 -280
  217. package/dist/lib/node/chunk-UOFHT4GZ.cjs.map +0 -7
  218. package/dist/lib/node/intent-resolver-WMMCOUEH.cjs.map +0 -7
  219. package/dist/lib/node/meeting-transcription-state-URIYILEQ.cjs +0 -34
  220. package/dist/lib/node/meeting-transcription-state-URIYILEQ.cjs.map +0 -7
  221. package/dist/lib/node/react-surface-WI2MGWCC.cjs.map +0 -7
  222. package/dist/lib/node/transcriber-QG5WPKX4.cjs +0 -49
  223. package/dist/lib/node/transcriber-QG5WPKX4.cjs.map +0 -7
  224. package/dist/lib/node-esm/app-graph-builder-UL6XLIZY.mjs +0 -192
  225. package/dist/lib/node-esm/app-graph-builder-UL6XLIZY.mjs.map +0 -7
  226. package/dist/lib/node-esm/chunk-6X7X2UZF.mjs +0 -254
  227. package/dist/lib/node-esm/chunk-6X7X2UZF.mjs.map +0 -7
  228. package/dist/lib/node-esm/chunk-GIO6J6FE.mjs +0 -74
  229. package/dist/lib/node-esm/chunk-GIO6J6FE.mjs.map +0 -7
  230. package/dist/lib/node-esm/chunk-HKATMD34.mjs +0 -37
  231. package/dist/lib/node-esm/chunk-HKATMD34.mjs.map +0 -7
  232. package/dist/lib/node-esm/chunk-PTZHDZ36.mjs.map +0 -7
  233. package/dist/lib/node-esm/chunk-YQYBLFNI.mjs.map +0 -7
  234. package/dist/lib/node-esm/intent-resolver-QN2LO5TX.mjs.map +0 -7
  235. package/dist/lib/node-esm/meeting-transcription-state-ZYVRAW6Y.mjs +0 -19
  236. package/dist/lib/node-esm/meeting-transcription-state-ZYVRAW6Y.mjs.map +0 -7
  237. package/dist/lib/node-esm/react-surface-PCH6NTVB.mjs.map +0 -7
  238. package/dist/lib/node-esm/transcriber-TMPYZ5L4.mjs +0 -37
  239. package/dist/lib/node-esm/transcriber-TMPYZ5L4.mjs.map +0 -7
  240. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -181
  241. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  242. package/dist/types/src/capabilities/meeting-transcription-state.d.ts +0 -6
  243. package/dist/types/src/capabilities/meeting-transcription-state.d.ts.map +0 -1
  244. package/dist/types/src/components/transcription.stories.d.ts +0 -15
  245. package/dist/types/src/components/transcription.stories.d.ts.map +0 -1
  246. package/dist/types/src/transcriber/transcriber.test.d.ts +0 -2
  247. package/dist/types/src/transcriber/transcriber.test.d.ts.map +0 -1
  248. package/dist/types/src/util/random-queue-dxn.d.ts +0 -3
  249. package/dist/types/src/util/random-queue-dxn.d.ts.map +0 -1
  250. package/src/capabilities/app-graph-builder.ts +0 -152
  251. package/src/capabilities/meeting-transcription-state.ts +0 -16
  252. package/src/components/transcription.stories.tsx +0 -196
  253. package/src/util/random-queue-dxn.ts +0 -9
  254. /package/dist/lib/browser/{TranscriptContainer-JQ3HFHLQ.mjs.map → TranscriptContainer-PFKLKRPQ.mjs.map} +0 -0
  255. /package/dist/lib/browser/{chunk-K7FOYAXO.mjs.map → chunk-IGEKO7ZU.mjs.map} +0 -0
  256. /package/dist/lib/node/{chunk-LP4FG423.cjs.map → chunk-5J3FBCON.cjs.map} +0 -0
  257. /package/dist/lib/node-esm/{TranscriptContainer-ZXUCOWGY.mjs.map → TranscriptContainer-DLNRFVTA.mjs.map} +0 -0
  258. /package/dist/lib/node-esm/{chunk-J4D2RBBH.mjs.map → chunk-KUWWHMOA.mjs.map} +0 -0
@@ -2,21 +2,20 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes, createResolver, type PluginsContext } from '@dxos/app-framework';
6
- import { create, refFromDXN } from '@dxos/live-object';
7
- import { type SpaceId } from '@dxos/react-client/echo';
5
+ import { Capabilities, contributes, createResolver, type PluginContext } from '@dxos/app-framework';
6
+ import { createQueueDxn } from '@dxos/echo-schema';
7
+ import { type SpaceId } from '@dxos/keys';
8
+ import { live, refFromDXN } from '@dxos/live-object';
8
9
 
9
10
  import { TranscriptionAction, TranscriptType } from '../types';
10
- import { getTimeStr, randomQueueDxn } from '../util';
11
11
 
12
- export default (context: PluginsContext) =>
12
+ export default (context: PluginContext) =>
13
13
  contributes(Capabilities.IntentResolver, [
14
14
  createResolver({
15
15
  intent: TranscriptionAction.Create,
16
16
  resolve: ({ name, spaceId }) => {
17
- const transcript = create(TranscriptType, {
18
- queue: refFromDXN(randomQueueDxn(spaceId as SpaceId)),
19
- name: name ?? `Transcript ${getTimeStr(Date.now())}`,
17
+ const transcript = live(TranscriptType, {
18
+ queue: refFromDXN(createQueueDxn(spaceId as SpaceId)),
20
19
  });
21
20
 
22
21
  return { data: { object: transcript } };
@@ -5,17 +5,18 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
8
+ import { isInstanceOf } from '@dxos/echo-schema';
8
9
 
9
10
  import { TranscriptionContainer } from '../components';
10
- import { TRANSCRIPTION_PLUGIN } from '../meta';
11
- import { isTranscript, type TranscriptType } from '../types';
11
+ import { meta } from '../meta';
12
+ import { TranscriptType } from '../types';
12
13
 
13
14
  export default () =>
14
15
  contributes(Capabilities.ReactSurface, [
15
16
  createSurface({
16
- id: `${TRANSCRIPTION_PLUGIN}/article/transcript`,
17
+ id: `${meta.id}/article/transcript`,
17
18
  role: ['article', 'section'],
18
- filter: (data): data is { subject: TranscriptType } => isTranscript(data.subject),
19
+ filter: (data): data is { subject: TranscriptType } => isInstanceOf(TranscriptType, data.subject),
19
20
  component: ({ data, role }) => <TranscriptionContainer transcript={data.subject} role={role} />,
20
21
  }),
21
22
  ]);
@@ -2,10 +2,11 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { contributes } from '@dxos/app-framework';
5
+ import { contributes, type PluginContext } from '@dxos/app-framework';
6
+ import { ClientCapabilities } from '@dxos/plugin-client';
6
7
 
7
8
  import { TranscriptionCapabilities } from './capabilities';
8
- import { MediaStreamRecorder, Transcriber } from '../transcriber';
9
+ import { MediaStreamRecorder, Transcriber, TranscriptionManager } from '../transcriber';
9
10
 
10
11
  // TODO(burdon): Move to config?
11
12
 
@@ -28,21 +29,48 @@ const TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;
28
29
  /**
29
30
  * Records audio while user is speaking and transcribes it after user is done speaking.
30
31
  */
31
- export default () => {
32
- const getTranscriber: TranscriptionCapabilities.GetTranscriber = ({ audioStreamTrack, onSegments }) => {
32
+ export default (context: PluginContext) => {
33
+ const getTranscriber: TranscriptionCapabilities.GetTranscriber = ({
34
+ audioStreamTrack,
35
+ onSegments,
36
+ transcriberConfig,
37
+ recorderConfig,
38
+ }) => {
33
39
  // Initialize audio transcription.
34
40
  return new Transcriber({
35
41
  config: {
36
42
  transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT,
37
43
  prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT,
44
+ ...transcriberConfig,
38
45
  },
39
46
  recorder: new MediaStreamRecorder({
40
47
  mediaStreamTrack: audioStreamTrack,
41
- interval: RECORD_INTERVAL,
48
+ config: {
49
+ interval: RECORD_INTERVAL,
50
+ ...recorderConfig,
51
+ },
42
52
  }),
43
53
  onSegments,
44
54
  });
45
55
  };
46
56
 
47
- return contributes(TranscriptionCapabilities.Transcriber, getTranscriber);
57
+ const getTranscriptionManager: TranscriptionCapabilities.GetTranscriptionManager = ({ messageEnricher }) => {
58
+ const client = context.getCapability(ClientCapabilities.Client);
59
+ const transcriptionManager = new TranscriptionManager({
60
+ edgeClient: client.edge,
61
+ messageEnricher,
62
+ });
63
+
64
+ const identity = client.halo.identity.get();
65
+ if (identity) {
66
+ transcriptionManager.setIdentityDid(identity.did);
67
+ }
68
+
69
+ return transcriptionManager;
70
+ };
71
+
72
+ return [
73
+ contributes(TranscriptionCapabilities.Transcriber, getTranscriber),
74
+ contributes(TranscriptionCapabilities.TranscriptionManager, getTranscriptionManager),
75
+ ];
48
76
  };
@@ -4,60 +4,200 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type StoryObj, type Meta } from '@storybook/react';
8
- import React, { useEffect, useState } from 'react';
7
+ import { type Meta, type StoryObj } from '@storybook/react';
8
+ import React, { type FC, useEffect, useMemo, useState } from 'react';
9
9
 
10
+ import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
11
+ import { withPluginManager } from '@dxos/app-framework/testing';
12
+ import { ObjectId } from '@dxos/echo-schema';
13
+ import { ClientPlugin } from '@dxos/plugin-client';
14
+ import { PreviewPlugin } from '@dxos/plugin-preview';
15
+ import { SpacePlugin } from '@dxos/plugin-space';
16
+ import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
17
+ import { ThemePlugin } from '@dxos/plugin-theme';
10
18
  import { faker } from '@dxos/random';
11
- import { hues } from '@dxos/react-ui-theme';
12
- import { withTheme, withLayout } from '@dxos/storybook-utils';
19
+ import { useMembers, useSpace } from '@dxos/react-client/echo';
20
+ import { IconButton, Toolbar } from '@dxos/react-ui';
21
+ import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
22
+ import { defaultTx } from '@dxos/react-ui-theme';
23
+ import { DataType } from '@dxos/schema';
24
+ import { Testing } from '@dxos/schema/testing';
25
+ import { withLayout } from '@dxos/storybook-utils';
13
26
 
14
- import { Transcript } from './Transcript';
27
+ import { renderMarkdown, Transcript, type TranscriptProps } from './Transcript';
28
+ import { useQueueModelAdapter } from '../../hooks';
29
+ import { SerializationModel } from '../../model';
30
+ import {
31
+ MessageBuilder,
32
+ TestItem,
33
+ useTestTranscriptionQueue,
34
+ useTestTranscriptionQueueWithEntityExtraction,
35
+ } from '../../testing';
15
36
  import translations from '../../translations';
16
37
 
17
- let start = new Date(Date.now() - 24 * 60 * 60 * 10_000);
18
- const next = () => {
19
- start = new Date(start.getTime() + Math.random() * 10_000);
20
- return start;
38
+ faker.seed(1);
39
+
40
+ /**
41
+ * Story wrapper with test controls.
42
+ */
43
+ const TranscriptContainer: FC<
44
+ TranscriptProps & {
45
+ running: boolean;
46
+ onRunningChange: (running: boolean) => void;
47
+ onReset?: () => void;
48
+ }
49
+ > = ({ space, model, running, onRunningChange, onReset }) => {
50
+ return (
51
+ <div className='grid grid-rows-[1fr_40px] grow divide-y divide-separator'>
52
+ <Transcript space={space} model={model} />
53
+ <div className='grid grid-cols-[1fr_16rem] overflow-hidden'>
54
+ <div className='flex items-center'>
55
+ <SyntaxHighlighter language='json' className='text-sm'>
56
+ {JSON.stringify(model.toJSON())}
57
+ </SyntaxHighlighter>
58
+ </div>
59
+ <Toolbar.Root classNames='justify-end'>
60
+ <IconButton
61
+ icon={running ? 'ph--pause--regular' : 'ph--play--regular'}
62
+ label={running ? 'Pause' : 'Start'}
63
+ onClick={() => onRunningChange(!running)}
64
+ />
65
+ {onReset && <IconButton icon='ph--x--regular' label='Reset' onClick={onReset} />}
66
+ </Toolbar.Root>
67
+ </div>
68
+ </div>
69
+ );
21
70
  };
22
71
 
23
- const users = Array.from({ length: 5 }, () => ({
24
- authorName: faker.person.fullName(),
25
- authorHue: faker.helpers.arrayElement(hues),
26
- }));
27
-
28
- const createBlock = () => {
29
- const author = faker.helpers.arrayElement(users);
30
- return {
31
- id: faker.string.uuid(),
32
- ...author,
33
- segments: Array.from({ length: 1 + Math.floor(Math.random() * 2) }, () => ({
34
- started: next(),
35
- text: faker.lorem.paragraph(),
36
- })),
72
+ type StoryProps = { messages?: DataType.Message[] } & Pick<TranscriptProps, 'ignoreAttention' | 'attendableId'>;
73
+
74
+ /**
75
+ * Basic story mutates array of messages.
76
+ */
77
+ const BasicStory = ({ messages: initialMessages = [], ...props }: StoryProps) => {
78
+ const [reset, setReset] = useState({});
79
+ const builder = useMemo(() => new MessageBuilder(), []);
80
+ const model = useMemo(
81
+ () => new SerializationModel<DataType.Message>(renderMarkdown([]), initialMessages),
82
+ [initialMessages, reset],
83
+ );
84
+ const [running, setRunning] = useState(true);
85
+ const [currentMessage, setCurrentMessage] = useState<DataType.Message | null>(null);
86
+ useEffect(() => {
87
+ if (!running) {
88
+ return;
89
+ }
90
+
91
+ if (!currentMessage) {
92
+ void builder.createMessage().then((message) => {
93
+ model.appendChunk(message);
94
+ setCurrentMessage(message);
95
+ });
96
+ return;
97
+ }
98
+
99
+ const i = setInterval(() => {
100
+ if (currentMessage?.blocks.length && currentMessage.blocks.length >= 3) {
101
+ setCurrentMessage(null);
102
+ clearInterval(i);
103
+ return;
104
+ }
105
+
106
+ currentMessage.blocks.push(builder.createBlock());
107
+ model.updateChunk(currentMessage);
108
+ }, 3_000);
109
+
110
+ return () => clearInterval(i);
111
+ }, [model, currentMessage, running]);
112
+
113
+ const handleReset = () => {
114
+ setCurrentMessage(null);
115
+ setRunning(false);
116
+ setReset({});
37
117
  };
118
+
119
+ return (
120
+ <TranscriptContainer
121
+ model={model}
122
+ running={running}
123
+ onRunningChange={setRunning}
124
+ onReset={handleReset}
125
+ {...props}
126
+ />
127
+ );
38
128
  };
39
129
 
40
- const meta: Meta<typeof Transcript> = {
130
+ /**
131
+ * Queue story mutates queue with model adapter.
132
+ */
133
+ const QueueStory = ({
134
+ messages: initialMessages = [],
135
+ queueId,
136
+ onReset,
137
+ ...props
138
+ }: StoryProps & { queueId: ObjectId; onReset: () => void }) => {
139
+ const [running, setRunning] = useState(true);
140
+ const space = useSpace();
141
+ const members = useMembers(space?.key).map((member) => member.identity);
142
+ const queue = useTestTranscriptionQueue(space, queueId, running, 2_000);
143
+ const model = useQueueModelAdapter(renderMarkdown(members), queue, initialMessages);
144
+
145
+ return (
146
+ <TranscriptContainer
147
+ space={space}
148
+ model={model}
149
+ running={running}
150
+ onRunningChange={setRunning}
151
+ onReset={onReset}
152
+ {...props}
153
+ />
154
+ );
155
+ };
156
+
157
+ // TODO(burdon): Reconcile with QueueStory.
158
+ const EntityExtractionQueueStory = () => {
159
+ const [running, setRunning] = useState(true);
160
+ const space = useSpace();
161
+ const members = useMembers(space?.key).map((member) => member.identity);
162
+ const queue = useTestTranscriptionQueueWithEntityExtraction(space, undefined, running, 2_000);
163
+ const model = useQueueModelAdapter(renderMarkdown(members), queue, []);
164
+
165
+ return <TranscriptContainer space={space} model={model} running={running} onRunningChange={setRunning} />;
166
+ };
167
+
168
+ /**
169
+ * Wrapper remounts on refresh to reload queue.
170
+ */
171
+ const QueueStoryWrapper = () => {
172
+ const [queueId] = useState(ObjectId.random());
173
+ const [key, setKey] = useState(ObjectId.random().toString());
174
+ const handleReset = () => {
175
+ setKey(ObjectId.random().toString());
176
+ };
177
+
178
+ return <QueueStory key={key} queueId={queueId} onReset={handleReset} />;
179
+ };
180
+
181
+ const meta: Meta<typeof QueueStory> = {
41
182
  title: 'plugins/plugin-transcription/Transcript',
42
- component: Transcript,
43
- render: ({ blocks: initialBlocks = [], ...args }) => {
44
- const [blocks, setBlocks] = useState(initialBlocks);
45
- useEffect(() => {
46
- const i = setInterval(() => {
47
- setBlocks((blocks) => [...blocks, createBlock()]);
48
- }, 1_000);
49
-
50
- return () => clearInterval(i);
51
- }, []);
52
-
53
- return <Transcript {...args} blocks={blocks} />;
54
- },
55
183
  decorators: [
56
- withTheme,
57
- withLayout({
58
- tooltips: true,
59
- fullscreen: true,
184
+ withPluginManager({
185
+ plugins: [
186
+ ThemePlugin({ tx: defaultTx }),
187
+ StorybookLayoutPlugin(),
188
+ ClientPlugin({
189
+ types: [TestItem, Testing.DocumentType, DataType.Person, DataType.Organization],
190
+ onClientInitialized: async (_, client) => {
191
+ await client.halo.createIdentity();
192
+ },
193
+ }),
194
+ PreviewPlugin(),
195
+ SpacePlugin(),
196
+ SettingsPlugin(),
197
+ IntentPlugin(),
198
+ ],
60
199
  }),
200
+ withLayout({ fullscreen: true }),
61
201
  ],
62
202
  parameters: {
63
203
  translations,
@@ -66,17 +206,35 @@ const meta: Meta<typeof Transcript> = {
66
206
 
67
207
  export default meta;
68
208
 
69
- type Story = StoryObj<typeof Transcript>;
209
+ type Story = StoryObj<typeof QueueStory>;
70
210
 
71
211
  export const Default: Story = {
212
+ render: BasicStory,
72
213
  args: {
73
214
  ignoreAttention: true,
74
215
  attendableId: 'story',
75
- blocks: Array.from({ length: 10 }, createBlock),
216
+ messages: await Promise.all(Array.from({ length: 10 }, () => MessageBuilder.singleton.createMessage())),
76
217
  },
77
218
  };
78
219
 
79
220
  export const Empty: Story = {
221
+ render: BasicStory,
222
+ args: {
223
+ ignoreAttention: true,
224
+ attendableId: 'story',
225
+ },
226
+ };
227
+
228
+ export const WithQueue: Story = {
229
+ render: QueueStoryWrapper,
230
+ args: {
231
+ ignoreAttention: true,
232
+ attendableId: 'story',
233
+ },
234
+ };
235
+
236
+ export const WithEntityExtractionQueue: Story = {
237
+ render: EntityExtractionQueueStory,
80
238
  args: {
81
239
  ignoreAttention: true,
82
240
  attendableId: 'story',