langfuse-ruby 0.1.3 → 0.1.4
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/.github/workflows/ci.yml +53 -0
- data/CHANGELOG.md +24 -4
- data/Gemfile.lock +3 -3
- data/README.md +5 -1
- data/langfuse-ruby.gemspec +2 -2
- data/lib/langfuse/client.rb +27 -2
- data/lib/langfuse/trace.rb +35 -0
- data/lib/langfuse/version.rb +1 -1
- data/test_offline.rb +32 -6
- metadata +23 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bb59924d3a9dcb1cb99841c6d07dd1277838ffee389d13ada1c8b03cafeb524
|
4
|
+
data.tar.gz: c5ba1846cd51fc3dc82fb43dd335d88394549652531a5243101ccd43ef71b3fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e448848c65cb8cd6f7ab7e4e566787bcab4aa8c43f20da7cc7a7a39e24e888c734c23644682f080635a0288b40fc4e3e169d8576445fdd07dde8d676faaccca
|
7
|
+
data.tar.gz: 9d9d1e88bf2e1161bd1d7f316e17600904169344b679839992a227eb35ac48e7edbe188ce782e3757f9f03a8a39104eac8c171a23f7bdc0c54b707754dfd87e8
|
@@ -0,0 +1,53 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ main, master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ main, master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
|
13
|
+
strategy:
|
14
|
+
matrix:
|
15
|
+
ruby-version: ['2.7', '3.0', '3.1', '3.2', '3.3']
|
16
|
+
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v4
|
19
|
+
|
20
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
21
|
+
uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
24
|
+
bundler-cache: true
|
25
|
+
|
26
|
+
- name: Run tests
|
27
|
+
run: bundle exec rspec
|
28
|
+
|
29
|
+
- name: Run offline tests
|
30
|
+
run: ruby test_offline.rb
|
31
|
+
|
32
|
+
- name: Run RuboCop
|
33
|
+
run: bundle exec rubocop
|
34
|
+
continue-on-error: true
|
35
|
+
|
36
|
+
build:
|
37
|
+
runs-on: ubuntu-latest
|
38
|
+
needs: test
|
39
|
+
|
40
|
+
steps:
|
41
|
+
- uses: actions/checkout@v4
|
42
|
+
|
43
|
+
- name: Set up Ruby
|
44
|
+
uses: ruby/setup-ruby@v1
|
45
|
+
with:
|
46
|
+
ruby-version: '3.2'
|
47
|
+
bundler-cache: true
|
48
|
+
|
49
|
+
- name: Build gem
|
50
|
+
run: gem build langfuse-ruby.gemspec
|
51
|
+
|
52
|
+
- name: Verify gem can be installed
|
53
|
+
run: gem install langfuse-ruby-*.gem
|
data/CHANGELOG.md
CHANGED
@@ -7,20 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [0.1.4] - 2025-07-29
|
11
|
+
|
10
12
|
### Added
|
13
|
+
- Added support for `trace-update` event type in Langfuse ingestion API
|
11
14
|
- Added support for `event-create` event type in Langfuse ingestion API
|
12
15
|
- New `Event` class for creating generic events within traces, spans, and generations
|
13
16
|
- Added `event()` method to `Client`, `Trace`, `Span`, and `Generation` classes
|
14
17
|
- Enhanced event validation to include all supported Langfuse event types
|
15
18
|
- New example file `examples/event_usage.rb` demonstrating event functionality
|
16
19
|
|
17
|
-
|
20
|
+
### Fixed
|
21
|
+
- Improved offline test error handling and authentication validation
|
22
|
+
- Enhanced error handling tests with proper configuration management
|
23
|
+
- Fixed prompt template validation tests in offline mode
|
24
|
+
- Better error message handling for authentication failures
|
18
25
|
|
19
|
-
###
|
26
|
+
### Improved
|
27
|
+
- More comprehensive error handling test coverage
|
28
|
+
- Better test isolation and cleanup procedures
|
29
|
+
- Enhanced debugging capabilities for offline testing
|
30
|
+
|
31
|
+
## [0.1.3] - 2025-07-13
|
32
|
+
|
33
|
+
### Fixed
|
34
|
+
- Enhanced event data validation and debugging capabilities
|
35
|
+
- More detailed error messages for event structure validation failures
|
36
|
+
|
37
|
+
## [0.1.2] - 2025-07-12
|
38
|
+
|
39
|
+
### Fixed
|
20
40
|
- Enhanced event data validation and debugging capabilities
|
21
41
|
- More detailed error messages for event structure validation failures
|
22
42
|
|
23
|
-
## [0.1.1] - 2025-
|
43
|
+
## [0.1.1] - 2025-07-12
|
24
44
|
|
25
45
|
### Fixed
|
26
46
|
- Improved error handling for `get_prompt` method when prompt doesn't exist
|
@@ -36,7 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
36
56
|
- Updated gemspec metadata to avoid RubyGems warnings
|
37
57
|
- Improved documentation with clearer error handling examples
|
38
58
|
|
39
|
-
## [0.1.0] - 2025-
|
59
|
+
## [0.1.0] - 2025-07-12
|
40
60
|
|
41
61
|
### Added
|
42
62
|
- Initial release of Langfuse Ruby SDK
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# Langfuse Ruby SDK
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/langfuse-ruby)
|
4
|
-
[](https://github.com/ai-firstly/langfuse-ruby/actions/workflows/ci.yml)
|
5
|
+
[](https://www.ruby-lang.org/)
|
6
|
+
[](LICENSE)
|
5
7
|
|
6
8
|
Ruby SDK for [Langfuse](https://langfuse.com) - the open-source LLM engineering platform. This SDK provides comprehensive tracing, prompt management, and evaluation capabilities for LLM applications.
|
7
9
|
|
@@ -80,6 +82,8 @@ generation = trace.generation(
|
|
80
82
|
|
81
83
|
generation.end(output: 'Hello! How can I help you today?', usage: { prompt_tokens: 10, completion_tokens: 15, total_tokens: 25 })
|
82
84
|
|
85
|
+
trace.update(output: 'Hello! How can I help you today?')
|
86
|
+
|
83
87
|
# Flush events (optional - happens automatically)
|
84
88
|
client.flush
|
85
89
|
```
|
data/langfuse-ruby.gemspec
CHANGED
@@ -41,8 +41,8 @@ Gem::Specification.new do |spec|
|
|
41
41
|
|
42
42
|
# Dependencies
|
43
43
|
spec.add_dependency 'concurrent-ruby', '~> 1.0'
|
44
|
-
spec.add_dependency 'faraday', '
|
45
|
-
spec.add_dependency 'faraday-net_http', '
|
44
|
+
spec.add_dependency 'faraday', '>= 1.8', '< 3.0'
|
45
|
+
spec.add_dependency 'faraday-net_http', '>= 1.0', '< 4.0'
|
46
46
|
spec.add_dependency 'json', '~> 2.0'
|
47
47
|
|
48
48
|
# Development dependencies
|
data/lib/langfuse/client.rb
CHANGED
@@ -188,7 +188,7 @@ module Langfuse
|
|
188
188
|
def enqueue_event(type, body)
|
189
189
|
# 验证事件类型是否有效
|
190
190
|
valid_types = %w[
|
191
|
-
trace-create
|
191
|
+
trace-create trace-update
|
192
192
|
generation-create generation-update
|
193
193
|
span-create span-update
|
194
194
|
event-create
|
@@ -207,7 +207,32 @@ module Langfuse
|
|
207
207
|
body: Utils.deep_stringify_keys(body)
|
208
208
|
}
|
209
209
|
|
210
|
-
|
210
|
+
if type == 'trace-update'
|
211
|
+
# 查找对应的 trace-create 事件并更新
|
212
|
+
trace_id = body['id'] || body[:id]
|
213
|
+
if trace_id
|
214
|
+
existing_event_index = @event_queue.find_index do |existing_event|
|
215
|
+
existing_event[:type] == 'trace-create' &&
|
216
|
+
(existing_event[:body]['id'] == trace_id || existing_event[:body][:id] == trace_id)
|
217
|
+
end
|
218
|
+
|
219
|
+
if existing_event_index
|
220
|
+
# 更新现有的 trace-create 事件
|
221
|
+
@event_queue[existing_event_index][:body].merge!(event[:body])
|
222
|
+
@event_queue[existing_event_index][:timestamp] = event[:timestamp]
|
223
|
+
puts "Updated existing trace-create event for trace_id: #{trace_id}" if @debug
|
224
|
+
else
|
225
|
+
# 如果没找到对应的 trace-create 事件,将 trace-update 转换为 trace-create
|
226
|
+
event[:type] = 'trace-create'
|
227
|
+
@event_queue << event
|
228
|
+
puts "Converted trace-update to trace-create for trace_id: #{trace_id}" if @debug
|
229
|
+
end
|
230
|
+
elsif @debug
|
231
|
+
puts 'Warning: trace-update event missing trace_id, skipping'
|
232
|
+
end
|
233
|
+
else
|
234
|
+
@event_queue << event
|
235
|
+
end
|
211
236
|
puts "Enqueued event: #{type}" if @debug
|
212
237
|
end
|
213
238
|
|
data/lib/langfuse/trace.rb
CHANGED
@@ -95,6 +95,23 @@ module Langfuse
|
|
95
95
|
)
|
96
96
|
end
|
97
97
|
|
98
|
+
def update(name: nil, user_id: nil, session_id: nil, version: nil,
|
99
|
+
release: nil, input: nil, output: nil, metadata: nil, tags: nil, **kwargs)
|
100
|
+
# 更新实例变量
|
101
|
+
@name = name if name
|
102
|
+
@user_id = user_id if user_id
|
103
|
+
@session_id = session_id if session_id
|
104
|
+
@version = version if version
|
105
|
+
@release = release if release
|
106
|
+
@input = input if input
|
107
|
+
@output = output if output
|
108
|
+
@metadata = metadata if metadata
|
109
|
+
@tags = tags if tags
|
110
|
+
@kwargs.merge!(kwargs) if kwargs.any?
|
111
|
+
# 触发 trace-update 事件
|
112
|
+
update_trace
|
113
|
+
end
|
114
|
+
|
98
115
|
def get_url
|
99
116
|
"#{@client.host}/trace/#{@id}"
|
100
117
|
end
|
@@ -134,5 +151,23 @@ module Langfuse
|
|
134
151
|
|
135
152
|
@client.enqueue_event('trace-create', data)
|
136
153
|
end
|
154
|
+
|
155
|
+
def update_trace
|
156
|
+
data = {
|
157
|
+
id: @id,
|
158
|
+
name: @name,
|
159
|
+
user_id: @user_id,
|
160
|
+
session_id: @session_id,
|
161
|
+
version: @version,
|
162
|
+
release: @release,
|
163
|
+
input: @input,
|
164
|
+
output: @output,
|
165
|
+
metadata: @metadata,
|
166
|
+
tags: @tags,
|
167
|
+
timestamp: @timestamp
|
168
|
+
}.merge(@kwargs).compact
|
169
|
+
|
170
|
+
@client.enqueue_event('trace-update', data)
|
171
|
+
end
|
137
172
|
end
|
138
173
|
end
|
data/lib/langfuse/version.rb
CHANGED
data/test_offline.rb
CHANGED
@@ -288,19 +288,45 @@ end
|
|
288
288
|
# Test 11: Error handling
|
289
289
|
puts "\n11. Testing error handling..."
|
290
290
|
begin
|
291
|
-
#
|
291
|
+
# Save current configuration
|
292
|
+
original_public_key = Langfuse.configuration.public_key
|
293
|
+
original_secret_key = Langfuse.configuration.secret_key
|
294
|
+
|
295
|
+
# Test authentication error - missing public key
|
292
296
|
begin
|
293
|
-
Langfuse
|
294
|
-
|
295
|
-
|
297
|
+
Langfuse.configuration.public_key = nil
|
298
|
+
ENV.delete('LANGFUSE_PUBLIC_KEY')
|
299
|
+
Langfuse.new(public_key: nil, secret_key: 'secret')
|
300
|
+
puts '❌ Expected AuthenticationError but none was raised'
|
301
|
+
rescue Langfuse::AuthenticationError => e
|
302
|
+
puts "✅ Authentication error caught: #{e.message}"
|
303
|
+
ensure
|
304
|
+
Langfuse.configuration.public_key = original_public_key
|
296
305
|
end
|
297
306
|
|
298
|
-
# Test authentication error
|
307
|
+
# Test authentication error - missing secret key
|
299
308
|
begin
|
300
|
-
Langfuse.
|
309
|
+
Langfuse.configuration.secret_key = nil
|
310
|
+
ENV.delete('LANGFUSE_SECRET_KEY')
|
311
|
+
Langfuse.new(public_key: 'public', secret_key: nil)
|
312
|
+
puts '❌ Expected AuthenticationError but none was raised'
|
301
313
|
rescue Langfuse::AuthenticationError => e
|
302
314
|
puts "✅ Authentication error caught: #{e.message}"
|
315
|
+
ensure
|
316
|
+
Langfuse.configuration.secret_key = original_secret_key
|
303
317
|
end
|
318
|
+
|
319
|
+
# Test validation error through prompt template
|
320
|
+
begin
|
321
|
+
template = Langfuse::PromptTemplate.from_template('Hello {{name}}!')
|
322
|
+
# This should work fine
|
323
|
+
result = template.format(name: 'World')
|
324
|
+
puts "✅ Prompt template validation passed: #{result}"
|
325
|
+
rescue Langfuse::ValidationError => e
|
326
|
+
puts "✅ Validation error caught: #{e.message}"
|
327
|
+
end
|
328
|
+
|
329
|
+
puts '✅ Error handling tests completed'
|
304
330
|
rescue StandardError => e
|
305
331
|
puts "❌ Error handling failed: #{e.message}"
|
306
332
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: langfuse-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Sun
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-07-
|
11
|
+
date: 2025-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -28,30 +28,42 @@ dependencies:
|
|
28
28
|
name: faraday
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.8'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '3.0'
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
|
-
- - "
|
41
|
+
- - ">="
|
39
42
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
43
|
+
version: '1.8'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '3.0'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: faraday-net_http
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
44
50
|
requirements:
|
45
|
-
- - "
|
51
|
+
- - ">="
|
46
52
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
53
|
+
version: '1.0'
|
54
|
+
- - "<"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '4.0'
|
48
57
|
type: :runtime
|
49
58
|
prerelease: false
|
50
59
|
version_requirements: !ruby/object:Gem::Requirement
|
51
60
|
requirements:
|
52
|
-
- - "
|
61
|
+
- - ">="
|
53
62
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
63
|
+
version: '1.0'
|
64
|
+
- - "<"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '4.0'
|
55
67
|
- !ruby/object:Gem::Dependency
|
56
68
|
name: json
|
57
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -172,6 +184,7 @@ executables: []
|
|
172
184
|
extensions: []
|
173
185
|
extra_rdoc_files: []
|
174
186
|
files:
|
187
|
+
- ".github/workflows/ci.yml"
|
175
188
|
- ".github/workflows/release.yml"
|
176
189
|
- ".gitignore"
|
177
190
|
- CHANGELOG.md
|