forensic-brain / brain.py
joduor's picture
Upload folder using huggingface_hub
5de13b5 verified
Raw
History Blame Contribute Delete
4.06 kB
"""
ForensicAI 2nd Brain — adaptive state manager.
Tracks case types, evidence confidence, and forensic insights across sessions.
"""
from __future__ import annotations
import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional
BRAIN_PATH = Path("/app/forensic_brain_state.json")
CASE_TYPES = [
"homicide", "sexual_assault", "burglary", "fraud",
"drug_offense", "digital_crime", "arson", "hit_and_run",
]
DEFAULT: dict = {
"session_count": 0,
"total_analyses": 0,
"total_evidence_items": 0,
"case_frequency": {c: 0 for c in CASE_TYPES},
"confidence_history": [],
"complexity_history": [],
"avg_confidence": 0.70,
"avg_complexity": 0.50,
"dominant_case": "default",
"pattern_generation": 1,
"feed_rate": 0.037,
"kill_rate": 0.060,
"last_updated": None,
"insights": [],
"evolution_log": [],
}
_CASE_PARAMS = {
"homicide": (0.025, 0.055),
"sexual_assault": (0.037, 0.061),
"digital_crime": (0.029, 0.057),
"drug_offense": (0.040, 0.060),
"arson": (0.033, 0.058),
"burglary": (0.038, 0.062),
"fraud": (0.026, 0.053),
"hit_and_run": (0.035, 0.059),
"default": (0.037, 0.060),
}
def load() -> dict:
if BRAIN_PATH.exists():
try:
return json.loads(BRAIN_PATH.read_text())
except Exception:
pass
return DEFAULT.copy()
def _save(state: dict) -> None:
BRAIN_PATH.parent.mkdir(parents=True, exist_ok=True)
state["last_updated"] = datetime.now(timezone.utc).isoformat()
BRAIN_PATH.write_text(json.dumps(state, indent=2))
def _recompute(state: dict) -> None:
dom = state["dominant_case"]
base_f, base_k = _CASE_PARAMS.get(dom, _CASE_PARAMS["default"])
conf = max(0.0, min(1.0, state["avg_confidence"]))
cmplx = max(0.0, min(1.0, state["avg_complexity"]))
state["feed_rate"] = round(base_f + cmplx * 0.008, 5)
state["kill_rate"] = round(base_k + conf * 0.006, 5)
def update(
case_type: Optional[str] = None,
confidence: Optional[float] = None,
complexity: Optional[float] = None,
n_evidence: int = 0,
insight: Optional[str] = None,
) -> dict:
state = load()
state["session_count"] += 1
state["total_analyses"] += 1
state["total_evidence_items"] += n_evidence
if confidence is not None:
h = state["confidence_history"]
h.append(round(confidence, 3))
state["confidence_history"] = h[-200:]
state["avg_confidence"] = round(sum(h) / len(h), 3)
if complexity is not None:
h = state["complexity_history"]
h.append(round(complexity, 3))
state["complexity_history"] = h[-200:]
state["avg_complexity"] = round(sum(h) / len(h), 3)
if case_type and case_type in state["case_frequency"]:
state["case_frequency"][case_type] += 1
state["dominant_case"] = max(
state["case_frequency"], key=lambda k: state["case_frequency"][k]
)
if insight:
state["insights"].append({
"ts": datetime.now(timezone.utc).isoformat(),
"text": insight,
})
state["insights"] = state["insights"][-30:]
_recompute(state)
if state["session_count"] % 15 == 0:
old = state["pattern_generation"]
state["pattern_generation"] += 1
state["evolution_log"].append({
"ts": datetime.now(timezone.utc).isoformat(),
"from_gen": old,
"to_gen": state["pattern_generation"],
"feed": state["feed_rate"],
"kill": state["kill_rate"],
"dominant": state["dominant_case"],
})
state["evolution_log"] = state["evolution_log"][-20:]
_save(state)
return state
def reset() -> dict:
state = DEFAULT.copy()
_save(state)
return state