import { ChatEventType, RoleType } from "@coze/api"; interface MessageHandler { canHandle(event: any, opts?: any, prevMessageList?: any[]): boolean; handle(event: any, prevMessageList: any[], opts?: any): any[]; } abstract class BaseMessageHandler implements MessageHandler { abstract canHandle(event: any, opts: any, prevMessageList?: any[]): boolean; abstract handle(event: any, prevMessageList: any[], opts: any): any[]; protected createMessage(content: string, role: RoleType, event: any, opts?: any) { const fileParseStatus = opts && opts.fileInfo ? event.data.type === "function_call" ? 1 : event.data.type === "tool_response" ? 2 : undefined:undefined return { content, role, fileInfo: (opts && opts.fileInfo) ? opts.fileInfo : undefined, fileParseStatus: fileParseStatus, event }; } } // 普通消息处理 添加欢迎语 class ConversationHelloHandler extends BaseMessageHandler { canHandle(event: any, opts: any, _prevMessageList?: any[]): boolean { return event.event_type === "conversation.created" && !opts.initMessage && !opts.fileInfo; } handle(event: any, prevMessageList: any[], _opts: any): any[] { return [ ...prevMessageList, this.createMessage(event.data.prologue, RoleType.Assistant, event,) ]; } } // 处理忽略的事件类型 class IgnoredEventHandler extends BaseMessageHandler { canHandle(event: any, _opts: any, _prevMessageList?: any[]): boolean { return ( (event.data.role === "assistant" && event.event_type === ChatEventType.CONVERSATION_MESSAGE_COMPLETED && event.data.type === "verbose") || (event.data.type === "answer" && event.event_type === ChatEventType.CONVERSATION_MESSAGE_COMPLETED) ); } handle(_event: any, prevMessageList: any[], _opts: any): any[] { // 直接返回原消息列表,不做任何更改 return prevMessageList; } } class UserMessageEventHandle extends BaseMessageHandler{ canHandle(event: any, _opts: any, _prevMessageList?: any[]): boolean { return event.event_type === ChatEventType.CONVERSATION_MESSAGE_COMPLETED && event.data.role === RoleType.User } handle(event: any, prevMessageList: any[], _opts: any): any[] { return [...prevMessageList,this.createMessage(event.data.content,event.data.role,event)] } } class NormalMessageEventHandle extends BaseMessageHandler{ canHandle(event: any, _opts: any, prevMessageList?: any[]): boolean { if(typeof prevMessageList === 'undefined'){ return false } let prevMessage = prevMessageList[prevMessageList.length - 1]; // 当前信息为增量,并且上一条信息为完成 if(prevMessage?.event.event_type === ChatEventType.CONVERSATION_MESSAGE_COMPLETED && event.event_type === ChatEventType.CONVERSATION_MESSAGE_DELTA){ return true }else{ return false; } } handle(event: any, prevMessageList: any[], _opts: any): any[] { return [...prevMessageList,this.createMessage(event.data.content,event.data.role,event)] } } class AppendMessageEventHandle extends BaseMessageHandler{ canHandle(event: any, _opts: any, prevMessageList?: any[]): boolean { if(typeof prevMessageList === 'undefined' || prevMessageList.length === 0){ return false; } let prevMessage = prevMessageList[prevMessageList.length - 1]; if(prevMessage.event?.event_type === ChatEventType.CONVERSATION_MESSAGE_DELTA && event.event_type === ChatEventType.CONVERSATION_MESSAGE_DELTA){ return true }else{ return false; } } handle(event: any, prevMessageList: any[], _opts: any): any[] { let prevMessage = prevMessageList[prevMessageList.length - 1]; return [...prevMessageList.slice(0,prevMessageList.length-1),{...prevMessage,content:prevMessage.content + event.data.content}] } } class BottomMessageEventHandle extends BaseMessageHandler{ canHandle(_event: any, _opts: any, _prevMessageList?: any[]): boolean { return true } handle(_event: any, _prevMessageList: any[], _opts: any): any[] { return _prevMessageList } } class FileFunctionCallEventHandle extends BaseMessageHandler{ canHandle(event: any, _opts: any, _prevMessageList?: any[]): boolean { if(event.data.type === "function_call"){ let jsonData = JSON.parse(event.data.content) return jsonData.name==='doc_reader-PDF_reader' && event.event_type === "conversation.message.completed" }else{ return false } } handle(event: any, prevMessageList: any[], opts: any): any[] { return [...prevMessageList,this.createMessage('',event.data.role,event,opts)] } } class FileFunctionResponseEventHandle extends BaseMessageHandler{ canHandle(event: any, _opts: any, prevMessageList?: any[]): boolean { if(typeof prevMessageList === 'undefined'){ return false } let prevMessage = prevMessageList[prevMessageList.length - 1]; if( prevMessage?.event.data.type === "function_call" && event.data.type ==="tool_response"){ return true }else { return false } } handle(event: any, prevMessageList: any[], opts: any): any[] { return [...prevMessageList.slice(0,prevMessageList.length-1),this.createMessage('',event.data.role,event,opts)] } } export class MessageHandlerStrategy { private handlers: MessageHandler[]; constructor() { this.handlers = [ new ConversationHelloHandler(), new IgnoredEventHandler(), new UserMessageEventHandle(), new NormalMessageEventHandle(), new AppendMessageEventHandle(), new FileFunctionCallEventHandle(), new FileFunctionResponseEventHandle(), new BottomMessageEventHandle() ]; } process(event: any, prevMessageList: any[], opts: any): any[] { for (const handler of this.handlers) { if (handler.canHandle(event, opts, prevMessageList)) { return handler.handle(event, prevMessageList, opts); } } return prevMessageList; // 理论上不会执行到这里 } }