Class: ActiveAgent::Delegation::Backend

Inherits:
Object
  • Object
show all
Defined in:
lib/active_agent/delegation/backend.rb

Overview

The provider and options a delegated call runs against.

A sub-agent's contract — what it accepts, what it returns — is separate from what actually serves it. Backend is that seam: the same SummarizerAgent can run on a cheap local model inside one parent and on a frontier model inside another, and neither parent's code changes when you move it.

Examples:

Swap the model, keep the provider

delegate_to SummarizerAgent, backend: { model: "gpt-4o-mini", temperature: 0 }

Swap the provider entirely

delegate_to SummarizerAgent, backend: :ollama

Swap both

delegate_to SummarizerAgent, backend: { provider: :anthropic, model: "claude-haiku-4-5" }

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(provider: nil, **options) ⇒ Backend

Returns a new instance of Backend.

Parameters:

  • provider (Symbol, String, nil) (defaults to: nil)
  • options (Hash)

    prompt options (model, temperature, ...)



42
43
44
45
46
# File 'lib/active_agent/delegation/backend.rb', line 42

def initialize(provider: nil, **options)
  @provider = provider&.to_sym
  @options  = options
  @mutex    = Mutex.new
end

Instance Attribute Details

#optionsHash (readonly)

Returns prompt options applied at the call site.

Returns:

  • (Hash)

    prompt options applied at the call site



25
26
27
# File 'lib/active_agent/delegation/backend.rb', line 25

def options
  @options
end

#providerSymbol? (readonly)

Returns provider reference (+:openai+, :anthropic, ...).

Returns:

  • (Symbol, nil)

    provider reference (+:openai+, :anthropic, ...)



23
24
25
# File 'lib/active_agent/delegation/backend.rb', line 23

def provider
  @provider
end

Class Method Details

.build(spec = nil) ⇒ Backend

Parameters:

  • spec (Backend, Symbol, String, Hash, nil) (defaults to: nil)

Returns:



29
30
31
32
33
34
35
36
37
38
# File 'lib/active_agent/delegation/backend.rb', line 29

def self.build(spec = nil)
  case spec
  when Backend        then spec
  when nil            then new
  when Symbol, String then new(provider: spec)
  when Hash           then new(**spec.symbolize_keys)
  else
    raise ArgumentError, "Delegation backend must be a Symbol, Hash or #{name}, got #{spec.inspect}"
  end
end

Instance Method Details

#agent_class_for(agent_class) ⇒ Class

Resolves the class a delegated call should instantiate.

Swapping providers means rebuilding provider configuration (host, keys, service), not just merging a hash — so the swap goes through a cached subclass configured by generate_with, the same code path a hand-written agent takes. The subclass reports its parent's name so template lookup keeps resolving to the original agent's views.

Parameters:

  • agent_class (Class)

    the declared sub-agent class

Returns:

  • (Class)


63
64
65
66
67
68
69
70
# File 'lib/active_agent/delegation/backend.rb', line 63

def agent_class_for(agent_class)
  return agent_class if provider.blank?

  @mutex.synchronize do
    @agent_classes ||= {}
    @agent_classes[agent_class] ||= build_agent_class(agent_class)
  end
end

#apply(agent) ⇒ ActiveAgent::Base

Applies call-site options to a prepared agent instance.

Applied after the action has run so the delegation site wins over the sub-agent's own prompt options — a call-site override is runtime configuration, which outranks class configuration everywhere else in ActiveAgent.

Parameters:

Returns:



81
82
83
84
# File 'lib/active_agent/delegation/backend.rb', line 81

def apply(agent)
  agent.prompt_options.merge!(options) if options.any?
  agent
end

#overrides?Boolean

Returns whether this backend changes anything.

Returns:

  • (Boolean)

    whether this backend changes anything



49
50
51
# File 'lib/active_agent/delegation/backend.rb', line 49

def overrides?
  provider.present? || options.any?
end

#to_hHash

Returns:

  • (Hash)


87
88
89
# File 'lib/active_agent/delegation/backend.rb', line 87

def to_h
  { provider: provider }.compact.merge(options)
end