htm 0.0.14 → 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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +269 -79
  4. data/db/migrate/00003_create_file_sources.rb +5 -0
  5. data/db/migrate/00004_create_nodes.rb +17 -0
  6. data/db/migrate/00005_create_tags.rb +7 -0
  7. data/db/migrate/00006_create_node_tags.rb +2 -0
  8. data/db/migrate/00007_create_robot_nodes.rb +7 -0
  9. data/db/schema.sql +41 -29
  10. data/docs/api/yard/HTM/Configuration.md +54 -0
  11. data/docs/api/yard/HTM/Database.md +13 -10
  12. data/docs/api/yard/HTM/EmbeddingService.md +5 -1
  13. data/docs/api/yard/HTM/LongTermMemory.md +18 -277
  14. data/docs/api/yard/HTM/PropositionError.md +18 -0
  15. data/docs/api/yard/HTM/PropositionService.md +66 -0
  16. data/docs/api/yard/HTM/QueryCache.md +88 -0
  17. data/docs/api/yard/HTM/RobotGroup.md +481 -0
  18. data/docs/api/yard/HTM/SqlBuilder.md +108 -0
  19. data/docs/api/yard/HTM/TagService.md +4 -0
  20. data/docs/api/yard/HTM/Telemetry/NullInstrument.md +13 -0
  21. data/docs/api/yard/HTM/Telemetry/NullMeter.md +15 -0
  22. data/docs/api/yard/HTM/Telemetry.md +109 -0
  23. data/docs/api/yard/HTM/WorkingMemoryChannel.md +176 -0
  24. data/docs/api/yard/HTM.md +11 -23
  25. data/docs/api/yard/index.csv +102 -25
  26. data/docs/api/yard-reference.md +8 -0
  27. data/docs/assets/images/multi-provider-failover.svg +51 -0
  28. data/docs/assets/images/robot-group-architecture.svg +65 -0
  29. data/docs/database/README.md +3 -3
  30. data/docs/database/public.file_sources.svg +29 -21
  31. data/docs/database/public.node_tags.md +2 -0
  32. data/docs/database/public.node_tags.svg +53 -41
  33. data/docs/database/public.nodes.md +2 -0
  34. data/docs/database/public.nodes.svg +52 -40
  35. data/docs/database/public.robot_nodes.md +2 -0
  36. data/docs/database/public.robot_nodes.svg +30 -22
  37. data/docs/database/public.robots.svg +16 -12
  38. data/docs/database/public.tags.md +3 -0
  39. data/docs/database/public.tags.svg +41 -33
  40. data/docs/database/schema.json +66 -0
  41. data/docs/database/schema.svg +60 -48
  42. data/docs/development/index.md +13 -0
  43. data/docs/development/rake-tasks.md +1068 -0
  44. data/docs/getting-started/quick-start.md +144 -155
  45. data/docs/guides/adding-memories.md +2 -3
  46. data/docs/guides/context-assembly.md +185 -184
  47. data/docs/guides/getting-started.md +154 -148
  48. data/docs/guides/index.md +7 -0
  49. data/docs/guides/long-term-memory.md +60 -92
  50. data/docs/guides/mcp-server.md +617 -0
  51. data/docs/guides/multi-robot.md +249 -345
  52. data/docs/guides/recalling-memories.md +153 -163
  53. data/docs/guides/robot-groups.md +604 -0
  54. data/docs/guides/search-strategies.md +61 -58
  55. data/docs/guides/working-memory.md +103 -136
  56. data/docs/index.md +30 -26
  57. data/examples/robot_groups/robot_worker.rb +1 -2
  58. data/examples/robot_groups/same_process.rb +1 -4
  59. data/lib/htm/robot_group.rb +721 -0
  60. data/lib/htm/version.rb +1 -1
  61. data/lib/htm/working_memory_channel.rb +250 -0
  62. data/lib/htm.rb +2 -0
  63. data/mkdocs.yml +2 -0
  64. metadata +18 -9
  65. data/db/migrate/00009_add_working_memory_to_robot_nodes.rb +0 -12
  66. data/db/migrate/00010_add_soft_delete_to_associations.rb +0 -29
  67. data/db/migrate/00011_add_performance_indexes.rb +0 -21
  68. data/db/migrate/00012_add_tags_trigram_index.rb +0 -18
  69. data/db/migrate/00013_enable_lz4_compression.rb +0 -43
  70. data/examples/robot_groups/lib/robot_group.rb +0 -419
  71. data/examples/robot_groups/lib/working_memory_channel.rb +0 -140
