Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 34 additions & 19 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,33 +1,48 @@
# Runtime artifacts
*.db
*.db-shm
*.db-wal

# Python
__pycache__/
*.py[cod]
*.pyo
*.pyd
.Python

# Testing / coverage
.pytest_cache/
.coverage
htmlcov/
.tox/
# Virtual env
.venv/
venv/
env/

# Build / packaging
dist/
# Build artifacts
build/
dist/
*.egg-info/
*.egg

# Virtual environments
.venv/
venv/
env/
# Testing
.pytest_cache/
.coverage
htmlcov/

# IDE
.vscode/
.idea/
*.swp

# Runtime
adaptive_runtime.db
*.db
*.sqlite
*.sqlite3

# Logs
*.log

# OS
.DS_Store
Thumbs.db
# Runtime database
adaptive_runtime.db
*.db
*.sqlite

# Python cache
__pycache__/
.pytest_cache/

# Virtual environment
.venv/
12 changes: 0 additions & 12 deletions __init__.py

This file was deleted.

9 changes: 9 additions & 0 deletions adaptive_runtime/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
Adaptive Runtime
"""

from .runtime.runtime_manager import Runtime, RuntimeResult

__all__ = ["Runtime", "RuntimeResult"]
__version__ = "0.1.0"

4 changes: 3 additions & 1 deletion core/__init__.py → adaptive_runtime/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .state_engine import StateEngine
from .state_engine import StateEngine
from .context_engine import ContextEngine, ContextResult
from .confidence_engine import ConfidenceEngine, ConfidenceResult
from .decision_engine import DecisionEngine, DecisionResult
Expand All @@ -11,3 +11,5 @@
"DecisionEngine", "DecisionResult",
"RecoveryEngine",
]


Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Confidence Engine adaptive probabilistic confidence scoring.
"""
Confidence Engine - adaptive probabilistic confidence scoring.
"""

import math
Expand All @@ -8,8 +8,8 @@
from typing import Deque

from pydantic import BaseModel
from observability.logger import get_logger
from observability.metrics import metrics
from ..observability.logger import get_logger
from ..observability.metrics import metrics

logger = get_logger("confidence_engine")

Expand Down Expand Up @@ -56,7 +56,6 @@ def __init__(
self._history: Deque[OutcomeRecord] = deque(maxlen=history_window)
self._call_count = 0

# ── Public API ─────────────────────────────────────────────────────────

def calculate(self, event: dict, context_risk: str) -> ConfidenceResult:
self._call_count += 1
Expand All @@ -80,7 +79,7 @@ def calculate(self, event: dict, context_risk: str) -> ConfidenceResult:
)
metrics.record("confidence.final", final)
logger.info(
"Confidence base=%.2f decay=%.2f hist=%.2f ctx=%.2f final=%.4f",
"Confidence → base=%.2f decay=%.2f hist=%.2f ctx=%.2f final=%.4f",
base, decay, hist_weight, ctx_adj, final,
)
return result
Expand All @@ -94,7 +93,6 @@ def record_outcome(self, success: bool, confidence: float, context_risk: str) ->
))
logger.debug("Outcome recorded: success=%s conf=%.3f", success, confidence)

# ── Internals ──────────────────────────────────────────────────────────

def _decay_factor(self) -> float:
"""Confidence decays slightly as call volume grows (simulate drift)."""
Expand All @@ -106,5 +104,7 @@ def _history_weight(self, context_risk: str) -> float:
if len(relevant) < 3:
return 1.0
success_rate = sum(1 for r in relevant if r.success) / len(relevant)
# Map [0, 1] success rate [0.6, 1.1] weight
# Map [0, 1] success rate → [0.6, 1.1] weight
return 0.6 + success_rate * 0.5


18 changes: 8 additions & 10 deletions core/context_engine.py → adaptive_runtime/core/context_engine.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
"""
Context Engine transforms raw events into contextual understanding.
"""
Context Engine - transforms raw events into contextual understanding.
"""

from pydantic import BaseModel, Field
from observability.logger import get_logger
from observability.metrics import metrics
from ..observability.logger import get_logger
from ..observability.metrics import metrics

logger = get_logger("context_engine")


# ── Models ─────────────────────────────────────────────────────────────────

class RawEvent(BaseModel):
type: str
Expand All @@ -29,7 +28,6 @@ class ContextResult(BaseModel):
tags: list[str]


# ── Thresholds ─────────────────────────────────────────────────────────────

_RISK_RULES: list[tuple[float, str]] = [
(0.85, "critical"),
Expand All @@ -56,13 +54,12 @@ class ContextResult(BaseModel):
}


# ── Engine ─────────────────────────────────────────────────────────────────

class ContextEngine:
"""
Classifies events and scores runtime context.

Uses lightweight rule-based scoring no ML dependencies.
Uses lightweight rule-based scoring - no ML dependencies.
"""

def __init__(self, custom_context_map: dict[str, str] | None = None):
Expand All @@ -88,12 +85,11 @@ def analyze(self, event: dict) -> ContextResult:

