- Added configuration options for requiring human approval before applying LLM-generated MCP patches. - Updated Docker setup to include skills directory. - Integrated skills management into the backend, allowing for procedural guides and skill matching. - Refactored database initialization to apply Alembic migrations. - Enhanced task approval process to handle MCP patch applications with optional approval. - Introduced new schemas for skills and updated existing APIs to support skills functionality. This commit lays the groundwork for improved agent capabilities and better management of MCP development processes.
122 lines
4.5 KiB
Python
122 lines
4.5 KiB
Python
"""Application configuration, loaded from environment variables."""
|
|
from __future__ import annotations
|
|
|
|
from functools import lru_cache
|
|
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(env_file=".env", extra="ignore", case_sensitive=False)
|
|
|
|
# Core security
|
|
secret_key: str = "dev-insecure-secret-change-me"
|
|
credential_encryption_key: str = ""
|
|
access_token_expire_minutes: int = 60 * 12
|
|
algorithm: str = "HS256"
|
|
|
|
first_admin_email: str = "admin@agentic.local"
|
|
first_admin_password: str = "changeme"
|
|
|
|
# Database / cache
|
|
database_url: str = "postgresql+asyncpg://agentic:agentic@postgres:5432/agentic_os"
|
|
redis_url: str = "redis://redis:6379/0"
|
|
|
|
# CORS: comma-separated allowed browser origins (no wildcard with credentials).
|
|
cors_allow_origins: str = "http://localhost:3000"
|
|
|
|
# LLM routing
|
|
litellm_base_url: str = "http://litellm:4000"
|
|
litellm_master_key: str = "sk-litellm-master-change-me"
|
|
ollama_base_url: str = "http://host.docker.internal:11434"
|
|
local_triage_model: str = "qwen2.5:7b-instruct"
|
|
cloud_reasoning_model: str = "openrouter/deepseek/deepseek-chat"
|
|
|
|
# Tiered LLM routing (local → gemini → deepseek → openrouter)
|
|
llm_local_model: str = "qwen2.5:7b-instruct"
|
|
llm_economy_gemini: str = "gemini-2.5-flash"
|
|
llm_economy_deepseek: str = "deepseek-chat"
|
|
llm_economy_openrouter: str = "deepseek/deepseek-chat"
|
|
llm_premium_gemini: str = "gemini-2.5-pro"
|
|
llm_premium_deepseek: str = "deepseek-reasoner"
|
|
llm_premium_openrouter: str = "anthropic/claude-3.5-sonnet"
|
|
llm_auto_escalate: bool = True
|
|
llm_max_tier: str = "premium"
|
|
llm_cloud_provider_order: str = "gemini,deepseek,openrouter"
|
|
|
|
# Cloud API keys
|
|
gemini_api_key: str = ""
|
|
openrouter_api_key: str = ""
|
|
openrouter_provisioning_key: str = ""
|
|
deepseek_api_key: str = ""
|
|
|
|
# Balance polling
|
|
balance_poll_interval_seconds: int = 900
|
|
min_balance_usd: float = 1.0
|
|
|
|
# Gitea / MCP repos
|
|
gitea_base_url: str = "http://10.77.30.250:3000"
|
|
gitea_username: str = "nearxos"
|
|
gitea_token: str = ""
|
|
mcp_repos: str = "ssh-generic-mcp,fortigate-mcp,fortiswitch-mcp,pfsense-mcp,proxmox-mcp,asterisk-mcp"
|
|
|
|
# Obsidian
|
|
obsidian_vault_repo: str = "homelab-vault"
|
|
obsidian_tasks_folder: str = "agentic-os-tasks"
|
|
obsidian_auto_push: bool = True
|
|
|
|
# Project memory MCP
|
|
memory_mcp_url: str = "http://10.77.30.184:8787/mcp"
|
|
memory_mcp_token: str = ""
|
|
memory_task_project_id: str = "agentic-os-task"
|
|
memory_search_projects: str = "agentic-os-task,agentic-os,global"
|
|
obsidian_search_paths: str = "agentic-os-tasks,Meta/Agent-Memory"
|
|
|
|
# Troubleshooting decision rules (YAML, editable via Admin → Rules)
|
|
troubleshooting_rules_path: str = "/app/rules/troubleshooting.yaml"
|
|
|
|
# Agent skills (procedural guides in skills/*/SKILL.md)
|
|
skills_path: str = "/app/skills"
|
|
skills_max_matched: int = 2
|
|
skills_max_body_chars: int = 8000
|
|
|
|
# Runtime paths (inside container)
|
|
runtime_dir: str = "/runtime"
|
|
|
|
# MCP self-development: agent patches MCP source on tool failure / missing capability
|
|
mcp_development_enabled: bool = True
|
|
mcp_dev_require_approval: bool = True # when true, apply/reload waits for human approval
|
|
mcp_dev_auto_push: bool = False # when false, patch applies + reload; git push needs approval
|
|
mcp_dev_model_tier: str = "premium"
|
|
|
|
# Worker: max tasks executed in parallel (MCP sessions are shared — use 1 for same-vessel safety)
|
|
worker_max_concurrent_tasks: int = 1
|
|
|
|
@property
|
|
def cors_origin_list(self) -> list[str]:
|
|
return [o.strip() for o in self.cors_allow_origins.split(",") if o.strip()]
|
|
|
|
@property
|
|
def mcp_repo_list(self) -> list[str]:
|
|
return [r.strip() for r in self.mcp_repos.split(",") if r.strip()]
|
|
|
|
def gitea_clone_url(self, repo: str) -> str:
|
|
"""Authenticated clone URL for a Gitea repo (preserves http/https from base URL)."""
|
|
base = self.gitea_base_url.rstrip("/")
|
|
if self.gitea_token:
|
|
from urllib.parse import urlparse
|
|
|
|
parsed = urlparse(base if "://" in base else f"http://{base}")
|
|
scheme = parsed.scheme or "http"
|
|
host = parsed.netloc or parsed.path
|
|
return f"{scheme}://{self.gitea_username}:{self.gitea_token}@{host}/{self.gitea_username}/{repo}.git"
|
|
return f"{base}/{self.gitea_username}/{repo}.git"
|
|
|
|
|
|
@lru_cache
|
|
def get_settings() -> Settings:
|
|
return Settings()
|
|
|
|
|
|
settings = get_settings()
|