htm 0.0.1 → 0.0.10

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 (184) hide show
  1. checksums.yaml +4 -4
  2. data/.aigcm_msg +1 -0
  3. data/.architecture/reviews/comprehensive-codebase-review.md +577 -0
  4. data/.claude/settings.local.json +92 -0
  5. data/.envrc +1 -0
  6. data/.irbrc +283 -80
  7. data/.tbls.yml +31 -0
  8. data/CHANGELOG.md +314 -16
  9. data/CLAUDE.md +603 -0
  10. data/README.md +76 -5
  11. data/Rakefile +5 -0
  12. data/SETUP.md +132 -101
  13. data/db/migrate/{20250101000001_enable_extensions.rb → 00001_enable_extensions.rb} +0 -1
  14. data/db/migrate/00002_create_robots.rb +11 -0
  15. data/db/migrate/00003_create_file_sources.rb +20 -0
  16. data/db/migrate/00004_create_nodes.rb +65 -0
  17. data/db/migrate/00005_create_tags.rb +13 -0
  18. data/db/migrate/00006_create_node_tags.rb +18 -0
  19. data/db/migrate/00007_create_robot_nodes.rb +26 -0
  20. data/db/migrate/00009_add_working_memory_to_robot_nodes.rb +12 -0
  21. data/db/schema.sql +390 -36
  22. data/docs/api/database.md +19 -232
  23. data/docs/api/embedding-service.md +1 -7
  24. data/docs/api/htm.md +305 -364
  25. data/docs/api/index.md +1 -7
  26. data/docs/api/long-term-memory.md +342 -590
  27. data/docs/api/yard/HTM/ActiveRecordConfig.md +23 -0
  28. data/docs/api/yard/HTM/AuthorizationError.md +11 -0
  29. data/docs/api/yard/HTM/CircuitBreaker.md +92 -0
  30. data/docs/api/yard/HTM/CircuitBreakerOpenError.md +34 -0
  31. data/docs/api/yard/HTM/Configuration.md +175 -0
  32. data/docs/api/yard/HTM/Database.md +99 -0
  33. data/docs/api/yard/HTM/DatabaseError.md +14 -0
  34. data/docs/api/yard/HTM/EmbeddingError.md +18 -0
  35. data/docs/api/yard/HTM/EmbeddingService.md +58 -0
  36. data/docs/api/yard/HTM/Error.md +11 -0
  37. data/docs/api/yard/HTM/JobAdapter.md +39 -0
  38. data/docs/api/yard/HTM/LongTermMemory.md +342 -0
  39. data/docs/api/yard/HTM/NotFoundError.md +17 -0
  40. data/docs/api/yard/HTM/Observability.md +107 -0
  41. data/docs/api/yard/HTM/QueryTimeoutError.md +19 -0
  42. data/docs/api/yard/HTM/Railtie.md +27 -0
  43. data/docs/api/yard/HTM/ResourceExhaustedError.md +13 -0
  44. data/docs/api/yard/HTM/TagError.md +18 -0
  45. data/docs/api/yard/HTM/TagService.md +67 -0
  46. data/docs/api/yard/HTM/Timeframe/Result.md +24 -0
  47. data/docs/api/yard/HTM/Timeframe.md +40 -0
  48. data/docs/api/yard/HTM/TimeframeExtractor/Result.md +24 -0
  49. data/docs/api/yard/HTM/TimeframeExtractor.md +45 -0
  50. data/docs/api/yard/HTM/ValidationError.md +20 -0
  51. data/docs/api/yard/HTM/WorkingMemory.md +131 -0
  52. data/docs/api/yard/HTM.md +80 -0
  53. data/docs/api/yard/index.csv +179 -0
  54. data/docs/api/yard-reference.md +51 -0
  55. data/docs/architecture/adrs/001-postgresql-timescaledb.md +1 -1
  56. data/docs/architecture/adrs/003-ollama-embeddings.md +1 -1
  57. data/docs/architecture/adrs/010-redis-working-memory-rejected.md +2 -27
  58. data/docs/architecture/adrs/index.md +2 -13
  59. data/docs/architecture/hive-mind.md +165 -166
  60. data/docs/architecture/index.md +2 -2
  61. data/docs/architecture/overview.md +5 -171
  62. data/docs/architecture/two-tier-memory.md +1 -35
  63. data/docs/assets/images/adr-010-current-architecture.svg +37 -0
  64. data/docs/assets/images/adr-010-proposed-architecture.svg +48 -0
  65. data/docs/assets/images/adr-dependency-tree.svg +93 -0
  66. data/docs/assets/images/class-hierarchy.svg +55 -0
  67. data/docs/assets/images/exception-hierarchy.svg +45 -0
  68. data/docs/assets/images/htm-architecture-overview.svg +83 -0
  69. data/docs/assets/images/htm-complete-memory-flow.svg +160 -0
  70. data/docs/assets/images/htm-context-assembly-flow.svg +148 -0
  71. data/docs/assets/images/htm-eviction-process.svg +141 -0
  72. data/docs/assets/images/htm-memory-addition-flow.svg +138 -0
  73. data/docs/assets/images/htm-memory-recall-flow.svg +152 -0
  74. data/docs/assets/images/htm-node-states.svg +123 -0
  75. data/docs/assets/images/project-structure.svg +78 -0
  76. data/docs/assets/images/test-directory-structure.svg +38 -0
  77. data/{dbdoc → docs/database}/README.md +127 -125
  78. data/docs/database/public.file_sources.md +42 -0
  79. data/docs/database/public.file_sources.svg +211 -0
  80. data/{dbdoc → docs/database}/public.node_tags.md +7 -8
  81. data/docs/database/public.node_tags.svg +239 -0
  82. data/{dbdoc → docs/database}/public.nodes.md +22 -17
  83. data/docs/database/public.nodes.svg +271 -0
  84. data/docs/database/public.robot_nodes.md +46 -0
  85. data/docs/database/public.robot_nodes.svg +243 -0
  86. data/{dbdoc → docs/database}/public.robots.md +2 -3
  87. data/docs/database/public.robots.svg +161 -0
  88. data/docs/database/public.tags.svg +139 -0
  89. data/{dbdoc → docs/database}/schema.json +941 -630
  90. data/docs/database/schema.svg +282 -0
  91. data/docs/development/index.md +1 -29
  92. data/docs/development/schema.md +134 -309
  93. data/docs/development/testing.md +1 -9
  94. data/docs/getting-started/index.md +47 -0
  95. data/docs/{installation.md → getting-started/installation.md} +2 -2
  96. data/docs/{quick-start.md → getting-started/quick-start.md} +5 -5
  97. data/docs/guides/adding-memories.md +295 -643
  98. data/docs/guides/recalling-memories.md +36 -1
  99. data/docs/guides/search-strategies.md +85 -51
  100. data/docs/images/htm-er-diagram.svg +156 -0
  101. data/docs/index.md +16 -31
  102. data/docs/multi_framework_support.md +4 -4
  103. data/examples/README.md +280 -0
  104. data/examples/basic_usage.rb +18 -16
  105. data/examples/cli_app/htm_cli.rb +146 -8
  106. data/examples/cli_app/temp.log +93 -0
  107. data/examples/custom_llm_configuration.rb +1 -2
  108. data/examples/example_app/app.rb +11 -14
  109. data/examples/file_loader_usage.rb +177 -0
  110. data/examples/robot_groups/lib/robot_group.rb +419 -0
  111. data/examples/robot_groups/lib/working_memory_channel.rb +140 -0
  112. data/examples/robot_groups/multi_process.rb +286 -0
  113. data/examples/robot_groups/robot_worker.rb +136 -0
  114. data/examples/robot_groups/same_process.rb +229 -0
  115. data/examples/sinatra_app/Gemfile +1 -0
  116. data/examples/sinatra_app/Gemfile.lock +166 -0
  117. data/examples/sinatra_app/app.rb +219 -24
  118. data/examples/timeframe_demo.rb +276 -0
  119. data/lib/htm/active_record_config.rb +10 -3
  120. data/lib/htm/circuit_breaker.rb +202 -0
  121. data/lib/htm/configuration.rb +313 -80
  122. data/lib/htm/database.rb +67 -36
  123. data/lib/htm/embedding_service.rb +39 -2
  124. data/lib/htm/errors.rb +131 -11
  125. data/lib/htm/{sinatra.rb → integrations/sinatra.rb} +87 -12
  126. data/lib/htm/job_adapter.rb +10 -3
  127. data/lib/htm/jobs/generate_embedding_job.rb +5 -4
  128. data/lib/htm/jobs/generate_tags_job.rb +4 -0
  129. data/lib/htm/loaders/markdown_loader.rb +263 -0
  130. data/lib/htm/loaders/paragraph_chunker.rb +112 -0
  131. data/lib/htm/long_term_memory.rb +601 -321
  132. data/lib/htm/models/file_source.rb +99 -0
  133. data/lib/htm/models/node.rb +116 -12
  134. data/lib/htm/models/robot.rb +53 -4
  135. data/lib/htm/models/robot_node.rb +51 -0
  136. data/lib/htm/models/tag.rb +302 -0
  137. data/lib/htm/observability.rb +395 -0
  138. data/lib/htm/tag_service.rb +60 -3
  139. data/lib/htm/tasks.rb +29 -0
  140. data/lib/htm/timeframe.rb +194 -0
  141. data/lib/htm/timeframe_extractor.rb +307 -0
  142. data/lib/htm/version.rb +1 -1
  143. data/lib/htm/working_memory.rb +165 -70
  144. data/lib/htm.rb +352 -133
  145. data/lib/tasks/doc.rake +300 -0
  146. data/lib/tasks/files.rake +299 -0
  147. data/lib/tasks/htm.rake +188 -2
  148. data/lib/tasks/jobs.rake +10 -12
  149. data/lib/tasks/tags.rake +194 -0
  150. data/mkdocs.yml +91 -9
  151. data/notes/ARCHITECTURE_REVIEW.md +1167 -0
  152. data/notes/IMPLEMENTATION_SUMMARY.md +606 -0
  153. data/notes/MULTI_FRAMEWORK_IMPLEMENTATION.md +451 -0
  154. data/notes/next_steps.md +100 -0
  155. data/notes/plan.md +627 -0
  156. data/notes/tag_ontology_enhancement_ideas.md +222 -0
  157. data/notes/timescaledb_removal_summary.md +200 -0
  158. metadata +177 -37
  159. data/db/migrate/20250101000002_create_robots.rb +0 -14
  160. data/db/migrate/20250101000003_create_nodes.rb +0 -42
  161. data/db/migrate/20250101000005_create_tags.rb +0 -38
  162. data/db/migrate/20250101000007_add_node_vector_indexes.rb +0 -30
  163. data/dbdoc/public.node_tags.svg +0 -112
  164. data/dbdoc/public.nodes.svg +0 -118
  165. data/dbdoc/public.robots.svg +0 -90
  166. data/dbdoc/public.tags.svg +0 -60
  167. data/dbdoc/schema.svg +0 -154
  168. data/{dbdoc → docs/database}/public.node_stats.md +0 -0
  169. data/{dbdoc → docs/database}/public.node_stats.svg +0 -0
  170. data/{dbdoc → docs/database}/public.nodes_tags.md +0 -0
  171. data/{dbdoc → docs/database}/public.nodes_tags.svg +0 -0
  172. data/{dbdoc → docs/database}/public.ontology_structure.md +0 -0
  173. data/{dbdoc → docs/database}/public.ontology_structure.svg +0 -0
  174. data/{dbdoc → docs/database}/public.operations_log.md +0 -0
  175. data/{dbdoc → docs/database}/public.operations_log.svg +0 -0
  176. data/{dbdoc → docs/database}/public.relationships.md +0 -0
  177. data/{dbdoc → docs/database}/public.relationships.svg +0 -0
  178. data/{dbdoc → docs/database}/public.robot_activity.md +0 -0
  179. data/{dbdoc → docs/database}/public.robot_activity.svg +0 -0
  180. data/{dbdoc → docs/database}/public.schema_migrations.md +0 -0
  181. data/{dbdoc → docs/database}/public.schema_migrations.svg +0 -0
  182. data/{dbdoc → docs/database}/public.tags.md +3 -3
  183. /data/{dbdoc → docs/database}/public.topic_relationships.md +0 -0
  184. /data/{dbdoc → docs/database}/public.topic_relationships.svg +0 -0
