htm 0.0.2 → 0.0.11
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/.aigcm_msg +1 -0
- data/.architecture/reviews/comprehensive-codebase-review.md +577 -0
- data/.claude/settings.local.json +95 -0
- data/.irbrc +283 -80
- data/.tbls.yml +2 -1
- data/CHANGELOG.md +327 -26
- data/CLAUDE.md +603 -0
- data/README.md +83 -12
- data/Rakefile +5 -0
- data/bin/htm_mcp.rb +527 -0
- data/db/migrate/{20250101000001_enable_extensions.rb → 00001_enable_extensions.rb} +0 -1
- data/db/migrate/00002_create_robots.rb +11 -0
- data/db/migrate/00003_create_file_sources.rb +20 -0
- data/db/migrate/00004_create_nodes.rb +65 -0
- data/db/migrate/00005_create_tags.rb +13 -0
- data/db/migrate/00006_create_node_tags.rb +18 -0
- data/db/migrate/00007_create_robot_nodes.rb +26 -0
- data/db/migrate/00009_add_working_memory_to_robot_nodes.rb +12 -0
- data/db/schema.sql +172 -1
- data/docs/api/database.md +1 -2
- data/docs/api/htm.md +197 -2
- data/docs/api/yard/HTM/ActiveRecordConfig.md +23 -0
- data/docs/api/yard/HTM/AuthorizationError.md +11 -0
- data/docs/api/yard/HTM/CircuitBreaker.md +92 -0
- data/docs/api/yard/HTM/CircuitBreakerOpenError.md +34 -0
- data/docs/api/yard/HTM/Configuration.md +175 -0
- data/docs/api/yard/HTM/Database.md +99 -0
- data/docs/api/yard/HTM/DatabaseError.md +14 -0
- data/docs/api/yard/HTM/EmbeddingError.md +18 -0
- data/docs/api/yard/HTM/EmbeddingService.md +58 -0
- data/docs/api/yard/HTM/Error.md +11 -0
- data/docs/api/yard/HTM/JobAdapter.md +39 -0
- data/docs/api/yard/HTM/LongTermMemory.md +342 -0
- data/docs/api/yard/HTM/NotFoundError.md +17 -0
- data/docs/api/yard/HTM/Observability.md +107 -0
- data/docs/api/yard/HTM/QueryTimeoutError.md +19 -0
- data/docs/api/yard/HTM/Railtie.md +27 -0
- data/docs/api/yard/HTM/ResourceExhaustedError.md +13 -0
- data/docs/api/yard/HTM/TagError.md +18 -0
- data/docs/api/yard/HTM/TagService.md +67 -0
- data/docs/api/yard/HTM/Timeframe/Result.md +24 -0
- data/docs/api/yard/HTM/Timeframe.md +40 -0
- data/docs/api/yard/HTM/TimeframeExtractor/Result.md +24 -0
- data/docs/api/yard/HTM/TimeframeExtractor.md +45 -0
- data/docs/api/yard/HTM/ValidationError.md +20 -0
- data/docs/api/yard/HTM/WorkingMemory.md +131 -0
- data/docs/api/yard/HTM.md +80 -0
- data/docs/api/yard/index.csv +179 -0
- data/docs/api/yard-reference.md +51 -0
- data/docs/database/README.md +128 -128
- data/docs/database/public.file_sources.md +42 -0
- data/docs/database/public.file_sources.svg +211 -0
- data/docs/database/public.node_tags.md +4 -4
- data/docs/database/public.node_tags.svg +212 -79
- data/docs/database/public.nodes.md +22 -12
- data/docs/database/public.nodes.svg +246 -127
- data/docs/database/public.robot_nodes.md +11 -9
- data/docs/database/public.robot_nodes.svg +220 -98
- data/docs/database/public.robots.md +2 -2
- data/docs/database/public.robots.svg +136 -81
- data/docs/database/public.tags.md +3 -3
- data/docs/database/public.tags.svg +118 -39
- data/docs/database/schema.json +850 -771
- data/docs/database/schema.svg +256 -197
- data/docs/development/schema.md +67 -2
- data/docs/guides/adding-memories.md +93 -7
- data/docs/guides/recalling-memories.md +36 -1
- data/examples/README.md +405 -0
- data/examples/cli_app/htm_cli.rb +65 -5
- data/examples/cli_app/temp.log +93 -0
- data/examples/file_loader_usage.rb +177 -0
- data/examples/mcp_client.rb +529 -0
- data/examples/robot_groups/lib/robot_group.rb +419 -0
- data/examples/robot_groups/lib/working_memory_channel.rb +140 -0
- data/examples/robot_groups/multi_process.rb +286 -0
- data/examples/robot_groups/robot_worker.rb +136 -0
- data/examples/robot_groups/same_process.rb +229 -0
- data/examples/timeframe_demo.rb +276 -0
- data/lib/htm/active_record_config.rb +1 -1
- data/lib/htm/circuit_breaker.rb +202 -0
- data/lib/htm/configuration.rb +59 -13
- data/lib/htm/database.rb +67 -36
- data/lib/htm/embedding_service.rb +39 -2
- data/lib/htm/errors.rb +131 -11
- data/lib/htm/jobs/generate_embedding_job.rb +5 -4
- data/lib/htm/jobs/generate_tags_job.rb +4 -0
- data/lib/htm/loaders/markdown_loader.rb +263 -0
- data/lib/htm/loaders/paragraph_chunker.rb +112 -0
- data/lib/htm/long_term_memory.rb +460 -343
- data/lib/htm/models/file_source.rb +99 -0
- data/lib/htm/models/node.rb +80 -5
- data/lib/htm/models/robot.rb +24 -1
- data/lib/htm/models/robot_node.rb +1 -0
- data/lib/htm/models/tag.rb +254 -4
- data/lib/htm/observability.rb +395 -0
- data/lib/htm/tag_service.rb +60 -3
- data/lib/htm/tasks.rb +26 -1
- data/lib/htm/timeframe.rb +194 -0
- data/lib/htm/timeframe_extractor.rb +307 -0
- data/lib/htm/version.rb +1 -1
- data/lib/htm/working_memory.rb +165 -70
- data/lib/htm.rb +328 -130
- data/lib/tasks/doc.rake +300 -0
- data/lib/tasks/files.rake +299 -0
- data/lib/tasks/htm.rake +158 -3
- data/lib/tasks/jobs.rake +3 -9
- data/lib/tasks/tags.rake +166 -6
- data/mkdocs.yml +36 -1
- data/notes/ARCHITECTURE_REVIEW.md +1167 -0
- data/notes/IMPLEMENTATION_SUMMARY.md +606 -0
- data/notes/MULTI_FRAMEWORK_IMPLEMENTATION.md +451 -0
- data/notes/next_steps.md +100 -0
- data/notes/plan.md +627 -0
- data/notes/tag_ontology_enhancement_ideas.md +222 -0
- data/notes/timescaledb_removal_summary.md +200 -0
- metadata +158 -17
- data/db/migrate/20250101000002_create_robots.rb +0 -14
- data/db/migrate/20250101000003_create_nodes.rb +0 -42
- data/db/migrate/20250101000005_create_tags.rb +0 -38
- data/db/migrate/20250101000007_add_node_vector_indexes.rb +0 -30
- data/db/migrate/20250125000001_add_content_hash_to_nodes.rb +0 -14
- data/db/migrate/20250125000002_create_robot_nodes.rb +0 -35
- data/db/migrate/20250125000003_remove_source_and_robot_id_from_nodes.rb +0 -28
- data/db/migrate/20250126000001_create_working_memories.rb +0 -19
- data/db/migrate/20250126000002_remove_unused_columns.rb +0 -12
- data/docs/database/public.working_memories.md +0 -40
- data/docs/database/public.working_memories.svg +0 -112
- data/lib/htm/models/working_memory_entry.rb +0 -88
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
|
|
@@ -141,7 +296,7 @@ namespace :htm do
|
|
|
141
296
|
end
|
|
142
297
|
|
|
143
298
|
namespace :doc do
|
|
144
|
-
desc "Generate/update database documentation in
|
|
299
|
+
desc "Generate/update database documentation in docs/database/ (uses .tbls.yml)"
|
|
145
300
|
task :db do
|
|
146
301
|
unless system("which tbls > /dev/null 2>&1")
|
|
147
302
|
puts "Error: 'tbls' is not installed."
|
|
@@ -172,7 +327,7 @@ namespace :htm do
|
|
|
172
327
|
sh "mkdocs serve"
|
|
173
328
|
end
|
|
174
329
|
|
|
175
|
-
desc "Generate DB docs, build site, and serve locally"
|
|
176
|
-
task :all => [:db, :build, :serve]
|
|
330
|
+
desc "Generate DB docs, YARD API docs, build site, and serve locally"
|
|
331
|
+
task :all => [:db, :yard, :build, :serve]
|
|
177
332
|
end
|
|
178
333
|
end
|
data/lib/tasks/jobs.rake
CHANGED
|
@@ -88,10 +88,7 @@ namespace :htm do
|
|
|
88
88
|
begin
|
|
89
89
|
# Use the service class directly (same as job)
|
|
90
90
|
result = HTM::EmbeddingService.generate(node.content)
|
|
91
|
-
node.update!(
|
|
92
|
-
embedding: result[:storage_embedding],
|
|
93
|
-
embedding_dimension: result[:dimension]
|
|
94
|
-
)
|
|
91
|
+
node.update!(embedding: result[:storage_embedding])
|
|
95
92
|
processed += 1
|
|
96
93
|
print "\rProcessed: #{processed}/#{total}"
|
|
97
94
|
rescue StandardError => e
|
|
@@ -191,10 +188,7 @@ namespace :htm do
|
|
|
191
188
|
begin
|
|
192
189
|
# Use the service class directly to regenerate
|
|
193
190
|
result = HTM::EmbeddingService.generate(node.content)
|
|
194
|
-
node.update!(
|
|
195
|
-
embedding: result[:storage_embedding],
|
|
196
|
-
embedding_dimension: result[:dimension]
|
|
197
|
-
)
|
|
191
|
+
node.update!(embedding: result[:storage_embedding])
|
|
198
192
|
processed += 1
|
|
199
193
|
print "\rProcessed: #{processed}/#{total}"
|
|
200
194
|
rescue StandardError => e
|
|
@@ -274,7 +268,7 @@ namespace :htm do
|
|
|
274
268
|
HTM::ActiveRecordConfig.establish_connection!
|
|
275
269
|
|
|
276
270
|
puts "Clearing embeddings..."
|
|
277
|
-
HTM::Models::Node.update_all(embedding: nil
|
|
271
|
+
HTM::Models::Node.update_all(embedding: nil)
|
|
278
272
|
|
|
279
273
|
puts "Clearing tags..."
|
|
280
274
|
HTM::Models::NodeTag.delete_all
|
data/lib/tasks/tags.rake
CHANGED
|
@@ -10,25 +10,185 @@
|
|
|
10
10
|
|
|
11
11
|
namespace :htm do
|
|
12
12
|
namespace :tags do
|
|
13
|
-
desc "Display tags as a hierarchical tree"
|
|
14
|
-
task :tree do
|
|
13
|
+
desc "Display tags as a hierarchical tree (text format). Optional prefix filter."
|
|
14
|
+
task :tree, [:prefix] do |_t, args|
|
|
15
15
|
require 'htm'
|
|
16
16
|
|
|
17
17
|
# Ensure database connection
|
|
18
18
|
HTM::ActiveRecordConfig.establish_connection!
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
tags = args[:prefix] ? HTM::Models::Tag.with_prefix(args[:prefix]) : HTM::Models::Tag.all
|
|
21
|
+
count = tags.count
|
|
21
22
|
|
|
22
23
|
if count.zero?
|
|
23
|
-
puts "No tags found in database."
|
|
24
|
+
puts args[:prefix] ? "No tags found with prefix '#{args[:prefix]}'." : "No tags found in database."
|
|
24
25
|
next
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
# Display tree using Tag model method
|
|
28
|
-
puts "\nHTM Tags Tree"
|
|
29
|
+
puts "\nHTM Tags Tree#{args[:prefix] ? " (prefix: #{args[:prefix]})" : ''}"
|
|
29
30
|
puts "=" * 40
|
|
30
|
-
print
|
|
31
|
+
print tags.tree_string
|
|
31
32
|
puts "\nTotal tags: #{count}"
|
|
32
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
|
|
33
193
|
end
|
|
34
194
|
end
|
data/mkdocs.yml
CHANGED
|
@@ -114,6 +114,7 @@ markdown_extensions:
|
|
|
114
114
|
repo_url_shorthand: true
|
|
115
115
|
user: madbomber
|
|
116
116
|
repo: htm
|
|
117
|
+
normalize_issue_symbols: true
|
|
117
118
|
- pymdownx.mark
|
|
118
119
|
- pymdownx.smartsymbols
|
|
119
120
|
- pymdownx.snippets:
|
|
@@ -205,6 +206,40 @@ nav:
|
|
|
205
206
|
- Long-Term Memory: api/long-term-memory.md
|
|
206
207
|
- Embedding Service: api/embedding-service.md
|
|
207
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
|
|
208
243
|
- Development:
|
|
209
244
|
- development/index.md
|
|
210
245
|
- Setup: development/setup.md
|
|
@@ -217,7 +252,7 @@ nav:
|
|
|
217
252
|
- Robots: database/public.robots.md
|
|
218
253
|
- Nodes: database/public.nodes.md
|
|
219
254
|
- Tags: database/public.tags.md
|
|
220
|
-
-
|
|
255
|
+
- File Sources: database/public.file_sources.md
|
|
221
256
|
- Join Tables:
|
|
222
257
|
- Node Tags: database/public.node_tags.md
|
|
223
258
|
- Nodes Tags (Legacy): database/public.nodes_tags.md
|