@shun-js/aibaiban-server 1.0.1 → 1.0.3
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/package.json +2 -2
- package/server/service/LLMService.js +31 -10
- package/server/util/llm-agent.js +7 -19
- package/server/util/prompt-agent.js +4 -3
- package/views/index.html +21 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shun-js/aibaiban-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "aibaiban.com server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai aibaiban"
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"access": "public",
|
|
45
45
|
"registry": "https://registry.npmjs.org/"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "6882b0a600e3ad421b67cee58134371ec478ce93"
|
|
48
48
|
}
|
|
@@ -28,6 +28,9 @@ exports.drawAgent = async (req, res) => {
|
|
|
28
28
|
chatFeishuMsg(req, `userPrompt-${input}`);
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
|
+
const startTime = Date.now();
|
|
32
|
+
let stepStart = startTime;
|
|
33
|
+
|
|
31
34
|
// start
|
|
32
35
|
res.streaming(`data: ${JSON.stringify({ step: 'router', status: 'start' })}\n\n`);
|
|
33
36
|
req.logger.info(methodName, 'step: router');
|
|
@@ -35,9 +38,10 @@ exports.drawAgent = async (req, res) => {
|
|
|
35
38
|
// intent
|
|
36
39
|
const intentResult = await callLLMForJSON(prompts.ROUTER_PROMPT.replace('{input}', input), res, 'router');
|
|
37
40
|
const intent = intentResult.intent;
|
|
38
|
-
|
|
41
|
+
const routerTime = Date.now() - stepStart;
|
|
42
|
+
req.logger.info(methodName, 'intent', intent, `${routerTime}ms`);
|
|
39
43
|
chatFeishuMsg(req, `intent-${intent}`);
|
|
40
|
-
res.streaming(`data: ${JSON.stringify({ step: 'router', intent })}\n\n`);
|
|
44
|
+
res.streaming(`data: ${JSON.stringify({ step: 'router', intent, duration: routerTime })}\n\n`);
|
|
41
45
|
|
|
42
46
|
// 非白板请求
|
|
43
47
|
if (intent === 'irrelevant') {
|
|
@@ -49,15 +53,18 @@ exports.drawAgent = async (req, res) => {
|
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
// 2. classify - 分类图表类型
|
|
56
|
+
stepStart = Date.now();
|
|
52
57
|
res.streaming(`data: ${JSON.stringify({ step: 'classify', status: 'start' })}\n\n`);
|
|
53
58
|
req.logger.info(methodName, 'step: classify');
|
|
54
59
|
const classifyResult = await callLLMForJSON(prompts.CLASSIFY_PROMPT.replace('{input}', input), res, 'classify');
|
|
55
60
|
const diagramType = classifyResult.diagramType;
|
|
56
|
-
|
|
61
|
+
const classifyTime = Date.now() - stepStart;
|
|
62
|
+
req.logger.info(methodName, 'diagramType', diagramType, `${classifyTime}ms`);
|
|
57
63
|
chatFeishuMsg(req, `diagramType-${diagramType}`);
|
|
58
|
-
res.streaming(`data: ${JSON.stringify({ step: 'classify', diagramType })}\n\n`);
|
|
64
|
+
res.streaming(`data: ${JSON.stringify({ step: 'classify', diagramType, duration: classifyTime })}\n\n`);
|
|
59
65
|
|
|
60
66
|
// 3. elaborate - 细化内容
|
|
67
|
+
stepStart = Date.now();
|
|
61
68
|
res.streaming(`data: ${JSON.stringify({ step: 'elaborate', status: 'start' })}\n\n`);
|
|
62
69
|
req.logger.info(methodName, 'step: elaborate');
|
|
63
70
|
const elaboration = await callLLM(
|
|
@@ -65,11 +72,13 @@ exports.drawAgent = async (req, res) => {
|
|
|
65
72
|
res,
|
|
66
73
|
'elaborate',
|
|
67
74
|
);
|
|
68
|
-
|
|
75
|
+
const elaborateTime = Date.now() - stepStart;
|
|
76
|
+
req.logger.info(methodName, 'elaboration', elaboration.slice(0, 100) + '...', `${elaborateTime}ms`);
|
|
69
77
|
chatFeishuMsg(req, `elaboration-${elaboration}`);
|
|
70
|
-
res.streaming(`data: ${JSON.stringify({ step: 'elaborate', done: true })}\n\n`);
|
|
78
|
+
res.streaming(`data: ${JSON.stringify({ step: 'elaborate', done: true, duration: elaborateTime })}\n\n`);
|
|
71
79
|
|
|
72
80
|
// 4. review - 质量检查
|
|
81
|
+
stepStart = Date.now();
|
|
73
82
|
res.streaming(`data: ${JSON.stringify({ step: 'review', status: 'start' })}\n\n`);
|
|
74
83
|
req.logger.info(methodName, 'step: review');
|
|
75
84
|
const reviewResult = await callLLMForJSON(
|
|
@@ -79,9 +88,10 @@ exports.drawAgent = async (req, res) => {
|
|
|
79
88
|
res,
|
|
80
89
|
'review',
|
|
81
90
|
);
|
|
82
|
-
|
|
91
|
+
const reviewTime = Date.now() - stepStart;
|
|
92
|
+
req.logger.info(methodName, 'reviewResult', reviewResult, `${reviewTime}ms`);
|
|
83
93
|
chatFeishuMsg(req, `reviewResult-${reviewResult}`);
|
|
84
|
-
res.streaming(`data: ${JSON.stringify({ step: 'review', result: reviewResult.result })}\n\n`);
|
|
94
|
+
res.streaming(`data: ${JSON.stringify({ step: 'review', result: reviewResult.result, duration: reviewTime })}\n\n`);
|
|
85
95
|
|
|
86
96
|
// 信息不足,追问用户
|
|
87
97
|
if (reviewResult.result === 'need_more_info') {
|
|
@@ -97,6 +107,7 @@ exports.drawAgent = async (req, res) => {
|
|
|
97
107
|
}
|
|
98
108
|
|
|
99
109
|
// 5. generate - 生成 Mermaid
|
|
110
|
+
stepStart = Date.now();
|
|
100
111
|
res.streaming(`data: ${JSON.stringify({ step: 'generate', status: 'start' })}\n\n`);
|
|
101
112
|
req.logger.info(methodName, 'step: generate');
|
|
102
113
|
const mermaidCode = await callLLM(
|
|
@@ -104,11 +115,21 @@ exports.drawAgent = async (req, res) => {
|
|
|
104
115
|
res,
|
|
105
116
|
'generate',
|
|
106
117
|
);
|
|
107
|
-
|
|
118
|
+
const generateTime = Date.now() - stepStart;
|
|
119
|
+
const totalTime = Date.now() - startTime;
|
|
120
|
+
req.logger.info(
|
|
121
|
+
methodName,
|
|
122
|
+
'mermaidCode',
|
|
123
|
+
mermaidCode.slice(0, 100) + '...',
|
|
124
|
+
`${generateTime}ms`,
|
|
125
|
+
`total: ${totalTime}ms`,
|
|
126
|
+
);
|
|
108
127
|
chatFeishuMsg(req, `mermaidCode-${mermaidCode}`);
|
|
109
128
|
|
|
110
129
|
// 返回最终结果
|
|
111
|
-
res.streaming(
|
|
130
|
+
res.streaming(
|
|
131
|
+
`data: ${JSON.stringify({ step: 'generate', mermaidCode, duration: generateTime, totalDuration: totalTime })}\n\n`,
|
|
132
|
+
);
|
|
112
133
|
res.streamingEnd();
|
|
113
134
|
} catch (error) {
|
|
114
135
|
req.logger.error(methodName, 'error', error);
|
package/server/util/llm-agent.js
CHANGED
|
@@ -38,38 +38,26 @@ function extractJSON(text) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
42
|
-
* 不发送中间 delta,只返回解析后的结果
|
|
41
|
+
* 调用 LLM 并解析 JSON
|
|
43
42
|
*/
|
|
44
43
|
exports.callLLMForJSON = async (prompt) => {
|
|
45
|
-
// 非流式调用,等待完整响应
|
|
46
44
|
const response = await llm.chat({
|
|
47
45
|
model: finalLLMConfig.modelName,
|
|
48
46
|
messages: [{ role: 'user', content: prompt }],
|
|
49
47
|
});
|
|
50
48
|
|
|
51
49
|
const fullContent = response.content || '';
|
|
52
|
-
// 不发送 delta,直接返回结果让调用方处理
|
|
53
50
|
return extractJSON(fullContent);
|
|
54
51
|
};
|
|
55
52
|
|
|
56
53
|
/**
|
|
57
|
-
*
|
|
58
|
-
* 不发送中间 delta,只返回完整内容
|
|
54
|
+
* 调用 LLM(普通文本)
|
|
59
55
|
*/
|
|
60
56
|
exports.callLLM = async (prompt) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
{
|
|
66
|
-
contentCallback: (chunk) => {
|
|
67
|
-
fullContent += chunk;
|
|
68
|
-
// 不发送中间 delta,避免显示问题
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
);
|
|
57
|
+
const response = await llm.chat({
|
|
58
|
+
model: finalLLMConfig.modelName,
|
|
59
|
+
messages: [{ role: 'user', content: prompt }],
|
|
60
|
+
});
|
|
72
61
|
|
|
73
|
-
|
|
74
|
-
return fullContent;
|
|
62
|
+
return response.content || '';
|
|
75
63
|
};
|
|
@@ -86,9 +86,10 @@ module.exports = {
|
|
|
86
86
|
|
|
87
87
|
⚠️ 重要语法限制:
|
|
88
88
|
1. 禁止使用以下 Mermaid 保留字作为节点名称: start, end, stop, pause, resume, done, state, choice, fork, join
|
|
89
|
-
2. 如果流程有"开始"或"结束",使用
|
|
90
|
-
3.
|
|
91
|
-
4.
|
|
89
|
+
2. 如果流程有"开始"或"结束",使用 node_start((开始))、node_end((结束)) 这样的自定义ID
|
|
90
|
+
3. 节点文本和连接线文本中禁止使用括号()[]{},这些是 Mermaid 的形状语法符号,会导致解析错误
|
|
91
|
+
4. 连接线标签示例: -->|是| 、-->|否| 、-->|提交|,不要写 -->|否(注册)| 或 -->|是(通过)|
|
|
92
|
+
5. 如需补充说明,用斜杠/顿号/破折号代替括号,如"否-注册"、"否/注册"
|
|
92
93
|
|
|
93
94
|
要求:
|
|
94
95
|
1. 生成合法的 Mermaid 语法
|
package/views/index.html
CHANGED
|
@@ -89,50 +89,52 @@
|
|
|
89
89
|
]
|
|
90
90
|
}
|
|
91
91
|
</script>
|
|
92
|
-
<!-- Microsoft Clarity -->
|
|
92
|
+
<!-- Microsoft Clarity (production only) -->
|
|
93
93
|
<script type="text/javascript">
|
|
94
|
-
|
|
95
|
-
c
|
|
96
|
-
c[a]
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
94
|
+
if (location.hostname.includes('aibaiban.com')) {
|
|
95
|
+
(function (c, l, a, r, i, t, y) {
|
|
96
|
+
c[a] =
|
|
97
|
+
c[a] ||
|
|
98
|
+
function () {
|
|
99
|
+
(c[a].q = c[a].q || []).push(arguments);
|
|
100
|
+
};
|
|
101
|
+
t = l.createElement(r);
|
|
102
|
+
t.async = 1;
|
|
103
|
+
t.src = 'https://www.clarity.ms/tag/' + i;
|
|
104
|
+
y = l.getElementsByTagName(r)[0];
|
|
105
|
+
y.parentNode.insertBefore(t, y);
|
|
106
|
+
})(window, document, 'clarity', 'script', 't5b230u2zp');
|
|
107
|
+
}
|
|
106
108
|
</script>
|
|
107
109
|
<script
|
|
108
110
|
type="module"
|
|
109
111
|
crossorigin
|
|
110
|
-
src="https://static-small.vincentqiao.com/aibaiban/static/index-
|
|
112
|
+
src="https://static-small.vincentqiao.com/aibaiban/static/index-CYIYkLbz.js"
|
|
111
113
|
></script>
|
|
112
114
|
<link
|
|
113
115
|
rel="modulepreload"
|
|
114
116
|
crossorigin
|
|
115
|
-
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/react-vendor-
|
|
117
|
+
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/react-vendor-zXWpQZWf.js"
|
|
116
118
|
/>
|
|
117
119
|
<link
|
|
118
120
|
rel="modulepreload"
|
|
119
121
|
crossorigin
|
|
120
|
-
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/antd-base-
|
|
122
|
+
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/antd-base-BkT6tJ3N.js"
|
|
121
123
|
/>
|
|
122
124
|
<link
|
|
123
125
|
rel="modulepreload"
|
|
124
126
|
crossorigin
|
|
125
|
-
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/antd-icons-
|
|
127
|
+
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/antd-icons-AALiXfxf.js"
|
|
126
128
|
/>
|
|
127
129
|
<link
|
|
128
130
|
rel="modulepreload"
|
|
129
131
|
crossorigin
|
|
130
|
-
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/antd-x-
|
|
132
|
+
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/antd-x-DKY-WOLC.js"
|
|
131
133
|
/>
|
|
132
134
|
<link
|
|
133
135
|
rel="modulepreload"
|
|
134
136
|
crossorigin
|
|
135
|
-
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/excalidraw-
|
|
137
|
+
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/excalidraw-WA-IihWf.js"
|
|
136
138
|
/>
|
|
137
139
|
<link
|
|
138
140
|
rel="stylesheet"
|