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
@@ -1,6 +1,6 @@
1
1
  # HTM Rake Tasks Reference
2
2
 
3
- Complete reference for all HTM rake tasks. HTM provides 44 rake tasks organized into five namespaces for managing the database, documentation, file loading, background jobs, and tag management.
3
+ Complete reference for all HTM rake tasks. HTM provides 46+ rake tasks organized into five namespaces for managing the database, documentation, file loading, background jobs, and tag management.
4
4
 
5
5
  ## Quick Reference
6
6
 
@@ -337,6 +337,64 @@ $ rake htm:db:reset
337
337
 
338
338
  ---
339
339
 
340
+ #### `rake htm:db:purge_all`
341
+
342
+ Permanently removes all soft-deleted records from all tables, including orphaned join table entries, orphaned propositions, and orphaned robots.
343
+
344
+ !!! danger "Warning"
345
+ This task permanently deletes data and cannot be undone!
346
+
347
+ ```bash
348
+ $ rake htm:db:purge_all
349
+
350
+ HTM Purge All Soft-Deleted Records
351
+ ============================================================
352
+
353
+ Records to permanently delete:
354
+ --------------------------------------------------------------
355
+ Soft-deleted nodes: 23
356
+ Soft-deleted node_tags: 45
357
+ Soft-deleted robot_nodes: 12
358
+ Orphaned node_tags: 3
359
+ Orphaned robot_nodes: 1
360
+ Orphaned propositions: 5
361
+ Orphaned robots (no nodes): 2
362
+ --------------------------------------------------------------
363
+ Total records to delete: 91
364
+
365
+ Proceed with permanent deletion? (yes/no): yes
366
+
367
+ Deleting records...
368
+ Deleted 45 soft-deleted node_tags entries
369
+ Deleted 3 orphaned node_tags entries
370
+ Deleted 12 soft-deleted robot_nodes entries
371
+ Deleted 1 orphaned robot_nodes entries
372
+ Deleted 5 orphaned propositions
373
+ Deleted 23 soft-deleted nodes
374
+ Deleted 2 orphaned robots
375
+
376
+ ✓ Purge complete!
377
+ ```
378
+
379
+ **What it removes:**
380
+
381
+ - **Soft-deleted records**: Nodes, node_tags, and robot_nodes with `deleted_at` set
382
+ - **Orphaned join entries**: node_tags and robot_nodes pointing to non-existent nodes
383
+ - **Orphaned propositions**: Proposition nodes whose `source_node_id` no longer exists
384
+ - **Orphaned robots**: Robots with no associated memory nodes
385
+
386
+ **Deletion order** (for referential integrity):
387
+
388
+ 1. Soft-deleted node_tags
389
+ 2. Orphaned node_tags
390
+ 3. Soft-deleted robot_nodes
391
+ 4. Orphaned robot_nodes
392
+ 5. Orphaned propositions
393
+ 6. Soft-deleted nodes
394
+ 7. Orphaned robots
395
+
396
+ ---
397
+
340
398
  ## Documentation Tasks (`htm:doc:*`)
341
399
 
342
400
  Tasks for generating API documentation, database diagrams, and building the documentation site.
@@ -645,75 +703,62 @@ Sync Status:
645
703
 
646
704
  ## Job Tasks (`htm:jobs:*`)
647
705
 
648
- Tasks for managing HTM background jobs (embedding generation, tag extraction, proposition extraction).
706
+ Tasks for managing HTM background jobs (embedding generation, tag extraction, proposition extraction). All processing tasks include progress bars with ETA display for visual feedback during long-running operations.
649
707
 
650
708
  ### Processing Jobs
651
709
 
652
- #### `rake htm:jobs:process`
710
+ #### `rake htm:jobs:process_all`
653
711
 
654
- Processes all pending background jobs (embeddings, tags, propositions).
712
+ Processes all pending background jobs in sequence: embeddings, then tags, then propositions.
655
713
 
