File size: 5,215 Bytes
027123c
 
19bd037
 
027123c
 
 
 
 
 
 
 
 
 
 
 
 
 
81e5fe7
079782d
 
 
 
81e5fe7
0e02a0f
 
 
 
0721bb4
 
3743cfe
 
 
 
 
 
027123c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
079782d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
027123c
 
 
 
 
 
19bd037
 
027123c
 
 
 
 
 
 
 
2ba0613
 
c7d59cf
2ba0613
 
027123c
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"""Centralized configuration management using pydantic-settings."""

# import os
# from typing import Optional
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    """Application settings loaded from environment variables."""

    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        extra="allow",
        case_sensitive=False,
    )

    # Feature flags
    # REMOVED 2026-07-02: the former ENABLE_SLOW_PATH flag is gone. `structured_flow`
    # now always runs the analytical slow path (Planner -> TaskRunner -> Assembler), so
    # every structured question persists a report_inputs record (reports no longer
    # depend on flipping a flag). extra="allow" ignores a stale ENABLE_SLOW_PATH in .env.

    # DEPRECATED 2026-06-24: the problem_validated gate was removed (the goal is now
    # user-entered objective + business_questions, no agent validation). This flag no
    # longer has any effect — the gate call site in ChatHandler is commented out. Kept
    # to avoid .env churn; remove once no environment references it.
    enable_gate: bool = Field(alias="enable_gate", default=False)

    # Skip init_db() (create_all + startup DDL) on boot. TRUE by default post-dedorch
    # cutover: Go owns the dedorch schema, so Python (consumer-only role) must NOT run
    # init_db — its ALTER/index DDL on Go-owned tables fails with InsufficientPrivilege
    # ("must be owner of table rooms"). Set to false only for a local Python-owned DB.
    skip_init_db: bool = Field(alias="SKIP_INIT_DB", default=True)

    # Database
    postgres_connstring: str

    # Redis
    redis_url: str
    redis_prefix: str = "dataeyond-agent-service_"

    # Azure OpenAI - GPT-4o (map to .env names with double underscores)
    azureai_api_key_4o: str = Field(alias="azureai__api_key__4o", default="")
    azureai_endpoint_url_4o: str = Field(alias="azureai__endpoint__url__4o", default="")
    azureai_deployment_name_4o: str = Field(alias="azureai__deployment__name__4o", default="")
    azureai_api_version_4o: str = Field(alias="azureai__api__version__4o", default="")

    # Azure OpenAI - Embeddings
    azureai_api_key_embedding: str = Field(alias="azureai__api_key__embedding", default="")
    azureai_endpoint_url_embedding: str = Field(alias="azureai__endpoint__url__embedding", default="")
    azureai_deployment_name_embedding: str = Field(alias="azureai__deployment__name__embedding", default="")
    azureai_api_version_embedding: str = Field(alias="azureai__api__version__embedding", default="")

    # Azure Document Intelligence
    azureai_docintel_endpoint: str = Field(alias="azureai__docintel__endpoint", default="")
    azureai_docintel_key: str = Field(alias="azureai__docintel__key", default="")

    # Azure Blob Storage
    azureai_blob_sas: str = Field(alias="azureai__blob__sas", default="")
    azureai_container_endpoint: str = Field(alias="azureai__container__endpoint", default="")
    azureai_container_name: str = Field(alias="azureai__container__name", default="")
    azureai_container_account_name: str = Field(alias="azureai__container__account__name", default="")

    # Object storage provider toggle. Mirrors the Go data plane's `storage.provider`
    # (see Orchestrator config: azure_blob | supabase_s3). Blank falls back to azure_blob.
    # Tabular query execution reads the processed Parquet from whichever backend is active.
    storage_provider: str = Field(alias="STORAGE_PROVIDER", default="azure_blob")

    # Supabase S3-compatible object storage (active when storage_provider == "supabase_s3").
    # BRIDGE (Option C): lets Python read the same bucket Go writes to, until Go exposes a
    # source-data endpoint (see docs/proposal_go_source_data_endpoint.md) — then this client
    # is removed and Python stops touching storage directly.
    supabase_s3_bucket: str = Field(alias="SUPABASE_S3_BUCKET", default="")
    supabase_s3_endpoint: str = Field(alias="SUPABASE_S3_ENDPOINT", default="")
    supabase_s3_region: str = Field(alias="SUPABASE_S3_REGION", default="")
    supabase_s3_access_key_id: str = Field(alias="SUPABASE_S3_ACCESS_KEY_ID", default="")
    supabase_s3_secret_access_key: str = Field(alias="SUPABASE_S3_SECRET_ACCESS_KEY", default="")

    # Langfuse
    LANGFUSE_PUBLIC_KEY: str
    LANGFUSE_SECRET_KEY: str
    LANGFUSE_HOST: str

    # MongoDB (for users - existing)
    # emarcal_mongo_endpoint_url: str = Field(alias="emarcal__mongo__endpoint__url", default="")
    # emarcal_buma_mongo_dbname: str = Field(alias="emarcal__buma__mongo__dbname", default="")

    # JWT (for users - existing)
    emarcal_jwt_secret_key: str = Field(alias="emarcal__jwt__secret_key", default="")
    emarcal_jwt_algorithm: str = Field(alias="emarcal__jwt__algorithm", default="HS256")

    # Bcrypt salt (for users - existing)
    emarcal_bcrypt_salt: str = Field(alias="emarcal__bcrypt__salt", default="")

    # DB credential encryption (Fernet key for user-registered database creds)
    dataeyond_db_credential_key: str = Field(
        alias="dataeyond__db__credential__key"
    )


# Singleton instance
settings = Settings()