Update app/services/outcome_service.py
Browse files- app/services/outcome_service.py +29 -26
app/services/outcome_service.py
CHANGED
|
@@ -4,15 +4,31 @@ from typing import Optional, Dict, Any
|
|
| 4 |
|
| 5 |
from sqlalchemy.orm import Session
|
| 6 |
|
| 7 |
-
from agentic_reliability_framework.core.governance.risk_engine import RiskEngine
|
| 8 |
-
from agentic_reliability_framework.core.governance.intents import (
|
| 9 |
-
InfrastructureIntent,
|
| 10 |
-
ProvisionResourceIntent,
|
| 11 |
-
GrantAccessIntent,
|
| 12 |
-
DeployConfigurationIntent,
|
| 13 |
-
)
|
| 14 |
from app.database.models_intents import IntentDB, OutcomeDB
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
logger = logging.getLogger(__name__)
|
| 17 |
|
| 18 |
|
|
@@ -20,7 +36,7 @@ class OutcomeConflictError(Exception):
|
|
| 20 |
pass
|
| 21 |
|
| 22 |
|
| 23 |
-
def reconstruct_oss_intent_from_json(oss_json: Dict[str, Any])
|
| 24 |
intent_type = oss_json.get("intent_type")
|
| 25 |
if intent_type == "provision_resource":
|
| 26 |
return ProvisionResourceIntent(**oss_json)
|
|
@@ -34,20 +50,13 @@ def reconstruct_oss_intent_from_json(oss_json: Dict[str, Any]) -> Infrastructure
|
|
| 34 |
)
|
| 35 |
|
| 36 |
|
| 37 |
-
def _create_dummy_intent(intent_type: str)
|
| 38 |
-
"""Create a valid dummy intent for a given intent type.
|
| 39 |
-
For now, only ProvisionResourceIntent is fully supported.
|
| 40 |
-
"""
|
| 41 |
-
from agentic_reliability_framework.core.governance.intents import (
|
| 42 |
-
ProvisionResourceIntent,
|
| 43 |
-
)
|
| 44 |
if intent_type == "ProvisionResourceIntent":
|
| 45 |
-
# Use string values directly; they must be valid according to the model
|
| 46 |
return ProvisionResourceIntent(
|
| 47 |
resource_type="vm",
|
| 48 |
region="eastus",
|
| 49 |
size="Standard_D2s_v3",
|
| 50 |
-
environment="dev",
|
| 51 |
requester="system"
|
| 52 |
)
|
| 53 |
else:
|
|
@@ -78,13 +87,13 @@ def record_outcome(
|
|
| 78 |
success=bool(success),
|
| 79 |
recorded_by=recorded_by,
|
| 80 |
notes=notes,
|
| 81 |
-
recorded_at=datetime.datetime.utcnow()
|
| 82 |
)
|
| 83 |
db.add(outcome)
|
| 84 |
db.commit()
|
| 85 |
db.refresh(outcome)
|
| 86 |
|
| 87 |
-
#
|
| 88 |
oss_intent = None
|
| 89 |
if intent.oss_payload:
|
| 90 |
try:
|
|
@@ -98,7 +107,6 @@ def record_outcome(
|
|
| 98 |
else:
|
| 99 |
oss_intent = _create_dummy_intent(intent.intent_type)
|
| 100 |
|
| 101 |
-
# Update risk engine if we have an intent
|
| 102 |
if oss_intent is not None:
|
| 103 |
try:
|
| 104 |
risk_engine.update_outcome(oss_intent, success)
|
|
@@ -107,10 +115,5 @@ def record_outcome(
|
|
| 107 |
"Failed to update RiskEngine after recording outcome for intent %s: %s",
|
| 108 |
deterministic_id, e
|
| 109 |
)
|
| 110 |
-
else:
|
| 111 |
-
logger.error(
|
| 112 |
-
"No valid OSS intent available for risk engine update; skipping outcome for %s",
|
| 113 |
-
deterministic_id
|
| 114 |
-
)
|
| 115 |
|
| 116 |
-
return outcome
|
|
|
|
| 4 |
|
| 5 |
from sqlalchemy.orm import Session
|
| 6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
from app.database.models_intents import IntentDB, OutcomeDB
|
| 8 |
|
| 9 |
+
# ---------------------------------------------------------------------------
|
| 10 |
+
# Local fallback types – dummy RiskEngine and intent classes
|
| 11 |
+
# ---------------------------------------------------------------------------
|
| 12 |
+
class RiskEngine:
|
| 13 |
+
def update_outcome(self, intent, success):
|
| 14 |
+
pass
|
| 15 |
+
|
| 16 |
+
class ProvisionResourceIntent:
|
| 17 |
+
def __init__(self, **kwargs):
|
| 18 |
+
for k, v in kwargs.items():
|
| 19 |
+
setattr(self, k, v)
|
| 20 |
+
|
| 21 |
+
class GrantAccessIntent:
|
| 22 |
+
def __init__(self, **kwargs):
|
| 23 |
+
for k, v in kwargs.items():
|
| 24 |
+
setattr(self, k, v)
|
| 25 |
+
|
| 26 |
+
class DeployConfigurationIntent:
|
| 27 |
+
def __init__(self, **kwargs):
|
| 28 |
+
for k, v in kwargs.items():
|
| 29 |
+
setattr(self, k, v)
|
| 30 |
+
# ---------------------------------------------------------------------------
|
| 31 |
+
|
| 32 |
logger = logging.getLogger(__name__)
|
| 33 |
|
| 34 |
|
|
|
|
| 36 |
pass
|
| 37 |
|
| 38 |
|
| 39 |
+
def reconstruct_oss_intent_from_json(oss_json: Dict[str, Any]):
|
| 40 |
intent_type = oss_json.get("intent_type")
|
| 41 |
if intent_type == "provision_resource":
|
| 42 |
return ProvisionResourceIntent(**oss_json)
|
|
|
|
| 50 |
)
|
| 51 |
|
| 52 |
|
| 53 |
+
def _create_dummy_intent(intent_type: str):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
if intent_type == "ProvisionResourceIntent":
|
|
|
|
| 55 |
return ProvisionResourceIntent(
|
| 56 |
resource_type="vm",
|
| 57 |
region="eastus",
|
| 58 |
size="Standard_D2s_v3",
|
| 59 |
+
environment="dev",
|
| 60 |
requester="system"
|
| 61 |
)
|
| 62 |
else:
|
|
|
|
| 87 |
success=bool(success),
|
| 88 |
recorded_by=recorded_by,
|
| 89 |
notes=notes,
|
| 90 |
+
recorded_at=datetime.datetime.utcnow()
|
| 91 |
)
|
| 92 |
db.add(outcome)
|
| 93 |
db.commit()
|
| 94 |
db.refresh(outcome)
|
| 95 |
|
| 96 |
+
# Reconstruct intent and update risk engine (mock)
|
| 97 |
oss_intent = None
|
| 98 |
if intent.oss_payload:
|
| 99 |
try:
|
|
|
|
| 107 |
else:
|
| 108 |
oss_intent = _create_dummy_intent(intent.intent_type)
|
| 109 |
|
|
|
|
| 110 |
if oss_intent is not None:
|
| 111 |
try:
|
| 112 |
risk_engine.update_outcome(oss_intent, success)
|
|
|
|
| 115 |
"Failed to update RiskEngine after recording outcome for intent %s: %s",
|
| 116 |
deterministic_id, e
|
| 117 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
|
| 119 |
+
return outcome
|