@dxos/plugin-transcription 0.8.0 → 0.8.1-main.013e445

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 (152) hide show
  1. package/dist/lib/browser/{TranscriptContainer-SX6PNFEC.mjs → TranscriptContainer-TJXP6ICP.mjs} +3 -3
  2. package/dist/lib/browser/app-graph-builder-ZIIDYMHP.mjs +39 -0
  3. package/dist/lib/browser/app-graph-builder-ZIIDYMHP.mjs.map +7 -0
  4. package/dist/lib/browser/{chunk-AS364WZZ.mjs → chunk-3NWYXRZS.mjs} +2 -2
  5. package/dist/lib/browser/chunk-MD4NQO6W.mjs +252 -0
  6. package/dist/lib/browser/chunk-MD4NQO6W.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-N3VKF2J3.mjs +415 -0
  8. package/dist/lib/browser/chunk-N3VKF2J3.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-YEVVZZTC.mjs +19 -0
  10. package/dist/lib/browser/chunk-YEVVZZTC.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-QIHUPVQD.mjs → chunk-YRW4MNRE.mjs} +23 -24
  12. package/dist/lib/browser/chunk-YRW4MNRE.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +203 -366
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/intent-resolver-AC6LFBE4.mjs +73 -0
  16. package/dist/lib/browser/intent-resolver-AC6LFBE4.mjs.map +7 -0
  17. package/dist/lib/browser/meta.json +1 -1
  18. package/dist/lib/browser/{react-surface-FOEWLLTZ.mjs → react-surface-OM2EECBI.mjs} +15 -8
  19. package/dist/lib/browser/{react-surface-FOEWLLTZ.mjs.map → react-surface-OM2EECBI.mjs.map} +2 -2
  20. package/dist/lib/browser/types/index.mjs +2 -1
  21. package/dist/lib/node/{TranscriptContainer-HU763SN3.cjs → TranscriptContainer-KNTN76RZ.cjs} +8 -8
  22. package/dist/lib/node/{TranscriptContainer-HU763SN3.cjs.map → TranscriptContainer-KNTN76RZ.cjs.map} +2 -2
  23. package/dist/lib/node/app-graph-builder-CJSNQYJZ.cjs +52 -0
  24. package/dist/lib/node/app-graph-builder-CJSNQYJZ.cjs.map +7 -0
  25. package/dist/lib/node/chunk-EKSRBQX7.cjs +437 -0
  26. package/dist/lib/node/chunk-EKSRBQX7.cjs.map +7 -0
  27. package/dist/lib/node/{chunk-QWXLQPP5.cjs → chunk-I6CUIAQH.cjs} +5 -5
  28. package/dist/lib/node/{app-graph-builder-YFBX3OTP.cjs → chunk-LEHTJHKP.cjs} +23 -7
  29. package/dist/lib/node/chunk-LEHTJHKP.cjs.map +7 -0
  30. package/dist/lib/node/chunk-T4W4AKGM.cjs +279 -0
  31. package/dist/lib/node/chunk-T4W4AKGM.cjs.map +7 -0
  32. package/dist/lib/node/{chunk-UIHEGU6Q.cjs → chunk-ZAE2IOZC.cjs} +25 -27
  33. package/dist/lib/node/chunk-ZAE2IOZC.cjs.map +7 -0
  34. package/dist/lib/node/index.cjs +220 -378
  35. package/dist/lib/node/index.cjs.map +4 -4
  36. package/dist/lib/node/intent-resolver-ZSQ2MHJJ.cjs +84 -0
  37. package/dist/lib/node/intent-resolver-ZSQ2MHJJ.cjs.map +7 -0
  38. package/dist/lib/node/meta.json +1 -1
  39. package/dist/lib/node/{react-surface-AGGGDOUC.cjs → react-surface-ZENSCF6S.cjs} +18 -12
  40. package/dist/lib/node/{react-surface-AGGGDOUC.cjs.map → react-surface-ZENSCF6S.cjs.map} +2 -2
  41. package/dist/lib/node/types/index.cjs +8 -7
  42. package/dist/lib/node/types/index.cjs.map +2 -2
  43. package/dist/lib/node-esm/{TranscriptContainer-DVBXQIQ4.mjs → TranscriptContainer-MOWZQSEO.mjs} +3 -3
  44. package/dist/lib/node-esm/app-graph-builder-ARTLU4U5.mjs +40 -0
  45. package/dist/lib/node-esm/app-graph-builder-ARTLU4U5.mjs.map +7 -0
  46. package/dist/lib/node-esm/chunk-4A6BWPRB.mjs +253 -0
  47. package/dist/lib/node-esm/chunk-4A6BWPRB.mjs.map +7 -0
  48. package/dist/lib/node-esm/{chunk-KEG3ME4O.mjs → chunk-DLXORY7Y.mjs} +22 -24
  49. package/dist/lib/node-esm/chunk-DLXORY7Y.mjs.map +7 -0
  50. package/dist/lib/node-esm/{chunk-WEZGRUG6.mjs → chunk-NFPDIQYG.mjs} +2 -2
  51. package/dist/lib/node-esm/chunk-SB5TLXBU.mjs +21 -0
  52. package/dist/lib/node-esm/chunk-SB5TLXBU.mjs.map +7 -0
  53. package/dist/lib/node-esm/chunk-SWV74BYU.mjs +416 -0
  54. package/dist/lib/node-esm/chunk-SWV74BYU.mjs.map +7 -0
  55. package/dist/lib/node-esm/index.mjs +203 -366
  56. package/dist/lib/node-esm/index.mjs.map +4 -4
  57. package/dist/lib/node-esm/intent-resolver-XU4BLUSF.mjs +74 -0
  58. package/dist/lib/node-esm/intent-resolver-XU4BLUSF.mjs.map +7 -0
  59. package/dist/lib/node-esm/meta.json +1 -1
  60. package/dist/lib/node-esm/{react-surface-6AYPLJ2B.mjs → react-surface-5CBEXLXJ.mjs} +15 -8
  61. package/dist/lib/node-esm/{react-surface-6AYPLJ2B.mjs.map → react-surface-5CBEXLXJ.mjs.map} +2 -2
  62. package/dist/lib/node-esm/types/index.mjs +2 -1
  63. package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
  64. package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -0
  65. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  66. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  67. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  68. package/dist/types/src/components/Transcript/Transcript.d.ts +2 -0
  69. package/dist/types/src/components/Transcript/Transcript.d.ts.map +1 -1
  70. package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +1 -1
  71. package/dist/types/src/components/TranscriptContainer.d.ts +1 -0
  72. package/dist/types/src/components/TranscriptContainer.d.ts.map +1 -1
  73. package/dist/types/src/components/index.d.ts +1 -0
  74. package/dist/types/src/components/index.d.ts.map +1 -1
  75. package/dist/types/src/components/transcription.stories.d.ts +3 -2
  76. package/dist/types/src/components/transcription.stories.d.ts.map +1 -1
  77. package/dist/types/src/hooks/index.d.ts +0 -1
  78. package/dist/types/src/hooks/index.d.ts.map +1 -1
  79. package/dist/types/src/index.d.ts +1 -0
  80. package/dist/types/src/index.d.ts.map +1 -1
  81. package/dist/types/src/meta.d.ts +2 -9
  82. package/dist/types/src/meta.d.ts.map +1 -1
  83. package/dist/types/src/transcriber/index.d.ts +1 -0
  84. package/dist/types/src/transcriber/index.d.ts.map +1 -1
  85. package/dist/types/src/transcriber/media-stream-recorder.d.ts +1 -0
  86. package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
  87. package/dist/types/src/transcriber/summarize.d.ts +5 -0
  88. package/dist/types/src/transcriber/summarize.d.ts.map +1 -0
  89. package/dist/types/src/transcription-manager.d.ts +39 -0
  90. package/dist/types/src/transcription-manager.d.ts.map +1 -0
  91. package/dist/types/src/translations.d.ts +5 -6
  92. package/dist/types/src/translations.d.ts.map +1 -1
  93. package/dist/types/src/types/schema.d.ts +9 -15
  94. package/dist/types/src/types/schema.d.ts.map +1 -1
  95. package/dist/types/src/types/types.d.ts +13 -6
  96. package/dist/types/src/types/types.d.ts.map +1 -1
  97. package/dist/types/src/util/random-queue-dxn.d.ts +2 -2
  98. package/dist/types/src/util/random-queue-dxn.d.ts.map +1 -1
  99. package/package.json +40 -37
  100. package/src/TranscriptionPlugin.tsx +1 -2
  101. package/src/capabilities/app-graph-builder.ts +25 -2
  102. package/src/capabilities/intent-resolver.ts +24 -2
  103. package/src/capabilities/react-surface.tsx +2 -2
  104. package/src/components/Transcript/Transcript.stories.tsx +46 -27
  105. package/src/components/Transcript/Transcript.tsx +205 -49
  106. package/src/components/TranscriptContainer.tsx +12 -147
  107. package/src/components/transcription.stories.tsx +11 -13
  108. package/src/hooks/index.ts +0 -1
  109. package/src/index.ts +1 -0
  110. package/src/meta.ts +2 -2
  111. package/src/transcriber/index.ts +1 -0
  112. package/src/transcriber/media-stream-recorder.ts +4 -0
  113. package/src/transcriber/summarize.ts +77 -0
  114. package/src/transcription-manager.ts +183 -0
  115. package/src/translations.ts +2 -2
  116. package/src/types/schema.ts +5 -3
  117. package/src/types/types.ts +12 -2
  118. package/src/util/random-queue-dxn.ts +2 -2
  119. package/dist/lib/browser/app-graph-builder-ZSSJIFY7.mjs +0 -7
  120. package/dist/lib/browser/app-graph-builder-ZSSJIFY7.mjs.map +0 -7
  121. package/dist/lib/browser/chunk-QIHUPVQD.mjs.map +0 -7
  122. package/dist/lib/browser/chunk-R4HHS6FA.mjs +0 -241
  123. package/dist/lib/browser/chunk-R4HHS6FA.mjs.map +0 -7
  124. package/dist/lib/browser/chunk-ZMES3U2D.mjs +0 -78
  125. package/dist/lib/browser/chunk-ZMES3U2D.mjs.map +0 -7
  126. package/dist/lib/browser/intent-resolver-EAR2TFK2.mjs +0 -32
  127. package/dist/lib/browser/intent-resolver-EAR2TFK2.mjs.map +0 -7
  128. package/dist/lib/node/app-graph-builder-YFBX3OTP.cjs.map +0 -7
  129. package/dist/lib/node/chunk-JBN3P6ZF.cjs +0 -97
  130. package/dist/lib/node/chunk-JBN3P6ZF.cjs.map +0 -7
  131. package/dist/lib/node/chunk-UIHEGU6Q.cjs.map +0 -7
  132. package/dist/lib/node/chunk-YV74Z74I.cjs +0 -267
  133. package/dist/lib/node/chunk-YV74Z74I.cjs.map +0 -7
  134. package/dist/lib/node/intent-resolver-3KJZGGUQ.cjs +0 -44
  135. package/dist/lib/node/intent-resolver-3KJZGGUQ.cjs.map +0 -7
  136. package/dist/lib/node-esm/app-graph-builder-77GQG6UF.mjs +0 -9
  137. package/dist/lib/node-esm/app-graph-builder-77GQG6UF.mjs.map +0 -7
  138. package/dist/lib/node-esm/chunk-36EQXBWR.mjs +0 -242
  139. package/dist/lib/node-esm/chunk-36EQXBWR.mjs.map +0 -7
  140. package/dist/lib/node-esm/chunk-KEG3ME4O.mjs.map +0 -7
  141. package/dist/lib/node-esm/chunk-XYU6B73V.mjs +0 -80
  142. package/dist/lib/node-esm/chunk-XYU6B73V.mjs.map +0 -7
  143. package/dist/lib/node-esm/intent-resolver-UGLYRD4X.mjs +0 -33
  144. package/dist/lib/node-esm/intent-resolver-UGLYRD4X.mjs.map +0 -7
  145. package/dist/types/src/hooks/useIsSpeaking.d.ts +0 -2
  146. package/dist/types/src/hooks/useIsSpeaking.d.ts.map +0 -1
  147. package/src/hooks/useIsSpeaking.ts +0 -77
  148. /package/dist/lib/browser/{TranscriptContainer-SX6PNFEC.mjs.map → TranscriptContainer-TJXP6ICP.mjs.map} +0 -0
  149. /package/dist/lib/browser/{chunk-AS364WZZ.mjs.map → chunk-3NWYXRZS.mjs.map} +0 -0
  150. /package/dist/lib/node/{chunk-QWXLQPP5.cjs.map → chunk-I6CUIAQH.cjs.map} +0 -0
  151. /package/dist/lib/node-esm/{TranscriptContainer-DVBXQIQ4.mjs.map → TranscriptContainer-MOWZQSEO.mjs.map} +0 -0
  152. /package/dist/lib/node-esm/{chunk-WEZGRUG6.mjs.map → chunk-NFPDIQYG.mjs.map} +0 -0
