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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +1 -1
- data/lib/robot_lab/mcp/transports/streamable_http.rb +1 -1
- data/lib/robot_lab/version.rb +1 -1
- metadata +3 -253
- data/.architecture/AGENTS.md +0 -32
- data/.architecture/config.yml +0 -8
- data/.architecture/members.yml +0 -60
- data/.architecture/reviews/feature-free-will.md +0 -490
- data/.architecture/reviews/overall-codebase.md +0 -427
- data/.claude/settings.local.json +0 -57
- data/.codex/config.toml +0 -2
- data/.envrc +0 -6
- data/.github/workflows/deploy-github-pages.yml +0 -52
- data/.irbrc +0 -6
- data/.loki +0 -65
- data/.quality/reek_baseline.txt +0 -43
- data/.rubocop.yml +0 -10
- data/Archspec.rb +0 -44
- data/CLAUDE.md +0 -141
- data/COMMITS.md +0 -196
- data/Rakefile +0 -193
- data/_typos.toml +0 -21
- data/agent2agent_review.md +0 -192
- data/agentf_improvements.md +0 -253
- data/agents.md +0 -14
- data/docs/api/core/index.md +0 -147
- data/docs/api/core/memory.md +0 -578
- data/docs/api/core/network.md +0 -553
- data/docs/api/core/result.md +0 -211
- data/docs/api/core/robot.md +0 -1667
- data/docs/api/core/state.md +0 -145
- data/docs/api/core/tool.md +0 -520
- data/docs/api/errors.md +0 -323
- data/docs/api/hooks.md +0 -469
- data/docs/api/index.md +0 -137
- data/docs/api/mcp/client.md +0 -387
- data/docs/api/mcp/index.md +0 -267
- data/docs/api/mcp/server.md +0 -252
- data/docs/api/mcp/transports.md +0 -339
- data/docs/api/messages/index.md +0 -126
- data/docs/api/messages/text-message.md +0 -170
- data/docs/api/messages/tool-call-message.md +0 -206
- data/docs/api/messages/tool-result-message.md +0 -242
- data/docs/api/messages/user-message.md +0 -232
- data/docs/api/skills.md +0 -423
- data/docs/api/streaming/context.md +0 -280
- data/docs/api/streaming/events.md +0 -185
- data/docs/api/streaming/index.md +0 -156
- data/docs/api/support.md +0 -846
- data/docs/architecture/core-concepts.md +0 -575
- data/docs/architecture/index.md +0 -252
- data/docs/architecture/message-flow.md +0 -366
- data/docs/architecture/network-orchestration.md +0 -478
- data/docs/architecture/robot-execution.md +0 -396
- data/docs/architecture/state-management.md +0 -410
- data/docs/assets/css/custom.css +0 -56
- data/docs/assets/images/robot_lab.jpg +0 -0
- data/docs/concepts.md +0 -641
- data/docs/examples/basic-chat.md +0 -258
- data/docs/examples/index.md +0 -425
- data/docs/examples/mcp-server.md +0 -403
- data/docs/examples/multi-robot-network.md +0 -476
- data/docs/examples/tool-usage.md +0 -468
- data/docs/getting-started/configuration.md +0 -645
- data/docs/getting-started/index.md +0 -56
- data/docs/getting-started/installation.md +0 -197
- data/docs/getting-started/quick-start.md +0 -293
- data/docs/guides/building-robots.md +0 -1187
- data/docs/guides/creating-networks.md +0 -736
- data/docs/guides/hooks.md +0 -1206
- data/docs/guides/index.md +0 -78
- data/docs/guides/knowledge.md +0 -219
- data/docs/guides/mcp-integration.md +0 -740
- data/docs/guides/memory.md +0 -458
- data/docs/guides/observability.md +0 -733
- data/docs/guides/streaming.md +0 -323
- data/docs/guides/using-tools.md +0 -780
- data/docs/index.md +0 -280
- data/docs/superpowers/plans/2026-05-06-agentskills.md +0 -1303
- data/docs/superpowers/specs/2026-05-06-agentskills-design.md +0 -247
- data/examples/.envrc +0 -3
- data/examples/01_simple_robot.rb +0 -31
- data/examples/02_tools.rb +0 -109
- data/examples/03_network.rb +0 -118
- data/examples/04_mcp.rb +0 -217
- data/examples/05_streaming.rb +0 -137
- data/examples/06_prompt_templates.rb +0 -325
- data/examples/07_network_memory.rb +0 -313
- data/examples/08_llm_config.rb +0 -162
- data/examples/09_chaining.rb +0 -251
- data/examples/10_memory.rb +0 -315
- data/examples/11_network_introspection.rb +0 -239
- data/examples/12_message_bus.rb +0 -67
- data/examples/13_spawn.rb +0 -85
- data/examples/14_rusty_circuit/.envrc +0 -1
- data/examples/14_rusty_circuit/.gitignore +0 -1
- data/examples/14_rusty_circuit/README.md +0 -1
- data/examples/14_rusty_circuit/comic.rb +0 -149
- data/examples/14_rusty_circuit/display.rb +0 -217
- data/examples/14_rusty_circuit/heckler.rb +0 -65
- data/examples/14_rusty_circuit/open_mic.rb +0 -132
- data/examples/14_rusty_circuit/prompts/open_mic_comic.md +0 -20
- data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +0 -23
- data/examples/14_rusty_circuit/prompts/open_mic_scout.md +0 -20
- data/examples/14_rusty_circuit/scout.rb +0 -165
- data/examples/14_rusty_circuit/show.log +0 -234
- data/examples/15_memory_network_and_bus/.envrc +0 -1
- data/examples/15_memory_network_and_bus/README.md +0 -66
- data/examples/15_memory_network_and_bus/editor_in_chief.rb +0 -24
- data/examples/15_memory_network_and_bus/editorial_pipeline.rb +0 -213
- data/examples/15_memory_network_and_bus/linux_writer.rb +0 -80
- data/examples/15_memory_network_and_bus/os_editor.rb +0 -48
- data/examples/15_memory_network_and_bus/os_writer.rb +0 -49
- data/examples/15_memory_network_and_bus/output/combined_article.md +0 -11
- data/examples/15_memory_network_and_bus/output/final_article.md +0 -8
- data/examples/15_memory_network_and_bus/output/linux_draft.md +0 -7
- data/examples/15_memory_network_and_bus/output/mac_draft.md +0 -7
- data/examples/15_memory_network_and_bus/output/memory.json +0 -13
- data/examples/15_memory_network_and_bus/output/revision_1.md +0 -29
- data/examples/15_memory_network_and_bus/output/revision_2.md +0 -50
- data/examples/15_memory_network_and_bus/output/revision_3.md +0 -8
- data/examples/15_memory_network_and_bus/output/windows_draft.md +0 -7
- data/examples/15_memory_network_and_bus/prompts/os_advocate.md +0 -13
- data/examples/15_memory_network_and_bus/prompts/os_chief.md +0 -13
- data/examples/15_memory_network_and_bus/prompts/os_editor.md +0 -13
- data/examples/16_writers_room/.envrc +0 -1
- data/examples/16_writers_room/display.rb +0 -158
- data/examples/16_writers_room/output/.gitignore +0 -4
- data/examples/16_writers_room/output/README.md +0 -69
- data/examples/16_writers_room/output/opus_001.md +0 -263
- data/examples/16_writers_room/output/opus_001_notes.log +0 -470
- data/examples/16_writers_room/output/opus_002.md +0 -245
- data/examples/16_writers_room/output/opus_002_notes.log +0 -546
- data/examples/16_writers_room/output/opus_002_screenplay.md +0 -7989
- data/examples/16_writers_room/output/opus_002_screenplay_notes.md +0 -993
- data/examples/16_writers_room/prompts/screenplay_writer.md +0 -66
- data/examples/16_writers_room/prompts/writer.md +0 -37
- data/examples/16_writers_room/room.rb +0 -186
- data/examples/16_writers_room/tools.rb +0 -173
- data/examples/16_writers_room/writer.rb +0 -121
- data/examples/16_writers_room/writers_room.rb +0 -256
- data/examples/17_skills.rb +0 -234
- data/examples/18_rails/.envrc +0 -3
- data/examples/18_rails/.gitignore +0 -5
- data/examples/18_rails/Gemfile +0 -11
- data/examples/18_rails/README.md +0 -67
- data/examples/18_rails/Rakefile +0 -4
- data/examples/18_rails/app/controllers/application_controller.rb +0 -4
- data/examples/18_rails/app/controllers/chat_controller.rb +0 -50
- data/examples/18_rails/app/jobs/application_job.rb +0 -4
- data/examples/18_rails/app/jobs/robot_run_job.rb +0 -25
- data/examples/18_rails/app/models/application_record.rb +0 -5
- data/examples/18_rails/app/models/robot_lab_result.rb +0 -36
- data/examples/18_rails/app/models/robot_lab_thread.rb +0 -23
- data/examples/18_rails/app/robots/chat_robot.rb +0 -25
- data/examples/18_rails/app/tools/time_tool.rb +0 -9
- data/examples/18_rails/app/views/chat/_user_message.html.erb +0 -1
- data/examples/18_rails/app/views/chat/index.html.erb +0 -67
- data/examples/18_rails/app/views/layouts/application.html.erb +0 -49
- data/examples/18_rails/bin/dev +0 -7
- data/examples/18_rails/bin/rails +0 -6
- data/examples/18_rails/bin/setup +0 -15
- data/examples/18_rails/config/application.rb +0 -33
- data/examples/18_rails/config/cable.yml +0 -2
- data/examples/18_rails/config/database.yml +0 -5
- data/examples/18_rails/config/environment.rb +0 -4
- data/examples/18_rails/config/initializers/robot_lab.rb +0 -11
- data/examples/18_rails/config/routes.rb +0 -6
- data/examples/18_rails/config.ru +0 -4
- data/examples/18_rails/db/migrate/001_create_robot_lab_tables.rb +0 -32
- data/examples/19_token_tracking.rb +0 -138
- data/examples/20_circuit_breaker.rb +0 -147
- data/examples/21_learning_loop.rb +0 -181
- data/examples/22_context_compression.rb +0 -172
- data/examples/23_convergence.rb +0 -133
- data/examples/24_structured_delegation.rb +0 -151
- data/examples/25_history_search/conversation.jsonl +0 -30
- data/examples/25_history_search.rb +0 -133
- data/examples/26_document_store/api_versioning_adr.md +0 -52
- data/examples/26_document_store/incident_postmortem.md +0 -46
- data/examples/26_document_store/postgres_runbook.md +0 -49
- data/examples/26_document_store/redis_caching_guide.md +0 -48
- data/examples/26_document_store/sidekiq_guide.md +0 -51
- data/examples/26_document_store.rb +0 -140
- data/examples/27_incident_response/README.md +0 -65
- data/examples/27_incident_response/incident_response.rb +0 -261
- data/examples/28_mcp_discovery.rb +0 -113
- data/examples/29_ractor_tools.rb +0 -240
- data/examples/30_ractor_network.rb +0 -252
- data/examples/31_launch_assessment.rb +0 -246
- data/examples/32_newsletter_reader.rb +0 -193
- data/examples/33_stock_generator.rb +0 -80
- data/examples/33_stock_predictor.rb +0 -327
- data/examples/34_agentskills.rb +0 -76
- data/examples/35_hooks.rb +0 -266
- data/examples/README.md +0 -550
- data/examples/common.rb +0 -180
- data/examples/prompts/assistant.md +0 -5
- data/examples/prompts/audit_trail.md +0 -8
- data/examples/prompts/billing.md +0 -10
- data/examples/prompts/classifier.md +0 -7
- data/examples/prompts/comedian.md +0 -6
- data/examples/prompts/comedy_critic.md +0 -10
- data/examples/prompts/configurable.md +0 -9
- data/examples/prompts/dispatcher.md +0 -12
- data/examples/prompts/entity_extractor.md +0 -14
- data/examples/prompts/escalation.md +0 -42
- data/examples/prompts/frontmatter_mcp_test.md +0 -9
- data/examples/prompts/frontmatter_named_test.md +0 -5
- data/examples/prompts/frontmatter_tools_test.md +0 -6
- data/examples/prompts/general.md +0 -7
- data/examples/prompts/github_assistant.md +0 -14
- data/examples/prompts/helper.md +0 -4
- data/examples/prompts/incident_responder.md +0 -18
- data/examples/prompts/keyword_extractor.md +0 -11
- data/examples/prompts/llm_config_demo.md +0 -20
- data/examples/prompts/order_support.md +0 -35
- data/examples/prompts/os_advocate.md +0 -13
- data/examples/prompts/os_chief.md +0 -13
- data/examples/prompts/os_editor.md +0 -13
- data/examples/prompts/parameterized_main_test.md +0 -6
- data/examples/prompts/pii_redactor.md +0 -7
- data/examples/prompts/product_support.md +0 -37
- data/examples/prompts/runbook_protocol.md +0 -12
- data/examples/prompts/sentiment_analyzer.md +0 -12
- data/examples/prompts/skill_a_test.md +0 -4
- data/examples/prompts/skill_b_test.md +0 -4
- data/examples/prompts/skill_config_test.md +0 -5
- data/examples/prompts/skill_cycle_a_test.md +0 -6
- data/examples/prompts/skill_cycle_b_test.md +0 -6
- data/examples/prompts/skill_description_test.md +0 -4
- data/examples/prompts/skill_leaf_test.md +0 -4
- data/examples/prompts/skill_nested_test.md +0 -6
- data/examples/prompts/skill_refs_main_test.md +0 -6
- data/examples/prompts/skill_self_ref_test.md +0 -6
- data/examples/prompts/skill_with_mcp_test.md +0 -9
- data/examples/prompts/skill_with_params_test.md +0 -6
- data/examples/prompts/skill_with_robot_name_test.md +0 -5
- data/examples/prompts/skill_with_tools_test.md +0 -6
- data/examples/prompts/sre_compliance.md +0 -10
- data/examples/prompts/structured_output.md +0 -7
- data/examples/prompts/synthesizer.md +0 -17
- data/examples/prompts/technical.md +0 -10
- data/examples/prompts/template_with_skills_test.md +0 -6
- data/examples/prompts/triage.md +0 -22
- data/examples/ruboruby.md +0 -423
- data/examples/run_all.rb +0 -60
- data/examples/xyzzy.rb +0 -97
- data/logfile +0 -8
- data/mkdocs.yml +0 -209
- data/robot_concurrency.md +0 -38
- data/simple_acp_review.md +0 -298
- data/temp.md +0 -6
- 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) |
|
data/docs/guides/knowledge.md
DELETED
|
@@ -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
|