mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-01 13:18:10 +00:00
Three cohesion cleanups uncovered during PR review, all behavior-preserving: - LLM.call / LLM.acall in llm.py now delegate to BaseLLM._emit_call_started_event instead of constructing LLMCallStartedEvent inline. The base helper already introspects sampling params off self via getattr; the inline duplication was accidental, not justified, and a duplication risk if anyone adds a tenth OTel sampling param later. - Extracted lib/crewai/llms/_finish_reason_utils.py:extract_choices_finish_reason_and_id as the shared extractor for the choices-based response shape. OpenAI Chat, Azure, and LiteLLM all read the same shape (response.id + choices[0].finish_reason) as both object attrs and dict keys. Providers with genuinely different shapes - Anthropic (stop_reason), Bedrock (stopReason), Gemini (protobuf enum), OpenAI Responses (status) - keep their own provider-specific helpers. - Dropped redundant try/except (AttributeError, TypeError) wrappers around bare getattr(obj, "field", None) calls across the new extraction helpers. getattr with a default already suppresses AttributeError, and the inner isinstance / dict.get / int-coercion ops can't raise TypeError in practice. Kept the catches that legitimately guard against IndexError (e.g. choices[0] on an empty list). Tests: 600 passed, 23 skipped, 14 pre-existing multimodal failures unchanged. Added 12 parametrized tests for the shared helper covering object + dict shapes, missing fields, non-string coercion, and never-raises invariants.