fix(a2a): declare a2a-sdk[http-server] so the a2a extra can serve - #6671
Open
arunpshankar wants to merge 1 commit into
Open
fix(a2a): declare a2a-sdk[http-server] so the a2a extra can serve#6671arunpshankar wants to merge 1 commit into
arunpshankar wants to merge 1 commit into
Conversation
The `a2a` extra installs `a2a-sdk` with no extras, which is enough to
import the package but not to run the server. `sse-starlette` is only
declared under a2a-sdk's `http-server`, `fastapi` and `all` extras, and
every server dispatcher imports it at module level:
a2a.server.routes.jsonrpc_dispatcher
a2a.server.routes.rest_dispatcher
a2a.compat.v0_3.jsonrpc_adapter
`to_a2a()` builds an `A2AStarletteApplication`, which routes through the
first of these, so a clean install of `google-adk[a2a]` raises
ModuleNotFoundError: No module named 'sse_starlette' at startup.
This is invisible during development because `mcp` requires
sse-starlette, so any environment that has ever installed the `mcp`
extra already satisfies it by accident. It surfaces on the first clean
install - typically a container - and the runtime reports a failed
startup probe on the port rather than the missing module.
Repro, from an empty venv:
pip install "a2a-sdk>=0.3.4,<2" # what the a2a extra installs
python -c "import a2a.server.routes.jsonrpc_dispatcher"
# ModuleNotFoundError: No module named 'sse_starlette'
pip install "a2a-sdk[http-server]>=0.3.4,<2"
python -c "import a2a.server.routes.jsonrpc_dispatcher" # ok
`http-server` rather than a direct `sse-starlette` pin because it states
the intent - ADK serves the A2A HTTP application - and leaves the
transitive set to a2a-sdk. The extra exists at the pinned floor (0.3.4)
and carries sse-starlette through the current 1.1.2, so it holds across
the whole `>=0.3.4,<2` range.
This is not the lazy-import case: the import is inside a2a-sdk, and it
is needed to serve, not merely to import. It also leaves
test_constructing_agent_defers_optional_mcp_server_stack unaffected -
that asserts sse_starlette is not imported when constructing an Agent,
which installing it does not change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to Issue or Description of Change
No existing issue.
Problem:
The
a2aextra installsa2a-sdkwith no extras. That is enough toimport the package but not to run the server:
sse-starletteis declaredonly under a2a-sdk's
http-server,fastapiandallextras, and everyserver dispatcher imports it at module level.
to_a2a()builds anA2AStarletteApplication, which routes througha2a.server.routes.jsonrpc_dispatcher, so a clean install ofgoogle-adk[a2a]fails at startup with:This stays invisible during development because
mcprequiressse-starlette, so any environment that has ever installed the
mcpextraalready satisfies it by accident. It surfaces on the first genuinely
clean install — typically a container — and the runtime then reports a
failed startup probe on the port rather than the missing module, which
sends you looking at networking instead of packaging.
Solution:
Declare
a2a-sdk[http-server]in thea2aextra.http-serverrather than a directsse-starlettepin because it statesthe intent — ADK serves the A2A HTTP application — and leaves the
transitive set to a2a-sdk to decide. The extra exists at the pinned floor
(0.3.4) and carries sse-starlette through the current 1.1.2, so it holds
across the whole
>=0.3.4,<2range.This is not the lazy-import case that some earlier dependency reports
turned out to be: the import lives inside a2a-sdk rather than in ADK, and
it is needed to serve, not merely to import.
Testing Plan
Unit Tests:
No unit test is added, and I want to be explicit about why rather than
add a token one: this is an install-time property, and CI installs the
extras it needs, so the failure is not observable from inside a test
session that can already import the module. Happy to add one if you would
like it — the natural home looks like the packaging-adjacent checks in
tests/unittests/test_import_loading.py.That file's
test_constructing_agent_defers_optional_mcp_server_stackasserts
sse_starletteis not imported when constructing anAgent.This change does not affect it: installing a package does not import it.
Manual End-to-End (E2E) Tests:
From an empty virtualenv, installing exactly what the
a2aextrainstalls today:
With this change:
pyproject-fmt==2.24.0, the version pinned in.pre-commit-config.yaml,reports
no change for pyproject.toml.Checklist