Skip to content

Commit c270a93

Browse files
committed
Add type definitions for observations and traces
This commit introduces comprehensive type definitions for Langfuse observations (spans, generations, events, etc.) and traces. The types provide structured attribute classes with validation and serialization. Key additions: - OBSERVATION_TYPES constant (10 types: span, generation, event, etc.) - LEVELS constant (DEBUG, DEFAULT, WARNING, ERROR) - SpanAttributes class with 7 configurable attributes - GenerationAttributes extending SpanAttributes with 6 LLM-specific fields - EmbeddingAttributes (extends GenerationAttributes) - TraceAttributes class with 11 trace-level attributes - 7 aliased attribute classes for other observation types All attribute classes include: - Keyword argument initialization - Accessor methods for all fields - #to_h method that excludes nil values Test coverage: 100% of types module (379 lines of specs) Closes #6
1 parent 8a60c06 commit c270a93

File tree

4 files changed

+716
-0
lines changed

4 files changed

+716
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ Thumbs.db
2828

2929
# Internal development progress tracking
3030
PROGRESS.md
31+
32+
langfuse-js/
33+
AGENTS.md

lib/langfuse.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require_relative "langfuse/version"
4+
require_relative "langfuse/types"
45

56
# Langfuse Ruby SDK
67
#

