@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.
- package/dist/lib/neutral/TranscriptionContainer-XNGXNGPX.mjs +35 -0
- package/dist/lib/neutral/TranscriptionContainer-XNGXNGPX.mjs.map +7 -0
- package/dist/lib/neutral/TranscriptionPlugin.mjs +34 -0
- package/dist/lib/neutral/TranscriptionPlugin.mjs.map +7 -0
- package/dist/lib/neutral/TranscriptionPlugin.node.mjs +25 -0
- package/dist/lib/neutral/TranscriptionPlugin.node.mjs.map +7 -0
- package/dist/lib/neutral/blueprint-definition-HOXDG5QP.mjs +15 -0
- package/dist/lib/neutral/blueprint-definition-HOXDG5QP.mjs.map +7 -0
- package/dist/lib/neutral/blueprints/index.mjs +8 -0
- package/dist/lib/neutral/capabilities/index.mjs +17 -0
- package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
- package/dist/lib/neutral/chunk-GL4RS533.mjs +22 -0
- package/dist/lib/neutral/chunk-GL4RS533.mjs.map +7 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/neutral/chunk-KAEXRX3Y.mjs +35 -0
- package/dist/lib/neutral/chunk-KAEXRX3Y.mjs.map +7 -0
- package/dist/lib/{browser/chunk-IQ5ZRMHZ.mjs → neutral/chunk-LS3R7EQI.mjs} +130 -195
- package/dist/lib/neutral/chunk-LS3R7EQI.mjs.map +7 -0
- package/dist/lib/neutral/chunk-MLRJWAQH.mjs +179 -0
- package/dist/lib/neutral/chunk-MLRJWAQH.mjs.map +7 -0
- package/dist/lib/neutral/chunk-NNR3EYR2.mjs +124 -0
- package/dist/lib/neutral/chunk-NNR3EYR2.mjs.map +7 -0
- package/dist/lib/neutral/chunk-NQQK7UZQ.mjs +244 -0
- package/dist/lib/neutral/chunk-NQQK7UZQ.mjs.map +7 -0
- package/dist/lib/neutral/chunk-WVEZMGBT.mjs +8 -0
- package/dist/lib/neutral/chunk-WVEZMGBT.mjs.map +7 -0
- package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs +30 -0
- package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs.map +7 -0
- package/dist/lib/neutral/components/index.mjs +207 -0
- package/dist/lib/neutral/components/index.mjs.map +7 -0
- package/dist/lib/neutral/containers/index.mjs +9 -0
- package/dist/lib/neutral/containers/index.mjs.map +7 -0
- package/dist/lib/neutral/create-2D6S4IMQ.mjs +21 -0
- package/dist/lib/neutral/create-2D6S4IMQ.mjs.map +7 -0
- package/dist/lib/neutral/hooks/index.mjs +17 -0
- package/dist/lib/neutral/index.mjs +44 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/meta.mjs +8 -0
- package/dist/lib/neutral/meta.mjs.map +7 -0
- package/dist/lib/neutral/open-2QB6IIET.mjs +27 -0
- package/dist/lib/neutral/open-2QB6IIET.mjs.map +7 -0
- package/dist/lib/neutral/operation-handler-NXMOAXFP.mjs +13 -0
- package/dist/lib/neutral/operation-handler-NXMOAXFP.mjs.map +7 -0
- package/dist/lib/neutral/operations/index.mjs +8 -0
- package/dist/lib/neutral/operations/index.mjs.map +7 -0
- package/dist/lib/neutral/plugin.mjs +16 -0
- package/dist/lib/neutral/plugin.mjs.map +7 -0
- package/dist/lib/neutral/react-surface-QF4MUMWG.mjs +26 -0
- package/dist/lib/neutral/react-surface-QF4MUMWG.mjs.map +7 -0
- package/dist/lib/neutral/summarize-CJPVKWYZ.mjs +78 -0
- package/dist/lib/neutral/summarize-CJPVKWYZ.mjs.map +7 -0
- package/dist/lib/neutral/text-content-LHSUG2D2.mjs +30 -0
- package/dist/lib/neutral/text-content-LHSUG2D2.mjs.map +7 -0
- package/dist/lib/{browser/transcriber-OYPLZFG5.mjs → neutral/transcriber-M3R6HPTZ.mjs} +21 -18
- package/dist/lib/neutral/transcriber-M3R6HPTZ.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +22 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/lib/neutral/types/index.mjs +12 -0
- package/dist/lib/neutral/types/index.mjs.map +7 -0
- package/dist/types/src/TranscriptionPlugin.d.ts +3 -1
- package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
- package/dist/types/src/TranscriptionPlugin.node.d.ts +4 -0
- package/dist/types/src/TranscriptionPlugin.node.d.ts.map +1 -0
- package/dist/types/src/TranscriptionPlugin.test.d.ts +2 -0
- package/dist/types/src/TranscriptionPlugin.test.d.ts.map +1 -0
- package/dist/types/src/blueprints/index.d.ts +2 -0
- package/dist/types/src/blueprints/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/transcription-blueprint.d.ts +4 -0
- package/dist/types/src/blueprints/transcription-blueprint.d.ts.map +1 -0
- package/dist/types/src/capabilities/blueprint-definition.d.ts +6 -0
- package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +10 -4
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +3 -2
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/text-content.d.ts +8 -0
- package/dist/types/src/capabilities/text-content.d.ts.map +1 -0
- package/dist/types/src/capabilities/transcriber.d.ts +4 -3
- package/dist/types/src/capabilities/transcriber.d.ts.map +1 -1
- package/dist/types/src/components/Transcription/Transcription.d.ts +18 -0
- package/dist/types/src/components/Transcription/Transcription.d.ts.map +1 -0
- package/dist/types/src/components/Transcription/Transcription.stories.d.ts +40 -0
- package/dist/types/src/components/Transcription/Transcription.stories.d.ts.map +1 -0
- package/dist/types/src/components/Transcription/index.d.ts +2 -0
- package/dist/types/src/components/Transcription/index.d.ts.map +1 -0
- package/dist/types/src/components/Transcription/transcription-extension.d.ts +15 -0
- package/dist/types/src/components/Transcription/transcription-extension.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -6
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/TranscriptionContainer/TranscriptionContainer.d.ts +6 -0
- package/dist/types/src/containers/TranscriptionContainer/TranscriptionContainer.d.ts.map +1 -0
- package/dist/types/src/containers/TranscriptionContainer/index.d.ts +2 -0
- package/dist/types/src/containers/TranscriptionContainer/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +3 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useAudioFile.d.ts.map +1 -1
- package/dist/types/src/hooks/useAudioTrack.d.ts.map +1 -1
- package/dist/types/src/hooks/useQueueModelAdapter.d.ts +1 -1
- package/dist/types/src/hooks/useQueueModelAdapter.d.ts.map +1 -1
- package/dist/types/src/hooks/useTranscriber.d.ts +2 -2
- package/dist/types/src/hooks/useTranscriber.d.ts.map +1 -1
- package/dist/types/src/hooks/useVoiceInput.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +2 -3
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/model/model.d.ts +2 -2
- package/dist/types/src/model/model.d.ts.map +1 -1
- package/dist/types/src/{segments-normalization → normalization}/index.d.ts +1 -1
- package/dist/types/src/normalization/index.d.ts.map +1 -0
- package/dist/types/src/{segments-normalization → normalization}/message-normalizer.d.ts +5 -5
- package/dist/types/src/normalization/message-normalizer.d.ts.map +1 -0
- package/dist/types/src/normalization/normalization.d.ts +543 -0
- package/dist/types/src/normalization/normalization.d.ts.map +1 -0
- package/dist/types/src/normalization/normalization.test.d.ts.map +1 -0
- package/dist/types/src/normalization/utils.d.ts +3 -0
- package/dist/types/src/normalization/utils.d.ts.map +1 -0
- package/dist/types/src/operations/create.d.ts +5 -0
- package/dist/types/src/operations/create.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +3 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/operations/open.d.ts +5 -0
- package/dist/types/src/operations/open.d.ts.map +1 -0
- package/dist/types/src/operations/summarize.d.ts +8 -0
- package/dist/types/src/operations/summarize.d.ts.map +1 -0
- package/dist/types/src/plugin.d.ts +4 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/stories/FileTranscription.stories.d.ts +18 -0
- package/dist/types/src/stories/FileTranscription.stories.d.ts.map +1 -0
- package/dist/types/src/stories/KeyWordRecognition.stories.d.ts +14 -0
- package/dist/types/src/stories/KeyWordRecognition.stories.d.ts.map +1 -0
- package/dist/types/src/stories/MicrophoneTranscription.stories.d.ts +20 -0
- package/dist/types/src/stories/MicrophoneTranscription.stories.d.ts.map +1 -0
- package/dist/types/src/stories/TranscriptionStory.d.ts +23 -0
- package/dist/types/src/stories/TranscriptionStory.d.ts.map +1 -0
- package/dist/types/src/stories/useIsSpeaking.d.ts.map +1 -0
- package/dist/types/src/testing/testing.d.ts +10 -10
- package/dist/types/src/testing/testing.d.ts.map +1 -1
- package/dist/types/src/transcriber/media-stream-recorder.d.ts +3 -3
- package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcriber.d.ts +60 -5
- package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcriber.test.d.ts +2 -0
- package/dist/types/src/transcriber/transcriber.test.d.ts.map +1 -0
- package/dist/types/src/transcriber/transcription-manager.d.ts +12 -13
- package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +10 -11
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/TranscriptOperation.d.ts +917 -0
- package/dist/types/src/types/TranscriptOperation.d.ts.map +1 -0
- package/dist/types/src/types/TranscriptionCapabilities.d.ts +17 -0
- package/dist/types/src/types/TranscriptionCapabilities.d.ts.map +1 -0
- package/dist/types/src/types/defs.d.ts +5 -0
- package/dist/types/src/types/defs.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +3 -2
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/util/array.d.ts.map +1 -1
- package/dist/types/src/util/get-time-str.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/monitor-audio-level.d.ts.map +1 -1
- package/dist/types/src/util/render-byline.d.ts +4 -0
- package/dist/types/src/util/render-byline.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +152 -84
- package/src/TranscriptionPlugin.node.ts +20 -0
- package/src/TranscriptionPlugin.test.ts +31 -0
- package/src/TranscriptionPlugin.tsx +22 -61
- package/src/blueprints/index.ts +5 -0
- package/src/blueprints/transcription-blueprint.ts +29 -0
- package/src/capabilities/blueprint-definition.ts +19 -0
- package/src/capabilities/index.ts +11 -6
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/react-surface.tsx +23 -14
- package/src/capabilities/text-content.ts +33 -0
- package/src/capabilities/transcriber.ts +53 -41
- package/src/components/{Transcript/Transcript.stories.tsx → Transcription/Transcription.stories.tsx} +80 -75
- package/src/components/Transcription/Transcription.tsx +64 -0
- package/src/components/{Transcript → Transcription}/index.ts +1 -1
- package/src/components/{Transcript/transcript-extension.ts → Transcription/transcription-extension.ts} +15 -48
- package/src/components/index.ts +1 -6
- package/src/containers/TranscriptionContainer/TranscriptionContainer.tsx +35 -0
- package/src/containers/TranscriptionContainer/index.ts +5 -0
- package/src/containers/index.ts +7 -0
- package/src/hooks/useAudioFile.ts +49 -53
- package/src/hooks/useQueueModelAdapter.ts +1 -1
- package/src/hooks/useTranscriber.ts +15 -7
- package/src/hooks/useVoiceInput.ts +3 -3
- package/src/index.ts +4 -5
- package/src/meta.ts +9 -6
- package/src/model/model.test.ts +27 -21
- package/src/model/model.ts +3 -3
- package/src/{segments-normalization → normalization}/message-normalizer.ts +20 -19
- package/src/{segments-normalization → normalization}/normalization.test.ts +26 -33
- package/src/normalization/normalization.ts +76 -0
- package/src/{segments-normalization → normalization}/utils.ts +2 -2
- package/src/operations/create.ts +24 -0
- package/src/operations/index.ts +11 -0
- package/src/operations/open.ts +28 -0
- package/src/operations/summarize.ts +101 -0
- package/src/plugin.ts +11 -0
- package/src/stories/FileTranscription.stories.tsx +269 -0
- package/src/{components/stories → stories}/KeyWordRecognition.stories.tsx +46 -40
- package/src/stories/MicrophoneTranscription.stories.tsx +264 -0
- package/src/stories/TranscriptionStory.tsx +93 -0
- package/src/testing/testing.ts +41 -41
- package/src/transcriber/media-stream-recorder.ts +4 -4
- package/src/transcriber/transcriber.browser.test.ts +5 -5
- package/src/transcriber/transcriber.test.ts +104 -0
- package/src/transcriber/transcriber.ts +101 -62
- package/src/transcriber/transcription-manager.ts +37 -52
- package/src/translations.ts +12 -10
- package/src/types/TranscriptOperation.ts +103 -0
- package/src/types/TranscriptionCapabilities.ts +39 -0
- package/src/types/defs.ts +9 -0
- package/src/types/index.ts +4 -2
- package/src/util/index.ts +1 -0
- package/src/util/render-byline.ts +33 -0
- package/dist/lib/browser/TranscriptContainer-H3AZQ4CQ.mjs +0 -11
- package/dist/lib/browser/chunk-53AXUEIQ.mjs +0 -764
- package/dist/lib/browser/chunk-53AXUEIQ.mjs.map +0 -7
- package/dist/lib/browser/chunk-GOF7MJNV.mjs +0 -19
- package/dist/lib/browser/chunk-GOF7MJNV.mjs.map +0 -7
- package/dist/lib/browser/chunk-IQ5ZRMHZ.mjs.map +0 -7
- package/dist/lib/browser/chunk-OSISJM2F.mjs +0 -55
- package/dist/lib/browser/chunk-OSISJM2F.mjs.map +0 -7
- package/dist/lib/browser/chunk-UDCCT32F.mjs +0 -8
- package/dist/lib/browser/chunk-UDCCT32F.mjs.map +0 -7
- package/dist/lib/browser/chunk-W2KNYJD6.mjs +0 -16
- package/dist/lib/browser/chunk-W2KNYJD6.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -125
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-BGADCHVM.mjs +0 -30
- package/dist/lib/browser/intent-resolver-BGADCHVM.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/react-surface-HMJS5FSS.mjs +0 -34
- package/dist/lib/browser/react-surface-HMJS5FSS.mjs.map +0 -7
- package/dist/lib/browser/transcriber-OYPLZFG5.mjs.map +0 -7
- package/dist/lib/browser/types/index.mjs +0 -14
- package/dist/lib/node/TranscriptContainer-KIG3GMAB.cjs +0 -32
- package/dist/lib/node/TranscriptContainer-KIG3GMAB.cjs.map +0 -7
- package/dist/lib/node/chunk-3PYT3BDM.cjs +0 -40
- package/dist/lib/node/chunk-3PYT3BDM.cjs.map +0 -7
- package/dist/lib/node/chunk-6LW5RA3K.cjs +0 -75
- package/dist/lib/node/chunk-6LW5RA3K.cjs.map +0 -7
- package/dist/lib/node/chunk-AFUZI63A.cjs +0 -42
- package/dist/lib/node/chunk-AFUZI63A.cjs.map +0 -7
- package/dist/lib/node/chunk-CVUN3UO7.cjs +0 -778
- package/dist/lib/node/chunk-CVUN3UO7.cjs.map +0 -7
- package/dist/lib/node/chunk-FKDJNJ57.cjs +0 -35
- package/dist/lib/node/chunk-FKDJNJ57.cjs.map +0 -7
- package/dist/lib/node/chunk-ZFAUMZXE.cjs +0 -518
- package/dist/lib/node/chunk-ZFAUMZXE.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -133
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-LL3TTI4H.cjs +0 -45
- package/dist/lib/node/intent-resolver-LL3TTI4H.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/react-surface-N25TBBG4.cjs +0 -56
- package/dist/lib/node/react-surface-N25TBBG4.cjs.map +0 -7
- package/dist/lib/node/transcriber-6J4FVFSZ.cjs +0 -68
- package/dist/lib/node/transcriber-6J4FVFSZ.cjs.map +0 -7
- package/dist/lib/node/types/index.cjs +0 -36
- package/dist/lib/node/types/index.cjs.map +0 -7
- package/dist/lib/node-esm/TranscriptContainer-G75LDEO5.mjs +0 -12
- package/dist/lib/node-esm/chunk-56QHOX4A.mjs +0 -765
- package/dist/lib/node-esm/chunk-56QHOX4A.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FH75X4JC.mjs +0 -56
- package/dist/lib/node-esm/chunk-FH75X4JC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-MFJO7EKD.mjs +0 -10
- package/dist/lib/node-esm/chunk-MFJO7EKD.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-MFJPEIVB.mjs +0 -17
- package/dist/lib/node-esm/chunk-MFJPEIVB.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PRL64SRU.mjs +0 -496
- package/dist/lib/node-esm/chunk-PRL64SRU.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-TXMDLLBR.mjs +0 -21
- package/dist/lib/node-esm/chunk-TXMDLLBR.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -126
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-5LVCYSJS.mjs +0 -31
- package/dist/lib/node-esm/intent-resolver-5LVCYSJS.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/react-surface-JGQSYGRR.mjs +0 -35
- package/dist/lib/node-esm/react-surface-JGQSYGRR.mjs.map +0 -7
- package/dist/lib/node-esm/transcriber-TVG2MBBN.mjs +0 -57
- package/dist/lib/node-esm/transcriber-TVG2MBBN.mjs.map +0 -7
- package/dist/lib/node-esm/types/index.mjs +0 -15
- package/dist/types/src/capabilities/capabilities.d.ts +0 -17
- package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/components/Transcript/Transcript.d.ts +0 -20
- package/dist/types/src/components/Transcript/Transcript.d.ts.map +0 -1
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts +0 -24
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +0 -1
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +0 -28
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +0 -1
- package/dist/types/src/components/Transcript/index.d.ts +0 -2
- package/dist/types/src/components/Transcript/index.d.ts.map +0 -1
- package/dist/types/src/components/Transcript/transcript-extension.d.ts +0 -19
- package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +0 -1
- package/dist/types/src/components/TranscriptContainer.d.ts +0 -8
- package/dist/types/src/components/TranscriptContainer.d.ts.map +0 -1
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts +0 -17
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +0 -1
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts +0 -10
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +0 -1
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts +0 -19
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +0 -1
- package/dist/types/src/components/stories/TranscriptionStory.d.ts +0 -11
- package/dist/types/src/components/stories/TranscriptionStory.d.ts.map +0 -1
- package/dist/types/src/components/stories/useIsSpeaking.d.ts.map +0 -1
- package/dist/types/src/segments-normalization/index.d.ts.map +0 -1
- package/dist/types/src/segments-normalization/message-normalizer.d.ts.map +0 -1
- package/dist/types/src/segments-normalization/normalization.d.ts +0 -329
- package/dist/types/src/segments-normalization/normalization.d.ts.map +0 -1
- package/dist/types/src/segments-normalization/normalization.test.d.ts.map +0 -1
- package/dist/types/src/segments-normalization/utils.d.ts +0 -3
- package/dist/types/src/segments-normalization/utils.d.ts.map +0 -1
- package/dist/types/src/types/schema.d.ts +0 -41
- package/dist/types/src/types/schema.d.ts.map +0 -1
- package/dist/types/src/types/types.d.ts +0 -31
- package/dist/types/src/types/types.d.ts.map +0 -1
- package/src/capabilities/capabilities.ts +0 -33
- package/src/capabilities/intent-resolver.ts +0 -24
- package/src/components/Transcript/Transcript.tsx +0 -100
- package/src/components/Transcript/deprecated/OldTranscript.tsx +0 -260
- package/src/components/TranscriptContainer.tsx +0 -30
- package/src/components/stories/FileTranscription.stories.tsx +0 -242
- package/src/components/stories/MicrophoneTranscription.stories.tsx +0 -280
- package/src/components/stories/TranscriptionStory.tsx +0 -41
- package/src/segments-normalization/normalization.ts +0 -105
- package/src/types/schema.ts +0 -41
- package/src/types/types.ts +0 -32
- package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
- package/dist/lib/{browser/TranscriptContainer-H3AZQ4CQ.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
- package/dist/lib/{node-esm/types → neutral/hooks}/index.mjs.map +0 -0
- package/dist/lib/{node-esm/TranscriptContainer-G75LDEO5.mjs.map → neutral/index.mjs.map} +0 -0
- package/dist/types/src/{segments-normalization → normalization}/normalization.test.d.ts +0 -0
- package/dist/types/src/{components/stories → stories}/useIsSpeaking.d.ts +0 -0
- package/src/{segments-normalization → normalization}/index.ts +1 -1
- /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
|
-
|
|
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:
|
|
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:
|
|
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 }:
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
212
|
-
|
|
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
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
251
|
-
|
|
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
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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 {
|
|
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 {
|
|
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:
|
|
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<
|
|
55
|
-
private
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
return this._enabled.value;
|
|
66
|
+
get enabled(): Atom.Atom<boolean> {
|
|
67
|
+
return this._enabledAtom;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
119
|
+
await this._maybeRestartTranscriber();
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
protected override async _open(): Promise<void> {
|
|
119
|
-
await this.
|
|
123
|
+
await this._maybeRestartTranscriber();
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
protected override async _close(): Promise<void> {
|
|
123
|
-
|
|
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
|
|
152
|
-
if (!this._audioStreamTrack || !this.
|
|
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
|
|
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(
|
|
168
|
+
let block = Obj.make(Message.Message, {
|
|
184
169
|
created: new Date().toISOString(),
|
|
185
170
|
blocks: segments,
|
|
186
171
|
sender: { identityDid: this._identityDid },
|
package/src/translations.ts
CHANGED
|
@@ -2,21 +2,23 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { type Resource } from '@dxos/react-ui';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import { meta } from '#meta';
|
|
8
|
+
|
|
9
|
+
export const translations = [
|
|
8
10
|
{
|
|
9
11
|
'en-US': {
|
|
10
|
-
[
|
|
11
|
-
'plugin
|
|
12
|
-
'transcript
|
|
12
|
+
[meta.id]: {
|
|
13
|
+
'plugin.name': 'Transcription',
|
|
14
|
+
'transcript-companion.label': 'Transcript',
|
|
13
15
|
|
|
14
|
-
'delete
|
|
15
|
-
'bookmark
|
|
16
|
-
'scroll
|
|
16
|
+
'delete.button': 'Delete',
|
|
17
|
+
'bookmark.button': 'Bookmark',
|
|
18
|
+
'scroll-to-end.label': 'Scroll to latest',
|
|
17
19
|
|
|
18
|
-
'settings
|
|
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
|
+
);
|