Skip to content

Commit

Permalink
Updated integration of syntax highlighter
Browse files Browse the repository at this point in the history
  • Loading branch information
salmenus committed Apr 26, 2024
1 parent 21dd1da commit a947d39
Show file tree
Hide file tree
Showing 25 changed files with 356 additions and 688 deletions.
5 changes: 1 addition & 4 deletions packages/extra/highlighter/src/ext/highlightJsExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ const createExtension = (): HighlighterExtension => {

return {
createHighlighter(options?: CreateHighlighterOptions): Highlighter {
const {
colorMode,
} = options ?? {};

const {colorMode} = options ?? {};
setColorMode(colorMode ?? defaultColorMode);
return highlighterFunction;
},
Expand Down
2 changes: 2 additions & 0 deletions packages/extra/markdown/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export type MarkdownStreamParserOptions = {
onComplete?: Function;
};

export type MarkdownStreamParserConfigOption = keyof Omit<MarkdownStreamParserOptions, 'onComplete'>;

export const createMarkdownStreamParser = (
domElement: HTMLElement,
options?: MarkdownStreamParserOptions,
Expand Down
12 changes: 12 additions & 0 deletions packages/js/core/src/exports/aiChat/aiChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,18 @@ export class AiChat<AiMsg = string> implements IAiChat<AiMsg> {
});
}

if (props.hasOwnProperty('adapter')) {
this.theAdapter = props.adapter ?? null;
}

if (props.hasOwnProperty('syntaxHighlighter')) {
this.theSyntaxHighlighter = props.syntaxHighlighter ?? null;
}

if (props.hasOwnProperty('conversationOptions')) {
this.theConversationOptions = props.conversationOptions ?? null;
}

this.controller.updateProps(props);
}

