@dxos/plugin-transcription 0.9.0 → 0.9.1-staging.ee54ba693a
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/PLUGIN.mdl +25 -5
- package/dist/lib/neutral/{TranscriptionArticle-L6XANBH5.mjs → TranscriptionArticle-FEWCWG4A.mjs} +4 -7
- package/dist/lib/neutral/TranscriptionArticle-FEWCWG4A.mjs.map +7 -0
- package/dist/lib/neutral/TranscriptionPlugin.mjs +29 -6
- package/dist/lib/neutral/TranscriptionPlugin.mjs.map +4 -4
- package/dist/lib/neutral/TranscriptionPlugin.node.mjs +3 -3
- package/dist/lib/neutral/TranscriptionPlugin.node.mjs.map +3 -3
- package/dist/lib/neutral/app-graph-builder-GQRMI22E.mjs +48 -0
- package/dist/lib/neutral/app-graph-builder-GQRMI22E.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +19 -5
- package/dist/lib/neutral/capabilities/index.mjs.map +3 -3
- package/dist/lib/neutral/chunk-5BVHY75B.mjs +54 -0
- package/dist/lib/neutral/chunk-5BVHY75B.mjs.map +7 -0
- package/dist/lib/neutral/chunk-HNXSU7HJ.mjs +8 -0
- package/dist/lib/neutral/{chunk-KXJZEYS7.mjs.map → chunk-HNXSU7HJ.mjs.map} +2 -2
- package/dist/lib/neutral/chunk-KOXLGGSL.mjs +30 -0
- package/dist/lib/neutral/chunk-KOXLGGSL.mjs.map +7 -0
- package/dist/lib/neutral/chunk-MDV7NBFJ.mjs +182 -0
- package/dist/lib/neutral/chunk-MDV7NBFJ.mjs.map +7 -0
- package/dist/lib/neutral/components/index.mjs +114 -258
- package/dist/lib/neutral/components/index.mjs.map +4 -4
- package/dist/lib/neutral/containers/index.mjs +1 -1
- package/dist/lib/neutral/{create-RVR7VC33.mjs → create-HNHGCKZ4.mjs} +2 -2
- package/dist/lib/neutral/enrich-message-DSJU4TXC.mjs +24 -0
- package/dist/lib/neutral/enrich-message-DSJU4TXC.mjs.map +7 -0
- package/dist/lib/neutral/entity-lookup-PCDW7NC4.mjs +25 -0
- package/dist/lib/neutral/entity-lookup-PCDW7NC4.mjs.map +7 -0
- package/dist/lib/neutral/hooks/index.mjs +93 -15
- package/dist/lib/neutral/hooks/index.mjs.map +4 -4
- package/dist/lib/neutral/index.mjs +8 -32
- package/dist/lib/neutral/markdown-extension-CCDXXY7E.mjs +16 -0
- package/dist/lib/neutral/markdown-extension-CCDXXY7E.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/meta.mjs +1 -1
- package/dist/lib/neutral/{open-A5KXKRH4.mjs → open-SNMZXXYO.mjs} +4 -6
- package/dist/lib/neutral/open-SNMZXXYO.mjs.map +7 -0
- package/dist/lib/neutral/operations/index.mjs +1 -1
- package/dist/lib/neutral/pipeline-status-XMWMAUJY.mjs +17 -0
- package/dist/lib/neutral/pipeline-status-XMWMAUJY.mjs.map +7 -0
- package/dist/lib/neutral/plugin.mjs +2 -2
- package/dist/lib/neutral/recording-session-IADO7ATU.mjs +15 -0
- package/dist/lib/neutral/recording-session-IADO7ATU.mjs.map +7 -0
- package/dist/lib/neutral/settings-7KE4MABW.mjs +31 -0
- package/dist/lib/neutral/settings-7KE4MABW.mjs.map +7 -0
- package/dist/lib/neutral/skill-definition-DXNK324V.mjs +15 -0
- package/dist/lib/neutral/skill-definition-DXNK324V.mjs.map +7 -0
- package/dist/lib/neutral/skills/index.mjs +8 -0
- package/dist/lib/neutral/{summarize-5XPPMVTE.mjs → summarize-LBUZTOTH.mjs} +4 -4
- package/dist/lib/neutral/summarize-LBUZTOTH.mjs.map +7 -0
- package/dist/lib/neutral/{text-content-KBB37HSM.mjs → text-content-NOWR642C.mjs} +9 -9
- package/dist/lib/neutral/text-content-NOWR642C.mjs.map +7 -0
- package/dist/lib/neutral/transcriber-6XZHUUHK.mjs +174 -0
- package/dist/lib/neutral/transcriber-6XZHUUHK.mjs.map +7 -0
- package/dist/lib/neutral/transcription-driver-DN6ELQXZ.mjs +207 -0
- package/dist/lib/neutral/transcription-driver-DN6ELQXZ.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +8 -1
- package/dist/lib/neutral/translations.mjs.map +3 -3
- package/dist/lib/neutral/types/index.mjs +3 -1
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +5 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/entity-lookup.d.ts +10 -0
- package/dist/types/src/capabilities/entity-lookup.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +11 -8
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/markdown-extension.d.ts +5 -0
- package/dist/types/src/capabilities/markdown-extension.d.ts.map +1 -0
- package/dist/types/src/capabilities/pipeline-status.d.ts +9 -0
- package/dist/types/src/capabilities/pipeline-status.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/recording-session.d.ts +5 -0
- package/dist/types/src/capabilities/recording-session.d.ts.map +1 -0
- package/dist/types/src/capabilities/settings.d.ts +5 -0
- package/dist/types/src/capabilities/settings.d.ts.map +1 -0
- package/dist/types/src/capabilities/skill-definition.d.ts +5 -0
- package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -0
- package/dist/types/src/capabilities/text-content.d.ts +1 -4
- 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/capabilities/transcription-driver.d.ts +5 -0
- package/dist/types/src/capabilities/transcription-driver.d.ts.map +1 -0
- package/dist/types/src/components/Mic/Mic.d.ts +12 -0
- package/dist/types/src/components/Mic/Mic.d.ts.map +1 -0
- package/dist/types/src/components/{Oracle/Oracle.stories.d.ts → Mic/Mic.stories.d.ts} +9 -7
- package/dist/types/src/components/Mic/Mic.stories.d.ts.map +1 -0
- package/dist/types/src/components/Mic/index.d.ts +2 -0
- package/dist/types/src/components/Mic/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.d.ts.map +1 -1
- package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.stories.d.ts +7 -0
- package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +0 -5
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useTranscriptionRecording.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +32 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/normalization/message-normalizer.d.ts +2 -2
- package/dist/types/src/normalization/message-normalizer.d.ts.map +1 -1
- package/dist/types/src/normalization/normalization.d.ts +98 -733
- package/dist/types/src/normalization/normalization.d.ts.map +1 -1
- package/dist/types/src/operations/enrich-message.d.ts +9 -0
- package/dist/types/src/operations/enrich-message.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts.map +1 -1
- package/dist/types/src/operations/open.d.ts.map +1 -1
- package/dist/types/src/operations/summarize.d.ts.map +1 -1
- package/dist/types/src/skills/index.d.ts +2 -0
- package/dist/types/src/skills/index.d.ts.map +1 -0
- package/dist/types/src/skills/transcription-skill.d.ts +4 -0
- package/dist/types/src/skills/transcription-skill.d.ts.map +1 -0
- package/dist/types/src/stories/Keyword.stories.d.ts +51 -0
- package/dist/types/src/stories/Keyword.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Pipeline.stories.d.ts +60 -0
- package/dist/types/src/stories/Pipeline.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Transcription.stories.d.ts +23 -0
- package/dist/types/src/stories/Transcription.stories.d.ts.map +1 -0
- package/dist/types/src/testing/decorators.d.ts +21 -0
- package/dist/types/src/testing/decorators.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/testing.d.ts +3 -13
- package/dist/types/src/testing/testing.d.ts.map +1 -1
- package/dist/types/src/{transcriber/transcription-manager.d.ts → transcription-manager.d.ts} +6 -5
- package/dist/types/src/transcription-manager.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +7 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/Settings.d.ts +13 -0
- package/dist/types/src/types/Settings.d.ts.map +1 -0
- package/dist/types/src/types/TranscriptOperation.d.ts +114 -1564
- package/dist/types/src/types/TranscriptOperation.d.ts.map +1 -1
- package/dist/types/src/types/TranscriptionCapabilities.d.ts +52 -11
- package/dist/types/src/types/TranscriptionCapabilities.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +1 -0
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +0 -3
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dx.config.ts +42 -0
- package/package.json +69 -69
- package/src/TranscriptionPlugin.node.ts +2 -2
- package/src/TranscriptionPlugin.test.ts +2 -2
- package/src/TranscriptionPlugin.tsx +40 -3
- package/src/capabilities/app-graph-builder.tsx +49 -0
- package/src/capabilities/entity-lookup.ts +32 -0
- package/src/capabilities/index.ts +8 -7
- package/src/capabilities/markdown-extension.ts +17 -0
- package/src/capabilities/pipeline-status.ts +23 -0
- package/src/capabilities/recording-session.ts +17 -0
- package/src/capabilities/settings.ts +34 -0
- package/src/capabilities/skill-definition.ts +15 -0
- package/src/capabilities/text-content.ts +10 -7
- package/src/capabilities/transcriber.ts +5 -48
- package/src/capabilities/transcription-driver.tsx +263 -0
- package/src/components/Mic/Mic.stories.tsx +66 -0
- package/src/components/Mic/Mic.tsx +136 -0
- package/src/components/Mic/index.ts +5 -0
- package/src/components/index.ts +1 -2
- package/src/containers/TranscriptionArticle/TranscriptionArticle.stories.tsx +4 -0
- package/src/containers/TranscriptionArticle/TranscriptionArticle.tsx +5 -6
- package/src/hooks/index.ts +0 -5
- package/src/hooks/useTranscriptionRecording.ts +27 -9
- package/src/index.ts +1 -5
- package/src/meta.ts +2 -35
- package/src/normalization/message-normalizer.ts +3 -3
- package/src/normalization/normalization.ts +3 -0
- package/src/operations/enrich-message.ts +27 -0
- package/src/operations/index.ts +1 -0
- package/src/operations/open.ts +2 -2
- package/src/operations/summarize.ts +2 -2
- package/src/skills/index.ts +5 -0
- package/src/skills/transcription-skill.ts +29 -0
- package/src/stories/Keyword.stories.tsx +98 -0
- package/src/stories/Pipeline.stories.tsx +361 -0
- package/src/stories/Transcription.stories.tsx +178 -0
- package/src/testing/decorators.ts +78 -0
- package/src/testing/index.ts +1 -0
- package/src/testing/testing.ts +14 -134
- package/src/{transcriber/transcription-manager.ts → transcription-manager.ts} +13 -12
- package/src/translations.ts +9 -1
- package/src/types/Settings.ts +59 -0
- package/src/types/TranscriptOperation.ts +22 -4
- package/src/types/TranscriptionCapabilities.ts +61 -20
- package/src/types/index.ts +1 -0
- package/src/util/index.ts +0 -3
- package/dist/lib/neutral/TranscriptionArticle-L6XANBH5.mjs.map +0 -7
- package/dist/lib/neutral/blueprint-definition-DA4QFRYJ.mjs +0 -15
- package/dist/lib/neutral/blueprint-definition-DA4QFRYJ.mjs.map +0 -7
- package/dist/lib/neutral/blueprints/index.mjs +0 -8
- package/dist/lib/neutral/chunk-FHNI26QW.mjs +0 -45
- package/dist/lib/neutral/chunk-FHNI26QW.mjs.map +0 -7
- package/dist/lib/neutral/chunk-KAEXRX3Y.mjs +0 -35
- package/dist/lib/neutral/chunk-KAEXRX3Y.mjs.map +0 -7
- package/dist/lib/neutral/chunk-KMT3BMMQ.mjs +0 -124
- package/dist/lib/neutral/chunk-KMT3BMMQ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-KXJZEYS7.mjs +0 -8
- package/dist/lib/neutral/chunk-MLRJWAQH.mjs +0 -179
- package/dist/lib/neutral/chunk-MLRJWAQH.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TO77KAQK.mjs +0 -298
- package/dist/lib/neutral/chunk-TO77KAQK.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TX3NQISZ.mjs +0 -435
- package/dist/lib/neutral/chunk-TX3NQISZ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs +0 -30
- package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs.map +0 -7
- package/dist/lib/neutral/open-A5KXKRH4.mjs.map +0 -7
- package/dist/lib/neutral/summarize-5XPPMVTE.mjs.map +0 -7
- package/dist/lib/neutral/text-content-KBB37HSM.mjs.map +0 -7
- package/dist/lib/neutral/transcriber-OGSF3XO5.mjs +0 -59
- package/dist/lib/neutral/transcriber-OGSF3XO5.mjs.map +0 -7
- package/dist/types/src/blueprints/index.d.ts +0 -2
- package/dist/types/src/blueprints/index.d.ts.map +0 -1
- package/dist/types/src/blueprints/transcription-blueprint.d.ts +0 -4
- package/dist/types/src/blueprints/transcription-blueprint.d.ts.map +0 -1
- package/dist/types/src/capabilities/blueprint-definition.d.ts +0 -6
- package/dist/types/src/capabilities/blueprint-definition.d.ts.map +0 -1
- package/dist/types/src/components/Oracle/Oracle.d.ts +0 -24
- package/dist/types/src/components/Oracle/Oracle.d.ts.map +0 -1
- package/dist/types/src/components/Oracle/Oracle.stories.d.ts.map +0 -1
- package/dist/types/src/components/Oracle/index.d.ts +0 -2
- package/dist/types/src/components/Oracle/index.d.ts.map +0 -1
- package/dist/types/src/components/Transcription/Transcription.d.ts +0 -11
- package/dist/types/src/components/Transcription/Transcription.d.ts.map +0 -1
- package/dist/types/src/components/Transcription/Transcription.stories.d.ts +0 -37
- package/dist/types/src/components/Transcription/Transcription.stories.d.ts.map +0 -1
- package/dist/types/src/components/Transcription/index.d.ts +0 -2
- package/dist/types/src/components/Transcription/index.d.ts.map +0 -1
- package/dist/types/src/components/Transcription/transcription-extension.d.ts +0 -15
- package/dist/types/src/components/Transcription/transcription-extension.d.ts.map +0 -1
- package/dist/types/src/enrichment/conversation.test.d.ts +0 -2
- package/dist/types/src/enrichment/conversation.test.d.ts.map +0 -1
- package/dist/types/src/enrichment/operations.d.ts +0 -200
- package/dist/types/src/enrichment/operations.d.ts.map +0 -1
- package/dist/types/src/enrichment/parser.d.ts +0 -26
- package/dist/types/src/enrichment/parser.d.ts.map +0 -1
- package/dist/types/src/enrichment/stream-simulator.d.ts +0 -38
- package/dist/types/src/enrichment/stream-simulator.d.ts.map +0 -1
- package/dist/types/src/hooks/useAudioFile.d.ts +0 -7
- package/dist/types/src/hooks/useAudioFile.d.ts.map +0 -1
- package/dist/types/src/hooks/useAudioTrack.d.ts +0 -5
- package/dist/types/src/hooks/useAudioTrack.d.ts.map +0 -1
- package/dist/types/src/hooks/useFeedModelAdapter.d.ts +0 -12
- package/dist/types/src/hooks/useFeedModelAdapter.d.ts.map +0 -1
- package/dist/types/src/hooks/useTranscriber.d.ts +0 -7
- package/dist/types/src/hooks/useTranscriber.d.ts.map +0 -1
- package/dist/types/src/hooks/useVoiceInput.d.ts +0 -11
- package/dist/types/src/hooks/useVoiceInput.d.ts.map +0 -1
- package/dist/types/src/model/index.d.ts +0 -2
- package/dist/types/src/model/index.d.ts.map +0 -1
- package/dist/types/src/model/model.d.ts +0 -68
- package/dist/types/src/model/model.d.ts.map +0 -1
- package/dist/types/src/model/model.test.d.ts +0 -2
- package/dist/types/src/model/model.test.d.ts.map +0 -1
- package/dist/types/src/stories/FileTranscription.stories.d.ts +0 -20
- package/dist/types/src/stories/FileTranscription.stories.d.ts.map +0 -1
- package/dist/types/src/stories/KeyWordRecognition.stories.d.ts +0 -14
- package/dist/types/src/stories/KeyWordRecognition.stories.d.ts.map +0 -1
- package/dist/types/src/stories/LiveTranscription.stories.d.ts +0 -20
- package/dist/types/src/stories/LiveTranscription.stories.d.ts.map +0 -1
- package/dist/types/src/stories/TranscriptionStory.d.ts +0 -21
- package/dist/types/src/stories/TranscriptionStory.d.ts.map +0 -1
- package/dist/types/src/stories/common.d.ts +0 -248
- package/dist/types/src/stories/common.d.ts.map +0 -1
- package/dist/types/src/transcriber/audio-recorder.d.ts +0 -47
- package/dist/types/src/transcriber/audio-recorder.d.ts.map +0 -1
- package/dist/types/src/transcriber/index.d.ts +0 -5
- package/dist/types/src/transcriber/index.d.ts.map +0 -1
- package/dist/types/src/transcriber/media-stream-recorder.d.ts +0 -30
- package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +0 -1
- package/dist/types/src/transcriber/transcriber.browser.test.d.ts +0 -2
- package/dist/types/src/transcriber/transcriber.browser.test.d.ts.map +0 -1
- package/dist/types/src/transcriber/transcriber.d.ts +0 -105
- package/dist/types/src/transcriber/transcriber.d.ts.map +0 -1
- package/dist/types/src/transcriber/transcriber.test.d.ts +0 -2
- package/dist/types/src/transcriber/transcriber.test.d.ts.map +0 -1
- package/dist/types/src/transcriber/transcription-manager.d.ts.map +0 -1
- package/dist/types/src/util/array.d.ts +0 -2
- package/dist/types/src/util/array.d.ts.map +0 -1
- package/dist/types/src/util/monitor-audio-level.d.ts +0 -6
- package/dist/types/src/util/monitor-audio-level.d.ts.map +0 -1
- package/dist/types/src/util/render-byline.d.ts +0 -4
- package/dist/types/src/util/render-byline.d.ts.map +0 -1
- package/src/blueprints/index.ts +0 -5
- package/src/blueprints/transcription-blueprint.ts +0 -29
- package/src/capabilities/blueprint-definition.ts +0 -19
- package/src/components/Oracle/Oracle.stories.tsx +0 -147
- package/src/components/Oracle/Oracle.tsx +0 -142
- package/src/components/Oracle/index.ts +0 -5
- package/src/components/Transcription/Transcription.stories.tsx +0 -213
- package/src/components/Transcription/Transcription.tsx +0 -55
- package/src/components/Transcription/index.ts +0 -5
- package/src/components/Transcription/transcription-extension.ts +0 -203
- package/src/enrichment/conversation.test.ts +0 -162
- package/src/enrichment/conversation.txt +0 -23
- package/src/enrichment/operations.ts +0 -271
- package/src/enrichment/parser.ts +0 -101
- package/src/enrichment/stream-simulator.ts +0 -125
- package/src/hooks/useAudioFile.ts +0 -88
- package/src/hooks/useAudioTrack.ts +0 -35
- package/src/hooks/useFeedModelAdapter.ts +0 -46
- package/src/hooks/useTranscriber.ts +0 -47
- package/src/hooks/useVoiceInput.ts +0 -66
- package/src/model/index.ts +0 -5
- package/src/model/model.test.ts +0 -175
- package/src/model/model.ts +0 -229
- package/src/stories/FileTranscription.stories.tsx +0 -143
- package/src/stories/KeyWordRecognition.stories.tsx +0 -132
- package/src/stories/LiveTranscription.stories.tsx +0 -153
- package/src/stories/TranscriptionStory.tsx +0 -101
- package/src/stories/common.ts +0 -233
- package/src/transcriber/audio-recorder.ts +0 -56
- package/src/transcriber/index.ts +0 -8
- package/src/transcriber/media-stream-recorder.ts +0 -120
- package/src/transcriber/transcriber.browser.test.ts +0 -230
- package/src/transcriber/transcriber.test.ts +0 -104
- package/src/transcriber/transcriber.ts +0 -303
- package/src/util/array.ts +0 -14
- package/src/util/monitor-audio-level.ts +0 -58
- package/src/util/render-byline.ts +0 -33
- /package/dist/lib/neutral/{create-RVR7VC33.mjs.map → create-HNHGCKZ4.mjs.map} +0 -0
- /package/dist/lib/neutral/{blueprints → skills}/index.mjs.map +0 -0
package/src/testing/testing.ts
CHANGED
|
@@ -2,34 +2,27 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import * as Effect from 'effect/Effect';
|
|
6
5
|
import * as Schema from 'effect/Schema';
|
|
7
|
-
import { useEffect, useMemo, useState } from 'react';
|
|
8
6
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { createFeedServiceLayer, type Space } from '@dxos/client/echo';
|
|
12
|
-
import { Context } from '@dxos/context';
|
|
13
|
-
import { DXN, Feed, Filter, Obj, Ref, Type } from '@dxos/echo';
|
|
14
|
-
import { EffectEx } from '@dxos/effect';
|
|
7
|
+
import { type Space } from '@dxos/client/echo';
|
|
8
|
+
import { DXN, Obj, Ref, Type } from '@dxos/echo';
|
|
15
9
|
import { IdentityDid } from '@dxos/keys';
|
|
16
|
-
import { log } from '@dxos/log';
|
|
17
10
|
import { random } from '@dxos/random';
|
|
18
|
-
import {
|
|
19
|
-
import { type ContentBlock, Message, Organization, Person } from '@dxos/types';
|
|
20
|
-
import { seedTestData } from '@dxos/types/testing';
|
|
11
|
+
import { type ContentBlock, Message } from '@dxos/types';
|
|
21
12
|
|
|
22
13
|
// TODO(burdon): Reconcile with plugin-markdown. Move to @dxos/schema/testing.
|
|
23
|
-
export const TestItem =
|
|
24
|
-
|
|
25
|
-
title:
|
|
26
|
-
|
|
14
|
+
export const TestItem = Type.makeObject(DXN.make('org.dxos.type.test', '0.1.0'))(
|
|
15
|
+
Schema.Struct({
|
|
16
|
+
title: Schema.String.annotations({
|
|
17
|
+
title: 'Title',
|
|
18
|
+
description: 'Product title',
|
|
19
|
+
}),
|
|
20
|
+
description: Schema.String.annotations({
|
|
21
|
+
title: 'Description',
|
|
22
|
+
description: 'Product description',
|
|
23
|
+
}),
|
|
27
24
|
}),
|
|
28
|
-
|
|
29
|
-
title: 'Description',
|
|
30
|
-
description: 'Product description',
|
|
31
|
-
}),
|
|
32
|
-
}).pipe(Type.makeObject(DXN.make('org.dxos.type.test', '0.1.0')));
|
|
25
|
+
);
|
|
33
26
|
|
|
34
27
|
// TODO(wittjosiah): Make builder generic and reuse for all message types.
|
|
35
28
|
abstract class AbstractMessageBuilder {
|
|
@@ -90,116 +83,3 @@ export class MessageBuilder extends AbstractMessageBuilder {
|
|
|
90
83
|
return this.start;
|
|
91
84
|
}
|
|
92
85
|
}
|
|
93
|
-
|
|
94
|
-
// TODO(burdon): Reconcile with BlockBuilder.
|
|
95
|
-
class EntityExtractionMessageBuilder extends AbstractMessageBuilder {
|
|
96
|
-
space: Space | undefined;
|
|
97
|
-
currentMessage: number = 0;
|
|
98
|
-
transcriptMessages: Message.Message[] = [];
|
|
99
|
-
|
|
100
|
-
async connect(space: Space): Promise<void> {
|
|
101
|
-
this.space = space;
|
|
102
|
-
const { transcriptMessages } = await seedTestData(space);
|
|
103
|
-
this.transcriptMessages = transcriptMessages;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
override async createMessage(): Promise<Message.Message> {
|
|
107
|
-
if (!this.space) {
|
|
108
|
-
throw new Error('Space not connected');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const objects = await this.space.db
|
|
112
|
-
.query(
|
|
113
|
-
Filter.or(
|
|
114
|
-
Filter.type(Person.Person),
|
|
115
|
-
Filter.type(Organization.Organization),
|
|
116
|
-
Filter.type(TestSchema.DocumentType),
|
|
117
|
-
),
|
|
118
|
-
)
|
|
119
|
-
.run();
|
|
120
|
-
|
|
121
|
-
log.info('context', { objects });
|
|
122
|
-
const message = this.transcriptMessages[this.currentMessage];
|
|
123
|
-
this.currentMessage++;
|
|
124
|
-
this.currentMessage = this.currentMessage % this.transcriptMessages.length;
|
|
125
|
-
|
|
126
|
-
const { message: enhancedMessage } = await processTranscriptMessage({
|
|
127
|
-
input: { message },
|
|
128
|
-
function: extractionAnthropicFunction,
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
return enhancedMessage;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
type UseTestTranscriptionQueue = (
|
|
136
|
-
space: Space | undefined,
|
|
137
|
-
running?: boolean,
|
|
138
|
-
interval?: number,
|
|
139
|
-
) => Feed.Feed | undefined;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Test transcription feed.
|
|
143
|
-
*/
|
|
144
|
-
export const useTestTranscriptionQueue: UseTestTranscriptionQueue = (
|
|
145
|
-
space: Space | undefined,
|
|
146
|
-
running = true,
|
|
147
|
-
interval = 1_000,
|
|
148
|
-
) => {
|
|
149
|
-
const feed = useMemo(() => (space ? space.db.add(Feed.make({ name: 'transcription' })) : undefined), [space]);
|
|
150
|
-
const builder = useMemo(() => new MessageBuilder(space), [space]);
|
|
151
|
-
|
|
152
|
-
useEffect(() => {
|
|
153
|
-
if (!space || !feed || !running) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
const feedServiceLayer = createFeedServiceLayer(space.queues);
|
|
157
|
-
|
|
158
|
-
const i = setInterval(() => {
|
|
159
|
-
void builder.createMessage(Math.ceil(Math.random() * 3)).then(async (message) => {
|
|
160
|
-
await Feed.append(feed, [message]).pipe(Effect.provide(feedServiceLayer), EffectEx.runAndForwardErrors);
|
|
161
|
-
});
|
|
162
|
-
}, interval);
|
|
163
|
-
return () => clearInterval(i);
|
|
164
|
-
}, [space, feed, running, interval]);
|
|
165
|
-
|
|
166
|
-
return feed;
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Test transcription feed with entity extraction.
|
|
171
|
-
*/
|
|
172
|
-
// TODO(burdon): Reconcile with useTestTranscriptionQueue.
|
|
173
|
-
export const useTestTranscriptionQueueWithEntityExtraction: UseTestTranscriptionQueue = (
|
|
174
|
-
space: Space | undefined,
|
|
175
|
-
running = true,
|
|
176
|
-
interval = 1_000,
|
|
177
|
-
) => {
|
|
178
|
-
const feed = useMemo(() => (space ? space.db.add(Feed.make({ name: 'transcription' })) : undefined), [space]);
|
|
179
|
-
const [builder] = useState(() => new EntityExtractionMessageBuilder());
|
|
180
|
-
|
|
181
|
-
useEffect(() => {
|
|
182
|
-
if (!space || !feed || !running) {
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
void builder.connect(space);
|
|
187
|
-
|
|
188
|
-
const feedServiceLayer = createFeedServiceLayer(space.queues);
|
|
189
|
-
const ctx = new Context();
|
|
190
|
-
scheduleTaskInterval(
|
|
191
|
-
ctx,
|
|
192
|
-
async () => {
|
|
193
|
-
const message = await builder.createMessage();
|
|
194
|
-
await Feed.append(feed, [message]).pipe(Effect.provide(feedServiceLayer), EffectEx.runAndForwardErrors);
|
|
195
|
-
},
|
|
196
|
-
interval,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
return () => {
|
|
200
|
-
void ctx.dispose();
|
|
201
|
-
};
|
|
202
|
-
}, [space, feed, running, interval]);
|
|
203
|
-
|
|
204
|
-
return feed;
|
|
205
|
-
};
|
|
@@ -7,15 +7,16 @@ import * as Effect from 'effect/Effect';
|
|
|
7
7
|
import * as Layer from 'effect/Layer';
|
|
8
8
|
|
|
9
9
|
import { synchronized } from '@dxos/async';
|
|
10
|
-
import {
|
|
10
|
+
import { type Space } from '@dxos/client/echo';
|
|
11
11
|
import { Resource } from '@dxos/context';
|
|
12
|
-
import { Feed, Obj } from '@dxos/echo';
|
|
12
|
+
import { Database, Feed, Obj } from '@dxos/echo';
|
|
13
13
|
import { EffectEx } from '@dxos/effect';
|
|
14
14
|
import { type EdgeHttpClient } from '@dxos/react-edge-client';
|
|
15
|
+
import { MediaStreamRecorder } from '@dxos/react-ui-transcription';
|
|
16
|
+
import { Transcriber } from '@dxos/transcription-pipeline';
|
|
15
17
|
import { type ContentBlock, Message } from '@dxos/types';
|
|
16
18
|
|
|
17
|
-
import {
|
|
18
|
-
import { Transcriber } from './transcriber';
|
|
19
|
+
import { type TranscriptionCapabilities } from '#types';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Length of the chunk in ms.
|
|
@@ -33,8 +34,6 @@ const PREFIXED_CHUNKS_AMOUNT = 10;
|
|
|
33
34
|
*/
|
|
34
35
|
const TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;
|
|
35
36
|
|
|
36
|
-
export type TranscriptMessageEnricher = (message: Message.Message) => Promise<Message.Message>;
|
|
37
|
-
|
|
38
37
|
export type TranscriptionManagerOptions = {
|
|
39
38
|
edgeClient: EdgeHttpClient;
|
|
40
39
|
registry: Registry.Registry;
|
|
@@ -42,22 +41,24 @@ export type TranscriptionManagerOptions = {
|
|
|
42
41
|
/**
|
|
43
42
|
* Enrich the message before it is written to the transcription feed.
|
|
44
43
|
*/
|
|
45
|
-
messageEnricher?: TranscriptMessageEnricher;
|
|
44
|
+
messageEnricher?: TranscriptionCapabilities.TranscriptMessageEnricher;
|
|
46
45
|
};
|
|
47
46
|
|
|
48
47
|
/**
|
|
49
|
-
* Manages transcription state for a meeting.
|
|
48
|
+
* Manages transcription state for a meeting. Concrete implementation of the
|
|
49
|
+
* {@link TranscriptionCapabilities.TranscriptionManager} service contract; consumers depend on the
|
|
50
|
+
* interface (via the `TranscriptionManagerProvider` capability), not this class.
|
|
50
51
|
*/
|
|
51
|
-
export class
|
|
52
|
+
export class TranscriptionManagerImpl extends Resource implements TranscriptionCapabilities.TranscriptionManager {
|
|
52
53
|
private readonly _edgeClient: EdgeHttpClient;
|
|
53
|
-
private readonly _messageEnricher?: TranscriptMessageEnricher;
|
|
54
|
+
private readonly _messageEnricher?: TranscriptionCapabilities.TranscriptMessageEnricher;
|
|
54
55
|
private readonly _registry: Registry.Registry;
|
|
55
56
|
private _audioStreamTrack?: MediaStreamTrack = undefined;
|
|
56
57
|
private _identityDid?: string = undefined;
|
|
57
58
|
private _mediaRecorder?: MediaStreamRecorder = undefined;
|
|
58
59
|
private _transcriber?: Transcriber = undefined;
|
|
59
60
|
private _feed?: Feed.Feed = undefined;
|
|
60
|
-
private _feedServiceLayer?: Layer.Layer<
|
|
61
|
+
private _feedServiceLayer?: Layer.Layer<Database.Service> = undefined;
|
|
61
62
|
private _enabledAtom = Atom.make(false);
|
|
62
63
|
|
|
63
64
|
constructor(options: TranscriptionManagerOptions) {
|
|
@@ -77,7 +78,7 @@ export class TranscriptionManager extends Resource {
|
|
|
77
78
|
|
|
78
79
|
setFeed(space: Space, feed: Feed.Feed): this {
|
|
79
80
|
this._feed = feed;
|
|
80
|
-
this._feedServiceLayer =
|
|
81
|
+
this._feedServiceLayer = Database.layer(space.db);
|
|
81
82
|
return this;
|
|
82
83
|
}
|
|
83
84
|
|
package/src/translations.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { meta } from '#meta';
|
|
|
9
9
|
export const translations = [
|
|
10
10
|
{
|
|
11
11
|
'en-US': {
|
|
12
|
-
[meta.
|
|
12
|
+
[meta.profile.key]: {
|
|
13
13
|
'plugin.name': 'Transcription',
|
|
14
14
|
'transcript-companion.label': 'Transcript',
|
|
15
15
|
|
|
@@ -19,6 +19,14 @@ export const translations = [
|
|
|
19
19
|
|
|
20
20
|
'start-recording.label': 'Start recording',
|
|
21
21
|
'stop-recording.label': 'Stop recording',
|
|
22
|
+
'hold-to-record.label': 'Hold to record',
|
|
23
|
+
|
|
24
|
+
'recording-options.label': 'Recording options',
|
|
25
|
+
'record-mode.label': 'Record mode',
|
|
26
|
+
'record-mode.toggle.label': 'Toggle',
|
|
27
|
+
'record-mode.hold.label': 'Hold to record (push to talk)',
|
|
28
|
+
'audio-device.label': 'Microphone',
|
|
29
|
+
'audio-device.default.label': 'System default',
|
|
22
30
|
|
|
23
31
|
'settings.entity-extraction.label': 'Entity extraction',
|
|
24
32
|
},
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// @import-as-namespace
|
|
6
|
+
|
|
7
|
+
import * as Schema from 'effect/Schema';
|
|
8
|
+
|
|
9
|
+
export type RecordMode = 'toggle' | 'hold';
|
|
10
|
+
|
|
11
|
+
export const Settings = Schema.mutable(
|
|
12
|
+
Schema.Struct({
|
|
13
|
+
entityExtraction: Schema.optional(
|
|
14
|
+
Schema.Boolean.annotations({
|
|
15
|
+
title: 'Entity extraction',
|
|
16
|
+
description:
|
|
17
|
+
'While transcribing, use the Assistant to detect and annotate mentions of known objects such as people or organizations.',
|
|
18
|
+
}),
|
|
19
|
+
).pipe(Schema.withConstructorDefault(() => true)),
|
|
20
|
+
|
|
21
|
+
recordMode: Schema.optional(
|
|
22
|
+
Schema.Literal('toggle', 'hold').annotations({
|
|
23
|
+
title: 'Record mode',
|
|
24
|
+
description:
|
|
25
|
+
'Whether the mic toggles recording on each click, or records only while the control is held (push-to-talk).',
|
|
26
|
+
}),
|
|
27
|
+
).pipe(Schema.withConstructorDefault(() => 'toggle' as const)),
|
|
28
|
+
|
|
29
|
+
audioDeviceId: Schema.optional(
|
|
30
|
+
Schema.String.annotations({
|
|
31
|
+
title: 'Audio input device',
|
|
32
|
+
description: 'Identifier of the microphone to capture from; empty uses the system default.',
|
|
33
|
+
}),
|
|
34
|
+
),
|
|
35
|
+
|
|
36
|
+
transcribeAfterMs: Schema.optional(
|
|
37
|
+
Schema.Number.annotations({
|
|
38
|
+
title: 'Initial buffering (ms)',
|
|
39
|
+
description: 'How long to accumulate audio before producing the first transcription.',
|
|
40
|
+
}),
|
|
41
|
+
).pipe(Schema.withConstructorDefault(() => 4000)),
|
|
42
|
+
|
|
43
|
+
streamMode: Schema.optional(
|
|
44
|
+
Schema.Literal('batch', 'word').annotations({
|
|
45
|
+
title: 'Reveal mode',
|
|
46
|
+
description: 'Whether transcribed text appears in batches or streams word-by-word.',
|
|
47
|
+
}),
|
|
48
|
+
).pipe(Schema.withConstructorDefault(() => 'word' as const)),
|
|
49
|
+
|
|
50
|
+
wordIntervalMs: Schema.optional(
|
|
51
|
+
Schema.Number.annotations({
|
|
52
|
+
title: 'Word interval (ms)',
|
|
53
|
+
description: 'Pacing between words when streaming word-by-word.',
|
|
54
|
+
}),
|
|
55
|
+
).pipe(Schema.withConstructorDefault(() => 80)),
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
export interface Settings extends Schema.Schema.Type<typeof Settings> {}
|
|
@@ -9,12 +9,14 @@ import * as Schema from 'effect/Schema';
|
|
|
9
9
|
import { AiService } from '@dxos/ai';
|
|
10
10
|
import { SpaceSchema } from '@dxos/client/echo';
|
|
11
11
|
import { Operation } from '@dxos/compute';
|
|
12
|
-
import { Database,
|
|
13
|
-
|
|
12
|
+
import { Database, DXN, Ref, Type } from '@dxos/echo';
|
|
13
|
+
// Message and Person are used via Type.getSchema(Message.Message); they also appear in emitted .d.ts.
|
|
14
|
+
// eslint-disable-next-line unused-imports/no-unused-imports
|
|
15
|
+
import { Message, type Person, Transcript } from '@dxos/types';
|
|
14
16
|
|
|
15
17
|
import { meta } from '#meta';
|
|
16
18
|
|
|
17
|
-
const makeKey = (name: string) => DXN.make(`${meta.
|
|
19
|
+
const makeKey = (name: string) => DXN.make(`${meta.profile.key}.operation.${name}`);
|
|
18
20
|
|
|
19
21
|
export const Create = Operation.make({
|
|
20
22
|
meta: { key: makeKey('create'), name: 'Create Transcript', icon: 'ph--microphone--regular' },
|
|
@@ -53,7 +55,7 @@ export const Open = Operation.make({
|
|
|
53
55
|
output: Schema.Struct({
|
|
54
56
|
content: Schema.String,
|
|
55
57
|
}),
|
|
56
|
-
services: [Database.Service
|
|
58
|
+
services: [Database.Service],
|
|
57
59
|
});
|
|
58
60
|
|
|
59
61
|
export const Summarize = Operation.make({
|
|
@@ -77,6 +79,22 @@ export const Summarize = Operation.make({
|
|
|
77
79
|
}),
|
|
78
80
|
}),
|
|
79
81
|
services: [AiService.AiService],
|
|
82
|
+
}).pipe(Operation.visible);
|
|
83
|
+
|
|
84
|
+
export const EnrichMessage = Operation.make({
|
|
85
|
+
meta: {
|
|
86
|
+
key: DXN.make('org.dxos.function.transcription.enrichMessage'),
|
|
87
|
+
name: 'Enrich Transcript Message',
|
|
88
|
+
description: 'Extract proper nouns from a transcript message and link them to objects in the space.',
|
|
89
|
+
icon: 'ph--text-t--regular',
|
|
90
|
+
},
|
|
91
|
+
input: Schema.Struct({
|
|
92
|
+
message: Type.getSchema(Message.Message),
|
|
93
|
+
}),
|
|
94
|
+
output: Schema.Struct({
|
|
95
|
+
message: Type.getSchema(Message.Message),
|
|
96
|
+
}),
|
|
97
|
+
services: [AiService.AiService, Database.Service],
|
|
80
98
|
});
|
|
81
99
|
|
|
82
100
|
export const SentenceNormalizationInput = Schema.Struct({
|
|
@@ -4,36 +4,77 @@
|
|
|
4
4
|
|
|
5
5
|
// @import-as-namespace
|
|
6
6
|
|
|
7
|
+
import { type Atom } from '@effect-atom/atom-react';
|
|
8
|
+
|
|
7
9
|
import { Capability } from '@dxos/app-framework';
|
|
10
|
+
import { type Space } from '@dxos/client/echo';
|
|
11
|
+
import { type Feed } from '@dxos/echo';
|
|
12
|
+
import { type EntityLookup as EntityLookupFn } from '@dxos/transcription-pipeline';
|
|
13
|
+
import { type Message } from '@dxos/types';
|
|
8
14
|
|
|
9
15
|
import { meta } from '#meta';
|
|
10
16
|
|
|
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 TranscriberProviderProps = {
|
|
20
|
-
audioStreamTrack: MediaStreamTrack;
|
|
21
|
-
recorderConfig?: Partial<MediaStreamRecorderProps['config']>;
|
|
22
|
-
transcriberConfig?: Partial<TranscriberProps['config']>;
|
|
23
|
-
onSegments: TranscriberProps['onSegments'];
|
|
24
|
-
transcribe?: TranscriberProps['transcribe'];
|
|
25
|
-
};
|
|
17
|
+
import * as SettingsModule from './Settings';
|
|
26
18
|
|
|
27
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Enriches a transcript message before it is written to the feed (e.g. entity linking).
|
|
21
|
+
*/
|
|
22
|
+
export type TranscriptMessageEnricher = (message: Message.Message) => Promise<Message.Message>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Service contract for the meeting transcription manager. Consumers (e.g. plugin-meeting) depend on
|
|
26
|
+
* this interface via the {@link TranscriptionManagerProvider} capability, not on the concrete
|
|
27
|
+
* implementation, keeping the manager's browser/SDK dependencies out of consumer packages.
|
|
28
|
+
*/
|
|
29
|
+
export interface TranscriptionManager {
|
|
30
|
+
readonly enabled: Atom.Atom<boolean>;
|
|
31
|
+
setFeed(space: Space, feed: Feed.Feed): void;
|
|
32
|
+
setAudioTrack(track?: MediaStreamTrack): Promise<void>;
|
|
33
|
+
setRecording(recording?: boolean): void;
|
|
34
|
+
setEnabled(enabled: boolean): Promise<void>;
|
|
35
|
+
open(): Promise<this>;
|
|
36
|
+
close(): Promise<this>;
|
|
37
|
+
}
|
|
28
38
|
|
|
29
39
|
export type TranscriptionManagerProviderProps = {
|
|
30
40
|
messageEnricher?: TranscriptMessageEnricher;
|
|
31
41
|
};
|
|
32
42
|
|
|
33
|
-
export type TranscriptionManagerProvider = (props: TranscriptionManagerProviderProps) =>
|
|
34
|
-
|
|
35
|
-
export const TranscriberProvider = Capability.make<TranscriberProvider>(`${meta.id}.capability.transcriber`);
|
|
43
|
+
export type TranscriptionManagerProvider = (props: TranscriptionManagerProviderProps) => TranscriptionManager;
|
|
36
44
|
|
|
37
45
|
export const TranscriptionManagerProvider = Capability.make<TranscriptionManagerProvider>(
|
|
38
|
-
`${meta.
|
|
46
|
+
`${meta.profile.key}.capability.transcription-manager`,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export const Settings = Capability.make<Atom.Writable<SettingsModule.Settings>>(
|
|
50
|
+
`${meta.profile.key}.capability.settings`,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The single active editor transcription session. `id` is the editor's attendable id (the key it
|
|
55
|
+
* registered under in `MarkdownCapabilities.EditorViews`); `recording` gates audio capture. `null`
|
|
56
|
+
* when no session is active.
|
|
57
|
+
*/
|
|
58
|
+
export type RecordingSession = { id: string; recording: boolean };
|
|
59
|
+
|
|
60
|
+
export const RecordingSession = Capability.make<Atom.Writable<RecordingSession | null>>(
|
|
61
|
+
`${meta.profile.key}.capability.recording-session`,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Resolves entity references for live-transcription enrichment. Backend-agnostic (full-text, vector,
|
|
66
|
+
* a remote service, …) so the headless driver depends on the function, not the database.
|
|
67
|
+
*/
|
|
68
|
+
export type EntityLookup = EntityLookupFn;
|
|
69
|
+
|
|
70
|
+
export const EntityLookup = Capability.make<EntityLookupFn>(`${meta.profile.key}.capability.entity-lookup`);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Live transcription lifecycle, published by the driver for observers (toolbar spinner, testbench):
|
|
74
|
+
* `recording` (mic capturing) → `draining` (mic off, finishing the pipeline) → `idle`.
|
|
75
|
+
*/
|
|
76
|
+
export type PipelinePhase = 'idle' | 'recording' | 'draining';
|
|
77
|
+
|
|
78
|
+
export const PipelineStatus = Capability.make<Atom.Writable<{ phase: PipelinePhase }>>(
|
|
79
|
+
`${meta.profile.key}.capability.pipeline-status`,
|
|
39
80
|
);
|
package/src/types/index.ts
CHANGED
package/src/util/index.ts
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/containers/TranscriptionArticle/TranscriptionArticle.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React from 'react';\n\nimport { type AppSurface } from '@dxos/app-toolkit/ui';\nimport { Filter, Obj, Query } from '@dxos/echo';\nimport { useMembers, useQuery } from '@dxos/react-client/echo';\nimport { Panel } from '@dxos/react-ui';\nimport { Menu, MenuBuilder, useMenuBuilder } from '@dxos/react-ui-menu';\nimport { Message, type Transcript } from '@dxos/types';\n\nimport { Transcription } from '#components';\nimport { useFeedModelAdapter, useTranscriptionRecording } from '#hooks';\nimport { meta } from '#meta';\n\nimport { renderByline } from '../../util';\n\nexport type TranscriptionArticleProps = AppSurface.ObjectArticleProps<Transcript.Transcript>;\n\nexport const TranscriptionArticle = ({ role, subject: transcript, attendableId }: TranscriptionArticleProps) => {\n const db = Obj.getDatabase(transcript);\n const members = useMembers(db?.spaceId).map((member) => member.identity);\n const feed = transcript.feed.target;\n const messages = useQuery(\n db,\n feed ? Query.select(Filter.type(Message.Message)).from(feed) : Query.select(Filter.nothing()),\n );\n const model = useFeedModelAdapter(renderByline(members), messages);\n const { recording, toggleRecording } = useTranscriptionRecording(transcript);\n\n const menuActions = useMenuBuilder(\n () =>\n MenuBuilder.make()\n .action(\n 'toggle-recording',\n {\n label: [recording ? 'stop-recording.label' : 'start-recording.label', { ns: meta.id }],\n icon: recording ? 'ph--stop-circle--regular' : 'ph--microphone--regular',\n disposition: 'toolbar',\n testId: 'transcription.toggle-recording',\n },\n toggleRecording,\n )\n .build(),\n [recording, toggleRecording],\n );\n\n return (\n <Panel.Root role={role}>\n <Menu.Root {...menuActions} attendableId={attendableId}>\n <Panel.Toolbar asChild>\n <Menu.Toolbar />\n </Panel.Toolbar>\n </Menu.Root>\n <Panel.Content asChild>\n <Transcription model={model} transcript={transcript} />\n </Panel.Content>\n </Panel.Root>\n );\n};\n"],
|
|
5
|
-
"mappings": ";;;;;;AAIA,OAAOA,WAAW;AAGlB,SAASC,QAAQC,KAAKC,aAAa;AACnC,SAASC,YAAYC,gBAAgB;AACrC,SAASC,aAAa;AACtB,SAASC,MAAMC,aAAaC,sBAAsB;AAClD,SAASC,eAAgC;AAEzC,SAASC,qBAAqB;AAC9B,SAASC,qBAAqBC,iCAAiC;AAC/D,SAASC,YAAY;AAMd,IAAMC,uBAAuB,CAAC,EAAEC,MAAMC,SAASC,YAAYC,aAAY,MAA6B;AACzG,QAAMC,KAAKC,IAAIC,YAAYJ,UAAAA;AAC3B,QAAMK,UAAUC,WAAWJ,IAAIK,OAAAA,EAASC,IAAI,CAACC,WAAWA,OAAOC,QAAQ;AACvE,QAAMC,OAAOX,WAAWW,KAAKC;AAC7B,QAAMC,WAAWC,SACfZ,IACAS,OAAOI,MAAMC,OAAOC,OAAOC,KAAKC,QAAQA,OAAO,CAAA,EAAGC,KAAKT,IAAAA,IAAQI,MAAMC,OAAOC,OAAOI,QAAO,CAAA,CAAA;AAE5F,QAAMC,QAAQC,oBAAoBC,aAAanB,OAAAA,GAAUQ,QAAAA;AACzD,QAAM,EAAEY,WAAWC,gBAAe,IAAKC,0BAA0B3B,UAAAA;AAEjE,QAAM4B,cAAcC,eAClB,MACEC,YAAYC,KAAI,EACbC,OACC,oBACA;IACEC,OAAO;MAACR,YAAY,yBAAyB;MAAyB;QAAES,IAAIC,KAAKC;MAAG;;IACpFC,MAAMZ,YAAY,6BAA6B;IAC/Ca,aAAa;IACbC,QAAQ;EACV,GACAb,eAAAA,EAEDc,MAAK,GACV;IAACf;IAAWC;GAAgB;AAG9B,SACE,sBAAA,cAACe,MAAMC,MAAI;IAAC5C;KACV,sBAAA,cAAC6C,KAAKD,MAAI;IAAE,GAAGd;IAAa3B;KAC1B,sBAAA,cAACwC,MAAMG,SAAO;IAACC,SAAAA;KACb,sBAAA,cAACF,KAAKC,SAAO,IAAA,CAAA,CAAA,GAGjB,sBAAA,cAACH,MAAMK,SAAO;IAACD,SAAAA;KACb,sBAAA,cAACE,eAAAA;IAAczB;IAActB;;AAIrC;",
|
|
6
|
-
"names": ["React", "Filter", "Obj", "Query", "useMembers", "useQuery", "Panel", "Menu", "MenuBuilder", "useMenuBuilder", "Message", "Transcription", "useFeedModelAdapter", "useTranscriptionRecording", "meta", "TranscriptionArticle", "role", "subject", "transcript", "attendableId", "db", "Obj", "getDatabase", "members", "useMembers", "spaceId", "map", "member", "identity", "feed", "target", "messages", "useQuery", "Query", "select", "Filter", "type", "Message", "from", "nothing", "model", "useFeedModelAdapter", "renderByline", "recording", "toggleRecording", "useTranscriptionRecording", "menuActions", "useMenuBuilder", "MenuBuilder", "make", "action", "label", "ns", "meta", "id", "icon", "disposition", "testId", "build", "Panel", "Root", "Menu", "Toolbar", "asChild", "Content", "Transcription"]
|
|
7
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import "./chunk-J5LGTIGS.mjs";
|
|
2
|
-
|
|
3
|
-
// src/capabilities/blueprint-definition.ts
|
|
4
|
-
import * as Effect from "effect/Effect";
|
|
5
|
-
import { Capability } from "@dxos/app-framework";
|
|
6
|
-
import { AppCapabilities } from "@dxos/app-toolkit";
|
|
7
|
-
import { TranscriptionBlueprint } from "#blueprints";
|
|
8
|
-
var blueprintDefinition = () => Effect.succeed([
|
|
9
|
-
Capability.contributes(AppCapabilities.BlueprintDefinition, TranscriptionBlueprint)
|
|
10
|
-
]);
|
|
11
|
-
var blueprint_definition_default = blueprintDefinition;
|
|
12
|
-
export {
|
|
13
|
-
blueprint_definition_default as default
|
|
14
|
-
};
|
|
15
|
-
//# sourceMappingURL=blueprint-definition-DA4QFRYJ.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/blueprint-definition.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { AppCapabilities } from '@dxos/app-toolkit';\n\nimport { TranscriptionBlueprint } from '#blueprints';\n\n// NOTE: Explicit annotation required: d.ts emit cannot portably name the inferred @dxos/compute types (TS2883).\nconst blueprintDefinition: () => Effect.Effect<\n Capability.Capability<typeof AppCapabilities.BlueprintDefinition>[],\n never,\n Capability.Service\n> = () => Effect.succeed([Capability.contributes(AppCapabilities.BlueprintDefinition, TranscriptionBlueprint)]);\n\nexport default blueprintDefinition;\n"],
|
|
5
|
-
"mappings": ";;;AAIA,YAAYA,YAAY;AAExB,SAASC,kBAAkB;AAC3B,SAASC,uBAAuB;AAEhC,SAASC,8BAA8B;AAGvC,IAAMC,sBAIF,MAAaC,eAAQ;EAACJ,WAAWK,YAAYJ,gBAAgBK,qBAAqBJ,sBAAAA;CAAwB;AAE9G,IAAA,+BAAeC;",
|
|
6
|
-
"names": ["Effect", "Capability", "AppCapabilities", "TranscriptionBlueprint", "blueprintDefinition", "succeed", "contributes", "BlueprintDefinition"]
|
|
7
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// src/meta.ts
|
|
2
|
-
import { Plugin } from "@dxos/app-framework";
|
|
3
|
-
import { DXN } from "@dxos/keys";
|
|
4
|
-
import { trim } from "@dxos/util";
|
|
5
|
-
var meta = Plugin.makeMeta({
|
|
6
|
-
key: DXN.make("org.dxos.plugin.transcription"),
|
|
7
|
-
name: "Transcription",
|
|
8
|
-
author: "DXOS",
|
|
9
|
-
description: trim`
|
|
10
|
-
Real-time voice-to-text transcription for DXOS Composer.
|
|
11
|
-
Captures microphone audio in short PCM chunks, batches them into WAV payloads, and streams
|
|
12
|
-
the results to a Whisper-compatible speech-recognition endpoint.
|
|
13
|
-
Transcribed segments are timestamped, deduplicated across chunk boundaries, and persisted
|
|
14
|
-
as Message objects in an ECHO Feed so that every participant in a shared space sees the
|
|
15
|
-
live transcript without any manual sync step.
|
|
16
|
-
|
|
17
|
-
Each recording session is represented as a Transcript object linked to its Feed.
|
|
18
|
-
The read-only editor renders messages with speaker bylines and wall-clock timestamps,
|
|
19
|
-
supporting markdown decoration and document preview.
|
|
20
|
-
An optional message enricher pipeline lets plugins annotate messages before they are
|
|
21
|
-
committed — for example, to attach speaker identity from a calls service.
|
|
22
|
-
|
|
23
|
-
The plugin ships two blueprint-compatible operations: Open (loads and formats a transcript
|
|
24
|
-
for reading by an AI assistant) and Summarize (sends the transcript text to an LLM and
|
|
25
|
-
returns a structured Markdown summary with key points, verbatim quotes, and actionable
|
|
26
|
-
tasks extracted from the conversation).
|
|
27
|
-
|
|
28
|
-
A sentence-normalization pass merges raw word-level tokens from the recognizer into
|
|
29
|
-
grammatically complete sentences, improving readability of the stored transcript without
|
|
30
|
-
altering the underlying audio timeline.
|
|
31
|
-
`,
|
|
32
|
-
icon: "ph--microphone--regular",
|
|
33
|
-
iconHue: "sky",
|
|
34
|
-
source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-transcription",
|
|
35
|
-
spec: "PLUGIN.mdl",
|
|
36
|
-
tags: [
|
|
37
|
-
"labs"
|
|
38
|
-
],
|
|
39
|
-
screenshots: []
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
export {
|
|
43
|
-
meta
|
|
44
|
-
};
|
|
45
|
-
//# sourceMappingURL=chunk-FHNI26QW.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/meta.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\nimport { DXN } from '@dxos/keys';\nimport { trim } from '@dxos/util';\n\nexport const meta = Plugin.makeMeta({\n key: DXN.make('org.dxos.plugin.transcription'),\n name: 'Transcription',\n author: 'DXOS',\n description: trim`\n Real-time voice-to-text transcription for DXOS Composer.\n Captures microphone audio in short PCM chunks, batches them into WAV payloads, and streams\n the results to a Whisper-compatible speech-recognition endpoint.\n Transcribed segments are timestamped, deduplicated across chunk boundaries, and persisted\n as Message objects in an ECHO Feed so that every participant in a shared space sees the\n live transcript without any manual sync step.\n\n Each recording session is represented as a Transcript object linked to its Feed.\n The read-only editor renders messages with speaker bylines and wall-clock timestamps,\n supporting markdown decoration and document preview.\n An optional message enricher pipeline lets plugins annotate messages before they are\n committed — for example, to attach speaker identity from a calls service.\n\n The plugin ships two blueprint-compatible operations: Open (loads and formats a transcript\n for reading by an AI assistant) and Summarize (sends the transcript text to an LLM and\n returns a structured Markdown summary with key points, verbatim quotes, and actionable\n tasks extracted from the conversation).\n\n A sentence-normalization pass merges raw word-level tokens from the recognizer into\n grammatically complete sentences, improving readability of the stored transcript without\n altering the underlying audio timeline.\n `,\n icon: 'ph--microphone--regular',\n iconHue: 'sky',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-transcription',\n spec: 'PLUGIN.mdl',\n tags: ['labs'],\n screenshots: [],\n});\n"],
|
|
5
|
-
"mappings": ";AAIA,SAASA,cAAc;AACvB,SAASC,WAAW;AACpB,SAASC,YAAY;AAEd,IAAMC,OAAOH,OAAOI,SAAS;EAClCC,KAAKJ,IAAIK,KAAK,+BAAA;EACdC,MAAM;EACNC,QAAQ;EACRC,aAAaP;;;;;;;;;;;;;;;;;;;;;;;EAuBbQ,MAAM;EACNC,SAAS;EACTC,QAAQ;EACRC,MAAM;EACNC,MAAM;IAAC;;EACPC,aAAa,CAAA;AACf,CAAA;",
|
|
6
|
-
"names": ["Plugin", "DXN", "trim", "meta", "makeMeta", "key", "make", "name", "author", "description", "icon", "iconHue", "source", "spec", "tags", "screenshots"]
|
|
7
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
// src/util/render-byline.ts
|
|
2
|
-
var renderByline = (identities) => (message, index, debug = false) => {
|
|
3
|
-
if (message.sender.role === "assistant") {
|
|
4
|
-
return [
|
|
5
|
-
message.blocks.find((block) => block._tag === "transcript")?.text ?? "",
|
|
6
|
-
""
|
|
7
|
-
];
|
|
8
|
-
}
|
|
9
|
-
const identity = identities.find((identity2) => identity2.did === message.sender.identityDid);
|
|
10
|
-
const name = identity?.profile?.displayName ?? message.sender.contact?.target?.fullName ?? message.sender.name ?? message.sender.email ?? message.sender.identityDid;
|
|
11
|
-
const blocks = message.blocks.filter((block) => block._tag === "transcript");
|
|
12
|
-
return [
|
|
13
|
-
// TODO(thure): Use an XML tag with the bits needed here.
|
|
14
|
-
`###### ${name}` + (debug ? ` [${index}]:${message.id}` : ""),
|
|
15
|
-
blocks.map((block) => block.text.trim()).join(" "),
|
|
16
|
-
""
|
|
17
|
-
];
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
// src/util/array.ts
|
|
21
|
-
var mergeFloat64Arrays = (arrays) => {
|
|
22
|
-
const newArray = new Float64Array(arrays.reduce((acc, array) => array.length + acc, 0));
|
|
23
|
-
let offset = 0;
|
|
24
|
-
for (const array of arrays) {
|
|
25
|
-
newArray.set(array, offset);
|
|
26
|
-
offset += array.length;
|
|
27
|
-
}
|
|
28
|
-
return newArray;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export {
|
|
32
|
-
mergeFloat64Arrays,
|
|
33
|
-
renderByline
|
|
34
|
-
};
|
|
35
|
-
//# sourceMappingURL=chunk-KAEXRX3Y.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/util/render-byline.ts", "../../../src/util/array.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Identity } from '@dxos/react-client/halo';\nimport { type Message } from '@dxos/types';\n\n// TODO(thure): Move this?\nexport const renderByline =\n (identities: Identity[]) =>\n (message: Message.Message, index: number, debug = false): string[] => {\n if (message.sender.role === 'assistant') {\n // Start/stop block.\n return [message.blocks.find((block) => block._tag === 'transcript')?.text ?? '', ''];\n }\n\n // TODO(burdon): Use link/reference markup for users (with popover).\n // TODO(burdon): Color and avatar.\n const identity = identities.find((identity) => identity.did === message.sender.identityDid);\n const name =\n identity?.profile?.displayName ??\n message.sender.contact?.target?.fullName ??\n message.sender.name ??\n message.sender.email ??\n message.sender.identityDid;\n const blocks = message.blocks.filter((block) => block._tag === 'transcript');\n return [\n // TODO(thure): Use an XML tag with the bits needed here.\n `###### ${name}` + (debug ? ` [${index}]:${message.id}` : ''),\n blocks.map((block) => block.text.trim()).join(' '),\n '',\n ];\n };\n", "//\n// Copyright 2025 DXOS.org\n//\n\nexport const mergeFloat64Arrays = (arrays: Float64Array[]) => {\n const newArray = new Float64Array(arrays.reduce((acc, array) => array.length + acc, 0));\n let offset = 0;\n for (const array of arrays) {\n newArray.set(array, offset);\n offset += array.length;\n }\n\n return newArray;\n};\n"],
|
|
5
|
-
"mappings": ";AAQO,IAAMA,eACX,CAACC,eACD,CAACC,SAA0BC,OAAeC,QAAQ,UAAK;AACrD,MAAIF,QAAQG,OAAOC,SAAS,aAAa;AAEvC,WAAO;MAACJ,QAAQK,OAAOC,KAAK,CAACC,UAAUA,MAAMC,SAAS,YAAA,GAAeC,QAAQ;MAAI;;EACnF;AAIA,QAAMC,WAAWX,WAAWO,KAAK,CAACI,cAAaA,UAASC,QAAQX,QAAQG,OAAOS,WAAW;AAC1F,QAAMC,OACJH,UAAUI,SAASC,eACnBf,QAAQG,OAAOa,SAASC,QAAQC,YAChClB,QAAQG,OAAOU,QACfb,QAAQG,OAAOgB,SACfnB,QAAQG,OAAOS;AACjB,QAAMP,SAASL,QAAQK,OAAOe,OAAO,CAACb,UAAUA,MAAMC,SAAS,YAAA;AAC/D,SAAO;;IAEL,UAAUK,IAAAA,MAAUX,QAAQ,KAAKD,KAAAA,KAAUD,QAAQqB,EAAE,KAAK;IAC1DhB,OAAOiB,IAAI,CAACf,UAAUA,MAAME,KAAKc,KAAI,CAAA,EAAIC,KAAK,GAAA;IAC9C;;AAEJ;;;AC5BK,IAAMC,qBAAqB,CAACC,WAAAA;AACjC,QAAMC,WAAW,IAAIC,aAAaF,OAAOG,OAAO,CAACC,KAAKC,UAAUA,MAAMC,SAASF,KAAK,CAAA,CAAA;AACpF,MAAIG,SAAS;AACb,aAAWF,SAASL,QAAQ;AAC1BC,aAASO,IAAIH,OAAOE,MAAAA;AACpBA,cAAUF,MAAMC;EAClB;AAEA,SAAOL;AACT;",
|
|
6
|
-
"names": ["renderByline", "identities", "message", "index", "debug", "sender", "role", "blocks", "find", "block", "_tag", "text", "identity", "did", "identityDid", "name", "profile", "displayName", "contact", "target", "fullName", "email", "filter", "id", "map", "trim", "join", "mergeFloat64Arrays", "arrays", "newArray", "Float64Array", "reduce", "acc", "array", "length", "offset", "set"]
|
|
7
|
-
}
|