data/db/schema.sql CHANGED
@@ -108,7 +108,7 @@ CREATE TABLE public.node_tags (
108
108
  node_id bigint NOT NULL,
109
109
  tag_id bigint NOT NULL,
110
110
  created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
111
- deleted_at timestamp(6) without time zone
111
+ deleted_at timestamp with time zone
112
112
  );
113
113
 
114
114
  --
@@ -135,6 +135,12 @@ COMMENT ON COLUMN public.node_tags.tag_id IS 'ID of the tag being applied';
135
135
 
136
136
  COMMENT ON COLUMN public.node_tags.created_at IS 'When this association was created';
137
137
 
138
+ --
139
+ -- Name: COLUMN node_tags.deleted_at; Type: COMMENT; Schema: public; Owner: -
140
+ --
141
+
142
+ COMMENT ON COLUMN public.node_tags.deleted_at IS 'Soft delete timestamp';
143
+
138
144
  --
139
145
  -- Name: node_tags_id_seq; Type: SEQUENCE; Schema: public; Owner: -
140
146
  --
@@ -288,10 +294,10 @@ CREATE TABLE public.robot_nodes (
288
294
  first_remembered_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
289
295
  last_remembered_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
290
296
  remember_count integer DEFAULT 1 NOT NULL,
297
+ working_memory boolean DEFAULT false NOT NULL,
291
298
  created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
292
299
  updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
293
- working_memory boolean DEFAULT false NOT NULL,
294
- deleted_at timestamp(6) without time zone
300
+ deleted_at timestamp with time zone
295
301
  );
296
302
 
297
303
  --
@@ -336,6 +342,12 @@ COMMENT ON COLUMN public.robot_nodes.remember_count IS 'Number of times this rob
336
342
 
337
343
  COMMENT ON COLUMN public.robot_nodes.working_memory IS 'True if this node is currently in the robot working memory';
338
344
 
345
+ --
346
+ -- Name: COLUMN robot_nodes.deleted_at; Type: COMMENT; Schema: public; Owner: -
347
+ --
348
+
349
+ COMMENT ON COLUMN public.robot_nodes.deleted_at IS 'Soft delete timestamp';
350
+
339
351
  --
340
352
  -- Name: robot_nodes_id_seq; Type: SEQUENCE; Schema: public; Owner: -
341
353
  --
@@ -421,7 +433,7 @@ CREATE TABLE public.tags (
421
433
  id bigint NOT NULL,
422
434
  name text NOT NULL,
423
435
  created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
424
- deleted_at timestamp(6) without time zone
436
+ deleted_at timestamp with time zone
425
437
  );
426
438
 
427
439
  --
@@ -442,6 +454,12 @@ COMMENT ON COLUMN public.tags.name IS 'Hierarchical tag in format: root:level1:l
442
454
 
443
455
  COMMENT ON COLUMN public.tags.created_at IS 'When this tag was created';
444
456
 
457
+ --
458
+ -- Name: COLUMN tags.deleted_at; Type: COMMENT; Schema: public; Owner: -
459
+ --
460
+
461
+ COMMENT ON COLUMN public.tags.deleted_at IS 'Soft delete timestamp';
462
+
445
463
  --
446
464
  -- Name: tags_id_seq; Type: SEQUENCE; Schema: public; Owner: -
447
465
  --
@@ -562,6 +580,12 @@ CREATE INDEX idx_file_sources_last_synced ON public.file_sources USING btree (la
562
580
 
563
581
  CREATE UNIQUE INDEX idx_file_sources_path_unique ON public.file_sources USING btree (file_path);
564
582
 
583
+ --
584
+ -- Name: idx_node_tags_deleted_at; Type: INDEX; Schema: public; Owner: -
585
+ --
586
+
587
+ CREATE INDEX idx_node_tags_deleted_at ON public.node_tags USING btree (deleted_at);
588
+
565
589
  --
566
590
  -- Name: idx_node_tags_node_id; Type: INDEX; Schema: public; Owner: -
567
591
  --
@@ -592,12 +616,6 @@ CREATE INDEX idx_nodes_access_count ON public.nodes USING btree (access_count);
592
616
 
593
617
  CREATE INDEX idx_nodes_active ON public.nodes USING btree (id) WHERE (deleted_at IS NULL);
594
618
 
595
- --
596
- -- Name: INDEX idx_nodes_active; Type: COMMENT; Schema: public; Owner: -
597
- --
598
-
599
- COMMENT ON INDEX public.idx_nodes_active IS 'Partial index for active (non-deleted) node queries';
600
-
601
619
  --
602
620
  -- Name: idx_nodes_active_with_embedding; Type: INDEX; Schema: public; Owner: -
603
621
  --
@@ -676,6 +694,12 @@ CREATE INDEX idx_nodes_source_id ON public.nodes USING btree (source_id);
676
694
 
677
695
  CREATE INDEX idx_nodes_updated_at ON public.nodes USING btree (updated_at);
678
696
 
697
+ --
698
+ -- Name: idx_robot_nodes_deleted_at; Type: INDEX; Schema: public; Owner: -
699
+ --
700
+
701
+ CREATE INDEX idx_robot_nodes_deleted_at ON public.robot_nodes USING btree (deleted_at);
702
+
679
703
  --
680
704
  -- Name: idx_robot_nodes_last_remembered_at; Type: INDEX; Schema: public; Owner: -
681
705
  --
@@ -706,6 +730,12 @@ CREATE UNIQUE INDEX idx_robot_nodes_unique ON public.robot_nodes USING btree (ro
706
730
 
707
731
  CREATE INDEX idx_robot_nodes_working_memory ON public.robot_nodes USING btree (robot_id, working_memory) WHERE (working_memory = true);
708
732
 
733
+ --
734
+ -- Name: idx_tags_deleted_at; Type: INDEX; Schema: public; Owner: -
735
+ --
736
+
737
+ CREATE INDEX idx_tags_deleted_at ON public.tags USING btree (deleted_at);
738
+
709
739
  --
710
740
  -- Name: idx_tags_name_pattern; Type: INDEX; Schema: public; Owner: -
711
741
  --
@@ -724,24 +754,6 @@ CREATE INDEX idx_tags_name_trgm ON public.tags USING gin (name public.gin_trgm_o
724
754
 
725
755
  CREATE UNIQUE INDEX idx_tags_name_unique ON public.tags USING btree (name);
726
756
 
727
- --
728
- -- Name: index_node_tags_on_deleted_at; Type: INDEX; Schema: public; Owner: -
729
- --
730
-
731
- CREATE INDEX index_node_tags_on_deleted_at ON public.node_tags USING btree (deleted_at);
732
-
733
- --
734
- -- Name: index_robot_nodes_on_deleted_at; Type: INDEX; Schema: public; Owner: -
735
- --
736
-
737
- CREATE INDEX index_robot_nodes_on_deleted_at ON public.robot_nodes USING btree (deleted_at);
738
-
739
- --
740
- -- Name: index_tags_on_deleted_at; Type: INDEX; Schema: public; Owner: -
741
- --
742
-
743
- CREATE INDEX index_tags_on_deleted_at ON public.tags USING btree (deleted_at);
744
-
745
757
  --
746
758
  -- Name: nodes fk_rails_920ad16d08; Type: FK CONSTRAINT; Schema: public; Owner: -
747
759
  --
@@ -781,4 +793,4 @@ ALTER TABLE ONLY public.robot_nodes
781
793
  -- PostgreSQL database dump complete
782
794
  --
783
795
 
784
- \unrestrict bjkKIo8iBhvKUCAsIDDWdDnwALL0oxUsmZVbvgEad6ZmhcLmalGL4Ih7bfe9nlh
796
+ \unrestrict 4WlUqnJzNHaNhcr67XLIIhAvRPidZODUPGkM34l27SvmC0zu6dIsQdJ8dtu589Z
@@ -81,6 +81,21 @@ Returns the value of attribute bedrock_region.
81
81
  ## bedrock_secret_key[RW] {: #attribute-i-bedrock_secret_key }
82
82
  Returns the value of attribute bedrock_secret_key.
83
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
+
84
99
  ## connection_timeout[RW] {: #attribute-i-connection_timeout }
85
100
  Returns the value of attribute connection_timeout.
86
101
 
@@ -102,6 +117,9 @@ Returns the value of attribute embedding_provider.
102
117
  ## embedding_timeout[RW] {: #attribute-i-embedding_timeout }
103
118
  Returns the value of attribute embedding_timeout.
104
119
 
120
+ ## extract_propositions[RW] {: #attribute-i-extract_propositions }
121
+ Returns the value of attribute extract_propositions.
122
+
105
123
  ## gemini_api_key[RW] {: #attribute-i-gemini_api_key }
106
124
  Returns the value of attribute gemini_api_key.
107
125
 
@@ -114,6 +132,12 @@ Returns the value of attribute job_backend.
114
132
  ## logger[RW] {: #attribute-i-logger }
115
133
  Returns the value of attribute logger.
116
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
+
117
141
  ## ollama_url[RW] {: #attribute-i-ollama_url }
118
142
  Returns the value of attribute ollama_url.
119
143
 
@@ -129,6 +153,33 @@ Provider-specific API keys and endpoints
129
153
  ## openrouter_api_key[RW] {: #attribute-i-openrouter_api_key }
130
154
  Returns the value of attribute openrouter_api_key.
131
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
+
132
183
  ## tag_extractor[RW] {: #attribute-i-tag_extractor }
133
184
  Returns the value of attribute tag_extractor.
134
185
 
@@ -141,6 +192,9 @@ Returns the value of attribute tag_provider.
141
192
  ## tag_timeout[RW] {: #attribute-i-tag_timeout }
142
193
  Returns the value of attribute tag_timeout.
143
194
 
195
+ ## telemetry_enabled[RW] {: #attribute-i-telemetry_enabled }
196
+ Enable OpenTelemetry metrics (default: false)
197
+
144
198
  ## token_counter[RW] {: #attribute-i-token_counter }
145
199
  Returns the value of attribute token_counter.
146
200
 
@@ -8,20 +8,23 @@ initialization
8
8
 
9
9
  # Class Methods
10
10
  ## default_config() {: #method-c-default_config }
11
- Get default database configuration
12
- **`@return`** [Hash, nil] Connection configuration hash
11
+ Get default database configuration (respects RAILS_ENV)
12
+
13
+ Uses ActiveRecordConfig which reads from config/database.yml and respects
14
+ RAILS_ENV for environment-specific database selection.
15
+ **`@return`** [Hash, nil] Connection configuration hash with PG-style keys
13
16
 
14
17
  ## drop(db_url nil) {: #method-c-drop }
15
- Drop all HTM tables
16
- **`@param`** [String] Database connection URL (uses ENV['HTM_DBURL'] if not provided)
18
+ Drop all HTM tables (respects RAILS_ENV)
19
+ **`@param`** [String] Database connection URL (uses default_config if not provided)
17
20
 
18
21
  **`@return`** [void]
19
22
 
20
23
  ## dump_schema(db_url nil) {: #method-c-dump_schema }
21
- Dump current database schema to db/schema.sql
24
+ Dump current database schema to db/schema.sql (respects RAILS_ENV)
22
25
 
23
26
  Uses pg_dump to create a clean SQL schema file without data
24
- **`@param`** [String] Database connection URL (uses ENV['HTM_DBURL'] if not provided)
27
+ **`@param`** [String] Database connection URL (uses default_config if not provided)
25
28
 
26
29
  **`@return`** [void]
27
30
 
@@ -39,16 +42,16 @@ comprehensive database documentation including:
39
42
  **`@return`** [void]
40
43
 
41
44
  ## info(db_url nil) {: #method-c-info }
42
- Show database info
43
- **`@param`** [String] Database connection URL (uses ENV['HTM_DBURL'] if not provided)
45
+ Show database info (respects RAILS_ENV)
46
+ **`@param`** [String] Database connection URL (uses default_config if not provided)
44
47
 
45
48
  **`@return`** [void]
46
49
 
47
50
  ## load_schema(db_url nil) {: #method-c-load_schema }
48
- Load schema from db/schema.sql
51
+ Load schema from db/schema.sql (respects RAILS_ENV)
49
52
 
50
53
  Uses psql to load the schema file
51
- **`@param`** [String] Database connection URL (uses ENV['HTM_DBURL'] if not provided)
54
+ **`@param`** [String] Database connection URL (uses default_config if not provided)
52
55
 
53
56
  **`@return`** [void]
54
57
 
@@ -39,8 +39,12 @@ Generate embedding with validation and processing
39
39
  storage_dimension: Integer # Padded dimension (2000)
40
40
  }
41
41
 
42
+ ## max_dimension() {: #method-c-max_dimension }
43
+ Maximum embedding dimension (configurable, default 2000)
44
+ **`@return`** [Integer] Max dimensions for pgvector HNSW index
45
+
42
46
  ## pad_embedding(embedding ) {: #method-c-pad_embedding }
43
- Pad embedding to MAX_DIMENSION with zeros
47
+ Pad embedding to max_dimension with zeros
44
48
  **`@param`** [Array<Float>] Original embedding
45
49
 
46
50
  **`@return`** [Array<Float>] Padded embedding
@@ -1,6 +1,8 @@
1
1
  # Class: HTM::LongTermMemory
2
2
  **Inherits:** Object
3
3
 
4
+ **Includes:** FulltextSearch, HybridSearch, NodeOperations, RelevanceScorer, RobotOperations, TagOperations, VectorSearch
5
+
4
6
 
5
7
  Long-term Memory - PostgreSQL/TimescaleDB-backed permanent storage
6
8
 
@@ -13,6 +15,21 @@ LongTermMemory provides durable storage for all memory nodes with:
13
15
  * ActiveRecord ORM for data access
14
16
  * Query result caching for efficiency
15
17
 
18
+ This class uses standalone utility classes and modules:
19
+
20
+ Standalone classes (used via class methods or instances):
21
+ * HTM::SqlBuilder: SQL condition building helpers (class methods)
22
+ * HTM::QueryCache: Query result caching (instantiated as @cache)
23
+
24
+ Included modules:
25
+ * RelevanceScorer: Dynamic relevance scoring
26
+ * NodeOperations: Node CRUD operations
27
+ * RobotOperations: Robot registration and activity
28
+ * TagOperations: Tag management
29
+ * VectorSearch: Vector similarity search
30
+ * FulltextSearch: Full-text search
31
+ * HybridSearch: Combined search strategies
32
+
16
33
 
17
34
  # Attributes
18
35
  ## query_timeout[RW] {: #attribute-i-query_timeout }
@@ -20,104 +37,11 @@ Returns the value of attribute query_timeout.
20
37
 
21
38
 
22
39
  # Instance Methods
23
- ## add(content:, token_count:0, robot_id:, embedding:nil, metadata:{}) {: #method-i-add }
24
- Add a node to long-term memory (with deduplication)
25
-
26
- If content already exists (by content_hash), links the robot to the existing
27
- node and updates timestamps. Otherwise creates a new node.
28
-
29
- **`@param`** [String] Conversation message/utterance
30
-
31
- **`@param`** [Integer] Token count
32
-
33
- **`@param`** [Integer] Robot identifier
34
-
35
- **`@param`** [Array<Float>, nil] Pre-generated embedding vector
36
-
37
- **`@param`** [Hash] Flexible metadata for the node (default: {})
38
-
39
- **`@return`** [Hash] { node_id:, is_new:, robot_node: }
40
-
41
- ## add_tag(node_id:, tag:) {: #method-i-add_tag }
42
- Add a tag to a node
43
-
44
- **`@param`** [Integer] Node database ID
45
-
46
- **`@param`** [String] Tag name
47
-
48
- **`@return`** [void]
49
-
50
- ## batch_load_node_tags(node_ids) {: #method-i-batch_load_node_tags }
51
- Batch load tags for multiple nodes (avoids N+1 queries)
52
-
53
- **`@param`** [Array<Integer>] Node database IDs
54
-
55
- **`@return`** [Hash<Integer, Array<String>>] Map of node_id to array of tag names
56
-
57
- ## calculate_relevance(node:, query_tags:[], vector_similarity:nil, node_tags:nil) {: #method-i-calculate_relevance }
58
- Calculate dynamic relevance score for a node given query context
59
-
60
- Combines multiple signals:
61
- * Vector similarity (semantic match)
62
- * Tag overlap (categorical match)
63
- * Recency (freshness)
64
- * Access frequency (popularity/utility)
65
-
66
- **`@param`** [Hash] Node data with similarity, tags, created_at, access_count
67
-
68
- **`@param`** [Array<String>] Tags associated with the query
69
-
70
- **`@param`** [Float, nil] Pre-computed vector similarity (0-1)
71
-
72
- **`@param`** [Array<String>, nil] Pre-loaded tags for this node (avoids N+1 query)
73
-
74
- **`@return`** [Float] Composite relevance score (0-10)
75
-
76
40
  ## clear_cache!() {: #method-i-clear_cache! }
77
- Clear the query cache
78
-
79
- Call this after any operation that modifies data (soft delete, restore, etc.)
80
- to ensure subsequent queries see fresh results.
81
-
82
- **`@return`** [void]
83
-
84
- ## delete(node_id) {: #method-i-delete }
85
- Delete a node
86
-
87
- **`@param`** [Integer] Node database ID
41
+ Clear the query result cache
88
42
 
89
43
  **`@return`** [void]
90
44
 
91
- ## exists?(node_id) {: #method-i-exists? }
92
- Check if a node exists
93
-
94
- **`@param`** [Integer] Node database ID
95
-
96
- **`@return`** [Boolean] True if node exists
97
-
98
- ## find_query_matching_tags(query, include_extracted:false) {: #method-i-find_query_matching_tags }
99
- Find tags that match terms in the query
100
-
101
- Searches the tags table for tags where any hierarchy level matches query
102
- words. For example, query "PostgreSQL database" would match tags like
103
- "database:postgresql", "database:sql", etc. Find tags matching a query using
104
- semantic extraction
105
-
106
- **`@param`** [String] Search query
107
-
108
- **`@param`** [Boolean] If true, returns hash with :extracted and :matched keys
109
-
110
- **`@return`** [Array<String>] Matching tag names (default)
111
-
112
- **`@return`** [Hash] If include_extracted: { extracted: [...], matched: [...] }
113
-
114
- ## get_node_tags(node_id) {: #method-i-get_node_tags }
115
- Get tags for a specific node
116
-
117
- **`@param`** [Integer] Node database ID
118
-
119
- **`@return`** [Array<String>] Tag names
120
-
121
45
  ## initialize(config, pool_size:nil, query_timeout:DEFAULT_QUERY_TIMEOUT, cache_size:DEFAULT_CACHE_SIZE, cache_ttl:DEFAULT_CACHE_TTL) {: #method-i-initialize }
122
46
  Initialize long-term memory storage
123
47
 
@@ -146,160 +70,9 @@ ltm = LongTermMemory.new(config, cache_size: 500, cache_ttl: 600)
146
70
  ```ruby
147
71
  ltm = LongTermMemory.new(config, cache_size: 0)
148
72
  ```
149
- ## link_robot_to_node(robot_id:, node:, working_memory:false) {: #method-i-link_robot_to_node }
150
- Link a robot to a node (create or update robot_node record)
151
-
152
- **`@param`** [Integer] Robot ID
153
-
154
- **`@param`** [HTM::Models::Node] Node to link
155
-
156
- **`@param`** [Boolean] Whether node is in working memory (default: false)
157
-
158
- **`@return`** [HTM::Models::RobotNode] The robot_node link record
159
-
160
- ## mark_evicted(robot_id:, node_ids:) {: #method-i-mark_evicted }
161
- Mark nodes as evicted from working memory
162
-
163
- Sets working_memory = false on the robot_nodes join table for the specified
164
- robot and node IDs.
165
-
166
- **`@param`** [Integer] Robot ID whose working memory is being evicted
167
-
168
- **`@param`** [Array<Integer>] Node IDs to mark as evicted
169
-
170
- **`@return`** [void]
171
-
172
- ## node_topics(node_id) {: #method-i-node_topics }
173
- Get topics for a specific node
174
-
175
- **`@param`** [Integer] Node database ID
176
-
177
- **`@return`** [Array<String>] Topic paths
178
-
179
- ## nodes_by_topic(topic_path, exact:false, limit:50) {: #method-i-nodes_by_topic }
180
- Retrieve nodes by ontological topic
181
-
182
- **`@param`** [String] Topic hierarchy path
183
-
184
- **`@param`** [Boolean] Exact match or prefix match
185
-
186
- **`@param`** [Integer] Maximum results
187
-
188
- **`@return`** [Array<Hash>] Matching nodes
189
-
190
- ## ontology_structure() {: #method-i-ontology_structure }
191
- Get ontology structure view
192
-
193
- **`@return`** [Array<Hash>] Ontology structure
194
-
195
73
  ## pool_size() {: #method-i-pool_size }
196
74
  For backwards compatibility with tests/code that expect pool_size
197
75
 
198
- ## popular_tags(limit:20, timeframe:nil) {: #method-i-popular_tags }
199
- Get most popular tags
200
-
201
- **`@param`** [Integer] Number of tags to return
202
-
203
- **`@param`** [Range, nil] Optional time range filter
204
-
205
- **`@return`** [Array<Hash>] Tags with usage counts
206
-
207
- ## register_robot(robot_name) {: #method-i-register_robot }
208
- Register a robot
209
-
210
- **`@param`** [String] Robot identifier
211
-
212
- **`@param`** [String] Robot name
213
-
214
- **`@return`** [void]
215
-
216
- ## retrieve(node_id) {: #method-i-retrieve }
217
- Retrieve a node by ID
218
-
219
- Automatically tracks access by incrementing access_count and updating
220
- last_accessed
221
-
222
- **`@param`** [Integer] Node database ID
223
-
224
- **`@return`** [Hash, nil] Node data or nil
225
-
226
- ## search(timeframe:, query:, limit:, embedding_service:, metadata:{}) {: #method-i-search }
227
- Vector similarity search
228
-
229
- **`@param`** [nil, Range, Array<Range>] Time range(s) to search (nil = no filter)
230
-
231
- **`@param`** [String] Search query
232
-
233
- **`@param`** [Integer] Maximum results
234
-
235
- **`@param`** [Object] Service to generate embeddings
236
-
237
- **`@param`** [Hash] Filter by metadata fields (default: {})
238
-
239
- **`@return`** [Array<Hash>] Matching nodes
240
-
241
- ## search_by_tags(tags:, match_all:false, timeframe:nil, limit:20) {: #method-i-search_by_tags }
242
- Search nodes by tags
243
-
244
- **`@param`** [Array<String>] Tags to search for
245
-
246
- **`@param`** [Boolean] If true, match ALL tags; if false, match ANY tag
247
-
248
- **`@param`** [Range, nil] Optional time range filter
249
-
250
- **`@param`** [Integer] Maximum results
251
-
252
- **`@return`** [Array<Hash>] Matching nodes with relevance scores
253
-
254
- ## search_fulltext(timeframe:, query:, limit:, metadata:{}) {: #method-i-search_fulltext }
255
- Full-text search
256
-
257
- **`@param`** [Range] Time range to search
258
-
259
- **`@param`** [String] Search query
260
-
261
- **`@param`** [Integer] Maximum results
262
-
263
- **`@param`** [Hash] Filter by metadata fields (default: {})
264
-
265
- **`@return`** [Array<Hash>] Matching nodes
266
-
267
- ## search_hybrid(timeframe:, query:, limit:, embedding_service:, prefilter_limit:100, metadata:{}) {: #method-i-search_hybrid }
268
- Hybrid search (full-text + vector)
269
-
270
- **`@param`** [Range] Time range to search
271
-
272
- **`@param`** [String] Search query
273
-
274
- **`@param`** [Integer] Maximum results
275
-
276
- **`@param`** [Object] Service to generate embeddings
277
-
278
- **`@param`** [Integer] Candidates to consider (default: 100)
279
-
280
- **`@param`** [Hash] Filter by metadata fields (default: {})
281
-
282
- **`@return`** [Array<Hash>] Matching nodes
283
-
284
- ## search_with_relevance(timeframe:, query:nil, query_tags:[], limit:20, embedding_service:nil, metadata:{}) {: #method-i-search_with_relevance }
285
- Search with dynamic relevance scoring
286
-
287
- Returns nodes with calculated relevance scores based on query context
288
-
289
- **`@param`** [nil, Range, Array<Range>] Time range(s) to search (nil = no filter)
290
-
291
- **`@param`** [String, nil] Search query
292
-
293
- **`@param`** [Array<String>] Tags to match
294
-
295
- **`@param`** [Integer] Maximum results
296
-
297
- **`@param`** [Object, nil] Service to generate embeddings
298
-
299
- **`@param`** [Hash] Filter by metadata fields (default: {})
300
-
301
- **`@return`** [Array<Hash>] Nodes with relevance scores
302
-
303
76
  ## shutdown() {: #method-i-shutdown }
304
77
  Shutdown - no-op with ActiveRecord (connection pool managed by ActiveRecord)
305
78
 
@@ -308,35 +81,3 @@ Get memory statistics
308
81
 
309
82
  **`@return`** [Hash] Statistics
310
83
 
311
- ## topic_relationships(min_shared_nodes:2, limit:50) {: #method-i-topic_relationships }
312
- Get topic relationships (co-occurrence)
313
-
314
- **`@param`** [Integer] Minimum shared nodes
315
-
316
- **`@param`** [Integer] Maximum relationships
317
-
318
- **`@return`** [Array<Hash>] Topic relationships
319
-
320
- ## track_access(node_ids) {: #method-i-track_access }
321
- Track access for multiple nodes (bulk operation)
322
-
323
- Updates access_count and last_accessed for all nodes in the array
324
-
325
- **`@param`** [Array<Integer>] Node IDs that were accessed
326
-
327
- **`@return`** [void]
328
-
329
- ## update_last_accessed(node_id) {: #method-i-update_last_accessed }
330
- Update last_accessed timestamp
331
-
332
- **`@param`** [Integer] Node database ID
333
-
334
- **`@return`** [void]
335
-
336
- ## update_robot_activity(robot_id) {: #method-i-update_robot_activity }
337
- Update robot activity timestamp
338
-
339
- **`@param`** [String] Robot identifier
340
-
341
- **`@return`** [void]
342
-
@@ -0,0 +1,18 @@
1
+ # Exception: HTM::PropositionError
2
+ **Inherits:** HTM::Error
3
+
4
+
5
+ Raised when proposition extraction fails
6
+
7
+ Common causes:
8
+ * LLM provider API errors
9
+ * Invalid proposition response format
10
+ * Network connectivity issues
11
+ * Model not available
12
+
13
+ Note: This error is distinct from CircuitBreakerOpenError. PropositionError
14
+ indicates a single failure, while CircuitBreakerOpenError indicates repeated
15
+ failures have triggered protective circuit breaking.
16
+
17
+
18
+