Skip to content

Commit

Permalink
Merge pull request #76 from assistants-hub/43_full_screen_chatbot
Browse files Browse the repository at this point in the history
#43 Fullscreen assistants with permalink
  • Loading branch information
santthosh authored May 22, 2024
2 parents f242439 + d254f97 commit 5d4eb87
Show file tree
Hide file tree
Showing 9 changed files with 474 additions and 205 deletions.
37 changes: 18 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,35 +64,34 @@ Below is an AI assistant demo generated with Assistants Hub available at [Math W

All models that support [OpenAI's Assistants API](https://platform.openai.com/docs/models/overview) are supported by [Assistants Hub](https://assistantshub.ai).

| Model Name | Provider | Streaming <br/>Responses | Documents | Functions |
|--------------------|----------|---------------------|-----------|-----|
| GPT-4o | OpenAI | :white_check_mark: | :white_check_mark: | :construction: |
| GPT-4-Turbo | OpenAI | :white_check_mark: | :white_check_mark: | :construction: |
| GPT-4 | OpenAI | :white_check_mark: | :white_check_mark: | :construction: |
| GPT-3.5-Turbo | OpenAI | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| GPT-3.5-Turbo-16k | OpenAI | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| GPT-3.5-Turbo-0125 | OpenAI | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Model Name | Provider | Streaming <br/>Responses | Documents | Functions |
| ------------------ | -------- | ------------------------ | ------------------------ | ------------------------ |
| GPT-4o | OpenAI | :white_check_mark: | :white_check_mark: | :construction: |
| GPT-4-Turbo | OpenAI | :white_check_mark: | :white_check_mark: | :construction: |
| GPT-4 | OpenAI | :white_check_mark: | :white_check_mark: | :construction: |
| GPT-3.5-Turbo | OpenAI | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| GPT-3.5-Turbo-16k | OpenAI | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| GPT-3.5-Turbo-0125 | OpenAI | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |

### Google Gemini Models

The gemini-1.5-pro-latest model is a large-scale language model developed by Google. It is designed to generate human-like text based on the input provided to it. The model is trained on a diverse range of text data to ensure that it can handle a wide variety of tasks and topics. [Read More](https://blog.google/technology/ai/google-gemini-next-generation-model-february-2024/#sundar-note)

| Model Name | Provider | Streaming <br/>Responses | Documents | Functions |
|-------------------------|----------|---------------------|-----------|-----|
| Gemini-1.5-Pro-latest | Google | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Gemini-1.5-Flash-latest | Google | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |

| Model Name | Provider | Streaming <br/>Responses | Documents | Functions |
| ----------------------- | -------- | ------------------------ | ------------------------ | ------------------------ |
| Gemini-1.5-Pro-latest | Google | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Gemini-1.5-Flash-latest | Google | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |

### Gorq Cloud

All models that support [Gorq Cloud API](https://console.groq.com/docs/models) are supported by [Assistants Hub](https://assistantshub.ai).

| Model Name | Provider | Streaming <br/>Responses | Documents | Functions |
|--------------------|----------|---------------------|-----------|-----|
| Llama3-8b-8192 | Groq | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Llama3-70b-8192 | Groq | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Mixtral-8x7b-32768 | Groq | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Gemma-7b-it-8192 | Groq | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Model Name | Provider | Streaming <br/>Responses | Documents | Functions |
| ------------------ | -------- | ------------------------ | ------------------------ | ------------------------ |
| Llama3-8b-8192 | Groq | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Llama3-70b-8192 | Groq | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Mixtral-8x7b-32768 | Groq | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| Gemma-7b-it-8192 | Groq | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: |

## Getting Started

Expand Down
119 changes: 119 additions & 0 deletions src/app/assistants/[id]/chat/ChatPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Button, TextInput } from 'flowbite-react';
import React, { useContext, useEffect, useRef } from 'react';
import AssistantContext from '@/app/assistants/[id]/AssistantContext';
import { useChatContext } from '@/app/assistants/[id]/chat/useChatContext';
import { getInputMessageLabel, getPrimaryColor } from '@/app/utils/assistant';
import { ChatPageHeader } from '@/app/assistants/[id]/chat/ChatPageHeader';
import { Message } from '@/app/types/message';
import ChatMessage from '@/app/assistants/[id]/chat/ChatMessage';
import ChatMessageStreaming from '@/app/assistants/[id]/chat/ChatMessageStreaming';
import ChatTyping from '@/app/assistants/[id]/chat/ChatTyping';

export default function ChatPage() {
const { assistant } = useContext(AssistantContext);

const bottomRef = useRef(null);
const messagesRef = useRef<HTMLDivElement | null>(null);

const {
typedMessage,
setTypedMessage,
messageStatus,
streamText,
messages,
sendMessage,
} = useChatContext();

useEffect(() => {
if (messagesRef?.current && 'scrollIntoView' in messagesRef.current) {
messagesRef.current.scrollIntoView({ block: 'end', behavior: 'smooth' });
}
}, [messages]);

useEffect(() => {
// @ts-ignore
bottomRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' });
}, [streamText]);

return (
<div key='1' className='flex h-screen flex-col'>
<div className='flex space-y-4 bg-gray-100 pb-2 pt-1'>
<ChatPageHeader />
</div>
<div className='flex-grow space-y-4 overflow-auto p-4 py-0 pt-0'>
<div className='mx-auto flex max-w-2xl flex-col rounded-b rounded-t-none'>
<div className={'max-w-2xl overflow-y-auto'}>
<div
className='flex flex-col gap-3 self-center overflow-y-auto px-4 py-2'
ref={messagesRef}
>
{messages.map((message: Message, index) => {
return <ChatMessage key={index} message={message} />;
})}
{streamText ? (
<>
<ChatMessageStreaming
message={streamText}
></ChatMessageStreaming>
<div ref={bottomRef} />
</>
) : (
<></>
)}
{messageStatus === 'in_progress' && !streamText ? (
<ChatTyping />
) : (
<></>
)}
</div>
</div>
</div>
</div>
<div className='z-100 mx-auto w-full max-w-2xl rounded-lg border border-2 bg-white p-6 shadow md:w-[800px]'>
{messageStatus === 'in_progress' ? (
<span className='text-xs font-normal text-gray-500 dark:text-white'>
{assistant.name} is typing...
</span>
) : (
<></>
)}
<div className='items-top flex space-x-2'>
<TextInput
className='block w-full rounded-lg border bg-white text-sm text-gray-900 dark:text-white dark:placeholder-gray-400'
placeholder={getInputMessageLabel(assistant)}
readOnly={false}
disabled={messageStatus === 'in_progress'}
value={typedMessage}
onKeyDown={(e) => {
if (e.key === 'Enter' && !e.shiftKey) {
sendMessage();
}
e.stopPropagation();
}}
onChange={(event) => {
setTypedMessage(event.target.value);
}}
></TextInput>
<Button
as='span'
className='inline-flex cursor-pointer justify-center border-transparent bg-transparent'
style={{
color: getPrimaryColor(assistant),
}}
onClick={sendMessage}
>
<svg
className='h-5 w-5 rotate-90 rtl:-rotate-90'
aria-hidden='true'
xmlns='http://www.w3.org/2000/svg'
fill='currentColor'
viewBox='0 0 18 20'
>
<path d='m17.914 18.594-8-18a1 1 0 0 0-1.828 0l-8 18a1 1 0 0 0 1.157 1.376L8 18.281V9a1 1 0 0 1 2 0v9.281l6.758 1.689a1 1 0 0 0 1.156-1.376Z' />
</svg>
</Button>
</div>
</div>
</div>
);
}
38 changes: 38 additions & 0 deletions src/app/assistants/[id]/chat/ChatPageContextWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useGetAssistant } from '@/app/assistants/[id]/client';
import React, { useEffect, useState } from 'react';
import { Assistant } from '@/app/types/assistant';
import ChatPage from '@/app/assistants/[id]/chat/ChatPage';
import { Spinner } from 'flowbite-react';
import AssistantContext from '@/app/assistants/[id]/AssistantContext';

export default function ChatPageContextWrapper(props: { assistantId: string }) {
let { assistantLoading, assistantResponse, assistantEmpty, reload } =
useGetAssistant(props.assistantId);

const [loading, setLoading] = useState(true);
const [assistant, setAssistant] = useState<Assistant>(assistantResponse);

useEffect(() => {
if (assistantResponse) {
setAssistant(assistantResponse);
setLoading(false);
}
}, [assistantLoading]);

const changeAssistant = async (assistant: Assistant) => {
setAssistant(assistant);
// We don't allow changes from the end-user so this is a no-op
};

return loading ? (
<div className='bg-grey flex h-[calc(100vh-120px)] items-center justify-center '>
<Spinner color='info' aria-label='Loading assistant..' />
</div>
) : (
<AssistantContext.Provider
value={{ assistant, setAssistant: changeAssistant }}
>
<ChatPage />
</AssistantContext.Provider>
);
}
39 changes: 39 additions & 0 deletions src/app/assistants/[id]/chat/ChatPageHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use client';

import { Card, Dropdown } from 'flowbite-react';
import Image from 'next/image';
import { useContext } from 'react';
import AssistantContext from '@/app/assistants/[id]/AssistantContext';
import { getImageHash } from '@/app/utils/hash';

export function ChatPageHeader() {
const { assistant } = useContext(AssistantContext);

return (
<Card className='mx-auto my-auto flex max-w-2xl'>
<div className='grid grid-cols-12 items-center'>
<div className='col-span-2'>
<Image
className='rounded-full'
src={
assistant.avatar
? assistant.avatar
: '/images/people/avatar/' + getImageHash(assistant.id) + '.jpg'
}
width={64}
height={64}
alt='Assistant'
/>
</div>
<div className='col-span-10 items-center justify-center'>
<p className='max-w-md text-xl font-semibold leading-relaxed'>
{assistant.name}
</p>
<p className='max-w-md text-sm leading-relaxed'>
{assistant.description}
</p>
</div>
</div>
</Card>
);
}
Loading

0 comments on commit 5d4eb87

Please sign in to comment.