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,792 @@
1
+ # API Reference
2
+
3
+ This document provides a comprehensive reference for the A2A Ruby SDK API.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Client API](#client-api)
8
+ - [Server API](#server-api)
9
+ - [Types API](#types-api)
10
+ - [Configuration API](#configuration-api)
11
+ - [Transport API](#transport-api)
12
+ - [Authentication API](#authentication-api)
13
+ - [Error Handling](#error-handling)
14
+
15
+ ## Client API
16
+
17
+ ### A2A::Client::HttpClient
18
+
19
+ The primary client for communicating with A2A agents over HTTP.
20
+
21
+ #### Constructor
22
+
23
+ ```ruby
24
+ client = A2A::Client::HttpClient.new(endpoint_url, **options)
25
+ ```
26
+
27
+ **Parameters:**
28
+ - `endpoint_url` (String) - The A2A agent endpoint URL
29
+ - `options` (Hash) - Optional configuration
30
+ - `:auth` (A2A::Client::Auth::Base) - Authentication strategy
31
+ - `:config` (A2A::Client::Config) - Client configuration
32
+ - `:middleware` (Array) - Middleware stack
33
+ - `:consumers` (Array) - Event consumers
34
+
35
+ **Example:**
36
+ ```ruby
37
+ auth = A2A::Client::Auth::OAuth2.new(
38
+ client_id: "your-id",
39
+ client_secret: "your-secret",
40
+ token_url: "https://auth.example.com/token"
41
+ )
42
+
43
+ config = A2A::Client::Config.new
44
+ config.timeout = 60
45
+ config.streaming = true
46
+
47
+ client = A2A::Client::HttpClient.new(
48
+ "https://agent.example.com/a2a",
49
+ auth: auth,
50
+ config: config
51
+ )
52
+ ```
53
+
54
+ #### Methods
55
+
56
+ ##### send_message(message, context: nil, &block)
57
+
58
+ Sends a message to the agent and handles responses.
59
+
60
+ **Parameters:**
61
+ - `message` (A2A::Types::Message) - The message to send
62
+ - `context` (Hash, optional) - Request context
63
+ - `&block` - Block to handle streaming responses
64
+
65
+ **Returns:**
66
+ - Single response (if not streaming)
67
+ - Enumerator (if streaming without block)
68
+ - Yields responses to block (if streaming with block)
69
+
70
+ **Example:**
71
+ ```ruby
72
+ message = A2A::Types::Message.new(
73
+ message_id: SecureRandom.uuid,
74
+ role: "user",
75
+ parts: [A2A::Types::TextPart.new(text: "Hello!")]
76
+ )
77
+
78
+ # Blocking call
79
+ response = client.send_message(message, streaming: false)
80
+
81
+ # Streaming with block
82
+ client.send_message(message) do |response|
83
+ case response
84
+ when A2A::Types::Message
85
+ puts "Agent: #{response.parts.first.text}"
86
+ when A2A::Types::TaskStatusUpdateEvent
87
+ puts "Status: #{response.status.state}"
88
+ end
89
+ end
90
+
91
+ # Streaming with enumerator
92
+ responses = client.send_message(message)
93
+ responses.each { |response| process(response) }
94
+ ```
95
+
96
+ ##### get_task(task_id, context: nil, history_length: nil)
97
+
98
+ Retrieves a task by ID.
99
+
100
+ **Parameters:**
101
+ - `task_id` (String) - The task ID
102
+ - `context` (Hash, optional) - Request context
103
+ - `history_length` (Integer, optional) - Limit message history
104
+
105
+ **Returns:**
106
+ - `A2A::Types::Task` - The task object
107
+
108
+ **Example:**
109
+ ```ruby
110
+ task = client.get_task("task-123", history_length: 10)
111
+ puts "Task state: #{task.status.state}"
112
+ puts "Progress: #{task.status.progress}%" if task.status.progress
113
+ ```
114
+
115
+ ##### cancel_task(task_id, context: nil)
116
+
117
+ Cancels a task.
118
+
119
+ **Parameters:**
120
+ - `task_id` (String) - The task ID
121
+ - `context` (Hash, optional) - Request context
122
+
123
+ **Returns:**
124
+ - `A2A::Types::Task` - The updated task
125
+
126
+ **Example:**
127
+ ```ruby
128
+ begin
129
+ task = client.cancel_task("task-123")
130
+ puts "Task canceled: #{task.status.state}"
131
+ rescue A2A::Errors::TaskNotCancelable => e
132
+ puts "Cannot cancel task: #{e.message}"
133
+ end
134
+ ```
135
+
136
+ ##### resubscribe(task_id, context: nil, &block)
137
+
138
+ Resubscribes to task updates for streaming.
139
+
140
+ **Parameters:**
141
+ - `task_id` (String) - The task ID
142
+ - `context` (Hash, optional) - Request context
143
+ - `&block` - Block to handle events
144
+
145
+ **Example:**
146
+ ```ruby
147
+ client.resubscribe("task-123") do |event|
148
+ case event
149
+ when A2A::Types::TaskStatusUpdateEvent
150
+ puts "Status update: #{event.status.state}"
151
+ when A2A::Types::TaskArtifactUpdateEvent
152
+ puts "New artifact: #{event.artifact.name}"
153
+ end
154
+ end
155
+ ```
156
+
157
+ ##### get_card(context: nil)
158
+
159
+ Retrieves the agent card.
160
+
161
+ **Parameters:**
162
+ - `context` (Hash, optional) - Request context
163
+
164
+ **Returns:**
165
+ - `A2A::Types::AgentCard` - The agent card
166
+
167
+ **Example:**
168
+ ```ruby
169
+ card = client.get_card
170
+ puts "Agent: #{card.name} v#{card.version}"
171
+ puts "Skills: #{card.skills.map(&:name).join(', ')}"
172
+ ```
173
+
174
+ ##### set_task_callback(task_id, push_config, context: nil)
175
+
176
+ Sets up push notifications for a task.
177
+
178
+ **Parameters:**
179
+ - `task_id` (String) - The task ID
180
+ - `push_config` (A2A::Types::PushNotificationConfig) - Push notification configuration
181
+ - `context` (Hash, optional) - Request context
182
+
183
+ **Example:**
184
+ ```ruby
185
+ push_config = A2A::Types::PushNotificationConfig.new(
186
+ url: "https://your-app.com/webhooks/a2a",
187
+ authentication: {
188
+ type: "bearer",
189
+ token: "webhook-secret"
190
+ }
191
+ )
192
+
193
+ client.set_task_callback("task-123", push_config)
194
+ ```
195
+
196
+ ### A2A::Client::Config
197
+
198
+ Client configuration object.
199
+
200
+ #### Properties
201
+
202
+ ```ruby
203
+ config = A2A::Client::Config.new
204
+
205
+ # Streaming configuration
206
+ config.streaming = true # Enable streaming responses
207
+ config.polling = false # Enable polling fallback
208
+
209
+ # Transport configuration
210
+ config.supported_transports = ['JSONRPC'] # Supported transport protocols
211
+ config.use_client_preference = true # Use client transport preference
212
+
213
+ # Timeout configuration
214
+ config.timeout = 30 # Request timeout in seconds
215
+ config.connect_timeout = 10 # Connection timeout in seconds
216
+
217
+ # Output configuration
218
+ config.accepted_output_modes = ['text', 'structured'] # Accepted output modes
219
+
220
+ # Push notification configuration
221
+ config.push_notification_configs = [] # Default push notification configs
222
+ ```
223
+
224
+ ## Server API
225
+
226
+ ### A2A::Server::Agent
227
+
228
+ Mixin for creating A2A agents.
229
+
230
+ #### Usage
231
+
232
+ ```ruby
233
+ class MyAgent
234
+ include A2A::Server::Agent
235
+
236
+ # Agent configuration
237
+ a2a_config(
238
+ name: "My Agent",
239
+ description: "A sample A2A agent",
240
+ version: "1.0.0"
241
+ )
242
+
243
+ # Define skills
244
+ a2a_skill "greeting" do |skill|
245
+ skill.description = "Greet users"
246
+ skill.tags = ["greeting", "conversation"]
247
+ skill.examples = ["Hello", "Say hi"]
248
+ skill.input_modes = ["text"]
249
+ skill.output_modes = ["text"]
250
+ end
251
+
252
+ # Define methods
253
+ a2a_method "greet" do |params|
254
+ name = params[:name] || "there"
255
+ { message: "Hello, #{name}!" }
256
+ end
257
+ end
258
+ ```
259
+
260
+ #### Class Methods
261
+
262
+ ##### a2a_config(**options)
263
+
264
+ Configures the agent metadata.
265
+
266
+ **Parameters:**
267
+ - `name` (String) - Agent name
268
+ - `description` (String) - Agent description
269
+ - `version` (String) - Agent version
270
+ - `url` (String, optional) - Agent URL
271
+ - `provider` (Hash, optional) - Provider information
272
+
273
+ ##### a2a_skill(name, &block)
274
+
275
+ Defines an agent skill.
276
+
277
+ **Parameters:**
278
+ - `name` (String) - Skill name
279
+ - `&block` - Configuration block
280
+
281
+ **Block methods:**
282
+ - `description` (String) - Skill description
283
+ - `tags` (Array<String>) - Skill tags
284
+ - `examples` (Array<String>) - Usage examples
285
+ - `input_modes` (Array<String>) - Supported input modes
286
+ - `output_modes` (Array<String>) - Supported output modes
287
+ - `security` (Hash, optional) - Security requirements
288
+
289
+ ##### a2a_method(name, **options, &block)
290
+
291
+ Defines an A2A method.
292
+
293
+ **Parameters:**
294
+ - `name` (String) - Method name
295
+ - `options` (Hash) - Method options
296
+ - `:streaming` (Boolean) - Whether method supports streaming
297
+ - `:auth_required` (Boolean) - Whether authentication is required
298
+ - `&block` - Method implementation
299
+
300
+ **Example:**
301
+ ```ruby
302
+ # Simple method
303
+ a2a_method "get_weather" do |params|
304
+ location = params[:location]
305
+ WeatherService.current(location)
306
+ end
307
+
308
+ # Streaming method
309
+ a2a_method "weather_forecast", streaming: true do |params|
310
+ Enumerator.new do |yielder|
311
+ # Yield status updates
312
+ yielder << task_status_update("working")
313
+
314
+ # Yield data
315
+ forecast_data.each do |day|
316
+ message = A2A::Types::Message.new(
317
+ message_id: SecureRandom.uuid,
318
+ role: "agent",
319
+ parts: [A2A::Types::TextPart.new(text: day.to_json)]
320
+ )
321
+ yielder << message
322
+ end
323
+
324
+ # Final status
325
+ yielder << task_status_update("completed")
326
+ end
327
+ end
328
+
329
+ # Method with authentication
330
+ a2a_method "secure_operation", auth_required: true do |params|
331
+ # Access current user via @current_user (set by auth middleware)
332
+ return { error: "Unauthorized" } unless @current_user
333
+
334
+ perform_secure_operation(params, @current_user)
335
+ end
336
+ ```
337
+
338
+ #### Instance Methods
339
+
340
+ ##### handle_a2a_request(request)
341
+
342
+ Handles an A2A JSON-RPC request.
343
+
344
+ **Parameters:**
345
+ - `request` (A2A::Protocol::JsonRpc::Request) - The JSON-RPC request
346
+
347
+ **Returns:**
348
+ - Hash - JSON-RPC response
349
+
350
+ ##### generate_agent_card(**overrides)
351
+
352
+ Generates an agent card from the agent definition.
353
+
354
+ **Parameters:**
355
+ - `overrides` (Hash) - Override default values
356
+
357
+ **Returns:**
358
+ - `A2A::Types::AgentCard` - The agent card
359
+
360
+ ### A2A::Server::TaskManager
361
+
362
+ Manages task lifecycle and persistence.
363
+
364
+ #### Constructor
365
+
366
+ ```ruby
367
+ task_manager = A2A::Server::TaskManager.new(storage: storage_backend)
368
+ ```
369
+
370
+ #### Methods
371
+
372
+ ##### create_task(type:, params: {}, **options)
373
+
374
+ Creates a new task.
375
+
376
+ **Parameters:**
377
+ - `type` (String) - Task type
378
+ - `params` (Hash) - Task parameters
379
+ - `options` (Hash) - Additional options
380
+
381
+ **Returns:**
382
+ - `A2A::Types::Task` - The created task
383
+
384
+ ##### update_task_status(task_id, status)
385
+
386
+ Updates task status.
387
+
388
+ **Parameters:**
389
+ - `task_id` (String) - Task ID
390
+ - `status` (A2A::Types::TaskStatus) - New status
391
+
392
+ **Returns:**
393
+ - `A2A::Types::Task` - Updated task
394
+
395
+ ##### get_task(task_id)
396
+
397
+ Retrieves a task.
398
+
399
+ **Parameters:**
400
+ - `task_id` (String) - Task ID
401
+
402
+ **Returns:**
403
+ - `A2A::Types::Task` - The task
404
+
405
+ **Raises:**
406
+ - `A2A::Errors::TaskNotFound` - If task doesn't exist
407
+
408
+ ## Types API
409
+
410
+ ### A2A::Types::Message
411
+
412
+ Represents an A2A message.
413
+
414
+ #### Constructor
415
+
416
+ ```ruby
417
+ message = A2A::Types::Message.new(
418
+ message_id: SecureRandom.uuid,
419
+ role: "user", # "user" or "agent"
420
+ parts: [part1, part2], # Array of Part objects
421
+ context_id: "context-123", # Optional
422
+ task_id: "task-123", # Optional
423
+ metadata: { key: "value" }, # Optional
424
+ extensions: [], # Optional
425
+ reference_task_ids: [] # Optional
426
+ )
427
+ ```
428
+
429
+ #### Properties
430
+
431
+ - `message_id` (String) - Unique message identifier
432
+ - `role` (String) - Message role ("user" or "agent")
433
+ - `parts` (Array<A2A::Types::Part>) - Message parts
434
+ - `context_id` (String, optional) - Context identifier
435
+ - `task_id` (String, optional) - Associated task ID
436
+ - `kind` (String) - Always "message"
437
+ - `metadata` (Hash, optional) - Additional metadata
438
+ - `extensions` (Array, optional) - Protocol extensions
439
+ - `reference_task_ids` (Array<String>, optional) - Referenced task IDs
440
+
441
+ ### A2A::Types::Part
442
+
443
+ Base class for message parts. Use specific subclasses:
444
+
445
+ #### A2A::Types::TextPart
446
+
447
+ ```ruby
448
+ text_part = A2A::Types::TextPart.new(
449
+ text: "Hello, world!",
450
+ metadata: { language: "en" } # Optional
451
+ )
452
+ ```
453
+
454
+ #### A2A::Types::FilePart
455
+
456
+ ```ruby
457
+ # File with bytes (base64 encoded)
458
+ file_part = A2A::Types::FilePart.new(
459
+ file: A2A::Types::FileWithBytes.new(
460
+ name: "document.pdf",
461
+ mime_type: "application/pdf",
462
+ bytes: Base64.encode64(file_content)
463
+ )
464
+ )
465
+
466
+ # File with URI reference
467
+ file_part = A2A::Types::FilePart.new(
468
+ file: A2A::Types::FileWithUri.new(
469
+ name: "document.pdf",
470
+ mime_type: "application/pdf",
471
+ uri: "https://storage.example.com/document.pdf"
472
+ )
473
+ )
474
+ ```
475
+
476
+ #### A2A::Types::DataPart
477
+
478
+ ```ruby
479
+ data_part = A2A::Types::DataPart.new(
480
+ data: { key: "value", numbers: [1, 2, 3] },
481
+ metadata: { format: "json" }
482
+ )
483
+ ```
484
+
485
+ ### A2A::Types::Task
486
+
487
+ Represents a task with lifecycle management.
488
+
489
+ #### Constructor
490
+
491
+ ```ruby
492
+ task = A2A::Types::Task.new(
493
+ id: SecureRandom.uuid,
494
+ context_id: SecureRandom.uuid,
495
+ status: A2A::Types::TaskStatus.new(state: "submitted"),
496
+ artifacts: [], # Optional
497
+ history: [], # Optional
498
+ metadata: {} # Optional
499
+ )
500
+ ```
501
+
502
+ #### Properties
503
+
504
+ - `id` (String) - Unique task identifier
505
+ - `context_id` (String) - Context identifier
506
+ - `status` (A2A::Types::TaskStatus) - Current task status
507
+ - `kind` (String) - Always "task"
508
+ - `artifacts` (Array<A2A::Types::Artifact>, optional) - Task artifacts
509
+ - `history` (Array<A2A::Types::Message>, optional) - Message history
510
+ - `metadata` (Hash, optional) - Additional metadata
511
+
512
+ ### A2A::Types::TaskStatus
513
+
514
+ Represents task status and progress.
515
+
516
+ #### Constructor
517
+
518
+ ```ruby
519
+ status = A2A::Types::TaskStatus.new(
520
+ state: "working", # Required
521
+ message: "Processing data...", # Optional
522
+ progress: 75, # Optional (0-100)
523
+ result: { processed: 1000 }, # Optional
524
+ error: { message: "Error occurred" }, # Optional
525
+ updated_at: Time.current.iso8601 # Optional
526
+ )
527
+ ```
528
+
529
+ #### Valid States
530
+
531
+ - `submitted` - Task created, waiting to start
532
+ - `working` - Task in progress
533
+ - `input-required` - Task needs user input
534
+ - `completed` - Task finished successfully
535
+ - `canceled` - Task was canceled
536
+ - `failed` - Task failed with error
537
+ - `rejected` - Task rejected (invalid params, etc.)
538
+ - `auth-required` - Task needs authentication
539
+ - `unknown` - Unknown state
540
+
541
+ ### A2A::Types::AgentCard
542
+
543
+ Represents agent capabilities and metadata.
544
+
545
+ #### Constructor
546
+
547
+ ```ruby
548
+ card = A2A::Types::AgentCard.new(
549
+ name: "Weather Agent",
550
+ description: "Provides weather information",
551
+ version: "1.0.0",
552
+ url: "https://agent.example.com/a2a",
553
+ preferred_transport: "JSONRPC",
554
+ skills: [skill1, skill2],
555
+ capabilities: capabilities,
556
+ default_input_modes: ["text"],
557
+ default_output_modes: ["text", "structured"],
558
+ additional_interfaces: [interface1], # Optional
559
+ security: security_config, # Optional
560
+ security_schemes: [scheme1], # Optional
561
+ provider: provider_info, # Optional
562
+ protocol_version: "0.3.0", # Optional
563
+ supports_authenticated_extended_card: true, # Optional
564
+ signatures: [signature1], # Optional
565
+ documentation_url: "https://docs.example.com", # Optional
566
+ icon_url: "https://example.com/icon.png" # Optional
567
+ )
568
+ ```
569
+
570
+ ## Configuration API
571
+
572
+ ### A2A.configure
573
+
574
+ Global configuration method.
575
+
576
+ ```ruby
577
+ A2A.configure do |config|
578
+ # Protocol configuration
579
+ config.protocol_version = "0.3.0"
580
+ config.default_transport = "JSONRPC"
581
+
582
+ # Feature flags
583
+ config.streaming_enabled = true
584
+ config.push_notifications_enabled = true
585
+
586
+ # Timeouts
587
+ config.default_timeout = 30
588
+ config.connect_timeout = 10
589
+
590
+ # Logging
591
+ config.log_level = :info
592
+ config.log_requests = false
593
+ config.log_responses = false
594
+
595
+ # Storage
596
+ config.storage_backend = :database # :memory, :redis, :database
597
+ config.database_url = ENV['DATABASE_URL']
598
+ config.redis_url = ENV['REDIS_URL']
599
+
600
+ # Security
601
+ config.force_ssl = true
602
+ config.ssl_verify = true
603
+
604
+ # Performance
605
+ config.enable_metrics = true
606
+ config.metrics_backend = :prometheus # :prometheus, :statsd
607
+
608
+ # Rate limiting
609
+ config.rate_limit_enabled = true
610
+ config.rate_limit_requests = 100
611
+ config.rate_limit_window = 60
612
+ end
613
+ ```
614
+
615
+ ## Transport API
616
+
617
+ ### A2A::Transport::Http
618
+
619
+ HTTP transport implementation using Faraday.
620
+
621
+ ```ruby
622
+ transport = A2A::Transport::Http.new(
623
+ endpoint_url: "https://agent.example.com/a2a",
624
+ timeout: 30,
625
+ ssl_verify: true
626
+ )
627
+
628
+ response = transport.send_request(json_rpc_request)
629
+ ```
630
+
631
+ ### A2A::Transport::SSE
632
+
633
+ Server-Sent Events transport for streaming.
634
+
635
+ ```ruby
636
+ sse = A2A::Transport::SSE.new(endpoint_url)
637
+
638
+ sse.stream(request) do |event|
639
+ case event.type
640
+ when 'message'
641
+ handle_message(JSON.parse(event.data))
642
+ when 'error'
643
+ handle_error(JSON.parse(event.data))
644
+ end
645
+ end
646
+ ```
647
+
648
+ ## Authentication API
649
+
650
+ ### A2A::Client::Auth::OAuth2
651
+
652
+ OAuth 2.0 client credentials flow.
653
+
654
+ ```ruby
655
+ auth = A2A::Client::Auth::OAuth2.new(
656
+ client_id: "your-client-id",
657
+ client_secret: "your-client-secret",
658
+ token_url: "https://auth.example.com/oauth/token",
659
+ scope: "a2a:read a2a:write" # Optional
660
+ )
661
+
662
+ # Manual token acquisition
663
+ token, expires_at = auth.get_token
664
+
665
+ # Automatic application to requests
666
+ client = A2A::Client::HttpClient.new(url, auth: auth)
667
+ ```
668
+
669
+ ### A2A::Client::Auth::JWT
670
+
671
+ JWT bearer token authentication.
672
+
673
+ ```ruby
674
+ auth = A2A::Client::Auth::JWT.new(
675
+ token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
676
+ header: "Authorization" # Optional, defaults to "Authorization"
677
+ )
678
+ ```
679
+
680
+ ### A2A::Client::Auth::ApiKey
681
+
682
+ API key authentication.
683
+
684
+ ```ruby
685
+ # Header-based API key
686
+ auth = A2A::Client::Auth::ApiKey.new(
687
+ key: "your-api-key",
688
+ header: "X-API-Key"
689
+ )
690
+
691
+ # Query parameter API key
692
+ auth = A2A::Client::Auth::ApiKey.new(
693
+ key: "your-api-key",
694
+ parameter: "api_key"
695
+ )
696
+ ```
697
+
698
+ ### Custom Authentication
699
+
700
+ ```ruby
701
+ class CustomAuth < A2A::Client::Auth::Base
702
+ def initialize(credentials)
703
+ @credentials = credentials
704
+ end
705
+
706
+ def apply_auth(request)
707
+ # Add custom authentication to request
708
+ request.headers['X-Custom-Auth'] = generate_signature(@credentials)
709
+ end
710
+
711
+ private
712
+
713
+ def generate_signature(credentials)
714
+ # Custom signature logic
715
+ end
716
+ end
717
+ ```
718
+
719
+ ## Error Handling
720
+
721
+ ### Exception Hierarchy
722
+
723
+ ```
724
+ A2A::Errors::A2AError
725
+ ├── A2A::Errors::ParseError (-32700)
726
+ ├── A2A::Errors::InvalidRequest (-32600)
727
+ ├── A2A::Errors::MethodNotFound (-32601)
728
+ ├── A2A::Errors::InvalidParams (-32602)
729
+ ├── A2A::Errors::InternalError (-32603)
730
+ ├── A2A::Errors::TaskNotFound (-32001)
731
+ ├── A2A::Errors::TaskNotCancelable (-32002)
732
+ ├── A2A::Errors::InvalidTaskState (-32003)
733
+ ├── A2A::Errors::AuthenticationRequired (-32004)
734
+ ├── A2A::Errors::InsufficientPermissions (-32005)
735
+ ├── A2A::Errors::RateLimitExceeded (-32006)
736
+ ├── A2A::Errors::InvalidAgentCard (-32007)
737
+ ├── A2A::Errors::TransportNotSupported (-32008)
738
+ ├── A2A::Errors::InvalidMessageFormat (-32009)
739
+ ├── A2A::Errors::ServiceUnavailable (-32010)
740
+ ├── A2A::Errors::ClientError
741
+ │ ├── A2A::Errors::HTTPError
742
+ │ ├── A2A::Errors::TimeoutError
743
+ │ └── A2A::Errors::AuthenticationError
744
+ └── A2A::Errors::ServerError
745
+ ```
746
+
747
+ ### Error Handling Patterns
748
+
749
+ ```ruby
750
+ begin
751
+ response = client.send_message(message)
752
+ rescue A2A::Errors::AuthenticationError => e
753
+ # Handle auth errors
754
+ refresh_credentials
755
+ retry
756
+ rescue A2A::Errors::TaskNotFound => e
757
+ # Handle missing task
758
+ logger.warn "Task not found: #{e.message}"
759
+ rescue A2A::Errors::RateLimitExceeded => e
760
+ # Handle rate limiting
761
+ sleep(e.retry_after || 60)
762
+ retry
763
+ rescue A2A::Errors::A2AError => e
764
+ # Handle all A2A protocol errors
765
+ logger.error "A2A Error #{e.code}: #{e.message}"
766
+ handle_protocol_error(e)
767
+ rescue StandardError => e
768
+ # Handle unexpected errors
769
+ logger.error "Unexpected error: #{e.message}"
770
+ raise
771
+ end
772
+ ```
773
+
774
+ ### Error Response Format
775
+
776
+ A2A errors include structured information:
777
+
778
+ ```ruby
779
+ begin
780
+ client.send_message(message)
781
+ rescue A2A::Errors::A2AError => e
782
+ puts "Error Code: #{e.code}"
783
+ puts "Message: #{e.message}"
784
+ puts "Data: #{e.data}" if e.data
785
+
786
+ # Convert to JSON-RPC error format
787
+ json_rpc_error = e.to_json_rpc_error
788
+ # => { code: -32001, message: "Task not found", data: {...} }
789
+ end
790
+ ```
791
+
792
+ For complete API documentation with examples, see the [YARD documentation](https://rubydoc.info/gems/a2a-ruby).