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
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'simple_flow'
4
+
5
+ class HTM
6
+ module Workflows
7
+ # RememberWorkflow orchestrates the parallel processing of node enrichment
8
+ #
9
+ # Uses simple_flow to manage the dependency graph and parallel execution
10
+ # of embedding generation, tag extraction, and proposition extraction.
11
+ #
12
+ # The workflow structure:
13
+ # save_node (no deps) -> embedding, tags, propositions (parallel)
14
+ #
15
+ # @example Basic usage with fiber concurrency
16
+ # workflow = HTM::Workflows::RememberWorkflow.new(htm_instance)
17
+ # node_id = workflow.call(content: "PostgreSQL is great", tags: ["database"])
18
+ #
19
+ # @example With inline execution (for testing)
20
+ # workflow = HTM::Workflows::RememberWorkflow.new(htm_instance, concurrency: :threads)
21
+ # node_id = workflow.call(content: "Test content")
22
+ #
23
+ class RememberWorkflow
24
+ attr_reader :htm, :pipeline
25
+
26
+ # Initialize the remember workflow
27
+ #
28
+ # @param htm [HTM] HTM instance for the robot
29
+ # @param concurrency [Symbol] Concurrency model (:auto, :threads, :async)
30
+ #
31
+ def initialize(htm, concurrency: :auto)
32
+ @htm = htm
33
+ @concurrency = concurrency
34
+ @pipeline = build_pipeline
35
+ end
36
+
37
+ # Execute the remember workflow
38
+ #
39
+ # @param content [String] Content to remember
40
+ # @param tags [Array<String>] Manual tags to assign
41
+ # @param metadata [Hash] Metadata for the node
42
+ # @return [Integer] Node ID of the created memory
43
+ #
44
+ def call(content:, tags: [], metadata: {})
45
+ initial_data = {
46
+ content: content,
47
+ tags: tags,
48
+ metadata: metadata,
49
+ robot_id: @htm.robot_id,
50
+ htm: @htm
51
+ }
52
+
53
+ result = @pipeline.call_parallel(SimpleFlow::Result.new(initial_data))
54
+
55
+ if result.continue?
56
+ result.context[:node_id]
57
+ else
58
+ HTM.logger.error "RememberWorkflow failed: #{result.errors.inspect}"
59
+ raise HTM::Error, "Remember workflow failed: #{result.errors.values.flatten.join(', ')}"
60
+ end
61
+ end
62
+
63
+ # Get visualization of the workflow as Mermaid diagram
64
+ #
65
+ # @return [String] Mermaid diagram source
66
+ #
67
+ def to_mermaid
68
+ @pipeline.visualize_mermaid
69
+ end
70
+
71
+ # Get execution plan
72
+ #
73
+ # @return [String] Execution plan description
74
+ #
75
+ def execution_plan
76
+ @pipeline.execution_plan
77
+ end
78
+
79
+ private
80
+
81
+ def build_pipeline
82
+ SimpleFlow::Pipeline.new(concurrency: @concurrency) do
83
+ # Step 1: Save node to database (no dependencies)
84
+ step :save_node, ->(result) {
85
+ data = result.value
86
+ htm = data[:htm]
87
+
88
+ # Calculate token count
89
+ token_count = HTM.count_tokens(data[:content])
90
+
91
+ # Store in long-term memory
92
+ save_result = htm.long_term_memory.add(
93
+ content: data[:content],
94
+ token_count: token_count,
95
+ robot_id: data[:robot_id],
96
+ embedding: nil,
97
+ metadata: data[:metadata]
98
+ )
99
+
100
+ node_id = save_result[:node_id]
101
+ is_new = save_result[:is_new]
102
+
103
+ HTM.logger.info "RememberWorkflow: Node #{node_id} saved (new: #{is_new})"
104
+
105
+ result
106
+ .with_context(:node_id, node_id)
107
+ .with_context(:is_new, is_new)
108
+ .with_context(:token_count, token_count)
109
+ .with_context(:robot_node, save_result[:robot_node])
110
+ .continue(data)
111
+ }, depends_on: :none
112
+
113
+ # Step 2: Generate embedding (depends on save_node, runs in parallel with tags/propositions)
114
+ step :generate_embedding, ->(result) {
115
+ node_id = result.context[:node_id]
116
+ is_new = result.context[:is_new]
117
+
118
+ # Only generate for new nodes
119
+ if is_new
120
+ begin
121
+ HTM::Jobs::GenerateEmbeddingJob.perform(node_id: node_id)
122
+ rescue StandardError => e
123
+ HTM.logger.error "RememberWorkflow: Embedding generation failed: #{e.message}"
124
+ # Continue despite error - embedding is non-critical
125
+ end
126
+ end
127
+
128
+ result.continue(result.value)
129
+ }, depends_on: [:save_node]
130
+
131
+ # Step 3: Generate tags (depends on save_node, runs in parallel with embedding/propositions)
132
+ step :generate_tags, ->(result) {
133
+ node_id = result.context[:node_id]
134
+ is_new = result.context[:is_new]
135
+ manual_tags = result.value[:tags] || []
136
+
137
+ if is_new
138
+ # Add manual tags immediately
139
+ if manual_tags.any?
140
+ manual_tags.each do |tag_name|
141
+ tag = HTM::Models::Tag.find_or_create_by!(name: tag_name)
142
+ HTM::Models::NodeTag.find_or_create_by!(node_id: node_id, tag_id: tag.id)
143
+ end
144
+ end
145
+
146
+ begin
147
+ HTM::Jobs::GenerateTagsJob.perform(node_id: node_id)
148
+ rescue StandardError => e
149
+ HTM.logger.error "RememberWorkflow: Tag generation failed: #{e.message}"
150
+ # Continue despite error - tags are non-critical
151
+ end
152
+ else
153
+ # For existing nodes, only add manual tags
154
+ if manual_tags.any?
155
+ node = HTM::Models::Node.find(node_id)
156
+ node.add_tags(manual_tags)
157
+ end
158
+ end
159
+
160
+ result.continue(result.value)
161
+ }, depends_on: [:save_node]
162
+
163
+ # Step 4: Generate propositions (depends on save_node, runs in parallel with embedding/tags)
164
+ step :generate_propositions, ->(result) {
165
+ node_id = result.context[:node_id]
166
+ is_new = result.context[:is_new]
167
+ metadata = result.value[:metadata] || {}
168
+ robot_id = result.value[:robot_id]
169
+
170
+ # Only extract propositions for new nodes that aren't already propositions
171
+ if is_new && HTM.config.extract_propositions && !metadata[:is_proposition]
172
+ begin
173
+ HTM::Jobs::GeneratePropositionsJob.perform(node_id: node_id, robot_id: robot_id)
174
+ rescue StandardError => e
175
+ HTM.logger.error "RememberWorkflow: Proposition extraction failed: #{e.message}"
176
+ # Continue despite error - propositions are non-critical
177
+ end
178
+ end
179
+
180
+ result.continue(result.value)
181
+ }, depends_on: [:save_node]
182
+
183
+ # Step 5: Finalize (depends on all enrichment steps)
184
+ step :finalize, ->(result) {
185
+ node_id = result.context[:node_id]
186
+ token_count = result.context[:token_count]
187
+ robot_node = result.context[:robot_node]
188
+ htm = result.value[:htm]
189
+
190
+ # Add to working memory
191
+ unless htm.working_memory.has_space?(token_count)
192
+ evicted = htm.working_memory.evict_to_make_space(token_count)
193
+ evicted_keys = evicted.map { |n| n[:key] }
194
+ htm.long_term_memory.mark_evicted(robot_id: result.value[:robot_id], node_ids: evicted_keys) if evicted_keys.any?
195
+ end
196
+ htm.working_memory.add(node_id, result.value[:content], token_count: token_count, access_count: 0)
197
+
198
+ # Mark as in working memory
199
+ robot_node.update!(working_memory: true)
200
+
201
+ # Update robot activity
202
+ htm.long_term_memory.update_robot_activity(result.value[:robot_id])
203
+
204
+ HTM.logger.info "RememberWorkflow: Node #{node_id} finalized"
205
+
206
+ result.continue(result.value)
207
+ }, depends_on: [:generate_embedding, :generate_tags, :generate_propositions]
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
data/lib/htm.rb CHANGED
@@ -19,6 +19,7 @@ require_relative "htm/jobs/generate_tags_job"
19
19
  require_relative "htm/jobs/generate_propositions_job"
20
20
  require_relative "htm/loaders/markdown_chunker"
21
21
  require_relative "htm/loaders/markdown_loader"
22
+ require_relative "htm/workflows/remember_workflow"
22
23
  require_relative "htm/observability"
23
24
  require_relative "htm/telemetry"
24
25
  require_relative "htm/working_memory_channel"
data/mkdocs.yml CHANGED
@@ -48,7 +48,6 @@ theme:
48
48
  - navigation.tracking
49
49
  - navigation.tabs
50
50
  - navigation.tabs.sticky
51
- - navigation.sections
52
51
  - navigation.path
53
52
  - navigation.indexes
54
53
  - navigation.top
@@ -166,7 +165,38 @@ extra:
166
165
 
167
166
  # Navigation
168
167
  nav:
169
- - Home: index.md
168
+ - Home:
169
+ - Overview: index.md
170
+ - MCP (htm_mcp):
171
+ - Server (htm_mcp): guides/mcp-server.md
172
+ - Example Usage: examples/mcp-client.md
173
+ - Robots!:
174
+ - robots/index.md
175
+ - Why "Robots"?: robots/why-robots.md
176
+ - Hive Mind: robots/hive-mind.md
177
+ - Two-Tier Memory: robots/two-tier-memory.md
178
+ - Multi-Robot Systems: robots/multi-robot.md
179
+ - Robot Groups: robots/robot-groups.md
180
+ - Additional Features:
181
+ - Configuration: guides/configuration.md
182
+ - Hierarchical Tags: guides/tags.md
183
+ - Propositions: guides/propositions.md
184
+ - File Loading: guides/file-loading.md
185
+ - Telemetry: guides/telemetry.md
186
+ - Search Strategies: guides/search-strategies.md
187
+ - Examples:
188
+ - examples/index.md
189
+ - Basic Usage: examples/basic-usage.md
190
+ - Standalone App: examples/standalone-app.md
191
+ - LLM Configuration: examples/llm-configuration.md
192
+ - Config Files: examples/config-files.md
193
+ - File Loading: examples/file-loading.md
194
+ - Timeframes: examples/timeframes.md
195
+ - Robot Groups: examples/robot-groups.md
196
+ - Telemetry: examples/telemetry.md
197
+ - Framework Integration:
198
+ - Rails App: examples/rails-integration.md
199
+ - Sinatra App: examples/sinatra-integration.md
170
200
  - Getting Started:
171
201
  - getting-started/index.md
172
202
  - Installation: getting-started/installation.md
@@ -174,8 +204,6 @@ nav:
174
204
  - Architecture:
175
205
  - architecture/index.md
176
206
  - Overview: architecture/overview.md
177
- - Two-Tier Memory: architecture/two-tier-memory.md
178
- - Hive Mind: architecture/hive-mind.md
179
207
  - ADRs:
180
208
  - architecture/adrs/index.md
181
209
  - ADR-001 PostgreSQL & TimescaleDB: architecture/adrs/001-postgresql-timescaledb.md
@@ -196,10 +224,7 @@ nav:
196
224
  - Recalling Memories: guides/recalling-memories.md
197
225
  - Working Memory: guides/working-memory.md
198
226
  - Long-Term Memory: guides/long-term-memory.md
199
- - Multi-Robot Usage: guides/multi-robot.md
200
- - Search Strategies: guides/search-strategies.md
201
227
  - Context Assembly: guides/context-assembly.md
202
- - MCP Server: guides/mcp-server.md
203
228
  - API Reference:
204
229
  - api/index.md
205
230
  - HTM Class: api/htm.md
@@ -211,7 +236,7 @@ nav:
211
236
  - api/yard-reference.md
212
237
  - HTM Module: api/yard/HTM.md
213
238
  - Core Classes:
214
- - Configuration: api/yard/HTM/Configuration.md
239
+ - Configuration: api/yard/HTM/Config.md
215
240
  - Database: api/yard/HTM/Database.md
216
241
  - LongTermMemory: api/yard/HTM/LongTermMemory.md
