@opentiny/tiny-robot 0.3.1-alpha.4 → 0.4.0-alpha.1

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/index2.js CHANGED
@@ -1,301 +1,841 @@
1
- import { ref as _, onMounted as ne, onBeforeUnmount as oe, defineComponent as P, createElementBlock as a, openBlock as r, createElementVNode as w, createVNode as $, unref as n, toDisplayString as B, mergeModels as W, useModel as j, computed as I, normalizeStyle as ie, Fragment as S, renderList as V, createBlock as H, resolveDynamicComponent as Y, nextTick as se, normalizeClass as U, withDirectives as q, createCommentVNode as G, renderSlot as A, withKeys as F, withModifiers as J, isRef as le, vModelText as re, vShow as ae } from "vue";
2
- import { IconEmptySearch as ue, IconEditPen as ce, IconDelete as de, IconCheck as me, IconClose as fe, IconMenu2 as pe } from "@opentiny/tiny-robot-svgs";
3
- import { _ as z } from "./_plugin-vue_export-helper.js";
4
- import { o as Z, a as ve, d as ge, c as ye } from "./index3.js";
5
- import { t as O } from "./utils.js";
6
- const D = _(!1);
7
- let T = 0, b;
8
- function _e() {
9
- const s = window.matchMedia("(hover: none) and (pointer: coarse)"), m = () => {
10
- D.value = s.matches;
11
- };
12
- m(), s.addEventListener("change", m);
13
- const t = (c) => {
14
- D.value = c.pointerType !== "mouse";
15
- };
16
- return window.addEventListener("pointerdown", t, !0), () => {
17
- s.removeEventListener("change", m), window.removeEventListener("pointerdown", t, !0);
18
- };
1
+ import { defineComponent as C, createElementBlock as B, openBlock as f, renderSlot as R, ref as M, computed as v, watch as Q, normalizeClass as Y, createVNode as z, unref as E, watchEffect as W, Fragment as N, createElementVNode as x, createBlock as k, withDirectives as q, toDisplayString as V, vShow as Z, resolveDynamicComponent as U, normalizeProps as O, guardReactiveProps as P, createCommentVNode as se, useCssModule as Oe, renderList as J, mergeProps as D, markRaw as w, provide as L, inject as A, toValue as S, reactive as De, withCtx as $, onMounted as fe, onUnmounted as Pe, nextTick as me } from "vue";
2
+ import { _ as T } from "./_plugin-vue_export-helper.js";
3
+ import { IconLoading as pe, IconAtom as Fe, IconArrowDown as _e, IconPlugin as ue, IconError as Ge, IconCancelled as Ke } from "@opentiny/tiny-robot-svgs";
4
+ import { u as Ue, a as He, w as Je, b as Ye } from "./index5.js";
5
+ const be = Symbol("bubble-message-group"), ge = Symbol("bubble-box-renderer-matches"), he = Symbol("bubble-box-fallback-renderer"), ve = Symbol(
6
+ "bubble-box-prop-fallback-renderer"
7
+ ), ye = Symbol("bubble-content-renderer-matches"), xe = Symbol(
8
+ "bubble-content-fallback-renderer"
9
+ ), Be = Symbol(
10
+ "bubble-content-prop-fallback-renderer"
11
+ ), ne = Symbol("bubble-store"), Re = Symbol("bubble-state-change-fn"), G = {
12
+ LOADING: -1,
13
+ NORMAL: 0,
14
+ CONTENT: 10,
15
+ ROLE: 20
16
+ }, ze = {
17
+ class: "tr-bubble__box",
18
+ "data-box-type": "box"
19
+ }, We = /* @__PURE__ */ C({
20
+ __name: "Box",
21
+ props: {
22
+ placement: {},
23
+ shape: {}
24
+ },
25
+ setup(t) {
26
+ return (e, n) => (f(), B("div", ze, [
27
+ R(e.$slots, "default", {}, void 0, !0)
28
+ ]));
29
+ }
30
+ }), oe = /* @__PURE__ */ T(We, [["__scopeId", "data-v-98101726"]]), Ve = ["src", "alt"], Xe = /* @__PURE__ */ C({
31
+ __name: "Image",
32
+ props: {
33
+ message: {},
34
+ contentIndex: {}
35
+ },
36
+ setup(t) {
37
+ const e = t, n = M(!1), s = M(!1), c = v(() => Array.isArray(e.message.content) ? e.message.content[e.contentIndex ?? 0] : null), u = v(() => c.value ? typeof c.value.image_url == "string" ? c.value.image_url : c.value.image_url.url : null);
38
+ Q(u, () => {
39
+ n.value = !1, s.value = !1;
40
+ });
41
+ const o = () => {
42
+ n.value = !0, s.value = !1;
43
+ }, d = () => {
44
+ s.value = !0, n.value = !0;
45
+ };
46
+ return (h, y) => {
47
+ var p;
48
+ return f(), B("img", {
49
+ class: Y(["tr-bubble__image", { loading: !n.value }]),
50
+ src: u.value,
51
+ alt: (p = c.value) == null ? void 0 : p.text,
52
+ loading: "lazy",
53
+ onLoad: o,
54
+ onError: d,
55
+ "data-type": "image"
56
+ }, null, 42, Ve);
57
+ };
58
+ }
59
+ }), Ce = /* @__PURE__ */ T(Xe, [["__scopeId", "data-v-f1a85934"]]), je = {
60
+ class: "tr-bubble__loading",
61
+ "data-type": "loading"
62
+ }, qe = /* @__PURE__ */ C({
63
+ __name: "Loading",
64
+ props: {
65
+ message: {},
66
+ contentIndex: {}
67
+ },
68
+ setup(t) {
69
+ return (e, n) => (f(), B("div", je, [
70
+ z(E(pe))
71
+ ]));
72
+ }
73
+ }), ke = /* @__PURE__ */ T(qe, [["__scopeId", "data-v-bc1b5ff4"]]), Ze = {
74
+ class: "tr-bubble__reasoning",
75
+ "data-type": "reasoning"
76
+ }, Qe = { class: "title" }, et = { class: "detail" }, tt = { class: "detail" }, nt = /* @__PURE__ */ C({
77
+ __name: "Reasoning",
78
+ props: {
79
+ message: {},
80
+ contentIndex: {}
81
+ },
82
+ setup(t) {
83
+ const e = t, { restMessage: n, restProps: s } = Ne(e, ["reasoning_content"]), c = ae(n, e.contentIndex), u = M(!1);
84
+ W(() => {
85
+ var h;
86
+ u.value = ((h = e.message.state) == null ? void 0 : h.open) ?? !1;
87
+ });
88
+ const o = we(), d = () => {
89
+ u.value = !u.value, o("open", u.value);
90
+ };
91
+ return (h, y) => {
92
+ var p;
93
+ return f(), B(N, null, [
94
+ x("div", Ze, [
95
+ x("div", {
96
+ class: "header",
97
+ onClick: d
98
+ }, [
99
+ z(E(Fe)),
100
+ x("span", Qe, V((p = e.message.state) != null && p.thinking ? "正在思考" : "已思考"), 1),
101
+ z(E(_e), {
102
+ class: Y(["expand-icon", { "-rotate-90": !u.value }])
103
+ }, null, 8, ["class"])
104
+ ]),
105
+ q(x("div", et, [
106
+ y[0] || (y[0] = x("div", { class: "side-border" }, [
107
+ x("div", { class: "dot-wrapper" }, [
108
+ x("div", { class: "dot" })
109
+ ]),
110
+ x("div", { class: "border-line" })
111
+ ], -1)),
112
+ x("p", tt, V(e.message.reasoning_content), 1)
113
+ ], 512), [
114
+ [Z, u.value]
115
+ ])
116
+ ]),
117
+ (f(), k(U(E(c)), O(P(E(s))), null, 16))
118
+ ], 64);
119
+ };
120
+ }
121
+ }), Ie = /* @__PURE__ */ T(nt, [["__scopeId", "data-v-b7c07b23"]]), st = {
122
+ key: 0,
123
+ class: "tr-bubble__text",
124
+ "data-type": "text"
125
+ }, ot = /* @__PURE__ */ C({
126
+ __name: "Text",
127
+ props: {
128
+ message: {},
129
+ contentIndex: {}
130
+ },
131
+ setup(t) {
132
+ const e = t, n = v(() => {
133
+ var s;
134
+ return typeof e.message.content == "string" ? e.message.content : (s = e.message.content) == null ? void 0 : s[e.contentIndex ?? 0].text;
135
+ });
136
+ return (s, c) => n.value ? (f(), B("p", st, V(n.value), 1)) : se("", !0);
137
+ }
138
+ }), re = /* @__PURE__ */ T(ot, [["__scopeId", "data-v-ab6bd049"]]), Ee = /* @__PURE__ */ C({
139
+ __name: "ToolRole",
140
+ props: {
141
+ message: {},
142
+ contentIndex: {}
143
+ },
144
+ setup(t) {
145
+ const e = t, n = ce();
146
+ return W(() => {
147
+ e.message.tool_call_id && (n.toolCallResults || (n.toolCallResults = {}), n.toolCallResults[e.message.tool_call_id] = e.message.content ?? "");
148
+ }), (s, c) => se("", !0);
149
+ }
150
+ });
151
+ let ee = null;
152
+ const rt = () => (ee || (ee = import("./index4.js")), ee);
153
+ let H = null;
154
+ const at = async () => {
155
+ if (H)
156
+ return H;
157
+ try {
158
+ const [t, e] = await Promise.all([import("markdown-it"), import("dompurify")]);
159
+ return H = { markdown: t.default, dompurify: e.default }, H;
160
+ } catch {
161
+ return console.warn("[BubbleMarkdownRenderer] install markdown-it and dompurify to use markdown renderer"), H = null, null;
162
+ }
163
+ }, lt = {
164
+ class: "tr-bubble__tool-call",
165
+ "data-type": "tool-call"
166
+ }, ct = { class: "header" }, ut = { class: "header-left" }, it = { class: "title" }, dt = { class: "header-right" }, ft = { class: "divider" }, mt = ["innerHTML"], pt = /* @__PURE__ */ C({
167
+ __name: "Tool",
168
+ props: {
169
+ message: {},
170
+ contentIndex: {},
171
+ toolIndex: {}
172
+ },
173
+ setup(t) {
174
+ const e = ["running", "success", "failed", "cancelled"], n = t, s = v(() => {
175
+ var r, m;
176
+ return (m = (r = n.message) == null ? void 0 : r.tool_calls) == null ? void 0 : m[n.toolIndex];
177
+ }), c = v(() => {
178
+ var m, g, I;
179
+ const r = (m = s.value) == null ? void 0 : m.id;
180
+ return r ? (I = (g = n.message.state) == null ? void 0 : g.toolCall) == null ? void 0 : I[r] : null;
181
+ }), u = ce(), o = v(() => {
182
+ var m;
183
+ const r = (m = c.value) == null ? void 0 : m.status;
184
+ return r && e.includes(r) ? r : u.toolCallDefaultStatus && e.includes(u.toolCallDefaultStatus) ? u.toolCallDefaultStatus : "";
185
+ }), d = /* @__PURE__ */ new Map([
186
+ ["running", { text: "正在调用", icon: pe }],
187
+ ["success", { text: "已调用", icon: ue }],
188
+ ["failed", { text: "调用失败", icon: Ge }],
189
+ ["cancelled", { text: "已取消", icon: Ke }]
190
+ ]), h = v(() => d.get(o.value) || { text: "", icon: ue }), y = Oe(), p = (r, m = 2) => {
191
+ if (!r)
192
+ return "";
193
+ let g = "";
194
+ try {
195
+ typeof r == "string" ? g = JSON.stringify(JSON.parse(r), null, m) : g = JSON.stringify(r, null, m);
196
+ } catch {
197
+ }
198
+ return g = g.replace(
199
+ /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/g,
200
+ (I) => {
201
+ let F = "number";
202
+ return /^"/.test(I) ? F = /:$/.test(I) ? "key" : "string" : /true|false/.test(I) ? F = "boolean" : /null/.test(I) && (F = "null"), `<span class="${y[F]}">${I}</span>`;
203
+ }
204
+ ), g;
205
+ }, _ = M(""), l = v(() => {
206
+ var m, g;
207
+ const r = (m = s.value) == null ? void 0 : m.id;
208
+ if (r)
209
+ return (g = u.toolCallResults) == null ? void 0 : g[r];
210
+ });
211
+ W(() => {
212
+ var g;
213
+ const r = (g = s.value) == null ? void 0 : g.function.arguments, m = l.value;
214
+ rt().then(({ jsonrepair: I }) => {
215
+ const F = I(typeof r == "string" ? r || "{}" : JSON.stringify(r));
216
+ _.value = p(
217
+ {
218
+ arguments: JSON.parse(F),
219
+ result: m ? JSON.parse(I(m || "{}")) : void 0
220
+ },
221
+ 2
222
+ );
223
+ }).catch((I) => {
224
+ console.warn(I);
225
+ });
226
+ });
227
+ const i = M(!1);
228
+ W(() => {
229
+ var r;
230
+ i.value = !!(((r = c.value) == null ? void 0 : r.open) ?? u.toolCallDefaultOpen);
231
+ });
232
+ const b = we(), a = () => {
233
+ var m, g;
234
+ i.value = !i.value;
235
+ const r = (m = s.value) == null ? void 0 : m.id;
236
+ r && b("toolCall", {
237
+ ...(g = n.message.state) == null ? void 0 : g.toolCall,
238
+ [r]: { ...c.value, open: i.value }
239
+ });
240
+ };
241
+ return (r, m) => {
242
+ var g;
243
+ return f(), B("div", lt, [
244
+ x("div", ct, [
245
+ x("div", ut, [
246
+ (f(), k(U(h.value.icon), {
247
+ class: Y(["header-icon", `icon-${o.value}`])
248
+ }, null, 8, ["class"])),
249
+ x("span", null, [
250
+ x("span", null, V(h.value.text) + " ", 1),
251
+ x("span", it, V(((g = s.value) == null ? void 0 : g.function.name) || "Untitled"), 1)
252
+ ])
253
+ ]),
254
+ x("div", dt, [
255
+ z(E(_e), {
256
+ class: Y(["expand-icon", { "-rotate-90": !i.value }]),
257
+ onClick: a
258
+ }, null, 8, ["class"])
259
+ ])
260
+ ]),
261
+ q(x("div", ft, null, 512), [
262
+ [Z, i.value]
263
+ ]),
264
+ q(x("div", {
265
+ class: "detail",
266
+ innerHTML: _.value
267
+ }, null, 8, mt), [
268
+ [Z, i.value]
269
+ ])
270
+ ]);
271
+ };
272
+ }
273
+ }), _t = "_key_1b448_2", bt = "_number_1b448_6", gt = "_string_1b448_10", ht = "_boolean_1b448_14", vt = {
274
+ key: _t,
275
+ number: bt,
276
+ string: gt,
277
+ boolean: ht,
278
+ null: "_null_1b448_18"
279
+ }, yt = {
280
+ $style: vt
281
+ }, Se = /* @__PURE__ */ T(pt, [["__cssModules", yt], ["__scopeId", "data-v-545ab64d"]]), $e = /* @__PURE__ */ C({
282
+ __name: "Tools",
283
+ props: {
284
+ message: {},
285
+ contentIndex: {}
286
+ },
287
+ setup(t) {
288
+ const e = t, { restMessage: n, restProps: s } = Ne(e, ["tool_calls"]), c = ae(n, e.contentIndex);
289
+ return (u, o) => (f(), B(N, null, [
290
+ (f(), k(U(E(c)), O(P(E(s))), null, 16)),
291
+ (f(!0), B(N, null, J(e.message.tool_calls, (d, h) => (f(), k(Se, D({
292
+ key: d.id
293
+ }, { ref_for: !0 }, e, { "tool-index": h }), null, 16, ["tool-index"]))), 128))
294
+ ], 64));
295
+ }
296
+ }), Ae = [
297
+ {
298
+ find: (t, e) => t.length === 1 && Array.isArray(t[0].content) && typeof e == "number" && t[0].content[e].type === "image_url",
299
+ renderer: w(oe),
300
+ priority: G.NORMAL,
301
+ attributes: { "data-box-type": "image" }
302
+ }
303
+ ], Me = [
304
+ {
305
+ find: (t) => !!t.loading,
306
+ renderer: w(ke),
307
+ priority: G.LOADING
308
+ },
309
+ {
310
+ find: (t) => typeof t.reasoning_content == "string",
311
+ renderer: w(Ie),
312
+ priority: G.NORMAL
313
+ },
314
+ {
315
+ find: (t) => Array.isArray(t.tool_calls) && t.tool_calls.length > 0,
316
+ renderer: w($e),
317
+ priority: G.NORMAL
318
+ },
319
+ {
320
+ find: (t, e) => Array.isArray(t.content) && t.content[e ?? 0].type === "image_url",
321
+ renderer: w(Ce),
322
+ priority: G.CONTENT
323
+ },
324
+ {
325
+ find: (t) => t.role === "tool",
326
+ renderer: w(Ee),
327
+ priority: G.ROLE
328
+ }
329
+ ], Le = w(oe), Te = w(re);
330
+ function xt(t) {
331
+ const { boxRendererMatches: e, fallbackBoxRenderer: n } = t;
332
+ e && L(ge, e), n && L(he, n);
19
333
  }
20
- function he() {
21
- b == null || b(), b = void 0;
334
+ function Bt(t) {
335
+ const { fallbackBoxRenderer: e } = t;
336
+ e && L(ve, e);
22
337
  }
23
- function Ce() {
24
- return typeof window > "u" ? {
25
- isTouchDevice: D
26
- } : (ne(() => {
27
- T++, T === 1 && (b = _e());
28
- }), oe(() => {
29
- T = Math.max(0, T - 1), T === 0 && he();
30
- }), {
31
- isTouchDevice: D
338
+ function Rt(t, e) {
339
+ const n = A(ge, Ae), s = A(he, void 0), c = A(ve, void 0);
340
+ return v(() => {
341
+ const u = S(t), o = S(n).find((d) => d.find(u, e));
342
+ return o ? {
343
+ renderer: o.renderer,
344
+ attributes: o.attributes
345
+ } : {
346
+ renderer: S(c) || S(s) || Le
347
+ };
32
348
  });
33
349
  }
34
- const ke = { class: "tr-history__empty" }, Le = { class: "tr-history__empty-icon" }, Ee = { class: "tr-history__empty-text" }, we = /* @__PURE__ */ P({
35
- __name: "Empty",
350
+ function Ct(t) {
351
+ const { contentRendererMatches: e, fallbackContentRenderer: n } = t;
352
+ e && L(ye, e), n && L(xe, n);
353
+ }
354
+ function kt(t) {
355
+ const { fallbackContentRenderer: e } = t;
356
+ e && L(Be, e);
357
+ }
358
+ function ae(t, e) {
359
+ const n = A(ye, Me), s = A(xe, void 0), c = A(Be, void 0);
360
+ return v(() => {
361
+ const u = S(t), o = S(n).find((d) => d.find(u, e));
362
+ return o ? o.renderer : S(c) || S(s) || Te;
363
+ });
364
+ }
365
+ function It(t) {
366
+ L(Re, t);
367
+ }
368
+ function we() {
369
+ return A(Re, (t, e) => {
370
+ console.warn(`[Bubble] State change function not found for key: ${t}`);
371
+ });
372
+ }
373
+ function le(t) {
374
+ const e = A(ne, void 0);
375
+ if (e)
376
+ return e;
377
+ const n = De(t || {});
378
+ return L(ne, n), n;
379
+ }
380
+ function ce() {
381
+ return A(ne, {});
382
+ }
383
+ function Et(t) {
384
+ L(be, t);
385
+ }
386
+ function St() {
387
+ return A(be, void 0);
388
+ }
389
+ function Ne(t, e) {
390
+ const n = v(() => {
391
+ const c = Object.entries(t.message).filter(([u]) => !e.includes(u));
392
+ return Object.fromEntries(c);
393
+ }), s = v(() => ({
394
+ ...t,
395
+ message: n.value
396
+ }));
397
+ return {
398
+ restMessage: n,
399
+ restProps: s
400
+ };
401
+ }
402
+ const ie = /* @__PURE__ */ C({
403
+ __name: "BubbleBoxWrapper",
36
404
  props: {
37
- text: { default: "暂无内容" }
405
+ role: {},
406
+ placement: {},
407
+ shape: {},
408
+ messages: {},
409
+ contentIndex: {}
38
410
  },
39
- setup(s) {
40
- const m = s;
41
- return (t, c) => (r(), a("div", ke, [
42
- w("span", Le, [
43
- $(n(ue))
411
+ setup(t) {
412
+ const e = t, n = Rt(() => e.messages, e.contentIndex);
413
+ return (s, c) => (f(), k(U(E(n).renderer), D({
414
+ "data-role": e.role,
415
+ "data-placement": e.placement,
416
+ "data-shape": e.shape
417
+ }, E(n).attributes), {
418
+ default: $(() => [
419
+ R(s.$slots, "default")
44
420
  ]),
45
- w("span", Ee, B(m.text), 1)
46
- ]));
421
+ _: 3
422
+ }, 16, ["data-role", "data-placement", "data-shape"]));
47
423
  }
48
- }), Re = /* @__PURE__ */ z(we, [["__scopeId", "data-v-d0340c39"]]), Ie = ["onClick"], Q = 4, xe = /* @__PURE__ */ P({
49
- __name: "MenuList",
50
- props: /* @__PURE__ */ W({
51
- items: {},
52
- menuListGap: { default: 8 }
53
- }, {
54
- trigger: { default: null },
55
- triggerModifiers: {},
56
- data: { default: null },
57
- dataModifiers: {}
58
- }),
59
- emits: /* @__PURE__ */ W(["item-click"], ["update:trigger", "update:data"]),
60
- setup(s, { emit: m }) {
61
- const t = j(s, "trigger"), c = j(s, "data"), h = s, C = m, E = _(null);
62
- Z(
63
- E,
64
- () => {
65
- t.value = null, c.value = null;
66
- },
67
- {
68
- ignore: [t]
69
- }
70
- );
71
- const { top: p, bottom: x, left: y } = ve(t), { width: M, height: k } = ge(E, void 0, { box: "border-box" }), { height: R } = ye(), o = I(() => {
72
- const L = {
73
- left: `min(${O(y.value)}, calc(100% - ${O(M.value + Q)}))`
74
- }, g = x.value + h.menuListGap;
75
- return g + k.value + Q > R.value ? L.bottom = `calc(100% - ${O(p.value - h.menuListGap)})` : L.top = O(g), L;
76
- }), v = (L) => {
77
- C("item-click", L), t.value = null, c.value = null;
78
- };
79
- return (L, g) => (r(), a("ul", {
80
- class: "tr-history__menu-list",
81
- ref_key: "menuRef",
82
- ref: E,
83
- style: ie(o.value)
84
- }, [
85
- (r(!0), a(S, null, V(h.items, (u) => (r(), a("li", {
86
- class: "tr-history__menu-list__item",
87
- key: u.id,
88
- onClick: (K) => v(u)
89
- }, [
90
- (r(), H(Y(u.icon))),
91
- w("span", null, B(u.text), 1)
92
- ], 8, Ie))), 128))
93
- ], 4));
424
+ }), te = /* @__PURE__ */ C({
425
+ __name: "BubbleContentWrapper",
426
+ props: {
427
+ message: {},
428
+ contentIndex: {}
429
+ },
430
+ emits: ["state-change"],
431
+ setup(t, { emit: e }) {
432
+ const n = t, s = ae(() => n.message, n.contentIndex), c = e;
433
+ return It((o, d) => {
434
+ c("state-change", {
435
+ key: o,
436
+ value: d,
437
+ contentIndex: n.contentIndex
438
+ });
439
+ }), (o, d) => (f(), k(U(E(s)), O(P(n)), null, 16));
94
440
  }
95
- }), Me = /* @__PURE__ */ z(xe, [["__scopeId", "data-v-89fdb41c"]]), Te = ({
96
- renameControlOnClickOutside: s,
97
- onItemTitleChange: m
98
- }) => {
99
- const t = _(void 0), c = _(null), h = I(() => {
100
- var o;
101
- return (o = c.value) == null ? void 0 : o.at(0);
102
- }), C = _(null), E = I(() => {
103
- var o;
104
- return (o = C.value) == null ? void 0 : o.at(0);
105
- }), p = _(null), x = I(() => {
106
- var o;
107
- return (o = p.value) == null ? void 0 : o.at(0);
108
- }), y = _(""), M = (o) => {
109
- t.value = o, y.value = o.title, se(() => {
110
- const v = h.value;
111
- v && (v.focus(), v.select());
441
+ }), $t = ["data-role", "data-placement"], At = { class: "tr-bubble__body" }, Mt = { class: "tr-bubble__content" }, Lt = { class: "tr-bubble__after" }, Tt = /* @__PURE__ */ C({
442
+ __name: "Bubble",
443
+ props: {
444
+ content: {},
445
+ reasoning_content: {},
446
+ tool_calls: {},
447
+ tool_call_id: {},
448
+ name: {},
449
+ role: {},
450
+ id: {},
451
+ loading: { type: Boolean },
452
+ state: {},
453
+ hidden: { type: Boolean },
454
+ avatar: {},
455
+ placement: { default: "start" },
456
+ shape: { default: "corner" },
457
+ contentRenderMode: { default: "single" },
458
+ fallbackBoxRenderer: {},
459
+ fallbackContentRenderer: {}
460
+ },
461
+ emits: ["state-change"],
462
+ setup(t, { emit: e }) {
463
+ const n = t, s = e;
464
+ le();
465
+ const c = St(), u = v(() => S(c)), o = v(() => {
466
+ var g;
467
+ if ((g = u.value) != null && g.messages.length)
468
+ return u.value.messages;
469
+ const { role: y, content: p, reasoning_content: _, tool_calls: l, tool_call_id: i, name: b, id: a, loading: r, state: m } = n;
470
+ return [{ role: y, content: p, reasoning_content: _, tool_calls: l, tool_call_id: i, name: b, id: a, loading: r, state: m }];
112
471
  });
113
- }, k = () => {
114
- t.value = void 0, y.value = "";
115
- }, R = () => {
116
- t.value && m(y.value, t.value), t.value = void 0, y.value = "";
472
+ Bt({ fallbackBoxRenderer: () => n.fallbackBoxRenderer }), kt({ fallbackContentRenderer: () => n.fallbackContentRenderer });
473
+ const d = v(() => o.value.length === 0 ? !0 : n.hidden), h = v(() => n.contentRenderMode === "split" && o.value.length === 1 && Array.isArray(o.value[0].content));
474
+ return (y, p) => q((f(), B("div", {
475
+ class: "tr-bubble",
476
+ "data-role": n.role,
477
+ "data-placement": n.placement
478
+ }, [
479
+ R(y.$slots, "prefix", {
480
+ messages: o.value,
481
+ role: t.role
482
+ }, void 0, !0),
483
+ x("div", At, [
484
+ n.avatar ? (f(), k(U(n.avatar), {
485
+ key: 0,
486
+ class: Y(["tr-bubble__avatar", y.$style["tr-bubble__avatar"]])
487
+ }, null, 8, ["class"])) : se("", !0),
488
+ x("div", Mt, [
489
+ h.value ? (f(!0), B(N, { key: 0 }, J(o.value[0].content, (_, l) => (f(), k(ie, {
490
+ key: l,
491
+ class: "tr-bubble__box",
492
+ role: n.role,
493
+ placement: n.placement,
494
+ shape: n.shape,
495
+ messages: o.value,
496
+ "content-index": l
497
+ }, {
498
+ default: $(() => [
499
+ z(te, {
500
+ message: o.value[0],
501
+ "content-index": l,
502
+ onStateChange: p[0] || (p[0] = (i) => s("state-change", { ...i, messageIndex: 0 }))
503
+ }, null, 8, ["message", "content-index"]),
504
+ R(y.$slots, "content-footer", {
505
+ messages: o.value,
506
+ role: n.role,
507
+ contentIndex: l
508
+ }, void 0, !0)
509
+ ]),
510
+ _: 2
511
+ }, 1032, ["role", "placement", "shape", "messages", "content-index"]))), 128)) : (f(), k(ie, {
512
+ key: 1,
513
+ role: n.role,
514
+ placement: n.placement,
515
+ shape: n.shape,
516
+ messages: o.value
517
+ }, {
518
+ default: $(() => [
519
+ (f(!0), B(N, null, J(o.value, (_, l) => (f(), B(N, {
520
+ key: `message-${l}`
521
+ }, [
522
+ Array.isArray(_.content) ? (f(!0), B(N, { key: 0 }, J(_.content, (i, b) => (f(), k(te, {
523
+ key: `content-${b}`,
524
+ message: _,
525
+ "content-index": b,
526
+ onStateChange: (a) => s("state-change", { ...a, messageIndex: l })
527
+ }, null, 8, ["message", "content-index", "onStateChange"]))), 128)) : (f(), k(te, {
528
+ key: 1,
529
+ message: _,
530
+ onStateChange: (i) => s("state-change", { ...i, messageIndex: l })
531
+ }, null, 8, ["message", "onStateChange"]))
532
+ ], 64))), 128)),
533
+ R(y.$slots, "content-footer", {
534
+ messages: o.value,
535
+ role: n.role
536
+ }, void 0, !0)
537
+ ]),
538
+ _: 3
539
+ }, 8, ["role", "placement", "shape", "messages"]))
540
+ ]),
541
+ x("div", Lt, [
542
+ R(y.$slots, "after", {
543
+ messages: o.value,
544
+ role: t.role
545
+ }, void 0, !0)
546
+ ])
547
+ ]),
548
+ R(y.$slots, "suffix", {
549
+ messages: o.value,
550
+ role: t.role
551
+ }, void 0, !0)
552
+ ], 8, $t)), [
553
+ [Z, !d.value]
554
+ ]);
555
+ }
556
+ }), wt = {
557
+ "tr-bubble__avatar": "_tr-bubble__avatar_1r87c_2"
558
+ }, Nt = {
559
+ $style: wt
560
+ }, K = /* @__PURE__ */ T(Tt, [["__cssModules", Nt], ["__scopeId", "data-v-576e318d"]]);
561
+ function de(t, e) {
562
+ const n = Q(t, (s, c) => {
563
+ c === !0 && s === !1 && (e(), n());
564
+ });
565
+ return n;
566
+ }
567
+ function Ot(t, e, n) {
568
+ const { scrollOnMount: s = !0, bottomThreshold: c = 20, scrollThrottle: u = 0 } = n ?? {}, o = M(!0);
569
+ let d = !1;
570
+ const h = /* @__PURE__ */ new Set(), y = () => He(t), { y: p, isScrolling: _ } = Ue(y, { throttle: u }), l = (a) => a.scrollHeight - a.scrollTop - a.clientHeight <= c, i = async (a = "auto") => {
571
+ const r = S(y);
572
+ if (r && (await me(), r.scrollTo({ top: r.scrollHeight, behavior: a }), a === "smooth" && !l(r))) {
573
+ const m = de(_, () => {
574
+ r.scrollTo({ top: r.scrollHeight, behavior: "auto" }), h.delete(m);
575
+ });
576
+ h.add(m);
577
+ }
578
+ }, b = () => {
579
+ d || !o.value || (d = !0, requestAnimationFrame(async () => {
580
+ d = !1, await i("auto");
581
+ }));
117
582
  };
118
- return (s === "confirm" || s === "cancel") && Z(
119
- h,
583
+ return Q(
584
+ p,
120
585
  () => {
121
- s === "confirm" ? R() : k();
586
+ const a = S(y);
587
+ a && (o.value = l(a));
122
588
  },
123
- { ignore: [E, x] }
124
- ), {
125
- editingItem: t,
126
- editorRefList: c,
127
- editorConfirmRefList: C,
128
- editorCancelRefList: p,
129
- editorValue: y,
130
- handleEdit: M,
131
- handleEditCancel: k,
132
- handleEditConfirm: R
589
+ { flush: "post" }
590
+ ), Je(
591
+ e,
592
+ () => {
593
+ b();
594
+ },
595
+ { flush: "post", throttle: 100 }
596
+ ), fe(() => {
597
+ s && i("smooth");
598
+ }), Pe(() => {
599
+ h.forEach((a) => {
600
+ a();
601
+ }), h.clear();
602
+ }), Ye("keydown", (a) => {
603
+ if (a.key === "End" && !o.value) {
604
+ const r = de(_, () => {
605
+ i("auto"), h.delete(r);
606
+ });
607
+ h.add(r);
608
+ }
609
+ }), {
610
+ scrollToBottom: i
133
611
  };
134
- }, X = Symbol("NO_GROUP"), $e = {
135
- key: 0,
136
- class: "tr-history__group-title"
137
- }, be = { class: "tr-history__group-items" }, Ge = ["onClick"], Oe = ["title"], Se = ["onClick"], Be = /* @__PURE__ */ P({
138
- __name: "index",
612
+ }
613
+ const Dt = /* @__PURE__ */ C({
614
+ __name: "BubbleItem",
139
615
  props: {
140
- data: {},
141
- selected: {},
142
- showRenameControls: { type: Boolean, default: !1 },
143
- renameControlOnClickOutside: { default: "confirm" },
144
- menuItems: { default: () => [
145
- { id: "rename", text: "重命名", icon: ce },
146
- { id: "delete", text: "删除", icon: de }
147
- ] },
148
- menuListGap: { default: 8 }
616
+ messageGroup: {},
617
+ roleConfig: {},
618
+ contentRenderMode: {}
149
619
  },
150
- emits: ["item-click", "item-title-change", "item-action"],
151
- setup(s, { emit: m }) {
152
- const t = s, c = m, h = (i) => {
153
- var f;
154
- const e = typeof ((f = i[0]) == null ? void 0 : f.group);
155
- return e === "string" || e === "symbol";
156
- }, C = I(() => {
157
- const i = t.data;
158
- return h(i) ? i : [{ group: X, items: i }];
159
- }), E = I(() => C.value.length === 0 || C.value.every((i) => i.items.length === 0)), {
160
- editingItem: p,
161
- editorRefList: x,
162
- editorConfirmRefList: y,
163
- editorCancelRefList: M,
164
- editorValue: k,
165
- handleEdit: R,
166
- handleEditCancel: o,
167
- handleEditConfirm: v
168
- } = Te({
169
- renameControlOnClickOutside: t.renameControlOnClickOutside,
170
- onItemTitleChange: (i, e) => {
171
- c("item-title-change", i, e);
172
- }
173
- }), { isTouchDevice: L } = Ce(), g = _(null), u = _(null), K = (i, e) => {
174
- if (i.currentTarget instanceof HTMLButtonElement) {
175
- if (u.value === e) {
176
- g.value = null, u.value = null;
177
- return;
178
- }
179
- g.value = i.currentTarget, u.value = e;
180
- } else
181
- g.value = null, u.value = null;
182
- }, ee = (i) => {
183
- const e = u.value;
184
- e && (i.id === "rename" && R(e), c("item-action", i, e));
620
+ emits: ["state-change"],
621
+ setup(t, { emit: e }) {
622
+ const n = t, s = e;
623
+ return Et(() => n.messageGroup), (c, u) => (f(), k(K, D(t.roleConfig, {
624
+ role: t.messageGroup.role,
625
+ "content-render-mode": t.contentRenderMode,
626
+ onStateChange: u[0] || (u[0] = (o) => s("state-change", o))
627
+ }), {
628
+ prefix: $((o) => [
629
+ R(c.$slots, "prefix", O(P(o)))
630
+ ]),
631
+ suffix: $((o) => [
632
+ R(c.$slots, "suffix", O(P(o)))
633
+ ]),
634
+ "content-footer": $((o) => [
635
+ R(c.$slots, "content-footer", O(P(o)))
636
+ ]),
637
+ after: $((o) => [
638
+ R(c.$slots, "after", O(P(o)))
639
+ ]),
640
+ _: 3
641
+ }, 16, ["role", "content-render-mode"]));
642
+ }
643
+ }), Pt = /* @__PURE__ */ C({
644
+ __name: "BubbleList",
645
+ props: {
646
+ messages: {},
647
+ groupStrategy: { type: [String, Function], default: "divider" },
648
+ dividerRole: { default: "user" },
649
+ fallbackRole: { default: "assistant" },
650
+ roleConfigs: {},
651
+ contentRenderMode: {},
652
+ autoScroll: { type: Boolean }
653
+ },
654
+ emits: ["state-change"],
655
+ setup(t, { expose: e, emit: n }) {
656
+ const s = t, c = n;
657
+ le();
658
+ const u = M(null);
659
+ let o = async () => {
185
660
  };
186
- return (i, e) => (r(), a("div", {
187
- class: U(["tr-history", { "touch-device": n(L) }])
661
+ if (s.autoScroll) {
662
+ const p = v(() => s.messages.at(-1)), { scrollToBottom: _ } = Ot(u, () => {
663
+ var l, i;
664
+ return [
665
+ s.messages.length,
666
+ (l = p.value) == null ? void 0 : l.content,
667
+ (i = p.value) == null ? void 0 : i.reasoning_content
668
+ ];
669
+ });
670
+ o = _, Q(
671
+ () => {
672
+ var l;
673
+ return (l = p.value) == null ? void 0 : l.role;
674
+ },
675
+ async (l) => {
676
+ l === "user" && (await me(), _("smooth"));
677
+ }
678
+ );
679
+ }
680
+ const d = (p) => {
681
+ const _ = [];
682
+ let l = !1;
683
+ for (const [i, b] of p.entries()) {
684
+ const a = _[_.length - 1];
685
+ Array.isArray(b.content) ? (_.push({
686
+ role: b.role || "",
687
+ messages: [b],
688
+ messageIndexes: [i],
689
+ startIndex: i
690
+ }), l = !0) : a && a.role === b.role && !l ? (a.messages.push(b), a.messageIndexes.push(i)) : (_.push({
691
+ role: b.role || "",
692
+ messages: [b],
693
+ messageIndexes: [i],
694
+ startIndex: i
695
+ }), l = !1);
696
+ }
697
+ return _;
698
+ }, h = (p, _) => {
699
+ const l = [];
700
+ let i = !1;
701
+ for (const [b, a] of p.entries()) {
702
+ const r = l[l.length - 1], m = a.role === _;
703
+ Array.isArray(a.content) ? (l.push({
704
+ role: a.role || "",
705
+ messages: [a],
706
+ messageIndexes: [b],
707
+ startIndex: b
708
+ }), i = !0) : r && r.role === _ === m && !i ? (r.messages.push(a), r.messageIndexes.push(b)) : (l.push({
709
+ role: m ? _ : a.role || "",
710
+ messages: [a],
711
+ messageIndexes: [b],
712
+ startIndex: b
713
+ }), i = !1);
714
+ }
715
+ return l;
716
+ }, y = v(() => s.messages.length === 0 ? [] : typeof s.groupStrategy == "function" ? s.groupStrategy(s.messages, s.dividerRole) : s.groupStrategy === "consecutive" ? d(s.messages) : h(s.messages, s.dividerRole));
717
+ return e({
718
+ scrollToBottom: o
719
+ }), (p, _) => (f(), B("div", {
720
+ class: "tr-bubble-list",
721
+ ref_key: "listRef",
722
+ ref: u
188
723
  }, [
189
- E.value ? (r(), H(Re, { key: 1 })) : (r(), a(S, { key: 0 }, [
190
- (r(!0), a(S, null, V(C.value, (f) => (r(), a("div", {
191
- class: "tr-history__group",
192
- key: f.group
193
- }, [
194
- f.group !== n(X) ? (r(), a("div", $e, B(f.group), 1)) : G("", !0),
195
- w("div", be, [
196
- (r(!0), a(S, null, V(f.items, (l, te) => (r(), a("div", {
197
- class: U(["tr-history__item", {
198
- selected: l.id && l.id === t.selected,
199
- editing: n(p) === l,
200
- active: u.value === l
201
- }]),
202
- key: l.id || te,
203
- onClick: (d) => c("item-click", l)
204
- }, [
205
- A(i.$slots, "item-prefix", { item: l }, void 0, !0),
206
- l.icon ? (r(), H(Y(l.icon), { key: 0 })) : G("", !0),
207
- n(p) === l ? q((r(), a("input", {
208
- key: 1,
209
- class: "tr-history__item-editor",
210
- type: "text",
211
- onClick: e[0] || (e[0] = J(() => {
212
- }, ["stop"])),
213
- ref_for: !0,
214
- ref_key: "editorRefList",
215
- ref: x,
216
- "onUpdate:modelValue": e[1] || (e[1] = (d) => le(k) ? k.value = d : null),
217
- onKeydown: [
218
- e[2] || (e[2] = F(
219
- //@ts-ignore
220
- (...d) => n(v) && n(v)(...d),
221
- ["enter"]
222
- )),
223
- e[3] || (e[3] = F(
224
- //@ts-ignore
225
- (...d) => n(o) && n(o)(...d),
226
- ["escape"]
227
- ))
228
- ]
229
- }, null, 544)), [
230
- [re, n(k)]
231
- ]) : A(i.$slots, "item-title", {
232
- key: 2,
233
- item: l
234
- }, () => [
235
- w("span", {
236
- class: "text",
237
- title: l.title
238
- }, B(l.title), 9, Oe)
239
- ], !0),
240
- w("span", {
241
- class: "tr-history__item-actions",
242
- onClick: e[6] || (e[6] = J(() => {
243
- }, ["stop"]))
244
- }, [
245
- t.showRenameControls && n(p) === l ? (r(), a("button", {
246
- key: 0,
247
- class: "editor-confirm",
248
- ref_for: !0,
249
- ref_key: "editorConfirmRefList",
250
- ref: y,
251
- onClick: e[4] || (e[4] = //@ts-ignore
252
- (...d) => n(v) && n(v)(...d))
253
- }, [
254
- $(n(me))
255
- ], 512)) : G("", !0),
256
- t.showRenameControls && n(p) === l ? (r(), a("button", {
257
- key: 1,
258
- class: "editor-cancel",
259
- ref_for: !0,
260
- ref_key: "editorCancelRefList",
261
- ref: M,
262
- onClick: e[5] || (e[5] = //@ts-ignore
263
- (...d) => n(o) && n(o)(...d))
264
- }, [
265
- $(n(fe))
266
- ], 512)) : G("", !0),
267
- w("button", {
268
- class: U(["menu", { hidden: n(p) === l }]),
269
- onClick: (d) => K(d, l)
270
- }, [
271
- $(n(pe))
272
- ], 10, Se)
273
- ])
274
- ], 10, Ge))), 128))
275
- ])
276
- ]))), 128)),
277
- q($(Me, {
278
- trigger: g.value,
279
- "onUpdate:trigger": e[7] || (e[7] = (f) => g.value = f),
280
- data: u.value,
281
- "onUpdate:data": e[8] || (e[8] = (f) => u.value = f),
282
- items: t.menuItems,
283
- "menu-list-gap": t.menuListGap,
284
- onItemClick: ee
285
- }, null, 8, ["trigger", "data", "items", "menu-list-gap"]), [
286
- [ae, g.value]
287
- ])
288
- ], 64))
289
- ], 2));
724
+ (f(!0), B(N, null, J(y.value, (l, i) => {
725
+ var b;
726
+ return f(), k(Dt, {
727
+ key: i,
728
+ role: l.role || s.fallbackRole,
729
+ "role-config": (b = s.roleConfigs) == null ? void 0 : b[l.role || s.fallbackRole],
730
+ "message-group": l,
731
+ "content-render-mode": s.contentRenderMode,
732
+ onStateChange: (a) => c("state-change", { ...a, messageIndex: l.startIndex + a.messageIndex })
733
+ }, {
734
+ prefix: $((a) => [
735
+ R(p.$slots, "prefix", D({ ref_for: !0 }, a, {
736
+ messageIndexes: l.messageIndexes
737
+ }), void 0, !0)
738
+ ]),
739
+ suffix: $((a) => [
740
+ R(p.$slots, "suffix", D({ ref_for: !0 }, a, {
741
+ messageIndexes: l.messageIndexes
742
+ }), void 0, !0)
743
+ ]),
744
+ "content-footer": $((a) => [
745
+ R(p.$slots, "content-footer", D({ ref_for: !0 }, a, {
746
+ messageIndexes: l.messageIndexes
747
+ }), void 0, !0)
748
+ ]),
749
+ after: $((a) => [
750
+ R(p.$slots, "after", D({ ref_for: !0 }, a, {
751
+ messageIndexes: l.messageIndexes
752
+ }), void 0, !0)
753
+ ]),
754
+ _: 2
755
+ }, 1032, ["role", "role-config", "message-group", "content-render-mode", "onStateChange"]);
756
+ }), 128))
757
+ ], 512));
758
+ }
759
+ }), X = /* @__PURE__ */ T(Pt, [["__scopeId", "data-v-12e98779"]]), j = /* @__PURE__ */ C({
760
+ __name: "BubbleProvider",
761
+ props: {
762
+ boxRendererMatches: {},
763
+ contentRendererMatches: {},
764
+ fallbackBoxRenderer: { type: [Object, Function] },
765
+ fallbackContentRenderer: { type: [Object, Function] },
766
+ initialStore: {}
767
+ },
768
+ setup(t) {
769
+ const e = t;
770
+ le(e.initialStore);
771
+ const n = v(() => (e.boxRendererMatches || []).concat(Ae).sort((o, d) => (o.priority ?? 0) - (d.priority ?? 0))), s = v(() => (e.contentRendererMatches || []).concat(Me).sort((o, d) => (o.priority ?? 0) - (d.priority ?? 0))), c = v(() => e.fallbackBoxRenderer || Le), u = v(() => e.fallbackContentRenderer || Te);
772
+ return xt({ boxRendererMatches: n, fallbackBoxRenderer: c }), Ct({ contentRendererMatches: s, fallbackContentRenderer: u }), (o, d) => R(o.$slots, "default");
773
+ }
774
+ }), Ft = ["innerHTML"], Gt = /* @__PURE__ */ C({
775
+ __name: "Markdown",
776
+ props: {
777
+ message: {},
778
+ contentIndex: {}
779
+ },
780
+ setup(t) {
781
+ const e = t, n = v(() => {
782
+ var d;
783
+ return typeof e.message.content == "string" ? e.message.content : (d = e.message.content) == null ? void 0 : d[e.contentIndex ?? 0].text;
784
+ }), s = M(null);
785
+ fe(async () => {
786
+ s.value = await at();
787
+ });
788
+ const { mdConfig: c, dompurifyConfig: u } = ce(), o = M("");
789
+ return W(() => {
790
+ if (s.value) {
791
+ const { markdown: d, dompurify: h } = s.value;
792
+ o.value = d(c || {}).render(String(n.value)), h.sanitize(o.value, u);
793
+ }
794
+ }), (d, h) => o.value ? (f(), B("div", {
795
+ key: 0,
796
+ class: "tr-bubble__markdown markdown-body",
797
+ "data-type": "markdown",
798
+ innerHTML: o.value
799
+ }, null, 8, Ft)) : (f(), k(re, O(D({ key: 1 }, e)), null, 16));
290
800
  }
291
- }), N = /* @__PURE__ */ z(Be, [["__scopeId", "data-v-97a7e8a2"]]), De = function(s) {
292
- s.component(N.name, N);
801
+ }), Kt = /* @__PURE__ */ T(Gt, [["__scopeId", "data-v-a419bf81"]]), Xt = {
802
+ Box: oe,
803
+ Image: Ce,
804
+ Loading: ke,
805
+ Markdown: Kt,
806
+ Reasoning: Ie,
807
+ Text: re,
808
+ Tool: Se,
809
+ ToolRole: Ee,
810
+ Tools: $e
293
811
  };
294
- Object.assign(N, {
295
- name: "TrHistory",
296
- install: De
297
- });
812
+ K.name = "TrBubble";
813
+ const Ut = function(t) {
814
+ t.component(K.name, K);
815
+ };
816
+ K.install = Ut;
817
+ const jt = K;
818
+ X.name = "TrBubbleList";
819
+ const Ht = function(t) {
820
+ t.component(X.name, X);
821
+ };
822
+ X.install = Ht;
823
+ const qt = X;
824
+ j.name = "TrBubbleProvider";
825
+ const Jt = function(t) {
826
+ t.component(j.name, j);
827
+ };
828
+ j.install = Jt;
829
+ const Zt = j;
298
830
  export {
299
- N as H,
300
- Ce as u
831
+ jt as B,
832
+ qt as a,
833
+ Zt as b,
834
+ G as c,
835
+ Xt as d,
836
+ ae as e,
837
+ we as f,
838
+ Ne as g,
839
+ Ot as h,
840
+ Rt as u
301
841
  };