htm 0.0.20 → 0.0.30

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.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -0
  3. data/Rakefile +104 -18
  4. data/db/migrate/00001_enable_extensions.rb +9 -5
  5. data/db/migrate/00002_create_robots.rb +18 -6
  6. data/db/migrate/00003_create_file_sources.rb +30 -17
  7. data/db/migrate/00004_create_nodes.rb +60 -48
  8. data/db/migrate/00005_create_tags.rb +24 -12
  9. data/db/migrate/00006_create_node_tags.rb +28 -13
  10. data/db/migrate/00007_create_robot_nodes.rb +40 -26
  11. data/db/schema.sql +17 -1
  12. data/db/seeds.rb +33 -33
  13. data/docs/database/naming-convention.md +244 -0
  14. data/docs/database_rake_tasks.md +31 -0
  15. data/docs/development/rake-tasks.md +80 -35
  16. data/docs/guides/mcp-server.md +70 -1
  17. data/examples/.envrc +6 -0
  18. data/examples/.gitignore +2 -0
  19. data/examples/00_create_examples_db.rb +94 -0
  20. data/examples/{basic_usage.rb → 01_basic_usage.rb} +12 -16
  21. data/examples/{custom_llm_configuration.rb → 03_custom_llm_configuration.rb} +13 -3
  22. data/examples/{file_loader_usage.rb → 04_file_loader_usage.rb} +11 -14
  23. data/examples/{timeframe_demo.rb → 05_timeframe_demo.rb} +10 -3
  24. data/examples/{example_app → 06_example_app}/app.rb +15 -15
  25. data/examples/{cli_app → 07_cli_app}/htm_cli.rb +15 -22
  26. data/examples/08_sinatra_app/Gemfile.lock +241 -0
  27. data/examples/{sinatra_app → 08_sinatra_app}/app.rb +19 -18
  28. data/examples/{mcp_client.rb → 09_mcp_client.rb} +5 -8
  29. data/examples/{telemetry → 10_telemetry}/SETUP_README.md +1 -1
  30. data/examples/{telemetry → 10_telemetry}/demo.rb +14 -10
  31. data/examples/11_robot_groups/README.md +335 -0
  32. data/examples/{robot_groups → 11_robot_groups/lib}/robot_worker.rb +17 -3
  33. data/examples/{robot_groups → 11_robot_groups}/multi_process.rb +9 -9
  34. data/examples/{robot_groups → 11_robot_groups}/same_process.rb +9 -12
  35. data/examples/{rails_app → 12_rails_app}/Gemfile +3 -0
  36. data/examples/{rails_app → 12_rails_app}/Gemfile.lock +87 -58
  37. data/examples/{rails_app → 12_rails_app}/app/controllers/dashboard_controller.rb +10 -6
  38. data/examples/{rails_app → 12_rails_app}/app/controllers/files_controller.rb +5 -5
  39. data/examples/{rails_app → 12_rails_app}/app/controllers/memories_controller.rb +11 -7
  40. data/examples/{rails_app → 12_rails_app}/app/controllers/robots_controller.rb +8 -8
  41. data/examples/12_rails_app/app/controllers/tags_controller.rb +36 -0
  42. data/examples/{rails_app → 12_rails_app}/app/views/dashboard/index.html.erb +2 -2
  43. data/examples/{rails_app → 12_rails_app}/app/views/files/new.html.erb +5 -2
  44. data/examples/{rails_app → 12_rails_app}/app/views/memories/_memory_card.html.erb +3 -3
  45. data/examples/{rails_app → 12_rails_app}/app/views/memories/deleted.html.erb +3 -3
  46. data/examples/{rails_app → 12_rails_app}/app/views/memories/edit.html.erb +3 -3
  47. data/examples/{rails_app → 12_rails_app}/app/views/memories/show.html.erb +4 -4
  48. data/examples/{rails_app → 12_rails_app}/app/views/robots/index.html.erb +2 -2
  49. data/examples/{rails_app → 12_rails_app}/app/views/robots/show.html.erb +4 -4
  50. data/examples/{rails_app → 12_rails_app}/app/views/search/index.html.erb +1 -1
  51. data/examples/{rails_app → 12_rails_app}/app/views/tags/index.html.erb +2 -2
  52. data/examples/{rails_app → 12_rails_app}/app/views/tags/show.html.erb +1 -1
  53. data/examples/12_rails_app/config/initializers/htm.rb +7 -0
  54. data/examples/12_rails_app/config/initializers/rack.rb +5 -0
  55. data/examples/README.md +230 -211
  56. data/examples/examples_helper.rb +138 -0
  57. data/lib/htm/config/builder.rb +167 -0
  58. data/lib/htm/config/database.rb +317 -0
  59. data/lib/htm/config/defaults.yml +37 -9
  60. data/lib/htm/config/section.rb +74 -0
  61. data/lib/htm/config/validator.rb +83 -0
  62. data/lib/htm/config.rb +64 -360
  63. data/lib/htm/database.rb +85 -127
  64. data/lib/htm/errors.rb +14 -0
  65. data/lib/htm/integrations/sinatra.rb +13 -44
  66. data/lib/htm/jobs/generate_embedding_job.rb +3 -4
  67. data/lib/htm/jobs/generate_propositions_job.rb +4 -5
  68. data/lib/htm/jobs/generate_tags_job.rb +16 -15
  69. data/lib/htm/loaders/defaults_loader.rb +23 -0
  70. data/lib/htm/loaders/markdown_loader.rb +17 -15
  71. data/lib/htm/loaders/xdg_config_loader.rb +9 -9
  72. data/lib/htm/long_term_memory/fulltext_search.rb +14 -14
  73. data/lib/htm/long_term_memory/hybrid_search.rb +396 -229
  74. data/lib/htm/long_term_memory/node_operations.rb +24 -23
  75. data/lib/htm/long_term_memory/relevance_scorer.rb +23 -20
  76. data/lib/htm/long_term_memory/robot_operations.rb +4 -4
  77. data/lib/htm/long_term_memory/tag_operations.rb +91 -77
  78. data/lib/htm/long_term_memory/vector_search.rb +4 -5
  79. data/lib/htm/long_term_memory.rb +13 -13
  80. data/lib/htm/mcp/cli.rb +115 -8
  81. data/lib/htm/mcp/resources.rb +4 -3
  82. data/lib/htm/mcp/server.rb +5 -4
  83. data/lib/htm/mcp/tools.rb +37 -28
  84. data/lib/htm/migration.rb +72 -0
  85. data/lib/htm/models/file_source.rb +52 -31
  86. data/lib/htm/models/node.rb +224 -108
  87. data/lib/htm/models/node_tag.rb +49 -28
  88. data/lib/htm/models/robot.rb +38 -27
  89. data/lib/htm/models/robot_node.rb +63 -35
  90. data/lib/htm/models/tag.rb +126 -123
  91. data/lib/htm/observability.rb +45 -41
  92. data/lib/htm/proposition_service.rb +76 -7
  93. data/lib/htm/railtie.rb +2 -2
  94. data/lib/htm/robot_group.rb +30 -18
  95. data/lib/htm/sequel_config.rb +215 -0
  96. data/lib/htm/sql_builder.rb +14 -16
  97. data/lib/htm/tag_service.rb +78 -0
  98. data/lib/htm/tasks.rb +3 -0
  99. data/lib/htm/version.rb +1 -1
  100. data/lib/htm/workflows/remember_workflow.rb +6 -5
  101. data/lib/htm.rb +26 -22
  102. data/lib/tasks/db.rake +0 -2
  103. data/lib/tasks/doc.rake +2 -2
  104. data/lib/tasks/files.rake +11 -18
  105. data/lib/tasks/htm.rake +190 -62
  106. data/lib/tasks/jobs.rake +179 -54
  107. data/lib/tasks/tags.rake +8 -13
  108. data/scripts/backfill_parent_tags.rb +376 -0
  109. data/scripts/normalize_plural_tags.rb +335 -0
  110. metadata +109 -80
  111. data/examples/rails_app/app/controllers/tags_controller.rb +0 -30
  112. data/examples/sinatra_app/Gemfile.lock +0 -166
  113. data/lib/htm/active_record_config.rb +0 -104
  114. /data/examples/{config_file_example → 02_config_file_example}/README.md +0 -0
  115. /data/examples/{config_file_example → 02_config_file_example}/config/htm.local.yml +0 -0
  116. /data/examples/{config_file_example → 02_config_file_example}/custom_config.yml +0 -0
  117. /data/examples/{config_file_example → 02_config_file_example}/show_config.rb +0 -0
  118. /data/examples/{example_app → 06_example_app}/Rakefile +0 -0
  119. /data/examples/{cli_app → 07_cli_app}/README.md +0 -0
  120. /data/examples/{sinatra_app → 08_sinatra_app}/Gemfile +0 -0
  121. /data/examples/{telemetry → 10_telemetry}/README.md +0 -0
  122. /data/examples/{telemetry → 10_telemetry}/grafana/dashboards/htm-metrics.json +0 -0
  123. /data/examples/{rails_app → 12_rails_app}/.gitignore +0 -0
  124. /data/examples/{rails_app → 12_rails_app}/Procfile.dev +0 -0
  125. /data/examples/{rails_app → 12_rails_app}/README.md +0 -0
  126. /data/examples/{rails_app → 12_rails_app}/Rakefile +0 -0
  127. /data/examples/{rails_app → 12_rails_app}/app/assets/stylesheets/application.css +0 -0
  128. /data/examples/{rails_app → 12_rails_app}/app/assets/stylesheets/inter-font.css +0 -0
  129. /data/examples/{rails_app → 12_rails_app}/app/controllers/application_controller.rb +0 -0
  130. /data/examples/{rails_app → 12_rails_app}/app/controllers/search_controller.rb +0 -0
  131. /data/examples/{rails_app → 12_rails_app}/app/javascript/application.js +0 -0
  132. /data/examples/{rails_app → 12_rails_app}/app/javascript/controllers/application.js +0 -0
  133. /data/examples/{rails_app → 12_rails_app}/app/javascript/controllers/index.js +0 -0
  134. /data/examples/{rails_app → 12_rails_app}/app/views/files/index.html.erb +0 -0
  135. /data/examples/{rails_app → 12_rails_app}/app/views/files/show.html.erb +0 -0
  136. /data/examples/{rails_app → 12_rails_app}/app/views/layouts/application.html.erb +0 -0
  137. /data/examples/{rails_app → 12_rails_app}/app/views/memories/index.html.erb +0 -0
  138. /data/examples/{rails_app → 12_rails_app}/app/views/memories/new.html.erb +0 -0
  139. /data/examples/{rails_app → 12_rails_app}/app/views/robots/new.html.erb +0 -0
  140. /data/examples/{rails_app → 12_rails_app}/app/views/shared/_navbar.html.erb +0 -0
  141. /data/examples/{rails_app → 12_rails_app}/app/views/shared/_stat_card.html.erb +0 -0
  142. /data/examples/{rails_app → 12_rails_app}/bin/dev +0 -0
  143. /data/examples/{rails_app → 12_rails_app}/bin/rails +0 -0
  144. /data/examples/{rails_app → 12_rails_app}/bin/rake +0 -0
  145. /data/examples/{rails_app → 12_rails_app}/config/application.rb +0 -0
  146. /data/examples/{rails_app → 12_rails_app}/config/boot.rb +0 -0
  147. /data/examples/{rails_app → 12_rails_app}/config/database.yml +0 -0
  148. /data/examples/{rails_app → 12_rails_app}/config/environment.rb +0 -0
  149. /data/examples/{rails_app → 12_rails_app}/config/importmap.rb +0 -0
  150. /data/examples/{rails_app → 12_rails_app}/config/routes.rb +0 -0
  151. /data/examples/{rails_app → 12_rails_app}/config/tailwind.config.js +0 -0
  152. /data/examples/{rails_app → 12_rails_app}/config.ru +0 -0
  153. /data/examples/{rails_app → 12_rails_app}/log/.keep +0 -0
  154. /data/examples/{rails_app → 12_rails_app}/tmp/local_secret.txt +0 -0
