activematrix 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +218 -51
- data/lib/active_matrix/agent_manager.rb +275 -0
- data/lib/active_matrix/agent_registry.rb +154 -0
- data/lib/active_matrix/bot/multi_instance_base.rb +189 -0
- data/lib/active_matrix/client.rb +5 -15
- data/lib/active_matrix/client_pool.rb +194 -0
- data/lib/active_matrix/event_router.rb +215 -0
- data/lib/active_matrix/memory/agent_memory.rb +128 -0
- data/lib/active_matrix/memory/base.rb +101 -0
- data/lib/active_matrix/memory/conversation_memory.rb +161 -0
- data/lib/active_matrix/memory/global_memory.rb +153 -0
- data/lib/active_matrix/memory.rb +28 -0
- data/lib/active_matrix/room.rb +131 -51
- data/lib/active_matrix/rooms/space.rb +1 -5
- data/lib/active_matrix/user.rb +10 -0
- data/lib/active_matrix/util/account_data_cache.rb +62 -24
- data/lib/active_matrix/util/cacheable.rb +73 -0
- data/lib/active_matrix/util/extensions.rb +4 -0
- data/lib/active_matrix/util/state_event_cache.rb +106 -31
- data/lib/active_matrix/version.rb +1 -1
- data/lib/active_matrix.rb +51 -3
- data/lib/generators/active_matrix/bot/bot_generator.rb +38 -0
- data/lib/generators/active_matrix/bot/templates/bot.rb.erb +111 -0
- data/lib/generators/active_matrix/bot/templates/bot_spec.rb.erb +68 -0
- data/lib/generators/active_matrix/install/install_generator.rb +44 -0
- data/lib/generators/active_matrix/install/templates/README +30 -0
- data/lib/generators/active_matrix/install/templates/active_matrix.rb +33 -0
- data/lib/generators/active_matrix/install/templates/agent_memory.rb +47 -0
- data/lib/generators/active_matrix/install/templates/conversation_context.rb +72 -0
- data/lib/generators/active_matrix/install/templates/create_agent_memories.rb +17 -0
- data/lib/generators/active_matrix/install/templates/create_conversation_contexts.rb +21 -0
- data/lib/generators/active_matrix/install/templates/create_global_memories.rb +20 -0
- data/lib/generators/active_matrix/install/templates/create_matrix_agents.rb +26 -0
- data/lib/generators/active_matrix/install/templates/global_memory.rb +70 -0
- data/lib/generators/active_matrix/install/templates/matrix_agent.rb +127 -0
- metadata +110 -4
- data/lib/active_matrix/util/rails_cache_adapter.rb +0 -37
- data/lib/active_matrix/util/tinycache.rb +0 -145
- data/lib/active_matrix/util/tinycache_adapter.rb +0 -87
@@ -1,145 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_matrix/util/tinycache_adapter'
|
4
|
-
|
5
|
-
module ActiveMatrix::Util
|
6
|
-
module Tinycache
|
7
|
-
CACHE_LEVELS = {
|
8
|
-
none: 0,
|
9
|
-
some: 1,
|
10
|
-
all: 2
|
11
|
-
}.freeze
|
12
|
-
|
13
|
-
def self.adapter
|
14
|
-
@adapter ||= if defined?(::Rails) && ::Rails.respond_to?(:cache)
|
15
|
-
require 'active_matrix/util/rails_cache_adapter'
|
16
|
-
RailsCacheAdapter
|
17
|
-
else
|
18
|
-
TinycacheAdapter
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.adapter=(adapter)
|
23
|
-
@adapter = adapter
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.extended(base)
|
27
|
-
helper_name = base.send(:cache_helper_module_name)
|
28
|
-
base.send :remove_const, helper_name if base.const_defined?(helper_name)
|
29
|
-
base.prepend base.const_set(helper_name, Module.new)
|
30
|
-
|
31
|
-
base.include InstanceMethods
|
32
|
-
end
|
33
|
-
|
34
|
-
def cached(*methods, **)
|
35
|
-
methods.each { |method| build_cache_methods(method, **) }
|
36
|
-
end
|
37
|
-
|
38
|
-
module InstanceMethods
|
39
|
-
def tinycache_adapter
|
40
|
-
@tinycache_adapter ||= Tinycache.adapter.new.tap do |adapter|
|
41
|
-
adapter.config = self.class.tinycache_adapter_config if adapter.respond_to? :config=
|
42
|
-
adapter.client = client if respond_to?(:client) && adapter.respond_to?(:client=)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def tinycache_adapter_config
|
48
|
-
@tinycache_adapter_config ||= {}
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def default_cache_key
|
54
|
-
proc do |method_name, _method_args|
|
55
|
-
method_name.to_sym
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def cache_helper_module_name
|
60
|
-
class_name = name&.gsub(':', '') || to_s.gsub(/[^a-zA-Z_0-9]/, '')
|
61
|
-
"#{class_name}Tinycache"
|
62
|
-
end
|
63
|
-
|
64
|
-
def build_cache_methods(method_name, cache_key: default_cache_key, cache_level: :none, expires_in: nil, **opts)
|
65
|
-
raise ArgumentError, 'Cache key must be a three-arg proc' unless cache_key.is_a? Proc
|
66
|
-
|
67
|
-
method_names = build_method_names(method_name)
|
68
|
-
tinycache_adapter_config[method_name] = {
|
69
|
-
level: cache_level,
|
70
|
-
expires: expires_in || (1 * 365 * 24 * 60 * 60) # 1 year
|
71
|
-
}
|
72
|
-
|
73
|
-
helper = const_get(cache_helper_module_name)
|
74
|
-
return if method_names.any? { |k, _| helper.respond_to? k }
|
75
|
-
|
76
|
-
helper.class_eval do
|
77
|
-
define_method(method_names[:cache_key]) do |*args|
|
78
|
-
cache_key.call(method_name, args)
|
79
|
-
end
|
80
|
-
|
81
|
-
define_method(method_names[:with_cache]) do |*args|
|
82
|
-
tinycache_adapter.fetch(__send__(method_names[:cache_key], *args), expires_in: expires_in) do
|
83
|
-
named = args.delete_at(-1) if args.last.is_a? Hash
|
84
|
-
named ||= {}
|
85
|
-
|
86
|
-
__send__(method_names[:without_cache], *args, **named)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
define_method(method_names[:without_cache]) do |*args|
|
91
|
-
orig = method(method_name).super_method
|
92
|
-
named = args.delete_at(-1) if args.last.is_a? Hash
|
93
|
-
named ||= {}
|
94
|
-
|
95
|
-
orig.call(*args, **named)
|
96
|
-
end
|
97
|
-
|
98
|
-
define_method(method_names[:clear_cache]) do |*args|
|
99
|
-
tinycache_adapter.delete(__send__(method_names[:cache_key], *args))
|
100
|
-
end
|
101
|
-
|
102
|
-
define_method(method_names[:cached]) do
|
103
|
-
true
|
104
|
-
end
|
105
|
-
|
106
|
-
define_method(method_names[:has_value]) do |*args|
|
107
|
-
tinycache_adapter.valid?(__send__(method_names[:cache_key], *args))
|
108
|
-
end
|
109
|
-
|
110
|
-
define_method(method_name) do |*args|
|
111
|
-
unless_proc = opts[:unless].is_a?(Symbol) ? opts[:unless].to_proc : opts[:unless]
|
112
|
-
|
113
|
-
raise ArgumentError, 'Invalid proc provided (must have arity between 1..3)' if unless_proc && !(1..3).include?(unless_proc.arity)
|
114
|
-
|
115
|
-
skip_cache = false
|
116
|
-
skip_cache ||= unless_proc.call(self, method_name, args) if unless_proc&.arity == 3
|
117
|
-
skip_cache ||= unless_proc.call(method_name, args) if unless_proc&.arity == 2
|
118
|
-
skip_cache ||= unless_proc.call(args) if unless_proc&.arity == 1
|
119
|
-
skip_cache ||= CACHE_LEVELS[client&.cache || :all] < CACHE_LEVELS[cache_level]
|
120
|
-
|
121
|
-
if skip_cache
|
122
|
-
__send__(method_names[:without_cache], *args)
|
123
|
-
else
|
124
|
-
__send__(method_names[:with_cache], *args)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def build_method_names(method)
|
131
|
-
# Clean up method name (split any suffix)
|
132
|
-
method_name = method.to_s.sub(/([?!=])$/, '')
|
133
|
-
punctuation = Regexp.last_match(-1)
|
134
|
-
|
135
|
-
{
|
136
|
-
cache_key: "#{method_name}_cache_key#{punctuation}",
|
137
|
-
with_cache: "#{method_name}_with_cache#{punctuation}",
|
138
|
-
without_cache: "#{method_name}_without_cache#{punctuation}",
|
139
|
-
clear_cache: "clear_#{method_name}_cache#{punctuation}",
|
140
|
-
cached: "#{method}_cached?",
|
141
|
-
has_value: "#{method}_has_value?"
|
142
|
-
}
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveMatrix::Util
|
4
|
-
class TinycacheAdapter
|
5
|
-
extend ActiveMatrix::Extensions
|
6
|
-
|
7
|
-
attr_accessor :config, :client
|
8
|
-
|
9
|
-
ignore_inspect :client
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@config = {}
|
13
|
-
|
14
|
-
clear
|
15
|
-
end
|
16
|
-
|
17
|
-
def read(key)
|
18
|
-
cache[key]&.value
|
19
|
-
end
|
20
|
-
|
21
|
-
def write(key, value, expires_in: nil, cache_level: nil)
|
22
|
-
expires_in ||= config.dig(key, :expires)
|
23
|
-
expires_in ||= 24 * 60 * 60
|
24
|
-
cache_level ||= client&.cache
|
25
|
-
cache_level ||= :all
|
26
|
-
cache_level = Tinycache::CACHE_LEVELS[cache_level] unless cache_level.is_a? Integer
|
27
|
-
|
28
|
-
return value if cache_level < Tinycache::CACHE_LEVELS[config.dig(key, :level) || :none]
|
29
|
-
|
30
|
-
cache[key] = Value.new(value, Time.now, Time.now + expires_in)
|
31
|
-
value
|
32
|
-
end
|
33
|
-
|
34
|
-
def exist?(key)
|
35
|
-
cache.key?(key)
|
36
|
-
end
|
37
|
-
|
38
|
-
def valid?(key)
|
39
|
-
exist?(key) && !cache[key].expired?
|
40
|
-
end
|
41
|
-
|
42
|
-
def fetch(key, expires_in: nil, cache_level: nil, **_opts)
|
43
|
-
expires_in ||= config.dig(key, :expires)
|
44
|
-
cache_level ||= client&.cache
|
45
|
-
cache_level ||= :all
|
46
|
-
cache_level = Tinycache::CACHE_LEVELS[cache_level]
|
47
|
-
|
48
|
-
return read(key) if exist?(key) && !cache[key].expired?
|
49
|
-
|
50
|
-
value = yield
|
51
|
-
write(key, value, expires_in: expires_in, cache_level: cache_level)
|
52
|
-
end
|
53
|
-
|
54
|
-
def delete(key)
|
55
|
-
return false unless exist?(key)
|
56
|
-
|
57
|
-
cache.delete key
|
58
|
-
true
|
59
|
-
end
|
60
|
-
|
61
|
-
def expire(key)
|
62
|
-
return unless exist? key
|
63
|
-
|
64
|
-
cache[key].expires_at = Time.at(0)
|
65
|
-
end
|
66
|
-
|
67
|
-
def clear
|
68
|
-
@cache = {}
|
69
|
-
end
|
70
|
-
|
71
|
-
def cleanup
|
72
|
-
@cache.select { |_, v| v.expired? }.each_value { |v| v.value = nil }
|
73
|
-
end
|
74
|
-
|
75
|
-
private
|
76
|
-
|
77
|
-
Value = Struct.new(:value, :timestamp, :expires_at) do
|
78
|
-
def expired?
|
79
|
-
return false if expires_at.nil?
|
80
|
-
|
81
|
-
Time.now > expires_at
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
attr_reader :cache
|
86
|
-
end
|
87
|
-
end
|