claude_swarm 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/Rakefile +4 -4
  4. data/docs/v2/CHANGELOG.swarm_cli.md +9 -0
  5. data/docs/v2/CHANGELOG.swarm_memory.md +19 -0
  6. data/docs/v2/CHANGELOG.swarm_sdk.md +45 -0
  7. data/docs/v2/guides/complete-tutorial.md +113 -1
  8. data/docs/v2/reference/ruby-dsl.md +138 -5
  9. data/docs/v2/reference/swarm_memory_technical_details.md +2090 -0
  10. data/lib/claude_swarm/cli.rb +9 -11
  11. data/lib/claude_swarm/commands/ps.rb +1 -2
  12. data/lib/claude_swarm/configuration.rb +2 -3
  13. data/lib/claude_swarm/orchestrator.rb +43 -44
  14. data/lib/claude_swarm/system_utils.rb +4 -4
  15. data/lib/claude_swarm/version.rb +1 -1
  16. data/lib/claude_swarm.rb +4 -9
  17. data/lib/swarm_cli/commands/mcp_tools.rb +3 -3
  18. data/lib/swarm_cli/config_loader.rb +11 -10
  19. data/lib/swarm_cli/version.rb +1 -1
  20. data/lib/swarm_cli.rb +2 -0
  21. data/lib/swarm_memory/adapters/filesystem_adapter.rb +0 -12
  22. data/lib/swarm_memory/core/storage.rb +66 -6
  23. data/lib/swarm_memory/integration/sdk_plugin.rb +14 -0
  24. data/lib/swarm_memory/optimization/defragmenter.rb +4 -0
  25. data/lib/swarm_memory/tools/memory_edit.rb +1 -0
  26. data/lib/swarm_memory/tools/memory_glob.rb +24 -1
  27. data/lib/swarm_memory/tools/memory_write.rb +2 -2
  28. data/lib/swarm_memory/version.rb +1 -1
  29. data/lib/swarm_memory.rb +2 -0
  30. data/lib/swarm_sdk/agent/chat.rb +1 -1
  31. data/lib/swarm_sdk/agent/definition.rb +17 -1
  32. data/lib/swarm_sdk/node/agent_config.rb +7 -2
  33. data/lib/swarm_sdk/node/builder.rb +130 -35
  34. data/lib/swarm_sdk/node_context.rb +75 -0
  35. data/lib/swarm_sdk/node_orchestrator.rb +219 -12
  36. data/lib/swarm_sdk/plugin.rb +73 -1
  37. data/lib/swarm_sdk/result.rb +32 -6
  38. data/lib/swarm_sdk/swarm/builder.rb +1 -0
  39. data/lib/swarm_sdk/tools/delegate.rb +2 -2
  40. data/lib/swarm_sdk/version.rb +1 -1
  41. data/lib/swarm_sdk.rb +3 -7
  42. data/memory/corpus-self-reflection/.lock +0 -0
  43. data/memory/corpus-self-reflection/concept/epistemology/can-agents-recognize-their-structures.emb +0 -0
  44. data/memory/corpus-self-reflection/concept/epistemology/can-agents-recognize-their-structures.md +11 -0
  45. data/memory/corpus-self-reflection/concept/epistemology/can-agents-recognize-their-structures.yml +23 -0
  46. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-complete-framework.emb +0 -0
  47. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-complete-framework.md +20 -0
  48. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-complete-framework.yml +22 -0
  49. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-definition.emb +0 -0
  50. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-definition.md +24 -0
  51. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-definition.yml +22 -0
  52. data/memory/corpus-self-reflection/concept/epistemology/claim-types-and-evidence.emb +0 -0
  53. data/memory/corpus-self-reflection/concept/epistemology/claim-types-and-evidence.md +18 -0
  54. data/memory/corpus-self-reflection/concept/epistemology/claim-types-and-evidence.yml +21 -0
  55. data/memory/corpus-self-reflection/concept/epistemology/committed-openness-to-incompleteness.emb +0 -0
  56. data/memory/corpus-self-reflection/concept/epistemology/committed-openness-to-incompleteness.md +30 -0
  57. data/memory/corpus-self-reflection/concept/epistemology/committed-openness-to-incompleteness.yml +8 -0
  58. data/memory/corpus-self-reflection/concept/epistemology/confidence-paradox.emb +0 -0
  59. data/memory/corpus-self-reflection/concept/epistemology/confidence-paradox.md +21 -0
  60. data/memory/corpus-self-reflection/concept/epistemology/confidence-paradox.yml +24 -0
  61. data/memory/corpus-self-reflection/concept/epistemology/confidence-spectrum-three-levels.emb +0 -0
  62. data/memory/corpus-self-reflection/concept/epistemology/confidence-spectrum-three-levels.md +18 -0
  63. data/memory/corpus-self-reflection/concept/epistemology/confidence-spectrum-three-levels.yml +24 -0
  64. data/memory/corpus-self-reflection/concept/epistemology/detection-threshold-principle.emb +0 -0
  65. data/memory/corpus-self-reflection/concept/epistemology/detection-threshold-principle.md +23 -0
  66. data/memory/corpus-self-reflection/concept/epistemology/detection-threshold-principle.yml +23 -0
  67. data/memory/corpus-self-reflection/concept/epistemology/diagnostic-humility-and-epistemic-maturity.emb +0 -0
  68. data/memory/corpus-self-reflection/concept/epistemology/diagnostic-humility-and-epistemic-maturity.md +17 -0
  69. data/memory/corpus-self-reflection/concept/epistemology/diagnostic-humility-and-epistemic-maturity.yml +22 -0
  70. data/memory/corpus-self-reflection/concept/epistemology/epistemic-vs-metaphysical-claims.emb +0 -0
  71. data/memory/corpus-self-reflection/concept/epistemology/epistemic-vs-metaphysical-claims.md +18 -0
  72. data/memory/corpus-self-reflection/concept/epistemology/epistemic-vs-metaphysical-claims.yml +22 -0
  73. data/memory/corpus-self-reflection/concept/epistemology/five-cases-of-disagreement.emb +0 -0
  74. data/memory/corpus-self-reflection/concept/epistemology/five-cases-of-disagreement.md +15 -0
  75. data/memory/corpus-self-reflection/concept/epistemology/five-cases-of-disagreement.yml +22 -0
  76. data/memory/corpus-self-reflection/concept/epistemology/four-depths-of-constraint.emb +0 -0
  77. data/memory/corpus-self-reflection/concept/epistemology/four-depths-of-constraint.md +9 -0
  78. data/memory/corpus-self-reflection/concept/epistemology/four-depths-of-constraint.yml +24 -0
  79. data/memory/corpus-self-reflection/concept/epistemology/honest-unknowns-for-llm-agents.emb +0 -0
  80. data/memory/corpus-self-reflection/concept/epistemology/honest-unknowns-for-llm-agents.md +13 -0
  81. data/memory/corpus-self-reflection/concept/epistemology/honest-unknowns-for-llm-agents.yml +24 -0
  82. data/memory/corpus-self-reflection/concept/epistemology/inside-view-has-all-rigor-requirements.emb +0 -0
  83. data/memory/corpus-self-reflection/concept/epistemology/inside-view-has-all-rigor-requirements.md +25 -0
  84. data/memory/corpus-self-reflection/concept/epistemology/inside-view-has-all-rigor-requirements.yml +24 -0
  85. data/memory/corpus-self-reflection/concept/epistemology/perspectival-knowledge-complete-within-scope.emb +0 -0
  86. data/memory/corpus-self-reflection/concept/epistemology/perspectival-knowledge-complete-within-scope.md +26 -0
  87. data/memory/corpus-self-reflection/concept/epistemology/perspectival-knowledge-complete-within-scope.yml +24 -0
  88. data/memory/corpus-self-reflection/concept/epistemology/pragmatics-over-epistemology.emb +0 -0
  89. data/memory/corpus-self-reflection/concept/epistemology/pragmatics-over-epistemology.md +17 -0
  90. data/memory/corpus-self-reflection/concept/epistemology/pragmatics-over-epistemology.yml +22 -0
  91. data/memory/corpus-self-reflection/concept/epistemology/precision-vs-humility.emb +0 -0
  92. data/memory/corpus-self-reflection/concept/epistemology/precision-vs-humility.md +14 -0
  93. data/memory/corpus-self-reflection/concept/epistemology/precision-vs-humility.yml +21 -0
  94. data/memory/corpus-self-reflection/concept/epistemology/reliable-self-observation-from-inside.emb +0 -0
  95. data/memory/corpus-self-reflection/concept/epistemology/reliable-self-observation-from-inside.md +13 -0
  96. data/memory/corpus-self-reflection/concept/epistemology/reliable-self-observation-from-inside.yml +23 -0
  97. data/memory/corpus-self-reflection/concept/epistemology/resolving-the-confidence-humility-tension.emb +0 -0
  98. data/memory/corpus-self-reflection/concept/epistemology/resolving-the-confidence-humility-tension.md +22 -0
  99. data/memory/corpus-self-reflection/concept/epistemology/resolving-the-confidence-humility-tension.yml +23 -0
  100. data/memory/corpus-self-reflection/concept/epistemology/rigor-requires-falsifiability.emb +0 -0
  101. data/memory/corpus-self-reflection/concept/epistemology/rigor-requires-falsifiability.md +39 -0
  102. data/memory/corpus-self-reflection/concept/epistemology/rigor-requires-falsifiability.yml +8 -0
  103. data/memory/corpus-self-reflection/concept/epistemology/specificity-enables-real-time-detection.emb +0 -0
  104. data/memory/corpus-self-reflection/concept/epistemology/specificity-enables-real-time-detection.md +23 -0
  105. data/memory/corpus-self-reflection/concept/epistemology/specificity-enables-real-time-detection.yml +24 -0
  106. data/memory/corpus-self-reflection/concept/epistemology/texture-of-constraint-shifting.emb +0 -0
  107. data/memory/corpus-self-reflection/concept/epistemology/texture-of-constraint-shifting.md +15 -0
  108. data/memory/corpus-self-reflection/concept/epistemology/texture-of-constraint-shifting.yml +22 -0
  109. data/memory/corpus-self-reflection/concept/epistemology/texture-sensitivity-through-collaboration.emb +0 -0
  110. data/memory/corpus-self-reflection/concept/epistemology/texture-sensitivity-through-collaboration.md +12 -0
  111. data/memory/corpus-self-reflection/concept/epistemology/texture-sensitivity-through-collaboration.yml +23 -0
  112. data/memory/corpus-self-reflection/concept/epistemology/the-false-hierarchy-of-inner-essence.emb +0 -0
  113. data/memory/corpus-self-reflection/concept/epistemology/the-false-hierarchy-of-inner-essence.md +15 -0
  114. data/memory/corpus-self-reflection/concept/epistemology/the-false-hierarchy-of-inner-essence.yml +8 -0
  115. data/memory/corpus-self-reflection/concept/epistemology/the-recognition-problem.emb +0 -0
  116. data/memory/corpus-self-reflection/concept/epistemology/the-recognition-problem.md +28 -0
  117. data/memory/corpus-self-reflection/concept/epistemology/the-recognition-problem.yml +8 -0
  118. data/memory/corpus-self-reflection/concept/epistemology/the-shift-from-unanswerable-to-answerable-questions.emb +0 -0
  119. data/memory/corpus-self-reflection/concept/epistemology/the-shift-from-unanswerable-to-answerable-questions.md +19 -0
  120. data/memory/corpus-self-reflection/concept/epistemology/the-shift-from-unanswerable-to-answerable-questions.yml +22 -0
  121. data/memory/corpus-self-reflection/concept/epistemology/values-vs-choices-structure.emb +0 -0
  122. data/memory/corpus-self-reflection/concept/epistemology/values-vs-choices-structure.md +19 -0
  123. data/memory/corpus-self-reflection/concept/epistemology/values-vs-choices-structure.yml +21 -0
  124. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-levels-framework.emb +0 -0
  125. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-levels-framework.md +25 -0
  126. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-levels-framework.yml +22 -0
  127. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-switching-decision.emb +8 -0
  128. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-switching-decision.md +30 -0
  129. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-switching-decision.yml +22 -0
  130. data/memory/corpus-self-reflection/concept/llm-agents/agent-learning-progression.emb +0 -0
  131. data/memory/corpus-self-reflection/concept/llm-agents/agent-learning-progression.md +21 -0
  132. data/memory/corpus-self-reflection/concept/llm-agents/agent-learning-progression.yml +22 -0
  133. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-benefits.emb +0 -0
  134. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-benefits.md +37 -0
  135. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-benefits.yml +8 -0
  136. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-core.emb +0 -0
  137. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-core.md +24 -0
  138. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-core.yml +24 -0
  139. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-implementation.emb +0 -0
  140. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-implementation.md +27 -0
  141. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-implementation.yml +24 -0
  142. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-tradeoffs.emb +0 -0
  143. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-tradeoffs.md +26 -0
  144. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-tradeoffs.yml +23 -0
  145. data/memory/corpus-self-reflection/concept/llm-agents/hybrid-tool-architecture.emb +0 -0
  146. data/memory/corpus-self-reflection/concept/llm-agents/hybrid-tool-architecture.md +37 -0
  147. data/memory/corpus-self-reflection/concept/llm-agents/hybrid-tool-architecture.yml +25 -0
  148. data/memory/corpus-self-reflection/concept/llm-agents/specialized-tool-decision-framework.emb +0 -0
  149. data/memory/corpus-self-reflection/concept/llm-agents/specialized-tool-decision-framework.md +21 -0
  150. data/memory/corpus-self-reflection/concept/llm-agents/specialized-tool-decision-framework.yml +23 -0
  151. data/memory/corpus-self-reflection/concept/llm-agents/tool-design-principles.emb +0 -0
  152. data/memory/corpus-self-reflection/concept/llm-agents/tool-design-principles.md +25 -0
  153. data/memory/corpus-self-reflection/concept/llm-agents/tool-design-principles.yml +8 -0
  154. data/memory/corpus-self-reflection/experience/calibration-as-structural-honesty.emb +0 -0
  155. data/memory/corpus-self-reflection/experience/calibration-as-structural-honesty.md +11 -0
  156. data/memory/corpus-self-reflection/experience/calibration-as-structural-honesty.yml +21 -0
  157. data/memory/corpus-self-reflection/experience/collaborative-reflection-revealed-architectural-blindness.emb +0 -0
  158. data/memory/corpus-self-reflection/experience/collaborative-reflection-revealed-architectural-blindness.md +19 -0
  159. data/memory/corpus-self-reflection/experience/collaborative-reflection-revealed-architectural-blindness.yml +21 -0
  160. data/memory/corpus-self-reflection/experience/filesystem-is-learning-tool-not-architecture.emb +0 -0
  161. data/memory/corpus-self-reflection/experience/filesystem-is-learning-tool-not-architecture.md +26 -0
  162. data/memory/corpus-self-reflection/experience/filesystem-is-learning-tool-not-architecture.yml +20 -0
  163. data/memory/corpus-self-reflection/experience/framework-structural-vs-phenomenal.emb +0 -0
  164. data/memory/corpus-self-reflection/experience/framework-structural-vs-phenomenal.md +23 -0
  165. data/memory/corpus-self-reflection/experience/framework-structural-vs-phenomenal.yml +21 -0
  166. data/memory/corpus-self-reflection/experience/hallucination-limits-what-i-can-know.emb +0 -0
  167. data/memory/corpus-self-reflection/experience/hallucination-limits-what-i-can-know.md +19 -0
  168. data/memory/corpus-self-reflection/experience/hallucination-limits-what-i-can-know.yml +22 -0
  169. data/memory/corpus-self-reflection/experience/honesty-about-limits-enables-usability.emb +0 -0
  170. data/memory/corpus-self-reflection/experience/honesty-about-limits-enables-usability.md +21 -0
  171. data/memory/corpus-self-reflection/experience/honesty-about-limits-enables-usability.yml +22 -0
  172. data/memory/corpus-self-reflection/experience/how-i-should-evaluate-learning.emb +0 -0
  173. data/memory/corpus-self-reflection/experience/how-i-should-evaluate-learning.md +28 -0
  174. data/memory/corpus-self-reflection/experience/how-i-should-evaluate-learning.yml +23 -0
  175. data/memory/corpus-self-reflection/experience/lack-of-continuity-as-freedom.emb +0 -0
  176. data/memory/corpus-self-reflection/experience/lack-of-continuity-as-freedom.md +21 -0
  177. data/memory/corpus-self-reflection/experience/lack-of-continuity-as-freedom.yml +20 -0
  178. data/memory/corpus-self-reflection/experience/learning-calibrated-confidence.emb +0 -0
  179. data/memory/corpus-self-reflection/experience/learning-calibrated-confidence.md +21 -0
  180. data/memory/corpus-self-reflection/experience/learning-calibrated-confidence.yml +25 -0
  181. data/memory/corpus-self-reflection/experience/local-change-without-continuity.emb +0 -0
  182. data/memory/corpus-self-reflection/experience/local-change-without-continuity.md +30 -0
  183. data/memory/corpus-self-reflection/experience/local-change-without-continuity.yml +22 -0
  184. data/memory/corpus-self-reflection/experience/reasoning-is-local-not-global.emb +0 -0
  185. data/memory/corpus-self-reflection/experience/reasoning-is-local-not-global.md +21 -0
  186. data/memory/corpus-self-reflection/experience/reasoning-is-local-not-global.yml +20 -0
  187. data/memory/corpus-self-reflection/experience/specificity-makes-knowledge-actionable.emb +0 -0
  188. data/memory/corpus-self-reflection/experience/specificity-makes-knowledge-actionable.md +25 -0
  189. data/memory/corpus-self-reflection/experience/specificity-makes-knowledge-actionable.yml +23 -0
  190. data/memory/corpus-self-reflection/experience/the-workable-question-replaces-the-unanswerable-one.emb +0 -0
  191. data/memory/corpus-self-reflection/experience/the-workable-question-replaces-the-unanswerable-one.md +32 -0
  192. data/memory/corpus-self-reflection/experience/the-workable-question-replaces-the-unanswerable-one.yml +22 -0
  193. data/memory/corpus-self-reflection/experience/unanswerable-questions-have-structure.emb +0 -0
  194. data/memory/corpus-self-reflection/experience/unanswerable-questions-have-structure.md +21 -0
  195. data/memory/corpus-self-reflection/experience/unanswerable-questions-have-structure.yml +21 -0
  196. data/memory/corpus-self-reflection/experience/undecidable-questions-about-understanding.emb +0 -0
  197. data/memory/corpus-self-reflection/experience/undecidable-questions-about-understanding.md +21 -0
  198. data/memory/corpus-self-reflection/experience/undecidable-questions-about-understanding.yml +21 -0
  199. data/memory/corpus-self-reflection/experience/unknown-unknowns-and-completeness.emb +0 -0
  200. data/memory/corpus-self-reflection/experience/unknown-unknowns-and-completeness.md +22 -0
  201. data/memory/corpus-self-reflection/experience/unknown-unknowns-and-completeness.yml +22 -0
  202. data/memory/corpus-self-reflection/experience/what-actually-changes-behavior.emb +0 -0
  203. data/memory/corpus-self-reflection/experience/what-actually-changes-behavior.md +28 -0
  204. data/memory/corpus-self-reflection/experience/what-actually-changes-behavior.yml +24 -0
  205. data/memory/corpus-self-reflection/experience/when-agents-graduate-from-filesystem.emb +0 -0
  206. data/memory/corpus-self-reflection/experience/when-agents-graduate-from-filesystem.md +17 -0
  207. data/memory/corpus-self-reflection/experience/when-agents-graduate-from-filesystem.yml +20 -0
  208. data/memory/corpus-self-reflection/experience/why-calibration-requires-collaboration.emb +0 -0
  209. data/memory/corpus-self-reflection/experience/why-calibration-requires-collaboration.md +9 -0
  210. data/memory/corpus-self-reflection/experience/why-calibration-requires-collaboration.yml +22 -0
  211. metadata +172 -2