656
714
  ```bash
657
- $ rake htm:jobs:process
658
- Processing pending jobs...
659
- Embedding jobs: 5 pending
660
- Tag jobs: 8 pending
661
- Proposition jobs: 0 pending
662
- Processing...
663
- ✓ Processed 13 jobs (13 successful, 0 failed)
715
+ $ rake htm:jobs:process_all
716
+ # Runs process_embeddings, process_tags, process_propositions in sequence
664
717
  ```
665
718
 
666
719
  ---
667
720
 
668
721
  #### `rake htm:jobs:process_embeddings`
669
722
 
670
- Processes only pending embedding generation jobs.
723
+ Processes nodes without embeddings, generating vector embeddings via the configured LLM provider. Shows a progress bar with ETA for visual feedback.
671
724
 
672
725
  ```bash
673
726
  $ rake htm:jobs:process_embeddings
674
- Processing embedding jobs...
675
- 5 pending jobs
676
- Processing...
677
- ✓ Node 1542 - embedding generated (768 dimensions)
678
- ✓ Node 1543 - embedding generated (768 dimensions)
679
- ...
680
- ✓ Processed 5 embedding jobs
727
+ Processing 50 nodes without embeddings...
728
+ Embeddings: |████████████████████████████████| 50/50 (100%) Time: 00:01:45
729
+ ✓ Generated embeddings for 50 nodes
681
730
  ```
682
731
 
732
+ **Progress bar format:** `Title: |████████████| count/total (percent%) ETA: mm:ss`
733
+
683
734
  ---
684
735
 
685
736
  #### `rake htm:jobs:process_tags`
686
737
 
687
- Processes only pending tag extraction jobs.
738
+ Processes nodes without tags, extracting hierarchical tags via the configured LLM provider. Shows a progress bar with ETA for visual feedback.
688
739
 
689
740
  ```bash
690
741
  $ rake htm:jobs:process_tags
691
- Processing tag jobs...
692
- 8 pending jobs
693
- Processing...
694
- ✓ Node 1542 - extracted 3 tags
695
- ✓ Node 1543 - extracted 2 tags
696
- ...
697
- ✓ Processed 8 tag jobs
742
+ Processing 50 nodes without tags...
743
+ Tags: |████████████████████████████████| 50/50 (100%) Time: 00:02:30
744
+ ✓ Extracted tags for 50 nodes
698
745
  ```
699
746
 
700
747
  ---
701
748
 
702
749
  #### `rake htm:jobs:process_propositions`
703
750
 
704
- Processes only pending proposition extraction jobs.
751
+ Extracts atomic propositions from nodes that haven't been processed yet. Tracks processed nodes via `source_node_id` metadata on proposition nodes. Shows a progress bar with ETA.
705
752
 
706
753
  ```bash
707
754
  $ rake htm:jobs:process_propositions
708
- Processing proposition jobs...
709
- 3 pending jobs
710
- Processing...
711
- ✓ Node 1542 - extracted 5 propositions
712
- ✓ Node 1543 - extracted 3 propositions
713
- ...
714
- ✓ Processed 3 proposition jobs, created 12 proposition nodes
755
+ Processing 25 nodes for proposition extraction...
756
+ Propositions: |████████████████████████████████| 25/25 (100%) Time: 00:03:15
757
+ ✓ Extracted propositions from 25 nodes, created 89 proposition nodes
715
758
  ```
716
759
 
760
+ **Note:** Only nodes that don't already have propositions extracted will be processed. The task tracks this by checking for proposition nodes with matching `source_node_id` in metadata.
761
+
717
762
  ---
718
763
 
719
764
  ### Job Status
@@ -57,7 +57,7 @@ The server logs to STDERR to avoid corrupting the JSON-RPC protocol on STDOUT.
57
57
 
58
58
  ## CLI Commands
59
59
 
60
- The `htm_mcp` executable includes management commands for database setup and diagnostics:
60
+ The `htm_mcp` executable includes management commands for database setup, diagnostics, and rake task execution:
61
61
 
