a2a 0.1.0.pre → 0.1.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +25 -4
- data/.tool-versions +1 -1
- data/CHANGELOG.md +19 -2
- data/Guardfile +1 -1
- data/README.md +49 -4
- data/lib/a2a/extensions/additional_properties.rb +121 -0
- data/lib/a2a/extensions/case_transformation.rb +46 -0
- data/lib/a2a/extensions/json_deserialization.rb +53 -0
- data/lib/a2a/types/agent_authentication.rb +13 -0
- data/lib/a2a/types/agent_capabilities.rb +15 -0
- data/lib/a2a/types/agent_card.rb +39 -0
- data/lib/a2a/types/agent_provider.rb +12 -0
- data/lib/a2a/types/agent_skill.rb +27 -0
- data/lib/a2a/types/artifact.rb +29 -0
- data/lib/a2a/types/authentication_info.rb +9 -0
- data/lib/a2a/types/cancel_task_request.rb +15 -0
- data/lib/a2a/types/cancel_task_response.rb +12 -0
- data/lib/a2a/types/data_part.rb +15 -0
- data/lib/a2a/types/error_codes.rb +26 -0
- data/lib/a2a/types/file_content.rb +18 -0
- data/lib/a2a/types/file_part.rb +15 -0
- data/lib/a2a/types/get_task_push_notification_request.rb +15 -0
- data/lib/a2a/types/get_task_push_notification_response.rb +12 -0
- data/lib/a2a/types/get_task_request.rb +15 -0
- data/lib/a2a/types/get_task_response.rb +12 -0
- data/lib/a2a/types/internal_error.rb +15 -0
- data/lib/a2a/types/invalid_params_error.rb +15 -0
- data/lib/a2a/types/invalid_request_error.rb +15 -0
- data/lib/a2a/types/json_parse_error.rb +15 -0
- data/lib/a2a/types/jsonrpc_error.rb +15 -0
- data/lib/a2a/types/jsonrpc_message.rb +12 -0
- data/lib/a2a/types/jsonrpc_request.rb +15 -0
- data/lib/a2a/types/jsonrpc_response.rb +12 -0
- data/lib/a2a/types/message.rb +15 -0
- data/lib/a2a/types/method_not_found_error.rb +15 -0
- data/lib/a2a/types/part.rb +6 -0
- data/lib/a2a/types/protocol_struct.rb +12 -0
- data/lib/a2a/types/push_notification_config.rb +15 -0
- data/lib/a2a/types/push_notification_not_supported_error.rb +15 -0
- data/lib/a2a/types/send_task_request.rb +15 -0
- data/lib/a2a/types/send_task_response.rb +13 -0
- data/lib/a2a/types/send_task_streaming_request.rb +15 -0
- data/lib/a2a/types/send_task_streaming_response.rb +15 -0
- data/lib/a2a/types/set_task_push_notification_request.rb +15 -0
- data/lib/a2a/types/set_task_push_notification_response.rb +12 -0
- data/lib/a2a/types/task.rb +25 -0
- data/lib/a2a/types/task_artifact_update_event.rb +18 -0
- data/lib/a2a/types/task_id_params.rb +12 -0
- data/lib/a2a/types/task_not_cancelable_error.rb +15 -0
- data/lib/a2a/types/task_not_found_error.rb +15 -0
- data/lib/a2a/types/task_push_notification_config.rb +12 -0
- data/lib/a2a/types/task_query_params.rb +9 -0
- data/lib/a2a/types/task_resubscription_request.rb +15 -0
- data/lib/a2a/types/task_send_params.rb +26 -0
- data/lib/a2a/types/task_state.rb +6 -0
- data/lib/a2a/types/task_status.rb +15 -0
- data/lib/a2a/types/task_status_update_event.rb +18 -0
- data/lib/a2a/types/text_part.rb +15 -0
- data/lib/a2a/types/unsupported_operation_error.rb +15 -0
- data/lib/a2a/types.rb +12 -0
- data/lib/a2a/version.rb +1 -1
- data/lib/a2a.rb +20 -1
- metadata +66 -319
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a735724d190d582f29a71d683d2e9c0eff95ff3ec90dd77e29ef3f091e7c8338
|
|
4
|
+
data.tar.gz: 7af91cf7fe7e0a112654a016955139672a47f3e55fe2bbfe4a66019a7b82dda1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7569e210cb5c08ec6c18dc612a8690472ce117b7aaac15ded258a314dc33cc82b0cf845d0a4d1be3a0cc3cdc36872f478db6f0955ed3c34e3b45e85886a0c31d
|
|
7
|
+
data.tar.gz: ccb3d85eccdc0934d52b76f2b4b7bcbc598e16a3fbc8d4e1c24c67600708923e5b25bfdf75776bab7217703aa772424ace4a0f2865952fe2a2f112df71425e6a
|
data/.rubocop.yml
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
plugins:
|
|
2
|
+
- rubocop-factory_bot
|
|
2
3
|
- rubocop-performance
|
|
3
4
|
- rubocop-rake
|
|
4
5
|
- rubocop-rspec
|
|
@@ -15,6 +16,10 @@ Gemspec/DevelopmentDependencies:
|
|
|
15
16
|
|
|
16
17
|
# ----------------------- Style -----------------------
|
|
17
18
|
|
|
19
|
+
Style/MixinUsage:
|
|
20
|
+
Exclude:
|
|
21
|
+
- bin/console
|
|
22
|
+
|
|
18
23
|
Style/StringLiterals:
|
|
19
24
|
Enabled: true
|
|
20
25
|
EnforcedStyle: single_quotes
|
|
@@ -28,23 +33,39 @@ Style/StringLiteralsInInterpolation:
|
|
|
28
33
|
Layout/LineLength:
|
|
29
34
|
Max: 120
|
|
30
35
|
Exclude:
|
|
31
|
-
-
|
|
36
|
+
- a2a.gemspec
|
|
32
37
|
|
|
33
38
|
# ---------------------- Metrics ----------------------
|
|
34
39
|
|
|
40
|
+
Metrics/AbcSize:
|
|
41
|
+
Enabled: false
|
|
42
|
+
|
|
35
43
|
Metrics/BlockLength:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
Enabled: false
|
|
45
|
+
|
|
46
|
+
Metrics/CyclomaticComplexity:
|
|
47
|
+
Enabled: false
|
|
48
|
+
|
|
49
|
+
Metrics/ClassLength:
|
|
50
|
+
Enabled: false
|
|
51
|
+
|
|
52
|
+
Metrics/MethodLength:
|
|
53
|
+
Enabled: false
|
|
39
54
|
|
|
40
55
|
Metrics/ParameterLists:
|
|
41
56
|
CountKeywordArgs: false
|
|
42
57
|
|
|
58
|
+
Metrics/PerceivedComplexity:
|
|
59
|
+
Enabled: false
|
|
60
|
+
|
|
43
61
|
# ----------------------- RSpec -----------------------
|
|
44
62
|
|
|
45
63
|
RSpec/ExampleLength:
|
|
46
64
|
Enabled: false
|
|
47
65
|
|
|
66
|
+
RSpec/MultipleExpectations:
|
|
67
|
+
Enabled: false
|
|
68
|
+
|
|
48
69
|
# RuboCop does not like the gem's name.
|
|
49
70
|
RSpec/SpecFilePathFormat:
|
|
50
71
|
Enabled: false
|
data/.tool-versions
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ruby 3.4.
|
|
1
|
+
ruby 3.4.3
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.1.1/)
|
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2025-05-03
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Protocol data structures defined according to the Agent2Agent specification
|
|
12
|
+
- Serialization and deserialization of protocol messages
|
|
13
|
+
- Typed data structures with validation
|
|
14
|
+
- Case transformation support (snake_case ↔ camelCase) during instantiation and serialization
|
|
15
|
+
- Flexible schema with support for additional properties beyond defined attributes
|
|
16
|
+
|
|
17
|
+
## [0.1.0.pre] - 2025-04-08
|
|
4
18
|
|
|
5
19
|
- Pre-release
|
|
20
|
+
|
|
21
|
+
[0.1.0]: https://github.com/wilsonsilva/a2a/compare/v0.1.0.pre...0.1.0
|
|
22
|
+
[0.1.0.pre]: https://github.com/wilsonsilva/a2a/compare/a20b9b6...v0.1.0.pre
|
data/Guardfile
CHANGED
data/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/a2a)
|
|
4
4
|

|
|
5
|
-
[](https://qlty.sh/gh/wilsonsilva/projects/a2a)
|
|
6
|
+
[](https://qlty.sh/gh/wilsonsilva/projects/a2a)
|
|
7
7
|
|
|
8
8
|
An open protocol enabling communication and interoperability between opaque agentic applications.
|
|
9
9
|
|
|
@@ -21,7 +21,11 @@ An open protocol enabling communication and interoperability between opaque agen
|
|
|
21
21
|
|
|
22
22
|
## 🔑 Key features
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
- Protocol data structures defined according to the Agent2Agent specification
|
|
25
|
+
- Serialization and deserialization of protocol messages
|
|
26
|
+
- Typed data structures with validation
|
|
27
|
+
- Case transformation support (snake_case ↔ camelCase) during instantiation and serialization
|
|
28
|
+
- Flexible schema with support for additional properties beyond defined attributes
|
|
25
29
|
|
|
26
30
|
## 📦 Installation
|
|
27
31
|
|
|
@@ -31,7 +35,48 @@ Install the gem by executing:
|
|
|
31
35
|
|
|
32
36
|
## ⚡️ Quickstart
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
```ruby
|
|
39
|
+
require 'a2a'
|
|
40
|
+
|
|
41
|
+
# Create a task send parameters object
|
|
42
|
+
task_params = A2A::TaskSendParams.new(
|
|
43
|
+
id: 'task-123',
|
|
44
|
+
session_id: 'session-456',
|
|
45
|
+
message: {
|
|
46
|
+
content: 'Plan a trip to Paris',
|
|
47
|
+
role: 'user'
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Build a JSON-RPC request object (no actual network request is made)
|
|
52
|
+
request = A2A::SendTaskRequest.new(
|
|
53
|
+
id: 1,
|
|
54
|
+
params: task_params
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Convert to JSON with camelCase formatting (as per protocol spec)
|
|
58
|
+
json_request = request.to_json
|
|
59
|
+
puts json_request
|
|
60
|
+
# => {"jsonrpc":"2.0","id":1,"method":"tasks/send","params":{"id":"task-123","sessionId":"session-456","message":{"content":"Plan a trip to Paris","role":"user"}}}
|
|
61
|
+
|
|
62
|
+
# Parse a JSON response string
|
|
63
|
+
agent_response = '{"jsonrpc":"2.0","id":1,"result":{"id":"task-123","status":"success","history":[{"role":"user","content":"Plan a trip to Paris"}]}}'
|
|
64
|
+
|
|
65
|
+
# Method 1: Parse the JSON first, then create the object
|
|
66
|
+
response_data = JSON.parse(agent_response)
|
|
67
|
+
response = A2A::SendTaskResponse.new(response_data)
|
|
68
|
+
|
|
69
|
+
# Method 2: Directly create the object from JSON (using the new from_json method)
|
|
70
|
+
response = A2A::SendTaskResponse.from_json(agent_response)
|
|
71
|
+
|
|
72
|
+
# Access the task information
|
|
73
|
+
if response.result
|
|
74
|
+
puts "Task status: #{response.result.status}"
|
|
75
|
+
puts "Messages: #{response.result.history&.length || 0}"
|
|
76
|
+
else
|
|
77
|
+
puts "Error: #{response.error&.message}"
|
|
78
|
+
end
|
|
79
|
+
```
|
|
35
80
|
|
|
36
81
|
## 📚 Documentation
|
|
37
82
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
module Extensions
|
|
5
|
+
# Allows a dry-struct to have additional properties beyond the defined schema.
|
|
6
|
+
# Limitations: the +attributes+ method does not return additional properties.
|
|
7
|
+
module AdditionalProperties
|
|
8
|
+
# @!visibility private
|
|
9
|
+
# @return [Hash] Storage for additional properties not defined in the schema
|
|
10
|
+
attr_reader :additional_properties
|
|
11
|
+
|
|
12
|
+
# @!visibility private
|
|
13
|
+
def self.included(base)
|
|
14
|
+
base.extend(ClassMethods)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Initialize with empty additional properties
|
|
18
|
+
def initialize(*)
|
|
19
|
+
super
|
|
20
|
+
@additional_properties ||= {}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Access additional properties via method_missing
|
|
24
|
+
#
|
|
25
|
+
# @param method_name [Symbol] Method name corresponding to property
|
|
26
|
+
# @param args [Array] Method arguments (unused)
|
|
27
|
+
#
|
|
28
|
+
# @return [Object, nil] Property value if found
|
|
29
|
+
#
|
|
30
|
+
def method_missing(method_name, *args)
|
|
31
|
+
if additional_properties.key?(method_name)
|
|
32
|
+
additional_properties[method_name]
|
|
33
|
+
else
|
|
34
|
+
super
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Indicate whether the object responds to the given method
|
|
39
|
+
#
|
|
40
|
+
# @param method_name [Symbol] Method name
|
|
41
|
+
# @param include_private [Boolean] Whether to include private methods
|
|
42
|
+
#
|
|
43
|
+
# @return [Boolean] Whether the object responds to the method
|
|
44
|
+
#
|
|
45
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
46
|
+
additional_properties.key?(method_name) || super
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Convert the struct to a hash, including additional properties
|
|
50
|
+
#
|
|
51
|
+
# @return [Hash] All properties as a hash
|
|
52
|
+
#
|
|
53
|
+
def to_h
|
|
54
|
+
super.merge(additional_properties)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Override the camelize method to handle additional properties correctly
|
|
58
|
+
#
|
|
59
|
+
# @param value [Object] The value to convert
|
|
60
|
+
#
|
|
61
|
+
# @return [Object] The value with camelized keys if applicable
|
|
62
|
+
#
|
|
63
|
+
def camelize(value)
|
|
64
|
+
case value
|
|
65
|
+
when Hash
|
|
66
|
+
value.to_h do |key, v|
|
|
67
|
+
[INFLECTOR.camelize_lower(key.to_s).to_sym, camelize(v)]
|
|
68
|
+
end
|
|
69
|
+
when Array
|
|
70
|
+
value.map { |item| camelize(item) }
|
|
71
|
+
else
|
|
72
|
+
value
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Class methods added to the class that includes AdditionalProperties
|
|
77
|
+
module ClassMethods
|
|
78
|
+
# Override the new method to handle additional properties
|
|
79
|
+
#
|
|
80
|
+
# @param hash [Hash, nil] Input hash including both schema and additional properties
|
|
81
|
+
#
|
|
82
|
+
# @return [Object] New instance with additional properties preserved
|
|
83
|
+
#
|
|
84
|
+
def new(hash = nil)
|
|
85
|
+
hash = {} if hash.nil?
|
|
86
|
+
|
|
87
|
+
# Convert all keys to symbols
|
|
88
|
+
input = hash.transform_keys(&:to_sym)
|
|
89
|
+
|
|
90
|
+
# Get schema keys
|
|
91
|
+
schema_keys = schema.keys.map(&:name)
|
|
92
|
+
|
|
93
|
+
# Split input into schema data and additional properties
|
|
94
|
+
schema_data = {}
|
|
95
|
+
additional_props = {}
|
|
96
|
+
|
|
97
|
+
input.each do |key, value|
|
|
98
|
+
snake_key = INFLECTOR.underscore(key.to_s).to_sym
|
|
99
|
+
|
|
100
|
+
if schema_keys.include?(snake_key)
|
|
101
|
+
schema_data[snake_key] = value
|
|
102
|
+
elsif schema_keys.include?(key)
|
|
103
|
+
schema_data[key] = value
|
|
104
|
+
else
|
|
105
|
+
# Store additional properties with snake_case keys
|
|
106
|
+
additional_props[snake_key] = value
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Create instance using schema data
|
|
111
|
+
instance = super(schema_data)
|
|
112
|
+
|
|
113
|
+
# Attach additional properties
|
|
114
|
+
instance.instance_variable_set(:@additional_properties, additional_props)
|
|
115
|
+
|
|
116
|
+
instance
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
module Extensions
|
|
5
|
+
# Allows a dry-struct to be instantiated and serialized with camelCase keys.
|
|
6
|
+
module CaseTransformation
|
|
7
|
+
def self.included(base)
|
|
8
|
+
base.class_eval do
|
|
9
|
+
# Transform keys to snake_case symbols when initializing the struct
|
|
10
|
+
transform_keys { |key| INFLECTOR.underscore(key.to_s).to_sym }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Converts hash keys from snake_case to camelCase recursively
|
|
15
|
+
#
|
|
16
|
+
# @param value [Object] The value to convert
|
|
17
|
+
#
|
|
18
|
+
# @return [Object] The value with camelized keys if applicable
|
|
19
|
+
#
|
|
20
|
+
def camelize(value)
|
|
21
|
+
case value
|
|
22
|
+
when Array
|
|
23
|
+
value.map { |item| camelize(item) }
|
|
24
|
+
when Hash
|
|
25
|
+
value.to_h do |key, v|
|
|
26
|
+
[INFLECTOR.camelize_lower(key.to_s).to_sym, camelize(v)]
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
value
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Serializes the object to JSON with an option for camelCase formatting
|
|
34
|
+
#
|
|
35
|
+
# @param camel_case [Boolean] Whether to convert keys to camelCase
|
|
36
|
+
#
|
|
37
|
+
# @return [String] JSON representation of the object
|
|
38
|
+
#
|
|
39
|
+
def to_json(camel_case: true, **)
|
|
40
|
+
data = to_h
|
|
41
|
+
data = camelize(data) if camel_case
|
|
42
|
+
data.to_json(**)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module A2A
|
|
6
|
+
module Extensions
|
|
7
|
+
# Provides JSON deserialization capabilities to a class
|
|
8
|
+
module JSONDeserialization
|
|
9
|
+
# @!visibility private
|
|
10
|
+
def self.included(base)
|
|
11
|
+
base.extend(ClassMethods)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Class methods added to the class that includes JsonDeserialization
|
|
15
|
+
module ClassMethods
|
|
16
|
+
# Creates a new instance from a JSON string
|
|
17
|
+
#
|
|
18
|
+
# @param json [String] JSON string to parse
|
|
19
|
+
# @return [ProtocolStruct] A new instance of the appropriate class
|
|
20
|
+
#
|
|
21
|
+
# @example Create a Google Maps Agent Card from JSON
|
|
22
|
+
# json_string = <<~JSON
|
|
23
|
+
# {
|
|
24
|
+
# "name": "Google Maps Agent",
|
|
25
|
+
# "description": "Plan routes, remember places, and generate directions",
|
|
26
|
+
# "url": "https://maps-agent.google.com",
|
|
27
|
+
# "provider": {
|
|
28
|
+
# "organization": "Google",
|
|
29
|
+
# "url": "https://google.com"
|
|
30
|
+
# },
|
|
31
|
+
# "version": "1.0.0",
|
|
32
|
+
# "capabilities": {
|
|
33
|
+
# "streaming": true,
|
|
34
|
+
# "pushNotifications": false
|
|
35
|
+
# },
|
|
36
|
+
# "skills": [
|
|
37
|
+
# {
|
|
38
|
+
# "id": "route-planner",
|
|
39
|
+
# "name": "Route planning",
|
|
40
|
+
# "description": "Helps plan routing between two locations"
|
|
41
|
+
# }
|
|
42
|
+
# ]
|
|
43
|
+
# }
|
|
44
|
+
# JSON
|
|
45
|
+
# agent_card = A2A::AgentCard.from_json(json_string)
|
|
46
|
+
#
|
|
47
|
+
def from_json(json)
|
|
48
|
+
new(JSON.parse(json))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Defines the authentication schemes and credentials for an agent.
|
|
5
|
+
class AgentAuthentication < ProtocolStruct
|
|
6
|
+
# @return [Array<String>] List of supported authentication schemes.
|
|
7
|
+
attribute :schemes, Types::Array.of(Types::String)
|
|
8
|
+
|
|
9
|
+
# @return [String, nil] Credentials for authentication. Can be a string (e.g., token) or null if not
|
|
10
|
+
# required initially.
|
|
11
|
+
attribute? :credentials, Types::String.optional
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Describes the capabilities of an agent.
|
|
5
|
+
class AgentCapabilities < ProtocolStruct
|
|
6
|
+
# @return [Boolean] Indicates if the agent supports streaming responses.
|
|
7
|
+
attribute? :streaming, Types::Bool.default(false)
|
|
8
|
+
|
|
9
|
+
# @return [Boolean] Indicates if the agent supports push notification mechanisms.
|
|
10
|
+
attribute? :push_notifications, Types::Bool.default(false)
|
|
11
|
+
|
|
12
|
+
# @return [Boolean] Indicates if the agent supports providing state transition history.
|
|
13
|
+
attribute? :state_transition_history, Types::Bool.default(false)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Represents the metadata card for an agent, describing its properties and capabilities.
|
|
5
|
+
class AgentCard < ProtocolStruct
|
|
6
|
+
# @return [String] The name of the agent.
|
|
7
|
+
attribute :name, Types::String
|
|
8
|
+
|
|
9
|
+
# @return [String, nil] An optional description of the agent.
|
|
10
|
+
attribute? :description, Types::String.optional
|
|
11
|
+
|
|
12
|
+
# @return [String] The base URL endpoint for interacting with the agent.
|
|
13
|
+
attribute :url, Types::String
|
|
14
|
+
|
|
15
|
+
# @return [AgentProvider, nil] Information about the provider of the agent.
|
|
16
|
+
attribute? :provider, Types::Constructor(AgentProvider).optional
|
|
17
|
+
|
|
18
|
+
# @return [String] The version identifier for the agent or its API.
|
|
19
|
+
attribute :version, Types::String
|
|
20
|
+
|
|
21
|
+
# @return [String, nil] An optional URL pointing to the agent's documentation.
|
|
22
|
+
attribute? :documentation_url, Types::String.optional
|
|
23
|
+
|
|
24
|
+
# @return [AgentCapabilities] The capabilities supported by the agent.
|
|
25
|
+
attribute :capabilities, Types::Constructor(AgentCapabilities)
|
|
26
|
+
|
|
27
|
+
# @return [AgentAuthentication, nil] Authentication details required to interact with the agent.
|
|
28
|
+
attribute? :authentication, Types::Constructor(AgentAuthentication).optional
|
|
29
|
+
|
|
30
|
+
# @return [Array<String>] Default input modes supported by the agent (e.g., 'text', 'file', 'json').
|
|
31
|
+
attribute? :default_input_modes, Types::Array.of(Types::String).default(['text'].freeze)
|
|
32
|
+
|
|
33
|
+
# @return [Array<String>] Default output modes supported by the agent (e.g., 'text', 'file', 'json').
|
|
34
|
+
attribute? :default_output_modes, Types::Array.of(Types::String).default(['text'].freeze)
|
|
35
|
+
|
|
36
|
+
# @return [Array<AgentSkill>] List of specific skills offered by the agent.
|
|
37
|
+
attribute :skills, Types::Array.of(Types::Constructor(AgentSkill))
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Represents the provider or organization behind an agent.
|
|
5
|
+
class AgentProvider < ProtocolStruct
|
|
6
|
+
# @return [String] The name of the organization providing the agent.
|
|
7
|
+
attribute :organization, Types::String
|
|
8
|
+
|
|
9
|
+
# @return [String, nil] URL associated with the agent provider.
|
|
10
|
+
attribute? :url, Types::String.optional
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Defines a specific skill or capability offered by an agent.
|
|
5
|
+
class AgentSkill < ProtocolStruct
|
|
6
|
+
# @return [String] Unique identifier for the skill.
|
|
7
|
+
attribute :id, Types::String
|
|
8
|
+
|
|
9
|
+
# @return [String] Human-readable name of the skill.
|
|
10
|
+
attribute :name, Types::String
|
|
11
|
+
|
|
12
|
+
# @return [String, nil] Optional description of the skill.
|
|
13
|
+
attribute? :description, Types::String.optional
|
|
14
|
+
|
|
15
|
+
# @return [Array<String>, nil] Optional list of tags associated with the skill for categorization.
|
|
16
|
+
attribute? :tags, Types::Array.of(Types::String).optional
|
|
17
|
+
|
|
18
|
+
# @return [Array<String>, nil] Optional list of example inputs or use cases for the skill.
|
|
19
|
+
attribute? :examples, Types::Array.of(Types::String).optional
|
|
20
|
+
|
|
21
|
+
# @return [Array<String>, nil] Optional list of input modes supported by this skill, overriding agent defaults.
|
|
22
|
+
attribute? :input_modes, Types::Array.of(Types::String).optional
|
|
23
|
+
|
|
24
|
+
# @return [Array<String>, nil] Optional list of output modes supported by this skill, overriding agent defaults.
|
|
25
|
+
attribute? :output_modes, Types::Array.of(Types::String).optional
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Represents an artifact generated or used by a task, potentially composed of multiple parts.
|
|
5
|
+
class Artifact < ProtocolStruct
|
|
6
|
+
# @return [String, nil] Optional name for the artifact.
|
|
7
|
+
attribute? :name, Types::String.optional
|
|
8
|
+
|
|
9
|
+
# @return [String, nil] Optional description of the artifact.
|
|
10
|
+
attribute? :description, Types::String.optional
|
|
11
|
+
|
|
12
|
+
# @return [Array<Part>] The constituent parts of the artifact.
|
|
13
|
+
attribute :parts, Types::Array.of(Types::Constructor(Part))
|
|
14
|
+
|
|
15
|
+
# @return [Integer, nil] Optional index for ordering artifacts, especially relevant in streaming or updates.
|
|
16
|
+
attribute? :index, Types::Integer.default(0)
|
|
17
|
+
|
|
18
|
+
# @return [Boolean, nil] Optional flag indicating if this artifact content should append to previous
|
|
19
|
+
# content (for streaming).
|
|
20
|
+
attribute? :append, Types::Bool.optional
|
|
21
|
+
|
|
22
|
+
# @return [Hash, nil] Optional metadata associated with the artifact.
|
|
23
|
+
attribute? :metadata, Types::Hash.optional
|
|
24
|
+
|
|
25
|
+
# @return [Boolean, nil] Optional flag indicating if this is the last chunk of data for this
|
|
26
|
+
# artifact (for streaming).
|
|
27
|
+
attribute? :last_chunk, Types::Bool.optional
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Authentication information, potentially including additional properties beyond the standard ones.
|
|
5
|
+
# (Note: Schema allows additional properties).
|
|
6
|
+
class AuthenticationInfo < AgentAuthentication
|
|
7
|
+
include Extensions::AdditionalProperties
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Request to cancel a currently running task.
|
|
5
|
+
class CancelTaskRequest < JSONRPCRequest
|
|
6
|
+
# @return [String] Method name for canceling a task.
|
|
7
|
+
attribute :method, Types::String.constant('tasks/cancel')
|
|
8
|
+
|
|
9
|
+
# @return [TaskIdParams] Parameters for the cancel task method.
|
|
10
|
+
attribute :params, Types::Constructor(TaskIdParams)
|
|
11
|
+
|
|
12
|
+
# @return [String] Method name for canceling a task.
|
|
13
|
+
def method = attributes[:method]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Response to a `tasks/cancel` request. Contains the updated Task object or an error.
|
|
5
|
+
class CancelTaskResponse < JSONRPCResponse
|
|
6
|
+
# @return [Task, nil] The canceled task information if successful.
|
|
7
|
+
attribute? :result, Types::Constructor(Task).optional
|
|
8
|
+
|
|
9
|
+
# @return [JSONRPCError, nil] Error information if the request failed.
|
|
10
|
+
attribute? :error, Types::Constructor(JSONRPCError).optional
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Represents a part of a message containing structured data (JSON).
|
|
5
|
+
class DataPart < ProtocolStruct
|
|
6
|
+
# @return [String] Type identifier for this part.
|
|
7
|
+
attribute :type, Types::String.constant('data')
|
|
8
|
+
|
|
9
|
+
# @return [Hash] The structured data content as a JSON object.
|
|
10
|
+
attribute :data, Types::Hash
|
|
11
|
+
|
|
12
|
+
# @return [Hash, nil] Optional metadata associated with this data part.
|
|
13
|
+
attribute? :metadata, Types::Hash.optional
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Standard JSON-RPC error codes
|
|
5
|
+
module ErrorCodes
|
|
6
|
+
# Invalid JSON was received by the server
|
|
7
|
+
PARSE_ERROR = -32_700
|
|
8
|
+
# The JSON sent is not a valid Request object
|
|
9
|
+
INVALID_REQUEST = -32_600
|
|
10
|
+
# The method does not exist / is not available
|
|
11
|
+
METHOD_NOT_FOUND = -32_601
|
|
12
|
+
# Invalid method parameter(s)
|
|
13
|
+
INVALID_PARAMS = -32_602
|
|
14
|
+
# Internal JSON-RPC error
|
|
15
|
+
INTERNAL_ERROR = -32_603
|
|
16
|
+
|
|
17
|
+
# The specified task was not found
|
|
18
|
+
TASK_NOT_FOUND = -32_001
|
|
19
|
+
# The specified task cannot be canceled
|
|
20
|
+
TASK_NOT_CANCELABLE = -32_002
|
|
21
|
+
# Push Notifications are not supported for this operation or agent
|
|
22
|
+
PUSH_NOTIFICATION_NOT_SUPPORTED = -32_003
|
|
23
|
+
# The requested operation is not supported by the agent
|
|
24
|
+
UNSUPPORTED_OPERATION = -32_004
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Represents the content of a file, either as base64 encoded bytes or a URI.
|
|
5
|
+
class FileContent < ProtocolStruct
|
|
6
|
+
# @return [String, nil] Optional name of the file.
|
|
7
|
+
attribute? :name, Types::String.optional
|
|
8
|
+
|
|
9
|
+
# @return [String, nil] Optional MIME type of the file content.
|
|
10
|
+
attribute? :mime_type, Types::String.optional
|
|
11
|
+
|
|
12
|
+
# @return [String, nil] File content encoded as a Base64 string. Use this OR `uri`.
|
|
13
|
+
attribute? :bytes, Types::String.optional
|
|
14
|
+
|
|
15
|
+
# @return [String, nil] URI pointing to the file content. Use this OR `bytes`.
|
|
16
|
+
attribute? :uri, Types::String.optional
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
# Represents a part of a message containing file content.
|
|
5
|
+
class FilePart < ProtocolStruct
|
|
6
|
+
# @return [String] Type identifier for this part.
|
|
7
|
+
attribute :type, Types::String.constant('file')
|
|
8
|
+
|
|
9
|
+
# @return [FileContent] The file content, provided either inline or via URI.
|
|
10
|
+
attribute :file, Types::Constructor(FileContent)
|
|
11
|
+
|
|
12
|
+
# @return [Hash, nil] Optional metadata associated with this file part.
|
|
13
|
+
attribute? :metadata, Types::Hash.optional
|
|
14
|
+
end
|
|
15
|
+
end
|