105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
"""Application configuration via environment variables."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pydantic_settings import BaseSettings
|
|
from pydantic import Field
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
# --- Service ---
|
|
service_name: str = "agentic-microservice"
|
|
service_version: str = "1.0.0"
|
|
host: str = "0.0.0.0"
|
|
port: int = 8000
|
|
debug: bool = False
|
|
|
|
# --- Redis ---
|
|
redis_host: str = "localhost"
|
|
redis_port: int = 6379
|
|
redis_db: int = 0
|
|
redis_password: str = ""
|
|
redis_key_prefix: str = "agentic"
|
|
session_ttl_seconds: int = 86400 # 24h
|
|
|
|
@property
|
|
def redis_url(self) -> str:
|
|
auth = f":{self.redis_password}@" if self.redis_password else ""
|
|
return f"redis://{auth}{self.redis_host}:{self.redis_port}/{self.redis_db}"
|
|
|
|
# --- Model providers ---
|
|
anthropic_api_key: str = ""
|
|
anthropic_base_url: str = "" # Custom base URL (for MiniMax Anthropic-compatible, etc.)
|
|
openai_api_key: str = ""
|
|
openai_base_url: str = "" # Custom base URL (for MiniMax, DeepInfra, etc.)
|
|
default_model_provider: str = "claude"
|
|
default_model_id: str = "claude-sonnet-4-20250514"
|
|
max_tokens: int = 4096
|
|
temperature: float = 0.3
|
|
|
|
# --- Context engine ---
|
|
model_context_window: int = 0 # 0 = use legacy fixed budget / explicit override
|
|
model_max_output_tokens: int = 4096
|
|
context_max_tokens: int = 0 # 0 = auto-budget from model window, fallback legacy 120k
|
|
compaction_threshold_tokens: int = 0 # 0 = derive from ratio
|
|
compaction_threshold_ratio: float = 0.80
|
|
context_reserve_ratio: float = 0.10
|
|
artifact_summary_max_chars: int = 2000
|
|
knowledge_base_max_tokens: int = 30_000
|
|
working_context_max_items: int = 20
|
|
tool_raw_output_max_chars: int = 2000
|
|
conversation_recent_raw_limit: int = 2
|
|
task_history_max_entries: int = 20
|
|
task_history_max_tokens: int = 1500
|
|
|
|
# --- MCP ---
|
|
mcp_config_path: str = "" # Path to mcp.json; empty = legacy single-server mode
|
|
mcp_server_command: str = "" # Legacy: single server command
|
|
mcp_server_args: list[str] = Field(default_factory=list)
|
|
mcp_timeout_seconds: float = 30.0
|
|
mcp_startup_timeout_seconds: float = 10.0
|
|
|
|
# --- Pricing (per 1M tokens) ---
|
|
cost_per_1m_input: float = 2.50
|
|
cost_per_1m_output: float = 15.00
|
|
|
|
# --- Orchestrator ---
|
|
max_execution_steps: int = 25
|
|
subagent_max_steps: int = 30
|
|
max_execution_timeout_seconds: float = 300.0 # 5 min global timeout
|
|
|
|
# --- SSE ---
|
|
sse_keepalive_seconds: float = 15.0
|
|
|
|
model_config = {"env_prefix": "AGENTIC_", "env_file": ".env", "extra": "ignore"}
|
|
|
|
@property
|
|
def reserve_tokens(self) -> int:
|
|
if self.model_context_window <= 0:
|
|
return 0
|
|
return max(0, int(self.model_context_window * self.context_reserve_ratio))
|
|
|
|
@property
|
|
def effective_context_budget(self) -> int:
|
|
if self.context_max_tokens > 0:
|
|
return self.context_max_tokens
|
|
|
|
if self.model_context_window > 0:
|
|
budget = (
|
|
self.model_context_window
|
|
- max(0, self.model_max_output_tokens)
|
|
- self.reserve_tokens
|
|
)
|
|
return max(1, budget)
|
|
|
|
return 120_000
|
|
|
|
@property
|
|
def effective_compaction_threshold(self) -> int:
|
|
if self.compaction_threshold_tokens > 0:
|
|
return min(self.compaction_threshold_tokens, self.effective_context_budget)
|
|
return max(1, int(self.effective_context_budget * self.compaction_threshold_ratio))
|
|
|
|
|
|
settings = Settings()
|