swarm_memory 2.1.4 → 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 (184) hide show
  1. checksums.yaml +4 -4
  2. data/lib/swarm_memory/version.rb +1 -1
  3. data/lib/swarm_memory.rb +7 -2
  4. metadata +6 -185
  5. data/lib/claude_swarm/base_executor.rb +0 -133
  6. data/lib/claude_swarm/claude_code_executor.rb +0 -349
  7. data/lib/claude_swarm/claude_mcp_server.rb +0 -78
  8. data/lib/claude_swarm/cli.rb +0 -697
  9. data/lib/claude_swarm/commands/ps.rb +0 -215
  10. data/lib/claude_swarm/commands/show.rb +0 -139
  11. data/lib/claude_swarm/configuration.rb +0 -373
  12. data/lib/claude_swarm/hooks/session_start_hook.rb +0 -42
  13. data/lib/claude_swarm/json_handler.rb +0 -91
  14. data/lib/claude_swarm/mcp_generator.rb +0 -243
  15. data/lib/claude_swarm/openai/chat_completion.rb +0 -256
  16. data/lib/claude_swarm/openai/executor.rb +0 -256
  17. data/lib/claude_swarm/openai/responses.rb +0 -319
  18. data/lib/claude_swarm/orchestrator.rb +0 -878
  19. data/lib/claude_swarm/process_tracker.rb +0 -78
  20. data/lib/claude_swarm/session_cost_calculator.rb +0 -209
  21. data/lib/claude_swarm/session_path.rb +0 -42
  22. data/lib/claude_swarm/settings_generator.rb +0 -77
  23. data/lib/claude_swarm/system_utils.rb +0 -46
  24. data/lib/claude_swarm/templates/generation_prompt.md.erb +0 -230
  25. data/lib/claude_swarm/tools/reset_session_tool.rb +0 -24
  26. data/lib/claude_swarm/tools/session_info_tool.rb +0 -24
  27. data/lib/claude_swarm/tools/task_tool.rb +0 -63
  28. data/lib/claude_swarm/version.rb +0 -5
  29. data/lib/claude_swarm/worktree_manager.rb +0 -475
  30. data/lib/claude_swarm/yaml_loader.rb +0 -22
  31. data/lib/claude_swarm.rb +0 -67
  32. data/lib/swarm_cli/cli.rb +0 -201
  33. data/lib/swarm_cli/command_registry.rb +0 -61
  34. data/lib/swarm_cli/commands/mcp_serve.rb +0 -130
  35. data/lib/swarm_cli/commands/mcp_tools.rb +0 -148
  36. data/lib/swarm_cli/commands/migrate.rb +0 -55
  37. data/lib/swarm_cli/commands/run.rb +0 -173
  38. data/lib/swarm_cli/config_loader.rb +0 -98
  39. data/lib/swarm_cli/formatters/human_formatter.rb +0 -781
  40. data/lib/swarm_cli/formatters/json_formatter.rb +0 -51
  41. data/lib/swarm_cli/interactive_repl.rb +0 -924
  42. data/lib/swarm_cli/mcp_serve_options.rb +0 -44
  43. data/lib/swarm_cli/mcp_tools_options.rb +0 -59
  44. data/lib/swarm_cli/migrate_options.rb +0 -54
  45. data/lib/swarm_cli/migrator.rb +0 -132
  46. data/lib/swarm_cli/options.rb +0 -151
  47. data/lib/swarm_cli/ui/components/agent_badge.rb +0 -33
  48. data/lib/swarm_cli/ui/components/content_block.rb +0 -120
  49. data/lib/swarm_cli/ui/components/divider.rb +0 -57
  50. data/lib/swarm_cli/ui/components/panel.rb +0 -62
  51. data/lib/swarm_cli/ui/components/usage_stats.rb +0 -70
  52. data/lib/swarm_cli/ui/formatters/cost.rb +0 -49
  53. data/lib/swarm_cli/ui/formatters/number.rb +0 -58
  54. data/lib/swarm_cli/ui/formatters/text.rb +0 -77
  55. data/lib/swarm_cli/ui/formatters/time.rb +0 -73
  56. data/lib/swarm_cli/ui/icons.rb +0 -36
  57. data/lib/swarm_cli/ui/renderers/event_renderer.rb +0 -188
  58. data/lib/swarm_cli/ui/state/agent_color_cache.rb +0 -45
  59. data/lib/swarm_cli/ui/state/depth_tracker.rb +0 -40
  60. data/lib/swarm_cli/ui/state/spinner_manager.rb +0 -170
  61. data/lib/swarm_cli/ui/state/usage_tracker.rb +0 -62
  62. data/lib/swarm_cli/version.rb +0 -5
  63. data/lib/swarm_cli.rb +0 -46
  64. data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -127
  65. data/lib/swarm_sdk/agent/builder.rb +0 -552
  66. data/lib/swarm_sdk/agent/chat.rb +0 -774
  67. data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -268
  68. data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +0 -204
  69. data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +0 -480
  70. data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +0 -78
  71. data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -233
  72. data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +0 -116
  73. data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +0 -83
  74. data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +0 -136
  75. data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
  76. data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -98
  77. data/lib/swarm_sdk/agent/context.rb +0 -116
  78. data/lib/swarm_sdk/agent/context_manager.rb +0 -315
  79. data/lib/swarm_sdk/agent/definition.rb +0 -477
  80. data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -182
  81. data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -161
  82. data/lib/swarm_sdk/builders/base_builder.rb +0 -409
  83. data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
  84. data/lib/swarm_sdk/concerns/cleanupable.rb +0 -39
  85. data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
  86. data/lib/swarm_sdk/concerns/validatable.rb +0 -55
  87. data/lib/swarm_sdk/configuration/parser.rb +0 -353
  88. data/lib/swarm_sdk/configuration/translator.rb +0 -255
  89. data/lib/swarm_sdk/configuration.rb +0 -135
  90. data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
  91. data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -106
  92. data/lib/swarm_sdk/context_compactor.rb +0 -335
  93. data/lib/swarm_sdk/context_management/builder.rb +0 -128
  94. data/lib/swarm_sdk/context_management/context.rb +0 -328
  95. data/lib/swarm_sdk/defaults.rb +0 -196
  96. data/lib/swarm_sdk/events_to_messages.rb +0 -199
  97. data/lib/swarm_sdk/hooks/adapter.rb +0 -359
  98. data/lib/swarm_sdk/hooks/context.rb +0 -197
  99. data/lib/swarm_sdk/hooks/definition.rb +0 -80
  100. data/lib/swarm_sdk/hooks/error.rb +0 -29
  101. data/lib/swarm_sdk/hooks/executor.rb +0 -146
  102. data/lib/swarm_sdk/hooks/registry.rb +0 -147
  103. data/lib/swarm_sdk/hooks/result.rb +0 -150
  104. data/lib/swarm_sdk/hooks/shell_executor.rb +0 -255
  105. data/lib/swarm_sdk/hooks/tool_call.rb +0 -35
  106. data/lib/swarm_sdk/hooks/tool_result.rb +0 -62
  107. data/lib/swarm_sdk/log_collector.rb +0 -227
  108. data/lib/swarm_sdk/log_stream.rb +0 -127
  109. data/lib/swarm_sdk/markdown_parser.rb +0 -75
  110. data/lib/swarm_sdk/model_aliases.json +0 -8
  111. data/lib/swarm_sdk/models.json +0 -1
  112. data/lib/swarm_sdk/models.rb +0 -120
  113. data/lib/swarm_sdk/node_context.rb +0 -245
  114. data/lib/swarm_sdk/observer/builder.rb +0 -81
  115. data/lib/swarm_sdk/observer/config.rb +0 -45
  116. data/lib/swarm_sdk/observer/manager.rb +0 -236
  117. data/lib/swarm_sdk/patterns/agent_observer.rb +0 -160
  118. data/lib/swarm_sdk/permissions/config.rb +0 -239
  119. data/lib/swarm_sdk/permissions/error_formatter.rb +0 -121
  120. data/lib/swarm_sdk/permissions/path_matcher.rb +0 -35
  121. data/lib/swarm_sdk/permissions/validator.rb +0 -173
  122. data/lib/swarm_sdk/permissions_builder.rb +0 -122
  123. data/lib/swarm_sdk/plugin.rb +0 -309
  124. data/lib/swarm_sdk/plugin_registry.rb +0 -101
  125. data/lib/swarm_sdk/proc_helpers.rb +0 -53
  126. data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -117
  127. data/lib/swarm_sdk/restore_result.rb +0 -65
  128. data/lib/swarm_sdk/result.rb +0 -123
  129. data/lib/swarm_sdk/snapshot.rb +0 -156
  130. data/lib/swarm_sdk/snapshot_from_events.rb +0 -397
  131. data/lib/swarm_sdk/state_restorer.rb +0 -476
  132. data/lib/swarm_sdk/state_snapshot.rb +0 -334
  133. data/lib/swarm_sdk/swarm/agent_initializer.rb +0 -683
  134. data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -167
  135. data/lib/swarm_sdk/swarm/builder.rb +0 -249
  136. data/lib/swarm_sdk/swarm/executor.rb +0 -213
  137. data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -150
  138. data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -340
  139. data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -154
  140. data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
  141. data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -358
  142. data/lib/swarm_sdk/swarm.rb +0 -717
  143. data/lib/swarm_sdk/swarm_loader.rb +0 -145
  144. data/lib/swarm_sdk/swarm_registry.rb +0 -136
  145. data/lib/swarm_sdk/tools/bash.rb +0 -282
  146. data/lib/swarm_sdk/tools/clock.rb +0 -44
  147. data/lib/swarm_sdk/tools/delegate.rb +0 -267
  148. data/lib/swarm_sdk/tools/document_converters/base_converter.rb +0 -83
  149. data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +0 -99
  150. data/lib/swarm_sdk/tools/document_converters/html_converter.rb +0 -101
  151. data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +0 -78
  152. data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +0 -194
  153. data/lib/swarm_sdk/tools/edit.rb +0 -145
  154. data/lib/swarm_sdk/tools/glob.rb +0 -166
  155. data/lib/swarm_sdk/tools/grep.rb +0 -235
  156. data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +0 -43
  157. data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +0 -163
  158. data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
  159. data/lib/swarm_sdk/tools/multi_edit.rb +0 -236
  160. data/lib/swarm_sdk/tools/path_resolver.rb +0 -92
  161. data/lib/swarm_sdk/tools/read.rb +0 -261
  162. data/lib/swarm_sdk/tools/registry.rb +0 -205
  163. data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +0 -117
  164. data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +0 -97
  165. data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +0 -108
  166. data/lib/swarm_sdk/tools/stores/read_tracker.rb +0 -96
  167. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +0 -272
  168. data/lib/swarm_sdk/tools/stores/storage.rb +0 -142
  169. data/lib/swarm_sdk/tools/stores/todo_manager.rb +0 -65
  170. data/lib/swarm_sdk/tools/think.rb +0 -98
  171. data/lib/swarm_sdk/tools/todo_write.rb +0 -235
  172. data/lib/swarm_sdk/tools/web_fetch.rb +0 -262
  173. data/lib/swarm_sdk/tools/write.rb +0 -112
  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 -79
  178. data/lib/swarm_sdk/workflow/builder.rb +0 -143
  179. data/lib/swarm_sdk/workflow/executor.rb +0 -497
  180. data/lib/swarm_sdk/workflow/node_builder.rb +0 -555
  181. data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -249
  182. data/lib/swarm_sdk/workflow.rb +0 -554
  183. data/lib/swarm_sdk.rb +0 -524
  184. /data/lib/swarm_memory/{errors.rb → error.rb} +0 -0
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # Models provides model validation and suggestion functionality
5
- #
6
- # Uses static JSON files:
7
- # - models.json: Curated model list from Parsera
8
- # - model_aliases.json: Shortcuts mapping to latest models
9
- #
10
- # This avoids network calls, API key requirements, and RubyLLM
11
- # registry manipulation.
12
- #
13
- # @example
14
- # model = SwarmSDK::Models.find("claude-sonnet-4-5-20250929")
15
- # model = SwarmSDK::Models.find("sonnet") # Uses alias
16
- # suggestions = SwarmSDK::Models.suggest_similar("anthropic:claude-sonnet-4-5")
17
- class Models
18
- MODELS_JSON_PATH = File.expand_path("models.json", __dir__)
19
- ALIASES_JSON_PATH = File.expand_path("model_aliases.json", __dir__)
20
-
21
- class << self
22
- # Find a model by ID or alias
23
- #
24
- # @param model_id [String] Model ID or alias to find
25
- # @return [Hash, nil] Model data or nil if not found
26
- def find(model_id)
27
- # Check if it's an alias first
28
- resolved_id = resolve_alias(model_id)
29
-
30
- all.find { |m| m["id"] == resolved_id || m[:id] == resolved_id }
31
- end
32
-
33
- # Resolve a model alias to full model ID
34
- #
35
- # @param model_id [String] Model ID or alias
36
- # @return [String] Resolved model ID (or original if not an alias)
37
- def resolve_alias(model_id)
38
- aliases[model_id.to_s] || model_id
39
- end
40
-
41
- # Suggest similar models for a given query
42
- #
43
- # Strips provider prefixes and normalizes for fuzzy matching.
44
- #
45
- # @param query [String] Model ID to match against
46
- # @param limit [Integer] Maximum number of suggestions
47
- # @return [Array<Hash>] Up to `limit` similar models
48
- def suggest_similar(query, limit: 3)
49
- # Strip provider prefix (e.g., "anthropic:claude-sonnet-4-5" → "claude-sonnet-4-5")
50
- query_without_prefix = query.to_s.sub(/^[^:]+:/, "")
51
- normalized_query = query_without_prefix.downcase.gsub(/[.\-_]/, "")
52
-
53
- matches = all.select do |model|
54
- model_id = (model["id"] || model[:id]).to_s
55
- model_name = (model["name"] || model[:name]).to_s
56
-
57
- normalized_id = model_id.downcase.gsub(/[.\-_]/, "")
58
- normalized_name = model_name.downcase.gsub(/[.\-_]/, "")
59
-
60
- normalized_id.include?(normalized_query) || normalized_name.include?(normalized_query)
61
- end.first(limit)
62
-
63
- matches.map do |m|
64
- {
65
- id: m["id"] || m[:id],
66
- name: m["name"] || m[:name],
67
- context_window: m["context_window"] || m[:context_window],
68
- }
69
- end
70
- end
71
-
72
- # Get all models
73
- #
74
- # @return [Array<Hash>] All models from models.json
75
- def all
76
- @models ||= load_models
77
- end
78
-
79
- # Get all aliases
80
- #
81
- # @return [Hash] Alias mappings
82
- def aliases
83
- @aliases ||= load_aliases
84
- end
85
-
86
- # Reload models and aliases from JSON files
87
- #
88
- # @return [Array<Hash>] Loaded models
89
- def reload!
90
- @models = load_models
91
- @aliases = load_aliases
92
- @models
93
- end
94
-
95
- private
96
-
97
- # Load models from JSON file
98
- #
99
- # @return [Array<Hash>] Models array
100
- def load_models
101
- JSON.parse(File.read(MODELS_JSON_PATH))
102
- rescue StandardError => e
103
- # Log error and return empty array
104
- RubyLLM.logger.error("Failed to load SwarmSDK models.json: #{e.class} - #{e.message}")
105
- []
106
- end
107
-
108
- # Load aliases from JSON file
109
- #
110
- # @return [Hash] Alias mappings
111
- def load_aliases
112
- JSON.parse(File.read(ALIASES_JSON_PATH))
113
- rescue StandardError => e
114
- # Log error and return empty hash
115
- RubyLLM.logger.debug("Failed to load SwarmSDK model_aliases.json: #{e.class} - #{e.message}")
116
- {}
117
- end
118
- end
119
- end
120
- end
@@ -1,245 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # NodeContext provides context information to node transformers
5
- #
6
- # This class is passed to input and output transformers, giving them access to:
7
- # - The original user prompt
8
- # - Results from all previous nodes
9
- # - Current node metadata
10
- # - Convenience accessors for common operations
11
- #
12
- # @example Input transformer
13
- # input do |ctx|
14
- # ctx.content # Previous node's content (convenience)
15
- # ctx.original_prompt # Original user prompt
16
- # ctx.all_results[:plan] # Access any previous node
17
- # ctx.node_name # Current node name
18
- # end
19
- #
20
- # @example Output transformer
21
- # output do |ctx|
22
- # ctx.content # Current result's content (convenience)
23
- # ctx.original_prompt # Original user prompt
24
- # ctx.all_results[:plan] # Access previous nodes
25
- # end
26
- class NodeContext
27
- attr_reader :original_prompt, :all_results, :node_name, :dependencies
28
-
29
- # For input transformers: result from previous node(s)
30
- attr_reader :previous_result
31
-
32
- # For output transformers: current node's result
33
- attr_reader :result
34
-
35
- class << self
36
- # Create a NodeContext for input transformers
37
- #
38
- # @param previous_result [Result, Hash, String] Previous node's result or hash of results
39
- # @param all_results [Hash<Symbol, Result>] Results from all completed nodes
40
- # @param original_prompt [String] The original user prompt
41
- # @param node_name [Symbol] Current node name
42
- # @param dependencies [Array<Symbol>] Node dependencies
43
- # @param transformed_content [String, nil] Already-transformed content from previous output transformer
44
- # @return [NodeContext]
45
- def for_input(previous_result:, all_results:, original_prompt:, node_name:, dependencies:, transformed_content: nil)
46
- new(
47
- previous_result: previous_result,
48
- all_results: all_results,
49
- original_prompt: original_prompt,
50
- node_name: node_name,
51
- dependencies: dependencies,
52
- result: nil,
53
- transformed_content: transformed_content,
54
- )
55
- end
56
-
57
- # Create a NodeContext for output transformers
58
- #
59
- # @param result [Result] Current node's execution result
60
- # @param all_results [Hash<Symbol, Result>] Results from all completed nodes (including current)
61
- # @param original_prompt [String] The original user prompt
62
- # @param node_name [Symbol] Current node name
63
- # @return [NodeContext]
64
- def for_output(result:, all_results:, original_prompt:, node_name:)
65
- new(
66
- result: result,
67
- all_results: all_results,
68
- original_prompt: original_prompt,
69
- node_name: node_name,
70
- dependencies: [],
71
- previous_result: nil,
72
- transformed_content: nil,
73
- )
74
- end
75
- end
76
-
77
- def initialize(previous_result:, all_results:, original_prompt:, node_name:, dependencies:, result:, transformed_content:)
78
- @previous_result = previous_result
79
- @result = result
80
- @all_results = all_results
81
- @original_prompt = original_prompt
82
- @node_name = node_name
83
- @dependencies = dependencies
84
- @transformed_content = transformed_content
85
- end
86
-
87
- # Convenience accessor: Get content from previous_result or result
88
- #
89
- # For input transformers:
90
- # - Returns transformed_content if available (from previous output transformer)
91
- # - Otherwise returns previous_result.content (original content)
92
- # - Returns nil for multiple dependencies (use all_results instead)
93
- # For output transformers: returns result.content
94
- #
95
- # @return [String, nil]
96
- def content
97
- if @result
98
- # Output transformer context: return current result's content
99
- @result.content
100
- elsif @transformed_content
101
- # Input transformer with transformed content from previous output
102
- @transformed_content
103
- elsif @previous_result.respond_to?(:content)
104
- # Input transformer context with Result object (original content)
105
- @previous_result.content
106
- elsif @previous_result.is_a?(Hash)
107
- # Input transformer with multiple dependencies (hash of results)
108
- nil # No single "content" - user must pick from all_results hash
109
- else
110
- # String or other type (initial prompt, no dependencies)
111
- @previous_result.to_s
112
- end
113
- end
114
-
115
- # Convenience accessor: Get agent from previous_result or result
116
- #
117
- # @return [String, nil]
118
- def agent
119
- if @result
120
- @result.agent
121
- elsif @previous_result.respond_to?(:agent)
122
- @previous_result.agent
123
- end
124
- end
125
-
126
- # Convenience accessor: Get logs from previous_result or result
127
- #
128
- # @return [Array, nil]
129
- def logs
130
- if @result
131
- @result.logs
132
- elsif @previous_result.respond_to?(:logs)
133
- @previous_result.logs
134
- end
135
- end
136
-
137
- # Convenience accessor: Get duration from previous_result or result
138
- #
139
- # @return [Float, nil]
140
- def duration
141
- if @result
142
- @result.duration
143
- elsif @previous_result.respond_to?(:duration)
144
- @previous_result.duration
145
- end
146
- end
147
-
148
- # Convenience accessor: Get error from previous_result or result
149
- #
150
- # @return [Exception, nil]
151
- def error
152
- if @result
153
- @result.error
154
- elsif @previous_result.respond_to?(:error)
155
- @previous_result.error
156
- end
157
- end
158
-
159
- # Convenience accessor: Check success status
160
- #
161
- # @return [Boolean, nil]
162
- def success?
163
- if @result
164
- @result.success?
165
- elsif @previous_result.respond_to?(:success?)
166
- @previous_result.success?
167
- end
168
- end
169
-
170
- # Control flow methods for transformers
171
- # These return special hashes that Workflow recognizes
172
-
173
- # Skip current node's LLM execution and return content immediately
174
- #
175
- # Only valid for input transformers.
176
- #
177
- # @param content [String] Content to return (skips LLM call)
178
- # @return [Hash] Control hash for skip_execution
179
- # @raise [ArgumentError] If content is nil
180
- #
181
- # @example
182
- # input do |ctx|
183
- # cached = check_cache(ctx.content)
184
- # return ctx.skip_execution(content: cached) if cached
185
- # ctx.content
186
- # end
187
- def skip_execution(content:)
188
- if content.nil?
189
- raise ArgumentError,
190
- "skip_execution requires content (got nil). " \
191
- "Check that ctx.content or your content source is not nil. " \
192
- "Node: #{@node_name}"
193
- end
194
- { skip_execution: true, content: content }
195
- end
196
-
197
- # Halt entire workflow and return content as final result
198
- #
199
- # Valid for both input and output transformers.
200
- #
201
- # @param content [String] Final content to return
202
- # @return [Hash] Control hash for halt_workflow
203
- # @raise [ArgumentError] If content is nil
204
- #
205
- # @example
206
- # output do |ctx|
207
- # return ctx.halt_workflow(content: ctx.content) if converged?(ctx.content)
208
- # ctx.content
209
- # end
210
- def halt_workflow(content:)
211
- if content.nil?
212
- raise ArgumentError,
213
- "halt_workflow requires content (got nil). " \
214
- "Check that ctx.content or your content source is not nil. " \
215
- "Node: #{@node_name}"
216
- end
217
- { halt_workflow: true, content: content }
218
- end
219
-
220
- # Jump to a different node with provided content as input
221
- #
222
- # Valid for both input and output transformers.
223
- #
224
- # @param node [Symbol] Node name to jump to
225
- # @param content [String] Content to pass to target node
226
- # @return [Hash] Control hash for goto_node
227
- # @raise [ArgumentError] If content is nil
228
- #
229
- # @example
230
- # input do |ctx|
231
- # return ctx.goto_node(:review, content: ctx.content) if needs_review?(ctx.content)
232
- # ctx.content
233
- # end
234
- def goto_node(node, content:)
235
- if content.nil?
236
- raise ArgumentError,
237
- "goto_node requires content (got nil). " \
238
- "Check that ctx.content or your content source is not nil. " \
239
- "This often happens when the previous node failed with an error. " \
240
- "Node: #{@node_name}, Target: #{node}"
241
- end
242
- { goto_node: node.to_sym, content: content }
243
- end
244
- end
245
- end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- module Observer
5
- # DSL for configuring observer agents
6
- #
7
- # Used by Swarm::Builder#observer to provide a clean DSL for defining
8
- # event handlers and observer configuration options.
9
- #
10
- # @example Basic usage
11
- # observer :profiler do
12
- # on :swarm_start do |event|
13
- # "Analyze this prompt: #{event[:prompt]}"
14
- # end
15
- #
16
- # timeout 120
17
- # max_concurrent 2
18
- # end
19
- class Builder
20
- # Initialize builder with agent name and config
21
- #
22
- # @param agent_name [Symbol] Name of the observer agent
23
- # @param config [Observer::Config] Configuration object to populate
24
- def initialize(agent_name, config)
25
- @agent_name = agent_name
26
- @config = config
27
- end
28
-
29
- # Register an event handler
30
- #
31
- # The block receives the event hash and should return:
32
- # - A prompt string to trigger the observer agent
33
- # - nil to skip execution for this event
34
- #
35
- # @param event_type [Symbol] Type of event to handle (e.g., :swarm_start, :tool_call)
36
- # @yield [Hash] Event hash
37
- # @yieldreturn [String, nil] Prompt or nil to skip
38
- # @return [void]
39
- #
40
- # @example
41
- # on :tool_call do |event|
42
- # next unless event[:tool_name] == "Bash"
43
- # "Check this command: #{event[:arguments][:command]}"
44
- # end
45
- def on(event_type, &block)
46
- @config.add_handler(event_type, &block)
47
- end
48
-
49
- # Set maximum concurrent executions for this observer
50
- #
51
- # Limits how many instances of this observer agent can run simultaneously.
52
- # Useful for resource-intensive observers.
53
- #
54
- # @param n [Integer] Maximum concurrent executions
55
- # @return [void]
56
- def max_concurrent(n)
57
- @config.options[:max_concurrent] = n
58
- end
59
-
60
- # Set timeout for observer execution
61
- #
62
- # Observer tasks will be cancelled after this duration.
63
- #
64
- # @param seconds [Integer] Timeout in seconds (default: 60)
65
- # @return [void]
66
- def timeout(seconds)
67
- @config.options[:timeout] = seconds
68
- end
69
-
70
- # Wait for observer to complete before swarm execution ends
71
- #
72
- # By default, observers are fire-and-forget. This option causes
73
- # the main execution to wait for this observer to complete.
74
- #
75
- # @return [void]
76
- def wait_for_completion!
77
- @config.options[:fire_and_forget] = false
78
- end
79
- end
80
- end
81
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- module Observer
5
- # Configuration for an observer agent
6
- #
7
- # Holds the agent name, event handlers (blocks that return prompts or nil),
8
- # and execution options.
9
- #
10
- # @example
11
- # config = Observer::Config.new(:profiler)
12
- # config.add_handler(:swarm_start) { |event| "Analyze: #{event[:prompt]}" }
13
- # config.options[:timeout] = 120
14
- class Config
15
- attr_reader :agent_name, :event_handlers, :options
16
-
17
- # Initialize a new observer configuration
18
- #
19
- # @param agent_name [Symbol] Name of the agent to use as observer
20
- def initialize(agent_name)
21
- @agent_name = agent_name
22
- @event_handlers = {} # { event_type => block }
23
- @options = {
24
- max_concurrent: nil,
25
- timeout: 60,
26
- fire_and_forget: true,
27
- }
28
- end
29
-
30
- # Add an event handler for a specific event type
31
- #
32
- # The block receives the event hash and should return:
33
- # - A prompt string to trigger the observer agent
34
- # - nil to skip execution for this event
35
- #
36
- # @param event_type [Symbol] Type of event to handle (e.g., :swarm_start, :tool_call)
37
- # @yield [Hash] Event hash with type, agent, and other data
38
- # @yieldreturn [String, nil] Prompt to execute or nil to skip
39
- # @return [void]
40
- def add_handler(event_type, &block)
41
- @event_handlers[event_type] = block
42
- end
43
- end
44
- end
45
- end