swarm_sdk 2.7.14 → 3.0.0.alpha2

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 (185) hide show
  1. checksums.yaml +4 -4
  2. data/lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb +16 -0
  3. data/lib/swarm_sdk/ruby_llm_patches/init.rb +4 -1
  4. data/lib/swarm_sdk/v3/agent.rb +1165 -0
  5. data/lib/swarm_sdk/v3/agent_builder.rb +533 -0
  6. data/lib/swarm_sdk/v3/agent_definition.rb +330 -0
  7. data/lib/swarm_sdk/v3/configuration.rb +490 -0
  8. data/lib/swarm_sdk/v3/debug_log.rb +86 -0
  9. data/lib/swarm_sdk/v3/event_stream.rb +130 -0
  10. data/lib/swarm_sdk/v3/hooks/context.rb +112 -0
  11. data/lib/swarm_sdk/v3/hooks/result.rb +115 -0
  12. data/lib/swarm_sdk/v3/hooks/runner.rb +128 -0
  13. data/lib/swarm_sdk/v3/mcp/connector.rb +183 -0
  14. data/lib/swarm_sdk/v3/mcp/mcp_error.rb +15 -0
  15. data/lib/swarm_sdk/v3/mcp/server_definition.rb +125 -0
  16. data/lib/swarm_sdk/v3/mcp/ssl_http_transport.rb +103 -0
  17. data/lib/swarm_sdk/v3/mcp/stdio_transport.rb +135 -0
  18. data/lib/swarm_sdk/v3/mcp/tool_proxy.rb +53 -0
  19. data/lib/swarm_sdk/v3/memory/adapters/base.rb +297 -0
  20. data/lib/swarm_sdk/v3/memory/adapters/faiss_support.rb +194 -0
  21. data/lib/swarm_sdk/v3/memory/adapters/filesystem_adapter.rb +212 -0
  22. data/lib/swarm_sdk/v3/memory/adapters/sqlite_adapter.rb +507 -0
  23. data/lib/swarm_sdk/v3/memory/adapters/vector_utils.rb +88 -0
  24. data/lib/swarm_sdk/v3/memory/card.rb +206 -0
  25. data/lib/swarm_sdk/v3/memory/cluster.rb +146 -0
  26. data/lib/swarm_sdk/v3/memory/compressor.rb +496 -0
  27. data/lib/swarm_sdk/v3/memory/consolidator.rb +427 -0
  28. data/lib/swarm_sdk/v3/memory/context_builder.rb +339 -0
  29. data/lib/swarm_sdk/v3/memory/edge.rb +105 -0
  30. data/lib/swarm_sdk/v3/memory/embedder.rb +185 -0
  31. data/lib/swarm_sdk/v3/memory/exposure_tracker.rb +104 -0
  32. data/lib/swarm_sdk/v3/memory/ingestion_pipeline.rb +394 -0
  33. data/lib/swarm_sdk/v3/memory/retriever.rb +289 -0
  34. data/lib/swarm_sdk/v3/memory/store.rb +489 -0
  35. data/lib/swarm_sdk/v3/skills/loader.rb +147 -0
  36. data/lib/swarm_sdk/v3/skills/manifest.rb +45 -0
  37. data/lib/swarm_sdk/v3/sub_task_agent.rb +248 -0
  38. data/lib/swarm_sdk/v3/tools/base.rb +80 -0
  39. data/lib/swarm_sdk/v3/tools/bash.rb +174 -0
  40. data/lib/swarm_sdk/v3/tools/clock.rb +32 -0
  41. data/lib/swarm_sdk/v3/tools/document_converters/base.rb +84 -0
  42. data/lib/swarm_sdk/v3/tools/document_converters/docx_converter.rb +120 -0
  43. data/lib/swarm_sdk/v3/tools/document_converters/pdf_converter.rb +111 -0
  44. data/lib/swarm_sdk/v3/tools/document_converters/xlsx_converter.rb +128 -0
  45. data/lib/swarm_sdk/v3/tools/edit.rb +111 -0
  46. data/lib/swarm_sdk/v3/tools/glob.rb +96 -0
  47. data/lib/swarm_sdk/v3/tools/grep.rb +200 -0
  48. data/lib/swarm_sdk/v3/tools/message_teammate.rb +15 -0
  49. data/lib/swarm_sdk/v3/tools/message_user.rb +15 -0
  50. data/lib/swarm_sdk/v3/tools/read.rb +213 -0
  51. data/lib/swarm_sdk/v3/tools/read_tracker.rb +40 -0
  52. data/lib/swarm_sdk/v3/tools/registry.rb +208 -0
  53. data/lib/swarm_sdk/v3/tools/sub_task.rb +183 -0
  54. data/lib/swarm_sdk/v3/tools/think.rb +88 -0
  55. data/lib/swarm_sdk/v3/tools/write.rb +87 -0
  56. data/lib/swarm_sdk/v3.rb +145 -0
  57. metadata +88 -149
  58. data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -175
  59. data/lib/swarm_sdk/agent/builder.rb +0 -705
  60. data/lib/swarm_sdk/agent/chat.rb +0 -1438
  61. data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -375
  62. data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +0 -204
  63. data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +0 -480
  64. data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +0 -85
  65. data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -290
  66. data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +0 -116
  67. data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +0 -83
  68. data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +0 -134
  69. data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
  70. data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -146
  71. data/lib/swarm_sdk/agent/context.rb +0 -115
  72. data/lib/swarm_sdk/agent/context_manager.rb +0 -315
  73. data/lib/swarm_sdk/agent/definition.rb +0 -588
  74. data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -226
  75. data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -173
  76. data/lib/swarm_sdk/agent/tool_registry.rb +0 -189
  77. data/lib/swarm_sdk/agent_registry.rb +0 -146
  78. data/lib/swarm_sdk/builders/base_builder.rb +0 -558
  79. data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
  80. data/lib/swarm_sdk/concerns/cleanupable.rb +0 -42
  81. data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
  82. data/lib/swarm_sdk/concerns/validatable.rb +0 -55
  83. data/lib/swarm_sdk/config.rb +0 -368
  84. data/lib/swarm_sdk/configuration/parser.rb +0 -397
  85. data/lib/swarm_sdk/configuration/translator.rb +0 -285
  86. data/lib/swarm_sdk/configuration.rb +0 -165
  87. data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
  88. data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -102
  89. data/lib/swarm_sdk/context_compactor.rb +0 -335
  90. data/lib/swarm_sdk/context_management/builder.rb +0 -128
  91. data/lib/swarm_sdk/context_management/context.rb +0 -328
  92. data/lib/swarm_sdk/custom_tool_registry.rb +0 -226
  93. data/lib/swarm_sdk/defaults.rb +0 -251
  94. data/lib/swarm_sdk/events_to_messages.rb +0 -199
  95. data/lib/swarm_sdk/hooks/adapter.rb +0 -359
  96. data/lib/swarm_sdk/hooks/context.rb +0 -197
  97. data/lib/swarm_sdk/hooks/definition.rb +0 -80
  98. data/lib/swarm_sdk/hooks/error.rb +0 -29
  99. data/lib/swarm_sdk/hooks/executor.rb +0 -146
  100. data/lib/swarm_sdk/hooks/registry.rb +0 -147
  101. data/lib/swarm_sdk/hooks/result.rb +0 -150
  102. data/lib/swarm_sdk/hooks/shell_executor.rb +0 -256
  103. data/lib/swarm_sdk/hooks/tool_call.rb +0 -35
  104. data/lib/swarm_sdk/hooks/tool_result.rb +0 -62
  105. data/lib/swarm_sdk/log_collector.rb +0 -227
  106. data/lib/swarm_sdk/log_stream.rb +0 -127
  107. data/lib/swarm_sdk/markdown_parser.rb +0 -75
  108. data/lib/swarm_sdk/model_aliases.json +0 -8
  109. data/lib/swarm_sdk/models.json +0 -44002
  110. data/lib/swarm_sdk/models.rb +0 -161
  111. data/lib/swarm_sdk/node_context.rb +0 -245
  112. data/lib/swarm_sdk/observer/builder.rb +0 -81
  113. data/lib/swarm_sdk/observer/config.rb +0 -45
  114. data/lib/swarm_sdk/observer/manager.rb +0 -248
  115. data/lib/swarm_sdk/patterns/agent_observer.rb +0 -160
  116. data/lib/swarm_sdk/permissions/config.rb +0 -239
  117. data/lib/swarm_sdk/permissions/error_formatter.rb +0 -121
  118. data/lib/swarm_sdk/permissions/path_matcher.rb +0 -35
  119. data/lib/swarm_sdk/permissions/validator.rb +0 -173
  120. data/lib/swarm_sdk/permissions_builder.rb +0 -122
  121. data/lib/swarm_sdk/plugin.rb +0 -309
  122. data/lib/swarm_sdk/plugin_registry.rb +0 -101
  123. data/lib/swarm_sdk/proc_helpers.rb +0 -53
  124. data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -119
  125. data/lib/swarm_sdk/restore_result.rb +0 -65
  126. data/lib/swarm_sdk/result.rb +0 -241
  127. data/lib/swarm_sdk/snapshot.rb +0 -156
  128. data/lib/swarm_sdk/snapshot_from_events.rb +0 -397
  129. data/lib/swarm_sdk/state_restorer.rb +0 -476
  130. data/lib/swarm_sdk/state_snapshot.rb +0 -334
  131. data/lib/swarm_sdk/swarm/agent_initializer.rb +0 -648
  132. data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -204
  133. data/lib/swarm_sdk/swarm/builder.rb +0 -256
  134. data/lib/swarm_sdk/swarm/executor.rb +0 -446
  135. data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -162
  136. data/lib/swarm_sdk/swarm/lazy_delegate_chat.rb +0 -372
  137. data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -361
  138. data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -290
  139. data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
  140. data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -392
  141. data/lib/swarm_sdk/swarm.rb +0 -973
  142. data/lib/swarm_sdk/swarm_loader.rb +0 -145
  143. data/lib/swarm_sdk/swarm_registry.rb +0 -136
  144. data/lib/swarm_sdk/tools/base.rb +0 -63
  145. data/lib/swarm_sdk/tools/bash.rb +0 -280
  146. data/lib/swarm_sdk/tools/clock.rb +0 -46
  147. data/lib/swarm_sdk/tools/delegate.rb +0 -389
  148. data/lib/swarm_sdk/tools/document_converters/base_converter.rb +0 -83
  149. data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +0 -99
  150. data/lib/swarm_sdk/tools/document_converters/html_converter.rb +0 -101
  151. data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +0 -78
  152. data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +0 -194
  153. data/lib/swarm_sdk/tools/edit.rb +0 -145
  154. data/lib/swarm_sdk/tools/glob.rb +0 -166
  155. data/lib/swarm_sdk/tools/grep.rb +0 -235
  156. data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +0 -43
  157. data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +0 -167
  158. data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
  159. data/lib/swarm_sdk/tools/mcp_tool_stub.rb +0 -198
  160. data/lib/swarm_sdk/tools/multi_edit.rb +0 -236
  161. data/lib/swarm_sdk/tools/path_resolver.rb +0 -92
  162. data/lib/swarm_sdk/tools/read.rb +0 -261
  163. data/lib/swarm_sdk/tools/registry.rb +0 -205
  164. data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +0 -117
  165. data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +0 -97
  166. data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +0 -108
  167. data/lib/swarm_sdk/tools/stores/read_tracker.rb +0 -96
  168. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +0 -273
  169. data/lib/swarm_sdk/tools/stores/storage.rb +0 -142
  170. data/lib/swarm_sdk/tools/stores/todo_manager.rb +0 -65
  171. data/lib/swarm_sdk/tools/think.rb +0 -100
  172. data/lib/swarm_sdk/tools/todo_write.rb +0 -237
  173. data/lib/swarm_sdk/tools/web_fetch.rb +0 -264
  174. data/lib/swarm_sdk/tools/write.rb +0 -112
  175. data/lib/swarm_sdk/transcript_builder.rb +0 -278
  176. data/lib/swarm_sdk/utils.rb +0 -68
  177. data/lib/swarm_sdk/validation_result.rb +0 -33
  178. data/lib/swarm_sdk/version.rb +0 -5
  179. data/lib/swarm_sdk/workflow/agent_config.rb +0 -95
  180. data/lib/swarm_sdk/workflow/builder.rb +0 -227
  181. data/lib/swarm_sdk/workflow/executor.rb +0 -497
  182. data/lib/swarm_sdk/workflow/node_builder.rb +0 -593
  183. data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -250
  184. data/lib/swarm_sdk/workflow.rb +0 -589
  185. data/lib/swarm_sdk.rb +0 -721
@@ -0,0 +1,289 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SwarmSDK
4
+ module V3
5
+ module Memory
6
+ # Hybrid search retriever combining semantic and keyword search
7
+ #
8
+ # Uses reciprocal rank fusion (RRF) to combine results from:
9
+ # 1. Semantic search via FAISS vector similarity
10
+ # 2. Keyword search via text matching
11
+ # 3. Graph expansion via 1-hop edge traversal
12
+ #
13
+ # @example
14
+ # retriever = Retriever.new(adapter: adapter, embedder: embedder)
15
+ # results = retriever.search("JWT authentication", top_k: 10)
16
+ class Retriever
17
+ # @param adapter [Adapters::Base] Storage adapter
18
+ # @param embedder [Embedder] Text embedder
19
+ # @param semantic_weight [Float] Weight for semantic results (0.0-1.0)
20
+ # @param keyword_weight [Float] Weight for keyword results (0.0-1.0)
21
+ def initialize(adapter:, embedder:, semantic_weight: 0.5, keyword_weight: 0.5)
22
+ @adapter = adapter
23
+ @embedder = embedder
24
+ @semantic_weight = semantic_weight
25
+ @keyword_weight = keyword_weight
26
+ @config = Configuration.instance
27
+ end
28
+
29
+ # Search for relevant memory cards
30
+ #
31
+ # @param query [String] Search query
32
+ # @param top_k [Integer] Number of results to return
33
+ # @return [Array<Card>] Ranked cards
34
+ #
35
+ # @example
36
+ # cards = retriever.search("How does auth work?", top_k: 10)
37
+ def search(query, top_k: 15)
38
+ DebugLog.log("retriever", "search: query=#{query[0..60].inspect}, top_k=#{top_k}")
39
+
40
+ semantic_results = DebugLog.time("retriever", "semantic_search(#{top_k * 2})") do
41
+ semantic_search(query, top_k: top_k * 2)
42
+ end
43
+
44
+ keyword_results = DebugLog.time("retriever", "keyword_search(#{top_k * 2})") do
45
+ keyword_search(query, top_k: top_k * 2)
46
+ end
47
+
48
+ DebugLog.log("retriever", "semantic=#{semantic_results.size} keyword=#{keyword_results.size}")
49
+
50
+ # Reciprocal rank fusion
51
+ fused = DebugLog.time("retriever", "rrf") do
52
+ reciprocal_rank_fusion(semantic_results, keyword_results)
53
+ end
54
+
55
+ # Graph expansion: add 1-hop neighbors of top results
56
+ expanded = DebugLog.time("retriever", "graph_expand") do
57
+ graph_expand(fused.take(top_k), top_k: top_k)
58
+ end
59
+
60
+ DebugLog.log("retriever", "fused=#{fused.size} expanded=#{expanded.size} returning=#{[expanded.size, top_k].min}")
61
+
62
+ # Return unique cards, limited to top_k
63
+ expanded.take(top_k)
64
+ end
65
+
66
+ private
67
+
68
+ # Semantic search via vector similarity
69
+ #
70
+ # @param query [String] Search query
71
+ # @param top_k [Integer] Number of results
72
+ # @return [Array<String>] Ranked card IDs
73
+ def semantic_search(query, top_k:)
74
+ embedding = @embedder.embed(query)
75
+ results = @adapter.vector_search(embedding, top_k: top_k, threshold: 0.1)
76
+ results.sort_by { |r| -r[:similarity] }.map { |r| r[:id] }
77
+ end
78
+
79
+ # BM25 keyword search
80
+ #
81
+ # Implements Okapi BM25 scoring for keyword-based retrieval.
82
+ # Catches exact names, IDs, error messages, and other literal matches
83
+ # that semantic search might miss.
84
+ #
85
+ # @param query [String] Search query
86
+ # @param top_k [Integer] Number of results
87
+ # @return [Array<String>] Ranked card IDs
88
+ def keyword_search(query, top_k:)
89
+ terms = tokenize(query)
90
+ return [] if terms.empty?
91
+
92
+ cards = @adapter.list_cards
93
+ return [] if cards.empty?
94
+
95
+ # Precompute corpus statistics for BM25
96
+ avg_dl = cards.sum { |c| tokenize(c.text).size }.to_f / cards.size
97
+ doc_freq = compute_document_frequencies(terms, cards)
98
+ n = cards.size
99
+
100
+ scored = cards.filter_map do |card|
101
+ card_terms = tokenize(card.text)
102
+ dl = card_terms.size
103
+
104
+ # BM25 score
105
+ bm25 = terms.sum do |term|
106
+ tf = card_terms.count(term)
107
+ next 0.0 if tf == 0
108
+
109
+ df = doc_freq[term] || 0
110
+ idf = Math.log((n - df + 0.5) / (df + 0.5) + 1.0)
111
+ numerator = tf * (@config.bm25_k1 + 1)
112
+ denominator = tf + @config.bm25_k1 * (1 - @config.bm25_b + @config.bm25_b * dl / avg_dl)
113
+ idf * numerator / denominator
114
+ end
115
+
116
+ # Boost for entity matches (exact term in entities list)
117
+ entity_boost = card.entities.count do |entity|
118
+ terms.any? { |t| entity.downcase.include?(t) }
119
+ end
120
+ bm25 += entity_boost * @config.bm25_entity_boost
121
+
122
+ { id: card.id, score: bm25 } if bm25 > 0.0
123
+ end
124
+
125
+ scored.sort_by { |s| -s[:score] }.take(top_k).map { |s| s[:id] }
126
+ end
127
+
128
+ # Combine ranked lists using reciprocal rank fusion
129
+ #
130
+ # @param semantic_ids [Array<String>] Semantic search results
131
+ # @param keyword_ids [Array<String>] Keyword search results
132
+ # @return [Array<Card>] Fused and ranked cards
133
+ def reciprocal_rank_fusion(semantic_ids, keyword_ids)
134
+ scores = Hash.new(0.0)
135
+
136
+ semantic_ids.each_with_index do |id, rank|
137
+ scores[id] += @semantic_weight * (1.0 / (@config.rrf_k + rank + 1))
138
+ end
139
+
140
+ keyword_ids.each_with_index do |id, rank|
141
+ scores[id] += @keyword_weight * (1.0 / (@config.rrf_k + rank + 1))
142
+ end
143
+
144
+ ranked_ids = scores.sort_by { |_, score| -score }.map(&:first)
145
+ ranked_ids.filter_map { |id| @adapter.read_card(id) }
146
+ end
147
+
148
+ # Expand results with 1-hop graph neighbors
149
+ #
150
+ # Limits to `config.max_neighbors_per_seed` neighbors per seed card
151
+ # to prevent any single highly-connected card from dominating
152
+ # the expanded results.
153
+ #
154
+ # @param cards [Array<Card>] Initial result cards
155
+ # @param top_k [Integer] Maximum total results
156
+ # @return [Array<Card>] Expanded results
157
+ def graph_expand(cards, top_k:)
158
+ seen_ids = Set.new(cards.map(&:id))
159
+ expanded = cards.dup
160
+
161
+ cards.each do |card|
162
+ break if expanded.size >= top_k
163
+
164
+ edges = @adapter.edges_for(card.id)
165
+ neighbors_added = 0
166
+
167
+ # Sort edges by weight descending to prefer strongest connections
168
+ edges.sort_by { |e| -e.weight }.each do |edge|
169
+ break if expanded.size >= top_k
170
+ break if neighbors_added >= @config.max_neighbors_per_seed
171
+
172
+ neighbor_id = edge.from_id == card.id ? edge.to_id : edge.from_id
173
+ next if seen_ids.include?(neighbor_id)
174
+
175
+ neighbor = @adapter.read_card(neighbor_id)
176
+ next unless neighbor
177
+
178
+ seen_ids.add(neighbor_id)
179
+ expanded << neighbor
180
+ neighbors_added += 1
181
+ end
182
+ end
183
+
184
+ expanded
185
+ end
186
+
187
+ # Tokenize text into lowercase terms, filtering stopwords and short tokens
188
+ #
189
+ # @param text [String] Text to tokenize
190
+ # @return [Array<String>] Lowercase tokens
191
+ def tokenize(text)
192
+ text.downcase
193
+ .gsub(/[^a-z0-9\s_-]/, " ")
194
+ .split(/\s+/)
195
+ .reject { |t| t.length < 2 || STOPWORDS.include?(t) }
196
+ end
197
+
198
+ # Compute document frequency for each query term
199
+ #
200
+ # @param terms [Array<String>] Query terms
201
+ # @param cards [Array<Card>] All cards in the corpus
202
+ # @return [Hash<String, Integer>] Term → document count
203
+ def compute_document_frequencies(terms, cards)
204
+ freq = Hash.new(0)
205
+ cards.each do |card|
206
+ card_terms = tokenize(card.text).to_set
207
+ terms.each { |term| freq[term] += 1 if card_terms.include?(term) }
208
+ end
209
+ freq
210
+ end
211
+
212
+ # Common English stopwords to filter from BM25 scoring
213
+ STOPWORDS = Set.new([
214
+ "the",
215
+ "a",
216
+ "an",
217
+ "is",
218
+ "are",
219
+ "was",
220
+ "were",
221
+ "be",
222
+ "been",
223
+ "being",
224
+ "have",
225
+ "has",
226
+ "had",
227
+ "do",
228
+ "does",
229
+ "did",
230
+ "will",
231
+ "would",
232
+ "shall",
233
+ "should",
234
+ "may",
235
+ "might",
236
+ "can",
237
+ "could",
238
+ "of",
239
+ "in",
240
+ "to",
241
+ "for",
242
+ "on",
243
+ "with",
244
+ "at",
245
+ "by",
246
+ "from",
247
+ "as",
248
+ "into",
249
+ "through",
250
+ "about",
251
+ "between",
252
+ "after",
253
+ "before",
254
+ "above",
255
+ "below",
256
+ "up",
257
+ "down",
258
+ "out",
259
+ "off",
260
+ "over",
261
+ "under",
262
+ "again",
263
+ "this",
264
+ "that",
265
+ "these",
266
+ "those",
267
+ "it",
268
+ "its",
269
+ "he",
270
+ "she",
271
+ "they",
272
+ "them",
273
+ "and",
274
+ "but",
275
+ "or",
276
+ "nor",
277
+ "not",
278
+ "no",
279
+ "so",
280
+ "if",
281
+ "then",
282
+ "than",
283
+ "too",
284
+ "very",
285
+ ]).freeze
286
+ end
287
+ end
288
+ end
289
+ end