62
62
  | Command | Description |
63
63
  |---------|-------------|
@@ -69,6 +69,9 @@ The `htm_mcp` executable includes management commands for database setup and dia
69
69
  | `htm_mcp stats` | Show memory statistics (nodes, tags, robots, database size) |
70
70
  | `htm_mcp version` | Show HTM version |
71
71
  | `htm_mcp help` | Show help with all environment variables |
72
+ | `htm_mcp rake <task>` | Run any HTM rake task |
73
+ | `htm_mcp rake -T` | List all available HTM rake tasks |
74
+ | `htm_mcp rake -T <pattern>` | List HTM rake tasks matching pattern |
72
75
 
73
76
  ### First-Time Setup
74
77
 
@@ -101,6 +104,72 @@ Migration Status
101
104
  3 applied, 1 pending
102
105
  ```
103
106
 
107
+ ### Rake Task Passthrough
108
+
109
+ The `htm_mcp rake` command allows you to run any HTM rake task directly through the MCP CLI. This is useful when working with HTM without a full Rails/Rake environment.
110
+
111
+ **List all available tasks:**
112
+
113
+ ```bash
114
+ $ htm_mcp rake -T
115
+ # or
116
+ $ htm_mcp rake --tasks
117
+
118
+ HTM Rake Tasks
119
+ ================================================================================
120
+ htm:db:console # Open psql console to database
121
+ htm:db:create # Create the database if it doesn't exist
122
+ htm:db:drop # Drop all HTM tables (WARNING: destructive!)
123
+ htm:db:info # Show database information
124
+ htm:db:migrate # Run pending database migrations
125
+ htm:db:purge_all # Permanently delete all soft-deleted records
126
+ ...
127
+ ```
128
+
129
+ **Filter tasks by pattern** (like standard `rake -T`):
130
+
131
+ ```bash
132
+ $ htm_mcp rake -T htm:jobs
133
+
134
+ HTM Rake Tasks
135
+ ================================================================================
136
+ htm:jobs:process_all # Process all pending jobs (embeddings, tags, propositions)
137
+ htm:jobs:process_embeddings # Process pending embedding jobs
138
+ htm:jobs:process_propositions # Process pending proposition extraction jobs
139
+ htm:jobs:process_tags # Process pending tag extraction jobs
140
+ htm:jobs:stats # Show job processing statistics
141
+
142
+ $ htm_mcp rake -T db:rebuild
143
+
144
+ HTM Rake Tasks
145
+ ================================================================================
146
+ htm:db:rebuild:embeddings # Clear and regenerate all embeddings
147
+ htm:db:rebuild:propositions # Extract propositions from all non-proposition nodes
148
+ ```
149
+
150
+ **Run specific tasks:**
151
+
152
+ ```bash
153
+ # Database tasks
154
+ $ htm_mcp rake htm:db:stats
155
+ $ htm_mcp rake htm:db:verify
156
+ $ htm_mcp rake htm:db:purge_all
157
+
158
+ # Job processing tasks
159
+ $ htm_mcp rake htm:jobs:process_all
160
+ $ htm_mcp rake htm:jobs:process_embeddings
161
+
162
+ # Tag tasks
163
+ $ htm_mcp rake htm:tags:tree
164
+ $ htm_mcp rake 'htm:tags:tree[database]' # With argument
165
+
166
+ # File tasks
167
+ $ htm_mcp rake htm:files:list
168
+ $ htm_mcp rake htm:files:sync
169
+ ```
170
+
171
+ **Note:** Tasks requiring arguments use the standard rake syntax with brackets quoted for shell safety: `htm_mcp rake 'htm:files:load[path/to/file.md]'`
172
+
104
173
  ## Tools Reference
105
174
 
106
175
  ### SetRobotTool
data/examples/.envrc ADDED
@@ -0,0 +1,6 @@
1
+ # htm/examples/.envrc
2
+
3
+ source_up
4
+
5
+ export HTM_ENV=examples
6
+ export HTM_DATABASE__URL="postgresql://dewayne@localhost:5432/htm_$HTM_ENV"
@@ -0,0 +1,2 @@
1
+ *.log
2
+ *.log.0
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Creates and sets up the htm_examples database
5
+ #
6
+ # This script should be run before any other examples to ensure
7
+ # the examples database exists and has the correct schema.
8
+ #
9
+ # Run via:
10
+ # ruby examples/00_create_examples_db.rb
11
+ # # or
12
+ # ./examples/00_create_examples_db.rb
13
+
14
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
15
+
16
+ # Set examples environment BEFORE loading HTM
17
+ ENV['HTM_ENV'] = 'examples'
18
+
19
+ service_name = ENV['HTM_SERVICE__NAME'] || 'htm'
20
+ db_name = "#{service_name}_examples"
21
+ db_url = "postgresql://#{ENV['USER']}@localhost:5432/#{db_name}"
22
+
23
+ ENV['HTM_DATABASE__URL'] = db_url
24
+
25
+ puts <<~HEADER
26
+
27
+ ==========================================
28
+ == HTM Examples Database Setup ==
29
+ ==========================================
30
+
31
+ Database: #{db_name}
32
+
33
+ HEADER
34
+
35
+ # Step 1: Create database if it doesn't exist
36
+ puts "1. Checking if database exists..."
37
+
38
+ check_cmd = "psql -lqt | cut -d \\| -f 1 | grep -qw #{db_name}"
39
+ db_exists = system(check_cmd)
40
+
41
+ if db_exists
42
+ puts " Database '#{db_name}' already exists."
43
+ else
44
+ puts " Creating database '#{db_name}'..."
45
+ unless system("createdb #{db_name}")
46
+ abort " ERROR: Failed to create database '#{db_name}'"
47
+ end
48
+ puts " Database created."
49
+ end
50
+
51
+ # Step 2: Enable extensions
52
+ puts "\n2. Enabling PostgreSQL extensions..."
53
+
54
+ extensions_sql = <<~SQL
55
+ CREATE EXTENSION IF NOT EXISTS vector;
56
+ CREATE EXTENSION IF NOT EXISTS pg_trgm;
57
+ SQL
58
+
59
+ unless system("psql -d #{db_name} -c \"#{extensions_sql}\" > /dev/null 2>&1")
60
+ abort " ERROR: Failed to enable extensions"
61
+ end
62
+ puts " Extensions enabled (pgvector, pg_trgm)."
63
+
64
+ # Step 3: Run migrations
65
+ puts "\n3. Running schema migrations..."
66
+
67
+ require "htm"
68
+
69
+ HTM.configure do |config|
70
+ config.job.backend = :inline
71
+ config.log_level = :info
72
+ config.telemetry_enabled = false
73
+ end
74
+
75
+ begin
76
+ HTM::SequelConfig.establish_connection!
77
+ HTM::Database.setup
78
+ puts " Schema setup complete."
79
+ rescue => e
80
+ abort " ERROR: #{e.message}"
81
+ end
82
+
83
+ puts <<~FOOTER
84
+
85
+ ==========================================
86
+ Examples database is ready!
87
+
88
+ You can now run examples:
89
+ ruby examples/basic_usage.rb
90
+ rake examples:basic
91
+ rake examples:all
92
+ ==========================================
93
+
94
+ FOOTER
@@ -4,25 +4,21 @@
4
4
  # Basic usage example for HTM
5
5
  #
6
6
  # Prerequisites:
7
- # 1. Configure database via environment or config file:
8
- # - HTM_DATABASE__URL="postgresql://user@localhost:5432/htm_development"
9
- # - Or individual vars: HTM_DATABASE__HOST, HTM_DATABASE__NAME, etc.
10
- # 2. Initialize database schema: rake htm:db:setup
11
- # 3. Install dependencies: bundle install
7
+ # 1. Set up examples database: rake examples:setup
8
+ # 2. Install dependencies: bundle install
9
+ #
10
+ # Run via:
11
+ # rake examples:basic
12
+ # # or
13
+ # ruby examples/basic_usage.rb
12
14
 
13
- require_relative '../lib/htm'
15
+ require_relative 'examples_helper'
14
16
 
15
- puts "HTM Basic Usage Example"
16
- puts "=" * 60
17
+ ExamplesHelper.section "HTM Basic Usage Example"
18
+ ExamplesHelper.print_environment
17
19
 
18
- # Check database configuration using the config system
19
- unless HTM.config.database_configured?
20
- puts "ERROR: Database not configured. Set one of:"
21
- puts " export HTM_DATABASE__URL=\"postgresql://user@localhost:5432/htm_development\""
22
- puts " Or configure in ~/.config/htm/htm.yml"
23
- puts "Run 'bin/htm_mcp help' for all configuration options."
24
- exit 1
25
- end
20
+ # Verify database is available
21
+ ExamplesHelper.require_database!
26
22
 
27
23
  begin
28
24
  # Configure HTM globally (uses Ollama by default from defaults.yml)
@@ -5,11 +5,21 @@
5
5
  #
6
6
  # This example demonstrates how to configure HTM with custom LLM methods
7
7
  # for embedding generation and tag extraction, as well as using defaults.
8
+ #
9
+ # Prerequisites:
10
+ # 1. Set up examples database: rake examples:setup
11
+ # 2. Install dependencies: bundle install
12
+ #
13
+ # Run via:
14
+ # ruby examples/custom_llm_configuration.rb
8
15
 
9
- require_relative '../lib/htm'
16
+ require_relative 'examples_helper'
10
17
 
11
- puts "HTM Custom LLM Configuration Example"
12
- puts "=" * 50
18
+ ExamplesHelper.section "HTM Custom LLM Configuration Example"
19
+ ExamplesHelper.print_environment
20
+
21
+ # Verify database is available
22
+ ExamplesHelper.require_database!
13
23
 
14
24
  # Example 1: Use Default Configuration (RubyLLM with Ollama)
15
25
  puts "\n1. Using Default Configuration (RubyLLM + Ollama)"
@@ -10,24 +10,21 @@
10
10
  # - Unloading files
11
11
  #
12
12
  # Prerequisites:
13
- # 1. Set HTM_DATABASE__URL environment variable (see SETUP.md)
14
- # 2. Initialize database schema: rake db_setup
15
- # 3. Install dependencies: bundle install
13
+ # 1. Set up examples database: rake examples:setup
14
+ # 2. Install dependencies: bundle install
15
+ #
16
+ # Run via:
17
+ # ruby examples/file_loader_usage.rb
16
18
 
17
- require_relative '../lib/htm'
19
+ require_relative 'examples_helper'
18
20
  require 'tempfile'
19
21
  require 'fileutils'
20
22
 
21
- puts "HTM File Loader Example"
22
- puts "=" * 60
23
+ ExamplesHelper.section "HTM File Loader Example"
24
+ ExamplesHelper.print_environment
23
25
 
24
- # Check environment
25
- unless ENV['HTM_DATABASE__URL']
26
- puts "ERROR: HTM_DATABASE__URL not set. Please set it:"
27
- puts " export HTM_DATABASE__URL=\"postgresql://postgres@localhost:5432/htm_development\""
28
- puts "See SETUP.md for details."
29
- exit 1
30
- end
26
+ # Verify database is available
27
+ ExamplesHelper.require_database!
31
28
 
32
29
  begin
33
30
  # Configure HTM globally (uses Ollama by default)
@@ -102,7 +99,7 @@ begin
102
99
  puts " Skipped: #{result[:skipped]}"
103
100
 
104
101
  # Access the file source to show frontmatter
105
- source = HTM::Models::FileSource.find(result[:file_source_id])
102
+ source = HTM::Models::FileSource[result[:file_source_id]]
106
103
  puts " Frontmatter title: #{source.title}"
107
104
  puts " Frontmatter author: #{source.author}"
108
105
  puts " Frontmatter tags: #{source.frontmatter_tags.join(', ')}"
@@ -3,10 +3,17 @@
3
3
 
4
4
  # Timeframe Demo - Demonstrates the various ways to use timeframes with recall
5
5
  #
6
- # Run with:
7
- # HTM_DATABASE__URL="postgresql://localhost/htm_development" ruby examples/timeframe_demo.rb
6
+ # Prerequisites:
7
+ # 1. Set up examples database: rake examples:setup
8
+ # 2. Install dependencies: bundle install
9
+ #
10
+ # Run via:
11
+ # rake examples:basic # runs basic_usage.rb
12
+ # ruby examples/timeframe_demo.rb
13
+
14
+ require_relative 'examples_helper'
8
15
 
9
- require_relative "../lib/htm"
16
+ ExamplesHelper.require_database!
10
17
 
11
18
  puts <<~HEADER
12
19
  ╔══════════════════════════════════════════════════════════════════╗
@@ -2,27 +2,27 @@
2
2
  # Example HTM Application
3
3
  #
4
4
  # This demonstrates a simple application using the HTM gem with full RubyLLM integration.
5
+ #
6
+ # Prerequisites:
7
+ # 1. Set up examples database: rake examples:setup
8
+ # 2. Install dependencies: bundle install
9
+ #
10
+ # Run via:
11
+ # ruby examples/example_app/app.rb
5
12
 
6
- require_relative '../../lib/htm'
13
+ require_relative '../examples_helper'
7
14
  require 'ruby_llm'
8
15
  require 'logger'
9
16
 
10
17
  class ExampleApp
11
18
  def self.run
12
19
  puts "\n=== HTM Full-Featured Example Application ==="
13
- puts "\nChecking database connection..."
14
-
15
- # Check if database is configured
16
- config = HTM::Database.default_config
17
- unless config
18
- puts "\n⚠ Database not configured!"
19
- puts "Set HTM_DATABASE__URL environment variable:"
20
- puts " export HTM_DATABASE__URL='postgresql://user:pass@host:port/dbname'"
21
- puts "\nOr run: rake app:bootstrap"
22
- return
23
- end
20
+ ExamplesHelper.print_environment
21
+
22
+ # Verify database is available
23
+ ExamplesHelper.require_database!
24
24
 
25
- puts "Database configured: #{config[:dbname]} @ #{config[:host]}"
25
+ puts "Database configured: #{HTM.config.actual_database_name}"
26
26
 
27
27
  # Configure HTM with RubyLLM for embeddings and tag generation
28
28
  puts "\nConfiguring HTM with RubyLLM..."
@@ -95,7 +95,7 @@ class ExampleApp
95
95
  # Check what was generated
96
96
  puts "\n--- Generated Tags ---"
97
97
  [node_1, node_2, node_3].each do |node_id|
98
- node = HTM::Models::Node.includes(:tags).find(node_id)
98
+ node = HTM::Models::Node[node_id]
99
99
  if node.tags.any?
100
100
  puts "Node #{node_id}:"
101
101
  node.tags.each { |tag| puts " - #{tag.name}" }
@@ -107,7 +107,7 @@ class ExampleApp
107
107
  # Check embeddings
108
108
  puts "\n--- Embedding Status ---"
109
109
  [node_1, node_2, node_3].each do |node_id|
110
- node = HTM::Models::Node.find(node_id)
110
+ node = HTM::Models::Node[node_id]
111
111
  if node.embedding
112
112
  dimensions = node.embedding.is_a?(Array) ? node.embedding.size : node.embedding_dimension
113
113
  status = "✓ Generated (#{dimensions} dimensions)"
@@ -9,15 +9,18 @@
9
9
  # - Progress feedback
10
10
  # - Database persistence
11
11
  #
12
+ # Prerequisites:
13
+ # 1. Set up examples database: rake examples:setup
14
+ # 2. Install dependencies: bundle install
15
+ #
12
16
  # Usage:
13
- # ruby htm_cli.rb
17
+ # ruby examples/cli_app/htm_cli.rb
14
18
  #
15
19
  # Environment:
16
- # HTM_DATABASE__URL - PostgreSQL connection URL (required)
17
20
  # OLLAMA_URL - Ollama server URL (default: http://localhost:11434)
18
21
  #
19
22
 
20
- require_relative '../../lib/htm'
23
+ require_relative '../examples_helper'
21
24
  require 'io/console'
22
25
  require 'ruby_llm'
23
26
 
@@ -86,7 +89,7 @@ class HTMCli
86
89
 
87
90
  loop do
88
91
  print "\nhtm> "
89
- input = gets&.chomp
92
+ input = $stdin.gets&.chomp
90
93
  break if input.nil? || input == 'exit'
91
94
 
92
95
  handle_command(input)
@@ -139,7 +142,7 @@ class HTMCli
139
142
  puts "[✓] Stored as node #{node_id} (#{duration}ms)"
140
143
 
141
144
  # Show what was generated (inline mode, so already complete)
142
- node = HTM::Models::Node.includes(:tags).find(node_id)
145
+ node = HTM::Models::Node[node_id]
143
146
 
144
147
  if node.embedding
145
148
  puts " Embedding: #{node.embedding_dimension} dimensions"
@@ -217,7 +220,7 @@ class HTMCli
217
220
  end
218
221
 
219
222
  # Show tags if any
220
- node = HTM::Models::Node.includes(:tags).find(memory['id'])
223
+ node = HTM::Models::Node[memory['id']]
221
224
  if node.tags.any?
222
225
  puts " Tags: #{node.tags.map(&:name).join(', ')}"
223
226
  else
@@ -259,10 +262,10 @@ class HTMCli
259
262
  puts
260
263
 
261
264
  # Get all tags with their nodes, optionally filtered by prefix
262
- tags_query = HTM::Models::Tag.includes(:nodes).order(:name)
263
- tags_query = tags_query.where("name LIKE ?", "#{filter}%") if filter && !filter.empty?
265
+ tags_query = HTM::Models::Tag.order(:name)
266
+ tags_query = tags_query.where(Sequel.like(:name, "#{filter}%")) if filter && !filter.empty?
264
267
 
265
- tags = tags_query.to_a
268
+ tags = tags_query.eager(:nodes).all
266
269
 
267
270
  if tags.empty?
268
271
  if filter
@@ -308,8 +311,8 @@ class HTMCli
308
311
  puts
309
312
 
310
313
  total_nodes = HTM::Models::Node.count
311
- nodes_with_embeddings = HTM::Models::Node.where.not(embedding: nil).count
312
- nodes_with_tags = HTM::Models::Node.joins(:tags).distinct.count
314
+ nodes_with_embeddings = HTM::Models::Node.exclude(embedding: nil).count
315
+ nodes_with_tags = HTM::Models::NodeTag.distinct.select(:node_id).count
313
316
  total_tags = HTM::Models::Tag.count
314
317
  total_robots = HTM::Models::Robot.count
315
318
 
@@ -376,17 +379,7 @@ class HTMCli
376
379
  end
377
380
 
378
381
  # Check database configuration
379
- unless ENV['HTM_DATABASE__URL']
380
- puts
381
- puts "[✗] Error: HTM_DATABASE__URL environment variable not set"
382
- puts
383
- puts "Please set your database connection URL:"
384
- puts " export HTM_DATABASE__URL='postgresql://postgres@localhost:5432/htm_development'"
385
- puts
386
- puts "See SETUP.md for database setup instructions."
387
- puts
388
- exit 1
389
- end
382
+ ExamplesHelper.require_database!
390
383
 
391
384
  # Check Ollama connection (optional but recommended)
392
385
  begin