File size: 3,604 Bytes
2d521fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import sys
from app.database.session import SessionLocal
from slowapi import Limiter
from slowapi.util import get_remote_address
from app.core.config import settings

# ARF core engine imports
from agentic_reliability_framework.core.governance.risk_engine import RiskEngine
from agentic_reliability_framework.core.decision.decision_engine import DecisionEngine
from agentic_reliability_framework.core.governance.stability_controller import LyapunovStabilityController
from agentic_reliability_framework.core.governance.causal_explainer import CausalExplainer
from agentic_reliability_framework.runtime.memory.rag_graph import RAGGraphMemory
from agentic_reliability_framework.core.models.event import ReliabilityEvent, HealingAction


# Dependency to get DB session
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


# Rate limiter with default limit from settings
limiter = Limiter(key_func=get_remote_address, default_limits=[settings.RATE_LIMIT])


# ARF engine dependencies (singletons for simplicity)
_risk_engine = None
_decision_engine = None
_stability_controller = None
_causal_explainer = None
_rag_graph = None


def _seed_rag_graph(rag):
    """Seed the RAG graph with historical healing action outcomes."""
    seed_data = [
        ("seed_restart_1", "test", HealingAction.RESTART_CONTAINER.value, True, 2),
        ("seed_restart_2", "test", HealingAction.RESTART_CONTAINER.value, True, 3),
        ("seed_restart_3", "test", HealingAction.RESTART_CONTAINER.value, False, 10),
        ("seed_rollback_1", "test", HealingAction.ROLLBACK.value, True, 1),
        ("seed_rollback_2", "test", HealingAction.ROLLBACK.value, True, 2),
        ("seed_rollback_3", "test", HealingAction.ROLLBACK.value, False, 5),
        ("seed_scale_1", "test", HealingAction.SCALE_OUT.value, True, 5),
        ("seed_scale_2", "test", HealingAction.SCALE_OUT.value, False, 15),
        ("seed_cb_1", "test", HealingAction.CIRCUIT_BREAKER.value, True, 1),
        ("seed_cb_2", "test", HealingAction.CIRCUIT_BREAKER.value, True, 2),
        ("seed_ts_1", "test", HealingAction.TRAFFIC_SHIFT.value, True, 4),
        ("seed_ts_2", "test", HealingAction.TRAFFIC_SHIFT.value, False, 8),
    ]
    for inc_id, comp, action, success, res_time in seed_data:
        event = ReliabilityEvent(
            component=comp,
            latency_p99=500,
            error_rate=0.1,
            service_mesh="default"
        )
        rag.record_outcome(
            incident_id=inc_id,
            event=event,
            action_taken=action,
            success=success,
            resolution_time_minutes=res_time
        )
    print("Seeded RAG graph with historical data", file=sys.stderr)


def get_rag_graph():
    global _rag_graph
    if _rag_graph is None:
        _rag_graph = RAGGraphMemory()
        _seed_rag_graph(_rag_graph)
    return _rag_graph


def get_decision_engine():
    global _decision_engine
    if _decision_engine is None:
        rag = get_rag_graph()
        _decision_engine = DecisionEngine(rag_graph=rag)
    return _decision_engine


def get_risk_engine():
    global _risk_engine
    if _risk_engine is None:
        _risk_engine = RiskEngine()
    return _risk_engine


def get_stability_controller():
    global _stability_controller
    if _stability_controller is None:
        _stability_controller = LyapunovStabilityController()
    return _stability_controller


def get_causal_explainer():
    global _causal_explainer
    if _causal_explainer is None:
        _causal_explainer = CausalExplainer()
    return _causal_explainer