fix(llm): strip cache-breakpoint marker in the litellm path (#6789) - #6790
Open
Anai-Guo wants to merge 1 commit into
Open
fix(llm): strip cache-breakpoint marker in the litellm path (#6789)#6790Anai-Guo wants to merge 1 commit into
Anai-Guo wants to merge 1 commit into
Conversation
…c#6789) The agent executor marks stable-prefix messages with a provider-agnostic cache_breakpoint flag. Native providers drop it in BaseLLM._format_messages, but the litellm fallback path (crewai.llm.LLM) never goes through that method, so the unknown field leaked into the request. Providers with strict message schemas — Mistral — reject it with an extra_forbidden validation error, so Agent execution failed for models that work fine via a direct LLM.call(). Strip the marker in LLM._format_messages_for_provider, copying only the messages that carry it so the executor'''s reused buffer keeps its markers across ReAct-loop iterations.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughChangesLiteLLM cache marker handling
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fixes #6789.
A
mistral/*LLM works via a directllm.call("Say hello"), but the same LLM attached to an Agent fails duringcrew.kickoff()with:Root cause
The agent executor marks the stable-prefix messages with a provider-agnostic
cache_breakpointflag (crew_agent_executor.py, viamark_cache_breakpoint). Adapters are expected to translate that marker into their own cache directive, or strip it:is_litellm=False) strip it inBaseLLM._format_messages.crewai.llm.LLM, used formistral/*, and anything not inSUPPORTED_NATIVE_PROVIDERS) does not go through_format_messages— it builds the wire payload in_format_messages_for_provider, which never removed the marker.So for litellm-routed models the unknown
cache_breakpointkey leaked straight into the request. Providers that tolerate extra message fields (OpenAI) silently ignore it; Mistral validates strictly and rejects it. Directllm.call()doesn't hit it because it doesn't carry the executor's markers.Fix
Strip
CACHE_BREAKPOINT_KEYat the top ofLLM._format_messages_for_provider, mirroring what the native path already does. Only the messages that actually carry the marker are copied, so the executor's reused message buffer keeps its markers for later ReAct-loop iterations (the same invariantTestBaseFormatDoesNotMutateguards for the native path).Tests
New
TestLiteLLMStripsMarkerintest_prompt_cache.py:test_provider_format_strips_marker— marker is gone from the wire payload, and the caller's buffer still has it. Fails onmain, passes with the fix.test_unmarked_messages_pass_through— no marker ⇒ payload unchanged.Full
test_prompt_cache.pypasses (11 passed).🤖 Generated with Claude Code