Skip to content

refactor(agents): migrate docqa + routing to hub (#1102)#1455

Open
kovtcharov-amd wants to merge 6 commits into
mainfrom
claudia/task-8fa7ecef
Open

refactor(agents): migrate docqa + routing to hub (#1102)#1455
kovtcharov-amd wants to merge 6 commits into
mainfrom
claudia/task-8fa7ecef

Conversation

@kovtcharov-amd

Copy link
Copy Markdown
Collaborator

Why this matters

DocumentQAAgent and RoutingAgent were the last two agents still living in the core source tree under src/gaia/agents/. They now ship as standalone gaia-agent-docqa / gaia-agent-routing wheels under hub/agents/python/, completing the "strip src/gaia/agents/ to framework only" goal for #1102. The core wheel no longer hardcodes them and they version independently.

Two distinct shapes, handled differently:

  • docqa is a building-block RAG agent — it registers via the gaia.agent entry point as a hidden agent (mirroring fileio), default model Qwen3.5-35B-A3B-GGUF. Discovered automatically by the registry; hidden from the UI selector.
  • routing is infrastructure — a meta-agent loaded by class path from the OpenAI-compatible API server (gaia-code model), not a registry agent (it doesn't inherit Agent). It ships without a gaia.agent entry point. gaia.api.agent_registry now resolves it at gaia_agent_routing.agent.RoutingAgent and fails loudly with an install hint (pip install gaia-agent-routing gaia-agent-code) when the wheel is absent — no silent fallback.

History is preserved via git mv. Each new wheel gets a CI workflow mirroring test_analyst_agent.yml, wired into the test_gaia_cli aggregator; test_code_agent.yml's path trigger follows routing to its new home.

Test plan

  • python util/lint.py --all — clean (black/isort/agent-conventions pass; bandit notes are pre-existing false positives in unrelated files)
  • pip install -e hub/agents/python/docqa hub/agents/python/routing && pytest hub/agents/python/{docqa,routing}/tests/ — 52 passed
  • pytest tests/unit/agents/test_registry.py tests/unit/test_agents_split.py tests/unit/test_errors.py tests/test_sdk.py::TestRoutingAgent — green
  • Import check: import gaia.api.agent_registry works; gaia-code resolves to gaia_agent_routing.agent.RoutingAgent; registry discovers docqa (hidden)
  • CI: new DocQA Agent Tests + Routing Agent Tests workflows install the wheels and run their tests

Pre-existing test_cli_smoke failures for the gaia-emr/gaia-code console scripts are unrelated to this change (they fail identically with this branch's changes stashed — stale installed entry-point metadata pointing at already-migrated modules).

DocumentQAAgent and RoutingAgent were the last two agents left in the
core source tree under src/gaia/agents/. They now ship as standalone
gaia-agent-docqa / gaia-agent-routing wheels under hub/agents/python/,
completing the "strip src/gaia/agents/ to framework only" goal for #1102
(only base/, tools/, registry.py, builder/ — plus the chat family and
email — remain in core).

docqa is a building-block RAG agent: it registers via the gaia.agent
entry point as a hidden agent (mirroring fileio), default model
Qwen3.5-35B-A3B-GGUF. routing is infrastructure — a meta-agent loaded by
class path from the OpenAI API server, not a registry agent — so it ships
without a gaia.agent entry point; gaia.api.agent_registry now resolves it
at gaia_agent_routing.agent.RoutingAgent and fails loudly with an install
hint when the wheel is absent.
@github-actions github-actions Bot added dependencies Dependency updates devops DevOps/infrastructure changes tests Test changes agents labels Jun 4, 2026
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Clean, well-executed refactor that finishes the #1102 goal of stripping src/gaia/agents/ down to framework-only. docqa and routing move out as standalone hub wheels with history preserved (git mv, 100% similarity), and the two are correctly handled as different shapes: docqa ships as a hidden registry agent via the gaia.agent entry point (mirroring fileio exactly), while routing ships as infrastructure with no entry point and is resolved by class path from the API server. The single most important thing to know: the code paths are consistent and fail loudly, but the docs were not updated — several pages still reference the old gaia.agents.routing.agent.RoutingAgent path that this PR makes invalid.

The new wheel __init__.py for docqa matches the established fileio pattern line-for-line (lazy __getattr__, build_registration, hidden=True), and the agent_registry change fails loudly with an actionable install hint rather than degrading silently — both fully in line with GAIA conventions.

Issues Found

🟡 Important

Stale docs reference the now-invalid routing path (docs/sdk/infrastructure/api-server.mdx:89, docs/spec/api-server.mdx:342, docs/playbooks/chat-agent/part-3-deployment.mdx:246)

These pages show "class_name": "gaia.agents.routing.agent.RoutingAgent" as a concrete, copy-pasteable example. After this PR the live value is gaia_agent_routing.agent.RoutingAgent (the change you made in src/gaia/api/agent_registry.py:33), so the docs now contradict the code. A user copying the api-server example will hit the exact ImportError your new hint warns about. CLAUDE.md requires docs match the SDK implementation, so these should move with the code. Suggested fix for the api-server example:

        "class_name": "gaia_agent_routing.agent.RoutingAgent",

Additionally, docs/sdk/agents/routing.mdx, docs/spec/routing-agent.mdx, and docs/guides/routing.mdx carry from gaia.agents.routing.agent import RoutingAgent import lines and GitHub source links to src/gaia/agents/routing/ that now 404. These need updating to gaia_agent_routing / hub/agents/python/routing/. If a docs sweep across the whole #1102 migration is planned as a follow-up, that's reasonable — but please call it out explicitly in the PR so it isn't lost, since this PR is what makes them wrong.

🟢 Minor

Traceback filter set not updated for the moved module (src/gaia/agents/base/errors.py:25)

FRAMEWORK_PATHS still lists "gaia/agents/routing", which no longer matches the installed module path (gaia_agent_routing/). Result: routing framework frames will now leak into user-facing error output instead of being filtered. Note this set is already stale for code/docker/jira (migrated in earlier PRs), so this is a pre-existing pattern rather than something you introduced — but routing joins the broken list here. A small follow-up to switch these to the gaia_agent_* paths would restore the intended filtering. tests/unit/test_errors.py:78 would move with it.

docqa CI path trigger misses a real import dependency (.github/workflows/test_docqa_agent.yml:42)

The docqa agent imports from gaia.agents.chat.tools import FileToolsMixin, but the workflow's path filter covers agents/base/** and agents/tools/**, not agents/chat/**. A change to FileToolsMixin won't trigger docqa tests. This mirrors the existing test_analyst_agent.yml filter, so it's consistent with precedent — flagging only as a latent coverage gap, not a blocker.

Strengths

  • Pattern fidelity: docqa's __init__.py and gaia-agent.yaml are a faithful copy of the fileio template (lazy import, hidden=True, namespaced_agent_id), and the routing/docqa CI workflows mirror test_analyst_agent.yml and wire cleanly into the test_gaia_cli aggregator including the test-summary needs list.
  • Fail-loudly done right: the gaia-code resolution error in agent_registry.py:160 raises with what failed, what to install, and where to look — exactly the three-part actionable error CLAUDE.md asks for, no silent provider/agent fallback.
  • Correct shape distinction: recognizing that routing is infrastructure (no Agent base class — confirmed at agent.py:18, no entry point) vs. docqa being a registry building block, and documenting the why in both the README and pyproject.toml comment, is the right call and prevents a future contributor from "fixing" the missing entry point.
  • Tests moved with the code and import paths updated throughout; pytest.importorskip guards added in tests/test_sdk.py and tests/unit/test_agents_split.py keep framework-only environments green.

Verdict

Approve with suggestions. No blocking code issues — the refactor is correct, consistent with prior #1102 migrations, and the runtime path fails loudly. The one thing that genuinely needs resolution before this is "done" is the stale routing docs (🟡): they now actively misdirect users to an import that errors. Either fix them here or explicitly track the docs sweep as a follow-up in the PR description. The minor items (errors.py filter, CI path trigger) are fine as fast-follows.

Self-review follow-up to the docqa/routing migration: the gaia-agent-code
CLI imported RoutingAgent from the old in-tree path
(gaia.agents.routing.agent), which the migration broke. Repoint it at
gaia_agent_routing.agent and declare gaia-agent-routing as a dependency of
gaia-agent-code, since the `gaia-code` query path routes through
RoutingAgent for language/project-type detection. No reverse dependency
(routing → code) — routing resolves CodeAgent through the registry at
runtime, avoiding a cycle.

Also clears the now-dead RoutingAgent allowance in the agent-conventions
checker (it only applied while routing lived under src/gaia/agents/).
itomek
itomek previously approved these changes Jun 8, 2026
# Conflicts:
#	hub/agents/python/docqa/tests/test_docqa_agent.py
@github-actions

Copy link
Copy Markdown
Contributor

🔴 tests/unit/agents/test_default_max_steps.py:47 — broken import after docqa move

docqa/agent.py was renamed to hub/…/gaia_agent_docqa/agent.py but this file was missed during the import-path sweep. Running pytest tests/unit/ will fail with ModuleNotFoundError: No module named 'gaia.agents.docqa'.

    def test_configs_inherit_the_override_at_construction(self):
        from gaia.agents.chat.agent import ChatAgentConfig
        pytest.importorskip("gaia_agent_docqa")
        from gaia_agent_docqa.agent import DocumentQAAgentConfig

Also needs import pytest at the top. Alternatively, guard the whole test the same way test_agents_split.py does for similar optional-wheel imports.

# Conflicts:
#	.github/workflows/test_gaia_cli.yml
#	setup.py
@github-actions

Copy link
Copy Markdown
Contributor

🟡 tests/unit/agents/test_default_max_steps.py:47 — stale import after the docqa move

DocumentQAAgent was moved from gaia.agents.docqa.agentgaia_agent_docqa.agent, but this test file wasn't updated. It will fail with ModuleNotFoundError in any CI job that runs the unit-test suite.

        pytest.importorskip("gaia_agent_docqa")
        from gaia_agent_docqa.agent import DocumentQAAgentConfig

(Same pattern used in test_agents_split.py:769.)

@github-actions

Copy link
Copy Markdown
Contributor

🔴 tests/unit/agents/test_default_max_steps.py:47 — stale import breaks unit tests

gaia.agents.docqa.agent was renamed/moved to gaia_agent_docqa.agent in this PR, but test_default_max_steps.py was not updated:

from gaia.agents.docqa.agent import DocumentQAAgentConfig   # line 47 — module gone

This will fail with ModuleNotFoundError whenever gaia-agent-docqa is installed (or immediately in CI since the old path no longer exists).

        pytest.importorskip("gaia_agent_docqa")
        from gaia_agent_docqa.agent import DocumentQAAgentConfig

@github-actions

Copy link
Copy Markdown
Contributor

🔴 tests/unit/agents/test_default_max_steps.py:47 has a broken import that wasn't updated with the docqa move:

# current (broken — module no longer exists)
from gaia.agents.docqa.agent import DocumentQAAgentConfig
from gaia_agent_docqa.agent import DocumentQAAgentConfig

The test at line 46 also needs a pytest.importorskip("gaia_agent_docqa") guard (matching the pattern in test_agents_split.py) so it skips cleanly in framework-only envs rather than erroring. Without both fixes, pytest tests/unit/ will fail any time gaia-agent-docqa isn't installed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents dependencies Dependency updates devops DevOps/infrastructure changes tests Test changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants