Skip to content

SANDBOX-1812: add typed HTTP client for sandbox agent API - #16

Merged
fbm3307 merged 1 commit into
masterfrom
feat/SANDBOX-1812-agent-http-client
Jul 13, 2026
Merged

SANDBOX-1812: add typed HTTP client for sandbox agent API#16
fbm3307 merged 1 commit into
masterfrom
feat/SANDBOX-1812-agent-http-client

Conversation

@fbm3307

@fbm3307 fbm3307 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator
  • Add pkg/agent.AgentClient with Execute, Assign, and HealthCheck for the sandbox agent HTTP API
  • Introduce typed errors (NetworkError, StatusError, DecodeError) so callers can branch with errors.As / errors.Is
  • Configurable via functional options (timeout, port, HTTP client, max response size); defaults: 30s, port 8090, 10 MB success-body cap, 512-byte error-body truncation
  • Unit tests against httptest covering success/failure paths, context cancel/deadline, options, and concurrent use (-race)

Assisted by: Cursor

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced Agent Client infrastructure for sandbox environment communication, enabling command execution with bearer token authentication, resource assignment, and health monitoring.
    • Configurable options for request timeout, custom HTTP client, port settings, and response size limits.
  • Tests

    • Added comprehensive test coverage for client operations, error handling, and concurrent execution.

- Introduce AgentClient with Execute, Assign, and HealthCheck
- Add NetworkError, StatusError, and DecodeError for callers to branch on
- Cap successful Execute bodies at 10 MB; truncate error bodies to 512 bytes
- Cover options, error types, and concurrent use with httptest tests

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Feny Mehta <fbm3307@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Walkthrough

Adds a configurable typed HTTP client for sandbox agent /exec, /assign, and /health APIs, structured network/status/decode errors, bounded response handling, and comprehensive tests covering options, failures, context behavior, and concurrency.

Changes

Agent client

Layer / File(s) Summary
Client configuration and error contracts
pkg/agent/client.go, pkg/agent/errors.go
Defines client defaults, functional options, exported endpoint client configuration, and structured network, status, and decode errors.
Endpoint request and response handling
pkg/agent/client.go
Implements authenticated /exec, unauthenticated /assign and /health, status validation, response-size limits, error wrapping, URL construction, and response-body draining.
Client behavior and concurrency tests
pkg/agent/client_test.go
Tests request construction, successful responses, error mapping, option overrides, context propagation, truncation, IPv6 formatting, and concurrent execution.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant AgentClient
  participant SandboxAgentAPI
  Caller->>AgentClient: Execute, Assign, or HealthCheck
  AgentClient->>SandboxAgentAPI: Send endpoint request
  SandboxAgentAPI-->>AgentClient: Return status and body
  AgentClient-->>Caller: Return response or structured error
Loading

Possibly related PRs

Suggested labels: feature, test

Suggested reviewers: alexeykazakov, rajivnathan

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% 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 clearly summarizes the main change: adding a typed HTTP client for the sandbox agent API.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/SANDBOX-1812-agent-http-client

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
pkg/agent/client.go (2)

106-113: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Error-path response bodies aren't drained before Close(), unlike the success path.

On success, drainBody (Lines 179, 207) reads up to 4 KB so the connection can be reused. On the StatusError path, only up to 512 bytes are read via readBodyTruncated (Lines 111, 176, 204) before the deferred Close() runs — the rest of the body is left unread, which typically prevents net/http from reusing the underlying connection. Given HealthCheck/Assign failures may be frequent (e.g., during pod startup), this adds unnecessary connection churn. Consider draining the remainder after truncation.

Also applies to: 171-178, 199-206

🤖 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 `@pkg/agent/client.go` around lines 106 - 113, Ensure all StatusError paths in
the client response handling drain the remaining response body after
readBodyTruncated and before the deferred Close, matching the success-path
behavior in drainBody. Update the shared error-handling logic used by
HealthCheck and Assign so the truncated body is preserved while the remainder is
consumed for connection reuse.

84-209: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Significant duplication across Execute, Assign, and HealthCheck.

Each method repeats request construction, Do/classifyDoError, and the StatusCode != http.StatusOKStatusError block almost verbatim. Extracting a shared doRequest(ctx, method, url, body, op string, headers map[string]string) (*http.Response, error) helper (returning the response for the caller to decode/drain) would reduce this to method-specific decode logic only.

As per path instructions, focus on maintainability for **.

🤖 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 `@pkg/agent/client.go` around lines 84 - 209, Reduce duplication among
AgentClient.Execute, AgentClient.Assign, and AgentClient.HealthCheck by
introducing a shared doRequest helper that accepts the context, HTTP method,
URL, optional body, operation name, and headers. Move request creation, header
application, HTTP execution, classifyDoError handling, and non-OK StatusError
construction into the helper, returning the successful response for each
method’s existing decode or drain logic; then simplify the three methods to call
it and retain only endpoint-specific behavior.

Source: Path instructions

🤖 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 `@pkg/agent/client.go`:
- Around line 106-113: Ensure all StatusError paths in the client response
handling drain the remaining response body after readBodyTruncated and before
the deferred Close, matching the success-path behavior in drainBody. Update the
shared error-handling logic used by HealthCheck and Assign so the truncated body
is preserved while the remainder is consumed for connection reuse.
- Around line 84-209: Reduce duplication among AgentClient.Execute,
AgentClient.Assign, and AgentClient.HealthCheck by introducing a shared
doRequest helper that accepts the context, HTTP method, URL, optional body,
operation name, and headers. Move request creation, header application, HTTP
execution, classifyDoError handling, and non-OK StatusError construction into
the helper, returning the successful response for each method’s existing decode
or drain logic; then simplify the three methods to call it and retain only
endpoint-specific behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: c834fa34-5f3d-4bb1-b51f-13ebd2e5137e

📥 Commits

Reviewing files that changed from the base of the PR and between db6b095 and 75d3ca3.

📒 Files selected for processing (3)
  • pkg/agent/client.go
  • pkg/agent/client_test.go
  • pkg/agent/errors.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • codeready-toolchain/mcp-common (manual)
  • codeready-toolchain/mcp-server-devsandbox (manual)
  • codeready-toolchain/api (manual)
  • codeready-toolchain/toolchain-common (manual)
  • codeready-toolchain/host-operator (manual)
  • codeready-toolchain/toolchain-e2e (manual)
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: CodeRabbit / Review
  • GitHub Check: build-test-coverage
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • pkg/agent/errors.go
  • pkg/agent/client_test.go
  • pkg/agent/client.go
🧬 Code graph analysis (2)
pkg/agent/client_test.go (1)
pkg/agent/types.go (3)
  • ExecResponse (11-16)
  • ExecRequest (5-8)
  • AssignRequest (19-21)
pkg/agent/client.go (1)
pkg/agent/types.go (3)
  • ExecResponse (11-16)
  • ExecRequest (5-8)
  • AssignRequest (19-21)
🔀 Multi-repo context codeready-toolchain/mcp-server-devsandbox

Linked repositories findings

codeready-toolchain/mcp-server-devsandbox

  • No /exec, /assign, AgentClient, or agent request/response type references were found.
  • The repository’s /health endpoint is the MCP server readiness probe in pkg/mcpinit/init.go:213, served on the MCP HTTP address (default localhost:8080), not the sandbox agent’s port 8090. It should not conflict with this client’s /health calls. [::codeready-toolchain/mcp-server-devsandbox::]

Other linked repositories

  • No consumers or shared contracts for AgentClient, ExecRequest, ExecResponse, AssignRequest, /exec, /assign, or port 8090 were found in mcp-common, api, toolchain-common, host-operator, or toolchain-e2e.
🔇 Additional comments (8)
pkg/agent/client.go (5)

1-34: LGTM!


40-81: LGTM!


106-113: 🎯 Functional Correctness

Only http.StatusOK (200) is treated as success.

Any other 2xx response (e.g., 201/202/204) from the agent would be classified as StatusError. If the agent's actual contract could ever return a non-200 success code, this would misclassify successful calls as failures. Worth confirming the agent's documented status codes.

Also applies to: 171-178, 199-206


211-242: LGTM!


106-146: 🎯 Functional Correctness

Body-read failures may need separate classification
After a 200 response, io.ReadAll(limited) errors currently become DecodeError. If mid-stream cancellation or connection loss should be treated as retryable transport failure, branch on ctx.Err() here before falling back to DecodeError; otherwise callers looking for *NetworkError will miss it.

pkg/agent/errors.go (1)

1-53: LGTM!

pkg/agent/client_test.go (2)

22-33: LGTM!

Also applies to: 35-219, 221-279, 281-335, 337-397, 399-461, 463-503


59-59: 🎯 Functional Correctness

Go 1.24+ is already requiredgo.mod declares go 1.24.6, so both t.Context() and for i := range n are supported here.

			> Likely an incorrect or invalid review comment.

@fbm3307
fbm3307 merged commit 2d316cf into master Jul 13, 2026
3 of 4 checks passed
@fbm3307
fbm3307 deleted the feat/SANDBOX-1812-agent-http-client branch July 13, 2026 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants