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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/README.md +269 -79
- data/db/migrate/00003_create_file_sources.rb +5 -0
- data/db/migrate/00004_create_nodes.rb +17 -0
- data/db/migrate/00005_create_tags.rb +7 -0
- data/db/migrate/00006_create_node_tags.rb +2 -0
- data/db/migrate/00007_create_robot_nodes.rb +7 -0
- data/db/schema.sql +41 -29
- data/docs/api/yard/HTM/Configuration.md +54 -0
- data/docs/api/yard/HTM/Database.md +13 -10
- data/docs/api/yard/HTM/EmbeddingService.md +5 -1
- data/docs/api/yard/HTM/LongTermMemory.md +18 -277
- data/docs/api/yard/HTM/PropositionError.md +18 -0
- data/docs/api/yard/HTM/PropositionService.md +66 -0
- data/docs/api/yard/HTM/QueryCache.md +88 -0
- data/docs/api/yard/HTM/RobotGroup.md +481 -0
- data/docs/api/yard/HTM/SqlBuilder.md +108 -0
- data/docs/api/yard/HTM/TagService.md +4 -0
- data/docs/api/yard/HTM/Telemetry/NullInstrument.md +13 -0
- data/docs/api/yard/HTM/Telemetry/NullMeter.md +15 -0
- data/docs/api/yard/HTM/Telemetry.md +109 -0
- data/docs/api/yard/HTM/WorkingMemoryChannel.md +176 -0
- data/docs/api/yard/HTM.md +11 -23
- data/docs/api/yard/index.csv +102 -25
- data/docs/api/yard-reference.md +8 -0
- data/docs/assets/images/multi-provider-failover.svg +51 -0
- data/docs/assets/images/robot-group-architecture.svg +65 -0
- data/docs/database/README.md +3 -3
- data/docs/database/public.file_sources.svg +29 -21
- data/docs/database/public.node_tags.md +2 -0
- data/docs/database/public.node_tags.svg +53 -41
- data/docs/database/public.nodes.md +2 -0
- data/docs/database/public.nodes.svg +52 -40
- data/docs/database/public.robot_nodes.md +2 -0
- data/docs/database/public.robot_nodes.svg +30 -22
- data/docs/database/public.robots.svg +16 -12
- data/docs/database/public.tags.md +3 -0
- data/docs/database/public.tags.svg +41 -33
- data/docs/database/schema.json +66 -0
- data/docs/database/schema.svg +60 -48
- data/docs/development/index.md +13 -0
- data/docs/development/rake-tasks.md +1068 -0
- data/docs/getting-started/quick-start.md +144 -155
- data/docs/guides/adding-memories.md +2 -3
- data/docs/guides/context-assembly.md +185 -184
- data/docs/guides/getting-started.md +154 -148
- data/docs/guides/index.md +7 -0
- data/docs/guides/long-term-memory.md +60 -92
- data/docs/guides/mcp-server.md +617 -0
- data/docs/guides/multi-robot.md +249 -345
- data/docs/guides/recalling-memories.md +153 -163
- data/docs/guides/robot-groups.md +604 -0
- data/docs/guides/search-strategies.md +61 -58
- data/docs/guides/working-memory.md +103 -136
- data/docs/index.md +30 -26
- data/examples/robot_groups/robot_worker.rb +1 -2
- data/examples/robot_groups/same_process.rb +1 -4
- data/lib/htm/robot_group.rb +721 -0
- data/lib/htm/version.rb +1 -1
- data/lib/htm/working_memory_channel.rb +250 -0
- data/lib/htm.rb +2 -0
- data/mkdocs.yml +2 -0
- metadata +18 -9
- data/db/migrate/00009_add_working_memory_to_robot_nodes.rb +0 -12
- data/db/migrate/00010_add_soft_delete_to_associations.rb +0 -29
- data/db/migrate/00011_add_performance_indexes.rb +0 -21
- data/db/migrate/00012_add_tags_trigram_index.rb +0 -18
- data/db/migrate/00013_enable_lz4_compression.rb +0 -43
- data/examples/robot_groups/lib/robot_group.rb +0 -419
- data/examples/robot_groups/lib/working_memory_channel.rb +0 -140
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Class: HTM::SqlBuilder
|
|
2
|
+
**Inherits:** Object
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
SQL building utilities for constructing safe, parameterized queries
|
|
6
|
+
|
|
7
|
+
Provides class methods for building SQL conditions for:
|
|
8
|
+
* Timeframe filtering (single range or multiple ranges)
|
|
9
|
+
* Metadata filtering (JSONB containment)
|
|
10
|
+
* Embedding sanitization and padding (SQL injection prevention)
|
|
11
|
+
* LIKE pattern sanitization (wildcard injection prevention)
|
|
12
|
+
|
|
13
|
+
All methods use proper escaping and parameterization to prevent SQL injection.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
**`@example`**
|
|
17
|
+
```ruby
|
|
18
|
+
HTM::SqlBuilder.timeframe_condition(1.week.ago..Time.now)
|
|
19
|
+
# => "(created_at BETWEEN '2024-01-01' AND '2024-01-08')"
|
|
20
|
+
```
|
|
21
|
+
**`@example`**
|
|
22
|
+
```ruby
|
|
23
|
+
HTM::SqlBuilder.metadata_condition({ priority: "high" })
|
|
24
|
+
# => "(metadata @> '{\"priority\":\"high\"}'::jsonb)"
|
|
25
|
+
```
|
|
26
|
+
**`@example`**
|
|
27
|
+
```ruby
|
|
28
|
+
HTM::SqlBuilder.sanitize_embedding([0.1, 0.2, 0.3])
|
|
29
|
+
# => "[0.1,0.2,0.3]"
|
|
30
|
+
```
|
|
31
|
+
**`@example`**
|
|
32
|
+
```ruby
|
|
33
|
+
HTM::SqlBuilder.sanitize_like_pattern("test%pattern")
|
|
34
|
+
# => "test\\%pattern"
|
|
35
|
+
```
|
|
36
|
+
# Class Methods
|
|
37
|
+
## apply_metadata(scope , metadata , column: "metadata") {: #method-c-apply_metadata }
|
|
38
|
+
Apply metadata filter to ActiveRecord scope
|
|
39
|
+
**`@param`** [ActiveRecord::Relation] Base scope
|
|
40
|
+
|
|
41
|
+
**`@param`** [Hash] Metadata to filter by
|
|
42
|
+
|
|
43
|
+
**`@param`** [String] Column name (default: "metadata")
|
|
44
|
+
|
|
45
|
+
**`@return`** [ActiveRecord::Relation] Scoped query
|
|
46
|
+
|
|
47
|
+
## apply_timeframe(scope , timeframe , column: :created_at) {: #method-c-apply_timeframe }
|
|
48
|
+
Apply timeframe filter to ActiveRecord scope
|
|
49
|
+
**`@param`** [ActiveRecord::Relation] Base scope
|
|
50
|
+
|
|
51
|
+
**`@param`** [nil, Range, Array<Range>] Time range(s)
|
|
52
|
+
|
|
53
|
+
**`@param`** [Symbol] Column name (default: :created_at)
|
|
54
|
+
|
|
55
|
+
**`@return`** [ActiveRecord::Relation] Scoped query
|
|
56
|
+
|
|
57
|
+
## metadata_condition(metadata , table_alias: nil, column: "metadata") {: #method-c-metadata_condition }
|
|
58
|
+
Build SQL condition for metadata filtering (JSONB containment)
|
|
59
|
+
**`@param`** [Hash] Metadata to filter by
|
|
60
|
+
|
|
61
|
+
**`@param`** [String, nil] Table alias (default: none)
|
|
62
|
+
|
|
63
|
+
**`@param`** [String] Column name (default: "metadata")
|
|
64
|
+
|
|
65
|
+
**`@return`** [String, nil] SQL condition or nil for no filter
|
|
66
|
+
|
|
67
|
+
## pad_embedding(embedding , target_dimension: MAX_EMBEDDING_DIMENSION) {: #method-c-pad_embedding }
|
|
68
|
+
Pad embedding to target dimension
|
|
69
|
+
|
|
70
|
+
Pads embedding with zeros to reach the target dimension for pgvector
|
|
71
|
+
compatibility.
|
|
72
|
+
**`@param`** [Array<Numeric>] Embedding vector
|
|
73
|
+
|
|
74
|
+
**`@param`** [Integer] Target dimension (default: MAX_EMBEDDING_DIMENSION)
|
|
75
|
+
|
|
76
|
+
**`@return`** [Array<Numeric>] Padded embedding
|
|
77
|
+
|
|
78
|
+
## sanitize_embedding(embedding ) {: #method-c-sanitize_embedding }
|
|
79
|
+
Sanitize embedding for SQL use
|
|
80
|
+
|
|
81
|
+
Validates that all values are numeric and converts to safe PostgreSQL vector
|
|
82
|
+
format. This prevents SQL injection by ensuring only valid numeric values are
|
|
83
|
+
included.
|
|
84
|
+
**`@param`** [Array<Numeric>] Embedding vector
|
|
85
|
+
|
|
86
|
+
**`@raise`** [ArgumentError] If embedding contains non-numeric values
|
|
87
|
+
|
|
88
|
+
**`@return`** [String] Sanitized vector string for PostgreSQL (e.g., "[0.1,0.2,0.3]")
|
|
89
|
+
|
|
90
|
+
## sanitize_like_pattern(pattern ) {: #method-c-sanitize_like_pattern }
|
|
91
|
+
Sanitize a string for use in SQL LIKE patterns
|
|
92
|
+
|
|
93
|
+
Escapes SQL LIKE wildcards (% and _) to prevent pattern injection.
|
|
94
|
+
**`@param`** [String] Pattern to sanitize
|
|
95
|
+
|
|
96
|
+
**`@return`** [String] Sanitized pattern safe for LIKE queries
|
|
97
|
+
|
|
98
|
+
## timeframe_condition(timeframe , table_alias: nil, column: "created_at") {: #method-c-timeframe_condition }
|
|
99
|
+
Build SQL condition for timeframe filtering
|
|
100
|
+
**`@param`** [nil, Range, Array<Range>] Time range(s)
|
|
101
|
+
|
|
102
|
+
**`@param`** [String, nil] Table alias (default: none)
|
|
103
|
+
|
|
104
|
+
**`@param`** [String] Column name (default: "created_at")
|
|
105
|
+
|
|
106
|
+
**`@return`** [String, nil] SQL condition or nil for no filter
|
|
107
|
+
|
|
108
|
+
|
|
@@ -29,6 +29,10 @@ Extract tags with validation and processing
|
|
|
29
29
|
|
|
30
30
|
**`@return`** [Array<String>] Validated tag names
|
|
31
31
|
|
|
32
|
+
## max_depth() {: #method-c-max_depth }
|
|
33
|
+
Maximum tag hierarchy depth (configurable, default 4)
|
|
34
|
+
**`@return`** [Integer] Max depth (3 colons max by default)
|
|
35
|
+
|
|
32
36
|
## parse_hierarchy(tag ) {: #method-c-parse_hierarchy }
|
|
33
37
|
Parse hierarchical structure of a tag
|
|
34
38
|
**`@param`** [String] Hierarchical tag (e.g., "ai:llm:embedding")
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Class: HTM::Telemetry::NullInstrument
|
|
2
|
+
**Inherits:** Object
|
|
3
|
+
|
|
4
|
+
**Includes:** Singleton
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Null instrument that accepts but ignores all metric operations
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Instance Methods
|
|
12
|
+
## add() {: #method-i-add }
|
|
13
|
+
## record() {: #method-i-record }
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Class: HTM::Telemetry::NullMeter
|
|
2
|
+
**Inherits:** Object
|
|
3
|
+
|
|
4
|
+
**Includes:** Singleton
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Null meter that creates null instruments Used when telemetry is disabled or
|
|
8
|
+
SDK unavailable
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Instance Methods
|
|
13
|
+
## create_counter() {: #method-i-create_counter }
|
|
14
|
+
## create_histogram() {: #method-i-create_histogram }
|
|
15
|
+
## create_up_down_counter() {: #method-i-create_up_down_counter }
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Module: HTM::Telemetry
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
OpenTelemetry-based observability for HTM
|
|
5
|
+
|
|
6
|
+
Provides opt-in metrics collection with zero overhead when disabled. Uses the
|
|
7
|
+
null object pattern - when telemetry is disabled or the SDK is not available,
|
|
8
|
+
all metric operations are no-ops.
|
|
9
|
+
|
|
10
|
+
**`@see`** [] for full implementation details
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
**`@example`**
|
|
14
|
+
```ruby
|
|
15
|
+
HTM.configure do |config|
|
|
16
|
+
config.telemetry_enabled = true
|
|
17
|
+
end
|
|
18
|
+
```
|
|
19
|
+
**`@example`**
|
|
20
|
+
```ruby
|
|
21
|
+
# Export to OTLP endpoint
|
|
22
|
+
ENV['OTEL_METRICS_EXPORTER'] = 'otlp'
|
|
23
|
+
ENV['OTEL_EXPORTER_OTLP_ENDPOINT'] = 'http://localhost:4318'
|
|
24
|
+
```
|
|
25
|
+
# Class Methods
|
|
26
|
+
## cache_operations() {: #method-c-cache_operations }
|
|
27
|
+
Counter for cache operations (hits, misses)
|
|
28
|
+
**`@return`** [OpenTelemetry::Metrics::Counter, NullInstrument]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
**`@example`**
|
|
32
|
+
```ruby
|
|
33
|
+
Telemetry.cache_operations.add(1, attributes: { 'operation' => 'hit' })
|
|
34
|
+
```
|
|
35
|
+
## embedding_latency() {: #method-c-embedding_latency }
|
|
36
|
+
Histogram for embedding generation latency
|
|
37
|
+
**`@return`** [OpenTelemetry::Metrics::Histogram, NullInstrument]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
**`@example`**
|
|
41
|
+
```ruby
|
|
42
|
+
Telemetry.embedding_latency.record(145, attributes: { 'provider' => 'ollama', 'status' => 'success' })
|
|
43
|
+
```
|
|
44
|
+
## enabled?() {: #method-c-enabled? }
|
|
45
|
+
Check if telemetry is enabled and SDK is available
|
|
46
|
+
**`@return`** [Boolean] true if telemetry should be active
|
|
47
|
+
|
|
48
|
+
## job_counter() {: #method-c-job_counter }
|
|
49
|
+
Counter for job execution (enqueued, completed, failed)
|
|
50
|
+
**`@return`** [OpenTelemetry::Metrics::Counter, NullInstrument]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
**`@example`**
|
|
54
|
+
```ruby
|
|
55
|
+
Telemetry.job_counter.add(1, attributes: { 'job' => 'embedding', 'status' => 'success' })
|
|
56
|
+
```
|
|
57
|
+
## measure(histogram , attributes {}) {: #method-c-measure }
|
|
58
|
+
Measure execution time of a block and record to a histogram
|
|
59
|
+
**`@param`** [OpenTelemetry::Metrics::Histogram, NullInstrument] The histogram to record to
|
|
60
|
+
|
|
61
|
+
**`@param`** [Hash] Attributes to attach to the measurement
|
|
62
|
+
|
|
63
|
+
**`@return`** [Object] The result of the block
|
|
64
|
+
|
|
65
|
+
**`@yield`** [] The block to measure
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
**`@example`**
|
|
69
|
+
```ruby
|
|
70
|
+
result = Telemetry.measure(Telemetry.embedding_latency, 'provider' => 'ollama') do
|
|
71
|
+
generate_embedding(text)
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
## meter() {: #method-c-meter }
|
|
75
|
+
Get the meter for creating instruments
|
|
76
|
+
**`@return`** [OpenTelemetry::Metrics::Meter, NullMeter] Real or null meter
|
|
77
|
+
|
|
78
|
+
## reset!() {: #method-c-reset! }
|
|
79
|
+
Reset telemetry state (for testing)
|
|
80
|
+
**`@return`** [void]
|
|
81
|
+
|
|
82
|
+
## sdk_available?() {: #method-c-sdk_available? }
|
|
83
|
+
Check if OpenTelemetry SDK is installed
|
|
84
|
+
**`@return`** [Boolean] true if SDK can be loaded
|
|
85
|
+
|
|
86
|
+
## search_latency() {: #method-c-search_latency }
|
|
87
|
+
Histogram for search operation latency
|
|
88
|
+
**`@return`** [OpenTelemetry::Metrics::Histogram, NullInstrument]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
**`@example`**
|
|
92
|
+
```ruby
|
|
93
|
+
Telemetry.search_latency.record(50, attributes: { 'strategy' => 'vector' })
|
|
94
|
+
```
|
|
95
|
+
## setup() {: #method-c-setup }
|
|
96
|
+
Initialize OpenTelemetry SDK
|
|
97
|
+
|
|
98
|
+
Called automatically when telemetry is enabled. Safe to call multiple times.
|
|
99
|
+
**`@return`** [void]
|
|
100
|
+
|
|
101
|
+
## tag_latency() {: #method-c-tag_latency }
|
|
102
|
+
Histogram for tag extraction latency
|
|
103
|
+
**`@return`** [OpenTelemetry::Metrics::Histogram, NullInstrument]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
**`@example`**
|
|
107
|
+
```ruby
|
|
108
|
+
Telemetry.tag_latency.record(250, attributes: { 'provider' => 'ollama', 'status' => 'success' })
|
|
109
|
+
```
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Class: HTM::WorkingMemoryChannel
|
|
2
|
+
**Inherits:** Object
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
Provides real-time synchronization of working memory changes across multiple
|
|
6
|
+
robots using PostgreSQL LISTEN/NOTIFY pub/sub mechanism.
|
|
7
|
+
|
|
8
|
+
This class enables distributed robots to maintain synchronized working memory
|
|
9
|
+
by broadcasting change notifications through PostgreSQL channels. When one
|
|
10
|
+
robot adds, evicts, or clears working memory, all other robots in the group
|
|
11
|
+
receive immediate notification.
|
|
12
|
+
|
|
13
|
+
**`@see`** [] Higher-level coordination using this channel
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
**`@example`**
|
|
17
|
+
```ruby
|
|
18
|
+
channel = HTM::WorkingMemoryChannel.new('support-team', db_config)
|
|
19
|
+
|
|
20
|
+
# Subscribe to changes
|
|
21
|
+
channel.on_change do |event, node_id, robot_id|
|
|
22
|
+
case event
|
|
23
|
+
when :added then puts "Node #{node_id} added by robot #{robot_id}"
|
|
24
|
+
when :evicted then puts "Node #{node_id} evicted by robot #{robot_id}"
|
|
25
|
+
when :cleared then puts "Working memory cleared by robot #{robot_id}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Start listening in background thread
|
|
30
|
+
channel.start_listening
|
|
31
|
+
|
|
32
|
+
# Publish a change
|
|
33
|
+
channel.notify(:added, node_id: 123, robot_id: 456)
|
|
34
|
+
|
|
35
|
+
# Cleanup when done
|
|
36
|
+
channel.stop_listening
|
|
37
|
+
```
|
|
38
|
+
# Attributes
|
|
39
|
+
## notifications_received[RW] {: #attribute-i-notifications_received }
|
|
40
|
+
Number of notifications received since channel was created
|
|
41
|
+
|
|
42
|
+
**`@return`** [Integer]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Instance Methods
|
|
46
|
+
## channel_name() {: #method-i-channel_name }
|
|
47
|
+
Returns the PostgreSQL channel name used for notifications.
|
|
48
|
+
|
|
49
|
+
The channel name is derived from the group name with a prefix and sanitization
|
|
50
|
+
of special characters.
|
|
51
|
+
|
|
52
|
+
**`@return`** [String] The PostgreSQL LISTEN/NOTIFY channel name
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
**`@example`**
|
|
56
|
+
```ruby
|
|
57
|
+
channel = HTM::WorkingMemoryChannel.new('my-group', db_config)
|
|
58
|
+
channel.channel_name # => "htm_wm_my_group"
|
|
59
|
+
```
|
|
60
|
+
## initialize(group_name, db_config) {: #method-i-initialize }
|
|
61
|
+
Creates a new working memory channel for a robot group.
|
|
62
|
+
|
|
63
|
+
The channel name is derived from the group name with non-alphanumeric
|
|
64
|
+
characters replaced by underscores to ensure PostgreSQL compatibility.
|
|
65
|
+
|
|
66
|
+
**`@option`** []
|
|
67
|
+
|
|
68
|
+
**`@option`** []
|
|
69
|
+
|
|
70
|
+
**`@option`** []
|
|
71
|
+
|
|
72
|
+
**`@option`** []
|
|
73
|
+
|
|
74
|
+
**`@option`** []
|
|
75
|
+
|
|
76
|
+
**`@param`** [String] Name of the robot group (used to create unique channel)
|
|
77
|
+
|
|
78
|
+
**`@param`** [Hash] PostgreSQL connection configuration hash
|
|
79
|
+
|
|
80
|
+
**`@return`** [WorkingMemoryChannel] a new instance of WorkingMemoryChannel
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
**`@example`**
|
|
84
|
+
```ruby
|
|
85
|
+
db_config = { host: 'localhost', port: 5432, dbname: 'htm_dev', user: 'postgres' }
|
|
86
|
+
channel = HTM::WorkingMemoryChannel.new('customer-support', db_config)
|
|
87
|
+
```
|
|
88
|
+
## listening?() {: #method-i-listening? }
|
|
89
|
+
Checks if the listener thread is currently active.
|
|
90
|
+
|
|
91
|
+
**`@return`** [Boolean] true if listening for notifications, false otherwise
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
**`@example`**
|
|
95
|
+
```ruby
|
|
96
|
+
channel.start_listening
|
|
97
|
+
channel.listening? # => true
|
|
98
|
+
channel.stop_listening
|
|
99
|
+
channel.listening? # => false
|
|
100
|
+
```
|
|
101
|
+
## notify(event, node_id:, robot_id:) {: #method-i-notify }
|
|
102
|
+
Broadcasts a working memory change notification to all listeners.
|
|
103
|
+
|
|
104
|
+
Uses PostgreSQL's pg_notify function to send a JSON payload containing the
|
|
105
|
+
event type, affected node ID, originating robot ID, and timestamp.
|
|
106
|
+
|
|
107
|
+
**`@param`** [Symbol] Type of change (:added, :evicted, or :cleared)
|
|
108
|
+
|
|
109
|
+
**`@param`** [Integer, nil] ID of the affected node (nil for :cleared events)
|
|
110
|
+
|
|
111
|
+
**`@param`** [Integer] ID of the robot that triggered the change
|
|
112
|
+
|
|
113
|
+
**`@return`** [void]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
**`@example`**
|
|
117
|
+
```ruby
|
|
118
|
+
channel.notify(:added, node_id: 123, robot_id: 1)
|
|
119
|
+
```
|
|
120
|
+
**`@example`**
|
|
121
|
+
```ruby
|
|
122
|
+
channel.notify(:cleared, node_id: nil, robot_id: 1)
|
|
123
|
+
```
|
|
124
|
+
## on_change(&callback) {: #method-i-on_change }
|
|
125
|
+
Registers a callback to be invoked when working memory changes occur.
|
|
126
|
+
|
|
127
|
+
Multiple callbacks can be registered; all will be called for each event.
|
|
128
|
+
Callbacks are invoked synchronously within the listener thread.
|
|
129
|
+
|
|
130
|
+
**`@return`** [void]
|
|
131
|
+
|
|
132
|
+
**`@yield`** [event, node_id, robot_id] Block called for each notification
|
|
133
|
+
|
|
134
|
+
**`@yieldparam`** [Symbol] Type of change (:added, :evicted, or :cleared)
|
|
135
|
+
|
|
136
|
+
**`@yieldparam`** [Integer, nil] ID of the affected node
|
|
137
|
+
|
|
138
|
+
**`@yieldparam`** [Integer] ID of the robot that triggered the change
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
**`@example`**
|
|
142
|
+
```ruby
|
|
143
|
+
channel.on_change do |event, node_id, robot_id|
|
|
144
|
+
puts "Received #{event} event for node #{node_id}"
|
|
145
|
+
end
|
|
146
|
+
```
|
|
147
|
+
## start_listening() {: #method-i-start_listening }
|
|
148
|
+
Starts listening for notifications in a background thread.
|
|
149
|
+
|
|
150
|
+
Creates a dedicated PostgreSQL connection that uses LISTEN to receive
|
|
151
|
+
notifications. The thread polls every 0.5 seconds, allowing for clean shutdown
|
|
152
|
+
via {#stop_listening}.
|
|
153
|
+
|
|
154
|
+
**`@return`** [Thread] The background listener thread
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
**`@example`**
|
|
158
|
+
```ruby
|
|
159
|
+
thread = channel.start_listening
|
|
160
|
+
puts "Listening: #{channel.listening?}" # => true
|
|
161
|
+
```
|
|
162
|
+
## stop_listening() {: #method-i-stop_listening }
|
|
163
|
+
Stops the background listener thread.
|
|
164
|
+
|
|
165
|
+
Signals the listener to stop, waits up to 0.5 seconds for clean exit, then
|
|
166
|
+
forcefully terminates if still running. The PostgreSQL connection is closed
|
|
167
|
+
automatically.
|
|
168
|
+
|
|
169
|
+
**`@return`** [void]
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
**`@example`**
|
|
173
|
+
```ruby
|
|
174
|
+
channel.stop_listening
|
|
175
|
+
puts "Listening: #{channel.listening?}" # => false
|
|
176
|
+
```
|
data/docs/api/yard/HTM.md
CHANGED
|
@@ -2,30 +2,10 @@
|
|
|
2
2
|
**Inherits:** Object
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
examples/robot_groups/lib/htm/working_memory_channel.rb frozen_string_literal:
|
|
6
|
+
true
|
|
6
7
|
|
|
7
|
-
All HTM errors inherit from HTM::Error, allowing you to catch all HTM-related
|
|
8
|
-
errors with a single rescue clause.
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
**`@example`**
|
|
12
|
-
```ruby
|
|
13
|
-
begin
|
|
14
|
-
htm.remember("some content")
|
|
15
|
-
rescue HTM::Error => e
|
|
16
|
-
logger.error "HTM error: #{e.message}"
|
|
17
|
-
end
|
|
18
|
-
```
|
|
19
|
-
**`@example`**
|
|
20
|
-
```ruby
|
|
21
|
-
begin
|
|
22
|
-
htm.forget(node_id, soft: false)
|
|
23
|
-
rescue HTM::NotFoundError
|
|
24
|
-
puts "Node not found"
|
|
25
|
-
rescue HTM::ValidationError
|
|
26
|
-
puts "Invalid input"
|
|
27
|
-
end
|
|
28
|
-
```
|
|
29
9
|
# Class Methods
|
|
30
10
|
## configure() {: #method-c-configure }
|
|
31
11
|
Configure HTM
|
|
@@ -57,6 +37,12 @@ Generate embedding using EmbeddingService
|
|
|
57
37
|
|
|
58
38
|
**`@return`** [Array<Float>] Embedding vector (original, not padded)
|
|
59
39
|
|
|
40
|
+
## extract_propositions(text ) {: #method-c-extract_propositions }
|
|
41
|
+
Extract propositions using PropositionService
|
|
42
|
+
**`@param`** [String] Text to analyze
|
|
43
|
+
|
|
44
|
+
**`@return`** [Array<String>] Extracted atomic propositions
|
|
45
|
+
|
|
60
46
|
## extract_tags(text , existing_ontology: []) {: #method-c-extract_tags }
|
|
61
47
|
Extract tags using TagService
|
|
62
48
|
**`@param`** [String] Text to analyze
|
|
@@ -75,4 +61,6 @@ Reset configuration to defaults
|
|
|
75
61
|
## configuration[RW] {: #attribute-c-configuration }
|
|
76
62
|
Get current configuration
|
|
77
63
|
|
|
78
|
-
**`@return`** [HTM::Configuration]
|
|
64
|
+
**`@return`** [HTM::Configuration]
|
|
65
|
+
|
|
66
|
+
|