217
242
  - WorkingMemory: api/yard/HTM/WorkingMemory.md
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: htm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.18
4
+ version: 0.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
@@ -163,6 +163,34 @@ dependencies:
163
163
  - - ">="
164
164
  - !ruby/object:Gem::Version
165
165
  version: '2.6'
166
+ - !ruby/object:Gem::Dependency
167
+ name: simple_flow
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ type: :runtime
174
+ prerelease: false
175
+ version_requirements: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ - !ruby/object:Gem::Dependency
181
+ name: async
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: '2.0'
187
+ type: :runtime
188
+ prerelease: false
189
+ version_requirements: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: '2.0'
166
194
  - !ruby/object:Gem::Dependency
167
195
  name: rake
168
196
  requirement: !ruby/object:Gem::Requirement
@@ -329,7 +357,8 @@ files:
329
357
  - docs/api/yard/HTM/AuthorizationError.md
330
358
  - docs/api/yard/HTM/CircuitBreaker.md
331
359
  - docs/api/yard/HTM/CircuitBreakerOpenError.md
332
- - docs/api/yard/HTM/Configuration.md
360
+ - docs/api/yard/HTM/Config.md
361
+ - docs/api/yard/HTM/ConfigSection.md
333
362
  - docs/api/yard/HTM/Database.md
334
363
  - docs/api/yard/HTM/DatabaseError.md
335
364
  - docs/api/yard/HTM/EmbeddingError.md
@@ -372,16 +401,17 @@ files:
372
401
  - docs/architecture/adrs/010-redis-working-memory-rejected.md
373
402
  - docs/architecture/adrs/011-pgai-integration.md
374
403
  - docs/architecture/adrs/index.md
375
- - docs/architecture/hive-mind.md
376
404
  - docs/architecture/index.md
377
405
  - docs/architecture/overview.md
378
- - docs/architecture/two-tier-memory.md
379
406
  - docs/assets/css/custom.css
380
407
  - docs/assets/images/adr-010-current-architecture.svg
381
408
  - docs/assets/images/adr-010-proposed-architecture.svg
382
409
  - docs/assets/images/adr-dependency-tree.svg
410
+ - docs/assets/images/balanced-strategy-decay.svg
383
411
  - docs/assets/images/class-hierarchy.svg
412
+ - docs/assets/images/eviction-priority.svg
384
413
  - docs/assets/images/exception-hierarchy.svg
414
+ - docs/assets/images/hive-mind-shared-memory.svg
385
415
  - docs/assets/images/htm-architecture-overview.svg
386
416
  - docs/assets/images/htm-complete-memory-flow.svg
387
417
  - docs/assets/images/htm-context-assembly-flow.svg
@@ -398,10 +428,12 @@ files:
398
428
  - docs/assets/images/htm-working-memory-architecture.svg
399
429
  - docs/assets/images/htm.jpg
400
430
  - docs/assets/images/htm_demo.gif
431
+ - docs/assets/images/memory-topology.svg
401
432
  - docs/assets/images/multi-provider-failover.svg
402
433
  - docs/assets/images/project-structure.svg
403
434
  - docs/assets/images/robot-group-architecture.svg
404
435
  - docs/assets/images/test-directory-structure.svg
436
+ - docs/assets/images/two-tier-memory-architecture.svg
405
437
  - docs/assets/js/mathjax.js
406
438
  - docs/assets/videos/htm_video.mp4
407
439
  - docs/database/README.md
@@ -442,26 +474,46 @@ files:
442
474
  - docs/development/schema.md
443
475
  - docs/development/setup.md
444
476
  - docs/development/testing.md
477
+ - docs/examples/basic-usage.md
478
+ - docs/examples/config-files.md
479
+ - docs/examples/file-loading.md
480
+ - docs/examples/index.md
481
+ - docs/examples/llm-configuration.md
482
+ - docs/examples/mcp-client.md
483
+ - docs/examples/rails-integration.md
484
+ - docs/examples/robot-groups.md
485
+ - docs/examples/sinatra-integration.md
486
+ - docs/examples/standalone-app.md
487
+ - docs/examples/telemetry.md
488
+ - docs/examples/timeframes.md
445
489
  - docs/getting-started/index.md
446
490
  - docs/getting-started/installation.md
447
491
  - docs/getting-started/quick-start.md
