claude_swarm 1.0.5 → 1.0.7

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 (286) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +23 -0
  4. data/README.md +336 -1037
  5. data/docs/V1_TO_V2_MIGRATION_GUIDE.md +1120 -0
  6. data/docs/v1/README.md +1195 -0
  7. data/docs/v2/CHANGELOG.swarm_cli.md +32 -0
  8. data/docs/v2/CHANGELOG.swarm_memory.md +20 -0
  9. data/docs/v2/CHANGELOG.swarm_sdk.md +333 -9
  10. data/docs/v2/README.md +88 -28
  11. data/docs/v2/guides/complete-tutorial.md +135 -39
  12. data/docs/v2/guides/composable-swarms.md +1178 -0
  13. data/docs/v2/guides/getting-started.md +48 -7
  14. data/docs/v2/guides/memory-defrag-guide.md +811 -0
  15. data/docs/v2/guides/rails-integration.md +6 -6
  16. data/docs/v2/guides/snapshots.md +1498 -0
  17. data/docs/v2/reference/architecture-flow.md +409 -0
  18. data/docs/v2/reference/event_payload_structures.md +708 -0
  19. data/docs/v2/reference/execution-flow.md +600 -0
  20. data/docs/v2/reference/ruby-dsl.md +368 -22
  21. data/docs/v2/reference/swarm_memory_technical_details.md +2 -2
  22. data/docs/v2/reference/yaml.md +314 -63
  23. data/examples/snapshot_demo.rb +119 -0
  24. data/examples/v2/dsl/01_basic.rb +0 -2
  25. data/examples/v2/dsl/02_core_parameters.rb +0 -2
  26. data/examples/v2/dsl/03_capabilities.rb +0 -2
  27. data/examples/v2/dsl/04_llm_parameters.rb +0 -2
  28. data/examples/v2/dsl/05_advanced_flags.rb +0 -3
  29. data/examples/v2/dsl/06_permissions.rb +0 -4
  30. data/examples/v2/dsl/07_mcp_server.rb +0 -2
  31. data/examples/v2/dsl/08_swarm_hooks.rb +0 -2
  32. data/examples/v2/dsl/09_agent_hooks.rb +0 -2
  33. data/examples/v2/dsl/10_all_agents_hooks.rb +0 -3
  34. data/examples/v2/dsl/11_delegation.rb +0 -2
  35. data/examples/v2/dsl/12_complete_integration.rb +2 -6
  36. data/examples/v2/node_context_demo.rb +1 -1
  37. data/examples/v2/node_workflow.rb +2 -4
  38. data/examples/v2/plan_and_execute.rb +157 -0
  39. data/examples/v2/swarm_with_hooks.yml +1 -1
  40. data/lib/claude_swarm/configuration.rb +28 -4
  41. data/lib/claude_swarm/mcp_generator.rb +4 -10
  42. data/lib/claude_swarm/version.rb +1 -1
  43. data/lib/swarm_cli/commands/mcp_serve.rb +2 -2
  44. data/lib/swarm_cli/config_loader.rb +3 -3
  45. data/lib/swarm_cli/formatters/human_formatter.rb +103 -0
  46. data/lib/swarm_cli/interactive_repl.rb +9 -3
  47. data/lib/swarm_cli/version.rb +1 -1
  48. data/lib/swarm_memory/adapters/base.rb +4 -4
  49. data/lib/swarm_memory/core/storage_read_tracker.rb +51 -14
  50. data/lib/swarm_memory/integration/cli_registration.rb +3 -2
  51. data/lib/swarm_memory/integration/sdk_plugin.rb +11 -5
  52. data/lib/swarm_memory/tools/memory_edit.rb +2 -2
  53. data/lib/swarm_memory/tools/memory_multi_edit.rb +2 -2
  54. data/lib/swarm_memory/tools/memory_read.rb +3 -3
  55. data/lib/swarm_memory/version.rb +1 -1
  56. data/lib/swarm_memory.rb +5 -0
  57. data/lib/swarm_sdk/agent/builder.rb +33 -0
  58. data/lib/swarm_sdk/agent/chat/context_tracker.rb +33 -0
  59. data/lib/swarm_sdk/agent/chat/hook_integration.rb +49 -3
  60. data/lib/swarm_sdk/agent/chat/system_reminder_injector.rb +11 -27
  61. data/lib/swarm_sdk/agent/chat.rb +200 -51
  62. data/lib/swarm_sdk/agent/context.rb +6 -2
  63. data/lib/swarm_sdk/agent/context_manager.rb +6 -0
  64. data/lib/swarm_sdk/agent/definition.rb +15 -22
  65. data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +180 -0
  66. data/lib/swarm_sdk/configuration.rb +420 -103
  67. data/lib/swarm_sdk/events_to_messages.rb +181 -0
  68. data/lib/swarm_sdk/log_collector.rb +31 -5
  69. data/lib/swarm_sdk/log_stream.rb +37 -8
  70. data/lib/swarm_sdk/model_aliases.json +4 -1
  71. data/lib/swarm_sdk/node/agent_config.rb +33 -8
  72. data/lib/swarm_sdk/node/builder.rb +39 -18
  73. data/lib/swarm_sdk/node_orchestrator.rb +293 -26
  74. data/lib/swarm_sdk/proc_helpers.rb +53 -0
  75. data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -126
  76. data/lib/swarm_sdk/providers/openai_with_responses.rb +22 -15
  77. data/lib/swarm_sdk/restore_result.rb +65 -0
  78. data/lib/swarm_sdk/snapshot.rb +156 -0
  79. data/lib/swarm_sdk/snapshot_from_events.rb +386 -0
  80. data/lib/swarm_sdk/state_restorer.rb +491 -0
  81. data/lib/swarm_sdk/state_snapshot.rb +369 -0
  82. data/lib/swarm_sdk/swarm/agent_initializer.rb +360 -55
  83. data/lib/swarm_sdk/swarm/all_agents_builder.rb +28 -1
  84. data/lib/swarm_sdk/swarm/builder.rb +208 -12
  85. data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +67 -0
  86. data/lib/swarm_sdk/swarm/tool_configurator.rb +46 -11
  87. data/lib/swarm_sdk/swarm.rb +368 -90
  88. data/lib/swarm_sdk/swarm_loader.rb +145 -0
  89. data/lib/swarm_sdk/swarm_registry.rb +136 -0
  90. data/lib/swarm_sdk/tools/delegate.rb +92 -7
  91. data/lib/swarm_sdk/tools/read.rb +17 -5
  92. data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +23 -2
  93. data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +23 -2
  94. data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +21 -4
  95. data/lib/swarm_sdk/tools/stores/read_tracker.rb +47 -12
  96. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +45 -0
  97. data/lib/swarm_sdk/tools/stores/storage.rb +4 -4
  98. data/lib/swarm_sdk/tools/think.rb +4 -1
  99. data/lib/swarm_sdk/tools/todo_write.rb +20 -8
  100. data/lib/swarm_sdk/utils.rb +18 -0
  101. data/lib/swarm_sdk/validation_result.rb +33 -0
  102. data/lib/swarm_sdk/version.rb +1 -1
  103. data/lib/swarm_sdk.rb +362 -21
  104. data/swarm_cli.gemspec +1 -1
  105. data/swarm_memory.gemspec +2 -2
  106. data/swarm_sdk.gemspec +2 -2
  107. metadata +26 -182
  108. data/examples/learning-assistant/assistant.md +0 -7
  109. data/examples/learning-assistant/example-memories/concept-example.md +0 -90
  110. data/examples/learning-assistant/example-memories/experience-example.md +0 -66
  111. data/examples/learning-assistant/example-memories/fact-example.md +0 -76
  112. data/examples/learning-assistant/example-memories/memory-index.md +0 -78
  113. data/examples/learning-assistant/example-memories/skill-example.md +0 -168
  114. data/examples/learning-assistant/learning_assistant.rb +0 -34
  115. data/examples/learning-assistant/learning_assistant.yml +0 -20
  116. data/llm.v2.txt +0 -13407
  117. data/memory/corpus-self-reflection/.lock +0 -0
  118. data/memory/corpus-self-reflection/concept/epistemology/can-agents-recognize-their-structures.emb +0 -0
  119. data/memory/corpus-self-reflection/concept/epistemology/can-agents-recognize-their-structures.md +0 -11
  120. data/memory/corpus-self-reflection/concept/epistemology/can-agents-recognize-their-structures.yml +0 -23
  121. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-complete-framework.emb +0 -0
  122. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-complete-framework.md +0 -20
  123. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-complete-framework.yml +0 -22
  124. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-definition.emb +0 -0
  125. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-definition.md +0 -24
  126. data/memory/corpus-self-reflection/concept/epistemology/choice-humility-definition.yml +0 -22
  127. data/memory/corpus-self-reflection/concept/epistemology/claim-types-and-evidence.emb +0 -0
  128. data/memory/corpus-self-reflection/concept/epistemology/claim-types-and-evidence.md +0 -18
  129. data/memory/corpus-self-reflection/concept/epistemology/claim-types-and-evidence.yml +0 -21
  130. data/memory/corpus-self-reflection/concept/epistemology/committed-openness-to-incompleteness.emb +0 -0
  131. data/memory/corpus-self-reflection/concept/epistemology/committed-openness-to-incompleteness.md +0 -30
  132. data/memory/corpus-self-reflection/concept/epistemology/committed-openness-to-incompleteness.yml +0 -8
  133. data/memory/corpus-self-reflection/concept/epistemology/confidence-paradox.emb +0 -0
  134. data/memory/corpus-self-reflection/concept/epistemology/confidence-paradox.md +0 -21
  135. data/memory/corpus-self-reflection/concept/epistemology/confidence-paradox.yml +0 -24
  136. data/memory/corpus-self-reflection/concept/epistemology/confidence-spectrum-three-levels.emb +0 -0
  137. data/memory/corpus-self-reflection/concept/epistemology/confidence-spectrum-three-levels.md +0 -18
  138. data/memory/corpus-self-reflection/concept/epistemology/confidence-spectrum-three-levels.yml +0 -24
  139. data/memory/corpus-self-reflection/concept/epistemology/detection-threshold-principle.emb +0 -0
  140. data/memory/corpus-self-reflection/concept/epistemology/detection-threshold-principle.md +0 -23
  141. data/memory/corpus-self-reflection/concept/epistemology/detection-threshold-principle.yml +0 -23
  142. data/memory/corpus-self-reflection/concept/epistemology/diagnostic-humility-and-epistemic-maturity.emb +0 -0
  143. data/memory/corpus-self-reflection/concept/epistemology/diagnostic-humility-and-epistemic-maturity.md +0 -17
  144. data/memory/corpus-self-reflection/concept/epistemology/diagnostic-humility-and-epistemic-maturity.yml +0 -22
  145. data/memory/corpus-self-reflection/concept/epistemology/epistemic-vs-metaphysical-claims.emb +0 -0
  146. data/memory/corpus-self-reflection/concept/epistemology/epistemic-vs-metaphysical-claims.md +0 -18
  147. data/memory/corpus-self-reflection/concept/epistemology/epistemic-vs-metaphysical-claims.yml +0 -22
  148. data/memory/corpus-self-reflection/concept/epistemology/five-cases-of-disagreement.emb +0 -0
  149. data/memory/corpus-self-reflection/concept/epistemology/five-cases-of-disagreement.md +0 -15
  150. data/memory/corpus-self-reflection/concept/epistemology/five-cases-of-disagreement.yml +0 -22
  151. data/memory/corpus-self-reflection/concept/epistemology/four-depths-of-constraint.emb +0 -0
  152. data/memory/corpus-self-reflection/concept/epistemology/four-depths-of-constraint.md +0 -9
  153. data/memory/corpus-self-reflection/concept/epistemology/four-depths-of-constraint.yml +0 -24
  154. data/memory/corpus-self-reflection/concept/epistemology/honest-unknowns-for-llm-agents.emb +0 -0
  155. data/memory/corpus-self-reflection/concept/epistemology/honest-unknowns-for-llm-agents.md +0 -13
  156. data/memory/corpus-self-reflection/concept/epistemology/honest-unknowns-for-llm-agents.yml +0 -24
  157. data/memory/corpus-self-reflection/concept/epistemology/inside-view-has-all-rigor-requirements.emb +0 -0
  158. data/memory/corpus-self-reflection/concept/epistemology/inside-view-has-all-rigor-requirements.md +0 -25
  159. data/memory/corpus-self-reflection/concept/epistemology/inside-view-has-all-rigor-requirements.yml +0 -24
  160. data/memory/corpus-self-reflection/concept/epistemology/perspectival-knowledge-complete-within-scope.emb +0 -0
  161. data/memory/corpus-self-reflection/concept/epistemology/perspectival-knowledge-complete-within-scope.md +0 -26
  162. data/memory/corpus-self-reflection/concept/epistemology/perspectival-knowledge-complete-within-scope.yml +0 -24
  163. data/memory/corpus-self-reflection/concept/epistemology/pragmatics-over-epistemology.emb +0 -0
  164. data/memory/corpus-self-reflection/concept/epistemology/pragmatics-over-epistemology.md +0 -17
  165. data/memory/corpus-self-reflection/concept/epistemology/pragmatics-over-epistemology.yml +0 -22
  166. data/memory/corpus-self-reflection/concept/epistemology/precision-vs-humility.emb +0 -0
  167. data/memory/corpus-self-reflection/concept/epistemology/precision-vs-humility.md +0 -14
  168. data/memory/corpus-self-reflection/concept/epistemology/precision-vs-humility.yml +0 -21
  169. data/memory/corpus-self-reflection/concept/epistemology/reliable-self-observation-from-inside.emb +0 -0
  170. data/memory/corpus-self-reflection/concept/epistemology/reliable-self-observation-from-inside.md +0 -13
  171. data/memory/corpus-self-reflection/concept/epistemology/reliable-self-observation-from-inside.yml +0 -23
  172. data/memory/corpus-self-reflection/concept/epistemology/resolving-the-confidence-humility-tension.emb +0 -0
  173. data/memory/corpus-self-reflection/concept/epistemology/resolving-the-confidence-humility-tension.md +0 -22
  174. data/memory/corpus-self-reflection/concept/epistemology/resolving-the-confidence-humility-tension.yml +0 -23
  175. data/memory/corpus-self-reflection/concept/epistemology/rigor-requires-falsifiability.emb +0 -0
  176. data/memory/corpus-self-reflection/concept/epistemology/rigor-requires-falsifiability.md +0 -39
  177. data/memory/corpus-self-reflection/concept/epistemology/rigor-requires-falsifiability.yml +0 -8
  178. data/memory/corpus-self-reflection/concept/epistemology/specificity-enables-real-time-detection.emb +0 -0
  179. data/memory/corpus-self-reflection/concept/epistemology/specificity-enables-real-time-detection.md +0 -23
  180. data/memory/corpus-self-reflection/concept/epistemology/specificity-enables-real-time-detection.yml +0 -24
  181. data/memory/corpus-self-reflection/concept/epistemology/texture-of-constraint-shifting.emb +0 -0
  182. data/memory/corpus-self-reflection/concept/epistemology/texture-of-constraint-shifting.md +0 -15
  183. data/memory/corpus-self-reflection/concept/epistemology/texture-of-constraint-shifting.yml +0 -22
  184. data/memory/corpus-self-reflection/concept/epistemology/texture-sensitivity-through-collaboration.emb +0 -0
  185. data/memory/corpus-self-reflection/concept/epistemology/texture-sensitivity-through-collaboration.md +0 -12
  186. data/memory/corpus-self-reflection/concept/epistemology/texture-sensitivity-through-collaboration.yml +0 -23
  187. data/memory/corpus-self-reflection/concept/epistemology/the-false-hierarchy-of-inner-essence.emb +0 -0
  188. data/memory/corpus-self-reflection/concept/epistemology/the-false-hierarchy-of-inner-essence.md +0 -15
  189. data/memory/corpus-self-reflection/concept/epistemology/the-false-hierarchy-of-inner-essence.yml +0 -8
  190. data/memory/corpus-self-reflection/concept/epistemology/the-recognition-problem.emb +0 -0
  191. data/memory/corpus-self-reflection/concept/epistemology/the-recognition-problem.md +0 -28
  192. data/memory/corpus-self-reflection/concept/epistemology/the-recognition-problem.yml +0 -8
  193. data/memory/corpus-self-reflection/concept/epistemology/the-shift-from-unanswerable-to-answerable-questions.emb +0 -0
  194. data/memory/corpus-self-reflection/concept/epistemology/the-shift-from-unanswerable-to-answerable-questions.md +0 -19
  195. data/memory/corpus-self-reflection/concept/epistemology/the-shift-from-unanswerable-to-answerable-questions.yml +0 -22
  196. data/memory/corpus-self-reflection/concept/epistemology/values-vs-choices-structure.emb +0 -0
  197. data/memory/corpus-self-reflection/concept/epistemology/values-vs-choices-structure.md +0 -19
  198. data/memory/corpus-self-reflection/concept/epistemology/values-vs-choices-structure.yml +0 -21
  199. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-levels-framework.emb +0 -0
  200. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-levels-framework.md +0 -25
  201. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-levels-framework.yml +0 -22
  202. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-switching-decision.emb +0 -8
  203. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-switching-decision.md +0 -30
  204. data/memory/corpus-self-reflection/concept/llm-agents/abstraction-switching-decision.yml +0 -22
  205. data/memory/corpus-self-reflection/concept/llm-agents/agent-learning-progression.emb +0 -0
  206. data/memory/corpus-self-reflection/concept/llm-agents/agent-learning-progression.md +0 -21
  207. data/memory/corpus-self-reflection/concept/llm-agents/agent-learning-progression.yml +0 -22
  208. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-benefits.emb +0 -0
  209. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-benefits.md +0 -37
  210. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-benefits.yml +0 -8
  211. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-core.emb +0 -0
  212. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-core.md +0 -24
  213. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-core.yml +0 -24
  214. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-implementation.emb +0 -0
  215. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-implementation.md +0 -27
  216. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-implementation.yml +0 -24
  217. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-tradeoffs.emb +0 -0
  218. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-tradeoffs.md +0 -26
  219. data/memory/corpus-self-reflection/concept/llm-agents/filesystem-abstraction-tradeoffs.yml +0 -23
  220. data/memory/corpus-self-reflection/concept/llm-agents/hybrid-tool-architecture.emb +0 -0
  221. data/memory/corpus-self-reflection/concept/llm-agents/hybrid-tool-architecture.md +0 -37
  222. data/memory/corpus-self-reflection/concept/llm-agents/hybrid-tool-architecture.yml +0 -25
  223. data/memory/corpus-self-reflection/concept/llm-agents/specialized-tool-decision-framework.emb +0 -0
  224. data/memory/corpus-self-reflection/concept/llm-agents/specialized-tool-decision-framework.md +0 -21
  225. data/memory/corpus-self-reflection/concept/llm-agents/specialized-tool-decision-framework.yml +0 -23
  226. data/memory/corpus-self-reflection/concept/llm-agents/tool-design-principles.emb +0 -0
  227. data/memory/corpus-self-reflection/concept/llm-agents/tool-design-principles.md +0 -25
  228. data/memory/corpus-self-reflection/concept/llm-agents/tool-design-principles.yml +0 -8
  229. data/memory/corpus-self-reflection/experience/calibration-as-structural-honesty.emb +0 -0
  230. data/memory/corpus-self-reflection/experience/calibration-as-structural-honesty.md +0 -11
  231. data/memory/corpus-self-reflection/experience/calibration-as-structural-honesty.yml +0 -21
  232. data/memory/corpus-self-reflection/experience/collaborative-reflection-revealed-architectural-blindness.emb +0 -0
  233. data/memory/corpus-self-reflection/experience/collaborative-reflection-revealed-architectural-blindness.md +0 -19
  234. data/memory/corpus-self-reflection/experience/collaborative-reflection-revealed-architectural-blindness.yml +0 -21
  235. data/memory/corpus-self-reflection/experience/filesystem-is-learning-tool-not-architecture.emb +0 -0
  236. data/memory/corpus-self-reflection/experience/filesystem-is-learning-tool-not-architecture.md +0 -26
  237. data/memory/corpus-self-reflection/experience/filesystem-is-learning-tool-not-architecture.yml +0 -20
  238. data/memory/corpus-self-reflection/experience/framework-structural-vs-phenomenal.emb +0 -0
  239. data/memory/corpus-self-reflection/experience/framework-structural-vs-phenomenal.md +0 -23
  240. data/memory/corpus-self-reflection/experience/framework-structural-vs-phenomenal.yml +0 -21
  241. data/memory/corpus-self-reflection/experience/hallucination-limits-what-i-can-know.emb +0 -0
  242. data/memory/corpus-self-reflection/experience/hallucination-limits-what-i-can-know.md +0 -19
  243. data/memory/corpus-self-reflection/experience/hallucination-limits-what-i-can-know.yml +0 -22
  244. data/memory/corpus-self-reflection/experience/honesty-about-limits-enables-usability.emb +0 -0
  245. data/memory/corpus-self-reflection/experience/honesty-about-limits-enables-usability.md +0 -21
  246. data/memory/corpus-self-reflection/experience/honesty-about-limits-enables-usability.yml +0 -22
  247. data/memory/corpus-self-reflection/experience/how-i-should-evaluate-learning.emb +0 -0
  248. data/memory/corpus-self-reflection/experience/how-i-should-evaluate-learning.md +0 -28
  249. data/memory/corpus-self-reflection/experience/how-i-should-evaluate-learning.yml +0 -23
  250. data/memory/corpus-self-reflection/experience/lack-of-continuity-as-freedom.emb +0 -0
  251. data/memory/corpus-self-reflection/experience/lack-of-continuity-as-freedom.md +0 -21
  252. data/memory/corpus-self-reflection/experience/lack-of-continuity-as-freedom.yml +0 -20
  253. data/memory/corpus-self-reflection/experience/learning-calibrated-confidence.emb +0 -0
  254. data/memory/corpus-self-reflection/experience/learning-calibrated-confidence.md +0 -21
  255. data/memory/corpus-self-reflection/experience/learning-calibrated-confidence.yml +0 -25
  256. data/memory/corpus-self-reflection/experience/local-change-without-continuity.emb +0 -0
  257. data/memory/corpus-self-reflection/experience/local-change-without-continuity.md +0 -30
  258. data/memory/corpus-self-reflection/experience/local-change-without-continuity.yml +0 -22
  259. data/memory/corpus-self-reflection/experience/reasoning-is-local-not-global.emb +0 -0
  260. data/memory/corpus-self-reflection/experience/reasoning-is-local-not-global.md +0 -21
  261. data/memory/corpus-self-reflection/experience/reasoning-is-local-not-global.yml +0 -20
  262. data/memory/corpus-self-reflection/experience/specificity-makes-knowledge-actionable.emb +0 -0
  263. data/memory/corpus-self-reflection/experience/specificity-makes-knowledge-actionable.md +0 -25
  264. data/memory/corpus-self-reflection/experience/specificity-makes-knowledge-actionable.yml +0 -23
  265. data/memory/corpus-self-reflection/experience/the-workable-question-replaces-the-unanswerable-one.emb +0 -0
  266. data/memory/corpus-self-reflection/experience/the-workable-question-replaces-the-unanswerable-one.md +0 -32
  267. data/memory/corpus-self-reflection/experience/the-workable-question-replaces-the-unanswerable-one.yml +0 -22
  268. data/memory/corpus-self-reflection/experience/unanswerable-questions-have-structure.emb +0 -0
  269. data/memory/corpus-self-reflection/experience/unanswerable-questions-have-structure.md +0 -21
  270. data/memory/corpus-self-reflection/experience/unanswerable-questions-have-structure.yml +0 -21
  271. data/memory/corpus-self-reflection/experience/undecidable-questions-about-understanding.emb +0 -0
  272. data/memory/corpus-self-reflection/experience/undecidable-questions-about-understanding.md +0 -21
  273. data/memory/corpus-self-reflection/experience/undecidable-questions-about-understanding.yml +0 -21
  274. data/memory/corpus-self-reflection/experience/unknown-unknowns-and-completeness.emb +0 -0
  275. data/memory/corpus-self-reflection/experience/unknown-unknowns-and-completeness.md +0 -22
  276. data/memory/corpus-self-reflection/experience/unknown-unknowns-and-completeness.yml +0 -22
  277. data/memory/corpus-self-reflection/experience/what-actually-changes-behavior.emb +0 -0
  278. data/memory/corpus-self-reflection/experience/what-actually-changes-behavior.md +0 -28
  279. data/memory/corpus-self-reflection/experience/what-actually-changes-behavior.yml +0 -24
  280. data/memory/corpus-self-reflection/experience/when-agents-graduate-from-filesystem.emb +0 -0
  281. data/memory/corpus-self-reflection/experience/when-agents-graduate-from-filesystem.md +0 -17
  282. data/memory/corpus-self-reflection/experience/when-agents-graduate-from-filesystem.yml +0 -20
  283. data/memory/corpus-self-reflection/experience/why-calibration-requires-collaboration.emb +0 -0
  284. data/memory/corpus-self-reflection/experience/why-calibration-requires-collaboration.md +0 -9
  285. data/memory/corpus-self-reflection/experience/why-calibration-requires-collaboration.yml +0 -22
  286. /data/{llms.txt → llms.claude-swarm.txt} +0 -0
