langfuse-ruby 0.1.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 +7 -0
- data/.github/workflows/ci.yml +47 -0
- data/.github/workflows/release.yml +51 -0
- data/.gitignore +81 -0
- data/CHANGELOG.md +49 -0
- data/FINAL_SUMMARY.md +191 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +102 -0
- data/LICENSE +21 -0
- data/PROJECT_SUMMARY.md +263 -0
- data/PUBLISH_GUIDE.md +300 -0
- data/README.md +436 -0
- data/RELEASE_CHECKLIST.md +130 -0
- data/Rakefile +23 -0
- data/examples/basic_tracing.rb +196 -0
- data/examples/prompt_management.rb +283 -0
- data/langfuse-ruby.gemspec +51 -0
- data/lib/langfuse/client.rb +278 -0
- data/lib/langfuse/errors.rb +9 -0
- data/lib/langfuse/evaluation.rb +267 -0
- data/lib/langfuse/generation.rb +190 -0
- data/lib/langfuse/prompt.rb +209 -0
- data/lib/langfuse/span.rb +166 -0
- data/lib/langfuse/trace.rb +155 -0
- data/lib/langfuse/utils.rb +41 -0
- data/lib/langfuse/version.rb +3 -0
- data/lib/langfuse.rb +40 -0
- data/scripts/release.sh +120 -0
- data/scripts/verify_release.rb +139 -0
- data/test_basic.rb +183 -0
- data/test_offline.rb +329 -0
- metadata +232 -0
data/test_offline.rb
ADDED
@@ -0,0 +1,329 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative 'lib/langfuse'
|
4
|
+
|
5
|
+
puts "🚀 Testing Langfuse Ruby SDK (Offline Mode)..."
|
6
|
+
|
7
|
+
# Test 1: Basic configuration
|
8
|
+
puts "\n1. Testing configuration..."
|
9
|
+
Langfuse.configure do |config|
|
10
|
+
config.public_key = "test_key"
|
11
|
+
config.secret_key = "test_secret"
|
12
|
+
config.host = "https://test.langfuse.com"
|
13
|
+
config.debug = false # Turn off debug to avoid network calls
|
14
|
+
end
|
15
|
+
|
16
|
+
puts "✅ Configuration successful"
|
17
|
+
|
18
|
+
# Test 2: Client initialization
|
19
|
+
puts "\n2. Testing client initialization..."
|
20
|
+
begin
|
21
|
+
client = Langfuse.new(
|
22
|
+
public_key: "test_key",
|
23
|
+
secret_key: "test_secret",
|
24
|
+
host: "https://test.langfuse.com",
|
25
|
+
debug: false
|
26
|
+
)
|
27
|
+
puts "✅ Client initialization successful"
|
28
|
+
rescue => e
|
29
|
+
puts "❌ Client initialization failed: #{e.message}"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Test 3: Trace creation (no network)
|
33
|
+
puts "\n3. Testing trace creation..."
|
34
|
+
begin
|
35
|
+
trace = client.trace(
|
36
|
+
name: "test-trace",
|
37
|
+
user_id: "test-user",
|
38
|
+
input: { message: "Hello, world!" }
|
39
|
+
)
|
40
|
+
puts "✅ Trace creation successful"
|
41
|
+
puts " Trace ID: #{trace.id}"
|
42
|
+
rescue => e
|
43
|
+
puts "❌ Trace creation failed: #{e.message}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# Test 4: Generation creation (no network)
|
47
|
+
puts "\n4. Testing generation creation..."
|
48
|
+
begin
|
49
|
+
generation = trace.generation(
|
50
|
+
name: "test-generation",
|
51
|
+
model: "gpt-3.5-turbo",
|
52
|
+
input: [{ role: "user", content: "Hello!" }],
|
53
|
+
output: { content: "Hi there!" }
|
54
|
+
)
|
55
|
+
puts "✅ Generation creation successful"
|
56
|
+
puts " Generation ID: #{generation.id}"
|
57
|
+
rescue => e
|
58
|
+
puts "❌ Generation creation failed: #{e.message}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Test 5: Prompt template
|
62
|
+
puts "\n5. Testing prompt template..."
|
63
|
+
begin
|
64
|
+
template = Langfuse::PromptTemplate.from_template(
|
65
|
+
"Hello {{name}}! How are you feeling {{mood}} today?"
|
66
|
+
)
|
67
|
+
|
68
|
+
formatted = template.format(
|
69
|
+
name: "Alice",
|
70
|
+
mood: "happy"
|
71
|
+
)
|
72
|
+
|
73
|
+
puts "✅ Prompt template successful"
|
74
|
+
puts " Variables: #{template.input_variables}"
|
75
|
+
puts " Formatted: #{formatted}"
|
76
|
+
rescue => e
|
77
|
+
puts "❌ Prompt template failed: #{e.message}"
|
78
|
+
end
|
79
|
+
|
80
|
+
# Test 6: Chat prompt template
|
81
|
+
puts "\n6. Testing chat prompt template..."
|
82
|
+
begin
|
83
|
+
chat_template = Langfuse::ChatPromptTemplate.from_messages([
|
84
|
+
{ role: "system", content: "You are a helpful {{role}} assistant." },
|
85
|
+
{ role: "user", content: "{{user_input}}" }
|
86
|
+
])
|
87
|
+
|
88
|
+
messages = chat_template.format(
|
89
|
+
role: "coding",
|
90
|
+
user_input: "Help me with Ruby"
|
91
|
+
)
|
92
|
+
|
93
|
+
puts "✅ Chat prompt template successful"
|
94
|
+
puts " Variables: #{chat_template.input_variables}"
|
95
|
+
puts " Messages: #{messages.length}"
|
96
|
+
rescue => e
|
97
|
+
puts "❌ Chat prompt template failed: #{e.message}"
|
98
|
+
end
|
99
|
+
|
100
|
+
# Test 7: Evaluators
|
101
|
+
puts "\n7. Testing evaluators..."
|
102
|
+
begin
|
103
|
+
# Exact match evaluator
|
104
|
+
exact_match = Langfuse::Evaluators::ExactMatchEvaluator.new
|
105
|
+
result = exact_match.evaluate(
|
106
|
+
"What is 2+2?",
|
107
|
+
"4",
|
108
|
+
expected: "4"
|
109
|
+
)
|
110
|
+
puts "✅ Exact match evaluator: #{result}"
|
111
|
+
|
112
|
+
# Similarity evaluator
|
113
|
+
similarity = Langfuse::Evaluators::SimilarityEvaluator.new
|
114
|
+
result = similarity.evaluate(
|
115
|
+
"What is AI?",
|
116
|
+
"Artificial Intelligence",
|
117
|
+
expected: "AI is artificial intelligence"
|
118
|
+
)
|
119
|
+
puts "✅ Similarity evaluator: #{result}"
|
120
|
+
|
121
|
+
# Length evaluator
|
122
|
+
length = Langfuse::Evaluators::LengthEvaluator.new(min_length: 5, max_length: 20)
|
123
|
+
result = length.evaluate(
|
124
|
+
"Test input",
|
125
|
+
"This is a test",
|
126
|
+
expected: nil
|
127
|
+
)
|
128
|
+
puts "✅ Length evaluator: #{result}"
|
129
|
+
|
130
|
+
# Contains evaluator
|
131
|
+
contains = Langfuse::Evaluators::ContainsEvaluator.new
|
132
|
+
result = contains.evaluate(
|
133
|
+
"Find Ruby",
|
134
|
+
"Ruby programming language",
|
135
|
+
expected: "Ruby"
|
136
|
+
)
|
137
|
+
puts "✅ Contains evaluator: #{result}"
|
138
|
+
|
139
|
+
# Regex evaluator
|
140
|
+
regex = Langfuse::Evaluators::RegexEvaluator.new(pattern: /\d+/)
|
141
|
+
result = regex.evaluate(
|
142
|
+
"Find numbers",
|
143
|
+
"There are 42 apples",
|
144
|
+
expected: nil
|
145
|
+
)
|
146
|
+
puts "✅ Regex evaluator: #{result}"
|
147
|
+
|
148
|
+
rescue => e
|
149
|
+
puts "❌ Evaluator failed: #{e.message}"
|
150
|
+
end
|
151
|
+
|
152
|
+
# Test 8: Utils
|
153
|
+
puts "\n8. Testing utilities..."
|
154
|
+
begin
|
155
|
+
id = Langfuse::Utils.generate_id
|
156
|
+
timestamp = Langfuse::Utils.current_timestamp
|
157
|
+
|
158
|
+
# Test data transformation
|
159
|
+
hash_data = { "key1" => "value1", "nested" => { "key2" => "value2" } }
|
160
|
+
symbolized = Langfuse::Utils.deep_symbolize_keys(hash_data)
|
161
|
+
stringified = Langfuse::Utils.deep_stringify_keys(symbolized)
|
162
|
+
|
163
|
+
puts "✅ Utils successful"
|
164
|
+
puts " ID: #{id[0..8]}..."
|
165
|
+
puts " Timestamp: #{timestamp}"
|
166
|
+
puts " Symbolized keys: #{symbolized.keys}"
|
167
|
+
puts " Stringified keys: #{stringified.keys}"
|
168
|
+
rescue => e
|
169
|
+
puts "❌ Utils failed: #{e.message}"
|
170
|
+
end
|
171
|
+
|
172
|
+
# Test 9: Event queue (without network)
|
173
|
+
puts "\n9. Testing event queue..."
|
174
|
+
begin
|
175
|
+
queue_size_before = client.instance_variable_get(:@event_queue).length
|
176
|
+
|
177
|
+
# Add some events
|
178
|
+
client.score(
|
179
|
+
trace_id: trace.id,
|
180
|
+
name: "test-score",
|
181
|
+
value: 0.9
|
182
|
+
)
|
183
|
+
|
184
|
+
trace.score(
|
185
|
+
name: "trace-score",
|
186
|
+
value: 0.8
|
187
|
+
)
|
188
|
+
|
189
|
+
generation.score(
|
190
|
+
name: "generation-score",
|
191
|
+
value: 0.95
|
192
|
+
)
|
193
|
+
|
194
|
+
queue_size_after = client.instance_variable_get(:@event_queue).length
|
195
|
+
|
196
|
+
puts "✅ Event queue successful"
|
197
|
+
puts " Events added: #{queue_size_after - queue_size_before}"
|
198
|
+
puts " Total events: #{queue_size_after}"
|
199
|
+
rescue => e
|
200
|
+
puts "❌ Event queue failed: #{e.message}"
|
201
|
+
end
|
202
|
+
|
203
|
+
# Test 10: Complex workflow
|
204
|
+
puts "\n10. Testing complex workflow..."
|
205
|
+
begin
|
206
|
+
# Create a complex trace with nested spans
|
207
|
+
complex_trace = client.trace(
|
208
|
+
name: "complex-workflow",
|
209
|
+
user_id: "user-456",
|
210
|
+
session_id: "session-789",
|
211
|
+
input: { query: "Explain quantum computing" },
|
212
|
+
metadata: {
|
213
|
+
environment: "test",
|
214
|
+
version: "1.0.0",
|
215
|
+
tags: ["physics", "computing"]
|
216
|
+
}
|
217
|
+
)
|
218
|
+
|
219
|
+
# Document retrieval span
|
220
|
+
retrieval_span = complex_trace.span(
|
221
|
+
name: "document-retrieval",
|
222
|
+
input: { query: "quantum computing basics" }
|
223
|
+
)
|
224
|
+
|
225
|
+
# Embedding generation
|
226
|
+
embedding_gen = retrieval_span.generation(
|
227
|
+
name: "embedding-generation",
|
228
|
+
model: "text-embedding-ada-002",
|
229
|
+
input: "quantum computing basics",
|
230
|
+
output: Array.new(1536) { rand(-1.0..1.0) }, # Mock embedding
|
231
|
+
usage: { prompt_tokens: 4, total_tokens: 4 }
|
232
|
+
)
|
233
|
+
|
234
|
+
retrieval_span.end(
|
235
|
+
output: {
|
236
|
+
documents: [
|
237
|
+
"Quantum computing uses quantum bits...",
|
238
|
+
"Quantum algorithms can solve certain problems..."
|
239
|
+
]
|
240
|
+
}
|
241
|
+
)
|
242
|
+
|
243
|
+
# Answer generation span
|
244
|
+
answer_span = complex_trace.span(
|
245
|
+
name: "answer-generation",
|
246
|
+
input: {
|
247
|
+
query: "Explain quantum computing",
|
248
|
+
context: ["Quantum computing uses quantum bits...", "Quantum algorithms can solve certain problems..."]
|
249
|
+
}
|
250
|
+
)
|
251
|
+
|
252
|
+
# LLM generation
|
253
|
+
llm_gen = answer_span.generation(
|
254
|
+
name: "openai-completion",
|
255
|
+
model: "gpt-4",
|
256
|
+
input: [
|
257
|
+
{ role: "system", content: "You are a physics expert." },
|
258
|
+
{ role: "user", content: "Explain quantum computing based on the context." }
|
259
|
+
],
|
260
|
+
output: {
|
261
|
+
content: "Quantum computing is a revolutionary approach to computation that leverages quantum mechanical phenomena like superposition and entanglement to process information in fundamentally different ways than classical computers."
|
262
|
+
},
|
263
|
+
usage: {
|
264
|
+
prompt_tokens: 120,
|
265
|
+
completion_tokens: 45,
|
266
|
+
total_tokens: 165
|
267
|
+
},
|
268
|
+
model_parameters: {
|
269
|
+
temperature: 0.7,
|
270
|
+
max_tokens: 200
|
271
|
+
}
|
272
|
+
)
|
273
|
+
|
274
|
+
answer_span.end(
|
275
|
+
output: {
|
276
|
+
answer: "Quantum computing is a revolutionary approach to computation that leverages quantum mechanical phenomena like superposition and entanglement to process information in fundamentally different ways than classical computers."
|
277
|
+
}
|
278
|
+
)
|
279
|
+
|
280
|
+
complex_trace.update(
|
281
|
+
output: {
|
282
|
+
answer: "Quantum computing is a revolutionary approach to computation that leverages quantum mechanical phenomena like superposition and entanglement to process information in fundamentally different ways than classical computers."
|
283
|
+
}
|
284
|
+
)
|
285
|
+
|
286
|
+
puts "✅ Complex workflow successful"
|
287
|
+
puts " Trace ID: #{complex_trace.id}"
|
288
|
+
puts " Spans created: 2"
|
289
|
+
puts " Generations created: 2"
|
290
|
+
|
291
|
+
rescue => e
|
292
|
+
puts "❌ Complex workflow failed: #{e.message}"
|
293
|
+
end
|
294
|
+
|
295
|
+
# Test 11: Error handling
|
296
|
+
puts "\n11. Testing error handling..."
|
297
|
+
begin
|
298
|
+
# Test validation error
|
299
|
+
begin
|
300
|
+
Langfuse::Utils.validate_required_fields({ name: "test" }, [:name, :required_field])
|
301
|
+
rescue Langfuse::ValidationError => e
|
302
|
+
puts "✅ Validation error caught: #{e.message}"
|
303
|
+
end
|
304
|
+
|
305
|
+
# Test authentication error
|
306
|
+
begin
|
307
|
+
Langfuse.new(public_key: nil, secret_key: "secret")
|
308
|
+
rescue Langfuse::AuthenticationError => e
|
309
|
+
puts "✅ Authentication error caught: #{e.message}"
|
310
|
+
end
|
311
|
+
|
312
|
+
rescue => e
|
313
|
+
puts "❌ Error handling failed: #{e.message}"
|
314
|
+
end
|
315
|
+
|
316
|
+
# Final summary
|
317
|
+
puts "\n🎉 All offline tests completed successfully!"
|
318
|
+
puts " The Langfuse Ruby SDK is ready for use!"
|
319
|
+
puts " Total events in queue: #{client.instance_variable_get(:@event_queue).length}"
|
320
|
+
|
321
|
+
# Clean shutdown (kill background thread)
|
322
|
+
client.instance_variable_get(:@flush_thread)&.kill
|
323
|
+
puts " Background thread terminated"
|
324
|
+
|
325
|
+
puts "\n📚 Next steps:"
|
326
|
+
puts " 1. Set your real Langfuse API keys"
|
327
|
+
puts " 2. Configure the correct host URL"
|
328
|
+
puts " 3. Start using the SDK in your application"
|
329
|
+
puts " 4. Check the examples/ directory for more usage patterns"
|
metadata
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: langfuse-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Your Name
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-07-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: concurrent-ruby
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday-net_http
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: json
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '13.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '13.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: vcr
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '6.0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '6.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: webmock
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '3.0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '3.0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: yard
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.9'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.9'
|
167
|
+
description: Ruby client library for Langfuse, providing tracing, prompt management,
|
168
|
+
and evaluation capabilities for LLM applications
|
169
|
+
email:
|
170
|
+
- your.email@example.com
|
171
|
+
executables: []
|
172
|
+
extensions: []
|
173
|
+
extra_rdoc_files: []
|
174
|
+
files:
|
175
|
+
- ".github/workflows/ci.yml"
|
176
|
+
- ".github/workflows/release.yml"
|
177
|
+
- ".gitignore"
|
178
|
+
- CHANGELOG.md
|
179
|
+
- FINAL_SUMMARY.md
|
180
|
+
- Gemfile
|
181
|
+
- Gemfile.lock
|
182
|
+
- LICENSE
|
183
|
+
- PROJECT_SUMMARY.md
|
184
|
+
- PUBLISH_GUIDE.md
|
185
|
+
- README.md
|
186
|
+
- RELEASE_CHECKLIST.md
|
187
|
+
- Rakefile
|
188
|
+
- examples/basic_tracing.rb
|
189
|
+
- examples/prompt_management.rb
|
190
|
+
- langfuse-ruby.gemspec
|
191
|
+
- lib/langfuse.rb
|
192
|
+
- lib/langfuse/client.rb
|
193
|
+
- lib/langfuse/errors.rb
|
194
|
+
- lib/langfuse/evaluation.rb
|
195
|
+
- lib/langfuse/generation.rb
|
196
|
+
- lib/langfuse/prompt.rb
|
197
|
+
- lib/langfuse/span.rb
|
198
|
+
- lib/langfuse/trace.rb
|
199
|
+
- lib/langfuse/utils.rb
|
200
|
+
- lib/langfuse/version.rb
|
201
|
+
- scripts/release.sh
|
202
|
+
- scripts/verify_release.rb
|
203
|
+
- test_basic.rb
|
204
|
+
- test_offline.rb
|
205
|
+
homepage: https://github.com/your-username/langfuse-ruby
|
206
|
+
licenses:
|
207
|
+
- MIT
|
208
|
+
metadata:
|
209
|
+
allowed_push_host: https://rubygems.org
|
210
|
+
homepage_uri: https://github.com/your-username/langfuse-ruby
|
211
|
+
source_code_uri: https://github.com/your-username/langfuse-ruby
|
212
|
+
changelog_uri: https://github.com/your-username/langfuse-ruby/blob/main/CHANGELOG.md
|
213
|
+
post_install_message:
|
214
|
+
rdoc_options: []
|
215
|
+
require_paths:
|
216
|
+
- lib
|
217
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
218
|
+
requirements:
|
219
|
+
- - ">="
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: 2.7.0
|
222
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
|
+
requirements:
|
224
|
+
- - ">="
|
225
|
+
- !ruby/object:Gem::Version
|
226
|
+
version: '0'
|
227
|
+
requirements: []
|
228
|
+
rubygems_version: 3.5.11
|
229
|
+
signing_key:
|
230
|
+
specification_version: 4
|
231
|
+
summary: Ruby SDK for Langfuse - Open source LLM engineering platform
|
232
|
+
test_files: []
|