activematrix 0.0.0 → 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/{matrix_sdk → active_matrix}/api.rb +18 -22
- data/lib/{matrix_sdk → active_matrix}/bot/base.rb +42 -39
- data/lib/{matrix_sdk → active_matrix}/bot/main.rb +4 -5
- data/lib/active_matrix/bot/multi_instance_base.rb +189 -0
- data/lib/active_matrix/bot.rb +7 -0
- data/lib/{matrix_sdk → active_matrix}/client.rb +21 -34
- data/lib/active_matrix/client_pool.rb +194 -0
- data/lib/{matrix_sdk → active_matrix}/errors.rb +4 -4
- data/lib/active_matrix/event_router.rb +215 -0
- data/lib/active_matrix/logging.rb +56 -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/{matrix_sdk → active_matrix}/mxid.rb +2 -2
- data/lib/{matrix_sdk → active_matrix}/protocols/as.rb +1 -1
- data/lib/{matrix_sdk → active_matrix}/protocols/cs.rb +6 -8
- data/lib/{matrix_sdk → active_matrix}/protocols/is.rb +1 -1
- data/lib/{matrix_sdk → active_matrix}/protocols/msc.rb +6 -8
- data/lib/{matrix_sdk → active_matrix}/protocols/ss.rb +2 -2
- data/lib/active_matrix/railtie.rb +18 -0
- data/lib/{matrix_sdk → active_matrix}/response.rb +2 -2
- data/lib/{matrix_sdk → active_matrix}/room.rb +148 -72
- data/lib/{matrix_sdk → active_matrix}/rooms/space.rb +3 -7
- data/lib/{matrix_sdk → active_matrix}/user.rb +23 -15
- data/lib/active_matrix/util/account_data_cache.rb +129 -0
- data/lib/active_matrix/util/cacheable.rb +73 -0
- data/lib/{matrix_sdk → active_matrix}/util/events.rb +8 -8
- data/lib/{matrix_sdk → active_matrix}/util/extensions.rb +6 -15
- data/lib/active_matrix/util/state_event_cache.rb +167 -0
- data/lib/{matrix_sdk → active_matrix}/util/uri.rb +4 -4
- data/lib/active_matrix/version.rb +5 -0
- data/lib/active_matrix.rb +81 -0
- 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 +168 -30
- data/lib/matrix_sdk/bot.rb +0 -4
- data/lib/matrix_sdk/util/account_data_cache.rb +0 -91
- data/lib/matrix_sdk/util/state_event_cache.rb +0 -92
- data/lib/matrix_sdk/util/tinycache.rb +0 -140
- data/lib/matrix_sdk/util/tinycache_adapter.rb +0 -87
- data/lib/matrix_sdk/version.rb +0 -5
- data/lib/matrix_sdk.rb +0 -75
@@ -0,0 +1,153 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module ActiveMatrix
|
6
|
+
module Memory
|
7
|
+
# Global memory storage accessible to all agents
|
8
|
+
class GlobalMemory < Base
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
# Get a value from global memory
|
12
|
+
def get(key)
|
13
|
+
fetch_with_cache(key) do
|
14
|
+
return nil unless defined?(::GlobalMemory)
|
15
|
+
|
16
|
+
::GlobalMemory.get(key)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set a value in global memory
|
21
|
+
def set(key, value, category: nil, expires_in: nil, public_read: true, public_write: false)
|
22
|
+
return false unless defined?(::GlobalMemory)
|
23
|
+
|
24
|
+
write_through(key, value, expires_in: expires_in) do
|
25
|
+
::GlobalMemory.set(key, value,
|
26
|
+
category: category,
|
27
|
+
expires_in: expires_in,
|
28
|
+
public_read: public_read,
|
29
|
+
public_write: public_write)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Check if a key exists
|
34
|
+
def exists?(key)
|
35
|
+
return false unless defined?(::GlobalMemory)
|
36
|
+
|
37
|
+
if @cache_enabled && Rails.cache.exist?(cache_key(key))
|
38
|
+
true
|
39
|
+
else
|
40
|
+
::GlobalMemory.active.exists?(key: key)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Delete a key
|
45
|
+
def delete(key)
|
46
|
+
return false unless defined?(::GlobalMemory)
|
47
|
+
|
48
|
+
delete_through(key) do
|
49
|
+
::GlobalMemory.where(key: key).destroy_all.any?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get all keys in a category
|
54
|
+
def keys(category: nil)
|
55
|
+
return [] unless defined?(::GlobalMemory)
|
56
|
+
|
57
|
+
scope = ::GlobalMemory.active
|
58
|
+
scope = scope.by_category(category) if category
|
59
|
+
scope.pluck(:key)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Get all values in a category
|
63
|
+
def by_category(category)
|
64
|
+
return {} unless defined?(::GlobalMemory)
|
65
|
+
|
66
|
+
::GlobalMemory.active.by_category(category).pluck(:key, :value).to_h
|
67
|
+
end
|
68
|
+
|
69
|
+
# Check if readable by agent
|
70
|
+
def readable?(key, agent = nil)
|
71
|
+
return false unless defined?(::GlobalMemory)
|
72
|
+
|
73
|
+
memory = ::GlobalMemory.find_by(key: key)
|
74
|
+
memory&.readable_by?(agent)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Check if writable by agent
|
78
|
+
def writable?(key, agent = nil)
|
79
|
+
return false unless defined?(::GlobalMemory)
|
80
|
+
|
81
|
+
memory = ::GlobalMemory.find_by(key: key)
|
82
|
+
memory&.writable_by?(agent)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Get with permission check
|
86
|
+
def get_for_agent(key, agent)
|
87
|
+
return nil unless readable?(key, agent)
|
88
|
+
|
89
|
+
get(key)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Set with permission check
|
93
|
+
def set_for_agent(key, value, agent, **)
|
94
|
+
# Allow creating new keys or updating writable ones
|
95
|
+
memory = ::GlobalMemory.find_by(key: key)
|
96
|
+
return false if memory && !memory.writable_by?(agent)
|
97
|
+
|
98
|
+
set(key, value, **)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Remember something globally
|
102
|
+
def remember(key, **)
|
103
|
+
value = get(key)
|
104
|
+
return value if value.present?
|
105
|
+
|
106
|
+
value = yield
|
107
|
+
set(key, value, **) if value.present?
|
108
|
+
value
|
109
|
+
end
|
110
|
+
|
111
|
+
# Broadcast a value to all agents
|
112
|
+
def broadcast(key, value, expires_in: 5.minutes)
|
113
|
+
set(key, value, category: 'broadcast', expires_in: expires_in, public_read: true)
|
114
|
+
|
115
|
+
# Notify all agents if event router is available
|
116
|
+
if defined?(EventRouter)
|
117
|
+
EventRouter.instance.broadcast_event({
|
118
|
+
type: 'global_memory.broadcast',
|
119
|
+
key: key,
|
120
|
+
value: value
|
121
|
+
})
|
122
|
+
end
|
123
|
+
|
124
|
+
true
|
125
|
+
end
|
126
|
+
|
127
|
+
# Share data between specific agents
|
128
|
+
def share(key, value, agent_names, expires_in: nil)
|
129
|
+
set(key, {
|
130
|
+
value: value,
|
131
|
+
allowed_agents: agent_names
|
132
|
+
}, category: 'shared', expires_in: expires_in, public_read: false)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Get shared data if allowed
|
136
|
+
def get_shared(key, agent)
|
137
|
+
data = get(key)
|
138
|
+
return nil unless data.is_a?(Hash) && data['allowed_agents']
|
139
|
+
|
140
|
+
allowed = data['allowed_agents']
|
141
|
+
return unless allowed.include?(agent.name) || allowed.include?('*')
|
142
|
+
|
143
|
+
data['value']
|
144
|
+
end
|
145
|
+
|
146
|
+
protected
|
147
|
+
|
148
|
+
def cache_key(key)
|
149
|
+
"global/#{key}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveMatrix
|
4
|
+
# Memory system for multi-agent architecture
|
5
|
+
module Memory
|
6
|
+
autoload :AgentMemory, 'active_matrix/memory/agent_memory'
|
7
|
+
autoload :ConversationMemory, 'active_matrix/memory/conversation_memory'
|
8
|
+
autoload :GlobalMemory, 'active_matrix/memory/global_memory'
|
9
|
+
autoload :Base, 'active_matrix/memory/base'
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Get memory interface for an agent
|
13
|
+
def for_agent(agent)
|
14
|
+
AgentMemory.new(agent)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Get conversation memory for agent and user
|
18
|
+
def for_conversation(agent, user_id, room_id)
|
19
|
+
ConversationMemory.new(agent, user_id, room_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Access global memory
|
23
|
+
def global
|
24
|
+
GlobalMemory.instance
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module ActiveMatrix
|
4
4
|
class MXID
|
5
5
|
attr_accessor :sigil, :localpart, :domain, :port
|
6
6
|
|
@@ -82,7 +82,7 @@ module MatrixSdk
|
|
82
82
|
# Check if the ID is of a room
|
83
83
|
# @return [Boolean] if the ID is of the room_id or room_alias types
|
84
84
|
def room?
|
85
|
-
|
85
|
+
%i[room_id room_alias].include?(type)
|
86
86
|
end
|
87
87
|
|
88
88
|
# Check if the ID is of a event
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# rubocop:disable Metrics/ModuleLength
|
4
|
-
module
|
4
|
+
module ActiveMatrix::Protocols::CS
|
5
5
|
# Gets the available client API versions
|
6
6
|
# @return [Array]
|
7
7
|
#
|
@@ -12,7 +12,7 @@ module MatrixSdk::Protocols::CS
|
|
12
12
|
# # => 'latest'
|
13
13
|
def client_api_versions
|
14
14
|
(@client_api_versions ||= request(:get, :client, '/versions')).versions.tap do |vers|
|
15
|
-
vers.instance_eval <<-
|
15
|
+
vers.instance_eval <<-CODE, __FILE__, __LINE__ + 1
|
16
16
|
if !respond_to? :latest
|
17
17
|
def latest
|
18
18
|
last
|
@@ -32,7 +32,7 @@ module MatrixSdk::Protocols::CS
|
|
32
32
|
# # => true
|
33
33
|
def client_api_unstable_features
|
34
34
|
(@client_api_versions ||= request(:get, :client, '/versions')).unstable_features.tap do |vers|
|
35
|
-
vers.instance_eval <<-
|
35
|
+
vers.instance_eval <<-CODE, __FILE__, __LINE__ + 1
|
36
36
|
def has?(feature)
|
37
37
|
feature = feature.to_s.to_sym unless feature.is_a? Symbol
|
38
38
|
fetch(feature, nil)
|
@@ -68,9 +68,7 @@ module MatrixSdk::Protocols::CS
|
|
68
68
|
# @see https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-sync
|
69
69
|
# For more information on the parameters and what they mean
|
70
70
|
def sync(timeout: 30.0, **params)
|
71
|
-
query = params.
|
72
|
-
%i[since filter full_state set_presence].include? k
|
73
|
-
end
|
71
|
+
query = params.slice(:since, :filter, :full_state, :set_presence)
|
74
72
|
|
75
73
|
query[:timeout] = (timeout * 1000).to_i if timeout
|
76
74
|
query[:timeout] = params.delete(:timeout_ms).to_i if params.key? :timeout_ms
|
@@ -198,7 +196,7 @@ module MatrixSdk::Protocols::CS
|
|
198
196
|
|
199
197
|
data = {
|
200
198
|
type: login_type,
|
201
|
-
initial_device_display_name: params.delete(:initial_device_display_name) {
|
199
|
+
initial_device_display_name: params.delete(:initial_device_display_name) { ActiveMatrix::Api::USER_AGENT }
|
202
200
|
}.merge params
|
203
201
|
data[:device_id] = device_id if device_id
|
204
202
|
|
@@ -785,7 +783,7 @@ module MatrixSdk::Protocols::CS
|
|
785
783
|
state_type = ERB::Util.url_encode state_type.to_s
|
786
784
|
key = ERB::Util.url_encode key.to_s
|
787
785
|
|
788
|
-
request(:get, client_api_latest, "/rooms/#{room_id}/state/#{state_type}#{
|
786
|
+
request(:get, client_api_latest, "/rooms/#{room_id}/state/#{state_type}#{"/#{key}" unless key.empty?}", query: query)
|
789
787
|
end
|
790
788
|
|
791
789
|
# Retrieves all current state objects from a room
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Preliminary support for unmerged MSCs (Matrix Spec Changes)
|
4
|
-
module
|
4
|
+
module ActiveMatrix::Protocols::MSC
|
5
5
|
def refresh_mscs
|
6
6
|
@msc = {}
|
7
7
|
end
|
@@ -9,12 +9,12 @@ module MatrixSdk::Protocols::MSC
|
|
9
9
|
# Check if there's support for MSC2108 - Sync over Server Sent Events
|
10
10
|
def msc2108?
|
11
11
|
@msc ||= {}
|
12
|
-
@msc[2108] ||=
|
12
|
+
@msc[2108] ||=
|
13
13
|
begin
|
14
14
|
request(:get, :client_r0, '/sync/sse', skip_auth: true, headers: { accept: 'text/event-stream' })
|
15
|
-
rescue
|
15
|
+
rescue ActiveMatrix::MatrixNotAuthorizedError # Returns 401 if implemented
|
16
16
|
true
|
17
|
-
rescue
|
17
|
+
rescue ActiveMatrix::MatrixRequestError
|
18
18
|
false
|
19
19
|
end
|
20
20
|
rescue StandardError => e
|
@@ -41,9 +41,7 @@ module MatrixSdk::Protocols::MSC
|
|
41
41
|
unless on_data.is_a?(Proc) && on_data.arity == 2
|
42
42
|
raise 'Needs to be logged in' unless access_token # TODO: Better error
|
43
43
|
|
44
|
-
query = params.
|
45
|
-
%i[filter full_state set_presence].include? k
|
46
|
-
end
|
44
|
+
query = params.slice(:filter, :full_state, :set_presence)
|
47
45
|
query[:user_id] = params.delete(:user_id) if protocol?(:AS) && params.key?(:user_id)
|
48
46
|
|
49
47
|
req = Net::HTTP::Get.new(homeserver.dup.tap do |u|
|
@@ -125,7 +123,7 @@ module MatrixSdk::Protocols::MSC
|
|
125
123
|
|
126
124
|
if %w[sync sync_error].include? event
|
127
125
|
data = JSON.parse(data, symbolize_names: true)
|
128
|
-
yield((
|
126
|
+
yield((ActiveMatrix::Response.new self, data), event: event, id: id)
|
129
127
|
elsif event
|
130
128
|
logger.info "MSC2108 : #{stream_id} : Received unknown event '#{event}'; #{data}"
|
131
129
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module ActiveMatrix::Protocols::SS
|
4
4
|
# Gets the server version
|
5
5
|
def server_version
|
6
|
-
|
6
|
+
ActiveMatrix::Response.new(self, request(:get, :federation_v1, '/version').server).tap do |resp|
|
7
7
|
resp.instance_eval <<-'CODE', __FILE__, __LINE__ + 1
|
8
8
|
def to_s
|
9
9
|
"#{name} #{version}"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/railtie'
|
4
|
+
|
5
|
+
module ActiveMatrix
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
initializer 'activematrix.configure_rails_initialization' do
|
8
|
+
# Configure Rails.logger as the default logger
|
9
|
+
ActiveMatrix.logger = Rails.logger
|
10
|
+
end
|
11
|
+
|
12
|
+
initializer 'activematrix.configure_cache' do
|
13
|
+
# Rails cache adapter is automatically used when Rails is detected
|
14
|
+
require 'active_matrix/util/rails_cache_adapter'
|
15
|
+
ActiveMatrix::Util::Tinycache.adapter = ActiveMatrix::Util::RailsCacheAdapter
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module ActiveMatrix
|
4
4
|
# An usability wrapper for API responses as an extended [Hash]
|
5
5
|
# All results can be read as both hash keys and as read-only methods on the key
|
6
6
|
#
|
@@ -39,7 +39,7 @@ module MatrixSdk
|
|
39
39
|
data.instance_variable_set(:@api, api)
|
40
40
|
|
41
41
|
data.select { |_k, v| v.is_a? Hash }
|
42
|
-
.
|
42
|
+
.each_value { |v| Response.new api, v }
|
43
43
|
|
44
44
|
data
|
45
45
|
end
|