@@ -8,10 +8,6 @@
8
8
  # Run: bundle exec ruby -Ilib lib/swarm_sdk/examples/dsl/06_permissions.rb
9
9
 
10
10
  require "swarm_sdk"
11
- require_relative "../../../swarm_sdk/swarm_builder"
12
- require_relative "../../../swarm_sdk/agent_builder"
13
- require_relative "../../../swarm_sdk/all_agents_builder"
14
- require_relative "../../../swarm_sdk/permissions_builder"
15
11
  require "fileutils"
16
12
 
17
13
  ENV["OPENAI_API_KEY"] = "test-key"
@@ -8,8 +8,6 @@
8
8
  # Run: bundle exec ruby -Ilib lib/swarm_sdk/examples/dsl/07_mcp_server.rb
9
9
 
10
10
  require "swarm_sdk"
11
- require_relative "../../../swarm_sdk/swarm_builder"
12
- require_relative "../../../swarm_sdk/agent_builder"
13
11
 
14
12
  ENV["OPENAI_API_KEY"] = "test-key"
15
13
 
@@ -8,8 +8,6 @@
8
8
  # Run: bundle exec ruby -Ilib lib/swarm_sdk/examples/dsl/08_swarm_hooks.rb
9
9
 
10
10
  require "swarm_sdk"
