robot_lab 0.3.0 → 0.3.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.
Files changed (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +1 -1
  4. data/lib/robot_lab/mcp/transports/streamable_http.rb +1 -1
  5. data/lib/robot_lab/version.rb +1 -1
  6. metadata +3 -253
  7. data/.architecture/AGENTS.md +0 -32
  8. data/.architecture/config.yml +0 -8
  9. data/.architecture/members.yml +0 -60
  10. data/.architecture/reviews/feature-free-will.md +0 -490
  11. data/.architecture/reviews/overall-codebase.md +0 -427
  12. data/.claude/settings.local.json +0 -57
  13. data/.codex/config.toml +0 -2
  14. data/.envrc +0 -6
  15. data/.github/workflows/deploy-github-pages.yml +0 -52
  16. data/.irbrc +0 -6
  17. data/.loki +0 -65
  18. data/.quality/reek_baseline.txt +0 -43
  19. data/.rubocop.yml +0 -10
  20. data/Archspec.rb +0 -44
  21. data/CLAUDE.md +0 -141
  22. data/COMMITS.md +0 -196
  23. data/Rakefile +0 -193
  24. data/_typos.toml +0 -21
  25. data/agent2agent_review.md +0 -192
  26. data/agentf_improvements.md +0 -253
  27. data/agents.md +0 -14
  28. data/docs/api/core/index.md +0 -147
  29. data/docs/api/core/memory.md +0 -578
  30. data/docs/api/core/network.md +0 -553
  31. data/docs/api/core/result.md +0 -211
  32. data/docs/api/core/robot.md +0 -1667
  33. data/docs/api/core/state.md +0 -145
  34. data/docs/api/core/tool.md +0 -520
  35. data/docs/api/errors.md +0 -323
  36. data/docs/api/hooks.md +0 -469
  37. data/docs/api/index.md +0 -137
  38. data/docs/api/mcp/client.md +0 -387
  39. data/docs/api/mcp/index.md +0 -267
  40. data/docs/api/mcp/server.md +0 -252
  41. data/docs/api/mcp/transports.md +0 -339
  42. data/docs/api/messages/index.md +0 -126
  43. data/docs/api/messages/text-message.md +0 -170
  44. data/docs/api/messages/tool-call-message.md +0 -206
  45. data/docs/api/messages/tool-result-message.md +0 -242
  46. data/docs/api/messages/user-message.md +0 -232
  47. data/docs/api/skills.md +0 -423
  48. data/docs/api/streaming/context.md +0 -280
  49. data/docs/api/streaming/events.md +0 -185
  50. data/docs/api/streaming/index.md +0 -156
  51. data/docs/api/support.md +0 -846
  52. data/docs/architecture/core-concepts.md +0 -575
  53. data/docs/architecture/index.md +0 -252
  54. data/docs/architecture/message-flow.md +0 -366
  55. data/docs/architecture/network-orchestration.md +0 -478
  56. data/docs/architecture/robot-execution.md +0 -396
  57. data/docs/architecture/state-management.md +0 -410
  58. data/docs/assets/css/custom.css +0 -56
  59. data/docs/assets/images/robot_lab.jpg +0 -0
  60. data/docs/concepts.md +0 -641
  61. data/docs/examples/basic-chat.md +0 -258
  62. data/docs/examples/index.md +0 -425
  63. data/docs/examples/mcp-server.md +0 -403
  64. data/docs/examples/multi-robot-network.md +0 -476
  65. data/docs/examples/tool-usage.md +0 -468
  66. data/docs/getting-started/configuration.md +0 -645
  67. data/docs/getting-started/index.md +0 -56
  68. data/docs/getting-started/installation.md +0 -197
  69. data/docs/getting-started/quick-start.md +0 -293
  70. data/docs/guides/building-robots.md +0 -1187
  71. data/docs/guides/creating-networks.md +0 -736
  72. data/docs/guides/hooks.md +0 -1206
  73. data/docs/guides/index.md +0 -78
  74. data/docs/guides/knowledge.md +0 -219
  75. data/docs/guides/mcp-integration.md +0 -740
  76. data/docs/guides/memory.md +0 -458
  77. data/docs/guides/observability.md +0 -733
  78. data/docs/guides/streaming.md +0 -323
  79. data/docs/guides/using-tools.md +0 -780
  80. data/docs/index.md +0 -280
  81. data/docs/superpowers/plans/2026-05-06-agentskills.md +0 -1303
  82. data/docs/superpowers/specs/2026-05-06-agentskills-design.md +0 -247
  83. data/examples/.envrc +0 -3
  84. data/examples/01_simple_robot.rb +0 -31
  85. data/examples/02_tools.rb +0 -109
  86. data/examples/03_network.rb +0 -118
  87. data/examples/04_mcp.rb +0 -217
  88. data/examples/05_streaming.rb +0 -137
  89. data/examples/06_prompt_templates.rb +0 -325
  90. data/examples/07_network_memory.rb +0 -313
  91. data/examples/08_llm_config.rb +0 -162
  92. data/examples/09_chaining.rb +0 -251
  93. data/examples/10_memory.rb +0 -315
  94. data/examples/11_network_introspection.rb +0 -239
  95. data/examples/12_message_bus.rb +0 -67
  96. data/examples/13_spawn.rb +0 -85
  97. data/examples/14_rusty_circuit/.envrc +0 -1
  98. data/examples/14_rusty_circuit/.gitignore +0 -1
  99. data/examples/14_rusty_circuit/README.md +0 -1
  100. data/examples/14_rusty_circuit/comic.rb +0 -149
  101. data/examples/14_rusty_circuit/display.rb +0 -217
  102. data/examples/14_rusty_circuit/heckler.rb +0 -65
  103. data/examples/14_rusty_circuit/open_mic.rb +0 -132
  104. data/examples/14_rusty_circuit/prompts/open_mic_comic.md +0 -20
  105. data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +0 -23
  106. data/examples/14_rusty_circuit/prompts/open_mic_scout.md +0 -20
  107. data/examples/14_rusty_circuit/scout.rb +0 -165
  108. data/examples/14_rusty_circuit/show.log +0 -234
  109. data/examples/15_memory_network_and_bus/.envrc +0 -1
  110. data/examples/15_memory_network_and_bus/README.md +0 -66
  111. data/examples/15_memory_network_and_bus/editor_in_chief.rb +0 -24
  112. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +0 -213
  113. data/examples/15_memory_network_and_bus/linux_writer.rb +0 -80
  114. data/examples/15_memory_network_and_bus/os_editor.rb +0 -48
  115. data/examples/15_memory_network_and_bus/os_writer.rb +0 -49
  116. data/examples/15_memory_network_and_bus/output/combined_article.md +0 -11
  117. data/examples/15_memory_network_and_bus/output/final_article.md +0 -8
  118. data/examples/15_memory_network_and_bus/output/linux_draft.md +0 -7
  119. data/examples/15_memory_network_and_bus/output/mac_draft.md +0 -7
  120. data/examples/15_memory_network_and_bus/output/memory.json +0 -13
  121. data/examples/15_memory_network_and_bus/output/revision_1.md +0 -29
  122. data/examples/15_memory_network_and_bus/output/revision_2.md +0 -50
  123. data/examples/15_memory_network_and_bus/output/revision_3.md +0 -8
  124. data/examples/15_memory_network_and_bus/output/windows_draft.md +0 -7
  125. data/examples/15_memory_network_and_bus/prompts/os_advocate.md +0 -13
  126. data/examples/15_memory_network_and_bus/prompts/os_chief.md +0 -13
  127. data/examples/15_memory_network_and_bus/prompts/os_editor.md +0 -13
  128. data/examples/16_writers_room/.envrc +0 -1
  129. data/examples/16_writers_room/display.rb +0 -158
  130. data/examples/16_writers_room/output/.gitignore +0 -4
  131. data/examples/16_writers_room/output/README.md +0 -69
  132. data/examples/16_writers_room/output/opus_001.md +0 -263
  133. data/examples/16_writers_room/output/opus_001_notes.log +0 -470
  134. data/examples/16_writers_room/output/opus_002.md +0 -245
  135. data/examples/16_writers_room/output/opus_002_notes.log +0 -546
  136. data/examples/16_writers_room/output/opus_002_screenplay.md +0 -7989
  137. data/examples/16_writers_room/output/opus_002_screenplay_notes.md +0 -993
  138. data/examples/16_writers_room/prompts/screenplay_writer.md +0 -66
  139. data/examples/16_writers_room/prompts/writer.md +0 -37
  140. data/examples/16_writers_room/room.rb +0 -186
  141. data/examples/16_writers_room/tools.rb +0 -173
  142. data/examples/16_writers_room/writer.rb +0 -121
  143. data/examples/16_writers_room/writers_room.rb +0 -256
  144. data/examples/17_skills.rb +0 -234
  145. data/examples/18_rails/.envrc +0 -3
  146. data/examples/18_rails/.gitignore +0 -5
  147. data/examples/18_rails/Gemfile +0 -11
  148. data/examples/18_rails/README.md +0 -67
  149. data/examples/18_rails/Rakefile +0 -4
  150. data/examples/18_rails/app/controllers/application_controller.rb +0 -4
  151. data/examples/18_rails/app/controllers/chat_controller.rb +0 -50
  152. data/examples/18_rails/app/jobs/application_job.rb +0 -4
  153. data/examples/18_rails/app/jobs/robot_run_job.rb +0 -25
  154. data/examples/18_rails/app/models/application_record.rb +0 -5
  155. data/examples/18_rails/app/models/robot_lab_result.rb +0 -36
  156. data/examples/18_rails/app/models/robot_lab_thread.rb +0 -23
  157. data/examples/18_rails/app/robots/chat_robot.rb +0 -25
  158. data/examples/18_rails/app/tools/time_tool.rb +0 -9
  159. data/examples/18_rails/app/views/chat/_user_message.html.erb +0 -1
  160. data/examples/18_rails/app/views/chat/index.html.erb +0 -67
  161. data/examples/18_rails/app/views/layouts/application.html.erb +0 -49
  162. data/examples/18_rails/bin/dev +0 -7
  163. data/examples/18_rails/bin/rails +0 -6
  164. data/examples/18_rails/bin/setup +0 -15
  165. data/examples/18_rails/config/application.rb +0 -33
  166. data/examples/18_rails/config/cable.yml +0 -2
  167. data/examples/18_rails/config/database.yml +0 -5
  168. data/examples/18_rails/config/environment.rb +0 -4
  169. data/examples/18_rails/config/initializers/robot_lab.rb +0 -11
  170. data/examples/18_rails/config/routes.rb +0 -6
  171. data/examples/18_rails/config.ru +0 -4
  172. data/examples/18_rails/db/migrate/001_create_robot_lab_tables.rb +0 -32
  173. data/examples/19_token_tracking.rb +0 -138
  174. data/examples/20_circuit_breaker.rb +0 -147
  175. data/examples/21_learning_loop.rb +0 -181
  176. data/examples/22_context_compression.rb +0 -172
  177. data/examples/23_convergence.rb +0 -133
  178. data/examples/24_structured_delegation.rb +0 -151
  179. data/examples/25_history_search/conversation.jsonl +0 -30
  180. data/examples/25_history_search.rb +0 -133
  181. data/examples/26_document_store/api_versioning_adr.md +0 -52
  182. data/examples/26_document_store/incident_postmortem.md +0 -46
  183. data/examples/26_document_store/postgres_runbook.md +0 -49
  184. data/examples/26_document_store/redis_caching_guide.md +0 -48
  185. data/examples/26_document_store/sidekiq_guide.md +0 -51
  186. data/examples/26_document_store.rb +0 -140
  187. data/examples/27_incident_response/README.md +0 -65
  188. data/examples/27_incident_response/incident_response.rb +0 -261
  189. data/examples/28_mcp_discovery.rb +0 -113
  190. data/examples/29_ractor_tools.rb +0 -240
  191. data/examples/30_ractor_network.rb +0 -252
  192. data/examples/31_launch_assessment.rb +0 -246
  193. data/examples/32_newsletter_reader.rb +0 -193
  194. data/examples/33_stock_generator.rb +0 -80
  195. data/examples/33_stock_predictor.rb +0 -327
  196. data/examples/34_agentskills.rb +0 -76
  197. data/examples/35_hooks.rb +0 -266
  198. data/examples/README.md +0 -550
  199. data/examples/common.rb +0 -180
  200. data/examples/prompts/assistant.md +0 -5
  201. data/examples/prompts/audit_trail.md +0 -8
  202. data/examples/prompts/billing.md +0 -10
  203. data/examples/prompts/classifier.md +0 -7
  204. data/examples/prompts/comedian.md +0 -6
  205. data/examples/prompts/comedy_critic.md +0 -10
  206. data/examples/prompts/configurable.md +0 -9
  207. data/examples/prompts/dispatcher.md +0 -12
  208. data/examples/prompts/entity_extractor.md +0 -14
  209. data/examples/prompts/escalation.md +0 -42
  210. data/examples/prompts/frontmatter_mcp_test.md +0 -9
  211. data/examples/prompts/frontmatter_named_test.md +0 -5
  212. data/examples/prompts/frontmatter_tools_test.md +0 -6
  213. data/examples/prompts/general.md +0 -7
  214. data/examples/prompts/github_assistant.md +0 -14
  215. data/examples/prompts/helper.md +0 -4
  216. data/examples/prompts/incident_responder.md +0 -18
  217. data/examples/prompts/keyword_extractor.md +0 -11
  218. data/examples/prompts/llm_config_demo.md +0 -20
  219. data/examples/prompts/order_support.md +0 -35
  220. data/examples/prompts/os_advocate.md +0 -13
  221. data/examples/prompts/os_chief.md +0 -13
  222. data/examples/prompts/os_editor.md +0 -13
  223. data/examples/prompts/parameterized_main_test.md +0 -6
  224. data/examples/prompts/pii_redactor.md +0 -7
  225. data/examples/prompts/product_support.md +0 -37
  226. data/examples/prompts/runbook_protocol.md +0 -12
  227. data/examples/prompts/sentiment_analyzer.md +0 -12
  228. data/examples/prompts/skill_a_test.md +0 -4
  229. data/examples/prompts/skill_b_test.md +0 -4
  230. data/examples/prompts/skill_config_test.md +0 -5
  231. data/examples/prompts/skill_cycle_a_test.md +0 -6
  232. data/examples/prompts/skill_cycle_b_test.md +0 -6
  233. data/examples/prompts/skill_description_test.md +0 -4
  234. data/examples/prompts/skill_leaf_test.md +0 -4
  235. data/examples/prompts/skill_nested_test.md +0 -6
  236. data/examples/prompts/skill_refs_main_test.md +0 -6
  237. data/examples/prompts/skill_self_ref_test.md +0 -6
  238. data/examples/prompts/skill_with_mcp_test.md +0 -9
  239. data/examples/prompts/skill_with_params_test.md +0 -6
  240. data/examples/prompts/skill_with_robot_name_test.md +0 -5
  241. data/examples/prompts/skill_with_tools_test.md +0 -6
  242. data/examples/prompts/sre_compliance.md +0 -10
  243. data/examples/prompts/structured_output.md +0 -7
  244. data/examples/prompts/synthesizer.md +0 -17
  245. data/examples/prompts/technical.md +0 -10
  246. data/examples/prompts/template_with_skills_test.md +0 -6
  247. data/examples/prompts/triage.md +0 -22
  248. data/examples/ruboruby.md +0 -423
  249. data/examples/run_all.rb +0 -60
  250. data/examples/xyzzy.rb +0 -97
  251. data/logfile +0 -8
  252. data/mkdocs.yml +0 -209
  253. data/robot_concurrency.md +0 -38
  254. data/simple_acp_review.md +0 -298
  255. data/temp.md +0 -6
  256. data/tool_manifest_plan.md +0 -155
data/docs/guides/index.md DELETED
@@ -1,78 +0,0 @@
1
- # Guides
2
-
3
- Practical guides for building applications with RobotLab.
4
-
5
- ## Getting Started
6
-
7
- If you're new to RobotLab, start here:
8
-
9
- <div class="grid cards" markdown>
10
-
11
- - [:octicons-cpu-24: **Building Robots**](building-robots.md)
12
-
13
- Create specialized AI agents with personalities and tools
14
-
15
- - [:octicons-git-branch-24: **Creating Networks**](creating-networks.md)
16
-
17
- Orchestrate multiple robots for complex workflows
18
-
19
- </div>
20
-
21
- ## Core Features
22
-
23
- <div class="grid cards" markdown>
24
-
25
- - [:octicons-tools-24: **Using Tools**](using-tools.md)
26
-
27
- Give robots custom capabilities to interact with external systems
28
-
29
- - [:octicons-server-24: **MCP Integration**](mcp-integration.md)
30
-
31
- Connect to Model Context Protocol servers
32
-
33
- - [:octicons-broadcast-24: **Streaming Responses**](streaming.md)
34
-
35
- Real-time streaming of LLM responses
36
-
37
- - [:octicons-cpu-24: **Memory System**](memory.md)
38
-
39
- Share data between robots with the memory system
40
-
41
- - [:octicons-pulse-24: **Observability & Safety**](observability.md)
42
-
43
- Token tracking, circuit breakers, doom loop detection, auto compaction, and learning accumulation
44
-
45
- - [:octicons-zap-24: **Hook System**](hooks.md)
46
-
47
- Lifecycle hooks for instrumentation, response caching, extensions, and cross-cutting concerns
48
-
49
- - [:octicons-search-24: **Knowledge & Retrieval**](knowledge.md)
50
-
51
- Chat history search and embedding-based document store for RAG workflows
52
-
53
- </div>
54
-
55
- ## Guide Index
56
-
57
- | Guide | Description | Time |
58
- |-------|-------------|------|
59
- | [Building Robots](building-robots.md) | Create and configure robots | 10 min |
60
- | [Creating Networks](creating-networks.md) | Multi-robot orchestration | 15 min |
61
- | [Using Tools](using-tools.md) | Add custom capabilities | 10 min |
62
- | [MCP Integration](mcp-integration.md) | External tool servers | 10 min |
63
- | [Streaming](streaming.md) | Real-time responses | 5 min |
64
- | [Memory](memory.md) | Shared data store | 5 min |
65
- | [Observability & Safety](observability.md) | Token tracking, circuit breaker, doom loop detection, auto compaction, learning loop | 10 min |
66
- | [Hook System](hooks.md) | Lifecycle hooks, extensions, response caching, instrumentation | 15 min |
67
- | [Knowledge & Retrieval](knowledge.md) | Chat history search and embedding-based document store (RAG) | 10 min |
68
-
69
- ## Extension Gems
70
-
71
- Additional capabilities are available as separate gems:
72
-
73
- | Gem | Description | Docs |
74
- |-----|-------------|------|
75
- | [robot_lab-rails](https://github.com/MadBomber/robot_lab-rails) | Rails generators, background jobs, Turbo Stream broadcasting | [Rails Integration guide](https://github.com/MadBomber/robot_lab-rails/blob/main/docs/guides/rails-integration.md) |
76
- | [robot_lab-ractor](https://github.com/MadBomber/robot_lab-ractor) | True CPU parallelism for tools and robot pipelines via Ruby Ractors | [Ractor Parallelism guide](https://github.com/MadBomber/robot_lab-ractor/blob/main/docs/guides/ractor-parallelism.md) |
77
- | [robot_lab-durable](https://github.com/MadBomber/robot_lab-durable) | Cross-session knowledge persistence with YAML-backed storage | [robot_lab-durable README](https://github.com/MadBomber/robot_lab-durable) |
78
- | [robot_lab-document_store](https://github.com/MadBomber/robot_lab-document_store) | Embedding-based semantic document search via fastembed | [robot_lab-document_store README](https://github.com/MadBomber/robot_lab-document_store) |
@@ -1,219 +0,0 @@
1
- # Knowledge & Retrieval
2
-
3
- Facilities for searching and retrieving knowledge from a robot's history and from external documents:
4
-
5
- - **Chat History Search** — semantic search over accumulated conversation turns
6
- - **Embedding-Based Document Store** — lightweight RAG: store arbitrary text, search by meaning
7
-
8
- ---
9
-
10
- ## Chat History Search
11
-
12
- ### The Problem
13
-
14
- Long-running robots accumulate many conversation turns. When you need to recall what was discussed earlier on a specific topic, re-sending the full history wastes tokens. `search_history` gives you a focused slice of the most relevant past messages without touching the LLM.
15
-
16
- ### robot.search_history
17
-
18
- ```ruby
19
- results = robot.search_history(query, limit: 5)
20
- ```
21
-
22
- Scores every message in the robot's conversation history against `query` using stemmed term-frequency cosine similarity (via the `classifier` gem). Returns up to `limit` `HistoryResult` objects sorted by score descending.
23
-
24
- > [!NOTE]
25
- > **Every** message in `@chat.messages` is scored — there is no role filter.
26
- > Results routinely include the `:system` prompt and raw `:tool` result payloads
27
- > (often JSON) alongside `:user` and `:assistant` turns. Filter by role yourself
28
- > if you only want the conversation:
29
- >
30
- > ```ruby
31
- > hits = robot.search_history(query, limit: 20)
32
- > .select { |r| %i[user assistant].include?(r.role) }
33
- > .first(3)
34
- > ```
35
-
36
- ```ruby
37
- results = robot.search_history("quarterly revenue", limit: 3)
38
-
39
- results.each do |r|
40
- puts "[#{r.role}] score=#{r.score.round(3)} idx=#{r.index}"
41
- puts " #{r.text}"
42
- end
43
- ```
44
-
45
- ### HistoryResult Fields
46
-
47
- | Field | Type | Description |
48
- |-------|------|-------------|
49
- | `text` | String | The message text |
50
- | `role` | Symbol | The message's role — `:user`, `:assistant`, `:system`, or `:tool` |
51
- | `score` | Float (0.0–1.0) | Cosine similarity with the query |
52
- | `index` | Integer | Position in `@chat.messages` |
53
-
54
- ### Typical Scores
55
-
56
- | Relationship | Typical Score |
57
- |---|---|
58
- | Direct answer to the query | 0.50 – 0.80 |
59
- | Same topic, different phrasing | 0.20 – 0.50 |
60
- | Unrelated | < 0.10 |
61
-
62
- ### Short Messages
63
-
64
- Messages shorter than 20 characters are skipped — they produce no meaningful term vector.
65
-
66
- ### Full Example
67
-
68
- ```ruby
69
- robot = RobotLab.build(name: "analyst", system_prompt: "You are a financial analyst.")
70
-
71
- # … after several robot.run() calls …
72
-
73
- hits = robot.search_history("customer acquisition cost")
74
- hits.each { |r| puts "#{r.role} (#{r.score.round(2)}): #{r.text}" }
75
- ```
76
-
77
- ### RAG Pattern — Retrieve Then Generate
78
-
79
- Use `search_history` to inject only the relevant past context into the next call:
80
-
81
- ```ruby
82
- hits = robot.search_history(user_query, limit: 3)
83
- context = hits.map(&:text).join("\n")
84
-
85
- robot.run("Recall context:\n#{context}\n\nNew question: #{user_query}")
86
- ```
87
-
88
- ### Optional Dependency
89
-
90
- `search_history` requires the `classifier` gem:
91
-
92
- ```ruby
93
- gem "classifier", "~> 2.3"
94
- ```
95
-
96
- Without it, calling `search_history` raises `RobotLab::DependencyError` with an install hint.
97
-
98
- ---
99
-
100
- ## Embedding-Based Document Store
101
-
102
- ### The Problem
103
-
104
- Sometimes the knowledge you need isn't in the conversation history — it's in a README, a product spec, a changelog. `store_document` / `search_documents` embed arbitrary text and retrieve the most relevant chunk at query time. Embeddings come from `fastembed` when it is installed, and from a built-in TF-IDF fallback when it is not (see [Embedding Model](#embedding-model)).
105
-
106
- ### memory.store_document / memory.search_documents
107
-
108
- ```ruby
109
- memory.store_document(:readme, File.read("README.md"))
110
- memory.store_document(:changelog, File.read("CHANGELOG.md"))
111
-
112
- hits = memory.search_documents("how to configure redis", limit: 3)
113
- hits.each { |h| puts "#{h[:key]} (#{h[:score].round(3)}): #{h[:text][0..80]}" }
114
- ```
115
-
116
- Each result hash contains:
117
-
118
- | Key | Type | Description |
119
- |-----|------|-------------|
120
- | `:key` | Symbol | The key the document was stored under |
121
- | `:text` | String | The full stored text |
122
- | `:score` | Float (0.0–1.0) | Cosine similarity with the query |
123
-
124
- ### Standalone DocumentStore
125
-
126
- The `Memory` methods delegate to `RobotLab::DocumentStore`, which can also be used directly:
127
-
128
- ```ruby
129
- store = RobotLab::DocumentStore.new
130
- store.store(:doc_a, "Ruby on Rails is a full-stack web framework.")
131
- store.store(:doc_b, "Postgres is an advanced relational database.")
132
-
133
- results = store.search("relational database SQL", limit: 2)
134
- puts results.first[:key] # => :doc_b
135
- ```
136
-
137
- Management methods:
138
-
139
- ```ruby
140
- store.size # => 2
141
- store.keys # => [:doc_a, :doc_b]
142
- store.empty? # => false
143
- store.delete(:doc_a)
144
- store.clear
145
- ```
146
-
147
- ### Embedding Model
148
-
149
- Default: `BAAI/bge-small-en-v1.5` (~23 MB, downloaded on first use, cached in `~/.cache/fastembed/`).
150
-
151
- Documents and queries are embedded asymmetrically: stored text goes through `Fastembed::TextEmbedding#passage_embed`, query text through `#query_embed`. RobotLab does **not** prepend any literal `"passage: "` / `"query: "` string of its own — it hands the raw text to the two methods and lets fastembed handle whatever instruction prefixing the model expects.
152
-
153
- Custom model:
154
-
155
- ```ruby
156
- store = RobotLab::DocumentStore.new(model_name: "BAAI/bge-base-en-v1.5")
157
- ```
158
-
159
- ### TF-IDF Fallback
160
-
161
- `DocumentStore` decides once, at load time, whether `fastembed` is available
162
- (`RobotLab::DocumentStore::FASTEMBED_AVAILABLE`). When it is **not**, the store
163
- still works — it silently falls back to a stemmed, stop-word-filtered,
164
- L2-normalised term-frequency embedder and compares those sparse vectors by
165
- cosine similarity. Nothing is downloaded and everything runs offline, which
166
- makes it convenient for development and CI.
167
-
168
- > [!WARNING]
169
- > The fallback is **lexical, not semantic**. It matches shared word stems only,
170
- > so a query and a document that mean the same thing in different words score
171
- > `0.0`. There is no error, no warning, and no change to the API — only
172
- > noticeably worse results. Check `RobotLab::DocumentStore::FASTEMBED_AVAILABLE`
173
- > if you need to know which path you are on, and note that `model_name:` is
174
- > ignored entirely when it is `false`.
175
-
176
- ### RAG Pattern
177
-
178
- ```ruby
179
- # 1. Index your knowledge base at startup
180
- memory.store_document(:readme, File.read("README.md"))
181
- memory.store_document(:changelog, File.read("CHANGELOG.md"))
182
- memory.store_document(:api_docs, File.read("docs/api.md"))
183
-
184
- # 2. At query time, retrieve the most relevant chunks
185
- hits = memory.search_documents(user_query, limit: 3)
186
- context = hits.map { |h| h[:text] }.join("\n\n")
187
-
188
- # 3. Pass context to your robot
189
- result = robot.run("Use the following context:\n#{context}\n\nQuestion: #{user_query}")
190
- ```
191
-
192
- ### Memory API Summary
193
-
194
- | Method | Description |
195
- |--------|-------------|
196
- | `memory.store_document(key, text)` | Embed and store a document |
197
- | `memory.search_documents(query, limit: 5)` | Search by semantic similarity |
198
- | `memory.document_keys` | List stored keys |
199
- | `memory.delete_document(key)` | Remove a document |
200
-
201
- ### Dependency
202
-
203
- The embedding-based document store requires the [`robot_lab-document_store`](https://github.com/MadBomber/robot_lab-document_store) extension gem. Add it to your Gemfile:
204
-
205
- ```ruby
206
- gem "robot_lab-document_store"
207
- ```
208
-
209
- The gem uses `fastembed` for ONNX-based embeddings when it is installed: the `BAAI/bge-small-en-v1.5` model (~23 MB) is downloaded on first use and cached in `~/.cache/fastembed/`. If `fastembed` cannot be loaded, `DocumentStore` still works via the lexical [TF-IDF fallback](#tf-idf-fallback).
210
-
211
- Without `robot_lab-document_store` itself loaded, calling `memory.store_document`, `memory.search_documents`, `memory.document_keys`, or `memory.delete_document` raises `RobotLab::DependencyError`.
212
-
213
- ---
214
-
215
- ## See Also
216
-
217
- - [Observability Guide](observability.md)
218
- - [examples/25_history_search.rb](https://github.com/MadBomber/robot_lab/blob/main/examples/25_history_search.rb) — Chat History Search
219
- - [examples/26_document_store.rb](https://github.com/MadBomber/robot_lab/blob/main/examples/26_document_store.rb) — Embedding-Based Document Store