Skip to content

Commit

Permalink
Merge pull request #972 from ElishaKay/nextjs-chat-fixes
Browse files Browse the repository at this point in the history
nextjs chat fix
  • Loading branch information
assafelovic authored Nov 1, 2024
2 parents cc9f73a + 1d9bea3 commit 303d2d6
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 28 deletions.
32 changes: 24 additions & 8 deletions backend/chat/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,36 @@ def __init__(

def create_agent(self):
"""Create React Agent Graph"""
#If not vector store, split and talk to the report
llm_provider_name = getattr(self.config, "llm_provider")
fast_llm_model = getattr(self.config, "fast_llm_model")
temperature = getattr(self.config, "temperature")
fast_token_limit = getattr(self.config, "fast_token_limit")
cfg = Config()

provider = get_llm(llm_provider_name, model=fast_llm_model, temperature=temperature, max_tokens=fast_token_limit, **self.config.llm_kwargs).llm
# Retrieve LLM using get_llm with settings from config
provider = get_llm(
llm_provider=cfg.smart_llm_provider,
model=cfg.smart_llm_model,
temperature=0.35,
max_tokens=cfg.smart_token_limit,
**self.config.llm_kwargs
).llm

# If vector_store is not initialized, process documents and add to vector_store
if not self.vector_store:
documents = self._process_document(self.report)
self.chat_config = {"configurable": {"thread_id": str(uuid.uuid4())}}
self.embedding = Memory(getattr(self.config, 'embedding_provider', None), self.headers).get_embeddings()
self.embedding = Memory(
cfg.embedding_provider,
cfg.embedding_model,
**cfg.embedding_kwargs
).get_embeddings()
self.vector_store = InMemoryVectorStore(self.embedding)
self.vector_store.add_texts(documents)
graph = create_react_agent(provider, tools=[self.vector_store_tool(self.vector_store)], checkpointer=MemorySaver())

# Create the React Agent Graph with the configured provider
graph = create_react_agent(
provider,
tools=[self.vector_store_tool(self.vector_store)],
checkpointer=MemorySaver()
)

return graph

def vector_store_tool(self, vector_store) -> Tool:
Expand Down
6 changes: 6 additions & 0 deletions frontend/nextjs/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ html {
scroll-behavior: smooth;
}

textarea {
max-height: 300px; /* Set an appropriate max height */
overflow-y: auto; /* Enable internal scrolling */
/* transition: height 0.2s ease-in-out; */
}

.log-message {
word-wrap: break-word; /* For handling long URLs or text */
overflow-wrap: break-word; /* For handling overflow in modern browsers */
Expand Down
95 changes: 77 additions & 18 deletions frontend/nextjs/components/InputArea.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Image from "next/image";
import { FC } from "react";
import { FC, useRef } from "react";
import TypeAnimation from "./TypeAnimation";

type TInputAreaProps = {
Expand All @@ -11,38 +11,92 @@ type TInputAreaProps = {
reset?: () => void;
};

// Debounce function to limit the rate at which a function can fire
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}

const InputArea: FC<TInputAreaProps> = ({
promptValue,
setPromptValue,
handleSubmit: handleSubmit,
handleSecondary: handleSecondary,
handleSubmit,
handleSecondary,
disabled,
reset,
}) => {
const placeholder = handleSecondary ? "Follow up questions..." : "What would you like to research next?"
const placeholder = handleSecondary
? "Follow up questions..."
: "What would you like to research next?";

const textareaRef = useRef<HTMLTextAreaElement>(null);

const resetHeight = () => {
if (textareaRef.current) {
textareaRef.current.style.height = '3em'; // Reset to base height
}
};

const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === 'Enter') {
if (e.shiftKey) {
return; // Allow new line on Shift+Enter
} else {
e.preventDefault();
if (!disabled) {
if (reset) reset();
handleSubmit(promptValue);
setPromptValue(''); // Clear prompt value
resetHeight(); // Reset height after submit
}
}
}
};

// Debounced version of the height adjustment function
const adjustHeight = debounce((target) => {
target.style.height = 'auto'; // Reset height to auto to allow shrinking
target.style.height = `${target.scrollHeight}px`; // Adjust height
}, 100); // Adjust the delay as needed

const handleTextareaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
const target = e.target;
adjustHeight(target); // Use debounced function
setPromptValue(target.value);
};

return (
<form
className="mx-auto flex h-[66px] w-full items-center justify-between rounded-lg border bg-white px-3 shadow-[2px_2px_38px_0px_rgba(0,0,0,0.25),0px_-2px_4px_0px_rgba(0,0,0,0.25)_inset,1px_2px_4px_0px_rgba(0,0,0,0.25)_inset]"
className="mx-auto flex pt-2 pb-2 w-full items-center justify-between rounded-lg border bg-white px-3 shadow-[2px_2px_38px_0px_rgba(0,0,0,0.25),0px_-2px_4px_0px_rgba(0,0,0,0.25)_inset,1px_2px_4px_0px_rgba(0,0,0,0.25)_inset]"
onSubmit={(e) => {
e.preventDefault();
if (reset) reset();
handleSubmit(promptValue);
setPromptValue(''); // Clear prompt value
resetHeight();
}}
>
{
handleSecondary &&
{handleSecondary && (
<div
role="button"
role="button"
aria-disabled={disabled}
className="relative flex h-[50px] w-[50px] shrink-0 items-center justify-center rounded-[3px] bg-[linear-gradient(154deg,#1B1B16_23.37%,#565646_91.91%)] disabled:pointer-events-none disabled:opacity-75"
onClick={(e) =>{
if (!disabled){
onClick={(e) => {
if (!disabled) {
e.preventDefault();
if (reset) reset();
handleSecondary(promptValue);
}
setPromptValue(''); // Clear prompt value
resetHeight();
}
}
}}
>
{disabled && (
<div className="absolute inset-0 flex items-center justify-center">
Expand All @@ -59,15 +113,20 @@ const InputArea: FC<TInputAreaProps> = ({
className={disabled ? "invisible" : ""}
/>
</div>
}
<input
type="text"
)}

<textarea
placeholder={placeholder}
className="focus-visible::outline-0 my-1 w-full pl-5 font-light not-italic leading-[normal] text-[#1B1B16]/30 text-black outline-none focus-visible:ring-0 focus-visible:ring-offset-0 sm:text-xl"
ref={textareaRef}
className="focus-visible::outline-0 my-1 w-full pl-5 font-light not-italic leading-[normal]
text-[#1B1B16]/30 text-black outline-none focus-visible:ring-0 focus-visible:ring-offset-0
sm:text-xl min-h-[3em] resize-none"
disabled={disabled}
value={promptValue}
required
onChange={(e) => setPromptValue(e.target.value)}
rows={2}
onKeyDown={handleKeyDown}
onChange={handleTextareaChange}
/>
<button
disabled={disabled}
Expand All @@ -93,4 +152,4 @@ const InputArea: FC<TInputAreaProps> = ({
);
};

export default InputArea;
export default InputArea;
4 changes: 2 additions & 2 deletions frontend/nextjs/components/Question.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const Question: React.FC<QuestionProps> = ({ question }) => {
/>
<p className="font-bold uppercase leading-[152%] text-white">
Question:
</p>
</p><br/>
</div>
<div className="grow text-white break-words max-w-full sm:truncate">&quot;{question}&quot;</div>
<div className="grow text-white break-words max-w-full log-message">&quot;{question}&quot;</div>
</div>
);
};
Expand Down

0 comments on commit 303d2d6

Please sign in to comment.