diff --git a/frontend/src/config/navigationConfig.tsx b/frontend/src/config/navigationConfig.tsx
index c35fac6..e58db2c 100644
--- a/frontend/src/config/navigationConfig.tsx
+++ b/frontend/src/config/navigationConfig.tsx
@@ -8,31 +8,23 @@ import {
BarChart as BarChartIcon,
Settings as SettingsIcon,
Work as WorkIcon,
- Info as InfoIcon,
Person as PersonIcon,
Business as BusinessIcon,
Quiz as QuizIcon,
Analytics as AnalyticsIcon,
Search as SearchIcon,
Bookmark as BookmarkIcon,
- History as HistoryIcon,
- QuestionAnswer as QuestionAnswerIcon,
- AttachMoney as AttachMoneyIcon,
- BubbleChart,
- InsertEmoticon,
+ BubbleChart,
} from '@mui/icons-material';
import FaceRetouchingNaturalIcon from '@mui/icons-material/FaceRetouchingNatural';
import LibraryBooksIcon from '@mui/icons-material/LibraryBooks';
-import PersonSearchIcon from '@mui/icons-material/PersonSearch';
import { BackstoryLogo } from 'components/ui/BackstoryLogo';
import { HomePage } from 'pages/HomePage';
import { CandidateChatPage } from 'pages/CandidateChatPage';
-import { ResumeBuilderPage } from 'pages/ResumeBuilderPage';
import { DocsPage } from 'pages/DocsPage';
import { CreateProfilePage } from 'pages/CreateProfilePage';
import { VectorVisualizerPage } from 'pages/VectorVisualizerPage';
import { BetaPage } from 'pages/BetaPage';
-import { CandidateListingPage } from 'pages/FindCandidatePage';
import { JobAnalysisPage } from 'pages/JobAnalysisPage';
import { GenerateCandidate } from 'pages/GenerateCandidate';
import { Settings } from 'pages/candidate/Settings';
@@ -42,11 +34,8 @@ import { EmailVerificationPage } from 'components/EmailVerificationComponents';
import { Box, Typography } from '@mui/material';
import { NavigationConfig, NavigationItem } from 'types/navigation';
import { CandidateProfile } from 'pages/candidate/Profile';
-import { JobPicker } from 'components/ui/JobPicker';
import { DocumentManager } from 'components/DocumentManager';
import { VectorVisualizer } from 'components/VectorVisualizer';
-import { ComingSoon } from 'components/ui/ComingSoon';
-import { Beta } from 'components/ui/Beta';
// Beta page components for placeholder routes
const SearchPage = () => (Search);
@@ -68,16 +57,14 @@ export const navigationConfig: NavigationConfig = {
{ id: 'candidate-qa-setup', label: 'Q&A Setup', icon: , path: '/candidate/qa-setup', component: Candidate q&a setup page, userTypes: ['candidate'] },
{ id: 'candidate-analytics', label: 'Analytics', icon: , path: '/candidate/analytics', component: Candidate analytics page, userTypes: ['candidate'] },
{ id: 'candidate-job-analysis', label: 'Job Analysis', path: '/candidate/job-analysis', icon: , component: , userTypes: ['candidate'], },
- { id: 'candidate-resumes', label: 'Resumes', icon: , path: '/candidate/resumes', component: Candidate resumes page, userTypes: ['candidate'] },
- { id: 'candidate-resume-builder', label: 'Resume Builder', path: '/candidate/resume-builder', icon: , component: , userTypes: ['candidate'], },
+ { id: 'candidate-resumes', label: 'Resumes', icon: , path: '/candidate/resumes', component: Candidate resumes page, userTypes: ['candidate'] },
{ id: 'candidate-content', label: 'Content', icon: , path: '/candidate/content', component: , userTypes: ['candidate'] },
{ id: 'candidate-settings', label: 'Settings', path: '/candidate/settings', icon: , component: , userTypes: ['candidate'], },
],
},
{
id: 'employer-menu', label: 'Employer Tools', icon: , userTypes: ['employer'], children: [
- { id: 'employer-job-analysis', label: 'Job Analysis', path: '/employer/job-analysis', icon: , component: , userTypes: ['employer'], },
- { id: 'employer-resume-builder', label: 'Resume Builder', path: '/employer/resume-builder', icon: , component: , userTypes: ['employer'], },
+ { id: 'employer-job-analysis', label: 'Job Analysis', path: '/employer/job-analysis', icon: , component: , userTypes: ['employer'], },
{ id: 'employer-knowledge-explorer', label: 'Knowledge Explorer', path: '/employer/knowledge-explorer', icon: , component: , userTypes: ['employer'], },
{ id: 'employer-search', label: 'Search', path: '/employer/search', icon: , component: , userTypes: ['employer'], },
{ id: 'employer-saved', label: 'Saved', path: '/employer/saved', icon: , component: , userTypes: ['employer'], },
diff --git a/frontend/src/pages/ResumeBuilderPage.css b/frontend/src/pages/ResumeBuilderPage.css
deleted file mode 100644
index 0f71ee9..0000000
--- a/frontend/src/pages/ResumeBuilderPage.css
+++ /dev/null
@@ -1,6 +0,0 @@
-.ResumeBuilder .JsonViewScrollable {
- min-height: unset !important;
- max-height: 30rem !important;
- border: 1px solid orange;
- overflow-x: auto !important;
-}
\ No newline at end of file
diff --git a/frontend/src/pages/ResumeBuilderPage.tsx b/frontend/src/pages/ResumeBuilderPage.tsx
deleted file mode 100644
index 85af5d0..0000000
--- a/frontend/src/pages/ResumeBuilderPage.tsx
+++ /dev/null
@@ -1,385 +0,0 @@
-import React, { useState, useCallback, useRef } from 'react';
-import {
- Tabs,
- Tab,
- Box,
-} from '@mui/material';
-import { SxProps } from '@mui/material';
-
-import { BackstoryQuery } from 'components/BackstoryQuery';
-import { Conversation } from 'components/Conversation';
-import { BackstoryPageProps } from 'components/BackstoryTab';
-import { ChatQuery, ChatMessage } from "types/types";
-import './ResumeBuilderPage.css';
-import { useAppState } from 'hooks/GlobalContext';
-
-/**
- * ResumeBuilder component
- *
- * A responsive component that displays job descriptions, generated resumes and fact checks
- * with different layouts for mobile and desktop views.
- */
-const ResumeBuilderPage: React.FC = (props: BackstoryPageProps) => {
- // State for editing job description
- const [hasJobDescription, setHasJobDescription] = useState(false);
- const [hasResume, setHasResume] = useState(false);
- const [hasFacts, setHasFacts] = useState(false);
- const jobConversationRef = useRef(null);
- const resumeConversationRef = useRef(null);
- const factsConversationRef = useRef(null);
-
- const [activeTab, setActiveTab] = useState(0);
-
- /**
- * Handle tab change for mobile view
- */
- const handleTabChange = (_event: React.SyntheticEvent, newValue: number): void => {
- setActiveTab(newValue);
- };
-
- const handleJobQuery = (query: ChatQuery) => {
- console.log(`handleJobQuery: ${query.prompt} -- `, jobConversationRef.current ? ' sending' : 'no handler');
- jobConversationRef.current?.submitQuery(query);
- };
-
- const handleResumeQuery = (query: ChatQuery) => {
- console.log(`handleResumeQuery: ${query.prompt} -- `, resumeConversationRef.current ? ' sending' : 'no handler');
- resumeConversationRef.current?.submitQuery(query);
- };
-
- const handleFactsQuery = (query: ChatQuery) => {
- console.log(`handleFactsQuery: ${query.prompt} -- `, factsConversationRef.current ? ' sending' : 'no handler');
- factsConversationRef.current?.submitQuery(query);
- };
-
- const filterJobDescriptionMessages = useCallback((messages: ChatMessage[]): ChatMessage[] => {
- if (messages === undefined || messages.length === 0) {
- return [];
- }
-
- if (messages.length > 0) {
- // messages[0].role = 'content';
- // messages[0].title = 'Job Description';
- // messages[0].disableCopy = false;
- // messages[0].expandable = true;
- }
-
- if (-1 !== messages.findIndex(m => m.status === 'done')) { // || (m.actions && m.actions.includes("resume_generated")))) {
- setHasResume(true);
- setHasFacts(true);
- }
-
- return messages;
-
- if (messages.length > 1) {
- setHasResume(true);
- setHasFacts(true);
- }
-
-
- if (messages.length > 3) {
- // messages[2] is Show job requirements
- // messages[3].role = 'job-requirements';
- // messages[3].title = 'Job Requirements';
- // messages[3].disableCopy = false;
- // messages[3].expanded = false;
- // messages[3].expandable = true;
- }
-
- /* Filter out the 2nd and 3rd (0-based) */
- const filtered = messages;//.filter((m, i) => i !== 1 && i !== 2);
- console.warn("Set filtering back on");
-
- return filtered;
- }, [setHasResume, setHasFacts]);
-
- const filterResumeMessages = useCallback((messages: ChatMessage[]): ChatMessage[] => {
- if (messages === undefined || messages.length === 0) {
- return [];
- }
-
- return messages;
-
- if (messages.length > 1) {
- // messages[0] is Show Qualifications
- // messages[1].role = 'qualifications';
- // messages[1].title = 'Candidate qualifications';
- // messages[1].disableCopy = false;
- // messages[1].expanded = false;
- // messages[1].expandable = true;
- }
-
- if (messages.length > 3) {
- // messages[2] is Show Resume
- // messages[3].role = 'resume';
- // messages[3].title = 'Generated Resume';
- // messages[3].disableCopy = false;
- // messages[3].expanded = true;
- // messages[3].expandable = true;
- }
-
- /* Filter out the 1st and 3rd messages (0-based) */
- const filtered = messages.filter((m, i) => i !== 0 && i !== 2);
-
- return filtered;
- }, []);
-
- const filterFactsMessages = useCallback((messages: ChatMessage[]): ChatMessage[] => {
- if (messages === undefined || messages.length === 0) {
- return [];
- }
-
- if (messages.length > 1) {
- // messages[0] is Show verification
- // messages[1].role = 'fact-check';
- // messages[1].title = 'Fact Check';
- // messages[1].disableCopy = false;
- // messages[1].expanded = true;
- // messages[1].expandable = true;
- }
-
- /* Filter out the 1st (0-based) */
- const filtered = messages.filter((m, i) => i !== 0);
-
- return filtered;
- }, []);
-
- const jobResponse = useCallback(async (message: ChatMessage) => {
- // if (message.actions && message.actions.includes("job_description")) {
- // if (jobConversationRef.current) {
- // await jobConversationRef.current.fetchHistory();
- // }
- // }
- // if (message.actions && message.actions.includes("resume_generated")) {
- // if (resumeConversationRef.current) {
- // await resumeConversationRef.current.fetchHistory();
- // }
- // setHasResume(true);
- // setActiveTab(1); // Switch to Resume tab
- // }
- // if (message.actions && message.actions.includes("facts_checked")) {
- // if (factsConversationRef.current) {
- // await factsConversationRef.current.fetchHistory();
- // }
- // setHasFacts(true);
- // }
- }, [setHasFacts, setHasResume, setActiveTab]);
-
- const resumeResponse = useCallback((message: ChatMessage): void => {
- console.log('onResumeResponse', message);
- setHasFacts(true);
- }, [setHasFacts]);
-
- const factsResponse = useCallback((message: ChatMessage): void => {
- console.log('onFactsResponse', message);
- }, []);
-
- const resetJobDescription = useCallback(() => {
- setHasJobDescription(false);
- setHasResume(false);
- setHasFacts(false);
- }, [setHasJobDescription, setHasResume, setHasFacts]);
-
- const resetResume = useCallback(() => {
- setHasResume(false);
- setHasFacts(false);
- }, [setHasResume, setHasFacts]);
-
- const resetFacts = useCallback(() => {
- setHasFacts(false);
- }, [setHasFacts]);
-
- return (Not re-implmented yet);
-
-
-// const renderJobDescriptionView = useCallback((sx?: SxProps) => {
-// console.log('renderJobDescriptionView');
-// const jobDescriptionQuestions = [
-//
- //
- //
-// ,
-// ];
-
- // const jobDescriptionPreamble: ChatMessage[] = [{
-// role: 'info',
-// content: `Once you paste a job description and press **Generate Resume**, Backstory will perform the following actions:
-
-// 1. **Job Analysis**: LLM extracts requirements from '\`Job Description\`' to generate a list of desired '\`Skills\`'.
-// 2. **Candidate Analysis**: LLM determines candidate qualifications by performing skill assessments.
-
-// For each '\`Skill\`' from **Job Analysis** phase:
-
-// 1. **RAG**: Retrieval Augmented Generation collection is queried for context related content for each '\`Skill\`'.
-// 2. **Evidence Creation**: LLM is queried to generate supporting evidence of '\`Skill\`' from the '\`RAG\`' and '\`Candidate Resume\`'.
-// 3. **Resume Generation**: LLM is provided the output from the **Candidate Analysis:Evidence Creation** phase and asked to generate a professional resume.
-
-// See [About > Resume Generation Architecture](/about/resume-generation) for more details.
-// `,
-// disableCopy: true
-// }];
-
-
- // if (!hasJobDescription) {
- // return
-
- // } else {
- // return
- // }
- // }, [filterJobDescriptionMessages, hasJobDescription, sessionId, setSnack, jobResponse, resetJobDescription, hasFacts, hasResume, submitQuery]);
-
- // /**
- // * Renders the resume view with loading indicator
- // */
- // const renderResumeView = useCallback((sx?: SxProps) => {
- // const resumeQuestions = [
- //
- //
- //
- // ,
- // ];
-
- // if (!hasFacts) {
- // return
- // } else {
- // return
- // }
- // }, [filterResumeMessages, hasFacts, sessionId, setSnack, resumeResponse, resetResume, hasResume, submitQuery]);
-
- // /**
- // * Renders the fact check view
- // */
- // const renderFactCheckView = useCallback((sx?: SxProps) => {
- // const factsQuestions = [
- //
- //
- // ,
- // ];
-
- // return
- // }, [ sessionId, setSnack, factsResponse, filterFactsMessages, resetFacts, hasResume, hasFacts, submitQuery]);
-
- // return (
- //
- // {/* Tabs */}
- //
- //
- // {hasResume && }
- // {hasFacts && }
- //
-
- // {/* Document display area */}
- //
- // {renderJobDescriptionView(/*{ height: "calc(100% - 72px - 48px)" }*/)}
- // {renderResumeView(/*{ height: "calc(100% - 72px - 48px)" }*/)}
- // {renderFactCheckView(/*{ height: "calc(100% - 72px - 48px)" }*/)}
- //
- //
- // );
-};
-
-export {
- ResumeBuilderPage
-};
-
diff --git a/frontend/src/pages/candidate/Settings.tsx b/frontend/src/pages/candidate/Settings.tsx
index 17d2a47..5bd9c36 100644
--- a/frontend/src/pages/candidate/Settings.tsx
+++ b/frontend/src/pages/candidate/Settings.tsx
@@ -19,20 +19,20 @@ import { useAppState } from 'hooks/GlobalContext';
import { useAuth } from 'hooks/AuthContext';
import * as Types from 'types/types';
-interface ServerTunables {
- system_prompt: string,
- tools: Tool[],
- rags: Tool[]
-};
+// interface ServerTunables {
+// system_prompt: string,
+// tools: Tool[],
+// rags: Tool[]
+// };
-type Tool = {
- type: string,
- enabled: boolean
- name: string,
- description: string,
- parameters?: any,
- returns?: any
-};
+// type Tool = {
+// type: string,
+// enabled: boolean
+// name: string,
+// description: string,
+// parameters?: any,
+// returns?: any
+// };
const SystemInfoComponent: React.FC<{ systemInfo: Types.SystemInfo | undefined }> = ({ systemInfo }) => {
const [systemElements, setSystemElements] = useState([]);
@@ -77,13 +77,13 @@ const SystemInfoComponent: React.FC<{ systemInfo: Types.SystemInfo | undefined }
const Settings = (props: BackstoryPageProps) => {
const { apiClient } = useAuth();
const { setSnack } = useAppState();
- const [editSystemPrompt, setEditSystemPrompt] = useState("");
+ // const [editSystemPrompt, setEditSystemPrompt] = useState("");
const [systemInfo, setSystemInfo] = useState(undefined);
- const [tools, setTools] = useState([]);
- const [rags, setRags] = useState([]);
- const [systemPrompt, setSystemPrompt] = useState("");
- const [messageHistoryLength, setMessageHistoryLength] = useState(5);
- const [serverTunables, setServerTunables] = useState(undefined);
+ // const [tools, setTools] = useState([]);
+ // const [rags, setRags] = useState([]);
+ // const [systemPrompt, setSystemPrompt] = useState("");
+ // const [messageHistoryLength, setMessageHistoryLength] = useState(5);
+ // const [serverTunables, setServerTunables] = useState(undefined);
// useEffect(() => {
// if (serverTunables === undefined || systemPrompt === serverTunables.system_prompt || !systemPrompt.trim()) {
@@ -179,14 +179,14 @@ const Settings = (props: BackstoryPageProps) => {
fetchSystemInfo();
- }, [systemInfo, setSystemInfo, setSnack])
+ }, [systemInfo, setSystemInfo, setSnack, apiClient]);
- useEffect(() => {
- if (!systemPrompt) {
- return;
- }
- setEditSystemPrompt(systemPrompt.trim());
- }, [systemPrompt, setEditSystemPrompt]);
+ // useEffect(() => {
+ // if (!systemPrompt) {
+ // return;
+ // }
+ // setEditSystemPrompt(systemPrompt.trim());
+ // }, [systemPrompt, setEditSystemPrompt]);
// const toggleRag = async (tool: Tool) => {
// tool.enabled = !tool.enabled
diff --git a/frontend/src/routes/CandidateRoute.tsx b/frontend/src/routes/CandidateRoute.tsx
index c36f417..84f4296 100644
--- a/frontend/src/routes/CandidateRoute.tsx
+++ b/frontend/src/routes/CandidateRoute.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { Box } from "@mui/material";
@@ -37,7 +37,7 @@ const CandidateRoute: React.FC = (props: CandidateRouteProp
}
getCandidate(username);
- }, [selectedCandidate, username, selectedCandidate, navigate, setSnack, apiClient]);
+ }, [setSelectedCandidate, selectedCandidate, username, navigate, setSnack, apiClient]);
if (selectedCandidate?.username !== username) {
return (
diff --git a/frontend/src/services/api-client.ts b/frontend/src/services/api-client.ts
index 2b69cca..464a69a 100644
--- a/frontend/src/services/api-client.ts
+++ b/frontend/src/services/api-client.ts
@@ -1210,35 +1210,6 @@ class ApiClient {
return this.handleApiResponseWithConversion(response);
}
- /**
- * Retry mechanism for rate-limited requests
- */
- private async retryWithBackoff(
- requestFn: () => Promise,
- maxRetries: number = 3
- ): Promise {
- let lastError: Error;
-
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
- try {
- const response = await requestFn();
- return await this.handleApiResponseWithRateLimit(response);
- } catch (error) {
- lastError = error as Error;
-
- if (error instanceof RateLimitError && attempt < maxRetries) {
- const delayMs = Math.min(error.retryAfterSeconds * 1000, 60000); // Max 1 minute
- console.warn(`Rate limited, retrying in ${delayMs}ms (attempt ${attempt + 1}/${maxRetries + 1})`);
- await new Promise(resolve => setTimeout(resolve, delayMs));
- continue;
- }
-
- throw error;
- }
- }
-
- throw lastError!;
- }
async resetChatSession(id: string): Promise<{ success: boolean; message: string }> {
const response = await fetch(`${this.baseUrl}/chat/sessions/${id}/reset`, {
method: 'PATCH',