@dxos/plugin-transcription 0.7.5-main.6a330ac → 0.7.5-main.6ab6199

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.
Files changed (42) hide show
  1. package/dist/lib/browser/chunk-GHTRJTEB.mjs +35 -0
  2. package/dist/lib/browser/chunk-GHTRJTEB.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +177 -69
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/{intent-resolver-EAR2TFK2.mjs → intent-resolver-RW6DEJC2.mjs} +2 -2
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/node/{chunk-JBN3P6ZF.cjs → chunk-HDRXDMK2.cjs} +4 -46
  8. package/dist/lib/node/chunk-HDRXDMK2.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +176 -68
  10. package/dist/lib/node/index.cjs.map +4 -4
  11. package/dist/lib/node/{intent-resolver-3KJZGGUQ.cjs → intent-resolver-KLBZ25XJ.cjs} +7 -7
  12. package/dist/lib/node/meta.json +1 -1
  13. package/dist/lib/node-esm/chunk-LORUIVS4.mjs +37 -0
  14. package/dist/lib/node-esm/chunk-LORUIVS4.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +177 -69
  16. package/dist/lib/node-esm/index.mjs.map +4 -4
  17. package/dist/lib/node-esm/{intent-resolver-UGLYRD4X.mjs → intent-resolver-4FMISUPW.mjs} +2 -2
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/types/src/hooks/index.d.ts +0 -1
  20. package/dist/types/src/hooks/index.d.ts.map +1 -1
  21. package/dist/types/src/index.d.ts +1 -0
  22. package/dist/types/src/index.d.ts.map +1 -1
  23. package/dist/types/src/transcriber/media-stream-recorder.d.ts +1 -0
  24. package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
  25. package/dist/types/src/transcription-manager.d.ts +36 -0
  26. package/dist/types/src/transcription-manager.d.ts.map +1 -0
  27. package/package.json +36 -36
  28. package/src/hooks/index.ts +0 -1
  29. package/src/index.ts +1 -0
  30. package/src/transcriber/media-stream-recorder.ts +4 -0
  31. package/src/transcription-manager.ts +173 -0
  32. package/dist/lib/browser/chunk-ZMES3U2D.mjs +0 -78
  33. package/dist/lib/browser/chunk-ZMES3U2D.mjs.map +0 -7
  34. package/dist/lib/node/chunk-JBN3P6ZF.cjs.map +0 -7
  35. package/dist/lib/node-esm/chunk-XYU6B73V.mjs +0 -80
  36. package/dist/lib/node-esm/chunk-XYU6B73V.mjs.map +0 -7
  37. package/dist/types/src/hooks/useIsSpeaking.d.ts +0 -2
  38. package/dist/types/src/hooks/useIsSpeaking.d.ts.map +0 -1
  39. package/src/hooks/useIsSpeaking.ts +0 -77
  40. /package/dist/lib/browser/{intent-resolver-EAR2TFK2.mjs.map → intent-resolver-RW6DEJC2.mjs.map} +0 -0
  41. /package/dist/lib/node/{intent-resolver-3KJZGGUQ.cjs.map → intent-resolver-KLBZ25XJ.cjs.map} +0 -0
  42. /package/dist/lib/node-esm/{intent-resolver-UGLYRD4X.mjs.map → intent-resolver-4FMISUPW.mjs.map} +0 -0
@@ -0,0 +1,35 @@
1
+ // packages/plugins/experimental/plugin-transcription/src/util/get-time-str.ts
2
+ var getTimeStr = (timestamp) => new Date(timestamp ?? Date.now()).toLocaleTimeString("en-US", {
3
+ timeZone: "UTC",
4
+ hour12: true,
5
+ hour: "numeric",
6
+ minute: "2-digit",
7
+ second: "2-digit"
8
+ });
9
+
10
+ // packages/plugins/experimental/plugin-transcription/src/util/random-queue-dxn.ts
11
+ import { ObjectId } from "@dxos/echo-schema";
12
+ import { DXN, QueueSubspaceTags, SpaceId } from "@dxos/keys";
13
+ var randomQueueDxn = () => new DXN(DXN.kind.QUEUE, [
14
+ QueueSubspaceTags.DATA,
15
+ SpaceId.random(),
16
+ ObjectId.random()
17
+ ]);
18
+
19
+ // packages/plugins/experimental/plugin-transcription/src/util/array.ts
20
+ var mergeFloat64Arrays = (arrays) => {
21
+ const newArray = new Float64Array(arrays.reduce((acc, array) => array.length + acc, 0));
22
+ let offset = 0;
23
+ for (const array of arrays) {
24
+ newArray.set(array, offset);
25
+ offset += array.length;
26
+ }
27
+ return newArray;
28
+ };
29
+
30
+ export {
31
+ mergeFloat64Arrays,
32
+ getTimeStr,
33
+ randomQueueDxn
34
+ };
35
+ //# sourceMappingURL=chunk-GHTRJTEB.mjs.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": ";AAIO,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;;;ACPF,SAASC,gBAAgB;AACzB,SAASC,KAAKC,mBAAmBC,eAAe;AAEzC,IAAMC,iBAAiB,MAC5B,IAAIC,IAAIA,IAAIC,KAAKC,OAAO;EAACC,kBAAkBC;EAAMC,QAAQC,OAAM;EAAIC,SAASD,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", "ObjectId", "DXN", "QueueSubspaceTags", "SpaceId", "randomQueueDxn", "DXN", "kind", "QUEUE", "QueueSubspaceTags", "DATA", "SpaceId", "random", "ObjectId", "mergeFloat64Arrays", "arrays", "newArray", "Float64Array", "reduce", "acc", "array", "length", "offset", "set"]
7
+ }
@@ -1,7 +1,6 @@
1
1
  import {
2
- mergeFloat64Arrays,
3
- monitorAudioLevel
4
- } from "./chunk-ZMES3U2D.mjs";
2
+ mergeFloat64Arrays
3
+ } from "./chunk-GHTRJTEB.mjs";
5
4
  import {
6
5
  TranscriptContainer
7
6
  } from "./chunk-AS364WZZ.mjs";
