Class: Google::ADK::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/google/adk/runner.rb

Overview

Main runner for orchestrating agent execution

Direct Known Subclasses

InMemoryRunner

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(agent:, app_name:, session_service: nil, plugins: []) ⇒ Runner

Initialize a runner

Parameters:

  • agent (BaseAgent)

    Root agent to run

  • app_name (String)

    Application name

  • session_service (BaseSessionService) (defaults to: nil)

    Session service (optional)

  • plugins (Array<Plugin>) (defaults to: [])

    Runner plugins (optional)



43
44
45
46
47
48
# File 'lib/google/adk/runner.rb', line 43

def initialize(agent:, app_name:, session_service: nil, plugins: [])
  @agent = agent
  @app_name = app_name
  @session_service = session_service || InMemorySessionService.new
  @plugins = plugins
end

Instance Attribute Details

#agentObject (readonly)

Returns the value of attribute agent.



35
36
37
# File 'lib/google/adk/runner.rb', line 35

def agent
  @agent
end

#app_nameObject (readonly)

Returns the value of attribute app_name.



35
36
37
# File 'lib/google/adk/runner.rb', line 35

def app_name
  @app_name
end

#pluginsObject (readonly)

Returns the value of attribute plugins.



35
36
37
# File 'lib/google/adk/runner.rb', line 35

def plugins
  @plugins
end

#session_serviceObject (readonly)

Returns the value of attribute session_service.



35
36
37
# File 'lib/google/adk/runner.rb', line 35

def session_service
  @session_service
end

Instance Method Details

#rewind_async(user_id:, session_id:, invocation_id:) ⇒ Object

Rewind session to previous state

Parameters:

  • user_id (String)

    User ID

  • session_id (String)

    Session ID

  • invocation_id (String)

    Invocation to rewind before

Raises:

  • (NotImplementedError)


188
189
190
# File 'lib/google/adk/runner.rb', line 188

def rewind_async(user_id:, session_id:, invocation_id:)
  raise NotImplementedError, "Rewind not yet implemented"
end

#run(user_id:, message:, session_id: nil, new_session: false) {|Event| ... } ⇒ Enumerator<Event>

Run the agent synchronously

Parameters:

  • user_id (String)

    User ID

  • session_id (String) (defaults to: nil)

    Session ID (optional)

  • message (String)

    User message

  • new_session (Boolean) (defaults to: false)

    Force new session (optional)

Yields:

  • (Event)

    Events during execution

Returns:

  • (Enumerator<Event>)

    Event stream



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
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/google/adk/runner.rb', line 58

def run(user_id:, message:, session_id: nil, new_session: false)
  Enumerator.new do |yielder|
    # Create or get session
    session = if session_id && !new_session
                @session_service.get_session(
                  app_name: @app_name,
                  user_id: user_id,
                  session_id: session_id
                )
              end

    session ||= @session_service.create_session(
      app_name: @app_name,
      user_id: user_id
    )

    invocation_id = "inv-#{SecureRandom.uuid}"

    # Create invocation context
    context = InvocationContext.new(
      session: session,
      agent: @agent,
      invocation_id: invocation_id,
      session_service: @session_service
    )

    # Create and yield user event
    user_event = Event.new(
      invocation_id: invocation_id,
      author: "user",
      content: message
    )
    
    # Plugin callback
    @plugins.each { |p| p.on_user_message(context, message) }
    
    yielder << user_event
    context.add_event(user_event)
    @plugins.each { |p| p.on_event(context, user_event) }

    # Update session
    @session_service.append_event(
      app_name: @app_name,
      user_id: user_id,
      session_id: session.id,
      event: user_event
    )

    # Run agent
    @plugins.each { |p| p.on_agent_start(context) }

    begin
      agent_events = @agent.run_async(message, context: context)
      
      # Process agent events
      agent_events.each do |event|
        yielder << event
        context.add_event(event)
        @plugins.each { |p| p.on_event(context, event) }

        # Update session with event
        @session_service.append_event(
          app_name: @app_name,
          user_id: user_id,
          session_id: session.id,
          event: event
        )

        # Handle state updates from event actions
        if event.actions&.state_delta && !event.actions.state_delta.empty?
          @session_service.update_session(
            app_name: @app_name,
            user_id: user_id,
            session_id: session.id,
            state_updates: event.actions.state_delta
          )
        end

        # Handle agent transfers
        if event.actions&.transfer_to_agent
          # In a full implementation, would transfer to another agent
          break
        end
      end
    rescue StandardError => e
      # Create error event
      error_event = Event.new(
        invocation_id: invocation_id,
        author: "system",
        content: "Error: #{e.message}"
      )
      yielder << error_event
      context.add_event(error_event)
    ensure
      @plugins.each { |p| p.on_agent_end(context) }
    end
  end
end

#run_async(user_id:, message:, session_id: nil, new_session: false) ⇒ Enumerator<Event>

Run the agent asynchronously

Parameters:

  • user_id (String)

    User ID

  • session_id (String) (defaults to: nil)

    Session ID (optional)

  • message (String)

    User message

  • new_session (Boolean) (defaults to: false)

    Force new session (optional)

Returns:

  • (Enumerator<Event>)

    Event stream



164
165
166
167
168
169
170
171
172
173
# File 'lib/google/adk/runner.rb', line 164

def run_async(user_id:, message:, session_id: nil, new_session: false)
  # In this simplified version, we delegate to the sync method
  # In a full implementation, this would use Async gem for true async
  run(
    user_id: user_id,
    message: message,
    session_id: session_id,
    new_session: new_session
  )
end

#run_live(user_id:, session_id:) ⇒ Object

Run in live/streaming mode (experimental)

Parameters:

  • user_id (String)

    User ID

  • session_id (String)

    Session ID

Raises:

  • (NotImplementedError)


179
180
181
# File 'lib/google/adk/runner.rb', line 179

def run_live(user_id:, session_id:)
  raise NotImplementedError, "Live mode not yet implemented"
end