htm 0.0.18 → 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 (216) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +119 -1
  3. data/README.md +12 -0
  4. data/Rakefile +104 -18
  5. data/db/migrate/00001_enable_extensions.rb +9 -5
  6. data/db/migrate/00002_create_robots.rb +18 -6
  7. data/db/migrate/00003_create_file_sources.rb +30 -17
  8. data/db/migrate/00004_create_nodes.rb +60 -48
  9. data/db/migrate/00005_create_tags.rb +24 -12
  10. data/db/migrate/00006_create_node_tags.rb +28 -13
  11. data/db/migrate/00007_create_robot_nodes.rb +40 -26
  12. data/db/schema.sql +17 -1
  13. data/db/seeds.rb +34 -34
  14. data/docs/api/embedding-service.md +140 -110
  15. data/docs/api/yard/HTM/ActiveRecordConfig.md +6 -0
  16. data/docs/api/yard/HTM/Config.md +173 -0
  17. data/docs/api/yard/HTM/ConfigSection.md +28 -0
  18. data/docs/api/yard/HTM/Database.md +1 -1
  19. data/docs/api/yard/HTM/Railtie.md +2 -2
  20. data/docs/api/yard/HTM.md +0 -57
  21. data/docs/api/yard/index.csv +76 -61
  22. data/docs/api/yard-reference.md +2 -1
  23. data/docs/architecture/adrs/003-ollama-embeddings.md +45 -36
  24. data/docs/architecture/adrs/004-hive-mind.md +1 -1
  25. data/docs/architecture/adrs/008-robot-identification.md +1 -1
  26. data/docs/architecture/index.md +11 -9
  27. data/docs/architecture/overview.md +11 -7
  28. data/docs/assets/images/balanced-strategy-decay.svg +41 -0
  29. data/docs/assets/images/class-hierarchy.svg +1 -1
  30. data/docs/assets/images/eviction-priority.svg +43 -0
  31. data/docs/assets/images/exception-hierarchy.svg +2 -2
  32. data/docs/assets/images/hive-mind-shared-memory.svg +52 -0
  33. data/docs/assets/images/htm-architecture-overview.svg +3 -3
  34. data/docs/assets/images/htm-core-components.svg +4 -4
  35. data/docs/assets/images/htm-layered-architecture.svg +1 -1
  36. data/docs/assets/images/htm-memory-addition-flow.svg +2 -2
  37. data/docs/assets/images/htm-memory-recall-flow.svg +2 -2
  38. data/docs/assets/images/memory-topology.svg +53 -0
  39. data/docs/assets/images/two-tier-memory-architecture.svg +55 -0
  40. data/docs/database/naming-convention.md +244 -0
  41. data/docs/database_rake_tasks.md +31 -0
  42. data/docs/development/rake-tasks.md +80 -35
  43. data/docs/development/setup.md +76 -44
  44. data/docs/examples/basic-usage.md +133 -0
  45. data/docs/examples/config-files.md +170 -0
  46. data/docs/examples/file-loading.md +208 -0
  47. data/docs/examples/index.md +116 -0
  48. data/docs/examples/llm-configuration.md +168 -0
  49. data/docs/examples/mcp-client.md +172 -0
  50. data/docs/examples/rails-integration.md +173 -0
  51. data/docs/examples/robot-groups.md +210 -0
  52. data/docs/examples/sinatra-integration.md +218 -0
  53. data/docs/examples/standalone-app.md +216 -0
  54. data/docs/examples/telemetry.md +224 -0
  55. data/docs/examples/timeframes.md +143 -0
  56. data/docs/getting-started/installation.md +97 -40
  57. data/docs/getting-started/quick-start.md +28 -11
  58. data/docs/guides/configuration.md +515 -0
  59. data/docs/guides/file-loading.md +322 -0
  60. data/docs/guides/getting-started.md +40 -9
  61. data/docs/guides/index.md +3 -3
  62. data/docs/guides/mcp-server.md +100 -13
  63. data/docs/guides/propositions.md +264 -0
  64. data/docs/guides/recalling-memories.md +4 -4
  65. data/docs/guides/search-strategies.md +3 -3
  66. data/docs/guides/tags.md +318 -0
  67. data/docs/guides/telemetry.md +229 -0
  68. data/docs/index.md +8 -16
  69. data/docs/{architecture → robots}/hive-mind.md +8 -111
  70. data/docs/robots/index.md +73 -0
  71. data/docs/{guides → robots}/multi-robot.md +3 -3
  72. data/docs/{guides → robots}/robot-groups.md +8 -7
  73. data/docs/{architecture → robots}/two-tier-memory.md +13 -149
  74. data/docs/robots/why-robots.md +85 -0
  75. data/examples/.envrc +6 -0
  76. data/examples/.gitignore +2 -0
  77. data/examples/00_create_examples_db.rb +94 -0
  78. data/examples/{basic_usage.rb → 01_basic_usage.rb} +12 -16
  79. data/examples/{custom_llm_configuration.rb → 03_custom_llm_configuration.rb} +13 -3
  80. data/examples/{file_loader_usage.rb → 04_file_loader_usage.rb} +11 -14
  81. data/examples/{timeframe_demo.rb → 05_timeframe_demo.rb} +10 -3
  82. data/examples/{example_app → 06_example_app}/app.rb +15 -15
  83. data/examples/{cli_app → 07_cli_app}/htm_cli.rb +15 -22
  84. data/examples/08_sinatra_app/Gemfile.lock +241 -0
  85. data/examples/{sinatra_app → 08_sinatra_app}/app.rb +19 -18
  86. data/examples/{mcp_client.rb → 09_mcp_client.rb} +5 -8
  87. data/examples/{telemetry → 10_telemetry}/SETUP_README.md +1 -1
  88. data/examples/{telemetry → 10_telemetry}/demo.rb +14 -10
  89. data/examples/11_robot_groups/README.md +335 -0
  90. data/examples/{robot_groups → 11_robot_groups/lib}/robot_worker.rb +17 -3
  91. data/examples/{robot_groups → 11_robot_groups}/multi_process.rb +9 -9
  92. data/examples/{robot_groups → 11_robot_groups}/same_process.rb +9 -12
  93. data/examples/{rails_app → 12_rails_app}/Gemfile +3 -0
  94. data/examples/{rails_app → 12_rails_app}/Gemfile.lock +87 -58
  95. data/examples/{rails_app → 12_rails_app}/app/controllers/dashboard_controller.rb +10 -6
  96. data/examples/{rails_app → 12_rails_app}/app/controllers/files_controller.rb +5 -5
  97. data/examples/{rails_app → 12_rails_app}/app/controllers/memories_controller.rb +11 -7
  98. data/examples/{rails_app → 12_rails_app}/app/controllers/robots_controller.rb +8 -8
  99. data/examples/12_rails_app/app/controllers/tags_controller.rb +36 -0
  100. data/examples/{rails_app → 12_rails_app}/app/views/dashboard/index.html.erb +2 -2
  101. data/examples/{rails_app → 12_rails_app}/app/views/files/new.html.erb +5 -2
  102. data/examples/{rails_app → 12_rails_app}/app/views/memories/_memory_card.html.erb +3 -3
  103. data/examples/{rails_app → 12_rails_app}/app/views/memories/deleted.html.erb +3 -3
  104. data/examples/{rails_app → 12_rails_app}/app/views/memories/edit.html.erb +3 -3
  105. data/examples/{rails_app → 12_rails_app}/app/views/memories/show.html.erb +4 -4
  106. data/examples/{rails_app → 12_rails_app}/app/views/robots/index.html.erb +2 -2
  107. data/examples/{rails_app → 12_rails_app}/app/views/robots/show.html.erb +4 -4
  108. data/examples/{rails_app → 12_rails_app}/app/views/search/index.html.erb +1 -1
  109. data/examples/{rails_app → 12_rails_app}/app/views/tags/index.html.erb +2 -2
  110. data/examples/{rails_app → 12_rails_app}/app/views/tags/show.html.erb +1 -1
  111. data/examples/12_rails_app/config/initializers/htm.rb +7 -0
  112. data/examples/12_rails_app/config/initializers/rack.rb +5 -0
  113. data/examples/README.md +230 -211
  114. data/examples/examples_helper.rb +138 -0
  115. data/lib/htm/config/builder.rb +167 -0
  116. data/lib/htm/config/database.rb +317 -0
  117. data/lib/htm/config/defaults.yml +41 -13
  118. data/lib/htm/config/section.rb +74 -0
  119. data/lib/htm/config/validator.rb +83 -0
  120. data/lib/htm/config.rb +65 -361
  121. data/lib/htm/database.rb +85 -127
  122. data/lib/htm/errors.rb +14 -0
  123. data/lib/htm/integrations/sinatra.rb +13 -44
  124. data/lib/htm/job_adapter.rb +75 -1
  125. data/lib/htm/jobs/generate_embedding_job.rb +3 -4
  126. data/lib/htm/jobs/generate_propositions_job.rb +4 -5
  127. data/lib/htm/jobs/generate_tags_job.rb +16 -15
  128. data/lib/htm/loaders/defaults_loader.rb +23 -0
  129. data/lib/htm/loaders/markdown_loader.rb +17 -15
  130. data/lib/htm/loaders/xdg_config_loader.rb +9 -9
  131. data/lib/htm/long_term_memory/fulltext_search.rb +14 -14
  132. data/lib/htm/long_term_memory/hybrid_search.rb +396 -229
  133. data/lib/htm/long_term_memory/node_operations.rb +24 -23
  134. data/lib/htm/long_term_memory/relevance_scorer.rb +23 -20
  135. data/lib/htm/long_term_memory/robot_operations.rb +4 -4
  136. data/lib/htm/long_term_memory/tag_operations.rb +91 -77
  137. data/lib/htm/long_term_memory/vector_search.rb +4 -5
  138. data/lib/htm/long_term_memory.rb +13 -13
  139. data/lib/htm/mcp/cli.rb +115 -8
  140. data/lib/htm/mcp/resources.rb +4 -3
  141. data/lib/htm/mcp/server.rb +5 -4
  142. data/lib/htm/mcp/tools.rb +37 -28
  143. data/lib/htm/migration.rb +72 -0
  144. data/lib/htm/models/file_source.rb +52 -31
  145. data/lib/htm/models/node.rb +224 -108
  146. data/lib/htm/models/node_tag.rb +49 -28
  147. data/lib/htm/models/robot.rb +38 -27
  148. data/lib/htm/models/robot_node.rb +63 -35
  149. data/lib/htm/models/tag.rb +126 -123
  150. data/lib/htm/observability.rb +45 -41
  151. data/lib/htm/proposition_service.rb +76 -7
  152. data/lib/htm/railtie.rb +2 -2
  153. data/lib/htm/robot_group.rb +30 -18
  154. data/lib/htm/sequel_config.rb +215 -0
  155. data/lib/htm/sql_builder.rb +14 -16
  156. data/lib/htm/tag_service.rb +78 -0
  157. data/lib/htm/tasks.rb +3 -0
  158. data/lib/htm/version.rb +1 -1
  159. data/lib/htm/workflows/remember_workflow.rb +213 -0
  160. data/lib/htm.rb +27 -22
  161. data/lib/tasks/db.rake +0 -2
  162. data/lib/tasks/doc.rake +2 -2
  163. data/lib/tasks/files.rake +11 -18
  164. data/lib/tasks/htm.rake +190 -62
  165. data/lib/tasks/jobs.rake +179 -54
  166. data/lib/tasks/tags.rake +8 -13
  167. data/mkdocs.yml +33 -8
  168. data/scripts/backfill_parent_tags.rb +376 -0
  169. data/scripts/normalize_plural_tags.rb +335 -0
  170. metadata +168 -86
  171. data/docs/api/yard/HTM/Configuration.md +0 -240
  172. data/docs/telemetry.md +0 -391
  173. data/examples/rails_app/app/controllers/tags_controller.rb +0 -30
  174. data/examples/sinatra_app/Gemfile.lock +0 -166
  175. data/lib/htm/active_record_config.rb +0 -104
  176. /data/examples/{config_file_example → 02_config_file_example}/README.md +0 -0
  177. /data/examples/{config_file_example → 02_config_file_example}/config/htm.local.yml +0 -0
  178. /data/examples/{config_file_example → 02_config_file_example}/custom_config.yml +0 -0
  179. /data/examples/{config_file_example → 02_config_file_example}/show_config.rb +0 -0
  180. /data/examples/{example_app → 06_example_app}/Rakefile +0 -0
  181. /data/examples/{cli_app → 07_cli_app}/README.md +0 -0
  182. /data/examples/{sinatra_app → 08_sinatra_app}/Gemfile +0 -0
  183. /data/examples/{telemetry → 10_telemetry}/README.md +0 -0
  184. /data/examples/{telemetry → 10_telemetry}/grafana/dashboards/htm-metrics.json +0 -0
  185. /data/examples/{rails_app → 12_rails_app}/.gitignore +0 -0
  186. /data/examples/{rails_app → 12_rails_app}/Procfile.dev +0 -0
  187. /data/examples/{rails_app → 12_rails_app}/README.md +0 -0
  188. /data/examples/{rails_app → 12_rails_app}/Rakefile +0 -0
  189. /data/examples/{rails_app → 12_rails_app}/app/assets/stylesheets/application.css +0 -0
  190. /data/examples/{rails_app → 12_rails_app}/app/assets/stylesheets/inter-font.css +0 -0
  191. /data/examples/{rails_app → 12_rails_app}/app/controllers/application_controller.rb +0 -0
  192. /data/examples/{rails_app → 12_rails_app}/app/controllers/search_controller.rb +0 -0
  193. /data/examples/{rails_app → 12_rails_app}/app/javascript/application.js +0 -0
  194. /data/examples/{rails_app → 12_rails_app}/app/javascript/controllers/application.js +0 -0
  195. /data/examples/{rails_app → 12_rails_app}/app/javascript/controllers/index.js +0 -0
  196. /data/examples/{rails_app → 12_rails_app}/app/views/files/index.html.erb +0 -0
  197. /data/examples/{rails_app → 12_rails_app}/app/views/files/show.html.erb +0 -0
  198. /data/examples/{rails_app → 12_rails_app}/app/views/layouts/application.html.erb +0 -0
  199. /data/examples/{rails_app → 12_rails_app}/app/views/memories/index.html.erb +0 -0
  200. /data/examples/{rails_app → 12_rails_app}/app/views/memories/new.html.erb +0 -0
  201. /data/examples/{rails_app → 12_rails_app}/app/views/robots/new.html.erb +0 -0
  202. /data/examples/{rails_app → 12_rails_app}/app/views/shared/_navbar.html.erb +0 -0
  203. /data/examples/{rails_app → 12_rails_app}/app/views/shared/_stat_card.html.erb +0 -0
  204. /data/examples/{rails_app → 12_rails_app}/bin/dev +0 -0
  205. /data/examples/{rails_app → 12_rails_app}/bin/rails +0 -0
  206. /data/examples/{rails_app → 12_rails_app}/bin/rake +0 -0
  207. /data/examples/{rails_app → 12_rails_app}/config/application.rb +0 -0
  208. /data/examples/{rails_app → 12_rails_app}/config/boot.rb +0 -0
  209. /data/examples/{rails_app → 12_rails_app}/config/database.yml +0 -0
  210. /data/examples/{rails_app → 12_rails_app}/config/environment.rb +0 -0
  211. /data/examples/{rails_app → 12_rails_app}/config/importmap.rb +0 -0
  212. /data/examples/{rails_app → 12_rails_app}/config/routes.rb +0 -0
  213. /data/examples/{rails_app → 12_rails_app}/config/tailwind.config.js +0 -0
  214. /data/examples/{rails_app → 12_rails_app}/config.ru +0 -0
  215. /data/examples/{rails_app → 12_rails_app}/log/.keep +0 -0
  216. /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
