sa2kit 3.4.0 → 3.7.0

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.
Files changed (157) hide show
  1. package/dist/business/index.d.mts +2 -7
  2. package/dist/business/index.d.ts +2 -7
  3. package/dist/business/index.js +1761 -8045
  4. package/dist/business/index.js.map +1 -1
  5. package/dist/business/index.mjs +1169 -7452
  6. package/dist/business/index.mjs.map +1 -1
  7. package/dist/business/portfolio/index.d.mts +1 -2
  8. package/dist/business/portfolio/index.d.ts +1 -2
  9. package/dist/{chunk-KVYHCGRY.js → chunk-7Z3XR2Y4.js} +552 -263
  10. package/dist/chunk-7Z3XR2Y4.js.map +1 -0
  11. package/dist/chunk-XPY45Y75.js +1143 -0
  12. package/dist/chunk-XPY45Y75.js.map +1 -0
  13. package/dist/{chunk-YIRPPMCN.mjs → chunk-XSTMLLJV.mjs} +474 -198
  14. package/dist/chunk-XSTMLLJV.mjs.map +1 -0
  15. package/dist/chunk-ZJLS5JU5.mjs +1090 -0
  16. package/dist/chunk-ZJLS5JU5.mjs.map +1 -0
  17. package/dist/common/aiApi/client/index.d.mts +71 -0
  18. package/dist/common/aiApi/client/index.d.ts +71 -0
  19. package/dist/common/aiApi/client/index.js +165 -0
  20. package/dist/common/aiApi/client/index.js.map +1 -0
  21. package/dist/common/aiApi/client/index.mjs +151 -0
  22. package/dist/common/aiApi/client/index.mjs.map +1 -0
  23. package/dist/common/aiApi/index.d.mts +184 -0
  24. package/dist/common/aiApi/index.d.ts +184 -0
  25. package/dist/common/aiApi/index.js +217 -0
  26. package/dist/common/aiApi/index.mjs +4 -0
  27. package/dist/common/aiApi/server/index.d.mts +3 -0
  28. package/dist/common/aiApi/server/index.d.ts +3 -0
  29. package/dist/common/aiApi/server/index.js +217 -0
  30. package/dist/common/aiApi/server/index.mjs +4 -0
  31. package/dist/common/components/index.js +176 -177
  32. package/dist/common/components/index.mjs +1 -2
  33. package/dist/common/index.js +2 -3
  34. package/dist/common/index.mjs +1 -2
  35. package/dist/{index-BSmd4ikf.d.ts → index-B4wDXFL0.d.mts} +39 -2
  36. package/dist/{index-r2-zE3iC.d.mts → index-B4wDXFL0.d.ts} +39 -2
  37. package/dist/{index-DLLPTprx.d.mts → index-B9vXYzok.d.mts} +48 -13
  38. package/dist/{index-VFDbZxVM.d.ts → index-BZ0MhRau.d.ts} +48 -13
  39. package/dist/index.d.mts +703 -181
  40. package/dist/index.d.ts +703 -181
  41. package/dist/index.js +2921 -7257
  42. package/dist/index.js.map +1 -1
  43. package/dist/index.mjs +2161 -6538
  44. package/dist/index.mjs.map +1 -1
  45. package/dist/types-CiqMQ-uu.d.mts +166 -0
  46. package/dist/types-CiqMQ-uu.d.ts +166 -0
  47. package/package.json +15 -60
  48. package/dist/CollisionBalls-DgKtscU2.d.mts +0 -41
  49. package/dist/CollisionBalls-DgKtscU2.d.ts +0 -41
  50. package/dist/business/calendar/index.d.mts +0 -6
  51. package/dist/business/calendar/index.d.ts +0 -6
  52. package/dist/business/calendar/index.js +0 -7433
  53. package/dist/business/calendar/index.js.map +0 -1
  54. package/dist/business/calendar/index.mjs +0 -7257
  55. package/dist/business/calendar/index.mjs.map +0 -1
  56. package/dist/business/calendar/routes/index.d.mts +0 -191
  57. package/dist/business/calendar/routes/index.d.ts +0 -191
  58. package/dist/business/calendar/routes/index.js +0 -844
  59. package/dist/business/calendar/routes/index.js.map +0 -1
  60. package/dist/business/calendar/routes/index.mjs +0 -826
  61. package/dist/business/calendar/routes/index.mjs.map +0 -1
  62. package/dist/chunk-3R6JHA6D.js +0 -120
  63. package/dist/chunk-3R6JHA6D.js.map +0 -1
  64. package/dist/chunk-4PJM4752.js +0 -4
  65. package/dist/chunk-4PJM4752.js.map +0 -1
  66. package/dist/chunk-7PMT4L4I.js +0 -324
  67. package/dist/chunk-7PMT4L4I.js.map +0 -1
  68. package/dist/chunk-FY2X3LYR.mjs +0 -3
  69. package/dist/chunk-FY2X3LYR.mjs.map +0 -1
  70. package/dist/chunk-GS4SAW25.mjs +0 -116
  71. package/dist/chunk-GS4SAW25.mjs.map +0 -1
  72. package/dist/chunk-HL4H2HF6.js +0 -279
  73. package/dist/chunk-HL4H2HF6.js.map +0 -1
  74. package/dist/chunk-IJIQUMAK.mjs +0 -272
  75. package/dist/chunk-IJIQUMAK.mjs.map +0 -1
  76. package/dist/chunk-KVYHCGRY.js.map +0 -1
  77. package/dist/chunk-MMDSZIXD.mjs +0 -286
  78. package/dist/chunk-MMDSZIXD.mjs.map +0 -1
  79. package/dist/chunk-N2O3OX5Y.mjs +0 -243
  80. package/dist/chunk-N2O3OX5Y.mjs.map +0 -1
  81. package/dist/chunk-RRQ2X26Z.js +0 -106
  82. package/dist/chunk-RRQ2X26Z.js.map +0 -1
  83. package/dist/chunk-RVNQI6BI.js +0 -249
  84. package/dist/chunk-RVNQI6BI.js.map +0 -1
  85. package/dist/chunk-UJUWDF7M.mjs +0 -336
  86. package/dist/chunk-UJUWDF7M.mjs.map +0 -1
  87. package/dist/chunk-VCKXK6V5.js +0 -345
  88. package/dist/chunk-VCKXK6V5.js.map +0 -1
  89. package/dist/chunk-VIEXDTNF.mjs +0 -100
  90. package/dist/chunk-VIEXDTNF.mjs.map +0 -1
  91. package/dist/chunk-YIRPPMCN.mjs.map +0 -1
  92. package/dist/common/ai/llm/core/index.d.mts +0 -70
  93. package/dist/common/ai/llm/core/index.d.ts +0 -70
  94. package/dist/common/ai/llm/core/index.js +0 -54
  95. package/dist/common/ai/llm/core/index.mjs +0 -5
  96. package/dist/common/ai/llm/electron/index.d.mts +0 -6
  97. package/dist/common/ai/llm/electron/index.d.ts +0 -6
  98. package/dist/common/ai/llm/electron/index.js +0 -67
  99. package/dist/common/ai/llm/electron/index.mjs +0 -10
  100. package/dist/common/ai/llm/index.d.mts +0 -3
  101. package/dist/common/ai/llm/index.d.ts +0 -3
  102. package/dist/common/ai/llm/index.js +0 -54
  103. package/dist/common/ai/llm/index.js.map +0 -1
  104. package/dist/common/ai/llm/index.mjs +0 -5
  105. package/dist/common/ai/llm/index.mjs.map +0 -1
  106. package/dist/common/ai/llm/miniapp/index.d.mts +0 -6
  107. package/dist/common/ai/llm/miniapp/index.d.ts +0 -6
  108. package/dist/common/ai/llm/miniapp/index.js +0 -59
  109. package/dist/common/ai/llm/miniapp/index.js.map +0 -1
  110. package/dist/common/ai/llm/miniapp/index.mjs +0 -6
  111. package/dist/common/ai/llm/miniapp/index.mjs.map +0 -1
  112. package/dist/common/ai/llm/rn/index.d.mts +0 -6
  113. package/dist/common/ai/llm/rn/index.d.ts +0 -6
  114. package/dist/common/ai/llm/rn/index.js +0 -59
  115. package/dist/common/ai/llm/rn/index.js.map +0 -1
  116. package/dist/common/ai/llm/rn/index.mjs +0 -6
  117. package/dist/common/ai/llm/rn/index.mjs.map +0 -1
  118. package/dist/common/ai/llm/ui/electron/index.d.mts +0 -5
  119. package/dist/common/ai/llm/ui/electron/index.d.ts +0 -5
  120. package/dist/common/ai/llm/ui/electron/index.js +0 -22
  121. package/dist/common/ai/llm/ui/electron/index.js.map +0 -1
  122. package/dist/common/ai/llm/ui/electron/index.mjs +0 -9
  123. package/dist/common/ai/llm/ui/electron/index.mjs.map +0 -1
  124. package/dist/common/ai/llm/ui/miniapp/index.d.mts +0 -9
  125. package/dist/common/ai/llm/ui/miniapp/index.d.ts +0 -9
  126. package/dist/common/ai/llm/ui/miniapp/index.js +0 -14
  127. package/dist/common/ai/llm/ui/miniapp/index.js.map +0 -1
  128. package/dist/common/ai/llm/ui/miniapp/index.mjs +0 -5
  129. package/dist/common/ai/llm/ui/miniapp/index.mjs.map +0 -1
  130. package/dist/common/ai/llm/ui/rn/index.d.mts +0 -9
  131. package/dist/common/ai/llm/ui/rn/index.d.ts +0 -9
  132. package/dist/common/ai/llm/ui/rn/index.js +0 -14
  133. package/dist/common/ai/llm/ui/rn/index.js.map +0 -1
  134. package/dist/common/ai/llm/ui/rn/index.mjs +0 -5
  135. package/dist/common/ai/llm/ui/rn/index.mjs.map +0 -1
  136. package/dist/common/ai/llm/ui/web/index.d.mts +0 -15
  137. package/dist/common/ai/llm/ui/web/index.d.ts +0 -15
  138. package/dist/common/ai/llm/ui/web/index.js +0 -21
  139. package/dist/common/ai/llm/ui/web/index.js.map +0 -1
  140. package/dist/common/ai/llm/ui/web/index.mjs +0 -8
  141. package/dist/common/ai/llm/ui/web/index.mjs.map +0 -1
  142. package/dist/common/ai/llm/web/index.d.mts +0 -6
  143. package/dist/common/ai/llm/web/index.d.ts +0 -6
  144. package/dist/common/ai/llm/web/index.js +0 -66
  145. package/dist/common/ai/llm/web/index.js.map +0 -1
  146. package/dist/common/ai/llm/web/index.mjs +0 -9
  147. package/dist/common/ai/llm/web/index.mjs.map +0 -1
  148. package/dist/index-BMgdH5dL.d.mts +0 -1716
  149. package/dist/index-IXMAeTtN.d.ts +0 -1716
  150. package/dist/types-B2rs_jq1.d.mts +0 -38
  151. package/dist/types-DgACCUpT.d.ts +0 -122
  152. package/dist/types-DwS2Eg0q.d.ts +0 -38
  153. package/dist/types-LU_BGSzk.d.mts +0 -122
  154. /package/dist/common/{ai/llm/core → aiApi}/index.js.map +0 -0
  155. /package/dist/common/{ai/llm/core → aiApi}/index.mjs.map +0 -0
  156. /package/dist/common/{ai/llm/electron → aiApi/server}/index.js.map +0 -0
  157. /package/dist/common/{ai/llm/electron → aiApi/server}/index.mjs.map +0 -0
