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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9b32fb9c3818579632e24051395d8f6e7820cde362a7068d861d0ee281b4a6c9
4
+ data.tar.gz: 1bbe7422de7f70a8e6c01e50f15b7d07a7232682fbac9c81276c8bd69867a6cf
5
+ SHA512:
6
+ metadata.gz: a3c1f685fa38fb4b44f8329d7c0fea22a3ce3c5503e3904b4632e2cb933df2a904091021c530bcc78e24ddc015f392bf73dcfb94a4deded9fdb6343c18a353c4
7
+ data.tar.gz: 163d991b30b75f3096270fffe6f74e9fb5ba5744df8897aea595c55ccf516e278ef159385c1ea79f244a646350eb67ec0e05c4498d66e51ea42f1d9a61790747
data/CHANGELOG.md ADDED
@@ -0,0 +1,43 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.1.0] - 2026-10-06
8
+
9
+ ### Added
10
+
11
+ - Rails-native A2A v1.0 server integration backed by `agent2agent ~> 2.0.0`.
12
+ - `A2A::Rails::Agent` and Skill DSL with application-owned Handler dispatch.
13
+ - Single-Skill automatic dispatch and multi-Skill Router support.
14
+ - Agent Card generation at `GET /.well-known/agent-card.json`.
15
+ - A2A JSON-RPC endpoint at `POST /a2a`.
16
+ - Synchronous Task lifecycle with `SUBMITTED`, `WORKING`, `COMPLETED`, `FAILED`, `REJECTED`, and `CANCELED` states.
17
+ - String, Hash, Array, and nil Handler-result mapping to A2A Artifacts.
18
+ - Thread-safe process-local in-memory Task Store.
19
+ - `SendMessage`, `GetTask`, `ListTasks`, and `CancelTask` support.
20
+ - `ListTasks` filtering, stable newest-first ordering, and opaque snapshot pagination.
21
+ - Lazy Rails configuration and Agent resolution.
22
+ - Automatically mounted Rails Engine and thin API controllers.
23
+ - Rails-facing logging boundary that suppresses the upstream SDK Rack-environment INFO log.
24
+ - `a2a:rails:install` and `a2a:rails:agent NAME` generators.
25
+ - Generator-backed Echo Quick Start verified through a real packaged `.gem` installed into a clean Rails application.
26
+ - CI coverage for Ruby 3.3, 3.4, and 4.0 with Rails 8.0 and 8.1.
27
+
28
+ ### Compatibility
29
+
30
+ - Ruby `>= 3.3`.
31
+ - Rails `>= 8.0, < 8.2`.
32
+ - A2A protocol version `1.0`.
33
+ - `agent2agent ~> 2.0.0`.
34
+
35
+ ### Known limitations
36
+
37
+ - Server-only; no A2A client.
38
+ - Non-streaming synchronous execution only.
39
+ - No Push Notifications, gRPC, ActiveJob execution, or durable Task Store.
40
+ - Default Task Store is process-local and is not shared across processes or preserved across restarts.
41
+ - Handler cancellation does not interrupt already-running application code or undo business side effects.
42
+ - `INPUT_REQUIRED` and `AUTH_REQUIRED` flows are not implemented.
43
+ - Continuing an existing Task via `message.taskId` is not supported in v0.1.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 changquan.cui
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,499 @@
1
+ # a2a-rails
2
+
3
+ Rails-native integration for exposing Rails applications as A2A agents.
4
+
5
+ > **Status: the v0.1.0 release candidate is prepared and CI-verified; the actual public release is next.**
6
+
7
+ ## Current Status
8
+
9
+ The A2A v1.0 SDK integration path, Gem core, Protocol Adapter, Agent / Skill DSL, Task lifecycle, Configuration, Agent Card generation, Rails Engine HTTP endpoints, generators, source-tree Quick Start, packaged-gem installation path, and v0.1.0 release-candidate metadata are now verified.
10
+
11
+ **Current stage:** Step 15-13 completed — v0.1.0 release-candidate preparation
12
+
13
+ **Next step:** **Step 15-14 — Execute the v0.1.0 release: final artifact verification from the exact main commit, public-release readiness, `v0.1.0` tag, RubyGems publication, GitHub Release, and post-release smoke verification.**
14
+
15
+ Step 15-13 adds `CHANGELOG.md`, canonical v0.1.0 release notes, a pre-release / publish / post-release checklist, and final RubyGems metadata for source, changelog, documentation, issue tracker, and MFA. The packaged-gem smoke now verifies those metadata fields plus README, CHANGELOG, LICENSE, Ruby compatibility, generator discovery, clean-app installation, Agent Card retrieval, and Echo `SendMessage`. The release-candidate CI is **13 / 13 green**, while the Gem suite remains **70 tests / 240 assertions / 0 failures / 0 errors / 0 skips**. See [Draft PR #7](https://github.com/cuichangquan/a2a-rails/pull/7).
16
+
17
+ Step 15-12 verified the actual built gem in a clean Rails application. Step 15-11 added the intentionally small `install` / `agent` generators and the generator-backed source-tree Quick Start. Step 15-10 implemented the automatically mounted Rails Engine, thin API controllers, a process-local Runtime that shares the in-memory Task Store across HTTP requests, and the Rails-facing SDK logging boundary. Step 15-9 implemented lazy Configuration and Agent Card generation. Step 15-8 wired `SendMessage`, `GetTask`, `ListTasks`, and `CancelTask` through the real SDK. Step 15-7 implemented the SDK-independent Task core. Step 15-6 implemented the Rails-facing Agent / Skill / Dispatcher API. Step 15-5 introduced the loadable Gem skeleton and Protocol Adapter. Step 15-4 verified the `agent2agent 2.0.0` SDK path across the supported Ruby / Rails matrix.
18
+
19
+ ## Development Progress
20
+
21
+ - [x] 1. Research A2A Protocol v1.0
22
+ - [x] 2. Research Ruby A2A SDKs / Gems
23
+ - [x] 3. Research Rails-oriented A2A alternatives
24
+ - [x] 4. Define the problem a2a-rails solves
25
+ - [x] 5. Define v0.1 scope
26
+ - [x] 6. Define terminology
27
+ - [x] 7. Define architecture
28
+ - [x] 8. Define Ruby SDK boundary
29
+ - [x] 9. Public API Design
30
+ - [x] 10. Agent Card Design
31
+ - [x] 11. Task Lifecycle Design
32
+ - [x] 12. Test Strategy
33
+ - [x] 13. Gem Structure
34
+ - [x] 14. Quick Start Design
35
+ - [ ] **15. Implementation / release preparation ← IN PROGRESS**
36
+ - [x] 15-4 SDK compatibility spike
37
+ - [x] 15-5 Gem skeleton + Protocol Adapter
38
+ - [x] 15-6 Agent / Skill DSL + Dispatcher
39
+ - [x] 15-7 Task core + MemoryStore
40
+ - [x] 15-8 Task operations through real SDK
41
+ - [x] 15-9 Configuration + Agent Card
42
+ - [x] 15-10 Rails Engine HTTP integration
43
+ - [x] 15-11 Generators + generated Quick Start
44
+ - [x] 15-12 Packaged-gem / release-readiness verification
45
+ - [x] 15-13 v0.1.0 release-candidate preparation
46
+ - [ ] 15-14 v0.1.0 release execution
47
+
48
+ ## v0.1 Direction
49
+
50
+ v0.1 is **server-first** and focuses on exposing a Rails application as an A2A Agent.
51
+
52
+ ```text
53
+ A2A Protocol
54
+ ↓
55
+ Ruby A2A SDK
56
+ ↓
57
+ a2a-rails
58
+ ↓
59
+ Rails Application
60
+ ↓
61
+ Business Logic
62
+ ```
63
+
64
+ Main principles:
65
+
66
+ - Do not reimplement the A2A Protocol.
67
+ - Focus on Rails integration.
68
+ - Keep SDK-specific APIs out of the public API.
69
+ - Prefer a small, non-streaming server scope for v0.1.
70
+ - Keep a2a-rails independent from ActingFor.
71
+
72
+ ## Quick Start
73
+
74
+ > The flow below is runtime-verified both from the repository source tree and from the built `a2a-rails-0.1.0` gem installed into a clean Rails application.
75
+
76
+ ### 1. Add and install
77
+
78
+ ```bash
79
+ bundle add a2a-rails
80
+ bin/rails generate a2a:rails:install
81
+ bin/rails generate a2a:rails:agent echo
82
+ mkdir -p app/services/echo
83
+ ```
84
+
85
+ `install` creates only:
86
+
87
+ ```text
88
+ config/initializers/a2a_rails.rb
89
+ ```
90
+
91
+ with:
92
+
93
+ ```ruby
94
+ A2A::Rails.configure do |config|
95
+ config.agent = "YourAgent"
96
+ config.public_base_url = ENV["A2A_PUBLIC_BASE_URL"]
97
+ end
98
+ ```
99
+
100
+ `agent echo` creates only:
101
+
102
+ ```text
103
+ app/agents/echo_agent.rb
104
+ ```
105
+
106
+ with:
107
+
108
+ ```ruby
109
+ class EchoAgent < A2A::Rails::Agent
110
+ name "Echo Agent"
111
+ description "TODO"
112
+ version "1.0"
113
+
114
+ # Add at least one skill.
115
+ end
116
+ ```
117
+
118
+ The generator deliberately does **not** create a Handler, route, controller, Task Store, job, migration, or registration side effect. It also does not reference a Handler that does not exist yet.
119
+
120
+ ### 2. Create the Handler
121
+
122
+ Create `app/services/echo/reply.rb`:
123
+
124
+ ```ruby
125
+ class Echo::Reply
126
+ def self.call(message:, context:)
127
+ text = message[:parts]
128
+ .filter_map { |part| part[:text] }
129
+ .join("\n")
130
+
131
+ "Echo: #{text}"
132
+ end
133
+ end
134
+ ```
135
+
136
+ ### 3. Define the Skill
137
+
138
+ Replace `app/agents/echo_agent.rb` with:
139
+
140
+ ```ruby
141
+ class EchoAgent < A2A::Rails::Agent
142
+ name "Echo Agent"
143
+ description "Echo messages"
144
+ version "1.0"
145
+
146
+ skill :reply,
147
+ description: "Echo a message",
148
+ tags: %w[echo],
149
+ handler: Echo::Reply
150
+ end
151
+ ```
152
+
153
+ A single Skill is selected automatically. No Router is required.
154
+
155
+ ### 4. Register the Agent
156
+
157
+ Replace `config/initializers/a2a_rails.rb` with:
158
+
159
+ ```ruby
160
+ A2A::Rails.configure do |config|
161
+ config.agent = "EchoAgent"
162
+ config.public_base_url = ENV["A2A_PUBLIC_BASE_URL"]
163
+ end
164
+ ```
165
+
166
+ For localhost, leave `A2A_PUBLIC_BASE_URL` unset or set it to `http://localhost:3000`. The Agent class name remains a String until an A2A endpoint resolves it, preserving Rails autoload / reload behavior.
167
+
168
+ No explicit Engine mount or host `config/routes.rb` change is required.
169
+
170
+ ### 5. Check the Agent Card
171
+
172
+ ```bash
173
+ bin/rails server
174
+ ```
175
+
176
+ ```bash
177
+ curl -sS http://localhost:3000/.well-known/agent-card.json \
178
+ -H "A2A-Version: 1.0"
179
+ ```
180
+
181
+ Expected essentials:
182
+
183
+ - HTTP 200
184
+ - Agent name `Echo Agent`
185
+ - Skill ID `reply`
186
+ - JSON-RPC A2A interface pointing to `http://localhost:3000/a2a`
187
+
188
+ ### 6. Send the first message
189
+
190
+ ```bash
191
+ curl -sS -X POST http://localhost:3000/a2a \
192
+ -H "Content-Type: application/json" \
193
+ -H "A2A-Version: 1.0" \
194
+ -d '{
195
+ "jsonrpc": "2.0",
196
+ "id": "1",
197
+ "method": "SendMessage",
198
+ "params": {
199
+ "message": {
200
+ "messageId": "msg-1",
201
+ "role": "ROLE_USER",
202
+ "parts": [{"text": "Hello"}]
203
+ }
204
+ }
205
+ }'
206
+ ```
207
+
208
+ Success means:
209
+
210
+ ```text
211
+ result.task.status.state == TASK_STATE_COMPLETED
212
+ Artifact Text Part == "Echo: Hello"
213
+ ```
214
+
215
+ See [the complete Quick Start design and verification notes](docs/design/quick-start.md).
216
+
217
+ ## Target Developer Experience
218
+
219
+ ```ruby
220
+ class ShoppingAgent < A2A::Rails::Agent
221
+ name "Shopping Agent"
222
+ description "Search and purchase products"
223
+ version "1.0"
224
+
225
+ skill :search_products,
226
+ description: "Search products",
227
+ tags: %w[shopping search],
228
+ handler: Shopping::SearchProducts
229
+ end
230
+ ```
231
+
232
+ Handler:
233
+
234
+ ```ruby
235
+ class Shopping::SearchProducts
236
+ def self.call(message:, context:)
237
+ # Rails business logic
238
+ end
239
+ end
240
+ ```
241
+
242
+ Registration:
243
+
244
+ ```ruby
245
+ A2A::Rails.configure do |config|
246
+ config.agent = "ShoppingAgent"
247
+ config.public_base_url = ENV["A2A_PUBLIC_BASE_URL"]
248
+ end
249
+ ```
250
+
251
+ v0.1 targets **one public A2A Agent per Rails application**. Handlers receive SDK-independent Ruby Hashes for `message` and `context`.
252
+
253
+ For multiple Skills, the application supplies a Router. The Router receives `skills:` as a frozen `Array<Symbol>` of declared Skill IDs and may return a matching Symbol or String. Unknown selections raise `A2A::Rails::UnknownSkillError`; the Dispatcher never silently chooses the first Skill.
254
+
255
+ ## Agent Card
256
+
257
+ The Gem automatically exposes:
258
+
259
+ ```text
260
+ GET /.well-known/agent-card.json
261
+ POST /a2a
262
+ ```
263
+
264
+ Agent Card behavior:
265
+
266
+ - generated from the Agent / Skill DSL;
267
+ - Skill IDs and default display names are generated from Skill declarations;
268
+ - optional `examples`, `input_modes`, and `output_modes` map to A2A Agent Card fields;
269
+ - Handler internals are never exposed;
270
+ - `public_base_url` wins when configured, otherwise the request base URL is used;
271
+ - default input/output mode is `text/plain`;
272
+ - Streaming, Push Notifications, and Extended Agent Cards are disabled for v0.1;
273
+ - generated Cards pass the real `agent2agent 2.0.0` Agent Card schema.
274
+
275
+ ## Task Lifecycle
276
+
277
+ Internally the Gem keeps SDK-independent Task states:
278
+
279
+ ```text
280
+ SUBMITTED
281
+ ↓
282
+ WORKING
283
+ ├──→ COMPLETED
284
+ ├──→ FAILED
285
+ └──→ REJECTED
286
+ ```
287
+
288
+ Cancellation can move a non-terminal Task to `CANCELED`.
289
+
290
+ Handler result mapping:
291
+
292
+ ```text
293
+ normal return → COMPLETED
294
+ A2A::Rails::RejectedTask → REJECTED
295
+ unexpected exception → FAILED
296
+ ```
297
+
298
+ Artifact mapping:
299
+
300
+ ```text
301
+ String → Text Part
302
+ Hash / Array → Data Part
303
+ nil → no Artifact
304
+ other object → ArtifactMappingError
305
+ ```
306
+
307
+ v0.1 Task behavior:
308
+
309
+ - server-generated Task IDs;
310
+ - client Context ID preserved, otherwise server-generated;
311
+ - terminal states are immutable;
312
+ - thread-safe process-local `Task::MemoryStore` by default;
313
+ - `SendMessage`, `GetTask`, `ListTasks`, and `CancelTask` supported;
314
+ - `ListTasks` supports context/state/timestamp filters, stable newest-first ordering, page sizes 1–100, and opaque snapshot pagination;
315
+ - cancellation is atomic, but does not interrupt Handler execution or undo business side effects;
316
+ - v0.1 Handler execution accepts text Message Parts;
317
+ - continuing an existing Task via `message.taskId` is not supported;
318
+ - `INPUT_REQUIRED` and `AUTH_REQUIRED` are out of scope.
319
+
320
+ The default store is for development and simple synchronous workloads. Tasks and pagination cursors are process-local and are not durable across process restarts or shared between processes.
321
+
322
+ ## Rails Integration
323
+
324
+ Step 15-10 provides:
325
+
326
+ - an automatically mounted Rails Engine;
327
+ - thin `ActionController::API` controllers;
328
+ - `/.well-known/agent-card.json` and `/a2a` routes;
329
+ - lazy application Agent resolution;
330
+ - one process-local Runtime that shares the default Task Store across HTTP requests;
331
+ - request-derived Agent Card URL fallback;
332
+ - a logging boundary that suppresses the upstream SDK `A2A::Server::Triage` INFO log containing the full Rack environment while restoring prior Console logging state afterward.
333
+
334
+ ## Generators
335
+
336
+ Step 15-11 implements:
337
+
338
+ ```text
339
+ a2a:rails:install
340
+ a2a:rails:agent NAME
341
+ ```
342
+
343
+ Verified contract:
344
+
345
+ - `install` creates only `config/initializers/a2a_rails.rb`;
346
+ - `agent echo` creates only `app/agents/echo_agent.rb`;
347
+ - the Agent scaffold has no dangling Handler reference;
348
+ - the generated Agent is not automatically registered;
349
+ - namespace-based generator invocation reproduces the documented files;
350
+ - the generated Echo setup boots under Rails and completes a real A2A `SendMessage` request.
351
+
352
+ Step 15-12 verifies the same generator contract from the **built and installed gem**, in a clean Rails application outside the repository source checkout.
353
+
354
+ ## Packaged Gem Verification
355
+
356
+ Step 15-12 verifies the distribution artifact itself:
357
+
358
+ - `gem build a2a-rails.gemspec` produces `a2a-rails-0.1.0`;
359
+ - the package contains the Engine, generator classes, generator templates, and routes required at runtime;
360
+ - the clean app resolves `a2a-rails-0.1.0` from the installed RubyGems path, not from the repository checkout;
361
+ - actual `bin/rails generate` commands discover both generators;
362
+ - generated files match the documented scaffold contract;
363
+ - the clean app boots and serves the generated Agent Card;
364
+ - `SendMessage` completes with the Echo Artifact;
365
+ - Step 15-12 verified package SHA256: `09c55122c5d5e6cb5f9b735664d70b000f67d23dcaad9f4a8ff960dbe02dd410`.
366
+
367
+ Step 15-13 extends this verification to user-facing release files and RubyGems metadata. The final published artifact must still be rebuilt and hashed from the exact tagged release commit.
368
+
369
+ ## Release Candidate
370
+
371
+ Step 15-13 prepares, but does not publish, v0.1.0:
372
+
373
+ - [CHANGELOG](CHANGELOG.md)
374
+ - [v0.1.0 release notes](docs/release/v0.1.0.md)
375
+ - [v0.1.0 release checklist](docs/release/v0.1.0-checklist.md)
376
+
377
+ The gemspec publishes canonical links for source code, changelog, documentation, and issue tracking, and requires RubyGems MFA. `README.md`, `CHANGELOG.md`, and `LICENSE` are verified as package contents.
378
+
379
+ No `v0.1.0` tag, RubyGems publication, GitHub Release, or repository-visibility change is performed in Step 15-13.
380
+
381
+ ## Test Strategy
382
+
383
+ v0.1 uses **Minitest** with four layers:
384
+
385
+ ```text
386
+ 4. Protocol E2E / Smoke Tests
387
+ 3. Rails Integration Tests
388
+ 2. Adapter Contract Tests
389
+ 1. Core Unit Tests
390
+ ```
391
+
392
+ The current CI matrix covers:
393
+
394
+ - Gem: Ruby 3.3 / 3.4 / 4.0
395
+ - SDK spike: Ruby 3.3 / 3.4 / 4.0
396
+ - Rails: Ruby 3.3 / 3.4 / 4.0 × Rails 8.0 / 8.1
397
+ - Packaged gem: Ruby 3.4 + clean Rails 8.1 application
398
+
399
+ Current Step 15-13 result:
400
+
401
+ ```text
402
+ 13 / 13 CI jobs green
403
+ 70 tests
404
+ 240 assertions
405
+ 0 failures
406
+ 0 errors
407
+ 0 skips
408
+ ```
409
+
410
+ Known warning-enabled output from upstream `agent2agent 2.0.0` remains, including circular-require / indentation / URI-parser warnings. Those warnings are distinct from the Rack-environment INFO logging that a2a-rails suppresses at the Rails-facing adapter boundary.
411
+
412
+ ## Gem Structure
413
+
414
+ ```text
415
+ lib/a2a/rails/
416
+ ├── agent.rb
417
+ ├── skill.rb
418
+ ├── dispatcher.rb
419
+ ├── configuration.rb
420
+ ├── runtime.rb
421
+ ├── engine.rb
422
+ ├── agent_card/
423
+ ├── task/
424
+ └── protocol/
425
+
426
+ lib/generators/a2a/rails/
427
+ ├── install_generator.rb
428
+ ├── agent_generator.rb
429
+ └── templates/
430
+ ```
431
+
432
+ Key boundaries:
433
+
434
+ - Rails Engine / controllers / routes are only the Rails integration layer.
435
+ - SDK-specific behavior stays behind `Protocol::Adapter` / `Protocol::Agent2AgentAdapter`.
436
+ - A2A camelCase fields, `TASK_STATE_*`, SDK schema objects, and SDK errors stay in the Protocol layer.
437
+ - Agent / Handler application constants remain lazily resolved through Rails.
438
+ - ActiveRecord and ActiveJob are not runtime requirements.
439
+ - v0.1 targets Ruby `>= 3.3` and Rails `>= 8.0, < 8.2`.
440
+
441
+ Current main dependencies:
442
+
443
+ - `agent2agent ~> 2.0.0`
444
+ - `actionpack >= 8.0, < 8.2`
445
+ - `json < 3`
446
+ - `rack >= 3.0, < 4`
447
+ - `railties >= 8.0, < 8.2`
448
+
449
+ ## v0.1 Scope
450
+
451
+ Included:
452
+
453
+ - Rails integration
454
+ - `A2A::Rails::Agent`
455
+ - Skill DSL and Handler dispatch
456
+ - Agent Card generation
457
+ - `/.well-known/agent-card.json`
458
+ - `POST /a2a`
459
+ - Task lifecycle
460
+ - `GetTask`, `ListTasks`, `CancelTask`
461
+ - `A2A-Version: 1.0` validation
462
+ - in-memory Task Store
463
+ - Rails Engine / Routes
464
+ - Configuration
465
+ - `install` / `agent` generators
466
+ - Rails logging boundary
467
+ - test support
468
+
469
+ Not included in v0.1:
470
+
471
+ - A2A Client
472
+ - ActiveRecord Task Store
473
+ - ActiveJob Task execution
474
+ - SSE / BiDi Streaming
475
+ - Push Notifications
476
+ - gRPC
477
+ - Human-in-the-loop
478
+ - `INPUT_REQUIRED` / `AUTH_REQUIRED` flows
479
+ - Agent Registry / Marketplace
480
+ - OAuth Server
481
+ - Authorization Engine
482
+ - ActingFor integration
483
+ - Admin UI
484
+ - LLM Agent Framework
485
+ - Orchestration Framework
486
+
487
+ ## Design Documents
488
+
489
+ - [v0.1 Design Decisions](docs/design/v0.1-decisions.md)
490
+ - [v0.1 Test Strategy](docs/design/test-strategy.md)
491
+ - [v0.1 Gem Structure](docs/design/gem-structure.md)
492
+ - [v0.1 Quick Start Design](docs/design/quick-start.md)
493
+ - [Step 15 SDK compatibility findings](docs/design/sdk-compatibility-spike.md)
494
+
495
+ ## Release Documents
496
+
497
+ - [CHANGELOG](CHANGELOG.md)
498
+ - [v0.1.0 Release Notes](docs/release/v0.1.0.md)
499
+ - [v0.1.0 Release Checklist](docs/release/v0.1.0-checklist.md)
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module A2A
4
+ module Rails
5
+ class AgentCardsController < ApplicationController
6
+ def show
7
+ response.set_header("A2A-Version", Protocol::Agent2AgentAdapter::PROTOCOL_VERSION)
8
+ render json: A2A::Rails.runtime.agent_card(request_base_url: request.base_url)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module A2A
4
+ module Rails
5
+ class ApplicationController < ActionController::API
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module A2A
4
+ module Rails
5
+ class RequestsController < ApplicationController
6
+ def create
7
+ status, headers, body = A2A::Rails.runtime.call(
8
+ env: request.env,
9
+ request_base_url: request.base_url
10
+ )
11
+
12
+ self.status = status
13
+ headers.each { |name, value| response.set_header(name, value) }
14
+ self.response_body = body
15
+ end
16
+ end
17
+ end
18
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ A2A::Rails::Engine.routes.draw do
4
+ get "/.well-known/agent-card.json", to: "agent_cards#show", defaults: { format: :json }
5
+ post "/a2a", to: "requests#create"
6
+ end