@@ -10,7 +10,7 @@ Setting up HTM for development involves:
10
10
  2. Installing Ruby and system dependencies
11
11
  3. Installing Ruby gem dependencies
12
12
  4. Setting up TimescaleDB database
13
- 5. Configuring Ollama for embeddings
13
+ 5. Configuring an LLM provider (Ollama, OpenAI, etc.)
14
14
  6. Verifying your setup
15
15
  7. Running tests and examples
16
16
 
@@ -274,77 +274,94 @@ ruby enable_extensions.rb
274
274
 
275
275
  This ensures that TimescaleDB, pgvector, and pg_trgm extensions are enabled.
276
276
 
277
- ## Step 5: Set Up Ollama for Embeddings
277
+ ## Step 5: Configure LLM Provider
278
278
 
279
- HTM uses Ollama (via RubyLLM) to generate vector embeddings for semantic search.
279
+ HTM uses RubyLLM to generate vector embeddings and extract tags. RubyLLM supports multiple providers, so you can choose what works best for your development environment.
280
280
 
281
- ### Install Ollama
281
+ ### Supported Providers
282
282
 
283
- #### macOS
283
+ | Provider | Best For | Setup Required |
284
+ |----------|----------|----------------|
285
+ | **Ollama** (default) | Local development, privacy | Install Ollama + models |
286
+ | **OpenAI** | Production, high-quality | API key only |
287
+ | **Anthropic** | Claude models for tags | API key only |
288
+ | **Gemini** | Google Cloud users | API key only |
284
289
 
