OpenHands / OpenHands/software-agent-sdk
[Bug]: OpenAI provider prefix stripped twice for namespaced model IDs in Responses API
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 539
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 137
Description
Bug Description
LLMProvider.from_model() parses a model string like openai/openai/example-model into model="openai/example-model" + provider="openai". When as_litellm_call_kwargs() forwards that as model="openai/example-model" + custom_llm_provider="openai", LiteLLM's Responses API path re-parses and strips the openai/ prefix again, sending example-model upstream and causing 400 Model not found.
This also affects any namespaced model ID whose inner segment is a LiteLLM provider name (e.g. openai/openai/o3-mini, mistral/mistral/large).
Upstream report: OpenHands/OpenHands#16365
Expected Behavior
The SDK should pass a model string that, after LiteLLM re-parses it, resolves to the originally parsed openai/example-model.
Actual Behavior
Before the fix, running the repro path through as_litellm_call_kwargs() sends example-model to the upstream endpoint. The upstream returns 400 Model not found because the model identifier has lost its provider namespace.
uv run pytest tests/sdk/llm/test_litellm_provider.py::test_llm_provider_preserves_namespaced_model_after_litellm_reparse -v
The regression test above (introduced in the fix) fails on main and passes after the change.
Acceptance Criteria
-
LLMProvider.as_litellm_call_kwargs()re-adds the provider prefix whenself.modelalready starts with it, so LiteLLM strips exactly one prefix and lands on the correct parsed model. -
uv run pytest tests/sdk/llm/test_litellm_provider.py -vpasses. - Existing nested-provider cases (openrouter, bedrock, mistral, litellm_proxy) continue to pass.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with LLMProvider.as_litellm_call_kwargs() and run tests/sdk/llm/test_litellm_provider.py::test_llm_provider_preserves_namespaced_model_after_litellm_reparse. Review the existing nested-provider tests, then verify the full test file and confirm that namespaced models retain the correct identifier after LiteLLM reparses them.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend-api-design, testing-qa
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100