st-comp 0.0.270 → 0.0.272

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/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: 百炼dashscope直连
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
- const response = await fetch(`https://dashscope.aliyuncs.com/api/v1/apps/${appId}/completion`, {
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
- input: { prompt: value },
49
- parameters: {
50
- incremental_output: false, // 非流式
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
- callback("error", `HTTP ${response.status}: ${response.statusText}`);
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
- let newlineIndex;
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 finalResult = "";
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
- if (finalResult) {
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
- if (line.startsWith("data:")) {
200
- const dataStr = line.substring(5).trim();
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("工作流请求失败:", error);
243
- callback("error", error.message);
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
- try {
253
- const response = await fetch(`${baseUrl}/middleLayer/ai/varietyAiHelper`, {
254
- method: "POST",
255
- headers: {
256
- "Content-Type": "application/json",
257
- token: token,
258
- },
259
- body: JSON.stringify({
260
- query: value,
261
- origin: "web",
262
- stream: true,
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(dataStr);
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
- finalResult = data.output.text;
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 (e) {
326
- // 忽略非 JSON 行
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
- } catch (error) {
332
- console.error("Node服务请求失败:", error);
333
- callback("error", error.message);
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
@@ -1,4 +1,4 @@
1
- import { i as m } from "./index-2dd72fda.js";
1
+ import { i as m } from "./index-72c532d5.js";
2
2
  import "vue";
3
3
  import "echarts";
4
4
  export {