htm 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +59 -1
- data/README.md +12 -0
- data/db/seeds.rb +1 -1
- data/docs/api/embedding-service.md +140 -110
- data/docs/api/yard/HTM/ActiveRecordConfig.md +6 -0
- data/docs/api/yard/HTM/Config.md +173 -0
- data/docs/api/yard/HTM/ConfigSection.md +28 -0
- data/docs/api/yard/HTM/Database.md +1 -1
- data/docs/api/yard/HTM/Railtie.md +2 -2
- data/docs/api/yard/HTM.md +0 -57
- data/docs/api/yard/index.csv +76 -61
- data/docs/api/yard-reference.md +2 -1
- data/docs/architecture/adrs/003-ollama-embeddings.md +45 -36
- data/docs/architecture/adrs/004-hive-mind.md +1 -1
- data/docs/architecture/adrs/008-robot-identification.md +1 -1
- data/docs/architecture/index.md +11 -9
- data/docs/architecture/overview.md +11 -7
- data/docs/assets/images/balanced-strategy-decay.svg +41 -0
- data/docs/assets/images/class-hierarchy.svg +1 -1
- data/docs/assets/images/eviction-priority.svg +43 -0
- data/docs/assets/images/exception-hierarchy.svg +2 -2
- data/docs/assets/images/hive-mind-shared-memory.svg +52 -0
- data/docs/assets/images/htm-architecture-overview.svg +3 -3
- data/docs/assets/images/htm-core-components.svg +4 -4
- data/docs/assets/images/htm-layered-architecture.svg +1 -1
- data/docs/assets/images/htm-memory-addition-flow.svg +2 -2
- data/docs/assets/images/htm-memory-recall-flow.svg +2 -2
- data/docs/assets/images/memory-topology.svg +53 -0
- data/docs/assets/images/two-tier-memory-architecture.svg +55 -0
- data/docs/development/setup.md +76 -44
- data/docs/examples/basic-usage.md +133 -0
- data/docs/examples/config-files.md +170 -0
- data/docs/examples/file-loading.md +208 -0
- data/docs/examples/index.md +116 -0
- data/docs/examples/llm-configuration.md +168 -0
- data/docs/examples/mcp-client.md +172 -0
- data/docs/examples/rails-integration.md +173 -0
- data/docs/examples/robot-groups.md +210 -0
- data/docs/examples/sinatra-integration.md +218 -0
- data/docs/examples/standalone-app.md +216 -0
- data/docs/examples/telemetry.md +224 -0
- data/docs/examples/timeframes.md +143 -0
- data/docs/getting-started/installation.md +97 -40
- data/docs/getting-started/quick-start.md +28 -11
- data/docs/guides/configuration.md +515 -0
- data/docs/guides/file-loading.md +322 -0
- data/docs/guides/getting-started.md +40 -9
- data/docs/guides/index.md +3 -3
- data/docs/guides/mcp-server.md +30 -12
- data/docs/guides/propositions.md +264 -0
- data/docs/guides/recalling-memories.md +4 -4
- data/docs/guides/search-strategies.md +3 -3
- data/docs/guides/tags.md +318 -0
- data/docs/guides/telemetry.md +229 -0
- data/docs/index.md +8 -16
- data/docs/{architecture → robots}/hive-mind.md +8 -111
- data/docs/robots/index.md +73 -0
- data/docs/{guides → robots}/multi-robot.md +3 -3
- data/docs/{guides → robots}/robot-groups.md +8 -7
- data/docs/{architecture → robots}/two-tier-memory.md +13 -149
- data/docs/robots/why-robots.md +85 -0
- data/lib/htm/config/defaults.yml +4 -4
- data/lib/htm/config.rb +2 -2
- data/lib/htm/job_adapter.rb +75 -1
- data/lib/htm/version.rb +1 -1
- data/lib/htm/workflows/remember_workflow.rb +212 -0
- data/lib/htm.rb +1 -0
- data/mkdocs.yml +33 -8
- metadata +60 -7
- data/docs/api/yard/HTM/Configuration.md +0 -240
- data/docs/telemetry.md +0 -391
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Rails Integration Example
|
|
2
|
+
|
|
3
|
+
A full-stack Rails application demonstrating HTM integration with a compelling UI/UX for exploring and managing semantic memories.
|
|
4
|
+
|
|
5
|
+
**Source:** [`examples/rails_app/`](https://github.com/madbomber/htm/tree/main/examples/rails_app)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The HTM Memory Explorer is a Rails 7.1 application that demonstrates:
|
|
10
|
+
|
|
11
|
+
- **Dashboard** - Overview of memory statistics, recent memories, top tags, and active robots
|
|
12
|
+
- **Memories Browser** - Full CRUD for memories with search, filtering, soft delete, and restore
|
|
13
|
+
- **Tag Visualization** - View tags as a list, text tree, or SVG hierarchy diagram
|
|
14
|
+
- **Robots Management** - Manage LLM agents in the hive mind architecture
|
|
15
|
+
- **Semantic Search** - Compare vector, full-text, and hybrid search strategies
|
|
16
|
+
- **File Loading** - Load markdown files with automatic chunking and re-sync
|
|
17
|
+
|
|
18
|
+
## Tech Stack
|
|
19
|
+
|
|
20
|
+
- Rails 7.1 with Hotwire (Turbo + Stimulus)
|
|
21
|
+
- Tailwind CSS for dark-themed UI
|
|
22
|
+
- PostgreSQL with pgvector
|
|
23
|
+
- HTM gem for semantic memory management
|
|
24
|
+
|
|
25
|
+
## Setup
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd examples/rails_app
|
|
29
|
+
|
|
30
|
+
# Install dependencies
|
|
31
|
+
bundle install
|
|
32
|
+
|
|
33
|
+
# Ensure HTM database is set up
|
|
34
|
+
export HTM_DATABASE__URL="postgresql://localhost/htm_development"
|
|
35
|
+
|
|
36
|
+
# Install frontend dependencies
|
|
37
|
+
rails tailwindcss:install
|
|
38
|
+
rails importmap:install
|
|
39
|
+
rails turbo:install
|
|
40
|
+
rails stimulus:install
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Running
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Start the Rails server with Tailwind CSS watching
|
|
47
|
+
./bin/dev
|
|
48
|
+
|
|
49
|
+
# Or start manually
|
|
50
|
+
bundle exec rails server
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Then open http://localhost:3000 in your browser.
|
|
54
|
+
|
|
55
|
+
## Pages
|
|
56
|
+
|
|
57
|
+
| Route | Description |
|
|
58
|
+
|-------|-------------|
|
|
59
|
+
| `/` | Dashboard with stats and overview |
|
|
60
|
+
| `/memories` | Browse, search, and filter memories |
|
|
61
|
+
| `/memories/new` | Add a new memory |
|
|
62
|
+
| `/memories/deleted` | View and restore deleted memories |
|
|
63
|
+
| `/tags` | Browse tags (list, tree, or diagram view) |
|
|
64
|
+
| `/robots` | Manage robots and switch active robot |
|
|
65
|
+
| `/search` | Semantic search playground |
|
|
66
|
+
| `/files` | File loading and management |
|
|
67
|
+
|
|
68
|
+
## How HTM Integration Works
|
|
69
|
+
|
|
70
|
+
### Automatic Rails Integration
|
|
71
|
+
|
|
72
|
+
The HTM gem includes a Rails Railtie (`lib/htm/railtie.rb`) that automatically:
|
|
73
|
+
|
|
74
|
+
1. Configures HTM to use `Rails.logger`
|
|
75
|
+
2. Sets job backend to `:active_job` (or `:inline` in test env)
|
|
76
|
+
3. Loads HTM rake tasks
|
|
77
|
+
4. Verifies database connection in development
|
|
78
|
+
|
|
79
|
+
### Controller Helper
|
|
80
|
+
|
|
81
|
+
The `ApplicationController` provides a `htm` helper method:
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
class ApplicationController < ActionController::Base
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def htm
|
|
88
|
+
@htm ||= HTM.new(
|
|
89
|
+
robot_name: session[:robot_name] || "web_user_#{session.id}"
|
|
90
|
+
)
|
|
91
|
+
end
|
|
92
|
+
helper_method :htm
|
|
93
|
+
end
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Using HTM in Controllers
|
|
97
|
+
|
|
98
|
+
```ruby
|
|
99
|
+
class MemoriesController < ApplicationController
|
|
100
|
+
def create
|
|
101
|
+
node_id = htm.remember(
|
|
102
|
+
params[:content],
|
|
103
|
+
tags: params[:tags]&.split(','),
|
|
104
|
+
metadata: { category: params[:category] }
|
|
105
|
+
)
|
|
106
|
+
redirect_to memories_path, notice: "Memory created (ID: #{node_id})"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def index
|
|
110
|
+
@memories = if params[:search].present?
|
|
111
|
+
htm.recall(params[:search], strategy: :hybrid, limit: 50, raw: true)
|
|
112
|
+
else
|
|
113
|
+
HTM::Models::Node.order(created_at: :desc).limit(50)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def destroy
|
|
118
|
+
htm.forget(params[:id]) # Soft delete by default
|
|
119
|
+
redirect_to memories_path, notice: "Memory deleted"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def restore
|
|
123
|
+
htm.restore(params[:id])
|
|
124
|
+
redirect_to memories_path, notice: "Memory restored"
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Tag Visualization
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
class TagsController < ApplicationController
|
|
133
|
+
def index
|
|
134
|
+
@tags = HTM::Models::Tag.all
|
|
135
|
+
|
|
136
|
+
respond_to do |format|
|
|
137
|
+
format.html
|
|
138
|
+
format.text { render plain: @tags.tree_string }
|
|
139
|
+
format.svg { render plain: @tags.tree_svg }
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Features Demonstrated
|
|
146
|
+
|
|
147
|
+
| HTM Feature | UI Component |
|
|
148
|
+
|-------------|--------------|
|
|
149
|
+
| `htm.remember()` | Memories > New form |
|
|
150
|
+
| `htm.recall()` | Search page with strategy selector |
|
|
151
|
+
| `htm.forget()` | Delete button (soft delete) |
|
|
152
|
+
| `htm.restore()` | Restore button in deleted view |
|
|
153
|
+
| `htm.load_file()` | Files page with file browser |
|
|
154
|
+
| Tag hierarchy | Tags page with tree/SVG views |
|
|
155
|
+
| Robot management | Robots page with activity stats |
|
|
156
|
+
|
|
157
|
+
## Development Notes
|
|
158
|
+
|
|
159
|
+
The app uses:
|
|
160
|
+
|
|
161
|
+
- `propshaft` for asset pipeline
|
|
162
|
+
- `importmap-rails` for JavaScript
|
|
163
|
+
- `tailwindcss-rails` for styling
|
|
164
|
+
- `kaminari` for pagination
|
|
165
|
+
- `turbo-rails` for SPA-like navigation
|
|
166
|
+
|
|
167
|
+
No JavaScript build step required.
|
|
168
|
+
|
|
169
|
+
## See Also
|
|
170
|
+
|
|
171
|
+
- [Getting Started Guide](../guides/getting-started.md)
|
|
172
|
+
- [Multi-Robot Systems](../robots/multi-robot.md)
|
|
173
|
+
- [Search Strategies](../guides/search-strategies.md)
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Robot Groups Example
|
|
2
|
+
|
|
3
|
+
This example demonstrates coordinating multiple robots with shared working memory and automatic failover capabilities.
|
|
4
|
+
|
|
5
|
+
**Source:** [`examples/robot_groups/same_process.rb`](https://github.com/madbomber/htm/blob/main/examples/robot_groups/same_process.rb)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Robot Groups enable:
|
|
10
|
+
|
|
11
|
+
- **Shared Working Memory**: Multiple robots share the same in-memory context
|
|
12
|
+
- **Active/Passive Roles**: Active robots handle requests; passive robots maintain synchronized context
|
|
13
|
+
- **Instant Failover**: When an active robot fails, passive robots take over with full context
|
|
14
|
+
- **Real-time Sync**: PostgreSQL LISTEN/NOTIFY enables real-time synchronization
|
|
15
|
+
- **Dynamic Scaling**: Add or remove robots on demand
|
|
16
|
+
|
|
17
|
+
## Running the Example
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
export HTM_DATABASE__URL="postgresql://user@localhost:5432/htm_development"
|
|
21
|
+
ruby examples/robot_groups/same_process.rb
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Code Walkthrough
|
|
25
|
+
|
|
26
|
+
### Create a Robot Group
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
group = HTM::RobotGroup.new(
|
|
30
|
+
name: 'customer-support-ha',
|
|
31
|
+
active: ['support-primary'], # Active robot names
|
|
32
|
+
passive: ['support-standby'], # Standby robot names
|
|
33
|
+
max_tokens: 8000 # Token limit for shared memory
|
|
34
|
+
)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Add Shared Memories
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
# Memories are automatically shared across all robots in the group
|
|
41
|
+
group.remember(
|
|
42
|
+
'Customer account #12345 prefers email communication.',
|
|
43
|
+
originator: 'support-primary'
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
group.remember(
|
|
47
|
+
'Open ticket #789: Billing discrepancy reported.',
|
|
48
|
+
originator: 'support-primary'
|
|
49
|
+
)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Check Synchronization Status
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
status = group.status
|
|
56
|
+
# => {
|
|
57
|
+
# name: 'customer-support-ha',
|
|
58
|
+
# active: ['support-primary'],
|
|
59
|
+
# passive: ['support-standby'],
|
|
60
|
+
# working_memory_nodes: 3,
|
|
61
|
+
# token_utilization: 0.15,
|
|
62
|
+
# in_sync: true
|
|
63
|
+
# }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Simulate Failover
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
# Primary robot fails
|
|
70
|
+
puts "Primary robot stopped responding!"
|
|
71
|
+
|
|
72
|
+
# Failover to standby
|
|
73
|
+
group.failover!
|
|
74
|
+
|
|
75
|
+
status = group.status
|
|
76
|
+
# Active robots now: ['support-standby']
|
|
77
|
+
# Passive robots now: []
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Recall with Full Context
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
# Standby has full context after failover
|
|
84
|
+
memories = group.recall('customer', limit: 5, strategy: :fulltext)
|
|
85
|
+
# => All memories are available immediately
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Scale Up (Add Robots)
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
# Add a second active robot
|
|
92
|
+
group.add_active('support-secondary')
|
|
93
|
+
group.sync_robot('support-secondary')
|
|
94
|
+
|
|
95
|
+
# Both robots now share the same working memory
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Collaborative Memory
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
# Either robot can add memories that sync to all
|
|
102
|
+
group.remember(
|
|
103
|
+
'Issue escalated to billing department.',
|
|
104
|
+
originator: 'support-secondary'
|
|
105
|
+
)
|
|
106
|
+
# Automatically synced to all group members
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Real-Time Sync
|
|
110
|
+
|
|
111
|
+
Robot Groups use PostgreSQL LISTEN/NOTIFY for real-time synchronization:
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
sync_stats = group.sync_stats
|
|
115
|
+
# => {
|
|
116
|
+
# nodes_synced: 5,
|
|
117
|
+
# evictions_synced: 0,
|
|
118
|
+
# notifications_received: 8
|
|
119
|
+
# }
|
|
120
|
+
|
|
121
|
+
# Check listener status
|
|
122
|
+
group.channel.listening? # => true
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## High Availability Pattern
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
┌─────────────────────────────────────────────────────────┐
|
|
129
|
+
│ RobotGroup │
|
|
130
|
+
│ 'customer-support-ha' │
|
|
131
|
+
├─────────────────────────────────────────────────────────┤
|
|
132
|
+
│ │
|
|
133
|
+
│ ┌─────────────────┐ ┌─────────────────┐ │
|
|
134
|
+
│ │ support-primary│ │ support-standby │ │
|
|
135
|
+
│ │ (ACTIVE) │ │ (PASSIVE) │ │
|
|
136
|
+
│ └────────┬────────┘ └────────┬────────┘ │
|
|
137
|
+
│ │ │ │
|
|
138
|
+
│ └───────────┬───────────┘ │
|
|
139
|
+
│ │ │
|
|
140
|
+
│ ┌──────────▼──────────┐ │
|
|
141
|
+
│ │ Shared Working │ │
|
|
142
|
+
│ │ Memory │ │
|
|
143
|
+
│ └──────────┬──────────┘ │
|
|
144
|
+
│ │ │
|
|
145
|
+
│ ┌──────────▼──────────┐ │
|
|
146
|
+
│ │ PostgreSQL │ │
|
|
147
|
+
│ │ LISTEN/NOTIFY │ │
|
|
148
|
+
│ └─────────────────────┘ │
|
|
149
|
+
└─────────────────────────────────────────────────────────┘
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Use Cases
|
|
153
|
+
|
|
154
|
+
### Customer Support
|
|
155
|
+
|
|
156
|
+
Multiple support agents share context about ongoing conversations:
|
|
157
|
+
|
|
158
|
+
```ruby
|
|
159
|
+
group = HTM::RobotGroup.new(
|
|
160
|
+
name: 'support-team',
|
|
161
|
+
active: ['agent-1', 'agent-2', 'agent-3'],
|
|
162
|
+
passive: ['backup-agent'],
|
|
163
|
+
max_tokens: 16000
|
|
164
|
+
)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Load Balancing
|
|
168
|
+
|
|
169
|
+
Distribute queries across multiple active robots:
|
|
170
|
+
|
|
171
|
+
```ruby
|
|
172
|
+
group = HTM::RobotGroup.new(
|
|
173
|
+
name: 'query-handlers',
|
|
174
|
+
active: ['handler-1', 'handler-2'],
|
|
175
|
+
passive: [],
|
|
176
|
+
max_tokens: 8000
|
|
177
|
+
)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Disaster Recovery
|
|
181
|
+
|
|
182
|
+
Keep a warm standby ready to take over:
|
|
183
|
+
|
|
184
|
+
```ruby
|
|
185
|
+
group = HTM::RobotGroup.new(
|
|
186
|
+
name: 'primary-with-dr',
|
|
187
|
+
active: ['primary'],
|
|
188
|
+
passive: ['dr-standby'],
|
|
189
|
+
max_tokens: 32000
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
# On primary failure
|
|
193
|
+
group.failover!
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Cleanup
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
# Clear shared working memory
|
|
200
|
+
group.clear_working_memory
|
|
201
|
+
|
|
202
|
+
# Stop the LISTEN/NOTIFY listener
|
|
203
|
+
group.shutdown
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## See Also
|
|
207
|
+
|
|
208
|
+
- [Multi-Robot Usage Guide](../robots/multi-robot.md)
|
|
209
|
+
- [Hive Mind Architecture](../robots/hive-mind.md)
|
|
210
|
+
- [Working Memory API](../api/working-memory.md)
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Sinatra Integration Example
|
|
2
|
+
|
|
3
|
+
A Sinatra web application demonstrating HTM integration with Sidekiq for background job processing.
|
|
4
|
+
|
|
5
|
+
**Source:** [`examples/sinatra_app/`](https://github.com/madbomber/htm/tree/main/examples/sinatra_app)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The Sinatra example demonstrates:
|
|
10
|
+
|
|
11
|
+
- HTM integration with Sinatra using `register_htm` helper
|
|
12
|
+
- Session-based robot identification
|
|
13
|
+
- RESTful API endpoints for memory operations
|
|
14
|
+
- Sidekiq for background embedding and tag generation
|
|
15
|
+
- Thread-safe concurrent request handling
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# PostgreSQL with pgvector
|
|
21
|
+
export HTM_DATABASE__URL="postgresql://user@localhost:5432/htm_development"
|
|
22
|
+
|
|
23
|
+
# Redis for Sidekiq (optional)
|
|
24
|
+
export REDIS_URL="redis://localhost:6379/0"
|
|
25
|
+
|
|
26
|
+
# Ollama for embeddings and tags
|
|
27
|
+
ollama pull nomic-embed-text
|
|
28
|
+
ollama pull gemma3:latest
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Setup
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cd examples/sinatra_app
|
|
35
|
+
|
|
36
|
+
# Install dependencies
|
|
37
|
+
bundle install
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Running
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Start the Sinatra app
|
|
44
|
+
bundle exec ruby app.rb
|
|
45
|
+
|
|
46
|
+
# In a separate terminal, start Sidekiq (optional, for async processing)
|
|
47
|
+
bundle exec sidekiq
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then open http://localhost:4567 in your browser.
|
|
51
|
+
|
|
52
|
+
## Code Walkthrough
|
|
53
|
+
|
|
54
|
+
### HTM Registration
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
require 'sinatra'
|
|
58
|
+
require_relative '../../lib/htm'
|
|
59
|
+
require_relative '../../lib/htm/integrations/sinatra'
|
|
60
|
+
|
|
61
|
+
class HTMApp < Sinatra::Base
|
|
62
|
+
# Register HTM with automatic configuration
|
|
63
|
+
register_htm
|
|
64
|
+
|
|
65
|
+
# Enable sessions for robot identification
|
|
66
|
+
enable :sessions
|
|
67
|
+
set :session_secret, ENV.fetch('SESSION_SECRET', SecureRandom.hex(64))
|
|
68
|
+
end
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Request Initialization
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
before do
|
|
75
|
+
# Use session ID as robot identifier
|
|
76
|
+
robot_name = session[:robot_id] ||= SecureRandom.uuid[0..7]
|
|
77
|
+
init_htm(robot_name: "web_user_#{robot_name}")
|
|
78
|
+
|
|
79
|
+
# Set content type for API responses
|
|
80
|
+
content_type :json if request.path.start_with?('/api/')
|
|
81
|
+
end
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### API Endpoints
|
|
85
|
+
|
|
86
|
+
```ruby
|
|
87
|
+
# Remember information
|
|
88
|
+
post '/api/remember' do
|
|
89
|
+
content = params[:content]
|
|
90
|
+
|
|
91
|
+
unless content && !content.empty?
|
|
92
|
+
halt 400, json(error: 'Content is required')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
node_id = remember(content)
|
|
96
|
+
|
|
97
|
+
json(
|
|
98
|
+
status: 'ok',
|
|
99
|
+
node_id: node_id,
|
|
100
|
+
message: 'Memory stored. Embedding and tags are being generated in background.'
|
|
101
|
+
)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Recall memories
|
|
105
|
+
get '/api/recall' do
|
|
106
|
+
topic = params[:topic]
|
|
107
|
+
limit = (params[:limit] || 10).to_i
|
|
108
|
+
strategy = (params[:strategy] || 'hybrid').to_sym
|
|
109
|
+
|
|
110
|
+
unless topic && !topic.empty?
|
|
111
|
+
halt 400, json(error: 'Topic is required')
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
memories = recall(topic, strategy: strategy, limit: limit)
|
|
115
|
+
|
|
116
|
+
json(memories: memories)
|
|
117
|
+
end
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## API Reference
|
|
121
|
+
|
|
122
|
+
### POST /api/remember
|
|
123
|
+
|
|
124
|
+
Store information in memory.
|
|
125
|
+
|
|
126
|
+
**Parameters:**
|
|
127
|
+
- `content` (required) - The text content to remember
|
|
128
|
+
|
|
129
|
+
**Response:**
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"status": "ok",
|
|
133
|
+
"node_id": 42,
|
|
134
|
+
"message": "Memory stored. Embedding and tags are being generated in background."
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### GET /api/recall
|
|
139
|
+
|
|
140
|
+
Recall memories matching a topic.
|
|
141
|
+
|
|
142
|
+
**Parameters:**
|
|
143
|
+
- `topic` (required) - Search topic
|
|
144
|
+
- `limit` (optional) - Max results (default: 10)
|
|
145
|
+
- `strategy` (optional) - Search strategy: `vector`, `fulltext`, or `hybrid` (default: hybrid)
|
|
146
|
+
- `timeframe` (optional) - Time range in seconds
|
|
147
|
+
|
|
148
|
+
**Response:**
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"memories": [
|
|
152
|
+
"PostgreSQL supports vector search via pgvector...",
|
|
153
|
+
"The HTM gem provides intelligent memory management..."
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### GET /api/stats
|
|
159
|
+
|
|
160
|
+
Get memory statistics.
|
|
161
|
+
|
|
162
|
+
**Response:**
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"total_nodes": 150,
|
|
166
|
+
"total_robots": 5,
|
|
167
|
+
"total_tags": 42,
|
|
168
|
+
"working_memory_nodes": 12
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Sidekiq Configuration
|
|
173
|
+
|
|
174
|
+
```ruby
|
|
175
|
+
require 'sidekiq'
|
|
176
|
+
|
|
177
|
+
Sidekiq.configure_server do |config|
|
|
178
|
+
config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') }
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
Sidekiq.configure_client do |config|
|
|
182
|
+
config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') }
|
|
183
|
+
end
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
HTM automatically uses Sidekiq for background jobs when available:
|
|
187
|
+
|
|
188
|
+
- `GenerateEmbeddingJob` - Generates vector embeddings
|
|
189
|
+
- `GenerateTagsJob` - Extracts hierarchical tags via LLM
|
|
190
|
+
|
|
191
|
+
## Environment Variables
|
|
192
|
+
|
|
193
|
+
| Variable | Default | Description |
|
|
194
|
+
|----------|---------|-------------|
|
|
195
|
+
| `HTM_DATABASE__URL` | (required) | PostgreSQL connection URL |
|
|
196
|
+
| `REDIS_URL` | `redis://localhost:6379/0` | Redis URL for Sidekiq |
|
|
197
|
+
| `OLLAMA_URL` | `http://localhost:11434` | Ollama server URL |
|
|
198
|
+
| `SESSION_SECRET` | (random) | Session encryption secret |
|
|
199
|
+
|
|
200
|
+
## Testing with curl
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Remember something
|
|
204
|
+
curl -X POST http://localhost:4567/api/remember \
|
|
205
|
+
-d "content=PostgreSQL supports vector similarity search"
|
|
206
|
+
|
|
207
|
+
# Recall memories
|
|
208
|
+
curl "http://localhost:4567/api/recall?topic=database&strategy=hybrid&limit=5"
|
|
209
|
+
|
|
210
|
+
# Get stats
|
|
211
|
+
curl http://localhost:4567/api/stats
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## See Also
|
|
215
|
+
|
|
216
|
+
- [Getting Started Guide](../guides/getting-started.md)
|
|
217
|
+
- [MCP Server Guide](../guides/mcp-server.md)
|
|
218
|
+
- [Configuration Guide](../guides/configuration.md)
|