data/lib/tasks/htm.rake CHANGED
@@ -124,6 +124,161 @@ namespace :htm do
124
124
  HTM::Database.info
125
125
  end
126
126
 
127
+ desc "Show record counts for all HTM tables"
128
+ task :stats do
129
+ require 'htm'
130
+
131
+ # Ensure database connection
132
+ HTM::ActiveRecordConfig.establish_connection!
133
+
134
+ puts "\nHTM Database Statistics"
135
+ puts "=" * 50
136
+
137
+ # Define tables with their models and optional extra info
138
+ tables = [
139
+ { name: 'robots', model: HTM::Models::Robot },
140
+ { name: 'nodes', model: HTM::Models::Node, extras: ->(m) {
141
+ # Node uses default_scope for active nodes, so m.count is active count
142
+ active = m.count
143
+ deleted = m.deleted.count
144
+ with_embedding = m.where.not(embedding: nil).count
145
+ " (active: #{active}, deleted: #{deleted}, with embeddings: #{with_embedding})"
146
+ }},
147
+ { name: 'tags', model: HTM::Models::Tag },
148
+ { name: 'nodes_tags', model: HTM::Models::NodeTag },
149
+ { name: 'file_sources', model: HTM::Models::FileSource }
150
+ ]
151
+
152
+ total = 0
153
+ max_name_len = tables.map { |t| t[:name].length }.max
154
+
155
+ tables.each do |table|
156
+ count = table[:model].count
157
+ total += count
158
+ extras = table[:extras] ? table[:extras].call(table[:model]) : ''
159
+
160
+ printf " %-#{max_name_len}s %8d%s\n", table[:name], count, extras
161
+ end
162
+
163
+ puts "-" * 50
164
+ printf " %-#{max_name_len}s %8d\n", "Total", total
165
+
166
+ # Additional stats
167
+ puts "\nAdditional Statistics:"
168
+
169
+ # Nodes per robot (via robot_nodes join table)
170
+ robot_counts = HTM::Models::RobotNode
171
+ .joins(:node)
172
+ .where(nodes: { deleted_at: nil })
173
+ .group(:robot_id)
174
+ .count
175
+ .transform_keys { |id| HTM::Models::Robot.find(id).name rescue "Unknown (#{id})" }
176
+ .sort_by { |_, count| -count }
177
+ .first(5)
178
+
179
+ if robot_counts.any?
180
+ puts " Top robots by node count:"
181
+ robot_counts.each do |name, count|
182
+ puts " #{name}: #{count}"
183
+ end
184
+ end
185
+
186
+ # Tag distribution
187
+ top_root_tags = HTM::Models::Tag
188
+ .select("split_part(name, ':', 1) as root, count(*) as cnt")
189
+ .group("split_part(name, ':', 1)")
190
+ .order("cnt DESC")
191
+ .limit(5)
192
+ .map { |t| [t.root, t.cnt] }
193
+
194
+ if top_root_tags.any?
195
+ puts " Top root tag categories:"
196
+ top_root_tags.each do |root, count|
197
+ puts " #{root}: #{count}"
198
+ end
199
+ end
200
+
201
+ puts
202
+ end
203
+
204
+ namespace :rebuild do
205
+ desc "Rebuild embeddings for all nodes. Clears existing embeddings and regenerates via LLM."
206
+ task :embeddings do
207
+ require 'htm'
208
+ require 'ruby-progressbar'
209
+
210
+ # Ensure database connection
211
+ HTM::ActiveRecordConfig.establish_connection!
212
+
213
+ # Node uses default_scope for active (non-deleted) nodes
214
+ node_count = HTM::Models::Node.count
215
+ with_embeddings = HTM::Models::Node.where.not(embedding: nil).count
216
+ without_embeddings = node_count - with_embeddings
217
+
218
+ puts "\nHTM Embeddings Rebuild"
219
+ puts "=" * 50
220
+ puts "Current state:"
221
+ puts " Total active nodes: #{node_count}"
222
+ puts " With embeddings: #{with_embeddings}"
223
+ puts " Without embeddings: #{without_embeddings}"
224
+ puts "\nThis will regenerate embeddings for ALL #{node_count} nodes."
225
+ puts "This operation may take a long time depending on your LLM provider."
226
+ print "\nType 'yes' to confirm: "
227
+
228
+ confirmation = $stdin.gets&.strip
229
+ unless confirmation == 'yes'
230
+ puts "Aborted."
231
+ next
232
+ end
233
+
234
+ puts "\nClearing existing embeddings..."
235
+ cleared = HTM::Models::Node.where.not(embedding: nil).update_all(embedding: nil)
236
+ puts " Cleared #{cleared} embeddings"
237
+
238
+ puts "\nGenerating embeddings for #{node_count} nodes..."
239
+ puts "(This may take a while depending on your LLM provider)\n"
240
+
241
+ # Create progress bar with ETA
242
+ progressbar = ProgressBar.create(
243
+ total: node_count,
244
+ format: '%t: |%B| %c/%C (%p%%) %e',
245
+ title: 'Embedding',
246
+ output: $stdout,
247
+ smoothing: 0.5
248
+ )
249
+
250
+ # Process each active node (default_scope excludes deleted)
251
+ errors = 0
252
+ success = 0
253
+
254
+ HTM::Models::Node.find_each do |node|
255
+ begin
256
+ # Generate embedding directly (not via job since we cleared them)
257
+ result = HTM::EmbeddingService.generate(node.content)
258
+
259
+ node.update!(embedding: result[:storage_embedding])
260
+ success += 1
261
+ rescue StandardError => e
262
+ errors += 1
263
+ progressbar.log " Error on node #{node.id}: #{e.message}"
264
+ end
265
+
266
+ progressbar.increment
267
+ end
268
+
269
+ progressbar.finish
270
+
271
+ # Final stats
272
+ final_with_embeddings = HTM::Models::Node.where.not(embedding: nil).count
273
+
274
+ puts "\nRebuild complete!"
275
+ puts " Nodes processed: #{node_count}"
276
+ puts " Successful: #{success}"
277
+ puts " Errors: #{errors}"
278
+ puts " Nodes with embeddings: #{final_with_embeddings}"
279
+ end
280
+ end
281
+
127
282
  namespace :schema do