@@ -30,27 +30,29 @@ var node_exports = {};
30
30
  __export(node_exports, {
31
31
  AppGraphBuilder: () => AppGraphBuilder,
32
32
  IntentResolver: () => IntentResolver,
33
- MediaStreamRecorder: () => MediaStreamRecorder,
33
+ MediaStreamRecorder: () => import_chunk_EKSRBQX7.MediaStreamRecorder,
34
34
  ReactSurface: () => ReactSurface,
35
- TRANSCRIPTION_PLUGIN: () => import_chunk_UIHEGU6Q.TRANSCRIPTION_PLUGIN,
36
- Transcriber: () => Transcriber,
37
- Transcript: () => import_chunk_YV74Z74I.Transcript,
38
- TranscriptContainer: () => import_chunk_QWXLQPP5.TranscriptContainer,
35
+ TRANSCRIPTION_PLUGIN: () => import_chunk_LEHTJHKP.TRANSCRIPTION_PLUGIN,
36
+ Transcriber: () => import_chunk_EKSRBQX7.Transcriber,
37
+ Transcript: () => import_chunk_T4W4AKGM.Transcript,
38
+ TranscriptContainer: () => import_chunk_I6CUIAQH.TranscriptContainer,
39
39
  TranscriptionCapabilities: () => TranscriptionCapabilities,
40
- TranscriptionContainer: () => import_chunk_YV74Z74I.TranscriptionContainer,
40
+ TranscriptionContainer: () => import_chunk_T4W4AKGM.TranscriptionContainer,
41
+ TranscriptionManager: () => TranscriptionManager,
41
42
  TranscriptionPlugin: () => TranscriptionPlugin,
42
- meta: () => import_chunk_UIHEGU6Q.meta,
43
+ meta: () => import_chunk_LEHTJHKP.meta,
44
+ summarizeTranscript: () => import_chunk_EKSRBQX7.summarizeTranscript,
43
45
  useAudioFile: () => useAudioFile,
44
46
  useAudioTrack: () => useAudioTrack,
45
- useIsSpeaking: () => useIsSpeaking,
46
47
  useTranscriber: () => useTranscriber,
47
48
  useVoiceInput: () => useVoiceInput
48
49
  });
49
50
  module.exports = __toCommonJS(node_exports);
50
- var import_chunk_JBN3P6ZF = require("./chunk-JBN3P6ZF.cjs");
51
- var import_chunk_QWXLQPP5 = require("./chunk-QWXLQPP5.cjs");
52
- var import_chunk_YV74Z74I = require("./chunk-YV74Z74I.cjs");
53
- var import_chunk_UIHEGU6Q = require("./chunk-UIHEGU6Q.cjs");
51
+ var import_chunk_EKSRBQX7 = require("./chunk-EKSRBQX7.cjs");
52
+ var import_chunk_I6CUIAQH = require("./chunk-I6CUIAQH.cjs");
53
+ var import_chunk_ZAE2IOZC = require("./chunk-ZAE2IOZC.cjs");
54
+ var import_chunk_T4W4AKGM = require("./chunk-T4W4AKGM.cjs");
55
+ var import_chunk_LEHTJHKP = require("./chunk-LEHTJHKP.cjs");
54
56
  var import_app_framework = require("@dxos/app-framework");
55
57
  var import_app_framework2 = require("@dxos/app-framework");
56
58
  var import_react = require("react");
@@ -58,31 +60,25 @@ var import_log = require("@dxos/log");
58
60
  var import_react2 = require("react");
59
61
  var import_react3 = require("react");
60
62
  var import_react4 = require("react");
61
- var import_extendable_media_recorder = require("extendable-media-recorder");
62
- var import_wavefile = require("wavefile");
63
63
  var import_async = require("@dxos/async");
64
- var import_invariant = require("@dxos/invariant");
64
+ var import_context = require("@dxos/context");
65
65
  var import_log2 = require("@dxos/log");
66
- var import_tracing = require("@dxos/tracing");
67
- var import_wavefile2 = require("wavefile");
66
+ var import_react_ui_sfx = require("@dxos/react-ui-sfx");
68
67
  var import_async2 = require("@dxos/async");
69
- var import_context = require("@dxos/context");
70
- var import_log3 = require("@dxos/log");
71
- var import_tracing2 = require("@dxos/tracing");
72
- var import_react5 = require("react");
73
- var import_async3 = require("@dxos/async");
74
68
  var import_context2 = require("@dxos/context");
