htm 0.0.18 → 0.0.20

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -1
  3. data/README.md +12 -0
  4. data/db/seeds.rb +1 -1
  5. data/docs/api/embedding-service.md +140 -110
  6. data/docs/api/yard/HTM/ActiveRecordConfig.md +6 -0
  7. data/docs/api/yard/HTM/Config.md +173 -0
  8. data/docs/api/yard/HTM/ConfigSection.md +28 -0
  9. data/docs/api/yard/HTM/Database.md +1 -1
  10. data/docs/api/yard/HTM/Railtie.md +2 -2
  11. data/docs/api/yard/HTM.md +0 -57
  12. data/docs/api/yard/index.csv +76 -61
  13. data/docs/api/yard-reference.md +2 -1
  14. data/docs/architecture/adrs/003-ollama-embeddings.md +45 -36
  15. data/docs/architecture/adrs/004-hive-mind.md +1 -1
  16. data/docs/architecture/adrs/008-robot-identification.md +1 -1
  17. data/docs/architecture/index.md +11 -9
  18. data/docs/architecture/overview.md +11 -7
  19. data/docs/assets/images/balanced-strategy-decay.svg +41 -0
  20. data/docs/assets/images/class-hierarchy.svg +1 -1
  21. data/docs/assets/images/eviction-priority.svg +43 -0
  22. data/docs/assets/images/exception-hierarchy.svg +2 -2
  23. data/docs/assets/images/hive-mind-shared-memory.svg +52 -0
  24. data/docs/assets/images/htm-architecture-overview.svg +3 -3
  25. data/docs/assets/images/htm-core-components.svg +4 -4
  26. data/docs/assets/images/htm-layered-architecture.svg +1 -1
  27. data/docs/assets/images/htm-memory-addition-flow.svg +2 -2
  28. data/docs/assets/images/htm-memory-recall-flow.svg +2 -2
  29. data/docs/assets/images/memory-topology.svg +53 -0
  30. data/docs/assets/images/two-tier-memory-architecture.svg +55 -0
  31. data/docs/development/setup.md +76 -44
  32. data/docs/examples/basic-usage.md +133 -0
  33. data/docs/examples/config-files.md +170 -0
  34. data/docs/examples/file-loading.md +208 -0
  35. data/docs/examples/index.md +116 -0
  36. data/docs/examples/llm-configuration.md +168 -0
  37. data/docs/examples/mcp-client.md +172 -0
  38. data/docs/examples/rails-integration.md +173 -0
  39. data/docs/examples/robot-groups.md +210 -0
  40. data/docs/examples/sinatra-integration.md +218 -0
  41. data/docs/examples/standalone-app.md +216 -0
  42. data/docs/examples/telemetry.md +224 -0
  43. data/docs/examples/timeframes.md +143 -0
  44. data/docs/getting-started/installation.md +97 -40
  45. data/docs/getting-started/quick-start.md +28 -11
  46. data/docs/guides/configuration.md +515 -0
  47. data/docs/guides/file-loading.md +322 -0
  48. data/docs/guides/getting-started.md +40 -9
  49. data/docs/guides/index.md +3 -3
  50. data/docs/guides/mcp-server.md +30 -12
  51. data/docs/guides/propositions.md +264 -0
  52. data/docs/guides/recalling-memories.md +4 -4
  53. data/docs/guides/search-strategies.md +3 -3
  54. data/docs/guides/tags.md +318 -0
  55. data/docs/guides/telemetry.md +229 -0
  56. data/docs/index.md +8 -16
  57. data/docs/{architecture → robots}/hive-mind.md +8 -111
  58. data/docs/robots/index.md +73 -0
  59. data/docs/{guides → robots}/multi-robot.md +3 -3
  60. data/docs/{guides → robots}/robot-groups.md +8 -7
  61. data/docs/{architecture → robots}/two-tier-memory.md +13 -149
  62. data/docs/robots/why-robots.md +85 -0
  63. data/lib/htm/config/defaults.yml +4 -4
  64. data/lib/htm/config.rb +2 -2
  65. data/lib/htm/job_adapter.rb +75 -1
  66. data/lib/htm/version.rb +1 -1
  67. data/lib/htm/workflows/remember_workflow.rb +212 -0
  68. data/lib/htm.rb +1 -0
  69. data/mkdocs.yml +33 -8
  70. metadata +60 -7
  71. data/docs/api/yard/HTM/Configuration.md +0 -240
  72. data/docs/telemetry.md +0 -391
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7379c23800bf3f00cc328be9725b14bcea06a9d2158eaf3b3bca80b11a6efb74
4
- data.tar.gz: ec96095a72ab89fed1dd7df0ceaeb3888938f5ddbdea6fd3f3c06aa15b80bf67
3
+ metadata.gz: 73eb1c7c8727363608ac47f7c1afd26ebb47021a173c105e5bba364598bf143f
4
+ data.tar.gz: e9c6954e8bb6da65e26ea55878da3e817e59f28e3383d74f9b48a0501ebd882b
5
5
  SHA512:
