@dxos/plugin-transcription 0.8.4-main.fd6878d → 0.9.0
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/LICENSE +102 -5
- package/PLUGIN.mdl +401 -0
- package/README.md +1 -1
- package/dist/lib/neutral/TranscriptionArticle-L6XANBH5.mjs +54 -0
- package/dist/lib/neutral/TranscriptionArticle-L6XANBH5.mjs.map +7 -0
- package/dist/lib/neutral/TranscriptionPlugin.mjs +46 -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/TranscriptionPlugin.workerd.mjs +21 -0
- package/dist/lib/neutral/TranscriptionPlugin.workerd.mjs.map +7 -0
- package/dist/lib/neutral/blueprint-definition-DA4QFRYJ.mjs +15 -0
- package/dist/lib/neutral/blueprint-definition-DA4QFRYJ.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-FHNI26QW.mjs +45 -0
- package/dist/lib/neutral/chunk-FHNI26QW.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/neutral/chunk-KMT3BMMQ.mjs +124 -0
- package/dist/lib/neutral/chunk-KMT3BMMQ.mjs.map +7 -0
- package/dist/lib/neutral/chunk-KXJZEYS7.mjs +8 -0
- package/dist/lib/neutral/chunk-KXJZEYS7.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-TO77KAQK.mjs +298 -0
- package/dist/lib/neutral/chunk-TO77KAQK.mjs.map +7 -0
- package/dist/lib/{browser/chunk-KJIQQHJB.mjs → neutral/chunk-TX3NQISZ.mjs} +115 -186
- package/dist/lib/neutral/chunk-TX3NQISZ.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 +269 -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-RVR7VC33.mjs +21 -0
- package/dist/lib/neutral/create-RVR7VC33.mjs.map +7 -0
- package/dist/lib/neutral/hooks/index.mjs +19 -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-A5KXKRH4.mjs +27 -0
- package/dist/lib/neutral/open-A5KXKRH4.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-YMZRO242.mjs +26 -0
- package/dist/lib/neutral/react-surface-YMZRO242.mjs.map +7 -0
- package/dist/lib/neutral/summarize-5XPPMVTE.mjs +77 -0
- package/dist/lib/neutral/summarize-5XPPMVTE.mjs.map +7 -0
- package/dist/lib/neutral/text-content-KBB37HSM.mjs +30 -0
- package/dist/lib/neutral/text-content-KBB37HSM.mjs.map +7 -0
- package/dist/lib/neutral/transcriber-OGSF3XO5.mjs +59 -0
- package/dist/lib/neutral/transcriber-OGSF3XO5.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +24 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/lib/neutral/types/index.mjs +10 -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/TranscriptionPlugin.workerd.d.ts +4 -0
- package/dist/types/src/TranscriptionPlugin.workerd.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 +11 -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/Oracle/Oracle.d.ts +24 -0
- package/dist/types/src/components/Oracle/Oracle.d.ts.map +1 -0
- package/dist/types/src/components/Oracle/Oracle.stories.d.ts +32 -0
- package/dist/types/src/components/Oracle/Oracle.stories.d.ts.map +1 -0
- package/dist/types/src/components/Oracle/index.d.ts +2 -0
- package/dist/types/src/components/Oracle/index.d.ts.map +1 -0
- package/dist/types/src/components/Transcription/Transcription.d.ts +11 -0
- package/dist/types/src/components/Transcription/Transcription.d.ts.map +1 -0
- package/dist/types/src/components/Transcription/Transcription.stories.d.ts +37 -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 +2 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.d.ts +6 -0
- package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.d.ts.map +1 -0
- package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.stories.d.ts +28 -0
- package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.stories.d.ts.map +1 -0
- package/dist/types/src/containers/TranscriptionArticle/index.d.ts +2 -0
- package/dist/types/src/containers/TranscriptionArticle/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/enrichment/conversation.test.d.ts +2 -0
- package/dist/types/src/enrichment/conversation.test.d.ts.map +1 -0
- package/dist/types/src/enrichment/operations.d.ts +200 -0
- package/dist/types/src/enrichment/operations.d.ts.map +1 -0
- package/dist/types/src/enrichment/parser.d.ts +26 -0
- package/dist/types/src/enrichment/parser.d.ts.map +1 -0
- package/dist/types/src/enrichment/stream-simulator.d.ts +38 -0
- package/dist/types/src/enrichment/stream-simulator.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +2 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- 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/useFeedModelAdapter.d.ts +12 -0
- package/dist/types/src/hooks/useFeedModelAdapter.d.ts.map +1 -0
- 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/useTranscriptionRecording.d.ts +12 -0
- package/dist/types/src/hooks/useTranscriptionRecording.d.ts.map +1 -0
- 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 +9 -7
- package/dist/types/src/normalization/message-normalizer.d.ts.map +1 -0
- package/dist/types/src/normalization/normalization.d.ts +834 -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 +20 -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/LiveTranscription.stories.d.ts +20 -0
- package/dist/types/src/stories/LiveTranscription.stories.d.ts.map +1 -0
- package/dist/types/src/stories/TranscriptionStory.d.ts +21 -0
- package/dist/types/src/stories/TranscriptionStory.d.ts.map +1 -0
- package/dist/types/src/stories/common.d.ts +248 -0
- package/dist/types/src/stories/common.d.ts.map +1 -0
- package/dist/types/src/testing/testing.d.ts +14 -15
- package/dist/types/src/testing/testing.d.ts.map +1 -1
- package/dist/types/src/transcriber/index.d.ts +1 -1
- package/dist/types/src/transcriber/index.d.ts.map +1 -1
- package/dist/types/src/transcriber/media-stream-recorder.d.ts +2 -2
- package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcriber.d.ts +61 -6
- 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 +17 -16
- package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +9 -8
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/TranscriptOperation.d.ts +1670 -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/index.d.ts +2 -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 +153 -85
- package/src/TranscriptionPlugin.node.ts +20 -0
- package/src/TranscriptionPlugin.test.ts +31 -0
- package/src/TranscriptionPlugin.tsx +28 -61
- package/src/TranscriptionPlugin.workerd.ts +18 -0
- 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 +16 -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 +54 -41
- package/src/components/Oracle/Oracle.stories.tsx +147 -0
- package/src/components/Oracle/Oracle.tsx +142 -0
- package/src/components/Oracle/index.ts +5 -0
- package/src/components/Transcription/Transcription.stories.tsx +213 -0
- package/src/components/Transcription/Transcription.tsx +55 -0
- package/src/components/{Transcript → Transcription}/index.ts +1 -1
- package/src/components/{Transcript/transcript-extension.ts → Transcription/transcription-extension.ts} +13 -46
- package/src/components/index.ts +2 -6
- package/src/containers/TranscriptionArticle/TranscriptionArticle.stories.tsx +61 -0
- package/src/containers/TranscriptionArticle/TranscriptionArticle.tsx +62 -0
- package/src/containers/TranscriptionArticle/index.ts +5 -0
- package/src/containers/index.ts +7 -0
- package/src/enrichment/conversation.test.ts +162 -0
- package/src/enrichment/conversation.txt +23 -0
- package/src/enrichment/operations.ts +271 -0
- package/src/enrichment/parser.ts +101 -0
- package/src/enrichment/stream-simulator.ts +125 -0
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useAudioFile.ts +49 -53
- package/src/hooks/useAudioTrack.ts +1 -1
- package/src/hooks/useFeedModelAdapter.ts +46 -0
- package/src/hooks/useTranscriber.ts +15 -7
- package/src/hooks/useTranscriptionRecording.ts +87 -0
- package/src/hooks/useVoiceInput.ts +3 -4
- package/src/index.ts +4 -5
- package/src/meta.ts +32 -7
- package/src/model/model.test.ts +22 -16
- package/src/model/model.ts +3 -3
- package/src/{segments-normalization → normalization}/message-normalizer.ts +37 -24
- package/src/{segments-normalization → normalization}/normalization.test.ts +9 -48
- 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 +102 -0
- package/src/plugin.ts +11 -0
- package/src/stories/FileTranscription.stories.tsx +143 -0
- package/src/{components/stories → stories}/KeyWordRecognition.stories.tsx +50 -46
- package/src/stories/LiveTranscription.stories.tsx +153 -0
- package/src/stories/TranscriptionStory.tsx +101 -0
- package/src/stories/common.ts +233 -0
- package/src/testing/testing.ts +53 -65
- package/src/transcriber/index.ts +1 -1
- package/src/transcriber/media-stream-recorder.ts +3 -3
- package/src/transcriber/transcriber.browser.test.ts +4 -5
- package/src/transcriber/transcriber.test.ts +104 -0
- package/src/transcriber/transcriber.ts +105 -60
- package/src/transcriber/transcription-manager.ts +49 -59
- package/src/translations.ts +10 -7
- package/src/types/TranscriptOperation.ts +106 -0
- package/src/types/TranscriptionCapabilities.ts +39 -0
- package/src/types/index.ts +2 -2
- package/src/util/index.ts +1 -0
- package/src/util/render-byline.ts +33 -0
- package/src/vite-env.d.ts +10 -0
- package/dist/lib/browser/TranscriptContainer-FH7VAWYA.mjs +0 -11
- package/dist/lib/browser/chunk-5WH45KBY.mjs +0 -19
- package/dist/lib/browser/chunk-5WH45KBY.mjs.map +0 -7
- package/dist/lib/browser/chunk-BJWYA2BU.mjs +0 -782
- package/dist/lib/browser/chunk-BJWYA2BU.mjs.map +0 -7
- package/dist/lib/browser/chunk-KJIQQHJB.mjs.map +0 -7
- package/dist/lib/browser/chunk-KWOOVS5G.mjs +0 -55
- package/dist/lib/browser/chunk-KWOOVS5G.mjs.map +0 -7
- package/dist/lib/browser/chunk-SREIAQSP.mjs +0 -16
- package/dist/lib/browser/chunk-SREIAQSP.mjs.map +0 -7
- package/dist/lib/browser/chunk-UKUSJTQW.mjs +0 -8
- package/dist/lib/browser/chunk-UKUSJTQW.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-AOVQ7JI4.mjs +0 -30
- package/dist/lib/browser/intent-resolver-AOVQ7JI4.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/react-surface-4MEJMKYQ.mjs +0 -34
- package/dist/lib/browser/react-surface-4MEJMKYQ.mjs.map +0 -7
- package/dist/lib/browser/transcriber-V77CN7XX.mjs +0 -56
- package/dist/lib/browser/transcriber-V77CN7XX.mjs.map +0 -7
- package/dist/lib/browser/types/index.mjs +0 -14
- package/dist/lib/node-esm/TranscriptContainer-GEUOOYHX.mjs +0 -12
- package/dist/lib/node-esm/chunk-A33GNR44.mjs +0 -507
- package/dist/lib/node-esm/chunk-A33GNR44.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-IKQMDRY6.mjs +0 -56
- package/dist/lib/node-esm/chunk-IKQMDRY6.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PHP7MCAY.mjs +0 -10
- package/dist/lib/node-esm/chunk-PHP7MCAY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-TM2ASOZA.mjs +0 -17
- package/dist/lib/node-esm/chunk-TM2ASOZA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XMUCZBP3.mjs +0 -21
- package/dist/lib/node-esm/chunk-XMUCZBP3.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-Y7PCJ34K.mjs +0 -783
- package/dist/lib/node-esm/chunk-Y7PCJ34K.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-P4XPIKQF.mjs +0 -31
- package/dist/lib/node-esm/intent-resolver-P4XPIKQF.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/react-surface-EZUPNHUC.mjs +0 -35
- package/dist/lib/node-esm/react-surface-EZUPNHUC.mjs.map +0 -7
- package/dist/lib/node-esm/transcriber-3SX3DNLV.mjs +0 -57
- package/dist/lib/node-esm/transcriber-3SX3DNLV.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 -9
- 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 +0 -3
- package/dist/types/src/components/stories/useIsSpeaking.d.ts.map +0 -1
- package/dist/types/src/hooks/useQueueModelAdapter.d.ts +0 -8
- package/dist/types/src/hooks/useQueueModelAdapter.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 -422
- 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.stories.tsx +0 -243
- package/src/components/Transcript/Transcript.tsx +0 -101
- package/src/components/Transcript/deprecated/OldTranscript.tsx +0 -260
- package/src/components/TranscriptContainer.tsx +0 -36
- package/src/components/stories/FileTranscription.stories.tsx +0 -246
- package/src/components/stories/MicrophoneTranscription.stories.tsx +0 -283
- package/src/components/stories/TranscriptionStory.tsx +0 -41
- package/src/components/stories/useIsSpeaking.tsx +0 -40
- package/src/hooks/useQueueModelAdapter.ts +0 -66
- package/src/segments-normalization/normalization.ts +0 -115
- package/src/types/schema.ts +0 -41
- package/src/types/types.ts +0 -33
- package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
- package/dist/lib/{browser/TranscriptContainer-FH7VAWYA.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-GEUOOYHX.mjs.map → neutral/index.mjs.map} +0 -0
- package/dist/types/src/{segments-normalization → normalization}/normalization.test.d.ts +0 -0
- package/src/{segments-normalization → normalization}/index.ts +1 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, {
|
|
6
|
+
type ChangeEvent,
|
|
7
|
+
type Dispatch,
|
|
8
|
+
type RefObject,
|
|
9
|
+
type SetStateAction,
|
|
10
|
+
useCallback,
|
|
11
|
+
useRef,
|
|
12
|
+
} from 'react';
|
|
13
|
+
|
|
14
|
+
import { IconButton, ScrollContainer, Toolbar } from '@dxos/react-ui';
|
|
15
|
+
import { type Message } from '@dxos/types';
|
|
16
|
+
|
|
17
|
+
import { Transcription } from '../components';
|
|
18
|
+
import { type SerializationModel } from '../model';
|
|
19
|
+
|
|
20
|
+
export type TranscriptionStoryProps = {
|
|
21
|
+
audioRef?: RefObject<HTMLAudioElement | null>;
|
|
22
|
+
model: SerializationModel<Message.Message>;
|
|
23
|
+
running: boolean;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
uploadAccept?: string;
|
|
26
|
+
onRunningChange: Dispatch<SetStateAction<boolean>>;
|
|
27
|
+
onUpload?: (file: File) => void;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Story wrapper that renders a transcript with playback controls, an optional audio file
|
|
32
|
+
* upload affordance, and a toolbar slot for additional controls.
|
|
33
|
+
*
|
|
34
|
+
* @param onUpload - Callback fired when the user picks a local audio file via the upload button.
|
|
35
|
+
* @param uploadAccept - HTML `accept` filter for the hidden file input. Defaults to `audio/*`.
|
|
36
|
+
*/
|
|
37
|
+
export const TranscriptionStory = ({
|
|
38
|
+
audioRef,
|
|
39
|
+
model,
|
|
40
|
+
running,
|
|
41
|
+
disabled,
|
|
42
|
+
uploadAccept = 'audio/*',
|
|
43
|
+
onRunningChange,
|
|
44
|
+
onUpload,
|
|
45
|
+
}: TranscriptionStoryProps) => {
|
|
46
|
+
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
47
|
+
|
|
48
|
+
const handleFileChange = useCallback(
|
|
49
|
+
(event: ChangeEvent<HTMLInputElement>) => {
|
|
50
|
+
const file = event.target.files?.[0];
|
|
51
|
+
if (file && onUpload) {
|
|
52
|
+
onUpload(file);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Reset so the same file can be re-selected.
|
|
56
|
+
event.target.value = '';
|
|
57
|
+
},
|
|
58
|
+
[onUpload],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
{audioRef && <audio ref={audioRef} autoPlay />}
|
|
64
|
+
<Toolbar.Root>
|
|
65
|
+
<IconButton
|
|
66
|
+
iconOnly
|
|
67
|
+
disabled={disabled}
|
|
68
|
+
icon={running ? 'ph--pause--regular' : 'ph--play--regular'}
|
|
69
|
+
label={running ? 'Pause' : 'Play'}
|
|
70
|
+
onClick={() => onRunningChange((running) => !running)}
|
|
71
|
+
/>
|
|
72
|
+
{onUpload && (
|
|
73
|
+
<>
|
|
74
|
+
<input
|
|
75
|
+
ref={fileInputRef}
|
|
76
|
+
type='file'
|
|
77
|
+
accept={uploadAccept}
|
|
78
|
+
disabled={disabled}
|
|
79
|
+
className='hidden'
|
|
80
|
+
onChange={handleFileChange}
|
|
81
|
+
/>
|
|
82
|
+
<IconButton
|
|
83
|
+
iconOnly
|
|
84
|
+
disabled={disabled}
|
|
85
|
+
icon='ph--upload--regular'
|
|
86
|
+
label='Upload audio'
|
|
87
|
+
onClick={() => fileInputRef.current?.click()}
|
|
88
|
+
/>
|
|
89
|
+
</>
|
|
90
|
+
)}
|
|
91
|
+
</Toolbar.Root>
|
|
92
|
+
<ScrollContainer.Root pin>
|
|
93
|
+
<ScrollContainer.Content>
|
|
94
|
+
<ScrollContainer.Viewport>
|
|
95
|
+
<Transcription model={model} />
|
|
96
|
+
</ScrollContainer.Viewport>
|
|
97
|
+
</ScrollContainer.Content>
|
|
98
|
+
</ScrollContainer.Root>
|
|
99
|
+
</>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// Helpers shared between LiveTranscription / FileTranscription stories.
|
|
6
|
+
// Each "live" story differs only in its *audio source* (mic vs file); everything else —
|
|
7
|
+
// the local in-memory message buffer, the transcriber lifecycle, and the plugin-manager
|
|
8
|
+
// decorator stack — is identical and lives here.
|
|
9
|
+
|
|
10
|
+
import { type Decorator } from '@storybook/react-vite';
|
|
11
|
+
import * as Effect from 'effect/Effect';
|
|
12
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
13
|
+
|
|
14
|
+
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
15
|
+
import { AppActivationEvents } from '@dxos/app-toolkit';
|
|
16
|
+
import { scheduleTask } from '@dxos/async';
|
|
17
|
+
import { Context } from '@dxos/context';
|
|
18
|
+
import { Obj } from '@dxos/echo';
|
|
19
|
+
import { SpeakingMonitor } from '@dxos/plugin-calls';
|
|
20
|
+
import { ClientPlugin, initializeIdentity } from '@dxos/plugin-client/testing';
|
|
21
|
+
import { PreviewPlugin } from '@dxos/plugin-preview/testing';
|
|
22
|
+
import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
|
|
23
|
+
import { IndexKind } from '@dxos/react-client/echo';
|
|
24
|
+
import { withLayout } from '@dxos/react-ui/testing';
|
|
25
|
+
import { Message, Organization, Person } from '@dxos/types';
|
|
26
|
+
import { seedTestData } from '@dxos/types/testing';
|
|
27
|
+
|
|
28
|
+
import { useFeedModelAdapter, useTranscriber } from '#hooks';
|
|
29
|
+
import { TestItem } from '#testing';
|
|
30
|
+
import { type TranscriptionCapabilities } from '#types';
|
|
31
|
+
|
|
32
|
+
import { type Transcriber, type TranscriberProps } from '../transcriber';
|
|
33
|
+
import { TranscriptionPlugin } from '../TranscriptionPlugin';
|
|
34
|
+
import { renderByline } from '../util';
|
|
35
|
+
|
|
36
|
+
export const useIsSpeaking = (track?: MediaStreamTrack) => {
|
|
37
|
+
const [isSpeaking, setIsSpeaking] = useState(false);
|
|
38
|
+
const speakingMonitor = useMemo(() => {
|
|
39
|
+
if (!track) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return new SpeakingMonitor(track);
|
|
44
|
+
}, [track]);
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!speakingMonitor) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const ctx = new Context();
|
|
52
|
+
scheduleTask(ctx, async () => {
|
|
53
|
+
speakingMonitor.speakingChanged.on(ctx, () => setIsSpeaking(speakingMonitor.isSpeaking));
|
|
54
|
+
await speakingMonitor.open();
|
|
55
|
+
ctx.onDispose(() => speakingMonitor.close());
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return () => {
|
|
59
|
+
void ctx.dispose();
|
|
60
|
+
};
|
|
61
|
+
}, [speakingMonitor]);
|
|
62
|
+
|
|
63
|
+
return isSpeaking;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
//
|
|
67
|
+
// Message model.
|
|
68
|
+
//
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* In-memory message buffer + model adapter for storybook use (production wires up a real
|
|
72
|
+
* space-backed `Feed`). Returns the renderable `model` plus an `appendMessage` callback.
|
|
73
|
+
*/
|
|
74
|
+
export const useStoryMessageModel = () => {
|
|
75
|
+
const [messages, setMessages] = useState<Message.Message[]>([]);
|
|
76
|
+
const appendMessage = useCallback((message: Message.Message) => setMessages((prev) => [...prev, message]), []);
|
|
77
|
+
const model = useFeedModelAdapter(renderByline([]), messages);
|
|
78
|
+
return { model, appendMessage };
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Wraps blocks in a `Message.Message` with the given sender and appends it to the local buffer.
|
|
83
|
+
* Provided as a convenience for stories that don't need entity-extraction or custom enrichment.
|
|
84
|
+
*/
|
|
85
|
+
export const useStoryAppendSegments = (
|
|
86
|
+
appendMessage: (message: Message.Message) => void,
|
|
87
|
+
sender: Message.Message['sender'] = {},
|
|
88
|
+
): TranscriberProps['onSegments'] =>
|
|
89
|
+
useCallback<TranscriberProps['onSegments']>(
|
|
90
|
+
async (blocks) => {
|
|
91
|
+
appendMessage(
|
|
92
|
+
Obj.make(Message.Message, {
|
|
93
|
+
created: new Date().toISOString(),
|
|
94
|
+
sender,
|
|
95
|
+
blocks,
|
|
96
|
+
}),
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
[appendMessage, sender],
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
//
|
|
103
|
+
// Transcriber lifecycle.
|
|
104
|
+
//
|
|
105
|
+
|
|
106
|
+
export type UseStoryTranscriberOptions = Pick<
|
|
107
|
+
TranscriptionCapabilities.TranscriberProviderProps,
|
|
108
|
+
'transcriberConfig' | 'recorderConfig' | 'onSegments'
|
|
109
|
+
> & {
|
|
110
|
+
audioStreamTrack?: MediaStreamTrack;
|
|
111
|
+
/** Whether the user has the toolbar toggle on. */
|
|
112
|
+
running: boolean;
|
|
113
|
+
/** Voice-activity flag — chunks recording only fires while `true`. */
|
|
114
|
+
isSpeaking: boolean;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Drives the transcriber's open/close + chunk-recording lifecycle off `running`,
|
|
119
|
+
* the open flag, and an `isSpeaking` voice-activity gate. Returns the transcriber instance
|
|
120
|
+
* (`undefined` until the capability resolves and an audio track is available).
|
|
121
|
+
*/
|
|
122
|
+
export const useStoryTranscriber = ({
|
|
123
|
+
audioStreamTrack,
|
|
124
|
+
running,
|
|
125
|
+
isSpeaking,
|
|
126
|
+
transcriberConfig,
|
|
127
|
+
recorderConfig,
|
|
128
|
+
onSegments,
|
|
129
|
+
}: UseStoryTranscriberOptions): Transcriber | undefined => {
|
|
130
|
+
const transcriber = useTranscriber({
|
|
131
|
+
audioStreamTrack,
|
|
132
|
+
onSegments,
|
|
133
|
+
transcriberConfig,
|
|
134
|
+
recorderConfig,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Open the transcriber when it becomes available; close on teardown.
|
|
138
|
+
// `tokenRef` is a per-effect identity so a late `close()` completion from a stale
|
|
139
|
+
// transcriber instance can't clobber `isOpen` after a newer instance has opened.
|
|
140
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
141
|
+
const tokenRef = useRef<symbol | null>(null);
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
if (!transcriber) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const token = Symbol();
|
|
147
|
+
tokenRef.current = token;
|
|
148
|
+
void transcriber.open().then(
|
|
149
|
+
() => tokenRef.current === token && setIsOpen(true),
|
|
150
|
+
() => tokenRef.current === token && setIsOpen(false),
|
|
151
|
+
);
|
|
152
|
+
return () => {
|
|
153
|
+
void transcriber.close().then(() => {
|
|
154
|
+
if (tokenRef.current === token) {
|
|
155
|
+
setIsOpen(false);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
}, [transcriber]);
|
|
160
|
+
|
|
161
|
+
// Start/stop chunk recording based on running + open + isSpeaking.
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
if (!transcriber || !isOpen) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (running && isSpeaking) {
|
|
167
|
+
transcriber.startChunksRecording();
|
|
168
|
+
} else {
|
|
169
|
+
transcriber.stopChunksRecording();
|
|
170
|
+
}
|
|
171
|
+
}, [transcriber, isOpen, running, isSpeaking]);
|
|
172
|
+
|
|
173
|
+
return transcriber;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
//
|
|
177
|
+
// Plugin manager decorator.
|
|
178
|
+
//
|
|
179
|
+
|
|
180
|
+
export type StoryDecoratorsOptions = {
|
|
181
|
+
/**
|
|
182
|
+
* Enable schema/graph/vector indexes after the client boots; needed for entity-extraction
|
|
183
|
+
* queries over seeded `Person` / `Organization` objects.
|
|
184
|
+
* @default false
|
|
185
|
+
*/
|
|
186
|
+
enableVectorIndex?: boolean;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Standard plugin-manager decorator for transcription stories: core plugins,
|
|
191
|
+
* `ClientPlugin` with `Person`/`Organization`/`TestItem` schemas + seeded test data, plus
|
|
192
|
+
* the `PreviewPlugin` and `TranscriptionPlugin`. Toggle `enableVectorIndex` for entity-extraction.
|
|
193
|
+
*/
|
|
194
|
+
export const createStoryDecorators = ({ enableVectorIndex = false }: StoryDecoratorsOptions = {}): Decorator[] => [
|
|
195
|
+
withLayout({ layout: 'column' }),
|
|
196
|
+
withPluginManager({
|
|
197
|
+
plugins: [
|
|
198
|
+
...corePlugins(),
|
|
199
|
+
StorybookPlugin({}),
|
|
200
|
+
ClientPlugin({
|
|
201
|
+
types: [TestItem, Person.Person, Organization.Organization],
|
|
202
|
+
onClientInitialized: ({ client }) =>
|
|
203
|
+
Effect.gen(function* () {
|
|
204
|
+
const { personalSpace } = yield* initializeIdentity(client);
|
|
205
|
+
if (enableVectorIndex) {
|
|
206
|
+
yield* enableQueryIndexes(client.services.services);
|
|
207
|
+
}
|
|
208
|
+
yield* Effect.promise(() => seedTestData(personalSpace));
|
|
209
|
+
}),
|
|
210
|
+
}),
|
|
211
|
+
PreviewPlugin(),
|
|
212
|
+
TranscriptionPlugin(),
|
|
213
|
+
],
|
|
214
|
+
fireEvents: [AppActivationEvents.SetupAppGraph],
|
|
215
|
+
}),
|
|
216
|
+
];
|
|
217
|
+
|
|
218
|
+
// TODO(mykola): Make API easier to use.
|
|
219
|
+
// TODO(mykola): Delete after enabling vector indexing by default.
|
|
220
|
+
const enableQueryIndexes = (services: { QueryService?: any }) =>
|
|
221
|
+
Effect.gen(function* () {
|
|
222
|
+
yield* Effect.promise(() =>
|
|
223
|
+
services.QueryService!.setConfig({
|
|
224
|
+
enabled: true,
|
|
225
|
+
indexes: [
|
|
226
|
+
{ kind: IndexKind.Kind.SCHEMA_MATCH },
|
|
227
|
+
{ kind: IndexKind.Kind.GRAPH },
|
|
228
|
+
{ kind: IndexKind.Kind.VECTOR },
|
|
229
|
+
],
|
|
230
|
+
}),
|
|
231
|
+
);
|
|
232
|
+
yield* Effect.promise(() => services.QueryService!.reindex());
|
|
233
|
+
});
|
package/src/testing/testing.ts
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as Schema from 'effect/Schema';
|
|
6
7
|
import { useEffect, useMemo, useState } from 'react';
|
|
7
8
|
|
|
8
|
-
import {
|
|
9
|
+
import { extractionAnthropicFunction, processTranscriptMessage } from '@dxos/assistant/extraction';
|
|
9
10
|
import { scheduleTaskInterval } from '@dxos/async';
|
|
10
|
-
import {
|
|
11
|
+
import { createFeedServiceLayer, type Space } from '@dxos/client/echo';
|
|
11
12
|
import { Context } from '@dxos/context';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { FunctionExecutor, ServiceContainer } from '@dxos/functions';
|
|
13
|
+
import { DXN, Feed, Filter, Obj, Ref, Type } from '@dxos/echo';
|
|
14
|
+
import { EffectEx } from '@dxos/effect';
|
|
15
15
|
import { IdentityDid } from '@dxos/keys';
|
|
16
16
|
import { log } from '@dxos/log';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
17
|
+
import { random } from '@dxos/random';
|
|
18
|
+
import { TestSchema } from '@dxos/schema/testing';
|
|
19
|
+
import { type ContentBlock, Message, Organization, Person } from '@dxos/types';
|
|
20
|
+
import { seedTestData } from '@dxos/types/testing';
|
|
21
21
|
|
|
22
22
|
// TODO(burdon): Reconcile with plugin-markdown. Move to @dxos/schema/testing.
|
|
23
23
|
export const TestItem = Schema.Struct({
|
|
@@ -29,16 +29,11 @@ export const TestItem = Schema.Struct({
|
|
|
29
29
|
title: 'Description',
|
|
30
30
|
description: 'Product description',
|
|
31
31
|
}),
|
|
32
|
-
}).pipe(
|
|
33
|
-
Type.Obj({
|
|
34
|
-
typename: 'dxos.org/type/Test',
|
|
35
|
-
version: '0.1.0',
|
|
36
|
-
}),
|
|
37
|
-
);
|
|
32
|
+
}).pipe(Type.makeObject(DXN.make('org.dxos.type.test', '0.1.0')));
|
|
38
33
|
|
|
39
34
|
// TODO(wittjosiah): Make builder generic and reuse for all message types.
|
|
40
35
|
abstract class AbstractMessageBuilder {
|
|
41
|
-
abstract createMessage(numSegments?: number): Promise<
|
|
36
|
+
abstract createMessage(numSegments?: number): Promise<Message.Message>;
|
|
42
37
|
}
|
|
43
38
|
|
|
44
39
|
/**
|
|
@@ -49,8 +44,8 @@ export class MessageBuilder extends AbstractMessageBuilder {
|
|
|
49
44
|
|
|
50
45
|
users = Array.from({ length: 5 }, () => ({
|
|
51
46
|
identityDid: IdentityDid.random().toString(),
|
|
52
|
-
name:
|
|
53
|
-
email:
|
|
47
|
+
name: random.person.fullName(),
|
|
48
|
+
email: random.internet.email(),
|
|
54
49
|
}));
|
|
55
50
|
|
|
56
51
|
start = new Date(Date.now() - 24 * 60 * 60 * 10_000);
|
|
@@ -59,22 +54,27 @@ export class MessageBuilder extends AbstractMessageBuilder {
|
|
|
59
54
|
super();
|
|
60
55
|
}
|
|
61
56
|
|
|
62
|
-
override async createMessage(numSegments = 1): Promise<
|
|
63
|
-
return Obj.make(
|
|
57
|
+
override async createMessage(numSegments = 1): Promise<Message.Message> {
|
|
58
|
+
return Obj.make(Message.Message, {
|
|
64
59
|
created: this.next().toISOString(),
|
|
65
|
-
sender:
|
|
60
|
+
sender: random.helpers.arrayElement(this.users),
|
|
66
61
|
blocks: Array.from({ length: numSegments }).map(() => this.createBlock()),
|
|
67
62
|
});
|
|
68
63
|
}
|
|
69
64
|
|
|
70
|
-
createBlock():
|
|
71
|
-
let text =
|
|
65
|
+
createBlock(): ContentBlock.Transcript {
|
|
66
|
+
let text = random.lorem.paragraph();
|
|
72
67
|
if (this._space) {
|
|
73
|
-
const label =
|
|
74
|
-
const obj = this._space.db.add(
|
|
75
|
-
|
|
68
|
+
const label = random.commerce.productName();
|
|
69
|
+
const obj = this._space.db.add(
|
|
70
|
+
Obj.make(TestItem, {
|
|
71
|
+
title: label,
|
|
72
|
+
description: random.lorem.paragraph(),
|
|
73
|
+
}),
|
|
74
|
+
);
|
|
75
|
+
const dxn = Ref.make(obj).uri;
|
|
76
76
|
const words = text.split(' ');
|
|
77
|
-
words.splice(Math.floor(Math.random() * words.length), 0, `[${label}]
|
|
77
|
+
words.splice(Math.floor(Math.random() * words.length), 0, `[${label}](${dxn})`);
|
|
78
78
|
text = words.join(' ');
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -93,17 +93,9 @@ export class MessageBuilder extends AbstractMessageBuilder {
|
|
|
93
93
|
|
|
94
94
|
// TODO(burdon): Reconcile with BlockBuilder.
|
|
95
95
|
class EntityExtractionMessageBuilder extends AbstractMessageBuilder {
|
|
96
|
-
executor = new FunctionExecutor(
|
|
97
|
-
new ServiceContainer().setServices({
|
|
98
|
-
// ai: {
|
|
99
|
-
// client: this.AiService,
|
|
100
|
-
// },
|
|
101
|
-
}),
|
|
102
|
-
);
|
|
103
|
-
|
|
104
96
|
space: Space | undefined;
|
|
105
97
|
currentMessage: number = 0;
|
|
106
|
-
transcriptMessages:
|
|
98
|
+
transcriptMessages: Message.Message[] = [];
|
|
107
99
|
|
|
108
100
|
async connect(space: Space): Promise<void> {
|
|
109
101
|
this.space = space;
|
|
@@ -111,14 +103,18 @@ class EntityExtractionMessageBuilder extends AbstractMessageBuilder {
|
|
|
111
103
|
this.transcriptMessages = transcriptMessages;
|
|
112
104
|
}
|
|
113
105
|
|
|
114
|
-
override async createMessage(): Promise<
|
|
106
|
+
override async createMessage(): Promise<Message.Message> {
|
|
115
107
|
if (!this.space) {
|
|
116
108
|
throw new Error('Space not connected');
|
|
117
109
|
}
|
|
118
110
|
|
|
119
|
-
const
|
|
111
|
+
const objects = await this.space.db
|
|
120
112
|
.query(
|
|
121
|
-
Filter.or(
|
|
113
|
+
Filter.or(
|
|
114
|
+
Filter.type(Person.Person),
|
|
115
|
+
Filter.type(Organization.Organization),
|
|
116
|
+
Filter.type(TestSchema.DocumentType),
|
|
117
|
+
),
|
|
122
118
|
)
|
|
123
119
|
.run();
|
|
124
120
|
|
|
@@ -129,8 +125,7 @@ class EntityExtractionMessageBuilder extends AbstractMessageBuilder {
|
|
|
129
125
|
|
|
130
126
|
const { message: enhancedMessage } = await processTranscriptMessage({
|
|
131
127
|
input: { message },
|
|
132
|
-
|
|
133
|
-
function: extractionAnthropicFn,
|
|
128
|
+
function: extractionAnthropicFunction,
|
|
134
129
|
});
|
|
135
130
|
|
|
136
131
|
return enhancedMessage;
|
|
@@ -139,71 +134,64 @@ class EntityExtractionMessageBuilder extends AbstractMessageBuilder {
|
|
|
139
134
|
|
|
140
135
|
type UseTestTranscriptionQueue = (
|
|
141
136
|
space: Space | undefined,
|
|
142
|
-
queueId?: Key.ObjectId,
|
|
143
137
|
running?: boolean,
|
|
144
138
|
interval?: number,
|
|
145
|
-
) =>
|
|
139
|
+
) => Feed.Feed | undefined;
|
|
146
140
|
|
|
147
141
|
/**
|
|
148
|
-
* Test
|
|
142
|
+
* Test transcription feed.
|
|
149
143
|
*/
|
|
150
144
|
export const useTestTranscriptionQueue: UseTestTranscriptionQueue = (
|
|
151
145
|
space: Space | undefined,
|
|
152
|
-
queueId?: Key.ObjectId,
|
|
153
146
|
running = true,
|
|
154
147
|
interval = 1_000,
|
|
155
148
|
) => {
|
|
156
|
-
|
|
157
|
-
const queueDxn = useMemo(() => (space ? createQueueDXN(space.id, queueId) : undefined), [space, queueId]);
|
|
158
|
-
const queue = useQueue<DataType.Message>(queueDxn);
|
|
149
|
+
const feed = useMemo(() => (space ? space.db.add(Feed.make({ name: 'transcription' })) : undefined), [space]);
|
|
159
150
|
const builder = useMemo(() => new MessageBuilder(space), [space]);
|
|
160
151
|
|
|
161
152
|
useEffect(() => {
|
|
162
|
-
if (!
|
|
153
|
+
if (!space || !feed || !running) {
|
|
163
154
|
return;
|
|
164
155
|
}
|
|
156
|
+
const feedServiceLayer = createFeedServiceLayer(space.queues);
|
|
165
157
|
|
|
166
158
|
const i = setInterval(() => {
|
|
167
159
|
void builder.createMessage(Math.ceil(Math.random() * 3)).then(async (message) => {
|
|
168
|
-
await
|
|
160
|
+
await Feed.append(feed, [message]).pipe(Effect.provide(feedServiceLayer), EffectEx.runAndForwardErrors);
|
|
169
161
|
});
|
|
170
162
|
}, interval);
|
|
171
163
|
return () => clearInterval(i);
|
|
172
|
-
}, [
|
|
164
|
+
}, [space, feed, running, interval]);
|
|
173
165
|
|
|
174
|
-
return
|
|
166
|
+
return feed;
|
|
175
167
|
};
|
|
176
168
|
|
|
177
169
|
/**
|
|
178
|
-
* Test transcription
|
|
170
|
+
* Test transcription feed with entity extraction.
|
|
179
171
|
*/
|
|
180
172
|
// TODO(burdon): Reconcile with useTestTranscriptionQueue.
|
|
181
173
|
export const useTestTranscriptionQueueWithEntityExtraction: UseTestTranscriptionQueue = (
|
|
182
174
|
space: Space | undefined,
|
|
183
|
-
queueId?: Key.ObjectId,
|
|
184
175
|
running = true,
|
|
185
176
|
interval = 1_000,
|
|
186
177
|
) => {
|
|
187
|
-
|
|
188
|
-
const queueDxn = useMemo(() => (space ? createQueueDXN(space.id, queueId) : undefined), [space, queueId]);
|
|
189
|
-
const queue = useQueue<DataType.Message>(queueDxn);
|
|
178
|
+
const feed = useMemo(() => (space ? space.db.add(Feed.make({ name: 'transcription' })) : undefined), [space]);
|
|
190
179
|
const [builder] = useState(() => new EntityExtractionMessageBuilder());
|
|
191
180
|
|
|
192
181
|
useEffect(() => {
|
|
193
|
-
if (!
|
|
182
|
+
if (!space || !feed || !running) {
|
|
194
183
|
return;
|
|
195
184
|
}
|
|
196
185
|
|
|
197
|
-
|
|
198
|
-
void builder.connect(space);
|
|
199
|
-
}
|
|
186
|
+
void builder.connect(space);
|
|
200
187
|
|
|
188
|
+
const feedServiceLayer = createFeedServiceLayer(space.queues);
|
|
201
189
|
const ctx = new Context();
|
|
202
190
|
scheduleTaskInterval(
|
|
203
191
|
ctx,
|
|
204
192
|
async () => {
|
|
205
193
|
const message = await builder.createMessage();
|
|
206
|
-
|
|
194
|
+
await Feed.append(feed, [message]).pipe(Effect.provide(feedServiceLayer), EffectEx.runAndForwardErrors);
|
|
207
195
|
},
|
|
208
196
|
interval,
|
|
209
197
|
);
|
|
@@ -211,7 +199,7 @@ export const useTestTranscriptionQueueWithEntityExtraction: UseTestTranscription
|
|
|
211
199
|
return () => {
|
|
212
200
|
void ctx.dispose();
|
|
213
201
|
};
|
|
214
|
-
}, [space,
|
|
202
|
+
}, [space, feed, running, interval]);
|
|
215
203
|
|
|
216
|
-
return
|
|
204
|
+
return feed;
|
|
217
205
|
};
|
package/src/transcriber/index.ts
CHANGED
|
@@ -19,7 +19,7 @@ const initializeExtendableMediaRecorder = async () => {
|
|
|
19
19
|
await register(await connect());
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
export type
|
|
22
|
+
export type MediaStreamRecorderProps = {
|
|
23
23
|
mediaStreamTrack: MediaStreamTrack;
|
|
24
24
|
config: {
|
|
25
25
|
interval: number;
|
|
@@ -37,12 +37,12 @@ export class MediaStreamRecorder implements AudioRecorder {
|
|
|
37
37
|
/**
|
|
38
38
|
* Default MediaRecorder implementation do not support wav encoding.
|
|
39
39
|
*/
|
|
40
|
-
private readonly _config:
|
|
40
|
+
private readonly _config: MediaStreamRecorderProps['config'];
|
|
41
41
|
private _mediaRecorder?: IMediaRecorder = undefined;
|
|
42
42
|
private _header?: Uint8Array = undefined;
|
|
43
43
|
private _onChunk?: (chunk: AudioChunk) => void;
|
|
44
44
|
|
|
45
|
-
constructor({ mediaStreamTrack, config }:
|
|
45
|
+
constructor({ mediaStreamTrack, config }: MediaStreamRecorderProps) {
|
|
46
46
|
this._mediaStreamTrack = mediaStreamTrack;
|
|
47
47
|
this._config = config;
|
|
48
48
|
}
|
|
@@ -4,15 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import path from 'node:path';
|
|
7
|
-
|
|
8
7
|
import { describe, expect, test } from 'vitest';
|
|
9
8
|
import { WaveFile } from 'wavefile';
|
|
10
9
|
|
|
11
10
|
import { Trigger } from '@dxos/async';
|
|
12
11
|
import { log } from '@dxos/log';
|
|
13
|
-
import { type DataType } from '@dxos/schema';
|
|
14
12
|
import { openAndClose } from '@dxos/test-utils';
|
|
15
13
|
import { TRACE_PROCESSOR, trace } from '@dxos/tracing';
|
|
14
|
+
import { type ContentBlock } from '@dxos/types';
|
|
16
15
|
|
|
17
16
|
import { type AudioChunk, type AudioRecorder, Transcriber } from '../transcriber';
|
|
18
17
|
import { mergeFloat64Arrays } from '../util';
|
|
@@ -94,7 +93,7 @@ describe.skip('Transcriber', () => {
|
|
|
94
93
|
});
|
|
95
94
|
|
|
96
95
|
test.skip('transcription of audio recording', { timeout: 10_000 }, async () => {
|
|
97
|
-
const trigger = new Trigger<
|
|
96
|
+
const trigger = new Trigger<ContentBlock.Transcript[]>({ autoReset: true });
|
|
98
97
|
const recorder = new MockAudioRecorder({
|
|
99
98
|
buffer: await readFile('test.wav'),
|
|
100
99
|
chunkDuration: 3_000,
|
|
@@ -128,7 +127,7 @@ describe.skip('Transcriber', () => {
|
|
|
128
127
|
});
|
|
129
128
|
|
|
130
129
|
test.skip('transcription of audio recording with overlapping chunks', { timeout: 20_000 }, async () => {
|
|
131
|
-
const trigger = new Trigger<
|
|
130
|
+
const trigger = new Trigger<ContentBlock.Transcript[]>({ autoReset: true });
|
|
132
131
|
const recorder = new MockAudioRecorder({
|
|
133
132
|
buffer: await readFile('test.wav'),
|
|
134
133
|
chunkDuration: 3_000,
|
|
@@ -213,7 +212,7 @@ class MockAudioRecorder implements AudioRecorder {
|
|
|
213
212
|
|
|
214
213
|
@trace.span()
|
|
215
214
|
async start(): Promise<void> {
|
|
216
|
-
log.info('start mock audio recorder', {
|
|
215
|
+
log.info('start mock audio recorder', { wavProps: this.wav.fmt });
|
|
217
216
|
const now = Date.now();
|
|
218
217
|
const samples = this.wav.getSamples();
|
|
219
218
|
const sampleRate = this.wavConfig.sampleRate;
|