Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions agentops/instrumentation/crewai/instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
from opentelemetry.sdk.resources import SERVICE_NAME, TELEMETRY_SDK_NAME, DEPLOYMENT_ENVIRONMENT
from agentops.instrumentation.crewai.version import __version__
from agentops.semconv import SpanAttributes, AgentOpsSpanKindValues, Meters, ToolAttributes, MessageAttributes
from agentops.semconv.core import CoreAttributes

Check warning on line 16 in agentops/instrumentation/crewai/instrumentation.py

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L16

Added line #L16 was not covered by tests
from .crewai_span_attributes import CrewAISpanAttributes, set_span_attribute
from agentops import get_client

Check warning on line 18 in agentops/instrumentation/crewai/instrumentation.py

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L18

Added line #L18 was not covered by tests

# Initialize logger
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -159,12 +161,20 @@
logger.debug(
f"CrewAI: Starting workflow instrumentation for Crew with {len(getattr(instance, 'agents', []))} agents"
)

config = get_client().config
attributes = {

Check warning on line 166 in agentops/instrumentation/crewai/instrumentation.py

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L165-L166

Added lines #L165 - L166 were not covered by tests
SpanAttributes.LLM_SYSTEM: "crewai",
}

if config.default_tags and len(config.default_tags) > 0:
tag_list = list(config.default_tags)
attributes[CoreAttributes.TAGS] = tag_list

Check warning on line 172 in agentops/instrumentation/crewai/instrumentation.py

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L170-L172

Added lines #L170 - L172 were not covered by tests

with tracer.start_as_current_span(
"crewai.workflow",
kind=SpanKind.INTERNAL,
attributes={
SpanAttributes.LLM_SYSTEM: "crewai",
},
attributes=attributes,
) as span:
try:
span.set_attribute(TELEMETRY_SDK_NAME, "agentops")
Expand Down Expand Up @@ -381,12 +391,21 @@
):
task_name = instance.description if hasattr(instance, "description") else "task"

config = get_client().config
attributes = {

Check warning on line 395 in agentops/instrumentation/crewai/instrumentation.py

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L394-L395

Added lines #L394 - L395 were not covered by tests
SpanAttributes.AGENTOPS_SPAN_KIND: AgentOpsSpanKindValues.TASK.value,
}

if config.default_tags and len(config.default_tags) > 0:
tag_list = list(config.default_tags)

Check warning on line 400 in agentops/instrumentation/crewai/instrumentation.py

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L399-L400

Added lines #L399 - L400 were not covered by tests
# TODO: This should be a set to prevent duplicates, but we need to ensure
# that the tags are not modified in place, so we convert to list first.
attributes[CoreAttributes.TAGS] = tag_list

Check warning on line 403 in agentops/instrumentation/crewai/instrumentation.py

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L403

Added line #L403 was not covered by tests

with tracer.start_as_current_span(
f"{task_name}.task",
kind=SpanKind.CLIENT,
attributes={
SpanAttributes.AGENTOPS_SPAN_KIND: AgentOpsSpanKindValues.TASK.value,
},
attributes=attributes,
) as span:
try:
span.set_attribute(TELEMETRY_SDK_NAME, "agentops")
Expand Down
52 changes: 52 additions & 0 deletions tests/unit/test_session_legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,55 @@ def test_crewai_kwargs_force_flush():

# Explicitly ensure the core isn't already shut down for the test
assert TracingCore.get_instance()._initialized, "TracingCore should still be initialized"


def test_crewai_task_instrumentation(instrumentation):
"""
Test the CrewAI task instrumentation focusing on span attributes and tags.
This test verifies that task spans are properly created with correct attributes
and tags without requiring a session.
"""
import agentops
from opentelemetry.trace import SpanKind
from agentops.semconv import SpanAttributes, AgentOpsSpanKindValues
from opentelemetry import trace
from agentops.semconv.core import CoreAttributes

# Initialize AgentOps with API key and default tags
agentops.init(
api_key="test-api-key",
)
agentops.start_session(tags=["test", "crewai-integration"])
# Get the tracer
tracer = trace.get_tracer(__name__)

# Create a mock task instance
class MockTask:
def __init__(self):
self.description = "Test Task Description"
self.agent = "Test Agent"
self.tools = ["tool1", "tool2"]

task = MockTask()

# Start a span for the task
with tracer.start_as_current_span(
f"{task.description}.task",
kind=SpanKind.CLIENT,
attributes={
SpanAttributes.AGENTOPS_SPAN_KIND: AgentOpsSpanKindValues.TASK.value,
CoreAttributes.TAGS: ["crewai", "task-test"],
},
) as span:
# Verify span attributes
assert span.attributes[SpanAttributes.AGENTOPS_SPAN_KIND] == AgentOpsSpanKindValues.TASK.value
assert "crewai" in span.attributes[CoreAttributes.TAGS]
assert "task-test" in span.attributes[CoreAttributes.TAGS]

# Verify span name
assert span.name == f"{task.description}.task"

# Verify span kind
assert span.kind == SpanKind.CLIENT

agentops.end_session(end_state="Success", end_state_reason="Test Finished", is_auto_end=True)
Loading