@baishuyun/chat-backend 0.0.18 → 0.0.20
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 +16 -0
- package/config/default.ts +13 -5
- package/dist/config/default.js +12 -5
- package/dist/src/app/main.js +9 -0
- package/dist/src/config/hono.config.js +2 -1
- package/dist/src/const/error_code.js +3 -0
- package/dist/src/controllers/agent/bots.controller.js +1 -1
- package/dist/src/controllers/common/connect.controll.js +4 -2
- package/dist/src/controllers/common/model.js +2 -0
- package/dist/src/controllers/common/transformer-factory/agent-calling-listener.js +44 -0
- package/dist/src/controllers/form/attachment-upload.controller.js +15 -15
- package/dist/src/controllers/form/build/build.controller.js +3 -2
- package/dist/src/controllers/form/conversation/clear.controller.js +6 -6
- package/dist/src/controllers/form/fill/batch-fill.controller.js +3 -4
- package/dist/src/controllers/form/fill/createBatchFillingTransformStream.js +1 -17
- package/dist/src/controllers/form/fill/fill.controller.js +2 -1
- package/dist/src/controllers/form/fill/utils.js +16 -0
- package/dist/src/controllers/report/query/query.controller.js +1 -1
- package/dist/src/middleware/botRouter.js +34 -0
- package/dist/src/routes/common/common.route.js +2 -1
- package/dist/src/services/asr/asr-websocket.js +183 -0
- package/dist/src/services/asr/volc-protocol.js +143 -0
- package/dist/src/services/fetchCozeInfo.js +1 -1
- package/dist/src/utils/createFakeUIMessageStreamResponse.js +25 -0
- package/dist/src/utils/createJsonStreamTransformer.js +17 -2
- package/dist/src/utils/createSpecialPartMeta.js +5 -0
- package/package.json +7 -5
- package/src/app/main.ts +12 -0
- package/src/config/hono.config.ts +2 -1
- package/src/const/error_code.ts +3 -0
- package/src/controllers/agent/bots.controller.ts +1 -1
- package/src/controllers/common/connect.controll.ts +5 -2
- package/src/controllers/common/model.ts +2 -0
- package/src/controllers/common/transformer-factory/agent-calling-listener.ts +69 -0
- package/src/controllers/form/attachment-upload.controller.ts +16 -15
- package/src/controllers/form/build/build.controller.ts +5 -2
- package/src/controllers/form/conversation/clear.controller.ts +12 -15
- package/src/controllers/form/fill/batch-fill.controller.ts +3 -5
- package/src/controllers/form/fill/createBatchFillingTransformStream.ts +1 -20
- package/src/controllers/form/fill/fill.controller.ts +3 -1
- package/src/controllers/form/fill/utils.ts +18 -0
- package/src/controllers/report/query/query.controller.ts +1 -1
- package/src/middleware/botRouter.ts +41 -0
- package/src/routes/common/common.route.ts +2 -1
- package/src/services/asr/asr-websocket.ts +231 -0
- package/src/services/asr/volc-protocol.ts +220 -0
- package/src/services/fetchCozeInfo.ts +1 -1
- package/src/utils/createFakeUIMessageStreamResponse.ts +27 -0
- package/src/utils/createJsonStreamTransformer.ts +21 -2
- package/src/utils/createSpecialPartMeta.ts +7 -0
|
@@ -5,7 +5,7 @@ import { logger } from '../logger/index.js';
|
|
|
5
5
|
export const fetchCozeInfo = async (bsTeamId: string): Promise<ICozeInfoOfTokenExchange> => {
|
|
6
6
|
const agentHost = config.get<string>('agent.host');
|
|
7
7
|
|
|
8
|
-
const apiUrl = `
|
|
8
|
+
const apiUrl = `https://${agentHost}/api/by_teamid/tokens`;
|
|
9
9
|
const res = await fetch(apiUrl, {
|
|
10
10
|
method: 'POST',
|
|
11
11
|
headers: {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createUIMessageStream, createUIMessageStreamResponse, generateId } from 'ai';
|
|
2
|
+
import { createSpecialPartMeta } from './createSpecialPartMeta.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 创建一个与 `streamText().toUIMessageStreamResponse()` 格式一致的假流式响应,
|
|
6
|
+
* 用于在无法调用真实模型时向客户端推送一条指定的文本消息。
|
|
7
|
+
*/
|
|
8
|
+
export const createFakeUIMessageStreamResponse = (text: string): Response => {
|
|
9
|
+
const stream = createUIMessageStream({
|
|
10
|
+
execute: ({ writer }) => {
|
|
11
|
+
const messageId = generateId();
|
|
12
|
+
const textId = generateId();
|
|
13
|
+
writer.write({ type: 'start', messageId });
|
|
14
|
+
writer.write({ type: 'text-start', id: textId });
|
|
15
|
+
writer.write({
|
|
16
|
+
type: 'text-delta',
|
|
17
|
+
id: textId,
|
|
18
|
+
delta: text,
|
|
19
|
+
providerMetadata: createSpecialPartMeta('error-bot-id-required'),
|
|
20
|
+
});
|
|
21
|
+
writer.write({ type: 'text-end', id: textId });
|
|
22
|
+
writer.write({ type: 'finish', finishReason: 'stop' });
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return createUIMessageStreamResponse({ stream });
|
|
27
|
+
};
|
|
@@ -31,6 +31,8 @@ export interface JsonStreamTransformerOptions<T> {
|
|
|
31
31
|
onErrorChunk?: (chunk: LanguageModelV2StreamPart) => void;
|
|
32
32
|
/** JSON 解析出错时的回调,返回要展示的错误消息(可选) */
|
|
33
33
|
onParseError?: (error: any) => string;
|
|
34
|
+
|
|
35
|
+
bypassParseError?: boolean; // 是否完全绕过解析错误处理,直接透传原始 chunk(不推荐,除非特殊场景)
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
/**
|
|
@@ -75,6 +77,7 @@ class JsonStreamProcessor<T> {
|
|
|
75
77
|
private parseCompleted: Promise<void> | null = null;
|
|
76
78
|
private resolveParseCompleted: (() => void) | null = null;
|
|
77
79
|
private terminated = false;
|
|
80
|
+
private passthroughMode = false; // 当启用且遇到非 JSON chunk 时,切换到透传模式
|
|
78
81
|
|
|
79
82
|
constructor(options: JsonStreamTransformerOptions<T>) {
|
|
80
83
|
this.options = options;
|
|
@@ -96,6 +99,11 @@ class JsonStreamProcessor<T> {
|
|
|
96
99
|
return;
|
|
97
100
|
}
|
|
98
101
|
|
|
102
|
+
if (this.passthroughMode) {
|
|
103
|
+
controller.enqueue(chunk);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
99
107
|
try {
|
|
100
108
|
// 1) error chunk → 通知下游后终止
|
|
101
109
|
if (chunk.type === 'error') {
|
|
@@ -117,6 +125,11 @@ class JsonStreamProcessor<T> {
|
|
|
117
125
|
this.parser.write(stripCodeFence(chunk.delta));
|
|
118
126
|
}
|
|
119
127
|
} catch (error) {
|
|
128
|
+
if (this.options.bypassParseError) {
|
|
129
|
+
this.passthroughMode = true;
|
|
130
|
+
controller.enqueue(chunk);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
120
133
|
this.enqueueError(controller, error);
|
|
121
134
|
}
|
|
122
135
|
}
|
|
@@ -169,6 +182,11 @@ class JsonStreamProcessor<T> {
|
|
|
169
182
|
};
|
|
170
183
|
|
|
171
184
|
this.parser.onError = (err: any) => {
|
|
185
|
+
if (this.options.bypassParseError) {
|
|
186
|
+
this.passthroughMode = true;
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
172
190
|
if (!this.terminated) {
|
|
173
191
|
const msg = this.options.onParseError
|
|
174
192
|
? this.options.onParseError(err)
|
|
@@ -180,8 +198,9 @@ class JsonStreamProcessor<T> {
|
|
|
180
198
|
};
|
|
181
199
|
|
|
182
200
|
this.parser.onEnd = () => {
|
|
183
|
-
|
|
184
|
-
|
|
201
|
+
if (!this.options.bypassParseError) {
|
|
202
|
+
enqueue(' ', JSON.stringify({ appendConfirm: 'save-fields' }));
|
|
203
|
+
}
|
|
185
204
|
this.completeParsing();
|
|
186
205
|
};
|
|
187
206
|
}
|