claude_swarm 1.0.0 → 1.0.2

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 (267) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/release.md +1 -1
  3. data/.claude/hooks/lint-code-files.rb +65 -0
  4. data/.rubocop.yml +22 -2
  5. data/CHANGELOG.md +21 -1
  6. data/CLAUDE.md +1 -1
  7. data/CONTRIBUTING.md +69 -0
  8. data/README.md +27 -2
  9. data/Rakefile +71 -3
  10. data/analyze_coverage.rb +94 -0
  11. data/docs/v2/CHANGELOG.swarm_cli.md +43 -0
  12. data/docs/v2/CHANGELOG.swarm_memory.md +379 -0
  13. data/docs/v2/CHANGELOG.swarm_sdk.md +362 -0
  14. data/docs/v2/README.md +308 -0
  15. data/docs/v2/guides/claude-code-agents.md +262 -0
  16. data/docs/v2/guides/complete-tutorial.md +3088 -0
  17. data/docs/v2/guides/getting-started.md +1456 -0
  18. data/docs/v2/guides/memory-adapters.md +998 -0
  19. data/docs/v2/guides/plugins.md +816 -0
  20. data/docs/v2/guides/quick-start-cli.md +1745 -0
  21. data/docs/v2/guides/rails-integration.md +1902 -0
  22. data/docs/v2/guides/swarm-memory.md +599 -0
  23. data/docs/v2/reference/cli.md +729 -0
  24. data/docs/v2/reference/ruby-dsl.md +2154 -0
  25. data/docs/v2/reference/yaml.md +1835 -0
  26. data/docs-team-swarm.yml +2222 -0
  27. data/examples/learning-assistant/assistant.md +7 -0
  28. data/examples/learning-assistant/example-memories/concept-example.md +90 -0
  29. data/examples/learning-assistant/example-memories/experience-example.md +66 -0
  30. data/examples/learning-assistant/example-memories/fact-example.md +76 -0
  31. data/examples/learning-assistant/example-memories/memory-index.md +78 -0
  32. data/examples/learning-assistant/example-memories/skill-example.md +168 -0
  33. data/examples/learning-assistant/learning_assistant.rb +34 -0
  34. data/examples/learning-assistant/learning_assistant.yml +20 -0
  35. data/examples/v2/dsl/01_basic.rb +44 -0
  36. data/examples/v2/dsl/02_core_parameters.rb +59 -0
  37. data/examples/v2/dsl/03_capabilities.rb +71 -0
  38. data/examples/v2/dsl/04_llm_parameters.rb +56 -0
  39. data/examples/v2/dsl/05_advanced_flags.rb +73 -0
  40. data/examples/v2/dsl/06_permissions.rb +80 -0
  41. data/examples/v2/dsl/07_mcp_server.rb +62 -0
  42. data/examples/v2/dsl/08_swarm_hooks.rb +53 -0
  43. data/examples/v2/dsl/09_agent_hooks.rb +67 -0
  44. data/examples/v2/dsl/10_all_agents_hooks.rb +67 -0
  45. data/examples/v2/dsl/11_delegation.rb +60 -0
  46. data/examples/v2/dsl/12_complete_integration.rb +137 -0
  47. data/examples/v2/file_tools_swarm.yml +102 -0
  48. data/examples/v2/hooks/01_basic_hooks.rb +133 -0
  49. data/examples/v2/hooks/02_usage_tracking.rb +201 -0
  50. data/examples/v2/hooks/03_production_monitoring.rb +429 -0
  51. data/examples/v2/hooks/agent_stop_exit_0.yml +21 -0
  52. data/examples/v2/hooks/agent_stop_exit_1.yml +21 -0
  53. data/examples/v2/hooks/agent_stop_exit_2.yml +26 -0
  54. data/examples/v2/hooks/multiple_hooks_all_pass.yml +37 -0
  55. data/examples/v2/hooks/multiple_hooks_first_fails.yml +37 -0
  56. data/examples/v2/hooks/multiple_hooks_second_fails.yml +37 -0
  57. data/examples/v2/hooks/multiple_hooks_warnings.yml +37 -0
  58. data/examples/v2/hooks/post_tool_use_exit_0.yml +24 -0
  59. data/examples/v2/hooks/post_tool_use_exit_1.yml +24 -0
  60. data/examples/v2/hooks/post_tool_use_exit_2.yml +24 -0
  61. data/examples/v2/hooks/post_tool_use_multi_matcher_exit_0.yml +26 -0
  62. data/examples/v2/hooks/post_tool_use_multi_matcher_exit_1.yml +26 -0
  63. data/examples/v2/hooks/post_tool_use_multi_matcher_exit_2.yml +26 -0
  64. data/examples/v2/hooks/pre_tool_use_exit_0.yml +24 -0
  65. data/examples/v2/hooks/pre_tool_use_exit_1.yml +24 -0
  66. data/examples/v2/hooks/pre_tool_use_exit_2.yml +24 -0
  67. data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_0.yml +26 -0
  68. data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_1.yml +26 -0
  69. data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_2.yml +27 -0
  70. data/examples/v2/hooks/swarm_summary.sh +44 -0
  71. data/examples/v2/hooks/user_prompt_exit_0.yml +21 -0
  72. data/examples/v2/hooks/user_prompt_exit_1.yml +21 -0
  73. data/examples/v2/hooks/user_prompt_exit_2.yml +21 -0
  74. data/examples/v2/hooks/validate_bash.rb +59 -0
  75. data/examples/v2/multi_directory_permissions.yml +221 -0
  76. data/examples/v2/node_context_demo.rb +127 -0
  77. data/examples/v2/node_workflow.rb +173 -0
  78. data/examples/v2/path_resolution_demo.rb +216 -0
  79. data/examples/v2/simple-swarm-v2.rb +90 -0
  80. data/examples/v2/simple-swarm-v2.yml +62 -0
  81. data/examples/v2/swarm.yml +71 -0
  82. data/examples/v2/swarm_with_hooks.yml +61 -0
  83. data/examples/v2/swarm_with_hooks_simple.yml +25 -0
  84. data/examples/v2/think_tool_demo.rb +62 -0
  85. data/exe/swarm +6 -0
  86. data/lib/claude_swarm/claude_mcp_server.rb +0 -6
  87. data/lib/claude_swarm/cli.rb +10 -3
  88. data/lib/claude_swarm/commands/ps.rb +19 -20
  89. data/lib/claude_swarm/commands/show.rb +1 -1
  90. data/lib/claude_swarm/configuration.rb +10 -12
  91. data/lib/claude_swarm/mcp_generator.rb +10 -1
  92. data/lib/claude_swarm/orchestrator.rb +73 -49
  93. data/lib/claude_swarm/system_utils.rb +37 -11
  94. data/lib/claude_swarm/version.rb +1 -1
  95. data/lib/claude_swarm/worktree_manager.rb +1 -0
  96. data/lib/claude_swarm/yaml_loader.rb +22 -0
  97. data/lib/claude_swarm.rb +7 -3
  98. data/lib/swarm_cli/cli.rb +201 -0
  99. data/lib/swarm_cli/command_registry.rb +61 -0
  100. data/lib/swarm_cli/commands/mcp_serve.rb +130 -0
  101. data/lib/swarm_cli/commands/mcp_tools.rb +148 -0
  102. data/lib/swarm_cli/commands/migrate.rb +55 -0
  103. data/lib/swarm_cli/commands/run.rb +173 -0
  104. data/lib/swarm_cli/config_loader.rb +97 -0
  105. data/lib/swarm_cli/formatters/human_formatter.rb +711 -0
  106. data/lib/swarm_cli/formatters/json_formatter.rb +51 -0
  107. data/lib/swarm_cli/interactive_repl.rb +918 -0
  108. data/lib/swarm_cli/mcp_serve_options.rb +44 -0
  109. data/lib/swarm_cli/mcp_tools_options.rb +59 -0
  110. data/lib/swarm_cli/migrate_options.rb +54 -0
  111. data/lib/swarm_cli/migrator.rb +132 -0
  112. data/lib/swarm_cli/options.rb +151 -0
  113. data/lib/swarm_cli/ui/components/agent_badge.rb +33 -0
  114. data/lib/swarm_cli/ui/components/content_block.rb +120 -0
  115. data/lib/swarm_cli/ui/components/divider.rb +57 -0
  116. data/lib/swarm_cli/ui/components/panel.rb +62 -0
  117. data/lib/swarm_cli/ui/components/usage_stats.rb +70 -0
  118. data/lib/swarm_cli/ui/formatters/cost.rb +49 -0
  119. data/lib/swarm_cli/ui/formatters/number.rb +58 -0
  120. data/lib/swarm_cli/ui/formatters/text.rb +77 -0
  121. data/lib/swarm_cli/ui/formatters/time.rb +73 -0
  122. data/lib/swarm_cli/ui/icons.rb +59 -0
  123. data/lib/swarm_cli/ui/renderers/event_renderer.rb +188 -0
  124. data/lib/swarm_cli/ui/state/agent_color_cache.rb +45 -0
  125. data/lib/swarm_cli/ui/state/depth_tracker.rb +40 -0
  126. data/lib/swarm_cli/ui/state/spinner_manager.rb +170 -0
  127. data/lib/swarm_cli/ui/state/usage_tracker.rb +62 -0
  128. data/lib/swarm_cli/version.rb +5 -0
  129. data/lib/swarm_cli.rb +44 -0
  130. data/lib/swarm_memory/adapters/base.rb +141 -0
  131. data/lib/swarm_memory/adapters/filesystem_adapter.rb +845 -0
  132. data/lib/swarm_memory/chat_extension.rb +34 -0
  133. data/lib/swarm_memory/cli/commands.rb +306 -0
  134. data/lib/swarm_memory/core/entry.rb +37 -0
  135. data/lib/swarm_memory/core/frontmatter_parser.rb +108 -0
  136. data/lib/swarm_memory/core/metadata_extractor.rb +68 -0
  137. data/lib/swarm_memory/core/path_normalizer.rb +75 -0
  138. data/lib/swarm_memory/core/semantic_index.rb +244 -0
  139. data/lib/swarm_memory/core/storage.rb +288 -0
  140. data/lib/swarm_memory/core/storage_read_tracker.rb +63 -0
  141. data/lib/swarm_memory/dsl/builder_extension.rb +40 -0
  142. data/lib/swarm_memory/dsl/memory_config.rb +113 -0
  143. data/lib/swarm_memory/embeddings/embedder.rb +36 -0
  144. data/lib/swarm_memory/embeddings/informers_embedder.rb +152 -0
  145. data/lib/swarm_memory/errors.rb +21 -0
  146. data/lib/swarm_memory/integration/cli_registration.rb +30 -0
  147. data/lib/swarm_memory/integration/configuration.rb +43 -0
  148. data/lib/swarm_memory/integration/registration.rb +31 -0
  149. data/lib/swarm_memory/integration/sdk_plugin.rb +531 -0
  150. data/lib/swarm_memory/optimization/analyzer.rb +244 -0
  151. data/lib/swarm_memory/optimization/defragmenter.rb +863 -0
  152. data/lib/swarm_memory/prompts/memory.md.erb +109 -0
  153. data/lib/swarm_memory/prompts/memory_assistant.md.erb +181 -0
  154. data/lib/swarm_memory/prompts/memory_researcher.md.erb +281 -0
  155. data/lib/swarm_memory/prompts/memory_retrieval.md.erb +78 -0
  156. data/lib/swarm_memory/search/semantic_search.rb +112 -0
  157. data/lib/swarm_memory/search/text_search.rb +42 -0
  158. data/lib/swarm_memory/search/text_similarity.rb +80 -0
  159. data/lib/swarm_memory/skills/meta/deep-learning.md +101 -0
  160. data/lib/swarm_memory/skills/meta/deep-learning.yml +14 -0
  161. data/lib/swarm_memory/tools/load_skill.rb +313 -0
  162. data/lib/swarm_memory/tools/memory_defrag.rb +382 -0
  163. data/lib/swarm_memory/tools/memory_delete.rb +99 -0
  164. data/lib/swarm_memory/tools/memory_edit.rb +185 -0
  165. data/lib/swarm_memory/tools/memory_glob.rb +160 -0
  166. data/lib/swarm_memory/tools/memory_grep.rb +247 -0
  167. data/lib/swarm_memory/tools/memory_multi_edit.rb +281 -0
  168. data/lib/swarm_memory/tools/memory_read.rb +123 -0
  169. data/lib/swarm_memory/tools/memory_write.rb +231 -0
  170. data/lib/swarm_memory/utils.rb +50 -0
  171. data/lib/swarm_memory/version.rb +5 -0
  172. data/lib/swarm_memory.rb +166 -0
  173. data/lib/swarm_sdk/agent/RETRY_LOGIC.md +127 -0
  174. data/lib/swarm_sdk/agent/builder.rb +461 -0
  175. data/lib/swarm_sdk/agent/chat/context_tracker.rb +314 -0
  176. data/lib/swarm_sdk/agent/chat/hook_integration.rb +372 -0
  177. data/lib/swarm_sdk/agent/chat/logging_helpers.rb +116 -0
  178. data/lib/swarm_sdk/agent/chat/system_reminder_injector.rb +152 -0
  179. data/lib/swarm_sdk/agent/chat.rb +1159 -0
  180. data/lib/swarm_sdk/agent/context.rb +112 -0
  181. data/lib/swarm_sdk/agent/context_manager.rb +309 -0
  182. data/lib/swarm_sdk/agent/definition.rb +556 -0
  183. data/lib/swarm_sdk/claude_code_agent_adapter.rb +205 -0
  184. data/lib/swarm_sdk/configuration.rb +296 -0
  185. data/lib/swarm_sdk/context_compactor/metrics.rb +147 -0
  186. data/lib/swarm_sdk/context_compactor/token_counter.rb +106 -0
  187. data/lib/swarm_sdk/context_compactor.rb +340 -0
  188. data/lib/swarm_sdk/hooks/adapter.rb +359 -0
  189. data/lib/swarm_sdk/hooks/context.rb +197 -0
  190. data/lib/swarm_sdk/hooks/definition.rb +80 -0
  191. data/lib/swarm_sdk/hooks/error.rb +29 -0
  192. data/lib/swarm_sdk/hooks/executor.rb +146 -0
  193. data/lib/swarm_sdk/hooks/registry.rb +147 -0
  194. data/lib/swarm_sdk/hooks/result.rb +150 -0
  195. data/lib/swarm_sdk/hooks/shell_executor.rb +254 -0
  196. data/lib/swarm_sdk/hooks/tool_call.rb +35 -0
  197. data/lib/swarm_sdk/hooks/tool_result.rb +62 -0
  198. data/lib/swarm_sdk/log_collector.rb +51 -0
  199. data/lib/swarm_sdk/log_stream.rb +69 -0
  200. data/lib/swarm_sdk/markdown_parser.rb +75 -0
  201. data/lib/swarm_sdk/model_aliases.json +5 -0
  202. data/lib/swarm_sdk/models.json +1 -0
  203. data/lib/swarm_sdk/models.rb +120 -0
  204. data/lib/swarm_sdk/node/agent_config.rb +49 -0
  205. data/lib/swarm_sdk/node/builder.rb +439 -0
  206. data/lib/swarm_sdk/node/transformer_executor.rb +248 -0
  207. data/lib/swarm_sdk/node_context.rb +170 -0
  208. data/lib/swarm_sdk/node_orchestrator.rb +384 -0
  209. data/lib/swarm_sdk/permissions/config.rb +239 -0
  210. data/lib/swarm_sdk/permissions/error_formatter.rb +121 -0
  211. data/lib/swarm_sdk/permissions/path_matcher.rb +35 -0
  212. data/lib/swarm_sdk/permissions/validator.rb +173 -0
  213. data/lib/swarm_sdk/permissions_builder.rb +122 -0
  214. data/lib/swarm_sdk/plugin.rb +147 -0
  215. data/lib/swarm_sdk/plugin_registry.rb +101 -0
  216. data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +243 -0
  217. data/lib/swarm_sdk/providers/openai_with_responses.rb +582 -0
  218. data/lib/swarm_sdk/result.rb +97 -0
  219. data/lib/swarm_sdk/swarm/agent_initializer.rb +334 -0
  220. data/lib/swarm_sdk/swarm/all_agents_builder.rb +140 -0
  221. data/lib/swarm_sdk/swarm/builder.rb +586 -0
  222. data/lib/swarm_sdk/swarm/mcp_configurator.rb +151 -0
  223. data/lib/swarm_sdk/swarm/tool_configurator.rb +419 -0
  224. data/lib/swarm_sdk/swarm.rb +982 -0
  225. data/lib/swarm_sdk/tools/bash.rb +274 -0
  226. data/lib/swarm_sdk/tools/clock.rb +44 -0
  227. data/lib/swarm_sdk/tools/delegate.rb +164 -0
  228. data/lib/swarm_sdk/tools/document_converters/base_converter.rb +83 -0
  229. data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +99 -0
  230. data/lib/swarm_sdk/tools/document_converters/html_converter.rb +101 -0
  231. data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +78 -0
  232. data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +194 -0
  233. data/lib/swarm_sdk/tools/edit.rb +150 -0
  234. data/lib/swarm_sdk/tools/glob.rb +158 -0
  235. data/lib/swarm_sdk/tools/grep.rb +228 -0
  236. data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +43 -0
  237. data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +163 -0
  238. data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +65 -0
  239. data/lib/swarm_sdk/tools/multi_edit.rb +232 -0
  240. data/lib/swarm_sdk/tools/path_resolver.rb +43 -0
  241. data/lib/swarm_sdk/tools/read.rb +251 -0
  242. data/lib/swarm_sdk/tools/registry.rb +93 -0
  243. data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +96 -0
  244. data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +76 -0
  245. data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +91 -0
  246. data/lib/swarm_sdk/tools/stores/read_tracker.rb +61 -0
  247. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +224 -0
  248. data/lib/swarm_sdk/tools/stores/storage.rb +148 -0
  249. data/lib/swarm_sdk/tools/stores/todo_manager.rb +65 -0
  250. data/lib/swarm_sdk/tools/think.rb +95 -0
  251. data/lib/swarm_sdk/tools/todo_write.rb +216 -0
  252. data/lib/swarm_sdk/tools/web_fetch.rb +261 -0
  253. data/lib/swarm_sdk/tools/write.rb +117 -0
  254. data/lib/swarm_sdk/utils.rb +50 -0
  255. data/lib/swarm_sdk/version.rb +5 -0
  256. data/lib/swarm_sdk.rb +157 -0
  257. data/llm.v2.txt +13407 -0
  258. data/rubocop/cop/security/no_reflection_methods.rb +47 -0
  259. data/rubocop/cop/security/no_ruby_llm_logger.rb +32 -0
  260. data/swarm_cli.gemspec +57 -0
  261. data/swarm_memory.gemspec +28 -0
  262. data/swarm_sdk.gemspec +41 -0
  263. data/team.yml +1 -1
  264. data/team_full.yml +1875 -0
  265. data/{team_v2.yml → team_sdk.yml} +121 -52
  266. metadata +247 -4
  267. data/EXAMPLES.md +0 -164
@@ -0,0 +1,2154 @@
1
+ # Ruby DSL Reference
2
+
3
+ Complete Ruby DSL API reference for building swarms programmatically.
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ The Ruby DSL provides a fluent, type-safe API for building swarms with IDE support and Ruby's full language features. All configuration can be done programmatically with variables, conditionals, loops, and functions.
10
+
11
+ **Key benefits:**
12
+ - Full Ruby language features (variables, conditionals, loops, functions)
13
+ - Ruby blocks for hooks (inline logic, no external scripts)
14
+ - Type-safe, chainable API
15
+ - IDE autocompletion and inline documentation
16
+
17
+ **Basic structure:**
18
+ ```ruby
19
+ swarm = SwarmSDK.build do
20
+ name "Swarm Name"
21
+ lead :agent_name
22
+
23
+ agent :agent_name do
24
+ # Agent configuration
25
+ end
26
+ end
27
+
28
+ result = swarm.execute("Task prompt")
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Top-Level Methods
34
+
35
+ ### SwarmSDK.configure
36
+
37
+ Configure global SwarmSDK settings.
38
+
39
+ **Signature:**
40
+ ```ruby
41
+ SwarmSDK.configure {|config| ... } → void
42
+ ```
43
+
44
+ **Parameters:**
45
+ - `block` (required): Configuration block
46
+
47
+ **Available settings:**
48
+ - `webfetch_provider` (String): LLM provider for WebFetch tool (e.g., "anthropic", "openai", "ollama")
49
+ - `webfetch_model` (String): Model name for WebFetch tool (e.g., "claude-3-5-haiku-20241022")
50
+ - `webfetch_base_url` (String, optional): Custom base URL for the provider
51
+ - `webfetch_max_tokens` (Integer): Maximum tokens for WebFetch LLM responses (default: 4096)
52
+
53
+ **Description:**
54
+ Global configuration that applies to all swarms. Currently used to configure the WebFetch tool's LLM processing behavior.
55
+
56
+ When `webfetch_provider` and `webfetch_model` are set, the WebFetch tool will process fetched web content using the configured LLM. Without this configuration, WebFetch returns raw markdown.
57
+
58
+ **Example:**
59
+ ```ruby
60
+ # Configure WebFetch to use Anthropic's Claude Haiku
61
+ SwarmSDK.configure do |config|
62
+ config.webfetch_provider = "anthropic"
63
+ config.webfetch_model = "claude-3-5-haiku-20241022"
64
+ config.webfetch_max_tokens = 4096
65
+ end
66
+
67
+ # Configure WebFetch to use local Ollama
68
+ SwarmSDK.configure do |config|
69
+ config.webfetch_provider = "ollama"
70
+ config.webfetch_model = "llama3.2"
71
+ config.webfetch_base_url = "http://localhost:11434"
72
+ end
73
+
74
+ # Reset to defaults (disables WebFetch LLM processing)
75
+ SwarmSDK.reset_settings!
76
+ ```
77
+
78
+ ---
79
+
80
+ ### SwarmSDK.build
81
+
82
+ Build a swarm using the DSL.
83
+
84
+ **Signature:**
85
+ ```ruby
86
+ SwarmSDK.build(&block) → Swarm | NodeOrchestrator
87
+ ```
88
+
89
+ **Parameters:**
90
+ - `block` (required): Configuration block
91
+
92
+ **Returns:**
93
+ - `Swarm`: For single-swarm configurations
94
+ - `NodeOrchestrator`: For multi-node workflow configurations
95
+
96
+ **Example:**
97
+ ```ruby
98
+ swarm = SwarmSDK.build do
99
+ name "Development Team"
100
+ lead :backend
101
+
102
+ agent :backend do
103
+ model "gpt-5"
104
+ tools :Read, :Write, :Bash
105
+ end
106
+ end
107
+ ```
108
+
109
+ ---
110
+
111
+ ### SwarmSDK.refresh_models_silently
112
+
113
+ Refresh the LLM model registry silently (called automatically by CLI).
114
+
115
+ **Signature:**
116
+ ```ruby
117
+ SwarmSDK.refresh_models_silently → void
118
+ ```
119
+
120
+ **Description:**
121
+ Updates RubyLLM's model registry to ensure latest model information is available. Called automatically by SwarmCLI before execution.
122
+
123
+ ---
124
+
125
+ ## Swarm Builder DSL
126
+
127
+ Methods available in the `SwarmSDK.build` block.
128
+
129
+ ### name
130
+
131
+ Set the swarm name.
132
+
133
+ **Signature:**
134
+ ```ruby
135
+ name(swarm_name) → void
136
+ ```
137
+
138
+ **Parameters:**
139
+ - `swarm_name` (String, required): Human-readable swarm name
140
+
141
+ **Example:**
142
+ ```ruby
143
+ name "Development Team"
144
+ name "Code Review Swarm"
145
+ ```
146
+
147
+ ---
148
+
149
+ ### lead
150
+
151
+ Set the lead agent (entry point for execution).
152
+
153
+ **Signature:**
154
+ ```ruby
155
+ lead(agent_name) → void
156
+ ```
157
+
158
+ **Parameters:**
159
+ - `agent_name` (Symbol, required): Name of lead agent
160
+
161
+ **Example:**
162
+ ```ruby
163
+ lead :backend
164
+ lead :coordinator
165
+ ```
166
+
167
+ ---
168
+
169
+ ### use_scratchpad
170
+
171
+ Enable or disable shared scratchpad tools for all agents.
172
+
173
+ **Signature:**
174
+ ```ruby
175
+ use_scratchpad(enabled) → void
176
+ ```
177
+
178
+ **Parameters:**
179
+ - `enabled` (Boolean, required): Whether to enable scratchpad tools
180
+
181
+ **Default:** `true` (scratchpad tools enabled)
182
+
183
+ **Description:**
184
+ Controls whether agents have access to scratchpad tools (ScratchpadWrite, ScratchpadRead, ScratchpadList). Scratchpad is volatile (in-memory only) and shared across all agents in the swarm.
185
+
186
+ **Example:**
187
+ ```ruby
188
+ # Enable scratchpad (default)
189
+ use_scratchpad true
190
+
191
+ # Disable scratchpad
192
+ use_scratchpad false
193
+ ```
194
+
195
+ ---
196
+
197
+ ### agent
198
+
199
+ Define an agent with its configuration.
200
+
201
+ **Signature:**
202
+ ```ruby
203
+ agent(name, &block) → void
204
+ ```
205
+
206
+ **Parameters:**
207
+ - `name` (Symbol, required): Agent name
208
+ - `block` (required): Agent configuration block
209
+
210
+ **Example:**
211
+ ```ruby
212
+ agent :backend do
213
+ model "gpt-5"
214
+ description "Backend API developer"
215
+ tools :Read, :Write, :Bash
216
+ delegates_to :database
217
+
218
+ hook :pre_tool_use, matcher: "Bash" do |ctx|
219
+ ctx.halt("Dangerous command") if ctx.tool_call.parameters[:command].include?("rm -rf")
220
+ end
221
+ end
222
+ ```
223
+
224
+ ---
225
+
226
+ ### all_agents
227
+
228
+ Configure settings that apply to all agents.
229
+
230
+ **Signature:**
231
+ ```ruby
232
+ all_agents(&block) → void
233
+ ```
234
+
235
+ **Parameters:**
236
+ - `block` (required): Configuration block (uses [AllAgentsBuilder DSL](#all-agents-builder-dsl))
237
+
238
+ **Description:**
239
+ Settings configured here apply to ALL agents but can be overridden at the agent level. Useful for shared configuration like provider, timeout, or global permissions.
240
+
241
+ **Example:**
242
+ ```ruby
243
+ all_agents do
244
+ provider :openai
245
+ base_url "http://proxy.example.com/v1"
246
+ timeout 180
247
+ tools :Read, :Write
248
+ coding_agent false
249
+
250
+ permissions do
251
+ tool(:Write).deny_paths "secrets/**"
252
+ end
253
+
254
+ hook :pre_tool_use, matcher: "Write" do |ctx|
255
+ # Validation for all agents
256
+ end
257
+ end
258
+ ```
259
+
260
+ ---
261
+
262
+ ### hook
263
+
264
+ Add a swarm-level hook (swarm_start or swarm_stop only).
265
+
266
+ **Signature:**
267
+ ```ruby
268
+ hook(event, command: nil, timeout: nil, &block) → void
269
+ ```
270
+
271
+ **Parameters:**
272
+ - `event` (Symbol, required): Event type (`:swarm_start` or `:swarm_stop`)
273
+ - `command` (String, optional): Shell command to execute
274
+ - `timeout` (Integer, optional): Command timeout in seconds (default: 60)
275
+ - `block` (optional): Ruby block for inline logic
276
+
277
+ **Valid events:** `:swarm_start`, `:swarm_stop`
278
+
279
+ **Example with block:**
280
+ ```ruby
281
+ hook :swarm_start do |ctx|
282
+ puts "Swarm starting: #{ctx.metadata[:prompt]}"
283
+ end
284
+
285
+ hook :swarm_stop do |ctx|
286
+ puts "Duration: #{ctx.metadata[:duration]}s"
287
+ puts "Cost: $#{ctx.metadata[:total_cost]}"
288
+ end
289
+ ```
290
+
291
+ **Example with command:**
292
+ ```ruby
293
+ hook :swarm_start, command: "echo 'Starting' >> log.txt"
294
+ hook :swarm_stop, command: "scripts/cleanup.sh", timeout: 30
295
+ ```
296
+
297
+ ---
298
+
299
+ ### node
300
+
301
+ Define a node (stage in multi-step workflow).
302
+
303
+ **Signature:**
304
+ ```ruby
305
+ node(name, &block) → void
306
+ ```
307
+
308
+ **Parameters:**
309
+ - `name` (Symbol, required): Node name
310
+ - `block` (required): Node configuration block (uses [NodeBuilder DSL](#node-builder-dsl))
311
+
312
+ **Description:**
313
+ Nodes enable multi-stage workflows where different agent teams collaborate in sequence. Each node is an independent swarm execution.
314
+
315
+ **Example:**
316
+ ```ruby
317
+ node :planning do
318
+ agent(:architect)
319
+
320
+ input do |ctx|
321
+ "Plan this task: #{ctx.original_prompt}"
322
+ end
323
+
324
+ output do |ctx|
325
+ File.write("plan.txt", ctx.content)
326
+ "Key decisions: #{extract_decisions(ctx.content)}"
327
+ end
328
+ end
329
+
330
+ node :implementation do
331
+ agent(:backend).delegates_to(:tester)
332
+ agent(:tester)
333
+
334
+ depends_on :planning
335
+
336
+ input do |ctx|
337
+ plan = ctx.all_results[:planning].content
338
+ "Implement based on:\n#{plan}"
339
+ end
340
+ end
341
+ ```
342
+
343
+ ---
344
+
345
+ ### start_node
346
+
347
+ Set the starting node for workflow execution.
348
+
349
+ **Signature:**
350
+ ```ruby
351
+ start_node(name) → void
352
+ ```
353
+
354
+ **Parameters:**
355
+ - `name` (Symbol, required): Name of starting node
356
+
357
+ **Required when:** Nodes are defined
358
+
359
+ **Example:**
360
+ ```ruby
361
+ start_node :planning
362
+
363
+ node :planning do
364
+ # ...
365
+ end
366
+
367
+ node :implementation do
368
+ depends_on :planning
369
+ end
370
+ ```
371
+
372
+ ---
373
+
374
+ ## Agent Builder DSL
375
+
376
+ Methods available in the `agent` block.
377
+
378
+ ### model
379
+
380
+ Set the LLM model.
381
+
382
+ **Signature:**
383
+ ```ruby
384
+ model(model_name) → void
385
+ model() → String # getter
386
+ ```
387
+
388
+ **Parameters:**
389
+ - `model_name` (String, required): Model identifier
390
+
391
+ **Default:** `"gpt-5"`
392
+
393
+ **Common models:**
394
+ - OpenAI: `"gpt-5"`, `"gpt-4o"`, `"o4"`, `"o4-mini"`
395
+ - Anthropic: `"claude-sonnet-4"`, `"claude-opus-4"`
396
+ - Google: `"gemini-2.5-flash"`, `"gemini-2.0-pro"`
397
+ - DeepSeek: `"deepseek-chat"`, `"deepseek-reasoner"`
398
+
399
+ **Example:**
400
+ ```ruby
401
+ model "gpt-5"
402
+ model "claude-sonnet-4"
403
+ model "deepseek-reasoner"
404
+ ```
405
+
406
+ ---
407
+
408
+ ### provider
409
+
410
+ Set the LLM provider.
411
+
412
+ **Signature:**
413
+ ```ruby
414
+ provider(provider_name) → void
415
+ provider() → String # getter
416
+ ```
417
+
418
+ **Parameters:**
419
+ - `provider_name` (String | Symbol, required): Provider name
420
+
421
+ **Default:** `"openai"`
422
+
423
+ **Supported providers:**
424
+ - `openai`: OpenAI
425
+ - `anthropic`: Anthropic Claude
426
+ - `google`: Google AI
427
+ - `deepseek`: DeepSeek
428
+ - `openrouter`: OpenRouter
429
+ - `mistral`: Mistral AI
430
+ - `perplexity`: Perplexity
431
+
432
+ **Example:**
433
+ ```ruby
434
+ provider :openai
435
+ provider "anthropic"
436
+ provider :deepseek
437
+ ```
438
+
439
+ ---
440
+
441
+ ### base_url
442
+
443
+ Set custom API endpoint (for proxies or compatible APIs).
444
+
445
+ **Signature:**
446
+ ```ruby
447
+ base_url(url) → void
448
+ base_url() → String # getter
449
+ ```
450
+
451
+ **Parameters:**
452
+ - `url` (String, required): API endpoint URL
453
+
454
+ **Default:** Provider's default endpoint
455
+
456
+ **Auto-sets:** `assume_model_exists: true` (skips model validation)
457
+
458
+ **Example:**
459
+ ```ruby
460
+ base_url "http://localhost:8080/v1"
461
+ base_url "https://proxy.example.com/v1"
462
+ base_url "https://openrouter.ai/api/v1"
463
+ ```
464
+
465
+ ---
466
+
467
+ ### api_version
468
+
469
+ Set API version for OpenAI-compatible providers.
470
+
471
+ **Signature:**
472
+ ```ruby
473
+ api_version(version) → void
474
+ api_version() → String # getter
475
+ ```
476
+
477
+ **Parameters:**
478
+ - `version` (String, required): API version path
479
+
480
+ **Valid values:**
481
+ - `"v1/chat/completions"`: Standard chat completions (default)
482
+ - `"v1/responses"`: Extended responses format
483
+
484
+ **Compatible providers:** `openai`, `deepseek`, `perplexity`, `mistral`, `openrouter`
485
+
486
+ **Example:**
487
+ ```ruby
488
+ # Standard chat completions
489
+ api_version "v1/chat/completions"
490
+
491
+ # Extended responses
492
+ api_version "v1/responses"
493
+ ```
494
+
495
+ ---
496
+
497
+ ### description
498
+
499
+ Set agent description (required).
500
+
501
+ **Signature:**
502
+ ```ruby
503
+ description(text) → void
504
+ ```
505
+
506
+ **Parameters:**
507
+ - `text` (String, required): Human-readable description
508
+
509
+ **Description:**
510
+ Describes the agent's role and responsibilities. Required for all agents.
511
+
512
+ **Example:**
513
+ ```ruby
514
+ description "Backend API developer specializing in Ruby on Rails"
515
+ description "Frontend developer with React and TypeScript expertise"
516
+ ```
517
+
518
+ ---
519
+
520
+ ### directory
521
+
522
+ Set agent's working directory.
523
+
524
+ **Signature:**
525
+ ```ruby
526
+ directory(dir) → void
527
+ ```
528
+
529
+ **Parameters:**
530
+ - `dir` (String, required): Directory path (absolute or relative)
531
+
532
+ **Default:** `"."`
533
+
534
+ **Description:**
535
+ All file operations (Read, Write, Edit) are relative to this directory. The directory must exist.
536
+
537
+ **Example:**
538
+ ```ruby
539
+ directory "."
540
+ directory "backend"
541
+ directory "/absolute/path/to/workspace"
542
+ ```
543
+
544
+ ---
545
+
546
+ ### system_prompt
547
+
548
+ Set custom system prompt text.
549
+
550
+ **Signature:**
551
+ ```ruby
552
+ system_prompt(text) → void
553
+ ```
554
+
555
+ **Parameters:**
556
+ - `text` (String, required): Custom prompt text
557
+
558
+ **Default:** `nil`
559
+
560
+ **Combination with `coding_agent`:**
561
+ - `coding_agent: false` (default): Uses only custom prompt + TODO/Scratchpad info
562
+ - `coding_agent: true`: Prepends base coding prompt, then custom prompt
563
+
564
+ **Example:**
565
+ ```ruby
566
+ system_prompt "You are a backend API developer. Focus on clean, testable code."
567
+ system_prompt <<~PROMPT
568
+ You are a code reviewer. For each file:
569
+ 1. Check for bugs and edge cases
570
+ 2. Suggest improvements
571
+ 3. Verify test coverage
572
+ PROMPT
573
+ ```
574
+
575
+ ---
576
+
577
+ ### coding_agent
578
+
579
+ Enable/disable base coding prompt.
580
+
581
+ **Signature:**
582
+ ```ruby
583
+ coding_agent(enabled) → void
584
+ ```
585
+
586
+ **Parameters:**
587
+ - `enabled` (Boolean, required): Include base prompt
588
+
589
+ **Default:** `false`
590
+
591
+ **Behavior:**
592
+ - `false`: Uses only custom `system_prompt` + TODO/Scratchpad sections
593
+ - `true`: Prepends comprehensive base coding prompt, then custom prompt
594
+
595
+ **Example:**
596
+ ```ruby
597
+ coding_agent true # Include base prompt for coding tasks
598
+ coding_agent false # Custom prompt only (default)
599
+ ```
600
+
601
+ ---
602
+
603
+ ### tools
604
+
605
+ Add tools to the agent.
606
+
607
+ **Signature:**
608
+ ```ruby
609
+ tools(*tool_names, include_default: true) → void
610
+ ```
611
+
612
+ **Parameters:**
613
+ - `tool_names` (Symbol, variadic): Tool names to add
614
+ - `include_default` (Boolean, keyword): Include default tools
615
+
616
+ **Default tools (when `include_default: true`):**
617
+ - `Read`, `Glob`, `Grep`, `TodoWrite`, `Think`, `WebFetch`
618
+
619
+ **Scratchpad tools** (added if `scratchpad true` at swarm level, default):
620
+ - `ScratchpadWrite`, `ScratchpadRead`, `ScratchpadList`
621
+
622
+ **Memory tools** (added if agent has `memory` configured):
623
+ - `MemoryWrite`, `MemoryRead`, `MemoryEdit`, `MemoryMultiEdit`, `MemoryGlob`, `MemoryGrep`, `MemoryDelete`
624
+
625
+ **Additional tools:**
626
+ - `Write`, `Edit`, `MultiEdit`, `Bash`
627
+
628
+ **Behavior:**
629
+ - Multiple calls are cumulative (tools are merged)
630
+ - Duplicates are automatically removed (uses Set internally)
631
+
632
+ **Example:**
633
+ ```ruby
634
+ # With defaults
635
+ tools :Write, :Bash
636
+
637
+ # Without defaults (explicit tools only)
638
+ tools :Read, :Write, :Bash, include_default: false
639
+
640
+ # Multiple calls (cumulative)
641
+ tools :Read, :Write
642
+ tools :Edit, :Bash # Now has: Read, Write, Edit, Bash + defaults
643
+ ```
644
+
645
+ ---
646
+
647
+ ### delegates_to
648
+
649
+ Set delegation targets (agents this agent can delegate to).
650
+
651
+ **Signature:**
652
+ ```ruby
653
+ delegates_to(*agent_names) → void
654
+ ```
655
+
656
+ **Parameters:**
657
+ - `agent_names` (Symbol, variadic): Names of agents to delegate to
658
+
659
+ **Default:** `[]`
660
+
661
+ **Behavior:**
662
+ - Multiple calls are cumulative
663
+ - Creates a `DelegateTaskTo{Agent}` tool for each target (e.g., `DelegateTaskToDatabase`)
664
+
665
+ **Example:**
666
+ ```ruby
667
+ delegates_to :database
668
+ delegates_to :tester, :reviewer
669
+ delegates_to :frontend # Cumulative - adds to existing list
670
+ ```
671
+
672
+ ---
673
+
674
+ ### memory
675
+
676
+ Configure persistent memory storage for this agent.
677
+
678
+ **Signature:**
679
+ ```ruby
680
+ memory(&block) → void
681
+ ```
682
+
683
+ **Parameters:**
684
+ - `block` (required): Memory configuration block
685
+
686
+ **Block DSL:**
687
+ - `adapter(symbol)` - Storage adapter (default: `:filesystem`)
688
+ - `directory(string)` - Directory where memory.json will be stored (required)
689
+
690
+ **Description:**
691
+ Enables persistent memory for the agent. When configured, the agent automatically gets all 7 memory tools (MemoryWrite, MemoryRead, MemoryEdit, MemoryMultiEdit, MemoryGlob, MemoryGrep, MemoryDelete) and a memory system prompt is appended to help the agent use memory effectively.
692
+
693
+ Memory is per-agent (isolated) and persistent (survives across sessions).
694
+
695
+ **Example:**
696
+ ```ruby
697
+ memory do
698
+ adapter :filesystem # optional, default
699
+ directory ".swarm/agent-memory"
700
+ end
701
+
702
+ # Minimal (adapter defaults to :filesystem)
703
+ memory do
704
+ directory ".swarm/my-agent"
705
+ end
706
+ ```
707
+
708
+ **Future adapters:** `:sqlite`, `:faiss` (not yet implemented)
709
+
710
+ ---
711
+
712
+ ### mcp_server
713
+
714
+ Add an MCP server configuration.
715
+
716
+ **Signature:**
717
+ ```ruby
718
+ mcp_server(name, **options) → void
719
+ ```
720
+
721
+ **Parameters:**
722
+ - `name` (Symbol, required): MCP server name
723
+ - `options` (Hash, required): Server configuration
724
+
725
+ **Transport types:**
726
+
727
+ **stdio transport:**
728
+ ```ruby
729
+ mcp_server :filesystem,
730
+ type: :stdio,
731
+ command: "npx",
732
+ args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed"],
733
+ env: { "VAR" => "value" } # optional
734
+ ```
735
+
736
+ **sse transport:**
737
+ ```ruby
738
+ mcp_server :web,
739
+ type: :sse,
740
+ url: "https://example.com/mcp",
741
+ headers: { authorization: "Bearer token" },
742
+ timeout: 60 # optional
743
+ ```
744
+
745
+ **http transport:**
746
+ ```ruby
747
+ mcp_server :api,
748
+ type: :http,
749
+ url: "https://api.example.com/mcp",
750
+ headers: { "api-key" => "key" },
751
+ timeout: 120 # optional
752
+ ```
753
+
754
+ ---
755
+
756
+ ### permissions
757
+
758
+ Configure tool permissions.
759
+
760
+ **Signature:**
761
+ ```ruby
762
+ permissions(&block) → void
763
+ ```
764
+
765
+ **Parameters:**
766
+ - `block` (required): Permissions configuration block (uses [PermissionsBuilder DSL](#permissions-builder-dsl))
767
+
768
+ **Description:**
769
+ Defines path patterns and command patterns for tool access control. Uses glob patterns for paths and regex for commands.
770
+
771
+ **Example:**
772
+ ```ruby
773
+ permissions do
774
+ tool(:Write).allow_paths "backend/**/*"
775
+ tool(:Write).deny_paths "backend/secrets/**"
776
+ tool(:Read).deny_paths "config/credentials.yml"
777
+ tool(:Bash).allow_commands "^git (status|diff|log)$"
778
+ tool(:Bash).deny_commands "^rm -rf"
779
+ end
780
+ ```
781
+
782
+ ---
783
+
784
+ ### hook
785
+
786
+ Add a hook (Ruby block or shell command).
787
+
788
+ **Signature:**
789
+ ```ruby
790
+ hook(event, matcher: nil, command: nil, timeout: nil, &block) → void
791
+ ```
792
+
793
+ **Parameters:**
794
+ - `event` (Symbol, required): Event type
795
+ - `matcher` (String | Regexp, optional): Tool name pattern (for tool events)
796
+ - `command` (String, optional): Shell command to execute
797
+ - `timeout` (Integer, optional): Command timeout in seconds (default: 60)
798
+ - `block` (optional): Ruby block for inline logic
799
+
800
+ **Valid events:**
801
+ - `:pre_tool_use`: Before tool execution
802
+ - `:post_tool_use`: After tool execution
803
+ - `:user_prompt`: Before sending user message
804
+ - `:agent_stop`: When agent finishes
805
+ - `:first_message`: First user message (once per swarm)
806
+ - `:pre_delegation`: Before delegating to another agent
807
+ - `:post_delegation`: After delegation completes
808
+ - `:context_warning`: When context window threshold exceeded
809
+
810
+ **Example with block:**
811
+ ```ruby
812
+ hook :pre_tool_use, matcher: "Bash" do |ctx|
813
+ if ctx.tool_call.parameters[:command].include?("rm -rf")
814
+ ctx.halt("Dangerous command blocked")
815
+ end
816
+ end
817
+
818
+ hook :post_tool_use, matcher: "Write|Edit" do |ctx|
819
+ puts "Modified: #{ctx.tool_call.parameters[:file_path]}"
820
+ end
821
+ ```
822
+
823
+ **Example with command:**
824
+ ```ruby
825
+ hook :pre_tool_use, matcher: "Write|Edit", command: "scripts/validate.sh"
826
+ hook :post_tool_use, matcher: "Bash", command: "logger 'Command executed'", timeout: 10
827
+ ```
828
+
829
+ ---
830
+
831
+ ### parameters
832
+
833
+ Set LLM parameters (temperature, top_p, etc.).
834
+
835
+ **Signature:**
836
+ ```ruby
837
+ parameters(params) → void
838
+ parameters() → Hash # getter
839
+ ```
840
+
841
+ **Parameters:**
842
+ - `params` (Hash, required): LLM parameters
843
+
844
+ **Common parameters:**
845
+ - `temperature` (Float): Randomness (0.0-2.0)
846
+ - `top_p` (Float): Nucleus sampling (0.0-1.0)
847
+ - `max_tokens` (Integer): Maximum output tokens
848
+ - `presence_penalty` (Float): Presence penalty (-2.0-2.0)
849
+ - `frequency_penalty` (Float): Frequency penalty (-2.0-2.0)
850
+
851
+ **Example:**
852
+ ```ruby
853
+ parameters temperature: 0.7, top_p: 0.95
854
+ parameters max_tokens: 2000, presence_penalty: 0.1
855
+ ```
856
+
857
+ ---
858
+
859
+ ### headers
860
+
861
+ Set custom HTTP headers for API requests.
862
+
863
+ **Signature:**
864
+ ```ruby
865
+ headers(header_hash) → void
866
+ headers() → Hash # getter
867
+ ```
868
+
869
+ **Parameters:**
870
+ - `header_hash` (Hash, required): HTTP headers
871
+
872
+ **Example:**
873
+ ```ruby
874
+ headers "X-API-Key" => "key123", "X-Organization" => "org123"
875
+ headers authorization: "Bearer token"
876
+ ```
877
+
878
+ ---
879
+
880
+ ### timeout
881
+
882
+ Set request timeout.
883
+
884
+ **Signature:**
885
+ ```ruby
886
+ timeout(seconds) → void
887
+ timeout() → Integer # getter
888
+ ```
889
+
890
+ **Parameters:**
891
+ - `seconds` (Integer, required): Timeout in seconds
892
+
893
+ **Default:** `300` (5 minutes)
894
+
895
+ **Example:**
896
+ ```ruby
897
+ timeout 180 # 3 minutes
898
+ timeout 600 # 10 minutes for reasoning models
899
+ ```
900
+
901
+ ---
902
+
903
+ ### context_window
904
+
905
+ Set explicit context window size.
906
+
907
+ **Signature:**
908
+ ```ruby
909
+ context_window(tokens) → void
910
+ context_window() → Integer # getter
911
+ ```
912
+
913
+ **Parameters:**
914
+ - `tokens` (Integer, required): Context window size in tokens
915
+
916
+ **Default:** Auto-detected from model registry
917
+
918
+ **Use case:** Override when using custom models or proxies
919
+
920
+ **Example:**
921
+ ```ruby
922
+ context_window 128000 # Override for custom model
923
+ context_window 200000 # Large context window
924
+ ```
925
+
926
+ ---
927
+
928
+ ### bypass_permissions
929
+
930
+ Disable permission checks for this agent.
931
+
932
+ **Signature:**
933
+ ```ruby
934
+ bypass_permissions(enabled) → void
935
+ ```
936
+
937
+ **Parameters:**
938
+ - `enabled` (Boolean, required): Bypass permissions
939
+
940
+ **Default:** `false`
941
+
942
+ **Warning:** Use with caution - allows unrestricted file/command access
943
+
944
+ **Example:**
945
+ ```ruby
946
+ bypass_permissions true # Disable all permission checks
947
+ ```
948
+
949
+ ---
950
+
951
+ ### max_concurrent_tools
952
+
953
+ Set maximum concurrent tool calls.
954
+
955
+ **Signature:**
956
+ ```ruby
957
+ max_concurrent_tools(count) → void
958
+ ```
959
+
960
+ **Parameters:**
961
+ - `count` (Integer, required): Max concurrent tools
962
+
963
+ **Default:** Swarm's `default_local_concurrency` (10)
964
+
965
+ **Example:**
966
+ ```ruby
967
+ max_concurrent_tools 5 # Limit concurrent tools
968
+ max_concurrent_tools 20 # Allow more parallelism
969
+ ```
970
+
971
+ ---
972
+
973
+ ### disable_default_tools
974
+
975
+ Include default tools (Read, Grep, Glob, TodoWrite, Think, and scratchpad tools).
976
+
977
+ **Signature:**
978
+ ```ruby
979
+ disable_default_tools(value) → void
980
+ ```
981
+
982
+ **Parameters:**
983
+ - `enabled` (Boolean, required): Include defaults
984
+
985
+ **Default:** `true`
986
+
987
+ **Note:** Prefer `tools(..., include_default: false)` for explicit control
988
+
989
+ **Example:**
990
+ ```ruby
991
+ disable_default_tools true # No default tools
992
+ ```
993
+
994
+ ---
995
+
996
+ ### assume_model_exists
997
+
998
+ Skip model validation (for custom models).
999
+
1000
+ **Signature:**
1001
+ ```ruby
1002
+ assume_model_exists(enabled) → void
1003
+ ```
1004
+
1005
+ **Parameters:**
1006
+ - `enabled` (Boolean, required): Skip validation
1007
+
1008
+ **Default:** `false` (validate), `true` when `base_url` is set
1009
+
1010
+ **Example:**
1011
+ ```ruby
1012
+ assume_model_exists true # Skip validation for custom model
1013
+ ```
1014
+
1015
+ ---
1016
+
1017
+ ## All-Agents Builder DSL
1018
+
1019
+ Methods available in the `all_agents` block.
1020
+
1021
+ ### model
1022
+
1023
+ Set default model for all agents.
1024
+
1025
+ **Signature:**
1026
+ ```ruby
1027
+ model(model_name) → void
1028
+ ```
1029
+
1030
+ **Parameters:**
1031
+ - `model_name` (String, required): Model identifier
1032
+
1033
+ **Example:**
1034
+ ```ruby
1035
+ all_agents do
1036
+ model "gpt-5"
1037
+ end
1038
+ ```
1039
+
1040
+ ---
1041
+
1042
+ ### provider
1043
+
1044
+ Set default provider for all agents.
1045
+
1046
+ **Signature:**
1047
+ ```ruby
1048
+ provider(provider_name) → void
1049
+ ```
1050
+
1051
+ **Parameters:**
1052
+ - `provider_name` (String | Symbol, required): Provider name
1053
+
1054
+ **Example:**
1055
+ ```ruby
1056
+ all_agents do
1057
+ provider :anthropic
1058
+ end
1059
+ ```
1060
+
1061
+ ---
1062
+
1063
+ ### base_url
1064
+
1065
+ Set default base URL for all agents.
1066
+
1067
+ **Signature:**
1068
+ ```ruby
1069
+ base_url(url) → void
1070
+ ```
1071
+
1072
+ **Parameters:**
1073
+ - `url` (String, required): API endpoint URL
1074
+
1075
+ **Example:**
1076
+ ```ruby
1077
+ all_agents do
1078
+ base_url "https://proxy.example.com/v1"
1079
+ end
1080
+ ```
1081
+
1082
+ ---
1083
+
1084
+ ### api_version
1085
+
1086
+ Set default API version for all agents.
1087
+
1088
+ **Signature:**
1089
+ ```ruby
1090
+ api_version(version) → void
1091
+ ```
1092
+
1093
+ **Parameters:**
1094
+ - `version` (String, required): API version path
1095
+
1096
+ **Example:**
1097
+ ```ruby
1098
+ all_agents do
1099
+ api_version "v1/responses"
1100
+ end
1101
+ ```
1102
+
1103
+ ---
1104
+
1105
+ ### timeout
1106
+
1107
+ Set default timeout for all agents.
1108
+
1109
+ **Signature:**
1110
+ ```ruby
1111
+ timeout(seconds) → void
1112
+ ```
1113
+
1114
+ **Parameters:**
1115
+ - `seconds` (Integer, required): Timeout in seconds
1116
+
1117
+ **Example:**
1118
+ ```ruby
1119
+ all_agents do
1120
+ timeout 180
1121
+ end
1122
+ ```
1123
+
1124
+ ---
1125
+
1126
+ ### parameters
1127
+
1128
+ Set default LLM parameters for all agents.
1129
+
1130
+ **Signature:**
1131
+ ```ruby
1132
+ parameters(params) → void
1133
+ ```
1134
+
1135
+ **Parameters:**
1136
+ - `params` (Hash, required): LLM parameters
1137
+
1138
+ **Example:**
1139
+ ```ruby
1140
+ all_agents do
1141
+ parameters temperature: 0.7, max_tokens: 2000
1142
+ end
1143
+ ```
1144
+
1145
+ ---
1146
+
1147
+ ### headers
1148
+
1149
+ Set default HTTP headers for all agents.
1150
+
1151
+ **Signature:**
1152
+ ```ruby
1153
+ headers(header_hash) → void
1154
+ ```
1155
+
1156
+ **Parameters:**
1157
+ - `header_hash` (Hash, required): HTTP headers
1158
+
1159
+ **Example:**
1160
+ ```ruby
1161
+ all_agents do
1162
+ headers "X-Organization" => "org123"
1163
+ end
1164
+ ```
1165
+
1166
+ ---
1167
+
1168
+ ### coding_agent
1169
+
1170
+ Set default coding_agent flag for all agents.
1171
+
1172
+ **Signature:**
1173
+ ```ruby
1174
+ coding_agent(enabled) → void
1175
+ ```
1176
+
1177
+ **Parameters:**
1178
+ - `enabled` (Boolean, required): Include base prompt
1179
+
1180
+ **Example:**
1181
+ ```ruby
1182
+ all_agents do
1183
+ coding_agent false
1184
+ end
1185
+ ```
1186
+
1187
+ ---
1188
+
1189
+ ### tools
1190
+
1191
+ Add tools that all agents will have.
1192
+
1193
+ **Signature:**
1194
+ ```ruby
1195
+ tools(*tool_names) → void
1196
+ ```
1197
+
1198
+ **Parameters:**
1199
+ - `tool_names` (Symbol, variadic): Tool names
1200
+
1201
+ **Example:**
1202
+ ```ruby
1203
+ all_agents do
1204
+ tools :Read, :Write
1205
+ end
1206
+ ```
1207
+
1208
+ ---
1209
+
1210
+ ### permissions
1211
+
1212
+ Configure permissions for all agents.
1213
+
1214
+ **Signature:**
1215
+ ```ruby
1216
+ permissions(&block) → void
1217
+ ```
1218
+
1219
+ **Parameters:**
1220
+ - `block` (required): Permissions configuration block
1221
+
1222
+ **Example:**
1223
+ ```ruby
1224
+ all_agents do
1225
+ permissions do
1226
+ tool(:Write).deny_paths "secrets/**"
1227
+ tool(:Bash).deny_commands "^rm -rf"
1228
+ end
1229
+ end
1230
+ ```
1231
+
1232
+ ---
1233
+
1234
+ ### hook
1235
+
1236
+ Add hook for all agents.
1237
+
1238
+ **Signature:**
1239
+ ```ruby
1240
+ hook(event, matcher: nil, command: nil, timeout: nil, &block) → void
1241
+ ```
1242
+
1243
+ **Parameters:** Same as agent-level `hook`
1244
+
1245
+ **Valid events:** All agent-level events (not swarm-level events)
1246
+
1247
+ **Example:**
1248
+ ```ruby
1249
+ all_agents do
1250
+ hook :pre_tool_use, matcher: "Write" do |ctx|
1251
+ # Validation for all agents
1252
+ end
1253
+ end
1254
+ ```
1255
+
1256
+ ---
1257
+
1258
+ ## Permissions Builder DSL
1259
+
1260
+ Methods available in the `permissions` block.
1261
+
1262
+ ### tool
1263
+
1264
+ Get a tool permissions proxy for configuring a specific tool.
1265
+
1266
+ **Signature:**
1267
+ ```ruby
1268
+ tool(tool_name) → ToolPermissionsProxy
1269
+ ```
1270
+
1271
+ **Parameters:**
1272
+ - `tool_name` (Symbol, required): Tool name
1273
+
1274
+ **Returns:** `ToolPermissionsProxy` with fluent methods
1275
+
1276
+ **Example:**
1277
+ ```ruby
1278
+ permissions do
1279
+ tool(:Write).allow_paths("src/**/*").deny_paths("src/secrets/**")
1280
+ tool(:Read).deny_paths("config/credentials.yml")
1281
+ tool(:Bash).allow_commands("^git status$")
1282
+ end
1283
+ ```
1284
+
1285
+ ---
1286
+
1287
+ ### allow_paths
1288
+
1289
+ Add allowed path patterns (chainable).
1290
+
1291
+ **Signature:**
1292
+ ```ruby
1293
+ allow_paths(*patterns) → self
1294
+ ```
1295
+
1296
+ **Parameters:**
1297
+ - `patterns` (String, variadic): Glob patterns
1298
+
1299
+ **Returns:** `self` (for chaining)
1300
+
1301
+ **Example:**
1302
+ ```ruby
1303
+ tool(:Write).allow_paths("backend/**/*")
1304
+ tool(:Write).allow_paths("frontend/**/*", "shared/**/*")
1305
+ ```
1306
+
1307
+ ---
1308
+
1309
+ ### deny_paths
1310
+
1311
+ Add denied path patterns (chainable).
1312
+
1313
+ **Signature:**
1314
+ ```ruby
1315
+ deny_paths(*patterns) → self
1316
+ ```
1317
+
1318
+ **Parameters:**
1319
+ - `patterns` (String, variadic): Glob patterns
1320
+
1321
+ **Returns:** `self` (for chaining)
1322
+
1323
+ **Example:**
1324
+ ```ruby
1325
+ tool(:Write).deny_paths("backend/secrets/**")
1326
+ tool(:Read).deny_paths("config/credentials.yml", ".env")
1327
+ ```
1328
+
1329
+ ---
1330
+
1331
+ ### allow_commands
1332
+
1333
+ Add allowed command patterns (Bash tool only, chainable).
1334
+
1335
+ **Signature:**
1336
+ ```ruby
1337
+ allow_commands(*patterns) → self
1338
+ ```
1339
+
1340
+ **Parameters:**
1341
+ - `patterns` (String, variadic): Regex patterns
1342
+
1343
+ **Returns:** `self` (for chaining)
1344
+
1345
+ **Example:**
1346
+ ```ruby
1347
+ tool(:Bash).allow_commands("^git (status|diff|log)$")
1348
+ tool(:Bash).allow_commands("^npm test$", "^bundle exec rspec$")
1349
+ ```
1350
+
1351
+ ---
1352
+
1353
+ ### deny_commands
1354
+
1355
+ Add denied command patterns (Bash tool only, chainable).
1356
+
1357
+ **Signature:**
1358
+ ```ruby
1359
+ deny_commands(*patterns) → self
1360
+ ```
1361
+
1362
+ **Parameters:**
1363
+ - `patterns` (String, variadic): Regex patterns
1364
+
1365
+ **Returns:** `self` (for chaining)
1366
+
1367
+ **Example:**
1368
+ ```ruby
1369
+ tool(:Bash).deny_commands("^rm -rf")
1370
+ tool(:Bash).deny_commands("^sudo", "^dd if=")
1371
+ ```
1372
+
1373
+ ---
1374
+
1375
+ ## Node Builder DSL
1376
+
1377
+ Methods available in the `node` block.
1378
+
1379
+ ### agent
1380
+
1381
+ Configure an agent for this node (returns fluent config object).
1382
+
1383
+ **Signature:**
1384
+ ```ruby
1385
+ agent(name) → AgentConfig
1386
+ ```
1387
+
1388
+ **Parameters:**
1389
+ - `name` (Symbol, required): Agent name
1390
+
1391
+ **Returns:** `AgentConfig` with `.delegates_to(*names)` method
1392
+
1393
+ **Example:**
1394
+ ```ruby
1395
+ # With delegation
1396
+ agent(:backend).delegates_to(:tester, :database)
1397
+
1398
+ # Without delegation
1399
+ agent(:planner)
1400
+ ```
1401
+
1402
+ ---
1403
+
1404
+ ### depends_on
1405
+
1406
+ Declare node dependencies (prerequisite nodes).
1407
+
1408
+ **Signature:**
1409
+ ```ruby
1410
+ depends_on(*node_names) → void
1411
+ ```
1412
+
1413
+ **Parameters:**
1414
+ - `node_names` (Symbol, variadic): Names of prerequisite nodes
1415
+
1416
+ **Example:**
1417
+ ```ruby
1418
+ depends_on :planning
1419
+ depends_on :frontend, :backend # Multiple dependencies
1420
+ ```
1421
+
1422
+ ---
1423
+
1424
+ ### lead
1425
+
1426
+ Override the lead agent for this node.
1427
+
1428
+ **Signature:**
1429
+ ```ruby
1430
+ lead(agent_name) → void
1431
+ ```
1432
+
1433
+ **Parameters:**
1434
+ - `agent_name` (Symbol, required): Lead agent name
1435
+
1436
+ **Default:** First agent in node
1437
+
1438
+ **Example:**
1439
+ ```ruby
1440
+ agent(:backend).delegates_to(:tester)
1441
+ agent(:tester)
1442
+ lead :tester # Make tester the lead instead of backend
1443
+ ```
1444
+
1445
+ ---
1446
+
1447
+ ### input
1448
+
1449
+ Define input transformer (Ruby block).
1450
+
1451
+ **Signature:**
1452
+ ```ruby
1453
+ input(&block) → void
1454
+ ```
1455
+
1456
+ **Parameters:**
1457
+ - `block` (required): Transformer block, receives `NodeContext`
1458
+
1459
+ **Block return values:**
1460
+ - `String`: Transformed input content
1461
+ - `Hash`: `{ skip_execution: true, content: "..." }` to skip node
1462
+
1463
+ **Context methods:**
1464
+ - `ctx.content`: Previous node's content (convenience)
1465
+ - `ctx.original_prompt`: Original user prompt
1466
+ - `ctx.all_results[:node_name]`: Access any previous node
1467
+ - `ctx.node_name`: Current node name
1468
+ - `ctx.dependencies`: Node dependencies
1469
+
1470
+ **Example:**
1471
+ ```ruby
1472
+ input do |ctx|
1473
+ previous = ctx.content
1474
+ "Task: #{ctx.original_prompt}\nPrevious: #{previous}"
1475
+ end
1476
+
1477
+ # Access specific nodes
1478
+ input do |ctx|
1479
+ plan = ctx.all_results[:planning].content
1480
+ design = ctx.all_results[:design].content
1481
+ "Implement:\nPlan: #{plan}\nDesign: #{design}"
1482
+ end
1483
+
1484
+ # Skip execution (caching)
1485
+ input do |ctx|
1486
+ cached = check_cache(ctx.content)
1487
+ if cached
1488
+ { skip_execution: true, content: cached }
1489
+ else
1490
+ ctx.content
1491
+ end
1492
+ end
1493
+ ```
1494
+
1495
+ ---
1496
+
1497
+ ### input_command
1498
+
1499
+ Define input transformer (Bash command).
1500
+
1501
+ **Signature:**
1502
+ ```ruby
1503
+ input_command(command, timeout: 60) → void
1504
+ ```
1505
+
1506
+ **Parameters:**
1507
+ - `command` (String, required): Bash command
1508
+ - `timeout` (Integer, keyword): Timeout in seconds
1509
+
1510
+ **Input:** NodeContext as JSON on stdin
1511
+
1512
+ **Exit codes:**
1513
+ - `0`: Success, use stdout as transformed content
1514
+ - `1`: Skip node execution, use current_input unchanged
1515
+ - `2`: Halt workflow with error from stderr
1516
+
1517
+ **Example:**
1518
+ ```ruby
1519
+ input_command "scripts/validate.sh", timeout: 30
1520
+ input_command "jq '.content'"
1521
+ ```
1522
+
1523
+ ---
1524
+
1525
+ ### output
1526
+
1527
+ Define output transformer (Ruby block).
1528
+
1529
+ **Signature:**
1530
+ ```ruby
1531
+ output(&block) → void
1532
+ ```
1533
+
1534
+ **Parameters:**
1535
+ - `block` (required): Transformer block, receives `NodeContext`
1536
+
1537
+ **Block return value:**
1538
+ - `String`: Transformed output content
1539
+
1540
+ **Context methods:**
1541
+ - `ctx.content`: Current node's result content (convenience)
1542
+ - `ctx.original_prompt`: Original user prompt
1543
+ - `ctx.all_results[:node_name]`: Access any completed node
1544
+ - `ctx.node_name`: Current node name
1545
+
1546
+ **Example:**
1547
+ ```ruby
1548
+ output do |ctx|
1549
+ # Side effect: save to file
1550
+ File.write("results/plan.txt", ctx.content)
1551
+
1552
+ # Return transformed output
1553
+ "Key decisions: #{extract_decisions(ctx.content)}"
1554
+ end
1555
+
1556
+ # Access multiple nodes
1557
+ output do |ctx|
1558
+ plan = ctx.all_results[:planning].content
1559
+ impl = ctx.content
1560
+ "Completed:\nPlan: #{plan}\nImpl: #{impl}"
1561
+ end
1562
+ ```
1563
+
1564
+ ---
1565
+
1566
+ ### output_command
1567
+
1568
+ Define output transformer (Bash command).
1569
+
1570
+ **Signature:**
1571
+ ```ruby
1572
+ output_command(command, timeout: 60) → void
1573
+ ```
1574
+
1575
+ **Parameters:**
1576
+ - `command` (String, required): Bash command
1577
+ - `timeout` (Integer, keyword): Timeout in seconds
1578
+
1579
+ **Input:** NodeContext as JSON on stdin
1580
+
1581
+ **Exit codes:**
1582
+ - `0`: Success, use stdout as transformed content
1583
+ - `1`: Pass through unchanged, use result.content
1584
+ - `2`: Halt workflow with error from stderr
1585
+
1586
+ **Example:**
1587
+ ```ruby
1588
+ output_command "scripts/format.sh", timeout: 30
1589
+ output_command "tee results.txt"
1590
+ ```
1591
+
1592
+ ---
1593
+
1594
+ ## Execution Methods
1595
+
1596
+ ### swarm.execute
1597
+
1598
+ Execute a task using the lead agent.
1599
+
1600
+ **Signature:**
1601
+ ```ruby
1602
+ swarm.execute(prompt, &block) → Result
1603
+ ```
1604
+
1605
+ **Parameters:**
1606
+ - `prompt` (String, required): Task prompt
1607
+ - `block` (optional): Log entry handler for streaming
1608
+
1609
+ **Returns:** `Result` object
1610
+
1611
+ **Example:**
1612
+ ```ruby
1613
+ # Basic execution
1614
+ result = swarm.execute("Build a REST API")
1615
+
1616
+ # With logging
1617
+ result = swarm.execute("Build a REST API") do |log_entry|
1618
+ puts "#{log_entry[:type]}: #{log_entry[:agent]}" if log_entry[:type] == "tool_call"
1619
+ end
1620
+
1621
+ # Check result
1622
+ if result.success?
1623
+ puts result.content
1624
+ puts "Cost: $#{result.total_cost}"
1625
+ puts "Tokens: #{result.total_tokens}"
1626
+ puts "Duration: #{result.duration}s"
1627
+ else
1628
+ puts "Error: #{result.error.message}"
1629
+ end
1630
+ ```
1631
+
1632
+ ---
1633
+
1634
+ ## Result Object
1635
+
1636
+ Returned by `swarm.execute`.
1637
+
1638
+ ### Attributes
1639
+
1640
+ **content**
1641
+ ```ruby
1642
+ result.content → String | nil
1643
+ ```
1644
+ Final response content from the swarm.
1645
+
1646
+ **agent**
1647
+ ```ruby
1648
+ result.agent → String
1649
+ ```
1650
+ Name of the agent that produced the final response.
1651
+
1652
+ **duration**
1653
+ ```ruby
1654
+ result.duration → Float
1655
+ ```
1656
+ Total execution duration in seconds.
1657
+
1658
+ **logs**
1659
+ ```ruby
1660
+ result.logs → Array<Hash>
1661
+ ```
1662
+ Array of log entries (events during execution).
1663
+
1664
+ **error**
1665
+ ```ruby
1666
+ result.error → Exception | nil
1667
+ ```
1668
+ Error object if execution failed, nil otherwise.
1669
+
1670
+ ---
1671
+
1672
+ ### Methods
1673
+
1674
+ **success?**
1675
+ ```ruby
1676
+ result.success? → Boolean
1677
+ ```
1678
+ Returns true if execution succeeded (no error).
1679
+
1680
+ **failure?**
1681
+ ```ruby
1682
+ result.failure? → Boolean
1683
+ ```
1684
+ Returns true if execution failed (has error).
1685
+
1686
+ **total_cost**
1687
+ ```ruby
1688
+ result.total_cost → Float
1689
+ ```
1690
+ Total cost in dollars across all LLM calls.
1691
+
1692
+ **total_tokens**
1693
+ ```ruby
1694
+ result.total_tokens → Integer
1695
+ ```
1696
+ Total tokens used (input + output).
1697
+
1698
+ **agents_involved**
1699
+ ```ruby
1700
+ result.agents_involved → Array<Symbol>
1701
+ ```
1702
+ List of all agents that participated.
1703
+
1704
+ **llm_requests**
1705
+ ```ruby
1706
+ result.llm_requests → Integer
1707
+ ```
1708
+ Number of LLM API calls made.
1709
+
1710
+ **tool_calls_count**
1711
+ ```ruby
1712
+ result.tool_calls_count → Integer
1713
+ ```
1714
+ Number of tool calls made.
1715
+
1716
+ **to_h**
1717
+ ```ruby
1718
+ result.to_h → Hash
1719
+ ```
1720
+ Convert to hash representation.
1721
+
1722
+ **to_json**
1723
+ ```ruby
1724
+ result.to_json → String
1725
+ ```
1726
+ Convert to JSON string.
1727
+
1728
+ ---
1729
+
1730
+ ## Context Management
1731
+
1732
+ SwarmSDK automatically manages conversation context to prevent hitting token limits while preserving accuracy.
1733
+
1734
+ ### Automatic Features
1735
+
1736
+ #### Ephemeral System Reminders
1737
+
1738
+ System reminders (guidance, tool lists, error recovery) are sent to the LLM but **NOT persisted** in conversation history. This prevents reminder accumulation and saves 80-95% of reminder tokens in long conversations.
1739
+
1740
+ **How it works:**
1741
+ ```
1742
+ Turn 1: Sends reminders → LLM sees them → NOT stored in history
1743
+ Turn 2: Sends new reminders → LLM sees only current turn's reminders
1744
+ Turn 20: No accumulated reminders (saves 1,200-13,800 tokens!)
1745
+ ```
1746
+
1747
+ **Automatic** - No configuration needed. All `<system-reminder>` blocks are extracted and sent ephemerally.
1748
+
1749
+ #### Automatic Compression (60% Threshold)
1750
+
1751
+ When context usage reaches **60%**, SwarmSDK automatically compresses old tool results to free space.
1752
+
1753
+ **What gets compressed:**
1754
+ - ✅ **Tool results** (`role: :tool`) older than 10 messages
1755
+ - ✅ **Long outputs** from Read, Bash, Grep, etc.
1756
+ - ❌ **User messages** - Never compressed (user intent preserved)
1757
+ - ❌ **Assistant messages** - Never compressed (reasoning preserved)
1758
+ - ❌ **Recent messages** (last 10) - Full detail maintained
1759
+
1760
+ **Progressive compression by age:**
1761
+ ```
1762
+ Age 11-20 messages: → 1000 chars max (light)
1763
+ Age 21-40 messages: → 500 chars max (moderate)
1764
+ Age 41-60 messages: → 200 chars max (heavy)
1765
+ Age 61+ messages: → 100 chars max (minimal summary)
1766
+ ```
1767
+
1768
+ **Triggers:**
1769
+ - Automatically at 60% context usage
1770
+ - Only once (doesn't re-compress)
1771
+ - Logs `context_compression` event
1772
+
1773
+ **Example log:**
1774
+ ```json
1775
+ {
1776
+ "type": "context_compression",
1777
+ "agent": "assistant",
1778
+ "total_messages": 45,
1779
+ "messages_compressed": 12,
1780
+ "tokens_before": 95000,
1781
+ "current_usage": "61%",
1782
+ "compression_strategy": "progressive_tool_result_compression",
1783
+ "keep_recent": 10
1784
+ }
1785
+ ```
1786
+
1787
+ **Token savings:**
1788
+ - Typical: 10,000-20,000 tokens freed
1789
+ - Heavy tool usage: 30,000-50,000 tokens freed
1790
+ - Extends conversation by 20-40% more turns
1791
+
1792
+ ### Context Warning Thresholds
1793
+
1794
+ SwarmSDK emits warnings at these thresholds:
1795
+ - **60%** - Triggers automatic compression
1796
+ - **80%** - Informational warning (approaching limit)
1797
+ - **90%** - Critical warning (near limit)
1798
+
1799
+ Each threshold emits once via `context_limit_warning` event.
1800
+
1801
+ ### Impact on Accuracy
1802
+
1803
+ **Minimal** - Compression is designed to preserve accuracy:
1804
+ 1. Recent context (last 10 messages) unchanged
1805
+ 2. Conversational flow preserved (user/assistant messages)
1806
+ 3. Tool results compressed but essential structure kept
1807
+ 4. Progressive (older = more compressed)
1808
+ 5. Only triggers when needed (60% full)
1809
+
1810
+ **When it might impact accuracy:**
1811
+ - Agent references very old tool results (rare)
1812
+ - Multi-file analysis across 40+ turns (uncommon)
1813
+
1814
+ **When it doesn't impact accuracy:**
1815
+ - Short conversations (<30 turns)
1816
+ - Recent tool results (always full detail)
1817
+ - User/assistant conversation (never compressed)
1818
+
1819
+ ### Manual Control
1820
+
1821
+ Context management is automatic, but you can monitor via events:
1822
+
1823
+ ```ruby
1824
+ swarm = SwarmSDK.build do
1825
+ name "My Swarm"
1826
+
1827
+ on :context_limit_warning do |ctx|
1828
+ puts "Context at #{ctx.metadata[:current_usage]}"
1829
+ end
1830
+
1831
+ on :context_compression do |ctx|
1832
+ puts "Compressed #{ctx.metadata[:messages_compressed]} messages"
1833
+ end
1834
+ end
1835
+ ```
1836
+
1837
+ ---
1838
+
1839
+ ## Hook Context Methods
1840
+
1841
+ Available in hook blocks via the `ctx` parameter.
1842
+
1843
+ ### Context Attributes
1844
+
1845
+ **event**
1846
+ ```ruby
1847
+ ctx.event → Symbol
1848
+ ```
1849
+ Current event type.
1850
+
1851
+ **agent_name**
1852
+ ```ruby
1853
+ ctx.agent_name → String
1854
+ ```
1855
+ Current agent name.
1856
+
1857
+ **tool_call**
1858
+ ```ruby
1859
+ ctx.tool_call → ToolCall
1860
+ ```
1861
+ Tool call object (for tool events).
1862
+
1863
+ **tool_result**
1864
+ ```ruby
1865
+ ctx.tool_result → ToolResult
1866
+ ```
1867
+ Tool result object (for post_tool_use).
1868
+
1869
+ **delegation_target**
1870
+ ```ruby
1871
+ ctx.delegation_target → Symbol
1872
+ ```
1873
+ Target agent name (for delegation events).
1874
+
1875
+ **metadata**
1876
+ ```ruby
1877
+ ctx.metadata → Hash
1878
+ ```
1879
+ Additional event metadata (read-write).
1880
+
1881
+ **swarm**
1882
+ ```ruby
1883
+ ctx.swarm → Swarm
1884
+ ```
1885
+ Reference to the swarm instance.
1886
+
1887
+ ---
1888
+
1889
+ ### Context Methods
1890
+
1891
+ **tool_event?**
1892
+ ```ruby
1893
+ ctx.tool_event? → Boolean
1894
+ ```
1895
+ Returns true if event is pre_tool_use or post_tool_use.
1896
+
1897
+ **delegation_event?**
1898
+ ```ruby
1899
+ ctx.delegation_event? → Boolean
1900
+ ```
1901
+ Returns true if event is pre_delegation or post_delegation.
1902
+
1903
+ **tool_name**
1904
+ ```ruby
1905
+ ctx.tool_name → String | nil
1906
+ ```
1907
+ Tool name (convenience method).
1908
+
1909
+ ---
1910
+
1911
+ ### Action Methods
1912
+
1913
+ **halt**
1914
+ ```ruby
1915
+ ctx.halt(message) → HookResult
1916
+ ```
1917
+ Halt execution and return error message.
1918
+
1919
+ **replace**
1920
+ ```ruby
1921
+ ctx.replace(value) → HookResult
1922
+ ```
1923
+ Replace tool result or prompt with custom value.
1924
+
1925
+ **reprompt**
1926
+ ```ruby
1927
+ ctx.reprompt(prompt) → HookResult
1928
+ ```
1929
+ Reprompt the agent with a new prompt (swarm_stop only).
1930
+
1931
+ **finish_agent**
1932
+ ```ruby
1933
+ ctx.finish_agent(message) → HookResult
1934
+ ```
1935
+ Finish current agent's execution with final message.
1936
+
1937
+ **finish_swarm**
1938
+ ```ruby
1939
+ ctx.finish_swarm(message) → HookResult
1940
+ ```
1941
+ Finish entire swarm execution with final message.
1942
+
1943
+ **breakpoint**
1944
+ ```ruby
1945
+ ctx.breakpoint → void
1946
+ ```
1947
+ Enter interactive debugging (binding.irb).
1948
+
1949
+ ---
1950
+
1951
+ ### ToolCall Object
1952
+
1953
+ **Attributes:**
1954
+ ```ruby
1955
+ tool_call.id → String # Tool call ID
1956
+ tool_call.name → String # Tool name
1957
+ tool_call.parameters → Hash # Tool parameters
1958
+ ```
1959
+
1960
+ ---
1961
+
1962
+ ### ToolResult Object
1963
+
1964
+ **Attributes:**
1965
+ ```ruby
1966
+ tool_result.tool_call_id → String # Tool call ID
1967
+ tool_result.tool_name → String # Tool name
1968
+ tool_result.content → String # Result content
1969
+ tool_result.success? → Boolean # Success status
1970
+ ```
1971
+
1972
+ ---
1973
+
1974
+ ## NodeContext Methods
1975
+
1976
+ Available in node transformer blocks via the `ctx` parameter.
1977
+
1978
+ ### Attributes
1979
+
1980
+ **original_prompt**
1981
+ ```ruby
1982
+ ctx.original_prompt → String
1983
+ ```
1984
+ Original user prompt for the workflow.
1985
+
1986
+ **all_results**
1987
+ ```ruby
1988
+ ctx.all_results → Hash<Symbol, Result>
1989
+ ```
1990
+ Results from all completed nodes.
1991
+
1992
+ **node_name**
1993
+ ```ruby
1994
+ ctx.node_name → Symbol
1995
+ ```
1996
+ Current node name.
1997
+
1998
+ **dependencies**
1999
+ ```ruby
2000
+ ctx.dependencies → Array<Symbol>
2001
+ ```
2002
+ Node dependencies (input transformers only).
2003
+
2004
+ ---
2005
+
2006
+ ### Convenience Methods
2007
+
2008
+ **content**
2009
+ ```ruby
2010
+ ctx.content → String | nil
2011
+ ```
2012
+ - Input transformers: Previous node's content (or transformed content)
2013
+ - Output transformers: Current node's content
2014
+
2015
+ **agent**
2016
+ ```ruby
2017
+ ctx.agent → String | nil
2018
+ ```
2019
+ Agent name from previous_result or result.
2020
+
2021
+ **logs**
2022
+ ```ruby
2023
+ ctx.logs → Array | nil
2024
+ ```
2025
+ Logs from previous_result or result.
2026
+
2027
+ **duration**
2028
+ ```ruby
2029
+ ctx.duration → Float | nil
2030
+ ```
2031
+ Duration from previous_result or result.
2032
+
2033
+ **error**
2034
+ ```ruby
2035
+ ctx.error → Exception | nil
2036
+ ```
2037
+ Error from previous_result or result.
2038
+
2039
+ **success?**
2040
+ ```ruby
2041
+ ctx.success? → Boolean | nil
2042
+ ```
2043
+ Success status from previous_result or result.
2044
+
2045
+ ---
2046
+
2047
+ ## Complete Example
2048
+
2049
+ ```ruby
2050
+ #!/usr/bin/env ruby
2051
+ require "swarm_sdk"
2052
+
2053
+ swarm = SwarmSDK.build do
2054
+ name "Code Review Team"
2055
+ lead :reviewer
2056
+
2057
+ # Apply settings to all agents
2058
+ all_agents do
2059
+ provider :anthropic
2060
+ timeout 180
2061
+ coding_agent false
2062
+
2063
+ permissions do
2064
+ tool(:Write).deny_paths "secrets/**"
2065
+ end
2066
+ end
2067
+
2068
+ # Lead reviewer agent
2069
+ agent :reviewer do
2070
+ model "claude-sonnet-4"
2071
+ description "Lead code reviewer coordinating the review process"
2072
+ directory "."
2073
+
2074
+ system_prompt <<~PROMPT
2075
+ You are a lead code reviewer. Coordinate the review process:
2076
+ 1. Delegate security checks to the security expert
2077
+ 2. Delegate performance analysis to the performance expert
2078
+ 3. Synthesize feedback into actionable recommendations
2079
+ PROMPT
2080
+
2081
+ tools :Read, :Write, :Edit
2082
+ delegates_to :security, :performance
2083
+
2084
+ hook :pre_delegation do |ctx|
2085
+ puts "Delegating to #{ctx.delegation_target}..."
2086
+ end
2087
+ end
2088
+
2089
+ # Security expert
2090
+ agent :security do
2091
+ model "gpt-5"
2092
+ description "Security expert checking for vulnerabilities"
2093
+
2094
+ system_prompt "You are a security expert. Check code for vulnerabilities, injection attacks, and security best practices."
2095
+
2096
+ tools :Read, :Grep
2097
+
2098
+ hook :pre_tool_use, matcher: "Read" do |ctx|
2099
+ # Log which files are being reviewed
2100
+ puts "Reviewing: #{ctx.tool_call.parameters[:file_path]}"
2101
+ end
2102
+ end
2103
+
2104
+ # Performance expert
2105
+ agent :performance do
2106
+ model "gpt-5"
2107
+ description "Performance expert analyzing efficiency"
2108
+
2109
+ system_prompt "You are a performance expert. Analyze code for performance issues, algorithmic complexity, and optimization opportunities."
2110
+
2111
+ tools :Read, :Grep, :Bash
2112
+
2113
+ permissions do
2114
+ tool(:Bash).allow_commands "^(node --prof|ruby-prof|py-spy)"
2115
+ end
2116
+ end
2117
+
2118
+ # Swarm-level hook
2119
+ hook :swarm_stop do |ctx|
2120
+ puts "\nReview complete!"
2121
+ puts "Duration: #{ctx.metadata[:duration]}s"
2122
+ puts "Cost: $#{ctx.metadata[:total_cost]}"
2123
+ end
2124
+ end
2125
+
2126
+ # Execute review
2127
+ result = swarm.execute("Review the authentication code in src/auth.rb") do |log|
2128
+ if log[:type] == "tool_call"
2129
+ puts " #{log[:tool]}: #{log[:arguments].inspect}"
2130
+ end
2131
+ end
2132
+
2133
+ # Check result
2134
+ if result.success?
2135
+ puts "\nFeedback:"
2136
+ puts result.content
2137
+
2138
+ puts "\nStats:"
2139
+ puts " Agents: #{result.agents_involved.join(", ")}"
2140
+ puts " Tokens: #{result.total_tokens}"
2141
+ puts " Cost: $#{result.total_cost}"
2142
+ else
2143
+ puts "Error: #{result.error.message}"
2144
+ exit 1
2145
+ end
2146
+ ```
2147
+
2148
+ ---
2149
+
2150
+ ## See Also
2151
+
2152
+ - [YAML Reference](./yaml.md): Complete YAML configuration reference
2153
+ - [CLI Reference](./cli.md): Command-line interface reference
2154
+ - [Getting Started Guide](../guides/getting-started.md): Introduction to SwarmSDK