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
10 changes: 10 additions & 0 deletions langfuse/_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ def _get_current_otel_span(self) -> Optional[otel_trace_api.Span]:
def update_current_generation(
self,
*,
name: Optional[str] = None,
input: Optional[Any] = None,
output: Optional[Any] = None,
metadata: Optional[Any] = None,
Expand All @@ -793,6 +794,7 @@ def update_current_generation(
details that become available during or after model generation.

Args:
name: The generation name
input: Updated input data for the model
output: Output from the model (e.g., completions)
metadata: Additional metadata to associate with the generation
Expand Down Expand Up @@ -835,6 +837,9 @@ def update_current_generation(
otel_span=current_otel_span, langfuse_client=self
)

if name:
Comment thread
hassiebp marked this conversation as resolved.
current_otel_span.update_name(name)

generation.update(
input=input,
output=output,
Expand All @@ -853,6 +858,7 @@ def update_current_generation(
def update_current_span(
self,
*,
name: Optional[str] = None,
input: Optional[Any] = None,
output: Optional[Any] = None,
metadata: Optional[Any] = None,
Expand All @@ -867,6 +873,7 @@ def update_current_span(
that become available during execution.

Args:
name: The span name
input: Updated input data for the operation
output: Output data from the operation
metadata: Additional metadata to associate with the span
Expand Down Expand Up @@ -905,6 +912,9 @@ def update_current_span(
environment=self._environment,
)

if name:
current_otel_span.update_name(name)

span.update(
input=input,
output=output,
Expand Down
10 changes: 10 additions & 0 deletions langfuse/_client/span.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ def __init__(
def update(
self,
*,
name: Optional[str] = None,
input: Optional[Any] = None,
output: Optional[Any] = None,
metadata: Optional[Any] = None,
Expand All @@ -575,6 +576,7 @@ def update(
during execution, such as outputs, metadata, or status changes.

Args:
name: Span name
input: Updated input data for the operation
output: Output data from the operation
metadata: Additional metadata to associate with the span
Expand Down Expand Up @@ -607,6 +609,9 @@ def update(
data=metadata, field="metadata", span=self._otel_span
)

if name:
self._otel_span.update_name(name)

attributes = create_span_attributes(
input=processed_input,
output=processed_output,
Expand Down Expand Up @@ -1048,6 +1053,7 @@ def __init__(
def update(
self,
*,
name: Optional[str] = None,
input: Optional[Any] = None,
output: Optional[Any] = None,
metadata: Optional[Any] = None,
Expand All @@ -1069,6 +1075,7 @@ def update(
token usage statistics, or cost details.

Args:
name: The generation name
input: Updated input data for the model
output: Output from the model (e.g., completions)
metadata: Additional metadata to associate with the generation
Expand Down Expand Up @@ -1123,6 +1130,9 @@ def update(
data=metadata, field="metadata", span=self._otel_span
)

if name:
self._otel_span.update_name(name)

attributes = create_generation_attributes(
input=processed_input,
output=processed_output,
Expand Down
74 changes: 74 additions & 0 deletions tests/test_otel.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,23 @@ def test_span_hierarchy(self, langfuse_client, memory_exporter):
# All spans should have the same trace ID
assert len(set(s["trace_id"] for s in spans)) == 1

def test_update_current_span_name(self, langfuse_client, memory_exporter):
"""Test updating current span name via update_current_span method."""
# Create a span using context manager
with langfuse_client.start_as_current_span(name="original-current-span"):
# Update the current span name
langfuse_client.update_current_span(name="updated-current-span")

# Verify the span name was updated
spans = self.get_spans_by_name(memory_exporter, "updated-current-span")
assert len(spans) == 1, "Expected one span with updated name"

# Also verify no spans exist with the original name
original_spans = self.get_spans_by_name(
memory_exporter, "original-current-span"
)
assert len(original_spans) == 0, "Expected no spans with original name"

def test_span_attributes(self, langfuse_client, memory_exporter):
"""Test that span attributes are correctly set and updated."""
# Create a span with attributes
Expand Down Expand Up @@ -360,6 +377,23 @@ def test_span_attributes(self, langfuse_client, memory_exporter):
== "Test status"
)

def test_span_name_update(self, langfuse_client, memory_exporter):
"""Test updating span name via update method."""
# Create a span with initial name
span = langfuse_client.start_span(name="original-span-name")

# Update the span name
span.update(name="updated-span-name")
span.end()

# Verify the span name was updated
spans = self.get_spans_by_name(memory_exporter, "updated-span-name")
assert len(spans) == 1, "Expected one span with updated name"

# Also verify no spans exist with the original name
original_spans = self.get_spans_by_name(memory_exporter, "original-span-name")
assert len(original_spans) == 0, "Expected no spans with original name"

def test_generation_span(self, langfuse_client, memory_exporter):
"""Test creating a generation span with model-specific attributes."""
# Create a generation
Expand Down Expand Up @@ -394,6 +428,27 @@ def test_generation_span(self, langfuse_client, memory_exporter):
)
assert usage == {"input": 10, "output": 5, "total": 15}

def test_generation_name_update(self, langfuse_client, memory_exporter):
"""Test updating generation name via update method."""
# Create a generation with initial name
generation = langfuse_client.start_generation(
name="original-generation-name", model="gpt-4"
)

# Update the generation name
generation.update(name="updated-generation-name")
generation.end()

# Verify the generation name was updated
spans = self.get_spans_by_name(memory_exporter, "updated-generation-name")
assert len(spans) == 1, "Expected one generation with updated name"

# Also verify no spans exist with the original name
original_spans = self.get_spans_by_name(
memory_exporter, "original-generation-name"
)
assert len(original_spans) == 0, "Expected no generations with original name"

def test_trace_update(self, langfuse_client, memory_exporter):
"""Test updating trace level attributes."""
# Create a span and update trace attributes
Expand Down Expand Up @@ -514,6 +569,25 @@ def test_complex_scenario(self, langfuse_client, memory_exporter):
assert llm_input == {"prompt": "Summarize this text"}
assert llm_output == {"text": "This is a summary"}

def test_update_current_generation_name(self, langfuse_client, memory_exporter):
"""Test updating current generation name via update_current_generation method."""
# Create a generation using context manager
with langfuse_client.start_as_current_generation(
name="original-current-generation", model="gpt-4"
):
# Update the current generation name
langfuse_client.update_current_generation(name="updated-current-generation")

# Verify the generation name was updated
spans = self.get_spans_by_name(memory_exporter, "updated-current-generation")
assert len(spans) == 1, "Expected one generation with updated name"

# Also verify no spans exist with the original name
original_spans = self.get_spans_by_name(
memory_exporter, "original-current-generation"
)
assert len(original_spans) == 0, "Expected no generations with original name"

def test_custom_trace_id(self, langfuse_client, memory_exporter):
"""Test setting a custom trace ID."""
# Create a custom trace ID
Expand Down