react-docs-ui 0.6.11 → 0.6.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.
@@ -0,0 +1,1171 @@
1
+ import { u as ee, j as e, c as x, aC as ie, aj as J, aD as le, am as se, a9 as ce, an as de, al as ue, ax as me, aB as xe } from "./DocsApp-CEu0IOyd.js";
2
+ import Q, { useState as d, useRef as D, useCallback as S, useEffect as _ } from "react";
3
+ import { Bot as $, User as ge, X as G, CheckCheck as pe, CheckCircle as he, Copy as re, Loader2 as X, AlertCircle as fe, Check as oe, RefreshCw as ve, Pencil as be, Trash2 as te, Square as je, Send as ye, AlertTriangle as Ne, GripVertical as we, Settings as ke, Plus as ne, Star as Ce, ExternalLink as Pe, EyeOff as Ie, Eye as Ee, Info as Se, Save as Ae } from "lucide-react";
4
+ import Te from "react-markdown";
5
+ import Me from "remark-gfm";
6
+ function ze(r, p) {
7
+ const n = D(null);
8
+ return S((...m) => {
9
+ n.current && clearTimeout(n.current), n.current = setTimeout(() => r(...m), p);
10
+ }, [r, p]);
11
+ }
12
+ function $e() {
13
+ const { openDialog: r, isConfigured: p, isDialogOpen: n, openSettings: m } = ee(), [i, u] = d(""), [I, o] = d(!1), [k, E] = d(!1), [l, T] = d({ top: 0, left: 0 }), h = D(null), M = D(null), N = S(() => {
14
+ if (n) {
15
+ o(!1);
16
+ return;
17
+ }
18
+ const v = window.getSelection(), w = v?.toString().trim() || "";
19
+ if (w.length < 5) {
20
+ u(""), o(!1);
21
+ return;
22
+ }
23
+ if (u(w), v && v.rangeCount > 0) {
24
+ const c = v.getRangeAt(0).getBoundingClientRect(), a = c.bottom + window.scrollY + 8, j = c.right + window.scrollX - 40;
25
+ T({ top: a, left: j }), E(!0), o(!0);
26
+ }
27
+ }, [n]), b = ze(N, 150);
28
+ _(() => {
29
+ let v = !1;
30
+ const w = () => {
31
+ v = !0, h.current && (clearTimeout(h.current), h.current = null);
32
+ }, C = () => {
33
+ v = !1, setTimeout(() => {
34
+ N();
35
+ }, 10);
36
+ }, c = () => {
37
+ v || b();
38
+ }, a = (j) => {
39
+ M.current && !M.current.contains(j.target) && (h.current = setTimeout(() => {
40
+ o(!1);
41
+ }, 200));
42
+ };
43
+ return document.addEventListener("mousedown", w), document.addEventListener("mouseup", C), document.addEventListener("selectionchange", c), document.addEventListener("click", a), () => {
44
+ document.removeEventListener("mousedown", w), document.removeEventListener("mouseup", C), document.removeEventListener("selectionchange", c), document.removeEventListener("click", a), h.current && clearTimeout(h.current);
45
+ };
46
+ }, [N, b]);
47
+ const L = S(() => {
48
+ if (i) {
49
+ if (!p) {
50
+ m();
51
+ return;
52
+ }
53
+ r({
54
+ selectedText: i,
55
+ pageTitle: document.title,
56
+ pageUrl: window.location.href
57
+ }), window.getSelection()?.removeAllRanges(), o(!1), u("");
58
+ }
59
+ }, [i, p, r, m]);
60
+ return !I || n ? null : /* @__PURE__ */ e.jsx(
61
+ "button",
62
+ {
63
+ ref: M,
64
+ onClick: L,
65
+ className: x(
66
+ "fixed z-50 flex items-center justify-center w-10 h-10 rounded-full",
67
+ "bg-primary text-primary-foreground shadow-lg",
68
+ "hover:bg-primary/90 transition-all duration-200 hover:scale-110",
69
+ k && "animate-in zoom-in-50 duration-200"
70
+ ),
71
+ style: {
72
+ top: l.top,
73
+ left: l.left
74
+ },
75
+ title: "向AI询问选中内容",
76
+ children: /* @__PURE__ */ e.jsx($, { className: "w-5 h-5" })
77
+ }
78
+ );
79
+ }
80
+ function De({ message: r, onRegenerate: p, onEdit: n, onDelete: m }) {
81
+ const [i, u] = d(!1), [I, o] = d(null), [k, E] = d(!1), [l, T] = d(r.content), h = r.role === "user", M = r.isStreaming, N = !!r.error, b = S(async (c) => {
82
+ if (navigator.clipboard && window.isSecureContext)
83
+ await navigator.clipboard.writeText(c);
84
+ else {
85
+ const a = document.createElement("textarea");
86
+ a.value = c, a.style.position = "fixed", a.style.left = "-9999px", a.style.top = "-9999px", document.body.appendChild(a), a.focus(), a.select();
87
+ try {
88
+ document.execCommand("copy");
89
+ } finally {
90
+ document.body.removeChild(a);
91
+ }
92
+ }
93
+ }, []), L = S(async () => {
94
+ try {
95
+ await b(r.content), u(!0), setTimeout(() => u(!1), 2e3);
96
+ } catch {
97
+ console.error("Failed to copy message");
98
+ }
99
+ }, [r.content, b]), v = S(async (c, a) => {
100
+ a.stopPropagation();
101
+ try {
102
+ await b(c), o(c), setTimeout(() => o(null), 2e3);
103
+ } catch {
104
+ console.error("Failed to copy code");
105
+ }
106
+ }, [b]), w = S(() => {
107
+ l.trim() && l !== r.content && n?.(l.trim()), E(!1);
108
+ }, [l, r.content, n]), C = S(() => {
109
+ T(r.content), E(!1);
110
+ }, [r.content]);
111
+ return /* @__PURE__ */ e.jsxs(
112
+ "div",
113
+ {
114
+ className: x(
115
+ "flex gap-3 p-4 group",
116
+ h ? "flex-row-reverse" : "flex-row"
117
+ ),
118
+ children: [
119
+ /* @__PURE__ */ e.jsx(
120
+ "div",
121
+ {
122
+ className: x(
123
+ "flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center",
124
+ h ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"
125
+ ),
126
+ children: h ? /* @__PURE__ */ e.jsx(ge, { className: "w-4 h-4" }) : /* @__PURE__ */ e.jsx($, { className: "w-4 h-4" })
127
+ }
128
+ ),
129
+ /* @__PURE__ */ e.jsx(
130
+ "div",
131
+ {
132
+ className: x(
133
+ "flex-1 min-w-0",
134
+ h ? "text-right" : "text-left"
135
+ ),
136
+ children: k ? /* @__PURE__ */ e.jsxs("div", { className: "inline-block max-w-full", children: [
137
+ /* @__PURE__ */ e.jsx(
138
+ "textarea",
139
+ {
140
+ value: l,
141
+ onChange: (c) => T(c.target.value),
142
+ className: x(
143
+ "w-full min-w-[200px] max-w-[400px] p-3 rounded-lg border",
144
+ "bg-background text-sm resize-none",
145
+ "focus:outline-none focus:ring-2 focus:ring-ring"
146
+ ),
147
+ rows: Math.min(10, l.split(`
148
+ `).length + 1),
149
+ autoFocus: !0
150
+ }
151
+ ),
152
+ /* @__PURE__ */ e.jsxs("div", { className: "flex justify-end gap-2 mt-2", children: [
153
+ /* @__PURE__ */ e.jsx(
154
+ "button",
155
+ {
156
+ onClick: C,
157
+ className: "p-1.5 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
158
+ title: "取消",
159
+ children: /* @__PURE__ */ e.jsx(G, { className: "w-4 h-4" })
160
+ }
161
+ ),
162
+ /* @__PURE__ */ e.jsx(
163
+ "button",
164
+ {
165
+ onClick: w,
166
+ className: "p-1.5 rounded text-primary hover:bg-primary/10 transition-colors",
167
+ title: "保存",
168
+ children: /* @__PURE__ */ e.jsx(pe, { className: "w-4 h-4" })
169
+ }
170
+ )
171
+ ] })
172
+ ] }) : /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
173
+ /* @__PURE__ */ e.jsxs(
174
+ "div",
175
+ {
176
+ className: x(
177
+ "inline-block max-w-full rounded-lg px-4 py-2",
178
+ h ? "bg-primary text-primary-foreground" : "bg-muted text-foreground",
179
+ N && "border border-destructive"
180
+ ),
181
+ children: [
182
+ r.content ? /* @__PURE__ */ e.jsx(
183
+ Te,
184
+ {
185
+ remarkPlugins: [Me],
186
+ components: {
187
+ pre: ({ children: c }) => {
188
+ const a = (g) => {
189
+ if (typeof g == "string") return g;
190
+ if (Array.isArray(g)) return g.map(a).join("");
191
+ if (Q.isValidElement(g)) {
192
+ const A = g.props;
193
+ if (A.children)
194
+ return a(A.children);
195
+ }
196
+ return "";
197
+ }, j = Q.Children.toArray(c).find(
198
+ (g) => Q.isValidElement(g) && g.type === "code"
199
+ ), y = j && Q.isValidElement(j) ? a(j.props.children).replace(/\n$/, "") : "";
200
+ return /* @__PURE__ */ e.jsxs("div", { className: "relative my-3 rounded-lg overflow-hidden border dark:border-zinc-700 border-zinc-200 dark:bg-[#141414] bg-[#fafafa]", children: [
201
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center justify-between px-4 py-2 border-b dark:border-zinc-700 border-zinc-200 dark:bg-[#1a1a1a] bg-zinc-100", children: [
202
+ /* @__PURE__ */ e.jsx("span", { className: "text-xs dark:text-zinc-400 text-zinc-500", children: "代码" }),
203
+ y && /* @__PURE__ */ e.jsx(
204
+ "button",
205
+ {
206
+ type: "button",
207
+ onClick: (g) => v(y, g),
208
+ className: "flex items-center gap-1 px-2 py-1 text-xs rounded dark:bg-zinc-700 dark:hover:bg-zinc-600 dark:text-zinc-300 bg-zinc-200 hover:bg-zinc-300 text-zinc-600 transition-colors",
209
+ children: I === y ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
210
+ /* @__PURE__ */ e.jsx(he, { className: "w-3.5 h-3.5 text-green-500" }),
211
+ "已复制"
212
+ ] }) : /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
213
+ /* @__PURE__ */ e.jsx(re, { className: "w-3.5 h-3.5" }),
214
+ "复制"
215
+ ] })
216
+ }
217
+ )
218
+ ] }),
219
+ /* @__PURE__ */ e.jsx("pre", { className: "!m-0 p-4 overflow-x-auto text-sm hljs", children: c })
220
+ ] });
221
+ },
222
+ code: ({ className: c, children: a, ...j }) => /language-(\w+)/.exec(c || "") || c?.includes("hljs") ? /* @__PURE__ */ e.jsx("code", { className: x(c, "block"), ...j, children: a }) : !c && String(a).includes(`
223
+ `) ? /* @__PURE__ */ e.jsx("code", { className: "block", ...j, children: a }) : /* @__PURE__ */ e.jsx("code", { className: "px-1.5 py-0.5 rounded dark:bg-zinc-700 bg-zinc-200 text-sm", ...j, children: a })
224
+ },
225
+ children: r.content
226
+ }
227
+ ) : M ? /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
228
+ /* @__PURE__ */ e.jsx(X, { className: "w-4 h-4 animate-spin" }),
229
+ /* @__PURE__ */ e.jsx("span", { children: "正在思考..." })
230
+ ] }) : null,
231
+ N && /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-2 text-destructive mt-2", children: [
232
+ /* @__PURE__ */ e.jsx(fe, { className: "w-4 h-4" }),
233
+ /* @__PURE__ */ e.jsx("span", { className: "text-sm", children: r.error })
234
+ ] })
235
+ ]
236
+ }
237
+ ),
238
+ !M && /* @__PURE__ */ e.jsxs("div", { className: x(
239
+ "flex items-center gap-2 mt-2 opacity-0 group-hover:opacity-100 transition-opacity",
240
+ h ? "justify-end" : "justify-start"
241
+ ), children: [
242
+ !h && r.content && /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
243
+ /* @__PURE__ */ e.jsx(
244
+ "button",
245
+ {
246
+ onClick: L,
247
+ className: "p-1.5 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
248
+ title: "复制",
249
+ children: i ? /* @__PURE__ */ e.jsx(oe, { className: "w-3.5 h-3.5 text-green-500" }) : /* @__PURE__ */ e.jsx(re, { className: "w-3.5 h-3.5" })
250
+ }
251
+ ),
252
+ p && /* @__PURE__ */ e.jsx(
253
+ "button",
254
+ {
255
+ onClick: p,
256
+ className: "p-1.5 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
257
+ title: "重新生成",
258
+ children: /* @__PURE__ */ e.jsx(ve, { className: "w-3.5 h-3.5" })
259
+ }
260
+ )
261
+ ] }),
262
+ h && n && /* @__PURE__ */ e.jsx(
263
+ "button",
264
+ {
265
+ onClick: () => E(!0),
266
+ className: "p-1.5 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
267
+ title: "编辑",
268
+ children: /* @__PURE__ */ e.jsx(be, { className: "w-3.5 h-3.5" })
269
+ }
270
+ ),
271
+ m && /* @__PURE__ */ e.jsx(
272
+ "button",
273
+ {
274
+ onClick: m,
275
+ className: "p-1.5 rounded text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors",
276
+ title: "删除",
277
+ children: /* @__PURE__ */ e.jsx(te, { className: "w-3.5 h-3.5" })
278
+ }
279
+ )
280
+ ] })
281
+ ] })
282
+ }
283
+ )
284
+ ]
285
+ }
286
+ );
287
+ }
288
+ function Re({
289
+ onSend: r,
290
+ onStop: p,
291
+ isLoading: n = !1,
292
+ disabled: m = !1,
293
+ placeholder: i = "输入消息..."
294
+ }) {
295
+ const [u, I] = d(""), o = D(null);
296
+ _(() => {
297
+ const l = o.current;
298
+ l && (l.style.height = "auto", l.style.height = `${Math.min(l.scrollHeight, 150)}px`);
299
+ }, [u]);
300
+ const k = () => {
301
+ const l = u.trim();
302
+ !l || n || m || (r(l), I(""), o.current && (o.current.style.height = "auto"));
303
+ }, E = (l) => {
304
+ l.key === "Enter" && !l.shiftKey && (l.preventDefault(), k());
305
+ };
306
+ return /* @__PURE__ */ e.jsxs("div", { className: "flex items-end gap-2 p-4 border-t bg-background", children: [
307
+ /* @__PURE__ */ e.jsx("div", { className: "flex-1 relative", children: /* @__PURE__ */ e.jsx(
308
+ "textarea",
309
+ {
310
+ ref: o,
311
+ value: u,
312
+ onChange: (l) => I(l.target.value),
313
+ onKeyDown: E,
314
+ placeholder: i,
315
+ disabled: m,
316
+ rows: 1,
317
+ className: x(
318
+ "w-full resize-none rounded-lg border bg-background px-4 py-2.5",
319
+ "text-sm placeholder:text-muted-foreground",
320
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
321
+ "disabled:cursor-not-allowed disabled:opacity-50",
322
+ "min-h-[40px] max-h-[150px]"
323
+ ),
324
+ style: {
325
+ height: "40px"
326
+ }
327
+ }
328
+ ) }),
329
+ n ? /* @__PURE__ */ e.jsx(
330
+ "button",
331
+ {
332
+ onClick: p,
333
+ className: x(
334
+ "flex-shrink-0 w-10 h-10 rounded-lg",
335
+ "flex items-center justify-center",
336
+ "bg-destructive text-destructive-foreground",
337
+ "hover:bg-destructive/90 transition-colors"
338
+ ),
339
+ title: "停止生成",
340
+ children: /* @__PURE__ */ e.jsx(je, { className: "w-4 h-4" })
341
+ }
342
+ ) : /* @__PURE__ */ e.jsx(
343
+ "button",
344
+ {
345
+ onClick: k,
346
+ disabled: !u.trim() || m,
347
+ className: x(
348
+ "flex-shrink-0 w-10 h-10 rounded-lg",
349
+ "flex items-center justify-center",
350
+ "bg-primary text-primary-foreground",
351
+ "hover:bg-primary/90 transition-colors",
352
+ "disabled:opacity-50 disabled:cursor-not-allowed"
353
+ ),
354
+ title: "发送消息",
355
+ children: /* @__PURE__ */ e.jsx(ye, { className: "w-4 h-4" })
356
+ }
357
+ )
358
+ ] });
359
+ }
360
+ const Le = 300, Fe = 700, Be = 500;
361
+ function Ge() {
362
+ const {
363
+ isDialogOpen: r,
364
+ closeDialog: p,
365
+ openSettings: n,
366
+ messages: m,
367
+ isLoading: i,
368
+ error: u,
369
+ isConfigured: I,
370
+ selectedText: o,
371
+ sendMessage: k,
372
+ regenerateLast: E,
373
+ clearHistory: l,
374
+ stopGeneration: T,
375
+ editMessage: h,
376
+ deleteMessage: M
377
+ } = ee(), N = D(null), b = D(null), L = D(null), v = D(null), w = D(!0), [C, c] = d(Be), [a, j] = d(!1), [y, g] = d({ x: 0, y: 0 }), [A, B] = d(!1), H = D({ x: 0, y: 0, posX: 0, posY: 0 }), O = S((s = "smooth") => {
378
+ N.current && N.current.scrollIntoView({ behavior: s });
379
+ }, []), W = S(() => {
380
+ const s = b.current;
381
+ if (!s) return;
382
+ const { scrollTop: P, scrollHeight: z, clientHeight: R } = s, F = z - P - R < 100;
383
+ w.current = F;
384
+ }, []);
385
+ _(() => {
386
+ if (w.current && N.current) {
387
+ const P = m[m.length - 1]?.isStreaming;
388
+ O(P ? "auto" : "smooth");
389
+ }
390
+ }, [m, O]), _(() => {
391
+ const s = (P) => {
392
+ P.key === "Escape" && r && p();
393
+ };
394
+ return document.addEventListener("keydown", s), () => document.removeEventListener("keydown", s);
395
+ }, [r, p]);
396
+ const K = S((s) => {
397
+ s.preventDefault(), j(!0);
398
+ const P = s.clientY, z = C, R = (Y) => {
399
+ const V = P - Y.clientY, q = Math.min(Fe, Math.max(Le, z + V));
400
+ c(q);
401
+ }, F = () => {
402
+ j(!1), document.removeEventListener("mousemove", R), document.removeEventListener("mouseup", F);
403
+ };
404
+ document.addEventListener("mousemove", R), document.addEventListener("mouseup", F);
405
+ }, [C]), U = S((s) => {
406
+ if (s.target.closest("button")) return;
407
+ s.preventDefault(), B(!0), H.current = {
408
+ x: s.clientX,
409
+ y: s.clientY,
410
+ posX: y.x,
411
+ posY: y.y
412
+ };
413
+ const P = (R) => {
414
+ const F = R.clientX - H.current.x, Y = R.clientY - H.current.y;
415
+ g({
416
+ x: H.current.posX + F,
417
+ y: H.current.posY + Y
418
+ });
419
+ }, z = () => {
420
+ B(!1), document.removeEventListener("mousemove", P), document.removeEventListener("mouseup", z);
421
+ };
422
+ document.addEventListener("mousemove", P), document.addEventListener("mouseup", z);
423
+ }, [y]), Z = S(() => {
424
+ g({ x: 0, y: 0 });
425
+ }, []);
426
+ return !I && r ? /* @__PURE__ */ e.jsx("div", { className: "fixed inset-x-4 bottom-4 z-50 mx-auto max-w-2xl", children: /* @__PURE__ */ e.jsxs(
427
+ "div",
428
+ {
429
+ className: x(
430
+ "bg-background border rounded-xl shadow-2xl",
431
+ "animate-in slide-in-from-bottom-4 duration-300"
432
+ ),
433
+ children: [
434
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center justify-between p-4 border-b", children: [
435
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-2", children: [
436
+ /* @__PURE__ */ e.jsx($, { className: "w-5 h-5 text-primary" }),
437
+ /* @__PURE__ */ e.jsx("h3", { className: "font-semibold", children: "AI 助手" })
438
+ ] }),
439
+ /* @__PURE__ */ e.jsx(
440
+ "button",
441
+ {
442
+ onClick: p,
443
+ className: "p-1.5 rounded hover:bg-muted transition-colors",
444
+ children: /* @__PURE__ */ e.jsx(G, { className: "w-4 h-4" })
445
+ }
446
+ )
447
+ ] }),
448
+ /* @__PURE__ */ e.jsxs("div", { className: "p-6 text-center", children: [
449
+ /* @__PURE__ */ e.jsx(Ne, { className: "w-12 h-12 mx-auto text-muted-foreground mb-4" }),
450
+ /* @__PURE__ */ e.jsx("h4", { className: "text-lg font-medium mb-2", children: "需要配置 AI" }),
451
+ /* @__PURE__ */ e.jsx("p", { className: "text-muted-foreground mb-4", children: "请先配置 AI 提供商和 API 密钥才能使用此功能" }),
452
+ /* @__PURE__ */ e.jsx(
453
+ "button",
454
+ {
455
+ onClick: () => {
456
+ p(), n();
457
+ },
458
+ className: "px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors",
459
+ children: "前往设置"
460
+ }
461
+ )
462
+ ] })
463
+ ]
464
+ }
465
+ ) }) : r ? /* @__PURE__ */ e.jsx(
466
+ "div",
467
+ {
468
+ className: "fixed inset-x-4 bottom-4 z-50 mx-auto max-w-2xl",
469
+ style: {
470
+ transform: `translate(${y.x}px, ${y.y}px)`
471
+ },
472
+ children: /* @__PURE__ */ e.jsxs(
473
+ "div",
474
+ {
475
+ ref: L,
476
+ className: x(
477
+ "bg-background border rounded-xl shadow-2xl overflow-hidden",
478
+ "animate-in slide-in-from-bottom-4 duration-300",
479
+ "flex flex-col",
480
+ A && "cursor-grabbing",
481
+ a && "cursor-ns-resize"
482
+ ),
483
+ style: { height: `${C}px`, maxHeight: "70vh" },
484
+ children: [
485
+ /* @__PURE__ */ e.jsxs(
486
+ "div",
487
+ {
488
+ className: "flex items-center justify-between p-4 border-b shrink-0 cursor-grab active:cursor-grabbing",
489
+ onMouseDown: U,
490
+ children: [
491
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-2", children: [
492
+ /* @__PURE__ */ e.jsx(we, { className: "w-4 h-4 text-muted-foreground" }),
493
+ /* @__PURE__ */ e.jsx($, { className: "w-5 h-5 text-primary" }),
494
+ /* @__PURE__ */ e.jsx("h3", { className: "font-semibold", children: "AI 助手" })
495
+ ] }),
496
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-1", children: [
497
+ y.x !== 0 || y.y !== 0 ? /* @__PURE__ */ e.jsx(
498
+ "button",
499
+ {
500
+ onClick: Z,
501
+ className: "p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground",
502
+ title: "重置位置",
503
+ children: /* @__PURE__ */ e.jsx(G, { className: "w-3 h-3" })
504
+ }
505
+ ) : null,
506
+ m.length > 0 && /* @__PURE__ */ e.jsx(
507
+ "button",
508
+ {
509
+ onClick: l,
510
+ className: "p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground",
511
+ title: "清除对话",
512
+ children: /* @__PURE__ */ e.jsx(te, { className: "w-4 h-4" })
513
+ }
514
+ ),
515
+ /* @__PURE__ */ e.jsx(
516
+ "button",
517
+ {
518
+ onClick: n,
519
+ className: "p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground",
520
+ title: "设置",
521
+ children: /* @__PURE__ */ e.jsx(ke, { className: "w-4 h-4" })
522
+ }
523
+ ),
524
+ /* @__PURE__ */ e.jsx(
525
+ "button",
526
+ {
527
+ onClick: p,
528
+ className: "p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground",
529
+ title: "关闭",
530
+ children: /* @__PURE__ */ e.jsx(G, { className: "w-4 h-4" })
531
+ }
532
+ )
533
+ ] })
534
+ ]
535
+ }
536
+ ),
537
+ o && /* @__PURE__ */ e.jsxs("div", { className: "px-4 py-2 bg-muted/50 border-b shrink-0", children: [
538
+ /* @__PURE__ */ e.jsx("div", { className: "text-xs text-muted-foreground mb-1", children: "选中的内容:" }),
539
+ /* @__PURE__ */ e.jsx("div", { className: "text-sm line-clamp-2", children: o })
540
+ ] }),
541
+ /* @__PURE__ */ e.jsx(
542
+ "div",
543
+ {
544
+ ref: b,
545
+ className: "flex-1 overflow-y-auto",
546
+ onScroll: W,
547
+ children: m.length === 0 ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col items-center justify-center h-full text-muted-foreground p-4", children: [
548
+ /* @__PURE__ */ e.jsx($, { className: "w-12 h-12 mb-4 opacity-50" }),
549
+ /* @__PURE__ */ e.jsxs("p", { className: "text-center", children: [
550
+ "你好!我是 AI 助手。",
551
+ /* @__PURE__ */ e.jsx("br", {}),
552
+ "有什么我可以帮助你的吗?"
553
+ ] })
554
+ ] }) : /* @__PURE__ */ e.jsxs("div", { className: "divide-y", children: [
555
+ m.map((s, P) => /* @__PURE__ */ e.jsx(
556
+ De,
557
+ {
558
+ message: s,
559
+ onRegenerate: s.role === "assistant" && P === m.length - 1 && !i ? E : void 0,
560
+ onEdit: s.role === "user" ? (z) => h(s.id, z) : void 0,
561
+ onDelete: i ? void 0 : () => M(s.id)
562
+ },
563
+ s.id
564
+ )),
565
+ /* @__PURE__ */ e.jsx("div", { ref: N })
566
+ ] })
567
+ }
568
+ ),
569
+ u && /* @__PURE__ */ e.jsx("div", { className: "px-4 py-2 bg-destructive/10 text-destructive text-sm border-t", children: u }),
570
+ /* @__PURE__ */ e.jsx(
571
+ Re,
572
+ {
573
+ onSend: k,
574
+ onStop: T,
575
+ isLoading: i,
576
+ placeholder: o ? "询问关于选中内容的问题..." : "输入消息..."
577
+ }
578
+ ),
579
+ /* @__PURE__ */ e.jsx(
580
+ "div",
581
+ {
582
+ ref: v,
583
+ className: "absolute top-0 left-1/2 -translate-x-1/2 w-20 h-2 cursor-ns-resize flex items-center justify-center",
584
+ onMouseDown: K,
585
+ children: /* @__PURE__ */ e.jsx("div", { className: "w-8 h-1 rounded-full bg-muted-foreground/30" })
586
+ }
587
+ )
588
+ ]
589
+ }
590
+ )
591
+ }
592
+ ) : null;
593
+ }
594
+ function _e() {
595
+ const { isSettingsOpen: r, closeSettings: p, config: n, updateConfig: m } = ee(), { toast: i } = ie(), [u, I] = d("openai"), [o, k] = d(J("openai")), [E, l] = d(""), [T, h] = d("providers"), [M, N] = d(!1), [b, L] = d(""), [v, w] = d({
596
+ modelId: "",
597
+ apiKey: "",
598
+ baseUrl: "",
599
+ maxTokens: 4096,
600
+ temperature: 0.7,
601
+ enabled: !0
602
+ }), [C, c] = d(!1), [a, j] = d(!1), [y, g] = d(null), [A, B] = d(!1), [H, O] = d(["openai", "claude", "gemini"]), W = ["openai", "claude", "gemini"], K = (t) => W.includes(t);
603
+ _(() => {
604
+ if (n) {
605
+ const t = n.provider || "openai";
606
+ I(t), k(n.models[t] || J("openai")), l(n.systemPrompt || ""), U();
607
+ }
608
+ }, [n]);
609
+ const U = async () => {
610
+ const t = await le();
611
+ O(t);
612
+ }, Z = (t) => {
613
+ if (!t) return;
614
+ I(t);
615
+ const f = n?.models[t];
616
+ k(f || J(t)), g(null);
617
+ }, s = (t) => {
618
+ k((f) => ({ ...f, ...t })), g(null);
619
+ }, P = async () => {
620
+ j(!0), g(null);
621
+ try {
622
+ const t = await me(u, o);
623
+ g(t), t.success ? i({
624
+ title: "连接成功",
625
+ description: t.message
626
+ }) : i({
627
+ title: "连接失败",
628
+ description: t.message,
629
+ variant: "destructive"
630
+ });
631
+ } catch (t) {
632
+ const f = t instanceof Error ? t.message : "测试失败";
633
+ g({
634
+ success: !1,
635
+ message: f
636
+ }), i({
637
+ title: "连接失败",
638
+ description: f,
639
+ variant: "destructive"
640
+ });
641
+ } finally {
642
+ j(!1);
643
+ }
644
+ }, z = async () => {
645
+ B(!0);
646
+ try {
647
+ await m({
648
+ provider: u,
649
+ systemPrompt: E,
650
+ models: {
651
+ ...n?.models || {},
652
+ [u]: o
653
+ }
654
+ }), i({
655
+ title: "保存成功",
656
+ description: "配置已保存"
657
+ }), p();
658
+ } catch (t) {
659
+ console.error("Failed to save config:", t), i({
660
+ title: "保存失败",
661
+ description: t instanceof Error ? t.message : "未知错误",
662
+ variant: "destructive"
663
+ });
664
+ } finally {
665
+ B(!1);
666
+ }
667
+ }, R = async () => {
668
+ if (!b.trim()) {
669
+ i({
670
+ title: "请输入 Provider 名称",
671
+ variant: "destructive"
672
+ });
673
+ return;
674
+ }
675
+ if (K(b)) {
676
+ i({
677
+ title: "不能使用预定义的 Provider 名称",
678
+ variant: "destructive"
679
+ });
680
+ return;
681
+ }
682
+ if (n?.models[b]) {
683
+ i({
684
+ title: "Provider 名称已存在",
685
+ variant: "destructive"
686
+ });
687
+ return;
688
+ }
689
+ const t = xe(v);
690
+ if (!t.valid) {
691
+ i({
692
+ title: "配置无效",
693
+ description: t.message,
694
+ variant: "destructive"
695
+ });
696
+ return;
697
+ }
698
+ try {
699
+ await m({
700
+ models: {
701
+ ...n?.models || {},
702
+ [b]: v
703
+ }
704
+ }), N(!1), L(""), w({
705
+ modelId: "",
706
+ apiKey: "",
707
+ baseUrl: "",
708
+ maxTokens: 4096,
709
+ temperature: 0.7,
710
+ enabled: !0
711
+ }), await U(), I(b), k(v), i({
712
+ title: "添加成功",
713
+ description: `Provider "${b}" 已添加`
714
+ });
715
+ } catch (f) {
716
+ console.error("Failed to add provider:", f), i({
717
+ title: "添加失败",
718
+ description: f instanceof Error ? f.message : "未知错误",
719
+ variant: "destructive"
720
+ });
721
+ }
722
+ }, F = async (t) => {
723
+ if (K(t)) {
724
+ i({
725
+ title: "不能删除预定义的 Provider",
726
+ variant: "destructive"
727
+ });
728
+ return;
729
+ }
730
+ if (confirm(`确定要删除 "${t}" 吗?`))
731
+ try {
732
+ await ce(t), await U(), u === t && (I("openai"), k(n?.models.openai || J("openai"))), i({
733
+ title: "删除成功",
734
+ description: `Provider "${t}" 已删除`
735
+ });
736
+ } catch (f) {
737
+ console.error("Failed to delete provider:", f), i({
738
+ title: "删除失败",
739
+ description: f instanceof Error ? f.message : "未知错误",
740
+ variant: "destructive"
741
+ });
742
+ }
743
+ }, Y = async () => {
744
+ B(!0);
745
+ try {
746
+ await m({ systemPrompt: E }), i({
747
+ title: "保存成功",
748
+ description: "系统提示词已更新"
749
+ });
750
+ } catch (t) {
751
+ console.error("Failed to save system prompt:", t), i({
752
+ title: "保存失败",
753
+ description: t instanceof Error ? t.message : "未知错误",
754
+ variant: "destructive"
755
+ });
756
+ } finally {
757
+ B(!1);
758
+ }
759
+ };
760
+ if (!r)
761
+ return null;
762
+ const V = de(u), q = ue(u), ae = K(u);
763
+ return /* @__PURE__ */ e.jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
764
+ /* @__PURE__ */ e.jsx(
765
+ "div",
766
+ {
767
+ className: "absolute inset-0 bg-black/50",
768
+ onClick: p
769
+ }
770
+ ),
771
+ /* @__PURE__ */ e.jsxs(
772
+ "div",
773
+ {
774
+ className: x(
775
+ "relative bg-background border rounded-xl shadow-2xl",
776
+ "w-full max-w-2xl mx-4 max-h-[90vh] overflow-hidden",
777
+ "flex flex-col",
778
+ "animate-in zoom-in-95 duration-200"
779
+ ),
780
+ children: [
781
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center justify-between p-4 border-b", children: [
782
+ /* @__PURE__ */ e.jsx("h2", { className: "text-lg font-semibold", children: "AI 设置" }),
783
+ /* @__PURE__ */ e.jsx(
784
+ "button",
785
+ {
786
+ onClick: p,
787
+ className: "p-1.5 rounded hover:bg-muted transition-colors",
788
+ children: /* @__PURE__ */ e.jsx(G, { className: "w-4 h-4" })
789
+ }
790
+ )
791
+ ] }),
792
+ /* @__PURE__ */ e.jsxs("div", { className: "flex border-b", children: [
793
+ /* @__PURE__ */ e.jsx(
794
+ "button",
795
+ {
796
+ onClick: () => h("providers"),
797
+ className: x(
798
+ "flex-1 px-4 py-3 text-sm font-medium transition-colors",
799
+ T === "providers" ? "border-b-2 border-primary text-primary" : "text-muted-foreground hover:text-foreground"
800
+ ),
801
+ children: "Provider 配置"
802
+ }
803
+ ),
804
+ /* @__PURE__ */ e.jsx(
805
+ "button",
806
+ {
807
+ onClick: () => h("settings"),
808
+ className: x(
809
+ "flex-1 px-4 py-3 text-sm font-medium transition-colors",
810
+ T === "settings" ? "border-b-2 border-primary text-primary" : "text-muted-foreground hover:text-foreground"
811
+ ),
812
+ children: "系统设置"
813
+ }
814
+ )
815
+ ] }),
816
+ /* @__PURE__ */ e.jsxs("div", { className: "flex-1 overflow-y-auto", children: [
817
+ T === "providers" && /* @__PURE__ */ e.jsxs("div", { className: "p-4 space-y-6", children: [
818
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-3", children: [
819
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center justify-between", children: [
820
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm font-medium", children: "选择 Provider" }),
821
+ /* @__PURE__ */ e.jsxs(
822
+ "button",
823
+ {
824
+ onClick: () => N(!0),
825
+ className: "flex items-center gap-1 px-3 py-1.5 rounded-lg text-sm bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
826
+ children: [
827
+ /* @__PURE__ */ e.jsx(ne, { className: "w-4 h-4" }),
828
+ "添加"
829
+ ]
830
+ }
831
+ )
832
+ ] }),
833
+ /* @__PURE__ */ e.jsx("div", { className: "grid grid-cols-2 gap-2", children: H.map((t) => /* @__PURE__ */ e.jsxs(
834
+ "div",
835
+ {
836
+ className: x(
837
+ "relative flex items-center justify-between p-3 rounded-lg border transition-colors",
838
+ u === t ? "bg-primary/10 border-primary" : "bg-background hover:bg-muted border-border"
839
+ ),
840
+ children: [
841
+ /* @__PURE__ */ e.jsxs(
842
+ "button",
843
+ {
844
+ onClick: () => Z(t),
845
+ className: "flex-1 text-left",
846
+ children: [
847
+ /* @__PURE__ */ e.jsx("div", { className: "font-medium text-sm", children: se(t) }),
848
+ n?.provider === t && /* @__PURE__ */ e.jsxs("div", { className: "text-xs text-primary flex items-center gap-1", children: [
849
+ /* @__PURE__ */ e.jsx(Ce, { className: "w-3 h-3" }),
850
+ "当前使用"
851
+ ] })
852
+ ]
853
+ }
854
+ ),
855
+ !ae && /* @__PURE__ */ e.jsx(
856
+ "button",
857
+ {
858
+ onClick: () => F(t),
859
+ className: "p-1.5 rounded hover:bg-muted text-destructive",
860
+ title: "删除",
861
+ children: /* @__PURE__ */ e.jsx(te, { className: "w-4 h-4" })
862
+ }
863
+ )
864
+ ]
865
+ },
866
+ t
867
+ )) })
868
+ ] }),
869
+ !M && /* @__PURE__ */ e.jsxs("div", { className: "space-y-4", children: [
870
+ /* @__PURE__ */ e.jsxs("h3", { className: "text-sm font-medium", children: [
871
+ se(u),
872
+ " 配置"
873
+ ] }),
874
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
875
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center justify-between", children: [
876
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm font-medium", children: "API 密钥" }),
877
+ V.apiKeyUrl && /* @__PURE__ */ e.jsxs(
878
+ "a",
879
+ {
880
+ href: V.apiKeyUrl,
881
+ target: "_blank",
882
+ rel: "noopener noreferrer",
883
+ className: "text-xs text-primary hover:underline flex items-center gap-1",
884
+ children: [
885
+ "获取密钥",
886
+ /* @__PURE__ */ e.jsx(Pe, { className: "w-3 h-3" })
887
+ ]
888
+ }
889
+ )
890
+ ] }),
891
+ /* @__PURE__ */ e.jsxs("div", { className: "relative", children: [
892
+ /* @__PURE__ */ e.jsx(
893
+ "input",
894
+ {
895
+ type: C ? "text" : "password",
896
+ value: o.apiKey,
897
+ onChange: (t) => s({ apiKey: t.target.value }),
898
+ placeholder: "sk-...",
899
+ className: "w-full px-3 py-2 pr-10 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
900
+ }
901
+ ),
902
+ /* @__PURE__ */ e.jsx(
903
+ "button",
904
+ {
905
+ type: "button",
906
+ onClick: () => c(!C),
907
+ className: "absolute right-2 top-1/2 -translate-y-1/2 p-1 text-muted-foreground hover:text-foreground",
908
+ children: C ? /* @__PURE__ */ e.jsx(Ie, { className: "w-4 h-4" }) : /* @__PURE__ */ e.jsx(Ee, { className: "w-4 h-4" })
909
+ }
910
+ )
911
+ ] })
912
+ ] }),
913
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
914
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm font-medium", children: "API 地址" }),
915
+ /* @__PURE__ */ e.jsx(
916
+ "input",
917
+ {
918
+ type: "text",
919
+ value: o.baseUrl,
920
+ onChange: (t) => s({ baseUrl: t.target.value }),
921
+ placeholder: "https://api.openai.com/v1",
922
+ className: "w-full px-3 py-2 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
923
+ }
924
+ )
925
+ ] }),
926
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
927
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm font-medium", children: "模型" }),
928
+ q.length > 0 ? /* @__PURE__ */ e.jsxs(
929
+ "select",
930
+ {
931
+ value: o.modelId,
932
+ onChange: (t) => s({ modelId: t.target.value }),
933
+ className: "w-full px-3 py-2 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring",
934
+ children: [
935
+ /* @__PURE__ */ e.jsx("option", { value: "", children: "选择模型" }),
936
+ q.map((t) => /* @__PURE__ */ e.jsx("option", { value: t, children: t }, t))
937
+ ]
938
+ }
939
+ ) : /* @__PURE__ */ e.jsx(
940
+ "input",
941
+ {
942
+ type: "text",
943
+ value: o.modelId,
944
+ onChange: (t) => s({ modelId: t.target.value }),
945
+ placeholder: "gpt-4o-mini",
946
+ className: "w-full px-3 py-2 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
947
+ }
948
+ )
949
+ ] }),
950
+ /* @__PURE__ */ e.jsxs("details", { className: "group", children: [
951
+ /* @__PURE__ */ e.jsxs("summary", { className: "cursor-pointer text-sm font-medium flex items-center gap-1", children: [
952
+ /* @__PURE__ */ e.jsx("span", { children: "高级设置" }),
953
+ /* @__PURE__ */ e.jsx("span", { className: "text-muted-foreground group-open:rotate-90 transition-transform", children: "▶" })
954
+ ] }),
955
+ /* @__PURE__ */ e.jsxs("div", { className: "mt-4 space-y-4 pl-2", children: [
956
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
957
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center justify-between", children: [
958
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm", children: "温度 (Temperature)" }),
959
+ /* @__PURE__ */ e.jsx("span", { className: "text-sm text-muted-foreground", children: o.temperature.toFixed(1) })
960
+ ] }),
961
+ /* @__PURE__ */ e.jsx(
962
+ "input",
963
+ {
964
+ type: "range",
965
+ min: "0",
966
+ max: "2",
967
+ step: "0.1",
968
+ value: o.temperature,
969
+ onChange: (t) => s({ temperature: parseFloat(t.target.value) }),
970
+ className: "w-full"
971
+ }
972
+ )
973
+ ] }),
974
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
975
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm", children: "最大输出长度 (Max Tokens)" }),
976
+ /* @__PURE__ */ e.jsx(
977
+ "input",
978
+ {
979
+ type: "number",
980
+ min: "1",
981
+ max: "128000",
982
+ value: o.maxTokens,
983
+ onChange: (t) => s({ maxTokens: parseInt(t.target.value) || 4096 }),
984
+ className: "w-full px-3 py-2 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
985
+ }
986
+ )
987
+ ] })
988
+ ] })
989
+ ] }),
990
+ y && /* @__PURE__ */ e.jsxs(
991
+ "div",
992
+ {
993
+ className: x(
994
+ "flex items-center gap-2 p-3 rounded-lg text-sm",
995
+ y.success ? "bg-green-500/10 text-green-600 dark:text-green-400" : "bg-destructive/10 text-destructive"
996
+ ),
997
+ children: [
998
+ y.success ? /* @__PURE__ */ e.jsx(oe, { className: "w-4 h-4 shrink-0" }) : /* @__PURE__ */ e.jsx(Se, { className: "w-4 h-4 shrink-0" }),
999
+ /* @__PURE__ */ e.jsx("span", { children: y.message })
1000
+ ]
1001
+ }
1002
+ ),
1003
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-2 pt-4 border-t", children: [
1004
+ /* @__PURE__ */ e.jsx(
1005
+ "button",
1006
+ {
1007
+ onClick: P,
1008
+ disabled: !o.apiKey || !o.modelId || a,
1009
+ className: x(
1010
+ "flex items-center gap-2 px-4 py-2 rounded-lg text-sm",
1011
+ "border border-border hover:bg-muted transition-colors",
1012
+ "disabled:opacity-50 disabled:cursor-not-allowed"
1013
+ ),
1014
+ children: a ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
1015
+ /* @__PURE__ */ e.jsx(X, { className: "w-4 h-4 animate-spin" }),
1016
+ "测试中..."
1017
+ ] }) : "测试连接"
1018
+ }
1019
+ ),
1020
+ /* @__PURE__ */ e.jsx(
1021
+ "button",
1022
+ {
1023
+ onClick: z,
1024
+ disabled: A,
1025
+ className: x(
1026
+ "flex items-center gap-2 px-4 py-2 rounded-lg text-sm ml-auto",
1027
+ "bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
1028
+ "disabled:opacity-50 disabled:cursor-not-allowed"
1029
+ ),
1030
+ children: A ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
1031
+ /* @__PURE__ */ e.jsx(X, { className: "w-4 h-4 animate-spin" }),
1032
+ "保存中..."
1033
+ ] }) : "保存设置"
1034
+ }
1035
+ )
1036
+ ] })
1037
+ ] }),
1038
+ M && /* @__PURE__ */ e.jsxs("div", { className: "space-y-4", children: [
1039
+ /* @__PURE__ */ e.jsx("h3", { className: "text-sm font-medium", children: "添加自定义 Provider" }),
1040
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
1041
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm font-medium", children: "Provider 名称" }),
1042
+ /* @__PURE__ */ e.jsx(
1043
+ "input",
1044
+ {
1045
+ type: "text",
1046
+ value: b,
1047
+ onChange: (t) => L(t.target.value),
1048
+ placeholder: "deepseek",
1049
+ className: "w-full px-3 py-2 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
1050
+ }
1051
+ ),
1052
+ /* @__PURE__ */ e.jsx("p", { className: "text-xs text-muted-foreground", children: "名称将用于标识此 Provider,不能与预定义 Provider 重复" })
1053
+ ] }),
1054
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
1055
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm font-medium", children: "API 密钥" }),
1056
+ /* @__PURE__ */ e.jsx(
1057
+ "input",
1058
+ {
1059
+ type: C ? "text" : "password",
1060
+ value: v.apiKey,
1061
+ onChange: (t) => w((f) => ({ ...f, apiKey: t.target.value })),
1062
+ placeholder: "sk-...",
1063
+ className: "w-full px-3 py-2 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
1064
+ }
1065
+ )
1066
+ ] }),
1067
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
1068
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm font-medium", children: "API 地址" }),
1069
+ /* @__PURE__ */ e.jsx(
1070
+ "input",
1071
+ {
1072
+ type: "text",
1073
+ value: v.baseUrl,
1074
+ onChange: (t) => w((f) => ({ ...f, baseUrl: t.target.value })),
1075
+ placeholder: "https://api.deepseek.com",
1076
+ className: "w-full px-3 py-2 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
1077
+ }
1078
+ )
1079
+ ] }),
1080
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
1081
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm font-medium", children: "模型" }),
1082
+ /* @__PURE__ */ e.jsx(
1083
+ "input",
1084
+ {
1085
+ type: "text",
1086
+ value: v.modelId,
1087
+ onChange: (t) => w((f) => ({ ...f, modelId: t.target.value })),
1088
+ placeholder: "deepseek-chat",
1089
+ className: "w-full px-3 py-2 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring"
1090
+ }
1091
+ )
1092
+ ] }),
1093
+ /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-2 pt-4 border-t", children: [
1094
+ /* @__PURE__ */ e.jsx(
1095
+ "button",
1096
+ {
1097
+ onClick: () => N(!1),
1098
+ className: "px-4 py-2 rounded-lg text-sm border border-border hover:bg-muted transition-colors",
1099
+ children: "取消"
1100
+ }
1101
+ ),
1102
+ /* @__PURE__ */ e.jsx(
1103
+ "button",
1104
+ {
1105
+ onClick: R,
1106
+ disabled: A,
1107
+ className: x(
1108
+ "flex items-center gap-2 px-4 py-2 rounded-lg text-sm ml-auto",
1109
+ "bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
1110
+ "disabled:opacity-50 disabled:cursor-not-allowed"
1111
+ ),
1112
+ children: A ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
1113
+ /* @__PURE__ */ e.jsx(X, { className: "w-4 h-4 animate-spin" }),
1114
+ "添加中..."
1115
+ ] }) : /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
1116
+ /* @__PURE__ */ e.jsx(ne, { className: "w-4 h-4" }),
1117
+ "添加"
1118
+ ] })
1119
+ }
1120
+ )
1121
+ ] })
1122
+ ] })
1123
+ ] }),
1124
+ T === "settings" && /* @__PURE__ */ e.jsxs("div", { className: "p-4 space-y-6", children: [
1125
+ /* @__PURE__ */ e.jsxs("div", { className: "space-y-2", children: [
1126
+ /* @__PURE__ */ e.jsx("label", { className: "text-sm font-medium", children: "系统提示词" }),
1127
+ /* @__PURE__ */ e.jsx(
1128
+ "textarea",
1129
+ {
1130
+ value: E,
1131
+ onChange: (t) => l(t.target.value),
1132
+ rows: 6,
1133
+ placeholder: "你是一个专业的文档助手,请根据用户的问题,提供准确、有帮助的回答。",
1134
+ className: "w-full px-3 py-2 rounded-lg border bg-background text-sm focus:outline-none focus:ring-2 focus:ring-ring resize-none"
1135
+ }
1136
+ ),
1137
+ /* @__PURE__ */ e.jsx("p", { className: "text-xs text-muted-foreground", children: "系统提示词用于定义 AI 助手的行为和角色" })
1138
+ ] }),
1139
+ /* @__PURE__ */ e.jsx("div", { className: "flex items-center gap-2 pt-4 border-t", children: /* @__PURE__ */ e.jsx(
1140
+ "button",
1141
+ {
1142
+ onClick: Y,
1143
+ disabled: A,
1144
+ className: x(
1145
+ "flex items-center gap-2 px-4 py-2 rounded-lg text-sm ml-auto",
1146
+ "bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
1147
+ "disabled:opacity-50 disabled:cursor-not-allowed"
1148
+ ),
1149
+ children: A ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
1150
+ /* @__PURE__ */ e.jsx(X, { className: "w-4 h-4 animate-spin" }),
1151
+ "保存中..."
1152
+ ] }) : /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
1153
+ /* @__PURE__ */ e.jsx(Ae, { className: "w-4 h-4" }),
1154
+ "保存提示词"
1155
+ ] })
1156
+ }
1157
+ ) })
1158
+ ] })
1159
+ ] })
1160
+ ]
1161
+ }
1162
+ )
1163
+ ] });
1164
+ }
1165
+ export {
1166
+ $e as A,
1167
+ Ge as a,
1168
+ _e as b,
1169
+ Re as c,
1170
+ De as d
1171
+ };