6
- metadata.gz: 428b9c8f1db0f3a7a4be6e0b8bc4cc27f0bf058e7847c409cfca423c1bf9722a8efad92dbdd276d69844ab771670ea7cdc62e292018bec4705ed3f9f66255c16
7
- data.tar.gz: af62a40339de40eac22f90b919a626b0f2d61a14440cdd5ca9e0aaf87ca088cc086cd35bc1eb4394d87a0646512c0a30d2fb47fdee7ec9ea2c4f11e469f2a44b
6
+ metadata.gz: cb76637105f6033ba58d35f5fe3d73b41b990bd327069c7c526c196c787c62d2287e0fdac58261a2ee7b6d739af9f11bd58843c77b7ad6b486da95e02468665e
7
+ data.tar.gz: 9e4da2a308bfb5efe31a050406caee29e7a653e401a9665a271b3c094d540d50115663966f11f26b7b58a51f7a9354047ee6117ce69250e7dc5ffabb30469a48
data/CHANGELOG.md CHANGED
@@ -6,6 +6,57 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ## [Unreleased]
9
+
10
+ ## [0.0.20] - 2025-12-22
11
+ ### Added
12
+ - **Fiber-based job backend** - New `:fiber` backend for I/O-bound background jobs
13
+ - Uses `async` gem for cooperative concurrency
14
+ - Non-blocking execution ideal for LLM API calls
15
+ - `JobAdapter.enqueue_parallel(jobs)` for concurrent job execution
16
+ - Fiber backend runs jobs with `Async::Barrier` for parallel coordination
17
+ - **RememberWorkflow using simple_flow** - Parallel processing pipeline for node enrichment
18
+ - Orchestrates save_node → (embedding, tags, propositions in parallel) → finalize
19
+ - Uses `SimpleFlow::Pipeline` with dependency-based step execution
20
+ - Configurable concurrency model (`:auto`, `:threads`, `:async`)
21
+ - Visualization support: `to_mermaid` and `execution_plan` methods
22
+
23
+ ### Changed
24
+ - **async gem is now a required dependency** - Previously optional, now always available
25
+ - Enables fiber-based concurrency for all HTM installations
26
+ - `:fiber` is now the default job backend (was `:thread`)
27
+ - **Default job backend changed from `:thread` to `:fiber`** - Better performance for I/O-bound LLM operations
28
+
29
+ ### Removed
30
+ - **`JobAdapter.async_available?` method** - No longer needed since async is always available
31
+
32
+ ### Fixed
33
+ - **`connection_timeout` default inconsistency** - Unified default to 60 seconds across all files
34
+ - `test/configuration_test.rb`, `docs/guides/configuration.md`, and `db/seeds.rb` now match `defaults.yml`
35
+
36
+ ### Dependencies
37
+ - Added `async` (~> 2.0) as required runtime dependency
38
+ - Added `simple_flow` for workflow orchestration
39
+
40
+ ## [0.0.19] - 2025-12-21
41
+
42
+ ### Changed
43
+ - **Reorganized "Robots!" documentation** - Consolidated 5 robot-related docs into `docs/robots/` subdirectory
44
+ - Created `docs/robots/index.md` as section overview with navigation table and architecture diagram
45
+ - Moved `docs/robots.md` → `docs/robots/why-robots.md`
46
+ - Moved `docs/guides/multi-robot.md` → `docs/robots/multi-robot.md`
47
+ - Moved `docs/guides/robot-groups.md` → `docs/robots/robot-groups.md`
48
+ - Moved `docs/architecture/two-tier-memory.md` → `docs/robots/two-tier-memory.md`
49
+ - Moved `docs/architecture/hive-mind.md` → `docs/robots/hive-mind.md`
50
+ - Updated `mkdocs.yml` navigation with logical information flow
51
+ - Fixed 30+ broken relative links across documentation files
52
+ - **Extracted inline SVG graphics to standalone files** - Improved documentation maintainability
53
+ - From `hive-mind.md`: `hive-mind-shared-memory.svg`, `memory-topology.svg`
54
+ - From `two-tier-memory.md`: `two-tier-memory-architecture.svg`, `eviction-priority.svg`, `balanced-strategy-decay.svg`
55
+ - All SVGs now in `docs/assets/images/` and referenced via markdown image syntax
56
+
57
+ ### Fixed
58
+ - **ConfigSection.md unrecognized link warning** - Wrapped method signatures in backticks to prevent MkDocs interpreting bracket parameters as links
59
+
9
60
  ## [0.0.18] - 2025-12-20
