@shun-js/aibaiban-server 1.0.4 → 1.0.6
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/assets/icon-192.png +0 -0
- package/assets/icon-512.png +0 -0
- package/assets/manifest.json +25 -0
- package/assets/sw.js +3 -0
- package/package.json +2 -2
- package/server/controller/SEOController.js +14 -0
- package/server/service/LLMService.js +2 -31
- package/server/service/SEOService.js +44 -0
- package/server/util/prompt-agent.js +32 -29
- package/views/index.html +7 -2
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "AI白板 - 智能协作白板工具",
|
|
3
|
+
"short_name": "AI白板",
|
|
4
|
+
"description": "AI白板是一款智能协作白板工具,结合Excalidraw强大的绘图能力和AI助手的智能辅助",
|
|
5
|
+
"start_url": "/",
|
|
6
|
+
"display": "standalone",
|
|
7
|
+
"background_color": "#ffffff",
|
|
8
|
+
"theme_color": "#1677ff",
|
|
9
|
+
"orientation": "any",
|
|
10
|
+
"icons": [
|
|
11
|
+
{
|
|
12
|
+
"src": "/icon-192.png",
|
|
13
|
+
"sizes": "192x192",
|
|
14
|
+
"type": "image/png",
|
|
15
|
+
"purpose": "any maskable"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"src": "/icon-512.png",
|
|
19
|
+
"sizes": "512x512",
|
|
20
|
+
"type": "image/png",
|
|
21
|
+
"purpose": "any maskable"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"categories": ["productivity", "utilities"]
|
|
25
|
+
}
|
package/assets/sw.js
ADDED
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.6",
|
|
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": "863c0f7f0ea82316e0bd8eb7035e56c964afa856"
|
|
48
48
|
}
|
|
@@ -15,4 +15,18 @@ module.exports = (app) => {
|
|
|
15
15
|
app.get('/4cb288d7aef5469c92616c0f5b5aeb89.txt', (req, res) => {
|
|
16
16
|
service.bingIndexNow(req, res);
|
|
17
17
|
});
|
|
18
|
+
|
|
19
|
+
// pwa
|
|
20
|
+
app.get('/manifest.json', (req, res) => {
|
|
21
|
+
service.manifestJson(req, res);
|
|
22
|
+
});
|
|
23
|
+
app.get('/sw.js', (req, res) => {
|
|
24
|
+
service.swJs(req, res);
|
|
25
|
+
});
|
|
26
|
+
app.get('/icon-192.png', (req, res) => {
|
|
27
|
+
service.icon192Png(req, res);
|
|
28
|
+
});
|
|
29
|
+
app.get('/icon-512.png', (req, res) => {
|
|
30
|
+
service.icon512Png(req, res);
|
|
31
|
+
});
|
|
18
32
|
};
|
|
@@ -7,7 +7,7 @@ const { chatFeishuMsg, errorFeishuMsg } = require('../util/feishu.js');
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* drawAgent - 流式 Agent 接口
|
|
10
|
-
* 流程:router -> classify -> elaborate ->
|
|
10
|
+
* 流程:router -> classify -> elaborate -> generate
|
|
11
11
|
*/
|
|
12
12
|
exports.drawAgent = async (req, res) => {
|
|
13
13
|
const methodName = 'drawAgent';
|
|
@@ -77,36 +77,7 @@ exports.drawAgent = async (req, res) => {
|
|
|
77
77
|
chatFeishuMsg(req, `elaboration-${elaboration}`);
|
|
78
78
|
res.streaming(`data: ${JSON.stringify({ step: 'elaborate', done: true, duration: elaborateTime })}\n\n`);
|
|
79
79
|
|
|
80
|
-
// 4.
|
|
81
|
-
stepStart = Date.now();
|
|
82
|
-
res.streaming(`data: ${JSON.stringify({ step: 'review', status: 'start' })}\n\n`);
|
|
83
|
-
req.logger.info(methodName, 'step: review');
|
|
84
|
-
const reviewResult = await callLLMForJSON(
|
|
85
|
-
prompts.REVIEW_PROMPT.replace('{input}', input)
|
|
86
|
-
.replace('{diagramType}', diagramType)
|
|
87
|
-
.replace('{elaboration}', elaboration),
|
|
88
|
-
res,
|
|
89
|
-
'review',
|
|
90
|
-
);
|
|
91
|
-
const reviewTime = Date.now() - stepStart;
|
|
92
|
-
req.logger.info(methodName, 'reviewResult', reviewResult, `${reviewTime}ms`);
|
|
93
|
-
chatFeishuMsg(req, `reviewResult-${reviewResult}`);
|
|
94
|
-
res.streaming(`data: ${JSON.stringify({ step: 'review', result: reviewResult.result, duration: reviewTime })}\n\n`);
|
|
95
|
-
|
|
96
|
-
// 信息不足,追问用户
|
|
97
|
-
if (reviewResult.result === 'need_more_info') {
|
|
98
|
-
res.streaming(
|
|
99
|
-
`data: ${JSON.stringify({
|
|
100
|
-
step: 'review',
|
|
101
|
-
result: 'need_more_info',
|
|
102
|
-
questions: reviewResult.questions,
|
|
103
|
-
})}\n\n`,
|
|
104
|
-
);
|
|
105
|
-
res.streamingEnd();
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// 5. generate - 生成 Mermaid
|
|
80
|
+
// 4. generate - 生成 Mermaid
|
|
110
81
|
stepStart = Date.now();
|
|
111
82
|
res.streaming(`data: ${JSON.stringify({ step: 'generate', status: 'start' })}\n\n`);
|
|
112
83
|
req.logger.info(methodName, 'step: generate');
|
|
@@ -36,3 +36,47 @@ exports.bingIndexNow = async (req, res) => {
|
|
|
36
36
|
const txt = await readFile(txtPath);
|
|
37
37
|
res.send(txt);
|
|
38
38
|
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* manifestJson
|
|
42
|
+
* @param {*} req
|
|
43
|
+
* @param {*} res
|
|
44
|
+
*/
|
|
45
|
+
exports.manifestJson = async (req, res) => {
|
|
46
|
+
const txtPath = path.resolve(__dirname, '../../assets/manifest.json');
|
|
47
|
+
const txt = await readFile(txtPath);
|
|
48
|
+
res.send(txt);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* swJs
|
|
53
|
+
* @param {*} req
|
|
54
|
+
* @param {*} res
|
|
55
|
+
*/
|
|
56
|
+
exports.swJs = async (req, res) => {
|
|
57
|
+
const txtPath = path.resolve(__dirname, '../../assets/sw.js');
|
|
58
|
+
const txt = await readFile(txtPath);
|
|
59
|
+
res.send(txt);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* icon192Png
|
|
64
|
+
* @param {*} req
|
|
65
|
+
* @param {*} res
|
|
66
|
+
*/
|
|
67
|
+
exports.icon192Png = async (req, res) => {
|
|
68
|
+
const txtPath = path.resolve(__dirname, '../../assets/icon-192.png');
|
|
69
|
+
const txt = await readFile(txtPath);
|
|
70
|
+
res.send(txt);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* icon512Png
|
|
75
|
+
* @param {*} req
|
|
76
|
+
* @param {*} res
|
|
77
|
+
*/
|
|
78
|
+
exports.icon512Png = async (req, res) => {
|
|
79
|
+
const txtPath = path.resolve(__dirname, '../../assets/icon-512.png');
|
|
80
|
+
const txt = await readFile(txtPath);
|
|
81
|
+
res.send(txt);
|
|
82
|
+
};
|
|
@@ -19,12 +19,16 @@ module.exports = {
|
|
|
19
19
|
CLASSIFY_PROMPT: `你是一个图表类型分析专家。根据用户需求,判断最适合的图表类型。
|
|
20
20
|
|
|
21
21
|
可选类型:
|
|
22
|
-
- flowchart:
|
|
23
|
-
- sequence:
|
|
24
|
-
- classDiagram:
|
|
25
|
-
- erDiagram: ER
|
|
22
|
+
- flowchart: 流程图、步骤图、决策流程、状态图、思维导图等通用图表
|
|
23
|
+
- sequence: 时序图、交互流程、调用链、消息传递
|
|
24
|
+
- classDiagram: 类图、对象关系、继承结构、接口设计
|
|
25
|
+
- erDiagram: ER图、实体关系图、数据库设计、数据模型
|
|
26
26
|
|
|
27
|
-
注意:
|
|
27
|
+
注意:
|
|
28
|
+
- 只能从以上4种类型中选择
|
|
29
|
+
- 提到"ER图"、"实体关系"、"数据库"、"表结构"时必须选 erDiagram
|
|
30
|
+
- 提到"类"、"继承"、"接口"、"对象"时选 classDiagram
|
|
31
|
+
- 如果不确定,默认选 flowchart
|
|
28
32
|
|
|
29
33
|
用户输入: {input}
|
|
30
34
|
|
|
@@ -45,25 +49,6 @@ module.exports = {
|
|
|
45
49
|
- classDiagram: {"classes": [{"name": "", "attributes": [...], "methods": [...]}], "relations": [...]}
|
|
46
50
|
- erDiagram: {"entities": [{"name": "", "attributes": [...]}], "relations": [...]}
|
|
47
51
|
|
|
48
|
-
只回复 JSON。`,
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* 质量检查
|
|
52
|
-
*/
|
|
53
|
-
REVIEW_PROMPT: `你是一个质量检查专家。检查以下图表描述是否信息充足,能否生成完整的图表。
|
|
54
|
-
|
|
55
|
-
用户原始输入: {input}
|
|
56
|
-
图表类型: {diagramType}
|
|
57
|
-
细化描述: {elaboration}
|
|
58
|
-
|
|
59
|
-
判断标准:
|
|
60
|
-
1. 节点/步骤是否足够(至少3个有意义的元素)
|
|
61
|
-
2. 关系/连接是否清晰
|
|
62
|
-
3. 是否有明显缺失的关键信息
|
|
63
|
-
|
|
64
|
-
如果信息充足,回复: {"result": "pass"}
|
|
65
|
-
如果信息不足,回复: {"result": "need_more_info", "questions": ["问题1", "问题2"]}
|
|
66
|
-
|
|
67
52
|
只回复 JSON。`,
|
|
68
53
|
|
|
69
54
|
/**
|
|
@@ -75,11 +60,29 @@ module.exports = {
|
|
|
75
60
|
细化描述: {elaboration}
|
|
76
61
|
|
|
77
62
|
⚠️ 重要语法限制:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
63
|
+
|
|
64
|
+
【通用规则】
|
|
65
|
+
1. 所有节点必须使用英文ID,中文文本放在形状符号内,如: node1[中文文本]、node2{判断条件}
|
|
66
|
+
2. 禁止直接用中文作为节点名,如: 访问网站 --> 判断(错误!)
|
|
67
|
+
3. 节点文本和连接线标签中禁止使用 ? ? () [] {} 等特殊符号
|
|
68
|
+
4. 连接线标签示例: -->|是|、-->|否|,不要写 -->|否(注册)|
|
|
69
|
+
5. 禁止使用 Mermaid 保留字作为节点ID: start, end, stop, state, choice, fork, join
|
|
70
|
+
|
|
71
|
+
【flowchart 示例】
|
|
72
|
+
flowchart TD
|
|
73
|
+
node_start((开始))
|
|
74
|
+
node_visit[访问网站]
|
|
75
|
+
node_check{是否已注册}
|
|
76
|
+
node_start --> node_visit
|
|
77
|
+
node_visit --> node_check
|
|
78
|
+
node_check -->|是| node_login[登录]
|
|
79
|
+
node_check -->|否| node_register[注册]
|
|
80
|
+
|
|
81
|
+
【erDiagram 属性格式】
|
|
82
|
+
- 格式: type name PK/FK "注释",每个属性最多4个部分
|
|
83
|
+
- 正确: string username PK "用户名"
|
|
84
|
+
- 错误: VARCHAR(50) UNIQUE NOT NULL username(不支持SQL语法)
|
|
85
|
+
- type只用: string, int, text, datetime, boolean, float
|
|
83
86
|
|
|
84
87
|
要求:
|
|
85
88
|
1. 生成合法的 Mermaid 语法
|
package/views/index.html
CHANGED
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
<script
|
|
110
110
|
type="module"
|
|
111
111
|
crossorigin
|
|
112
|
-
src="https://static-small.vincentqiao.com/aibaiban/static/index-
|
|
112
|
+
src="https://static-small.vincentqiao.com/aibaiban/static/index-D3qgIOvl.js"
|
|
113
113
|
></script>
|
|
114
114
|
<link
|
|
115
115
|
rel="modulepreload"
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
<link
|
|
135
135
|
rel="modulepreload"
|
|
136
136
|
crossorigin
|
|
137
|
-
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/excalidraw-
|
|
137
|
+
href="https://static-small.vincentqiao.com/aibaiban/static/chunks/excalidraw-BV1kaZIV.js"
|
|
138
138
|
/>
|
|
139
139
|
<link
|
|
140
140
|
rel="stylesheet"
|
|
@@ -144,5 +144,10 @@
|
|
|
144
144
|
</head>
|
|
145
145
|
<body>
|
|
146
146
|
<div id="root"></div>
|
|
147
|
+
<script>
|
|
148
|
+
if ('serviceWorker' in navigator) {
|
|
149
|
+
navigator.serviceWorker.register('/sw.js');
|
|
150
|
+
}
|
|
151
|
+
</script>
|
|
147
152
|
</body>
|
|
148
153
|
</html>
|