Skip to content
Closed
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
3 changes: 3 additions & 0 deletions agentops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def init(
log_level: Optional[Union[str, int]] = None,
fail_safe: Optional[bool] = None,
exporter_endpoint: Optional[str] = None,
session_name: Optional[str] = None,
**kwargs,
):
"""
Expand Down Expand Up @@ -88,6 +89,7 @@ def init(
fail_safe (bool): Whether to suppress errors and continue execution when possible.
exporter_endpoint (str, optional): Endpoint for the exporter. If none is provided, key will
be read from the AGENTOPS_EXPORTER_ENDPOINT environment variable.
session_name (str, optional): Name of the session to be used in the span attributes.
**kwargs: Additional configuration parameters to be passed to the client.
"""
global _client
Expand Down Expand Up @@ -116,6 +118,7 @@ def init(
log_level=log_level,
fail_safe=fail_safe,
exporter_endpoint=exporter_endpoint,
session_name=session_name,
**kwargs,
)

Expand Down
12 changes: 10 additions & 2 deletions agentops/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,18 @@
if self.config.auto_start_session:
from agentops.legacy import start_session

# Pass default_tags if they exist
if self.config.default_tags:
if self.config.default_tags and self.config.session_name:
logger.debug(f"Starting session with tags: {self.config.default_tags}")
logger.debug(f"Starting session with name: {self.config.session_name}")
session = start_session(session_name=self.config.session_name, tags=list(self.config.default_tags))

Check warning on line 105 in agentops/client/client.py

View check run for this annotation

Codecov / codecov/patch

agentops/client/client.py#L103-L105

Added lines #L103 - L105 were not covered by tests
elif self.config.default_tags:
logger.debug(f"Starting session with tags: {self.config.default_tags}")

Check warning on line 107 in agentops/client/client.py

View check run for this annotation

Codecov / codecov/patch

agentops/client/client.py#L107

Added line #L107 was not covered by tests
session = start_session(tags=list(self.config.default_tags))
elif self.config.session_name:
logger.debug(f"Starting session with name: {self.config.session_name}")
session = start_session(session_name=self.config.session_name)

Check warning on line 111 in agentops/client/client.py

View check run for this annotation

Codecov / codecov/patch

agentops/client/client.py#L110-L111

Added lines #L110 - L111 were not covered by tests
else:
logger.debug("Starting session without tags or name")
session = start_session()

# Register this session globally
Expand Down
10 changes: 10 additions & 0 deletions agentops/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@
default_factory=lambda: None, metadata={"description": "Custom span processor for OpenTelemetry trace data"}
)

session_name: Optional[str] = field(
default_factory=lambda: None,
metadata={"description": "Name of the session to be used in the span attributes"},
)

def configure(
self,
api_key: Optional[str] = None,
Expand All @@ -144,6 +149,7 @@
exporter: Optional[SpanExporter] = None,
processor: Optional[SpanProcessor] = None,
exporter_endpoint: Optional[str] = None,
session_name: Optional[str] = None,
):
"""Configure settings from kwargs, validating where necessary"""
if api_key is not None:
Expand Down Expand Up @@ -214,6 +220,9 @@
# else:
# self.exporter_endpoint = self.endpoint

if session_name is not None:
self.session_name = session_name

Check warning on line 224 in agentops/config.py

View check run for this annotation

Codecov / codecov/patch

agentops/config.py#L224

Added line #L224 was not covered by tests

def dict(self):
"""Return a dictionary representation of the config"""
return {
Expand All @@ -235,6 +244,7 @@
"exporter": self.exporter,
"processor": self.processor,
"exporter_endpoint": self.exporter_endpoint,
"session_name": self.session_name,
}

def json(self):
Expand Down
61 changes: 50 additions & 11 deletions agentops/instrumentation/crewai/instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from agentops.instrumentation.crewai.version import __version__
from agentops.semconv import SpanAttributes, AgentOpsSpanKindValues, Meters, ToolAttributes, MessageAttributes
from .crewai_span_attributes import CrewAISpanAttributes, set_span_attribute
from agentops import get_client

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L17