10
61
  ### Added
11
62
  - **Anyway::Config-based configuration system** - Replaced custom Configuration class with robust multi-source config management
@@ -689,7 +740,14 @@ HTM.config.embedding.model
689
740
  - Working memory size is user-configurable
690
741
  - See ADRs for detailed architectural decisions and rationale
691
742
 
692
- [Unreleased]: https://github.com/madbomber/htm/compare/v0.0.12...HEAD
743
+ [Unreleased]: https://github.com/madbomber/htm/compare/v0.0.19...HEAD
744
+ [0.0.19]: https://github.com/madbomber/htm/compare/v0.0.18...v0.0.19
745
+ [0.0.18]: https://github.com/madbomber/htm/compare/v0.0.17...v0.0.18
746
+ [0.0.17]: https://github.com/madbomber/htm/compare/v0.0.15...v0.0.17
747
+ [0.0.15]: https://github.com/madbomber/htm/compare/v0.0.14...v0.0.15
748
+ [0.0.14]: https://github.com/madbomber/htm/compare/v0.0.13...v0.0.14
749
+ [0.0.13]: https://github.com/madbomber/htm/compare/v0.0.11...v0.0.13
750
+ [0.0.11]: https://github.com/madbomber/htm/compare/v0.0.10...v0.0.11
693
751
  [0.0.12]: https://github.com/madbomber/htm/compare/v0.0.10...v0.0.12
694
752
  [0.0.10]: https://github.com/madbomber/htm/compare/v0.0.9...v0.0.10
695
753
  [0.0.9]: https://github.com/madbomber/htm/compare/v0.0.8...v0.0.9
data/README.md CHANGED
@@ -1,4 +1,16 @@
1
+
1
2
  <div align="center">
3
+ <div style="background: linear-gradient(135deg, #90EE90 0%, #32CD32 100%); border: 4px solid #228B22; border-radius: 12px; padding: 20px; margin: 20px auto; max-width: 800px; box-shadow: 0 8px 16px rgba(34, 139, 34, 0.3);">
4
+ <p style="color: #000000; font-size: 42px; font-weight: bold; margin: 0;">
5
+ 🚀 v0.0.20 🚀
6
+ </p>
7
+ <p style="color: #000; font-size: 27px; font-weight: bold; margin: 10px 0 0 0; line-height: 1.6;">
8
+ <strong>Fiber-based concurrency</strong> is now the default.<br/>
9
+ Parallel embedding, tagging, and proposition extraction via simple_flow.
10
+ </p>
11
+ </div>
12
+
13
+
2
14
  <h1>HTM</h1>
