File size: 1,824 Bytes
55d584b
 
0ccf2f0
55d584b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ccf2f0
55d584b
 
 
 
 
 
0ccf2f0
 
55d584b
 
 
 
0ccf2f0
 
55d584b
7b4e922
0ccf2f0
55d584b
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
#!/usr/bin/env python3
"""
Anchor Data Classes - Shared data structures for semantic anchors.

Contains the core data classes used by both semantic anchors and memory pool
to avoid circular import issues.
"""

from typing import List, Dict, Any, Optional
import time
from dataclasses import dataclass


@dataclass
class AnchorProvenance:
    """Provenance tracking for anchors."""

    first_seen: float
    utterance_ids: List[str]
    update_count: int
    last_updated: float
    creation_context: Dict[str, Any]
    update_history: List[Dict[str, Any]]

    def add_update(self, utterance_id: str, context: Dict[str, Any]):
        """Record an anchor update."""
        self.utterance_ids.append(utterance_id)
        self.update_count += 1
        self.last_updated = time.time()
        self.update_history.append(
            {"timestamp": self.last_updated, "utterance_id": utterance_id, "context": context}
        )


@dataclass
class SemanticAnchor:
    """Enhanced anchor with semantic embedding and provenance."""

    anchor_id: str
    concept_text: str
    embedding: List[float]
    heat: float
    provenance: Optional[AnchorProvenance]
    cluster_id: Optional[str] = None
    semantic_drift: float = 0.0
    stability_score: float = 1.0

    def calculate_age_days(self) -> float:
        """Calculate anchor age in days."""
        if self.provenance is None:
            return 0.0
        return (time.time() - self.provenance.first_seen) / (24 * 3600)

    def calculate_activity_rate(self) -> float:
        """Calculate activity rate (updates per day)."""
        if self.provenance is None:
            return 0.0
        age_days = self.calculate_age_days()
        if age_days < 0.001:  # Less than ~1.5 minutes old
            return 0.0
        return self.provenance.update_count / age_days