@plteam/chat-ui
Version:
CUI Kit is a free and open-source library for creating AI assistant chat interfaces, built with React, Material UI, and TypeScript
95 lines (94 loc) • 3.87 kB
JavaScript
import { StreamResponseState } from './ThreadModel';
import { MessageText } from './MessageText';
export class MessageSender {
content;
userMessage;
assistantMessage;
thread;
constructor(content, userMessage, assistantMessage, thread) {
this.content = content;
this.userMessage = userMessage;
this.assistantMessage = assistantMessage;
this.thread = thread;
}
_finished = false;
setText = (text) => {
if (!this._finished) {
this.changeTypingStatus(true);
}
this.assistantMessage.text = text;
};
pushChunk = (chunk) => {
if (!this.assistantMessage.text && this.thread.streamStatus.value !== StreamResponseState.TYPING_MESSAGE) {
this.thread.streamStatus.value = StreamResponseState.TYPING_MESSAGE;
}
this.assistantMessage.text += chunk;
};
setStatus = (status) => {
this.thread.streamStatus.value = status;
};
changeTypingStatus = (status) => {
if (status !== this.assistantMessage.typing.value) {
this.assistantMessage.typing.value = status;
if (!status) {
this._finished = true;
}
}
};
updateCurrentTextIndex = () => {
this.assistantMessage.texts.value = [
...this.assistantMessage.texts.value,
new MessageText(''),
];
};
getUserParams = (resolver, getInternalMessage) => {
const message = this.assistantMessage;
const internalUserMessage = getInternalMessage(this.userMessage);
const content = this.content;
let attachments = [];
if (Array.isArray(content)) {
attachments = content.filter(v => v.type !== 'text');
}
return {
content: this.content,
attachments,
history: this.thread.messages.currentMessages.value.map(getInternalMessage),
message: internalUserMessage,
assistantMessage: getInternalMessage(message),
toolType: this.thread.tool.value,
pushChunk: this.pushChunk,
setText: this.setText,
setStatus: this.setStatus,
onFinish: () => {
this.changeTypingStatus(false);
resolver({ message: internalUserMessage });
message.reasoningManager.updateTimeSec();
this.thread.isTyping.value = false;
message.data.content = message.texts.value.map((v) => ({
type: 'text',
text: v.text,
}));
},
reasoning: {
pushChunk: (chunk) => {
if (this.thread.streamStatus.value !== StreamResponseState.THINKING) {
this.thread.streamStatus.value = StreamResponseState.THINKING;
}
message.reasoningManager.pushChunk(chunk);
},
setFull: message.reasoningManager.setText,
setTitle: message.reasoningManager.setUserHeader,
setTimeSec: message.reasoningManager.setUserTimeSec,
setViewType: message.reasoningManager.setUserViewType,
unlockAutoManagement: message.reasoningManager.unlockAutoManagment,
},
actions: {
updateThreadId: (newId) => this.thread.id = newId,
updateThreadTitle: (newTitle) => this.thread.observableTitle.value = newTitle,
updateUserMessageId: (newId) => this.userMessage.data.id = newId,
updateAssistantMessageId: (newId) => message.data.id = newId,
updateCurrentTextIndex: this.updateCurrentTextIndex,
},
};
};
}