htm 0.0.17 → 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.
- checksums.yaml +4 -4
- data/.architecture/decisions/adrs/001-use-postgresql-timescaledb-storage.md +1 -1
- data/.architecture/decisions/adrs/011-database-side-embedding-generation-with-pgai.md +4 -4
- data/.architecture/decisions/adrs/012-llm-driven-ontology-topic-extraction.md +1 -1
- data/.envrc +12 -25
- data/.irbrc +7 -7
- data/.tbls.yml +2 -2
- data/CHANGELOG.md +130 -1
- data/README.md +13 -1
- data/Rakefile +8 -3
- data/SETUP.md +12 -12
- data/bin/htm_mcp +0 -4
- data/db/seed_data/README.md +2 -2
- data/db/seeds.rb +3 -3
- data/docs/api/database.md +37 -37
- data/docs/api/embedding-service.md +140 -110
- data/docs/api/htm.md +1 -1
- data/docs/api/yard/HTM/ActiveRecordConfig.md +8 -2
- data/docs/api/yard/HTM/Config.md +173 -0
- data/docs/api/yard/HTM/ConfigSection.md +28 -0
- data/docs/api/yard/HTM/Database.md +7 -8
- data/docs/api/yard/HTM/JobAdapter.md +1 -1
- data/docs/api/yard/HTM.md +0 -57
- data/docs/api/yard/index.csv +76 -61
- data/docs/api/yard-reference.md +2 -1
- data/docs/architecture/adrs/001-postgresql-timescaledb.md +1 -1
- data/docs/architecture/adrs/003-ollama-embeddings.md +45 -36
- data/docs/architecture/adrs/004-hive-mind.md +1 -1
- data/docs/architecture/adrs/008-robot-identification.md +1 -1
- data/docs/architecture/adrs/011-pgai-integration.md +4 -4
- data/docs/architecture/index.md +11 -9
- data/docs/architecture/overview.md +11 -7
- data/docs/assets/images/balanced-strategy-decay.svg +41 -0
- data/docs/assets/images/class-hierarchy.svg +1 -1
- data/docs/assets/images/eviction-priority.svg +43 -0
- data/docs/assets/images/exception-hierarchy.svg +2 -2
- data/docs/assets/images/hive-mind-shared-memory.svg +52 -0
- data/docs/assets/images/htm-architecture-overview.svg +3 -3
- data/docs/assets/images/htm-core-components.svg +4 -4
- data/docs/assets/images/htm-layered-architecture.svg +1 -1
- data/docs/assets/images/htm-memory-addition-flow.svg +2 -2
- data/docs/assets/images/htm-memory-recall-flow.svg +2 -2
- data/docs/assets/images/memory-topology.svg +53 -0
- data/docs/assets/images/two-tier-memory-architecture.svg +55 -0
- data/docs/database_rake_tasks.md +5 -5
- data/docs/development/rake-tasks.md +11 -11
- data/docs/development/setup.md +97 -65
- data/docs/development/testing.md +1 -1
- data/docs/examples/basic-usage.md +133 -0
- data/docs/examples/config-files.md +170 -0
- data/docs/examples/file-loading.md +208 -0
- data/docs/examples/index.md +116 -0
- data/docs/examples/llm-configuration.md +168 -0
- data/docs/examples/mcp-client.md +172 -0
- data/docs/examples/rails-integration.md +173 -0
- data/docs/examples/robot-groups.md +210 -0
- data/docs/examples/sinatra-integration.md +218 -0
- data/docs/examples/standalone-app.md +216 -0
- data/docs/examples/telemetry.md +224 -0
- data/docs/examples/timeframes.md +143 -0
- data/docs/getting-started/installation.md +117 -60
- data/docs/getting-started/quick-start.md +35 -18
- data/docs/guides/configuration.md +515 -0
- data/docs/guides/file-loading.md +322 -0
- data/docs/guides/getting-started.md +42 -11
- data/docs/guides/index.md +3 -3
- data/docs/guides/long-term-memory.md +1 -1
- data/docs/guides/mcp-server.md +47 -29
- data/docs/guides/propositions.md +264 -0
- data/docs/guides/recalling-memories.md +4 -4
- data/docs/guides/search-strategies.md +3 -3
- data/docs/guides/tags.md +318 -0
- data/docs/guides/telemetry.md +229 -0
- data/docs/index.md +10 -18
- data/docs/multi_framework_support.md +8 -8
- data/docs/{architecture → robots}/hive-mind.md +8 -111
- data/docs/robots/index.md +73 -0
- data/docs/{guides → robots}/multi-robot.md +3 -3
- data/docs/{guides → robots}/robot-groups.md +14 -13
- data/docs/{architecture → robots}/two-tier-memory.md +13 -149
- data/docs/robots/why-robots.md +85 -0
- data/docs/setup_local_database.md +19 -19
- data/docs/using_rake_tasks_in_your_app.md +14 -14
- data/examples/README.md +50 -6
- data/examples/basic_usage.rb +31 -21
- data/examples/cli_app/README.md +8 -8
- data/examples/cli_app/htm_cli.rb +5 -5
- data/examples/config_file_example/README.md +256 -0
- data/examples/config_file_example/config/htm.local.yml +34 -0
- data/examples/config_file_example/custom_config.yml +22 -0
- data/examples/config_file_example/show_config.rb +125 -0
- data/examples/custom_llm_configuration.rb +7 -7
- data/examples/example_app/Rakefile +2 -2
- data/examples/example_app/app.rb +8 -8
- data/examples/file_loader_usage.rb +9 -9
- data/examples/mcp_client.rb +5 -5
- data/examples/rails_app/Gemfile.lock +48 -56
- data/examples/rails_app/README.md +1 -1
- data/examples/robot_groups/multi_process.rb +5 -5
- data/examples/robot_groups/robot_worker.rb +5 -5
- data/examples/robot_groups/same_process.rb +9 -9
- data/examples/sinatra_app/app.rb +1 -1
- data/examples/timeframe_demo.rb +1 -1
- data/lib/htm/active_record_config.rb +12 -25
- data/lib/htm/circuit_breaker.rb +0 -2
- data/lib/htm/config/defaults.yml +246 -0
- data/lib/htm/config.rb +888 -0
- data/lib/htm/database.rb +23 -27
- data/lib/htm/embedding_service.rb +0 -4
- data/lib/htm/integrations/sinatra.rb +3 -7
- data/lib/htm/job_adapter.rb +76 -16
- data/lib/htm/jobs/generate_embedding_job.rb +1 -7
- data/lib/htm/jobs/generate_propositions_job.rb +2 -12
- data/lib/htm/jobs/generate_tags_job.rb +1 -8
- data/lib/htm/loaders/defaults_loader.rb +143 -0
- data/lib/htm/loaders/xdg_config_loader.rb +116 -0
- data/lib/htm/mcp/cli.rb +200 -58
- data/lib/htm/mcp/server.rb +3 -3
- data/lib/htm/proposition_service.rb +2 -12
- data/lib/htm/railtie.rb +3 -4
- data/lib/htm/tag_service.rb +1 -8
- data/lib/htm/version.rb +1 -1
- data/lib/htm/workflows/remember_workflow.rb +212 -0
- data/lib/htm.rb +125 -5
- data/mkdocs.yml +33 -8
- metadata +83 -10
- data/config/database.yml +0 -77
- data/docs/api/yard/HTM/Configuration.md +0 -229
- data/docs/telemetry.md +0 -391
- data/lib/htm/configuration.rb +0 -799
|
@@ -1,229 +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`**
|
|
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`**
|
|
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`**
|
|
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`**
|
|
51
|
-
```ruby
|
|
52
|
-
HTM.configure do |config|
|
|
53
|
-
config.embedding_generator = ->(text) {
|
|
54
|
-
MyApp::LLMService.embed(text) # Returns Array<Float>
|
|
55
|
-
}
|
|
56
|
-
config.tag_extractor = ->(text, ontology) {
|
|
57
|
-
MyApp::LLMService.extract_tags(text, ontology) # Returns Array<String>
|
|
58
|
-
}
|
|
59
|
-
config.logger = Rails.logger
|
|
60
|
-
end
|
|
61
|
-
```
|
|
62
|
-
# Attributes
|
|
63
|
-
## anthropic_api_key[RW] {: #attribute-i-anthropic_api_key }
|
|
64
|
-
Returns the value of attribute anthropic_api_key.
|
|
65
|
-
|
|
66
|
-
## azure_api_key[RW] {: #attribute-i-azure_api_key }
|
|
67
|
-
Returns the value of attribute azure_api_key.
|
|
68
|
-
|
|
69
|
-
## azure_api_version[RW] {: #attribute-i-azure_api_version }
|
|
70
|
-
Returns the value of attribute azure_api_version.
|
|
71
|
-
|
|
72
|
-
## azure_endpoint[RW] {: #attribute-i-azure_endpoint }
|
|
73
|
-
Returns the value of attribute azure_endpoint.
|
|
74
|
-
|
|
75
|
-
## bedrock_access_key[RW] {: #attribute-i-bedrock_access_key }
|
|
76
|
-
Returns the value of attribute bedrock_access_key.
|
|
77
|
-
|
|
78
|
-
## bedrock_region[RW] {: #attribute-i-bedrock_region }
|
|
79
|
-
Returns the value of attribute bedrock_region.
|
|
80
|
-
|
|
81
|
-
## bedrock_secret_key[RW] {: #attribute-i-bedrock_secret_key }
|
|
82
|
-
Returns the value of attribute bedrock_secret_key.
|
|
83
|
-
|
|
84
|
-
## chunk_overlap[RW] {: #attribute-i-chunk_overlap }
|
|
85
|
-
Character overlap between chunks (default: 64)
|
|
86
|
-
|
|
87
|
-
## chunk_size[RW] {: #attribute-i-chunk_size }
|
|
88
|
-
Chunking configuration (for file loading)
|
|
89
|
-
|
|
90
|
-
## circuit_breaker_failure_threshold[RW] {: #attribute-i-circuit_breaker_failure_threshold }
|
|
91
|
-
Circuit breaker configuration
|
|
92
|
-
|
|
93
|
-
## circuit_breaker_half_open_max_calls[RW] {: #attribute-i-circuit_breaker_half_open_max_calls }
|
|
94
|
-
Successes to close (default: 3)
|
|
95
|
-
|
|
96
|
-
## circuit_breaker_reset_timeout[RW] {: #attribute-i-circuit_breaker_reset_timeout }
|
|
97
|
-
Seconds before half-open (default: 60)
|
|
98
|
-
|
|
99
|
-
## connection_timeout[RW] {: #attribute-i-connection_timeout }
|
|
100
|
-
Returns the value of attribute connection_timeout.
|
|
101
|
-
|
|
102
|
-
## deepseek_api_key[RW] {: #attribute-i-deepseek_api_key }
|
|
103
|
-
Returns the value of attribute deepseek_api_key.
|
|
104
|
-
|
|
105
|
-
## embedding_dimensions[RW] {: #attribute-i-embedding_dimensions }
|
|
106
|
-
Returns the value of attribute embedding_dimensions.
|
|
107
|
-
|
|
108
|
-
## embedding_generator[RW] {: #attribute-i-embedding_generator }
|
|
109
|
-
Returns the value of attribute embedding_generator.
|
|
110
|
-
|
|
111
|
-
## embedding_model[RW] {: #attribute-i-embedding_model }
|
|
112
|
-
Returns the value of attribute embedding_model.
|
|
113
|
-
|
|
114
|
-
## embedding_provider[RW] {: #attribute-i-embedding_provider }
|
|
115
|
-
Returns the value of attribute embedding_provider.
|
|
116
|
-
|
|
117
|
-
## embedding_timeout[RW] {: #attribute-i-embedding_timeout }
|
|
118
|
-
Returns the value of attribute embedding_timeout.
|
|
119
|
-
|
|
120
|
-
## extract_propositions[RW] {: #attribute-i-extract_propositions }
|
|
121
|
-
Returns the value of attribute extract_propositions.
|
|
122
|
-
|
|
123
|
-
## gemini_api_key[RW] {: #attribute-i-gemini_api_key }
|
|
124
|
-
Returns the value of attribute gemini_api_key.
|
|
125
|
-
|
|
126
|
-
## huggingface_api_key[RW] {: #attribute-i-huggingface_api_key }
|
|
127
|
-
Returns the value of attribute huggingface_api_key.
|
|
128
|
-
|
|
129
|
-
## job_backend[RW] {: #attribute-i-job_backend }
|
|
130
|
-
Returns the value of attribute job_backend.
|
|
131
|
-
|
|
132
|
-
## logger[RW] {: #attribute-i-logger }
|
|
133
|
-
Returns the value of attribute logger.
|
|
134
|
-
|
|
135
|
-
## max_embedding_dimension[RW] {: #attribute-i-max_embedding_dimension }
|
|
136
|
-
Limit configuration
|
|
137
|
-
|
|
138
|
-
## max_tag_depth[RW] {: #attribute-i-max_tag_depth }
|
|
139
|
-
Max tag hierarchy depth (default: 4)
|
|
140
|
-
|
|
141
|
-
## ollama_url[RW] {: #attribute-i-ollama_url }
|
|
142
|
-
Returns the value of attribute ollama_url.
|
|
143
|
-
|
|
144
|
-
## openai_api_key[RW] {: #attribute-i-openai_api_key }
|
|
145
|
-
Provider-specific API keys and endpoints
|
|
146
|
-
|
|
147
|
-
## openai_organization[RW] {: #attribute-i-openai_organization }
|
|
148
|
-
Provider-specific API keys and endpoints
|
|
149
|
-
|
|
150
|
-
## openai_project[RW] {: #attribute-i-openai_project }
|
|
151
|
-
Provider-specific API keys and endpoints
|
|
152
|
-
|
|
153
|
-
## openrouter_api_key[RW] {: #attribute-i-openrouter_api_key }
|
|
154
|
-
Returns the value of attribute openrouter_api_key.
|
|
155
|
-
|
|
156
|
-
## proposition_extractor[RW] {: #attribute-i-proposition_extractor }
|
|
157
|
-
Returns the value of attribute proposition_extractor.
|
|
158
|
-
|
|
159
|
-
## proposition_model[RW] {: #attribute-i-proposition_model }
|
|
160
|
-
Returns the value of attribute proposition_model.
|
|
161
|
-
|
|
162
|
-
## proposition_provider[RW] {: #attribute-i-proposition_provider }
|
|
163
|
-
Returns the value of attribute proposition_provider.
|
|
164
|
-
|
|
165
|
-
## proposition_timeout[RW] {: #attribute-i-proposition_timeout }
|
|
166
|
-
Returns the value of attribute proposition_timeout.
|
|
167
|
-
|
|
168
|
-
## relevance_access_weight[RW] {: #attribute-i-relevance_access_weight }
|
|
169
|
-
Access frequency weight (default: 0.1)
|
|
170
|
-
|
|
171
|
-
## relevance_recency_half_life_hours[RW] {: #attribute-i-relevance_recency_half_life_hours }
|
|
172
|
-
Decay half-life in hours (default: 168 = 1 week)
|
|
173
|
-
|
|
174
|
-
## relevance_recency_weight[RW] {: #attribute-i-relevance_recency_weight }
|
|
175
|
-
Temporal freshness weight (default: 0.1)
|
|
176
|
-
|
|
177
|
-
## relevance_semantic_weight[RW] {: #attribute-i-relevance_semantic_weight }
|
|
178
|
-
Relevance scoring weights (must sum to 1.0)
|
|
179
|
-
|
|
180
|
-
## relevance_tag_weight[RW] {: #attribute-i-relevance_tag_weight }
|
|
181
|
-
Tag overlap weight (default: 0.3)
|
|
182
|
-
|
|
183
|
-
## tag_extractor[RW] {: #attribute-i-tag_extractor }
|
|
184
|
-
Returns the value of attribute tag_extractor.
|
|
185
|
-
|
|
186
|
-
## tag_model[RW] {: #attribute-i-tag_model }
|
|
187
|
-
Returns the value of attribute tag_model.
|
|
188
|
-
|
|
189
|
-
## tag_provider[RW] {: #attribute-i-tag_provider }
|
|
190
|
-
Returns the value of attribute tag_provider.
|
|
191
|
-
|
|
192
|
-
## tag_timeout[RW] {: #attribute-i-tag_timeout }
|
|
193
|
-
Returns the value of attribute tag_timeout.
|
|
194
|
-
|
|
195
|
-
## telemetry_enabled[RW] {: #attribute-i-telemetry_enabled }
|
|
196
|
-
Enable OpenTelemetry metrics (default: false)
|
|
197
|
-
|
|
198
|
-
## token_counter[RW] {: #attribute-i-token_counter }
|
|
199
|
-
Returns the value of attribute token_counter.
|
|
200
|
-
|
|
201
|
-
## week_start[RW] {: #attribute-i-week_start }
|
|
202
|
-
Returns the value of attribute week_start.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
# Instance Methods
|
|
206
|
-
## configure_ruby_llm(providernil) {: #method-i-configure_ruby_llm }
|
|
207
|
-
Configure RubyLLM with the appropriate provider credentials
|
|
208
|
-
|
|
209
|
-
**`@param`** [Symbol] The provider to configure (:openai, :anthropic, etc.)
|
|
210
|
-
|
|
211
|
-
## initialize() {: #method-i-initialize }
|
|
212
|
-
**`@return`** [Configuration] a new instance of Configuration
|
|
213
|
-
|
|
214
|
-
## normalize_ollama_model(model_name) {: #method-i-normalize_ollama_model }
|
|
215
|
-
Normalize Ollama model name to include tag if missing
|
|
216
|
-
|
|
217
|
-
Ollama models require a tag (e.g., :latest, :7b, :13b). If the user specifies
|
|
218
|
-
a model without a tag, we append :latest by default.
|
|
219
|
-
|
|
220
|
-
**`@param`** [String] Original model name
|
|
221
|
-
|
|
222
|
-
**`@return`** [String] Normalized model name with tag
|
|
223
|
-
|
|
224
|
-
## reset_to_defaults() {: #method-i-reset_to_defaults }
|
|
225
|
-
Reset to default RubyLLM-based implementations
|
|
226
|
-
|
|
227
|
-
## validate!() {: #method-i-validate! }
|
|
228
|
-
Validate configuration
|
|
229
|
-
|
data/docs/telemetry.md
DELETED
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
# Telemetry (OpenTelemetry Metrics)
|
|
2
|
-
|
|
3
|
-
HTM includes optional OpenTelemetry-based metrics for production observability. This document provides detailed configuration and usage information.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
HTM uses [OpenTelemetry](https://opentelemetry.io/) for metrics collection, the industry-standard observability framework. This provides:
|
|
8
|
-
|
|
9
|
-
- **Universal compatibility**: Works with 50+ observability backends
|
|
10
|
-
- **Zero vendor lock-in**: Emit standard OTLP, route anywhere
|
|
11
|
-
- **Zero overhead when disabled**: Null object pattern ensures no performance impact
|
|
12
|
-
|
|
13
|
-
## Quick Start
|
|
14
|
-
|
|
15
|
-
### 1. Install Dependencies
|
|
16
|
-
|
|
17
|
-
Add the OpenTelemetry gems to your Gemfile:
|
|
18
|
-
|
|
19
|
-
```ruby
|
|
20
|
-
gem 'opentelemetry-sdk'
|
|
21
|
-
gem 'opentelemetry-metrics-sdk'
|
|
22
|
-
gem 'opentelemetry-exporter-otlp' # For OTLP export
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### 2. Enable Telemetry
|
|
26
|
-
|
|
27
|
-
```ruby
|
|
28
|
-
HTM.configure do |config|
|
|
29
|
-
config.telemetry_enabled = true
|
|
30
|
-
end
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Or via environment variable:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
export HTM_TELEMETRY_ENABLED="true"
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### 3. Configure Destination
|
|
40
|
-
|
|
41
|
-
Set standard OpenTelemetry environment variables:
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
export OTEL_METRICS_EXPORTER="otlp"
|
|
45
|
-
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Configuration Options
|
|
49
|
-
|
|
50
|
-
### HTM Configuration
|
|
51
|
-
|
|
52
|
-
| Option | Type | Default | Description |
|
|
53
|
-
|--------|------|---------|-------------|
|
|
54
|
-
| `telemetry_enabled` | Boolean | `false` | Enable/disable telemetry |
|
|
55
|
-
|
|
56
|
-
```ruby
|
|
57
|
-
HTM.configure do |config|
|
|
58
|
-
config.telemetry_enabled = true
|
|
59
|
-
end
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Environment Variables
|
|
63
|
-
|
|
64
|
-
#### HTM-specific
|
|
65
|
-
|
|
66
|
-
| Variable | Default | Description |
|
|
67
|
-
|----------|---------|-------------|
|
|
68
|
-
| `HTM_TELEMETRY_ENABLED` | `false` | Enable telemetry (`true`/`false`) |
|
|
69
|
-
|
|
70
|
-
#### OpenTelemetry Standard
|
|
71
|
-
|
|
72
|
-
These are standard OpenTelemetry environment variables (not HTM-specific):
|
|
73
|
-
|
|
74
|
-
| Variable | Example | Description |
|
|
75
|
-
|----------|---------|-------------|
|
|
76
|
-
| `OTEL_SERVICE_NAME` | `htm` | Service name in telemetry data |
|
|
77
|
-
| `OTEL_METRICS_EXPORTER` | `otlp` | Metrics exporter type |
|
|
78
|
-
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4318` | OTLP collector endpoint |
|
|
79
|
-
| `OTEL_EXPORTER_OTLP_HEADERS` | `Authorization=Bearer token` | Headers for OTLP requests |
|
|
80
|
-
|
|
81
|
-
## Available Metrics
|
|
82
|
-
|
|
83
|
-
### htm.jobs (Counter)
|
|
84
|
-
|
|
85
|
-
Counts job executions by type and outcome.
|
|
86
|
-
|
|
87
|
-
**Attributes:**
|
|
88
|
-
- `job`: Job type (`embedding`, `tags`)
|
|
89
|
-
- `status`: Outcome (`success`, `error`, `circuit_open`)
|
|
90
|
-
|
|
91
|
-
**Example queries (PromQL):**
|
|
92
|
-
```promql
|
|
93
|
-
# Jobs per minute by type
|
|
94
|
-
rate(htm_jobs_total[1m])
|
|
95
|
-
|
|
96
|
-
# Error rate for embedding jobs
|
|
97
|
-
rate(htm_jobs_total{job="embedding",status="error"}[5m])
|
|
98
|
-
/ rate(htm_jobs_total{job="embedding"}[5m])
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### htm.embedding.latency (Histogram)
|
|
102
|
-
|
|
103
|
-
Measures embedding generation time in milliseconds.
|
|
104
|
-
|
|
105
|
-
**Attributes:**
|
|
106
|
-
- `provider`: LLM provider (`ollama`, `openai`, etc.)
|
|
107
|
-
- `status`: Outcome (`success`, `error`)
|
|
108
|
-
|
|
109
|
-
**Example queries (PromQL):**
|
|
110
|
-
```promql
|
|
111
|
-
# p95 embedding latency
|
|
112
|
-
histogram_quantile(0.95, rate(htm_embedding_latency_bucket[5m]))
|
|
113
|
-
|
|
114
|
-
# Average latency by provider
|
|
115
|
-
rate(htm_embedding_latency_sum[5m]) / rate(htm_embedding_latency_count[5m])
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### htm.tag.latency (Histogram)
|
|
119
|
-
|
|
120
|
-
Measures tag extraction time in milliseconds.
|
|
121
|
-
|
|
122
|
-
**Attributes:**
|
|
123
|
-
- `provider`: LLM provider (`ollama`, `openai`, etc.)
|
|
124
|
-
- `status`: Outcome (`success`, `error`)
|
|
125
|
-
|
|
126
|
-
**Example queries (PromQL):**
|
|
127
|
-
```promql
|
|
128
|
-
# p99 tag extraction latency
|
|
129
|
-
histogram_quantile(0.99, rate(htm_tag_latency_bucket[5m]))
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### htm.search.latency (Histogram)
|
|
133
|
-
|
|
134
|
-
Measures search operation time in milliseconds.
|
|
135
|
-
|
|
136
|
-
**Attributes:**
|
|
137
|
-
- `strategy`: Search strategy (`vector`, `fulltext`, `hybrid`)
|
|
138
|
-
|
|
139
|
-
**Example queries (PromQL):**
|
|
140
|
-
```promql
|
|
141
|
-
# Search latency by strategy
|
|
142
|
-
histogram_quantile(0.95, rate(htm_search_latency_bucket[5m])) by (strategy)
|
|
143
|
-
|
|
144
|
-
# Hybrid search avg latency
|
|
145
|
-
rate(htm_search_latency_sum{strategy="hybrid"}[5m])
|
|
146
|
-
/ rate(htm_search_latency_count{strategy="hybrid"}[5m])
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
### htm.cache.operations (Counter)
|
|
150
|
-
|
|
151
|
-
Counts cache hits and misses.
|
|
152
|
-
|
|
153
|
-
**Attributes:**
|
|
154
|
-
- `operation`: Operation type (`hit`, `miss`)
|
|
155
|
-
|
|
156
|
-
**Example queries (PromQL):**
|
|
157
|
-
```promql
|
|
158
|
-
# Cache hit rate
|
|
159
|
-
rate(htm_cache_operations_total{operation="hit"}[5m])
|
|
160
|
-
/ (rate(htm_cache_operations_total{operation="hit"}[5m])
|
|
161
|
-
+ rate(htm_cache_operations_total{operation="miss"}[5m]))
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## Compatible Backends
|
|
165
|
-
|
|
166
|
-
HTM metrics work with any OTLP-compatible platform:
|
|
167
|
-
|
|
168
|
-
### Open Source / Self-Hosted
|
|
169
|
-
|
|
170
|
-
| Platform | OTLP Support | Notes |
|
|
171
|
-
|----------|--------------|-------|
|
|
172
|
-
| **Jaeger** | Native (v1.35+) | Distributed tracing with metrics |
|
|
173
|
-
| **Prometheus** | Via receiver | Popular metrics platform |
|
|
174
|
-
| **Grafana Tempo** | Native | Traces with metrics correlation |
|
|
175
|
-
| **Grafana Mimir** | Native | Scalable Prometheus-compatible |
|
|
176
|
-
| **SigNoz** | Native | Full-stack observability |
|
|
177
|
-
| **Uptrace** | Native | Open source APM |
|
|
178
|
-
|
|
179
|
-
### Commercial / SaaS
|
|
180
|
-
|
|
181
|
-
| Platform | OTLP Support | Notes |
|
|
182
|
-
|----------|--------------|-------|
|
|
183
|
-
| **Datadog** | Native | Full-stack observability |
|
|
184
|
-
| **New Relic** | Native | APM and infrastructure |
|
|
185
|
-
| **Honeycomb** | Native (preferred) | High-cardinality observability |
|
|
186
|
-
| **Splunk APM** | Native | Enterprise observability |
|
|
187
|
-
| **Dynatrace** | Native | AI-powered monitoring |
|
|
188
|
-
| **AWS X-Ray** | Via ADOT | AWS native tracing |
|
|
189
|
-
| **Google Cloud Trace** | Native | GCP native tracing |
|
|
190
|
-
| **Azure Monitor** | Native | Azure native monitoring |
|
|
191
|
-
| **Grafana Cloud** | Native | Managed Grafana stack |
|
|
192
|
-
|
|
193
|
-
## Setup Examples
|
|
194
|
-
|
|
195
|
-
### Jaeger (Local Development)
|
|
196
|
-
|
|
197
|
-
```bash
|
|
198
|
-
# Start Jaeger with OTLP support
|
|
199
|
-
docker run -d --name jaeger \
|
|
200
|
-
-p 4318:4318 \
|
|
201
|
-
-p 16686:16686 \
|
|
202
|
-
jaegertracing/all-in-one:latest
|
|
203
|
-
|
|
204
|
-
# Configure HTM
|
|
205
|
-
export HTM_TELEMETRY_ENABLED="true"
|
|
206
|
-
export OTEL_METRICS_EXPORTER="otlp"
|
|
207
|
-
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Prometheus (via OpenTelemetry Collector)
|
|
211
|
-
|
|
212
|
-
```yaml
|
|
213
|
-
# otel-collector-config.yaml
|
|
214
|
-
receivers:
|
|
215
|
-
otlp:
|
|
216
|
-
protocols:
|
|
217
|
-
grpc:
|
|
218
|
-
http:
|
|
219
|
-
|
|
220
|
-
exporters:
|
|
221
|
-
prometheus:
|
|
222
|
-
endpoint: "0.0.0.0:8889"
|
|
223
|
-
|
|
224
|
-
service:
|
|
225
|
-
pipelines:
|
|
226
|
-
metrics:
|
|
227
|
-
receivers: [otlp]
|
|
228
|
-
exporters: [prometheus]
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
```bash
|
|
232
|
-
docker run -d \
|
|
233
|
-
-p 4317:4317 \
|
|
234
|
-
-p 4318:4318 \
|
|
235
|
-
-p 8889:8889 \
|
|
236
|
-
-v $(pwd)/otel-collector-config.yaml:/etc/otel-collector-config.yaml \
|
|
237
|
-
otel/opentelemetry-collector:latest \
|
|
238
|
-
--config=/etc/otel-collector-config.yaml
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### Datadog
|
|
242
|
-
|
|
243
|
-
```bash
|
|
244
|
-
export HTM_TELEMETRY_ENABLED="true"
|
|
245
|
-
export OTEL_METRICS_EXPORTER="otlp"
|
|
246
|
-
export OTEL_EXPORTER_OTLP_ENDPOINT="https://otlp.datadoghq.com"
|
|
247
|
-
export OTEL_EXPORTER_OTLP_HEADERS="DD-API-KEY=your-api-key"
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Honeycomb
|
|
251
|
-
|
|
252
|
-
```bash
|
|
253
|
-
export HTM_TELEMETRY_ENABLED="true"
|
|
254
|
-
export OTEL_METRICS_EXPORTER="otlp"
|
|
255
|
-
export OTEL_EXPORTER_OTLP_ENDPOINT="https://api.honeycomb.io"
|
|
256
|
-
export OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=your-api-key"
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### New Relic
|
|
260
|
-
|
|
261
|
-
```bash
|
|
262
|
-
export HTM_TELEMETRY_ENABLED="true"
|
|
263
|
-
export OTEL_METRICS_EXPORTER="otlp"
|
|
264
|
-
export OTEL_EXPORTER_OTLP_ENDPOINT="https://otlp.nr-data.net"
|
|
265
|
-
export OTEL_EXPORTER_OTLP_HEADERS="api-key=your-license-key"
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
## Architecture
|
|
269
|
-
|
|
270
|
-
### Null Object Pattern
|
|
271
|
-
|
|
272
|
-
HTM uses a null object pattern for telemetry. When disabled:
|
|
273
|
-
|
|
274
|
-
```ruby
|
|
275
|
-
# This code runs identically whether telemetry is enabled or not
|
|
276
|
-
HTM::Telemetry.job_counter.add(1, attributes: { 'job' => 'embedding' })
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
When telemetry is disabled or the SDK is not installed:
|
|
280
|
-
- `HTM::Telemetry.meter` returns a `NullMeter`
|
|
281
|
-
- All instruments return `NullInstrument` instances
|
|
282
|
-
- All operations (`add`, `record`) are no-ops returning `nil`
|
|
283
|
-
- Zero memory allocation, zero CPU overhead
|
|
284
|
-
|
|
285
|
-
### Code Flow
|
|
286
|
-
|
|
287
|
-

|
|
288
|
-
|
|
289
|
-
### Instrumentation Points
|
|
290
|
-
|
|
291
|
-
HTM instruments these key operations:
|
|
292
|
-
|
|
293
|
-
| Component | Metrics Recorded |
|
|
294
|
-
|-----------|-----------------|
|
|
295
|
-
| `GenerateEmbeddingJob` | `htm.jobs`, `htm.embedding.latency` |
|
|
296
|
-
| `GenerateTagsJob` | `htm.jobs`, `htm.tag.latency` |
|
|
297
|
-
| `VectorSearch#search` | `htm.search.latency` (strategy: vector) |
|
|
298
|
-
| `FulltextSearch#search_fulltext` | `htm.search.latency` (strategy: fulltext) |
|
|
299
|
-
| `HybridSearch#search_hybrid` | `htm.search.latency` (strategy: hybrid) |
|
|
300
|
-
| `QueryCache#fetch` | `htm.cache.operations` |
|
|
301
|
-
|
|
302
|
-
## Testing
|
|
303
|
-
|
|
304
|
-
When writing tests, reset telemetry state between tests:
|
|
305
|
-
|
|
306
|
-
```ruby
|
|
307
|
-
def setup
|
|
308
|
-
HTM::Telemetry.reset!
|
|
309
|
-
HTM.configuration.telemetry_enabled = false
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
def teardown
|
|
313
|
-
HTM::Telemetry.reset!
|
|
314
|
-
end
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
### Verifying Metrics in Tests
|
|
318
|
-
|
|
319
|
-
```ruby
|
|
320
|
-
def test_records_embedding_latency
|
|
321
|
-
# Create a mock histogram
|
|
322
|
-
recorded = []
|
|
323
|
-
mock_histogram = Object.new
|
|
324
|
-
mock_histogram.define_singleton_method(:record) do |value, **kwargs|
|
|
325
|
-
recorded << { value: value, attributes: kwargs[:attributes] }
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
# Inject mock (requires test helper)
|
|
329
|
-
HTM::Telemetry.instance_variable_set(:@embedding_latency, mock_histogram)
|
|
330
|
-
|
|
331
|
-
# Run operation
|
|
332
|
-
HTM::Jobs::GenerateEmbeddingJob.perform(node_id: node.id)
|
|
333
|
-
|
|
334
|
-
# Verify
|
|
335
|
-
assert recorded.any? { |r| r[:attributes]['status'] == 'success' }
|
|
336
|
-
end
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
## Troubleshooting
|
|
340
|
-
|
|
341
|
-
### Metrics Not Appearing
|
|
342
|
-
|
|
343
|
-
1. **Check telemetry is enabled:**
|
|
344
|
-
```ruby
|
|
345
|
-
puts HTM.configuration.telemetry_enabled # Should be true
|
|
346
|
-
puts HTM::Telemetry.enabled? # Should be true
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
2. **Check SDK is installed:**
|
|
350
|
-
```ruby
|
|
351
|
-
puts HTM::Telemetry.sdk_available? # Should be true
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
3. **Check environment variables:**
|
|
355
|
-
```bash
|
|
356
|
-
echo $OTEL_METRICS_EXPORTER
|
|
357
|
-
echo $OTEL_EXPORTER_OTLP_ENDPOINT
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
4. **Check collector is running:**
|
|
361
|
-
```bash
|
|
362
|
-
curl http://localhost:4318/v1/metrics # Should not 404
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
### High Cardinality Issues
|
|
366
|
-
|
|
367
|
-
Avoid high-cardinality attributes in metrics. HTM uses low-cardinality attributes by design:
|
|
368
|
-
|
|
369
|
-
- `job`: 2-3 values (embedding, tags, propositions)
|
|
370
|
-
- `status`: 3 values (success, error, circuit_open)
|
|
371
|
-
- `provider`: ~10 values (ollama, openai, etc.)
|
|
372
|
-
- `strategy`: 3 values (vector, fulltext, hybrid)
|
|
373
|
-
- `operation`: 2 values (hit, miss)
|
|
374
|
-
|
|
375
|
-
### Performance Concerns
|
|
376
|
-
|
|
377
|
-
With telemetry disabled (default), there is zero overhead:
|
|
378
|
-
- No gem loading
|
|
379
|
-
- No object allocation
|
|
380
|
-
- No method calls beyond the null check
|
|
381
|
-
|
|
382
|
-
With telemetry enabled, overhead is minimal:
|
|
383
|
-
- ~1-5μs per metric recording
|
|
384
|
-
- Memory for histogram buckets (~1KB per histogram)
|
|
385
|
-
|
|
386
|
-
## References
|
|
387
|
-
|
|
388
|
-
- [OpenTelemetry Ruby SDK](https://github.com/open-telemetry/opentelemetry-ruby)
|
|
389
|
-
- [OpenTelemetry Metrics SDK](https://github.com/open-telemetry/opentelemetry-ruby/tree/main/metrics_sdk)
|
|
390
|
-
- [OpenTelemetry Specification](https://opentelemetry.io/docs/specs/otel/)
|
|
391
|
-
- [OTLP Protocol](https://opentelemetry.io/docs/specs/otlp/)
|