290
+ ### Option A: Ollama (Recommended for Development)
291
+
292
+ Ollama runs locally with no API costs.
293
+
294
+ #### Install Ollama
295
+
296
+ **macOS:**
285
297
  ```bash
286
- # Download and install from official site
298
+ # Direct download
287
299
  curl https://ollama.ai/install.sh | sh
288
300
 
289
301
  # Or using Homebrew
290
302
  brew install ollama
291
303
  ```
292
304
 
293
- #### Linux
294
-
305
+ **Linux:**
295
306
  ```bash
296
307
  curl https://ollama.ai/install.sh | sh
297
308
  ```
298
309
 
299
- ### Start Ollama Service
310
+ #### Start Ollama Service
300
311
 
301
- Ollama typically starts automatically after installation. Verify it's running:
312
+ Ollama typically starts automatically. Verify it's running:
302
313
 
303
314
  ```bash
304
- # Check if Ollama is running
305
315
  curl http://localhost:11434/api/version
306
-
307
- # Expected output:
308
- # {"version":"0.1.x"}
309
316
  ```
310
317
 
311
- If not running, start it manually:
318
+ If not running:
312
319
 
313
320
  ```bash
314
- # macOS - Ollama runs as a background service
315
- # Check Activity Monitor or start from Applications
316
-
321
+ # macOS - Check Activity Monitor or start from Applications
317
322
  # Linux
318
323
  ollama serve &
319
324
  ```
