langfuse-rb 0.8.0 → 0.9.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -1
- data/README.md +4 -1
- data/lib/langfuse/chat_prompt_client.rb +135 -20
- data/lib/langfuse/client.rb +24 -13
- data/lib/langfuse/otel_attributes.rb +12 -4
- data/lib/langfuse/prompt_renderer.rb +18 -0
- data/lib/langfuse/text_prompt_client.rb +21 -3
- data/lib/langfuse/version.rb +1 -1
- data/lib/langfuse.rb +1 -0
- metadata +4 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1eedf02269727792fdb13a343429d2108556cc4c7df52dea9e2c638a011409a0
|
|
4
|
+
data.tar.gz: 0130f17065fa3e4233090e858a2699105d9be48dce85d6765b0c3ee394c88bff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 036b34ce7908114bdad51bf895c5f50159f005bbf53f3256a347dc7a6c813d9c49d18c9f7491dc42c8771d66fb6b509ae1441af6812d575ff45b80fe4e73ce6e
|
|
7
|
+
data.tar.gz: c4cf129fd0260c35f91e75797903d29e16d74b0bf543a89d9f566201a69e08eaf6245fc9d117e5f2f0e3bad5673cfee5cd54e0802d46a53809ab9c5ea825f172
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.0] - 2026-04-28
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Expose `type`, `commit_message`, and `resolution_graph` metadata on text and chat prompt clients (#87)
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Preserve and compile chat prompt message placeholders in parity with Langfuse Python and JS SDKs (#86)
|
|
17
|
+
- Preserve raw prompt compile variables instead of HTML-escaping JSON, XML, and HTML-like values (#85)
|
|
18
|
+
- Suppress prompt name/version attribution on fallback prompt clients so fallback output is not reported as prompt version 0 (#84)
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
- Link to upstream Langfuse agent skills and refresh README header image (#81, #83)
|
|
22
|
+
|
|
10
23
|
## [0.8.0] - 2026-04-24
|
|
11
24
|
|
|
12
25
|
### Added
|
|
@@ -100,7 +113,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
100
113
|
- Migrated from legacy ingestion API to OTLP endpoint
|
|
101
114
|
- Removed `tracing_enabled` configuration flag (#2)
|
|
102
115
|
|
|
103
|
-
[Unreleased]: https://github.com/simplepractice/langfuse-rb/compare/v0.
|
|
116
|
+
[Unreleased]: https://github.com/simplepractice/langfuse-rb/compare/v0.9.0...HEAD
|
|
117
|
+
[0.9.0]: https://github.com/simplepractice/langfuse-rb/compare/v0.8.0...v0.9.0
|
|
104
118
|
[0.8.0]: https://github.com/simplepractice/langfuse-rb/compare/v0.7.0...v0.8.0
|
|
105
119
|
[0.7.0]: https://github.com/simplepractice/langfuse-rb/compare/v0.6.0...v0.7.0
|
|
106
120
|
[0.6.0]: https://github.com/simplepractice/langfuse-rb/compare/v0.5.0...v0.6.0
|
data/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
<img width="2255" height="527" alt="langfuse-wordart" src="https://github.com/user-attachments/assets/59422d0a-6ecb-4e5f-a21c-cae955b5ce75" />
|
|
2
|
+
|
|
2
3
|
|
|
3
4
|
# Langfuse Ruby SDK
|
|
4
5
|
|
|
@@ -68,6 +69,8 @@ end
|
|
|
68
69
|
- [Tracing](docs/TRACING.md)
|
|
69
70
|
- [Scoring](docs/SCORING.md)
|
|
70
71
|
- [Rails Patterns](docs/RAILS.md)
|
|
72
|
+
- [Agent Skills](https://github.com/langfuse/skills)
|
|
73
|
+
- [Agent Skill Docs](https://langfuse.com/docs/api-and-data-platform/features/agent-skill)
|
|
71
74
|
|
|
72
75
|
## License
|
|
73
76
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require_relative "prompt_renderer"
|
|
4
4
|
|
|
5
5
|
module Langfuse
|
|
6
6
|
# Chat prompt client for compiling chat prompts with variable substitution
|
|
@@ -20,6 +20,8 @@ module Langfuse
|
|
|
20
20
|
# chat_prompt.labels # => ["production"]
|
|
21
21
|
#
|
|
22
22
|
class ChatPromptClient
|
|
23
|
+
PLACEHOLDER_TYPE = "placeholder"
|
|
24
|
+
|
|
23
25
|
# @return [String] Prompt name
|
|
24
26
|
attr_reader :name
|
|
25
27
|
|
|
@@ -35,14 +37,24 @@ module Langfuse
|
|
|
35
37
|
# @return [Hash] Prompt configuration
|
|
36
38
|
attr_reader :config
|
|
37
39
|
|
|
38
|
-
# @return [Array<Hash>] Array of message hashes
|
|
40
|
+
# @return [Array<Hash>] Array of message hashes and placeholder entries
|
|
39
41
|
attr_reader :prompt
|
|
40
42
|
|
|
43
|
+
# @return [String, nil] Optional commit message for this prompt version
|
|
44
|
+
attr_reader :commit_message
|
|
45
|
+
|
|
46
|
+
# @return [Hash, nil] Optional dependency resolution graph for composed prompts
|
|
47
|
+
attr_reader :resolution_graph
|
|
48
|
+
|
|
49
|
+
# @return [Boolean] Whether this client uses caller-provided fallback content
|
|
50
|
+
attr_reader :is_fallback
|
|
51
|
+
|
|
41
52
|
# Initialize a new chat prompt client
|
|
42
53
|
#
|
|
43
54
|
# @param prompt_data [Hash] The prompt data from the API
|
|
55
|
+
# @param is_fallback [Boolean] Whether this client wraps caller-provided fallback content
|
|
44
56
|
# @raise [ArgumentError] if prompt data is invalid
|
|
45
|
-
def initialize(prompt_data)
|
|
57
|
+
def initialize(prompt_data, is_fallback: false)
|
|
46
58
|
validate_prompt_data!(prompt_data)
|
|
47
59
|
|
|
48
60
|
@name = prompt_data["name"]
|
|
@@ -51,16 +63,27 @@ module Langfuse
|
|
|
51
63
|
@labels = prompt_data["labels"] || []
|
|
52
64
|
@tags = prompt_data["tags"] || []
|
|
53
65
|
@config = prompt_data["config"] || {}
|
|
66
|
+
@commit_message = prompt_data["commitMessage"]
|
|
67
|
+
@resolution_graph = prompt_data["resolutionGraph"]
|
|
68
|
+
@is_fallback = is_fallback
|
|
54
69
|
end
|
|
55
70
|
|
|
56
|
-
#
|
|
71
|
+
# @return [String] Prompt type ("chat")
|
|
72
|
+
def type
|
|
73
|
+
"chat"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Compile the chat prompt with variable substitution and message placeholders
|
|
57
77
|
#
|
|
58
78
|
# Returns an array of message hashes with roles and compiled content.
|
|
59
|
-
#
|
|
60
|
-
#
|
|
79
|
+
# Placeholder entries are resolved from keyword arguments: arrays are
|
|
80
|
+
# expanded, empty arrays are skipped, unresolved placeholders stay in the
|
|
81
|
+
# output, and malformed values raise before invalid messages are sent to
|
|
82
|
+
# an LLM provider.
|
|
61
83
|
#
|
|
62
|
-
# @param kwargs [Hash] Variables
|
|
63
|
-
# @return [Array<Hash>] Array of compiled messages
|
|
84
|
+
# @param kwargs [Hash] Variables and placeholder values to compile
|
|
85
|
+
# @return [Array<Hash>] Array of compiled messages and unresolved placeholders
|
|
86
|
+
# @raise [ArgumentError] if a placeholder value is malformed
|
|
64
87
|
#
|
|
65
88
|
# @example
|
|
66
89
|
# chat_prompt.compile(name: "Alice", topic: "Ruby")
|
|
@@ -69,9 +92,18 @@ module Langfuse
|
|
|
69
92
|
# # { role: :user, content: "Hello Alice, let's discuss Ruby!" }
|
|
70
93
|
# # ]
|
|
71
94
|
def compile(**kwargs)
|
|
72
|
-
|
|
73
|
-
|
|
95
|
+
unresolved = []
|
|
96
|
+
compiled = []
|
|
97
|
+
prompt.each do |message|
|
|
98
|
+
normalized = symbolize_keys(message)
|
|
99
|
+
if normalized[:type].to_s == PLACEHOLDER_TYPE
|
|
100
|
+
append_placeholder(normalized, kwargs, compiled, unresolved)
|
|
101
|
+
else
|
|
102
|
+
compiled << compile_message(normalized, kwargs)
|
|
103
|
+
end
|
|
74
104
|
end
|
|
105
|
+
warn_unresolved(unresolved)
|
|
106
|
+
compiled
|
|
75
107
|
end
|
|
76
108
|
|
|
77
109
|
private
|
|
@@ -88,19 +120,102 @@ module Langfuse
|
|
|
88
120
|
raise ArgumentError, "prompt must be an Array" unless prompt_data["prompt"].is_a?(Array)
|
|
89
121
|
end
|
|
90
122
|
|
|
91
|
-
# Compile a single message with variable substitution
|
|
123
|
+
# Compile a single role/content message with variable substitution
|
|
92
124
|
#
|
|
93
|
-
# @param
|
|
125
|
+
# @param normalized [Hash] Symbolized message hash
|
|
94
126
|
# @param variables [Hash] Variables to substitute
|
|
95
127
|
# @return [Hash] Compiled message with :role and :content as symbols
|
|
96
|
-
def compile_message(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
128
|
+
def compile_message(normalized, variables)
|
|
129
|
+
normalized.except(:type).merge(
|
|
130
|
+
role: normalize_role(normalized[:role]),
|
|
131
|
+
content: render(normalized[:content] || "", variables)
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# @api private
|
|
136
|
+
def append_placeholder(message, variables, compiled, unresolved)
|
|
137
|
+
name = message[:name].to_s
|
|
138
|
+
found, value = lookup_placeholder(variables, name)
|
|
139
|
+
return append_unresolved(name, compiled, unresolved) unless found
|
|
140
|
+
|
|
141
|
+
expand_placeholder(name, value, variables, compiled)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# @api private
|
|
145
|
+
def append_unresolved(name, compiled, unresolved)
|
|
146
|
+
unresolved << name
|
|
147
|
+
compiled << { type: PLACEHOLDER_TYPE, name: name }
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @api private
|
|
151
|
+
def expand_placeholder(name, value, variables, compiled)
|
|
152
|
+
return if value.is_a?(Array) && value.empty?
|
|
153
|
+
|
|
154
|
+
unless value.is_a?(Array)
|
|
155
|
+
raise ArgumentError, "Placeholder '#{name}' must contain an array of chat message hashes, got #{value.class}."
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
value.each { |entry| compiled << placeholder_message(entry, variables, name) }
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# @api private
|
|
162
|
+
def lookup_placeholder(variables, name)
|
|
163
|
+
return [true, variables[name.to_sym]] if variables.key?(name.to_sym)
|
|
164
|
+
return [true, variables[name]] if variables.key?(name)
|
|
165
|
+
|
|
166
|
+
[false, nil]
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# @api private
|
|
170
|
+
def placeholder_message(message, variables, name)
|
|
171
|
+
unless message.is_a?(Hash)
|
|
172
|
+
raise ArgumentError,
|
|
173
|
+
"Placeholder '#{name}' must contain an array of chat message hashes with role and content fields."
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
normalized = symbolize_keys(message)
|
|
177
|
+
unless valid_placeholder_message?(normalized)
|
|
178
|
+
raise ArgumentError,
|
|
179
|
+
"Placeholder '#{name}' must contain an array of chat message hashes with role and content fields."
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
normalized.merge(
|
|
183
|
+
role: normalize_role(normalized[:role]),
|
|
184
|
+
content: render(normalized[:content] || "", variables)
|
|
185
|
+
)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# @api private
|
|
189
|
+
def render(content, variables)
|
|
190
|
+
variables.empty? ? content : PromptRenderer.render(content, variables)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# @api private
|
|
194
|
+
def valid_placeholder_message?(message)
|
|
195
|
+
message.is_a?(Hash) &&
|
|
196
|
+
message.key?(:role) &&
|
|
197
|
+
!message[:role].to_s.empty? &&
|
|
198
|
+
message.key?(:content)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# @api private
|
|
202
|
+
def warn_unresolved(names)
|
|
203
|
+
return if names.empty?
|
|
204
|
+
|
|
205
|
+
unresolved_names = names.uniq.sort
|
|
206
|
+
message = "Placeholders #{unresolved_names.inspect} have not been resolved. " \
|
|
207
|
+
"Pass them as keyword arguments to compile()."
|
|
208
|
+
warn_msg(message)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# @api private
|
|
212
|
+
def warn_msg(message)
|
|
213
|
+
Langfuse.configuration.logger.warn("Langfuse: #{message}")
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# @api private
|
|
217
|
+
def symbolize_keys(hash)
|
|
218
|
+
hash.transform_keys(&:to_sym)
|
|
104
219
|
end
|
|
105
220
|
|
|
106
221
|
# Normalize role to symbol
|
data/lib/langfuse/client.rb
CHANGED
|
@@ -823,9 +823,9 @@ module Langfuse
|
|
|
823
823
|
|
|
824
824
|
case type
|
|
825
825
|
when :text
|
|
826
|
-
TextPromptClient.new(prompt_data)
|
|
826
|
+
TextPromptClient.new(prompt_data, is_fallback: true)
|
|
827
827
|
when :chat
|
|
828
|
-
ChatPromptClient.new(prompt_data)
|
|
828
|
+
ChatPromptClient.new(prompt_data, is_fallback: true)
|
|
829
829
|
end
|
|
830
830
|
end
|
|
831
831
|
|
|
@@ -856,7 +856,8 @@ module Langfuse
|
|
|
856
856
|
|
|
857
857
|
# Normalize prompt content for API request
|
|
858
858
|
#
|
|
859
|
-
# Converts Ruby symbol keys to string keys for chat messages
|
|
859
|
+
# Converts Ruby symbol keys to string keys for chat messages and preserves
|
|
860
|
+
# Langfuse message placeholder entries.
|
|
860
861
|
#
|
|
861
862
|
# @param prompt [String, Array] The prompt content
|
|
862
863
|
# @param type [Symbol] The prompt type
|
|
@@ -866,18 +867,28 @@ module Langfuse
|
|
|
866
867
|
|
|
867
868
|
# Normalize chat messages to use string keys
|
|
868
869
|
prompt.map do |message|
|
|
869
|
-
|
|
870
|
-
normalized
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
k
|
|
874
|
-
end
|
|
875
|
-
{
|
|
876
|
-
"role" => normalized[:role]&.to_s,
|
|
877
|
-
"content" => normalized[:content]
|
|
878
|
-
}
|
|
870
|
+
normalized = message.transform_keys(&:to_s)
|
|
871
|
+
next placeholder_prompt_content(normalized) if normalized["type"] == ChatPromptClient::PLACEHOLDER_TYPE
|
|
872
|
+
|
|
873
|
+
normalize_chat_message_content(normalized)
|
|
879
874
|
end
|
|
880
875
|
end
|
|
876
|
+
|
|
877
|
+
# @api private
|
|
878
|
+
def placeholder_prompt_content(message)
|
|
879
|
+
{
|
|
880
|
+
"type" => ChatPromptClient::PLACEHOLDER_TYPE,
|
|
881
|
+
"name" => message["name"].to_s
|
|
882
|
+
}
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
# @api private
|
|
886
|
+
def normalize_chat_message_content(message)
|
|
887
|
+
message.merge(
|
|
888
|
+
"role" => message["role"]&.to_s,
|
|
889
|
+
"content" => message["content"]
|
|
890
|
+
)
|
|
891
|
+
end
|
|
881
892
|
end
|
|
882
893
|
# rubocop:enable Metrics/ClassLength
|
|
883
894
|
end
|
|
@@ -302,11 +302,9 @@ module Langfuse
|
|
|
302
302
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
303
303
|
def self.add_prompt_attributes(otel_attributes, prompt)
|
|
304
304
|
return unless prompt
|
|
305
|
+
return if fallback_prompt?(prompt)
|
|
305
306
|
|
|
306
|
-
# Handle hash-like prompts
|
|
307
307
|
if prompt.is_a?(Hash) || prompt.respond_to?(:[])
|
|
308
|
-
return if prompt[:is_fallback] || prompt["is_fallback"]
|
|
309
|
-
|
|
310
308
|
otel_attributes[OBSERVATION_PROMPT_NAME] = prompt[:name] || prompt["name"]
|
|
311
309
|
otel_attributes[OBSERVATION_PROMPT_VERSION] = prompt[:version] || prompt["version"]
|
|
312
310
|
# Handle objects with name/version methods (already converted in Trace#generation)
|
|
@@ -315,6 +313,16 @@ module Langfuse
|
|
|
315
313
|
otel_attributes[OBSERVATION_PROMPT_VERSION] = prompt.version
|
|
316
314
|
end
|
|
317
315
|
end
|
|
316
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
317
|
+
|
|
318
|
+
# @api private
|
|
319
|
+
def self.fallback_prompt?(prompt)
|
|
320
|
+
return true if prompt.respond_to?(:is_fallback) && prompt.is_fallback
|
|
321
|
+
return false unless prompt.is_a?(Hash)
|
|
322
|
+
|
|
323
|
+
!!get_hash_value(prompt, :is_fallback)
|
|
324
|
+
end
|
|
325
|
+
private_class_method :fallback_prompt?
|
|
318
326
|
end
|
|
319
|
-
# rubocop:enable Metrics/
|
|
327
|
+
# rubocop:enable Metrics/ModuleLength
|
|
320
328
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "mustache"
|
|
4
|
+
|
|
5
|
+
module Langfuse
|
|
6
|
+
# Renders prompt templates with Langfuse SDK-compatible variable semantics.
|
|
7
|
+
#
|
|
8
|
+
# @api private
|
|
9
|
+
class PromptRenderer < Mustache
|
|
10
|
+
# Langfuse variables are model input, not browser output; JS/Python SDKs substitute raw values.
|
|
11
|
+
#
|
|
12
|
+
# @param value [Object] Value to insert into the prompt
|
|
13
|
+
# @return [String] Raw string representation
|
|
14
|
+
def escape(value)
|
|
15
|
+
value.to_s
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require_relative "prompt_renderer"
|
|
4
4
|
|
|
5
5
|
module Langfuse
|
|
6
6
|
# Text prompt client for compiling text prompts with variable substitution
|
|
@@ -38,11 +38,21 @@ module Langfuse
|
|
|
38
38
|
# @return [String] Raw prompt template string
|
|
39
39
|
attr_reader :prompt
|
|
40
40
|
|
|
41
|
+
# @return [String, nil] Optional commit message for this prompt version
|
|
42
|
+
attr_reader :commit_message
|
|
43
|
+
|
|
44
|
+
# @return [Hash, nil] Optional dependency resolution graph for composed prompts
|
|
45
|
+
attr_reader :resolution_graph
|
|
46
|
+
|
|
47
|
+
# @return [Boolean] Whether this client uses caller-provided fallback content
|
|
48
|
+
attr_reader :is_fallback
|
|
49
|
+
|
|
41
50
|
# Initialize a new text prompt client
|
|
42
51
|
#
|
|
43
52
|
# @param prompt_data [Hash] The prompt data from the API
|
|
53
|
+
# @param is_fallback [Boolean] Whether this client wraps caller-provided fallback content
|
|
44
54
|
# @raise [ArgumentError] if prompt data is invalid
|
|
45
|
-
def initialize(prompt_data)
|
|
55
|
+
def initialize(prompt_data, is_fallback: false)
|
|
46
56
|
validate_prompt_data!(prompt_data)
|
|
47
57
|
|
|
48
58
|
@name = prompt_data["name"]
|
|
@@ -51,6 +61,14 @@ module Langfuse
|
|
|
51
61
|
@labels = prompt_data["labels"] || []
|
|
52
62
|
@tags = prompt_data["tags"] || []
|
|
53
63
|
@config = prompt_data["config"] || {}
|
|
64
|
+
@commit_message = prompt_data["commitMessage"]
|
|
65
|
+
@resolution_graph = prompt_data["resolutionGraph"]
|
|
66
|
+
@is_fallback = is_fallback
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @return [String] Prompt type ("text")
|
|
70
|
+
def type
|
|
71
|
+
"text"
|
|
54
72
|
end
|
|
55
73
|
|
|
56
74
|
# Compile the prompt with variable substitution
|
|
@@ -64,7 +82,7 @@ module Langfuse
|
|
|
64
82
|
def compile(**kwargs)
|
|
65
83
|
return prompt if kwargs.empty?
|
|
66
84
|
|
|
67
|
-
|
|
85
|
+
PromptRenderer.render(prompt, kwargs)
|
|
68
86
|
end
|
|
69
87
|
|
|
70
88
|
private
|
data/lib/langfuse/version.rb
CHANGED
data/lib/langfuse.rb
CHANGED
|
@@ -54,6 +54,7 @@ require_relative "langfuse/span_processor"
|
|
|
54
54
|
require_relative "langfuse/observations"
|
|
55
55
|
require_relative "langfuse/trace_id"
|
|
56
56
|
require_relative "langfuse/score_client"
|
|
57
|
+
require_relative "langfuse/prompt_renderer"
|
|
57
58
|
require_relative "langfuse/text_prompt_client"
|
|
58
59
|
require_relative "langfuse/chat_prompt_client"
|
|
59
60
|
require_relative "langfuse/timestamp_parser"
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: langfuse-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- SimplePractice
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: faraday
|
|
@@ -177,6 +176,7 @@ files:
|
|
|
177
176
|
- lib/langfuse/otel_attributes.rb
|
|
178
177
|
- lib/langfuse/otel_setup.rb
|
|
179
178
|
- lib/langfuse/prompt_cache.rb
|
|
179
|
+
- lib/langfuse/prompt_renderer.rb
|
|
180
180
|
- lib/langfuse/propagation.rb
|
|
181
181
|
- lib/langfuse/rails_cache_adapter.rb
|
|
182
182
|
- lib/langfuse/sampling.rb
|
|
@@ -198,7 +198,6 @@ metadata:
|
|
|
198
198
|
source_code_uri: https://github.com/simplepractice/langfuse-rb
|
|
199
199
|
changelog_uri: https://github.com/simplepractice/langfuse-rb/blob/main/CHANGELOG.md
|
|
200
200
|
rubygems_mfa_required: 'true'
|
|
201
|
-
post_install_message:
|
|
202
201
|
rdoc_options: []
|
|
203
202
|
require_paths:
|
|
204
203
|
- lib
|
|
@@ -213,8 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
213
212
|
- !ruby/object:Gem::Version
|
|
214
213
|
version: '0'
|
|
215
214
|
requirements: []
|
|
216
|
-
rubygems_version:
|
|
217
|
-
signing_key:
|
|
215
|
+
rubygems_version: 4.0.8
|
|
218
216
|
specification_version: 4
|
|
219
217
|
summary: Ruby SDK for Langfuse - LLM observability and prompt management
|
|
220
218
|
test_files: []
|