htm 0.0.11 → 0.0.15

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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/.dictate.toml +46 -0
  3. data/.envrc +2 -0
  4. data/CHANGELOG.md +85 -2
  5. data/README.md +348 -79
  6. data/Rakefile +14 -2
  7. data/bin/htm_mcp.rb +94 -0
  8. data/config/database.yml +20 -13
  9. data/db/migrate/00003_create_file_sources.rb +5 -0
  10. data/db/migrate/00004_create_nodes.rb +17 -0
  11. data/db/migrate/00005_create_tags.rb +7 -0
  12. data/db/migrate/00006_create_node_tags.rb +2 -0
  13. data/db/migrate/00007_create_robot_nodes.rb +7 -0
  14. data/db/schema.sql +69 -100
  15. data/docs/api/index.md +1 -1
  16. data/docs/api/yard/HTM/Configuration.md +54 -0
  17. data/docs/api/yard/HTM/Database.md +13 -10
  18. data/docs/api/yard/HTM/EmbeddingService.md +5 -1
  19. data/docs/api/yard/HTM/LongTermMemory.md +18 -277
  20. data/docs/api/yard/HTM/PropositionError.md +18 -0
  21. data/docs/api/yard/HTM/PropositionService.md +66 -0
  22. data/docs/api/yard/HTM/QueryCache.md +88 -0
  23. data/docs/api/yard/HTM/RobotGroup.md +481 -0
  24. data/docs/api/yard/HTM/SqlBuilder.md +108 -0
  25. data/docs/api/yard/HTM/TagService.md +4 -0
  26. data/docs/api/yard/HTM/Telemetry/NullInstrument.md +13 -0
  27. data/docs/api/yard/HTM/Telemetry/NullMeter.md +15 -0
  28. data/docs/api/yard/HTM/Telemetry.md +109 -0
  29. data/docs/api/yard/HTM/WorkingMemoryChannel.md +176 -0
  30. data/docs/api/yard/HTM.md +8 -22
  31. data/docs/api/yard/index.csv +102 -25
  32. data/docs/api/yard-reference.md +8 -0
  33. data/docs/architecture/index.md +1 -1
  34. data/docs/assets/images/multi-provider-failover.svg +51 -0
  35. data/docs/assets/images/robot-group-architecture.svg +65 -0
  36. data/docs/database/README.md +3 -3
  37. data/docs/database/public.file_sources.svg +29 -21
  38. data/docs/database/public.node_tags.md +2 -0
  39. data/docs/database/public.node_tags.svg +53 -41
  40. data/docs/database/public.nodes.md +2 -0
  41. data/docs/database/public.nodes.svg +52 -40
  42. data/docs/database/public.robot_nodes.md +2 -0
  43. data/docs/database/public.robot_nodes.svg +30 -22
  44. data/docs/database/public.robots.svg +16 -12
  45. data/docs/database/public.tags.md +3 -0
  46. data/docs/database/public.tags.svg +41 -33
  47. data/docs/database/schema.json +66 -0
  48. data/docs/database/schema.svg +60 -48
  49. data/docs/development/index.md +14 -1
  50. data/docs/development/rake-tasks.md +1068 -0
  51. data/docs/getting-started/index.md +1 -1
  52. data/docs/getting-started/quick-start.md +144 -155
  53. data/docs/guides/adding-memories.md +2 -3
  54. data/docs/guides/context-assembly.md +185 -184
  55. data/docs/guides/getting-started.md +154 -148
  56. data/docs/guides/index.md +8 -1
  57. data/docs/guides/long-term-memory.md +60 -92
  58. data/docs/guides/mcp-server.md +617 -0
  59. data/docs/guides/multi-robot.md +249 -345
  60. data/docs/guides/recalling-memories.md +153 -163
  61. data/docs/guides/robot-groups.md +604 -0
  62. data/docs/guides/search-strategies.md +61 -58
  63. data/docs/guides/working-memory.md +103 -136
  64. data/docs/images/telemetry-architecture.svg +153 -0
  65. data/docs/index.md +30 -26
  66. data/docs/telemetry.md +391 -0
  67. data/examples/README.md +46 -1
  68. data/examples/cli_app/README.md +1 -1
  69. data/examples/cli_app/htm_cli.rb +1 -1
  70. data/examples/robot_groups/robot_worker.rb +1 -2
  71. data/examples/robot_groups/same_process.rb +1 -4
  72. data/examples/sinatra_app/app.rb +1 -1
  73. data/examples/telemetry/README.md +147 -0
  74. data/examples/telemetry/SETUP_README.md +169 -0
  75. data/examples/telemetry/demo.rb +498 -0
  76. data/examples/telemetry/grafana/dashboards/htm-metrics.json +457 -0
  77. data/lib/htm/configuration.rb +261 -70
  78. data/lib/htm/database.rb +46 -22
  79. data/lib/htm/embedding_service.rb +24 -14
  80. data/lib/htm/errors.rb +15 -1
  81. data/lib/htm/jobs/generate_embedding_job.rb +19 -0
  82. data/lib/htm/jobs/generate_propositions_job.rb +103 -0
  83. data/lib/htm/jobs/generate_tags_job.rb +24 -0
  84. data/lib/htm/loaders/markdown_chunker.rb +79 -0
  85. data/lib/htm/loaders/markdown_loader.rb +41 -15
  86. data/lib/htm/long_term_memory/fulltext_search.rb +138 -0
  87. data/lib/htm/long_term_memory/hybrid_search.rb +324 -0
  88. data/lib/htm/long_term_memory/node_operations.rb +209 -0
  89. data/lib/htm/long_term_memory/relevance_scorer.rb +355 -0
  90. data/lib/htm/long_term_memory/robot_operations.rb +34 -0
  91. data/lib/htm/long_term_memory/tag_operations.rb +428 -0
  92. data/lib/htm/long_term_memory/vector_search.rb +109 -0
  93. data/lib/htm/long_term_memory.rb +51 -1153
  94. data/lib/htm/models/node.rb +35 -2
  95. data/lib/htm/models/node_tag.rb +31 -0
  96. data/lib/htm/models/robot_node.rb +31 -0
  97. data/lib/htm/models/tag.rb +44 -0
  98. data/lib/htm/proposition_service.rb +169 -0
  99. data/lib/htm/query_cache.rb +214 -0
  100. data/lib/htm/robot_group.rb +721 -0
  101. data/lib/htm/sql_builder.rb +178 -0
  102. data/lib/htm/tag_service.rb +16 -6
  103. data/lib/htm/tasks.rb +8 -2
  104. data/lib/htm/telemetry.rb +224 -0
  105. data/lib/htm/version.rb +1 -1
  106. data/lib/htm/working_memory_channel.rb +250 -0
  107. data/lib/htm.rb +66 -3
  108. data/lib/tasks/doc.rake +1 -1
  109. data/lib/tasks/htm.rake +259 -13
  110. data/mkdocs.yml +98 -96
  111. metadata +55 -20
  112. data/.aigcm_msg +0 -1
  113. data/.claude/settings.local.json +0 -95
  114. data/CLAUDE.md +0 -603
  115. data/db/migrate/00009_add_working_memory_to_robot_nodes.rb +0 -12
  116. data/examples/cli_app/temp.log +0 -93
  117. data/examples/robot_groups/lib/robot_group.rb +0 -419
  118. data/examples/robot_groups/lib/working_memory_channel.rb +0 -140
  119. data/lib/htm/loaders/paragraph_chunker.rb +0 -112
  120. data/notes/ARCHITECTURE_REVIEW.md +0 -1167
  121. data/notes/IMPLEMENTATION_SUMMARY.md +0 -606
  122. data/notes/MULTI_FRAMEWORK_IMPLEMENTATION.md +0 -451
  123. data/notes/next_steps.md +0 -100
  124. data/notes/plan.md +0 -627
  125. data/notes/tag_ontology_enhancement_ideas.md +0 -222
  126. data/notes/timescaledb_removal_summary.md +0 -200
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6e41109b86fd5c51c8f96cec8a11ea9455035da54d72ae461b3b2f0a7ab7a8d
4
- data.tar.gz: 1fe15917933aefa827a12c6e92406711ab95449097cb78bdab4c0f6510f595c1
3
+ metadata.gz: 9ae4db5f168c495f5afef19f740f16ee9b39136cd54403f54090921cb6952275
4
+ data.tar.gz: 454816f53e620a72efeae7bd8b6c0a30c459403b4f1b6a3d0ca7adf30f3cda7c
5
5
  SHA512:
6
- metadata.gz: c02e326797a6986e1a5b987bec948f09c0ffc7cb45045898e3fc6faf5c57c9bf3ca4d399324e88528f994c7e3e1989bb71f462aae8adbb270b7c99654aa135d3
7
- data.tar.gz: 4ee90ea84f36ab2d85c72cae4f5a1382e9a174d354f2d976d73b8915cb5dc8df68f6ae799ec082076293ce9b386500b94b4fe12d291903c0804351f5fd027151
6
+ metadata.gz: 52adbf798f4004961936f9112878d245c6872bf812611efa47bc9b7808ba39510d79d0902f109db8169e1cd0d5420338094edd7719f995f67c1b3def07a2a4d2
7
+ data.tar.gz: 7ac9e6a8913b9b836ddfdfdb909857ac62bdd2c5d6c6c904c2a257224fc80499a118afd3d63a3a14d0daed838e11c02b2f2149eddb8c0385ebb2d5be9ab258f8
data/.dictate.toml ADDED
@@ -0,0 +1,46 @@
1
+ # Dictator Configuration for HTM
2
+ # Decree-based structural enforcement
3
+ # https://github.com/seuros/dictator
4
+
5
+ [decree.supreme]
6
+ # Universal structural rules (applies to ALL files)
7
+ trailing_whitespace = "deny"
8
+ tabs_vs_spaces = "spaces"
9
+ tab_width = 2
10
+ final_newline = "require"
11
+ line_endings = "lf"
12
+ blank_line_whitespace = "deny"
13
+
14
+ [decree.ruby]
15
+ # Ruby-specific structural enforcement
16
+ max_line_length = 120
17
+ max_lines = 300
18
+ ignore_comments = true
19
+ ignore_blank_lines = true
20
+ method_visibility_order = ["public", "protected", "private"]
21
+ comment_spacing = true
22
+
23
+ [decree.ruby.linter]
24
+ # External linter - Dictator adds: -A --format json
25
+ command = "rubocop"
26
+
27
+ [decree.frontmatter]
28
+ # YAML frontmatter ordering for .md files
29
+ order = ["title", "slug", "pubDate", "description", "tags", "draft"]
30
+ required = ["title"]
31
+
32
+ # Disable unused language decrees
33
+ [decree.typescript]
34
+ enabled = false
35
+
36
+ [decree.golang]
37
+ enabled = false
38
+
39
+ [decree.rust]
40
+ enabled = false
41
+
42
+ [decree.python]
43
+ enabled = false
44
+
45
+ [decree.kjr]
46
+ enabled = false
data/.envrc CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  export RR=`pwd`
4
4
 
5
+ export HTM_EXTRACT_PROPOSITIONS=true
6
+
5
7
  # Database connection - Localhost PostgreSQL
6
8
  export HTM_DBHOST=localhost
7
9
  export HTM_DBPORT=5432
data/CHANGELOG.md CHANGED
@@ -7,6 +7,89 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.0.15] - 2025-12-06
11
+
12
+ ### Added
13
+ - **"Why Robots Instead of Agents?" README section** - Explains terminology choice
14
+ - Opens with Shakespeare quote from Romeo and Juliet
15
+ - Discusses semantic clarity, honest capabilities, avoiding hype cycle
16
+ - Critiques "agent" frameworks that are just prompt wrappers
17
+ - References rich heritage (Čapek's R.U.R., Asimov's Three Laws)
18
+ - Notes cultural personality of robots (R2-D2, Wall-E, Bender)
19
+ - **MCP Server documentation** - Comprehensive guide for AI assistant integration
20
+ - Added MCP Server section to README.md with tools/resources reference
21
+ - Created `docs/guides/mcp-server.md` with detailed configuration for Claude Desktop, Claude Code, and AIA
22
+ - Covers all 11 tools (SetRobot, Remember, Recall, Forget, Restore, ListTags, SearchTags, FindByTopic, Stats, GetRobot, GetWorkingMemory)
23
+ - Covers all 3 resources (statistics, tags/hierarchy, memories/recent)
24
+ - Usage examples, session management, and troubleshooting guide
25
+ - **HTM Rake Tasks Reference** - Complete documentation for all 44 rake tasks
26
+ - Added rake tasks summary table to README.md Development section
27
+ - Created `docs/development/rake-tasks.md` with detailed reference organized by namespace:
28
+ - Database Tasks (`htm:db:*`) - 16 tasks
29
+ - Documentation Tasks (`htm:doc:*`) - 9 tasks
30
+ - File Loading Tasks (`htm:files:*`) - 7 tasks
31
+ - Job Tasks (`htm:jobs:*`) - 7 tasks
32
+ - Tag Tasks (`htm:tags:*`) - 5 tasks
33
+ - Common workflows, environment variables, and troubleshooting
34
+
35
+ ### Fixed
36
+ - **Documentation code examples** - Fixed incorrect API usage in docs/guides/*.md
37
+ - `add_node()` → `remember()`
38
+ - `topic:` named parameter → positional argument in `recall()`
39
+ - `retrieve(key)` → `long_term_memory.retrieve(node_id)`
40
+ - `create_context()` → `working_memory.assemble_context()`
41
+ - Removed invalid parameters: `type:`, `importance:`, `category:`, `related_to:`
42
+
43
+ ## [0.0.14] - 2025-12-05
44
+
45
+ ### Added
46
+ - **OpenTelemetry metrics** - Optional observability with zero overhead when disabled
47
+ - New `HTM::Telemetry` module with null object pattern
48
+ - Metrics: `htm.jobs` (counter), `htm.embedding.latency`, `htm.tag.latency`, `htm.search.latency` (histograms), `htm.cache.operations` (counter)
49
+ - Instrumented: `GenerateEmbeddingJob`, `GenerateTagsJob`, search methods, `QueryCache`
50
+ - Enable via `HTM_TELEMETRY_ENABLED=true` or `config.telemetry_enabled = true`
51
+ - Works with 50+ OTLP-compatible backends (Jaeger, Prometheus, Datadog, etc.)
52
+ - Comprehensive documentation in `docs/telemetry.md`
53
+ - 18 new telemetry tests
54
+ - **Telemetry demo with Grafana visualization** - `examples/telemetry/`
55
+ - Live dashboard showing HTM metrics (job counts, latencies, cache hit rates)
56
+ - Uses Homebrew-installed Prometheus and Grafana (no Docker required)
57
+ - Auto-configures Prometheus scrape target
58
+ - Pre-built Grafana dashboard JSON for easy import
59
+ - Interactive shutdown prompt for service management
60
+ - **`htm:db:create` rake task** - Create database if it doesn't exist (respects `RAILS_ENV`)
61
+
62
+ ### Changed
63
+ - **All `htm:db:*` tasks now respect `RAILS_ENV`** - Following Rails conventions
64
+ - Database selection based on environment: `htm_development`, `htm_test`, `htm_production`
65
+ - `rake test` automatically sets `RAILS_ENV=test`
66
+ - Example: `RAILS_ENV=test rake htm:db:setup` operates on `htm_test`
67
+ - **`config/database.yml` refactored** - Extracts base name from `HTM_DBURL` and appends environment suffix
68
+ - `HTM_DBURL=postgresql://...htm_development` + `RAILS_ENV=test` → connects to `htm_test`
69
+ - **`HTM::Database.default_config` now respects `RAILS_ENV`** - Uses `ActiveRecordConfig.load_database_config`
70
+ - **Renamed `htm:db:test` to `htm:db:verify`** - Avoids naming collision with test database namespace
71
+ - `htm:db:verify` verifies database connection
72
+ - `RAILS_ENV=test rake htm:db:*` operates on test database
73
+
74
+ ## [0.0.13] - 2025-12-04
75
+
76
+ ### Changed
77
+ - **MarkdownChunker now uses Baran gem** - Replaced custom ParagraphChunker with Baran's `MarkdownSplitter`
78
+ - Respects markdown structure (headers, code blocks, horizontal rules)
79
+ - Configurable `chunk_size` and `chunk_overlap` settings
80
+ - Returns cursor positions for each chunk
81
+ - **Fuzzy tag search with trigram matching** - Tags now searchable with fuzzy matching via pg_trgm
82
+ - **LongTermMemory modularization** - Refactored into separate concerns for better maintainability
83
+ - Search optimizations for vector, fulltext, and hybrid strategies
84
+
85
+ ### Fixed
86
+ - **Configurable limits** - The following are now configurable (previously hard-coded):
87
+ - `max_embedding_dimension` (default: 2000)
88
+ - `max_tag_depth` (default: 4)
89
+ - Circuit breaker settings: `failure_threshold`, `reset_timeout`, `half_open_max_calls`
90
+ - Relevance scoring weights: `semantic_weight`, `tag_weight`, `recency_weight`, `access_weight`
91
+ - `relevance_recency_half_life_hours` (default: 168 = 1 week)
92
+
10
93
  ## [0.0.11] - 2025-12-02
11
94
 
12
95
  ### Added
@@ -260,7 +343,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
260
343
  - **Markdown file loader** - Load markdown files into long-term memory
261
344
  - `FileSource` model to track loaded files with metadata and sync status
262
345
  - `MarkdownLoader` with YAML frontmatter extraction
263
- - `ParagraphChunker` for splitting content into semantic chunks
346
+ - `MarkdownChunker` for splitting content into semantic chunks (uses Baran gem)
264
347
  - DELTA_TIME tolerance (5 seconds) for reliable file change detection
265
348
  - **New HTM API methods** for file operations:
266
349
  - `htm.load_file(path, force: false)` - Load single markdown file
@@ -347,7 +430,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
347
430
  ## [0.0.1] - 2025-10-25
348
431
 
349
432
  ### Added
350
- - Initial release of HTM (Hierarchical Temporary Memory)
433
+ - Initial release of HTM (Hierarchical Temporal Memory)
351
434
  - Two-tier memory system:
352
435
  - Working memory: Token-limited, in-memory active context
353
436
  - Long-term memory: Durable PostgreSQL/TimescaleDB storage
data/README.md CHANGED
@@ -51,6 +51,12 @@
51
51
  - Cross-robot context awareness
52
52
  - Track which robot said what
53
53
 
54
+ - **Robot Groups**
55
+ - Coordinate multiple robots with shared working memory
56
+ - Real-time synchronization via PostgreSQL LISTEN/NOTIFY
57
+ - Active/passive roles for instant failover
58
+ - Dynamic scaling (add/remove robots at runtime)
59
+
54
60
  - **LLM-Driven Tag Extraction**
55
61
  - Automatic hierarchical tag extraction from content
56
62
  - Tags in colon-delimited format (e.g., `database:postgresql:performance`)
@@ -68,6 +74,12 @@
68
74
  - Source file tracking with re-sync support
69
75
  - YAML frontmatter extraction as metadata
70
76
 
77
+ - **Telemetry (OpenTelemetry)**
78
+ - Optional metrics collection via OpenTelemetry
79
+ - Zero overhead when disabled (null object pattern)
80
+ - Works with 50+ backends (Jaeger, Prometheus, Datadog, etc.)
81
+ - Tracks job latency, search performance, and cache effectiveness
82
+
71
83
  ## Installation
72
84
 
73
85
  Add this line to your application's Gemfile:
@@ -306,6 +318,82 @@ rake htm:files:sync # Sync all files (reload changed)
306
318
  rake htm:files:stats # Show file loading statistics
307
319
  ```
308
320
 
321
+ ### Robot Groups
322
+
323
+ Robot Groups enable coordination of multiple robots with shared working memory and real-time synchronization. This is useful for high-availability setups, load balancing, and collaborative AI agents.
324
+
325
+ **Key Classes:**
326
+ - `HTM::RobotGroup` - Coordinates multiple robots with active/passive roles and shared working memory
327
+ - `HTM::WorkingMemoryChannel` - PostgreSQL LISTEN/NOTIFY pub/sub for real-time cross-process synchronization
328
+
329
+ **Basic Usage:**
330
+
331
+ ```ruby
332
+ require 'htm'
333
+
334
+ HTM.configure do |config|
335
+ config.embedding_provider = :ollama
336
+ config.embedding_model = 'nomic-embed-text'
337
+ end
338
+
339
+ # Create a robot group with primary + standby
340
+ group = HTM::RobotGroup.new(
341
+ name: 'customer-support-ha',
342
+ active: ['support-primary'],
343
+ passive: ['support-standby'],
344
+ max_tokens: 8000
345
+ )
346
+
347
+ # Add memories to the shared working memory
348
+ group.remember("Customer #123 prefers email communication", originator: 'support-primary')
349
+
350
+ # All robots in the group can recall shared memories
351
+ memories = group.recall('customer', limit: 5, strategy: :fulltext)
352
+
353
+ # Simulate failover when primary fails
354
+ group.failover! # Promotes standby to active
355
+
356
+ # Dynamic scaling - add more robots at runtime
357
+ group.add_active('support-secondary')
358
+ group.sync_robot('support-secondary') # Sync existing memories
359
+
360
+ # Check group status
361
+ status = group.status
362
+ # => { name: "customer-support-ha", active: [...], passive: [...], in_sync: true, ... }
363
+
364
+ # Cleanup
365
+ group.shutdown
366
+ ```
367
+
368
+ **Cross-Process Synchronization:**
369
+
370
+ For multi-process deployments, use `HTM::WorkingMemoryChannel` directly:
371
+
372
+ ```ruby
373
+ # In each worker process
374
+ channel = HTM::WorkingMemoryChannel.new('my-group', HTM::Database.default_config)
375
+
376
+ # Listen for memory changes from other processes
377
+ channel.on_change do |event, node_id, origin_robot_id|
378
+ case event
379
+ when :added # Another robot added a memory
380
+ when :evicted # Another robot evicted a memory
381
+ when :cleared # Another robot cleared working memory
382
+ end
383
+ end
384
+
385
+ channel.start_listening
386
+
387
+ # Notify other processes when you add a memory
388
+ channel.notify(:added, node_id: node.id, robot_id: my_robot_id)
389
+ ```
390
+
391
+ **Demo Applications:**
392
+
393
+ See `examples/robot_groups/` for complete examples:
394
+ - `same_process.rb` - Single-process demo with multiple robots
395
+ - `multi_process.rb` - Multi-process demo with real-time sync
396
+
309
397
  ### Automatic Tag Extraction
310
398
 
311
399
  HTM automatically extracts hierarchical tags from content using LLM analysis. Tags are inferred from the content itself - you never specify them manually.
@@ -373,6 +461,137 @@ rake htm:jobs:clear_all
373
461
 
374
462
  See `rake -T htm:jobs` for complete list of job management tasks.
375
463
 
464
+ ## Telemetry (OpenTelemetry)
465
+
466
+ HTM includes optional OpenTelemetry-based metrics for production observability. Telemetry is **disabled by default** with zero overhead when off.
467
+
468
+ ### Enabling Telemetry
469
+
470
+ ```ruby
471
+ HTM.configure do |config|
472
+ config.telemetry_enabled = true
473
+ end
474
+
475
+ # Or via environment variable
476
+ # HTM_TELEMETRY_ENABLED=true
477
+ ```
478
+
479
+ ### Configuring the Destination
480
+
481
+ HTM emits metrics via standard OpenTelemetry protocols. Configure your destination using environment variables:
482
+
483
+ ```bash
484
+ # Export to any OTLP-compatible backend
485
+ export OTEL_METRICS_EXPORTER="otlp"
486
+ export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
487
+ ```
488
+
489
+ ### Available Metrics
490
+
491
+ | Metric | Type | Attributes | Description |
492
+ |--------|------|------------|-------------|
493
+ | `htm.jobs` | Counter | `job`, `status` | Job execution counts (embedding, tags) |
494
+ | `htm.embedding.latency` | Histogram | `provider`, `status` | Embedding generation time (ms) |
495
+ | `htm.tag.latency` | Histogram | `provider`, `status` | Tag extraction time (ms) |
496
+ | `htm.search.latency` | Histogram | `strategy` | Search operation time (ms) |
497
+ | `htm.cache.operations` | Counter | `operation` | Cache hits/misses |
498
+
499
+ ### Compatible Backends
500
+
501
+ HTM works with any OTLP-compatible observability platform:
502
+
503
+ **Open Source:** Jaeger, Prometheus, Grafana Tempo/Mimir, SigNoz, Uptrace
504
+
505
+ **Commercial:** Datadog, New Relic, Honeycomb, Splunk, Dynatrace, AWS X-Ray, Google Cloud Trace, Azure Monitor
506
+
507
+ ### Optional Dependencies
508
+
509
+ Users who want telemetry should add these gems:
510
+
511
+ ```ruby
512
+ gem 'opentelemetry-sdk'
513
+ gem 'opentelemetry-metrics-sdk'
514
+ gem 'opentelemetry-exporter-otlp' # For OTLP export
515
+ ```
516
+
517
+ ### Design
518
+
519
+ HTM uses a **null object pattern** for telemetry. When disabled or when the SDK is not installed:
520
+ - All metric operations are no-ops
521
+ - Zero runtime overhead
522
+ - No errors or exceptions
523
+
524
+ See [docs/telemetry.md](docs/telemetry.md) for detailed configuration and usage examples.
525
+
526
+ ## MCP Server (Model Context Protocol)
527
+
528
+ HTM includes an MCP server that exposes memory capabilities to AI assistants like Claude Desktop, Claude Code, and AIA. This enables any MCP-compatible client to store, recall, and manage memories through a standardized protocol.
529
+
530
+ ### Available Tools
531
+
532
+ | Tool | Description |
533
+ |------|-------------|
534
+ | `SetRobotTool` | Set the robot identity for the session (call first) |
535
+ | `GetRobotTool` | Get current robot information |
536
+ | `GetWorkingMemoryTool` | Get working memory contents for session restore |
537
+ | `RememberTool` | Store information with optional tags and metadata |
538
+ | `RecallTool` | Search memories using vector, fulltext, or hybrid strategies |
539
+ | `ForgetTool` | Soft-delete a memory (recoverable) |
540
+ | `RestoreTool` | Restore a soft-deleted memory |
541
+ | `ListTagsTool` | List tags with optional prefix filtering |
542
+ | `SearchTagsTool` | Fuzzy tag search with typo tolerance |
543
+ | `FindByTopicTool` | Find nodes by topic with optional fuzzy matching |
544
+ | `StatsTool` | Get memory usage statistics |
545
+
546
+ ### Available Resources
547
+
548
+ | URI | Description |
549
+ |-----|-------------|
550
+ | `htm://statistics` | Memory statistics as JSON |
551
+ | `htm://tags/hierarchy` | Tag hierarchy as text tree |
552
+ | `htm://memories/recent` | Last 20 memories |
553
+
554
+ ### Client Configuration
555
+
556
+ **Claude Desktop** (`~/.config/claude/claude_desktop_config.json`):
557
+ ```json
558
+ {
559
+ "mcpServers": {
560
+ "htm-memory": {
561
+ "command": "htm_mcp.rb",
562
+ "env": {
563
+ "HTM_DBURL": "postgresql://user@localhost:5432/htm_development"
564
+ }
565
+ }
566
+ }
567
+ }
568
+ ```
569
+
570
+ **Claude Code** (`~/.claude/claude_code_config.json`):
571
+ ```json
572
+ {
573
+ "mcpServers": {
574
+ "htm-memory": {
575
+ "command": "htm_mcp.rb",
576
+ "env": {
577
+ "HTM_DBURL": "postgresql://user@localhost:5432/htm_development"
578
+ }
579
+ }
580
+ }
581
+ }
582
+ ```
583
+
584
+ **AIA** (`~/.config/aia/config.yml`):
585
+ ```yaml
586
+ mcp_servers:
587
+ htm-memory:
588
+ command: htm_mcp.rb
589
+ env:
590
+ HTM_DBURL: postgresql://user@localhost:5432/htm_development
591
+ ```
592
+
593
+ See [docs/guides/mcp-server.md](docs/guides/mcp-server.md) for detailed configuration, usage examples, and troubleshooting.
594
+
376
595
  ## Configuration
377
596
 
378
597
  HTM uses dependency injection for LLM access, allowing you to configure embedding generation, tag extraction, logging, and token counting.
@@ -1160,6 +1379,17 @@ export HTM_LOG_LEVEL="INFO" # Default
1160
1379
 
1161
1380
  This is used by the default logger when `HTM.configure` is called without a custom logger.
1162
1381
 
1382
+ #### HTM_TELEMETRY_ENABLED
1383
+
1384
+ Enable OpenTelemetry metrics collection:
1385
+
1386
+ ```bash
1387
+ export HTM_TELEMETRY_ENABLED="true" # Enable telemetry
1388
+ export HTM_TELEMETRY_ENABLED="false" # Disable (default)
1389
+ ```
1390
+
1391
+ When enabled, HTM emits metrics to configured OpenTelemetry collectors. See [Telemetry](#telemetry-opentelemetry) for details.
1392
+
1163
1393
  ### Quick Setup Examples
1164
1394
 
1165
1395
  #### Local Development (PostgreSQL)
@@ -1239,50 +1469,86 @@ rake test
1239
1469
  ruby examples/basic_usage.rb
1240
1470
  ```
1241
1471
 
1242
- ### Database Management
1243
-
1244
- HTM provides comprehensive rake tasks under the `htm:db` namespace for managing the database:
1245
-
1246
- ```bash
1247
- # List all database tasks
1248
- rake -T htm:db
1249
-
1250
- # Set up database (create schema + run migrations)
1251
- rake htm:db:setup
1252
-
1253
- # Run pending migrations only
1254
- rake htm:db:migrate
1255
-
1256
- # Show migration status (which migrations are applied)
1257
- rake htm:db:status
1258
-
1259
- # Show database info (size, tables, extensions, row counts)
1260
- rake htm:db:info
1261
-
1262
- # Test database connection
1263
- rake htm:db:test
1264
-
1265
- # Open PostgreSQL console (interactive psql session)
1266
- rake htm:db:console
1267
-
1268
- # Seed database with sample data
1269
- rake htm:db:seed
1270
-
1271
- # Drop all HTM tables (WARNING: destructive!)
1272
- rake htm:db:drop
1273
-
1274
- # Drop and recreate database (WARNING: destructive!)
1275
- rake htm:db:reset
1276
- ```
1277
-
1278
1472
  **Important**: Make sure `direnv allow` has been run once in the project directory to load database environment variables from `.envrc`. Alternatively, you can manually export the environment variables:
1279
1473
 
1280
1474
  ```bash
1281
- # Manually export HTM_DBURL
1282
1475
  export HTM_DBURL="postgresql://user:password@host:port/dbname?sslmode=require"
1283
1476
  ```
1284
1477
 
1285
- **Common Workflows**:
1478
+ ### HTM Rake Tasks Reference
1479
+
1480
+ HTM provides comprehensive rake tasks for database management, documentation, file loading, job processing, and tag management. Use `rake -T htm` to see all available tasks.
1481
+
1482
+ #### Database Tasks (`htm:db:*`)
1483
+
1484
+ | Task | Description |
1485
+ |------|-------------|
1486
+ | `rake htm:db:setup` | Set up HTM database schema and run migrations (sets up from scratch) |
1487
+ | `rake htm:db:create` | Create database if it doesn't exist (respects RAILS_ENV) |
1488
+ | `rake htm:db:migrate` | Run pending database migrations |
1489
+ | `rake htm:db:status` | Show migration status |
1490
+ | `rake htm:db:verify` | Verify database connection (respects RAILS_ENV) |
1491
+ | `rake htm:db:info` | Show database info (size, tables, extensions) |
1492
+ | `rake htm:db:stats` | Show record counts for all HTM tables |
1493
+ | `rake htm:db:console` | Open PostgreSQL console (respects RAILS_ENV) |
1494
+ | `rake htm:db:seed` | Seed database with sample data |
1495
+ | `rake htm:db:schema:dump` | Dump current schema to db/schema.sql |
1496
+ | `rake htm:db:schema:load` | Load schema from db/schema.sql |
1497
+ | `rake htm:db:rebuild:embeddings` | Rebuild embeddings for all nodes |
1498
+ | `rake htm:db:rebuild:propositions` | Rebuild propositions for all non-proposition nodes |
1499
+ | `rake htm:db:tags:cleanup` | Soft delete orphaned tags and stale node_tags entries |
1500
+ | `rake htm:db:drop` | Drop all HTM tables (WARNING: destructive!) |
1501
+ | `rake htm:db:reset` | Drop and recreate database (WARNING: destructive!) |
1502
+
1503
+ #### Documentation Tasks (`htm:doc:*`)
1504
+
1505
+ | Task | Description |
1506
+ |------|-------------|
1507
+ | `rake htm:doc:all` | Generate DB docs, YARD API docs, build site, and serve |
1508
+ | `rake htm:doc:yard` | Build YARD API documentation (markdown format for MkDocs) |
1509
+ | `rake htm:doc:db` | Generate/update database documentation in docs/database/ |
1510
+ | `rake htm:doc:build` | Build documentation site with MkDocs |
1511
+ | `rake htm:doc:serve` | Serve documentation site locally with MkDocs |
1512
+ | `rake htm:doc:server[port]` | Start YARD documentation server (live reload) |
1513
+ | `rake htm:doc:fix_anchors` | Fix YARD anchor links for MkDocs compatibility |
1514
+ | `rake htm:doc:stats` | Show documentation coverage statistics |
1515
+ | `rake htm:doc:clean` | Clean generated documentation |
1516
+
1517
+ #### File Loading Tasks (`htm:files:*`)
1518
+
1519
+ | Task | Description |
1520
+ |------|-------------|
1521
+ | `rake htm:files:load[path]` | Load a markdown file into long-term memory |
1522
+ | `rake htm:files:load_dir[path,pattern]` | Load all markdown files from a directory |
1523
+ | `rake htm:files:list` | List all loaded file sources |
1524
+ | `rake htm:files:info[path]` | Show details for a loaded file |
1525
+ | `rake htm:files:sync` | Sync all loaded files (reload changed files) |
1526
+ | `rake htm:files:unload[path]` | Unload a file from memory |
1527
+ | `rake htm:files:stats` | Show file loading statistics |
1528
+
1529
+ #### Job Processing Tasks (`htm:jobs:*`)
1530
+
1531
+ | Task | Description |
1532
+ |------|-------------|
1533
+ | `rake htm:jobs:stats` | Show statistics for nodes and async job processing |
1534
+ | `rake htm:jobs:process_embeddings` | Process pending embedding jobs for nodes without embeddings |
1535
+ | `rake htm:jobs:process_tags` | Process pending tag extraction jobs for nodes without tags |
1536
+ | `rake htm:jobs:process_all` | Process all pending jobs (embeddings and tags) |
1537
+ | `rake htm:jobs:reprocess_embeddings` | Reprocess embeddings for all nodes (force regeneration) |
1538
+ | `rake htm:jobs:failed` | Show nodes that failed async processing |
1539
+ | `rake htm:jobs:clear_all` | Clear all embeddings and tags (for testing/development) |
1540
+
1541
+ #### Tag Management Tasks (`htm:tags:*`)
1542
+
1543
+ | Task | Description |
1544
+ |------|-------------|
1545
+ | `rake htm:tags:tree[prefix]` | Display tags as a hierarchical tree (text format) |
1546
+ | `rake htm:tags:mermaid[prefix]` | Export tags as Mermaid flowchart to tags.md |
1547
+ | `rake htm:tags:svg[prefix]` | Export tags as SVG visualization to tags.svg |
1548
+ | `rake htm:tags:export[prefix]` | Export tags in all formats (tags.txt, tags.md, tags.svg) |
1549
+ | `rake htm:tags:rebuild` | Rebuild all tags from node content |
1550
+
1551
+ ### Common Workflows
1286
1552
 
1287
1553
  ```bash
1288
1554
  # Initial setup (first time)
@@ -1295,57 +1561,35 @@ rake htm:db:migrate # Run pending migrations
1295
1561
  # Check database state
1296
1562
  rake htm:db:status # See migration status
1297
1563
  rake htm:db:info # See database details
1564
+ rake htm:db:stats # See record counts
1298
1565
 
1299
- # Reset database (development only!)
1300
- rake htm:db:reset # Drops and recreates everything
1301
-
1302
- # Open database console for debugging
1303
- rake htm:db:console # Opens psql
1304
- ```
1305
-
1306
- ### Async Job Management
1307
-
1308
- HTM provides rake tasks under the `htm:jobs` namespace for managing async embedding and tag extraction jobs:
1309
-
1310
- ```bash
1311
- # List all job management tasks
1312
- rake -T htm:jobs
1313
-
1314
- # Show statistics for async processing
1566
+ # Monitor async processing
1315
1567
  rake htm:jobs:stats
1568
+ rake htm:jobs:failed # Show stuck jobs
1316
1569
 
1317
- # Process pending jobs
1318
- rake htm:jobs:process_embeddings # Process nodes without embeddings
1319
- rake htm:jobs:process_tags # Process nodes without tags
1320
- rake htm:jobs:process_all # Process both
1321
-
1322
- # Reprocess all nodes (force regeneration)
1323
- rake htm:jobs:reprocess_embeddings # WARNING: Prompts for confirmation
1324
-
1325
- # Debugging and maintenance
1326
- rake htm:jobs:failed # Show stuck jobs (>1 hour old)
1327
- rake htm:jobs:clear_all # Clear all embeddings/tags (testing only)
1328
- ```
1570
+ # Process pending jobs manually
1571
+ rake htm:jobs:process_all
1329
1572
 
1330
- **Common Workflows**:
1573
+ # Generate documentation
1574
+ rake htm:doc:all # Full documentation build
1575
+ rake htm:doc:serve # Local preview
1331
1576
 
1332
- ```bash
1333
- # Monitor async processing
1334
- rake htm:jobs:stats
1577
+ # Load files into memory
1578
+ rake 'htm:files:load[docs/guide.md]'
1579
+ rake 'htm:files:load_dir[docs/,**/*.md]'
1335
1580
 
1336
- # Manually process pending jobs (if async job runner is not running)
1337
- rake htm:jobs:process_all
1581
+ # View tag hierarchy
1582
+ rake htm:tags:tree
1583
+ rake 'htm:tags:svg[database]' # Export filtered tags
1338
1584
 
1339
- # Debug stuck jobs
1340
- rake htm:jobs:failed
1341
- rake htm:jobs:process_embeddings # Retry failed embeddings
1585
+ # Reset database (development only!)
1586
+ rake htm:db:reset # Drops and recreates everything
1342
1587
 
1343
- # Development/testing: force regeneration
1344
- rake htm:jobs:reprocess_embeddings # Regenerate all embeddings
1345
- rake htm:jobs:clear_all # Clear everything and start fresh
1588
+ # Open database console for debugging
1589
+ rake htm:db:console # Opens psql
1346
1590
  ```
1347
1591
 
1348
- See the [Async Job Processing](#async-job-processing) section for more details.
1592
+ See the [Async Job Processing](#async-job-processing) section for more details on background jobs.
1349
1593
 
1350
1594
  ## Testing
1351
1595
 
@@ -1409,6 +1653,31 @@ This separation allows you to provide any LLM implementation while HTM handles r
1409
1653
  - [x] Phase 8: Production-ready gem
1410
1654
 
1411
1655
 
1656
+ ## Why "Robots" Instead of "Agents"?
1657
+
1658
+ > "What's in a name? That which we call a rose
1659
+ > By any other name would smell as sweet."
1660
+ > — Shakespeare, *Romeo and Juliet*
1661
+
1662
+ Shakespeare argues names are arbitrary. In software, we respectfully disagree—names shape expectations and understanding.
1663
+
1664
+ HTM uses "robots" rather than the fashionable "agents" for several reasons:
1665
+
1666
+ - **Semantic clarity**: "Agent" is overloaded—user agents, software agents, real estate agents, secret agents. "Robot" is specific to automated workers.
1667
+
1668
+ - **Honest about capabilities**: "Agent" implies autonomy and genuine decision-making. These systems follow instructions—they don't have agency. "Robot" acknowledges what they actually are: tools.
1669
+
1670
+ - **Avoiding the hype cycle**: "AI Agent" and "Agentic AI" became buzzwords in 2023-2024, often meaning nothing more than "LLM with a prompt." We prefer terminology that will age well.
1671
+
1672
+ - **Many "agent" frameworks are prompt wrappers**: Look under the hood of popular agent libraries and you'll often find a single prompt in a for-loop. Calling that an "agent" sets false expectations.
1673
+
1674
+ - **Rich heritage**: "Robot" comes from Karel Čapek's 1920 play *R.U.R.* (from Czech *robota*, meaning labor). Isaac Asimov gave us the Three Laws. There's decades of thoughtful writing about robot ethics and behavior. "Agent" has no comparable tradition.
1675
+
1676
+ - **Personality**: Robots are endearing—R2-D2, Wall-E, Bender. They have cultural weight that "agent" lacks.
1677
+
1678
+ Honest terminology leads to clearer thinking. These are robots: tireless workers with perfect memory, executing instructions on our behalf. That's exactly what HTM helps them do better.
1679
+
1680
+
1412
1681
  ## Contributing
1413
1682
 
1414
1683
  Bug reports and pull requests are welcome on GitHub at https://github.com/madbomber/htm.