UNPKG

@difizen/magent-au

Version:
304 lines (269 loc) 8.49 kB
import type { ChatEventChunk, ChatEventError, IChatEvent } from '@difizen/magent-chat'; import { ChatEvent } from '@difizen/magent-chat'; import { autoFactory, AutoFactoryOption, Fetcher } from '@difizen/magent-core'; import { inject, prop } from '@difizen/mana-app'; import { AgentManager } from '../agent/agent-manager.js'; import { AUAgentChatMessageItem } from './ai-message-item.js'; import { AUChatEvent } from './protocol.js'; import type { AUChatMessageItemOption, ChatEventResult, ChatEventStep, ChatEventStepQA, StepContent, } from './protocol.js'; @autoFactory() export class PeerChatMessageItem extends AUAgentChatMessageItem { @prop() contentMap: Record<string, string> = {}; @prop() planningPlanner: string; @prop() executingPlanner: string; @prop() expressingPlanner: string; @prop() reviewingPlanner: string; // @prop() // currentStep = 0; @prop() steps: ChatEventStep[] = []; lastChunkAgent?: string; @prop() received = false; // @prop() // planningContent = ''; // @prop() // executingContent: ChatEventStepQA[] = []; // @prop() // expressingContent = ''; // @prop() // reviewingContent = ''; @prop() currRound: number; @prop() roundsContent: StepContent[]; @prop() protected currRoundContent: StepContent; protected _isConstructorInitialized = false; constructor( @inject(AutoFactoryOption) option: AUChatMessageItemOption, @inject(Fetcher) fetcher: Fetcher, @inject(AgentManager) agentManager: AgentManager, ) { super(option, fetcher, agentManager); this.agentReady = this.agentDeferred.promise; this.addEmptyRoundContent(0); this.initialize(); this._isConstructorInitialized = true; } /** * @param roundStartsAt 当前轮从第几步开始 */ protected addEmptyRoundContent = (roundStartsAt: number) => { if (this.currRound === undefined) { this.currRound = -1; } this.currRound += 1; this.currRoundContent = { currentStep: 0, roundStartsAt, // 第一轮肯定从planner开始 planningContent: '', executingContent: [], expressingContent: '', reviewingContent: '', }; if (!this.roundsContent) { this.roundsContent = []; } this.roundsContent.push(this.currRoundContent); }; override initialize = async () => { await this.getAgent(); if (!this.agent) { throw new Error('Cannot access agent'); } await this.agent.ready; if (!this.agent.planner?.members) { throw new Error('Missing PEER member'); } const members = this.agent?.planner?.members; if (!members) { return; } const planning = members[0]; this.planningPlanner = planning.id; const executing = members[1]; this.executingPlanner = executing.id; const expressing = members[2]; this.expressingPlanner = expressing.id; const reviewing = members[3]; this.currRoundContent.reviewingContent = this.contentMap[this.reviewingPlanner]; this.currRoundContent.planningContent = this.contentMap[this.planningPlanner]; this.currRoundContent.expressingContent = this.contentMap[this.expressingPlanner]; this.contentMap[this.expressingPlanner] = this._content; this.reviewingPlanner = reviewing.id; }; override get content(): string { if (this.currRoundContent.expressingContent) { return this.currRoundContent.expressingContent; } if (this.expressingPlanner) { return this.contentMap[this.expressingPlanner] || ''; } return this._content || ''; } override set content(v) { if (!this._isConstructorInitialized) { this._content = v; return; } if (this.currRoundContent.expressingContent) { this.currRoundContent.expressingContent = v; } if (this.expressingPlanner) { this.contentMap[this.expressingPlanner] = v; } else { this._content = v; } } /** * * @param agent_id 当前chunk的agent_id * 判断当前是不是需要开启新的一轮对话执行。 */ protected judgeAndAddEmptyRound = (agent_id: string) => { switch (agent_id) { case this.planningPlanner: case this.executingPlanner: // expressingContent有可能是undefined if ( this.currRound >= 0 && this.roundsContent[this.currRound].expressingContent && this.roundsContent[this.currRound].expressingContent !== '' ) { this.addEmptyRoundContent(agent_id === this.planningPlanner ? 0 : 1); } break; case this.expressingPlanner: if ( this.currRound >= 0 && this.roundsContent[this.currRound].reviewingContent && // 有可能undefined this.roundsContent[this.currRound].reviewingContent !== '' ) { this.addEmptyRoundContent(2); } break; case this.reviewingPlanner: // 一般不会有某一轮对话一上来就是rwviewing break; } }; override appendChunk(e: ChatEventChunk) { if (this.planningPlanner) { this.judgeAndAddEmptyRound(e['agent_id']); switch (e['agent_id']) { case this.planningPlanner: this.currRoundContent.planningContent = `${this.currRoundContent.planningContent || ''}${e.output || ''}`; try { const data = JSON.parse(this.currRoundContent.planningContent); this.currRoundContent.planningContent = data.thought; this.currRoundContent.planningContent += '\n\n'; this.currRoundContent.planningContent += this.toContentStr( data.framework as string | string[], ); this.currRoundContent.currentStep = 1; } catch (e) { // console.error(e); } break; case this.expressingPlanner: this.currRoundContent.expressingContent = `${this.currRoundContent.expressingContent || ''}${e.output || ''}`; break; case this.reviewingPlanner: this.currRoundContent.reviewingContent = `${this.currRoundContent.reviewingContent || ''}${e.output || ''}`; break; default: break; } } else { this.contentMap[e['agent_id']] = `${this.contentMap[e['agent_id']] || ''}${e.output || ''}`; } if (this.lastChunkAgent !== e['agent_id']) { this.lastChunkAgent = e['agent_id']; } } protected toContentStr = (out: string | string[]) => { if (typeof out === 'string') { return out; } if (out instanceof Array) { return out .map((i) => { return `* ${i}`; }) .join('\n'); } return ''; }; override handleEventData(e: IChatEvent) { this.received = true; if (ChatEvent.isChunk(e)) { this.appendChunk(e as ChatEventChunk); } let eventStep = 0; if (e['agent_id'] === this.planningPlanner) { eventStep = 0; } if (e['agent_id'] === this.executingPlanner) { eventStep = 1; } if (e['agent_id'] === this.expressingPlanner) { eventStep = 2; } if (e['agent_id'] === this.reviewingPlanner) { eventStep = 3; } if (eventStep > this.currRoundContent.currentStep) { this.currRoundContent.currentStep = eventStep; } if (AUChatEvent.isResult(e)) { this.handleResult(e as ChatEventResult); } if (AUChatEvent.isStep(e)) { this.handleSteps(e as ChatEventStep); } if (ChatEvent.isError(e)) { this.handleError(e as ChatEventError); } } override handleSteps(e: ChatEventStep): void { let eventStep = 0; if (e.agent_id === this.planningPlanner) { eventStep = 1; } if (e.agent_id === this.executingPlanner) { eventStep = 2; this.currRoundContent.executingContent = e.output as ChatEventStepQA[]; } if (e.agent_id === this.expressingPlanner) { eventStep = 3; } if (e.agent_id === this.reviewingPlanner) { eventStep = 4; this.currRoundContent.reviewingContent = this.toContentStr( e.output as string | string[], ); } if (eventStep > this.currRoundContent.currentStep) { this.currRoundContent.currentStep = eventStep; } this.steps[eventStep] = e; } override handleResult(e: ChatEventResult): void { super.handleResult(e); const currRoundContent = this.roundsContent[this.currRound]; // TODO: 具体第几轮 currRoundContent.currentStep = 4; } }