datarobot_genai.dragent.frontends.a2a
a2a
A2A server helpers for DataRobot-hosted agents.
This module owns the A2A protocol layer: agent card construction, OAuth2
security scheme assembly, Cross-Application Access capability extensions,
and endpoint URL resolution. The FastAPI framework glue lives in
:mod:~datarobot_genai.dragent.frontends.fastapi.
DRAgentA2AStarletteApplication
Bases: A2AStarletteApplication
A2A server that gates public agent-card access on per-agent developer opt-in.
Unauthenticated access also depends on platform-level opt-in per cluster to route anonymous traffic to the agent; this class enforces only the agent-side policy once a request reaches the process.
Source code in datarobot_genai/dragent/frontends/a2a.py
DRAgentA2AFrontEndPluginWorker
Bases: A2AFrontEndPluginWorker
A2A worker with identity-keyed public cards and an authenticated extended card.
Source code in datarobot_genai/dragent/frontends/a2a.py
create_a2a_server
create_a2a_server(agent_card: AgentCard, agent_executor: NATWorkflowAgentExecutor, *, enable_unauthenticated_well_known_route: bool = False, redacted_agent_card_config: DRAgentA2ARedactedAgentCardConfig | None = None) -> DRAgentA2AStarletteApplication
Create an A2A server with identity-keyed public and extended agent cards.
Unauthenticated GET /.well-known/agent-card.json access requires opt-in
at two levels: platform administrators must enable unauthenticated routing
per cluster, and enable_unauthenticated_well_known_route must be set
in the agent's workflow.yaml. This method enforces the agent-side
flag only.
When the agent flag is disabled (default), unauthenticated callers receive
the generic 404 -- indistinguishable from a nonexistent agent, so the
refusal is not an existence oracle. When enabled, they receive a redacted
card, shaped by redacted_agent_card_config (e.g. its skills list is
empty unless redacted_agent_card_config.enable_skills opts in).
Authenticated callers always receive the full card. extended_agent_card
is also wired for agent/getAuthenticatedExtendedCard clients.
Source code in datarobot_genai/dragent/frontends/a2a.py
get_a2a_endpoint_url
Construct the A2A endpoint URL for the running server.
Three tiers, most specific first:
- Behind an Envoy API gateway (
DR_WORKLOAD_EXTERNAL_URL_HOSTandDR_WORKLOAD_EXTERNAL_URL_PREFIXare both injected), the gateway's own route is the only externally reachable one, so it wins in every hosting mode. - In a DataRobot deployment (
MLOPS_DEPLOYMENT_IDis set) or workload (WORKLOAD_ID), composes the platform URL fromDATAROBOT_PUBLIC_API_ENDPOINT/DATAROBOT_ENDPOINT. - Otherwise falls back to the local
http://{host}:{port}/a2a/URL.
mount_path is the suffix A2A is actually mounted under inside the container.
Every tier forwards the full prefixed path through to the app, so the suffix has
to appear in the advertised URL or clients would address a route that does not
exist. DRAgentA2AConfig never passes an empty mount_path (it rejects
mounting A2A at the application root), but this function stays a generic URL
composer rather than re-asserting that policy: an empty value here just yields
the tier's own base with a single trailing slash.
Source code in datarobot_genai/dragent/frontends/a2a.py
resolve_oauth_endpoints
async
Resolve (authorization_url, token_url) from an OAuth2ResourceServerConfig.
Uses OIDC discovery when discovery_url is set, otherwise derives from issuer_url.
Source code in datarobot_genai/dragent/frontends/a2a.py
build_oauth_flow_from_server_auth
async
build_oauth_flow_from_server_auth(server_auth: OAuth2ResourceServerConfig) -> tuple[AuthorizationCodeOAuthFlow, list[str]]
Build the authorization_code OAuth2 flow and scopes from a NAT server_auth config.
Source code in datarobot_genai/dragent/frontends/a2a.py
build_oauth_flow_from_cross_app_access
build_oauth_flow_from_cross_app_access(config: CrossApplicationAccessConfig) -> tuple[ClientCredentialsOAuthFlow, list[str]]
Build the client_credentials flow and scopes from a CrossApplicationAccessConfig.
Extracts the OpenAPI-standard fields (token_url, scopes) only.
Cross-Application Access extension parameters are handled separately by
:func:build_cross_app_capability_extension and MUST NOT appear here.
Source code in datarobot_genai/dragent/frontends/a2a.py
build_cross_app_capability_extension
Build the Cross-Application Access extension entry for capabilities.extensions.
Only extension-bound fields go in params; token_url and scopes
are intentionally omitted — they belong to OpenAPI securitySchemes.
Source code in datarobot_genai/dragent/frontends/a2a.py
build_internal_identity_extension
Build the internal identity extension for the current runtime, or None in local dev.
In a deployment container (MLOPS_DEPLOYMENT_ID) the params carry
deployment_id; in a workload container (WORKLOAD_ID) they carry
workload_id. Returns None when neither identity is present.
Source code in datarobot_genai/dragent/frontends/a2a.py
build_external_identity_extension
Build the external identity extension for catalog discovery.
Source code in datarobot_genai/dragent/frontends/a2a.py
build_default_bearer_security_schemes
build_default_bearer_security_schemes() -> tuple[dict[str, SecurityScheme], list[dict[str, list[str]]]]
Return the default HTTP Bearer scheme for agents without explicit OAuth config.
Source code in datarobot_genai/dragent/frontends/a2a.py
build_security_schemes
async
build_security_schemes(frontend_config: A2AFrontEndConfig, cross_app_access: CrossApplicationAccessConfig | None) -> tuple[dict[str, SecurityScheme], list[dict[str, list[str]]]]
Assemble A2A security schemes, merging up to two auth sources.
server_auth→ authorization_code flow.cross_app_access→ client_credentials flow.- Neither configured → HTTP Bearer scheme for DataRobot API tokens.
Always returns a populated securitySchemes map.
Source code in datarobot_genai/dragent/frontends/a2a.py
create_agent_card
async
create_agent_card(frontend_config: A2AFrontEndConfig, cross_app_access: CrossApplicationAccessConfig | None, skills: list[AgentSkill], external: DRAgentA2AExternalConfig | None = None, mount_path: str = A2A_MOUNT_PATH) -> AgentCard
Build an :class:~a2a.types.AgentCard for a DataRobot-hosted A2A agent.
When skills is empty, a single default skill is generated from
frontend_config.name / frontend_config.description.
mount_path must match where the A2A app is actually mounted, so the card's
url points at the live RPC endpoint rather than the default /a2a/.
Source code in datarobot_genai/dragent/frontends/a2a.py
redact_agent_card
Return a public-safe view of an agent card.
Strips advertised skills, unless include_skills opts back in, and removes
internal/external identity extensions while preserving auth and
cross-application-access metadata needed for anonymous discovery.