Skip to content

Commit 7563f30

Browse files
committed
fix: Move a2a global discovery path
1 parent 6c5001b commit 7563f30

File tree

9 files changed

+33
-20
lines changed

9 files changed

+33
-20
lines changed

server/a2a/handler.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,27 @@ func (h *Handler) Rebuild(agents []store.AgentDefinition, flows []store.FlowDefi
112112
h.mu.Unlock()
113113
}
114114

115-
func (h *Handler) ServeAgentCard(w http.ResponseWriter, r *http.Request) {
115+
const a2aPrefix = "/api/v1/a2a/"
116+
const wellKnownSuffix = "/.well-known/agent-card.json"
117+
118+
func (h *Handler) ServeA2A(w http.ResponseWriter, r *http.Request) {
119+
path := r.URL.Path
120+
rest := strings.TrimPrefix(path, a2aPrefix)
121+
122+
if rest == ".well-known/agent-card.json" {
123+
h.serveGlobalCards(w, r)
124+
return
125+
}
126+
127+
if strings.HasSuffix(path, wellKnownSuffix) {
128+
h.servePerAgentCard(w, r)
129+
return
130+
}
131+
132+
h.serveJSONRPC(w, r)
133+
}
134+
135+
func (h *Handler) serveGlobalCards(w http.ResponseWriter, r *http.Request) {
116136
agentID := r.URL.Query().Get("agent")
117137

118138
h.mu.RLock()
@@ -140,8 +160,8 @@ func (h *Handler) ServeAgentCard(w http.ResponseWriter, r *http.Request) {
140160
json.NewEncoder(w).Encode(cardList)
141161
}
142162

143-
func (h *Handler) ServePerAgentCard(w http.ResponseWriter, r *http.Request) {
144-
agentID := extractAgentID(r.URL.Path, "/api/v1/a2a/", "/.well-known/agent-card.json")
163+
func (h *Handler) servePerAgentCard(w http.ResponseWriter, r *http.Request) {
164+
agentID := extractAgentID(r.URL.Path, a2aPrefix, wellKnownSuffix)
145165

146166
h.mu.RLock()
147167
card, ok := h.cards[agentID]
@@ -157,13 +177,8 @@ func (h *Handler) ServePerAgentCard(w http.ResponseWriter, r *http.Request) {
157177
json.NewEncoder(w).Encode(card)
158178
}
159179

160-
func (h *Handler) ServeJSONRPC(w http.ResponseWriter, r *http.Request) {
161-
if strings.HasSuffix(r.URL.Path, "/.well-known/agent-card.json") {
162-
h.ServePerAgentCard(w, r)
163-
return
164-
}
165-
166-
agentID := extractAgentID(r.URL.Path, "/api/v1/a2a/", "")
180+
func (h *Handler) serveJSONRPC(w http.ResponseWriter, r *http.Request) {
181+
agentID := extractAgentID(r.URL.Path, a2aPrefix, "")
167182

168183
h.mu.RLock()
169184
handler, ok := h.handlers[agentID]

server/api/user/a2a_swagger.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ type A2AJSONRPCResponse struct {
5656
// @Produce json
5757
// @Param agent query string false "Filter by agent ID. When provided, returns a single card object instead of an array." example(home-assistant)
5858
// @Success 200 {array} A2AAgentCard "List of agent cards (or single card object when ?agent= is used)"
59-
// @Router /.well-known/agent-card.json [get]
59+
// @Router /a2a/.well-known/agent-card.json [get]
6060
func (h *Handler) A2AListCards() {}
6161

6262
// A2APerAgentCard returns the agent card for a specific agent.

server/api/user/docs/userapi_docs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const docTemplateuserapi = `{
1515
"host": "{{.Host}}",
1616
"basePath": "{{.BasePath}}",
1717
"paths": {
18-
"/.well-known/agent-card.json": {
18+
"/a2a/.well-known/agent-card.json": {
1919
"get": {
2020
"description": "Returns agent cards for all agents that have A2A enabled. Each card describes the agent's identity, capabilities, skills, and security requirements following the A2A protocol specification.",
2121
"produces": [

server/api/user/docs/userapi_swagger.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"host": "localhost:8080",
1313
"basePath": "/api/v1",
1414
"paths": {
15-
"/.well-known/agent-card.json": {
15+
"/a2a/.well-known/agent-card.json": {
1616
"get": {
1717
"description": "Returns agent cards for all agents that have A2A enabled. Each card describes the agent's identity, capabilities, skills, and security requirements following the A2A protocol specification.",
1818
"produces": [

server/api/user/docs/userapi_swagger.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ info:
167167
title: Magec User API
168168
version: "1.0"
169169
paths:
170-
/.well-known/agent-card.json:
170+
/a2a/.well-known/agent-card.json:
171171
get:
172172
description: Returns agent cards for all agents that have A2A enabled. Each
173173
card describes the agent's identity, capabilities, skills, and security requirements

server/main.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,8 @@ func main() {
172172
httpMux.Handle("/api/v1/agent/", userRecorded)
173173
httpMux.Handle("/api/v1/voice/", newVoiceHandler(dataStore, agentRouter))
174174

175-
// A2A protocol endpoints (per-agent card + JSON-RPC invoke)
176-
httpMux.HandleFunc("/.well-known/agent-card.json", a2aHandler.ServeAgentCard)
177-
httpMux.HandleFunc("/api/v1/a2a/", a2aHandler.ServeJSONRPC)
175+
// A2A protocol endpoints (global discovery + per-agent card + JSON-RPC invoke)
176+
httpMux.HandleFunc("/api/v1/a2a/", a2aHandler.ServeA2A)
178177

179178
userAPI := user.New(dataStore)
180179
httpMux.HandleFunc("/api/v1/health", userAPI.Health)

server/middleware/middleware.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ func ClientAuth(next http.Handler, dataStore *store.Store) http.Handler {
4545
if r.Method == http.MethodOptions ||
4646
path == "/api/v1/health" ||
4747
path == "/api/v1/voice/events" ||
48-
path == "/.well-known/agent-card.json" ||
4948
(strings.HasPrefix(path, "/api/v1/a2a/") && strings.HasSuffix(path, "/.well-known/agent-card.json")) ||
5049
strings.HasPrefix(path, "/api/v1/webhooks/") ||
5150
!strings.HasPrefix(path, "/api/") {

website/content/docs/a2a.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ That's it. The agent is now discoverable and invocable via A2A.
3838

3939
| Endpoint | Auth | Description |
4040
|----------|------|-------------|
41-
| `/.well-known/agent-card.json` | No | Lists all A2A-enabled agents |
41+
| `/api/v1/a2a/.well-known/agent-card.json` | No | Lists all A2A-enabled agents |
4242
| `/api/v1/a2a/{agentId}/.well-known/agent-card.json` | No | Agent card for a specific agent |
4343
| `/api/v1/a2a/{agentId}` | Bearer token | JSON-RPC invocation endpoint |
4444

website/public/docs/a2a/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ <h2 id="endpoints">Endpoints</h2>
184184
</thead>
185185
<tbody>
186186
<tr>
187-
<td><code>/.well-known/agent-card.json</code></td>
187+
<td><code>/api/v1/a2a/.well-known/agent-card.json</code></td>
188188
<td>No</td>
189189
<td>Lists all A2A-enabled agents</td>
190190
</tr>

0 commit comments

Comments
 (0)