@amaster.ai/asr-client 1.0.0-beta.7 → 1.0.0-beta.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,207 +1,554 @@
1
1
  // src/asr-client.ts
2
2
  var ASR_PATH = "/api/proxy/builtin/platform/qwen-asr-realtime/api-ws/v1/realtime";
3
- async function listen(onTranscript) {
4
- const ws = new WebSocket(ASR_PATH);
5
- let mediaStream = null;
6
- let audioContext = null;
3
+ async function createRealtimeRecorder() {
4
+ let stream = null;
5
+ let ctx = null;
6
+ let source = null;
7
7
  let processor = null;
8
- const stop = () => {
9
- if (mediaStream) {
10
- mediaStream.getTracks().forEach((t) => t.stop());
11
- mediaStream = null;
12
- }
13
- if (processor) {
14
- processor.disconnect();
8
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
9
+ throw new Error("\u672A\u627E\u5230\u9EA6\u514B\u98CE\u6216\u65E0\u6743\u9650");
10
+ }
11
+ return {
12
+ async start(onAudio) {
13
+ stream = await navigator.mediaDevices.getUserMedia({
14
+ audio: { sampleRate: 16e3, channelCount: 1, echoCancellation: true }
15
+ });
16
+ log("\u2705 \u9EA6\u514B\u98CE\u5DF2\u542F\u52A8", "success");
17
+ log("\u{1F4AC} \u8BF7\u5BF9\u7740\u9EA6\u514B\u98CE\u8BF4\u8BDD\uFF0C\u5B9E\u65F6\u8BC6\u522B\u4E2D...", "success");
18
+ ctx = new AudioContext({ sampleRate: 16e3 });
19
+ source = ctx.createMediaStreamSource(stream);
20
+ processor = ctx.createScriptProcessor(4096, 1, 1);
21
+ processor.onaudioprocess = (e) => {
22
+ const inputData = e.inputBuffer.getChannelData(0);
23
+ const pcm = new Int16Array(inputData.length);
24
+ for (let i = 0; i < inputData.length; i++) {
25
+ const s = Math.max(-1, Math.min(1, inputData[i] || 0));
26
+ pcm[i] = s < 0 ? s * 32768 : s * 32767;
27
+ }
28
+ const bytes = new Uint8Array(pcm.buffer);
29
+ let binary = "";
30
+ for (let i = 0; i < bytes.length; i++) {
31
+ binary += String.fromCharCode(bytes[i] || 0);
32
+ }
33
+ onAudio(btoa(binary));
34
+ };
35
+ source.connect(processor);
36
+ processor.connect(ctx.destination);
37
+ },
38
+ async stop() {
39
+ stream?.getTracks().forEach((t) => t.stop());
40
+ source?.disconnect();
41
+ processor?.disconnect();
42
+ if (ctx) {
43
+ await ctx.close();
44
+ }
45
+ stream = null;
46
+ ctx = null;
47
+ source = null;
15
48
  processor = null;
16
49
  }
17
- if (audioContext) {
18
- audioContext.close();
19
- audioContext = null;
20
- }
21
- if (ws.readyState === WebSocket.OPEN) {
22
- ws.send(JSON.stringify({ type: "input_audio_buffer.commit" }));
23
- ws.close();
24
- }
25
50
  };
26
- return new Promise((resolve, reject) => {
27
- ws.onmessage = async (event) => {
28
- const data = JSON.parse(event.data);
29
- if (data.type === "session.created") {
30
- try {
31
- mediaStream = await navigator.mediaDevices.getUserMedia({
32
- audio: { sampleRate: 16e3, channelCount: 1, echoCancellation: true }
33
- });
34
- audioContext = new AudioContext({ sampleRate: 16e3 });
35
- const source = audioContext.createMediaStreamSource(mediaStream);
36
- processor = audioContext.createScriptProcessor(4096, 1, 1);
37
- processor.onaudioprocess = (e) => {
38
- if (ws.readyState !== WebSocket.OPEN) return;
39
- const input = e.inputBuffer.getChannelData(0);
40
- const pcm = new Int16Array(input.length);
41
- for (let i = 0; i < input.length; i++) {
42
- const s = Math.max(-1, Math.min(1, input[i]));
43
- pcm[i] = s < 0 ? s * 32768 : s * 32767;
44
- }
45
- const bytes = new Uint8Array(pcm.buffer);
46
- let binary = "";
47
- for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
48
- ws.send(JSON.stringify({ type: "input_audio_buffer.append", audio: btoa(binary) }));
49
- };
50
- source.connect(processor);
51
- processor.connect(audioContext.destination);
52
- resolve(stop);
53
- } catch (err) {
54
- reject(err);
55
- }
56
- }
57
- if (data.type === "conversation.item.input_audio_transcription.text") {
58
- onTranscript(data.text || "", false);
59
- }
60
- if (data.type === "conversation.item.input_audio_transcription.completed") {
61
- onTranscript(data.text || data.transcript || "", true);
62
- }
63
- if (data.type === "error") {
64
- stop();
65
- reject(new Error(data.error?.message || "ASR error"));
66
- }
67
- };
68
- ws.onerror = () => reject(new Error("ASR connection failed"));
69
- });
51
+ }
52
+ var log = (message, type = "") => {
53
+ console.log(`[${type}]`, message);
54
+ };
55
+ var eventIdCounter = 0;
56
+ function generateEventId() {
57
+ return `event_${Date.now()}_${++eventIdCounter}`;
70
58
  }
71
59
  function createASRClient(config) {
72
60
  const {
73
- // audioFormat = 'pcm16',
74
- sampleRate = 16e3,
75
61
  onReady,
76
62
  onSpeechStart,
77
63
  onSpeechEnd,
78
64
  onTranscript,
79
- onError
65
+ onAudioBufferCommitted,
66
+ onSessionFinished,
67
+ onError,
68
+ onClose,
69
+ getAccessToken,
70
+ audioFormat = "pcm",
71
+ sampleRate = 16e3,
72
+ language = "zh",
73
+ enableVAD = true,
74
+ vadThreshold = 0.2,
75
+ vadSilenceDurationMs = 400
80
76
  } = config;
81
77
  let ws = null;
82
- let mediaStream = null;
83
- let audioContext = null;
84
- let processor = null;
78
+ let recorder = null;
79
+ let isRecordingFlag = false;
80
+ let isClosing = false;
81
+ const path = ASR_PATH;
82
+ function sendEvent(event) {
83
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
84
+ throw new Error("WebSocket not connected");
85
+ }
86
+ ws.send(JSON.stringify(event));
87
+ }
88
+ function buildSessionConfig() {
89
+ const sessionConfig = {
90
+ input_audio_format: audioFormat,
91
+ sample_rate: sampleRate,
92
+ input_audio_transcription: {
93
+ language
94
+ }
95
+ };
96
+ if (enableVAD) {
97
+ sessionConfig.turn_detection = {
98
+ type: "server_vad",
99
+ threshold: vadThreshold,
100
+ silence_duration_ms: vadSilenceDurationMs
101
+ };
102
+ } else {
103
+ sessionConfig.turn_detection = null;
104
+ }
105
+ return sessionConfig;
106
+ }
107
+ function sendSessionUpdate() {
108
+ const event = {
109
+ event_id: generateEventId(),
110
+ type: "session.update",
111
+ session: buildSessionConfig()
112
+ };
113
+ sendEvent(event);
114
+ }
115
+ function sendAudioBufferAppend(audio) {
116
+ const event = {
117
+ event_id: generateEventId(),
118
+ type: "input_audio_buffer.append",
119
+ audio
120
+ };
121
+ sendEvent(event);
122
+ }
123
+ function sendAudioBufferCommit() {
124
+ const event = {
125
+ event_id: generateEventId(),
126
+ type: "input_audio_buffer.commit"
127
+ };
128
+ sendEvent(event);
129
+ }
130
+ function sendSessionFinish() {
131
+ const event = {
132
+ event_id: generateEventId(),
133
+ type: "session.finish"
134
+ };
135
+ sendEvent(event);
136
+ }
137
+ function handleServerEvent(data) {
138
+ switch (data.type) {
139
+ case "session.created":
140
+ try {
141
+ sendSessionUpdate();
142
+ } catch (err2) {
143
+ onError?.(
144
+ new Error(
145
+ "Failed to send session.update: " + (err2 instanceof Error ? err2.message : String(err2))
146
+ )
147
+ );
148
+ }
149
+ break;
150
+ case "session.updated":
151
+ onReady?.();
152
+ break;
153
+ case "input_audio_buffer.speech_started":
154
+ onSpeechStart?.();
155
+ break;
156
+ case "input_audio_buffer.speech_stopped":
157
+ onSpeechEnd?.();
158
+ break;
159
+ case "input_audio_buffer.committed":
160
+ onAudioBufferCommitted?.();
161
+ break;
162
+ case "conversation.item.input_audio_transcription.text":
163
+ onTranscript?.(data.text || data.stash || data.transcript || "", false);
164
+ break;
165
+ case "conversation.item.input_audio_transcription.completed":
166
+ onTranscript?.(data.text || data.transcript || "", true);
167
+ break;
168
+ case "session.finished":
169
+ onSessionFinished?.();
170
+ close();
171
+ break;
172
+ case "error":
173
+ const err = new Error(data.error?.message || "ASR error");
174
+ onError?.(err);
175
+ break;
176
+ default:
177
+ console.warn("[ASR] Unknown server event:", data.type);
178
+ }
179
+ }
85
180
  async function connect() {
181
+ let wsUrl = path;
182
+ if (getAccessToken) {
183
+ const token = getAccessToken();
184
+ if (token) {
185
+ const separator = path.includes("?") ? "&" : "?";
186
+ wsUrl = `${path}${separator}token=${encodeURIComponent(token)}`;
187
+ }
188
+ }
189
+ if (typeof window !== "undefined" && window.location) {
190
+ const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
191
+ if (!wsUrl.startsWith("ws://") && !wsUrl.startsWith("wss://")) {
192
+ wsUrl = `${protocol}//${window.location.host}${wsUrl}`;
193
+ }
194
+ }
195
+ ws = new WebSocket(wsUrl);
86
196
  return new Promise((resolve, reject) => {
87
- ws = new WebSocket(ASR_PATH);
197
+ if (!ws) {
198
+ reject(new Error("Failed to create WebSocket"));
199
+ return;
200
+ }
88
201
  ws.onopen = () => {
202
+ log("WebSocket connected", "success");
89
203
  };
90
204
  ws.onmessage = (event) => {
91
- const data = JSON.parse(event.data);
92
- if (data.type === "session.created") {
93
- onReady?.();
94
- resolve();
95
- }
96
- if (data.type === "input_audio_buffer.speech_started") {
97
- onSpeechStart?.();
98
- }
99
- if (data.type === "input_audio_buffer.speech_stopped") {
100
- onSpeechEnd?.();
101
- }
102
- if (data.type === "conversation.item.input_audio_transcription.text") {
103
- onTranscript?.(data.text || "", false);
104
- }
105
- if (data.type === "conversation.item.input_audio_transcription.completed") {
106
- onTranscript?.(data.text || data.transcript || "", true);
107
- }
108
- if (data.type === "error") {
109
- const err = new Error(data.error?.message || "Unknown error");
110
- onError?.(err);
111
- reject(err);
205
+ try {
206
+ const data = JSON.parse(event.data);
207
+ handleServerEvent(data);
208
+ if (data.type === "session.updated") {
209
+ resolve();
210
+ }
211
+ } catch (err) {
212
+ const error = new Error(
213
+ "Failed to parse server message: " + (err instanceof Error ? err.message : String(err))
214
+ );
215
+ onError?.(error);
216
+ reject(error);
112
217
  }
113
218
  };
114
- ws.onerror = () => {
115
- const err = new Error("WebSocket connection error");
219
+ ws.onerror = (error) => {
220
+ console.error("WebSocket error:", error);
221
+ const err = new Error("WebSocket error");
116
222
  onError?.(err);
117
223
  reject(err);
118
224
  };
119
225
  ws.onclose = () => {
226
+ isRecordingFlag = false;
120
227
  ws = null;
228
+ onClose?.();
121
229
  };
122
230
  });
123
231
  }
124
232
  async function startRecording() {
125
- if (typeof window === "undefined") {
126
- throw new Error("Recording only supported in browser");
127
- }
128
233
  if (!ws || ws.readyState !== WebSocket.OPEN) {
129
234
  throw new Error("WebSocket not connected");
130
235
  }
236
+ if (isRecordingFlag) {
237
+ return;
238
+ }
131
239
  try {
132
- mediaStream = await navigator.mediaDevices.getUserMedia({
133
- audio: {
134
- sampleRate,
135
- channelCount: 1,
136
- echoCancellation: true,
137
- noiseSuppression: true
138
- }
139
- });
140
- audioContext = new AudioContext({ sampleRate });
141
- const source = audioContext.createMediaStreamSource(mediaStream);
142
- processor = audioContext.createScriptProcessor(4096, 1, 1);
143
- processor.onaudioprocess = (e) => {
240
+ recorder = await createRealtimeRecorder();
241
+ isRecordingFlag = true;
242
+ await recorder.start((audio) => {
144
243
  if (!ws || ws.readyState !== WebSocket.OPEN) return;
145
- const inputData = e.inputBuffer.getChannelData(0);
146
- const inputLen = inputData.length;
147
- const pcm = new Int16Array(inputLen);
148
- for (let i = 0; i < inputLen; i++) {
149
- const s = Math.max(-1, Math.min(1, inputData[i]));
150
- pcm[i] = s < 0 ? s * 32768 : s * 32767;
151
- }
152
- const bytes = new Uint8Array(pcm.buffer);
153
- const len = bytes.length;
154
- let binary = "";
155
- for (let i = 0; i < len; i++) {
156
- binary += String.fromCharCode(bytes[i]);
244
+ try {
245
+ sendAudioBufferAppend(audio);
246
+ } catch (err) {
247
+ console.error("[ASR] Failed to send audio:", err);
157
248
  }
158
- const base64 = btoa(binary);
159
- ws.send(JSON.stringify({
160
- type: "input_audio_buffer.append",
161
- audio: base64
162
- }));
163
- };
164
- source.connect(processor);
165
- processor.connect(audioContext.destination);
249
+ });
166
250
  } catch (err) {
167
- onError?.(err);
251
+ console.error("[ASR] Failed to start recorder:", err);
252
+ onError?.(err instanceof Error ? err : new Error(String(err)));
168
253
  throw err;
169
254
  }
170
255
  }
171
- function stopRecording() {
172
- if (mediaStream) {
173
- mediaStream.getTracks().forEach((track) => track.stop());
174
- mediaStream = null;
175
- }
176
- if (processor) {
177
- processor.disconnect();
178
- processor = null;
256
+ async function stopRecording() {
257
+ if (!isRecordingFlag) {
258
+ return;
179
259
  }
180
- if (audioContext) {
181
- audioContext.close();
182
- audioContext = null;
260
+ try {
261
+ await recorder?.stop();
262
+ } catch (err) {
263
+ console.error("[ASR] Error stopping recorder:", err);
183
264
  }
184
- if (ws && ws.readyState === WebSocket.OPEN) {
185
- ws.send(JSON.stringify({ type: "input_audio_buffer.commit" }));
265
+ recorder = null;
266
+ isRecordingFlag = false;
267
+ if (!enableVAD && ws?.readyState === WebSocket.OPEN) {
268
+ try {
269
+ sendAudioBufferCommit();
270
+ } catch (err) {
271
+ console.error("[ASR] Failed to send commit:", err);
272
+ }
186
273
  }
187
274
  }
188
- function close() {
189
- stopRecording();
190
- if (ws) {
191
- ws.close();
192
- ws = null;
275
+ async function close() {
276
+ if (isClosing) {
277
+ return;
278
+ }
279
+ isClosing = true;
280
+ await stopRecording();
281
+ if (ws?.readyState === WebSocket.OPEN) {
282
+ try {
283
+ sendSessionFinish();
284
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
285
+ } catch (err) {
286
+ console.error("[ASR] Failed to send session.finish:", err);
287
+ }
193
288
  }
289
+ if (ws && ws?.readyState !== WebSocket.CLOSING && ws?.readyState !== WebSocket.CLOSED) {
290
+ ws?.close();
291
+ }
292
+ ws = null;
293
+ isClosing = false;
294
+ }
295
+ function isRecording() {
296
+ return isRecordingFlag;
297
+ }
298
+ function isConnected() {
299
+ return ws !== null && ws.readyState === WebSocket.OPEN;
194
300
  }
195
301
  return {
196
302
  connect,
197
303
  startRecording,
198
304
  stopRecording,
199
- close
305
+ close,
306
+ isRecording,
307
+ isConnected
308
+ };
309
+ }
310
+ var asr_client_default = (authConfig) => (config) => createASRClient({ ...authConfig, ...config });
311
+
312
+ // src/http-asr-client.ts
313
+ import { createHttpClient } from "@amaster.ai/http-client";
314
+ var ASR_HTTP_PATH = "/api/proxy/builtin/platform/qwen-asr/compatible-mode/v1/chat/completions";
315
+ var RECORDER_WORKLET = `
316
+ class RecorderProcessor extends AudioWorkletProcessor {
317
+ process(inputs) {
318
+ const input = inputs[0];
319
+ if (input && input[0]) {
320
+ this.port.postMessage(input[0].slice(0));
321
+ }
322
+ return true;
323
+ }
324
+ }
325
+ registerProcessor('recorder-processor', RecorderProcessor);
326
+ `;
327
+ async function createWebRecorder(props) {
328
+ let stream;
329
+ let ctx;
330
+ let node;
331
+ let source;
332
+ const chunks = [];
333
+ const cleanup = () => {
334
+ try {
335
+ source?.disconnect();
336
+ node?.disconnect();
337
+ stream?.getTracks().forEach((t) => t.stop());
338
+ ctx?.close();
339
+ } catch (e) {
340
+ }
341
+ };
342
+ return {
343
+ async start() {
344
+ try {
345
+ stream = await navigator.mediaDevices.getUserMedia({
346
+ audio: {
347
+ channelCount: 1,
348
+ echoCancellation: true,
349
+ noiseSuppression: true,
350
+ autoGainControl: true
351
+ }
352
+ });
353
+ ctx = new AudioContext();
354
+ const blob = new Blob([RECORDER_WORKLET], {
355
+ type: "application/javascript"
356
+ });
357
+ const url = URL.createObjectURL(blob);
358
+ await ctx.audioWorklet.addModule(url);
359
+ URL.revokeObjectURL(url);
360
+ source = ctx.createMediaStreamSource(stream);
361
+ node = new AudioWorkletNode(ctx, "recorder-processor");
362
+ node.port.onmessage = (e) => {
363
+ const input = e.data;
364
+ const pcm = new Int16Array(input.length);
365
+ for (let i = 0; i < input.length; i++) {
366
+ const s = Math.max(-1, Math.min(1, input[i] || 0));
367
+ pcm[i] = s < 0 ? s * 32768 : s * 32767;
368
+ }
369
+ chunks.push(pcm);
370
+ };
371
+ source.connect(node);
372
+ props?.onStart?.();
373
+ } catch (error) {
374
+ props?.onError?.(
375
+ error instanceof Error ? error : new Error(String(error))
376
+ );
377
+ cleanup();
378
+ }
379
+ },
380
+ async stop() {
381
+ cleanup();
382
+ const total = chunks.reduce((s, c) => s + c.length, 0);
383
+ const pcm = new Int16Array(total);
384
+ let offset = 0;
385
+ for (const c of chunks) {
386
+ pcm.set(c, offset);
387
+ offset += c.length;
388
+ }
389
+ const result = { pcm, sampleRate: ctx?.sampleRate ?? 16e3 };
390
+ const base64 = await blobToBase64(
391
+ pcmToWav(result.pcm, result.sampleRate)
392
+ );
393
+ props?.onStop?.(base64);
394
+ }
395
+ };
396
+ }
397
+ function pcmToWav(pcm, sampleRate) {
398
+ const buffer = new ArrayBuffer(44 + pcm.length * 2);
399
+ const view = new DataView(buffer);
400
+ const write = (o, s) => {
401
+ for (let i = 0; i < s.length; i++) view.setUint8(o + i, s.charCodeAt(i));
200
402
  };
403
+ write(0, "RIFF");
404
+ view.setUint32(4, 36 + pcm.length * 2, true);
405
+ write(8, "WAVE");
406
+ write(12, "fmt ");
407
+ view.setUint32(16, 16, true);
408
+ view.setUint16(20, 1, true);
409
+ view.setUint16(22, 1, true);
410
+ view.setUint32(24, sampleRate, true);
411
+ view.setUint32(28, sampleRate * 2, true);
412
+ view.setUint16(32, 2, true);
413
+ view.setUint16(34, 16, true);
414
+ write(36, "data");
415
+ view.setUint32(40, pcm.length * 2, true);
416
+ for (let i = 0; i < pcm.length; i++) {
417
+ view.setInt16(44 + i * 2, pcm[i] || 0, true);
418
+ }
419
+ return new Blob([buffer], { type: "audio/wav" });
420
+ }
421
+ function blobToBase64(blob) {
422
+ return new Promise((resolve, reject) => {
423
+ const reader = new FileReader();
424
+ reader.onloadend = () => {
425
+ const result = reader.result;
426
+ resolve(result.split(",")[1] || "");
427
+ };
428
+ reader.onerror = reject;
429
+ reader.readAsDataURL(blob);
430
+ });
431
+ }
432
+ var AsrHttpClient = class {
433
+ constructor(config, path) {
434
+ this.recorder = null;
435
+ this.path = "";
436
+ this.recognizing = false;
437
+ this.http = config.http ?? createHttpClient();
438
+ this.config = config;
439
+ this.path = path;
440
+ }
441
+ async startRecording() {
442
+ if (this.recorder) {
443
+ return;
444
+ }
445
+ const options = {
446
+ onStart: () => {
447
+ this.config.onRecordingStart?.();
448
+ this.config.onStatusChange?.("recording");
449
+ },
450
+ onStop: async (base64) => {
451
+ this.config.onStatusChange?.("recognizing");
452
+ const text = await this.recognizeFile(base64);
453
+ this.config.onResult?.(text);
454
+ this.config.onRecordingStop?.();
455
+ this.config.onStatusChange?.("idle");
456
+ this.recorder = null;
457
+ },
458
+ onError: (err) => {
459
+ this.config.onError?.(err);
460
+ this.config.onStatusChange?.("idle");
461
+ this.recorder = null;
462
+ }
463
+ };
464
+ this.recorder = await (this.config.createRecorder?.(options) ?? createWebRecorder(options));
465
+ await this.recorder.start();
466
+ }
467
+ async stopRecording() {
468
+ if (this.recorder) {
469
+ await this.recorder.stop();
470
+ this.recorder = null;
471
+ } else {
472
+ this.config.onResult?.("");
473
+ this.config.onRecordingStop?.();
474
+ this.config.onStatusChange?.("idle");
475
+ }
476
+ }
477
+ async recognizeFile(base64) {
478
+ if (this.recognizing) {
479
+ return "";
480
+ }
481
+ this.recognizing = true;
482
+ try {
483
+ const response = await this.http.request({
484
+ url: this.path,
485
+ method: "POST",
486
+ headers: { "Content-Type": "application/json" },
487
+ data: JSON.stringify({
488
+ model: "qwen3-asr-flash",
489
+ messages: [
490
+ {
491
+ role: "user",
492
+ content: [
493
+ {
494
+ type: "input_audio",
495
+ input_audio: { data: `data:audio/wav;base64,${base64}` }
496
+ }
497
+ ]
498
+ }
499
+ ]
500
+ })
501
+ });
502
+ return response?.data?.choices?.[0]?.message?.content || "";
503
+ } catch (e) {
504
+ console.error("ASR recognition error:", e);
505
+ return "";
506
+ } finally {
507
+ this.recognizing = false;
508
+ }
509
+ }
510
+ async recordAndRecognize(ms) {
511
+ await this.startRecording();
512
+ await new Promise((r) => setTimeout(r, ms));
513
+ await this.stopRecording();
514
+ }
515
+ async recognizeUrl(url) {
516
+ try {
517
+ const res = await this.http.request({
518
+ url: this.path,
519
+ method: "POST",
520
+ headers: { "Content-Type": "application/json" },
521
+ data: JSON.stringify({
522
+ model: "qwen3-asr-flash",
523
+ messages: [
524
+ {
525
+ role: "user",
526
+ content: [{ type: "input_audio", input_audio: { url } }]
527
+ }
528
+ ]
529
+ })
530
+ });
531
+ return res?.data?.choices?.[0]?.message?.content || "";
532
+ } catch (e) {
533
+ console.error("ASR recognition error:", e);
534
+ return "";
535
+ }
536
+ }
537
+ };
538
+ function createASRHttpClient(config) {
539
+ let path = ASR_HTTP_PATH;
540
+ if (config.getAccessToken) {
541
+ const token = config.getAccessToken();
542
+ if (token) {
543
+ const separator = path.includes("?") ? "&" : "?";
544
+ path = `${path}${separator}token=${encodeURIComponent(token)}`;
545
+ }
546
+ }
547
+ return new AsrHttpClient(config, path);
201
548
  }
549
+ var http_asr_client_default = (authConfig) => (config) => createASRHttpClient({ ...authConfig, ...config });
202
550
  export {
203
- createASRClient,
204
- createASRClient as createAsrClient,
205
- listen
551
+ asr_client_default as createASRClient,
552
+ http_asr_client_default as createASRHttpClient
206
553
  };
207
554
  //# sourceMappingURL=index.js.map