Skip to content

fix(provider): preserve transport and surface clone failures [P2; independent] #4582

Description

@aheritier

🤖 Automated architect agent — this comment was posted by the architect bot from Docker Agentic Platform, not by a human engineer

What

Make provider reconstruction fail visibly and preserve the selected transport and explicit user options. A title, MCP sampling request or compaction operation must not silently run against the unmodified base provider when the requested clone cannot be built.

Preserve native Vertex dispatch/authentication independently of the provider identity used for catalog lookup. Preserve explicit thinking-off intent through defaults, environment expansion, custom providers and routing without sharing mutable options.

This is independently shippable on already available models (for example Claude 4.6 / Haiku 4.5); it does not need to activate new 5.x policy or wait for #4576.

Why

Internal defects: immutable source evidence

The research revision is 49e4ca657fd454e9d46ea258e8cf61c517df9aab, not a selected implementation base. These are static observations to reproduce with caller-level tests:

  1. CloneWithOptions, lines 15–29 logs a warning and returns the original provider when a rebuilder is absent or fails. The requested restrictions can therefore be ignored without an error reaching the caller.
  2. Title generation applies no-thinking, max-token and structured-output options, then immediately uses the returned provider. MCP sampling likewise continues to inference after cloning. Compaction and context-window resolution also call the same helper.
  3. Vertex construction rewrites Provider for models.dev identity before giving the configuration to the Anthropic-native client. The attached rebuilder reconstructs from the supplied configuration. A catalog identity must not replace the original dispatch identity.
  4. Existing mergeCloneOptions already writes a disabled sentinel to avoid provider-default resurrection. Preserve and extend that work; do not claim the sentinel is missing. fix(provider): WithNoThinking clone no longer leaks provider-level thinking_budget #3238 and refactor(provider): replace ProviderRegistry any with typed RebuildProviderFunc #4278 are merged predecessors, not the remaining fail-visible/dispatch fix. Closed CloneWithOptions uses the wrong environment.Provider #676 concerned the environment provider, not this full contract.

These are docker-agent correctness requirements, not vendor requirements to adopt a particular Go API.

Official documentation: why the transport and intent differences matter

  • Claude on Vertex uses Google-authenticated native prediction with project/location/model in the URL and anthropic_version: vertex-2023-10-16 in the body. A clone must not switch to the Claude API or leak a direct API key. The current Vertex auth code explicitly clears that key and supports request-context token sourcing.
  • Thinking and effort distinguish disabled thinking, adaptive thinking and effort. A failed strict-off clone cannot be treated as permission to reason at a lower effort. Model-specific 5.x validation belongs to the core issue, not this prerequisite.

How — indicative

Prefer an additive checked-clone API returning (Provider, error) and migrate internal callers. If the public single-return API must remain for Go compatibility, document deprecation and ensure failed strict options cannot cause inference on the base provider (for example, an error-returning provider using existing contracts). Do not silently break a public signature or add a hidden retry loop.

Keep original dispatch configuration separate from catalog/display identity and carry it through the existing rebuilder. Preserve project, location, selected host, credentials/token source, gateway bypass and ordered option precedence. Keep state request/session-scoped where it varies between conversations; do not mutate shared configuration maps.

Handle failures at the caller boundary: title candidate exhaustion is nonfatal to chat; MCP returns an actionable error; compaction/context-limit resolution propagates failure without replacing session context or performing an unrequested base-model inference. Existing explicit title-candidate behavior may remain; a hidden base fallback is not a candidate.

Acceptance criteria

  • Missing rebuilder and synthetic reconstruction errors reach the actual title/MCP/compaction/context-limit callers. Fake-server call counts show no base-provider inference after a failed clone; a helper-only test is insufficient.
  • Cloning google + publisher: anthropic preserves native rawPredict/streamRawPredict, model-in-URL dialect, project/location and OAuth request context; no direct endpoint/API-key leakage. Test both supported native auth construction paths.
  • Literal/environment/inherited/custom/routed configurations and cumulative options retain strict off, max tokens and structured-output removal/preservation as requested. No thinking resurrection or mutable option sharing.
  • Titles exhaust existing candidates cleanly; MCP with and without tools exposes the error; compaction and window resolution leave context intact when reconstruction fails.
  • Legacy models, non-Claude providers, embedders, restricted registries and the existing disabled sentinel have regression controls. Do not globally reinterpret legacy thinking budgets or activate 5.x modes here.
  • Go SDK/failure-behavior documentation and caller-level tests ship in the same PR. During authorized implementation, run task build, task test, task lint, relevant targeted/race checks and review the exact final head. No unauthorized dependency acquisition is implied.
  • The complete caller-visible fix is merged/delivered, not merely a compiling checked helper.

Dependencies and boundaries

No technical dependencies. This may ship before or after the independent routing-price work in #4576, which is being handled separately and must not be duplicated or expanded here. It is a prerequisite for the 5.x core, not an assurance that all 5.x configurations already work. #4116 remains related and separate. Do not modify or close #4553 as part of this issue.

Implementation PR linkage: pending.

External pricing work: PR #4579 — price routed turns using the serving model is now listed as open. Discovery only; not reviewed here. This link does not establish the full per-stream origin/P3 contract or per-attempt fallback accounting. Do not duplicate or intervene in that workstream.

Epic: #4580

Cross-links

Epic: #4580. Documentation: #4581 (independent). This fix is a prerequisite for #4583, and transitively #4584. External #4576 / #4579 is independent work; its full origin-contract coverage is unreviewed. No implementation PR is linked for this issue yet.

Activity

  1. added
    area/providersFor features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.)
    area/providers/anthropicFor features/issues/fixes related to the usage of Anthropic models
    area/sessionsFor features/issues/fixes related to session lifecycle (resume, persistence, export)
    area/mcpMCP protocol, MCP tool servers, integration
    area/runtimeRuntime engine, agent loop execution, tool dispatch, loop detection
    on Oct 13, 2026
  2. self-assigned this
    on Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area/mcpMCP protocol, MCP tool servers, integrationarea/providersFor features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.)area/providers/anthropicFor features/issues/fixes related to the usage of Anthropic modelsarea/runtimeRuntime engine, agent loop execution, tool dispatch, loop detectionarea/sessionsFor features/issues/fixes related to session lifecycle (resume, persistence, export)

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions