@epicbagel/saas-kit 1.7.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -1
- package/THIRD_PARTY_NOTICES.md +14 -0
- package/dist/chunk-2BSFYU22.cjs +71 -0
- package/dist/chunk-5OF6D3GH.js +158 -0
- package/dist/chunk-7QTFYEPE.cjs +153 -0
- package/dist/{chunk-GTVSRRE3.cjs → chunk-BGCNGYPL.cjs} +2 -2
- package/dist/{chunk-QTWJQQDH.cjs → chunk-FBVZRRA4.cjs} +6 -6
- package/dist/chunk-GJ7S3L6R.js +71 -0
- package/dist/chunk-HLAHOVEI.js +412 -0
- package/dist/{chunk-F3B4M6DU.js → chunk-HTPPNW74.js} +1 -1
- package/dist/chunk-KQBXAQAY.cjs +221 -0
- package/dist/{chunk-JN6JOSZG.js → chunk-LQPJGZIE.js} +7 -7
- package/dist/chunk-NKWHDI4C.cjs +158 -0
- package/dist/chunk-T3XMHWYV.js +221 -0
- package/dist/chunk-UOVA4YKW.js +153 -0
- package/dist/chunk-ZZ7ICQR2.cjs +412 -0
- package/dist/hooks/use-agent-audio-visualizer-bar.cjs +8 -0
- package/dist/hooks/use-agent-audio-visualizer-bar.d.cts +4 -0
- package/dist/hooks/use-agent-audio-visualizer-bar.d.ts +4 -0
- package/dist/hooks/use-agent-audio-visualizer-bar.js +8 -0
- package/dist/hooks/use-dictation.cjs +10 -0
- package/dist/hooks/use-dictation.d.cts +61 -0
- package/dist/hooks/use-dictation.d.ts +61 -0
- package/dist/hooks/use-dictation.js +10 -0
- package/dist/primitives/activity-feed.cjs +3 -3
- package/dist/primitives/activity-feed.js +4 -4
- package/dist/primitives/agent-audio-visualizer-bar.cjs +16 -0
- package/dist/primitives/agent-audio-visualizer-bar.d.cts +75 -0
- package/dist/primitives/agent-audio-visualizer-bar.d.ts +75 -0
- package/dist/primitives/agent-audio-visualizer-bar.js +16 -0
- package/dist/primitives/alert.d.cts +1 -1
- package/dist/primitives/alert.d.ts +1 -1
- package/dist/primitives/archive-confirmation-dialog.cjs +2 -2
- package/dist/primitives/archive-confirmation-dialog.js +3 -3
- package/dist/primitives/attachment.d.cts +1 -1
- package/dist/primitives/attachment.d.ts +1 -1
- package/dist/primitives/badge.d.cts +1 -1
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/board-view.cjs +6 -6
- package/dist/primitives/board-view.js +5 -5
- package/dist/primitives/bubble.d.cts +1 -1
- package/dist/primitives/bubble.d.ts +1 -1
- package/dist/primitives/button.d.cts +2 -2
- package/dist/primitives/button.d.ts +2 -2
- package/dist/primitives/chat.cjs +59 -28
- package/dist/primitives/chat.d.cts +8 -3
- package/dist/primitives/chat.d.ts +8 -3
- package/dist/primitives/chat.js +56 -25
- package/dist/primitives/code-block.cjs +4 -4
- package/dist/primitives/code-block.js +3 -3
- package/dist/primitives/connection.cjs +6 -6
- package/dist/primitives/connection.js +7 -7
- package/dist/primitives/copy-button.cjs +3 -3
- package/dist/primitives/copy-button.js +2 -2
- package/dist/primitives/dictation-provider.cjs +8 -0
- package/dist/primitives/dictation-provider.d.cts +2 -0
- package/dist/primitives/dictation-provider.d.ts +2 -0
- package/dist/primitives/dictation-provider.js +8 -0
- package/dist/primitives/editable-list.cjs +1 -1
- package/dist/primitives/editable-list.js +1 -1
- package/dist/primitives/file-dropzone.cjs +3 -3
- package/dist/primitives/file-dropzone.js +2 -2
- package/dist/primitives/file-preview.cjs +6 -6
- package/dist/primitives/file-preview.js +5 -5
- package/dist/primitives/filter-bar.cjs +4 -4
- package/dist/primitives/filter-bar.js +3 -3
- package/dist/primitives/input-group.d.cts +1 -1
- package/dist/primitives/input-group.d.ts +1 -1
- package/dist/primitives/item.d.cts +2 -2
- package/dist/primitives/item.d.ts +2 -2
- package/dist/primitives/resource-list.cjs +6 -6
- package/dist/primitives/resource-list.js +5 -5
- package/dist/primitives/section-header.d.cts +1 -1
- package/dist/primitives/section-header.d.ts +1 -1
- package/dist/primitives/section.cjs +2 -2
- package/dist/primitives/section.js +3 -3
- package/dist/primitives/sheet.d.cts +1 -1
- package/dist/primitives/sheet.d.ts +1 -1
- package/dist/primitives/switch-field.cjs +2 -2
- package/dist/primitives/switch-field.js +3 -3
- package/dist/primitives/theme-selector.cjs +3 -3
- package/dist/primitives/theme-selector.js +4 -4
- package/dist/primitives/toggle-group.d.cts +2 -2
- package/dist/primitives/toggle-group.d.ts +2 -2
- package/dist/primitives/toggle.d.cts +2 -2
- package/dist/primitives/toggle.d.ts +2 -2
- package/dist/primitives/voice-dictation-button.cjs +5 -2
- package/dist/primitives/voice-dictation-button.d.cts +5 -9
- package/dist/primitives/voice-dictation-button.d.ts +5 -9
- package/dist/primitives/voice-dictation-button.js +4 -1
- package/dist/primitives/voice-session-controls.cjs +12 -0
- package/dist/primitives/voice-session-controls.d.cts +31 -0
- package/dist/primitives/voice-session-controls.d.ts +31 -0
- package/dist/primitives/voice-session-controls.js +12 -0
- package/package.json +51 -1
- package/dist/chunk-LKPM6DQP.cjs +0 -244
- package/dist/chunk-TI57GAQP.js +0 -244
- package/dist/{chunk-HREEZUKL.js → chunk-DILYV4FI.js} +3 -3
- package/dist/{chunk-MU4F3DSW.cjs → chunk-FARCLWLU.cjs} +2 -2
- package/dist/{chunk-CRTH5GJ5.cjs → chunk-MW67PHAQ.cjs} +3 -3
- package/dist/{chunk-KNKV25WS.js → chunk-UFFHGKI7.js} +3 -3
- package/dist/{chunk-HBRVOGLA.js → chunk-WHDHUYS6.js} +3 -3
- package/dist/{chunk-Z3JJSNR5.cjs → chunk-ZLEM2SAU.cjs} +2 -2
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
|
|
2
|
+
|
|
3
|
+
// src/hooks/use-dictation.ts
|
|
4
|
+
var _react = require('react');
|
|
5
|
+
var DictationContext = _react.createContext.call(void 0, null);
|
|
6
|
+
function DictationProvider({ transcribe, scopeKey, children }) {
|
|
7
|
+
const scope = _react.useRef.call(void 0, { key: scopeKey, generation: 0 });
|
|
8
|
+
if (scope.current.key !== scopeKey) scope.current = { key: scopeKey, generation: scope.current.generation + 1 };
|
|
9
|
+
const generation = scope.current.generation;
|
|
10
|
+
const value = _react.useMemo.call(void 0, () => ({ transcribe, scope, generation }), [transcribe, generation]);
|
|
11
|
+
return _react.createElement.call(void 0, DictationContext.Provider, { value }, children);
|
|
12
|
+
}
|
|
13
|
+
var EMPTY = { state: "idle", transcript: "", interimTranscript: "", error: null, canRetry: false };
|
|
14
|
+
var MIME_TYPES = ["audio/webm;codecs=opus", "audio/mp4", "audio/ogg;codecs=opus", "audio/webm"];
|
|
15
|
+
var SILENCE = [];
|
|
16
|
+
function createAudioLevels() {
|
|
17
|
+
let bands = SILENCE;
|
|
18
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
19
|
+
return {
|
|
20
|
+
subscribe: (listener) => {
|
|
21
|
+
listeners.add(listener);
|
|
22
|
+
return () => {
|
|
23
|
+
listeners.delete(listener);
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
getSnapshot: () => bands,
|
|
27
|
+
update: (next) => {
|
|
28
|
+
if (next.length === bands.length && next.every((value, index) => value === bands[index])) return;
|
|
29
|
+
bands = next;
|
|
30
|
+
listeners.forEach((listener) => listener());
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function meterStream(stream, levels, active) {
|
|
35
|
+
let context;
|
|
36
|
+
let source;
|
|
37
|
+
let analyser;
|
|
38
|
+
let frame;
|
|
39
|
+
let stopped = false;
|
|
40
|
+
const stop = () => {
|
|
41
|
+
if (stopped) return;
|
|
42
|
+
stopped = true;
|
|
43
|
+
if (frame !== void 0) cancelAnimationFrame(frame);
|
|
44
|
+
try {
|
|
45
|
+
_optionalChain([source, 'optionalAccess', _2 => _2.disconnect, 'call', _3 => _3()]);
|
|
46
|
+
} catch (e) {
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
_optionalChain([analyser, 'optionalAccess', _4 => _4.disconnect, 'call', _5 => _5()]);
|
|
50
|
+
} catch (e2) {
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
void _optionalChain([context, 'optionalAccess', _6 => _6.close, 'call', _7 => _7(), 'access', _8 => _8.catch, 'call', _9 => _9(() => {
|
|
54
|
+
})]);
|
|
55
|
+
} catch (e3) {
|
|
56
|
+
}
|
|
57
|
+
levels.update(SILENCE);
|
|
58
|
+
};
|
|
59
|
+
try {
|
|
60
|
+
const Constructor = _nullishCoalesce(window.AudioContext, () => ( window.webkitAudioContext));
|
|
61
|
+
if (!Constructor || typeof requestAnimationFrame !== "function") return stop;
|
|
62
|
+
context = new Constructor();
|
|
63
|
+
source = context.createMediaStreamSource(stream);
|
|
64
|
+
analyser = context.createAnalyser();
|
|
65
|
+
analyser.fftSize = 512;
|
|
66
|
+
analyser.smoothingTimeConstant = 0.7;
|
|
67
|
+
source.connect(analyser);
|
|
68
|
+
const bins = new Uint8Array(analyser.frequencyBinCount);
|
|
69
|
+
const binWidth = context.sampleRate / analyser.fftSize;
|
|
70
|
+
const highest = Math.min(8e3, context.sampleRate / 2);
|
|
71
|
+
let sampledAt = -Infinity;
|
|
72
|
+
const sample = (time) => {
|
|
73
|
+
if (stopped) return;
|
|
74
|
+
if (!active()) {
|
|
75
|
+
stop();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
if (time - sampledAt >= 40) {
|
|
80
|
+
sampledAt = time;
|
|
81
|
+
analyser.getByteFrequencyData(bins);
|
|
82
|
+
const bands = Array.from({ length: 24 }, (_, index) => {
|
|
83
|
+
const from = Math.min(bins.length - 1, Math.floor(80 * (highest / 80) ** (index / 24) / binWidth));
|
|
84
|
+
const to = Math.min(bins.length, Math.max(from + 1, Math.ceil(80 * (highest / 80) ** ((index + 1) / 24) / binWidth)));
|
|
85
|
+
let total = 0;
|
|
86
|
+
for (let bin = from; bin < to; bin++) total += bins[bin];
|
|
87
|
+
return Math.round(total / (to - from) / 255 * 1e3) / 1e3;
|
|
88
|
+
});
|
|
89
|
+
levels.update(bands);
|
|
90
|
+
}
|
|
91
|
+
frame = requestAnimationFrame(sample);
|
|
92
|
+
} catch (e4) {
|
|
93
|
+
stop();
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
if (context.state === "suspended") void context.resume().catch(stop);
|
|
97
|
+
frame = requestAnimationFrame(sample);
|
|
98
|
+
} catch (e5) {
|
|
99
|
+
stop();
|
|
100
|
+
}
|
|
101
|
+
return stop;
|
|
102
|
+
}
|
|
103
|
+
function recognitionConstructor() {
|
|
104
|
+
if (typeof window === "undefined") return void 0;
|
|
105
|
+
const speech = window;
|
|
106
|
+
return _nullishCoalesce(speech.SpeechRecognition, () => ( speech.webkitSpeechRecognition));
|
|
107
|
+
}
|
|
108
|
+
function microphoneError(reason) {
|
|
109
|
+
const name = _optionalChain([reason, 'optionalAccess', _10 => _10.name]);
|
|
110
|
+
if (name === "NotAllowedError" || name === "SecurityError") return "Microphone access is blocked. Allow it in your browser and try again.";
|
|
111
|
+
if (name === "NotFoundError" || name === "NotReadableError") return "The microphone is unavailable. Check your microphone and try again.";
|
|
112
|
+
return "Recording could not start. Check your microphone and try again.";
|
|
113
|
+
}
|
|
114
|
+
function recognitionError(code) {
|
|
115
|
+
if (code === "not-allowed" || code === "service-not-allowed") return microphoneError({ name: "NotAllowedError" });
|
|
116
|
+
if (code === "audio-capture") return microphoneError({ name: "NotFoundError" });
|
|
117
|
+
if (code === "no-speech") return "No speech was detected. Try again.";
|
|
118
|
+
return "Speech recognition stopped. Try again.";
|
|
119
|
+
}
|
|
120
|
+
function releaseMeter(session) {
|
|
121
|
+
_optionalChain([session, 'access', _11 => _11.stopMeter, 'optionalCall', _12 => _12()]);
|
|
122
|
+
session.stopMeter = void 0;
|
|
123
|
+
}
|
|
124
|
+
function releaseTracks(session) {
|
|
125
|
+
releaseMeter(session);
|
|
126
|
+
_optionalChain([session, 'access', _13 => _13.stream, 'optionalAccess', _14 => _14.getTracks, 'call', _15 => _15(), 'access', _16 => _16.forEach, 'call', _17 => _17((track) => track.stop())]);
|
|
127
|
+
session.stream = void 0;
|
|
128
|
+
}
|
|
129
|
+
function dispose(session) {
|
|
130
|
+
session.controller.abort();
|
|
131
|
+
if (session.nativeTimer) clearTimeout(session.nativeTimer);
|
|
132
|
+
const recorder = session.recorder;
|
|
133
|
+
if (recorder) {
|
|
134
|
+
recorder.ondataavailable = null;
|
|
135
|
+
recorder.onstop = null;
|
|
136
|
+
recorder.onerror = null;
|
|
137
|
+
if (recorder.state !== "inactive") {
|
|
138
|
+
try {
|
|
139
|
+
recorder.stop();
|
|
140
|
+
} catch (e6) {
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const recognition = session.recognition;
|
|
145
|
+
if (recognition) {
|
|
146
|
+
recognition.onresult = null;
|
|
147
|
+
recognition.onerror = null;
|
|
148
|
+
recognition.onend = null;
|
|
149
|
+
try {
|
|
150
|
+
recognition.abort();
|
|
151
|
+
} catch (e7) {
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
releaseTracks(session);
|
|
155
|
+
session.resolveCapture(null);
|
|
156
|
+
session.resolveNativeEnd();
|
|
157
|
+
}
|
|
158
|
+
function useDictation({ lang = "en-US", continuous = true, onTranscript } = {}) {
|
|
159
|
+
const provider = _react.useContext.call(void 0, DictationContext);
|
|
160
|
+
const transcribe = _nullishCoalesce(_optionalChain([provider, 'optionalAccess', _18 => _18.transcribe]), () => ( null));
|
|
161
|
+
const scope = _nullishCoalesce(_optionalChain([provider, 'optionalAccess', _19 => _19.scope]), () => ( null));
|
|
162
|
+
const scopeGeneration = _nullishCoalesce(_optionalChain([provider, 'optionalAccess', _20 => _20.generation]), () => ( 0));
|
|
163
|
+
const [snapshot, setSnapshot] = _react.useState.call(void 0, EMPTY);
|
|
164
|
+
const [supported, setSupported] = _react.useState.call(void 0, false);
|
|
165
|
+
const current = _react.useRef.call(void 0, null);
|
|
166
|
+
const mounted = _react.useRef.call(void 0, true);
|
|
167
|
+
const callback = _react.useRef.call(void 0, onTranscript);
|
|
168
|
+
const activeScope = _react.useRef.call(void 0, scope);
|
|
169
|
+
activeScope.current = scope;
|
|
170
|
+
callback.current = onTranscript;
|
|
171
|
+
_react.useEffect.call(void 0, () => {
|
|
172
|
+
setSupported(transcribe ? typeof navigator !== "undefined" && !!_optionalChain([navigator, 'access', _21 => _21.mediaDevices, 'optionalAccess', _22 => _22.getUserMedia]) && typeof MediaRecorder !== "undefined" : typeof recognitionConstructor() === "function");
|
|
173
|
+
}, [transcribe]);
|
|
174
|
+
const cancel = _react.useCallback.call(void 0, () => {
|
|
175
|
+
const session = current.current;
|
|
176
|
+
current.current = null;
|
|
177
|
+
if (session) dispose(session);
|
|
178
|
+
if (mounted.current) setSnapshot(EMPTY);
|
|
179
|
+
}, []);
|
|
180
|
+
_react.useEffect.call(void 0, () => {
|
|
181
|
+
const session = current.current;
|
|
182
|
+
if (session && (session.scope !== scope || session.scopeGeneration !== scopeGeneration)) cancel();
|
|
183
|
+
}, [cancel, scope, scopeGeneration]);
|
|
184
|
+
_react.useEffect.call(void 0, () => {
|
|
185
|
+
mounted.current = true;
|
|
186
|
+
return () => {
|
|
187
|
+
mounted.current = false;
|
|
188
|
+
const session = current.current;
|
|
189
|
+
current.current = null;
|
|
190
|
+
if (session) dispose(session);
|
|
191
|
+
};
|
|
192
|
+
}, []);
|
|
193
|
+
const isCurrent = _react.useCallback.call(void 0, (session) => mounted.current && current.current === session && session.scope === activeScope.current && session.scopeGeneration === (_nullishCoalesce(_optionalChain([session, 'access', _23 => _23.scope, 'optionalAccess', _24 => _24.current, 'access', _25 => _25.generation]), () => ( 0))) && !session.controller.signal.aborted, []);
|
|
194
|
+
const start = _react.useCallback.call(void 0, async () => {
|
|
195
|
+
if (scope !== activeScope.current || scopeGeneration !== (_nullishCoalesce(_optionalChain([scope, 'optionalAccess', _26 => _26.current, 'access', _27 => _27.generation]), () => ( 0)))) return;
|
|
196
|
+
if (current.current && isCurrent(current.current) && ["requesting", "recording", "transcribing"].includes(current.current.phase)) return;
|
|
197
|
+
cancel();
|
|
198
|
+
let resolveCapture;
|
|
199
|
+
let resolveNativeEnd;
|
|
200
|
+
const session = {
|
|
201
|
+
language: lang,
|
|
202
|
+
transcribe,
|
|
203
|
+
scope,
|
|
204
|
+
scopeGeneration,
|
|
205
|
+
controller: new AbortController(),
|
|
206
|
+
phase: "requesting",
|
|
207
|
+
chunks: [],
|
|
208
|
+
capture: new Promise((resolve) => {
|
|
209
|
+
resolveCapture = resolve;
|
|
210
|
+
}),
|
|
211
|
+
resolveCapture: (blob) => resolveCapture(blob),
|
|
212
|
+
nativeEnd: new Promise((resolve) => {
|
|
213
|
+
resolveNativeEnd = resolve;
|
|
214
|
+
}),
|
|
215
|
+
resolveNativeEnd: () => resolveNativeEnd(),
|
|
216
|
+
nativeEnded: false,
|
|
217
|
+
transcript: "",
|
|
218
|
+
interim: "",
|
|
219
|
+
notified: /* @__PURE__ */ new Set(),
|
|
220
|
+
audioLevels: transcribe ? createAudioLevels() : void 0
|
|
221
|
+
};
|
|
222
|
+
current.current = session;
|
|
223
|
+
setSnapshot({ ...EMPTY, state: "requesting" });
|
|
224
|
+
if (transcribe) {
|
|
225
|
+
try {
|
|
226
|
+
if (!_optionalChain([navigator, 'access', _28 => _28.mediaDevices, 'optionalAccess', _29 => _29.getUserMedia]) || typeof MediaRecorder === "undefined") throw new Error("unsupported");
|
|
227
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
228
|
+
if (!isCurrent(session)) {
|
|
229
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
session.stream = stream;
|
|
233
|
+
const mimeType = MIME_TYPES.find((mime) => _optionalChain([MediaRecorder, 'access', _30 => _30.isTypeSupported, 'optionalCall', _31 => _31(mime)]));
|
|
234
|
+
const recorder = mimeType ? new MediaRecorder(stream, { mimeType }) : new MediaRecorder(stream);
|
|
235
|
+
session.recorder = recorder;
|
|
236
|
+
recorder.ondataavailable = (event) => {
|
|
237
|
+
if (isCurrent(session) && event.data.size) session.chunks.push(event.data);
|
|
238
|
+
};
|
|
239
|
+
recorder.onstop = () => {
|
|
240
|
+
releaseTracks(session);
|
|
241
|
+
if (!isCurrent(session)) {
|
|
242
|
+
session.resolveCapture(null);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const type = recorder.mimeType || _optionalChain([session, 'access', _32 => _32.chunks, 'access', _33 => _33[0], 'optionalAccess', _34 => _34.type]) || mimeType || "audio/webm";
|
|
246
|
+
const blob = new Blob(session.chunks, { type });
|
|
247
|
+
session.blob = blob;
|
|
248
|
+
session.chunks = [];
|
|
249
|
+
session.resolveCapture(blob);
|
|
250
|
+
};
|
|
251
|
+
recorder.onerror = () => {
|
|
252
|
+
if (!isCurrent(session)) return;
|
|
253
|
+
releaseTracks(session);
|
|
254
|
+
session.phase = "error";
|
|
255
|
+
session.resolveCapture(null);
|
|
256
|
+
setSnapshot({ ...EMPTY, state: "error", error: "Recording was interrupted. Try again." });
|
|
257
|
+
};
|
|
258
|
+
recorder.start();
|
|
259
|
+
session.phase = "recording";
|
|
260
|
+
session.stopMeter = meterStream(stream, session.audioLevels, () => isCurrent(session) && session.phase === "recording");
|
|
261
|
+
setSnapshot({ ...EMPTY, state: "recording" });
|
|
262
|
+
} catch (error) {
|
|
263
|
+
releaseTracks(session);
|
|
264
|
+
if (!isCurrent(session)) return;
|
|
265
|
+
session.phase = "error";
|
|
266
|
+
setSnapshot({ ...EMPTY, state: "error", error: microphoneError(error) });
|
|
267
|
+
}
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
try {
|
|
271
|
+
const Constructor = recognitionConstructor();
|
|
272
|
+
if (!Constructor) throw new Error("unsupported");
|
|
273
|
+
const recognition = new Constructor();
|
|
274
|
+
session.recognition = recognition;
|
|
275
|
+
recognition.lang = lang;
|
|
276
|
+
recognition.continuous = continuous;
|
|
277
|
+
recognition.interimResults = true;
|
|
278
|
+
recognition.onresult = (event) => {
|
|
279
|
+
if (!isCurrent(session) || session.phase === "error") return;
|
|
280
|
+
const final = [];
|
|
281
|
+
const interim = [];
|
|
282
|
+
const chunks = [];
|
|
283
|
+
for (let i = 0; i < event.results.length; i++) {
|
|
284
|
+
const result = event.results[i];
|
|
285
|
+
if (!result) continue;
|
|
286
|
+
const text = result[0].transcript.trim();
|
|
287
|
+
if (result.isFinal) {
|
|
288
|
+
final.push(text);
|
|
289
|
+
if (!session.notified.has(i)) {
|
|
290
|
+
session.notified.add(i);
|
|
291
|
+
if (text) chunks.push(text);
|
|
292
|
+
}
|
|
293
|
+
} else interim.push(text);
|
|
294
|
+
}
|
|
295
|
+
session.transcript = final.join(" ");
|
|
296
|
+
session.interim = interim.join(" ");
|
|
297
|
+
setSnapshot((previous) => ({ ...previous, transcript: session.transcript, interimTranscript: session.interim }));
|
|
298
|
+
if (chunks.length) _optionalChain([callback, 'access', _35 => _35.current, 'optionalCall', _36 => _36(chunks.join(" "))]);
|
|
299
|
+
};
|
|
300
|
+
recognition.onend = () => {
|
|
301
|
+
session.nativeEnded = true;
|
|
302
|
+
session.resolveNativeEnd();
|
|
303
|
+
if (isCurrent(session) && session.phase === "recording") {
|
|
304
|
+
session.phase = "ready";
|
|
305
|
+
setSnapshot((previous) => ({ ...previous, state: "ready" }));
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
recognition.onerror = (event) => {
|
|
309
|
+
if (!isCurrent(session)) return;
|
|
310
|
+
session.phase = "error";
|
|
311
|
+
session.nativeEnded = true;
|
|
312
|
+
session.resolveNativeEnd();
|
|
313
|
+
setSnapshot((previous) => ({ ...previous, state: "error", error: recognitionError(event.error) }));
|
|
314
|
+
};
|
|
315
|
+
recognition.start();
|
|
316
|
+
session.phase = "recording";
|
|
317
|
+
setSnapshot({ ...EMPTY, state: "recording" });
|
|
318
|
+
} catch (error) {
|
|
319
|
+
if (!isCurrent(session)) return;
|
|
320
|
+
session.phase = "error";
|
|
321
|
+
setSnapshot({ ...EMPTY, state: "error", error: microphoneError(error) });
|
|
322
|
+
}
|
|
323
|
+
}, [cancel, continuous, isCurrent, lang, scope, scopeGeneration, transcribe]);
|
|
324
|
+
const finish = _react.useCallback.call(void 0, async (session) => {
|
|
325
|
+
if (!isCurrent(session)) return null;
|
|
326
|
+
releaseMeter(session);
|
|
327
|
+
session.phase = "transcribing";
|
|
328
|
+
setSnapshot((previous) => ({ ...previous, state: "transcribing", error: null, canRetry: false }));
|
|
329
|
+
if (!session.transcribe) {
|
|
330
|
+
if (!session.nativeEnded) {
|
|
331
|
+
session.nativeTimer = setTimeout(() => {
|
|
332
|
+
try {
|
|
333
|
+
_optionalChain([session, 'access', _37 => _37.recognition, 'optionalAccess', _38 => _38.abort, 'call', _39 => _39()]);
|
|
334
|
+
} catch (e8) {
|
|
335
|
+
}
|
|
336
|
+
session.resolveNativeEnd();
|
|
337
|
+
}, 1e3);
|
|
338
|
+
try {
|
|
339
|
+
_optionalChain([session, 'access', _40 => _40.recognition, 'optionalAccess', _41 => _41.stop, 'call', _42 => _42()]);
|
|
340
|
+
} catch (e9) {
|
|
341
|
+
session.resolveNativeEnd();
|
|
342
|
+
}
|
|
343
|
+
await session.nativeEnd;
|
|
344
|
+
clearTimeout(session.nativeTimer);
|
|
345
|
+
}
|
|
346
|
+
if (!isCurrent(session) || session.phase === "error") return null;
|
|
347
|
+
const text2 = [session.transcript, session.interim].filter(Boolean).join(" ").trim();
|
|
348
|
+
session.phase = "ready";
|
|
349
|
+
setSnapshot({ ...EMPTY, state: "ready", transcript: text2 });
|
|
350
|
+
return text2;
|
|
351
|
+
}
|
|
352
|
+
let text;
|
|
353
|
+
try {
|
|
354
|
+
if (!session.blob) {
|
|
355
|
+
if (_optionalChain([session, 'access', _43 => _43.recorder, 'optionalAccess', _44 => _44.state]) !== "inactive") _optionalChain([session, 'access', _45 => _45.recorder, 'optionalAccess', _46 => _46.stop, 'call', _47 => _47()]);
|
|
356
|
+
const blob = await session.capture;
|
|
357
|
+
if (!isCurrent(session) || !blob) return null;
|
|
358
|
+
session.blob = blob;
|
|
359
|
+
}
|
|
360
|
+
if (!session.blob.size) throw new Error("No audio was recorded. Try again.");
|
|
361
|
+
text = (await session.transcribe(session.blob, { language: session.language, signal: session.controller.signal })).trim();
|
|
362
|
+
if (!isCurrent(session)) return null;
|
|
363
|
+
if (!text) throw new Error("No speech was detected. Record again.");
|
|
364
|
+
} catch (error) {
|
|
365
|
+
if (!isCurrent(session)) return null;
|
|
366
|
+
releaseTracks(session);
|
|
367
|
+
session.phase = "error";
|
|
368
|
+
const message = error instanceof Error && error.message ? error.message : "Transcription failed. Try again.";
|
|
369
|
+
setSnapshot({ ...EMPTY, state: "error", error: message, canRetry: !!_optionalChain([session, 'access', _48 => _48.blob, 'optionalAccess', _49 => _49.size]) });
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
session.transcript = text;
|
|
373
|
+
session.phase = "ready";
|
|
374
|
+
setSnapshot({ ...EMPTY, state: "ready", transcript: text });
|
|
375
|
+
_optionalChain([callback, 'access', _50 => _50.current, 'optionalCall', _51 => _51(text)]);
|
|
376
|
+
return text;
|
|
377
|
+
}, [isCurrent]);
|
|
378
|
+
const stop = _react.useCallback.call(void 0, () => {
|
|
379
|
+
const session = current.current;
|
|
380
|
+
if (!session) return Promise.resolve(null);
|
|
381
|
+
if (!isCurrent(session)) {
|
|
382
|
+
cancel();
|
|
383
|
+
return Promise.resolve(null);
|
|
384
|
+
}
|
|
385
|
+
if (session.phase === "requesting") {
|
|
386
|
+
cancel();
|
|
387
|
+
return Promise.resolve(null);
|
|
388
|
+
}
|
|
389
|
+
if (session.finish) return session.finish;
|
|
390
|
+
if (session.phase === "error") return Promise.resolve(null);
|
|
391
|
+
session.finish = finish(session);
|
|
392
|
+
return session.finish;
|
|
393
|
+
}, [cancel, finish, isCurrent]);
|
|
394
|
+
const retry = _react.useCallback.call(void 0, () => {
|
|
395
|
+
const session = current.current;
|
|
396
|
+
if (session && !isCurrent(session)) {
|
|
397
|
+
cancel();
|
|
398
|
+
return Promise.resolve(null);
|
|
399
|
+
}
|
|
400
|
+
if (!_optionalChain([session, 'optionalAccess', _52 => _52.transcribe]) || !_optionalChain([session, 'access', _53 => _53.blob, 'optionalAccess', _54 => _54.size])) return Promise.resolve(null);
|
|
401
|
+
if (session.phase !== "error") return _nullishCoalesce(session.finish, () => ( Promise.resolve(null)));
|
|
402
|
+
session.finish = finish(session);
|
|
403
|
+
return session.finish;
|
|
404
|
+
}, [cancel, finish, isCurrent]);
|
|
405
|
+
const visibleSnapshot = current.current && !isCurrent(current.current) ? EMPTY : snapshot;
|
|
406
|
+
return { ...visibleSnapshot, audioLevels: current.current && isCurrent(current.current) ? current.current.audioLevels : void 0, supported, start, stop, retry, cancel };
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
exports.DictationProvider = DictationProvider; exports.useDictation = useDictation;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunk2BSFYU22cjs = require('../chunk-2BSFYU22.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
exports.useAgentAudioVisualizerBarAnimator = _chunk2BSFYU22cjs.useAgentAudioVisualizerBarAnimator;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
type AgentVisualizerState = 'disconnected' | 'connecting' | 'initializing' | 'listening' | 'thinking' | 'speaking' | 'failed';
|
|
2
|
+
declare function useAgentAudioVisualizerBarAnimator(state: AgentVisualizerState | undefined, columns: number, interval: number): number[];
|
|
3
|
+
|
|
4
|
+
export { type AgentVisualizerState, useAgentAudioVisualizerBarAnimator };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
type AgentVisualizerState = 'disconnected' | 'connecting' | 'initializing' | 'listening' | 'thinking' | 'speaking' | 'failed';
|
|
2
|
+
declare function useAgentAudioVisualizerBarAnimator(state: AgentVisualizerState | undefined, columns: number, interval: number): number[];
|
|
3
|
+
|
|
4
|
+
export { type AgentVisualizerState, useAgentAudioVisualizerBarAnimator };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
var _chunkZZ7ICQR2cjs = require('../chunk-ZZ7ICQR2.cjs');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
exports.DictationProvider = _chunkZZ7ICQR2cjs.DictationProvider; exports.useDictation = _chunkZZ7ICQR2cjs.useDictation;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface DictationTranscribeOptions {
|
|
5
|
+
/** BCP-47 language requested by the control. */
|
|
6
|
+
language: string;
|
|
7
|
+
/** Cancel the upload/provider request when the control is dismissed. */
|
|
8
|
+
signal: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
/** The host authenticates this request; provider credentials never belong in the kit. */
|
|
11
|
+
type DictationTranscribe = (audio: Blob, options: DictationTranscribeOptions) => Promise<string>;
|
|
12
|
+
interface DictationProviderProps {
|
|
13
|
+
transcribe: DictationTranscribe;
|
|
14
|
+
/** Change when the acting user or workspace changes to discard its active take. */
|
|
15
|
+
scopeKey?: string;
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
type DictationScope = {
|
|
19
|
+
current: {
|
|
20
|
+
key: string | undefined;
|
|
21
|
+
generation: number;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
type DictationContextValue = {
|
|
25
|
+
transcribe: DictationTranscribe;
|
|
26
|
+
scope: DictationScope;
|
|
27
|
+
generation: number;
|
|
28
|
+
};
|
|
29
|
+
/** Use recorded audio + the host's API for every descendant dictation control. */
|
|
30
|
+
declare function DictationProvider({ transcribe, scopeKey, children }: DictationProviderProps): React.FunctionComponentElement<React.ProviderProps<DictationContextValue | null>>;
|
|
31
|
+
type DictationState = "idle" | "requesting" | "recording" | "transcribing" | "ready" | "error";
|
|
32
|
+
interface UseDictationOptions {
|
|
33
|
+
lang?: string;
|
|
34
|
+
/** Applies to native recognition. API capture finishes when stop is called. */
|
|
35
|
+
continuous?: boolean;
|
|
36
|
+
/** Native final chunks, or one complete API transcript. Do not also commit stop's result. */
|
|
37
|
+
onTranscript?: (text: string) => void;
|
|
38
|
+
}
|
|
39
|
+
interface DictationCapture {
|
|
40
|
+
state: DictationState;
|
|
41
|
+
supported: boolean;
|
|
42
|
+
transcript: string;
|
|
43
|
+
interimTranscript: string;
|
|
44
|
+
error: string | null;
|
|
45
|
+
canRetry: boolean;
|
|
46
|
+
/** Live bands from the recording stream. Native speech recognition exposes no audio meter. */
|
|
47
|
+
audioLevels?: {
|
|
48
|
+
subscribe: (listener: () => void) => () => void;
|
|
49
|
+
getSnapshot: () => number[];
|
|
50
|
+
};
|
|
51
|
+
start: () => Promise<void>;
|
|
52
|
+
/** Returns null on cancellation/failure; concurrent stops share one transcription. */
|
|
53
|
+
stop: () => Promise<string | null>;
|
|
54
|
+
/** Retries the same recorded take after an API failure. */
|
|
55
|
+
retry: () => Promise<string | null>;
|
|
56
|
+
cancel: () => void;
|
|
57
|
+
}
|
|
58
|
+
/** Shared microphone lifecycle. Without a provider, existing native dictation keeps working. */
|
|
59
|
+
declare function useDictation({ lang, continuous, onTranscript }?: UseDictationOptions): DictationCapture;
|
|
60
|
+
|
|
61
|
+
export { type DictationCapture, DictationProvider, type DictationProviderProps, type DictationState, type DictationTranscribe, type DictationTranscribeOptions, type UseDictationOptions, useDictation };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface DictationTranscribeOptions {
|
|
5
|
+
/** BCP-47 language requested by the control. */
|
|
6
|
+
language: string;
|
|
7
|
+
/** Cancel the upload/provider request when the control is dismissed. */
|
|
8
|
+
signal: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
/** The host authenticates this request; provider credentials never belong in the kit. */
|
|
11
|
+
type DictationTranscribe = (audio: Blob, options: DictationTranscribeOptions) => Promise<string>;
|
|
12
|
+
interface DictationProviderProps {
|
|
13
|
+
transcribe: DictationTranscribe;
|
|
14
|
+
/** Change when the acting user or workspace changes to discard its active take. */
|
|
15
|
+
scopeKey?: string;
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
type DictationScope = {
|
|
19
|
+
current: {
|
|
20
|
+
key: string | undefined;
|
|
21
|
+
generation: number;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
type DictationContextValue = {
|
|
25
|
+
transcribe: DictationTranscribe;
|
|
26
|
+
scope: DictationScope;
|
|
27
|
+
generation: number;
|
|
28
|
+
};
|
|
29
|
+
/** Use recorded audio + the host's API for every descendant dictation control. */
|
|
30
|
+
declare function DictationProvider({ transcribe, scopeKey, children }: DictationProviderProps): React.FunctionComponentElement<React.ProviderProps<DictationContextValue | null>>;
|
|
31
|
+
type DictationState = "idle" | "requesting" | "recording" | "transcribing" | "ready" | "error";
|
|
32
|
+
interface UseDictationOptions {
|
|
33
|
+
lang?: string;
|
|
34
|
+
/** Applies to native recognition. API capture finishes when stop is called. */
|
|
35
|
+
continuous?: boolean;
|
|
36
|
+
/** Native final chunks, or one complete API transcript. Do not also commit stop's result. */
|
|
37
|
+
onTranscript?: (text: string) => void;
|
|
38
|
+
}
|
|
39
|
+
interface DictationCapture {
|
|
40
|
+
state: DictationState;
|
|
41
|
+
supported: boolean;
|
|
42
|
+
transcript: string;
|
|
43
|
+
interimTranscript: string;
|
|
44
|
+
error: string | null;
|
|
45
|
+
canRetry: boolean;
|
|
46
|
+
/** Live bands from the recording stream. Native speech recognition exposes no audio meter. */
|
|
47
|
+
audioLevels?: {
|
|
48
|
+
subscribe: (listener: () => void) => () => void;
|
|
49
|
+
getSnapshot: () => number[];
|
|
50
|
+
};
|
|
51
|
+
start: () => Promise<void>;
|
|
52
|
+
/** Returns null on cancellation/failure; concurrent stops share one transcription. */
|
|
53
|
+
stop: () => Promise<string | null>;
|
|
54
|
+
/** Retries the same recorded take after an API failure. */
|
|
55
|
+
retry: () => Promise<string | null>;
|
|
56
|
+
cancel: () => void;
|
|
57
|
+
}
|
|
58
|
+
/** Shared microphone lifecycle. Without a provider, existing native dictation keeps working. */
|
|
59
|
+
declare function useDictation({ lang, continuous, onTranscript }?: UseDictationOptions): DictationCapture;
|
|
60
|
+
|
|
61
|
+
export { type DictationCapture, DictationProvider, type DictationProviderProps, type DictationState, type DictationTranscribe, type DictationTranscribeOptions, type UseDictationOptions, useDictation };
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
var _chunkKGFL3VWYcjs = require('../chunk-KGFL3VWY.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
var _chunkPQUSJEXLcjs = require('../chunk-PQUSJEXL.cjs');
|
|
8
|
+
require('../chunk-VGTINL5Q.cjs');
|
|
7
9
|
|
|
8
10
|
|
|
9
|
-
var _chunkWABCLRBRcjs = require('../chunk-WABCLRBR.cjs');
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
var
|
|
13
|
-
require('../chunk-VGTINL5Q.cjs');
|
|
13
|
+
var _chunkWABCLRBRcjs = require('../chunk-WABCLRBR.cjs');
|
|
14
14
|
require('../chunk-I6GUOEBO.cjs');
|
|
15
15
|
|
|
16
16
|
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ChipTabs
|
|
4
4
|
} from "../chunk-QD63LB2F.js";
|
|
5
|
+
import {
|
|
6
|
+
Input
|
|
7
|
+
} from "../chunk-QMA3WVB7.js";
|
|
8
|
+
import "../chunk-H7TETFLB.js";
|
|
5
9
|
import {
|
|
6
10
|
Avatar,
|
|
7
11
|
AvatarFallback,
|
|
8
12
|
AvatarImage
|
|
9
13
|
} from "../chunk-3OWGL4Q2.js";
|
|
10
|
-
import {
|
|
11
|
-
Input
|
|
12
|
-
} from "../chunk-QMA3WVB7.js";
|
|
13
|
-
import "../chunk-H7TETFLB.js";
|
|
14
14
|
import "../chunk-D4ZL2OEQ.js";
|
|
15
15
|
import {
|
|
16
16
|
EmptyState
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var _chunkNKWHDI4Ccjs = require('../chunk-NKWHDI4C.cjs');
|
|
9
|
+
require('../chunk-KWLSBTB2.cjs');
|
|
10
|
+
require('../chunk-2BSFYU22.cjs');
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
exports.AgentAudioVisualizerBar = _chunkNKWHDI4Ccjs.AgentAudioVisualizerBar; exports.AgentAudioVisualizerBarElementVariants = _chunkNKWHDI4Ccjs.AgentAudioVisualizerBarElementVariants; exports.AgentAudioVisualizerBarVariants = _chunkNKWHDI4Ccjs.AgentAudioVisualizerBarVariants; exports.normalizeVolumeBands = _chunkNKWHDI4Ccjs.normalizeVolumeBands;
|