Form Template Method / Pull Up Method from the Refactoring Guru catalog.
The three SDK-based providers (Claude, OpenAI, Gemini) each had their own
near-identical implementations of:
- validateConnection: try a tiny request, catch errors, map a handful
of patterns, warn on the rest
- validateModelName: iterate regex patterns, warn on no match
- handle{X}Error: switch on HTTP status, map to AIProviderError with
brand-flavored messages
These collapse into three protected hooks on BaseAIProvider:
- getModelNamePatterns(): RegExp[]
- sendValidationProbe(): Promise<void>
- mapProviderError(error): AIProviderError | null
- providerErrorMessages(): Partial<Record<number, string>>
The base owns the wrapping logic (warning, status -> error-type map,
common message patterns). Providers only contribute their unique parts.
Side effects:
- normalizeError now consults mapProviderError before generic mapping,
so provider-specific patterns work via the existing try/catch in
BaseAIProvider.complete/stream. The per-provider try/catch wrappers
around doComplete/doStream are removed.
- The unknown-error message becomes `${providerName} error: ${msg}`
instead of the hardcoded `Provider error:` / `Claude API error:` etc.
- OpenWebUI's HTTP-based validateConnection is preserved (override),
since its non-SDK shape doesn't fit the SDK probe pattern.
Quick-win refactors from the Refactoring Guru catalog:
- Replace Magic Number with Symbolic Constant: extract DEFAULT_TIMEOUT_MS,
DEFAULT_MAX_RETRIES, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE, default
models per provider, and validation prompt into src/constants.ts.
- Parameterize Method: collapse validateTemperature / validateTopP /
validateMaxTokens (and the inline timeout/maxRetries checks) into a
single validateNumberInRange helper with bounds metadata.
- Inline Class / Remove Middle Man: drop the unused ProviderRegistry
class from utils/factory.ts. createProvider now dispatches through
the PROVIDER_REGISTRY const directly instead of a parallel switch.
Also fixes stale VERSION constant in src/index.ts (was 1.3.1).