Class: SwarmSDK::Configuration::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/swarm_sdk/configuration/parser.rb

Overview

Handles YAML parsing, validation, and normalization

This class is responsible for:

  • Loading and parsing YAML content
  • Validating configuration structure
  • Normalizing data (symbolizing keys, env interpolation)
  • Detecting configuration type (swarm vs workflow)
  • Loading agents and nodes
  • Detecting circular dependencies

After parsing, the parsed data can be translated to a Swarm/Workflow using the Translator class.

Constant Summary collapse

ENV_VAR_WITH_DEFAULT_PATTERN =
/\$\{([^:}]+)(:=([^}]*))?\}/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(yaml_content, base_dir:, env_interpolation: nil) ⇒ Parser

Initialize parser with YAML content and options

Parameters:

  • yaml_content (String)

    YAML configuration content

  • base_dir (String, Pathname)

    Base directory for resolving paths

  • 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.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/swarm_sdk/configuration/parser.rb', line 42

def initialize(yaml_content, base_dir:, env_interpolation: nil)
  @yaml_content = yaml_content
  @base_dir = Pathname.new(base_dir).expand_path
  @env_interpolation = env_interpolation
  @config_type = nil
  @swarm_id = nil
  @swarm_name = nil
  @lead_agent = nil
  @start_node = nil
  @agents = {}
  @all_agents_config = {}
  @swarm_hooks = {}
  @all_agents_hooks = {}
  @external_swarms = {}
  @nodes = {}
  @scratchpad_mode = :disabled
  @execution_timeout = nil
end

Instance Attribute Details

#agentsObject (readonly)

Returns the value of attribute agents.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def agents
  @agents
end

#all_agents_configObject (readonly)

Returns the value of attribute all_agents_config.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def all_agents_config
  @all_agents_config
end

#all_agents_hooksObject (readonly)

Returns the value of attribute all_agents_hooks.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def all_agents_hooks
  @all_agents_hooks
end

#base_dirObject (readonly)

Returns the value of attribute base_dir.



117
118
119
# File 'lib/swarm_sdk/configuration/parser.rb', line 117

def base_dir
  @base_dir
end

#config_typeObject (readonly)

Returns the value of attribute config_type.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def config_type
  @config_type
end

#execution_timeoutObject (readonly)

Returns the value of attribute execution_timeout.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def execution_timeout
  @execution_timeout
end

#external_swarmsObject (readonly)

Returns the value of attribute external_swarms.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def external_swarms
  @external_swarms
end

#lead_agentObject (readonly)

Returns the value of attribute lead_agent.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def lead_agent
  @lead_agent
end

#nodesObject (readonly)

Returns the value of attribute nodes.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def nodes
  @nodes
end

#scratchpad_modeObject (readonly)

Returns the value of attribute scratchpad_mode.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def scratchpad_mode
  @scratchpad_mode
end

#start_nodeObject (readonly)

Returns the value of attribute start_node.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def start_node
  @start_node
end

#swarm_hooksObject (readonly)

Returns the value of attribute swarm_hooks.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def swarm_hooks
  @swarm_hooks
end

#swarm_idObject (readonly)

Returns the value of attribute swarm_id.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def swarm_id
  @swarm_id
end

#swarm_nameObject (readonly)

Returns the value of attribute swarm_name.



20
21
22
# File 'lib/swarm_sdk/configuration/parser.rb', line 20

def swarm_name
  @swarm_name
end

Instance Method Details

#agent_namesObject



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

def agent_names
  @agents.keys
end

#connections_for(agent_name) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/swarm_sdk/configuration/parser.rb', line 88

def connections_for(agent_name)
  agent_config = @agents[agent_name]
  return [] unless agent_config

  delegates = agent_config[:delegates_to] || []

  # Handle both array and hash formats for delegates_to
  case delegates
  when Array
    # Array of symbols: [:frontend, :backend]
    # OR array of hashes: [{agent: :frontend, tool_name: "Custom"}]
    delegates.map do |item|
      case item
      when Symbol, String
        item.to_sym
      when Hash
        # Extract agent name from hash format
        agent_name = item[:agent] || item["agent"]
        agent_name&.to_sym
      end
    end.compact # Remove nils from malformed hashes
  when Hash
    # Hash format: {frontend: "Custom", backend: nil}
    delegates.keys.map(&:to_sym)
  else
    []
  end
end

#parseObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/swarm_sdk/configuration/parser.rb', line 61

def parse
  @config = YAML.safe_load(@yaml_content, permitted_classes: [Symbol], aliases: true)

  unless @config.is_a?(Hash)
    raise ConfigurationError, "Invalid YAML syntax: configuration must be a Hash"
  end

  @config = Utils.symbolize_keys(@config)
  interpolate_env_vars!(@config) if env_interpolation_enabled?

  validate_version
  detect_and_validate_type
  load_common_config
  load_type_specific_config
  load_agents
  load_nodes if @config_type == :workflow
  detect_circular_dependencies

  self
rescue Psych::SyntaxError => e
  raise ConfigurationError, "Invalid YAML syntax: #{e.message}"
end