Expand Down
30 changes: 28 additions & 2 deletions packages/js/core/src/exports/aiChat/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ export class NluxRenderer<AiMsg> {
userPersona: this.thePersonasOptions?.user ?? undefined,
initialConversationContent: this.theInitialConversationContent ?? undefined,
autoScroll: this.theConversationOptions?.autoScroll,
streamingAnimationSpeed: this.theConversationOptions?.streamingAnimationSpeed,
streamingAnimationSpeed: this.theConversationOptions?.streamingAnimationSpeed ?? undefined,
syntaxHighlighter: this.context.syntaxHighlighter,
openLinksInNewWindow: this.theConversationOptions?.openLinksInNewWindow ?? undefined,
skipAnimation: false,
promptBox: {
placeholder: this.thePromptBoxOptions?.placeholder ?? undefined,
autoFocus: this.thePromptBoxOptions?.autoFocus ?? undefined,
Expand Down Expand Up @@ -324,6 +327,19 @@ export class NluxRenderer<AiMsg> {
this.chatRoom?.setProps({
autoScroll: props.conversationOptions?.autoScroll ?? undefined,
streamingAnimationSpeed: props.conversationOptions?.streamingAnimationSpeed ?? undefined,
syntaxHighlighter: this.context.syntaxHighlighter ?? undefined,
openLinksInNewWindow: props.conversationOptions?.openLinksInNewWindow ?? undefined,
skipAnimation: false,
});
}

if (props.hasOwnProperty('syntaxHighlighter')) {
this.context.update({
syntaxHighlighter: props.syntaxHighlighter,
});

this.chatRoom?.setProps({
syntaxHighlighter: props.syntaxHighlighter,
});
}

Expand Down Expand Up @@ -371,7 +387,17 @@ export class NluxRenderer<AiMsg> {
}

if (props.hasOwnProperty('syntaxHighlighter')) {
// TODO - Handle syntax highlighter change
this.context.update({
syntaxHighlighter: props.syntaxHighlighter,
});

this.chatRoom?.setProps({
syntaxHighlighter: props.syntaxHighlighter,
});
}

if (props.hasOwnProperty('')) {

}

if (props.hasOwnProperty('personaOptions')) {
Expand Down
3 changes: 3 additions & 0 deletions packages/js/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export type {
EventName,
EventCallback,
EventsMap,
MessageReceivedEventDetails,
MessageRenderedEventDetails,
ErrorCallback,
ErrorEventDetails,
ReadyCallback,
Expand All @@ -38,6 +40,7 @@ export type {
PreDestroyEventDetails,
MessageSentCallback,
MessageReceivedCallback,
MessageRenderedCallback,
} from './types/event';

export type {
Expand Down
44 changes: 37 additions & 7 deletions packages/js/core/src/logic/chat/chat-room/chat-room.model.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {MarkdownStreamParserConfigOption} from '@nlux-dev/markdown/src';
import {createAutoScrollController} from '../../../../../../shared/src/interactions/autoScroll/autoScrollController';
import {AutoScrollController} from '../../../../../../shared/src/interactions/autoScroll/type';
import {ChatItem} from '../../../../../../shared/src/types/conversation';
Expand All @@ -17,7 +18,6 @@ import {submitPromptFactory} from './actions/submitPrompt';
import {renderChatRoom} from './chat-room.render';
import {CompChatRoomActions, CompChatRoomElements, CompChatRoomEvents, CompChatRoomProps} from './chat-room.types';
import {updateChatRoom} from './chat-room.update';
import {getStreamingAnimationSpeed} from './utils/streamingAnimationSpeed';

@Model('chat-room', renderChatRoom, updateChatRoom)
export class CompChatRoom<AiMsg> extends BaseComp<
Expand All @@ -36,6 +36,9 @@ export class CompChatRoom<AiMsg> extends BaseComp<
botPersona,
userPersona,
initialConversationContent,
syntaxHighlighter,
skipAnimation,
openLinksInNewWindow,
}: CompChatRoomProps<AiMsg>,
) {
super(context, {
Expand All @@ -45,10 +48,12 @@ export class CompChatRoom<AiMsg> extends BaseComp<
botPersona,
userPersona,
promptBox,
syntaxHighlighter,
openLinksInNewWindow,
skipAnimation,
});

this.addConversation(
getStreamingAnimationSpeed(streamingAnimationSpeed),
botPersona,
userPersona,
initialConversationContent,
Expand Down Expand Up @@ -103,10 +108,20 @@ export class CompChatRoom<AiMsg> extends BaseComp<
this.autoScrollController?.updateProps({autoScroll});
}

if (props.hasOwnProperty('syntaxHighlighter')) {
this.setProp('syntaxHighlighter', props.syntaxHighlighter!);
}

if (props.hasOwnProperty('openLinksInNewWindow')) {
this.setProp('openLinksInNewWindow', props.openLinksInNewWindow!);
}

if (props.hasOwnProperty('skipAnimation')) {
this.setProp('skipAnimation', props.skipAnimation!);
}

if (props.hasOwnProperty('streamingAnimationSpeed')) {
this.conversation?.setStreamingAnimationSpeed(
getStreamingAnimationSpeed(props.streamingAnimationSpeed),
);
this.setProp('streamingAnimationSpeed', props.streamingAnimationSpeed!);
}

if (props.hasOwnProperty('botPersona')) {
Expand Down Expand Up @@ -134,19 +149,34 @@ export class CompChatRoom<AiMsg> extends BaseComp<
this.setProp('visible', true);
}

protected setProp<K extends keyof CompChatRoomProps<AiMsg>>(key: K, value: CompChatRoomProps<AiMsg>[K]) {
super.setProp(key, value);

if (
key === 'openLinksInNewWindow' || key === 'syntaxHighlighter' ||
key === 'skipAnimation' || key === 'streamingAnimationSpeed'
) {
const updateKey = key as MarkdownStreamParserConfigOption;
const updateValue = value as CompConversationProps<AiMsg>[MarkdownStreamParserConfigOption];
this.conversation.updateMarkdownStreamRenderer(updateKey, updateValue);
}
}

private addConversation(
streamingAnimationSpeed: number,
botPersona?: BotPersona,
userPersona?: UserPersona,
initialConversationContent?: readonly ChatItem<AiMsg>[],
) {
this.conversation = comp(CompConversation<AiMsg>)
.withContext(this.context)
.withProps<CompConversationProps<AiMsg>>({
streamingAnimationSpeed,
botPersona,
userPersona,
messages: initialConversationContent,
openLinksInNewWindow: this.props.openLinksInNewWindow,
skipAnimation: this.props.skipAnimation,
streamingAnimationSpeed: this.props.streamingAnimationSpeed,
syntaxHighlighter: this.props.syntaxHighlighter,
})
.create();

Expand Down
6 changes: 5 additions & 1 deletion packages/js/core/src/logic/chat/chat-room/chat-room.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {ChatItem} from '../../../../../../shared/src/types/conversation';
import {PromptBoxProps} from '../../../../../../shared/src/ui/PromptBox/props';
import {HighlighterExtension} from '../../../exports/aiChat/highlighter/highlighter';
import {BotPersona, UserPersona} from '../../../exports/aiChat/options/personaOptions';

export type CompChatRoomEvents = 'chat-room-ready'
Expand All @@ -11,8 +12,11 @@ export type CompChatRoomProps<AiMsg> = {
userPersona?: UserPersona,
initialConversationContent?: readonly ChatItem<AiMsg>[];
autoScroll?: boolean;
streamingAnimationSpeed?: number | null;
promptBox: Partial<PromptBoxProps>;
openLinksInNewWindow?: boolean;
skipAnimation?: boolean;
streamingAnimationSpeed?: number;
syntaxHighlighter?: HighlighterExtension;
};

export type CompChatRoomElements = {
Expand Down

This file was deleted.

49 changes: 0 additions & 49 deletions packages/js/core/src/logic/chat/chat-room/utils/textMessage.ts

This file was deleted.

25 changes: 24 additions & 1 deletion packages/js/core/src/logic/chat/chatItem/chatItem.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {MarkdownStreamParserConfigOption} from '../../../../../../extra/markdown/src';
import {BaseComp} from '../../../exports/aiChat/comp/base';
import {Model} from '../../../exports/aiChat/comp/decorators';
import {CompEventListener, Model} from '../../../exports/aiChat/comp/decorators';
import {HighlighterExtension} from '../../../exports/aiChat/highlighter/highlighter';
import {ControllerContext} from '../../../types/controllerContext';
import {renderChatItem} from './chatItem.render';
import {CompChatItemActions, CompChatItemElements, CompChatItemEvents, CompChatItemProps} from './chatItem.types';
Expand All @@ -25,4 +27,25 @@ export class CompChatItem<AiMsg> extends BaseComp<
this.throwIfDestroyed();
// TODO - implement chunking
}

public updateMarkdownStreamRenderer(
newProp: MarkdownStreamParserConfigOption,
newValue: CompChatItemProps[keyof CompChatItemProps],
) {
this.setProp(newProp, newValue);

if (newProp === 'syntaxHighlighter') {
const typedNewValue = newValue as HighlighterExtension | undefined;
this.executeDomAction('updateMarkdownStreamRenderer', {
syntaxHighlighter: typedNewValue,
} satisfies Partial<CompChatItemProps>);
}
}

@CompEventListener('markdown-stream-complete')
private onMarkdownStreamComplete(messageRendered: AiMsg) {
this.context.emit('messageRendered', {
uid: this.props.uid,
});
}
}
36 changes: 27 additions & 9 deletions packages/js/core/src/logic/chat/chatItem/chatItem.render.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {MarkdownStreamParser} from '@nlux/markdown';
import {createMarkdownStreamParser} from '../../../../../../extra/markdown/src';
import {createChatItemDom} from '../../../../../../shared/src/ui/ChatItem/create';
import {CompRenderer} from '../../../types/comp';
Expand All @@ -9,6 +10,7 @@ export const renderChatItem: CompRenderer<
> = ({
props,
appendToRoot,
compEvent,
}) => {

const root = createChatItemDom(props.domProps);
Expand All @@ -28,15 +30,18 @@ export const renderChatItem: CompRenderer<
messageContainer.append(streamingRoot);
appendToRoot(root);

const markdownStreamParser = createMarkdownStreamParser(markdownContainer, {
openLinksInNewWindow: true,
skipAnimation: false,
syntaxHighlighter: undefined,
streamingAnimationSpeed: undefined,
onComplete: () => {
// Do nothing
},
});
let markdownStreamParser: MarkdownStreamParser | undefined = undefined;

let markdownStreamProps: CompChatItemProps = {...props};
const initMarkdownStreamParser = (newProps: CompChatItemProps) => {
return createMarkdownStreamParser(markdownContainer, {
openLinksInNewWindow: newProps.openLinksInNewWindow ?? true,
skipAnimation: newProps.skipAnimation ?? false,
syntaxHighlighter: newProps.syntaxHighlighter,
streamingAnimationSpeed: newProps.streamingAnimationSpeed,
onComplete: () => compEvent('markdown-stream-complete'),
});
};

return {
elements: {
Expand All @@ -47,11 +52,24 @@ export const renderChatItem: CompRenderer<
root.focus();
},
processStreamedChunk: (chunk: string) => {
if (!markdownStreamParser) {
markdownStreamParser = initMarkdownStreamParser(markdownStreamProps);
}

markdownStreamParser.next(chunk);
},
updateMarkdownStreamRenderer: (newProps: Partial<CompChatItemProps>) => {
markdownStreamProps = {
...markdownStreamProps,
...newProps,
};

initMarkdownStreamParser(markdownStreamProps);
},
},
onDestroy: () => {
root.remove();
markdownStreamParser = undefined;
},
};
};
Loading

0 comments on commit a947d39

Please sign in to comment.