A2A Protocol

This commit is contained in:
2026-10-21 08:23:55 -03:00
parent b08affa48c
commit 3765c3f43a
32 changed files with 2141 additions and 12 deletions

View File

@@ -219,6 +219,10 @@ import asyncio
@app.get("/gateway/events/{session_id:path}")
async def gateway_events(session_id: str):
existing = await session_store.get(session_id)
if existing and existing.active_backend and registry.get(existing.active_backend).protocol == "a2a":
raise HTTPException(status_code=409, detail="A2A backend: use message/send; native event proxy is unavailable")
async def stream():
yield (
"event: connected\n"
@@ -250,6 +254,9 @@ async def gateway_events(session_id: str):
return
backend = registry.get(backend_id)
if backend.protocol == "a2a":
yield 'event: error\ndata: {"message":"Native event proxy is unavailable for A2A backends"}\n\n'
return
backend_base_url = (
getattr(backend, "base_url", None)
@@ -325,4 +332,17 @@ async def gateway_events(session_id: str):
"Connection": "keep-alive",
"X-Accel-Buffering": "no",
},
)
)
# Opt-in: existing deployments do not import or require the A2A SDK.
if settings.ENABLE_A2A:
from agent_framework.a2a.server import install_a2a
async def _a2a_gateway_handler(data: dict):
return await gateway_message(GatewayRequest(**data))
install_a2a(
app, _a2a_gateway_handler, registry, settings.A2A_PUBLIC_URL,
settings.A2A_SECURITY_SCHEMES or None, settings.A2A_SECURITY or None,
task_mode=settings.A2A_TASK_MODE, timeout_seconds=settings.A2A_TASK_TIMEOUT_SECONDS,
)

View File

@@ -3,6 +3,7 @@ from __future__ import annotations
from functools import lru_cache
from typing import Literal
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -16,6 +17,13 @@ class GatewaySettings(BaseSettings):
API_PORT: int = 8010
CORS_ORIGINS: str = "http://localhost:5173"
ENABLE_A2A: bool = False
A2A_TASK_MODE: bool = True
A2A_TASK_TIMEOUT_SECONDS: float = Field(default=120.0, gt=0)
A2A_PUBLIC_URL: str = "http://localhost:8010"
A2A_SECURITY_SCHEMES: dict = Field(default_factory=dict)
A2A_SECURITY: list[dict[str, list[str]]] = Field(default_factory=list)
BACKENDS_CONFIG_PATH: str = "./config/backends.yaml"
GLOBAL_ROUTING_MODE: Literal["router", "supervisor", "hybrid"] = "hybrid"
GLOBAL_KEEP_ACTIVE_BACKEND: bool = True