htm 0.0.1 → 0.0.10
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 +92 -0
- data/.envrc +1 -0
- data/.irbrc +283 -80
- data/.tbls.yml +31 -0
- data/CHANGELOG.md +314 -16
- data/CLAUDE.md +603 -0
- data/README.md +76 -5
- data/Rakefile +5 -0
- data/SETUP.md +132 -101
- 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 +390 -36
- data/docs/api/database.md +19 -232
- data/docs/api/embedding-service.md +1 -7
- data/docs/api/htm.md +305 -364
- data/docs/api/index.md +1 -7
- data/docs/api/long-term-memory.md +342 -590
- 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/architecture/adrs/001-postgresql-timescaledb.md +1 -1
- data/docs/architecture/adrs/003-ollama-embeddings.md +1 -1
- data/docs/architecture/adrs/010-redis-working-memory-rejected.md +2 -27
- data/docs/architecture/adrs/index.md +2 -13
- data/docs/architecture/hive-mind.md +165 -166
- data/docs/architecture/index.md +2 -2
- data/docs/architecture/overview.md +5 -171
- data/docs/architecture/two-tier-memory.md +1 -35
- data/docs/assets/images/adr-010-current-architecture.svg +37 -0
- data/docs/assets/images/adr-010-proposed-architecture.svg +48 -0
- data/docs/assets/images/adr-dependency-tree.svg +93 -0
- data/docs/assets/images/class-hierarchy.svg +55 -0
- data/docs/assets/images/exception-hierarchy.svg +45 -0
- data/docs/assets/images/htm-architecture-overview.svg +83 -0
- data/docs/assets/images/htm-complete-memory-flow.svg +160 -0
- data/docs/assets/images/htm-context-assembly-flow.svg +148 -0
- data/docs/assets/images/htm-eviction-process.svg +141 -0
- data/docs/assets/images/htm-memory-addition-flow.svg +138 -0
- data/docs/assets/images/htm-memory-recall-flow.svg +152 -0
- data/docs/assets/images/htm-node-states.svg +123 -0
- data/docs/assets/images/project-structure.svg +78 -0
- data/docs/assets/images/test-directory-structure.svg +38 -0
- data/{dbdoc → docs/database}/README.md +127 -125
- data/docs/database/public.file_sources.md +42 -0
- data/docs/database/public.file_sources.svg +211 -0
- data/{dbdoc → docs/database}/public.node_tags.md +7 -8
- data/docs/database/public.node_tags.svg +239 -0
- data/{dbdoc → docs/database}/public.nodes.md +22 -17
- data/docs/database/public.nodes.svg +271 -0
- data/docs/database/public.robot_nodes.md +46 -0
- data/docs/database/public.robot_nodes.svg +243 -0
- data/{dbdoc → docs/database}/public.robots.md +2 -3
- data/docs/database/public.robots.svg +161 -0
- data/docs/database/public.tags.svg +139 -0
- data/{dbdoc → docs/database}/schema.json +941 -630
- data/docs/database/schema.svg +282 -0
- data/docs/development/index.md +1 -29
- data/docs/development/schema.md +134 -309
- data/docs/development/testing.md +1 -9
- data/docs/getting-started/index.md +47 -0
- data/docs/{installation.md → getting-started/installation.md} +2 -2
- data/docs/{quick-start.md → getting-started/quick-start.md} +5 -5
- data/docs/guides/adding-memories.md +295 -643
- data/docs/guides/recalling-memories.md +36 -1
- data/docs/guides/search-strategies.md +85 -51
- data/docs/images/htm-er-diagram.svg +156 -0
- data/docs/index.md +16 -31
- data/docs/multi_framework_support.md +4 -4
- data/examples/README.md +280 -0
- data/examples/basic_usage.rb +18 -16
- data/examples/cli_app/htm_cli.rb +146 -8
- data/examples/cli_app/temp.log +93 -0
- data/examples/custom_llm_configuration.rb +1 -2
- data/examples/example_app/app.rb +11 -14
- data/examples/file_loader_usage.rb +177 -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/sinatra_app/Gemfile +1 -0
- data/examples/sinatra_app/Gemfile.lock +166 -0
- data/examples/sinatra_app/app.rb +219 -24
- data/examples/timeframe_demo.rb +276 -0
- data/lib/htm/active_record_config.rb +10 -3
- data/lib/htm/circuit_breaker.rb +202 -0
- data/lib/htm/configuration.rb +313 -80
- 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/{sinatra.rb → integrations/sinatra.rb} +87 -12
- data/lib/htm/job_adapter.rb +10 -3
- 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 +601 -321
- data/lib/htm/models/file_source.rb +99 -0
- data/lib/htm/models/node.rb +116 -12
- data/lib/htm/models/robot.rb +53 -4
- data/lib/htm/models/robot_node.rb +51 -0
- data/lib/htm/models/tag.rb +302 -0
- data/lib/htm/observability.rb +395 -0
- data/lib/htm/tag_service.rb +60 -3
- data/lib/htm/tasks.rb +29 -0
- 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 +352 -133
- data/lib/tasks/doc.rake +300 -0
- data/lib/tasks/files.rake +299 -0
- data/lib/tasks/htm.rake +188 -2
- data/lib/tasks/jobs.rake +10 -12
- data/lib/tasks/tags.rake +194 -0
- data/mkdocs.yml +91 -9
- 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 +177 -37
- 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/dbdoc/public.node_tags.svg +0 -112
- data/dbdoc/public.nodes.svg +0 -118
- data/dbdoc/public.robots.svg +0 -90
- data/dbdoc/public.tags.svg +0 -60
- data/dbdoc/schema.svg +0 -154
- data/{dbdoc → docs/database}/public.node_stats.md +0 -0
- data/{dbdoc → docs/database}/public.node_stats.svg +0 -0
- data/{dbdoc → docs/database}/public.nodes_tags.md +0 -0
- data/{dbdoc → docs/database}/public.nodes_tags.svg +0 -0
- data/{dbdoc → docs/database}/public.ontology_structure.md +0 -0
- data/{dbdoc → docs/database}/public.ontology_structure.svg +0 -0
- data/{dbdoc → docs/database}/public.operations_log.md +0 -0
- data/{dbdoc → docs/database}/public.operations_log.svg +0 -0
- data/{dbdoc → docs/database}/public.relationships.md +0 -0
- data/{dbdoc → docs/database}/public.relationships.svg +0 -0
- data/{dbdoc → docs/database}/public.robot_activity.md +0 -0
- data/{dbdoc → docs/database}/public.robot_activity.svg +0 -0
- data/{dbdoc → docs/database}/public.schema_migrations.md +0 -0
- data/{dbdoc → docs/database}/public.schema_migrations.svg +0 -0
- data/{dbdoc → docs/database}/public.tags.md +3 -3
- /data/{dbdoc → docs/database}/public.topic_relationships.md +0 -0
- /data/{dbdoc → docs/database}/public.topic_relationships.svg +0 -0
data/.envrc
CHANGED
|
@@ -9,6 +9,7 @@ export HTM_DBNAME=htm_development
|
|
|
9
9
|
export HTM_DBUSER=${USER}
|
|
10
10
|
export HTM_DBPASS=
|
|
11
11
|
export HTM_DBURL="postgresql://${HTM_DBUSER}@${HTM_DBHOST}:${HTM_DBPORT}/${HTM_DBNAME}?sslmode=disable"
|
|
12
|
+
# export HTM_DBURL="postgresql://dewayne@localhost:5432/htm_development"
|
|
12
13
|
|
|
13
14
|
# Uncomment if using TimescaleDB Cloud instead:
|
|
14
15
|
# export HTM_SERVICE_NAME=$TIGER_SERVICE_NAME
|
data/.irbrc
CHANGED
|
@@ -1,97 +1,144 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# HTM
|
|
4
|
-
#
|
|
5
|
-
# Or just: irb (if in the htm directory)
|
|
3
|
+
# HTM Interactive Development Console
|
|
4
|
+
# Usage: HTM_DBURL="postgresql://user@localhost:5432/htm_development" irb
|
|
6
5
|
|
|
7
|
-
puts "Loading HTM library..."
|
|
8
|
-
|
|
9
|
-
# Load the HTM library
|
|
10
6
|
require_relative 'lib/htm'
|
|
7
|
+
require 'debug_me'
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
HTM
|
|
9
|
+
puts "=" * 60
|
|
10
|
+
puts "HTM Interactive Console"
|
|
11
|
+
puts "=" * 60
|
|
14
12
|
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
c.reset_to_defaults
|
|
13
|
+
# Database Connection
|
|
14
|
+
begin
|
|
15
|
+
HTM::ActiveRecordConfig.establish_connection! unless HTM::ActiveRecordConfig.connected?
|
|
16
|
+
db_name = HTM::Database.default_config[:dbname] rescue 'unknown'
|
|
17
|
+
puts "✓ Database connected: #{db_name}"
|
|
18
|
+
rescue => e
|
|
19
|
+
puts "✗ Database connection failed: #{e.message}"
|
|
23
20
|
end
|
|
24
21
|
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
# Configure HTM with sensible defaults for interactive use
|
|
23
|
+
HTM.configure do |config|
|
|
24
|
+
config.job_backend = :inline
|
|
25
|
+
config.embedding_provider = :ollama
|
|
26
|
+
config.embedding_model = 'nomic-embed-text:latest'
|
|
27
|
+
config.embedding_dimensions = 768
|
|
28
|
+
config.tag_provider = :ollama
|
|
29
|
+
config.tag_model = 'gemma3:latest'
|
|
30
|
+
config.reset_to_defaults
|
|
31
|
+
end
|
|
32
|
+
puts "✓ HTM configured (inline jobs, Ollama provider)"
|
|
30
33
|
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
# Model shortcuts (constants for easy access)
|
|
35
|
+
Node = HTM::Models::Node
|
|
36
|
+
Tag = HTM::Models::Tag
|
|
37
|
+
NodeTag = HTM::Models::NodeTag
|
|
38
|
+
Robot = HTM::Models::Robot
|
|
39
|
+
RobotNode = HTM::Models::RobotNode
|
|
40
|
+
FileSource = HTM::Models::FileSource
|
|
41
|
+
|
|
42
|
+
# Pre-built HTM instances for common testing scenarios
|
|
43
|
+
def user
|
|
44
|
+
@user ||= HTM.new(robot_name: "User")
|
|
36
45
|
end
|
|
37
46
|
|
|
47
|
+
def assistant
|
|
48
|
+
@assistant ||= HTM.new(robot_name: "Assistant")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def researcher
|
|
52
|
+
@researcher ||= HTM.new(robot_name: "Researcher")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def coder
|
|
56
|
+
@coder ||= HTM.new(robot_name: "Coder")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def htm
|
|
60
|
+
@htm ||= HTM.new(robot_name: "IRB Console")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# RubyLLM shortcuts
|
|
64
|
+
def llm
|
|
65
|
+
require 'ruby_llm' unless defined?(RubyLLM)
|
|
66
|
+
RubyLLM
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def chat(message, model: 'gemma3:latest')
|
|
70
|
+
llm.chat(messages: [{ role: 'user', content: message }], model: model).content
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def embed(text, model: 'nomic-embed-text:latest')
|
|
74
|
+
llm.embed(text, model: model)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Database utilities
|
|
38
78
|
def db_stats
|
|
39
79
|
puts <<~STATS
|
|
40
80
|
|
|
41
81
|
=== Database Statistics ===
|
|
42
|
-
Nodes:
|
|
43
|
-
Tags:
|
|
44
|
-
NodeTags:
|
|
45
|
-
Robots:
|
|
82
|
+
Nodes: #{Node.count} (#{Node.deleted.count} deleted)
|
|
83
|
+
Tags: #{Tag.count}
|
|
84
|
+
NodeTags: #{NodeTag.count}
|
|
85
|
+
Robots: #{Robot.count}
|
|
86
|
+
RobotNodes: #{RobotNode.count}
|
|
87
|
+
FileSources: #{FileSource.count}
|
|
46
88
|
|
|
47
89
|
STATS
|
|
48
90
|
end
|
|
49
91
|
|
|
92
|
+
def health
|
|
93
|
+
HTM::Observability.health_check
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def healthy?
|
|
97
|
+
HTM::Observability.healthy?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Node exploration
|
|
50
101
|
def recent_nodes(limit = 5)
|
|
51
102
|
puts "\n=== Recent Nodes ==="
|
|
52
103
|
Node.order(created_at: :desc).limit(limit).each do |node|
|
|
53
104
|
tags = node.tags.pluck(:name).join(', ')
|
|
54
105
|
tags_str = tags.empty? ? "(no tags)" : tags
|
|
55
|
-
|
|
106
|
+
content_preview = node.content.to_s[0..60].gsub("\n", " ")
|
|
107
|
+
puts "Node #{node.id}: #{content_preview}..."
|
|
56
108
|
puts " Tags: #{tags_str}"
|
|
57
|
-
puts " Embedding: #{node.embedding ?
|
|
58
|
-
puts ""
|
|
109
|
+
puts " Embedding: #{node.embedding ? "✓ (#{node.embedding.size}d)" : '✗'}"
|
|
110
|
+
puts " Created: #{node.created_at}"
|
|
111
|
+
puts
|
|
59
112
|
end
|
|
113
|
+
nil
|
|
60
114
|
end
|
|
61
115
|
|
|
62
|
-
def
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
count = tag.nodes.count
|
|
66
|
-
puts "#{tag.name} (#{count} nodes)"
|
|
67
|
-
end
|
|
68
|
-
puts
|
|
69
|
-
end
|
|
116
|
+
def recent_by_robot(robot_name, limit = 10)
|
|
117
|
+
robot = Robot.find_by(name: robot_name)
|
|
118
|
+
return puts("Robot '#{robot_name}' not found") unless robot
|
|
70
119
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
puts "#{tag.name} (#{count} nodes)"
|
|
120
|
+
puts "\n=== Recent Nodes by #{robot_name} ==="
|
|
121
|
+
robot.nodes.order(created_at: :desc).limit(limit).each do |node|
|
|
122
|
+
content_preview = node.content.to_s[0..60].gsub("\n", " ")
|
|
123
|
+
puts "Node #{node.id}: #{content_preview}..."
|
|
76
124
|
end
|
|
77
|
-
|
|
125
|
+
nil
|
|
78
126
|
end
|
|
79
127
|
|
|
80
|
-
def
|
|
81
|
-
node = Node.includes(:tags).find(node_id)
|
|
82
|
-
embedding_info =
|
|
83
|
-
"✓ (#{node.embedding.size} dimensions)"
|
|
84
|
-
else
|
|
85
|
-
'✗'
|
|
86
|
-
end
|
|
128
|
+
def node_info(node_id)
|
|
129
|
+
node = Node.includes(:tags, :robots).find(node_id)
|
|
130
|
+
embedding_info = node.embedding ? "✓ (#{node.embedding.size} dimensions)" : '✗'
|
|
87
131
|
|
|
88
132
|
puts <<~NODE_INFO
|
|
89
133
|
|
|
90
134
|
=== Node #{node_id} ===
|
|
91
135
|
Content: #{node.content}
|
|
92
|
-
|
|
136
|
+
Type: #{node.memory_type}
|
|
137
|
+
Importance: #{node.importance}
|
|
93
138
|
Created: #{node.created_at}
|
|
139
|
+
Last Accessed: #{node.last_accessed}
|
|
94
140
|
Embedding: #{embedding_info}
|
|
141
|
+
Deleted: #{node.deleted_at ? "Yes (#{node.deleted_at})" : 'No'}
|
|
95
142
|
|
|
96
143
|
Tags:
|
|
97
144
|
NODE_INFO
|
|
@@ -101,45 +148,201 @@ def node_with_tags(node_id)
|
|
|
101
148
|
else
|
|
102
149
|
puts " (no tags)"
|
|
103
150
|
end
|
|
151
|
+
|
|
152
|
+
puts "\n Robots:"
|
|
153
|
+
if node.robots.any?
|
|
154
|
+
node.robots.each { |robot| puts " - #{robot.name}" }
|
|
155
|
+
else
|
|
156
|
+
puts " (no robots)"
|
|
157
|
+
end
|
|
104
158
|
puts
|
|
105
159
|
node
|
|
106
160
|
end
|
|
107
161
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
puts
|
|
112
|
-
|
|
162
|
+
# Tag exploration
|
|
163
|
+
def tag_tree(prefix = nil)
|
|
164
|
+
scope = prefix ? Tag.where("name LIKE ?", "#{prefix}%") : Tag.all
|
|
165
|
+
puts scope.tree_string
|
|
166
|
+
nil
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def recent_tags(limit = 10)
|
|
170
|
+
puts "\n=== Recent Tags ==="
|
|
171
|
+
Tag.order(created_at: :desc).limit(limit).each do |tag|
|
|
172
|
+
count = tag.nodes.count
|
|
173
|
+
puts "#{tag.name} (#{count} nodes)"
|
|
174
|
+
end
|
|
175
|
+
nil
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def popular_tags(limit = 20)
|
|
179
|
+
puts "\n=== Popular Tags ==="
|
|
180
|
+
Tag.joins(:nodes)
|
|
181
|
+
.group('tags.id', 'tags.name')
|
|
182
|
+
.order('COUNT(nodes.id) DESC')
|
|
183
|
+
.limit(limit)
|
|
184
|
+
.pluck('tags.name', 'COUNT(nodes.id)')
|
|
185
|
+
.each { |name, count| puts "#{name} (#{count} nodes)" }
|
|
186
|
+
nil
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def search_tags(pattern)
|
|
190
|
+
puts "\n=== Tags matching '#{pattern}' ==="
|
|
191
|
+
Tag.where("name LIKE ?", "%#{pattern}%").each do |tag|
|
|
192
|
+
count = tag.nodes.count
|
|
193
|
+
puts "#{tag.name} (#{count} nodes)"
|
|
194
|
+
end
|
|
195
|
+
nil
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Robot exploration
|
|
199
|
+
def list_robots
|
|
200
|
+
puts "\n=== Robots ==="
|
|
201
|
+
Robot.all.each do |robot|
|
|
202
|
+
node_count = robot.nodes.count
|
|
203
|
+
puts "#{robot.name} (#{node_count} nodes) - created #{robot.created_at}"
|
|
204
|
+
end
|
|
205
|
+
nil
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Memory operations
|
|
209
|
+
def remember(content, type: :fact, importance: 5.0, tags: [])
|
|
210
|
+
node = htm.remember(content, type: type, importance: importance, tags: tags)
|
|
211
|
+
puts "✓ Created node #{node.id}"
|
|
212
|
+
node
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def recall(query, limit: 5, raw: false)
|
|
216
|
+
htm.recall(query, limit: limit, raw: raw)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def search(query, strategy: :hybrid, limit: 10)
|
|
220
|
+
htm.long_term_memory.search(query, strategy: strategy, limit: limit)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def similar_to(node_id, limit: 5)
|
|
224
|
+
node = Node.find(node_id)
|
|
225
|
+
node.nearest_neighbors(:embedding, distance: :cosine).limit(limit)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Timeframe helpers
|
|
229
|
+
def today
|
|
230
|
+
Date.today.beginning_of_day..Date.today.end_of_day
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def yesterday
|
|
234
|
+
1.day.ago.beginning_of_day..1.day.ago.end_of_day
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def this_week
|
|
238
|
+
Date.today.beginning_of_week..Date.today.end_of_day
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def last_week
|
|
242
|
+
1.week.ago.beginning_of_week..1.week.ago.end_of_week
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def nodes_in(timeframe)
|
|
246
|
+
Node.where(created_at: timeframe)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# File loading helpers
|
|
250
|
+
def load_file(path, force: false)
|
|
251
|
+
htm.load_file(path, force: force)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def load_directory(path, pattern: '**/*.md', force: false)
|
|
255
|
+
htm.load_directory(path, pattern: pattern, force: force)
|
|
113
256
|
end
|
|
114
257
|
|
|
258
|
+
def loaded_files
|
|
259
|
+
puts "\n=== Loaded Files ==="
|
|
260
|
+
FileSource.all.each do |fs|
|
|
261
|
+
sync_status = fs.needs_sync? ? "needs sync" : "synced"
|
|
262
|
+
puts "#{fs.file_path} (#{fs.chunks.count} chunks, #{sync_status})"
|
|
263
|
+
end
|
|
264
|
+
nil
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# Reload helper
|
|
268
|
+
def reload!
|
|
269
|
+
puts "Reloading HTM library..."
|
|
270
|
+
load 'lib/htm.rb'
|
|
271
|
+
@htm = nil
|
|
272
|
+
@user = nil
|
|
273
|
+
@assistant = nil
|
|
274
|
+
@researcher = nil
|
|
275
|
+
@coder = nil
|
|
276
|
+
puts "✓ Reloaded"
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# Help
|
|
115
280
|
def htm_help
|
|
116
|
-
puts <<~
|
|
281
|
+
puts <<~HELP
|
|
117
282
|
|
|
118
283
|
============================================================
|
|
119
284
|
HTM Interactive Console
|
|
120
285
|
============================================================
|
|
121
286
|
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
287
|
+
ROBOT INSTANCES (lazy-loaded):
|
|
288
|
+
htm - Default console instance
|
|
289
|
+
user - "User" robot (the human)
|
|
290
|
+
assistant - "Assistant" robot
|
|
291
|
+
researcher - "Researcher" robot
|
|
292
|
+
coder - "Coder" robot
|
|
293
|
+
|
|
294
|
+
MODEL CONSTANTS:
|
|
295
|
+
Node, Tag, NodeTag, Robot, RobotNode, FileSource
|
|
296
|
+
|
|
297
|
+
MEMORY OPERATIONS:
|
|
298
|
+
remember(content, type:, importance:, tags:)
|
|
299
|
+
recall(query, limit:, raw:)
|
|
300
|
+
search(query, strategy:, limit:)
|
|
301
|
+
similar_to(node_id, limit:)
|
|
302
|
+
|
|
303
|
+
NODE EXPLORATION:
|
|
304
|
+
recent_nodes(limit)
|
|
305
|
+
recent_by_robot(robot_name, limit)
|
|
306
|
+
node_info(node_id)
|
|
307
|
+
nodes_in(timeframe)
|
|
308
|
+
|
|
309
|
+
TAG EXPLORATION:
|
|
310
|
+
tag_tree(prefix)
|
|
311
|
+
recent_tags(limit)
|
|
312
|
+
popular_tags(limit)
|
|
313
|
+
search_tags(pattern)
|
|
314
|
+
|
|
315
|
+
ROBOT EXPLORATION:
|
|
316
|
+
list_robots
|
|
127
317
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
recent_tags(n) # Show n recent tags (default: 10)
|
|
133
|
-
search_tags(pattern) # Search tags by pattern
|
|
134
|
-
node_with_tags(id) # Show node details with tags
|
|
135
|
-
create_test_node(str) # Create a test node
|
|
136
|
-
reload! # Reload HTM library
|
|
318
|
+
FILE LOADING:
|
|
319
|
+
load_file(path, force:)
|
|
320
|
+
load_directory(path, pattern:, force:)
|
|
321
|
+
loaded_files
|
|
137
322
|
|
|
138
|
-
|
|
139
|
-
|
|
323
|
+
TIMEFRAME HELPERS:
|
|
324
|
+
today, yesterday, this_week, last_week
|
|
325
|
+
|
|
326
|
+
RUBYLLM:
|
|
327
|
+
llm - RubyLLM module
|
|
328
|
+
chat(message, model:) - Quick chat
|
|
329
|
+
embed(text, model:) - Generate embedding
|
|
330
|
+
|
|
331
|
+
DATABASE:
|
|
332
|
+
db_stats - Show table counts
|
|
333
|
+
health - Full health check
|
|
334
|
+
healthy? - Quick boolean check
|
|
335
|
+
|
|
336
|
+
UTILITIES:
|
|
337
|
+
reload! - Reload HTM library
|
|
338
|
+
htm_help - Show this help
|
|
339
|
+
|
|
340
|
+
HELP
|
|
341
|
+
nil
|
|
140
342
|
end
|
|
141
343
|
|
|
142
|
-
|
|
143
|
-
|
|
344
|
+
puts "✓ Helpers loaded"
|
|
345
|
+
puts "=" * 60
|
|
346
|
+
puts "\nType 'htm_help' for available commands\n\n"
|
|
144
347
|
|
|
145
|
-
|
|
348
|
+
db_stats
|
data/.tbls.yml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# tbls configuration for HTM database documentation
|
|
2
|
+
# https://github.com/k1LoW/tbls
|
|
3
|
+
|
|
4
|
+
# Database connection - uses HTM_DBURL environment variable
|
|
5
|
+
# tbls expands environment variables with $VAR or ${VAR} syntax
|
|
6
|
+
dsn: $HTM_DBURL
|
|
7
|
+
|
|
8
|
+
# Output documentation to docs/database directory
|
|
9
|
+
docPath: docs/database
|
|
10
|
+
|
|
11
|
+
# Documentation format options
|
|
12
|
+
format:
|
|
13
|
+
adjust_table_width: true
|
|
14
|
+
sort: true
|
|
15
|
+
|
|
16
|
+
# ER diagram settings
|
|
17
|
+
er:
|
|
18
|
+
format: svg
|
|
19
|
+
comment: true
|
|
20
|
+
distance: 2
|
|
21
|
+
|
|
22
|
+
# Include schema metadata
|
|
23
|
+
include:
|
|
24
|
+
- public.*
|
|
25
|
+
|
|
26
|
+
# Lint rules for schema quality
|
|
27
|
+
lint:
|
|
28
|
+
requireColumnComment:
|
|
29
|
+
enabled: false
|
|
30
|
+
requireTableComment:
|
|
31
|
+
enabled: false
|