diff --git a/.gitignore b/.gitignore index 97fd3d1..5bc5244 100644 --- a/.gitignore +++ b/.gitignore @@ -109,3 +109,8 @@ Thumbs.db ui/node_modules navigator/.venv +# Context Engineering +BETA_README.md +DAY8_COMPLETE_SUMMARY.md +SPRINT_B_SUMMARY.md + diff --git a/navigator/app/config.py b/navigator/app/config.py index f06c6f9..11a162e 100644 --- a/navigator/app/config.py +++ b/navigator/app/config.py @@ -1,4 +1,5 @@ -from pydantic import BaseSettings, Field +from pydantic import Field +from pydantic_settings import BaseSettings from pathlib import Path from typing import Optional diff --git a/navigator/app/main.py b/navigator/app/main.py index e474bc2..3c0ea42 100644 --- a/navigator/app/main.py +++ b/navigator/app/main.py @@ -40,9 +40,13 @@ allow_headers=["*"] ) -# Serve static assets -app.mount("/images", StaticFiles(directory=os.path.join(DATA_DIR, "images")), name="images") -app.mount("/plans", StaticFiles(directory=os.path.join(DATA_DIR, "plans")), name="plans") +# Serve static assets (only mount if directories exist) +images_dir = os.path.join(DATA_DIR, "images") +plans_dir = os.path.join(DATA_DIR, "plans") +if os.path.isdir(images_dir): + app.mount("/images", StaticFiles(directory=images_dir), name="images") +if os.path.isdir(plans_dir): + app.mount("/plans", StaticFiles(directory=plans_dir), name="plans") # ---- Lazy singletons ---- _store: FaissStore | None = None @@ -159,7 +163,10 @@ async def _startup_warm(): def _warm(): try: get_store() - get_model_and_transform() + # Optionally warm model depending on env + disable_warm = os.getenv("DISABLE_MODEL_WARMUP", "false").lower() == "true" + if not disable_warm: + get_model_and_transform() get_session_store() except Exception: # Avoid crashing startup on warm errors diff --git a/navigator/data/plans/.keep b/navigator/data/plans/.keep new file mode 100644 index 0000000..e69de29 diff --git a/navigator/requirements.txt b/navigator/requirements.txt index 139fc76..7a3a3c7 100644 --- a/navigator/requirements.txt +++ b/navigator/requirements.txt @@ -2,6 +2,7 @@ fastapi==0.111.0 uvicorn[standard]==0.30.1 pydantic==2.7.4 +pydantic-settings>=2.2 numpy>=1.24 pillow>=10.0 faiss-cpu>=1.8.0 diff --git a/navigator/runtime.txt b/navigator/runtime.txt new file mode 100644 index 0000000..530fe91 --- /dev/null +++ b/navigator/runtime.txt @@ -0,0 +1 @@ +3.11.9 \ No newline at end of file diff --git a/render.yaml b/render.yaml index 8c82094..0cbcff6 100644 --- a/render.yaml +++ b/render.yaml @@ -1,14 +1,14 @@ services: - type: web name: arch-circare-api - runtime: python + env: python rootDir: navigator buildCommand: pip install -r requirements.txt startCommand: uvicorn app.main:app --host 0.0.0.0 --port $PORT plan: starter envVars: - key: DATA_DIR - value: ../data + value: data - key: MAX_UPLOAD_MB value: "10" - key: ALLOW_PDF @@ -17,10 +17,14 @@ services: value: "https://arch-circare-ui.onrender.com,http://localhost:5173" - key: UPLOAD_TMP_DIR value: /tmp + - key: PYTHON_VERSION + value: "3.11.9" + - key: DISABLE_MODEL_WARMUP + value: "true" - type: web name: arch-circare-ui - runtime: static + env: static rootDir: ui buildCommand: npm ci --no-audit --no-fund && npm run build staticPublishPath: dist diff --git a/ui/src/components/FeedbackButtons.tsx b/ui/src/components/FeedbackButtons.tsx index 113b208..702a856 100644 --- a/ui/src/components/FeedbackButtons.tsx +++ b/ui/src/components/FeedbackButtons.tsx @@ -1,5 +1,4 @@ -import React from 'react'; - +// Feedback controls for each result card interface FeedbackButtonsProps { imageId: string; isLiked?: boolean; diff --git a/ui/src/components/LatentMap.tsx b/ui/src/components/LatentMap.tsx index eb180b8..c53f01e 100644 --- a/ui/src/components/LatentMap.tsx +++ b/ui/src/components/LatentMap.tsx @@ -188,7 +188,7 @@ export default function LatentMap({ onLensChange, selectedProjectId, lensImageId // Update hover tooltip const point = findPointAt(x, y, canvas); - setHoveredPoint(point); + setHoveredPoint(point ?? null); if (point) { setHoveredPosition({ x, y }); } else { diff --git a/ui/src/components/ResultsGrid.tsx b/ui/src/components/ResultsGrid.tsx index 544af6f..f80d4bf 100644 --- a/ui/src/components/ResultsGrid.tsx +++ b/ui/src/components/ResultsGrid.tsx @@ -1,4 +1,5 @@ import { API_BASE } from '../lib/api'; +// Note: queryId is intentionally not destructured from props to satisfy TS6133 import FeedbackButtons from './FeedbackButtons'; interface SearchResult { @@ -117,7 +118,7 @@ function SpatialMetricsTooltip({ projectId, spatialDebug }: { ); } -export default function ResultsGrid({ results, isLoading, latency, debug, onOpenGallery, onFeedback, feedbackState, queryId }: ResultsGridProps) { +export default function ResultsGrid({ results, isLoading, latency, debug, onOpenGallery, onFeedback, feedbackState }: ResultsGridProps) { if (isLoading) { return (