st-comp 0.0.270 → 0.0.271
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 +3 -3
- package/es/VarietyAiHelper.js +3 -3
- package/es/VarietySearch.cjs +18 -18
- package/es/VarietySearch.js +1826 -1821
- package/es/aiTools-4412c56c.cjs +2 -0
- package/es/aiTools-e6e4e996.js +111 -0
- package/es/aiTools.js +102 -275
- package/es/style.css +1 -1
- package/lib/aiTools.js +102 -275
- package/lib/bundle.js +1 -1
- package/lib/bundle.umd.cjs +197 -199
- package/lib/{index-2dd72fda.js → index-15c834c8.js} +16876 -16909
- package/lib/{python-126b61c5.js → python-dcd40798.js} +1 -1
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/VarietyAiHelper/index.vue +0 -3
- package/packages/VarietySearch/components/FactorScreen/index.vue +38 -25
- package/public/aiTools.js +102 -275
- package/src/App.vue +3 -3
- package/src/pages/VarietySearch/index.vue +264 -82
- package/es/aiTools-275c9799.cjs +0 -4
- package/es/aiTools-9c59a74a.js +0 -149
package/lib/aiTools.js
CHANGED
|
@@ -1,307 +1,93 @@
|
|
|
1
|
-
// 辅助函数:处理缓冲区剩余数据
|
|
2
|
-
const tryProcessBuffer = (buffer, callback) => {
|
|
3
|
-
const lines = buffer.split("\n");
|
|
4
|
-
let currentEvent = null;
|
|
5
|
-
|
|
6
|
-
for (const line of lines) {
|
|
7
|
-
if (line.startsWith("event:")) {
|
|
8
|
-
currentEvent = line.substring(6).trim();
|
|
9
|
-
continue;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
if (line.startsWith("data:")) {
|
|
13
|
-
const dataStr = line.substring(5).trim();
|
|
14
|
-
if (dataStr && dataStr !== "[DONE]") {
|
|
15
|
-
try {
|
|
16
|
-
const parsed = JSON.parse(dataStr);
|
|
17
|
-
|
|
18
|
-
// 错误响应
|
|
19
|
-
if (currentEvent === "error" || parsed.code || parsed.message) {
|
|
20
|
-
const errorMsg = parsed.message || parsed.code || "未知错误";
|
|
21
|
-
callback("error", `百炼服务端错误: ${errorMsg}`);
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// 正常响应
|
|
26
|
-
const text = parsed?.output?.text;
|
|
27
|
-
if (text && callback) callback("message", text);
|
|
28
|
-
} catch (e) {}
|
|
29
|
-
}
|
|
30
|
-
currentEvent = null;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
|
|
35
1
|
/**
|
|
36
|
-
* @description:
|
|
2
|
+
* @description: 通用 SSE 流式请求
|
|
3
|
+
* @param {Object} params
|
|
4
|
+
* @param {string} params.baseUrl - 服务地址
|
|
5
|
+
* @param {string} params.path - 接口路径
|
|
6
|
+
* @param {string} params.token - 认证token
|
|
7
|
+
* @param {string} params.value - 查询内容
|
|
8
|
+
* @param {string} params.origin - 来源标识,默认 "web"
|
|
9
|
+
* @param {Function} params.getSSE - 回调函数 (type, str) => void
|
|
10
|
+
* type: "finish" || "error" || "message"
|
|
37
11
|
*/
|
|
38
|
-
|
|
39
|
-
export const sendToBaiLianAppNonStreaming = async ({ appId, apiKey, value }) => {
|
|
12
|
+
const sendToNodeSSE = async ({ baseUrl, path, token, value, origin = "web", getSSE }) => {
|
|
40
13
|
try {
|
|
41
|
-
|
|
14
|
+
// 创建请求
|
|
15
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
42
16
|
method: "POST",
|
|
43
17
|
headers: {
|
|
44
|
-
Authorization: `Bearer ${apiKey}`,
|
|
45
18
|
"Content-Type": "application/json",
|
|
19
|
+
token,
|
|
46
20
|
},
|
|
47
21
|
body: JSON.stringify({
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
},
|
|
52
|
-
}),
|
|
53
|
-
});
|
|
54
|
-
if (!response.ok) {
|
|
55
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
56
|
-
}
|
|
57
|
-
const data = await response.json();
|
|
58
|
-
const outputText = data?.output?.text;
|
|
59
|
-
return outputText;
|
|
60
|
-
} catch (error) {
|
|
61
|
-
if (error.name === "AbortError") {
|
|
62
|
-
throw new Error("请求超时");
|
|
63
|
-
}
|
|
64
|
-
throw error;
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
// 百炼应用(流式)
|
|
68
|
-
export const sendToBaiLianAppStreaming = async ({ appId, apiKey, value, callback }) => {
|
|
69
|
-
try {
|
|
70
|
-
const response = await fetch(`https://dashscope.aliyuncs.com/api/v1/apps/${appId}/completion`, {
|
|
71
|
-
method: "POST",
|
|
72
|
-
body: JSON.stringify({
|
|
73
|
-
input: { prompt: value },
|
|
74
|
-
parameters: { incremental_output: "true" },
|
|
75
|
-
debug: {},
|
|
22
|
+
query: value,
|
|
23
|
+
origin,
|
|
24
|
+
stream: true,
|
|
76
25
|
}),
|
|
77
|
-
headers: {
|
|
78
|
-
Authorization: `Bearer ${apiKey}`,
|
|
79
|
-
"Content-Type": "application/json",
|
|
80
|
-
"X-DashScope-SSE": "enable",
|
|
81
|
-
},
|
|
82
26
|
});
|
|
83
|
-
|
|
84
27
|
if (!response.ok) {
|
|
85
|
-
|
|
28
|
+
getSSE("error", `HTTP ${response.status}: ${response.statusText}`);
|
|
86
29
|
return;
|
|
87
30
|
}
|
|
88
31
|
|
|
32
|
+
// 创建reader读取器和decoder解码器
|
|
89
33
|
const reader = response.body.getReader();
|
|
90
34
|
const decoder = new TextDecoder();
|
|
91
|
-
let buffer = "";
|
|
92
|
-
let currentEvent = null; // 记录当前 event 类型
|
|
93
|
-
|
|
94
|
-
while (true) {
|
|
95
|
-
const { done, value } = await reader.read();
|
|
96
|
-
if (done) {
|
|
97
|
-
// 处理最后可能遗留的数据
|
|
98
|
-
if (buffer.trim()) {
|
|
99
|
-
tryProcessBuffer(buffer, callback);
|
|
100
|
-
}
|
|
101
|
-
callback("finish", "");
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
buffer += decoder.decode(value, { stream: true });
|
|
106
35
|
|
|
107
|
-
|
|
108
|
-
while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
|
|
109
|
-
const line = buffer.substring(0, newlineIndex).trim();
|
|
110
|
-
buffer = buffer.substring(newlineIndex + 1);
|
|
111
|
-
|
|
112
|
-
// 处理 event: 行(错误类型)
|
|
113
|
-
if (line.startsWith("event:")) {
|
|
114
|
-
currentEvent = line.substring(6).trim();
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// 处理 data: 行
|
|
119
|
-
if (line.startsWith("data:")) {
|
|
120
|
-
const dataStr = line.substring(5).trim();
|
|
121
|
-
|
|
122
|
-
// 检查是否是错误响应
|
|
123
|
-
if (currentEvent === "error" || (dataStr && dataStr.startsWith("{"))) {
|
|
124
|
-
try {
|
|
125
|
-
const parsed = JSON.parse(dataStr);
|
|
126
|
-
|
|
127
|
-
// 处理错误响应
|
|
128
|
-
if (parsed.code || parsed.message || currentEvent === "error") {
|
|
129
|
-
const errorMsg = parsed.message || parsed.code || "未知错误";
|
|
130
|
-
callback("error", `百炼服务端错误: ${errorMsg}`);
|
|
131
|
-
return; // 终止流式处理
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// 正常响应:提取 text
|
|
135
|
-
const text = parsed?.output?.text;
|
|
136
|
-
if (text && callback) {
|
|
137
|
-
callback("message", text);
|
|
138
|
-
}
|
|
139
|
-
} catch (e) {
|
|
140
|
-
console.debug("JSON 解析失败:", dataStr);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// 重置 event 类型
|
|
145
|
-
currentEvent = null;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
} catch (error) {
|
|
150
|
-
console.error("流式请求失败:", error);
|
|
151
|
-
callback("error", error.message);
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
// 百炼workflow(流式)
|
|
155
|
-
export const sendToBaiLianWorkflowStreaming = async ({ mode, appId, apiKey, token, value, callback }) => {
|
|
156
|
-
try {
|
|
157
|
-
const response = await fetch(`https://dashscope.aliyuncs.com/api/v1/apps/${appId}/completion`, {
|
|
158
|
-
method: "POST",
|
|
159
|
-
body: JSON.stringify({
|
|
160
|
-
input: { prompt: value, biz_params: { token, mode, origin: "web" } },
|
|
161
|
-
parameters: { incremental_output: "true", flow_stream_mode: "message_format_plus" },
|
|
162
|
-
debug: {},
|
|
163
|
-
}),
|
|
164
|
-
headers: {
|
|
165
|
-
Authorization: `Bearer ${apiKey}`,
|
|
166
|
-
"Content-Type": "application/json",
|
|
167
|
-
"X-DashScope-SSE": "enable",
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
if (!response.ok) {
|
|
172
|
-
callback("error", `HTTP ${response.status}: ${response.statusText}`);
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const reader = response.body.getReader();
|
|
177
|
-
const decoder = new TextDecoder();
|
|
36
|
+
// 缓冲区数据
|
|
178
37
|
let buffer = "";
|
|
179
|
-
let
|
|
180
|
-
// 记录已出现的节点(去重用)
|
|
181
|
-
const nodeMap = {};
|
|
38
|
+
let newlineIndex;
|
|
182
39
|
|
|
183
40
|
while (true) {
|
|
184
41
|
const { done, value } = await reader.read();
|
|
42
|
+
// 判断SSE是否传输结束
|
|
185
43
|
if (done) {
|
|
186
|
-
|
|
187
|
-
callback("message", finalResult);
|
|
188
|
-
}
|
|
189
|
-
callback("finish", "");
|
|
44
|
+
getSSE("finish");
|
|
190
45
|
break;
|
|
191
46
|
}
|
|
192
|
-
|
|
47
|
+
// 缓冲区填入数据
|
|
193
48
|
buffer += decoder.decode(value, { stream: true });
|
|
194
49
|
let newlineIndex;
|
|
50
|
+
// 从缓冲区中逐条提取完整的消息行
|
|
195
51
|
while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
|
|
52
|
+
// 提取一行
|
|
196
53
|
const line = buffer.substring(0, newlineIndex).trim();
|
|
54
|
+
// 移除已提取的部分
|
|
197
55
|
buffer = buffer.substring(newlineIndex + 1);
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const dataStr = line.substring(
|
|
56
|
+
if (line.startsWith("data: ")) {
|
|
57
|
+
// 切割掉前面的data: , 总计6个字符, 并且去除空格
|
|
58
|
+
const dataStr = line.substring(6).trim();
|
|
59
|
+
// 过滤空数据, 和结束标记
|
|
201
60
|
if (!dataStr || dataStr === "[DONE]") continue;
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
const parsed = JSON.parse(dataStr);
|
|
205
|
-
const output = parsed?.output;
|
|
206
|
-
const wfMsg = output?.workflow_message;
|
|
207
|
-
|
|
208
|
-
// 提取节点信息
|
|
209
|
-
if (wfMsg?.node_name && wfMsg?.node_type) {
|
|
210
|
-
const nodeName = wfMsg.node_name;
|
|
211
|
-
const nodeStatus = wfMsg.node_status; // "executing" | "success"
|
|
212
|
-
const isCompleted = wfMsg.node_is_completed;
|
|
213
|
-
|
|
214
|
-
// 去重:同一节点只推送状态变化
|
|
215
|
-
const prevStatus = nodeMap[nodeName];
|
|
216
|
-
if (prevStatus !== nodeStatus || (isCompleted && prevStatus !== "success")) {
|
|
217
|
-
nodeMap[nodeName] = isCompleted ? "success" : nodeStatus;
|
|
218
|
-
callback("node", {
|
|
219
|
-
name: nodeName,
|
|
220
|
-
status: isCompleted ? "success" : "executing",
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// 最终结果
|
|
226
|
-
if (output?.finish_reason === "stop" && output?.text) {
|
|
227
|
-
finalResult = output.text;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// 错误
|
|
231
|
-
if (output?.code || output?.message) {
|
|
232
|
-
callback("error", output.message || output.code || "未知错误");
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
} catch (e) {
|
|
236
|
-
// 忽略非 JSON 行
|
|
237
|
-
}
|
|
61
|
+
getSSE("message", dataStr);
|
|
238
62
|
}
|
|
239
63
|
}
|
|
240
64
|
}
|
|
241
65
|
} catch (error) {
|
|
242
|
-
console.error("
|
|
243
|
-
|
|
66
|
+
console.error("SSE请求失败:", error);
|
|
67
|
+
getSSE("error", error.message || "sendToNodeSSE检测到异常");
|
|
244
68
|
}
|
|
245
69
|
};
|
|
246
70
|
|
|
247
|
-
|
|
248
|
-
* @description: Node+OpenAi
|
|
249
|
-
*/
|
|
250
|
-
// 品种池AI助手(流式) - 品种池AI助手
|
|
71
|
+
// 品种池AI查询助手
|
|
251
72
|
export const sendToNodeVarietyAiHelper = async ({ baseUrl, token, value, callback }) => {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}),
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
if (!response.ok) {
|
|
267
|
-
callback("error", `HTTP ${response.status}: ${response.statusText}`);
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const reader = response.body.getReader();
|
|
272
|
-
const decoder = new TextDecoder();
|
|
273
|
-
let buffer = "";
|
|
274
|
-
let finalResult = "";
|
|
275
|
-
const nodeMap = {};
|
|
276
|
-
|
|
277
|
-
while (true) {
|
|
278
|
-
const { done, value } = await reader.read();
|
|
279
|
-
if (done) {
|
|
280
|
-
if (finalResult) {
|
|
281
|
-
callback("message", finalResult);
|
|
282
|
-
}
|
|
283
|
-
callback("finish", "");
|
|
284
|
-
break;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
buffer += decoder.decode(value, { stream: true });
|
|
288
|
-
let newlineIndex;
|
|
289
|
-
while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
|
|
290
|
-
const line = buffer.substring(0, newlineIndex).trim();
|
|
291
|
-
buffer = buffer.substring(newlineIndex + 1);
|
|
292
|
-
|
|
293
|
-
if (line.startsWith("data: ")) {
|
|
294
|
-
const dataStr = line.substring(6).trim();
|
|
295
|
-
if (!dataStr || dataStr === "[DONE]") continue;
|
|
296
|
-
|
|
73
|
+
// 工作流节点
|
|
74
|
+
const nodeMap = {};
|
|
75
|
+
const params = {
|
|
76
|
+
baseUrl,
|
|
77
|
+
path: "/middleLayer/ai/varietyAiHelper",
|
|
78
|
+
token,
|
|
79
|
+
value,
|
|
80
|
+
origin: "web",
|
|
81
|
+
getSSE: (type, str) => {
|
|
82
|
+
switch (type) {
|
|
83
|
+
case "message": {
|
|
297
84
|
try {
|
|
298
|
-
const data = JSON.parse(
|
|
299
|
-
|
|
300
|
-
// 节点状态更新
|
|
85
|
+
const data = JSON.parse(str);
|
|
86
|
+
// 节点状态
|
|
301
87
|
if (data.node_name && data.node_status) {
|
|
302
88
|
const nodeName = data.node_name;
|
|
303
89
|
const nodeStatus = data.node_status === "success" ? "success" : "executing";
|
|
304
|
-
|
|
90
|
+
// 节点状态发生改变, 推送节点状态变更
|
|
305
91
|
if (nodeMap[nodeName] !== nodeStatus) {
|
|
306
92
|
nodeMap[nodeName] = nodeStatus;
|
|
307
93
|
callback("node", {
|
|
@@ -310,26 +96,67 @@ export const sendToNodeVarietyAiHelper = async ({ baseUrl, token, value, callbac
|
|
|
310
96
|
});
|
|
311
97
|
}
|
|
312
98
|
}
|
|
313
|
-
|
|
314
|
-
// 最终结果
|
|
99
|
+
// 结果输出
|
|
315
100
|
if (data.output?.finish_reason === "stop" && data.output?.text) {
|
|
316
|
-
|
|
317
|
-
callback("message", finalResult);
|
|
101
|
+
callback("message", data.output.text);
|
|
318
102
|
}
|
|
319
|
-
|
|
320
103
|
// 错误处理
|
|
321
104
|
if (data.error) {
|
|
322
105
|
callback("error", data.error);
|
|
323
|
-
return;
|
|
324
106
|
}
|
|
325
|
-
} catch (
|
|
326
|
-
//
|
|
107
|
+
} catch (error) {
|
|
108
|
+
// 忽略非序列化消息
|
|
327
109
|
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case "finish": {
|
|
113
|
+
callback("finish");
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case "error": {
|
|
117
|
+
callback("error", str);
|
|
118
|
+
break;
|
|
328
119
|
}
|
|
329
120
|
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
return sendToNodeSSE(params);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// 因子脚本测试助手
|
|
127
|
+
export const sendToNodeFactorAiTest = async ({ baseUrl, token, value, callback }) => {
|
|
128
|
+
const params = {
|
|
129
|
+
baseUrl,
|
|
130
|
+
path: "/middleLayer/ai/factorAiTest",
|
|
131
|
+
token,
|
|
132
|
+
value,
|
|
133
|
+
origin: "web",
|
|
134
|
+
getSSE: (type, str) => {
|
|
135
|
+
switch (type) {
|
|
136
|
+
case "message": {
|
|
137
|
+
try {
|
|
138
|
+
const data = JSON.parse(str);
|
|
139
|
+
// 结果输出
|
|
140
|
+
if (data.output) {
|
|
141
|
+
callback("message", data.output?.content);
|
|
142
|
+
}
|
|
143
|
+
// 错误处理
|
|
144
|
+
if (data.error) {
|
|
145
|
+
callback("error", data.error);
|
|
146
|
+
}
|
|
147
|
+
} catch (error) {}
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
case "finish": {
|
|
151
|
+
callback("finish");
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
case "error": {
|
|
155
|
+
callback("error", str);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
return sendToNodeSSE(params);
|
|
335
162
|
};
|
package/lib/bundle.js
CHANGED