128
283
  desc "Dump current schema to db/schema.sql"
129
284
  task :dump do
@@ -138,10 +293,41 @@ namespace :htm do
138
293
  end
139
294
  end
140
295
 
141
- desc "Generate/update database documentation in dbdoc/"
142
- task :doc do
296
+ end
297
+
298
+ namespace :doc do
299
+ desc "Generate/update database documentation in docs/database/ (uses .tbls.yml)"
300
+ task :db do
301
+ unless system("which tbls > /dev/null 2>&1")
302
+ puts "Error: 'tbls' is not installed."
303
+ puts "Install it with: brew install tbls"
304
+ exit 1
305
+ end
143
306
  require 'htm'
144
307
  HTM::Database.generate_docs
145
308
  end
309
+
310
+ desc "Build documentation site with MkDocs"
311
+ task :build do
312
+ unless system("which mkdocs > /dev/null 2>&1")
313
+ puts "Error: 'mkdocs' is not installed."
314
+ puts "Install it with: brew install mkdocs"
315
+ exit 1
316
+ end
317
+ sh "mkdocs build"
318
+ end
319
+
320
+ desc "Serve documentation site locally with MkDocs"
321
+ task :serve do
322
+ unless system("which mkdocs > /dev/null 2>&1")
323
+ puts "Error: 'mkdocs' is not installed."
324
+ puts "Install it with: brew install mkdocs"
325
+ exit 1
326
+ end
327
+ sh "mkdocs serve"
328
+ end
329
+
330
+ desc "Generate DB docs, YARD API docs, build site, and serve locally"
331
+ task :all => [:db, :yard, :build, :serve]
146
332
  end
