mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-09-20 01:55:38 +00:00
* fix: append trailing user turn in native Gemini provider GeminiCompletion._format_messages_for_gemini maps assistant messages to Gemini's 'model' role but never guards against the resulting contents list ending on a model turn. CrewAI's own agent loop (max iterations, guardrail retries) can produce exactly that history, and Gemini's generateContent API rejects it with 400 'Requests ending with a model turn are not supported'. Mirrors the existing Mistral/Ollama guard in LLM._format_messages_for_provider, which never applies to Gemini since gemini/google model strings resolve to this native provider instead of the LiteLLM fallback path. Fixes #6972 * fix: append trailing user turn for Gemini on the LiteLLM fallback path LLM._format_messages_for_provider already guards Mistral/Ollama against a trailing assistant turn, but Gemini models routed through the LiteLLM fallback (no google-genai installed, or a model name not recognized as native) had no equivalent guard. litellm's own Vertex/Gemini transformation doesn't handle this either, so the request reaches Gemini's generateContent API unguarded and 400s. Complements the native-provider fix in GeminiCompletion, covering both dispatch paths. * fix: don't append text turn after unresolved Gemini function call Address CodeRabbit review on #6973: appending a plain 'Please continue.' user turn after a trailing model turn that contains an unresolved function_call violates Gemini's function-calling protocol -- it requires a matching functionResponse, not free text. Raise a targeted error instead so the caller notices rather than silently sending a malformed follow-up. Also strengthens the native-provider formatting tests to assert exact role sequence and text content (not just the last role), per review, and adds a regression test for the unresolved-function-call case. * fix: guard None parts when checking Gemini history for unresolved function call contents[-1].parts is typed list[Part] | None; iterating it directly failed mypy (union-attr) on 3.10-3.13. Narrow to [] before the any() check and document the ValueError in the docstring. --------- Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>