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.
177 lines (154 loc) • 7.1 kB
text/typescript
import '@nlux-dev/themes/src/nova/main.css';
import '@nlux-dev/themes/src/unstyled/main.css';
import '@nlux-dev/themes/src/luna/main.css';
import {ChatItem, createAiChat, DisplayOptions} from '@nlux-dev/core/src';
import DOMPurify from 'dompurify';
// import {highlighter} from '@nlux-dev/highlighter/src';
// import '@nlux-dev/highlighter/src/themes/stackoverflow/dark.css';
import {createChatAdapter as createHuggingFaceChatAdapter} from '@nlux-dev/hf/src';
import {createChatAdapter as createLangChainChatAdapter} from '@nlux-dev/langchain/src';
import {createChatAdapter as createNlbridgeChatAdapter} from '@nlux-dev/nlbridge/src';
import {createUnsafeChatAdapter as createOpenAiChatAdapter} from '@nlux-dev/openai/src';
import './style.css';
document.addEventListener('DOMContentLoaded', () => {
const parent = document.getElementById('root')!;
type ThemeId = 'nova' | 'luna' | 'unstyled' | 'dev';
let themeId: ThemeId = 'nova';
let colorScheme: 'light' | 'dark' | 'auto' = 'dark';
const htmlSanitizer = (html: string) => {
const trustedTypes = globalThis?.trustedTypes as unknown as {
createPolicy: (name: string, policy: Record<string, unknown>) => unknown;
};
if (typeof trustedTypes.createPolicy === 'function') {
const policy = trustedTypes.createPolicy('htmlSanitizer', {
createHTML: (input: string) => DOMPurify.sanitize(input),
});
return policy.createHTML(html);
}
return DOMPurify.sanitize(html);
};
const nlBridgeAdapter = createNlbridgeChatAdapter<string>()
.withUrl('http://localhost:8899/');
const langChainAdapter = createLangChainChatAdapter()
.withUrl('https://pynlux.api.nlkit.com/einbot')
.withDataTransferMode('stream')
.withInputSchema(true);
const huggingFaceAdapter = createHuggingFaceChatAdapter()
.withModel('gpt4')
.withDataTransferMode('batch')
.withAuthToken('N/A');
const openAiAdapter = createOpenAiChatAdapter()
.withApiKey(localStorage.getItem('openai-api-key') || 'N/A')
.withDataTransferMode('stream');
const themeSelector = document.querySelector('#themeSelector') as HTMLSelectElement;
themeSelector.addEventListener('change', () => {
themeId = themeSelector.value as ThemeId;
displayOptions.themeId = themeId;
aiChat.updateProps({displayOptions});
});
const colorSchemeSelector = document.querySelector('#colorSchemeSelector') as HTMLSelectElement;
colorSchemeSelector.addEventListener('change', () => {
colorScheme = colorSchemeSelector.value as 'light' | 'dark';
displayOptions.colorScheme = colorScheme;
aiChat.updateProps({displayOptions});
document.body.style.backgroundColor = colorScheme === 'dark' ? 'black' : 'white';
});
document.body.style.backgroundColor = colorScheme === 'dark' ? 'black' : 'white';
const longMessage = 'Hello, [how can I help you](http://questions.com)? This is going to be a very long greeting '
+ 'It is so long that it will be split into multiple lines. It will also showcase that no '
+ 'typing animation will be shown for this message when it is loaded. This is a very long '
+ 'message. Trust me.\n' + 'In a message, long and true,\n' + 'Words kept flowing, never few.\n'
+ 'Stories told with heartfelt grace,\n' + 'In each line, a sacred space.\n\n'
+ 'Each word a bridge, connecting souls,\n'
+ 'Across distances, making us whole.\n'
+ 'Emotions poured, thoughts unfurled,\n'
+ 'In this message, a treasure world.\n\n'
+ 'Pages filled with hopes and dreams,\n'
+ 'In this message, it truly seems,\n'
+ 'That connection can transcend the miles,\n'
+ 'In this message, love it files.\n'
+ 'So let us embrace this lengthy tale,\n'
+ 'For in its depth, we will prevail.\n'
+ 'For in a message, long and grand,\n'
+ 'We find connection, hand in hand.';
const messageWithCode = '```python\n'
+ 'def hello_world():\n'
+ ' print("Hello, World!")\n'
+ '```\n'
+ 'This is a code block.';
const initialConversation: ChatItem<string>[] = [
{role: 'assistant', message: longMessage},
{role: 'user', message: 'I need help with my account.'},
{
role: 'assistant',
message: 'Sure, I can help you with that.\n\nLet\'s start with some python code:\n\n' + messageWithCode,
},
];
const displayOptions: DisplayOptions = {
width: 600,
height: 400,
themeId,
colorScheme,
};
const domElement = document.createElement('div');
domElement.style.width = '24px';
domElement.style.height = '24px';
domElement.style.backgroundColor = 'red';
const aiChat = createAiChat<string>()
// .withAdapter(nlBridgeAdapter)
// .withAdapter(openAiAdapter)
.withAdapter(langChainAdapter)
// .withInitialConversation(initialConversation)
.withComposerOptions({
placeholder: 'Type your prompt here',
autoFocus: true,
// submitShortcut: 'CommandEnter',
})
.withConversationOptions({
// autoScroll: false,
// showWelcomeMessage: false,
conversationStarters: [
{
icon: 'https://content.nlkit.com/logos/nlkit.png',
prompt: 'What can I help you with today? Imagine I am a chatbot.',
},
{
icon: domElement,
prompt: 'How can I assist you today?',
},
{
prompt: 'What can I help you with today? Imagine I am a chatbot.',
label: 'Reverse Roles',
},
{
prompt: 'How can I assist you today?',
},
],
})
.withDisplayOptions(displayOptions)
.withMessageOptions({
markdownLinkTarget: 'blank',
htmlSanitizer: htmlSanitizer,
// htmlSanitizer: (html: string) => html.replace('h', 'x'),
// syntaxHighlighter: highlighter,
// showCodeBlockCopyButton: false,
})
.withPersonaOptions({
user: {
name: 'Alex',
avatar: 'https://docs.nlkit.com/nlux/images/personas/alex.png',
},
assistant: {
name: 'AI Assistant',
avatar: 'https://docs.nlkit.com/nlux/images/personas/harry-botter.png',
tagline: 'Welcome to the chat',
},
});
aiChat.on('messageReceived', (event) => console.log('messageReceived', event));
aiChat.on('messageRendered', (event) => console.log('messageRendered', event));
aiChat.mount(parent);
(window as any).aiChat = aiChat;
aiChat.updateProps({
// syntaxHighlighter: highlighter,
});
});