Added line #L17 was not covered by tests


# Initialize logger
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -156,15 +158,26 @@
args,
kwargs,
):
span_name = "crewai.workflow"

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L161

Added line #L161 was not covered by tests
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.session_name:
span_name = f"{config.session_name}.workflow"

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

View check run for this annotation

Codecov / codecov/patch

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

Added lines #L170 - L171 were not covered by tests

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

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L173-L175

Added lines #L173 - L175 were not covered by tests

with tracer.start_as_current_span(
"crewai.workflow",
name=span_name,
kind=SpanKind.INTERNAL,
attributes={
SpanAttributes.LLM_SYSTEM: "crewai",
},
attributes=attributes,
) as span:
try:
span.set_attribute(TELEMETRY_SDK_NAME, "agentops")
Expand Down Expand Up @@ -327,12 +340,19 @@
tracer, duration_histogram, token_histogram, environment, application_name, wrapped, instance, args, kwargs
):
agent_name = instance.role if hasattr(instance, "role") else "agent"
attributes = {

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L343

Added line #L343 was not covered by tests
SpanAttributes.AGENTOPS_SPAN_KIND: AgentOpsSpanKindValues.AGENT.value,
}

config = get_client().config
if config.default_tags and len(config.default_tags) > 0:
tag_list = list(config.default_tags)
attributes[SpanAttributes.AGENTOPS_SPAN_TAGS] = tag_list

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L347-L350

Added lines #L347 - L350 were not covered by tests

with tracer.start_as_current_span(
f"{agent_name}.agent",
kind=SpanKind.CLIENT,
attributes={
SpanAttributes.AGENTOPS_SPAN_KIND: AgentOpsSpanKindValues.AGENT.value,
},
attributes=attributes,
) as span:
try:
span.set_attribute(TELEMETRY_SDK_NAME, "agentops")
Expand Down Expand Up @@ -381,12 +401,22 @@
):
task_name = instance.description if hasattr(instance, "description") else "task"

config = get_client().config
attributes = {

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L404-L405

Added lines #L404 - L405 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)
attributes[SpanAttributes.AGENTOPS_SPAN_TAGS] = tag_list

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L409-L411

Added lines #L409 - L411 were not covered by tests

if config.session_name:
task_name = config.session_name

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L413-L414

Added lines #L413 - L414 were 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 All @@ -411,7 +441,16 @@
tracer, duration_histogram, token_histogram, environment, application_name, wrapped, instance, args, kwargs
):
llm = instance.model if hasattr(instance, "model") else "llm"
with tracer.start_as_current_span(f"{llm}.llm", kind=SpanKind.CLIENT, attributes={}) as span:
attributes = {

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L444

Added line #L444 was not covered by tests
SpanAttributes.AGENTOPS_SPAN_KIND: AgentOpsSpanKindValues.LLM.value,
}

config = get_client().config
if config.default_tags and len(config.default_tags) > 0:
tag_list = list(config.default_tags)
attributes[SpanAttributes.AGENTOPS_SPAN_TAGS] = tag_list

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L448-L451

Added lines #L448 - L451 were not covered by tests

with tracer.start_as_current_span(f"{llm}.llm", kind=SpanKind.CLIENT, attributes=attributes) as span:

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

View check run for this annotation

Codecov / codecov/patch

agentops/instrumentation/crewai/instrumentation.py#L453

Added line #L453 was not covered by tests
start_time = time.time()
try:
span.set_attribute(TELEMETRY_SDK_NAME, "agentops")
Expand Down
11 changes: 8 additions & 3 deletions agentops/legacy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ def end_session(self, **kwargs):
_flush_span_processors()


def _create_session_span(tags: Union[Dict[str, Any], List[str], None] = None) -> tuple:
def _create_session_span(
session_name: Optional[str] = None, tags: Union[Dict[str, Any], List[str], None] = None
) -> tuple:
"""
Helper function to create a session span with tags.

Expand All @@ -94,10 +96,13 @@ def _create_session_span(tags: Union[Dict[str, Any], List[str], None] = None) ->
attributes = {}
if tags:
attributes["tags"] = tags
return _make_span("session", span_kind=SpanKind.SESSION, attributes=attributes)

span_name = "session" if session_name is None else session_name
return _make_span(span_name, span_kind=SpanKind.SESSION, attributes=attributes)


def start_session(
session_name: Optional[str] = None,
tags: Union[Dict[str, Any], List[str], None] = None,
) -> Session:
"""
Expand Down Expand Up @@ -153,7 +158,7 @@ def start_session(
_current_session = dummy_session
return dummy_session

span, ctx, token = _create_session_span(tags)
span, ctx, token = _create_session_span(session_name, tags)
session = Session(span, token)

# Set the global session reference
Expand Down
1 change: 1 addition & 0 deletions agentops/semconv/span_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class SpanAttributes:
AGENTOPS_ENTITY_INPUT = "agentops.entity.input"
AGENTOPS_SPAN_KIND = "agentops.span.kind"
AGENTOPS_ENTITY_NAME = "agentops.entity.name"
AGENTOPS_SPAN_TAGS = "tags"

# Operation attributes
OPERATION_NAME = "operation.name"
Expand Down
1 change: 1 addition & 0 deletions docs/v1/concepts/sessions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Optionally, sessions may include:
- **Tags**: Tags allow for the categorization and later retrieval of sessions.
- **Host Environment**: Automatically gathers basic information about the system on which the session ran.
- **Video**: If applicable, an optional video recording of the session.
- **Session Name**: A custom name for the session that helps identify and organize different types of sessions in the dashboard. Can be set during initialization or when starting a session.


### Methods
Expand Down
1 change: 1 addition & 0 deletions docs/v1/usage/sdk-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ The first element of AgentOps is always calling .init()
- `auto_start_session` (bool): Whether to start a session automatically when the client is created. You may wish to delay starting a session in order to do additional setup or starting a session on a child process.
- `inherited_session_id` (str, optional): When creating the client, passing in this value will connect the client to an existing session. This is useful when having separate processes contribute to the same session.
- `skip_auto_end_session` (bool, optional): If you are using a framework such as Crew, the framework can decide when to halt execution. Setting this parameter to true will not end your agentops session when this happens.
- `session_name` (str, optional): Name of the session to be used in the span attributes. This helps identify and organize different types of sessions in the dashboard.

**Returns**:

Expand Down
13 changes: 13 additions & 0 deletions docs/v2/concepts/sessions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ import agentops
agentops.init(api_key="YOUR_API_KEY", tags=["production"])
```

You can also provide a custom name for your session during initialization:

```python
import agentops

# Initialize with a custom session name
agentops.init(
api_key="YOUR_API_KEY",
session_name="customer-support-bot",
tags=["production"]
)
```

This approach:
- Creates a session automatically when you initialize the SDK
- Tracks all events in the context of this session
Expand Down
1 change: 1 addition & 0 deletions docs/v2/concepts/tags.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import agentops
agentops.init(
api_key="YOUR_API_KEY",
tags=["production", "customer-service", "gpt-4"]
session_name="customer-support-agent"
)
```

Expand Down
1 change: 1 addition & 0 deletions docs/v2/usage/sdk-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Initializes the AgentOps SDK and automatically starts tracking your application.
- `fail_safe` (bool, optional): Whether to suppress errors and continue execution when possible. Defaults to False.
- `exporter_endpoint` (str, optional): Endpoint for the exporter. If not provided, will be read from the `AGENTOPS_EXPORTER_ENDPOINT` environment variable. Defaults to 'https://otlp.agentops.ai/v1/traces'.
- `export_flush_interval` (int, optional): Time interval in milliseconds between automatic exports of telemetry data. Defaults to 1000.
- `session_name` (str, optional): Name of the session to be used in the span attributes. This helps identify and organize different types of sessions in the dashboard.

**Returns**:

Expand Down
Loading