@@ -1,272 +0,0 @@
1
- import { useAiChat } from './chunk-GS4SAW25.mjs';
2
- import { Dialog, DialogContent, DialogHeader, DialogTitle, Button, Input } from './chunk-MMDSZIXD.mjs';
3
- import { cn } from './chunk-FUA6ZGMI.mjs';
4
- import React2, { useState, useRef, useMemo, useEffect } from 'react';
5
-
6
- var AiChatDialog = ({
7
- open,
8
- onOpenChange,
9
- client,
10
- title = "AI \u5BF9\u8BDD",
11
- placeholder = "\u8F93\u5165\u4F60\u60F3\u54A8\u8BE2\u7684\u95EE\u9898...",
12
- systemPrompt,
13
- template,
14
- templateVariables,
15
- initialMessages,
16
- requestOptions,
17
- onResponse,
18
- onError,
19
- className,
20
- contentClassName
21
- }) => {
22
- const { messages, sendMessage, isLoading, error } = useAiChat({
23
- client,
24
- systemPrompt,
25
- template,
26
- initialMessages
27
- });
28
- const [input, setInput] = useState("");
29
- const listRef = useRef(null);
30
- const hasMessages = messages.length > 0;
31
- const helperText = useMemo(() => {
32
- return template ? "\u6A21\u677F\u5DF2\u542F\u7528\uFF0C\u652F\u6301 {{input}} \u53D8\u91CF\u3002" : "\u76F4\u63A5\u8F93\u5165\u5373\u53EF\u5F00\u59CB\u5BF9\u8BDD\u3002";
33
- }, [template]);
34
- useEffect(() => {
35
- if (!listRef.current) return;
36
- listRef.current.scrollTop = listRef.current.scrollHeight;
37
- }, [messages, open, isLoading]);
38
- const handleSend = async () => {
39
- const content = input.trim();
40
- if (!content || isLoading) return;
41
- setInput("");
42
- try {
43
- const response = await sendMessage(content, {
44
- ...requestOptions,
45
- template,
46
- variables: templateVariables
47
- });
48
- onResponse?.(response);
49
- } catch (err) {
50
- const nextError = err instanceof Error ? err : new Error(String(err));
51
- onError?.(nextError);
52
- }
53
- };
54
- const handleKeyDown = (event) => {
55
- if (event.key === "Enter" && !event.shiftKey) {
56
- event.preventDefault();
57
- handleSend();
58
- }
59
- };
60
- return /* @__PURE__ */ React2.createElement(Dialog, { open, onOpenChange }, /* @__PURE__ */ React2.createElement(
61
- DialogContent,
62
- {
63
- className: cn(
64
- "max-w-3xl border border-slate-200 bg-white p-0",
65
- contentClassName
66
- )
67
- },
68
- /* @__PURE__ */ React2.createElement("div", { className: cn("flex flex-col", className) }, /* @__PURE__ */ React2.createElement(DialogHeader, { className: "border-b border-slate-100 px-6 py-4" }, /* @__PURE__ */ React2.createElement(DialogTitle, { className: "text-base font-semibold text-slate-900" }, title)), /* @__PURE__ */ React2.createElement("div", { className: "flex flex-1 flex-col gap-4 px-6 py-4" }, /* @__PURE__ */ React2.createElement(
69
- "div",
70
- {
71
- ref: listRef,
72
- className: "max-h-[60vh] min-h-[240px] overflow-y-auto rounded-xl border border-slate-100 bg-slate-50/60 p-4"
73
- },
74
- !hasMessages && /* @__PURE__ */ React2.createElement("div", { className: "flex h-full flex-col items-center justify-center gap-2 text-sm text-slate-400" }, /* @__PURE__ */ React2.createElement("span", null, "\u6682\u65E0\u5BF9\u8BDD\u5185\u5BB9"), /* @__PURE__ */ React2.createElement("span", null, "\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u4F53\u9A8C AI \u5BF9\u8BDD\u3002")),
75
- /* @__PURE__ */ React2.createElement("div", { className: "flex flex-col gap-3" }, messages.map((message, index) => {
76
- const isUser = message.role === "user";
77
- return /* @__PURE__ */ React2.createElement(
78
- "div",
79
- {
80
- key: `${message.role}-${index}`,
81
- className: cn(
82
- "max-w-[85%] whitespace-pre-wrap rounded-2xl px-4 py-2 text-sm leading-relaxed",
83
- isUser ? "ml-auto bg-slate-900 text-white" : "mr-auto border border-slate-200 bg-white text-slate-800"
84
- )
85
- },
86
- message.content
87
- );
88
- }), isLoading && /* @__PURE__ */ React2.createElement("div", { className: "mr-auto max-w-[70%] rounded-2xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-500" }, "AI \u6B63\u5728\u601D\u8003..."))
89
- ), /* @__PURE__ */ React2.createElement("div", { className: "rounded-xl border border-slate-100 bg-white p-4 shadow-sm" }, /* @__PURE__ */ React2.createElement(
90
- "textarea",
91
- {
92
- value: input,
93
- onChange: (event) => setInput(event.target.value),
94
- onKeyDown: handleKeyDown,
95
- placeholder,
96
- className: "min-h-[96px] w-full resize-none rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-300"
97
- }
98
- ), /* @__PURE__ */ React2.createElement("div", { className: "mt-3 flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React2.createElement("span", { className: "text-xs text-slate-400" }, helperText), /* @__PURE__ */ React2.createElement(Button, { onClick: handleSend, disabled: !input.trim() || isLoading }, isLoading ? "\u53D1\u9001\u4E2D..." : "\u53D1\u9001")), error && /* @__PURE__ */ React2.createElement("div", { className: "mt-2 rounded-md border border-rose-200 bg-rose-50 px-3 py-2 text-xs text-rose-600" }, error.message || "\u5BF9\u8BDD\u51FA\u9519\uFF0C\u8BF7\u91CD\u8BD5\u3002"))))
99
- ));
100
- };
101
- var DEFAULT_AI_CONFIG = {
102
- apiKey: "",
103
- baseUrl: "https://api.openai.com/v1",
104
- model: "gpt-3.5-turbo",
105
- systemPrompt: "",
106
- template: "{{input}}",
107
- temperature: 0.7,
108
- topP: 1,
109
- maxTokens: 1024
110
- };
111
- var mergeConfig = (base, overrides, stored) => {
112
- return {
113
- ...base,
114
- ...overrides ?? {},
115
- ...stored ?? {}
116
- };
117
- };
118
- var AiConfigPage = ({
119
- storageKey = "sa2kit-ai-config",
120
- initialConfig,
121
- title = "AI \u914D\u7F6E",
122
- description = "\u914D\u7F6E API Key\u3001\u6A21\u578B\u4E0E\u63D0\u793A\u8BCD\u6A21\u677F\uFF0C\u7528\u4E8E AI \u5BF9\u8BDD\u80FD\u529B\u3002",
123
- onSave,
124
- onChange
125
- }) => {
126
- const baseConfig = useMemo(
127
- () => mergeConfig(DEFAULT_AI_CONFIG, initialConfig),
128
- [initialConfig]
129
- );
130
- const [config, setConfig] = useState(baseConfig);
131
- const [status, setStatus] = useState(null);
132
- const [showApiKey, setShowApiKey] = useState(false);
133
- useEffect(() => {
134
- if (typeof window === "undefined") {
135
- return;
136
- }
137
- if (!storageKey) {
138
- return;
139
- }
140
- const storedRaw = localStorage.getItem(storageKey);
141
- if (!storedRaw) {
142
- return;
143
- }
144
- try {
145
- const stored = JSON.parse(storedRaw);
146
- setConfig(mergeConfig(DEFAULT_AI_CONFIG, initialConfig, stored));
147
- } catch (error) {
148
- console.warn("[AiConfigPage] Failed to parse stored config:", error);
149
- }
150
- }, [storageKey, initialConfig]);
151
- const updateConfig = (updates) => {
152
- setConfig((prev) => {
153
- const next = { ...prev, ...updates };
154
- onChange?.(next);
155
- return next;
156
- });
157
- };
158
- const updateNumber = (key, value) => {
159
- const nextValue = Number(value);
160
- if (Number.isNaN(nextValue)) {
161
- return;
162
- }
163
- updateConfig({ [key]: nextValue });
164
- };
165
- const saveConfig = () => {
166
- if (typeof window !== "undefined" && storageKey) {
167
- try {
168
- localStorage.setItem(storageKey, JSON.stringify(config));
169
- } catch (error) {
170
- setStatus({ type: "error", text: "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u6D4F\u89C8\u5668\u5B58\u50A8\u6743\u9650\u3002" });
171
- return;
172
- }
173
- }
174
- setStatus({ type: "success", text: "\u5DF2\u4FDD\u5B58\u914D\u7F6E\u3002" });
175
- onSave?.(config);
176
- };
177
- const resetConfig = () => {
178
- const next = mergeConfig(DEFAULT_AI_CONFIG, initialConfig);
179
- setConfig(next);
180
- onChange?.(next);
181
- if (typeof window !== "undefined" && storageKey) {
182
- localStorage.removeItem(storageKey);
183
- }
184
- setStatus({ type: "success", text: "\u5DF2\u6062\u590D\u9ED8\u8BA4\u914D\u7F6E\u3002" });
185
- };
186
- return /* @__PURE__ */ React2.createElement("div", { className: "w-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm" }, /* @__PURE__ */ React2.createElement("div", { className: "flex flex-col gap-2 border-b border-slate-100 pb-4" }, /* @__PURE__ */ React2.createElement("h2", { className: "text-xl font-semibold text-slate-900" }, title), /* @__PURE__ */ React2.createElement("p", { className: "text-sm text-slate-500" }, description)), /* @__PURE__ */ React2.createElement("div", { className: "mt-6 grid gap-6" }, /* @__PURE__ */ React2.createElement("section", { className: "rounded-xl border border-slate-100 bg-slate-50/60 p-4" }, /* @__PURE__ */ React2.createElement("h3", { className: "text-sm font-semibold text-slate-700" }, "API \u4FE1\u606F"), /* @__PURE__ */ React2.createElement("div", { className: "mt-4 grid gap-4" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "text-xs font-medium text-slate-500" }, "Base URL"), /* @__PURE__ */ React2.createElement(
187
- Input,
188
- {
189
- value: config.baseUrl,
190
- onChange: (event) => updateConfig({ baseUrl: event.target.value }),
191
- placeholder: "https://api.openai.com/v1",
192
- className: "mt-2"
193
- }
194
- )), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "text-xs font-medium text-slate-500" }, "API Key"), /* @__PURE__ */ React2.createElement("div", { className: "mt-2 flex gap-2" }, /* @__PURE__ */ React2.createElement(
195
- Input,
196
- {
197
- value: config.apiKey,
198
- onChange: (event) => updateConfig({ apiKey: event.target.value }),
199
- placeholder: "sk-...",
200
- type: showApiKey ? "text" : "password"
201
- }
202
- ), /* @__PURE__ */ React2.createElement(
203
- Button,
204
- {
205
- type: "button",
206
- variant: "outline",
207
- onClick: () => setShowApiKey((prev) => !prev)
208
- },
209
- showApiKey ? "\u9690\u85CF" : "\u663E\u793A"
210
- ))), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "text-xs font-medium text-slate-500" }, "\u6A21\u578B"), /* @__PURE__ */ React2.createElement(
211
- Input,
212
- {
213
- value: config.model,
214
- onChange: (event) => updateConfig({ model: event.target.value }),
215
- placeholder: "gpt-3.5-turbo",
216
- className: "mt-2"
217
- }
218
- )))), /* @__PURE__ */ React2.createElement("section", { className: "rounded-xl border border-slate-100 bg-white p-4 shadow-sm" }, /* @__PURE__ */ React2.createElement("h3", { className: "text-sm font-semibold text-slate-700" }, "\u63D0\u793A\u8BCD\u4E0E\u4E0A\u4E0B\u6587"), /* @__PURE__ */ React2.createElement("div", { className: "mt-4 grid gap-4" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "text-xs font-medium text-slate-500" }, "\u7CFB\u7EDF\u63D0\u793A\u8BCD"), /* @__PURE__ */ React2.createElement(
219
- "textarea",
220
- {
221
- value: config.systemPrompt,
222
- onChange: (event) => updateConfig({ systemPrompt: event.target.value }),
223
- placeholder: "\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684 AI \u52A9\u624B...",
224
- className: "mt-2 min-h-[96px] w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-300"
225
- }
226
- )), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "text-xs font-medium text-slate-500" }, "\u63D0\u793A\u8BCD\u6A21\u677F"), /* @__PURE__ */ React2.createElement(
227
- "textarea",
228
- {
229
- value: config.template,
230
- onChange: (event) => updateConfig({ template: event.target.value }),
231
- placeholder: "\u8BF7\u56DE\u7B54\uFF1A{{input}}",
232
- className: "mt-2 min-h-[96px] w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-300"
233
- }
234
- ), /* @__PURE__ */ React2.createElement("p", { className: "mt-2 text-xs text-slate-400" }, "\u652F\u6301\u53D8\u91CF\u63D2\u5165\uFF1A", /* @__PURE__ */ React2.createElement("code", { className: "rounded bg-slate-100 px-1" }, "{{input}}"))))), /* @__PURE__ */ React2.createElement("section", { className: "rounded-xl border border-slate-100 bg-slate-50/60 p-4" }, /* @__PURE__ */ React2.createElement("h3", { className: "text-sm font-semibold text-slate-700" }, "\u6A21\u578B\u53C2\u6570"), /* @__PURE__ */ React2.createElement("div", { className: "mt-4 grid gap-4 md:grid-cols-3" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "text-xs font-medium text-slate-500" }, "Temperature"), /* @__PURE__ */ React2.createElement(
235
- Input,
236
- {
237
- type: "number",
238
- value: config.temperature,
239
- onChange: (event) => updateNumber("temperature", event.target.value),
240
- className: "mt-2"
241
- }
242
- )), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "text-xs font-medium text-slate-500" }, "Top P"), /* @__PURE__ */ React2.createElement(
243
- Input,
244
- {
245
- type: "number",
246
- value: config.topP,
247
- onChange: (event) => updateNumber("topP", event.target.value),
248
- className: "mt-2"
249
- }
250
- )), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "text-xs font-medium text-slate-500" }, "Max Tokens"), /* @__PURE__ */ React2.createElement(
251
- Input,
252
- {
253
- type: "number",
254
- value: config.maxTokens,
255
- onChange: (event) => updateNumber("maxTokens", event.target.value),
256
- className: "mt-2"
257
- }
258
- )))), /* @__PURE__ */ React2.createElement("div", { className: "flex flex-wrap items-center gap-3" }, /* @__PURE__ */ React2.createElement(Button, { onClick: saveConfig }, "\u4FDD\u5B58\u914D\u7F6E"), /* @__PURE__ */ React2.createElement(Button, { variant: "outline", onClick: resetConfig }, "\u6062\u590D\u9ED8\u8BA4"), status && /* @__PURE__ */ React2.createElement(
259
- "span",
260
- {
261
- className: cn(
262
- "text-xs",
263
- status.type === "success" ? "text-emerald-600" : "text-rose-600"
264
- )
265
- },
266
- status.text
267
- ))));
268
- };
269
-
270
- export { AiChatDialog, AiConfigPage };
271
- //# sourceMappingURL=chunk-IJIQUMAK.mjs.map
272
- //# sourceMappingURL=chunk-IJIQUMAK.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/common/ai/llm/ui/web/components/AiChatDialog.tsx","../src/common/ai/llm/ui/web/components/AiConfigPage.tsx"],"names":["React","useMemo","useState","useEffect"],"mappings":"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","file":"chunk-IJIQUMAK.mjs","sourcesContent":["'use client';\n\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { Button } from '../../../../../components/Button';\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '../../../../../components/Dialog';\nimport { cn } from '../../../../../utils/cn';\nimport { useAiChat } from '../../../hooks/useAiChat';\nimport type { AiChatDialogProps } from '../../types';\n\ntype WebAiChatDialogProps = AiChatDialogProps & {\n className?: string;\n contentClassName?: string;\n};\n\nexport const AiChatDialog: React.FC<WebAiChatDialogProps> = ({\n open,\n onOpenChange,\n client,\n title = 'AI 对话',\n placeholder = '输入你想咨询的问题...',\n systemPrompt,\n template,\n templateVariables,\n initialMessages,\n requestOptions,\n onResponse,\n onError,\n className,\n contentClassName,\n}) => {\n const { messages, sendMessage, isLoading, error } = useAiChat({\n client,\n systemPrompt,\n template,\n initialMessages,\n });\n const [input, setInput] = useState('');\n const listRef = useRef<HTMLDivElement>(null);\n\n const hasMessages = messages.length > 0;\n const helperText = useMemo(() => {\n return template ? '模板已启用,支持 {{input}} 变量。' : '直接输入即可开始对话。';\n }, [template]);\n\n useEffect(() => {\n if (!listRef.current) return;\n listRef.current.scrollTop = listRef.current.scrollHeight;\n }, [messages, open, isLoading]);\n\n const handleSend = async () => {\n const content = input.trim();\n if (!content || isLoading) return;\n setInput('');\n try {\n const response = await sendMessage(content, {\n ...requestOptions,\n template,\n variables: templateVariables,\n });\n onResponse?.(response);\n } catch (err) {\n const nextError = err instanceof Error ? err : new Error(String(err));\n onError?.(nextError);\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n handleSend();\n }\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n className={cn(\n 'max-w-3xl border border-slate-200 bg-white p-0',\n contentClassName\n )}\n >\n <div className={cn('flex flex-col', className)}>\n <DialogHeader className=\"border-b border-slate-100 px-6 py-4\">\n <DialogTitle className=\"text-base font-semibold text-slate-900\">{title}</DialogTitle>\n </DialogHeader>\n\n <div className=\"flex flex-1 flex-col gap-4 px-6 py-4\">\n <div\n ref={listRef}\n className=\"max-h-[60vh] min-h-[240px] overflow-y-auto rounded-xl border border-slate-100 bg-slate-50/60 p-4\"\n >\n {!hasMessages && (\n <div className=\"flex h-full flex-col items-center justify-center gap-2 text-sm text-slate-400\">\n <span>暂无对话内容</span>\n <span>输入消息开始体验 AI 对话。</span>\n </div>\n )}\n <div className=\"flex flex-col gap-3\">\n {messages.map((message, index) => {\n const isUser = message.role === 'user';\n return (\n <div\n key={`${message.role}-${index}`}\n className={cn(\n 'max-w-[85%] whitespace-pre-wrap rounded-2xl px-4 py-2 text-sm leading-relaxed',\n isUser\n ? 'ml-auto bg-slate-900 text-white'\n : 'mr-auto border border-slate-200 bg-white text-slate-800'\n )}\n >\n {message.content}\n </div>\n );\n })}\n {isLoading && (\n <div className=\"mr-auto max-w-[70%] rounded-2xl border border-slate-200 bg-white px-4 py-2 text-sm text-slate-500\">\n AI 正在思考...\n </div>\n )}\n </div>\n </div>\n\n <div className=\"rounded-xl border border-slate-100 bg-white p-4 shadow-sm\">\n <textarea\n value={input}\n onChange={(event) => setInput(event.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"min-h-[96px] w-full resize-none rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-300\"\n />\n <div className=\"mt-3 flex flex-wrap items-center justify-between gap-3\">\n <span className=\"text-xs text-slate-400\">{helperText}</span>\n <Button onClick={handleSend} disabled={!input.trim() || isLoading}>\n {isLoading ? '发送中...' : '发送'}\n </Button>\n </div>\n {error && (\n <div className=\"mt-2 rounded-md border border-rose-200 bg-rose-50 px-3 py-2 text-xs text-rose-600\">\n {error.message || '对话出错,请重试。'}\n </div>\n )}\n </div>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n};\n","'use client';\n\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { Button } from '../../../../../components/Button';\nimport { Input } from '../../../../../components/Input';\nimport { cn } from '../../../../../utils/cn';\nimport type { AiConfigPageProps, AiUiConfig } from '../../types';\n\nconst DEFAULT_AI_CONFIG: AiUiConfig = {\n apiKey: '',\n baseUrl: 'https://api.openai.com/v1',\n model: 'gpt-3.5-turbo',\n systemPrompt: '',\n template: '{{input}}',\n temperature: 0.7,\n topP: 1,\n maxTokens: 1024,\n};\n\nconst mergeConfig = (\n base: AiUiConfig,\n overrides?: Partial<AiUiConfig>,\n stored?: Partial<AiUiConfig>\n): AiUiConfig => {\n return {\n ...base,\n ...(overrides ?? {}),\n ...(stored ?? {}),\n };\n};\n\nexport const AiConfigPage: React.FC<AiConfigPageProps> = ({\n storageKey = 'sa2kit-ai-config',\n initialConfig,\n title = 'AI 配置',\n description = '配置 API Key、模型与提示词模板,用于 AI 对话能力。',\n onSave,\n onChange,\n}) => {\n const baseConfig = useMemo(\n () => mergeConfig(DEFAULT_AI_CONFIG, initialConfig),\n [initialConfig]\n );\n const [config, setConfig] = useState<AiUiConfig>(baseConfig);\n const [status, setStatus] = useState<{ type: 'success' | 'error'; text: string } | null>(null);\n const [showApiKey, setShowApiKey] = useState(false);\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n if (!storageKey) {\n return;\n }\n const storedRaw = localStorage.getItem(storageKey);\n if (!storedRaw) {\n return;\n }\n try {\n const stored = JSON.parse(storedRaw) as Partial<AiUiConfig>;\n setConfig(mergeConfig(DEFAULT_AI_CONFIG, initialConfig, stored));\n } catch (error) {\n console.warn('[AiConfigPage] Failed to parse stored config:', error);\n }\n }, [storageKey, initialConfig]);\n\n const updateConfig = (updates: Partial<AiUiConfig>) => {\n setConfig((prev) => {\n const next = { ...prev, ...updates };\n onChange?.(next);\n return next;\n });\n };\n\n const updateNumber = (key: keyof AiUiConfig, value: string) => {\n const nextValue = Number(value);\n if (Number.isNaN(nextValue)) {\n return;\n }\n updateConfig({ [key]: nextValue } as Partial<AiUiConfig>);\n };\n\n const saveConfig = () => {\n if (typeof window !== 'undefined' && storageKey) {\n try {\n localStorage.setItem(storageKey, JSON.stringify(config));\n } catch (error) {\n setStatus({ type: 'error', text: '保存失败,请检查浏览器存储权限。' });\n return;\n }\n }\n setStatus({ type: 'success', text: '已保存配置。' });\n onSave?.(config);\n };\n\n const resetConfig = () => {\n const next = mergeConfig(DEFAULT_AI_CONFIG, initialConfig);\n setConfig(next);\n onChange?.(next);\n if (typeof window !== 'undefined' && storageKey) {\n localStorage.removeItem(storageKey);\n }\n setStatus({ type: 'success', text: '已恢复默认配置。' });\n };\n\n return (\n <div className=\"w-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm\">\n <div className=\"flex flex-col gap-2 border-b border-slate-100 pb-4\">\n <h2 className=\"text-xl font-semibold text-slate-900\">{title}</h2>\n <p className=\"text-sm text-slate-500\">{description}</p>\n </div>\n\n <div className=\"mt-6 grid gap-6\">\n <section className=\"rounded-xl border border-slate-100 bg-slate-50/60 p-4\">\n <h3 className=\"text-sm font-semibold text-slate-700\">API 信息</h3>\n <div className=\"mt-4 grid gap-4\">\n <div>\n <label className=\"text-xs font-medium text-slate-500\">Base URL</label>\n <Input\n value={config.baseUrl}\n onChange={(event) => updateConfig({ baseUrl: event.target.value })}\n placeholder=\"https://api.openai.com/v1\"\n className=\"mt-2\"\n />\n </div>\n <div>\n <label className=\"text-xs font-medium text-slate-500\">API Key</label>\n <div className=\"mt-2 flex gap-2\">\n <Input\n value={config.apiKey}\n onChange={(event) => updateConfig({ apiKey: event.target.value })}\n placeholder=\"sk-...\"\n type={showApiKey ? 'text' : 'password'}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setShowApiKey((prev) => !prev)}\n >\n {showApiKey ? '隐藏' : '显示'}\n </Button>\n </div>\n </div>\n <div>\n <label className=\"text-xs font-medium text-slate-500\">模型</label>\n <Input\n value={config.model}\n onChange={(event) => updateConfig({ model: event.target.value })}\n placeholder=\"gpt-3.5-turbo\"\n className=\"mt-2\"\n />\n </div>\n </div>\n </section>\n\n <section className=\"rounded-xl border border-slate-100 bg-white p-4 shadow-sm\">\n <h3 className=\"text-sm font-semibold text-slate-700\">提示词与上下文</h3>\n <div className=\"mt-4 grid gap-4\">\n <div>\n <label className=\"text-xs font-medium text-slate-500\">系统提示词</label>\n <textarea\n value={config.systemPrompt}\n onChange={(event) => updateConfig({ systemPrompt: event.target.value })}\n placeholder=\"你是一个专业的 AI 助手...\"\n className=\"mt-2 min-h-[96px] w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-300\"\n />\n </div>\n <div>\n <label className=\"text-xs font-medium text-slate-500\">提示词模板</label>\n <textarea\n value={config.template}\n onChange={(event) => updateConfig({ template: event.target.value })}\n placeholder=\"请回答:{{input}}\"\n className=\"mt-2 min-h-[96px] w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-300\"\n />\n <p className=\"mt-2 text-xs text-slate-400\">\n 支持变量插入:<code className=\"rounded bg-slate-100 px-1\">{\"{{input}}\"}</code>\n </p>\n </div>\n </div>\n </section>\n\n <section className=\"rounded-xl border border-slate-100 bg-slate-50/60 p-4\">\n <h3 className=\"text-sm font-semibold text-slate-700\">模型参数</h3>\n <div className=\"mt-4 grid gap-4 md:grid-cols-3\">\n <div>\n <label className=\"text-xs font-medium text-slate-500\">Temperature</label>\n <Input\n type=\"number\"\n value={config.temperature}\n onChange={(event) => updateNumber('temperature', event.target.value)}\n className=\"mt-2\"\n />\n </div>\n <div>\n <label className=\"text-xs font-medium text-slate-500\">Top P</label>\n <Input\n type=\"number\"\n value={config.topP}\n onChange={(event) => updateNumber('topP', event.target.value)}\n className=\"mt-2\"\n />\n </div>\n <div>\n <label className=\"text-xs font-medium text-slate-500\">Max Tokens</label>\n <Input\n type=\"number\"\n value={config.maxTokens}\n onChange={(event) => updateNumber('maxTokens', event.target.value)}\n className=\"mt-2\"\n />\n </div>\n </div>\n </section>\n\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button onClick={saveConfig}>保存配置</Button>\n <Button variant=\"outline\" onClick={resetConfig}>\n 恢复默认\n </Button>\n {status && (\n <span\n className={cn(\n 'text-xs',\n status.type === 'success' ? 'text-emerald-600' : 'text-rose-600'\n )}\n >\n {status.text}\n </span>\n )}\n </div>\n </div>\n </div>\n );\n};\n"]}