lib/langfuse/types.rb

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
# frozen_string_literal: true
2+
3+
module Langfuse
4+
# Type definitions and constants for Langfuse domain models
5+
#
6+
# Provides observation type constants and attribute classes for type-safe
7+
# handling of Langfuse observations and traces.
8+
#
9+
# @example Using observation types
10+
# Langfuse::Types::OBSERVATION_TYPES # => ["span", "generation", ...]
11+
# Langfuse::Types::LEVELS # => ["DEBUG", "DEFAULT", "WARNING", "ERROR"]
12+
#
13+
# @example Using attribute classes
14+
# attrs = Langfuse::Types::SpanAttributes.new(
15+
# input: { query: "test" },
16+
# level: "DEFAULT",
17+
# metadata: { source: "api" }
18+
# )
19+
# attrs.to_h # => { input: {...}, level: "DEFAULT", metadata: {...} }
20+
#
21+
module Types
22+
# Types of observations that can be created in Langfuse
23+
#
24+
# - `span`: General-purpose observations for tracking operations, functions, or logical units of work
25+
# - `generation`: Specialized observations for LLM calls with model parameters, usage, and costs
26+
# - `event`: Point-in-time occurrences or log entries within a trace
27+
# - `embedding`: Observations for embedding generation calls
28+
# - `agent`: Observations for agent-based workflows
29+
# - `tool`: Observations for tool/function calls
30+
# - `chain`: Observations for chain-based workflows
31+
# - `retriever`: Observations for retrieval operations
32+
# - `evaluator`: Observations for evaluation operations
33+
# - `guardrail`: Observations for guardrail checks
34+
#
35+
# @return [Array<String>] Array of observation type strings
36+
OBSERVATION_TYPES = %w[
37+
span generation event embedding
38+
agent tool chain retriever
39+
evaluator guardrail
40+
].freeze
41+
42+
# Severity levels for observations in Langfuse
43+
#
44+
# Used to categorize the importance or severity of observations:
45+
# - `DEBUG`: Detailed diagnostic information
46+
# - `DEFAULT`: Normal operation information
47+
# - `WARNING`: Potentially problematic situations
48+
# - `ERROR`: Error conditions that need attention
49+
#
50+
# @return [Array<String>] Array of level strings
51+
LEVELS = %w[DEBUG DEFAULT WARNING ERROR].freeze
52+
53+
# Attributes for Langfuse span observations
54+
#
55+
# Spans are used to track operations, functions, or logical units of work.
56+
# They can contain other spans, generations, or events as children.
57+
#
58+
# @example
59+
# attrs = SpanAttributes.new(
60+
# input: { query: "SELECT * FROM users" },
61+
# output: { count: 42 },
62+
# level: "DEFAULT",
63+
# metadata: { source: "database" }
64+
# )
65+
# attrs.to_h # => { input: {...}, output: {...}, level: "DEFAULT", metadata: {...} }
66+
#
67+
class SpanAttributes
68+
# @return [Object, nil] Input data for the operation being tracked
69+
attr_accessor :input
70+
71+
# @return [Object, nil] Output data from the operation
72+
attr_accessor :output
73+
74+
# @return [Hash, nil] Additional metadata as key-value pairs
75+
attr_accessor :metadata
76+
77+
# @return [String, nil] Severity level of the observation (DEBUG, DEFAULT, WARNING, ERROR)
78+
attr_accessor :level
79+
80+
# @return [String, nil] Human-readable status message
81+
attr_accessor :status_message
82+
83+
# @return [String, nil] Version identifier for the code/model being tracked
84+
attr_accessor :version
85+
86+
# @return [String, nil] Environment where the operation is running (e.g., 'production', 'staging')
87+
attr_accessor :environment
88+
89+
# Initialize a new SpanAttributes instance
90+
#
91+
# @param input [Object, nil] Input data for the operation
92+
# @param output [Object, nil] Output data from the operation
93+
# @param metadata [Hash, nil] Additional metadata as key-value pairs
94+
# @param level [String, nil] Severity level (DEBUG, DEFAULT, WARNING, ERROR)
95+
# @param status_message [String, nil] Human-readable status message
96+
# @param version [String, nil] Version identifier
97+
# @param environment [String, nil] Environment identifier
98+
# rubocop:disable Metrics/ParameterLists
99+
def initialize(input: nil, output: nil, metadata: nil, level: nil, status_message: nil, version: nil,
100+
environment: nil)
101+
# rubocop:enable Metrics/ParameterLists
102+
@input = input
103+
@output = output
104+
@metadata = metadata
105+
@level = level
106+
@status_message = status_message
107+
@version = version
108+
@environment = environment
109+
end
110+
111+
# Convert attributes to a hash representation
112+
#
113+
# Returns a hash with all non-nil attributes. Nil values are excluded.
114+
#
115+
# @return [Hash] Hash representation of attributes
116+
def to_h
117+
{
118+
input: @input,
119+
output: @output,
120+
metadata: @metadata,
121+
level: @level,
122+
status_message: @status_message,
123+
version: @version,
124+
environment: @environment
125+
}.compact
126+
end
127+
end
128+
129+
# Attributes for Langfuse generation observations
130+
#
131+
# Generations are specialized observations for tracking LLM interactions,
132+
# including model parameters, usage metrics, costs, and prompt information.
133+
#
134+
# @example
135+
# attrs = GenerationAttributes.new(
136+
# model: "gpt-4",
137+
# input: { messages: [...] },
138+
# output: { content: "Hello!" },
139+
# model_parameters: { temperature: 0.7 },
140+
# usage_details: { prompt_tokens: 100, completion_tokens: 50 },
141+
# prompt: { name: "greeting", version: 1, is_fallback: false }
142+
# )
143+
#
144+
class GenerationAttributes < SpanAttributes
145+
# @return [Time, nil] Timestamp when the model started generating completion
146+
attr_accessor :completion_start_time
147+
148+
# @return [String, nil] Name of the language model used (e.g., 'gpt-4', 'claude-3-opus')
149+
attr_accessor :model
150+
151+
# @return [Hash, nil] Parameters passed to the model (temperature, max_tokens, etc.)
152+
attr_accessor :model_parameters
153+
154+
# @return [Hash, nil] Token usage and other model-specific usage metrics
155+
attr_accessor :usage_details
156+
157+
# @return [Hash, nil] Cost breakdown for the generation (totalCost, etc.)
158+
attr_accessor :cost_details
159+
160+
# @return [Hash, nil] Information about the prompt used from Langfuse prompt management
161+
# Hash should contain :name (String), :version (Integer), :is_fallback (Boolean)
162+
attr_accessor :prompt
163+
164+
# Initialize a new GenerationAttributes instance
165+
#
166+
# @param completion_start_time [Time, nil] Timestamp when completion started
167+
# @param model [String, nil] Model name
168+
# @param model_parameters [Hash, nil] Model parameters
169+
# @param usage_details [Hash, nil] Usage metrics
170+
# @param cost_details [Hash, nil] Cost breakdown
171+
# @param prompt [Hash, nil] Prompt information with :name, :version, :is_fallback keys
172+
# @param kwargs [Hash] Additional keyword arguments passed to SpanAttributes
173+
# rubocop:disable Metrics/ParameterLists
174+
def initialize(completion_start_time: nil, model: nil, model_parameters: nil, usage_details: nil,
175+
cost_details: nil, prompt: nil, **)
176+
# rubocop:enable Metrics/ParameterLists
177+
super(**)
178+
@completion_start_time = completion_start_time
179+
@model = model
180+
@model_parameters = model_parameters
181+
@usage_details = usage_details
182+
@cost_details = cost_details
183+
@prompt = prompt
184+
end
185+
186+
# Convert attributes to a hash representation
187+
#
188+
# Returns a hash with all non-nil attributes, including both span and generation-specific fields.
189+
#
190+
# @return [Hash] Hash representation of attributes
191+
def to_h
192+
super.merge(
193+
completion_start_time: @completion_start_time,
194+
model: @model,
195+
model_parameters: @model_parameters,
196+
usage_details: @usage_details,
197+
cost_details: @cost_details,
198+
prompt: @prompt
199+
).compact
200+
end
201+
end
202+
203+
# Attributes for Langfuse embedding observations
204+
#
205+
# Embeddings are specialized observations for tracking embedding generation calls.
206+
# They extend GenerationAttributes to include all generation-specific fields.
207+
#
208+
class EmbeddingAttributes < GenerationAttributes
209+
end
210+
211+
# Attributes for Langfuse traces
212+
#
213+
# Traces are the top-level containers that group related observations together.
214+
# They represent a complete workflow, request, or user interaction.
215+
#
216+
# @example
217+
# attrs = TraceAttributes.new(
218+
# name: "user-request",
219+
# user_id: "user-123",
220+
# session_id: "session-456",
221+
# input: { query: "What is Ruby?" },
222+
# output: { answer: "Ruby is a programming language" },
223+
# tags: ["api", "v1"],
224+
# public: false
225+
# )
226+
#
227+
class TraceAttributes
228+
# @return [String, nil] Human-readable name for the trace
229+
attr_accessor :name
230+
231+
# @return [String, nil] Identifier for the user associated with this trace
232+
attr_accessor :user_id
233+
234+
# @return [String, nil] Session identifier for grouping related traces
235+
attr_accessor :session_id
236+
237+
# @return [String, nil] Version identifier for the code/application
238+
attr_accessor :version
239+
240+
# @return [String, nil] Release identifier for deployment tracking
241+
attr_accessor :release
242+
243+
# @return [Object, nil] Input data that initiated the trace
244+
attr_accessor :input
245+
246+
# @return [Object, nil] Final output data from the trace
247+
attr_accessor :output
248+
249+
# @return [Hash, nil] Additional metadata for the trace
250+
attr_accessor :metadata
251+
252+
# @return [Array<String>, nil] Tags for categorizing and filtering traces
253+
attr_accessor :tags
254+
255+
# @return [Boolean, nil] Whether this trace should be publicly visible
256+
attr_accessor :public
257+
258+
# @return [String, nil] Environment where the trace was captured
259+
attr_accessor :environment
260+
261+
# Initialize a new TraceAttributes instance
262+
#
263+
# @param name [String, nil] Human-readable name for the trace
264+
# @param user_id [String, nil] User identifier
265+
# @param session_id [String, nil] Session identifier
266+
# @param version [String, nil] Version identifier
267+
# @param release [String, nil] Release identifier
268+
# @param input [Object, nil] Input data
269+
# @param output [Object, nil] Output data
270+
# @param metadata [Hash, nil] Additional metadata
271+
# @param tags [Array<String>, nil] Tags array
272+
# @param public [Boolean, nil] Public visibility flag
273+
# @param environment [String, nil] Environment identifier
274+
# rubocop:disable Metrics/ParameterLists
275+
def initialize(name: nil, user_id: nil, session_id: nil, version: nil, release: nil, input: nil, output: nil,
276+
metadata: nil, tags: nil, public: nil, environment: nil)
277+
# rubocop:enable Metrics/ParameterLists
278+
@name = name
279+
@user_id = user_id
280+
@session_id = session_id
281+
@version = version
282+
@release = release
283+
@input = input
284+
@output = output
285+
@metadata = metadata
286+
@tags = tags
287+
@public = public
288+
@environment = environment
289+
end
290+
291+
# Convert attributes to a hash representation
292+
#
293+
# Returns a hash with all non-nil attributes. Nil values are excluded.
294+
#
295+
# @return [Hash] Hash representation of attributes
296+
def to_h
297+
{
298+
name: @name,
299+
user_id: @user_id,
300+
session_id: @session_id,
301+
version: @version,
302+
release: @release,
303+
input: @input,
304+
output: @output,
305+
metadata: @metadata,
306+
tags: @tags,
307+
public: @public,
308+
environment: @environment
309+
}.compact
310+
end
311+
end
312+
313+
# Alias for event observation attributes (same as SpanAttributes)
314+
EventAttributes = SpanAttributes
315+
316+
# Alias for agent observation attributes (same as SpanAttributes)
317+
AgentAttributes = SpanAttributes
318+
319+
# Alias for tool observation attributes (same as SpanAttributes)
320+
ToolAttributes = SpanAttributes
321+
322+
# Alias for chain observation attributes (same as SpanAttributes)
323+
ChainAttributes = SpanAttributes
324+
325+
# Alias for retriever observation attributes (same as SpanAttributes)
326+
RetrieverAttributes = SpanAttributes
327+
328+
# Alias for evaluator observation attributes (same as SpanAttributes)
329+
EvaluatorAttributes = SpanAttributes
330+
331+
# Alias for guardrail observation attributes (same as SpanAttributes)
332+
GuardrailAttributes = SpanAttributes
333+
end
334+
end

0 commit comments

Comments
 (0)