Skip to content

Commit d5e606a

Browse files
kovtcharov-amdOvtcharov
andauthored
refactor(agents): migrate code to hub (#1397, #1102) (#1421)
## Why this matters CodeAgent was baked into the core `amd-gaia` wheel, so it could only ship on the framework's release cycle and `RoutingAgent` hard-imported the entire code stack at module load. After this change, **CodeAgent ships as an independent `gaia-agent-code` wheel** (`hub/agents/python/code/`), discovered via the `gaia.agent` entry-point group like the other migrated agents. `RoutingAgent` stays in the framework and now **resolves CodeAgent lazily through the registry** (`AgentRegistry().create_agent("code", ...)`), so the core no longer depends on the code package — and fails loudly with an actionable install hint if the wheel is missing. Completes the `code` row of #1397 (legacy modernization) and #1102 (move production agents to `hub/agents/`). ## Test plan - [x] `python util/lint.py --agents` — clean (2 pre-existing docqa/emr warnings, unrelated) - [x] `python util/lint.py --black --isort --fix` — clean; `black --check hub/agents/python/code/` clean - [x] `uvx pylint src/gaia -E --rcfile .pylintrc --disable C0103,C0301,W0246,W0221,E1102,R0401,E0401,W0718,W0212` — clean (only the ignorable Windows `os.geteuid` E1101) - [x] Framework decoupling: `pytest tests/unit/agents/test_routing_agent.py tests/unit/agents/test_registry.py tests/unit/test_agent_required_connectors.py tests/unit/test_errors.py tests/unit/test_code_index_mixin.py` — 144 passed - [x] Migrated package (gated subset, mirrors `test_code_agent.yml`): `pytest hub/agents/python/code/tests/test_code_agent_mixins.py hub/agents/python/code/tests/test_code_agent.py::TestCodeAgent -k "not workflow and not integration and not process_query"` + validators + guardrails + `TestCodeAgentIntegration` — green - [x] `gaia_agent_code.build_registration()` returns `id=code, source=installed, namespaced_agent_id=installed:code`; `gaia-code` console script resolves to `gaia_agent_code.cli:main` - [x] `tests/test_api.py` + `tests/mcp/test_agent_mcp_server.py` collect with no import errors (api_registry change is docstring-only) - [x] Repo-wide grep: no stale `gaia.agents.code` imports remain (the two `gaia/agents/code` strings in `errors.py` FRAMEWORK_PATHS are intentionally kept, matching the jira/blender/docker migrations) ### Notes for the reviewer - `tests/unit/cli/test_cli_smoke.py` may show a stale `gaia-code -> gaia.agents.code.cli` entry **only** in a dev environment with a previously editable-installed `amd-gaia` (the documented worktree gotcha). A clean install picks up the updated `setup.py` (no `gaia-code`) and passes. - A few pre-existing, **non-gated** code tests still fail offline (Context7 service in `test_external_tools`, `run_npm_command` registry drift in `test_typescript_tools`, `process_query` LLM tests, and `hasattr` assertions in the ungated `test_sdk` code-mixin checks). All were verified to fail identically on `main`; fixing them is out of scope for this migration. Co-authored-by: Ovtcharov <kovtchar@amd.com>
1 parent 9d31f42 commit d5e606a

86 files changed

Lines changed: 372 additions & 207 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/publish.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,6 @@ jobs:
442442
- name: Verify CLI entry points
443443
run: |
444444
gaia --help
445-
gaia-code --help
446445
gaia-mcp --help
447446
gaia-emr --help
448447

.github/workflows/test_code_agent.yml

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@ on:
1111
push:
1212
branches: [ main ]
1313
paths:
14-
- 'src/gaia/agents/code/**'
14+
- 'hub/agents/python/code/**'
1515
- 'src/gaia/agents/base/**'
16-
- 'tests/test_code_agent*.py'
16+
- 'src/gaia/agents/routing/**'
1717
- 'setup.py'
1818
- '.github/workflows/test_code_agent.yml'
1919
pull_request:
2020
branches: [ main ]
2121
types: [opened, synchronize, reopened, ready_for_review]
2222
paths:
23-
- 'src/gaia/agents/code/**'
23+
- 'hub/agents/python/code/**'
2424
- 'src/gaia/agents/base/**'
25-
- 'tests/test_code_agent*.py'
25+
- 'src/gaia/agents/routing/**'
2626
- 'setup.py'
2727
- '.github/workflows/test_code_agent.yml'
2828
merge_group:
@@ -59,6 +59,8 @@ jobs:
5959
- name: Install dependencies
6060
run: |
6161
uv pip install --system -e .[dev]
62+
# CodeAgent ships as the standalone gaia-agent-code wheel (#1397, #1102)
63+
uv pip install --system -e hub/agents/python/code
6264
# Install optional dependencies for code agent
6365
uv pip install --system black pylint
6466
@@ -71,7 +73,7 @@ jobs:
7173
echo ""
7274
7375
# Run mixin tests
74-
python -m pytest tests/test_code_agent_mixins.py -v --tb=short
76+
python -m pytest hub/agents/python/code/tests/test_code_agent_mixins.py -v --tb=short
7577
7678
# Store the result
7779
MIXIN_TEST_EXIT=$?
@@ -93,9 +95,16 @@ jobs:
9395
echo ""
9496
9597
# Run with pytest for better output formatting
96-
python -m pytest tests/test_code_agent.py::TestCodeAgent -v --tb=short \
98+
python -m pytest hub/agents/python/code/tests/test_code_agent.py::TestCodeAgent -v --tb=short \
9799
-k "not workflow and not integration and not process_query"
98100
101+
# Validators and write-guardrail tests (moved here from tests/unit and
102+
# tests/ root during the hub migration; keep them gated).
103+
python -m pytest \
104+
hub/agents/python/code/tests/test_code_validators.py \
105+
hub/agents/python/code/tests/test_file_io_guardrails.py \
106+
-v --tb=short
107+
99108
- name: Run Code Agent Integration Tests
100109
run: |
101110
echo ""
@@ -106,7 +115,7 @@ jobs:
106115
echo ""
107116
108117
# Run integration tests
109-
python -m pytest tests/test_code_agent.py::TestCodeAgentIntegration -v --tb=short
118+
python -m pytest hub/agents/python/code/tests/test_code_agent.py::TestCodeAgentIntegration -v --tb=short
110119
111120
- name: Run Code Agent Workflow Tests
112121
# Workflow tests invoke process_query which requires a running LLM.
@@ -122,7 +131,7 @@ jobs:
122131
echo ""
123132
124133
# Run workflow tests with timeout
125-
timeout 300 python -m pytest tests/test_code_agent.py -v --tb=short \
134+
timeout 300 python -m pytest hub/agents/python/code/tests/test_code_agent.py -v --tb=short \
126135
-k "workflow or process_query or complete_workflow"
127136
128137
- name: Test Summary

CLAUDE.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,10 +463,11 @@ Defined in [`setup.py`](setup.py) under `console_scripts`:
463463
|--------|-------------|---------|
464464
| `gaia` / `gaia-cli` | `gaia.cli:main` | Main CLI — all `gaia <subcommand>` |
465465
| `gaia-mcp` | `gaia.mcp.mcp_bridge:main` | Standalone MCP bridge binary |
466-
| `gaia-code` | `gaia.agents.code.cli:main` | CodeAgent standalone entry (NOT `gaia code`) |
467466

468467
The `gaia-emr` console script now ships with the standalone `gaia-agent-emr` hub package (`hub/agents/python/emr/`), not the core wheel.
469468

469+
`gaia-code` is no longer a core `console_scripts` entry — it ships with the standalone `gaia-agent-code` wheel (`hub/agents/python/code/`, entry point `gaia_agent_code.cli:main`).
470+
470471
## Architecture
471472

472473
**See [`docs/reference/dev.mdx`](docs/reference/dev.mdx)** for detailed architecture documentation.
@@ -587,7 +588,7 @@ All commands are registered in [`src/gaia/cli.py`](src/gaia/cli.py). Run `gaia -
587588
- `gaia perf-vis` - Visualize performance results
588589

589590
**Standalone binaries** (separate `console_scripts`, not subcommands):
590-
- `gaia-code` - CodeAgent entry (`src/gaia/agents/code/cli.py`)
591+
- `gaia-code` - CodeAgent entry, from the `gaia-agent-code` wheel (`hub/agents/python/code/gaia_agent_code/cli.py`)
591592
- `gaia-emr` - Medical intake entry (ships with the `gaia-agent-emr` hub package, `hub/agents/python/emr/gaia_agent_emr/cli.py`)
592593
- `gaia-mcp` - Standalone MCP bridge binary
593594

docs/sdk/mixins/code-mixins.mdx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ icon: "code"
88
</Info>
99

1010
<Note>
11-
**Import:** `from gaia.agents.code.tools.cli_tools import CLIToolsMixin`
11+
**Import:** `from gaia_agent_code.tools.cli_tools import CLIToolsMixin`
1212
</Note>
1313
---
1414

@@ -24,7 +24,7 @@ icon: "code"
2424

2525
```python
2626
from gaia.agents.base.agent import Agent
27-
from gaia.agents.code.tools.cli_tools import CLIToolsMixin
27+
from gaia_agent_code.tools.cli_tools import CLIToolsMixin
2828

2929
class MyDevAgent(Agent, CLIToolsMixin):
3030
"""Agent with CLI capabilities."""
@@ -46,15 +46,15 @@ result = agent.process_query("Run npm install and start the dev server")
4646

4747
## 13.2 CodeToolsMixin (Code Generation)
4848

49-
**Import:** `from gaia.agents.code.tools.code_tools import CodeToolsMixin`
49+
**Import:** `from gaia_agent_code.tools.code_tools import CodeToolsMixin`
5050

5151
**Detailed Spec:** [spec/code-tools-mixin](/spec/code-tools-mixin)
5252

5353
**Purpose:** Code generation, scaffolding, and project templates.
5454

5555
```python
5656
from gaia.agents.base.agent import Agent
57-
from gaia.agents.code.tools.code_tools import CodeToolsMixin
57+
from gaia_agent_code.tools.code_tools import CodeToolsMixin
5858

5959
class MyCodeAgent(Agent, CodeToolsMixin):
6060
"""Agent with code generation."""
@@ -99,15 +99,15 @@ class MyAgent(Agent, FileIOToolsMixin):
9999

100100
## 13.4 ValidationToolsMixin (Code Validation)
101101

102-
**Import:** `from gaia.agents.code.tools.validation_tools import ValidationToolsMixin`
102+
**Import:** `from gaia_agent_code.tools.validation_tools import ValidationToolsMixin`
103103

104104
**Detailed Spec:** [spec/validation-tools-mixin](/spec/validation-tools-mixin)
105105

106106
**Purpose:** Syntax checking, linting, and code quality validation.
107107

108108
```python
109109
from gaia.agents.base.agent import Agent
110-
from gaia.agents.code.tools.validation_tools import ValidationToolsMixin
110+
from gaia_agent_code.tools.validation_tools import ValidationToolsMixin
111111

112112
class MyAgent(Agent, ValidationToolsMixin):
113113
"""Agent with validation."""
@@ -124,15 +124,15 @@ class MyAgent(Agent, ValidationToolsMixin):
124124

125125
## 13.5 ErrorFixingMixin (Error Detection & Fixing)
126126

127-
**Import:** `from gaia.agents.code.tools.error_fixing import ErrorFixingMixin`
127+
**Import:** `from gaia_agent_code.tools.error_fixing import ErrorFixingMixin`
128128

129129
**Detailed Spec:** [spec/error-fixing-mixin](/spec/error-fixing-mixin)
130130

131131
**Purpose:** Automatic error detection and intelligent fixing using LLM.
132132

133133
```python
134134
from gaia.agents.base.agent import Agent
135-
from gaia.agents.code.tools.error_fixing import ErrorFixingMixin
135+
from gaia_agent_code.tools.error_fixing import ErrorFixingMixin
136136

137137
class MyAgent(Agent, ErrorFixingMixin):
138138
"""Agent with error fixing."""
@@ -155,15 +155,15 @@ result = agent.process_query(
155155

156156
## 13.6 TestingMixin (Test Execution)
157157

158-
**Import:** `from gaia.agents.code.tools.testing import TestingMixin`
158+
**Import:** `from gaia_agent_code.tools.testing import TestingMixin`
159159

160160
**Detailed Spec:** [spec/testing-mixin](/spec/testing-mixin)
161161

162162
**Purpose:** Test execution, coverage analysis, and test generation.
163163

164164
```python
165165
from gaia.agents.base.agent import Agent
166-
from gaia.agents.code.tools.testing import TestingMixin
166+
from gaia_agent_code.tools.testing import TestingMixin
167167

168168
class MyAgent(Agent, TestingMixin):
169169
"""Agent with testing."""
@@ -180,15 +180,15 @@ class MyAgent(Agent, TestingMixin):
180180

181181
## 13.7 PrismaToolsMixin (Database Setup)
182182

183-
**Import:** `from gaia.agents.code.tools.prisma_tools import PrismaToolsMixin`
183+
**Import:** `from gaia_agent_code.tools.prisma_tools import PrismaToolsMixin`
184184

185185
**Detailed Spec:** [spec/prisma-tools-mixin](/spec/prisma-tools-mixin)
186186

187187
**Purpose:** Prisma ORM setup, schema generation, and database migrations.
188188

189189
```python
190190
from gaia.agents.base.agent import Agent
191-
from gaia.agents.code.tools.prisma_tools import PrismaToolsMixin
191+
from gaia_agent_code.tools.prisma_tools import PrismaToolsMixin
192192

193193
class MyAgent(Agent, PrismaToolsMixin):
194194
"""Agent with Prisma support."""
@@ -205,15 +205,15 @@ class MyAgent(Agent, PrismaToolsMixin):
205205

206206
## 13.8 TypeScriptToolsMixin (TypeScript Development)
207207

208-
**Import:** `from gaia.agents.code.tools.typescript_tools import TypeScriptToolsMixin`
208+
**Import:** `from gaia_agent_code.tools.typescript_tools import TypeScriptToolsMixin`
209209

210210
**Detailed Spec:** [spec/typescript-tools-mixin](/spec/typescript-tools-mixin)
211211

212212
**Purpose:** TypeScript project setup, type checking, and compilation.
213213

214214
```python
215215
from gaia.agents.base.agent import Agent
216-
from gaia.agents.code.tools.typescript_tools import TypeScriptToolsMixin
216+
from gaia_agent_code.tools.typescript_tools import TypeScriptToolsMixin
217217

218218
class MyAgent(Agent, TypeScriptToolsMixin):
219219
"""Agent with TypeScript support."""
@@ -230,15 +230,15 @@ class MyAgent(Agent, TypeScriptToolsMixin):
230230

231231
## 13.9 WebToolsMixin (Web Development)
232232

233-
**Import:** `from gaia.agents.code.tools.web_dev_tools import WebToolsMixin`
233+
**Import:** `from gaia_agent_code.tools.web_dev_tools import WebToolsMixin`
234234

235235
**Detailed Spec:** [spec/web-tools-mixin](/spec/web-tools-mixin)
236236

237237
**Purpose:** Frontend development with React, Vue, Svelte scaffolding and component generation.
238238

239239
```python
240240
from gaia.agents.base.agent import Agent
241-
from gaia.agents.code.tools.web_dev_tools import WebToolsMixin
241+
from gaia_agent_code.tools.web_dev_tools import WebToolsMixin
242242

243243
class MyAgent(Agent, WebToolsMixin):
244244
"""Agent with web dev tools."""

docs/spec/cli-tools-mixin.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ title: "CLIToolsMixin"
88

99
<Note>
1010
**Component:** CLIToolsMixin
11-
**Module:** `gaia.agents.code.tools.cli_tools`
12-
**Import:** `from gaia.agents.code.tools.cli_tools import CLIToolsMixin`
11+
**Module:** `gaia_agent_code.tools.cli_tools`
12+
**Import:** `from gaia_agent_code.tools.cli_tools import CLIToolsMixin`
1313
</Note>
1414
---
1515

@@ -456,7 +456,7 @@ if not result["success"] and "port" in result:
456456
print(f"Port {result['port']} is in use by PID {result['blocking_pid']}")
457457

458458
# Kill the blocking process
459-
from gaia.agents.code.tools.cli_tools import kill_process_on_port
459+
from gaia_agent_code.tools.cli_tools import kill_process_on_port
460460
if kill_process_on_port(result['port']):
461461
print("Killed blocking process, retrying...")
462462
result = agent.run_cli_command(...)
@@ -472,7 +472,7 @@ if not result["success"] and "port" in result:
472472

473473
```python
474474
import pytest
475-
from gaia.agents.code.tools.cli_tools import (
475+
from gaia_agent_code.tools.cli_tools import (
476476
CLIToolsMixin,
477477
is_port_available,
478478
find_available_port,

docs/spec/code-formatting-mixin.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ title: "CodeFormattingMixin"
88

99
<Note>
1010
**Component:** CodeFormattingMixin
11-
**Module:** `gaia.agents.code.tools.code_formatting`
12-
**Import:** `from gaia.agents.code.tools.code_formatting import CodeFormattingMixin`
11+
**Module:** `gaia_agent_code.tools.code_formatting`
12+
**Import:** `from gaia_agent_code.tools.code_formatting import CodeFormattingMixin`
1313
</Note>
1414
---
1515

docs/spec/code-models.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ title: "Code Agent Models"
88

99
<Note>
1010
**Component:** Code Agent Data Models (7 models)
11-
**Module:** `gaia.agents.code.models`
12-
**Import:** `from gaia.agents.code.models import CodeSymbol, ParsedCode, ProjectPlan, ValidationResult, ExecutionResult, ProjectStructure, WorkflowPlan`
11+
**Module:** `gaia_agent_code.models`
12+
**Import:** `from gaia_agent_code.models import CodeSymbol, ParsedCode, ProjectPlan, ValidationResult, ExecutionResult, ProjectStructure, WorkflowPlan`
1313
</Note>
1414
---
1515

@@ -173,7 +173,7 @@ class LintIssue:
173173
### Example 1: Code Symbol Extraction
174174

175175
```python
176-
from gaia.agents.code.models import CodeSymbol, ParsedCode
176+
from gaia_agent_code.models import CodeSymbol, ParsedCode
177177

178178
# Parse Python code
179179
code = '''
@@ -213,7 +213,7 @@ print(f"Found {len(parsed.symbols)} symbols")
213213
### Example 2: Validation Workflow
214214

215215
```python
216-
from gaia.agents.code.models import ValidationResult
216+
from gaia_agent_code.models import ValidationResult
217217

218218
# Validate generated code
219219
result = ValidationResult(
@@ -233,7 +233,7 @@ if result.file_modified:
233233
### Example 3: Project Creation
234234

235235
```python
236-
from gaia.agents.code.models import ProjectPlan, ModuleSpec, TestSpec
236+
from gaia_agent_code.models import ProjectPlan, ModuleSpec, TestSpec
237237

238238
# Create project plan
239239
plan = ProjectPlan(

docs/spec/code-tools-mixin.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ title: "CodeToolsMixin"
88

99
<Note>
1010
**Component:** CodeToolsMixin
11-
**Module:** `gaia.agents.code.tools.code_tools`
12-
**Import:** `from gaia.agents.code.tools.code_tools import CodeToolsMixin`
11+
**Module:** `gaia_agent_code.tools.code_tools`
12+
**Import:** `from gaia_agent_code.tools.code_tools import CodeToolsMixin`
1313
</Note>
1414
---
1515

@@ -549,7 +549,7 @@ RETRY_MAX_TOKENS = 2048
549549

550550
```python
551551
import pytest
552-
from gaia.agents.code.tools.code_tools import CodeToolsMixin
552+
from gaia_agent_code.tools.code_tools import CodeToolsMixin
553553

554554
def test_generate_function():
555555
"""Test function generation."""

docs/spec/error-fixing-mixin.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ title: "ErrorFixingMixin"
88

99
<Note>
1010
**Component:** ErrorFixingMixin
11-
**Module:** `gaia.agents.code.tools.error_fixing`
12-
**Import:** `from gaia.agents.code.tools.error_fixing import ErrorFixingMixin`
11+
**Module:** `gaia_agent_code.tools.error_fixing`
12+
**Import:** `from gaia_agent_code.tools.error_fixing import ErrorFixingMixin`
1313
</Note>
1414
---
1515

docs/spec/external-tools-mixin.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ title: "ExternalToolsMixin"
88

99
<Note>
1010
**Component:** ExternalToolsMixin
11-
**Module:** `gaia.agents.code.tools.external_tools`
12-
**Import:** `from gaia.agents.code.tools.external_tools import ExternalToolsMixin`
11+
**Module:** `gaia_agent_code.tools.external_tools`
12+
**Import:** `from gaia_agent_code.tools.external_tools import ExternalToolsMixin`
1313
</Note>
1414
---
1515

0 commit comments

Comments
 (0)