Spaces:
Sleeping
Sleeping
| """Central paths and constants for the Küchenpass-Agent project.""" | |
| from __future__ import annotations | |
| import os | |
| from pathlib import Path | |
| PROJECT_ROOT = Path(__file__).resolve().parent.parent | |
| DATA_DIR = PROJECT_ROOT / "data" | |
| RAW_DIR = DATA_DIR / "raw" | |
| PROCESSED_DIR = DATA_DIR / "processed" | |
| SAMPLES_DIR = DATA_DIR / "samples" | |
| MODELS_DIR = PROJECT_ROOT / "models" | |
| DOCS_DIR = PROJECT_ROOT / "docs" | |
| SCREENSHOTS_DIR = DOCS_DIR / "screenshots" | |
| ML_MODEL_PATH = MODELS_DIR / "prep_time_xgb.joblib" | |
| ML_PIPELINE_PATH = MODELS_DIR / "prep_time_pipeline.joblib" | |
| ML_METRICS_PATH = MODELS_DIR / "ml_metrics.json" | |
| CV_MODEL_PATH = MODELS_DIR / "food_classifier.pth" | |
| CV_CLASSES_PATH = MODELS_DIR / "cv_classes.json" | |
| CV_METRICS_PATH = MODELS_DIR / "cv_metrics.json" | |
| # Geographic plausibility bounds for the Food Delivery dataset (India). Latitude/ | |
| # longitude outside these ranges are treated as noise and set to NaN during | |
| # cleaning. Kept deliberately wide so valid rows are never dropped. | |
| GEO_LAT_BOUNDS = (6.0, 38.0) | |
| GEO_LON_BOUNDS = (68.0, 98.0) | |
| # Restaurant-relevant subset of Food-101 (10 dishes that map to typical orders) | |
| CV_TARGET_CLASSES: list[str] = [ | |
| "pizza", | |
| "hamburger", | |
| "spaghetti_bolognese", | |
| "caesar_salad", | |
| "french_fries", | |
| "ramen", | |
| "steak", | |
| "sushi", | |
| "lasagna", | |
| "tiramisu", | |
| ] | |
| STATIONS = ["grill", "pasta", "salad", "fryer", "pizza", "dessert", "cold"] | |
| DISH_TO_STATION: dict[str, str] = { | |
| "pizza": "pizza", | |
| "hamburger": "grill", | |
| "burger": "grill", | |
| "steak": "grill", | |
| "spaghetti_bolognese": "pasta", | |
| "spaghetti": "pasta", | |
| "lasagna": "pasta", | |
| "pasta": "pasta", | |
| "ramen": "pasta", | |
| "caesar_salad": "salad", | |
| "salad": "salad", | |
| "french_fries": "fryer", | |
| "fries": "fryer", | |
| "sushi": "cold", | |
| "tiramisu": "dessert", | |
| "dessert": "dessert", | |
| } | |
| OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-4o-mini") | |
| DECISION_CONFIDENCE_THRESHOLD = 0.6 | |
| # Maps NLP order dishes (which may carry style suffixes like "pizza_margherita" | |
| # or synonyms like "cheeseburger") onto one of the 10 CV_TARGET_CLASSES so the | |
| # pass-decision can compare the photographed dish with the order. Keys are | |
| # matched first exactly, then as substrings (see canonical_cv_dish). | |
| DISH_TO_CV_CLASS: dict[str, str] = { | |
| "pizza": "pizza", | |
| "margherita": "pizza", | |
| "hamburger": "hamburger", | |
| "burger": "hamburger", | |
| "cheeseburger": "hamburger", | |
| "spaghetti_bolognese": "spaghetti_bolognese", | |
| "spaghetti": "spaghetti_bolognese", | |
| "bolognese": "spaghetti_bolognese", | |
| "lasagna": "lasagna", | |
| "lasagne": "lasagna", | |
| "caesar_salad": "caesar_salad", | |
| "salad": "caesar_salad", | |
| "salat": "caesar_salad", | |
| "french_fries": "french_fries", | |
| "fries": "french_fries", | |
| "pommes": "french_fries", | |
| "ramen": "ramen", | |
| "steak": "steak", | |
| "sushi": "sushi", | |
| "tiramisu": "tiramisu", | |
| } | |
| # Per-class top-1 confidence thresholds for the pass decision. Derived from the | |
| # threshold sweep in src/cv/evaluate.py (precision target 0.95 per class). | |
| # Classes that are easily confused (lasagna<->pizza, spaghetti<->lasagna) need a | |
| # higher bar before we send the plate to the guest. Missing classes fall back to | |
| # DECISION_CONFIDENCE_THRESHOLD. | |
| PER_CLASS_THRESHOLDS: dict[str, float] = { | |
| "lasagna": 0.85, | |
| "pizza": 0.75, | |
| "spaghetti_bolognese": 0.80, | |
| "hamburger": 0.75, | |
| "ramen": 0.70, | |
| "steak": 0.70, | |
| "caesar_salad": 0.60, | |
| "sushi": 0.60, | |
| "tiramisu": 0.55, | |
| "french_fries": 0.55, | |
| } | |
| for _d in (DATA_DIR, RAW_DIR, PROCESSED_DIR, SAMPLES_DIR, MODELS_DIR): | |
| _d.mkdir(parents=True, exist_ok=True) | |