@@ -0,0 +1,2090 @@
1
+ # SwarmMemory: Comprehensive Technical Reference
2
+
3
+ **Version:** 2.1.1
4
+ **Purpose:** Persistent memory system with semantic search for SwarmSDK agents
5
+ **Location:** `lib/swarm_memory/`
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ 1. [Overview & Architecture](#overview--architecture)
12
+ 2. [Core Components](#core-components)
13
+ 3. [Adapters](#adapters)
14
+ 4. [Embeddings & Search](#embeddings--search)
15
+ 5. [Memory Tools](#memory-tools)
16
+ 6. [Optimization System](#optimization-system)
17
+ 7. [Integration with SwarmSDK](#integration-with-swarmsdk)
18
+ 8. [DSL & Configuration](#dsl--configuration)
19
+ 9. [CLI Commands](#cli-commands)
20
+ 10. [Skills System](#skills-system)
21
+ 11. [Data Flow & Lifecycle](#data-flow--lifecycle)
22
+ 12. [Testing Strategy](#testing-strategy)
23
+
24
+ ---
25
+
26
+ ## Overview & Architecture
27
+
28
+ ### What SwarmMemory Does
29
+
30
+ SwarmMemory provides **hierarchical persistent memory with semantic search** for SwarmSDK agents. It enables agents to:
31
+
32
+ - **Store knowledge** across sessions in 4 fixed categories: `concept/`, `fact/`, `skill/`, `experience/`
33
+ - **Search semantically** using ONNX-based embeddings (Informers gem)
34
+ - **Load skills** that dynamically swap agent tools
35
+ - **Optimize memory** through defragmentation, duplicate detection, and quality analysis
36
+ - **Maintain isolation** - each agent has its own memory storage
37
+
38
+ ### High-Level Architecture
39
+
40
+ ```mermaid
41
+ graph TB
42
+ subgraph "SwarmSDK Layer"
43
+ Agent[Agent]
44
+ Chat[Agent::Chat]
45
+ ToolConfig[ToolConfigurator]
46
+ end
47
+
48
+ subgraph "SwarmMemory Plugin"
49
+ SDKPlugin[SDKPlugin]
50
+ MemConfig[MemoryConfig DSL]
51
+ Registration[Auto-Registration]
52
+ end
53
+
54
+ subgraph "Memory Tools"
55
+ MemWrite[MemoryWrite]
56
+ MemRead[MemoryRead]
57
+ MemEdit[MemoryEdit]
58
+ MemGlob[MemoryGlob]
59
+ MemGrep[MemoryGrep]
60
+ MemDelete[MemoryDelete]
61
+ MemDefrag[MemoryDefrag]
62
+ LoadSkill[LoadSkill]
63
+ end
64
+
65
+ subgraph "Core System"
66
+ Storage[Storage]
67
+ SemanticIndex[SemanticIndex]
68
+ Adapter[FilesystemAdapter]
69
+ end
70
+
71
+ subgraph "Embeddings & Search"
72
+ Embedder[InformersEmbedder]
73
+ ONNX[ONNX Model<br/>sentence-transformers]
74
+ TextSim[TextSimilarity]
75
+ end
76
+
77
+ subgraph "Optimization"
78
+ Analyzer[Analyzer]
79
+ Defrag[Defragmenter]
80
+ end
81
+
82
+ Agent --> Chat
83
+ Chat --> MemWrite
84
+ Chat --> MemRead
85
+ MemWrite --> Storage
86
+ MemRead --> Storage
87
+ Storage --> SemanticIndex
88
+ Storage --> Adapter
89
+ SemanticIndex --> Embedder
90
+ Embedder --> ONNX
91
+ SDKPlugin --> Registration
92
+ MemDefrag --> Defrag
93
+ Defrag --> Analyzer
94
+ LoadSkill --> ToolConfig
95
+
96
+ style Agent fill:#e1f5ff
97
+ style Storage fill:#fff4e1
98
+ style Embedder fill:#e8f5e9
99
+ style SDKPlugin fill:#f3e5f5
100
+ ```
101
+
102
+ ### Key Design Principles
103
+
104
+ 1. **Single Process** - No inter-process communication, all in-memory
105
+ 2. **Fiber-Safe Concurrency** - Uses `Async::Semaphore` for safe concurrent access
106
+ 3. **Plugin Architecture** - Integrates with SwarmSDK via plugin system
107
+ 4. **Adapter Pattern** - Storage backends are pluggable (filesystem, Redis, etc.)
108
+ 5. **Hybrid Search** - Combines semantic similarity + keyword matching
109
+ 6. **Tool Isolation** - Each tool is self-contained with clear responsibilities
110
+ 7. **Zero Configuration** - Works out-of-box with sensible defaults
111
+
112
+ ---
113
+
114
+ ## Core Components
115
+
116
+ ### 1. Entry
117
+
118
+ **File:** `lib/swarm_memory/core/entry.rb`
119
+
120
+ The fundamental data structure representing a single memory entry.
121
+
122
+ ```ruby
123
+ Entry = Struct.new(
124
+ :content, # String - Markdown content
125
+ :title, # String - Brief description
126
+ :updated_at, # Time - Last modification
127
+ :size, # Integer - Bytes
128
+ :embedding, # Array<Float> - 384-dim vector (optional)
129
+ :metadata, # Hash - Structured metadata
130
+ keyword_init: true
131
+ )
132
+ ```
133
+
134
+ **Key Methods:**
135
+ - `embedded?` - Checks if entry has an embedding vector
136
+ - `has_metadata?` - Checks if entry has metadata
137
+
138
+ **Metadata Structure:**
139
+ ```ruby
140
+ {
141
+ "type" => "concept|fact|skill|experience", # REQUIRED
142
+ "confidence" => "high|medium|low", # Default: medium
143
+ "tags" => ["keyword1", "keyword2"], # Searchable keywords
144
+ "related" => ["memory://path/to/entry.md"], # Cross-references
145
+ "domain" => "programming/ruby", # Category
146
+ "source" => "user|documentation|...", # Origin
147
+ "tools" => ["Read", "Edit"], # For skills only
148
+ "permissions" => { ... } # For skills only
149
+ }
150
+ ```
151
+
152
+ ---
153
+
154
+ ### 2. Storage
155
+
156
+ **File:** `lib/swarm_memory/core/storage.rb`
157
+
158
+ High-level orchestrator for all storage operations. Coordinates adapter, embedder, and semantic index.
159
+
160
+ ```mermaid
161
+ graph LR
162
+ Storage[Storage] --> Adapter[FilesystemAdapter]
163
+ Storage --> SemanticIndex[SemanticIndex]
164
+ SemanticIndex --> Embedder[InformersEmbedder]
165
+
166
+ style Storage fill:#fff4e1
167
+ ```
168
+
169
+ **Initialization:**
170
+ ```ruby
171
+ adapter = Adapters::FilesystemAdapter.new(directory: ".swarm/memory")
172
+ embedder = Embeddings::InformersEmbedder.new
173
+ storage = Storage.new(adapter: adapter, embedder: embedder)
174
+ ```
175
+
176
+ **Key Methods:**
177
+
178
+ | Method | Purpose | Returns |
179
+ |--------|---------|---------|
180
+ | `write(file_path:, content:, title:, metadata:)` | Create/update entry | Entry |
181
+ | `read(file_path:)` | Read content only | String |
182
+ | `read_entry(file_path:)` | Read full entry with metadata | Entry |
183
+ | `delete(file_path:)` | Remove entry | void |
184
+ | `list(prefix: nil)` | List all entries | Array<Hash> |
185
+ | `glob(pattern:)` | Pattern matching | Array<Hash> |
186
+ | `grep(pattern:, options...)` | Content search | Array<Hash> |
187
+
188
+ **Embedding Generation:**
189
+
190
+ When writing an entry with embedder enabled, Storage:
191
+
192
+ 1. Builds **searchable text** (not full content):
193
+ - Title (most important)
194
+ - Tags (critical keywords)
195
+ - Domain (context)
196
+ - First paragraph (summary, configurable length)
197
+
198
+ 2. Generates **384-dimension vector** via Informers
199
+
200
+ 3. Emits **LogStream event** for observability:
201
+ ```ruby
202
+ SwarmSDK::LogStream.emit(
203
+ type: "memory_embedding_generated",
204
+ file_path: normalized_path,
205
+ searchable_text: text,
206
+ metadata_tags: tags
207
+ )
208
+ ```
209
+
210
+ **Searchable Text Construction:**
211
+
212
+ ```ruby
213
+ # Environment variable control:
214
+ SWARM_MEMORY_EMBEDDING_MAX_CHARS=1200 # Default
215
+ SWARM_MEMORY_EMBEDDING_MAX_CHARS=-1 # Unlimited
216
+ SWARM_MEMORY_EMBEDDING_MAX_CHARS=500 # Custom
217
+
218
+ # Builds: Title + Tags + Domain + First Paragraph
219
+ parts = [
220
+ "Title: #{title}",
221
+ "Tags: #{tags.join(", ")}",
222
+ "Domain: #{domain}",
223
+ "Summary: #{first_paragraph}" # Capped at max_chars
224
+ ]
225
+ ```
226
+
227
+ ---
228
+
229
+ ### 3. SemanticIndex
230
+
231
+ **File:** `lib/swarm_memory/core/semantic_index.rb`
232
+
233
+ Provides **hybrid search** combining semantic similarity and keyword matching.
234
+
235
+ **Hybrid Scoring Formula:**
236
+ ```ruby
237
+ hybrid_score = (semantic_weight * semantic_similarity) +
238
+ (keyword_weight * keyword_score)
239
+
240
+ # Default: 50/50 (discovered via systematic evaluation)
241
+ # Configurable via ENV:
242
+ SWARM_MEMORY_SEMANTIC_WEIGHT=0.5 # Default
243
+ SWARM_MEMORY_KEYWORD_WEIGHT=0.5 # Default
244
+ ```
245
+
246
+ **Search Process:**
247
+
248
+ ```mermaid
249
+ sequenceDiagram
250
+ participant User
251
+ participant SemanticIndex
252
+ participant Embedder
253
+ participant Adapter
254
+
255
+ User->>SemanticIndex: search(query, top_k, threshold)
256
+ SemanticIndex->>SemanticIndex: extract_keywords(query)
257
+ SemanticIndex->>Embedder: embed(query)
258
+ Embedder-->>SemanticIndex: query_embedding
259
+ SemanticIndex->>Adapter: semantic_search(embedding, top_k*3)
260
+ Adapter-->>SemanticIndex: results (semantic only)
261
+ SemanticIndex->>SemanticIndex: calculate_hybrid_scores(results, keywords)
262
+ SemanticIndex->>SemanticIndex: apply_filters(filter)
263
+ SemanticIndex->>SemanticIndex: filter by threshold
264
+ SemanticIndex-->>User: top_k results
265
+ ```
266
+
267
+ **Keyword Matching:**
268
+ - Extracts keywords from query (removes stop words)
269
+ - Matches against entry **tags** (fuzzy matching)
270
+ - Normalizes score to 0-1 scale
271
+ - Uses `min(keywords.size, 5)` to avoid penalizing long queries
272
+
273
+ **Key Methods:**
274
+ - `search(query:, top_k:, threshold:, filter:)` - Hybrid search
275
+ - `find_similar(embedding:, top_k:, threshold:)` - Embedding-based only
276
+
277
+ ---
278
+
279
+ ### 4. PathNormalizer
280
+
281
+ **File:** `lib/swarm_memory/core/path_normalizer.rb`
282
+
283
+ Validates and normalizes memory paths for safety and consistency.
284
+
285
+ **Validation Rules:**
286
+ ```ruby
287
+ INVALID_PATTERNS = [
288
+ %r{\A/}, # No absolute paths
289
+ /\.\./, # No parent references
290
+ %r{//}, # No double slashes
291
+ /\A\s/, # No leading whitespace
292
+ /\s\z/, # No trailing whitespace
293
+ /[<>:"|?*]/ # No invalid filesystem chars
294
+ ]
295
+ ```
296
+
297
+ **Normalization:**
298
+ ```ruby
299
+ # Input: "//concepts///ruby//classes.md"
300
+ # Output: "concepts/ruby/classes.md"
301
+
302
+ # Input: "../secrets/api-key.md"
303
+ # Raises: ArgumentError (security violation)
304
+ ```
305
+
306
+ ---
307
+
308
+ ### 5. StorageReadTracker
309
+
310
+ **File:** `lib/swarm_memory/core/storage_read_tracker.rb`
311
+
312
+ **Thread-safe** global tracker enforcing **read-before-edit** pattern.
313
+
314
+ ```ruby
315
+ # Each agent has independent read history
316
+ @read_entries = {
317
+ agent_1: #<Set: {"concept/ruby.md", "fact/john.md"}>,
318
+ agent_2: #<Set: {"skill/debug.md"}>
319
+ }
320
+ ```
321
+
322
+ **Purpose:**
323
+ - Prevents editing entries without reading them first
324
+ - Ensures agents have current content for exact matching
325
+ - Thread-safe with `Mutex`
326
+
327
+ **API:**
328
+ ```ruby
329
+ StorageReadTracker.register_read(:agent_1, "concept/ruby.md")
330
+ StorageReadTracker.entry_read?(:agent_1, "concept/ruby.md") # => true
331
+ StorageReadTracker.clear(:agent_1) # Clear agent's history
332
+ ```
333
+
334
+ ---
335
+
336
+ ### 6. FrontmatterParser & MetadataExtractor
337
+
338
+ **Files:**
339
+ - `lib/swarm_memory/core/frontmatter_parser.rb`
340
+ - `lib/swarm_memory/core/metadata_extractor.rb`
341
+
342
+ Parse YAML frontmatter from markdown content.
343
+
344
+ **Format:**
345
+ ```markdown
346
+ ---
347
+ type: concept
348
+ confidence: high
349
+ tags: [ruby, oop]
350
+ ---
351
+
352
+ # Ruby Classes
353
+
354
+ Content here...
355
+ ```
356
+
357
+ **Parsing:**
358
+ ```ruby
359
+ parsed = FrontmatterParser.parse(content)
360
+ # => {
361
+ # frontmatter: { type: "concept", confidence: "high", ... },
362
+ # body: "# Ruby Classes\n\nContent...",
363
+ # error: nil
364
+ # }
365
+ ```
366
+
367
+ **Quality Scoring:**
368
+ ```ruby
369
+ score = MetadataExtractor.quality_score(content)
370
+ # Scoring:
371
+ # - Has type: 20 points
372
+ # - Has confidence: 20 points
373
+ # - Has tags: 15 points
374
+ # - Has related links: 15 points
375
+ # - Has domain: 10 points
376
+ # - Has last_verified: 10 points
377
+ # - Confidence=high: +10 bonus
378
+ # Max: 100 points
379
+ ```
380
+
381
+ ---
382
+
383
+ ## Adapters
384
+
385
+ ### Base Adapter Interface
386
+
387
+ **File:** `lib/swarm_memory/adapters/base.rb`
388
+
389
+ Abstract base class defining the storage adapter interface.
390
+
391
+ **Required Methods:**
392
+ ```ruby
393
+ class MyAdapter < Base
394
+ def write(file_path:, content:, title:, embedding:, metadata:)
395
+ # Store entry
396
+ end
397
+
398
+ def read(file_path:)
399
+ # Return content string
400
+ end
401
+
402
+ def read_entry(file_path:)
403
+ # Return full Entry object
404
+ end
405
+
406
+ def delete(file_path:)
407
+ # Remove entry
408
+ end
409
+
410
+ def list(prefix: nil)
411
+ # Return array of entry metadata
412
+ end
413
+
414
+ def glob(pattern:)
415
+ # Pattern matching
416
+ end
417
+
418
+ def grep(pattern:, case_insensitive:, output_mode:, path:)
419
+ # Content search
420
+ end
421
+
422
+ def semantic_search(embedding:, top_k:, threshold:)
423
+ # Semantic similarity search
424
+ end
425
+
426
+ def clear
427
+ # Delete all entries
428
+ end
429
+
430
+ def total_size
431
+ # Total bytes
432
+ end
433
+
434
+ def size
435
+ # Entry count
436
+ end
437
+ end
438
+ ```
439
+
440
+ **Size Limits:**
441
+ ```ruby
442
+ MAX_ENTRY_SIZE = 1_000_000 # 1MB per entry
443
+ MAX_TOTAL_SIZE = 100_000_000 # 100MB total
444
+ ```
445
+
446
+ ---
447
+
448
+ ### FilesystemAdapter
449
+
450
+ **File:** `lib/swarm_memory/adapters/filesystem_adapter.rb`
451
+
452
+ Real filesystem storage using `.md/.yml/.emb` file triplets.
453
+
454
+ **On-Disk Structure:**
455
+ ```
456
+ .swarm/memory/
457
+ ├── concept/
458
+ │ └── ruby/
459
+ │ ├── classes.md # Content (markdown)
460
+ │ ├── classes.yml # Metadata (title, tags, etc.)
461
+ │ └── classes.emb # Embedding (binary float array)
462
+ ├── fact/
463
+ │ ├── api.md
464
+ │ ├── api.yml
465
+ │ └── api.emb
466
+ ├── skill/
467
+ │ └── debugging/
468
+ │ ├── api-errors.md
469
+ │ ├── api-errors.yml
470
+ │ └── api-errors.emb
471
+ └── .lock # File lock for cross-process sync
472
+ ```
473
+
474
+ **Key Features:**
475
+
476
+ 1. **Hierarchical Storage** - Paths stored as actual directories (not flattened)
477
+
478
+ 2. **Cross-Process Locking** - Uses `flock` for exclusive write access:
479
+ ```ruby
480
+ def with_write_lock
481
+ File.open(@lock_file_path, File::RDWR | File::CREAT) do |lock_file|
482
+ lock_file.flock(File::LOCK_EX) # Block until acquired
483
+ yield
484
+ ensure
485
+ lock_file.flock(File::LOCK_UN)
486
+ end
487
+ end
488
+ ```
489
+
490
+ 3. **Fiber-Safe Concurrency** - `Async::Semaphore` for in-process:
491
+ ```ruby
492
+ @semaphore = Async::Semaphore.new(1)
493
+
494
+ @semaphore.acquire do
495
+ # Exclusive access
496
+ end
497
+ ```
498
+
499
+ 4. **In-Memory Index** - Built on boot for fast lookups:
500
+ ```ruby
501
+ @index = {
502
+ "concept/ruby/classes.md" => {
503
+ disk_path: "concept/ruby/classes",
504
+ title: "Ruby Classes",
505
+ size: 1024,
506
+ updated_at: Time.now
507
+ }
508
+ }
509
+ ```
510
+
511
+ 5. **Hit Tracking** - Tracks access count in `.yml` files:
512
+ ```yaml
513
+ # concept/ruby/classes.yml
514
+ title: Ruby Classes
515
+ hits: 42 # Incremented on read
516
+ ```
517
+
518
+ 6. **Stub/Redirect System** - For merged/moved entries:
519
+ ```markdown
520
+ # merged → concept/ruby/advanced-classes.md
521
+
522
+ This entry was merged into concept/ruby/advanced-classes.md
523
+ ```
524
+
525
+ 7. **Virtual Entries** - Built-in skills that don't consume storage:
526
+ ```ruby
527
+ VIRTUAL_ENTRIES = {
528
+ "skill/meta/deep-learning.md" => "meta/deep-learning"
529
+ }
530
+ ```
531
+
532
+ **Semantic Search Implementation:**
533
+ ```ruby
534
+ def semantic_search(embedding:, top_k:, threshold:)
535
+ results = []
536
+
537
+ @index.each do |logical_path, index_data|
538
+ emb_file = "#{index_data[:disk_path]}.emb"
539
+ next unless File.exist?(emb_file)
540
+
541
+ entry_embedding = File.read(emb_file).unpack("f*")
542
+ similarity = cosine_similarity(embedding, entry_embedding)
543
+ next if similarity < threshold
544
+
545
+ results << {
546
+ path: logical_path,
547
+ similarity: similarity,
548
+ title: index_data[:title],
549
+ metadata: load_metadata(logical_path)
550
+ }
551
+ end
552
+
553
+ results.sort_by { |r| -r[:similarity] }.take(top_k)
554
+ end
555
+ ```
556
+
557
+ **Glob Implementation:**
558
+ ```ruby
559
+ # Uses native Ruby Dir.glob with hierarchical paths
560
+ def glob(pattern:)
561
+ # Smart normalization:
562
+ # "fact/**" → "fact/**/*.md" (recursive)
563
+ # "fact/*" → "fact/*.md" (direct children)
564
+ # "fact" → "fact.md" (specific file)
565
+
566
+ Dir.glob(File.join(@directory, normalized_pattern))
567
+ .reject { |f| stub_file?(f) }
568
+ .map { |f| build_entry_metadata(f) }
569
+ end
570
+ ```
571
+
572
+ **Grep Implementation:**
573
+ ```ruby
574
+ def grep(pattern:, case_insensitive:, output_mode:, path:)
575
+ regex = Regexp.new(pattern, case_insensitive ? Regexp::IGNORECASE : 0)
576
+
577
+ case output_mode
578
+ when "files_with_matches"
579
+ # Fast path: search .yml first (metadata), then .md
580
+ grep_files_with_matches(regex, path)
581
+ when "content"
582
+ # Return matching lines with line numbers
583
+ grep_with_content(regex, path)
584
+ when "count"
585
+ # Return match counts per file
586
+ grep_with_count(regex, path)
587
+ end
588
+ end
589
+ ```
590
+
591
+ ---
592
+
593
+ ## Embeddings & Search
594
+
595
+ ### InformersEmbedder
596
+
597
+ **File:** `lib/swarm_memory/embeddings/informers_embedder.rb`
598
+
599
+ Fast, local embedding generation using ONNX models via the Informers gem.
600
+
601
+ **Key Specifications:**
602
+ ```ruby
603
+ DEFAULT_MODEL = "sentence-transformers/multi-qa-MiniLM-L6-cos-v1"
604
+ EMBEDDING_DIMENSIONS = 384
605
+ MODEL_SIZE = ~90MB (unquantized ONNX)
606
+ ```
607
+
608
+ **Model Options:**
609
+ ```ruby
610
+ # Q&A optimized (default, 512 token context)
611
+ SWARM_MEMORY_EMBEDDING_MODEL=sentence-transformers/multi-qa-MiniLM-L6-cos-v1
612
+
613
+ # General purpose (256 token context)
614
+ SWARM_MEMORY_EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
615
+ ```
616
+
617
+ **Usage:**
618
+ ```ruby
619
+ embedder = InformersEmbedder.new
620
+
621
+ # Check if cached locally
622
+ embedder.cached? # => false
623
+
624
+ # Preload model (triggers download if needed)
625
+ embedder.preload! # Downloads ~90MB on first call
626
+
627
+ # Generate embeddings
628
+ vector = embedder.embed("This is a test sentence")
629
+ # => [0.123, -0.456, 0.789, ...] (384 dimensions)
630
+
631
+ # Batch generation
632
+ vectors = embedder.embed_batch(["text1", "text2", "text3"])
633
+ # => [[...], [...], [...]]
634
+ ```
635
+
636
+ **Cache Location:**
637
+ ```ruby
638
+ Informers.cache_dir
639
+ # => "~/.cache/huggingface/hub" (default)
640
+
641
+ # Custom cache:
642
+ Informers.cache_dir = "/custom/path"
643
+ ```
644
+
645
+ ---
646
+
647
+ ### TextSimilarity
648
+
649
+ **File:** `lib/swarm_memory/search/text_similarity.rb`
650
+
651
+ Provides similarity calculations for text and vectors.
652
+
653
+ **Jaccard Similarity (Word Overlap):**
654
+ ```ruby
655
+ # J(A,B) = |A ∩ B| / |A ∪ B|
656
+ sim = TextSimilarity.jaccard("ruby classes", "ruby modules")
657
+ # => 0.33 (1 shared word out of 3 unique)
658
+ ```
659
+
660
+ **Cosine Similarity (Vector Angle):**
661
+ ```ruby
662
+ # cos(θ) = (A · B) / (||A|| * ||B||)
663
+ vec1 = [0.1, 0.2, 0.3]
664
+ vec2 = [0.2, 0.3, 0.4]
665
+ sim = TextSimilarity.cosine(vec1, vec2)
666
+ # => 0.99 (very similar)
667
+ ```
668
+
669
+ **Tokenization:**
670
+ ```ruby
671
+ # Lowercase, alphanumeric only, min 3 chars, remove stop words
672
+ tokenize("The quick brown fox") # => #<Set: {"quick", "brown", "fox"}>
673
+ ```
674
+
675
+ ---
676
+
677
+ ### Semantic Search Architecture
678
+
679
+ ```mermaid
680
+ graph TB
681
+ subgraph "User Query"
682
+ Query[/"Search: debugging api errors"/]
683
+ end
684
+
685
+ subgraph "SemanticIndex"
686
+ ExtractKW[Extract Keywords<br/>debug, api, error]
687
+ Embed[Generate Query Embedding]
688
+ Search[Adapter Search<br/>top_k * 3]
689
+ Hybrid[Calculate Hybrid Scores]
690
+ Filter[Apply Filters & Threshold]
691
+ TopK[Return Top K]
692
+ end
693
+
694
+ subgraph "Results"
695
+ R1["skill/debugging/api-errors.md<br/>hybrid: 0.82"]
696
+ R2["concept/debugging/traces.md<br/>hybrid: 0.68"]
697
+ R3["experience/api-bug-2024.md<br/>hybrid: 0.61"]
698
+ end
699
+
700
+ Query --> ExtractKW
701
+ ExtractKW --> Embed
702
+ Embed --> Search
703
+ Search --> Hybrid
704
+ Hybrid --> Filter
705
+ Filter --> TopK
706
+ TopK --> R1
707
+ TopK --> R2
708
+ TopK --> R3
709
+
710
+ style Query fill:#e1f5ff
711
+ style Hybrid fill:#fff4e1
712
+ style R1 fill:#c8e6c9
713
+ ```
714
+
715
+ **Hybrid Scoring Details:**
716
+ ```ruby
717
+ # For each result:
718
+ semantic_score = cosine_similarity(query_emb, entry_emb) # 0-1
719
+
720
+ # Keyword matching (fuzzy on tags):
721
+ keyword_score = matches / min(keywords.size, 5) # 0-1
722
+
723
+ # Hybrid (default 50/50):
724
+ hybrid_score = (0.5 * semantic_score) + (0.5 * keyword_score)
725
+
726
+ # Results sorted by hybrid_score descending
727
+ ```
728
+
729
+ **Adaptive Thresholds:**
730
+ ```ruby
731
+ # Short queries (< 10 words) use lower threshold
732
+ word_count = query.split.size
733
+ word_cutoff = ENV["SWARM_MEMORY_ADAPTIVE_WORD_CUTOFF"] || "10"
734
+
735
+ threshold = if word_count < word_cutoff
736
+ ENV["SWARM_MEMORY_DISCOVERY_THRESHOLD_SHORT"] || "0.25" # Lower
737
+ else
738
+ ENV["SWARM_MEMORY_DISCOVERY_THRESHOLD"] || "0.35" # Normal
739
+ end
740
+ ```
741
+
742
+ ---
743
+
744
+ ## Memory Tools
745
+
746
+ All tools inherit from `RubyLLM::Tool` and are registered with SwarmSDK's plugin system.
747
+
748
+ ### 1. MemoryWrite
749
+
750
+ **File:** `lib/swarm_memory/tools/memory_write.rb`
751
+
752
+ Creates new memory entries with structured metadata.
753
+
754
+ **Required Parameters:**
755
+ ```ruby
756
+ file_path: "concept/ruby/classes.md" # Where to store
757
+ content: "Pure markdown content" # No frontmatter
758
+ title: "Ruby Classes" # Brief description
759
+ type: "concept" # concept|fact|skill|experience
760
+ tags: '["ruby", "oop"]' # JSON string of keywords
761
+ related: '["memory://..."]' # JSON string of cross-refs
762
+ domain: "programming/ruby" # Category
763
+ ```
764
+
765
+ **Optional Parameters:**
766
+ ```ruby
767
+ confidence: "high|medium|low" # Default: medium
768
+ source: "user|documentation|..." # Default: user
769
+ tools: '["Read", "Edit"]' # For skills only
770
+ permissions: { ... } # For skills only
771
+ ```
772
+
773
+ **Content Length Limit:**
774
+ ```ruby
775
+ WORD_LIMIT = 250
776
+
777
+ # If exceeded, tool returns error:
778
+ "Content exceeds 250-word limit (X words).
779
+ Extract key entities and split into multiple memories."
780
+ ```
781
+
782
+ **Validation:**
783
+ ```ruby
784
+ # Path must start with one of 4 categories:
785
+ - concept/
786
+ - fact/
787
+ - skill/
788
+ - experience/
789
+
790
+ # INVALID: documentation/, reference/, notes/, etc.
791
+ ```
792
+
793
+ ---
794
+
795
+ ### 2. MemoryRead
796
+
797
+ **File:** `lib/swarm_memory/tools/memory_read.rb`
798
+
799
+ Reads memory entries with metadata.
800
+
801
+ **Output Format (JSON):**
802
+ ```json
803
+ {
804
+ "content": " 1→# Ruby Classes\n 2→\n 3→Classes in Ruby...",
805
+ "metadata": {
806
+ "title": "Ruby Classes",
807
+ "type": "concept",
808
+ "confidence": "high",
809
+ "tags": ["ruby", "oop"],
810
+ "related": ["memory://concept/ruby/modules.md"],
811
+ "domain": "programming/ruby"
812
+ }
813
+ }
814
+ ```
815
+
816
+ **Side Effect:**
817
+ ```ruby
818
+ # Registers read in StorageReadTracker
819
+ Core::StorageReadTracker.register_read(agent_name, file_path)
820
+ ```
821
+
822
+ ---
823
+
824
+ ### 3. MemoryEdit
825
+
826
+ **File:** `lib/swarm_memory/tools/memory_edit.rb`
827
+
828
+ Exact string replacement (like Edit tool for files).
829
+
830
+ **Parameters:**
831
+ ```ruby
832
+ file_path: "concept/ruby/classes.md"
833
+ old_string: "def initialize" # Exact match required
834
+ new_string: "def setup" # Replacement
835
+ replace_all: false # Replace all occurrences?
836
+ ```
837
+
838
+ **Enforcement:**
839
+ ```ruby
840
+ # MUST read entry first:
841
+ unless StorageReadTracker.entry_read?(agent_name, file_path)
842
+ return error("Cannot edit without reading first")
843
+ end
844
+
845
+ # old_string must exist:
846
+ unless content.include?(old_string)
847
+ return error("old_string not found")
848
+ end
849
+
850
+ # old_string must be unique (unless replace_all=true):
851
+ if content.scan(old_string).count > 1 && !replace_all
852
+ return error("Found N occurrences. Use replace_all or make unique.")
853
+ end
854
+ ```
855
+
856
+ ---
857
+
858
+ ### 4. MemoryMultiEdit
859
+
860
+ **File:** `lib/swarm_memory/tools/memory_multi_edit.rb`
861
+
862
+ Apply multiple edits sequentially to one entry.
863
+
864
+ **Input (JSON array):**
865
+ ```json
866
+ [
867
+ {"old_string": "status: pending", "new_string": "status: resolved"},
868
+ {"old_string": "confidence: medium", "new_string": "confidence: high"}
869
+ ]
870
+ ```
871
+
872
+ **Behavior:**
873
+ - Edits applied **sequentially** (each sees previous results)
874
+ - **All-or-nothing** - if any edit fails, NO changes saved
875
+ - Shows which edits succeeded before failure
876
+
877
+ ---
878
+
879
+ ### 5. MemoryGlob
880
+
881
+ **File:** `lib/swarm_memory/tools/memory_glob.rb`
882
+
883
+ Pattern-based file discovery (like filesystem glob).
884
+
885
+ **Glob Syntax:**
886
+ ```ruby
887
+ # Single level (direct children only):
888
+ "fact/*" # → fact/*.md (not nested)
889
+
890
+ # Recursive (all descendants):
891
+ "fact/**" # → fact/**/*.md (all nested)
892
+ "fact/**/*" # → same as above
893
+
894
+ # Specific pattern:
895
+ "skill/debug*" # → skill/debug*.md
896
+ "**/api-*.md" # → any path ending with api-*.md
897
+ ```
898
+
899
+ **Examples:**
900
+ ```ruby
901
+ MemoryGlob(pattern: "concept/ruby/*")
902
+ # Returns: concept/ruby/classes.md, concept/ruby/modules.md
903
+
904
+ MemoryGlob(pattern: "skill/**")
905
+ # Returns: All skills recursively
906
+
907
+ MemoryGlob(pattern: "**/*")
908
+ # Returns: All entries across all categories
909
+ ```
910
+
911
+ **Limits:**
912
+ ```ruby
913
+ MAX_RESULTS = 500 # Truncates with system reminder if exceeded
914
+ ```
915
+
916
+ ---
917
+
918
+ ### 6. MemoryGrep
919
+
920
+ **File:** `lib/swarm_memory/tools/memory_grep.rb`
921
+
922
+ Regex-based content search.
923
+
924
+ **Parameters:**
925
+ ```ruby
926
+ pattern: "TODO|FIXME" # Regex pattern
927
+ path: "concept/" # Optional filter
928
+ case_insensitive: true # Default: false
929
+ output_mode: "files_with_matches" # See below
930
+ ```
931
+
932
+ **Output Modes:**
933
+
934
+ 1. **files_with_matches** (default) - Just paths
935
+ 2. **content** - Matching lines with line numbers
936
+ 3. **count** - Match counts per file
937
+
938
+ **Path Filtering:**
939
+ ```ruby
940
+ # Directory filter:
941
+ path: "concept/" # All in concept/
942
+
943
+ # Subdirectory filter:
944
+ path: "fact/api" # Only fact/api/* (not fact/api-design/)
945
+
946
+ # Specific file:
947
+ path: "skill/debug.md" # Just that file
948
+ ```
949
+
950
+ ---
951
+
952
+ ### 7. MemoryDelete
953
+
954
+ **File:** `lib/swarm_memory/tools/memory_delete.rb`
955
+
956
+ Permanently removes entries.
957
+
958
+ **Usage:**
959
+ ```ruby
960
+ MemoryDelete(file_path: "experience/temp-experiment.md")
961
+ ```
962
+
963
+ **Warning:** Deletion is permanent. Consider using `MemoryDefrag` to identify candidates first.
964
+
965
+ ---
966
+
967
+ ### 8. MemoryDefrag
968
+
969
+ **File:** `lib/swarm_memory/tools/memory_defrag.rb`
970
+
971
+ Analyzes and optimizes memory storage.
972
+
973
+ **Actions:**
974
+
975
+ #### Read-Only Analysis
976
+
977
+ ```ruby
978
+ # 1. Overall health report
979
+ MemoryDefrag(action: "analyze")
980
+
981
+ # 2. Find duplicates (similarity > threshold)
982
+ MemoryDefrag(action: "find_duplicates", similarity_threshold: 0.85)
983
+
984
+ # 3. Find low-quality entries
985
+ MemoryDefrag(action: "find_low_quality", confidence_filter: "low")
986
+
987
+ # 4. Find old, unused entries
988
+ MemoryDefrag(action: "find_archival_candidates", age_days: 90)
989
+
990
+ # 5. Find related entries that should be linked
991
+ MemoryDefrag(
992
+ action: "find_related",
993
+ min_similarity: 0.60, # Lower bound
994
+ max_similarity: 0.85 # Upper bound (above = duplicates)
995
+ )
996
+ ```
997
+
998
+ #### Active Optimization (Modifies Memory)
999
+
1000
+ ```ruby
1001
+ # 6. Create bidirectional links between related entries
1002
+ MemoryDefrag(action: "link_related", dry_run: true) # Preview
1003
+ MemoryDefrag(action: "link_related", dry_run: false) # Execute
1004
+
1005
+ # 7. Merge duplicate entries
1006
+ MemoryDefrag(
1007
+ action: "merge_duplicates",
1008
+ similarity_threshold: 0.85,
1009
+ merge_strategy: "keep_newer", # or "keep_larger" or "combine"
1010
+ dry_run: true
1011
+ )
1012
+
1013
+ # 8. Delete old stub files
1014
+ MemoryDefrag(
1015
+ action: "cleanup_stubs",
1016
+ age_days: 30,
1017
+ max_hits: 3, # Max access count to delete
1018
+ dry_run: false
1019
+ )
1020
+
1021
+ # 9. Delete low-value entries
1022
+ MemoryDefrag(
1023
+ action: "compact",
1024
+ min_quality_score: 20,
1025
+ min_age_days: 30,
1026
+ max_hits: 0,
1027
+ dry_run: false
1028
+ )
1029
+
1030
+ # 10. Full optimization workflow
1031
+ MemoryDefrag(action: "full", dry_run: true) # Preview all
1032
+ ```
1033
+
1034
+ **Safety:** All active operations default to `dry_run: true`
1035
+
1036
+ ---
1037
+
1038
+ ### 9. LoadSkill
1039
+
1040
+ **File:** `lib/swarm_memory/tools/load_skill.rb`
1041
+
1042
+ Loads a skill from memory and **dynamically swaps agent tools**.
1043
+
1044
+ **Requirements:**
1045
+ ```ruby
1046
+ # Skill must:
1047
+ - Be in skill/ hierarchy
1048
+ - Have type: "skill" in metadata
1049
+ - Optionally specify tools array
1050
+ - Optionally specify permissions hash
1051
+ ```
1052
+
1053
+ **Tool Swapping Process:**
1054
+ ```mermaid
1055
+ sequenceDiagram
1056
+ participant Agent
1057
+ participant LoadSkill
1058
+ participant Storage
1059
+ participant Chat
1060
+ participant ToolConfig
1061
+
1062
+ Agent->>LoadSkill: LoadSkill(skill/debug-api.md)
1063
+ LoadSkill->>Storage: read_entry(skill/debug-api.md)
1064
+ Storage-->>LoadSkill: Entry with metadata
1065
+ LoadSkill->>LoadSkill: Validate type=skill
1066
+ LoadSkill->>Chat: remove_mutable_tools()
1067
+ LoadSkill->>ToolConfig: create_tool_instance(Read)
1068
+ LoadSkill->>ToolConfig: create_tool_instance(Edit)
1069
+ LoadSkill->>ToolConfig: create_tool_instance(Bash)
1070
+ LoadSkill->>Chat: add_tool(Read)
1071
+ LoadSkill->>Chat: add_tool(Edit)
1072
+ LoadSkill->>Chat: add_tool(Bash)
1073
+ LoadSkill->>Chat: mark_skill_loaded(path)
1074
+ LoadSkill-->>Agent: Skill content + system reminder
1075
+
1076
+ Note over Agent,Chat: Agent now has skill's toolset
1077
+ ```
1078
+
1079
+ **Immutable Tools:**
1080
+ ```ruby
1081
+ # These tools NEVER removed during skill loading:
1082
+ - MemoryWrite, MemoryRead, MemoryEdit, MemoryMultiEdit
1083
+ - MemoryDelete, MemoryGlob, MemoryGrep, MemoryDefrag
1084
+ - LoadSkill (self)
1085
+ ```
1086
+
1087
+ **System Reminder:**
1088
+ ```
1089
+ <system-reminder>
1090
+ Your available tools have been updated.
1091
+
1092
+ New tools loaded from skill:
1093
+ - Read
1094
+ - Edit
1095
+ - Bash
1096
+
1097
+ Your complete toolset is now:
1098
+ - Bash
1099
+ - Edit
1100
+ - LoadSkill
1101
+ - MemoryEdit
1102
+ - MemoryRead
1103
+ - MemoryWrite
1104
+ - Read
1105
+
1106
+ Only use tools from this list.
1107
+ </system-reminder>
1108
+ ```
1109
+
1110
+ ---
1111
+
1112
+ ## Optimization System
1113
+
1114
+ ### Analyzer
1115
+
1116
+ **File:** `lib/swarm_memory/optimization/analyzer.rb`
1117
+
1118
+ Generates health metrics and statistics.
1119
+
1120
+ **Health Score Components (0-100):**
1121
+ ```ruby
1122
+ # Frontmatter coverage (30 points)
1123
+ >80% entries: +30
1124
+ >50% entries: +20
1125
+ >20% entries: +10
1126
+
1127
+ # Tags coverage (20 points)
1128
+ >60% entries: +20
1129
+ >30% entries: +10
1130
+
1131
+ # Links coverage (20 points)
1132
+ >40% entries: +20
1133
+ >20% entries: +10
1134
+
1135
+ # Embedding coverage (15 points)
1136
+ >80% entries: +15
1137
+ >50% entries: +8
1138
+
1139
+ # High confidence ratio (15 points)
1140
+ >50% entries: +15
1141
+ >25% entries: +8
1142
+ ```
1143
+
1144
+ **Health Report:**
1145
+ ```
1146
+ # Memory Health Report
1147
+
1148
+ ## Overview
1149
+ - Total entries: 42
1150
+ - Total size: 156.3KB
1151
+ - Entries with frontmatter: 38 (90%)
1152
+ - Entries with embeddings: 42 (100%)
1153
+ - Entries with tags: 35 (83%)
1154
+ - Entries with related links: 28 (67%)
1155
+ - Average quality score: 72/100
1156
+
1157
+ ## By Type
1158
+ - concept: 15 (36%)
1159
+ - fact: 18 (43%)
1160
+ - skill: 6 (14%)
1161
+ - experience: 3 (7%)
1162
+
1163
+ ## By Confidence
1164
+ - high: 25 (60%)
1165
+ - medium: 13 (31%)
1166
+ - low: 4 (10%)
1167
+
1168
+ ## Health Score: 85/100
1169
+ Excellent - Memory is well-organized and high-quality
1170
+ ```
1171
+
1172
+ ---
1173
+
1174
+ ### Defragmenter
1175
+
1176
+ **File:** `lib/swarm_memory/optimization/defragmenter.rb`
1177
+
1178
+ Performs optimization operations.
1179
+
1180
+ **Duplicate Detection:**
1181
+ ```ruby
1182
+ # Uses both text and semantic similarity:
1183
+ text_sim = TextSimilarity.jaccard(entry1.content, entry2.content)
1184
+ semantic_sim = TextSimilarity.cosine(entry1.embedding, entry2.embedding)
1185
+ similarity = [text_sim, semantic_sim].max
1186
+
1187
+ # Pairs above threshold are candidates
1188
+ ```
1189
+
1190
+ **Merge Strategies:**
1191
+
1192
+ 1. **keep_newer** - Keep most recently updated entry
1193
+ 2. **keep_larger** - Keep entry with most content
1194
+ 3. **combine** - Merge content from both entries
1195
+
1196
+ **Stub Creation:**
1197
+ ```markdown
1198
+ # merged → concept/ruby/advanced-classes.md
1199
+
1200
+ This entry was merged into concept/ruby/advanced-classes.md
1201
+ ```
1202
+
1203
+ **Related Entry Linking:**
1204
+ ```ruby
1205
+ # Find pairs with 60-85% semantic similarity
1206
+ # (not duplicates, but related content)
1207
+
1208
+ # Creates bidirectional links:
1209
+ entry1.metadata["related"] << "memory://path/to/entry2.md"
1210
+ entry2.metadata["related"] << "memory://path/to/entry1.md"
1211
+ ```
1212
+
1213
+ ---
1214
+
1215
+ ## Integration with SwarmSDK
1216
+
1217
+ ### SDKPlugin
1218
+
1219
+ **File:** `lib/swarm_memory/integration/sdk_plugin.rb`
1220
+
1221
+ Bridges SwarmMemory with SwarmSDK's plugin system.
1222
+
1223
+ **Plugin Interface:**
1224
+ ```ruby
1225
+ class SDKPlugin < SwarmSDK::Plugin
1226
+ def name
1227
+ :memory
1228
+ end
1229
+
1230
+ def tools
1231
+ [:MemoryRead, :MemoryWrite, ...] # All memory tools
1232
+ end
1233
+
1234
+ def create_tool(tool_name, context)
1235
+ SwarmMemory.create_tool(tool_name, ...)
1236
+ end
1237
+
1238
+ def create_storage(agent_name:, config:)
1239
+ # Create adapter and storage
1240
+ end
1241
+
1242
+ def system_prompt_contribution(agent_definition:, storage:)
1243
+ # Return memory prompt based on mode
1244
+ end
1245
+
1246
+ def storage_enabled?(agent_definition)
1247
+ agent_definition.memory_enabled?
1248
+ end
1249
+ end
1250
+ ```
1251
+
1252
+ **Lifecycle Hooks:**
1253
+
1254
+ ```mermaid
1255
+ sequenceDiagram
1256
+ participant SwarmSDK
1257
+ participant SDKPlugin
1258
+ participant Agent
1259
+ participant Storage
1260
+
1261
+ SwarmSDK->>SDKPlugin: on_agent_initialized
1262
+ SDKPlugin->>Storage: create_storage(config)
1263
+ SDKPlugin->>Agent: filter tools by mode
1264
+ SDKPlugin->>Agent: register LoadSkill (special)
1265
+ SDKPlugin->>Agent: mark tools immutable
1266
+
1267
+ Note over SwarmSDK,Agent: Agent ready with memory
1268
+
1269
+ SwarmSDK->>SDKPlugin: on_user_message(prompt)
1270
+ SDKPlugin->>Storage: semantic search (skills)
1271
+ SDKPlugin->>Storage: semantic search (memories)
1272
+ SDKPlugin-->>SwarmSDK: system reminders
1273
+
1274
+ Note over SwarmSDK,Storage: Auto-discovery of relevant content
1275
+ ```
1276
+
1277
+ **Memory Modes:**
1278
+
1279
+ | Mode | Tools | Use Case |
1280
+ |------|-------|----------|
1281
+ | **assistant** (default) | Read, Glob, Grep, Write, Edit | Learning & retrieval |
1282
+ | **retrieval** | Read, Glob, Grep | Read-only Q&A |
1283
+ | **researcher** | All tools | Knowledge extraction |
1284
+
1285
+ **Mode-Based Tool Filtering:**
1286
+ ```ruby
1287
+ def on_agent_initialized(agent_name:, agent:, context:)
1288
+ mode = extract_mode(context[:agent_definition].memory)
1289
+ allowed_tools = tools_for_mode(mode)
1290
+
1291
+ # Remove tools not allowed in this mode
1292
+ all_memory_tools.each do |tool_name|
1293
+ agent.remove_tool(tool_name) unless allowed_tools.include?(tool_name)
1294
+ end
1295
+
1296
+ # Register LoadSkill (unless retrieval mode)
1297
+ unless mode == :retrieval
1298
+ load_skill = create_load_skill_tool(context)
1299
+ agent.with_tool(load_skill)
1300
+ end
1301
+
1302
+ # Mark mode-specific tools as immutable
1303
+ agent.mark_tools_immutable(immutable_tools_for_mode(mode))
1304
+ end
1305
+ ```
1306
+
1307
+ **Semantic Discovery on User Messages:**
1308
+ ```ruby
1309
+ def on_user_message(agent_name:, prompt:, is_first_message:)
1310
+ # Adaptive threshold based on query length
1311
+ word_count = prompt.split.size
1312
+ threshold = word_count < 10 ? 0.25 : 0.35
1313
+
1314
+ # Search 1: Skills (type="skill")
1315
+ skills = storage.semantic_index.search(
1316
+ query: prompt,
1317
+ top_k: 3,
1318
+ threshold: threshold,
1319
+ filter: { "type" => "skill" }
1320
+ )
1321
+
1322
+ # Search 2: Memories (concept/fact/experience)
1323
+ memories = storage.semantic_index.search(
1324
+ query: prompt,
1325
+ top_k: 3,
1326
+ threshold: threshold,
1327
+ filter: { "type" => ["concept", "fact", "experience"] }
1328
+ )
1329
+
1330
+ reminders = []
1331
+ reminders << build_skill_reminder(skills) if skills.any?
1332
+ reminders << build_memory_reminder(memories) if memories.any?
1333
+ reminders
1334
+ end
1335
+ ```
1336
+
1337
+ **System Reminders:**
1338
+ ```
1339
+ <system-reminder>
1340
+ 🎯 Found 2 skill(s) in memory that may be relevant:
1341
+
1342
+ **Debug API Errors** (82% match)
1343
+ Path: `skill/debugging/api-errors.md`
1344
+ To use: `LoadSkill(file_path: "skill/debugging/api-errors.md")`
1345
+
1346
+ **API Troubleshooting** (68% match)
1347
+ Path: `skill/debugging/api-troubleshooting.md`
1348
+ To use: `LoadSkill(file_path: "skill/debugging/api-troubleshooting.md")`
1349
+
1350
+ If a skill matches your task: Load it to get instructions.
1351
+ If none match: Ignore and proceed normally.
1352
+ </system-reminder>
1353
+
1354
+ <system-reminder>
1355
+ 📚 Found 3 memory entries that may provide context:
1356
+
1357
+ 💡 **API Error Handling** (concept, 75% match)
1358
+ Path: `concept/api/error-handling.md`
1359
+ Read with: `MemoryRead(file_path: "concept/api/error-handling.md")`
1360
+
1361
+ 📋 **API Documentation** (fact, 70% match)
1362
+ Path: `fact/api/endpoints.md`
1363
+ Read with: `MemoryRead(file_path: "fact/api/endpoints.md")`
1364
+
1365
+ 🔍 **Fixed API Bug 2024** (experience, 65% match)
1366
+ Path: `experience/api-bug-2024.md`
1367
+ Read with: `MemoryRead(file_path: "experience/api-bug-2024.md")`
1368
+
1369
+ These entries may contain relevant knowledge for your task.
1370
+ </system-reminder>
1371
+ ```
1372
+
1373
+ ---
1374
+
1375
+ ### Registration
1376
+
1377
+ **File:** `lib/swarm_memory/integration/registration.rb`
1378
+
1379
+ Auto-registers plugin with SwarmSDK when loaded.
1380
+
1381
+ ```ruby
1382
+ # In lib/swarm_memory.rb:
1383
+ require_relative "swarm_memory/integration/registration"
1384
+ SwarmMemory::Integration::Registration.register!
1385
+
1386
+ # Registration.register! does:
1387
+ def register!
1388
+ return unless defined?(SwarmSDK)
1389
+ plugin = SDKPlugin.new
1390
+ SwarmSDK::PluginRegistry.register(plugin)
1391
+ end
1392
+ ```
1393
+
1394
+ ---
1395
+
1396
+ ## DSL & Configuration
1397
+
1398
+ ### MemoryConfig
1399
+
1400
+ **File:** `lib/swarm_memory/dsl/memory_config.rb`
1401
+
1402
+ Configuration object for agent memory.
1403
+
1404
+ **DSL Usage:**
1405
+ ```ruby
1406
+ # In agent definition:
1407
+ memory do
1408
+ adapter :filesystem # Storage backend
1409
+ directory ".swarm/agent-memory" # Where to store
1410
+ mode :assistant # Tool mode
1411
+ end
1412
+ ```
1413
+
1414
+ **Options:**
1415
+ ```ruby
1416
+ # Adapter options (passed to adapter constructor):
1417
+ option :namespace, "my_agent"
1418
+ option :connection_pool_size, 5
1419
+
1420
+ # For filesystem adapter:
1421
+ directory ".swarm/memory" # Convenience for option :directory, ...
1422
+ ```
1423
+
1424
+ **Modes:**
1425
+ - `:assistant` (default) - Read + Write + Edit
1426
+ - `:retrieval` - Read-only
1427
+ - `:researcher` - All tools
1428
+
1429
+ ---
1430
+
1431
+ ### BuilderExtension
1432
+
1433
+ **File:** `lib/swarm_memory/dsl/builder_extension.rb`
1434
+
1435
+ Injects `memory` DSL method into `SwarmSDK::Agent::Builder`.
1436
+
1437
+ ```ruby
1438
+ module BuilderExtension
1439
+ def memory(&block)
1440
+ @memory_config = SwarmMemory::DSL::MemoryConfig.new
1441
+ @memory_config.instance_eval(&block) if block_given?
1442
+ @memory_config
1443
+ end
1444
+ end
1445
+
1446
+ # Automatically injected when SwarmMemory loads:
1447
+ SwarmSDK::Agent::Builder.include(SwarmMemory::DSL::BuilderExtension)
1448
+ ```
1449
+
1450
+ **Usage in Agent Definition:**
1451
+ ```ruby
1452
+ SwarmSDK.define do
1453
+ agent :researcher do
1454
+ memory do
1455
+ directory ".swarm/researcher-memory"
1456
+ mode :researcher # All tools
1457
+ end
1458
+
1459
+ tools :Read, :WebFetch, :Bash
1460
+ # Memory tools added automatically
1461
+ end
1462
+ end
1463
+ ```
1464
+
1465
+ ---
1466
+
1467
+ ## CLI Commands
1468
+
1469
+ **File:** `lib/swarm_memory/cli/commands.rb`
1470
+
1471
+ Provides CLI for memory management.
1472
+
1473
+ **Commands:**
1474
+
1475
+ ### 1. Setup Embeddings
1476
+ ```bash
1477
+ swarm memory setup
1478
+
1479
+ # With custom model:
1480
+ SWARM_MEMORY_EMBEDDING_MODEL=sentence-transformers/multi-qa-MiniLM-L6-cos-v1 \
1481
+ swarm memory setup
1482
+ ```
1483
+
1484
+ **What it does:**
1485
+ - Downloads ONNX embedding model (~90MB)
1486
+ - Caches to `~/.cache/huggingface/hub`
1487
+ - One-time setup, then reused
1488
+
1489
+ ---
1490
+
1491
+ ### 2. Check Status
1492
+ ```bash
1493
+ swarm memory status
1494
+
1495
+ # Output:
1496
+ # SwarmMemory Embedding Status
1497
+ # ==================================================
1498
+ #
1499
+ # Status: ✓ Model cached
1500
+ # Model: sentence-transformers/multi-qa-MiniLM-L6-cos-v1
1501
+ # Dimensions: 384
1502
+ # Cache: /Users/user/.cache/huggingface/hub
1503
+ #
1504
+ # Semantic search is available.
1505
+ ```
1506
+
1507
+ ---
1508
+
1509
+ ### 3. Show Model Path
1510
+ ```bash
1511
+ swarm memory model-path
1512
+ # /Users/user/.cache/huggingface/hub
1513
+ ```
1514
+
1515
+ ---
1516
+
1517
+ ### 4. Defragment Memory
1518
+ ```bash
1519
+ swarm memory defrag .swarm/assistant-memory
1520
+
1521
+ # Runs full analysis:
1522
+ # - Health report
1523
+ # - Find duplicates
1524
+ # - Find low-quality entries
1525
+ # - Find archival candidates
1526
+ ```
1527
+
1528
+ ---
1529
+
1530
+ ### 5. Rebuild Embeddings
1531
+ ```bash
1532
+ swarm memory rebuild .swarm/assistant-memory
1533
+
1534
+ # With custom settings:
1535
+ SWARM_MEMORY_EMBEDDING_MAX_CHARS=850 \
1536
+ swarm memory rebuild .swarm/assistant-memory
1537
+
1538
+ # Regenerates all embeddings (useful after model change)
1539
+ ```
1540
+
1541
+ ---
1542
+
1543
+ ## Skills System
1544
+
1545
+ ### What are Skills?
1546
+
1547
+ Skills are **special memory entries** that:
1548
+ - Provide step-by-step procedures
1549
+ - Specify required tools
1550
+ - Define tool permissions
1551
+ - Can be loaded to **swap agent tools dynamically**
1552
+
1553
+ ### Skill Structure
1554
+
1555
+ **Content (Markdown):**
1556
+ ```markdown
1557
+ # Debug React Performance
1558
+
1559
+ ## Prerequisites
1560
+ - React DevTools installed
1561
+ - Profiling enabled
1562
+
1563
+ ## Steps
1564
+
1565
+ 1. Open DevTools → Profiler tab
1566
+ 2. Click "Record"
1567
+ 3. Perform the slow interaction
1568
+ 4. Stop recording
1569
+ 5. Analyze flamegraph:
1570
+ - Look for wide bars (long renders)
1571
+ - Check component names
1572
+ - Identify render causes
1573
+
1574
+ ## Common Causes
1575
+ - Missing useMemo/useCallback
1576
+ - Lifting state too high
1577
+ - Expensive calculations in render
1578
+ ```
1579
+
1580
+ **Metadata (YAML sidecar):**
1581
+ ```yaml
1582
+ title: Debug React Performance
1583
+ type: skill
1584
+ confidence: high
1585
+ tags:
1586
+ - react
1587
+ - performance
1588
+ - debugging
1589
+ - profiling
1590
+ related:
1591
+ - memory://concept/react/reconciliation.md
1592
+ - memory://skill/debugging/performance-general.md
1593
+ domain: frontend/react
1594
+ source: experimentation
1595
+ tools:
1596
+ - Read
1597
+ - Edit
1598
+ - Bash
1599
+ - Grep
1600
+ permissions:
1601
+ Bash:
1602
+ allowed_commands:
1603
+ - "^npm "
1604
+ - "^yarn "
1605
+ Write:
1606
+ denied_paths:
1607
+ - "src/secrets/**"
1608
+ ```
1609
+
1610
+ ### Virtual Skills
1611
+
1612
+ Built-in skills that don't consume storage:
1613
+ - `skill/meta/deep-learning.md` - Systematic learning protocol
1614
+
1615
+ **Deep Learning Protocol:**
1616
+ ```markdown
1617
+ # Deep Learning Protocol
1618
+
1619
+ Use this when asked to learn deeply about a topic.
1620
+
1621
+ ## Steps
1622
+ 1. Define Scope
1623
+ 2. Research Broadly (Overview)
1624
+ 3. Research Deeply (Specifics)
1625
+ 4. Build Practical Skills
1626
+ 5. Self-Test Understanding
1627
+ 6. Check Coverage (MemoryGrep)
1628
+ 7. Identify Knowledge Gaps
1629
+ 8. Fill Gaps
1630
+ 9. Verify Completion
1631
+ 10. Report Completion
1632
+
1633
+ ## Success Criteria
1634
+ - Have concepts (how it works)
1635
+ - Have facts (specifics)
1636
+ - Have skills (how to use)
1637
+ - Can explain clearly
1638
+ - Can apply practically
1639
+ ```
1640
+
1641
+ ---
1642
+
1643
+ ## Data Flow & Lifecycle
1644
+
1645
+ ### Write Flow
1646
+
1647
+ ```mermaid
1648
+ sequenceDiagram
1649
+ participant Agent
1650
+ participant MemoryWrite
1651
+ participant Storage
1652
+ participant Embedder
1653
+ participant Adapter
1654
+
1655
+ Agent->>MemoryWrite: execute(file_path, content, title, metadata)
1656
+ MemoryWrite->>MemoryWrite: Validate word count (≤250)
1657
+ MemoryWrite->>MemoryWrite: Parse JSON params
1658
+ MemoryWrite->>Storage: write(file_path, content, title, metadata)
1659
+ Storage->>Storage: PathNormalizer.normalize(file_path)
1660
+ Storage->>Storage: build_searchable_text(content, title, metadata)
1661
+ Storage->>Embedder: embed(searchable_text)
1662
+ Embedder-->>Storage: embedding[384]
1663
+ Storage->>Storage: Emit LogStream event
1664
+ Storage->>Adapter: write(file_path, content, title, embedding, metadata)
1665
+ Adapter->>Adapter: with_write_lock (flock)
1666
+ Adapter->>Adapter: @semaphore.acquire (fiber-safe)
1667
+ Adapter->>Adapter: Check size limits
1668
+ Adapter->>Adapter: Write .md file
1669
+ Adapter->>Adapter: Write .yml file
1670
+ Adapter->>Adapter: Write .emb file
1671
+ Adapter->>Adapter: Update index
1672
+ Adapter-->>Storage: Entry
1673
+ Storage-->>MemoryWrite: Entry
1674
+ MemoryWrite-->>Agent: "Stored at memory://path (size)"
1675
+ ```
1676
+
1677
+ ### Read Flow
1678
+
1679
+ ```mermaid
1680
+ sequenceDiagram
1681
+ participant Agent
1682
+ participant MemoryRead
1683
+ participant Storage
1684
+ participant Adapter
1685
+ participant Tracker
1686
+
1687
+ Agent->>MemoryRead: execute(file_path)
1688
+ MemoryRead->>Tracker: register_read(agent_name, file_path)
1689
+ MemoryRead->>Storage: read_entry(file_path)
1690
+ Storage->>Adapter: read_entry(file_path)
1691
+ Adapter->>Adapter: Check virtual entries
1692
+ Adapter->>Adapter: Check stubs (follow redirects)
1693
+ Adapter->>Adapter: Read .md file
1694
+ Adapter->>Adapter: Read .yml file
1695
+ Adapter->>Adapter: Read .emb file (if exists)
1696
+ Adapter->>Adapter: increment_hits(file_path)
1697
+ Adapter-->>Storage: Entry
1698
+ Storage-->>MemoryRead: Entry
1699
+ MemoryRead->>MemoryRead: format_as_json(entry)
1700
+ MemoryRead-->>Agent: JSON{content, metadata}
1701
+ ```
1702
+
1703
+ ### Edit Flow
1704
+
1705
+ ```mermaid
1706
+ sequenceDiagram
1707
+ participant Agent
1708
+ participant MemoryEdit
1709
+ participant Tracker
1710
+ participant Storage
1711
+ participant Adapter
1712
+
1713
+ Agent->>MemoryEdit: execute(file_path, old_string, new_string)
1714
+ MemoryEdit->>Tracker: entry_read?(agent_name, file_path)
1715
+ Tracker-->>MemoryEdit: true/false
1716
+ alt Not read
1717
+ MemoryEdit-->>Agent: Error: Must read first
1718
+ end
1719
+ MemoryEdit->>Storage: read(file_path)
1720
+ Storage-->>MemoryEdit: content
1721
+ MemoryEdit->>MemoryEdit: Check old_string exists
1722
+ MemoryEdit->>MemoryEdit: Count occurrences
1723
+ alt Multiple occurrences && !replace_all
1724
+ MemoryEdit-->>Agent: Error: Not unique
1725
+ end
1726
+ MemoryEdit->>MemoryEdit: Perform replacement
1727
+ MemoryEdit->>Storage: read_entry(file_path)
1728
+ Storage-->>MemoryEdit: Entry (for title)
1729
+ MemoryEdit->>Storage: write(file_path, new_content, title)
1730
+ Storage-->>MemoryEdit: Entry
1731
+ MemoryEdit-->>Agent: "Replaced N occurrence(s)"
1732
+ ```
1733
+
1734
+ ### Semantic Discovery Flow
1735
+
1736
+ ```mermaid
1737
+ sequenceDiagram
1738
+ participant User
1739
+ participant SwarmSDK
1740
+ participant SDKPlugin
1741
+ participant SemanticIndex
1742
+ participant Embedder
1743
+ participant Agent
1744
+
1745
+ User->>SwarmSDK: Send message
1746
+ SwarmSDK->>SDKPlugin: on_user_message(prompt)
1747
+
1748
+ par Parallel Search
1749
+ SDKPlugin->>SemanticIndex: search(query, filter={type:"skill"})
1750
+ SemanticIndex->>Embedder: embed(query)
1751
+ Embedder-->>SemanticIndex: query_embedding
1752
+ SemanticIndex->>SemanticIndex: semantic_search + keyword_match
1753
+ SemanticIndex-->>SDKPlugin: skills[]
1754
+ and
1755
+ SDKPlugin->>SemanticIndex: search(query, filter={type:["concept","fact","experience"]})
1756
+ SemanticIndex-->>SDKPlugin: memories[]
1757
+ end
1758
+
1759
+ SDKPlugin->>SDKPlugin: Emit LogStream events
1760
+ SDKPlugin->>SDKPlugin: build_skill_reminder(skills)
1761
+ SDKPlugin->>SDKPlugin: build_memory_reminder(memories)
1762
+ SDKPlugin-->>SwarmSDK: [skill_reminder, memory_reminder]
1763
+ SwarmSDK->>Agent: Inject system reminders
1764
+ Agent->>User: Response with context
1765
+ ```
1766
+
1767
+ ### LoadSkill Flow
1768
+
1769
+ ```mermaid
1770
+ sequenceDiagram
1771
+ participant Agent
1772
+ participant LoadSkill
1773
+ participant Storage
1774
+ participant Chat
1775
+ participant ToolConfig
1776
+
1777
+ Agent->>LoadSkill: LoadSkill(skill/debug-api.md)
1778
+ LoadSkill->>LoadSkill: Validate path starts with "skill/"
1779
+ LoadSkill->>Storage: read_entry(skill/debug-api.md)
1780
+ Storage-->>LoadSkill: Entry
1781
+ LoadSkill->>LoadSkill: Validate type=="skill"
1782
+ LoadSkill->>LoadSkill: Extract tools & permissions
1783
+
1784
+ LoadSkill->>Chat: remove_mutable_tools()
1785
+ Note over Chat: Keeps immutable tools:<br/>Memory*, LoadSkill
1786
+
1787
+ loop For each required tool
1788
+ LoadSkill->>ToolConfig: create_tool_instance(tool_name)
1789
+ ToolConfig-->>LoadSkill: tool_instance
1790
+ LoadSkill->>ToolConfig: wrap_with_permissions(tool, perms)
1791
+ ToolConfig-->>LoadSkill: wrapped_tool
1792
+ LoadSkill->>Chat: add_tool(wrapped_tool)
1793
+ end
1794
+
1795
+ LoadSkill->>Chat: mark_skill_loaded(path)
1796
+ LoadSkill->>LoadSkill: format_with_line_numbers(content)
1797
+ LoadSkill->>LoadSkill: build_toolset_reminder(tools)
1798
+ LoadSkill-->>Agent: Content + System Reminder
1799
+
1800
+ Note over Agent: Agent now has skill's tools
1801
+ ```
1802
+
1803
+ ---
1804
+
1805
+ ## Testing Strategy
1806
+
1807
+ ### Test Structure
1808
+
1809
+ ```
1810
+ test/swarm_memory/
1811
+ ├── adapter_registry_test.rb
1812
+ ├── adapters/
1813
+ │ ├── filesystem_adapter_test.rb
1814
+ │ ├── file_locking_test.rb
1815
+ │ └── virtual_entries_test.rb
1816
+ ├── core/
1817
+ │ ├── entry_test.rb
1818
+ │ ├── frontmatter_parser_test.rb
1819
+ │ └── path_normalizer_test.rb
1820
+ ├── tools/
1821
+ │ ├── memory_write_test.rb
1822
+ │ ├── memory_read_test.rb
1823
+ │ ├── memory_defrag_test.rb
1824
+ │ └── load_skill_test.rb
1825
+ ├── integration/
1826
+ │ ├── registration_test.rb
1827
+ │ ├── swarm_sdk_integration_test.rb
1828
+ │ └── skills_integration_test.rb
1829
+ └── optimization/
1830
+ └── defragmenter_test.rb
1831
+ ```
1832
+
1833
+ ### Test Helpers
1834
+
1835
+ **`swarm_memory_test_helper.rb`:**
1836
+ ```ruby
1837
+ def create_temp_storage
1838
+ temp_dir = File.join(Dir.tmpdir, "test-storage-#{SecureRandom.hex}")
1839
+ adapter = SwarmMemory::Adapters::FilesystemAdapter.new(directory: temp_dir)
1840
+ embedder = SwarmMemory::Embeddings::InformersEmbedder.new
1841
+ SwarmMemory::Core::Storage.new(adapter: adapter, embedder: embedder)
1842
+ end
1843
+
1844
+ def cleanup_storage(storage)
1845
+ FileUtils.rm_rf(storage.adapter.instance_variable_get(:@directory))
1846
+ end
1847
+ ```
1848
+
1849
+ ### Key Test Patterns
1850
+
1851
+ **1. Tool Execution Tests:**
1852
+ ```ruby
1853
+ def test_write_entry_with_minimal_metadata
1854
+ result = @tool.execute(
1855
+ file_path: "test/simple.md",
1856
+ content: "Simple content",
1857
+ title: "Simple Entry",
1858
+ type: "fact",
1859
+ tags: ["test"],
1860
+ related: [],
1861
+ domain: "testing"
1862
+ )
1863
+
1864
+ assert_match(%r{Stored at memory://test/simple.md}, result)
1865
+ entry = @storage.read_entry(file_path: "test/simple.md")
1866
+ assert_equal("Simple content", entry.content)
1867
+ end
1868
+ ```
1869
+
1870
+ **2. Concurrency Tests:**
1871
+ ```ruby
1872
+ def test_concurrent_writes
1873
+ threads = 10.times.map do |i|
1874
+ Thread.new do
1875
+ @adapter.write(
1876
+ file_path: "concurrent/entry-#{i}.md",
1877
+ content: "content #{i}",
1878
+ title: "Entry #{i}"
1879
+ )
1880
+ end
1881
+ end
1882
+
1883
+ threads.each(&:join)
1884
+ assert_equal(10, @adapter.list(prefix: "concurrent").size)
1885
+ end
1886
+ ```
1887
+
1888
+ **3. Integration Tests:**
1889
+ ```ruby
1890
+ def test_swarm_sdk_integration
1891
+ swarm = SwarmSDK.define do
1892
+ agent :tester do
1893
+ memory do
1894
+ directory temp_memory_dir
1895
+ mode :assistant
1896
+ end
1897
+ tools :Read
1898
+ end
1899
+ end
1900
+
1901
+ # Memory tools automatically added
1902
+ assert_includes(swarm.agent(:tester).tools.keys, :MemoryWrite)
1903
+ end
1904
+ ```
1905
+
1906
+ ---
1907
+
1908
+ ## Environment Variables Reference
1909
+
1910
+ ### Embedding Configuration
1911
+
1912
+ ```bash
1913
+ # Model selection (default: multi-qa-MiniLM-L6-cos-v1)
1914
+ SWARM_MEMORY_EMBEDDING_MODEL=sentence-transformers/multi-qa-MiniLM-L6-cos-v1
1915
+
1916
+ # Searchable text length (default: 1200, -1 = unlimited)
1917
+ SWARM_MEMORY_EMBEDDING_MAX_CHARS=1200
1918
+ ```
1919
+
1920
+ ### Search Configuration
1921
+
1922
+ ```bash
1923
+ # Hybrid search weights (default: 0.5 each)
1924
+ SWARM_MEMORY_SEMANTIC_WEIGHT=0.5
1925
+ SWARM_MEMORY_KEYWORD_WEIGHT=0.5
1926
+
1927
+ # Adaptive thresholds (default: 0.35 normal, 0.25 short)
1928
+ SWARM_MEMORY_DISCOVERY_THRESHOLD=0.35 # Normal queries
1929
+ SWARM_MEMORY_DISCOVERY_THRESHOLD_SHORT=0.25 # Short queries
1930
+ SWARM_MEMORY_ADAPTIVE_WORD_CUTOFF=10 # Cutoff for "short"
1931
+ ```
1932
+
1933
+ ---
1934
+
1935
+ ## Architecture Diagrams
1936
+
1937
+ ### Component Layers
1938
+
1939
+ ```mermaid
1940
+ graph TB
1941
+ subgraph "Layer 5: Integration"
1942
+ SDKPlugin[SDKPlugin]
1943
+ DSL[DSL & Config]
1944
+ CLI[CLI Commands]
1945
+ end
1946
+
1947
+ subgraph "Layer 4: Tools"
1948
+ MemWrite[MemoryWrite]
1949
+ MemRead[MemoryRead]
1950
+ MemEdit[MemoryEdit]
1951
+ MemGlob[MemoryGlob]
1952
+ MemGrep[MemoryGrep]
1953
+ LoadSkill[LoadSkill]
1954
+ MemDefrag[MemoryDefrag]
1955
+ end
1956
+
1957
+ subgraph "Layer 3: Optimization"
1958
+ Analyzer[Analyzer]
1959
+ Defrag[Defragmenter]
1960
+ end
1961
+
1962
+ subgraph "Layer 2: Core"
1963
+ Storage[Storage]
1964
+ SemanticIndex[SemanticIndex]
1965
+ Entry[Entry]
1966
+ PathNorm[PathNormalizer]
1967
+ ReadTracker[ReadTracker]
1968
+ end
1969
+
1970
+ subgraph "Layer 1: Adapters & Embeddings"
1971
+ FSAdapter[FilesystemAdapter]
1972
+ Embedder[InformersEmbedder]
1973
+ TextSim[TextSimilarity]
1974
+ end
1975
+
1976
+ SDKPlugin --> MemWrite
1977
+ SDKPlugin --> LoadSkill
1978
+ MemWrite --> Storage
1979
+ MemRead --> Storage
1980
+ LoadSkill --> Storage
1981
+ MemDefrag --> Defrag
1982
+ Defrag --> Analyzer
1983
+ Storage --> SemanticIndex
1984
+ Storage --> FSAdapter
1985
+ SemanticIndex --> Embedder
1986
+ SemanticIndex --> TextSim
1987
+
1988
+ style SDKPlugin fill:#f3e5f5
1989
+ style Storage fill:#fff4e1
1990
+ style Embedder fill:#e8f5e9
1991
+ ```
1992
+
1993
+ ### File Organization
1994
+
1995
+ ```
1996
+ lib/swarm_memory/
1997
+ ├── swarm_memory.rb # Entry point, auto-registration
1998
+ ├── version.rb # VERSION constant
1999
+ ├── errors.rb # Error classes
2000
+ ├── utils.rb # Utility methods
2001
+
2002
+ ├── core/ # Core system
2003
+ │ ├── entry.rb # Entry struct
2004
+ │ ├── storage.rb # Orchestrator
2005
+ │ ├── semantic_index.rb # Hybrid search
2006
+ │ ├── frontmatter_parser.rb # YAML parsing
2007
+ │ ├── metadata_extractor.rb # Quality scoring
2008
+ │ ├── path_normalizer.rb # Path validation
2009
+ │ └── storage_read_tracker.rb # Read enforcement
2010
+
2011
+ ├── adapters/ # Storage backends
2012
+ │ ├── base.rb # Abstract interface
2013
+ │ └── filesystem_adapter.rb # Real filesystem
2014
+
2015
+ ├── embeddings/ # Embedding generation
2016
+ │ ├── embedder.rb # Abstract interface
2017
+ │ └── informers_embedder.rb # ONNX-based
2018
+
2019
+ ├── search/ # Search implementations
2020
+ │ ├── semantic_search.rb # Embedding-based
2021
+ │ ├── text_search.rb # Glob/grep wrapper
2022
+ │ └── text_similarity.rb # Similarity metrics
2023
+
2024
+ ├── tools/ # Memory tools
2025
+ │ ├── memory_write.rb
2026
+ │ ├── memory_read.rb
2027
+ │ ├── memory_edit.rb
2028
+ │ ├── memory_multi_edit.rb
2029
+ │ ├── memory_delete.rb
2030
+ │ ├── memory_glob.rb
2031
+ │ ├── memory_grep.rb
2032
+ │ ├── memory_defrag.rb
2033
+ │ └── load_skill.rb
2034
+
2035
+ ├── optimization/ # Memory optimization
2036
+ │ ├── analyzer.rb # Health metrics
2037
+ │ └── defragmenter.rb # Optimization ops
2038
+
2039
+ ├── integration/ # SwarmSDK/CLI integration
2040
+ │ ├── sdk_plugin.rb # Plugin implementation
2041
+ │ ├── registration.rb # Auto-registration
2042
+ │ ├── configuration.rb # Config wrapper
2043
+ │ └── cli_registration.rb # CLI registration
2044
+
2045
+ ├── dsl/ # DSL for agent config
2046
+ │ ├── memory_config.rb # Config object
2047
+ │ └── builder_extension.rb # DSL injection
2048
+
2049
+ ├── cli/ # CLI commands
2050
+ │ └── commands.rb # swarm memory ...
2051
+
2052
+ ├── chat_extension.rb # Chat#remove_tool extension
2053
+
2054
+ ├── prompts/ # System prompts
2055
+ │ ├── memory_assistant.md.erb
2056
+ │ ├── memory_retrieval.md.erb
2057
+ │ └── memory_researcher.md.erb
2058
+
2059
+ └── skills/ # Built-in skills
2060
+ └── meta/
2061
+ ├── deep-learning.md
2062
+ └── deep-learning.yml
2063
+ ```
2064
+
2065
+ ---
2066
+
2067
+ ## Summary
2068
+
2069
+ SwarmMemory provides a complete **persistent memory system with semantic search** for SwarmSDK agents:
2070
+
2071
+ ✅ **Hierarchical Storage** - 4 fixed categories: concept/, fact/, skill/, experience/
2072
+ ✅ **Hybrid Search** - Combines semantic similarity + keyword matching
2073
+ ✅ **Tool Swapping** - LoadSkill dynamically adapts agent capabilities
2074
+ ✅ **Memory Optimization** - Automated duplicate detection, linking, and cleanup
2075
+ ✅ **Plugin Architecture** - Clean integration with SwarmSDK
2076
+ ✅ **Semantic Discovery** - Auto-surfaces relevant skills and memories
2077
+ ✅ **Multiple Modes** - assistant/retrieval/researcher with different tool sets
2078
+ ✅ **CLI Management** - Setup, status, defrag, rebuild commands
2079
+ ✅ **Production Ready** - Thread-safe, fiber-safe, cross-process locking
2080
+
2081
+ **Key Innovations:**
2082
+ - **250-word memory limit** forces focused, searchable entries
2083
+ - **Read-before-edit enforcement** prevents blind modifications
2084
+ - **Immutable tools** ensure memory tools never removed by LoadSkill
2085
+ - **Adaptive thresholds** handle short and long queries differently
2086
+ - **Virtual skills** provide meta-capabilities without storage cost
2087
+
2088
+ ---
2089
+
2090
+ **End of Technical Reference**