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
2 changes: 1 addition & 1 deletion agentops/instrumentation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def get_instance(self) -> BaseInstrumentor:
provider_import_name="openai",
),
InstrumentorLoader(
module_name="opentelemetry.instrumentation.anthropic",
module_name="agentops.instrumentation.anthropic",
class_name="AnthropicInstrumentor",
provider_import_name="anthropic",
),
Expand Down
38 changes: 38 additions & 0 deletions agentops/instrumentation/anthropic/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Anthropic API instrumentation.

This module provides instrumentation for the Anthropic API,
including chat completions, streaming, and event handling.
"""

import logging
from typing import Collection

def get_version() -> str:
"""Get the version of the Anthropic SDK, or 'unknown' if not found

Attempts to retrieve the installed version of the Anthropic SDK using importlib.metadata.
Falls back to 'unknown' if the version cannot be determined.

Returns:
The version string of the Anthropic SDK or 'unknown'
"""
try:
from importlib.metadata import version
return version("anthropic")
except ImportError:
logger.debug("Could not find Anthropic SDK version")
return "unknown"

LIBRARY_NAME = "anthropic"
LIBRARY_VERSION: str = get_version()

logger = logging.getLogger(__name__)

# Import after defining constants to avoid circular imports
from agentops.instrumentation.anthropic.instrumentor import AnthropicInstrumentor # noqa: E402

__all__ = [
"LIBRARY_NAME",
"LIBRARY_VERSION",
"AnthropicInstrumentor",
]
20 changes: 20 additions & 0 deletions agentops/instrumentation/anthropic/attributes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Attribute extraction for Anthropic API instrumentation."""

from agentops.instrumentation.anthropic.attributes.common import get_common_instrumentation_attributes
from agentops.instrumentation.anthropic.attributes.message import get_message_attributes, get_completion_attributes
from agentops.instrumentation.anthropic.attributes.tools import (
extract_tool_definitions,
extract_tool_use_blocks,
extract_tool_results,
get_tool_attributes
)

__all__ = [
"get_common_instrumentation_attributes",
"get_message_attributes",
"get_completion_attributes",
"extract_tool_definitions",
"extract_tool_use_blocks",
"extract_tool_results",
"get_tool_attributes",
]
62 changes: 62 additions & 0 deletions agentops/instrumentation/anthropic/attributes/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""Common attribute extraction for Anthropic instrumentation."""

from typing import Dict, Any

from agentops.logging import logger
from agentops.semconv import InstrumentationAttributes, SpanAttributes
from agentops.instrumentation.common.attributes import AttributeMap, get_common_attributes
from agentops.instrumentation.anthropic import LIBRARY_NAME, LIBRARY_VERSION

def get_common_instrumentation_attributes() -> AttributeMap:
"""Get common instrumentation attributes for the Anthropic instrumentation.

This combines the generic AgentOps attributes with Anthropic specific library attributes.

Returns:
Dictionary of common instrumentation attributes
"""
attributes = get_common_attributes()
attributes.update({
InstrumentationAttributes.LIBRARY_NAME: LIBRARY_NAME,
InstrumentationAttributes.LIBRARY_VERSION: LIBRARY_VERSION,
})
return attributes


def extract_request_attributes(kwargs: Dict[str, Any]) -> AttributeMap:
"""Extract all request attributes from kwargs.

This consolidated function extracts all relevant attributes from the request
kwargs, including model, system prompt, messages, max_tokens, temperature,
and other parameters. It replaces the individual extraction functions with
a single comprehensive approach.

Args:
kwargs: Request keyword arguments

Returns:
Dictionary of extracted request attributes
"""
attributes = {}

# Extract model
if 'model' in kwargs:
attributes[SpanAttributes.LLM_REQUEST_MODEL] = kwargs["model"]

# Extract max_tokens
if 'max_tokens' in kwargs:
attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] = kwargs["max_tokens"]

# Extract temperature
if 'temperature' in kwargs:
attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] = kwargs["temperature"]

# Extract top_p
if "top_p" in kwargs:
attributes[SpanAttributes.LLM_REQUEST_TOP_P] = kwargs["top_p"]

# Extract streaming
if "stream" in kwargs:
attributes[SpanAttributes.LLM_REQUEST_STREAMING] = kwargs["stream"]

return attributes
Loading
Loading