3
15
  <img src="docs/assets/images/htm_demo.gif" alt="Tree of Knowledge is Growing" width="400">
4
16
 
data/db/seeds.rb CHANGED
@@ -37,7 +37,7 @@ tag_provider = (ENV['HTM_TAG_PROVIDER'] || 'ollama').to_sym
37
37
  tag_model = ENV['HTM_TAG_MODEL'] || 'gemma3'
38
38
  embedding_timeout = (ENV['HTM_EMBEDDING_TIMEOUT'] || '120').to_i
39
39
  tag_timeout = (ENV['HTM_TAG_TIMEOUT'] || '180').to_i
40
- connection_timeout = (ENV['HTM_CONNECTION_TIMEOUT'] || '30').to_i
40
+ connection_timeout = (ENV['HTM_CONNECTION_TIMEOUT'] || '60').to_i
41
41
 
42
42
  puts "Configuration:"
43
43
  puts " Embedding Provider: #{embedding_provider}"
@@ -4,15 +4,21 @@ Client-side embedding generation service for HTM.
4
4
 
5
5
  ## Overview
6
6
 
7
- `HTM::EmbeddingService` generates vector embeddings for text content before database insertion. It supports multiple embedding providers:
7
+ `HTM::EmbeddingService` generates vector embeddings for text content before database insertion. It uses RubyLLM to support multiple embedding providers:
8
8
 
9
- - **Ollama** - Local embedding server (default, via `nomic-embed-text` model)
10
- - **OpenAI** - OpenAI's `text-embedding-3-small` model
9
+ - **Ollama** - Local embedding server (default for development)
10
+ - **OpenAI** - OpenAI's embedding models
11
+ - **Anthropic** - For tag extraction (via chat models)
12
+ - **Gemini** - Google's embedding models
13
+ - **Azure** - Azure OpenAI deployments
14
+ - **Bedrock** - AWS Bedrock models
15
+ - **DeepSeek** - DeepSeek embeddings
11
16
 
12
17
  The service also provides token counting for working memory management.
13
18
 
14
19
  **Architecture:**
15
- - Ruby application generates embeddings via HTTP call to Ollama/OpenAI
20
+ - Ruby application generates embeddings via RubyLLM
21
+ - RubyLLM handles provider-specific API calls
16
22
  - Embeddings are passed to PostgreSQL during INSERT
17
23
  - Simple, reliable, cross-platform operation
18
24
 
@@ -34,7 +40,6 @@ Create a new embedding service instance.
34
40
  HTM::EmbeddingService.new(
35
41
  provider = :ollama,
36
42
  model: 'nomic-embed-text',
37
- ollama_url: nil,
38
43
  dimensions: nil
39
44
  )
40
45
  ```
@@ -43,11 +48,12 @@ HTM::EmbeddingService.new(
43
48
 
44
49
  | Parameter | Type | Default | Description |
45
50
  |-----------|------|---------|-------------|
46
- | `provider` | Symbol | `:ollama` | Embedding provider (`:ollama`, `:openai`) |
47
- | `model` | String | `'nomic-embed-text'` | Model name for the provider |
48
- | `ollama_url` | String, nil | `ENV['OLLAMA_URL']` or `'http://localhost:11434'` | Ollama server URL |
51
+ | `provider` | Symbol | `:ollama` | Embedding provider (`:ollama`, `:openai`, `:gemini`, `:azure`, `:bedrock`, `:deepseek`) |
52
+ | `model` | String | Provider-dependent | Model name for the provider |
49
53
  | `dimensions` | Integer, nil | Auto-detected | Expected embedding dimensions |
50
54
 
55
+ **Provider-specific configuration** is handled via environment variables (see RubyLLM documentation).
56
+
51
57
  #### Returns
52
58
 
53
59
  `HTM::EmbeddingService` - Configured embedding service instance
@@ -58,20 +64,19 @@ HTM::EmbeddingService.new(
58
64
 
59
65
  #### Examples
60
66
 
61
- **Default Ollama configuration:**
67
+ **Default configuration (uses Ollama):**
62
68
 
63
69
  ```ruby
