@dxos/plugin-transcription 0.8.4-main.2e9d522 → 0.8.4-main.5ea62a8
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-OX7OOODC.mjs +11 -0
- package/dist/lib/browser/blueprint-definition-QQSGTX5F.mjs +142 -0
- package/dist/lib/browser/blueprint-definition-QQSGTX5F.mjs.map +7 -0
- package/dist/lib/browser/{chunk-4FJIYH7T.mjs → chunk-26XDG6GQ.mjs} +2 -2
- package/dist/lib/browser/{chunk-5WH45KBY.mjs → chunk-3X7HP44M.mjs} +8 -1
- package/dist/lib/browser/{chunk-5WH45KBY.mjs.map → chunk-3X7HP44M.mjs.map} +1 -1
- package/dist/lib/browser/{chunk-5KPYIC3N.mjs → chunk-5I4BMOGE.mjs} +422 -402
- package/dist/lib/browser/chunk-5I4BMOGE.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FFEPEPCU.mjs → chunk-BA64VLLR.mjs} +85 -94
- package/dist/lib/browser/chunk-BA64VLLR.mjs.map +7 -0
- package/dist/lib/browser/chunk-HXVGV7T6.mjs +63 -0
- package/dist/lib/browser/chunk-HXVGV7T6.mjs.map +7 -0
- package/dist/lib/browser/{chunk-U6QBOGTN.mjs → chunk-TNEQFHIU.mjs} +2 -2
- package/dist/lib/browser/{chunk-U6QBOGTN.mjs.map → chunk-TNEQFHIU.mjs.map} +1 -1
- package/dist/lib/browser/index.mjs +18 -12
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/intent-resolver-T3EGLS3L.mjs +25 -0
- package/dist/lib/browser/intent-resolver-T3EGLS3L.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-E5D5AE3F.mjs → react-surface-QYX74JNG.mjs} +8 -8
- package/dist/lib/browser/react-surface-QYX74JNG.mjs.map +7 -0
- package/dist/lib/browser/{transcriber-PXT4QBFY.mjs → transcriber-JOOAQVYV.mjs} +5 -5
- package/dist/lib/browser/transcriber-JOOAQVYV.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +6 -8
- package/dist/lib/node-esm/{TranscriptContainer-VBAOM5DG.mjs → TranscriptContainer-BUWK63SI.mjs} +4 -4
- package/dist/lib/node-esm/blueprint-definition-4PLCTH5Q.mjs +143 -0
- package/dist/lib/node-esm/blueprint-definition-4PLCTH5Q.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-RHF2ALML.mjs → chunk-3QAIZGMW.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-RHF2ALML.mjs.map → chunk-3QAIZGMW.mjs.map} +1 -1
- package/dist/lib/node-esm/{chunk-TJKAO7VR.mjs → chunk-DT3AOC3E.mjs} +422 -402
- package/dist/lib/node-esm/chunk-DT3AOC3E.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-HT3W7LDP.mjs → chunk-J5GQ3KGX.mjs} +85 -94
- package/dist/lib/node-esm/chunk-J5GQ3KGX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-Y2B4HWSS.mjs → chunk-NWD757KH.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-XMUCZBP3.mjs → chunk-QARUDLHN.mjs} +7 -1
- package/dist/lib/node-esm/{chunk-XMUCZBP3.mjs.map → chunk-QARUDLHN.mjs.map} +1 -1
- package/dist/lib/node-esm/chunk-W72HVQMD.mjs +64 -0
- package/dist/lib/node-esm/chunk-W72HVQMD.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +18 -12
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/intent-resolver-VDHCUAIO.mjs +26 -0
- package/dist/lib/node-esm/intent-resolver-VDHCUAIO.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-QRDJOHN5.mjs → react-surface-TM7XOQBR.mjs} +8 -8
- package/dist/lib/node-esm/react-surface-TM7XOQBR.mjs.map +7 -0
- package/dist/lib/node-esm/{transcriber-YUTEVANE.mjs → transcriber-QPS55YP2.mjs} +5 -5
- package/dist/lib/node-esm/transcriber-QPS55YP2.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +6 -8
- package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/blueprint-definition.d.ts +5 -0
- package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
- 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 +3 -2
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/transcriber.d.ts +1 -1
- package/dist/types/src/capabilities/transcriber.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/Transcript.d.ts +4 -4
- package/dist/types/src/components/Transcript/Transcript.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts +32 -15
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +2 -2
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +1 -1
- package/dist/types/src/components/TranscriptContainer.d.ts +2 -2
- package/dist/types/src/components/TranscriptContainer.d.ts.map +1 -1
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts +5 -2
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts +10 -5
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts +7 -4
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/TranscriptionStory.d.ts +1 -0
- 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 +7 -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/useVoiceInput.d.ts.map +1 -1
- package/dist/types/src/segments-normalization/normalization.d.ts +366 -321
- package/dist/types/src/segments-normalization/normalization.d.ts.map +1 -1
- package/dist/types/src/testing/testing.d.ts +1 -1
- package/dist/types/src/testing/testing.d.ts.map +1 -1
- package/dist/types/src/transcriber/media-stream-recorder.d.ts +1 -1
- package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcription-manager.d.ts +3 -7
- package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
- package/dist/types/src/types/Transcript.d.ts +30 -0
- package/dist/types/src/types/Transcript.d.ts.map +1 -0
- package/dist/types/src/types/TranscriptAction.d.ts +23 -0
- package/dist/types/src/types/TranscriptAction.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -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/tsconfig.tsbuildinfo +1 -1
- package/package.json +55 -53
- package/src/TranscriptionPlugin.tsx +10 -5
- package/src/capabilities/blueprint-definition.ts +31 -0
- package/src/capabilities/capabilities.ts +3 -3
- package/src/capabilities/index.ts +1 -0
- package/src/capabilities/intent-resolver.ts +5 -11
- package/src/capabilities/react-surface.tsx +2 -2
- package/src/capabilities/transcriber.ts +3 -2
- package/src/components/Transcript/Transcript.stories.tsx +12 -13
- package/src/components/Transcript/Transcript.tsx +8 -7
- package/src/components/Transcript/deprecated/OldTranscript.tsx +4 -4
- package/src/components/TranscriptContainer.tsx +5 -4
- package/src/components/stories/FileTranscription.stories.tsx +22 -12
- package/src/components/stories/KeyWordRecognition.stories.tsx +12 -6
- package/src/components/stories/MicrophoneTranscription.stories.tsx +10 -9
- package/src/components/stories/TranscriptionStory.tsx +9 -5
- package/src/functions/index.ts +6 -0
- package/src/functions/open.ts +37 -0
- package/src/functions/summarize.ts +97 -0
- package/src/hooks/useAudioFile.ts +1 -10
- package/src/hooks/useVoiceInput.ts +3 -2
- package/src/model/model.test.ts +1 -1
- package/src/segments-normalization/message-normalizer.ts +1 -1
- package/src/segments-normalization/normalization.test.ts +4 -4
- package/src/segments-normalization/normalization.ts +37 -36
- package/src/testing/testing.ts +3 -3
- package/src/transcriber/media-stream-recorder.ts +1 -1
- package/src/transcriber/transcriber.browser.test.ts +2 -1
- package/src/transcriber/transcriber.ts +2 -1
- package/src/transcriber/transcription-manager.ts +17 -38
- package/src/types/{schema.ts → Transcript.ts} +11 -8
- package/src/types/TranscriptAction.ts +24 -0
- package/src/types/index.ts +2 -1
- package/src/types/types.ts +0 -23
- package/dist/lib/browser/TranscriptContainer-6WCKCXQ6.mjs +0 -11
- package/dist/lib/browser/chunk-5KPYIC3N.mjs.map +0 -7
- package/dist/lib/browser/chunk-FFEPEPCU.mjs.map +0 -7
- package/dist/lib/browser/chunk-R7INNNUQ.mjs +0 -55
- package/dist/lib/browser/chunk-R7INNNUQ.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-3O33MMP5.mjs +0 -30
- package/dist/lib/browser/intent-resolver-3O33MMP5.mjs.map +0 -7
- package/dist/lib/browser/react-surface-E5D5AE3F.mjs.map +0 -7
- package/dist/lib/browser/transcriber-PXT4QBFY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HT3W7LDP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-TJKAO7VR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-U65ZWK3L.mjs +0 -56
- package/dist/lib/node-esm/chunk-U65ZWK3L.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-YMN5SXNC.mjs +0 -31
- package/dist/lib/node-esm/intent-resolver-YMN5SXNC.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-QRDJOHN5.mjs.map +0 -7
- package/dist/lib/node-esm/transcriber-YUTEVANE.mjs.map +0 -7
- package/dist/types/src/types/schema.d.ts +0 -41
- package/dist/types/src/types/schema.d.ts.map +0 -1
- /package/dist/lib/browser/{TranscriptContainer-6WCKCXQ6.mjs.map → TranscriptContainer-OX7OOODC.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-4FJIYH7T.mjs.map → chunk-26XDG6GQ.mjs.map} +0 -0
- /package/dist/lib/node-esm/{TranscriptContainer-VBAOM5DG.mjs.map → TranscriptContainer-BUWK63SI.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-Y2B4HWSS.mjs.map → chunk-NWD757KH.mjs.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/components/TranscriptContainer.tsx", "../../../src/hooks/useAudioFile.ts", "../../../src/hooks/useAudioTrack.ts", "../../../src/hooks/useQueueModelAdapter.ts", "../../../src/model/model.ts", "../../../src/hooks/useTranscriber.ts", "../../../src/capabilities/index.ts", "../../../src/hooks/useVoiceInput.ts", "../../../src/components/Transcript/Transcript.tsx", "../../../src/components/Transcript/transcript-extension.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React from 'react';\n\nimport { fullyQualifiedId, getSpace } from '@dxos/client/echo';\nimport { useMembers, useQueue } from '@dxos/react-client/echo';\nimport { StackItem } from '@dxos/react-ui-stack';\nimport { type DataType } from '@dxos/schema';\n\nimport { useQueueModelAdapter } from '../hooks';\nimport { type Transcript } from '../types';\n\nimport { TranscriptView, renderMarkdown } from './Transcript';\n\nexport type TranscriptionContainerProps = {\n role: string;\n transcript: Transcript.Transcript;\n};\n\nexport const TranscriptionContainer = ({ transcript }: TranscriptionContainerProps) => {\n const attendableId = fullyQualifiedId(transcript);\n const space = getSpace(transcript);\n const members = useMembers(space?.key).map((member) => member.identity);\n const queue = useQueue<DataType.Message>(transcript.queue.dxn, { pollInterval: 1_000 });\n const model = useQueueModelAdapter(renderMarkdown(members), queue);\n\n return (\n <StackItem.Content classNames='container-max-width pli-2'>\n <TranscriptView attendableId={attendableId} space={space} model={model} transcript={transcript} />\n </StackItem.Content>\n );\n};\n\nexport default TranscriptionContainer;\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport { scheduleTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { log } from '@dxos/log';\n\nexport type UseAudioState = {\n audio?: HTMLAudioElement;\n stream?: MediaStream;\n track?: MediaStreamTrack;\n};\n\nexport const useAudioFile = (audioUrl: string, constraints?: MediaTrackConstraints): UseAudioState => {\n const [{ audio, stream, track }, setStream] = useState<UseAudioState>({});\n useEffect(() => {\n const ctx = new Context();\n\n scheduleTask(ctx, async () => {\n const response = await fetch(audioUrl);\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n ctx.onDispose(() => {\n URL.revokeObjectURL(objectUrl);\n });\n\n const audio = new Audio();\n audio.src = objectUrl;\n\n await new Promise<void>((resolve, reject) => {\n audio.addEventListener(\n 'error',\n (err) => {\n log.error('error', { err });\n reject(err);\n },\n { once: true },\n );\n audio.addEventListener(\n 'canplay',\n async () => {\n resolve();\n },\n { once: true },\n );\n audio.load();\n });\n\n const audioCtx = new AudioContext();\n\n // Resume AudioContext if it's suspended.\n if (audioCtx.state === 'suspended') {\n await audioCtx.resume();\n }\n\n const destination = audioCtx.createMediaStreamDestination();\n destination.channelCount = 1;\n\n const source = audioCtx.createMediaElementSource(audio);\n source.connect(destination);\n const track = destination.stream.getAudioTracks()[0];\n if (constraints) {\n await track.applyConstraints(constraints).catch((err) => log.catch(err));\n }\n\n // Also connect to speakers so audio is audible.\n setStream({\n audio,\n stream: destination.stream,\n track: destination.stream.getAudioTracks()[0],\n });\n });\n\n return () => {\n void ctx.dispose();\n };\n }, [audioUrl]);\n\n return { audio, stream, track };\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\n/**\n *\n */\n// TODO(burdon): Reconcile with react-ui-sfx and plugin-calls.\nexport const useAudioTrack = (active?: boolean, constraints?: MediaTrackConstraints): MediaStreamTrack | undefined => {\n const [track, setTrack] = useState<MediaStreamTrack>();\n useEffect(() => {\n if (!active) {\n track?.stop();\n setTrack(undefined);\n return;\n }\n\n const initAudio = async () => {\n const audio = new Audio();\n audio.srcObject = await navigator.mediaDevices.getUserMedia({ audio: constraints ?? true });\n const [track] = audio.srcObject.getAudioTracks();\n if (track) {\n setTrack(track);\n }\n };\n\n if (active) {\n void initAudio();\n }\n }, [active]);\n\n return track;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useMemo, useState } from 'react';\n\nimport type { Obj } from '@dxos/echo';\nimport { type Queue } from '@dxos/react-client/echo';\n\nimport { type ChunkRenderer, SerializationModel } from '../model';\n\n/**\n * Model adapter for a queue.\n */\nexport const useQueueModelAdapter = <T extends Obj.Any>(\n renderer: ChunkRenderer<T>,\n queue: Queue<T> | undefined,\n initialChunks: T[] = [],\n): SerializationModel<T> => {\n const model = useMemo(() => new SerializationModel<T>(renderer, initialChunks), [queue]);\n const [loaded, setLoaded] = useState(false);\n\n // Set initial blocks.\n useEffect(() => {\n if (!queue) {\n return;\n }\n\n const update = () => {\n for (const block of queue?.objects ?? []) {\n model.appendChunk(block);\n }\n\n setLoaded(true);\n };\n\n // TODO(burdon): This is a hack to ensure the queue is loaded.\n let i: NodeJS.Timeout | undefined;\n if (queue.isLoading) {\n i = setInterval(() => {\n if (!queue?.isLoading) {\n clearInterval(i);\n update();\n }\n }, 1_000);\n } else {\n update();\n }\n\n return () => clearTimeout(i);\n }, [model, queue]);\n\n // TODO(burdon): Can we listen for queue events?\n useEffect(() => {\n if (!loaded || !queue || model.chunks.length === queue.objects.length) {\n return;\n }\n\n const chunk = queue.objects.at(-1);\n if (chunk) {\n model.appendChunk(chunk);\n }\n }, [model, loaded, queue?.objects.length]);\n\n return model;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { Text } from '@codemirror/state';\nimport { type EditorView } from '@codemirror/view';\n\nimport { Event } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nexport type Chunk = { id: string };\n\n/**\n * Covert block to a set of markdown lines.\n */\nexport type ChunkRenderer<T extends Chunk> = (chunk: T, index: number, debug?: boolean) => string[];\n\n/**\n * Abstract representation of the document model.\n */\nexport interface ChunkDocument {\n lineCount(): number;\n replaceLines(from: number, remove: number, insert: string[]): void;\n}\n\n/**\n * Codemirror document adapter.\n */\nexport class DocumentAdapter implements ChunkDocument {\n constructor(private readonly _view: EditorView) {}\n\n /** The document must always have at least one line. */\n lineCount(): number {\n return this._view.state.doc.lines - 1;\n }\n\n replaceLines(from: number, remove: number, insert: string[]): void {\n log('replaceLines', { count: this._view.state.doc.lines, from, remove, insert });\n\n const numLines = this._view.state.doc.lines;\n const posFrom = this._view.state.doc.line(from).from;\n const posTo = remove === 0 ? posFrom : this._view.state.doc.line(Math.min(numLines, from + remove)).from;\n\n // Don't remove the last line.\n let text = insert.join('\\n');\n if (posTo === this._view.state.doc.length) {\n text += '\\n';\n }\n\n this._view.dispatch({\n changes: { from: posFrom, to: posTo, insert: text },\n });\n }\n}\n\ntype ChunkChange<T extends Chunk> =\n | {\n type: 'append';\n index: number;\n chunk: T;\n }\n | {\n type: 'update';\n index: number;\n chunk: T;\n }\n | {\n type: 'delete';\n index: number;\n id: string;\n };\n\n/**\n * Each Chunk can be converted into a set of lines.\n * Chunks can be added, updated or deleted from the Queue.\n * A Document is an immutable projection that represents a flat list of lines corresponding to the Queue.\n *\n * Ideally we would implement a custom virtual Text model for the View, but this currently isn't possible in Codemirror.\n * Instead this model tracks changes and syncs them with the ChunkDocument.\n */\nexport class SerializationModel<T extends Chunk> {\n /** Ordered set of chunks. */\n private readonly _chunks: T[] = [];\n\n /** Map of chunk IDs to their current line counts. */\n private readonly _chunkLineCounts = new Map<string, number>();\n\n /** Map of line numbers to chunk IDs. */\n private readonly _lineToChunk = new Map<number, T>();\n\n /** Track chunk changes since last sync. */\n private readonly _changes: Array<ChunkChange<T>> = [];\n\n /** Emits when the document is updated. */\n public readonly update = new Event<void>();\n\n constructor(\n private readonly _renderer: ChunkRenderer<T>,\n initialChunks: T[] = [],\n ) {\n initialChunks.forEach((chunk) => {\n this.appendChunk(chunk);\n });\n }\n\n toJSON(): { chunks: number; changes: number } {\n return {\n chunks: this._chunks.length,\n changes: this._changes.length,\n };\n }\n\n get doc() {\n return Text.of([...this._chunks.flatMap((chunk, index) => this._renderer(chunk, index)), '']);\n }\n\n get chunks() {\n return this._chunks;\n }\n\n /**\n * Get the block ID at the given line number.\n */\n getChunkAtLine(line: number): T | undefined {\n return this._lineToChunk.get(line);\n }\n\n reset(): this {\n this._chunks.length = 0;\n this._chunkLineCounts.clear();\n this._lineToChunk.clear();\n this.update.emit();\n return this;\n }\n\n appendChunk(chunk: T): this {\n const index = this._chunks.length;\n this._chunks.push(chunk);\n this._changes.push({ type: 'append', index, chunk });\n this.update.emit();\n return this;\n }\n\n updateChunk(chunk: T): this {\n const index = this._chunks.findIndex((c) => c.id === chunk.id);\n invariant(index !== -1);\n this._chunks[index] = chunk;\n this._changes.push({ type: 'update', index, chunk });\n this.update.emit();\n return this;\n }\n\n deleteBlock(id: string): this {\n const index = this._chunks.findIndex((c) => c.id === id);\n invariant(index !== -1);\n this._chunks.splice(index, 1);\n this._changes.push({ type: 'delete', index, id });\n this.update.emit();\n return this;\n }\n\n /**\n * Syncs the tracked changes with the ChunkDocument.\n */\n sync(document: ChunkDocument): this {\n log('sync', { changes: this._changes });\n\n // Process each change in order.\n for (const change of this._changes) {\n switch (change.type) {\n case 'append': {\n // For appends, convert block to lines and add at the end.\n const lines = this._renderer(change.chunk, change.index);\n const lastLine = document.lineCount();\n document.replaceLines(lastLine + 1, 0, lines);\n break;\n }\n\n case 'update': {\n // For updates, find the block's line range and replace with new lines.\n let lineStart = 1;\n for (let i = 0; i < change.index; i++) {\n lineStart += this._chunkLineCounts.get(this._chunks[i].id)!;\n }\n const previousLineCount = this._chunkLineCounts.get(change.chunk.id)!;\n const newLines = this._renderer(change.chunk, change.index);\n document.replaceLines(lineStart, previousLineCount, newLines);\n break;\n }\n\n case 'delete': {\n // For deletes, find the block's line range and remove those lines.\n let lineStart = 1;\n for (let i = 0; i < change.index; i++) {\n lineStart += this._chunkLineCounts.get(this._chunks[i].id)!;\n }\n const previousLineCount = this._chunkLineCounts.get(change.id)!;\n document.replaceLines(lineStart, previousLineCount, []);\n break;\n }\n }\n }\n\n // Clear the line-to-block mapping.\n this._lineToChunk.clear();\n\n // Update all block line counts and line-to-block mapping after processing changes.\n let currentLine = 1;\n for (const [index, chunk] of this._chunks.entries()) {\n const lineCount = this._renderer(chunk, index).length;\n this._chunkLineCounts.set(chunk.id, lineCount);\n this._lineToChunk.set(currentLine, chunk);\n currentLine += lineCount;\n }\n\n // Clean up deleted blocks.\n const chunkIds = new Set(this._chunks.map((chunk) => chunk.id));\n for (const id of this._chunkLineCounts.keys()) {\n if (!chunkIds.has(id)) {\n this._chunkLineCounts.delete(id);\n }\n }\n\n // Clear changes after sync.\n this._changes.length = 0;\n return this;\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useMemo } from 'react';\n\nimport { useCapabilities } from '@dxos/app-framework';\n\nimport { TranscriptionCapabilities } from '../capabilities';\nimport { type Transcriber } from '../transcriber';\n\n/**\n * Records audio while user is speaking and transcribes it after user is done speaking.\n */\nexport const useTranscriber = ({\n audioStreamTrack,\n recorderConfig,\n transcriberConfig,\n onSegments,\n}: Partial<TranscriptionCapabilities.GetTranscriberProps>) => {\n const [getTranscriber] = useCapabilities(TranscriptionCapabilities.Transcriber);\n\n // Initialize audio transcription.\n const transcriber = useMemo<Transcriber | undefined>(() => {\n if (!getTranscriber || !audioStreamTrack || !onSegments) {\n return undefined;\n }\n\n return getTranscriber({ audioStreamTrack, recorderConfig, transcriberConfig, onSegments });\n }, [getTranscriber, audioStreamTrack, recorderConfig, transcriberConfig, onSegments]);\n\n useEffect(() => {\n return () => {\n void transcriber?.close();\n };\n }, [transcriber]);\n\n return transcriber;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { lazy } from '@dxos/app-framework';\n\nexport const BlueprintDefinition = lazy(() => import('./blueprint-definition'));\nexport const IntentResolver = lazy(() => import('./intent-resolver'));\nexport const ReactSurface = lazy(() => import('./react-surface'));\nexport const Transcriber = lazy(() => import('./transcriber'));\n\nexport * from './capabilities';\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useCallback, useEffect, useState } from 'react';\n\nimport { scheduleMicroTask } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { log } from '@dxos/log';\nimport { useSoundEffect } from '@dxos/react-ui-sfx';\n\nimport { type TranscriberParams } from '../transcriber';\n\nimport { useAudioTrack } from './useAudioTrack';\nimport { useTranscriber } from './useTranscriber';\n\nexport type UseVoiceInputProps = {\n active?: boolean;\n onUpdate: (text: string) => void;\n};\n\n/**\n * Hook for voice input.\n */\nexport const useVoiceInput = ({ active, onUpdate }: UseVoiceInputProps) => {\n const soundStart = useSoundEffect('StartRecording');\n const soundStop = useSoundEffect('StopRecording');\n\n const handleSegments = useCallback<TranscriberParams['onSegments']>(async (segments) => {\n const text = segments.map((str) => str.text.trim().replace(/[^\\w\\s]/g, '')).join(' ');\n onUpdate(text);\n }, []);\n\n // Audio/transcription.\n const [recording, setRecording] = useState(false);\n const track = useAudioTrack(active);\n const transcriber = useTranscriber({\n audioStreamTrack: track,\n onSegments: handleSegments,\n });\n\n // Start/stop transcription.\n useEffect(() => {\n const ctx = new Context();\n scheduleMicroTask(ctx, async () => {\n if (active && transcriber) {\n await transcriber.open();\n log.info('starting...');\n setRecording(true);\n void soundStart.play();\n transcriber.startChunksRecording();\n } else if (!active && transcriber?.isOpen) {\n transcriber?.stopChunksRecording();\n await transcriber?.close();\n log.info('stopped');\n setRecording(false);\n void soundStop.play();\n }\n });\n\n return () => {\n void ctx.dispose();\n };\n }, [active, transcriber]);\n\n return { recording };\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { type Space } from '@dxos/react-client/echo';\nimport { type Identity } from '@dxos/react-client/halo';\nimport { IconButton, type ThemedClassName, useThemeContext } from '@dxos/react-ui';\nimport {\n createBasicExtensions,\n createMarkdownExtensions,\n createRenderer,\n createThemeExtensions,\n decorateMarkdown,\n editorWidth,\n preview,\n useTextEditor,\n} from '@dxos/react-ui-editor';\nimport { mx } from '@dxos/react-ui-theme';\nimport { type DataType } from '@dxos/schema';\nimport { isNotFalsy } from '@dxos/util';\n\nimport { type SerializationModel } from '../../model';\nimport { type Transcript } from '../../types';\n\nimport { transcript } from './transcript-extension';\n\nexport const renderMarkdown =\n (identities: Identity[]) =>\n (message: DataType.Message, index: number, debug = false): string[] => {\n if (message.sender.role === 'assistant') {\n // Start/stop block.\n return [message.blocks.find((block) => block._tag === 'transcript')?.text ?? '', ''];\n }\n\n // TODO(burdon): Use link/reference markup for users (with popover).\n // TODO(burdon): Color and avatar.\n const identity = identities.find((identity) => identity.did === message.sender.identityDid);\n const name =\n identity?.profile?.displayName ??\n message.sender.contact?.target?.fullName ??\n message.sender.name ??\n message.sender.email ??\n message.sender.identityDid;\n const blocks = message.blocks.filter((block) => block._tag === 'transcript');\n return [\n `###### ${name}` + (debug ? ` [${index}]:${message.id}` : ''),\n blocks.map((block) => block.text.trim()).join(' '),\n '',\n ];\n };\n\nexport type TranscriptViewProps = ThemedClassName<{\n transcript?: Transcript.Transcript;\n space?: Space;\n model: SerializationModel<DataType.Message>;\n // TODO(wittjosiah): Move to container.\n attendableId?: string;\n ignoreAttention?: boolean;\n}>;\n\n/**\n * Transcript component implemented using the editor.\n */\nexport const TranscriptView = ({\n classNames,\n transcript: object,\n space,\n model,\n attendableId,\n ignoreAttention,\n}: TranscriptViewProps) => {\n const { themeMode } = useThemeContext();\n const { parentRef } = useTextEditor(() => {\n return {\n extensions: [\n createBasicExtensions({ readOnly: true, lineWrapping: true, search: true }),\n createMarkdownExtensions({ themeMode }),\n createThemeExtensions({ themeMode }),\n decorateMarkdown(),\n space && preview(),\n transcript({\n model,\n started: object?.started ? new Date(object.started) : undefined,\n renderButton: createRenderer(({ onClick }) => (\n <IconButton icon='ph--arrow-line-down--regular' iconOnly label='Scroll to bottom' onClick={onClick} />\n )),\n }),\n ].filter(isNotFalsy),\n };\n }, [space, model]);\n\n return (\n <div\n ref={parentRef}\n className={mx('flex grow overflow-hidden', editorWidth, classNames)}\n data-popover-collision-boundary={true}\n />\n );\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension, RangeSetBuilder } from '@codemirror/state';\nimport { EditorView, GutterMarker, ViewPlugin, type ViewUpdate, gutter } from '@codemirror/view';\nimport { format } from 'date-fns/format';\nimport { intervalToDuration } from 'date-fns/intervalToDuration';\n\nimport { type CleanupFn, addEventListener, combine } from '@dxos/async';\nimport { type RenderCallback } from '@dxos/react-ui-editor';\nimport { type DataType } from '@dxos/schema';\n\nimport { DocumentAdapter, type SerializationModel } from '../../model';\n\n/**\n * Data structure that maps Chunks queue to lines with transcript state.\n */\nexport type TranscriptOptions = {\n model: SerializationModel<DataType.Message>;\n started?: Date;\n renderButton?: RenderCallback<{ onClick: () => void }>;\n};\n\n/**\n * Scrolling transcript with timestamps.\n */\nexport const transcript = ({ model, started, renderButton }: TranscriptOptions): Extension => {\n return [\n // Show timestamps in the gutter.\n gutter({\n class: 'cm-timestamp-gutter',\n lineMarkerChange: (update) => update.docChanged || update.viewportChanged,\n markers: (view) => {\n const start = getStartTime(started, model.chunks[0]);\n const builder = new RangeSetBuilder<GutterMarker>();\n for (const { from, to } of view.visibleRanges) {\n let line = view.state.doc.lineAt(from);\n while (line.from <= to) {\n const block = model.getChunkAtLine(line.number)?.blocks[0];\n const timestamp = block?._tag === 'transcript' && block.started;\n if (timestamp) {\n builder.add(line.from, line.from, new TimestampMarker(line.number, new Date(timestamp), start));\n }\n\n if (line.to + 1 > view.state.doc.length) {\n break;\n }\n\n line = view.state.doc.lineAt(line.to + 1);\n }\n }\n\n return builder.finish();\n },\n }),\n\n // Listen for model updates.\n ViewPlugin.fromClass(\n class {\n private readonly _controls?: HTMLDivElement;\n private readonly _cleanup: CleanupFn;\n private readonly _adapter: DocumentAdapter;\n private _initialized = false;\n\n constructor(view: EditorView) {\n this._adapter = new DocumentAdapter(view);\n\n const scroller = view.scrollDOM;\n let isAutoScrolling = false;\n let hasScrolled = false;\n\n let timeout: NodeJS.Timeout | undefined;\n const scrollToBottom = (smooth = false) => {\n scroller.style.scrollBehavior = smooth ? 'smooth' : '';\n\n // Temporarily hide scrollbar to prevent flicker.\n scroller.classList.add('cm-hide-scrollbar');\n isAutoScrolling = true;\n clearTimeout(timeout);\n timeout = setTimeout(() => {\n this._controls?.classList.add('opacity-0');\n scroller.classList.remove('cm-hide-scrollbar');\n isAutoScrolling = false;\n }, 500);\n\n // Scroll to bottom.\n view.dispatch({\n effects: EditorView.scrollIntoView(view.state.doc.length, { y: 'end' }),\n });\n };\n\n // Scroll button.\n if (renderButton) {\n this._controls = document.createElement('div');\n this._controls.classList.add('cm-controls', 'transition-opacity', 'duration-300', 'opacity-0');\n view.dom.appendChild(this._controls);\n renderButton(\n this._controls,\n {\n onClick: () => {\n scrollToBottom(false);\n },\n },\n view,\n );\n }\n\n // Event listeners.\n this._cleanup = combine(\n addEventListener(view.scrollDOM, 'scroll', () => {\n if (!isAutoScrolling) {\n hasScrolled = true;\n this._controls?.classList.remove('opacity-0');\n }\n }),\n\n model.update.on(() => {\n // Check if clamped to bottom.\n const autoScroll =\n scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight === 0 || !hasScrolled;\n\n // Sync.\n model.sync(this._adapter);\n\n // Scroll.\n if (autoScroll) {\n scrollToBottom(true);\n }\n }),\n );\n }\n\n update(update: ViewUpdate) {\n // Initial sync.\n if (!this._initialized) {\n this._initialized = true;\n setTimeout(() => {\n model.sync(this._adapter);\n });\n }\n }\n\n destroy() {\n this._controls?.remove();\n this._cleanup();\n }\n },\n ),\n\n EditorView.theme({\n '.cm-scroller': {\n overflowY: 'scroll',\n },\n '.cm-hide-scrollbar': {\n scrollbarWidth: 'none',\n '-ms-overflow-style': 'none',\n },\n '.cm-hide-scrollbar::-webkit-scrollbar': {\n display: 'none',\n },\n '.cm-controls': {\n position: 'absolute',\n bottom: '0.5rem',\n right: '0.5rem',\n zIndex: 1000,\n },\n '.cm-line': {\n paddingRight: '1rem',\n },\n '.cm-timestamp-gutter': {\n width: '6rem',\n paddingRight: '1rem',\n },\n '.cm-timestamp-gutter > .cm-gutterElement > div': {\n display: 'inline-flex',\n textAlign: 'right',\n padding: '3px',\n },\n }),\n ];\n};\n\n/**\n * Gutter marker that displays a timestamp.\n */\nclass TimestampMarker extends GutterMarker {\n constructor(\n readonly _line: number,\n readonly _timestamp: Date,\n readonly _started?: Date,\n ) {\n super();\n }\n\n override eq(other: this): boolean {\n return other._timestamp === this._timestamp;\n }\n\n override toDOM(view: EditorView): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'text-sm text-subdued hover:bg-hoverSurface cursor-pointer';\n el.textContent = formatTimestamp(this._timestamp, this._started);\n // TODO(burdon): Click to bookmark or copy hyperlink.\n el.onclick = () => {\n const pos = view.state.doc.line(this._line).from;\n view.dispatch({\n effects: EditorView.scrollIntoView(pos, { y: 'start' }),\n });\n };\n\n return el;\n }\n}\n\nconst getStartTime = (started?: Date, message?: DataType.Message): Date | undefined => {\n if (started) {\n return started;\n }\n\n if (message?.blocks[0]?._tag === 'transcript' && message.blocks[0].started) {\n return new Date(message.blocks[0].started);\n }\n\n return undefined;\n};\n\nconst formatTimestamp = (timestamp: Date, relative?: Date) => {\n if (relative) {\n const pad = (n = 0) => String(n).padStart(2, '0');\n const { hours, minutes, seconds } = intervalToDuration({ start: relative, end: timestamp });\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;\n } else {\n return format(timestamp, 'HH:mm:ss');\n }\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["React", "fullyQualifiedId", "getSpace", "useMembers", "useQueue", "StackItem", "useEffect", "useState", "scheduleTask", "Context", "log", "useAudioFile", "audioUrl", "constraints", "audio", "stream", "track", "setStream", "ctx", "response", "fetch", "blob", "objectUrl", "URL", "createObjectURL", "onDispose", "revokeObjectURL", "Audio", "src", "Promise", "resolve", "reject", "addEventListener", "err", "error", "once", "load", "audioCtx", "AudioContext", "state", "resume", "destination", "createMediaStreamDestination", "channelCount", "source", "createMediaElementSource", "connect", "getAudioTracks", "applyConstraints", "catch", "dispose", "useEffect", "useState", "useAudioTrack", "active", "constraints", "track", "setTrack", "useState", "useEffect", "stop", "undefined", "initAudio", "audio", "Audio", "srcObject", "navigator", "mediaDevices", "getUserMedia", "getAudioTracks", "useEffect", "useMemo", "useState", "Text", "Event", "invariant", "log", "DocumentAdapter", "lineCount", "_view", "state", "doc", "lines", "replaceLines", "from", "remove", "insert", "count", "numLines", "posFrom", "line", "posTo", "Math", "min", "text", "join", "length", "dispatch", "changes", "to", "SerializationModel", "toJSON", "chunks", "_chunks", "_changes", "of", "flatMap", "chunk", "index", "_renderer", "getChunkAtLine", "_lineToChunk", "get", "reset", "_chunkLineCounts", "clear", "update", "emit", "appendChunk", "push", "type", "updateChunk", "findIndex", "c", "id", "deleteBlock", "splice", "sync", "document", "change", "lastLine", "lineStart", "i", "previousLineCount", "newLines", "currentLine", "entries", "set", "chunkIds", "Set", "map", "keys", "has", "delete", "initialChunks", "Map", "forEach", "useQueueModelAdapter", "renderer", "queue", "initialChunks", "model", "useMemo", "SerializationModel", "loaded", "setLoaded", "useState", "useEffect", "update", "block", "objects", "appendChunk", "i", "isLoading", "setInterval", "clearInterval", "clearTimeout", "chunks", "length", "chunk", "at", "useEffect", "useMemo", "useCapabilities", "lazy", "BlueprintDefinition", "lazy", "IntentResolver", "ReactSurface", "Transcriber", "useTranscriber", "audioStreamTrack", "recorderConfig", "transcriberConfig", "onSegments", "getTranscriber", "useCapabilities", "TranscriptionCapabilities", "Transcriber", "transcriber", "useMemo", "undefined", "useEffect", "close", "useCallback", "useEffect", "useState", "scheduleMicroTask", "Context", "log", "useSoundEffect", "useVoiceInput", "active", "onUpdate", "soundStart", "useSoundEffect", "soundStop", "handleSegments", "useCallback", "segments", "text", "map", "str", "trim", "replace", "join", "recording", "setRecording", "useState", "track", "useAudioTrack", "transcriber", "useTranscriber", "audioStreamTrack", "onSegments", "useEffect", "ctx", "Context", "scheduleMicroTask", "open", "log", "info", "play", "startChunksRecording", "isOpen", "stopChunksRecording", "close", "dispose", "React", "IconButton", "useThemeContext", "createBasicExtensions", "createMarkdownExtensions", "createRenderer", "createThemeExtensions", "decorateMarkdown", "editorWidth", "preview", "useTextEditor", "mx", "isNotFalsy", "RangeSetBuilder", "EditorView", "GutterMarker", "ViewPlugin", "gutter", "format", "intervalToDuration", "addEventListener", "combine", "transcript", "model", "started", "renderButton", "gutter", "class", "lineMarkerChange", "update", "docChanged", "viewportChanged", "markers", "view", "start", "getStartTime", "chunks", "builder", "RangeSetBuilder", "from", "to", "visibleRanges", "line", "state", "doc", "lineAt", "block", "getChunkAtLine", "number", "blocks", "timestamp", "_tag", "add", "TimestampMarker", "Date", "length", "finish", "ViewPlugin", "fromClass", "_initialized", "setTimeout", "sync", "_adapter", "destroy", "_controls", "remove", "_cleanup", "_define_property", "DocumentAdapter", "scroller", "scrollDOM", "isAutoScrolling", "hasScrolled", "timeout", "scrollToBottom", "smooth", "style", "scrollBehavior", "classList", "clearTimeout", "dispatch", "effects", "EditorView", "scrollIntoView", "y", "document", "createElement", "dom", "appendChild", "onClick", "combine", "addEventListener", "on", "autoScroll", "scrollHeight", "scrollTop", "clientHeight", "theme", "overflowY", "scrollbarWidth", "display", "position", "bottom", "right", "zIndex", "paddingRight", "width", "textAlign", "padding", "GutterMarker", "eq", "other", "_timestamp", "toDOM", "el", "className", "textContent", "formatTimestamp", "_started", "onclick", "pos", "_line", "message", "undefined", "relative", "pad", "n", "String", "padStart", "hours", "minutes", "seconds", "intervalToDuration", "end", "format", "renderMarkdown", "identities", "message", "index", "debug", "sender", "role", "blocks", "find", "block", "_tag", "text", "identity", "did", "identityDid", "name", "profile", "displayName", "contact", "target", "fullName", "email", "filter", "id", "map", "trim", "join", "TranscriptView", "classNames", "transcript", "object", "space", "model", "attendableId", "ignoreAttention", "themeMode", "useThemeContext", "parentRef", "useTextEditor", "extensions", "createBasicExtensions", "readOnly", "lineWrapping", "search", "createMarkdownExtensions", "createThemeExtensions", "decorateMarkdown", "preview", "started", "Date", "undefined", "renderButton", "createRenderer", "onClick", "IconButton", "icon", "iconOnly", "label", "isNotFalsy", "div", "ref", "className", "mx", "editorWidth", "data-popover-collision-boundary", "TranscriptionContainer", "transcript", "attendableId", "fullyQualifiedId", "space", "getSpace", "members", "useMembers", "key", "map", "member", "identity", "queue", "useQueue", "dxn", "pollInterval", "model", "useQueueModelAdapter", "renderMarkdown", "React", "StackItem", "Content", "classNames", "TranscriptView"]
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TRANSCRIPTION_URL
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HXVGV7T6.mjs";
|
|
4
4
|
|
|
5
5
|
// src/transcriber/media-stream-recorder.ts
|
|
6
6
|
import { MediaRecorder, register } from "extendable-media-recorder";
|
|
@@ -9,6 +9,19 @@ import { synchronized } from "@dxos/async";
|
|
|
9
9
|
import { invariant } from "@dxos/invariant";
|
|
10
10
|
import { log } from "@dxos/log";
|
|
11
11
|
import { trace } from "@dxos/tracing";
|
|
12
|
+
function _define_property(obj, key, value) {
|
|
13
|
+
if (key in obj) {
|
|
14
|
+
Object.defineProperty(obj, key, {
|
|
15
|
+
value,
|
|
16
|
+
enumerable: true,
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
obj[key] = value;
|
|
22
|
+
}
|
|
23
|
+
return obj;
|
|
24
|
+
}
|
|
12
25
|
function _ts_decorate(decorators, target, key, desc) {
|
|
13
26
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
14
27
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -22,12 +35,6 @@ var initializeExtendableMediaRecorder = async () => {
|
|
|
22
35
|
await register(await connect());
|
|
23
36
|
};
|
|
24
37
|
var MediaStreamRecorder = class {
|
|
25
|
-
constructor({ mediaStreamTrack, config }) {
|
|
26
|
-
this._mediaRecorder = void 0;
|
|
27
|
-
this._header = void 0;
|
|
28
|
-
this._mediaStreamTrack = mediaStreamTrack;
|
|
29
|
-
this._config = config;
|
|
30
|
-
}
|
|
31
38
|
get wavConfig() {
|
|
32
39
|
const settings = this._mediaStreamTrack.getSettings();
|
|
33
40
|
return {
|
|
@@ -43,7 +50,7 @@ var MediaStreamRecorder = class {
|
|
|
43
50
|
this._onChunk = onChunk;
|
|
44
51
|
}
|
|
45
52
|
async start() {
|
|
46
|
-
await (initializingPromise
|
|
53
|
+
await (initializingPromise ?? (initializingPromise = initializeExtendableMediaRecorder())).catch((err) => log.info("initializeExtendableMediaRecorder", {
|
|
47
54
|
err
|
|
48
55
|
}, {
|
|
49
56
|
F: __dxlog_file,
|
|
@@ -110,6 +117,15 @@ var MediaStreamRecorder = class {
|
|
|
110
117
|
data: wav.getSamples()
|
|
111
118
|
});
|
|
112
119
|
}
|
|
120
|
+
constructor({ mediaStreamTrack, config }) {
|
|
121
|
+
_define_property(this, "_mediaStreamTrack", void 0);
|
|
122
|
+
_define_property(this, "_config", void 0);
|
|
123
|
+
_define_property(this, "_mediaRecorder", void 0);
|
|
124
|
+
_define_property(this, "_header", void 0);
|
|
125
|
+
_define_property(this, "_onChunk", void 0);
|
|
126
|
+
this._mediaStreamTrack = mediaStreamTrack;
|
|
127
|
+
this._config = config;
|
|
128
|
+
}
|
|
113
129
|
};
|
|
114
130
|
_ts_decorate([
|
|
115
131
|
synchronized
|
|
@@ -137,6 +153,19 @@ var mergeFloat64Arrays = (arrays) => {
|
|
|
137
153
|
};
|
|
138
154
|
|
|
139
155
|
// src/transcriber/transcriber.ts
|
|
156
|
+
function _define_property2(obj, key, value) {
|
|
157
|
+
if (key in obj) {
|
|
158
|
+
Object.defineProperty(obj, key, {
|
|
159
|
+
value,
|
|
160
|
+
enumerable: true,
|
|
161
|
+
configurable: true,
|
|
162
|
+
writable: true
|
|
163
|
+
});
|
|
164
|
+
} else {
|
|
165
|
+
obj[key] = value;
|
|
166
|
+
}
|
|
167
|
+
return obj;
|
|
168
|
+
}
|
|
140
169
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
141
170
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
142
171
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -145,23 +174,10 @@ function _ts_decorate2(decorators, target, key, desc) {
|
|
|
145
174
|
}
|
|
146
175
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/transcriber/transcriber.ts";
|
|
147
176
|
var Transcriber = class extends Resource {
|
|
148
|
-
constructor({ config, recorder, onSegments }) {
|
|
149
|
-
super();
|
|
150
|
-
this._audioChunks = [];
|
|
151
|
-
this._lastUsedTimestamp = 0;
|
|
152
|
-
this._openTrigger = new Trigger({
|
|
153
|
-
autoReset: true
|
|
154
|
-
});
|
|
155
|
-
this._recording = false;
|
|
156
|
-
this._transcribeTask = void 0;
|
|
157
|
-
this._config = config;
|
|
158
|
-
this._recorder = recorder;
|
|
159
|
-
this._onSegments = onSegments;
|
|
160
|
-
}
|
|
161
177
|
async _open(ctx) {
|
|
162
178
|
log2.info("opening", void 0, {
|
|
163
179
|
F: __dxlog_file2,
|
|
164
|
-
L:
|
|
180
|
+
L: 102,
|
|
165
181
|
S: this,
|
|
166
182
|
C: (f, a) => f(...a)
|
|
167
183
|
});
|
|
@@ -173,7 +189,7 @@ var Transcriber = class extends Resource {
|
|
|
173
189
|
async _close() {
|
|
174
190
|
log2.info("closing", void 0, {
|
|
175
191
|
F: __dxlog_file2,
|
|
176
|
-
L:
|
|
192
|
+
L: 110,
|
|
177
193
|
S: this,
|
|
178
194
|
C: (f, a) => f(...a)
|
|
179
195
|
});
|
|
@@ -184,7 +200,7 @@ var Transcriber = class extends Resource {
|
|
|
184
200
|
startChunksRecording() {
|
|
185
201
|
log2.info("starting", void 0, {
|
|
186
202
|
F: __dxlog_file2,
|
|
187
|
-
L:
|
|
203
|
+
L: 117,
|
|
188
204
|
S: this,
|
|
189
205
|
C: (f, a) => f(...a)
|
|
190
206
|
});
|
|
@@ -201,7 +217,7 @@ var Transcriber = class extends Resource {
|
|
|
201
217
|
this._transcribeTask?.schedule();
|
|
202
218
|
log2.info("stopped", void 0, {
|
|
203
219
|
F: __dxlog_file2,
|
|
204
|
-
L:
|
|
220
|
+
L: 132,
|
|
205
221
|
S: this,
|
|
206
222
|
C: (f, a) => f(...a)
|
|
207
223
|
});
|
|
@@ -211,7 +227,7 @@ var Transcriber = class extends Resource {
|
|
|
211
227
|
chunk
|
|
212
228
|
}, {
|
|
213
229
|
F: __dxlog_file2,
|
|
214
|
-
L:
|
|
230
|
+
L: 136,
|
|
215
231
|
S: this,
|
|
216
232
|
C: (f, a) => f(...a)
|
|
217
233
|
});
|
|
@@ -227,7 +243,7 @@ var Transcriber = class extends Resource {
|
|
|
227
243
|
chunks: this._audioChunks.length
|
|
228
244
|
}, {
|
|
229
245
|
F: __dxlog_file2,
|
|
230
|
-
L:
|
|
246
|
+
L: 152,
|
|
231
247
|
S: this,
|
|
232
248
|
C: (f, a) => f(...a)
|
|
233
249
|
});
|
|
@@ -279,7 +295,7 @@ var Transcriber = class extends Resource {
|
|
|
279
295
|
string: segments.map((segments2) => segments2.text).join(" ")
|
|
280
296
|
}, {
|
|
281
297
|
F: __dxlog_file2,
|
|
282
|
-
L:
|
|
298
|
+
L: 216,
|
|
283
299
|
S: this,
|
|
284
300
|
C: (f, a) => f(...a)
|
|
285
301
|
});
|
|
@@ -306,6 +322,14 @@ var Transcriber = class extends Resource {
|
|
|
306
322
|
text: segment.text.trim()
|
|
307
323
|
}));
|
|
308
324
|
}
|
|
325
|
+
constructor({ config, recorder, onSegments }) {
|
|
326
|
+
super(), _define_property2(this, "_audioChunks", []), _define_property2(this, "_lastUsedTimestamp", 0), _define_property2(this, "_openTrigger", new Trigger({
|
|
327
|
+
autoReset: true
|
|
328
|
+
})), _define_property2(this, "_config", void 0), _define_property2(this, "_recorder", void 0), _define_property2(this, "_onSegments", void 0), _define_property2(this, "_recording", false), _define_property2(this, "_transcribeTask", void 0);
|
|
329
|
+
this._config = config;
|
|
330
|
+
this._recorder = recorder;
|
|
331
|
+
this._onSegments = onSegments;
|
|
332
|
+
}
|
|
309
333
|
};
|
|
310
334
|
_ts_decorate2([
|
|
311
335
|
trace2.span({
|
|
@@ -324,6 +348,19 @@ import { synchronized as synchronized2 } from "@dxos/async";
|
|
|
324
348
|
import { Resource as Resource2 } from "@dxos/context";
|
|
325
349
|
import { Obj } from "@dxos/echo";
|
|
326
350
|
import { DataType } from "@dxos/schema";
|
|
351
|
+
function _define_property3(obj, key, value) {
|
|
352
|
+
if (key in obj) {
|
|
353
|
+
Object.defineProperty(obj, key, {
|
|
354
|
+
value,
|
|
355
|
+
enumerable: true,
|
|
356
|
+
configurable: true,
|
|
357
|
+
writable: true
|
|
358
|
+
});
|
|
359
|
+
} else {
|
|
360
|
+
obj[key] = value;
|
|
361
|
+
}
|
|
362
|
+
return obj;
|
|
363
|
+
}
|
|
327
364
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
328
365
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
329
366
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -334,17 +371,6 @@ var RECORD_INTERVAL = 200;
|
|
|
334
371
|
var PREFIXED_CHUNKS_AMOUNT = 10;
|
|
335
372
|
var TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;
|
|
336
373
|
var TranscriptionManager = class extends Resource2 {
|
|
337
|
-
constructor(options) {
|
|
338
|
-
super();
|
|
339
|
-
this._audioStreamTrack = void 0;
|
|
340
|
-
this._identityDid = void 0;
|
|
341
|
-
this._mediaRecorder = void 0;
|
|
342
|
-
this._transcriber = void 0;
|
|
343
|
-
this._queue = void 0;
|
|
344
|
-
this._enabled = signal(false);
|
|
345
|
-
this._edgeClient = options.edgeClient;
|
|
346
|
-
this._messageEnricher = options.messageEnricher;
|
|
347
|
-
}
|
|
348
374
|
/** @reactive */
|
|
349
375
|
get enabled() {
|
|
350
376
|
return this._enabled.value;
|
|
@@ -370,73 +396,32 @@ var TranscriptionManager = class extends Resource2 {
|
|
|
370
396
|
}
|
|
371
397
|
return this;
|
|
372
398
|
}
|
|
373
|
-
/**
|
|
374
|
-
* Enable or disable transcription.
|
|
375
|
-
* @param enabled - Whether to enable transcription.
|
|
376
|
-
*/
|
|
377
399
|
async setEnabled(enabled) {
|
|
378
400
|
if (this._enabled.value === enabled) {
|
|
379
401
|
return;
|
|
380
402
|
}
|
|
381
403
|
this._enabled.value = enabled ?? false;
|
|
382
|
-
|
|
404
|
+
if (enabled) {
|
|
405
|
+
await this._maybeRestartTranscriber();
|
|
406
|
+
} else {
|
|
407
|
+
await this._stopTranscriber();
|
|
408
|
+
}
|
|
383
409
|
}
|
|
384
410
|
async setAudioTrack(track) {
|
|
385
411
|
if (this._audioStreamTrack === track) {
|
|
386
412
|
return;
|
|
387
413
|
}
|
|
388
414
|
this._audioStreamTrack = track;
|
|
389
|
-
|
|
415
|
+
await this._maybeRestartTranscriber();
|
|
390
416
|
}
|
|
391
417
|
async _open() {
|
|
392
|
-
await this.
|
|
418
|
+
await this._maybeRestartTranscriber();
|
|
393
419
|
}
|
|
394
420
|
async _close() {
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
-
// TODO(burdon): Change this to setEnables (explicit), not toggle.
|
|
398
|
-
async _toggleTranscriber() {
|
|
399
|
-
await this._maybeReinitTranscriber();
|
|
400
|
-
if (this._enabled.value) {
|
|
401
|
-
await this._transcriber?.open();
|
|
402
|
-
const block = Obj.make(DataType.Message, {
|
|
403
|
-
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
404
|
-
blocks: [
|
|
405
|
-
{
|
|
406
|
-
_tag: "transcript",
|
|
407
|
-
text: "Started",
|
|
408
|
-
started: (/* @__PURE__ */ new Date()).toISOString()
|
|
409
|
-
}
|
|
410
|
-
],
|
|
411
|
-
sender: {
|
|
412
|
-
role: "assistant"
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
await this._queue?.append([
|
|
416
|
-
block
|
|
417
|
-
]);
|
|
418
|
-
} else {
|
|
419
|
-
await this._transcriber?.close();
|
|
420
|
-
const block = Obj.make(DataType.Message, {
|
|
421
|
-
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
422
|
-
blocks: [
|
|
423
|
-
{
|
|
424
|
-
_tag: "transcript",
|
|
425
|
-
text: "Stopped",
|
|
426
|
-
started: (/* @__PURE__ */ new Date()).toISOString()
|
|
427
|
-
}
|
|
428
|
-
],
|
|
429
|
-
sender: {
|
|
430
|
-
role: "assistant"
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
await this._queue?.append([
|
|
434
|
-
block
|
|
435
|
-
]);
|
|
436
|
-
}
|
|
421
|
+
await this._stopTranscriber();
|
|
437
422
|
}
|
|
438
|
-
async
|
|
439
|
-
if (!this._audioStreamTrack || !this._enabled.value) {
|
|
423
|
+
async _maybeRestartTranscriber() {
|
|
424
|
+
if (!this._audioStreamTrack || !this._enabled.value || !this.isOpen) {
|
|
440
425
|
return;
|
|
441
426
|
}
|
|
442
427
|
let needReinit = false;
|
|
@@ -459,8 +444,12 @@ var TranscriptionManager = class extends Resource2 {
|
|
|
459
444
|
recorder: this._mediaRecorder,
|
|
460
445
|
onSegments: (segments) => this._onSegments(segments)
|
|
461
446
|
});
|
|
447
|
+
await this._transcriber?.open();
|
|
462
448
|
}
|
|
463
449
|
}
|
|
450
|
+
async _stopTranscriber() {
|
|
451
|
+
await this._transcriber?.close();
|
|
452
|
+
}
|
|
464
453
|
async _onSegments(segments) {
|
|
465
454
|
if (!this.isOpen || !this._queue) {
|
|
466
455
|
return;
|
|
@@ -479,10 +468,12 @@ var TranscriptionManager = class extends Resource2 {
|
|
|
479
468
|
block
|
|
480
469
|
]);
|
|
481
470
|
}
|
|
471
|
+
constructor(options) {
|
|
472
|
+
super(), _define_property3(this, "_edgeClient", void 0), _define_property3(this, "_messageEnricher", void 0), _define_property3(this, "_audioStreamTrack", void 0), _define_property3(this, "_identityDid", void 0), _define_property3(this, "_mediaRecorder", void 0), _define_property3(this, "_transcriber", void 0), _define_property3(this, "_queue", void 0), _define_property3(this, "_enabled", signal(false));
|
|
473
|
+
this._edgeClient = options.edgeClient;
|
|
474
|
+
this._messageEnricher = options.messageEnricher;
|
|
475
|
+
}
|
|
482
476
|
};
|
|
483
|
-
_ts_decorate3([
|
|
484
|
-
synchronized2
|
|
485
|
-
], TranscriptionManager.prototype, "setEnabled", null);
|
|
486
477
|
_ts_decorate3([
|
|
487
478
|
synchronized2
|
|
488
479
|
], TranscriptionManager.prototype, "setAudioTrack", null);
|
|
@@ -492,4 +483,4 @@ export {
|
|
|
492
483
|
Transcriber,
|
|
493
484
|
TranscriptionManager
|
|
494
485
|
};
|
|
495
|
-
//# sourceMappingURL=chunk-
|
|
486
|
+
//# sourceMappingURL=chunk-BA64VLLR.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/transcriber/media-stream-recorder.ts", "../../../src/transcriber/transcriber.ts", "../../../src/util/array.ts", "../../../src/transcriber/transcription-manager.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type IBlobEvent, type IMediaRecorder, MediaRecorder, register } from 'extendable-media-recorder';\nimport { WaveFile } from 'wavefile';\n\nimport { synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/tracing';\n\nimport { type AudioChunk, type AudioRecorder, type WavConfig } from './audio-recorder';\n\nlet initializingPromise: Promise<void> | undefined;\n\nconst initializeExtendableMediaRecorder = async () => {\n const { connect } = await import('extendable-media-recorder-wav-encoder');\n await register(await connect());\n};\n\nexport type MediaStreamRecorderParams = {\n mediaStreamTrack: MediaStreamTrack;\n config: {\n interval: number;\n };\n};\n\n/**\n * Recorder that uses the MediaContext API and AudioNode API to record audio.\n *\n * It records MediaStream using https://www.npmjs.com/package/extendable-media-recorder.\n */\n@trace.resource()\nexport class MediaStreamRecorder implements AudioRecorder {\n private readonly _mediaStreamTrack: MediaStreamTrack;\n /**\n * Default MediaRecorder implementation do not support wav encoding.\n */\n private readonly _config: MediaStreamRecorderParams['config'];\n private _mediaRecorder?: IMediaRecorder = undefined;\n private _header?: Uint8Array = undefined;\n private _onChunk?: (chunk: AudioChunk) => void;\n\n constructor({ mediaStreamTrack, config }: MediaStreamRecorderParams) {\n this._mediaStreamTrack = mediaStreamTrack;\n this._config = config;\n }\n\n get wavConfig(): WavConfig {\n const settings = this._mediaStreamTrack.getSettings();\n return {\n channels: settings.channelCount ?? 1,\n sampleRate: settings.sampleRate ?? 16000,\n bitDepthCode: settings.sampleSize ? String(settings.sampleSize) : '16',\n };\n }\n\n get mediaStreamTrack() {\n return this._mediaStreamTrack;\n }\n\n setOnChunk(onChunk: (chunk: AudioChunk) => void): void {\n this._onChunk = onChunk;\n }\n\n async start(): Promise<void> {\n await (initializingPromise ??= initializeExtendableMediaRecorder()).catch((err) =>\n log.info('initializeExtendableMediaRecorder', { err }),\n );\n\n if (!this._mediaRecorder) {\n const stream = new MediaStream([this._mediaStreamTrack]);\n this._mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/wav' });\n }\n\n if (this._mediaRecorder.state === 'recording') {\n return;\n }\n invariant(this._onChunk, 'MediaStreamRecorder: onChunk is not set');\n this._mediaRecorder.ondataavailable = (event) => this._ondataavailable(event);\n this._mediaRecorder.start(this._config.interval);\n }\n\n async stop(): Promise<void> {\n if (this._mediaRecorder?.state !== 'recording') {\n return;\n }\n this._mediaRecorder.stop();\n }\n\n @synchronized\n private async _ondataavailable(event: IBlobEvent): Promise<void> {\n const blob = event.data;\n const uint8Array = new Uint8Array(await blob.arrayBuffer());\n\n // First chunk from the MediaRecorder has a header.\n const isHeader =\n uint8Array[0] === 0x52 && // R\n uint8Array[1] === 0x49 && // I\n uint8Array[2] === 0x46 && // F\n uint8Array[3] === 0x46; // F\n let wav: WaveFile;\n\n if (isHeader) {\n wav = new WaveFile(uint8Array);\n this._header = uint8Array.slice(0, 44);\n } else if (this._header) {\n wav = new WaveFile(new Uint8Array([...this._header, ...uint8Array]));\n } else {\n log.warn('MediaStreamRecorder: no header');\n return;\n }\n\n this._onChunk!({\n timestamp: Date.now(),\n data: wav.getSamples(),\n });\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { WaveFile } from 'wavefile';\n\nimport { DeferredTask, Trigger } from '@dxos/async';\nimport { type Context, LifecycleState, Resource } from '@dxos/context';\nimport { log } from '@dxos/log';\nimport { type DataType } from '@dxos/schema';\nimport { trace } from '@dxos/tracing';\n\nimport { TRANSCRIPTION_URL } from '../types';\nimport { mergeFloat64Arrays } from '../util';\n\nimport { type AudioChunk, type AudioRecorder } from './audio-recorder';\n\ntype WhisperWord = {\n word: string;\n\n /**\n * Time in seconds from the start of the audio.\n */\n start: number;\n\n /**\n * Time in seconds from the start of the audio.\n */\n end: number;\n};\n\ntype WhisperSegment = {\n text: string;\n\n /**\n * Time in seconds from the start of the audio.\n */\n start: number;\n\n /**\n * Time in seconds from the start of the audio.\n */\n end: number;\n\n /**\n * Probability of no speech in the segment.\n */\n no_speech_prob: number;\n\n words: WhisperWord[];\n};\n\nexport type TranscribeConfig = {\n /**\n * Number of chunks to transcribe automatically after.\n */\n transcribeAfterChunksAmount: number;\n\n /**\n * Number of chunks to save before the user starts speaking.\n * This is needed to catch the beginning of the user's speech.\n */\n prefixBufferChunksAmount: number;\n};\n\nexport type TranscriberParams = {\n config: TranscribeConfig;\n recorder: AudioRecorder;\n /**\n * Callback to handle the transcribed segments, after all segment transformers are applied.\n * @param segments - The transcribed segments.\n */\n onSegments: (segments: DataType.MessageBlock.Transcript[]) => Promise<void>;\n};\n\n/**\n * Handles transcription of audio chunks.\n * If user is not speaking, the last `minChunksAmount` chunks are saved and transcribed.\n * If user is speaking, the chunks are added to the buffer until the user is done talking.\n */\nexport class Transcriber extends Resource {\n private _audioChunks: AudioChunk[] = [];\n private _lastUsedTimestamp = 0;\n\n private readonly _openTrigger = new Trigger({ autoReset: true });\n\n private readonly _config: TranscribeConfig;\n private readonly _recorder: AudioRecorder;\n private readonly _onSegments: TranscriberParams['onSegments'];\n\n private _recording = false;\n private _transcribeTask?: DeferredTask = undefined;\n\n constructor({ config, recorder, onSegments }: TranscriberParams) {\n super();\n this._config = config;\n this._recorder = recorder;\n this._onSegments = onSegments;\n }\n\n protected override async _open(ctx: Context): Promise<void> {\n log.info('opening');\n this._recorder.setOnChunk((chunk) => this._saveAudioChunk(chunk));\n await this._recorder.start();\n this._transcribeTask = new DeferredTask(ctx, async () => this._transcribe());\n this._openTrigger.wake();\n }\n\n protected override async _close(): Promise<void> {\n log.info('closing');\n this._recording = false;\n this._transcribeTask = undefined;\n await this._recorder.stop();\n }\n\n startChunksRecording(): void {\n log.info('starting');\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n\n this._recording = true;\n }\n\n stopChunksRecording(): void {\n if (this._lifecycleState !== LifecycleState.OPEN || !this._recording) {\n return;\n }\n\n this._recording = false;\n this._transcribeTask?.schedule();\n log.info('stopped');\n }\n\n private _saveAudioChunk(chunk: AudioChunk): void {\n log('saving audio chunk', { chunk });\n this._audioChunks.push(chunk);\n\n // Clean the buffer if the user is not speaking and the transcription task is not scheduled.\n if (\n !this._recording &&\n (!this._transcribeTask || !this._transcribeTask.scheduled) &&\n this._audioChunks.length >= this._config.prefixBufferChunksAmount\n ) {\n this._audioChunks = this._dropOldChunks();\n } else if (this._audioChunks.length >= this._config.transcribeAfterChunksAmount && this._recording) {\n this._transcribeTask?.schedule();\n }\n }\n\n private async _transcribe(): Promise<void> {\n log('transcribing', { chunks: this._audioChunks.length });\n const chunks = this._audioChunks;\n this._audioChunks = this._dropOldChunks();\n if (chunks.length === 0) {\n return;\n }\n\n const audio = await this._mergeAudioChunks(chunks);\n const segments = await this._fetchTranscription(audio);\n if (!Array.isArray(segments) || segments.length === 0) {\n return;\n }\n\n const alignedSegments = this._alignSegments(segments, chunks);\n if (alignedSegments.length > 0) {\n await this._onSegments(alignedSegments);\n }\n }\n\n private _dropOldChunks(): AudioChunk[] {\n return this._config.prefixBufferChunksAmount > 0\n ? this._audioChunks.slice(-this._config.prefixBufferChunksAmount)\n : [];\n }\n\n @trace.span({ showInBrowserTimeline: true })\n private async _mergeAudioChunks(chunks: AudioChunk[]): Promise<string> {\n const file = new WaveFile();\n const wavConfig = this._recorder.wavConfig;\n\n file.fromScratch(\n wavConfig.channels,\n wavConfig.sampleRate,\n wavConfig.bitDepthCode,\n mergeFloat64Arrays(chunks.map(({ data }) => data)),\n );\n\n return file.toBase64();\n }\n\n @trace.span({ showInBrowserTimeline: true })\n private async _fetchTranscription(audio: string): Promise<WhisperSegment[]> {\n if (audio.length === 0) {\n this._audioChunks = [];\n throw new Error('No audio to send for transcribing');\n }\n\n const response = await fetch(`${TRANSCRIPTION_URL}/transcribe`, {\n method: 'POST',\n body: JSON.stringify({ audio }),\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n this._audioChunks = [];\n throw new Error(`Transcription failed: ${response.statusText}`);\n }\n\n const { segments } = (await response.json()) as {\n segments: WhisperSegment[];\n };\n\n log.info('transcription response', {\n segments: segments.length,\n string: segments.map((segments) => segments.text).join(' '),\n });\n\n return segments;\n }\n\n private _alignSegments(segments: WhisperSegment[], originalChunks: AudioChunk[]): DataType.MessageBlock.Transcript[] {\n // Absolute zero for all relative timestamps in the segments.\n const zeroTimestamp = originalChunks.at(0)!.timestamp;\n\n const filteredSegments = segments\n // Use segments that end after the last used timestamp.\n // Segments could overlap, so we need to filter words that starts after the last used timestamp.\n .filter((segment) => zeroTimestamp + segment.end * 1_000 >= this._lastUsedTimestamp)\n // Use words that starts after the last used timestamp.\n .map((segment) => {\n const words = segment.words.filter((word) => zeroTimestamp + word.start * 1_000 >= this._lastUsedTimestamp);\n return {\n ...segment,\n words,\n text: words.map((word) => word.word).join(''),\n start: words.at(0)?.start ?? segment.end,\n };\n })\n .filter((segment) => segment.words.length > 0);\n\n if (filteredSegments.length === 0) {\n return [];\n }\n\n // Update last timestamp.\n this._lastUsedTimestamp = zeroTimestamp + filteredSegments.at(-1)!.end * 1_000;\n\n // Add absolute timestamp to each segment.\n return filteredSegments.map((segment) => ({\n _tag: 'transcript',\n started: new Date(zeroTimestamp + segment.start * 1_000).toISOString(),\n text: segment.text.trim(),\n }));\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nexport const mergeFloat64Arrays = (arrays: Float64Array[]) => {\n const newArray = new Float64Array(arrays.reduce((acc, array) => array.length + acc, 0));\n let offset = 0;\n for (const array of arrays) {\n newArray.set(array, offset);\n offset += array.length;\n }\n\n return newArray;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { signal } from '@preact/signals-core';\n\nimport { synchronized } from '@dxos/async';\nimport { Resource } from '@dxos/context';\nimport { Obj } from '@dxos/echo';\nimport { type Queue } from '@dxos/echo-db';\nimport { type EdgeHttpClient } from '@dxos/react-edge-client';\nimport { DataType } from '@dxos/schema';\n\nimport { MediaStreamRecorder } from './media-stream-recorder';\nimport { Transcriber } from './transcriber';\n\n/**\n * Length of the chunk in ms.\n */\nconst RECORD_INTERVAL = 200;\n\n/**\n * Number of chunks to save before the user starts speaking.\n */\nconst PREFIXED_CHUNKS_AMOUNT = 10;\n\n/**\n * Number of chunks to transcribe automatically after.\n * Combined should be mess than 25MB or whisper would fail.\n */\nconst TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;\n\nexport type TranscriptMessageEnricher = (message: DataType.Message) => Promise<DataType.Message>;\n\nexport type TranscriptionManagerOptions = {\n edgeClient: EdgeHttpClient;\n\n /**\n * Enrich the message before it is written to the transcription queue.\n */\n messageEnricher?: TranscriptMessageEnricher;\n};\n\n/**\n * Manages transcription state for a meeting.\n */\nexport class TranscriptionManager extends Resource {\n private readonly _edgeClient: EdgeHttpClient;\n private readonly _messageEnricher?: TranscriptMessageEnricher;\n private _audioStreamTrack?: MediaStreamTrack = undefined;\n private _identityDid?: string = undefined;\n private _mediaRecorder?: MediaStreamRecorder = undefined;\n private _transcriber?: Transcriber = undefined;\n private _queue?: Queue<DataType.Message> = undefined;\n private _enabled = signal(false);\n\n constructor(options: TranscriptionManagerOptions) {\n super();\n this._edgeClient = options.edgeClient;\n this._messageEnricher = options.messageEnricher;\n }\n\n /** @reactive */\n get enabled() {\n return this._enabled.value;\n }\n\n setQueue(queue: Queue<DataType.Message>): this {\n this._queue = queue;\n return this;\n }\n\n setIdentityDid(did: string): this {\n if (this._identityDid !== did) {\n this._identityDid = did;\n }\n return this;\n }\n\n setRecording(recording?: boolean): this {\n if (!this.isOpen || !this._enabled.value) {\n return this;\n }\n\n if (recording) {\n this._transcriber?.startChunksRecording();\n } else {\n this._transcriber?.stopChunksRecording();\n }\n return this;\n }\n\n async setEnabled(enabled: boolean): Promise<void> {\n if (this._enabled.value === enabled) {\n return;\n }\n\n this._enabled.value = enabled ?? false;\n if (enabled) {\n await this._maybeRestartTranscriber();\n } else {\n await this._stopTranscriber();\n }\n }\n\n @synchronized\n async setAudioTrack(track?: MediaStreamTrack): Promise<void> {\n if (this._audioStreamTrack === track) {\n return;\n }\n\n this._audioStreamTrack = track;\n await this._maybeRestartTranscriber();\n }\n\n protected override async _open(): Promise<void> {\n await this._maybeRestartTranscriber();\n }\n\n protected override async _close(): Promise<void> {\n await this._stopTranscriber();\n }\n\n private async _maybeRestartTranscriber(): Promise<void> {\n if (!this._audioStreamTrack || !this._enabled.value || !this.isOpen) {\n return;\n }\n\n // Reinitialize transcriber if queue or media stream track has changed.\n let needReinit = false;\n if (this._audioStreamTrack !== this._mediaRecorder?.mediaStreamTrack) {\n this._mediaRecorder = new MediaStreamRecorder({\n mediaStreamTrack: this._audioStreamTrack,\n config: { interval: RECORD_INTERVAL },\n });\n needReinit = true;\n }\n if (needReinit) {\n await this._transcriber?.close();\n this._transcriber = new Transcriber({\n config: {\n transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT,\n prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT,\n },\n recorder: this._mediaRecorder,\n onSegments: (segments) => this._onSegments(segments),\n });\n\n await this._transcriber?.open();\n }\n }\n\n private async _stopTranscriber(): Promise<void> {\n await this._transcriber?.close();\n }\n\n private async _onSegments(segments: DataType.MessageBlock.Transcript[]): Promise<void> {\n if (!this.isOpen || !this._queue) {\n return;\n }\n\n let block = Obj.make(DataType.Message, {\n created: new Date().toISOString(),\n blocks: segments,\n sender: { identityDid: this._identityDid },\n });\n\n if (this._messageEnricher) {\n block = await this._messageEnricher(block);\n }\n\n await this._queue.append([block]);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["MediaRecorder", "register", "WaveFile", "synchronized", "invariant", "log", "trace", "initializingPromise", "initializeExtendableMediaRecorder", "connect", "MediaStreamRecorder", "wavConfig", "settings", "_mediaStreamTrack", "getSettings", "channels", "channelCount", "sampleRate", "bitDepthCode", "sampleSize", "String", "mediaStreamTrack", "setOnChunk", "onChunk", "_onChunk", "start", "catch", "err", "info", "_mediaRecorder", "stream", "MediaStream", "mimeType", "state", "ondataavailable", "event", "_ondataavailable", "_config", "interval", "stop", "blob", "data", "uint8Array", "Uint8Array", "arrayBuffer", "isHeader", "wav", "_header", "slice", "warn", "timestamp", "Date", "now", "getSamples", "config", "undefined", "resource", "WaveFile", "DeferredTask", "Trigger", "LifecycleState", "Resource", "log", "trace", "mergeFloat64Arrays", "arrays", "newArray", "Float64Array", "reduce", "acc", "array", "length", "offset", "set", "Transcriber", "Resource", "_open", "ctx", "log", "info", "_recorder", "setOnChunk", "chunk", "_saveAudioChunk", "start", "_transcribeTask", "DeferredTask", "_transcribe", "_openTrigger", "wake", "_close", "_recording", "undefined", "stop", "startChunksRecording", "_lifecycleState", "LifecycleState", "OPEN", "stopChunksRecording", "schedule", "_audioChunks", "push", "scheduled", "length", "_config", "prefixBufferChunksAmount", "_dropOldChunks", "transcribeAfterChunksAmount", "chunks", "audio", "_mergeAudioChunks", "segments", "_fetchTranscription", "Array", "isArray", "alignedSegments", "_alignSegments", "_onSegments", "slice", "file", "WaveFile", "wavConfig", "fromScratch", "channels", "sampleRate", "bitDepthCode", "mergeFloat64Arrays", "map", "data", "toBase64", "Error", "response", "fetch", "TRANSCRIPTION_URL", "method", "body", "JSON", "stringify", "headers", "ok", "statusText", "json", "string", "text", "join", "originalChunks", "zeroTimestamp", "at", "timestamp", "filteredSegments", "filter", "segment", "end", "_lastUsedTimestamp", "words", "word", "_tag", "started", "Date", "toISOString", "trim", "config", "recorder", "onSegments", "_define_property", "Trigger", "autoReset", "span", "showInBrowserTimeline", "signal", "synchronized", "Resource", "Obj", "DataType", "RECORD_INTERVAL", "PREFIXED_CHUNKS_AMOUNT", "TRANSCRIBE_AFTER_CHUNKS_AMOUNT", "TranscriptionManager", "Resource", "enabled", "_enabled", "value", "setQueue", "queue", "_queue", "setIdentityDid", "did", "_identityDid", "setRecording", "recording", "isOpen", "_transcriber", "startChunksRecording", "stopChunksRecording", "setEnabled", "_maybeRestartTranscriber", "_stopTranscriber", "setAudioTrack", "track", "_audioStreamTrack", "_open", "_close", "needReinit", "_mediaRecorder", "mediaStreamTrack", "MediaStreamRecorder", "config", "interval", "close", "Transcriber", "transcribeAfterChunksAmount", "prefixBufferChunksAmount", "recorder", "onSegments", "segments", "_onSegments", "open", "block", "Obj", "make", "DataType", "Message", "created", "Date", "toISOString", "blocks", "sender", "identityDid", "_messageEnricher", "append", "options", "_define_property", "_edgeClient", "undefined", "signal", "edgeClient", "messageEnricher"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export,
|
|
3
|
+
meta
|
|
4
|
+
} from "./chunk-3X7HP44M.mjs";
|
|
5
|
+
|
|
6
|
+
// src/types/TranscriptAction.ts
|
|
7
|
+
var TranscriptAction_exports = {};
|
|
8
|
+
__export(TranscriptAction_exports, {
|
|
9
|
+
Create: () => Create
|
|
10
|
+
});
|
|
11
|
+
import { Schema as Schema2 } from "effect";
|
|
12
|
+
import { SpaceSchema } from "@dxos/client/echo";
|
|
13
|
+
|
|
14
|
+
// src/types/Transcript.ts
|
|
15
|
+
var Transcript_exports = {};
|
|
16
|
+
__export(Transcript_exports, {
|
|
17
|
+
Transcript: () => Transcript,
|
|
18
|
+
makeTranscript: () => makeTranscript
|
|
19
|
+
});
|
|
20
|
+
import { Schema } from "effect";
|
|
21
|
+
import { Queue } from "@dxos/client/echo";
|
|
22
|
+
import { Obj, Ref, Type } from "@dxos/echo";
|
|
23
|
+
var Transcript = Schema.Struct({
|
|
24
|
+
// TODO(wittjosiah): Remove?
|
|
25
|
+
// TODO(burdon): Use Date or string?
|
|
26
|
+
started: Schema.optional(Schema.String),
|
|
27
|
+
ended: Schema.optional(Schema.String),
|
|
28
|
+
/**
|
|
29
|
+
* Queue containing TranscriptBlock objects.
|
|
30
|
+
*/
|
|
31
|
+
queue: Type.Ref(Queue)
|
|
32
|
+
}).pipe(Type.Obj({
|
|
33
|
+
typename: "dxos.org/type/Transcript",
|
|
34
|
+
version: "0.1.0"
|
|
35
|
+
}));
|
|
36
|
+
var TranscriptHeader = Schema.Struct({
|
|
37
|
+
started: Schema.optional(Schema.String)
|
|
38
|
+
});
|
|
39
|
+
var makeTranscript = (queueDxn) => Obj.make(Transcript, {
|
|
40
|
+
queue: Ref.fromDXN(queueDxn)
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// src/types/TranscriptAction.ts
|
|
44
|
+
var Create = class extends Schema2.TaggedClass()(`${meta.id}/action/create`, {
|
|
45
|
+
input: Schema2.Struct({
|
|
46
|
+
name: Schema2.optional(Schema2.String),
|
|
47
|
+
space: SpaceSchema
|
|
48
|
+
}),
|
|
49
|
+
output: Schema2.Struct({
|
|
50
|
+
object: Transcript
|
|
51
|
+
})
|
|
52
|
+
}) {
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// src/types/types.ts
|
|
56
|
+
var TRANSCRIPTION_URL = "https://calls-service.dxos.workers.dev";
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
Transcript_exports,
|
|
60
|
+
TranscriptAction_exports,
|
|
61
|
+
TRANSCRIPTION_URL
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=chunk-HXVGV7T6.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/types/TranscriptAction.ts", "../../../src/types/Transcript.ts", "../../../src/types/types.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\nimport { SpaceSchema } from '@dxos/client/echo';\n\nimport { meta } from '../meta';\n\nimport { Transcript } from './Transcript';\n\n/**\n * Endpoint to the calls service.\n */\nexport class Create extends Schema.TaggedClass<Create>()(`${meta.id}/action/create`, {\n input: Schema.Struct({\n name: Schema.optional(Schema.String),\n space: SpaceSchema,\n }),\n output: Schema.Struct({\n object: Transcript,\n }),\n}) {}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\nimport { Queue } from '@dxos/client/echo';\nimport { type DXN, Obj, Ref, Type } from '@dxos/echo';\n\n/**\n * Root transcript object created when the user starts a transcription.\n */\nexport const Transcript = Schema.Struct({\n // TODO(wittjosiah): Remove?\n // TODO(burdon): Use Date or string?\n started: Schema.optional(Schema.String),\n ended: Schema.optional(Schema.String),\n\n /**\n * Queue containing TranscriptBlock objects.\n */\n queue: Type.Ref(Queue),\n}).pipe(\n Type.Obj({\n typename: 'dxos.org/type/Transcript',\n version: '0.1.0',\n }),\n);\n\nexport type Transcript = Schema.Schema.Type<typeof Transcript>;\n\n// TODO(burdon): Do these need to be kept in sync with EDGE?\n\n/**\n * First message in queue.\n * Contains metadata for the recording and transcript.\n */\nconst TranscriptHeader = Schema.Struct({\n started: Schema.optional(Schema.String),\n});\n\nexport type TranscriptHeader = Schema.Schema.Type<typeof TranscriptHeader>;\n\nexport const makeTranscript = (queueDxn: DXN) => Obj.make(Transcript, { queue: Ref.fromDXN(queueDxn) });\n", "//\n// Copyright 2025 DXOS.org\n//\n\n/**\n * Endpoint to the calls service.\n */\n// TODO(burdon): Reconfigure/move.\nexport const TRANSCRIPTION_URL = 'https://calls-service.dxos.workers.dev';\n"],
|
|
5
|
+
"mappings": ";;;;;;AAAA;;;;AAIA,SAASA,UAAAA,eAAc;AAEvB,SAASC,mBAAmB;;;ACN5B;;;;;AAIA,SAASC,cAAc;AAEvB,SAASC,aAAa;AACtB,SAAmBC,KAAKC,KAAKC,YAAY;AAKlC,IAAMC,aAAaC,OAAOC,OAAO;;;EAGtCC,SAASF,OAAOG,SAASH,OAAOI,MAAM;EACtCC,OAAOL,OAAOG,SAASH,OAAOI,MAAM;;;;EAKpCE,OAAOC,KAAKC,IAAIC,KAAAA;AAClB,CAAA,EAAGC,KACDH,KAAKI,IAAI;EACPC,UAAU;EACVC,SAAS;AACX,CAAA,CAAA;AAWF,IAAMC,mBAAmBd,OAAOC,OAAO;EACrCC,SAASF,OAAOG,SAASH,OAAOI,MAAM;AACxC,CAAA;AAIO,IAAMW,iBAAiB,CAACC,aAAkBL,IAAIM,KAAKlB,YAAY;EAAEO,OAAOE,IAAIU,QAAQF,QAAAA;AAAU,CAAA;;;AD5B9F,IAAMG,SAAN,cAAqBC,QAAOC,YAAW,EAAW,GAAGC,KAAKC,EAAE,kBAAkB;EACnFC,OAAOJ,QAAOK,OAAO;IACnBC,MAAMN,QAAOO,SAASP,QAAOQ,MAAM;IACnCC,OAAOC;EACT,CAAA;EACAC,QAAQX,QAAOK,OAAO;IACpBO,QAAQC;EACV,CAAA;AACF,CAAA,EAAA;AAAI;;;AEfG,IAAMC,oBAAoB;",
|
|
6
|
+
"names": ["Schema", "SpaceSchema", "Schema", "Queue", "Obj", "Ref", "Type", "Transcript", "Schema", "Struct", "started", "optional", "String", "ended", "queue", "Type", "Ref", "Queue", "pipe", "Obj", "typename", "version", "TranscriptHeader", "makeTranscript", "queueDxn", "make", "fromDXN", "Create", "Schema", "TaggedClass", "meta", "id", "input", "Struct", "name", "optional", "String", "space", "SpaceSchema", "output", "object", "Transcript", "TRANSCRIPTION_URL"]
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TRANSCRIPTION_PLUGIN
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3X7HP44M.mjs";
|
|
4
4
|
|
|
5
5
|
// src/capabilities/capabilities.ts
|
|
6
6
|
import { defineCapability } from "@dxos/app-framework";
|
|
@@ -13,4 +13,4 @@ var TranscriptionCapabilities;
|
|
|
13
13
|
export {
|
|
14
14
|
TranscriptionCapabilities
|
|
15
15
|
};
|
|
16
|
-
//# sourceMappingURL=chunk-
|
|
16
|
+
//# sourceMappingURL=chunk-TNEQFHIU.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/capabilities/capabilities.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { defineCapability } from '@dxos/app-framework';\n\nimport { TRANSCRIPTION_PLUGIN } from '../meta';\nimport {\n type
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { defineCapability } from '@dxos/app-framework';\n\nimport { TRANSCRIPTION_PLUGIN } from '../meta';\nimport {\n type MediaStreamRecorderParams,\n type Transcriber,\n type TranscriberParams,\n type TranscriptMessageEnricher,\n type TranscriptionManager,\n} from '../transcriber';\n\nexport namespace TranscriptionCapabilities {\n export type GetTranscriberProps = {\n audioStreamTrack: MediaStreamTrack;\n recorderConfig?: Partial<MediaStreamRecorderParams['config']>;\n transcriberConfig?: Partial<TranscriberParams['config']>;\n onSegments: TranscriberParams['onSegments'];\n };\n export type GetTranscriber = (props: GetTranscriberProps) => Transcriber;\n export const Transcriber = defineCapability<GetTranscriber>(`${TRANSCRIPTION_PLUGIN}/capability/transcriber`);\n\n export type GetTranscriptionManagerProps = {\n messageEnricher?: TranscriptMessageEnricher;\n };\n export type GetTranscriptionManager = (props: GetTranscriptionManagerProps) => TranscriptionManager;\n export const TranscriptionManager = defineCapability<GetTranscriptionManager>(\n `${TRANSCRIPTION_PLUGIN}/capability/transcription-manager`,\n );\n}\n"],
|
|
5
5
|
"mappings": ";;;;;AAIA,SAASA,wBAAwB;UAWhBC,4BAAAA;6BAQFC,cAAcC,iBAAiC,GAAGC,oBAAAA,yBAA6C;6BAM/FC,uBAAuBF,iBAClC,GAAGC,oBAAAA,mCAAuD;AAE9D,GAjBiBH,8BAAAA,4BAAAA,CAAAA,EAAAA;;",
|
|
6
6
|
"names": ["defineCapability", "TranscriptionCapabilities", "Transcriber", "defineCapability", "TRANSCRIPTION_PLUGIN", "TranscriptionManager"]
|
|
7
7
|
}
|