diff --git a/lib/crewai-core/src/crewai_core/telemetry.py b/lib/crewai-core/src/crewai_core/telemetry.py index 026c89243..18476fcf5 100644 --- a/lib/crewai-core/src/crewai_core/telemetry.py +++ b/lib/crewai-core/src/crewai_core/telemetry.py @@ -264,10 +264,12 @@ class Telemetry: def flow_creation_span(self, flow_name: str) -> None: """Records the creation of a new flow.""" + from crewai_core.version import get_crewai_version def _operation() -> None: tracer = trace.get_tracer("crewai.telemetry") span = tracer.start_span("Flow Creation") + self._add_attribute(span, "crewai_version", get_crewai_version()) self._add_attribute(span, "flow_name", flow_name) close_span(span) diff --git a/lib/crewai-core/tests/test_smoke.py b/lib/crewai-core/tests/test_smoke.py index 44e350282..573101847 100644 --- a/lib/crewai-core/tests/test_smoke.py +++ b/lib/crewai-core/tests/test_smoke.py @@ -233,3 +233,31 @@ def test_core_telemetry_records_feature_usage( tracer.start_span.assert_called_once_with("Feature Usage") span.set_attribute.assert_any_call("feature", "cli_usage:view_traces") span.end.assert_called_once() + + +def test_core_telemetry_records_flow_creation_version( + monkeypatch: pytest.MonkeyPatch, +) -> None: + from crewai_core.telemetry import Telemetry + + Telemetry._instance = None + monkeypatch.delenv("OTEL_SDK_DISABLED", raising=False) + monkeypatch.delenv("CREWAI_DISABLE_TELEMETRY", raising=False) + monkeypatch.delenv("CREWAI_DISABLE_TRACKING", raising=False) + monkeypatch.setattr("crewai_core.version.get_crewai_version", lambda: "1.0.0") + + tracer = Mock() + span = Mock() + tracer.start_span.return_value = span + monkeypatch.setattr( + "crewai_core.telemetry.trace.get_tracer", + lambda _name: tracer, + ) + + telemetry = Telemetry() + telemetry.flow_creation_span("ResearchFlow") + + tracer.start_span.assert_called_once_with("Flow Creation") + span.set_attribute.assert_any_call("crewai_version", "1.0.0") + span.set_attribute.assert_any_call("flow_name", "ResearchFlow") + span.end.assert_called_once() diff --git a/lib/crewai/src/crewai/telemetry/telemetry.py b/lib/crewai/src/crewai/telemetry/telemetry.py index c6c0060d1..c149f1fb3 100644 --- a/lib/crewai/src/crewai/telemetry/telemetry.py +++ b/lib/crewai/src/crewai/telemetry/telemetry.py @@ -949,6 +949,7 @@ class Telemetry: def _operation() -> None: tracer = trace.get_tracer("crewai.telemetry") span = tracer.start_span("Flow Creation") + self._add_attribute(span, "crewai_version", version("crewai")) self._add_attribute(span, "flow_name", flow_name) close_span(span) diff --git a/lib/crewai/tests/telemetry/test_telemetry.py b/lib/crewai/tests/telemetry/test_telemetry.py index 3bb05b8bd..7ffd8f1b6 100644 --- a/lib/crewai/tests/telemetry/test_telemetry.py +++ b/lib/crewai/tests/telemetry/test_telemetry.py @@ -96,6 +96,32 @@ def test_flow_execution_span_records_crewai_version(): span.set_attribute.assert_any_call("flow_name", "ResearchFlow") +def test_flow_creation_span_records_crewai_version(): + tracer = Mock() + span = Mock() + tracer.start_span.return_value = span + + with ( + patch.dict( + os.environ, + { + "CREWAI_DISABLE_TELEMETRY": "false", + "CREWAI_DISABLE_TRACKING": "false", + "OTEL_SDK_DISABLED": "false", + }, + ), + patch("crewai.telemetry.telemetry.TracerProvider"), + patch("crewai.telemetry.telemetry.trace.get_tracer", return_value=tracer), + patch("crewai.telemetry.telemetry.version", return_value="9.9.9"), + ): + telemetry = Telemetry() + telemetry.flow_creation_span("ResearchFlow") + + tracer.start_span.assert_called_once_with("Flow Creation") + span.set_attribute.assert_any_call("crewai_version", "9.9.9") + span.set_attribute.assert_any_call("flow_name", "ResearchFlow") + + @patch("crewai.telemetry.telemetry.logger.error") @patch( "opentelemetry.exporter.otlp.proto.http.trace_exporter.OTLPSpanExporter.export",