75
- var import_log4 = require("@dxos/log");
76
- var import_react_ui_sfx = require("@dxos/react-ui-sfx");
69
+ var import_echo_db = require("@dxos/echo-db");
70
+ var import_echo_schema = require("@dxos/echo-schema");
71
+ var import_invariant = require("@dxos/invariant");
72
+ var import_keys = require("@dxos/keys");
77
73
  var import_app_framework3 = require("@dxos/app-framework");
78
74
  var import_plugin_client = require("@dxos/plugin-client");
79
75
  var TranscriptionCapabilities;
80
76
  (function(TranscriptionCapabilities2) {
81
- TranscriptionCapabilities2.Transcription = (0, import_app_framework2.defineCapability)(`${import_chunk_UIHEGU6Q.TRANSCRIPTION_PLUGIN}/capability/transcription`);
77
+ TranscriptionCapabilities2.Transcription = (0, import_app_framework2.defineCapability)(`${import_chunk_LEHTJHKP.TRANSCRIPTION_PLUGIN}/capability/transcription`);
82
78
  })(TranscriptionCapabilities || (TranscriptionCapabilities = {}));
83
- var AppGraphBuilder = (0, import_app_framework.lazy)(() => import("./app-graph-builder-YFBX3OTP.cjs"));
84
- var IntentResolver = (0, import_app_framework.lazy)(() => import("./intent-resolver-3KJZGGUQ.cjs"));
85
- var ReactSurface = (0, import_app_framework.lazy)(() => import("./react-surface-AGGGDOUC.cjs"));
79
+ var AppGraphBuilder = (0, import_app_framework.lazy)(() => import("./app-graph-builder-CJSNQYJZ.cjs"));
80
+ var IntentResolver = (0, import_app_framework.lazy)(() => import("./intent-resolver-ZSQ2MHJJ.cjs"));
81
+ var ReactSurface = (0, import_app_framework.lazy)(() => import("./react-surface-ZENSCF6S.cjs"));
86
82
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-transcription/src/hooks/useAudioFile.ts";
87
83
  var useAudioFile = (audioUrl) => {
88
84
  const [{ audio, stream, track }, setStream] = (0, import_react.useState)({});
@@ -166,333 +162,20 @@ var useAudioTrack = (active) => {
166
162
  ]);
167
163
  return track;
168
164
  };
