Module: Legion::Extensions::Agentic::Memory::Trace::Helpers::HotTier

Defined in:
lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb

Constant Summary collapse

HOT_TTL =

24 hours

86_400

Class Method Summary collapse

Class Method Details

.available?Boolean

Returns true when the RedisHash module is loaded and Redis is reachable.

Returns:

  • (Boolean)


52
53
54
55
56
57
# File 'lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb', line 52

def available?
  defined?(Legion::Cache::RedisHash) &&
    Legion::Cache::RedisHash.redis_available?
rescue StandardError => _e
  false
end

.cache_scope_id(trace, tenant_id: nil, agent_id: nil) ⇒ Object



71
72
73
74
75
76
# File 'lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb', line 71

def cache_scope_id(trace, tenant_id: nil, agent_id: nil)
  return scope_id(tenant_id: tenant_id, agent_id: agent_id) if agent_id
  return tenant_id if tenant_id

  trace[:partition_id]
end

.cache_trace(trace, tenant_id: nil, agent_id: nil) ⇒ Object

Cache a trace in the Redis hot tier.



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb', line 15

def cache_trace(trace, tenant_id: nil, agent_id: nil)
  return unless available?

  scope = cache_scope_id(trace, tenant_id: tenant_id, agent_id: agent_id)
  key = trace_key(scope, trace[:trace_id])
  data = serialize_trace(trace)
  Legion::Cache::RedisHash.hset(key, data)
  Legion::Cache::RedisHash.expire(key, HOT_TTL)

  index_key = "legion:tier:hot:#{scope}"
  Legion::Cache::RedisHash.zadd(index_key, Time.now.to_f, trace[:trace_id])
end

.deserialize_trace(data) ⇒ Object

Deserialize a Redis string-hash back to a typed trace hash.



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb', line 94

def deserialize_trace(data)
  {
    trace_id:        data['trace_id'],
    trace_type:      data['trace_type']&.to_sym,
    content_payload: data['content_payload'],
    strength:        data['strength']&.to_f,
    peak_strength:   data['peak_strength']&.to_f,
    confidence:      data['confidence']&.to_f,
    storage_tier:    :hot,
    partition_id:    data['partition_id'],
    last_reinforced: data['last_reinforced']
  }
end

.evict_trace(trace_id, tenant_id: nil, agent_id: nil) ⇒ Object

Evict a trace from the hot tier and remove it from the sorted-set index.



40
41
42
43
44
45
46
47
48
49
# File 'lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb', line 40

def evict_trace(trace_id, tenant_id: nil, agent_id: nil)
  return unless available?

  scope = scope_id(tenant_id: tenant_id, agent_id: agent_id)
  key = trace_key(scope, trace_id)
  Legion::Cache.delete(key)

  index_key = "legion:tier:hot:#{scope}"
  Legion::Cache::RedisHash.zrem(index_key, trace_id)
end

.fetch_trace(trace_id, tenant_id: nil, agent_id: nil) ⇒ Object

Fetch a trace from the hot tier. Returns a deserialized trace hash or nil on miss.



29
30
31
32
33
34
35
36
37
# File 'lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb', line 29

def fetch_trace(trace_id, tenant_id: nil, agent_id: nil)
  return nil unless available?

  key = trace_key(scope_id(tenant_id: tenant_id, agent_id: agent_id), trace_id)
  data = Legion::Cache::RedisHash.hgetall(key)
  return nil if data.nil? || data.empty?

  deserialize_trace(data)
end

.scope_id(tenant_id: nil, agent_id: nil) ⇒ Object



64
65
66
67
68
69
# File 'lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb', line 64

def scope_id(tenant_id: nil, agent_id: nil)
  return tenant_id if tenant_id && agent_id.nil?
  return agent_id if agent_id && tenant_id.nil?

  [tenant_id, agent_id].compact.join(':')
end

.serialize_trace(trace) ⇒ Object

Serialize a trace hash to a string-only flat hash suitable for Redis HSET.



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb', line 79

def serialize_trace(trace)
  {
    'trace_id'        => trace[:trace_id].to_s,
    'trace_type'      => trace[:trace_type].to_s,
    'content_payload' => trace[:content_payload].to_s,
    'strength'        => trace[:strength].to_s,
    'peak_strength'   => trace[:peak_strength].to_s,
    'confidence'      => trace[:confidence].to_s,
    'storage_tier'    => 'hot',
    'partition_id'    => trace[:partition_id].to_s,
    'last_reinforced' => (trace[:last_reinforced] || Time.now).to_s
  }
end

.trace_key(scope_id, trace_id) ⇒ Object

Build the namespaced Redis key for a trace.



60
61
62
# File 'lib/legion/extensions/agentic/memory/trace/helpers/hot_tier.rb', line 60

def trace_key(scope_id, trace_id)
  "legion:trace:#{scope_id}:#{trace_id}"
end