Module: AgentHarness::Extensions::Composition

Defined in:
lib/agent_harness/extensions.rb

Class Method Summary collapse

Class Method Details

.compose(extensions) ⇒ Object



174
175
176
177
178
179
# File 'lib/agent_harness/extensions.rb', line 174

def compose(extensions)
  return [] if extensions.nil? || extensions.empty?

  detect_tool_conflicts(extensions)
  extensions
end

.detect_tool_conflicts(extensions) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/agent_harness/extensions.rb', line 181

def detect_tool_conflicts(extensions)
  tool_owners = {}

  extensions.each do |extension|
    extension.tools.each do |tool|
      tool_name = tool[:name] || tool["name"]
      next unless tool_name

      if tool_owners.key?(tool_name)
        raise ConfigurationError,
          "Tool name conflict: '#{tool_name}' is provided by both " \
          "'#{tool_owners[tool_name]}' and '#{extension.name}'"
      end

      tool_owners[tool_name] = extension.name
    end
  end
end

.merge_mcp_servers(extensions) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/agent_harness/extensions.rb', line 208

def merge_mcp_servers(extensions)
  servers = extensions.flat_map(&:mcp_servers)
  names = servers.map { |s| s[:name] || s["name"] }.compact
  duplicates = names.group_by { |n| n }.select { |_, v| v.size > 1 }.keys

  unless duplicates.empty?
    raise ConfigurationError,
      "MCP server name conflict across extensions: #{duplicates.join(", ")}"
  end

  servers
end

.merge_system_prompts(extensions) ⇒ Object



200
201
202
# File 'lib/agent_harness/extensions.rb', line 200

def merge_system_prompts(extensions)
  extensions.flat_map(&:system_prompt_additions).reject { |a| a.nil? || a.empty? }
end

.merge_tools(extensions) ⇒ Object



204
205
206
# File 'lib/agent_harness/extensions.rb', line 204

def merge_tools(extensions)
  extensions.flat_map(&:tools)
end