@@ -0,0 +1,241 @@
1
+ PATH
2
+ remote: ../..
3
+ specs:
4
+ htm (0.0.21)
5
+ activesupport
6
+ anyway_config (>= 2.6)
7
+ async (~> 2.0)
8
+ baran
9
+ chronic
10
+ fast-mcp
11
+ lru_redux
12
+ pg (>= 1.5.0)
13
+ ruby-progressbar
14
+ ruby_llm
15
+ sequel (>= 5.0)
16
+ sequel_pg
17
+ simple_flow
18
+ tiktoken_ruby
19
+
20
+ GEM
21
+ remote: https://rubygems.org/
22
+ specs:
23
+ activesupport (8.1.2)
24
+ base64
25
+ bigdecimal
26
+ concurrent-ruby (~> 1.0, >= 1.3.1)
27
+ connection_pool (>= 2.2.5)
28
+ drb
29
+ i18n (>= 1.6, < 2)
30
+ json
31
+ logger (>= 1.4.2)
32
+ minitest (>= 5.1)
33
+ securerandom (>= 0.3)
34
+ tzinfo (~> 2.0, >= 2.0.5)
35
+ uri (>= 0.13.1)
36
+ addressable (2.8.8)
37
+ public_suffix (>= 2.0.2, < 8.0)
38
+ anyway_config (2.7.2)
39
+ ruby-next-core (~> 1.0)
40
+ async (2.36.0)
41
+ console (~> 1.29)
42
+ fiber-annotation
43
+ io-event (~> 1.11)
44
+ metrics (~> 0.12)
45
+ traces (~> 0.18)
46
+ baran (0.2.1)
47
+ base64 (0.3.0)
48
+ bigdecimal (4.0.1)
49
+ chronic (0.10.2)
50
+ concurrent-ruby (1.3.6)
51
+ connection_pool (3.0.2)
52
+ console (1.34.2)
53
+ fiber-annotation
54
+ fiber-local (~> 1.1)
55
+ json
56
+ drb (2.2.3)
57
+ dry-configurable (1.3.0)
58
+ dry-core (~> 1.1)
59
+ zeitwerk (~> 2.6)
60
+ dry-core (1.2.0)
61
+ concurrent-ruby (~> 1.0)
62
+ logger
63
+ zeitwerk (~> 2.6)
64
+ dry-inflector (1.3.1)
65
+ dry-initializer (3.2.0)
66
+ dry-logic (1.6.0)
67
+ bigdecimal
68
+ concurrent-ruby (~> 1.0)
69
+ dry-core (~> 1.1)
70
+ zeitwerk (~> 2.6)
71
+ dry-schema (1.15.0)
72
+ concurrent-ruby (~> 1.0)
73
+ dry-configurable (~> 1.0, >= 1.0.1)
74
+ dry-core (~> 1.1)
75
+ dry-initializer (~> 3.2)
76
+ dry-logic (~> 1.6)
77
+ dry-types (~> 1.8)
78
+ zeitwerk (~> 2.6)
79
+ dry-types (1.9.0)
80
+ bigdecimal (>= 3.0)
81
+ concurrent-ruby (~> 1.0)
82
+ dry-core (~> 1.0)
83
+ dry-inflector (~> 1.0)
84
+ dry-logic (~> 1.4)
85
+ zeitwerk (~> 2.6)
86
+ event_stream_parser (1.0.0)
87
+ faraday (2.14.0)
88
+ faraday-net_http (>= 2.0, < 3.5)
89
+ json
90
+ logger
91
+ faraday-multipart (1.2.0)
92
+ multipart-post (~> 2.0)
93
+ faraday-net_http (3.4.2)
94
+ net-http (~> 0.5)
95
+ faraday-retry (2.4.0)
96
+ faraday (~> 2.0)
97
+ fast-mcp (1.6.0)
98
+ addressable (~> 2.8)
99
+ base64
100
+ dry-schema (~> 1.14)
101
+ json (~> 2.0)
102
+ mime-types (~> 3.4)
103
+ rack (>= 2.0, < 4.0)
104
+ ffi (1.17.3-aarch64-linux-gnu)
105
+ ffi (1.17.3-aarch64-linux-musl)
106
+ ffi (1.17.3-arm-linux-gnu)
107
+ ffi (1.17.3-arm-linux-musl)
108
+ ffi (1.17.3-arm64-darwin)
109
+ ffi (1.17.3-x86_64-darwin)
110
+ ffi (1.17.3-x86_64-linux-gnu)
111
+ ffi (1.17.3-x86_64-linux-musl)
112
+ fiber-annotation (0.2.0)
113
+ fiber-local (1.1.0)
114
+ fiber-storage
115
+ fiber-storage (1.0.1)
116
+ i18n (1.14.8)
117
+ concurrent-ruby (~> 1.0)
118
+ io-event (1.14.2)
119
+ json (2.18.0)
120
+ listen (3.10.0)
121
+ logger
122
+ rb-fsevent (~> 0.10, >= 0.10.3)
123
+ rb-inotify (~> 0.9, >= 0.9.10)
124
+ logger (1.7.0)
125
+ lru_redux (1.1.0)
126
+ marcel (1.1.0)
127
+ metrics (0.15.0)
128
+ mime-types (3.7.0)
129
+ logger
130
+ mime-types-data (~> 3.2025, >= 3.2025.0507)
131
+ mime-types-data (3.2026.0113)
132
+ minitest (6.0.1)
133
+ prism (~> 1.5)
134
+ multi_json (1.19.1)
135
+ multipart-post (2.4.1)
136
+ mustermann (3.0.4)
137
+ ruby2_keywords (~> 0.0.1)
138
+ net-http (0.9.1)
139
+ uri (>= 0.11.1)
140
+ nio4r (2.7.5)
141
+ pg (1.6.3)
142
+ pg (1.6.3-aarch64-linux)
143
+ pg (1.6.3-aarch64-linux-musl)
144
+ pg (1.6.3-arm64-darwin)
145
+ pg (1.6.3-x86_64-darwin)
146
+ pg (1.6.3-x86_64-linux)
147
+ pg (1.6.3-x86_64-linux-musl)
148
+ prism (1.8.0)
149
+ public_suffix (7.0.2)
150
+ puma (6.6.1)
151
+ nio4r (~> 2.0)
152
+ rack (2.2.21)
153
+ rack-protection (3.2.0)
154
+ base64 (>= 0.1.0)
155
+ rack (~> 2.2, >= 2.2.4)
156
+ rb-fsevent (0.11.2)
157
+ rb-inotify (0.11.1)
158
+ ffi (~> 1.0)
159
+ redis (5.4.1)
160
+ redis-client (>= 0.22.0)
161
+ redis-client (0.26.3)
162
+ connection_pool
163
+ rerun (0.14.0)
164
+ listen (~> 3.0)
165
+ ruby-next-core (1.2.0)
166
+ ruby-progressbar (1.13.0)
167
+ ruby2_keywords (0.0.5)
168
+ ruby_llm (1.11.0)
169
+ base64
170
+ event_stream_parser (~> 1)
171
+ faraday (>= 1.10.0)
172
+ faraday-multipart (>= 1)
173
+ faraday-net_http (>= 1)
174
+ faraday-retry (>= 1)
175
+ marcel (~> 1.0)
176
+ ruby_llm-schema (~> 0.2.1)
177
+ zeitwerk (~> 2)
178
+ ruby_llm-schema (0.2.5)
179
+ securerandom (0.4.1)
180
+ sequel (5.100.0)
181
+ bigdecimal
182
+ sequel_pg (1.18.2)
183
+ pg (>= 0.18.0, != 1.2.0)
184
+ sequel (>= 4.38.0)
185
+ sidekiq (7.3.9)
186
+ base64
187
+ connection_pool (>= 2.3.0)
188
+ logger
189
+ rack (>= 2.2.4)
190
+ redis-client (>= 0.22.2)
191
+ simple_flow (0.3.0)
192
+ sinatra (3.2.0)
193
+ mustermann (~> 3.0)
194
+ rack (~> 2.2, >= 2.2.4)
195
+ rack-protection (= 3.2.0)
196
+ tilt (~> 2.0)
197
+ sinatra-contrib (3.2.0)
198
+ multi_json (>= 0.0.2)
199
+ mustermann (~> 3.0)
200
+ rack-protection (= 3.2.0)
201
+ sinatra (= 3.2.0)
202
+ tilt (~> 2.0)
203
+ tiktoken_ruby (0.0.15.1-aarch64-linux)
204
+ tiktoken_ruby (0.0.15.1-aarch64-linux-musl)
205
+ tiktoken_ruby (0.0.15.1-arm-linux)
206
+ tiktoken_ruby (0.0.15.1-arm64-darwin)
207
+ tiktoken_ruby (0.0.15.1-x86_64-darwin)
208
+ tiktoken_ruby (0.0.15.1-x86_64-linux)
209
+ tiktoken_ruby (0.0.15.1-x86_64-linux-musl)
210
+ tilt (2.7.0)
211
+ traces (0.18.2)
212
+ tzinfo (2.0.6)
213
+ concurrent-ruby (~> 1.0)
214
+ uri (1.1.1)
215
+ zeitwerk (2.7.4)
216
+
217
+ PLATFORMS
218
+ aarch64-linux
219
+ aarch64-linux-gnu
220
+ aarch64-linux-musl
221
+ arm-linux
222
+ arm-linux-gnu
223
+ arm-linux-musl
224
+ arm64-darwin
225
+ x86_64-darwin
226
+ x86_64-linux
227
+ x86_64-linux-gnu
228
+ x86_64-linux-musl
229
+
230
+ DEPENDENCIES
231
+ htm!
232
+ multi_json
233
+ puma (~> 6.0)
234
+ redis (~> 5.0)
235
+ rerun
236
+ sidekiq (~> 7.0)
237
+ sinatra (~> 3.0)
238
+ sinatra-contrib (~> 3.0)
239
+
240
+ BUNDLED WITH
241
+ 2.7.2
@@ -9,12 +9,15 @@
9
9
  # - RESTful API endpoints
10
10
  # - Thread-safe concurrent request handling
11
11
  #
12
+ # Prerequisites:
13
+ # 1. Set up examples database: rake examples:setup
14
+ # 2. Install dependencies: cd examples/sinatra_app && bundle install
15
+ #
12
16
  # Usage:
13
- # bundle install
17
+ # cd examples/sinatra_app
14
18
  # bundle exec ruby app.rb
15
19
  #
16
20
  # Environment:
17
- # HTM_DATABASE__URL - PostgreSQL connection URL (required)
18
21
  # REDIS_URL - Redis connection URL (for Sidekiq, default: redis://localhost:6379/0)
19
22
  # OLLAMA_URL - Ollama server URL (default: http://localhost:11434)
20
23
  #
@@ -23,7 +26,7 @@ require 'sinatra'
23
26
  require 'sinatra/json'
24
27
  require 'sidekiq'
25
28
  require 'securerandom'
26
- require_relative '../../lib/htm'
29
+ require_relative '../examples_helper'
27
30
  require_relative '../../lib/htm/integrations/sinatra'
28
31
 
29
32
  # Sidekiq configuration
@@ -112,8 +115,8 @@ class HTMApp < Sinatra::Base
112
115
  # API: Get memory statistics
113
116
  get '/api/stats' do
114
117
  total_nodes = HTM::Models::Node.count
115
- nodes_with_embeddings = HTM::Models::Node.where.not(embedding: nil).count
116
- nodes_with_tags = HTM::Models::Node.joins(:tags).distinct.count
118
+ nodes_with_embeddings = HTM::Models::Node.exclude(embedding: nil).count
119
+ nodes_with_tags = HTM::Models::NodeTag.distinct.select(:node_id).count
117
120
  total_tags = HTM::Models::Tag.count
118
121
 
119
122
  robot_nodes = HTM::Models::RobotNode.where(robot_id: htm.robot_id).count
@@ -139,19 +142,17 @@ class HTMApp < Sinatra::Base
139
142
  json(
140
143
  status: 'ok',
141
144
  job_backend: HTM.configuration.job_backend,
142
- database: HTM::ActiveRecordConfig.connected?,
145
+ database: HTM::SequelConfig.connected?,
143
146
  timestamp: Time.now.iso8601
144
147
  )
145
148
  end
146
149
 
147
150
  # API: Get all tags as a tree structure
148
151
  get '/api/tags' do
149
- tags = HTM::Models::Tag.all
150
-
151
152
  json(
152
153
  status: 'ok',
153
- count: tags.count,
154
- tree: tags.tree
154
+ count: HTM::Models::Tag.count,
155
+ tree: HTM::Models::Tag.tree_string
155
156
  )
156
157
  end
157
158
 
@@ -182,11 +183,11 @@ class HTMApp < Sinatra::Base
182
183
  token_count: memory['token_count']
183
184
  }
184
185
 
185
- # Include hybrid search scoring if available
186
- if memory['similarity']
186
+ # Include hybrid search scoring if available (RRF-based)
187
+ if memory['rrf_score']
187
188
  result[:similarity] = memory['similarity'].to_f.round(4)
188
- result[:tag_boost] = memory['tag_boost'].to_f.round(4)
189
- result[:combined_score] = memory['combined_score'].to_f.round(4)
189
+ result[:tag_depth_score] = memory['tag_depth_score'].to_f.round(4)
190
+ result[:rrf_score] = memory['rrf_score'].to_f.round(4)
190
191
  end
191
192
 
192
193
  result
@@ -292,7 +293,7 @@ __END__
292
293
 
293
294
  <div class="section">
294
295
  <h2>Recall Memories</h2>
295
- <p><small>Hybrid search uses combined scoring: (similarity × 0.7) + (tag_boost × 0.3)</small></p>
296
+ <p><small>Hybrid search uses Reciprocal Rank Fusion (RRF) combining vector, fulltext, and tag results</small></p>
296
297
  <input type="text" id="recallTopic" placeholder="Enter topic to search...">
