htm 0.0.1
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 +7 -0
- data/.architecture/decisions/adrs/001-use-postgresql-timescaledb-storage.md +227 -0
- data/.architecture/decisions/adrs/002-two-tier-memory-architecture.md +322 -0
- data/.architecture/decisions/adrs/003-ollama-default-embedding-provider.md +339 -0
- data/.architecture/decisions/adrs/004-multi-robot-shared-memory-hive-mind.md +374 -0
- data/.architecture/decisions/adrs/005-rag-based-retrieval-with-hybrid-search.md +443 -0
- data/.architecture/decisions/adrs/006-context-assembly-strategies.md +444 -0
- data/.architecture/decisions/adrs/007-working-memory-eviction-strategy.md +461 -0
- data/.architecture/decisions/adrs/008-robot-identification-system.md +550 -0
- data/.architecture/decisions/adrs/009-never-forget-explicit-deletion-only.md +570 -0
- data/.architecture/decisions/adrs/010-redis-working-memory-rejected.md +323 -0
- data/.architecture/decisions/adrs/011-database-side-embedding-generation-with-pgai.md +585 -0
- data/.architecture/decisions/adrs/012-llm-driven-ontology-topic-extraction.md +583 -0
- data/.architecture/decisions/adrs/013-activerecord-orm-and-many-to-many-tagging.md +299 -0
- data/.architecture/decisions/adrs/014-client-side-embedding-generation-workflow.md +569 -0
- data/.architecture/decisions/adrs/015-hierarchical-tag-ontology-and-llm-extraction.md +701 -0
- data/.architecture/decisions/adrs/016-async-embedding-and-tag-generation.md +694 -0
- data/.architecture/members.yml +144 -0
- data/.architecture/reviews/2025-10-29-llm-configuration-and-async-processing-review.md +1137 -0
- data/.architecture/reviews/initial-system-analysis.md +330 -0
- data/.envrc +32 -0
- data/.irbrc +145 -0
- data/CHANGELOG.md +150 -0
- data/COMMITS.md +196 -0
- data/LICENSE +21 -0
- data/README.md +1347 -0
- data/Rakefile +51 -0
- data/SETUP.md +268 -0
- data/config/database.yml +67 -0
- data/db/migrate/20250101000001_enable_extensions.rb +14 -0
- data/db/migrate/20250101000002_create_robots.rb +14 -0
- data/db/migrate/20250101000003_create_nodes.rb +42 -0
- data/db/migrate/20250101000005_create_tags.rb +38 -0
- data/db/migrate/20250101000007_add_node_vector_indexes.rb +30 -0
- data/db/schema.sql +473 -0
- data/db/seed_data/README.md +100 -0
- data/db/seed_data/presidents.md +136 -0
- data/db/seed_data/states.md +151 -0
- data/db/seeds.rb +208 -0
- data/dbdoc/README.md +173 -0
- data/dbdoc/public.node_stats.md +48 -0
- data/dbdoc/public.node_stats.svg +41 -0
- data/dbdoc/public.node_tags.md +40 -0
- data/dbdoc/public.node_tags.svg +112 -0
- data/dbdoc/public.nodes.md +54 -0
- data/dbdoc/public.nodes.svg +118 -0
- data/dbdoc/public.nodes_tags.md +39 -0
- data/dbdoc/public.nodes_tags.svg +112 -0
- data/dbdoc/public.ontology_structure.md +48 -0
- data/dbdoc/public.ontology_structure.svg +38 -0
- data/dbdoc/public.operations_log.md +42 -0
- data/dbdoc/public.operations_log.svg +130 -0
- data/dbdoc/public.relationships.md +39 -0
- data/dbdoc/public.relationships.svg +41 -0
- data/dbdoc/public.robot_activity.md +46 -0
- data/dbdoc/public.robot_activity.svg +35 -0
- data/dbdoc/public.robots.md +35 -0
- data/dbdoc/public.robots.svg +90 -0
- data/dbdoc/public.schema_migrations.md +29 -0
- data/dbdoc/public.schema_migrations.svg +26 -0
- data/dbdoc/public.tags.md +35 -0
- data/dbdoc/public.tags.svg +60 -0
- data/dbdoc/public.topic_relationships.md +45 -0
- data/dbdoc/public.topic_relationships.svg +32 -0
- data/dbdoc/schema.json +1437 -0
- data/dbdoc/schema.svg +154 -0
- data/docs/api/database.md +806 -0
- data/docs/api/embedding-service.md +532 -0
- data/docs/api/htm.md +797 -0
- data/docs/api/index.md +259 -0
- data/docs/api/long-term-memory.md +1096 -0
- data/docs/api/working-memory.md +665 -0
- data/docs/architecture/adrs/001-postgresql-timescaledb.md +314 -0
- data/docs/architecture/adrs/002-two-tier-memory.md +411 -0
- data/docs/architecture/adrs/003-ollama-embeddings.md +421 -0
- data/docs/architecture/adrs/004-hive-mind.md +437 -0
- data/docs/architecture/adrs/005-rag-retrieval.md +531 -0
- data/docs/architecture/adrs/006-context-assembly.md +496 -0
- data/docs/architecture/adrs/007-eviction-strategy.md +645 -0
- data/docs/architecture/adrs/008-robot-identification.md +625 -0
- data/docs/architecture/adrs/009-never-forget.md +648 -0
- data/docs/architecture/adrs/010-redis-working-memory-rejected.md +323 -0
- data/docs/architecture/adrs/011-pgai-integration.md +494 -0
- data/docs/architecture/adrs/index.md +215 -0
- data/docs/architecture/hive-mind.md +736 -0
- data/docs/architecture/index.md +351 -0
- data/docs/architecture/overview.md +538 -0
- data/docs/architecture/two-tier-memory.md +873 -0
- data/docs/assets/css/custom.css +83 -0
- data/docs/assets/images/htm-core-components.svg +63 -0
- data/docs/assets/images/htm-database-schema.svg +93 -0
- data/docs/assets/images/htm-hive-mind-architecture.svg +125 -0
- data/docs/assets/images/htm-importance-scoring-framework.svg +83 -0
- data/docs/assets/images/htm-layered-architecture.svg +71 -0
- data/docs/assets/images/htm-long-term-memory-architecture.svg +115 -0
- data/docs/assets/images/htm-working-memory-architecture.svg +120 -0
- data/docs/assets/images/htm.jpg +0 -0
- data/docs/assets/images/htm_demo.gif +0 -0
- data/docs/assets/js/mathjax.js +18 -0
- data/docs/assets/videos/htm_video.mp4 +0 -0
- data/docs/database_rake_tasks.md +322 -0
- data/docs/development/contributing.md +787 -0
- data/docs/development/index.md +336 -0
- data/docs/development/schema.md +596 -0
- data/docs/development/setup.md +719 -0
- data/docs/development/testing.md +819 -0
- data/docs/guides/adding-memories.md +824 -0
- data/docs/guides/context-assembly.md +1009 -0
- data/docs/guides/getting-started.md +577 -0
- data/docs/guides/index.md +118 -0
- data/docs/guides/long-term-memory.md +941 -0
- data/docs/guides/multi-robot.md +866 -0
- data/docs/guides/recalling-memories.md +927 -0
- data/docs/guides/search-strategies.md +953 -0
- data/docs/guides/working-memory.md +717 -0
- data/docs/index.md +214 -0
- data/docs/installation.md +477 -0
- data/docs/multi_framework_support.md +519 -0
- data/docs/quick-start.md +655 -0
- data/docs/setup_local_database.md +302 -0
- data/docs/using_rake_tasks_in_your_app.md +383 -0
- data/examples/basic_usage.rb +93 -0
- data/examples/cli_app/README.md +317 -0
- data/examples/cli_app/htm_cli.rb +270 -0
- data/examples/custom_llm_configuration.rb +183 -0
- data/examples/example_app/Rakefile +71 -0
- data/examples/example_app/app.rb +206 -0
- data/examples/sinatra_app/Gemfile +21 -0
- data/examples/sinatra_app/app.rb +335 -0
- data/lib/htm/active_record_config.rb +113 -0
- data/lib/htm/configuration.rb +342 -0
- data/lib/htm/database.rb +594 -0
- data/lib/htm/embedding_service.rb +115 -0
- data/lib/htm/errors.rb +34 -0
- data/lib/htm/job_adapter.rb +154 -0
- data/lib/htm/jobs/generate_embedding_job.rb +65 -0
- data/lib/htm/jobs/generate_tags_job.rb +82 -0
- data/lib/htm/long_term_memory.rb +965 -0
- data/lib/htm/models/node.rb +109 -0
- data/lib/htm/models/node_tag.rb +33 -0
- data/lib/htm/models/robot.rb +52 -0
- data/lib/htm/models/tag.rb +76 -0
- data/lib/htm/railtie.rb +76 -0
- data/lib/htm/sinatra.rb +157 -0
- data/lib/htm/tag_service.rb +135 -0
- data/lib/htm/tasks.rb +38 -0
- data/lib/htm/version.rb +5 -0
- data/lib/htm/working_memory.rb +182 -0
- data/lib/htm.rb +400 -0
- data/lib/tasks/db.rake +19 -0
- data/lib/tasks/htm.rake +147 -0
- data/lib/tasks/jobs.rake +312 -0
- data/mkdocs.yml +190 -0
- data/scripts/install_local_database.sh +309 -0
- metadata +341 -0
|
@@ -0,0 +1,736 @@
|
|
|
1
|
+
# Hive Mind Architecture: Multi-Robot Shared Memory
|
|
2
|
+
|
|
3
|
+
HTM implements a "hive mind" architecture where multiple robots (AI agents) share a global memory database. This enables cross-robot learning, context continuity across sessions, and collaborative knowledge building without requiring users to repeat information.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
In the hive mind model, all robots access a single shared long-term memory database while maintaining independent working memory for process isolation. This design provides the best of both worlds: global knowledge sharing with local performance optimization.
|
|
8
|
+
|
|
9
|
+
<svg viewBox="0 0 900 600" xmlns="http://www.w3.org/2000/svg" style="background: transparent;">
|
|
10
|
+
<!-- Title -->
|
|
11
|
+
<text x="450" y="30" text-anchor="middle" fill="#E0E0E0" font-size="18" font-weight="bold">Hive Mind: Shared Long-Term Memory</text>
|
|
12
|
+
|
|
13
|
+
<!-- Central Database -->
|
|
14
|
+
<ellipse cx="450" cy="300" rx="180" ry="120" fill="rgba(156, 39, 176, 0.2)" stroke="#9C27B0" stroke-width="3"/>
|
|
15
|
+
<text x="450" y="280" text-anchor="middle" fill="#E0E0E0" font-size="16" font-weight="bold">Long-Term Memory</text>
|
|
16
|
+
<text x="450" y="305" text-anchor="middle" fill="#B0B0B0" font-size="12">PostgreSQL</text>
|
|
17
|
+
<text x="450" y="325" text-anchor="middle" fill="#B0B0B0" font-size="12">Shared Global Database</text>
|
|
18
|
+
<text x="450" y="345" text-anchor="middle" fill="#4CAF50" font-size="13" font-weight="bold">All Robots Access Here</text>
|
|
19
|
+
|
|
20
|
+
<!-- Robot 1: Code Helper -->
|
|
21
|
+
<rect x="50" y="80" width="200" height="100" fill="rgba(33, 150, 243, 0.2)" stroke="#2196F3" stroke-width="2" rx="5"/>
|
|
22
|
+
<text x="150" y="110" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 1: Code Helper</text>
|
|
23
|
+
<text x="150" y="135" text-anchor="middle" fill="#B0B0B0" font-size="11">ID: robot-abc123</text>
|
|
24
|
+
<text x="150" y="155" text-anchor="middle" fill="#B0B0B0" font-size="11">Own Working Memory</text>
|
|
25
|
+
|
|
26
|
+
<!-- Robot 2: Research Assistant -->
|
|
27
|
+
<rect x="650" y="80" width="200" height="100" fill="rgba(76, 175, 80, 0.2)" stroke="#4CAF50" stroke-width="2" rx="5"/>
|
|
28
|
+
<text x="750" y="110" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 2: Research Bot</text>
|
|
29
|
+
<text x="750" y="135" text-anchor="middle" fill="#B0B0B0" font-size="11">ID: robot-xyz789</text>
|
|
30
|
+
<text x="750" y="155" text-anchor="middle" fill="#B0B0B0" font-size="11">Own Working Memory</text>
|
|
31
|
+
|
|
32
|
+
<!-- Robot 3: Chat Companion -->
|
|
33
|
+
<rect x="50" y="450" width="200" height="100" fill="rgba(255, 152, 0, 0.2)" stroke="#FF9800" stroke-width="2" rx="5"/>
|
|
34
|
+
<text x="150" y="480" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 3: Chat Bot</text>
|
|
35
|
+
<text x="150" y="505" text-anchor="middle" fill="#B0B0B0" font-size="11">ID: robot-def456</text>
|
|
36
|
+
<text x="150" y="525" text-anchor="middle" fill="#B0B0B0" font-size="11">Own Working Memory</text>
|
|
37
|
+
|
|
38
|
+
<!-- Robot 4: Design Assistant -->
|
|
39
|
+
<rect x="650" y="450" width="200" height="100" fill="rgba(244, 67, 54, 0.2)" stroke="#F44336" stroke-width="2" rx="5"/>
|
|
40
|
+
<text x="750" y="480" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 4: Designer</text>
|
|
41
|
+
<text x="750" y="505" text-anchor="middle" fill="#B0B0B0" font-size="11">ID: robot-ghi012</text>
|
|
42
|
+
<text x="750" y="525" text-anchor="middle" fill="#B0B0B0" font-size="11">Own Working Memory</text>
|
|
43
|
+
|
|
44
|
+
<!-- Connections to central database -->
|
|
45
|
+
<line x1="150" y1="180" x2="320" y2="240" stroke="#2196F3" stroke-width="3"/>
|
|
46
|
+
<line x1="750" y1="180" x2="580" y2="240" stroke="#4CAF50" stroke-width="3"/>
|
|
47
|
+
<line x1="150" y1="450" x2="320" y2="360" stroke="#FF9800" stroke-width="3"/>
|
|
48
|
+
<line x1="750" y1="450" x2="580" y2="360" stroke="#F44336" stroke-width="3"/>
|
|
49
|
+
|
|
50
|
+
<!-- Labels on connections -->
|
|
51
|
+
<text x="235" y="210" fill="#2196F3" font-size="10">read/write</text>
|
|
52
|
+
<text x="650" y="210" fill="#4CAF50" font-size="10">read/write</text>
|
|
53
|
+
<text x="235" y="410" fill="#FF9800" font-size="10">read/write</text>
|
|
54
|
+
<text x="650" y="410" fill="#F44336" font-size="10">read/write</text>
|
|
55
|
+
|
|
56
|
+
<!-- Key benefit -->
|
|
57
|
+
<rect x="300" y="520" width="300" height="60" fill="rgba(76, 175, 80, 0.1)" stroke="#4CAF50" stroke-width="2" rx="5"/>
|
|
58
|
+
<text x="450" y="545" text-anchor="middle" fill="#4CAF50" font-size="13" font-weight="bold">Knowledge Sharing:</text>
|
|
59
|
+
<text x="450" y="565" text-anchor="middle" fill="#B0B0B0" font-size="11">All robots see all memories</text>
|
|
60
|
+
</svg>
|
|
61
|
+
|
|
62
|
+
!!! info "Related ADR"
|
|
63
|
+
See [ADR-004: Multi-Robot Shared Memory (Hive Mind)](adrs/004-hive-mind.md) for the complete architectural decision record.
|
|
64
|
+
|
|
65
|
+
## Why Hive Mind?
|
|
66
|
+
|
|
67
|
+
### Problems with Isolated Memory
|
|
68
|
+
|
|
69
|
+
When each robot has independent memory:
|
|
70
|
+
|
|
71
|
+
- Users repeat information across robots
|
|
72
|
+
- Context lost when switching robots
|
|
73
|
+
- No cross-robot learning
|
|
74
|
+
- Fragmented conversation history
|
|
75
|
+
- Architectural decisions made by one robot unknown to others
|
|
76
|
+
|
|
77
|
+
### Benefits of Shared Memory
|
|
78
|
+
|
|
79
|
+
With the hive mind architecture:
|
|
80
|
+
|
|
81
|
+
- **Context continuity**: User never repeats themselves
|
|
82
|
+
- **Cross-robot learning**: Knowledge compounds across agents
|
|
83
|
+
- **Seamless switching**: Switch robots without losing context
|
|
84
|
+
- **Unified knowledge base**: Single source of truth
|
|
85
|
+
- **Collaborative development**: Robots build on each other's work
|
|
86
|
+
|
|
87
|
+
!!! success "User Experience"
|
|
88
|
+
With shared memory, users can switch from a code helper to a research assistant without explaining the project context again. The research assistant already knows what the code helper learned.
|
|
89
|
+
|
|
90
|
+
## Architecture Design
|
|
91
|
+
|
|
92
|
+
### Memory Topology
|
|
93
|
+
|
|
94
|
+
HTM uses a hybrid memory topology:
|
|
95
|
+
|
|
96
|
+
- **Long-Term Memory**: Shared globally across all robots
|
|
97
|
+
- **Working Memory**: Per-robot, process-local
|
|
98
|
+
|
|
99
|
+
<svg viewBox="0 0 800 500" xmlns="http://www.w3.org/2000/svg" style="background: transparent;">
|
|
100
|
+
<!-- Title -->
|
|
101
|
+
<text x="400" y="30" text-anchor="middle" fill="#E0E0E0" font-size="16" font-weight="bold">Memory Topology: Shared LTM + Local WM</text>
|
|
102
|
+
|
|
103
|
+
<!-- Legend -->
|
|
104
|
+
<rect x="50" y="50" width="20" height="20" fill="rgba(156, 39, 176, 0.3)" stroke="#9C27B0"/>
|
|
105
|
+
<text x="80" y="65" fill="#B0B0B0" font-size="12">Shared (Global)</text>
|
|
106
|
+
<rect x="200" y="50" width="20" height="20" fill="rgba(33, 150, 243, 0.3)" stroke="#2196F3"/>
|
|
107
|
+
<text x="230" y="65" fill="#B0B0B0" font-size="12">Per-Robot (Local)</text>
|
|
108
|
+
|
|
109
|
+
<!-- Robot 1 -->
|
|
110
|
+
<g transform="translate(0, 100)">
|
|
111
|
+
<text x="150" y="0" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 1 (Process 1)</text>
|
|
112
|
+
<rect x="50" y="20" width="200" height="80" fill="rgba(33, 150, 243, 0.2)" stroke="#2196F3" stroke-width="2" rx="5"/>
|
|
113
|
+
<text x="150" y="50" text-anchor="middle" fill="#E0E0E0" font-size="12">Working Memory</text>
|
|
114
|
+
<text x="150" y="70" text-anchor="middle" fill="#B0B0B0" font-size="10">In-memory, token-limited</text>
|
|
115
|
+
<text x="150" y="85" text-anchor="middle" fill="#B0B0B0" font-size="10">Independent</text>
|
|
116
|
+
</g>
|
|
117
|
+
|
|
118
|
+
<!-- Robot 2 -->
|
|
119
|
+
<g transform="translate(300, 100)">
|
|
120
|
+
<text x="150" y="0" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 2 (Process 2)</text>
|
|
121
|
+
<rect x="50" y="20" width="200" height="80" fill="rgba(33, 150, 243, 0.2)" stroke="#2196F3" stroke-width="2" rx="5"/>
|
|
122
|
+
<text x="150" y="50" text-anchor="middle" fill="#E0E0E0" font-size="12">Working Memory</text>
|
|
123
|
+
<text x="150" y="70" text-anchor="middle" fill="#B0B0B0" font-size="10">In-memory, token-limited</text>
|
|
124
|
+
<text x="150" y="85" text-anchor="middle" fill="#B0B0B0" font-size="10">Independent</text>
|
|
125
|
+
</g>
|
|
126
|
+
|
|
127
|
+
<!-- Shared Long-Term Memory -->
|
|
128
|
+
<rect x="150" y="280" width="500" height="150" fill="rgba(156, 39, 176, 0.2)" stroke="#9C27B0" stroke-width="3" rx="5"/>
|
|
129
|
+
<text x="400" y="310" text-anchor="middle" fill="#E0E0E0" font-size="16" font-weight="bold">Long-Term Memory (Shared)</text>
|
|
130
|
+
<text x="400" y="340" text-anchor="middle" fill="#B0B0B0" font-size="12">PostgreSQL</text>
|
|
131
|
+
<text x="400" y="365" text-anchor="middle" fill="#B0B0B0" font-size="12">All robots read/write here</text>
|
|
132
|
+
<text x="400" y="390" text-anchor="middle" fill="#B0B0B0" font-size="12">Memories attributed with robot_id</text>
|
|
133
|
+
<text x="400" y="410" text-anchor="middle" fill="#4CAF50" font-size="12" font-weight="bold">Single Source of Truth</text>
|
|
134
|
+
|
|
135
|
+
<!-- Connections -->
|
|
136
|
+
<line x1="150" y1="200" x2="300" y2="280" stroke="#9C27B0" stroke-width="2" marker-end="url(#arrow-purple)"/>
|
|
137
|
+
<line x1="450" y1="200" x2="400" y2="280" stroke="#9C27B0" stroke-width="2" marker-end="url(#arrow-purple)"/>
|
|
138
|
+
|
|
139
|
+
<text x="225" y="240" fill="#9C27B0" font-size="10">read/write</text>
|
|
140
|
+
<text x="425" y="240" fill="#9C27B0" font-size="10">read/write</text>
|
|
141
|
+
|
|
142
|
+
<defs>
|
|
143
|
+
<marker id="arrow-purple" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
144
|
+
<polygon points="0 0, 10 3, 0 6" fill="#9C27B0"/>
|
|
145
|
+
</marker>
|
|
146
|
+
</defs>
|
|
147
|
+
|
|
148
|
+
<!-- Key Point -->
|
|
149
|
+
<rect x="100" y="460" width="600" height="30" fill="rgba(76, 175, 80, 0.1)" stroke="#4CAF50" stroke-width="1" rx="3"/>
|
|
150
|
+
<text x="400" y="480" text-anchor="middle" fill="#4CAF50" font-size="12">Each robot has fast local cache (WM) + access to global knowledge (LTM)</text>
|
|
151
|
+
</svg>
|
|
152
|
+
|
|
153
|
+
### Why This Design?
|
|
154
|
+
|
|
155
|
+
**Shared Long-Term Memory:**
|
|
156
|
+
|
|
157
|
+
- Global knowledge base accessible to all robots
|
|
158
|
+
- Cross-robot context continuity
|
|
159
|
+
- Simplified architecture (single database)
|
|
160
|
+
- Unified search across all conversations
|
|
161
|
+
|
|
162
|
+
**Per-Robot Working Memory:**
|
|
163
|
+
|
|
164
|
+
- Fast O(1) local access without network overhead
|
|
165
|
+
- Process isolation (no distributed state synchronization)
|
|
166
|
+
- Independent token budgets per robot
|
|
167
|
+
- Simple implementation (Ruby Hash, no Redis needed)
|
|
168
|
+
|
|
169
|
+
!!! warning "Design Trade-off"
|
|
170
|
+
This architecture optimizes for **single-user, multi-robot** scenarios. For multi-tenant deployments, add row-level security or database sharding by tenant_id.
|
|
171
|
+
|
|
172
|
+
## Robot Identification System
|
|
173
|
+
|
|
174
|
+
Every robot in the hive mind has a unique identity for attribution tracking and activity monitoring.
|
|
175
|
+
|
|
176
|
+
### Dual Identifier System
|
|
177
|
+
|
|
178
|
+
HTM uses two identifiers for each robot:
|
|
179
|
+
|
|
180
|
+
#### 1. Robot ID (`robot_id`)
|
|
181
|
+
|
|
182
|
+
- **Type**: UUID v4 (RFC 4122)
|
|
183
|
+
- **Format**: `"f47ac10b-58cc-4372-a567-0e02b2c3d479"`
|
|
184
|
+
- **Generation**: `SecureRandom.uuid` if not provided
|
|
185
|
+
- **Purpose**: Primary key, foreign key references, attribution
|
|
186
|
+
- **Uniqueness**: Guaranteed (collision probability: ~10^-36)
|
|
187
|
+
|
|
188
|
+
#### 2. Robot Name (`robot_name`)
|
|
189
|
+
|
|
190
|
+
- **Type**: String (human-readable)
|
|
191
|
+
- **Format**: Any descriptive string (e.g., "Code Helper", "Research Assistant")
|
|
192
|
+
- **Generation**: `"robot_#{robot_id[0..7]}"` if not provided
|
|
193
|
+
- **Purpose**: Display, debugging, logging
|
|
194
|
+
- **Uniqueness**: Not enforced (names can collide)
|
|
195
|
+
|
|
196
|
+
### Robot Initialization
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
# Option 1: Auto-generated identity (ephemeral robot)
|
|
200
|
+
htm = HTM.new(robot_name: "Code Helper")
|
|
201
|
+
# robot_id: auto-generated UUID (new each session)
|
|
202
|
+
# robot_name: "Code Helper"
|
|
203
|
+
|
|
204
|
+
# Option 2: Persistent identity (stable robot)
|
|
205
|
+
ROBOT_ID = ENV['ROBOT_ID'] || "f47ac10b-58cc-4372-a567-0e02b2c3d479"
|
|
206
|
+
htm = HTM.new(
|
|
207
|
+
robot_id: ROBOT_ID,
|
|
208
|
+
robot_name: "Code Helper"
|
|
209
|
+
)
|
|
210
|
+
# robot_id: same across sessions
|
|
211
|
+
# robot_name: "Code Helper"
|
|
212
|
+
|
|
213
|
+
# Option 3: Minimal (auto-generate everything)
|
|
214
|
+
htm = HTM.new
|
|
215
|
+
# robot_id: auto-generated UUID
|
|
216
|
+
# robot_name: "robot_f47ac10b" (derived from UUID)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
!!! tip "Persistent vs Ephemeral Robots"
|
|
220
|
+
- **Ephemeral**: New UUID every session. Useful for testing or one-off tasks.
|
|
221
|
+
- **Persistent**: Store robot_id in config/environment. Recommended for production robots with stable identities.
|
|
222
|
+
|
|
223
|
+
### Robot Registry
|
|
224
|
+
|
|
225
|
+
All robots are registered in the `robots` table on first initialization:
|
|
226
|
+
|
|
227
|
+
```sql
|
|
228
|
+
CREATE TABLE robots (
|
|
229
|
+
id TEXT PRIMARY KEY, -- robot_id (UUID)
|
|
230
|
+
name TEXT, -- robot_name (human-readable)
|
|
231
|
+
created_at TIMESTAMP DEFAULT NOW(),
|
|
232
|
+
last_active TIMESTAMP DEFAULT NOW(),
|
|
233
|
+
metadata JSONB -- future extensibility
|
|
234
|
+
);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Registration flow:**
|
|
238
|
+
|
|
239
|
+
```ruby
|
|
240
|
+
def register_robot
|
|
241
|
+
@long_term_memory.register_robot(@robot_id, @robot_name)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# SQL: UPSERT semantics
|
|
245
|
+
# INSERT INTO robots (id, name) VALUES ($1, $2)
|
|
246
|
+
# ON CONFLICT (id) DO UPDATE
|
|
247
|
+
# SET name = $2, last_active = CURRENT_TIMESTAMP
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
!!! info "Related ADR"
|
|
251
|
+
See [ADR-008: Robot Identification System](adrs/008-robot-identification.md) for detailed design decisions.
|
|
252
|
+
|
|
253
|
+
## Memory Attribution
|
|
254
|
+
|
|
255
|
+
Every memory node stores the `robot_id` of the robot that created it, enabling attribution tracking and analysis.
|
|
256
|
+
|
|
257
|
+
### Attribution Schema
|
|
258
|
+
|
|
259
|
+
```sql
|
|
260
|
+
CREATE TABLE nodes (
|
|
261
|
+
id BIGSERIAL PRIMARY KEY,
|
|
262
|
+
key TEXT UNIQUE NOT NULL,
|
|
263
|
+
value TEXT NOT NULL,
|
|
264
|
+
robot_id TEXT NOT NULL REFERENCES robots(id), -- Attribution!
|
|
265
|
+
...
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
-- Index for robot-specific queries
|
|
269
|
+
CREATE INDEX idx_nodes_robot_id ON nodes(robot_id);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Attribution Tracking
|
|
273
|
+
|
|
274
|
+
When a robot adds a memory:
|
|
275
|
+
|
|
276
|
+
```ruby
|
|
277
|
+
def add_node(key, value, ...)
|
|
278
|
+
# Store with attribution
|
|
279
|
+
node_id = @long_term_memory.add(
|
|
280
|
+
key: key,
|
|
281
|
+
value: value,
|
|
282
|
+
robot_id: @robot_id, # Attribution
|
|
283
|
+
...
|
|
284
|
+
)
|
|
285
|
+
end
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Attribution Queries
|
|
289
|
+
|
|
290
|
+
#### Which robot said this?
|
|
291
|
+
|
|
292
|
+
```ruby
|
|
293
|
+
def which_robot_said(topic, limit: 100)
|
|
294
|
+
results = @long_term_memory.search_fulltext(
|
|
295
|
+
timeframe: (Time.at(0)..Time.now),
|
|
296
|
+
query: topic,
|
|
297
|
+
limit: limit
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
results.group_by { |n| n['robot_id'] }
|
|
301
|
+
.transform_values(&:count)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# Example usage
|
|
305
|
+
breakdown = htm.which_robot_said("PostgreSQL")
|
|
306
|
+
# => { "robot-abc123" => 15, "robot-xyz789" => 8 }
|
|
307
|
+
|
|
308
|
+
# Get robot names
|
|
309
|
+
breakdown.map do |robot_id, count|
|
|
310
|
+
robot = db.query("SELECT name FROM robots WHERE id = $1", [robot_id]).first
|
|
311
|
+
"#{robot['name']}: #{count} mentions"
|
|
312
|
+
end
|
|
313
|
+
# => ["Code Helper: 15 mentions", "Research Bot: 8 mentions"]
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
#### Conversation timeline
|
|
317
|
+
|
|
318
|
+
```ruby
|
|
319
|
+
def conversation_timeline(topic, limit: 50)
|
|
320
|
+
results = @long_term_memory.search_fulltext(
|
|
321
|
+
timeframe: (Time.at(0)..Time.now),
|
|
322
|
+
query: topic,
|
|
323
|
+
limit: limit
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
results.sort_by { |n| n['created_at'] }
|
|
327
|
+
.map { |n| {
|
|
328
|
+
timestamp: n['created_at'],
|
|
329
|
+
robot: n['robot_id'],
|
|
330
|
+
content: n['value'],
|
|
331
|
+
type: n['type']
|
|
332
|
+
}}
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
# Example usage
|
|
336
|
+
timeline = htm.conversation_timeline("HTM design", limit: 20)
|
|
337
|
+
# => [
|
|
338
|
+
# { timestamp: "2025-10-20 10:00:00", robot: "robot-abc123", content: "Let's use PostgreSQL", ... },
|
|
339
|
+
# { timestamp: "2025-10-20 10:15:00", robot: "robot-xyz789", content: "I agree, TimescaleDB is perfect", ... },
|
|
340
|
+
# ...
|
|
341
|
+
# ]
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### Robot activity
|
|
345
|
+
|
|
346
|
+
```sql
|
|
347
|
+
-- Which robots have been active?
|
|
348
|
+
SELECT id, name, last_active
|
|
349
|
+
FROM robots
|
|
350
|
+
ORDER BY last_active DESC;
|
|
351
|
+
|
|
352
|
+
-- Which robot contributed most memories?
|
|
353
|
+
SELECT r.name, COUNT(n.id) as memory_count
|
|
354
|
+
FROM robots r
|
|
355
|
+
LEFT JOIN nodes n ON n.robot_id = r.id
|
|
356
|
+
GROUP BY r.id, r.name
|
|
357
|
+
ORDER BY memory_count DESC;
|
|
358
|
+
|
|
359
|
+
-- What has a specific robot been doing?
|
|
360
|
+
SELECT operation, created_at, details
|
|
361
|
+
FROM operations_log
|
|
362
|
+
WHERE robot_id = 'robot-abc123'
|
|
363
|
+
ORDER BY created_at DESC
|
|
364
|
+
LIMIT 50;
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Cross-Robot Knowledge Sharing
|
|
368
|
+
|
|
369
|
+
The power of the hive mind lies in automatic knowledge sharing across robots.
|
|
370
|
+
|
|
371
|
+
### Use Case 1: Cross-Session Context
|
|
372
|
+
|
|
373
|
+
A user works with Robot A in one session, then Robot B in another session. Robot B automatically knows what Robot A learned.
|
|
374
|
+
|
|
375
|
+
```ruby
|
|
376
|
+
# Session 1 - Robot A (Code Helper)
|
|
377
|
+
htm_a = HTM.new(robot_id: "robot-abc123", robot_name: "Code Helper A")
|
|
378
|
+
htm_a.add_node(
|
|
379
|
+
"user_pref_001",
|
|
380
|
+
"User prefers debug_me over puts for debugging",
|
|
381
|
+
type: :preference,
|
|
382
|
+
importance: 9.0
|
|
383
|
+
)
|
|
384
|
+
# Stored in long-term memory with robot_id: "robot-abc123"
|
|
385
|
+
|
|
386
|
+
# === User logs out, logs in next day ===
|
|
387
|
+
|
|
388
|
+
# Session 2 - Robot B (different process, same or different machine)
|
|
389
|
+
htm_b = HTM.new(robot_id: "robot-xyz789", robot_name: "Code Helper B")
|
|
390
|
+
|
|
391
|
+
# Robot B recalls preferences
|
|
392
|
+
memories = htm_b.recall(timeframe: "last week", topic: "debugging preference")
|
|
393
|
+
# => Finds preference from Robot A!
|
|
394
|
+
# => [{ "key" => "user_pref_001", "robot_id" => "robot-abc123", ... }]
|
|
395
|
+
|
|
396
|
+
# Robot B knows user preference without being told
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Use Case 2: Collaborative Development
|
|
400
|
+
|
|
401
|
+
Different robots working on different aspects of a project can build on each other's knowledge.
|
|
402
|
+
|
|
403
|
+
```ruby
|
|
404
|
+
# Robot A (Architecture discussion)
|
|
405
|
+
htm_a = HTM.new(robot_name: "Architect Bot")
|
|
406
|
+
htm_a.add_node(
|
|
407
|
+
"decision_001",
|
|
408
|
+
"We decided to use PostgreSQL with TimescaleDB for HTM storage",
|
|
409
|
+
type: :decision,
|
|
410
|
+
importance: 10.0,
|
|
411
|
+
tags: ["architecture", "database"]
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
# Robot B (Implementation)
|
|
415
|
+
htm_b = HTM.new(robot_name: "Code Bot")
|
|
416
|
+
memories = htm_b.recall(timeframe: "today", topic: "database decision")
|
|
417
|
+
# => Finds architectural decision from Robot A
|
|
418
|
+
|
|
419
|
+
# Robot B implements based on Robot A's decision
|
|
420
|
+
htm_b.add_node(
|
|
421
|
+
"implementation_001",
|
|
422
|
+
"Implemented Database class with ConnectionPool for PostgreSQL",
|
|
423
|
+
type: :code,
|
|
424
|
+
importance: 7.0,
|
|
425
|
+
related_to: ["decision_001"], # Link to Robot A's decision
|
|
426
|
+
tags: ["implementation", "database"]
|
|
427
|
+
)
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Use Case 3: Multi-Robot Conversation Analysis
|
|
431
|
+
|
|
432
|
+
Analyze contributions from different robots across a conversation:
|
|
433
|
+
|
|
434
|
+
```ruby
|
|
435
|
+
# Get all mentions of "TimescaleDB"
|
|
436
|
+
breakdown = htm.which_robot_said("TimescaleDB", limit: 100)
|
|
437
|
+
# => {
|
|
438
|
+
# "robot-abc123" => 25, # Architect Bot
|
|
439
|
+
# "robot-xyz789" => 12, # Code Bot
|
|
440
|
+
# "robot-def456" => 8 # Research Bot
|
|
441
|
+
# }
|
|
442
|
+
|
|
443
|
+
# Get chronological conversation
|
|
444
|
+
timeline = htm.conversation_timeline("TimescaleDB design", limit: 50)
|
|
445
|
+
# => [
|
|
446
|
+
# { timestamp: "2025-10-20 10:00", robot: "robot-abc123", content: "Let's explore TimescaleDB" },
|
|
447
|
+
# { timestamp: "2025-10-20 10:15", robot: "robot-xyz789", content: "I'll implement the connection" },
|
|
448
|
+
# { timestamp: "2025-10-20 10:30", robot: "robot-def456", content: "Here's the research on compression" },
|
|
449
|
+
# ...
|
|
450
|
+
# ]
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
## Robot Activity Tracking
|
|
454
|
+
|
|
455
|
+
HTM automatically tracks robot activity through:
|
|
456
|
+
|
|
457
|
+
### 1. Robot Registry Updates
|
|
458
|
+
|
|
459
|
+
Every HTM operation updates the robot's `last_active` timestamp:
|
|
460
|
+
|
|
461
|
+
```ruby
|
|
462
|
+
def update_robot_activity
|
|
463
|
+
@long_term_memory.update_robot_activity(@robot_id)
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
# SQL
|
|
467
|
+
# UPDATE robots
|
|
468
|
+
# SET last_active = CURRENT_TIMESTAMP
|
|
469
|
+
# WHERE id = $1
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### 2. Operations Log
|
|
473
|
+
|
|
474
|
+
Every operation is logged with robot attribution:
|
|
475
|
+
|
|
476
|
+
```ruby
|
|
477
|
+
def add_node(key, value, ...)
|
|
478
|
+
# ... add node ...
|
|
479
|
+
|
|
480
|
+
# Log operation
|
|
481
|
+
@long_term_memory.log_operation(
|
|
482
|
+
operation: 'add',
|
|
483
|
+
node_id: node_id,
|
|
484
|
+
robot_id: @robot_id,
|
|
485
|
+
details: { key: key, type: type }
|
|
486
|
+
)
|
|
487
|
+
end
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
```sql
|
|
491
|
+
CREATE TABLE operations_log (
|
|
492
|
+
id BIGSERIAL PRIMARY KEY,
|
|
493
|
+
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
494
|
+
operation TEXT NOT NULL, -- add, retrieve, recall, forget, evict
|
|
495
|
+
node_id BIGINT REFERENCES nodes(id),
|
|
496
|
+
robot_id TEXT NOT NULL REFERENCES robots(id),
|
|
497
|
+
details JSONB
|
|
498
|
+
);
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### 3. Activity Queries
|
|
502
|
+
|
|
503
|
+
```sql
|
|
504
|
+
-- Active robots in last 24 hours
|
|
505
|
+
SELECT id, name, last_active
|
|
506
|
+
FROM robots
|
|
507
|
+
WHERE last_active > NOW() - INTERVAL '24 hours'
|
|
508
|
+
ORDER BY last_active DESC;
|
|
509
|
+
|
|
510
|
+
-- Operations by robot
|
|
511
|
+
SELECT r.name, COUNT(ol.id) as operation_count
|
|
512
|
+
FROM robots r
|
|
513
|
+
JOIN operations_log ol ON ol.robot_id = r.id
|
|
514
|
+
WHERE ol.timestamp > NOW() - INTERVAL '7 days'
|
|
515
|
+
GROUP BY r.name
|
|
516
|
+
ORDER BY operation_count DESC;
|
|
517
|
+
|
|
518
|
+
-- Most active robots by memory contributions
|
|
519
|
+
SELECT r.name, COUNT(n.id) as memory_count
|
|
520
|
+
FROM robots r
|
|
521
|
+
JOIN nodes n ON n.robot_id = r.id
|
|
522
|
+
WHERE n.created_at > NOW() - INTERVAL '30 days'
|
|
523
|
+
GROUP BY r.name
|
|
524
|
+
ORDER BY memory_count DESC;
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Privacy Considerations
|
|
528
|
+
|
|
529
|
+
The hive mind architecture has important privacy implications:
|
|
530
|
+
|
|
531
|
+
### Current Design: Single-User Assumption
|
|
532
|
+
|
|
533
|
+
HTM v1 assumes a **single-user scenario** where all robots work for the same user:
|
|
534
|
+
|
|
535
|
+
- All robots see all memories
|
|
536
|
+
- No isolation between robots
|
|
537
|
+
- No access control or permissions
|
|
538
|
+
- Simple, performant, easy to use
|
|
539
|
+
|
|
540
|
+
!!! warning "Privacy Warning"
|
|
541
|
+
In the current design, **all robots can access all memories**. This is intentional for single-user scenarios but unsuitable for multi-user or multi-tenant deployments without additional security layers.
|
|
542
|
+
|
|
543
|
+
### Future: Multi-Tenancy Support
|
|
544
|
+
|
|
545
|
+
For multi-user scenarios, consider these privacy enhancements:
|
|
546
|
+
|
|
547
|
+
#### 1. Row-Level Security (RLS)
|
|
548
|
+
|
|
549
|
+
PostgreSQL's RLS can enforce tenant isolation:
|
|
550
|
+
|
|
551
|
+
```sql
|
|
552
|
+
-- Enable RLS on nodes table
|
|
553
|
+
ALTER TABLE nodes ENABLE ROW LEVEL SECURITY;
|
|
554
|
+
|
|
555
|
+
-- Policy: Users can only see their own tenant's nodes
|
|
556
|
+
CREATE POLICY tenant_isolation ON nodes
|
|
557
|
+
FOR ALL
|
|
558
|
+
TO PUBLIC
|
|
559
|
+
USING (tenant_id = current_setting('app.tenant_id')::TEXT);
|
|
560
|
+
|
|
561
|
+
-- Set tenant context per connection
|
|
562
|
+
SET app.tenant_id = 'user-123';
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
#### 2. Robot Visibility Levels
|
|
566
|
+
|
|
567
|
+
Add visibility controls to nodes:
|
|
568
|
+
|
|
569
|
+
```sql
|
|
570
|
+
ALTER TABLE nodes ADD COLUMN visibility TEXT DEFAULT 'shared';
|
|
571
|
+
-- Values: 'private' (robot-only), 'shared' (all robots), 'team' (robot group)
|
|
572
|
+
|
|
573
|
+
-- Private memory (only this robot)
|
|
574
|
+
htm.add_node("private_key", "sensitive data", visibility: :private)
|
|
575
|
+
|
|
576
|
+
-- Shared with specific robots
|
|
577
|
+
htm.add_node("team_key", "team data", visibility: { team: ['robot-a', 'robot-b'] })
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
#### 3. Robot Groups/Teams
|
|
581
|
+
|
|
582
|
+
Organize robots into teams with shared memory:
|
|
583
|
+
|
|
584
|
+
```sql
|
|
585
|
+
CREATE TABLE robot_teams (
|
|
586
|
+
id BIGSERIAL PRIMARY KEY,
|
|
587
|
+
name TEXT NOT NULL,
|
|
588
|
+
created_at TIMESTAMP DEFAULT NOW()
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
CREATE TABLE robot_team_members (
|
|
592
|
+
robot_id TEXT REFERENCES robots(id),
|
|
593
|
+
team_id BIGINT REFERENCES robot_teams(id),
|
|
594
|
+
PRIMARY KEY (robot_id, team_id)
|
|
595
|
+
);
|
|
596
|
+
|
|
597
|
+
-- Query memories by team
|
|
598
|
+
SELECT n.*
|
|
599
|
+
FROM nodes n
|
|
600
|
+
JOIN robot_team_members rtm ON rtm.robot_id = n.robot_id
|
|
601
|
+
WHERE rtm.team_id = $1;
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
## Performance Characteristics
|
|
605
|
+
|
|
606
|
+
### Shared Long-Term Memory
|
|
607
|
+
|
|
608
|
+
| Aspect | Performance | Notes |
|
|
609
|
+
|--------|------------|-------|
|
|
610
|
+
| **Concurrent reads** | Excellent | PostgreSQL read scaling |
|
|
611
|
+
| **Concurrent writes** | Good | MVCC handles concurrent inserts |
|
|
612
|
+
| **Attribution queries** | Fast | Indexed on `robot_id` |
|
|
613
|
+
| **Cross-robot search** | Fast | Same as single-robot search |
|
|
614
|
+
| **Registry updates** | Minimal overhead | Simple UPDATE per operation |
|
|
615
|
+
|
|
616
|
+
### Per-Robot Working Memory
|
|
617
|
+
|
|
618
|
+
| Aspect | Performance | Notes |
|
|
619
|
+
|--------|------------|-------|
|
|
620
|
+
| **Memory isolation** | O(1) | No synchronization needed |
|
|
621
|
+
| **Process independence** | Excellent | No shared state |
|
|
622
|
+
| **Eviction** | O(n log n) | Per-robot, doesn't affect others |
|
|
623
|
+
| **Context assembly** | O(n log n) | Per-robot, fast |
|
|
624
|
+
|
|
625
|
+
### Scalability
|
|
626
|
+
|
|
627
|
+
#### Vertical Scaling
|
|
628
|
+
|
|
629
|
+
- **Database connections**: Use connection pooling (default)
|
|
630
|
+
- **Robot count**: Limited by database connections (~100-200 concurrent)
|
|
631
|
+
- **Memory size**: Each robot process uses ~1-2GB RAM for working memory
|
|
632
|
+
|
|
633
|
+
#### Horizontal Scaling
|
|
634
|
+
|
|
635
|
+
- **Multi-process**: Each robot process is independent
|
|
636
|
+
- **Multi-host**: All hosts share PostgreSQL database
|
|
637
|
+
- **Read replicas**: Route reads to replicas, writes to primary
|
|
638
|
+
- **Sharding**: Partition by `robot_id` or `tenant_id` for massive scale
|
|
639
|
+
|
|
640
|
+
## Code Examples
|
|
641
|
+
|
|
642
|
+
### Example 1: Persistent Robot with Stable Identity
|
|
643
|
+
|
|
644
|
+
```ruby
|
|
645
|
+
# Store robot ID in config or environment
|
|
646
|
+
ROBOT_ID = ENV.fetch('ROBOT_ID', 'code-helper-001')
|
|
647
|
+
|
|
648
|
+
# Initialize with persistent identity
|
|
649
|
+
htm = HTM.new(
|
|
650
|
+
robot_id: ROBOT_ID,
|
|
651
|
+
robot_name: "Code Helper",
|
|
652
|
+
working_memory_size: 128_000
|
|
653
|
+
)
|
|
654
|
+
|
|
655
|
+
# Add memories (attributed to this robot)
|
|
656
|
+
htm.add_node("arch_decision", "Use PostgreSQL", importance: 10.0)
|
|
657
|
+
|
|
658
|
+
# All memories from this robot_id across sessions
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Example 2: Multi-Robot Collaboration
|
|
662
|
+
|
|
663
|
+
```ruby
|
|
664
|
+
# Robot A: Architecture discussion
|
|
665
|
+
robot_a = HTM.new(robot_id: "arch-001", robot_name: "Architect")
|
|
666
|
+
robot_a.add_node(
|
|
667
|
+
"db_choice",
|
|
668
|
+
"PostgreSQL chosen for ACID guarantees and pgvector support",
|
|
669
|
+
type: :decision,
|
|
670
|
+
importance: 10.0
|
|
671
|
+
)
|
|
672
|
+
|
|
673
|
+
# Robot B: Implementation (different process, accesses same LTM)
|
|
674
|
+
robot_b = HTM.new(robot_id: "code-001", robot_name: "Coder")
|
|
675
|
+
decisions = robot_b.recall(timeframe: "today", topic: "database")
|
|
676
|
+
# => Finds Robot A's decision automatically
|
|
677
|
+
|
|
678
|
+
robot_b.add_node(
|
|
679
|
+
"db_impl",
|
|
680
|
+
"Implemented Database class with connection pooling",
|
|
681
|
+
type: :code,
|
|
682
|
+
related_to: ["db_choice"] # Link to Robot A's decision
|
|
683
|
+
)
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
### Example 3: Robot Activity Dashboard
|
|
687
|
+
|
|
688
|
+
```ruby
|
|
689
|
+
# Get all robots and their activity
|
|
690
|
+
stats = {}
|
|
691
|
+
|
|
692
|
+
robots = db.query("SELECT * FROM robots ORDER BY last_active DESC")
|
|
693
|
+
|
|
694
|
+
robots.each do |robot|
|
|
695
|
+
# Count memories
|
|
696
|
+
memory_count = db.query(<<~SQL, [robot['id']]).first['count'].to_i
|
|
697
|
+
SELECT COUNT(*) FROM nodes WHERE robot_id = $1
|
|
698
|
+
SQL
|
|
699
|
+
|
|
700
|
+
# Recent operations
|
|
701
|
+
recent_ops = db.query(<<~SQL, [robot['id']]).to_a
|
|
702
|
+
SELECT operation, COUNT(*) as count
|
|
703
|
+
FROM operations_log
|
|
704
|
+
WHERE robot_id = $1 AND timestamp > NOW() - INTERVAL '7 days'
|
|
705
|
+
GROUP BY operation
|
|
706
|
+
SQL
|
|
707
|
+
|
|
708
|
+
stats[robot['name']] = {
|
|
709
|
+
id: robot['id'],
|
|
710
|
+
last_active: robot['last_active'],
|
|
711
|
+
total_memories: memory_count,
|
|
712
|
+
recent_operations: recent_ops
|
|
713
|
+
}
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
# Display dashboard
|
|
717
|
+
stats.each do |name, data|
|
|
718
|
+
puts "#{name} (#{data[:id]})"
|
|
719
|
+
puts " Last active: #{data[:last_active]}"
|
|
720
|
+
puts " Total memories: #{data[:total_memories]}"
|
|
721
|
+
puts " Recent operations:"
|
|
722
|
+
data[:recent_operations].each do |op|
|
|
723
|
+
puts " #{op['operation']}: #{op['count']}"
|
|
724
|
+
end
|
|
725
|
+
puts
|
|
726
|
+
end
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
## Related Documentation
|
|
730
|
+
|
|
731
|
+
- [Architecture Index](index.md) - System overview and component summary
|
|
732
|
+
- [Architecture Overview](overview.md) - Detailed architecture and data flows
|
|
733
|
+
- [Two-Tier Memory System](two-tier-memory.md) - Working memory and long-term memory design
|
|
734
|
+
- [ADR-004: Multi-Robot Shared Memory (Hive Mind)](adrs/004-hive-mind.md)
|
|
735
|
+
- [ADR-008: Robot Identification System](adrs/008-robot-identification.md)
|
|
736
|
+
- [API Reference](../api/htm.md) - Complete API documentation
|