Fase 0 complete: extract all business logic, auth, database, and 176 endpoints from monolithic app.py into dedicated modules. Structure: - app.py: FastAPI hub (CORS, routers, startup/shutdown) - models.py: 13 Pydantic request models - utils.py: shared utilities (embed status, upload validation, process registries) - config.py: constants, env vars, model catalogs - auth/: crypto, jwt_auth, oidc, rate_limit - database/: db(), init_db(), schema DDL - services/: genai, compliance, chat, terraform, embeddings, cis_reports, mcp - routes/: 13 APIRouter modules (auth, users, oci_config, oci_explorer, genai, mcp, adb, embeddings, reports, chat, terraform, settings, cis_engine) Also: README updated with OCIR auth instructions for manual docker run. 86 tests passing.
124 lines
8.2 KiB
Python
124 lines
8.2 KiB
Python
"""
|
|
Application configuration — constants, paths, environment variables, model catalogs.
|
|
"""
|
|
import os
|
|
import secrets
|
|
import time
|
|
import logging
|
|
import concurrent.futures
|
|
from pathlib import Path
|
|
|
|
# ── Secrets & Auth ───────────────────────────────────────────────────────────
|
|
APP_SECRET = os.environ.get("APP_SECRET") or secrets.token_hex(32)
|
|
if not os.environ.get("APP_SECRET"):
|
|
import warnings
|
|
warnings.warn("APP_SECRET not set — using random key (tokens will not survive restarts). Set APP_SECRET in .env for production.")
|
|
JWT_ALG = "HS256"
|
|
JWT_EXP_H = int(os.environ.get("JWT_EXPIRY_HOURS", "12"))
|
|
|
|
# ── Paths ────────────────────────────────────────────────────────────────────
|
|
DATA = Path(os.environ.get("DATA_DIR", "/data"))
|
|
DB_PATH = DATA / "agent.db"
|
|
OCI_DIR = DATA / "oci_configs"
|
|
REPORTS = DATA / "reports"
|
|
MCP_DIR = DATA / "mcp_servers"
|
|
WALLET_DIR = DATA / "wallets"
|
|
TERRAFORM_DIR = DATA / "terraform"
|
|
_EMBED_STATUS_DIR = DATA / ".embed_status"
|
|
|
|
for d in [DATA, OCI_DIR, REPORTS, MCP_DIR, WALLET_DIR, TERRAFORM_DIR, _EMBED_STATUS_DIR]:
|
|
d.mkdir(parents=True, exist_ok=True)
|
|
|
|
# ── App Settings ─────────────────────────────────────────────────────────────
|
|
VERSION = "1.1"
|
|
_START_TIME = time.time()
|
|
_MAX_UPLOAD_BYTES = 50 * 1024 * 1024 # 50MB
|
|
|
|
# ── Chat Memory Compaction ───────────────────────────────────────────────────
|
|
COMPACT_TOKEN_THRESHOLD = 6000
|
|
COMPACT_KEEP_RECENT = 20
|
|
COMPACT_SUMMARY_MAX_TOKENS = 1500
|
|
COMPACT_MIN_MESSAGES = 8
|
|
|
|
# ── Concurrency ──────────────────────────────────────────────────────────────
|
|
_chat_executor = concurrent.futures.ThreadPoolExecutor(max_workers=10, thread_name_prefix="chat")
|
|
|
|
# ── Logging ──────────────────────────────────────────────────────────────────
|
|
logging.basicConfig(level=logging.INFO)
|
|
log = logging.getLogger("agent")
|
|
|
|
# ── OCI GenAI Models Catalog ─────────────────────────────────────────────────
|
|
GENAI_MODELS = {
|
|
"meta.llama-4-maverick-17b-128e-instruct-fp8": {"provider":"meta","name":"Meta Llama 4 Maverick","api_format":"GENERIC","max_tokens":8192,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyah6tjdejjashngznsylutuhhvufukzb2g2ls54g2flsfq"}},
|
|
"meta.llama-4-scout-17b-16e-instruct": {"provider":"meta","name":"Meta Llama 4 Scout","api_format":"GENERIC","max_tokens":8192,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyaw23hfc7mtvv5wef3gwvvaguyzqmhb5lx4r5s3y2xzc4a"}},
|
|
"google.gemini-2.5-pro": {"provider":"google","name":"Google Gemini 2.5 Pro","api_format":"GENERIC","max_tokens":65536,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyargceyuaysrjzo2metq2rinavayxqmpu7tkm6mmfojcvq"}},
|
|
"google.gemini-2.5-flash": {"provider":"google","name":"Google Gemini 2.5 Flash","api_format":"GENERIC","max_tokens":8192,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyaeo4ehrn25guuats5s45hnvswlhxo6riop275l2bkr2vq"}},
|
|
"openai.gpt-5.2": {"provider":"openai","name":"OpenAI GPT-5.2","api_format":"GENERIC","max_tokens":32768,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceya4fw3p5fddnexbfcurnz7spgkqb4mq4a6y5ubyv7777sa"}},
|
|
"openai.gpt-5.1": {"provider":"openai","name":"OpenAI GPT-5.1","api_format":"GENERIC","max_tokens":32768,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceya3darth2ozqcfssb2bats5jitpgigllccajasdyqljnkq"}},
|
|
"openai.gpt-5-mini": {"provider":"openai","name":"OpenAI GPT-5 Mini","api_format":"GENERIC","max_tokens":16384,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceya3eain4n6v3edm4ryjvze5hnjouujd4vralxntfalwjaq"}},
|
|
"openai.gpt-4.1": {"provider":"openai","name":"OpenAI GPT-4.1","api_format":"GENERIC","max_tokens":32768,"penalties":True,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyaa6g75r2qqmtzjaooqtlxv4lxkpcqp2jdd6plpq7yq7ea"}},
|
|
"openai.gpt-4.1-mini": {"provider":"openai","name":"OpenAI GPT-4.1 Mini","api_format":"GENERIC","max_tokens":16384,"penalties":True,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceya6pk3sxishpiexm2rb5sf4ytb5tsbz4to2g3g23smidaa"}},
|
|
"openai.gpt-4o": {"provider":"openai","name":"OpenAI GPT-4o","api_format":"GENERIC","max_tokens":16384,"penalties":True,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyah7slrtboxdbfdy5cdspsfts62yumoclpdgwydopse7za"}},
|
|
"openai.o4-mini": {"provider":"openai","name":"OpenAI o4-mini","api_format":"GENERIC","reasoning":True,"max_tokens":100000,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceya5ivfqp4fxlajoeg2cahlqtuuswagiv6a7dggpigy23bq"}},
|
|
"openai.o3": {"provider":"openai","name":"OpenAI o3","api_format":"GENERIC","reasoning":True,"max_tokens":100000,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyalgnrukpjk6wm5zsf4jzkoneahgswhrk7kukkoagwnzma"}},
|
|
"xai.grok-4": {"provider":"xai","name":"xAI Grok 4","api_format":"GENERIC","max_tokens":131072,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyaldmhg25is4nouena4oa2pj4nvwgfeempo4syiaazukia"}},
|
|
"xai.grok-3": {"provider":"xai","name":"xAI Grok 3","api_format":"GENERIC","max_tokens":131072,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyag3w2xk76vlahjujj2gdfeuzhflt25gbo3bxidlsqfjla"}},
|
|
"xai.grok-3-mini-fast": {"provider":"xai","name":"xAI Grok 3 Mini Fast","api_format":"GENERIC","max_tokens":131072,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyauvjoll2repj5pbtkk7pinwj57ex3lkehzpxd6v6rxscq"}},
|
|
}
|
|
|
|
EMBEDDING_MODELS = {
|
|
"cohere.embed-v4.0": {"name":"Cohere Embed v4.0 (Multimodal)","dims":1536,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyahw4vlsxm7newcqtlgmristnwxlrxox3h7bcnlomjpgwa"}},
|
|
"openai.text-embedding-3-large": {"name":"OpenAI Text Embedding 3 Large","dims":3072,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceya3i6o2p5h2mij6unya5bsyc46aqey5hwy3icncawo3vcq"}},
|
|
"openai.text-embedding-3-small": {"name":"OpenAI Text Embedding 3 Small","dims":1536,
|
|
"ocids":{"us-ashburn-1":"ocid1.generativeaimodel.oc1.iad.amaaaaaask7dceyarjpjyniixp4tf7kyhr5bfajxmky4sjmbki2hp55ns2pq"}},
|
|
}
|
|
|
|
GENAI_REGIONS = [
|
|
"us-chicago-1","us-ashburn-1","us-phoenix-1","uk-london-1",
|
|
"eu-frankfurt-1","ap-tokyo-1","ap-osaka-1","sa-saopaulo-1",
|
|
"ca-toronto-1","ap-melbourne-1","ap-mumbai-1","eu-amsterdam-1",
|
|
"me-jeddah-1","ap-singapore-1","ap-seoul-1","sa-vinhedo-1",
|
|
]
|
|
|
|
OCI_REGIONS = {
|
|
"Americas": [
|
|
"us-ashburn-1","us-phoenix-1","us-chicago-1","us-sanjose-1","us-saltlake-2",
|
|
"ca-toronto-1","ca-montreal-1",
|
|
"sa-saopaulo-1","sa-vinhedo-1","sa-bogota-1","sa-santiago-1","sa-valparaiso-1",
|
|
"mx-queretaro-1","mx-monterrey-1",
|
|
],
|
|
"Europe": [
|
|
"eu-frankfurt-1","eu-amsterdam-1","eu-zurich-1","eu-madrid-1","eu-marseille-1",
|
|
"eu-milan-1","eu-paris-1","eu-stockholm-1","eu-jovanovac-1","eu-dcc-rome-1",
|
|
"uk-london-1","uk-cardiff-1",
|
|
"il-jerusalem-1",
|
|
],
|
|
"Asia Pacific": [
|
|
"ap-tokyo-1","ap-osaka-1","ap-seoul-1","ap-chuncheon-1",
|
|
"ap-mumbai-1","ap-hyderabad-1",
|
|
"ap-melbourne-1","ap-sydney-1",
|
|
"ap-singapore-1","ap-singapore-2",
|
|
],
|
|
"Middle East & Africa": [
|
|
"me-jeddah-1","me-abudhabi-1","me-dubai-1","me-riyadh-1",
|
|
"af-johannesburg-1",
|
|
],
|
|
}
|