diff --git a/frontend/src/App.css b/frontend/src/App.css index c2adba1..a477280 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -50,6 +50,15 @@ div { margin: 0 auto; } + +.DocBox { + display: flex; + flex-direction: column; + flex-grow: 1; + max-width: 2048px; + margin: 0 auto; +} + .Controls { display: flex; background-color: #F5F5F5; diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 0816f02..007dd72 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -47,9 +47,7 @@ import '@fontsource/roboto/700.css'; const welcomeMarkdown = ` # Welcome to Backstory -Backstory was written by James Ketrenos in order to provide answers to questions potential employers may have about his work history. In addition to being a RAG enabled expert system, the LLM has access to real-time data. - -You can ask things like: +Backstory was written by James Ketrenos in order to provide answers to questions potential employers may have about his work history. In addition to being a RAG enabled expert system, the LLM has access to real-time data. You can ask things like: diff --git a/frontend/src/DocumentViewer.tsx b/frontend/src/DocumentViewer.tsx index cc5c548..27f3346 100644 --- a/frontend/src/DocumentViewer.tsx +++ b/frontend/src/DocumentViewer.tsx @@ -136,7 +136,7 @@ const DocumentViewer: React.FC = ({generateResume, resume, value={jobDescription} onChange={(e) => setJobDescription(e.target.value)} onKeyDown={handleKeyPress} - placeholder="Enter a job description, then click Generate..." + placeholder="Paste a job description (or URL that resolves to one), then click Generate..." /> @@ -160,10 +160,10 @@ const DocumentViewer: React.FC = ({generateResume, resume, Generating resume... } - - {resume !== undefined - ? NOTE: As with all LLMs, hallucination is always a possibility. If this resume seems too good to be true, expand the LLM information for this query section and click the links to the relavent RAG source document to read the details. Or go back to 'Backstory' and ask a question. - : Once you click Generate under the Job Description, a resume will be generated based on the user's RAG content and the job description. + + {resume !== undefined || processing == true + ? NOTE: As with all LLMs, hallucination is always a possibility. If the generated resume seems too good to be true, expand the LLM information for this query section (at the end of the resume) and click the links in the Top RAG matches to view the relavent RAG source document to read the details. Or go back to 'Backstory' and ask a question. + : Once you click Generate under the Job Description, a resume will be generated based on the user's RAG content and the job description. } )} @@ -193,7 +193,7 @@ const DocumentViewer: React.FC = ({generateResume, resume, value={jobDescription} onChange={(e) => setJobDescription(e.target.value)} onKeyDown={handleKeyPress} - placeholder="Enter a job description, then click Generate..." + placeholder="Paste a job description (or URL that resolves to one), then click Generate..." /> @@ -217,7 +217,12 @@ const DocumentViewer: React.FC = ({generateResume, resume, data-testid="loader" /> - {resume !== undefined && NOTE: As with all LLMs, hallucination is always a possibility. If this resume seems too good to be true, expand the LLM information for this query section and click the links to the relavent RAG source document to read the details. Or go back to 'Backstory' and ask a question.} + + {resume !== undefined || processing == true + ? NOTE: As with all LLMs, hallucination is always a possibility. If the generated resume seems too good to be true, expand the LLM information for this query section (at the end of the resume) and click the links to the relavent RAG source document to read the details. Or go back to 'Backstory' and ask a question. + : Once you click Generate under the Job Description, a resume will be generated based on the user's RAG content and the job description. + } + diff --git a/frontend/src/MessageMeta.tsx b/frontend/src/MessageMeta.tsx index 9ebef46..a25b227 100644 --- a/frontend/src/MessageMeta.tsx +++ b/frontend/src/MessageMeta.tsx @@ -78,7 +78,7 @@ const MessageMeta = ({ metadata }: MessageMetaInterface) => { { metadata.tools !== undefined && metadata.tools.length !== 0 && - + }> Tools queried @@ -88,10 +88,10 @@ const MessageMeta = ({ metadata }: MessageMetaInterface) => { {metadata.tools.map((tool: any, index: number) => {index !== 0 && } -
+
{tool.tool}
-
{JSON.stringify(tool.result, null, 2)}
+
{JSON.stringify(tool.result, null, 2)}
)} diff --git a/frontend/src/ResumeBuilder.tsx b/frontend/src/ResumeBuilder.tsx index f2530d7..c52c4ca 100644 --- a/frontend/src/ResumeBuilder.tsx +++ b/frontend/src/ResumeBuilder.tsx @@ -203,7 +203,7 @@ const ResumeBuilder = ({scrollToBottom, isScrolledToBottom, setProcessing, proce }; return ( - + ); - return ( - - setJobDescription(e.target.value)} - onKeyDown={handleKeyPress} - placeholder="Enter the job description.." - id="JobDescriptionInput" - /> - - - - - - {processing === true && countdown > 0 && ( - Estimated response time: {countdown}s - )} - - {generateStatus && } - {/* {resume && } */} - - - ); } diff --git a/src/server.py b/src/server.py index 5f31fb7..60c963d 100644 --- a/src/server.py +++ b/src/server.py @@ -137,7 +137,7 @@ When answering queries, follow these steps: 1. First analyze the query to determine if real-time information might be helpful 2. Even when [{context_tag}] is provided, consider whether the tools would provide more current or comprehensive information 3. Use the provided tools whenever they would enhance your response, regardless of whether context is also available -4. When presenting information like weather forecasts, include relevant emojis immediately before the corresponding text. For example, for a sunny day, say \"☀️ Sunny\" or if the forecast says there will be \"rain showers, say \"🌧️ Rain showers\". Use this mapping for weather emojis: Sunny: ☀️, Cloudy: ☁️, Rainy: 🌧️, Snowy: ❄️ +4. When presenting weather forecasts, include relevant emojis immediately before the corresponding text. For example, for a sunny day, say \"☀️ Sunny\" or if the forecast says there will be \"rain showers, say \"🌧️ Rain showers\". Use this mapping for weather emojis: Sunny: ☀️, Cloudy: ☁️, Rainy: 🌧️, Snowy: ❄️ 4. When both [{context_tag}] and tool outputs are relevant, synthesize information from both sources to provide the most complete answer 5. Always prioritize the most up-to-date and relevant information, whether it comes from [{context_tag}] or tools 6. If [{context_tag}] and tool outputs contain conflicting information, prefer the tool outputs as they likely represent more current data @@ -273,6 +273,9 @@ def is_valid_uuid(value): def default_tools(tools): return [{**tool, "enabled": True} for tool in tools] +def find_summarize_tool(tools): + return [{**tool, "enabled": True} for tool in tools if tool.get("name", "") == "AnalyzeSite"] + def llm_tools(tools): return [tool for tool in tools if tool.get("enabled", False) == True] @@ -846,6 +849,13 @@ class WebServer: yield {"status": "processing", "message": "Processing request...", "num_ctx": ctx_size} # Use the async generator in an async for loop + # + # To support URL lookup: + # + # 1. Enable tools in a call to chat() with a simple prompt to invoke the tool to generate the summary if requested. + # 2. If not requested (no tool call,) abort the path + # 3. Otherwise, we know the URL was good and can use that URLs fetched content as context. + # response = self.client.generate(model=self.model, system=system_generate_resume, prompt=content, options={ 'num_ctx': ctx_size }) metadata["eval_count"] += response['eval_count'] metadata["eval_duration"] += response['eval_duration']