Class: SwarmSDK::Builders::BaseBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/swarm_sdk/builders/base_builder.rb

Overview

Base builder with shared DSL methods for Swarm and Workflow builders

Provides common functionality:

  • Basic configuration (name, id, scratchpad)
  • Agent definition (inline DSL, markdown files, with overrides)
  • All agents configuration
  • External swarms registry
  • Validation helpers
  • Merging logic

Subclasses must implement:

  • build_swarm - Build and return the appropriate instance
  • Type-specific DSL methods (lead for Swarm, node/start_node for Workflow)

Direct Known Subclasses

Swarm::Builder, Workflow::Builder

Instance Method Summary collapse

Constructor Details

#initialize(allow_filesystem_tools: nil) ⇒ BaseBuilder

Returns a new instance of BaseBuilder.



20
21
22
23
24
25
26
27
28
# File 'lib/swarm_sdk/builders/base_builder.rb', line 20

def initialize(allow_filesystem_tools: nil)
  @swarm_id = nil
  @swarm_name = nil
  @agents = {}
  @all_agents_config = nil
  @swarm_registry_config = []
  @scratchpad = :disabled
  @allow_filesystem_tools = allow_filesystem_tools
end

Instance Method Details

#agent(name, content = nil, &block) ⇒ Object

Define an agent with fluent API, load from markdown, or reference registry

Supports multiple forms:

  1. Registry lookup: agent :name (pulls from global registry)
  2. Registry + overrides: agent :name do ... end (when registered)
  3. Inline DSL: agent :name do ... end (when not registered)
  4. Markdown content: agent :name, <<~MD ... MD
  5. Markdown + overrides: agent :name, <<~MD do ... end

Examples:

Inline DSL

agent :backend do
  model "gpt-5"
  system_prompt "You build APIs"
  tools :Read, :Write
end

Registry lookup (agent must be registered with SwarmSDK.agent)

agent :backend  # Pulls configuration from registry

Registry + overrides

agent :backend do
  # Base config from registry, then apply overrides
  tools :CustomTool  # Adds to registry-defined tools
end

Markdown content

agent :backend, "---\ndescription: \"Backend developer\"\nmodel: \"gpt-4\"\n---\n\nYou build APIs.\n"


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/swarm_sdk/builders/base_builder.rb', line 101

def agent(name, content = nil, &block)
  name = name.to_sym

  # Case 1: agent :name, <<~MD do ... end (markdown + overrides)
  if content.is_a?(String) && block_given? && markdown_content?(content)
    load_agent_from_markdown_with_overrides(content, name, &block)

  # Case 2: agent :name, <<~MD (markdown only)
  elsif content.is_a?(String) && !block_given? && markdown_content?(content)
    load_agent_from_markdown(content, name)

  # Case 3: agent :name (registry lookup only - no content, no block)
  elsif content.nil? && !block_given?
    load_agent_from_registry(name)

  # Case 4: agent :name do ... end (with registered agent - registry + overrides)
  elsif content.nil? && block_given? && AgentRegistry.registered?(name)
    load_agent_from_registry_with_overrides(name, &block)

  # Case 5: agent :name do ... end (inline DSL - not registered)
  elsif block_given?
    builder = Agent::Builder.new(name)
    builder.instance_eval(&block)
    @agents[name] = builder

  else
    raise ArgumentError,
      "Invalid agent definition for '#{name}'. Use:\n  " \
        "agent :#{name} { ... }           # Inline DSL\n  " \
        "agent :#{name}                   # Registry lookup\n  " \
        "agent :#{name} { ... }           # Registry + overrides (if registered)\n  " \
        "agent :#{name}, <<~MD ... MD     # Markdown\n  " \
        "agent :#{name}, <<~MD do ... end # Markdown + overrides"
  end
end

#all_agents(&block) ⇒ Object

Configure all agents with a block

Examples:

all_agents do
  tools :Read, :Write

  hook :pre_tool_use, matcher: "Write" do |ctx|
    # Validation for all agents
  end
end


147
148
149
150
151
# File 'lib/swarm_sdk/builders/base_builder.rb', line 147

def all_agents(&block)
  builder = Swarm::AllAgentsBuilder.new
  builder.instance_eval(&block)
  @all_agents_config = builder
end

#build_swarmSwarm, Workflow

Build the actual Swarm or Workflow instance

Subclasses must implement this method.

Returns:

Raises:

  • (NotImplementedError)


158
159
160
# File 'lib/swarm_sdk/builders/base_builder.rb', line 158

def build_swarm
  raise NotImplementedError, "#{self.class} must implement #build_swarm"
end

#id(swarm_id) ⇒ Object

Set swarm ID

Parameters:

  • swarm_id (String)

    Unique identifier for this swarm/workflow



33
34
35
# File 'lib/swarm_sdk/builders/base_builder.rb', line 33

def id(swarm_id)
  @swarm_id = swarm_id
end

#name(swarm_name) ⇒ Object

Set swarm/workflow name



38
39
40
# File 'lib/swarm_sdk/builders/base_builder.rb', line 38

def name(swarm_name)
  @swarm_name = swarm_name
end

#scratchpad(mode) ⇒ Object

Configure scratchpad mode

For Workflow: :enabled (shared across nodes), :per_node (isolated), or :disabled For Swarm: :enabled or :disabled

Parameters:

  • mode (Symbol, Boolean)

    Scratchpad mode



48
49
50
# File 'lib/swarm_sdk/builders/base_builder.rb', line 48

def scratchpad(mode)
  @scratchpad = mode
end

#swarms { ... } ⇒ Object

Register external swarms for composable swarms

Examples:

swarms do
  register "code_review", file: "./swarms/code_review.rb"
  register "testing", file: "./swarms/testing.yml", keep_context: false
end

Yields:

  • Block containing register() calls



61
62
63
64
65
# File 'lib/swarm_sdk/builders/base_builder.rb', line 61

def swarms(&block)
  builder = Swarm::SwarmRegistryBuilder.new
  builder.instance_eval(&block)
  @swarm_registry_config = builder.registrations
end