htm 0.0.1

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 (155) hide show
  1. checksums.yaml +7 -0
  2. data/.architecture/decisions/adrs/001-use-postgresql-timescaledb-storage.md +227 -0
  3. data/.architecture/decisions/adrs/002-two-tier-memory-architecture.md +322 -0
  4. data/.architecture/decisions/adrs/003-ollama-default-embedding-provider.md +339 -0
  5. data/.architecture/decisions/adrs/004-multi-robot-shared-memory-hive-mind.md +374 -0
  6. data/.architecture/decisions/adrs/005-rag-based-retrieval-with-hybrid-search.md +443 -0
  7. data/.architecture/decisions/adrs/006-context-assembly-strategies.md +444 -0
  8. data/.architecture/decisions/adrs/007-working-memory-eviction-strategy.md +461 -0
  9. data/.architecture/decisions/adrs/008-robot-identification-system.md +550 -0
  10. data/.architecture/decisions/adrs/009-never-forget-explicit-deletion-only.md +570 -0
  11. data/.architecture/decisions/adrs/010-redis-working-memory-rejected.md +323 -0
  12. data/.architecture/decisions/adrs/011-database-side-embedding-generation-with-pgai.md +585 -0
  13. data/.architecture/decisions/adrs/012-llm-driven-ontology-topic-extraction.md +583 -0
  14. data/.architecture/decisions/adrs/013-activerecord-orm-and-many-to-many-tagging.md +299 -0
  15. data/.architecture/decisions/adrs/014-client-side-embedding-generation-workflow.md +569 -0
  16. data/.architecture/decisions/adrs/015-hierarchical-tag-ontology-and-llm-extraction.md +701 -0
  17. data/.architecture/decisions/adrs/016-async-embedding-and-tag-generation.md +694 -0
  18. data/.architecture/members.yml +144 -0
  19. data/.architecture/reviews/2025-10-29-llm-configuration-and-async-processing-review.md +1137 -0
  20. data/.architecture/reviews/initial-system-analysis.md +330 -0
  21. data/.envrc +32 -0
  22. data/.irbrc +145 -0
  23. data/CHANGELOG.md +150 -0
  24. data/COMMITS.md +196 -0
  25. data/LICENSE +21 -0
  26. data/README.md +1347 -0
  27. data/Rakefile +51 -0
  28. data/SETUP.md +268 -0
  29. data/config/database.yml +67 -0
  30. data/db/migrate/20250101000001_enable_extensions.rb +14 -0
  31. data/db/migrate/20250101000002_create_robots.rb +14 -0
  32. data/db/migrate/20250101000003_create_nodes.rb +42 -0
  33. data/db/migrate/20250101000005_create_tags.rb +38 -0
  34. data/db/migrate/20250101000007_add_node_vector_indexes.rb +30 -0
  35. data/db/schema.sql +473 -0
  36. data/db/seed_data/README.md +100 -0
  37. data/db/seed_data/presidents.md +136 -0
  38. data/db/seed_data/states.md +151 -0
  39. data/db/seeds.rb +208 -0
  40. data/dbdoc/README.md +173 -0
  41. data/dbdoc/public.node_stats.md +48 -0
  42. data/dbdoc/public.node_stats.svg +41 -0
  43. data/dbdoc/public.node_tags.md +40 -0
  44. data/dbdoc/public.node_tags.svg +112 -0
  45. data/dbdoc/public.nodes.md +54 -0
  46. data/dbdoc/public.nodes.svg +118 -0
  47. data/dbdoc/public.nodes_tags.md +39 -0
  48. data/dbdoc/public.nodes_tags.svg +112 -0
  49. data/dbdoc/public.ontology_structure.md +48 -0
  50. data/dbdoc/public.ontology_structure.svg +38 -0
  51. data/dbdoc/public.operations_log.md +42 -0
  52. data/dbdoc/public.operations_log.svg +130 -0
  53. data/dbdoc/public.relationships.md +39 -0
  54. data/dbdoc/public.relationships.svg +41 -0
  55. data/dbdoc/public.robot_activity.md +46 -0
  56. data/dbdoc/public.robot_activity.svg +35 -0
  57. data/dbdoc/public.robots.md +35 -0
  58. data/dbdoc/public.robots.svg +90 -0
  59. data/dbdoc/public.schema_migrations.md +29 -0
  60. data/dbdoc/public.schema_migrations.svg +26 -0
  61. data/dbdoc/public.tags.md +35 -0
  62. data/dbdoc/public.tags.svg +60 -0
  63. data/dbdoc/public.topic_relationships.md +45 -0
  64. data/dbdoc/public.topic_relationships.svg +32 -0
  65. data/dbdoc/schema.json +1437 -0
  66. data/dbdoc/schema.svg +154 -0
  67. data/docs/api/database.md +806 -0
  68. data/docs/api/embedding-service.md +532 -0
  69. data/docs/api/htm.md +797 -0
  70. data/docs/api/index.md +259 -0
  71. data/docs/api/long-term-memory.md +1096 -0
  72. data/docs/api/working-memory.md +665 -0
  73. data/docs/architecture/adrs/001-postgresql-timescaledb.md +314 -0
  74. data/docs/architecture/adrs/002-two-tier-memory.md +411 -0
  75. data/docs/architecture/adrs/003-ollama-embeddings.md +421 -0
  76. data/docs/architecture/adrs/004-hive-mind.md +437 -0
  77. data/docs/architecture/adrs/005-rag-retrieval.md +531 -0
  78. data/docs/architecture/adrs/006-context-assembly.md +496 -0
  79. data/docs/architecture/adrs/007-eviction-strategy.md +645 -0
  80. data/docs/architecture/adrs/008-robot-identification.md +625 -0
  81. data/docs/architecture/adrs/009-never-forget.md +648 -0
  82. data/docs/architecture/adrs/010-redis-working-memory-rejected.md +323 -0
  83. data/docs/architecture/adrs/011-pgai-integration.md +494 -0
  84. data/docs/architecture/adrs/index.md +215 -0
  85. data/docs/architecture/hive-mind.md +736 -0
  86. data/docs/architecture/index.md +351 -0
  87. data/docs/architecture/overview.md +538 -0
  88. data/docs/architecture/two-tier-memory.md +873 -0
  89. data/docs/assets/css/custom.css +83 -0
  90. data/docs/assets/images/htm-core-components.svg +63 -0
  91. data/docs/assets/images/htm-database-schema.svg +93 -0
  92. data/docs/assets/images/htm-hive-mind-architecture.svg +125 -0
  93. data/docs/assets/images/htm-importance-scoring-framework.svg +83 -0
  94. data/docs/assets/images/htm-layered-architecture.svg +71 -0
  95. data/docs/assets/images/htm-long-term-memory-architecture.svg +115 -0
  96. data/docs/assets/images/htm-working-memory-architecture.svg +120 -0
  97. data/docs/assets/images/htm.jpg +0 -0
  98. data/docs/assets/images/htm_demo.gif +0 -0
  99. data/docs/assets/js/mathjax.js +18 -0
  100. data/docs/assets/videos/htm_video.mp4 +0 -0
  101. data/docs/database_rake_tasks.md +322 -0
  102. data/docs/development/contributing.md +787 -0
  103. data/docs/development/index.md +336 -0
  104. data/docs/development/schema.md +596 -0
  105. data/docs/development/setup.md +719 -0
  106. data/docs/development/testing.md +819 -0
  107. data/docs/guides/adding-memories.md +824 -0
  108. data/docs/guides/context-assembly.md +1009 -0
  109. data/docs/guides/getting-started.md +577 -0
  110. data/docs/guides/index.md +118 -0
  111. data/docs/guides/long-term-memory.md +941 -0
  112. data/docs/guides/multi-robot.md +866 -0
  113. data/docs/guides/recalling-memories.md +927 -0
  114. data/docs/guides/search-strategies.md +953 -0
  115. data/docs/guides/working-memory.md +717 -0
  116. data/docs/index.md +214 -0
  117. data/docs/installation.md +477 -0
  118. data/docs/multi_framework_support.md +519 -0
  119. data/docs/quick-start.md +655 -0
  120. data/docs/setup_local_database.md +302 -0
  121. data/docs/using_rake_tasks_in_your_app.md +383 -0
  122. data/examples/basic_usage.rb +93 -0
  123. data/examples/cli_app/README.md +317 -0
  124. data/examples/cli_app/htm_cli.rb +270 -0
  125. data/examples/custom_llm_configuration.rb +183 -0
  126. data/examples/example_app/Rakefile +71 -0
  127. data/examples/example_app/app.rb +206 -0
  128. data/examples/sinatra_app/Gemfile +21 -0
  129. data/examples/sinatra_app/app.rb +335 -0
  130. data/lib/htm/active_record_config.rb +113 -0
  131. data/lib/htm/configuration.rb +342 -0
  132. data/lib/htm/database.rb +594 -0
  133. data/lib/htm/embedding_service.rb +115 -0
  134. data/lib/htm/errors.rb +34 -0
  135. data/lib/htm/job_adapter.rb +154 -0
  136. data/lib/htm/jobs/generate_embedding_job.rb +65 -0
  137. data/lib/htm/jobs/generate_tags_job.rb +82 -0
  138. data/lib/htm/long_term_memory.rb +965 -0
  139. data/lib/htm/models/node.rb +109 -0
  140. data/lib/htm/models/node_tag.rb +33 -0
  141. data/lib/htm/models/robot.rb +52 -0
  142. data/lib/htm/models/tag.rb +76 -0
  143. data/lib/htm/railtie.rb +76 -0
  144. data/lib/htm/sinatra.rb +157 -0
  145. data/lib/htm/tag_service.rb +135 -0
  146. data/lib/htm/tasks.rb +38 -0
  147. data/lib/htm/version.rb +5 -0
  148. data/lib/htm/working_memory.rb +182 -0
  149. data/lib/htm.rb +400 -0
  150. data/lib/tasks/db.rake +19 -0
  151. data/lib/tasks/htm.rake +147 -0
  152. data/lib/tasks/jobs.rake +312 -0
  153. data/mkdocs.yml +190 -0
  154. data/scripts/install_local_database.sh +309 -0
  155. metadata +341 -0
@@ -0,0 +1,519 @@
1
+ # HTM Multi-Framework Support
2
+
3
+ HTM works seamlessly in three types of applications:
4
+ 1. **CLI Applications** - Command-line tools with synchronous execution
5
+ 2. **Sinatra Applications** - Web apps with Sidekiq background jobs
6
+ 3. **Rails Applications** - Full Rails integration with ActiveJob
7
+
8
+ ## Quick Start by Framework
9
+
10
+ ### CLI Applications
11
+
12
+ ```ruby
13
+ #!/usr/bin/env ruby
14
+ require 'htm'
15
+
16
+ # Configure for CLI (synchronous execution)
17
+ HTM.configure do |config|
18
+ config.job_backend = :inline # Jobs run immediately
19
+ end
20
+
21
+ htm = HTM.new(robot_name: "cli_assistant")
22
+
23
+ # Store information (waits for embedding + tags)
24
+ node_id = htm.remember("PostgreSQL is great for time-series data")
25
+ puts "Stored as node #{node_id}"
26
+
27
+ # Search memories
28
+ memories = htm.recall("PostgreSQL", limit: 10)
29
+ puts "Found #{memories.length} memories"
30
+ ```
31
+
32
+ **Example:** [`examples/cli_app/htm_cli.rb`](https://github.com/madbomber/htm/blob/main/examples/cli_app/htm_cli.rb)
33
+
34
+ ---
35
+
36
+ ### Sinatra Applications
37
+
38
+ ```ruby
39
+ require 'sinatra'
40
+ require 'htm'
41
+ require 'htm/sinatra'
42
+
43
+ class MyApp < Sinatra::Base
44
+ # Automatically configures HTM with Sidekiq
45
+ register_htm
46
+
47
+ enable :sessions
48
+
49
+ before do
50
+ init_htm(robot_name: session[:user_id] || 'guest')
51
+ end
52
+
53
+ post '/remember' do
54
+ node_id = remember(params[:content], source: 'user')
55
+ json status: 'ok', node_id: node_id
56
+ end
57
+
58
+ get '/recall' do
59
+ memories = recall(params[:topic], limit: 10)
60
+ json memories: memories
61
+ end
62
+ end
63
+ ```
64
+
65
+ **Example:** [`examples/sinatra_app/app.rb`](https://github.com/madbomber/htm/blob/main/examples/sinatra_app/app.rb)
66
+
67
+ ---
68
+
69
+ ### Rails Applications
70
+
71
+ ```ruby
72
+ # HTM automatically configures itself in Rails
73
+
74
+ # app/controllers/memories_controller.rb
75
+ class MemoriesController < ApplicationController
76
+ def create
77
+ htm = HTM.new(robot_name: "user_#{current_user.id}")
78
+ node_id = htm.remember(params[:content], source: 'user')
79
+
80
+ render json: { status: 'ok', node_id: node_id }
81
+ end
82
+
83
+ def index
84
+ htm = HTM.new(robot_name: "user_#{current_user.id}")
85
+ memories = htm.recall(params[:topic], limit: 10)
86
+
87
+ render json: { memories: memories }
88
+ end
89
+ end
90
+ ```
91
+
92
+ Rails auto-configuration happens via `HTM::Railtie`:
93
+ - Uses Rails.logger
94
+ - Uses ActiveJob for background jobs
95
+ - Inline jobs in test environment
96
+ - Rake tasks auto-loaded
97
+
98
+ ---
99
+
100
+ ## Job Backend Comparison
101
+
102
+ | Backend | Best For | Speed | Infrastructure | Use Case |
103
+ |---------|----------|-------|----------------|----------|
104
+ | `:inline` | CLI, Tests | Slow (synchronous) | None | Development, testing, CLI tools |
105
+ | `:thread` | Simple apps | Fast | None | Quick prototypes, standalone |
106
+ | `:sidekiq` | Sinatra | Fast | Redis required | Microservices, Sinatra apps |
107
+ | `:active_job` | Rails | Fast | Rails required | Rails applications |
108
+
109
+ ### Performance Characteristics
110
+
111
+ **:inline (Synchronous)**
112
+ ```ruby
113
+ # User waits for completion
114
+ node_id = htm.remember("text") # ~1-3 seconds
115
+ # Embedding and tags already generated
116
+ ```
117
+
118
+ **:sidekiq/:active_job (Asynchronous)**
119
+ ```ruby
120
+ # User gets immediate response
121
+ node_id = htm.remember("text") # ~15ms
122
+ # Embedding and tags generated in background (~1 second)
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Configuration
128
+
129
+ ### Auto-Detection
130
+
131
+ HTM automatically detects the appropriate backend:
132
+
133
+ ```ruby
134
+ # Test environment → :inline
135
+ ENV['RAILS_ENV'] = 'test'
136
+ HTM.configuration.job_backend # => :inline
137
+
138
+ # Rails app → :active_job
139
+ defined?(ActiveJob)
140
+ HTM.configuration.job_backend # => :active_job
141
+
142
+ # Sidekiq available → :sidekiq
143
+ defined?(Sidekiq)
144
+ HTM.configuration.job_backend # => :sidekiq
145
+
146
+ # Default → :thread
147
+ HTM.configuration.job_backend # => :thread
148
+ ```
149
+
150
+ ### Manual Override
151
+
152
+ ```ruby
153
+ HTM.configure do |config|
154
+ config.job_backend = :inline # Force synchronous
155
+ end
156
+ ```
157
+
158
+ ### Environment Variable
159
+
160
+ ```bash
161
+ export HTM_JOB_BACKEND=inline # Override auto-detection
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Framework-Specific Features
167
+
168
+ ### CLI Applications
169
+
170
+ **Features:**
171
+ - Synchronous execution (`:inline` backend)
172
+ - Progress feedback in terminal
173
+ - No background infrastructure needed
174
+ - Simple error handling
175
+
176
+ **Best Practices:**
177
+ ```ruby
178
+ # Use inline backend
179
+ HTM.configure do |config|
180
+ config.job_backend = :inline
181
+
182
+ # CLI-friendly logging
183
+ config.logger.formatter = proc do |severity, datetime, progname, msg|
184
+ case severity
185
+ when 'INFO' then "[✓] #{msg}\n"
186
+ when 'ERROR' then "[✗] #{msg}\n"
187
+ else "[•] #{msg}\n"
188
+ end
189
+ end
190
+ end
191
+ ```
192
+
193
+ ---
194
+
195
+ ### Sinatra Applications
196
+
197
+ **Features:**
198
+ - Sidekiq background jobs
199
+ - Session-based robot identification
200
+ - Thread-safe request handling
201
+ - RESTful API integration
202
+
203
+ **Setup:**
204
+ ```ruby
205
+ # Gemfile
206
+ gem 'sinatra'
207
+ gem 'sidekiq'
208
+ gem 'redis'
209
+ gem 'htm'
210
+
211
+ # app.rb
212
+ require 'htm/sinatra'
213
+
214
+ class MyApp < Sinatra::Base
215
+ register_htm # Auto-configures HTM
216
+
217
+ enable :sessions
218
+
219
+ before do
220
+ robot_name = session[:user_id] || 'guest'
221
+ init_htm(robot_name: "user_#{robot_name}")
222
+ end
223
+ end
224
+ ```
225
+
226
+ **Deployment:**
227
+ ```bash
228
+ # Start Redis
229
+ redis-server
230
+
231
+ # Start Sidekiq worker
232
+ bundle exec sidekiq -r ./app.rb
233
+
234
+ # Start web server
235
+ bundle exec ruby app.rb
236
+ ```
237
+
238
+ ---
239
+
240
+ ### Rails Applications
241
+
242
+ **Features:**
243
+ - Automatic configuration via Railtie
244
+ - ActiveJob integration
245
+ - Rails logger integration
246
+ - Rake tasks loaded automatically
247
+ - Test environment auto-configured
248
+
249
+ **Setup:**
250
+ ```ruby
251
+ # Gemfile
252
+ gem 'htm'
253
+
254
+ # config/initializers/htm.rb (optional)
255
+ HTM.configure do |config|
256
+ config.embedding_model = 'nomic-embed-text'
257
+ config.tag_model = 'llama3'
258
+ end
259
+ ```
260
+
261
+ **Usage in Controllers:**
262
+ ```ruby
263
+ class MemoriesController < ApplicationController
264
+ def create
265
+ htm = HTM.new(robot_name: "user_#{current_user.id}")
266
+ node_id = htm.remember(params[:content])
267
+
268
+ # Job enqueued via ActiveJob
269
+ # Returns immediately
270
+
271
+ render json: { node_id: node_id }
272
+ end
273
+ end
274
+ ```
275
+
276
+ **Testing:**
277
+ ```ruby
278
+ # test/test_helper.rb or spec/rails_helper.rb
279
+
280
+ # Jobs run synchronously in tests (auto-configured)
281
+ RSpec.describe MemoriesController do
282
+ it "creates memory" do
283
+ post :create, params: { content: "Test memory" }
284
+
285
+ # Embedding and tags already generated (inline in tests)
286
+ node = HTM::Models::Node.last
287
+ expect(node.embedding).to be_present
288
+ expect(node.tags).not_to be_empty
289
+ end
290
+ end
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Thread Safety
296
+
297
+ HTM is thread-safe for concurrent web requests:
298
+
299
+ ✅ **Thread-Safe Components:**
300
+ - `HTM::WorkingMemory` - Per-instance state
301
+ - `HTM::LongTermMemory` - Connection pooling
302
+ - Database operations - PostgreSQL ACID compliance
303
+ - Job enqueueing - Atomic operations
304
+
305
+ ⚠️ **Considerations:**
306
+ - Each HTM instance is independent
307
+ - Connection pool sized appropriately (`db_pool_size`)
308
+ - Concurrent node creation is safe
309
+ - Shared memory across robots (by design)
310
+
311
+ **Example: Concurrent Requests**
312
+ ```ruby
313
+ # Sinatra/Rails - Multiple requests simultaneously
314
+ # Request 1:
315
+ htm1 = HTM.new(robot_name: "user_123")
316
+ htm1.remember("Message 1") # ✓ Thread-safe
317
+
318
+ # Request 2 (concurrent):
319
+ htm2 = HTM.new(robot_name: "user_456")
320
+ htm2.remember("Message 2") # ✓ Thread-safe
321
+
322
+ # Separate instances, no conflicts
323
+ ```
324
+
325
+ ---
326
+
327
+ ## Database Connection Management
328
+
329
+ ### CLI Applications
330
+ ```ruby
331
+ # Single connection, simple usage
332
+ htm = HTM.new
333
+ # Connection established once
334
+ ```
335
+
336
+ ### Sinatra Applications
337
+ ```ruby
338
+ # Connection pooling handled by middleware
339
+ class MyApp < Sinatra::Base
340
+ use HTM::Sinatra::Middleware # Manages connections
341
+ end
342
+ ```
343
+
344
+ ### Rails Applications
345
+ ```ruby
346
+ # Rails manages connections automatically
347
+ # HTM shares Rails' connection pool
348
+ ```
349
+
350
+ ### Connection Pool Settings
351
+ ```ruby
352
+ htm = HTM.new(
353
+ db_pool_size: 10, # Max connections
354
+ db_query_timeout: 30_000 # 30 seconds
355
+ )
356
+ ```
357
+
358
+ ---
359
+
360
+ ## Troubleshooting
361
+
362
+ ### Jobs Not Running (Sinatra)
363
+
364
+ **Problem:** Memories created but no embeddings/tags
365
+
366
+ **Solution:**
367
+ ```bash
368
+ # Check Sidekiq is running
369
+ ps aux | grep sidekiq
370
+
371
+ # Start Sidekiq worker
372
+ bundle exec sidekiq -r ./app.rb -q htm
373
+
374
+ # Check Redis
375
+ redis-cli ping
376
+ ```
377
+
378
+ ### Jobs Not Running (Rails)
379
+
380
+ **Problem:** Background jobs not processing
381
+
382
+ **Solution:**
383
+ ```bash
384
+ # Check ActiveJob backend configured
385
+ # config/application.rb
386
+ config.active_job.queue_adapter = :sidekiq
387
+
388
+ # Start Sidekiq
389
+ bundle exec sidekiq
390
+ ```
391
+
392
+ ### Slow CLI Performance
393
+
394
+ **Problem:** CLI operations take too long
395
+
396
+ **Solution:**
397
+ ```ruby
398
+ # Use faster/smaller models
399
+ HTM.configure do |config|
400
+ config.embedding_model = 'all-minilm' # Smaller, faster
401
+ config.tag_model = 'gemma2:2b' # Smaller model
402
+ end
403
+
404
+ # Or disable features
405
+ HTM.configure do |config|
406
+ config.tag_extractor = ->(_text, _ontology) { [] } # Skip tags
407
+ end
408
+ ```
409
+
410
+ ### Thread Safety Issues
411
+
412
+ **Problem:** Concurrent request errors
413
+
414
+ **Solution:**
415
+ ```ruby
416
+ # Increase connection pool
417
+ htm = HTM.new(db_pool_size: 20)
418
+
419
+ # Check for shared state (anti-pattern)
420
+ # DON'T:
421
+ $htm = HTM.new # Global shared instance
422
+
423
+ # DO:
424
+ def htm
425
+ @htm ||= HTM.new(robot_name: current_user.id)
426
+ end
427
+ ```
428
+
429
+ ---
430
+
431
+ ## Migration Guide
432
+
433
+ ### Existing CLI Apps
434
+
435
+ ```ruby
436
+ # Before (blocking):
437
+ # Jobs run in threads (may not complete)
438
+
439
+ # After (explicit inline):
440
+ HTM.configure do |config|
441
+ config.job_backend = :inline
442
+ end
443
+ # Jobs run synchronously, guaranteed to complete
444
+ ```
445
+
446
+ ### Existing Sinatra Apps
447
+
448
+ ```ruby
449
+ # Before:
450
+ require 'htm'
451
+ # Threads used (not production-ready)
452
+
453
+ # After:
454
+ require 'htm/sinatra'
455
+ register_htm # Auto-configures Sidekiq
456
+ # Production-ready background jobs
457
+ ```
458
+
459
+ ### Existing Rails Apps
460
+
461
+ ```ruby
462
+ # Before:
463
+ # Manual configuration required
464
+
465
+ # After:
466
+ # Just add gem 'htm' - auto-configures via Railtie
467
+ # Uses ActiveJob automatically
468
+ ```
469
+
470
+ ---
471
+
472
+ ## Best Practices
473
+
474
+ ### CLI Applications
475
+ 1. Use `:inline` backend for predictability
476
+ 2. Add progress indicators for user feedback
477
+ 3. Handle Ollama connection errors gracefully
478
+ 4. Consider caching for repeated queries
479
+
480
+ ### Sinatra Applications
481
+ 1. Use `register_htm` for auto-configuration
482
+ 2. Always use sessions for robot identification
483
+ 3. Run Sidekiq workers in production
484
+ 4. Monitor Redis memory usage
485
+
486
+ ### Rails Applications
487
+ 1. Create initializer for custom configuration
488
+ 2. Use per-user robot names
489
+ 3. Let Rails manage database connections
490
+ 4. Use ActiveJob for all background processing
491
+
492
+ ---
493
+
494
+ ## Examples
495
+
496
+ See working examples in the repository:
497
+
498
+ - **CLI:** [`examples/cli_app/htm_cli.rb`](https://github.com/madbomber/htm/blob/main/examples/cli_app/htm_cli.rb)
499
+ - **Sinatra:** [`examples/sinatra_app/app.rb`](https://github.com/madbomber/htm/blob/main/examples/sinatra_app/app.rb)
500
+ - **Rails:** `examples/rails_app/` (full Rails 7 app)
501
+
502
+ ---
503
+
504
+ ## Summary
505
+
506
+ | Feature | CLI | Sinatra | Rails |
507
+ |---------|-----|---------|-------|
508
+ | Job Backend | inline | sidekiq | active_job |
509
+ | Setup Complexity | Low | Medium | Low (auto) |
510
+ | Infrastructure | Database only | +Redis | +Rails |
511
+ | Response Time | Slow (1-3s) | Fast (15ms) | Fast (15ms) |
512
+ | Production Ready | ✓ (small scale) | ✓ | ✓ |
513
+ | Background Jobs | No | Yes | Yes |
514
+ | Auto-Configuration | Manual | `register_htm` | Railtie |
515
+
516
+ **Recommendation:**
517
+ - CLI tools → Use `:inline` backend
518
+ - Sinatra apps → Use `:sidekiq` backend
519
+ - Rails apps → Use `:active_job` backend (default)