@seer-ai/seer-vue 0.1.0-beta.2 → 0.1.0-beta.4
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/client.d.ts +2 -0
- package/dist/components/SeerChat.vue.d.ts +2 -2
- package/dist/index.css +1 -1
- package/dist/index.js +221 -181
- package/package.json +3 -2
package/dist/client.d.ts
CHANGED
|
@@ -7,8 +7,10 @@ export interface SeerChatMessage {
|
|
|
7
7
|
export interface SeerClientOptions {
|
|
8
8
|
endpoint: string;
|
|
9
9
|
sessionEndpoint?: string;
|
|
10
|
+
challengeTokenProvider?: () => Promise<string>;
|
|
10
11
|
model?: string;
|
|
11
12
|
fetcher?: typeof fetch;
|
|
13
|
+
now?: () => number;
|
|
12
14
|
}
|
|
13
15
|
export interface SeerChatRequest {
|
|
14
16
|
messages: SeerChatMessage[];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { SeerClientOptions } from
|
|
1
|
+
import type { SeerClientOptions } from "../client";
|
|
2
2
|
type __VLS_Props = {
|
|
3
3
|
endpoint?: string;
|
|
4
4
|
model?: string;
|
|
5
5
|
stream?: boolean;
|
|
6
|
-
fetcher?: SeerClientOptions[
|
|
6
|
+
fetcher?: SeerClientOptions["fetcher"];
|
|
7
7
|
title?: string;
|
|
8
8
|
placeholder?: string;
|
|
9
9
|
};
|
package/dist/index.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.seer-chat[data-v-
|
|
1
|
+
.seer-chat[data-v-fefeb009]{display:grid;gap:18px;max-width:720px;min-height:640px;padding:0;overflow:hidden;color:#18212f;background:radial-gradient(circle at 18% 0%,rgba(71,106,255,.14),transparent 32%),linear-gradient(180deg,#fff,#f7f9fd);border:1px solid rgba(127,143,170,.28);border-radius:28px;box-shadow:0 24px 70px #151f3429}.seer-chat__header[data-v-fefeb009]{display:flex;gap:16px;align-items:flex-start;justify-content:space-between;padding:22px 22px 18px;color:#fff;background:linear-gradient(135deg,#141f34f5,#243f76f0),#172033}.seer-chat__header h2[data-v-fefeb009]{margin:0;font-size:22px;letter-spacing:-.03em}.seer-chat__header p[data-v-fefeb009],.seer-chat__empty[data-v-fefeb009],.seer-chat__status[data-v-fefeb009]{margin:4px 0 0;color:#5f6f89;font-size:14px}.seer-chat__header p[data-v-fefeb009]{max-width:34ch;color:#ffffffb8}.seer-chat__messages[data-v-fefeb009]{display:grid;gap:12px;align-content:start;min-height:330px;max-height:470px;padding:18px 18px 4px;overflow-y:auto}.seer-chat__empty[data-v-fefeb009]{display:grid;place-items:center;min-height:260px;padding:0 28px;color:#66748a;text-align:center;border:1px dashed rgba(127,143,170,.38);border-radius:22px;background:#ffffff9e}.seer-chat__message[data-v-fefeb009]{display:grid;gap:6px;max-width:min(86%,520px);padding:13px 15px;border:1px solid rgba(127,143,170,.16);border-radius:18px 18px 18px 6px;background:#ffffffe0;box-shadow:0 12px 28px #151f3414}.seer-chat__message--user[data-v-fefeb009]{justify-self:end;color:#fff;border-color:transparent;border-radius:18px 18px 6px;background:linear-gradient(135deg,#285cff,#1d45c9);box-shadow:0 14px 30px #1f5eff3d}.seer-chat__role[data-v-fefeb009]{font-size:12px;font-weight:700;opacity:.75}.seer-chat__body[data-v-fefeb009]{display:flex;flex-direction:column}.seer-chat__line[data-v-fefeb009]{margin:0;white-space:pre-wrap;overflow-wrap:anywhere}.seer-chat__line[data-v-fefeb009]:not(:last-child){margin-bottom:5px}.seer-chat__line[data-v-fefeb009]:empty{height:7px}.seer-chat__link[data-v-fefeb009]{color:#1f5eff;font-weight:600;text-decoration:underline;text-underline-offset:2px;overflow-wrap:anywhere}.seer-chat__link[data-v-fefeb009]:hover{color:#173fb3}.seer-chat__message--user .seer-chat__link[data-v-fefeb009]{color:#fff}.seer-chat__error[data-v-fefeb009],.seer-chat__handoff[data-v-fefeb009]{margin:0 18px;padding:10px 12px;border-radius:14px}.seer-chat__error[data-v-fefeb009]{color:#8a1f11;background:#fff0ed}.seer-chat__handoff[data-v-fefeb009]{color:#704600;background:#fff7db}.seer-chat__form[data-v-fefeb009]{display:grid;gap:11px;margin:0 18px 18px;padding:14px;background:#fff;border:1px solid rgba(127,143,170,.26);border-radius:22px;box-shadow:0 18px 38px #151f3417}.seer-chat__label[data-v-fefeb009]{font-size:13px;font-weight:700}.seer-chat textarea[data-v-fefeb009]{width:100%;box-sizing:border-box;min-height:92px;padding:14px;color:inherit;line-height:1.55;background:#f8fafd;border:1px solid transparent;border-radius:16px;outline:none;resize:vertical;transition:background .16s ease,border-color .16s ease,box-shadow .16s ease}.seer-chat button[data-v-fefeb009]{color:inherit;font-weight:700;border:0;cursor:pointer;transition:transform .16s ease,box-shadow .16s ease,opacity .16s ease}.seer-chat button[data-v-fefeb009]:not(:disabled):hover{transform:translateY(-1px)}.seer-chat button[data-v-fefeb009]:disabled{cursor:not-allowed;opacity:.5}.seer-chat button[data-v-fefeb009]:focus-visible,.seer-chat textarea[data-v-fefeb009]:focus-visible{border-color:#1f5eff6b;box-shadow:0 0 0 4px #1f5eff21}.seer-chat__clear-button[data-v-fefeb009]{flex:0 0 auto;padding:8px 11px;color:#ffffffc7;font-size:12px;background:transparent;border:1px solid rgba(255,255,255,.18)!important;border-radius:12px}.seer-chat__clear-button[data-v-fefeb009]:not(:disabled):hover{color:#fff;background:#ffffff1a;box-shadow:none}.seer-chat__stop-button[data-v-fefeb009]{padding:8px 11px;color:#6c3b12;font-size:12px;background:#fff1df;border-radius:12px}.seer-chat__send-button[data-v-fefeb009]{display:inline-flex;gap:8px;align-items:center;justify-content:center;min-width:86px;padding:10px 14px;color:#fff;background:linear-gradient(135deg,#1f5eff,#173fb3);border-radius:14px;box-shadow:0 12px 24px #1f5eff38}.seer-chat__send-button[data-v-fefeb009]:not(:disabled):hover{box-shadow:0 14px 28px #1f5eff47}.seer-chat__hint[data-v-fefeb009]{margin-right:auto;color:#7a879a;font-size:12px}.seer-chat__composer-footer[data-v-fefeb009]{display:flex;gap:8px;align-items:center;justify-content:flex-end}
|
package/dist/index.js
CHANGED
|
@@ -1,193 +1,196 @@
|
|
|
1
|
-
import { hasInjectionContext as
|
|
2
|
-
function
|
|
3
|
-
const
|
|
4
|
-
let
|
|
1
|
+
import { hasInjectionContext as $, inject as N, ref as E, defineComponent as q, computed as L, openBlock as v, createElementBlock as m, createElementVNode as f, toDisplayString as T, unref as w, createCommentVNode as x, Fragment as I, renderList as R, normalizeClass as M, withModifiers as O, withDirectives as B, withKeys as K, vModelText as D } from "vue";
|
|
2
|
+
function F(t) {
|
|
3
|
+
const n = t.fetcher ?? fetch, e = t.model ?? "seer", o = t.now ?? (() => Math.floor(Date.now() / 1e3));
|
|
4
|
+
let u, i = 0;
|
|
5
5
|
return {
|
|
6
|
-
async chat(
|
|
7
|
-
const
|
|
6
|
+
async chat(l, d = {}) {
|
|
7
|
+
const a = l.stream ?? !1, s = await p(), r = {
|
|
8
8
|
"Content-Type": "application/json"
|
|
9
9
|
};
|
|
10
|
-
|
|
11
|
-
const
|
|
10
|
+
s && (r.Authorization = `Bearer ${s}`);
|
|
11
|
+
const h = await n(t.endpoint, {
|
|
12
12
|
method: "POST",
|
|
13
|
-
headers:
|
|
14
|
-
signal:
|
|
13
|
+
headers: r,
|
|
14
|
+
signal: d.signal,
|
|
15
15
|
body: JSON.stringify({
|
|
16
|
-
model:
|
|
17
|
-
messages:
|
|
18
|
-
stream:
|
|
19
|
-
conversation_id:
|
|
20
|
-
metadata:
|
|
16
|
+
model: l.model ?? e,
|
|
17
|
+
messages: l.messages,
|
|
18
|
+
stream: a,
|
|
19
|
+
conversation_id: l.conversationId,
|
|
20
|
+
metadata: l.metadata
|
|
21
21
|
})
|
|
22
22
|
});
|
|
23
|
-
if (!
|
|
24
|
-
throw new Error(await
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
27
|
-
const
|
|
28
|
-
return
|
|
23
|
+
if (!h.ok)
|
|
24
|
+
throw new Error(await j(h));
|
|
25
|
+
if (a)
|
|
26
|
+
return U(h, d.onDelta);
|
|
27
|
+
const y = await h.json();
|
|
28
|
+
return A(y);
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
-
async function
|
|
32
|
-
if (!
|
|
31
|
+
async function p() {
|
|
32
|
+
if (!t.sessionEndpoint)
|
|
33
33
|
return;
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
return
|
|
37
|
-
const
|
|
38
|
-
method: "GET"
|
|
34
|
+
const l = o();
|
|
35
|
+
if (u && i - 30 > l)
|
|
36
|
+
return u;
|
|
37
|
+
const d = await n(t.sessionEndpoint, {
|
|
38
|
+
method: "GET",
|
|
39
|
+
headers: await _()
|
|
39
40
|
});
|
|
40
|
-
if (!
|
|
41
|
-
throw new Error(await
|
|
42
|
-
const
|
|
43
|
-
return
|
|
41
|
+
if (!d.ok)
|
|
42
|
+
throw new Error(await j(d));
|
|
43
|
+
const a = await d.json();
|
|
44
|
+
return u = a.token, i = a.expires_at, u;
|
|
45
|
+
}
|
|
46
|
+
async function _() {
|
|
47
|
+
const l = {};
|
|
48
|
+
return t.challengeTokenProvider && (l["X-Seer-Challenge-Token"] = await t.challengeTokenProvider()), l;
|
|
44
49
|
}
|
|
45
50
|
}
|
|
46
|
-
function
|
|
47
|
-
var e,
|
|
48
|
-
const
|
|
51
|
+
function A(t) {
|
|
52
|
+
var e, o, u;
|
|
53
|
+
const n = (e = t.choices) == null ? void 0 : e[0];
|
|
49
54
|
return {
|
|
50
|
-
content: ((
|
|
51
|
-
conversationId:
|
|
52
|
-
citations:
|
|
53
|
-
handoffRequested:
|
|
54
|
-
finishReason:
|
|
55
|
+
content: ((o = n == null ? void 0 : n.message) == null ? void 0 : o.content) ?? ((u = n == null ? void 0 : n.delta) == null ? void 0 : u.content) ?? "",
|
|
56
|
+
conversationId: t.conversation_id,
|
|
57
|
+
citations: t.citations ?? [],
|
|
58
|
+
handoffRequested: t.handoff_requested ?? !1,
|
|
59
|
+
finishReason: n == null ? void 0 : n.finish_reason
|
|
55
60
|
};
|
|
56
61
|
}
|
|
57
|
-
async function
|
|
58
|
-
var
|
|
59
|
-
if (!
|
|
60
|
-
return
|
|
61
|
-
const e =
|
|
62
|
-
let
|
|
62
|
+
async function U(t, n) {
|
|
63
|
+
var a, s, r;
|
|
64
|
+
if (!t.body)
|
|
65
|
+
return A({});
|
|
66
|
+
const e = t.body.getReader(), o = new TextDecoder();
|
|
67
|
+
let u = "", i = "", p, _ = [], l = !1, d;
|
|
63
68
|
for (; ; ) {
|
|
64
|
-
const { done:
|
|
65
|
-
if (
|
|
69
|
+
const { done: h, value: y } = await e.read();
|
|
70
|
+
if (h)
|
|
66
71
|
break;
|
|
67
|
-
|
|
68
|
-
const
|
|
72
|
+
u += o.decode(y, { stream: !0 });
|
|
73
|
+
const g = u.split(`
|
|
69
74
|
|
|
70
75
|
`);
|
|
71
|
-
|
|
72
|
-
for (const
|
|
73
|
-
const
|
|
74
|
-
if (!
|
|
76
|
+
u = g.pop() ?? "";
|
|
77
|
+
for (const k of g) {
|
|
78
|
+
const b = V(k);
|
|
79
|
+
if (!b || b === "[DONE]")
|
|
75
80
|
continue;
|
|
76
|
-
const
|
|
77
|
-
|
|
81
|
+
const S = JSON.parse(b), c = (a = S.choices) == null ? void 0 : a[0], C = ((s = c == null ? void 0 : c.delta) == null ? void 0 : s.content) ?? ((r = c == null ? void 0 : c.message) == null ? void 0 : r.content) ?? "";
|
|
82
|
+
C && (i += C, n == null || n(C)), p = S.conversation_id ?? p, _ = S.citations ?? _, l = S.handoff_requested ?? l, d = (c == null ? void 0 : c.finish_reason) ?? d;
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
return {
|
|
81
|
-
content:
|
|
82
|
-
conversationId:
|
|
83
|
-
citations:
|
|
84
|
-
handoffRequested:
|
|
85
|
-
finishReason:
|
|
86
|
+
content: i,
|
|
87
|
+
conversationId: p,
|
|
88
|
+
citations: _,
|
|
89
|
+
handoffRequested: l,
|
|
90
|
+
finishReason: d
|
|
86
91
|
};
|
|
87
92
|
}
|
|
88
|
-
function
|
|
89
|
-
const
|
|
93
|
+
function V(t) {
|
|
94
|
+
const n = t.split(`
|
|
90
95
|
`).map((e) => e.trim()).filter((e) => e.startsWith("data:")).map((e) => e.slice(5).trim());
|
|
91
|
-
return
|
|
96
|
+
return n.length === 0 ? null : n.join(`
|
|
92
97
|
`);
|
|
93
98
|
}
|
|
94
|
-
async function
|
|
95
|
-
let
|
|
99
|
+
async function j(t) {
|
|
100
|
+
let n = t.statusText || "unknown error";
|
|
96
101
|
try {
|
|
97
|
-
const e = await
|
|
98
|
-
typeof (e == null ? void 0 : e.detail) == "string" ?
|
|
102
|
+
const e = await t.json();
|
|
103
|
+
typeof (e == null ? void 0 : e.detail) == "string" ? n = e.detail : typeof (e == null ? void 0 : e.error) == "string" && (n = e.error);
|
|
99
104
|
} catch {
|
|
100
|
-
const e = await
|
|
101
|
-
e && (
|
|
105
|
+
const e = await t.text().catch(() => "");
|
|
106
|
+
e && (n = e);
|
|
102
107
|
}
|
|
103
|
-
return `seer chat request failed with status ${
|
|
108
|
+
return `seer chat request failed with status ${t.status}: ${n}`;
|
|
104
109
|
}
|
|
105
|
-
const
|
|
106
|
-
install(
|
|
107
|
-
|
|
110
|
+
const P = Symbol("seer-chat-options"), ce = {
|
|
111
|
+
install(t, n) {
|
|
112
|
+
t.provide(P, n);
|
|
108
113
|
}
|
|
109
114
|
};
|
|
110
|
-
function
|
|
111
|
-
const e = {
|
|
115
|
+
function z(t = {}) {
|
|
116
|
+
const e = { ...$() ? N(P, void 0) : void 0, ...t };
|
|
112
117
|
if (!e.endpoint)
|
|
113
118
|
throw new Error("Seer chat endpoint is required. Pass it to app.use() or useSeerChat().");
|
|
114
|
-
const
|
|
119
|
+
const o = {
|
|
115
120
|
endpoint: e.endpoint,
|
|
116
121
|
sessionEndpoint: e.sessionEndpoint,
|
|
122
|
+
challengeTokenProvider: e.challengeTokenProvider,
|
|
117
123
|
model: e.model,
|
|
118
124
|
fetcher: e.fetcher
|
|
119
|
-
},
|
|
120
|
-
let
|
|
121
|
-
async function
|
|
122
|
-
const
|
|
123
|
-
if (!
|
|
125
|
+
}, u = F(o), i = E([]), p = E(!1), _ = E(null), l = E(), d = E([]), a = E(!1);
|
|
126
|
+
let s = null;
|
|
127
|
+
async function r(g) {
|
|
128
|
+
const k = g.trim();
|
|
129
|
+
if (!k || p.value)
|
|
124
130
|
return;
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
e.stream && (
|
|
131
|
+
const b = { role: "user", content: k };
|
|
132
|
+
i.value = [...i.value, b], p.value = !0, _.value = null, s = new AbortController();
|
|
133
|
+
const S = { role: "assistant", content: "" };
|
|
134
|
+
e.stream && (i.value = [...i.value, S]);
|
|
129
135
|
try {
|
|
130
|
-
const
|
|
136
|
+
const c = await u.chat(
|
|
131
137
|
{
|
|
132
|
-
messages:
|
|
138
|
+
messages: i.value.filter((C) => C.content),
|
|
133
139
|
stream: e.stream ?? !1,
|
|
134
|
-
conversationId:
|
|
140
|
+
conversationId: l.value
|
|
135
141
|
},
|
|
136
142
|
{
|
|
137
|
-
signal:
|
|
138
|
-
onDelta(
|
|
139
|
-
|
|
143
|
+
signal: s.signal,
|
|
144
|
+
onDelta(C) {
|
|
145
|
+
S.content += C, i.value = [...i.value];
|
|
140
146
|
}
|
|
141
147
|
}
|
|
142
148
|
);
|
|
143
|
-
e.stream || (
|
|
144
|
-
} catch (
|
|
145
|
-
|
|
149
|
+
e.stream || (i.value = [...i.value, { role: "assistant", content: c.content }]), l.value = c.conversationId, d.value = c.citations, a.value = c.handoffRequested;
|
|
150
|
+
} catch (c) {
|
|
151
|
+
c.name !== "AbortError" && (_.value = c instanceof Error ? c.message : String(c));
|
|
146
152
|
} finally {
|
|
147
|
-
|
|
153
|
+
p.value = !1, s = null;
|
|
148
154
|
}
|
|
149
155
|
}
|
|
150
|
-
function
|
|
151
|
-
|
|
156
|
+
function h() {
|
|
157
|
+
i.value = [], _.value = null, l.value = void 0, d.value = [], a.value = !1;
|
|
152
158
|
}
|
|
153
|
-
function
|
|
154
|
-
|
|
159
|
+
function y() {
|
|
160
|
+
s == null || s.abort();
|
|
155
161
|
}
|
|
156
162
|
return {
|
|
157
|
-
messages:
|
|
158
|
-
loading:
|
|
159
|
-
error:
|
|
160
|
-
conversationId:
|
|
161
|
-
citations:
|
|
162
|
-
handoffRequested:
|
|
163
|
-
send:
|
|
164
|
-
reset:
|
|
165
|
-
abort:
|
|
163
|
+
messages: i,
|
|
164
|
+
loading: p,
|
|
165
|
+
error: _,
|
|
166
|
+
conversationId: l,
|
|
167
|
+
citations: d,
|
|
168
|
+
handoffRequested: a,
|
|
169
|
+
send: r,
|
|
170
|
+
reset: h,
|
|
171
|
+
abort: y
|
|
166
172
|
};
|
|
167
173
|
}
|
|
168
|
-
const
|
|
174
|
+
const J = {
|
|
169
175
|
class: "seer-chat",
|
|
170
176
|
"aria-label": "多发货 AI 客服聊天"
|
|
171
|
-
},
|
|
177
|
+
}, G = { class: "seer-chat__header" }, H = {
|
|
172
178
|
class: "seer-chat__messages",
|
|
173
179
|
"aria-live": "polite"
|
|
174
180
|
}, W = {
|
|
175
181
|
key: 0,
|
|
176
182
|
class: "seer-chat__empty"
|
|
177
|
-
},
|
|
183
|
+
}, X = { class: "seer-chat__role" }, Q = { class: "seer-chat__body" }, Y = ["href"], Z = { key: 1 }, ee = {
|
|
178
184
|
key: 0,
|
|
179
185
|
class: "seer-chat__status"
|
|
180
|
-
},
|
|
186
|
+
}, te = {
|
|
181
187
|
key: 1,
|
|
182
188
|
class: "seer-chat__error",
|
|
183
189
|
role: "alert"
|
|
184
|
-
},
|
|
190
|
+
}, ne = {
|
|
185
191
|
key: 2,
|
|
186
192
|
class: "seer-chat__handoff"
|
|
187
|
-
},
|
|
188
|
-
key: 3,
|
|
189
|
-
class: "seer-chat__citations"
|
|
190
|
-
}, ee = ["placeholder", "disabled"], te = { class: "seer-chat__actions" }, ne = ["disabled"], se = /* @__PURE__ */ M({
|
|
193
|
+
}, se = ["placeholder", "disabled", "onKeydown"], ae = { class: "seer-chat__composer-footer" }, oe = ["disabled"], re = /* @__PURE__ */ q({
|
|
191
194
|
__name: "SeerChat",
|
|
192
195
|
props: {
|
|
193
196
|
endpoint: {},
|
|
@@ -197,91 +200,128 @@ const G = {
|
|
|
197
200
|
title: { default: "多发货 AI 客服" },
|
|
198
201
|
placeholder: { default: "输入你的问题,例如:美国海派怎么报价?" }
|
|
199
202
|
},
|
|
200
|
-
setup(
|
|
201
|
-
const
|
|
202
|
-
endpoint:
|
|
203
|
-
model:
|
|
204
|
-
stream:
|
|
205
|
-
fetcher:
|
|
206
|
-
}),
|
|
207
|
-
|
|
208
|
-
|
|
203
|
+
setup(t) {
|
|
204
|
+
const n = t, e = E(""), o = z({
|
|
205
|
+
endpoint: n.endpoint,
|
|
206
|
+
model: n.model,
|
|
207
|
+
stream: n.stream,
|
|
208
|
+
fetcher: n.fetcher
|
|
209
|
+
}), u = L(
|
|
210
|
+
() => e.value.trim().length > 0 && !o.loading.value
|
|
211
|
+
), i = /https?:\/\/[^\s)]+/g;
|
|
212
|
+
function p(a) {
|
|
213
|
+
return /标签|箱唛/.test(a) ? "点击下载箱唛" : /入库单|交接单/.test(a) ? "点击下载入库单" : /面单/.test(a) ? "点击下载面单" : /截图/.test(a) ? "点击查看报价截图" : /下载链接|labelUrl|下载/.test(a) ? "点击下载" : /链接/.test(a) ? "点击查看" : null;
|
|
214
|
+
}
|
|
215
|
+
function _(a) {
|
|
216
|
+
const s = [];
|
|
217
|
+
i.lastIndex = 0;
|
|
218
|
+
let r = 0, h;
|
|
219
|
+
for (; (h = i.exec(a)) !== null; ) {
|
|
220
|
+
const y = h[0], g = h.index;
|
|
221
|
+
g > r && s.push({ kind: "text", value: a.slice(r, g) });
|
|
222
|
+
const k = a.lastIndexOf(`
|
|
223
|
+
`, g - 1) + 1, b = p(a.slice(k, g)) ?? y;
|
|
224
|
+
s.push({ kind: "link", href: y, label: b }), r = g + y.length;
|
|
225
|
+
}
|
|
226
|
+
return r < a.length && s.push({ kind: "text", value: a.slice(r) }), s;
|
|
227
|
+
}
|
|
228
|
+
function l(a) {
|
|
229
|
+
return a.split(`
|
|
230
|
+
`).map((s) => _(s));
|
|
231
|
+
}
|
|
232
|
+
async function d() {
|
|
233
|
+
if (!u.value)
|
|
209
234
|
return;
|
|
210
|
-
const
|
|
211
|
-
e.value = "", await
|
|
235
|
+
const a = e.value;
|
|
236
|
+
e.value = "", await o.send(a);
|
|
212
237
|
}
|
|
213
|
-
return (
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
238
|
+
return (a, s) => (v(), m("section", J, [
|
|
239
|
+
f("header", G, [
|
|
240
|
+
f("div", null, [
|
|
241
|
+
f("h2", null, T(t.title), 1),
|
|
242
|
+
s[3] || (s[3] = f("p", null, "可咨询渠道报价、时效、下单资料、入仓和售后问题。", -1))
|
|
218
243
|
]),
|
|
219
|
-
|
|
244
|
+
f("button", {
|
|
220
245
|
type: "button",
|
|
221
|
-
class: "seer-
|
|
222
|
-
onClick:
|
|
223
|
-
}, "
|
|
246
|
+
class: "seer-chat__clear-button",
|
|
247
|
+
onClick: s[0] || (s[0] = (r) => w(o).reset())
|
|
248
|
+
}, " 清空对话 ")
|
|
224
249
|
]),
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
(
|
|
228
|
-
key: `${
|
|
229
|
-
class:
|
|
250
|
+
f("div", H, [
|
|
251
|
+
w(o).messages.value.length === 0 ? (v(), m("p", W, " 直接输入问题即可,复杂查单或赔付问题会提示转人工。 ")) : x("", !0),
|
|
252
|
+
(v(!0), m(I, null, R(w(o).messages.value, (r, h) => (v(), m("article", {
|
|
253
|
+
key: `${r.role}-${h}`,
|
|
254
|
+
class: M(["seer-chat__message", `seer-chat__message--${r.role}`])
|
|
230
255
|
}, [
|
|
231
|
-
|
|
232
|
-
|
|
256
|
+
f("span", X, T(r.role === "user" ? "你" : "AI 客服"), 1),
|
|
257
|
+
f("div", Q, [
|
|
258
|
+
(v(!0), m(I, null, R(l(r.content), (y, g) => (v(), m("p", {
|
|
259
|
+
key: g,
|
|
260
|
+
class: "seer-chat__line"
|
|
261
|
+
}, [
|
|
262
|
+
(v(!0), m(I, null, R(y, (k, b) => (v(), m(I, { key: b }, [
|
|
263
|
+
k.kind === "link" ? (v(), m("a", {
|
|
264
|
+
key: 0,
|
|
265
|
+
class: "seer-chat__link",
|
|
266
|
+
href: k.href,
|
|
267
|
+
target: "_blank",
|
|
268
|
+
rel: "noopener noreferrer"
|
|
269
|
+
}, T(k.label), 9, Y)) : (v(), m("span", Z, T(k.value), 1))
|
|
270
|
+
], 64))), 128))
|
|
271
|
+
]))), 128))
|
|
272
|
+
])
|
|
233
273
|
], 2))), 128))
|
|
234
274
|
]),
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
a[4] || (a[4] = u("span", null, "参考资料", -1)),
|
|
240
|
-
u("ul", null, [
|
|
241
|
-
(m(!0), v(j, null, O(h(s).citations.value, (o) => (m(), v("li", { key: o }, S(o), 1))), 128))
|
|
242
|
-
])
|
|
243
|
-
])) : b("", !0),
|
|
244
|
-
u("form", {
|
|
275
|
+
w(o).loading.value ? (v(), m("p", ee, "正在回复...")) : x("", !0),
|
|
276
|
+
w(o).error.value ? (v(), m("p", te, T(w(o).error.value), 1)) : x("", !0),
|
|
277
|
+
w(o).handoffRequested.value ? (v(), m("p", ne, " 建议转人工:请留下联系方式或等待客服接入。 ")) : x("", !0),
|
|
278
|
+
f("form", {
|
|
245
279
|
class: "seer-chat__form",
|
|
246
|
-
onSubmit:
|
|
280
|
+
onSubmit: O(d, ["prevent"])
|
|
247
281
|
}, [
|
|
248
|
-
|
|
282
|
+
s[6] || (s[6] = f("label", {
|
|
249
283
|
class: "seer-chat__label",
|
|
250
284
|
for: "seer-chat-input"
|
|
251
285
|
}, "问题", -1)),
|
|
252
|
-
|
|
286
|
+
B(f("textarea", {
|
|
253
287
|
id: "seer-chat-input",
|
|
254
|
-
"onUpdate:modelValue":
|
|
255
|
-
placeholder:
|
|
256
|
-
disabled:
|
|
257
|
-
rows: "3"
|
|
258
|
-
|
|
259
|
-
|
|
288
|
+
"onUpdate:modelValue": s[1] || (s[1] = (r) => e.value = r),
|
|
289
|
+
placeholder: t.placeholder,
|
|
290
|
+
disabled: w(o).loading.value,
|
|
291
|
+
rows: "3",
|
|
292
|
+
onKeydown: K(O(d, ["exact", "prevent"]), ["enter"])
|
|
293
|
+
}, null, 40, se), [
|
|
294
|
+
[D, e.value]
|
|
260
295
|
]),
|
|
261
|
-
|
|
262
|
-
|
|
296
|
+
f("div", ae, [
|
|
297
|
+
s[5] || (s[5] = f("span", { class: "seer-chat__hint" }, "Enter 发送 · Shift+Enter 换行", -1)),
|
|
298
|
+
w(o).loading.value ? (v(), m("button", {
|
|
263
299
|
key: 0,
|
|
264
300
|
type: "button",
|
|
265
|
-
class: "seer-
|
|
266
|
-
onClick:
|
|
267
|
-
}, " 停止 ")) :
|
|
268
|
-
|
|
301
|
+
class: "seer-chat__stop-button",
|
|
302
|
+
onClick: s[2] || (s[2] = (r) => w(o).abort())
|
|
303
|
+
}, " 停止 ")) : x("", !0),
|
|
304
|
+
f("button", {
|
|
305
|
+
class: "seer-chat__send-button",
|
|
269
306
|
type: "submit",
|
|
270
|
-
disabled: !
|
|
271
|
-
},
|
|
307
|
+
disabled: !u.value
|
|
308
|
+
}, [...s[4] || (s[4] = [
|
|
309
|
+
f("span", null, "发送", -1),
|
|
310
|
+
f("span", { "aria-hidden": "true" }, "↵", -1)
|
|
311
|
+
])], 8, oe)
|
|
272
312
|
])
|
|
273
313
|
], 32)
|
|
274
314
|
]));
|
|
275
315
|
}
|
|
276
|
-
}),
|
|
277
|
-
const e =
|
|
278
|
-
for (const [
|
|
279
|
-
e[
|
|
316
|
+
}), le = (t, n) => {
|
|
317
|
+
const e = t.__vccOpts || t;
|
|
318
|
+
for (const [o, u] of n)
|
|
319
|
+
e[o] = u;
|
|
280
320
|
return e;
|
|
281
|
-
},
|
|
321
|
+
}, ue = /* @__PURE__ */ le(re, [["__scopeId", "data-v-fefeb009"]]);
|
|
282
322
|
export {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
323
|
+
ue as SeerChat,
|
|
324
|
+
ce as SeerChatPlugin,
|
|
325
|
+
F as createSeerClient,
|
|
326
|
+
z as useSeerChat
|
|
287
327
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seer-ai/seer-vue",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.4",
|
|
4
4
|
"description": "Vue chat plugin for the seer OpenAI-compatible API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"test": "vitest run",
|
|
24
24
|
"typecheck": "vue-tsc --noEmit",
|
|
25
|
-
"build": "vite build && vue-tsc -p tsconfig.build.json --declaration --emitDeclarationOnly --outDir dist"
|
|
25
|
+
"build": "vite build && vue-tsc -p tsconfig.build.json --declaration --emitDeclarationOnly --outDir dist",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
26
27
|
},
|
|
27
28
|
"peerDependencies": {
|
|
28
29
|
"vue": "^3.5.0"
|