@dxos/plugin-transcription 0.8.0 → 0.8.1-main.a06ad20
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-SX6PNFEC.mjs → TranscriptContainer-N4KQHMY4.mjs} +2 -2
- package/dist/lib/browser/{chunk-AS364WZZ.mjs → chunk-BDVUIRBP.mjs} +2 -2
- package/dist/lib/browser/chunk-GHTRJTEB.mjs +35 -0
- package/dist/lib/browser/chunk-GHTRJTEB.mjs.map +7 -0
- package/dist/lib/browser/{chunk-R4HHS6FA.mjs → chunk-YX447BJ4.mjs} +16 -16
- package/dist/lib/browser/chunk-YX447BJ4.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +180 -72
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/{intent-resolver-EAR2TFK2.mjs → intent-resolver-RW6DEJC2.mjs} +2 -2
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-FOEWLLTZ.mjs → react-surface-UPTZBHVB.mjs} +3 -3
- package/dist/lib/node/{TranscriptContainer-HU763SN3.cjs → TranscriptContainer-4BWXOVML.cjs} +7 -7
- package/dist/lib/node/{TranscriptContainer-HU763SN3.cjs.map → TranscriptContainer-4BWXOVML.cjs.map} +2 -2
- package/dist/lib/node/{chunk-YV74Z74I.cjs → chunk-ANSWGFMS.cjs} +18 -18
- package/dist/lib/node/chunk-ANSWGFMS.cjs.map +7 -0
- package/dist/lib/node/{chunk-JBN3P6ZF.cjs → chunk-HDRXDMK2.cjs} +4 -46
- package/dist/lib/node/chunk-HDRXDMK2.cjs.map +7 -0
- package/dist/lib/node/{chunk-QWXLQPP5.cjs → chunk-I35KHI2G.cjs} +5 -5
- package/dist/lib/node/index.cjs +182 -74
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/{intent-resolver-3KJZGGUQ.cjs → intent-resolver-KLBZ25XJ.cjs} +7 -7
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-surface-AGGGDOUC.cjs → react-surface-NCKXB7EQ.cjs} +7 -7
- package/dist/lib/node-esm/{TranscriptContainer-DVBXQIQ4.mjs → TranscriptContainer-6IKRASR6.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-WEZGRUG6.mjs → chunk-2CPKXRN6.mjs} +2 -2
- package/dist/lib/node-esm/chunk-LORUIVS4.mjs +37 -0
- package/dist/lib/node-esm/chunk-LORUIVS4.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-36EQXBWR.mjs → chunk-ZMK2QLW2.mjs} +16 -16
- package/dist/lib/node-esm/chunk-ZMK2QLW2.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +180 -72
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/{intent-resolver-UGLYRD4X.mjs → intent-resolver-4FMISUPW.mjs} +2 -2
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-6AYPLJ2B.mjs → react-surface-2WJQ67LB.mjs} +3 -3
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/components/transcription.stories.d.ts +2 -1
- package/dist/types/src/components/transcription.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +0 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/transcriber/media-stream-recorder.d.ts +1 -0
- package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
- package/dist/types/src/transcription-manager.d.ts +36 -0
- package/dist/types/src/transcription-manager.d.ts.map +1 -0
- package/package.json +37 -37
- package/src/components/TranscriptContainer.tsx +11 -15
- package/src/hooks/index.ts +0 -1
- package/src/index.ts +1 -0
- package/src/transcriber/media-stream-recorder.ts +4 -0
- package/src/transcription-manager.ts +173 -0
- package/dist/lib/browser/chunk-R4HHS6FA.mjs.map +0 -7
- package/dist/lib/browser/chunk-ZMES3U2D.mjs +0 -78
- package/dist/lib/browser/chunk-ZMES3U2D.mjs.map +0 -7
- package/dist/lib/node/chunk-JBN3P6ZF.cjs.map +0 -7
- package/dist/lib/node/chunk-YV74Z74I.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-36EQXBWR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XYU6B73V.mjs +0 -80
- package/dist/lib/node-esm/chunk-XYU6B73V.mjs.map +0 -7
- package/dist/types/src/hooks/useIsSpeaking.d.ts +0 -2
- package/dist/types/src/hooks/useIsSpeaking.d.ts.map +0 -1
- package/src/hooks/useIsSpeaking.ts +0 -77
- /package/dist/lib/browser/{TranscriptContainer-SX6PNFEC.mjs.map → TranscriptContainer-N4KQHMY4.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-AS364WZZ.mjs.map → chunk-BDVUIRBP.mjs.map} +0 -0
- /package/dist/lib/browser/{intent-resolver-EAR2TFK2.mjs.map → intent-resolver-RW6DEJC2.mjs.map} +0 -0
- /package/dist/lib/browser/{react-surface-FOEWLLTZ.mjs.map → react-surface-UPTZBHVB.mjs.map} +0 -0
- /package/dist/lib/node/{chunk-QWXLQPP5.cjs.map → chunk-I35KHI2G.cjs.map} +0 -0
- /package/dist/lib/node/{intent-resolver-3KJZGGUQ.cjs.map → intent-resolver-KLBZ25XJ.cjs.map} +0 -0
- /package/dist/lib/node/{react-surface-AGGGDOUC.cjs.map → react-surface-NCKXB7EQ.cjs.map} +0 -0
- /package/dist/lib/node-esm/{TranscriptContainer-DVBXQIQ4.mjs.map → TranscriptContainer-6IKRASR6.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-WEZGRUG6.mjs.map → chunk-2CPKXRN6.mjs.map} +0 -0
- /package/dist/lib/node-esm/{intent-resolver-UGLYRD4X.mjs.map → intent-resolver-4FMISUPW.mjs.map} +0 -0
- /package/dist/lib/node-esm/{react-surface-6AYPLJ2B.mjs.map → react-surface-2WJQ67LB.mjs.map} +0 -0
|
@@ -26,13 +26,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
mod
|
|
27
27
|
));
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
var
|
|
30
|
-
__export(
|
|
29
|
+
var chunk_ANSWGFMS_exports = {};
|
|
30
|
+
__export(chunk_ANSWGFMS_exports, {
|
|
31
31
|
Transcript: () => Transcript,
|
|
32
32
|
TranscriptContainer_default: () => TranscriptContainer_default,
|
|
33
33
|
TranscriptionContainer: () => TranscriptionContainer
|
|
34
34
|
});
|
|
35
|
-
module.exports = __toCommonJS(
|
|
35
|
+
module.exports = __toCommonJS(chunk_ANSWGFMS_exports);
|
|
36
36
|
var import_chunk_UIHEGU6Q = require("./chunk-UIHEGU6Q.cjs");
|
|
37
37
|
var import_effect = require("effect");
|
|
38
38
|
var import_react = __toESM(require("react"));
|
|
@@ -107,7 +107,7 @@ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/experimental/pl
|
|
|
107
107
|
var TranscriptionContainer = ({ transcript }) => {
|
|
108
108
|
const { t } = (0, import_react_ui.useTranslation)(import_chunk_UIHEGU6Q.TRANSCRIPTION_PLUGIN);
|
|
109
109
|
const edge = (0, import_react_edge_client.useEdgeClient)();
|
|
110
|
-
const
|
|
110
|
+
const ai = useAiServiceClient();
|
|
111
111
|
const { dispatchPromise: dispatch } = (0, import_app_framework.useIntentDispatcher)();
|
|
112
112
|
const queue = (0, import_react_edge_client.useQueue)(edge, transcript.queue ? import_keys.DXN.parse(transcript.queue) : void 0, {
|
|
113
113
|
pollInterval: 1e3
|
|
@@ -116,7 +116,7 @@ var TranscriptionContainer = ({ transcript }) => {
|
|
|
116
116
|
const handleSummarize = (0, import_react.useCallback)(async () => {
|
|
117
117
|
setIsSummarizing(true);
|
|
118
118
|
try {
|
|
119
|
-
const document = await summarizeTranscript(edge,
|
|
119
|
+
const document = await summarizeTranscript(edge, ai, transcript);
|
|
120
120
|
const space = (0, import_echo.getSpace)(transcript);
|
|
121
121
|
const target = space?.properties[import_types2.CollectionType.typename]?.target;
|
|
122
122
|
await dispatch((0, import_effect.pipe)((0, import_app_framework.createIntent)(import_types2.SpaceAction.AddObject, {
|
|
@@ -150,17 +150,17 @@ var TranscriptionContainer = ({ transcript }) => {
|
|
|
150
150
|
})));
|
|
151
151
|
};
|
|
152
152
|
var TranscriptContainer_default = TranscriptionContainer;
|
|
153
|
-
var summarizeTranscript = async (
|
|
153
|
+
var summarizeTranscript = async (edge, ai, transcript) => {
|
|
154
154
|
(0, import_invariant.invariant)(transcript.queue, "No queue found for transcript", {
|
|
155
155
|
F: __dxlog_file,
|
|
156
|
-
L:
|
|
156
|
+
L: 86,
|
|
157
157
|
S: void 0,
|
|
158
158
|
A: [
|
|
159
159
|
"transcript.queue",
|
|
160
160
|
"'No queue found for transcript'"
|
|
161
161
|
]
|
|
162
162
|
});
|
|
163
|
-
const queue = new import_echo_db.QueueImpl(
|
|
163
|
+
const queue = new import_echo_db.QueueImpl(edge, import_keys.DXN.parse(transcript.queue));
|
|
164
164
|
await queue.refresh();
|
|
165
165
|
const content = queue.items.filter((block) => (0, import_echo_schema.isInstanceOf)(import_chunk_UIHEGU6Q.TranscriptBlock, block)).map((block) => `${block.author}: ${block.segments.map((segment) => segment.text).join("\n")}`).join("\n\n");
|
|
166
166
|
const parser = new import_assistant.MixedStreamParser();
|
|
@@ -168,11 +168,11 @@ var summarizeTranscript = async (edgeClient, aiService, transcript) => {
|
|
|
168
168
|
blockCount: queue.items.length
|
|
169
169
|
}, {
|
|
170
170
|
F: __dxlog_file,
|
|
171
|
-
L:
|
|
171
|
+
L: 97,
|
|
172
172
|
S: void 0,
|
|
173
173
|
C: (f, a) => f(...a)
|
|
174
174
|
});
|
|
175
|
-
const output = await parser.parse(await
|
|
175
|
+
const output = await parser.parse(await ai.exec({
|
|
176
176
|
model: import_assistant.DEFAULT_LLM_MODEL,
|
|
177
177
|
systemPrompt: SUMMARIZE_PROMPT,
|
|
178
178
|
history: [
|
|
@@ -191,13 +191,13 @@ var summarizeTranscript = async (edgeClient, aiService, transcript) => {
|
|
|
191
191
|
output
|
|
192
192
|
}, {
|
|
193
193
|
F: __dxlog_file,
|
|
194
|
-
L:
|
|
194
|
+
L: 106,
|
|
195
195
|
S: void 0,
|
|
196
196
|
C: (f, a) => f(...a)
|
|
197
197
|
});
|
|
198
198
|
(0, import_invariant.invariant)(output[0].content[0].type === "text", "Expected text content", {
|
|
199
199
|
F: __dxlog_file,
|
|
200
|
-
L:
|
|
200
|
+
L: 107,
|
|
201
201
|
S: void 0,
|
|
202
202
|
A: [
|
|
203
203
|
"output[0].content[0].type === 'text'",
|
|
@@ -237,10 +237,10 @@ var SUMMARIZE_PROMPT = `
|
|
|
237
237
|
# Tasks
|
|
238
238
|
At the end of the summary include tasks.
|
|
239
239
|
Extract only the tasks that are:
|
|
240
|
-
- Directly actionable
|
|
241
|
-
- Clearly assigned to a person or team (or can easily be inferred)
|
|
242
|
-
- Strongly implied by the conversation and/or user note (no speculative tasks)
|
|
243
|
-
- Specific enough that someone reading them would know exactly what to do next
|
|
240
|
+
- Directly actionable.
|
|
241
|
+
- Clearly assigned to a person or team (or can easily be inferred).
|
|
242
|
+
- Strongly implied by the conversation and/or user note (no speculative tasks).
|
|
243
|
+
- Specific enough that someone reading them would know exactly what to do next.
|
|
244
244
|
|
|
245
245
|
Format all tasks as markdown checkboxes using the syntax:
|
|
246
246
|
- [ ] Task description
|
|
@@ -252,7 +252,7 @@ var SUMMARIZE_PROMPT = `
|
|
|
252
252
|
var useAiServiceClient = () => {
|
|
253
253
|
const config = (0, import_react_client.useConfig)();
|
|
254
254
|
const endpoint = config.values.runtime?.services?.ai?.server ?? "http://localhost:8788";
|
|
255
|
-
return (0, import_react.useMemo)(() => new import_assistant.
|
|
255
|
+
return (0, import_react.useMemo)(() => new import_assistant.AIServiceEdgeClient({
|
|
256
256
|
endpoint
|
|
257
257
|
}), [
|
|
258
258
|
endpoint
|
|
@@ -264,4 +264,4 @@ var useAiServiceClient = () => {
|
|
|
264
264
|
TranscriptContainer_default,
|
|
265
265
|
TranscriptionContainer
|
|
266
266
|
});
|
|
267
|
-
//# sourceMappingURL=chunk-
|
|
267
|
+
//# sourceMappingURL=chunk-ANSWGFMS.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/components/TranscriptContainer.tsx", "../../../src/components/Transcript/Transcript.tsx"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { pipe } from 'effect';\nimport React, { useCallback, useMemo, useState, type FC } from 'react';\n\nimport { chain, createIntent, LayoutAction, useIntentDispatcher } from '@dxos/app-framework';\nimport { Message } from '@dxos/artifact';\nimport { AIServiceEdgeClient, DEFAULT_LLM_MODEL, MixedStreamParser, type AIServiceClient } from '@dxos/assistant';\nimport { create, getSpace, makeRef } from '@dxos/client/echo';\nimport { QueueImpl } from '@dxos/echo-db';\nimport { createStatic, isInstanceOf } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { DXN } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { DocumentType } from '@dxos/plugin-markdown/types';\nimport { CollectionType, SpaceAction } from '@dxos/plugin-space/types';\nimport { useConfig } from '@dxos/react-client';\nimport { useEdgeClient, useQueue, type EdgeHttpClient } from '@dxos/react-edge-client';\nimport { IconButton, Toolbar, useTranslation } from '@dxos/react-ui';\nimport { ScrollContainer } from '@dxos/react-ui-components';\nimport { StackItem } from '@dxos/react-ui-stack';\nimport { TextType } from '@dxos/schema';\n\nimport { Transcript } from './Transcript';\nimport { TRANSCRIPTION_PLUGIN } from '../meta';\nimport { TranscriptBlock, type TranscriptType } from '../types';\n\nexport const TranscriptionContainer: FC<{ transcript: TranscriptType }> = ({ transcript }) => {\n const { t } = useTranslation(TRANSCRIPTION_PLUGIN);\n const edge = useEdgeClient();\n const ai = useAiServiceClient();\n const { dispatchPromise: dispatch } = useIntentDispatcher();\n\n const queue = useQueue<TranscriptBlock>(edge, transcript.queue ? DXN.parse(transcript.queue) : undefined, {\n pollInterval: 1_000,\n });\n\n // TODO(dmaretskyi): Pending state and errors should be handled by the framework!!!\n const [isSummarizing, setIsSummarizing] = useState(false);\n const handleSummarize = useCallback(async () => {\n setIsSummarizing(true);\n try {\n const document = await summarizeTranscript(edge, ai, transcript);\n const space = getSpace(transcript);\n const target = space?.properties[CollectionType.typename]?.target;\n await dispatch(\n pipe(\n createIntent(SpaceAction.AddObject, { object: document, target }),\n chain(LayoutAction.Open, { part: 'main' }),\n ),\n );\n } finally {\n setIsSummarizing(false);\n }\n }, [transcript, edge]);\n\n // TODO(dmaretskyi): Move action to menu.\n return (\n <StackItem.Content toolbar={true}>\n <StackItem.Heading>\n <Toolbar.Root classNames='flex gap-2'>\n <IconButton\n icon='ph--subtitles--regular'\n iconOnly\n size={5}\n disabled={isSummarizing}\n onClick={handleSummarize}\n label={t('summary button')}\n />\n {isSummarizing && <div className='text-sm'>{t('summarizing label')}</div>}\n </Toolbar.Root>\n </StackItem.Heading>\n <ScrollContainer>\n <Transcript blocks={queue?.items} />\n </ScrollContainer>\n </StackItem.Content>\n );\n};\n\nexport default TranscriptionContainer;\n\n// TODO(dmaretskyi): Extract to the new file once transcript refactoring has settled.\nconst summarizeTranscript = async (edge: EdgeHttpClient, ai: AIServiceClient, transcript: TranscriptType) => {\n invariant(transcript.queue, 'No queue found for transcript');\n\n const queue = new QueueImpl(edge, DXN.parse(transcript.queue));\n await queue.refresh();\n const content = queue.items\n .filter((block) => isInstanceOf(TranscriptBlock, block))\n .map((block) => `${block.author}: ${block.segments.map((segment) => segment.text).join('\\n')}`)\n .join('\\n\\n');\n\n const parser = new MixedStreamParser();\n\n log.info('summarizing transcript', { blockCount: queue.items.length });\n const output = await parser.parse(\n await ai.exec({\n model: DEFAULT_LLM_MODEL,\n systemPrompt: SUMMARIZE_PROMPT,\n history: [createStatic(Message, { role: 'user', content: [{ type: 'text', text: content }] })],\n }),\n );\n\n log.info('transcript summary', { output });\n invariant(output[0].content[0].type === 'text', 'Expected text content');\n const summary = output[0].content[0].text;\n\n // TODO(dmaretskyi): .started is missing.\n const name = `Summary ${(transcript.started ?? new Date()).toLocaleString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n })}`;\n\n return create(DocumentType, {\n name,\n content: makeRef(create(TextType, { content: summary })),\n threads: [],\n });\n};\n\n// TODO(dmaretskyi): Add example to set consistent structure for the summary.\nconst SUMMARIZE_PROMPT = `\n # Goal\n Create a markdown summary of the transcript provided.\n\n # Formatting\n - Format the summary as a markdown document without extra comments like \"Here is the summary of the transcript:\".\n - Use markdown formatting for headings and bullet points.\n - Format the summary as a list of key points and takeaways.\n - All names of people should be in bold.\n\n # Note Taking\n - Correlate items in the summary with the person of origin to build a coherent narrative.\n - Include short quotes verbatim where appropriate. Especially when concerned with design decisions and problem descriptions.\n\n # Tasks\n At the end of the summary include tasks.\n Extract only the tasks that are:\n - Directly actionable.\n - Clearly assigned to a person or team (or can easily be inferred).\n - Strongly implied by the conversation and/or user note (no speculative tasks).\n - Specific enough that someone reading them would know exactly what to do next.\n\n Format all tasks as markdown checkboxes using the syntax:\n - [ ] Task description\n\n Additional information can be included (indented).\n\n If no actionable tasks are found, omit this tasks section.\n`;\n\n// TODO(dmaretskyi): Extract?\n// Also this conflicts with plugin automation providing the ai client via a capability. Need to reconcile.\nconst useAiServiceClient = (): AIServiceClient => {\n const config = useConfig();\n const endpoint = config.values.runtime?.services?.ai?.server ?? 'http://localhost:8788'; // TOOD(burdon): Standardize consts.\n return useMemo(() => new AIServiceEdgeClient({ endpoint }), [endpoint]);\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { formatDistanceToNow } from 'date-fns/formatDistanceToNow';\nimport React, { type FC } from 'react';\n\nimport { Icon, IconButton, useTranslation } from '@dxos/react-ui';\n\nimport { TRANSCRIPTION_PLUGIN } from '../../meta';\nimport { type TranscriptBlock } from '../../types';\n\n// TODO(burdon): react-ui-list.\n// TODO(burdon): Actions (e.g., mark, summarize, translate, label, delete).\n\nexport type TranscriptProps = {\n blocks?: TranscriptBlock[];\n};\n\nexport const Transcript: FC<TranscriptProps> = ({ blocks }) => {\n const { t } = useTranslation(TRANSCRIPTION_PLUGIN);\n const hoverButton = 'p-1 min-bs-1 transition-opacity duration-250 opacity-10 group-hover:opacity-100';\n\n return (\n <div role='list' className='flex flex-col grow gap-2 m-1'>\n {blocks?.map((block) => (\n <div\n role='listitem'\n key={block.id}\n className='flex flex-col py-1 border border-transparent hover:border-separator rounded'\n >\n <div className='group flex items-center px-2'>\n <Icon icon='ph--user--regular' />\n <div className='px-2 text-sm text-subdued'>{block.author}</div>\n <div className='grow' />\n <IconButton\n disabled\n icon='ph--x--regular'\n label={t('delete button')}\n iconOnly\n size={4}\n classNames={hoverButton}\n />\n </div>\n\n {block.segments.map((segment, i) => (\n <div key={i} className='group flex flex-col'>\n <div className='px-2'>{segment.text}</div>\n <div className='flex gap-1 items-center justify-between px-2'>\n <div className='grow' />\n <div className='truncate text-xs text-subdued'>\n {formatDistanceToNow(segment.started, { addSuffix: true })}\n </div>\n <IconButton\n disabled\n icon='ph--bookmark-simple--regular'\n label={t('bookmark button')}\n iconOnly\n size={4}\n classNames={hoverButton}\n />\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\n );\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_types", "import_react", "import_react_ui", "Transcript", "blocks", "t", "useTranslation", "TRANSCRIPTION_PLUGIN", "hoverButton", "React", "div", "role", "className", "map", "block", "key", "id", "Icon", "icon", "author", "IconButton", "disabled", "label", "iconOnly", "size", "classNames", "segments", "segment", "i", "text", "formatDistanceToNow", "started", "addSuffix", "TranscriptionContainer", "transcript", "edge", "useEdgeClient", "ai", "useAiServiceClient", "dispatchPromise", "dispatch", "useIntentDispatcher", "queue", "useQueue", "DXN", "parse", "undefined", "pollInterval", "isSummarizing", "setIsSummarizing", "useState", "handleSummarize", "useCallback", "document", "summarizeTranscript", "space", "getSpace", "target", "properties", "CollectionType", "typename", "pipe", "createIntent", "SpaceAction", "AddObject", "object", "chain", "LayoutAction", "Open", "part", "StackItem", "Content", "toolbar", "Heading", "Toolbar", "Root", "onClick", "ScrollContainer", "items", "invariant", "QueueImpl", "refresh", "content", "filter", "isInstanceOf", "TranscriptBlock", "join", "parser", "MixedStreamParser", "log", "info", "blockCount", "length", "output", "exec", "model", "DEFAULT_LLM_MODEL", "systemPrompt", "SUMMARIZE_PROMPT", "history", "createStatic", "Message", "type", "summary", "name", "Date", "toLocaleString", "year", "month", "day", "hour", "minute", "create", "DocumentType", "makeRef", "TextType", "threads", "config", "useConfig", "endpoint", "values", "runtime", "services", "server", "useMemo", "AIServiceEdgeClient"]
|
|
7
|
+
}
|
|
@@ -16,14 +16,13 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var
|
|
20
|
-
__export(
|
|
19
|
+
var chunk_HDRXDMK2_exports = {};
|
|
20
|
+
__export(chunk_HDRXDMK2_exports, {
|
|
21
21
|
getTimeStr: () => getTimeStr,
|
|
22
22
|
mergeFloat64Arrays: () => mergeFloat64Arrays,
|
|
23
|
-
monitorAudioLevel: () => monitorAudioLevel,
|
|
24
23
|
randomQueueDxn: () => randomQueueDxn
|
|
25
24
|
});
|
|
26
|
-
module.exports = __toCommonJS(
|
|
25
|
+
module.exports = __toCommonJS(chunk_HDRXDMK2_exports);
|
|
27
26
|
var import_echo_schema = require("@dxos/echo-schema");
|
|
28
27
|
var import_keys = require("@dxos/keys");
|
|
29
28
|
var getTimeStr = (timestamp) => new Date(timestamp ?? Date.now()).toLocaleTimeString("en-US", {
|
|
@@ -47,51 +46,10 @@ var mergeFloat64Arrays = (arrays) => {
|
|
|
47
46
|
}
|
|
48
47
|
return newArray;
|
|
49
48
|
};
|
|
50
|
-
var monitorAudioLevel = ({ mediaStreamTrack, onMeasure, intervalMs = 1e3 / 10 }) => {
|
|
51
|
-
let timeout = -1;
|
|
52
|
-
let interval = -1;
|
|
53
|
-
const audioContext = new AudioContext();
|
|
54
|
-
const stream = new MediaStream();
|
|
55
|
-
stream.addTrack(mediaStreamTrack);
|
|
56
|
-
const mediaStreamAudioSourceNode = audioContext.createMediaStreamSource(stream);
|
|
57
|
-
const analyserNode = audioContext.createAnalyser();
|
|
58
|
-
mediaStreamAudioSourceNode.connect(analyserNode);
|
|
59
|
-
analyserNode.fftSize = 32;
|
|
60
|
-
const pcmData = new Float32Array(analyserNode.fftSize);
|
|
61
|
-
let peak = 0;
|
|
62
|
-
interval = window.setInterval(() => {
|
|
63
|
-
onMeasure(peak);
|
|
64
|
-
peak = 0;
|
|
65
|
-
}, intervalMs);
|
|
66
|
-
const tick = () => {
|
|
67
|
-
timeout = window.setTimeout(() => {
|
|
68
|
-
analyserNode.getFloatTimeDomainData(pcmData);
|
|
69
|
-
let sumSquares = 0;
|
|
70
|
-
for (const amplitude of pcmData) {
|
|
71
|
-
sumSquares += amplitude * amplitude;
|
|
72
|
-
}
|
|
73
|
-
const current = Math.sqrt(sumSquares / pcmData.length);
|
|
74
|
-
if (current > peak) {
|
|
75
|
-
peak = current;
|
|
76
|
-
}
|
|
77
|
-
tick();
|
|
78
|
-
}, intervalMs);
|
|
79
|
-
};
|
|
80
|
-
tick();
|
|
81
|
-
return () => {
|
|
82
|
-
mediaStreamAudioSourceNode.disconnect();
|
|
83
|
-
analyserNode.disconnect();
|
|
84
|
-
void audioContext.close();
|
|
85
|
-
clearInterval(interval);
|
|
86
|
-
clearTimeout(timeout);
|
|
87
|
-
stream.removeTrack(mediaStreamTrack);
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
49
|
// Annotate the CommonJS export names for ESM import in node:
|
|
91
50
|
0 && (module.exports = {
|
|
92
51
|
getTimeStr,
|
|
93
52
|
mergeFloat64Arrays,
|
|
94
|
-
monitorAudioLevel,
|
|
95
53
|
randomQueueDxn
|
|
96
54
|
});
|
|
97
|
-
//# sourceMappingURL=chunk-
|
|
55
|
+
//# sourceMappingURL=chunk-HDRXDMK2.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/util/get-time-str.ts", "../../../src/util/random-queue-dxn.ts", "../../../src/util/array.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nexport const getTimeStr = (timestamp?: number) =>\n new Date(timestamp ?? Date.now()).toLocaleTimeString('en-US', {\n timeZone: 'UTC',\n hour12: true,\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n });\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { ObjectId } from '@dxos/echo-schema';\nimport { DXN, QueueSubspaceTags, SpaceId } from '@dxos/keys';\n\nexport const randomQueueDxn = () =>\n new DXN(DXN.kind.QUEUE, [QueueSubspaceTags.DATA, SpaceId.random(), ObjectId.random()]);\n", "//\n// Copyright 2025 DXOS.org\n//\n\nexport const mergeFloat64Arrays = (arrays: Float64Array[]) => {\n const newArray = new Float64Array(arrays.reduce((acc, array) => array.length + acc, 0));\n let offset = 0;\n for (const array of arrays) {\n newArray.set(array, offset);\n offset += array.length;\n }\n\n return newArray;\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;ACIA,yBAAyB;AACzB,kBAAgD;ADDzC,IAAMA,aAAa,CAACC,cACzB,IAAIC,KAAKD,aAAaC,KAAKC,IAAG,CAAA,EAAIC,mBAAmB,SAAS;EAC5DC,UAAU;EACVC,QAAQ;EACRC,MAAM;EACNC,QAAQ;EACRC,QAAQ;AACV,CAAA;ACJK,IAAMC,iBAAiB,MAC5B,IAAIC,gBAAIA,gBAAIC,KAAKC,OAAO;EAACC,8BAAkBC;EAAMC,oBAAQC,OAAM;EAAIC,4BAASD,OAAM;CAAG;ACJhF,IAAME,qBAAqB,CAACC,WAAAA;AACjC,QAAMC,WAAW,IAAIC,aAAaF,OAAOG,OAAO,CAACC,KAAKC,UAAUA,MAAMC,SAASF,KAAK,CAAA,CAAA;AACpF,MAAIG,SAAS;AACb,aAAWF,SAASL,QAAQ;AAC1BC,aAASO,IAAIH,OAAOE,MAAAA;AACpBA,cAAUF,MAAMC;EAClB;AAEA,SAAOL;AACT;",
|
|
6
|
+
"names": ["getTimeStr", "timestamp", "Date", "now", "toLocaleTimeString", "timeZone", "hour12", "hour", "minute", "second", "randomQueueDxn", "DXN", "kind", "QUEUE", "QueueSubspaceTags", "DATA", "SpaceId", "random", "ObjectId", "mergeFloat64Arrays", "arrays", "newArray", "Float64Array", "reduce", "acc", "array", "length", "offset", "set"]
|
|
7
|
+
}
|
|
@@ -26,15 +26,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
mod
|
|
27
27
|
));
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
var
|
|
30
|
-
__export(
|
|
29
|
+
var chunk_I35KHI2G_exports = {};
|
|
30
|
+
__export(chunk_I35KHI2G_exports, {
|
|
31
31
|
TranscriptContainer: () => TranscriptContainer
|
|
32
32
|
});
|
|
33
|
-
module.exports = __toCommonJS(
|
|
33
|
+
module.exports = __toCommonJS(chunk_I35KHI2G_exports);
|
|
34
34
|
var import_react = require("react");
|
|
35
|
-
var TranscriptContainer = (0, import_react.lazy)(() => import("./TranscriptContainer-
|
|
35
|
+
var TranscriptContainer = (0, import_react.lazy)(() => import("./TranscriptContainer-4BWXOVML.cjs"));
|
|
36
36
|
// Annotate the CommonJS export names for ESM import in node:
|
|
37
37
|
0 && (module.exports = {
|
|
38
38
|
TranscriptContainer
|
|
39
39
|
});
|
|
40
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-I35KHI2G.cjs.map
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -34,22 +34,22 @@ __export(node_exports, {
|
|
|
34
34
|
ReactSurface: () => ReactSurface,
|
|
35
35
|
TRANSCRIPTION_PLUGIN: () => import_chunk_UIHEGU6Q.TRANSCRIPTION_PLUGIN,
|
|
36
36
|
Transcriber: () => Transcriber,
|
|
37
|
-
Transcript: () =>
|
|
38
|
-
TranscriptContainer: () =>
|
|
37
|
+
Transcript: () => import_chunk_ANSWGFMS.Transcript,
|
|
38
|
+
TranscriptContainer: () => import_chunk_I35KHI2G.TranscriptContainer,
|
|
39
39
|
TranscriptionCapabilities: () => TranscriptionCapabilities,
|
|
40
|
-
TranscriptionContainer: () =>
|
|
40
|
+
TranscriptionContainer: () => import_chunk_ANSWGFMS.TranscriptionContainer,
|
|
41
|
+
TranscriptionManager: () => TranscriptionManager,
|
|
41
42
|
TranscriptionPlugin: () => TranscriptionPlugin,
|
|
42
43
|
meta: () => import_chunk_UIHEGU6Q.meta,
|
|
43
44
|
useAudioFile: () => useAudioFile,
|
|
44
45
|
useAudioTrack: () => useAudioTrack,
|
|
45
|
-
useIsSpeaking: () => useIsSpeaking,
|
|
46
46
|
useTranscriber: () => useTranscriber,
|
|
47
47
|
useVoiceInput: () => useVoiceInput
|
|
48
48
|
});
|
|
49
49
|
module.exports = __toCommonJS(node_exports);
|
|
50
|
-
var
|
|
51
|
-
var
|
|
52
|
-
var
|
|
50
|
+
var import_chunk_HDRXDMK2 = require("./chunk-HDRXDMK2.cjs");
|
|
51
|
+
var import_chunk_I35KHI2G = require("./chunk-I35KHI2G.cjs");
|
|
52
|
+
var import_chunk_ANSWGFMS = require("./chunk-ANSWGFMS.cjs");
|
|
53
53
|
var import_chunk_UIHEGU6Q = require("./chunk-UIHEGU6Q.cjs");
|
|
54
54
|
var import_app_framework = require("@dxos/app-framework");
|
|
55
55
|
var import_app_framework2 = require("@dxos/app-framework");
|
|
@@ -57,7 +57,6 @@ var import_react = require("react");
|
|
|
57
57
|
var import_log = require("@dxos/log");
|
|
58
58
|
var import_react2 = require("react");
|
|
59
59
|
var import_react3 = require("react");
|
|
60
|
-
var import_react4 = require("react");
|
|
61
60
|
var import_extendable_media_recorder = require("extendable-media-recorder");
|
|
62
61
|
var import_wavefile = require("wavefile");
|
|
63
62
|
var import_async = require("@dxos/async");
|
|
@@ -69,11 +68,17 @@ var import_async2 = require("@dxos/async");
|
|
|
69
68
|
var import_context = require("@dxos/context");
|
|
70
69
|
var import_log3 = require("@dxos/log");
|
|
71
70
|
var import_tracing2 = require("@dxos/tracing");
|
|
72
|
-
var
|
|
71
|
+
var import_react4 = require("react");
|
|
73
72
|
var import_async3 = require("@dxos/async");
|
|
74
73
|
var import_context2 = require("@dxos/context");
|
|
75
74
|
var import_log4 = require("@dxos/log");
|
|
76
75
|
var import_react_ui_sfx = require("@dxos/react-ui-sfx");
|
|
76
|
+
var import_async4 = require("@dxos/async");
|
|
77
|
+
var import_context3 = require("@dxos/context");
|
|
78
|
+
var import_echo_db = require("@dxos/echo-db");
|
|
79
|
+
var import_echo_schema = require("@dxos/echo-schema");
|
|
80
|
+
var import_invariant2 = require("@dxos/invariant");
|
|
81
|
+
var import_keys = require("@dxos/keys");
|
|
77
82
|
var import_app_framework3 = require("@dxos/app-framework");
|
|
78
83
|
var import_plugin_client = require("@dxos/plugin-client");
|
|
79
84
|
var TranscriptionCapabilities;
|
|
@@ -81,8 +86,8 @@ var TranscriptionCapabilities;
|
|
|
81
86
|
TranscriptionCapabilities2.Transcription = (0, import_app_framework2.defineCapability)(`${import_chunk_UIHEGU6Q.TRANSCRIPTION_PLUGIN}/capability/transcription`);
|
|
82
87
|
})(TranscriptionCapabilities || (TranscriptionCapabilities = {}));
|
|
83
88
|
var AppGraphBuilder = (0, import_app_framework.lazy)(() => import("./app-graph-builder-YFBX3OTP.cjs"));
|
|
84
|
-
var IntentResolver = (0, import_app_framework.lazy)(() => import("./intent-resolver-
|
|
85
|
-
var ReactSurface = (0, import_app_framework.lazy)(() => import("./react-surface-
|
|
89
|
+
var IntentResolver = (0, import_app_framework.lazy)(() => import("./intent-resolver-KLBZ25XJ.cjs"));
|
|
90
|
+
var ReactSurface = (0, import_app_framework.lazy)(() => import("./react-surface-NCKXB7EQ.cjs"));
|
|
86
91
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-transcription/src/hooks/useAudioFile.ts";
|
|
87
92
|
var useAudioFile = (audioUrl) => {
|
|
88
93
|
const [{ audio, stream, track }, setStream] = (0, import_react.useState)({});
|
|
@@ -166,59 +171,6 @@ var useAudioTrack = (active) => {
|
|
|
166
171
|
]);
|
|
167
172
|
return track;
|
|
168
173
|
};
|
|
169
|
-
var useIsSpeaking = (mediaStreamTrack) => {
|
|
170
|
-
const [isSpeaking, setIsSpeaking] = (0, import_react3.useState)(false);
|
|
171
|
-
const isSpeakingRef = (0, import_react3.useRef)(isSpeaking);
|
|
172
|
-
(0, import_react3.useEffect)(() => {
|
|
173
|
-
if (!mediaStreamTrack) {
|
|
174
|
-
setIsSpeaking(false);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
isSpeakingRef.current = isSpeaking;
|
|
178
|
-
const interval = window.setInterval(() => {
|
|
179
|
-
if (isSpeaking === isSpeakingRef.current) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
setIsSpeaking(isSpeakingRef.current);
|
|
183
|
-
}, 50);
|
|
184
|
-
return () => {
|
|
185
|
-
clearInterval(interval);
|
|
186
|
-
};
|
|
187
|
-
}, [
|
|
188
|
-
isSpeaking,
|
|
189
|
-
isSpeakingRef,
|
|
190
|
-
mediaStreamTrack
|
|
191
|
-
]);
|
|
192
|
-
(0, import_react3.useEffect)(() => {
|
|
193
|
-
if (!mediaStreamTrack) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
let timeout = -1;
|
|
197
|
-
const cleanup = (0, import_chunk_JBN3P6ZF.monitorAudioLevel)({
|
|
198
|
-
mediaStreamTrack,
|
|
199
|
-
onMeasure: (vol) => {
|
|
200
|
-
const audioLevelAboveThreshold = vol > (isSpeakingRef.current ? 0.02 : 0.05);
|
|
201
|
-
if (audioLevelAboveThreshold) {
|
|
202
|
-
clearTimeout(timeout);
|
|
203
|
-
timeout = -1;
|
|
204
|
-
isSpeakingRef.current = true;
|
|
205
|
-
} else if (timeout === -1) {
|
|
206
|
-
timeout = window.setTimeout(() => {
|
|
207
|
-
isSpeakingRef.current = false;
|
|
208
|
-
timeout = -1;
|
|
209
|
-
}, 1e3);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
return () => {
|
|
214
|
-
cleanup();
|
|
215
|
-
};
|
|
216
|
-
}, [
|
|
217
|
-
isSpeaking,
|
|
218
|
-
mediaStreamTrack
|
|
219
|
-
]);
|
|
220
|
-
return isSpeaking;
|
|
221
|
-
};
|
|
222
174
|
function _ts_decorate(decorators, target, key, desc) {
|
|
223
175
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
224
176
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -246,6 +198,9 @@ var MediaStreamRecorder = class {
|
|
|
246
198
|
bitDepthCode: settings.sampleSize ? String(settings.sampleSize) : "16"
|
|
247
199
|
};
|
|
248
200
|
}
|
|
201
|
+
get mediaStreamTrack() {
|
|
202
|
+
return this._mediaStreamTrack;
|
|
203
|
+
}
|
|
249
204
|
setOnChunk(onChunk) {
|
|
250
205
|
this._onChunk = onChunk;
|
|
251
206
|
}
|
|
@@ -254,7 +209,7 @@ var MediaStreamRecorder = class {
|
|
|
254
209
|
err
|
|
255
210
|
}, {
|
|
256
211
|
F: __dxlog_file2,
|
|
257
|
-
L:
|
|
212
|
+
L: 62,
|
|
258
213
|
S: this,
|
|
259
214
|
C: (f, a) => f(...a)
|
|
260
215
|
}));
|
|
@@ -271,7 +226,7 @@ var MediaStreamRecorder = class {
|
|
|
271
226
|
}
|
|
272
227
|
(0, import_invariant.invariant)(this._onChunk, "MediaStreamRecorder: onChunk is not set", {
|
|
273
228
|
F: __dxlog_file2,
|
|
274
|
-
L:
|
|
229
|
+
L: 73,
|
|
275
230
|
S: this,
|
|
276
231
|
A: [
|
|
277
232
|
"this._onChunk",
|
|
@@ -306,7 +261,7 @@ var MediaStreamRecorder = class {
|
|
|
306
261
|
} else {
|
|
307
262
|
import_log2.log.warn("MediaStreamRecorder: no header", void 0, {
|
|
308
263
|
F: __dxlog_file2,
|
|
309
|
-
L:
|
|
264
|
+
L: 104,
|
|
310
265
|
S: this,
|
|
311
266
|
C: (f, a) => f(...a)
|
|
312
267
|
});
|
|
@@ -415,7 +370,7 @@ var Transcriber = class extends import_context.Resource {
|
|
|
415
370
|
async _mergeAudioChunks(chunks) {
|
|
416
371
|
const file = new import_wavefile2.WaveFile();
|
|
417
372
|
const wavConfig = this._recorder.wavConfig;
|
|
418
|
-
file.fromScratch(wavConfig.channels, wavConfig.sampleRate, wavConfig.bitDepthCode, (0,
|
|
373
|
+
file.fromScratch(wavConfig.channels, wavConfig.sampleRate, wavConfig.bitDepthCode, (0, import_chunk_HDRXDMK2.mergeFloat64Arrays)(chunks.map(({ data }) => data)));
|
|
419
374
|
return file.toBase64();
|
|
420
375
|
}
|
|
421
376
|
async _fetchTranscription(audio) {
|
|
@@ -483,7 +438,7 @@ var RECORD_INTERVAL = 200;
|
|
|
483
438
|
var PREFIXED_CHUNKS_AMOUNT = 10;
|
|
484
439
|
var TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;
|
|
485
440
|
var useTranscriber = ({ audioStreamTrack, onSegments }) => {
|
|
486
|
-
const transcriber = (0,
|
|
441
|
+
const transcriber = (0, import_react3.useMemo)(() => {
|
|
487
442
|
if (!onSegments || !audioStreamTrack) {
|
|
488
443
|
return void 0;
|
|
489
444
|
}
|
|
@@ -502,7 +457,7 @@ var useTranscriber = ({ audioStreamTrack, onSegments }) => {
|
|
|
502
457
|
audioStreamTrack,
|
|
503
458
|
onSegments
|
|
504
459
|
]);
|
|
505
|
-
(0,
|
|
460
|
+
(0, import_react3.useEffect)(() => {
|
|
506
461
|
return () => {
|
|
507
462
|
void transcriber?.close();
|
|
508
463
|
};
|
|
@@ -515,17 +470,17 @@ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/p
|
|
|
515
470
|
var useVoiceInput = ({ active, onUpdate }) => {
|
|
516
471
|
const soundStart = (0, import_react_ui_sfx.useSoundEffect)("StartRecording");
|
|
517
472
|
const soundStop = (0, import_react_ui_sfx.useSoundEffect)("StopRecording");
|
|
518
|
-
const handleSegments = (0,
|
|
473
|
+
const handleSegments = (0, import_react4.useCallback)(async (segments) => {
|
|
519
474
|
const text = segments.map((str) => str.text.trim().replace(/[^\w\s]/g, "")).join(" ");
|
|
520
475
|
onUpdate(text);
|
|
521
476
|
}, []);
|
|
522
|
-
const [recording, setRecording] = (0,
|
|
477
|
+
const [recording, setRecording] = (0, import_react4.useState)(false);
|
|
523
478
|
const track = useAudioTrack(active);
|
|
524
479
|
const transcriber = useTranscriber({
|
|
525
480
|
audioStreamTrack: track,
|
|
526
481
|
onSegments: handleSegments
|
|
527
482
|
});
|
|
528
|
-
(0,
|
|
483
|
+
(0, import_react4.useEffect)(() => {
|
|
529
484
|
const ctx = new import_context2.Context(void 0, {
|
|
530
485
|
F: __dxlog_file4,
|
|
531
486
|
L: 43
|
|
@@ -566,6 +521,159 @@ var useVoiceInput = ({ active, onUpdate }) => {
|
|
|
566
521
|
recording
|
|
567
522
|
};
|
|
568
523
|
};
|
|
524
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
525
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
526
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
527
|
+
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;
|
|
528
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
529
|
+
}
|
|
530
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-transcription/src/transcription-manager.ts";
|
|
531
|
+
var RECORD_INTERVAL2 = 200;
|
|
532
|
+
var PREFIXED_CHUNKS_AMOUNT2 = 10;
|
|
533
|
+
var TRANSCRIBE_AFTER_CHUNKS_AMOUNT2 = 50;
|
|
534
|
+
var TranscriptionManager = class extends import_context3.Resource {
|
|
535
|
+
constructor(edgeClient) {
|
|
536
|
+
super();
|
|
537
|
+
this._audioStreamTrack = void 0;
|
|
538
|
+
this._name = void 0;
|
|
539
|
+
this._mediaRecorder = void 0;
|
|
540
|
+
this._transcriber = void 0;
|
|
541
|
+
this._enabled = false;
|
|
542
|
+
this._queue = void 0;
|
|
543
|
+
this._edgeClient = edgeClient;
|
|
544
|
+
}
|
|
545
|
+
async _open() {
|
|
546
|
+
await this._toggleTranscriber();
|
|
547
|
+
}
|
|
548
|
+
async _close() {
|
|
549
|
+
void this._transcriber?.close();
|
|
550
|
+
}
|
|
551
|
+
setRecording(recording) {
|
|
552
|
+
if (!this.isOpen || !this._enabled) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
if (recording) {
|
|
556
|
+
this._transcriber?.startChunksRecording();
|
|
557
|
+
} else {
|
|
558
|
+
this._transcriber?.stopChunksRecording();
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Enable or disable transcription.
|
|
563
|
+
* @param enabled - Whether to enable transcription.
|
|
564
|
+
*/
|
|
565
|
+
async setEnabled(enabled) {
|
|
566
|
+
if (this._enabled === enabled) {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
this._enabled = enabled ?? false;
|
|
570
|
+
this.isOpen && await this._toggleTranscriber();
|
|
571
|
+
}
|
|
572
|
+
async setAudioTrack(track) {
|
|
573
|
+
if (this._audioStreamTrack === track) {
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
this._audioStreamTrack = track;
|
|
577
|
+
this.isOpen && await this._toggleTranscriber();
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Set the queue to save the transcription to.
|
|
581
|
+
* @param queue - The queue to save the transcription to or the DXN of the queue.
|
|
582
|
+
*/
|
|
583
|
+
setQueue(queue) {
|
|
584
|
+
switch (typeof queue) {
|
|
585
|
+
case "string":
|
|
586
|
+
if (this._queue?.dxn.toString() === queue) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
this._queue = new import_echo_db.QueueImpl(this._edgeClient, import_keys.DXN.parse(queue));
|
|
590
|
+
break;
|
|
591
|
+
case "object":
|
|
592
|
+
if (this._queue === queue) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
(0, import_invariant2.invariant)(queue instanceof import_echo_db.QueueImpl, void 0, {
|
|
596
|
+
F: __dxlog_file5,
|
|
597
|
+
L: 110,
|
|
598
|
+
S: this,
|
|
599
|
+
A: [
|
|
600
|
+
"queue instanceof QueueImpl",
|
|
601
|
+
""
|
|
602
|
+
]
|
|
603
|
+
});
|
|
604
|
+
this._queue = queue;
|
|
605
|
+
break;
|
|
606
|
+
case "undefined":
|
|
607
|
+
this._queue = void 0;
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
setName(name) {
|
|
612
|
+
if (this._name === name) {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
this._name = name;
|
|
616
|
+
}
|
|
617
|
+
async _toggleTranscriber() {
|
|
618
|
+
await this._maybeReinitTranscriber();
|
|
619
|
+
if (this._enabled) {
|
|
620
|
+
await this._transcriber?.open();
|
|
621
|
+
} else {
|
|
622
|
+
await this._transcriber?.close();
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
async _maybeReinitTranscriber() {
|
|
626
|
+
if (!this._audioStreamTrack || !this._enabled) {
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
let needReinit = false;
|
|
630
|
+
if (this._audioStreamTrack !== this._mediaRecorder?.mediaStreamTrack) {
|
|
631
|
+
this._mediaRecorder = new MediaStreamRecorder({
|
|
632
|
+
mediaStreamTrack: this._audioStreamTrack,
|
|
633
|
+
interval: RECORD_INTERVAL2
|
|
634
|
+
});
|
|
635
|
+
needReinit = true;
|
|
636
|
+
}
|
|
637
|
+
if (needReinit) {
|
|
638
|
+
await this._transcriber?.close();
|
|
639
|
+
this._transcriber = new Transcriber({
|
|
640
|
+
config: {
|
|
641
|
+
transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT2,
|
|
642
|
+
prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT2
|
|
643
|
+
},
|
|
644
|
+
recorder: this._mediaRecorder,
|
|
645
|
+
onSegments: (segments) => this._onSegments(segments)
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
async _onSegments(segments) {
|
|
650
|
+
if (!this.isOpen || !this._queue) {
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
const block = (0, import_echo_schema.createStatic)(import_chunk_UIHEGU6Q.TranscriptBlock, {
|
|
654
|
+
author: this._name,
|
|
655
|
+
segments
|
|
656
|
+
});
|
|
657
|
+
this._queue.append([
|
|
658
|
+
block
|
|
659
|
+
]);
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
_ts_decorate3([
|
|
663
|
+
import_async4.synchronized
|
|
664
|
+
], TranscriptionManager.prototype, "setRecording", null);
|
|
665
|
+
_ts_decorate3([
|
|
666
|
+
import_async4.synchronized
|
|
667
|
+
], TranscriptionManager.prototype, "setEnabled", null);
|
|
668
|
+
_ts_decorate3([
|
|
669
|
+
import_async4.synchronized
|
|
670
|
+
], TranscriptionManager.prototype, "setAudioTrack", null);
|
|
671
|
+
_ts_decorate3([
|
|
672
|
+
import_async4.synchronized
|
|
673
|
+
], TranscriptionManager.prototype, "setQueue", null);
|
|
674
|
+
_ts_decorate3([
|
|
675
|
+
import_async4.synchronized
|
|
676
|
+
], TranscriptionManager.prototype, "setName", null);
|
|
569
677
|
var translations_default = [
|
|
570
678
|
{
|
|
571
679
|
"en-US": {
|
|
@@ -650,11 +758,11 @@ var TranscriptionPlugin = () => (0, import_app_framework3.definePlugin)(import_c
|
|
|
650
758
|
TranscriptContainer,
|
|
651
759
|
TranscriptionCapabilities,
|
|
652
760
|
TranscriptionContainer,
|
|
761
|
+
TranscriptionManager,
|
|
653
762
|
TranscriptionPlugin,
|
|
654
763
|
meta,
|
|
655
764
|
useAudioFile,
|
|
656
765
|
useAudioTrack,
|
|
657
|
-
useIsSpeaking,
|
|
658
766
|
useTranscriber,
|
|
659
767
|
useVoiceInput
|
|
660
768
|
});
|