a2a-ruby 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +137 -0
  4. data/.simplecov +46 -0
  5. data/.yardopts +10 -0
  6. data/CHANGELOG.md +33 -0
  7. data/CODE_OF_CONDUCT.md +128 -0
  8. data/CONTRIBUTING.md +165 -0
  9. data/Gemfile +43 -0
  10. data/Guardfile +34 -0
  11. data/LICENSE.txt +21 -0
  12. data/PUBLISHING_CHECKLIST.md +214 -0
  13. data/README.md +171 -0
  14. data/Rakefile +165 -0
  15. data/docs/agent_execution.md +309 -0
  16. data/docs/api_reference.md +792 -0
  17. data/docs/configuration.md +780 -0
  18. data/docs/events.md +475 -0
  19. data/docs/getting_started.md +668 -0
  20. data/docs/integration.md +262 -0
  21. data/docs/server_apps.md +621 -0
  22. data/docs/troubleshooting.md +765 -0
  23. data/lib/a2a/client/api_methods.rb +263 -0
  24. data/lib/a2a/client/auth/api_key.rb +161 -0
  25. data/lib/a2a/client/auth/interceptor.rb +288 -0
  26. data/lib/a2a/client/auth/jwt.rb +189 -0
  27. data/lib/a2a/client/auth/oauth2.rb +146 -0
  28. data/lib/a2a/client/auth.rb +137 -0
  29. data/lib/a2a/client/base.rb +316 -0
  30. data/lib/a2a/client/config.rb +210 -0
  31. data/lib/a2a/client/connection_pool.rb +233 -0
  32. data/lib/a2a/client/http_client.rb +524 -0
  33. data/lib/a2a/client/json_rpc_handler.rb +136 -0
  34. data/lib/a2a/client/middleware/circuit_breaker_interceptor.rb +245 -0
  35. data/lib/a2a/client/middleware/logging_interceptor.rb +371 -0
  36. data/lib/a2a/client/middleware/rate_limit_interceptor.rb +142 -0
  37. data/lib/a2a/client/middleware/retry_interceptor.rb +161 -0
  38. data/lib/a2a/client/middleware.rb +116 -0
  39. data/lib/a2a/client/performance_tracker.rb +60 -0
  40. data/lib/a2a/configuration/defaults.rb +34 -0
  41. data/lib/a2a/configuration/environment_loader.rb +76 -0
  42. data/lib/a2a/configuration/file_loader.rb +115 -0
  43. data/lib/a2a/configuration/inheritance.rb +101 -0
  44. data/lib/a2a/configuration/validator.rb +180 -0
  45. data/lib/a2a/configuration.rb +201 -0
  46. data/lib/a2a/errors.rb +291 -0
  47. data/lib/a2a/modules.rb +50 -0
  48. data/lib/a2a/monitoring/alerting.rb +490 -0
  49. data/lib/a2a/monitoring/distributed_tracing.rb +398 -0
  50. data/lib/a2a/monitoring/health_endpoints.rb +204 -0
  51. data/lib/a2a/monitoring/metrics_collector.rb +438 -0
  52. data/lib/a2a/monitoring.rb +463 -0
  53. data/lib/a2a/plugin.rb +358 -0
  54. data/lib/a2a/plugin_manager.rb +159 -0
  55. data/lib/a2a/plugins/example_auth.rb +81 -0
  56. data/lib/a2a/plugins/example_middleware.rb +118 -0
  57. data/lib/a2a/plugins/example_transport.rb +76 -0
  58. data/lib/a2a/protocol/agent_card.rb +8 -0
  59. data/lib/a2a/protocol/agent_card_server.rb +584 -0
  60. data/lib/a2a/protocol/capability.rb +496 -0
  61. data/lib/a2a/protocol/json_rpc.rb +254 -0
  62. data/lib/a2a/protocol/message.rb +8 -0
  63. data/lib/a2a/protocol/task.rb +8 -0
  64. data/lib/a2a/rails/a2a_controller.rb +258 -0
  65. data/lib/a2a/rails/controller_helpers.rb +499 -0
  66. data/lib/a2a/rails/engine.rb +167 -0
  67. data/lib/a2a/rails/generators/agent_generator.rb +311 -0
  68. data/lib/a2a/rails/generators/install_generator.rb +209 -0
  69. data/lib/a2a/rails/generators/migration_generator.rb +232 -0
  70. data/lib/a2a/rails/generators/templates/add_a2a_indexes.rb +57 -0
  71. data/lib/a2a/rails/generators/templates/agent_controller.rb +122 -0
  72. data/lib/a2a/rails/generators/templates/agent_controller_spec.rb +160 -0
  73. data/lib/a2a/rails/generators/templates/agent_readme.md +200 -0
  74. data/lib/a2a/rails/generators/templates/create_a2a_push_notification_configs.rb +68 -0
  75. data/lib/a2a/rails/generators/templates/create_a2a_tasks.rb +83 -0
  76. data/lib/a2a/rails/generators/templates/example_agent_controller.rb +228 -0
  77. data/lib/a2a/rails/generators/templates/initializer.rb +108 -0
  78. data/lib/a2a/rails/generators/templates/push_notification_config_model.rb +228 -0
  79. data/lib/a2a/rails/generators/templates/task_model.rb +200 -0
  80. data/lib/a2a/rails/tasks/a2a.rake +228 -0
  81. data/lib/a2a/server/a2a_methods.rb +520 -0
  82. data/lib/a2a/server/agent.rb +537 -0
  83. data/lib/a2a/server/agent_execution/agent_executor.rb +279 -0
  84. data/lib/a2a/server/agent_execution/request_context.rb +219 -0
  85. data/lib/a2a/server/apps/rack_app.rb +311 -0
  86. data/lib/a2a/server/apps/sinatra_app.rb +261 -0
  87. data/lib/a2a/server/default_request_handler.rb +350 -0
  88. data/lib/a2a/server/events/event_consumer.rb +116 -0
  89. data/lib/a2a/server/events/event_queue.rb +226 -0
  90. data/lib/a2a/server/example_agent.rb +248 -0
  91. data/lib/a2a/server/handler.rb +281 -0
  92. data/lib/a2a/server/middleware/authentication_middleware.rb +212 -0
  93. data/lib/a2a/server/middleware/cors_middleware.rb +171 -0
  94. data/lib/a2a/server/middleware/logging_middleware.rb +362 -0
  95. data/lib/a2a/server/middleware/rate_limit_middleware.rb +382 -0
  96. data/lib/a2a/server/middleware.rb +213 -0
  97. data/lib/a2a/server/push_notification_manager.rb +327 -0
  98. data/lib/a2a/server/request_handler.rb +136 -0
  99. data/lib/a2a/server/storage/base.rb +141 -0
  100. data/lib/a2a/server/storage/database.rb +266 -0
  101. data/lib/a2a/server/storage/memory.rb +274 -0
  102. data/lib/a2a/server/storage/redis.rb +320 -0
  103. data/lib/a2a/server/storage.rb +38 -0
  104. data/lib/a2a/server/task_manager.rb +534 -0
  105. data/lib/a2a/transport/grpc.rb +481 -0
  106. data/lib/a2a/transport/http.rb +415 -0
  107. data/lib/a2a/transport/sse.rb +499 -0
  108. data/lib/a2a/types/agent_card.rb +540 -0
  109. data/lib/a2a/types/artifact.rb +99 -0
  110. data/lib/a2a/types/base_model.rb +223 -0
  111. data/lib/a2a/types/events.rb +117 -0
  112. data/lib/a2a/types/message.rb +106 -0
  113. data/lib/a2a/types/part.rb +288 -0
  114. data/lib/a2a/types/push_notification.rb +139 -0
  115. data/lib/a2a/types/security.rb +167 -0
  116. data/lib/a2a/types/task.rb +154 -0
  117. data/lib/a2a/types.rb +88 -0
  118. data/lib/a2a/utils/helpers.rb +245 -0
  119. data/lib/a2a/utils/message_buffer.rb +278 -0
  120. data/lib/a2a/utils/performance.rb +247 -0
  121. data/lib/a2a/utils/rails_detection.rb +97 -0
  122. data/lib/a2a/utils/structured_logger.rb +306 -0
  123. data/lib/a2a/utils/time_helpers.rb +167 -0
  124. data/lib/a2a/utils/validation.rb +8 -0
  125. data/lib/a2a/version.rb +6 -0
  126. data/lib/a2a-rails.rb +58 -0
  127. data/lib/a2a.rb +198 -0
  128. metadata +437 -0
@@ -0,0 +1,668 @@
1
+ # Getting Started with A2A Ruby SDK
2
+
3
+ Welcome to the A2A Ruby SDK! This guide will help you get up and running with Google's Agent2Agent (A2A) Protocol in your Ruby applications.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Basic Concepts](#basic-concepts)
9
+ - [Your First A2A Client](#your-first-a2a-client)
10
+ - [Your First A2A Server](#your-first-a2a-server)
11
+ - [Rails Integration](#rails-integration)
12
+ - [Authentication](#authentication)
13
+ - [Task Management](#task-management)
14
+ - [Troubleshooting](#troubleshooting)
15
+ - [Next Steps](#next-steps)
16
+
17
+ ## Installation
18
+
19
+ ### Requirements
20
+
21
+ - Ruby 2.7 or higher
22
+ - Bundler
23
+
24
+ ### Install the Gem
25
+
26
+ Add to your Gemfile:
27
+
28
+ ```ruby
29
+ gem 'a2a-ruby'
30
+ ```
31
+
32
+ Then run:
33
+
34
+ ```bash
35
+ bundle install
36
+ ```
37
+
38
+ Or install directly:
39
+
40
+ ```bash
41
+ gem install a2a-ruby
42
+ ```
43
+
44
+ ### Verify Installation
45
+
46
+ ```ruby
47
+ require 'a2a'
48
+ puts A2A::VERSION
49
+ ```
50
+
51
+ ## Basic Concepts
52
+
53
+ ### Agent2Agent Protocol
54
+
55
+ The A2A protocol enables agents to communicate with each other using standardized message formats and transport protocols. Key concepts include:
56
+
57
+ - **Messages**: Structured communication between agents
58
+ - **Tasks**: Long-running operations with lifecycle management
59
+ - **Agent Cards**: Self-describing agent capabilities
60
+ - **Transports**: Communication protocols (JSON-RPC, gRPC, HTTP+JSON)
61
+
62
+ ### Core Components
63
+
64
+ - **Client**: Consumes services from other agents
65
+ - **Server**: Exposes your application as an A2A agent
66
+ - **Types**: Protocol-compliant data structures
67
+ - **Transport**: Communication layer (HTTP, gRPC, SSE)
68
+
69
+ ## Your First A2A Client
70
+
71
+ Let's create a simple client to communicate with an A2A agent:
72
+
73
+ ```ruby
74
+ require 'a2a'
75
+
76
+ # Create a client pointing to an A2A agent
77
+ client = A2A::Client::HttpClient.new("https://example-agent.com/a2a")
78
+
79
+ # Create a message
80
+ message = A2A::Types::Message.new(
81
+ message_id: SecureRandom.uuid,
82
+ role: "user",
83
+ parts: [
84
+ A2A::Types::TextPart.new(text: "What's the weather like today?")
85
+ ]
86
+ )
87
+
88
+ # Send the message and handle responses
89
+ begin
90
+ client.send_message(message) do |response|
91
+ case response
92
+ when A2A::Types::Message
93
+ puts "Agent: #{response.parts.first.text}"
94
+ when A2A::Types::TaskStatusUpdateEvent
95
+ puts "Task Status: #{response.status.state}"
96
+ when A2A::Types::Task
97
+ puts "Task Created: #{response.id}"
98
+ end
99
+ end
100
+ rescue A2A::Errors::ClientError => e
101
+ puts "Error: #{e.message}"
102
+ end
103
+ ```
104
+
105
+ ### Client Configuration
106
+
107
+ ```ruby
108
+ # Configure client behavior
109
+ config = A2A::Client::Config.new
110
+ config.streaming = true
111
+ config.timeout = 60
112
+ config.supported_transports = ['JSONRPC', 'HTTP+JSON']
113
+
114
+ client = A2A::Client::HttpClient.new(
115
+ "https://example-agent.com/a2a",
116
+ config: config
117
+ )
118
+ ```
119
+
120
+ ### Working with Tasks
121
+
122
+ ```ruby
123
+ # Get task status
124
+ task = client.get_task("task-123")
125
+ puts "Task state: #{task.status.state}"
126
+
127
+ # Cancel a task
128
+ client.cancel_task("task-123")
129
+
130
+ # Resubscribe to task updates
131
+ client.resubscribe("task-123") do |event|
132
+ puts "Task update: #{event.status.state}"
133
+ end
134
+ ```
135
+
136
+ ## Your First A2A Server
137
+
138
+ Create an A2A server to expose your application's capabilities:
139
+
140
+ ### Plain Ruby Server
141
+
142
+ ```ruby
143
+ require 'a2a'
144
+ require 'sinatra'
145
+
146
+ class WeatherAgent
147
+ include A2A::Server::Agent
148
+
149
+ # Define agent skills
150
+ a2a_skill "weather_lookup" do |skill|
151
+ skill.description = "Get current weather information"
152
+ skill.tags = ["weather", "information"]
153
+ skill.examples = ["What's the weather in San Francisco?"]
154
+ skill.input_modes = ["text"]
155
+ skill.output_modes = ["text"]
156
+ end
157
+
158
+ # Define A2A methods
159
+ a2a_method "get_weather" do |params|
160
+ location = params[:location] || "Unknown"
161
+
162
+ # Simulate weather lookup
163
+ {
164
+ location: location,
165
+ temperature: "72°F",
166
+ condition: "Sunny",
167
+ timestamp: Time.current.iso8601
168
+ }
169
+ end
170
+
171
+ # Streaming method example
172
+ a2a_method "weather_forecast", streaming: true do |params|
173
+ Enumerator.new do |yielder|
174
+ # Yield status updates
175
+ yielder << A2A::Types::TaskStatusUpdateEvent.new(
176
+ task_id: params[:task_id],
177
+ context_id: params[:context_id],
178
+ status: A2A::Types::TaskStatus.new(state: "working")
179
+ )
180
+
181
+ # Generate forecast data
182
+ 5.times do |day|
183
+ forecast = {
184
+ day: day + 1,
185
+ temperature: "#{70 + rand(10)}°F",
186
+ condition: ["Sunny", "Cloudy", "Rainy"].sample
187
+ }
188
+
189
+ yielder << A2A::Types::Message.new(
190
+ message_id: SecureRandom.uuid,
191
+ role: "agent",
192
+ parts: [A2A::Types::TextPart.new(text: forecast.to_json)]
193
+ )
194
+ end
195
+
196
+ # Final status
197
+ yielder << A2A::Types::TaskStatusUpdateEvent.new(
198
+ task_id: params[:task_id],
199
+ context_id: params[:context_id],
200
+ status: A2A::Types::TaskStatus.new(state: "completed")
201
+ )
202
+ end
203
+ end
204
+ end
205
+
206
+ # Sinatra integration
207
+ post '/a2a/rpc' do
208
+ content_type :json
209
+
210
+ agent = WeatherAgent.new
211
+ request_body = request.body.read
212
+
213
+ begin
214
+ json_rpc_request = A2A::Protocol::JsonRpc.parse_request(request_body)
215
+ response = agent.handle_a2a_request(json_rpc_request)
216
+ response.to_json
217
+ rescue A2A::Errors::A2AError => e
218
+ status 400
219
+ e.to_json_rpc_error.to_json
220
+ end
221
+ end
222
+
223
+ get '/a2a/agent-card' do
224
+ content_type :json
225
+
226
+ agent = WeatherAgent.new
227
+ card = agent.generate_agent_card(
228
+ name: "Weather Agent",
229
+ description: "Provides weather information and forecasts",
230
+ version: "1.0.0",
231
+ url: "#{request.base_url}/a2a"
232
+ )
233
+
234
+ card.to_h.to_json
235
+ end
236
+ ```
237
+
238
+ ## Rails Integration
239
+
240
+ The A2A Ruby SDK provides seamless Rails integration through an engine.
241
+
242
+ ### Setup
243
+
244
+ Generate the A2A configuration:
245
+
246
+ ```bash
247
+ rails generate a2a:install
248
+ ```
249
+
250
+ This creates:
251
+ - `config/initializers/a2a.rb` - Configuration file
252
+ - Routes for A2A endpoints
253
+ - Database migrations (if using ActiveRecord storage)
254
+
255
+ ### Create an Agent Controller
256
+
257
+ ```bash
258
+ rails generate a2a:agent weather
259
+ ```
260
+
261
+ This generates:
262
+ - `app/controllers/weather_agent_controller.rb`
263
+ - Spec file
264
+ - README with usage instructions
265
+
266
+ ### Example Agent Controller
267
+
268
+ ```ruby
269
+ class WeatherAgentController < ApplicationController
270
+ include A2A::Rails::ControllerHelpers
271
+
272
+ # Define agent metadata
273
+ a2a_config(
274
+ name: "Weather Service Agent",
275
+ description: "Provides weather information and forecasts",
276
+ version: "1.0.0"
277
+ )
278
+
279
+ # Define skills
280
+ a2a_skill "weather_lookup" do |skill|
281
+ skill.description = "Get current weather for any location"
282
+ skill.tags = ["weather", "current", "lookup"]
283
+ skill.examples = [
284
+ "What's the weather in New York?",
285
+ "Current conditions in Tokyo"
286
+ ]
287
+ end
288
+
289
+ # A2A method implementations
290
+ a2a_method "get_current_weather" do |params|
291
+ location = params[:location]
292
+
293
+ # Your weather service logic here
294
+ weather_data = WeatherService.current(location)
295
+
296
+ {
297
+ location: location,
298
+ temperature: weather_data.temperature,
299
+ condition: weather_data.condition,
300
+ humidity: weather_data.humidity,
301
+ timestamp: Time.current.iso8601
302
+ }
303
+ end
304
+
305
+ a2a_method "get_forecast", streaming: true do |params|
306
+ location = params[:location]
307
+ days = params[:days] || 5
308
+
309
+ Enumerator.new do |yielder|
310
+ # Initial status
311
+ yielder << task_status_update("working", "Fetching forecast data...")
312
+
313
+ # Get forecast data
314
+ forecast = WeatherService.forecast(location, days)
315
+
316
+ forecast.each_with_index do |day_forecast, index|
317
+ # Yield each day's forecast
318
+ message = A2A::Types::Message.new(
319
+ message_id: SecureRandom.uuid,
320
+ role: "agent",
321
+ parts: [
322
+ A2A::Types::TextPart.new(
323
+ text: "Day #{index + 1}: #{day_forecast.condition}, #{day_forecast.temperature}"
324
+ )
325
+ ]
326
+ )
327
+ yielder << message
328
+
329
+ # Progress update
330
+ progress = ((index + 1).to_f / days * 100).round
331
+ yielder << task_status_update("working", "Progress: #{progress}%", progress)
332
+ end
333
+
334
+ # Completion
335
+ yielder << task_status_update("completed", "Forecast complete")
336
+ end
337
+ end
338
+
339
+ private
340
+
341
+ def task_status_update(state, message = nil, progress = nil)
342
+ A2A::Types::TaskStatusUpdateEvent.new(
343
+ task_id: params[:task_id],
344
+ context_id: params[:context_id],
345
+ status: A2A::Types::TaskStatus.new(
346
+ state: state,
347
+ message: message,
348
+ progress: progress
349
+ )
350
+ )
351
+ end
352
+ end
353
+ ```
354
+
355
+ ### Routes
356
+
357
+ The Rails engine automatically provides these routes:
358
+
359
+ ```ruby
360
+ # config/routes.rb
361
+ Rails.application.routes.draw do
362
+ mount A2A::Engine => "/a2a"
363
+
364
+ # This provides:
365
+ # POST /a2a/rpc - JSON-RPC endpoint
366
+ # GET /a2a/agent-card - Agent card discovery
367
+ # GET /a2a/capabilities - Capabilities listing
368
+ end
369
+ ```
370
+
371
+ ## Authentication
372
+
373
+ ### Client Authentication
374
+
375
+ ```ruby
376
+ # OAuth 2.0
377
+ auth = A2A::Client::Auth::OAuth2.new(
378
+ client_id: "your-client-id",
379
+ client_secret: "your-client-secret",
380
+ token_url: "https://auth.example.com/token"
381
+ )
382
+
383
+ client = A2A::Client::HttpClient.new(
384
+ "https://agent.example.com/a2a",
385
+ auth: auth
386
+ )
387
+
388
+ # JWT Bearer Token
389
+ auth = A2A::Client::Auth::JWT.new(token: "your-jwt-token")
390
+
391
+ # API Key
392
+ auth = A2A::Client::Auth::ApiKey.new(
393
+ key: "your-api-key",
394
+ header: "X-API-Key" # or use query parameter
395
+ )
396
+ ```
397
+
398
+ ### Server Authentication
399
+
400
+ ```ruby
401
+ class SecureAgentController < ApplicationController
402
+ include A2A::Rails::ControllerHelpers
403
+
404
+ # Configure authentication
405
+ before_action :authenticate_a2a_request
406
+
407
+ private
408
+
409
+ def authenticate_a2a_request
410
+ # JWT validation example
411
+ token = request.headers['Authorization']&.sub(/^Bearer /, '')
412
+
413
+ begin
414
+ payload = JWT.decode(token, Rails.application.secret_key_base, true, algorithm: 'HS256')
415
+ @current_user = User.find(payload[0]['user_id'])
416
+ rescue JWT::DecodeError
417
+ render json: { error: 'Invalid token' }, status: :unauthorized
418
+ end
419
+ end
420
+ end
421
+ ```
422
+
423
+ ## Task Management
424
+
425
+ ### Creating and Managing Tasks
426
+
427
+ ```ruby
428
+ # In your agent method
429
+ a2a_method "long_running_task" do |params|
430
+ # Create a task
431
+ task = create_task(
432
+ type: "data_processing",
433
+ params: params,
434
+ metadata: { user_id: current_user.id }
435
+ )
436
+
437
+ # Start background processing
438
+ ProcessDataJob.perform_later(task.id, params)
439
+
440
+ # Return task immediately
441
+ task
442
+ end
443
+
444
+ # Background job
445
+ class ProcessDataJob < ApplicationJob
446
+ def perform(task_id, params)
447
+ task_manager = A2A::Server::TaskManager.new
448
+
449
+ begin
450
+ # Update status
451
+ task_manager.update_task_status(task_id,
452
+ A2A::Types::TaskStatus.new(state: "working")
453
+ )
454
+
455
+ # Do work...
456
+ result = process_data(params)
457
+
458
+ # Complete task
459
+ task_manager.update_task_status(task_id,
460
+ A2A::Types::TaskStatus.new(
461
+ state: "completed",
462
+ result: result
463
+ )
464
+ )
465
+ rescue => e
466
+ # Handle errors
467
+ task_manager.update_task_status(task_id,
468
+ A2A::Types::TaskStatus.new(
469
+ state: "failed",
470
+ error: { message: e.message, type: e.class.name }
471
+ )
472
+ )
473
+ end
474
+ end
475
+ end
476
+ ```
477
+
478
+ ### Push Notifications
479
+
480
+ ```ruby
481
+ # Set up push notifications for a task
482
+ push_config = A2A::Types::PushNotificationConfig.new(
483
+ url: "https://your-app.com/webhooks/a2a",
484
+ authentication: {
485
+ type: "bearer",
486
+ token: "your-webhook-token"
487
+ }
488
+ )
489
+
490
+ client.set_task_callback(task_id, push_config)
491
+
492
+ # Webhook handler
493
+ post '/webhooks/a2a' do
494
+ # Verify authentication
495
+ token = request.headers['Authorization']&.sub(/^Bearer /, '')
496
+ halt 401 unless token == ENV['WEBHOOK_TOKEN']
497
+
498
+ # Parse event
499
+ event_data = JSON.parse(request.body.read)
500
+
501
+ case event_data['type']
502
+ when 'TaskStatusUpdateEvent'
503
+ handle_task_status_update(event_data)
504
+ when 'TaskArtifactUpdateEvent'
505
+ handle_task_artifact_update(event_data)
506
+ end
507
+
508
+ status 200
509
+ end
510
+ ```
511
+
512
+ ## Troubleshooting
513
+
514
+ ### Common Issues
515
+
516
+ #### Connection Errors
517
+
518
+ ```ruby
519
+ begin
520
+ client.send_message(message)
521
+ rescue A2A::Errors::HTTPError => e
522
+ puts "HTTP Error: #{e.message}"
523
+ # Check network connectivity and endpoint URL
524
+ rescue A2A::Errors::TimeoutError => e
525
+ puts "Timeout: #{e.message}"
526
+ # Increase timeout or check server performance
527
+ end
528
+ ```
529
+
530
+ #### Authentication Failures
531
+
532
+ ```ruby
533
+ begin
534
+ client.send_message(message)
535
+ rescue A2A::Errors::AuthenticationError => e
536
+ puts "Auth Error: #{e.message}"
537
+ # Check credentials and token expiration
538
+ end
539
+ ```
540
+
541
+ #### Protocol Errors
542
+
543
+ ```ruby
544
+ begin
545
+ response = client.send_message(message)
546
+ rescue A2A::Errors::InvalidRequest => e
547
+ puts "Invalid Request: #{e.message}"
548
+ # Check message format and required fields
549
+ rescue A2A::Errors::MethodNotFound => e
550
+ puts "Method Not Found: #{e.message}"
551
+ # Check agent card for available methods
552
+ end
553
+ ```
554
+
555
+ ### Debugging
556
+
557
+ Enable debug logging:
558
+
559
+ ```ruby
560
+ A2A.configure do |config|
561
+ config.log_level = :debug
562
+ end
563
+ ```
564
+
565
+ Use the development console:
566
+
567
+ ```bash
568
+ bin/console
569
+ ```
570
+
571
+ ```ruby
572
+ # Test agent card retrieval
573
+ client = A2A::Client::HttpClient.new("https://agent.example.com/a2a")
574
+ card = client.get_card
575
+ puts card.to_h.to_json
576
+ ```
577
+
578
+ ### Performance Issues
579
+
580
+ Monitor performance with built-in metrics:
581
+
582
+ ```ruby
583
+ A2A.configure do |config|
584
+ config.enable_metrics = true
585
+ config.metrics_backend = :prometheus # or :statsd
586
+ end
587
+ ```
588
+
589
+ ### FAQ
590
+
591
+ **Q: How do I handle file uploads in messages?**
592
+
593
+ A: Use `FilePart` with base64 encoding or URI references:
594
+
595
+ ```ruby
596
+ # Base64 file
597
+ file_part = A2A::Types::FilePart.new(
598
+ file: A2A::Types::FileWithBytes.new(
599
+ name: "document.pdf",
600
+ mime_type: "application/pdf",
601
+ bytes: Base64.encode64(file_content)
602
+ )
603
+ )
604
+
605
+ # URI reference
606
+ file_part = A2A::Types::FilePart.new(
607
+ file: A2A::Types::FileWithUri.new(
608
+ name: "document.pdf",
609
+ mime_type: "application/pdf",
610
+ uri: "https://storage.example.com/files/document.pdf"
611
+ )
612
+ )
613
+ ```
614
+
615
+ **Q: How do I implement custom authentication?**
616
+
617
+ A: Create a custom auth strategy:
618
+
619
+ ```ruby
620
+ class CustomAuth < A2A::Client::Auth::Base
621
+ def initialize(api_key)
622
+ @api_key = api_key
623
+ end
624
+
625
+ def apply_auth(request)
626
+ request.headers['X-Custom-Auth'] = @api_key
627
+ end
628
+ end
629
+
630
+ client = A2A::Client::HttpClient.new(url, auth: CustomAuth.new("key"))
631
+ ```
632
+
633
+ **Q: Can I use multiple transports?**
634
+
635
+ A: Yes, configure transport preferences:
636
+
637
+ ```ruby
638
+ config = A2A::Client::Config.new
639
+ config.supported_transports = ['JSONRPC', 'GRPC', 'HTTP+JSON']
640
+ config.use_client_preference = true
641
+
642
+ client = A2A::Client::HttpClient.new(url, config: config)
643
+ ```
644
+
645
+ ## Next Steps
646
+
647
+ Now that you have the basics, explore these advanced topics:
648
+
649
+ - [Client Documentation](client.md) - Advanced client configuration and usage
650
+ - [Server Documentation](server.md) - Building production-ready A2A servers
651
+ - [Rails Integration](rails.md) - Deep dive into Rails-specific features
652
+ - [Authentication Guide](authentication.md) - Comprehensive security setup
653
+ - [Deployment Guide](deployment.md) - Production deployment best practices
654
+ - [API Reference](https://rubydoc.info/gems/a2a-ruby) - Complete API documentation
655
+
656
+ ### Example Applications
657
+
658
+ Check out complete example applications:
659
+
660
+ - [Weather Agent](https://github.com/a2aproject/a2a-ruby-examples/tree/main/weather-agent)
661
+ - [File Processing Service](https://github.com/a2aproject/a2a-ruby-examples/tree/main/file-processor)
662
+ - [Multi-Agent Chat](https://github.com/a2aproject/a2a-ruby-examples/tree/main/multi-agent-chat)
663
+
664
+ ### Community
665
+
666
+ - [GitHub Discussions](https://github.com/a2aproject/a2a-ruby/discussions)
667
+ - [Issue Tracker](https://github.com/a2aproject/a2a-ruby/issues)
668
+ - [Contributing Guide](../CONTRIBUTING.md)