Class: SwarmSDK::V3::Memory::ContextBuilder
- Inherits:
-
Object
- Object
- SwarmSDK::V3::Memory::ContextBuilder
- Defined in:
- lib/swarm_sdk/v3/memory/context_builder.rb
Overview
Assembles working context from memory tiers
Combines retrieved memory cards, recent turns (STM buffer), cluster summaries, active constraints, and an exploration sample into a coherent working context for the LLM.
Includes an “exploration sprinkle” — 1-2 low-exposure cards that are loosely relevant to the query. This prevents permanent forgetting of rarely-accessed memories by giving them occasional exposure.
## Associative Memory
When ‘associative_memory: true`, exploration cards are labeled under a distinct “YOU ALSO REMEMBER:” section, and a brief guidance is appended after the memory context encouraging the LLM to naturally bring up these tangential memories when the conversation allows — like a person who says “btw, how was Porto?” after discussing Portugal.
When ‘associative_memory: false` (default), exploration cards are formatted identically to retrieved cards. They still serve their anti-forgetting purpose (exposure bumping via `record_access!`), but the LLM is not encouraged to surface them conversationally.
Instance Method Summary collapse
-
#build(query:, recent_turns: [], system_prompt: nil, read_only: false) ⇒ Array<Hash>
Build working context for a query.
-
#initialize(retriever:, adapter:, retrieval_top_k: 15, embedder: nil, associative_memory: false) ⇒ ContextBuilder
constructor
A new instance of ContextBuilder.
Constructor Details
#initialize(retriever:, adapter:, retrieval_top_k: 15, embedder: nil, associative_memory: false) ⇒ ContextBuilder
Returns a new instance of ContextBuilder.
38 39 40 41 42 43 44 45 |
# File 'lib/swarm_sdk/v3/memory/context_builder.rb', line 38 def initialize(retriever:, adapter:, retrieval_top_k: 15, embedder: nil, associative_memory: false) @retriever = retriever @adapter = adapter @retrieval_top_k = retrieval_top_k @embedder = @associative_memory = associative_memory @config = Configuration.instance end |
Instance Method Details
#build(query:, recent_turns: [], system_prompt: nil, read_only: false) ⇒ Array<Hash>
Build working context for a query
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/swarm_sdk/v3/memory/context_builder.rb', line 67 def build(query:, recent_turns: [], system_prompt: nil, read_only: false) DebugLog.log("context_builder", "build: query=#{query[0..60].inspect}") retrieved_cards = DebugLog.time("context_builder", "retriever.search(top_k=#{@retrieval_top_k})") do @retriever.search(query, top_k: @retrieval_top_k) end exploration_cards = DebugLog.time("context_builder", "find_exploration_cards") do find_exploration_cards(query, retrieved_cards) end all_cards = retrieved_cards + exploration_cards relevant_clusters = find_relevant_clusters(all_cards) active_constraints = find_active_constraints(all_cards) all_cards = DebugLog.time("context_builder", "deduplicate_cards(#{all_cards.size})") do deduplicate_cards(all_cards) end DebugLog.log("context_builder", "retrieved=#{retrieved_cards.size} exploration=#{exploration_cards.size} deduped=#{all_cards.size} clusters=#{relevant_clusters.size} constraints=#{active_constraints.size}") # Record access on all cards included in context (skip in read-only mode) unless read_only all_cards.each do |card| card.record_access! @adapter.write_card(card) end end = [] # Build memory context from all tiers memory_context = format_memory_context( retrieved_cards, exploration_cards, relevant_clusters, active_constraints ) # System prompt with memory context if system_prompt system_content = system_prompt system_content = "#{system_content}\n\n#{memory_context}" unless memory_context.empty? << { role: "system", content: system_content } elsif !memory_context.empty? << { role: "system", content: memory_context } end # Recent turns (STM buffer) .concat(recent_turns) end |