@szjy/ai-coms 0.1.8 → 0.1.12

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,24 +1,27 @@
1
- import { computed as q, openBlock as P, createElementBlock as L, normalizeStyle as K, createElementVNode as x, normalizeClass as W, getCurrentInstance as re, ref as C, watch as ue, onUnmounted as de, createBlock as J, Transition as oe, withCtx as M, createVNode as E, createCommentVNode as B, nextTick as ae, resolveComponent as X, toDisplayString as D, createTextVNode as fe, Fragment as Y, renderList as Z, withKeys as pe, defineComponent as me, withModifiers as he } from "vue";
2
- const ve = "/images/ai-round.png", ye = "/images/ai-sqrt.png", ge = "/images/bars-loading.svg";
3
- function se(t) {
4
- return t.startsWith("http://") || t.startsWith("https://") ? t : `${location.protocol}//${location.host}${t}`;
1
+ var it = Object.defineProperty;
2
+ var lt = (r, e, a) => e in r ? it(r, e, { enumerable: !0, configurable: !0, writable: !0, value: a }) : r[e] = a;
3
+ var U = (r, e, a) => lt(r, typeof e != "symbol" ? e + "" : e, a);
4
+ import { computed as O, openBlock as w, createElementBlock as C, normalizeStyle as ue, createElementVNode as u, normalizeClass as ne, getCurrentInstance as je, ref as x, watch as Fe, onUnmounted as ct, createBlock as me, Transition as ge, withCtx as J, toDisplayString as q, withDirectives as He, vShow as qe, createCommentVNode as M, createVNode as j, nextTick as We, onBeforeUnmount as ut, resolveComponent as Ae, createTextVNode as fe, Fragment as pe, renderList as Ne, withKeys as dt, defineComponent as Ge, withModifiers as ht } from "vue";
5
+ const ft = "/images/ai-round.png", pt = "/images/ai-sqrt.png", mt = "/images/bars-loading.svg";
6
+ function Je(r) {
7
+ return r.startsWith("http://") || r.startsWith("https://") ? r : `${location.protocol}//${location.host}${r}`;
5
8
  }
6
- async function be(t, n, s, l = "", r = {}) {
7
- const { projectId: e } = r, o = se(l), u = new URL(`${o}/v1/chat/completions`), d = (r == null ? void 0 : r.authToken) || "app-oLZVFFdYyJX2QK3rdOLWsC2u";
8
- r != null && r.authToken || console.error("缺少 authToken!现在默认使用内网的 authToken");
9
- const y = new Request(u, {
9
+ async function gt(r, e, a, t = "", o = {}) {
10
+ const { projectId: n } = o, s = Je(t), i = new URL(`${s}/v1/chat/completions`), l = (o == null ? void 0 : o.authToken) || "app-oLZVFFdYyJX2QK3rdOLWsC2u";
11
+ o != null && o.authToken || console.error("缺少 authToken!现在默认使用内网的 authToken");
12
+ const y = new Request(i, {
10
13
  method: "post",
11
14
  headers: {
12
15
  "Content-Type": "application/json",
13
- Authorization: `Bearer ${d}`
16
+ Authorization: `Bearer ${l}`
14
17
  },
15
18
  body: JSON.stringify({
16
19
  model: "dify",
17
20
  stream: !0,
18
21
  inputs: {
19
- token: n,
20
- projectCode: s,
21
- ...e ? { projectId: e } : {}
22
+ token: e,
23
+ projectCode: a,
24
+ ...n ? { projectId: n } : {}
22
25
  },
23
26
  messages: [
24
27
  {
@@ -27,19 +30,19 @@ async function be(t, n, s, l = "", r = {}) {
27
30
  },
28
31
  {
29
32
  role: "user",
30
- content: t
33
+ content: r
31
34
  }
32
35
  ]
33
36
  })
34
37
  });
35
38
  return fetch(y);
36
39
  }
37
- async function we(t, n, s, l = "", r = {}) {
38
- const e = new URL("http://localhost:11434/api/chat"), o = {};
39
- Object.keys(o).forEach((d) => {
40
- e.searchParams.append(d, o[d]);
40
+ async function vt(r, e, a, t = "", o = {}) {
41
+ const n = new URL("http://localhost:11434/api/chat"), s = {};
42
+ Object.keys(s).forEach((l) => {
43
+ n.searchParams.append(l, s[l]);
41
44
  });
42
- const u = new Request(e, {
45
+ const i = new Request(n, {
43
46
  mode: "cors",
44
47
  method: "post",
45
48
  headers: {
@@ -55,23 +58,23 @@ async function we(t, n, s, l = "", r = {}) {
55
58
  },
56
59
  {
57
60
  role: "user",
58
- content: t
61
+ content: r
59
62
  }
60
63
  ]
61
64
  })
62
65
  });
63
- return fetch(u);
66
+ return fetch(i);
64
67
  }
65
- async function xe(t, n, s, l = "", r = {}) {
66
- const e = new URL(`${location.origin}/spark/v1/chat/completions`), o = {};
67
- Object.keys(o).forEach((d) => {
68
- e.searchParams.append(d, o[d]);
68
+ async function yt(r, e, a, t = "", o = {}) {
69
+ const n = new URL(`${location.origin}/spark/v1/chat/completions`), s = {};
70
+ Object.keys(s).forEach((l) => {
71
+ n.searchParams.append(l, s[l]);
69
72
  });
70
- const u = new Request(e, {
73
+ const i = new Request(n, {
71
74
  method: "post",
72
75
  headers: {
73
76
  "Content-Type": "application/json",
74
- Authorization: `Bearer ${n}`
77
+ Authorization: `Bearer ${e}`
75
78
  },
76
79
  body: JSON.stringify({
77
80
  model: "generalv4.0Ultra",
@@ -79,23 +82,23 @@ async function xe(t, n, s, l = "", r = {}) {
79
82
  messages: [
80
83
  {
81
84
  role: "user",
82
- content: t
85
+ content: r
83
86
  }
84
87
  ]
85
88
  })
86
89
  });
87
- return fetch(u);
90
+ return fetch(i);
88
91
  }
89
- async function ke(t, n, s, l = "", r = {}) {
90
- const e = new URL(`${location.origin}/siliconflow/v1/chat/completions`), o = {};
91
- Object.keys(o).forEach((d) => {
92
- e.searchParams.append(d, o[d]);
92
+ async function wt(r, e, a, t = "", o = {}) {
93
+ const n = new URL(`${location.origin}/siliconflow/v1/chat/completions`), s = {};
94
+ Object.keys(s).forEach((l) => {
95
+ n.searchParams.append(l, s[l]);
93
96
  });
94
- const u = new Request(e, {
97
+ const i = new Request(n, {
95
98
  method: "post",
96
99
  headers: {
97
100
  "Content-Type": "application/json",
98
- Authorization: `Bearer ${n}`
101
+ Authorization: `Bearer ${e}`
99
102
  },
100
103
  body: JSON.stringify({
101
104
  // 集成了大部分模型,可以免费使用
@@ -104,23 +107,23 @@ async function ke(t, n, s, l = "", r = {}) {
104
107
  messages: [
105
108
  {
106
109
  role: "user",
107
- content: t
110
+ content: r
108
111
  }
109
112
  ]
110
113
  })
111
114
  });
112
- return fetch(u);
115
+ return fetch(i);
113
116
  }
114
- async function Se(t, n, s, l = "", r = {}) {
115
- const e = new URL(`${location.origin}/moonshot/v1/chat/completions`), o = {};
116
- Object.keys(o).forEach((d) => {
117
- e.searchParams.append(d, o[d]);
117
+ async function kt(r, e, a, t = "", o = {}) {
118
+ const n = new URL(`${location.origin}/moonshot/v1/chat/completions`), s = {};
119
+ Object.keys(s).forEach((l) => {
120
+ n.searchParams.append(l, s[l]);
118
121
  });
119
- const u = new Request(e, {
122
+ const i = new Request(n, {
120
123
  method: "post",
121
124
  headers: {
122
125
  "Content-Type": "application/json",
123
- Authorization: `Bearer ${n}`
126
+ Authorization: `Bearer ${e}`
124
127
  },
125
128
  body: JSON.stringify({
126
129
  model: "moonshot-v1-8k",
@@ -132,23 +135,23 @@ async function Se(t, n, s, l = "", r = {}) {
132
135
  },
133
136
  {
134
137
  role: "user",
135
- content: t
138
+ content: r
136
139
  }
137
140
  ]
138
141
  })
139
142
  });
140
- return fetch(u);
143
+ return fetch(i);
141
144
  }
142
- async function _e(t, n, s, l = "", r = {}) {
143
- const e = new URL(`${location.origin}/dashscope/compatible-mode/v1/chat/completions`), o = {};
144
- Object.keys(o).forEach((d) => {
145
- e.searchParams.append(d, o[d]);
145
+ async function bt(r, e, a, t = "", o = {}) {
146
+ const n = new URL(`${location.origin}/dashscope/compatible-mode/v1/chat/completions`), s = {};
147
+ Object.keys(s).forEach((l) => {
148
+ n.searchParams.append(l, s[l]);
146
149
  });
147
- const u = new Request(e, {
150
+ const i = new Request(n, {
148
151
  method: "post",
149
152
  headers: {
150
153
  "Content-Type": "application/json",
151
- Authorization: `Bearer ${n}`
154
+ Authorization: `Bearer ${e}`
152
155
  },
153
156
  body: JSON.stringify({
154
157
  model: "qwq-32b-preview",
@@ -160,45 +163,75 @@ async function _e(t, n, s, l = "", r = {}) {
160
163
  },
161
164
  {
162
165
  role: "user",
163
- content: t
166
+ content: r
164
167
  }
165
168
  ]
166
169
  })
167
170
  });
168
- return fetch(u);
171
+ return fetch(i);
169
172
  }
170
- async function Ce(t, n, s, l = "", r = {}) {
171
- const e = se(l), o = new URL(`${e}/support/${s}/a`), u = {};
172
- Object.keys(u).forEach((y) => {
173
- o.searchParams.append(y, u[y]);
173
+ async function St(r, e, a, t = "", o = {}) {
174
+ const n = Je(t), s = new URL(`${n}/support/${a}/a`), i = {};
175
+ Object.keys(i).forEach((y) => {
176
+ s.searchParams.append(y, i[y]);
174
177
  });
175
- const d = new Request(o, {
178
+ const l = new Request(s, {
176
179
  method: "post",
177
180
  headers: {
178
181
  "Content-Type": "application/json",
179
- Authorization: `Bearer ${n}`
182
+ Authorization: `Bearer ${e}`
180
183
  },
181
184
  body: JSON.stringify({
182
- content: t
185
+ content: r
183
186
  })
184
187
  });
185
- return fetch(d);
188
+ return fetch(l);
186
189
  }
187
- const Te = (t) => {
188
- if (t.startsWith("data:")) {
189
- const n = t.substring(5).trim();
190
- if (n === "[DONE]")
190
+ const Ct = (r) => {
191
+ if (r.startsWith("data:")) {
192
+ const e = r.substring(5).trim();
193
+ if (e === "[DONE]")
191
194
  return {
192
195
  done: !0
193
196
  };
194
197
  try {
195
- return JSON.parse(n);
196
- } catch (s) {
197
- console.error("JSON parsing error:", s);
198
+ return JSON.parse(e);
199
+ } catch (a) {
200
+ console.error("JSON parsing error:", a);
198
201
  }
199
202
  }
200
203
  return null;
201
- }, G = [
204
+ }, _e = "<think>", ke = "</think>", Ue = (r, e) => {
205
+ const a = Math.max(0, r.length - (e.length - 1));
206
+ for (let t = a; t < r.length; t++)
207
+ if (e.startsWith(r.slice(t)))
208
+ return r.length - t;
209
+ return 0;
210
+ }, xt = (r) => {
211
+ let e = "", a = "", t = r || "", o = !1;
212
+ for (; t; ) {
213
+ const n = t.indexOf(_e), s = t.indexOf(ke);
214
+ if (n >= 0 && (s < 0 || n < s))
215
+ a += t.slice(0, n), t = t.slice(n + _e.length), o = !0;
216
+ else if (s >= 0 && (n < 0 || s < n))
217
+ e += t.slice(0, s), t = t.slice(s + ke.length), o = !1;
218
+ else if (o) {
219
+ const i = Ue(t, ke);
220
+ e += t.slice(0, t.length - i), t = "";
221
+ } else {
222
+ const i = Math.max(
223
+ Ue(t, _e),
224
+ Ue(t, ke)
225
+ );
226
+ a += t.slice(0, t.length - i), t = "";
227
+ }
228
+ }
229
+ return {
230
+ thinking: e.trim(),
231
+ content: a.trim(),
232
+ isThinkingStreaming: o
233
+ };
234
+ }, Oe = [
202
235
  {
203
236
  label: "模拟数据模型",
204
237
  modelName: "standard",
@@ -207,116 +240,120 @@ const Te = (t) => {
207
240
  {
208
241
  label: "Spark 星火大模型",
209
242
  modelName: "spark",
210
- api: xe
243
+ api: yt
211
244
  },
212
245
  {
213
246
  label: "Ollama 3 大模型",
214
247
  modelName: "ollama3",
215
- api: we
248
+ api: vt
216
249
  },
217
250
  {
218
251
  label: "SiliconFlow 硅基流动大模型",
219
252
  modelName: "siliconflow",
220
- api: ke
253
+ api: wt
221
254
  },
222
255
  {
223
256
  label: "Kimi Moonshot 月之暗面大模型",
224
257
  modelName: "moonshot",
225
- api: Se
258
+ api: kt
226
259
  },
227
260
  {
228
261
  label: "通义千问大模型",
229
262
  modelName: "dashscope",
230
- api: _e
263
+ api: bt
231
264
  },
232
265
  {
233
266
  label: "数智建管大模型",
234
267
  modelName: "szjy",
235
- api: Ce
268
+ api: St
236
269
  },
237
270
  {
238
271
  label: "Dify (OpenAI 兼容)",
239
272
  modelName: "dify-openai",
240
- api: be
273
+ api: gt
241
274
  }
242
- ], ee = {
243
- standard(t, n) {
244
- let s = "";
245
- return t instanceof Uint8Array ? s = n.decode(t, {
275
+ ], Ve = {
276
+ standard(r, e) {
277
+ let a = "";
278
+ return r instanceof Uint8Array ? a = e.decode(r, {
246
279
  stream: !0
247
- }) : s = t, {
248
- content: s
280
+ }) : a = r, {
281
+ content: a
249
282
  };
250
283
  },
251
- spark(t) {
252
- const n = Te(t);
253
- return n.done ? {
254
- done: !0
255
- } : {
256
- content: n.choices[0].delta.content || ""
284
+ spark(r) {
285
+ const e = Ct(r);
286
+ if (e.done)
287
+ return {
288
+ done: !0
289
+ };
290
+ const a = e.choices[0].delta, t = a.reasoning_content || a.reasoning;
291
+ let o = a.content || "";
292
+ return t && (o = `<think>${t}</think>${o}`), {
293
+ content: o
257
294
  };
258
295
  },
259
- siliconflow(t) {
260
- return this.spark(t);
296
+ siliconflow(r) {
297
+ return this.spark(r);
261
298
  },
262
- moonshot(t) {
263
- return this.spark(t);
299
+ moonshot(r) {
300
+ return this.spark(r);
264
301
  },
265
- dashscope(t) {
266
- return this.spark(t);
302
+ dashscope(r) {
303
+ return this.spark(r);
267
304
  },
268
- szjy(t) {
269
- return this.spark(t);
305
+ szjy(r) {
306
+ return this.spark(r);
270
307
  },
271
- "dify-openai"(t) {
272
- return this.spark(t);
308
+ "dify-openai"(r) {
309
+ return this.spark(r);
273
310
  },
274
- ollama3(t) {
311
+ ollama3(r) {
275
312
  return {
276
- content: JSON.parse(t).message.content
313
+ content: JSON.parse(r).message.content
277
314
  };
278
315
  }
279
- }, te = (t, n, s) => {
280
- const l = t.split(s);
281
- return l.slice(0, -1).forEach((r) => {
282
- r.trim() !== "" && n.enqueue(r);
283
- }), l[l.length - 1];
284
- }, Re = (t) => {
285
- let n = "";
316
+ }, $e = (r, e, a) => {
317
+ const t = r.split(a);
318
+ return t.slice(0, -1).forEach((o) => {
319
+ o.trim() !== "" && e.enqueue(o);
320
+ }), t[t.length - 1];
321
+ }, Rt = (r) => {
322
+ let e = "";
286
323
  return new TransformStream({
287
- transform(s, l) {
288
- if (n += s, n.trim().startsWith("data:"))
289
- n = te(n, l, t);
324
+ transform(a, t) {
325
+ if (e += a, e.trim().startsWith("data:"))
326
+ e = $e(e, t, r);
290
327
  else
291
328
  try {
292
- JSON.parse(n), n = te(n, l, t);
329
+ JSON.parse(e), e = $e(e, t, r);
293
330
  } catch {
294
- l.enqueue(s), n = "";
331
+ t.enqueue(a), e = "";
295
332
  }
296
333
  },
297
- flush(s) {
298
- n.trim() !== "" && s.enqueue(n);
334
+ flush(a) {
335
+ e.trim() !== "" && a.enqueue(e);
299
336
  }
300
337
  });
301
338
  };
302
- async function Pe(t, n) {
303
- const s = t.api;
304
- return s ? new Promise((l) => {
305
- s(n.text, n.token, n.identifier, n.baseUrl, n.extraConfig).then((r) => {
306
- if (r.body) {
307
- const e = r.body.pipeThrough(new TextDecoderStream()).pipeThrough(Re(`
339
+ async function Tt(r, e) {
340
+ const a = r.api;
341
+ return a ? new Promise((t) => {
342
+ a(e.text, e.token, e.identifier, e.baseUrl, e.extraConfig).then((o) => {
343
+ if (o.body) {
344
+ const n = o.body.pipeThrough(new TextDecoderStream()).pipeThrough(Rt(`
308
345
  `)).getReader();
309
- console.log("reader from response:", e), l({
346
+ console.log("reader from response:", n), t({
310
347
  error: 0,
311
- reader: e
348
+ reader: n
312
349
  });
313
350
  } else
314
- l({
351
+ t({
315
352
  error: 1,
316
353
  reader: null
317
354
  });
318
- }).catch((r) => {
319
- l({
355
+ }).catch(() => {
356
+ t({
320
357
  error: 1,
321
358
  reader: null
322
359
  });
@@ -326,20 +363,30 @@ async function Pe(t, n) {
326
363
  reader: null
327
364
  };
328
365
  }
329
- let F = null;
330
- function Ne() {
331
- return F || (window.markdownit ? F = new window.markdownit({
366
+ let Z = null;
367
+ function At() {
368
+ return Z || (window.markdownit ? (Z = new window.markdownit({
332
369
  html: !0,
333
370
  linkify: !0,
334
371
  typographer: !0
335
- }) : console.log("markdownit is not loaded"), F);
372
+ }), Z.renderer.rules.fence = (r, e) => {
373
+ const a = r[e], t = (a.info || "").trim().split(/\s+/)[0];
374
+ let o = "";
375
+ if (t && window.hljs && window.hljs.getLanguage(t))
376
+ try {
377
+ o = window.hljs.highlight(a.content, { language: t }).value;
378
+ } catch {
379
+ o = "";
380
+ }
381
+ return o || (o = Z.utils.escapeHtml(a.content)), `<pre class="md-code-block"><code class="hljs${t ? " language-" + t : ""}">${o}</code></pre>`;
382
+ }) : console.log("markdownit is not loaded"), Z);
336
383
  }
337
- const le = (t, n) => {
338
- const s = t.__vccOpts || t;
339
- for (const [l, r] of n)
340
- s[l] = r;
341
- return s;
342
- }, Oe = ["src", "alt"], Le = {
384
+ const _t = (r, e) => {
385
+ const a = r.__vccOpts || r;
386
+ for (const [t, o] of e)
387
+ a[t] = o;
388
+ return a;
389
+ }, Ut = ["src", "alt"], Pt = {
343
390
  __name: "SvgIcon",
344
391
  props: {
345
392
  // 图标名称或完整URL
@@ -368,48 +415,48 @@ const le = (t, n) => {
368
415
  default: "/icons/"
369
416
  }
370
417
  },
371
- setup(t) {
372
- const n = t, s = q(() => {
373
- if (n.name.startsWith("http://") || n.name.startsWith("https://") || n.name.startsWith("/"))
374
- return n.name;
375
- const e = n.name.endsWith(".svg") ? n.name : `${n.name}.svg`;
376
- return `${n.basePath}${e}`;
377
- }), l = q(() => {
378
- const e = typeof n.size == "number" ? `${n.size}px` : n.size;
418
+ setup(r) {
419
+ const e = r, a = O(() => {
420
+ if (e.name.startsWith("http://") || e.name.startsWith("https://") || e.name.startsWith("/"))
421
+ return e.name;
422
+ const n = e.name.endsWith(".svg") ? e.name : `${e.name}.svg`;
423
+ return `${e.basePath}${n}`;
424
+ }), t = O(() => {
425
+ const n = typeof e.size == "number" ? `${e.size}px` : e.size;
379
426
  return {
380
- width: e,
381
- height: e,
427
+ width: n,
428
+ height: n,
382
429
  display: "inline-flex",
383
430
  justifyContent: "center",
384
431
  alignItems: "center"
385
432
  };
386
- }), r = q(() => {
387
- const e = {
433
+ }), o = O(() => {
434
+ const n = {
388
435
  width: "100%",
389
436
  height: "100%"
390
437
  };
391
- return n.color && (e.filter = `drop-shadow(0 0 0 ${n.color})`), e;
438
+ return e.color && (n.filter = `drop-shadow(0 0 0 ${e.color})`), n;
392
439
  });
393
- return (e, o) => (P(), L("div", {
440
+ return (n, s) => (w(), C("div", {
394
441
  class: "svg-icon-wrapper",
395
- style: K(l.value)
442
+ style: ue(t.value)
396
443
  }, [
397
- x("img", {
398
- src: s.value,
399
- alt: t.name,
400
- class: W(["svg-icon", t.className]),
401
- style: K(r.value)
402
- }, null, 14, Oe)
444
+ u("img", {
445
+ src: a.value,
446
+ alt: r.name,
447
+ class: ne(["svg-icon", r.className]),
448
+ style: ue(o.value)
449
+ }, null, 14, Ut)
403
450
  ], 4));
404
451
  }
405
- }, V = /* @__PURE__ */ le(Le, [["__scopeId", "data-v-490b11c1"]]), je = async (t) => {
452
+ }, be = /* @__PURE__ */ _t(Pt, [["__scopeId", "data-v-490b11c1"]]), It = async (r) => {
406
453
  if (navigator.clipboard && navigator.permissions)
407
- await navigator.clipboard.writeText(t);
454
+ await navigator.clipboard.writeText(r);
408
455
  else {
409
- const n = document.createElement("textArea");
410
- n.value = t, n.style.width = 0, n.style.position = "fixed", n.style.left = "-999px", n.style.top = "10px", n.setAttribute("readonly", "readonly"), document.body.appendChild(n), n.select(), document.execCommand("copy"), document.body.removeChild(n);
456
+ const e = document.createElement("textArea");
457
+ e.value = r, e.style.width = 0, e.style.position = "fixed", e.style.left = "-999px", e.style.top = "10px", e.setAttribute("readonly", "readonly"), document.body.appendChild(e), e.select(), document.execCommand("copy"), document.body.removeChild(e);
411
458
  }
412
- }, ze = ["innerHTML"], Ue = {
459
+ }, Lt = { class: "thinking-title" }, Et = { class: "thinking-toggle-hint" }, Mt = ["innerHTML"], Ft = ["innerHTML"], Nt = 10, Ot = {
413
460
  __name: "Previewer",
414
461
  props: {
415
462
  reader: null,
@@ -426,145 +473,677 @@ const le = (t, n) => {
426
473
  "completed",
427
474
  "updating"
428
475
  ],
429
- setup(t, { expose: n, emit: s }) {
430
- const { appContext: l } = re(), { $message: r } = l.config.globalProperties, e = t, o = C(e.displayText || ""), u = C(""), d = C(!0), y = C(!1), _ = C(!!e.displayText), U = s, N = C(null);
431
- let T = null;
432
- const A = q(() => F ? F.render(o.value) : o.value), I = () => {
433
- e.reader && e.reader.cancel(), y.value = !0, c.value = !1, p(), _.value = !0, U("completed", o.value), d.value = !1, T && (cancelAnimationFrame(T), T = null);
434
- }, j = q(() => `${A.value}`), m = C(!1), f = () => {
435
- m.value = !0;
436
- }, p = () => {
437
- m.value = !1;
438
- }, c = C(!1), i = async () => {
439
- if (!e.reader) return;
440
- const b = new TextDecoder("utf-8");
441
- for (d.value = !0; !y.value; )
476
+ setup(r, { expose: e, emit: a }) {
477
+ const { appContext: t } = je(), { $message: o } = t.config.globalProperties, n = r, s = x(n.displayText || ""), i = x(!0), l = x(!1), y = x(!!n.displayText), R = a, F = x(null);
478
+ let _ = null;
479
+ const S = O(() => xt(s.value)), W = O(() => S.value.thinking.length > 0), T = x(n.displayText ? S.value.content.length : 0), N = O(() => S.value.isThinkingStreaming && !y.value), v = x(!1), p = () => {
480
+ v.value = !v.value;
481
+ };
482
+ let m = null, d = null;
483
+ const c = x(0);
484
+ Fe(() => S.value.thinking, ($) => {
485
+ !$ || c.value > 0 || (d === null && (d = m ?? Date.now()), S.value.content && k());
486
+ });
487
+ const k = () => {
488
+ if (c.value > 0 || !W.value) return;
489
+ const $ = d ?? m;
490
+ $ && (c.value = Math.max(1, Math.round((Date.now() - $) / 1e3)));
491
+ }, b = O(() => N.value ? "正在思考..." : c.value > 0 ? `已深度思考(用时 ${c.value} 秒)` : "思考过程"), L = O(() => W.value ? Z ? Z.render(S.value.thinking) : S.value.thinking : ""), A = O(() => S.value.content.slice(0, T.value)), I = O(() => Z ? Z.render(A.value) : A.value), g = () => {
492
+ n.reader && n.reader.cancel(), l.value = !0, H.value = !1, G(), y.value = !0, k(), R("completed", s.value), i.value = !1, _ && (cancelAnimationFrame(_), _ = null);
493
+ }, V = O(() => `${I.value}`), K = x(!1), X = () => {
494
+ K.value = !0;
495
+ }, G = () => {
496
+ K.value = !1;
497
+ }, H = x(!1), oe = async () => {
498
+ if (!n.reader) return;
499
+ const $ = new TextDecoder("utf-8");
500
+ for (i.value = !0; !l.value; )
442
501
  try {
443
- if (!e.reader) {
444
- c.value = !0;
502
+ if (!n.reader) {
503
+ H.value = !0;
445
504
  break;
446
505
  }
447
- const { value: a, done: g } = await e.reader.read();
448
- if (!e.reader) {
449
- c.value = !0;
506
+ const { value: z, done: E } = await n.reader.read();
507
+ if (!n.reader) {
508
+ H.value = !0;
450
509
  break;
451
510
  }
452
- if (g) {
453
- c.value = !0;
511
+ if (E) {
512
+ H.value = !0;
454
513
  break;
455
514
  }
456
- const S = ee[e.model];
457
- if (!S)
515
+ const Q = Ve[n.model];
516
+ if (!Q)
458
517
  break;
459
- const O = S.call(ee, a, b);
460
- if (O.done) {
461
- c.value = !0;
518
+ const re = Q.call(Ve, z, $);
519
+ if (re.done) {
520
+ H.value = !0;
462
521
  break;
463
522
  }
464
- u.value += O.content, T === null && k();
465
- } catch (a) {
466
- c.value = !0, console.log(3333, a), U("failed", a), I();
523
+ !m && re.content && (m = Date.now()), s.value += re.content, _ === null && de();
524
+ } catch (z) {
525
+ H.value = !0, console.log(3333, z), R("failed", z), g();
467
526
  break;
468
527
  } finally {
469
- p();
528
+ G();
470
529
  }
471
- }, h = async () => {
472
- e.scrollToBottomFn && e.scrollToBottomFn();
473
- }, v = (b = () => {
474
- }, a = () => {
530
+ }, se = async () => {
531
+ n.scrollToBottomFn && n.scrollToBottomFn();
532
+ }, ie = ($ = () => {
533
+ }, z = () => {
475
534
  }) => {
476
- if (u.value.length > 0) {
477
- const g = u.value.substring(0, 10);
478
- o.value += g, u.value = u.value.substring(10), b();
479
- } else
480
- a();
481
- }, k = () => {
482
- if (y.value && T) {
483
- cancelAnimationFrame(T), T = null, d.value = !1;
535
+ const E = S.value.content.length;
536
+ T.value > E && (T.value = E), T.value < E ? (T.value = Math.min(E, T.value + Nt), $()) : z();
537
+ }, de = () => {
538
+ if (l.value && _) {
539
+ cancelAnimationFrame(_), _ = null, i.value = !1;
484
540
  return;
485
541
  }
486
- c.value ? v(
542
+ H.value ? ie(
487
543
  () => {
488
- T = requestAnimationFrame(k), U("updating", null);
544
+ _ = requestAnimationFrame(de), R("updating", null);
489
545
  },
490
546
  () => {
491
- U("completed", o.value), d.value = !1, _.value = !0, ae(() => {
492
- if (c.value = !1, e.messagePostRender && N.value)
547
+ k(), R("completed", s.value), i.value = !1, y.value = !0, We(() => {
548
+ if (H.value = !1, n.messagePostRender && F.value)
493
549
  try {
494
- e.messagePostRender(N.value, o.value);
495
- } catch (b) {
496
- console.error("messagePostRender 执行失败:", b);
550
+ n.messagePostRender(F.value, S.value.content);
551
+ } catch ($) {
552
+ console.error("messagePostRender 执行失败:", $);
497
553
  }
498
- }), T = null;
554
+ }), _ = null;
499
555
  }
500
- ) : (v(), T = requestAnimationFrame(k)), h();
556
+ ) : (ie(), _ = requestAnimationFrame(de)), se();
501
557
  };
502
- ue(
503
- () => e.reader,
558
+ Fe(
559
+ () => n.reader,
504
560
  () => {
505
- e.reader && i();
561
+ n.reader && oe();
506
562
  },
507
563
  {
508
564
  immediate: !0,
509
565
  deep: !0
510
566
  }
511
- ), de(() => {
512
- I();
513
- }), n({
514
- abortReader: I,
515
- initializeStart: f,
516
- initializeEnd: p
517
- }), q(() => m.value ? !0 : (!e.reader || !d || o.value, !1));
518
- const w = async () => {
567
+ ), ct(() => {
568
+ g();
569
+ }), e({
570
+ abortReader: g,
571
+ initializeStart: X,
572
+ initializeEnd: G
573
+ }), O(() => K.value ? !0 : (!n.reader || !i || s.value, !1));
574
+ const we = async () => {
519
575
  try {
520
- const b = o.value;
521
- await je(b), r.success("复制成功");
522
- } catch (b) {
523
- console.error("复制失败:", b), r.error("复制失败");
576
+ const $ = S.value.content || s.value;
577
+ await It($), o.success("复制成功");
578
+ } catch ($) {
579
+ console.error("复制失败:", $), o.error("复制失败");
524
580
  }
525
581
  };
526
- return (b, a) => (P(), J(oe, { name: "fade" }, {
527
- default: M(() => [
528
- j.value ? (P(), L("div", {
582
+ return ($, z) => (w(), me(ge, { name: "fade" }, {
583
+ default: J(() => [
584
+ V.value || W.value ? (w(), C("div", {
529
585
  key: 0,
530
586
  ref_key: "refWrapperContent",
531
- ref: N,
587
+ ref: F,
532
588
  "text-16": "",
533
589
  class: "w-full h-full overflow-y-auto relative",
534
590
  "p-24px": ""
535
591
  }, [
536
- x("div", {
537
- class: "markdown-wrapper",
538
- innerHTML: j.value
539
- }, null, 8, ze),
540
- _.value ? (P(), L("div", {
592
+ W.value ? (w(), C("div", {
541
593
  key: 0,
594
+ class: ne(["ai-thinking-block", {
595
+ "is-expanded": v.value || N.value,
596
+ "is-streaming": N.value
597
+ }])
598
+ }, [
599
+ u("div", {
600
+ class: "thinking-header",
601
+ onClick: p
602
+ }, [
603
+ z[0] || (z[0] = u("svg", {
604
+ class: "thinking-arrow",
605
+ viewBox: "0 0 1024 1024",
606
+ width: "10",
607
+ height: "10"
608
+ }, [
609
+ u("path", {
610
+ d: "M704 512 320 256v512z",
611
+ fill: "currentColor"
612
+ })
613
+ ], -1)),
614
+ u("span", Lt, q(b.value), 1),
615
+ u("span", Et, q(v.value || N.value ? "收起" : "展开"), 1)
616
+ ]),
617
+ He(u("div", {
618
+ class: "thinking-body",
619
+ innerHTML: L.value
620
+ }, null, 8, Mt), [
621
+ [qe, v.value || N.value]
622
+ ])
623
+ ], 2)) : M("", !0),
624
+ u("div", {
625
+ class: "markdown-wrapper",
626
+ innerHTML: V.value
627
+ }, null, 8, Ft),
628
+ y.value ? (w(), C("div", {
629
+ key: 1,
542
630
  class: "ai-copy-btn-wrapper",
543
- onClick: w
631
+ onClick: we
544
632
  }, [
545
- E(V, {
633
+ j(be, {
546
634
  name: "/images/svg/copy.svg",
547
635
  color: "#666666"
548
636
  }),
549
- a[0] || (a[0] = x("span", { class: "copy-text" }, "复制", -1))
550
- ])) : B("", !0)
551
- ], 512)) : B("", !0)
637
+ z[1] || (z[1] = u("span", { class: "copy-text" }, "复制", -1))
638
+ ])) : M("", !0)
639
+ ], 512)) : M("", !0)
552
640
  ]),
553
641
  _: 1
554
642
  }));
555
643
  }
556
- }, Ie = { class: "panel-header" }, $e = { class: "header-actions" }, Ee = { class: "header-title" }, Ae = { class: "action-icons" }, qe = { class: "body-content" }, Me = {
644
+ };
645
+ class Vt {
646
+ constructor(e, a) {
647
+ U(this, "ratio");
648
+ U(this, "leftover", new Float32Array(0));
649
+ U(this, "fracOffset", 0);
650
+ this.ratio = e / a;
651
+ }
652
+ reset() {
653
+ this.leftover = new Float32Array(0), this.fracOffset = 0;
654
+ }
655
+ process(e) {
656
+ if (this.ratio === 1)
657
+ return new Float32Array(e);
658
+ const a = new Float32Array(this.leftover.length + e.length);
659
+ if (a.set(this.leftover), a.set(e, this.leftover.length), a.length < 2)
660
+ return this.leftover = a, new Float32Array(0);
661
+ const t = [];
662
+ let o = this.fracOffset;
663
+ for (; o < a.length - 1; ) {
664
+ const s = Math.floor(o), i = o - s, l = a[s], y = a[s + 1];
665
+ t.push(l + i * (y - l)), o += this.ratio;
666
+ }
667
+ const n = Math.min(a.length, Math.floor(o));
668
+ return this.leftover = a.slice(n), this.fracOffset = o - n, Float32Array.from(t);
669
+ }
670
+ }
671
+ class $t {
672
+ constructor(e = {}) {
673
+ U(this, "targetSampleRate");
674
+ U(this, "audioContext", null);
675
+ U(this, "mediaStream", null);
676
+ U(this, "sourceNode", null);
677
+ U(this, "processorNode", null);
678
+ U(this, "muteGain", null);
679
+ U(this, "resampler", null);
680
+ U(this, "audioChunks", []);
681
+ U(this, "onVolumeChange");
682
+ U(this, "onAudioChunk");
683
+ U(this, "_isRecording", !1);
684
+ this.targetSampleRate = e.sampleRate || 16e3, this.onVolumeChange = e.onVolumeChange, this.onAudioChunk = e.onAudioChunk;
685
+ }
686
+ get isRecording() {
687
+ return this._isRecording;
688
+ }
689
+ /**
690
+ * 开始录音
691
+ */
692
+ async start() {
693
+ if (this._isRecording) return;
694
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia)
695
+ throw new Error("当前浏览器环境不支持获取麦克风音频,请使用现代浏览器并确保在 HTTPS/localhost 环境下运行。");
696
+ try {
697
+ this.mediaStream = await navigator.mediaDevices.getUserMedia({
698
+ audio: {
699
+ channelCount: { ideal: 1 },
700
+ sampleRate: { ideal: this.targetSampleRate },
701
+ echoCancellation: !0,
702
+ noiseSuppression: !0,
703
+ autoGainControl: !0
704
+ }
705
+ });
706
+ } catch (t) {
707
+ throw t.name === "NotAllowedError" || t.name === "PermissionDeniedError" ? new Error("麦克风权限被拒绝,请在浏览器地址栏允许麦克风访问权限。") : t.name === "NotFoundError" || t.name === "DevicesNotFoundError" ? new Error("未检测到可用的麦克风输入设备。") : new Error(`无法启动麦克风: ${t.message || t}`);
708
+ }
709
+ const e = window.AudioContext || window.webkitAudioContext;
710
+ try {
711
+ this.audioContext = new e({ sampleRate: this.targetSampleRate });
712
+ } catch {
713
+ this.audioContext = new e();
714
+ }
715
+ this.audioContext.state === "suspended" && await this.audioContext.resume(), this.audioChunks = [], this.resampler = this.audioContext.sampleRate === this.targetSampleRate ? null : new Vt(this.audioContext.sampleRate, this.targetSampleRate), this.sourceNode = this.audioContext.createMediaStreamSource(this.mediaStream);
716
+ const a = 4096;
717
+ this.processorNode = this.audioContext.createScriptProcessor(a, 1, 1), this.processorNode.onaudioprocess = (t) => {
718
+ var s;
719
+ if (!this._isRecording) return;
720
+ const o = new Float32Array(t.inputBuffer.getChannelData(0));
721
+ if (this.onVolumeChange) {
722
+ let i = 0;
723
+ for (let R = 0; R < o.length; R++)
724
+ i += o[R] * o[R];
725
+ const l = Math.sqrt(i / o.length), y = Math.min(100, Math.round(l * 100 * 5));
726
+ this.onVolumeChange(y);
727
+ }
728
+ const n = this.resampler ? this.resampler.process(o) : o;
729
+ n.length && (this.audioChunks.push(n), (s = this.onAudioChunk) == null || s.call(this, n));
730
+ }, 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;
731
+ }
732
+ /**
733
+ * 停止录音并返回完整的 16kHz Float32Array 音频数据
734
+ */
735
+ async stop() {
736
+ if (!this._isRecording)
737
+ return new Float32Array(0);
738
+ this._isRecording = !1, this.cleanup();
739
+ const e = this.audioChunks.reduce((o, n) => o + n.length, 0), a = new Float32Array(e);
740
+ let t = 0;
741
+ for (const o of this.audioChunks)
742
+ a.set(o, t), t += o.length;
743
+ return this.audioChunks = [], a;
744
+ }
745
+ /**
746
+ * 取消录音并丢弃采集的数据
747
+ */
748
+ cancel() {
749
+ this._isRecording = !1, this.audioChunks = [], this.cleanup();
750
+ }
751
+ cleanup() {
752
+ this.processorNode && (this.processorNode.disconnect(), this.processorNode.onaudioprocess = null, this.processorNode = null), this.muteGain && (this.muteGain.disconnect(), this.muteGain = null), this.sourceNode && (this.sourceNode.disconnect(), this.sourceNode = null), this.resampler = null, this.mediaStream && (this.mediaStream.getTracks().forEach((e) => e.stop()), this.mediaStream = null), this.audioContext && this.audioContext.state !== "closed" && (this.audioContext.close().catch(() => {
753
+ }), this.audioContext = null);
754
+ }
755
+ }
756
+ function Bt(r, e, a) {
757
+ if (e === a)
758
+ return new Float32Array(r);
759
+ const t = e / a, o = Math.round(r.length / t), n = new Float32Array(o);
760
+ for (let s = 0; s < o; s++) {
761
+ const i = s * t, l = Math.floor(i), y = i - l, R = r[l] ?? 0, F = r[l + 1] ?? R;
762
+ n[s] = R + y * (F - R);
763
+ }
764
+ return n;
765
+ }
766
+ async function zt(r, e = 16e3) {
767
+ const a = await r.arrayBuffer(), t = window.AudioContext || window.webkitAudioContext, o = new t();
768
+ try {
769
+ const n = await o.decodeAudioData(a);
770
+ let s;
771
+ if (n.numberOfChannels > 1) {
772
+ s = new Float32Array(n.length);
773
+ for (let i = 0; i < n.numberOfChannels; i++) {
774
+ const l = n.getChannelData(i);
775
+ for (let y = 0; y < n.length; y++)
776
+ s[y] += l[y] / n.numberOfChannels;
777
+ }
778
+ } else
779
+ s = n.getChannelData(0);
780
+ return Bt(s, n.sampleRate, e);
781
+ } finally {
782
+ o.state !== "closed" && await o.close().catch(() => {
783
+ });
784
+ }
785
+ }
786
+ function Be(r, e = 16e3) {
787
+ const a = new ArrayBuffer(44 + r.length * 2), t = new DataView(a), o = (s, i) => {
788
+ for (let l = 0; l < i.length; l++)
789
+ t.setUint8(s + l, i.charCodeAt(l));
790
+ };
791
+ o(0, "RIFF"), t.setUint32(4, 36 + r.length * 2, !0), o(8, "WAVE"), o(12, "fmt "), t.setUint32(16, 16, !0), t.setUint16(20, 1, !0), t.setUint16(22, 1, !0), t.setUint32(24, e, !0), t.setUint32(28, e * 2, !0), t.setUint16(32, 2, !0), t.setUint16(34, 16, !0), o(36, "data"), t.setUint32(40, r.length * 2, !0);
792
+ let n = 44;
793
+ for (let s = 0; s < r.length; s++, n += 2) {
794
+ const i = Math.max(-1, Math.min(1, r[s]));
795
+ t.setInt16(n, i < 0 ? i * 32768 : i * 32767, !0);
796
+ }
797
+ return new Blob([t], { type: "audio/wav" });
798
+ }
799
+ const Ke = 16e3, Dt = Math.round(Ke * 0.35), Qe = "/scripts/ai/whisper.worker.js";
800
+ function jt() {
801
+ return new Worker(Pe(Qe), { type: "module" });
802
+ }
803
+ function Pe(r) {
804
+ return /^https?:\/\//i.test(r) ? r : typeof location < "u" ? new URL(r, location.origin).href : r;
805
+ }
806
+ function ze(r) {
807
+ if (!r.ok) return !1;
808
+ const e = (r.headers.get("content-type") || "").toLowerCase();
809
+ return !(e.includes("text/html") || e.includes("application/xhtml+xml"));
810
+ }
811
+ async function Ht(r) {
812
+ try {
813
+ const e = await fetch(r, { method: "HEAD" });
814
+ if (ze(e)) return !0;
815
+ } catch {
816
+ }
817
+ try {
818
+ const e = await fetch(r, { headers: { Range: "bytes=0-64" } });
819
+ if (ze(e)) return !0;
820
+ } catch {
821
+ }
822
+ return !1;
823
+ }
824
+ async function qt(r) {
825
+ const e = [];
826
+ r && e.push(Pe(r)), e.push(Pe(Qe));
827
+ const a = [...new Set(e.filter(Boolean))];
828
+ for (const t of a)
829
+ if (await Ht(t))
830
+ return console.log("[VoiceInputManager] 使用语音 Worker:", t), t;
831
+ return console.warn(
832
+ "[VoiceInputManager] 未探测到可访问的 Worker 脚本,将回退到 Vite 打包注入地址。已尝试:",
833
+ a.join(" , ")
834
+ ), null;
835
+ }
836
+ class Wt {
837
+ constructor(e = {}) {
838
+ U(this, "recorder", null);
839
+ U(this, "worker", null);
840
+ U(this, "status", "idle");
841
+ U(this, "options");
842
+ U(this, "isReady", !1);
843
+ U(this, "initPromise", null);
844
+ U(this, "currentTaskId", 0);
845
+ U(this, "pcmParts", []);
846
+ U(this, "pcmLength", 0);
847
+ U(this, "streamChunkIndex", 0);
848
+ U(this, "committedText", "");
849
+ this.options = {
850
+ soundBaseUrl: "/sounds/",
851
+ remoteHost: "https://hf-mirror.com",
852
+ modelId: "onnx-community/whisper-base",
853
+ language: "chinese",
854
+ ...e
855
+ };
856
+ }
857
+ get currentStatus() {
858
+ return this.status;
859
+ }
860
+ get ready() {
861
+ return this.isReady;
862
+ }
863
+ /**
864
+ * 初始化语音引擎(延迟加载,仅在首次使用或调用时触发)
865
+ */
866
+ async init(e) {
867
+ if (!this.isReady)
868
+ return this.initPromise ? this.initPromise : (e && (this.options.soundBaseUrl = e), this.initPromise = new Promise((a, t) => {
869
+ this.setStatus("loading", "正在准备语音识别引擎..."), (async () => {
870
+ var n, s;
871
+ try {
872
+ const i = await qt(this.options.workerUrl);
873
+ this.worker = i ? new Worker(i, { type: "module" }) : jt(), this.worker.onmessage = (l) => {
874
+ this.handleWorkerMessage(l, a, t);
875
+ }, this.worker.onerror = (l) => {
876
+ var F, _;
877
+ const R = `语音后台线程异常: ${l.message || l.filename || i || "未知错误"}`;
878
+ this.initPromise = null, this.setStatus("error", R), (_ = (F = this.options).onError) == null || _.call(F, R), t(l);
879
+ }, this.worker.postMessage({
880
+ type: "INIT",
881
+ data: {
882
+ modelId: this.options.modelId,
883
+ soundBaseUrl: this.options.soundBaseUrl,
884
+ remoteHost: this.options.remoteHost
885
+ }
886
+ });
887
+ } catch (i) {
888
+ const l = `创建语音 Worker 失败: ${i.message || i}`;
889
+ this.initPromise = null, this.setStatus("error", l), (s = (n = this.options).onError) == null || s.call(n, l), t(i);
890
+ }
891
+ })();
892
+ }), this.initPromise);
893
+ }
894
+ /**
895
+ * 开始语音录入(只采集,点「完成」后再转写)
896
+ */
897
+ async startRecording() {
898
+ var e, a, t, o;
899
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
900
+ const n = window.isSecureContext ? "当前浏览器环境不支持获取麦克风音频,请使用现代浏览器。" : "当前页面不是安全上下文,浏览器禁止调用麦克风。请使用 https:// 或 http://localhost / http://127.0.0.1 访问(通过局域网 IP 的 http 地址无法录音)。";
901
+ throw this.setStatus("error", n), (a = (e = this.options).onError) == null || a.call(e, n), new Error(n);
902
+ }
903
+ this.isReady || await this.init(), this.recorder || (this.recorder = new $t({
904
+ onVolumeChange: (n) => {
905
+ var s, i;
906
+ (i = (s = this.options).onVolumeChange) == null || i.call(s, n);
907
+ },
908
+ onAudioChunk: (n) => {
909
+ this.appendPcm(n);
910
+ }
911
+ }));
912
+ try {
913
+ this.currentTaskId++, this.resetStreamState(), await this.recorder.start(), this.setStatus("recording", "正在录音...");
914
+ } catch (n) {
915
+ throw this.setStatus("error", n.message || "启动录音失败"), (o = (t = this.options).onError) == null || o.call(t, n.message || "启动录音失败"), n;
916
+ }
917
+ }
918
+ /**
919
+ * 停止录音并触发模型端侧推理
920
+ */
921
+ async stopAndTranscribe() {
922
+ var e, a, t, o;
923
+ if (!(!this.recorder || !this.recorder.isRecording))
924
+ try {
925
+ await this.recorder.stop();
926
+ const n = this.mergePcm();
927
+ if (n.length === 0) {
928
+ this.resetStreamState(), this.setStatus("idle");
929
+ return;
930
+ }
931
+ this.setStatus("transcribing", "正在识别语音...");
932
+ try {
933
+ const s = Be(n), i = URL.createObjectURL(s);
934
+ (a = (e = this.options).onAudioRecorded) == null || a.call(e, i, s);
935
+ } catch (s) {
936
+ console.warn("生成录音回放音频失败:", s);
937
+ }
938
+ await this.transcribeAudioData(n);
939
+ } catch (n) {
940
+ this.setStatus("error", n.message || "音频处理失败"), (o = (t = this.options).onError) == null || o.call(t, n.message || "音频处理失败");
941
+ }
942
+ }
943
+ /**
944
+ * 直接对外部传入的 16kHz Float32Array 音频进行端侧推理(例如文件上传)
945
+ */
946
+ async transcribeAudioData(e, a) {
947
+ var t, o, n, s;
948
+ this.isReady || await this.init(), this.setStatus("transcribing", "正在流式识别音频...");
949
+ try {
950
+ a && ((o = (t = this.options).onAudioRecorded) == null || o.call(t, a, Be(e))), this.currentTaskId++, this.resetStreamState(), this.appendPcm(e), this.dispatchFullAudio();
951
+ } catch (i) {
952
+ this.setStatus("error", i.message || "音频处理失败"), (s = (n = this.options).onError) == null || s.call(n, i.message || "音频处理失败");
953
+ }
954
+ }
955
+ /**
956
+ * 上传音频/视频文件(支持 mp4, wav, mp3, m4a 等)并在浏览器端解析识别
957
+ */
958
+ async transcribeFile(e) {
959
+ var a, t;
960
+ this.isReady || await this.init(), this.setStatus("loading", "正在解析音频文件...");
961
+ try {
962
+ const o = await zt(e);
963
+ if (o.length === 0)
964
+ throw new Error("未能从该文件中提取出有效音频");
965
+ const n = URL.createObjectURL(e);
966
+ await this.transcribeAudioData(o, n);
967
+ } catch (o) {
968
+ this.setStatus("error", o.message || "音频文件解析失败"), (t = (a = this.options).onError) == null || t.call(a, o.message || "音频文件解析失败");
969
+ }
970
+ }
971
+ /**
972
+ * 取消当前录音并丢弃
973
+ */
974
+ cancelRecording() {
975
+ var a;
976
+ const e = this.currentTaskId;
977
+ this.currentTaskId++, (a = this.worker) == null || a.postMessage({ type: "CANCEL", taskId: e }), this.resetStreamState(), this.recorder && this.recorder.cancel(), this.setStatus("idle");
978
+ }
979
+ /**
980
+ * 取消当前的语音识别推理任务
981
+ */
982
+ cancelTranscribe() {
983
+ var a;
984
+ const e = this.currentTaskId;
985
+ this.currentTaskId++, (a = this.worker) == null || a.postMessage({ type: "CANCEL", taskId: e }), this.resetStreamState(), (this.status === "transcribing" || this.status === "recording") && this.setStatus("idle");
986
+ }
987
+ /**
988
+ * 清除本地模型缓存
989
+ */
990
+ async clearCache() {
991
+ this.worker && (this.worker.postMessage({ type: "CLEAR_CACHE" }), this.isReady = !1, this.initPromise = null);
992
+ }
993
+ /**
994
+ * 销毁并释放所有资源
995
+ */
996
+ destroy() {
997
+ var a;
998
+ const e = this.currentTaskId;
999
+ this.currentTaskId++, (a = this.worker) == null || a.postMessage({ type: "CANCEL", taskId: e }), 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");
1000
+ }
1001
+ resetStreamState() {
1002
+ this.pcmParts = [], this.pcmLength = 0, this.streamChunkIndex = 0, this.committedText = "";
1003
+ }
1004
+ appendPcm(e) {
1005
+ !e || e.length === 0 || (this.pcmParts.push(new Float32Array(e)), this.pcmLength += e.length);
1006
+ }
1007
+ mergePcm() {
1008
+ const e = new Float32Array(this.pcmLength);
1009
+ let a = 0;
1010
+ for (const t of this.pcmParts)
1011
+ e.set(t, a), a += t.length;
1012
+ return e;
1013
+ }
1014
+ emitPartial(e) {
1015
+ var a, t;
1016
+ (t = (a = this.options).onPartial) == null || t.call(a, (e || "").trim());
1017
+ }
1018
+ finishStream(e) {
1019
+ var t, o;
1020
+ const a = (e ?? this.committedText).trim();
1021
+ this.setStatus("idle"), (o = (t = this.options).onResult) == null || o.call(t, a);
1022
+ }
1023
+ /**
1024
+ * 录音结束或上传:整段一次送入 Worker。超过 30s 由 Worker 按重叠窗口切分。
1025
+ */
1026
+ dispatchFullAudio() {
1027
+ if (!this.worker) {
1028
+ this.finishStream();
1029
+ return;
1030
+ }
1031
+ if (this.pcmLength < Dt) {
1032
+ this.finishStream();
1033
+ return;
1034
+ }
1035
+ const e = this.mergePcm(), a = e.length > Ke * 30;
1036
+ this.committedText = "", this.worker.postMessage(
1037
+ {
1038
+ type: "TRANSCRIBE",
1039
+ data: {
1040
+ taskId: this.currentTaskId,
1041
+ audio: e,
1042
+ language: this.options.language,
1043
+ stream: !0,
1044
+ chunkIndex: this.streamChunkIndex++,
1045
+ isFinal: !0,
1046
+ mode: "append",
1047
+ nativeChunking: a
1048
+ }
1049
+ },
1050
+ [e.buffer]
1051
+ );
1052
+ }
1053
+ handleWorkerMessage(e, a, t) {
1054
+ var y, R, F, _;
1055
+ const { type: o, data: n, taskId: s, text: i, error: l } = e.data;
1056
+ switch (o) {
1057
+ case "READY":
1058
+ this.isReady = !0, this.setStatus("ready", "语音引擎就绪"), a == null || a();
1059
+ break;
1060
+ case "PROGRESS":
1061
+ if (n) {
1062
+ const S = typeof n.progress == "number" ? Math.round(n.progress) : 0;
1063
+ this.setStatus("downloading", `正在下载语音模型... ${S}%`), (R = (y = this.options).onProgress) == null || R.call(y, {
1064
+ status: n.status || "progress",
1065
+ progress: S,
1066
+ file: n.file,
1067
+ loaded: n.loaded,
1068
+ total: n.total
1069
+ });
1070
+ }
1071
+ break;
1072
+ case "TRANSCRIBING":
1073
+ if (s && s !== this.currentTaskId) return;
1074
+ this.status !== "recording" && this.setStatus("transcribing", "正在流式转写文字...");
1075
+ break;
1076
+ case "PARTIAL":
1077
+ if (s && s !== this.currentTaskId) return;
1078
+ this.committedText = i || "", this.emitPartial(this.committedText);
1079
+ break;
1080
+ case "RESULT":
1081
+ if (s && s !== this.currentTaskId)
1082
+ return;
1083
+ this.committedText = (i || "").trim() || this.committedText, this.emitPartial(this.committedText), this.finishStream(this.committedText);
1084
+ break;
1085
+ case "CACHE_CLEARED":
1086
+ this.setStatus("idle", "语音模型缓存已清空");
1087
+ break;
1088
+ case "ERROR":
1089
+ if (s && s !== this.currentTaskId) return;
1090
+ this.setStatus("error", l || "语音服务异常"), (_ = (F = this.options).onError) == null || _.call(F, l || "语音服务异常"), t == null || t(new Error(l));
1091
+ break;
1092
+ }
1093
+ }
1094
+ setStatus(e, a) {
1095
+ var t, o;
1096
+ this.status = e, (o = (t = this.options).onStatusChange) == null || o.call(t, e, a);
1097
+ }
1098
+ }
1099
+ const Gt = { class: "panel-header" }, Jt = { class: "header-actions" }, Kt = { class: "header-title" }, Qt = { class: "action-icons" }, Zt = { class: "body-content" }, Yt = {
557
1100
  key: 0,
558
1101
  class: "welcome-content"
559
- }, Fe = { class: "subtitle" }, Be = { class: "highlight" }, De = { class: "quick-questions" }, Ve = ["onClick"], We = {
1102
+ }, Xt = { class: "subtitle" }, en = { class: "highlight" }, tn = { class: "quick-questions" }, nn = ["onClick"], rn = {
560
1103
  key: 1,
561
1104
  class: "message-content user-content"
562
- }, Je = { class: "panel-footer" }, He = {
1105
+ }, an = { class: "panel-footer" }, on = {
563
1106
  key: 0,
564
- src: ge,
1107
+ src: mt,
565
1108
  alt: "加载中",
566
1109
  class: "loading-icon"
567
- }, Qe = { class: "input-box" }, Ke = ["src"], Xe = {
1110
+ }, sn = {
1111
+ key: 0,
1112
+ class: "voice-progress-banner"
1113
+ }, ln = { class: "progress-info" }, cn = { class: "progress-text" }, un = {
1114
+ key: 0,
1115
+ class: "progress-percent"
1116
+ }, dn = {
1117
+ key: 0,
1118
+ class: "progress-track"
1119
+ }, hn = { class: "recording-main" }, fn = { class: "recording-status" }, pn = {
1120
+ key: 0,
1121
+ class: "recording-time"
1122
+ }, mn = { class: "recording-hint" }, gn = {
1123
+ key: 1,
1124
+ class: "volume-waves"
1125
+ }, vn = { class: "recording-actions" }, yn = ["title"], wn = {
1126
+ key: 0,
1127
+ class: "voice-playback-bar"
1128
+ }, kn = ["title"], bn = { class: "playback-play-icon" }, Sn = {
1129
+ key: 0,
1130
+ viewBox: "0 0 24 24",
1131
+ width: "14",
1132
+ height: "14",
1133
+ fill: "currentColor"
1134
+ }, Cn = {
1135
+ key: 1,
1136
+ viewBox: "0 0 24 24",
1137
+ width: "14",
1138
+ height: "14",
1139
+ fill: "currentColor"
1140
+ }, xn = { class: "playback-title" }, Rn = {
1141
+ key: 0,
1142
+ class: "playback-time"
1143
+ }, Tn = {
1144
+ key: 1,
1145
+ class: "playback-waves"
1146
+ }, An = { class: "input-box" }, _n = { class: "input-actions-box" }, Un = ["src"], Ze = {
568
1147
  __name: "ChatPanel",
569
1148
  props: {
570
1149
  modelValue: {
@@ -606,111 +1185,249 @@ const le = (t, n) => {
606
1185
  extraConfig: {
607
1186
  type: Object,
608
1187
  default: () => ({})
1188
+ },
1189
+ /**
1190
+ * 语音识别模型静态资源基础路径,默认为 '/sounds/'
1191
+ */
1192
+ soundBaseUrl: {
1193
+ type: String,
1194
+ default: "/sounds/"
1195
+ },
1196
+ /**
1197
+ * Whisper Worker 脚本地址。不传则自动探测
1198
+ */
1199
+ workerUrl: {
1200
+ type: String,
1201
+ default: ""
1202
+ },
1203
+ /**
1204
+ * 是否显示麦克风语音输入入口,默认关闭
1205
+ */
1206
+ enableVoiceInput: {
1207
+ type: Boolean,
1208
+ default: !1
1209
+ },
1210
+ /**
1211
+ * 是否显示上传音频/视频识别入口,默认关闭
1212
+ */
1213
+ enableVoiceUpload: {
1214
+ type: Boolean,
1215
+ default: !1
1216
+ },
1217
+ /**
1218
+ * 嵌入式形态(sz-ai-chat-plain 使用):面板宽高 100% 撑满外层容器、
1219
+ * 隐藏抽屉模式按钮;关闭按钮退化为「清空会话回到欢迎页」。默认关闭(挂件行为不变)
1220
+ */
1221
+ embedded: {
1222
+ type: Boolean,
1223
+ default: !1
609
1224
  }
610
1225
  },
611
1226
  emits: ["update:modelValue", "submit"],
612
- setup(t, { emit: n }) {
613
- const { appContext: s } = re(), { $message: l } = s.config.globalProperties, r = t, e = q(() => G.find((a) => a.modelName === r.llmName) ?? G.find((a) => a.modelName === "szjy")), o = n, u = C(""), d = C(null), y = C(!1), _ = C([]), U = C([
1227
+ setup(r, { emit: e }) {
1228
+ const { appContext: a } = je(), { $message: t } = a.config.globalProperties, o = r;
1229
+ let n = null;
1230
+ const s = x("idle"), i = x(""), l = x(0), y = x(0), R = x(0);
1231
+ let F = null;
1232
+ const _ = x(""), S = x(!1), W = x(0);
1233
+ let T = null;
1234
+ const N = x(""), v = x(""), p = O(() => s.value === "downloading"), m = O(() => s.value === "loading"), d = O(() => s.value === "recording"), c = O(() => s.value === "transcribing"), k = O(() => d.value ? "正在录音,点击完成后开始识别" : N.value ? "正在流式转写..." : "正在识别语音中..."), b = O(() => o.enableVoiceInput ? "请输入您的问题或点击麦克风语音输入" : o.enableVoiceUpload ? "请输入您的问题或上传音频识别" : "请输入您的问题"), L = (f, h) => {
1235
+ const P = (f || "").trim(), B = (h || "").trim();
1236
+ return B ? P ? /[A-Za-z0-9]$/.test(P) && /[A-Za-z0-9]/.test(B.charAt(0)) ? `${P} ${B}` : `${P}${B}` : B : P;
1237
+ }, A = (f) => {
1238
+ const h = Math.floor(f / 60), P = f % 60;
1239
+ return `${h.toString().padStart(2, "0")}:${P.toString().padStart(2, "0")}`;
1240
+ }, I = () => (n || (n = new Wt({
1241
+ soundBaseUrl: o.soundBaseUrl || "/sounds/",
1242
+ workerUrl: o.workerUrl || void 0,
1243
+ onStatusChange: (f, h) => {
1244
+ s.value = f, h && (i.value = h);
1245
+ },
1246
+ onProgress: (f) => {
1247
+ typeof f.progress == "number" && (l.value = f.progress);
1248
+ },
1249
+ onVolumeChange: (f) => {
1250
+ y.value = f;
1251
+ },
1252
+ onAudioRecorded: (f) => {
1253
+ _.value && URL.revokeObjectURL(_.value), _.value = f, W.value = R.value;
1254
+ },
1255
+ onPartial: (f) => {
1256
+ N.value = f || "", E.value = L(v.value, f);
1257
+ },
1258
+ onResult: (f) => {
1259
+ N.value = f || "", E.value = L(v.value, f), f ? t.success("语音识别完成") : t.warning("未能识别出有效语音,请重试"), setTimeout(() => {
1260
+ N.value = "", Q.value && Q.value.focus();
1261
+ }, 100);
1262
+ },
1263
+ onError: (f) => {
1264
+ t.error(f || "语音输入服务出错"), V();
1265
+ }
1266
+ })), n), g = () => {
1267
+ V(), R.value = 0, F = setInterval(() => {
1268
+ R.value += 1;
1269
+ }, 1e3);
1270
+ }, V = () => {
1271
+ F && (clearInterval(F), F = null);
1272
+ }, K = async () => {
1273
+ if (!o.enableVoiceInput) return;
1274
+ if (d.value) {
1275
+ await X();
1276
+ return;
1277
+ }
1278
+ S.value && T && (T.pause(), S.value = !1);
1279
+ const f = I();
1280
+ try {
1281
+ v.value = E.value, N.value = "", g(), await f.startRecording();
1282
+ } catch (h) {
1283
+ V(), console.error("启动录音失败:", h);
1284
+ }
1285
+ }, X = async () => {
1286
+ V(), n && await n.stopAndTranscribe();
1287
+ }, G = x(null), H = () => {
1288
+ o.enableVoiceUpload && G.value && (G.value.value = "", G.value.click());
1289
+ }, oe = async (f) => {
1290
+ var Y;
1291
+ if (!o.enableVoiceUpload) return;
1292
+ const h = f.target, P = (Y = h == null ? void 0 : h.files) == null ? void 0 : Y[0];
1293
+ if (!P) return;
1294
+ S.value && T && (T.pause(), S.value = !1);
1295
+ const B = I();
1296
+ try {
1297
+ v.value = E.value, N.value = "", t.info(`正在流式识别文件: ${P.name}`), await B.transcribeFile(P);
1298
+ } catch (D) {
1299
+ t.error(`文件识别失败: ${D.message || D}`);
1300
+ }
1301
+ }, se = () => {
1302
+ V(), N.value = "", E.value = v.value, n && n.cancelRecording();
1303
+ }, ie = () => {
1304
+ N.value = "", E.value = v.value, n && n.cancelTranscribe(), t.info("已取消本次语音识别");
1305
+ }, de = () => {
1306
+ if (_.value) {
1307
+ if (S.value && T) {
1308
+ T.pause(), S.value = !1;
1309
+ return;
1310
+ }
1311
+ T && (T.pause(), T = null), T = new Audio(_.value), T.onloadedmetadata = () => {
1312
+ T && !isNaN(T.duration) && (W.value = Math.round(T.duration));
1313
+ }, T.onended = () => {
1314
+ S.value = !1;
1315
+ }, T.onerror = () => {
1316
+ S.value = !1, t.error("音频试听播放失败");
1317
+ }, T.play().then(() => {
1318
+ S.value = !0;
1319
+ }).catch((f) => {
1320
+ console.error("音频播放出错:", f), S.value = !1;
1321
+ });
1322
+ }
1323
+ }, we = () => {
1324
+ T && (T.pause(), T = null), S.value = !1, _.value && (URL.revokeObjectURL(_.value), _.value = "");
1325
+ };
1326
+ ut(() => {
1327
+ V(), we(), n && (n.destroy(), n = null);
1328
+ });
1329
+ const $ = O(() => Oe.find((f) => f.modelName === o.llmName) ?? Oe.find((f) => f.modelName === "szjy")), z = e, E = x(""), Q = x(null), re = x(!1), ee = x([]), et = x([
614
1330
  "什么是AI助理,能做什么?",
615
1331
  "当前项目的基本情况?",
616
1332
  "当前项目的进度情况?",
617
1333
  "当前项目的参建方有哪些?",
618
1334
  "数智建管平台有哪些功能?能做什么?"
619
- ]), N = C([]), T = C(!1), A = C(null), I = () => {
620
- ae(() => {
621
- if (A.value) {
622
- const a = A.value, g = a.scrollHeight, S = a.scrollTop, O = a.clientHeight;
623
- g - S - O < 100 ? a.scrollTop = g : a.scrollTo({
624
- top: g
1335
+ ]), le = x([]), he = x(!1), Ce = x(null), xe = () => {
1336
+ We(() => {
1337
+ if (Ce.value) {
1338
+ const f = Ce.value, h = f.scrollHeight, P = f.scrollTop, B = f.clientHeight;
1339
+ h - P - B < 100 ? f.scrollTop = h : f.scrollTo({
1340
+ top: h
625
1341
  });
626
1342
  }
627
1343
  });
628
- }, j = C(!1), m = q(() => j.value ? "/images/ai-stop.png" : "/images/ai-send.png"), f = (a, g) => {
629
- console.log("onFailedReader", a, g), T.value = !1;
630
- const S = w();
631
- S && S.initializeEnd(), l.error("转换失败,请重试"), j.value = !1, setTimeout(() => {
632
- d.value && d.value.focus();
1344
+ }, ae = x(!1), tt = O(() => ae.value ? "/images/ai-stop.png" : "/images/ai-send.png"), Ee = (f, h) => {
1345
+ console.log("onFailedReader", f, h), he.value = !1;
1346
+ const P = Me();
1347
+ P && P.initializeEnd(), t.error("转换失败,请重试"), ae.value = !1, setTimeout(() => {
1348
+ Q.value && Q.value.focus();
633
1349
  });
634
- }, p = (a, g) => {
635
- T.value = !1, j.value = !1, I(), g && _.value[a] && (_.value[a].displayText = g), setTimeout(() => {
636
- d.value && d.value.focus();
1350
+ }, nt = (f, h) => {
1351
+ he.value = !1, ae.value = !1, xe(), h && ee.value[f] && (ee.value[f].displayText = h), setTimeout(() => {
1352
+ Q.value && Q.value.focus();
637
1353
  });
638
- }, c = (a) => {
639
- j.value = !0;
640
- }, i = () => {
641
- j.value = !1, o("update:modelValue", !1), y.value = !1, _.value = [];
642
- }, h = C(!1), v = () => {
643
- h.value = !h.value;
644
- }, k = (a) => {
645
- u.value = a, b();
646
- }, w = () => {
647
- for (let a = N.value.length - 1; a >= 0; a--)
648
- if (N.value[a])
649
- return N.value[a];
1354
+ }, rt = (f) => {
1355
+ ae.value = !0;
1356
+ }, at = () => {
1357
+ ae.value = !1, z("update:modelValue", !1), re.value = !1, ee.value = [];
1358
+ }, Re = x(!1), ot = () => {
1359
+ Re.value = !Re.value;
1360
+ }, st = (f) => {
1361
+ E.value = f, Te();
1362
+ }, Me = () => {
1363
+ for (let f = le.value.length - 1; f >= 0; f--)
1364
+ if (le.value[f])
1365
+ return le.value[f];
650
1366
  return null;
651
- }, b = async () => {
652
- if (console.log("stylizingLoading:", T.value), T.value) {
653
- const R = w();
654
- console.log("lastPreviewer:", R), R && (console.log("abortReader"), R.abortReader());
1367
+ }, Te = async () => {
1368
+ if (console.log("stylizingLoading:", he.value), he.value) {
1369
+ const Y = Me();
1370
+ console.log("lastPreviewer:", Y), Y && (console.log("abortReader"), Y.abortReader());
655
1371
  return;
656
1372
  }
657
- if (!u.value.trim()) {
658
- console.log("no input, return"), d.value.focus();
1373
+ if (!E.value.trim()) {
1374
+ console.log("no input, return"), Q.value.focus();
659
1375
  return;
660
1376
  }
661
- _.value.push({
1377
+ ee.value.push({
662
1378
  type: "user",
663
- content: u.value
664
- }), j.value = !0, y.value = !0, o("submit", u.value), I();
665
- const a = u.value;
666
- u.value = "";
667
- const g = _.value.length;
668
- N.value[g] && N.value[g].initializeStart(), T.value = !0, _.value.push({
1379
+ content: E.value
1380
+ }), ae.value = !0, re.value = !0, z("submit", E.value), xe();
1381
+ const f = E.value;
1382
+ E.value = "";
1383
+ const h = ee.value.length;
1384
+ le.value[h] && le.value[h].initializeStart(), he.value = !0, ee.value.push({
669
1385
  type: "ai"
670
1386
  });
671
- const { error: S, reader: O } = await Pe(e.value, {
672
- text: a,
673
- token: r.token,
674
- identifier: r.identifier,
675
- baseUrl: r.baseUrl,
676
- extraConfig: r.extraConfig
1387
+ const { error: P, reader: B } = await Tt($.value, {
1388
+ text: f,
1389
+ token: o.token,
1390
+ identifier: o.identifier,
1391
+ baseUrl: o.baseUrl,
1392
+ extraConfig: o.extraConfig
677
1393
  });
678
- if (S) {
679
- console.log(45455, S), f(g, S);
1394
+ if (P) {
1395
+ console.log(45455, P), Ee(h, P);
680
1396
  return;
681
1397
  }
682
- O && (_.value[g].reader = O);
1398
+ B && (ee.value[h].reader = B);
683
1399
  };
684
- return (a, g) => {
685
- const S = X("el-icon"), O = X("el-input");
686
- return P(), J(oe, { name: "slide" }, {
687
- default: M(() => [
688
- t.modelValue ? (P(), L("div", {
1400
+ return (f, h) => {
1401
+ const P = Ae("el-icon"), B = Ae("el-button"), Y = Ae("el-input");
1402
+ return w(), me(ge, { name: "slide" }, {
1403
+ default: J(() => [
1404
+ r.modelValue ? (w(), C("div", {
689
1405
  key: 0,
690
- class: W(["ai-panel", { "drawer-mode": h.value }])
1406
+ class: ne(["ai-panel", { "drawer-mode": Re.value, "embedded-mode": r.embedded }])
691
1407
  }, [
692
- x("div", Ie, [
693
- x("div", $e, [
694
- x("div", Ee, D(t.title), 1),
695
- x("div", Ae, [
696
- E(S, {
1408
+ u("div", Gt, [
1409
+ u("div", Jt, [
1410
+ u("div", Kt, q(r.title), 1),
1411
+ u("div", Qt, [
1412
+ r.embedded ? M("", !0) : (w(), me(P, {
1413
+ key: 0,
697
1414
  class: "action-icon",
698
- onClick: v
1415
+ onClick: ot
699
1416
  }, {
700
- default: M(() => [
701
- E(V, {
1417
+ default: J(() => [
1418
+ j(be, {
702
1419
  name: "/images/svg/drawer-layout.svg",
703
1420
  color: "#999999"
704
1421
  })
705
1422
  ]),
706
1423
  _: 1
707
- }),
708
- E(S, {
1424
+ })),
1425
+ j(P, {
709
1426
  class: "action-icon",
710
- onClick: i
1427
+ onClick: at
711
1428
  }, {
712
- default: M(() => [
713
- E(V, {
1429
+ default: J(() => [
1430
+ j(be, {
714
1431
  name: "/images/svg/close.svg",
715
1432
  color: "#999999"
716
1433
  })
@@ -720,389 +1437,637 @@ const le = (t, n) => {
720
1437
  ])
721
1438
  ])
722
1439
  ]),
723
- x("div", qe, [
724
- y.value ? (P(), L("div", {
1440
+ u("div", Zt, [
1441
+ re.value ? (w(), C("div", {
725
1442
  key: 1,
726
1443
  class: "chat-messages",
727
1444
  ref_key: "messageContainerRef",
728
- ref: A
1445
+ ref: Ce
729
1446
  }, [
730
- (P(!0), L(Y, null, Z(_.value, (R, $) => (P(), L("div", {
731
- key: $,
732
- class: W(["message-item", R.type === "user" ? "user-message" : "ai-message"])
1447
+ (w(!0), C(pe, null, Ne(ee.value, (D, ce) => (w(), C("div", {
1448
+ key: ce,
1449
+ class: ne(["message-item", D.type === "user" ? "user-message" : "ai-message"])
733
1450
  }, [
734
- R.type === "ai" ? (P(), J(Ue, {
1451
+ D.type === "ai" ? (w(), me(Ot, {
735
1452
  key: 0,
736
1453
  ref_for: !0,
737
- ref: (z) => N.value[$] = z,
738
- reader: R.reader,
739
- "onUpdate:reader": (z) => R.reader = z,
740
- model: r.llmName,
741
- displayText: R.displayText,
742
- scrollToBottomFn: I,
743
- messagePostRender: t.messagePostRender,
744
- onFailed: (z) => f($, z),
745
- onCompleted: (z) => p($, z),
746
- onUpdating: () => c()
747
- }, null, 8, ["reader", "onUpdate:reader", "model", "displayText", "messagePostRender", "onFailed", "onCompleted", "onUpdating"])) : (P(), L("div", We, D(R.content), 1))
1454
+ ref: (te) => le.value[ce] = te,
1455
+ reader: D.reader,
1456
+ "onUpdate:reader": (te) => D.reader = te,
1457
+ model: o.llmName,
1458
+ displayText: D.displayText,
1459
+ scrollToBottomFn: xe,
1460
+ messagePostRender: r.messagePostRender,
1461
+ onFailed: (te) => Ee(ce, te),
1462
+ onCompleted: (te) => nt(ce, te),
1463
+ onUpdating: () => rt()
1464
+ }, null, 8, ["reader", "onUpdate:reader", "model", "displayText", "messagePostRender", "onFailed", "onCompleted", "onUpdating"])) : (w(), C("div", rn, q(D.content), 1))
748
1465
  ], 2))), 128))
749
- ], 512)) : (P(), L("div", Me, [
750
- g[2] || (g[2] = x("div", { class: "title" }, [
751
- x("img", {
752
- src: ye,
1466
+ ], 512)) : (w(), C("div", Yt, [
1467
+ h[2] || (h[2] = u("div", { class: "title" }, [
1468
+ u("img", {
1469
+ src: pt,
753
1470
  alt: "AI助手",
754
1471
  class: "panel-icon"
755
1472
  }),
756
- x("h3", { class: "title-text" }, "Hi, 您好")
1473
+ u("h3", { class: "title-text" }, "Hi, 您好")
757
1474
  ], -1)),
758
- x("div", Fe, [
759
- g[1] || (g[1] = fe(" 我是", -1)),
760
- x("span", Be, D(t.title), 1)
1475
+ u("div", Xt, [
1476
+ h[1] || (h[1] = fe(" 我是", -1)),
1477
+ u("span", en, q(r.title), 1)
761
1478
  ]),
762
- x("div", De, [
763
- (P(!0), L(Y, null, Z(U.value, (R, $) => (P(), L("div", {
764
- key: $,
1479
+ u("div", tn, [
1480
+ (w(!0), C(pe, null, Ne(et.value, (D, ce) => (w(), C("div", {
1481
+ key: ce,
765
1482
  class: "question-item",
766
- onClick: (z) => k(R)
1483
+ onClick: (te) => st(D)
767
1484
  }, [
768
- x("span", null, D(R), 1),
769
- E(S, null, {
770
- default: M(() => [
771
- E(V, {
1485
+ u("span", null, q(D), 1),
1486
+ j(P, null, {
1487
+ default: J(() => [
1488
+ j(be, {
772
1489
  name: "/images/svg/arrow-right.svg",
773
1490
  color: "#999999"
774
1491
  })
775
1492
  ]),
776
1493
  _: 1
777
1494
  })
778
- ], 8, Ve))), 128))
1495
+ ], 8, nn))), 128))
779
1496
  ])
780
1497
  ]))
781
1498
  ]),
782
- x("div", Je, [
783
- j.value ? (P(), L("img", He)) : B("", !0),
784
- x("div", Qe, [
785
- E(O, {
786
- modelValue: u.value,
787
- "onUpdate:modelValue": g[0] || (g[0] = (R) => u.value = R),
1499
+ u("div", an, [
1500
+ ae.value ? (w(), C("img", on)) : M("", !0),
1501
+ j(ge, { name: "fade" }, {
1502
+ default: J(() => [
1503
+ p.value || m.value ? (w(), C("div", sn, [
1504
+ u("div", ln, [
1505
+ h[3] || (h[3] = u("span", { class: "progress-icon" }, "⏳", -1)),
1506
+ u("span", cn, q(i.value), 1),
1507
+ l.value > 0 ? (w(), C("span", un, q(l.value) + "%", 1)) : M("", !0)
1508
+ ]),
1509
+ l.value > 0 ? (w(), C("div", dn, [
1510
+ u("div", {
1511
+ class: "progress-bar",
1512
+ style: ue({ width: l.value + "%" })
1513
+ }, null, 4)
1514
+ ])) : M("", !0)
1515
+ ])) : M("", !0)
1516
+ ]),
1517
+ _: 1
1518
+ }),
1519
+ j(ge, { name: "fade" }, {
1520
+ default: J(() => [
1521
+ d.value || c.value ? (w(), C("div", {
1522
+ key: 0,
1523
+ class: ne(["voice-recording-panel", { "has-transcript": c.value }])
1524
+ }, [
1525
+ u("div", hn, [
1526
+ u("div", fn, [
1527
+ u("span", {
1528
+ class: ne(["recording-pulse", { transcribing: c.value }])
1529
+ }, null, 2),
1530
+ d.value ? (w(), C("span", pn, q(A(R.value)), 1)) : M("", !0),
1531
+ u("span", mn, q(k.value), 1),
1532
+ d.value ? (w(), C("div", gn, [
1533
+ u("span", {
1534
+ class: "wave",
1535
+ style: ue({ height: Math.max(4, Math.min(22, y.value * 0.3)) + "px" })
1536
+ }, null, 4),
1537
+ u("span", {
1538
+ class: "wave",
1539
+ style: ue({ height: Math.max(4, Math.min(30, y.value * 0.5)) + "px" })
1540
+ }, null, 4),
1541
+ u("span", {
1542
+ class: "wave",
1543
+ style: ue({ height: Math.max(4, Math.min(18, y.value * 0.25)) + "px" })
1544
+ }, null, 4)
1545
+ ])) : M("", !0)
1546
+ ]),
1547
+ u("div", vn, [
1548
+ d.value ? (w(), C(pe, { key: 0 }, [
1549
+ j(B, {
1550
+ size: "small",
1551
+ circle: "",
1552
+ onClick: se,
1553
+ title: "取消录音",
1554
+ class: "voice-cancel-btn"
1555
+ }, {
1556
+ default: J(() => [...h[4] || (h[4] = [
1557
+ u("svg", {
1558
+ viewBox: "0 0 1024 1024",
1559
+ width: "12",
1560
+ height: "12"
1561
+ }, [
1562
+ u("path", {
1563
+ 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",
1564
+ fill: "currentColor"
1565
+ })
1566
+ ], -1)
1567
+ ])]),
1568
+ _: 1
1569
+ }),
1570
+ j(B, {
1571
+ type: "primary",
1572
+ size: "small",
1573
+ round: "",
1574
+ onClick: X,
1575
+ class: "voice-finish-btn"
1576
+ }, {
1577
+ default: J(() => [...h[5] || (h[5] = [
1578
+ fe(" 完成 ", -1)
1579
+ ])]),
1580
+ _: 1
1581
+ })
1582
+ ], 64)) : c.value ? (w(), me(B, {
1583
+ key: 1,
1584
+ size: "small",
1585
+ round: "",
1586
+ onClick: ie,
1587
+ class: "voice-cancel-transcribe-btn"
1588
+ }, {
1589
+ default: J(() => [...h[6] || (h[6] = [
1590
+ fe(" 取消识别 ", -1)
1591
+ ])]),
1592
+ _: 1
1593
+ })) : M("", !0)
1594
+ ])
1595
+ ]),
1596
+ c.value ? (w(), C("div", {
1597
+ key: 0,
1598
+ class: ne(["live-transcript", { empty: !N.value }]),
1599
+ title: N.value
1600
+ }, [
1601
+ N.value ? (w(), C(pe, { key: 0 }, [
1602
+ fe(q(N.value), 1),
1603
+ h[7] || (h[7] = u("span", { class: "caret" }, "|", -1))
1604
+ ], 64)) : (w(), C(pe, { key: 1 }, [
1605
+ fe("正在识别,文字将实时显示...")
1606
+ ], 64))
1607
+ ], 10, yn)) : M("", !0)
1608
+ ], 2)) : M("", !0)
1609
+ ]),
1610
+ _: 1
1611
+ }),
1612
+ j(ge, { name: "fade" }, {
1613
+ default: J(() => [
1614
+ _.value && !d.value && !c.value ? (w(), C("div", wn, [
1615
+ u("div", {
1616
+ class: "playback-main",
1617
+ onClick: de,
1618
+ title: S.value ? "点击暂停" : "点击播放录音"
1619
+ }, [
1620
+ u("div", bn, [
1621
+ S.value ? (w(), C("svg", Cn, [...h[9] || (h[9] = [
1622
+ u("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }, null, -1)
1623
+ ])])) : (w(), C("svg", Sn, [...h[8] || (h[8] = [
1624
+ u("path", { d: "M8 5v14l11-7z" }, null, -1)
1625
+ ])]))
1626
+ ]),
1627
+ u("span", xn, q(S.value ? "正在播放录音..." : "点击试听本次录音"), 1),
1628
+ W.value > 0 ? (w(), C("span", Rn, q(A(W.value)), 1)) : M("", !0),
1629
+ S.value ? (w(), C("div", Tn, [...h[10] || (h[10] = [
1630
+ u("span", { class: "wave-bar" }, null, -1),
1631
+ u("span", { class: "wave-bar" }, null, -1),
1632
+ u("span", { class: "wave-bar" }, null, -1),
1633
+ u("span", { class: "wave-bar" }, null, -1)
1634
+ ])])) : M("", !0)
1635
+ ], 8, kn),
1636
+ u("div", {
1637
+ class: "playback-close",
1638
+ onClick: we,
1639
+ title: "清除试听"
1640
+ }, [...h[11] || (h[11] = [
1641
+ u("svg", {
1642
+ viewBox: "0 0 1024 1024",
1643
+ width: "12",
1644
+ height: "12"
1645
+ }, [
1646
+ u("path", {
1647
+ 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",
1648
+ fill: "currentColor"
1649
+ })
1650
+ ], -1)
1651
+ ])])
1652
+ ])) : M("", !0)
1653
+ ]),
1654
+ _: 1
1655
+ }),
1656
+ He(u("div", An, [
1657
+ j(Y, {
1658
+ modelValue: E.value,
1659
+ "onUpdate:modelValue": h[0] || (h[0] = (D) => E.value = D),
788
1660
  ref_key: "refInputTextString",
789
- ref: d,
790
- placeholder: "请输入您的问题",
1661
+ ref: Q,
1662
+ placeholder: b.value,
791
1663
  autofocus: "",
792
- onKeyup: pe(b, ["enter"])
1664
+ onKeyup: dt(Te, ["enter"])
793
1665
  }, {
794
- append: M(() => [
795
- x("div", {
796
- class: "send-icon-box",
797
- onClick: b
798
- }, [
799
- x("img", {
800
- src: m.value,
801
- alt: "发送",
802
- class: "send-icon"
803
- }, null, 8, Ke)
1666
+ append: J(() => [
1667
+ u("div", _n, [
1668
+ r.enableVoiceUpload ? (w(), C("div", {
1669
+ key: 0,
1670
+ class: "voice-upload-btn",
1671
+ onClick: H,
1672
+ title: "上传音频/视频文件识别 (支持 .wav, .mp4, .mp3, .m4a)"
1673
+ }, [...h[12] || (h[12] = [
1674
+ u("svg", {
1675
+ viewBox: "0 0 24 24",
1676
+ width: "17",
1677
+ height: "17",
1678
+ fill: "none",
1679
+ stroke: "currentColor",
1680
+ "stroke-width": "2",
1681
+ "stroke-linecap": "round",
1682
+ "stroke-linejoin": "round"
1683
+ }, [
1684
+ u("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
1685
+ u("polyline", { points: "17 8 12 3 7 8" }),
1686
+ u("line", {
1687
+ x1: "12",
1688
+ y1: "3",
1689
+ x2: "12",
1690
+ y2: "15"
1691
+ })
1692
+ ], -1)
1693
+ ])])) : M("", !0),
1694
+ r.enableVoiceUpload ? (w(), C("input", {
1695
+ key: 1,
1696
+ type: "file",
1697
+ ref_key: "refAudioFileInput",
1698
+ ref: G,
1699
+ accept: "audio/*,video/mp4,.wav,.mp4,.mp3,.m4a",
1700
+ style: { display: "none" },
1701
+ onChange: oe
1702
+ }, null, 544)) : M("", !0),
1703
+ r.enableVoiceInput ? (w(), C("div", {
1704
+ key: 2,
1705
+ class: ne(["voice-mic-btn", { "loading-anim": p.value || m.value }]),
1706
+ onClick: K,
1707
+ title: "语音输入"
1708
+ }, [...h[13] || (h[13] = [
1709
+ u("svg", {
1710
+ viewBox: "0 0 24 24",
1711
+ width: "18",
1712
+ height: "18",
1713
+ fill: "none",
1714
+ stroke: "currentColor",
1715
+ "stroke-width": "2",
1716
+ "stroke-linecap": "round",
1717
+ "stroke-linejoin": "round"
1718
+ }, [
1719
+ u("path", {
1720
+ d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z",
1721
+ fill: "currentColor",
1722
+ opacity: "0.2"
1723
+ }),
1724
+ u("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
1725
+ u("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
1726
+ u("line", {
1727
+ x1: "12",
1728
+ y1: "19",
1729
+ x2: "12",
1730
+ y2: "22"
1731
+ })
1732
+ ], -1)
1733
+ ])], 2)) : M("", !0),
1734
+ u("div", {
1735
+ class: "send-icon-box",
1736
+ onClick: Te
1737
+ }, [
1738
+ u("img", {
1739
+ src: tt.value,
1740
+ alt: "发送",
1741
+ class: "send-icon"
1742
+ }, null, 8, Un)
1743
+ ])
804
1744
  ])
805
1745
  ]),
806
1746
  _: 1
807
- }, 8, ["modelValue"])
1747
+ }, 8, ["modelValue", "placeholder"])
1748
+ ], 512), [
1749
+ [qe, !d.value && !c.value]
808
1750
  ])
809
1751
  ])
810
- ], 2)) : B("", !0)
1752
+ ], 2)) : M("", !0)
811
1753
  ]),
812
1754
  _: 1
813
1755
  });
814
1756
  };
815
1757
  }
816
1758
  };
817
- var ie = { exports: {} };
818
- (function(t, n) {
819
- (function(s, l) {
820
- t.exports = l();
1759
+ var Ye = { exports: {} };
1760
+ (function(r, e) {
1761
+ (function(a, t) {
1762
+ r.exports = t();
821
1763
  })(window, function() {
822
- return function(s) {
823
- var l = {};
824
- function r(e) {
825
- if (l[e]) return l[e].exports;
826
- var o = l[e] = { i: e, l: !1, exports: {} };
827
- return s[e].call(o.exports, o, o.exports, r), o.l = !0, o.exports;
1764
+ return function(a) {
1765
+ var t = {};
1766
+ function o(n) {
1767
+ if (t[n]) return t[n].exports;
1768
+ var s = t[n] = { i: n, l: !1, exports: {} };
1769
+ return a[n].call(s.exports, s, s.exports, o), s.l = !0, s.exports;
828
1770
  }
829
- return r.m = s, r.c = l, r.d = function(e, o, u) {
830
- r.o(e, o) || Object.defineProperty(e, o, { enumerable: !0, get: u });
831
- }, r.r = function(e) {
832
- typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 });
833
- }, r.t = function(e, o) {
834
- if (1 & o && (e = r(e)), 8 & o || 4 & o && typeof e == "object" && e && e.__esModule) return e;
835
- var u = /* @__PURE__ */ Object.create(null);
836
- if (r.r(u), Object.defineProperty(u, "default", { enumerable: !0, value: e }), 2 & o && typeof e != "string") for (var d in e) r.d(u, d, (function(y) {
837
- return e[y];
838
- }).bind(null, d));
839
- return u;
840
- }, r.n = function(e) {
841
- var o = e && e.__esModule ? function() {
842
- return e.default;
1771
+ return o.m = a, o.c = t, o.d = function(n, s, i) {
1772
+ o.o(n, s) || Object.defineProperty(n, s, { enumerable: !0, get: i });
1773
+ }, o.r = function(n) {
1774
+ typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(n, "__esModule", { value: !0 });
1775
+ }, o.t = function(n, s) {
1776
+ if (1 & s && (n = o(n)), 8 & s || 4 & s && typeof n == "object" && n && n.__esModule) return n;
1777
+ var i = /* @__PURE__ */ Object.create(null);
1778
+ if (o.r(i), Object.defineProperty(i, "default", { enumerable: !0, value: n }), 2 & s && typeof n != "string") for (var l in n) o.d(i, l, (function(y) {
1779
+ return n[y];
1780
+ }).bind(null, l));
1781
+ return i;
1782
+ }, o.n = function(n) {
1783
+ var s = n && n.__esModule ? function() {
1784
+ return n.default;
843
1785
  } : function() {
844
- return e;
1786
+ return n;
845
1787
  };
846
- return r.d(o, "a", o), o;
847
- }, r.o = function(e, o) {
848
- return Object.prototype.hasOwnProperty.call(e, o);
849
- }, r.p = "", r(r.s = 0);
850
- }([function(s, l, r) {
851
- function e(m, f, p, c) {
852
- p.push(m), c.push([].concat(f[m] || []));
1788
+ return o.d(s, "a", s), s;
1789
+ }, o.o = function(n, s) {
1790
+ return Object.prototype.hasOwnProperty.call(n, s);
1791
+ }, o.p = "", o(o.s = 0);
1792
+ }([function(a, t, o) {
1793
+ function n(v, p, m, d) {
1794
+ m.push(v), d.push([].concat(p[v] || []));
853
1795
  }
854
- function o(m, f) {
855
- if (!m) throw new Error("[getMaxDepsChain] dep 参数不能为空");
856
- var p = [], c = [], i = [];
857
- for (e(m, f, c, i); c.length; ) {
858
- var h = i.pop();
859
- if (h && h.length) {
860
- var v = h.shift();
861
- if (i.push(h), ~c.indexOf(v)) throw new Error("[getMaxDepsChain][loop] 存在循环依赖,请检查依赖关系; nextName: " + v + ", mainStack: " + c);
862
- e(v, f, c, i);
863
- } else p.push([].concat(c)), c.pop();
1796
+ function s(v, p) {
1797
+ if (!v) throw new Error("[getMaxDepsChain] dep 参数不能为空");
1798
+ var m = [], d = [], c = [];
1799
+ for (n(v, p, d, c); d.length; ) {
1800
+ var k = c.pop();
1801
+ if (k && k.length) {
1802
+ var b = k.shift();
1803
+ if (c.push(k), ~d.indexOf(b)) throw new Error("[getMaxDepsChain][loop] 存在循环依赖,请检查依赖关系; nextName: " + b + ", mainStack: " + d);
1804
+ n(b, p, d, c);
1805
+ } else m.push([].concat(d)), d.pop();
864
1806
  }
865
- return p.reduce(function(k, w) {
866
- return w.length > k.length ? w : k;
1807
+ return m.reduce(function(L, A) {
1808
+ return A.length > L.length ? A : L;
867
1809
  }, []);
868
1810
  }
869
- function u(m) {
870
- if (!m) throw new Error("[depsParser] 入参不能为空");
871
- var f = {};
872
- m.forEach(function(c) {
873
- f[c.name] = c.deps || [];
1811
+ function i(v) {
1812
+ if (!v) throw new Error("[depsParser] 入参不能为空");
1813
+ var p = {};
1814
+ v.forEach(function(d) {
1815
+ p[d.name] = d.deps || [];
874
1816
  });
875
- var p = [];
876
- return m.forEach(function(c) {
877
- var i = o(c.name, f).length - 1;
878
- c.priority = i, p[i] = (p[i] || []).concat(c);
879
- }), p;
1817
+ var m = [];
1818
+ return v.forEach(function(d) {
1819
+ var c = s(d.name, p).length - 1;
1820
+ d.priority = c, m[c] = (m[c] || []).concat(d);
1821
+ }), m;
880
1822
  }
881
- r.r(l), r.d(l, "loadScript", function() {
882
- return N;
883
- }), r.d(l, "loadScripts", function() {
1823
+ o.r(t), o.d(t, "loadScript", function() {
1824
+ return _;
1825
+ }), o.d(t, "loadScripts", function() {
1826
+ return S;
1827
+ }), o.d(t, "dynamicLoadScripts", function() {
1828
+ return W;
1829
+ }), o.d(t, "createScriptsLoadIterator", function() {
884
1830
  return T;
885
- }), r.d(l, "dynamicLoadScripts", function() {
886
- return A;
887
- }), r.d(l, "createScriptsLoadIterator", function() {
888
- return I;
889
- }), r.d(l, "loadScriptsQueue", function() {
890
- return j;
891
- }), r.d(l, "getMaxDepsChain", function() {
892
- return o;
893
- }), r.d(l, "depsParser", function() {
894
- return u;
1831
+ }), o.d(t, "loadScriptsQueue", function() {
1832
+ return N;
1833
+ }), o.d(t, "getMaxDepsChain", function() {
1834
+ return s;
1835
+ }), o.d(t, "depsParser", function() {
1836
+ return i;
895
1837
  });
896
- var d = function() {
897
- return (d = Object.assign || function(m) {
898
- for (var f, p = 1, c = arguments.length; p < c; p++) for (var i in f = arguments[p]) Object.prototype.hasOwnProperty.call(f, i) && (m[i] = f[i]);
899
- return m;
1838
+ var l = function() {
1839
+ return (l = Object.assign || function(v) {
1840
+ for (var p, m = 1, d = arguments.length; m < d; m++) for (var c in p = arguments[m]) Object.prototype.hasOwnProperty.call(p, c) && (v[c] = p[c]);
1841
+ return v;
900
1842
  }).apply(this, arguments);
901
- }, y = function(m, f, p, c) {
902
- return new (p || (p = Promise))(function(i, h) {
903
- function v(b) {
1843
+ }, y = function(v, p, m, d) {
1844
+ return new (m || (m = Promise))(function(c, k) {
1845
+ function b(I) {
904
1846
  try {
905
- w(c.next(b));
906
- } catch (a) {
907
- h(a);
1847
+ A(d.next(I));
1848
+ } catch (g) {
1849
+ k(g);
908
1850
  }
909
1851
  }
910
- function k(b) {
1852
+ function L(I) {
911
1853
  try {
912
- w(c.throw(b));
913
- } catch (a) {
914
- h(a);
1854
+ A(d.throw(I));
1855
+ } catch (g) {
1856
+ k(g);
915
1857
  }
916
1858
  }
917
- function w(b) {
918
- var a;
919
- b.done ? i(b.value) : (a = b.value, a instanceof p ? a : new p(function(g) {
920
- g(a);
921
- })).then(v, k);
1859
+ function A(I) {
1860
+ var g;
1861
+ I.done ? c(I.value) : (g = I.value, g instanceof m ? g : new m(function(V) {
1862
+ V(g);
1863
+ })).then(b, L);
922
1864
  }
923
- w((c = c.apply(m, [])).next());
1865
+ A((d = d.apply(v, [])).next());
924
1866
  });
925
- }, _ = function(m, f) {
926
- var p, c, i, h, v = { label: 0, sent: function() {
927
- if (1 & i[0]) throw i[1];
928
- return i[1];
1867
+ }, R = function(v, p) {
1868
+ var m, d, c, k, b = { label: 0, sent: function() {
1869
+ if (1 & c[0]) throw c[1];
1870
+ return c[1];
929
1871
  }, trys: [], ops: [] };
930
- return h = { next: k(0), throw: k(1), return: k(2) }, typeof Symbol == "function" && (h[Symbol.iterator] = function() {
1872
+ return k = { next: L(0), throw: L(1), return: L(2) }, typeof Symbol == "function" && (k[Symbol.iterator] = function() {
931
1873
  return this;
932
- }), h;
933
- function k(w) {
934
- return function(b) {
935
- return function(a) {
936
- if (p) throw new TypeError("Generator is already executing.");
937
- for (; v; ) try {
938
- if (p = 1, c && (i = 2 & a[0] ? c.return : a[0] ? c.throw || ((i = c.return) && i.call(c), 0) : c.next) && !(i = i.call(c, a[1])).done) return i;
939
- switch (c = 0, i && (a = [2 & a[0], i.value]), a[0]) {
1874
+ }), k;
1875
+ function L(A) {
1876
+ return function(I) {
1877
+ return function(g) {
1878
+ if (m) throw new TypeError("Generator is already executing.");
1879
+ for (; b; ) try {
1880
+ if (m = 1, d && (c = 2 & g[0] ? d.return : g[0] ? d.throw || ((c = d.return) && c.call(d), 0) : d.next) && !(c = c.call(d, g[1])).done) return c;
1881
+ switch (d = 0, c && (g = [2 & g[0], c.value]), g[0]) {
940
1882
  case 0:
941
1883
  case 1:
942
- i = a;
1884
+ c = g;
943
1885
  break;
944
1886
  case 4:
945
- return v.label++, { value: a[1], done: !1 };
1887
+ return b.label++, { value: g[1], done: !1 };
946
1888
  case 5:
947
- v.label++, c = a[1], a = [0];
1889
+ b.label++, d = g[1], g = [0];
948
1890
  continue;
949
1891
  case 7:
950
- a = v.ops.pop(), v.trys.pop();
1892
+ g = b.ops.pop(), b.trys.pop();
951
1893
  continue;
952
1894
  default:
953
- if (i = v.trys, !((i = i.length > 0 && i[i.length - 1]) || a[0] !== 6 && a[0] !== 2)) {
954
- v = 0;
1895
+ if (c = b.trys, !((c = c.length > 0 && c[c.length - 1]) || g[0] !== 6 && g[0] !== 2)) {
1896
+ b = 0;
955
1897
  continue;
956
1898
  }
957
- if (a[0] === 3 && (!i || a[1] > i[0] && a[1] < i[3])) {
958
- v.label = a[1];
1899
+ if (g[0] === 3 && (!c || g[1] > c[0] && g[1] < c[3])) {
1900
+ b.label = g[1];
959
1901
  break;
960
1902
  }
961
- if (a[0] === 6 && v.label < i[1]) {
962
- v.label = i[1], i = a;
1903
+ if (g[0] === 6 && b.label < c[1]) {
1904
+ b.label = c[1], c = g;
963
1905
  break;
964
1906
  }
965
- if (i && v.label < i[2]) {
966
- v.label = i[2], v.ops.push(a);
1907
+ if (c && b.label < c[2]) {
1908
+ b.label = c[2], b.ops.push(g);
967
1909
  break;
968
1910
  }
969
- i[2] && v.ops.pop(), v.trys.pop();
1911
+ c[2] && b.ops.pop(), b.trys.pop();
970
1912
  continue;
971
1913
  }
972
- a = f.call(m, v);
973
- } catch (g) {
974
- a = [6, g], c = 0;
1914
+ g = p.call(v, b);
1915
+ } catch (V) {
1916
+ g = [6, V], d = 0;
975
1917
  } finally {
976
- p = i = 0;
1918
+ m = c = 0;
977
1919
  }
978
- if (5 & a[0]) throw a[1];
979
- return { value: a[0] ? a[1] : void 0, done: !0 };
980
- }([w, b]);
1920
+ if (5 & g[0]) throw g[1];
1921
+ return { value: g[0] ? g[1] : void 0, done: !0 };
1922
+ }([A, I]);
981
1923
  };
982
1924
  }
983
- }, U = function(m) {
1925
+ }, F = function(v) {
984
1926
  if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
985
- var f, p = m[Symbol.asyncIterator];
986
- return p ? p.call(m) : (m = typeof __values == "function" ? __values(m) : m[Symbol.iterator](), f = {}, c("next"), c("throw"), c("return"), f[Symbol.asyncIterator] = function() {
1927
+ var p, m = v[Symbol.asyncIterator];
1928
+ return m ? m.call(v) : (v = typeof __values == "function" ? __values(v) : v[Symbol.iterator](), p = {}, d("next"), d("throw"), d("return"), p[Symbol.asyncIterator] = function() {
987
1929
  return this;
988
- }, f);
989
- function c(i) {
990
- f[i] = m[i] && function(h) {
991
- return new Promise(function(v, k) {
992
- (function(w, b, a, g) {
993
- Promise.resolve(g).then(function(S) {
994
- w({ value: S, done: a });
995
- }, b);
996
- })(v, k, (h = m[i](h)).done, h.value);
1930
+ }, p);
1931
+ function d(c) {
1932
+ p[c] = v[c] && function(k) {
1933
+ return new Promise(function(b, L) {
1934
+ (function(A, I, g, V) {
1935
+ Promise.resolve(V).then(function(K) {
1936
+ A({ value: K, done: g });
1937
+ }, I);
1938
+ })(b, L, (k = v[c](k)).done, k.value);
997
1939
  });
998
1940
  };
999
1941
  }
1000
1942
  };
1001
- function N(m, f) {
1002
- return f === void 0 && (f = !1), new Promise(function(p, c) {
1003
- var i = f ? document.head : document.body, h = document.createElement("script");
1004
- h.type = "text/javascript", h.src = m, h.crossOrigin = "anonymous", h.onreadystatechange = p, h.onload = p, h.onerror = c, i.appendChild(h);
1943
+ function _(v, p) {
1944
+ return p === void 0 && (p = !1), new Promise(function(m, d) {
1945
+ var c = p ? document.head : document.body, k = document.createElement("script");
1946
+ k.type = "text/javascript", k.src = v, k.crossOrigin = "anonymous", k.onreadystatechange = m, k.onload = m, k.onerror = d, c.appendChild(k);
1005
1947
  });
1006
1948
  }
1007
- var T = function(m, f) {
1008
- return f === void 0 && (f = {}), y(void 0, void 0, void 0, function() {
1009
- var p, c, i, h, v;
1010
- return _(this, function(k) {
1011
- switch (k.label) {
1949
+ var S = function(v, p) {
1950
+ return p === void 0 && (p = {}), y(void 0, void 0, void 0, function() {
1951
+ var m, d, c, k, b;
1952
+ return R(this, function(L) {
1953
+ switch (L.label) {
1012
1954
  case 0:
1013
- return p = f.baseUrl, c = p === void 0 ? "" : p, i = f.lastLoadResult, h = f.inHead, v = h !== void 0 && h, [4, Promise.all(m.map(function(w) {
1955
+ return m = p.baseUrl, d = m === void 0 ? "" : m, c = p.lastLoadResult, k = p.inHead, b = k !== void 0 && k, [4, Promise.all(v.map(function(A) {
1014
1956
  return y(void 0, void 0, void 0, function() {
1015
- var b, a, g, S, O, R, $, z;
1016
- return _(this, function(Q) {
1017
- switch (Q.label) {
1957
+ var I, g, V, K, X, G, H, oe;
1958
+ return R(this, function(se) {
1959
+ switch (se.label) {
1018
1960
  case 0:
1019
- return b = w.name, a = w.path, g = w.deps, ($ = {})[b] = !0, S = $, (z = {})[b] = !1, O = z, window[b] ? [2, S] : [3, 1];
1961
+ return I = A.name, g = A.path, V = A.deps, (H = {})[I] = !0, K = H, (oe = {})[I] = !1, X = oe, window[I] ? [2, K] : [3, 1];
1020
1962
  case 1:
1021
- return R = !0, g && i && [].concat(g).forEach(function(ce) {
1022
- i[ce] !== !1 && (R = !0);
1023
- }), R ? [4, N(a.indexOf("http") === 0 || a.indexOf("//:") === 0 ? a : c + a, v).then(function() {
1024
- return S;
1963
+ return G = !0, V && c && [].concat(V).forEach(function(ie) {
1964
+ c[ie] !== !1 && (G = !0);
1965
+ }), G ? [4, _(g.indexOf("http") === 0 || g.indexOf("//:") === 0 ? g : d + g, b).then(function() {
1966
+ return K;
1025
1967
  }).catch(function() {
1026
- return O;
1968
+ return X;
1027
1969
  })] : [3, 3];
1028
1970
  case 2:
1029
- return [2, Q.sent()];
1971
+ return [2, se.sent()];
1030
1972
  case 3:
1031
- return [2, O];
1973
+ return [2, X];
1032
1974
  }
1033
1975
  });
1034
1976
  });
1035
1977
  }))];
1036
1978
  case 1:
1037
- return [2, k.sent()];
1979
+ return [2, L.sent()];
1038
1980
  }
1039
1981
  });
1040
1982
  });
1041
- }, A = function(m, f) {
1042
- return f === void 0 && (f = {}), function() {
1043
- var p = [].concat(u(m));
1983
+ }, W = function(v, p) {
1984
+ return p === void 0 && (p = {}), function() {
1985
+ var m = [].concat(i(v));
1044
1986
  return { next: function() {
1045
- if (p.length) {
1046
- var c = p.shift();
1047
- return T(c, f).then(function(i) {
1048
- return { value: i, done: !1 };
1987
+ if (m.length) {
1988
+ var d = m.shift();
1989
+ return S(d, p).then(function(c) {
1990
+ return { value: c, done: !1 };
1049
1991
  });
1050
1992
  }
1051
1993
  return Promise.resolve({ done: !0 });
1052
1994
  } };
1053
1995
  };
1054
- }, I = function(m, f) {
1055
- var p;
1056
- return f === void 0 && (f = {}), (p = {})[Symbol.asyncIterator] = A(m, f), p;
1057
- }, j = function(m, f) {
1058
- return f === void 0 && (f = {}), y(void 0, void 0, void 0, function() {
1059
- var p, c, i, h, v, k;
1060
- return _(this, function(w) {
1061
- switch (w.label) {
1996
+ }, T = function(v, p) {
1997
+ var m;
1998
+ return p === void 0 && (p = {}), (m = {})[Symbol.asyncIterator] = W(v, p), m;
1999
+ }, N = function(v, p) {
2000
+ return p === void 0 && (p = {}), y(void 0, void 0, void 0, function() {
2001
+ var m, d, c, k, b, L;
2002
+ return R(this, function(A) {
2003
+ switch (A.label) {
1062
2004
  case 0:
1063
- w.trys.push([0, 5, 6, 11]), p = U(I(m, f)), w.label = 1;
2005
+ A.trys.push([0, 5, 6, 11]), m = F(T(v, p)), A.label = 1;
1064
2006
  case 1:
1065
- return [4, p.next()];
2007
+ return [4, m.next()];
1066
2008
  case 2:
1067
- if ((c = w.sent()).done) return [3, 4];
1068
- i = c.value, f.lastLoadResult = f.lastLoadResult || {}, console.log("current load: ", i), i.forEach(function(b) {
1069
- f.lastLoadResult = d(d({}, f.lastLoadResult), b);
1070
- }), w.label = 3;
2009
+ if ((d = A.sent()).done) return [3, 4];
2010
+ c = d.value, p.lastLoadResult = p.lastLoadResult || {}, console.log("current load: ", c), c.forEach(function(I) {
2011
+ p.lastLoadResult = l(l({}, p.lastLoadResult), I);
2012
+ }), A.label = 3;
1071
2013
  case 3:
1072
2014
  return [3, 1];
1073
2015
  case 4:
1074
2016
  return [3, 11];
1075
2017
  case 5:
1076
- return h = w.sent(), v = { error: h }, [3, 11];
2018
+ return k = A.sent(), b = { error: k }, [3, 11];
1077
2019
  case 6:
1078
- return w.trys.push([6, , 9, 10]), c && !c.done && (k = p.return) ? [4, k.call(p)] : [3, 8];
2020
+ return A.trys.push([6, , 9, 10]), d && !d.done && (L = m.return) ? [4, L.call(m)] : [3, 8];
1079
2021
  case 7:
1080
- w.sent(), w.label = 8;
2022
+ A.sent(), A.label = 8;
1081
2023
  case 8:
1082
2024
  return [3, 10];
1083
2025
  case 9:
1084
- if (v) throw v.error;
2026
+ if (b) throw b.error;
1085
2027
  return [7];
1086
2028
  case 10:
1087
2029
  return [7];
1088
2030
  case 11:
1089
- return [2, f.lastLoadResult];
2031
+ return [2, p.lastLoadResult];
1090
2032
  }
1091
2033
  });
1092
2034
  });
1093
2035
  };
1094
2036
  }]);
1095
2037
  });
1096
- })(ie);
1097
- var Ye = ie.exports;
1098
- const Ze = {
2038
+ })(Ye);
2039
+ var Pn = Ye.exports;
2040
+ function Xe() {
2041
+ const r = [
2042
+ {
2043
+ name: "markdownit",
2044
+ path: "markdown-it.min.js"
2045
+ },
2046
+ {
2047
+ name: "hljs",
2048
+ path: "highlight.11.11.1.min.js"
2049
+ }
2050
+ ];
2051
+ let e = {};
2052
+ Pn.loadScriptsQueue(r, {
2053
+ baseUrl: "/scripts/ai/",
2054
+ lastLoadResult: e,
2055
+ inHead: !1
2056
+ }).then((a) => {
2057
+ if (console.log("load ai deps: ", a), window.markdownit) {
2058
+ const t = window.markdownit();
2059
+ console.log("markdownit: ", t), At();
2060
+ }
2061
+ });
2062
+ }
2063
+ const In = {
1099
2064
  key: 0,
1100
2065
  class: "ai-assistant"
1101
- }, Ge = {
2066
+ }, Ln = {
1102
2067
  name: "AiChat"
1103
2068
  //这个⾮常重要,就是未来你放到其他项⽬中,组件标签的名字,⽐如:<sz-workflow></sz-workflow>
1104
- }, et = /* @__PURE__ */ me({
1105
- ...Ge,
2069
+ }, En = /* @__PURE__ */ Ge({
2070
+ ...Ln,
1106
2071
  props: {
1107
2072
  token: {
1108
2073
  type: String,
@@ -1146,190 +2111,402 @@ const Ze = {
1146
2111
  extraConfig: {
1147
2112
  type: Object,
1148
2113
  default: () => ({})
2114
+ },
2115
+ /**
2116
+ * 语音识别模型静态资源基础路径,默认为 '/sounds/'
2117
+ */
2118
+ soundBaseUrl: {
2119
+ type: String,
2120
+ default: "/sounds/"
2121
+ },
2122
+ /**
2123
+ * Whisper Worker 脚本地址。不传则自动探测库产物与 /scripts/ai/whisper.worker.js
2124
+ */
2125
+ workerUrl: {
2126
+ type: String,
2127
+ default: ""
2128
+ },
2129
+ /**
2130
+ * 是否显示麦克风语音输入入口,默认关闭
2131
+ */
2132
+ enableVoiceInput: {
2133
+ type: Boolean,
2134
+ default: !1
2135
+ },
2136
+ /**
2137
+ * 是否显示上传音频/视频识别入口,默认关闭
2138
+ */
2139
+ enableVoiceUpload: {
2140
+ type: Boolean,
2141
+ default: !1
1149
2142
  }
1150
2143
  },
1151
- setup(t) {
1152
- const n = C(!1), s = C(!1), l = () => {
1153
- n.value = !n.value;
1154
- }, r = () => {
1155
- s.value = !0, n.value = !1;
1156
- }, e = (d) => {
1157
- console.log("用户输入:", d);
1158
- }, o = [
1159
- {
1160
- name: "markdownit",
1161
- path: "markdown-it.min.js"
1162
- },
1163
- {
1164
- name: "hljs",
1165
- path: "highlight.11.11.1.min.js"
1166
- }
1167
- ];
1168
- let u = {};
1169
- return Ye.loadScriptsQueue(o, {
1170
- baseUrl: "/scripts/ai/",
1171
- lastLoadResult: u,
1172
- inHead: !1
1173
- }).then((d) => {
1174
- if (console.log("load ai deps: ", d), window.markdownit) {
1175
- const y = window.markdownit();
1176
- console.log("markdownit: ", y), Ne();
1177
- }
1178
- }), (d, y) => s.value ? B("", !0) : (P(), L("div", Ze, [
1179
- E(Xe, {
1180
- modelValue: n.value,
1181
- "onUpdate:modelValue": y[0] || (y[0] = (_) => n.value = _),
1182
- onSubmit: e,
1183
- token: t.token,
1184
- identifier: t.identifier,
1185
- baseUrl: t.baseUrl,
1186
- title: t.title,
1187
- llmName: t.llmName,
1188
- messagePostRender: t.messagePostRender,
1189
- extraConfig: t.extraConfig
1190
- }, null, 8, ["modelValue", "token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig"]),
1191
- x("div", {
2144
+ setup(r) {
2145
+ const e = x(!1), a = x(!1), t = () => {
2146
+ e.value = !e.value;
2147
+ }, o = () => {
2148
+ a.value = !0, e.value = !1;
2149
+ }, n = (s) => {
2150
+ console.log("用户输入:", s);
2151
+ };
2152
+ return Xe(), (s, i) => a.value ? M("", !0) : (w(), C("div", In, [
2153
+ j(Ze, {
2154
+ modelValue: e.value,
2155
+ "onUpdate:modelValue": i[0] || (i[0] = (l) => e.value = l),
2156
+ onSubmit: n,
2157
+ token: r.token,
2158
+ identifier: r.identifier,
2159
+ baseUrl: r.baseUrl,
2160
+ title: r.title,
2161
+ llmName: r.llmName,
2162
+ messagePostRender: r.messagePostRender,
2163
+ extraConfig: r.extraConfig,
2164
+ soundBaseUrl: r.soundBaseUrl,
2165
+ workerUrl: r.workerUrl,
2166
+ enableVoiceInput: r.enableVoiceInput,
2167
+ enableVoiceUpload: r.enableVoiceUpload
2168
+ }, null, 8, ["modelValue", "token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableVoiceUpload"]),
2169
+ u("div", {
1192
2170
  class: "ai-icon",
1193
- onClick: l
2171
+ onClick: t
1194
2172
  }, [
1195
- x("div", {
2173
+ u("div", {
1196
2174
  class: "close-icon",
1197
- onClick: he(r, ["stop"])
1198
- }, [...y[1] || (y[1] = [
1199
- x("svg", {
2175
+ onClick: ht(o, ["stop"])
2176
+ }, [...i[1] || (i[1] = [
2177
+ u("svg", {
1200
2178
  viewBox: "0 0 1024 1024",
1201
2179
  width: "8",
1202
2180
  height: "8"
1203
2181
  }, [
1204
- x("path", {
2182
+ u("path", {
1205
2183
  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",
1206
2184
  fill: "currentColor"
1207
2185
  })
1208
2186
  ], -1)
1209
2187
  ])]),
1210
- y[2] || (y[2] = x("img", {
1211
- src: ve,
2188
+ i[2] || (i[2] = u("img", {
2189
+ src: ft,
1212
2190
  alt: "AI助手"
1213
2191
  }, null, -1)),
1214
- y[3] || (y[3] = x("span", { class: "ai-icon-text" }, "AI助手", -1))
2192
+ i[3] || (i[3] = u("span", { class: "ai-icon-text" }, "AI助手", -1))
1215
2193
  ])
1216
2194
  ]));
1217
2195
  }
1218
- }), tt = /* @__PURE__ */ le(et, [["__scopeId", "data-v-33f89960"]]), ne = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2196
+ }), Mn = { class: "ai-chat-plain" }, Fn = {
2197
+ name: "AiChatPlain"
2198
+ // 注册后的组件标签名:<sz-ai-chat-plain>
2199
+ }, Nn = /* @__PURE__ */ Ge({
2200
+ ...Fn,
2201
+ props: {
2202
+ token: {
2203
+ type: String,
2204
+ default: ""
2205
+ },
2206
+ identifier: {
2207
+ type: String,
2208
+ default: ""
2209
+ },
2210
+ baseUrl: {
2211
+ type: String,
2212
+ default: ""
2213
+ },
2214
+ title: {
2215
+ type: String,
2216
+ default: "数智AI助理"
2217
+ },
2218
+ /**
2219
+ * 大模型名称,对应 LLMTypes 中的 modelName
2220
+ * 例如: 'szjy' | 'spark' | 'dify-openai' | 'siliconflow' 等
2221
+ * 默认使用 'szjy'
2222
+ */
2223
+ llmName: {
2224
+ type: String,
2225
+ default: "szjy"
2226
+ },
2227
+ /**
2228
+ * 消息后处理回调函数
2229
+ * 在 AI 消息渲染完成后调用,可用于自定义处理渲染后的内容
2230
+ * @param container - 消息容器的 DOM 元素
2231
+ * @param textContent - 消息的文本内容
2232
+ */
2233
+ messagePostRender: {
2234
+ type: Function,
2235
+ default: null
2236
+ },
2237
+ /**
2238
+ * 额外配置参数,用于扩展供应商 API 调用
2239
+ * 例如:{ projectId: 'xxx' } 供 Dify 等供应商使用
2240
+ */
2241
+ extraConfig: {
2242
+ type: Object,
2243
+ default: () => ({})
2244
+ },
2245
+ /**
2246
+ * 语音识别模型静态资源基础路径,默认为 '/sounds/'
2247
+ */
2248
+ soundBaseUrl: {
2249
+ type: String,
2250
+ default: "/sounds/"
2251
+ },
2252
+ /**
2253
+ * Whisper Worker 脚本地址。不传则自动探测库产物与 /scripts/ai/whisper.worker.js
2254
+ */
2255
+ workerUrl: {
2256
+ type: String,
2257
+ default: ""
2258
+ },
2259
+ /**
2260
+ * 是否显示麦克风语音输入入口,默认关闭
2261
+ */
2262
+ enableVoiceInput: {
2263
+ type: Boolean,
2264
+ default: !1
2265
+ },
2266
+ /**
2267
+ * 是否显示上传音频/视频识别入口,默认关闭
2268
+ */
2269
+ enableVoiceUpload: {
2270
+ type: Boolean,
2271
+ default: !1
2272
+ }
2273
+ },
2274
+ emits: ["submit"],
2275
+ setup(r, { emit: e }) {
2276
+ const a = e;
2277
+ return Xe(), (t, o) => (w(), C("div", Mn, [
2278
+ j(Ze, {
2279
+ "model-value": !0,
2280
+ token: r.token,
2281
+ identifier: r.identifier,
2282
+ baseUrl: r.baseUrl,
2283
+ title: r.title,
2284
+ llmName: r.llmName,
2285
+ messagePostRender: r.messagePostRender,
2286
+ extraConfig: r.extraConfig,
2287
+ soundBaseUrl: r.soundBaseUrl,
2288
+ workerUrl: r.workerUrl,
2289
+ enableVoiceInput: r.enableVoiceInput,
2290
+ enableVoiceUpload: r.enableVoiceUpload,
2291
+ embedded: !0,
2292
+ onSubmit: o[0] || (o[0] = (n) => a("submit", n))
2293
+ }, null, 8, ["token", "identifier", "baseUrl", "title", "llmName", "messagePostRender", "extraConfig", "soundBaseUrl", "workerUrl", "enableVoiceInput", "enableVoiceUpload"])
2294
+ ]));
2295
+ }
2296
+ }), De = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1219
2297
  __proto__: null,
1220
- SzAiChat: tt
1221
- }, Symbol.toStringTag, { value: "Module" })), H = function(t) {
1222
- if (!H.installed) {
1223
- H.installed = !0;
1224
- for (let n in ne) {
1225
- const s = Reflect.get(ne, n);
1226
- t.component(s.name, s);
2298
+ SzAiChat: En,
2299
+ SzAiChatPlain: Nn
2300
+ }, Symbol.toStringTag, { value: "Module" })), Ie = function(r) {
2301
+ if (!Ie.installed) {
2302
+ Ie.installed = !0;
2303
+ for (let e in De) {
2304
+ const a = Reflect.get(De, e);
2305
+ r.component(a.name, a);
1227
2306
  }
1228
2307
  }
1229
- }, nt = (t, n) => {
1230
- const s = n ? `?${new URLSearchParams(n).toString()}` : "";
1231
- console.log(`点击了路由链接: ${t}${s}`);
1232
- }, rt = (t) => {
1233
- const n = t.indexOf("?");
1234
- if (n === -1)
1235
- return { routeName: t };
1236
- const s = t.substring(0, n), l = t.substring(n + 1), r = {};
1237
- return new URLSearchParams(l).forEach((o, u) => {
1238
- r[u] = o;
1239
- }), { routeName: s, queryParams: Object.keys(r).length > 0 ? r : void 0 };
1240
- }, ot = {
2308
+ }, On = (r, e) => {
2309
+ const a = e ? `?${new URLSearchParams(e).toString()}` : "";
2310
+ console.log(`点击了路由链接: ${r}${a}`);
2311
+ }, Vn = (r) => {
2312
+ const e = r.indexOf("?");
2313
+ if (e === -1)
2314
+ return { routeName: r };
2315
+ const a = r.substring(0, e), t = r.substring(e + 1), o = {};
2316
+ return new URLSearchParams(t).forEach((s, i) => {
2317
+ o[i] = s;
2318
+ }), { routeName: a, queryParams: Object.keys(o).length > 0 ? o : void 0 };
2319
+ }, $n = {
1241
2320
  color: "#536fec",
1242
2321
  fontWeight: "bold",
1243
2322
  textDecoration: "underline",
1244
2323
  cursor: "pointer",
1245
2324
  padding: "0 3px"
1246
- }, at = (t) => {
1247
- const n = /#router:([^#]+)#/g, s = [];
1248
- let l = 0, r;
1249
- for (; (r = n.exec(t)) !== null; ) {
1250
- r.index > l && s.push({ text: t.substring(l, r.index) });
1251
- const e = r[1], { routeName: o, queryParams: u } = rt(e);
1252
- s.push({ text: o, routeName: o, queryParams: u }), l = n.lastIndex;
2325
+ }, Bn = (r) => {
2326
+ const e = /#router:([^#]+)#/g, a = [];
2327
+ let t = 0, o;
2328
+ for (; (o = e.exec(r)) !== null; ) {
2329
+ o.index > t && a.push({ text: r.substring(t, o.index) });
2330
+ const n = o[1], { routeName: s, queryParams: i } = Vn(n);
2331
+ a.push({ text: s, routeName: s, queryParams: i }), t = e.lastIndex;
1253
2332
  }
1254
- return l < t.length && s.push({ text: t.substring(l) }), s;
1255
- }, st = (t, n, s = {}, l) => {
1256
- const { onRouteClick: r = nt, linkStyle: e = {} } = s, o = document.createElement("a");
1257
- o.href = "#", o.textContent = t;
1258
- const u = { ...ot, ...e };
1259
- return Object.assign(o.style, u), o.addEventListener("click", (d) => {
1260
- d.preventDefault(), r(n, l);
1261
- }), o;
1262
- }, lt = (t) => {
1263
- const n = /#router:([^#]+)#/g, s = [], l = document.createTreeWalker(
1264
- t,
2333
+ return t < r.length && a.push({ text: r.substring(t) }), a;
2334
+ }, zn = (r, e, a = {}, t) => {
2335
+ const { onRouteClick: o = On, linkStyle: n = {} } = a, s = document.createElement("a");
2336
+ s.href = "#", s.textContent = r;
2337
+ const i = { ...$n, ...n };
2338
+ return Object.assign(s.style, i), s.addEventListener("click", (l) => {
2339
+ l.preventDefault(), o(e, t);
2340
+ }), s;
2341
+ }, Dn = (r) => {
2342
+ const e = /#router:([^#]+)#/g, a = [], t = document.createTreeWalker(
2343
+ r,
1265
2344
  NodeFilter.SHOW_TEXT,
1266
2345
  null
1267
2346
  );
1268
- let r = l.nextNode();
1269
- for (; r; ) {
1270
- const e = r, o = e.textContent || "";
1271
- if (n.test(o)) {
1272
- n.lastIndex = 0;
1273
- const u = at(o);
1274
- u.length > 0 && s.push({ node: e, replacements: u });
2347
+ let o = t.nextNode();
2348
+ for (; o; ) {
2349
+ const n = o, s = n.textContent || "";
2350
+ if (e.test(s)) {
2351
+ e.lastIndex = 0;
2352
+ const i = Bn(s);
2353
+ i.length > 0 && a.push({ node: n, replacements: i });
1275
2354
  }
1276
- r = l.nextNode();
2355
+ o = t.nextNode();
1277
2356
  }
1278
- return s;
1279
- }, dt = (t, n, s = {}) => {
1280
- const l = lt(t);
1281
- l.forEach(({ node: r, replacements: e }) => {
1282
- var u;
1283
- const o = document.createDocumentFragment();
1284
- e.forEach(({ text: d, routeName: y, queryParams: _ }) => {
2357
+ return a;
2358
+ }, Gn = (r, e, a = {}) => {
2359
+ const t = Dn(r);
2360
+ t.forEach(({ node: o, replacements: n }) => {
2361
+ var i;
2362
+ const s = document.createDocumentFragment();
2363
+ n.forEach(({ text: l, routeName: y, queryParams: R }) => {
1285
2364
  if (y) {
1286
- const U = st(d, y, s, _);
1287
- o.appendChild(U);
2365
+ const F = zn(l, y, a, R);
2366
+ s.appendChild(F);
1288
2367
  } else
1289
- o.appendChild(document.createTextNode(d));
1290
- }), (u = r.parentNode) == null || u.replaceChild(o, r);
1291
- }), s != null && s.nodeCallback && l.forEach(({ node: r, replacements: e }) => {
1292
- var o;
1293
- (o = s.nodeCallback) == null || o.call(s, r, e);
2368
+ s.appendChild(document.createTextNode(l));
2369
+ }), (i = o.parentNode) == null || i.replaceChild(s, o);
2370
+ }), a != null && a.nodeCallback && t.forEach(({ node: o, replacements: n }) => {
2371
+ var s;
2372
+ (s = a.nodeCallback) == null || s.call(a, o, n);
1294
2373
  });
1295
- }, it = "0.1.8", ct = "Sz";
1296
- function ft({
1297
- componentPrefix: t = ct,
1298
- components: n = []
2374
+ }, ve = "szjy-voice-models", Se = "szjy-voice-cache-v1";
2375
+ function ye() {
2376
+ return typeof navigator < "u" && !!navigator.storage && typeof navigator.storage.getDirectory == "function";
2377
+ }
2378
+ async function Le(r = ve) {
2379
+ if (!ye()) return null;
2380
+ try {
2381
+ return await (await navigator.storage.getDirectory()).getDirectoryHandle(r, { create: !0 });
2382
+ } catch (e) {
2383
+ return console.warn("[OPFS] 获取目录失败,将使用降级缓存:", e), null;
2384
+ }
2385
+ }
2386
+ async function Jn(r, e, a = ve) {
2387
+ if (ye())
2388
+ try {
2389
+ const t = await Le(a);
2390
+ if (t) {
2391
+ const n = await (await t.getFileHandle(r, { create: !0 })).createWritable();
2392
+ return await n.write(e), await n.close(), !0;
2393
+ }
2394
+ } catch (t) {
2395
+ console.warn(`[OPFS] 写入文件 ${r} 失败:`, t);
2396
+ }
2397
+ if (typeof caches < "u")
2398
+ try {
2399
+ const t = await caches.open(Se), o = new Response(e, {
2400
+ headers: { "Content-Type": "application/octet-stream" }
2401
+ });
2402
+ return await t.put(`/${a}/${r}`, o), !0;
2403
+ } catch (t) {
2404
+ console.warn(`[CacheStorage] 缓存写入 ${r} 失败:`, t);
2405
+ }
2406
+ return !1;
2407
+ }
2408
+ async function Kn(r, e = ve) {
2409
+ if (ye())
2410
+ try {
2411
+ const a = await Le(e);
2412
+ if (a)
2413
+ return await (await (await a.getFileHandle(r, { create: !1 })).getFile()).arrayBuffer();
2414
+ } catch {
2415
+ }
2416
+ if (typeof caches < "u")
2417
+ try {
2418
+ const t = await (await caches.open(Se)).match(`/${e}/${r}`);
2419
+ if (t)
2420
+ return await t.arrayBuffer();
2421
+ } catch {
2422
+ }
2423
+ return null;
2424
+ }
2425
+ async function Qn(r, e = ve) {
2426
+ if (ye())
2427
+ try {
2428
+ const a = await Le(e);
2429
+ if (a)
2430
+ return (await (await a.getFileHandle(r, { create: !1 })).getFile()).size > 0;
2431
+ } catch {
2432
+ }
2433
+ if (typeof caches < "u")
2434
+ try {
2435
+ return !!await (await caches.open(Se)).match(`/${e}/${r}`);
2436
+ } catch {
2437
+ }
2438
+ return !1;
2439
+ }
2440
+ async function Zn(r = ve) {
2441
+ let e = !1;
2442
+ if (ye())
2443
+ try {
2444
+ await (await navigator.storage.getDirectory()).removeEntry(r, { recursive: !0 }), e = !0, console.log(`[OPFS] 成功清空语音模型缓存目录: ${r}`);
2445
+ } catch (a) {
2446
+ a.name === "NotFoundError" ? e = !0 : console.warn(`[OPFS] 清理目录 ${r} 异常:`, a);
2447
+ }
2448
+ if (typeof caches < "u")
2449
+ try {
2450
+ const a = await caches.keys();
2451
+ for (const t of a)
2452
+ (t.includes("transformers") || t.includes("szjy-voice") || t === Se) && (await caches.delete(t), e = !0);
2453
+ } catch (a) {
2454
+ console.warn("[CacheStorage] 清除缓存异常:", a);
2455
+ }
2456
+ return e;
2457
+ }
2458
+ const jn = "0.1.12", Hn = "Sz";
2459
+ function Yn({
2460
+ componentPrefix: r = Hn,
2461
+ components: e = []
1299
2462
  } = {}) {
1300
- const s = [];
1301
- function l(e, o, u) {
1302
- e.component(t + o) || e.component(
1303
- t + o,
1304
- u
2463
+ const a = [];
2464
+ function t(n, s, i) {
2465
+ n.component(r + s) || n.component(
2466
+ r + s,
2467
+ i
1305
2468
  );
1306
2469
  }
1307
- function r(e) {
1308
- s.includes(e) || (s.push(e), n.forEach((o) => {
1309
- const { name: u, alias: d } = o;
1310
- l(e, u, o), d && d.forEach((y) => {
1311
- l(e, y, o);
2470
+ function o(n) {
2471
+ a.includes(n) || (a.push(n), e.forEach((s) => {
2472
+ const { name: i, alias: l } = s;
2473
+ t(n, i, s), l && l.forEach((y) => {
2474
+ t(n, y, s);
1312
2475
  });
1313
2476
  }));
1314
2477
  }
1315
2478
  return {
1316
- version: it,
1317
- componentPrefix: t,
1318
- install: r
2479
+ version: jn,
2480
+ componentPrefix: r,
2481
+ install: o
1319
2482
  };
1320
2483
  }
1321
- const pt = {
1322
- install(t) {
1323
- H(t);
2484
+ const Xn = {
2485
+ install(r) {
2486
+ Ie(r);
1324
2487
  }
1325
2488
  };
1326
2489
  export {
1327
- tt as SzAiChat,
1328
- ft as create,
1329
- st as createRouteLink,
1330
- pt as default,
1331
- lt as findRouteTextNodes,
1332
- rt as parseRouteMarkerContent,
1333
- at as parseRouteMarkers,
1334
- dt as routeLinkRender
2490
+ $t as AudioRecorder,
2491
+ Qe as DEFAULT_WHISPER_WORKER_URL,
2492
+ Vt as StreamResampler,
2493
+ En as SzAiChat,
2494
+ Nn as SzAiChatPlain,
2495
+ Wt as VoiceInputManager,
2496
+ Zn as clearVoiceModelCache,
2497
+ Yn as create,
2498
+ zn as createRouteLink,
2499
+ zt as decodeAudioFile,
2500
+ Xn as default,
2501
+ Dn as findRouteTextNodes,
2502
+ Be as float32ToWav,
2503
+ Kn as getFileFromCache,
2504
+ Le as getOPFSDirectory,
2505
+ Qn as hasFileInCache,
2506
+ ye as isOPFSSupported,
2507
+ Vn as parseRouteMarkerContent,
2508
+ Bn as parseRouteMarkers,
2509
+ Bt as resampleAudioData,
2510
+ Gn as routeLinkRender,
2511
+ Jn as saveFileToCache
1335
2512
  };