htm 0.0.2 → 0.0.11
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/.aigcm_msg +1 -0
- data/.architecture/reviews/comprehensive-codebase-review.md +577 -0
- data/.claude/settings.local.json +95 -0
- data/.irbrc +283 -80
- data/.tbls.yml +2 -1
- data/CHANGELOG.md +327 -26
- data/CLAUDE.md +603 -0
- data/README.md +83 -12
- data/Rakefile +5 -0
- data/bin/htm_mcp.rb +527 -0
- data/db/migrate/{20250101000001_enable_extensions.rb → 00001_enable_extensions.rb} +0 -1
- data/db/migrate/00002_create_robots.rb +11 -0
- data/db/migrate/00003_create_file_sources.rb +20 -0
- data/db/migrate/00004_create_nodes.rb +65 -0
- data/db/migrate/00005_create_tags.rb +13 -0
- data/db/migrate/00006_create_node_tags.rb +18 -0
- data/db/migrate/00007_create_robot_nodes.rb +26 -0
- data/db/migrate/00009_add_working_memory_to_robot_nodes.rb +12 -0
- data/db/schema.sql +172 -1
- data/docs/api/database.md +1 -2
- data/docs/api/htm.md +197 -2
- data/docs/api/yard/HTM/ActiveRecordConfig.md +23 -0
- data/docs/api/yard/HTM/AuthorizationError.md +11 -0
- data/docs/api/yard/HTM/CircuitBreaker.md +92 -0
- data/docs/api/yard/HTM/CircuitBreakerOpenError.md +34 -0
- data/docs/api/yard/HTM/Configuration.md +175 -0
- data/docs/api/yard/HTM/Database.md +99 -0
- data/docs/api/yard/HTM/DatabaseError.md +14 -0
- data/docs/api/yard/HTM/EmbeddingError.md +18 -0
- data/docs/api/yard/HTM/EmbeddingService.md +58 -0
- data/docs/api/yard/HTM/Error.md +11 -0
- data/docs/api/yard/HTM/JobAdapter.md +39 -0
- data/docs/api/yard/HTM/LongTermMemory.md +342 -0
- data/docs/api/yard/HTM/NotFoundError.md +17 -0
- data/docs/api/yard/HTM/Observability.md +107 -0
- data/docs/api/yard/HTM/QueryTimeoutError.md +19 -0
- data/docs/api/yard/HTM/Railtie.md +27 -0
- data/docs/api/yard/HTM/ResourceExhaustedError.md +13 -0
- data/docs/api/yard/HTM/TagError.md +18 -0
- data/docs/api/yard/HTM/TagService.md +67 -0
- data/docs/api/yard/HTM/Timeframe/Result.md +24 -0
- data/docs/api/yard/HTM/Timeframe.md +40 -0
- data/docs/api/yard/HTM/TimeframeExtractor/Result.md +24 -0
- data/docs/api/yard/HTM/TimeframeExtractor.md +45 -0
- data/docs/api/yard/HTM/ValidationError.md +20 -0
- data/docs/api/yard/HTM/WorkingMemory.md +131 -0
- data/docs/api/yard/HTM.md +80 -0
- data/docs/api/yard/index.csv +179 -0
- data/docs/api/yard-reference.md +51 -0
- data/docs/database/README.md +128 -128
- data/docs/database/public.file_sources.md +42 -0
- data/docs/database/public.file_sources.svg +211 -0
- data/docs/database/public.node_tags.md +4 -4
- data/docs/database/public.node_tags.svg +212 -79
- data/docs/database/public.nodes.md +22 -12
- data/docs/database/public.nodes.svg +246 -127
- data/docs/database/public.robot_nodes.md +11 -9
- data/docs/database/public.robot_nodes.svg +220 -98
- data/docs/database/public.robots.md +2 -2
- data/docs/database/public.robots.svg +136 -81
- data/docs/database/public.tags.md +3 -3
- data/docs/database/public.tags.svg +118 -39
- data/docs/database/schema.json +850 -771
- data/docs/database/schema.svg +256 -197
- data/docs/development/schema.md +67 -2
- data/docs/guides/adding-memories.md +93 -7
- data/docs/guides/recalling-memories.md +36 -1
- data/examples/README.md +405 -0
- data/examples/cli_app/htm_cli.rb +65 -5
- data/examples/cli_app/temp.log +93 -0
- data/examples/file_loader_usage.rb +177 -0
- data/examples/mcp_client.rb +529 -0
- data/examples/robot_groups/lib/robot_group.rb +419 -0
- data/examples/robot_groups/lib/working_memory_channel.rb +140 -0
- data/examples/robot_groups/multi_process.rb +286 -0
- data/examples/robot_groups/robot_worker.rb +136 -0
- data/examples/robot_groups/same_process.rb +229 -0
- data/examples/timeframe_demo.rb +276 -0
- data/lib/htm/active_record_config.rb +1 -1
- data/lib/htm/circuit_breaker.rb +202 -0
- data/lib/htm/configuration.rb +59 -13
- data/lib/htm/database.rb +67 -36
- data/lib/htm/embedding_service.rb +39 -2
- data/lib/htm/errors.rb +131 -11
- data/lib/htm/jobs/generate_embedding_job.rb +5 -4
- data/lib/htm/jobs/generate_tags_job.rb +4 -0
- data/lib/htm/loaders/markdown_loader.rb +263 -0
- data/lib/htm/loaders/paragraph_chunker.rb +112 -0
- data/lib/htm/long_term_memory.rb +460 -343
- data/lib/htm/models/file_source.rb +99 -0
- data/lib/htm/models/node.rb +80 -5
- data/lib/htm/models/robot.rb +24 -1
- data/lib/htm/models/robot_node.rb +1 -0
- data/lib/htm/models/tag.rb +254 -4
- data/lib/htm/observability.rb +395 -0
- data/lib/htm/tag_service.rb +60 -3
- data/lib/htm/tasks.rb +26 -1
- data/lib/htm/timeframe.rb +194 -0
- data/lib/htm/timeframe_extractor.rb +307 -0
- data/lib/htm/version.rb +1 -1
- data/lib/htm/working_memory.rb +165 -70
- data/lib/htm.rb +328 -130
- data/lib/tasks/doc.rake +300 -0
- data/lib/tasks/files.rake +299 -0
- data/lib/tasks/htm.rake +158 -3
- data/lib/tasks/jobs.rake +3 -9
- data/lib/tasks/tags.rake +166 -6
- data/mkdocs.yml +36 -1
- data/notes/ARCHITECTURE_REVIEW.md +1167 -0
- data/notes/IMPLEMENTATION_SUMMARY.md +606 -0
- data/notes/MULTI_FRAMEWORK_IMPLEMENTATION.md +451 -0
- data/notes/next_steps.md +100 -0
- data/notes/plan.md +627 -0
- data/notes/tag_ontology_enhancement_ideas.md +222 -0
- data/notes/timescaledb_removal_summary.md +200 -0
- metadata +158 -17
- data/db/migrate/20250101000002_create_robots.rb +0 -14
- data/db/migrate/20250101000003_create_nodes.rb +0 -42
- data/db/migrate/20250101000005_create_tags.rb +0 -38
- data/db/migrate/20250101000007_add_node_vector_indexes.rb +0 -30
- data/db/migrate/20250125000001_add_content_hash_to_nodes.rb +0 -14
- data/db/migrate/20250125000002_create_robot_nodes.rb +0 -35
- data/db/migrate/20250125000003_remove_source_and_robot_id_from_nodes.rb +0 -28
- data/db/migrate/20250126000001_create_working_memories.rb +0 -19
- data/db/migrate/20250126000002_remove_unused_columns.rb +0 -12
- data/docs/database/public.working_memories.md +0 -40
- data/docs/database/public.working_memories.svg +0 -112
- data/lib/htm/models/working_memory_entry.rb +0 -88
data/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,307 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.0.11] - 2025-12-02
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **MCP Server and Client** - Model Context Protocol integration for AI assistants
|
|
14
|
+
- `bin/htm_mcp.rb` - FastMCP-based server exposing HTM tools:
|
|
15
|
+
- `SetRobotTool` - Set robot identity for the session (per-client isolation)
|
|
16
|
+
- `GetRobotTool` - Get current robot information
|
|
17
|
+
- `GetWorkingMemoryTool` - Retrieve working memory for session restore
|
|
18
|
+
- `RememberTool` - Store information with tags and metadata
|
|
19
|
+
- `RecallTool` - Search memories with vector/fulltext/hybrid strategies
|
|
20
|
+
- `ForgetTool` / `RestoreTool` - Soft delete and restore memories
|
|
21
|
+
- `ListTagsTool` - List tags with optional prefix filtering
|
|
22
|
+
- `StatsTool` - Memory usage statistics
|
|
23
|
+
- Resources: `htm://statistics`, `htm://tags/hierarchy`, `htm://memories/recent`
|
|
24
|
+
- STDERR logging to avoid corrupting MCP JSON-RPC protocol
|
|
25
|
+
- Session-based robot identity via `MCPSession` module
|
|
26
|
+
- `examples/mcp_client.rb` - Interactive chat client using ruby_llm-mcp:
|
|
27
|
+
- Prompts for robot name on startup (or uses `HTM_ROBOT_NAME` env var)
|
|
28
|
+
- Session restore: offers to restore working memory from previous session
|
|
29
|
+
- Interactive chat loop with Ollama LLM (gpt-oss model)
|
|
30
|
+
- Tool call logging for visibility
|
|
31
|
+
- Slash commands: `/tools`, `/resources`, `/stats`, `/tags`, `/clear`, `/help`, `/exit`
|
|
32
|
+
- **Session restore feature** - MCP client can restore previous session context
|
|
33
|
+
- `GetWorkingMemoryTool` returns all nodes in working memory for a robot
|
|
34
|
+
- Client prompts user to restore previous session on startup
|
|
35
|
+
- Working memory injected into chat context for continuity
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- **GetWorkingMemoryTool** now uses `joins(:node)` to exclude soft-deleted nodes
|
|
39
|
+
- **StatsTool** fixed scope error (`Node.active` → `Node.count` with default_scope)
|
|
40
|
+
- **MCP tool response parsing** - Extract `.text` from `RubyLLM::MCP::Content` objects
|
|
41
|
+
|
|
42
|
+
## [0.0.10] - 2025-12-02
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- **Robot groups example with multi-process synchronization** - New `examples/robot_groups/` directory
|
|
46
|
+
- `RobotGroup` class for coordinating multiple robots with shared working memory
|
|
47
|
+
- `WorkingMemoryChannel` for real-time sync via PostgreSQL LISTEN/NOTIFY
|
|
48
|
+
- `same_process.rb` - Single-process demo of robot groups with failover
|
|
49
|
+
- `multi_process.rb` - Cross-process coordination with separate Ruby processes
|
|
50
|
+
- `robot_worker.rb` - Worker process for multi-process demo
|
|
51
|
+
- Demonstrates high-availability patterns: active/passive roles, warm standby, instant failover
|
|
52
|
+
- **Examples directory README** - Comprehensive documentation for all example programs
|
|
53
|
+
- Describes 9 example programs across standalone scripts and application examples
|
|
54
|
+
- Usage instructions, features, and directory structure
|
|
55
|
+
- Quick reference table for choosing the right example
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
- **YARD documentation updates** - Added documentation for metadata parameter support
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
- **Refactored working memory persistence to robot_nodes join table** - Simpler, more efficient schema
|
|
63
|
+
- Added `working_memory` boolean column to `robot_nodes` table (default: false)
|
|
64
|
+
- Partial index `idx_robot_nodes_working_memory` for efficient queries on active working memory
|
|
65
|
+
- Working memory state now tracked per robot-node relationship
|
|
66
|
+
- `remember()` and `recall()` now set `working_memory = true` when adding to working memory
|
|
67
|
+
- Eviction sets `working_memory = false` on evicted nodes
|
|
68
|
+
- **Updated `mark_evicted` signature** - Now requires `robot_id:` and `node_ids:` keyword arguments
|
|
69
|
+
- **Added space check to `remember()`** - Now evicts old memories before adding if working memory is full (was missing, only `recall()` had this check)
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
- **`RobotNode.in_working_memory` scope** - Query nodes currently in a robot's working memory
|
|
73
|
+
- **`Robot#memory_summary[:in_working_memory]`** - Now uses efficient scope instead of separate table
|
|
74
|
+
|
|
75
|
+
### Removed
|
|
76
|
+
- **`working_memories` table** - Replaced by `working_memory` boolean on `robot_nodes`
|
|
77
|
+
- **`WorkingMemoryEntry` model** - No longer needed
|
|
78
|
+
- **Migration `00008_create_working_memories.rb`** - Replaced by simpler approach
|
|
79
|
+
|
|
80
|
+
### Migration
|
|
81
|
+
| Migration | Table | Description |
|
|
82
|
+
|-----------|-------|-------------|
|
|
83
|
+
| `00009_add_working_memory_to_robot_nodes.rb` | `robot_nodes` | Adds working_memory boolean column |
|
|
84
|
+
|
|
85
|
+
## [0.0.9] - 2025-11-29
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
- **Consolidated database migrations** - Reduced 14 migrations to 8 clean migrations
|
|
89
|
+
- Each migration now handles exactly one table
|
|
90
|
+
- Removed incremental add/remove column migrations
|
|
91
|
+
- All indexes, constraints, and foreign keys included in table creation
|
|
92
|
+
- Migrations ordered by dependencies (extensions, then tables with FKs)
|
|
93
|
+
- Migration files now use simple numeric prefixes (00001-00008)
|
|
94
|
+
|
|
95
|
+
### Migration Files
|
|
96
|
+
| Migration | Table | Description |
|
|
97
|
+
|-----------|-------|-------------|
|
|
98
|
+
| `00001_enable_extensions.rb` | (extensions) | Enables vector and pg_trgm |
|
|
99
|
+
| `00002_create_robots.rb` | `robots` | Robot registry |
|
|
100
|
+
| `00003_create_file_sources.rb` | `file_sources` | Source file metadata |
|
|
101
|
+
| `00004_create_nodes.rb` | `nodes` | Core memory storage |
|
|
102
|
+
| `00005_create_tags.rb` | `tags` | Tag names |
|
|
103
|
+
| `00006_create_node_tags.rb` | `node_tags` | Node-tag join table |
|
|
104
|
+
| `00007_create_robot_nodes.rb` | `robot_nodes` | Robot-node join table |
|
|
105
|
+
| `00008_create_working_memories.rb` | `working_memories` | Per-robot working memory |
|
|
106
|
+
|
|
107
|
+
## [0.0.8] - 2025-11-29
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
- **Circuit breaker pattern for LLM services** - Prevents cascading failures from external APIs
|
|
111
|
+
- New `HTM::CircuitBreaker` class with configurable thresholds
|
|
112
|
+
- Three states: `:closed` (normal), `:open` (failing fast), `:half_open` (testing recovery)
|
|
113
|
+
- Configurable `failure_threshold` (default: 5), `reset_timeout` (default: 60s)
|
|
114
|
+
- Thread-safe implementation with Mutex protection
|
|
115
|
+
- Integrated into `EmbeddingService` and `TagService`
|
|
116
|
+
- Background jobs handle `CircuitBreakerOpenError` gracefully
|
|
117
|
+
- **Thread-safe WorkingMemory** - All public methods now protected by Mutex
|
|
118
|
+
- `add`, `remove`, `has_space?`, `evict_to_make_space` synchronized
|
|
119
|
+
- `assemble_context`, `token_count`, `utilization_percentage`, `node_count` synchronized
|
|
120
|
+
- Internal helpers renamed to `*_unlocked` variants for safe internal use
|
|
121
|
+
- **Observability module** (`HTM::Observability`) for system monitoring
|
|
122
|
+
- `connection_pool_stats` - Pool health with warning/critical/exhausted status
|
|
123
|
+
- `circuit_breaker_stats` - Service circuit breaker states
|
|
124
|
+
- `query_timing_stats` - Query performance metrics (avg, min, max, p50, p95, p99)
|
|
125
|
+
- `service_timing_stats` - Embedding/tag generation timing
|
|
126
|
+
- `memory_stats` - Process memory usage
|
|
127
|
+
- `health_check` - Comprehensive system health verification
|
|
128
|
+
- `healthy?` - Quick boolean health check
|
|
129
|
+
- Configurable thresholds: 75% warning, 90% critical for connection pool
|
|
130
|
+
- **Comprehensive test suites**:
|
|
131
|
+
- `test/circuit_breaker_test.rb` - 13 tests for circuit breaker states and transitions
|
|
132
|
+
- `test/embedding_service_test.rb` - 19 tests for validation, generation, and circuit breaker
|
|
133
|
+
- `test/observability_test.rb` - 10 tests for observability module
|
|
134
|
+
- Updated `test/tag_service_test.rb` - Added 4 circuit breaker tests (total 33 tests)
|
|
135
|
+
- Expanded `test/integration_test.rb` - Added 13 new integration tests
|
|
136
|
+
- **Architecture review document** - Comprehensive multi-perspective codebase review
|
|
137
|
+
- Reviews from 8 specialist perspectives (Systems, Domain, Security, etc.)
|
|
138
|
+
- Located at `.architecture/reviews/comprehensive-codebase-review.md`
|
|
139
|
+
- **Enhanced YARD documentation** for all error classes with examples
|
|
140
|
+
|
|
141
|
+
### Changed
|
|
142
|
+
- **CircuitBreakerOpenError** now extends `HTM::Error` (was `EmbeddingError`)
|
|
143
|
+
- Allows both EmbeddingService and TagService to use it
|
|
144
|
+
- **EmbeddingService and TagService** re-raise `CircuitBreakerOpenError` without wrapping
|
|
145
|
+
- Enables proper circuit breaker behavior in calling code
|
|
146
|
+
- **GenerateEmbeddingJob and GenerateTagsJob** log warnings for circuit breaker open state
|
|
147
|
+
- Graceful degradation when LLM services are unavailable
|
|
148
|
+
|
|
149
|
+
### Removed
|
|
150
|
+
- **`embedding_dimension` column from nodes table** - Unused since embeddings are always padded to 2000
|
|
151
|
+
- **`embedding_model` column from nodes table** - Not needed for current use cases
|
|
152
|
+
|
|
153
|
+
## [0.0.7] - 2025-11-28
|
|
154
|
+
|
|
155
|
+
### Security
|
|
156
|
+
- **Fixed SQL injection vulnerabilities** in multiple locations:
|
|
157
|
+
- `LongTermMemory#build_timeframe_condition` - Now uses `connection.quote`
|
|
158
|
+
- `LongTermMemory#topic_relationships` - Now uses parameterized queries ($1, $2)
|
|
159
|
+
- `Node#similarity_to` - Added embedding validation and proper quoting
|
|
160
|
+
- `Database#run_activerecord_migrations` - Uses `sanitize_sql_array`
|
|
161
|
+
- **Removed hardcoded database credentials** from default configuration
|
|
162
|
+
|
|
163
|
+
### Added
|
|
164
|
+
- **Thread-safe cache statistics** - Added `Mutex` synchronization for `@cache_stats`
|
|
165
|
+
- **Input validation for `remember` method** - Validates content size and tag format
|
|
166
|
+
- **URL format validation** - `Database.parse_connection_url` now validates scheme, host, and database name
|
|
167
|
+
- **Encoding fallback in MarkdownLoader** - UTF-8 with binary fallback for non-UTF-8 files
|
|
168
|
+
- **File size validation** - MarkdownLoader enforces 10 MB maximum file size
|
|
169
|
+
- **New test suites**:
|
|
170
|
+
- `test/configuration_test.rb` - Configuration validation tests
|
|
171
|
+
- `test/working_memory_test.rb` - Working memory operations and eviction tests
|
|
172
|
+
- `test/tag_service_test.rb` - Tag validation and extraction tests
|
|
173
|
+
|
|
174
|
+
### Changed
|
|
175
|
+
- **Wrapped `LongTermMemory#add` in transaction** - Ensures atomicity for node creation
|
|
176
|
+
- **Updated documentation** - Removed outdated TimescaleDB references, added pgvector and async processing info
|
|
177
|
+
- **Defensive copies in WorkingMemory** - Uses `.dup` in `assemble_context` to prevent mutation
|
|
178
|
+
- **Embedding validation** - `Node#similarity_to` validates embedding is array of finite numbers
|
|
179
|
+
|
|
180
|
+
### Fixed
|
|
181
|
+
- **N+1 query in `search_with_relevance`** - Added `batch_load_node_tags` helper
|
|
182
|
+
- **Bare rescue in `get_node_tags`** - Now catches specific `ActiveRecord::RecordNotFound`
|
|
183
|
+
|
|
184
|
+
## [0.0.6] - 2025-11-28
|
|
185
|
+
|
|
186
|
+
### Added
|
|
187
|
+
- **Automatic timeframe extraction from queries** - No LLM required
|
|
188
|
+
- `TimeframeExtractor` service parses natural language time expressions
|
|
189
|
+
- Uses `chronic` gem for robust date/time parsing
|
|
190
|
+
- Supports standard expressions: "yesterday", "last week", "this morning", etc.
|
|
191
|
+
- `FEW` constant (3) maps "few", "a few", "several" to numeric values
|
|
192
|
+
- "recently"/"recent" without units defaults to 3 days
|
|
193
|
+
- Custom weekend handling: "weekend before last", "N weekends ago"
|
|
194
|
+
- Returns cleaned query with temporal expression removed
|
|
195
|
+
- **Flexible `timeframe` parameter in `recall` method** - Multiple input types:
|
|
196
|
+
- `nil` - No time filter (searches all time)
|
|
197
|
+
- `Date` / `DateTime` / `Time` - Entire day (00:00:00 to 23:59:59)
|
|
198
|
+
- `Range` - Exact time window
|
|
199
|
+
- `String` - Natural language parsing via Chronic
|
|
200
|
+
- `:auto` - Extract timeframe from query text automatically
|
|
201
|
+
- `Array<Range>` - Multiple time windows OR'd together
|
|
202
|
+
- **`HTM::Timeframe` normalizer class** - Converts all input types to Range or Array<Range>
|
|
203
|
+
- `Timeframe.normalize(input, query:)` handles all conversions
|
|
204
|
+
- `Timeframe.valid?(input)` validates timeframe input
|
|
205
|
+
- Returns `Result` struct with `:timeframe`, `:query`, `:extracted` when using `:auto`
|
|
206
|
+
- **Configurable week start** - `HTM.configuration.week_start`
|
|
207
|
+
- Options: `:sunday` (default) or `:monday`
|
|
208
|
+
- Passed to Chronic for "last week" and similar expressions
|
|
209
|
+
- **Timeframe demo** - `examples/timeframe_demo.rb` showcasing all input types
|
|
210
|
+
- Run with `rake timeframe_demo`
|
|
211
|
+
- **New rake task**: `rake timeframe_demo` to run the demo
|
|
212
|
+
|
|
213
|
+
### Changed
|
|
214
|
+
- **`recall` method** now accepts all new timeframe input types
|
|
215
|
+
- **`validate_timeframe!`** uses `HTM::Timeframe.valid?` for validation
|
|
216
|
+
- **`LongTermMemory` search methods** support `nil` and `Array<Range>` timeframes
|
|
217
|
+
- `apply_timeframe_scope` handles OR conditions for multiple ranges
|
|
218
|
+
|
|
219
|
+
### Dependencies
|
|
220
|
+
- Added `chronic` gem for natural language date parsing
|
|
221
|
+
|
|
222
|
+
## [0.0.5] - 2025-11-28
|
|
223
|
+
|
|
10
224
|
### Added
|
|
225
|
+
- **Semantic tag matching for queries** - Query tags are now extracted using LLM
|
|
226
|
+
- Uses same `TagService.extract()` process as node storage
|
|
227
|
+
- 3-step search strategy: exact match → prefix match → component match
|
|
228
|
+
- Component matching searches right-to-left (most specific first)
|
|
229
|
+
- Replaces naive keyword substring matching
|
|
230
|
+
- **New rake tasks for database maintenance**:
|
|
231
|
+
- `htm:db:stats` - Show record counts for all HTM tables with breakdowns
|
|
232
|
+
- `htm:db:rebuild:embeddings` - Clear and regenerate all embeddings with progress bar
|
|
233
|
+
- `htm:tags:rebuild` - Clear and regenerate all tags with progress bar
|
|
234
|
+
- **Progress bar support** - Added `ruby-progressbar` gem for long-running rake tasks
|
|
235
|
+
- **CLI demo enhancements** (`examples/cli_app/htm_cli.rb`):
|
|
236
|
+
- Shows extracted tags, searched tags, and matched tags during recall
|
|
237
|
+
- Generates context-aware responses using RubyLLM with Ollama
|
|
238
|
+
- Stores LLM responses in long-term memory for learning
|
|
239
|
+
|
|
240
|
+
### Changed
|
|
241
|
+
- **Improved tag extraction prompt** with CRITICAL CONSTRAINTS to prevent:
|
|
242
|
+
- Circular references (concept at both root and leaf)
|
|
243
|
+
- Self-containment (parent containing itself as descendant)
|
|
244
|
+
- Duplicate segments in hierarchy path
|
|
245
|
+
- Redundant duplicates across branches
|
|
246
|
+
- **TagService validation** now programmatically enforces:
|
|
247
|
+
- Self-containment detection (root == leaf)
|
|
248
|
+
- Duplicate segment detection in hierarchy path
|
|
249
|
+
- Maximum depth reduced from 5 to 4 levels
|
|
250
|
+
- **`find_query_matching_tags` method** completely rewritten:
|
|
251
|
+
- Now uses LLM-based semantic extraction instead of keyword matching
|
|
252
|
+
- Returns both extracted and matched tags via `include_extracted: true` option
|
|
253
|
+
|
|
254
|
+
### Fixed
|
|
255
|
+
- Tag search no longer matches unrelated tags via substring (e.g., "man" matching "management")
|
|
256
|
+
|
|
257
|
+
## [0.0.4] - 2025-11-28
|
|
258
|
+
|
|
259
|
+
### Added
|
|
260
|
+
- **Markdown file loader** - Load markdown files into long-term memory
|
|
261
|
+
- `FileSource` model to track loaded files with metadata and sync status
|
|
262
|
+
- `MarkdownLoader` with YAML frontmatter extraction
|
|
263
|
+
- `ParagraphChunker` for splitting content into semantic chunks
|
|
264
|
+
- DELTA_TIME tolerance (5 seconds) for reliable file change detection
|
|
265
|
+
- **New HTM API methods** for file operations:
|
|
266
|
+
- `htm.load_file(path, force: false)` - Load single markdown file
|
|
267
|
+
- `htm.load_directory(path, pattern: '**/*.md', force: false)` - Load directory
|
|
268
|
+
- `htm.nodes_from_file(path)` - Query nodes from a loaded file
|
|
269
|
+
- `htm.unload_file(path)` - Unload file and soft-delete its chunks
|
|
270
|
+
- **File loading rake tasks**:
|
|
271
|
+
- `htm:files:load[path]` - Load a markdown file
|
|
272
|
+
- `htm:files:load_dir[path,pattern]` - Load directory with glob pattern
|
|
273
|
+
- `htm:files:list` - List all loaded file sources
|
|
274
|
+
- `htm:files:info[path]` - Show details for a loaded file
|
|
275
|
+
- `htm:files:unload[path]` - Unload a file from memory
|
|
276
|
+
- `htm:files:sync` - Re-sync all loaded files (reload changed files)
|
|
277
|
+
- `htm:files:stats` - Show file loading statistics
|
|
278
|
+
- **FileSource model features**:
|
|
279
|
+
- `needs_sync?(mtime)` with DELTA_TIME tolerance for mtime comparison
|
|
280
|
+
- `frontmatter_tags`, `title`, `author` accessors for frontmatter data
|
|
281
|
+
- `soft_delete_chunks!` for bulk soft-delete of associated nodes
|
|
282
|
+
- `by_path` scope for path-based lookups
|
|
283
|
+
- **New example**: `examples/file_loader_usage.rb` demonstrating all file operations
|
|
284
|
+
- **New tests**: FileSource model tests (19) and MarkdownLoader tests (18)
|
|
285
|
+
|
|
286
|
+
### Changed
|
|
287
|
+
- Node model now has optional `source_id` foreign key to FileSource
|
|
288
|
+
- Node model has `chunk_position` column for ordering chunks within a file
|
|
289
|
+
|
|
290
|
+
## [0.0.2] - 2025-11-28
|
|
291
|
+
|
|
292
|
+
### Added
|
|
293
|
+
- **Soft delete for memory nodes** - `forget()` now soft deletes by default (recoverable)
|
|
294
|
+
- `restore(node_id)` to recover soft-deleted nodes
|
|
295
|
+
- `purge_deleted(older_than:, confirm:)` to permanently remove old deleted nodes
|
|
296
|
+
- Permanent delete requires `soft: false, confirm: :confirmed`
|
|
297
|
+
- `deleted_at` column and scopes: `Node.deleted`, `Node.with_deleted`
|
|
298
|
+
- **Tag hierarchy visualization** - Export tag trees in multiple formats
|
|
299
|
+
- `Tag.all.tree` returns nested hash structure
|
|
300
|
+
- `Tag.all.tree_string` returns directory-style text tree
|
|
301
|
+
- `Tag.all.tree_mermaid` generates Mermaid flowchart syntax
|
|
302
|
+
- `Tag.all.tree_svg` generates SVG with dark theme, transparent background
|
|
303
|
+
- Rake tasks: `htm:tags:tree`, `htm:tags:mermaid`, `htm:tags:svg`, `htm:tags:export`
|
|
304
|
+
- All rake tasks accept optional prefix filter parameter
|
|
305
|
+
- **Per-robot working memory persistence** - Optional database-backed working memory
|
|
306
|
+
- New `working_memories` table for state restoration after process restart
|
|
307
|
+
- `WorkingMemoryEntry` model with `sync`, `load`, `clear` methods
|
|
308
|
+
- Enables cross-robot observability in hive mind architecture
|
|
309
|
+
- **Temporal filtering in recall** - Parse timeframe strings (seconds/minutes/hours)
|
|
310
|
+
- **Integration tests** for embeddings, vector search, and recall options
|
|
11
311
|
- **Multi-provider LLM support via RubyLLM** - HTM now supports 9 LLM providers:
|
|
12
312
|
- OpenAI (`text-embedding-3-small`, `gpt-4o-mini`)
|
|
13
313
|
- Anthropic (`claude-3-haiku-20240307`)
|
|
@@ -18,41 +318,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
18
318
|
- OpenRouter
|
|
19
319
|
- AWS Bedrock
|
|
20
320
|
- DeepSeek
|
|
21
|
-
- Provider-specific configuration attributes
|
|
22
|
-
- `openai_api_key`, `openai_organization`, `openai_project`
|
|
23
|
-
- `anthropic_api_key`
|
|
24
|
-
- `gemini_api_key`
|
|
25
|
-
- `azure_api_key`, `azure_endpoint`, `azure_api_version`
|
|
26
|
-
- `ollama_url`
|
|
27
|
-
- `huggingface_api_key`
|
|
28
|
-
- `openrouter_api_key`
|
|
29
|
-
- `bedrock_access_key`, `bedrock_secret_key`, `bedrock_region`
|
|
30
|
-
- `deepseek_api_key`
|
|
321
|
+
- Provider-specific configuration attributes for all supported providers
|
|
31
322
|
- `HTM::Configuration#configure_ruby_llm` method for provider credential setup
|
|
32
323
|
- `SUPPORTED_PROVIDERS` constant listing all available providers
|
|
33
324
|
- `DEFAULT_DIMENSIONS` hash with typical embedding dimensions per provider
|
|
34
325
|
- Architecture documentation using ai-software-architect framework
|
|
35
|
-
- Comprehensive ADRs (Architecture Decision Records)
|
|
36
|
-
- ADR-001: PostgreSQL with TimescaleDB for storage
|
|
37
|
-
- ADR-002: Two-tier memory architecture (working + long-term)
|
|
38
|
-
- ADR-003: Ollama as default embedding provider
|
|
39
|
-
- ADR-004: Multi-robot shared memory (hive mind)
|
|
40
|
-
- ADR-005: RAG-based retrieval with hybrid search
|
|
41
|
-
- ADR-006: Context assembly strategies (recent, important, balanced)
|
|
42
|
-
- ADR-007: Working memory eviction strategy (hybrid importance + recency)
|
|
43
|
-
- ADR-008: Robot identification system (UUID + name)
|
|
44
|
-
- ADR-009: Never-forget philosophy with explicit deletion
|
|
45
|
-
- Architecture review team with 8 specialist perspectives
|
|
46
|
-
- Had the robot convert my notss and system analysis documentation into Architectural Decision Records (ADR)
|
|
326
|
+
- Comprehensive ADRs (Architecture Decision Records) for all major design decisions
|
|
47
327
|
|
|
48
328
|
### Changed
|
|
49
329
|
- **Embedding generator now uses `RubyLLM.embed()`** instead of raw HTTP calls to Ollama
|
|
50
330
|
- **Tag extractor now uses `RubyLLM.chat()`** instead of raw HTTP calls to Ollama
|
|
331
|
+
- **Sinatra integration moved** to `lib/htm/integrations/sinatra.rb` (require path changed)
|
|
332
|
+
- **Hybrid search includes nodes without embeddings** using 0.5 default similarity
|
|
51
333
|
- Configuration validation now checks provider is in `SUPPORTED_PROVIDERS`
|
|
334
|
+
- MkDocs documentation reorganized with tbls schema docs integration
|
|
52
335
|
- Updated CLAUDE.md with multi-provider documentation and examples
|
|
53
|
-
- Environment variables section expanded with all provider API keys
|
|
54
336
|
|
|
55
|
-
|
|
337
|
+
### Removed
|
|
338
|
+
- Unused `nodes.in_working_memory` column (was never set to true)
|
|
339
|
+
- Unused `robots.metadata` column (never referenced in codebase)
|
|
340
|
+
- One-off test scripts replaced with proper Minitest integration tests
|
|
341
|
+
|
|
342
|
+
### Fixed
|
|
343
|
+
- Sinatra session secret error (Rack requires 64+ bytes)
|
|
344
|
+
- Thread-safe database connection in Sinatra integration
|
|
345
|
+
- tbls database documentation rake task configuration
|
|
346
|
+
|
|
347
|
+
## [0.0.1] - 2025-10-25
|
|
56
348
|
|
|
57
349
|
### Added
|
|
58
350
|
- Initial release of HTM (Hierarchical Temporary Memory)
|
|
@@ -176,5 +468,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
176
468
|
- Working memory size is user-configurable
|
|
177
469
|
- See ADRs for detailed architectural decisions and rationale
|
|
178
470
|
|
|
179
|
-
[Unreleased]: https://github.com/madbomber/htm/compare/v0.
|
|
180
|
-
[0.
|
|
471
|
+
[Unreleased]: https://github.com/madbomber/htm/compare/v0.0.12...HEAD
|
|
472
|
+
[0.0.12]: https://github.com/madbomber/htm/compare/v0.0.10...v0.0.12
|
|
473
|
+
[0.0.10]: https://github.com/madbomber/htm/compare/v0.0.9...v0.0.10
|
|
474
|
+
[0.0.9]: https://github.com/madbomber/htm/compare/v0.0.8...v0.0.9
|
|
475
|
+
[0.0.8]: https://github.com/madbomber/htm/compare/v0.0.7...v0.0.8
|
|
476
|
+
[0.0.7]: https://github.com/madbomber/htm/compare/v0.0.6...v0.0.7
|
|
477
|
+
[0.0.6]: https://github.com/madbomber/htm/compare/v0.0.5...v0.0.6
|
|
478
|
+
[0.0.5]: https://github.com/madbomber/htm/compare/v0.0.4...v0.0.5
|
|
479
|
+
[0.0.4]: https://github.com/madbomber/htm/compare/v0.0.2...v0.0.4
|
|
480
|
+
[0.0.2]: https://github.com/madbomber/htm/compare/v0.0.1...v0.0.2
|
|
481
|
+
[0.0.1]: https://github.com/madbomber/htm/releases/tag/v0.0.1
|