swarm_sdk 2.7.13 → 3.0.0.alpha1

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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb +43 -22
  3. data/lib/swarm_sdk/ruby_llm_patches/init.rb +6 -0
  4. data/lib/swarm_sdk/ruby_llm_patches/mcp_ssl_patch.rb +144 -0
  5. data/lib/swarm_sdk/ruby_llm_patches/tool_concurrency_patch.rb +3 -4
  6. data/lib/swarm_sdk/v3/agent.rb +1165 -0
  7. data/lib/swarm_sdk/v3/agent_builder.rb +533 -0
  8. data/lib/swarm_sdk/v3/agent_definition.rb +330 -0
  9. data/lib/swarm_sdk/v3/configuration.rb +490 -0
  10. data/lib/swarm_sdk/v3/debug_log.rb +86 -0
  11. data/lib/swarm_sdk/v3/event_stream.rb +130 -0
  12. data/lib/swarm_sdk/v3/hooks/context.rb +112 -0
  13. data/lib/swarm_sdk/v3/hooks/result.rb +115 -0
  14. data/lib/swarm_sdk/v3/hooks/runner.rb +128 -0
  15. data/lib/swarm_sdk/v3/mcp/connector.rb +183 -0
  16. data/lib/swarm_sdk/v3/mcp/mcp_error.rb +15 -0
  17. data/lib/swarm_sdk/v3/mcp/server_definition.rb +125 -0
  18. data/lib/swarm_sdk/v3/mcp/ssl_http_transport.rb +103 -0
  19. data/lib/swarm_sdk/v3/mcp/stdio_transport.rb +135 -0
  20. data/lib/swarm_sdk/v3/mcp/tool_proxy.rb +53 -0
  21. data/lib/swarm_sdk/v3/memory/adapters/base.rb +297 -0
  22. data/lib/swarm_sdk/v3/memory/adapters/faiss_support.rb +194 -0
  23. data/lib/swarm_sdk/v3/memory/adapters/filesystem_adapter.rb +212 -0
  24. data/lib/swarm_sdk/v3/memory/adapters/sqlite_adapter.rb +507 -0
  25. data/lib/swarm_sdk/v3/memory/adapters/vector_utils.rb +88 -0
  26. data/lib/swarm_sdk/v3/memory/card.rb +206 -0
  27. data/lib/swarm_sdk/v3/memory/cluster.rb +146 -0
  28. data/lib/swarm_sdk/v3/memory/compressor.rb +496 -0
  29. data/lib/swarm_sdk/v3/memory/consolidator.rb +427 -0
  30. data/lib/swarm_sdk/v3/memory/context_builder.rb +339 -0
  31. data/lib/swarm_sdk/v3/memory/edge.rb +105 -0
  32. data/lib/swarm_sdk/v3/memory/embedder.rb +185 -0
  33. data/lib/swarm_sdk/v3/memory/exposure_tracker.rb +104 -0
  34. data/lib/swarm_sdk/v3/memory/ingestion_pipeline.rb +394 -0
  35. data/lib/swarm_sdk/v3/memory/retriever.rb +289 -0
  36. data/lib/swarm_sdk/v3/memory/store.rb +489 -0
  37. data/lib/swarm_sdk/v3/skills/loader.rb +147 -0
  38. data/lib/swarm_sdk/v3/skills/manifest.rb +45 -0
  39. data/lib/swarm_sdk/v3/sub_task_agent.rb +248 -0
  40. data/lib/swarm_sdk/v3/tools/base.rb +80 -0
  41. data/lib/swarm_sdk/v3/tools/bash.rb +174 -0
  42. data/lib/swarm_sdk/v3/tools/clock.rb +32 -0
  43. data/lib/swarm_sdk/v3/tools/edit.rb +111 -0
  44. data/lib/swarm_sdk/v3/tools/glob.rb +96 -0
  45. data/lib/swarm_sdk/v3/tools/grep.rb +200 -0
  46. data/lib/swarm_sdk/v3/tools/message_teammate.rb +15 -0
  47. data/lib/swarm_sdk/v3/tools/message_user.rb +15 -0
  48. data/lib/swarm_sdk/v3/tools/read.rb +181 -0
  49. data/lib/swarm_sdk/v3/tools/read_tracker.rb +40 -0
  50. data/lib/swarm_sdk/v3/tools/registry.rb +208 -0
  51. data/lib/swarm_sdk/v3/tools/sub_task.rb +183 -0
  52. data/lib/swarm_sdk/v3/tools/think.rb +88 -0
  53. data/lib/swarm_sdk/v3/tools/write.rb +87 -0
  54. data/lib/swarm_sdk/v3.rb +145 -0
  55. metadata +84 -148
  56. data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -175
  57. data/lib/swarm_sdk/agent/builder.rb +0 -680
  58. data/lib/swarm_sdk/agent/chat.rb +0 -1432
  59. data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -375
  60. data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +0 -204
  61. data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +0 -480
  62. data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +0 -85
  63. data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -290
  64. data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +0 -116
  65. data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +0 -83
  66. data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +0 -134
  67. data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
  68. data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -146
  69. data/lib/swarm_sdk/agent/context.rb +0 -115
  70. data/lib/swarm_sdk/agent/context_manager.rb +0 -315
  71. data/lib/swarm_sdk/agent/definition.rb +0 -581
  72. data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -226
  73. data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -161
  74. data/lib/swarm_sdk/agent/tool_registry.rb +0 -189
  75. data/lib/swarm_sdk/agent_registry.rb +0 -146
  76. data/lib/swarm_sdk/builders/base_builder.rb +0 -553
  77. data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
  78. data/lib/swarm_sdk/concerns/cleanupable.rb +0 -39
  79. data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
  80. data/lib/swarm_sdk/concerns/validatable.rb +0 -55
  81. data/lib/swarm_sdk/config.rb +0 -367
  82. data/lib/swarm_sdk/configuration/parser.rb +0 -397
  83. data/lib/swarm_sdk/configuration/translator.rb +0 -283
  84. data/lib/swarm_sdk/configuration.rb +0 -165
  85. data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
  86. data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -102
  87. data/lib/swarm_sdk/context_compactor.rb +0 -335
  88. data/lib/swarm_sdk/context_management/builder.rb +0 -128
  89. data/lib/swarm_sdk/context_management/context.rb +0 -328
  90. data/lib/swarm_sdk/custom_tool_registry.rb +0 -226
  91. data/lib/swarm_sdk/defaults.rb +0 -251
  92. data/lib/swarm_sdk/events_to_messages.rb +0 -199
  93. data/lib/swarm_sdk/hooks/adapter.rb +0 -359
  94. data/lib/swarm_sdk/hooks/context.rb +0 -197
  95. data/lib/swarm_sdk/hooks/definition.rb +0 -80
  96. data/lib/swarm_sdk/hooks/error.rb +0 -29
  97. data/lib/swarm_sdk/hooks/executor.rb +0 -146
  98. data/lib/swarm_sdk/hooks/registry.rb +0 -147
  99. data/lib/swarm_sdk/hooks/result.rb +0 -150
  100. data/lib/swarm_sdk/hooks/shell_executor.rb +0 -256
  101. data/lib/swarm_sdk/hooks/tool_call.rb +0 -35
  102. data/lib/swarm_sdk/hooks/tool_result.rb +0 -62
  103. data/lib/swarm_sdk/log_collector.rb +0 -227
  104. data/lib/swarm_sdk/log_stream.rb +0 -127
  105. data/lib/swarm_sdk/markdown_parser.rb +0 -75
  106. data/lib/swarm_sdk/model_aliases.json +0 -8
  107. data/lib/swarm_sdk/models.json +0 -44002
  108. data/lib/swarm_sdk/models.rb +0 -161
  109. data/lib/swarm_sdk/node_context.rb +0 -245
  110. data/lib/swarm_sdk/observer/builder.rb +0 -81
  111. data/lib/swarm_sdk/observer/config.rb +0 -45
  112. data/lib/swarm_sdk/observer/manager.rb +0 -236
  113. data/lib/swarm_sdk/patterns/agent_observer.rb +0 -160
  114. data/lib/swarm_sdk/permissions/config.rb +0 -239
  115. data/lib/swarm_sdk/permissions/error_formatter.rb +0 -121
  116. data/lib/swarm_sdk/permissions/path_matcher.rb +0 -35
  117. data/lib/swarm_sdk/permissions/validator.rb +0 -173
  118. data/lib/swarm_sdk/permissions_builder.rb +0 -122
  119. data/lib/swarm_sdk/plugin.rb +0 -309
  120. data/lib/swarm_sdk/plugin_registry.rb +0 -101
  121. data/lib/swarm_sdk/proc_helpers.rb +0 -53
  122. data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -117
  123. data/lib/swarm_sdk/restore_result.rb +0 -65
  124. data/lib/swarm_sdk/result.rb +0 -212
  125. data/lib/swarm_sdk/snapshot.rb +0 -156
  126. data/lib/swarm_sdk/snapshot_from_events.rb +0 -397
  127. data/lib/swarm_sdk/state_restorer.rb +0 -476
  128. data/lib/swarm_sdk/state_snapshot.rb +0 -334
  129. data/lib/swarm_sdk/swarm/agent_initializer.rb +0 -648
  130. data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -195
  131. data/lib/swarm_sdk/swarm/builder.rb +0 -256
  132. data/lib/swarm_sdk/swarm/executor.rb +0 -290
  133. data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -151
  134. data/lib/swarm_sdk/swarm/lazy_delegate_chat.rb +0 -372
  135. data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -360
  136. data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -270
  137. data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
  138. data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -392
  139. data/lib/swarm_sdk/swarm.rb +0 -843
  140. data/lib/swarm_sdk/swarm_loader.rb +0 -145
  141. data/lib/swarm_sdk/swarm_registry.rb +0 -136
  142. data/lib/swarm_sdk/tools/base.rb +0 -63
  143. data/lib/swarm_sdk/tools/bash.rb +0 -280
  144. data/lib/swarm_sdk/tools/clock.rb +0 -46
  145. data/lib/swarm_sdk/tools/delegate.rb +0 -389
  146. data/lib/swarm_sdk/tools/document_converters/base_converter.rb +0 -83
  147. data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +0 -99
  148. data/lib/swarm_sdk/tools/document_converters/html_converter.rb +0 -101
  149. data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +0 -78
  150. data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +0 -194
  151. data/lib/swarm_sdk/tools/edit.rb +0 -145
  152. data/lib/swarm_sdk/tools/glob.rb +0 -166
  153. data/lib/swarm_sdk/tools/grep.rb +0 -235
  154. data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +0 -43
  155. data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +0 -167
  156. data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
  157. data/lib/swarm_sdk/tools/mcp_tool_stub.rb +0 -198
  158. data/lib/swarm_sdk/tools/multi_edit.rb +0 -236
  159. data/lib/swarm_sdk/tools/path_resolver.rb +0 -92
  160. data/lib/swarm_sdk/tools/read.rb +0 -261
  161. data/lib/swarm_sdk/tools/registry.rb +0 -205
  162. data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +0 -117
  163. data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +0 -97
  164. data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +0 -108
  165. data/lib/swarm_sdk/tools/stores/read_tracker.rb +0 -96
  166. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +0 -273
  167. data/lib/swarm_sdk/tools/stores/storage.rb +0 -142
  168. data/lib/swarm_sdk/tools/stores/todo_manager.rb +0 -65
  169. data/lib/swarm_sdk/tools/think.rb +0 -100
  170. data/lib/swarm_sdk/tools/todo_write.rb +0 -237
  171. data/lib/swarm_sdk/tools/web_fetch.rb +0 -264
  172. data/lib/swarm_sdk/tools/write.rb +0 -112
  173. data/lib/swarm_sdk/transcript_builder.rb +0 -278
  174. data/lib/swarm_sdk/utils.rb +0 -68
  175. data/lib/swarm_sdk/validation_result.rb +0 -33
  176. data/lib/swarm_sdk/version.rb +0 -5
  177. data/lib/swarm_sdk/workflow/agent_config.rb +0 -95
  178. data/lib/swarm_sdk/workflow/builder.rb +0 -227
  179. data/lib/swarm_sdk/workflow/executor.rb +0 -497
  180. data/lib/swarm_sdk/workflow/node_builder.rb +0 -593
  181. data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -250
  182. data/lib/swarm_sdk/workflow.rb +0 -589
  183. data/lib/swarm_sdk.rb +0 -718
@@ -1,205 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # Adapter for converting Claude Code agent markdown files to SwarmSDK format
5
- #
6
- # Claude Code agent files use a different syntax and conventions than SwarmSDK:
7
- # - Tools are comma-separated strings instead of arrays
8
- # - Model shortcuts like 'sonnet', 'opus', 'haiku' instead of full model IDs
9
- # - Tool permissions like 'Write(src/**)' instead of SwarmSDK's permission system
10
- # - Required 'name' field in frontmatter
11
- #
12
- # This adapter:
13
- # - Detects Claude Code format by checking frontmatter markers
14
- # - Converts tools from comma-separated strings to arrays
15
- # - Maps model shortcuts to canonical model IDs
16
- # - Strips unsupported tool permission syntax with warnings
17
- # - Sets coding_agent: true by default
18
- # - Warns about unsupported fields
19
- #
20
- # @example Parse a Claude Code agent file
21
- # content = File.read('.claude/agents/reviewer.md')
22
- # config = ClaudeCodeAgentAdapter.parse(content, :reviewer)
23
- # agent = Agent::Definition.new(:reviewer, config)
24
- #
25
- class ClaudeCodeAgentAdapter
26
- # Fields supported in Claude Code agent frontmatter
27
- SUPPORTED_FIELDS = ["name", "description", "tools", "model"].freeze
28
-
29
- # SwarmSDK documentation URL for reference
30
- SWARM_SDK_DOCS_URL = "https://github.com/parruda/claude-swarm/blob/main/docs/v2/README.md"
31
-
32
- # Pattern to detect tool permission syntax like Write(src/**)
33
- TOOL_PERMISSION_PATTERN = /^([A-Za-z_]+)\([^)]+\)$/
34
-
35
- class << self
36
- # Detect if content appears to be in Claude Code agent format
37
- #
38
- # Detection is based on tools field type:
39
- # - Claude Code: tools is a comma-separated string (e.g., "Read, Write, Bash")
40
- # - SwarmSDK: tools is an array (e.g., [Read, Write, Bash])
41
- #
42
- # Note: The 'name' field alone is not sufficient since SwarmSDK also supports it
43
- #
44
- # @param content [String] Markdown content with YAML frontmatter
45
- # @return [Boolean] true if content appears to be Claude Code format
46
- def claude_code_format?(content)
47
- return false unless content =~ /\A---\s*\n(.*?)\n---\s*\n/m
48
-
49
- frontmatter_yaml = Regexp.last_match(1)
50
- frontmatter = YAML.safe_load(frontmatter_yaml, permitted_classes: [Symbol], aliases: true)
51
-
52
- return false unless frontmatter.is_a?(Hash)
53
-
54
- # Only detect as Claude Code if tools field is a comma-separated string
55
- # This is the most reliable indicator since SwarmSDK always uses arrays
56
- frontmatter.key?("tools") && frontmatter["tools"].is_a?(String)
57
- rescue Psych::SyntaxError
58
- false
59
- end
60
-
61
- # Parse Claude Code agent markdown and convert to SwarmSDK format
62
- #
63
- # @param content [String] Markdown content with YAML frontmatter
64
- # @param agent_name [Symbol, String] Name of the agent
65
- # @param inherit_model [String, nil] Model to use when frontmatter has 'inherit'
66
- # @return [Hash] Configuration hash suitable for Agent::Definition.new
67
- # @raise [ConfigurationError] if content format is invalid
68
- def parse(content, agent_name, inherit_model: nil)
69
- new(inherit_model: inherit_model).parse(content, agent_name)
70
- end
71
- end
72
-
73
- # Initialize adapter with optional context
74
- #
75
- # @param inherit_model [String, nil] Model to use when frontmatter has 'inherit'
76
- def initialize(inherit_model: nil)
77
- @inherit_model = inherit_model
78
- @warnings = []
79
- end
80
-
81
- # Parse Claude Code agent content
82
- #
83
- # @param content [String] Markdown content with YAML frontmatter
84
- # @param agent_name [Symbol, String] Name of the agent
85
- # @return [Hash] Configuration hash for Agent::Definition
86
- # @raise [ConfigurationError] if format is invalid
87
- def parse(content, agent_name)
88
- unless content =~ /\A---\s*\n(.*?)\n---\s*\n(.*)\z/m
89
- raise ConfigurationError, "Invalid Claude Code agent format. Expected YAML frontmatter followed by prompt content."
90
- end
91
-
92
- frontmatter_yaml = Regexp.last_match(1)
93
- prompt_content = Regexp.last_match(2).strip
94
-
95
- frontmatter = YAML.safe_load(frontmatter_yaml, permitted_classes: [Symbol], aliases: true)
96
-
97
- unless frontmatter.is_a?(Hash)
98
- raise ConfigurationError, "Invalid frontmatter format in Claude Code agent file"
99
- end
100
-
101
- config = build_config(frontmatter, prompt_content, agent_name)
102
- emit_warnings(agent_name)
103
- config
104
- end
105
-
106
- private
107
-
108
- # Build SwarmSDK configuration from Claude Code frontmatter
109
- def build_config(frontmatter, prompt_content, agent_name)
110
- warn_unknown_fields(frontmatter)
111
-
112
- config = {
113
- description: frontmatter["description"],
114
- system_prompt: prompt_content,
115
- coding_agent: true, # Default for Claude Code agents
116
- }
117
-
118
- # Parse tools if present
119
- if frontmatter["tools"]
120
- config[:tools] = parse_tools(frontmatter["tools"])
121
- end
122
-
123
- # Parse model if present
124
- if frontmatter["model"]
125
- config[:model] = resolve_model(frontmatter["model"])
126
- end
127
-
128
- config
129
- end
130
-
131
- # Parse tools field - handles both comma-separated string and array
132
- #
133
- # @param tools_field [String, Array] Tools from frontmatter
134
- # @return [Array<String>] Array of tool names
135
- def parse_tools(tools_field)
136
- tools_array = if tools_field.is_a?(String)
137
- tools_field.split(",").map(&:strip)
138
- else
139
- Array(tools_field).map(&:to_s)
140
- end
141
-
142
- # Clean tool permissions and collect warnings
143
- tools_array.map { |tool| clean_tool_permissions(tool) }.compact
144
- end
145
-
146
- # Strip tool permission syntax and warn if detected
147
- #
148
- # @param tool_string [String] Tool name, possibly with permissions like 'Write(src/**)'
149
- # @return [String, nil] Clean tool name, or nil if invalid
150
- def clean_tool_permissions(tool_string)
151
- if tool_string =~ TOOL_PERMISSION_PATTERN
152
- tool_name = Regexp.last_match(1)
153
- @warnings << "Tool permission syntax '#{tool_string}' detected in agent file. SwarmSDK supports permissions but uses different syntax. Using '#{tool_name}' without restrictions for now. See SwarmSDK documentation for permission configuration: #{SWARM_SDK_DOCS_URL}"
154
- tool_name
155
- else
156
- tool_string
157
- end
158
- end
159
-
160
- # Resolve model shortcuts to canonical model IDs
161
- #
162
- # Uses SwarmSDK::Models.resolve_alias to map shortcuts like 'sonnet'
163
- # to the latest model IDs from model_aliases.json.
164
- #
165
- # @param model_field [String] Model from frontmatter
166
- # @return [String, Symbol] Canonical model ID or :inherit symbol
167
- def resolve_model(model_field)
168
- model_str = model_field.to_s.strip
169
-
170
- # Handle 'inherit' keyword
171
- return :inherit if model_str == "inherit"
172
-
173
- # Resolve using SwarmSDK model aliases
174
- # This maps 'sonnet' → 'claude-sonnet-4-5-20250929', etc.
175
- SwarmSDK::Models.resolve_alias(model_str)
176
- end
177
-
178
- # Warn about unknown frontmatter fields
179
- def warn_unknown_fields(frontmatter)
180
- unknown_fields = frontmatter.keys - SUPPORTED_FIELDS
181
-
182
- unknown_fields.each do |field|
183
- @warnings << case field
184
- when "hooks"
185
- "Hooks configuration detected in agent frontmatter. SwarmSDK handles hooks at the swarm level. See: #{SWARM_SDK_DOCS_URL}"
186
- else
187
- "Unknown field '#{field}' in Claude Code agent file. Ignoring. Supported fields: #{SUPPORTED_FIELDS.join(", ")}"
188
- end
189
- end
190
- end
191
-
192
- # Emit all collected warnings via LogCollector
193
- def emit_warnings(agent_name)
194
- return if @warnings.empty?
195
-
196
- @warnings.each do |warning|
197
- LogCollector.emit(
198
- type: "claude_code_conversion_warning",
199
- agent: agent_name,
200
- message: warning,
201
- )
202
- end
203
- end
204
- end
205
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- module Concerns
5
- # Shared cleanup functionality for Swarm and Workflow
6
- #
7
- # Both classes must have:
8
- # - mcp_clients: Hash of MCP client arrays
9
- # - delegation_instances_hash: Hash of delegation instances (via Snapshotable)
10
- #
11
- module Cleanupable
12
- # Cleanup all MCP clients
13
- #
14
- # Stops all MCP client connections gracefully.
15
- # Should be called when the swarm/workflow is no longer needed.
16
- #
17
- # @return [void]
18
- def cleanup
19
- # Check if there's anything to clean up
20
- return if @mcp_clients.empty? && (!delegation_instances_hash || delegation_instances_hash.empty?)
21
-
22
- # Stop MCP clients for all agents
23
- @mcp_clients.each do |agent_name, clients|
24
- clients.each do |client|
25
- client.stop
26
- RubyLLM.logger.debug("SwarmSDK: Stopped MCP client '#{client.name}' for agent #{agent_name}")
27
- rescue StandardError => e
28
- RubyLLM.logger.debug("SwarmSDK: Error stopping MCP client '#{client.name}': #{e.message}")
29
- end
30
- end
31
-
32
- @mcp_clients.clear
33
-
34
- # Clear delegation instances
35
- delegation_instances_hash&.clear
36
- end
37
- end
38
- end
39
- end
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- module Concerns
5
- # Shared snapshot and restore functionality for Swarm and Workflow
6
- #
7
- # Both classes must implement:
8
- # - primary_agents: Returns hash of primary agent instances
9
- # - delegation_instances_hash: Returns hash of delegation instances
10
- # - agent_definitions: Returns hash of agent definitions
11
- # - swarm_id: Returns the swarm/workflow ID
12
- # - parent_swarm_id: Returns the parent ID (or nil)
13
- # - name: Returns the swarm/workflow name
14
- #
15
- module Snapshotable
16
- # Create snapshot of current conversation state
17
- #
18
- # Returns a Snapshot object containing:
19
- # - All agent conversations (@messages arrays)
20
- # - Agent context state (warnings, compression, TodoWrite tracking, skills)
21
- # - Delegation instance conversations
22
- # - Scratchpad contents (volatile shared storage)
23
- # - Read tracking state (which files each agent has read with digests)
24
- # - Memory read tracking state (which memory entries each agent has read with digests)
25
- #
26
- # @return [Snapshot] Snapshot object with convenient serialization methods
27
- def snapshot
28
- StateSnapshot.new(self).snapshot
29
- end
30
-
31
- # Restore conversation state from snapshot
32
- #
33
- # Accepts a Snapshot object, hash, or JSON string. Validates compatibility
34
- # between snapshot and current configuration, restores agent conversations,
35
- # context state, scratchpad, and read tracking.
36
- #
37
- # The swarm/workflow must be created with the SAME configuration (agent definitions,
38
- # tools, prompts) as when the snapshot was created. Only conversation state
39
- # is restored from the snapshot.
40
- #
41
- # @param snapshot [Snapshot, Hash, String] Snapshot object, hash, or JSON string
42
- # @param preserve_system_prompts [Boolean] Use historical system prompts instead of current config (default: false)
43
- # @return [RestoreResult] Result with warnings about skipped agents
44
- def restore(snapshot, preserve_system_prompts: false)
45
- StateRestorer.new(self, snapshot, preserve_system_prompts: preserve_system_prompts).restore
46
- end
47
-
48
- # Interface method: Get primary agent instances
49
- #
50
- # Must be implemented by including class.
51
- #
52
- # @return [Hash<Symbol, Agent::Chat>] Primary agent instances
53
- def primary_agents
54
- raise NotImplementedError, "#{self.class} must implement #primary_agents"
55
- end
56
-
57
- # Interface method: Get delegation instance hash
58
- #
59
- # Must be implemented by including class.
60
- #
61
- # @return [Hash<String, Agent::Chat>] Delegation instances with keys like "delegate@delegator"
62
- def delegation_instances_hash
63
- raise NotImplementedError, "#{self.class} must implement #delegation_instances_hash"
64
- end
65
- end
66
- end
67
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- module Concerns
5
- # Shared validation functionality for Swarm and Workflow
6
- #
7
- # Both classes must have:
8
- # - agent_definitions: Hash of Agent::Definition objects
9
- # - swarm_id: Swarm/workflow identifier
10
- # - parent_swarm_id: Parent identifier (or nil)
11
- #
12
- module Validatable
13
- # Validate swarm/workflow configuration and return warnings
14
- #
15
- # This performs lightweight validation checks without creating agents.
16
- # Useful for displaying configuration warnings before execution.
17
- #
18
- # @return [Array<Hash>] Array of warning hashes from all agent definitions
19
- def validate
20
- @agent_definitions.flat_map { |_name, definition| definition.validate }
21
- end
22
-
23
- # Emit validation warnings as log events
24
- #
25
- # This validates all agent definitions and emits any warnings as
26
- # model_lookup_warning events through LogStream. Useful for emitting
27
- # warnings before execution starts (e.g., in REPL after welcome screen).
28
- #
29
- # Requires LogStream.emitter to be set.
30
- #
31
- # @return [Array<Hash>] The validation warnings that were emitted
32
- def emit_validation_warnings
33
- warnings = validate
34
-
35
- warnings.each do |warning|
36
- case warning[:type]
37
- when :model_not_found
38
- LogStream.emit(
39
- type: "model_lookup_warning",
40
- agent: warning[:agent],
41
- swarm_id: @swarm_id,
42
- parent_swarm_id: @parent_swarm_id,
43
- model: warning[:model],
44
- error_message: warning[:error_message],
45
- suggestions: warning[:suggestions],
46
- timestamp: Time.now.utc.iso8601,
47
- )
48
- end
49
- end
50
-
51
- warnings
52
- end
53
- end
54
- end
55
- end