UNPKG

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
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'; @Model('chatItem', renderChatItem, updateChatItem) 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>); } } @CompEventListener('markdown-stream-complete') private onMarkdownStreamComplete(messageRendered: AiMsg) { this.context.emit('messageRendered', {uid: this.props.uid}); } }