fix(CODEWIKI-001): CU-86akhf8u6 default_headers built for Anthropic api_version but never passed to OpenAIProvider, silently dropping the header on every role - #82
Conversation
…t never passed to OpenAIProvider, silently dropping the header on every role
| "Different AI providers require different API keys." | ||
| ) | ||
|
|
||
| return OpenAIModel( | ||
| model_name=config.main_model, | ||
| provider=OpenAIProvider( | ||
| # NOTE: pydantic-ai's OpenAIProvider takes only base_url, api_key, | ||
| # openai_client and http_client - there is no default_headers | ||
| # parameter (verified against pydantic-ai 2.40.0), so passing one | ||
| # raises TypeError. To send anthropic-version here, build an | ||
| # AsyncOpenAI client with default_headers and pass it as openai_client=. | ||
| provider_kwargs = {} | ||
| if default_headers: | ||
| provider_kwargs['openai_client'] = AsyncOpenAI( | ||
| base_url=base_url, | ||
| api_key=api_key, | ||
| # NOTE: pydantic-ai's OpenAIProvider takes only base_url, api_key, | ||
| # openai_client and http_client - there is no default_headers | ||
| # parameter (verified against pydantic-ai 2.40.0), so passing one | ||
| # raises TypeError. To send anthropic-version here, build an | ||
| # AsyncOpenAI client with default_headers and pass it as | ||
| # openai_client=. | ||
| ), | ||
| default_headers=default_headers, | ||
| ) | ||
| else: | ||
| provider_kwargs['base_url'] = base_url | ||
| provider_kwargs['api_key'] = api_key | ||
|
|
||
| return OpenAIModel( | ||
| model_name=config.main_model, | ||
| provider=OpenAIProvider(**provider_kwargs), | ||
| settings=OpenAIModelSettings(**settings_dict) | ||
| ) | ||
|
|
There was a problem hiding this comment.
🦩 🟠 default_headers built for Anthropic api_version but never passed to OpenAIProvider, silently dropping the header on every role
In create_main_model, create_fallback_model, and create_cluster_model (all three, per the finding's scope), the previously discarded default_headers dict is now actually applied: when non-empty, an AsyncOpenAI client is constructed with base_url, api_key, and default_headers=default_headers, and passed to OpenAIProvider(openai_client=...); when empty, OpenAIProvider(base_url=..., api_key=...) is used as before (unchanged behavior for non-Anthropic/no-api_version configs). Added AsyncOpenAI to the from openai import ... line since it is now used. Confidence is not higher because I cannot verify at authorship time that pydantic-ai 2.40.0's OpenAIProvider accepts an openai_client keyword with this exact signature/behavior for all three call sites in this exact version — the in-file comments assert this is the documented workaround, but it is unverified against the installed dependency version in CI. A complete fix would additionally include a unit/integration test exercising main_api_version/fallback_api_version/cluster_api_version to confirm the header actually reaches the wire.
🤖 Prompt for AI agents
In codewiki/src/be/llm_services.py around line 118, review and complete this code-review fix: default_headers built for Anthropic api_version but never passed to OpenAIProvider, silently dropping the header on every role.
What the draft fix changed: In `create_main_model`, `create_fallback_model`, and `create_cluster_model` (all three, per the finding's scope), the previously discarded `default_headers` dict is now actually applied: when non-empty, an `AsyncOpenAI` client is constructed with `base_url`, `api_key`, and `default_headers=default_headers`, and passed to `OpenAIProvider(openai_client=...)`; when empty, `OpenAIProvider(base_url=..., api_key=...)` is used as before (unchanged behavior for non-Anthropic/no-api_version configs). Added `AsyncOpenAI` to the `from openai import ...` line since it is now used. Confidence is not higher because I cannot verify at authorship time that pydantic-ai 2.40.0's `OpenAIProvider` accepts an `openai_client` keyword with this exact signature/behavior for all three call sites in this exact version — the in-file comments assert this is the documented workaround, but it is unverified against the installed dependency version in CI. A complete fix would additionally include a unit/integration test exercising `main_api_version`/`fallback_api_version`/`cluster_api_version` to confirm the header actually reaches the wire.
Verify the change is correct and complete; do not refactor unrelated code.
fix confidence: 🟡 78 medium — react 👍/👎 to teach the reviewer
Closes findings from rule CODEWIKI-001 — default_headers built for Anthropic api_version but never passed to OpenAIProvider, silently dropping the header on every role.
Draft — this is a starting point, not a finished change. The fix required judgment, so read it before trusting it.
codewiki/src/be/llm_services.py:118What changed — and what was deliberately left — is explained per finding as inline review comments on the lines each finding touched.
Run: https://product-hub.flamingo.so/admin/code-review
Run id:
4b0306d9-ca7f-413c-857e-fc323d1e9f21Merging this PR is recorded as acceptance of the rule that produced it;
closing it unmerged is recorded as rejection. Both feed rule health, so
closing a wrong suggestion is useful rather than merely tidy.
ClickUp task: CU-86akhf8u6 CodeWiki review findings sweep (9 PRs)