refactor: trim transitive dependencies for library consumers - #3778
Conversation
…ansport pkg/modelsdev, pkg/gateway and pkg/httpclient only needed remote.NewTransport, but importing pkg/remote drags the whole OCI registry stack (go-containerregistry, docker/cli, credential helpers) into every consumer of pkg/model/provider, pkg/session and pkg/agent. Move the transport (and its proxy fallback logic) to pkg/desktop/transport, which only depends on pkg/desktop and pkg/memoize. remote.NewTransport is kept as a deprecated forwarder so existing integrations keep compiling and behaving identically. pkg/model/provider now pulls 24 external modules instead of 31.
pkg/model/provider/anthropic unconditionally imported anthropic-sdk-go/vertex and golang.org/x/oauth2/google, pulling the whole Google Cloud auth stack (cloud.google.com/go/auth, google.golang.org/api, grpc, protobuf, ...) into every consumer of the plain Anthropic provider. Move NewVertexClient to pkg/model/provider/anthropic/vertex.NewClient, built on the new anthropic.NewClientFromFactory wiring point. Config validation still runs before GCP credential discovery, and the default providers registry keeps full Vertex support through the vertexai provider, so existing YAML configs behave identically. Direct callers of anthropic.NewVertexClient get a compile-time error pointing at the new package rather than a silent behavior change. pkg/model/provider/anthropic now pulls 35 external modules instead of 57.
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟡 NEEDS ATTENTION
| if req.GetBody != nil { | ||
| body, bodyErr := req.GetBody() | ||
| if bodyErr != nil { | ||
| return nil, err |
There was a problem hiding this comment.
[medium] Wrong error returned when GetBody fails — proxy error masks body-reconstruction failure
When the proxy is unavailable and RoundTrip falls back to a direct retry, it calls req.GetBody() to reconstruct the request body. If GetBody() itself returns an error (bodyErr), the code discards that error and returns the original proxy socket error (err) instead:
body, bodyErr := req.GetBody()
if bodyErr != nil {
return nil, err // bodyErr is silently dropped
}The caller receives a misleading "proxy unavailable" or "dial unix …" error when the real failure is body reconstruction. Although GetBody closures rarely fail in practice (they typically wrap an already-buffered body), the error contract is still broken — if they do fail the wrong error is surfaced, making the root cause invisible.
| return nil, err | |
| return nil, bodyErr |
| Confidence | Score |
|---|---|
| 🟢 strong | 100/100 |
Downstream Go projects importing cagent packages (
pkg/session,pkg/agent,pkg/model/provider,pkg/model/provider/anthropic) were pulling heavy transitive dependencies they didn't need — the full OCI registry stack and the entire Google Cloud auth stack — simply because those packages importedpkg/remoteandpkg/model/provider/anthropicunconditionally.The first commit moves the Docker Desktop proxy HTTP transport from
pkg/remoteinto a new leaf packagepkg/desktop/transport. The newtransport.Newconstructor carries no OCI registry baggage;remote.NewTransportis kept as a deprecated forwarder so existing callers keep compiling without changes. Internal packages (pkg/httpclient,pkg/modelsdev,pkg/gateway,pkg/remote) are updated to import the new location. The second commit moves Vertex AI support out ofpkg/model/provider/anthropicintopkg/model/provider/anthropic/vertex, wired through a newanthropic.NewClientFromFactoryextension point. Config validation still runs before GCP credential discovery, credentials are still resolved eagerly, and the default providers registry retains full Vertex support through thevertexaiprovider — YAML configs are unaffected. Direct callers of the removedanthropic.NewVertexClientget a compile-time error rather than a silent behavior change.pkg/model/providerpkg/model/provider/anthropictask build,task test, andtask lintall pass. Thepkg/teamloaderexample tests require a local Docker Model Runner and fail identically onmain— pre-existing, unrelated.