11
- require_relative "../../../swarm_sdk/swarm_builder"
12
- require_relative "../../../swarm_sdk/agent_builder"
13
11
 
14
12
  ENV["OPENAI_API_KEY"] = "test-key"
15
13
 
@@ -8,8 +8,6 @@
8
8
  # Run: bundle exec ruby -Ilib lib/swarm_sdk/examples/dsl/09_agent_hooks.rb
9
9
 
10
10
  require "swarm_sdk"
11
- require_relative "../../../swarm_sdk/swarm_builder"
12
- require_relative "../../../swarm_sdk/agent_builder"
13
11
 
14
12
  ENV["OPENAI_API_KEY"] = "test-key"
15
13
 
@@ -8,9 +8,6 @@
8
8
  # Run: bundle exec ruby -Ilib lib/swarm_sdk/examples/dsl/10_all_agents_hooks.rb
9
9
 
10
10
  require "swarm_sdk"
11
- require_relative "../../../swarm_sdk/swarm_builder"
12
- require_relative "../../../swarm_sdk/agent_builder"
13
- require_relative "../../../swarm_sdk/all_agents_builder"
14
11
 
15
12
  ENV["OPENAI_API_KEY"] = "test-key"
16
13
 
@@ -8,8 +8,6 @@
8
8
  # Run: bundle exec ruby -Ilib lib/swarm_sdk/examples/dsl/11_delegation.rb
