Skip to content

Commit abd14de

Browse files
committed
update
1 parent 0898095 commit abd14de

4 files changed

Lines changed: 60 additions & 74 deletions

File tree

langfuse/_client/constants.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,32 @@
33
This module defines constants used throughout the Langfuse OpenTelemetry integration.
44
"""
55

6+
import enum
7+
from typing import Literal
8+
from typing_extensions import TypeAlias
9+
610
LANGFUSE_TRACER_NAME = "langfuse-sdk"
711

8-
# Valid observation types for the @observe decorator
12+
13+
class ObservationType(str, enum.Enum):
14+
"""Enumeration of valid observation types for Langfuse tracing.
15+
16+
This enum defines all the observation types that can be used with the @observe
17+
decorator and other Langfuse SDK methods.
18+
"""
19+
20+
SPAN = "SPAN"
21+
GENERATION = "GENERATION"
22+
AGENT = "AGENT"
23+
TOOL = "TOOL"
24+
CHAIN = "CHAIN"
25+
RETRIEVER = "RETRIEVER"
26+
EMBEDDING = "EMBEDDING"
27+
EVALUATOR = "EVALUATOR"
28+
GUARDRAIL = "GUARDRAIL"
29+
30+
31+
# Valid observation types for the @observe decorator (lowercase user interface)
932
VALID_OBSERVATION_TYPES = {
1033
"span",
1134
"event",
@@ -14,5 +37,22 @@
1437
"tool",
1538
"chain",
1639
"retriever",
40+
"evaluator",
1741
"embedding",
42+
"guardrail",
1843
}
44+
45+
ObservationTypeLiteralNoEvent: TypeAlias = Literal[
46+
"span",
47+
"generation",
48+
"agent",
49+
"tool",
50+
"chain",
51+
"retriever",
52+
"evaluator",
53+
"embedding",
54+
"guardrail",
55+
]
56+
57+
ObservationTypeLiteral: TypeAlias = ObservationTypeLiteralNoEvent | Literal["event"]
58+
]

langfuse/_client/observe.py

Lines changed: 15 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
Dict,
1111
Generator,
1212
Iterable,
13-
Literal,
1413
Optional,
1514
Tuple,
1615
TypeVar,
@@ -26,7 +25,7 @@
2625
LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED,
2726
)
2827

29-
from langfuse._client.constants import VALID_OBSERVATION_TYPES
28+
from langfuse._client.constants import VALID_OBSERVATION_TYPES, ObservationTypeLiteralNoEvent
3029
from langfuse._client.get_client import _set_current_public_key, get_client
3130
from langfuse._client.span import LangfuseGeneration, LangfuseSpan
3231
from langfuse.types import TraceContext
@@ -67,19 +66,7 @@ def observe(
6766
func: None = None,
6867
*,
6968
name: Optional[str] = None,
70-
as_type: Optional[Literal["generation"]] = None,
71-
type: Optional[
72-
Literal[
73-
"span",
74-
"event",
75-
"generation",
76-
"agent",
77-
"tool",
78-
"chain",
79-
"retriever",
80-
"embedding",
81-
]
82-
] = None,
69+
as_type: Optional[ObservationTypeLiteralNoEvent] = None,
8370
capture_input: Optional[bool] = None,
8471
capture_output: Optional[bool] = None,
8572
transform_to_string: Optional[Callable[[Iterable], str]] = None,
@@ -90,19 +77,7 @@ def observe(
9077
func: Optional[F] = None,
9178
*,
9279
name: Optional[str] = None,
93-
as_type: Optional[Literal["generation"]] = None,
94-
type: Optional[
95-
Literal[
96-
"span",
97-
"event",
98-
"generation",
99-
"agent",
100-
"tool",
101-
"chain",
102-
"retriever",
103-
"embedding",
104-
]
105-
] = None,
80+
as_type: Optional[ObservationTypeLiteralNoEvent] = None,
10681
capture_input: Optional[bool] = None,
10782
capture_output: Optional[bool] = None,
10883
transform_to_string: Optional[Callable[[Iterable], str]] = None,
@@ -119,11 +94,10 @@ def observe(
11994
Args:
12095
func (Optional[Callable]): The function to decorate. When used with parentheses @observe(), this will be None.
12196
name (Optional[str]): Custom name for the created trace or span. If not provided, the function name is used.
122-
as_type (Optional[Literal["generation"]]): Set to "generation" to create a specialized LLM generation span
123-
with model metrics support, suitable for tracking language model outputs.
124-
type (Optional[Literal]): Set the observation type for agentic workflows. Supported values:
125-
"generation", "agent", "tool", "chain", "retriever", "embedding". When specified, creates spans with
126-
the specified type for graph visualization and filtering in the Langfuse UI.
97+
as_type (Optional[Literal]): Set the observation type. Supported values:
98+
"generation", "span", "agent", "tool", "chain", "retriever", "embedding", "evaluator", "guardrail".
99+
When set to "generation", creates a specialized LLM generation span with model metrics support.
100+
Other types create spans with the specified type for graph visualization and filtering in the Langfuse UI.
127101
128102
Returns:
129103
Callable: A wrapped version of the original function that automatically creates and manages Langfuse spans.
@@ -151,7 +125,7 @@ async def generate_answer(query):
151125
152126
For automatic graph instrumentation with agent workflows:
153127
```python
154-
@observe(type="agent")
128+
@observe(as_type="agent")
155129
def planning_agent():
156130
return create_plan()
157131
```
@@ -182,18 +156,11 @@ def sub_process():
182156
- For async functions, the decorator returns an async function wrapper.
183157
- For sync functions, the decorator returns a synchronous wrapper.
184158
"""
185-
if as_type is not None and type is not None:
186-
raise ValueError(
187-
"Cannot specify both 'as_type' and 'type' parameters. Please use only one of them."
188-
)
189-
if type is not None and type not in VALID_OBSERVATION_TYPES:
190-
raise ValueError(
191-
f"Invalid observation type '{type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}"
192-
)
193159
if as_type is not None and as_type not in VALID_OBSERVATION_TYPES:
194-
raise ValueError(
195-
f"Invalid as_type '{as_type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}"
160+
self._log.warning(
161+
f"Invalid as_type '{as_type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}. Defaulting to 'span'."
196162
)
163+
as_type = "span"
197164

198165
function_io_capture_enabled = os.environ.get(
199166
LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, "True"
@@ -210,14 +177,12 @@ def sub_process():
210177
)
211178

212179
def decorator(func: F) -> F:
213-
# TODO: merge smartly with manually set as_type
214-
consolidated_type = type or as_type
215180

216181
return (
217182
self._async_observe(
218183
func,
219184
name=name,
220-
as_type=consolidated_type,
185+
as_type=as_type,
221186
capture_input=should_capture_input,
222187
capture_output=should_capture_output,
223188
transform_to_string=transform_to_string,
@@ -226,7 +191,7 @@ def decorator(func: F) -> F:
226191
else self._sync_observe(
227192
func,
228193
name=name,
229-
as_type=consolidated_type,
194+
as_type=as_type,
230195
capture_input=should_capture_input,
231196
capture_output=should_capture_output,
232197
transform_to_string=transform_to_string,
@@ -253,18 +218,7 @@ def _async_observe(
253218
func: F,
254219
*,
255220
name: Optional[str],
256-
as_type: Optional[
257-
Literal[
258-
"span",
259-
"generation",
260-
"event",
261-
"agent",
262-
"tool",
263-
"chain",
264-
"retriever",
265-
"embedding",
266-
]
267-
],
221+
as_type: Optional[ObservationTypeLiteralNoEvent],
268222
capture_input: bool,
269223
capture_output: bool,
270224
transform_to_string: Optional[Callable[[Iterable], str]] = None,
@@ -373,18 +327,7 @@ def _sync_observe(
373327
func: F,
374328
*,
375329
name: Optional[str],
376-
as_type: Optional[
377-
Literal[
378-
"span",
379-
"generation",
380-
"event",
381-
"agent",
382-
"tool",
383-
"chain",
384-
"retriever",
385-
"embedding",
386-
]
387-
],
330+
as_type: Optional[ObservationTypeLiteralNoEvent],
388331
capture_input: bool,
389332
capture_output: bool,
390333
transform_to_string: Optional[Callable[[Iterable], str]] = None,

langfuse/_client/span.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ def __init__(
109109
prompt: Associated prompt template from Langfuse prompt management
110110
"""
111111
self._otel_span = otel_span
112+
self._otel_span.set_attribute(
113+
LangfuseOtelSpanAttributes.OBSERVATION_TYPE, as_type
114+
)
112115
self._langfuse_client = langfuse_client
113116

114117
self.trace_id = self._langfuse_client._get_otel_trace_id(otel_span)

tests/test_manual_graph_instrumentation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
def test_observe_type_agent_instrumentation():
8-
"""Test @observe(type='agent') with the type-based approach."""
8+
"""Test @observe(as_type='agent') with the as_type-based approach."""
99
langfuse = Langfuse()
1010
api = get_api()
1111

0 commit comments

Comments
 (0)