@dxos/plugin-transcription 0.8.2-staging.7ac8446 → 0.8.3-main.672df60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/TranscriptContainer-3EH6QHPJ.mjs +11 -0
- package/dist/lib/browser/{chunk-K7FOYAXO.mjs → chunk-DL2276CA.mjs} +2 -2
- package/dist/lib/browser/{chunk-6ZR5MDK3.mjs → chunk-GOF7MJNV.mjs} +3 -3
- package/dist/lib/browser/{chunk-6ZR5MDK3.mjs.map → chunk-GOF7MJNV.mjs.map} +1 -1
- package/dist/lib/browser/{chunk-YCZISX63.mjs → chunk-LMLE2QYX.mjs} +130 -99
- package/dist/lib/browser/chunk-LMLE2QYX.mjs.map +7 -0
- package/dist/lib/browser/chunk-NODIXNQP.mjs +54 -0
- package/dist/lib/browser/chunk-NODIXNQP.mjs.map +7 -0
- package/dist/lib/browser/chunk-RULOUJHH.mjs +764 -0
- package/dist/lib/browser/chunk-RULOUJHH.mjs.map +7 -0
- package/dist/lib/browser/{chunk-YEPT334A.mjs → chunk-W2KNYJD6.mjs} +4 -4
- package/dist/lib/browser/chunk-W2KNYJD6.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +31 -219
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/{intent-resolver-4R66ZCKT.mjs → intent-resolver-I2LJSQDR.mjs} +7 -11
- package/dist/lib/browser/intent-resolver-I2LJSQDR.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-FQUHU5G7.mjs → react-surface-FPVBUAW4.mjs} +11 -9
- package/dist/lib/browser/react-surface-FPVBUAW4.mjs.map +7 -0
- package/dist/lib/browser/transcriber-KV5VJ6EZ.mjs +56 -0
- package/dist/lib/browser/transcriber-KV5VJ6EZ.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +4 -8
- package/dist/lib/node/{TranscriptContainer-QEYTTT2V.cjs → TranscriptContainer-JXOIM6N6.cjs} +9 -8
- package/dist/lib/node/TranscriptContainer-JXOIM6N6.cjs.map +7 -0
- package/dist/lib/node/{chunk-NVZWGFJL.cjs → chunk-AFUZI63A.cjs} +6 -6
- package/dist/lib/node/{chunk-NVZWGFJL.cjs.map → chunk-AFUZI63A.cjs.map} +1 -1
- package/dist/lib/node/chunk-CQSQI53U.cjs +778 -0
- package/dist/lib/node/chunk-CQSQI53U.cjs.map +7 -0
- package/dist/lib/node/chunk-EIMUQYCZ.cjs +74 -0
- package/dist/lib/node/chunk-EIMUQYCZ.cjs.map +7 -0
- package/dist/lib/node/{chunk-CZMLKKWT.cjs → chunk-FKDJNJ57.cjs} +8 -8
- package/dist/lib/node/chunk-FKDJNJ57.cjs.map +7 -0
- package/dist/lib/node/{chunk-LP4FG423.cjs → chunk-IY6IM7GC.cjs} +5 -5
- package/dist/lib/node/{chunk-FCCJALOT.cjs → chunk-JABOFOJ5.cjs} +129 -99
- package/dist/lib/node/chunk-JABOFOJ5.cjs.map +7 -0
- package/dist/lib/node/index.cjs +60 -254
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/{intent-resolver-WMMCOUEH.cjs → intent-resolver-LLMGF5I5.cjs} +10 -11
- package/dist/lib/node/intent-resolver-LLMGF5I5.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-surface-WI2MGWCC.cjs → react-surface-REQZMCYO.cjs} +13 -11
- package/dist/lib/node/react-surface-REQZMCYO.cjs.map +7 -0
- package/dist/lib/node/transcriber-ZSDN6GMP.cjs +68 -0
- package/dist/lib/node/transcriber-ZSDN6GMP.cjs.map +7 -0
- package/dist/lib/node/types/index.cjs +7 -11
- package/dist/lib/node/types/index.cjs.map +2 -2
- package/dist/lib/node-esm/{TranscriptContainer-ZXUCOWGY.mjs → TranscriptContainer-K5VZZ4OB.mjs} +4 -3
- package/dist/lib/node-esm/chunk-BRPFVRAD.mjs +55 -0
- package/dist/lib/node-esm/chunk-BRPFVRAD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-YQYBLFNI.mjs → chunk-GD5IZDKD.mjs} +130 -99
- package/dist/lib/node-esm/chunk-GD5IZDKD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-PTZHDZ36.mjs → chunk-MFJPEIVB.mjs} +4 -4
- package/dist/lib/node-esm/chunk-MFJPEIVB.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-J4D2RBBH.mjs → chunk-SKK7VDQZ.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-X4DDJIVL.mjs → chunk-TXMDLLBR.mjs} +3 -3
- package/dist/lib/node-esm/{chunk-X4DDJIVL.mjs.map → chunk-TXMDLLBR.mjs.map} +1 -1
- package/dist/lib/node-esm/chunk-V54MCG5P.mjs +765 -0
- package/dist/lib/node-esm/chunk-V54MCG5P.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +31 -219
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/{intent-resolver-QN2LO5TX.mjs → intent-resolver-WOZKOEBW.mjs} +7 -11
- package/dist/lib/node-esm/intent-resolver-WOZKOEBW.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-PCH6NTVB.mjs → react-surface-ROQN77NT.mjs} +11 -9
- package/dist/lib/node-esm/react-surface-ROQN77NT.mjs.map +7 -0
- package/dist/lib/node-esm/transcriber-JHPFZVJJ.mjs +57 -0
- package/dist/lib/node-esm/transcriber-JHPFZVJJ.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +4 -8
- package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts +8 -10
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +2 -183
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/transcriber.d.ts +2 -1
- package/dist/types/src/capabilities/transcriber.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/Transcript.d.ts +14 -4
- package/dist/types/src/components/Transcript/Transcript.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts +19 -4
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +27 -0
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +1 -0
- package/dist/types/src/components/Transcript/transcript-extension.d.ts +19 -0
- package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +1 -0
- package/dist/types/src/components/TranscriptContainer.d.ts.map +1 -1
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts +17 -0
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +1 -0
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts +10 -0
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +1 -0
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts +19 -0
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +1 -0
- package/dist/types/src/components/stories/TranscriptionStory.d.ts +11 -0
- package/dist/types/src/components/stories/TranscriptionStory.d.ts.map +1 -0
- package/dist/types/src/components/stories/useIsSpeaking.d.ts +3 -0
- package/dist/types/src/components/stories/useIsSpeaking.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useAudioFile.d.ts +1 -1
- package/dist/types/src/hooks/useAudioFile.d.ts.map +1 -1
- package/dist/types/src/hooks/useAudioTrack.d.ts +1 -1
- package/dist/types/src/hooks/useAudioTrack.d.ts.map +1 -1
- package/dist/types/src/hooks/useQueueModelAdapter.d.ts +7 -0
- package/dist/types/src/hooks/useQueueModelAdapter.d.ts.map +1 -0
- package/dist/types/src/hooks/useTranscriber.d.ts +1 -1
- package/dist/types/src/hooks/useTranscriber.d.ts.map +1 -1
- package/dist/types/src/hooks/useVoiceInput.d.ts.map +1 -1
- package/dist/types/src/model/index.d.ts +2 -0
- package/dist/types/src/model/index.d.ts.map +1 -0
- package/dist/types/src/model/model.d.ts +68 -0
- package/dist/types/src/model/model.d.ts.map +1 -0
- package/dist/types/src/model/model.test.d.ts +2 -0
- package/dist/types/src/model/model.test.d.ts.map +1 -0
- package/dist/types/src/segments-normalization/index.d.ts +4 -0
- package/dist/types/src/segments-normalization/index.d.ts.map +1 -0
- package/dist/types/src/segments-normalization/message-normalizer.d.ts +26 -0
- package/dist/types/src/segments-normalization/message-normalizer.d.ts.map +1 -0
- package/dist/types/src/segments-normalization/normalization.d.ts +520 -0
- package/dist/types/src/segments-normalization/normalization.d.ts.map +1 -0
- package/dist/types/src/segments-normalization/normalization.test.d.ts +2 -0
- package/dist/types/src/segments-normalization/normalization.test.d.ts.map +1 -0
- package/dist/types/src/segments-normalization/utils.d.ts +3 -0
- package/dist/types/src/segments-normalization/utils.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/testing.d.ts +40 -0
- package/dist/types/src/testing/testing.d.ts.map +1 -0
- package/dist/types/src/transcriber/media-stream-recorder.d.ts +8 -5
- package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcriber.browser.test.d.ts +2 -0
- package/dist/types/src/transcriber/transcriber.browser.test.d.ts.map +1 -0
- package/dist/types/src/transcriber/transcriber.d.ts +6 -2
- package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcription-manager.d.ts +20 -16
- package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +3 -20
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +23 -40
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +15 -8
- package/dist/types/src/types/types.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 +0 -1
- 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/tsconfig.tsbuildinfo +1 -1
- package/package.json +62 -41
- package/src/TranscriptionPlugin.tsx +14 -21
- package/src/capabilities/capabilities.ts +15 -8
- package/src/capabilities/index.ts +0 -2
- package/src/capabilities/intent-resolver.ts +7 -8
- package/src/capabilities/react-surface.tsx +5 -4
- package/src/capabilities/transcriber.ts +34 -6
- package/src/components/Transcript/Transcript.stories.tsx +201 -43
- package/src/components/Transcript/Transcript.tsx +83 -208
- package/src/components/Transcript/deprecated/OldTranscript.tsx +260 -0
- package/src/components/Transcript/transcript-extension.ts +236 -0
- package/src/components/TranscriptContainer.tsx +11 -6
- package/src/components/stories/FileTranscription.stories.tsx +240 -0
- package/src/components/stories/KeyWordRecognition.stories.tsx +128 -0
- package/src/components/stories/MicrophoneTranscription.stories.tsx +274 -0
- package/src/components/stories/TranscriptionStory.tsx +41 -0
- package/src/components/stories/useIsSpeaking.tsx +40 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useAudioFile.ts +39 -9
- package/src/hooks/useAudioTrack.ts +2 -2
- package/src/hooks/useQueueModelAdapter.ts +65 -0
- package/src/hooks/useTranscriber.ts +4 -2
- package/src/meta.ts +2 -2
- package/src/model/index.ts +5 -0
- package/src/model/model.test.ts +169 -0
- package/src/model/model.ts +229 -0
- package/src/segments-normalization/index.ts +7 -0
- package/src/segments-normalization/message-normalizer.ts +108 -0
- package/src/segments-normalization/normalization.test.ts +142 -0
- package/src/segments-normalization/normalization.ts +103 -0
- package/src/segments-normalization/utils.ts +9 -0
- package/src/testing/index.ts +5 -0
- package/src/testing/testing.ts +216 -0
- package/src/transcriber/media-stream-recorder.ts +14 -7
- package/src/transcriber/{transcriber.test.ts → transcriber.browser.test.ts} +7 -7
- package/src/transcriber/transcriber.ts +33 -20
- package/src/transcriber/transcription-manager.ts +81 -70
- package/src/translations.ts +2 -3
- package/src/types/schema.ts +11 -33
- package/src/types/types.ts +8 -12
- package/src/util/index.ts +0 -1
- package/dist/lib/browser/TranscriptContainer-JQ3HFHLQ.mjs +0 -10
- package/dist/lib/browser/app-graph-builder-VDQOVX7P.mjs +0 -191
- package/dist/lib/browser/app-graph-builder-VDQOVX7P.mjs.map +0 -7
- package/dist/lib/browser/chunk-G4B6CPC2.mjs +0 -253
- package/dist/lib/browser/chunk-G4B6CPC2.mjs.map +0 -7
- package/dist/lib/browser/chunk-GU2BNYKZ.mjs +0 -35
- package/dist/lib/browser/chunk-GU2BNYKZ.mjs.map +0 -7
- package/dist/lib/browser/chunk-OGNXNGJB.mjs +0 -73
- package/dist/lib/browser/chunk-OGNXNGJB.mjs.map +0 -7
- package/dist/lib/browser/chunk-YCZISX63.mjs.map +0 -7
- package/dist/lib/browser/chunk-YEPT334A.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-4R66ZCKT.mjs.map +0 -7
- package/dist/lib/browser/meeting-transcription-state-DLFHQK72.mjs +0 -18
- package/dist/lib/browser/meeting-transcription-state-DLFHQK72.mjs.map +0 -7
- package/dist/lib/browser/react-surface-FQUHU5G7.mjs.map +0 -7
- package/dist/lib/browser/transcriber-LGMIWDYI.mjs +0 -36
- package/dist/lib/browser/transcriber-LGMIWDYI.mjs.map +0 -7
- package/dist/lib/node/TranscriptContainer-QEYTTT2V.cjs.map +0 -7
- package/dist/lib/node/app-graph-builder-IFSIVNUR.cjs +0 -200
- package/dist/lib/node/app-graph-builder-IFSIVNUR.cjs.map +0 -7
- package/dist/lib/node/chunk-3KHUSQNW.cjs +0 -55
- package/dist/lib/node/chunk-3KHUSQNW.cjs.map +0 -7
- package/dist/lib/node/chunk-CZMLKKWT.cjs.map +0 -7
- package/dist/lib/node/chunk-FCCJALOT.cjs.map +0 -7
- package/dist/lib/node/chunk-P4VVD6ZO.cjs +0 -95
- package/dist/lib/node/chunk-P4VVD6ZO.cjs.map +0 -7
- package/dist/lib/node/chunk-UOFHT4GZ.cjs +0 -280
- package/dist/lib/node/chunk-UOFHT4GZ.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-WMMCOUEH.cjs.map +0 -7
- package/dist/lib/node/meeting-transcription-state-URIYILEQ.cjs +0 -34
- package/dist/lib/node/meeting-transcription-state-URIYILEQ.cjs.map +0 -7
- package/dist/lib/node/react-surface-WI2MGWCC.cjs.map +0 -7
- package/dist/lib/node/transcriber-QG5WPKX4.cjs +0 -49
- package/dist/lib/node/transcriber-QG5WPKX4.cjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-UL6XLIZY.mjs +0 -192
- package/dist/lib/node-esm/app-graph-builder-UL6XLIZY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-6X7X2UZF.mjs +0 -254
- package/dist/lib/node-esm/chunk-6X7X2UZF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-GIO6J6FE.mjs +0 -74
- package/dist/lib/node-esm/chunk-GIO6J6FE.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HKATMD34.mjs +0 -37
- package/dist/lib/node-esm/chunk-HKATMD34.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PTZHDZ36.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YQYBLFNI.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-QN2LO5TX.mjs.map +0 -7
- package/dist/lib/node-esm/meeting-transcription-state-ZYVRAW6Y.mjs +0 -19
- package/dist/lib/node-esm/meeting-transcription-state-ZYVRAW6Y.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-PCH6NTVB.mjs.map +0 -7
- package/dist/lib/node-esm/transcriber-TMPYZ5L4.mjs +0 -37
- package/dist/lib/node-esm/transcriber-TMPYZ5L4.mjs.map +0 -7
- package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -181
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/capabilities/meeting-transcription-state.d.ts +0 -6
- package/dist/types/src/capabilities/meeting-transcription-state.d.ts.map +0 -1
- package/dist/types/src/components/transcription.stories.d.ts +0 -15
- package/dist/types/src/components/transcription.stories.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/util/random-queue-dxn.d.ts +0 -3
- package/dist/types/src/util/random-queue-dxn.d.ts.map +0 -1
- package/src/capabilities/app-graph-builder.ts +0 -152
- package/src/capabilities/meeting-transcription-state.ts +0 -16
- package/src/components/transcription.stories.tsx +0 -196
- package/src/util/random-queue-dxn.ts +0 -9
- /package/dist/lib/browser/{TranscriptContainer-JQ3HFHLQ.mjs.map → TranscriptContainer-3EH6QHPJ.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-K7FOYAXO.mjs.map → chunk-DL2276CA.mjs.map} +0 -0
- /package/dist/lib/node/{chunk-LP4FG423.cjs.map → chunk-IY6IM7GC.cjs.map} +0 -0
- /package/dist/lib/node-esm/{TranscriptContainer-ZXUCOWGY.mjs.map → TranscriptContainer-K5VZZ4OB.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-J4D2RBBH.mjs.map → chunk-SKK7VDQZ.mjs.map} +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TranscriptContainer_default,
|
|
3
|
+
TranscriptionContainer
|
|
4
|
+
} from "./chunk-RULOUJHH.mjs";
|
|
5
|
+
import "./chunk-W2KNYJD6.mjs";
|
|
6
|
+
import "./chunk-GOF7MJNV.mjs";
|
|
7
|
+
export {
|
|
8
|
+
TranscriptionContainer,
|
|
9
|
+
TranscriptContainer_default as default
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=TranscriptContainer-3EH6QHPJ.mjs.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// packages/plugins/plugin-transcription/src/components/index.ts
|
|
2
2
|
import { lazy } from "react";
|
|
3
|
-
var TranscriptContainer = lazy(() => import("./TranscriptContainer-
|
|
3
|
+
var TranscriptContainer = lazy(() => import("./TranscriptContainer-3EH6QHPJ.mjs"));
|
|
4
4
|
|
|
5
5
|
export {
|
|
6
6
|
TranscriptContainer
|
|
7
7
|
};
|
|
8
|
-
//# sourceMappingURL=chunk-
|
|
8
|
+
//# sourceMappingURL=chunk-DL2276CA.mjs.map
|
|
@@ -5,9 +5,9 @@ var meta = {
|
|
|
5
5
|
name: "Transcription",
|
|
6
6
|
description: "Voice transcription.",
|
|
7
7
|
icon: "ph--microphone--regular",
|
|
8
|
-
source: "https://github.com/dxos/dxos/tree/main/packages/plugins/
|
|
8
|
+
source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-transcription",
|
|
9
9
|
tags: [
|
|
10
|
-
"
|
|
10
|
+
"labs"
|
|
11
11
|
],
|
|
12
12
|
screenshots: []
|
|
13
13
|
};
|
|
@@ -16,4 +16,4 @@ export {
|
|
|
16
16
|
TRANSCRIPTION_PLUGIN,
|
|
17
17
|
meta
|
|
18
18
|
};
|
|
19
|
-
//# sourceMappingURL=chunk-
|
|
19
|
+
//# sourceMappingURL=chunk-GOF7MJNV.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/meta.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type PluginMeta } from '@dxos/app-framework';\n\nexport const TRANSCRIPTION_PLUGIN = 'dxos.org/plugin/transcription';\n\nexport const meta: PluginMeta = {\n id: TRANSCRIPTION_PLUGIN,\n name: 'Transcription',\n description: 'Voice transcription.',\n icon: 'ph--microphone--regular',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type PluginMeta } from '@dxos/app-framework';\n\nexport const TRANSCRIPTION_PLUGIN = 'dxos.org/plugin/transcription';\n\nexport const meta: PluginMeta = {\n id: TRANSCRIPTION_PLUGIN,\n name: 'Transcription',\n description: 'Voice transcription.',\n icon: 'ph--microphone--regular',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-transcription',\n tags: ['labs'],\n screenshots: [],\n};\n"],
|
|
5
5
|
"mappings": ";AAMO,IAAMA,uBAAuB;AAE7B,IAAMC,OAAmB;EAC9BC,IAAIF;EACJG,MAAM;EACNC,aAAa;EACbC,MAAM;EACNC,QAAQ;EACRC,MAAM;IAAC;;EACPC,aAAa,CAAA;AACf;",
|
|
6
6
|
"names": ["TRANSCRIPTION_PLUGIN", "meta", "id", "name", "description", "icon", "source", "tags", "screenshots"]
|
|
7
7
|
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import {
|
|
5
|
-
TRANSCRIPTION_URL,
|
|
6
|
-
TranscriptBlock
|
|
7
|
-
} from "./chunk-OGNXNGJB.mjs";
|
|
2
|
+
TRANSCRIPTION_URL
|
|
3
|
+
} from "./chunk-NODIXNQP.mjs";
|
|
8
4
|
|
|
9
5
|
// packages/plugins/plugin-transcription/src/transcriber/media-stream-recorder.ts
|
|
10
6
|
import { MediaRecorder, register } from "extendable-media-recorder";
|
|
@@ -26,11 +22,11 @@ var initializeExtendableMediaRecorder = async () => {
|
|
|
26
22
|
await register(await connect());
|
|
27
23
|
};
|
|
28
24
|
var MediaStreamRecorder = class {
|
|
29
|
-
constructor({ mediaStreamTrack,
|
|
25
|
+
constructor({ mediaStreamTrack, config }) {
|
|
30
26
|
this._mediaRecorder = void 0;
|
|
31
27
|
this._header = void 0;
|
|
32
28
|
this._mediaStreamTrack = mediaStreamTrack;
|
|
33
|
-
this.
|
|
29
|
+
this._config = config;
|
|
34
30
|
}
|
|
35
31
|
get wavConfig() {
|
|
36
32
|
const settings = this._mediaStreamTrack.getSettings();
|
|
@@ -51,7 +47,7 @@ var MediaStreamRecorder = class {
|
|
|
51
47
|
err
|
|
52
48
|
}, {
|
|
53
49
|
F: __dxlog_file,
|
|
54
|
-
L:
|
|
50
|
+
L: 69,
|
|
55
51
|
S: this,
|
|
56
52
|
C: (f, a) => f(...a)
|
|
57
53
|
}));
|
|
@@ -68,7 +64,7 @@ var MediaStreamRecorder = class {
|
|
|
68
64
|
}
|
|
69
65
|
invariant(this._onChunk, "MediaStreamRecorder: onChunk is not set", {
|
|
70
66
|
F: __dxlog_file,
|
|
71
|
-
L:
|
|
67
|
+
L: 80,
|
|
72
68
|
S: this,
|
|
73
69
|
A: [
|
|
74
70
|
"this._onChunk",
|
|
@@ -76,7 +72,7 @@ var MediaStreamRecorder = class {
|
|
|
76
72
|
]
|
|
77
73
|
});
|
|
78
74
|
this._mediaRecorder.ondataavailable = (event) => this._ondataavailable(event);
|
|
79
|
-
this._mediaRecorder.start(this.
|
|
75
|
+
this._mediaRecorder.start(this._config.interval);
|
|
80
76
|
}
|
|
81
77
|
async stop() {
|
|
82
78
|
if (this._mediaRecorder?.state !== "recording") {
|
|
@@ -103,7 +99,7 @@ var MediaStreamRecorder = class {
|
|
|
103
99
|
} else {
|
|
104
100
|
log.warn("MediaStreamRecorder: no header", void 0, {
|
|
105
101
|
F: __dxlog_file,
|
|
106
|
-
L:
|
|
102
|
+
L: 111,
|
|
107
103
|
S: this,
|
|
108
104
|
C: (f, a) => f(...a)
|
|
109
105
|
});
|
|
@@ -128,6 +124,19 @@ import { DeferredTask, Trigger } from "@dxos/async";
|
|
|
128
124
|
import { LifecycleState, Resource } from "@dxos/context";
|
|
129
125
|
import { log as log2 } from "@dxos/log";
|
|
130
126
|
import { trace as trace2 } from "@dxos/tracing";
|
|
127
|
+
|
|
128
|
+
// packages/plugins/plugin-transcription/src/util/array.ts
|
|
129
|
+
var mergeFloat64Arrays = (arrays) => {
|
|
130
|
+
const newArray = new Float64Array(arrays.reduce((acc, array) => array.length + acc, 0));
|
|
131
|
+
let offset = 0;
|
|
132
|
+
for (const array of arrays) {
|
|
133
|
+
newArray.set(array, offset);
|
|
134
|
+
offset += array.length;
|
|
135
|
+
}
|
|
136
|
+
return newArray;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// packages/plugins/plugin-transcription/src/transcriber/transcriber.ts
|
|
131
140
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
132
141
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
133
142
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -150,17 +159,35 @@ var Transcriber = class extends Resource {
|
|
|
150
159
|
this._onSegments = onSegments;
|
|
151
160
|
}
|
|
152
161
|
async _open(ctx) {
|
|
162
|
+
log2.info("opening", void 0, {
|
|
163
|
+
F: __dxlog_file2,
|
|
164
|
+
L: 101,
|
|
165
|
+
S: this,
|
|
166
|
+
C: (f, a) => f(...a)
|
|
167
|
+
});
|
|
153
168
|
this._recorder.setOnChunk((chunk) => this._saveAudioChunk(chunk));
|
|
154
169
|
await this._recorder.start();
|
|
155
170
|
this._transcribeTask = new DeferredTask(ctx, async () => this._transcribe());
|
|
156
171
|
this._openTrigger.wake();
|
|
157
172
|
}
|
|
158
173
|
async _close() {
|
|
174
|
+
log2.info("closing", void 0, {
|
|
175
|
+
F: __dxlog_file2,
|
|
176
|
+
L: 109,
|
|
177
|
+
S: this,
|
|
178
|
+
C: (f, a) => f(...a)
|
|
179
|
+
});
|
|
159
180
|
this._recording = false;
|
|
160
181
|
this._transcribeTask = void 0;
|
|
161
182
|
await this._recorder.stop();
|
|
162
183
|
}
|
|
163
184
|
startChunksRecording() {
|
|
185
|
+
log2.info("starting", void 0, {
|
|
186
|
+
F: __dxlog_file2,
|
|
187
|
+
L: 116,
|
|
188
|
+
S: this,
|
|
189
|
+
C: (f, a) => f(...a)
|
|
190
|
+
});
|
|
164
191
|
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
165
192
|
return;
|
|
166
193
|
}
|
|
@@ -172,13 +199,19 @@ var Transcriber = class extends Resource {
|
|
|
172
199
|
}
|
|
173
200
|
this._recording = false;
|
|
174
201
|
this._transcribeTask?.schedule();
|
|
202
|
+
log2.info("stopped", void 0, {
|
|
203
|
+
F: __dxlog_file2,
|
|
204
|
+
L: 131,
|
|
205
|
+
S: this,
|
|
206
|
+
C: (f, a) => f(...a)
|
|
207
|
+
});
|
|
175
208
|
}
|
|
176
209
|
_saveAudioChunk(chunk) {
|
|
177
210
|
log2("saving audio chunk", {
|
|
178
211
|
chunk
|
|
179
212
|
}, {
|
|
180
213
|
F: __dxlog_file2,
|
|
181
|
-
L:
|
|
214
|
+
L: 135,
|
|
182
215
|
S: this,
|
|
183
216
|
C: (f, a) => f(...a)
|
|
184
217
|
});
|
|
@@ -194,7 +227,7 @@ var Transcriber = class extends Resource {
|
|
|
194
227
|
chunks: this._audioChunks.length
|
|
195
228
|
}, {
|
|
196
229
|
F: __dxlog_file2,
|
|
197
|
-
L:
|
|
230
|
+
L: 151,
|
|
198
231
|
S: this,
|
|
199
232
|
C: (f, a) => f(...a)
|
|
200
233
|
});
|
|
@@ -238,15 +271,15 @@ var Transcriber = class extends Resource {
|
|
|
238
271
|
});
|
|
239
272
|
if (!response.ok) {
|
|
240
273
|
this._audioChunks = [];
|
|
241
|
-
throw new Error(
|
|
274
|
+
throw new Error(`Transcription failed: ${response.statusText}`);
|
|
242
275
|
}
|
|
243
276
|
const { segments } = await response.json();
|
|
244
277
|
log2.info("transcription response", {
|
|
245
|
-
segments,
|
|
278
|
+
segments: segments.length,
|
|
246
279
|
string: segments.map((segments2) => segments2.text).join(" ")
|
|
247
280
|
}, {
|
|
248
281
|
F: __dxlog_file2,
|
|
249
|
-
L:
|
|
282
|
+
L: 215,
|
|
250
283
|
S: this,
|
|
251
284
|
C: (f, a) => f(...a)
|
|
252
285
|
});
|
|
@@ -268,8 +301,9 @@ var Transcriber = class extends Resource {
|
|
|
268
301
|
}
|
|
269
302
|
this._lastUsedTimestamp = zeroTimestamp + filteredSegments.at(-1).end * 1e3;
|
|
270
303
|
return filteredSegments.map((segment) => ({
|
|
271
|
-
|
|
272
|
-
|
|
304
|
+
type: "transcription",
|
|
305
|
+
started: new Date(zeroTimestamp + segment.start * 1e3).toISOString(),
|
|
306
|
+
text: segment.text.trim()
|
|
273
307
|
}));
|
|
274
308
|
}
|
|
275
309
|
};
|
|
@@ -285,59 +319,66 @@ _ts_decorate2([
|
|
|
285
319
|
], Transcriber.prototype, "_fetchTranscription", null);
|
|
286
320
|
|
|
287
321
|
// packages/plugins/plugin-transcription/src/transcriber/transcription-manager.ts
|
|
322
|
+
import { signal } from "@preact/signals-core";
|
|
288
323
|
import { synchronized as synchronized2 } from "@dxos/async";
|
|
289
324
|
import { Resource as Resource2 } from "@dxos/context";
|
|
290
|
-
import {
|
|
291
|
-
import {
|
|
292
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
293
|
-
import { DXN } from "@dxos/keys";
|
|
325
|
+
import { create } from "@dxos/echo-schema";
|
|
326
|
+
import { DataType } from "@dxos/schema";
|
|
294
327
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
295
328
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
296
329
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
297
330
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
298
331
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
299
332
|
}
|
|
300
|
-
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-transcription/src/transcriber/transcription-manager.ts";
|
|
301
333
|
var RECORD_INTERVAL = 200;
|
|
302
334
|
var PREFIXED_CHUNKS_AMOUNT = 10;
|
|
303
335
|
var TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;
|
|
304
336
|
var TranscriptionManager = class extends Resource2 {
|
|
305
|
-
constructor(
|
|
337
|
+
constructor(options) {
|
|
306
338
|
super();
|
|
307
339
|
this._audioStreamTrack = void 0;
|
|
308
|
-
this.
|
|
309
|
-
this._hue = void 0;
|
|
340
|
+
this._identityDid = void 0;
|
|
310
341
|
this._mediaRecorder = void 0;
|
|
311
342
|
this._transcriber = void 0;
|
|
312
|
-
this._enabled = false;
|
|
313
343
|
this._queue = void 0;
|
|
314
|
-
this.
|
|
344
|
+
this._enabled = signal(false);
|
|
345
|
+
this._edgeClient = options.edgeClient;
|
|
346
|
+
this._messageEnricher = options.messageEnricher;
|
|
315
347
|
}
|
|
316
|
-
|
|
317
|
-
|
|
348
|
+
/** @reactive */
|
|
349
|
+
get enabled() {
|
|
350
|
+
return this._enabled.value;
|
|
318
351
|
}
|
|
319
|
-
|
|
320
|
-
|
|
352
|
+
setQueue(queue) {
|
|
353
|
+
this._queue = queue;
|
|
354
|
+
return this;
|
|
355
|
+
}
|
|
356
|
+
setIdentityDid(did) {
|
|
357
|
+
if (this._identityDid !== did) {
|
|
358
|
+
this._identityDid = did;
|
|
359
|
+
}
|
|
360
|
+
return this;
|
|
321
361
|
}
|
|
322
362
|
setRecording(recording) {
|
|
323
|
-
if (!this.isOpen || !this._enabled) {
|
|
324
|
-
return;
|
|
363
|
+
if (!this.isOpen || !this._enabled.value) {
|
|
364
|
+
return this;
|
|
325
365
|
}
|
|
326
366
|
if (recording) {
|
|
327
367
|
this._transcriber?.startChunksRecording();
|
|
328
368
|
} else {
|
|
329
369
|
this._transcriber?.stopChunksRecording();
|
|
330
370
|
}
|
|
371
|
+
return this;
|
|
331
372
|
}
|
|
332
373
|
/**
|
|
333
374
|
* Enable or disable transcription.
|
|
334
375
|
* @param enabled - Whether to enable transcription.
|
|
335
376
|
*/
|
|
336
377
|
async setEnabled(enabled) {
|
|
337
|
-
if (this._enabled === enabled) {
|
|
378
|
+
if (this._enabled.value === enabled) {
|
|
338
379
|
return;
|
|
339
380
|
}
|
|
340
|
-
this._enabled = enabled ?? false;
|
|
381
|
+
this._enabled.value = enabled ?? false;
|
|
341
382
|
this.isOpen && await this._toggleTranscriber();
|
|
342
383
|
}
|
|
343
384
|
async setAudioTrack(track) {
|
|
@@ -347,67 +388,64 @@ var TranscriptionManager = class extends Resource2 {
|
|
|
347
388
|
this._audioStreamTrack = track;
|
|
348
389
|
this.isOpen && await this._toggleTranscriber();
|
|
349
390
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
* @param queue - The queue to save the transcription to or the DXN of the queue.
|
|
353
|
-
*/
|
|
354
|
-
setQueue(queue) {
|
|
355
|
-
switch (typeof queue) {
|
|
356
|
-
case "string":
|
|
357
|
-
if (this._queue?.dxn.toString() === queue) {
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
this._queue = new QueueImpl(this._edgeClient, DXN.parse(queue));
|
|
361
|
-
break;
|
|
362
|
-
case "object":
|
|
363
|
-
if (this._queue === queue) {
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
invariant2(queue instanceof QueueImpl, void 0, {
|
|
367
|
-
F: __dxlog_file3,
|
|
368
|
-
L: 113,
|
|
369
|
-
S: this,
|
|
370
|
-
A: [
|
|
371
|
-
"queue instanceof QueueImpl",
|
|
372
|
-
""
|
|
373
|
-
]
|
|
374
|
-
});
|
|
375
|
-
this._queue = queue;
|
|
376
|
-
break;
|
|
377
|
-
case "undefined":
|
|
378
|
-
this._queue = void 0;
|
|
379
|
-
break;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
setName(name) {
|
|
383
|
-
if (this._name === name) {
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
this._name = name;
|
|
391
|
+
async _open() {
|
|
392
|
+
await this._toggleTranscriber();
|
|
387
393
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
this._hue = hue;
|
|
394
|
+
async _close() {
|
|
395
|
+
void this._transcriber?.close();
|
|
393
396
|
}
|
|
397
|
+
// TODO(burdon): Change this to setEnables (explicit), not toggle.
|
|
394
398
|
async _toggleTranscriber() {
|
|
395
399
|
await this._maybeReinitTranscriber();
|
|
396
|
-
if (this._enabled) {
|
|
400
|
+
if (this._enabled.value) {
|
|
397
401
|
await this._transcriber?.open();
|
|
402
|
+
const block = create(DataType.Message, {
|
|
403
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
404
|
+
blocks: [
|
|
405
|
+
{
|
|
406
|
+
type: "transcription",
|
|
407
|
+
text: "Started",
|
|
408
|
+
started: (/* @__PURE__ */ new Date()).toISOString()
|
|
409
|
+
}
|
|
410
|
+
],
|
|
411
|
+
sender: {
|
|
412
|
+
role: "assistant"
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
this._queue?.append([
|
|
416
|
+
block
|
|
417
|
+
]);
|
|
398
418
|
} else {
|
|
399
419
|
await this._transcriber?.close();
|
|
420
|
+
const block = create(DataType.Message, {
|
|
421
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
422
|
+
blocks: [
|
|
423
|
+
{
|
|
424
|
+
type: "transcription",
|
|
425
|
+
text: "Stopped",
|
|
426
|
+
started: (/* @__PURE__ */ new Date()).toISOString()
|
|
427
|
+
}
|
|
428
|
+
],
|
|
429
|
+
sender: {
|
|
430
|
+
role: "assistant"
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
this._queue?.append([
|
|
434
|
+
block
|
|
435
|
+
]);
|
|
400
436
|
}
|
|
401
437
|
}
|
|
402
438
|
async _maybeReinitTranscriber() {
|
|
403
|
-
if (!this._audioStreamTrack || !this._enabled) {
|
|
439
|
+
if (!this._audioStreamTrack || !this._enabled.value) {
|
|
404
440
|
return;
|
|
405
441
|
}
|
|
406
442
|
let needReinit = false;
|
|
407
443
|
if (this._audioStreamTrack !== this._mediaRecorder?.mediaStreamTrack) {
|
|
408
444
|
this._mediaRecorder = new MediaStreamRecorder({
|
|
409
445
|
mediaStreamTrack: this._audioStreamTrack,
|
|
410
|
-
|
|
446
|
+
config: {
|
|
447
|
+
interval: RECORD_INTERVAL
|
|
448
|
+
}
|
|
411
449
|
});
|
|
412
450
|
needReinit = true;
|
|
413
451
|
}
|
|
@@ -427,38 +465,31 @@ var TranscriptionManager = class extends Resource2 {
|
|
|
427
465
|
if (!this.isOpen || !this._queue) {
|
|
428
466
|
return;
|
|
429
467
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
468
|
+
let block = create(DataType.Message, {
|
|
469
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
470
|
+
blocks: segments,
|
|
471
|
+
sender: {
|
|
472
|
+
identityDid: this._identityDid
|
|
473
|
+
}
|
|
434
474
|
});
|
|
475
|
+
if (this._messageEnricher) {
|
|
476
|
+
block = await this._messageEnricher(block);
|
|
477
|
+
}
|
|
435
478
|
this._queue.append([
|
|
436
479
|
block
|
|
437
480
|
]);
|
|
438
481
|
}
|
|
439
482
|
};
|
|
440
|
-
_ts_decorate3([
|
|
441
|
-
synchronized2
|
|
442
|
-
], TranscriptionManager.prototype, "setRecording", null);
|
|
443
483
|
_ts_decorate3([
|
|
444
484
|
synchronized2
|
|
445
485
|
], TranscriptionManager.prototype, "setEnabled", null);
|
|
446
486
|
_ts_decorate3([
|
|
447
487
|
synchronized2
|
|
448
488
|
], TranscriptionManager.prototype, "setAudioTrack", null);
|
|
449
|
-
_ts_decorate3([
|
|
450
|
-
synchronized2
|
|
451
|
-
], TranscriptionManager.prototype, "setQueue", null);
|
|
452
|
-
_ts_decorate3([
|
|
453
|
-
synchronized2
|
|
454
|
-
], TranscriptionManager.prototype, "setName", null);
|
|
455
|
-
_ts_decorate3([
|
|
456
|
-
synchronized2
|
|
457
|
-
], TranscriptionManager.prototype, "setHue", null);
|
|
458
489
|
|
|
459
490
|
export {
|
|
460
491
|
MediaStreamRecorder,
|
|
461
492
|
Transcriber,
|
|
462
493
|
TranscriptionManager
|
|
463
494
|
};
|
|
464
|
-
//# sourceMappingURL=chunk-
|
|
495
|
+
//# sourceMappingURL=chunk-LMLE2QYX.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/transcriber/media-stream-recorder.ts", "../../../src/transcriber/transcriber.ts", "../../../src/util/array.ts", "../../../src/transcriber/transcription-manager.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type IBlobEvent, type IMediaRecorder, MediaRecorder, register } from 'extendable-media-recorder';\nimport { WaveFile } from 'wavefile';\n\nimport { synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/tracing';\n\nimport { type WavConfig, type AudioChunk, type AudioRecorder } from './audio-recorder';\n\nlet initializingPromise: Promise<void> | undefined;\n\nconst initializeExtendableMediaRecorder = async () => {\n const { connect } = await import('extendable-media-recorder-wav-encoder');\n await register(await connect());\n};\n\nexport type MediaStreamRecorderParams = {\n mediaStreamTrack: MediaStreamTrack;\n config: {\n interval: number;\n };\n};\n\n/**\n * Recorder that uses the MediaContext API and AudioNode API to record audio.\n *\n * It records MediaStream using https://www.npmjs.com/package/extendable-media-recorder.\n */\n@trace.resource()\nexport class MediaStreamRecorder implements AudioRecorder {\n private readonly _mediaStreamTrack: MediaStreamTrack;\n /**\n * Default MediaRecorder implementation do not support wav encoding.\n */\n private readonly _config: MediaStreamRecorderParams['config'];\n private _mediaRecorder?: IMediaRecorder = undefined;\n private _header?: Uint8Array = undefined;\n private _onChunk?: (chunk: AudioChunk) => void;\n\n constructor({ mediaStreamTrack, config }: MediaStreamRecorderParams) {\n this._mediaStreamTrack = mediaStreamTrack;\n this._config = config;\n }\n\n get wavConfig(): WavConfig {\n const settings = this._mediaStreamTrack.getSettings();\n return {\n channels: settings.channelCount ?? 1,\n sampleRate: settings.sampleRate ?? 16000,\n bitDepthCode: settings.sampleSize ? String(settings.sampleSize) : '16',\n };\n }\n\n get mediaStreamTrack() {\n return this._mediaStreamTrack;\n }\n\n setOnChunk(onChunk: (chunk: AudioChunk) => void): void {\n this._onChunk = onChunk;\n }\n\n async start(): Promise<void> {\n await (initializingPromise ??= initializeExtendableMediaRecorder()).catch((err) =>\n log.info('initializeExtendableMediaRecorder', { err }),\n );\n\n if (!this._mediaRecorder) {\n const stream = new MediaStream([this._mediaStreamTrack]);\n this._mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/wav' });\n }\n\n if (this._mediaRecorder.state === 'recording') {\n return;\n }\n invariant(this._onChunk, 'MediaStreamRecorder: onChunk is not set');\n this._mediaRecorder.ondataavailable = (event) => this._ondataavailable(event);\n this._mediaRecorder.start(this._config.interval);\n }\n\n async stop(): Promise<void> {\n if (this._mediaRecorder?.state !== 'recording') {\n return;\n }\n this._mediaRecorder.stop();\n }\n\n @synchronized\n private async _ondataavailable(event: IBlobEvent): Promise<void> {\n const blob = event.data;\n const uint8Array = new Uint8Array(await blob.arrayBuffer());\n\n // First chunk from the MediaRecorder has a header.\n const isHeader =\n uint8Array[0] === 0x52 && // R\n uint8Array[1] === 0x49 && // I\n uint8Array[2] === 0x46 && // F\n uint8Array[3] === 0x46; // F\n let wav: WaveFile;\n\n if (isHeader) {\n wav = new WaveFile(uint8Array);\n this._header = uint8Array.slice(0, 44);\n } else if (this._header) {\n wav = new WaveFile(new Uint8Array([...this._header, ...uint8Array]));\n } else {\n log.warn('MediaStreamRecorder: no header');\n return;\n }\n\n this._onChunk!({\n timestamp: Date.now(),\n data: wav.getSamples(),\n });\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { WaveFile } from 'wavefile';\n\nimport { DeferredTask, Trigger } from '@dxos/async';\nimport { type Context, LifecycleState, Resource } from '@dxos/context';\nimport { log } from '@dxos/log';\nimport { type DataType } from '@dxos/schema';\nimport { trace } from '@dxos/tracing';\n\nimport { type AudioRecorder, type AudioChunk } from './audio-recorder';\nimport { TRANSCRIPTION_URL } from '../types';\nimport { mergeFloat64Arrays } from '../util';\n\ntype WhisperWord = {\n word: string;\n\n /**\n * Time in seconds from the start of the audio.\n */\n start: number;\n\n /**\n * Time in seconds from the start of the audio.\n */\n end: number;\n};\n\ntype WhisperSegment = {\n text: string;\n\n /**\n * Time in seconds from the start of the audio.\n */\n start: number;\n\n /**\n * Time in seconds from the start of the audio.\n */\n end: number;\n\n /**\n * Probability of no speech in the segment.\n */\n no_speech_prob: number;\n\n words: WhisperWord[];\n};\n\nexport type TranscribeConfig = {\n /**\n * Number of chunks to transcribe automatically after.\n */\n transcribeAfterChunksAmount: number;\n\n /**\n * Number of chunks to save before the user starts speaking.\n * This is needed to catch the beginning of the user's speech.\n */\n prefixBufferChunksAmount: number;\n};\n\nexport type TranscriberParams = {\n config: TranscribeConfig;\n recorder: AudioRecorder;\n /**\n * Callback to handle the transcribed segments, after all segment transformers are applied.\n * @param segments - The transcribed segments.\n */\n onSegments: (segments: DataType.MessageBlock.Transcription[]) => Promise<void>;\n};\n\n/**\n * Handles transcription of audio chunks.\n * If user is not speaking, the last `minChunksAmount` chunks are saved and transcribed.\n * If user is speaking, the chunks are added to the buffer until the user is done talking.\n */\nexport class Transcriber extends Resource {\n private _audioChunks: AudioChunk[] = [];\n private _lastUsedTimestamp = 0;\n\n private readonly _openTrigger = new Trigger({ autoReset: true });\n\n private readonly _config: TranscribeConfig;\n private readonly _recorder: AudioRecorder;\n private readonly _onSegments: TranscriberParams['onSegments'];\n\n private _recording = false;\n private _transcribeTask?: DeferredTask = undefined;\n\n constructor({ config, recorder, onSegments }: TranscriberParams) {\n super();\n this._config = config;\n this._recorder = recorder;\n this._onSegments = onSegments;\n }\n\n protected override async _open(ctx: Context): Promise<void> {\n log.info('opening');\n this._recorder.setOnChunk((chunk) => this._saveAudioChunk(chunk));\n await this._recorder.start();\n this._transcribeTask = new DeferredTask(ctx, async () => this._transcribe());\n this._openTrigger.wake();\n }\n\n protected override async _close(): Promise<void> {\n log.info('closing');\n this._recording = false;\n this._transcribeTask = undefined;\n await this._recorder.stop();\n }\n\n startChunksRecording(): void {\n log.info('starting');\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n\n this._recording = true;\n }\n\n stopChunksRecording(): void {\n if (this._lifecycleState !== LifecycleState.OPEN || !this._recording) {\n return;\n }\n\n this._recording = false;\n this._transcribeTask?.schedule();\n log.info('stopped');\n }\n\n private _saveAudioChunk(chunk: AudioChunk): void {\n log('saving audio chunk', { chunk });\n this._audioChunks.push(chunk);\n\n // Clean the buffer if the user is not speaking and the transcription task is not scheduled.\n if (\n !this._recording &&\n (!this._transcribeTask || !this._transcribeTask.scheduled) &&\n this._audioChunks.length >= this._config.prefixBufferChunksAmount\n ) {\n this._audioChunks = this._dropOldChunks();\n } else if (this._audioChunks.length >= this._config.transcribeAfterChunksAmount && this._recording) {\n this._transcribeTask?.schedule();\n }\n }\n\n private async _transcribe(): Promise<void> {\n log('transcribing', { chunks: this._audioChunks.length });\n const chunks = this._audioChunks;\n this._audioChunks = this._dropOldChunks();\n if (chunks.length === 0) {\n return;\n }\n\n const audio = await this._mergeAudioChunks(chunks);\n const segments = await this._fetchTranscription(audio);\n if (!Array.isArray(segments) || segments.length === 0) {\n return;\n }\n\n const alignedSegments = this._alignSegments(segments, chunks);\n if (alignedSegments.length > 0) {\n await this._onSegments(alignedSegments);\n }\n }\n\n private _dropOldChunks(): AudioChunk[] {\n return this._config.prefixBufferChunksAmount > 0\n ? this._audioChunks.slice(-this._config.prefixBufferChunksAmount)\n : [];\n }\n\n @trace.span({ showInBrowserTimeline: true })\n private async _mergeAudioChunks(chunks: AudioChunk[]): Promise<string> {\n const file = new WaveFile();\n const wavConfig = this._recorder.wavConfig;\n\n file.fromScratch(\n wavConfig.channels,\n wavConfig.sampleRate,\n wavConfig.bitDepthCode,\n mergeFloat64Arrays(chunks.map(({ data }) => data)),\n );\n\n return file.toBase64();\n }\n\n @trace.span({ showInBrowserTimeline: true })\n private async _fetchTranscription(audio: string): Promise<WhisperSegment[]> {\n if (audio.length === 0) {\n this._audioChunks = [];\n throw new Error('No audio to send for transcribing');\n }\n\n const response = await fetch(`${TRANSCRIPTION_URL}/transcribe`, {\n method: 'POST',\n body: JSON.stringify({ audio }),\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n this._audioChunks = [];\n throw new Error(`Transcription failed: ${response.statusText}`);\n }\n\n const { segments } = (await response.json()) as {\n segments: WhisperSegment[];\n };\n\n log.info('transcription response', {\n segments: segments.length,\n string: segments.map((segments) => segments.text).join(' '),\n });\n\n return segments;\n }\n\n private _alignSegments(\n segments: WhisperSegment[],\n originalChunks: AudioChunk[],\n ): DataType.MessageBlock.Transcription[] {\n // Absolute zero for all relative timestamps in the segments.\n const zeroTimestamp = originalChunks.at(0)!.timestamp;\n\n const filteredSegments = segments\n // Use segments that end after the last used timestamp.\n // Segments could overlap, so we need to filter words that starts after the last used timestamp.\n .filter((segment) => zeroTimestamp + segment.end * 1_000 >= this._lastUsedTimestamp)\n // Use words that starts after the last used timestamp.\n .map((segment) => {\n const words = segment.words.filter((word) => zeroTimestamp + word.start * 1_000 >= this._lastUsedTimestamp);\n return {\n ...segment,\n words,\n text: words.map((word) => word.word).join(''),\n start: words.at(0)?.start ?? segment.end,\n };\n })\n .filter((segment) => segment.words.length > 0);\n\n if (filteredSegments.length === 0) {\n return [];\n }\n\n // Update last timestamp.\n this._lastUsedTimestamp = zeroTimestamp + filteredSegments.at(-1)!.end * 1_000;\n\n // Add absolute timestamp to each segment.\n return filteredSegments.map((segment) => ({\n type: 'transcription',\n started: new Date(zeroTimestamp + segment.start * 1_000).toISOString(),\n text: segment.text.trim(),\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", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { signal } from '@preact/signals-core';\n\nimport { synchronized } from '@dxos/async';\nimport { Resource } from '@dxos/context';\nimport { type Queue } from '@dxos/echo-db';\nimport { create } from '@dxos/echo-schema';\nimport { type EdgeHttpClient } from '@dxos/react-edge-client';\nimport { DataType } from '@dxos/schema';\n\nimport { MediaStreamRecorder } from './media-stream-recorder';\nimport { Transcriber } from './transcriber';\n\n/**\n * Length of the chunk in ms.\n */\nconst RECORD_INTERVAL = 200;\n\n/**\n * Number of chunks to save before the user starts speaking.\n */\nconst PREFIXED_CHUNKS_AMOUNT = 10;\n\n/**\n * Number of chunks to transcribe automatically after.\n * Combined should be mess than 25MB or whisper would fail.\n */\nconst TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;\n\nexport type TranscriptMessageEnricher = (message: DataType.Message) => Promise<DataType.Message>;\n\nexport type TranscriptionManagerOptions = {\n edgeClient: EdgeHttpClient;\n\n /**\n * Enrich the message before it is written to the transcription queue.\n */\n messageEnricher?: TranscriptMessageEnricher;\n};\n\n/**\n * Manages transcription state for a meeting.\n */\nexport class TranscriptionManager extends Resource {\n private readonly _edgeClient: EdgeHttpClient;\n private readonly _messageEnricher?: TranscriptMessageEnricher;\n private _audioStreamTrack?: MediaStreamTrack = undefined;\n private _identityDid?: string = undefined;\n private _mediaRecorder?: MediaStreamRecorder = undefined;\n private _transcriber?: Transcriber = undefined;\n private _queue?: Queue<DataType.Message> = undefined;\n private _enabled = signal(false);\n\n constructor(options: TranscriptionManagerOptions) {\n super();\n this._edgeClient = options.edgeClient;\n this._messageEnricher = options.messageEnricher;\n }\n\n /** @reactive */\n get enabled() {\n return this._enabled.value;\n }\n\n setQueue(queue: Queue<DataType.Message>): this {\n this._queue = queue;\n return this;\n }\n\n setIdentityDid(did: string): this {\n if (this._identityDid !== did) {\n this._identityDid = did;\n }\n return this;\n }\n\n setRecording(recording?: boolean): this {\n if (!this.isOpen || !this._enabled.value) {\n return this;\n }\n\n if (recording) {\n this._transcriber?.startChunksRecording();\n } else {\n this._transcriber?.stopChunksRecording();\n }\n return this;\n }\n\n /**\n * Enable or disable transcription.\n * @param enabled - Whether to enable transcription.\n */\n @synchronized\n async setEnabled(enabled?: boolean): Promise<void> {\n if (this._enabled.value === enabled) {\n return;\n }\n\n this._enabled.value = enabled ?? false;\n // TODO(burdon): Why is toggle called here?\n this.isOpen && (await this._toggleTranscriber());\n }\n\n @synchronized\n async setAudioTrack(track?: MediaStreamTrack): Promise<void> {\n if (this._audioStreamTrack === track) {\n return;\n }\n\n this._audioStreamTrack = track;\n this.isOpen && (await this._toggleTranscriber());\n }\n\n protected override async _open(): Promise<void> {\n await this._toggleTranscriber();\n }\n\n protected override async _close(): Promise<void> {\n void this._transcriber?.close();\n }\n\n // TODO(burdon): Change this to setEnables (explicit), not toggle.\n private async _toggleTranscriber(): Promise<void> {\n await this._maybeReinitTranscriber();\n\n // Open or close transcriber if transcription is enabled or disabled.\n if (this._enabled.value) {\n await this._transcriber?.open();\n // TODO(burdon): Started and stopped blocks appear twice.\n const block = create(DataType.Message, {\n created: new Date().toISOString(),\n blocks: [{ type: 'transcription', text: 'Started', started: new Date().toISOString() }],\n sender: { role: 'assistant' },\n });\n this._queue?.append([block]);\n } else {\n await this._transcriber?.close();\n const block = create(DataType.Message, {\n created: new Date().toISOString(),\n blocks: [{ type: 'transcription', text: 'Stopped', started: new Date().toISOString() }],\n sender: { role: 'assistant' },\n });\n this._queue?.append([block]);\n }\n }\n\n private async _maybeReinitTranscriber(): Promise<void> {\n if (!this._audioStreamTrack || !this._enabled.value) {\n return;\n }\n\n // Reinitialize transcriber if queue or media stream track has changed.\n let needReinit = false;\n if (this._audioStreamTrack !== this._mediaRecorder?.mediaStreamTrack) {\n this._mediaRecorder = new MediaStreamRecorder({\n mediaStreamTrack: this._audioStreamTrack,\n config: { interval: RECORD_INTERVAL },\n });\n needReinit = true;\n }\n if (needReinit) {\n await this._transcriber?.close();\n this._transcriber = new Transcriber({\n config: {\n transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT,\n prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT,\n },\n recorder: this._mediaRecorder,\n onSegments: (segments) => this._onSegments(segments),\n });\n }\n }\n\n private async _onSegments(segments: DataType.MessageBlock.Transcription[]): Promise<void> {\n if (!this.isOpen || !this._queue) {\n return;\n }\n\n let block = create(DataType.Message, {\n created: new Date().toISOString(),\n blocks: segments,\n sender: { identityDid: this._identityDid },\n });\n\n if (this._messageEnricher) {\n block = await this._messageEnricher(block);\n }\n\n this._queue.append([block]);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["MediaRecorder", "register", "WaveFile", "synchronized", "invariant", "log", "trace", "initializingPromise", "initializeExtendableMediaRecorder", "connect", "MediaStreamRecorder", "mediaStreamTrack", "config", "_mediaRecorder", "undefined", "_header", "_mediaStreamTrack", "_config", "wavConfig", "settings", "getSettings", "channels", "channelCount", "sampleRate", "bitDepthCode", "sampleSize", "String", "setOnChunk", "onChunk", "_onChunk", "start", "catch", "err", "info", "stream", "MediaStream", "mimeType", "state", "ondataavailable", "event", "_ondataavailable", "interval", "stop", "blob", "data", "uint8Array", "Uint8Array", "arrayBuffer", "isHeader", "wav", "slice", "warn", "timestamp", "Date", "now", "getSamples", "resource", "WaveFile", "DeferredTask", "Trigger", "LifecycleState", "Resource", "log", "trace", "mergeFloat64Arrays", "arrays", "newArray", "Float64Array", "reduce", "acc", "array", "length", "offset", "set", "Transcriber", "Resource", "config", "recorder", "onSegments", "_audioChunks", "_lastUsedTimestamp", "_openTrigger", "Trigger", "autoReset", "_recording", "_transcribeTask", "undefined", "_config", "_recorder", "_onSegments", "_open", "ctx", "log", "info", "setOnChunk", "chunk", "_saveAudioChunk", "start", "DeferredTask", "_transcribe", "wake", "_close", "stop", "startChunksRecording", "_lifecycleState", "LifecycleState", "OPEN", "stopChunksRecording", "schedule", "push", "scheduled", "length", "prefixBufferChunksAmount", "_dropOldChunks", "transcribeAfterChunksAmount", "chunks", "audio", "_mergeAudioChunks", "segments", "_fetchTranscription", "Array", "isArray", "alignedSegments", "_alignSegments", "slice", "file", "WaveFile", "wavConfig", "fromScratch", "channels", "sampleRate", "bitDepthCode", "mergeFloat64Arrays", "map", "data", "toBase64", "Error", "response", "fetch", "TRANSCRIPTION_URL", "method", "body", "JSON", "stringify", "headers", "ok", "statusText", "json", "string", "text", "join", "originalChunks", "zeroTimestamp", "at", "timestamp", "filteredSegments", "filter", "segment", "end", "words", "word", "type", "started", "Date", "toISOString", "trim", "span", "showInBrowserTimeline", "signal", "synchronized", "Resource", "create", "DataType", "RECORD_INTERVAL", "PREFIXED_CHUNKS_AMOUNT", "TRANSCRIBE_AFTER_CHUNKS_AMOUNT", "TranscriptionManager", "Resource", "options", "_audioStreamTrack", "undefined", "_identityDid", "_mediaRecorder", "_transcriber", "_queue", "_enabled", "signal", "_edgeClient", "edgeClient", "_messageEnricher", "messageEnricher", "enabled", "value", "setQueue", "queue", "setIdentityDid", "did", "setRecording", "recording", "isOpen", "startChunksRecording", "stopChunksRecording", "setEnabled", "_toggleTranscriber", "setAudioTrack", "track", "_open", "_close", "close", "_maybeReinitTranscriber", "open", "block", "create", "DataType", "Message", "created", "Date", "toISOString", "blocks", "type", "text", "started", "sender", "role", "append", "needReinit", "mediaStreamTrack", "MediaStreamRecorder", "config", "interval", "Transcriber", "transcribeAfterChunksAmount", "prefixBufferChunksAmount", "recorder", "onSegments", "segments", "_onSegments", "identityDid"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TRANSCRIPTION_PLUGIN
|
|
3
|
+
} from "./chunk-GOF7MJNV.mjs";
|
|
4
|
+
|
|
5
|
+
// packages/plugins/plugin-transcription/src/types/schema.ts
|
|
6
|
+
import { Schema } from "effect";
|
|
7
|
+
import { Expando, Ref, TypedObject } from "@dxos/echo-schema";
|
|
8
|
+
var TranscriptSchema = Schema.Struct({
|
|
9
|
+
// TODO(wittjosiah): Remove?
|
|
10
|
+
// TODO(burdon): Use Date or string?
|
|
11
|
+
started: Schema.optional(Schema.String),
|
|
12
|
+
ended: Schema.optional(Schema.String),
|
|
13
|
+
/**
|
|
14
|
+
* Queue containing TranscriptBlock objects.
|
|
15
|
+
*/
|
|
16
|
+
// TODO(wittjosiah): Should be a ref to a queue.
|
|
17
|
+
queue: Ref(Expando)
|
|
18
|
+
});
|
|
19
|
+
var TranscriptType = class extends TypedObject({
|
|
20
|
+
typename: "dxos.org/type/Transcript",
|
|
21
|
+
version: "0.1.0"
|
|
22
|
+
})(TranscriptSchema.fields) {
|
|
23
|
+
};
|
|
24
|
+
var TranscriptHeader = Schema.Struct({
|
|
25
|
+
started: Schema.optional(Schema.String)
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// packages/plugins/plugin-transcription/src/types/types.ts
|
|
29
|
+
import { Schema as Schema2 } from "effect";
|
|
30
|
+
import { SpaceId } from "@dxos/react-client/echo";
|
|
31
|
+
var TRANSCRIPTION_URL = "https://calls-service.dxos.workers.dev";
|
|
32
|
+
(function(TranscriptionAction2) {
|
|
33
|
+
const TRANSCRIPTION_ACTION = `${TRANSCRIPTION_PLUGIN}/action`;
|
|
34
|
+
class Create extends Schema2.TaggedClass()(`${TRANSCRIPTION_ACTION}/create`, {
|
|
35
|
+
input: Schema2.Struct({
|
|
36
|
+
name: Schema2.optional(Schema2.String),
|
|
37
|
+
spaceId: SpaceId
|
|
38
|
+
}),
|
|
39
|
+
output: Schema2.Struct({
|
|
40
|
+
object: TranscriptType
|
|
41
|
+
})
|
|
42
|
+
}) {
|
|
43
|
+
}
|
|
44
|
+
TranscriptionAction2.Create = Create;
|
|
45
|
+
})(TranscriptionAction || (TranscriptionAction = {}));
|
|
46
|
+
var TranscriptionAction;
|
|
47
|
+
|
|
48
|
+
export {
|
|
49
|
+
TranscriptSchema,
|
|
50
|
+
TranscriptType,
|
|
51
|
+
TRANSCRIPTION_URL,
|
|
52
|
+
TranscriptionAction
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=chunk-NODIXNQP.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/types/schema.ts", "../../../src/types/types.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\nimport { Expando, Ref, TypedObject } from '@dxos/echo-schema';\n\n/**\n * Root transcript object created when the user starts a transcription.\n */\nexport const TranscriptSchema = Schema.Struct({\n // TODO(wittjosiah): Remove?\n // TODO(burdon): Use Date or string?\n started: Schema.optional(Schema.String),\n ended: Schema.optional(Schema.String),\n\n /**\n * Queue containing TranscriptBlock objects.\n */\n // TODO(wittjosiah): Should be a ref to a queue.\n queue: Ref(Expando),\n});\n\nexport class TranscriptType extends TypedObject({\n typename: 'dxos.org/type/Transcript',\n version: '0.1.0',\n})(TranscriptSchema.fields) {}\n\n// TODO(burdon): Do these need to be kept in sync with EDGE?\n\n/**\n * First message in queue.\n * Contains metadata for the recording and transcript.\n */\nconst TranscriptHeader = Schema.Struct({\n started: Schema.optional(Schema.String),\n});\n\nexport type TranscriptHeader = Schema.Schema.Type<typeof TranscriptHeader>;\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\nimport { SpaceId } from '@dxos/react-client/echo';\n\nimport { TranscriptType } from './schema';\nimport { TRANSCRIPTION_PLUGIN } from '../meta';\n\n// TODO(burdon): Move to separate proto.\n\n/**\n * Endpoint to the calls service.\n */\n// TODO(burdon): Reconfigure/move.\nexport const TRANSCRIPTION_URL = 'https://calls-service.dxos.workers.dev';\n\nexport namespace TranscriptionAction {\n const TRANSCRIPTION_ACTION = `${TRANSCRIPTION_PLUGIN}/action`;\n\n export class Create extends Schema.TaggedClass<Create>()(`${TRANSCRIPTION_ACTION}/create`, {\n input: Schema.Struct({\n name: Schema.optional(Schema.String),\n spaceId: SpaceId,\n }),\n output: Schema.Struct({\n object: TranscriptType,\n }),\n }) {}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAIA,SAASA,cAAc;AAEvB,SAASC,SAASC,KAAKC,mBAAmB;AAKnC,IAAMC,mBAAmBC,OAAOC,OAAO;;;EAG5CC,SAASF,OAAOG,SAASH,OAAOI,MAAM;EACtCC,OAAOL,OAAOG,SAASH,OAAOI,MAAM;;;;;EAMpCE,OAAOC,IAAIC,OAAAA;AACb,CAAA;AAEO,IAAMC,iBAAN,cAA6BC,YAAY;EAC9CC,UAAU;EACVC,SAAS;AACX,CAAA,EAAGb,iBAAiBc,MAAM,EAAA;AAAG;AAQ7B,IAAMC,mBAAmBd,OAAOC,OAAO;EACrCC,SAASF,OAAOG,SAASH,OAAOI,MAAM;AACxC,CAAA;;;ACjCA,SAASW,UAAAA,eAAc;AAEvB,SAASC,eAAe;AAWjB,IAAMC,oBAAoB;UAEhBC,sBAAAA;AACf,QAAMC,uBAAuB,GAAGC,oBAAAA;EAEzB,MAAMC,eAAeC,QAAOC,YAAW,EAAW,GAAGJ,oBAAAA,WAA+B;IACzFK,OAAOF,QAAOG,OAAO;MACnBC,MAAMJ,QAAOK,SAASL,QAAOM,MAAM;MACnCC,SAASC;IACX,CAAA;IACAC,QAAQT,QAAOG,OAAO;MACpBO,QAAQC;IACV,CAAA;EACF,CAAA,EAAA;EAAI;uBARSZ,SAAAA;AASf,GAZiBH,wBAAAA,sBAAAA,CAAAA,EAAAA;;",
|
|
6
|
+
"names": ["Schema", "Expando", "Ref", "TypedObject", "TranscriptSchema", "Schema", "Struct", "started", "optional", "String", "ended", "queue", "Ref", "Expando", "TranscriptType", "TypedObject", "typename", "version", "fields", "TranscriptHeader", "Schema", "SpaceId", "TRANSCRIPTION_URL", "TranscriptionAction", "TRANSCRIPTION_ACTION", "TRANSCRIPTION_PLUGIN", "Create", "Schema", "TaggedClass", "input", "Struct", "name", "optional", "String", "spaceId", "SpaceId", "output", "object", "TranscriptType"]
|
|
7
|
+
}
|