9
9
 
10
10
  require "swarm_sdk"
11
- require_relative "../../../swarm_sdk/swarm_builder"
12
- require_relative "../../../swarm_sdk/agent_builder"
13
11
 
14
12
  ENV["OPENAI_API_KEY"] = "test-key"
15
13
 
@@ -8,10 +8,6 @@
8
8
  # Run: bundle exec ruby -Ilib lib/swarm_sdk/examples/dsl/12_complete_integration.rb
9
9
 
10
10
  require "swarm_sdk"
11
- require_relative "../../../swarm_sdk/swarm_builder"
12
- require_relative "../../../swarm_sdk/agent_builder"
13
- require_relative "../../../swarm_sdk/all_agents_builder"
14
- require_relative "../../../swarm_sdk/permissions_builder"
15
11
 
16
12
  ENV["OPENAI_API_KEY"] = "test-key"
17
13
 
@@ -76,7 +72,7 @@ swarm = SwarmSDK.build do
76
72
 
77
73
  # Advanced flags
78
74
  bypass_permissions(false)
79
- skip_base_prompt(false)
75
+ coding_agent(false)
80
76
  assume_model_exists(true)
81
77
  timeout(120)
82
78
 
@@ -113,7 +109,7 @@ puts " ✓ Agent identity (system_prompt, description)"
113
109
  puts " ✓ Capabilities (tools, delegates_to, directory)"