64
70
  service = HTM::EmbeddingService.new
65
- # Uses Ollama at http://localhost:11434 with nomic-embed-text (768 dimensions)
71
+ # Uses Ollama with nomic-embed-text (768 dimensions)
66
72
  ```
67
73
 
68
- **Custom Ollama model:**
74
+ **Ollama with custom model:**
69
75
 
70
76
  ```ruby
71
77
  service = HTM::EmbeddingService.new(
72
78
  :ollama,
73
79
  model: 'mxbai-embed-large',
74
- ollama_url: 'http://localhost:11434',
75
80
  dimensions: 1024
76
81
  )
77
82
  ```
@@ -87,15 +92,27 @@ service = HTM::EmbeddingService.new(
87
92
  )
88
93
  ```
89
94
 
90
- **HTM automatically initializes EmbeddingService:**
95
+ **Gemini configuration:**
91
96
 
92
97
  ```ruby
93
- htm = HTM.new(
94
- robot_name: "Assistant",
95
- embedding_provider: :ollama,
96
- embedding_model: 'nomic-embed-text'
98
+ # Requires GEMINI_API_KEY environment variable
99
+ service = HTM::EmbeddingService.new(
100
+ :gemini,
101
+ model: 'text-embedding-004',
102
+ dimensions: 768
97
103
  )
98
- # EmbeddingService configured automatically
104
+ ```
105
+
106
+ **HTM global configuration (recommended):**
107
+
108
+ ```ruby
109
+ HTM.configure do |config|
110
+ config.embedding.provider = :openai # or :ollama, :gemini, etc.
111
+ config.embedding.model = 'text-embedding-3-small'
112
+ end
113
+
114
+ htm = HTM.new(robot_name: "Assistant")
115
+ # EmbeddingService configured automatically from global config
99
116
  ```
100
117
 
101
118
  ---
@@ -144,21 +161,24 @@ begin
144
161
  embedding = service.embed("some text")
145
162
  rescue HTM::EmbeddingError => e
146
163
  puts "Embedding failed: #{e.message}"
147
- # Check Ollama is running: curl http://localhost:11434/api/tags
164
+ # For Ollama: Check if running with `curl http://localhost:11434/api/tags`
165
+ # For cloud providers: Check API key is set correctly
148
166
  end
149
167
  ```
150
168
 
151
169
  #### Implementation Details
152
170
 
153
- **Ollama provider:**
154
- - Makes HTTP POST to `/api/embeddings`
155
- - Returns dense vector representation
156
- - Requires Ollama server running locally
171
+ All providers are handled through RubyLLM, which provides a consistent interface across providers.
172
+
173
+ **Ollama:** Local HTTP calls, requires Ollama server running
157
174
 
158
- **OpenAI provider:**
159
- - Makes HTTP POST to OpenAI API
160
- - Requires `OPENAI_API_KEY` environment variable
161
- - API costs: $0.0001 per 1K tokens
175
+ **OpenAI:** Cloud API calls, requires `OPENAI_API_KEY`
176
+
177
+ **Gemini:** Cloud API calls, requires `GEMINI_API_KEY`
178
+
179
+ **Azure:** Cloud API calls, requires Azure credentials
180
+
181
+ **Bedrock:** AWS API calls, requires AWS credentials
162
182
 
163
183
  ---
164
184
 
@@ -207,11 +227,13 @@ htm.add_message(
207
227
 
208
228
  ## Embedding Providers
209
229
 
210
- ### Ollama (Default)
230
+ HTM uses RubyLLM which supports multiple providers. Choose based on your requirements for privacy, cost, and quality.
231
+
232
+ ### Ollama (Default for Development)
211
233
 
212
234
  **Status**: ✅ Fully implemented
213
235
 
214
- Local embedding server with various models, accessed via HTTP.
236
+ Local embedding server with various models.
215
237
 
216
238
  **Installation:**
217
239
 
@@ -234,25 +256,10 @@ ollama pull nomic-embed-text
234
256
  **Configuration:**
235
257
 
236
258
  ```ruby
237
- service = HTM::EmbeddingService.new(
238
- :ollama,
239
- model: 'nomic-embed-text',
240
- ollama_url: 'http://localhost:11434'
241
- )
242
-
243
- embedding = service.embed("test text")
244
- ```
245
-
246
- **Troubleshooting:**
247
-
248
- If Ollama is unavailable, embedding generation will fail:
249
-
250
- ```ruby
251
- # Check Ollama is running
252
- system("curl http://localhost:11434/api/tags")
253
-
254
- # Start Ollama if needed
255
- system("ollama serve")
259
+ HTM.configure do |config|
260
+ config.embedding.provider = :ollama
261
+ config.embedding.model = 'nomic-embed-text'
262
+ end
256
263
  ```
257
264
 
258
265
  **Advantages:**
@@ -264,15 +271,14 @@ system("ollama serve")
264
271
  **Disadvantages:**
265
272
  - ❌ Requires local installation
266
273
  - ❌ Uses local compute resources
267
- - ❌ Slightly lower quality than OpenAI
268
274
 
269
275
  ---
270
276
 
271
- ### OpenAI
277
+ ### OpenAI (Recommended for Production)
272
278
 
273
279
  **Status**: ✅ Fully implemented
274
280
 
275
- Uses OpenAI's embedding API, accessed via HTTP.
281
+ Uses OpenAI's embedding API.
276
282
 
277
283
  **Configuration:**
278
284
 
@@ -281,13 +287,10 @@ export OPENAI_API_KEY="sk-..."
281
287
  ```
282
288
 
283
289
  ```ruby
284
- service = HTM::EmbeddingService.new(
285
- :openai,
286
- model: 'text-embedding-3-small'
287
- )
288
-
289
- # Add message - embedding generated via OpenAI API
290
- embedding = service.embed("test text")
290
+ HTM.configure do |config|
291
+ config.embedding.provider = :openai
292
+ config.embedding.model = 'text-embedding-3-small'
293
+ end
291
294
  ```
292
295
 
293
296
  **Models:**
@@ -295,20 +298,7 @@ embedding = service.embed("test text")
295
298
  | Model | Dimensions | Speed | Cost |
296
299
  |-------|------------|-------|------|
297
300
  | `text-embedding-3-small` | 1536 | Fast | $0.0001/1K tokens |
298
- | `text-embedding-ada-002` | 1536 | Fast | $0.0001/1K tokens |
299
-
300
- **Error Handling:**
301
-
302
- ```ruby
303
- begin
304
- service = HTM::EmbeddingService.new(:openai)
305
- embedding = service.embed("test")
306
- rescue HTM::EmbeddingError => e
307
- if e.message.include?("API key")
308
- puts "Set OPENAI_API_KEY environment variable"
309
- end
310
- end
311
- ```
301
+ | `text-embedding-3-large` | 3072 | Fast | $0.00013/1K tokens |
312
302
 
313
303
  **Advantages:**
314
304
  - ✅ High quality embeddings
@@ -316,10 +306,44 @@ end
316
306
  - ✅ Managed service
317
307
 
318
308
  **Disadvantages:**
319
- - ❌ API costs ($0.0001 per 1K tokens)
309
+ - ❌ API costs
320
310
  - ❌ Requires internet connection
321
- - ❌ Data sent to OpenAI servers
322
- - ❌ Requires API key management
311
+ - ❌ Data sent to cloud
312
+
313
+ ---
314
+
315
+ ### Other Providers
316
+
317
+ **Gemini:**
318
+ ```bash
319
+ export GEMINI_API_KEY="..."
320
+ ```
321
+ ```ruby
322
+ HTM.configure do |config|
323
+ config.embedding.provider = :gemini
324
+ config.embedding.model = 'text-embedding-004'
325
+ end
326
+ ```
327
+
328
+ **Azure OpenAI:**
329
+ ```bash
330
+ export AZURE_OPENAI_API_KEY="..."
331
+ export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com"
332
+ ```
333
+
334
+ **AWS Bedrock:**
335
+ ```bash
336
+ export AWS_ACCESS_KEY_ID="..."
337
+ export AWS_SECRET_ACCESS_KEY="..."
338
+ export AWS_REGION="us-east-1"
339
+ ```
340
+
341
+ **DeepSeek:**
342
+ ```bash
343
+ export DEEPSEEK_API_KEY="..."
344
+ ```
345
+
346
+ See the [RubyLLM documentation](https://rubyllm.com/) for complete provider configuration.
323
347
 
324
348
  ---
325
349
 
@@ -335,15 +359,17 @@ end
335
359
  system("ollama serve")
336
360
  ```
337
361
 
338
- **OpenAI API key missing:**
362
+ **API key missing (cloud providers):**
339
363
 
340
364
  ```ruby
341
- # Error: OPENAI_API_KEY not set
365
+ # Error: API key not set
342
366
  # Solution: Set environment variable
343
- ENV['OPENAI_API_KEY'] = 'sk-...'
367
+ ENV['OPENAI_API_KEY'] = 'sk-...' # For OpenAI
368
+ ENV['ANTHROPIC_API_KEY'] = 'sk-...' # For Anthropic
369
+ ENV['GEMINI_API_KEY'] = '...' # For Gemini
344
370
  ```
345
371
 
346
- **Invalid model:**
372
+ **Invalid model (Ollama):**
347
373
 
348
374
  ```ruby
349
375
  # Error: Model not found
@@ -368,9 +394,10 @@ Based on typical production workloads:
368
394
  | Ollama | nomic-embed-text | 20ms | 40ms | Free |
369
395
  | Ollama | mxbai-embed-large | 30ms | 60ms | Free |
370
396
  | OpenAI | text-embedding-3-small | 40ms | 80ms | $0.10 |
397
+ | Gemini | text-embedding-004 | 50ms | 90ms | Varies |
371
398
 
372
399
  **Factors affecting latency:**
373
- - Network latency (Ollama local vs OpenAI remote)
400
+ - Network latency (local providers vs cloud)
374
401
  - Text length (longer text = more tokens = slower)
375
402
  - Model size (larger models = slower)
376
403
  - System load (CPU/GPU utilization)
@@ -380,14 +407,17 @@ Based on typical production workloads:
380
407
  **Use appropriate model size:**
381
408
 
382
409
  ```ruby
383
- # Fast but lower quality
384
- service = HTM::EmbeddingService.new(:ollama, model: 'all-minilm')
410
+ # Fast but lower quality (Ollama)
411
+ HTM.configure { |c| c.embedding.model = 'all-minilm' }
385
412
 
386
- # Balanced (recommended)
387
- service = HTM::EmbeddingService.new(:ollama, model: 'nomic-embed-text')
413
+ # Balanced - Ollama (recommended for development)
414
+ HTM.configure { |c| c.embedding.model = 'nomic-embed-text' }
388
415
 
389
- # Slower but higher quality
390
- service = HTM::EmbeddingService.new(:ollama, model: 'mxbai-embed-large')
416
+ # High quality - OpenAI (recommended for production)
417
+ HTM.configure do |c|
418
+ c.embedding.provider = :openai
419
+ c.embedding.model = 'text-embedding-3-small'
420
+ end
391
421
  ```
392
422
 
393
423
  **Batch operations:**
@@ -410,12 +440,12 @@ end
410
440
  HTM initializes `EmbeddingService` automatically:
411
441
 
412
442
  ```ruby
413
- htm = HTM.new(
414
- robot_name: "Assistant",
415
- embedding_provider: :ollama, # Optional, default
416
- embedding_model: 'nomic-embed-text' # Optional, default
417
- )
443
+ HTM.configure do |config|
444
+ config.embedding.provider = :ollama # or :openai, :gemini, etc.
445
+ config.embedding.model = 'nomic-embed-text'
446
+ end
418
447
 
448
+ htm = HTM.new(robot_name: "Assistant")
419
449
  # EmbeddingService is ready to use internally
420
450
  ```
421
451
 
@@ -426,13 +456,13 @@ sequenceDiagram
426
456
  participant App as Application
427
457
  participant HTM as HTM
428
458
  participant ES as EmbeddingService
429
- participant Ollama as Ollama/OpenAI
459
+ participant LLM as LLM Provider (via RubyLLM)
430
460
  participant DB as PostgreSQL
431
461
 
432
462
  App->>HTM: add_message(content)
433
463
  HTM->>ES: embed(content)
434
- ES->>Ollama: HTTP POST /api/embeddings
435
- Ollama->>ES: embedding vector
464
+ ES->>LLM: Generate embedding
465
+ LLM->>ES: embedding vector
436
466
  ES->>HTM: Array<Float>
437
467
  HTM->>DB: INSERT with embedding
438
468
  DB->>HTM: node_id
@@ -484,21 +514,20 @@ puts "Token count: #{tokens}"
484
514
  ### Multiple Providers
485
515
 
486
516
  ```ruby
487
- # Ollama for development
488
- dev_service = HTM::EmbeddingService.new(
489
- :ollama,
490
- model: 'nomic-embed-text'
491
- )
517
+ # Configure for development (Ollama)
518
+ HTM.configure do |config|
519
+ config.embedding.provider = :ollama
520
+ config.embedding.model = 'nomic-embed-text'
521
+ end
492
522
 
493
- # OpenAI for production
494
- prod_service = HTM::EmbeddingService.new(
495
- :openai,
496
- model: 'text-embedding-3-small'
497
- )
523
+ # Configure for production (OpenAI)
524
+ HTM.configure do |config|
525
+ config.embedding.provider = :openai
526
+ config.embedding.model = 'text-embedding-3-small'
527
+ end
498
528
 
499
- # Same interface
500
- dev_embedding = dev_service.embed("test")
501
- prod_embedding = prod_service.embed("test")
529
+ # Same interface regardless of provider
530
+ embedding = HTM::EmbeddingService.new.embed("test")
502
531
  ```
503
532
 
504
533
  ### Custom Model Dimensions
@@ -521,6 +550,7 @@ embedding = service.embed("text")
521
550
 
522
551
  - [HTM API](htm.md) - Main HTM class
523
552
  - [LongTermMemory API](long-term-memory.md) - Storage layer
524
- - [ADR-003: Ollama Embeddings](../architecture/adrs/003-ollama-embeddings.md) - Architecture decision
525
- - [Ollama Documentation](https://ollama.ai/docs) - Ollama setup guide
526
- - [OpenAI Embeddings](https://platform.openai.com/docs/guides/embeddings) - OpenAI API docs
553
+ - [ADR-003: Default Embedding Provider](../architecture/adrs/003-ollama-embeddings.md) - Architecture decision for defaults
554
+ - [RubyLLM Documentation](https://rubyllm.com/) - Multi-provider LLM interface
555
+ - [Ollama Documentation](https://ollama.ai/docs) - Local LLM provider
556
+ - [OpenAI Embeddings](https://platform.openai.com/docs/guides/embeddings) - Cloud embeddings
@@ -4,6 +4,10 @@
4
4
 
5
5
  ActiveRecord database configuration and model loading
6
6
 
7
+ Uses HTM::Config for database settings. Configuration can come from:
8
+ * Environment variables (HTM_DATABASE__URL, HTM_DATABASE__HOST, etc.)
9
+ * Programmatic configuration via HTM.configure
10
+
7
11
 
8
12
  # Class Methods
9
13
  ## connected?() {: #method-c-connected? }
@@ -18,6 +22,8 @@ Close all database connections
18
22
  Establish database connection from HTM::Config
19
23
  ## load_database_config() {: #method-c-load_database_config }
20
24
  Load database configuration from HTM::Config
25
+ **`@return`** [Hash] ActiveRecord-compatible configuration hash
26
+
21
27
  ## verify_extensions!() {: #method-c-verify_extensions! }
22
28
  Verify required extensions are available
23
29