ci / test (push) Successful in 27s
- ontology/know.yaml: 49 Klassen, 66 Beziehungen, 12 Vokabulare (72 Konzepte); erzeugt: know.ttl (OWL + SKOS), Ansicht aus viewer.html.tmpl - knaster.ontology: Modell + Prüfung, Export, Momentaufnahme der n8n-Workflows (nur GET; KNOW-Spezifikation aus dem Workflow-Code, Aufrufe inkl. Laufzeit- Operationen, direktes SQL), Abgleich, Übernahme von Entscheidungen - Service-Routine Schritt 8: Verstöße als Befunde, Ontologie-Änderungen als Vorschläge ontology_change (immer Freigabe); „ordne P-x <konzept> zu“; Entscheidungen in ontology_decisions, `knaster ontology apply` schreibt sie in die YAML (Version +1) - CLI: knaster ontology validate|export|snapshot|check|apply; knaster validate prüft Modell und Aktualität der Turtle-Datei - Gegen echten n8n-Export geprüft: neue Befunde B31–B33 (verified/confirmed, KAN ruft unbekannte Operation, MPA ordnet Projektereignisse nie ein) - SPEC-ontology, BETRIEB §6, Router-Image enthält die Ontologie Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
3.4 KiB
Python
77 lines
3.4 KiB
Python
"""Konfiguration aus Umgebungsvariablen."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from dataclasses import dataclass, field
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[3]
|
|
|
|
|
|
def _bool(value: str | None, default: bool) -> bool:
|
|
if value is None:
|
|
return default
|
|
return value.strip().lower() in {"1", "true", "yes", "ja", "on"}
|
|
|
|
|
|
@dataclass
|
|
class Settings:
|
|
api_token: str = ""
|
|
db_url: str = "sqlite:///data/knaster.db"
|
|
site_dir: Path = field(default_factory=lambda: REPO_ROOT / "sites" / "knaster")
|
|
skills_dir: Path = field(default_factory=lambda: REPO_ROOT / "skills")
|
|
config_dir: Path = field(default_factory=lambda: REPO_ROOT / "config")
|
|
dry_run: bool = True
|
|
litellm_base_url: str = "http://litellm:4000"
|
|
litellm_api_key: str = ""
|
|
embed_model: str = "embed-default"
|
|
rerank_url: str = ""
|
|
rerank_model: str = "rerank-default"
|
|
portainer_host: str = ""
|
|
portainer_key: str = ""
|
|
proxmox_url: str = ""
|
|
proxmox_token_id: str = ""
|
|
proxmox_token_secret: str = ""
|
|
notify_webhook_url: str = ""
|
|
job_webhook_url: str = ""
|
|
webhook_auth: str = "" # Wert des Authorization-Headers für ausgehende Webhooks (n8n Header Auth)
|
|
request_timeout: float = 120.0
|
|
canary_interval: float = 60.0 # 0 = Prober aus
|
|
ontology_path: Path = field(default_factory=lambda: REPO_ROOT / "ontology" / "know.yaml")
|
|
ontology_snapshot: str = "" # Datei mit n8n-Workflows (JSON) statt Live-Abruf, z. B. für Tests/offline
|
|
n8n_host: str = "" # nur lesend: GET /api/v1/workflows für den Ontologie-Abgleich
|
|
n8n_api_key: str = ""
|
|
|
|
@classmethod
|
|
def from_env(cls) -> Settings:
|
|
env = os.environ
|
|
base = cls()
|
|
return cls(
|
|
api_token=env.get("KNASTER_API_TOKEN", base.api_token),
|
|
db_url=env.get("KNASTER_DB_URL", base.db_url),
|
|
site_dir=Path(env.get("KNASTER_SITE_DIR", base.site_dir)),
|
|
skills_dir=Path(env.get("KNASTER_SKILLS_DIR", base.skills_dir)),
|
|
config_dir=Path(env.get("KNASTER_CONFIG_DIR", base.config_dir)),
|
|
dry_run=_bool(env.get("KNASTER_DRY_RUN"), True),
|
|
litellm_base_url=env.get("LITELLM_BASE_URL", base.litellm_base_url),
|
|
litellm_api_key=env.get("LITELLM_API_KEY", base.litellm_api_key),
|
|
embed_model=env.get("KNASTER_EMBED_MODEL", base.embed_model),
|
|
rerank_url=env.get("RERANK_URL", base.rerank_url),
|
|
rerank_model=env.get("KNASTER_RERANK_MODEL", base.rerank_model),
|
|
portainer_host=env.get("PORTAINER_HOST", ""),
|
|
portainer_key=env.get("PORTAINER_KEY", ""),
|
|
proxmox_url=env.get("PROXMOX_URL", ""),
|
|
proxmox_token_id=env.get("PROXMOX_TOKEN_ID", ""),
|
|
proxmox_token_secret=env.get("PROXMOX_TOKEN_SECRET", ""),
|
|
notify_webhook_url=env.get("NOTIFY_WEBHOOK_URL", ""),
|
|
job_webhook_url=env.get("KNASTER_JOB_WEBHOOK_URL", ""),
|
|
webhook_auth=env.get("KNASTER_WEBHOOK_AUTH", ""),
|
|
request_timeout=float(env.get("KNASTER_REQUEST_TIMEOUT", base.request_timeout)),
|
|
canary_interval=float(env.get("KNASTER_CANARY_INTERVAL", base.canary_interval)),
|
|
ontology_path=Path(env.get("KNASTER_ONTOLOGY", base.ontology_path)),
|
|
ontology_snapshot=env.get("KNASTER_ONTOLOGY_SNAPSHOT", ""),
|
|
n8n_host=env.get("N8N_HOST", ""),
|
|
n8n_api_key=env.get("N8N_API_KEY", ""),
|
|
)
|