Files
Agentic-OS/backend/app/config.py
nearxos 0375b20bb4 Enhance MCP development features and introduce skills management
- 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.
2026-06-14 22:27:24 +03:00

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()