fix: preserve provider on LiteLLM-routed models - #6849
Conversation
LiteLLM construction computed the real provider in `__new__` but never passed it into init, so `BaseLLM` silently defaulted every shared-path model to `openai`. Infer the provider from a `provider/model` prefix when none is supplied so groq, cohere, mistral, and the rest report themselves correctly to callers like the policy engine.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe change extracts providers from prefixed model identifiers for LiteLLM routing and prevents duplicate prefixes when creating Instructor clients. Tests cover OpenAI, Anthropic, Groq, Together, and Groq-qualified models. ChangesProvider routing
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/crewai/src/crewai/llms/base_llm.py`:
- Around line 277-280: Make provider qualification idempotent across BaseLLM and
the downstream object path: preserve the original qualified model while setting
provider, and ensure the internal instructor path does not prepend provider when
self.llm.model already starts with it. Update the LiteLLM routing flow
accordingly and add a regression test covering a model such as
groq/llama-3.3-70b to verify it is passed only once.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 1d754196-b76d-4390-9e6d-c19b0d4457eb
📒 Files selected for processing (2)
lib/crewai/src/crewai/llms/base_llm.pylib/crewai/tests/test_llm.py
With LiteLLM models now carrying a real `provider` while `model` keeps its `provider/name` form, `InternalInstructor` was building `groq/groq/...` for `instructor.from_provider`. Skip the prefix when the model string is already qualified.
16d6353 to
f9b51fe
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e655682. Configure here.
Preserving the real provider on the LiteLLM path made `format_multimodal_content` emit Anthropic-native blocks for `anthropic/...` models, which LiteLLM rejects. Keep `provider` as the model identity for policies, but format multimodal blocks with the OpenAI chat schema when `is_litellm` is set. Expose the formatter helper on `BaseLLM` so native OpenAI/Azure completions share the same API.
43f14ab to
948b22b
Compare

LiteLLM-routed models kept
LLM.providerstuck on the openai default because construction never passed the computed provider into init. Downstream consumers, including the model-provider allowlist, therefore treated groq, cohere, mistral, and similar calls as openai.BaseLLMnow infers the provider from aprovider/modelprefix when none is supplied.Note
Medium Risk
Changes default provider inference and multimodal/instructor wiring for all LiteLLM-backed models; incorrect behavior could mis-route allowlists or break vision/file payloads, though scope is narrow and well covered by new tests.
Overview
LiteLLM-routed models (
groq/…,cohere/…, etc.) no longer defaultprovidertoopenaiwhen it is omitted at construction.BaseLLMnow setsproviderfrom the model’sprefix/modelstring via_extract_provider, so allowlists and other consumers see the real vendor while routing still goes through LiteLLM.Multimodal file handling is split from provider identity: sync/async message file processing uses
_multimodal_formatter_name()instead ofself.provider. On theLLMLiteLLM path,providerstays (e.g.anthropic) but formatting uses theopenaicontent-block schema LiteLLM expects on the wire.InternalInstructorbuilds the instructor model id without double-prefixing when the model string is already qualified (e.g.groq/llama-3.3-70b).Tests cover prefix → provider on LiteLLM, multimodal formatter behavior, and instructor qualification.
Reviewed by Cursor Bugbot for commit 948b22b. Bugbot is set up for automated code reviews on this repo. Configure here.