htm 0.0.14 → 0.0.17
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/.envrc +1 -0
- data/CHANGELOG.md +100 -0
- data/README.md +107 -1412
- data/bin/htm_mcp +31 -0
- data/config/database.yml +7 -4
- data/db/migrate/00003_create_file_sources.rb +5 -0
- data/db/migrate/00004_create_nodes.rb +17 -0
- data/db/migrate/00005_create_tags.rb +7 -0
- data/db/migrate/00006_create_node_tags.rb +2 -0
- data/db/migrate/00007_create_robot_nodes.rb +7 -0
- data/db/schema.sql +41 -29
- data/docs/api/yard/HTM/Configuration.md +54 -0
- data/docs/api/yard/HTM/Database.md +13 -10
- data/docs/api/yard/HTM/EmbeddingService.md +5 -1
- data/docs/api/yard/HTM/LongTermMemory.md +18 -277
- data/docs/api/yard/HTM/PropositionError.md +18 -0
- data/docs/api/yard/HTM/PropositionService.md +66 -0
- data/docs/api/yard/HTM/QueryCache.md +88 -0
- data/docs/api/yard/HTM/RobotGroup.md +481 -0
- data/docs/api/yard/HTM/SqlBuilder.md +108 -0
- data/docs/api/yard/HTM/TagService.md +4 -0
- data/docs/api/yard/HTM/Telemetry/NullInstrument.md +13 -0
- data/docs/api/yard/HTM/Telemetry/NullMeter.md +15 -0
- data/docs/api/yard/HTM/Telemetry.md +109 -0
- data/docs/api/yard/HTM/WorkingMemoryChannel.md +176 -0
- data/docs/api/yard/HTM.md +11 -23
- data/docs/api/yard/index.csv +102 -25
- data/docs/api/yard-reference.md +8 -0
- data/docs/assets/images/multi-provider-failover.svg +51 -0
- data/docs/assets/images/robot-group-architecture.svg +65 -0
- data/docs/database/README.md +3 -3
- data/docs/database/public.file_sources.svg +29 -21
- data/docs/database/public.node_tags.md +2 -0
- data/docs/database/public.node_tags.svg +53 -41
- data/docs/database/public.nodes.md +2 -0
- data/docs/database/public.nodes.svg +52 -40
- data/docs/database/public.robot_nodes.md +2 -0
- data/docs/database/public.robot_nodes.svg +30 -22
- data/docs/database/public.robots.svg +16 -12
- data/docs/database/public.tags.md +3 -0
- data/docs/database/public.tags.svg +41 -33
- data/docs/database/schema.json +66 -0
- data/docs/database/schema.svg +60 -48
- data/docs/development/index.md +13 -0
- data/docs/development/rake-tasks.md +1068 -0
- data/docs/getting-started/installation.md +31 -11
- data/docs/getting-started/quick-start.md +144 -155
- data/docs/guides/adding-memories.md +2 -3
- data/docs/guides/context-assembly.md +185 -184
- data/docs/guides/getting-started.md +154 -148
- data/docs/guides/index.md +7 -0
- data/docs/guides/long-term-memory.md +60 -92
- data/docs/guides/mcp-server.md +1052 -0
- data/docs/guides/multi-robot.md +249 -345
- data/docs/guides/recalling-memories.md +153 -163
- data/docs/guides/robot-groups.md +604 -0
- data/docs/guides/search-strategies.md +61 -58
- data/docs/guides/working-memory.md +103 -136
- data/docs/index.md +30 -26
- data/docs/multi_framework_support.md +2 -2
- data/examples/mcp_client.rb +2 -2
- data/examples/rails_app/.gitignore +2 -0
- data/examples/rails_app/Gemfile +22 -0
- data/examples/rails_app/Gemfile.lock +438 -0
- data/examples/rails_app/Procfile.dev +1 -0
- data/examples/rails_app/README.md +98 -0
- data/examples/rails_app/Rakefile +5 -0
- data/examples/rails_app/app/assets/stylesheets/application.css +83 -0
- data/examples/rails_app/app/assets/stylesheets/inter-font.css +6 -0
- data/examples/rails_app/app/controllers/application_controller.rb +19 -0
- data/examples/rails_app/app/controllers/dashboard_controller.rb +27 -0
- data/examples/rails_app/app/controllers/files_controller.rb +205 -0
- data/examples/rails_app/app/controllers/memories_controller.rb +102 -0
- data/examples/rails_app/app/controllers/robots_controller.rb +44 -0
- data/examples/rails_app/app/controllers/search_controller.rb +46 -0
- data/examples/rails_app/app/controllers/tags_controller.rb +30 -0
- data/examples/rails_app/app/javascript/application.js +4 -0
- data/examples/rails_app/app/javascript/controllers/application.js +9 -0
- data/examples/rails_app/app/javascript/controllers/index.js +6 -0
- data/examples/rails_app/app/views/dashboard/index.html.erb +123 -0
- data/examples/rails_app/app/views/files/index.html.erb +108 -0
- data/examples/rails_app/app/views/files/new.html.erb +321 -0
- data/examples/rails_app/app/views/files/show.html.erb +130 -0
- data/examples/rails_app/app/views/layouts/application.html.erb +124 -0
- data/examples/rails_app/app/views/memories/_memory_card.html.erb +51 -0
- data/examples/rails_app/app/views/memories/deleted.html.erb +62 -0
- data/examples/rails_app/app/views/memories/edit.html.erb +35 -0
- data/examples/rails_app/app/views/memories/index.html.erb +81 -0
- data/examples/rails_app/app/views/memories/new.html.erb +71 -0
- data/examples/rails_app/app/views/memories/show.html.erb +126 -0
- data/examples/rails_app/app/views/robots/index.html.erb +106 -0
- data/examples/rails_app/app/views/robots/new.html.erb +36 -0
- data/examples/rails_app/app/views/robots/show.html.erb +79 -0
- data/examples/rails_app/app/views/search/index.html.erb +184 -0
- data/examples/rails_app/app/views/shared/_navbar.html.erb +52 -0
- data/examples/rails_app/app/views/shared/_stat_card.html.erb +52 -0
- data/examples/rails_app/app/views/tags/index.html.erb +131 -0
- data/examples/rails_app/app/views/tags/show.html.erb +67 -0
- data/examples/rails_app/bin/dev +8 -0
- data/examples/rails_app/bin/rails +4 -0
- data/examples/rails_app/bin/rake +4 -0
- data/examples/rails_app/config/application.rb +33 -0
- data/examples/rails_app/config/boot.rb +5 -0
- data/examples/rails_app/config/database.yml +15 -0
- data/examples/rails_app/config/environment.rb +5 -0
- data/examples/rails_app/config/importmap.rb +7 -0
- data/examples/rails_app/config/routes.rb +38 -0
- data/examples/rails_app/config/tailwind.config.js +35 -0
- data/examples/rails_app/config.ru +5 -0
- data/examples/rails_app/log/.keep +0 -0
- data/examples/rails_app/tmp/local_secret.txt +1 -0
- data/examples/robot_groups/robot_worker.rb +1 -2
- data/examples/robot_groups/same_process.rb +1 -4
- data/lib/htm/active_record_config.rb +2 -5
- data/lib/htm/configuration.rb +35 -2
- data/lib/htm/database.rb +3 -6
- data/lib/htm/mcp/cli.rb +333 -0
- data/lib/htm/mcp/group_tools.rb +476 -0
- data/lib/htm/mcp/resources.rb +89 -0
- data/lib/htm/mcp/server.rb +98 -0
- data/lib/htm/mcp/tools.rb +488 -0
- data/lib/htm/models/file_source.rb +5 -3
- data/lib/htm/railtie.rb +0 -4
- data/lib/htm/robot_group.rb +721 -0
- data/lib/htm/tasks.rb +7 -4
- data/lib/htm/version.rb +1 -1
- data/lib/htm/working_memory_channel.rb +250 -0
- data/lib/htm.rb +2 -0
- data/lib/tasks/htm.rake +6 -9
- data/mkdocs.yml +2 -0
- metadata +75 -11
- data/bin/htm_mcp.rb +0 -621
- data/db/migrate/00009_add_working_memory_to_robot_nodes.rb +0 -12
- data/db/migrate/00010_add_soft_delete_to_associations.rb +0 -29
- data/db/migrate/00011_add_performance_indexes.rb +0 -21
- data/db/migrate/00012_add_tags_trigram_index.rb +0 -18
- data/db/migrate/00013_enable_lz4_compression.rb +0 -43
- data/examples/robot_groups/lib/robot_group.rb +0 -419
- data/examples/robot_groups/lib/working_memory_channel.rb +0 -140
data/lib/htm/tasks.rb
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
#
|
|
9
9
|
# This will make the following tasks available:
|
|
10
10
|
#
|
|
11
|
-
# Database tasks (all respect RAILS_ENV, default: development):
|
|
11
|
+
# Database tasks (all respect HTM_ENV/RAILS_ENV, default: development):
|
|
12
12
|
# rake htm:db:create # Create database if it doesn't exist
|
|
13
13
|
# rake htm:db:setup # Set up HTM database schema and run migrations
|
|
14
14
|
# rake htm:db:migrate # Run pending database migrations
|
|
@@ -20,10 +20,13 @@
|
|
|
20
20
|
# rake htm:db:drop # Drop all HTM tables (destructive!)
|
|
21
21
|
# rake htm:db:reset # Drop and recreate database (destructive!)
|
|
22
22
|
#
|
|
23
|
+
# Environment detection priority: HTM_ENV > RAILS_ENV > RACK_ENV > 'development'
|
|
24
|
+
#
|
|
23
25
|
# Examples:
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
26
|
+
# HTM_ENV=test rake htm:db:create # Create htm_test database
|
|
27
|
+
# HTM_ENV=test rake htm:db:setup # Setup test database with migrations
|
|
28
|
+
# HTM_ENV=test rake htm:db:drop # Drop test database
|
|
29
|
+
# RAILS_ENV=test rake htm:db:create # Also works (for Rails apps)
|
|
27
30
|
#
|
|
28
31
|
# Async job tasks:
|
|
29
32
|
# rake htm:jobs:stats # Show async job statistics
|
data/lib/htm/version.rb
CHANGED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# examples/robot_groups/lib/htm/working_memory_channel.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
class HTM
|
|
5
|
+
# Provides real-time synchronization of working memory changes across multiple
|
|
6
|
+
# robots using PostgreSQL LISTEN/NOTIFY pub/sub mechanism.
|
|
7
|
+
#
|
|
8
|
+
# This class enables distributed robots to maintain synchronized working memory
|
|
9
|
+
# by broadcasting change notifications through PostgreSQL channels. When one robot
|
|
10
|
+
# adds, evicts, or clears working memory, all other robots in the group receive
|
|
11
|
+
# immediate notification.
|
|
12
|
+
#
|
|
13
|
+
# @example Basic usage
|
|
14
|
+
# channel = HTM::WorkingMemoryChannel.new('support-team', db_config)
|
|
15
|
+
#
|
|
16
|
+
# # Subscribe to changes
|
|
17
|
+
# channel.on_change do |event, node_id, robot_id|
|
|
18
|
+
# case event
|
|
19
|
+
# when :added then puts "Node #{node_id} added by robot #{robot_id}"
|
|
20
|
+
# when :evicted then puts "Node #{node_id} evicted by robot #{robot_id}"
|
|
21
|
+
# when :cleared then puts "Working memory cleared by robot #{robot_id}"
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# # Start listening in background thread
|
|
26
|
+
# channel.start_listening
|
|
27
|
+
#
|
|
28
|
+
# # Publish a change
|
|
29
|
+
# channel.notify(:added, node_id: 123, robot_id: 456)
|
|
30
|
+
#
|
|
31
|
+
# # Cleanup when done
|
|
32
|
+
# channel.stop_listening
|
|
33
|
+
#
|
|
34
|
+
# @see HTM::RobotGroup Higher-level coordination using this channel
|
|
35
|
+
#
|
|
36
|
+
class WorkingMemoryChannel
|
|
37
|
+
# Prefix used for all PostgreSQL channel names
|
|
38
|
+
# @return [String]
|
|
39
|
+
CHANNEL_PREFIX = 'htm_wm'
|
|
40
|
+
|
|
41
|
+
# Number of notifications received since channel was created
|
|
42
|
+
# @return [Integer]
|
|
43
|
+
attr_reader :notifications_received
|
|
44
|
+
|
|
45
|
+
# Creates a new working memory channel for a robot group.
|
|
46
|
+
#
|
|
47
|
+
# The channel name is derived from the group name with non-alphanumeric
|
|
48
|
+
# characters replaced by underscores to ensure PostgreSQL compatibility.
|
|
49
|
+
#
|
|
50
|
+
# @param group_name [String] Name of the robot group (used to create unique channel)
|
|
51
|
+
# @param db_config [Hash] PostgreSQL connection configuration hash
|
|
52
|
+
# @option db_config [String] :host Database host
|
|
53
|
+
# @option db_config [Integer] :port Database port
|
|
54
|
+
# @option db_config [String] :dbname Database name
|
|
55
|
+
# @option db_config [String] :user Database user
|
|
56
|
+
# @option db_config [String] :password Database password (optional)
|
|
57
|
+
#
|
|
58
|
+
# @example
|
|
59
|
+
# db_config = { host: 'localhost', port: 5432, dbname: 'htm_dev', user: 'postgres' }
|
|
60
|
+
# channel = HTM::WorkingMemoryChannel.new('customer-support', db_config)
|
|
61
|
+
#
|
|
62
|
+
def initialize(group_name, db_config)
|
|
63
|
+
@group_name = group_name
|
|
64
|
+
@channel = "#{CHANNEL_PREFIX}_#{group_name.gsub(/[^a-z0-9_]/i, '_')}"
|
|
65
|
+
@db_config = db_config
|
|
66
|
+
@listeners = []
|
|
67
|
+
@listen_thread = nil
|
|
68
|
+
@stop_requested = false
|
|
69
|
+
@notifications_received = 0
|
|
70
|
+
@mutex = Mutex.new
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @!group Publishing
|
|
74
|
+
|
|
75
|
+
# Broadcasts a working memory change notification to all listeners.
|
|
76
|
+
#
|
|
77
|
+
# Uses PostgreSQL's pg_notify function to send a JSON payload containing
|
|
78
|
+
# the event type, affected node ID, originating robot ID, and timestamp.
|
|
79
|
+
#
|
|
80
|
+
# @param event [Symbol] Type of change (:added, :evicted, or :cleared)
|
|
81
|
+
# @param node_id [Integer, nil] ID of the affected node (nil for :cleared events)
|
|
82
|
+
# @param robot_id [Integer] ID of the robot that triggered the change
|
|
83
|
+
# @return [void]
|
|
84
|
+
#
|
|
85
|
+
# @example Notify that a node was added
|
|
86
|
+
# channel.notify(:added, node_id: 123, robot_id: 1)
|
|
87
|
+
#
|
|
88
|
+
# @example Notify that working memory was cleared
|
|
89
|
+
# channel.notify(:cleared, node_id: nil, robot_id: 1)
|
|
90
|
+
#
|
|
91
|
+
def notify(event, node_id:, robot_id:)
|
|
92
|
+
payload = {
|
|
93
|
+
event: event,
|
|
94
|
+
node_id: node_id,
|
|
95
|
+
robot_id: robot_id,
|
|
96
|
+
timestamp: Time.now.iso8601
|
|
97
|
+
}.to_json
|
|
98
|
+
|
|
99
|
+
with_connection do |conn|
|
|
100
|
+
conn.exec_params('SELECT pg_notify($1, $2)', [@channel, payload])
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @!endgroup
|
|
105
|
+
|
|
106
|
+
# @!group Subscribing
|
|
107
|
+
|
|
108
|
+
# Registers a callback to be invoked when working memory changes occur.
|
|
109
|
+
#
|
|
110
|
+
# Multiple callbacks can be registered; all will be called for each event.
|
|
111
|
+
# Callbacks are invoked synchronously within the listener thread.
|
|
112
|
+
#
|
|
113
|
+
# @yield [event, node_id, robot_id] Block called for each notification
|
|
114
|
+
# @yieldparam event [Symbol] Type of change (:added, :evicted, or :cleared)
|
|
115
|
+
# @yieldparam node_id [Integer, nil] ID of the affected node
|
|
116
|
+
# @yieldparam robot_id [Integer] ID of the robot that triggered the change
|
|
117
|
+
# @return [void]
|
|
118
|
+
#
|
|
119
|
+
# @example Register a change handler
|
|
120
|
+
# channel.on_change do |event, node_id, robot_id|
|
|
121
|
+
# puts "Received #{event} event for node #{node_id}"
|
|
122
|
+
# end
|
|
123
|
+
#
|
|
124
|
+
def on_change(&callback)
|
|
125
|
+
@mutex.synchronize { @listeners << callback }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Starts listening for notifications in a background thread.
|
|
129
|
+
#
|
|
130
|
+
# Creates a dedicated PostgreSQL connection that uses LISTEN to receive
|
|
131
|
+
# notifications. The thread polls every 0.5 seconds, allowing for clean
|
|
132
|
+
# shutdown via {#stop_listening}.
|
|
133
|
+
#
|
|
134
|
+
# @return [Thread] The background listener thread
|
|
135
|
+
#
|
|
136
|
+
# @example Start and verify listening
|
|
137
|
+
# thread = channel.start_listening
|
|
138
|
+
# puts "Listening: #{channel.listening?}" # => true
|
|
139
|
+
#
|
|
140
|
+
def start_listening
|
|
141
|
+
@stop_requested = false
|
|
142
|
+
@listen_thread = Thread.new do
|
|
143
|
+
listen_loop
|
|
144
|
+
end
|
|
145
|
+
@listen_thread.abort_on_exception = true
|
|
146
|
+
@listen_thread
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Stops the background listener thread.
|
|
150
|
+
#
|
|
151
|
+
# Signals the listener to stop, waits up to 0.5 seconds for clean exit,
|
|
152
|
+
# then forcefully terminates if still running. The PostgreSQL connection
|
|
153
|
+
# is closed automatically.
|
|
154
|
+
#
|
|
155
|
+
# @return [void]
|
|
156
|
+
#
|
|
157
|
+
# @example Clean shutdown
|
|
158
|
+
# channel.stop_listening
|
|
159
|
+
# puts "Listening: #{channel.listening?}" # => false
|
|
160
|
+
#
|
|
161
|
+
def stop_listening
|
|
162
|
+
@stop_requested = true
|
|
163
|
+
# Give the thread a moment to exit cleanly
|
|
164
|
+
@listen_thread&.join(0.5)
|
|
165
|
+
@listen_thread&.kill if @listen_thread&.alive?
|
|
166
|
+
@listen_thread = nil
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# @!endgroup
|
|
170
|
+
|
|
171
|
+
# @!group Status
|
|
172
|
+
|
|
173
|
+
# Checks if the listener thread is currently active.
|
|
174
|
+
#
|
|
175
|
+
# @return [Boolean] true if listening for notifications, false otherwise
|
|
176
|
+
#
|
|
177
|
+
# @example
|
|
178
|
+
# channel.start_listening
|
|
179
|
+
# channel.listening? # => true
|
|
180
|
+
# channel.stop_listening
|
|
181
|
+
# channel.listening? # => false
|
|
182
|
+
#
|
|
183
|
+
def listening?
|
|
184
|
+
@listen_thread&.alive? || false
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Returns the PostgreSQL channel name used for notifications.
|
|
188
|
+
#
|
|
189
|
+
# The channel name is derived from the group name with a prefix and
|
|
190
|
+
# sanitization of special characters.
|
|
191
|
+
#
|
|
192
|
+
# @return [String] The PostgreSQL LISTEN/NOTIFY channel name
|
|
193
|
+
#
|
|
194
|
+
# @example
|
|
195
|
+
# channel = HTM::WorkingMemoryChannel.new('my-group', db_config)
|
|
196
|
+
# channel.channel_name # => "htm_wm_my_group"
|
|
197
|
+
#
|
|
198
|
+
def channel_name
|
|
199
|
+
@channel
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# @!endgroup
|
|
203
|
+
|
|
204
|
+
private
|
|
205
|
+
|
|
206
|
+
def listen_loop
|
|
207
|
+
conn = PG.connect(@db_config)
|
|
208
|
+
conn.exec("LISTEN #{conn.escape_identifier(@channel)}")
|
|
209
|
+
|
|
210
|
+
until @stop_requested
|
|
211
|
+
# Wait for notification with timeout (allows checking @stop_requested)
|
|
212
|
+
conn.wait_for_notify(0.5) do |_channel, _pid, payload|
|
|
213
|
+
handle_notification(payload)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
rescue PG::Error => e
|
|
217
|
+
unless @stop_requested
|
|
218
|
+
HTM.logger.error "WorkingMemoryChannel error: #{e.message}"
|
|
219
|
+
sleep 1
|
|
220
|
+
retry
|
|
221
|
+
end
|
|
222
|
+
ensure
|
|
223
|
+
conn&.close
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def handle_notification(payload)
|
|
227
|
+
data = JSON.parse(payload, symbolize_names: true)
|
|
228
|
+
|
|
229
|
+
@mutex.synchronize do
|
|
230
|
+
@notifications_received += 1
|
|
231
|
+
@listeners.each do |callback|
|
|
232
|
+
callback.call(
|
|
233
|
+
data[:event].to_sym,
|
|
234
|
+
data[:node_id],
|
|
235
|
+
data[:robot_id]
|
|
236
|
+
)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
rescue JSON::ParserError => e
|
|
240
|
+
HTM.logger.error "Invalid notification payload: #{e.message}"
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def with_connection
|
|
244
|
+
conn = PG.connect(@db_config)
|
|
245
|
+
yield conn
|
|
246
|
+
ensure
|
|
247
|
+
conn&.close
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
data/lib/htm.rb
CHANGED
|
@@ -21,6 +21,8 @@ require_relative "htm/loaders/markdown_chunker"
|
|
|
21
21
|
require_relative "htm/loaders/markdown_loader"
|
|
22
22
|
require_relative "htm/observability"
|
|
23
23
|
require_relative "htm/telemetry"
|
|
24
|
+
require_relative "htm/working_memory_channel"
|
|
25
|
+
require_relative "htm/robot_group"
|
|
24
26
|
|
|
25
27
|
require "pg"
|
|
26
28
|
require "securerandom"
|
data/lib/tasks/htm.rake
CHANGED
|
@@ -68,14 +68,13 @@ namespace :htm do
|
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
desc "Verify database connection (respects RAILS_ENV)"
|
|
71
|
+
desc "Verify database connection (respects HTM_ENV/RAILS_ENV)"
|
|
72
72
|
task :verify do
|
|
73
73
|
require 'htm'
|
|
74
74
|
|
|
75
|
-
env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
|
76
75
|
config = HTM::ActiveRecordConfig.load_database_config
|
|
77
76
|
|
|
78
|
-
puts "Verifying HTM database connection (#{env})..."
|
|
77
|
+
puts "Verifying HTM database connection (#{HTM.env})..."
|
|
79
78
|
puts " Host: #{config[:host]}"
|
|
80
79
|
puts " Port: #{config[:port]}"
|
|
81
80
|
puts " Database: #{config[:database]}"
|
|
@@ -107,14 +106,13 @@ namespace :htm do
|
|
|
107
106
|
end
|
|
108
107
|
end
|
|
109
108
|
|
|
110
|
-
desc "Open PostgreSQL console (respects RAILS_ENV)"
|
|
109
|
+
desc "Open PostgreSQL console (respects HTM_ENV/RAILS_ENV)"
|
|
111
110
|
task :console do
|
|
112
111
|
require 'htm'
|
|
113
112
|
|
|
114
|
-
env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
|
115
113
|
config = HTM::ActiveRecordConfig.load_database_config
|
|
116
114
|
|
|
117
|
-
puts "Connecting to #{config[:database]} (#{env})..."
|
|
115
|
+
puts "Connecting to #{config[:database]} (#{HTM.env})..."
|
|
118
116
|
exec "psql", "-h", config[:host],
|
|
119
117
|
"-p", config[:port].to_s,
|
|
120
118
|
"-U", config[:username],
|
|
@@ -416,15 +414,14 @@ namespace :htm do
|
|
|
416
414
|
end
|
|
417
415
|
end
|
|
418
416
|
|
|
419
|
-
desc "Create database if it doesn't exist (respects RAILS_ENV)"
|
|
417
|
+
desc "Create database if it doesn't exist (respects HTM_ENV/RAILS_ENV)"
|
|
420
418
|
task :create do
|
|
421
419
|
require 'htm'
|
|
422
420
|
|
|
423
|
-
env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
|
424
421
|
config = HTM::ActiveRecordConfig.load_database_config
|
|
425
422
|
db_name = config[:database]
|
|
426
423
|
|
|
427
|
-
puts "Creating database: #{db_name} (#{env})"
|
|
424
|
+
puts "Creating database: #{db_name} (#{HTM.env})"
|
|
428
425
|
|
|
429
426
|
admin_config = config.dup
|
|
430
427
|
admin_config[:database] = 'postgres'
|
data/mkdocs.yml
CHANGED
|
@@ -199,6 +199,7 @@ nav:
|
|
|
199
199
|
- Multi-Robot Usage: guides/multi-robot.md
|
|
200
200
|
- Search Strategies: guides/search-strategies.md
|
|
201
201
|
- Context Assembly: guides/context-assembly.md
|
|
202
|
+
- MCP Server: guides/mcp-server.md
|
|
202
203
|
- API Reference:
|
|
203
204
|
- api/index.md
|
|
204
205
|
- HTM Class: api/htm.md
|
|
@@ -245,6 +246,7 @@ nav:
|
|
|
245
246
|
- Setup: development/setup.md
|
|
246
247
|
- Testing: development/testing.md
|
|
247
248
|
- Contributing: development/contributing.md
|
|
249
|
+
- Rake Tasks Reference: development/rake-tasks.md
|
|
248
250
|
- Database Schema: development/schema.md
|
|
249
251
|
- Database Tables:
|
|
250
252
|
- database/README.md
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: htm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.17
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dewayne VanHoozer
|
|
@@ -256,7 +256,7 @@ description: |
|
|
|
256
256
|
email:
|
|
257
257
|
- dvanhoozer@gmail.com
|
|
258
258
|
executables:
|
|
259
|
-
- htm_mcp
|
|
259
|
+
- htm_mcp
|
|
260
260
|
extensions: []
|
|
261
261
|
extra_rdoc_files: []
|
|
262
262
|
files:
|
|
@@ -290,7 +290,7 @@ files:
|
|
|
290
290
|
- README.md
|
|
291
291
|
- Rakefile
|
|
292
292
|
- SETUP.md
|
|
293
|
-
- bin/htm_mcp
|
|
293
|
+
- bin/htm_mcp
|
|
294
294
|
- config/database.yml
|
|
295
295
|
- db/migrate/00001_enable_extensions.rb
|
|
296
296
|
- db/migrate/00002_create_robots.rb
|
|
@@ -299,11 +299,6 @@ files:
|
|
|
299
299
|
- db/migrate/00005_create_tags.rb
|
|
300
300
|
- db/migrate/00006_create_node_tags.rb
|
|
301
301
|
- db/migrate/00007_create_robot_nodes.rb
|
|
302
|
-
- db/migrate/00009_add_working_memory_to_robot_nodes.rb
|
|
303
|
-
- db/migrate/00010_add_soft_delete_to_associations.rb
|
|
304
|
-
- db/migrate/00011_add_performance_indexes.rb
|
|
305
|
-
- db/migrate/00012_add_tags_trigram_index.rb
|
|
306
|
-
- db/migrate/00013_enable_lz4_compression.rb
|
|
307
302
|
- db/schema.sql
|
|
308
303
|
- db/seed_data/README.md
|
|
309
304
|
- db/seed_data/presidents.md
|
|
@@ -331,17 +326,26 @@ files:
|
|
|
331
326
|
- docs/api/yard/HTM/LongTermMemory.md
|
|
332
327
|
- docs/api/yard/HTM/NotFoundError.md
|
|
333
328
|
- docs/api/yard/HTM/Observability.md
|
|
329
|
+
- docs/api/yard/HTM/PropositionError.md
|
|
330
|
+
- docs/api/yard/HTM/PropositionService.md
|
|
331
|
+
- docs/api/yard/HTM/QueryCache.md
|
|
334
332
|
- docs/api/yard/HTM/QueryTimeoutError.md
|
|
335
333
|
- docs/api/yard/HTM/Railtie.md
|
|
336
334
|
- docs/api/yard/HTM/ResourceExhaustedError.md
|
|
335
|
+
- docs/api/yard/HTM/RobotGroup.md
|
|
336
|
+
- docs/api/yard/HTM/SqlBuilder.md
|
|
337
337
|
- docs/api/yard/HTM/TagError.md
|
|
338
338
|
- docs/api/yard/HTM/TagService.md
|
|
339
|
+
- docs/api/yard/HTM/Telemetry.md
|
|
340
|
+
- docs/api/yard/HTM/Telemetry/NullInstrument.md
|
|
341
|
+
- docs/api/yard/HTM/Telemetry/NullMeter.md
|
|
339
342
|
- docs/api/yard/HTM/Timeframe.md
|
|
340
343
|
- docs/api/yard/HTM/Timeframe/Result.md
|
|
341
344
|
- docs/api/yard/HTM/TimeframeExtractor.md
|
|
342
345
|
- docs/api/yard/HTM/TimeframeExtractor/Result.md
|
|
343
346
|
- docs/api/yard/HTM/ValidationError.md
|
|
344
347
|
- docs/api/yard/HTM/WorkingMemory.md
|
|
348
|
+
- docs/api/yard/HTM/WorkingMemoryChannel.md
|
|
345
349
|
- docs/api/yard/index.csv
|
|
346
350
|
- docs/architecture/adrs/001-postgresql-timescaledb.md
|
|
347
351
|
- docs/architecture/adrs/002-two-tier-memory.md
|
|
@@ -381,7 +385,9 @@ files:
|
|
|
381
385
|
- docs/assets/images/htm-working-memory-architecture.svg
|
|
382
386
|
- docs/assets/images/htm.jpg
|
|
383
387
|
- docs/assets/images/htm_demo.gif
|
|
388
|
+
- docs/assets/images/multi-provider-failover.svg
|
|
384
389
|
- docs/assets/images/project-structure.svg
|
|
390
|
+
- docs/assets/images/robot-group-architecture.svg
|
|
385
391
|
- docs/assets/images/test-directory-structure.svg
|
|
386
392
|
- docs/assets/js/mathjax.js
|
|
387
393
|
- docs/assets/videos/htm_video.mp4
|
|
@@ -419,6 +425,7 @@ files:
|
|
|
419
425
|
- docs/database_rake_tasks.md
|
|
420
426
|
- docs/development/contributing.md
|
|
421
427
|
- docs/development/index.md
|
|
428
|
+
- docs/development/rake-tasks.md
|
|
422
429
|
- docs/development/schema.md
|
|
423
430
|
- docs/development/setup.md
|
|
424
431
|
- docs/development/testing.md
|
|
@@ -430,8 +437,10 @@ files:
|
|
|
430
437
|
- docs/guides/getting-started.md
|
|
431
438
|
- docs/guides/index.md
|
|
432
439
|
- docs/guides/long-term-memory.md
|
|
440
|
+
- docs/guides/mcp-server.md
|
|
433
441
|
- docs/guides/multi-robot.md
|
|
434
442
|
- docs/guides/recalling-memories.md
|
|
443
|
+
- docs/guides/robot-groups.md
|
|
435
444
|
- docs/guides/search-strategies.md
|
|
436
445
|
- docs/guides/working-memory.md
|
|
437
446
|
- docs/images/htm-er-diagram.svg
|
|
@@ -450,8 +459,56 @@ files:
|
|
|
450
459
|
- examples/example_app/app.rb
|
|
451
460
|
- examples/file_loader_usage.rb
|
|
452
461
|
- examples/mcp_client.rb
|
|
453
|
-
- examples/
|
|
454
|
-
- examples/
|
|
462
|
+
- examples/rails_app/.gitignore
|
|
463
|
+
- examples/rails_app/Gemfile
|
|
464
|
+
- examples/rails_app/Gemfile.lock
|
|
465
|
+
- examples/rails_app/Procfile.dev
|
|
466
|
+
- examples/rails_app/README.md
|
|
467
|
+
- examples/rails_app/Rakefile
|
|
468
|
+
- examples/rails_app/app/assets/stylesheets/application.css
|
|
469
|
+
- examples/rails_app/app/assets/stylesheets/inter-font.css
|
|
470
|
+
- examples/rails_app/app/controllers/application_controller.rb
|
|
471
|
+
- examples/rails_app/app/controllers/dashboard_controller.rb
|
|
472
|
+
- examples/rails_app/app/controllers/files_controller.rb
|
|
473
|
+
- examples/rails_app/app/controllers/memories_controller.rb
|
|
474
|
+
- examples/rails_app/app/controllers/robots_controller.rb
|
|
475
|
+
- examples/rails_app/app/controllers/search_controller.rb
|
|
476
|
+
- examples/rails_app/app/controllers/tags_controller.rb
|
|
477
|
+
- examples/rails_app/app/javascript/application.js
|
|
478
|
+
- examples/rails_app/app/javascript/controllers/application.js
|
|
479
|
+
- examples/rails_app/app/javascript/controllers/index.js
|
|
480
|
+
- examples/rails_app/app/views/dashboard/index.html.erb
|
|
481
|
+
- examples/rails_app/app/views/files/index.html.erb
|
|
482
|
+
- examples/rails_app/app/views/files/new.html.erb
|
|
483
|
+
- examples/rails_app/app/views/files/show.html.erb
|
|
484
|
+
- examples/rails_app/app/views/layouts/application.html.erb
|
|
485
|
+
- examples/rails_app/app/views/memories/_memory_card.html.erb
|
|
486
|
+
- examples/rails_app/app/views/memories/deleted.html.erb
|
|
487
|
+
- examples/rails_app/app/views/memories/edit.html.erb
|
|
488
|
+
- examples/rails_app/app/views/memories/index.html.erb
|
|
489
|
+
- examples/rails_app/app/views/memories/new.html.erb
|
|
490
|
+
- examples/rails_app/app/views/memories/show.html.erb
|
|
491
|
+
- examples/rails_app/app/views/robots/index.html.erb
|
|
492
|
+
- examples/rails_app/app/views/robots/new.html.erb
|
|
493
|
+
- examples/rails_app/app/views/robots/show.html.erb
|
|
494
|
+
- examples/rails_app/app/views/search/index.html.erb
|
|
495
|
+
- examples/rails_app/app/views/shared/_navbar.html.erb
|
|
496
|
+
- examples/rails_app/app/views/shared/_stat_card.html.erb
|
|
497
|
+
- examples/rails_app/app/views/tags/index.html.erb
|
|
498
|
+
- examples/rails_app/app/views/tags/show.html.erb
|
|
499
|
+
- examples/rails_app/bin/dev
|
|
500
|
+
- examples/rails_app/bin/rails
|
|
501
|
+
- examples/rails_app/bin/rake
|
|
502
|
+
- examples/rails_app/config.ru
|
|
503
|
+
- examples/rails_app/config/application.rb
|
|
504
|
+
- examples/rails_app/config/boot.rb
|
|
505
|
+
- examples/rails_app/config/database.yml
|
|
506
|
+
- examples/rails_app/config/environment.rb
|
|
507
|
+
- examples/rails_app/config/importmap.rb
|
|
508
|
+
- examples/rails_app/config/routes.rb
|
|
509
|
+
- examples/rails_app/config/tailwind.config.js
|
|
510
|
+
- examples/rails_app/log/.keep
|
|
511
|
+
- examples/rails_app/tmp/local_secret.txt
|
|
455
512
|
- examples/robot_groups/multi_process.rb
|
|
456
513
|
- examples/robot_groups/robot_worker.rb
|
|
457
514
|
- examples/robot_groups/same_process.rb
|
|
@@ -485,6 +542,11 @@ files:
|
|
|
485
542
|
- lib/htm/long_term_memory/robot_operations.rb
|
|
486
543
|
- lib/htm/long_term_memory/tag_operations.rb
|
|
487
544
|
- lib/htm/long_term_memory/vector_search.rb
|
|
545
|
+
- lib/htm/mcp/cli.rb
|
|
546
|
+
- lib/htm/mcp/group_tools.rb
|
|
547
|
+
- lib/htm/mcp/resources.rb
|
|
548
|
+
- lib/htm/mcp/server.rb
|
|
549
|
+
- lib/htm/mcp/tools.rb
|
|
488
550
|
- lib/htm/models/file_source.rb
|
|
489
551
|
- lib/htm/models/node.rb
|
|
490
552
|
- lib/htm/models/node_tag.rb
|
|
@@ -495,6 +557,7 @@ files:
|
|
|
495
557
|
- lib/htm/proposition_service.rb
|
|
496
558
|
- lib/htm/query_cache.rb
|
|
497
559
|
- lib/htm/railtie.rb
|
|
560
|
+
- lib/htm/robot_group.rb
|
|
498
561
|
- lib/htm/sql_builder.rb
|
|
499
562
|
- lib/htm/tag_service.rb
|
|
500
563
|
- lib/htm/tasks.rb
|
|
@@ -503,6 +566,7 @@ files:
|
|
|
503
566
|
- lib/htm/timeframe_extractor.rb
|
|
504
567
|
- lib/htm/version.rb
|
|
505
568
|
- lib/htm/working_memory.rb
|
|
569
|
+
- lib/htm/working_memory_channel.rb
|
|
506
570
|
- lib/tasks/db.rake
|
|
507
571
|
- lib/tasks/doc.rake
|
|
508
572
|
- lib/tasks/files.rake
|
|
@@ -532,7 +596,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
532
596
|
- !ruby/object:Gem::Version
|
|
533
597
|
version: '0'
|
|
534
598
|
requirements: []
|
|
535
|
-
rubygems_version: 4.0.
|
|
599
|
+
rubygems_version: 4.0.1
|
|
536
600
|
specification_version: 4
|
|
537
601
|
summary: Hierarchical Temporal Memory for LLM robots
|
|
538
602
|
test_files: []
|