Skip to content

refactor(provider): deduplicate provider client boilerplate#3398

Merged
dgageot merged 1 commit into
mainfrom
worktree-board-1b7299f662592aa4
Jul 2, 2026
Merged

refactor(provider): deduplicate provider client boilerplate#3398
dgageot merged 1 commit into
mainfrom
worktree-board-1b7299f662592aa4

Conversation

@dgageot

@dgageot dgageot commented Jul 1, 2026

Copy link
Copy Markdown
Member

The five provider clients (openai, anthropic, gemini, bedrock, dmr) each
contained several identical blocks of setup code, making every new provider a
copy-paste exercise and any cross-cutting fix a multi-file hunt. This PR
extracts those repeated patterns into shared helpers with no observable
behavior change.

Six kinds of duplication were collapsed: the option-accumulation loop that all
constructors and factories ran (options.Apply); the HTTP transport-wrapping
block repeated in seven places (options.ModelOptions.WrapTransport); the
track_usage flag check present at seven call sites (base.Config.TrackUsageEnabled);
the Docker AI Gateway fail-fast and per-request short-lived token fetch that
appeared in six constructors (base.VerifyDockerGatewayAuth and
base.GatewayAuthToken); the gateway httpclient option list copied three
times (base.GatewayHTTPOptions); and the rerank-score JSON parser that was
byte-identical in openai and anthropic (providerutil.ParseRerankScores). One
small behavior improvement is folded in: ParseRerankScores now returns
"expected N scores, got M" when the JSON is valid but the score count is wrong,
instead of the generic "invalid rerank JSON" error. All other error strings,
log lines, and side-effect timing are preserved exactly — the per-request token
fetch still happens inside its gateway closure.

New unit tests cover every extracted helper directly, and the full test suite,
linter, race detector, and GOOS=js GOARCH=wasm build all pass.

Extract the code every provider client repeated into shared helpers,
so adding a new provider needs less copy-paste:

- options.Apply: opt-accumulation loop (6 constructors + factories)
- options.ModelOptions.WrapTransport: HTTP transport wrapping (7 blocks)
- base.Config.TrackUsageEnabled: track_usage default-on check (7 sites)
- base.VerifyDockerGatewayAuth / base.GatewayAuthToken: Docker AI
  Gateway fail-fast check and per-request short-lived token fetch
  (6 blocks across anthropic, gemini, openai)
- base.GatewayHTTPOptions: gateway httpclient option list (3 copies)
- providerutil.ParseRerankScores: byte-identical rerank JSON parsing
  from openai and anthropic; now also surfaces score-count mismatches
  instead of a generic parse error

All extractions are behavior-preserving (same error strings, log lines,
and side-effect timing); new helpers are covered by direct unit tests.
@dgageot dgageot requested a review from a team as a code owner July 1, 2026 23:05

// parseRerankScoresAnthropic parses a JSON payload of the form {"scores":[...]} and validates length.
// This helper is local to the Anthropic provider to avoid cyclic dependencies.
func parseRerankScoresAnthropic(raw string, expected int) ([]float64, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This was moved to some util thing, but it's only used by anthropic, why would we move it and make it public?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Because it's used by openai too?

@aheritier aheritier added area/providers For features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.) kind/refactor PR refactors code without behavior change labels Jul 1, 2026
@dgageot dgageot merged commit a5141d1 into main Jul 2, 2026
15 checks passed
@dgageot dgageot deleted the worktree-board-1b7299f662592aa4 branch July 2, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/providers For features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.) kind/refactor PR refactors code without behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants