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.
- checksums.yaml +4 -4
- data/lib/swarm_memory/version.rb +1 -1
- metadata +5 -184
- data/lib/claude_swarm/base_executor.rb +0 -133
- data/lib/claude_swarm/claude_code_executor.rb +0 -349
- data/lib/claude_swarm/claude_mcp_server.rb +0 -78
- data/lib/claude_swarm/cli.rb +0 -697
- data/lib/claude_swarm/commands/ps.rb +0 -215
- data/lib/claude_swarm/commands/show.rb +0 -139
- data/lib/claude_swarm/configuration.rb +0 -373
- data/lib/claude_swarm/hooks/session_start_hook.rb +0 -42
- data/lib/claude_swarm/json_handler.rb +0 -91
- data/lib/claude_swarm/mcp_generator.rb +0 -230
- data/lib/claude_swarm/openai/chat_completion.rb +0 -256
- data/lib/claude_swarm/openai/executor.rb +0 -256
- data/lib/claude_swarm/openai/responses.rb +0 -319
- data/lib/claude_swarm/orchestrator.rb +0 -878
- data/lib/claude_swarm/process_tracker.rb +0 -78
- data/lib/claude_swarm/session_cost_calculator.rb +0 -209
- data/lib/claude_swarm/session_path.rb +0 -42
- data/lib/claude_swarm/settings_generator.rb +0 -77
- data/lib/claude_swarm/system_utils.rb +0 -46
- data/lib/claude_swarm/templates/generation_prompt.md.erb +0 -230
- data/lib/claude_swarm/tools/reset_session_tool.rb +0 -24
- data/lib/claude_swarm/tools/session_info_tool.rb +0 -24
- data/lib/claude_swarm/tools/task_tool.rb +0 -63
- data/lib/claude_swarm/version.rb +0 -5
- data/lib/claude_swarm/worktree_manager.rb +0 -475
- data/lib/claude_swarm/yaml_loader.rb +0 -22
- data/lib/claude_swarm.rb +0 -67
- data/lib/swarm_cli/cli.rb +0 -201
- data/lib/swarm_cli/command_registry.rb +0 -61
- data/lib/swarm_cli/commands/mcp_serve.rb +0 -130
- data/lib/swarm_cli/commands/mcp_tools.rb +0 -148
- data/lib/swarm_cli/commands/migrate.rb +0 -55
- data/lib/swarm_cli/commands/run.rb +0 -173
- data/lib/swarm_cli/config_loader.rb +0 -98
- data/lib/swarm_cli/formatters/human_formatter.rb +0 -781
- data/lib/swarm_cli/formatters/json_formatter.rb +0 -51
- data/lib/swarm_cli/interactive_repl.rb +0 -924
- data/lib/swarm_cli/mcp_serve_options.rb +0 -44
- data/lib/swarm_cli/mcp_tools_options.rb +0 -59
- data/lib/swarm_cli/migrate_options.rb +0 -54
- data/lib/swarm_cli/migrator.rb +0 -132
- data/lib/swarm_cli/options.rb +0 -151
- data/lib/swarm_cli/ui/components/agent_badge.rb +0 -33
- data/lib/swarm_cli/ui/components/content_block.rb +0 -120
- data/lib/swarm_cli/ui/components/divider.rb +0 -57
- data/lib/swarm_cli/ui/components/panel.rb +0 -62
- data/lib/swarm_cli/ui/components/usage_stats.rb +0 -70
- data/lib/swarm_cli/ui/formatters/cost.rb +0 -49
- data/lib/swarm_cli/ui/formatters/number.rb +0 -58
- data/lib/swarm_cli/ui/formatters/text.rb +0 -77
- data/lib/swarm_cli/ui/formatters/time.rb +0 -73
- data/lib/swarm_cli/ui/icons.rb +0 -36
- data/lib/swarm_cli/ui/renderers/event_renderer.rb +0 -188
- data/lib/swarm_cli/ui/state/agent_color_cache.rb +0 -45
- data/lib/swarm_cli/ui/state/depth_tracker.rb +0 -40
- data/lib/swarm_cli/ui/state/spinner_manager.rb +0 -170
- data/lib/swarm_cli/ui/state/usage_tracker.rb +0 -62
- data/lib/swarm_cli/version.rb +0 -5
- data/lib/swarm_cli.rb +0 -46
- data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -127
- data/lib/swarm_sdk/agent/builder.rb +0 -552
- data/lib/swarm_sdk/agent/chat.rb +0 -774
- data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -268
- data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +0 -204
- data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +0 -480
- data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +0 -78
- data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -233
- data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +0 -116
- data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +0 -83
- data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +0 -136
- data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
- data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -98
- data/lib/swarm_sdk/agent/context.rb +0 -116
- data/lib/swarm_sdk/agent/context_manager.rb +0 -315
- data/lib/swarm_sdk/agent/definition.rb +0 -477
- data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -182
- data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -161
- data/lib/swarm_sdk/builders/base_builder.rb +0 -409
- data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
- data/lib/swarm_sdk/concerns/cleanupable.rb +0 -39
- data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
- data/lib/swarm_sdk/concerns/validatable.rb +0 -55
- data/lib/swarm_sdk/configuration/parser.rb +0 -353
- data/lib/swarm_sdk/configuration/translator.rb +0 -255
- data/lib/swarm_sdk/configuration.rb +0 -135
- data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
- data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -106
- data/lib/swarm_sdk/context_compactor.rb +0 -335
- data/lib/swarm_sdk/context_management/builder.rb +0 -128
- data/lib/swarm_sdk/context_management/context.rb +0 -328
- data/lib/swarm_sdk/defaults.rb +0 -196
- data/lib/swarm_sdk/events_to_messages.rb +0 -199
- data/lib/swarm_sdk/hooks/adapter.rb +0 -359
- data/lib/swarm_sdk/hooks/context.rb +0 -197
- data/lib/swarm_sdk/hooks/definition.rb +0 -80
- data/lib/swarm_sdk/hooks/error.rb +0 -29
- data/lib/swarm_sdk/hooks/executor.rb +0 -146
- data/lib/swarm_sdk/hooks/registry.rb +0 -147
- data/lib/swarm_sdk/hooks/result.rb +0 -150
- data/lib/swarm_sdk/hooks/shell_executor.rb +0 -255
- data/lib/swarm_sdk/hooks/tool_call.rb +0 -35
- data/lib/swarm_sdk/hooks/tool_result.rb +0 -62
- data/lib/swarm_sdk/log_collector.rb +0 -227
- data/lib/swarm_sdk/log_stream.rb +0 -127
- data/lib/swarm_sdk/markdown_parser.rb +0 -75
- data/lib/swarm_sdk/model_aliases.json +0 -8
- data/lib/swarm_sdk/models.json +0 -1
- data/lib/swarm_sdk/models.rb +0 -120
- data/lib/swarm_sdk/node_context.rb +0 -245
- data/lib/swarm_sdk/observer/builder.rb +0 -81
- data/lib/swarm_sdk/observer/config.rb +0 -45
- data/lib/swarm_sdk/observer/manager.rb +0 -236
- data/lib/swarm_sdk/patterns/agent_observer.rb +0 -160
- data/lib/swarm_sdk/permissions/config.rb +0 -239
- data/lib/swarm_sdk/permissions/error_formatter.rb +0 -121
- data/lib/swarm_sdk/permissions/path_matcher.rb +0 -35
- data/lib/swarm_sdk/permissions/validator.rb +0 -173
- data/lib/swarm_sdk/permissions_builder.rb +0 -122
- data/lib/swarm_sdk/plugin.rb +0 -309
- data/lib/swarm_sdk/plugin_registry.rb +0 -101
- data/lib/swarm_sdk/proc_helpers.rb +0 -53
- data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -117
- data/lib/swarm_sdk/restore_result.rb +0 -65
- data/lib/swarm_sdk/result.rb +0 -123
- data/lib/swarm_sdk/snapshot.rb +0 -156
- data/lib/swarm_sdk/snapshot_from_events.rb +0 -397
- data/lib/swarm_sdk/state_restorer.rb +0 -476
- data/lib/swarm_sdk/state_snapshot.rb +0 -334
- data/lib/swarm_sdk/swarm/agent_initializer.rb +0 -683
- data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -167
- data/lib/swarm_sdk/swarm/builder.rb +0 -249
- data/lib/swarm_sdk/swarm/executor.rb +0 -213
- data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -150
- data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -340
- data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -154
- data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
- data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -358
- data/lib/swarm_sdk/swarm.rb +0 -717
- data/lib/swarm_sdk/swarm_loader.rb +0 -145
- data/lib/swarm_sdk/swarm_registry.rb +0 -136
- data/lib/swarm_sdk/tools/bash.rb +0 -282
- data/lib/swarm_sdk/tools/clock.rb +0 -44
- data/lib/swarm_sdk/tools/delegate.rb +0 -267
- data/lib/swarm_sdk/tools/document_converters/base_converter.rb +0 -83
- data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +0 -99
- data/lib/swarm_sdk/tools/document_converters/html_converter.rb +0 -101
- data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +0 -78
- data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +0 -194
- data/lib/swarm_sdk/tools/edit.rb +0 -145
- data/lib/swarm_sdk/tools/glob.rb +0 -166
- data/lib/swarm_sdk/tools/grep.rb +0 -235
- data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +0 -43
- data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +0 -163
- data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
- data/lib/swarm_sdk/tools/multi_edit.rb +0 -236
- data/lib/swarm_sdk/tools/path_resolver.rb +0 -92
- data/lib/swarm_sdk/tools/read.rb +0 -261
- data/lib/swarm_sdk/tools/registry.rb +0 -205
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +0 -117
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +0 -97
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +0 -108
- data/lib/swarm_sdk/tools/stores/read_tracker.rb +0 -96
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +0 -272
- data/lib/swarm_sdk/tools/stores/storage.rb +0 -142
- data/lib/swarm_sdk/tools/stores/todo_manager.rb +0 -65
- data/lib/swarm_sdk/tools/think.rb +0 -98
- data/lib/swarm_sdk/tools/todo_write.rb +0 -235
- data/lib/swarm_sdk/tools/web_fetch.rb +0 -262
- data/lib/swarm_sdk/tools/write.rb +0 -112
- data/lib/swarm_sdk/utils.rb +0 -68
- data/lib/swarm_sdk/validation_result.rb +0 -33
- data/lib/swarm_sdk/version.rb +0 -5
- data/lib/swarm_sdk/workflow/agent_config.rb +0 -79
- data/lib/swarm_sdk/workflow/builder.rb +0 -143
- data/lib/swarm_sdk/workflow/executor.rb +0 -497
- data/lib/swarm_sdk/workflow/node_builder.rb +0 -555
- data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -249
- data/lib/swarm_sdk/workflow.rb +0 -554
- data/lib/swarm_sdk.rb +0 -524
data/lib/swarm_sdk/models.rb
DELETED
|
@@ -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
|