Skip to content

Commit

Permalink
feat: lark chatbi
Browse files Browse the repository at this point in the history
  • Loading branch information
meta-d committed Sep 28, 2024
1 parent 722110a commit 65a04a8
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 66 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<div class="flex items-end rounded-[2rem] p-2 bg-black/5 dark:bg-white/10">
<div class="flex items-end rounded-[2rem] p-2 active:scale-[.99] active:translate-y-0.5 transition-all
bg-black/5 dark:bg-white/10 active:bg-black/10 active:dark:bg-white/5">
<textarea #userInput matInput class="ngm-colpilot__input flex-1 w-full px-1.5 m-2 z-10 resize-none overflow-visible"
id="userInput" onInput="this.parentNode.dataset.replicatedValue = this.value"
[placeholder]="'PAC.Chat.MessageDigitalExpert' | translate: {Default: 'Message digital expert'}"
Expand Down
28 changes: 12 additions & 16 deletions packages/analytics/src/chatbi/commands/handlers/chatbi.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from '@metad/server-ai'
import { Inject, Logger } from '@nestjs/common'
import { CommandBus, CommandHandler, ICommandHandler } from '@nestjs/cqrs'
import { EMPTY, from, Observable } from 'rxjs'
import { IsNull } from 'typeorm'
import { ChatBIModelService } from '../../../chatbi-model'
import { SemanticModelMemberService } from '../../../model-member'
Expand Down Expand Up @@ -43,17 +42,15 @@ export class ChatBIHandler implements ICommandHandler<ChatBICommand> {
private readonly commandBus: CommandBus
) {}

public async execute(command: ChatBICommand): Promise<Observable<any>> {
public async execute(command: ChatBICommand): Promise<any> {
const { input } = command
const { tenant, organizationId, user, larkService } = input

const conversation = await this.getUserConversation(input)
if (!conversation) {
return from(
larkService.errorMessage(
input,
new Error(`Failed to create chat conversation for user: ${input.userId}`)
)
return await larkService.errorMessage(
input,
new Error(`Failed to create chat conversation for user: ${input.userId}`)
)
}

Expand All @@ -65,18 +62,17 @@ export class ChatBIHandler implements ICommandHandler<ChatBICommand> {
userId: user.id,
copilot: conversation.copilot
}))
return EMPTY
} catch(err) {
//
return await larkService.errorMessage(
input,
err
)
}

return new Observable((subscriber) => {
conversation.ask(input.text).then()
return () => {
// when cancel
conversation.destroy()
}
})
// Ask
conversation.ask(input.text).then()

return
}