320
325
 
321
- ### Pull the gpt-oss Model
322
-
323
- HTM uses the `gpt-oss` model by default:
326
+ #### Pull Required Models
324
327
 
325
328
  ```bash
326
- # Pull the model (downloads ~4GB)
327
- ollama pull gpt-oss
329
+ # Pull embedding model
330
+ ollama pull nomic-embed-text
331
+
332
+ # Pull tag extraction model
333
+ ollama pull gemma3:latest
328
334
 
329
- # Verify the model is available
335
+ # Verify models
330
336
  ollama list
331
- # Should show gpt-oss in the list
332
337
  ```
333
338
 
334
- ### Test Embedding Generation
339
+ #### Configure Custom URL (Optional)
335
340
 
336
341
  ```bash
337
- # Test that embeddings work
338
- ollama run gpt-oss "Hello, HTM!"
342
+ export OLLAMA_URL="http://custom-host:11434"
339
343
  ```
340
344
 
341
- ### Optional: Configure Custom Ollama URL
345
+ ### Option B: OpenAI (Recommended for Production)
342
346
 
343
- If Ollama is running on a different host or port:
347
+ ```bash
348
+ export OPENAI_API_KEY="sk-..."
349
+ ```
344
350
 
351
+ Configure in your code:
352
+ ```ruby
353
+ HTM.configure do |config|
354
+ config.embedding.provider = :openai
355
+ config.embedding.model = 'text-embedding-3-small'
356
+ end
357
+ ```
358
+
359
+ ### Option C: Other Providers
360
+
361
+ Set the appropriate API key:
345
362
  ```bash
346
- # Add to ~/.bashrc__tiger
347
- export OLLAMA_URL="http://custom-host:11434"
363
+ export ANTHROPIC_API_KEY="sk-ant-..."
364
+ export GEMINI_API_KEY="..."
348
365
  ```
349
366
 
350
367
  ## Step 6: Initialize Database Schema
@@ -420,11 +437,11 @@ HTM Basic Usage Example
420
437
  ============================================================
421
438
 
422
439
  1. Initializing HTM for 'Code Helper' robot...
423
- Using RubyLLM with Ollama provider and gpt-oss model for embeddings
440
+ Using RubyLLM with configured provider for embeddings
424
441
  ✓ HTM initialized
425
442
  Robot ID: robot-abc123
426
443
  Robot Name: Code Helper
427
- Embedding Service: Ollama (gpt-oss via RubyLLM)
444
+ Embedding Service: Configured provider via RubyLLM
428
445
 
429
446
  2. Adding memory nodes...
430
447
  ✓ Added decision about database choice
@@ -485,11 +502,14 @@ HTM uses environment variables for configuration. Here's a complete reference:
485
502
  | `HTM_DATABASE__PORT` | Database port | `37807` |
486
503
  | `HTM_SERVICE_NAME` | Service identifier (informational) | `db-67977` |
487
504
 
488
- ### Ollama Variables
505
+ ### LLM Provider Variables
489
506
 
490
507
  | Variable | Description | Example |
491
508
  |----------|-------------|---------|
492
- | `OLLAMA_URL` | Ollama API URL (optional) | `http://localhost:11434` |
509
+ | `OLLAMA_URL` | Ollama API URL (if using Ollama) | `http://localhost:11434` |
510
+ | `OPENAI_API_KEY` | OpenAI API key (if using OpenAI) | `sk-...` |
511
+ | `ANTHROPIC_API_KEY` | Anthropic API key (if using Anthropic) | `sk-ant-...` |
512
+ | `GEMINI_API_KEY` | Gemini API key (if using Gemini) | `...` |
493
513
 
494
514
  ### Managing Environment Files
495
515
 
@@ -497,7 +517,7 @@ You can organize your environment variables using multiple files:
497
517
 
498
518
  ```bash
499
519
  # ~/.bashrc__tiger - Database configuration
500
- # ~/.bashrc__ollama - Ollama configuration (if needed)
520
+ # LLM provider environment variables (set based on your chosen provider)
501
521
 
502
522
  # Load all configuration files in ~/.bashrc
503
523
  source ~/.bashrc__tiger
@@ -527,11 +547,11 @@ psql $HTM_DATABASE__URL
527
547
  docker ps | grep timescale
528
548
  ```
529
549
 
530
- #### "Ollama connection refused"
550
+ #### "LLM provider connection failed"
531
551
 
532
552
  **Symptoms**: Embedding generation fails
533
553
 
534
- **Solutions**:
554
+ **Solutions for Ollama**:
535
555
 
536
556
  ```bash
537
557
  # Verify Ollama is running
@@ -541,11 +561,23 @@ curl http://localhost:11434/api/version
541
561
  # macOS: Start from Applications or Activity Monitor
542
562
  # Linux: ollama serve &
543
563
 
544
- # Check if model is downloaded
545
- ollama list | grep gpt-oss
564
+ # Check if models are downloaded
565
+ ollama list | grep nomic-embed-text
566
+
567
+ # Pull models if missing
568
+ ollama pull nomic-embed-text
569
+ ollama pull gemma3:latest
570
+ ```
571
+
572
+ **Solutions for Cloud Providers**:
573
+
574
+ ```bash
575
+ # Verify API key is set
576
+ echo $OPENAI_API_KEY
577
+ echo $ANTHROPIC_API_KEY
546
578
 
547
- # Pull model if missing
548
- ollama pull gpt-oss
579
+ # Test API connectivity
580
+ curl https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY"
549
581
  ```
550
582
 
551
583
  #### "Extension not available"
@@ -602,7 +634,7 @@ rake db_setup
602
634
  source ~/.bashrc__tiger
603
635
  env | grep TIGER
604
636
 
605
- # Check Ollama is running
637
+ # Check LLM provider (if using Ollama)
606
638
  curl http://localhost:11434/api/version
607
639
 
608
640
  # Run tests with verbose output
