Просмотр исходного кода

[#1] chore: update default models, rewrite allergen check to use cached LLM, and update README grading layout

Lange François 3 недель назад
Родитель
Сommit
d10b10758b
53 измененных файлов с 374 добавлено и 114 удалено
  1. BIN
      Project.pdf
  2. 2 1
      README.md
  3. BIN
      Retro Planning.pdf
  4. 70 68
      app.py
  5. 1 1
      configure_zabbix_alerts.py
  6. 1 1
      docs/Backup_Procedure.md
  7. BIN
      docs/Backup_Procedure.pdf
  8. 1 1
      docs/Data_Ingestion.md
  9. BIN
      docs/Data_Ingestion.pdf
  10. 2 2
      docs/Final_Report.md
  11. BIN
      docs/Final_Report.pdf
  12. 1 1
      docs/Installation_Guide.md
  13. BIN
      docs/Installation_Guide.pdf
  14. 2 2
      docs/Operator_Installation_Guide.md
  15. BIN
      docs/Operator_Installation_Guide.pdf
  16. 1 1
      docs/Scrum_Artifacts.md
  17. BIN
      docs/Scrum_Artifacts.pdf
  18. 1 1
      docs/Scrum_Daily.md
  19. BIN
      docs/Scrum_Daily.pdf
  20. 1 1
      docs/Scrum_Plan.md
  21. BIN
      docs/Scrum_Plan.pdf
  22. 1 1
      docs/Scrum_Retro.md
  23. BIN
      docs/Scrum_Retro.pdf
  24. 1 1
      docs/Scrum_Review.md
  25. BIN
      docs/Scrum_Review.pdf
  26. 1 1
      docs/Scrum_Wiki.md
  27. BIN
      docs/Scrum_Wiki.pdf
  28. 1 1
      docs/Start_Stop_Procedures.md
  29. BIN
      docs/Start_Stop_Procedures.pdf
  30. 18 10
      docs/Technical_Document.md
  31. BIN
      docs/Technical_Document.pdf
  32. 1 1
      docs/Test_Cases_Sprint8.md
  33. BIN
      docs/Test_Cases_Sprint8.pdf
  34. 1 1
      docs/User_Description.md
  35. BIN
      docs/User_Description.pdf
  36. 2 2
      docs/User_Guide.md
  37. BIN
      docs/User_Guide.pdf
  38. 1 1
      docs/WSL_Deployment.md
  39. BIN
      docs/WSL_Deployment.pdf
  40. 1 1
      docs/Wiki_Home.md
  41. BIN
      docs/Wiki_Home.pdf
  42. BIN
      docs/architecture.pdf
  43. BIN
      docs/disaster_recovery_plan.pdf
  44. BIN
      docs/distributed_deployment.pdf
  45. BIN
      docs/docker_connection.pdf
  46. BIN
      docs/project_report.pdf
  47. BIN
      docs/retro_planning.pdf
  48. BIN
      docs/taiga_audit_report.pdf
  49. BIN
      docs/zabbix_monitoring.pdf
  50. 258 9
      generate_docs.py
  51. 1 1
      scripts/deploy_to_server.py
  52. 3 3
      scripts/manage_models.sh
  53. 1 1
      snmp_notifier.py

+ 2 - 1
README.md

@@ -41,7 +41,8 @@ This project leverages specialized AI skills to maintain code quality, documenta
 - **Test Generator**: Generates comprehensive unit and integration tests focusing on boundary conditions and logical coverage.
 - **Test Generator**: Generates comprehensive unit and integration tests focusing on boundary conditions and logical coverage.
 
 
 ## Grading
 ## Grading
-There will be 6 grades in total: 3 for Project Management 1 (PM1) and 3 for Domain-specifc Project 1 (DSP1).
+
+There will be 6 grades in total: 3 for Project Management 1 (PM1) and 3 for Domain-specific Project 1 (DSP1).
 
 
 ### PM1:
 ### PM1:
 * Requirements analysis and assessment.
 * Requirements analysis and assessment.

BIN
Retro Planning.pdf


+ 70 - 68
app.py

@@ -35,7 +35,7 @@ def get_active_model() -> str:
         load_dotenv(dotenv_path=env_path, override=True)
         load_dotenv(dotenv_path=env_path, override=True)
     except Exception:
     except Exception:
         pass
         pass
-    return os.environ.get('LLM_MODEL', 'llama3.2-vision:11b')
+    return os.environ.get('LLM_MODEL', 'llama3.2:3b')
 
 
 ACTIVE_MODEL = get_active_model()
 ACTIVE_MODEL = get_active_model()
 
 
@@ -45,78 +45,80 @@ def strip_scratchpad(text: str) -> str:
     clean_text = re.sub(r'<scratchpad>.*?</scratchpad>', '', text, flags=re.DOTALL)
     clean_text = re.sub(r'<scratchpad>.*?</scratchpad>', '', text, flags=re.DOTALL)
     return clean_text.strip()
     return clean_text.strip()
 
 
+@st.cache_data(show_spinner=False)
 def detect_allergens_from_text(name: str, ingredients: str) -> set:
 def detect_allergens_from_text(name: str, ingredients: str) -> set:
     import re
     import re
+    import ollama
     detected = set()
     detected = set()
-    text = (name + " " + ingredients).lower()
-    mappings = {
-        "peanut": "Peanuts",
-        "cacahuète": "Peanuts",
-        "cacahuete": "Peanuts",
-        "egg": "Eggs",
-        "oeuf": "Eggs",
-        "œuf": "Eggs",
-        "milk": "Milk",
-        "lait": "Milk",
-        "butter": "Milk",
-        "beurre": "Milk",
-        "cheese": "Milk",
-        "fromage": "Milk",
-        "cream": "Milk",
-        "crème": "Milk",
-        "creme": "Milk",
-        "wheat": "Wheat",
-        "blé": "Wheat",
-        "ble": "Wheat",
-        "gluten": "Gluten",
-        "soy": "Soy",
-        "soja": "Soy",
-        "almond": "Tree Nuts",
-        "amande": "Tree Nuts",
-        "cashew": "Tree Nuts",
-        "walnut": "Tree Nuts",
-        "noix": "Tree Nuts",
-        "hazelnut": "Tree Nuts",
-        "noisette": "Tree Nuts",
-        "pecan": "Tree Nuts",
-        "pistachio": "Tree Nuts",
-        "pistache": "Tree Nuts",
-        "fish": "Fish",
-        "poisson": "Fish",
-        "salmon": "Fish",
-        "saumon": "Fish",
-        "tuna": "Fish",
-        "thon": "Fish",
-        "shrimp": "Shellfish",
-        "crevette": "Shellfish",
-        "crab": "Shellfish",
-        "crabe": "Shellfish",
-        "lobster": "Shellfish",
-        "homard": "Shellfish",
-        "mussel": "Shellfish",
-        "moule": "Shellfish",
-        "oyster": "Shellfish",
-        "huître": "Shellfish",
-        "huitre": "Shellfish",
-        "sesame": "Sesame",
-        "sésame": "Sesame",
-        "mustard": "Mustard",
-        "moutarde": "Mustard",
-        "celery": "Celery",
-        "céleri": "Celery",
-        "celeri": "Celery",
-        "lupin": "Lupin",
-        "mollusc": "Molluscs",
-        "mollusque": "Molluscs",
-        "sulphite": "Sulphites",
-        "sulfite": "Sulphites"
-    }
-    for keyword, allergen in mappings.items():
-        pattern = r'\b' + re.escape(keyword) + r's?\b'
-        if re.search(pattern, text):
-            detected.add(allergen)
+    
+    # Extract candidate terms from name and ingredients
+    candidates = []
+    if ingredients:
+        # Split by typical separators: commas, semicolons, parentheses, newlines
+        parts = re.split(r'[,;()\[\]\n\r]', ingredients)
+        for p in parts:
+            p_clean = re.sub(r'[*_\d%]+', '', p).strip()
+            # Remove empty or common placeholder ingredients/non-ingredients
+            if len(p_clean) > 2 and p_clean.lower() not in ['ingredients', 'and', 'contains', 'may contain', 'natural', 'artificial', 'flavors', 'flavor', 'preservative', 'color', 'colors']:
+                candidates.append(p_clean)
+                
+    if name:
+        name_clean = re.sub(r'[*_\d%]+', '', name).strip()
+        if len(name_clean) > 2:
+            candidates.append(name_clean)
+            for word in re.split(r'\s+', name_clean):
+                w_clean = word.strip()
+                if len(w_clean) > 2 and w_clean.lower() not in ['with', 'and', 'for', 'the', 'bar', 'cup', 'can', 'bag', 'mix']:
+                    candidates.append(w_clean)
+                    
+    # Deduplicate candidates while keeping order
+    seen = set()
+    unique_candidates = []
+    for c in candidates:
+        c_low = c.lower()
+        if c_low not in seen:
+            seen.add(c_low)
+            unique_candidates.append(c)
+            
+    if not unique_candidates:
+        return detected
+        
+    prompt_lines = [
+        "You are a food safety expert. For each item in the list below, answer the question exactly.",
+        "Respond with 'Yes' or 'No'. Format the output exactly as:",
+        "ItemName: Yes/No",
+        "\nQuestions:"
+    ]
+    for c in unique_candidates:
+        prompt_lines.append(f"Answer by yes or no, if it is in some case answer yes : Are {c} allergens.")
+        
+    prompt = "\n".join(prompt_lines)
+    
+    try:
+        response = ollama.chat(model=get_active_model(), messages=[
+            {'role': 'user', 'content': prompt}
+        ])
+        content = response['message']['content']
+        for line in content.split('\n'):
+            if ':' in line:
+                parts = line.split(':')
+                left = parts[0].strip().lower()
+                right = parts[1].strip().lower()
+                
+                for c in unique_candidates:
+                    c_low = c.lower()
+                    if c_low in left and 'yes' in right:
+                        detected.add(c.title())
+            else:
+                for c in unique_candidates:
+                    c_low = c.lower()
+                    if f"are {c} allergens" in line.lower() and 'yes' in line.lower():
+                        detected.add(c.title())
+    except Exception:
+        pass
     return detected
     return detected
 
 
+
 def filter_scratchpad_stream(stream, raw_accumulator=None):
 def filter_scratchpad_stream(stream, raw_accumulator=None):
     buffer = ""
     buffer = ""
     in_scratchpad = False
     in_scratchpad = False

+ 1 - 1
configure_zabbix_alerts.py

@@ -1,6 +1,6 @@
 #ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 #ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 import json
 import json
-#ident "@(#)$Format:LocalFoodAI:configure_zabbix_alerts.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
+#ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 import urllib.request
 import urllib.request
 import os
 import os
 
 

+ 1 - 1
docs/Backup_Procedure.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Database Backup and Restore Procedure
 # Database Backup and Restore Procedure
 
 
 ## 1. Overview & Policy
 ## 1. Overview & Policy

BIN
docs/Backup_Procedure.pdf


+ 1 - 1
docs/Data_Ingestion.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Data Ingestion Pipeline
 # Data Ingestion Pipeline
 
 
 ## Overview
 ## Overview

BIN
docs/Data_Ingestion.pdf


+ 2 - 2
docs/Final_Report.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Final Project Report (Living Document)
 # Final Project Report (Living Document)
 
 
 ## What Has Been Done
 ## What Has Been Done
@@ -6,7 +6,7 @@
 2. **Database Optimization**: Successfully loaded OpenFoodFacts records and utilized advanced vertical partitioning and FULLTEXT indices.
 2. **Database Optimization**: Successfully loaded OpenFoodFacts records and utilized advanced vertical partitioning and FULLTEXT indices.
 3. **Clinical Subquery Strategy**: Refactored the core Pandas/SQL query pipeline to use subquery limiting, resolving Cartesian join explosions and reducing query latency to ~0.04s.
 3. **Clinical Subquery Strategy**: Refactored the core Pandas/SQL query pipeline to use subquery limiting, resolving Cartesian join explosions and reducing query latency to ~0.04s.
 4. **Monitoring & Security**: Nginx securely proxies traffic on Port 80. Zabbix actively monitors proxy and server health, dynamically handling SNMP/alert loops in local/offline fallback mode.
 4. **Monitoring & Security**: Nginx securely proxies traffic on Port 80. Zabbix actively monitors proxy and server health, dynamically handling SNMP/alert loops in local/offline fallback mode.
-5. **Git Versioning**: Implemented Git `.gitattributes` to push `$Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $` tracking directly into the Python Application UI.
+5. **Git Versioning**: Implemented Git `.gitattributes` to push `$Id$` tracking directly into the Python Application UI.
 
 
 ## What Needs To Be Done (Day 2 Operations)
 ## What Needs To Be Done (Day 2 Operations)
 1. **SSL/TLS Certificates**: The Nginx proxy is functional on HTTP port 80. Port 443 (HTTPS) must be configured with a Let's Encrypt certificate for true production encryption.
 1. **SSL/TLS Certificates**: The Nginx proxy is functional on HTTP port 80. Port 443 (HTTPS) must be configured with a Let's Encrypt certificate for true production encryption.

BIN
docs/Final_Report.pdf


+ 1 - 1
docs/Installation_Guide.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Installation Guide
 # Installation Guide
 
 
 ## Requirements
 ## Requirements

BIN
docs/Installation_Guide.pdf


+ 2 - 2
docs/Operator_Installation_Guide.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Local Food AI - Detailed Operator Installation Guide
 # Local Food AI - Detailed Operator Installation Guide
 
 
 This document is a step-by-step installation, mapping, configuration, and verification manual for deploying the **Local Food AI** system in an enterprise environment. It covers hybrid hypervisor infrastructure (WSL2, Hyper-V, and VirtualBox), cross-node networking, SNMPv3 monitoring, alert channels, and acceptance testing.
 This document is a step-by-step installation, mapping, configuration, and verification manual for deploying the **Local Food AI** system in an enterprise environment. It covers hybrid hypervisor infrastructure (WSL2, Hyper-V, and VirtualBox), cross-node networking, SNMPv3 monitoring, alert channels, and acceptance testing.
@@ -179,6 +179,6 @@ Run these test cases to verify the installation:
 | :--- | :--- | :--- | :---: |
 | :--- | :--- | :--- | :---: |
 | **TC-OP-01** | Search 'Cheese' on Search Tab | 10+ records returned in <0.04s. Listeria warning flags on unpasteurized. | `[ ]` |
 | **TC-OP-01** | Search 'Cheese' on Search Tab | 10+ records returned in <0.04s. Listeria warning flags on unpasteurized. | `[ ]` |
 | **TC-OP-02** | Enter '1.5 cups' in Plate Tab | Parsed and converted to metric grams based on density index. | `[ ]` |
 | **TC-OP-02** | Enter '1.5 cups' in Plate Tab | Parsed and converted to metric grams based on density index. | `[ ]` |
-| **TC-OP-03** | Ask Chat: 'Can I eat sushi?' | llama3.2-vision:11b retrieves database context and flags raw fish as forbidden for pregnancy. | `[ ]` |
+| **TC-OP-03** | Ask Chat: 'Can I eat sushi?' | llama3.2:3b retrieves database context and flags raw fish as forbidden for pregnancy. | `[ ]` |
 | **TC-OP-04** | Trigger manual db backup | Timestamped compressed .sql.gz created inside backups/ folder. | `[ ]` |
 | **TC-OP-04** | Trigger manual db backup | Timestamped compressed .sql.gz created inside backups/ folder. | `[ ]` |
 | **TC-OP-05** | Terminate Ollama Container | Zabbix PROBLEM active alert generated on dashboard in < 30 seconds. | `[ ]` |
 | **TC-OP-05** | Terminate Ollama Container | Zabbix PROBLEM active alert generated on dashboard in < 30 seconds. | `[ ]` |

BIN
docs/Operator_Installation_Guide.pdf


+ 1 - 1
docs/Scrum_Artifacts.md

@@ -1,3 +1,3 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Scrum Artifacts
 # Scrum Artifacts
 Contains User Stories, velocity tracking, and burndown charts from Taiga.
 Contains User Stories, velocity tracking, and burndown charts from Taiga.

BIN
docs/Scrum_Artifacts.pdf


+ 1 - 1
docs/Scrum_Daily.md

@@ -1,3 +1,3 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Daily Scrums
 # Daily Scrums
 - **26.05.07 DAILY**: Fixed time scope bug, added Nginx proxy, built sync scripts.
 - **26.05.07 DAILY**: Fixed time scope bug, added Nginx proxy, built sync scripts.

BIN
docs/Scrum_Daily.pdf


+ 1 - 1
docs/Scrum_Plan.md

@@ -1,3 +1,3 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Sprint Plans
 # Sprint Plans
 - **Sprint 10 PLAN**: Fix LLM Tool Calling, optimize Cartesian SQL explosion, build Teams webhooks.
 - **Sprint 10 PLAN**: Fix LLM Tool Calling, optimize Cartesian SQL explosion, build Teams webhooks.

BIN
docs/Scrum_Plan.pdf


+ 1 - 1
docs/Scrum_Retro.md

@@ -1,3 +1,3 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Sprint Retrospectives
 # Sprint Retrospectives
 - **Sprint 10 RETROSPECTIVE**: Mitigated dirty data duplicates using SQL `GROUP BY`. Need to maintain strict Git commit tagging (`TG-XXX`).
 - **Sprint 10 RETROSPECTIVE**: Mitigated dirty data duplicates using SQL `GROUP BY`. Need to maintain strict Git commit tagging (`TG-XXX`).

BIN
docs/Scrum_Retro.pdf


+ 1 - 1
docs/Scrum_Review.md

@@ -1,3 +1,3 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Sprint Reviews
 # Sprint Reviews
 - **Sprint 10 REVIEW**: App executes sub-second searches. Nginx fully operational on Port 80.
 - **Sprint 10 REVIEW**: App executes sub-second searches. Nginx fully operational on Port 80.

BIN
docs/Scrum_Review.pdf


+ 1 - 1
docs/Scrum_Wiki.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Scrum Wiki Master List & Index Portal
 # Scrum Wiki Master List & Index Portal
 
 
 Welcome to the static Scrum documentation portal. This master wiki aggregates and organizes all daily stand-up logs, planning reports, retrospectives, reviews, and velocity charts recorded during the agile development of the **Local Food AI** clinical dietetics engine.
 Welcome to the static Scrum documentation portal. This master wiki aggregates and organizes all daily stand-up logs, planning reports, retrospectives, reviews, and velocity charts recorded during the agile development of the **Local Food AI** clinical dietetics engine.

BIN
docs/Scrum_Wiki.pdf


+ 1 - 1
docs/Start_Stop_Procedures.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Infrastructure Stop & Start Operational Procedures
 # Infrastructure Stop & Start Operational Procedures
 
 
 This runbook outlines the exact sequence and commands to start, stop, and verify each microservice in the Local Food AI environment.
 This runbook outlines the exact sequence and commands to start, stop, and verify each microservice in the Local Food AI environment.

BIN
docs/Start_Stop_Procedures.pdf


+ 18 - 10
docs/Technical_Document.md

@@ -1,5 +1,5 @@
-#ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
-# Local Food AI - Capstone Technical Document
+# $Id$
+Local Food AI - Capstone Technical Document
 
 
 This document provides a comprehensive technical overview of the **Local Food AI** system. It details the installation and configuration procedures, technologies used, Antigravity agent usage/permissions, agent engineering reflections, local LLM design decisions, local microservice component communication, and data privacy verification.
 This document provides a comprehensive technical overview of the **Local Food AI** system. It details the installation and configuration procedures, technologies used, Antigravity agent usage/permissions, agent engineering reflections, local LLM design decisions, local microservice component communication, and data privacy verification.
 
 
@@ -32,19 +32,26 @@ flowchart TD
     end
     end
 
 
     subgraph "Gateway & Application Nodes"
     subgraph "Gateway & Application Nodes"
-        Nginx["Nginx Reverse Proxy\n(Port 80)"]
-        Streamlit["Streamlit Web App\n(Port 8502 / Docker Container)"]
+        Nginx["Nginx Reverse Proxy
+(Port 80)"]
+        Streamlit["Streamlit Web App
+(Port 8502 / Docker Container)"]
     end
     end
 
 
     subgraph "Intelligence & Search Nodes"
     subgraph "Intelligence & Search Nodes"
-        Ollama["Ollama Daemon\n(Port 11434 / Docker Container)"]
-        SearXNG["SearXNG Meta-Search\n(Port 8085 / Docker Container)"]
+        Ollama["Ollama Daemon
+(Port 11434 / Docker Container)"]
+        SearXNG["SearXNG Meta-Search
+(Port 8085 / Docker Container)"]
     end
     end
 
 
     subgraph "Data Storage & Observability Nodes"
     subgraph "Data Storage & Observability Nodes"
-        MySQL["MySQL Database Server\n(Port 3306 / Docker Container)"]
-        Zabbix["Zabbix Server & Agent\n(Ports 10051 & 10050)"]
-        ZabbixWeb["Zabbix Web Dashboard\n(Port 8081)"]
+        MySQL["MySQL Database Server
+(Port 3306 / Docker Container)"]
+        Zabbix["Zabbix Server & Agent
+(Ports 10051 & 10050)"]
+        ZabbixWeb["Zabbix Web Dashboard
+(Port 8081)"]
     end
     end
 
 
     %% Communication paths
     %% Communication paths
@@ -144,7 +151,8 @@ During the deployment and configuration phases, the Antigravity agent encountere
 ### 5.1 Regex Greediness Corrupting Python Literals
 ### 5.1 Regex Greediness Corrupting Python Literals
 * **The Struggle**: The dynamic git filter `git-ident-filter.py` used a greedy wildcard matching pattern `.*?[^$]*?$` which matched across lines. During checkouts, this matched from the `$Format:` string literal on line 403 of `app.py` directly to the regex search string on line 404, corrupting the code block into a single invalid tag and triggering a `SyntaxError: unterminated string literal`.
 * **The Struggle**: The dynamic git filter `git-ident-filter.py` used a greedy wildcard matching pattern `.*?[^$]*?$` which matched across lines. During checkouts, this matched from the `$Format:` string literal on line 403 of `app.py` directly to the regex search string on line 404, corrupting the code block into a single invalid tag and triggering a `SyntaxError: unterminated string literal`.
 * **The Resolution**:
 * **The Resolution**:
-  1. We modified the pattern in the filter to be line-restricted (`[^\r\n$]+\$`), ensuring it never matches across newline boundaries.
+  1. We modified the pattern in the filter to be line-restricted (`[^
+$]+\$`), ensuring it never matches across newline boundaries.
   2. We split the string literal searches inside `app.py` so they are physically split across concatenated strings (e.g. `"$Form" + "at:"`), which prevents the filter from ever matching the source code strings.
   2. We split the string literal searches inside `app.py` so they are physically split across concatenated strings (e.g. `"$Form" + "at:"`), which prevents the filter from ever matching the source code strings.
 
 
 ### 5.2 Git Checkout Filter Self-Mod Loops
 ### 5.2 Git Checkout Filter Self-Mod Loops

BIN
docs/Technical_Document.pdf


+ 1 - 1
docs/Test_Cases_Sprint8.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Sprint 8 Legacy Test Cases
 # Sprint 8 Legacy Test Cases
 - Tested RAG AI tool integration.
 - Tested RAG AI tool integration.
 - Tested user authentication flows.
 - Tested user authentication flows.

BIN
docs/Test_Cases_Sprint8.pdf


+ 1 - 1
docs/User_Description.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Local Food AI - User Description & Functional Guide
 # Local Food AI - User Description & Functional Guide
 
 
 ## 1. System Vision
 ## 1. System Vision

BIN
docs/User_Description.pdf


+ 2 - 2
docs/User_Guide.md

@@ -1,5 +1,5 @@
-#ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
-# Local Food AI - Clinician User Manual
+# $Id$
+Local Food AI - Clinician User Manual
 
 
 Welcome to the **Local Food AI** clinical dietitian explorer. This guide explains how to use the platform to search for products, build custom recipe plates, calculate cumulative nutritional statistics, and consult the privacy-safe AI assistant.
 Welcome to the **Local Food AI** clinical dietitian explorer. This guide explains how to use the platform to search for products, build custom recipe plates, calculate cumulative nutritional statistics, and consult the privacy-safe AI assistant.
 
 

BIN
docs/User_Guide.pdf


+ 1 - 1
docs/WSL_Deployment.md

@@ -1,4 +1,4 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # WSL Deployment Runbook
 # WSL Deployment Runbook
 To deploy on Windows Subsystem for Linux:
 To deploy on Windows Subsystem for Linux:
 1. Ensure WSL2 backend is enabled in Docker Desktop.
 1. Ensure WSL2 backend is enabled in Docker Desktop.

BIN
docs/WSL_Deployment.pdf


+ 1 - 1
docs/Wiki_Home.md

@@ -1,3 +1,3 @@
-# $Id: 03cbc893f143c3ae43fc35e97913bedb89b41e23 Lange François lanfr144@school.lu 2026/06/11 10:38:26 Lange François lanfr144@school.lu 2026/06/11 10:38:26   [#1] chore: fix git-ident-filter self-modification regex bug by concatenating search strings [PreRelease-1.0-28-g03cbc89] $
+# $Id$
 # Documentation Home
 # Documentation Home
 Welcome to the static documentation mirror. Please navigate the markdown files in this directory for architectural diagrams and guides.
 Welcome to the static documentation mirror. Please navigate the markdown files in this directory for architectural diagrams and guides.

BIN
docs/Wiki_Home.pdf


BIN
docs/architecture.pdf


BIN
docs/disaster_recovery_plan.pdf


BIN
docs/distributed_deployment.pdf


BIN
docs/docker_connection.pdf


BIN
docs/project_report.pdf


BIN
docs/retro_planning.pdf


BIN
docs/taiga_audit_report.pdf


BIN
docs/zabbix_monitoring.pdf


+ 258 - 9
generate_docs.py

@@ -3,7 +3,7 @@
 # $Author$
 # $Author$
 # $log$
 # $log$
 import os
 import os
-#ident "@(#)$Format:LocalFoodAI:generate_docs.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
+#ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 import subprocess
 import subprocess
 
 
 docs_dir = "docs"
 docs_dir = "docs"
@@ -141,17 +141,266 @@ Drop a `en.openfoodfacts.org.products.csv` file into the `/data` folder and run
 5. Navigate to `http://localhost` (or `http://localhost:8502` for direct Streamlit port)
 5. Navigate to `http://localhost` (or `http://localhost:8502` for direct Streamlit port)
 """,
 """,
     "User_Guide.md": """# $Id$
     "User_Guide.md": """# $Id$
-# User Guide
+Local Food AI - Clinician User Manual
+
+Welcome to the **Local Food AI** clinical dietitian explorer. This guide explains how to use the platform to search for products, build custom recipe plates, calculate cumulative nutritional statistics, and consult the privacy-safe AI assistant.
+
+---
+
+## 1. Accessing the Application
+
+To access the platform on your local network:
+1. Open your web browser (Chrome, Firefox, or Safari).
+2. Enter the host address provided by your IT administrator (e.g., `http://192.168.130.170:8502/` or `http://localhost:8502/`).
+3. You will be greeted by the secure login screen.
 
 
-## 1. Clinical Data Search
-Search for products using keywords. The system utilizes FULLTEXT matching to instantly return the top 10 relevant matches alongside macronutrient data.
+---
+
+## 2. Account Login & Security
+
+To protect patient information, the system requires credentials:
+* **Login**: Enter your standard clinician username and password.
+* **Request Reset**: If you have forgotten your password, select **Reset Password** in the sidebar. Enter your username, and a secure password recovery link will be dispatched to your registered email.
+* **Active Session**: The application uses secure local browser cookies to retain your login session for a convenient experience. Select **Logout** in the sidebar at any time to terminate your session.
+
+---
 
 
-## 2. My Plate Builder
-Add portion sizes of different foods to calculate cumulative nutritional intake. Use the 🗑️ icon to remove items.
+## 3. Sidebar Features & Controls
+
+The left-hand sidebar houses several global settings:
+* **Network Status**: Visual indicator of whether you are in *Online/Server* mode or *Offline/Local Fallback* mode.
+* **LLM Engine Status**: Displays the active local AI model being queried (e.g., `llama3.2:3b`).
+* **Active User Info**: Shows the logged-in clinician profile.
+* **Dynamic Version Header**: Displays the system Git version, date, and commit code for auditable change management.
+
+---
+
+## 4. Feature Guides
+
+The application dashboard is split into three interactive workspace tabs:
+
+### 4.1. Clinical Data Search Tab 🔍
+Use this tab to browse the local OpenFoodFacts food database.
+1. **Keyword Input**: Type a product name, brand, or barcode (e.g., "whole wheat bread" or "unpasteurized cheese").
+2. **Dynamic Results**: The database performs a rapid search, displaying the top 10 matched products.
+3. **Nutritional Score**: Shows the Nutri-Score grade (A to E) and details (Proteins, Carbs, Fats, Energy in kcal) per 100g.
+4. **Allergen Warnings**: Shows highlight flags if the product contains common allergens matching your client's needs.
+
+### 4.2. My Plate Builder Tab 🍽️
+Build custom meals or recipe portions to calculate total client nutritional intake.
+1. **Adding Items**: When browsing foods in the Search Tab, click **Add to Plate**.
+2. **Specifying Portions**: Input the quantity using either decimal weights (in grams) or common volume descriptors (e.g., "1.5 cups", "2 tablespoons"). The converter translates volume to metric weight based on the product density.
+3. **Cumulative Intake Table**: The tab renders a table summarizing individual macros and total energy.
+4. **Visual Metrics**: Renders a dynamic bar chart comparing Carbs, Proteins, and Fats against recommended clinical intake thresholds.
+5. **Editing the Plate**: Use the trash bin icon (🗑️) to instantly remove any item from the calculation.
+
+### 4.3. Consultation Chat Tab 💬
+Consult the built-in clinical AI dietitian assistant for recipe validation, medical profile warnings, and meal plans.
+1. **Client Profile Selection**: Select active dietary constraints (e.g., pregnancy, diabetes, kidney disease, vegetarian) in the dropdown.
+2. **Asking Questions**: Type your prompt (e.g., "Is unpasteurized brie cheese safe for a pregnant client?" or "Design a low-sodium, high-protein menu").
+3. **RAG-Augmented Output**: The local AI assistant automatically searches the SQL database to fetch exact ingredient and macro rows before writing its response.
+4. **Chain-of-Thought Explanation**: The AI displays its reasoning process step-by-step to explain how it formulated the final diet recommendation or safety warning.
+
+---
 
 
-## 3. Chat with AI
-Ask the `qwen2.5:7b` model complex dietary questions. It natively utilizes RAG Tool Calling to silently search the database and formulate clinical answers.
+## 5. Privacy and Offline Support
+
+Because patient privacy is critical:
+* **No Cloud Overhead**: All search strings, chat prompts, and plate records are processed locally inside the host node.
+* **Safe External Searches**: When asking about foods not indexed in the database, the AI queries a local private search wrapper (SearXNG) that strips metadata and cookies, ensuring no identifying queries are sent to external web engines.
 """,
 """,
+
+
+
+        "Technical_Document.md": """# $Id$
+Local Food AI - Capstone Technical Document
+
+This document provides a comprehensive technical overview of the **Local Food AI** system. It details the installation and configuration procedures, technologies used, Antigravity agent usage/permissions, agent engineering reflections, local LLM design decisions, local microservice component communication, and data privacy verification.
+
+---
+
+## 1. System Overview & Technologies Used
+
+The Local Food AI system is a privacy-first, locally-hosted clinical dietitian platform. It is designed to run in environments with strict network restrictions (such as clinics or hospitals) while delivering sub-second database lookups and medical advice.
+
+### Technology Stack
+* **Frontend Web UI**: Streamlit (Python) - hosts search tabs, plate builder, and RAG chat portal.
+* **Database**: MySQL 8.0 - stores OpenFoodFacts records with dynamic vertical partitioning.
+* **Database Migrations**: Alembic - automates schema migrations and relational view definitions.
+* **AI NLP Inference Engine**: Ollama (locally hosted daemon) - runs quantized local models.
+* **Private Web Meta-Search**: SearXNG - provides anonymous web search fallback without cookies or tracking.
+* **Observability Suite**: Zabbix (Server, Web UI, and Agent) - captures SNMP telemetry, custom application traps, and status loops.
+* **Web Server Proxy Gateway**: Nginx - acts as a secure reverse proxy on standard network Port 80.
+* **Task Pipelines**: Apache Airflow - schedules and monitors data ingestion flows.
+
+---
+
+## 2. Dynamic Component Infrastructure Diagram
+
+The diagram below represents how the system components communicate locally inside the closed network boundary. All request-response loops are processed within the host server limits.
+
+```mermaid
+flowchart TD
+    subgraph "Client Layer"
+        Browser["Clinician Browser"]
+    end
+
+    subgraph "Gateway & Application Nodes"
+        Nginx["Nginx Reverse Proxy\n(Port 80)"]
+        Streamlit["Streamlit Web App\n(Port 8502 / Docker Container)"]
+    end
+
+    subgraph "Intelligence & Search Nodes"
+        Ollama["Ollama Daemon\n(Port 11434 / Docker Container)"]
+        SearXNG["SearXNG Meta-Search\n(Port 8085 / Docker Container)"]
+    end
+
+    subgraph "Data Storage & Observability Nodes"
+        MySQL["MySQL Database Server\n(Port 3306 / Docker Container)"]
+        Zabbix["Zabbix Server & Agent\n(Ports 10051 & 10050)"]
+        ZabbixWeb["Zabbix Web Dashboard\n(Port 8081)"]
+    end
+
+    %% Communication paths
+    Browser -->|HTTP| Nginx
+    Nginx -->|Reverse Proxy Pass| Streamlit
+    Streamlit -->|EAV & FULLTEXT SQL queries| MySQL
+    Streamlit -->|Local Chat Inference / RAG| Ollama
+    Streamlit -->|Tool-Calling search queries| SearXNG
+    Streamlit -->|SNMP Traps / Telemetry| Zabbix
+    ZabbixWeb -->|Queries metrics| Zabbix
+```
+
+---
+
+## 3. Installation & Configuration Guide
+
+To deploy the Local Food AI system, follow the sequential commands below:
+
+### 3.1 Prerequisite Environment Setup
+The notebook workstation must have at least 16 GB of RAM, Docker, and Docker Compose installed.
+
+### 3.2 Dynamic Double-Mode Configuration
+1. **Host Environment File (`.env`)**:
+   Configure database credentials, active network mode, and the target model name:
+   ```ini
+   NETWORK_MODE=server
+   LLM_MODEL=llama3.2:3b
+   MYSQL_ROOT_PASSWORD=your_db_password_here
+   DB_READER_PASS=your_db_password_here
+   DB_LOADER_PASS=your_db_password_here
+   DB_APP_AUTH_PASS=your_db_password_here
+   MYSQL_ZABBIX_PASSWORD=your_db_password_here
+   SERVER_HOST=192.168.130.170
+   SERVER_USER=francois
+   SERVER_PASS=your_db_password_here
+   ```
+
+2. **Compose Topology Mappings**:
+   The `app` container maps the host's `.env` config file dynamically using environment bindings and volume mounts inside [docker-compose.yml](file:///c:/Users/lanfr144/Documents/DOPRO1/Antigravity/Food/docker-compose.yml):
+   ```yaml
+     app:
+       build:
+         context: .
+         dockerfile: docker/app/Dockerfile
+       ports:
+         - "8502:8501"
+       environment:
+         - DB_HOST=mysql
+         - DB_USER=food_reader
+         - DB_PASS=${DB_READER_PASS}
+         - LLM_MODEL=${LLM_MODEL}
+       volumes:
+         - ./.env:/app/.env
+   ```
+
+### 3.3 Execution Commands
+* **Production Build & Launch**:
+  ```bash
+  docker compose up -d --build
+  ```
+* **Offline Local Fallback Build & Launch**:
+  ```bash
+  docker compose -f docker-compose_skip.yml up -d --build
+  ```
+* **Sequential Shutdown & Restart (Safe Ordering)**:
+  Run the sequential operations script to prevent dependency hangs:
+  ```bash
+  chmod +x manage_services.sh
+  ./manage_services.sh restart
+  ```
+
+---
+
+## 4. Antigravity Models, Agent Tasks & Permissions
+
+During the capstone engineering lifecycle, specialized Antigravity models were utilized to orchestrate task domains. To maintain strict repository security, agent permissions were configured with the narrowest scope possible.
+
+### 4.1 Antigravity Models & Task Domains
+* **Code Review Subagent**: Analyzed pull requests and code modifications in `app.py`, identifying structural vulnerabilities and syntax errors.
+* **Doc Writer Subagent**: Maintained and generated the markdown manuals inside the `docs/` folder, ensuring they stayed synchronized with file changes.
+* **Expert Coach Subagent**: Guided architectural patterns, enforced optimal EAV vertical partitioning schemas in MySQL, and checked the validity of `$Format:` dynamic headers.
+* **Git Commit Governance Subagent**: Linked repository commits directly to the Taiga task board using strict Taiga hooks and validated task creation.
+* **SQL Optimizer Subagent**: Reviewed indices, FULLTEXT query structures, and partitioning tables to prevent Cartesian query time increases.
+
+### 4.2 Agent Permissions Configuration
+To restrict the agent's capability and protect the developer environment, permissions were set under the following restrictions:
+* **`read_file` & `write_file`**: Limited exclusively to the workspace directory `c:\\Users\\lanfr144\\Documents\\DOPRO1\\Antigravity\\Food` (excluding system-level directories like `/tmp` or `.gemini`).
+* **`command` (Shell Execution)**: Sandboxed to standard non-root terminal commands. Command prefixes were limited to `git`, `python`, `chmod`, `docker-compose`, and `Get-Content` within the workspace path.
+* **`read_url` & `execute_url`**: Restrained solely to local network nodes (`192.168.130.170` for docker orchestration and `192.168.130.161` for Taiga API requests) to prevent external DNS lookups or unauthorized egress.
+
+---
+
+## 5. Reflections: Engineering Struggles & Solutions
+
+During the deployment and configuration phases, the Antigravity agent encountered several technical struggles, which were successfully resolved as follows:
+
+### 5.1 Regex Greediness Corrupting Python Literals
+* **The Struggle**: The dynamic git filter `git-ident-filter.py` used a greedy wildcard matching pattern `.*?[^$]*?$` which matched across lines. During checkouts, this matched from the `$Format:` string literal on line 403 of `app.py` directly to the regex search string on line 404, corrupting the code block into a single invalid tag and triggering a `SyntaxError: unterminated string literal`.
+* **The Resolution**:
+  1. We modified the pattern in the filter to be line-restricted (`[^\r\n$]+\$`), ensuring it never matches across newline boundaries.
+  2. We split the string literal searches inside `app.py` so they are physically split across concatenated strings (e.g. `"$Form" + "at:"`), which prevents the filter from ever matching the source code strings.
+
+### 5.2 Git Checkout Filter Self-Mod Loops
+* **The Struggle**: When performing cache resets or major checkouts, Git deleted `local_tools/git-ident-filter.py` from the disk. When git began restoring other files, it attempted to call the smudge filter, but since the script was missing, Python threw file-not-found errors and checkouts failed.
+* **The Resolution**: We separated the checkout process by checking out the filter script first (`git checkout HEAD -- local_tools/git-ident-filter.py`), and then executing checkout on the rest of the repository.
+
+### 5.3 Character Encoding Conflicts
+* **The Struggle**: French accent characters (such as `ç` in `Lange François`) in the smudged Git headers were written using different system encoding tables. Python's default text readers choked on these characters with decode errors, blocking file writes.
+* **The Resolution**: We built custom Python encoding sanitizer scripts that opened markdown and python files with `errors='replace'`, stripped out replacement characters, and forced them to overwrite as clean UTF-8 strings.
+
+---
+
+## 6. Local LLM Rationale
+
+The Local Food AI system is configured to run **`llama3.2:3b`** (quantized 3-Billion parameter Llama 3.2 model) natively using Ollama.
+
+### Rationale
+1. **Hardware Memory Footprint**: The model utilizes 4-bit quantization, requiring roughly 2.2 GB of RAM. This fits comfortably inside the minimal hardware constraint (16 GB total notebook memory) alongside the MySQL and Zabbix containers.
+2. **Clinical Dialogue Proficiency**: Despite its small size, Llama 3.2 is highly optimized for instruction-following and tool-calling. This allows the Streamlit app to reliably execute RAG lookups (generating SQL queries or meta-search requests) and format responses using clinical CoT templates.
+3. **Completely Local Inference**: The model runs entirely inside the `food-ollama-1` container on the local network, bypassing any latency or dependency associated with commercial cloud models.
+
+---
+
+## 7. Data Privacy Verification: Keeping User Data on the Server
+
+To prove and guarantee that no clinical user details or dietary profiles leave the local server boundary, we executed the following verification procedures:
+
+1. **Proxy Access Log Audits**:
+   Audited Nginx (`/var/log/nginx/access.log`) and Streamlit access logs. All connections originate exclusively from local subnet IPs (e.g., `192.168.1.50` or loopback `127.0.0.1`).
+2. **Network Egress Block (Docker Configuration)**:
+   The `mysql` and `app` services inside `docker-compose.yml` run inside a custom bridge network. The database container has no external port bindings to the public internet, and the `app` container only exposes port `8502` to the local LAN.
+3. **Private Web Meta-Search (SearXNG)**:
+   The SearXNG meta-search container redirects external queries locally. Standard search APIs route traffic anonymously through local proxy rotators to prevent search engines from linking queries to the clinician's IP or user profile.
+4. **Traffic Sniffing (TCPDump Verification)**:
+   We ran `tcpdump` on the server interface during active chat sessions:
+   ```bash
+   tcpdump -i eth0 dst port not 80 and dst port not 22 and dst port not 161
+   ```
+   No packet transmissions were detected routing data outside the local network, proving that LLM prompts, dietitian responses, and plate nutritional configurations remain entirely inside the local node boundary.
+""",
+
+
     "Wiki_Home.md": """# $Id$
     "Wiki_Home.md": """# $Id$
 # Documentation Home
 # Documentation Home
 Welcome to the static documentation mirror. Please navigate the markdown files in this directory for architectural diagrams and guides.
 Welcome to the static documentation mirror. Please navigate the markdown files in this directory for architectural diagrams and guides.
@@ -537,7 +786,7 @@ Run these test cases to verify the installation:
 | :--- | :--- | :--- | :---: |
 | :--- | :--- | :--- | :---: |
 | **TC-OP-01** | Search 'Cheese' on Search Tab | 10+ records returned in <0.04s. Listeria warning flags on unpasteurized. | `[ ]` |
 | **TC-OP-01** | Search 'Cheese' on Search Tab | 10+ records returned in <0.04s. Listeria warning flags on unpasteurized. | `[ ]` |
 | **TC-OP-02** | Enter '1.5 cups' in Plate Tab | Parsed and converted to metric grams based on density index. | `[ ]` |
 | **TC-OP-02** | Enter '1.5 cups' in Plate Tab | Parsed and converted to metric grams based on density index. | `[ ]` |
-| **TC-OP-03** | Ask Chat: 'Can I eat sushi?' | llama3.2-vision:11b retrieves database context and flags raw fish as forbidden for pregnancy. | `[ ]` |
+| **TC-OP-03** | Ask Chat: 'Can I eat sushi?' | llama3.2:3b retrieves database context and flags raw fish as forbidden for pregnancy. | `[ ]` |
 | **TC-OP-04** | Trigger manual db backup | Timestamped compressed .sql.gz created inside backups/ folder. | `[ ]` |
 | **TC-OP-04** | Trigger manual db backup | Timestamped compressed .sql.gz created inside backups/ folder. | `[ ]` |
 | **TC-OP-05** | Terminate Ollama Container | Zabbix PROBLEM active alert generated on dashboard in < 30 seconds. | `[ ]` |
 | **TC-OP-05** | Terminate Ollama Container | Zabbix PROBLEM active alert generated on dashboard in < 30 seconds. | `[ ]` |
 """
 """

+ 1 - 1
scripts/deploy_to_server.py

@@ -34,7 +34,7 @@ def deploy():
         ssh.connect(host, username=user, password=password, timeout=10)
         ssh.connect(host, username=user, password=password, timeout=10)
         print("Connected successfully!")
         print("Connected successfully!")
         
         
-        local_model = os.environ.get('LLM_MODEL', 'llama3.2-vision:11b')
+        local_model = os.environ.get('LLM_MODEL', 'llama3.2:3b')
         command = f"cd food_project && git stash && rm -f git_version.txt git_id.txt && git pull && git stash clear && sed -i 's/^LLM_MODEL=.*/LLM_MODEL={local_model}/' .env && docker-compose up -d --build"
         command = f"cd food_project && git stash && rm -f git_version.txt git_id.txt && git pull && git stash clear && sed -i 's/^LLM_MODEL=.*/LLM_MODEL={local_model}/' .env && docker-compose up -d --build"
         print(f"Executing: {command}")
         print(f"Executing: {command}")
         
         

+ 3 - 3
scripts/manage_models.sh

@@ -1,12 +1,12 @@
 #!/bin/bash
 #!/bin/bash
 #ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 #ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 
 
-echo "Pulling the new efficient billion-parameter model (llama3.2-vision:11b)..."
-docker exec food-ollama-1 ollama pull llama3.2-vision:11b
+echo "Pulling the new efficient billion-parameter model (llama3.2:3b)..."
+docker exec food-ollama-1 ollama pull llama3.2:3b
 
 
 echo "Cleaning up unused models to free up disk space..."
 echo "Cleaning up unused models to free up disk space..."
 docker exec food-ollama-1 ollama rm qwen2.5:7b
 docker exec food-ollama-1 ollama rm qwen2.5:7b
-docker exec food-ollama-1 ollama rm llama3.2:3b
+docker exec food-ollama-1 ollama rm llama3.2-vision:11b
 
 
 echo "Currently installed models:"
 echo "Currently installed models:"
 docker exec food-ollama-1 ollama list
 docker exec food-ollama-1 ollama list

+ 1 - 1
snmp_notifier.py

@@ -1,7 +1,7 @@
 #ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 #ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 import os
 import os
 import socket
 import socket
-#ident "@(#)$Format:LocalFoodAI:snmp_notifier.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
+#ident "@(#)$Format:LocalFoodAI:app.py:%an:%ae:%ad:%cn:%ce:%cd:%H:%D:%N$"
 import socket
 import socket
 
 
 class SNMPNotifier:
 class SNMPNotifier: