mirror of
https://github.com/hoshikawa2/compass_backoffice.git
synced 2026-07-09 13:54:20 +00:00
374 lines
23 KiB
Python
374 lines
23 KiB
Python
"""
|
|
Configuration management module using Pydantic Settings.
|
|
|
|
This module provides configuration loading from environment variables and YAML files,
|
|
with validation of required fields.
|
|
"""
|
|
|
|
from typing import Optional, List
|
|
from pathlib import Path
|
|
from pydantic import BaseModel, Field, field_validator, AliasChoices
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
import yaml
|
|
import os
|
|
from dotenv import load_dotenv
|
|
|
|
_PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
load_dotenv(_PROJECT_ROOT / ".env", override=False)
|
|
|
|
|
|
class LLMConfig(BaseModel):
|
|
"""LLM configuration model."""
|
|
|
|
provider: str = Field(..., description="LLM provider (openai, anthropic, etc.)")
|
|
model: str = Field(..., description="Model name")
|
|
temperature: float = Field(0.7, ge=0.0, le=2.0, description="Temperature for generation")
|
|
max_tokens: Optional[int] = Field(None, gt=0, description="Maximum tokens to generate")
|
|
|
|
@field_validator('provider')
|
|
@classmethod
|
|
def validate_provider(cls, v: str) -> str:
|
|
"""Validate that provider is supported."""
|
|
supported = ['openai', 'anthropic', 'oci_openai', 'oci', 'mock']
|
|
if v not in supported:
|
|
raise ValueError(f"Provider must be one of {supported}, got: {v}")
|
|
return v
|
|
|
|
|
|
class AgentConfig(BaseModel):
|
|
"""Agent-specific configuration model."""
|
|
|
|
name: str = Field(..., description="Agent name")
|
|
description: str = Field(..., description="Agent description")
|
|
system_prompt: str = Field(..., description="System prompt for the agent")
|
|
tools: List[str] = Field(default_factory=list, description="List of enabled tools")
|
|
max_iterations: int = Field(10, gt=0, description="Maximum graph iterations")
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(env_file=str(_PROJECT_ROOT / ".env"), extra="ignore", case_sensitive=False)
|
|
"""
|
|
Main settings class with support for environment variables and YAML files.
|
|
|
|
Configuration can be loaded from:
|
|
1. Environment variables (highest priority)
|
|
2. .env file
|
|
3. YAML file (via from_yaml method)
|
|
4. Default values (lowest priority)
|
|
"""
|
|
|
|
# App settings
|
|
APP_NAME: str = Field(default="Agent Microservice", description="Application name")
|
|
VERSION: str = Field(default="1.0.0", description="Application version")
|
|
DEBUG: bool = Field(default=False, description="Debug mode")
|
|
|
|
# LLM settings
|
|
LLM_PROVIDER: str = Field(default="oci_openai", description="LLM provider")
|
|
LLM_MODEL: str = Field(default="gpt-4", description="LLM model name")
|
|
LLM_TEMPERATURE: float = Field(default=0.7, ge=0.0, le=2.0, description="LLM temperature")
|
|
LLM_MAX_TOKENS: Optional[int] = Field(default=None, gt=0, description="Max tokens")
|
|
|
|
# Classification LLM settings
|
|
CLASSIFICATION_LLM_MODEL: str = Field(default="openai.gpt-4.1", description="Model name for classification node")
|
|
CLASSIFICATION_LLM_TEMPERATURE: float = Field(default=0.3, ge=0.0, le=2.0, description="Temperature for classification node")
|
|
CLASSIFICATION_LLM_MAX_TOKENS: int = Field(default=1024, gt=0, description="Max tokens for classification node")
|
|
CLASSIFICATION_LLM_TOP_P: float = Field(default=0.8, description="Top P for classification node")
|
|
CLASSIFICATION_LLM_TOP_K: float = Field(default=250, description="Top K for classification node")
|
|
|
|
# Large Classification LLM settings (for complex reasoning/canceling)
|
|
CLASSIFICATION_LARGE_LLM_MODEL: str = Field(default="openai.gpt-4.1", description="Large model name for critical classification steps")
|
|
CLASSIFICATION_LARGE_LLM_TEMPERATURE: float = Field(default=0.3, ge=0.0, le=2.0, description="Temperature for large classification node")
|
|
CLASSIFICATION_LARGE_LLM_MAX_TOKENS: int = Field(default=1024, gt=0, description="Max tokens for large classification node")
|
|
CLASSIFICATION_LARGE_LLM_TOP_P: float = Field(default=0.8, description="Top P for large classification node")
|
|
CLASSIFICATION_LARGE_LLM_TOP_K: float = Field(default=250, description="Top K for large classification node")
|
|
|
|
# API Keys
|
|
OPENAI_API_KEY: Optional[str] = Field(default=None, description="OpenAI API key")
|
|
ANTHROPIC_API_KEY: Optional[str] = Field(default=None, description="Anthropic API key")
|
|
|
|
# Server settings
|
|
HOST: str = Field(default="0.0.0.0", description="Server host")
|
|
PORT: int = Field(default=8000, gt=0, lt=65536, description="Server port")
|
|
|
|
# Logging
|
|
LOG_LEVEL: str = Field(default="INFO", description="Logging level")
|
|
LOG_FORMAT: str = Field(default="text", description="Log format (json or text)")
|
|
LOG_NOISY_LEVEL: str = Field(default="WARNING", description="Level applied to chatty third-party loggers (pymongo, urllib3, httpx, ...)")
|
|
|
|
# Checkpointing
|
|
CHECKPOINT_BACKEND: str = Field(default="memory", description="Checkpoint backend (memory or mongodb)")
|
|
MONGODB_CONNECTION_STRING: Optional[str] = Field(default=None, description="MongoDB connection string")
|
|
MONGODB_DATABASE: str = Field(default="agent_db", description="MongoDB database name")
|
|
MONGODB_COLLECTION: str = Field(default="checkpoints", description="MongoDB collection name")
|
|
|
|
# Autonomous Database / MongoDB Settings (memory cache + business data)
|
|
AUTONOMOUS_NOSQL_HOST: Optional[str] = Field(default=None, description="MongoDB host (OCI Autonomous)")
|
|
AUTONOMOUS_NOSQL_USER: Optional[str] = Field(
|
|
default=None,
|
|
description="MongoDB username (shared with TAIS via MONGODB_DB_USER alias)",
|
|
validation_alias=AliasChoices("AUTONOMOUS_NOSQL_USER", "MONGODB_DB_USER"),
|
|
)
|
|
AUTONOMOUS_NOSQL_PASSWORD: Optional[str] = Field(
|
|
default=None,
|
|
description="MongoDB password (shared with TAIS via MONGODB_DB_PASSWORD alias)",
|
|
validation_alias=AliasChoices("AUTONOMOUS_NOSQL_PASSWORD", "MONGODB_DB_PASSWORD", "MONGO_DB_PASSWORD"),
|
|
)
|
|
AUTONOMOUS_NOSQL_DB_NAME: Optional[str] = Field(default=None, description="MongoDB database name")
|
|
AUTONOMOUS_NOSQL_URL: Optional[str] = Field(default=None, description="MongoDB full connection URL (alternative to host+user+password)")
|
|
AUTONOMOUS_NOSQL_COLLECTION: str = Field(default="cases", description="Default collection for business data")
|
|
AUTONOMOUS_NOSQL_MEMORY_COLLECTION: str = Field(default="memory", description="Collection for cache/memory data")
|
|
USE_AUTONOMUS_NOSQL_LOCAL: bool = Field(default=False, description="Whether to use a local AutonomousDB instance instead of OCI Autonomous Database (for development/testing)")
|
|
|
|
# OCI Streaming settings
|
|
ENABLE_OCI_STREAMING: bool = Field(default=True, description="Whether to enable OCI Streaming consumer")
|
|
OCI_STREAM_ENDPOINT: Optional[str] = Field(default=None, description="OCI Streaming Custom Endpoint (e.g. https://10.152.97.46)")
|
|
OCI_REGION: str = Field(default="sa-saopaulo-1", description="OCI Region")
|
|
OCI_REQUEST_STREAM_OCID: Optional[str] = Field(default=None, description="OCID of the request stream")
|
|
OCI_RESPONSE_STREAM_OCID: Optional[str] = Field(default=None, description="OCID of the response stream")
|
|
OCI_CONSUMER_GROUP_NAME: str = Field(default="cg-case-process-bo-agent", description="Group name for OCI streaming consumer")
|
|
OCI_MESSAGES_LIMIT: int = Field(default=10, gt=0, description="Max messages to fetch per poll")
|
|
OCI_CONFIG_PROFILE: str = Field(default="DEFAULT", description="OCI config profile to use")
|
|
OCI_RESOLVE_TO_IP: Optional[str] = Field(default=None, description="IP to resolve the custom endpoint to")
|
|
OCI_STREAMING_SEMAPHORE_LIMIT: int = Field(default=8, gt=0, description="Max concurrent message processing (semaphore limit)")
|
|
|
|
# Response Emulator settings
|
|
EMULATOR_TEMPLATES_TOP_K: int = Field(default=5, gt=0, description="Top-K retrieved from the templates RAG in the response emulator")
|
|
EMULATOR_HISTORY_HIGH_SCORE_TOP_K: int = Field(default=5, gt=0, description="Top-K retrieved from the history RAG for the high-score bucket — positive references the model should learn from")
|
|
EMULATOR_HISTORY_LOW_SCORE_TOP_K: int = Field(default=5, gt=0, description="Top-K retrieved from the history RAG for the low-score bucket — negative examples the model must avoid imitating")
|
|
|
|
# Agent settings (optional)
|
|
AGENT_NAME: Optional[str] = Field(default=None, description="Agent name")
|
|
AGENT_DESCRIPTION: Optional[str] = Field(default=None, description="Agent description")
|
|
AGENT_SYSTEM_PROMPT: Optional[str] = Field(default=None, description="Agent system prompt")
|
|
AGENT_MAX_ITERATIONS: int = Field(default=10, gt=0, description="Max agent iterations")
|
|
AGENT_TYPE: str = Field(default="backoffice", description="Used as service.agent_type in application logs")
|
|
|
|
# IMDB API settings
|
|
PMID_API_HOST: str = Field(default="0.0.0.0", description="IMDB access host")
|
|
PMID_API_BASIC_TOKEN: str = Field(default="Basic base64_encoded_token", description="IMDB access basic token")
|
|
PMID_API_TIMEOUT: Optional[float] = Field(default=10.0, description="IMDB API timeout in seconds")
|
|
PMID_API_CLIENT_ID: str = Field(default="client_id", description="IMDB API client id")
|
|
|
|
# Siebel API settings
|
|
SIEBEL_API_HOST: Optional[str] = Field(default="https://siebel-api-url", description="Siebel API host ")
|
|
SIEBEL_API_ROUTE: str = Field(default="/customers/v1/backOfficeSRopening", description="Siebel API route (path)")
|
|
SIEBEL_API_TIMEOUT: int = Field(default=10, description="Siebel API timeout in seconds")
|
|
SIEBEL_API_USERNAME: Optional[str] = Field(default=None, description="Siebel API username")
|
|
SIEBEL_API_PASSWORD: Optional[str] = Field(default=None, description="Siebel API password")
|
|
SIEBEL_API_CLIENT_ID: Optional[str] = Field(default=None, description="Siebel API client id")
|
|
|
|
# Siebel Prospect API settings (non-TIM / canceled customers)
|
|
SIEBEL_PROSPECT_API_HOST: Optional[str] = Field(default=None, description="Siebel Prospect API host (base only)")
|
|
SIEBEL_PROSPECT_API_ROUTE: str = Field(default="", description="Siebel Prospect API route (path)")
|
|
SIEBEL_PROSPECT_API_AUTHORIZATION: Optional[str] = Field(default=None, description="Siebel Prospect API Authorization header (Basic)")
|
|
SIEBEL_PROSPECT_API_CLIENT_ID: Optional[str] = Field(default=None, description="Siebel Prospect API client id")
|
|
|
|
# Siebel SR status update (closing) settings
|
|
SIEBEL_STATUS_API_HOST: Optional[str] = Field(default=None, description="Siebel Pós-pago: host do endpoint de fechamento da SR")
|
|
SIEBEL_STATUS_API_ROUTE: str = Field(default="/interactions/v1/statusServiceRequest", description="Siebel Pós-pago: rota para fechamento da SR")
|
|
SIEBEL_PREPAGO_STATUS_API_HOST: Optional[str] = Field(default=None, description="Siebel Pré-pago: host do endpoint de fechamento")
|
|
SIEBEL_PREPAGO_STATUS_API_ROUTE: str = Field(default="/customers/v1/serviceRequest", description="Siebel Pré-pago: rota do endpoint de fechamento")
|
|
|
|
# ABRT API settings
|
|
ABRT_API_BASE_URL: str = Field(default="0.0.0.0", description="ABRT API host")
|
|
ABRT_API_AUTHORIZATION: str = Field(default="Basic <base64-credentials>", description="ABRT API Authorization header (Basic)")
|
|
ABRT_API_TOKEN: str = Field(default="token", description="ABRT API token header")
|
|
ABRT_API_TIMEOUT: Optional[float] = Field(default=10.0, description="ABRT API timeout in seconds")
|
|
ABRT_API_CLIENT_ID: str = Field(default="clientId", description="ABRT API client id")
|
|
|
|
# Portability API settings
|
|
PORTABILITY_API_URL: str = Field(default="0.0.0.0", description="Portability API URL")
|
|
PORTABILITY_API_AUTHORIZATION: str = Field(default="username", description="API basic authorization")
|
|
PORTABILITY_API_TIMEOUT: Optional[float] = Field(default=10.0, description="Portability API timeout in seconds")
|
|
PORTABILITY_API_CLIENT_ID: str = Field(default="clientId", description="Portability API client id")
|
|
|
|
# SSL
|
|
VERIFY_SSL: bool = Field(default=True, description="Verify SSL")
|
|
|
|
# Langfuse settings
|
|
USE_LANGFUSE_PROMPTS: bool = Field(default=True, description="Whether to use prompts from Langfuse")
|
|
USE_LANGFUSE_TRACING: bool = Field(default=True, description="Whether to send traces/generations to Langfuse")
|
|
LANGFUSE_PROMPTS_TTL: int = Field(default=600, description="TTL for Langfuse prompts cache in seconds")
|
|
LANGFUSE_SECRET_KEY: str | None = Field(default=None, description="Langfuse secret key", validation_alias=AliasChoices("LANGFUSE_SECRET_KEY", "langfuse_secret_key"))
|
|
LANGFUSE_PUBLIC_KEY: str | None = Field(default=None, description="Langfuse public key", validation_alias=AliasChoices("LANGFUSE_PUBLIC_KEY", "langfuse_public_key"))
|
|
LANGFUSE_BASE_URL: str | None = Field(default=None, description="Langfuse base URL", validation_alias=AliasChoices("LANGFUSE_BASE_URL", "langfuse_base_url", "LANGFUSE_HOST", "langfuse_host"))
|
|
LANGFUSE_ENVIRONMENT: str = Field(default="development", description="Langfuse tracing environment (e.g. development, staging, production)")
|
|
OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: Optional[str] = Field(
|
|
default=None,
|
|
description="Path to the PEM/CRT file with the CA bundle used to verify the Langfuse OTLP endpoint. Required in TIM environments where Langfuse is served behind an internal CA. Leave empty for local dev over plain HTTP.",
|
|
)
|
|
|
|
# Anatel Dictionary settings
|
|
USE_FULL_ANATEL_DICT: bool = Field(default=False, description="Whether to use the full Anatel motives dictionary instead of filtering by service")
|
|
|
|
# Migration control. Default False: domain nodes must use framework services/MCP/fallbacks.
|
|
BACKOFFICE_ALLOW_LEGACY_CLIENTS: bool = Field(default=False, description="Allow direct legacy TIM clients as a parity escape hatch. Keep False for framework-native execution.")
|
|
|
|
# Speech Analytics API settings
|
|
SPEECH_PREDICTION_BASE_URL: Optional[str] = Field(default=None, description="Base URL of the Speech Prediction API gateway (OAuth2 + prediction endpoint)")
|
|
SPEECH_PREDICTION_CLIENT_ID: Optional[str] = Field(default=None, description="Client ID for the Speech Prediction OAuth2 client_credentials flow")
|
|
SPEECH_PREDICTION_CLIENT_SECRET: Optional[str] = Field(default=None, description="Client Secret for the Speech Prediction OAuth2 client_credentials flow")
|
|
SPEECH_HISTORY_BASE_URL: Optional[str] = Field(default=None, description="Base URL of the Speech History API (audio-toxico)")
|
|
SPEECH_HISTORY_AUDIENCE: Optional[str] = Field(default=None, description="Google ID Token target audience for the Speech History API")
|
|
SPEECH_HISTORY_HOST: Optional[str] = Field(default=None, description="Host header value for the Speech History API when calling via internal IP")
|
|
SPEECH_TIMEOUT: float = Field(default=10.0, description="Timeout in seconds shared by both Speech API calls (prediction and history)")
|
|
SPEECH_SIMILARITY_THRESHOLD: int = Field(default=70, ge=0, le=100, description="Minimum LLM-judged similarity percent (0-100) for a historical complaint to appear in historico_relacionado")
|
|
|
|
# TAIS Knowledge Base settings
|
|
MONGODB_DB_USER: Optional[str] = Field(
|
|
default=None,
|
|
description="Oracle ADB user for TAIS knowledge base (shares Mongo credentials)",
|
|
validation_alias=AliasChoices("MONGODB_DB_USER", "TAIS_DB_USER"),
|
|
)
|
|
MONGODB_DB_PASSWORD: Optional[str] = Field(
|
|
default=None,
|
|
description="Oracle ADB password for TAIS knowledge base (shares Mongo credentials)",
|
|
validation_alias=AliasChoices("MONGODB_DB_PASSWORD", "TAIS_DB_PASSWORD", "MONGO_DB_PASSWORD"),
|
|
)
|
|
TAIS_DB_DSN: Optional[str] = Field(default=None, description="Oracle ADB DSN for TAIS knowledge base")
|
|
TAIS_DB_TIMEOUT: float = Field(default=30.0, description="Timeout in seconds for TAIS DB connection and OCI GenAI embedding calls")
|
|
TAIS_GENAI_ENDPOINT: Optional[str] = Field(default=None, description="OCI GenAI endpoint used for embeddings")
|
|
TAIS_GENAI_COMPARTMENT_ID: Optional[str] = Field(default=None, description="OCI compartment OCID used for embeddings")
|
|
TAIS_GENAI_EMBED_MODEL_ID: str = Field(default="cohere.embed-multilingual-v3.0", description="OCI GenAI embedding model id")
|
|
TAIS_TABLE_CHUNKS: str = Field(default="CHUNKS_CHAR_COHERE_3", description="Oracle table containing TAIS chunks + embeddings")
|
|
TAIS_TABLE_FILES: str = Field(default="files_oci", description="Oracle table containing TAIS raw documents")
|
|
TAIS_TOP_K: int = Field(default=3, gt=0, description="Number of unique documents returned by TAIS KB search")
|
|
TAIS_KB_LLM_MODEL: str = Field(default="openai.gpt-4.1", description="Modelo LLM framework para pós-processamento da KB")
|
|
TAIS_KB_LLM_TEMPERATURE: float = Field(default=0.3, ge=0.0, le=2.0)
|
|
TAIS_KB_LLM_MAX_TOKENS: int = Field(default=4096, gt=0, description="Tokens de saída — manter alto para respostas completas")
|
|
TAIS_KB_LLM_TOP_P: float = Field(default=0.9)
|
|
TAIS_KB_LLM_TOP_K: float = Field(default=250)
|
|
TAIS_KB_USE_SPEECH_SUMMARY: bool = Field(default=False, description="Se True, usa speech.reclamacao_resumo como query; se False, usa complaint.description")
|
|
TAIS_KB_PREPROCESS: bool = Field(default=False, description="Pré-processa a query com LLM antes do embedding")
|
|
TAIS_KB_POSTPROCESS: bool = Field(default=True, description="Pós-processa resultados com LLM para síntese")
|
|
|
|
# Emulator RAG (Oracle ADB + OCI Cohere embeddings). DB credentials reuse the TAIS settings.
|
|
EMULATOR_RAG_OCI_GENAI_ENDPOINT: Optional[str] = Field(default=None, description="OCI GenAI endpoint for emulator RAG embeddings")
|
|
EMULATOR_RAG_COMPARTMENT_ID: Optional[str] = Field(default=None, description="OCI compartment OCID for emulator RAG embeddings")
|
|
EMULATOR_RAG_EMBED_MODEL_ID: str = Field(default="cohere.embed-multilingual-v3.0", description="OCI GenAI embedding model for emulator RAG")
|
|
EMULATOR_RAG_TEMPLATES_CHUNKS: str = Field(default="TEMPLATES_COHERE_3", description="Oracle table with templates chunks + embeddings")
|
|
EMULATOR_RAG_ANATEL_NOTAS_RESPOSTA_CHUNKS: str = Field(default="ANATEL_NOTAS_CHUNKS_RESPOSTA_COHERE_3", description="Oracle table with approved Anatel response chunks + embeddings")
|
|
EMULATOR_RAG_TOP_K: int = Field(default=5, gt=0, description="Default top-k used by the QA /emulator-rag/search route")
|
|
EMULATOR_RAG_HISTORY_HIGH_SCORE_THRESHOLD: int = Field(default=4, ge=0, le=5, description="High-score filter for the history RAG (anatel_resposta): chunks with `nota >= threshold` are retrieved as positive references")
|
|
EMULATOR_RAG_HISTORY_LOW_SCORE_THRESHOLD: int = Field(default=2, ge=0, le=5, description="Low-score filter for the history RAG (anatel_resposta): chunks with `nota <= threshold` are retrieved as negative examples the model must avoid imitating")
|
|
EMULATOR_RAG_ALLOW_MOCK_FALLBACK: bool = Field(default=False, description="LOCAL DEV ONLY: when true, RAG wrappers fall back to JSON mocks if the real backend is unset or fails. Must remain false in any shared environment (dev kube, fqa, prod) to avoid silent mock responses.")
|
|
|
|
model_config = {
|
|
"env_file": ".env",
|
|
"case_sensitive": False,
|
|
"extra": "ignore"
|
|
}
|
|
|
|
@field_validator('LLM_PROVIDER')
|
|
@classmethod
|
|
def validate_llm_provider(cls, v: str) -> str:
|
|
"""Validate that LLM provider is supported."""
|
|
supported = ['openai', 'anthropic', 'oci_openai', 'oci', 'mock']
|
|
if v not in supported:
|
|
raise ValueError(f"LLM_PROVIDER must be one of {supported}, got: {v}")
|
|
return v
|
|
|
|
@field_validator('LOG_LEVEL')
|
|
@classmethod
|
|
def validate_log_level(cls, v: str) -> str:
|
|
"""Validate log level."""
|
|
valid_levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
|
|
v_upper = v.upper()
|
|
if v_upper not in valid_levels:
|
|
raise ValueError(f"LOG_LEVEL must be one of {valid_levels}, got: {v}")
|
|
return v_upper
|
|
|
|
@field_validator('LOG_FORMAT')
|
|
@classmethod
|
|
def validate_log_format(cls, v: str) -> str:
|
|
"""Validate log format."""
|
|
valid_formats = ['json', 'text']
|
|
v_lower = v.lower()
|
|
if v_lower not in valid_formats:
|
|
raise ValueError(f"LOG_FORMAT must be one of {valid_formats}, got: {v}")
|
|
return v_lower
|
|
|
|
@classmethod
|
|
def from_yaml(cls, path: str) -> "Settings":
|
|
"""
|
|
Load settings from a YAML file.
|
|
|
|
Args:
|
|
path: Path to the YAML configuration file
|
|
|
|
Returns:
|
|
Settings instance with values loaded from YAML
|
|
|
|
Raises:
|
|
FileNotFoundError: If the YAML file doesn't exist
|
|
yaml.YAMLError: If the YAML file is malformed
|
|
ValueError: If required fields are missing or invalid
|
|
"""
|
|
with open(path, 'r') as f:
|
|
config_dict = yaml.safe_load(f)
|
|
|
|
if config_dict is None:
|
|
config_dict = {}
|
|
|
|
return cls(**config_dict)
|
|
|
|
def to_llm_config(self) -> LLMConfig:
|
|
"""
|
|
Convert settings to LLMConfig model.
|
|
|
|
Returns:
|
|
LLMConfig instance with LLM-specific settings
|
|
"""
|
|
return LLMConfig(
|
|
provider=self.LLM_PROVIDER,
|
|
model=self.LLM_MODEL,
|
|
temperature=self.LLM_TEMPERATURE,
|
|
max_tokens=self.LLM_MAX_TOKENS
|
|
)
|
|
|
|
def to_agent_config(self) -> Optional[AgentConfig]:
|
|
"""
|
|
Convert settings to AgentConfig model if agent settings are present.
|
|
|
|
Returns:
|
|
AgentConfig instance if all required fields are present, None otherwise
|
|
"""
|
|
if not all([self.AGENT_NAME, self.AGENT_DESCRIPTION, self.AGENT_SYSTEM_PROMPT]):
|
|
return None
|
|
|
|
return AgentConfig(
|
|
name=self.AGENT_NAME,
|
|
description=self.AGENT_DESCRIPTION,
|
|
system_prompt=self.AGENT_SYSTEM_PROMPT,
|
|
tools=[], # Tools would be configured separately
|
|
max_iterations=self.AGENT_MAX_ITERATIONS
|
|
)
|
|
|
|
def setup_langfuse(self):
|
|
"""
|
|
Export Langfuse settings to environment variables.
|
|
Many libraries (like the Langfuse client and agent-framework) expect these
|
|
to be present in os.environ for authentication.
|
|
"""
|
|
if self.LANGFUSE_PUBLIC_KEY:
|
|
os.environ["LANGFUSE_PUBLIC_KEY"] = self.LANGFUSE_PUBLIC_KEY
|
|
|
|
if self.LANGFUSE_SECRET_KEY:
|
|
os.environ["LANGFUSE_SECRET_KEY"] = self.LANGFUSE_SECRET_KEY
|
|
|
|
if self.LANGFUSE_BASE_URL:
|
|
# Ensure protocol is present
|
|
url = self.LANGFUSE_BASE_URL
|
|
if url and not url.startswith(("http://", "https://")):
|
|
url = f"https://{url}" # Default to https if missing
|
|
|
|
os.environ["LANGFUSE_BASE_URL"] = url
|
|
os.environ["LANGFUSE_HOST"] = url
|
|
|
|
os.environ["LANGFUSE_TRACING_ENVIRONMENT"] = self.LANGFUSE_ENVIRONMENT
|
|
|
|
|
|
# Global settings instance
|
|
settings = Settings()
|
|
settings.setup_langfuse()
|