| |
| """Application-wide constants and configuration values.""" |
| import os |
|
|
| APP_VERSION = "1.0.0" |
|
|
| |
| BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + "/" |
| STATIC_DIR = os.path.join(BASE_DIR, "static") |
| DATA_DIR = os.getenv("ODYSSEUS_DATA_DIR", os.path.join(BASE_DIR, "data")) |
|
|
| |
| |
| |
| |
| SESSIONS_FILE = os.path.join(DATA_DIR, "sessions.json") |
| MEMORY_FILE = os.path.join(DATA_DIR, "memory.json") |
| MEMORY_DOC = os.path.join(DATA_DIR, "memory_doc.md") |
| PERSONAL_DIR = os.path.join(DATA_DIR, "personal_docs") |
| RUNBOOK_DIR = os.path.join(PERSONAL_DIR, "runbook") |
| UPLOAD_DIR = os.path.join(DATA_DIR, "uploads") |
| FEATURES_FILE = os.path.join(DATA_DIR, "features.json") |
| SETTINGS_FILE = os.path.join(DATA_DIR, "settings.json") |
| AUTH_FILE = os.path.join(DATA_DIR, "auth.json") |
| USER_PREFS_FILE = os.path.join(DATA_DIR, "user_prefs.json") |
| PRESETS_FILE = os.path.join(DATA_DIR, "presets.json") |
| INTEGRATIONS_FILE = os.path.join(DATA_DIR, "integrations.json") |
| CONTACTS_FILE = os.path.join(DATA_DIR, "contacts.json") |
| APP_KEY_FILE = os.path.join(DATA_DIR, ".app_key") |
| EMBEDDING_ENDPOINT_FILE = os.path.join(DATA_DIR, "embedding_endpoint.json") |
| COOKBOOK_STATE_FILE = os.path.join(DATA_DIR, "cookbook_state.json") |
| BG_JOBS_FILE = os.path.join(DATA_DIR, "bg_jobs.json") |
| VAULT_FILE = os.path.join(DATA_DIR, "vault.json") |
| TIDY_CALENDAR_STATE_FILE = os.path.join(DATA_DIR, "tidy_calendar_state.json") |
| SKILLS_FILE = os.path.join(DATA_DIR, "skills.json") |
| APP_DB = os.path.join(DATA_DIR, "app.db") |
| SCHEDULED_EMAILS_DB = os.path.join(DATA_DIR, "scheduled_emails.db") |
| EMAIL_CACHE_DB = os.path.join(DATA_DIR, "email_cache.db") |
|
|
| |
| PERSONAL_UPLOADS_DIR = os.path.join(DATA_DIR, "personal_uploads") |
| EMOJI_CACHE_DIR = os.path.join(DATA_DIR, "emoji_cache") |
| RAG_DIR = os.path.join(DATA_DIR, "rag") |
| CHROMA_DIR = os.path.join(DATA_DIR, "chroma") |
| BG_JOBS_DIR = os.path.join(DATA_DIR, "bg_jobs") |
| DEEP_RESEARCH_DIR = os.path.join(DATA_DIR, "deep_research") |
| MCP_OAUTH_DIR = os.path.join(DATA_DIR, "mcp_oauth") |
| GENERATED_IMAGES_DIR = os.path.join(DATA_DIR, "generated_images") |
| TTS_CACHE_DIR = os.path.join(DATA_DIR, "tts_cache") |
| EMAIL_URGENCY_CACHE_DIR = os.path.join(DATA_DIR, "email_urgency_cache") |
| SKILLS_DIR = os.path.join(DATA_DIR, "skills") |
| GALLERY_DIR = os.path.join(DATA_DIR, "gallery") |
| GALLERY_UPLOADS_DIR = os.path.join(DATA_DIR, "gallery_uploads") |
| MEMORY_VECTORS_DIR = os.path.join(DATA_DIR, "memory_vectors") |
|
|
| |
| MAIL_ATTACHMENTS_DIR = os.getenv("ODYSSEUS_MAIL_ATTACHMENTS_DIR", os.path.join(DATA_DIR, "mail-attachments")) |
| FASTEMBED_CACHE_DIR = os.getenv("FASTEMBED_CACHE_PATH", os.path.join(DATA_DIR, "fastembed_cache")) |
|
|
| |
| |
| MAX_OUTPUT_CHARS = 10_000 |
| MAX_READ_CHARS = 20_000 |
| MAX_DIFF_LINES = 400 |
|
|
| |
| MAX_CONTEXT_MESSAGES = 90 |
| REQUEST_TIMEOUT = 20 |
| OPENAI_COMPAT_PATH = "/v1/chat/completions" |
|
|
| |
| DEFAULT_HOST = os.getenv("LLM_HOST", "localhost") |
| LLM_HOSTS = [h.strip() for h in os.getenv("LLM_HOSTS", "").split(",") if h.strip()] |
| OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") |
| SEARXNG_INSTANCE = os.getenv("SEARXNG_INSTANCE", "http://localhost:8080") |
|
|
|
|
| |
| CLEANUP_ENABLED = os.getenv("CLEANUP_ENABLED", "True").lower() == "true" |
| CLEANUP_INTERVAL_HOURS = int(os.getenv("CLEANUP_INTERVAL_HOURS", "24")) |
|
|
| |
| DEFAULT_TEMPERATURE = 1.0 |
| DEFAULT_MAX_TOKENS = 0 |
|
|
|
|
| def internal_api_base() -> str: |
| """Base URL for in-process loopback calls to Odysseus's own API. |
| |
| Agent tools and background jobs reach admin-gated routes by calling the |
| running server over HTTP. Resolution order: |
| 1. ODYSSEUS_INTERNAL_BASE - explicit override (e.g. behind a TLS proxy). |
| 2. APP_PORT - http://127.0.0.1:$APP_PORT (docker-compose). |
| 3. Fallback http://127.0.0.1:7000 - legacy default. |
| |
| 127.0.0.1 (not "localhost") avoids IPv6/DNS ambiguity for a strictly-local |
| call. Without this, loopback tools fail with "All connection attempts |
| failed" whenever the server is not on port 7000. |
| """ |
| override = os.environ.get("ODYSSEUS_INTERNAL_BASE") |
| if override: |
| return override.rstrip("/") |
| return f"http://127.0.0.1:{os.environ.get('APP_PORT', '7000')}" |
|
|