metrics.record("context.pressure", pressure)
logger.info(
"Context risk=%s stability=%s ctx=%s pressure=%.2f",
"Context → risk=%s stability=%s ctx=%s pressure=%.2f",
risk, stability, context_label, pressure,
)
return result

# ── Internals ──────────────────────────────────────────────────────────

def _pressure_score(self, raw: RawEvent) -> float:
"""Weighted composite score in [0, 1]."""
Expand Down Expand Up @@ -132,3 +128,5 @@ def _build_tags(raw: RawEvent, risk: str) -> list[str]:
if raw.latency_ms > 2000:
tags.append("latency:high")
return tags


Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""
Decision Engine generates adaptive runtime decisions.
"""
Decision Engine - generates adaptive runtime decisions.
"""

from pydantic import BaseModel
from observability.logger import get_logger
from observability.metrics import metrics
from ..observability.logger import get_logger
from ..observability.metrics import metrics

logger = get_logger("decision_engine")

Expand All @@ -17,8 +17,7 @@ class DecisionResult(BaseModel):
metadata: dict = {}


# ── Action ruleset ─────────────────────────────────────────────────────────
# Each rule: (context_label, risk_level, min_confidence) → action
# Each rule: (context_label, risk_level, min_confidence) → action
# Evaluated top-to-bottom; first match wins.

_RULES: list[tuple[str | None, str | None, float, str, str]] = [
Expand Down Expand Up @@ -79,12 +78,11 @@ def decide(
)
metrics.record("decision.confidence", confidence)
logger.info(
"Decision action=%s confidence=%.3f reason=%s priority=%s",
"Decision → action=%s confidence=%.3f reason=%s priority=%s",
action, confidence, reason, priority,
)
return result

# ── Internals ──────────────────────────────────────────────────────────

def _match(self, context: str, risk: str, confidence: float) -> tuple[str, str]:
for ctx_rule, risk_rule, min_conf, action, reason in self._rules:
Expand All @@ -94,3 +92,5 @@ def _match(self, context: str, risk: str, confidence: float) -> tuple[str, str]:
if ctx_ok and risk_ok and conf_ok:
return action, reason
return "monitor_and_wait", "no_matching_rule"


Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"""
Recovery Engine self-healing runtime resilience.
"""
Recovery Engine - self-healing runtime resilience.
"""

import asyncio
from datetime import datetime
from typing import Callable, Awaitable

from pydantic import BaseModel
from observability.logger import get_logger
from observability.metrics import metrics
from ..observability.logger import get_logger
from ..observability.metrics import metrics

logger = get_logger("recovery_engine")

Expand Down Expand Up @@ -36,7 +36,6 @@ def __init__(self, store, agent_id: str, max_retries: int = 3, base_delay: float
self.base_delay = base_delay
self._last_checkpoint: CheckpointMeta | None = None

# ── Checkpointing ──────────────────────────────────────────────────────

async def create_checkpoint(self, state: dict) -> CheckpointMeta:
snap_id = await self.store.save_snapshot(
Expand Down Expand Up @@ -64,7 +63,6 @@ async def restore_latest(self) -> dict | None:
logger.warning("No snapshot found for agent '%s'", self.agent_id)
return None

# ── Retry orchestration ────────────────────────────────────────────────

async def retry(
self,
Expand All @@ -87,7 +85,7 @@ async def retry(
last_exc = exc
delay = self.base_delay * (2 ** (attempt - 1))
logger.warning(
"Attempt %d/%d failed: %s retrying in %.1fs",
"Attempt %d/%d failed: %s - retrying in %.1fs",
attempt, self.max_retries, exc, delay,
)
metrics.record("recovery.retry_fail", 1)
Expand All @@ -101,7 +99,6 @@ async def retry(
return await fallback()
raise last_exc

# ── Crash recovery ─────────────────────────────────────────────────────

async def crash_recovery(self, state_engine) -> dict:
"""
Expand All @@ -122,5 +119,7 @@ async def crash_recovery(self, state_engine) -> dict:
logger.info("[Recovery] State recovered from snapshot.")
return snap

logger.error("[Recovery] No recoverable state found starting fresh.")
logger.error("[Recovery] No recoverable state found - starting fresh.")
return {}


11 changes: 6 additions & 5 deletions core/state_engine.py → adaptive_runtime/core/state_engine.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""
State Engine manages runtime persistence and state memory.
"""
State Engine - manages runtime persistence and state memory.
"""

from datetime import datetime
from typing import Any

from observability.logger import get_logger
from observability.metrics import metrics
from ..observability.logger import get_logger
from ..observability.metrics import metrics

logger = get_logger("state_engine")

Expand All @@ -24,7 +24,6 @@ def __init__(self, store, agent_id: str):
self.agent_id = agent_id
self._state: dict[str, Any] = {}

# ── Public API ─────────────────────────────────────────────────────────

async def save_state(self, state: dict) -> None:
self._state.update(state)
Expand Down Expand Up @@ -56,3 +55,5 @@ async def reset_state(self) -> None:
@property
def current(self) -> dict:
return dict(self._state)


Loading
Loading