a2a 0.1.0.pre → 0.2.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/.agent-docs/ROADMAP.md +423 -0
- data/.agent-docs/index.md +124 -0
- data/.agent-docs/llms.txt +318 -0
- data/.agent-docs/specification/json.json +2575 -0
- data/.agent-docs/specification.md +1924 -0
- data/.agent-docs/topics/a2a-and-mcp.md +132 -0
- data/.agent-docs/topics/agent-discovery.md +96 -0
- data/.agent-docs/topics/enterprise-ready.md +139 -0
- data/.agent-docs/topics/extensions.md +260 -0
- data/.agent-docs/topics/key-concepts.md +99 -0
- data/.agent-docs/topics/life-of-a-task.md +255 -0
- data/.agent-docs/topics/streaming-and-async.md +111 -0
- data/.agent-docs/topics/what-is-a2a.md +218 -0
- data/.agent-docs/tutorials/index.md +31 -0
- data/.agent-docs/tutorials/python/1-introduction.md +32 -0
- data/.agent-docs/tutorials/python/2-setup.md +55 -0
- data/.agent-docs/tutorials/python/3-agent-skills-and-card.md +48 -0
- data/.agent-docs/tutorials/python/4-agent-executor.md +57 -0
- data/.agent-docs/tutorials/python/5-start-server.md +55 -0
- data/.agent-docs/tutorials/python/6-interact-with-server.md +95 -0
- data/.agent-docs/tutorials/python/7-streaming-and-multiturn.md +97 -0
- data/.agent-docs/tutorials/python/8-next-steps.md +40 -0
- data/.agent-docs/types.ts +1544 -0
- data/.agent-docs/types_mapping.md +196 -0
- data/.claude/commands/gemfile/update.md +52 -0
- data/.claude/settings.local.json +23 -0
- data/.rubocop.yml +25 -4
- data/.tool-versions +1 -1
- data/CHANGELOG.md +86 -2
- data/CLAUDE.md +98 -0
- data/Guardfile +1 -1
- data/README.md +55 -4
- data/Rakefile +1 -3
- data/WARP.md +115 -0
- 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 +51 -0
- data/lib/a2a/types/agent_capabilities.rb +18 -0
- data/lib/a2a/types/agent_card.rb +71 -0
- data/lib/a2a/types/agent_card_signature.rb +17 -0
- data/lib/a2a/types/agent_extension.rb +19 -0
- data/lib/a2a/types/agent_interface.rb +13 -0
- data/lib/a2a/types/agent_provider.rb +12 -0
- data/lib/a2a/types/agent_skill.rb +34 -0
- data/lib/a2a/types/api_key_security_scheme.rb +15 -0
- data/lib/a2a/types/artifact.rb +24 -0
- data/lib/a2a/types/authenticated_extended_card_not_configured_error.rb +43 -0
- data/lib/a2a/types/authorization_code_oauth_flow.rb +22 -0
- data/lib/a2a/types/cancel_task_request.rb +18 -0
- data/lib/a2a/types/cancel_task_response.rb +12 -0
- data/lib/a2a/types/client_credentials_oauth_flow.rb +16 -0
- data/lib/a2a/types/content_type_not_supported_error.rb +42 -0
- data/lib/a2a/types/data_part.rb +12 -0
- data/lib/a2a/types/delete_task_push_notification_config_params.rb +9 -0
- data/lib/a2a/types/delete_task_push_notification_config_request.rb +18 -0
- data/lib/a2a/types/delete_task_push_notification_config_response.rb +13 -0
- data/lib/a2a/types/error.rb +19 -0
- data/lib/a2a/types/error_codes.rb +32 -0
- data/lib/a2a/types/file_base.rb +12 -0
- data/lib/a2a/types/file_part.rb +13 -0
- data/lib/a2a/types/file_with_bytes.rb +9 -0
- data/lib/a2a/types/file_with_uri.rb +9 -0
- data/lib/a2a/types/get_authenticated_extended_card_request.rb +15 -0
- data/lib/a2a/types/get_authenticated_extended_card_response.rb +13 -0
- data/lib/a2a/types/get_task_push_notification_config_params.rb +9 -0
- data/lib/a2a/types/get_task_push_notification_config_request.rb +21 -0
- data/lib/a2a/types/get_task_push_notification_request.rb +18 -0
- data/lib/a2a/types/get_task_push_notification_response.rb +12 -0
- data/lib/a2a/types/get_task_request.rb +18 -0
- data/lib/a2a/types/get_task_response.rb +12 -0
- data/lib/a2a/types/http_auth_security_scheme.rb +18 -0
- data/lib/a2a/types/implicit_oauth_flow.rb +16 -0
- data/lib/a2a/types/invalid_agent_response_error.rb +41 -0
- data/lib/a2a/types/list_task_push_notification_config_params.rb +8 -0
- data/lib/a2a/types/list_task_push_notification_config_request.rb +18 -0
- data/lib/a2a/types/list_task_push_notification_config_response.rb +13 -0
- data/lib/a2a/types/message.rb +35 -0
- data/lib/a2a/types/message_send_configuration.rb +20 -0
- data/lib/a2a/types/message_send_params.rb +16 -0
- data/lib/a2a/types/mutual_tls_security_scheme.rb +9 -0
- data/lib/a2a/types/oauth2_security_scheme.rb +16 -0
- data/lib/a2a/types/oauth_flows.rb +20 -0
- data/lib/a2a/types/openid_connect_security_scheme.rb +12 -0
- data/lib/a2a/types/part.rb +7 -0
- data/lib/a2a/types/part_base.rb +9 -0
- data/lib/a2a/types/password_oauth_flow.rb +16 -0
- data/lib/a2a/types/protocol_struct.rb +12 -0
- data/lib/a2a/types/push_notification_authentication_info.rb +12 -0
- data/lib/a2a/types/push_notification_config.rb +20 -0
- data/lib/a2a/types/push_notification_not_supported_error.rb +42 -0
- data/lib/a2a/types/request.rb +15 -0
- data/lib/a2a/types/security_scheme.rb +11 -0
- data/lib/a2a/types/security_scheme_base.rb +9 -0
- data/lib/a2a/types/send_message_request.rb +18 -0
- data/lib/a2a/types/send_message_response.rb +13 -0
- data/lib/a2a/types/send_streaming_message_request.rb +18 -0
- data/lib/a2a/types/send_streaming_message_response.rb +15 -0
- data/lib/a2a/types/set_task_push_notification_config_request.rb +18 -0
- data/lib/a2a/types/set_task_push_notification_request.rb +18 -0
- data/lib/a2a/types/set_task_push_notification_response.rb +12 -0
- data/lib/a2a/types/task.rb +29 -0
- data/lib/a2a/types/task_artifact_update_event.rb +29 -0
- data/lib/a2a/types/task_id_params.rb +12 -0
- data/lib/a2a/types/task_not_cancelable_error.rb +42 -0
- data/lib/a2a/types/task_not_found_error.rb +42 -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 +18 -0
- data/lib/a2a/types/task_state.rb +7 -0
- data/lib/a2a/types/task_status.rb +15 -0
- data/lib/a2a/types/task_status_update_event.rb +25 -0
- data/lib/a2a/types/text_part.rb +12 -0
- data/lib/a2a/types/transport_protocol.rb +6 -0
- data/lib/a2a/types/unsupported_operation_error.rb +42 -0
- data/lib/a2a/types.rb +25 -0
- data/lib/a2a/version.rb +1 -1
- data/lib/a2a.rb +30 -1
- metadata +128 -299
data/WARP.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# WARP.md
|
2
|
+
|
3
|
+
This file provides guidance to WARP (warp.dev) when working with code in this repository.
|
4
|
+
|
5
|
+
## Development Commands
|
6
|
+
|
7
|
+
### Essential Commands
|
8
|
+
```bash
|
9
|
+
# Setup development environment
|
10
|
+
bin/setup
|
11
|
+
|
12
|
+
# Interactive console for experimentation
|
13
|
+
bin/console
|
14
|
+
|
15
|
+
# Install gem locally for testing
|
16
|
+
bundle exec rake install
|
17
|
+
|
18
|
+
# Run all tests
|
19
|
+
bundle exec rspec
|
20
|
+
|
21
|
+
# Run tests with coverage (opens HTML report)
|
22
|
+
rake coverage
|
23
|
+
|
24
|
+
# Lint code with RuboCop
|
25
|
+
bundle exec rubocop
|
26
|
+
|
27
|
+
# Auto-fix RuboCop offenses (safe only)
|
28
|
+
bundle exec rubocop --autocorrect
|
29
|
+
|
30
|
+
# Run comprehensive quality assurance
|
31
|
+
rake qa
|
32
|
+
```
|
33
|
+
|
34
|
+
### Testing and Quality
|
35
|
+
```bash
|
36
|
+
# Run specific test file
|
37
|
+
bundle exec rspec spec/a2a_spec.rb
|
38
|
+
|
39
|
+
# Run tests with focus on failed specs
|
40
|
+
bundle exec rspec --only-failures
|
41
|
+
|
42
|
+
# Generate YARD documentation
|
43
|
+
bundle exec yard
|
44
|
+
|
45
|
+
# Type checking with Steep
|
46
|
+
bundle exec steep check
|
47
|
+
|
48
|
+
# Security audit
|
49
|
+
bundle exec bundle-audit
|
50
|
+
|
51
|
+
# Documentation coverage measurement
|
52
|
+
rake yardstick_measure
|
53
|
+
rake verify_measurements
|
54
|
+
```
|
55
|
+
|
56
|
+
### Development Workflow
|
57
|
+
```bash
|
58
|
+
# Watch files for changes (requires Guard)
|
59
|
+
bundle exec guard
|
60
|
+
|
61
|
+
# Build gem package
|
62
|
+
bundle exec rake build
|
63
|
+
|
64
|
+
# Release new version (updates version, creates tag, pushes to RubyGems)
|
65
|
+
bundle exec rake release
|
66
|
+
```
|
67
|
+
|
68
|
+
### Claude AI Commands
|
69
|
+
```bash
|
70
|
+
# Update Gemfile dependencies with commit
|
71
|
+
claude --print --verbose "/gemfile:update --commit"
|
72
|
+
```
|
73
|
+
|
74
|
+
## Architecture Overview
|
75
|
+
|
76
|
+
### Core Structure
|
77
|
+
- **A2A Protocol Implementation**: Ruby implementation of the Agent2Agent communication protocol
|
78
|
+
- **Dry-Struct Based**: Uses `dry-struct` for typed data structures with validation
|
79
|
+
- **Case Transformation**: Automatic conversion between snake_case (Ruby) and camelCase (JSON protocol)
|
80
|
+
- **JSON-RPC Messages**: Full support for JSON-RPC request/response patterns
|
81
|
+
|
82
|
+
### Key Components
|
83
|
+
|
84
|
+
#### Extensions (`lib/a2a/extensions/`)
|
85
|
+
- **CaseTransformation**: Handles snake_case ↔ camelCase conversion during serialization
|
86
|
+
- **JSONDeserialization**: Enables creating objects directly from JSON strings
|
87
|
+
- **AdditionalProperties**: Supports flexible schema with extra properties
|
88
|
+
|
89
|
+
#### Types System (`lib/a2a/types/`)
|
90
|
+
- Protocol-compliant data structures (requests, responses, agents, tasks, etc.)
|
91
|
+
- All types inherit from `Dry::Struct` with validation
|
92
|
+
- Support for additional properties beyond defined attributes
|
93
|
+
|
94
|
+
### Development Environment
|
95
|
+
- **Ruby Version**: 3.4+ required
|
96
|
+
- **Type System**: RBS type definitions in `sig/` directory
|
97
|
+
- **Testing**: RSpec with FactoryBot for test data
|
98
|
+
- **Code Quality**: RuboCop with multiple plugins (performance, RSpec, factory_bot)
|
99
|
+
- **Documentation**: YARD with 100% coverage requirement
|
100
|
+
- **Security**: Bundler Audit integration
|
101
|
+
- **CI/CD**: Overcommit hooks for pre-commit validation
|
102
|
+
|
103
|
+
### Protocol Implementation Details
|
104
|
+
The gem provides Ruby objects for all A2A protocol message types:
|
105
|
+
- Task management (send, cancel, status)
|
106
|
+
- Agent capabilities and authentication
|
107
|
+
- File and artifact handling
|
108
|
+
- Push notifications
|
109
|
+
- Error handling with standardized codes
|
110
|
+
|
111
|
+
All objects support:
|
112
|
+
- Instantiation from hash data (with automatic key transformation)
|
113
|
+
- JSON serialization with protocol-compliant camelCase keys
|
114
|
+
- Type validation and additional property support
|
115
|
+
- Parsing from JSON strings via `from_json` methods
|
@@ -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,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
module Extensions
|
5
|
+
# Provides JSON deserialization capabilities to a class
|
6
|
+
module JSONDeserialization
|
7
|
+
# @!visibility private
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Class methods added to the class that includes JsonDeserialization
|
13
|
+
module ClassMethods
|
14
|
+
# Creates a new instance from a JSON string
|
15
|
+
#
|
16
|
+
# @param json [String] JSON string to parse
|
17
|
+
# @return [ProtocolStruct] A new instance of the appropriate class
|
18
|
+
#
|
19
|
+
# @example Create a Google Maps Agent Card from JSON
|
20
|
+
# json_string = <<~JSON
|
21
|
+
# {
|
22
|
+
# "name": "Google Maps Agent",
|
23
|
+
# "description": "Plan routes, remember places, and generate directions",
|
24
|
+
# "url": "https://maps-agent.google.com",
|
25
|
+
# "provider": {
|
26
|
+
# "organization": "Google",
|
27
|
+
# "url": "https://google.com"
|
28
|
+
# },
|
29
|
+
# "version": "1.0.0",
|
30
|
+
# "capabilities": {
|
31
|
+
# "streaming": true,
|
32
|
+
# "pushNotifications": false
|
33
|
+
# },
|
34
|
+
# "skills": [
|
35
|
+
# {
|
36
|
+
# "id": "route-planner",
|
37
|
+
# "name": "Route planning",
|
38
|
+
# "description": "Helps plan routing between two locations"
|
39
|
+
# }
|
40
|
+
# ]
|
41
|
+
# }
|
42
|
+
# JSON
|
43
|
+
# agent_card = A2A::AgentCard.from_json(json_string)
|
44
|
+
#
|
45
|
+
def from_json(json)
|
46
|
+
new(MultiJson.load(json, symbolize_keys: true))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,18 @@
|
|
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
|
+
|
15
|
+
# @return [Array<AgentExtension>, nil] A list of protocol extensions supported by the agent.
|
16
|
+
attribute? :extensions, Types::Array.of(Types::Constructor(AgentExtension)).optional
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
# The AgentCard is a self-describing manifest for an agent. It provides essential
|
5
|
+
# metadata including the agent's identity, capabilities, skills, supported
|
6
|
+
# communication methods, and security requirements.
|
7
|
+
class AgentCard < ProtocolStruct
|
8
|
+
# @return [String] The version of the A2A protocol this agent supports.
|
9
|
+
attribute :protocol_version, Types::String.default('0.3.0')
|
10
|
+
|
11
|
+
# @return [String] A human-readable name for the agent.
|
12
|
+
attribute :name, Types::String
|
13
|
+
|
14
|
+
# @return [String] A human-readable description of the agent, assisting users and other agents
|
15
|
+
# in understanding its purpose.
|
16
|
+
attribute :description, Types::String
|
17
|
+
|
18
|
+
# @return [URI] The preferred endpoint URL for interacting with the agent.
|
19
|
+
# This URL MUST support the transport specified by 'preferred_transport'.
|
20
|
+
attribute :url, Types::URI
|
21
|
+
|
22
|
+
# @return [String] The transport protocol for the preferred endpoint (the main 'url' field).
|
23
|
+
# If not specified, defaults to 'JSONRPC'.
|
24
|
+
attribute? :preferred_transport, Types::String.default('JSONRPC')
|
25
|
+
|
26
|
+
# @return [Array<AgentInterface>, nil] A list of additional supported interfaces (transport and URL combinations).
|
27
|
+
# This allows agents to expose multiple transports, potentially at different URLs.
|
28
|
+
attribute? :additional_interfaces, Types::Array.of(Types::Constructor(AgentInterface)).optional
|
29
|
+
|
30
|
+
# @return [URI, nil] An optional URL to an icon for the agent.
|
31
|
+
attribute? :icon_url, Types::URI.optional
|
32
|
+
|
33
|
+
# @return [AgentProvider, nil] Information about the provider of the agent.
|
34
|
+
attribute? :provider, Types::Constructor(AgentProvider).optional
|
35
|
+
|
36
|
+
# @return [String] The agent's own version number. The format is defined by the provider.
|
37
|
+
attribute :version, Types::String
|
38
|
+
|
39
|
+
# @return [URI, nil] An optional URL to the agent's documentation.
|
40
|
+
attribute? :documentation_url, Types::URI.optional
|
41
|
+
|
42
|
+
# @return [AgentCapabilities] A declaration of optional capabilities supported by the agent.
|
43
|
+
attribute :capabilities, Types::Constructor(AgentCapabilities)
|
44
|
+
|
45
|
+
# @return [Hash<String, SecurityScheme>, nil] A declaration of the security schemes available to authorize requests.
|
46
|
+
# The key is the scheme name. Follows the OpenAPI 3.0 Security Scheme Object.
|
47
|
+
attribute? :security_schemes, Types::Hash.map(Types::Symbol | Types::String, Types::Constructor(SecurityScheme)).optional
|
48
|
+
|
49
|
+
# @return [Array<Hash>, nil] A list of security requirement objects that apply to all agent interactions.
|
50
|
+
# Each object lists security schemes that can be used. Follows the OpenAPI 3.0 Security Requirement Object.
|
51
|
+
attribute? :security, Types::Array.of(Types::Hash.map(Types::String | Types::Symbol, Types::Array.of(Types::String))).optional
|
52
|
+
|
53
|
+
# @return [Array<String>] Default set of supported input MIME types for all skills, which can be
|
54
|
+
# overridden on a per-skill basis.
|
55
|
+
attribute :default_input_modes, Types::Array.of(Types::String)
|
56
|
+
|
57
|
+
# @return [Array<String>] Default set of supported output MIME types for all skills, which can be
|
58
|
+
# overridden on a per-skill basis.
|
59
|
+
attribute :default_output_modes, Types::Array.of(Types::String)
|
60
|
+
|
61
|
+
# @return [Array<AgentSkill>] The set of skills, or distinct capabilities, that the agent can perform.
|
62
|
+
attribute :skills, Types::Array.of(Types::Constructor(AgentSkill))
|
63
|
+
|
64
|
+
# @return [Boolean] If true, the agent can provide an extended agent card with additional details
|
65
|
+
# to authenticated users. Defaults to false.
|
66
|
+
attribute? :supports_authenticated_extended_card, Types::Bool.default(false)
|
67
|
+
|
68
|
+
# @return [Array<AgentCardSignature>, nil] JSON Web Signatures computed for this AgentCard.
|
69
|
+
attribute? :signatures, Types::Array.of(Types::Constructor(AgentCardSignature)).optional
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
# AgentCardSignature represents a JWS signature of an AgentCard.
|
5
|
+
# This follows the JSON format of an RFC 7515 JSON Web Signature (JWS).
|
6
|
+
class AgentCardSignature < ProtocolStruct
|
7
|
+
# @return [String] The protected JWS header for the signature. This is a Base64url-encoded
|
8
|
+
# JSON object, as per RFC 7515.
|
9
|
+
attribute :protected, Types::String
|
10
|
+
|
11
|
+
# @return [String] The computed signature, Base64url-encoded.
|
12
|
+
attribute :signature, Types::String
|
13
|
+
|
14
|
+
# @return [Hash, nil] The unprotected JWS header values.
|
15
|
+
attribute? :header, Types::Hash.optional
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
# A declaration of a protocol extension supported by an Agent.
|
5
|
+
class AgentExtension < ProtocolStruct
|
6
|
+
# @return [URI] The unique URI identifying the extension.
|
7
|
+
attribute :uri, Types::URI
|
8
|
+
|
9
|
+
# @return [String, nil] A human-readable description of how this agent uses the extension.
|
10
|
+
attribute? :description, Types::String.optional
|
11
|
+
|
12
|
+
# @return [Boolean] If true, the client must understand and comply with the extension's requirements
|
13
|
+
# to interact with the agent.
|
14
|
+
attribute? :required, Types::Bool.default(false)
|
15
|
+
|
16
|
+
# @return [Hash, nil] Optional, extension-specific configuration parameters.
|
17
|
+
attribute? :params, Types::Hash.optional
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
# Declares a combination of a target URL and a transport protocol for interacting with the agent.
|
5
|
+
# This allows agents to expose the same functionality over multiple transport mechanisms.
|
6
|
+
class AgentInterface < ProtocolStruct
|
7
|
+
# @return [URI] The URL where this interface is available. Must be a valid absolute HTTPS URL in production.
|
8
|
+
attribute :url, Types::URI
|
9
|
+
|
10
|
+
# @return [String] The transport protocol supported at this URL.
|
11
|
+
attribute :transport, Types::String
|
12
|
+
end
|
13
|
+
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 [URI] A URL for the agent provider's website or relevant documentation.
|
10
|
+
attribute :url, Types::URI
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,34 @@
|
|
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] A detailed description of the skill, intended to help clients or users
|
13
|
+
# understand its purpose and functionality.
|
14
|
+
attribute :description, Types::String
|
15
|
+
|
16
|
+
# @return [Array<String>] A set of keywords describing the skill's capabilities.
|
17
|
+
attribute :tags, Types::Array.of(Types::String)
|
18
|
+
|
19
|
+
# @return [Array<String>, nil] Optional list of example inputs or use cases for the skill.
|
20
|
+
attribute? :examples, Types::Array.of(Types::String).optional
|
21
|
+
|
22
|
+
# @return [Array<String>, nil] Optional list of input modes supported by this skill, overriding agent defaults.
|
23
|
+
attribute? :input_modes, Types::Array.of(Types::String).optional
|
24
|
+
|
25
|
+
# @return [Array<String>, nil] Optional list of output modes supported by this skill, overriding agent defaults.
|
26
|
+
attribute? :output_modes, Types::Array.of(Types::String).optional
|
27
|
+
|
28
|
+
# @return [Array<Hash>, nil] Security schemes necessary for the agent to leverage this skill.
|
29
|
+
# As in the overall AgentCard.security, this list represents a logical OR of security
|
30
|
+
# requirement objects. Each object is a set of security schemes that must be used together
|
31
|
+
# (a logical AND).
|
32
|
+
attribute? :security, Types::Array.of(Types::Hash.map(Types::String, Types::Array.of(Types::String))).optional
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
# Defines a security scheme using an API key.
|
5
|
+
class APIKeySecurityScheme < SecuritySchemeBase
|
6
|
+
# @return [String] The type of the security scheme. Must be 'apiKey'.
|
7
|
+
attribute :type, Types::String.constant('apiKey')
|
8
|
+
|
9
|
+
# @return [String] The location of the API key.
|
10
|
+
attribute :in, Types::String.enum('query', 'header', 'cookie')
|
11
|
+
|
12
|
+
# @return [String] The name of the header, query, or cookie parameter to be used.
|
13
|
+
attribute :name, Types::String
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
# Represents a file, data structure, or other resource generated by an agent during a task.
|
5
|
+
class Artifact < ProtocolStruct
|
6
|
+
# @return [String] A unique identifier (e.g. UUID) for the artifact within the scope of the task.
|
7
|
+
attribute :artifact_id, Types::String
|
8
|
+
|
9
|
+
# @return [String, nil] An optional, human-readable name for the artifact.
|
10
|
+
attribute? :name, Types::String.optional
|
11
|
+
|
12
|
+
# @return [String, nil] An optional, human-readable description of the artifact.
|
13
|
+
attribute? :description, Types::String.optional
|
14
|
+
|
15
|
+
# @return [Array<Part>] An array of content parts that make up the artifact.
|
16
|
+
attribute :parts, Types::Array.of(Types::Constructor(Part))
|
17
|
+
|
18
|
+
# @return [Hash, nil] Optional metadata for extensions. The key is an extension-specific identifier.
|
19
|
+
attribute? :metadata, Types::Hash.optional
|
20
|
+
|
21
|
+
# @return [Array<String>, nil] The URIs of extensions that are relevant to this artifact.
|
22
|
+
attribute? :extensions, Types::Array.of(Types::String).optional
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
# Error for missing authenticated extended card configuration (-32007)
|
5
|
+
#
|
6
|
+
# Raised when the agent does not have an Authenticated Extended Card configured.
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
#
|
10
|
+
# @example Create an authenticated extended card not configured error
|
11
|
+
# error = JSONRPC::AuthenticatedExtendedCardNotConfiguredError.new
|
12
|
+
#
|
13
|
+
class AuthenticatedExtendedCardNotConfiguredError < JSONRPC::Error
|
14
|
+
# Creates a new Authenticated Extended Card Not Configured Error with code -32007
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
#
|
18
|
+
# @example Create an authenticated extended card not configured error with default message
|
19
|
+
# error = JSONRPC::AuthenticatedExtendedCardNotConfiguredError.new
|
20
|
+
#
|
21
|
+
# @example Create an authenticated extended card not configured error with exception details
|
22
|
+
# error = JSONRPC::AuthenticatedExtendedCardNotConfiguredError.new(
|
23
|
+
# data: { feature: 'extended_card' }, request_id: 1
|
24
|
+
# )
|
25
|
+
#
|
26
|
+
# @param message [String] short description of the error
|
27
|
+
# @param data [Hash, Array, String, Number, Boolean, nil] additional error information
|
28
|
+
# @param request_id [String, Integer, nil] the request identifier
|
29
|
+
#
|
30
|
+
def initialize(
|
31
|
+
message = 'Authenticated Extended Card not configured.',
|
32
|
+
data: nil,
|
33
|
+
request_id: nil
|
34
|
+
)
|
35
|
+
super(
|
36
|
+
message,
|
37
|
+
code: ErrorCodes::AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED,
|
38
|
+
data:,
|
39
|
+
request_id:
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
# Defines configuration details for the OAuth 2.0 Authorization Code flow.
|
5
|
+
class AuthorizationCodeOAuthFlow < ProtocolStruct
|
6
|
+
# @return [URI] The authorization URL to be used for this flow.
|
7
|
+
# This MUST be a URL and use TLS.
|
8
|
+
attribute :authorization_url, Types::URI
|
9
|
+
|
10
|
+
# @return [URI] The token URL to be used for this flow.
|
11
|
+
# This MUST be a URL and use TLS.
|
12
|
+
attribute :token_url, Types::URI
|
13
|
+
|
14
|
+
# @return [URI, nil] The URL to be used for obtaining refresh tokens.
|
15
|
+
# This MUST be a URL and use TLS.
|
16
|
+
attribute? :refresh_url, Types::URI.optional
|
17
|
+
|
18
|
+
# @return [Hash] The available scopes for the OAuth2 security scheme. A map between the scope
|
19
|
+
# name and a short description for it.
|
20
|
+
attribute :scopes, Types::Hash.map(Types::String, Types::String)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module A2A
|
4
|
+
# Request to cancel a currently running task.
|
5
|
+
class CancelTaskRequest < JSONRPC::Request
|
6
|
+
# @return [String] Method name for canceling a task.
|
7
|
+
METHOD = 'tasks/cancel'
|
8
|
+
|
9
|
+
# @return [String] Method name for canceling a task.
|
10
|
+
attribute :method, Types::String.constant(METHOD)
|
11
|
+
|
12
|
+
# @return [TaskIdParams] Parameters for the cancel task method.
|
13
|
+
attribute :params, Types::Constructor(TaskIdParams)
|
14
|
+
|
15
|
+
# @return [String] Method name for canceling a task.
|
16
|
+
def method = attributes[:method]
|
17
|
+
end
|
18
|
+
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 < JSONRPC::Response
|
6
|
+
# @return [Task, nil] The canceled task information if successful.
|
7
|
+
attribute? :result, Types::Constructor(Task).optional
|
8
|
+
|
9
|
+
# @return [JSONRPC::Error, nil] Error information if the request failed.
|
10
|
+
attribute? :error, Types::Constructor(JSONRPC::Error).optional
|
11
|
+
end
|
12
|
+
end
|