147
333
  end
data/lib/tasks/jobs.rake CHANGED
@@ -42,9 +42,13 @@ namespace :htm do
42
42
  # Tags by depth
43
43
  if total_tags > 0
44
44
  puts "\nTag hierarchy breakdown:"
45
- HTM::Models::Tag.all.each do |tag|
46
- depth = tag.name.count(':')
47
- puts " Depth #{depth}: #{tag.name.count(':', depth)} tags" if depth <= 3
45
+ depth_counts = Hash.new(0)
46
+ HTM::Models::Tag.pluck(:name).each do |name|
47
+ depth = name.count(':')
48
+ depth_counts[depth] += 1
49
+ end
50
+ depth_counts.keys.sort.each do |depth|
51
+ puts " Depth #{depth}: #{depth_counts[depth]} tags"
48
52
  end
49
53
  end
50
54
 
@@ -84,10 +88,7 @@ namespace :htm do
84
88
  begin
85
89
  # Use the service class directly (same as job)
86
90
  result = HTM::EmbeddingService.generate(node.content)
87
- node.update!(
88
- embedding: result[:storage_embedding],
89
- embedding_dimension: result[:dimension]
90
- )
91
+ node.update!(embedding: result[:storage_embedding])
91
92
  processed += 1
92
93
  print "\rProcessed: #{processed}/#{total}"
