46 lines
1.7 KiB
Python
46 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
import copy
|
|
import json
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List
|
|
|
|
from .models import LocalProblem, PlanDelta
|
|
|
|
|
|
class OfflineEngine:
|
|
def __init__(self) -> None:
|
|
# Simple in-memory stores; in production these would be persistent DB tables
|
|
self.local_problems: Dict[str, LocalProblem] = {}
|
|
self.local_deltas: List[PlanDelta] = []
|
|
self.central_state: Dict[str, Any] = {"execution_log": []}
|
|
|
|
# Local problem management
|
|
def add_local_problem(self, problem: LocalProblem) -> None:
|
|
self.local_problems[problem.id] = problem
|
|
|
|
def list_local_problems(self) -> List[LocalProblem]:
|
|
return list(self.local_problems.values())
|
|
|
|
# Delta management
|
|
def push_delta(self, delta: PlanDelta) -> None:
|
|
self.local_deltas.append(delta)
|
|
|
|
def reconcile(self) -> Dict[str, Any]:
|
|
# Deterministic reconciliation: apply deltas in order to central_state
|
|
state = copy.deepcopy(self.central_state)
|
|
for d in self.local_deltas:
|
|
# simplistic: delta.plan contains an "actions" list to append to log
|
|
actions = d.plan.get("actions", []) if isinstance(d.plan, dict) else []
|
|
for a in actions:
|
|
state.setdefault("execution_log", []).append({"t": datetime.utcnow().isoformat(), "action": a})
|
|
# store a versioned delta as part of central state for auditability
|
|
state.setdefault("applied_deltas", []).append(d.to_json())
|
|
# After reconciliation, reset local deltas as if they were consumed
|
|
self.central_state = state
|
|
self.local_deltas = []
|
|
return state
|
|
|
|
def current_state(self) -> Dict[str, Any]:
|
|
return copy.deepcopy(self.central_state)
|