Module: SwarmSDK

Defined in:
lib/swarm_sdk/ruby_llm_patches/mcp_ssl_patch.rb,
lib/swarm_sdk.rb,
lib/swarm_sdk/swarm.rb,
lib/swarm_sdk/utils.rb,
lib/swarm_sdk/config.rb,
lib/swarm_sdk/models.rb,
lib/swarm_sdk/plugin.rb,
lib/swarm_sdk/result.rb,
lib/swarm_sdk/version.rb,
lib/swarm_sdk/defaults.rb,
lib/swarm_sdk/snapshot.rb,
lib/swarm_sdk/workflow.rb,
lib/swarm_sdk/agent/chat.rb,
lib/swarm_sdk/log_stream.rb,
lib/swarm_sdk/tools/base.rb,
lib/swarm_sdk/tools/bash.rb,
lib/swarm_sdk/tools/edit.rb,
lib/swarm_sdk/tools/glob.rb,
lib/swarm_sdk/tools/grep.rb,
lib/swarm_sdk/tools/read.rb,
lib/swarm_sdk/hooks/error.rb,
lib/swarm_sdk/tools/clock.rb,
lib/swarm_sdk/tools/think.rb,
lib/swarm_sdk/tools/write.rb,
lib/swarm_sdk/hooks/result.rb,
lib/swarm_sdk/node_context.rb,
lib/swarm_sdk/proc_helpers.rb,
lib/swarm_sdk/swarm_loader.rb,
lib/swarm_sdk/agent/builder.rb,
lib/swarm_sdk/agent/context.rb,
lib/swarm_sdk/configuration.rb,
lib/swarm_sdk/hooks/adapter.rb,
lib/swarm_sdk/hooks/context.rb,
lib/swarm_sdk/log_collector.rb,
lib/swarm_sdk/swarm/builder.rb,
lib/swarm_sdk/agent_registry.rb,
lib/swarm_sdk/hooks/executor.rb,
lib/swarm_sdk/hooks/registry.rb,
lib/swarm_sdk/restore_result.rb,
lib/swarm_sdk/state_restorer.rb,
lib/swarm_sdk/state_snapshot.rb,
lib/swarm_sdk/swarm/executor.rb,
lib/swarm_sdk/swarm_registry.rb,
lib/swarm_sdk/tools/delegate.rb,
lib/swarm_sdk/tools/registry.rb,
lib/swarm_sdk/hooks/tool_call.rb,
lib/swarm_sdk/markdown_parser.rb,
lib/swarm_sdk/observer/config.rb,
lib/swarm_sdk/plugin_registry.rb,
lib/swarm_sdk/tools/web_fetch.rb,
lib/swarm_sdk/agent/definition.rb,
lib/swarm_sdk/hooks/definition.rb,
lib/swarm_sdk/observer/builder.rb,
lib/swarm_sdk/observer/manager.rb,
lib/swarm_sdk/tools/multi_edit.rb,
lib/swarm_sdk/tools/todo_write.rb,
lib/swarm_sdk/workflow/builder.rb,
lib/swarm_sdk/context_compactor.rb,
lib/swarm_sdk/hooks/tool_result.rb,
lib/swarm_sdk/validation_result.rb,
lib/swarm_sdk/workflow/executor.rb,
lib/swarm_sdk/events_to_messages.rb,
lib/swarm_sdk/permissions/config.rb,
lib/swarm_sdk/transcript_builder.rb,
lib/swarm_sdk/agent/tool_registry.rb,
lib/swarm_sdk/permissions_builder.rb,
lib/swarm_sdk/swarm/hook_triggers.rb,
lib/swarm_sdk/tools/mcp_tool_stub.rb,
lib/swarm_sdk/tools/path_resolver.rb,
lib/swarm_sdk/concerns/cleanupable.rb,
lib/swarm_sdk/concerns/validatable.rb,
lib/swarm_sdk/configuration/parser.rb,
lib/swarm_sdk/custom_tool_registry.rb,
lib/swarm_sdk/hooks/shell_executor.rb,
lib/swarm_sdk/snapshot_from_events.rb,
lib/swarm_sdk/tools/stores/storage.rb,
lib/swarm_sdk/agent/context_manager.rb,
lib/swarm_sdk/builders/base_builder.rb,
lib/swarm_sdk/concerns/snapshotable.rb,
lib/swarm_sdk/permissions/validator.rb,
lib/swarm_sdk/workflow/agent_config.rb,
lib/swarm_sdk/workflow/node_builder.rb,
lib/swarm_sdk/swarm/mcp_configurator.rb,
lib/swarm_sdk/patterns/agent_observer.rb,
lib/swarm_sdk/swarm/agent_initializer.rb,
lib/swarm_sdk/swarm/logging_callbacks.rb,
lib/swarm_sdk/swarm/tool_configurator.rb,
lib/swarm_sdk/configuration/translator.rb,
lib/swarm_sdk/permissions/path_matcher.rb,
lib/swarm_sdk/swarm/all_agents_builder.rb,
lib/swarm_sdk/swarm/lazy_delegate_chat.rb,
lib/swarm_sdk/claude_code_agent_adapter.rb,
lib/swarm_sdk/context_compactor/metrics.rb,
lib/swarm_sdk/tools/stores/read_tracker.rb,
lib/swarm_sdk/tools/stores/todo_manager.rb,
lib/swarm_sdk/context_management/builder.rb,
lib/swarm_sdk/context_management/context.rb,
lib/swarm_sdk/agent/system_prompt_builder.rb,
lib/swarm_sdk/permissions/error_formatter.rb,
lib/swarm_sdk/swarm/swarm_registry_builder.rb,
lib/swarm_sdk/workflow/transformer_executor.rb,
lib/swarm_sdk/ruby_llm_patches/mcp_ssl_patch.rb,
lib/swarm_sdk/ruby_llm_patches/mcp_ssl_patch.rb,
lib/swarm_sdk/context_compactor/token_counter.rb,
lib/swarm_sdk/tools/stores/scratchpad_storage.rb,
lib/swarm_sdk/agent/chat_helpers/event_emitter.rb,
lib/swarm_sdk/agent/chat_helpers/serialization.rb,
lib/swarm_sdk/tools/image_formats/tiff_builder.rb,
lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb,
lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb,
lib/swarm_sdk/agent/chat_helpers/token_tracking.rb,
lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb,
lib/swarm_sdk/agent/chat_helpers/context_tracker.rb,
lib/swarm_sdk/agent/chat_helpers/instrumentation.rb,
lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb,
lib/swarm_sdk/agent/chat_helpers/hook_integration.rb,
lib/swarm_sdk/agent/chat_helpers/system_reminders.rb,
lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb,
lib/swarm_sdk/agent/llm_instrumentation_middleware.rb,
lib/swarm_sdk/tools/document_converters/pdf_converter.rb,
lib/swarm_sdk/tools/document_converters/base_converter.rb,
lib/swarm_sdk/tools/document_converters/docx_converter.rb,
lib/swarm_sdk/tools/document_converters/html_converter.rb,
lib/swarm_sdk/tools/document_converters/xlsx_converter.rb,
lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb,
lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb,
lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb

Overview

Patch 3: SSE#create_sse_client

This method calls HTTPX.plugin(:stream) directly, bypassing HTTPClient. Merges SSL options with ALPN protocol when version is :http1.

Defined Under Namespace

Modules: Agent, Builders, Concerns, ContextManagement, CustomToolRegistry, Defaults, Hooks, LogCollector, LogStream, McpSslPatch, Observer, Patterns, Permissions, PluginRegistry, ProcHelpers, Tools, Utils Classes: AgentNotFoundError, AgentRegistry, CircularDependencyError, ClaudeCodeAgentAdapter, Config, Configuration, ConfigurationError, ContextCompactor, Error, EventsToMessages, ExecutionTimeoutError, InterruptedError, LLMError, MCPError, MCPTimeoutError, MCPTransportError, MarkdownParser, Models, NodeContext, PermissionsBuilder, Plugin, RestoreResult, Result, Snapshot, SnapshotFromEvents, StateError, StateRestorer, StateSnapshot, Swarm, SwarmLoader, SwarmRegistry, TimeoutError, ToolExecutionError, ToolPermissionsProxy, TranscriptBuilder, TurnTimeoutError, ValidationResult, Workflow

Constant Summary collapse

VERSION =
"2.7.15"

Class Method Summary collapse

Class Method Details

.agent(name) { ... } ⇒ void

This method returns an undefined value.

Register a global agent definition

Declares an agent configuration that can be referenced by name in any swarm definition. This allows defining agents in separate files and composing them into swarms without duplication.

The registered block uses the Agent::Builder DSL and is executed when the agent is referenced in a swarm definition.

Examples:

Register agent in separate file

# agents/backend.rb
SwarmSDK.agent :backend do
  model "claude-sonnet-4"
  description "Backend API developer"
  system_prompt "You build REST APIs"
  tools :Read, :Edit, :Bash
  delegates_to :database
end

Reference in swarm definition

# swarm.rb
require_relative "agents/backend"

SwarmSDK.build do
  name "Dev Team"
  lead :backend

  agent :backend  # Pulls from registry
end

Extend registered agent with overrides

SwarmSDK.build do
  name "Extended Team"
  lead :backend

  agent :backend do
    # Registry config applied first, then this block
    tools :CustomTool    # Adds to existing tools
    delegates_to :cache  # Adds delegation target
  end
end

Parameters:

  • name (Symbol, String)

    Agent name (will be symbolized)

Yields:

  • Agent configuration block using Agent::Builder DSL

Raises:

  • (ArgumentError)

    If no block is provided

See Also:



187
188
189
# File 'lib/swarm_sdk.rb', line 187

def agent(name, &block)
  AgentRegistry.register(name, &block)
end

.build(allow_filesystem_tools: nil, &block) ⇒ Swarm

Main entry point for DSL - builds simple multi-agent swarms

Returns:

  • (Swarm)

    Always returns a Swarm instance



352
353
354
# File 'lib/swarm_sdk.rb', line 352

def build(allow_filesystem_tools: nil, &block)
  Swarm::Builder.build(allow_filesystem_tools: allow_filesystem_tools, &block)
end

.clear_agent_registry!void

This method returns an undefined value.

Clear the global agent registry

Removes all registered agent definitions. Primarily useful for testing to ensure clean state between tests.

Examples:

In test teardown

def teardown
  SwarmSDK.clear_agent_registry!
end


202
203
204
# File 'lib/swarm_sdk.rb', line 202

def clear_agent_registry!
  AgentRegistry.clear
end

.clear_custom_tools!void

This method returns an undefined value.

Clear all registered custom tools

Removes all custom tool registrations. Primarily useful for testing to ensure clean state between tests.

Examples:

In test teardown

def teardown
  SwarmSDK.clear_custom_tools!
end


345
346
347
# File 'lib/swarm_sdk.rb', line 345

def clear_custom_tools!
  CustomToolRegistry.clear
end

.configConfig

Get the global configuration instance

Returns:

  • (Config)

    The singleton Config instance



110
111
112
# File 'lib/swarm_sdk.rb', line 110

def config
  Config.instance
end

.configure {|Config| ... } ⇒ Config

Configure SwarmSDK global settings

Examples:

SwarmSDK.configure do |config|
  config.openai_api_key = "sk-..."
  config.default_model = "claude-sonnet-4"
end

Yields:

  • (Config)

    The configuration instance

Returns:

  • (Config)

    The configuration instance



124
125
126
127
# File 'lib/swarm_sdk.rb', line 124

def configure
  yield(config) if block_given?
  config
end

.custom_tool_registered?(name) ⇒ Boolean

Check if a custom tool is registered

Examples:

SwarmSDK.register_tool(WeatherTool)
SwarmSDK.custom_tool_registered?(:Weather)  #=> true
SwarmSDK.custom_tool_registered?(:Unknown)  #=> false

Parameters:

  • name (Symbol, String)

    Tool name

Returns:

  • (Boolean)

    true if the tool is registered



305
306
307
# File 'lib/swarm_sdk.rb', line 305

def custom_tool_registered?(name)
  CustomToolRegistry.registered?(name)
end

.custom_toolsArray<Symbol>

Get all registered custom tool names

Examples:

SwarmSDK.register_tool(WeatherTool)
SwarmSDK.register_tool(StockTool)
SwarmSDK.custom_tools  #=> [:Weather, :Stock]

Returns:

  • (Array<Symbol>)

    List of registered custom tool names



317
318
319
# File 'lib/swarm_sdk.rb', line 317

def custom_tools
  CustomToolRegistry.tool_names
end

.load(yaml_content, base_dir: Dir.pwd, allow_filesystem_tools: nil, env_interpolation: nil) ⇒ Swarm, Workflow

Load swarm from YAML string

This is the primary programmatic API for loading YAML configurations. For file-based loading, use SwarmSDK.load_file for convenience.

Examples:

Load from YAML string

yaml = "version: 2\nswarm:\n  name: \"Dev Team\"\n  lead: backend\n  agents:\n    backend:\n      description: \"Backend developer\"\n      model: \"gpt-4\"\n      agent_file: \"agents/backend.md\"  # Resolved relative to base_dir\n"

swarm = SwarmSDK.load(yaml, base_dir: "/path/to/project")
result = swarm.execute("Build authentication")

Load with default base_dir (Dir.pwd)

yaml = File.read("config.yml")
swarm = SwarmSDK.load(yaml)  # base_dir defaults to Dir.pwd

Load without environment variable interpolation

swarm = SwarmSDK.load(yaml, env_interpolation: false)

Parameters:

  • yaml_content (String)

    YAML configuration content

  • base_dir (String, Pathname) (defaults to: Dir.pwd)

    Base directory for resolving agent file paths (default: Dir.pwd)

  • allow_filesystem_tools (Boolean, nil) (defaults to: nil)

    Whether to allow filesystem tools (nil uses global setting)

  • env_interpolation (Boolean, nil) (defaults to: nil)

    Whether to interpolate environment variables. When nil, uses the global SwarmSDK.config.env_interpolation setting. When true, interpolates $VAR and $VAR:=default patterns. When false, skips interpolation entirely.

Returns:

Raises:



492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
# File 'lib/swarm_sdk.rb', line 492

def load(yaml_content, base_dir: Dir.pwd, allow_filesystem_tools: nil, env_interpolation: nil)
  config = Configuration.new(yaml_content, base_dir: base_dir, env_interpolation: env_interpolation)
  config.load_and_validate
  swarm = config.to_swarm(allow_filesystem_tools: allow_filesystem_tools)

  # Apply hooks if any are configured (YAML-only feature)
  if hooks_configured?(config)
    Hooks::Adapter.apply_hooks(swarm, config)
  end

  # Store config reference for agent hooks (applied during initialize_agents)
  swarm.config_for_hooks = config

  swarm
end

.load_file(path, allow_filesystem_tools: nil, env_interpolation: nil) ⇒ Swarm, Workflow

Load swarm from YAML file (convenience method)

Reads the YAML file and uses the file's directory as the base directory for resolving agent file paths. This is the recommended method for loading swarms from configuration files.

Examples:

swarm = SwarmSDK.load_file("config.yml")
result = swarm.execute("Build authentication")

With absolute path

swarm = SwarmSDK.load_file("/absolute/path/config.yml")

Load without environment variable interpolation

swarm = SwarmSDK.load_file("config.yml", env_interpolation: false)

