@szjy/ai-coms 0.1.16 → 0.1.17

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.mjs CHANGED
@@ -1,14 +1,14 @@
1
- var yt = Object.defineProperty;
2
- var vt = (e, t, s) => t in e ? yt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : e[t] = s;
3
- var M = (e, t, s) => vt(e, typeof t != "symbol" ? t + "" : t, s);
4
- import { computed as N, openBlock as S, createElementBlock as x, normalizeStyle as ue, createElementVNode as d, normalizeClass as re, getCurrentInstance as Je, ref as T, watch as Pe, onUnmounted as wt, createBlock as ge, Transition as ye, withCtx as J, toDisplayString as W, withDirectives as Ke, vShow as Xe, createCommentVNode as $, createVNode as D, nextTick as Ye, onBeforeUnmount as bt, resolveComponent as Me, createTextVNode as pe, Fragment as me, renderList as Be, withKeys as kt, defineComponent as Ze, withModifiers as St } from "vue";
5
- const Ct = "/images/ai-round.png", At = "/images/ai-sqrt.png", xt = "/images/bars-loading.svg";
6
- function Qe(e) {
1
+ var Yt = Object.defineProperty;
2
+ var Xt = (e, t, n) => t in e ? Yt(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
+ var N = (e, t, n) => Xt(e, typeof t != "symbol" ? t + "" : t, n);
4
+ import { computed as q, openBlock as T, createElementBlock as L, normalizeStyle as ce, createElementVNode as p, normalizeClass as le, getCurrentInstance as bt, ref as R, watch as ye, onUnmounted as De, createBlock as Se, Transition as Le, withCtx as ie, toDisplayString as Q, withDirectives as kt, vShow as St, createCommentVNode as H, createVNode as ne, nextTick as Ct, inject as Zt, shallowRef as it, provide as Qt, toValue as lt, defineComponent as Ue, Fragment as he, renderList as Fe, createTextVNode as fe, onMounted as en, unref as Re, reactive as tn, onBeforeUnmount as nn, resolveComponent as Je, withKeys as sn, withModifiers as on } from "vue";
5
+ const rn = "/images/ai-round.png", an = "/images/ai-sqrt.png", ln = "/images/sikao.svg", cn = "/images/bars-loading.svg";
6
+ function At(e) {
7
7
  return e.startsWith("http://") || e.startsWith("https://") ? e : `${location.protocol}//${location.host}${e}`;
8
8
  }
9
- async function Tt(e, t, s, r = "", o = {}) {
10
- const { projectId: n } = o, a = Qe(r), i = new URL(`${a}/v1/chat/completions`), l = (o == null ? void 0 : o.authToken) || "app-oLZVFFdYyJX2QK3rdOLWsC2u";
11
- o != null && o.authToken || console.error("缺少 authToken!现在默认使用内网的 authToken");
9
+ async function un(e, t, n, s = "", r = {}) {
10
+ const { projectId: o } = r, a = At(s), i = new URL(`${a}/v1/chat/completions`), l = (r == null ? void 0 : r.authToken) || "app-oLZVFFdYyJX2QK3rdOLWsC2u";
11
+ r != null && r.authToken || console.error("缺少 authToken!现在默认使用内网的 authToken");
12
12
  const c = new Request(i, {
13
13
  method: "post",
14
14
  headers: {
@@ -20,8 +20,8 @@ async function Tt(e, t, s, r = "", o = {}) {
20
20
  stream: !0,
21
21
  inputs: {
22
22
  token: t,
23
- projectCode: s,
24
- ...n ? { projectId: n } : {}
23
+ projectCode: n,
24
+ ...o ? { projectId: o } : {}
25
25
  },
26
26
  messages: [
27
27
  {
@@ -37,12 +37,12 @@ async function Tt(e, t, s, r = "", o = {}) {
37
37
  });
38
38
  return fetch(c);
39
39
  }
40
- async function Rt(e, t, s, r = "", o = {}) {
41
- const n = new URL("http://localhost:11434/api/chat"), a = {};
40
+ async function dn(e, t, n, s = "", r = {}) {
41
+ const o = new URL("http://localhost:11434/api/chat"), a = {};
42
42
  Object.keys(a).forEach((l) => {
43
- n.searchParams.append(l, a[l]);
43
+ o.searchParams.append(l, a[l]);
44
44
  });
45
- const i = new Request(n, {
45
+ const i = new Request(o, {
46
46
  mode: "cors",
47
47
  method: "post",
48
48
  headers: {
@@ -65,12 +65,12 @@ async function Rt(e, t, s, r = "", o = {}) {
65
65
  });
66
66
  return fetch(i);
67
67
  }
68
- async function Ut(e, t, s, r = "", o = {}) {
69
- const n = new URL(`${location.origin}/spark/v1/chat/completions`), a = {};
68
+ async function fn(e, t, n, s = "", r = {}) {
69
+ const o = new URL(`${location.origin}/spark/v1/chat/completions`), a = {};
70
70
  Object.keys(a).forEach((l) => {
71
- n.searchParams.append(l, a[l]);
71
+ o.searchParams.append(l, a[l]);
72
72
  });
73
- const i = new Request(n, {
73
+ const i = new Request(o, {
74
74
  method: "post",
75
75
  headers: {
76
76
  "Content-Type": "application/json",
@@ -89,12 +89,12 @@ async function Ut(e, t, s, r = "", o = {}) {
89
89
  });
90
90
  return fetch(i);
91
91
  }
92
- async function _t(e, t, s, r = "", o = {}) {
93
- const n = new URL(`${location.origin}/siliconflow/v1/chat/completions`), a = {};
92
+ async function hn(e, t, n, s = "", r = {}) {
93
+ const o = new URL(`${location.origin}/siliconflow/v1/chat/completions`), a = {};
94
94
  Object.keys(a).forEach((l) => {
95
- n.searchParams.append(l, a[l]);
95
+ o.searchParams.append(l, a[l]);
96
96
  });
97
- const i = new Request(n, {
97
+ const i = new Request(o, {
98
98
  method: "post",
99
99
  headers: {
100
100
  "Content-Type": "application/json",
@@ -114,12 +114,12 @@ async function _t(e, t, s, r = "", o = {}) {
114
114
  });
115
115
  return fetch(i);
116
116
  }
117
- async function Pt(e, t, s, r = "", o = {}) {
118
- const n = new URL(`${location.origin}/moonshot/v1/chat/completions`), a = {};
117
+ async function pn(e, t, n, s = "", r = {}) {
118
+ const o = new URL(`${location.origin}/moonshot/v1/chat/completions`), a = {};
119
119
  Object.keys(a).forEach((l) => {
120
- n.searchParams.append(l, a[l]);
120
+ o.searchParams.append(l, a[l]);
121
121
  });
122
- const i = new Request(n, {
122
+ const i = new Request(o, {
123
123
  method: "post",
124
124
  headers: {
125
125
  "Content-Type": "application/json",
@@ -142,12 +142,12 @@ async function Pt(e, t, s, r = "", o = {}) {
142
142
  });
143
143
  return fetch(i);
144
144
  }
145
- async function Mt(e, t, s, r = "", o = {}) {
146
- const n = new URL(`${location.origin}/dashscope/compatible-mode/v1/chat/completions`), a = {};
145
+ async function mn(e, t, n, s = "", r = {}) {
146
+ const o = new URL(`${location.origin}/dashscope/compatible-mode/v1/chat/completions`), a = {};
147
147
  Object.keys(a).forEach((l) => {
148
- n.searchParams.append(l, a[l]);
148
+ o.searchParams.append(l, a[l]);
149
149
  });
150
- const i = new Request(n, {
150
+ const i = new Request(o, {
151
151
  method: "post",
152
152
  headers: {
153
153
  "Content-Type": "application/json",
@@ -170,8 +170,8 @@ async function Mt(e, t, s, r = "", o = {}) {
170
170
  });
171
171
  return fetch(i);
172
172
  }
173
- async function It(e, t, s, r = "", o = {}) {
174
- const n = Qe(r), a = new URL(`${n}/support/${s}/a`), i = {};
173
+ async function vn(e, t, n, s = "", r = {}) {
174
+ const o = At(s), a = new URL(`${o}/support/${n}/a`), i = {};
175
175
  Object.keys(i).forEach((c) => {
176
176
  a.searchParams.append(c, i[c]);
177
177
  });
@@ -187,7 +187,7 @@ async function It(e, t, s, r = "", o = {}) {
187
187
  });
188
188
  return fetch(l);
189
189
  }
190
- const Et = [
190
+ const gn = [
191
191
  "根据您的问题,我为您整理了以下构件:",
192
192
  "",
193
193
  "```szjy-ui",
@@ -236,18 +236,18 @@ const Et = [
236
236
  "",
237
237
  "点击上方按钮即可在 BIM 沙盘中定位对应构件。"
238
238
  ].join(`
239
- `), jt = 8, zt = 80, Lt = (e) => new Promise((t) => setTimeout(t, e));
240
- function $t(e, t) {
241
- const s = Math.ceil(e.length / t), r = [];
242
- for (let o = 0; o < e.length; o += s)
243
- r.push(e.slice(o, o + s));
244
- return r.length ? r : [""];
245
- }
246
- async function Ot(e, t, s, r = "", o = {}) {
247
- const a = (o && typeof o.mockResponse == "string" ? o.mockResponse.trim() : "") || Et, i = new TextEncoder(), l = new ReadableStream({
239
+ `), yn = 8, wn = 80, bn = (e) => new Promise((t) => setTimeout(t, e));
240
+ function kn(e, t) {
241
+ const n = Math.ceil(e.length / t), s = [];
242
+ for (let r = 0; r < e.length; r += n)
243
+ s.push(e.slice(r, r + n));
244
+ return s.length ? s : [""];
245
+ }
246
+ async function Sn(e, t, n, s = "", r = {}) {
247
+ const a = (r && typeof r.mockResponse == "string" ? r.mockResponse.trim() : "") || gn, i = new TextEncoder(), l = new ReadableStream({
248
248
  async start(c) {
249
- for (const b of $t(a, jt))
250
- c.enqueue(i.encode(b)), await Lt(zt);
249
+ for (const d of kn(a, yn))
250
+ c.enqueue(i.encode(d)), await bn(wn);
251
251
  c.close();
252
252
  }
253
253
  });
@@ -256,7 +256,7 @@ async function Ot(e, t, s, r = "", o = {}) {
256
256
  headers: { "Content-Type": "text/plain; charset=utf-8" }
257
257
  });
258
258
  }
259
- const Nt = (e) => {
259
+ const Cn = (e) => {
260
260
  if (e.startsWith("data:")) {
261
261
  const t = e.substring(5).trim();
262
262
  if (t === "[DONE]")
@@ -265,103 +265,103 @@ const Nt = (e) => {
265
265
  };
266
266
  try {
267
267
  return JSON.parse(t);
268
- } catch (s) {
269
- console.error("JSON parsing error:", s);
268
+ } catch (n) {
269
+ console.error("JSON parsing error:", n);
270
270
  }
271
271
  }
272
272
  return null;
273
- }, Ie = "<think>", Se = "</think>", Ee = (e, t) => {
274
- const s = Math.max(0, e.length - (t.length - 1));
275
- for (let r = s; r < e.length; r++)
276
- if (t.startsWith(e.slice(r)))
277
- return e.length - r;
273
+ }, Ke = "<think>", Ne = "</think>", Ye = (e, t) => {
274
+ const n = Math.max(0, e.length - (t.length - 1));
275
+ for (let s = n; s < e.length; s++)
276
+ if (t.startsWith(e.slice(s)))
277
+ return e.length - s;
278
278
  return 0;
279
- }, Ft = (e) => {
280
- let t = "", s = "", r = e || "", o = !1;
281
- for (; r; ) {
282
- const n = r.indexOf(Ie), a = r.indexOf(Se);
283
- if (n >= 0 && (a < 0 || n < a))
284
- s += r.slice(0, n), r = r.slice(n + Ie.length), o = !0;
285
- else if (a >= 0 && (n < 0 || a < n))
286
- t += r.slice(0, a), r = r.slice(a + Se.length), o = !1;
287
- else if (o) {
288
- const i = Ee(r, Se);
289
- t += r.slice(0, r.length - i), r = "";
279
+ }, An = (e) => {
280
+ let t = "", n = "", s = e || "", r = !1;
281
+ for (; s; ) {
282
+ const o = s.indexOf(Ke), a = s.indexOf(Ne);
283
+ if (o >= 0 && (a < 0 || o < a))
284
+ n += s.slice(0, o), s = s.slice(o + Ke.length), r = !0;
285
+ else if (a >= 0 && (o < 0 || a < o))
286
+ t += s.slice(0, a), s = s.slice(a + Ne.length), r = !1;
287
+ else if (r) {
288
+ const i = Ye(s, Ne);
289
+ t += s.slice(0, s.length - i), s = "";
290
290
  } else {
291
291
  const i = Math.max(
292
- Ee(r, Ie),
293
- Ee(r, Se)
292
+ Ye(s, Ke),
293
+ Ye(s, Ne)
294
294
  );
295
- s += r.slice(0, r.length - i), r = "";
295
+ n += s.slice(0, s.length - i), s = "";
296
296
  }
297
297
  }
298
298
  return {
299
299
  thinking: t.trim(),
300
- content: s.trim(),
301
- isThinkingStreaming: o
300
+ content: n.trim(),
301
+ isThinkingStreaming: r
302
302
  };
303
- }, Ve = [
303
+ }, ct = [
304
304
  {
305
305
  label: "模拟数据模型",
306
306
  modelName: "standard",
307
307
  // 不请求真实后端:流式输出 extraConfig.mockResponse(或内置样例),
308
308
  // 配合 sz-ai-chat 的 mockResponse prop 用于本地联调
309
- api: Ot
309
+ api: Sn
310
310
  },
311
311
  {
312
312
  label: "Spark 星火大模型",
313
313
  modelName: "spark",
314
- api: Ut
314
+ api: fn
315
315
  },
316
316
  {
317
317
  label: "Ollama 3 大模型",
318
318
  modelName: "ollama3",
319
- api: Rt
319
+ api: dn
320
320
  },
321
321
  {
322
322
  label: "SiliconFlow 硅基流动大模型",
323
323
  modelName: "siliconflow",
324
- api: _t
324
+ api: hn
325
325
  },
326
326
  {
327
327
  label: "Kimi Moonshot 月之暗面大模型",
328
328
  modelName: "moonshot",
329
- api: Pt
329
+ api: pn
330
330
  },
331
331
  {
332
332
  label: "通义千问大模型",
333
333
  modelName: "dashscope",
334
- api: Mt
334
+ api: mn
335
335
  },
336
336
  {
337
337
  label: "数智建管大模型",
338
338
  modelName: "szjy",
339
- api: It
339
+ api: vn
340
340
  },
341
341
  {
342
342
  label: "Dify (OpenAI 兼容)",
343
343
  modelName: "dify-openai",
344
- api: Tt
344
+ api: un
345
345
  }
346
- ], He = {
346
+ ], ut = {
347
347
  standard(e, t) {
348
- let s = "";
349
- return e instanceof Uint8Array ? s = t.decode(e, {
348
+ let n = "";
349
+ return e instanceof Uint8Array ? n = t.decode(e, {
350
350
  stream: !0
351
- }) : s = e, {
352
- content: s
351
+ }) : n = e, {
352
+ content: n
353
353
  };
354
354
  },
355
355
  spark(e) {
356
- const t = Nt(e);
356
+ const t = Cn(e);
357
357
  if (t.done)
358
358
  return {
359
359
  done: !0
360
360
  };
361
- const s = t.choices[0].delta, r = s.reasoning_content || s.reasoning;
362
- let o = s.content || "";
363
- return r && (o = `<think>${r}</think>${o}`), {
364
- content: o
361
+ const n = t.choices[0].delta, s = n.reasoning_content || n.reasoning;
362
+ let r = n.content || "";
363
+ return s && (r = `<think>${s}</think>${r}`), {
364
+ content: r
365
365
  };
366
366
  },
367
367
  siliconflow(e) {
@@ -384,47 +384,47 @@ const Nt = (e) => {
384
384
  content: JSON.parse(e).message.content
385
385
  };
386
386
  }
387
- }, De = (e, t, s) => {
388
- const r = e.split(s);
389
- return r.slice(0, -1).forEach((o) => {
390
- o.trim() !== "" && t.enqueue(o);
391
- }), r[r.length - 1];
392
- }, Bt = (e) => {
387
+ }, dt = (e, t, n) => {
388
+ const s = e.split(n);
389
+ return s.slice(0, -1).forEach((r) => {
390
+ r.trim() !== "" && t.enqueue(r);
391
+ }), s[s.length - 1];
392
+ }, Tn = (e) => {
393
393
  let t = "";
394
394
  return new TransformStream({
395
- transform(s, r) {
396
- if (t += s, t.trim().startsWith("data:"))
397
- t = De(t, r, e);
395
+ transform(n, s) {
396
+ if (t += n, t.trim().startsWith("data:"))
397
+ t = dt(t, s, e);
398
398
  else
399
399
  try {
400
- JSON.parse(t), t = De(t, r, e);
400
+ JSON.parse(t), t = dt(t, s, e);
401
401
  } catch {
402
- r.enqueue(s), t = "";
402
+ s.enqueue(n), t = "";
403
403
  }
404
404
  },
405
- flush(s) {
406
- t.trim() !== "" && s.enqueue(t);
405
+ flush(n) {
406
+ t.trim() !== "" && n.enqueue(t);
407
407
  }
408
408
  });
409
409
  };
410
- async function Vt(e, t) {
411
- const s = e.api;
412
- return s ? new Promise((r) => {
413
- s(t.text, t.token, t.identifier, t.baseUrl, t.extraConfig).then((o) => {
414
- if (o.body) {
415
- const n = o.body.pipeThrough(new TextDecoderStream()).pipeThrough(Bt(`
410
+ async function xn(e, t) {
411
+ const n = e.api;
412
+ return n ? new Promise((s) => {
413
+ n(t.text, t.token, t.identifier, t.baseUrl, t.extraConfig).then((r) => {
414
+ if (r.body) {
415
+ const o = r.body.pipeThrough(new TextDecoderStream()).pipeThrough(Tn(`
416
416
  `)).getReader();
417
- console.log("reader from response:", n), r({
417
+ console.log("reader from response:", o), s({
418
418
  error: 0,
419
- reader: n
419
+ reader: o
420
420
  });
421
421
  } else
422
- r({
422
+ s({
423
423
  error: 1,
424
424
  reader: null
425
425
  });
426
426
  }).catch(() => {
427
- r({
427
+ s({
428
428
  error: 1,
429
429
  reader: null
430
430
  });
@@ -434,98 +434,98 @@ async function Vt(e, t) {
434
434
  reader: null
435
435
  };
436
436
  }
437
- const Le = /* @__PURE__ */ new Map(), $e = /* @__PURE__ */ new Map();
438
- function et(e, t) {
439
- Le.set(e, t);
437
+ const et = /* @__PURE__ */ new Map(), tt = /* @__PURE__ */ new Map();
438
+ function Tt(e, t) {
439
+ et.set(e, t);
440
440
  }
441
- function Ht(e, t) {
442
- $e.set(e, t);
441
+ function Rn(e, t) {
442
+ tt.set(e, t);
443
443
  }
444
- function Dt(e) {
445
- return Le.get(e);
444
+ function En(e) {
445
+ return et.get(e);
446
446
  }
447
- function qt(e) {
448
- return Le.has(e);
447
+ function Ln(e) {
448
+ return et.has(e);
449
449
  }
450
- function Wt(e) {
451
- return $e.get(e);
450
+ function Pn(e) {
451
+ return tt.get(e);
452
452
  }
453
- function Gt(e) {
454
- return $e.has(e);
453
+ function Un(e) {
454
+ return tt.has(e);
455
455
  }
456
- const Jt = {
456
+ const Mn = {
457
457
  "&": "&amp;",
458
458
  "<": "&lt;",
459
459
  ">": "&gt;",
460
460
  '"': "&quot;",
461
461
  "'": "&#39;"
462
462
  };
463
- function ve(e) {
464
- return String(e ?? "").replace(/[&<>"']/g, (t) => Jt[t]);
463
+ function Ie(e) {
464
+ return String(e ?? "").replace(/[&<>"']/g, (t) => Mn[t]);
465
465
  }
466
- function Kt(e) {
467
- const s = tt(e, { block: e });
468
- return s ? `<div class="szjy-ui" data-szjy-ui="1">${s}</div>` : "";
466
+ function _n(e) {
467
+ const n = xt(e, { block: e });
468
+ return n ? `<div class="szjy-ui" data-szjy-ui="1">${n}</div>` : "";
469
469
  }
470
- function tt(e, t) {
470
+ function xt(e, t) {
471
471
  if (!e || typeof e != "object" || typeof e.type != "string") return "";
472
- const s = Dt(e.type);
473
- return s ? s(e, t) : "";
472
+ const n = En(e.type);
473
+ return n ? n(e, t) : "";
474
474
  }
475
- function Xt(e) {
475
+ function jn(e) {
476
476
  const t = e.action;
477
477
  if (!t || typeof t != "string") return "";
478
- if (!Gt(t))
479
- return ` disabled title="未知动作:${ve(t)}"`;
480
- const s = e.actionParams === void 0 ? "" : encodeURIComponent(JSON.stringify(e.actionParams ?? null));
481
- return ` data-szjy-ui-action="${ve(t)}" data-szjy-ui-params="${s}"`;
478
+ if (!Un(t))
479
+ return ` disabled title="未知动作:${Ie(t)}"`;
480
+ const n = e.actionParams === void 0 ? "" : encodeURIComponent(JSON.stringify(e.actionParams ?? null));
481
+ return ` data-szjy-ui-action="${Ie(t)}" data-szjy-ui-params="${n}"`;
482
482
  }
483
- function Yt(e) {
483
+ function In(e) {
484
484
  return typeof e == "number" && Number.isFinite(e) && e >= 0 ? `${e}px` : typeof e == "string" && /^\d+(\.\d+)?(px|rem|em|%)?$/.test(e.trim()) ? /^\d+(\.\d+)?$/.test(e.trim()) ? `${e.trim()}px` : e.trim() : "12px";
485
485
  }
486
- function Zt(e, t) {
487
- const s = typeof e.title == "string" && e.title ? `<div class="szjy-ui-list__title">${ve(e.title)}</div>` : "", o = (Array.isArray(e.items) ? e.items : []).map((a) => tt(a, t)).filter(Boolean).map((a) => `<div class="szjy-ui-list__item">${a}</div>`).join(""), n = ve(Yt(e.gap));
488
- return '<div class="szjy-ui-list">' + s + `<div class="szjy-ui-list__items" style="gap:${n}">${o}</div></div>`;
486
+ function zn(e, t) {
487
+ const n = typeof e.title == "string" && e.title ? `<div class="szjy-ui-list__title">${Ie(e.title)}</div>` : "", r = (Array.isArray(e.items) ? e.items : []).map((a) => xt(a, t)).filter(Boolean).map((a) => `<div class="szjy-ui-list__item">${a}</div>`).join(""), o = Ie(In(e.gap));
488
+ return '<div class="szjy-ui-list">' + n + `<div class="szjy-ui-list__items" style="gap:${o}">${r}</div></div>`;
489
489
  }
490
- et("list", Zt);
491
- const Qt = ["default", "primary", "success", "warning", "danger", "info", "text"], en = ["small", "default", "large"];
492
- function tn(e, t) {
493
- const s = e.props, r = s && typeof s == "object" ? s : {}, o = Qt.includes(r.type) ? r.type : "default", n = en.includes(r.size) ? r.size : "default", a = ve(r.content ?? r.text ?? "按钮"), i = Xt(e);
494
- return `<button type="button" class="${["szjy-ui-btn", `szjy-ui-btn--${o}`, `szjy-ui-btn--${n}`].join(" ")}"${i}><span class="szjy-ui-btn__text">${a}</span><span class="szjy-ui-btn__status" aria-live="polite"></span></button>`;
490
+ Tt("list", zn);
491
+ const $n = ["default", "primary", "success", "warning", "danger", "info", "text"], On = ["small", "default", "large"];
492
+ function Bn(e, t) {
493
+ const n = e.props, s = n && typeof n == "object" ? n : {}, r = $n.includes(s.type) ? s.type : "default", o = On.includes(s.size) ? s.size : "default", a = Ie(s.content ?? s.text ?? "按钮"), i = jn(e);
494
+ return `<button type="button" class="${["szjy-ui-btn", `szjy-ui-btn--${r}`, `szjy-ui-btn--${o}`].join(" ")}"${i}><span class="szjy-ui-btn__text">${a}</span><span class="szjy-ui-btn__status" aria-live="polite"></span></button>`;
495
495
  }
496
- et("button", tn);
497
- const nn = 15e3, nt = /未就绪|未加载/, rn = "BIM_SANDBOX", sn = {
496
+ Tt("button", Bn);
497
+ const Nn = 15e3, Rt = /未就绪|未加载/, Vn = "BIM_SANDBOX", Fn = {
498
498
  locateComponent: (e) => [e == null ? void 0 : e.wbsCode],
499
499
  openPDFSearch: () => []
500
500
  };
501
- let on = 0;
502
- function an(e, t) {
503
- let s;
501
+ let Dn = 0;
502
+ function Hn(e, t) {
503
+ let n;
504
504
  if (!e || e === "self")
505
- s = [window];
505
+ n = [window];
506
506
  else if (e === "parent")
507
- s = [window.parent];
507
+ n = [window.parent];
508
508
  else if (e === "top")
509
- s = [window.top];
509
+ n = [window.top];
510
510
  else if (typeof e == "function")
511
511
  try {
512
- s = e(t);
513
- } catch (n) {
514
- console.error("[szjy-ui] 解析 postMessage 目标窗口失败:", n), s = [];
512
+ n = e(t);
513
+ } catch (o) {
514
+ console.error("[szjy-ui] 解析 postMessage 目标窗口失败:", o), n = [];
515
515
  }
516
- else Array.isArray(e) ? s = e : s = [e];
517
- const r = [], o = (n) => {
518
- if (n) {
519
- if (Array.isArray(n)) {
520
- n.forEach(o);
516
+ else Array.isArray(e) ? n = e : n = [e];
517
+ const s = [], r = (o) => {
518
+ if (o) {
519
+ if (Array.isArray(o)) {
520
+ o.forEach(r);
521
521
  return;
522
522
  }
523
- typeof n.postMessage == "function" && !r.includes(n) && r.push(n);
523
+ typeof o.postMessage == "function" && !s.includes(o) && s.push(o);
524
524
  }
525
525
  };
526
- return o(s), r;
526
+ return r(n), s;
527
527
  }
528
- function de(e) {
528
+ function Pe(e) {
529
529
  if (e === window) return `self (${location.origin})`;
530
530
  if (e === window.parent) return "parent";
531
531
  if (e === window.top) return "top";
@@ -535,7 +535,7 @@ function de(e) {
535
535
  return "window (cross-origin)";
536
536
  }
537
537
  }
538
- function ln(e) {
538
+ function qn(e) {
539
539
  try {
540
540
  const t = e.$bimSandbox;
541
541
  return t && typeof t == "object" ? t : null;
@@ -543,52 +543,52 @@ function ln(e) {
543
543
  return null;
544
544
  }
545
545
  }
546
- function cn(e, t, s) {
547
- if (t.type !== rn) return { handled: !1 };
548
- const r = sn[t.action];
549
- if (!r) return { handled: !1 };
550
- const o = ln(e);
551
- if (!o || typeof o[t.action] != "function") return { handled: !1 };
552
- const n = r(t.payload);
546
+ function Wn(e, t, n) {
547
+ if (t.type !== Vn) return { handled: !1 };
548
+ const s = Fn[t.action];
549
+ if (!s) return { handled: !1 };
550
+ const r = qn(e);
551
+ if (!r || typeof r[t.action] != "function") return { handled: !1 };
552
+ const o = s(t.payload);
553
553
  let a;
554
554
  try {
555
- a = o[t.action](...n);
555
+ a = r[t.action](...o);
556
556
  } catch (i) {
557
557
  return console.error("[szjy-ui] $bimSandbox 方法调用异常,回退 postMessage:", i), { handled: !1 };
558
558
  }
559
- return s && console.log("[szjy-ui] $bimSandbox 直调", {
559
+ return n && console.log("[szjy-ui] $bimSandbox 直调", {
560
560
  method: t.action,
561
- args: n,
561
+ args: o,
562
562
  result: a,
563
- target: de(e)
563
+ target: Pe(e)
564
564
  }), { handled: !0, result: a };
565
565
  }
566
- function rt(e, t, s, r, o, n, a) {
566
+ function Et(e, t, n, s, r, o, a) {
567
567
  return (() => {
568
- const { handled: l, result: c } = cn(e, t, a);
569
- return l ? (c && c.success ? n && K(s, "success", c.message || "执行成功") : c && nt.test(String(c.message || "")) && r > 0 ? (a && console.warn(
570
- `[szjy-ui] $bimSandbox 直调失败(${c.message}),${o}ms 后自动重试,剩余 ${r - 1} 次`
571
- ), n && K(s, "retrying", `${c.message},${Math.round(o / 1e3)}s 后自动重试`), setTimeout(() => {
572
- rt(e, t, s, r - 1, o, n, a);
573
- }, o)) : n && K(s, "error", c && c.message || "执行失败"), !0) : !1;
568
+ const { handled: l, result: c } = Wn(e, t, a);
569
+ return l ? (c && c.success ? o && pe(n, "success", c.message || "执行成功") : c && Rt.test(String(c.message || "")) && s > 0 ? (a && console.warn(
570
+ `[szjy-ui] $bimSandbox 直调失败(${c.message}),${r}ms 后自动重试,剩余 ${s - 1} 次`
571
+ ), o && pe(n, "retrying", `${c.message},${Math.round(r / 1e3)}s 后自动重试`), setTimeout(() => {
572
+ Et(e, t, n, s - 1, r, o, a);
573
+ }, r)) : o && pe(n, "error", c && c.message || "执行失败"), !0) : !1;
574
574
  })();
575
575
  }
576
- function un(e) {
577
- const t = dn(e.config), s = !e.config || e.config.debug !== !1, r = t.feedback !== !1, o = t.retry === !1 ? { retries: 0, delay: 2e3 } : { retries: 2, delay: 2e3, ...t.retry || {} };
576
+ function Gn(e) {
577
+ const t = Jn(e.config), n = !e.config || e.config.debug !== !1, s = t.feedback !== !1, r = t.retry === !1 ? { retries: 0, delay: 2e3 } : { retries: 2, delay: 2e3, ...t.retry || {} };
578
578
  if (!e.params || typeof e.params != "object" || Array.isArray(e.params)) {
579
- console.warn("[szjy-ui] postMessage 动作的 actionParams 必须是对象:", e.params), K(e.triggerEl, "error", "参数无效");
579
+ console.warn("[szjy-ui] postMessage 动作的 actionParams 必须是对象:", e.params), pe(e.triggerEl, "error", "参数无效");
580
580
  return;
581
581
  }
582
- const n = { ...e.params }, a = an(t.target, n);
582
+ const o = { ...e.params }, a = Hn(t.target, o);
583
583
  if (!a.length) {
584
- console.warn("[szjy-ui] postMessage 无可用目标窗口,target 配置:", t.target), K(e.triggerEl, "error", "无目标窗口");
584
+ console.warn("[szjy-ui] postMessage 无可用目标窗口,target 配置:", t.target), pe(e.triggerEl, "error", "无目标窗口");
585
585
  return;
586
586
  }
587
587
  const i = t.targetOrigin || "*", l = t.transport || "auto";
588
588
  if (l !== "postMessage") {
589
589
  let c = !1;
590
- for (const b of a)
591
- if (rt(b, n, e.triggerEl, o.retries, o.delay, r, s)) {
590
+ for (const d of a)
591
+ if (Et(d, o, e.triggerEl, r.retries, r.delay, s, n)) {
592
592
  c = !0;
593
593
  break;
594
594
  }
@@ -596,153 +596,153 @@ function un(e) {
596
596
  return;
597
597
  if (l === "global") {
598
598
  console.warn("[szjy-ui] transport=global 但 $bimSandbox 全局方法不可用:", {
599
- targets: a.map(de),
600
- message: n
601
- }), K(e.triggerEl, "error", "全局方法不可用");
599
+ targets: a.map(Pe),
600
+ message: o
601
+ }), pe(e.triggerEl, "error", "全局方法不可用");
602
602
  return;
603
603
  }
604
- s && console.log("[szjy-ui] $bimSandbox 不可用,回退 postMessage 通道");
604
+ n && console.log("[szjy-ui] $bimSandbox 不可用,回退 postMessage 通道");
605
605
  }
606
- n.requestId === void 0 && (n.requestId = `szjy-ui-${Date.now()}-${++on}`), st(a, n, i), s && console.log("[szjy-ui] postMessage 已发送", {
607
- message: n,
608
- targets: a.map(de),
606
+ o.requestId === void 0 && (o.requestId = `szjy-ui-${Date.now()}-${++Dn}`), Lt(a, o, i), n && console.log("[szjy-ui] postMessage 已发送", {
607
+ message: o,
608
+ targets: a.map(Pe),
609
609
  targetOrigin: i,
610
- feedback: r
611
- }), r && (K(e.triggerEl, "loading", "已发送"), fn(n, a, e.triggerEl, i, o, s));
610
+ feedback: s
611
+ }), s && (pe(e.triggerEl, "loading", "已发送"), Kn(o, a, e.triggerEl, i, r, n));
612
612
  }
613
- function dn(e) {
613
+ function Jn(e) {
614
614
  return e && e.postMessage || {};
615
615
  }
616
- function st(e, t, s) {
617
- e.forEach((r) => {
616
+ function Lt(e, t, n) {
617
+ e.forEach((s) => {
618
618
  try {
619
- r.postMessage(t, s);
620
- } catch (o) {
621
- console.error("[szjy-ui] postMessage 发送失败:", o);
619
+ s.postMessage(t, n);
620
+ } catch (r) {
621
+ console.error("[szjy-ui] postMessage 发送失败:", r);
622
622
  }
623
623
  });
624
624
  }
625
- function fn(e, t, s, r, o, n) {
626
- let a = o.retries;
627
- const i = o.delay;
625
+ function Kn(e, t, n, s, r, o) {
626
+ let a = r.retries;
627
+ const i = r.delay;
628
628
  let l = null;
629
629
  const c = () => {
630
630
  window.removeEventListener("message", P), l && (clearTimeout(l), l = null);
631
- }, b = () => {
631
+ }, d = () => {
632
632
  l && clearTimeout(l), l = setTimeout(() => {
633
- c(), n && console.warn("[szjy-ui] postMessage 超时未收到回执", { message: e, targets: t.map(de), targetOrigin: r }), K(s, "none", "未收到回执");
634
- }, nn);
633
+ c(), o && console.warn("[szjy-ui] postMessage 超时未收到回执", { message: e, targets: t.map(Pe), targetOrigin: s }), pe(n, "none", "未收到回执");
634
+ }, Nn);
635
635
  }, P = (A) => {
636
- const p = A.data;
637
- !p || typeof p != "object" || e.type !== void 0 && p.type !== e.type || p.success !== void 0 && (e.requestId !== void 0 && p.requestId !== void 0 && String(p.requestId) !== String(e.requestId) || A.source && !t.includes(A.source) || (n && console.log("[szjy-ui] postMessage 收到回执", {
638
- requestId: p.requestId,
639
- success: p.success,
640
- message: p.message,
641
- data: p.data,
642
- from: de(A.source)
643
- }), p.success ? (c(), K(s, "success", p.message || "执行成功")) : nt.test(String(p.message || "")) && a > 0 ? (a -= 1, n && console.warn(`[szjy-ui] postMessage 回执失败(${p.message}),${i}ms 后自动重试,剩余 ${a} 次`), K(s, "retrying", `${p.message},${Math.round(i / 1e3)}s 后自动重试`), l && clearTimeout(l), setTimeout(() => {
644
- st(t, e, r), n && console.log("[szjy-ui] postMessage 重试已发送", { message: e, targets: t.map(de), targetOrigin: r }), K(s, "loading", "已发送"), b();
645
- }, i)) : (c(), K(s, "error", p.message || "执行失败"))));
636
+ const m = A.data;
637
+ !m || typeof m != "object" || e.type !== void 0 && m.type !== e.type || m.success !== void 0 && (e.requestId !== void 0 && m.requestId !== void 0 && String(m.requestId) !== String(e.requestId) || A.source && !t.includes(A.source) || (o && console.log("[szjy-ui] postMessage 收到回执", {
638
+ requestId: m.requestId,
639
+ success: m.success,
640
+ message: m.message,
641
+ data: m.data,
642
+ from: Pe(A.source)
643
+ }), m.success ? (c(), pe(n, "success", m.message || "执行成功")) : Rt.test(String(m.message || "")) && a > 0 ? (a -= 1, o && console.warn(`[szjy-ui] postMessage 回执失败(${m.message}),${i}ms 后自动重试,剩余 ${a} 次`), pe(n, "retrying", `${m.message},${Math.round(i / 1e3)}s 后自动重试`), l && clearTimeout(l), setTimeout(() => {
644
+ Lt(t, e, s), o && console.log("[szjy-ui] postMessage 重试已发送", { message: e, targets: t.map(Pe), targetOrigin: s }), pe(n, "loading", "已发送"), d();
645
+ }, i)) : (c(), pe(n, "error", m.message || "执行失败"))));
646
646
  };
647
- window.addEventListener("message", P), b();
647
+ window.addEventListener("message", P), d();
648
648
  }
649
- function K(e, t, s) {
649
+ function pe(e, t, n) {
650
650
  if (!e || !e.isConnected) return;
651
- const r = e.querySelector(":scope > .szjy-ui-btn__status");
652
- e.classList.remove("is-loading", "is-success", "is-error", "is-retrying"), t && t !== "none" && e.classList.add(`is-${t}`), r && (r.textContent = s || "");
651
+ const s = e.querySelector(":scope > .szjy-ui-btn__status");
652
+ e.classList.remove("is-loading", "is-success", "is-error", "is-retrying"), t && t !== "none" && e.classList.add(`is-${t}`), s && (s.textContent = n || "");
653
653
  }
654
- Ht("postMessage", un);
655
- const hn = "szjy-ui";
656
- function pn(e) {
654
+ Rn("postMessage", Gn);
655
+ const Yn = "szjy-ui";
656
+ function Xn(e) {
657
657
  if (!e || typeof e != "string") return null;
658
658
  const t = e.trim();
659
659
  if (!t.startsWith("{")) return null;
660
- let s;
660
+ let n;
661
661
  try {
662
- s = JSON.parse(t);
662
+ n = JSON.parse(t);
663
663
  } catch {
664
664
  return null;
665
665
  }
666
- return mn(s);
666
+ return Zn(n);
667
667
  }
668
- function mn(e) {
669
- return !e || typeof e != "object" || Array.isArray(e) || typeof e.type != "string" || !qt(e.type) || e.items !== void 0 && !Array.isArray(e.items) ? null : e;
668
+ function Zn(e) {
669
+ return !e || typeof e != "object" || Array.isArray(e) || typeof e.type != "string" || !Ln(e.type) || e.items !== void 0 && !Array.isArray(e.items) ? null : e;
670
670
  }
671
- function gn(e, t = {}) {
671
+ function Qn(e, t = {}) {
672
672
  if (!e) return () => {
673
673
  };
674
- const s = (r) => {
674
+ const n = (s) => {
675
675
  var A;
676
- const o = r.target, n = o && typeof o.closest == "function" ? o.closest("[data-szjy-ui-action]") : null;
677
- if (!n || !e.contains(n)) return;
678
- const a = n.getAttribute("data-szjy-ui-action") || "", i = Wt(a);
676
+ const r = s.target, o = r && typeof r.closest == "function" ? r.closest("[data-szjy-ui-action]") : null;
677
+ if (!o || !e.contains(o)) return;
678
+ const a = o.getAttribute("data-szjy-ui-action") || "", i = Pn(a);
679
679
  if (!i) {
680
680
  console.warn(`[szjy-ui] 未注册的动作: ${a}`);
681
681
  return;
682
682
  }
683
- const l = n.getAttribute("data-szjy-ui-params");
683
+ const l = o.getAttribute("data-szjy-ui-params");
684
684
  let c = null;
685
685
  if (l)
686
686
  try {
687
687
  c = JSON.parse(decodeURIComponent(l));
688
- } catch (p) {
689
- console.error("[szjy-ui] actionParams 解析失败:", p);
688
+ } catch (m) {
689
+ console.error("[szjy-ui] actionParams 解析失败:", m);
690
690
  return;
691
691
  }
692
- const b = t.getConfig ? t.getConfig() : null;
693
- if (!b || b.debug !== !1) {
694
- const p = (A = n.querySelector(":scope > .szjy-ui-btn__text")) == null ? void 0 : A.textContent;
692
+ const d = t.getConfig ? t.getConfig() : null;
693
+ if (!d || d.debug !== !1) {
694
+ const m = (A = o.querySelector(":scope > .szjy-ui-btn__text")) == null ? void 0 : A.textContent;
695
695
  console.log("[szjy-ui] 动作触发", {
696
696
  action: a,
697
697
  params: c,
698
- text: (p || n.textContent || "").trim().slice(0, 40),
699
- trigger: n
698
+ text: (m || o.textContent || "").trim().slice(0, 40),
699
+ trigger: o
700
700
  });
701
701
  }
702
702
  const P = t.getInterceptor ? t.getInterceptor() : null;
703
- if (!(P && P(a, c, n) === !1)) {
703
+ if (!(P && P(a, c, o) === !1)) {
704
704
  if (t.onAction)
705
705
  try {
706
- t.onAction({ action: a, params: c, triggerEl: n });
707
- } catch (p) {
708
- console.error("[szjy-ui] onAction 回调执行失败:", p);
706
+ t.onAction({ action: a, params: c, triggerEl: o });
707
+ } catch (m) {
708
+ console.error("[szjy-ui] onAction 回调执行失败:", m);
709
709
  }
710
- i({ params: c, config: b, triggerEl: n });
710
+ i({ params: c, config: d, triggerEl: o });
711
711
  }
712
712
  };
713
- return e.addEventListener("click", s), () => {
714
- e.removeEventListener("click", s);
713
+ return e.addEventListener("click", n), () => {
714
+ e.removeEventListener("click", n);
715
715
  };
716
716
  }
717
- let ee = null;
718
- function yn() {
719
- return ee || (window.markdownit ? (ee = new window.markdownit({
717
+ let Ce = null;
718
+ function es() {
719
+ return Ce || (window.markdownit ? (Ce = new window.markdownit({
720
720
  html: !0,
721
721
  linkify: !0,
722
722
  typographer: !0
723
- }), ee.renderer.rules.fence = (e, t) => {
724
- const s = e[t], r = (s.info || "").trim().split(/\s+/)[0];
725
- if (r === hn) {
726
- const n = pn(s.content), a = n ? Kt(n) : "";
723
+ }), Ce.renderer.rules.fence = (e, t) => {
724
+ const n = e[t], s = (n.info || "").trim().split(/\s+/)[0];
725
+ if (s === Yn) {
726
+ const o = Xn(n.content), a = o ? _n(o) : "";
727
727
  if (a)
728
728
  return a;
729
729
  }
730
- let o = "";
731
- if (r && window.hljs && window.hljs.getLanguage(r))
730
+ let r = "";
731
+ if (s && window.hljs && window.hljs.getLanguage(s))
732
732
  try {
733
- o = window.hljs.highlight(s.content, { language: r }).value;
733
+ r = window.hljs.highlight(n.content, { language: s }).value;
734
734
  } catch {
735
- o = "";
735
+ r = "";
736
736
  }
737
- return o || (o = ee.utils.escapeHtml(s.content)), `<pre class="md-code-block"><code class="hljs${r ? " language-" + r : ""}">${o}</code></pre>`;
738
- }) : console.log("markdownit is not loaded"), ee);
739
- }
740
- const vn = (e, t) => {
741
- const s = e.__vccOpts || e;
742
- for (const [r, o] of t)
743
- s[r] = o;
744
- return s;
745
- }, wn = ["src", "alt"], bn = {
737
+ return r || (r = Ce.utils.escapeHtml(n.content)), `<pre class="md-code-block"><code class="hljs${s ? " language-" + s : ""}">${r}</code></pre>`;
738
+ }) : console.log("markdownit is not loaded"), Ce);
739
+ }
740
+ const ts = (e, t) => {
741
+ const n = e.__vccOpts || e;
742
+ for (const [s, r] of t)
743
+ n[s] = r;
744
+ return n;
745
+ }, ns = ["src", "alt"], ss = {
746
746
  __name: "SvgIcon",
747
747
  props: {
748
748
  // 图标名称或完整URL
@@ -772,47 +772,47 @@ const vn = (e, t) => {
772
772
  }
773
773
  },
774
774
  setup(e) {
775
- const t = e, s = N(() => {
775
+ const t = e, n = q(() => {
776
776
  if (t.name.startsWith("http://") || t.name.startsWith("https://") || t.name.startsWith("/"))
777
777
  return t.name;
778
- const n = t.name.endsWith(".svg") ? t.name : `${t.name}.svg`;
779
- return `${t.basePath}${n}`;
780
- }), r = N(() => {
781
- const n = typeof t.size == "number" ? `${t.size}px` : t.size;
778
+ const o = t.name.endsWith(".svg") ? t.name : `${t.name}.svg`;
779
+ return `${t.basePath}${o}`;
780
+ }), s = q(() => {
781
+ const o = typeof t.size == "number" ? `${t.size}px` : t.size;
782
782
  return {
783
- width: n,
784
- height: n,
783
+ width: o,
784
+ height: o,
785
785
  display: "inline-flex",
786
786
  justifyContent: "center",
787
787
  alignItems: "center"
788
788
  };
789
- }), o = N(() => {
790
- const n = {
789
+ }), r = q(() => {
790
+ const o = {
791
791
  width: "100%",
792
792
  height: "100%"
793
793
  };
794
- return t.color && (n.filter = `drop-shadow(0 0 0 ${t.color})`), n;
794
+ return t.color && (o.filter = `drop-shadow(0 0 0 ${t.color})`), o;
795
795
  });
796
- return (n, a) => (S(), x("div", {
796
+ return (o, a) => (T(), L("div", {
797
797
  class: "svg-icon-wrapper",
798
- style: ue(r.value)
798
+ style: ce(s.value)
799
799
  }, [
800
- d("img", {
801
- src: s.value,
800
+ p("img", {
801
+ src: n.value,
802
802
  alt: e.name,
803
- class: re(["svg-icon", e.className]),
804
- style: ue(o.value)
805
- }, null, 14, wn)
803
+ class: le(["svg-icon", e.className]),
804
+ style: ce(r.value)
805
+ }, null, 14, ns)
806
806
  ], 4));
807
807
  }
808
- }, Ce = /* @__PURE__ */ vn(bn, [["__scopeId", "data-v-490b11c1"]]), kn = async (e) => {
808
+ }, Ve = /* @__PURE__ */ ts(ss, [["__scopeId", "data-v-490b11c1"]]), os = async (e) => {
809
809
  if (navigator.clipboard && navigator.permissions)
810
810
  await navigator.clipboard.writeText(e);
811
811
  else {
812
812
  const t = document.createElement("textArea");
813
813
  t.value = e, t.style.width = 0, t.style.position = "fixed", t.style.left = "-999px", t.style.top = "10px", t.setAttribute("readonly", "readonly"), document.body.appendChild(t), t.select(), document.execCommand("copy"), document.body.removeChild(t);
814
814
  }
815
- }, Sn = { class: "thinking-title" }, Cn = { class: "thinking-toggle-hint" }, An = ["innerHTML"], xn = ["innerHTML"], Tn = 10, Rn = {
815
+ }, rs = { class: "thinking-title" }, as = { class: "thinking-toggle-hint" }, is = ["innerHTML"], ls = ["innerHTML"], cs = 10, us = {
816
816
  __name: "Previewer",
817
817
  props: {
818
818
  reader: null,
@@ -841,128 +841,132 @@ const vn = (e, t) => {
841
841
  },
842
842
  emits: [
843
843
  "failed",
844
+ "started",
844
845
  "completed",
845
846
  "updating",
846
847
  "ui-action"
847
848
  ],
848
- setup(e, { expose: t, emit: s }) {
849
- const { appContext: r } = Je(), { $message: o } = r.config.globalProperties, n = e, a = T(n.displayText || ""), i = T(!0), l = T(!1), c = T(!!n.displayText), b = s, P = T(null);
849
+ setup(e, { expose: t, emit: n }) {
850
+ const { appContext: s } = bt(), { $message: r } = s.config.globalProperties, o = e, a = R(o.displayText || ""), i = R(!0), l = R(!1), c = R(!!o.displayText), d = n, P = R(null);
850
851
  let A = null;
851
- Pe(P, (j) => {
852
- A && (A(), A = null), j && (A = gn(j, {
852
+ ye(P, (W) => {
853
+ A && (A(), A = null), W && (A = Qn(W, {
853
854
  // 点击时才读取最新 props,宿主更新 customUi/uiActionHandler 后立即生效
854
- getConfig: () => n.customUi,
855
- getInterceptor: () => n.uiActionHandler,
856
- onAction: (_) => b("ui-action", _)
855
+ getConfig: () => o.customUi,
856
+ getInterceptor: () => o.uiActionHandler,
857
+ onAction: (h) => d("ui-action", h)
857
858
  }));
858
859
  });
859
- let p = null;
860
- const F = N(() => Ft(a.value)), U = N(() => F.value.thinking.length > 0), z = T(n.displayText ? F.value.content.length : 0), y = N(() => F.value.isThinkingStreaming && !c.value), m = T(!1), v = () => {
861
- m.value = !m.value;
860
+ let m = null;
861
+ const S = q(() => An(a.value)), x = q(() => S.value.thinking.length > 0), _ = R(o.displayText ? S.value.content.length : 0), w = q(() => S.value.isThinkingStreaming && !c.value), u = R(!1), k = () => {
862
+ u.value = !u.value;
862
863
  };
863
- let f = null, u = null;
864
- const k = T(0);
865
- Pe(() => F.value.thinking, (j) => {
866
- !j || k.value > 0 || (u === null && (u = f ?? Date.now()), F.value.content && C());
864
+ let v = null, f = null;
865
+ const U = R(0);
866
+ ye(() => S.value.thinking, (W) => {
867
+ !W || U.value > 0 || (f === null && (f = v ?? Date.now()), S.value.content && M());
867
868
  });
868
- const C = () => {
869
- if (k.value > 0 || !U.value) return;
870
- const j = u ?? f;
871
- j && (k.value = Math.max(1, Math.round((Date.now() - j) / 1e3)));
872
- }, L = N(() => y.value ? "正在思考..." : k.value > 0 ? `已深度思考(用时 ${k.value} 秒)` : "思考过程"), R = N(() => U.value ? ee ? ee.render(F.value.thinking) : F.value.thinking : ""), I = N(() => F.value.content.slice(0, z.value)), w = N(() => ee ? ee.render(I.value) : I.value), O = () => {
873
- n.reader && n.reader.cancel(), l.value = !0, q.value = !1, ne(), c.value = !0, C(), b("completed", a.value), i.value = !1, p && (cancelAnimationFrame(p), p = null);
874
- }, X = N(() => `${w.value}`), Y = T(!1), Z = () => {
875
- Y.value = !0;
876
- }, ne = () => {
877
- Y.value = !1;
878
- }, q = T(!1), oe = async () => {
879
- if (!n.reader) return;
880
- const j = new TextDecoder("utf-8");
869
+ const M = () => {
870
+ if (U.value > 0 || !x.value) return;
871
+ const W = f ?? v;
872
+ W && (U.value = Math.max(1, Math.round((Date.now() - W) / 1e3)));
873
+ }, F = q(() => w.value ? "正在思考..." : U.value > 0 ? `已深度思考(用时 ${U.value} 秒)` : "思考过程"), I = q(() => x.value ? Ce ? Ce.render(S.value.thinking) : S.value.thinking : ""), O = q(() => S.value.content.slice(0, _.value)), E = q(() => Ce ? Ce.render(O.value) : O.value), D = () => {
874
+ o.reader && o.reader.cancel(), l.value = !0, X.value = !1, ae(), c.value = !0, M(), d("completed", a.value), i.value = !1, m && (cancelAnimationFrame(m), m = null);
875
+ }, se = q(() => `${E.value}`), K = R(!1), oe = () => {
876
+ K.value = !0;
877
+ }, ae = () => {
878
+ K.value = !1;
879
+ }, X = R(!1), ue = async () => {
880
+ if (!o.reader) return;
881
+ const W = new TextDecoder("utf-8");
881
882
  for (i.value = !0; !l.value; )
882
883
  try {
883
- if (!n.reader) {
884
- q.value = !0;
884
+ if (!o.reader) {
885
+ X.value = !0;
885
886
  break;
886
887
  }
887
- const { value: _, done: V } = await n.reader.read();
888
- if (!n.reader) {
889
- q.value = !0;
888
+ const { value: h, done: j } = await o.reader.read();
889
+ if (!o.reader) {
890
+ X.value = !0;
890
891
  break;
891
892
  }
892
- if (V) {
893
- q.value = !0;
893
+ if (j) {
894
+ X.value = !0;
894
895
  break;
895
896
  }
896
- const ie = He[n.model];
897
- if (!ie)
897
+ const V = ut[o.model];
898
+ if (!V)
898
899
  break;
899
- const G = ie.call(He, _, j);
900
- if (G.done) {
901
- q.value = !0;
900
+ const B = V.call(ut, h, W);
901
+ if (B.done) {
902
+ X.value = !0;
902
903
  break;
903
904
  }
904
- !f && G.content && (f = Date.now()), a.value += G.content, p === null && ae();
905
- } catch (_) {
906
- q.value = !0, console.log(3333, _), b("failed", _), O();
905
+ !v && B.content && (v = Date.now(), d("started")), a.value += B.content, m === null && de();
906
+ } catch (h) {
907
+ X.value = !0, console.log(3333, h), d("failed", h), D();
907
908
  break;
908
909
  } finally {
909
- ne();
910
+ ae();
910
911
  }
911
- }, fe = async () => {
912
- n.scrollToBottomFn && n.scrollToBottomFn();
913
- }, ke = (j = () => {
914
- }, _ = () => {
912
+ }, me = async () => {
913
+ o.scrollToBottomFn && o.scrollToBottomFn();
914
+ }, ve = (W = () => {
915
+ }, h = () => {
915
916
  }) => {
916
- const V = F.value.content.length;
917
- z.value > V && (z.value = V), z.value < V ? (z.value = Math.min(V, z.value + Tn), j()) : _();
918
- }, ae = () => {
919
- if (l.value && p) {
920
- cancelAnimationFrame(p), p = null, i.value = !1;
917
+ const j = S.value.content.length;
918
+ _.value > j && (_.value = j), _.value < j ? (_.value = Math.min(j, _.value + cs), W()) : h();
919
+ }, de = () => {
920
+ if (l.value && m) {
921
+ cancelAnimationFrame(m), m = null, i.value = !1;
921
922
  return;
922
923
  }
923
- q.value ? ke(
924
+ X.value ? ve(
924
925
  () => {
925
- p = requestAnimationFrame(ae), b("updating", null);
926
+ m = requestAnimationFrame(de), d("updating", null);
926
927
  },
927
928
  () => {
928
- C(), b("completed", a.value), i.value = !1, c.value = !0, Ye(() => {
929
- if (q.value = !1, n.messagePostRender && P.value)
929
+ M(), d("completed", a.value), i.value = !1, c.value = !0, Ct(() => {
930
+ if (X.value = !1, o.messagePostRender && P.value)
930
931
  try {
931
- n.messagePostRender(P.value, F.value.content);
932
- } catch (j) {
933
- console.error("messagePostRender 执行失败:", j);
932
+ o.messagePostRender(P.value, S.value.content);
933
+ } catch (W) {
934
+ console.error("messagePostRender 执行失败:", W);
934
935
  }
935
- }), p = null;
936
+ }), m = null;
936
937
  }
937
- ) : (ke(), p = requestAnimationFrame(ae)), fe();
938
+ ) : (ve(), m = requestAnimationFrame(de)), me();
938
939
  };
939
- Pe(
940
- () => n.reader,
940
+ ye(
941
+ () => o.reader,
941
942
  () => {
942
- n.reader && oe();
943
+ o.reader && ue();
943
944
  },
944
945
  {
945
946
  immediate: !0,
946
947
  deep: !0
947
948
  }
948
- ), wt(() => {
949
- A && (A(), A = null), O();
949
+ ), De(() => {
950
+ A && (A(), A = null), D();
950
951
  }), t({
951
- abortReader: O,
952
- initializeStart: Z,
953
- initializeEnd: ne
954
- }), N(() => Y.value ? !0 : (!n.reader || !i || a.value, !1));
955
- const xe = async () => {
952
+ abortReader: D,
953
+ initializeStart: oe,
954
+ initializeEnd: ae,
955
+ // 全双工语音集成(ChatPanel TTS 用):流式原文与中止状态
956
+ getRawText: () => a.value,
957
+ isAborted: () => l.value
958
+ }), q(() => K.value ? !0 : (!o.reader || !i || a.value, !1));
959
+ const Ae = async () => {
956
960
  try {
957
- const j = F.value.content || a.value;
958
- await kn(j), o.success("复制成功");
959
- } catch (j) {
960
- console.error("复制失败:", j), o.error("复制失败");
961
+ const W = S.value.content || a.value;
962
+ await os(W), r.success("复制成功");
963
+ } catch (W) {
964
+ console.error("复制失败:", W), r.error("复制失败");
961
965
  }
962
966
  };
963
- return (j, _) => (S(), ge(ye, { name: "fade" }, {
964
- default: J(() => [
965
- X.value || U.value ? (S(), x("div", {
967
+ return (W, h) => (T(), Se(Le, { name: "fade" }, {
968
+ default: ie(() => [
969
+ se.value || x.value ? (T(), L("div", {
966
970
  key: 0,
967
971
  ref_key: "refWrapperContent",
968
972
  ref: P,
@@ -970,65 +974,65 @@ const vn = (e, t) => {
970
974
  class: "w-full h-full overflow-y-auto relative",
971
975
  "p-24px": ""
972
976
  }, [
973
- U.value ? (S(), x("div", {
977
+ x.value ? (T(), L("div", {
974
978
  key: 0,
975
- class: re(["ai-thinking-block", {
976
- "is-expanded": m.value || y.value,
977
- "is-streaming": y.value
979
+ class: le(["ai-thinking-block", {
980
+ "is-expanded": u.value || w.value,
981
+ "is-streaming": w.value
978
982
  }])
979
983
  }, [
980
- d("div", {
984
+ p("div", {
981
985
  class: "thinking-header",
982
- onClick: v
986
+ onClick: k
983
987
  }, [
984
- _[0] || (_[0] = d("svg", {
988
+ h[0] || (h[0] = p("svg", {
985
989
  class: "thinking-arrow",
986
990
  viewBox: "0 0 1024 1024",
987
991
  width: "10",
988
992
  height: "10"
989
993
  }, [
990
- d("path", {
994
+ p("path", {
991
995
  d: "M704 512 320 256v512z",
992
996
  fill: "currentColor"
993
997
  })
994
998
  ], -1)),
995
- d("span", Sn, W(L.value), 1),
996
- d("span", Cn, W(m.value || y.value ? "收起" : "展开"), 1)
999
+ p("span", rs, Q(F.value), 1),
1000
+ p("span", as, Q(u.value || w.value ? "收起" : "展开"), 1)
997
1001
  ]),
998
- Ke(d("div", {
1002
+ kt(p("div", {
999
1003
  class: "thinking-body",
1000
- innerHTML: R.value
1001
- }, null, 8, An), [
1002
- [Xe, m.value || y.value]
1004
+ innerHTML: I.value
1005
+ }, null, 8, is), [
1006
+ [St, u.value || w.value]
1003
1007
  ])
1004
- ], 2)) : $("", !0),
1005
- d("div", {
1008
+ ], 2)) : H("", !0),
1009
+ p("div", {
1006
1010
  class: "markdown-wrapper",
1007
- innerHTML: X.value
1008
- }, null, 8, xn),
1009
- c.value ? (S(), x("div", {
1011
+ innerHTML: se.value
1012
+ }, null, 8, ls),
1013
+ c.value ? (T(), L("div", {
1010
1014
  key: 1,
1011
1015
  class: "ai-copy-btn-wrapper",
1012
- onClick: xe
1016
+ onClick: Ae
1013
1017
  }, [
1014
- D(Ce, {
1018
+ ne(Ve, {
1015
1019
  name: "/images/svg/copy.svg",
1016
1020
  color: "#666666"
1017
1021
  }),
1018
- _[1] || (_[1] = d("span", { class: "copy-text" }, "复制", -1))
1019
- ])) : $("", !0)
1020
- ], 512)) : $("", !0)
1022
+ h[1] || (h[1] = p("span", { class: "copy-text" }, "复制", -1))
1023
+ ])) : H("", !0)
1024
+ ], 512)) : H("", !0)
1021
1025
  ]),
1022
1026
  _: 1
1023
1027
  }));
1024
1028
  }
1025
1029
  };
1026
- class Un {
1027
- constructor(t, s) {
1028
- M(this, "ratio");
1029
- M(this, "leftover", new Float32Array(0));
1030
- M(this, "fracOffset", 0);
1031
- this.ratio = t / s;
1030
+ class ds {
1031
+ constructor(t, n) {
1032
+ N(this, "ratio");
1033
+ N(this, "leftover", new Float32Array(0));
1034
+ N(this, "fracOffset", 0);
1035
+ this.ratio = t / n;
1032
1036
  }
1033
1037
  reset() {
1034
1038
  this.leftover = new Float32Array(0), this.fracOffset = 0;
@@ -1036,32 +1040,32 @@ class Un {
1036
1040
  process(t) {
1037
1041
  if (this.ratio === 1)
1038
1042
  return new Float32Array(t);
1039
- const s = new Float32Array(this.leftover.length + t.length);
1040
- if (s.set(this.leftover), s.set(t, this.leftover.length), s.length < 2)
1041
- return this.leftover = s, new Float32Array(0);
1042
- const r = [];
1043
- let o = this.fracOffset;
1044
- for (; o < s.length - 1; ) {
1045
- const a = Math.floor(o), i = o - a, l = s[a], c = s[a + 1];
1046
- r.push(l + i * (c - l)), o += this.ratio;
1043
+ const n = new Float32Array(this.leftover.length + t.length);
1044
+ if (n.set(this.leftover), n.set(t, this.leftover.length), n.length < 2)
1045
+ return this.leftover = n, new Float32Array(0);
1046
+ const s = [];
1047
+ let r = this.fracOffset;
1048
+ for (; r < n.length - 1; ) {
1049
+ const a = Math.floor(r), i = r - a, l = n[a], c = n[a + 1];
1050
+ s.push(l + i * (c - l)), r += this.ratio;
1047
1051
  }
1048
- const n = Math.min(s.length, Math.floor(o));
1049
- return this.leftover = s.slice(n), this.fracOffset = o - n, Float32Array.from(r);
1052
+ const o = Math.min(n.length, Math.floor(r));
1053
+ return this.leftover = n.slice(o), this.fracOffset = r - o, Float32Array.from(s);
1050
1054
  }
1051
1055
  }
1052
- class _n {
1056
+ class fs {
1053
1057
  constructor(t = {}) {
1054
- M(this, "targetSampleRate");
1055
- M(this, "audioContext", null);
1056
- M(this, "mediaStream", null);
1057
- M(this, "sourceNode", null);
1058
- M(this, "processorNode", null);
1059
- M(this, "muteGain", null);
1060
- M(this, "resampler", null);
1061
- M(this, "audioChunks", []);
1062
- M(this, "onVolumeChange");
1063
- M(this, "onAudioChunk");
1064
- M(this, "_isRecording", !1);
1058
+ N(this, "targetSampleRate");
1059
+ N(this, "audioContext", null);
1060
+ N(this, "mediaStream", null);
1061
+ N(this, "sourceNode", null);
1062
+ N(this, "processorNode", null);
1063
+ N(this, "muteGain", null);
1064
+ N(this, "resampler", null);
1065
+ N(this, "audioChunks", []);
1066
+ N(this, "onVolumeChange");
1067
+ N(this, "onAudioChunk");
1068
+ N(this, "_isRecording", !1);
1065
1069
  this.targetSampleRate = t.sampleRate || 16e3, this.onVolumeChange = t.onVolumeChange, this.onAudioChunk = t.onAudioChunk;
1066
1070
  }
1067
1071
  get isRecording() {
@@ -1084,8 +1088,8 @@ class _n {
1084
1088
  autoGainControl: !0
1085
1089
  }
1086
1090
  });
1087
- } catch (r) {
1088
- throw r.name === "NotAllowedError" || r.name === "PermissionDeniedError" ? new Error("麦克风权限被拒绝,请在浏览器地址栏允许麦克风访问权限。") : r.name === "NotFoundError" || r.name === "DevicesNotFoundError" ? new Error("未检测到可用的麦克风输入设备。") : new Error(`无法启动麦克风: ${r.message || r}`);
1091
+ } catch (s) {
1092
+ throw s.name === "NotAllowedError" || s.name === "PermissionDeniedError" ? new Error("麦克风权限被拒绝,请在浏览器地址栏允许麦克风访问权限。") : s.name === "NotFoundError" || s.name === "DevicesNotFoundError" ? new Error("未检测到可用的麦克风输入设备。") : new Error(`无法启动麦克风: ${s.message || s}`);
1089
1093
  }
1090
1094
  const t = window.AudioContext || window.webkitAudioContext;
1091
1095
  try {
@@ -1093,21 +1097,21 @@ class _n {
1093
1097
  } catch {
1094
1098
  this.audioContext = new t();
1095
1099
  }
1096
- this.audioContext.state === "suspended" && await this.audioContext.resume(), this.audioChunks = [], this.resampler = this.audioContext.sampleRate === this.targetSampleRate ? null : new Un(this.audioContext.sampleRate, this.targetSampleRate), this.sourceNode = this.audioContext.createMediaStreamSource(this.mediaStream);
1097
- const s = 4096;
1098
- this.processorNode = this.audioContext.createScriptProcessor(s, 1, 1), this.processorNode.onaudioprocess = (r) => {
1100
+ this.audioContext.state === "suspended" && await this.audioContext.resume(), this.audioChunks = [], this.resampler = this.audioContext.sampleRate === this.targetSampleRate ? null : new ds(this.audioContext.sampleRate, this.targetSampleRate), this.sourceNode = this.audioContext.createMediaStreamSource(this.mediaStream);
1101
+ const n = 4096;
1102
+ this.processorNode = this.audioContext.createScriptProcessor(n, 1, 1), this.processorNode.onaudioprocess = (s) => {
1099
1103
  var a;
1100
1104
  if (!this._isRecording) return;
1101
- const o = new Float32Array(r.inputBuffer.getChannelData(0));
1105
+ const r = new Float32Array(s.inputBuffer.getChannelData(0));
1102
1106
  if (this.onVolumeChange) {
1103
1107
  let i = 0;
1104
- for (let b = 0; b < o.length; b++)
1105
- i += o[b] * o[b];
1106
- const l = Math.sqrt(i / o.length), c = Math.min(100, Math.round(l * 100 * 5));
1108
+ for (let d = 0; d < r.length; d++)
1109
+ i += r[d] * r[d];
1110
+ const l = Math.sqrt(i / r.length), c = Math.min(100, Math.round(l * 100 * 5));
1107
1111
  this.onVolumeChange(c);
1108
1112
  }
1109
- const n = this.resampler ? this.resampler.process(o) : o;
1110
- n.length && (this.audioChunks.push(n), (a = this.onAudioChunk) == null || a.call(this, n));
1113
+ const o = this.resampler ? this.resampler.process(r) : r;
1114
+ o.length && (this.audioChunks.push(o), (a = this.onAudioChunk) == null || a.call(this, o));
1111
1115
  }, this.muteGain = this.audioContext.createGain(), this.muteGain.gain.value = 0, this.sourceNode.connect(this.processorNode), this.processorNode.connect(this.muteGain), this.muteGain.connect(this.audioContext.destination), this._isRecording = !0;
1112
1116
  }
1113
1117
  /**
@@ -1117,11 +1121,11 @@ class _n {
1117
1121
  if (!this._isRecording)
1118
1122
  return new Float32Array(0);
1119
1123
  this._isRecording = !1, this.cleanup();
1120
- const t = this.audioChunks.reduce((o, n) => o + n.length, 0), s = new Float32Array(t);
1121
- let r = 0;
1122
- for (const o of this.audioChunks)
1123
- s.set(o, r), r += o.length;
1124
- return this.audioChunks = [], s;
1124
+ const t = this.audioChunks.reduce((r, o) => r + o.length, 0), n = new Float32Array(t);
1125
+ let s = 0;
1126
+ for (const r of this.audioChunks)
1127
+ n.set(r, s), s += r.length;
1128
+ return this.audioChunks = [], n;
1125
1129
  }
1126
1130
  /**
1127
1131
  * 取消录音并丢弃采集的数据
@@ -1134,99 +1138,99 @@ class _n {
1134
1138
  }), this.audioContext = null);
1135
1139
  }
1136
1140
  }
1137
- function Pn(e, t, s) {
1138
- if (t === s)
1141
+ function hs(e, t, n) {
1142
+ if (t === n)
1139
1143
  return new Float32Array(e);
1140
- const r = t / s, o = Math.round(e.length / r), n = new Float32Array(o);
1141
- for (let a = 0; a < o; a++) {
1142
- const i = a * r, l = Math.floor(i), c = i - l, b = e[l] ?? 0, P = e[l + 1] ?? b;
1143
- n[a] = b + c * (P - b);
1144
+ const s = t / n, r = Math.round(e.length / s), o = new Float32Array(r);
1145
+ for (let a = 0; a < r; a++) {
1146
+ const i = a * s, l = Math.floor(i), c = i - l, d = e[l] ?? 0, P = e[l + 1] ?? d;
1147
+ o[a] = d + c * (P - d);
1144
1148
  }
1145
- return n;
1149
+ return o;
1146
1150
  }
1147
- async function Mn(e, t = 16e3) {
1148
- const s = await e.arrayBuffer(), r = window.AudioContext || window.webkitAudioContext, o = new r();
1151
+ async function ps(e, t = 16e3) {
1152
+ const n = await e.arrayBuffer(), s = window.AudioContext || window.webkitAudioContext, r = new s();
1149
1153
  try {
1150
- const n = await o.decodeAudioData(s);
1154
+ const o = await r.decodeAudioData(n);
1151
1155
  let a;
1152
- if (n.numberOfChannels > 1) {
1153
- a = new Float32Array(n.length);
1154
- for (let i = 0; i < n.numberOfChannels; i++) {
1155
- const l = n.getChannelData(i);
1156
- for (let c = 0; c < n.length; c++)
1157
- a[c] += l[c] / n.numberOfChannels;
1156
+ if (o.numberOfChannels > 1) {
1157
+ a = new Float32Array(o.length);
1158
+ for (let i = 0; i < o.numberOfChannels; i++) {
1159
+ const l = o.getChannelData(i);
1160
+ for (let c = 0; c < o.length; c++)
1161
+ a[c] += l[c] / o.numberOfChannels;
1158
1162
  }
1159
1163
  } else
1160
- a = n.getChannelData(0);
1161
- return Pn(a, n.sampleRate, t);
1164
+ a = o.getChannelData(0);
1165
+ return hs(a, o.sampleRate, t);
1162
1166
  } finally {
1163
- o.state !== "closed" && await o.close().catch(() => {
1167
+ r.state !== "closed" && await r.close().catch(() => {
1164
1168
  });
1165
1169
  }
1166
1170
  }
1167
- function qe(e, t = 16e3) {
1168
- const s = new ArrayBuffer(44 + e.length * 2), r = new DataView(s), o = (a, i) => {
1171
+ function ft(e, t = 16e3) {
1172
+ const n = new ArrayBuffer(44 + e.length * 2), s = new DataView(n), r = (a, i) => {
1169
1173
  for (let l = 0; l < i.length; l++)
1170
- r.setUint8(a + l, i.charCodeAt(l));
1174
+ s.setUint8(a + l, i.charCodeAt(l));
1171
1175
  };
1172
- o(0, "RIFF"), r.setUint32(4, 36 + e.length * 2, !0), o(8, "WAVE"), o(12, "fmt "), r.setUint32(16, 16, !0), r.setUint16(20, 1, !0), r.setUint16(22, 1, !0), r.setUint32(24, t, !0), r.setUint32(28, t * 2, !0), r.setUint16(32, 2, !0), r.setUint16(34, 16, !0), o(36, "data"), r.setUint32(40, e.length * 2, !0);
1173
- let n = 44;
1174
- for (let a = 0; a < e.length; a++, n += 2) {
1176
+ r(0, "RIFF"), s.setUint32(4, 36 + e.length * 2, !0), r(8, "WAVE"), r(12, "fmt "), s.setUint32(16, 16, !0), s.setUint16(20, 1, !0), s.setUint16(22, 1, !0), s.setUint32(24, t, !0), s.setUint32(28, t * 2, !0), s.setUint16(32, 2, !0), s.setUint16(34, 16, !0), r(36, "data"), s.setUint32(40, e.length * 2, !0);
1177
+ let o = 44;
1178
+ for (let a = 0; a < e.length; a++, o += 2) {
1175
1179
  const i = Math.max(-1, Math.min(1, e[a]));
1176
- r.setInt16(n, i < 0 ? i * 32768 : i * 32767, !0);
1180
+ s.setInt16(o, i < 0 ? i * 32768 : i * 32767, !0);
1177
1181
  }
1178
- return new Blob([r], { type: "audio/wav" });
1182
+ return new Blob([s], { type: "audio/wav" });
1179
1183
  }
1180
- const ot = 16e3, In = Math.round(ot * 0.35), at = "/scripts/ai/whisper.worker.js";
1181
- function En() {
1182
- return new Worker(je(at), { type: "module" });
1184
+ const Pt = 16e3, ms = Math.round(Pt * 0.35), Ut = "/scripts/ai/whisper.worker.js";
1185
+ function vs() {
1186
+ return new Worker(Ze(Ut), { type: "module" });
1183
1187
  }
1184
- function je(e) {
1188
+ function Ze(e) {
1185
1189
  return /^https?:\/\//i.test(e) ? e : typeof location < "u" ? new URL(e, location.origin).href : e;
1186
1190
  }
1187
- function We(e) {
1191
+ function ht(e) {
1188
1192
  if (!e.ok) return !1;
1189
1193
  const t = (e.headers.get("content-type") || "").toLowerCase();
1190
1194
  return !(t.includes("text/html") || t.includes("application/xhtml+xml"));
1191
1195
  }
1192
- async function jn(e) {
1196
+ async function gs(e) {
1193
1197
  try {
1194
1198
  const t = await fetch(e, { method: "HEAD" });
1195
- if (We(t)) return !0;
1199
+ if (ht(t)) return !0;
1196
1200
  } catch {
1197
1201
  }
1198
1202
  try {
1199
1203
  const t = await fetch(e, { headers: { Range: "bytes=0-64" } });
1200
- if (We(t)) return !0;
1204
+ if (ht(t)) return !0;
1201
1205
  } catch {
1202
1206
  }
1203
1207
  return !1;
1204
1208
  }
1205
- async function zn(e) {
1209
+ async function ys(e) {
1206
1210
  const t = [];
1207
- e && t.push(je(e)), t.push(je(at));
1208
- const s = [...new Set(t.filter(Boolean))];
1209
- for (const r of s)
1210
- if (await jn(r))
1211
- return console.log("[VoiceInputManager] 使用语音 Worker:", r), r;
1211
+ e && t.push(Ze(e)), t.push(Ze(Ut));
1212
+ const n = [...new Set(t.filter(Boolean))];
1213
+ for (const s of n)
1214
+ if (await gs(s))
1215
+ return console.log("[VoiceInputManager] 使用语音 Worker:", s), s;
1212
1216
  return console.warn(
1213
1217
  "[VoiceInputManager] 未探测到可访问的 Worker 脚本,将回退到 Vite 打包注入地址。已尝试:",
1214
- s.join(" , ")
1218
+ n.join(" , ")
1215
1219
  ), null;
1216
1220
  }
1217
- class Ln {
1221
+ class ws {
1218
1222
  constructor(t = {}) {
1219
- M(this, "recorder", null);
1220
- M(this, "worker", null);
1221
- M(this, "status", "idle");
1222
- M(this, "options");
1223
- M(this, "isReady", !1);
1224
- M(this, "initPromise", null);
1225
- M(this, "currentTaskId", 0);
1226
- M(this, "pcmParts", []);
1227
- M(this, "pcmLength", 0);
1228
- M(this, "streamChunkIndex", 0);
1229
- M(this, "committedText", "");
1223
+ N(this, "recorder", null);
1224
+ N(this, "worker", null);
1225
+ N(this, "status", "idle");
1226
+ N(this, "options");
1227
+ N(this, "isReady", !1);
1228
+ N(this, "initPromise", null);
1229
+ N(this, "currentTaskId", 0);
1230
+ N(this, "pcmParts", []);
1231
+ N(this, "pcmLength", 0);
1232
+ N(this, "streamChunkIndex", 0);
1233
+ N(this, "committedText", "");
1230
1234
  this.options = {
1231
1235
  soundBaseUrl: "/sounds/",
1232
1236
  remoteHost: "https://hf-mirror.com",
@@ -1246,17 +1250,17 @@ class Ln {
1246
1250
  */
1247
1251
  async init(t) {
1248
1252
  if (!this.isReady)
1249
- return this.initPromise ? this.initPromise : (t && (this.options.soundBaseUrl = t), this.initPromise = new Promise((s, r) => {
1253
+ return this.initPromise ? this.initPromise : (t && (this.options.soundBaseUrl = t), this.initPromise = new Promise((n, s) => {
1250
1254
  this.setStatus("loading", "正在准备语音识别引擎..."), (async () => {
1251
- var n, a;
1255
+ var o, a;
1252
1256
  try {
1253
- const i = await zn(this.options.workerUrl);
1254
- this.worker = i ? new Worker(i, { type: "module" }) : En(), this.worker.onmessage = (l) => {
1255
- this.handleWorkerMessage(l, s, r);
1257
+ const i = await ys(this.options.workerUrl);
1258
+ this.worker = i ? new Worker(i, { type: "module" }) : vs(), this.worker.onmessage = (l) => {
1259
+ this.handleWorkerMessage(l, n, s);
1256
1260
  }, this.worker.onerror = (l) => {
1257
1261
  var P, A;
1258
- const b = `语音后台线程异常: ${l.message || l.filename || i || "未知错误"}`;
1259
- this.initPromise = null, this.setStatus("error", b), (A = (P = this.options).onError) == null || A.call(P, b), r(l);
1262
+ const d = `语音后台线程异常: ${l.message || l.filename || i || "未知错误"}`;
1263
+ this.initPromise = null, this.setStatus("error", d), (A = (P = this.options).onError) == null || A.call(P, d), s(l);
1260
1264
  }, this.worker.postMessage({
1261
1265
  type: "INIT",
1262
1266
  data: {
@@ -1267,7 +1271,7 @@ class Ln {
1267
1271
  });
1268
1272
  } catch (i) {
1269
1273
  const l = `创建语音 Worker 失败: ${i.message || i}`;
1270
- this.initPromise = null, this.setStatus("error", l), (a = (n = this.options).onError) == null || a.call(n, l), r(i);
1274
+ this.initPromise = null, this.setStatus("error", l), (a = (o = this.options).onError) == null || a.call(o, l), s(i);
1271
1275
  }
1272
1276
  })();
1273
1277
  }), this.initPromise);
@@ -1276,94 +1280,94 @@ class Ln {
1276
1280
  * 开始语音录入(只采集,点「完成」后再转写)
1277
1281
  */
1278
1282
  async startRecording() {
1279
- var t, s, r, o;
1283
+ var t, n, s, r;
1280
1284
  if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
1281
- const n = window.isSecureContext ? "当前浏览器环境不支持获取麦克风音频,请使用现代浏览器。" : "当前页面不是安全上下文,浏览器禁止调用麦克风。请使用 https:// 或 http://localhost / http://127.0.0.1 访问(通过局域网 IP 的 http 地址无法录音)。";
1282
- throw this.setStatus("error", n), (s = (t = this.options).onError) == null || s.call(t, n), new Error(n);
1285
+ const o = window.isSecureContext ? "当前浏览器环境不支持获取麦克风音频,请使用现代浏览器。" : "当前页面不是安全上下文,浏览器禁止调用麦克风。请使用 https:// 或 http://localhost / http://127.0.0.1 访问(通过局域网 IP 的 http 地址无法录音)。";
1286
+ throw this.setStatus("error", o), (n = (t = this.options).onError) == null || n.call(t, o), new Error(o);
1283
1287
  }
1284
- this.isReady || await this.init(), this.recorder || (this.recorder = new _n({
1285
- onVolumeChange: (n) => {
1288
+ this.isReady || await this.init(), this.recorder || (this.recorder = new fs({
1289
+ onVolumeChange: (o) => {
1286
1290
  var a, i;
1287
- (i = (a = this.options).onVolumeChange) == null || i.call(a, n);
1291
+ (i = (a = this.options).onVolumeChange) == null || i.call(a, o);
1288
1292
  },
1289
- onAudioChunk: (n) => {
1290
- this.appendPcm(n);
1293
+ onAudioChunk: (o) => {
1294
+ this.appendPcm(o);
1291
1295
  }
1292
1296
  }));
1293
1297
  try {
1294
1298
  this.currentTaskId++, this.resetStreamState(), await this.recorder.start(), this.setStatus("recording", "正在录音...");
1295
- } catch (n) {
1296
- throw this.setStatus("error", n.message || "启动录音失败"), (o = (r = this.options).onError) == null || o.call(r, n.message || "启动录音失败"), n;
1299
+ } catch (o) {
1300
+ throw this.setStatus("error", o.message || "启动录音失败"), (r = (s = this.options).onError) == null || r.call(s, o.message || "启动录音失败"), o;
1297
1301
  }
1298
1302
  }
1299
1303
  /**
1300
1304
  * 停止录音并触发模型端侧推理
1301
1305
  */
1302
1306
  async stopAndTranscribe() {
1303
- var t, s, r, o;
1307
+ var t, n, s, r;
1304
1308
  if (!(!this.recorder || !this.recorder.isRecording))
1305
1309
  try {
1306
1310
  await this.recorder.stop();
1307
- const n = this.mergePcm();
1308
- if (n.length === 0) {
1311
+ const o = this.mergePcm();
1312
+ if (o.length === 0) {
1309
1313
  this.resetStreamState(), this.setStatus("idle");
1310
1314
  return;
1311
1315
  }
1312
1316
  this.setStatus("transcribing", "正在识别语音...");
1313
1317
  try {
1314
- const a = qe(n), i = URL.createObjectURL(a);
1315
- (s = (t = this.options).onAudioRecorded) == null || s.call(t, i, a);
1318
+ const a = ft(o), i = URL.createObjectURL(a);
1319
+ (n = (t = this.options).onAudioRecorded) == null || n.call(t, i, a);
1316
1320
  } catch (a) {
1317
1321
  console.warn("生成录音回放音频失败:", a);
1318
1322
  }
1319
- await this.transcribeAudioData(n);
1320
- } catch (n) {
1321
- this.setStatus("error", n.message || "音频处理失败"), (o = (r = this.options).onError) == null || o.call(r, n.message || "音频处理失败");
1323
+ await this.transcribeAudioData(o);
1324
+ } catch (o) {
1325
+ this.setStatus("error", o.message || "音频处理失败"), (r = (s = this.options).onError) == null || r.call(s, o.message || "音频处理失败");
1322
1326
  }
1323
1327
  }
1324
1328
  /**
1325
1329
  * 直接对外部传入的 16kHz Float32Array 音频进行端侧推理(例如文件上传)
1326
1330
  */
1327
- async transcribeAudioData(t, s) {
1328
- var r, o, n, a;
1331
+ async transcribeAudioData(t, n) {
1332
+ var s, r, o, a;
1329
1333
  this.isReady || await this.init(), this.setStatus("transcribing", "正在流式识别音频...");
1330
1334
  try {
1331
- s && ((o = (r = this.options).onAudioRecorded) == null || o.call(r, s, qe(t))), this.currentTaskId++, this.resetStreamState(), this.appendPcm(t), this.dispatchFullAudio();
1335
+ n && ((r = (s = this.options).onAudioRecorded) == null || r.call(s, n, ft(t))), this.currentTaskId++, this.resetStreamState(), this.appendPcm(t), this.dispatchFullAudio();
1332
1336
  } catch (i) {
1333
- this.setStatus("error", i.message || "音频处理失败"), (a = (n = this.options).onError) == null || a.call(n, i.message || "音频处理失败");
1337
+ this.setStatus("error", i.message || "音频处理失败"), (a = (o = this.options).onError) == null || a.call(o, i.message || "音频处理失败");
1334
1338
  }
1335
1339
  }
1336
1340
  /**
1337
1341
  * 上传音频/视频文件(支持 mp4, wav, mp3, m4a 等)并在浏览器端解析识别
1338
1342
  */
1339
1343
  async transcribeFile(t) {
1340
- var s, r;
1344
+ var n, s;
1341
1345
  this.isReady || await this.init(), this.setStatus("loading", "正在解析音频文件...");
1342
1346
  try {
1343
- const o = await Mn(t);
1344
- if (o.length === 0)
1347
+ const r = await ps(t);
1348
+ if (r.length === 0)
1345
1349
  throw new Error("未能从该文件中提取出有效音频");
1346
- const n = URL.createObjectURL(t);
1347
- await this.transcribeAudioData(o, n);
1348
- } catch (o) {
1349
- this.setStatus("error", o.message || "音频文件解析失败"), (r = (s = this.options).onError) == null || r.call(s, o.message || "音频文件解析失败");
1350
+ const o = URL.createObjectURL(t);
1351
+ await this.transcribeAudioData(r, o);
1352
+ } catch (r) {
1353
+ this.setStatus("error", r.message || "音频文件解析失败"), (s = (n = this.options).onError) == null || s.call(n, r.message || "音频文件解析失败");
1350
1354
  }
1351
1355
  }
1352
1356
  /**
1353
1357
  * 取消当前录音并丢弃
1354
1358
  */
1355
1359
  cancelRecording() {
1356
- var s;
1360
+ var n;
1357
1361
  const t = this.currentTaskId;
1358
- this.currentTaskId++, (s = this.worker) == null || s.postMessage({ type: "CANCEL", taskId: t }), this.resetStreamState(), this.recorder && this.recorder.cancel(), this.setStatus("idle");
1362
+ this.currentTaskId++, (n = this.worker) == null || n.postMessage({ type: "CANCEL", taskId: t }), this.resetStreamState(), this.recorder && this.recorder.cancel(), this.setStatus("idle");
1359
1363
  }
1360
1364
  /**
1361
1365
  * 取消当前的语音识别推理任务
1362
1366
  */
1363
1367
  cancelTranscribe() {
1364
- var s;
1368
+ var n;
1365
1369
  const t = this.currentTaskId;
1366
- this.currentTaskId++, (s = this.worker) == null || s.postMessage({ type: "CANCEL", taskId: t }), this.resetStreamState(), (this.status === "transcribing" || this.status === "recording") && this.setStatus("idle");
1370
+ this.currentTaskId++, (n = this.worker) == null || n.postMessage({ type: "CANCEL", taskId: t }), this.resetStreamState(), (this.status === "transcribing" || this.status === "recording") && this.setStatus("idle");
1367
1371
  }
1368
1372
  /**
1369
1373
  * 清除本地模型缓存
@@ -1375,9 +1379,9 @@ class Ln {
1375
1379
  * 销毁并释放所有资源
1376
1380
  */
1377
1381
  destroy() {
1378
- var s;
1382
+ var n;
1379
1383
  const t = this.currentTaskId;
1380
- this.currentTaskId++, (s = this.worker) == null || s.postMessage({ type: "CANCEL", taskId: t }), this.resetStreamState(), this.recorder && (this.recorder.cancel(), this.recorder = null), this.worker && (this.worker.terminate(), this.worker = null), this.isReady = !1, this.initPromise = null, this.setStatus("idle");
1384
+ this.currentTaskId++, (n = this.worker) == null || n.postMessage({ type: "CANCEL", taskId: t }), this.resetStreamState(), this.recorder && (this.recorder.cancel(), this.recorder = null), this.worker && (this.worker.terminate(), this.worker = null), this.isReady = !1, this.initPromise = null, this.setStatus("idle");
1381
1385
  }
1382
1386
  resetStreamState() {
1383
1387
  this.pcmParts = [], this.pcmLength = 0, this.streamChunkIndex = 0, this.committedText = "";
@@ -1387,19 +1391,19 @@ class Ln {
1387
1391
  }
1388
1392
  mergePcm() {
1389
1393
  const t = new Float32Array(this.pcmLength);
1390
- let s = 0;
1391
- for (const r of this.pcmParts)
1392
- t.set(r, s), s += r.length;
1394
+ let n = 0;
1395
+ for (const s of this.pcmParts)
1396
+ t.set(s, n), n += s.length;
1393
1397
  return t;
1394
1398
  }
1395
1399
  emitPartial(t) {
1396
- var s, r;
1397
- (r = (s = this.options).onPartial) == null || r.call(s, (t || "").trim());
1400
+ var n, s;
1401
+ (s = (n = this.options).onPartial) == null || s.call(n, (t || "").trim());
1398
1402
  }
1399
1403
  finishStream(t) {
1400
- var r, o;
1401
- const s = (t ?? this.committedText).trim();
1402
- this.setStatus("idle"), (o = (r = this.options).onResult) == null || o.call(r, s);
1404
+ var s, r;
1405
+ const n = (t ?? this.committedText).trim();
1406
+ this.setStatus("idle"), (r = (s = this.options).onResult) == null || r.call(s, n);
1403
1407
  }
1404
1408
  /**
1405
1409
  * 录音结束或上传:整段一次送入 Worker。超过 30s 由 Worker 按重叠窗口切分。
@@ -1409,11 +1413,11 @@ class Ln {
1409
1413
  this.finishStream();
1410
1414
  return;
1411
1415
  }
1412
- if (this.pcmLength < In) {
1416
+ if (this.pcmLength < ms) {
1413
1417
  this.finishStream();
1414
1418
  return;
1415
1419
  }
1416
- const t = this.mergePcm(), s = t.length > ot * 30;
1420
+ const t = this.mergePcm(), n = t.length > Pt * 30;
1417
1421
  this.committedText = "", this.worker.postMessage(
1418
1422
  {
1419
1423
  type: "TRANSCRIBE",
@@ -1425,28 +1429,28 @@ class Ln {
1425
1429
  chunkIndex: this.streamChunkIndex++,
1426
1430
  isFinal: !0,
1427
1431
  mode: "append",
1428
- nativeChunking: s
1432
+ nativeChunking: n
1429
1433
  }
1430
1434
  },
1431
1435
  [t.buffer]
1432
1436
  );
1433
1437
  }
1434
- handleWorkerMessage(t, s, r) {
1435
- var c, b, P, A;
1436
- const { type: o, data: n, taskId: a, text: i, error: l } = t.data;
1437
- switch (o) {
1438
+ handleWorkerMessage(t, n, s) {
1439
+ var c, d, P, A;
1440
+ const { type: r, data: o, taskId: a, text: i, error: l } = t.data;
1441
+ switch (r) {
1438
1442
  case "READY":
1439
- this.isReady = !0, this.setStatus("ready", "语音引擎就绪"), s == null || s();
1443
+ this.isReady = !0, this.setStatus("ready", "语音引擎就绪"), n == null || n();
1440
1444
  break;
1441
1445
  case "PROGRESS":
1442
- if (n) {
1443
- const p = typeof n.progress == "number" ? Math.round(n.progress) : 0;
1444
- this.setStatus("downloading", `正在下载语音模型... ${p}%`), (b = (c = this.options).onProgress) == null || b.call(c, {
1445
- status: n.status || "progress",
1446
- progress: p,
1447
- file: n.file,
1448
- loaded: n.loaded,
1449
- total: n.total
1446
+ if (o) {
1447
+ const m = typeof o.progress == "number" ? Math.round(o.progress) : 0;
1448
+ this.setStatus("downloading", `正在下载语音模型... ${m}%`), (d = (c = this.options).onProgress) == null || d.call(c, {
1449
+ status: o.status || "progress",
1450
+ progress: m,
1451
+ file: o.file,
1452
+ loaded: o.loaded,
1453
+ total: o.total
1450
1454
  });
1451
1455
  }
1452
1456
  break;
@@ -1468,63 +1472,1056 @@ class Ln {
1468
1472
  break;
1469
1473
  case "ERROR":
1470
1474
  if (a && a !== this.currentTaskId) return;
1471
- this.setStatus("error", l || "语音服务异常"), (A = (P = this.options).onError) == null || A.call(P, l || "语音服务异常"), r == null || r(new Error(l));
1475
+ this.setStatus("error", l || "语音服务异常"), (A = (P = this.options).onError) == null || A.call(P, l || "语音服务异常"), s == null || s(new Error(l));
1472
1476
  break;
1473
1477
  }
1474
1478
  }
1475
- setStatus(t, s) {
1476
- var r, o;
1477
- this.status = t, (o = (r = this.options).onStatusChange) == null || o.call(r, t, s);
1479
+ setStatus(t, n) {
1480
+ var s, r;
1481
+ this.status = t, (r = (s = this.options).onStatusChange) == null || r.call(s, t, n);
1482
+ }
1483
+ }
1484
+ const xe = 16e3, pt = 0.015, bs = 0.25, ks = 2e3, mt = 3e4, Ss = 250, vt = 350, Cs = 0.25, As = 900, Ts = 0.5, xs = 12, gt = 1024, Rs = 260, Es = 600, Ls = 80, Mt = 28, nt = "/api/voice", sr = {
1485
+ filterLength: 256,
1486
+ delay: 64,
1487
+ step: 0.1,
1488
+ epsilon: 1e-6
1489
+ }, Ps = 256, Us = 64, Ms = 0.1, _s = 1e-6;
1490
+ class js {
1491
+ constructor(t = {}) {
1492
+ N(this, "w");
1493
+ N(this, "xBuf");
1494
+ N(this, "filterLength");
1495
+ N(this, "delay");
1496
+ N(this, "mu");
1497
+ N(this, "eps");
1498
+ /** Ring cursor into xBuf (reference history). */
1499
+ N(this, "cursor", 0);
1500
+ /** How many reference samples we have buffered so far (for warm-up). */
1501
+ N(this, "filled", 0);
1502
+ this.filterLength = t.filterLength ?? Ps, this.delay = t.delay ?? Us, this.mu = t.step ?? Ms, this.eps = t.epsilon ?? _s, this.w = new Float32Array(this.filterLength), this.xBuf = new Float32Array(this.delay + this.filterLength);
1503
+ }
1504
+ /**
1505
+ * Push the next mic/reference block; returns the echo-removed mic samples
1506
+ * (same length as the input). Reference may be shorter than the mic block
1507
+ * (e.g. silence pad) — it is zero-filled to the block length.
1508
+ */
1509
+ process(t, n) {
1510
+ const s = t.length, r = new Float32Array(s);
1511
+ if (s === 0) return r;
1512
+ const o = this.xBuf, a = o.length;
1513
+ let i = this.cursor;
1514
+ for (let l = 0; l < s; l++) {
1515
+ o[i] = l < n.length ? n[l] : 0, i = (i + 1) % a, this.filled = Math.min(this.filled + 1, a);
1516
+ const c = t[l];
1517
+ if (this.filled >= this.delay + this.filterLength) {
1518
+ let d = 0, P = 0, A = (i - this.delay + a) % a;
1519
+ for (let _ = 0; _ < this.filterLength; _++) {
1520
+ const w = o[A];
1521
+ d += this.w[_] * w, P += w * w, A = (A - 1 + a) % a;
1522
+ }
1523
+ const m = c - d;
1524
+ r[l] = m;
1525
+ const S = P + this.eps, x = this.mu * m / S;
1526
+ A = (i - this.delay + a) % a;
1527
+ for (let _ = 0; _ < this.filterLength; _++)
1528
+ this.w[_] += x * o[A], A = (A - 1 + a) % a;
1529
+ } else
1530
+ r[l] = c;
1531
+ }
1532
+ return this.cursor = i, r;
1533
+ }
1534
+ /** Reset adaptation (call on start/stop to avoid stale speaker->mic path). */
1535
+ reset() {
1536
+ this.w.fill(0), this.xBuf.fill(0), this.cursor = 0, this.filled = 0;
1537
+ }
1538
+ }
1539
+ const ze = (e, t) => `${e.replace(/\/+$/, "")}${t}`;
1540
+ function Is(e = nt, t = {}) {
1541
+ return fetch(ze(e, "/ready"), { headers: t }).then((n) => n.json());
1542
+ }
1543
+ function zs(e = nt, t = {}) {
1544
+ return fetch(ze(e, "/config"), { headers: t }).then((n) => n.json());
1545
+ }
1546
+ function or(e, t = {}, n, s) {
1547
+ const r = {
1548
+ "content-type": "application/octet-stream",
1549
+ ...t
1550
+ };
1551
+ return s !== void 0 && (r["x-voice-session"] = s), fetch(ze(e, "/asr"), {
1552
+ method: "POST",
1553
+ headers: r,
1554
+ // slice() copies so the body is exactly this view's span.
1555
+ body: n.slice().buffer
1556
+ }).then(async (o) => {
1557
+ if (!o.ok) throw new Error(`asr http ${o.status}`);
1558
+ return await o.json();
1559
+ });
1560
+ }
1561
+ function yt(e, t = {}, n) {
1562
+ return fetch(ze(e, "/cancel"), {
1563
+ method: "POST",
1564
+ headers: { "content-type": "application/json", ...t },
1565
+ body: JSON.stringify({ sessionId: n })
1566
+ }).then(async (s) => {
1567
+ if (!s.ok) throw new Error(`cancel http ${s.status}`);
1568
+ return await s.json();
1569
+ });
1570
+ }
1571
+ function $s(e, t = {}, n, s) {
1572
+ const r = ze(e, "/stream");
1573
+ if (!(Object.keys(t).length > 0)) {
1574
+ const S = new EventSource(r);
1575
+ return S.onopen = () => s({ connected: !0 }), S.onerror = () => s({ connected: !1 }), S.addEventListener("audio", (x) => {
1576
+ try {
1577
+ n(JSON.parse(x.data));
1578
+ } catch {
1579
+ }
1580
+ }), { close: () => S.close() };
1581
+ }
1582
+ let a = !1, i = null, l = null, c = "";
1583
+ const d = () => {
1584
+ a || l !== null || (l = setTimeout(() => {
1585
+ l = null, m();
1586
+ }, 3e3));
1587
+ }, P = (S, x) => {
1588
+ if (S === "audio")
1589
+ try {
1590
+ n(JSON.parse(x));
1591
+ } catch {
1592
+ }
1593
+ }, A = () => {
1594
+ let S;
1595
+ for (; (S = c.indexOf(`
1596
+
1597
+ `)) !== -1; ) {
1598
+ const x = c.slice(0, S);
1599
+ c = c.slice(S + 2);
1600
+ let _ = "message";
1601
+ const w = [];
1602
+ for (const u of x.split(`
1603
+ `))
1604
+ u.startsWith(":") || (u.startsWith("event:") ? _ = u.slice(6).trim() : u.startsWith("data:") && w.push(u.slice(5).trimStart()));
1605
+ w.length > 0 && P(_, w.join(`
1606
+ `));
1607
+ }
1608
+ }, m = async () => {
1609
+ if (!a) {
1610
+ i = new AbortController();
1611
+ try {
1612
+ const S = await fetch(r, { headers: t, signal: i.signal });
1613
+ if (!S.ok || !S.body) throw new Error(`stream http ${S.status}`);
1614
+ s({ connected: !0 });
1615
+ const x = S.body.getReader(), _ = new TextDecoder();
1616
+ for (; ; ) {
1617
+ const { done: w, value: u } = await x.read();
1618
+ if (w) break;
1619
+ c += _.decode(u, { stream: !0 }), A();
1620
+ }
1621
+ } catch {
1622
+ }
1623
+ a || (s({ connected: !1 }), d());
1624
+ }
1625
+ };
1626
+ return m(), {
1627
+ close: () => {
1628
+ a = !0, l !== null && clearTimeout(l);
1629
+ try {
1630
+ i == null || i.abort();
1631
+ } catch {
1632
+ }
1633
+ }
1634
+ };
1635
+ }
1636
+ function Os(e, t) {
1637
+ const { asrUrl: n, getHeaders: s, getEchoReference: r } = t;
1638
+ let o = "idle";
1639
+ const a = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set();
1640
+ let P = !1, A = null, m = null, S = null, x = !1, _ = !1, w = !1, u = [], k = [], v = 0, f = 0, U = !1, M = 0, F = !1, I = 0, O = null, E = 0, D = "";
1641
+ const se = () => typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `p-${Date.now()}-${Math.random().toString(36).slice(2)}`, K = (h) => {
1642
+ o = h;
1643
+ for (const j of a)
1644
+ try {
1645
+ j(h);
1646
+ } catch {
1647
+ }
1648
+ }, oe = (h) => {
1649
+ const j = h.trim();
1650
+ if (j)
1651
+ for (const V of i)
1652
+ try {
1653
+ V(j);
1654
+ } catch {
1655
+ }
1656
+ }, ae = () => {
1657
+ const h = new Float32Array(u.reduce((V, B) => V + B.length, 0));
1658
+ let j = 0;
1659
+ for (const V of u)
1660
+ h.set(V, j), j += V.length;
1661
+ return h;
1662
+ }, X = async () => {
1663
+ if (F || d.size === 0 || u.length === 0) return;
1664
+ const h = u.reduce(($, Z) => $ + Z.length, 0) / xe;
1665
+ if (h < Ts || h > xs) return;
1666
+ const j = ae();
1667
+ if (j.length <= E) return;
1668
+ const V = j.subarray(E);
1669
+ E = j.length;
1670
+ const B = I;
1671
+ F = !0;
1672
+ const Y = new AbortController();
1673
+ O = Y;
1674
+ try {
1675
+ const $ = await fetch(n, {
1676
+ method: "POST",
1677
+ headers: {
1678
+ "content-type": "application/octet-stream",
1679
+ ...(s == null ? void 0 : s()) ?? {},
1680
+ // 协议字段为 x-voice-session(PRD 4.3);dsh 后端读取的是
1681
+ // x-dsh-session,测试后端期间两个都发,后端各取所需。
1682
+ "x-voice-session": D,
1683
+ "x-dsh-session": D
1684
+ },
1685
+ // .slice() copies so the body is exactly the delta: subarray() is a
1686
+ // view whose .buffer still spans the whole capture.
1687
+ body: V.slice().buffer,
1688
+ signal: Y.signal
1689
+ });
1690
+ if (!$.ok) return;
1691
+ const Z = await $.json();
1692
+ if (B !== I) return;
1693
+ const g = (Z.text ?? "").trim();
1694
+ if (!g) return;
1695
+ for (const C of d)
1696
+ try {
1697
+ C(g);
1698
+ } catch {
1699
+ }
1700
+ } catch {
1701
+ } finally {
1702
+ F = !1, O === Y && (O = null);
1703
+ }
1704
+ }, ue = async (h) => {
1705
+ if (!P) {
1706
+ P = !0, K("transcribing");
1707
+ try {
1708
+ const j = h.slice().buffer, V = await fetch(n, {
1709
+ method: "POST",
1710
+ headers: {
1711
+ "content-type": "application/octet-stream",
1712
+ ...(s == null ? void 0 : s()) ?? {}
1713
+ },
1714
+ body: j
1715
+ });
1716
+ if (!V.ok) throw new Error(`asr http ${V.status}`);
1717
+ const B = await V.json();
1718
+ B.text && oe(B.text);
1719
+ } catch (j) {
1720
+ console.warn(`[voice] transcription failed: ${String(j)}`);
1721
+ } finally {
1722
+ P = !1, K(x ? w ? "speech" : "recording" : "idle");
1723
+ }
1724
+ }
1725
+ }, me = () => {
1726
+ if (u.length === 0) return;
1727
+ const h = ae();
1728
+ u = [], w = !1, v = 0, f = 0, ue(h);
1729
+ }, ve = () => {
1730
+ const h = Math.floor(vt / 1e3 * xe);
1731
+ h > 0 && u.push(new Float32Array(h)), me();
1732
+ }, de = (h) => {
1733
+ if (!x || U) return;
1734
+ let j = 0;
1735
+ for (let $ = 0; $ < h.length; $++) j += h[$] * h[$];
1736
+ const V = Math.sqrt(j / h.length), B = h.length / xe * 1e3, Y = Math.min(1, V / bs);
1737
+ for (const $ of c)
1738
+ try {
1739
+ $(Y);
1740
+ } catch {
1741
+ }
1742
+ if (_) {
1743
+ if (!w && V > pt) {
1744
+ w = !0, K("speech");
1745
+ for (const $ of l)
1746
+ try {
1747
+ $();
1748
+ } catch {
1749
+ }
1750
+ }
1751
+ if (f += B, u.push(h), f > mt) {
1752
+ ve();
1753
+ return;
1754
+ }
1755
+ M += B, M >= As && (M = 0, X());
1756
+ return;
1757
+ }
1758
+ if (V > pt) {
1759
+ if (!w) {
1760
+ w = !0, K("speech");
1761
+ for (const $ of l)
1762
+ try {
1763
+ $();
1764
+ } catch {
1765
+ }
1766
+ for (const $ of k) u.push($);
1767
+ k = [];
1768
+ }
1769
+ f += B, v = 0, u.push(h), f > mt && ve();
1770
+ } else if (w)
1771
+ f += B, v += B, u.push(h), v > ks && ve();
1772
+ else {
1773
+ k.push(h);
1774
+ const $ = Ss;
1775
+ let Z = 0, g = 0;
1776
+ for (let C = k.length - 1; C >= 0; C--)
1777
+ if (Z += k[C].length / xe * 1e3, Z > $) {
1778
+ g = C + 1;
1779
+ break;
1780
+ }
1781
+ g > 0 && (k = k.slice(g));
1782
+ }
1783
+ }, Ae = async () => {
1784
+ var V;
1785
+ if (x) return;
1786
+ const h = ((V = r == null ? void 0 : r()) == null ? void 0 : V.node) ?? null;
1787
+ m = await navigator.mediaDevices.getUserMedia({
1788
+ audio: {
1789
+ channelCount: 1,
1790
+ echoCancellation: h === null,
1791
+ noiseSuppression: !0,
1792
+ autoGainControl: !0
1793
+ }
1794
+ }), A = new AudioContext({ sampleRate: xe }), await A.resume().catch(() => {
1795
+ });
1796
+ const j = A.createMediaStreamSource(m);
1797
+ if (h === null)
1798
+ S = A.createScriptProcessor(gt, 1, 1), S.onaudioprocess = (B) => {
1799
+ const Y = B.inputBuffer.getChannelData(0);
1800
+ de(new Float32Array(Y));
1801
+ }, j.connect(S);
1802
+ else {
1803
+ const B = new js({});
1804
+ S = A.createScriptProcessor(gt, 2, 1), S.onaudioprocess = (Y) => {
1805
+ const $ = Y.inputBuffer.getChannelData(0), Z = Y.inputBuffer.getChannelData(1);
1806
+ de(B.process($, Z));
1807
+ }, j.connect(S, 0, 0), h.connect(S, 0, 1);
1808
+ }
1809
+ S.connect(A.destination), x = !0;
1810
+ }, W = async (h = !1) => {
1811
+ if (!x) return;
1812
+ x = !1, U = !0, I++, M = 0;
1813
+ try {
1814
+ O == null || O.abort();
1815
+ } catch {
1816
+ }
1817
+ O = null;
1818
+ const j = _;
1819
+ _ = !1;
1820
+ try {
1821
+ if (h ? !1 : j ? u.length > 0 : w) {
1822
+ const B = u.reduce((Y, $) => Y + $.length, 0) / xe;
1823
+ if (!j || B >= Cs) {
1824
+ const Y = Math.floor(vt / 1e3 * xe);
1825
+ u.push(new Float32Array(Y)), me();
1826
+ } else
1827
+ u = [];
1828
+ } else
1829
+ u = [];
1830
+ w = !1, v = 0, f = 0, k = [];
1831
+ } finally {
1832
+ U = !1;
1833
+ }
1834
+ try {
1835
+ S == null || S.disconnect();
1836
+ } catch {
1837
+ }
1838
+ S = null, E = 0, D = "";
1839
+ try {
1840
+ m == null || m.getTracks().forEach((V) => V.stop());
1841
+ } catch {
1842
+ }
1843
+ m = null;
1844
+ try {
1845
+ await (A == null ? void 0 : A.close());
1846
+ } catch {
1847
+ }
1848
+ A = null;
1849
+ };
1850
+ return {
1851
+ get state() {
1852
+ return o;
1853
+ },
1854
+ async start(h) {
1855
+ if (!x) {
1856
+ _ = (h == null ? void 0 : h.hold) === !0, I++, M = 0, E = 0, D = se(), K("recording");
1857
+ try {
1858
+ await Ae();
1859
+ } catch (j) {
1860
+ throw _ = !1, K("idle"), j;
1861
+ }
1862
+ }
1863
+ },
1864
+ async stop() {
1865
+ if (!x) {
1866
+ K("idle");
1867
+ return;
1868
+ }
1869
+ await W(), P || K("idle");
1870
+ },
1871
+ async cancel() {
1872
+ await W(!0), K("idle");
1873
+ },
1874
+ onSegment(h) {
1875
+ return i.add(h), () => {
1876
+ i.delete(h);
1877
+ };
1878
+ },
1879
+ onState(h) {
1880
+ return a.add(h), h(o), () => {
1881
+ a.delete(h);
1882
+ };
1883
+ },
1884
+ onSpeechStart(h) {
1885
+ return l.add(h), () => {
1886
+ l.delete(h);
1887
+ };
1888
+ },
1889
+ onLevel(h) {
1890
+ return c.add(h), () => {
1891
+ c.delete(h);
1892
+ };
1893
+ },
1894
+ onPartial(h) {
1895
+ return d.add(h), () => {
1896
+ d.delete(h);
1897
+ };
1898
+ }
1899
+ };
1900
+ }
1901
+ function Bs(e) {
1902
+ const t = e instanceof DOMException ? e.name : "", n = e instanceof Error ? e.message : String(e);
1903
+ switch (t) {
1904
+ case "NotAllowedError":
1905
+ case "SecurityError":
1906
+ return "麦克风被拒绝:请在浏览器地址栏的权限设置里允许麦克风";
1907
+ case "NotFoundError":
1908
+ case "OverconstrainedError":
1909
+ return "找不到麦克风设备:请检查系统输入设备";
1910
+ case "NotReadableError":
1911
+ return "麦克风被其他程序占用";
1912
+ default:
1913
+ return n ? `麦克风不可用:${n}` : "麦克风不可用";
1914
+ }
1915
+ }
1916
+ function Ns(e) {
1917
+ const t = atob(e), n = new Uint8Array(t.length);
1918
+ for (let r = 0; r < t.length; r++) n[r] = t.charCodeAt(r);
1919
+ const s = n[0] === 82 && n[1] === 73 && n[2] === 70 && n[3] === 70;
1920
+ return URL.createObjectURL(new Blob([n], { type: s ? "audio/wav" : "audio/mpeg" }));
1921
+ }
1922
+ function Vs(e) {
1923
+ const t = /* @__PURE__ */ new Set();
1924
+ let n = { connected: !1, playing: !1, caption: null };
1925
+ const s = [], r = _t();
1926
+ let o = null;
1927
+ const a = () => {
1928
+ for (const d of t) d(n);
1929
+ }, i = (d) => {
1930
+ n = { ...n, ...d }, a();
1931
+ }, l = () => {
1932
+ const d = s.shift();
1933
+ if (!d) {
1934
+ i({ playing: !1, caption: null });
1935
+ return;
1936
+ }
1937
+ Fs();
1938
+ const P = Ns(d.audio);
1939
+ r.src = P, r.onended = () => {
1940
+ URL.revokeObjectURL(P), l();
1941
+ }, r.onerror = () => {
1942
+ URL.revokeObjectURL(P), l();
1943
+ }, i({ playing: !0, caption: d.text }), r.play().catch(() => {
1944
+ i({ playing: !1 });
1945
+ });
1946
+ }, c = (d) => {
1947
+ d.sessionId === e.getSessionId() && d.audio && (s.push(d), r.paused && l());
1948
+ };
1949
+ return {
1950
+ connect() {
1951
+ var d;
1952
+ o === null && (o = $s(
1953
+ e.streamUrl,
1954
+ ((d = e.getHeaders) == null ? void 0 : d.call(e)) ?? {},
1955
+ c,
1956
+ (P) => i({ connected: P.connected })
1957
+ ));
1958
+ },
1959
+ skip() {
1960
+ s.length = 0, r.pause(), r.onended = null, r.onerror = null, i({ playing: !1, caption: null });
1961
+ },
1962
+ subscribe(d) {
1963
+ return t.add(d), d(n), () => {
1964
+ t.delete(d);
1965
+ };
1966
+ },
1967
+ getEchoReference() {
1968
+ return je ? { node: je } : null;
1969
+ }
1970
+ };
1971
+ }
1972
+ let Xe = null;
1973
+ function _t() {
1974
+ return Xe === null && (Xe = typeof Audio < "u" ? new Audio() : {}), Xe;
1975
+ }
1976
+ let _e = null, je = null;
1977
+ function Fs() {
1978
+ if (_e === null) {
1979
+ _e = new AudioContext();
1980
+ const e = _t();
1981
+ je === null && (je = _e.createMediaElementSource(e), je.connect(_e.destination));
1478
1982
  }
1983
+ return _e;
1984
+ }
1985
+ const jt = Symbol("szjy-voice");
1986
+ function It() {
1987
+ const e = Zt(jt);
1988
+ if (!e)
1989
+ throw new Error("useVoiceContext() 必须在 useVoice() 所在组件的子树中调用");
1990
+ return e;
1991
+ }
1992
+ function Ds(e) {
1993
+ const t = R("idle"), n = R(null), s = it(null), r = it(null), o = R(null), a = () => {
1994
+ var u;
1995
+ return ((u = e.getAuthHeaders) == null ? void 0 : u.call(e)) ?? {};
1996
+ }, i = () => lt(e.sessionId), l = () => lt(e.running) === !0;
1997
+ let c = !1;
1998
+ const d = () => {
1999
+ c = !0;
2000
+ }, P = () => {
2001
+ var u;
2002
+ (u = r.value) == null || u.skip(), yt(m(), a(), i()).catch(() => {
2003
+ });
2004
+ };
2005
+ let A = e.apiBase ?? nt;
2006
+ const m = () => A;
2007
+ let S = !1;
2008
+ (async () => {
2009
+ try {
2010
+ const u = await Is(m(), a());
2011
+ if (S) return;
2012
+ if (u.protocolVersion !== void 0 && u.protocolVersion !== 1) {
2013
+ n.value = "语音协议不兼容";
2014
+ return;
2015
+ }
2016
+ if (u.modelReady !== void 0 && u.modelReady === !1) {
2017
+ n.value = "语音模型未就绪";
2018
+ return;
2019
+ }
2020
+ const k = await zs(m(), a());
2021
+ if (S) return;
2022
+ A = e.apiBase ?? k.basePath ?? A, o.value = k.asr;
2023
+ const v = Vs({
2024
+ // openAudioStream(base) 内部会追加 /stream(api.ts 契约),此处传 base
2025
+ streamUrl: m(),
2026
+ getHeaders: a,
2027
+ getSessionId: i
2028
+ });
2029
+ r.value = v, v.connect();
2030
+ const f = Os(k.asr, {
2031
+ asrUrl: `${m()}/asr`,
2032
+ getHeaders: a,
2033
+ getEchoReference: () => v.getEchoReference()
2034
+ });
2035
+ f.onState((U) => {
2036
+ t.value = U;
2037
+ }), f.onSpeechStart(() => {
2038
+ v.skip(), yt(m(), a(), i()).catch(() => {
2039
+ }), l() && e.onCancelTurn();
2040
+ }), f.onSegment((U) => {
2041
+ const M = U.trim();
2042
+ if (!M) return;
2043
+ e.onTranscript(M);
2044
+ const F = c || k.asr.autoSend;
2045
+ c = !1, F && setTimeout(() => {
2046
+ try {
2047
+ e.onSubmit();
2048
+ } catch {
2049
+ }
2050
+ }, 60);
2051
+ }), s.value = f;
2052
+ } catch (u) {
2053
+ S || (n.value = `语音服务不可用:${u instanceof Error ? u.message : String(u)}`);
2054
+ }
2055
+ })();
2056
+ const x = () => {
2057
+ var u, k;
2058
+ S = !0, (u = s.value) == null || u.stop(), s.value = null, (k = r.value) == null || k.skip(), r.value = null;
2059
+ };
2060
+ De(x);
2061
+ const _ = (u, k = !1) => {
2062
+ !u && !k || fetch(`${m()}/speak`, {
2063
+ method: "POST",
2064
+ headers: { "content-type": "application/json", ...a() },
2065
+ body: JSON.stringify({ sessionId: i(), text: u, final: k })
2066
+ }).catch(() => {
2067
+ });
2068
+ };
2069
+ return Qt(jt, {
2070
+ engine: s,
2071
+ playback: r,
2072
+ config: o,
2073
+ asrState: t,
2074
+ error: n,
2075
+ requestSubmitOnNextSegment: d,
2076
+ skipPlayback: P,
2077
+ speak: _
2078
+ }), { asrState: t, error: n, dispose: x, speak: _ };
1479
2079
  }
1480
- const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { class: "header-title" }, Fn = { class: "action-icons" }, Bn = { class: "body-content" }, Vn = {
2080
+ const Hs = { class: "szjyv-ptt-backdrop" }, qs = {
2081
+ key: 0,
2082
+ class: "szjyv-ptt-caret"
2083
+ }, Ws = { class: "szjyv-kbd" }, Gs = /* @__PURE__ */ Ue({
2084
+ __name: "VoiceOverlay",
2085
+ props: {
2086
+ levels: {},
2087
+ armedCancel: { type: Boolean },
2088
+ pending: { type: Boolean },
2089
+ partial: {},
2090
+ source: {},
2091
+ hotkey: {}
2092
+ },
2093
+ setup(e) {
2094
+ const t = e, n = q(() => t.armedCancel ? "#f85149" : "#2ea043"), s = q(
2095
+ () => Array.from({ length: Mt }, (o, a) => t.levels[a] ?? 0)
2096
+ ), r = q(() => {
2097
+ const o = t.hotkey, a = typeof navigator < "u" && /Mac|iP(hone|ad|od)/.test(navigator.platform ?? "");
2098
+ switch (o) {
2099
+ case "Control":
2100
+ return a ? "⌃" : "Ctrl";
2101
+ case "Alt":
2102
+ return a ? "⌥" : "Alt";
2103
+ case "Meta":
2104
+ return a ? "⌘" : "Win";
2105
+ case "Shift":
2106
+ return "Shift";
2107
+ case " ":
2108
+ return "Space";
2109
+ default:
2110
+ return o;
2111
+ }
2112
+ });
2113
+ return (o, a) => (T(), L("div", Hs, [
2114
+ p("div", {
2115
+ class: le(["szjyv-ptt-card", { cancel: e.armedCancel }])
2116
+ }, [
2117
+ p("div", {
2118
+ class: le(["szjyv-ptt-wave", { frozen: e.pending }])
2119
+ }, [
2120
+ (T(!0), L(he, null, Fe(s.value, (i, l) => (T(), L("span", {
2121
+ key: l,
2122
+ class: "szjyv-ptt-bar",
2123
+ style: ce({
2124
+ height: `${3 + i * 37}px`,
2125
+ background: n.value,
2126
+ opacity: 0.45 + i * 0.55
2127
+ })
2128
+ }, null, 4))), 128))
2129
+ ], 2),
2130
+ e.partial && !e.armedCancel ? (T(), L("div", {
2131
+ key: 0,
2132
+ class: le(["szjyv-ptt-live", { stale: e.pending }])
2133
+ }, [
2134
+ fe(Q(e.partial) + " ", 1),
2135
+ e.pending ? H("", !0) : (T(), L("span", qs))
2136
+ ], 2)) : H("", !0),
2137
+ p("div", {
2138
+ class: "szjyv-ptt-hint",
2139
+ style: ce({ color: e.armedCancel ? "#f85149" : "#8b949e" })
2140
+ }, [
2141
+ e.pending ? (T(), L(he, { key: 0 }, [
2142
+ a[0] || (a[0] = p("span", { class: "szjyv-spin szjyv-ptt-spinner" }, null, -1)),
2143
+ a[1] || (a[1] = fe(" 识别中… ", -1))
2144
+ ], 64)) : e.armedCancel ? (T(), L(he, { key: 1 }, [
2145
+ fe("松开手指 取消发送")
2146
+ ], 64)) : e.source === "key" ? (T(), L(he, { key: 2 }, [
2147
+ a[2] || (a[2] = fe(" 松开 ", -1)),
2148
+ p("span", Ws, Q(r.value), 1),
2149
+ a[3] || (a[3] = fe(" 发送 · ", -1)),
2150
+ a[4] || (a[4] = p("span", { class: "szjyv-kbd" }, "Esc", -1)),
2151
+ a[5] || (a[5] = fe(" 取消 ", -1))
2152
+ ], 64)) : (T(), L(he, { key: 3 }, [
2153
+ fe("松开发送 · 上滑取消")
2154
+ ], 64))
2155
+ ], 4)
2156
+ ], 2)
2157
+ ]));
2158
+ }
2159
+ }), zt = /* @__PURE__ */ Ue({
2160
+ __name: "EqualizerBars",
2161
+ props: {
2162
+ color: {},
2163
+ height: {}
2164
+ },
2165
+ setup(e) {
2166
+ return (t, n) => (T(), L("span", {
2167
+ class: "szjyv-eq",
2168
+ style: ce({ height: `${e.height}px` })
2169
+ }, [
2170
+ (T(), L(he, null, Fe(3, (s) => p("span", {
2171
+ key: s,
2172
+ style: ce({
2173
+ background: e.color,
2174
+ animationDelay: `${(s - 1) * 0.18}s`
2175
+ })
2176
+ }, null, 4)), 64))
2177
+ ], 4));
2178
+ }
2179
+ }), Js = {
2180
+ key: 1,
2181
+ class: "szjyv-toast"
2182
+ }, Ks = ["title"], Ys = {
2183
+ key: 2,
2184
+ class: "szjyv-mic-icon",
2185
+ viewBox: "0 0 24 24",
2186
+ width: "17",
2187
+ height: "17",
2188
+ fill: "none",
2189
+ stroke: "currentColor",
2190
+ "stroke-width": "2",
2191
+ "stroke-linecap": "round",
2192
+ "stroke-linejoin": "round",
2193
+ "aria-hidden": "true"
2194
+ }, Xs = ["stroke"], Zs = {
2195
+ key: 4,
2196
+ class: "szjyv-mic-label"
2197
+ }, Qs = /* @__PURE__ */ Ue({
2198
+ __name: "VoiceMicButton",
2199
+ setup(e) {
2200
+ const t = It(), n = t.asrState, s = R(null), r = {
2201
+ idle: "voice: 待识别(点按说话)",
2202
+ recording: "voice: 录音中…",
2203
+ speech: "voice: 说话中…",
2204
+ transcribing: "voice: 识别中…",
2205
+ "loading-model": "voice: 模型加载中…"
2206
+ }, o = {
2207
+ idle: "#8b949e",
2208
+ recording: "#f85149",
2209
+ speech: "#2ea043",
2210
+ transcribing: "#58a6ff",
2211
+ "loading-model": "#bc8cff"
2212
+ }, a = R(!1), i = R(!1), l = R([]), c = R(""), d = R(!1), P = R("pointer"), A = R(""), m = R(null), S = R(null), x = R(null), _ = R(0), w = R(!1), u = R(!1), k = R(!1);
2213
+ ye(
2214
+ () => t.config.value,
2215
+ (g) => {
2216
+ A.value = (g == null ? void 0 : g.hotkey) ?? "";
2217
+ },
2218
+ { immediate: !0 }
2219
+ );
2220
+ const v = q(() => n.value === "transcribing" || n.value === "loading-model"), f = q(() => {
2221
+ var g;
2222
+ return s.value ? "voice error" : n.value === "idle" ? "mic" : ((g = r[n.value]) == null ? void 0 : g.replace("voice: ", "")) ?? "mic";
2223
+ }), U = q(() => {
2224
+ if (s.value) return s.value;
2225
+ const g = A.value ? `;也可长按 ${M(A.value)}` : "";
2226
+ return `${r[n.value] ?? ""}(长按说话,松开发送${g})`;
2227
+ });
2228
+ function M(g) {
2229
+ const C = typeof navigator < "u" && /Mac|iP(hone|ad|od)/.test(navigator.platform ?? "");
2230
+ switch (g) {
2231
+ case "Control":
2232
+ return C ? "⌃" : "Ctrl";
2233
+ case "Alt":
2234
+ return C ? "⌥" : "Alt";
2235
+ case "Meta":
2236
+ return C ? "⌘" : "Win";
2237
+ case "Shift":
2238
+ return "Shift";
2239
+ case " ":
2240
+ return "Space";
2241
+ default:
2242
+ return g;
2243
+ }
2244
+ }
2245
+ ye(
2246
+ () => t.error.value,
2247
+ (g) => {
2248
+ g !== null && s.value === null && (s.value = g);
2249
+ },
2250
+ { immediate: !0 }
2251
+ ), ye(s, (g) => {
2252
+ g !== null && setTimeout(() => {
2253
+ s.value === g && (s.value = null);
2254
+ }, 4e3);
2255
+ });
2256
+ const F = async () => {
2257
+ const g = t.engine.value;
2258
+ if (g) {
2259
+ if (k.value) {
2260
+ k.value = !1;
2261
+ return;
2262
+ }
2263
+ s.value = null;
2264
+ try {
2265
+ g.state === "idle" ? await g.start() : await g.stop();
2266
+ } catch (C) {
2267
+ s.value = C instanceof Error ? C.message : String(C);
2268
+ }
2269
+ }
2270
+ };
2271
+ ye(a, (g) => {
2272
+ const C = t.engine.value;
2273
+ if (!g || !C) return;
2274
+ l.value = [];
2275
+ const G = C.onLevel((we) => {
2276
+ l.value = l.value.length < Mt ? [...l.value, we] : [...l.value.slice(1), we];
2277
+ });
2278
+ c.value = "";
2279
+ const ee = C.onPartial((we) => {
2280
+ c.value = we;
2281
+ }), re = C.onSegment(() => {
2282
+ d.value = !1, c.value = "";
2283
+ });
2284
+ I = () => {
2285
+ G(), ee(), re();
2286
+ };
2287
+ });
2288
+ let I = null;
2289
+ ye(a, (g, C) => {
2290
+ !g && C && I && (I(), I = null);
2291
+ }), ye([d, n], ([g, C]) => {
2292
+ if (!g || C === "transcribing" || C === "loading-model") return;
2293
+ setTimeout(() => {
2294
+ d.value = !1, c.value = "";
2295
+ }, C === "idle" ? 220 : 12e3);
2296
+ });
2297
+ const O = (g) => {
2298
+ if (x.value && (clearTimeout(x.value), x.value = null), !u.value) {
2299
+ S.value = null;
2300
+ return;
2301
+ }
2302
+ u.value = !1, S.value = null, k.value = !0, a.value = !1, i.value = !1, w.value = !1;
2303
+ const C = t.engine.value;
2304
+ if (g) {
2305
+ c.value = "", d.value = !1, C == null || C.cancel();
2306
+ return;
2307
+ }
2308
+ d.value = !0, t.requestSubmitOnNextSegment(), C == null || C.stop();
2309
+ }, E = (g, C, G = "pointer", ee = Rs) => {
2310
+ t.engine.value !== null && (x.value && clearTimeout(x.value), _.value = g, S.value = G, C == null || C(), x.value = setTimeout(() => {
2311
+ var re;
2312
+ x.value = null, u.value = !0, P.value = G, a.value = !0, d.value = !1, c.value = "", s.value = null, (re = t.engine.value) == null || re.start({ hold: !0 }).catch((we) => {
2313
+ s.value = Bs(we), u.value = !1, S.value = null, a.value = !1;
2314
+ });
2315
+ }, ee));
2316
+ }, D = (g) => {
2317
+ if (!u.value || S.value === "key") return;
2318
+ const C = _.value - g > Ls;
2319
+ C !== w.value && (w.value = C, i.value = C);
2320
+ }, se = (g) => {
2321
+ E(g.clientY, () => {
2322
+ try {
2323
+ g.currentTarget.setPointerCapture(g.pointerId);
2324
+ } catch {
2325
+ }
2326
+ });
2327
+ }, K = (g) => D(g.clientY), oe = () => {
2328
+ S.value !== "key" && O(w.value);
2329
+ }, ae = () => {
2330
+ S.value !== "key" && O(!0);
2331
+ }, X = () => {
2332
+ const g = m.value;
2333
+ if (!g) return null;
2334
+ let C = g.parentElement;
2335
+ for (let G = 0; C && G < 4; G++) {
2336
+ const ee = Array.from(C.querySelectorAll("button")).filter(
2337
+ (re) => re !== g && !g.contains(re)
2338
+ );
2339
+ if (ee.length > 0) return ee[ee.length - 1];
2340
+ C = C.parentElement;
2341
+ }
2342
+ return null;
2343
+ }, ue = R(X);
2344
+ ue.value = X;
2345
+ let me = !1;
2346
+ const ve = (g) => {
2347
+ const C = ue.value();
2348
+ if (!C) return;
2349
+ const G = C.getBoundingClientRect();
2350
+ g.clientX >= G.left && g.clientX <= G.right && g.clientY >= G.top && g.clientY <= G.bottom && Y.value(g.clientY);
2351
+ }, de = (g) => Z.value(g.clientY), Ae = () => {
2352
+ S.value !== "key" && $.value(w.value);
2353
+ }, W = () => {
2354
+ S.value !== "key" && $.value(!0);
2355
+ }, h = (g) => {
2356
+ if (!k.value) return;
2357
+ const C = ue.value(), G = g.target;
2358
+ !C || !G || !(C === G || C.contains(G)) || (k.value = !1, g.preventDefault(), g.stopImmediatePropagation());
2359
+ }, j = (g) => {
2360
+ const C = A.value;
2361
+ if (C) {
2362
+ if (S.value !== null) {
2363
+ if (g.key === C || S.value === "pointer" && g.key !== "Escape") return;
2364
+ $.value(!0);
2365
+ return;
2366
+ }
2367
+ g.key !== C || g.repeat || g.isComposing || Y.value(0, void 0, "key", Es);
2368
+ }
2369
+ }, V = (g) => {
2370
+ S.value === "key" && g.key === A.value && $.value(!1);
2371
+ }, B = () => {
2372
+ S.value === "key" && $.value(!0);
2373
+ }, Y = R(E);
2374
+ Y.value = E;
2375
+ const $ = R(O);
2376
+ $.value = O;
2377
+ const Z = R(D);
2378
+ return Z.value = D, en(() => {
2379
+ me || (window.addEventListener("pointerdown", ve), window.addEventListener("pointermove", de), window.addEventListener("pointerup", Ae), window.addEventListener("pointercancel", W), window.addEventListener("click", h, !0), window.addEventListener("keydown", j), window.addEventListener("keyup", V), window.addEventListener("blur", B));
2380
+ }), De(() => {
2381
+ me = !0, window.removeEventListener("pointerdown", ve), window.removeEventListener("pointermove", de), window.removeEventListener("pointerup", Ae), window.removeEventListener("pointercancel", W), window.removeEventListener("click", h, !0), window.removeEventListener("keydown", j), window.removeEventListener("keyup", V), window.removeEventListener("blur", B), x.value && clearTimeout(x.value), I == null || I();
2382
+ }), (g, C) => (T(), L(he, null, [
2383
+ a.value || d.value ? (T(), Se(Gs, {
2384
+ key: 0,
2385
+ levels: l.value,
2386
+ "armed-cancel": i.value,
2387
+ pending: d.value,
2388
+ partial: c.value,
2389
+ source: P.value,
2390
+ hotkey: A.value
2391
+ }, null, 8, ["levels", "armed-cancel", "pending", "partial", "source", "hotkey"])) : H("", !0),
2392
+ s.value ? (T(), L("div", Js, Q(s.value), 1)) : H("", !0),
2393
+ p("button", {
2394
+ ref_key: "anchorRef",
2395
+ ref: m,
2396
+ class: "szjyv-mic",
2397
+ title: U.value,
2398
+ onClick: F,
2399
+ onPointerdown: se,
2400
+ onPointermove: C[0] || (C[0] = (G) => K(G)),
2401
+ onPointerup: oe,
2402
+ onPointercancel: ae
2403
+ }, [
2404
+ v.value ? (T(), L("span", {
2405
+ key: 0,
2406
+ class: "szjyv-spin szjyv-mic-spinner",
2407
+ style: ce({ borderTopColor: o[Re(n)] })
2408
+ }, null, 4)) : Re(n) === "speech" ? (T(), Se(zt, {
2409
+ key: 1,
2410
+ color: "#2ea043",
2411
+ height: 11
2412
+ })) : Re(n) === "idle" && !a.value ? (T(), L("svg", Ys, [
2413
+ p("path", {
2414
+ d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z",
2415
+ stroke: s.value ? "#f85149" : "#57606a",
2416
+ fill: "currentColor",
2417
+ "fill-opacity": "0.15"
2418
+ }, null, 8, Xs),
2419
+ C[1] || (C[1] = p("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }, null, -1)),
2420
+ C[2] || (C[2] = p("line", {
2421
+ x1: "12",
2422
+ y1: "19",
2423
+ x2: "12",
2424
+ y2: "22"
2425
+ }, null, -1))
2426
+ ])) : (T(), L("span", {
2427
+ key: 3,
2428
+ class: le(["szjyv-mic-dot", { pulse: Re(n) === "recording" && !s.value }]),
2429
+ style: ce({ background: s.value ? "#f85149" : o[Re(n)] })
2430
+ }, null, 6)),
2431
+ a.value || f.value !== "mic" ? (T(), L("span", Zs, Q(a.value ? i.value ? "松开取消" : "松开发送" : f.value), 1)) : H("", !0)
2432
+ ], 40, Ks)
2433
+ ], 64));
2434
+ }
2435
+ }), eo = { class: "szjyv-captionbar" }, to = /* @__PURE__ */ Ue({
2436
+ __name: "VoiceCaptionBar",
2437
+ setup(e) {
2438
+ const t = It(), n = tn({ connected: !1, playing: !1, caption: null });
2439
+ let s = null;
2440
+ const r = ye(
2441
+ () => t.playback.value,
2442
+ (l) => {
2443
+ !l || s || (s = l.subscribe((c) => Object.assign(n, c)));
2444
+ },
2445
+ { immediate: !0 }
2446
+ );
2447
+ De(() => {
2448
+ r(), s == null || s();
2449
+ });
2450
+ const o = q(() => n.connected && n.playing), a = q(
2451
+ () => o.value ? "#2ea043" : n.connected ? "#8b949e" : "#f85149"
2452
+ ), i = () => {
2453
+ t.skipPlayback();
2454
+ };
2455
+ return (l, c) => (T(), L("div", eo, [
2456
+ o.value ? (T(), Se(zt, {
2457
+ key: 0,
2458
+ color: "#2ea043",
2459
+ height: 13
2460
+ })) : (T(), L("span", {
2461
+ key: 1,
2462
+ class: le(["szjyv-caption-dot", { offline: !n.connected }]),
2463
+ style: ce({ background: a.value })
2464
+ }, null, 6)),
2465
+ (T(), L("span", {
2466
+ key: n.caption ?? "idle",
2467
+ class: "szjyv-caption-text"
2468
+ }, Q(n.caption ?? (n.connected ? "voice ready" : "voice offline")), 1)),
2469
+ n.playing ? (T(), L("button", {
2470
+ key: 2,
2471
+ class: "szjyv-skip",
2472
+ onClick: i
2473
+ }, "skip")) : H("", !0)
2474
+ ]));
2475
+ }
2476
+ }), no = { class: "panel-header" }, so = { class: "header-actions" }, oo = { class: "header-title" }, ro = { class: "action-icons" }, ao = { class: "body-content" }, io = {
1481
2477
  key: 0,
1482
2478
  class: "welcome-content"
1483
- }, Hn = { class: "subtitle" }, Dn = { class: "highlight" }, qn = { class: "quick-questions" }, Wn = ["onClick"], Gn = {
2479
+ }, lo = { class: "subtitle" }, co = { class: "highlight" }, uo = { class: "quick-questions" }, fo = ["onClick"], ho = {
1484
2480
  key: 1,
1485
2481
  class: "message-content user-content"
1486
- }, Jn = { class: "panel-footer" }, Kn = {
2482
+ }, po = {
1487
2483
  key: 0,
1488
- src: xt,
1489
- alt: "加载中",
1490
- class: "loading-icon"
1491
- }, Xn = {
2484
+ class: "ai-thinking-indicator"
2485
+ }, mo = {
2486
+ key: 1,
2487
+ class: "ai-failed-tip"
2488
+ }, vo = { class: "panel-footer" }, go = {
1492
2489
  key: 0,
1493
2490
  class: "voice-progress-banner"
1494
- }, Yn = { class: "progress-info" }, Zn = { class: "progress-text" }, Qn = {
2491
+ }, yo = { class: "progress-info" }, wo = { class: "progress-text" }, bo = {
1495
2492
  key: 0,
1496
2493
  class: "progress-percent"
1497
- }, er = {
2494
+ }, ko = {
1498
2495
  key: 0,
1499
2496
  class: "progress-track"
1500
- }, tr = { class: "recording-main" }, nr = { class: "recording-status" }, rr = {
2497
+ }, So = { class: "recording-main" }, Co = { class: "recording-status" }, Ao = {
1501
2498
  key: 0,
1502
2499
  class: "recording-time"
1503
- }, sr = { class: "recording-hint" }, or = {
2500
+ }, To = { class: "recording-hint" }, xo = {
1504
2501
  key: 1,
1505
2502
  class: "volume-waves"
1506
- }, ar = { class: "recording-actions" }, ir = ["title"], lr = {
2503
+ }, Ro = { class: "recording-actions" }, Eo = ["title"], Lo = {
1507
2504
  key: 0,
1508
2505
  class: "voice-playback-bar"
1509
- }, cr = ["title"], ur = { class: "playback-play-icon" }, dr = {
2506
+ }, Po = ["title"], Uo = { class: "playback-play-icon" }, Mo = {
1510
2507
  key: 0,
1511
2508
  viewBox: "0 0 24 24",
1512
2509
  width: "14",
1513
2510
  height: "14",
1514
2511
  fill: "currentColor"
1515
- }, fr = {
2512
+ }, _o = {
1516
2513
  key: 1,
1517
2514
  viewBox: "0 0 24 24",
1518
2515
  width: "14",
1519
2516
  height: "14",
1520
2517
  fill: "currentColor"
1521
- }, hr = { class: "playback-title" }, pr = {
2518
+ }, jo = { class: "playback-title" }, Io = {
1522
2519
  key: 0,
1523
2520
  class: "playback-time"
1524
- }, mr = {
2521
+ }, zo = {
1525
2522
  key: 1,
1526
2523
  class: "playback-waves"
1527
- }, gr = { class: "input-box" }, yr = { class: "input-actions-box" }, vr = ["src"], it = {
2524
+ }, $o = { class: "input-box" }, Oo = { class: "input-actions-box" }, Bo = ["src"], $t = {
1528
2525
  __name: "ChatPanel",
1529
2526
  props: {
1530
2527
  modelValue: {
@@ -1591,6 +2588,27 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
1591
2588
  /**
1592
2589
  * 是否显示上传音频/视频识别入口,默认关闭
1593
2590
  */
2591
+ /**
2592
+ * 全双工语音(gateway-openai /api/voice):识别 → 填入输入框,助手回复经 SSE 朗读。
2593
+ * 默认关闭以向后兼容;开启后挂载全双工麦克风与字幕栏。
2594
+ */
2595
+ enableDuplexVoice: {
2596
+ type: Boolean,
2597
+ default: !1
2598
+ },
2599
+ /** 全双工语音后端地址;留空则用默认 /api/voice(同源代理或 /config basePath 纠正) */
2600
+ voiceApiBase: {
2601
+ type: String,
2602
+ default: ""
2603
+ },
2604
+ /**
2605
+ * 朗读助手回复(TTS)。默认关闭——识别填入输入框不依赖此项;
2606
+ * 运行时切换即时生效(无需重挂载组件)。
2607
+ */
2608
+ enableVoiceTts: {
2609
+ type: Boolean,
2610
+ default: !1
2611
+ },
1594
2612
  enableVoiceUpload: {
1595
2613
  type: Boolean,
1596
2614
  default: !1
@@ -1629,210 +2647,275 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
1629
2647
  },
1630
2648
  emits: ["update:modelValue", "submit", "ui-action"],
1631
2649
  setup(e, { emit: t }) {
1632
- const { appContext: s } = Je(), { $message: r } = s.config.globalProperties, o = e;
1633
- let n = null;
1634
- const a = T("idle"), i = T(""), l = T(0), c = T(0), b = T(0);
2650
+ const { appContext: n } = bt(), { $message: s } = n.config.globalProperties, r = e;
2651
+ let o = null;
2652
+ const a = R("idle"), i = R(""), l = R(0), c = R(0), d = R(0);
1635
2653
  let P = null;
1636
- const A = T(""), p = T(!1), F = T(0);
1637
- let U = null;
1638
- const z = T(""), y = T(""), m = N(() => a.value === "downloading"), v = N(() => a.value === "loading"), f = N(() => a.value === "recording"), u = N(() => a.value === "transcribing"), k = N(() => f.value ? "正在录音,点击完成后开始识别" : z.value ? "正在流式转写..." : "正在识别语音中..."), C = N(() => o.enableVoiceInput ? "请输入您的问题或点击麦克风语音输入" : o.enableVoiceUpload ? "请输入您的问题或上传音频识别" : "请输入您的问题"), L = (g, h) => {
1639
- const E = (g || "").trim(), B = (h || "").trim();
1640
- return B ? E ? /[A-Za-z0-9]$/.test(E) && /[A-Za-z0-9]/.test(B.charAt(0)) ? `${E} ${B}` : `${E}${B}` : B : E;
1641
- }, R = (g) => {
1642
- const h = Math.floor(g / 60), E = g % 60;
1643
- return `${h.toString().padStart(2, "0")}:${E.toString().padStart(2, "0")}`;
1644
- }, I = () => (n || (n = new Ln({
1645
- soundBaseUrl: o.soundBaseUrl || "/sounds/",
1646
- workerUrl: o.workerUrl || void 0,
1647
- onStatusChange: (g, h) => {
1648
- a.value = g, h && (i.value = h);
2654
+ const A = R(""), m = R(!1), S = R(0);
2655
+ let x = null;
2656
+ const _ = R(""), w = R(""), u = q(() => a.value === "downloading"), k = q(() => a.value === "loading"), v = q(() => a.value === "recording"), f = q(() => a.value === "transcribing"), U = q(() => v.value ? "正在录音,点击完成后开始识别" : _.value ? "正在流式转写..." : "正在识别语音中..."), M = q(() => r.enableVoiceInput ? "请输入您的问题或点击麦克风语音输入" : r.enableVoiceUpload ? "请输入您的问题或上传音频识别" : "请输入您的问题"), F = (y, b) => {
2657
+ const z = (y || "").trim(), J = (b || "").trim();
2658
+ return J ? z ? /[A-Za-z0-9]$/.test(z) && /[A-Za-z0-9]/.test(J.charAt(0)) ? `${z} ${J}` : `${z}${J}` : J : z;
2659
+ }, I = (y) => {
2660
+ const b = Math.floor(y / 60), z = y % 60;
2661
+ return `${b.toString().padStart(2, "0")}:${z.toString().padStart(2, "0")}`;
2662
+ }, O = () => (o || (o = new ws({
2663
+ soundBaseUrl: r.soundBaseUrl || "/sounds/",
2664
+ workerUrl: r.workerUrl || void 0,
2665
+ onStatusChange: (y, b) => {
2666
+ a.value = y, b && (i.value = b);
1649
2667
  },
1650
- onProgress: (g) => {
1651
- typeof g.progress == "number" && (l.value = g.progress);
2668
+ onProgress: (y) => {
2669
+ typeof y.progress == "number" && (l.value = y.progress);
1652
2670
  },
1653
- onVolumeChange: (g) => {
1654
- c.value = g;
2671
+ onVolumeChange: (y) => {
2672
+ c.value = y;
1655
2673
  },
1656
- onAudioRecorded: (g) => {
1657
- A.value && URL.revokeObjectURL(A.value), A.value = g, F.value = b.value;
2674
+ onAudioRecorded: (y) => {
2675
+ A.value && URL.revokeObjectURL(A.value), A.value = y, S.value = d.value;
1658
2676
  },
1659
- onPartial: (g) => {
1660
- z.value = g || "", _.value = L(y.value, g);
2677
+ onPartial: (y) => {
2678
+ _.value = y || "", h.value = F(w.value, y);
1661
2679
  },
1662
- onResult: (g) => {
1663
- z.value = g || "", _.value = L(y.value, g), g ? r.success("语音识别完成") : r.warning("未能识别出有效语音,请重试"), setTimeout(() => {
1664
- z.value = "", V.value && V.value.focus();
2680
+ onResult: (y) => {
2681
+ _.value = y || "", h.value = F(w.value, y), y ? s.success("语音识别完成") : s.warning("未能识别出有效语音,请重试"), setTimeout(() => {
2682
+ _.value = "", j.value && j.value.focus();
1665
2683
  }, 100);
1666
2684
  },
1667
- onError: (g) => {
1668
- r.error(g || "语音输入服务出错"), O();
2685
+ onError: (y) => {
2686
+ s.error(y || "语音输入服务出错"), D();
1669
2687
  }
1670
- })), n), w = () => {
1671
- O(), b.value = 0, P = setInterval(() => {
1672
- b.value += 1;
2688
+ })), o), E = () => {
2689
+ D(), d.value = 0, P = setInterval(() => {
2690
+ d.value += 1;
1673
2691
  }, 1e3);
1674
- }, O = () => {
2692
+ }, D = () => {
1675
2693
  P && (clearInterval(P), P = null);
1676
- }, X = async () => {
1677
- if (!o.enableVoiceInput) return;
1678
- if (f.value) {
1679
- await Y();
2694
+ }, se = async () => {
2695
+ if (!r.enableVoiceInput) return;
2696
+ if (v.value) {
2697
+ await K();
1680
2698
  return;
1681
2699
  }
1682
- p.value && U && (U.pause(), p.value = !1);
1683
- const g = I();
2700
+ m.value && x && (x.pause(), m.value = !1);
2701
+ const y = O();
1684
2702
  try {
1685
- y.value = _.value, z.value = "", w(), await g.startRecording();
1686
- } catch (h) {
1687
- O(), console.error("启动录音失败:", h);
2703
+ w.value = h.value, _.value = "", E(), await y.startRecording();
2704
+ } catch (b) {
2705
+ D(), console.error("启动录音失败:", b);
1688
2706
  }
1689
- }, Y = async () => {
1690
- O(), n && await n.stopAndTranscribe();
1691
- }, Z = T(null), ne = () => {
1692
- o.enableVoiceUpload && Z.value && (Z.value.value = "", Z.value.click());
1693
- }, q = async (g) => {
1694
- var te;
1695
- if (!o.enableVoiceUpload) return;
1696
- const h = g.target, E = (te = h == null ? void 0 : h.files) == null ? void 0 : te[0];
1697
- if (!E) return;
1698
- p.value && U && (U.pause(), p.value = !1);
1699
- const B = I();
2707
+ }, K = async () => {
2708
+ D(), o && await o.stopAndTranscribe();
2709
+ }, oe = R(null), ae = () => {
2710
+ r.enableVoiceUpload && oe.value && (oe.value.value = "", oe.value.click());
2711
+ }, X = async (y) => {
2712
+ var ge;
2713
+ if (!r.enableVoiceUpload) return;
2714
+ const b = y.target, z = (ge = b == null ? void 0 : b.files) == null ? void 0 : ge[0];
2715
+ if (!z) return;
2716
+ m.value && x && (x.pause(), m.value = !1);
2717
+ const J = O();
1700
2718
  try {
1701
- y.value = _.value, z.value = "", r.info(`正在流式识别文件: ${E.name}`), await B.transcribeFile(E);
1702
- } catch (H) {
1703
- r.error(`文件识别失败: ${H.message || H}`);
2719
+ w.value = h.value, _.value = "", s.info(`正在流式识别文件: ${z.name}`), await J.transcribeFile(z);
2720
+ } catch (te) {
2721
+ s.error(`文件识别失败: ${te.message || te}`);
1704
2722
  }
1705
- }, oe = () => {
1706
- O(), z.value = "", _.value = y.value, n && n.cancelRecording();
1707
- }, fe = () => {
1708
- z.value = "", _.value = y.value, n && n.cancelTranscribe(), r.info("已取消本次语音识别");
1709
- }, ke = () => {
2723
+ }, ue = () => {
2724
+ D(), _.value = "", h.value = w.value, o && o.cancelRecording();
2725
+ }, me = () => {
2726
+ _.value = "", h.value = w.value, o && o.cancelTranscribe(), s.info("已取消本次语音识别");
2727
+ }, ve = () => {
1710
2728
  if (A.value) {
1711
- if (p.value && U) {
1712
- U.pause(), p.value = !1;
2729
+ if (m.value && x) {
2730
+ x.pause(), m.value = !1;
1713
2731
  return;
1714
2732
  }
1715
- U && (U.pause(), U = null), U = new Audio(A.value), U.onloadedmetadata = () => {
1716
- U && !isNaN(U.duration) && (F.value = Math.round(U.duration));
1717
- }, U.onended = () => {
1718
- p.value = !1;
1719
- }, U.onerror = () => {
1720
- p.value = !1, r.error("音频试听播放失败");
1721
- }, U.play().then(() => {
1722
- p.value = !0;
1723
- }).catch((g) => {
1724
- console.error("音频播放出错:", g), p.value = !1;
2733
+ x && (x.pause(), x = null), x = new Audio(A.value), x.onloadedmetadata = () => {
2734
+ x && !isNaN(x.duration) && (S.value = Math.round(x.duration));
2735
+ }, x.onended = () => {
2736
+ m.value = !1;
2737
+ }, x.onerror = () => {
2738
+ m.value = !1, s.error("音频试听播放失败");
2739
+ }, x.play().then(() => {
2740
+ m.value = !0;
2741
+ }).catch((y) => {
2742
+ console.error("音频播放出错:", y), m.value = !1;
1725
2743
  });
1726
2744
  }
1727
- }, ae = () => {
1728
- U && (U.pause(), U = null), p.value = !1, A.value && (URL.revokeObjectURL(A.value), A.value = "");
2745
+ }, de = () => {
2746
+ x && (x.pause(), x = null), m.value = !1, A.value && (URL.revokeObjectURL(A.value), A.value = "");
1729
2747
  };
1730
- bt(() => {
1731
- O(), ae(), n && (n.destroy(), n = null);
2748
+ nn(() => {
2749
+ D(), de(), o && (o.destroy(), o = null);
1732
2750
  });
1733
- const xe = N(() => Ve.find((g) => g.modelName === o.llmName) ?? Ve.find((g) => g.modelName === "szjy")), j = t, _ = T(""), V = T(null), ie = T(!1), G = T([]), ut = T([
2751
+ const Ae = q(() => ct.find((y) => y.modelName === r.llmName) ?? ct.find((y) => y.modelName === "szjy")), W = t, h = R(""), j = R(null), V = R(!1), B = R([]), Y = R([
1734
2752
  "什么是AI助理,能做什么?",
1735
2753
  "当前项目的基本情况?",
1736
2754
  "当前项目的进度情况?",
1737
2755
  "当前项目的参建方有哪些?",
1738
2756
  "数智建管平台有哪些功能?能做什么?"
1739
- ]), le = T([]), he = T(!1), Te = T(null), Re = () => {
1740
- Ye(() => {
1741
- if (Te.value) {
1742
- const g = Te.value, h = g.scrollHeight, E = g.scrollTop, B = g.clientHeight;
1743
- h - E - B < 100 ? g.scrollTop = h : g.scrollTo({
1744
- top: h
2757
+ ]), $ = R([]), Z = R(!1), g = R(null), C = () => {
2758
+ Ct(() => {
2759
+ if (g.value) {
2760
+ const y = g.value, b = y.scrollHeight, z = y.scrollTop, J = y.clientHeight;
2761
+ b - z - J < 100 ? y.scrollTop = b : y.scrollTo({
2762
+ top: b
1745
2763
  });
1746
2764
  }
1747
2765
  });
1748
- }, se = T(!1), dt = N(() => se.value ? "/images/ai-stop.png" : "/images/ai-send.png"), Ne = (g, h) => {
1749
- console.log("onFailedReader", g, h), he.value = !1;
1750
- const E = Fe();
1751
- E && E.initializeEnd(), r.error("转换失败,请重试"), se.value = !1, setTimeout(() => {
1752
- V.value && V.value.focus();
2766
+ }, G = R(!1), ee = R(!1), re = R("");
2767
+ let we = "";
2768
+ const Nt = q(() => G.value ? "/images/ai-stop.png" : "/images/ai-send.png"), ot = (y, b) => {
2769
+ var be;
2770
+ console.log("onFailedReader", y, b), Me(), Z.value = !1, ee.value = !1;
2771
+ const z = We();
2772
+ z && z.initializeEnd();
2773
+ const J = B.value[y], ge = $.value[y], te = ((be = ge == null ? void 0 : ge.getRawText) == null ? void 0 : be.call(ge)) || "";
2774
+ J && J.type === "ai" && !J.displayText && !te && B.value.splice(y, 1), re.value = we, G.value = !1, C(), setTimeout(() => {
2775
+ j.value && j.value.focus();
1753
2776
  });
1754
- }, ft = (g, h) => {
1755
- he.value = !1, se.value = !1, Re(), h && G.value[g] && (G.value[g].displayText = h), setTimeout(() => {
1756
- V.value && V.value.focus();
2777
+ }, Vt = (y) => {
2778
+ ee.value = !1;
2779
+ }, Ft = (y, b) => {
2780
+ Z.value = !1, G.value = !1, ee.value = !1, C(), Kt(y, b), b && B.value[y] && (B.value[y].displayText = b), setTimeout(() => {
2781
+ j.value && j.value.focus();
1757
2782
  });
1758
- }, ht = (g) => {
1759
- se.value = !0;
1760
- }, pt = () => {
1761
- se.value = !1, j("update:modelValue", !1), ie.value = !1, G.value = [];
1762
- }, Ue = T(!1), mt = () => {
1763
- Ue.value = !Ue.value;
1764
- }, gt = (g) => {
1765
- _.value = g, _e();
1766
- }, Fe = () => {
1767
- for (let g = le.value.length - 1; g >= 0; g--)
1768
- if (le.value[g])
1769
- return le.value[g];
2783
+ }, Dt = (y) => {
2784
+ G.value = !0, Jt(y);
2785
+ }, Ht = () => {
2786
+ G.value = !1, ee.value = !1, re.value = "", W("update:modelValue", !1), V.value = !1, B.value = [];
2787
+ }, qe = R(!1), qt = () => {
2788
+ qe.value = !qe.value;
2789
+ }, Wt = (y) => {
2790
+ h.value = y, Be();
2791
+ }, We = () => {
2792
+ for (let y = $.value.length - 1; y >= 0; y--)
2793
+ if ($.value[y])
2794
+ return $.value[y];
1770
2795
  return null;
1771
- }, _e = async () => {
1772
- if (console.log("stylizingLoading:", he.value), he.value) {
1773
- const te = Fe();
1774
- console.log("lastPreviewer:", te), te && (console.log("abortReader"), te.abortReader());
2796
+ }, Be = async () => {
2797
+ if (console.log("stylizingLoading:", Z.value), Z.value) {
2798
+ ee.value = !1;
2799
+ const b = We();
2800
+ console.log("lastPreviewer:", b), b && (console.log("abortReader"), b.abortReader());
1775
2801
  return;
1776
2802
  }
1777
- if (!_.value.trim()) {
1778
- console.log("no input, return"), V.value.focus();
2803
+ if (!h.value.trim()) {
2804
+ console.log("no input, return"), j.value.focus();
1779
2805
  return;
1780
2806
  }
1781
- G.value.push({
2807
+ B.value.push({
1782
2808
  type: "user",
1783
- content: _.value
1784
- }), se.value = !0, ie.value = !0, j("submit", _.value), Re();
1785
- const g = _.value;
1786
- _.value = "";
1787
- const h = G.value.length;
1788
- le.value[h] && le.value[h].initializeStart(), he.value = !0, G.value.push({
2809
+ content: h.value
2810
+ }), G.value = !0, V.value = !0, re.value = "", W("submit", h.value), C();
2811
+ const y = h.value;
2812
+ we = y, h.value = "", await rt(y);
2813
+ }, Gt = async () => {
2814
+ const y = re.value;
2815
+ !y || Z.value || (re.value = "", we = y, G.value = !0, C(), await rt(y));
2816
+ }, rt = async (y) => {
2817
+ const b = B.value.length;
2818
+ $.value[b] && $.value[b].initializeStart(), Z.value = !0, ee.value = !0, B.value.push({
1789
2819
  type: "ai"
1790
2820
  });
1791
- const { error: E, reader: B } = await Vt(xe.value, {
1792
- text: g,
1793
- token: o.token,
1794
- identifier: o.identifier,
1795
- baseUrl: o.baseUrl,
2821
+ const { error: z, reader: J } = await xn(Ae.value, {
2822
+ text: y,
2823
+ token: r.token,
2824
+ identifier: r.identifier,
2825
+ baseUrl: r.baseUrl,
1796
2826
  // mock 模式(llmName=standard)经 extraConfig 读取 mockResponse,不侵入 API 签名
1797
- extraConfig: o.mockResponse ? Object.assign({}, o.extraConfig, { mockResponse: o.mockResponse }) : o.extraConfig
2827
+ extraConfig: r.mockResponse ? Object.assign({}, r.extraConfig, { mockResponse: r.mockResponse }) : r.extraConfig
1798
2828
  });
1799
- if (E) {
1800
- console.log(45455, E), Ne(h, E);
2829
+ if (z) {
2830
+ console.log(45455, z), ot(b, z);
1801
2831
  return;
1802
2832
  }
1803
- B && (G.value[h].reader = B);
2833
+ J && (B.value[b].reader = J);
1804
2834
  };
1805
- return (g, h) => {
1806
- const E = Me("el-icon"), B = Me("el-button"), te = Me("el-input");
1807
- return S(), ge(ye, { name: "slide" }, {
1808
- default: J(() => [
1809
- e.modelValue ? (S(), x("div", {
2835
+ let Ee = null, Te = 0, at = 0;
2836
+ const Ge = R(r.enableVoiceTts);
2837
+ ye(
2838
+ () => r.enableVoiceTts,
2839
+ (y) => {
2840
+ Ge.value = y, y || Me();
2841
+ }
2842
+ );
2843
+ const Me = () => {
2844
+ Te = 0;
2845
+ }, Jt = (y) => {
2846
+ if (!Ee) return;
2847
+ const b = $.value[y];
2848
+ if (!b || !b.getRawText) return;
2849
+ const z = b.getRawText() || "";
2850
+ if (!Ge.value) {
2851
+ z.length > Te && (Te = z.length);
2852
+ return;
2853
+ }
2854
+ const J = Date.now();
2855
+ z.length > Te && J - at > 250 && (Ee(z.slice(Te), !1), Te = z.length, at = J);
2856
+ }, Kt = (y, b) => {
2857
+ if (!Ee) return;
2858
+ if (!Ge.value) {
2859
+ Me();
2860
+ return;
2861
+ }
2862
+ const z = $.value[y];
2863
+ if (z && z.isAborted && z.isAborted()) {
2864
+ Me();
2865
+ return;
2866
+ }
2867
+ const J = b || (z && z.getRawText ? z.getRawText() : "") || "";
2868
+ J.length > Te && Ee(J.slice(Te), !1), Ee("", !0), Me();
2869
+ };
2870
+ if (r.enableDuplexVoice) {
2871
+ const y = "chat-voice-" + Date.now().toString(36) + Math.random().toString(36).slice(2, 8), { speak: b } = Ds({
2872
+ apiBase: r.voiceApiBase || void 0,
2873
+ sessionId: y,
2874
+ running: q(() => G.value),
2875
+ onTranscript: (z) => {
2876
+ h.value = F(h.value, z);
2877
+ },
2878
+ onSubmit: () => {
2879
+ Be();
2880
+ },
2881
+ onCancelTurn: () => {
2882
+ const z = We();
2883
+ z && z.abortReader();
2884
+ }
2885
+ });
2886
+ Ee = b;
2887
+ }
2888
+ return (y, b) => {
2889
+ const z = Je("el-icon"), J = Je("el-button"), ge = Je("el-input");
2890
+ return T(), Se(Le, { name: "slide" }, {
2891
+ default: ie(() => [
2892
+ e.modelValue ? (T(), L("div", {
1810
2893
  key: 0,
1811
- class: re(["ai-panel", { "drawer-mode": Ue.value, "embedded-mode": e.embedded }])
2894
+ class: le(["ai-panel", { "drawer-mode": qe.value, "embedded-mode": e.embedded }])
1812
2895
  }, [
1813
- d("div", $n, [
1814
- d("div", On, [
1815
- d("div", Nn, W(e.title), 1),
1816
- d("div", Fn, [
1817
- e.embedded ? $("", !0) : (S(), ge(E, {
2896
+ p("div", no, [
2897
+ p("div", so, [
2898
+ p("div", oo, Q(e.title), 1),
2899
+ p("div", ro, [
2900
+ e.embedded ? H("", !0) : (T(), Se(z, {
1818
2901
  key: 0,
1819
2902
  class: "action-icon",
1820
- onClick: mt
2903
+ onClick: qt
1821
2904
  }, {
1822
- default: J(() => [
1823
- D(Ce, {
2905
+ default: ie(() => [
2906
+ ne(Ve, {
1824
2907
  name: "/images/svg/drawer-layout.svg",
1825
2908
  color: "#999999"
1826
2909
  })
1827
2910
  ]),
1828
2911
  _: 1
1829
2912
  })),
1830
- D(E, {
2913
+ ne(z, {
1831
2914
  class: "action-icon",
1832
- onClick: pt
2915
+ onClick: Ht
1833
2916
  }, {
1834
- default: J(() => [
1835
- D(Ce, {
2917
+ default: ie(() => [
2918
+ ne(Ve, {
1836
2919
  name: "/images/svg/close.svg",
1837
2920
  color: "#999999"
1838
2921
  })
@@ -1842,132 +2925,156 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
1842
2925
  ])
1843
2926
  ])
1844
2927
  ]),
1845
- d("div", Bn, [
1846
- ie.value ? (S(), x("div", {
2928
+ p("div", ao, [
2929
+ V.value ? (T(), L("div", {
1847
2930
  key: 1,
1848
2931
  class: "chat-messages",
1849
2932
  ref_key: "messageContainerRef",
1850
- ref: Te
2933
+ ref: g
1851
2934
  }, [
1852
- (S(!0), x(me, null, Be(G.value, (H, ce) => (S(), x("div", {
1853
- key: ce,
1854
- class: re(["message-item", H.type === "user" ? "user-message" : "ai-message"])
2935
+ (T(!0), L(he, null, Fe(B.value, (te, be) => (T(), L("div", {
2936
+ key: be,
2937
+ class: le(["message-item", te.type === "user" ? "user-message" : "ai-message"])
1855
2938
  }, [
1856
- H.type === "ai" ? (S(), ge(Rn, {
2939
+ te.type === "ai" ? (T(), Se(us, {
1857
2940
  key: 0,
1858
2941
  ref_for: !0,
1859
- ref: (Q) => le.value[ce] = Q,
1860
- reader: H.reader,
1861
- "onUpdate:reader": (Q) => H.reader = Q,
1862
- model: o.llmName,
1863
- displayText: H.displayText,
1864
- scrollToBottomFn: Re,
2942
+ ref: (ke) => $.value[be] = ke,
2943
+ reader: te.reader,
2944
+ "onUpdate:reader": (ke) => te.reader = ke,
2945
+ model: r.llmName,
2946
+ displayText: te.displayText,
2947
+ scrollToBottomFn: C,
1865
2948
  messagePostRender: e.messagePostRender,
1866
2949
  customUi: e.customUi,
1867
2950
  uiActionHandler: e.uiActionHandler,
1868
- onFailed: (Q) => Ne(ce, Q),
1869
- onCompleted: (Q) => ft(ce, Q),
1870
- onUpdating: () => ht(),
1871
- onUiAction: h[0] || (h[0] = (Q) => j("ui-action", Q))
1872
- }, null, 8, ["reader", "onUpdate:reader", "model", "displayText", "messagePostRender", "customUi", "uiActionHandler", "onFailed", "onCompleted", "onUpdating"])) : (S(), x("div", Gn, W(H.content), 1))
1873
- ], 2))), 128))
1874
- ], 512)) : (S(), x("div", Vn, [
1875
- h[3] || (h[3] = d("div", { class: "title" }, [
1876
- d("img", {
1877
- src: At,
2951
+ onFailed: (ke) => ot(be, ke),
2952
+ onStarted: () => Vt(),
2953
+ onCompleted: (ke) => Ft(be, ke),
2954
+ onUpdating: () => Dt(be),
2955
+ onUiAction: b[0] || (b[0] = (ke) => W("ui-action", ke))
2956
+ }, null, 8, ["reader", "onUpdate:reader", "model", "displayText", "messagePostRender", "customUi", "uiActionHandler", "onFailed", "onStarted", "onCompleted", "onUpdating"])) : (T(), L("div", ho, Q(te.content), 1))
2957
+ ], 2))), 128)),
2958
+ ne(Le, { name: "ai-status-fade" }, {
2959
+ default: ie(() => [
2960
+ ee.value ? (T(), L("div", po, [...b[4] || (b[4] = [
2961
+ p("img", {
2962
+ src: ln,
2963
+ alt: "AI思考中",
2964
+ class: "thinking-icon"
2965
+ }, null, -1),
2966
+ p("img", {
2967
+ src: cn,
2968
+ alt: "",
2969
+ class: "thinking-loading-icon"
2970
+ }, null, -1),
2971
+ p("span", { class: "thinking-text" }, "正在努力思考中~", -1)
2972
+ ])])) : re.value ? (T(), L("div", mo, [
2973
+ b[5] || (b[5] = p("span", { class: "failed-text" }, "网络问题请重试", -1)),
2974
+ p("button", {
2975
+ class: "retry-btn",
2976
+ onClick: Gt
2977
+ }, "重试")
2978
+ ])) : H("", !0)
2979
+ ]),
2980
+ _: 1
2981
+ })
2982
+ ], 512)) : (T(), L("div", io, [
2983
+ b[3] || (b[3] = p("div", { class: "title" }, [
2984
+ p("img", {
2985
+ src: an,
1878
2986
  alt: "AI助手",
1879
2987
  class: "panel-icon"
1880
2988
  }),
1881
- d("h3", { class: "title-text" }, "Hi, 您好")
2989
+ p("h3", { class: "title-text" }, "Hi, 您好")
1882
2990
  ], -1)),
1883
- d("div", Hn, [
1884
- h[2] || (h[2] = pe(" 我是", -1)),
1885
- d("span", Dn, W(e.title), 1)
2991
+ p("div", lo, [
2992
+ b[2] || (b[2] = fe(" 我是", -1)),
2993
+ p("span", co, Q(e.title), 1)
1886
2994
  ]),
1887
- d("div", qn, [
1888
- (S(!0), x(me, null, Be(ut.value, (H, ce) => (S(), x("div", {
1889
- key: ce,
2995
+ p("div", uo, [
2996
+ (T(!0), L(he, null, Fe(Y.value, (te, be) => (T(), L("div", {
2997
+ key: be,
1890
2998
  class: "question-item",
1891
- onClick: (Q) => gt(H)
2999
+ onClick: (ke) => Wt(te)
1892
3000
  }, [
1893
- d("span", null, W(H), 1),
1894
- D(E, null, {
1895
- default: J(() => [
1896
- D(Ce, {
3001
+ p("span", null, Q(te), 1),
3002
+ ne(z, null, {
3003
+ default: ie(() => [
3004
+ ne(Ve, {
1897
3005
  name: "/images/svg/arrow-right.svg",
1898
3006
  color: "#999999"
1899
3007
  })
1900
3008
  ]),
1901
3009
  _: 1
1902
3010
  })
1903
- ], 8, Wn))), 128))
3011
+ ], 8, fo))), 128))
1904
3012
  ])
1905
3013
  ]))
1906
3014
  ]),
1907
- d("div", Jn, [
1908
- se.value ? (S(), x("img", Kn)) : $("", !0),
1909
- D(ye, { name: "fade" }, {
1910
- default: J(() => [
1911
- m.value || v.value ? (S(), x("div", Xn, [
1912
- d("div", Yn, [
1913
- h[4] || (h[4] = d("span", { class: "progress-icon" }, "⏳", -1)),
1914
- d("span", Zn, W(i.value), 1),
1915
- l.value > 0 ? (S(), x("span", Qn, W(l.value) + "%", 1)) : $("", !0)
3015
+ p("div", vo, [
3016
+ ne(Le, { name: "fade" }, {
3017
+ default: ie(() => [
3018
+ u.value || k.value ? (T(), L("div", go, [
3019
+ p("div", yo, [
3020
+ b[6] || (b[6] = p("span", { class: "progress-icon" }, "⏳", -1)),
3021
+ p("span", wo, Q(i.value), 1),
3022
+ l.value > 0 ? (T(), L("span", bo, Q(l.value) + "%", 1)) : H("", !0)
1916
3023
  ]),
1917
- l.value > 0 ? (S(), x("div", er, [
1918
- d("div", {
3024
+ l.value > 0 ? (T(), L("div", ko, [
3025
+ p("div", {
1919
3026
  class: "progress-bar",
1920
- style: ue({ width: l.value + "%" })
3027
+ style: ce({ width: l.value + "%" })
1921
3028
  }, null, 4)
1922
- ])) : $("", !0)
1923
- ])) : $("", !0)
3029
+ ])) : H("", !0)
3030
+ ])) : H("", !0)
1924
3031
  ]),
1925
3032
  _: 1
1926
3033
  }),
1927
- D(ye, { name: "fade" }, {
1928
- default: J(() => [
1929
- f.value || u.value ? (S(), x("div", {
3034
+ ne(Le, { name: "fade" }, {
3035
+ default: ie(() => [
3036
+ v.value || f.value ? (T(), L("div", {
1930
3037
  key: 0,
1931
- class: re(["voice-recording-panel", { "has-transcript": u.value }])
3038
+ class: le(["voice-recording-panel", { "has-transcript": f.value }])
1932
3039
  }, [
1933
- d("div", tr, [
1934
- d("div", nr, [
1935
- d("span", {
1936
- class: re(["recording-pulse", { transcribing: u.value }])
3040
+ p("div", So, [
3041
+ p("div", Co, [
3042
+ p("span", {
3043
+ class: le(["recording-pulse", { transcribing: f.value }])
1937
3044
  }, null, 2),
1938
- f.value ? (S(), x("span", rr, W(R(b.value)), 1)) : $("", !0),
1939
- d("span", sr, W(k.value), 1),
1940
- f.value ? (S(), x("div", or, [
1941
- d("span", {
3045
+ v.value ? (T(), L("span", Ao, Q(I(d.value)), 1)) : H("", !0),
3046
+ p("span", To, Q(U.value), 1),
3047
+ v.value ? (T(), L("div", xo, [
3048
+ p("span", {
1942
3049
  class: "wave",
1943
- style: ue({ height: Math.max(4, Math.min(22, c.value * 0.3)) + "px" })
3050
+ style: ce({ height: Math.max(4, Math.min(22, c.value * 0.3)) + "px" })
1944
3051
  }, null, 4),
1945
- d("span", {
3052
+ p("span", {
1946
3053
  class: "wave",
1947
- style: ue({ height: Math.max(4, Math.min(30, c.value * 0.5)) + "px" })
3054
+ style: ce({ height: Math.max(4, Math.min(30, c.value * 0.5)) + "px" })
1948
3055
  }, null, 4),
1949
- d("span", {
3056
+ p("span", {
1950
3057
  class: "wave",
1951
- style: ue({ height: Math.max(4, Math.min(18, c.value * 0.25)) + "px" })
3058
+ style: ce({ height: Math.max(4, Math.min(18, c.value * 0.25)) + "px" })
1952
3059
  }, null, 4)
1953
- ])) : $("", !0)
3060
+ ])) : H("", !0)
1954
3061
  ]),
1955
- d("div", ar, [
1956
- f.value ? (S(), x(me, { key: 0 }, [
1957
- D(B, {
3062
+ p("div", Ro, [
3063
+ v.value ? (T(), L(he, { key: 0 }, [
3064
+ ne(J, {
1958
3065
  size: "small",
1959
3066
  circle: "",
1960
- onClick: oe,
3067
+ onClick: ue,
1961
3068
  title: "取消录音",
1962
3069
  class: "voice-cancel-btn"
1963
3070
  }, {
1964
- default: J(() => [...h[5] || (h[5] = [
1965
- d("svg", {
3071
+ default: ie(() => [...b[7] || (b[7] = [
3072
+ p("svg", {
1966
3073
  viewBox: "0 0 1024 1024",
1967
3074
  width: "12",
1968
3075
  height: "12"
1969
3076
  }, [
1970
- d("path", {
3077
+ p("path", {
1971
3078
  d: "M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",
1972
3079
  fill: "currentColor"
1973
3080
  })
@@ -1975,111 +3082,111 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
1975
3082
  ])]),
1976
3083
  _: 1
1977
3084
  }),
1978
- D(B, {
3085
+ ne(J, {
1979
3086
  type: "primary",
1980
3087
  size: "small",
1981
3088
  round: "",
1982
- onClick: Y,
3089
+ onClick: K,
1983
3090
  class: "voice-finish-btn"
1984
3091
  }, {
1985
- default: J(() => [...h[6] || (h[6] = [
1986
- pe(" 完成 ", -1)
3092
+ default: ie(() => [...b[8] || (b[8] = [
3093
+ fe(" 完成 ", -1)
1987
3094
  ])]),
1988
3095
  _: 1
1989
3096
  })
1990
- ], 64)) : u.value ? (S(), ge(B, {
3097
+ ], 64)) : f.value ? (T(), Se(J, {
1991
3098
  key: 1,
1992
3099
  size: "small",
1993
3100
  round: "",
1994
- onClick: fe,
3101
+ onClick: me,
1995
3102
  class: "voice-cancel-transcribe-btn"
1996
3103
  }, {
1997
- default: J(() => [...h[7] || (h[7] = [
1998
- pe(" 取消识别 ", -1)
3104
+ default: ie(() => [...b[9] || (b[9] = [
3105
+ fe(" 取消识别 ", -1)
1999
3106
  ])]),
2000
3107
  _: 1
2001
- })) : $("", !0)
3108
+ })) : H("", !0)
2002
3109
  ])
2003
3110
  ]),
2004
- u.value ? (S(), x("div", {
3111
+ f.value ? (T(), L("div", {
2005
3112
  key: 0,
2006
- class: re(["live-transcript", { empty: !z.value }]),
2007
- title: z.value
3113
+ class: le(["live-transcript", { empty: !_.value }]),
3114
+ title: _.value
2008
3115
  }, [
2009
- z.value ? (S(), x(me, { key: 0 }, [
2010
- pe(W(z.value), 1),
2011
- h[8] || (h[8] = d("span", { class: "caret" }, "|", -1))
2012
- ], 64)) : (S(), x(me, { key: 1 }, [
2013
- pe("正在识别,文字将实时显示...")
3116
+ _.value ? (T(), L(he, { key: 0 }, [
3117
+ fe(Q(_.value), 1),
3118
+ b[10] || (b[10] = p("span", { class: "caret" }, "|", -1))
3119
+ ], 64)) : (T(), L(he, { key: 1 }, [
3120
+ fe("正在识别,文字将实时显示...")
2014
3121
  ], 64))
2015
- ], 10, ir)) : $("", !0)
2016
- ], 2)) : $("", !0)
3122
+ ], 10, Eo)) : H("", !0)
3123
+ ], 2)) : H("", !0)
2017
3124
  ]),
2018
3125
  _: 1
2019
3126
  }),
2020
- D(ye, { name: "fade" }, {
2021
- default: J(() => [
2022
- A.value && !f.value && !u.value ? (S(), x("div", lr, [
2023
- d("div", {
3127
+ ne(Le, { name: "fade" }, {
3128
+ default: ie(() => [
3129
+ A.value && !v.value && !f.value ? (T(), L("div", Lo, [
3130
+ p("div", {
2024
3131
  class: "playback-main",
2025
- onClick: ke,
2026
- title: p.value ? "点击暂停" : "点击播放录音"
3132
+ onClick: ve,
3133
+ title: m.value ? "点击暂停" : "点击播放录音"
2027
3134
  }, [
2028
- d("div", ur, [
2029
- p.value ? (S(), x("svg", fr, [...h[10] || (h[10] = [
2030
- d("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }, null, -1)
2031
- ])])) : (S(), x("svg", dr, [...h[9] || (h[9] = [
2032
- d("path", { d: "M8 5v14l11-7z" }, null, -1)
3135
+ p("div", Uo, [
3136
+ m.value ? (T(), L("svg", _o, [...b[12] || (b[12] = [
3137
+ p("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }, null, -1)
3138
+ ])])) : (T(), L("svg", Mo, [...b[11] || (b[11] = [
3139
+ p("path", { d: "M8 5v14l11-7z" }, null, -1)
2033
3140
  ])]))
2034
3141
  ]),
2035
- d("span", hr, W(p.value ? "正在播放录音..." : "点击试听本次录音"), 1),
2036
- F.value > 0 ? (S(), x("span", pr, W(R(F.value)), 1)) : $("", !0),
2037
- p.value ? (S(), x("div", mr, [...h[11] || (h[11] = [
2038
- d("span", { class: "wave-bar" }, null, -1),
2039
- d("span", { class: "wave-bar" }, null, -1),
2040
- d("span", { class: "wave-bar" }, null, -1),
2041
- d("span", { class: "wave-bar" }, null, -1)
2042
- ])])) : $("", !0)
2043
- ], 8, cr),
2044
- d("div", {
3142
+ p("span", jo, Q(m.value ? "正在播放录音..." : "点击试听本次录音"), 1),
3143
+ S.value > 0 ? (T(), L("span", Io, Q(I(S.value)), 1)) : H("", !0),
3144
+ m.value ? (T(), L("div", zo, [...b[13] || (b[13] = [
3145
+ p("span", { class: "wave-bar" }, null, -1),
3146
+ p("span", { class: "wave-bar" }, null, -1),
3147
+ p("span", { class: "wave-bar" }, null, -1),
3148
+ p("span", { class: "wave-bar" }, null, -1)
3149
+ ])])) : H("", !0)
3150
+ ], 8, Po),
3151
+ p("div", {
2045
3152
  class: "playback-close",
2046
- onClick: ae,
3153
+ onClick: de,
2047
3154
  title: "清除试听"
2048
- }, [...h[12] || (h[12] = [
2049
- d("svg", {
3155
+ }, [...b[14] || (b[14] = [
3156
+ p("svg", {
2050
3157
  viewBox: "0 0 1024 1024",
2051
3158
  width: "12",
2052
3159
  height: "12"
2053
3160
  }, [
2054
- d("path", {
3161
+ p("path", {
2055
3162
  d: "M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",
2056
3163
  fill: "currentColor"
2057
3164
  })
2058
3165
  ], -1)
2059
3166
  ])])
2060
- ])) : $("", !0)
3167
+ ])) : H("", !0)
2061
3168
  ]),
2062
3169
  _: 1
2063
3170
  }),
2064
- Ke(d("div", gr, [
2065
- D(te, {
2066
- modelValue: _.value,
2067
- "onUpdate:modelValue": h[1] || (h[1] = (H) => _.value = H),
3171
+ kt(p("div", $o, [
3172
+ ne(ge, {
3173
+ modelValue: h.value,
3174
+ "onUpdate:modelValue": b[1] || (b[1] = (te) => h.value = te),
2068
3175
  ref_key: "refInputTextString",
2069
- ref: V,
2070
- placeholder: C.value,
3176
+ ref: j,
3177
+ placeholder: M.value,
2071
3178
  autofocus: "",
2072
- onKeyup: kt(_e, ["enter"])
3179
+ onKeyup: sn(Be, ["enter"])
2073
3180
  }, {
2074
- append: J(() => [
2075
- d("div", yr, [
2076
- e.enableVoiceUpload ? (S(), x("div", {
3181
+ append: ie(() => [
3182
+ p("div", Oo, [
3183
+ e.enableVoiceUpload ? (T(), L("div", {
2077
3184
  key: 0,
2078
3185
  class: "voice-upload-btn",
2079
- onClick: ne,
3186
+ onClick: ae,
2080
3187
  title: "上传音频/视频文件识别 (支持 .wav, .mp4, .mp3, .m4a)"
2081
- }, [...h[13] || (h[13] = [
2082
- d("svg", {
3188
+ }, [...b[15] || (b[15] = [
3189
+ p("svg", {
2083
3190
  viewBox: "0 0 24 24",
2084
3191
  width: "17",
2085
3192
  height: "17",
@@ -2089,32 +3196,32 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
2089
3196
  "stroke-linecap": "round",
2090
3197
  "stroke-linejoin": "round"
2091
3198
  }, [
2092
- d("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
2093
- d("polyline", { points: "17 8 12 3 7 8" }),
2094
- d("line", {
3199
+ p("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
3200
+ p("polyline", { points: "17 8 12 3 7 8" }),
3201
+ p("line", {
2095
3202
  x1: "12",
2096
3203
  y1: "3",
2097
3204
  x2: "12",
2098
3205
  y2: "15"
2099
3206
  })
2100
3207
  ], -1)
2101
- ])])) : $("", !0),
2102
- e.enableVoiceUpload ? (S(), x("input", {
3208
+ ])])) : H("", !0),
3209
+ e.enableVoiceUpload ? (T(), L("input", {
2103
3210
  key: 1,
2104
3211
  type: "file",
2105
3212
  ref_key: "refAudioFileInput",
2106
- ref: Z,
3213
+ ref: oe,
2107
3214
  accept: "audio/*,video/mp4,.wav,.mp4,.mp3,.m4a",
2108
3215
  style: { display: "none" },
2109
- onChange: q
2110
- }, null, 544)) : $("", !0),
2111
- e.enableVoiceInput ? (S(), x("div", {
3216
+ onChange: X
3217
+ }, null, 544)) : H("", !0),
3218
+ e.enableVoiceInput ? (T(), L("div", {
2112
3219
  key: 2,
2113
- class: re(["voice-mic-btn", { "loading-anim": m.value || v.value }]),
2114
- onClick: X,
3220
+ class: le(["voice-mic-btn", { "loading-anim": u.value || k.value }]),
3221
+ onClick: se,
2115
3222
  title: "语音输入"
2116
- }, [...h[14] || (h[14] = [
2117
- d("svg", {
3223
+ }, [...b[16] || (b[16] = [
3224
+ p("svg", {
2118
3225
  viewBox: "0 0 24 24",
2119
3226
  width: "18",
2120
3227
  height: "18",
@@ -2124,328 +3231,330 @@ const $n = { class: "panel-header" }, On = { class: "header-actions" }, Nn = { c
2124
3231
  "stroke-linecap": "round",
2125
3232
  "stroke-linejoin": "round"
2126
3233
  }, [
2127
- d("path", {
3234
+ p("path", {
2128
3235
  d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z",
2129
3236
  fill: "currentColor",
2130
3237
  opacity: "0.2"
2131
3238
  }),
2132
- d("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
2133
- d("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
2134
- d("line", {
3239
+ p("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
3240
+ p("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
3241
+ p("line", {
2135
3242
  x1: "12",
2136
3243
  y1: "19",
2137
3244
  x2: "12",
2138
3245
  y2: "22"
2139
3246
  })
2140
3247
  ], -1)
2141
- ])], 2)) : $("", !0),
2142
- d("div", {
3248
+ ])], 2)) : H("", !0),
3249
+ e.enableDuplexVoice ? (T(), Se(Re(Qs), { key: 3 })) : H("", !0),
3250
+ p("div", {
2143
3251
  class: "send-icon-box",
2144
- onClick: _e
3252
+ onClick: Be
2145
3253
  }, [
2146
- d("img", {
2147
- src: dt.value,
3254
+ p("img", {
3255
+ src: Nt.value,
2148
3256
  alt: "发送",
2149
3257
  class: "send-icon"
2150
- }, null, 8, vr)
3258
+ }, null, 8, Bo)
2151
3259
  ])
2152
3260
  ])
2153
3261
  ]),
2154
3262
  _: 1
2155
3263
  }, 8, ["modelValue", "placeholder"])
2156
3264
  ], 512), [
2157
- [Xe, !f.value && !u.value]
2158
- ])
3265
+ [St, !v.value && !f.value]
3266
+ ]),
3267
+ e.enableDuplexVoice ? (T(), Se(Re(to), { key: 0 })) : H("", !0)
2159
3268
  ])
2160
- ], 2)) : $("", !0)
3269
+ ], 2)) : H("", !0)
2161
3270
  ]),
2162
3271
  _: 1
2163
3272
  });
2164
3273
  };
2165
3274
  }
2166
3275
  };
2167
- var lt = { exports: {} };
3276
+ var Ot = { exports: {} };
2168
3277
  (function(e, t) {
2169
- (function(s, r) {
2170
- e.exports = r();
3278
+ (function(n, s) {
3279
+ e.exports = s();
2171
3280
  })(window, function() {
2172
- return function(s) {
2173
- var r = {};
2174
- function o(n) {
2175
- if (r[n]) return r[n].exports;
2176
- var a = r[n] = { i: n, l: !1, exports: {} };
2177
- return s[n].call(a.exports, a, a.exports, o), a.l = !0, a.exports;
3281
+ return function(n) {
3282
+ var s = {};
3283
+ function r(o) {
3284
+ if (s[o]) return s[o].exports;
3285
+ var a = s[o] = { i: o, l: !1, exports: {} };
3286
+ return n[o].call(a.exports, a, a.exports, r), a.l = !0, a.exports;
2178
3287
  }
2179
- return o.m = s, o.c = r, o.d = function(n, a, i) {
2180
- o.o(n, a) || Object.defineProperty(n, a, { enumerable: !0, get: i });
2181
- }, o.r = function(n) {
2182
- typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(n, "__esModule", { value: !0 });
2183
- }, o.t = function(n, a) {
2184
- if (1 & a && (n = o(n)), 8 & a || 4 & a && typeof n == "object" && n && n.__esModule) return n;
3288
+ return r.m = n, r.c = s, r.d = function(o, a, i) {
3289
+ r.o(o, a) || Object.defineProperty(o, a, { enumerable: !0, get: i });
3290
+ }, r.r = function(o) {
3291
+ typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(o, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(o, "__esModule", { value: !0 });
3292
+ }, r.t = function(o, a) {
3293
+ if (1 & a && (o = r(o)), 8 & a || 4 & a && typeof o == "object" && o && o.__esModule) return o;
2185
3294
  var i = /* @__PURE__ */ Object.create(null);
2186
- if (o.r(i), Object.defineProperty(i, "default", { enumerable: !0, value: n }), 2 & a && typeof n != "string") for (var l in n) o.d(i, l, (function(c) {
2187
- return n[c];
3295
+ if (r.r(i), Object.defineProperty(i, "default", { enumerable: !0, value: o }), 2 & a && typeof o != "string") for (var l in o) r.d(i, l, (function(c) {
3296
+ return o[c];
2188
3297
  }).bind(null, l));
2189
3298
  return i;
2190
- }, o.n = function(n) {
2191
- var a = n && n.__esModule ? function() {
2192
- return n.default;
3299
+ }, r.n = function(o) {
3300
+ var a = o && o.__esModule ? function() {
3301
+ return o.default;
2193
3302
  } : function() {
2194
- return n;
3303
+ return o;
2195
3304
  };
2196
- return o.d(a, "a", a), a;
2197
- }, o.o = function(n, a) {
2198
- return Object.prototype.hasOwnProperty.call(n, a);
2199
- }, o.p = "", o(o.s = 0);
2200
- }([function(s, r, o) {
2201
- function n(y, m, v, f) {
2202
- v.push(y), f.push([].concat(m[y] || []));
3305
+ return r.d(a, "a", a), a;
3306
+ }, r.o = function(o, a) {
3307
+ return Object.prototype.hasOwnProperty.call(o, a);
3308
+ }, r.p = "", r(r.s = 0);
3309
+ }([function(n, s, r) {
3310
+ function o(w, u, k, v) {
3311
+ k.push(w), v.push([].concat(u[w] || []));
2203
3312
  }
2204
- function a(y, m) {
2205
- if (!y) throw new Error("[getMaxDepsChain] dep 参数不能为空");
2206
- var v = [], f = [], u = [];
2207
- for (n(y, m, f, u); f.length; ) {
2208
- var k = u.pop();
2209
- if (k && k.length) {
2210
- var C = k.shift();
2211
- if (u.push(k), ~f.indexOf(C)) throw new Error("[getMaxDepsChain][loop] 存在循环依赖,请检查依赖关系; nextName: " + C + ", mainStack: " + f);
2212
- n(C, m, f, u);
2213
- } else v.push([].concat(f)), f.pop();
3313
+ function a(w, u) {
3314
+ if (!w) throw new Error("[getMaxDepsChain] dep 参数不能为空");
3315
+ var k = [], v = [], f = [];
3316
+ for (o(w, u, v, f); v.length; ) {
3317
+ var U = f.pop();
3318
+ if (U && U.length) {
3319
+ var M = U.shift();
3320
+ if (f.push(U), ~v.indexOf(M)) throw new Error("[getMaxDepsChain][loop] 存在循环依赖,请检查依赖关系; nextName: " + M + ", mainStack: " + v);
3321
+ o(M, u, v, f);
3322
+ } else k.push([].concat(v)), v.pop();
2214
3323
  }
2215
- return v.reduce(function(L, R) {
2216
- return R.length > L.length ? R : L;
3324
+ return k.reduce(function(F, I) {
3325
+ return I.length > F.length ? I : F;
2217
3326
  }, []);
2218
3327
  }
2219
- function i(y) {
2220
- if (!y) throw new Error("[depsParser] 入参不能为空");
2221
- var m = {};
2222
- y.forEach(function(f) {
2223
- m[f.name] = f.deps || [];
3328
+ function i(w) {
3329
+ if (!w) throw new Error("[depsParser] 入参不能为空");
3330
+ var u = {};
3331
+ w.forEach(function(v) {
3332
+ u[v.name] = v.deps || [];
2224
3333
  });
2225
- var v = [];
2226
- return y.forEach(function(f) {
2227
- var u = a(f.name, m).length - 1;
2228
- f.priority = u, v[u] = (v[u] || []).concat(f);
2229
- }), v;
3334
+ var k = [];
3335
+ return w.forEach(function(v) {
3336
+ var f = a(v.name, u).length - 1;
3337
+ v.priority = f, k[f] = (k[f] || []).concat(v);
3338
+ }), k;
2230
3339
  }
2231
- o.r(r), o.d(r, "loadScript", function() {
3340
+ r.r(s), r.d(s, "loadScript", function() {
2232
3341
  return A;
2233
- }), o.d(r, "loadScripts", function() {
2234
- return p;
2235
- }), o.d(r, "dynamicLoadScripts", function() {
2236
- return F;
2237
- }), o.d(r, "createScriptsLoadIterator", function() {
2238
- return U;
2239
- }), o.d(r, "loadScriptsQueue", function() {
2240
- return z;
2241
- }), o.d(r, "getMaxDepsChain", function() {
3342
+ }), r.d(s, "loadScripts", function() {
3343
+ return m;
3344
+ }), r.d(s, "dynamicLoadScripts", function() {
3345
+ return S;
3346
+ }), r.d(s, "createScriptsLoadIterator", function() {
3347
+ return x;
3348
+ }), r.d(s, "loadScriptsQueue", function() {
3349
+ return _;
3350
+ }), r.d(s, "getMaxDepsChain", function() {
2242
3351
  return a;
2243
- }), o.d(r, "depsParser", function() {
3352
+ }), r.d(s, "depsParser", function() {
2244
3353
  return i;
2245
3354
  });
2246
3355
  var l = function() {
2247
- return (l = Object.assign || function(y) {
2248
- for (var m, v = 1, f = arguments.length; v < f; v++) for (var u in m = arguments[v]) Object.prototype.hasOwnProperty.call(m, u) && (y[u] = m[u]);
2249
- return y;
3356
+ return (l = Object.assign || function(w) {
3357
+ for (var u, k = 1, v = arguments.length; k < v; k++) for (var f in u = arguments[k]) Object.prototype.hasOwnProperty.call(u, f) && (w[f] = u[f]);
3358
+ return w;
2250
3359
  }).apply(this, arguments);
2251
- }, c = function(y, m, v, f) {
2252
- return new (v || (v = Promise))(function(u, k) {
2253
- function C(I) {
3360
+ }, c = function(w, u, k, v) {
3361
+ return new (k || (k = Promise))(function(f, U) {
3362
+ function M(O) {
2254
3363
  try {
2255
- R(f.next(I));
2256
- } catch (w) {
2257
- k(w);
3364
+ I(v.next(O));
3365
+ } catch (E) {
3366
+ U(E);
2258
3367
  }
2259
3368
  }
2260
- function L(I) {
3369
+ function F(O) {
2261
3370
  try {
2262
- R(f.throw(I));
2263
- } catch (w) {
2264
- k(w);
3371
+ I(v.throw(O));
3372
+ } catch (E) {
3373
+ U(E);
2265
3374
  }
2266
3375
  }
2267
- function R(I) {
2268
- var w;
2269
- I.done ? u(I.value) : (w = I.value, w instanceof v ? w : new v(function(O) {
2270
- O(w);
2271
- })).then(C, L);
3376
+ function I(O) {
3377
+ var E;
3378
+ O.done ? f(O.value) : (E = O.value, E instanceof k ? E : new k(function(D) {
3379
+ D(E);
3380
+ })).then(M, F);
2272
3381
  }
2273
- R((f = f.apply(y, [])).next());
3382
+ I((v = v.apply(w, [])).next());
2274
3383
  });
2275
- }, b = function(y, m) {
2276
- var v, f, u, k, C = { label: 0, sent: function() {
2277
- if (1 & u[0]) throw u[1];
2278
- return u[1];
3384
+ }, d = function(w, u) {
3385
+ var k, v, f, U, M = { label: 0, sent: function() {
3386
+ if (1 & f[0]) throw f[1];
3387
+ return f[1];
2279
3388
  }, trys: [], ops: [] };
2280
- return k = { next: L(0), throw: L(1), return: L(2) }, typeof Symbol == "function" && (k[Symbol.iterator] = function() {
3389
+ return U = { next: F(0), throw: F(1), return: F(2) }, typeof Symbol == "function" && (U[Symbol.iterator] = function() {
2281
3390
  return this;
2282
- }), k;
2283
- function L(R) {
2284
- return function(I) {
2285
- return function(w) {
2286
- if (v) throw new TypeError("Generator is already executing.");
2287
- for (; C; ) try {
2288
- if (v = 1, f && (u = 2 & w[0] ? f.return : w[0] ? f.throw || ((u = f.return) && u.call(f), 0) : f.next) && !(u = u.call(f, w[1])).done) return u;
2289
- switch (f = 0, u && (w = [2 & w[0], u.value]), w[0]) {
3391
+ }), U;
3392
+ function F(I) {
3393
+ return function(O) {
3394
+ return function(E) {
3395
+ if (k) throw new TypeError("Generator is already executing.");
3396
+ for (; M; ) try {
3397
+ if (k = 1, v && (f = 2 & E[0] ? v.return : E[0] ? v.throw || ((f = v.return) && f.call(v), 0) : v.next) && !(f = f.call(v, E[1])).done) return f;
3398
+ switch (v = 0, f && (E = [2 & E[0], f.value]), E[0]) {
2290
3399
  case 0:
2291
3400
  case 1:
2292
- u = w;
3401
+ f = E;
2293
3402
  break;
2294
3403
  case 4:
2295
- return C.label++, { value: w[1], done: !1 };
3404
+ return M.label++, { value: E[1], done: !1 };
2296
3405
  case 5:
2297
- C.label++, f = w[1], w = [0];
3406
+ M.label++, v = E[1], E = [0];
2298
3407
  continue;
2299
3408
  case 7:
2300
- w = C.ops.pop(), C.trys.pop();
3409
+ E = M.ops.pop(), M.trys.pop();
2301
3410
  continue;
2302
3411
  default:
2303
- if (u = C.trys, !((u = u.length > 0 && u[u.length - 1]) || w[0] !== 6 && w[0] !== 2)) {
2304
- C = 0;
3412
+ if (f = M.trys, !((f = f.length > 0 && f[f.length - 1]) || E[0] !== 6 && E[0] !== 2)) {
3413
+ M = 0;
2305
3414
  continue;
2306
3415
  }
2307
- if (w[0] === 3 && (!u || w[1] > u[0] && w[1] < u[3])) {
2308
- C.label = w[1];
3416
+ if (E[0] === 3 && (!f || E[1] > f[0] && E[1] < f[3])) {
3417
+ M.label = E[1];
2309
3418
  break;
2310
3419
  }
2311
- if (w[0] === 6 && C.label < u[1]) {
2312
- C.label = u[1], u = w;
3420
+ if (E[0] === 6 && M.label < f[1]) {
3421
+ M.label = f[1], f = E;
2313
3422
  break;
2314
3423
  }
2315
- if (u && C.label < u[2]) {
2316
- C.label = u[2], C.ops.push(w);
3424
+ if (f && M.label < f[2]) {
3425
+ M.label = f[2], M.ops.push(E);
2317
3426
  break;
2318
3427
  }
2319
- u[2] && C.ops.pop(), C.trys.pop();
3428
+ f[2] && M.ops.pop(), M.trys.pop();
2320
3429
  continue;
2321
3430
  }
2322
- w = m.call(y, C);
2323
- } catch (O) {
2324
- w = [6, O], f = 0;
3431
+ E = u.call(w, M);
3432
+ } catch (D) {
3433
+ E = [6, D], v = 0;
2325
3434
  } finally {
2326
- v = u = 0;
3435
+ k = f = 0;
2327
3436
  }
2328
- if (5 & w[0]) throw w[1];
2329
- return { value: w[0] ? w[1] : void 0, done: !0 };
2330
- }([R, I]);
3437
+ if (5 & E[0]) throw E[1];
3438
+ return { value: E[0] ? E[1] : void 0, done: !0 };
3439
+ }([I, O]);
2331
3440
  };
2332
3441
  }
2333
- }, P = function(y) {
3442
+ }, P = function(w) {
2334
3443
  if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
2335
- var m, v = y[Symbol.asyncIterator];
2336
- return v ? v.call(y) : (y = typeof __values == "function" ? __values(y) : y[Symbol.iterator](), m = {}, f("next"), f("throw"), f("return"), m[Symbol.asyncIterator] = function() {
3444
+ var u, k = w[Symbol.asyncIterator];
3445
+ return k ? k.call(w) : (w = typeof __values == "function" ? __values(w) : w[Symbol.iterator](), u = {}, v("next"), v("throw"), v("return"), u[Symbol.asyncIterator] = function() {
2337
3446
  return this;
2338
- }, m);
2339
- function f(u) {
2340
- m[u] = y[u] && function(k) {
2341
- return new Promise(function(C, L) {
2342
- (function(R, I, w, O) {
2343
- Promise.resolve(O).then(function(X) {
2344
- R({ value: X, done: w });
2345
- }, I);
2346
- })(C, L, (k = y[u](k)).done, k.value);
3447
+ }, u);
3448
+ function v(f) {
3449
+ u[f] = w[f] && function(U) {
3450
+ return new Promise(function(M, F) {
3451
+ (function(I, O, E, D) {
3452
+ Promise.resolve(D).then(function(se) {
3453
+ I({ value: se, done: E });
3454
+ }, O);
3455
+ })(M, F, (U = w[f](U)).done, U.value);
2347
3456
  });
2348
3457
  };
2349
3458
  }
2350
3459
  };
2351
- function A(y, m) {
2352
- return m === void 0 && (m = !1), new Promise(function(v, f) {
2353
- var u = m ? document.head : document.body, k = document.createElement("script");
2354
- k.type = "text/javascript", k.src = y, k.crossOrigin = "anonymous", k.onreadystatechange = v, k.onload = v, k.onerror = f, u.appendChild(k);
3460
+ function A(w, u) {
3461
+ return u === void 0 && (u = !1), new Promise(function(k, v) {
3462
+ var f = u ? document.head : document.body, U = document.createElement("script");
3463
+ U.type = "text/javascript", U.src = w, U.crossOrigin = "anonymous", U.onreadystatechange = k, U.onload = k, U.onerror = v, f.appendChild(U);
2355
3464
  });
2356
3465
  }
2357
- var p = function(y, m) {
2358
- return m === void 0 && (m = {}), c(void 0, void 0, void 0, function() {
2359
- var v, f, u, k, C;
2360
- return b(this, function(L) {
2361
- switch (L.label) {
3466
+ var m = function(w, u) {
3467
+ return u === void 0 && (u = {}), c(void 0, void 0, void 0, function() {
3468
+ var k, v, f, U, M;
3469
+ return d(this, function(F) {
3470
+ switch (F.label) {
2362
3471
  case 0:
2363
- return v = m.baseUrl, f = v === void 0 ? "" : v, u = m.lastLoadResult, k = m.inHead, C = k !== void 0 && k, [4, Promise.all(y.map(function(R) {
3472
+ return k = u.baseUrl, v = k === void 0 ? "" : k, f = u.lastLoadResult, U = u.inHead, M = U !== void 0 && U, [4, Promise.all(w.map(function(I) {
2364
3473
  return c(void 0, void 0, void 0, function() {
2365
- var I, w, O, X, Y, Z, ne, q;
2366
- return b(this, function(oe) {
2367
- switch (oe.label) {
3474
+ var O, E, D, se, K, oe, ae, X;
3475
+ return d(this, function(ue) {
3476
+ switch (ue.label) {
2368
3477
  case 0:
2369
- return I = R.name, w = R.path, O = R.deps, (ne = {})[I] = !0, X = ne, (q = {})[I] = !1, Y = q, window[I] ? [2, X] : [3, 1];
3478
+ return O = I.name, E = I.path, D = I.deps, (ae = {})[O] = !0, se = ae, (X = {})[O] = !1, K = X, window[O] ? [2, se] : [3, 1];
2370
3479
  case 1:
2371
- return Z = !0, O && u && [].concat(O).forEach(function(fe) {
2372
- u[fe] !== !1 && (Z = !0);
2373
- }), Z ? [4, A(w.indexOf("http") === 0 || w.indexOf("//:") === 0 ? w : f + w, C).then(function() {
2374
- return X;
3480
+ return oe = !0, D && f && [].concat(D).forEach(function(me) {
3481
+ f[me] !== !1 && (oe = !0);
3482
+ }), oe ? [4, A(E.indexOf("http") === 0 || E.indexOf("//:") === 0 ? E : v + E, M).then(function() {
3483
+ return se;
2375
3484
  }).catch(function() {
2376
- return Y;
3485
+ return K;
2377
3486
  })] : [3, 3];
2378
3487
  case 2:
2379
- return [2, oe.sent()];
3488
+ return [2, ue.sent()];
2380
3489
  case 3:
2381
- return [2, Y];
3490
+ return [2, K];
2382
3491
  }
2383
3492
  });
2384
3493
  });
2385
3494
  }))];
2386
3495
  case 1:
2387
- return [2, L.sent()];
3496
+ return [2, F.sent()];
2388
3497
  }
2389
3498
  });
2390
3499
  });
2391
- }, F = function(y, m) {
2392
- return m === void 0 && (m = {}), function() {
2393
- var v = [].concat(i(y));
3500
+ }, S = function(w, u) {
3501
+ return u === void 0 && (u = {}), function() {
3502
+ var k = [].concat(i(w));
2394
3503
  return { next: function() {
2395
- if (v.length) {
2396
- var f = v.shift();
2397
- return p(f, m).then(function(u) {
2398
- return { value: u, done: !1 };
3504
+ if (k.length) {
3505
+ var v = k.shift();
3506
+ return m(v, u).then(function(f) {
3507
+ return { value: f, done: !1 };
2399
3508
  });
2400
3509
  }
2401
3510
  return Promise.resolve({ done: !0 });
2402
3511
  } };
2403
3512
  };
2404
- }, U = function(y, m) {
2405
- var v;
2406
- return m === void 0 && (m = {}), (v = {})[Symbol.asyncIterator] = F(y, m), v;
2407
- }, z = function(y, m) {
2408
- return m === void 0 && (m = {}), c(void 0, void 0, void 0, function() {
2409
- var v, f, u, k, C, L;
2410
- return b(this, function(R) {
2411
- switch (R.label) {
3513
+ }, x = function(w, u) {
3514
+ var k;
3515
+ return u === void 0 && (u = {}), (k = {})[Symbol.asyncIterator] = S(w, u), k;
3516
+ }, _ = function(w, u) {
3517
+ return u === void 0 && (u = {}), c(void 0, void 0, void 0, function() {
3518
+ var k, v, f, U, M, F;
3519
+ return d(this, function(I) {
3520
+ switch (I.label) {
2412
3521
  case 0:
2413
- R.trys.push([0, 5, 6, 11]), v = P(U(y, m)), R.label = 1;
3522
+ I.trys.push([0, 5, 6, 11]), k = P(x(w, u)), I.label = 1;
2414
3523
  case 1:
2415
- return [4, v.next()];
3524
+ return [4, k.next()];
2416
3525
  case 2:
2417
- if ((f = R.sent()).done) return [3, 4];
2418
- u = f.value, m.lastLoadResult = m.lastLoadResult || {}, console.log("current load: ", u), u.forEach(function(I) {
2419
- m.lastLoadResult = l(l({}, m.lastLoadResult), I);
2420
- }), R.label = 3;
3526
+ if ((v = I.sent()).done) return [3, 4];
3527
+ f = v.value, u.lastLoadResult = u.lastLoadResult || {}, console.log("current load: ", f), f.forEach(function(O) {
3528
+ u.lastLoadResult = l(l({}, u.lastLoadResult), O);
3529
+ }), I.label = 3;
2421
3530
  case 3:
2422
3531
  return [3, 1];
2423
3532
  case 4:
2424
3533
  return [3, 11];
2425
3534
  case 5:
2426
- return k = R.sent(), C = { error: k }, [3, 11];
3535
+ return U = I.sent(), M = { error: U }, [3, 11];
2427
3536
  case 6:
2428
- return R.trys.push([6, , 9, 10]), f && !f.done && (L = v.return) ? [4, L.call(v)] : [3, 8];
3537
+ return I.trys.push([6, , 9, 10]), v && !v.done && (F = k.return) ? [4, F.call(k)] : [3, 8];
2429
3538
  case 7:
2430
- R.sent(), R.label = 8;
3539
+ I.sent(), I.label = 8;
2431
3540
  case 8:
2432
3541
  return [3, 10];
2433
3542
  case 9:
2434
- if (C) throw C.error;
3543
+ if (M) throw M.error;
2435
3544
  return [7];
2436
3545
  case 10:
2437
3546
  return [7];
2438
3547
  case 11:
2439
- return [2, m.lastLoadResult];
3548
+ return [2, u.lastLoadResult];
2440
3549
  }
2441
3550
  });
2442
3551
  });
2443
3552
  };
2444
3553
  }]);
2445
3554
  });
2446
- })(lt);
2447
- var wr = lt.exports;
2448
- function ct() {
3555
+ })(Ot);
3556
+ var No = Ot.exports;
3557
+ function Bt() {
2449
3558
  const e = [
2450
3559
  {
2451
3560
  name: "markdownit",
@@ -2457,25 +3566,25 @@ function ct() {
2457
3566
  }
2458
3567
  ];
2459
3568
  let t = {};
2460
- wr.loadScriptsQueue(e, {
3569
+ No.loadScriptsQueue(e, {
2461
3570
  baseUrl: "/scripts/ai/",
2462
3571
  lastLoadResult: t,
2463
3572
  inHead: !1
2464
- }).then((s) => {
2465
- if (console.log("load ai deps: ", s), window.markdownit) {
2466
- const r = window.markdownit();
2467
- console.log("markdownit: ", r), yn();
3573
+ }).then((n) => {
3574
+ if (console.log("load ai deps: ", n), window.markdownit) {
3575
+ const s = window.markdownit();
3576
+ console.log("markdownit: ", s), es();
2468
3577
  }
2469
3578
  });
2470
3579
  }
2471
- const br = {
3580
+ const Vo = {
2472
3581
  key: 0,
2473
3582
  class: "ai-assistant"
2474
- }, kr = {
3583
+ }, Fo = {
2475
3584
  name: "AiChat"
2476
3585
  //这个⾮常重要,就是未来你放到其他项⽬中,组件标签的名字,⽐如:<sz-workflow></sz-workflow>
2477
- }, Sr = /* @__PURE__ */ Ze({
2478
- ...kr,
3586
+ }, Do = /* @__PURE__ */ Ue({
3587
+ ...Fo,
2479
3588
  props: {
2480
3589
  token: {
2481
3590
  type: String,
@@ -2544,6 +3653,23 @@ const br = {
2544
3653
  /**
2545
3654
  * 是否显示上传音频/视频识别入口,默认关闭
2546
3655
  */
3656
+ /**
3657
+ * 全双工语音(gateway-openai /api/voice):识别填入输入框,助手回复朗读。
3658
+ * 默认关闭以向后兼容;voiceApiBase 留空用默认 /api/voice。
3659
+ */
3660
+ enableDuplexVoice: {
3661
+ type: Boolean,
3662
+ default: !1
3663
+ },
3664
+ voiceApiBase: {
3665
+ type: String,
3666
+ default: ""
3667
+ },
3668
+ /** 朗读助手回复(TTS),默认关闭;运行时切换即时生效 */
3669
+ enableVoiceTts: {
3670
+ type: Boolean,
3671
+ default: !1
3672
+ },
2547
3673
  enableVoiceUpload: {
2548
3674
  type: Boolean,
2549
3675
  default: !1
@@ -2574,19 +3700,19 @@ const br = {
2574
3700
  },
2575
3701
  emits: ["ui-action"],
2576
3702
  setup(e, { emit: t }) {
2577
- const s = T(!1), r = T(!1), o = t, n = () => {
2578
- s.value = !s.value;
3703
+ const n = R(!1), s = R(!1), r = t, o = () => {
3704
+ n.value = !n.value;
2579
3705
  }, a = () => {
2580
- r.value = !0, s.value = !1;
3706
+ s.value = !0, n.value = !1;
2581
3707
  }, i = (l) => {
2582
3708
  console.log("用户输入:", l);
2583
3709
  };
2584
- return ct(), (l, c) => r.value ? $("", !0) : (S(), x("div", br, [
2585
- D(it, {
2586
- modelValue: s.value,
2587
- "onUpdate:modelValue": c[0] || (c[0] = (b) => s.value = b),
3710
+ return Bt(), (l, c) => s.value ? H("", !0) : (T(), L("div", Vo, [
3711
+ ne($t, {
3712
+ modelValue: n.value,
3713
+ "onUpdate:modelValue": c[0] || (c[0] = (d) => n.value = d),
2588
3714
  onSubmit: i,
2589
- onUiAction: c[1] || (c[1] = (b) => o("ui-action", b)),
3715
+ onUiAction: c[1] || (c[1] = (d) => r("ui-action", d)),
2590
3716
  token: e.token,
2591
3717
  identifier: e.identifier,
2592
3718
  baseUrl: e.baseUrl,
@@ -2600,40 +3726,43 @@ const br = {
2600
3726
  soundBaseUrl: e.soundBaseUrl,
2601
3727
  workerUrl: e.workerUrl,
2602
3728
  enableVoiceInput: e.enableVoiceInput,
3729
+ enableDuplexVoice: e.enableDuplexVoice,
3730
+ voiceApiBase: e.voiceApiBase,
3731
+ enableVoiceTts: e.enableVoiceTts,
2603
3732
  enableVoiceUpload: e.enableVoiceUpload
2604
- }, null, 8, ["modelValue", "token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "customUi", "uiActionHandler", "mockResponse", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableVoiceUpload"]),
2605
- d("div", {
3733
+ }, null, 8, ["modelValue", "token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "customUi", "uiActionHandler", "mockResponse", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableDuplexVoice", "voiceApiBase", "enableVoiceTts", "enableVoiceUpload"]),
3734
+ p("div", {
2606
3735
  class: "ai-icon",
2607
- onClick: n
3736
+ onClick: o
2608
3737
  }, [
2609
- d("div", {
3738
+ p("div", {
2610
3739
  class: "close-icon",
2611
- onClick: St(a, ["stop"])
3740
+ onClick: on(a, ["stop"])
2612
3741
  }, [...c[2] || (c[2] = [
2613
- d("svg", {
3742
+ p("svg", {
2614
3743
  viewBox: "0 0 1024 1024",
2615
3744
  width: "8",
2616
3745
  height: "8"
2617
3746
  }, [
2618
- d("path", {
3747
+ p("path", {
2619
3748
  d: "M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",
2620
3749
  fill: "currentColor"
2621
3750
  })
2622
3751
  ], -1)
2623
3752
  ])]),
2624
- c[3] || (c[3] = d("img", {
2625
- src: Ct,
3753
+ c[3] || (c[3] = p("img", {
3754
+ src: rn,
2626
3755
  alt: "AI助手"
2627
3756
  }, null, -1)),
2628
- c[4] || (c[4] = d("span", { class: "ai-icon-text" }, "AI助手", -1))
3757
+ c[4] || (c[4] = p("span", { class: "ai-icon-text" }, "AI助手", -1))
2629
3758
  ])
2630
3759
  ]));
2631
3760
  }
2632
- }), Cr = { class: "ai-chat-plain" }, Ar = {
3761
+ }), Ho = { class: "ai-chat-plain" }, qo = {
2633
3762
  name: "AiChatPlain"
2634
3763
  // 注册后的组件标签名:<sz-ai-chat-plain>
2635
- }, xr = /* @__PURE__ */ Ze({
2636
- ...Ar,
3764
+ }, Wo = /* @__PURE__ */ Ue({
3765
+ ...qo,
2637
3766
  props: {
2638
3767
  token: {
2639
3768
  type: String,
@@ -2702,6 +3831,23 @@ const br = {
2702
3831
  /**
2703
3832
  * 是否显示上传音频/视频识别入口,默认关闭
2704
3833
  */
3834
+ /**
3835
+ * 全双工语音(gateway-openai /api/voice):识别填入输入框,助手回复朗读。
3836
+ * 默认关闭以向后兼容;voiceApiBase 留空用默认 /api/voice。
3837
+ */
3838
+ enableDuplexVoice: {
3839
+ type: Boolean,
3840
+ default: !1
3841
+ },
3842
+ voiceApiBase: {
3843
+ type: String,
3844
+ default: ""
3845
+ },
3846
+ /** 朗读助手回复(TTS),默认关闭;运行时切换即时生效 */
3847
+ enableVoiceTts: {
3848
+ type: Boolean,
3849
+ default: !1
3850
+ },
2705
3851
  enableVoiceUpload: {
2706
3852
  type: Boolean,
2707
3853
  default: !1
@@ -2732,9 +3878,9 @@ const br = {
2732
3878
  },
2733
3879
  emits: ["submit", "ui-action"],
2734
3880
  setup(e, { emit: t }) {
2735
- const s = t;
2736
- return ct(), (r, o) => (S(), x("div", Cr, [
2737
- D(it, {
3881
+ const n = t;
3882
+ return Bt(), (s, r) => (T(), L("div", Ho, [
3883
+ ne($t, {
2738
3884
  "model-value": !0,
2739
3885
  token: e.token,
2740
3886
  identifier: e.identifier,
@@ -2749,242 +3895,279 @@ const br = {
2749
3895
  soundBaseUrl: e.soundBaseUrl,
2750
3896
  workerUrl: e.workerUrl,
2751
3897
  enableVoiceInput: e.enableVoiceInput,
3898
+ enableDuplexVoice: e.enableDuplexVoice,
3899
+ voiceApiBase: e.voiceApiBase,
3900
+ enableVoiceTts: e.enableVoiceTts,
2752
3901
  enableVoiceUpload: e.enableVoiceUpload,
2753
3902
  embedded: !0,
2754
- onSubmit: o[0] || (o[0] = (n) => s("submit", n)),
2755
- onUiAction: o[1] || (o[1] = (n) => s("ui-action", n))
2756
- }, null, 8, ["token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "customUi", "uiActionHandler", "mockResponse", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableVoiceUpload"])
3903
+ onSubmit: r[0] || (r[0] = (o) => n("submit", o)),
3904
+ onUiAction: r[1] || (r[1] = (o) => n("ui-action", o))
3905
+ }, null, 8, ["token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "customUi", "uiActionHandler", "mockResponse", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableDuplexVoice", "voiceApiBase", "enableVoiceTts", "enableVoiceUpload"])
2757
3906
  ]));
2758
3907
  }
2759
- }), Ge = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3908
+ }), wt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2760
3909
  __proto__: null,
2761
- SzAiChat: Sr,
2762
- SzAiChatPlain: xr
2763
- }, Symbol.toStringTag, { value: "Module" })), ze = function(e) {
2764
- if (!ze.installed) {
2765
- ze.installed = !0;
2766
- for (let t in Ge) {
2767
- const s = Reflect.get(Ge, t);
2768
- e.component(s.name, s);
3910
+ SzAiChat: Do,
3911
+ SzAiChatPlain: Wo
3912
+ }, Symbol.toStringTag, { value: "Module" })), Qe = function(e) {
3913
+ if (!Qe.installed) {
3914
+ Qe.installed = !0;
3915
+ for (let t in wt) {
3916
+ const n = Reflect.get(wt, t);
3917
+ e.component(n.name, n);
2769
3918
  }
2770
3919
  }
2771
- }, Tr = (e, t) => {
2772
- const s = t ? `?${new URLSearchParams(t).toString()}` : "";
2773
- console.log(`点击了路由链接: ${e}${s}`);
2774
- }, Rr = (e) => {
3920
+ }, Go = (e, t) => {
3921
+ const n = t ? `?${new URLSearchParams(t).toString()}` : "";
3922
+ console.log(`点击了路由链接: ${e}${n}`);
3923
+ }, Jo = (e) => {
2775
3924
  const t = e.indexOf("?");
2776
3925
  if (t === -1)
2777
3926
  return { routeName: e };
2778
- const s = e.substring(0, t), r = e.substring(t + 1), o = {};
2779
- return new URLSearchParams(r).forEach((a, i) => {
2780
- o[i] = a;
2781
- }), { routeName: s, queryParams: Object.keys(o).length > 0 ? o : void 0 };
2782
- }, Ur = {
3927
+ const n = e.substring(0, t), s = e.substring(t + 1), r = {};
3928
+ return new URLSearchParams(s).forEach((a, i) => {
3929
+ r[i] = a;
3930
+ }), { routeName: n, queryParams: Object.keys(r).length > 0 ? r : void 0 };
3931
+ }, Ko = {
2783
3932
  color: "#536fec",
2784
3933
  fontWeight: "bold",
2785
3934
  textDecoration: "underline",
2786
3935
  cursor: "pointer",
2787
3936
  padding: "0 3px"
2788
- }, _r = (e) => {
2789
- const t = /#router:([^#]+)#/g, s = [];
2790
- let r = 0, o;
2791
- for (; (o = t.exec(e)) !== null; ) {
2792
- o.index > r && s.push({ text: e.substring(r, o.index) });
2793
- const n = o[1], { routeName: a, queryParams: i } = Rr(n);
2794
- s.push({ text: a, routeName: a, queryParams: i }), r = t.lastIndex;
2795
- }
2796
- return r < e.length && s.push({ text: e.substring(r) }), s;
2797
- }, Pr = (e, t, s = {}, r) => {
2798
- const { onRouteClick: o = Tr, linkStyle: n = {} } = s, a = document.createElement("a");
3937
+ }, Yo = (e) => {
3938
+ const t = /#router:([^#]+)#/g, n = [];
3939
+ let s = 0, r;
3940
+ for (; (r = t.exec(e)) !== null; ) {
3941
+ r.index > s && n.push({ text: e.substring(s, r.index) });
3942
+ const o = r[1], { routeName: a, queryParams: i } = Jo(o);
3943
+ n.push({ text: a, routeName: a, queryParams: i }), s = t.lastIndex;
3944
+ }
3945
+ return s < e.length && n.push({ text: e.substring(s) }), n;
3946
+ }, Xo = (e, t, n = {}, s) => {
3947
+ const { onRouteClick: r = Go, linkStyle: o = {} } = n, a = document.createElement("a");
2799
3948
  a.href = "#", a.textContent = e;
2800
- const i = { ...Ur, ...n };
3949
+ const i = { ...Ko, ...o };
2801
3950
  return Object.assign(a.style, i), a.addEventListener("click", (l) => {
2802
- l.preventDefault(), o(t, r);
3951
+ l.preventDefault(), r(t, s);
2803
3952
  }), a;
2804
- }, Mr = (e) => {
2805
- const t = /#router:([^#]+)#/g, s = [], r = document.createTreeWalker(
3953
+ }, Zo = (e) => {
3954
+ const t = /#router:([^#]+)#/g, n = [], s = document.createTreeWalker(
2806
3955
  e,
2807
3956
  NodeFilter.SHOW_TEXT,
2808
3957
  null
2809
3958
  );
2810
- let o = r.nextNode();
2811
- for (; o; ) {
2812
- const n = o, a = n.textContent || "";
3959
+ let r = s.nextNode();
3960
+ for (; r; ) {
3961
+ const o = r, a = o.textContent || "";
2813
3962
  if (t.test(a)) {
2814
3963
  t.lastIndex = 0;
2815
- const i = _r(a);
2816
- i.length > 0 && s.push({ node: n, replacements: i });
3964
+ const i = Yo(a);
3965
+ i.length > 0 && n.push({ node: o, replacements: i });
2817
3966
  }
2818
- o = r.nextNode();
3967
+ r = s.nextNode();
2819
3968
  }
2820
- return s;
2821
- }, Lr = (e, t, s = {}) => {
2822
- const r = Mr(e);
2823
- r.forEach(({ node: o, replacements: n }) => {
3969
+ return n;
3970
+ }, rr = (e, t, n = {}) => {
3971
+ const s = Zo(e);
3972
+ s.forEach(({ node: r, replacements: o }) => {
2824
3973
  var i;
2825
3974
  const a = document.createDocumentFragment();
2826
- n.forEach(({ text: l, routeName: c, queryParams: b }) => {
3975
+ o.forEach(({ text: l, routeName: c, queryParams: d }) => {
2827
3976
  if (c) {
2828
- const P = Pr(l, c, s, b);
3977
+ const P = Xo(l, c, n, d);
2829
3978
  a.appendChild(P);
2830
3979
  } else
2831
3980
  a.appendChild(document.createTextNode(l));
2832
- }), (i = o.parentNode) == null || i.replaceChild(a, o);
2833
- }), s != null && s.nodeCallback && r.forEach(({ node: o, replacements: n }) => {
3981
+ }), (i = r.parentNode) == null || i.replaceChild(a, r);
3982
+ }), n != null && n.nodeCallback && s.forEach(({ node: r, replacements: o }) => {
2834
3983
  var a;
2835
- (a = s.nodeCallback) == null || a.call(s, o, n);
3984
+ (a = n.nodeCallback) == null || a.call(n, r, o);
2836
3985
  });
2837
- }, we = "szjy-voice-models", Ae = "szjy-voice-cache-v1";
2838
- function be() {
3986
+ }, $e = "szjy-voice-models", He = "szjy-voice-cache-v1";
3987
+ function Oe() {
2839
3988
  return typeof navigator < "u" && !!navigator.storage && typeof navigator.storage.getDirectory == "function";
2840
3989
  }
2841
- async function Oe(e = we) {
2842
- if (!be()) return null;
3990
+ async function st(e = $e) {
3991
+ if (!Oe()) return null;
2843
3992
  try {
2844
3993
  return await (await navigator.storage.getDirectory()).getDirectoryHandle(e, { create: !0 });
2845
3994
  } catch (t) {
2846
3995
  return console.warn("[OPFS] 获取目录失败,将使用降级缓存:", t), null;
2847
3996
  }
2848
3997
  }
2849
- async function $r(e, t, s = we) {
2850
- if (be())
3998
+ async function ar(e, t, n = $e) {
3999
+ if (Oe())
2851
4000
  try {
2852
- const r = await Oe(s);
2853
- if (r) {
2854
- const n = await (await r.getFileHandle(e, { create: !0 })).createWritable();
2855
- return await n.write(t), await n.close(), !0;
4001
+ const s = await st(n);
4002
+ if (s) {
4003
+ const o = await (await s.getFileHandle(e, { create: !0 })).createWritable();
4004
+ return await o.write(t), await o.close(), !0;
2856
4005
  }
2857
- } catch (r) {
2858
- console.warn(`[OPFS] 写入文件 ${e} 失败:`, r);
4006
+ } catch (s) {
4007
+ console.warn(`[OPFS] 写入文件 ${e} 失败:`, s);
2859
4008
  }
2860
4009
  if (typeof caches < "u")
2861
4010
  try {
2862
- const r = await caches.open(Ae), o = new Response(t, {
4011
+ const s = await caches.open(He), r = new Response(t, {
2863
4012
  headers: { "Content-Type": "application/octet-stream" }
2864
4013
  });
2865
- return await r.put(`/${s}/${e}`, o), !0;
2866
- } catch (r) {
2867
- console.warn(`[CacheStorage] 缓存写入 ${e} 失败:`, r);
4014
+ return await s.put(`/${n}/${e}`, r), !0;
4015
+ } catch (s) {
4016
+ console.warn(`[CacheStorage] 缓存写入 ${e} 失败:`, s);
2868
4017
  }
2869
4018
  return !1;
2870
4019
  }
2871
- async function Or(e, t = we) {
2872
- if (be())
4020
+ async function ir(e, t = $e) {
4021
+ if (Oe())
2873
4022
  try {
2874
- const s = await Oe(t);
2875
- if (s)
2876
- return await (await (await s.getFileHandle(e, { create: !1 })).getFile()).arrayBuffer();
4023
+ const n = await st(t);
4024
+ if (n)
4025
+ return await (await (await n.getFileHandle(e, { create: !1 })).getFile()).arrayBuffer();
2877
4026
  } catch {
2878
4027
  }
2879
4028
  if (typeof caches < "u")
2880
4029
  try {
2881
- const r = await (await caches.open(Ae)).match(`/${t}/${e}`);
2882
- if (r)
2883
- return await r.arrayBuffer();
4030
+ const s = await (await caches.open(He)).match(`/${t}/${e}`);
4031
+ if (s)
4032
+ return await s.arrayBuffer();
2884
4033
  } catch {
2885
4034
  }
2886
4035
  return null;
2887
4036
  }
2888
- async function Nr(e, t = we) {
2889
- if (be())
4037
+ async function lr(e, t = $e) {
4038
+ if (Oe())
2890
4039
  try {
2891
- const s = await Oe(t);
2892
- if (s)
2893
- return (await (await s.getFileHandle(e, { create: !1 })).getFile()).size > 0;
4040
+ const n = await st(t);
4041
+ if (n)
4042
+ return (await (await n.getFileHandle(e, { create: !1 })).getFile()).size > 0;
2894
4043
  } catch {
2895
4044
  }
2896
4045
  if (typeof caches < "u")
2897
4046
  try {
2898
- return !!await (await caches.open(Ae)).match(`/${t}/${e}`);
4047
+ return !!await (await caches.open(He)).match(`/${t}/${e}`);
2899
4048
  } catch {
2900
4049
  }
2901
4050
  return !1;
2902
4051
  }
2903
- async function Fr(e = we) {
4052
+ async function cr(e = $e) {
2904
4053
  let t = !1;
2905
- if (be())
4054
+ if (Oe())
2906
4055
  try {
2907
4056
  await (await navigator.storage.getDirectory()).removeEntry(e, { recursive: !0 }), t = !0, console.log(`[OPFS] 成功清空语音模型缓存目录: ${e}`);
2908
- } catch (s) {
2909
- s.name === "NotFoundError" ? t = !0 : console.warn(`[OPFS] 清理目录 ${e} 异常:`, s);
4057
+ } catch (n) {
4058
+ n.name === "NotFoundError" ? t = !0 : console.warn(`[OPFS] 清理目录 ${e} 异常:`, n);
2910
4059
  }
2911
4060
  if (typeof caches < "u")
2912
4061
  try {
2913
- const s = await caches.keys();
2914
- for (const r of s)
2915
- (r.includes("transformers") || r.includes("szjy-voice") || r === Ae) && (await caches.delete(r), t = !0);
2916
- } catch (s) {
2917
- console.warn("[CacheStorage] 清除缓存异常:", s);
4062
+ const n = await caches.keys();
4063
+ for (const s of n)
4064
+ (s.includes("transformers") || s.includes("szjy-voice") || s === He) && (await caches.delete(s), t = !0);
4065
+ } catch (n) {
4066
+ console.warn("[CacheStorage] 清除缓存异常:", n);
2918
4067
  }
2919
4068
  return t;
2920
4069
  }
2921
- const Ir = "0.1.16", Er = "Sz";
2922
- function Br({
2923
- componentPrefix: e = Er,
4070
+ const Qo = "0.1.17", er = "Sz";
4071
+ function ur({
4072
+ componentPrefix: e = er,
2924
4073
  components: t = []
2925
4074
  } = {}) {
2926
- const s = [];
2927
- function r(n, a, i) {
2928
- n.component(e + a) || n.component(
4075
+ const n = [];
4076
+ function s(o, a, i) {
4077
+ o.component(e + a) || o.component(
2929
4078
  e + a,
2930
4079
  i
2931
4080
  );
2932
4081
  }
2933
- function o(n) {
2934
- s.includes(n) || (s.push(n), t.forEach((a) => {
4082
+ function r(o) {
4083
+ n.includes(o) || (n.push(o), t.forEach((a) => {
2935
4084
  const { name: i, alias: l } = a;
2936
- r(n, i, a), l && l.forEach((c) => {
2937
- r(n, c, a);
4085
+ s(o, i, a), l && l.forEach((c) => {
4086
+ s(o, c, a);
2938
4087
  });
2939
4088
  }));
2940
4089
  }
2941
4090
  return {
2942
- version: Ir,
4091
+ version: Qo,
2943
4092
  componentPrefix: e,
2944
- install: o
4093
+ install: r
2945
4094
  };
2946
4095
  }
2947
- const Vr = {
4096
+ const dr = {
2948
4097
  install(e) {
2949
- ze(e);
4098
+ Qe(e);
2950
4099
  }
2951
4100
  };
2952
4101
  export {
2953
- _n as AudioRecorder,
2954
- Et as DEFAULT_MOCK_RESPONSE,
2955
- at as DEFAULT_WHISPER_WORKER_URL,
2956
- hn as SZJY_UI_FENCE_LANG,
2957
- Un as StreamResampler,
2958
- Sr as SzAiChat,
2959
- xr as SzAiChatPlain,
2960
- Ln as VoiceInputManager,
2961
- gn as bindSzjyUiEvents,
2962
- Fr as clearVoiceModelCache,
2963
- Br as create,
2964
- Ot as createMockStylized,
2965
- Pr as createRouteLink,
2966
- Mn as decodeAudioFile,
2967
- Vr as default,
2968
- ve as escapeHtml,
2969
- Mr as findRouteTextNodes,
2970
- qe as float32ToWav,
2971
- Or as getFileFromCache,
2972
- Oe as getOPFSDirectory,
2973
- Wt as getSzjyUiAction,
2974
- Dt as getSzjyUiComponent,
2975
- Nr as hasFileInCache,
2976
- Gt as hasSzjyUiAction,
2977
- qt as hasSzjyUiComponent,
2978
- be as isOPFSSupported,
2979
- Rr as parseRouteMarkerContent,
2980
- _r as parseRouteMarkers,
2981
- pn as parseSzjyUiFence,
2982
- Ht as registerSzjyUiAction,
2983
- et as registerSzjyUiComponent,
2984
- Xt as renderActionAttrs,
2985
- Kt as renderSzjyUiBlock,
2986
- tt as renderSzjyUiNode,
2987
- Pn as resampleAudioData,
2988
- Lr as routeLinkRender,
2989
- $r as saveFileToCache
4102
+ sr as AEC_DEFAULTS,
4103
+ fs as AudioRecorder,
4104
+ gt as BUFFER_SIZE,
4105
+ Ls as CANCEL_DRAG_PX,
4106
+ nt as DEFAULT_BASE_PATH,
4107
+ gn as DEFAULT_MOCK_RESPONSE,
4108
+ Ut as DEFAULT_WHISPER_WORKER_URL,
4109
+ pt as ENERGY_THRESHOLD,
4110
+ zt as EqualizerBars,
4111
+ Rs as HOLD_THRESHOLD_MS,
4112
+ Es as KEY_HOLD_THRESHOLD_MS,
4113
+ bs as LEVEL_CEILING,
4114
+ mt as MAX_SEGMENT_MS,
4115
+ Cs as MIN_HOLD_SEGMENT_S,
4116
+ js as NlmsAec,
4117
+ As as PARTIAL_INTERVAL_MS,
4118
+ xs as PARTIAL_MAX_S,
4119
+ Ts as PARTIAL_MIN_S,
4120
+ vt as POST_PAD_MS,
4121
+ Ss as PRE_PAD_MS,
4122
+ xe as SAMPLE_RATE,
4123
+ ks as SILENCE_TIMEOUT_MS,
4124
+ Yn as SZJY_UI_FENCE_LANG,
4125
+ ds as StreamResampler,
4126
+ Do as SzAiChat,
4127
+ Wo as SzAiChatPlain,
4128
+ jt as VOICE_CONTEXT_KEY,
4129
+ to as VoiceCaptionBar,
4130
+ ws as VoiceInputManager,
4131
+ Qs as VoiceMicButton,
4132
+ Gs as VoiceOverlay,
4133
+ Mt as WAVE_BARS,
4134
+ Qn as bindSzjyUiEvents,
4135
+ cr as clearVoiceModelCache,
4136
+ ur as create,
4137
+ Os as createAsrEngine,
4138
+ Sn as createMockStylized,
4139
+ Vs as createPlaybackEngine,
4140
+ Xo as createRouteLink,
4141
+ ps as decodeAudioFile,
4142
+ dr as default,
4143
+ Ie as escapeHtml,
4144
+ Zo as findRouteTextNodes,
4145
+ ft as float32ToWav,
4146
+ zs as getConfig,
4147
+ ir as getFileFromCache,
4148
+ st as getOPFSDirectory,
4149
+ Is as getReady,
4150
+ Pn as getSzjyUiAction,
4151
+ En as getSzjyUiComponent,
4152
+ lr as hasFileInCache,
4153
+ Un as hasSzjyUiAction,
4154
+ Ln as hasSzjyUiComponent,
4155
+ Oe as isOPFSSupported,
4156
+ Bs as micErrorMessage,
4157
+ $s as openAudioStream,
4158
+ Jo as parseRouteMarkerContent,
4159
+ Yo as parseRouteMarkers,
4160
+ Xn as parseSzjyUiFence,
4161
+ or as postAsr,
4162
+ yt as postCancel,
4163
+ Rn as registerSzjyUiAction,
4164
+ Tt as registerSzjyUiComponent,
4165
+ jn as renderActionAttrs,
4166
+ _n as renderSzjyUiBlock,
4167
+ xt as renderSzjyUiNode,
4168
+ hs as resampleAudioData,
4169
+ rr as routeLinkRender,
4170
+ ar as saveFileToCache,
4171
+ Ds as useVoice,
4172
+ It as useVoiceContext
2990
4173
  };