@dxos/plugin-transcription 0.8.2-main.12df754 → 0.8.2-main.36232bc
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-4D4BHE7G.mjs → TranscriptContainer-2VFHUHLE.mjs} +3 -3
- package/dist/lib/browser/app-graph-builder-TDP6PYV6.mjs +350 -0
- package/dist/lib/browser/app-graph-builder-TDP6PYV6.mjs.map +7 -0
- package/dist/lib/browser/{chunk-DR3NBV6Q.mjs → chunk-KSUYWWIU.mjs} +105 -78
- package/dist/lib/browser/chunk-KSUYWWIU.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5BE6RTNC.mjs → chunk-LTIQFX4W.mjs} +1 -1
- package/dist/lib/browser/{chunk-5BE6RTNC.mjs.map → chunk-LTIQFX4W.mjs.map} +1 -1
- package/dist/lib/browser/{chunk-RHHJZQPM.mjs → chunk-NFVDICSJ.mjs} +133 -116
- package/dist/lib/browser/chunk-NFVDICSJ.mjs.map +7 -0
- package/dist/lib/browser/chunk-O6RY7FNK.mjs +27 -0
- package/dist/lib/browser/chunk-O6RY7FNK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5Q3R53U3.mjs → chunk-YRWBY6UK.mjs} +9 -21
- package/dist/lib/browser/chunk-YRWBY6UK.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +29 -17
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-ZQQEH27F.mjs → intent-resolver-ZWKYRFE7.mjs} +4 -4
- package/dist/lib/browser/{intent-resolver-ZQQEH27F.mjs.map → intent-resolver-ZWKYRFE7.mjs.map} +2 -2
- package/dist/lib/browser/{meeting-transcription-state-5D52VTHU.mjs → meeting-transcription-state-MNA2XROE.mjs} +2 -2
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-HETJ5XY6.mjs → react-surface-F32UNCKZ.mjs} +18 -7
- package/dist/lib/browser/react-surface-F32UNCKZ.mjs.map +7 -0
- package/dist/lib/browser/settings-6YAHKVKX.mjs +24 -0
- package/dist/lib/browser/settings-6YAHKVKX.mjs.map +7 -0
- package/dist/lib/browser/{transcriber-SMRLU2KY.mjs → transcriber-MSBS4VBI.mjs} +4 -4
- package/dist/lib/browser/types/index.mjs +3 -3
- package/dist/lib/node/{TranscriptContainer-ZWP6UKY6.cjs → TranscriptContainer-E2D7PKO3.cjs} +8 -8
- package/dist/lib/node/{TranscriptContainer-ZWP6UKY6.cjs.map → TranscriptContainer-E2D7PKO3.cjs.map} +2 -2
- package/dist/lib/node/app-graph-builder-W4VDMVGV.cjs +351 -0
- package/dist/lib/node/app-graph-builder-W4VDMVGV.cjs.map +7 -0
- package/dist/lib/node/{chunk-LA73IHCB.cjs → chunk-7XIIUVN3.cjs} +108 -80
- package/dist/lib/node/chunk-7XIIUVN3.cjs.map +7 -0
- package/dist/lib/node/{chunk-3QEJ5EBO.cjs → chunk-IXU57SCA.cjs} +10 -22
- package/dist/lib/node/chunk-IXU57SCA.cjs.map +7 -0
- package/dist/lib/node/{chunk-HYGDHS6X.cjs → chunk-JUGOXWES.cjs} +4 -4
- package/dist/lib/node/{chunk-HYGDHS6X.cjs.map → chunk-JUGOXWES.cjs.map} +1 -1
- package/dist/lib/node/{chunk-KO6MKCED.cjs → chunk-NBC6V3M2.cjs} +136 -118
- package/dist/lib/node/chunk-NBC6V3M2.cjs.map +7 -0
- package/dist/lib/node/{chunk-WXG4Z2EZ.cjs → chunk-TJMZ26GS.cjs} +23 -8
- package/dist/lib/node/chunk-TJMZ26GS.cjs.map +7 -0
- package/dist/lib/node/index.cjs +46 -34
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/{intent-resolver-VY3XWYAA.cjs → intent-resolver-RM4JOCDV.cjs} +8 -8
- package/dist/lib/node/{intent-resolver-VY3XWYAA.cjs.map → intent-resolver-RM4JOCDV.cjs.map} +2 -2
- package/dist/lib/node/{meeting-transcription-state-OYWCY5XE.cjs → meeting-transcription-state-5XLTMWPA.cjs} +6 -6
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-surface-M2JQIIDY.cjs → react-surface-YQHBGPOC.cjs} +20 -11
- package/dist/lib/node/react-surface-YQHBGPOC.cjs.map +7 -0
- package/dist/lib/node/settings-ZMB4XRWS.cjs +38 -0
- package/dist/lib/node/settings-ZMB4XRWS.cjs.map +7 -0
- package/dist/lib/node/{transcriber-E6AAB4SU.cjs → transcriber-55OE4X6I.cjs} +10 -10
- package/dist/lib/node/types/index.cjs +8 -8
- package/dist/lib/node/types/index.cjs.map +1 -1
- package/dist/lib/node-esm/{TranscriptContainer-3HJ752CP.mjs → TranscriptContainer-5N3BSK2S.mjs} +3 -3
- package/dist/lib/node-esm/app-graph-builder-DDDVKUHS.mjs +351 -0
- package/dist/lib/node-esm/app-graph-builder-DDDVKUHS.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-SDMGJZLN.mjs → chunk-4RMJO6QQ.mjs} +133 -116
- package/dist/lib/node-esm/chunk-4RMJO6QQ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-YXZOLOFT.mjs → chunk-5E2MR5XK.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-YXZOLOFT.mjs.map → chunk-5E2MR5XK.mjs.map} +1 -1
- package/dist/lib/node-esm/chunk-HZBSWUJH.mjs +28 -0
- package/dist/lib/node-esm/chunk-HZBSWUJH.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-54HDN33F.mjs → chunk-OS2ITZUL.mjs} +9 -21
- package/dist/lib/node-esm/chunk-OS2ITZUL.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-K3R3YK3S.mjs → chunk-UWF6LM27.mjs} +105 -78
- package/dist/lib/node-esm/chunk-UWF6LM27.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +29 -17
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-FCTNJPWY.mjs → intent-resolver-HDRFXMKP.mjs} +4 -4
- package/dist/lib/node-esm/{intent-resolver-FCTNJPWY.mjs.map → intent-resolver-HDRFXMKP.mjs.map} +2 -2
- package/dist/lib/node-esm/{meeting-transcription-state-XMZJ45P4.mjs → meeting-transcription-state-3WOZ52BQ.mjs} +2 -2
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-PXFSIM6V.mjs → react-surface-DRDNXTFZ.mjs} +18 -7
- package/dist/lib/node-esm/react-surface-DRDNXTFZ.mjs.map +7 -0
- package/dist/lib/node-esm/settings-I35TVDUG.mjs +25 -0
- package/dist/lib/node-esm/settings-I35TVDUG.mjs.map +7 -0
- package/dist/lib/node-esm/{transcriber-REAGRCPY.mjs → transcriber-HH7EMCGH.mjs} +4 -4
- package/dist/lib/node-esm/types/index.mjs +3 -3
- package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +1 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings.d.ts +4 -0
- package/dist/types/src/capabilities/settings.d.ts.map +1 -0
- package/dist/types/src/components/Transcript/Transcript.d.ts +6 -4
- package/dist/types/src/components/Transcript/Transcript.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts +8 -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 +4 -4
- package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +1 -1
- package/dist/types/src/components/TranscriptContainer.d.ts.map +1 -1
- package/dist/types/src/components/TranscriptionSettings/TranscriptionSettings.d.ts +6 -0
- package/dist/types/src/components/TranscriptionSettings/TranscriptionSettings.d.ts.map +1 -0
- package/dist/types/src/components/TranscriptionSettings/index.d.ts +2 -0
- package/dist/types/src/components/TranscriptionSettings/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/transcription.stories.d.ts +6 -3
- package/dist/types/src/components/transcription.stories.d.ts.map +1 -1
- package/dist/types/src/entity-extraction/entity-extraction.d.ts +33 -7
- package/dist/types/src/entity-extraction/entity-extraction.d.ts.map +1 -1
- package/dist/types/src/hooks/useQueueModelAdapter.d.ts +2 -2
- package/dist/types/src/hooks/useQueueModelAdapter.d.ts.map +1 -1
- package/dist/types/src/model/model.d.ts +23 -23
- package/dist/types/src/model/model.d.ts.map +1 -1
- 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 +39 -0
- package/dist/types/src/testing/testing.d.ts.map +1 -0
- package/dist/types/src/transcriber/transcriber.d.ts +2 -2
- package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcription-manager.d.ts +17 -15
- package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +3 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +0 -21
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +5 -1
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/package.json +48 -45
- package/src/TranscriptionPlugin.tsx +29 -12
- package/src/capabilities/app-graph-builder.ts +99 -29
- package/src/capabilities/capabilities.ts +1 -1
- package/src/capabilities/index.ts +1 -0
- package/src/capabilities/intent-resolver.ts +2 -2
- package/src/capabilities/react-surface.tsx +12 -4
- package/src/capabilities/settings.ts +20 -0
- package/src/components/Transcript/Transcript.stories.tsx +71 -35
- package/src/components/Transcript/Transcript.tsx +30 -29
- package/src/components/Transcript/deprecated/{Transcript.tsx → OldTranscript.tsx} +24 -1
- package/src/components/Transcript/transcript-extension.ts +20 -17
- package/src/components/TranscriptContainer.tsx +6 -4
- package/src/components/TranscriptionSettings/TranscriptionSettings.tsx +26 -0
- package/src/components/TranscriptionSettings/index.ts +5 -0
- package/src/components/index.ts +1 -0
- package/src/components/transcription.stories.tsx +77 -29
- package/src/entity-extraction/entity-extraction.test.ts +55 -9
- package/src/entity-extraction/entity-extraction.ts +105 -55
- package/src/entity-extraction/system-prompt.tpl +38 -9
- package/src/hooks/useQueueModelAdapter.ts +44 -11
- package/src/model/model.test.ts +85 -43
- package/src/model/model.ts +59 -59
- package/src/testing/index.ts +5 -0
- package/src/testing/testing.ts +208 -0
- package/src/transcriber/transcriber.browser.test.ts +3 -3
- package/src/transcriber/transcriber.ts +16 -10
- package/src/transcriber/transcription-manager.ts +66 -57
- package/src/translations.ts +2 -0
- package/src/types/schema.ts +1 -24
- package/src/types/types.ts +11 -3
- package/dist/lib/browser/app-graph-builder-I4SSIQMW.mjs +0 -168
- package/dist/lib/browser/app-graph-builder-I4SSIQMW.mjs.map +0 -7
- package/dist/lib/browser/chunk-5Q3R53U3.mjs.map +0 -7
- package/dist/lib/browser/chunk-DR3NBV6Q.mjs.map +0 -7
- package/dist/lib/browser/chunk-GI5LZ4SV.mjs +0 -8
- package/dist/lib/browser/chunk-GI5LZ4SV.mjs.map +0 -7
- package/dist/lib/browser/chunk-RHHJZQPM.mjs.map +0 -7
- package/dist/lib/browser/react-surface-HETJ5XY6.mjs.map +0 -7
- package/dist/lib/node/app-graph-builder-WWC4WNTG.cjs +0 -177
- package/dist/lib/node/app-graph-builder-WWC4WNTG.cjs.map +0 -7
- package/dist/lib/node/chunk-3QEJ5EBO.cjs.map +0 -7
- package/dist/lib/node/chunk-KO6MKCED.cjs.map +0 -7
- package/dist/lib/node/chunk-LA73IHCB.cjs.map +0 -7
- package/dist/lib/node/chunk-WXG4Z2EZ.cjs.map +0 -7
- package/dist/lib/node/react-surface-M2JQIIDY.cjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-PPJQAFSI.mjs +0 -169
- package/dist/lib/node-esm/app-graph-builder-PPJQAFSI.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-54HDN33F.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-K3R3YK3S.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-SDMGJZLN.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XY22OP6H.mjs +0 -10
- package/dist/lib/node-esm/chunk-XY22OP6H.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-PXFSIM6V.mjs.map +0 -7
- package/dist/types/src/components/Transcript/deprecated/Transcript.d.ts +0 -13
- package/dist/types/src/components/Transcript/deprecated/Transcript.d.ts.map +0 -1
- package/dist/types/src/components/Transcript/testings.d.ts +0 -51
- package/dist/types/src/components/Transcript/testings.d.ts.map +0 -1
- package/dist/types/src/testing/test-data.d.ts +0 -73
- package/dist/types/src/testing/test-data.d.ts.map +0 -1
- package/src/components/Transcript/testings.ts +0 -182
- package/src/testing/test-data.ts +0 -314
- /package/dist/lib/browser/{TranscriptContainer-4D4BHE7G.mjs.map → TranscriptContainer-2VFHUHLE.mjs.map} +0 -0
- /package/dist/lib/browser/{meeting-transcription-state-5D52VTHU.mjs.map → meeting-transcription-state-MNA2XROE.mjs.map} +0 -0
- /package/dist/lib/browser/{transcriber-SMRLU2KY.mjs.map → transcriber-MSBS4VBI.mjs.map} +0 -0
- /package/dist/lib/node/{meeting-transcription-state-OYWCY5XE.cjs.map → meeting-transcription-state-5XLTMWPA.cjs.map} +0 -0
- /package/dist/lib/node/{transcriber-E6AAB4SU.cjs.map → transcriber-55OE4X6I.cjs.map} +0 -0
- /package/dist/lib/node-esm/{TranscriptContainer-3HJ752CP.mjs.map → TranscriptContainer-5N3BSK2S.mjs.map} +0 -0
- /package/dist/lib/node-esm/{meeting-transcription-state-XMZJ45P4.mjs.map → meeting-transcription-state-3WOZ52BQ.mjs.map} +0 -0
- /package/dist/lib/node-esm/{transcriber-REAGRCPY.mjs.map → transcriber-HH7EMCGH.mjs.map} +0 -0
|
@@ -5,33 +5,35 @@
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
7
|
import { type Meta, type StoryObj } from '@storybook/react';
|
|
8
|
-
import React, { useEffect, useMemo, useState
|
|
8
|
+
import React, { type FC, useEffect, useMemo, useState } from 'react';
|
|
9
9
|
|
|
10
10
|
import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
|
|
11
11
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
12
|
+
import { ObjectId } from '@dxos/echo-schema';
|
|
12
13
|
import { ClientPlugin } from '@dxos/plugin-client';
|
|
13
14
|
import { PreviewPlugin } from '@dxos/plugin-preview';
|
|
14
15
|
import { SpacePlugin } from '@dxos/plugin-space';
|
|
15
16
|
import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
|
|
16
17
|
import { ThemePlugin } from '@dxos/plugin-theme';
|
|
17
18
|
import { faker } from '@dxos/random';
|
|
18
|
-
import { useSpace } from '@dxos/react-client/echo';
|
|
19
|
+
import { useMembers, useSpace } from '@dxos/react-client/echo';
|
|
19
20
|
import { IconButton, Toolbar } from '@dxos/react-ui';
|
|
20
21
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
21
22
|
import { defaultTx } from '@dxos/react-ui-theme';
|
|
23
|
+
import { Contact, Organization, type MessageType } from '@dxos/schema';
|
|
24
|
+
import { Testing } from '@dxos/schema/testing';
|
|
22
25
|
import { withLayout } from '@dxos/storybook-utils';
|
|
23
26
|
|
|
24
27
|
import { renderMarkdown, Transcript, type TranscriptProps } from './Transcript';
|
|
28
|
+
import { useQueueModelAdapter } from '../../hooks';
|
|
29
|
+
import { SerializationModel } from '../../model';
|
|
25
30
|
import {
|
|
26
|
-
|
|
31
|
+
MessageBuilder,
|
|
27
32
|
TestItem,
|
|
28
33
|
useTestTranscriptionQueue,
|
|
29
34
|
useTestTranscriptionQueueWithEntityExtraction,
|
|
30
|
-
} from '
|
|
31
|
-
import { useQueueModelAdapter } from '../../hooks';
|
|
32
|
-
import { BlockModel } from '../../model';
|
|
35
|
+
} from '../../testing';
|
|
33
36
|
import translations from '../../translations';
|
|
34
|
-
import { type TranscriptBlock } from '../../types';
|
|
35
37
|
|
|
36
38
|
faker.seed(1);
|
|
37
39
|
|
|
@@ -67,45 +69,49 @@ const TranscriptContainer: FC<
|
|
|
67
69
|
);
|
|
68
70
|
};
|
|
69
71
|
|
|
70
|
-
type StoryProps = {
|
|
72
|
+
type StoryProps = { messages?: MessageType[] } & Pick<TranscriptProps, 'ignoreAttention' | 'attendableId'>;
|
|
71
73
|
|
|
72
74
|
/**
|
|
73
|
-
* Basic story mutates array of
|
|
75
|
+
* Basic story mutates array of messages.
|
|
74
76
|
*/
|
|
75
|
-
const BasicStory = ({
|
|
77
|
+
const BasicStory = ({ messages: initialMessages = [], ...props }: StoryProps) => {
|
|
76
78
|
const [reset, setReset] = useState({});
|
|
77
|
-
const builder = useMemo(() => new
|
|
78
|
-
const model = useMemo(
|
|
79
|
+
const builder = useMemo(() => new MessageBuilder(), []);
|
|
80
|
+
const model = useMemo(
|
|
81
|
+
() => new SerializationModel<MessageType>(renderMarkdown([]), initialMessages),
|
|
82
|
+
[initialMessages, reset],
|
|
83
|
+
);
|
|
79
84
|
const [running, setRunning] = useState(true);
|
|
80
|
-
const [
|
|
85
|
+
const [currentMessage, setCurrentMessage] = useState<MessageType | null>(null);
|
|
81
86
|
useEffect(() => {
|
|
82
87
|
if (!running) {
|
|
83
88
|
return;
|
|
84
89
|
}
|
|
85
90
|
|
|
86
|
-
if (!
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
if (!currentMessage) {
|
|
92
|
+
void builder.createMessage().then((message) => {
|
|
93
|
+
model.appendChunk(message);
|
|
94
|
+
setCurrentMessage(message);
|
|
95
|
+
});
|
|
90
96
|
return;
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
const i = setInterval(() => {
|
|
94
|
-
if (
|
|
95
|
-
|
|
100
|
+
if (currentMessage?.blocks.length && currentMessage.blocks.length >= 3) {
|
|
101
|
+
setCurrentMessage(null);
|
|
96
102
|
clearInterval(i);
|
|
97
103
|
return;
|
|
98
104
|
}
|
|
99
105
|
|
|
100
|
-
|
|
101
|
-
model.
|
|
106
|
+
currentMessage.blocks.push(builder.createBlock());
|
|
107
|
+
model.updateChunk(currentMessage);
|
|
102
108
|
}, 3_000);
|
|
103
109
|
|
|
104
110
|
return () => clearInterval(i);
|
|
105
|
-
}, [model,
|
|
111
|
+
}, [model, currentMessage, running]);
|
|
106
112
|
|
|
107
113
|
const handleReset = () => {
|
|
108
|
-
|
|
114
|
+
setCurrentMessage(null);
|
|
109
115
|
setRunning(false);
|
|
110
116
|
setReset({});
|
|
111
117
|
};
|
|
@@ -124,24 +130,54 @@ const BasicStory = ({ blocks: initialBlocks = [], ...props }: StoryProps) => {
|
|
|
124
130
|
/**
|
|
125
131
|
* Queue story mutates queue with model adapter.
|
|
126
132
|
*/
|
|
127
|
-
const QueueStory = ({
|
|
133
|
+
const QueueStory = ({
|
|
134
|
+
messages: initialMessages = [],
|
|
135
|
+
queueId,
|
|
136
|
+
onReset,
|
|
137
|
+
...props
|
|
138
|
+
}: StoryProps & { queueId: ObjectId; onReset: () => void }) => {
|
|
128
139
|
const [running, setRunning] = useState(true);
|
|
129
140
|
const space = useSpace();
|
|
130
|
-
const
|
|
131
|
-
const
|
|
141
|
+
const members = useMembers(space?.key).map((member) => member.identity);
|
|
142
|
+
const queue = useTestTranscriptionQueue(space, queueId, running, 2_000);
|
|
143
|
+
const model = useQueueModelAdapter(renderMarkdown(members), queue, initialMessages);
|
|
132
144
|
|
|
133
|
-
return
|
|
145
|
+
return (
|
|
146
|
+
<TranscriptContainer
|
|
147
|
+
space={space}
|
|
148
|
+
model={model}
|
|
149
|
+
running={running}
|
|
150
|
+
onRunningChange={setRunning}
|
|
151
|
+
onReset={onReset}
|
|
152
|
+
{...props}
|
|
153
|
+
/>
|
|
154
|
+
);
|
|
134
155
|
};
|
|
135
156
|
|
|
157
|
+
// TODO(burdon): Reconcile with QueueStory.
|
|
136
158
|
const EntityExtractionQueueStory = () => {
|
|
137
159
|
const [running, setRunning] = useState(true);
|
|
138
160
|
const space = useSpace();
|
|
139
|
-
const
|
|
140
|
-
const
|
|
161
|
+
const members = useMembers(space?.key).map((member) => member.identity);
|
|
162
|
+
const queue = useTestTranscriptionQueueWithEntityExtraction(space, undefined, running, 2_000);
|
|
163
|
+
const model = useQueueModelAdapter(renderMarkdown(members), queue, []);
|
|
141
164
|
|
|
142
165
|
return <TranscriptContainer space={space} model={model} running={running} onRunningChange={setRunning} />;
|
|
143
166
|
};
|
|
144
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Wrapper remounts on refresh to reload queue.
|
|
170
|
+
*/
|
|
171
|
+
const QueueStoryWrapper = () => {
|
|
172
|
+
const [queueId] = useState(ObjectId.random());
|
|
173
|
+
const [key, setKey] = useState(ObjectId.random().toString());
|
|
174
|
+
const handleReset = () => {
|
|
175
|
+
setKey(ObjectId.random().toString());
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
return <QueueStory key={key} queueId={queueId} onReset={handleReset} />;
|
|
179
|
+
};
|
|
180
|
+
|
|
145
181
|
const meta: Meta<typeof QueueStory> = {
|
|
146
182
|
title: 'plugins/plugin-transcription/Transcript',
|
|
147
183
|
decorators: [
|
|
@@ -150,7 +186,7 @@ const meta: Meta<typeof QueueStory> = {
|
|
|
150
186
|
ThemePlugin({ tx: defaultTx }),
|
|
151
187
|
StorybookLayoutPlugin(),
|
|
152
188
|
ClientPlugin({
|
|
153
|
-
types: [TestItem],
|
|
189
|
+
types: [TestItem, Testing.DocumentType, Contact, Organization],
|
|
154
190
|
onClientInitialized: async (_, client) => {
|
|
155
191
|
await client.halo.createIdentity();
|
|
156
192
|
},
|
|
@@ -170,14 +206,14 @@ const meta: Meta<typeof QueueStory> = {
|
|
|
170
206
|
|
|
171
207
|
export default meta;
|
|
172
208
|
|
|
173
|
-
type Story = StoryObj<
|
|
209
|
+
type Story = StoryObj<typeof QueueStory>;
|
|
174
210
|
|
|
175
211
|
export const Default: Story = {
|
|
176
212
|
render: BasicStory,
|
|
177
213
|
args: {
|
|
178
214
|
ignoreAttention: true,
|
|
179
215
|
attendableId: 'story',
|
|
180
|
-
|
|
216
|
+
messages: await Promise.all(Array.from({ length: 10 }, () => MessageBuilder.singleton.createMessage())),
|
|
181
217
|
},
|
|
182
218
|
};
|
|
183
219
|
|
|
@@ -190,7 +226,7 @@ export const Empty: Story = {
|
|
|
190
226
|
};
|
|
191
227
|
|
|
192
228
|
export const WithQueue: Story = {
|
|
193
|
-
render:
|
|
229
|
+
render: QueueStoryWrapper,
|
|
194
230
|
args: {
|
|
195
231
|
ignoreAttention: true,
|
|
196
232
|
attendableId: 'story',
|
|
@@ -200,7 +236,7 @@ export const WithQueue: Story = {
|
|
|
200
236
|
export const WithEntityExtractionQueue: Story = {
|
|
201
237
|
render: EntityExtractionQueueStory,
|
|
202
238
|
args: {
|
|
203
|
-
|
|
204
|
-
|
|
239
|
+
ignoreAttention: true,
|
|
240
|
+
attendableId: 'story',
|
|
205
241
|
},
|
|
206
242
|
};
|
|
@@ -4,10 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
-
import { DXN } from '@dxos/keys';
|
|
8
|
-
import { log } from '@dxos/log';
|
|
9
|
-
import { resolveRef, useClient } from '@dxos/react-client';
|
|
10
7
|
import { type Space } from '@dxos/react-client/echo';
|
|
8
|
+
import { type Identity } from '@dxos/react-client/halo';
|
|
11
9
|
import { IconButton, type ThemedClassName, useThemeContext } from '@dxos/react-ui';
|
|
12
10
|
import {
|
|
13
11
|
createBasicExtensions,
|
|
@@ -20,26 +18,42 @@ import {
|
|
|
20
18
|
useTextEditor,
|
|
21
19
|
} from '@dxos/react-ui-editor';
|
|
22
20
|
import { mx } from '@dxos/react-ui-theme';
|
|
21
|
+
import { type MessageType } from '@dxos/schema';
|
|
23
22
|
import { isNotFalsy } from '@dxos/util';
|
|
24
23
|
|
|
25
24
|
import { transcript } from './transcript-extension';
|
|
26
|
-
import { type
|
|
27
|
-
import { type TranscriptType
|
|
25
|
+
import { type SerializationModel } from '../../model';
|
|
26
|
+
import { type TranscriptType } from '../../types';
|
|
28
27
|
|
|
29
|
-
export const renderMarkdown =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
export const renderMarkdown =
|
|
29
|
+
(identities: Identity[]) =>
|
|
30
|
+
(message: MessageType, index: number, debug = false): string[] => {
|
|
31
|
+
if (message.sender.role === 'assistant') {
|
|
32
|
+
// Start/stop block.
|
|
33
|
+
return [message.blocks.find((block) => block.type === 'transcription')?.text ?? '', ''];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// TODO(burdon): Use link/reference markup for users (with popover).
|
|
37
|
+
// TODO(burdon): Color and avatar.
|
|
38
|
+
const identity = identities.find((identity) => identity.did === message.sender.identityDid);
|
|
39
|
+
const name =
|
|
40
|
+
identity?.profile?.displayName ??
|
|
41
|
+
message.sender.contact?.target?.fullName ??
|
|
42
|
+
message.sender.name ??
|
|
43
|
+
message.sender.email ??
|
|
44
|
+
message.sender.identityDid;
|
|
45
|
+
const blocks = message.blocks.filter((block) => block.type === 'transcription');
|
|
46
|
+
return [
|
|
47
|
+
`###### ${name}` + (debug ? ` [${index}]:${message.id}` : ''),
|
|
48
|
+
blocks.map((block) => block.text.trim()).join(' '),
|
|
49
|
+
'',
|
|
50
|
+
];
|
|
51
|
+
};
|
|
38
52
|
|
|
39
53
|
export type TranscriptProps = ThemedClassName<{
|
|
40
54
|
transcript?: TranscriptType;
|
|
41
55
|
space?: Space;
|
|
42
|
-
model:
|
|
56
|
+
model: SerializationModel<MessageType>;
|
|
43
57
|
// TODO(wittjosiah): Move to container.
|
|
44
58
|
attendableId?: string;
|
|
45
59
|
ignoreAttention?: boolean;
|
|
@@ -56,7 +70,6 @@ export const Transcript = ({
|
|
|
56
70
|
attendableId,
|
|
57
71
|
ignoreAttention,
|
|
58
72
|
}: TranscriptProps) => {
|
|
59
|
-
const client = useClient();
|
|
60
73
|
const { themeMode } = useThemeContext();
|
|
61
74
|
const { parentRef } = useTextEditor(() => {
|
|
62
75
|
return {
|
|
@@ -65,19 +78,7 @@ export const Transcript = ({
|
|
|
65
78
|
createMarkdownExtensions({ themeMode }),
|
|
66
79
|
createThemeExtensions({ themeMode }),
|
|
67
80
|
decorateMarkdown(),
|
|
68
|
-
space &&
|
|
69
|
-
preview({
|
|
70
|
-
onLookup: async ({ label, ref }) => {
|
|
71
|
-
log.info('onLookup', { label, ref });
|
|
72
|
-
const dxn = DXN.parse(ref);
|
|
73
|
-
if (!dxn) {
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const object = await resolveRef(client, dxn, space);
|
|
78
|
-
return { label, object };
|
|
79
|
-
},
|
|
80
|
-
}),
|
|
81
|
+
space && preview(),
|
|
81
82
|
transcript({
|
|
82
83
|
model,
|
|
83
84
|
started: object?.started ? new Date(object.started) : undefined,
|
|
@@ -7,6 +7,7 @@ import { yieldOrContinue } from 'main-thread-scheduling';
|
|
|
7
7
|
import React, { type FC, useCallback, useEffect, useMemo, useRef, useState, type WheelEvent } from 'react';
|
|
8
8
|
import { type OnResizeCallback, useResizeDetector } from 'react-resize-detector';
|
|
9
9
|
|
|
10
|
+
import { EchoObject, S } from '@dxos/echo-schema';
|
|
10
11
|
import { IconButton, type ThemedClassName, useTranslation } from '@dxos/react-ui';
|
|
11
12
|
import { useAttention } from '@dxos/react-ui-attention';
|
|
12
13
|
import {
|
|
@@ -20,7 +21,29 @@ import {
|
|
|
20
21
|
import { mx } from '@dxos/react-ui-theme';
|
|
21
22
|
|
|
22
23
|
import { TRANSCRIPTION_PLUGIN } from '../../../meta';
|
|
23
|
-
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Transcription fragment.
|
|
27
|
+
*/
|
|
28
|
+
const TranscriptSegment = S.Struct({
|
|
29
|
+
// TODO(burdon): TS from service is not Unix TS (x1000).
|
|
30
|
+
started: S.String,
|
|
31
|
+
text: S.String,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
type TranscriptSegment = S.Schema.Type<typeof TranscriptSegment>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Transcription block (from single speaker).
|
|
38
|
+
*/
|
|
39
|
+
const TranscriptBlock = S.Struct({
|
|
40
|
+
id: S.String,
|
|
41
|
+
authorName: S.optional(S.String), // TODO(burdon): Replace with identityDid.
|
|
42
|
+
authorHue: S.optional(S.String), // TOOD(burdon): Remove.
|
|
43
|
+
segments: S.Array(TranscriptSegment),
|
|
44
|
+
}).pipe(EchoObject({ typename: 'dxos.org/type/TranscriptBlock', version: '0.1.0' }));
|
|
45
|
+
|
|
46
|
+
type TranscriptBlock = S.Schema.Type<typeof TranscriptBlock>;
|
|
24
47
|
|
|
25
48
|
// TODO(burdon): Actions (e.g., mark, summarize, translate, label, delete).
|
|
26
49
|
|
|
@@ -9,15 +9,15 @@ import { intervalToDuration } from 'date-fns/intervalToDuration';
|
|
|
9
9
|
|
|
10
10
|
import { type CleanupFn, addEventListener, combine } from '@dxos/async';
|
|
11
11
|
import { type RenderCallback } from '@dxos/react-ui-editor';
|
|
12
|
+
import { type MessageType } from '@dxos/schema';
|
|
12
13
|
|
|
13
|
-
import { DocumentAdapter, type
|
|
14
|
-
import { type TranscriptBlock } from '../../types';
|
|
14
|
+
import { DocumentAdapter, type SerializationModel } from '../../model';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Data structure that maps
|
|
17
|
+
* Data structure that maps Chunks queue to lines with transcript state.
|
|
18
18
|
*/
|
|
19
19
|
export type TranscriptOptions = {
|
|
20
|
-
model:
|
|
20
|
+
model: SerializationModel<MessageType>;
|
|
21
21
|
started?: Date;
|
|
22
22
|
renderButton?: RenderCallback<{ onClick: () => void }>;
|
|
23
23
|
};
|
|
@@ -32,12 +32,13 @@ export const transcript = ({ model, started, renderButton }: TranscriptOptions):
|
|
|
32
32
|
class: 'cm-timestamp-gutter',
|
|
33
33
|
lineMarkerChange: (update) => update.docChanged || update.viewportChanged,
|
|
34
34
|
markers: (view) => {
|
|
35
|
-
const start = getStartTime(started, model.
|
|
35
|
+
const start = getStartTime(started, model.chunks[0]);
|
|
36
36
|
const builder = new RangeSetBuilder<GutterMarker>();
|
|
37
37
|
for (const { from, to } of view.visibleRanges) {
|
|
38
38
|
let line = view.state.doc.lineAt(from);
|
|
39
39
|
while (line.from <= to) {
|
|
40
|
-
const
|
|
40
|
+
const block = model.getChunkAtLine(line.number)?.blocks[0];
|
|
41
|
+
const timestamp = block?.type === 'transcription' && block.started;
|
|
41
42
|
if (timestamp) {
|
|
42
43
|
builder.add(line.from, line.from, new TimestampMarker(line.number, new Date(timestamp), start));
|
|
43
44
|
}
|
|
@@ -69,13 +70,15 @@ export const transcript = ({ model, started, renderButton }: TranscriptOptions):
|
|
|
69
70
|
let isAutoScrolling = false;
|
|
70
71
|
let hasScrolled = false;
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
let timeout: NodeJS.Timeout | undefined;
|
|
74
|
+
const scrollToBottom = (smooth = false) => {
|
|
75
|
+
scroller.style.scrollBehavior = smooth ? 'smooth' : '';
|
|
74
76
|
|
|
75
77
|
// Temporarily hide scrollbar to prevent flicker.
|
|
76
78
|
scroller.classList.add('cm-hide-scrollbar');
|
|
77
79
|
isAutoScrolling = true;
|
|
78
|
-
|
|
80
|
+
clearTimeout(timeout);
|
|
81
|
+
timeout = setTimeout(() => {
|
|
79
82
|
this._controls?.classList.add('opacity-0');
|
|
80
83
|
scroller.classList.remove('cm-hide-scrollbar');
|
|
81
84
|
isAutoScrolling = false;
|
|
@@ -96,7 +99,7 @@ export const transcript = ({ model, started, renderButton }: TranscriptOptions):
|
|
|
96
99
|
this._controls,
|
|
97
100
|
{
|
|
98
101
|
onClick: () => {
|
|
99
|
-
scrollToBottom();
|
|
102
|
+
scrollToBottom(false);
|
|
100
103
|
},
|
|
101
104
|
},
|
|
102
105
|
view,
|
|
@@ -122,7 +125,7 @@ export const transcript = ({ model, started, renderButton }: TranscriptOptions):
|
|
|
122
125
|
|
|
123
126
|
// Scroll.
|
|
124
127
|
if (autoScroll) {
|
|
125
|
-
scrollToBottom();
|
|
128
|
+
scrollToBottom(true);
|
|
126
129
|
}
|
|
127
130
|
}),
|
|
128
131
|
);
|
|
@@ -210,24 +213,24 @@ class TimestampMarker extends GutterMarker {
|
|
|
210
213
|
}
|
|
211
214
|
}
|
|
212
215
|
|
|
213
|
-
const getStartTime = (started?: Date,
|
|
216
|
+
const getStartTime = (started?: Date, message?: MessageType): Date | undefined => {
|
|
214
217
|
if (started) {
|
|
215
218
|
return started;
|
|
216
219
|
}
|
|
217
220
|
|
|
218
|
-
if (
|
|
219
|
-
return new Date(
|
|
221
|
+
if (message?.blocks[0]?.type === 'transcription' && message.blocks[0].started) {
|
|
222
|
+
return new Date(message.blocks[0].started);
|
|
220
223
|
}
|
|
221
224
|
|
|
222
225
|
return undefined;
|
|
223
226
|
};
|
|
224
227
|
|
|
225
228
|
const formatTimestamp = (timestamp: Date, relative?: Date) => {
|
|
226
|
-
if (
|
|
227
|
-
return format(timestamp, 'HH:mm:ss');
|
|
228
|
-
} else {
|
|
229
|
+
if (relative) {
|
|
229
230
|
const pad = (n = 0) => String(n).padStart(2, '0');
|
|
230
231
|
const { hours, minutes, seconds } = intervalToDuration({ start: relative, end: timestamp });
|
|
231
232
|
return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
|
|
233
|
+
} else {
|
|
234
|
+
return format(timestamp, 'HH:mm:ss');
|
|
232
235
|
}
|
|
233
236
|
};
|
|
@@ -5,18 +5,20 @@
|
|
|
5
5
|
import React, { type FC } from 'react';
|
|
6
6
|
|
|
7
7
|
import { fullyQualifiedId, getSpace } from '@dxos/client/echo';
|
|
8
|
-
import { useQueue } from '@dxos/react-client/echo';
|
|
8
|
+
import { useMembers, useQueue } from '@dxos/react-client/echo';
|
|
9
9
|
import { StackItem } from '@dxos/react-ui-stack';
|
|
10
|
+
import { type MessageType } from '@dxos/schema';
|
|
10
11
|
|
|
11
12
|
import { Transcript, renderMarkdown } from './Transcript';
|
|
12
13
|
import { useQueueModelAdapter } from '../hooks';
|
|
13
|
-
import { type
|
|
14
|
+
import { type TranscriptType } from '../types';
|
|
14
15
|
|
|
15
16
|
export const TranscriptionContainer: FC<{ role: string; transcript: TranscriptType }> = ({ role, transcript }) => {
|
|
16
17
|
const attendableId = fullyQualifiedId(transcript);
|
|
17
18
|
const space = getSpace(transcript);
|
|
18
|
-
const
|
|
19
|
-
const
|
|
19
|
+
const members = useMembers(space?.key).map((member) => member.identity);
|
|
20
|
+
const queue = useQueue<MessageType>(transcript.queue.dxn, { pollInterval: 1_000 });
|
|
21
|
+
const model = useQueueModelAdapter(renderMarkdown(members), queue);
|
|
20
22
|
|
|
21
23
|
return (
|
|
22
24
|
<StackItem.Content role={role} classNames='container-max-width pli-2'>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { Input, useTranslation } from '@dxos/react-ui';
|
|
8
|
+
import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
|
|
9
|
+
|
|
10
|
+
import { TRANSCRIPTION_PLUGIN } from '../../meta';
|
|
11
|
+
import { type TranscriptionSettingsProps } from '../../types';
|
|
12
|
+
|
|
13
|
+
export const TranscriptionSettings = ({ settings }: { settings: TranscriptionSettingsProps }) => {
|
|
14
|
+
const { t } = useTranslation(TRANSCRIPTION_PLUGIN);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<DeprecatedFormContainer>
|
|
18
|
+
<DeprecatedFormInput label={t('settings entity extraction label')}>
|
|
19
|
+
<Input.Switch
|
|
20
|
+
checked={!!settings.entityExtraction}
|
|
21
|
+
onCheckedChange={(checked) => (settings.entityExtraction = checked)}
|
|
22
|
+
/>
|
|
23
|
+
</DeprecatedFormInput>
|
|
24
|
+
</DeprecatedFormContainer>
|
|
25
|
+
);
|
|
26
|
+
};
|
package/src/components/index.ts
CHANGED