Parameters:

  • path (String, Pathname)

    Path to YAML configuration file

  • allow_filesystem_tools (Boolean, nil) (defaults to: nil)

    Whether to allow filesystem tools (nil uses global setting)

  • env_interpolation (Boolean, nil) (defaults to: nil)

    Whether to interpolate environment variables. When nil, uses the global SwarmSDK.config.env_interpolation setting. When true, interpolates $VAR and $VAR:=default patterns. When false, skips interpolation entirely.

Returns:

Raises:



532
533
534
535
536
537
538
539
540
541
542
543
544
545
# File 'lib/swarm_sdk.rb', line 532

def load_file(path, allow_filesystem_tools: nil, env_interpolation: nil)
  config = Configuration.load_file(path, env_interpolation: env_interpolation)
  swarm = config.to_swarm(allow_filesystem_tools: allow_filesystem_tools)

  # Apply hooks if any are configured (YAML-only feature)
  if hooks_configured?(config)
    Hooks::Adapter.apply_hooks(swarm, config)
  end

  # Store config reference for agent hooks (applied during initialize_agents)
  swarm.config_for_hooks = config

  swarm
end

.register_tool(tool_class) ⇒ Symbol .register_tool(name, tool_class) ⇒ Symbol

Register a custom tool for use in swarms

Provides a simple way to add tools without creating a full plugin. Tools can be registered with an explicit name or the name can be inferred from the class name.

Custom tools are available to any agent that includes them in their tools configuration, just like built-in tools.

Examples:

Register with inferred name

class WeatherTool < RubyLLM::Tool
  description "Get weather for a city"
  param :city, type: "string", required: true

  def execute(city:)
    "Weather in #{city}: Sunny, 72°F"
  end
end

SwarmSDK.register_tool(WeatherTool)  # Registers as :Weather

Register with explicit name

SwarmSDK.register_tool(:GetWeather, WeatherTool)

Tool with agent context

class ContextAwareTool < RubyLLM::Tool
  # Declare what context the tool needs
  def self.creation_requirements
    [:agent_name, :directory]
  end

  def initialize(agent_name:, directory:)
    super()
    @agent_name = agent_name
    @directory = directory
  end

  description "Shows agent context"
  def execute
    "Agent: #{@agent_name} in #{@directory}"
  end
end

SwarmSDK.register_tool(ContextAwareTool)

Use registered tool in a swarm

SwarmSDK.register_tool(WeatherTool)

swarm = SwarmSDK.build do
  name "Weather Assistant"
  lead :assistant

  agent :assistant do
    model "claude-sonnet-4"
    description "Weather helper"
    tools :Weather, :Read  # Custom + built-in tools
  end
end

Overloads:

  • .register_tool(tool_class) ⇒ Symbol

    Register a tool with name inferred from class name

    Parameters:

    • tool_class (Class)

      Tool class (must inherit from RubyLLM::Tool)

    Returns:

    • (Symbol)

      The registered tool name

  • .register_tool(name, tool_class) ⇒ Symbol

    Register a tool with explicit name

    Parameters:

    • name (Symbol, String)

      Tool name

    • tool_class (Class)

      Tool class (must inherit from RubyLLM::Tool)

    Returns:

    • (Symbol)

      The registered tool name

Raises:

  • (ArgumentError)

    If tool_class doesn't inherit from RubyLLM::Tool

  • (ArgumentError)

    If a tool with the same name is already registered

  • (ArgumentError)

    If the name conflicts with a built-in or plugin tool

See Also:



282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/swarm_sdk.rb', line 282

def register_tool(name_or_class, tool_class = nil)
  if tool_class.nil?
    # Single argument: infer name from class
    tool_class = name_or_class
    name = CustomToolRegistry.infer_name(tool_class)
  else
    # Two arguments: explicit name
    name = name_or_class.to_sym
  end

  CustomToolRegistry.register(name, tool_class)
  name
end

.reset_config!void

This method returns an undefined value.

Reset configuration to defaults

Clears all configuration including explicit values and cached ENV values. Use in tests to ensure clean state.



135
136
137
# File 'lib/swarm_sdk.rb', line 135

def reset_config!
  Config.reset!
end

.unregister_tool(name) ⇒ Class?

Unregister a custom tool

Examples:

SwarmSDK.register_tool(WeatherTool)
SwarmSDK.unregister_tool(:Weather)
SwarmSDK.custom_tool_registered?(:Weather)  #=> false

Parameters:

  • name (Symbol, String)

    Tool name to unregister

Returns:

  • (Class, nil)

    The unregistered tool class, or nil if not found



330
331
332
# File 'lib/swarm_sdk.rb', line 330

def unregister_tool(name)
  CustomToolRegistry.unregister(name)
end

.validate(yaml_content, base_dir: Dir.pwd) ⇒ Array<Hash>

Validate YAML configuration without creating a swarm

Performs comprehensive validation of YAML configuration including:

  • YAML syntax
  • Required fields (version, swarm name, lead, agents)
  • Agent configurations (description, directory existence)
  • Circular dependencies
  • File references (agent_file paths)
  • Hook configurations

Examples:

Validate YAML string

errors = SwarmSDK.validate(yaml_content)
if errors.empty?
  puts "Configuration is valid!"
else
  errors.each do |error|
    puts "#{error[:field]}: #{error[:message]}"
  end
end

Error hash structure

{
  type: :missing_field,           # Error type
  field: "swarm.agents.backend.description",  # JSON-style path to field
  message: "Agent 'backend' missing required 'description' field",
  agent: "backend"                # Optional, present if error is agent-specific
}

Parameters:

  • yaml_content (String)

    YAML configuration content

  • base_dir (String, Pathname) (defaults to: Dir.pwd)

    Base directory for resolving agent file paths (default: Dir.pwd)

Returns:

  • (Array<Hash>)

    Array of error hashes (empty if valid)



394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/swarm_sdk.rb', line 394

def validate(yaml_content, base_dir: Dir.pwd)
  errors = []

  begin
    config = Configuration.new(yaml_content, base_dir: base_dir)
    config.load_and_validate

    # Build swarm to trigger DSL validation
    # This catches errors from Agent::Definition, Builder, etc.
    config.to_swarm
  rescue ConfigurationError, CircularDependencyError => e
    errors << parse_configuration_error(e)
  rescue StandardError => e
    errors << {
      type: :unknown_error,
      field: nil,
      message: e.message,
    }
  end

  errors
end

.validate_file(path) ⇒ Array<Hash>

Validate YAML configuration file

Convenience method that reads the file and validates the content.

Examples:

errors = SwarmSDK.validate_file("config.yml")
if errors.empty?
  puts "Valid configuration!"
  swarm = SwarmSDK.load_file("config.yml")
else
  errors.each { |e| puts "Error: #{e[:message]}" }
end

Parameters:

  • path (String, Pathname)

    Path to YAML configuration file

Returns:

  • (Array<Hash>)

    Array of error hashes (empty if valid)



432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/swarm_sdk.rb', line 432

def validate_file(path)
  path = Pathname.new(path).expand_path

  unless path.exist?
    return [{
      type: :file_not_found,
      field: nil,
      message: "Configuration file not found: #{path}",
    }]
  end

  yaml_content = File.read(path)
  base_dir = path.dirname

  validate(yaml_content, base_dir: base_dir)
rescue StandardError => e
  [{
    type: :file_read_error,
    field: nil,
    message: "Error reading file: #{e.message}",
  }]
end

.workflow(allow_filesystem_tools: nil, &block) ⇒ Workflow

Entry point for building multi-stage workflows

Returns:

  • (Workflow)

    Always returns a Workflow instance



359
360
361
# File 'lib/swarm_sdk.rb', line 359

def workflow(allow_filesystem_tools: nil, &block)
  Workflow::Builder.build(allow_filesystem_tools: allow_filesystem_tools, &block)
end