169
- var useIsSpeaking = (mediaStreamTrack) => {
170
- const [isSpeaking, setIsSpeaking] = (0, import_react3.useState)(false);
171
- const isSpeakingRef = (0, import_react3.useRef)(isSpeaking);
172
- (0, import_react3.useEffect)(() => {
173
- if (!mediaStreamTrack) {
174
- setIsSpeaking(false);
175
- return;
176
- }
177
- isSpeakingRef.current = isSpeaking;
178
- const interval = window.setInterval(() => {
179
- if (isSpeaking === isSpeakingRef.current) {
180
- return;
181
- }
182
- setIsSpeaking(isSpeakingRef.current);
183
- }, 50);
184
- return () => {
185
- clearInterval(interval);
186
- };
187
- }, [
188
- isSpeaking,
189
- isSpeakingRef,
190
- mediaStreamTrack
191
- ]);
192
- (0, import_react3.useEffect)(() => {
193
- if (!mediaStreamTrack) {
194
- return;
195
- }
196
- let timeout = -1;
197
- const cleanup = (0, import_chunk_JBN3P6ZF.monitorAudioLevel)({
198
- mediaStreamTrack,
199
- onMeasure: (vol) => {
200
- const audioLevelAboveThreshold = vol > (isSpeakingRef.current ? 0.02 : 0.05);
201
- if (audioLevelAboveThreshold) {
202
- clearTimeout(timeout);
203
- timeout = -1;
204
- isSpeakingRef.current = true;
205
- } else if (timeout === -1) {
206
- timeout = window.setTimeout(() => {
207
- isSpeakingRef.current = false;
208
- timeout = -1;
209
- }, 1e3);
210
- }
211
- }
212
- });
213
- return () => {
214
- cleanup();
215
- };
216
- }, [
217
- isSpeaking,
218
- mediaStreamTrack
219
- ]);
220
- return isSpeaking;
221
- };
222
- function _ts_decorate(decorators, target, key, desc) {
223
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
224
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
225
- 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;
226
- return c > 3 && r && Object.defineProperty(target, key, r), r;
227
- }
228
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-transcription/src/transcriber/media-stream-recorder.ts";
229
- var initializingPromise;
230
- var initializeExtendableMediaRecorder = async () => {
231
- const { connect } = await import("extendable-media-recorder-wav-encoder");
232
- await (0, import_extendable_media_recorder.register)(await connect());
233
- };
234
- var MediaStreamRecorder = class {
235
- constructor({ mediaStreamTrack, interval }) {
236
- this._mediaRecorder = void 0;
237
- this._header = void 0;
238
- this._mediaStreamTrack = mediaStreamTrack;
239
- this._interval = interval;
240
- }
241
- get wavConfig() {
242
- const settings = this._mediaStreamTrack.getSettings();
243
- return {
244
- channels: settings.channelCount ?? 1,
245
- sampleRate: settings.sampleRate ?? 16e3,
246
- bitDepthCode: settings.sampleSize ? String(settings.sampleSize) : "16"
247
- };
248
- }
249
- setOnChunk(onChunk) {
250
- this._onChunk = onChunk;
251
- }
252
- async start() {
253
- await (initializingPromise ??= initializeExtendableMediaRecorder()).catch((err) => import_log2.log.info("initializeExtendableMediaRecorder", {
254
- err
255
- }, {
256
- F: __dxlog_file2,
257
- L: 58,
258
- S: this,
259
- C: (f, a) => f(...a)
260
- }));
261
- if (!this._mediaRecorder) {
262
- const stream = new MediaStream([
263
- this._mediaStreamTrack
264
- ]);
265
- this._mediaRecorder = new import_extendable_media_recorder.MediaRecorder(stream, {
266
- mimeType: "audio/wav"
267
- });
268
- }
269
- if (this._mediaRecorder.state === "recording") {
270
- return;
271
- }
272
- (0, import_invariant.invariant)(this._onChunk, "MediaStreamRecorder: onChunk is not set", {
273
- F: __dxlog_file2,
274
- L: 69,
275
- S: this,
276
- A: [
277
- "this._onChunk",
278
- "'MediaStreamRecorder: onChunk is not set'"
279
- ]
280
- });
281
- this._mediaRecorder.ondataavailable = (event) => this._ondataavailable(event);
282
- this._mediaRecorder.start(this._interval);
283
- }
284
- async stop() {
285
- if (this._mediaRecorder?.state !== "recording") {
286
- return;
287
- }
288
- this._mediaRecorder.stop();
289
- }
290
- async _ondataavailable(event) {
291
- const blob = event.data;
292
- const uint8Array = new Uint8Array(await blob.arrayBuffer());
293
- const isHeader = uint8Array[0] === 82 && // R
294
- uint8Array[1] === 73 && // I
295
- uint8Array[2] === 70 && // F
296
- uint8Array[3] === 70;
297
- let wav;
298
- if (isHeader) {
299
- wav = new import_wavefile.WaveFile(uint8Array);
300
- this._header = uint8Array.slice(0, 44);
301
- } else if (this._header) {
302
- wav = new import_wavefile.WaveFile(new Uint8Array([
303
- ...this._header,
304
- ...uint8Array
305
- ]));
306
- } else {
307
- import_log2.log.warn("MediaStreamRecorder: no header", void 0, {
308
- F: __dxlog_file2,
309
- L: 100,
310
- S: this,
311
- C: (f, a) => f(...a)
312
- });
313
- return;
314
- }
315
- this._onChunk({
316
- timestamp: Date.now(),
317
- data: wav.getSamples()
318
- });
319
- }
320
- };
321
- _ts_decorate([
322
- import_async.synchronized
323
- ], MediaStreamRecorder.prototype, "_ondataavailable", null);
324
- MediaStreamRecorder = _ts_decorate([
325
- import_tracing.trace.resource()
326
- ], MediaStreamRecorder);
327
- function _ts_decorate2(decorators, target, key, desc) {
328
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
329
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
330
- 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;
331
- return c > 3 && r && Object.defineProperty(target, key, r), r;
332
- }
333
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-transcription/src/transcriber/transcriber.ts";
334
- var Transcriber = class extends import_context.Resource {
335
- constructor({ config, recorder, onSegments }) {
336
- super();
337
- this._audioChunks = [];
338
- this._lastUsedTimestamp = 0;
339
- this._openTrigger = new import_async2.Trigger({
340
- autoReset: true
341
- });
342
- this._recording = false;
343
- this._transcribeTask = void 0;
344
- this._config = config;
345
- this._recorder = recorder;
346
- this._onSegments = onSegments;
347
- }
348
- async _open(ctx) {
349
- this._recorder.setOnChunk((chunk) => this._saveAudioChunk(chunk));
350
- await this._recorder.start();
351
- this._transcribeTask = new import_async2.DeferredTask(ctx, async () => this._transcribe());
352
- this._openTrigger.wake();
353
- }
354
- async _close() {
355
- this._recording = false;
356
- this._transcribeTask = void 0;
357
- await this._recorder.stop();
358
- }
359
- startChunksRecording() {
360
- if (this._lifecycleState !== import_context.LifecycleState.OPEN) {
361
- return;
362
- }
363
- this._recording = true;
364
- }
365
- stopChunksRecording() {
366
- if (this._lifecycleState !== import_context.LifecycleState.OPEN || !this._recording) {
367
- return;
368
- }
369
- this._recording = false;
370
- this._transcribeTask?.schedule();
371
- }
372
- _saveAudioChunk(chunk) {
373
- (0, import_log3.log)("saving audio chunk", {
374
- chunk
375
- }, {
376
- F: __dxlog_file3,
377
- L: 124,
378
- S: this,
379
- C: (f, a) => f(...a)
380
- });
381
- this._audioChunks.push(chunk);
382
- if (!this._recording && (!this._transcribeTask || !this._transcribeTask.scheduled) && this._audioChunks.length >= this._config.prefixBufferChunksAmount) {
383
- this._audioChunks = this._dropOldChunks();
384
- } else if (this._audioChunks.length >= this._config.transcribeAfterChunksAmount && this._recording) {
385
- this._transcribeTask?.schedule();
386
- }
387
- }
388
- async _transcribe() {
389
- (0, import_log3.log)("transcribing", {
390
- chunks: this._audioChunks.length
391
- }, {
392
- F: __dxlog_file3,
393
- L: 140,
394
- S: this,
395
- C: (f, a) => f(...a)
396
- });
397
- const chunks = this._audioChunks;
398
- this._audioChunks = this._dropOldChunks();
399
- if (chunks.length === 0) {
400
- return;
401
- }
402
- const audio = await this._mergeAudioChunks(chunks);
403
- const segments = await this._fetchTranscription(audio);
404
- if (!Array.isArray(segments) || segments.length === 0) {
405
- return;
406
- }
407
- const alignedSegments = this._alignSegments(segments, chunks);
408
- if (alignedSegments.length > 0) {
409
- await this._onSegments(alignedSegments);
410
- }
411
- }
412
- _dropOldChunks() {
413
- return this._config.prefixBufferChunksAmount > 0 ? this._audioChunks.slice(-this._config.prefixBufferChunksAmount) : [];
414
- }
415
- async _mergeAudioChunks(chunks) {
416
- const file = new import_wavefile2.WaveFile();
417
- const wavConfig = this._recorder.wavConfig;
418
- file.fromScratch(wavConfig.channels, wavConfig.sampleRate, wavConfig.bitDepthCode, (0, import_chunk_JBN3P6ZF.mergeFloat64Arrays)(chunks.map(({ data }) => data)));
419
- return file.toBase64();
420
- }
421
- async _fetchTranscription(audio) {
422
- if (audio.length === 0) {
423
- this._audioChunks = [];
424
- throw new Error("No audio to send for transcribing");
425
- }
426
- const response = await fetch(`${import_chunk_UIHEGU6Q.TRANSCRIPTION_URL}/transcribe`, {
427
- method: "POST",
428
- body: JSON.stringify({
429
- audio
430
- }),
431
- headers: {
432
- "Content-Type": "application/json"
433
- }
434
- });
435
- if (!response.ok) {
436
- this._audioChunks = [];
437
- throw new Error("Failed to transcribe");
438
- }
439
- const { segments } = await response.json();
440
- import_log3.log.info("transcription response", {
441
- segments,
442
- string: segments.map((segments2) => segments2.text).join(" ")
443
- }, {
444
- F: __dxlog_file3,
445
- L: 206,
446
- S: this,
447
- C: (f, a) => f(...a)
448
- });
449
- return segments;
450
- }
451
- _alignSegments(segments, originalChunks) {
452
- const zeroTimestamp = originalChunks.at(0).timestamp;
453
- const filteredSegments = segments.filter((segment) => zeroTimestamp + segment.end * 1e3 >= this._lastUsedTimestamp).map((segment) => {
454
- const words = segment.words.filter((word) => zeroTimestamp + word.start * 1e3 >= this._lastUsedTimestamp);
455
- return {
456
- ...segment,
457
- words,
458
- text: words.map((word) => word.word).join(""),
459
- start: words.at(0)?.start ?? segment.end
460
- };
461
- }).filter((segment) => segment.words.length > 0);
462
- if (filteredSegments.length === 0) {
463
- return [];
464
- }
465
- this._lastUsedTimestamp = zeroTimestamp + filteredSegments.at(-1).end * 1e3;
466
- return filteredSegments.map((segment) => ({
467
- started: new Date(zeroTimestamp + segment.start * 1e3),
468
- text: segment.text
469
- }));
470
- }
471
- };
472
- _ts_decorate2([
473
- import_tracing2.trace.span({
474
- showInBrowserTimeline: true
475
- })
476
- ], Transcriber.prototype, "_mergeAudioChunks", null);
477
- _ts_decorate2([
478
- import_tracing2.trace.span({
479
- showInBrowserTimeline: true
480
- })
481
- ], Transcriber.prototype, "_fetchTranscription", null);
482
165
  var RECORD_INTERVAL = 200;