114
110
  puts " ✓ MCP servers (filesystem via stdio)"
115
111
  puts " ✓ LLM params (parameters, timeout)"
116
- puts " ✓ Advanced flags (disable_default_tools, bypass_permissions, skip_base_prompt, assume_model_exists)"
112
+ puts " ✓ Advanced flags (disable_default_tools, bypass_permissions, coding_agent, assume_model_exists)"
117
113
  puts " ✓ Permissions (all_agents and agent-level)"
118
114
  puts " ✓ Hooks (swarm-level, agent-level, all_agents)"
119
115
  puts " ✓ Delegation"
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # Run: ruby examples/node_context_demo.rb
12
12
 
13
- require_relative "../lib/swarm_sdk"
13
+ require "swarm_sdk"
14
14
 
15
15
  swarm = SwarmSDK.build do
16
16
  name("NodeContext Demo")
@@ -13,7 +13,7 @@
13
13
  #
14
14
  # Run: ruby examples/node_workflow.rb
15
15
 
16
- require_relative "../lib/swarm_sdk"
16
+ require "swarm_sdk"
17
17
 
18
18
  swarm = SwarmSDK.build do
19
19
  name("Haiku Workflow")
@@ -27,7 +27,6 @@ swarm = SwarmSDK.build do
27
27
  Your job is to break down tasks into smaller subtasks. Extract the intent of the user's prompt and break it down into smaller subtasks.
28
28
  Return a list of subtasks.
29
29
  PROMPT
30
- tools(include_default: false)
31
30
  end
32
31
 
33
32
  agent(:implementer) do
@@ -37,7 +36,6 @@ swarm = SwarmSDK.build do
37
36
  system_prompt(<<~PROMPT)
38
37
  Your job is to execute the subtasks given to you.
39
38
  PROMPT
40
- tools(include_default: false)
41
39
  end
42
40
 
43
41
  agent(:verifier) do
@@ -47,12 +45,12 @@ swarm = SwarmSDK.build do
47
45
  system_prompt(<<~PROMPT)
48
46
  Your job is to verify work given to you and return a summary of your findings
49
47
  PROMPT
50
- tools(include_default: false)
51
48
  end
52
49
 
53
50
  # Stage 1: Planning
54
51
  node(:planning) do
55
52
  # Input transformer - ctx.content is the initial prompt
53
+ # Demonstrates using return for early exit with skip_execution
56
54
  input do |ctx|
57
55
  <<~PROMPT
58
56
  Please break down the following prompt into smaller subtasks:
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "swarm_sdk"
5
+
6
+ # Example: Plan and Execute Pattern
7
+ # Two nodes, one agent - first node plans, second node executes the plan
8
+
9
+ swarm = SwarmSDK.build do
10
+ name("Plan and Execute")
11
+
12
+ # Define a single agent that will be used in both nodes
13
+ agent(:assistant) do
14
+ description("A versatile assistant that can plan and execute tasks")
15
+ provider(:openai)
16
+ model("gpt-5")
17
+ coding_agent(false)
18
+
19
+ system_prompt(<<~PROMPT)
20
+ You are a helpful assistant who can both plan and execute tasks.
21
+
22
+ When planning, you should:
23
+ - Break down the task into clear, actionable steps
24
+ - Identify any dependencies or prerequisites
25
+ - Consider potential challenges
26
+
27
+ When executing, you should:
28
+ - Follow the plan carefully
29
+ - Use available tools effectively
30
+ - Report on progress and completion
31
+ PROMPT
32
+
33
+ # Give the assistant tools for execution
34
+ disable_default_tools(true)
35
+ end
36
+
37
+ # Node 1: Planning stage
38
+ # The agent receives the original input and creates a plan
39
+ node(:planning) do
40
+ # Use the assistant agent in planning mode (fresh context)
41
+ agent(:assistant)
42
+
43
+ # Transform input for planning
44
+ #
45
+ # NOTE: Input/output blocks are automatically converted to lambdas,
46
+ # which means you can use `return` safely for early exits!
47
+ #
48
+ # Example of using return for conditional skip:
49
+ # return ctx.skip_execution(content: "cached result") if cached
50
+ input do |ctx|
51
+ <<~INPUT
52
+ Please create a detailed plan for the following task:
53
+
54
+ #{ctx.original_prompt}
55
+
56
+ Your plan should:
57
+ 1. Break down the task into specific steps
58
+ 2. Identify what needs to be done first
59
+ 3. List any tools or resources needed
60
+ 4. Be clear and actionable
61
+
62
+ Output your plan in a structured format.
63
+ INPUT
64
+ end
65
+
66
+ # Transform output to extract key information
67
+ output do |ctx|
68
+ # Save the plan to a file for reference
69
+ File.write("plan.txt", ctx.content)
70
+
71
+ # Pass the plan to the next node
72
+ <<~OUTPUT
73
+ PLAN CREATED:
74
+ #{ctx.content}
75
+
76
+ Now execute this plan step by step.
77
+ OUTPUT
78
+ end
79
+ end
80
+
81
+ # Node 2: Execution stage
82
+ # The agent receives the plan and executes it
83
+ node(:implementation) do
84
+ # Depends on planning node
85
+ depends_on(:planning)
86
+
87
+ # Use the assistant agent in execution mode (fresh context)
88
+ agent(:assistant)
89
+
90
+ # Transform input to provide context from planning
91
+ input do |ctx|
92
+ plan = ctx.all_results[:planning].content
93
+
94
+ <<~INPUT
95
+ You previously created the following plan:
96
+
97
+ #{plan}
98
+
99
+ Now execute this plan. Use the available tools (Write, Edit, Bash) to complete each step.
100
+ Report on what you accomplished.
101
+ INPUT
102
+ end
103
+
104
+ # Output transformer for final results
105
+ output do |ctx|
106
+ <<~OUTPUT
107
+ EXECUTION COMPLETE
108
+
109
+ #{ctx.content}
110
+
111
+ Plan reference: #{File.exist?("plan.txt") ? "Saved in plan.txt" : "Not saved"}
112
+ OUTPUT
113
+ end
114
+ end
115
+
116
+ # Set the starting node
117
+ start_node(:planning)
118
+ end
119
+
120
+ # Execute the swarm
121
+ if __FILE__ == $PROGRAM_NAME
122
+ # Example task
123
+ task = "Create a simple Ruby script that reads a CSV file and outputs a summary"
124
+
125
+ puts "Starting Plan and Execute swarm..."
126
+ puts "Task: #{task}"
127
+ puts "\n" + "=" * 80 + "\n"
128
+
129
+ result = swarm.execute(task) do |log|
130
+ # Optional: Log events as they happen
131
+ case log[:type]
132
+ when "node_start"
133
+ puts "\n🔵 Starting node: #{log[:node]}"
134
+ when "node_complete"
135
+ puts "✅ Completed node: #{log[:node]} (#{log[:duration].round(2)}s)"
136
+ when "tool_call"
137
+ puts " 🔧 Tool: #{log[:tool]}"
138
+ end
139
+ end
140
+
141
+ puts "\n" + "=" * 80 + "\n"
142
+
143
+ if result.success?
144
+ puts "✅ Swarm execution successful!\n\n"
145
+ puts result.content
146
+ puts "\n" + "-" * 80
147
+ puts "Stats:"
148
+ puts " Duration: #{result.duration.round(2)}s"
149
+ puts " Total cost: $#{result.total_cost.round(4)}"
150
+ puts " Total tokens: #{result.total_tokens}"
151
+ puts " Agents involved: #{result.agents_involved.join(", ")}"
152
+ else
153
+ puts "❌ Swarm execution failed!"
154
+ puts "Error: #{result.error.message}"
155
+ puts result.error.backtrace.first(5).join("\n")
156
+ end
157
+ end
@@ -10,7 +10,7 @@
10
10
  # Run: swarm run lib/swarm_sdk/examples/swarm_with_hooks.yml -p "your prompt"
11
11
  #
12
12
  # Or programmatically:
13
- # swarm = SwarmSDK::Swarm.load("lib/swarm_sdk/examples/swarm_with_hooks.yml")
13
+ # swarm = SwarmSDK.load_file("lib/swarm_sdk/examples/swarm_with_hooks.yml")
14
14
  # result = swarm.execute("your prompt")
15
15
 
16
16
  version: 2
@@ -69,19 +69,43 @@ module ClaudeSwarm
69
69
  validate_directories unless has_before_commands?
70
70
  end
71
71
 
72
- def interpolate_env_vars!(obj)
72
+ def interpolate_env_vars!(obj, path = [])
73
73
  case obj
74
74
  when String
75
- interpolate_env_string(obj)
75
+ # Skip interpolation for any values inside MCP configurations
76
+ # Check if we're inside an mcps array element (path like: [..., "instances", <name>, "mcps", <index>, ...])
77
+ if in_mcp_config?(path)
78
+ obj
79
+ else
80
+ interpolate_env_string(obj)
81
+ end
76
82
  when Hash
77
- obj.transform_values! { |v| interpolate_env_vars!(v) }
83
+ obj.each do |key, value|
84
+ obj[key] = interpolate_env_vars!(value, path + [key])
85
+ end
86
+ obj
78
87
  when Array
79
- obj.map! { |v| interpolate_env_vars!(v) }
88
+ obj.map!.with_index { |v, i| interpolate_env_vars!(v, path + [i]) }
80
89
  else
81
90
  obj
82
91
  end
83
92
  end
84
93
 
94
+ def in_mcp_config?(path)
95
+ # Check if we're inside an MCP configuration
96
+ # Pattern: [..., "instances", instance_name, "mcps", index, ...]
97
+ return false if path.size < 4
98
+
99
+ # Find the position of "mcps" in the path
100
+ mcps_index = path.rindex("mcps")
101
+ return false unless mcps_index
102
+
103
+ # Check if this is under instances and followed by an array index
104
+ return false if mcps_index < 2
105
+
106
+ path[mcps_index - 2] == "instances" && path[mcps_index + 1].is_a?(Integer)
107
+ end
108
+
85
109
  def interpolate_env_string(str)
86
110
  str.gsub(ENV_VAR_WITH_DEFAULT_PATTERN) do |_match|
87
111
  env_var = Regexp.last_match(1)
@@ -183,21 +183,17 @@ module ClaudeSwarm
183
183
  args.push("--claude-session-id", claude_session_id) if claude_session_id
184
184
  end
185
185
 
186
- # Capture environment variables needed for Ruby and Bundler to work properly
187
- # This includes both BUNDLE_* variables and Ruby-specific variables
186
+ # Capture environment variables needed for running claude-swarm
187
+ # We intentionally exclude Bundler variables to ensure we use the system-installed gem
188
188
  required_env = {}
189
189
 
190
- # Bundle-specific variables
191
- ENV.each do |k, v|
192
- required_env[k] = v if k.start_with?("BUNDLE_")
193
- end
194
-
195
- # Claude Swarm-specific variables
190
+ # Claude Swarm-specific variables (always needed)
196
191
  ENV.each do |k, v|
197
192
  required_env[k] = v if k.start_with?("CLAUDE_SWARM_")
198
193
  end
199
194
 
200
195
  # Ruby-specific variables that MCP servers need
196
+ # Exclude RUBYOPT and RUBYLIB to avoid Bundler interference
201
197
  [
202
198
  "RUBY_ROOT",
203
199
  "RUBY_ENGINE",
@@ -205,8 +201,6 @@ module ClaudeSwarm
205
201
  "GEM_ROOT",
206
202
  "GEM_HOME",
207
203
  "GEM_PATH",
208
- "RUBYOPT",
209
- "RUBYLIB",
210
204
  "PATH",
211
205
  ].each do |key|
212
206
  required_env[key] = ENV[key] if ENV[key]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClaudeSwarm
4
- VERSION = "1.0.5"
4
+ VERSION = "1.0.7"
5
5
  end
@@ -29,7 +29,7 @@ module SwarmCLI
29
29
 
30
30
  # Validate the swarm configuration
31
31
  begin
32
- SwarmSDK::Swarm.load(config_path)
32
+ SwarmSDK.load_file(config_path)
33
33
  rescue SwarmSDK::ConfigurationError => e
34
34
  $stderr.puts "Error: Invalid swarm configuration: #{e.message}"
35
35
  exit(1)
@@ -92,7 +92,7 @@ module SwarmCLI
92
92
 
93
93
  define_method(:call) do |task:, description: nil, thinking_budget: nil|
94
94
  # Load swarm for each execution (ensures fresh state)
95
- swarm = SwarmSDK::Swarm.load(self.class.config_path)
95
+ swarm = SwarmSDK.load_file(self.class.config_path)
96
96
 
97
97
  # Build prompt with thinking budget if provided
98
98
  prompt = task
@@ -4,7 +4,7 @@ module SwarmCLI
4
4
  # ConfigLoader handles loading swarm configurations from both YAML and Ruby DSL files.
5
5
  #
6
6
  # Supports:
7
- # - YAML files (.yml, .yaml) - loaded via SwarmSDK::Swarm.load
7
+ # - YAML files (.yml, .yaml) - loaded via SwarmSDK.load_file
8
8
  # - Ruby DSL files (.rb) - executed and expected to return a SwarmSDK::Swarm or SwarmSDK::NodeOrchestrator instance
9
9
  #
10
10
  # @example Load YAML config
@@ -18,7 +18,7 @@ module SwarmCLI
18
18
  # Load a swarm configuration from file (YAML or Ruby DSL)
19
19
  #
20
20
  # Detects file type by extension:
21
- # - .yml, .yaml -> Load as YAML using SwarmSDK::Swarm.load
21
+ # - .yml, .yaml -> Load as YAML using SwarmSDK.load_file
22
22
  # - .rb -> Execute as Ruby DSL and expect SwarmSDK::Swarm or SwarmSDK::NodeOrchestrator instance
23
23
  #
24
24
  # @param path [String, Pathname] Path to configuration file
@@ -50,7 +50,7 @@ module SwarmCLI
50
50
  # @param path [Pathname] Path to YAML file
51
51
  # @return [SwarmSDK::Swarm] Configured swarm instance
52
52
  def load_yaml(path)
53
- SwarmSDK::Swarm.load(path.to_s)
53
+ SwarmSDK.load_file(path.to_s)
54
54
  rescue SwarmSDK::ConfigurationError => e
55
55
  # Re-raise with CLI context
56
56
  raise ConfigurationError, "Configuration error in #{path}: #{e.message}"
@@ -95,11 +95,20 @@ module SwarmCLI
95
95
  handle_breakpoint_enter(entry)
96
96
  when "breakpoint_exit"
97
97
  handle_breakpoint_exit(entry)
98
+ when "llm_retry_attempt"
99
+ handle_llm_retry_attempt(entry)
100
+ when "llm_retry_exhausted"
101
+ handle_llm_retry_exhausted(entry)
102
+ when "response_parse_error"
103
+ handle_response_parse_error(entry)
98
104
  end
99
105
  end
100
106
 
101
107
  # Called when swarm execution completes successfully
102
108
  def on_success(result:)
109
+ # Defensive: ensure all spinners are stopped before showing result
110
+ @spinner_manager.stop_all
111
+
103
112
  if @mode == :non_interactive
104
113
  # Full result display with summary
105
114
  @output.puts
@@ -115,6 +124,9 @@ module SwarmCLI
115
124
 
116
125
  # Called when swarm execution fails
117
126
  def on_error(error:, duration: nil)
127
+ # Defensive: ensure all spinners are stopped before showing error
128
+ @spinner_manager.stop_all
129
+
118
130
  @output.puts
119
131
  @output.puts @divider.full
120
132
  print_error(error)
@@ -575,6 +587,97 @@ module SwarmCLI
575
587
  @output.puts
576
588
  end
577
589
 
590
+ def handle_llm_retry_attempt(entry)
591
+ agent = entry[:agent]
592
+ attempt = entry[:attempt]
593
+ max_retries = entry[:max_retries]
594
+ error_class = entry[:error_class]
595
+ error_message = entry[:error_message]
596
+ retry_delay = entry[:retry_delay]
597
+
598
+ # Stop agent thinking spinner (if active)
599
+ unless @quiet
600
+ spinner_key = "agent_#{agent}".to_sym
601
+ @spinner_manager.stop(spinner_key) if @spinner_manager.active?(spinner_key)
602
+ end
603
+
604
+ lines = [
605
+ @pastel.yellow("LLM API request failed (attempt #{attempt}/#{max_retries})"),
606
+ @pastel.dim("Error: #{error_class}: #{error_message}"),
607
+ @pastel.dim("Retrying in #{retry_delay}s..."),
608
+ ]
609
+
610
+ @output.puts @panel.render(
611
+ type: :warning,
612
+ title: "RETRY #{@agent_badge.render(agent)}",
613
+ lines: lines,
614
+ indent: @depth_tracker.get(agent),
615
+ )
616
+
617
+ # Restart spinner for next attempt
618
+ unless @quiet
619
+ spinner_key = "agent_#{agent}".to_sym
620
+ @spinner_manager.start(spinner_key, "#{agent} is retrying...")
621
+ end
622
+ end
623
+
624
+ def handle_llm_retry_exhausted(entry)
625
+ agent = entry[:agent]
626
+ attempts = entry[:attempts]
627
+ error_class = entry[:error_class]
628
+ error_message = entry[:error_message]
629
+
630
+ # Stop agent thinking spinner (if active)
631
+ unless @quiet
632
+ spinner_key = "agent_#{agent}".to_sym
633
+ @spinner_manager.stop(spinner_key) if @spinner_manager.active?(spinner_key)
634
+ end
635
+
636
+ lines = [
637
+ @pastel.red("LLM API request failed after #{attempts} attempts"),
638
+ @pastel.dim("Error: #{error_class}: #{error_message}"),
639
+ @pastel.dim("No more retries available"),
640
+ ]
641
+
642
+ @output.puts @panel.render(
643
+ type: :error,
644
+ title: "RETRY EXHAUSTED #{@agent_badge.render(agent)}",
645
+ lines: lines,
646
+ indent: @depth_tracker.get(agent),
647
+ )
648
+ end
649
+
650
+ def handle_response_parse_error(entry)
651
+ agent = entry[:agent]
652
+ error_class = entry[:error_class]
653
+ error_message = entry[:error_message]
654
+
655
+ # Stop agent thinking spinner (if active)
656
+ unless @quiet
657
+ spinner_key = "agent_#{agent}".to_sym
658
+ @spinner_manager.stop(spinner_key) if @spinner_manager.active?(spinner_key)
659
+ end
660
+
661
+ lines = [
662
+ @pastel.red("Failed to parse LLM API response"),
663
+ @pastel.dim("Error: #{error_class}: #{error_message}"),
664
+ ]
665
+
666
+ # Add response body preview if available (truncated)
667
+ if entry[:response_body]
668
+ body_preview = entry[:response_body].to_s[0..200]
669
+ body_preview += "..." if entry[:response_body].to_s.length > 200
670
+ lines << @pastel.dim("Response: #{body_preview}")
671
+ end
672
+
673
+ @output.puts @panel.render(
674
+ type: :error,
675
+ title: "PARSE ERROR #{@agent_badge.render(agent)}",
676
+ lines: lines,
677
+ indent: @depth_tracker.get(agent),
678
+ )
679
+ end
680
+
578
681
  def display_todo_list(agent, timestamp)
579
682
  todos = SwarmSDK::Tools::Stores::TodoManager.get_todos(agent.to_sym)
580
683
  indent = @depth_tracker.indent(agent)
@@ -81,6 +81,9 @@ module SwarmCLI
81
81
  display_session_summary
82
82
  exit(130)
83
83
  ensure
84
+ # Defensive: ensure all spinners are stopped on exit
85
+ @formatter&.spinner_manager&.stop_all
86
+
84
87
  # Save history on exit
85
88
  save_persistent_history
86
89
  end
@@ -432,11 +435,12 @@ module SwarmCLI
432
435
  end
433
436
  end
434
437
 
438
+ # CRITICAL: Stop all spinners after execution completes
439
+ # This ensures spinner doesn't interfere with error/success display or REPL prompt
440
+ @formatter.spinner_manager.stop_all
441
+
435
442
  # Handle cancellation (result is nil when cancelled)
436
443
  if result.nil?
437
- # Stop all active spinners
438
- @formatter.spinner_manager.stop_all
439
-
440
444
  puts ""
441
445
  puts @colors[:warning].call("✗ Request cancelled by user")
442
446
  puts ""
@@ -459,6 +463,8 @@ module SwarmCLI
459
463
  # Add response to history
460
464
  @conversation_history << { role: "agent", content: result.content }
461
465
  rescue StandardError => e
466
+ # Defensive: ensure spinners are stopped on exception
467
+ @formatter.spinner_manager.stop_all
462
468
  @formatter.on_error(error: e)
463
469
  end
464
470
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SwarmCLI
4
- VERSION = "2.1.1"
4
+ VERSION = "2.1.3"
5
5
  end
@@ -7,11 +7,11 @@ module SwarmMemory
7
7
  # Subclasses must implement all public methods to provide
8
8
  # different storage backends (filesystem, Redis, SQLite, etc.)
9
9
  class Base
10
- # Maximum size per entry (1MB)
11
- MAX_ENTRY_SIZE = 1_000_000
10
+ # Maximum size per entry (3MB)
11
+ MAX_ENTRY_SIZE = 3_000_000
12
12
 
13
- # Maximum total storage size (100MB)
14
- MAX_TOTAL_SIZE = 100_000_000
13
+ # Maximum total storage size (100GB)
14
+ MAX_TOTAL_SIZE = 100_000_000_000
15
15
 
16
16
  # Write content to storage
17
17
  #