@@ -1929,3 +1929,91 @@ def test_start_as_current_observation_types():
19291929 if obs .name == f"test-{ obs_type } " and obs .type == obs_type .upper ()
19301930 ]
19311931 assert len (observations ) == 1 , f"Expected one { obs_type .upper ()} observation"
1932+
1933+
1934+ def test_that_generation_like_properties_are_actually_created ():
1935+ """Test that generation-like observation types properly support generation properties."""
1936+ from langfuse ._client .constants import (
1937+ get_observation_types_list ,
1938+ ObservationTypeGenerationLike ,
1939+ )
1940+
1941+ langfuse = Langfuse ()
1942+ generation_like_types = get_observation_types_list (ObservationTypeGenerationLike )
1943+
1944+ test_model = "test-model"
1945+ test_completion_start_time = datetime .now (timezone .utc )
1946+ test_model_parameters = {"temperature" : 0.7 , "max_tokens" : 100 }
1947+ test_usage_details = {"prompt_tokens" : 10 , "completion_tokens" : 20 }
1948+ test_cost_details = {"input" : 0.01 , "output" : 0.02 , "total" : 0.03 }
1949+
1950+ with langfuse .start_as_current_span (name = "parent" ) as parent_span :
1951+ parent_span .update_trace (name = "generation-properties-test" )
1952+ trace_id = parent_span .trace_id
1953+
1954+ for obs_type in generation_like_types :
1955+ with parent_span .start_as_current_observation (
1956+ name = f"test-{ obs_type } " ,
1957+ as_type = obs_type ,
1958+ model = test_model ,
1959+ completion_start_time = test_completion_start_time ,
1960+ model_parameters = test_model_parameters ,
1961+ usage_details = test_usage_details ,
1962+ cost_details = test_cost_details ,
1963+ ) as obs :
1964+ # Verify the properties are accessible on the observation object
1965+ if hasattr (obs , "model" ):
1966+ assert (
1967+ obs .model == test_model
1968+ ), f"{ obs_type } should have model property"
1969+ if hasattr (obs , "completion_start_time" ):
1970+ assert (
1971+ obs .completion_start_time == test_completion_start_time
1972+ ), f"{ obs_type } should have completion_start_time property"
1973+ if hasattr (obs , "model_parameters" ):
1974+ assert (
1975+ obs .model_parameters == test_model_parameters
1976+ ), f"{ obs_type } should have model_parameters property"
1977+ if hasattr (obs , "usage_details" ):
1978+ assert (
1979+ obs .usage_details == test_usage_details
1980+ ), f"{ obs_type } should have usage_details property"
1981+ if hasattr (obs , "cost_details" ):
1982+ assert (
1983+ obs .cost_details == test_cost_details
1984+ ), f"{ obs_type } should have cost_details property"
1985+
1986+ langfuse .flush ()
1987+
1988+ api = get_api ()
1989+ trace = api .trace .get (trace_id )
1990+
1991+ # Verify that the properties are persisted in the API for generation-like types
1992+ for obs_type in generation_like_types :
1993+ observations = [
1994+ obs
1995+ for obs in trace .observations
1996+ if obs .name == f"test-{ obs_type } " and obs .type == obs_type .upper ()
1997+ ]
1998+ assert (
1999+ len (observations ) == 1
2000+ ), f"Expected one { obs_type .upper ()} observation, but found { len (observations )} "
2001+
2002+ obs = observations [0 ]
2003+
2004+ assert obs .model == test_model , f"{ obs_type } should have model property"
2005+ assert (
2006+ obs .model_parameters == test_model_parameters
2007+ ), f"{ obs_type } should have model_parameters property"
2008+
2009+ # usage_details
2010+ assert hasattr (obs , "usage_details" ), f"{ obs_type } should have usage_details"
2011+ assert obs .usage_details == dict (
2012+ test_usage_details , total = 30
2013+ ), f"{ obs_type } should persist usage_details" # API adds total
2014+
2015+ # completion_start_time
2016+ if obs .completion_start_time is not None :
2017+ assert (
2018+ obs .completion_start_time is not None
2019+ ), f"{ obs_type } should persist completion_start_time property"
0 commit comments