Files

162 lines
5.3 KiB
Python

from .memory import make_route_memory, summarize_memory, add_stage_record
def make_event_packet(metadata=None) -> dict:
"""Create a minimal EVENT_PACKET container."""
return {
"signals": {},
"projections": {},
"relations": {},
"sstates": {},
"equality_links": {},
"conflicts": {},
"route_memory": make_route_memory(),
"current_sstate_id": None,
"current_stage": None,
"metadata": metadata or {},
}
def ensure_packet(packet=None) -> dict:
"""Ensure an object is a usable EVENT_PACKET dict."""
if packet is None or not isinstance(packet, dict):
return make_event_packet()
packet.setdefault("signals", {})
packet.setdefault("projections", {})
packet.setdefault("relations", {})
packet.setdefault("sstates", {})
packet.setdefault("equality_links", {})
packet.setdefault("conflicts", {})
packet.setdefault("route_memory", make_route_memory())
packet.setdefault("current_sstate_id", None)
packet.setdefault("current_stage", None)
packet.setdefault("metadata", {})
return packet
def _append_unique(target_list, value):
if value and value not in target_list:
target_list.append(value)
def add_signal(packet: dict, signal: dict) -> dict:
packet = ensure_packet(packet)
packet["signals"][signal["id"]] = signal
_append_unique(packet["route_memory"].setdefault("signal_ids", []), signal["id"])
return packet
def add_projection(packet: dict, projection: dict) -> dict:
packet = ensure_packet(packet)
packet["projections"][projection["id"]] = projection
_append_unique(packet["route_memory"].setdefault("projection_ids", []), projection["id"])
return packet
def add_relation(packet: dict, relation: dict) -> dict:
packet = ensure_packet(packet)
packet["relations"][relation["id"]] = relation
_append_unique(packet["route_memory"].setdefault("relation_ids", []), relation["id"])
return packet
def add_sstate(packet: dict, sstate: dict) -> dict:
packet = ensure_packet(packet)
packet["sstates"][sstate["id"]] = sstate
packet["current_sstate_id"] = sstate["id"]
_append_unique(packet["route_memory"].setdefault("sstate_ids", []), sstate["id"])
return packet
def add_conflict(packet: dict, conflict: dict) -> dict:
packet = ensure_packet(packet)
packet["conflicts"][conflict["id"]] = conflict
_append_unique(packet["route_memory"].setdefault("conflict_ids", []), conflict["id"])
# Attach conflict id to involved relations/sstates if present.
for rel_id in conflict.get("involved_relation_ids", []):
rel = packet.get("relations", {}).get(rel_id)
if rel is not None:
_append_unique(rel.setdefault("conflict_ids", []), conflict["id"])
for s_id in conflict.get("involved_sstate_ids", []):
sstate = packet.get("sstates", {}).get(s_id)
if sstate is not None:
_append_unique(sstate.setdefault("conflict_ids", []), conflict["id"])
return packet
def get_latest_signals(packet: dict, n: int = 1) -> list:
packet = ensure_packet(packet)
values = list(packet.get("signals", {}).values())
return values[-n:]
def get_projection_ids_for_signal(packet: dict, signal_id: str) -> list:
packet = ensure_packet(packet)
return [
proj_id for proj_id, proj in packet.get("projections", {}).items()
if proj.get("source_signal_id") == signal_id
]
def signal_exists(packet: dict, signal_id: str) -> bool:
packet = ensure_packet(packet)
return signal_id in packet.get("signals", {})
def packet_summary(packet=None) -> dict:
"""Return compact EVENT_PACKET summary."""
packet = ensure_packet(packet)
memory = packet.get("route_memory", {})
memory_summary = summarize_memory(memory)
return {
"signals": len(packet.get("signals", {})),
"projections": len(packet.get("projections", {})),
"relations": len(packet.get("relations", {})),
"sstates": len(packet.get("sstates", {})),
"conflicts": len(packet.get("conflicts", {})),
"current_sstate_id": packet.get("current_sstate_id"),
"route_memory_id": memory.get("id"),
"stage_records": memory_summary.get("stage_records", 0),
"sampler_step_records": memory_summary.get("sampler_step_records", 0),
}
def record_stage(
packet: dict,
stage_name: str,
action: str,
observed_behavior: str = "",
metadata=None,
input_signal_ids=None,
output_signal_ids=None,
projection_ids=None,
relation_ids=None,
sstate_ids=None,
conflict_ids=None,
formula_note: str = "",
) -> dict:
"""Attach a stage record to RouteMemory."""
packet = ensure_packet(packet)
record = {
"stage_name": stage_name,
"node_name": stage_name,
"action": action,
"input_signal_ids": input_signal_ids or [],
"output_signal_ids": output_signal_ids or [],
"projection_ids": projection_ids or [],
"relation_ids": relation_ids or [],
"sstate_ids": sstate_ids or [],
"conflict_ids": conflict_ids or [],
"observed_behavior": observed_behavior,
"formula_note": formula_note,
"metadata": metadata or {},
}
packet["route_memory"] = add_stage_record(packet.get("route_memory", {}), record)
packet["current_stage"] = stage_name
return packet