* Dedupe URL routing helpers and tighten adjacent hostname checks * Match providers by hostname, not substring, in _detect_provider _detect_provider used `"anthropic.com" in url`-style substring checks, so a URL that merely contained a provider's domain in its path or query — or a look-alike host like `anthropic.com.example` — was misclassified and picked the wrong auth-header/payload shape. Switch it to the existing `_host_match` helper (hostname exact/subdomain match), the same way the human-readable labels and curated model lists already work, finishing that migration. Also harden `_host_match` against trailing-dot FQDNs. Not a credential-leak fix: _detect_provider only classifies a URL the admin already configured next to its key, and the URL — not this function — decides where the request goes. This is a correctness/consistency cleanup. Adds tests that import the real helpers (test_endpoint_resolver.py tests local copies, so it can't catch this) covering the substring false-positives. Refs #768. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Import build_headers under its real name in model_routes It was imported as `build_headers as _provider_headers`, which collides with the unrelated llm_core._provider_headers(provider, headers) — same name, different signature. Use the real name to remove the confusion. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Use hostname matching in URL builders, not raw suffix checks PR review flagged that _detect_provider() was hardened to match on hostname, but several helpers still used raw host.endswith("anthropic.com") / host.endswith("ollama.com"), which match adjacent hosts like notanthropic.com / notollama.com. Route the remaining checks through _host_match(): _is_ollama_native_url and _ollama_api_root in llm_core, and _anthropic_api_root / _ollama_api_root in endpoint_resolver. With _detect_provider already hostname-correct, the trailing "or host.endswith(...)" clauses in build_chat_url / build_models_url are redundant, so drop them rather than fix the substring match in place. Add builder-level tests asserting look-alike and domain-in-path hosts route to the OpenAI-compatible default. They import the real builders and fail on the pre-fix code. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
6.0 KiB
6.0 KiB