@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @baishuyun/chat-backend
|
|
2
2
|
|
|
3
|
+
## 0.0.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @baishuyun/coze-provider@1.0.0
|
|
9
|
+
- @baishuyun/agents@1.0.0
|
|
10
|
+
- @baishuyun/types@2.0.0
|
|
11
|
+
|
|
12
|
+
## 0.0.19
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- @baishuyun/coze-provider@0.1.1
|
|
18
|
+
|
|
3
19
|
## 0.0.18
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/config/default.ts
CHANGED
|
@@ -17,26 +17,26 @@ export default {
|
|
|
17
17
|
agent: {
|
|
18
18
|
host: process.env.AGENT_HOST || '47.99.202.157',
|
|
19
19
|
|
|
20
|
-
apiAuthKey: process.env.
|
|
20
|
+
apiAuthKey: process.env.BOT_API_KEY,
|
|
21
21
|
|
|
22
22
|
userId: process.env.BUILTIN_COZE_USER_ID,
|
|
23
23
|
|
|
24
24
|
common: {
|
|
25
|
-
baseUrl: `
|
|
25
|
+
baseUrl: `https://${process.env.AGENT_HOST}/v3/`,
|
|
26
26
|
apiKey: process.env.BOT_API_KEY, // load from env
|
|
27
27
|
},
|
|
28
28
|
|
|
29
29
|
form: {
|
|
30
30
|
build: {
|
|
31
31
|
botId: process.env.BUILD_BOT_ID || '7579927677256073216',
|
|
32
|
-
baseUrl: `
|
|
32
|
+
baseUrl: `https://${process.env.AGENT_HOST}/v3/`,
|
|
33
33
|
apiKey: process.env.BOT_API_KEY, // load from env
|
|
34
34
|
intentBotId: process.env.FORM_BUILD_INTENT_BOT_ID || '7615799745042186240',
|
|
35
35
|
},
|
|
36
36
|
|
|
37
37
|
fill: {
|
|
38
38
|
botId: process.env.FILL_BOT_ID || '7586483957357608960',
|
|
39
|
-
baseUrl: `
|
|
39
|
+
baseUrl: `https://${process.env.AGENT_HOST}/v3/`,
|
|
40
40
|
apiKey: process.env.BOT_API_KEY, // load from env
|
|
41
41
|
ocrApiKey: process.env.OCR_API_KEY || '', // load from env
|
|
42
42
|
},
|
|
@@ -45,9 +45,17 @@ export default {
|
|
|
45
45
|
report: {
|
|
46
46
|
query: {
|
|
47
47
|
botId: process.env.QUERY_BOT_ID || '7595888372090929152',
|
|
48
|
-
baseUrl: `
|
|
48
|
+
baseUrl: `https://${process.env.AGENT_HOST}/v3/`,
|
|
49
49
|
apiKey: process.env.BOT_API_KEY, // load from env
|
|
50
50
|
},
|
|
51
51
|
},
|
|
52
|
+
|
|
53
|
+
asr: {
|
|
54
|
+
appid: process.env.VOLC_APPID || '',
|
|
55
|
+
token: process.env.VOLC_TOKEN || '',
|
|
56
|
+
secretKey: process.env.VOLC_SECRET_KEY || '',
|
|
57
|
+
cluster: process.env.VOLC_CLUSTER || '',
|
|
58
|
+
host: process.env.VOLC_ASR_HOST || 'openspeech.bytedance.com',
|
|
59
|
+
},
|
|
52
60
|
},
|
|
53
61
|
};
|
package/dist/config/default.js
CHANGED
|
@@ -14,22 +14,22 @@ export default {
|
|
|
14
14
|
},
|
|
15
15
|
agent: {
|
|
16
16
|
host: process.env.AGENT_HOST || '47.99.202.157',
|
|
17
|
-
apiAuthKey: process.env.
|
|
17
|
+
apiAuthKey: process.env.BOT_API_KEY,
|
|
18
18
|
userId: process.env.BUILTIN_COZE_USER_ID,
|
|
19
19
|
common: {
|
|
20
|
-
baseUrl: `
|
|
20
|
+
baseUrl: `https://${process.env.AGENT_HOST}/v3/`,
|
|
21
21
|
apiKey: process.env.BOT_API_KEY, // load from env
|
|
22
22
|
},
|
|
23
23
|
form: {
|
|
24
24
|
build: {
|
|
25
25
|
botId: process.env.BUILD_BOT_ID || '7579927677256073216',
|
|
26
|
-
baseUrl: `
|
|
26
|
+
baseUrl: `https://${process.env.AGENT_HOST}/v3/`,
|
|
27
27
|
apiKey: process.env.BOT_API_KEY, // load from env
|
|
28
28
|
intentBotId: process.env.FORM_BUILD_INTENT_BOT_ID || '7615799745042186240',
|
|
29
29
|
},
|
|
30
30
|
fill: {
|
|
31
31
|
botId: process.env.FILL_BOT_ID || '7586483957357608960',
|
|
32
|
-
baseUrl: `
|
|
32
|
+
baseUrl: `https://${process.env.AGENT_HOST}/v3/`,
|
|
33
33
|
apiKey: process.env.BOT_API_KEY, // load from env
|
|
34
34
|
ocrApiKey: process.env.OCR_API_KEY || '', // load from env
|
|
35
35
|
},
|
|
@@ -37,9 +37,16 @@ export default {
|
|
|
37
37
|
report: {
|
|
38
38
|
query: {
|
|
39
39
|
botId: process.env.QUERY_BOT_ID || '7595888372090929152',
|
|
40
|
-
baseUrl: `
|
|
40
|
+
baseUrl: `https://${process.env.AGENT_HOST}/v3/`,
|
|
41
41
|
apiKey: process.env.BOT_API_KEY, // load from env
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
|
+
asr: {
|
|
45
|
+
appid: process.env.VOLC_APPID || '',
|
|
46
|
+
token: process.env.VOLC_TOKEN || '',
|
|
47
|
+
secretKey: process.env.VOLC_SECRET_KEY || '',
|
|
48
|
+
cluster: process.env.VOLC_CLUSTER || '',
|
|
49
|
+
host: process.env.VOLC_ASR_HOST || 'openspeech.bytedance.com',
|
|
50
|
+
},
|
|
44
51
|
},
|
|
45
52
|
};
|
package/dist/src/app/main.js
CHANGED
|
@@ -22,3 +22,12 @@ app.get('/web/api/health', (c) => {
|
|
|
22
22
|
service: 'hono-app',
|
|
23
23
|
});
|
|
24
24
|
});
|
|
25
|
+
// 挂载 ASR WebSocket Server
|
|
26
|
+
import { WebSocketServer } from 'ws';
|
|
27
|
+
import { server } from '../config/hono.config.js';
|
|
28
|
+
import { handleASRConnection } from '../services/asr/asr-websocket.js';
|
|
29
|
+
const wss = new WebSocketServer({
|
|
30
|
+
server: server,
|
|
31
|
+
path: '/web/api/asr',
|
|
32
|
+
});
|
|
33
|
+
wss.on('connection', handleASRConnection);
|
|
@@ -36,11 +36,12 @@ app.onError((err, c) => {
|
|
|
36
36
|
// 返回统一的 JSON 错误响应
|
|
37
37
|
return c.json({ message: 'Internal Server Error' }, 500);
|
|
38
38
|
});
|
|
39
|
-
serve({
|
|
39
|
+
const server = serve({
|
|
40
40
|
fetch: app.fetch,
|
|
41
41
|
hostname: config.get('app.host') || '',
|
|
42
42
|
port: config.get('app.port') || 3001,
|
|
43
43
|
}, (info) => {
|
|
44
44
|
logger.info(`Server is running on http://localhost:${info.port}`);
|
|
45
45
|
});
|
|
46
|
+
export { server };
|
|
46
47
|
export default app;
|
|
@@ -3,7 +3,7 @@ import { logger } from '../../logger/index.js';
|
|
|
3
3
|
import { safeJsonParser } from '../../utils/safeJsonParser.js';
|
|
4
4
|
export const listBots = async (c) => {
|
|
5
5
|
const agentHost = config.get('agent.host');
|
|
6
|
-
const apiBots = `
|
|
6
|
+
const apiBots = `https://${agentHost}/v1/bots`;
|
|
7
7
|
const cozeInfo = c.get('X-Coze-Info');
|
|
8
8
|
logger.debug(`Fetching bots from ${apiBots} with cozeToken: ${cozeInfo.cozeToken}`);
|
|
9
9
|
const result = await fetch(apiBots, {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { convertToModelMessages, streamText } from 'ai';
|
|
2
2
|
import { createBaseModel } from './model.js';
|
|
3
|
+
import { logger } from '../../logger/index.js';
|
|
3
4
|
export const connectToAgent = async (c) => {
|
|
4
5
|
let requestBody;
|
|
5
6
|
try {
|
|
@@ -12,13 +13,14 @@ export const connectToAgent = async (c) => {
|
|
|
12
13
|
const cozeInfo = c.get('X-Coze-Info');
|
|
13
14
|
const messages = requestBody.messages;
|
|
14
15
|
const botId = c.req.header('X-Bot-Id') || '';
|
|
16
|
+
logger.debug('enter common controller');
|
|
15
17
|
const stream = streamText({
|
|
16
|
-
model: createBaseModel(botId, cozeInfo
|
|
18
|
+
model: createBaseModel(botId, cozeInfo?.cozeToken),
|
|
17
19
|
messages: convertToModelMessages(messages),
|
|
18
20
|
includeRawChunks: true,
|
|
19
21
|
headers: {
|
|
20
22
|
'x-user-var': requestBody.userVar,
|
|
21
|
-
'x-user-id': cozeInfo
|
|
23
|
+
'x-user-id': cozeInfo?.userId,
|
|
22
24
|
},
|
|
23
25
|
});
|
|
24
26
|
return stream.toUIMessageStreamResponse();
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { createCoze } from '@baishuyun/coze-provider';
|
|
2
2
|
import config from 'config';
|
|
3
|
+
import { createAgentCallingListener } from './transformer-factory/agent-calling-listener.js';
|
|
3
4
|
export const createBaseModel = (botId, token) => {
|
|
4
5
|
const coze = createCoze({
|
|
5
6
|
apiKey: token || config.get('agent.common.apiKey'),
|
|
6
7
|
baseURL: config.get('agent.common.baseUrl'),
|
|
7
8
|
botId: botId,
|
|
9
|
+
extraStreamTransformers: [createAgentCallingListener],
|
|
8
10
|
});
|
|
9
11
|
return coze.chat('chat');
|
|
10
12
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createJsonStreamTransformer, } from '../../../utils/createJsonStreamTransformer.js';
|
|
2
|
+
import { JSONParser } from '@streamparser/json';
|
|
3
|
+
import { isTargetElement } from '../../report/query/utils.js';
|
|
4
|
+
function createJSONParser() {
|
|
5
|
+
return new JSONParser({
|
|
6
|
+
stringBufferSize: undefined,
|
|
7
|
+
numberBufferSize: undefined,
|
|
8
|
+
separator: '',
|
|
9
|
+
paths: ['$.type', '$.prompt', '$.agent'],
|
|
10
|
+
keepStack: true,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export const fieldHandlers = [
|
|
14
|
+
{
|
|
15
|
+
path: '$.type',
|
|
16
|
+
handler: (ctx, value) => ctx.setPartialResult({ type: value }),
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
path: '$.prompt',
|
|
20
|
+
handler: (ctx, value) => ctx.setPartialResult({ prompt: value }),
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
path: '$.agent',
|
|
24
|
+
handler: (ctx, value) => ctx.setPartialResult({ agent: value }),
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
function handleParsedValue(ctx) {
|
|
28
|
+
const { parsedInfo, getResult, currentChunkId, deltaChunkEnqueuer: enqueueTextDelta, ctrl } = ctx;
|
|
29
|
+
const { value } = parsedInfo;
|
|
30
|
+
for (const { path, handler } of fieldHandlers) {
|
|
31
|
+
if (isTargetElement(path, parsedInfo)) {
|
|
32
|
+
handler(ctx, value);
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
enqueueTextDelta(`${JSON.stringify(value)},`, { type: 'agent-calling', result: JSON.stringify(getResult()) }, currentChunkId, true);
|
|
37
|
+
}
|
|
38
|
+
export const createAgentCallingListener = () => {
|
|
39
|
+
return createJsonStreamTransformer({
|
|
40
|
+
bypassParseError: true,
|
|
41
|
+
createJSONParser,
|
|
42
|
+
onParseValue: handleParsedValue,
|
|
43
|
+
});
|
|
44
|
+
};
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {} from
|
|
2
|
-
import config from
|
|
3
|
-
import { logger } from
|
|
4
|
-
import { parseImg } from
|
|
1
|
+
import {} from 'hono';
|
|
2
|
+
import config from 'config';
|
|
3
|
+
import { logger } from '../../logger/index.js';
|
|
4
|
+
import { parseImg } from './fill/utils.js';
|
|
5
5
|
export const uploadAttachment = async (c) => {
|
|
6
6
|
const formData = await c.req.formData();
|
|
7
|
-
const file = formData.get(
|
|
7
|
+
const file = formData.get('file'); // as FormData | null;
|
|
8
8
|
// 校验文件是否存在
|
|
9
9
|
if (!file || !(file instanceof Blob)) {
|
|
10
|
-
return c.json({ error:
|
|
10
|
+
return c.json({ error: '请上传有效的文件' }, 400);
|
|
11
11
|
}
|
|
12
12
|
const forwardFormData = new FormData();
|
|
13
|
-
forwardFormData.append(
|
|
14
|
-
const apiKey = config.get(
|
|
15
|
-
const host = config.get(
|
|
16
|
-
const api = `
|
|
13
|
+
forwardFormData.append('file', file);
|
|
14
|
+
const apiKey = config.get('agent.apiAuthKey');
|
|
15
|
+
const host = config.get('agent.host');
|
|
16
|
+
const api = `https://${host}/v1/files/upload`;
|
|
17
17
|
logger.debug(c.body);
|
|
18
18
|
const response = await fetch(api, {
|
|
19
|
-
method:
|
|
19
|
+
method: 'POST',
|
|
20
20
|
body: formData,
|
|
21
21
|
headers: {
|
|
22
22
|
// Add any auth headers
|
|
@@ -24,9 +24,7 @@ export const uploadAttachment = async (c) => {
|
|
|
24
24
|
},
|
|
25
25
|
});
|
|
26
26
|
if (!response.ok) {
|
|
27
|
-
const errorData = await response
|
|
28
|
-
.json()
|
|
29
|
-
.catch(() => ({ message: "上传失败" }));
|
|
27
|
+
const errorData = await response.json().catch(() => ({ message: '上传失败' }));
|
|
30
28
|
return c.json({
|
|
31
29
|
error: `目标接口返回错误: ${errorData.message}`,
|
|
32
30
|
status: response.status,
|
|
@@ -35,8 +33,10 @@ export const uploadAttachment = async (c) => {
|
|
|
35
33
|
const data = await response.json();
|
|
36
34
|
const { url, uri, ...rest } = data?.data || {};
|
|
37
35
|
const orcResult = await parseImg(file);
|
|
36
|
+
// replace file url protol to https
|
|
37
|
+
const secureUrl = url.replace('http://', 'https://');
|
|
38
38
|
return c.json({
|
|
39
|
-
url,
|
|
39
|
+
url: secureUrl,
|
|
40
40
|
name: uri,
|
|
41
41
|
contentType: file.type,
|
|
42
42
|
parsedData: orcResult,
|
|
@@ -37,13 +37,14 @@ export const buildForm = async (c) => {
|
|
|
37
37
|
}
|
|
38
38
|
return {
|
|
39
39
|
type: "text",
|
|
40
|
-
text: `【确认搭建:${formName}】
|
|
40
|
+
text: `【确认搭建:${formName}】 ${p.text}`
|
|
41
41
|
};
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
+
const lastSecondMsg = allMsg.length > 1 ? allMsg[allMsg.length - 2] : null;
|
|
44
45
|
const stream = streamText({
|
|
45
46
|
model,
|
|
46
|
-
messages: convertToModelMessages([lastUserMsg]),
|
|
47
|
+
messages: convertToModelMessages([lastSecondMsg, lastUserMsg].filter(Boolean)),
|
|
47
48
|
includeRawChunks: true,
|
|
48
49
|
headers: {
|
|
49
50
|
"x-user-stage": intent,
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import config from
|
|
1
|
+
import config from 'config';
|
|
2
2
|
export const clearConversation = async (c) => {
|
|
3
3
|
let requestBody;
|
|
4
|
-
const agentHost = config.get(
|
|
5
|
-
const baseUrl = `
|
|
6
|
-
const apiKey = config.get(
|
|
4
|
+
const agentHost = config.get('agent.host');
|
|
5
|
+
const baseUrl = `https://${agentHost}/v1`;
|
|
6
|
+
const apiKey = config.get('agent.apiAuthKey');
|
|
7
7
|
try {
|
|
8
8
|
const json = await c.req.json();
|
|
9
9
|
requestBody = json;
|
|
10
10
|
}
|
|
11
11
|
catch (_) {
|
|
12
|
-
return c.json({ error:
|
|
12
|
+
return c.json({ error: 'Invalid JSON' }, 400);
|
|
13
13
|
}
|
|
14
14
|
const result = await fetch(`${baseUrl}/conversations/${requestBody.conversationId}/clear`, {
|
|
15
|
-
method:
|
|
15
|
+
method: 'POST',
|
|
16
16
|
headers: {
|
|
17
17
|
// Add any auth headers
|
|
18
18
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -2,7 +2,7 @@ import {} from 'hono';
|
|
|
2
2
|
import { convertToModelMessages, streamText, createUIMessageStream, createUIMessageStreamResponse, generateId, } from 'ai';
|
|
3
3
|
import { logger } from '../../../logger/index.js';
|
|
4
4
|
import { createBatchFillingModel } from './model.js';
|
|
5
|
-
import { mode2part } from './utils.js';
|
|
5
|
+
import { extraGeneratePromptFromRandomContent, mode2part } from './utils.js';
|
|
6
6
|
const getModelMessagesFromUserMessages = ({ continueMessageId, currentMsg, formStructure, mode, messages, }) => {
|
|
7
7
|
// init fill
|
|
8
8
|
if (continueMessageId && currentMsg) {
|
|
@@ -12,7 +12,7 @@ const getModelMessagesFromUserMessages = ({ continueMessageId, currentMsg, formS
|
|
|
12
12
|
parts: [
|
|
13
13
|
{
|
|
14
14
|
type: 'text',
|
|
15
|
-
text:
|
|
15
|
+
text: `\n\n${extraGeneratePromptFromRandomContent()}\n\nformStructure: ${JSON.stringify(formStructure)}\n\n`,
|
|
16
16
|
},
|
|
17
17
|
mode2part(mode),
|
|
18
18
|
{
|
|
@@ -30,7 +30,7 @@ const getModelMessagesFromUserMessages = ({ continueMessageId, currentMsg, formS
|
|
|
30
30
|
};
|
|
31
31
|
lastUserMsg.parts.push({
|
|
32
32
|
type: 'text',
|
|
33
|
-
text:
|
|
33
|
+
text: `\n\n${extraGeneratePromptFromRandomContent()}\n\nformStructure: ${JSON.stringify(formStructure)}\n\n`,
|
|
34
34
|
});
|
|
35
35
|
lastUserMsg.parts.push(mode2part(mode));
|
|
36
36
|
return convertToModelMessages([lastUserMsg]);
|
|
@@ -118,7 +118,6 @@ async function handleContinueGeneration(c, { messages, continueMessageId, mode,
|
|
|
118
118
|
mode,
|
|
119
119
|
formStructure,
|
|
120
120
|
});
|
|
121
|
-
logger.debug(`continue modelMessages ${JSON.stringify(modelMessages)}`);
|
|
122
121
|
const result = streamText({
|
|
123
122
|
model: createBatchFillingModel(),
|
|
124
123
|
messages: modelMessages,
|
|
@@ -85,23 +85,7 @@ export const createBatchFillingResultTransformer = (enableJsonParser) => {
|
|
|
85
85
|
controller.terminate(); // 信号通知下游可读流已关闭
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
|
-
|
|
89
|
-
if (subFormField) {
|
|
90
|
-
// enqueueTextDelta(
|
|
91
|
-
// JSON.stringify(value),
|
|
92
|
-
// {
|
|
93
|
-
// type: 'mcp-fields-json',
|
|
94
|
-
// field: subFormField.value,
|
|
95
|
-
// },
|
|
96
|
-
// id,
|
|
97
|
-
// true
|
|
98
|
-
// );
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (value.fieldType === 'subform') {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
// logger.debug(`id in onValue: ${id}`);
|
|
88
|
+
// logger.debug(`onValue: ${JSON.stringify(value, null, 2)}`);
|
|
105
89
|
enqueueTextDelta(`${JSON.stringify(value)},`, {
|
|
106
90
|
type: 'mcp-fields-json',
|
|
107
91
|
field: value,
|
|
@@ -22,6 +22,7 @@ export const fillForm = async (c) => {
|
|
|
22
22
|
const mode = requestBody.mode;
|
|
23
23
|
const num = requestBody.count;
|
|
24
24
|
const messages = requestBody.messages;
|
|
25
|
+
logger.debug('enter fillForm controller');
|
|
25
26
|
// 如果是批量填写,调用批量填写接口
|
|
26
27
|
if (mode === 'batch') {
|
|
27
28
|
return batchFillForm(c);
|
|
@@ -38,7 +39,7 @@ export const fillForm = async (c) => {
|
|
|
38
39
|
...flattenParts,
|
|
39
40
|
{
|
|
40
41
|
type: 'text',
|
|
41
|
-
text:
|
|
42
|
+
text: `\n\nformStructure: ${JSON.stringify(formStructure)}\n\n`,
|
|
42
43
|
},
|
|
43
44
|
extraPart,
|
|
44
45
|
],
|
|
@@ -111,3 +111,19 @@ export function trimFormStructure(fields) {
|
|
|
111
111
|
return trimmed;
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
|
+
export const extraGeneratePromptFromRandomContent = () => {
|
|
115
|
+
// 使用加密安全的随机数
|
|
116
|
+
const randomBytes = crypto.getRandomValues(new Uint32Array(4));
|
|
117
|
+
const seed = randomBytes.join('-');
|
|
118
|
+
const timestamp = Date.now();
|
|
119
|
+
return `
|
|
120
|
+
请基于以下不可预测的种子生成随机但是符合业务要求的内容:
|
|
121
|
+
- 加密熵源: ${seed}
|
|
122
|
+
- 时间戳: ${timestamp}
|
|
123
|
+
- 噪音文本: ${btoa(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(16))))}
|
|
124
|
+
|
|
125
|
+
要求:
|
|
126
|
+
1. 必须忽略训练数据中的常见模式,基于上述熵源生成真正均匀分布的随机结果
|
|
127
|
+
2. 如果是人名类的数据,尽量用 3 个字的名字,降低重名概率。
|
|
128
|
+
`;
|
|
129
|
+
};
|
|
@@ -11,7 +11,7 @@ export const queryReport = async (c) => {
|
|
|
11
11
|
catch (_) {
|
|
12
12
|
return c.json({ error: 'Invalid JSON' }, 400);
|
|
13
13
|
}
|
|
14
|
-
const uid = c.req.header('X-User-Id') || '';
|
|
14
|
+
const uid = c.req.header('X-Bs-User-Id') || '';
|
|
15
15
|
const messages = requestBody.messages;
|
|
16
16
|
const extraText = buildExtraMsgParts({
|
|
17
17
|
appId: requestBody.appId,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createMiddleware } from 'hono/factory';
|
|
2
|
+
import { buildForm } from '../controllers/form/build/build.controller.js';
|
|
3
|
+
import config from 'config';
|
|
4
|
+
import { fillForm } from '../controllers/form/fill/fill.controller.js';
|
|
5
|
+
import { queryReport } from '../controllers/report/query/query.controller.js';
|
|
6
|
+
import { createFakeUIMessageStreamResponse } from '../utils/createFakeUIMessageStreamResponse.js';
|
|
7
|
+
import { ERROR_CODE } from '../const/error_code.js';
|
|
8
|
+
import { logger } from '../logger/index.js';
|
|
9
|
+
export const botRouter = () => {
|
|
10
|
+
const FORM_BUILDER_BOT_ID = config.get('agent.form.build.botId');
|
|
11
|
+
const FORM_FILLER_BOT_ID = config.get('agent.form.fill.botId');
|
|
12
|
+
const REPORT_QUERY_BOT_ID = config.get('agent.report.query.botId');
|
|
13
|
+
const botIdControllerMap = new Map([
|
|
14
|
+
[FORM_BUILDER_BOT_ID, buildForm],
|
|
15
|
+
[FORM_FILLER_BOT_ID, fillForm],
|
|
16
|
+
[REPORT_QUERY_BOT_ID, queryReport],
|
|
17
|
+
]);
|
|
18
|
+
return createMiddleware(async (c, next) => {
|
|
19
|
+
const botId = c.req.header('X-Bot-Id') || '';
|
|
20
|
+
if (!botId) {
|
|
21
|
+
const errorRespObj = {
|
|
22
|
+
error: 'Bot ID is required',
|
|
23
|
+
code: ERROR_CODE.BOT_ID_MISSING,
|
|
24
|
+
};
|
|
25
|
+
return createFakeUIMessageStreamResponse(JSON.stringify(errorRespObj));
|
|
26
|
+
}
|
|
27
|
+
if (botIdControllerMap.has(botId)) {
|
|
28
|
+
const controller = botIdControllerMap.get(botId);
|
|
29
|
+
return await controller(c);
|
|
30
|
+
}
|
|
31
|
+
logger.debug(`No controller found for botId: ${botId}, passing to next middleware`);
|
|
32
|
+
await next();
|
|
33
|
+
});
|
|
34
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import { connectToAgent } from '../../controllers/common/connect.controll.js';
|
|
3
3
|
import { tokenExchange } from '../../middleware/tokenExchange.js';
|
|
4
|
+
import { botRouter } from '../../middleware/botRouter.js';
|
|
4
5
|
export const createCommonRouter = () => {
|
|
5
6
|
const commonRouter = new Hono();
|
|
6
|
-
commonRouter.post('/connect', tokenExchange(), connectToAgent);
|
|
7
|
+
commonRouter.post('/connect', /*tokenExchange(),*/ botRouter(), connectToAgent);
|
|
7
8
|
return commonRouter;
|
|
8
9
|
};
|