Class: Google::ADK::SequentialAgent

Inherits:
BaseAgent
  • Object
show all
Defined in:
lib/google/adk/agents/workflow_agents/sequential_agent.rb

Overview

Agent that executes sub-agents sequentially

Constant Summary

Constants inherited from BaseAgent

BaseAgent::AGENT_NAME_REGEX

Instance Attribute Summary collapse

Attributes inherited from BaseAgent

#after_agent_callback, #before_agent_callback, #description, #name, #parent_agent, #sub_agents

Instance Method Summary collapse

Methods inherited from BaseAgent

#clone, #find_agent, #find_sub_agent, from_config, #run_live

Constructor Details

#initialize(name:, agents:, description: nil, before_agent_callback: nil, after_agent_callback: nil) ⇒ SequentialAgent

Initialize a sequential agent

Parameters:

  • name (String)

    Agent name

  • description (String) (defaults to: nil)

    Agent description (optional)

  • agents (Array<BaseAgent>)

    Agents to execute in order

  • before_agent_callback (Proc) (defaults to: nil)

    Callback before agent execution

  • after_agent_callback (Proc) (defaults to: nil)

    Callback after agent execution

Raises:

  • (ArgumentError)

    If no agents provided



17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/google/adk/agents/workflow_agents/sequential_agent.rb', line 17

def initialize(name:, agents:, description: nil,
               before_agent_callback: nil, after_agent_callback: nil)
  raise ArgumentError, "Sequential agent requires at least one agent" if agents.empty?

  super(
    name: name,
    description: description || "Executes #{agents.length} agents sequentially",
    sub_agents: agents,
    before_agent_callback: before_agent_callback,
    after_agent_callback: after_agent_callback
  )

  @agents = agents
end

Instance Attribute Details

#agentsObject (readonly)

Returns the value of attribute agents.



7
8
9
# File 'lib/google/adk/agents/workflow_agents/sequential_agent.rb', line 7

def agents
  @agents
end

Instance Method Details

#run_async(message, context: nil) {|Event| ... } ⇒ Object

Run agents sequentially

Parameters:

  • message (String)

    Initial message

  • context (InvocationContext) (defaults to: nil)

    Invocation context

Yields:

  • (Event)

    Events during execution



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/google/adk/agents/workflow_agents/sequential_agent.rb', line 37

def run_async(message, context: nil)
  Enumerator.new do |yielder|
    invocation_id = context&.invocation_id || "seq-#{SecureRandom.uuid}"

    # Yield start event
    start_event = Event.new(
      invocation_id: invocation_id,
      author: @name,
      content: "Starting sequential execution with #{@agents.length} agents"
    )
    yielder << start_event

    # Execute each agent in sequence
    current_input = message
    @agents.each_with_index do |agent, index|
      begin
        # Yield progress event
        progress_event = Event.new(
          invocation_id: invocation_id,
          author: @name,
          content: "Executing agent #{index + 1}/#{@agents.length}: #{agent.name}"
        )
        yielder << progress_event

        # Run the agent
        agent_output = nil
        if agent.respond_to?(:run_async)
          agent.run_async(current_input, context: context).each do |event|
            yielder << event
            # Capture last content as output for next agent
            agent_output = event.content if event.content
          end
        else
          # For agents that don't implement run_async
          error_event = Event.new(
            invocation_id: invocation_id,
            author: @name,
            content: "Agent #{agent.name} does not implement run_async"
          )
          yielder << error_event
          agent_output = current_input
        end

        # Use this agent's output as next agent's input
        current_input = agent_output || current_input

      rescue StandardError => e
        # Handle errors gracefully
        error_event = Event.new(
          invocation_id: invocation_id,
          author: @name,
          content: "Error in agent #{agent.name}: #{e.message}"
        )
        yielder << error_event
        
        # Continue with original input if agent failed
        current_input = message
      end
    end

    # Yield completion event
    end_event = Event.new(
      invocation_id: invocation_id,
      author: @name,
      content: "Completed sequential execution. Final output: #{current_input}"
    )
    yielder << end_event
  end
end