st-comp 0.0.253 → 0.0.255
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/es/VarietyAiHelper.cjs +5 -4
- package/es/VarietyAiHelper.js +281 -233
- package/es/aiTools.js +59 -18
- package/es/style.css +1 -1
- package/lib/aiTools.js +59 -18
- package/lib/bundle.js +1 -1
- package/lib/bundle.umd.cjs +54 -53
- package/lib/{index-0dab5f01.js → index-73a5aa87.js} +1993 -1945
- package/lib/{python-1a46034d.js → python-8821365d.js} +1 -1
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/VarietyAiHelper/index.vue +58 -9
- package/public/aiTools.js +59 -18
package/package.json
CHANGED
|
@@ -77,7 +77,7 @@ const handleFeedbackAction = async (action, messageIndex) => {
|
|
|
77
77
|
type: 2,
|
|
78
78
|
resTime: message.resTime,
|
|
79
79
|
createTime: message.createTime,
|
|
80
|
-
firstPackageTime: message.firstPackageTime
|
|
80
|
+
firstPackageTime: message.firstPackageTime,
|
|
81
81
|
};
|
|
82
82
|
await stConfig.request.post("/alarm/deliversign/addVarietyAiHelperLog", params);
|
|
83
83
|
ElMessage.success("感谢您的反馈!我们将持续跟踪并进行优化");
|
|
@@ -96,7 +96,7 @@ const handleFeedbackAction = async (action, messageIndex) => {
|
|
|
96
96
|
type: null,
|
|
97
97
|
resTime: message.resTime,
|
|
98
98
|
createTime: message.createTime,
|
|
99
|
-
firstPackageTime: message.firstPackageTime
|
|
99
|
+
firstPackageTime: message.firstPackageTime,
|
|
100
100
|
};
|
|
101
101
|
await stConfig.request.post("/alarm/deliversign/addVarietyAiHelperLog", params);
|
|
102
102
|
}
|
|
@@ -144,7 +144,31 @@ const sendMessage = async () => {
|
|
|
144
144
|
apiKey,
|
|
145
145
|
value: content,
|
|
146
146
|
callback: (type, data) => {
|
|
147
|
-
|
|
147
|
+
// 百炼应用错误
|
|
148
|
+
if (type === "error") {
|
|
149
|
+
isThinking.value = false;
|
|
150
|
+
isSending.value = false;
|
|
151
|
+
|
|
152
|
+
// 移除占位的AI消息
|
|
153
|
+
messages.value.pop();
|
|
154
|
+
|
|
155
|
+
// 添加错误提示消息
|
|
156
|
+
messages.value.push({
|
|
157
|
+
role: "assistant",
|
|
158
|
+
userContent: content,
|
|
159
|
+
content: `❌ ${data}`,
|
|
160
|
+
showFeedback: false,
|
|
161
|
+
hasFeedback: false,
|
|
162
|
+
createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
|
163
|
+
resTime: new Date().getTime() - resTime,
|
|
164
|
+
firstPackageTime: 0,
|
|
165
|
+
});
|
|
166
|
+
handleFeedbackAction("default", messages.value.length - 1);
|
|
167
|
+
scrollToBottom();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// 流式输出(正常)
|
|
171
|
+
else if (type === "message") {
|
|
148
172
|
fullResponse += data;
|
|
149
173
|
// 直接更新最后一条AI消息
|
|
150
174
|
const lastMessage = messages.value[messages.value.length - 1];
|
|
@@ -156,12 +180,14 @@ const sendMessage = async () => {
|
|
|
156
180
|
if (lastMessage.firstPackageTime === 0) {
|
|
157
181
|
lastMessage.firstPackageTime = new Date().getTime() - resTime;
|
|
158
182
|
}
|
|
159
|
-
}
|
|
183
|
+
}
|
|
184
|
+
// 流式输出(完毕)
|
|
185
|
+
else if (type === "finish") {
|
|
160
186
|
isThinking.value = false;
|
|
161
187
|
isSending.value = false;
|
|
188
|
+
const lastMessage = messages.value[messages.value.length - 1];
|
|
162
189
|
|
|
163
190
|
// 显示反馈按钮
|
|
164
|
-
const lastMessage = messages.value[messages.value.length - 1];
|
|
165
191
|
if (lastMessage && lastMessage.role === "assistant") {
|
|
166
192
|
lastMessage.showFeedback = true;
|
|
167
193
|
lastMessage.resTime = new Date().getTime() - resTime;
|
|
@@ -186,7 +212,7 @@ const sendMessage = async () => {
|
|
|
186
212
|
messages.value.push({
|
|
187
213
|
role: "assistant",
|
|
188
214
|
userContent: content,
|
|
189
|
-
content: "抱歉,AI服务响应异常,请稍后重试。",
|
|
215
|
+
content: "❌ 抱歉,AI服务响应异常,请稍后重试。",
|
|
190
216
|
showFeedback: true,
|
|
191
217
|
hasFeedback: false,
|
|
192
218
|
createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
|
@@ -199,6 +225,29 @@ const sendMessage = async () => {
|
|
|
199
225
|
isThinking.value = false;
|
|
200
226
|
}
|
|
201
227
|
};
|
|
228
|
+
|
|
229
|
+
// 处理键盘事件:Ctrl+Enter 换行,Enter 发送
|
|
230
|
+
const handleKeydown = (event) => {
|
|
231
|
+
if (event.key === "Enter") {
|
|
232
|
+
if (event.ctrlKey) {
|
|
233
|
+
// Ctrl + Enter: 插入换行符
|
|
234
|
+
event.preventDefault();
|
|
235
|
+
const textarea = event.target;
|
|
236
|
+
const start = textarea.selectionStart;
|
|
237
|
+
const end = textarea.selectionEnd;
|
|
238
|
+
inputMessage.value = inputMessage.value.substring(0, start) + "\n" + inputMessage.value.substring(end);
|
|
239
|
+
// 将光标移动到新插入的换行符之后
|
|
240
|
+
nextTick(() => {
|
|
241
|
+
textarea.selectionStart = textarea.selectionEnd = start + 1;
|
|
242
|
+
});
|
|
243
|
+
} else {
|
|
244
|
+
// 单独的 Enter: 发送消息
|
|
245
|
+
event.preventDefault();
|
|
246
|
+
sendMessage();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
202
251
|
// 滚动到底部
|
|
203
252
|
const scrollToBottom = async () => {
|
|
204
253
|
await nextTick();
|
|
@@ -317,12 +366,12 @@ defineExpose({
|
|
|
317
366
|
type="textarea"
|
|
318
367
|
:rows="4"
|
|
319
368
|
:autosize="{ minRows: 2, maxRows: 4 }"
|
|
320
|
-
placeholder="输入您想查询的品种条件..."
|
|
321
|
-
@keydown
|
|
369
|
+
placeholder="输入您想查询的品种条件... (Ctrl+Enter换行,Enter发送)"
|
|
370
|
+
@keydown="handleKeydown"
|
|
322
371
|
/>
|
|
323
372
|
<div class="input-actions">
|
|
324
373
|
<div class="input-hint">
|
|
325
|
-
<span>Ctrl + Enter
|
|
374
|
+
<span>Enter 发送 | Ctrl + Enter 换行</span>
|
|
326
375
|
</div>
|
|
327
376
|
<el-button
|
|
328
377
|
class="send-btn"
|
package/public/aiTools.js
CHANGED
|
@@ -27,7 +27,7 @@ export const sendToBaiLianAppNonStreaming = async ({ appId, apiKey, value }) =>
|
|
|
27
27
|
throw error;
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
|
-
// 流式返回
|
|
30
|
+
// 流式返回 - 支持错误处理
|
|
31
31
|
export const sendToBaiLianAppStreaming = async ({ appId, apiKey, value, callback }) => {
|
|
32
32
|
try {
|
|
33
33
|
const response = await fetch(`https://dashscope.aliyuncs.com/api/v1/apps/${appId}/completion`, {
|
|
@@ -43,13 +43,17 @@ export const sendToBaiLianAppStreaming = async ({ appId, apiKey, value, callback
|
|
|
43
43
|
"X-DashScope-SSE": "enable",
|
|
44
44
|
},
|
|
45
45
|
});
|
|
46
|
-
|
|
47
|
-
if (!response.ok)
|
|
48
|
-
|
|
46
|
+
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
callback("error", `HTTP ${response.status}: ${response.statusText}`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
49
52
|
const reader = response.body.getReader();
|
|
50
53
|
const decoder = new TextDecoder();
|
|
51
54
|
let buffer = "";
|
|
52
|
-
|
|
55
|
+
let currentEvent = null; // 记录当前 event 类型
|
|
56
|
+
|
|
53
57
|
while (true) {
|
|
54
58
|
const { done, value } = await reader.read();
|
|
55
59
|
if (done) {
|
|
@@ -60,28 +64,48 @@ export const sendToBaiLianAppStreaming = async ({ appId, apiKey, value, callback
|
|
|
60
64
|
callback("finish", "");
|
|
61
65
|
break;
|
|
62
66
|
}
|
|
63
|
-
|
|
67
|
+
|
|
64
68
|
buffer += decoder.decode(value, { stream: true });
|
|
65
|
-
|
|
69
|
+
|
|
66
70
|
let newlineIndex;
|
|
67
71
|
while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
|
|
68
72
|
const line = buffer.substring(0, newlineIndex).trim();
|
|
69
73
|
buffer = buffer.substring(newlineIndex + 1);
|
|
70
|
-
|
|
74
|
+
|
|
75
|
+
// 处理 event: 行(错误类型)
|
|
76
|
+
if (line.startsWith("event:")) {
|
|
77
|
+
currentEvent = line.substring(6).trim();
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 处理 data: 行
|
|
71
82
|
if (line.startsWith("data:")) {
|
|
72
|
-
const
|
|
73
|
-
|
|
83
|
+
const dataStr = line.substring(5).trim();
|
|
84
|
+
|
|
85
|
+
// 检查是否是错误响应
|
|
86
|
+
if (currentEvent === "error" || (dataStr && dataStr.startsWith("{"))) {
|
|
74
87
|
try {
|
|
75
|
-
const parsed = JSON.parse(
|
|
88
|
+
const parsed = JSON.parse(dataStr);
|
|
89
|
+
|
|
90
|
+
// 处理错误响应
|
|
91
|
+
if (parsed.code || parsed.message || currentEvent === "error") {
|
|
92
|
+
const errorMsg = parsed.message || parsed.code || "未知错误";
|
|
93
|
+
callback("error", `百炼服务端错误: ${errorMsg}`);
|
|
94
|
+
return; // 终止流式处理
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 正常响应:提取 text
|
|
76
98
|
const text = parsed?.output?.text;
|
|
77
99
|
if (text && callback) {
|
|
78
100
|
callback("message", text);
|
|
79
101
|
}
|
|
80
102
|
} catch (e) {
|
|
81
|
-
|
|
82
|
-
console.debug("等待完整数据...");
|
|
103
|
+
console.debug("JSON 解析失败:", dataStr);
|
|
83
104
|
}
|
|
84
105
|
}
|
|
106
|
+
|
|
107
|
+
// 重置 event 类型
|
|
108
|
+
currentEvent = null;
|
|
85
109
|
}
|
|
86
110
|
}
|
|
87
111
|
}
|
|
@@ -92,18 +116,35 @@ export const sendToBaiLianAppStreaming = async ({ appId, apiKey, value, callback
|
|
|
92
116
|
};
|
|
93
117
|
|
|
94
118
|
// 辅助函数:处理缓冲区剩余数据
|
|
95
|
-
|
|
119
|
+
const tryProcessBuffer = (buffer, callback) => {
|
|
96
120
|
const lines = buffer.split("\n");
|
|
121
|
+
let currentEvent = null;
|
|
122
|
+
|
|
97
123
|
for (const line of lines) {
|
|
124
|
+
if (line.startsWith("event:")) {
|
|
125
|
+
currentEvent = line.substring(6).trim();
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
|
|
98
129
|
if (line.startsWith("data:")) {
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
130
|
+
const dataStr = line.substring(5).trim();
|
|
131
|
+
if (dataStr && dataStr !== "[DONE]") {
|
|
101
132
|
try {
|
|
102
|
-
const parsed = JSON.parse(
|
|
133
|
+
const parsed = JSON.parse(dataStr);
|
|
134
|
+
|
|
135
|
+
// 错误响应
|
|
136
|
+
if (currentEvent === "error" || parsed.code || parsed.message) {
|
|
137
|
+
const errorMsg = parsed.message || parsed.code || "未知错误";
|
|
138
|
+
callback("error", `百炼服务端错误: ${errorMsg}`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// 正常响应
|
|
103
143
|
const text = parsed?.output?.text;
|
|
104
144
|
if (text && callback) callback("message", text);
|
|
105
145
|
} catch (e) {}
|
|
106
146
|
}
|
|
147
|
+
currentEvent = null;
|
|
107
148
|
}
|
|
108
149
|
}
|
|
109
|
-
}
|
|
150
|
+
};
|