From c1df6ffed574c3eb0d5ba276a4ebe9a669f9cbf3 Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Thu, 24 Apr 2025 16:55:28 -0700 Subject: [PATCH] Fixed type-os during migration --- .gitignore | 2 ++ Dockerfile | 11 +++++++++-- dev-keys/.keep | 0 docker-compose.yml | 3 ++- frontend/src/App.css | 1 - frontend/src/App.tsx | 5 ++++- frontend/src/Conversation.tsx | 11 +++++++++++ frontend/src/DocumentViewer.tsx | 26 +++++++++++++------------- frontend/src/logo.svg | 1 - sessions-prod/.keep | 0 src/server.py | 16 +++++++++------- src/utils/defines.py | 4 ++-- 12 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 dev-keys/.keep delete mode 100644 frontend/src/logo.svg create mode 100644 sessions-prod/.keep diff --git a/.gitignore b/.gitignore index 275febe..d1b49e3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,7 @@ cache/** jupyter/** ollama/** sessions/** +sessions-prod/** chromadb/** chromadb-prod/** +dev-keys/** diff --git a/Dockerfile b/Dockerfile index c0a9899..ca85044 100644 --- a/Dockerfile +++ b/Dockerfile @@ -337,8 +337,11 @@ RUN apt-get update \ WORKDIR /opt/ollama # Download the nightly ollama release from ipex-llm -ENV OLLAMA_VERSION=https://github.com/intel/ipex-llm/releases/download/v2.2.0/ollama-ipex-llm-2.2.0-ubuntu.tgz +#ENV OLLAMA_VERSION=https://github.com/intel/ipex-llm/releases/download/v2.2.0/ollama-ipex-llm-2.2.0-ubuntu.tgz #ENV OLLAMA_VERSION=https://github.com/intel/ipex-llm/releases/download/v2.3.0-nightly/ollama-ipex-llm-2.3.0b20250415-ubuntu.tgz + +# NOTE: NO longer at github.com/intel -- now at ipex-llm +ENV OLLAMA_VERSION=https://github.com/ipex-llm/ipex-llm/releases/download/v2.2.0/ollama-ipex-llm-2.2.0-ubuntu.tgz RUN wget -qO - ${OLLAMA_VERSION} | \ tar --strip-components=1 -C . -xzv @@ -411,12 +414,16 @@ RUN { \ && chmod +x /fetch-models.sh ENV PYTHONUNBUFFERED=1 + # Enable ext_intel_free_memory -ENV ZES_ENABLE_SYSMAN=1 +ENV ZES_ENABLE_SYSMAN=1 + # Use all GPUs ENV OLLAMA_NUM_GPU=999 + # Use immediate command lists ENV SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1 + # Use persistent cache ENV SYCL_CACHE_PERSISTENT=1 diff --git a/dev-keys/.keep b/dev-keys/.keep new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.yml b/docker-compose.yml index f7f6ab9..81c52eb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,6 +25,7 @@ services: - ./cache:/root/.cache # Persist all models and GPU kernel cache - ./sessions:/opt/backstory/sessions:rw # Persist sessions - ./chromadb:/opt/backstory/chromadb:rw # Persist ChromaDB + - ./dev-keys:/opt/backstory/keys:ro # Developer keys - ./docs:/opt/backstory/docs:ro # Live mount of RAG content - ./src:/opt/backstory/src:rw # Live mount server src - ./frontend:/opt/backstory/frontend:rw # Live mount frontend src @@ -57,7 +58,7 @@ services: volumes: - ./cache:/root/.cache # Persist all models and GPU kernel cache - ./chromadb-prod:/opt/backstory/chromadb:rw # Persist ChromaDB - - ./sessions:/opt/backstory/sessions:rw # Persist sessions + - ./sessions-prod:/opt/backstory/sessions:rw # Persist sessions - ./docs:/opt/backstory/docs:ro # Live mount of RAG content - ./frontend:/opt/backstory/frontend:rw # Live mount frontend src cap_add: # used for running ze-monitor within container diff --git a/frontend/src/App.css b/frontend/src/App.css index a034a7c..ebce5fa 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -123,7 +123,6 @@ button { flex-direction: column; font-size: 0.9rem; width: 100%; - /* max-width: 1024px; */ margin: 0 auto; } diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index f2384f0..3a8382a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -16,6 +16,7 @@ import IconButton from '@mui/material/IconButton'; import Box from '@mui/material/Box'; import CssBaseline from '@mui/material/CssBaseline'; import MenuIcon from '@mui/icons-material/Menu'; +import { useTheme } from '@mui/material/styles'; import { ResumeBuilder } from './ResumeBuilder'; @@ -83,6 +84,8 @@ const App = () => { const isDesktop = useMediaQuery('(min-width:650px)'); const prevIsDesktopRef = useRef(isDesktop); const chatRef = useRef(null); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down('md')); // Set the snack pop-up and open it const setSnack: SetSnackType = useCallback((message: string, severity: SeverityType = "success") => { @@ -154,7 +157,7 @@ What would you like to know about James? ]; const chatQuestions = [ - + diff --git a/frontend/src/Conversation.tsx b/frontend/src/Conversation.tsx index a8bcf90..068d30e 100644 --- a/frontend/src/Conversation.tsx +++ b/frontend/src/Conversation.tsx @@ -172,6 +172,9 @@ const Conversation = forwardRef(({ } catch (error) { console.error('Error generating session ID:', error); setProcessingMessage({ role: "error", content: "Unable to obtain history from server." }); + setTimeout(() => { + setProcessingMessage(undefined); + }, 5000); setSnack("Unable to obtain chat history.", "error"); } }; @@ -429,6 +432,10 @@ const Conversation = forwardRef(({ // Show error scrolledToBottom = isScrolledToBottom(); setProcessingMessage({ role: 'error', content: update.message }); + setTimeout(() => { + setProcessingMessage(undefined); + }, 5000); + // Add a small delay to ensure React has time to update the UI await new Promise(resolve => setTimeout(resolve, 0)); if (scrolledToBottom) { @@ -477,6 +484,10 @@ const Conversation = forwardRef(({ setSnack("Unable to process query", "error"); scrolledToBottom = isScrolledToBottom(); setProcessingMessage({ role: 'error', content: "Unable to process query" }); + setTimeout(() => { + setProcessingMessage(undefined); + }, 5000); + setProcessing(false); stopCountdown(); if (scrolledToBottom) { diff --git a/frontend/src/DocumentViewer.tsx b/frontend/src/DocumentViewer.tsx index b2a659f..ff931a7 100644 --- a/frontend/src/DocumentViewer.tsx +++ b/frontend/src/DocumentViewer.tsx @@ -222,9 +222,9 @@ const DocumentViewer: React.FC = ({ return message; }, []); - const renderJobDescriptionView = useCallback(() => { + const renderJobDescriptionView = useCallback((small: boolean) => { const jobDescriptionQuestions = [ - + , @@ -267,9 +267,9 @@ const DocumentViewer: React.FC = ({ /** * Renders the resume view with loading indicator */ - const renderResumeView = useCallback(() => { + const renderResumeView = useCallback((small: boolean) => { const resumeQuestions = [ - + , @@ -310,9 +310,9 @@ const DocumentViewer: React.FC = ({ /** * Renders the fact check view */ - const renderFactCheckView = useCallback(() => { + const renderFactCheckView = useCallback((small: boolean) => { const factsQuestions = [ - + , ]; @@ -346,7 +346,7 @@ const DocumentViewer: React.FC = ({ const children = []; children.push( - {renderJobDescriptionView()} + {renderJobDescriptionView(false)} ); /* Resume panel - conditionally rendered if resume defined, or processing is in progress */ @@ -354,7 +354,7 @@ const DocumentViewer: React.FC = ({ children.push( - {renderResumeView()} + {renderResumeView(false)} ); } @@ -364,7 +364,7 @@ const DocumentViewer: React.FC = ({ children.push( - {renderFactCheckView()} + {renderFactCheckView(false)} ); } @@ -417,13 +417,13 @@ const DocumentViewer: React.FC = ({ const getActiveMobileContent = () => { switch (activeTab) { case 0: - return renderJobDescriptionView(); + return renderJobDescriptionView(true); case 1: - return renderResumeView(); + return renderResumeView(true); case 2: - return renderFactCheckView(); + return renderFactCheckView(true); default: - return renderJobDescriptionView(); + return renderJobDescriptionView(true); } }; diff --git a/frontend/src/logo.svg b/frontend/src/logo.svg deleted file mode 100644 index 9dfc1c0..0000000 --- a/frontend/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/sessions-prod/.keep b/sessions-prod/.keep new file mode 100644 index 0000000..e69de29 diff --git a/src/server.py b/src/server.py index 9e98617..41ac1bb 100644 --- a/src/server.py +++ b/src/server.py @@ -542,11 +542,12 @@ class WebServer: data = await request.json() try: + session = context["sessions"][type] response = {} for reset in data["reset"]: match reset: case "system_prompt": - context["sessions"][type]["system_prompt"] = system_message + session["system_prompt"] = system_message response["system_prompt"] = { "system_prompt": system_message } case "rags": context["rags"] = rags.copy() @@ -555,11 +556,11 @@ class WebServer: context["tools"] = default_tools(tools) response["tools"] = context["tools"] case "history": - context["sessions"][type]["llm_history"] = [] - context["sessions"][type]["user_history"] = [] - context["sessions"][type]["context_tokens"] = round(len(str(context["system"])) * 3 / 4) # Estimate context usage + session["llm_history"] = [] + session["user_history"] = [] + session["context_tokens"] = round(len(str(session["system_prompt"])) * 3 / 4) # Estimate context usage response["history"] = [] - response["context_used"] = context["sessions"][type]["context_tokens"] + response["context_used"] = session["context_tokens"] case "message_history_length": context["message_history_length"] = DEFAULT_HISTORY_LENGTH response["message_history_length"] = DEFAULT_HISTORY_LENGTH @@ -580,13 +581,14 @@ class WebServer: return JSONResponse({"error": "Invalid context_id"}, status_code=400) context = self.upsert_context(context_id) data = await request.json() + session = context["sessions"]["chat"] for k in data.keys(): match k: case "system_prompt": system_prompt = data[k].strip() if not system_prompt: return JSONResponse({ "status": "error", "message": "System prompt can not be empty." }) - context["system"] = [{"role": "system", "content": system_prompt}] + session["system_prompt"] = system_prompt self.save_context(context_id) return JSONResponse({ "system_prompt": system_prompt }) case "message_history_length": @@ -604,7 +606,7 @@ class WebServer: return JSONResponse({"error": "Invalid context_id"}, status_code=400) context = self.upsert_context(context_id) return JSONResponse({ - "system_prompt": context["system"][0]["content"], + "system_prompt": context["sessions"]["chat"]["system_prompt"], "message_history_length": context["message_history_length"] }) diff --git a/src/utils/defines.py b/src/utils/defines.py index 8a24f8c..95ba2a8 100644 --- a/src/utils/defines.py +++ b/src/utils/defines.py @@ -13,5 +13,5 @@ session_dir = "/opt/backstory/sessions" static_content = '/opt/backstory/frontend/deployed' resume_doc = '/opt/backstory/docs/resume/generic.txt' # Only used for testing; backstory-prod will not use this -key_path = '/opt/backstory/src/key.pem' -cert_path = '/opt/backstory/src/cert.pem' \ No newline at end of file +key_path = '/opt/backstory/keys/key.pem' +cert_path = '/opt/backstory/keys/cert.pem' \ No newline at end of file