async getUserConversation(input: ChatBILarkContext): Promise<ChatBIConversation> {
Expand Down
119 changes: 119 additions & 0 deletions packages/analytics/src/chatbi/tools/answer.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { createSlicersTitle } from './answer'

describe('Answer', () => {
beforeEach(async () => {
//
})

describe('createSlicersTitle', () => {
it('should return an array', async () => {
const result = createSlicersTitle([
{
dimension: {
dimension: '[0RTYPE]',
hierarchy: '[0RTYPE]',
parameter: '[!V000003]'
},
members: [
{
key: '[M]',
caption: '在平均比率下的标准兑换'
}
]
},
{
dimension: {
dimension: '[0CURRENCY]',
hierarchy: '[0CURRENCY]',
parameter: '[!V000004]'
},
members: [
{
key: '[USD]',
caption: 'USD'
}
]
},
{
dimension: {
dimension: '[2CP3MJ5KTNH8ZFZHFAZCH2WTDYK]',
hierarchy: '[2CP3MJ5KTNH8ZFZHFAZCH2WTDYK]'
},
members: [
{
key: '2024',
value: '2024'
}
]
}
])

console.log(result)

expect(result).toStrictEqual([])
})

it('should return an array', async () => {
const result = createSlicersTitle([
{
dimension: {
dimension: '[0RTYPE]',
hierarchy: '[0RTYPE]',
parameter: '[!V000003]'
},
members: [
{
key: '[M]',
caption: '在平均比率下的标准兑换'
}
]
},
{
dimension: {
dimension: '[0CURRENCY]',
hierarchy: '[0CURRENCY]',
parameter: '[!V000004]'
},
members: [
{
key: '[USD]',
caption: 'USD'
}
]
},
{
dimension: {
parameter: '',
dimension: '[2CISDDISTRCHANNEL]',
hierarchy: '[2CISDDISTRCHANNEL]',
level: '[2CISDDISTRCHANNEL].[LEVEL01]',
zeroSuppression: true
},
exclude: false,
members: [
{
key: '[00]',
caption: '通用'
}
]
},
{
dimension: {
dimension: '[2CP3MJ5KTNH8ZFZHFAZCH2WTDYK]',
hierarchy: '[2CP3MJ5KTNH8ZFZHFAZCH2WTDYK]'
},
members: [
{
key: '2024',
value: '2024'
}
]
}
])

console.log(result)

expect(result).toStrictEqual([])
})
})
})
29 changes: 2 additions & 27 deletions packages/analytics/src/chatbi/tools/answer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ import {
ChartAnnotation,
ChartBusinessService,
ChartDimensionRoleType,
ChartDimensionSchema,
ChartMeasureSchema,
DataSettings,
DataSettingsSchema,
Dimension,
EntityType,
FilteringLogic,
Expand All @@ -23,22 +20,18 @@ import {
isTimeRangesSlicer,
Measure,
OrderBy,
OrderBySchema,
PresentationVariant,
PropertyMeasure,
slicerAsString,
SlicerSchema,
TimeRangesSlicer,
timeRangesSlicerAsString,
TimeSlicerSchema,
toAdvancedFilter,
tryFixDimension,
tryFixSlicer,
tryFixVariableSlicer,
workOutTimeRangeSlicers
} from '@metad/ocap-core'
import { firstValueFrom, Subject, takeUntil } from 'rxjs'
import { z } from 'zod'
import { ChatLarkMessage } from '../message'
import { ChatAnswerSchema, ChatBILarkContext, ChatContext, IChatBIConversation } from '../types'
import { createBaseChart } from './charts/chart'
Expand All @@ -62,25 +55,6 @@ export type ChatAnswer = {
orders: OrderBy[]
}

// export const ChatAnswerSchema = z.object({
// preface: z.string().describe('preface of the answer'),
// visualType: z.enum(['Chart', 'Table', 'KPI']).describe('Visual type of result'),
// dataSettings: DataSettingsSchema.optional().describe('The data settings of the widget'),
// chartType: z
// .object({
// type: z.enum(['Column', 'Line', 'Pie', 'Bar']).describe('The type of chart')
// })
// .optional()
// .describe('Chart configuration'),
// dimensions: z.array(ChartDimensionSchema).optional().describe('The dimensions used by the chart'),
// measures: z.array(ChartMeasureSchema).optional().describe('The measures used by the chart'),
// orders: z.array(OrderBySchema).optional().describe('The orders used by the chart'),
// top: z.number().optional().describe('The number of top members'),
// slicers: z.array(SlicerSchema).optional().describe('The slicers to filter data'),
// timeSlicers: z.array(TimeSlicerSchema).optional().describe('The time slicers to filter data'),
// variables: z.array(VariableSchema).optional().describe('The variables to the query of cube'),
// conclusion: z.string().optional().describe('conclusion of the answer')
// })

export function createChatAnswerTool(context: ChatContext, larkContext: ChatBILarkContext) {
const { chatId, logger, dsCoreService, conversation } = context
Expand Down Expand Up @@ -242,7 +216,8 @@ const colors = [
'carmine' //洋红色
]

function createSlicersTitle(slicers: ISlicer[]) {
export function createSlicersTitle(slicers: ISlicer[]) {
// console.log(JSON.stringify(slicers, null, 2))
return slicers.map((slicer) => {
return {
tag: 'text_tag',
Expand Down
39 changes: 17 additions & 22 deletions packages/server/src/integration-lark/lark.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,28 +149,23 @@ export class LarkService {
this.logger.debug('im.message.receive_v1:')
this.logger.debug(data)

const user = await this.getUser(client, tenant.id, data.sender.sender_id.union_id)

const result = await this.commandBus.execute<LarkMessageCommand, Observable<any>>(
new LarkMessageCommand({
tenant,
organizationId,
integrationId: integration.id,
user,
message: data as any,
chatId,
chatType: data.message.chat_type,
larkService: this
})
)
result.subscribe({
next: () => {
//
},
error: () => {
//
}
})
try {
const user = await this.getUser(client, tenant.id, data.sender.sender_id.union_id)
await this.commandBus.execute<LarkMessageCommand, Observable<any>>(
new LarkMessageCommand({
tenant,
organizationId,
integrationId: integration.id,
user,
message: data as any,
chatId,
chatType: data.message.chat_type,
larkService: this
})
)
} catch(err) {
console.error(err)
}

this.logger.debug('Return for message:' + data.event_id)
return 'ok'
Expand Down

0 comments on commit 65a04a8

Please sign in to comment.