diff --git a/Makefile b/Makefile index 70588ba..573988f 100644 --- a/Makefile +++ b/Makefile @@ -187,7 +187,12 @@ dev: echo "✓ LangGraph server started on localhost:2024"; \ echo "Starting Gateway API..."; \ cd backend && uv run uvicorn src.gateway.app:app --host 0.0.0.0 --port 8001 > ../logs/gateway.log 2>&1 & \ - sleep 2; \ + sleep 3; \ + if ! lsof -i :8001 -sTCP:LISTEN -t >/dev/null 2>&1; then \ + echo "✗ Gateway API failed to start. Last log output:"; \ + tail -30 logs/gateway.log; \ + cleanup; \ + fi; \ echo "✓ Gateway API started on localhost:8001"; \ echo "Starting Frontend..."; \ cd frontend && pnpm run dev > ../logs/frontend.log 2>&1 & \ diff --git a/backend/src/agents/lead_agent/agent.py b/backend/src/agents/lead_agent/agent.py index 5877a71..7775cd1 100644 --- a/backend/src/agents/lead_agent/agent.py +++ b/backend/src/agents/lead_agent/agent.py @@ -12,6 +12,7 @@ from src.agents.middlewares.title_middleware import TitleMiddleware from src.agents.middlewares.uploads_middleware import UploadsMiddleware from src.agents.middlewares.view_image_middleware import ViewImageMiddleware from src.agents.thread_state import ThreadState +from src.config.app_config import get_app_config from src.config.summarization_config import get_summarization_config from src.models import create_chat_model from src.sandbox.middleware import SandboxMiddleware @@ -213,7 +214,6 @@ def _build_middlewares(config: RunnableConfig): # Add ViewImageMiddleware only if the current model supports vision model_name = config.get("configurable", {}).get("model_name") or config.get("configurable", {}).get("model") - from src.config import get_app_config app_config = get_app_config() # If no model_name specified, use the first model (default) diff --git a/backend/src/config/app_config.py b/backend/src/config/app_config.py index f438315..3c219d9 100644 --- a/backend/src/config/app_config.py +++ b/backend/src/config/app_config.py @@ -113,7 +113,10 @@ class AppConfig(BaseModel): """ if isinstance(config, str): if config.startswith("$"): - return os.getenv(config[1:], config) + env_value = os.getenv(config[1:]) + if env_value is None: + raise ValueError(f"Environment variable {config[1:]} not found for config value {config}") + return env_value return config elif isinstance(config, dict): return {k: cls.resolve_env_variables(v) for k, v in config.items()} diff --git a/backend/src/config/extensions_config.py b/backend/src/config/extensions_config.py index 61e2668..8b8f3e4 100644 --- a/backend/src/config/extensions_config.py +++ b/backend/src/config/extensions_config.py @@ -130,9 +130,10 @@ class ExtensionsConfig(BaseModel): for key, value in config.items(): if isinstance(value, str): if value.startswith("$"): - env_value = os.getenv(value[1:], None) - if env_value is not None: - config[key] = env_value + env_value = os.getenv(value[1:]) + if env_value is None: + raise ValueError(f"Environment variable {value[1:]} not found for config value {value}") + config[key] = env_value else: config[key] = value elif isinstance(value, dict): diff --git a/backend/src/gateway/app.py b/backend/src/gateway/app.py index 617e15d..f8643a0 100644 --- a/backend/src/gateway/app.py +++ b/backend/src/gateway/app.py @@ -1,9 +1,11 @@ import logging +import sys from collections.abc import AsyncGenerator from contextlib import asynccontextmanager from fastapi import FastAPI +from src.config.app_config import get_app_config from src.gateway.config import get_gateway_config from src.gateway.routers import artifacts, mcp, memory, models, skills, uploads @@ -20,6 +22,14 @@ logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: """Application lifespan handler.""" + + # Load config and check necessary environment variables at startup + try: + get_app_config() + logger.info("Configuration loaded successfully") + except Exception as e: + logger.error(f"Failed to load configuration: {e}") + sys.exit(1) config = get_gateway_config() logger.info(f"Starting API Gateway on {config.host}:{config.port}")