483
166
  var PREFIXED_CHUNKS_AMOUNT = 10;
484
167
  var TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;
485
168
  var useTranscriber = ({ audioStreamTrack, onSegments }) => {
486
- const transcriber = (0, import_react4.useMemo)(() => {
169
+ const transcriber = (0, import_react3.useMemo)(() => {
487
170
  if (!onSegments || !audioStreamTrack) {
488
171
  return void 0;
489
172
  }
490
- return new Transcriber({
173
+ return new import_chunk_EKSRBQX7.Transcriber({
491
174
  config: {
492
175
  transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT,
493
176
  prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT
494
177
  },
495
- recorder: new MediaStreamRecorder({
178
+ recorder: new import_chunk_EKSRBQX7.MediaStreamRecorder({
496
179
  mediaStreamTrack: audioStreamTrack,
497
180
  interval: RECORD_INTERVAL
498
181
  }),
@@ -502,7 +185,7 @@ var useTranscriber = ({ audioStreamTrack, onSegments }) => {
502
185
  audioStreamTrack,
503
186
  onSegments
504
187
  ]);
505
- (0, import_react4.useEffect)(() => {
188
+ (0, import_react3.useEffect)(() => {
506
189
  return () => {
507
190
  void transcriber?.close();
508
191
  };
@@ -511,30 +194,30 @@ var useTranscriber = ({ audioStreamTrack, onSegments }) => {
511
194
  ]);
512
195
  return transcriber;
513
196
  };
514
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-transcription/src/hooks/useVoiceInput.ts";
197
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-transcription/src/hooks/useVoiceInput.ts";
515
198
  var useVoiceInput = ({ active, onUpdate }) => {
516
199
  const soundStart = (0, import_react_ui_sfx.useSoundEffect)("StartRecording");
517
200
  const soundStop = (0, import_react_ui_sfx.useSoundEffect)("StopRecording");
518
- const handleSegments = (0, import_react5.useCallback)(async (segments) => {
201
+ const handleSegments = (0, import_react4.useCallback)(async (segments) => {
519
202
  const text = segments.map((str) => str.text.trim().replace(/[^\w\s]/g, "")).join(" ");
520
203
  onUpdate(text);
521
204
  }, []);
522
- const [recording, setRecording] = (0, import_react5.useState)(false);
205
+ const [recording, setRecording] = (0, import_react4.useState)(false);
523
206
  const track = useAudioTrack(active);
524
207
  const transcriber = useTranscriber({
525
208
  audioStreamTrack: track,
526
209
  onSegments: handleSegments
527
210
  });
528
- (0, import_react5.useEffect)(() => {
529
- const ctx = new import_context2.Context(void 0, {
530
- F: __dxlog_file4,
211
+ (0, import_react4.useEffect)(() => {
212
+ const ctx = new import_context.Context(void 0, {
213
+ F: __dxlog_file2,
531
214
  L: 43
532
215
  });
533
- (0, import_async3.scheduleMicroTask)(ctx, async () => {
216
+ (0, import_async.scheduleMicroTask)(ctx, async () => {
534
217
  if (active && transcriber) {
535
218
  await transcriber.open();
536
- import_log4.log.info("starting...", void 0, {
537
- F: __dxlog_file4,
219
+ import_log2.log.info("starting...", void 0, {
220
+ F: __dxlog_file2,
538
221
  L: 47,
539
222
  S: void 0,
540
223
  C: (f, a) => f(...a)
@@ -545,8 +228,8 @@ var useVoiceInput = ({ active, onUpdate }) => {
545
228
  } else if (!active && transcriber?.isOpen) {
546
229
  transcriber?.stopChunksRecording();
547
230
  await transcriber?.close();
548
- import_log4.log.info("stopped", void 0, {
549
- F: __dxlog_file4,
231
+ import_log2.log.info("stopped", void 0, {
232
+ F: __dxlog_file2,
550
233
  L: 54,
551
234
  S: void 0,
552
235
  C: (f, a) => f(...a)
@@ -566,13 +249,178 @@ var useVoiceInput = ({ active, onUpdate }) => {
566
249
  recording
567
250
  };
568
251
  };
252
+ function _ts_decorate(decorators, target, key, desc) {
253
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
254
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
255
+ 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;
256
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
257
+ }
258
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-transcription/src/transcription-manager.ts";
259
+ var RECORD_INTERVAL2 = 200;
260
+ var PREFIXED_CHUNKS_AMOUNT2 = 10;
261
+ var TRANSCRIBE_AFTER_CHUNKS_AMOUNT2 = 50;
262
+ var TranscriptionManager = class extends import_context2.Resource {
263
+ constructor(edgeClient) {
264
+ super();
265
+ this._audioStreamTrack = void 0;
266
+ this._name = void 0;
267
+ this._hue = void 0;
268
+ this._mediaRecorder = void 0;
269
+ this._transcriber = void 0;
270
+ this._enabled = false;
271
+ this._queue = void 0;
272
+ this._edgeClient = edgeClient;
273
+ }
274
+ async _open() {
275
+ await this._toggleTranscriber();
276
+ }
277
+ async _close() {
278
+ void this._transcriber?.close();
279
+ }
280
+ setRecording(recording) {
281
+ if (!this.isOpen || !this._enabled) {
282
+ return;
283
+ }
284
+ if (recording) {
285
+ this._transcriber?.startChunksRecording();
286
+ } else {
287
+ this._transcriber?.stopChunksRecording();
288
+ }
289
+ }
290
+ /**
291
+ * Enable or disable transcription.
292
+ * @param enabled - Whether to enable transcription.
293
+ */
294
+ async setEnabled(enabled) {
295
+ if (this._enabled === enabled) {
296
+ return;
297
+ }
298
+ this._enabled = enabled ?? false;
299
+ this.isOpen && await this._toggleTranscriber();
300
+ }
301
+ async setAudioTrack(track) {
302
+ if (this._audioStreamTrack === track) {
303
+ return;
304
+ }
305
+ this._audioStreamTrack = track;
306
+ this.isOpen && await this._toggleTranscriber();
307
+ }
308
+ /**
309
+ * Set the queue to save the transcription to.
310
+ * @param queue - The queue to save the transcription to or the DXN of the queue.
311
+ */
312
+ setQueue(queue) {
313
+ switch (typeof queue) {
314
+ case "string":
315
+ if (this._queue?.dxn.toString() === queue) {
316
+ return;
317
+ }
318
+ this._queue = new import_echo_db.QueueImpl(this._edgeClient, import_keys.DXN.parse(queue));
319
+ break;
320
+ case "object":
321
+ if (this._queue === queue) {
322
+ return;
323
+ }
324
+ (0, import_invariant.invariant)(queue instanceof import_echo_db.QueueImpl, void 0, {
325
+ F: __dxlog_file3,
326
+ L: 112,
327
+ S: this,
328
+ A: [
329
+ "queue instanceof QueueImpl",
330
+ ""
331
+ ]
332
+ });
333
+ this._queue = queue;
334
+ break;
335
+ case "undefined":
336
+ this._queue = void 0;
337
+ break;
338
+ }
339
+ }
340
+ setName(name) {
341
+ if (this._name === name) {
342
+ return;
343
+ }
344
+ this._name = name;
345
+ }
346
+ setHue(hue) {
347
+ if (this._hue === hue) {
348
+ return;
349
+ }
350
+ this._hue = hue;
351
+ }
352
+ async _toggleTranscriber() {
353
+ await this._maybeReinitTranscriber();
354
+ if (this._enabled) {
355
+ await this._transcriber?.open();
356
+ } else {
357
+ await this._transcriber?.close();
358
+ }
359
+ }
360
+ async _maybeReinitTranscriber() {
361
+ if (!this._audioStreamTrack || !this._enabled) {
362
+ return;
363
+ }
364
+ let needReinit = false;
365
+ if (this._audioStreamTrack !== this._mediaRecorder?.mediaStreamTrack) {
366
+ this._mediaRecorder = new import_chunk_EKSRBQX7.MediaStreamRecorder({
367
+ mediaStreamTrack: this._audioStreamTrack,
368
+ interval: RECORD_INTERVAL2
369
+ });
370
+ needReinit = true;
371
+ }
372
+ if (needReinit) {
373
+ await this._transcriber?.close();
374
+ this._transcriber = new import_chunk_EKSRBQX7.Transcriber({
375
+ config: {
376
+ transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT2,
377
+ prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT2
378
+ },
379
+ recorder: this._mediaRecorder,
380
+ onSegments: (segments) => this._onSegments(segments)
381
+ });
382
+ }
383
+ }
384
+ async _onSegments(segments) {
385
+ if (!this.isOpen || !this._queue) {
386
+ return;
387
+ }
388
+ const block = (0, import_echo_schema.createStatic)(import_chunk_ZAE2IOZC.TranscriptBlock, {
389
+ authorName: this._name,
390
+ authorHue: this._hue,
391
+ segments
392
+ });
393
+ this._queue.append([
394
+ block
395
+ ]);
396
+ }
397
+ };
398
+ _ts_decorate([
399
+ import_async2.synchronized
400
+ ], TranscriptionManager.prototype, "setRecording", null);
401
+ _ts_decorate([
402
+ import_async2.synchronized
403
+ ], TranscriptionManager.prototype, "setEnabled", null);
404
+ _ts_decorate([
405
+ import_async2.synchronized
406
+ ], TranscriptionManager.prototype, "setAudioTrack", null);
407
+ _ts_decorate([
408
+ import_async2.synchronized
409
+ ], TranscriptionManager.prototype, "setQueue", null);
410
+ _ts_decorate([
411
+ import_async2.synchronized
412
+ ], TranscriptionManager.prototype, "setName", null);
413
+ _ts_decorate([
414
+ import_async2.synchronized
415
+ ], TranscriptionManager.prototype, "setHue", null);
569
416
  var translations_default = [
570
417
  {
571
418
  "en-US": {
572
- [import_chunk_UIHEGU6Q.TranscriptType.typename]: {
573
- "typename label": "Transcript"
419
+ [import_chunk_ZAE2IOZC.TranscriptType.typename]: {
420
+ "typename label": "Transcript",
421
+ "object name placeholder": "New transcript"
574
422
  },
575
- [import_chunk_UIHEGU6Q.TRANSCRIPTION_PLUGIN]: {
423
+ [import_chunk_LEHTJHKP.TRANSCRIPTION_PLUGIN]: {
576
424
  "plugin name": "Transcription",
577
425
  "calls label": "Transcript",
578
426
  "calls panel label": "Transcription",
@@ -580,60 +428,53 @@ var translations_default = [
580
428
  "delete calls label": "Delete",
581
429
  "delete button": "Delete",
582
430
  "bookmark button": "Bookmark",
583
- "summary button": "Create summary",
584
- "summarizing label": "Summarizing..."
431
+ "scroll to end label": "Scroll to latest"
585
432
  }
586
433
  }
587
434
  }
588
435
  ];
589
- var TranscriptionPlugin = () => (0, import_app_framework3.definePlugin)(import_chunk_UIHEGU6Q.meta, [
436
+ var TranscriptionPlugin = () => (0, import_app_framework3.definePlugin)(import_chunk_LEHTJHKP.meta, [
590
437
  (0, import_app_framework3.defineModule)({
591
- id: `${import_chunk_UIHEGU6Q.meta.id}/module/translations`,
438
+ id: `${import_chunk_LEHTJHKP.meta.id}/module/translations`,
592
439
  activatesOn: import_app_framework3.Events.SetupTranslations,
593
440
  activate: () => (0, import_app_framework3.contributes)(import_app_framework3.Capabilities.Translations, translations_default)
594
441
  }),
595
442
  (0, import_app_framework3.defineModule)({
596
- id: `${import_chunk_UIHEGU6Q.meta.id}/module/transcription`,
443
+ id: `${import_chunk_LEHTJHKP.meta.id}/module/transcription`,
597
444
  activatesOn: import_app_framework3.Events.Startup,
598
445
  activate: () => (0, import_app_framework3.contributes)(TranscriptionCapabilities.Transcription, null)
599
446
  }),
600
447
  (0, import_app_framework3.defineModule)({
601
- id: `${import_chunk_UIHEGU6Q.meta.id}/module/metadata`,
448
+ id: `${import_chunk_LEHTJHKP.meta.id}/module/metadata`,
602
449
  activatesOn: import_app_framework3.Events.SetupMetadata,
603
450
  activate: () => (0, import_app_framework3.contributes)(import_app_framework3.Capabilities.Metadata, {
604
- id: import_chunk_UIHEGU6Q.TranscriptType.typename,
451
+ id: import_chunk_ZAE2IOZC.TranscriptType.typename,
605
452
  metadata: {
606
- placeholder: [
607
- "transcript title placeholder",
608
- {
609
- ns: import_chunk_UIHEGU6Q.TRANSCRIPTION_PLUGIN
610
- }
611
- ],
612
453
  icon: "ph--subtitles--regular"
613
454
  }
614
455
  })
615
456
  }),
616
457
  (0, import_app_framework3.defineModule)({
617
- id: `${import_chunk_UIHEGU6Q.meta.id}/module/schema`,
458
+ id: `${import_chunk_LEHTJHKP.meta.id}/module/schema`,
618
459
  activatesOn: import_plugin_client.ClientEvents.SetupSchema,
619
460
  activate: () => [
620
461
  (0, import_app_framework3.contributes)(import_plugin_client.ClientCapabilities.Schema, [
621
- import_chunk_UIHEGU6Q.TranscriptType
462
+ import_chunk_ZAE2IOZC.TranscriptType
622
463
  ])
623
464
  ]
624
465
  }),
625
466
  (0, import_app_framework3.defineModule)({
626
- id: `${import_chunk_UIHEGU6Q.meta.id}/module/react-surface`,
467
+ id: `${import_chunk_LEHTJHKP.meta.id}/module/react-surface`,
627
468
  activatesOn: import_app_framework3.Events.SetupReactSurface,
628
469
  activate: ReactSurface
629
470
  }),
630
471
  (0, import_app_framework3.defineModule)({
631
- id: `${import_chunk_UIHEGU6Q.meta.id}/module/intent-resolver`,
472
+ id: `${import_chunk_LEHTJHKP.meta.id}/module/intent-resolver`,
632
473
  activatesOn: import_app_framework3.Events.SetupIntentResolver,
633
474
  activate: IntentResolver
634
475
  }),
635
476
  (0, import_app_framework3.defineModule)({
636
- id: `${import_chunk_UIHEGU6Q.meta.id}/module/app-graph-builder`,
477
+ id: `${import_chunk_LEHTJHKP.meta.id}/module/app-graph-builder`,
637
478
  activatesOn: import_app_framework3.Events.SetupAppGraph,
638
479
  activate: AppGraphBuilder
639
480
  })
@@ -650,11 +491,12 @@ var TranscriptionPlugin = () => (0, import_app_framework3.definePlugin)(import_c
650
491
  TranscriptContainer,
651
492
  TranscriptionCapabilities,
652
493
  TranscriptionContainer,
494
+ TranscriptionManager,
653
495
  TranscriptionPlugin,
654
496
  meta,
497
+ summarizeTranscript,
655
498
  useAudioFile,
656
499
  useAudioTrack,
657
- useIsSpeaking,
658
500
  useTranscriber,
659
501
  useVoiceInput
660
502
  });