@dxos/plugin-transcription 0.8.3 → 0.8.4-main.1068cf700f
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-MV3JBKLS.mjs +12 -0
- package/dist/lib/browser/blueprint-definition-K3E72ZBC.mjs +19 -0
- package/dist/lib/browser/blueprint-definition-K3E72ZBC.mjs.map +7 -0
- package/dist/lib/browser/blueprints/index.mjs +9 -0
- package/dist/lib/browser/chunk-AV44VISC.mjs +148 -0
- package/dist/lib/browser/chunk-AV44VISC.mjs.map +7 -0
- package/dist/lib/browser/chunk-HOOPZ7EM.mjs +35 -0
- package/dist/lib/browser/chunk-HOOPZ7EM.mjs.map +7 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/browser/{chunk-53AXUEIQ.mjs → chunk-K3JJ46VV.mjs} +367 -433
- package/dist/lib/browser/chunk-K3JJ46VV.mjs.map +7 -0
- package/dist/lib/browser/chunk-Q5OC3WVG.mjs +72 -0
- package/dist/lib/browser/chunk-Q5OC3WVG.mjs.map +7 -0
- package/dist/lib/browser/{chunk-UDCCT32F.mjs → chunk-RUKY36XW.mjs} +3 -3
- package/dist/lib/browser/{chunk-IQ5ZRMHZ.mjs → chunk-TKFU53OZ.mjs} +70 -105
- package/dist/lib/browser/chunk-TKFU53OZ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +68 -75
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/operation-resolver-GLEBGPKH.mjs +22 -0
- package/dist/lib/browser/operation-resolver-GLEBGPKH.mjs.map +7 -0
- package/dist/lib/browser/react-surface-AWZ2A5WZ.mjs +35 -0
- package/dist/lib/browser/react-surface-AWZ2A5WZ.mjs.map +7 -0
- package/dist/lib/browser/{transcriber-OYPLZFG5.mjs → transcriber-SLVQP76E.mjs} +17 -13
- package/dist/lib/browser/transcriber-SLVQP76E.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +8 -8
- package/dist/lib/node-esm/{TranscriptContainer-G75LDEO5.mjs → TranscriptContainer-7M43UAZ2.mjs} +5 -4
- package/dist/lib/node-esm/TranscriptContainer-7M43UAZ2.mjs.map +7 -0
- package/dist/lib/node-esm/blueprint-definition-2WIDDA3Y.mjs +20 -0
- package/dist/lib/node-esm/blueprint-definition-2WIDDA3Y.mjs.map +7 -0
- package/dist/lib/node-esm/blueprints/index.mjs +10 -0
- package/dist/lib/node-esm/blueprints/index.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-4BFY6P2D.mjs +73 -0
- package/dist/lib/node-esm/chunk-4BFY6P2D.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-PRL64SRU.mjs → chunk-EPC27WWV.mjs} +70 -105
- package/dist/lib/node-esm/chunk-EPC27WWV.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-NVM2QUMX.mjs +37 -0
- package/dist/lib/node-esm/chunk-NVM2QUMX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-MFJO7EKD.mjs → chunk-SNZAN34I.mjs} +3 -3
- package/dist/lib/node-esm/{chunk-56QHOX4A.mjs → chunk-TIUYXGQN.mjs} +367 -433
- package/dist/lib/node-esm/chunk-TIUYXGQN.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-TTJBW7CY.mjs +149 -0
- package/dist/lib/node-esm/chunk-TTJBW7CY.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +68 -75
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/operation-resolver-SMCFTUFM.mjs +23 -0
- package/dist/lib/node-esm/operation-resolver-SMCFTUFM.mjs.map +7 -0
- package/dist/lib/node-esm/react-surface-YBBXC4W5.mjs +36 -0
- package/dist/lib/node-esm/react-surface-YBBXC4W5.mjs.map +7 -0
- package/dist/lib/node-esm/{transcriber-TVG2MBBN.mjs → transcriber-BO2N3UQ4.mjs} +17 -13
- package/dist/lib/node-esm/transcriber-BO2N3UQ4.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +8 -8
- package/dist/types/src/TranscriptionPlugin.d.ts +2 -1
- package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
- package/dist/types/src/blueprints/index.d.ts +2 -0
- package/dist/types/src/blueprints/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/transcription-blueprint.d.ts +21 -0
- package/dist/types/src/blueprints/transcription-blueprint.d.ts.map +1 -0
- package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts +10 -0
- package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts.map +1 -0
- package/dist/types/src/capabilities/blueprint-definition/index.d.ts +3 -0
- package/dist/types/src/capabilities/blueprint-definition/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +4 -4
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-handler/index.d.ts +3 -0
- package/dist/types/src/capabilities/operation-handler/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-handler/operation-handler.d.ts +5 -0
- package/dist/types/src/capabilities/operation-handler/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/transcriber/index.d.ts +3 -0
- package/dist/types/src/capabilities/transcriber/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/transcriber/transcriber.d.ts +9 -0
- package/dist/types/src/capabilities/transcriber/transcriber.d.ts.map +1 -0
- package/dist/types/src/components/Transcript/Transcript.d.ts +7 -10
- package/dist/types/src/components/Transcript/Transcript.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts +34 -18
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +12 -12
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/transcript-extension.d.ts +3 -7
- package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +1 -1
- package/dist/types/src/components/TranscriptContainer.d.ts +5 -6
- package/dist/types/src/components/TranscriptContainer.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts +8 -7
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts +10 -6
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts +10 -9
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/TranscriptionStory.d.ts +4 -3
- package/dist/types/src/components/stories/TranscriptionStory.d.ts.map +1 -1
- package/dist/types/src/functions/index.d.ts +3 -0
- package/dist/types/src/functions/index.d.ts.map +1 -0
- package/dist/types/src/functions/open.d.ts +11 -0
- package/dist/types/src/functions/open.d.ts.map +1 -0
- package/dist/types/src/functions/summarize.d.ts +11 -0
- package/dist/types/src/functions/summarize.d.ts.map +1 -0
- package/dist/types/src/hooks/useAudioFile.d.ts.map +1 -1
- package/dist/types/src/hooks/useQueueModelAdapter.d.ts +1 -1
- package/dist/types/src/hooks/useQueueModelAdapter.d.ts.map +1 -1
- package/dist/types/src/hooks/useTranscriber.d.ts +2 -2
- package/dist/types/src/hooks/useTranscriber.d.ts.map +1 -1
- package/dist/types/src/hooks/useVoiceInput.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +2 -3
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/segments-normalization/message-normalizer.d.ts +5 -5
- package/dist/types/src/segments-normalization/message-normalizer.d.ts.map +1 -1
- package/dist/types/src/segments-normalization/normalization.d.ts +503 -311
- package/dist/types/src/segments-normalization/normalization.d.ts.map +1 -1
- package/dist/types/src/segments-normalization/utils.d.ts +2 -2
- package/dist/types/src/segments-normalization/utils.d.ts.map +1 -1
- package/dist/types/src/testing/testing.d.ts +10 -10
- package/dist/types/src/testing/testing.d.ts.map +1 -1
- package/dist/types/src/transcriber/index.d.ts +1 -1
- package/dist/types/src/transcriber/index.d.ts.map +1 -1
- package/dist/types/src/transcriber/media-stream-recorder.d.ts +3 -3
- package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcriber.d.ts +4 -4
- package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcription-manager.d.ts +12 -13
- package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +11 -11
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/TranscriptAction.d.ts +25 -0
- package/dist/types/src/types/TranscriptAction.d.ts.map +1 -0
- package/dist/types/src/types/capabilities.d.ts +18 -0
- package/dist/types/src/types/capabilities.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +3 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +0 -26
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/render-byline.d.ts +4 -0
- package/dist/types/src/util/render-byline.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +88 -72
- package/src/TranscriptionPlugin.tsx +40 -58
- package/src/blueprints/index.ts +5 -0
- package/src/blueprints/transcription-blueprint.ts +25 -0
- package/src/capabilities/blueprint-definition/blueprint-definition.ts +24 -0
- package/src/capabilities/blueprint-definition/index.ts +7 -0
- package/src/capabilities/index.ts +4 -7
- package/src/capabilities/operation-handler/index.ts +7 -0
- package/src/capabilities/operation-handler/operation-handler.ts +25 -0
- package/src/capabilities/operation-resolver/index.ts +7 -0
- package/src/capabilities/operation-resolver/operation-resolver.ts +25 -0
- package/src/capabilities/react-surface/index.ts +7 -0
- package/src/capabilities/react-surface/react-surface.tsx +28 -0
- package/src/capabilities/transcriber/index.ts +7 -0
- package/src/capabilities/transcriber/transcriber.ts +85 -0
- package/src/components/Transcript/Transcript.stories.tsx +61 -57
- package/src/components/Transcript/Transcript.tsx +25 -59
- package/src/components/Transcript/deprecated/OldTranscript.tsx +11 -11
- package/src/components/Transcript/transcript-extension.ts +13 -46
- package/src/components/TranscriptContainer.tsx +19 -15
- package/src/components/stories/FileTranscription.stories.tsx +80 -70
- package/src/components/stories/KeyWordRecognition.stories.tsx +17 -13
- package/src/components/stories/MicrophoneTranscription.stories.tsx +89 -87
- package/src/components/stories/TranscriptionStory.tsx +14 -14
- package/src/functions/index.ts +6 -0
- package/src/functions/open.ts +37 -0
- package/src/functions/summarize.ts +103 -0
- package/src/hooks/useAudioFile.ts +49 -53
- package/src/hooks/useQueueModelAdapter.ts +1 -1
- package/src/hooks/useTranscriber.ts +12 -7
- package/src/hooks/useVoiceInput.ts +4 -3
- package/src/index.ts +1 -1
- package/src/meta.ts +9 -6
- package/src/model/model.test.ts +27 -21
- package/src/segments-normalization/message-normalizer.ts +19 -14
- package/src/segments-normalization/normalization.test.ts +25 -32
- package/src/segments-normalization/normalization.ts +59 -49
- package/src/segments-normalization/utils.ts +2 -2
- package/src/testing/testing.ts +42 -32
- package/src/transcriber/index.ts +1 -1
- package/src/transcriber/media-stream-recorder.ts +4 -4
- package/src/transcriber/transcriber.browser.test.ts +6 -5
- package/src/transcriber/transcriber.ts +9 -11
- package/src/transcriber/transcription-manager.ts +37 -52
- package/src/translations.ts +6 -4
- package/src/types/TranscriptAction.ts +32 -0
- package/src/types/capabilities.ts +33 -0
- package/src/types/index.ts +3 -1
- package/src/types/types.ts +0 -23
- package/src/util/index.ts +1 -0
- package/src/util/render-byline.ts +33 -0
- package/dist/lib/browser/TranscriptContainer-H3AZQ4CQ.mjs +0 -11
- package/dist/lib/browser/chunk-53AXUEIQ.mjs.map +0 -7
- package/dist/lib/browser/chunk-GOF7MJNV.mjs +0 -19
- package/dist/lib/browser/chunk-GOF7MJNV.mjs.map +0 -7
- package/dist/lib/browser/chunk-IQ5ZRMHZ.mjs.map +0 -7
- package/dist/lib/browser/chunk-OSISJM2F.mjs +0 -55
- package/dist/lib/browser/chunk-OSISJM2F.mjs.map +0 -7
- package/dist/lib/browser/chunk-W2KNYJD6.mjs +0 -16
- package/dist/lib/browser/chunk-W2KNYJD6.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-BGADCHVM.mjs +0 -30
- package/dist/lib/browser/intent-resolver-BGADCHVM.mjs.map +0 -7
- package/dist/lib/browser/react-surface-HMJS5FSS.mjs +0 -34
- package/dist/lib/browser/react-surface-HMJS5FSS.mjs.map +0 -7
- package/dist/lib/browser/transcriber-OYPLZFG5.mjs.map +0 -7
- package/dist/lib/node/TranscriptContainer-KIG3GMAB.cjs +0 -32
- package/dist/lib/node/TranscriptContainer-KIG3GMAB.cjs.map +0 -7
- package/dist/lib/node/chunk-3PYT3BDM.cjs +0 -40
- package/dist/lib/node/chunk-3PYT3BDM.cjs.map +0 -7
- package/dist/lib/node/chunk-6LW5RA3K.cjs +0 -75
- package/dist/lib/node/chunk-6LW5RA3K.cjs.map +0 -7
- package/dist/lib/node/chunk-AFUZI63A.cjs +0 -42
- package/dist/lib/node/chunk-AFUZI63A.cjs.map +0 -7
- package/dist/lib/node/chunk-CVUN3UO7.cjs +0 -778
- package/dist/lib/node/chunk-CVUN3UO7.cjs.map +0 -7
- package/dist/lib/node/chunk-FKDJNJ57.cjs +0 -35
- package/dist/lib/node/chunk-FKDJNJ57.cjs.map +0 -7
- package/dist/lib/node/chunk-ZFAUMZXE.cjs +0 -518
- package/dist/lib/node/chunk-ZFAUMZXE.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -133
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-LL3TTI4H.cjs +0 -45
- package/dist/lib/node/intent-resolver-LL3TTI4H.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/react-surface-N25TBBG4.cjs +0 -56
- package/dist/lib/node/react-surface-N25TBBG4.cjs.map +0 -7
- package/dist/lib/node/transcriber-6J4FVFSZ.cjs +0 -68
- package/dist/lib/node/transcriber-6J4FVFSZ.cjs.map +0 -7
- package/dist/lib/node/types/index.cjs +0 -36
- package/dist/lib/node/types/index.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-56QHOX4A.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FH75X4JC.mjs +0 -56
- package/dist/lib/node-esm/chunk-FH75X4JC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-MFJPEIVB.mjs +0 -17
- package/dist/lib/node-esm/chunk-MFJPEIVB.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PRL64SRU.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-TXMDLLBR.mjs +0 -21
- package/dist/lib/node-esm/chunk-TXMDLLBR.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-5LVCYSJS.mjs +0 -31
- package/dist/lib/node-esm/intent-resolver-5LVCYSJS.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-JGQSYGRR.mjs +0 -35
- package/dist/lib/node-esm/react-surface-JGQSYGRR.mjs.map +0 -7
- package/dist/lib/node-esm/transcriber-TVG2MBBN.mjs.map +0 -7
- package/dist/types/src/capabilities/capabilities.d.ts +0 -17
- package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface.d.ts +0 -4
- package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
- package/dist/types/src/capabilities/transcriber.d.ts +0 -8
- package/dist/types/src/capabilities/transcriber.d.ts.map +0 -1
- package/dist/types/src/types/schema.d.ts +0 -41
- package/dist/types/src/types/schema.d.ts.map +0 -1
- package/src/capabilities/capabilities.ts +0 -33
- package/src/capabilities/intent-resolver.ts +0 -24
- package/src/capabilities/react-surface.tsx +0 -22
- package/src/capabilities/transcriber.ts +0 -76
- package/src/types/schema.ts +0 -41
- /package/dist/lib/browser/{TranscriptContainer-H3AZQ4CQ.mjs.map → TranscriptContainer-MV3JBKLS.mjs.map} +0 -0
- /package/dist/lib/{node-esm/TranscriptContainer-G75LDEO5.mjs.map → browser/blueprints/index.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-UDCCT32F.mjs.map → chunk-RUKY36XW.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-MFJO7EKD.mjs.map → chunk-SNZAN34I.mjs.map} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as Schema from 'effect/Schema';
|
|
7
|
+
|
|
8
|
+
import { Database, Obj, Type } from '@dxos/echo';
|
|
9
|
+
import { QueueService, defineFunction } from '@dxos/functions';
|
|
10
|
+
import { Message, Transcript } from '@dxos/types';
|
|
11
|
+
|
|
12
|
+
import { renderByline } from '../util';
|
|
13
|
+
|
|
14
|
+
export default defineFunction({
|
|
15
|
+
key: 'dxos.org/function/transcription/open',
|
|
16
|
+
name: 'Open',
|
|
17
|
+
description: 'Opens and reads the contents of a transcription object.',
|
|
18
|
+
inputSchema: Schema.Struct({
|
|
19
|
+
transcript: Type.Ref(Transcript.Transcript).annotations({
|
|
20
|
+
description: 'The ID of the transcription object.',
|
|
21
|
+
}),
|
|
22
|
+
}),
|
|
23
|
+
outputSchema: Schema.Struct({
|
|
24
|
+
content: Schema.String,
|
|
25
|
+
}),
|
|
26
|
+
handler: Effect.fn(function* ({ data: { transcript } }) {
|
|
27
|
+
const transcriptObj = yield* Database.load(transcript);
|
|
28
|
+
const { dxn } = yield* Effect.promise(() => transcriptObj.queue.load());
|
|
29
|
+
const queue = yield* QueueService.getQueue(dxn);
|
|
30
|
+
yield* Effect.promise(() => queue?.queryObjects());
|
|
31
|
+
const content = queue?.objects
|
|
32
|
+
.filter((message) => Obj.instanceOf(Message.Message, message))
|
|
33
|
+
.flatMap((message, index) => renderByline([])(message, index))
|
|
34
|
+
.join('\n\n');
|
|
35
|
+
return { content };
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Array from 'effect/Array';
|
|
6
|
+
import * as Effect from 'effect/Effect';
|
|
7
|
+
import * as Function from 'effect/Function';
|
|
8
|
+
import * as Layer from 'effect/Layer';
|
|
9
|
+
import * as Option from 'effect/Option';
|
|
10
|
+
import * as Schema from 'effect/Schema';
|
|
11
|
+
|
|
12
|
+
import { AiService, ConsolePrinter, ToolExecutionService, ToolResolverService } from '@dxos/ai';
|
|
13
|
+
import { AiSession, GenerationObserver } from '@dxos/assistant';
|
|
14
|
+
import { TracingService, defineFunction } from '@dxos/functions';
|
|
15
|
+
import { trim } from '@dxos/util';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Summarize a transcript of a meeting.
|
|
19
|
+
*/
|
|
20
|
+
export default defineFunction({
|
|
21
|
+
key: 'dxos.org/function/transcription/summarize',
|
|
22
|
+
name: 'Summarize',
|
|
23
|
+
description: 'Summarize a transcript of a meeting.',
|
|
24
|
+
inputSchema: Schema.Struct({
|
|
25
|
+
transcript: Schema.String.annotations({
|
|
26
|
+
description: 'The transcript of the meeting.',
|
|
27
|
+
}),
|
|
28
|
+
notes: Schema.optional(Schema.String).annotations({
|
|
29
|
+
description: 'Additional notes from the participants.',
|
|
30
|
+
}),
|
|
31
|
+
}),
|
|
32
|
+
outputSchema: Schema.Struct({
|
|
33
|
+
summary: Schema.String.annotations({
|
|
34
|
+
description: 'The summary of the transcript.',
|
|
35
|
+
}),
|
|
36
|
+
}),
|
|
37
|
+
handler: Effect.fnUntraced(
|
|
38
|
+
function* ({ data: { transcript, notes } }) {
|
|
39
|
+
const result = yield* new AiSession().run({
|
|
40
|
+
prompt: `Transcript: ${transcript}\n\nNotes: ${notes}`,
|
|
41
|
+
history: [],
|
|
42
|
+
system: systemPrompt,
|
|
43
|
+
observer: GenerationObserver.fromPrinter(new ConsolePrinter({ tag: 'summarize' })),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const summary = Function.pipe(
|
|
47
|
+
result,
|
|
48
|
+
Array.findLast((msg) => msg.sender.role === 'assistant' && msg.blocks.some((block) => block._tag === 'text')),
|
|
49
|
+
Option.flatMap((msg) =>
|
|
50
|
+
Function.pipe(
|
|
51
|
+
msg.blocks,
|
|
52
|
+
Array.findLast((block) => block._tag === 'text'),
|
|
53
|
+
Option.map((block) => block.text),
|
|
54
|
+
),
|
|
55
|
+
),
|
|
56
|
+
Option.getOrThrowWith(() => new Error('No summary found')),
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return { summary };
|
|
60
|
+
},
|
|
61
|
+
Effect.provide(
|
|
62
|
+
Layer.mergeAll(
|
|
63
|
+
AiService.model('@anthropic/claude-sonnet-4-0'),
|
|
64
|
+
ToolResolverService.layerEmpty,
|
|
65
|
+
ToolExecutionService.layerEmpty,
|
|
66
|
+
TracingService.layerNoop,
|
|
67
|
+
),
|
|
68
|
+
),
|
|
69
|
+
),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const systemPrompt = trim`
|
|
73
|
+
You are a helpful assistant that summarizes transcripts of meetings.
|
|
74
|
+
|
|
75
|
+
# Goal
|
|
76
|
+
Create a markdown summary of the meeting transcript with text notes provided.
|
|
77
|
+
Notes are very important so make sure to include them in the summary if they contain meaningful information.
|
|
78
|
+
|
|
79
|
+
# Formatting
|
|
80
|
+
- Format the summary as a markdown document without extra comments like "Here is the summary of the transcript:".
|
|
81
|
+
- Use markdown formatting for headings and bullet points.
|
|
82
|
+
- Format the summary as a list of key points and takeaways.
|
|
83
|
+
- All names of people should be in bold.
|
|
84
|
+
|
|
85
|
+
# Note Taking
|
|
86
|
+
- Correlate items in the summary with the person of origin to build a coherent narrative.
|
|
87
|
+
- Include short quotes verbatim where appropriate. Especially when concerned with design decisions and problem descriptions.
|
|
88
|
+
|
|
89
|
+
# Tasks
|
|
90
|
+
At the end of the summary include tasks.
|
|
91
|
+
Extract only the tasks that are:
|
|
92
|
+
- Directly actionable.
|
|
93
|
+
- Clearly assigned to a person or team (or can easily be inferred).
|
|
94
|
+
- Strongly implied by the conversation and/or user note (no speculative tasks).
|
|
95
|
+
- Specific enough that someone reading them would know exactly what to do next.
|
|
96
|
+
|
|
97
|
+
Format all tasks as markdown checkboxes using the syntax:
|
|
98
|
+
- [ ] Task description.
|
|
99
|
+
|
|
100
|
+
Additional information can be included (indented).
|
|
101
|
+
|
|
102
|
+
If no actionable tasks are found, omit this tasks section.
|
|
103
|
+
`;
|
|
@@ -20,67 +20,63 @@ export const useAudioFile = (audioUrl: string, constraints?: MediaTrackConstrain
|
|
|
20
20
|
const ctx = new Context();
|
|
21
21
|
|
|
22
22
|
scheduleTask(ctx, async () => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
URL.
|
|
28
|
-
|
|
23
|
+
// TODO(wittjosiah): Fetch to external url fails in headless storybook test.
|
|
24
|
+
try {
|
|
25
|
+
const response = await fetch(audioUrl);
|
|
26
|
+
const blob = await response.blob();
|
|
27
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
28
|
+
ctx.onDispose(() => {
|
|
29
|
+
URL.revokeObjectURL(objectUrl);
|
|
30
|
+
});
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
const audio = new Audio();
|
|
33
|
+
audio.src = objectUrl;
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
log.info('starting...');
|
|
46
|
-
try {
|
|
47
|
-
// Try to play the audio
|
|
48
|
-
await audio.play();
|
|
35
|
+
await new Promise<void>((resolve, reject) => {
|
|
36
|
+
audio.addEventListener(
|
|
37
|
+
'error',
|
|
38
|
+
(err) => {
|
|
39
|
+
log.error('error', { err });
|
|
40
|
+
reject(err);
|
|
41
|
+
},
|
|
42
|
+
{ once: true },
|
|
43
|
+
);
|
|
44
|
+
audio.addEventListener(
|
|
45
|
+
'canplay',
|
|
46
|
+
async () => {
|
|
49
47
|
resolve();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
},
|
|
56
|
-
{ once: true },
|
|
57
|
-
);
|
|
58
|
-
audio.load();
|
|
59
|
-
});
|
|
48
|
+
},
|
|
49
|
+
{ once: true },
|
|
50
|
+
);
|
|
51
|
+
audio.load();
|
|
52
|
+
});
|
|
60
53
|
|
|
61
|
-
|
|
54
|
+
const audioCtx = new AudioContext();
|
|
62
55
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
// Resume AudioContext if it's suspended.
|
|
57
|
+
if (audioCtx.state === 'suspended') {
|
|
58
|
+
await audioCtx.resume();
|
|
59
|
+
}
|
|
67
60
|
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
const destination = audioCtx.createMediaStreamDestination();
|
|
62
|
+
destination.channelCount = 1;
|
|
70
63
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
const source = audioCtx.createMediaElementSource(audio);
|
|
65
|
+
source.connect(destination);
|
|
66
|
+
const track = destination.stream.getAudioTracks()[0];
|
|
67
|
+
if (constraints) {
|
|
68
|
+
await track.applyConstraints(constraints).catch((err) => log.catch(err));
|
|
69
|
+
}
|
|
77
70
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
71
|
+
// Also connect to speakers so audio is audible.
|
|
72
|
+
setStream({
|
|
73
|
+
audio,
|
|
74
|
+
stream: destination.stream,
|
|
75
|
+
track: destination.stream.getAudioTracks()[0],
|
|
76
|
+
});
|
|
77
|
+
} catch (err) {
|
|
78
|
+
log.catch(err);
|
|
79
|
+
}
|
|
84
80
|
});
|
|
85
81
|
|
|
86
82
|
return () => {
|
|
@@ -12,7 +12,7 @@ import { type ChunkRenderer, SerializationModel } from '../model';
|
|
|
12
12
|
/**
|
|
13
13
|
* Model adapter for a queue.
|
|
14
14
|
*/
|
|
15
|
-
export const useQueueModelAdapter = <T extends Obj.
|
|
15
|
+
export const useQueueModelAdapter = <T extends Obj.Unknown>(
|
|
16
16
|
renderer: ChunkRenderer<T>,
|
|
17
17
|
queue: Queue<T> | undefined,
|
|
18
18
|
initialChunks: T[] = [],
|
|
@@ -4,30 +4,35 @@
|
|
|
4
4
|
|
|
5
5
|
import { useEffect, useMemo } from 'react';
|
|
6
6
|
|
|
7
|
-
import { useCapabilities } from '@dxos/app-framework';
|
|
7
|
+
import { useCapabilities } from '@dxos/app-framework/ui';
|
|
8
8
|
|
|
9
|
-
import { TranscriptionCapabilities } from '../capabilities';
|
|
10
9
|
import { type Transcriber } from '../transcriber';
|
|
10
|
+
import { TranscriptionCapabilities } from '../types';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Records audio while user is speaking and transcribes it after user is done speaking.
|
|
14
14
|
*/
|
|
15
15
|
export const useTranscriber = ({
|
|
16
16
|
audioStreamTrack,
|
|
17
|
-
onSegments,
|
|
18
|
-
transcriberConfig,
|
|
19
17
|
recorderConfig,
|
|
18
|
+
transcriberConfig,
|
|
19
|
+
onSegments,
|
|
20
20
|
}: Partial<TranscriptionCapabilities.GetTranscriberProps>) => {
|
|
21
21
|
const [getTranscriber] = useCapabilities(TranscriptionCapabilities.Transcriber);
|
|
22
22
|
|
|
23
23
|
// Initialize audio transcription.
|
|
24
24
|
const transcriber = useMemo<Transcriber | undefined>(() => {
|
|
25
|
-
if (!
|
|
25
|
+
if (!getTranscriber || !audioStreamTrack || !onSegments) {
|
|
26
26
|
return undefined;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
return getTranscriber({
|
|
30
|
-
|
|
29
|
+
return getTranscriber({
|
|
30
|
+
audioStreamTrack,
|
|
31
|
+
recorderConfig,
|
|
32
|
+
transcriberConfig,
|
|
33
|
+
onSegments,
|
|
34
|
+
});
|
|
35
|
+
}, [getTranscriber, audioStreamTrack, recorderConfig, transcriberConfig, onSegments]);
|
|
31
36
|
|
|
32
37
|
useEffect(() => {
|
|
33
38
|
return () => {
|
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { scheduleMicroTask } from '@dxos/async';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
10
|
import { useSoundEffect } from '@dxos/react-ui-sfx';
|
|
11
11
|
|
|
12
|
+
import { type TranscriberProps } from '../transcriber';
|
|
13
|
+
|
|
12
14
|
import { useAudioTrack } from './useAudioTrack';
|
|
13
15
|
import { useTranscriber } from './useTranscriber';
|
|
14
|
-
import { type TranscriberParams } from '../transcriber';
|
|
15
16
|
|
|
16
17
|
export type UseVoiceInputProps = {
|
|
17
18
|
active?: boolean;
|
|
@@ -25,7 +26,7 @@ export const useVoiceInput = ({ active, onUpdate }: UseVoiceInputProps) => {
|
|
|
25
26
|
const soundStart = useSoundEffect('StartRecording');
|
|
26
27
|
const soundStop = useSoundEffect('StopRecording');
|
|
27
28
|
|
|
28
|
-
const handleSegments = useCallback<
|
|
29
|
+
const handleSegments = useCallback<TranscriberProps['onSegments']>(async (segments) => {
|
|
29
30
|
const text = segments.map((str) => str.text.trim().replace(/[^\w\s]/g, '')).join(' ');
|
|
30
31
|
onUpdate(text);
|
|
31
32
|
}, []);
|
package/src/index.ts
CHANGED
package/src/meta.ts
CHANGED
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type
|
|
5
|
+
import { type Plugin } from '@dxos/app-framework';
|
|
6
|
+
import { trim } from '@dxos/util';
|
|
6
7
|
|
|
7
|
-
export const
|
|
8
|
-
|
|
9
|
-
export const meta: PluginMeta = {
|
|
10
|
-
id: TRANSCRIPTION_PLUGIN,
|
|
8
|
+
export const meta: Plugin.Meta = {
|
|
9
|
+
id: 'dxos.org/plugin/transcription',
|
|
11
10
|
name: 'Transcription',
|
|
12
|
-
description:
|
|
11
|
+
description: trim`
|
|
12
|
+
Real-time voice-to-text transcription service for capturing spoken content.
|
|
13
|
+
Convert audio input into searchable text that integrates seamlessly with notes and documents.
|
|
14
|
+
`,
|
|
13
15
|
icon: 'ph--microphone--regular',
|
|
16
|
+
iconHue: 'sky',
|
|
14
17
|
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-transcription',
|
|
15
18
|
tags: ['labs'],
|
|
16
19
|
screenshots: [],
|
package/src/model/model.test.ts
CHANGED
|
@@ -7,18 +7,18 @@ import { describe, test } from 'vitest';
|
|
|
7
7
|
|
|
8
8
|
import { Obj } from '@dxos/echo';
|
|
9
9
|
import type { ObjectId } from '@dxos/keys';
|
|
10
|
-
import {
|
|
10
|
+
import { Message } from '@dxos/types';
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { type ChunkRenderer, DocumentAdapter, SerializationModel } from './model';
|
|
13
13
|
|
|
14
|
-
const blockToMarkdown: ChunkRenderer<
|
|
15
|
-
message:
|
|
14
|
+
const blockToMarkdown: ChunkRenderer<Message.Message> = (
|
|
15
|
+
message: Message.Message,
|
|
16
16
|
index: number,
|
|
17
17
|
debug = true,
|
|
18
18
|
): string[] => {
|
|
19
19
|
return [
|
|
20
20
|
`###### ${message.sender.name}`,
|
|
21
|
-
...message.blocks.filter((block) => block.
|
|
21
|
+
...message.blocks.filter((block) => block._tag === 'transcript').map((block) => block.text),
|
|
22
22
|
'',
|
|
23
23
|
];
|
|
24
24
|
};
|
|
@@ -27,17 +27,17 @@ const createDate = () => new Date().toISOString();
|
|
|
27
27
|
|
|
28
28
|
describe('SerializationModel', () => {
|
|
29
29
|
test('basic', ({ expect }) => {
|
|
30
|
-
const model = new SerializationModel<
|
|
30
|
+
const model = new SerializationModel<Message.Message>(blockToMarkdown);
|
|
31
31
|
expect(model.chunks.length).to.eq(0);
|
|
32
32
|
expect(model.doc.toString()).to.eq('');
|
|
33
33
|
|
|
34
34
|
// Create message.
|
|
35
|
-
const message = Obj.make(
|
|
35
|
+
const message = Obj.make(Message.Message, {
|
|
36
36
|
created: createDate(),
|
|
37
37
|
sender: { name: 'Alice' },
|
|
38
38
|
blocks: [
|
|
39
39
|
{
|
|
40
|
-
|
|
40
|
+
_tag: 'transcript',
|
|
41
41
|
started: createDate(),
|
|
42
42
|
text: 'Hello world!',
|
|
43
43
|
},
|
|
@@ -51,7 +51,9 @@ describe('SerializationModel', () => {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// Update message.
|
|
54
|
-
|
|
54
|
+
Obj.change(message, (m) => {
|
|
55
|
+
m.blocks.push({ _tag: 'transcript', started: createDate(), text: 'Hello again!' });
|
|
56
|
+
});
|
|
55
57
|
model.updateChunk(message);
|
|
56
58
|
{
|
|
57
59
|
const text = model.doc.toString();
|
|
@@ -62,19 +64,19 @@ describe('SerializationModel', () => {
|
|
|
62
64
|
|
|
63
65
|
test('sync - append', ({ expect }) => {
|
|
64
66
|
const view = new EditorView({ extensions: [], doc: '' });
|
|
65
|
-
const model = new SerializationModel<
|
|
67
|
+
const model = new SerializationModel<Message.Message>(blockToMarkdown);
|
|
66
68
|
const adapter = new DocumentAdapter(view);
|
|
67
69
|
expect(adapter.lineCount()).to.eq(0);
|
|
68
70
|
expect(view.state.doc.toString()).to.eq('');
|
|
69
71
|
|
|
70
72
|
// Append message.
|
|
71
73
|
{
|
|
72
|
-
const message = Obj.make(
|
|
74
|
+
const message = Obj.make(Message.Message, {
|
|
73
75
|
created: createDate(),
|
|
74
76
|
sender: { name: 'Alice' },
|
|
75
77
|
blocks: [
|
|
76
78
|
{
|
|
77
|
-
|
|
79
|
+
_tag: 'transcript',
|
|
78
80
|
started: createDate(),
|
|
79
81
|
text: 'Hello world!',
|
|
80
82
|
},
|
|
@@ -87,12 +89,12 @@ describe('SerializationModel', () => {
|
|
|
87
89
|
|
|
88
90
|
// Append message.
|
|
89
91
|
{
|
|
90
|
-
const message = Obj.make(
|
|
92
|
+
const message = Obj.make(Message.Message, {
|
|
91
93
|
created: createDate(),
|
|
92
94
|
sender: { name: 'Bob' },
|
|
93
95
|
blocks: [
|
|
94
96
|
{
|
|
95
|
-
|
|
97
|
+
_tag: 'transcript',
|
|
96
98
|
started: createDate(),
|
|
97
99
|
text: 'Hello world!',
|
|
98
100
|
},
|
|
@@ -106,7 +108,7 @@ describe('SerializationModel', () => {
|
|
|
106
108
|
|
|
107
109
|
test('sync - append, update, delete', ({ expect }) => {
|
|
108
110
|
const view = new EditorView({ extensions: [], doc: '' });
|
|
109
|
-
const model = new SerializationModel<
|
|
111
|
+
const model = new SerializationModel<Message.Message>(blockToMarkdown);
|
|
110
112
|
const adapter = new DocumentAdapter(view);
|
|
111
113
|
expect(adapter.lineCount()).to.eq(0);
|
|
112
114
|
|
|
@@ -114,12 +116,12 @@ describe('SerializationModel', () => {
|
|
|
114
116
|
|
|
115
117
|
// Append message.
|
|
116
118
|
{
|
|
117
|
-
const message = Obj.make(
|
|
119
|
+
const message = Obj.make(Message.Message, {
|
|
118
120
|
created: createDate(),
|
|
119
121
|
sender: { name: 'Alice' },
|
|
120
122
|
blocks: [
|
|
121
123
|
{
|
|
122
|
-
|
|
124
|
+
_tag: 'transcript',
|
|
123
125
|
started: createDate(),
|
|
124
126
|
text: 'Hello world!',
|
|
125
127
|
},
|
|
@@ -131,13 +133,17 @@ describe('SerializationModel', () => {
|
|
|
131
133
|
expect(view.state.doc.toString()).to.eq('###### Alice\nHello world!\n\n');
|
|
132
134
|
|
|
133
135
|
// Update message (add block).
|
|
134
|
-
|
|
136
|
+
Obj.change(message, (m) => {
|
|
137
|
+
m.blocks.push({ _tag: 'transcript', started: createDate(), text: 'Hello again!' });
|
|
138
|
+
});
|
|
135
139
|
model.updateChunk(message);
|
|
136
140
|
model.sync(adapter);
|
|
137
141
|
expect(view.state.doc.toString()).to.eq('###### Alice\nHello world!\nHello again!\n\n');
|
|
138
142
|
|
|
139
143
|
// Update message (remove block).
|
|
140
|
-
|
|
144
|
+
Obj.change(message, (m) => {
|
|
145
|
+
m.blocks.splice(0, 1);
|
|
146
|
+
});
|
|
141
147
|
model.updateChunk(message);
|
|
142
148
|
model.sync(adapter);
|
|
143
149
|
expect(view.state.doc.toString()).to.eq('###### Alice\nHello again!\n\n');
|
|
@@ -147,10 +153,10 @@ describe('SerializationModel', () => {
|
|
|
147
153
|
|
|
148
154
|
// Append message.
|
|
149
155
|
{
|
|
150
|
-
const message = Obj.make(
|
|
156
|
+
const message = Obj.make(Message.Message, {
|
|
151
157
|
created: createDate(),
|
|
152
158
|
sender: { name: 'Bob' },
|
|
153
|
-
blocks: [{
|
|
159
|
+
blocks: [{ _tag: 'transcript', started: createDate(), text: 'Hello again!' }],
|
|
154
160
|
});
|
|
155
161
|
model.appendChunk(message);
|
|
156
162
|
model.sync(adapter);
|
|
@@ -6,24 +6,22 @@
|
|
|
6
6
|
// Copyright 2025 DXOS.org
|
|
7
7
|
//
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
import { asyncTimeout, DeferredTask } from '@dxos/async';
|
|
9
|
+
import { DeferredTask, asyncTimeout } from '@dxos/async';
|
|
12
10
|
import { LifecycleState, Resource } from '@dxos/context';
|
|
13
11
|
import { type Queue } from '@dxos/echo-db';
|
|
14
|
-
import { type FunctionExecutor } from '@dxos/functions';
|
|
12
|
+
import { type FunctionExecutor } from '@dxos/functions-runtime';
|
|
15
13
|
import { log } from '@dxos/log';
|
|
16
|
-
import { type
|
|
14
|
+
import { type Message } from '@dxos/types';
|
|
17
15
|
|
|
18
|
-
import { type MessageWithRangeId, sentenceNormalization } from './normalization';
|
|
16
|
+
import { type MessageWithRangeId, type NormalizationOutput, sentenceNormalization } from './normalization';
|
|
19
17
|
import { getActorId } from './utils';
|
|
20
18
|
|
|
21
19
|
const PROCESSING_TIMEOUT = 20_000; // ms
|
|
22
20
|
const MAX_RANGE_ID_COUNT = 10;
|
|
23
21
|
|
|
24
|
-
export type
|
|
22
|
+
export type SegmentsNormalizerProps = {
|
|
25
23
|
functionExecutor: FunctionExecutor;
|
|
26
|
-
queue: Queue<
|
|
24
|
+
queue: Queue<Message.Message>;
|
|
27
25
|
startingCursor: QueueCursor;
|
|
28
26
|
};
|
|
29
27
|
|
|
@@ -36,13 +34,13 @@ export type QueueCursor = {
|
|
|
36
34
|
// TODO(mykola): .
|
|
37
35
|
export class MessageNormalizer extends Resource {
|
|
38
36
|
private readonly _functionExecutor: FunctionExecutor;
|
|
39
|
-
private _queue: Queue<
|
|
37
|
+
private _queue: Queue<Message.Message>;
|
|
40
38
|
private _cursor: QueueCursor;
|
|
41
39
|
private _messagesToProcess: MessageWithRangeId[] = [];
|
|
42
40
|
private _normalizationTask?: DeferredTask;
|
|
43
41
|
private _lastProcessedMessageIds?: string[];
|
|
44
42
|
|
|
45
|
-
constructor({ functionExecutor, queue, startingCursor }:
|
|
43
|
+
constructor({ functionExecutor, queue, startingCursor }: SegmentsNormalizerProps) {
|
|
46
44
|
super();
|
|
47
45
|
this._functionExecutor = functionExecutor;
|
|
48
46
|
this._queue = queue;
|
|
@@ -51,7 +49,8 @@ export class MessageNormalizer extends Resource {
|
|
|
51
49
|
|
|
52
50
|
protected override async _open(): Promise<void> {
|
|
53
51
|
this._normalizationTask = new DeferredTask(this._ctx, () => this._processMessages());
|
|
54
|
-
|
|
52
|
+
|
|
53
|
+
const updateMessages = () => {
|
|
55
54
|
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
56
55
|
return;
|
|
57
56
|
}
|
|
@@ -62,8 +61,14 @@ export class MessageNormalizer extends Resource {
|
|
|
62
61
|
});
|
|
63
62
|
|
|
64
63
|
this._normalizationTask!.schedule();
|
|
65
|
-
}
|
|
66
|
-
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Initial update.
|
|
67
|
+
updateMessages();
|
|
68
|
+
|
|
69
|
+
// Subscribe to queue changes.
|
|
70
|
+
const unsubscribe = this._queue.subscribe(updateMessages);
|
|
71
|
+
this._ctx.onDispose(unsubscribe);
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
// Need to unpack strings from blocks from messages run them through the function and then pack them back into blocks into messages.
|
|
@@ -81,7 +86,7 @@ export class MessageNormalizer extends Resource {
|
|
|
81
86
|
|
|
82
87
|
try {
|
|
83
88
|
// TODO(mykola): Executor should support timeout.
|
|
84
|
-
const response = await asyncTimeout(
|
|
89
|
+
const response: NormalizationOutput = await asyncTimeout(
|
|
85
90
|
this._functionExecutor.invoke(sentenceNormalization, { messages }),
|
|
86
91
|
PROCESSING_TIMEOUT,
|
|
87
92
|
);
|