297
298
  <div class="filter-row">
298
299
  <select id="recallStrategy">
@@ -382,10 +383,10 @@ __END__
382
383
  // Format timeframe for display
383
384
  const timeframeDisplay = formatTimeframe(data.timeframe);
384
385
  const memoriesHtml = data.memories.map(m => {
385
- // Build scoring info if available (hybrid search)
386
+ // Build scoring info if available (hybrid search with RRF)
386
387
  let scoreInfo = '';
387
- if (m.combined_score !== undefined) {
388
- scoreInfo = `<br><small class="scores">Score: ${m.combined_score.toFixed(3)} (similarity: ${m.similarity.toFixed(3)}, tag boost: ${m.tag_boost.toFixed(3)})</small>`;
388
+ if (m.rrf_score !== undefined) {
389
+ scoreInfo = `<br><small class="scores">RRF Score: ${m.rrf_score.toFixed(3)} (similarity: ${m.similarity.toFixed(3)}, tag depth: ${m.tag_depth_score.toFixed(3)})</small>`;
389
390
  }
390
391
  // Calculate age of memory
391
392
  const age = formatAge(m.created_at);
@@ -8,9 +8,9 @@
8
8
  # using a local Ollama model.
9
9
  #
10
10
  # Prerequisites:
11
- # 1. Install gems: gem install ruby_llm-mcp
12
- # 2. Have Ollama running with gpt-oss model: ollama pull gpt-oss
13
- # 3. Set HTM_DATABASE__URL environment variable
11
+ # 1. Set up examples database: rake examples:setup
12
+ # 2. Install gems: gem install ruby_llm-mcp
13
+ # 3. Have Ollama running with gpt-oss model: ollama pull gpt-oss
14
14
  # 4. The htm_mcp executable must be available (this client will launch it)
15
15
  #
16
16
  # Usage:
@@ -23,6 +23,7 @@
23
23
  # - List tags and statistics
24
24
  # - All through conversational AI with tool calling
25
25
 
26
+ require_relative 'examples_helper'
26
27
  require 'ruby_llm'
27
28
  require 'ruby_llm/mcp'
28
29
 
@@ -57,11 +58,7 @@ class HTMMcpClient
57
58
  private
58
59
 
59
60
  def validate_environment
60
- unless ENV['HTM_DATABASE__URL']
61
- warn 'Error: HTM_DATABASE__URL not set.'
62
- warn ' export HTM_DATABASE__URL="postgresql://postgres@localhost:5432/htm_development"'
63
- exit 1
64
- end
61
+ ExamplesHelper.require_database!
65
62
 
66
63
  unless File.exist?(MCP_SERVER_PATH)
67
64
  warn "Error: MCP server not found at #{MCP_SERVER_PATH}"
@@ -1,6 +1,6 @@
1
1
  # HTM Telemetry Demo Setup
2
2
 
3
- This guide walks you through setting up Prometheus and Grafana to visualize HTM metrics.
3
+ This guide walks you through setting up Prometheus and Grafana to visualize HTM metrics. Its intended as a guid for your own applications. The demo.rb program in this directory takes care of all of the setup steps before it starts it HTM process to generate the telemetry.
4
4
 
5
5
  ## Prerequisites
6
6
 
@@ -7,8 +7,9 @@
7
7
  # locally installed Prometheus and Grafana (via Homebrew).
8
8
  #
9
9
  # Prerequisites:
10
- # brew install grafana prometheus
11
- # gem install prometheus-client webrick
10
+ # 1. Set up examples database: rake examples:setup
11
+ # 2. brew install grafana prometheus
12
+ # 3. gem install prometheus-client webrick
12
13
  #
13
14
  # Usage:
14
15
  # cd examples/telemetry
@@ -101,11 +102,14 @@ class TelemetryDemo
101
102
  def load_htm
102
103
  puts "Loading HTM..."
103
104
 
104
- # Use bundler for HTM and its dependencies
105
- require 'bundler/setup'
106
- require_relative '../../lib/htm'
105
+ # Use examples_helper which sets up examples environment and database
106
+ require_relative '../examples_helper'
107
107
 
108
108
  puts " [OK] HTM #{HTM::VERSION}"
109
+ puts " [OK] Environment: #{HTM.config.environment}"
110
+ puts " [OK] Database: #{HTM.config.actual_database_name}"
111
+
112
+ ExamplesHelper.require_database!
109
113
  puts
110
114
  end
111
115
 
@@ -306,21 +310,21 @@ class TelemetryDemo
306
310
 
307
311
  begin
308
312
  # Find the robot
309
- robot = HTM::Models::Robot.find_by(name: ROBOT_NAME)
313
+ robot = HTM::Models::Robot.first(name: ROBOT_NAME)
310
314
 
311
315
  if robot
312
316
  # Find all nodes associated with this robot
313
- node_ids = HTM::Models::RobotNode.where(robot_id: robot.id).pluck(:node_id)
317
+ node_ids = HTM::Models::RobotNode.where(robot_id: robot.id).select_map(:node_id)
314
318
 
315
319
  if node_ids.any?
316
320
  # Hard delete the nodes
317
- deleted_count = HTM::Models::Node.where(id: node_ids).delete_all
321
+ deleted_count = HTM::Models::Node.where(id: node_ids).delete
318
322
 
319
323
  # Clean up robot_nodes join table
320
- HTM::Models::RobotNode.where(robot_id: robot.id).delete_all
324
+ HTM::Models::RobotNode.where(robot_id: robot.id).delete
321
325
 
322
326
  # Clean up any orphaned node_tags
323
- HTM::Models::NodeTag.where(node_id: node_ids).delete_all
327
+ HTM::Models::NodeTag.where(node_id: node_ids).delete
324
328
 
325
329
  puts " [OK] Deleted #{deleted_count} previous demo nodes"
326
330
  else