a2a-rails 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 +7 -0
- data/CHANGELOG.md +43 -0
- data/LICENSE +21 -0
- data/README.md +499 -0
- data/app/controllers/a2a/rails/agent_cards_controller.rb +12 -0
- data/app/controllers/a2a/rails/application_controller.rb +8 -0
- data/app/controllers/a2a/rails/requests_controller.rb +18 -0
- data/config/routes.rb +6 -0
- data/lib/a2a/rails/agent.rb +106 -0
- data/lib/a2a/rails/agent_card/builder.rb +95 -0
- data/lib/a2a/rails/agent_card/validator.rb +109 -0
- data/lib/a2a/rails/configuration.rb +96 -0
- data/lib/a2a/rails/dispatcher.rb +47 -0
- data/lib/a2a/rails/engine.rb +24 -0
- data/lib/a2a/rails/errors.rb +42 -0
- data/lib/a2a/rails/protocol/adapter.rb +13 -0
- data/lib/a2a/rails/protocol/agent2agent_adapter.rb +125 -0
- data/lib/a2a/rails/protocol/request_handler.rb +172 -0
- data/lib/a2a/rails/protocol/task_mapper.rb +106 -0
- data/lib/a2a/rails/runtime.rb +43 -0
- data/lib/a2a/rails/skill.rb +92 -0
- data/lib/a2a/rails/task/artifact_mapper.rb +38 -0
- data/lib/a2a/rails/task/lifecycle.rb +98 -0
- data/lib/a2a/rails/task/memory_store.rb +161 -0
- data/lib/a2a/rails/task/result_mapper.rb +32 -0
- data/lib/a2a/rails/task/store.rb +29 -0
- data/lib/a2a/rails/task.rb +16 -0
- data/lib/a2a/rails/version.rb +7 -0
- data/lib/a2a-rails.rb +36 -0
- data/lib/generators/a2a/rails/agent_generator.rb +20 -0
- data/lib/generators/a2a/rails/install_generator.rb +16 -0
- data/lib/generators/a2a/rails/templates/agent.rb.tt +7 -0
- data/lib/generators/a2a/rails/templates/initializer.rb.tt +4 -0
- metadata +192 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "digest"
|
|
4
|
+
require "securerandom"
|
|
5
|
+
require "time"
|
|
6
|
+
require_relative "store"
|
|
7
|
+
|
|
8
|
+
module A2A
|
|
9
|
+
module Rails
|
|
10
|
+
module Task
|
|
11
|
+
class MemoryStore < Store
|
|
12
|
+
UNSET = Object.new.freeze
|
|
13
|
+
DEFAULT_PAGE_SIZE = 50
|
|
14
|
+
MAX_PAGE_SIZE = 100
|
|
15
|
+
|
|
16
|
+
def initialize
|
|
17
|
+
@tasks = {}
|
|
18
|
+
@pages = {}
|
|
19
|
+
@mutex = Mutex.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def save(task)
|
|
23
|
+
id = task.fetch(:id)
|
|
24
|
+
@mutex.synchronize do
|
|
25
|
+
@tasks[id] = copy(task)
|
|
26
|
+
copy(@tasks[id])
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def find(task_id)
|
|
31
|
+
@mutex.synchronize { copy(find!(task_id)) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def transition(task_id, state:, timestamp: Time.now.utc, artifacts: UNSET, message: UNSET)
|
|
35
|
+
validate_state!(state)
|
|
36
|
+
|
|
37
|
+
@mutex.synchronize do
|
|
38
|
+
task = find!(task_id)
|
|
39
|
+
return copy(task) if terminal?(task)
|
|
40
|
+
|
|
41
|
+
task[:status] = status_hash(state, timestamp, message)
|
|
42
|
+
task[:artifacts] = copy(artifacts) unless artifacts.equal?(UNSET)
|
|
43
|
+
copy(task)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def cancel(task_id, timestamp: Time.now.utc)
|
|
48
|
+
@mutex.synchronize do
|
|
49
|
+
task = find!(task_id)
|
|
50
|
+
state = task.dig(:status, :state)
|
|
51
|
+
raise TaskNotCancelableError.new(task_id, state: state) if TERMINAL_STATES.include?(state)
|
|
52
|
+
|
|
53
|
+
task[:status] = status_hash(:canceled, timestamp, UNSET)
|
|
54
|
+
copy(task)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def list(context_id: nil, status: nil, status_timestamp_after: nil,
|
|
59
|
+
page_size: DEFAULT_PAGE_SIZE, page_token: nil)
|
|
60
|
+
validate_page_size!(page_size)
|
|
61
|
+
validate_state!(status) if status
|
|
62
|
+
after = normalize_time(status_timestamp_after) if status_timestamp_after
|
|
63
|
+
fingerprint = query_fingerprint(context_id:, status:, status_timestamp_after: after, page_size:)
|
|
64
|
+
|
|
65
|
+
@mutex.synchronize do
|
|
66
|
+
rows, offset = page_rows(page_token, fingerprint) do
|
|
67
|
+
filtered_rows(context_id:, status:, status_timestamp_after: after)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
next_offset = offset + page_size
|
|
71
|
+
next_token = ""
|
|
72
|
+
if next_offset < rows.length
|
|
73
|
+
next_token = SecureRandom.uuid
|
|
74
|
+
@pages[next_token] = { rows: rows, offset: next_offset, fingerprint: fingerprint }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
{
|
|
78
|
+
tasks: copy(rows.slice(offset, page_size) || []),
|
|
79
|
+
total_size: rows.length,
|
|
80
|
+
page_size: page_size,
|
|
81
|
+
next_page_token: next_token
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def find!(task_id)
|
|
89
|
+
@tasks[task_id] || raise(TaskNotFoundError, task_id)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def terminal?(task)
|
|
93
|
+
TERMINAL_STATES.include?(task.dig(:status, :state))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def validate_state!(state)
|
|
97
|
+
return if STATES.include?(state)
|
|
98
|
+
|
|
99
|
+
raise InvalidTaskStateError, "Unknown task state: #{state.inspect}"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def validate_page_size!(page_size)
|
|
103
|
+
return if page_size.is_a?(Integer) && (1..MAX_PAGE_SIZE).cover?(page_size)
|
|
104
|
+
|
|
105
|
+
raise InvalidTaskQueryError, "page_size must be an integer from 1 to #{MAX_PAGE_SIZE}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def normalize_time(value)
|
|
109
|
+
return value.utc if value.respond_to?(:utc) && !value.is_a?(String)
|
|
110
|
+
|
|
111
|
+
Time.iso8601(value.to_s).utc
|
|
112
|
+
rescue ArgumentError
|
|
113
|
+
raise InvalidTaskQueryError, "status_timestamp_after must be an ISO 8601 timestamp"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def status_hash(state, timestamp, message)
|
|
117
|
+
status = { state: state, timestamp: normalize_time(timestamp).iso8601(6) }
|
|
118
|
+
status[:message] = message unless message.equal?(UNSET)
|
|
119
|
+
status
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def page_rows(page_token, fingerprint)
|
|
123
|
+
if page_token && !page_token.empty?
|
|
124
|
+
cursor = @pages[page_token]
|
|
125
|
+
unless cursor && cursor[:fingerprint] == fingerprint
|
|
126
|
+
raise InvalidTaskQueryError, "Invalid page_token or changed query"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
[cursor[:rows], cursor[:offset]]
|
|
130
|
+
else
|
|
131
|
+
[copy(yield), 0]
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def filtered_rows(context_id:, status:, status_timestamp_after:)
|
|
136
|
+
@tasks.values
|
|
137
|
+
.select do |task|
|
|
138
|
+
(!context_id || task[:context_id] == context_id) &&
|
|
139
|
+
(!status || task.dig(:status, :state) == status) &&
|
|
140
|
+
(!status_timestamp_after || task_time(task) >= status_timestamp_after)
|
|
141
|
+
end
|
|
142
|
+
.sort_by { |task| [task_time(task), task.fetch(:id)] }
|
|
143
|
+
.reverse
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def task_time(task)
|
|
147
|
+
Time.iso8601(task.dig(:status, :timestamp))
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def query_fingerprint(context_id:, status:, status_timestamp_after:, page_size:)
|
|
151
|
+
normalized = [context_id, status, status_timestamp_after&.iso8601(6), page_size]
|
|
152
|
+
Digest::SHA256.hexdigest(Marshal.dump(normalized))
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def copy(value)
|
|
156
|
+
Marshal.load(Marshal.dump(value))
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
module Rails
|
|
5
|
+
module Task
|
|
6
|
+
class ResultMapper
|
|
7
|
+
FAILURE_MESSAGE = "Task execution failed"
|
|
8
|
+
REJECTION_MESSAGE = "Task rejected"
|
|
9
|
+
|
|
10
|
+
def initialize(artifact_mapper: ArtifactMapper.new)
|
|
11
|
+
@artifact_mapper = artifact_mapper
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def completed(value)
|
|
15
|
+
artifact = @artifact_mapper.call(value)
|
|
16
|
+
outcome = { state: :completed }
|
|
17
|
+
outcome[:artifacts] = [artifact] if artifact
|
|
18
|
+
outcome
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def rejected(error)
|
|
22
|
+
message = error.message.to_s.empty? ? REJECTION_MESSAGE : error.message.to_s
|
|
23
|
+
{ state: :rejected, message: message }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def failed(_error)
|
|
27
|
+
{ state: :failed, message: FAILURE_MESSAGE }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
module Rails
|
|
5
|
+
module Task
|
|
6
|
+
class Store
|
|
7
|
+
def save(_task)
|
|
8
|
+
raise NotImplementedError, "Task stores must implement #save"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def find(_task_id)
|
|
12
|
+
raise NotImplementedError, "Task stores must implement #find"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def transition(_task_id, state:, **_attributes)
|
|
16
|
+
raise NotImplementedError, "Task stores must implement #transition"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def cancel(_task_id, **_attributes)
|
|
20
|
+
raise NotImplementedError, "Task stores must implement #cancel"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def list(**_filters)
|
|
24
|
+
raise NotImplementedError, "Task stores must implement #list"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A2A
|
|
4
|
+
module Rails
|
|
5
|
+
module Task
|
|
6
|
+
STATES = %i[submitted working completed failed rejected canceled].freeze
|
|
7
|
+
TERMINAL_STATES = %i[completed failed rejected canceled].freeze
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require_relative "task/store"
|
|
13
|
+
require_relative "task/memory_store"
|
|
14
|
+
require_relative "task/artifact_mapper"
|
|
15
|
+
require_relative "task/result_mapper"
|
|
16
|
+
require_relative "task/lifecycle"
|
data/lib/a2a-rails.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "a2a/rails/version"
|
|
4
|
+
require_relative "a2a/rails/errors"
|
|
5
|
+
require_relative "a2a/rails/configuration"
|
|
6
|
+
require_relative "a2a/rails/skill"
|
|
7
|
+
require_relative "a2a/rails/agent"
|
|
8
|
+
require_relative "a2a/rails/dispatcher"
|
|
9
|
+
require_relative "a2a/rails/agent_card/validator"
|
|
10
|
+
require_relative "a2a/rails/agent_card/builder"
|
|
11
|
+
require_relative "a2a/rails/task"
|
|
12
|
+
require_relative "a2a/rails/protocol/adapter"
|
|
13
|
+
require_relative "a2a/rails/protocol/task_mapper"
|
|
14
|
+
require_relative "a2a/rails/protocol/request_handler"
|
|
15
|
+
require_relative "a2a/rails/protocol/agent2agent_adapter"
|
|
16
|
+
require_relative "a2a/rails/runtime"
|
|
17
|
+
require_relative "a2a/rails/engine"
|
|
18
|
+
|
|
19
|
+
module A2A
|
|
20
|
+
module Rails
|
|
21
|
+
class << self
|
|
22
|
+
def configuration
|
|
23
|
+
@configuration ||= Configuration.new
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def configure
|
|
27
|
+
yield configuration
|
|
28
|
+
configuration
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def runtime
|
|
32
|
+
@runtime ||= Runtime.new
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators/named_base"
|
|
4
|
+
|
|
5
|
+
module A2A
|
|
6
|
+
module Rails
|
|
7
|
+
class AgentGenerator < ::Rails::Generators::NamedBase
|
|
8
|
+
namespace "a2a:rails:agent"
|
|
9
|
+
source_root File.expand_path("templates", __dir__)
|
|
10
|
+
|
|
11
|
+
def create_agent
|
|
12
|
+
template "agent.rb.tt", File.join("app/agents", class_path, "#{file_name}_agent.rb")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def agent_display_name
|
|
16
|
+
file_name.split("_").map(&:capitalize).join(" ")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators/base"
|
|
4
|
+
|
|
5
|
+
module A2A
|
|
6
|
+
module Rails
|
|
7
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
8
|
+
namespace "a2a:rails:install"
|
|
9
|
+
source_root File.expand_path("templates", __dir__)
|
|
10
|
+
|
|
11
|
+
def create_initializer
|
|
12
|
+
template "initializer.rb.tt", "config/initializers/a2a_rails.rb"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: a2a-rails
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- cuichangquan
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-10-06 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: agent2agent
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 2.0.0
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 2.0.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: actionpack
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '8.0'
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '8.2'
|
|
36
|
+
type: :runtime
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '8.0'
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '8.2'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: json
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - "<"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '3'
|
|
53
|
+
type: :runtime
|
|
54
|
+
prerelease: false
|
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - "<"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '3'
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: rack
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '3.0'
|
|
67
|
+
- - "<"
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '4'
|
|
70
|
+
type: :runtime
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '3.0'
|
|
77
|
+
- - "<"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '4'
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: railties
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '8.0'
|
|
87
|
+
- - "<"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '8.2'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '8.0'
|
|
97
|
+
- - "<"
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '8.2'
|
|
100
|
+
- !ruby/object:Gem::Dependency
|
|
101
|
+
name: minitest
|
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
|
103
|
+
requirements:
|
|
104
|
+
- - "~>"
|
|
105
|
+
- !ruby/object:Gem::Version
|
|
106
|
+
version: '5.25'
|
|
107
|
+
type: :development
|
|
108
|
+
prerelease: false
|
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
110
|
+
requirements:
|
|
111
|
+
- - "~>"
|
|
112
|
+
- !ruby/object:Gem::Version
|
|
113
|
+
version: '5.25'
|
|
114
|
+
- !ruby/object:Gem::Dependency
|
|
115
|
+
name: rake
|
|
116
|
+
requirement: !ruby/object:Gem::Requirement
|
|
117
|
+
requirements:
|
|
118
|
+
- - "~>"
|
|
119
|
+
- !ruby/object:Gem::Version
|
|
120
|
+
version: '13.2'
|
|
121
|
+
type: :development
|
|
122
|
+
prerelease: false
|
|
123
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
124
|
+
requirements:
|
|
125
|
+
- - "~>"
|
|
126
|
+
- !ruby/object:Gem::Version
|
|
127
|
+
version: '13.2'
|
|
128
|
+
description: Expose Rails applications as A2A agents while keeping protocol SDK details
|
|
129
|
+
behind an internal adapter boundary.
|
|
130
|
+
executables: []
|
|
131
|
+
extensions: []
|
|
132
|
+
extra_rdoc_files: []
|
|
133
|
+
files:
|
|
134
|
+
- CHANGELOG.md
|
|
135
|
+
- LICENSE
|
|
136
|
+
- README.md
|
|
137
|
+
- app/controllers/a2a/rails/agent_cards_controller.rb
|
|
138
|
+
- app/controllers/a2a/rails/application_controller.rb
|
|
139
|
+
- app/controllers/a2a/rails/requests_controller.rb
|
|
140
|
+
- config/routes.rb
|
|
141
|
+
- lib/a2a-rails.rb
|
|
142
|
+
- lib/a2a/rails/agent.rb
|
|
143
|
+
- lib/a2a/rails/agent_card/builder.rb
|
|
144
|
+
- lib/a2a/rails/agent_card/validator.rb
|
|
145
|
+
- lib/a2a/rails/configuration.rb
|
|
146
|
+
- lib/a2a/rails/dispatcher.rb
|
|
147
|
+
- lib/a2a/rails/engine.rb
|
|
148
|
+
- lib/a2a/rails/errors.rb
|
|
149
|
+
- lib/a2a/rails/protocol/adapter.rb
|
|
150
|
+
- lib/a2a/rails/protocol/agent2agent_adapter.rb
|
|
151
|
+
- lib/a2a/rails/protocol/request_handler.rb
|
|
152
|
+
- lib/a2a/rails/protocol/task_mapper.rb
|
|
153
|
+
- lib/a2a/rails/runtime.rb
|
|
154
|
+
- lib/a2a/rails/skill.rb
|
|
155
|
+
- lib/a2a/rails/task.rb
|
|
156
|
+
- lib/a2a/rails/task/artifact_mapper.rb
|
|
157
|
+
- lib/a2a/rails/task/lifecycle.rb
|
|
158
|
+
- lib/a2a/rails/task/memory_store.rb
|
|
159
|
+
- lib/a2a/rails/task/result_mapper.rb
|
|
160
|
+
- lib/a2a/rails/task/store.rb
|
|
161
|
+
- lib/a2a/rails/version.rb
|
|
162
|
+
- lib/generators/a2a/rails/agent_generator.rb
|
|
163
|
+
- lib/generators/a2a/rails/install_generator.rb
|
|
164
|
+
- lib/generators/a2a/rails/templates/agent.rb.tt
|
|
165
|
+
- lib/generators/a2a/rails/templates/initializer.rb.tt
|
|
166
|
+
homepage: https://github.com/cuichangquan/a2a-rails
|
|
167
|
+
licenses:
|
|
168
|
+
- MIT
|
|
169
|
+
metadata:
|
|
170
|
+
source_code_uri: https://github.com/cuichangquan/a2a-rails
|
|
171
|
+
changelog_uri: https://github.com/cuichangquan/a2a-rails/blob/main/CHANGELOG.md
|
|
172
|
+
documentation_uri: https://github.com/cuichangquan/a2a-rails#readme
|
|
173
|
+
bug_tracker_uri: https://github.com/cuichangquan/a2a-rails/issues
|
|
174
|
+
rubygems_mfa_required: 'true'
|
|
175
|
+
rdoc_options: []
|
|
176
|
+
require_paths:
|
|
177
|
+
- lib
|
|
178
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
179
|
+
requirements:
|
|
180
|
+
- - ">="
|
|
181
|
+
- !ruby/object:Gem::Version
|
|
182
|
+
version: '3.3'
|
|
183
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - ">="
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '0'
|
|
188
|
+
requirements: []
|
|
189
|
+
rubygems_version: 3.6.4
|
|
190
|
+
specification_version: 4
|
|
191
|
+
summary: Rails-native integration for exposing Rails applications as A2A agents
|
|
192
|
+
test_files: []
|