@@ -12,6 +11,7 @@ import {
12
11
  import {
13
12
  TRANSCRIPTION_PLUGIN,
14
13
  TRANSCRIPTION_URL,
14
+ TranscriptBlock,
15
15
  TranscriptType,
16
16
  meta
17
17
  } from "./chunk-QIHUPVQD.mjs";
@@ -28,7 +28,7 @@ var TranscriptionCapabilities;
28
28
 
29
29
  // packages/plugins/experimental/plugin-transcription/src/capabilities/index.ts
30
30
  var AppGraphBuilder = lazy(() => import("./app-graph-builder-ZSSJIFY7.mjs"));
31
- var IntentResolver = lazy(() => import("./intent-resolver-EAR2TFK2.mjs"));
31
+ var IntentResolver = lazy(() => import("./intent-resolver-RW6DEJC2.mjs"));
32
32
  var ReactSurface = lazy(() => import("./react-surface-FOEWLLTZ.mjs"));
33
33
 
34
34
  // packages/plugins/experimental/plugin-transcription/src/hooks/useAudioFile.ts
@@ -121,64 +121,8 @@ var useAudioTrack = (active) => {
121
121
  return track;
122
122
  };
123
123
 
124
- // packages/plugins/experimental/plugin-transcription/src/hooks/useIsSpeaking.ts
125
- import { useEffect as useEffect3, useRef, useState as useState3 } from "react";
126
- var useIsSpeaking = (mediaStreamTrack) => {
127
- const [isSpeaking, setIsSpeaking] = useState3(false);
128
- const isSpeakingRef = useRef(isSpeaking);
129
- useEffect3(() => {
130
- if (!mediaStreamTrack) {
131
- setIsSpeaking(false);
132
- return;
133
- }
134
- isSpeakingRef.current = isSpeaking;
135
- const interval = window.setInterval(() => {
136
- if (isSpeaking === isSpeakingRef.current) {
137
- return;
138
- }
139
- setIsSpeaking(isSpeakingRef.current);
140
- }, 50);
141
- return () => {
142
- clearInterval(interval);
143
- };
144
- }, [
145
- isSpeaking,
146
- isSpeakingRef,
147
- mediaStreamTrack
148
- ]);
149
- useEffect3(() => {
150
- if (!mediaStreamTrack) {
151
- return;
152
- }
153
- let timeout = -1;
154
- const cleanup = monitorAudioLevel({
155
- mediaStreamTrack,
156
- onMeasure: (vol) => {
157
- const audioLevelAboveThreshold = vol > (isSpeakingRef.current ? 0.02 : 0.05);
158
- if (audioLevelAboveThreshold) {
159
- clearTimeout(timeout);
160
- timeout = -1;
161
- isSpeakingRef.current = true;
162
- } else if (timeout === -1) {
163
- timeout = window.setTimeout(() => {
164
- isSpeakingRef.current = false;
165
- timeout = -1;
166
- }, 1e3);
167
- }
168
- }
169
- });
170
- return () => {
171
- cleanup();
172
- };
173
- }, [
174
- isSpeaking,
175
- mediaStreamTrack
176
- ]);
177
- return isSpeaking;
178
- };
179
-
180
124
  // packages/plugins/experimental/plugin-transcription/src/hooks/useTranscriber.ts
181
- import { useEffect as useEffect4, useMemo } from "react";
125
+ import { useEffect as useEffect3, useMemo } from "react";
182
126
 
183
127
  // packages/plugins/experimental/plugin-transcription/src/transcriber/media-stream-recorder.ts
184
128
  import { MediaRecorder, register } from "extendable-media-recorder";
@@ -214,6 +158,9 @@ var MediaStreamRecorder = class {
214
158
  bitDepthCode: settings.sampleSize ? String(settings.sampleSize) : "16"
215
159
  };
216
160
  }
161
+ get mediaStreamTrack() {
162
+ return this._mediaStreamTrack;
163
+ }
217
164
  setOnChunk(onChunk) {
218
165
  this._onChunk = onChunk;
219
166
  }
@@ -222,7 +169,7 @@ var MediaStreamRecorder = class {
222
169
  err
223
170
  }, {
224
171
  F: __dxlog_file2,
225
- L: 58,
172
+ L: 62,
226
173
  S: this,
227
174
  C: (f, a) => f(...a)
228
175
  }));
@@ -239,7 +186,7 @@ var MediaStreamRecorder = class {
239
186
  }