@@ -0,0 +1,133 @@
1
+ # Basic Usage Example
2
+
3
+ This example demonstrates the core HTM operations: configuring the system, remembering information, and recalling memories.
4
+
5
+ **Source:** [`examples/basic_usage.rb`](https://github.com/madbomber/htm/blob/main/examples/basic_usage.rb)
6
+
7
+ ## Overview
8
+
9
+ The basic usage example shows:
10
+
11
+ - Configuring HTM with a provider (Ollama by default)
12
+ - Initializing an HTM instance for a robot
13
+ - Storing memories with `remember()`
14
+ - Retrieving memories with `recall()`
15
+ - Using different search strategies
16
+
17
+ ## Running the Example
18
+
19
+ ```bash
20
+ export HTM_DATABASE__URL="postgresql://user@localhost:5432/htm_development"
21
+ ruby examples/basic_usage.rb
22
+ ```
23
+
24
+ ## Code Walkthrough
25
+
26
+ ### Configuration
27
+
28
+ ```ruby
29
+ HTM.configure do |config|
30
+ # Provider configuration (Ollama is default)
31
+ config.embedding.provider = :ollama
32
+ config.embedding.model = 'nomic-embed-text:latest'
33
+ config.embedding.dimensions = 768
34
+
35
+ config.tag.provider = :ollama
36
+ config.tag.model = 'gemma3:latest'
37
+
38
+ # Use inline job backend for synchronous execution
39
+ # In production, use :thread or :sidekiq for async
40
+ config.job.backend = :inline
41
+ end
42
+ ```
43
+
44
+ ### Initialize HTM
45
+
46
+ ```ruby
47
+ htm = HTM.new(
48
+ robot_name: "Code Helper",
49
+ working_memory_size: 128_000 # Token limit
50
+ )
51
+ ```
52
+
53
+ ### Storing Memories
54
+
55
+ ```ruby
56
+ # Remember automatically generates embeddings and tags
57
+ node_id = htm.remember(
58
+ "PostgreSQL supports native vector search with pgvector."
59
+ )
60
+
61
+ # Tags are extracted via LLM
62
+ # Embeddings enable semantic search
63
+ ```
64
+
65
+ ### Recalling Memories
66
+
67
+ ```ruby
68
+ # Full-text search (keyword matching)
69
+ memories = htm.recall(
70
+ "PostgreSQL",
71
+ timeframe: (Time.now - 3600)..Time.now,
72
+ limit: 5,
73
+ strategy: :fulltext
74
+ )
75
+
76
+ # Vector search (semantic similarity)
77
+ memories = htm.recall("database features", strategy: :vector)
78
+
79
+ # Hybrid search (combines both)
80
+ memories = htm.recall("database features", strategy: :hybrid)
81
+ ```
82
+
83
+ ## Expected Output
84
+
85
+ ```
86
+ HTM Basic Usage Example
87
+ ============================================================
88
+
89
+ 1. Configuring HTM with Ollama provider...
90
+ ✓ HTM configured with Ollama provider (inline job backend)
91
+
92
+ 2. Initializing HTM for 'Code Helper' robot...
93
+ ✓ HTM initialized
94
+ Robot ID: 1
95
+ Robot Name: Code Helper
96
+ Embedding Service: ollama (nomic-embed-text:latest)
97
+
98
+ 3. Remembering information...
99
+ ✓ Remembered decision about database choice (node 1)
100
+ ✓ Remembered decision about RAG approach (node 2)
101
+ ✓ Remembered fact about user preferences (node 3)
102
+
103
+ 4. Recalling memories about 'PostgreSQL'...
104
+ ✓ Found 1 memories
105
+ - Node 1: We decided to use PostgreSQL for HTM storage because...
106
+
107
+ ============================================================
108
+ ✓ Example completed successfully!
109
+ ```
110
+
111
+ ## Key Concepts
112
+
113
+ ### Search Strategies
114
+
115
+ | Strategy | Description | Best For |
116
+ |----------|-------------|----------|
117
+ | `:fulltext` | Keyword matching with PostgreSQL tsvector | Exact term matches |
118
+ | `:vector` | Semantic similarity with pgvector | Conceptual queries |
119
+ | `:hybrid` | Combines both with RRF scoring | General queries |
120
+
121
+ ### Job Backends
122
+
123
+ | Backend | Behavior | Use Case |
124
+ |---------|----------|----------|
125
+ | `:inline` | Synchronous execution | Examples, testing |
126
+ | `:thread` | Background threads | Development |
127
+ | `:sidekiq` | Sidekiq workers | Production |
128
+
129
+ ## See Also
130
+
131
+ - [LLM Configuration Example](llm-configuration.md)
132
+ - [Adding Memories Guide](../guides/adding-memories.md)
133
+ - [Search Strategies Guide](../guides/search-strategies.md)
@@ -0,0 +1,170 @@
1
+ # Configuration Files Example
2
+
3
+ This example demonstrates HTM's flexible, layered configuration management using the `anyway_config` gem.
4
+
5
+ **Source:** [`examples/config_file_example/`](https://github.com/madbomber/htm/tree/main/examples/config_file_example)
6
+
7
+ ## Overview
8
+
9
+ The configuration example shows:
10
+
11
+ - Configuration source hierarchy and priority
12
+ - Using `htm_mcp config` to generate config files
13
+ - Environment-specific configuration sections
14
+ - Environment variable overrides with `HTM_*`
15
+ - Custom config file paths with `HTM_CONF`
16
+ - Programmatic configuration with `HTM.configure`
17
+
18
+ ## Configuration Priority
19
+
20
+ HTM loads configuration from multiple sources, merged in priority order:
21
+
22
+ | Priority | Source | Location |
23
+ |----------|--------|----------|
24
+ | 1 (lowest) | Bundled Defaults | `lib/htm/config/defaults.yml` |
25
+ | 2 | XDG User Config | `~/.config/htm/htm.yml` |
26
+ | 3 | Project Config | `./config/htm.yml` |
27
+ | 4 | Local Overrides | `./config/htm.local.yml` |
28
+ | 5 | HTM_CONF File | Path in `HTM_CONF` env var |
29
+ | 6 | Environment Variables | `HTM_*` |
30
+ | 7 (highest) | Code Block | `HTM.configure { }` |
31
+
32
+ ## Running the Example
33
+
34
+ ```bash
35
+ cd examples/config_file_example
36
+
37
+ # Basic usage - loads ./config/htm.local.yml automatically
38
+ ruby show_config.rb
39
+
40
+ # Different environment
41
+ HTM_ENV=production ruby show_config.rb
42
+
43
+ # Override with environment variable
44
+ HTM_EMBEDDING__MODEL=mxbai-embed-large ruby show_config.rb
45
+
46
+ # Use custom config file
47
+ HTM_CONF=./custom_config.yml ruby show_config.rb
48
+
49
+ # Combine multiple overrides
50
+ HTM_CONF=./custom_config.yml HTM_ENV=test HTM_LOG_LEVEL=warn ruby show_config.rb
51
+ ```
52
+
53
+ ## Generating Config Files
54
+
55
+ Use the `htm_mcp config` command to output the complete default configuration:
56
+
57
+ ```bash
58
+ # Create a project config file
59
+ htm_mcp config > ./config/htm.yml
60
+
61
+ # Create a local overrides file (add to .gitignore)
62
+ htm_mcp config > ./config/htm.local.yml
63
+
64
+ # Create a user-wide XDG config
65
+ mkdir -p ~/.config/htm
66
+ htm_mcp config > ~/.config/htm/htm.yml
67
+ ```
68
+
69
+ ## Example Config Files
70
+
71
+ ### Project Config with Environment Sections
72
+
73
+ ```yaml
74
+ # ./config/htm.yml
75
+ defaults:
76
+ database:
77
+ host: localhost
78
+ port: 5432
79
+
80
+ development:
81
+ database:
82
+ name: myapp_development
83
+ log_level: debug
84
+
85
+ production:
86
+ database:
87
+ name: myapp_production
88
+ pool_size: 25
89
+ telemetry_enabled: true
90
+ ```
91
+
92
+ ### Local Overrides (Gitignored)
93
+
94
+ ```yaml
95
+ # ./config/htm.local.yml
96
+ database:
97
+ name: my_local_db
98
+
99
+ providers:
100
+ openai:
101
+ api_key: sk-your-actual-key
102
+
103
+ log_level: debug
104
+ ```
105
+
106
+ ## Environment Variables
107
+
108
+ Use double underscores (`__`) for nested values:
109
+
110
+ ```bash
111
+ # Database configuration
112
+ export HTM_DATABASE__URL="postgresql://user:pass@host:5432/dbname"
113
+ export HTM_DATABASE__POOL_SIZE=25
114
+
115
+ # Embedding configuration
116
+ export HTM_EMBEDDING__PROVIDER=openai
117
+ export HTM_EMBEDDING__MODEL=text-embedding-3-small
118
+
119
+ # Provider credentials
120
+ export HTM_PROVIDERS__OPENAI__API_KEY=sk-your-key
121
+ ```
122
+
123
+ ## Example Output
124
+
125
+ The `show_config.rb` script displays loaded configuration with source tracing:
126
+
127
+ ```
128
+ HTM Configuration Example
129
+ ============================================================
130
+
131
+ Environment: development
132
+
133
+ Config sources checked:
134
+ - Bundled defaults: lib/htm/config/defaults.yml
135
+ - XDG config: ~/.config/htm/htm.yml
136
+ - Project config: ./config/htm.yml
137
+ - Local overrides: ./config/htm.local.yml
138
+ - HTM_CONF override: (not set)
139
+ - Environment variables: HTM_*
140
+
141
+ ------------------------------------------------------------
142
+ Configuration with Sources:
143
+ ------------------------------------------------------------
144
+
145
+ database:
146
+ host: "localhost" # from: htm.local.yml
147
+ port: 5432 # from: htm.local.yml
148
+ name: "htm_example" # from: htm.local.yml
149
+ pool_size: 10 # from: bundled_defaults
150
+ embedding:
151
+ provider: "ollama" # from: htm.local.yml
152
+ model: "nomic-embed-text:latest" # from: htm.local.yml
153
+ ...
154
+ ```
155
+
156
+ ## Files in This Example
157
+
158
+ ```
159
+ config_file_example/
160
+ ├── README.md # Detailed documentation
161
+ ├── show_config.rb # Demo script with source tracing
162
+ ├── custom_config.yml # Example for HTM_CONF usage
163
+ └── config/
164
+ └── htm.local.yml # Auto-loaded local overrides
165
+ ```
166
+
167
+ ## See Also
168
+
169
+ - [Configuration Guide](../guides/configuration.md)
170
+ - [anyway_config Documentation](https://github.com/palkan/anyway_config)