Class: A2A::Client::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/a2a/client/base.rb

Direct Known Subclasses

HttpClient

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config: nil, middleware: [], consumers: []) ⇒ Base

Initialize a new client

Parameters:

  • config (Config, nil) (defaults to: nil)

    Client configuration

  • middleware (Array) (defaults to: [])

    List of middleware interceptors

  • consumers (Array) (defaults to: [])

    List of event consumers



22
23
24
25
26
27
# File 'lib/a2a/client/base.rb', line 22

def initialize(config: nil, middleware: [], consumers: [])
  @config = config || Config.new
  @middleware = middleware.dup
  @consumers = consumers.dup
  @task_callbacks = {}
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



14
15
16
# File 'lib/a2a/client/base.rb', line 14

def config
  @config
end

#consumersObject (readonly)

Returns the value of attribute consumers.



14
15
16
# File 'lib/a2a/client/base.rb', line 14

def consumers
  @consumers
end

#middlewareObject (readonly)

Returns the value of attribute middleware.



14
15
16
# File 'lib/a2a/client/base.rb', line 14

def middleware
  @middleware
end

Instance Method Details

#add_consumer(consumer) ⇒ void

This method returns an undefined value.

Add an event consumer

Parameters:

  • consumer (Object)

    The event consumer



155
156
157
# File 'lib/a2a/client/base.rb', line 155

def add_consumer(consumer)
  @consumers << consumer
end

#add_middleware(interceptor) ⇒ void

This method returns an undefined value.

Add middleware to the client

Parameters:

  • interceptor (Object)

    The middleware interceptor



137
138
139
# File 'lib/a2a/client/base.rb', line 137

def add_middleware(interceptor)
  @middleware << interceptor
end

#agent_supports_transport?(agent_card, transport) ⇒ Boolean (private)

Check if an agent supports a specific transport

Parameters:

  • agent_card (AgentCard)

    The agent card

  • transport (String)

    The transport to check

Returns:

  • (Boolean)

    True if the agent supports the transport



309
310
311
312
313
# File 'lib/a2a/client/base.rb', line 309

def agent_supports_transport?(agent_card, transport)
  return true if agent_card.preferred_transport == transport

  agent_card.additional_interfaces&.any? { |iface| iface.transport == transport }
end

#cancel_task(task_id, context: nil) ⇒ Task

Cancel a task

Parameters:

  • task_id (String)

    The task ID to cancel

  • context (Hash, nil) (defaults to: nil)

    Optional context information

Returns:

  • (Task)

    The updated task

Raises:

  • (NotImplementedError)

    Must be implemented by subclasses



59
60
61
# File 'lib/a2a/client/base.rb', line 59

def cancel_task(task_id, context: nil)
  raise NotImplementedError, "#{self.class}#cancel_task must be implemented"
end

#delete_task_callback(task_id, push_notification_config_id, context: nil) ⇒ void

This method returns an undefined value.

Delete a callback configuration for a task

Parameters:

  • task_id (String)

    The task ID

  • push_notification_config_id (String)

    The push notification config ID

  • context (Hash, nil) (defaults to: nil)

    Optional context information

Raises:

  • (NotImplementedError)

    Must be implemented by subclasses



128
129
130
# File 'lib/a2a/client/base.rb', line 128

def delete_task_callback(task_id, push_notification_config_id, context: nil)
  raise NotImplementedError, "#{self.class}#delete_task_callback must be implemented"
end

#ensure_agent_card(agent_card) ⇒ AgentCard (protected)

Convert an agent card hash or object to an AgentCard instance

Parameters:

  • agent_card (AgentCard, Hash)

    The agent card to convert

Returns:

  • (AgentCard)

    The agent card instance



295
296
297
298
299
# File 'lib/a2a/client/base.rb', line 295

def ensure_agent_card(agent_card)
  return agent_card if agent_card.is_a?(A2A::Types::AgentCard)

  A2A::Types::AgentCard.from_h(agent_card)
end

#ensure_message(message) ⇒ Message (protected)

Convert a message hash or object to a Message instance

Parameters:

  • message (Message, Hash)

    The message to convert

Returns:

  • (Message)

    The message instance



273
274
275
276
277
# File 'lib/a2a/client/base.rb', line 273

def ensure_message(message)
  return message if message.is_a?(A2A::Types::Message)

  A2A::Types::Message.from_h(message)
end

#ensure_task(task) ⇒ Task (protected)

Convert a task hash or object to a Task instance

Parameters:

  • task (Task, Hash)

    The task to convert

Returns:

  • (Task)

    The task instance



284
285
286
287
288
# File 'lib/a2a/client/base.rb', line 284

def ensure_task(task)
  return task if task.is_a?(A2A::Types::Task)

  A2A::Types::Task.from_h(task)
end

#execute_with_middleware(request, context = {}) {|request, context| ... } ⇒ Object (protected)

Execute middleware chain for a request

Parameters:

  • request (Object)

    The request object

  • context (Hash) (defaults to: {})

    The request context

Yields:

  • (request, context)

    The block to execute after middleware

Returns:

  • (Object)

    The result of the block execution



244
245
246
247
248
249
250
251
252
# File 'lib/a2a/client/base.rb', line 244

def execute_with_middleware(request, context = {}, &block)
  # Create a chain of middleware calls
  chain = @middleware.reverse.reduce(proc(&block)) do |next_call, middleware|
    proc { |req, ctx| middleware.call(req, ctx, next_call) }
  end

  # Execute the chain
  chain.call(request, context)
end

#get_card(context: nil, authenticated: false) ⇒ AgentCard

Get the agent card

Parameters:

  • context (Hash, nil) (defaults to: nil)

    Optional context information

  • authenticated (Boolean) (defaults to: false)

    Whether to get authenticated extended card

Returns:

  • (AgentCard)

    The agent card

Raises:

  • (NotImplementedError)

    Must be implemented by subclasses



70
71
72
# File 'lib/a2a/client/base.rb', line 70

def get_card(context: nil, authenticated: false)
  raise NotImplementedError, "#{self.class}#get_card must be implemented"
end

#get_endpoint_url(agent_card, transport) ⇒ String

Get the endpoint URL for a specific transport

Parameters:

  • agent_card (AgentCard)

    The agent card

  • transport (String)

    The transport protocol

Returns:

  • (String)

    The endpoint URL



223
224
225
226
227
228
229
230
231
232
233
# File 'lib/a2a/client/base.rb', line 223

def get_endpoint_url(agent_card, transport)
  # Check if the transport matches the preferred transport
  return agent_card.url if agent_card.preferred_transport == transport

  # Look for the transport in additional interfaces
  interface = agent_card.additional_interfaces&.find { |iface| iface.transport == transport }
  return interface.url if interface

  # Fallback to main URL if no specific interface found
  agent_card.url
end

#get_task(task_id, context: nil, history_length: nil) ⇒ Task

Get a task by ID

Parameters:

  • task_id (String)

    The task ID

  • context (Hash, nil) (defaults to: nil)

    Optional context information

  • history_length (Integer, nil) (defaults to: nil)

    Maximum number of history messages to include

Returns:

  • (Task)

    The task

Raises:

  • (NotImplementedError)

    Must be implemented by subclasses



48
49
50
# File 'lib/a2a/client/base.rb', line 48

def get_task(task_id, context: nil, history_length: nil)
  raise NotImplementedError, "#{self.class}#get_task must be implemented"
end

#get_task_callback(task_id, push_notification_config_id, context: nil) ⇒ TaskPushNotificationConfig

Get the callback configuration for a task

Parameters:

  • task_id (String)

    The task ID

  • push_notification_config_id (String)

    The push notification config ID

  • context (Hash, nil) (defaults to: nil)

    Optional context information

Returns:

  • (TaskPushNotificationConfig)

    The callback configuration

Raises:

  • (NotImplementedError)

    Must be implemented by subclasses



105
106
107
# File 'lib/a2a/client/base.rb', line 105

def get_task_callback(task_id, push_notification_config_id, context: nil)
  raise NotImplementedError, "#{self.class}#get_task_callback must be implemented"
end

#list_task_callbacks(task_id, context: nil) ⇒ Array<TaskPushNotificationConfig>

List all callback configurations for a task

Parameters:

  • task_id (String)

    The task ID

  • context (Hash, nil) (defaults to: nil)

    Optional context information

Returns:

  • (Array<TaskPushNotificationConfig>)

    List of callback configurations

Raises:

  • (NotImplementedError)

    Must be implemented by subclasses



116
117
118
# File 'lib/a2a/client/base.rb', line 116

def list_task_callbacks(task_id, context: nil)
  raise NotImplementedError, "#{self.class}#list_task_callbacks must be implemented"
end

#negotiate_transport(agent_card) ⇒ String

Negotiate transport with agent card

Parameters:

  • agent_card (AgentCard)

    The agent card

Returns:

  • (String)

    The negotiated transport protocol

Raises:



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/a2a/client/base.rb', line 197

def negotiate_transport(agent_card)
  # Use client preference if enabled
  if @config.use_client_preference?
    preferred = @config.preferred_transport
    return preferred if agent_supports_transport?(agent_card, preferred)
  end

  # Find first mutually supported transport
  @config.supported_transports.each do |transport|
    return transport if agent_supports_transport?(agent_card, transport)
  end

  # Fallback to agent's preferred transport if we support it
  agent_preferred = agent_card.preferred_transport
  return agent_preferred if @config.supports_transport?(agent_preferred)

  # No compatible transport found
  raise A2A::Errors::ClientError, "No compatible transport protocol found"
end

#polling?Boolean

Check if the client supports polling

Returns:

  • (Boolean)

    True if polling is supported and enabled



180
181
182
# File 'lib/a2a/client/base.rb', line 180

def polling?
  @config.polling?
end

#process_event(event) ⇒ void (protected)

This method returns an undefined value.

Process events with registered consumers

Parameters:

  • event (Object)

    The event to process



259
260
261
262
263
264
265
266
# File 'lib/a2a/client/base.rb', line 259

def process_event(event)
  @consumers.each do |consumer|
    consumer.call(event)
  rescue StandardError => e
    # Log error but don't fail the entire processing
    warn "Error in event consumer: #{e.message}"
  end
end

#remove_consumer(consumer) ⇒ void

This method returns an undefined value.

Remove an event consumer

Parameters:

  • consumer (Object)

    The event consumer to remove



164
165
166
# File 'lib/a2a/client/base.rb', line 164

def remove_consumer(consumer)
  @consumers.delete(consumer)
end

#remove_middleware(interceptor) ⇒ void

This method returns an undefined value.

Remove middleware from the client

Parameters:

  • interceptor (Object)

    The middleware interceptor to remove



146
147
148
# File 'lib/a2a/client/base.rb', line 146

def remove_middleware(interceptor)
  @middleware.delete(interceptor)
end

#resubscribe(task_id, context: nil) ⇒ Enumerator

Resubscribe to a task for streaming updates

Parameters:

  • task_id (String)

    The task ID to resubscribe to

  • context (Hash, nil) (defaults to: nil)

    Optional context information

Returns:

  • (Enumerator)

    Stream of task updates

Raises:

  • (NotImplementedError)

    Must be implemented by subclasses



81
82
83
# File 'lib/a2a/client/base.rb', line 81

def resubscribe(task_id, context: nil)
  raise NotImplementedError, "#{self.class}#resubscribe must be implemented"
end

#send_message(message, context: nil) ⇒ Enumerator, Message

Send a message to the agent

Parameters:

  • message (Message, Hash)

    The message to send

  • context (Hash, nil) (defaults to: nil)

    Optional context information

Returns:

  • (Enumerator, Message)

    Stream of responses or single response

Raises:

  • (NotImplementedError)

    Must be implemented by subclasses



36
37
38
# File 'lib/a2a/client/base.rb', line 36

def send_message(message, context: nil)
  raise NotImplementedError, "#{self.class}#send_message must be implemented"
end

#set_task_callback(task_id, push_notification_config, context: nil) ⇒ void

This method returns an undefined value.

Set a callback for task updates

Parameters:

  • task_id (String)

    The task ID

  • push_notification_config (PushNotificationConfig, Hash)

    The push notification configuration

  • context (Hash, nil) (defaults to: nil)

    Optional context information

Raises:

  • (NotImplementedError)

    Must be implemented by subclasses



93
94
95
# File 'lib/a2a/client/base.rb', line 93

def set_task_callback(task_id, push_notification_config, context: nil)
  raise NotImplementedError, "#{self.class}#set_task_callback must be implemented"
end

#streaming?Boolean

Check if the client supports streaming

Returns:

  • (Boolean)

    True if streaming is supported and enabled



172
173
174
# File 'lib/a2a/client/base.rb', line 172

def streaming?
  @config.streaming?
end

#supported_transportsArray<String>

Get the supported transports

Returns:

  • (Array<String>)

    List of supported transport protocols



188
189
190
# File 'lib/a2a/client/base.rb', line 188

def supported_transports
  @config.supported_transports
end