remix-nlux
Version:
Remix IDE NLUX integration. Remix IDE is the leading IDE for building and deploying smart contracts on Ethereum. NLUX is a JavaScript and React library for building conversational AI experiences.
113 lines (97 loc) • 4.23 kB
text/typescript
import {ChatItemProps} from '@shared/components/ChatItem/props';
import {ChatSegmentItem} from '@shared/types/chatSegment/chatSegment';
import {ChatSegmentAiMessage} from '@shared/types/chatSegment/chatSegmentAiMessage';
import {ChatSegmentUserMessage} from '@shared/types/chatSegment/chatSegmentUserMessage';
import {BaseComp} from '../../../aiChat/comp/base';
import {CompEventListener, Model} from '../../../aiChat/comp/decorators';
import {HighlighterExtension} from '../../../aiChat/highlighter/highlighter';
import {ControllerContext} from '../../../types/controllerContext';
import {renderChatItem} from './chatItem.render';
import {CompChatItemActions, CompChatItemElements, CompChatItemEvents, CompChatItemProps} from './chatItem.types';
import {updateChatItem} from './chatItem.update';
export class CompChatItem<AiMsg> extends BaseComp<
AiMsg, CompChatItemProps, CompChatItemElements, CompChatItemEvents, CompChatItemActions
> {
private aiMessageContent: AiMsg | undefined;
private serverResponse: Array<string | object | undefined> = [];
private stringContent: string = '';
constructor(
context: ControllerContext<AiMsg>,
props: CompChatItemProps,
) {
super(context, props);
if (props.domProps.message !== undefined) {
this.stringContent = props.domProps.message;
}
}
public addChunk(chunk: AiMsg, serverResponse?: string | object) {
this.throwIfDestroyed();
this.executeDomAction('processStreamedChunk', chunk);
if (typeof chunk === 'string') {
this.stringContent += chunk;
}
this.serverResponse.push(serverResponse);
}
public commitChunks() {
this.throwIfDestroyed();
this.executeDomAction('commitStreamedChunks');
}
public getChatSegmentItem(): ChatSegmentItem<AiMsg> {
const domProps = this.getProp('domProps') as ChatItemProps;
if (domProps.direction === 'received') {
return {
uid: this.props.uid,
participantRole: 'assistant',
content: this.getItemContent() as AiMsg,
contentType: 'text',
serverResponse: this.serverResponse,
status: 'complete',
dataTransferMode: 'batch',
time: new Date(),
} satisfies ChatSegmentAiMessage<AiMsg>;
}
return {
uid: this.props.uid,
participantRole: 'user',
content: this.getItemContent() as string,
contentType: 'text',
status: 'complete',
time: new Date(),
} satisfies ChatSegmentUserMessage;
}
public getItemContent(): AiMsg | string {
return this.aiMessageContent ?? this.stringContent;
}
public updateDomProps(updatedProps: Partial<ChatItemProps>) {
const oldProps: ChatItemProps = this.getProp('domProps') as ChatItemProps;
const newProps: ChatItemProps = {
...oldProps,
...updatedProps,
};
this.setProp('domProps', newProps);
this.executeDomAction('updateDomProps', oldProps, newProps);
}
public updateMarkdownStreamRenderer(
newProp: keyof CompChatItemProps,
newValue: CompChatItemProps[typeof newProp],
) {
this.setProp(newProp, newValue);
if (newProp === 'syntaxHighlighter') {
const typedNewValue = newValue as HighlighterExtension | undefined;
this.executeDomAction('updateMarkdownStreamRenderer', {
syntaxHighlighter: typedNewValue,
} satisfies Partial<CompChatItemProps>);
}
if (newProp === 'htmlSanitizer') {
const typedNewValue = newValue as ((html: string) => string) | undefined;
this.executeDomAction('updateMarkdownStreamRenderer', {
htmlSanitizer: typedNewValue,
} satisfies Partial<CompChatItemProps>);
}
}
private onMarkdownStreamComplete(messageRendered: AiMsg) {
this.context.emit('messageRendered', {uid: this.props.uid});
}
}