240
187
  invariant(this._onChunk, "MediaStreamRecorder: onChunk is not set", {
241
188
  F: __dxlog_file2,
242
- L: 69,
189
+ L: 73,
243
190
  S: this,
244
191
  A: [
245
192
  "this._onChunk",
@@ -274,7 +221,7 @@ var MediaStreamRecorder = class {
274
221
  } else {
275
222
  log2.warn("MediaStreamRecorder: no header", void 0, {
276
223
  F: __dxlog_file2,
277
- L: 100,
224
+ L: 104,
278
225
  S: this,
279
226
  C: (f, a) => f(...a)
280
227
  });
@@ -479,7 +426,7 @@ var useTranscriber = ({ audioStreamTrack, onSegments }) => {
479
426
  audioStreamTrack,
480
427
  onSegments
481
428
  ]);
482
- useEffect4(() => {
429
+ useEffect3(() => {
483
430
  return () => {
484
431
  void transcriber?.close();
485
432
  };
@@ -490,7 +437,7 @@ var useTranscriber = ({ audioStreamTrack, onSegments }) => {
490
437
  };
491
438
 
492
439
  // packages/plugins/experimental/plugin-transcription/src/hooks/useVoiceInput.ts
493
- import { useState as useState4, useEffect as useEffect5, useCallback } from "react";
440
+ import { useState as useState3, useEffect as useEffect4, useCallback } from "react";
494
441
  import { scheduleMicroTask } from "@dxos/async";
495
442
  import { Context } from "@dxos/context";
496
443
  import { log as log4 } from "@dxos/log";
@@ -503,13 +450,13 @@ var useVoiceInput = ({ active, onUpdate }) => {
503
450
  const text = segments.map((str) => str.text.trim().replace(/[^\w\s]/g, "")).join(" ");
504
451
  onUpdate(text);
505
452
  }, []);
506
- const [recording, setRecording] = useState4(false);
453
+ const [recording, setRecording] = useState3(false);
507
454
  const track = useAudioTrack(active);
508
455
  const transcriber = useTranscriber({
509
456
  audioStreamTrack: track,
510
457
  onSegments: handleSegments
511
458
  });
512
- useEffect5(() => {
459
+ useEffect4(() => {
513
460
  const ctx = new Context(void 0, {
514
461
  F: __dxlog_file4,
515
462
  L: 43
@@ -551,6 +498,167 @@ var useVoiceInput = ({ active, onUpdate }) => {
551
498
  };
552
499
  };
553
500
 
501
+ // packages/plugins/experimental/plugin-transcription/src/transcription-manager.ts
502
+ import { synchronized as synchronized2 } from "@dxos/async";
503
+ import { Resource as Resource2 } from "@dxos/context";
504
+ import { QueueImpl } from "@dxos/echo-db";
505
+ import { createStatic } from "@dxos/echo-schema";
506
+ import { invariant as invariant2 } from "@dxos/invariant";
507
+ import { DXN } from "@dxos/keys";
508
+ function _ts_decorate3(decorators, target, key, desc) {
509
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
510
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
511
+ 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;
512
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
513
+ }
514
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-transcription/src/transcription-manager.ts";
515
+ var RECORD_INTERVAL2 = 200;
516
+ var PREFIXED_CHUNKS_AMOUNT2 = 10;
517
+ var TRANSCRIBE_AFTER_CHUNKS_AMOUNT2 = 50;
518
+ var TranscriptionManager = class extends Resource2 {
519
+ constructor(edgeClient) {
520
+ super();
521
+ this._audioStreamTrack = void 0;
522
+ this._name = void 0;
523
+ this._mediaRecorder = void 0;
524
+ this._transcriber = void 0;
525
+ this._enabled = false;
526
+ this._queue = void 0;
527
+ this._edgeClient = edgeClient;
528
+ }
529
+ async _open() {
530
+ await this._toggleTranscriber();
531
+ }
532
+ async _close() {
533
+ void this._transcriber?.close();
534
+ }
535
+ setRecording(recording) {
536
+ if (!this.isOpen || !this._enabled) {
537
+ return;
538
+ }
539
+ if (recording) {
540
+ this._transcriber?.startChunksRecording();
541
+ } else {
542
+ this._transcriber?.stopChunksRecording();
543
+ }
544
+ }
545
+ /**
546
+ * Enable or disable transcription.
547
+ * @param enabled - Whether to enable transcription.
548
+ */
549
+ async setEnabled(enabled) {
550
+ if (this._enabled === enabled) {
551
+ return;
552
+ }
553
+ this._enabled = enabled ?? false;
554
+ this.isOpen && await this._toggleTranscriber();
555
+ }
556
+ async setAudioTrack(track) {
557
+ if (this._audioStreamTrack === track) {
558
+ return;
559
+ }
560
+ this._audioStreamTrack = track;
561
+ this.isOpen && await this._toggleTranscriber();
562
+ }
563
+ /**
564
+ * Set the queue to save the transcription to.
565
+ * @param queue - The queue to save the transcription to or the DXN of the queue.
566
+ */
567
+ setQueue(queue) {
568
+ switch (typeof queue) {
569
+ case "string":
570
+ if (this._queue?.dxn.toString() === queue) {
571
+ return;
572
+ }
573
+ this._queue = new QueueImpl(this._edgeClient, DXN.parse(queue));
574
+ break;
575
+ case "object":
576
+ if (this._queue === queue) {
577
+ return;
578
+ }
579
+ invariant2(queue instanceof QueueImpl, void 0, {
580
+ F: __dxlog_file5,
581
+ L: 110,
582
+ S: this,
583
+ A: [
584
+ "queue instanceof QueueImpl",
585
+ ""
586
+ ]
587
+ });
588
+ this._queue = queue;
589
+ break;
590
+ case "undefined":
591
+ this._queue = void 0;
592
+ break;
593
+ }
594
+ }
595
+ setName(name) {
596
+ if (this._name === name) {
597
+ return;
598
+ }
599
+ this._name = name;
600
+ }
601
+ async _toggleTranscriber() {
602
+ await this._maybeReinitTranscriber();
603
+ if (this._enabled) {
604
+ await this._transcriber?.open();
605
+ } else {
606
+ await this._transcriber?.close();
607
+ }
608
+ }
609
+ async _maybeReinitTranscriber() {
610
+ if (!this._audioStreamTrack || !this._enabled) {
611
+ return;
612
+ }
613
+ let needReinit = false;
614
+ if (this._audioStreamTrack !== this._mediaRecorder?.mediaStreamTrack) {
615
+ this._mediaRecorder = new MediaStreamRecorder({
616
+ mediaStreamTrack: this._audioStreamTrack,
617
+ interval: RECORD_INTERVAL2
618
+ });
619
+ needReinit = true;
620
+ }
621
+ if (needReinit) {
622
+ await this._transcriber?.close();
623
+ this._transcriber = new Transcriber({
624
+ config: {
625
+ transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT2,
626
+ prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT2
627
+ },
628
+ recorder: this._mediaRecorder,
629
+ onSegments: (segments) => this._onSegments(segments)
630
+ });
631
+ }
632
+ }
633
+ async _onSegments(segments) {
634
+ if (!this.isOpen || !this._queue) {
635
+ return;
636
+ }
637
+ const block = createStatic(TranscriptBlock, {
638
+ author: this._name,
639
+ segments
640
+ });
641
+ this._queue.append([
642
+ block
643
+ ]);
644
+ }
645
+ };
646
+ _ts_decorate3([
647
+ synchronized2
648
+ ], TranscriptionManager.prototype, "setRecording", null);
649
+ _ts_decorate3([
650
+ synchronized2
651
+ ], TranscriptionManager.prototype, "setEnabled", null);
652
+ _ts_decorate3([
653
+ synchronized2
654
+ ], TranscriptionManager.prototype, "setAudioTrack", null);
655
+ _ts_decorate3([
656
+ synchronized2
657
+ ], TranscriptionManager.prototype, "setQueue", null);
658
+ _ts_decorate3([
659
+ synchronized2
660
+ ], TranscriptionManager.prototype, "setName", null);
661
+
554
662
  // packages/plugins/experimental/plugin-transcription/src/TranscriptionPlugin.tsx
555
663
  import { Capabilities, Events, contributes, defineModule, definePlugin } from "@dxos/app-framework";
556
664
  import { ClientCapabilities, ClientEvents } from "@dxos/plugin-client";
@@ -641,11 +749,11 @@ export {
641
749
  TranscriptContainer,
642
750
  TranscriptionCapabilities,
643
751
  TranscriptionContainer,
752
+ TranscriptionManager,
644
753
  TranscriptionPlugin,
645
754
  meta,
646
755
  useAudioFile,
647
756
  useAudioTrack,
648
- useIsSpeaking,
649
757
  useTranscriber,
650
758
  useVoiceInput
651
759
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/capabilities/index.ts", "../../../src/capabilities/capabilities.ts", "../../../src/hooks/useAudioFile.ts", "../../../src/hooks/useAudioTrack.ts", "../../../src/hooks/useIsSpeaking.ts", "../../../src/hooks/useTranscriber.ts", "../../../src/transcriber/media-stream-recorder.ts", "../../../src/transcriber/transcriber.ts", "../../../src/hooks/useVoiceInput.ts", "../../../src/TranscriptionPlugin.tsx", "../../../src/translations.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { lazy } from '@dxos/app-framework';\n\nexport const AppGraphBuilder = lazy(() => import('./app-graph-builder'));\nexport const IntentResolver = lazy(() => import('./intent-resolver'));\nexport const ReactSurface = lazy(() => import('./react-surface'));\n\nexport * from './capabilities';\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { defineCapability } from '@dxos/app-framework';\n\nimport { TRANSCRIPTION_PLUGIN } from '../meta';\n\nexport namespace TranscriptionCapabilities {\n // TODO(burdon): Currently this is just a marker; adapt useVoiceInput to use this.\n export const Transcription = defineCapability<null>(`${TRANSCRIPTION_PLUGIN}/capability/transcription`);\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\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): UseAudioState => {\n const [{ audio, stream, track }, setStream] = useState<UseAudioState>({});\n useEffect(() => {\n const t = setTimeout(async () => {\n const response = await fetch(audioUrl);\n const blob = await response.blob();\n const audio = new Audio();\n audio.src = URL.createObjectURL(blob);\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 () => {\n log.info('starting...');\n resolve();\n },\n { once: true },\n );\n audio.load();\n });\n\n const ctx = new AudioContext();\n\n const destination = ctx.createMediaStreamDestination();\n destination.channelCount = 1;\n\n const source = ctx.createMediaElementSource(audio);\n source.connect(destination);\n\n setStream({\n audio,\n stream: destination.stream,\n track: destination.stream.getAudioTracks()[0],\n });\n });\n\n return () => clearTimeout(t);\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): 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: 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, useRef, useState } from 'react';\n\nimport { monitorAudioLevel } from '../util';\n\nexport const useIsSpeaking = (mediaStreamTrack?: MediaStreamTrack) => {\n const [isSpeaking, setIsSpeaking] = useState(false);\n\n // The audio level is monitored very rapidly, and we don't want\n // react involved in tracking the state because it causes way\n // too many re-renders. To work around this, we use the isSpeakingRef\n // to track the state and then sync it using another effect.\n const isSpeakingRef = useRef(isSpeaking);\n\n // this effect syncs the state on a 50ms interval\n useEffect(() => {\n if (!mediaStreamTrack) {\n setIsSpeaking(false);\n return;\n }\n\n isSpeakingRef.current = isSpeaking;\n const interval = window.setInterval(() => {\n // state is already in sync do nothing\n if (isSpeaking === isSpeakingRef.current) {\n return;\n }\n\n // sync state\n setIsSpeaking(isSpeakingRef.current);\n }, 50);\n\n return () => {\n clearInterval(interval);\n };\n }, [isSpeaking, isSpeakingRef, mediaStreamTrack]);\n\n useEffect(() => {\n if (!mediaStreamTrack) {\n return;\n }\n\n let timeout = -1;\n const cleanup = monitorAudioLevel({\n mediaStreamTrack,\n onMeasure: (vol) => {\n // Once the user has been determined to be speaking, we want\n // to lower the threshold because speech patterns don't always\n // kick up above 0.05\n const audioLevelAboveThreshold = vol > (isSpeakingRef.current ? 0.02 : 0.05);\n if (audioLevelAboveThreshold) {\n // user is still speaking, clear timeout & reset.\n clearTimeout(timeout);\n timeout = -1;\n // track state.\n isSpeakingRef.current = true;\n } else if (timeout === -1) {\n // user is not speaking and timeout is not set.\n timeout = window.setTimeout(() => {\n isSpeakingRef.current = false;\n // reset timeout\n timeout = -1;\n }, 1_000);\n }\n },\n });\n\n return () => {\n cleanup();\n };\n }, [isSpeaking, mediaStreamTrack]);\n\n return isSpeaking;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useMemo } from 'react';\n\nimport { MediaStreamRecorder, Transcriber, type TranscriberParams } from '../transcriber';\n\n// TODO(burdon): Move to config?\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 UseTranscriberProps = {\n audioStreamTrack?: MediaStreamTrack;\n onSegments?: TranscriberParams['onSegments'];\n};\n\n/**\n * Records audio while user is speaking and transcribes it after user is done speaking.\n */\nexport const useTranscriber = ({ audioStreamTrack, onSegments }: UseTranscriberProps) => {\n // Initialize audio transcription.\n const transcriber = useMemo<Transcriber | undefined>(() => {\n if (!onSegments || !audioStreamTrack) {\n return undefined;\n }\n\n return new Transcriber({\n config: {\n transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT,\n prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT,\n },\n recorder: new MediaStreamRecorder({\n mediaStreamTrack: audioStreamTrack,\n interval: RECORD_INTERVAL,\n }),\n onSegments,\n });\n }, [audioStreamTrack, 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 { type IBlobEvent, type IMediaRecorder, MediaRecorder, register } from 'extendable-media-recorder';\nimport { WaveFile } from 'wavefile';\n\nimport { synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/tracing';\n\nimport { type WavConfig, type AudioChunk, type AudioRecorder } from './audio-recorder';\n\nlet initializingPromise: Promise<void> | undefined;\n\nconst initializeExtendableMediaRecorder = async () => {\n const { connect } = await import('extendable-media-recorder-wav-encoder');\n await register(await connect());\n};\n\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 _interval: number;\n private _mediaRecorder?: IMediaRecorder = undefined;\n private _header?: Uint8Array = undefined;\n private _onChunk?: (chunk: AudioChunk) => void;\n\n constructor({ mediaStreamTrack, interval }: { mediaStreamTrack: MediaStreamTrack; interval: number }) {\n this._mediaStreamTrack = mediaStreamTrack;\n this._interval = interval;\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 setOnChunk(onChunk: (chunk: AudioChunk) => void): void {\n this._onChunk = onChunk;\n }\n\n async start() {\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._interval);\n }\n\n async stop() {\n if (this._mediaRecorder?.state !== 'recording') {\n return;\n }\n this._mediaRecorder.stop();\n }\n\n @synchronized\n private async _ondataavailable(event: IBlobEvent) {\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 { trace } from '@dxos/tracing';\n\nimport { type AudioRecorder, type AudioChunk } from './audio-recorder';\nimport { TRANSCRIPTION_URL, type TranscriptSegment } from '../types';\nimport { mergeFloat64Arrays } from '../util';\n\ntype WhisperWord = {\n word: string;\n\n /**\n * Time in seconds from the start of the audio.\n */\n start: number;\n\n /**\n * Time in seconds from the start of the audio.\n */\n end: number;\n};\n\ntype WhisperSegment = {\n text: string;\n\n /**\n * Time in seconds from the start of the audio.\n */\n start: number;\n\n /**\n * Time in seconds from the start of the audio.\n */\n end: number;\n\n /**\n * Probability of no speech in the segment.\n */\n no_speech_prob: number;\n\n words: WhisperWord[];\n};\n\nexport type TranscribeConfig = {\n /**\n * Number of chunks to transcribe automatically after.\n */\n transcribeAfterChunksAmount: number;\n\n /**\n * Number of chunks to save before the user starts speaking.\n * This is needed to catch the beginning of the user's speech.\n */\n prefixBufferChunksAmount: number;\n};\n\nexport type TranscriberParams = {\n config: TranscribeConfig;\n recorder: AudioRecorder;\n onSegments: (segments: TranscriptSegment[]) => 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) {\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() {\n this._recording = false;\n this._transcribeTask = undefined;\n await this._recorder.stop();\n }\n\n startChunksRecording() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n this._recording = true;\n }\n\n stopChunksRecording() {\n if (this._lifecycleState !== LifecycleState.OPEN || !this._recording) {\n return;\n }\n this._recording = false;\n this._transcribeTask?.schedule();\n }\n\n private _saveAudioChunk(chunk: AudioChunk) {\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() {\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() {\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[]) {\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) {\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('Failed to transcribe');\n }\n\n const {\n segments,\n }: {\n segments: WhisperSegment[];\n } = await response.json();\n\n log.info('transcription response', {\n segments,\n string: segments.map((segments) => segments.text).join(' '),\n });\n\n return segments;\n }\n\n private _alignSegments(segments: WhisperSegment[], originalChunks: AudioChunk[]): TranscriptSegment[] {\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 started: new Date(zeroTimestamp + segment.start * 1_000),\n text: segment.text,\n }));\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useState, useEffect, useCallback } 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 { useAudioTrack } from './useAudioTrack';\nimport { useTranscriber } from './useTranscriber';\nimport { type TranscriberParams } from '../transcriber';\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 2023 DXOS.org\n//\n\nimport { Capabilities, Events, contributes, defineModule, definePlugin } from '@dxos/app-framework';\nimport { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';\n\nimport { AppGraphBuilder, IntentResolver, ReactSurface, TranscriptionCapabilities } from './capabilities';\nimport { meta, TRANSCRIPTION_PLUGIN } from './meta';\nimport translations from './translations';\nimport { TranscriptType } from './types';\n\nexport const TranscriptionPlugin = () =>\n definePlugin(meta, [\n defineModule({\n id: `${meta.id}/module/translations`,\n activatesOn: Events.SetupTranslations,\n activate: () => contributes(Capabilities.Translations, translations),\n }),\n defineModule({\n id: `${meta.id}/module/transcription`,\n activatesOn: Events.Startup,\n activate: () => contributes(TranscriptionCapabilities.Transcription, null),\n }),\n defineModule({\n id: `${meta.id}/module/metadata`,\n activatesOn: Events.SetupMetadata,\n activate: () =>\n contributes(Capabilities.Metadata, {\n id: TranscriptType.typename,\n metadata: {\n placeholder: ['transcript title placeholder', { ns: TRANSCRIPTION_PLUGIN }],\n icon: 'ph--subtitles--regular',\n },\n }),\n }),\n defineModule({\n id: `${meta.id}/module/schema`,\n activatesOn: ClientEvents.SetupSchema,\n activate: () => [contributes(ClientCapabilities.Schema, [TranscriptType])],\n }),\n defineModule({\n id: `${meta.id}/module/react-surface`,\n activatesOn: Events.SetupReactSurface,\n activate: ReactSurface,\n }),\n defineModule({\n id: `${meta.id}/module/intent-resolver`,\n activatesOn: Events.SetupIntentResolver,\n activate: IntentResolver,\n }),\n defineModule({\n id: `${meta.id}/module/app-graph-builder`,\n activatesOn: Events.SetupAppGraph,\n activate: AppGraphBuilder,\n }),\n ]);\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { TRANSCRIPTION_PLUGIN } from './meta';\nimport { TranscriptType } from './types';\n\nexport default [\n {\n 'en-US': {\n [TranscriptType.typename]: {\n 'typename label': 'Transcript',\n },\n [TRANSCRIPTION_PLUGIN]: {\n 'plugin name': 'Transcription',\n 'calls label': 'Transcript',\n 'calls panel label': 'Transcription',\n 'create calls label': 'Create transcription',\n 'delete calls label': 'Delete',\n\n 'delete button': 'Delete',\n 'bookmark button': 'Bookmark',\n 'summary button': 'Create summary',\n 'summarizing label': 'Summarizing...',\n },\n },\n },\n];\n"],
5
- "mappings": "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",
6
- "names": ["lazy", "defineCapability", "TranscriptionCapabilities", "Transcription", "defineCapability", "TRANSCRIPTION_PLUGIN", "AppGraphBuilder", "lazy", "IntentResolver", "ReactSurface", "useEffect", "useState", "log", "useAudioFile", "audioUrl", "audio", "stream", "track", "setStream", "t", "setTimeout", "response", "fetch", "blob", "Audio", "src", "URL", "createObjectURL", "Promise", "resolve", "reject", "addEventListener", "err", "error", "once", "info", "load", "ctx", "AudioContext", "destination", "createMediaStreamDestination", "channelCount", "source", "createMediaElementSource", "connect", "getAudioTracks", "clearTimeout", "useEffect", "useState", "useAudioTrack", "active", "track", "setTrack", "useState", "useEffect", "stop", "undefined", "initAudio", "audio", "Audio", "srcObject", "navigator", "mediaDevices", "getUserMedia", "getAudioTracks", "useEffect", "useRef", "useState", "useIsSpeaking", "mediaStreamTrack", "isSpeaking", "setIsSpeaking", "useState", "isSpeakingRef", "useRef", "useEffect", "current", "interval", "window", "setInterval", "clearInterval", "timeout", "cleanup", "monitorAudioLevel", "onMeasure", "vol", "audioLevelAboveThreshold", "clearTimeout", "setTimeout", "useEffect", "useMemo", "MediaRecorder", "register", "WaveFile", "synchronized", "invariant", "log", "trace", "initializingPromise", "initializeExtendableMediaRecorder", "connect", "MediaStreamRecorder", "constructor", "mediaStreamTrack", "interval", "_mediaRecorder", "undefined", "_header", "_mediaStreamTrack", "_interval", "wavConfig", "settings", "getSettings", "channels", "channelCount", "sampleRate", "bitDepthCode", "sampleSize", "String", "setOnChunk", "onChunk", "_onChunk", "start", "catch", "err", "info", "stream", "MediaStream", "mimeType", "state", "ondataavailable", "event", "_ondataavailable", "stop", "blob", "data", "uint8Array", "Uint8Array", "arrayBuffer", "isHeader", "wav", "slice", "warn", "timestamp", "Date", "now", "getSamples", "resource", "WaveFile", "DeferredTask", "Trigger", "LifecycleState", "Resource", "log", "trace", "Transcriber", "Resource", "constructor", "config", "recorder", "onSegments", "_audioChunks", "_lastUsedTimestamp", "_openTrigger", "Trigger", "autoReset", "_recording", "_transcribeTask", "undefined", "_config", "_recorder", "_onSegments", "_open", "ctx", "setOnChunk", "chunk", "_saveAudioChunk", "start", "DeferredTask", "_transcribe", "wake", "_close", "stop", "startChunksRecording", "_lifecycleState", "LifecycleState", "OPEN", "stopChunksRecording", "schedule", "log", "push", "scheduled", "length", "prefixBufferChunksAmount", "_dropOldChunks", "transcribeAfterChunksAmount", "chunks", "audio", "_mergeAudioChunks", "segments", "_fetchTranscription", "Array", "isArray", "alignedSegments", "_alignSegments", "slice", "file", "WaveFile", "wavConfig", "fromScratch", "channels", "sampleRate", "bitDepthCode", "mergeFloat64Arrays", "map", "data", "toBase64", "Error", "response", "fetch", "TRANSCRIPTION_URL", "method", "body", "JSON", "stringify", "headers", "ok", "json", "info", "string", "text", "join", "originalChunks", "zeroTimestamp", "at", "timestamp", "filteredSegments", "filter", "segment", "end", "words", "word", "started", "Date", "trace", "span", "showInBrowserTimeline", "RECORD_INTERVAL", "PREFIXED_CHUNKS_AMOUNT", "TRANSCRIBE_AFTER_CHUNKS_AMOUNT", "useTranscriber", "audioStreamTrack", "onSegments", "transcriber", "useMemo", "undefined", "Transcriber", "config", "transcribeAfterChunksAmount", "prefixBufferChunksAmount", "recorder", "MediaStreamRecorder", "mediaStreamTrack", "interval", "useEffect", "close", "useState", "useEffect", "useCallback", "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", "Capabilities", "Events", "contributes", "defineModule", "definePlugin", "ClientCapabilities", "ClientEvents", "TranscriptType", "typename", "TRANSCRIPTION_PLUGIN", "TranscriptionPlugin", "definePlugin", "meta", "defineModule", "id", "activatesOn", "Events", "SetupTranslations", "activate", "contributes", "Capabilities", "Translations", "translations", "Startup", "TranscriptionCapabilities", "Transcription", "SetupMetadata", "Metadata", "TranscriptType", "typename", "metadata", "placeholder", "ns", "TRANSCRIPTION_PLUGIN", "icon", "ClientEvents", "SetupSchema", "ClientCapabilities", "Schema", "SetupReactSurface", "ReactSurface", "SetupIntentResolver", "IntentResolver", "SetupAppGraph", "AppGraphBuilder"]
3
+ "sources": ["../../../src/capabilities/index.ts", "../../../src/capabilities/capabilities.ts", "../../../src/hooks/useAudioFile.ts", "../../../src/hooks/useAudioTrack.ts", "../../../src/hooks/useTranscriber.ts", "../../../src/transcriber/media-stream-recorder.ts", "../../../src/transcriber/transcriber.ts", "../../../src/hooks/useVoiceInput.ts", "../../../src/transcription-manager.ts", "../../../src/TranscriptionPlugin.tsx", "../../../src/translations.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { lazy } from '@dxos/app-framework';\n\nexport const AppGraphBuilder = lazy(() => import('./app-graph-builder'));\nexport const IntentResolver = lazy(() => import('./intent-resolver'));\nexport const ReactSurface = lazy(() => import('./react-surface'));\n\nexport * from './capabilities';\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { defineCapability } from '@dxos/app-framework';\n\nimport { TRANSCRIPTION_PLUGIN } from '../meta';\n\nexport namespace TranscriptionCapabilities {\n // TODO(burdon): Currently this is just a marker; adapt useVoiceInput to use this.\n export const Transcription = defineCapability<null>(`${TRANSCRIPTION_PLUGIN}/capability/transcription`);\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\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): UseAudioState => {\n const [{ audio, stream, track }, setStream] = useState<UseAudioState>({});\n useEffect(() => {\n const t = setTimeout(async () => {\n const response = await fetch(audioUrl);\n const blob = await response.blob();\n const audio = new Audio();\n audio.src = URL.createObjectURL(blob);\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 () => {\n log.info('starting...');\n resolve();\n },\n { once: true },\n );\n audio.load();\n });\n\n const ctx = new AudioContext();\n\n const destination = ctx.createMediaStreamDestination();\n destination.channelCount = 1;\n\n const source = ctx.createMediaElementSource(audio);\n source.connect(destination);\n\n setStream({\n audio,\n stream: destination.stream,\n track: destination.stream.getAudioTracks()[0],\n });\n });\n\n return () => clearTimeout(t);\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): 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: 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 } from 'react';\n\nimport { MediaStreamRecorder, Transcriber, type TranscriberParams } from '../transcriber';\n\n// TODO(burdon): Move to config?\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 UseTranscriberProps = {\n audioStreamTrack?: MediaStreamTrack;\n onSegments?: TranscriberParams['onSegments'];\n};\n\n/**\n * Records audio while user is speaking and transcribes it after user is done speaking.\n */\nexport const useTranscriber = ({ audioStreamTrack, onSegments }: UseTranscriberProps) => {\n // Initialize audio transcription.\n const transcriber = useMemo<Transcriber | undefined>(() => {\n if (!onSegments || !audioStreamTrack) {\n return undefined;\n }\n\n return new Transcriber({\n config: {\n transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT,\n prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT,\n },\n recorder: new MediaStreamRecorder({\n mediaStreamTrack: audioStreamTrack,\n interval: RECORD_INTERVAL,\n }),\n onSegments,\n });\n }, [audioStreamTrack, 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 { type IBlobEvent, type IMediaRecorder, MediaRecorder, register } from 'extendable-media-recorder';\nimport { WaveFile } from 'wavefile';\n\nimport { synchronized } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { trace } from '@dxos/tracing';\n\nimport { type WavConfig, type AudioChunk, type AudioRecorder } from './audio-recorder';\n\nlet initializingPromise: Promise<void> | undefined;\n\nconst initializeExtendableMediaRecorder = async () => {\n const { connect } = await import('extendable-media-recorder-wav-encoder');\n await register(await connect());\n};\n\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 _interval: number;\n private _mediaRecorder?: IMediaRecorder = undefined;\n private _header?: Uint8Array = undefined;\n private _onChunk?: (chunk: AudioChunk) => void;\n\n constructor({ mediaStreamTrack, interval }: { mediaStreamTrack: MediaStreamTrack; interval: number }) {\n this._mediaStreamTrack = mediaStreamTrack;\n this._interval = interval;\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() {\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._interval);\n }\n\n async stop() {\n if (this._mediaRecorder?.state !== 'recording') {\n return;\n }\n this._mediaRecorder.stop();\n }\n\n @synchronized\n private async _ondataavailable(event: IBlobEvent) {\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 { trace } from '@dxos/tracing';\n\nimport { type AudioRecorder, type AudioChunk } from './audio-recorder';\nimport { TRANSCRIPTION_URL, type TranscriptSegment } from '../types';\nimport { mergeFloat64Arrays } from '../util';\n\ntype WhisperWord = {\n word: string;\n\n /**\n * Time in seconds from the start of the audio.\n */\n start: number;\n\n /**\n * Time in seconds from the start of the audio.\n */\n end: number;\n};\n\ntype WhisperSegment = {\n text: string;\n\n /**\n * Time in seconds from the start of the audio.\n */\n start: number;\n\n /**\n * Time in seconds from the start of the audio.\n */\n end: number;\n\n /**\n * Probability of no speech in the segment.\n */\n no_speech_prob: number;\n\n words: WhisperWord[];\n};\n\nexport type TranscribeConfig = {\n /**\n * Number of chunks to transcribe automatically after.\n */\n transcribeAfterChunksAmount: number;\n\n /**\n * Number of chunks to save before the user starts speaking.\n * This is needed to catch the beginning of the user's speech.\n */\n prefixBufferChunksAmount: number;\n};\n\nexport type TranscriberParams = {\n config: TranscribeConfig;\n recorder: AudioRecorder;\n onSegments: (segments: TranscriptSegment[]) => 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) {\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() {\n this._recording = false;\n this._transcribeTask = undefined;\n await this._recorder.stop();\n }\n\n startChunksRecording() {\n if (this._lifecycleState !== LifecycleState.OPEN) {\n return;\n }\n this._recording = true;\n }\n\n stopChunksRecording() {\n if (this._lifecycleState !== LifecycleState.OPEN || !this._recording) {\n return;\n }\n this._recording = false;\n this._transcribeTask?.schedule();\n }\n\n private _saveAudioChunk(chunk: AudioChunk) {\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() {\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() {\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[]) {\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) {\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('Failed to transcribe');\n }\n\n const {\n segments,\n }: {\n segments: WhisperSegment[];\n } = await response.json();\n\n log.info('transcription response', {\n segments,\n string: segments.map((segments) => segments.text).join(' '),\n });\n\n return segments;\n }\n\n private _alignSegments(segments: WhisperSegment[], originalChunks: AudioChunk[]): TranscriptSegment[] {\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 started: new Date(zeroTimestamp + segment.start * 1_000),\n text: segment.text,\n }));\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useState, useEffect, useCallback } 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 { useAudioTrack } from './useAudioTrack';\nimport { useTranscriber } from './useTranscriber';\nimport { type TranscriberParams } from '../transcriber';\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 { synchronized } from '@dxos/async';\nimport { Resource } from '@dxos/context';\nimport { QueueImpl, type Queue } from '@dxos/echo-db';\nimport { createStatic } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { DXN } from '@dxos/keys';\nimport { type EdgeHttpClient } from '@dxos/react-edge-client';\n\nimport { MediaStreamRecorder, Transcriber } from './transcriber';\nimport { TranscriptBlock, type TranscriptSegment } from './types';\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\n/**\n * Manages transcription state.\n */\n// TODO(mykola): Reconcile with useTranscriber hook.\nexport class TranscriptionManager extends Resource {\n private readonly _edgeClient: EdgeHttpClient;\n private _audioStreamTrack?: MediaStreamTrack = undefined;\n private _name?: string = undefined;\n private _mediaRecorder?: MediaStreamRecorder = undefined;\n private _transcriber?: Transcriber = undefined;\n private _enabled = false;\n private _queue?: Queue<TranscriptBlock> = undefined;\n\n constructor(edgeClient: EdgeHttpClient) {\n super();\n this._edgeClient = edgeClient;\n }\n\n protected override async _open() {\n await this._toggleTranscriber();\n }\n\n protected override async _close() {\n void this._transcriber?.close();\n }\n\n @synchronized\n setRecording(recording?: boolean) {\n if (!this.isOpen || !this._enabled) {\n return;\n }\n\n if (recording) {\n this._transcriber?.startChunksRecording();\n } else {\n this._transcriber?.stopChunksRecording();\n }\n }\n\n /**\n * Enable or disable transcription.\n * @param enabled - Whether to enable transcription.\n */\n @synchronized\n async setEnabled(enabled?: boolean) {\n if (this._enabled === enabled) {\n return;\n }\n this._enabled = enabled ?? false;\n this.isOpen && (await this._toggleTranscriber());\n }\n\n @synchronized\n async setAudioTrack(track?: MediaStreamTrack) {\n if (this._audioStreamTrack === track) {\n return;\n }\n this._audioStreamTrack = track;\n this.isOpen && (await this._toggleTranscriber());\n }\n\n /**\n * Set the queue to save the transcription to.\n * @param queue - The queue to save the transcription to or the DXN of the queue.\n */\n @synchronized\n setQueue(queue?: Queue<TranscriptBlock> | string) {\n switch (typeof queue) {\n case 'string':\n if (this._queue?.dxn.toString() === queue) {\n return;\n }\n this._queue = new QueueImpl<TranscriptBlock>(this._edgeClient, DXN.parse(queue));\n break;\n case 'object':\n if (this._queue === queue) {\n return;\n }\n invariant(queue instanceof QueueImpl);\n this._queue = queue;\n break;\n case 'undefined':\n this._queue = undefined;\n break;\n }\n }\n\n @synchronized\n setName(name: string) {\n if (this._name === name) {\n return;\n }\n this._name = name;\n }\n\n private async _toggleTranscriber() {\n await this._maybeReinitTranscriber();\n\n // Open or close transcriber if transcription is enabled or disabled.\n if (this._enabled) {\n await this._transcriber?.open();\n } else {\n await this._transcriber?.close();\n }\n }\n\n private async _maybeReinitTranscriber() {\n if (!this._audioStreamTrack || !this._enabled) {\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 interval: RECORD_INTERVAL,\n });\n needReinit = true;\n }\n if (needReinit) {\n await this._transcriber?.close();\n this._transcriber = new Transcriber({\n config: {\n transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT,\n prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT,\n },\n recorder: this._mediaRecorder,\n onSegments: (segments) => this._onSegments(segments),\n });\n }\n }\n\n private async _onSegments(segments: TranscriptSegment[]) {\n if (!this.isOpen || !this._queue) {\n return;\n }\n\n const block = createStatic(TranscriptBlock, { author: this._name, segments });\n this._queue.append([block]);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { Capabilities, Events, contributes, defineModule, definePlugin } from '@dxos/app-framework';\nimport { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';\n\nimport { AppGraphBuilder, IntentResolver, ReactSurface, TranscriptionCapabilities } from './capabilities';\nimport { meta, TRANSCRIPTION_PLUGIN } from './meta';\nimport translations from './translations';\nimport { TranscriptType } from './types';\n\nexport const TranscriptionPlugin = () =>\n definePlugin(meta, [\n defineModule({\n id: `${meta.id}/module/translations`,\n activatesOn: Events.SetupTranslations,\n activate: () => contributes(Capabilities.Translations, translations),\n }),\n defineModule({\n id: `${meta.id}/module/transcription`,\n activatesOn: Events.Startup,\n activate: () => contributes(TranscriptionCapabilities.Transcription, null),\n }),\n defineModule({\n id: `${meta.id}/module/metadata`,\n activatesOn: Events.SetupMetadata,\n activate: () =>\n contributes(Capabilities.Metadata, {\n id: TranscriptType.typename,\n metadata: {\n placeholder: ['transcript title placeholder', { ns: TRANSCRIPTION_PLUGIN }],\n icon: 'ph--subtitles--regular',\n },\n }),\n }),\n defineModule({\n id: `${meta.id}/module/schema`,\n activatesOn: ClientEvents.SetupSchema,\n activate: () => [contributes(ClientCapabilities.Schema, [TranscriptType])],\n }),\n defineModule({\n id: `${meta.id}/module/react-surface`,\n activatesOn: Events.SetupReactSurface,\n activate: ReactSurface,\n }),\n defineModule({\n id: `${meta.id}/module/intent-resolver`,\n activatesOn: Events.SetupIntentResolver,\n activate: IntentResolver,\n }),\n defineModule({\n id: `${meta.id}/module/app-graph-builder`,\n activatesOn: Events.SetupAppGraph,\n activate: AppGraphBuilder,\n }),\n ]);\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { TRANSCRIPTION_PLUGIN } from './meta';\nimport { TranscriptType } from './types';\n\nexport default [\n {\n 'en-US': {\n [TranscriptType.typename]: {\n 'typename label': 'Transcript',\n },\n [TRANSCRIPTION_PLUGIN]: {\n 'plugin name': 'Transcription',\n 'calls label': 'Transcript',\n 'calls panel label': 'Transcription',\n 'create calls label': 'Create transcription',\n 'delete calls label': 'Delete',\n\n 'delete button': 'Delete',\n 'bookmark button': 'Bookmark',\n 'summary button': 'Create summary',\n 'summarizing label': 'Summarizing...',\n },\n },\n },\n];\n"],
5
+ "mappings": "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",
6
+ "names": ["lazy", "defineCapability", "TranscriptionCapabilities", "Transcription", "defineCapability", "TRANSCRIPTION_PLUGIN", "AppGraphBuilder", "lazy", "IntentResolver", "ReactSurface", "useEffect", "useState", "log", "useAudioFile", "audioUrl", "audio", "stream", "track", "setStream", "t", "setTimeout", "response", "fetch", "blob", "Audio", "src", "URL", "createObjectURL", "Promise", "resolve", "reject", "addEventListener", "err", "error", "once", "info", "load", "ctx", "AudioContext", "destination", "createMediaStreamDestination", "channelCount", "source", "createMediaElementSource", "connect", "getAudioTracks", "clearTimeout", "useEffect", "useState", "useAudioTrack", "active", "track", "setTrack", "useState", "useEffect", "stop", "undefined", "initAudio", "audio", "Audio", "srcObject", "navigator", "mediaDevices", "getUserMedia", "getAudioTracks", "useEffect", "useMemo", "MediaRecorder", "register", "WaveFile", "synchronized", "invariant", "log", "trace", "initializingPromise", "initializeExtendableMediaRecorder", "connect", "MediaStreamRecorder", "constructor", "mediaStreamTrack", "interval", "_mediaRecorder", "undefined", "_header", "_mediaStreamTrack", "_interval", "wavConfig", "settings", "getSettings", "channels", "channelCount", "sampleRate", "bitDepthCode", "sampleSize", "String", "setOnChunk", "onChunk", "_onChunk", "start", "catch", "err", "info", "stream", "MediaStream", "mimeType", "state", "ondataavailable", "event", "_ondataavailable", "stop", "blob", "data", "uint8Array", "Uint8Array", "arrayBuffer", "isHeader", "wav", "slice", "warn", "timestamp", "Date", "now", "getSamples", "resource", "WaveFile", "DeferredTask", "Trigger", "LifecycleState", "Resource", "log", "trace", "Transcriber", "Resource", "constructor", "config", "recorder", "onSegments", "_audioChunks", "_lastUsedTimestamp", "_openTrigger", "Trigger", "autoReset", "_recording", "_transcribeTask", "undefined", "_config", "_recorder", "_onSegments", "_open", "ctx", "setOnChunk", "chunk", "_saveAudioChunk", "start", "DeferredTask", "_transcribe", "wake", "_close", "stop", "startChunksRecording", "_lifecycleState", "LifecycleState", "OPEN", "stopChunksRecording", "schedule", "log", "push", "scheduled", "length", "prefixBufferChunksAmount", "_dropOldChunks", "transcribeAfterChunksAmount", "chunks", "audio", "_mergeAudioChunks", "segments", "_fetchTranscription", "Array", "isArray", "alignedSegments", "_alignSegments", "slice", "file", "WaveFile", "wavConfig", "fromScratch", "channels", "sampleRate", "bitDepthCode", "mergeFloat64Arrays", "map", "data", "toBase64", "Error", "response", "fetch", "TRANSCRIPTION_URL", "method", "body", "JSON", "stringify", "headers", "ok", "json", "info", "string", "text", "join", "originalChunks", "zeroTimestamp", "at", "timestamp", "filteredSegments", "filter", "segment", "end", "words", "word", "started", "Date", "trace", "span", "showInBrowserTimeline", "RECORD_INTERVAL", "PREFIXED_CHUNKS_AMOUNT", "TRANSCRIBE_AFTER_CHUNKS_AMOUNT", "useTranscriber", "audioStreamTrack", "onSegments", "transcriber", "useMemo", "undefined", "Transcriber", "config", "transcribeAfterChunksAmount", "prefixBufferChunksAmount", "recorder", "MediaStreamRecorder", "mediaStreamTrack", "interval", "useEffect", "close", "useState", "useEffect", "useCallback", "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", "synchronized", "Resource", "QueueImpl", "createStatic", "invariant", "DXN", "RECORD_INTERVAL", "PREFIXED_CHUNKS_AMOUNT", "TRANSCRIBE_AFTER_CHUNKS_AMOUNT", "TranscriptionManager", "Resource", "constructor", "edgeClient", "_audioStreamTrack", "undefined", "_name", "_mediaRecorder", "_transcriber", "_enabled", "_queue", "_edgeClient", "_open", "_toggleTranscriber", "_close", "close", "setRecording", "recording", "isOpen", "startChunksRecording", "stopChunksRecording", "setEnabled", "enabled", "setAudioTrack", "track", "setQueue", "queue", "dxn", "toString", "QueueImpl", "DXN", "parse", "invariant", "setName", "name", "_maybeReinitTranscriber", "open", "needReinit", "mediaStreamTrack", "MediaStreamRecorder", "interval", "Transcriber", "config", "transcribeAfterChunksAmount", "prefixBufferChunksAmount", "recorder", "onSegments", "segments", "_onSegments", "block", "createStatic", "TranscriptBlock", "author", "append", "synchronized", "Capabilities", "Events", "contributes", "defineModule", "definePlugin", "ClientCapabilities", "ClientEvents", "TranscriptType", "typename", "TRANSCRIPTION_PLUGIN", "TranscriptionPlugin", "definePlugin", "meta", "defineModule", "id", "activatesOn", "Events", "SetupTranslations", "activate", "contributes", "Capabilities", "Translations", "translations", "Startup", "TranscriptionCapabilities", "Transcription", "SetupMetadata", "Metadata", "TranscriptType", "typename", "metadata", "placeholder", "ns", "TRANSCRIPTION_PLUGIN", "icon", "ClientEvents", "SetupSchema", "ClientCapabilities", "Schema", "SetupReactSurface", "ReactSurface", "SetupIntentResolver", "IntentResolver", "SetupAppGraph", "AppGraphBuilder"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getTimeStr,
3
3
  randomQueueDxn
4
- } from "./chunk-ZMES3U2D.mjs";
4
+ } from "./chunk-GHTRJTEB.mjs";
5
5
  import {
6
6
  TranscriptType,
7
7
  TranscriptionAction
@@ -29,4 +29,4 @@ var intent_resolver_default = (context) => contributes(Capabilities.IntentResolv
29
29
  export {
30
30
  intent_resolver_default as default
31
31
  };
32
- //# sourceMappingURL=intent-resolver-EAR2TFK2.mjs.map
32
+ //# sourceMappingURL=intent-resolver-RW6DEJC2.mjs.map