@baishuyun/chat-backend 0.0.10 → 0.0.12

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/.env.example CHANGED
@@ -18,3 +18,6 @@ FILL_BOT_ID=xxxxx
18
18
 
19
19
  # query bot id
20
20
  QUERY_BOT_ID=xxxxx
21
+
22
+ # query suggest bot id
23
+ QUERY_SUGGEST_BOT_ID=xxxx
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @baishuyun/chat-backend
2
2
 
3
+ ## 0.0.12
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @baishuyun/coze-provider@0.0.12
9
+ - @baishuyun/types@1.0.12
10
+
11
+ ## 0.0.11
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+ - @baishuyun/coze-provider@0.0.11
17
+ - @baishuyun/types@1.0.11
18
+
3
19
  ## 0.0.10
4
20
 
5
21
  ### Patch Changes
@@ -7,6 +7,10 @@ module.exports = {
7
7
  autorestart: true, // 异常时自动重启(核心)
8
8
  watch: false, // 生产环境关闭文件监听(避免容器内文件变动触发重启)
9
9
  max_memory_restart: '2G', // 内存超过 1G 自动重启(防止内存泄漏)
10
+
11
+ listen_timeout: 10000,
12
+ kill_timeout: 5000,
13
+
10
14
  env: {
11
15
  // 开发环境变量
12
16
  NODE_ENV: 'development',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baishuyun/chat-backend",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -22,8 +22,8 @@
22
22
  "parse-sse": "^0.1.0",
23
23
  "pino": "^10.1.0",
24
24
  "zod": "^4.1.13",
25
- "@baishuyun/coze-provider": "0.0.10",
26
- "@baishuyun/types": "1.0.10"
25
+ "@baishuyun/coze-provider": "0.0.12",
26
+ "@baishuyun/types": "1.0.12"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/config": "^3.3.5",
@@ -34,7 +34,7 @@
34
34
  "pm2": "^6.0.14",
35
35
  "tsx": "^4.7.1",
36
36
  "typescript": "^5.8.3",
37
- "@baishuyun/typescript-config": "0.0.10"
37
+ "@baishuyun/typescript-config": "0.0.12"
38
38
  },
39
39
  "scripts": {
40
40
  "dev": "cross-env NODE_ENV=development tsx watch src/index.ts",
package/src/app/main.ts CHANGED
@@ -13,7 +13,12 @@ import { createReportRouter } from '../routes/report/report.route.js';
13
13
  app.route('web/api/form', createFormRouter());
14
14
  app.route('web/api/report', createReportRouter());
15
15
 
16
- // add test route
17
- app.get('web/api/test', (c) => {
18
- return c.json({ message: 'Test route is working!' });
16
+ // 基础健康检查
17
+ app.get('/web/api/health', (c) => {
18
+ return c.json({
19
+ status: 'ok',
20
+ timestamp: new Date().toISOString(),
21
+ uptime: process.uptime(),
22
+ service: 'hono-app',
23
+ });
19
24
  });
@@ -0,0 +1,54 @@
1
+ import { type LanguageModelV2StreamPart } from '@ai-sdk/provider';
2
+ import { JSONParser } from '@streamparser/json';
3
+ import { type IQueryResult } from '@baishuyun/types';
4
+ import {
5
+ createJsonStreamTransformer,
6
+ type IParserCtx,
7
+ } from '../../../utils/createJsonStreamTransformer.js';
8
+ import { logger } from '../../../logger/index.js';
9
+
10
+ export interface ISuggestion {
11
+ t: string;
12
+ v: string;
13
+ }
14
+
15
+ type suggestions = Array<ISuggestion>;
16
+
17
+ export const createQuerySuggestionTransformer = () => {
18
+ return createJsonStreamTransformer<suggestions>({
19
+ createJSONParser: createJSONParser,
20
+ onParseValue: handleParsedValue,
21
+ onParseError(error) {
22
+ logger.error('JSON parsing error in query transformer: ', error);
23
+ return '数据解析异常,请重试';
24
+ },
25
+ onErrorChunk(chunk) {
26
+ logger.error('Received error chunk in query transformer');
27
+ return '';
28
+ },
29
+ });
30
+ };
31
+
32
+ function createJSONParser(): JSONParser {
33
+ return new JSONParser({
34
+ stringBufferSize: undefined,
35
+ numberBufferSize: undefined,
36
+ separator: '',
37
+ paths: ['$.*'],
38
+ keepStack: true,
39
+ });
40
+ }
41
+
42
+ function handleParsedValue(ctx: IParserCtx<suggestions>): void {
43
+ const { parsedInfo, getResult, currentChunkId, deltaChunkEnqueuer: enqueueTextDelta, ctrl } = ctx;
44
+ const { value } = parsedInfo;
45
+
46
+ logger.debug('Parsed JSON value: ' + JSON.stringify(value));
47
+
48
+ enqueueTextDelta(
49
+ `${JSON.stringify(value)},`,
50
+ { type: 'query-suggestion-parsed-info', result: JSON.stringify(getResult()) },
51
+ currentChunkId + 2,
52
+ true
53
+ );
54
+ }
@@ -2,6 +2,7 @@ import { createCoze } from '@baishuyun/coze-provider';
2
2
 
3
3
  import config from 'config';
4
4
  import { createQueryResultTransformer } from './createQueryTransformStream.js';
5
+ import { createQuerySuggestionTransformer } from './createQuerySuggestionTransStream.js';
5
6
 
6
7
  export const createReportQueryModel = () => {
7
8
  const reportQuery = createCoze({
@@ -15,3 +16,16 @@ export const createReportQueryModel = () => {
15
16
 
16
17
  return reportQueryModel;
17
18
  };
19
+
20
+ export const createQuerySuggestionModel = () => {
21
+ const reportQuery = createCoze({
22
+ apiKey: config.get<string>('agent.report.query.apiKey'),
23
+ baseURL: config.get<string>('agent.report.query.baseUrl'),
24
+ botId: config.get<string>('agent.report.query.botId'),
25
+ extraStreamTransformers: [createQuerySuggestionTransformer],
26
+ });
27
+
28
+ const reportQueryModel = reportQuery.chat('chat');
29
+
30
+ return reportQueryModel;
31
+ };
@@ -0,0 +1,46 @@
1
+ import { type Context } from 'hono';
2
+ import { convertToModelMessages, streamText, type UIMessage, generateId } from 'ai';
3
+ import { createReportQueryModel } from './model.js';
4
+
5
+ export const queryReportSuggest = async (c: Context) => {
6
+ let requestBody;
7
+
8
+ try {
9
+ const json = await c.req.json();
10
+ requestBody = json;
11
+ } catch (_) {
12
+ return c.json({ error: 'Invalid JSON' }, 400);
13
+ }
14
+
15
+ const uid = c.req.header('X-User-Id') || '';
16
+ const messages: UIMessage[] = requestBody.messages;
17
+
18
+ const forms = requestBody.forms || [];
19
+
20
+ const modelMessages = convertToModelMessages([
21
+ {
22
+ role: 'user',
23
+ parts: [
24
+ {
25
+ type: 'text',
26
+ text: JSON.stringify(forms),
27
+ },
28
+ ],
29
+ },
30
+ ]);
31
+
32
+ console.log('Final messages for query suggestion: ', JSON.stringify(modelMessages, null, 2));
33
+
34
+ const stream = streamText({
35
+ model: createReportQueryModel(),
36
+ messages: modelMessages,
37
+ includeRawChunks: true,
38
+ headers: {
39
+ 'x-user-id': uid,
40
+ },
41
+ });
42
+
43
+ return stream.toUIMessageStreamResponse({
44
+ originalMessages: messages, // 建议添加,便于消息 ID 管理
45
+ });
46
+ };
@@ -1,5 +1,6 @@
1
1
  import { Hono } from 'hono';
2
2
  import { queryReport } from '../../controllers/report/query/query.controller.js';
3
+ import { queryReportSuggest } from '../../controllers/report/query/suggest.controller.js';
3
4
 
4
5
  export const createReportRouter = () => {
5
6
  const reportRouter = new Hono();
@@ -7,5 +8,7 @@ export const createReportRouter = () => {
7
8
  // 智能问数
8
9
  reportRouter.post('/query', queryReport);
9
10
 
11
+ reportRouter.post('/query/suggest', queryReportSuggest);
12
+
10
13
  return reportRouter;
11
14
  };