core/sensorium/vision/arena.py

83 lines
2.3 KiB
Python

"""Vision Delta-CRDT wrappers over the shared compiler substrate."""
from __future__ import annotations
import threading
from dataclasses import dataclass
from sensorium.compiler.arena import LocalArena
from sensorium.compiler.delta import ContentAddressedDelta, merge_deltas
from sensorium.compiler.trace import merge_trace_hash
from sensorium.vision.trace import vision_evidence_trace
from sensorium.vision.types import VisionCompilationUnit
MergeKey = tuple[str, str, str]
@dataclass(frozen=True, slots=True)
class VisionDelta:
_inner: ContentAddressedDelta[VisionCompilationUnit]
@classmethod
def from_units(
cls,
units: tuple[VisionCompilationUnit, ...] | list[VisionCompilationUnit],
) -> "VisionDelta":
return cls(ContentAddressedDelta.from_units(units))
@property
def units(self) -> tuple[VisionCompilationUnit, ...]:
return self._inner.units
def join(self, other: "VisionDelta") -> "VisionDelta":
return VisionDelta(self._inner.join(other._inner))
@property
def merge_keys(self) -> tuple[MergeKey, ...]:
return self._inner.merge_keys
def __len__(self) -> int:
return len(self._inner)
class VisionArena:
__slots__ = ("_arena",)
def __init__(self) -> None:
self._arena: LocalArena[VisionCompilationUnit] = LocalArena()
def push(self, unit: VisionCompilationUnit) -> None:
self._arena.push(unit)
def is_empty(self) -> bool:
return self._arena.is_empty()
def snapshot(self) -> VisionDelta:
return VisionDelta(self._arena.snapshot())
def __len__(self) -> int:
return len(self._arena)
_THREAD_LOCAL = threading.local()
def thread_local_vision_arena() -> VisionArena:
arena = getattr(_THREAD_LOCAL, "vision_arena", None)
if arena is None:
arena = VisionArena()
_THREAD_LOCAL.vision_arena = arena
return arena
def reset_thread_local_vision_arena() -> None:
if hasattr(_THREAD_LOCAL, "vision_arena"):
del _THREAD_LOCAL.vision_arena
def merge_vision_deltas(deltas: list[VisionDelta] | tuple[VisionDelta, ...]) -> VisionDelta:
return VisionDelta(merge_deltas(delta._inner for delta in deltas))
def vision_merge_trace_hash(merged: VisionDelta) -> str:
return merge_trace_hash(merged._inner, vision_evidence_trace)