Skip to content

feat(agents): route gateway to container-mode agents via Deployment e…#644

Merged
benmccown merged 2 commits into
mainfrom
agent-gateway-container-routing
Jul 14, 2026
Merged

feat(agents): route gateway to container-mode agents via Deployment e…#644
benmccown merged 2 commits into
mainfrom
agent-gateway-container-routing

Conversation

@benmccown

@benmccown benmccown commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

feat(agents): route gateway to container-mode agents via Deployment.endpoints

What & why

Teaches the agents-plugin gateway proxy to route to container-mode (docker/k8s) agents by resolving their address from the projected AgentDeployment.endpoints, instead of the hardcoded loopback endpoint. Subprocess mode is unchanged and stays the default.

This is the stop-gap that unblocks agents-in-k8s: without it, a containerized agent can be deployed but inbound traffic can't reach it, since the gateway is hardwired to a loopback 127.0.0.1:<port> that's only valid for a same-host subprocess.

Changes

  • entities.py — promote endpointendpoints: list[Endpoint] and add a deployment_mode discriminator (subprocess|docker|k8s, default subprocess). endpoint stays as the subprocess loopback compat shim for one release.
  • gateway.py — add _get_deployment_endpoint / _is_deployment_routable, the single place resolution branches on mode: container modes read the first http(s) URL from endpoints; subprocess reads endpoint. Routable once status is running; not-ready → 503, missing → 404 (unchanged contract).
  • The SSRF origin guard is origin-relative (not a host allow-list), so it works unchanged for k8s Service DNS and docker host:port.

Out of scope

  • Load-balancing across deployments; per-deployment authN.
  • Possible future direction (not committed to): folding agent routing into the Inference Gateway would likely retire this proxy. This stop-gap stands on its own.

Coordination

The container producer path (compile → DeploymentConfig, status/endpoint projection) lands separately and this PR consumes it. Preferably that change absorbs the self-contained entities.py hunk, after which this branch rebases and drops it. It's assumed the controller projects the deployments-plugin READY onto the agents-local running.

Testing

  • Unit (49 pass): subprocess unchanged (regression), docker/k8s resolves from endpoints (both routes), 503 not-ready, 404 missing, Service-DNS origin guard. ruff + ty clean.
  • Manual E2E (docker mode, dev pod): seeded a container-mode AgentDeployment pointing at a docker-in-docker mock agent; reached it 200 via both agent-name and deployment-name routes; verified 503 (not-ready) and 404 (missing). k8s Service-DNS routing is covered by unit tests.

Summary by CodeRabbit

  • New Features
    • Gateway proxy now supports container-based deployments by resolving and routing to the deployment’s available HTTP/HTTPS endpoints.
    • Agent-name routing now selects only “routable” (running/ready) deployments with resolvable endpoints.
  • Bug Fixes
    • Improved 503 responses for unroutable/pending deployments, including clearer details about routability and deployment state.
    • Added defensive handling when a resolved proxy target is unexpectedly unavailable.
  • Tests
    • Added unit coverage for container-mode endpoint resolution for both deployment-name and agent-name proxying, plus SSRF/origin guard validation.
  • Chores
    • Updated plugin installation to enable docker/k8s extras for deployment support.

@benmccown benmccown requested review from a team as code owners July 10, 2026 22:10
@benmccown benmccown requested a review from tylersbray July 10, 2026 22:11
@benmccown benmccown self-assigned this Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c0c2e708-7ff5-4224-a4c3-7c0a15902067

📥 Commits

Reviewing files that changed from the base of the PR and between ad499f0 and 6b8e53f.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • pyproject.toml

📝 Walkthrough

Walkthrough

The gateway now resolves container deployment targets from projected HTTP/HTTPS endpoints, checks routability by deployment mode and status, and applies this logic to direct and agent-name proxying. Tests cover routing, unavailable deployments, missing deployments, and origin validation.

Changes

Container-mode gateway routing

Layer / File(s) Summary
Gateway endpoint resolution
plugins/nemo-agents/src/nemo_agents_plugin/api/v2/gateway.py
Container deployments use the first supported projected endpoint, while subprocess deployments use their loopback endpoint. Direct and agent-name proxying require a running deployment with a resolved endpoint and retain origin-relative SSRF validation.
Container-mode gateway tests
plugins/nemo-agents/tests/unit/test_gateway.py
Adds container deployment fixtures and tests endpoint selection, completion-path forwarding, unavailable and missing deployments, agent-name selection, and cross-origin rejection.
Container deployment plugin extras
pyproject.toml
Enables Docker and Kubernetes extras for the deployments plugin dependency group.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Gateway
  participant AgentDeployment
  participant Target
  Client->>Gateway: Proxy request
  Gateway->>AgentDeployment: Resolve routable endpoint
  AgentDeployment-->>Gateway: HTTP/HTTPS endpoint
  Gateway->>Target: Forward request
  Target-->>Gateway: Proxy response
  Gateway-->>Client: Return response
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: routing the gateway to container-mode agents via deployment endpoints.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent-gateway-container-routing

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
plugins/nemo-agents/tests/unit/test_gateway.py (1)

