@shun-js/aibaiban-server 0.8.4 → 0.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shun-js/aibaiban-server",
3
- "version": "0.8.4",
3
+ "version": "0.8.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": "52e8268b4ab1635eead49bf93fc2587c84e83fda"
47
+ "gitHead": "04eafc5cc7cc90e3fe81103daa88c168ff6f5037"
48
48
  }
@@ -5,18 +5,8 @@ const service = require('../service/LLMService.js');
5
5
  * controller
6
6
  */
7
7
  module.exports = (app) => {
8
- // intent
9
- app.post('/intent', (req, res) => {
10
- service.intent(req, res);
11
- });
12
-
13
- // drawWithTools (使用结构化 JSON 输出)
14
- app.post('/drawWithTools', (req, res) => {
15
- service.drawWithTools(req, res);
16
- });
17
-
18
- // draw/agent (流式 Agent)
19
- app.post('/draw/agent', (req, res) => {
8
+ // draw agent
9
+ app.post('/chat-streaming', (req, res) => {
20
10
  service.drawAgent(req, res);
21
11
  });
22
12
  };
@@ -1,93 +1,7 @@
1
- // llm
2
- const { llmParseIntent } = require('../util/llm-intent.js');
3
-
4
- // structured json output
5
- const { generateFlowchartWithTools } = require('../util/llm-toolcall.js');
6
-
7
- // util
8
- const { chatFeishuMsg, chatResFeishuMsg, errorFeishuMsg } = require('../util/feishu.js');
9
-
10
1
  // llm agent
11
2
  const { callLLMForJSON, callLLM } = require('../util/llm-agent.js');
12
3
  const prompts = require('../util/prompt-agent.js');
13
4
 
14
- /**
15
- * intent
16
- * @param {*} req
17
- * @param {*} res
18
- * @returns
19
- */
20
- exports.intent = async (req, res) => {
21
- const methodName = 'intent';
22
-
23
- // check
24
- if (!req.body.userPrompt) {
25
- const msg = 'need userPrompt';
26
- req.logger.error(methodName, msg);
27
- res.jsonFail(msg);
28
- return;
29
- }
30
-
31
- // const
32
- const userPrompt = decodeURIComponent(req.body.userPrompt);
33
- req.logger.info(methodName, 'userPrompt', userPrompt);
34
- chatFeishuMsg(req);
35
-
36
- // go
37
- try {
38
- const llmParseIntentRes = await llmParseIntent(userPrompt);
39
- const llmParseIntentObj = JSON.parse(llmParseIntentRes);
40
- req.logger.info(methodName, 'llmParseIntentObj', llmParseIntentObj);
41
-
42
- // r
43
- chatResFeishuMsg(req, JSON.stringify(llmParseIntentObj));
44
- res.jsonSuccess('success', llmParseIntentObj);
45
- } catch (error) {
46
- const msg = 'parse intent error';
47
- errorFeishuMsg(req, msg);
48
- req.logger.error(methodName, msg, error);
49
- res.jsonFail(msg);
50
- }
51
- };
52
-
53
- /**
54
- * drawWithTools - 使用结构化 JSON 输出生成流程图
55
- * @param {*} req
56
- * @param {*} res
57
- * @returns
58
- */
59
- exports.drawWithTools = async (req, res) => {
60
- const methodName = 'drawWithTools';
61
-
62
- // check
63
- if (!req.body.userPrompt) {
64
- const msg = 'need userPrompt';
65
- req.logger.error(methodName, msg);
66
- res.jsonFail(msg);
67
- return;
68
- }
69
-
70
- // const
71
- const userPrompt = decodeURIComponent(req.body.userPrompt);
72
- req.logger.info(methodName, 'userPrompt', userPrompt);
73
- chatFeishuMsg(req);
74
-
75
- // go
76
- try {
77
- const diagram = await generateFlowchartWithTools(userPrompt);
78
- req.logger.info(methodName, 'diagram', diagram);
79
-
80
- // r
81
- chatResFeishuMsg(req, JSON.stringify(diagram));
82
- res.jsonSuccess('success', diagram);
83
- } catch (error) {
84
- const msg = 'draw with tools error';
85
- errorFeishuMsg(req, msg);
86
- req.logger.error(methodName, msg, error);
87
- res.jsonFail(msg);
88
- }
89
- };
90
-
91
5
  /**
92
6
  * drawAgent - 流式 Agent 接口
93
7
  * 流程:router -> classify -> elaborate -> review -> generate
@@ -116,6 +30,8 @@ exports.drawAgent = async (req, res) => {
116
30
  const intentResult = await callLLMForJSON(prompts.ROUTER_PROMPT.replace('{input}', input), res, 'router');
117
31
  const intent = intentResult.intent;
118
32
  req.logger.info(methodName, 'intent', intent);
33
+ // 发送结果
34
+ res.streaming(`data: ${JSON.stringify({ step: 'router', intent })}\n\n`);
119
35
 
120
36
  // 非白板请求
121
37
  if (intent === 'irrelevant') {
@@ -132,6 +48,8 @@ exports.drawAgent = async (req, res) => {
132
48
  const classifyResult = await callLLMForJSON(prompts.CLASSIFY_PROMPT.replace('{input}', input), res, 'classify');
133
49
  const diagramType = classifyResult.diagramType;
134
50
  req.logger.info(methodName, 'diagramType', diagramType);
51
+ // 发送结果
52
+ res.streaming(`data: ${JSON.stringify({ step: 'classify', diagramType })}\n\n`);
135
53
 
136
54
  // 3. elaborate - 细化内容
137
55
  res.streaming(`data: ${JSON.stringify({ step: 'elaborate', status: 'start' })}\n\n`);
@@ -142,6 +60,8 @@ exports.drawAgent = async (req, res) => {
142
60
  'elaborate',
143
61
  );
144
62
  req.logger.info(methodName, 'elaboration', elaboration.slice(0, 100) + '...');
63
+ // 发送结果(不显示内容,只标记完成)
64
+ res.streaming(`data: ${JSON.stringify({ step: 'elaborate', done: true })}\n\n`);
145
65
 
146
66
  // 4. review - 质量检查
147
67
  res.streaming(`data: ${JSON.stringify({ step: 'review', status: 'start' })}\n\n`);
@@ -154,6 +74,8 @@ exports.drawAgent = async (req, res) => {
154
74
  'review',
155
75
  );
156
76
  req.logger.info(methodName, 'reviewResult', reviewResult);
77
+ // 发送结果
78
+ res.streaming(`data: ${JSON.stringify({ step: 'review', result: reviewResult.result })}\n\n`);
157
79
 
158
80
  // 信息不足,追问用户
159
81
  if (reviewResult.result === 'need_more_info') {
@@ -43,9 +43,9 @@ function extractJSON(text) {
43
43
 
44
44
  /**
45
45
  * 流式调用 LLM 并解析 JSON
46
- * 使用非流式 API,但过程流式输出给客户端
46
+ * 不发送中间 delta,只返回解析后的结果
47
47
  */
48
- exports.callLLMForJSON = async (prompt, res, step) => {
48
+ exports.callLLMForJSON = async (prompt) => {
49
49
  // 非流式调用,等待完整响应
50
50
  const response = await llm.chat({
51
51
  model: llmConfig.modelName,
@@ -53,16 +53,15 @@ exports.callLLMForJSON = async (prompt, res, step) => {
53
53
  });
54
54
 
55
55
  const fullContent = response.content || '';
56
- // 流式输出给客户端
57
- res.streaming(`data: ${JSON.stringify({ step, delta: fullContent })}\n\n`);
58
-
56
+ // 不发送 delta,直接返回结果让调用方处理
59
57
  return extractJSON(fullContent);
60
58
  };
61
59
 
62
60
  /**
63
61
  * 流式调用 LLM(普通文本)
62
+ * 不发送中间 delta,只返回完整内容
64
63
  */
65
- exports.callLLM = async (prompt, res, step) => {
64
+ exports.callLLM = async (prompt) => {
66
65
  let fullContent = '';
67
66
 
68
67
  await llm.chatWithStreaming(
@@ -70,8 +69,7 @@ exports.callLLM = async (prompt, res, step) => {
70
69
  {
71
70
  contentCallback: (chunk) => {
72
71
  fullContent += chunk;
73
- // 直接流式返回给客户端
74
- res.streaming(`data: ${JSON.stringify({ step, delta: chunk })}\n\n`);
72
+ // 不发送中间 delta,避免显示问题
75
73
  },
76
74
  },
77
75
  );