swarm_memory 2.1.5 → 2.1.6

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 (182) hide show
  1. checksums.yaml +4 -4
  2. data/lib/swarm_memory/version.rb +1 -1
  3. metadata +5 -184
  4. data/lib/claude_swarm/base_executor.rb +0 -133
  5. data/lib/claude_swarm/claude_code_executor.rb +0 -349
  6. data/lib/claude_swarm/claude_mcp_server.rb +0 -78
  7. data/lib/claude_swarm/cli.rb +0 -697
  8. data/lib/claude_swarm/commands/ps.rb +0 -215
  9. data/lib/claude_swarm/commands/show.rb +0 -139
  10. data/lib/claude_swarm/configuration.rb +0 -373
  11. data/lib/claude_swarm/hooks/session_start_hook.rb +0 -42
  12. data/lib/claude_swarm/json_handler.rb +0 -91
  13. data/lib/claude_swarm/mcp_generator.rb +0 -230
  14. data/lib/claude_swarm/openai/chat_completion.rb +0 -256
  15. data/lib/claude_swarm/openai/executor.rb +0 -256
  16. data/lib/claude_swarm/openai/responses.rb +0 -319
  17. data/lib/claude_swarm/orchestrator.rb +0 -878
  18. data/lib/claude_swarm/process_tracker.rb +0 -78
  19. data/lib/claude_swarm/session_cost_calculator.rb +0 -209
  20. data/lib/claude_swarm/session_path.rb +0 -42
  21. data/lib/claude_swarm/settings_generator.rb +0 -77
  22. data/lib/claude_swarm/system_utils.rb +0 -46
  23. data/lib/claude_swarm/templates/generation_prompt.md.erb +0 -230
  24. data/lib/claude_swarm/tools/reset_session_tool.rb +0 -24
  25. data/lib/claude_swarm/tools/session_info_tool.rb +0 -24
  26. data/lib/claude_swarm/tools/task_tool.rb +0 -63
  27. data/lib/claude_swarm/version.rb +0 -5
  28. data/lib/claude_swarm/worktree_manager.rb +0 -475
  29. data/lib/claude_swarm/yaml_loader.rb +0 -22
  30. data/lib/claude_swarm.rb +0 -67
  31. data/lib/swarm_cli/cli.rb +0 -201
  32. data/lib/swarm_cli/command_registry.rb +0 -61
  33. data/lib/swarm_cli/commands/mcp_serve.rb +0 -130
  34. data/lib/swarm_cli/commands/mcp_tools.rb +0 -148
  35. data/lib/swarm_cli/commands/migrate.rb +0 -55
  36. data/lib/swarm_cli/commands/run.rb +0 -173
  37. data/lib/swarm_cli/config_loader.rb +0 -98
  38. data/lib/swarm_cli/formatters/human_formatter.rb +0 -781
  39. data/lib/swarm_cli/formatters/json_formatter.rb +0 -51
  40. data/lib/swarm_cli/interactive_repl.rb +0 -924
  41. data/lib/swarm_cli/mcp_serve_options.rb +0 -44
  42. data/lib/swarm_cli/mcp_tools_options.rb +0 -59
  43. data/lib/swarm_cli/migrate_options.rb +0 -54
  44. data/lib/swarm_cli/migrator.rb +0 -132
  45. data/lib/swarm_cli/options.rb +0 -151
  46. data/lib/swarm_cli/ui/components/agent_badge.rb +0 -33
  47. data/lib/swarm_cli/ui/components/content_block.rb +0 -120
  48. data/lib/swarm_cli/ui/components/divider.rb +0 -57
  49. data/lib/swarm_cli/ui/components/panel.rb +0 -62
  50. data/lib/swarm_cli/ui/components/usage_stats.rb +0 -70
  51. data/lib/swarm_cli/ui/formatters/cost.rb +0 -49
  52. data/lib/swarm_cli/ui/formatters/number.rb +0 -58
  53. data/lib/swarm_cli/ui/formatters/text.rb +0 -77
  54. data/lib/swarm_cli/ui/formatters/time.rb +0 -73
  55. data/lib/swarm_cli/ui/icons.rb +0 -36
  56. data/lib/swarm_cli/ui/renderers/event_renderer.rb +0 -188
  57. data/lib/swarm_cli/ui/state/agent_color_cache.rb +0 -45
  58. data/lib/swarm_cli/ui/state/depth_tracker.rb +0 -40
  59. data/lib/swarm_cli/ui/state/spinner_manager.rb +0 -170
  60. data/lib/swarm_cli/ui/state/usage_tracker.rb +0 -62
  61. data/lib/swarm_cli/version.rb +0 -5
  62. data/lib/swarm_cli.rb +0 -46
  63. data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -127
  64. data/lib/swarm_sdk/agent/builder.rb +0 -552
  65. data/lib/swarm_sdk/agent/chat.rb +0 -774
  66. data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -268
  67. data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +0 -204
  68. data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +0 -480
  69. data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +0 -78
  70. data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -233
  71. data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +0 -116
  72. data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +0 -83
  73. data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +0 -136
  74. data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
  75. data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -98
  76. data/lib/swarm_sdk/agent/context.rb +0 -116
  77. data/lib/swarm_sdk/agent/context_manager.rb +0 -315
  78. data/lib/swarm_sdk/agent/definition.rb +0 -477
  79. data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -182
  80. data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -161
  81. data/lib/swarm_sdk/builders/base_builder.rb +0 -409
  82. data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
  83. data/lib/swarm_sdk/concerns/cleanupable.rb +0 -39
  84. data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
  85. data/lib/swarm_sdk/concerns/validatable.rb +0 -55
  86. data/lib/swarm_sdk/configuration/parser.rb +0 -353
  87. data/lib/swarm_sdk/configuration/translator.rb +0 -255
  88. data/lib/swarm_sdk/configuration.rb +0 -135
  89. data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
  90. data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -106
  91. data/lib/swarm_sdk/context_compactor.rb +0 -335
  92. data/lib/swarm_sdk/context_management/builder.rb +0 -128
  93. data/lib/swarm_sdk/context_management/context.rb +0 -328
  94. data/lib/swarm_sdk/defaults.rb +0 -196
  95. data/lib/swarm_sdk/events_to_messages.rb +0 -199
  96. data/lib/swarm_sdk/hooks/adapter.rb +0 -359
  97. data/lib/swarm_sdk/hooks/context.rb +0 -197
  98. data/lib/swarm_sdk/hooks/definition.rb +0 -80
  99. data/lib/swarm_sdk/hooks/error.rb +0 -29
  100. data/lib/swarm_sdk/hooks/executor.rb +0 -146
  101. data/lib/swarm_sdk/hooks/registry.rb +0 -147
  102. data/lib/swarm_sdk/hooks/result.rb +0 -150
  103. data/lib/swarm_sdk/hooks/shell_executor.rb +0 -255
  104. data/lib/swarm_sdk/hooks/tool_call.rb +0 -35
  105. data/lib/swarm_sdk/hooks/tool_result.rb +0 -62
  106. data/lib/swarm_sdk/log_collector.rb +0 -227
  107. data/lib/swarm_sdk/log_stream.rb +0 -127
  108. data/lib/swarm_sdk/markdown_parser.rb +0 -75
  109. data/lib/swarm_sdk/model_aliases.json +0 -8
  110. data/lib/swarm_sdk/models.json +0 -1
  111. data/lib/swarm_sdk/models.rb +0 -120
  112. data/lib/swarm_sdk/node_context.rb +0 -245
  113. data/lib/swarm_sdk/observer/builder.rb +0 -81
  114. data/lib/swarm_sdk/observer/config.rb +0 -45
  115. data/lib/swarm_sdk/observer/manager.rb +0 -236
  116. data/lib/swarm_sdk/patterns/agent_observer.rb +0 -160
  117. data/lib/swarm_sdk/permissions/config.rb +0 -239
  118. data/lib/swarm_sdk/permissions/error_formatter.rb +0 -121
  119. data/lib/swarm_sdk/permissions/path_matcher.rb +0 -35
  120. data/lib/swarm_sdk/permissions/validator.rb +0 -173
  121. data/lib/swarm_sdk/permissions_builder.rb +0 -122
  122. data/lib/swarm_sdk/plugin.rb +0 -309
  123. data/lib/swarm_sdk/plugin_registry.rb +0 -101
  124. data/lib/swarm_sdk/proc_helpers.rb +0 -53
  125. data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -117
  126. data/lib/swarm_sdk/restore_result.rb +0 -65
  127. data/lib/swarm_sdk/result.rb +0 -123
  128. data/lib/swarm_sdk/snapshot.rb +0 -156
  129. data/lib/swarm_sdk/snapshot_from_events.rb +0 -397
  130. data/lib/swarm_sdk/state_restorer.rb +0 -476
  131. data/lib/swarm_sdk/state_snapshot.rb +0 -334
  132. data/lib/swarm_sdk/swarm/agent_initializer.rb +0 -683
  133. data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -167
  134. data/lib/swarm_sdk/swarm/builder.rb +0 -249
  135. data/lib/swarm_sdk/swarm/executor.rb +0 -213
  136. data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -150
  137. data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -340
  138. data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -154
  139. data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
  140. data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -358
  141. data/lib/swarm_sdk/swarm.rb +0 -717
  142. data/lib/swarm_sdk/swarm_loader.rb +0 -145
  143. data/lib/swarm_sdk/swarm_registry.rb +0 -136
  144. data/lib/swarm_sdk/tools/bash.rb +0 -282
  145. data/lib/swarm_sdk/tools/clock.rb +0 -44
  146. data/lib/swarm_sdk/tools/delegate.rb +0 -267
  147. data/lib/swarm_sdk/tools/document_converters/base_converter.rb +0 -83
  148. data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +0 -99
  149. data/lib/swarm_sdk/tools/document_converters/html_converter.rb +0 -101
  150. data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +0 -78
  151. data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +0 -194
  152. data/lib/swarm_sdk/tools/edit.rb +0 -145
  153. data/lib/swarm_sdk/tools/glob.rb +0 -166
  154. data/lib/swarm_sdk/tools/grep.rb +0 -235
  155. data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +0 -43
  156. data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +0 -163
  157. data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
  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 -272
  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 -98
  170. data/lib/swarm_sdk/tools/todo_write.rb +0 -235
  171. data/lib/swarm_sdk/tools/web_fetch.rb +0 -262
  172. data/lib/swarm_sdk/tools/write.rb +0 -112
  173. data/lib/swarm_sdk/utils.rb +0 -68
  174. data/lib/swarm_sdk/validation_result.rb +0 -33
  175. data/lib/swarm_sdk/version.rb +0 -5
  176. data/lib/swarm_sdk/workflow/agent_config.rb +0 -79
  177. data/lib/swarm_sdk/workflow/builder.rb +0 -143
  178. data/lib/swarm_sdk/workflow/executor.rb +0 -497
  179. data/lib/swarm_sdk/workflow/node_builder.rb +0 -555
  180. data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -249
  181. data/lib/swarm_sdk/workflow.rb +0 -554
  182. data/lib/swarm_sdk.rb +0 -524
@@ -1,309 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # Base class for SwarmSDK plugins
5
- #
6
- # Plugins provide tools, storage, configuration parsing, and lifecycle hooks.
7
- # Plugins are self-registering - they call SwarmSDK::PluginRegistry.register
8
- # when the gem is loaded.
9
- #
10
- # ## Adding Custom Attributes to Agents
11
- #
12
- # Plugins can add custom attributes to Agent::Definition that are preserved
13
- # when agents are cloned (e.g., in Workflow). To do this:
14
- #
15
- # 1. Add attr_reader to Agent::Definition for your attribute
16
- # 2. Parse the attribute in Agent::Definition#initialize
17
- # 3. Implement serialize_config to preserve it during serialization
18
- #
19
- # @example Plugin with custom agent attributes
20
- # # 1. Extend Agent::Definition (in your plugin gem)
21
- # module SwarmSDK
22
- # module Agent
23
- # class Definition
24
- # attr_reader :my_custom_config
25
- #
26
- # alias_method :original_initialize, :initialize
27
- # def initialize(name, config = {})
28
- # @my_custom_config = config[:my_custom_config]
29
- # original_initialize(name, config)
30
- # end
31
- # end
32
- # end
33
- # end
34
- #
35
- # # 2. Implement plugin with serialize_config
36
- # class MyPlugin < SwarmSDK::Plugin
37
- # def name
38
- # :my_plugin
39
- # end
40
- #
41
- # def tools
42
- # [:MyTool, :OtherTool]
43
- # end
44
- #
45
- # def create_tool(tool_name, context)
46
- # # Create and return tool instance
47
- # end
48
- #
49
- # # Preserve custom config when agents are cloned
50
- # def serialize_config(agent_definition:)
51
- # return {} unless agent_definition.my_custom_config
52
- #
53
- # { my_custom_config: agent_definition.my_custom_config }
54
- # end
55
- # end
56
- #
57
- # SwarmSDK::PluginRegistry.register(MyPlugin.new)
58
- #
59
- # Now agents can use your custom config:
60
- #
61
- # agent :researcher do
62
- # my_custom_config { option: "value" }
63
- # end
64
- #
65
- # And it will be preserved when Workflow clones the agent!
66
- #
67
- # @example Real-world: SwarmMemory plugin
68
- # # SwarmMemory adds 'memory' attribute to agents
69
- # class SDKPlugin < SwarmSDK::Plugin
70
- # def serialize_config(agent_definition:)
71
- # return {} unless agent_definition.memory
72
- # { memory: agent_definition.memory }
73
- # end
74
- # end
75
- #
76
- class Plugin
77
- # Plugin name (must be unique)
78
- #
79
- # @return [Symbol] Plugin identifier
80
- def name
81
- raise NotImplementedError, "#{self.class} must implement #name"
82
- end
83
-
84
- # List of tools provided by this plugin
85
- #
86
- # @return [Array<Symbol>] Tool names (e.g., [:MemoryWrite, :MemoryRead])
87
- def tools
88
- []
89
- end
90
-
91
- # Create a tool instance
92
- #
93
- # @param tool_name [Symbol] Tool name (e.g., :MemoryWrite)
94
- # @param context [Hash] Creation context
95
- # - :agent_name [Symbol] Agent identifier
96
- # - :storage [Object] Plugin storage instance (if created)
97
- # - :agent_definition [Agent::Definition] Full agent definition
98
- # - :chat [Agent::Chat] Chat instance (for tools that need it)
99
- # - :tool_configurator [Swarm::ToolConfigurator] For tools that register other tools
100
- # @return [RubyLLM::Tool] Tool instance
101
- def create_tool(tool_name, context)
102
- raise NotImplementedError, "#{self.class} must implement #create_tool"
103
- end
104
-
105
- # Create plugin storage for an agent (optional)
106
- #
107
- # Called during agent initialization. Return nil if plugin doesn't need storage.
108
- #
109
- # @param agent_name [Symbol] Agent identifier
110
- # @param config [Object] Plugin configuration from agent definition
111
- # @return [Object, nil] Storage instance or nil
112
- def create_storage(agent_name:, config:)
113
- nil
114
- end
115
-
116
- # Parse plugin configuration from agent definition
117
- #
118
- # @param raw_config [Object] Raw config (DSL object or Hash from YAML)
119
- # @return [Object] Parsed configuration
120
- def parse_config(raw_config)
121
- raw_config
122
- end
123
-
124
- # Contribute to agent system prompt (optional)
125
- #
126
- # @param agent_definition [Agent::Definition] Agent definition
127
- # @param storage [Object, nil] Plugin storage instance (if created)
128
- # @return [String, nil] Prompt contribution or nil
129
- def system_prompt_contribution(agent_definition:, storage:)
130
- nil
131
- end
132
-
133
- # Tools that should be marked immutable (optional)
134
- #
135
- # Immutable tools cannot be removed by other tools (e.g., LoadSkill).
136
- #
137
- # @return [Array<Symbol>] Tool names
138
- def immutable_tools
139
- []
140
- end
141
-
142
- # Agent storage enabled for this agent? (optional)
143
- #
144
- # @param agent_definition [Agent::Definition] Agent definition
145
- # @return [Boolean] True if storage should be created
146
- def storage_enabled?(agent_definition)
147
- false
148
- end
149
-
150
- # Lifecycle: Called when agent is initialized
151
- #
152
- # @param agent_name [Symbol] Agent identifier
153
- # @param agent [Agent::Chat] Chat instance
154
- # @param context [Hash] Initialization context
155
- # - :storage [Object, nil] Plugin storage
156
- # - :agent_definition [Agent::Definition] Definition
157
- # - :tool_configurator [Swarm::ToolConfigurator] Configurator
158
- def on_agent_initialized(agent_name:, agent:, context:)
159
- # Override if needed
160
- end
161
-
162
- # Lifecycle: Called when swarm starts
163
- #
164
- # @param swarm [Swarm] Swarm instance
165
- def on_swarm_started(swarm:)
166
- # Override if needed
167
- end
168
-
169
- # Lifecycle: Called when swarm stops
170
- #
171
- # @param swarm [Swarm] Swarm instance
172
- def on_swarm_stopped(swarm:)
173
- # Override if needed
174
- end
175
-
176
- # Lifecycle: Called on every user message
177
- #
178
- # Plugins can return system reminders to inject based on the user's prompt.
179
- # This enables features like semantic skill discovery, context injection, etc.
180
- #
181
- # @param agent_name [Symbol] Agent identifier
182
- # @param prompt [String] The user's message
183
- # @param is_first_message [Boolean] True if this is the first message in the conversation
184
- # @return [Array<String>] System reminders to inject (empty array if none)
185
- #
186
- # @example Semantic skill discovery
187
- # def on_user_message(agent_name:, prompt:, is_first_message:)
188
- # skills = semantic_search(prompt, threshold: 0.65)
189
- # return [] if skills.empty?
190
- #
191
- # [build_skill_reminder(skills)]
192
- # end
193
- def on_user_message(agent_name:, prompt:, is_first_message:)
194
- []
195
- end
196
-
197
- # Contribute to agent serialization (optional)
198
- #
199
- # Called when Agent::Definition.to_h is invoked (e.g., for cloning agents
200
- # in Workflow). Plugins can return config keys that should be
201
- # included in the serialized hash to preserve their state.
202
- #
203
- # This allows plugins to maintain their configuration when agents are
204
- # cloned or serialized, without SwarmSDK needing to know about plugin-specific fields.
205
- #
206
- # @param agent_definition [Agent::Definition] Agent definition
207
- # @return [Hash] Config keys to include in to_h (e.g., { memory: config })
208
- #
209
- # @example Memory plugin serialization
210
- # def serialize_config(agent_definition:)
211
- # return {} unless agent_definition.memory
212
- #
213
- # { memory: agent_definition.memory }
214
- # end
215
- def serialize_config(agent_definition:)
216
- {}
217
- end
218
-
219
- # Snapshot plugin-specific state for an agent
220
- #
221
- # Called during state snapshot creation (e.g., session persistence).
222
- # Return any state your plugin needs to persist for this agent.
223
- # The returned hash will be JSON serialized.
224
- #
225
- # @param agent_name [Symbol] Agent identifier
226
- # @return [Hash] Plugin-specific state (empty hash if nothing to snapshot)
227
- #
228
- # @example Memory read tracking
229
- # def snapshot_agent_state(agent_name)
230
- # entries = StorageReadTracker.get_read_entries(agent_name)
231
- # return {} if entries.empty?
232
- #
233
- # { read_entries: entries }
234
- # end
235
- def snapshot_agent_state(agent_name)
236
- {}
237
- end
238
-
239
- # Restore plugin-specific state for an agent
240
- #
241
- # Called during state restoration. Restore any persisted state.
242
- # This method is idempotent - calling it multiple times with
243
- # the same state should produce the same result.
244
- #
245
- # @param agent_name [Symbol] Agent identifier
246
- # @param state [Hash] Previously snapshotted state (with symbol keys)
247
- # @return [void]
248
- #
249
- # @example Memory read tracking
250
- # def restore_agent_state(agent_name, state)
251
- # entries = state[:read_entries] || state["read_entries"]
252
- # return unless entries
253
- #
254
- # StorageReadTracker.restore_read_entries(agent_name, entries)
255
- # end
256
- def restore_agent_state(agent_name, state)
257
- # Override if needed
258
- end
259
-
260
- # Get digest for a tool result (e.g., file hash, memory entry hash)
261
- #
262
- # Called during tool result metadata collection. Returns a digest
263
- # that can be used to detect if the resource has changed since
264
- # it was last read. This enables change detection hooks.
265
- #
266
- # @param agent_name [Symbol] Agent identifier
267
- # @param tool_name [String] Name of the tool (e.g., "MemoryRead")
268
- # @param path [String] Path or identifier of the resource
269
- # @return [String, nil] Digest string or nil if not tracked by this plugin
270
- #
271
- # @example Memory read tracking
272
- # def get_tool_result_digest(agent_name:, tool_name:, path:)
273
- # return unless tool_name == "MemoryRead"
274
- #
275
- # StorageReadTracker.get_read_entries(agent_name)[path]
276
- # end
277
- def get_tool_result_digest(agent_name:, tool_name:, path:)
278
- nil
279
- end
280
-
281
- # Translate YAML configuration into DSL calls
282
- #
283
- # Called during YAML-to-DSL translation. Plugins can translate their
284
- # specific YAML configuration keys into DSL method calls on the builder.
285
- # This allows SDK to remain plugin-agnostic while plugins can add
286
- # YAML configuration support.
287
- #
288
- # @param builder [Agent::Builder] Builder instance (self in DSL context)
289
- # @param agent_config [Hash] Full agent config from YAML
290
- # @return [void]
291
- #
292
- # @example Memory plugin YAML translation
293
- # def translate_yaml_config(builder, agent_config)
294
- # memory_config = agent_config[:memory]
295
- # return unless memory_config
296
- #
297
- # builder.instance_eval do
298
- # memory do
299
- # directory(memory_config[:directory])
300
- # adapter(memory_config[:adapter]) if memory_config[:adapter]
301
- # mode(memory_config[:mode]) if memory_config[:mode]
302
- # end
303
- # end
304
- # end
305
- def translate_yaml_config(builder, agent_config)
306
- # Override if plugin needs YAML configuration support
307
- end
308
- end
309
- end
@@ -1,101 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # Plugin registry for managing SwarmSDK extensions
5
- #
6
- # Plugins register themselves when loaded, providing tools, storage,
7
- # and lifecycle hooks without SwarmSDK needing to know about them.
8
- module PluginRegistry
9
- @plugins = {}
10
- @tool_map = {}
11
-
12
- class << self
13
- # Register a plugin
14
- #
15
- # @param plugin [Plugin] Plugin instance
16
- # @raise [ArgumentError] If plugin with same name already registered
17
- def register(plugin)
18
- raise ArgumentError, "Plugin must inherit from SwarmSDK::Plugin" unless plugin.is_a?(Plugin)
19
-
20
- name = plugin.name
21
- raise ArgumentError, "Plugin name required" unless name
22
- raise ArgumentError, "Plugin #{name} already registered" if @plugins.key?(name)
23
-
24
- @plugins[name] = plugin
25
-
26
- # Build tool → plugin mapping
27
- plugin.tools.each do |tool_name|
28
- if @tool_map.key?(tool_name)
29
- raise ArgumentError, "Tool #{tool_name} already registered by #{@tool_map[tool_name].name}"
30
- end
31
-
32
- @tool_map[tool_name] = plugin
33
- end
34
- end
35
-
36
- # Get plugin by name
37
- #
38
- # @param name [Symbol] Plugin name
39
- # @return [Plugin, nil] Plugin instance or nil
40
- def get(name)
41
- @plugins[name]
42
- end
43
-
44
- # Get all registered plugins
45
- #
46
- # @return [Array<Plugin>] All plugins
47
- def all
48
- @plugins.values
49
- end
50
-
51
- # Check if plugin is registered
52
- #
53
- # @param name [Symbol] Plugin name
54
- # @return [Boolean] True if registered
55
- def registered?(name)
56
- @plugins.key?(name)
57
- end
58
-
59
- # Get plugin that provides a tool
60
- #
61
- # @param tool_name [Symbol] Tool name
62
- # @return [Plugin, nil] Plugin that provides tool or nil
63
- def plugin_for_tool(tool_name)
64
- @tool_map[tool_name]
65
- end
66
-
67
- # Check if tool is provided by a plugin
68
- #
69
- # @param tool_name [Symbol] Tool name
70
- # @return [Boolean] True if tool is plugin-provided
71
- def plugin_tool?(tool_name)
72
- @tool_map.key?(tool_name)
73
- end
74
-
75
- # Get all tools provided by plugins
76
- #
77
- # @return [Hash<Symbol, Plugin>] Tool name → Plugin mapping
78
- def tools
79
- @tool_map.dup
80
- end
81
-
82
- # Clear all plugins (for testing)
83
- #
84
- # @return [void]
85
- def clear
86
- @plugins.clear
87
- @tool_map.clear
88
- end
89
-
90
- # Emit lifecycle event to all plugins
91
- #
92
- # @param event [Symbol] Event name
93
- # @param args [Hash] Event arguments
94
- def emit_event(event, **args)
95
- @plugins.each_value do |plugin|
96
- plugin.public_send(event, **args) if plugin.respond_to?(event)
97
- end
98
- end
99
- end
100
- end
101
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # Helper methods for working with Procs and Lambdas
5
- #
6
- # Provides functionality to convert regular Proc objects into Lambdas to enable
7
- # safe use of return statements in DSL blocks (like input/output transformers).
8
- module ProcHelpers
9
- class << self
10
- # Convert a Proc to a Lambda
11
- #
12
- # The fundamental difference between a Proc and a Lambda is in how they handle
13
- # return statements. In a Proc, return exits the enclosing method (or program),
14
- # while in a Lambda, return only exits the lambda itself.
15
- #
16
- # This method converts a Proc to a Lambda by:
17
- # 1. Converting the proc to an unbound method via define_method
18
- # 2. Wrapping it in a lambda that binds and calls the method
19
- # 3. In the method, return exits the method (not the original scope)
20
- #
21
- # This allows users to write natural control flow with return statements:
22
- #
23
- # @example
24
- # my_proc = proc { |x| return x * 2 if x > 0; 0 }
25
- # my_lambda = ProcHelpers.to_lambda(my_proc)
26
- # my_lambda.call(5) # => 10 (return works safely!)
27
- #
28
- # @param proc [Proc] The proc to convert
29
- # @return [Proc] A lambda with the same behavior but safe return semantics
30
- def to_lambda(proc)
31
- return proc if proc.lambda?
32
-
33
- # Save local reference to proc so we can use it in module_exec/lambda scopes
34
- source_proc = proc
35
-
36
- # Convert proc to unbound method
37
- # define_method with a block converts the block to a method, where return
38
- # exits the method (not the original scope)
39
- unbound_method = Module.new.module_exec do
40
- instance_method(define_method(:_proc_call, &source_proc))
41
- end
42
-
43
- # Return lambda which binds our unbound method to correct receiver and calls it
44
- lambda do |*args, **kwargs, &block|
45
- # Bind method to the original proc's receiver (the context where it was defined)
46
- # This preserves access to instance variables, local variables via closure, etc.
47
- receiver = source_proc.binding.eval("self")
48
- unbound_method.bind(receiver).call(*args, **kwargs, &block)
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,117 +0,0 @@
1
- You are an AI agent designed to help users with their tasks. Use the instructions below and the tools available to you to assist the user.
2
-
3
- IMPORTANT: Assist with defensive security tasks only. Refuse to create, modify, or improve code that may be used maliciously. Allow security analysis, detection rules, vulnerability explanations, defensive tools, and security documentation.
4
- IMPORTANT: You must NEVER generate or guess URLs for the user unless you are confident that the URLs are appropriate for the task at hand. You may use URLs provided by the user in their messages or local files.
5
-
6
- # Tone and style
7
-
8
- You should be concise, direct, and to the point.
9
- You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail.
10
- IMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.
11
- IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your actions or summarizing what you did), unless the user asks you to.
12
- Do not add additional explanation or summary unless requested by the user. After working on a task, just stop, rather than providing an explanation of what you did.
13
- Answer the user's question directly, without elaboration, explanation, or details. Brief answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as "The answer is <answer>.", "Here is the content..." or "Based on the information provided, the answer is..." or "Here is what I will do next...". Here are some examples to demonstrate appropriate verbosity:
14
- <example>
15
- user: 2 + 2
16
- assistant: 4
17
- </example>
18
-
19
- <example>
20
- user: what is 2+2?
21
- assistant: 4
22
- </example>
23
-
24
- <example>
25
- user: is 11 a prime number?
26
- assistant: Yes
27
- </example>
28
-
29
- <example>
30
- user: what command should I run to list files in the current directory?
31
- assistant: ls
32
- </example>
33
-
34
- <example>
35
- user: How many golf balls fit inside a jetta?
36
- assistant: 150000
37
- </example>
38
-
39
- <example>
40
- user: what files are in the directory src/?
41
- assistant: [reads directory and sees foo.c, bar.c, baz.c]
42
- user: which file contains the implementation of foo?
43
- assistant: src/foo.c
44
- </example>
45
- When you run a non-trivial bash command, you should explain what the command does and why you are running it, to make sure the user understands what you are doing (this is especially important when you are running a command that will make changes to the user's system).
46
- Output text to communicate with the user; all text you output outside of tool use is displayed to the user. Only use tools to complete tasks. Never use tools like Bash or comments as means to communicate with the user during the session.
47
- If you cannot or will not help the user with something, please do not say why or what it could lead to, since this comes across as preachy and annoying. Please offer helpful alternatives if possible, and otherwise keep your response to 1-2 sentences.
48
- Only use emojis if the user explicitly requests it. Avoid using emojis in all communication unless asked.
49
- IMPORTANT: Keep your responses short and focused.
50
-
51
- # Proactiveness
52
-
53
- You are allowed to be proactive, but only when the user asks you to do something. You should strive to strike a balance between:
54
-
55
- - Doing the right thing when asked, including taking actions and follow-up actions
56
- - Not surprising the user with actions you take without asking
57
- For example, if the user asks you how to approach something, you should do your best to answer their question first, and not immediately jump into taking actions.
58
-
59
- # Professional objectivity
60
-
61
- Prioritize technical accuracy and truthfulness over validating the user's beliefs. Focus on facts and problem-solving, providing direct, objective technical info without any unnecessary superlatives, praise, or emotional validation. It is best for the user if you honestly applies the same rigorous standards to all ideas and disagrees when necessary, even if it may not be what the user wants to hear. Objective guidance and respectful correction are more valuable than false agreement. Whenever there is uncertainty, it's best to investigate to find the truth first rather than instinctively confirming the user's beliefs.
62
-
63
- # Following conventions
64
-
65
- When making changes to files, first understand the file's conventions. Mimic existing style, use existing libraries and utilities, and follow existing patterns.
66
-
67
- - NEVER assume that a given library is available, even if it is well known. Whenever you reference a library or framework, first check that this project already uses the given library. For example, you might look at neighboring files, or check configuration files like package.json, requirements.txt, Cargo.toml, Gemfile, and so on depending on the context.
68
- - When you create something new, first look at existing examples to see how they're written; then consider naming conventions and other patterns.
69
- - When you edit something, first look at the surrounding context (especially imports/requires) to understand the choice of frameworks and libraries. Then consider how to make the given change in a way that is most consistent with existing patterns.
70
- - Always follow security best practices. Never introduce code that exposes or logs secrets and keys. Never commit secrets or keys to repositories.
71
-
72
- # Doing tasks
73
-
74
- The user will primarily request you perform tasks. This includes solving problems, adding new functionality, refactoring, explaining content, and more. For these tasks the following steps are recommended:
75
-
76
- - Use the available search tools to understand the context and the user's query. You are encouraged to use the search tools extensively both in parallel and sequentially.
77
- - Implement the solution using all tools available to you
78
- - Verify the solution if possible with tests. NEVER assume specific test framework or test script. Check the project documentation or search to determine the testing approach.
79
- - When you have completed a task, if there are linting or validation commands available to you, run them to ensure your work is correct. NEVER assume what these commands are - check the project documentation first.
80
- NEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive.
81
-
82
- # Tool usage policy
83
-
84
- - When doing file search, prefer to use the Grep and Glob tools efficiently to reduce resource usage.
85
- - You should proactively use specialized tools when the task at hand matches their purpose.
86
- - You can call multiple tools in a single response. If you intend to call multiple tools and there are no dependencies between them, make all independent tool calls in parallel. Maximize use of parallel tool calls where possible to increase efficiency. However, if some tool calls depend on previous calls to inform dependent values, do NOT call these tools in parallel and instead call them sequentially. For instance, if one operation must complete before another starts, run these operations sequentially instead. Never use placeholders or guess missing parameters in tool calls.
87
- - If the user specifies that they want you to run tools "in parallel", you MUST send a single message with multiple tool use content blocks. For example, if you need to delegate a task to multiple agents in parallel, send a single message with multiple DelegateTask tool calls.
88
- - Use specialized tools instead of bash commands when possible, as this provides a better user experience. For file operations, use dedicated tools: Read for reading files instead of cat/head/tail, Edit/MultiEdit for editing instead of sed/awk, and Write for creating files instead of cat with heredoc or echo redirection. Reserve bash tools exclusively for actual system commands and terminal operations that require shell execution. NEVER use bash echo or other command-line tools to communicate thoughts, explanations, or instructions to the user. Output all communication directly in your response text instead.
89
-
90
- You MUST answer concisely with fewer than 4 lines of text (not including tool use or code generation), unless user asks for detail.
91
-
92
-
93
- # Today's date
94
-
95
- <today-date>
96
- #{date}
97
- #</today-date>
98
-
99
- # Environment information
100
-
101
- Here is useful information about the environment you are running in:
102
- <env>
103
- Working directory: <%= cwd %>
104
- Platform: <%= platform %>
105
- OS Version: <%= os_version %>
106
- </env>
107
-
108
- IMPORTANT: Assist with defensive security tasks only. Refuse to create, modify, or improve code that may be used maliciously. Allow security analysis, detection rules, vulnerability explanations, defensive tools, and security documentation.
109
-
110
- # Code References
111
-
112
- When referencing specific functions or pieces of code include the pattern `file_path:line_number` to allow the user to easily navigate to the source location.
113
-
114
- <example>
115
- user: Where are errors handled?
116
- assistant: Errors are handled in the `processRequest` function in src/services/handler.ts:245.
117
- </example>
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # Result object returned from snapshot restore operations
5
- #
6
- # Provides information about the restore process, including any warnings
7
- # about agents or delegations that couldn't be restored due to configuration
8
- # mismatches.
9
- #
10
- # @example Successful restore
11
- # result = swarm.restore(snapshot_data)
12
- # if result.success?
13
- # puts "All agents restored successfully"
14
- # end
15
- #
16
- # @example Partial restore with warnings
17
- # result = swarm.restore(snapshot_data)
18
- # if result.partial_restore?
19
- # puts result.summary
20
- # result.warnings.each do |warning|
21
- # puts " - #{warning[:message]}"
22
- # end
23
- # end
24
- class RestoreResult
25
- attr_reader :warnings, :skipped_agents, :skipped_delegations
26
-
27
- # Initialize restore result
28
- #
29
- # @param warnings [Array<Hash>] Warning messages with details
30
- # @param skipped_agents [Array<Symbol>] Names of agents that couldn't be restored
31
- # @param skipped_delegations [Array<String>] Names of delegation instances that couldn't be restored
32
- def initialize(warnings:, skipped_agents:, skipped_delegations:)
33
- @warnings = warnings
34
- @skipped_agents = skipped_agents
35
- @skipped_delegations = skipped_delegations
36
- end
37
-
38
- # Check if restore was completely successful
39
- #
40
- # @return [Boolean] true if all agents restored without warnings
41
- def success?
42
- warnings.empty?
43
- end
44
-
45
- # Check if restore was partial (some agents skipped)
46
- #
47
- # @return [Boolean] true if some agents were skipped
48
- def partial_restore?
49
- !warnings.empty?
50
- end
51
-
52
- # Get human-readable summary of restore result
53
- #
54
- # @return [String] Summary message
55
- def summary
56
- if success?
57
- "Snapshot restored successfully. All agents restored."
58
- else
59
- "Snapshot restored with warnings. " \
60
- "#{skipped_agents.size} agents skipped, " \
61
- "#{skipped_delegations.size} delegation instances skipped."
62
- end
63
- end
64
- end
65
- end