93
94
  rescue StandardError => e
@@ -187,10 +188,7 @@ namespace :htm do
187
188
  begin
188
189
  # Use the service class directly to regenerate
189
190
  result = HTM::EmbeddingService.generate(node.content)
190
- node.update!(
191
- embedding: result[:storage_embedding],
192
- embedding_dimension: result[:dimension]
193
- )
191
+ node.update!(embedding: result[:storage_embedding])
194
192
  processed += 1
195
193
  print "\rProcessed: #{processed}/#{total}"
196
194
  rescue StandardError => e
@@ -270,7 +268,7 @@ namespace :htm do
270
268
  HTM::ActiveRecordConfig.establish_connection!
271
269
 
272
270
  puts "Clearing embeddings..."
273
- HTM::Models::Node.update_all(embedding: nil, embedding_dimension: nil)
271
+ HTM::Models::Node.update_all(embedding: nil)
274
272
 
275
273
  puts "Clearing tags..."
276
274
  HTM::Models::NodeTag.delete_all
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ # HTM Tag Management Tasks
4
+ #
5
+ # These tasks are available to any application using the HTM gem.
6
+ # Add to your application's Rakefile:
7
+ #
8
+ # require 'htm/tasks'
9
+ #
10
+
11
+ namespace :htm do
12
+ namespace :tags do
13
+ desc "Display tags as a hierarchical tree (text format). Optional prefix filter."
14
+ task :tree, [:prefix] do |_t, args|
15
+ require 'htm'
16
+
17
+ # Ensure database connection
18
+ HTM::ActiveRecordConfig.establish_connection!
19
+
20
+ tags = args[:prefix] ? HTM::Models::Tag.with_prefix(args[:prefix]) : HTM::Models::Tag.all
21
+ count = tags.count
22
+
23
+ if count.zero?
24
+ puts args[:prefix] ? "No tags found with prefix '#{args[:prefix]}'." : "No tags found in database."
25
+ next
26
+ end
27
+
28
+ # Display tree using Tag model method
29
+ puts "\nHTM Tags Tree#{args[:prefix] ? " (prefix: #{args[:prefix]})" : ''}"
30
+ puts "=" * 40
31
+ print tags.tree_string
32
+ puts "\nTotal tags: #{count}"
33
+ end
34
+
35
+ desc "Export tags as Mermaid flowchart to tags.md. Optional prefix filter."
36
+ task :mermaid, [:prefix] do |_t, args|
37
+ require 'htm'
38
+
39
+ # Ensure database connection
40
+ HTM::ActiveRecordConfig.establish_connection!
41
+
42
+ tags = args[:prefix] ? HTM::Models::Tag.with_prefix(args[:prefix]) : HTM::Models::Tag.all
43
+ count = tags.count
44
+
45
+ if count.zero?
46
+ puts args[:prefix] ? "No tags found with prefix '#{args[:prefix]}'." : "No tags found in database."
47
+ next
48
+ end
49
+
50
+ mermaid = tags.tree_mermaid(direction: 'TD')
51
+ File.write('tags.md', mermaid)
52
+
53
+ puts "Mermaid flowchart written to: tags.md"
54
+ puts "Tags exported: #{count}#{args[:prefix] ? " (prefix: #{args[:prefix]})" : ''}"
55
+ end
56
+
57
+ desc "Export tags as SVG visualization to tags.svg. Optional prefix filter."
58
+ task :svg, [:prefix] do |_t, args|
59
+ require 'htm'
60
+
61
+ # Ensure database connection
62
+ HTM::ActiveRecordConfig.establish_connection!
63
+
64
+ tags = args[:prefix] ? HTM::Models::Tag.with_prefix(args[:prefix]) : HTM::Models::Tag.all
65
+ count = tags.count
66
+
67
+ if count.zero?
68
+ puts args[:prefix] ? "No tags found with prefix '#{args[:prefix]}'." : "No tags found in database."
69
+ next
70
+ end
71
+
72
+ title = args[:prefix] ? "HTM Tags: #{args[:prefix]}*" : 'HTM Tag Hierarchy'
73
+ svg = tags.tree_svg(title: title)
74
+ File.write('tags.svg', svg)
75
+
76
+ puts "SVG visualization written to: tags.svg"
77
+ puts "Tags exported: #{count}#{args[:prefix] ? " (prefix: #{args[:prefix]})" : ''}"
78
+ end
79
+
80
+ desc "Rebuild all tags from node content. Clears existing tags and regenerates using LLM."
81
+ task :rebuild do
82
+ require 'htm'
83
+
84
+ # Ensure database connection
85
+ HTM::ActiveRecordConfig.establish_connection!
86
+
87
+ # Node uses default_scope for active (non-deleted) nodes
88
+ node_count = HTM::Models::Node.count
89
+ tag_count = HTM::Models::Tag.count
90
+ node_tag_count = HTM::Models::NodeTag.count
91
+
92
+ puts "\nHTM Tags Rebuild"
93
+ puts "=" * 40
94
+ puts "This will:"
95
+ puts " - Delete #{node_tag_count} node-tag associations"
96
+ puts " - Delete #{tag_count} tags"
97
+ puts " - Regenerate tags for #{node_count} nodes using LLM"
98
+ puts "\nThis operation cannot be undone."
99
+ print "\nType 'yes' to confirm: "
100
+
101
+ confirmation = $stdin.gets&.strip
102
+ unless confirmation == 'yes'
103
+ puts "Aborted."
104
+ next
105
+ end
106
+
107
+ puts "\nClearing existing tags..."
108
+
109
+ # Clear join table first (foreign key constraint)
110
+ deleted_associations = HTM::Models::NodeTag.delete_all
111
+ puts " Deleted #{deleted_associations} node-tag associations"
112
+
113
+ # Clear tags table
114
+ deleted_tags = HTM::Models::Tag.delete_all
115
+ puts " Deleted #{deleted_tags} tags"
116
+
117
+ puts "\nRegenerating tags for #{node_count} nodes..."
118
+ puts "(This may take a while depending on your LLM provider)\n"
119
+
120
+ require 'ruby-progressbar'
121
+
122
+ # Create progress bar with ETA
123
+ progressbar = ProgressBar.create(
124
+ total: node_count,
125
+ format: '%t: |%B| %c/%C (%p%%) %e',
126
+ title: 'Processing',
127
+ output: $stdout,
128
+ smoothing: 0.5
129
+ )
130
+
131
+ # Process each active node (default_scope excludes deleted)
132
+ errors = 0
133
+
134
+ HTM::Models::Node.find_each do |node|
135
+ begin
136
+ HTM::Jobs::GenerateTagsJob.perform(node_id: node.id)
137
+ rescue StandardError => e
138
+ errors += 1
139
+ progressbar.log " Error on node #{node.id}: #{e.message}"
140
+ end
141
+
142
+ progressbar.increment
143
+ end
144
+
145
+ progressbar.finish
146
+
147
+ # Final stats
148
+ new_tag_count = HTM::Models::Tag.count
149
+ new_association_count = HTM::Models::NodeTag.count
150
+
151
+ puts "\nRebuild complete!"
152
+ puts " Nodes processed: #{node_count}"
153
+ puts " Errors: #{errors}"
154
+ puts " Tags created: #{new_tag_count}"
155
+ puts " Node-tag associations: #{new_association_count}"
156
+ end
157
+
158
+ desc "Export tags in all formats (tags.txt, tags.md, tags.svg). Optional prefix filter."
159
+ task :export, [:prefix] do |_t, args|
160
+ require 'htm'
161
+
162
+ # Ensure database connection
163
+ HTM::ActiveRecordConfig.establish_connection!
164
+
165
+ tags = args[:prefix] ? HTM::Models::Tag.with_prefix(args[:prefix]) : HTM::Models::Tag.all
166
+ count = tags.count
167
+
168
+ if count.zero?
169
+ puts args[:prefix] ? "No tags found with prefix '#{args[:prefix]}'." : "No tags found in database."
170
+ next
171
+ end
172
+
173
+ prefix_note = args[:prefix] ? " (prefix: #{args[:prefix]})" : ''
174
+ title = args[:prefix] ? "HTM Tags: #{args[:prefix]}*" : 'HTM Tag Hierarchy'
175
+
176
+ # Export text tree
177
+ text_content = "HTM Tags Tree#{prefix_note}\n" + ("=" * 40) + "\n"
178
+ text_content += tags.tree_string
179
+ text_content += "\nTotal tags: #{count}\n"
180
+ File.write('tags.txt', text_content)
181
+ puts "Text tree written to: tags.txt"
182
+
183
+ # Export Mermaid
184
+ File.write('tags.md', tags.tree_mermaid)
185
+ puts "Mermaid flowchart written to: tags.md"
186
+
187
+ # Export SVG
188
+ File.write('tags.svg', tags.tree_svg(title: title))
189
+ puts "SVG visualization written to: tags.svg"
190
+
191
+ puts "\nTags exported: #{count}#{prefix_note}"
192
+ end
193
+ end
194
+ end
data/mkdocs.yml CHANGED
@@ -13,21 +13,21 @@ edit_uri: edit/main/docs/
13
13
  # Configuration
14
14
  theme:
15
15
  name: material
16
-
16
+
17
17
  # Color scheme - Default to light mode
18
18
  palette:
19
19
  # Palette toggle for light mode (default)
20
20
  - scheme: default
21
- primary: blue
22
- accent: blue
21
+ primary: indigo
22
+ accent: deep purple
23
23
  toggle:
24
24
  icon: material/brightness-7
25
25
  name: Switch to dark mode
26
-
26
+
27
27
  # Palette toggle for dark mode
28
28
  - scheme: slate
29
- primary: blue
30
- accent: blue
29
+ primary: indigo
30
+ accent: deep purple
31
31
  toggle:
32
32
  icon: material/brightness-4
33
33
  name: Switch to light mode
@@ -37,6 +37,10 @@ theme:
37
37
  text: Roboto
38
38
  code: Roboto Mono
39
39
 
40
+ # Logo and icon
41
+ icon:
42
+ repo: fontawesome/brands/github
43
+
40
44
  # Theme features
41
45
  features:
42
46
  # Navigation
@@ -48,6 +52,7 @@ theme:
48
52
  - navigation.path
49
53
  - navigation.indexes
50
54
  - navigation.top
55
+ - navigation.footer
51
56
 
52
57
  # Table of contents
53
58
  - toc.follow
@@ -72,6 +77,7 @@ theme:
72
77
  plugins:
73
78
  - search:
74
79
  separator: '[\s\-,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
80
+ - tags
75
81
 
76
82
  # Extensions
77
83
  markdown_extensions:
@@ -82,6 +88,7 @@ markdown_extensions:
82
88
  - def_list
83
89
  - footnotes
84
90
  - md_in_html
91
+ - tables
85
92
  - toc:
86
93
  permalink: true
87
94
  title: On this page
@@ -92,6 +99,7 @@ markdown_extensions:
92
99
  - pymdownx.betterem:
93
100
  smart_enable: all
94
101
  - pymdownx.caret
102
+ - pymdownx.critic
95
103
  - pymdownx.details
96
104
  - pymdownx.emoji:
97
105
  emoji_generator: !!python/name:material.extensions.emoji.to_svg
@@ -106,8 +114,11 @@ markdown_extensions:
106
114
  repo_url_shorthand: true
107
115
  user: madbomber
108
116
  repo: htm
117
+ normalize_issue_symbols: true
109
118
  - pymdownx.mark
110
119
  - pymdownx.smartsymbols
120
+ - pymdownx.snippets:
121
+ check_paths: true
111
122
  - pymdownx.superfences:
112
123
  custom_fences:
113
124
  - name: mermaid
@@ -138,11 +149,28 @@ extra:
138
149
  link: https://rubygems.org/gems/htm
139
150
  name: HTM on RubyGems
140
151
 
152
+ analytics:
153
+ feedback:
154
+ title: Was this page helpful?
155
+ ratings:
156
+ - icon: material/emoticon-happy-outline
157
+ name: This page was helpful
158
+ data: 1
159
+ note: >-
160
+ Thanks for your feedback!
161
+ - icon: material/emoticon-sad-outline
162
+ name: This page could be improved
163
+ data: 0
164
+ note: >-
165
+ Thanks for your feedback! Help us improve by creating an issue.
166
+
141
167
  # Navigation
142
168
  nav:
143
169
  - Home: index.md
144
- - Installation: installation.md
145
- - Quick Start: quick-start.md
170
+ - Getting Started:
171
+ - getting-started/index.md
172
+ - Installation: getting-started/installation.md
173
+ - Quick Start: getting-started/quick-start.md
146
174
  - Architecture:
147
175
  - architecture/index.md
148
176
  - Overview: architecture/overview.md
@@ -178,13 +206,67 @@ nav:
178
206
  - Long-Term Memory: api/long-term-memory.md
179
207
  - Embedding Service: api/embedding-service.md
180
208
  - Database: api/database.md
209
+ - YARD Reference:
210
+ - api/yard-reference.md
211
+ - HTM Module: api/yard/HTM.md
212
+ - Core Classes:
213
+ - Configuration: api/yard/HTM/Configuration.md
214
+ - Database: api/yard/HTM/Database.md
215
+ - LongTermMemory: api/yard/HTM/LongTermMemory.md
216
+ - WorkingMemory: api/yard/HTM/WorkingMemory.md
217
+ - Services:
218
+ - EmbeddingService: api/yard/HTM/EmbeddingService.md
219
+ - TagService: api/yard/HTM/TagService.md
220
+ - JobAdapter: api/yard/HTM/JobAdapter.md
221
+ - Utilities:
222
+ - CircuitBreaker: api/yard/HTM/CircuitBreaker.md
223
+ - Observability: api/yard/HTM/Observability.md
224
+ - Timeframe: api/yard/HTM/Timeframe.md
225
+ - TimeframeExtractor: api/yard/HTM/TimeframeExtractor.md
226
+ - Internal:
227
+ - ActiveRecordConfig: api/yard/HTM/ActiveRecordConfig.md
228
+ - Railtie: api/yard/HTM/Railtie.md
229
+ - Errors:
230
+ - Error: api/yard/HTM/Error.md
231
+ - AuthorizationError: api/yard/HTM/AuthorizationError.md
232
+ - CircuitBreakerOpenError: api/yard/HTM/CircuitBreakerOpenError.md
233
+ - DatabaseError: api/yard/HTM/DatabaseError.md
234
+ - EmbeddingError: api/yard/HTM/EmbeddingError.md
235
+ - NotFoundError: api/yard/HTM/NotFoundError.md
236
+ - QueryTimeoutError: api/yard/HTM/QueryTimeoutError.md
237
+ - ResourceExhaustedError: api/yard/HTM/ResourceExhaustedError.md
238
+ - TagError: api/yard/HTM/TagError.md
239
+ - ValidationError: api/yard/HTM/ValidationError.md
240
+ - Result Types:
241
+ - Timeframe Result: api/yard/HTM/Timeframe/Result.md
242
+ - TimeframeExtractor Result: api/yard/HTM/TimeframeExtractor/Result.md
181
243
  - Development:
182
244
  - development/index.md
183
245
  - Setup: development/setup.md
184
246
  - Testing: development/testing.md
185
247
  - Contributing: development/contributing.md
186
248
  - Database Schema: development/schema.md
249
+ - Database Tables:
250
+ - database/README.md
251
+ - Core Tables:
252
+ - Robots: database/public.robots.md
253
+ - Nodes: database/public.nodes.md
254
+ - Tags: database/public.tags.md
255
+ - File Sources: database/public.file_sources.md
256
+ - Join Tables:
257
+ - Node Tags: database/public.node_tags.md
258
+ - Nodes Tags (Legacy): database/public.nodes_tags.md
259
+ - Robot Nodes: database/public.robot_nodes.md
260
+ - Views & Stats:
261
+ - Node Stats: database/public.node_stats.md
262
+ - Robot Activity: database/public.robot_activity.md
263
+ - Topic Relationships: database/public.topic_relationships.md
264
+ - Ontology Structure: database/public.ontology_structure.md
265
+ - Relationships: database/public.relationships.md
266
+ - System:
267
+ - Operations Log: database/public.operations_log.md
268
+ - Schema Migrations: database/public.schema_migrations.md
187
269
  - Multi-Framework Support: multi_framework_support.md
188
270
  - Database Rake Tasks: database_rake_tasks.md
189
271
  - Using Rake Tasks: using_rake_tasks_in_your_app.md
190
- - Setup Local Database: setup_local_database.md
272
+ - Setup Local Database: setup_local_database.md