Spaces:
Configuration error
Configuration error
File size: 5,890 Bytes
77bcbf1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | """
Cascade Core - Event and CausationLink primitives.
These are the fundamental data structures that represent causation.
"""
from dataclasses import dataclass, field
from typing import Dict, List, Any, Optional
from datetime import datetime
import time
import uuid
def _generate_event_id() -> str:
"""Generate a unique event ID with timestamp prefix for ordering."""
timestamp = int(time.time() * 1000000)
unique = uuid.uuid4().hex[:8]
return f"evt_{timestamp}_{unique}"
@dataclass
class Event:
"""
A discrete event in the causation graph.
Events are the nodes in your causation graph. Each event represents
something that happened in your system at a point in time.
Attributes:
event_id: Unique identifier (auto-generated if not provided)
timestamp: Unix timestamp when event occurred
component: Which system component generated this event
event_type: Category of event (e.g., 'training', 'inference', 'error')
data: Arbitrary key-value data associated with the event
source_signal: The original signal that created this event (for debugging)
Example:
>>> event = Event(
... timestamp=time.time(),
... component="neural_network",
... event_type="gradient_explosion",
... data={"layer": "fc3", "magnitude": 1e12}
... )
"""
timestamp: float
component: str
event_type: str
data: Dict[str, Any] = field(default_factory=dict)
event_id: str = field(default_factory=_generate_event_id)
source_signal: Optional[Any] = field(default=None, repr=False)
def __post_init__(self):
"""Ensure timestamp is float."""
if isinstance(self.timestamp, datetime):
self.timestamp = self.timestamp.timestamp()
def to_dict(self) -> Dict[str, Any]:
"""Serialize event to dictionary."""
return {
"event_id": self.event_id,
"timestamp": self.timestamp,
"component": self.component,
"event_type": self.event_type,
"data": self.data,
}
@classmethod
def from_dict(cls, d: Dict[str, Any]) -> "Event":
"""Deserialize event from dictionary."""
return cls(
event_id=d.get("event_id", _generate_event_id()),
timestamp=d["timestamp"],
component=d["component"],
event_type=d["event_type"],
data=d.get("data", {}),
)
def __hash__(self):
return hash(self.event_id)
def __eq__(self, other):
if isinstance(other, Event):
return self.event_id == other.event_id
return False
@dataclass
class CausationLink:
"""
A causal relationship between two events.
Links are the edges in your causation graph. Each link represents
a cause-effect relationship: event A caused event B.
Attributes:
from_event: ID of the causing event
to_event: ID of the caused event
causation_type: How the causation was detected
- 'temporal': A happened shortly before B
- 'correlation': A and B metrics moved together
- 'threshold': A crossed a threshold triggering B
- 'direct': Explicit causation declared in code
strength: Confidence in the causal relationship (0.0 to 1.0)
explanation: Human-readable explanation of the link
metrics_involved: Which metrics connect these events
Example:
>>> link = CausationLink(
... from_event="evt_123",
... to_event="evt_456",
... causation_type="threshold",
... strength=0.95,
... explanation="Loss exceeded 10.0, triggering gradient clipping"
... )
"""
from_event: str
to_event: str
causation_type: str # 'temporal', 'correlation', 'threshold', 'direct'
strength: float = 1.0
explanation: str = ""
metrics_involved: List[str] = field(default_factory=list)
def __post_init__(self):
"""Validate strength is in range."""
self.strength = max(0.0, min(1.0, self.strength))
def to_dict(self) -> Dict[str, Any]:
"""Serialize link to dictionary."""
return {
"from_event": self.from_event,
"to_event": self.to_event,
"causation_type": self.causation_type,
"strength": self.strength,
"explanation": self.explanation,
"metrics_involved": self.metrics_involved,
}
@classmethod
def from_dict(cls, d: Dict[str, Any]) -> "CausationLink":
"""Deserialize link from dictionary."""
return cls(
from_event=d["from_event"],
to_event=d["to_event"],
causation_type=d["causation_type"],
strength=d.get("strength", 1.0),
explanation=d.get("explanation", ""),
metrics_involved=d.get("metrics_involved", []),
)
@dataclass
class CausationChain:
"""
A chain of causal events from origin to destination.
Represents a full causal path through the graph.
Attributes:
events: List of events in causal order
links: List of links connecting the events
total_strength: Combined strength of all links
depth: Number of hops in the chain
narrative: Human-readable story of what happened
"""
events: List[Event]
links: List[CausationLink]
total_strength: float = 1.0
depth: int = 0
narrative: str = ""
def __post_init__(self):
self.depth = len(self.links)
if not self.total_strength and self.links:
# Calculate combined strength
self.total_strength = 1.0
for link in self.links:
self.total_strength *= link.strength
|