devils-agent / baim /state.py
devildasdf's picture
Upload experimental BAIM code, research checkpoints and measured evaluations
795f737 verified
Raw
History Blame Contribute Delete
2.04 kB
"""Canonical semantic state; hashes are identifiers, never embeddings."""
from dataclasses import dataclass, asdict
import hashlib
import json
def canonical(value):
return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
def digest(value):
return hashlib.sha256(canonical(value).encode("utf-8")).hexdigest()
def normalize(text):
return " ".join(text.split())
@dataclass(frozen=True)
class Element:
ref: str
role: str
name: str
path: str
visible: bool = True
enabled: bool = True
sensitive: bool = False
def semantic(self):
return dict(role=self.role, name="[REDACTED]" if self.sensitive else normalize(self.name),
path=self.path, visible=self.visible, enabled=self.enabled,
sensitive=self.sensitive)
@property
def signature(self):
return digest(self.semantic())
@dataclass(frozen=True)
class State:
document_id: str
revision: int
origin: str
elements: tuple[Element, ...]
@property
def state_hash(self):
# Order is meaningful for ordinal tasks. Ephemeral refs are excluded.
return digest(dict(origin=self.origin, elements=[e.semantic() for e in self.elements]))
def compact(self):
return dict(document=self.document_id, revision=self.revision, hash=self.state_hash,
elements=[dict(ref=e.ref, **e.semantic()) for e in self.elements])
def delta(self, previous):
if self.document_id != previous.document_id:
return dict(reset=self.compact())
before = {e.ref: e for e in previous.elements}
after = {e.ref: e for e in self.elements}
return dict(base=previous.state_hash, hash=self.state_hash, revision=self.revision,
removed=sorted(before.keys() - after.keys()),
changed=[dict(ref=r, **e.semantic()) for r, e in after.items()
if r not in before or e != before[r]],
order=list(after))