448
492
  - docs/guides/adding-memories.md
493
+ - docs/guides/configuration.md
449
494
  - docs/guides/context-assembly.md
495
+ - docs/guides/file-loading.md
450
496
  - docs/guides/getting-started.md
451
497
  - docs/guides/index.md
452
498
  - docs/guides/long-term-memory.md
453
499
  - docs/guides/mcp-server.md
454
- - docs/guides/multi-robot.md
500
+ - docs/guides/propositions.md
455
501
  - docs/guides/recalling-memories.md
456
- - docs/guides/robot-groups.md
457
502
  - docs/guides/search-strategies.md
503
+ - docs/guides/tags.md
504
+ - docs/guides/telemetry.md
458
505
  - docs/guides/working-memory.md
459
506
  - docs/images/htm-er-diagram.svg
460
507
  - docs/images/telemetry-architecture.svg
461
508
  - docs/index.md
462
509
  - docs/multi_framework_support.md
510
+ - docs/robots/hive-mind.md
511
+ - docs/robots/index.md
512
+ - docs/robots/multi-robot.md
513
+ - docs/robots/robot-groups.md
514
+ - docs/robots/two-tier-memory.md
515
+ - docs/robots/why-robots.md
463
516
  - docs/setup_local_database.md
464
- - docs/telemetry.md
465
517
  - docs/using_rake_tasks_in_your_app.md
466
518
  - examples/README.md
467
519
  - examples/basic_usage.rb
@@ -585,6 +637,7 @@ files:
585
637
  - lib/htm/timeframe.rb
586
638
  - lib/htm/timeframe_extractor.rb
587
639
  - lib/htm/version.rb
640
+ - lib/htm/workflows/remember_workflow.rb
588
641
  - lib/htm/working_memory.rb
589
642
  - lib/htm/working_memory_channel.rb
590
643
  - lib/tasks/db.rake
