Skip to content

Commit dce15d5

Browse files
committed
feat: timeout in tool of chatbi lark
1 parent 4fdf462 commit dce15d5

File tree

5 files changed

+49
-54
lines changed

5 files changed

+49
-54
lines changed

packages/analytics/src/chatbi/conversation.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ import {
1818
} from '@metad/ocap-core'
1919
import {
2020
AgentState,
21-
Copilot,
2221
CopilotCheckpointSaver,
2322
CopilotKnowledgeService,
2423
createExampleFewShotPrompt,
25-
createLLM,
2624
createReactAgent,
2725
createReferencesRetrieverTool,
2826
} from '@metad/server-ai'
@@ -51,8 +49,9 @@ import { createIndicatorTool } from './tools/indicator'
5149
* ChatBI conversation for Lark
5250
*/
5351
export class ChatBIConversation implements IChatBIConversation {
52+
static readonly toolCallTimeout = 30 * 1000 // 30s
53+
5454
private readonly logger = new Logger(ChatBIConversation.name)
55-
static readonly toolCallTimeout = 10000
5655
readonly commandName = 'chatbi'
5756

5857
public id: string = null
@@ -339,7 +338,7 @@ ${createAgentStepsInstructions(
339338
if (isString(content) && content.startsWith('Error:')) {
340339
this.logger.error(content)
341340
const toolCallMessage = state.messages[state.messages.length - 2]
342-
this.logger.debug((<ToolMessage>toolCallMessage).lc_kwargs)
341+
this.logger.verbose((<ToolMessage>toolCallMessage).lc_kwargs)
343342
return 'agent'
344343
}
345344

@@ -443,7 +442,7 @@ ${createAgentStepsInstructions(
443442

444443
if (content) {
445444
verboseContent = content
446-
this.logger.debug(`[ChatBI] [Graph]: verbose content`, verboseContent)
445+
this.logger.debug(`[ChatBI] [Graph] verbose content: `, verboseContent)
447446
// 对话结束时还有正在思考的消息,则意味着出现错误
448447
if (['thinking', 'continuing', 'waiting'].includes(this.message?.status)) {
449448
this.message.update({
@@ -462,7 +461,7 @@ ${createAgentStepsInstructions(
462461
this.status = 'idle'
463462

464463
} catch (err: any) {
465-
console.error(err)
464+
this.logger.error(err)
466465
this.status = 'error'
467466
if (err instanceof ToolInputParsingException) {
468467
this.chatContext.larkService.errorMessage(this.chatContext, err)

packages/analytics/src/chatbi/tools/answer.ts

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
tryFixVariableSlicer,
3232
workOutTimeRangeSlicers
3333
} from '@metad/ocap-core'
34-
import { race } from '@metad/server-common'
34+
import { getErrorMessage, race } from '@metad/server-common'
3535
import { firstValueFrom, Subject, takeUntil } from 'rxjs'
3636
import { ChatBIConversation } from '../conversation'
3737
import { ChatLarkMessage } from '../message'
@@ -63,52 +63,46 @@ export function createChatAnswerTool(context: ChatContext, larkContext: ChatBILa
6363
async (answer): Promise<string> => {
6464
logger.debug(`Execute copilot action 'answerQuestion':`, JSON.stringify(answer, null, 2))
6565
try {
66-
try {
67-
// 限制总体超时时间
68-
return await race(
69-
ChatBIConversation.toolCallTimeout,
70-
(async () => {
71-
let entityType = null
72-
if (answer.dataSettings) {
73-
// Make sure datasource exists
74-
const _dataSource = await dsCoreService._getDataSource(answer.dataSettings.dataSource)
75-
const entity = await firstValueFrom(
76-
dsCoreService.selectEntitySet(
77-
answer.dataSettings.dataSource,
78-
answer.dataSettings.entitySet
79-
)
66+
// 限制总体超时时间
67+
return await race(
68+
ChatBIConversation.toolCallTimeout,
69+
(async () => {
70+
let entityType = null
71+
if (answer.dataSettings) {
72+
// Make sure datasource exists
73+
const _dataSource = await dsCoreService._getDataSource(answer.dataSettings.dataSource)
74+
const entity = await firstValueFrom(
75+
dsCoreService.selectEntitySet(
76+
answer.dataSettings.dataSource,
77+
answer.dataSettings.entitySet
8078
)
81-
entityType = entity.entityType
82-
}
83-
84-
// Fetch data for chart or table or kpi
85-
if (answer.dimensions?.length || answer.measures?.length) {
86-
const { categoryMembers } = await drawChartMessage(
87-
{ ...context, entityType: entityType || context.entityType },
88-
conversation,
89-
answer as ChatAnswer
90-
)
91-
// Max limit 20 members
92-
const members = categoryMembers
93-
? JSON.stringify(Object.values(categoryMembers).slice(0, 20))
94-
: 'Empty'
79+
)
80+
entityType = entity.entityType
81+
}
9582

96-
return `The analysis data has been displayed to the user. The dimension members involved in this data analysis are:
83+
// Fetch data for chart or table or kpi
84+
if (answer.dimensions?.length || answer.measures?.length) {
85+
const { categoryMembers } = await drawChartMessage(
86+
{ ...context, entityType: entityType || context.entityType },
87+
conversation,
88+
answer as ChatAnswer
89+
)
90+
// Max limit 20 members
91+
const members = categoryMembers
92+
? JSON.stringify(Object.values(categoryMembers).slice(0, 20))
93+
: 'Empty'
94+
95+
return `The analysis data has been displayed to the user. The dimension members involved in this data analysis are:
9796
${members}
9897
Please give more analysis suggestions about other dimensions or filter by dimensioin members, 3 will be enough.`
99-
}
100-
101-
return `图表答案已经回复给用户了,请不要重复回答了。`
102-
})()
103-
)
104-
} catch (err) {
105-
throw new Error(
106-
`Timeout in getting cube context (dataSource=${answer.dataSettings.dataSource}, cube=${answer.dataSettings.entitySet})`
107-
)
108-
}
98+
}
99+
100+
return `图表答案已经回复给用户了,请不要重复回答了。`
101+
})()
102+
)
109103
} catch (err) {
110-
logger.error(err)
111-
return `Error: ${err}。如果需要用户提供更多信息,请直接提醒用户。`
104+
logger.debug(getErrorMessage(err))
105+
return `Error: ${getErrorMessage(err)}; If more information is needed from the user, remind the user directly.`
112106
}
113107
},
114108
{

packages/analytics/src/chatbi/tools/cube-context.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { tool } from '@langchain/core/tools'
22
import { isEntitySet, markdownModelCube } from '@metad/ocap-core'
3-
import { race } from '@metad/server-common'
3+
import { getErrorMessage, race } from '@metad/server-common'
44
import { firstValueFrom, switchMap } from 'rxjs'
55
import { ChatBIModelService } from '../../chatbi-model/'
66
import { ChatContext, GetCubesContextSchema } from '../types'
@@ -17,7 +17,7 @@ export function createCubeContextTool(context: ChatContext, modelService: ChatBI
1717
(async () => {
1818
let context = ''
1919
for await (const item of cubes) {
20-
logger.debug(` get context for:`, item.modelId, item.name)
20+
logger.debug(` get context for (modelId=${item.modelId}, cube=${item.name})`)
2121

2222
let entityType = await conversation.getCubeCache(item.modelId, item.name)
2323
if (!entityType) {
@@ -53,7 +53,9 @@ export function createCubeContextTool(context: ChatContext, modelService: ChatBI
5353
})()
5454
)
5555
} catch (err) {
56-
return 'Error:' + err.message
56+
const errorInfo = 'Error: ' + getErrorMessage(err)
57+
logger.debug(`Call getCubeContext: ` + errorInfo)
58+
return errorInfo
5759
}
5860
},
5961
{

packages/analytics/src/data-source/queries/handlers/olap-query.handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class OlapQueryHandler implements IQueryHandler<DataSourceOlapQuery> {
2727
const { id, sessionId, dataSourceId, body, forceRefresh, acceptLanguage } = query.input
2828
const user = query.user
2929

30-
this.logger.debug(`Executing OLAP query [${id}] for dataSource: ${dataSourceId}`)
30+
this.logger.verbose(`Executing OLAP query [${id}] for dataSource: ${dataSourceId}`)
3131

3232
let dataSource = await this.dsService.findOne(dataSourceId, {
3333
relations: ['type', 'authentications']

packages/analytics/src/model/queries/handlers/olap-query.handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ITryRequest, RequestContext } from '@metad/server-core'
1+
import { ITryRequest } from '@metad/server-core'
22
import { Logger } from '@nestjs/common'
33
import { ConfigService } from '@nestjs/config'
44
import { IQueryHandler, QueryBus, QueryHandler } from '@nestjs/cqrs'
@@ -26,7 +26,7 @@ export class ModelOlapQueryHandler implements IQueryHandler<ModelOlapQuery> {
2626
const { id, sessionId, modelId, body, forceRefresh, acceptLanguage } = query.input
2727
const user = query.user
2828

29-
this.logger.debug(`Executing OLAP query [${id}] for model: ${modelId}`)
29+
this.logger.verbose(`Executing OLAP query [${id}] for model: ${modelId}`)
3030

3131
let key = ''
3232
const model = await this.semanticModelService.findOne(modelId, {

0 commit comments

Comments
 (0)