Skip to content

Commit 6c6b3ba

Browse files
authored
fix(packaging): stop the amd-gaia[agents] extra from downgrading the core wheel (#2262)
## Summary After `gaia init --profile npu`, running `gaia chat --device npu` failed with an install hint that couldn't work: `pip install "amd-gaia[agents]"` doesn't install the chat agent — it silently **downgrades amd-gaia from 0.22.0 to 0.20.0**. The `agents` extra named 15 `gaia-agent-*` wheels that aren't published to PyPI yet, and a declared-but-unsatisfiable extra makes the *whole* release unresolvable, so pip/uv backtrack to the newest older release that doesn't declare the extra at all. Every "agent not installed" error in the codebase pointed at this same broken pair of commands. This PR removes the broken extras and repoints every one of those messages — plus the `gaia init` completion banner, which was recommending `gaia chat` as a ready next step right after installing nothing that could run it — at the install path that actually resolves today: pulling the agent straight from this repo's `hub/agents/python/<id>/` subdirectory. The registry's discovery mechanism itself was already correct (verified against an isolated venv with `gaia-agent-chat` actually installed); the bug was entirely in the packaging metadata and the guidance text. Publishing the `gaia-agent-*` wheels to PyPI is a separate, deliberately-paused decision (`.github/workflows/publish_agents.yml`, tracked by #1179/#1513) — out of scope here. ## Test plan - [x] `python util/lint.py --all` — clean (pre-existing mypy/bandit warnings only) - [x] `tests/unit/test_packaging.py::TestAgentWheelExtras` — new regression guard; fails against the old `setup.py`, passes against the fix - [x] `tests/unit/agents/test_install_hints.py` — new; asserts no message recommends the broken commands and every source-install path exists on disk - [x] `tests/unit/test_agent_pypi_publish.py`, `tests/unit/test_publish_agents_to_hub.py` — publish-matrix discovery still resolves via the new `AGENT_WHEEL_PACKAGES` list - [x] `tests/unit/agents/test_registry.py` (48 tests) — run against an isolated venv with `gaia-agent-chat` actually installed; registry correctly discovers `chat`/`doc`/`file`. Wired into `test_chat_agent.yml` so this stops silently skipping in CI. - [x] `tests/unit/` full suite — 6458 passed, 151 skipped, 8 pre-existing failures unrelated to this change (confirmed identical via `git stash`) - [x] Manual repro: `gaia chat` now prints the working `uv pip install "gaia-agent-chat @ git+...#subdirectory=hub/agents/python/chat"` command instead of the broken one
1 parent 8744a51 commit 6c6b3ba

27 files changed

Lines changed: 497 additions & 157 deletions

.github/workflows/publish_agents.yml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
#
44
# Publish the AMD production *Python* agent wheels (gaia-agent-<id>) to PyPI.
55
# Issue #1179 (Agent Hub dual distribution): R2 is the canonical source for the
6-
# Hub UI; PyPI is the canonical source for `pip install gaia-agent-<id>` and the
7-
# `amd-gaia[agents]` meta-extra. The C++ agent binaries are handled separately
8-
# by build_agents.yml.
6+
# Hub UI; PyPI is the canonical source for `pip install gaia-agent-<id>`. The
7+
# C++ agent binaries are handled separately by build_agents.yml.
8+
#
9+
# NOTE (#2240): there is deliberately no `amd-gaia[agents]` meta-extra. While
10+
# these wheels aren't live on PyPI (publishing is paused below), declaring
11+
# them as an extras_require entry made the extra unsatisfiable at the
12+
# current amd-gaia release, which made pip/uv silently backtrack-downgrade
13+
# to an older release that didn't declare it. The agent list instead lives
14+
# as a plain constant, setup.py's AGENT_WHEEL_PACKAGES.
915
#
1016
# Flow:
11-
# discover (read setup.py[agents] -> matrix)
17+
# discover (read setup.py's AGENT_WHEEL_PACKAGES -> matrix)
1218
# -> build (tag only: build each wheel + twine check, upload artifact)
1319
# -> approve (tag only: single manual gate, "publish" environment)
1420
# -> publish (tag only: gh-action-pypi-publish per agent, skip-existing)
@@ -54,9 +60,9 @@ permissions:
5460

5561
jobs:
5662

57-
# ── Discover: derive the agent matrix from setup.py[agents] ──────────
58-
# Single source of truth — adding an agent to the meta-extra auto-includes
59-
# it here. No hand-maintained second list to drift.
63+
# ── Discover: derive the agent matrix from setup.py's AGENT_WHEEL_PACKAGES ──
64+
# Single source of truth — adding an agent to that list auto-includes it
65+
# here. No hand-maintained second list to drift.
6066
discover:
6167
name: Discover Agent Packages
6268
runs-on: ubuntu-latest

.github/workflows/test_chat_agent.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,21 @@ jobs:
8484
echo ""
8585
python -m pytest hub/agents/python/chat/tests/ -v --tb=short
8686
87+
- name: Run Framework Registry Discovery Tests
88+
env:
89+
GAIA_MEMORY_DISABLED: "1"
90+
run: |
91+
echo "================================================================"
92+
echo " FRAMEWORK REGISTRY DISCOVERY TESTS"
93+
echo "================================================================"
94+
# tests/unit/agents/test_registry.py::TestBuiltinRegistration has
95+
# chat-specific cases that importorskip("gaia_agent_chat") -- this
96+
# is the only CI job that installs that wheel, so it's the only
97+
# place these actually run instead of silently skipping (#2240).
98+
echo "Verifying AgentRegistry actually resolves the installed gaia-agent-chat wheel..."
99+
echo ""
100+
python -m pytest tests/unit/agents/test_registry.py -v --tb=short
101+
87102
- name: Run Chat Agent Unit Tests
88103
env:
89104
# Skip memory init — Lemonade isn't available in this CI job; the

docs/reference/cli.mdx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,16 @@ pip install gaia-agent-summarize # one agent
539539
pip install "amd-gaia[agents]" # every AMD production agent
540540
```
541541

542+
<Note>
543+
PyPI publishing for `gaia-agent-*` wheels is currently paused (tracked by
544+
[#2240](https://github.com/amd/gaia/issues/2240)), so the commands above don't
545+
resolve yet. Until publishing lands, install an agent straight from this repo:
546+
547+
```bash From source (works today)
548+
uv pip install "gaia-agent-summarize @ git+https://github.com/amd/gaia.git#subdirectory=hub/agents/python/summarize"
549+
```
550+
</Note>
551+
542552
The **Hub (R2)** path is the Agent UI's discover/install panel, which downloads
543553
the wheel from R2 into `~/.gaia/agents/<id>/` (`POST /api/agents/install`, backed
544554
by `gaia.hub.installer`). Use it when browsing the Hub UI; use `pip install` for

hub/agents/python/chat/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ framework wheel.
88
## Install
99

1010
```bash
11-
pip install gaia-agent-chat # from PyPI (once published)
11+
pip install gaia-agent-chat # from PyPI (once published — see #2240)
1212
pip install -e hub/agents/python/chat # editable, for development
13+
uv pip install "gaia-agent-chat @ git+https://github.com/amd/gaia.git#subdirectory=hub/agents/python/chat" # works today without a repo checkout
1314
```
1415

1516
Installing registers the `chat`, `doc`, and `file` agents via the `gaia.agent`

hub/agents/python/routing/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ importable so the API server can resolve it.
1414
## Install
1515

1616
```bash
17-
pip install gaia-agent-routing # from PyPI (once published)
17+
pip install gaia-agent-routing # from PyPI (once published — see #2240)
1818
pip install -e hub/agents/python/routing # editable, for development
19+
uv pip install "gaia-agent-routing @ git+https://github.com/amd/gaia.git#subdirectory=hub/agents/python/routing" # works today without a repo checkout
1920
```
2021

2122
The API server's `gaia-code` model routes through `RoutingAgent`, which in turn
22-
needs the `gaia-agent-code` wheel installed. Install both (or
23-
`pip install amd-gaia[agents]`) to use `gaia api` for code generation.
23+
needs the `gaia-agent-code` wheel installed. Install both the same way (swap
24+
`routing` for `code` in the subdirectory) to use `gaia api` for code
25+
generation.
2426

2527
## Develop / test
2628

hub/agents/python/routing/gaia_agent_routing/agent.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import Any, Dict, List, Optional
88

99
from gaia.agents.base.agent import Agent
10+
from gaia.agents.install_hints import agent_not_installed_message
1011
from gaia.llm import create_client
1112
from gaia.logger import get_logger
1213

@@ -490,11 +491,13 @@ def _build_code_agent(self, language: str, project_type: str) -> Agent:
490491
registry.discover()
491492
if registry.get("code") is None:
492493
raise RuntimeError(
493-
"CodeAgent is not installed. RoutingAgent routes coding tasks "
494-
"to the 'gaia-agent-code' package, which is not present. "
495-
"Install it with 'uv pip install gaia-agent-code' (or "
496-
"'uv pip install \"amd-gaia[agents]\"'), then retry. See "
497-
"docs/spec/agent-hub-restructure.mdx."
494+
agent_not_installed_message(
495+
"CodeAgent is not installed. RoutingAgent routes coding "
496+
"tasks to the 'gaia-agent-code' package, which is not "
497+
"present",
498+
"gaia-agent-code",
499+
next_step=("Then retry. See docs/spec/agent-hub-restructure.mdx."),
500+
)
498501
)
499502

500503
# Build agent kwargs, including output_handler if provided

setup.py

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,37 @@
1414

1515
tkml_version = "5.0.4"
1616

17+
# Standalone AMD production agent wheels (issues #1102, #1179). Each ships as
18+
# a separate 'gaia-agent-<id>' PyPI package depending on this framework
19+
# wheel. Deliberately NOT an extras_require entry: this list is read
20+
# statically by util/list_agent_packages.py (single source of truth for
21+
# .github/workflows/publish_agents.yml's build/publish matrix and
22+
# tests/unit/test_agent_pypi_publish.py) without ever being handed to pip's
23+
# resolver. An extras_require entry naming these packages made 'pip install
24+
# "amd-gaia[agents]"' unsatisfiable while the wheels are unpublished
25+
# (publish_agents.yml's publish job is paused), which made the resolver
26+
# silently downgrade amd-gaia itself to the newest release that didn't
27+
# declare the extra (#2240) -- see setup.py history / PR fixing #2240 for
28+
# the incident. Do not move this back into extras_require until the wheels
29+
# are live on PyPI.
30+
AGENT_WHEEL_PACKAGES = [
31+
"gaia-agent-summarize",
32+
"gaia-agent-sd",
33+
"gaia-agent-fileio",
34+
"gaia-agent-docker",
35+
"gaia-agent-jira",
36+
"gaia-agent-blender",
37+
"gaia-agent-emr",
38+
"gaia-agent-code",
39+
"gaia-agent-connectors-demo",
40+
"gaia-agent-analyst",
41+
"gaia-agent-browser",
42+
"gaia-agent-docqa",
43+
"gaia-agent-routing",
44+
"gaia-agent-email",
45+
"gaia-agent-chat",
46+
]
47+
1748
setup(
1849
name="amd-gaia",
1950
version=gaia_version,
@@ -270,42 +301,12 @@
270301
"build>=1.0.0",
271302
"twine>=5.0.0",
272303
],
273-
# Standalone AMD production agents (issues #1102, #1179). Each agent
274-
# ships as a separate 'gaia-agent-<id>' wheel that depends on this
275-
# framework wheel; 'amd-gaia[agents]' installs all migrated agents at
276-
# once. Add an entry here when each agent's wheel is first published.
277-
"agent-summarize": ["gaia-agent-summarize"],
278-
"agent-sd": ["gaia-agent-sd"],
279-
"agent-fileio": ["gaia-agent-fileio"],
280-
"agent-docker": ["gaia-agent-docker"],
281-
"agent-jira": ["gaia-agent-jira"],
282-
"agent-blender": ["gaia-agent-blender"],
283-
"agent-emr": ["gaia-agent-emr"],
284-
"agent-code": ["gaia-agent-code"],
285-
"agent-connectors-demo": ["gaia-agent-connectors-demo"],
286-
"agent-analyst": ["gaia-agent-analyst"],
287-
"agent-browser": ["gaia-agent-browser"],
288-
"agent-docqa": ["gaia-agent-docqa"],
289-
"agent-routing": ["gaia-agent-routing"],
290-
"agent-email": ["gaia-agent-email"],
291-
"agent-chat": ["gaia-agent-chat"],
292-
"agents": [
293-
"gaia-agent-summarize",
294-
"gaia-agent-sd",
295-
"gaia-agent-fileio",
296-
"gaia-agent-docker",
297-
"gaia-agent-jira",
298-
"gaia-agent-blender",
299-
"gaia-agent-emr",
300-
"gaia-agent-code",
301-
"gaia-agent-connectors-demo",
302-
"gaia-agent-analyst",
303-
"gaia-agent-browser",
304-
"gaia-agent-docqa",
305-
"gaia-agent-routing",
306-
"gaia-agent-email",
307-
"gaia-agent-chat",
308-
],
304+
# NOTE: no 'agent-<id>' / 'agents' extras here -- see
305+
# AGENT_WHEEL_PACKAGES above for why (#2240) and where that list
306+
# actually lives now. Install an agent from source until the wheels
307+
# are published:
308+
# uv pip install "gaia-agent-<id> @ git+https://github.com/amd/gaia.git#subdirectory=hub/agents/python/<id>"
309+
# (see gaia.agents.install_hints.source_install_command).
309310
},
310311
classifiers=[
311312
"Development Status :: 4 - Beta",

src/gaia/agents/install_hints.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
2+
# SPDX-License-Identifier: MIT
3+
"""Shared "agent wheel not installed" messaging.
4+
5+
The ``gaia-agent-*`` wheels (chat, email, code, sd, docker, ...) are built
6+
and packaged (``hub/agents/python/<id>/``) but publishing them to PyPI is
7+
still paused (see ``.github/workflows/publish_agents.yml``, tracked by
8+
#1179 / #1513). Until that lands, ``pip install gaia-agent-<id>`` and
9+
``pip install "amd-gaia[agents]"`` both fail on a clean environment (#2240)
10+
-- so every call site that used to recommend them needs to point at the one
11+
install path that actually resolves today: pip installing straight from the
12+
package's subdirectory in this repo.
13+
"""
14+
15+
# hub/agents/python/<subdir> for each wheel this module has a hint for. Keep
16+
# in sync with the directories under hub/agents/python/ (ls hub/agents/python/).
17+
_AGENT_SOURCE_SUBDIRS = {
18+
"gaia-agent-analyst": "analyst",
19+
"gaia-agent-blender": "blender",
20+
"gaia-agent-browser": "browser",
21+
"gaia-agent-chat": "chat",
22+
"gaia-agent-code": "code",
23+
"gaia-agent-connectors-demo": "connectors-demo",
24+
"gaia-agent-docker": "docker",
25+
"gaia-agent-docqa": "docqa",
26+
"gaia-agent-email": "email",
27+
"gaia-agent-emr": "emr",
28+
"gaia-agent-fileio": "fileio",
29+
"gaia-agent-jira": "jira",
30+
"gaia-agent-routing": "routing",
31+
"gaia-agent-sd": "sd",
32+
"gaia-agent-summarize": "summarize",
33+
}
34+
35+
_REPO_URL = "https://github.com/amd/gaia.git"
36+
37+
38+
def source_install_command(wheel: str) -> str:
39+
"""Return the pip command that installs ``wheel`` straight from source.
40+
41+
Raises ``KeyError`` if ``wheel`` isn't a known ``gaia-agent-*`` package --
42+
that's a bug at the call site (a typo'd wheel name), not a runtime
43+
condition to swallow.
44+
"""
45+
subdir = _AGENT_SOURCE_SUBDIRS[wheel]
46+
return (
47+
f'uv pip install "{wheel} @ git+{_REPO_URL}#subdirectory='
48+
f'hub/agents/python/{subdir}"'
49+
)
50+
51+
52+
def agent_not_installed_message(
53+
subject: str, wheel: str, *, next_step: str = ""
54+
) -> str:
55+
"""Build the standard "agent not installed" error text for ``wheel``.
56+
57+
``subject`` is the complete first sentence, without a trailing period,
58+
e.g. ``"The chat agent is not installed"`` or ``"The drafting eval needs
59+
the email agent"``. ``next_step`` is an optional trailing instruction,
60+
e.g. ``"Then re-run `gaia chat`."``.
61+
62+
The ``gaia-agent-*`` wheels aren't on PyPI yet (#2240), so this
63+
deliberately does NOT recommend ``pip install gaia-agent-<id>`` or
64+
``pip install "amd-gaia[agents]"`` -- both fail on a clean environment.
65+
It points at the verified working install instead: pip installing
66+
straight from this repo's subdirectory.
67+
"""
68+
command = source_install_command(wheel)
69+
message = (
70+
f"{subject}. The `{wheel}` package isn't published yet "
71+
f"(see https://github.com/amd/gaia/issues/2240); install it from "
72+
f"source instead:\n`{command}`"
73+
)
74+
if next_step:
75+
message = f"{message} {next_step}"
76+
return message

src/gaia/api/agent_registry.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from gaia.agents.base.agent import Agent
2323
from gaia.agents.base.api_agent import ApiAgent
24+
from gaia.agents.install_hints import source_install_command
2425
from gaia.api.sse_handler import SSEOutputHandler
2526

2627
logger = logging.getLogger(__name__)
@@ -164,9 +165,10 @@ def get_agent(self, model_id: str) -> Agent:
164165
# an install hint rather than degrading silently.
165166
hint = (
166167
" The 'gaia-code' model routes through RoutingAgent, which "
167-
"ships as the 'gaia-agent-routing' wheel. Install it with "
168-
"'pip install gaia-agent-routing gaia-agent-code' (or "
169-
"'pip install amd-gaia[agents]'). See "
168+
"ships as the 'gaia-agent-routing' wheel. Neither it nor "
169+
"'gaia-agent-code' is published yet (#2240); install both "
170+
f"from source: '{source_install_command('gaia-agent-routing')}' "
171+
f"and '{source_install_command('gaia-agent-code')}'. See "
170172
"docs/spec/agent-hub-restructure.mdx."
171173
)
172174
raise ValueError(f"Agent {model_id} not available: {e}.{hint}") from e

src/gaia/apps/docker/app.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
from dataclasses import dataclass
1616
from typing import Any, Optional
1717

18+
from gaia.agents.install_hints import agent_not_installed_message
19+
1820
logger = logging.getLogger(__name__)
1921

2022

@@ -28,9 +30,11 @@ def _load_docker_agent():
2830
from gaia_agent_docker.agent import DEFAULT_MODEL, DockerAgent
2931
except ImportError as e:
3032
raise ImportError(
31-
"The docker agent is not installed. Install it with "
32-
'`uv pip install gaia-agent-docker` (or `uv pip install "amd-gaia[agents]"` '
33-
"for all AMD agents). See https://amd-gaia.ai/docs/guides/docker."
33+
agent_not_installed_message(
34+
"The docker agent is not installed",
35+
"gaia-agent-docker",
36+
next_step="See https://amd-gaia.ai/docs/guides/docker.",
37+
)
3438
) from e
3539
return DockerAgent, DEFAULT_MODEL
3640

0 commit comments

Comments
 (0)