@@ -1,240 +0,0 @@
1
- # Class: HTM::Configuration
2
- **Inherits:** Object
3
-
4
-
5
- HTM Configuration
6
-
7
- HTM uses RubyLLM for multi-provider LLM support. Supported providers:
8
- * :openai (OpenAI API)
9
- * :anthropic (Anthropic Claude)
10
- * :gemini (Google Gemini)
11
- * :azure (Azure OpenAI)
12
- * :ollama (Local Ollama - default)
13
- * :huggingface (HuggingFace Inference API)
14
- * :openrouter (OpenRouter)
15
- * :bedrock (AWS Bedrock)
16
- * :deepseek (DeepSeek)
17
-
18
-
19
- **`@example`** Using nested configuration sections
20
- ```ruby
21
- HTM.configure do |config|
22
- config.embedding.provider = :openai
23
- config.embedding.model = 'text-embedding-3-small'
24
- config.tag.provider = :openai
25
- config.tag.model = 'gpt-4o-mini'
26
- config.openai_api_key = ENV['OPENAI_API_KEY']
27
- end
28
- ```
29
- **`@example`** Using Ollama (local default)
30
- ```ruby
31
- HTM.configure do |config|
32
- config.embedding.provider = :ollama
33
- config.embedding.model = 'nomic-embed-text'
34
- config.tag.provider = :ollama
35
- config.tag.model = 'llama3'
36
- config.ollama_url = 'http://localhost:11434'
37
- end
38
- ```
39
- **`@example`** Mixed providers
40
- ```ruby
41
- HTM.configure do |config|
42
- config.embedding.provider = :openai
43
- config.embedding.model = 'text-embedding-3-small'
44
- config.openai_api_key = ENV['OPENAI_API_KEY']
45
- config.tag.provider = :anthropic
46
- config.tag.model = 'claude-3-haiku-20240307'
47
- config.anthropic_api_key = ENV['ANTHROPIC_API_KEY']
48
- end
49
- ```
50
- **`@example`** Job and chunking configuration
51
- ```ruby
52
- HTM.configure do |config|
53
- config.job.backend = :inline # or :sidekiq, :active_job, :thread
54
- config.chunking.size = 1024
55
- config.chunking.overlap = 64
56
- config.proposition.enabled = true
57
- config.proposition.provider = :ollama
58
- config.proposition.model = 'gemma3:latest'
59
- end
60
- ```
61
- **`@example`**
62
- ```ruby
63
- HTM.configure do |config|
64
- config.embedding_generator = ->(text) {
65
- MyApp::LLMService.embed(text) # Returns Array<Float>
66
- }
67
- config.tag_extractor = ->(text, ontology) {
68
- MyApp::LLMService.extract_tags(text, ontology) # Returns Array<String>
69
- }
70
- config.logger = Rails.logger
71
- end
72
- ```
73
- # Attributes
74
- ## anthropic_api_key[RW] {: #attribute-i-anthropic_api_key }
75
- Returns the value of attribute anthropic_api_key.
76
-
77
- ## azure_api_key[RW] {: #attribute-i-azure_api_key }
78
- Returns the value of attribute azure_api_key.
79
-
80
- ## azure_api_version[RW] {: #attribute-i-azure_api_version }
81
- Returns the value of attribute azure_api_version.
82
-
83
- ## azure_endpoint[RW] {: #attribute-i-azure_endpoint }
84
- Returns the value of attribute azure_endpoint.
85
-
86
- ## bedrock_access_key[RW] {: #attribute-i-bedrock_access_key }
87
- Returns the value of attribute bedrock_access_key.
88
-
89
- ## bedrock_region[RW] {: #attribute-i-bedrock_region }
90
- Returns the value of attribute bedrock_region.
91
-
92
- ## bedrock_secret_key[RW] {: #attribute-i-bedrock_secret_key }
93
- Returns the value of attribute bedrock_secret_key.
94
-
95
- ## chunk_overlap[RW] {: #attribute-i-chunk_overlap }
96
- Character overlap between chunks (default: 64)
97
-
98
- ## chunk_size[RW] {: #attribute-i-chunk_size }
99
- Chunking configuration (for file loading)
100
-
101
- ## circuit_breaker_failure_threshold[RW] {: #attribute-i-circuit_breaker_failure_threshold }
102
- Circuit breaker configuration
103
-
104
- ## circuit_breaker_half_open_max_calls[RW] {: #attribute-i-circuit_breaker_half_open_max_calls }
105
- Successes to close (default: 3)
106
-
107
- ## circuit_breaker_reset_timeout[RW] {: #attribute-i-circuit_breaker_reset_timeout }
108
- Seconds before half-open (default: 60)
109
-
110
- ## connection_timeout[RW] {: #attribute-i-connection_timeout }
111
- Returns the value of attribute connection_timeout.
112
-
113
- ## deepseek_api_key[RW] {: #attribute-i-deepseek_api_key }
114
- Returns the value of attribute deepseek_api_key.
115
-
116
- ## embedding_dimensions[RW] {: #attribute-i-embedding_dimensions }
117
- Returns the value of attribute embedding_dimensions.
118
-
119
- ## embedding_generator[RW] {: #attribute-i-embedding_generator }
120
- Returns the value of attribute embedding_generator.
121
-
122
- ## embedding_model[RW] {: #attribute-i-embedding_model }
123
- Returns the value of attribute embedding_model.
124
-
125
- ## embedding_provider[RW] {: #attribute-i-embedding_provider }
126
- Returns the value of attribute embedding_provider.
127
-
128
- ## embedding_timeout[RW] {: #attribute-i-embedding_timeout }
129
- Returns the value of attribute embedding_timeout.
130
-
131
- ## extract_propositions[RW] {: #attribute-i-extract_propositions }
132
- Returns the value of attribute extract_propositions.
133
-
134
- ## gemini_api_key[RW] {: #attribute-i-gemini_api_key }
135
- Returns the value of attribute gemini_api_key.
136
-
137
- ## huggingface_api_key[RW] {: #attribute-i-huggingface_api_key }
138
- Returns the value of attribute huggingface_api_key.
139
-
140
- ## job_backend[RW] {: #attribute-i-job_backend }
141
- Returns the value of attribute job_backend.
142
-
143
- ## logger[RW] {: #attribute-i-logger }
144
- Returns the value of attribute logger.
145
-
146
- ## max_embedding_dimension[RW] {: #attribute-i-max_embedding_dimension }
147
- Limit configuration
148
-
149
- ## max_tag_depth[RW] {: #attribute-i-max_tag_depth }
150
- Max tag hierarchy depth (default: 4)
151
-
152
- ## ollama_url[RW] {: #attribute-i-ollama_url }
153
- Returns the value of attribute ollama_url.
154
-
155
- ## openai_api_key[RW] {: #attribute-i-openai_api_key }
156
- Provider-specific API keys and endpoints
157
-
158
- ## openai_organization[RW] {: #attribute-i-openai_organization }
159
- Provider-specific API keys and endpoints
160
-
161
- ## openai_project[RW] {: #attribute-i-openai_project }
162
- Provider-specific API keys and endpoints
163
-
164
- ## openrouter_api_key[RW] {: #attribute-i-openrouter_api_key }
165
- Returns the value of attribute openrouter_api_key.
166
-
167
- ## proposition_extractor[RW] {: #attribute-i-proposition_extractor }
168
- Returns the value of attribute proposition_extractor.
169
-
170
- ## proposition_model[RW] {: #attribute-i-proposition_model }
171
- Returns the value of attribute proposition_model.
172
-
173
- ## proposition_provider[RW] {: #attribute-i-proposition_provider }
174
- Returns the value of attribute proposition_provider.
175
-
176
- ## proposition_timeout[RW] {: #attribute-i-proposition_timeout }
177
- Returns the value of attribute proposition_timeout.
178
-
179
- ## relevance_access_weight[RW] {: #attribute-i-relevance_access_weight }
180
- Access frequency weight (default: 0.1)
181
-
182
- ## relevance_recency_half_life_hours[RW] {: #attribute-i-relevance_recency_half_life_hours }
183
- Decay half-life in hours (default: 168 = 1 week)
184
-
185
- ## relevance_recency_weight[RW] {: #attribute-i-relevance_recency_weight }
186
- Temporal freshness weight (default: 0.1)
187
-
188
- ## relevance_semantic_weight[RW] {: #attribute-i-relevance_semantic_weight }
189
- Relevance scoring weights (must sum to 1.0)
190
-
191
- ## relevance_tag_weight[RW] {: #attribute-i-relevance_tag_weight }
192
- Tag overlap weight (default: 0.3)
193
-
194
- ## tag_extractor[RW] {: #attribute-i-tag_extractor }
195
- Returns the value of attribute tag_extractor.
196
-
197
- ## tag_model[RW] {: #attribute-i-tag_model }
198
- Returns the value of attribute tag_model.
199
-
200
- ## tag_provider[RW] {: #attribute-i-tag_provider }
201
- Returns the value of attribute tag_provider.
202
-
203
- ## tag_timeout[RW] {: #attribute-i-tag_timeout }
204
- Returns the value of attribute tag_timeout.
205
-
206
- ## telemetry_enabled[RW] {: #attribute-i-telemetry_enabled }
207
- Enable OpenTelemetry metrics (default: false)
208
-
209
- ## token_counter[RW] {: #attribute-i-token_counter }
210
- Returns the value of attribute token_counter.
211
-
212
- ## week_start[RW] {: #attribute-i-week_start }
213
- Returns the value of attribute week_start.
214
-
215
-
216
- # Instance Methods
217
- ## configure_ruby_llm(providernil) {: #method-i-configure_ruby_llm }
218
- Configure RubyLLM with the appropriate provider credentials
219
-
220
- **`@param`** [Symbol] The provider to configure (:openai, :anthropic, etc.)
221
-
222
- ## initialize() {: #method-i-initialize }
223
- **`@return`** [Configuration] a new instance of Configuration
224
-
225
- ## normalize_ollama_model(model_name) {: #method-i-normalize_ollama_model }
226
- Normalize Ollama model name to include tag if missing
227
-
228
- Ollama models require a tag (e.g., :latest, :7b, :13b). If the user specifies
229
- a model without a tag, we append :latest by default.
230
-
231
- **`@param`** [String] Original model name
232
-
233
- **`@return`** [String] Normalized model name with tag
234
-
235
- ## reset_to_defaults() {: #method-i-reset_to_defaults }
236
- Reset to default RubyLLM-based implementations
237
-
238
- ## validate!() {: #method-i-validate! }
239
- Validate configuration
240
-