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
data/lib/a2a/errors.rb ADDED
@@ -0,0 +1,291 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # Exception classes for the A2A Ruby SDK
5
+ #
6
+ module A2A
7
+ module Errors
8
+ ##
9
+ # Base class for all A2A errors
10
+ #
11
+ class A2AError < StandardError
12
+ attr_reader :code, :data
13
+
14
+ def initialize(message = nil, code: nil, data: nil)
15
+ super(message)
16
+ @code = code
17
+ @data = data
18
+ end
19
+
20
+ # Convert to JSON-RPC error format
21
+ # @return [Hash]
22
+ def to_json_rpc_error
23
+ {
24
+ code: @code,
25
+ message: message,
26
+ data: @data
27
+ }.compact
28
+ end
29
+ end
30
+
31
+ ##
32
+ # Configuration-related errors
33
+ #
34
+ class ConfigurationError < A2AError; end
35
+
36
+ ##
37
+ # JSON-RPC 2.0 standard errors
38
+ #
39
+
40
+ # Parse error - Invalid JSON was received by the server
41
+ class ParseError < A2AError
42
+ def initialize(message = "Parse error", **options)
43
+ super(message, code: -32_700, **options)
44
+ end
45
+ end
46
+
47
+ # Invalid Request - The JSON sent is not a valid Request object
48
+ class InvalidRequest < A2AError
49
+ def initialize(message = "Invalid Request", **options)
50
+ super(message, code: -32_600, **options)
51
+ end
52
+ end
53
+
54
+ # Method not found - The method does not exist / is not available
55
+ class MethodNotFound < A2AError
56
+ def initialize(message = "Method not found", **options)
57
+ super(message, code: -32_601, **options)
58
+ end
59
+ end
60
+
61
+ # Invalid params - Invalid method parameter(s)
62
+ class InvalidParams < A2AError
63
+ def initialize(message = "Invalid params", **options)
64
+ super(message, code: -32_602, **options)
65
+ end
66
+ end
67
+
68
+ # Internal error - Internal JSON-RPC error
69
+ class InternalError < A2AError
70
+ def initialize(message = "Internal error", **options)
71
+ super(message, code: -32_603, **options)
72
+ end
73
+ end
74
+
75
+ ##
76
+ # A2A-specific errors (-32001 to -32010)
77
+ #
78
+
79
+ # Task not found
80
+ class TaskNotFound < A2AError
81
+ def initialize(message = "Task not found", **options)
82
+ super(message, code: -32_001, **options)
83
+ end
84
+ end
85
+
86
+ # Task cannot be canceled
87
+ class TaskNotCancelable < A2AError
88
+ def initialize(message = "Task cannot be canceled", **options)
89
+ super(message, code: -32_002, **options)
90
+ end
91
+ end
92
+
93
+ # Invalid task state
94
+ class InvalidTaskState < A2AError
95
+ def initialize(message = "Invalid task state", **options)
96
+ super(message, code: -32_003, **options)
97
+ end
98
+ end
99
+
100
+ # Authentication required
101
+ class AuthenticationRequired < A2AError
102
+ def initialize(message = "Authentication required", **options)
103
+ super(message, code: -32_004, **options)
104
+ end
105
+ end
106
+
107
+ # Authorization failed
108
+ class AuthorizationFailed < A2AError
109
+ def initialize(message = "Authorization failed", **options)
110
+ super(message, code: -32_005, **options)
111
+ end
112
+ end
113
+
114
+ # Rate limit exceeded
115
+ class RateLimitExceeded < A2AError
116
+ def initialize(message = "Rate limit exceeded", **options)
117
+ super(message, code: -32_006, **options)
118
+ end
119
+ end
120
+
121
+ # Agent unavailable
122
+ class AgentUnavailable < A2AError
123
+ def initialize(message = "Agent unavailable", **options)
124
+ super(message, code: -32_007, **options)
125
+ end
126
+ end
127
+
128
+ # Protocol version mismatch
129
+ class ProtocolVersionMismatch < A2AError
130
+ def initialize(message = "Protocol version mismatch", **options)
131
+ super(message, code: -32_008, **options)
132
+ end
133
+ end
134
+
135
+ # Capability not supported
136
+ class CapabilityNotSupported < A2AError
137
+ def initialize(message = "Capability not supported", **options)
138
+ super(message, code: -32_009, **options)
139
+ end
140
+ end
141
+
142
+ # Resource exhausted
143
+ class ResourceExhausted < A2AError
144
+ def initialize(message = "Resource exhausted", **options)
145
+ super(message, code: -32_010, **options)
146
+ end
147
+ end
148
+
149
+ # Unsupported operation
150
+ class UnsupportedOperation < A2AError
151
+ def initialize(message = "Operation not supported", **options)
152
+ super(message, code: -32_011, **options)
153
+ end
154
+ end
155
+
156
+ # Not found (generic)
157
+ class NotFound < A2AError
158
+ def initialize(message = "Not found", **options)
159
+ super(message, code: -32_404, **options)
160
+ end
161
+ end
162
+
163
+ ##
164
+ # Client-side errors
165
+ #
166
+
167
+ # Base client error
168
+ class ClientError < A2AError; end
169
+
170
+ # HTTP-related errors
171
+ class HTTPError < ClientError
172
+ attr_reader :status_code, :response_body
173
+
174
+ def initialize(message, status_code: nil, response_body: nil, **options)
175
+ super(message, **options)
176
+ @status_code = status_code
177
+ @response_body = response_body
178
+ end
179
+ end
180
+
181
+ # Timeout errors
182
+ class TimeoutError < ClientError; end
183
+
184
+ # Authentication errors
185
+ class AuthenticationError < ClientError; end
186
+
187
+ # JSON parsing errors
188
+ class JSONError < ClientError; end
189
+
190
+ # Transport errors
191
+ class TransportError < ClientError; end
192
+
193
+ # Server-side errors
194
+ class ServerError < A2AError
195
+ attr_reader :error
196
+
197
+ def initialize(error = nil, message: nil)
198
+ @error = error
199
+ super(message || error&.message || "Server error")
200
+ end
201
+ end
202
+
203
+ ##
204
+ # Utility methods for error handling
205
+ #
206
+ module ErrorUtils
207
+ ##
208
+ # Convert an exception to a JSON-RPC error response
209
+ #
210
+ # @param exception [Exception] The exception to convert
211
+ # @param request_id [String, Integer, nil] The request ID
212
+ # @return [Hash] JSON-RPC error response
213
+ def self.exception_to_json_rpc_error(exception, request_id: nil)
214
+ if exception.is_a?(A2AError)
215
+ A2A::Protocol::JsonRpc.build_error_response(
216
+ code: exception.code,
217
+ message: exception.message,
218
+ data: exception.data,
219
+ id: request_id
220
+ )
221
+ else
222
+ # Map standard Ruby exceptions to JSON-RPC errors
223
+ case exception
224
+ when ArgumentError
225
+ A2A::Protocol::JsonRpc.build_error_response(
226
+ code: A2A::Protocol::JsonRpc::INVALID_PARAMS,
227
+ message: exception.message,
228
+ id: request_id
229
+ )
230
+ when NoMethodError
231
+ A2A::Protocol::JsonRpc.build_error_response(
232
+ code: A2A::Protocol::JsonRpc::METHOD_NOT_FOUND,
233
+ message: "Method not found",
234
+ id: request_id
235
+ )
236
+ else
237
+ A2A::Protocol::JsonRpc.build_error_response(
238
+ code: A2A::Protocol::JsonRpc::INTERNAL_ERROR,
239
+ message: exception.message,
240
+ id: request_id
241
+ )
242
+ end
243
+ end
244
+ end
245
+
246
+ ##
247
+ # Create an A2A error from a JSON-RPC error code
248
+ #
249
+ # @param code [Integer] The error code
250
+ # @param message [String] The error message
251
+ # @param data [Object, nil] Additional error data
252
+ # @return [A2AError] The appropriate error instance
253
+ def self.from_json_rpc_code(code, message, data: nil)
254
+ case code
255
+ when A2A::Protocol::JsonRpc::PARSE_ERROR
256
+ ParseError.new(message, data: data)
257
+ when A2A::Protocol::JsonRpc::INVALID_REQUEST
258
+ InvalidRequest.new(message, data: data)
259
+ when A2A::Protocol::JsonRpc::METHOD_NOT_FOUND
260
+ MethodNotFound.new(message, data: data)
261
+ when A2A::Protocol::JsonRpc::INVALID_PARAMS
262
+ InvalidParams.new(message, data: data)
263
+ when A2A::Protocol::JsonRpc::INTERNAL_ERROR
264
+ InternalError.new(message, data: data)
265
+ when A2A::Protocol::JsonRpc::TASK_NOT_FOUND
266
+ TaskNotFound.new(message, data: data)
267
+ when A2A::Protocol::JsonRpc::TASK_NOT_CANCELABLE
268
+ TaskNotCancelable.new(message, data: data)
269
+ when A2A::Protocol::JsonRpc::INVALID_TASK_STATE
270
+ InvalidTaskState.new(message, data: data)
271
+ when A2A::Protocol::JsonRpc::AUTHENTICATION_REQUIRED
272
+ AuthenticationRequired.new(message, data: data)
273
+ when A2A::Protocol::JsonRpc::AUTHORIZATION_FAILED
274
+ AuthorizationFailed.new(message, data: data)
275
+ when A2A::Protocol::JsonRpc::RATE_LIMIT_EXCEEDED
276
+ RateLimitExceeded.new(message, data: data)
277
+ when A2A::Protocol::JsonRpc::AGENT_UNAVAILABLE
278
+ AgentUnavailable.new(message, data: data)
279
+ when A2A::Protocol::JsonRpc::PROTOCOL_VERSION_MISMATCH
280
+ ProtocolVersionMismatch.new(message, data: data)
281
+ when A2A::Protocol::JsonRpc::CAPABILITY_NOT_SUPPORTED
282
+ CapabilityNotSupported.new(message, data: data)
283
+ when A2A::Protocol::JsonRpc::RESOURCE_EXHAUSTED
284
+ ResourceExhausted.new(message, data: data)
285
+ else
286
+ A2AError.new(message, code: code, data: data)
287
+ end
288
+ end
289
+ end
290
+ end
291
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # Module definitions for A2A SDK
5
+ #
6
+ # This file defines all the necessary module namespaces to prevent
7
+ # "uninitialized constant" errors when classes are defined before
8
+ # their parent modules.
9
+ #
10
+
11
+ module A2A
12
+ module Types
13
+ end
14
+
15
+ module Server
16
+ module Middleware
17
+ end
18
+
19
+ module Storage
20
+ end
21
+ end
22
+
23
+ module Client
24
+ module Auth
25
+ end
26
+
27
+ module Middleware
28
+ end
29
+ end
30
+
31
+ module Transport
32
+ end
33
+
34
+ module Monitoring
35
+ end
36
+
37
+ module Rails
38
+ module Generators
39
+ end
40
+ end
41
+
42
+ module Utils
43
+ end
44
+
45
+ module Plugins
46
+ end
47
+
48
+ module Errors
49
+ end
50
+ end