langsmith-sdk 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Langsmith
4
- # Module that provides method decoration for automatic tracing.
5
- # Include this module in your class and use the `traceable` class method
6
- # to mark methods for tracing.
7
- #
8
- # @example
9
- # class MyService
10
- # include Langsmith::Traceable
11
- #
12
- # traceable run_type: "llm"
13
- # def call_llm(prompt)
14
- # # automatically traced
15
- # end
16
- #
17
- # traceable run_type: "tool", name: "search"
18
- # def search(query)
19
- # # traced with custom name
20
- # end
21
- #
22
- # traceable run_type: "chain", tenant_id: "tenant-123"
23
- # def process_for_tenant(data)
24
- # # traced to specific tenant
25
- # end
26
- # end
27
- module Traceable
28
- def self.included(base)
29
- base.extend(ClassMethods)
30
- end
31
-
32
- module ClassMethods
33
- # Marks the next defined method as traceable
34
- def traceable(run_type: "chain", name: nil, metadata: nil, tags: nil, tenant_id: nil)
35
- @pending_traceable_options = {
36
- run_type: run_type,
37
- name: name,
38
- metadata: metadata,
39
- tags: tags,
40
- tenant_id: tenant_id
41
- }
42
- end
43
-
44
- def method_added(method_name)
45
- super
46
-
47
- return unless @pending_traceable_options
48
-
49
- options = @pending_traceable_options
50
- @pending_traceable_options = nil
51
-
52
- # Don't wrap private/protected methods that start with underscore
53
- return if method_name.to_s.start_with?("_langsmith_")
54
-
55
- wrap_method(method_name, options)
56
- end
57
-
58
- private
59
-
60
- def wrap_method(method_name, options)
61
- original_method = instance_method(method_name)
62
- trace_name = options[:name] || "#{name}##{method_name}"
63
-
64
- # Remove original method to avoid "method redefined" warning
65
- remove_method(method_name)
66
-
67
- define_method(method_name) do |*args, **kwargs, &block|
68
- Langsmith.trace(
69
- trace_name,
70
- run_type: options[:run_type],
71
- inputs: build_trace_inputs(args, kwargs, original_method),
72
- metadata: options[:metadata],
73
- tags: options[:tags],
74
- tenant_id: options[:tenant_id]
75
- ) do |_run|
76
- if kwargs.empty?
77
- original_method.bind(self).call(*args, &block)
78
- else
79
- original_method.bind(self).call(*args, **kwargs, &block)
80
- end
81
- end
82
- end
83
- end
84
- end
85
-
86
- private
87
-
88
- def build_trace_inputs(args, kwargs, method)
89
- params = method.parameters
90
- inputs = {}
91
-
92
- # Map positional arguments
93
- args.each_with_index do |arg, index|
94
- param = params[index]
95
- param_name = param ? param[1] : "arg#{index}"
96
- inputs[param_name] = serialize_input(arg)
97
- end
98
-
99
- # Map keyword arguments
100
- kwargs.each do |key, value|
101
- inputs[key] = serialize_input(value)
102
- end
103
-
104
- inputs
105
- end
106
-
107
- def serialize_input(value)
108
- case value
109
- when String, Numeric, TrueClass, FalseClass, NilClass
110
- value
111
- when Array
112
- value.map { |v| serialize_input(v) }
113
- when Hash
114
- value.transform_values { |v| serialize_input(v) }
115
- else
116
- value.to_s
117
- end
118
- end
119
- end
120
- end