@baishuyun/chat-backend 0.0.12 → 0.0.14

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @baishuyun/chat-backend
2
2
 
3
+ ## 0.0.14
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @baishuyun/coze-provider@0.0.14
9
+ - @baishuyun/types@1.0.14
10
+
11
+ ## 0.0.13
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+ - @baishuyun/coze-provider@0.0.13
17
+ - @baishuyun/types@1.0.13
18
+
3
19
  ## 0.0.12
4
20
 
5
21
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baishuyun/chat-backend",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
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.12",
26
- "@baishuyun/types": "1.0.12"
25
+ "@baishuyun/coze-provider": "0.0.14",
26
+ "@baishuyun/types": "1.0.14"
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.12"
37
+ "@baishuyun/typescript-config": "0.0.14"
38
38
  },
39
39
  "scripts": {
40
40
  "dev": "cross-env NODE_ENV=development tsx watch src/index.ts",
@@ -49,6 +49,16 @@ export const createBatchFillingResultTransformer = (enableJsonParser: boolean) =
49
49
  }
50
50
  } else {
51
51
  // logger.debug(`bypass chunk in batch filling transformer: ${JSON.stringify(chunk)}`);
52
+ if (chunk.type === 'error') {
53
+ enqueueTextDelta('error', {
54
+ type: 'agent-error',
55
+ error: '操作超时,请刷新重试',
56
+ });
57
+
58
+ resolveParseCompleted?.();
59
+ controller.terminate(); // 信号通知下游可读流已关闭
60
+ return;
61
+ }
52
62
  controller.enqueue(chunk);
53
63
  }
54
64
  } catch (e) {
@@ -48,6 +48,17 @@ export const createFieldsFillingResultTransformer = (enableJsonParser: boolean)
48
48
  parser.write(delta.replace('json', ''));
49
49
  }
50
50
  } else {
51
+ if (chunk.type === 'error') {
52
+ enqueueTextDelta('error', {
53
+ type: 'agent-error',
54
+ error: '操作超时,请刷新重试',
55
+ });
56
+
57
+ resolveParseCompleted?.();
58
+ controller.terminate(); // 信号通知下游可读流已关闭
59
+ return;
60
+ }
61
+
51
62
  controller.enqueue(chunk);
52
63
  }
53
64
  } catch (e) {
@@ -2,7 +2,7 @@ import { type Context } from 'hono';
2
2
  import { convertToModelMessages, streamText, type UIMessage, generateId } from 'ai';
3
3
  import { logger } from '../../../logger/index.js';
4
4
  import { createFillingModel } from './model.js';
5
- import { mode2part } from './utils.js';
5
+ import { mode2part, trimFormStructure } from './utils.js';
6
6
  import { batchFillForm } from './batch-fill.controller.js';
7
7
 
8
8
  /**
@@ -20,7 +20,7 @@ export const fillForm = async (c: Context) => {
20
20
  return c.json({ error: 'Invalid JSON' }, 400);
21
21
  }
22
22
 
23
- const formStructure = requestBody.formStructure;
23
+ const formStructure = trimFormStructure(requestBody.formStructure || []);
24
24
  const mode = requestBody.mode;
25
25
  const num = requestBody.count;
26
26
  const messages: UIMessage[] = requestBody.messages;
@@ -30,14 +30,19 @@ export const fillForm = async (c: Context) => {
30
30
  return batchFillForm(c);
31
31
  }
32
32
 
33
+ const flattenParts = messages.flatMap((msg) => msg.parts);
34
+
35
+ const msg = [] as UIMessage[];
36
+
33
37
  if (formStructure) {
34
38
  const extraPart = mode2part(mode, num);
35
39
 
36
40
  try {
37
- messages.push({
41
+ msg.push({
38
42
  id: generateId(),
39
43
  role: 'user',
40
44
  parts: [
45
+ ...flattenParts,
41
46
  {
42
47
  type: 'text',
43
48
  text: `formStructure: ${JSON.stringify(formStructure)}`,
@@ -50,9 +55,11 @@ export const fillForm = async (c: Context) => {
50
55
  }
51
56
  }
52
57
 
58
+ const modelMessages = convertToModelMessages(msg);
59
+
53
60
  const stream = streamText({
54
61
  model: createFillingModel(),
55
- messages: convertToModelMessages(messages),
62
+ messages: modelMessages,
56
63
  includeRawChunks: true,
57
64
  headers: {
58
65
  'x-user-stage': requestBody.stage,
@@ -109,3 +109,67 @@ export const fillingChunkGuard = (
109
109
 
110
110
  return true;
111
111
  };
112
+
113
+ interface TrimmedWidget {
114
+ type: string;
115
+ widgetName: string;
116
+ // 子表单只展开一层,不再嵌套递归
117
+ items?: Array<{
118
+ description?: string | null;
119
+ label: string;
120
+ widget: {
121
+ type: string;
122
+ widgetName: string;
123
+ };
124
+ }>;
125
+ }
126
+
127
+ interface TrimmedField {
128
+ description?: string | null;
129
+ label: string;
130
+ widget: TrimmedWidget;
131
+ }
132
+
133
+ interface OriginalField {
134
+ description?: string | null;
135
+ label: string;
136
+ widget: {
137
+ type: string;
138
+ widgetName: string;
139
+ items?: OriginalField[];
140
+ [key: string]: any;
141
+ };
142
+ [key: string]: any;
143
+ }
144
+
145
+ /**
146
+ * 裁剪表单结构,子表单只展开一层
147
+ */
148
+ export function trimFormStructure(fields: OriginalField[]): TrimmedField[] {
149
+ return fields.map((field) => {
150
+ const trimmed: TrimmedField = {
151
+ description: field.description,
152
+ label: field.label,
153
+ widget: {
154
+ type: field.widget.type,
155
+ widgetName: field.widget.widgetName,
156
+ },
157
+ };
158
+
159
+ if (field.widget.items && Array.isArray(field.widget.items)) {
160
+ // 过滤掉无效 item(null/undefined 或缺少 widget)
161
+ trimmed.widget.items = field.widget.items
162
+ .filter((item): item is OriginalField => item != null && item.widget != null)
163
+ .map((item) => ({
164
+ description: item.description,
165
+ label: item.label,
166
+ widget: {
167
+ type: item.widget.type,
168
+ widgetName: item.widget.widgetName,
169
+ },
170
+ }));
171
+ }
172
+
173
+ return trimmed;
174
+ });
175
+ }