2222from typing_extensions import TypeAlias
2323
2424from opentelemetry .context import Context
25+ from opentelemetry .semconv .attributes import error_attributes
2526from opentelemetry .trace import INVALID_SPAN as _INVALID_SPAN
2627from opentelemetry .trace import Span , SpanKind
28+ from opentelemetry .trace .status import Status , StatusCode
2729
2830if TYPE_CHECKING :
2931 from opentelemetry .util .genai .handler import TelemetryHandler
30- from opentelemetry .semconv .attributes import error_attributes
31- from opentelemetry .trace .status import Status , StatusCode
3232
3333ContextToken : TypeAlias = Token [Context ]
3434
3535
36- @dataclass ()
37- class GenericPart :
38- """Used for provider-specific message part types that don't match
39- the standard MessagePart types defined in semantic conventions. Wrap custom
40- types with GenericPart(value=...) to explicitly opt-in to non-standard types.
41- This will be removed in a future version when all instrumentations use core types."""
42-
43- value : Any
44- type : Literal ["generic" ] = "generic"
45-
46-
4736class ContentCapturingMode (Enum ):
4837 # Do not capture content (default).
4938 NO_CONTENT = 0
@@ -55,6 +44,17 @@ class ContentCapturingMode(Enum):
5544 SPAN_AND_EVENT = 3
5645
5746
47+ @dataclass ()
48+ class GenericPart :
49+ """Used for provider-specific message part types that don't match
50+ the standard MessagePart types defined in semantic conventions. Wrap custom
51+ types with GenericPart(value=...) to explicitly opt-in to non-standard types.
52+ This will be removed in a future version when all instrumentations use core types."""
53+
54+ value : Any
55+ type : Literal ["generic" ] = "generic"
56+
57+
5858@dataclass ()
5959class ToolCallRequest :
6060 """Represents a tool call requested by the model (message part only).
@@ -293,7 +293,6 @@ def _apply_error_attributes(self, error: Error) -> None:
293293 def _apply_finish (self , _error : Error | None = None ) -> None :
294294 """Apply finish telemetry (attributes, metrics, events)."""
295295 # nothing to do at the base class level
296- pass
297296
298297 def stop (self ) -> None :
299298 """Finalize the invocation successfully and end its span."""
@@ -306,6 +305,11 @@ def fail(self, error: Error | BaseException) -> None:
306305 self ._handler ._finish (self , error )
307306
308307
309- from opentelemetry .util .genai .inference_invocation import (
310- LLMInvocation , # noqa: F401
311- )
308+ def __getattr__ (name : str ) -> object :
309+ if name == "LLMInvocation" :
310+ from opentelemetry .util .genai .inference_invocation import ( # noqa: PLC0415 # pylint: disable=import-outside-toplevel
311+ LLMInvocation ,
312+ )
313+
314+ return LLMInvocation
315+ raise AttributeError (f"module { __name__ !r} has no attribute { name !r} " )
0 commit comments