Skip to content
Draft
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
1 change: 1 addition & 0 deletions util/opentelemetry-util-genai/.changelog/300.removed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove deprecated ``start_inference``, ``start_llm``, ``start_embedding``, ``start_tool``, ``start_workflow``, ``stop_llm``, ``fail_llm``, ``start_invoke_local_agent``, and ``start_invoke_remote_agent`` methods from ``TelemetryHandler``. Use ``inference()``, ``embedding()``, ``tool()``, ``workflow()``, ``invoke_local_agent()``, and ``invoke_remote_agent()`` instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ def _maybe_create_event(self) -> LogRecord | None:
class LLMInvocation:
"""Deprecated. Use InferenceInvocation instead.

Data container for an LLM invocation. Pass to handler.llm() to start
the span, then update fields and call handler.stop_llm() or handler.fail_llm().
Data container for an LLM invocation. Pass to handler.inference() to start
the span, then update fields and call invocation.stop() or invocation.fail().
"""

request_model: str | None = None
Expand Down Expand Up @@ -261,7 +261,7 @@ def _start_with_handler(
logger: Logger,
completion_hook: CompletionHook,
) -> None:
"""Create and start an InferenceInvocation from this data container. Called by handler.start_llm()."""
"""Create and start an InferenceInvocation from this data container. Called by handler.inference()."""
inv = InferenceInvocation(
tracer,
metrics_recorder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@
get_tracer,
)
from opentelemetry.util.genai._agent_invocation import AgentInvocation
from opentelemetry.util.genai._inference_invocation import LLMInvocation
from opentelemetry.util.genai._invocation import Error
from opentelemetry.util.genai.completion_hook import (
CompletionHook,
_NoOpCompletionHook,
Expand Down Expand Up @@ -126,77 +124,6 @@ def should_capture_content(self) -> bool:
"""
return self._capture_content

# New-style factory methods: construct + start in one call, handler stored on invocation
def start_inference(
self,
provider: str,
*,
request_model: str | None = None,
server_address: str | None = None,
server_port: int | None = None,
operation_name: str | None = None,
) -> InferenceInvocation:
"""Create and start an LLM inference invocation.

.. deprecated:: 1.0b0
Use ``handler.inference()`` instead.

Set remaining attributes (input_messages, temperature, etc.) on the
returned invocation, then call invocation.stop() or invocation.fail().
"""
return InferenceInvocation(
self._tracer,
self._metrics_recorder,
self._logger,
self._completion_hook,
provider,
request_model=request_model,
server_address=server_address,
server_port=server_port,
operation_name=operation_name,
)

def start_llm(self, invocation: LLMInvocation) -> LLMInvocation:
"""Start an LLM invocation.

.. deprecated::
Use ``handler.inference()`` instead.
"""
invocation._start_with_handler(
self._tracer,
self._metrics_recorder,
self._logger,
self._completion_hook,
)
return invocation

def start_embedding(
self,
provider: str,
*,
request_model: str | None = None,
server_address: str | None = None,
server_port: int | None = None,
) -> EmbeddingInvocation:
"""Create and start an Embedding invocation.

.. deprecated:: 1.0b0
Use ``handler.embedding()`` instead.

Set remaining attributes (encoding_formats, etc.) on the returned
invocation, then call invocation.stop() or invocation.fail().
"""
return EmbeddingInvocation(
self._tracer,
self._metrics_recorder,
self._logger,
self._completion_hook,
provider,
request_model=request_model,
server_address=server_address,
server_port=server_port,
)

def retrieval(
self,
*,
Expand Down Expand Up @@ -226,80 +153,6 @@ def retrieval(
server_port=server_port,
)

def start_tool(
self,
name: str,
*,
tool_call_id: str | None = None,
tool_type: str | None = None,
tool_description: str | None = None,
) -> ToolInvocation:
"""Create and start a tool invocation.

.. deprecated:: 1.0b0
Use ``handler.tool()`` instead.

Set tool_result on the returned invocation when done, then call
invocation.stop() or invocation.fail().
"""
return ToolInvocation(
self._tracer,
self._metrics_recorder,
self._logger,
self._completion_hook,
name,
tool_call_id=tool_call_id,
tool_type=tool_type,
tool_description=tool_description,
)

def start_workflow(
self,
*,
name: str | None = None,
) -> WorkflowInvocation:
"""Create and start a workflow invocation.

.. deprecated:: 1.0b0
Use ``handler.workflow()`` instead.

Set remaining attributes on the returned invocation, then call
invocation.stop() or invocation.fail().
"""
return WorkflowInvocation(
self._tracer,
self._metrics_recorder,
self._logger,
self._completion_hook,
name,
)

def stop_llm(self, invocation: LLMInvocation) -> LLMInvocation: # pylint: disable=no-self-use
"""Finalize an LLM invocation successfully and end its span.

.. deprecated::
Use ``handler.inference()`` and then ``inference.stop()`` instead.
"""
invocation._sync_to_invocation()
if invocation._inference_invocation is not None:
invocation._inference_invocation.stop()
return invocation

def fail_llm( # pylint: disable=no-self-use
self,
invocation: LLMInvocation,
error: Error,
) -> LLMInvocation:
"""Fail an LLM invocation and end its span with error status.

.. deprecated::
Use ``handler.inference()`` and then ``inference.fail()`` instead.
"""
invocation._sync_to_invocation()
if invocation._inference_invocation is not None:
invocation._inference_invocation.fail(error)
return invocation

# New-style factory methods: construct + start in one call, handler stored on invocation

def inference(
Expand Down Expand Up @@ -387,64 +240,6 @@ def tool(
tool_description=tool_description,
)

def start_invoke_local_agent(
self,
*,
request_model: str | None = None,
agent_name: str | None = None,
) -> AgentInvocation:
"""Create and start a local agent invocation (INTERNAL span kind).

.. deprecated:: 1.0b0
Use ``handler.invoke_local_agent()`` instead.

Use for agents running within the same process (e.g. LangChain, CrewAI).

Set remaining attributes (agent_name, etc.) on the returned invocation,
then call invocation.stop() or invocation.fail().
"""
return AgentInvocation(
self._tracer,
self._metrics_recorder,
self._logger,
self._completion_hook,
span_kind=SpanKind.INTERNAL,
request_model=request_model,
agent_name=agent_name,
)

def start_invoke_remote_agent(
self,
provider: str,
*,
request_model: str | None = None,
server_address: str | None = None,
server_port: int | None = None,
agent_name: str | None = None,
) -> AgentInvocation:
"""Create and start a remote agent invocation (CLIENT span kind).

.. deprecated:: 1.0b0
Use ``handler.invoke_remote_agent()`` instead.

Use for agents invoked over a remote service (e.g. OpenAI Assistants, AWS Bedrock).

Set remaining attributes (agent_name, etc.) on the returned invocation,
then call invocation.stop() or invocation.fail().
"""
return AgentInvocation(
self._tracer,
self._metrics_recorder,
self._logger,
self._completion_hook,
provider=provider,
span_kind=SpanKind.CLIENT,
request_model=request_model,
agent_name=agent_name,
server_address=server_address,
server_port=server_port,
)

def invoke_local_agent(
self,
*,
Expand Down
6 changes: 3 additions & 3 deletions util/opentelemetry-util-genai/tests/test_handler_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


class TelemetryHandlerMetricsTest(TestBase):
def test_stop_llm_records_duration_and_tokens(self) -> None:
def test_inference_stop_records_duration_and_tokens(self) -> None:
handler = TelemetryHandler(
tracer_provider=self.tracer_provider,
meter_provider=self.meter_provider,
Expand Down Expand Up @@ -74,7 +74,7 @@ def test_stop_llm_records_duration_and_tokens(self) -> None:
places=3,
)

def test_stop_llm_records_duration_and_tokens_with_additional_attributes(
def test_inference_stop_records_duration_and_tokens_with_additional_attributes(
self,
) -> None:
handler = TelemetryHandler(
Expand Down Expand Up @@ -114,7 +114,7 @@ def test_stop_llm_records_duration_and_tokens_with_additional_attributes(
)
self.assertIsNone(point.attributes.get("should not be on metrics"))

def test_fail_llm_records_error_and_available_tokens(self) -> None:
def test_inference_fail_records_error_and_available_tokens(self) -> None:
handler = TelemetryHandler(
tracer_provider=self.tracer_provider,
meter_provider=self.meter_provider,
Expand Down
12 changes: 6 additions & 6 deletions util/opentelemetry-util-genai/tests/test_handler_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,36 +51,36 @@ class TelemetryHandlerWorkflowTest(_WorkflowTestBase):
# start_workflow
# ------------------------------------------------------------------

def test_start_workflow_creates_span(self) -> None:
def test_workflow_creates_span(self) -> None:
invocation = self.handler.workflow(name="my_workflow")
self.assertIsNot(invocation.span, INVALID_SPAN)
invocation.stop()

def test_start_workflow_span_name(self) -> None:
def test_workflow_span_name(self) -> None:
invocation = self.handler.workflow(name="my_pipeline")
invocation.stop()

spans = self._get_finished_spans()
self.assertEqual(len(spans), 1)
self.assertEqual(spans[0].name, "invoke_workflow my_pipeline")

def test_start_workflow_span_name_without_name(self) -> None:
def test_workflow_span_name_without_name(self) -> None:
invocation = self.handler.workflow(name=None)
invocation.stop()

spans = self._get_finished_spans()
self.assertEqual(len(spans), 1)
self.assertEqual(spans[0].name, "invoke_workflow")

def test_start_workflow_span_kind_is_internal(self) -> None:
def test_workflow_span_kind_is_internal(self) -> None:
invocation = self.handler.workflow(name="wf")
invocation.stop()

spans = self._get_finished_spans()
self.assertEqual(len(spans), 1)
self.assertEqual(spans[0].kind, SpanKind.INTERNAL)

def test_start_workflow_records_monotonic_start(self) -> None:
def test_workflow_records_monotonic_start(self) -> None:
with patch("timeit.default_timer", return_value=500.0):
invocation = self.handler.workflow(name="wf")
self.assertEqual(invocation._monotonic_start_s, 500.0)
Expand Down Expand Up @@ -183,7 +183,7 @@ def test_workflow_context_manager_default_invocation(self) -> None:


class TelemetryHandlerWorkflowSamplingTest(_WorkflowTestBase):
def test_start_workflow_passes_sampling_attributes_at_span_creation(
def test_workflow_passes_sampling_attributes_at_span_creation(
self,
) -> None:
"""Verify that sampling-relevant attributes are available at start_span() time for workflows."""
Expand Down
2 changes: 1 addition & 1 deletion util/opentelemetry-util-genai/tests/test_toolcall.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def test_tool_span_is_internal_kind():
assert span_exporter.get_finished_spans()[0].kind == SpanKind.INTERNAL


def test_start_tool_passes_sampling_attributes_at_span_creation():
def test_tool_passes_sampling_attributes_at_span_creation():
"""Verify that sampling-relevant attributes are available at start_span() time for tools."""
captured_attributes = {}

Expand Down
6 changes: 3 additions & 3 deletions util/opentelemetry-util-genai/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ def test_llm_manual_start_and_stop_creates_span(self):
},
)

def test_start_inference_passes_sampling_attributes_at_span_creation(self):
def test_inference_passes_sampling_attributes_at_span_creation(self):
"""Verify that sampling-relevant attributes are available at start_span() time."""
captured_attributes = {}

Expand Down Expand Up @@ -461,7 +461,7 @@ def get_description(self):
)
assert captured_attributes[server_attributes.SERVER_PORT] == 8080

def test_start_inference_sampler_can_drop_span_based_on_attributes(self):
def test_inference_sampler_can_drop_span_based_on_attributes(self):
"""Verify that a sampler can reject spans based on attributes passed at creation time."""

class ModelRejectingSampler: # pylint: disable=no-self-use
Expand Down Expand Up @@ -512,7 +512,7 @@ def get_description(self):
assert len(spans) == 1
assert spans[0].name == "chat accepted-model"

def test_start_embedding_passes_sampling_attributes_at_span_creation(self):
def test_embedding_passes_sampling_attributes_at_span_creation(self):
"""Verify that sampling-relevant attributes are available at start_span() time for embeddings."""
captured_attributes = {}

Expand Down