Module: SwarmSDK

Defined in:
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/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/permissions_builder.rb,
lib/swarm_sdk/swarm/hook_triggers.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/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/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

Defined Under Namespace

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

Constant Summary collapse

VERSION =
"2.5.1"

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:



146
147
148
# File 'lib/swarm_sdk.rb', line 146

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



311
312
313
# File 'lib/swarm_sdk.rb', line 311

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


161
162
163
# File 'lib/swarm_sdk.rb', line 161

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


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

def clear_custom_tools!
  CustomToolRegistry.clear
end

.configConfig

Get the global configuration instance

Returns:

  • (Config)

    The singleton Config instance



69
70
71
# File 'lib/swarm_sdk.rb', line 69

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



83
84
85
86
# File 'lib/swarm_sdk.rb', line 83

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



264
265
266
# File 'lib/swarm_sdk.rb', line 264

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



276
277
278
# File 'lib/swarm_sdk.rb', line 276

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 = <<~YAML
  version: 2
  swarm:
    name: "Dev Team"
    lead: backend
    agents:
      backend:
        description: "Backend developer"
        model: "gpt-4"
        agent_file: "agents/backend.md"  # Resolved relative to base_dir
YAML

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:



451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/swarm_sdk.rb', line 451

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:



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

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:



241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/swarm_sdk.rb', line 241

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.



94
95
96
# File 'lib/swarm_sdk.rb', line 94

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



289
290
291
# File 'lib/swarm_sdk.rb', line 289

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)



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/swarm_sdk.rb', line 353

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)



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

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



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

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