Add AGENTS.md documentation for AI agent guidance

This commit is contained in:
2026-02-23 09:59:52 -05:00
commit 2e2b817435
21 changed files with 2513 additions and 0 deletions

91
app/config.py Normal file
View File

@@ -0,0 +1,91 @@
"""Configuration management for watsonx-openai-proxy."""
import os
from typing import Dict, Optional
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
"""Application settings loaded from environment variables."""
# IBM Cloud Configuration
ibm_cloud_api_key: str
watsonx_project_id: str
watsonx_cluster: str = "us-south"
# Server Configuration
host: str = "0.0.0.0"
port: int = 8000
log_level: str = "info"
# API Configuration
api_key: Optional[str] = None
allowed_origins: str = "*"
# Token Management
token_refresh_interval: int = 3000 # 50 minutes in seconds
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False,
extra="allow", # Allow extra fields for model mapping
)
@property
def watsonx_base_url(self) -> str:
"""Construct the watsonx.ai base URL from cluster."""
return f"https://{self.watsonx_cluster}.ml.cloud.ibm.com/ml/v1"
@property
def cors_origins(self) -> list[str]:
"""Parse CORS origins from comma-separated string."""
if self.allowed_origins == "*":
return ["*"]
return [origin.strip() for origin in self.allowed_origins.split(",")]
def get_model_mapping(self) -> Dict[str, str]:
"""Extract model mappings from environment variables.
Looks for variables like MODEL_MAP_GPT4=ibm/granite-4-h-small
and creates a mapping dict.
"""
import re
mapping = {}
# Check os.environ first
for key, value in os.environ.items():
if key.startswith("MODEL_MAP_"):
model_name = key.replace("MODEL_MAP_", "")
model_name = re.sub(r'([A-Z]+)(\d+)', r'\1-\2', model_name)
openai_model = model_name.lower().replace("_", "-")
mapping[openai_model] = value
# Also check pydantic's extra fields (from .env file)
# These come in as lowercase: model_map_gpt4 instead of MODEL_MAP_GPT4
extra = getattr(self, '__pydantic_extra__', {}) or {}
for key, value in extra.items():
if key.startswith("model_map_"):
# Convert back to uppercase for processing
model_name = key.replace("model_map_", "").upper()
model_name = re.sub(r'([A-Z]+)(\d+)', r'\1-\2', model_name)
openai_model = model_name.lower().replace("_", "-")
mapping[openai_model] = value
return mapping
def map_model(self, openai_model: str) -> str:
"""Map an OpenAI model name to a watsonx model ID.
Args:
openai_model: OpenAI model name (e.g., "gpt-4", "gpt-3.5-turbo")
Returns:
Corresponding watsonx model ID, or the original name if no mapping exists
"""
model_map = self.get_model_mapping()
return model_map.get(openai_model, openai_model)
# Global settings instance
settings = Settings()