488-617: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing coverage for protocol-filtering branch in _get_deployment_endpoint.

All container fixtures use an http endpoint; no test exercises endpoints containing only grpc/tcp entries (→ None/503) or a mixed list where a non-http entry precedes an http one (→ correct skip-and-continue). This is the one untested branch of the new resolution logic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/nemo-agents/tests/unit/test_gateway.py` around lines 488 - 617, Add
tests in TestContainerModeByDeploymentName covering _get_deployment_endpoint
protocol filtering: verify a running deployment with only grpc/tcp endpoints
returns 503, and verify a mixed endpoint list with a non-http entry before an
http entry skips the unsupported endpoint and routes to the HTTP URL. Use the
existing _make_container_deployment, Endpoint, client, and HTTP mock patterns.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@plugins/nemo-agents/tests/unit/test_gateway.py`:
- Around line 488-617: Add tests in TestContainerModeByDeploymentName covering
_get_deployment_endpoint protocol filtering: verify a running deployment with
only grpc/tcp endpoints returns 503, and verify a mixed endpoint list with a
non-http entry before an http entry skips the unsupported endpoint and routes to
the HTTP URL. Use the existing _make_container_deployment, Endpoint, client, and
HTTP mock patterns.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 69189d08-62be-4912-9836-06c2dccd7d6e

📥 Commits

Reviewing files that changed from the base of the PR and between ba80434 and bc7430e.

📒 Files selected for processing (3)
  • plugins/nemo-agents/src/nemo_agents_plugin/api/v2/gateway.py
  • plugins/nemo-agents/src/nemo_agents_plugin/entities.py
  • plugins/nemo-agents/tests/unit/test_gateway.py

@github-actions github-actions Bot added the feat label Jul 10, 2026
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 23880/31011 77.0% 61.8%
Integration Tests 13811/29660 46.6% 19.6%

…ndpoints

Teach the agents-plugin gateway proxy to resolve a container-mode (docker/k8s)
agent's address from the projected `AgentDeployment.endpoints` instead of the
hardcoded loopback `endpoint`. Subprocess mode is unchanged and remains the
default. This is the deliberate stop-gap that unblocks agents in k8s.

- Promote `endpoint` -> `endpoints: list[Endpoint]` on AgentDeployment and add a
  `deployment_mode` discriminator (subprocess|docker|k8s). `endpoint` is kept as
  the subprocess loopback compat shim for one release.
- Add `_get_deployment_endpoint` / `_is_deployment_routable` gateway helpers: the
  only place endpoint resolution branches on mode. Container modes read the first
  http(s) URL from `endpoints`; subprocess reads the loopback `endpoint`.
- A container deployment is routable once its status is `running` (the controller
  projects the deployments-plugin READY status onto `running`); not-ready -> 503,
  missing -> 404, matching today's contract.
- The SSRF origin guard is origin-relative, so it works unchanged for k8s Service
  DNS and docker host:port targets; documented, no allow-list change.
- Unit tests: subprocess resolution unchanged (regression), docker/k8s resolution
  from `endpoints`, 503 not-ready, 404 missing, Service-DNS origin guard.

Note: coordinate the `endpoint`->`endpoints` + `deployment_mode` entity change and
the status/endpoint projection with the container producer work; that change may
absorb the entity portion of this diff.

Signed-off-by: Ben McCown <bmccown@nvidia.com>
@benmccown benmccown force-pushed the agent-gateway-container-routing branch from bc7430e to ad499f0 Compare July 13, 2026 21:09

@tylersbray tylersbray left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Signed-off-by: Ben McCown <bmccown@nvidia.com>
@benmccown benmccown enabled auto-merge July 14, 2026 16:56
@benmccown benmccown added this pull request to the merge queue Jul 14, 2026
Merged via the queue into main with commit ac12328 Jul 14, 2026
57 checks passed
@benmccown benmccown deleted the agent-gateway-container-routing branch July 14, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants