Skip to content

Commit

Permalink
Feat: New module screen
Browse files Browse the repository at this point in the history
  • Loading branch information
TheHunterDog committed Nov 29, 2024
1 parent 85ebc6c commit 64ee847
Show file tree
Hide file tree
Showing 13 changed files with 333 additions and 75 deletions.
3 changes: 3 additions & 0 deletions public/retry.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
122 changes: 103 additions & 19 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import createChatMessage from './util/chatMessageFactory.ts';
import LocalApiHandler from './util/localApiHandler.ts';
import DocumentCheckPage from './components/pages/document_check_page/document_check_page.tsx';
import { createFetchDocument, fetchedDocument } from './util/documentFactory.ts';
import DefaultTemplate from './components/template/default-Template.tsx';
import KamervragenTemplate from './components/template/kamervragen-Template.tsx';

export interface chatMessage {
id: Key;
Expand All @@ -27,15 +29,24 @@ function App() {
const [errorOccured, setErrorOccured] = useState(false);
const [DocumentsChecked, setDocumentsChecked] = useState<fetchedDocument[]>([]);
const [documentsToCheck, setDocumentsToCheck] = useState<fetchedDocument[]>([]);
const [allSpecialties, setAllSpecialties] = useState([]);
const [LLMModel, setLLMModel] = useState('BramVanRoy/fietje-2-chat');
const [availableModels, setAvailableModels] = useState([]);
const [jsonBodyPrompt, setJsonBodyPrompt] = useState({});

const [allSpecialties, setAllSpecialties] = useState([])
useEffect(() => {
APIhandler.current.setLLMModel(LLMModel);
}, [LLMModel]);

useEffect(() => {
APIhandler.current.setApiUrl(apiUrl);
APIhandler.current.setApiToken(apiToken);
APIhandler.current.getSpecialties().then((response) => {
setAllSpecialties(response);
});
APIhandler.current.getAvailableModles().then((response) => {
setAvailableModels(response);
});
}, [apiUrl, apiToken]);

useEffect(() => {
Expand All @@ -46,21 +57,46 @@ function App() {
setMessages([]);
};

const handleMessage = (message: string) => {
if (message === '') {
return;
}
if (apiUrl === '') {
const handleMessage = (
message:
| string
| {
inleiding: string;
vragen: string;
departmentSentiment: string;
news: string;
},
) => {
// Early returns for edge cases
if (!message || apiUrl === '') {
return;
}

// Set API call status
setAPIcall(true);
setMessages((val) => val.concat(createChatMessage(message, true)));

// Combine message if it's an object, otherwise use it as-is
const combinedMessage =
typeof message === 'object'
? `${message.inleiding} ${message.vragen} ${message.departmentSentiment} ${message.news}`
: message;
if (typeof message === 'object') {
setJsonBodyPrompt({
message,
combinedMessage,
prompt: `${message.inleiding} ${message.vragen}`,
});
}
// Update the messages state
setMessages((val) => val.concat(createChatMessage(combinedMessage, true)));

// Fetch documents using the combined message
APIhandler.current
.queryDocuments(message)
.queryDocuments(combinedMessage)
.then((response) => {
const { documents } = response;
// eslint-disable-next-line @typescript-eslint/no-explicit-any

// Map fetched documents to the desired format
const fetchedDocuments = documents.map(
(
document: {
Expand All @@ -86,13 +122,17 @@ function App() {
document.metadata.question_number,
),
);

// Update documents state
setDocumentsToCheck(fetchedDocuments);
setAPIcall(false);
})
.catch((_error) => {});
.catch((_error) => {
// Handle errors if necessary
setAPIcall(false); // Ensure the API call flag is reset on error
});
};

const callLlm = (query: string, documents: fetchedDocument[]) => {
const callLlm = (query: string | object, documents: fetchedDocument[]) => {
APIhandler.current
.infereLLM(query, documents)
.then((response) => {
Expand All @@ -107,21 +147,50 @@ function App() {
})
.catch((_error: Error) => {});
};

const renderTemplate = () => {
if (specialty === 'KamerVragen') {
return (
<KamervragenTemplate
onSubmit={(values: {
inleiding: string;
vragen: string;
departmentSentiment: string;
news: string;
}) => {
setInitalized(true);
handleMessage(values);
}}
/>
);
}

return (
<DefaultTemplate
onSubmit={(values: { question: string }) => {
setInitalized(true);
handleMessage(values.question);
}}
/>
);
};

return (
<div className="wrapper">
<Header
chatPage={initalized}
specialty={specialty}
setLLMModel={(model: SetStateAction<string>) => setLLMModel(model)}
models={availableModels}
/>
{!initalized && (
<HomePage
onSubmit={(values: { question: string }) => {
setInitalized(true);
handleMessage(values.question);
}}
template={renderTemplate()}
setApiToken={(token: SetStateAction<string>) => setapiToken(token)}
setApiUrl={(url: SetStateAction<string>) => setApiUrl(url)}
setSpecialtyCallback={(selectedSpecialty: SetStateAction<string>) => setspecialty(selectedSpecialty)}
setSpecialtyCallback={(selectedSpecialty: SetStateAction<string>) =>
setspecialty(selectedSpecialty)
}
specialties={allSpecialties}
/>
)}
Expand All @@ -133,7 +202,11 @@ function App() {
setDocumentsToCheck([]);
setAPIcall(true);
setDocumentsChecked(documents);
callLlm(messages.at(messages.length - 1)?.message ?? '', documents);
if (Object.keys(jsonBodyPrompt).length > 0) {
callLlm(jsonBodyPrompt, documents);
} else {
callLlm(messages.at(messages.length - 1)?.message ?? '', documents);
}
}}
/>
)}
Expand All @@ -147,10 +220,21 @@ function App() {
setErrorOccured(false);
setDocumentsChecked([]);
}}
regenerateMessage={() => {
if (Object.keys(jsonBodyPrompt).length > 0) {
callLlm(jsonBodyPrompt, DocumentsChecked);
} else {
callLlm(messages.at(messages.length - 1)?.message ?? '', DocumentsChecked);
}
}}
errorOccured={errorOccured}
retryFailure={() => {
setErrorOccured(false);
callLlm(messages.at(messages.length - 1)?.message ?? '', DocumentsChecked);
if (Object.keys(jsonBodyPrompt).length > 0) {
callLlm(jsonBodyPrompt, DocumentsChecked);
} else {
callLlm(messages.at(messages.length - 1)?.message ?? '', DocumentsChecked);
}
}}
/>
)}
Expand Down
3 changes: 3 additions & 0 deletions src/assets/retry.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions src/components/atoms/SubmitButton/SubmitButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
interface SubmitButtonProps {
onClick: () => void;
text: string;
}

function SubmitButton({ onClick, text }: SubmitButtonProps) {
return (
<button
type="button"
className="submit-button"
onClick={() => onClick()}>
{text}
</button>
);
}

export default SubmitButton;
21 changes: 21 additions & 0 deletions src/components/atoms/inputTextField/inputTextField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
interface InputTextFieldProps {
label: string;
id: string;
onChange: (val: string) => void;
}

function InputTextField({ label, id, onChange }: InputTextFieldProps) {
return (
<div className="input-text-field">
<label htmlFor={id}>{label}</label>
<input
id={id}
type="text"
name={label}
onChange={(e) => onChange(e.currentTarget.value)}
/>
</div>
);
}

export default InputTextField;
6 changes: 4 additions & 2 deletions src/components/atoms/question-bar/question-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import sendIcon from '../../../assets/send-black.svg';
interface QuestionBarProps {
onSubmit: (values: string) => void;
disabled?: boolean;
placeholder?: string;
}

function QuestionBar({ onSubmit, disabled }: QuestionBarProps) {
function QuestionBar({ onSubmit, disabled, placeholder }: QuestionBarProps) {
const [question, setquestion] = useState('');

const handleSubmit = () => {
Expand All @@ -21,7 +22,7 @@ function QuestionBar({ onSubmit, disabled }: QuestionBarProps) {
<div className={`question-bar ${disabled && 'disabled'}`}>
<input
type="text"
placeholder="Schrijf hier je vraag"
placeholder={placeholder ?? 'Schrijf hier je vraag'}
value={question}
onChange={(val) => setquestion(val.target.value)}
disabled={disabled}
Expand Down Expand Up @@ -49,6 +50,7 @@ function QuestionBar({ onSubmit, disabled }: QuestionBarProps) {

QuestionBar.defaultProps = {
disabled: false,
placeholder: 'Schrijf hier je vraag',
};

export default QuestionBar;
68 changes: 44 additions & 24 deletions src/components/molecules/chatmessage/chatmessage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { useState } from 'react';
import TextElement from '../../atoms/TextElement/TextElement.tsx';
import './chatmessage.css';
import retryIcon from '../../../assets/retry.svg';
import Button from '../../atoms/button/Button.tsx';

interface ChatMessageProps {
fromUser?: boolean;
username?: string;
message: string;
sources?: string[];
retryFunction?: () => void;
}
function ChatMessage({ fromUser, username, message, sources }: ChatMessageProps) {
function ChatMessage({ fromUser, username, message, sources, retryFunction }: ChatMessageProps) {
const [showSources, setShowSources] = useState(false);

const renderSources = () => {
Expand Down Expand Up @@ -36,31 +39,47 @@ function ChatMessage({ fromUser, username, message, sources }: ChatMessageProps)
{message}
</TextElement>
</div>

{sources && sources.length > 0 && (
<div className="chat-message__sources">
<div
className="chat-message__sources-header"
role="button"
tabIndex={0}
onClick={() => setShowSources(!showSources)}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
setShowSources(!showSources);
}
}}>
<TextElement type="chatmessage chat-message__sources__text">
Gebruikte bronnen
</TextElement>
<div className="gylph">{showSources ? '▲' : '▼'}</div>
</div>
{showSources && (
<div className="chat-message__sources__container">
{showSources && renderSources()}
</div>
<div className="wrap--actions">
<div className="action">
{/* show svg */}
{retryFunction && (
<Button
className="retry-button"
onClick={retryFunction}
aria-label="Retry">
<img
style={{ height: '20px' }}
src={retryIcon}
alt="retry"
className="retry-icon"
/>
</Button>
)}
</div>
)}
{sources && sources.length > 0 && (
<div className="chat-message__sources">
<div
className="chat-message__sources-header"
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
setShowSources(!showSources);
}
}}>
<TextElement type="chatmessage chat-message__sources__text">
Gebruikte bronnen
</TextElement>
<div className="gylph">{showSources ? '▲' : '▼'}</div>
</div>
{showSources && (
<div className="chat-message__sources__container">
{showSources && renderSources()}
</div>
)}
</div>
)}
</div>
</div>
</div>
);
Expand All @@ -70,6 +89,7 @@ ChatMessage.defaultProps = {
fromUser: false,
username: '',
sources: [],
retryFunction: () => {},
};

export default ChatMessage;
Loading

0 comments on commit 64ee847

Please sign in to comment.