langfuse-ruby 0.1.0 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 136c2037b43d0d3005419cf33240cc191034564518e923c497882cec27e6335b
4
- data.tar.gz: 465b7c9c581a285c47dfd2d529a995b2ba0beb9dc16b756bb1736d370f35fb88
3
+ metadata.gz: d97c16de061cdf52403a05086a90aaac149b9fe9dc6d771e36709e763abcb3eb
4
+ data.tar.gz: c254257501aff83671377cc50ea8f25c143d8dca6fa0f40d157fcfa6eb3d75b9
5
5
  SHA512:
6
- metadata.gz: ccf93a4c782d1b56eb42a3be4a1463e07e1198bf570447b383f8a82cb4286988ef99043feafec412ed5e944795511c6086976eb77115f233854aa7c2a2b1d7bb
7
- data.tar.gz: 2a30b9cd42f901cfc9181f4a068e5c25e5c3a833e0238484c746ca55a7c4f0021a1b1a2218337b8394db678e65fe2cc2f7539951804d898eae7452909102b995
6
+ metadata.gz: f2cf7c8a6d72bb5a81b73ba6a5a110e9e6312b09e9a790a14d566a41b1e7d4a8ce40c53fb8d0d74b4c12c9cd06bd20e03680b6829505f69aa7b80dee3ecf6750
7
+ data.tar.gz: c880f859cf2f0d6fc9586ceada7c7488ff25a8be4c3fbf4740443477e592b8eee20895e24c69c371a8f0a96c60fd40d1a66de2126b762378ea41115665de3666
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- langfuse-ruby (0.1.0)
4
+ langfuse-ruby (0.1.1)
5
5
  concurrent-ruby (~> 1.0)
6
6
  faraday (~> 2.0)
7
7
  faraday-net_http (~> 3.0)
@@ -0,0 +1,206 @@
1
+ # Langfuse Ruby SDK - Prompt 获取故障排除指南
2
+
3
+ ## 问题描述
4
+
5
+ 当调用 `client.get_prompt("prompt-name")` 时,可能会遇到以下错误:
6
+
7
+ ```
8
+ JSON::ParserError: unexpected token at '<!DOCTYPE html>
9
+ ```
10
+
11
+ ## 问题原因
12
+
13
+ 这个错误通常表示 Langfuse API 返回了 HTML 页面而不是预期的 JSON 响应。最常见的原因是:
14
+
15
+ 1. **404 错误**:请求的 prompt 不存在
16
+ 2. **认证问题**:API 密钥无效或权限不足
17
+ 3. **网络问题**:无法连接到 Langfuse 服务器
18
+
19
+ ## 解决方案
20
+
21
+ ### 1. 检查 Prompt 是否存在
22
+
23
+ 首先确认要获取的 prompt 是否已在 Langfuse 中创建:
24
+
25
+ ```ruby
26
+ # 尝试获取 prompt
27
+ begin
28
+ prompt = client.get_prompt("your-prompt-name")
29
+ puts "成功获取 prompt: #{prompt.name}"
30
+ rescue Langfuse::ValidationError => e
31
+ if e.message.include?("404")
32
+ puts "Prompt 不存在,请先创建它"
33
+ else
34
+ puts "其他验证错误: #{e.message}"
35
+ end
36
+ rescue => e
37
+ puts "未知错误: #{e.message}"
38
+ end
39
+ ```
40
+
41
+ ### 2. 创建测试 Prompt
42
+
43
+ 如果 prompt 不存在,可以先创建一个:
44
+
45
+ ```ruby
46
+ # 创建一个测试 prompt
47
+ test_prompt = client.create_prompt(
48
+ name: "test-prompt",
49
+ prompt: "Hello {{name}}! This is a test prompt.",
50
+ labels: ["test"],
51
+ config: { temperature: 0.7 }
52
+ )
53
+
54
+ puts "创建了 prompt: #{test_prompt.name}"
55
+
56
+ # 然后尝试获取它
57
+ retrieved_prompt = client.get_prompt("test-prompt")
58
+ puts "成功获取 prompt: #{retrieved_prompt.name}"
59
+ ```
60
+
61
+ ### 3. 检查 API 密钥
62
+
63
+ 确认 API 密钥设置正确:
64
+
65
+ ```ruby
66
+ # 检查环境变量
67
+ puts "Public Key: #{ENV['LANGFUSE_PUBLIC_KEY']}"
68
+ puts "Secret Key: #{ENV['LANGFUSE_SECRET_KEY'] ? '已设置' : '未设置'}"
69
+ puts "Host: #{ENV['LANGFUSE_HOST'] || 'https://cloud.langfuse.com'}"
70
+
71
+ # 或者在代码中直接设置
72
+ client = Langfuse.new(
73
+ public_key: "your-public-key",
74
+ secret_key: "your-secret-key",
75
+ host: "https://cloud.langfuse.com"
76
+ )
77
+ ```
78
+
79
+ ### 4. 测试连接
80
+
81
+ 测试与 Langfuse 服务器的基本连接:
82
+
83
+ ```ruby
84
+ begin
85
+ response = client.send(:get, "/api/public/health")
86
+ puts "连接正常"
87
+ rescue => e
88
+ puts "连接失败: #{e.message}"
89
+ end
90
+ ```
91
+
92
+ ### 5. 启用调试模式
93
+
94
+ 启用调试模式以获取更多信息:
95
+
96
+ ```ruby
97
+ client = Langfuse.new(
98
+ public_key: "your-public-key",
99
+ secret_key: "your-secret-key",
100
+ host: "https://cloud.langfuse.com",
101
+ debug: true # 启用调试模式
102
+ )
103
+ ```
104
+
105
+ ## 改进的错误处理
106
+
107
+ Ruby SDK 已经改进了错误处理,现在会提供更清晰的错误信息:
108
+
109
+ ```ruby
110
+ begin
111
+ prompt = client.get_prompt("non-existent-prompt")
112
+ rescue Langfuse::ValidationError => e
113
+ puts "验证错误: #{e.message}"
114
+ # 现在会显示:Resource not found (404). Server returned HTML page instead of JSON API response. This usually means the requested resource does not exist.
115
+ rescue Langfuse::AuthenticationError => e
116
+ puts "认证错误: #{e.message}"
117
+ rescue => e
118
+ puts "其他错误: #{e.message}"
119
+ end
120
+ ```
121
+
122
+ ## 常见问题
123
+
124
+ ### Q: 为什么会收到 HTML 响应而不是 JSON?
125
+
126
+ A: 当 API 端点返回 404 错误时,Langfuse 服务器返回一个 HTML 错误页面而不是 JSON 响应。这是 Web 应用程序的常见行为。
127
+
128
+ ### Q: 如何确认 prompt 名称是否正确?
129
+
130
+ A: 可以登录 Langfuse Web 界面查看所有可用的 prompt,或者使用 API 列出所有 prompt:
131
+
132
+ ```ruby
133
+ # 注意:这需要使用底层 API 方法
134
+ # prompts = client.api.prompts.list()
135
+ ```
136
+
137
+ ### Q: 大小写是否重要?
138
+
139
+ A: 是的,prompt 名称是区分大小写的。确保使用正确的大小写。
140
+
141
+ ### Q: 如何处理网络超时?
142
+
143
+ A: 可以调整超时设置:
144
+
145
+ ```ruby
146
+ client = Langfuse.new(
147
+ public_key: "your-public-key",
148
+ secret_key: "your-secret-key",
149
+ host: "https://cloud.langfuse.com",
150
+ timeout: 60 # 60 秒超时
151
+ )
152
+ ```
153
+
154
+ ## 完整示例
155
+
156
+ 以下是一个完整的示例,展示如何安全地获取 prompt:
157
+
158
+ ```ruby
159
+ require 'langfuse'
160
+
161
+ # 初始化客户端
162
+ client = Langfuse.new(
163
+ public_key: ENV['LANGFUSE_PUBLIC_KEY'],
164
+ secret_key: ENV['LANGFUSE_SECRET_KEY'],
165
+ host: ENV['LANGFUSE_HOST'] || 'https://cloud.langfuse.com',
166
+ debug: true
167
+ )
168
+
169
+ # 安全地获取 prompt
170
+ def safe_get_prompt(client, name)
171
+ begin
172
+ prompt = client.get_prompt(name)
173
+ puts "✅ 成功获取 prompt: #{prompt.name}"
174
+ return prompt
175
+ rescue Langfuse::ValidationError => e
176
+ if e.message.include?("404")
177
+ puts "❌ Prompt '#{name}' 不存在"
178
+ puts "建议:请先在 Langfuse 中创建这个 prompt"
179
+ else
180
+ puts "❌ 验证错误: #{e.message}"
181
+ end
182
+ rescue Langfuse::AuthenticationError => e
183
+ puts "❌ 认证失败: #{e.message}"
184
+ puts "建议:检查 API 密钥是否正确"
185
+ rescue => e
186
+ puts "❌ 未知错误: #{e.message}"
187
+ end
188
+ return nil
189
+ end
190
+
191
+ # 使用示例
192
+ prompt = safe_get_prompt(client, "your-prompt-name")
193
+ if prompt
194
+ compiled = prompt.compile(variable: "value")
195
+ puts "编译后的 prompt: #{compiled}"
196
+ end
197
+ ```
198
+
199
+ ## 获取帮助
200
+
201
+ 如果问题仍然存在,请:
202
+
203
+ 1. 检查 [Langfuse 文档](https://langfuse.com/docs/prompts/get-started)
204
+ 2. 访问 [GitHub Issues](https://github.com/langfuse/langfuse-ruby/issues)
205
+ 3. 加入 [Discord 社区](https://discord.gg/langfuse)
206
+ 4. 查看 [状态页面](https://status.langfuse.com) 了解服务状态
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Langfuse Ruby SDK
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/langfuse-ruby.svg)](https://badge.fury.io/rb/langfuse-ruby)
4
- [![Build Status](https://github.com/your-username/langfuse-ruby/workflows/CI/badge.svg)](https://github.com/your-username/langfuse-ruby/actions)
4
+ [![Build Status](https://github.com/ai-firstly/langfuse-ruby/workflows/CI/badge.svg)](https://github.com/ai-firstly/langfuse-ruby/actions)
5
5
 
6
6
  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
7
 
@@ -422,7 +422,7 @@ For an interactive prompt that will allow you to experiment.
422
422
 
423
423
  ## Contributing
424
424
 
425
- Bug reports and pull requests are welcome on GitHub at https://github.com/your-username/langfuse-ruby.
425
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ai-firstly/langfuse-ruby.
426
426
 
427
427
  ## License
428
428
 
@@ -433,4 +433,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
433
433
  - [Langfuse Documentation](https://langfuse.com/docs)
434
434
  - [Langfuse GitHub](https://github.com/langfuse/langfuse)
435
435
  - [API Reference](https://api.reference.langfuse.com)
436
- - [Ruby SDK Documentation](https://rubydoc.info/gems/langfuse-ruby)
436
+ - [Ruby SDK Documentation](https://rubydoc.info/gems/langfuse-ruby)
@@ -45,5 +45,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
45
45
  - rubocop (~> 1.0)
46
46
  - yard (~> 0.9)
47
47
 
48
- [Unreleased]: https://github.com/your-username/langfuse-ruby/compare/v0.1.0...HEAD
49
- [0.1.0]: https://github.com/your-username/langfuse-ruby/releases/tag/v0.1.0
48
+ [Unreleased]: https://github.com/ai-firstly/langfuse-ruby/compare/v0.1.0...HEAD
49
+ [0.1.0]: https://github.com/ai-firstly/langfuse-ruby/releases/tag/v0.1.0
@@ -30,10 +30,10 @@ git add .
30
30
  git commit -m "Initial commit: Langfuse Ruby SDK v0.1.0"
31
31
 
32
32
  # 添加远程仓库(替换为您的 GitHub 仓库)
33
- git remote add origin https://github.com/your-username/langfuse-ruby.git
33
+ git remote add origin https://github.com/ai-firstly/langfuse-ruby.git
34
34
 
35
35
  # 推送到 GitHub
36
- git push -u origin main
36
+ git push -u origin master
37
37
  ```
38
38
 
39
39
  ### 3. 创建 GitHub 仓库
@@ -50,7 +50,7 @@ git push -u origin main
50
50
 
51
51
  ```bash
52
52
  # 构建 gem
53
- gem build langfuse.gemspec
53
+ gem build langfuse-ruby.gemspec
54
54
 
55
55
  # 检查构建结果
56
56
  ls -la *.gem
@@ -60,13 +60,13 @@ ls -la *.gem
60
60
 
61
61
  ```bash
62
62
  # 本地安装构建的 gem
63
- gem install ./langfuse-0.1.0.gem
63
+ gem install ./langfuse-ruby-0.1.0.gem
64
64
 
65
65
  # 测试安装是否成功
66
66
  ruby -e "require 'langfuse'; puts 'Langfuse loaded successfully'"
67
67
 
68
68
  # 卸载本地测试版本
69
- gem uninstall langfuse
69
+ gem uninstall langfuse-ruby
70
70
  ```
71
71
 
72
72
  ### 3. 运行完整测试
@@ -111,7 +111,7 @@ chmod 0600 ~/.gem/credentials
111
111
  gem build langfuse.gemspec
112
112
 
113
113
  # 发布到 RubyGems
114
- gem push langfuse-0.1.0.gem
114
+ gem push langfuse-ruby-0.1.0.gem
115
115
  ```
116
116
 
117
117
  ## 📊 发布后验证
data/docs/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Langfuse Ruby SDK 文档
2
+
3
+ 本目录包含 Langfuse Ruby SDK 的所有文档。
4
+
5
+ ## 📚 文档索引
6
+
7
+ ### 开发和发布
8
+ - [📋 发布指南](PUBLISH_GUIDE.md) - 详细的 gem 发布流程
9
+ - [✅ 发布检查清单](RELEASE_CHECKLIST.md) - 发布前的检查项目
10
+ - [📝 变更日志](CHANGELOG.md) - 版本更新记录
11
+
12
+ ### 项目概览
13
+ - [📊 项目总结](PROJECT_SUMMARY.md) - 项目整体介绍
14
+ - [🎯 最终总结](FINAL_SUMMARY.md) - 项目完成情况总结
15
+
16
+ ## 🔗 相关链接
17
+
18
+ - [主要 README](../README.md) - 项目主页和使用说明
19
+ - [示例代码](../examples/) - 使用示例
20
+ - [API 文档](../lib/) - 源代码文档
21
+ - [测试文件](../spec/) - 测试用例
22
+
23
+ ## 📞 获取帮助
24
+
25
+ 如果您在使用过程中遇到问题,请:
26
+
27
+ 1. 查看相关文档
28
+ 2. 检查 [GitHub Issues](https://github.com/ai-firstly/langfuse-ruby/issues)
29
+ 3. 提交新的 Issue 或 Pull Request
30
+
31
+ ---
32
+
33
+ **感谢您使用 Langfuse Ruby SDK!** 🚀
@@ -1,20 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'lib/langfuse/version'
2
4
 
3
5
  Gem::Specification.new do |spec|
4
6
  spec.name = 'langfuse-ruby'
5
7
  spec.version = Langfuse::VERSION
6
- spec.authors = ['Your Name']
7
- spec.email = ['your.email@example.com']
8
+ spec.authors = ['Richard Sun']
9
+ spec.email = ['richard.sun@ai-firstly.com']
8
10
  spec.summary = 'Ruby SDK for Langfuse - Open source LLM engineering platform'
9
- spec.description = 'Ruby client library for Langfuse, providing tracing, prompt management, and evaluation capabilities for LLM applications'
10
- spec.homepage = 'https://github.com/your-username/langfuse-ruby'
11
+ spec.description = 'Ruby client library for Langfuse, providing tracing, prompt management, ' \
12
+ 'and evaluation capabilities for LLM applications'
13
+ spec.homepage = 'https://langfuse.com'
11
14
  spec.license = 'MIT'
12
15
  spec.required_ruby_version = '>= 2.7.0'
13
16
 
14
17
  spec.metadata['allowed_push_host'] = 'https://rubygems.org'
15
- spec.metadata['homepage_uri'] = spec.homepage
16
- spec.metadata['source_code_uri'] = 'https://github.com/your-username/langfuse-ruby'
17
- spec.metadata['changelog_uri'] = 'https://github.com/your-username/langfuse-ruby/blob/main/CHANGELOG.md'
18
+ spec.metadata['homepage_uri'] = 'https://langfuse.com/docs/sdk/ruby'
19
+ spec.metadata['source_code_uri'] = 'https://github.com/ai-firstly/langfuse-ruby'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/ai-firstly/langfuse-ruby/blob/main/CHANGELOG.md'
21
+ spec.metadata['documentation_uri'] = 'https://rubydoc.info/gems/langfuse-ruby'
22
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/ai-firstly/langfuse-ruby/issues'
18
23
 
19
24
  # Specify which files should be added to the gem when it is released.
20
25
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
@@ -16,8 +16,8 @@ module Langfuse
16
16
  @timeout = timeout || Langfuse.configuration.timeout
17
17
  @retries = retries || Langfuse.configuration.retries
18
18
 
19
- raise AuthenticationError, "Public key is required" unless @public_key
20
- raise AuthenticationError, "Secret key is required" unless @secret_key
19
+ raise AuthenticationError, 'Public key is required' unless @public_key
20
+ raise AuthenticationError, 'Secret key is required' unless @secret_key
21
21
 
22
22
  @connection = build_connection
23
23
  @event_queue = Concurrent::Array.new
@@ -95,8 +95,8 @@ module Langfuse
95
95
  def get_prompt(name, version: nil, label: nil, cache_ttl_seconds: 60)
96
96
  cache_key = "prompt:#{name}:#{version}:#{label}"
97
97
 
98
- if cached_prompt = @prompt_cache&.dig(cache_key)
99
- return cached_prompt[:prompt] if Time.now - cached_prompt[:cached_at] < cache_ttl_seconds
98
+ if (cached_prompt = @prompt_cache&.dig(cache_key)) && (Time.now - cached_prompt[:cached_at] < cache_ttl_seconds)
99
+ return cached_prompt[:prompt]
100
100
  end
101
101
 
102
102
  path = "/api/public/prompts/#{name}"
@@ -104,7 +104,22 @@ module Langfuse
104
104
  params[:version] = version if version
105
105
  params[:label] = label if label
106
106
 
107
+ puts "Making request to: #{@host}#{path} with params: #{params}" if @debug
108
+
107
109
  response = get(path, params)
110
+
111
+ puts "Response status: #{response.status}" if @debug
112
+ puts "Response headers: #{response.headers}" if @debug
113
+ puts "Response body type: #{response.body.class}" if @debug
114
+
115
+ # Check if response body is a string (HTML) instead of parsed JSON
116
+ if response.body.is_a?(String) && response.body.include?('<!DOCTYPE html>')
117
+ puts 'Received HTML response instead of JSON:' if @debug
118
+ puts response.body[0..200] if @debug
119
+ raise APIError,
120
+ 'Received HTML response instead of JSON. This usually indicates a 404 error or incorrect API endpoint.'
121
+ end
122
+
108
123
  prompt = Prompt.new(response.body)
109
124
 
110
125
  # Cache the prompt
@@ -123,12 +138,12 @@ module Langfuse
123
138
  **kwargs
124
139
  }
125
140
 
126
- response = post("/api/public/prompts", data)
141
+ response = post('/api/public/prompts', data)
127
142
  Prompt.new(response.body)
128
143
  end
129
144
 
130
145
  # Score/Evaluation operations
131
- def score(trace_id: nil, observation_id: nil, name:, value:, data_type: nil, comment: nil, **kwargs)
146
+ def score(name:, value:, trace_id: nil, observation_id: nil, data_type: nil, comment: nil, **kwargs)
132
147
  data = {
133
148
  name: name,
134
149
  value: value,
@@ -187,15 +202,15 @@ module Langfuse
187
202
  batch: events,
188
203
  metadata: {
189
204
  batch_size: events.length,
190
- sdk_name: "langfuse-ruby",
205
+ sdk_name: 'langfuse-ruby',
191
206
  sdk_version: Langfuse::VERSION
192
207
  }
193
208
  }
194
209
 
195
210
  begin
196
- response = post("/api/public/ingestion", batch_data)
211
+ response = post('/api/public/ingestion', batch_data)
197
212
  puts "Flushed #{events.length} events" if @debug
198
- rescue => e
213
+ rescue StandardError => e
199
214
  puts "Failed to flush events: #{e.message}" if @debug
200
215
  # Re-queue events on failure
201
216
  events.each { |event| @event_queue << event }
@@ -214,9 +229,13 @@ module Langfuse
214
229
  Faraday.new(url: @host) do |conn|
215
230
  conn.request :authorization, :basic, @public_key, @secret_key
216
231
  conn.request :json
232
+ # 更宽松的 JSON 响应处理,支持更多 content-type
217
233
  conn.response :json, content_type: /\bjson$/
218
234
  conn.adapter Faraday.default_adapter
219
235
  conn.options.timeout = @timeout
236
+
237
+ # 添加响应中间件来处理错误响应
238
+ conn.response :logger if @debug
220
239
  end
221
240
  end
222
241
 
@@ -236,29 +255,40 @@ module Langfuse
236
255
  rescue Faraday::ConnectionFailed => e
237
256
  if retries_left > 0
238
257
  retries_left -= 1
239
- sleep(2 ** (@retries - retries_left))
258
+ sleep(2**(@retries - retries_left))
240
259
  retry
241
260
  end
242
261
  raise NetworkError, "Connection failed: #{e.message}"
243
- rescue => e
262
+ rescue StandardError => e
244
263
  raise APIError, "Request failed: #{e.message}"
245
264
  end
246
265
  end
247
266
 
248
267
  def handle_response(response)
268
+ puts "Handling response with status: #{response.status}" if @debug
269
+
249
270
  case response.status
250
271
  when 200..299
251
272
  response
252
273
  when 401
253
274
  raise AuthenticationError, "Authentication failed: #{response.body}"
275
+ when 404
276
+ # 404 错误通常返回 HTML 页面
277
+ error_message = 'Resource not found (404)'
278
+ if response.body.is_a?(String) && response.body.include?('<!DOCTYPE html>')
279
+ error_message += '. Server returned HTML page instead of JSON API response. This usually means the requested resource does not exist.'
280
+ else
281
+ error_message += ": #{response.body}"
282
+ end
283
+ raise ValidationError, error_message
254
284
  when 429
255
285
  raise RateLimitError, "Rate limit exceeded: #{response.body}"
256
286
  when 400..499
257
- raise ValidationError, "Client error: #{response.body}"
287
+ raise ValidationError, "Client error (#{response.status}): #{response.body}"
258
288
  when 500..599
259
- raise APIError, "Server error: #{response.body}"
289
+ raise APIError, "Server error (#{response.status}): #{response.body}"
260
290
  else
261
- raise APIError, "Unexpected response: #{response.status} #{response.body}"
291
+ raise APIError, "Unexpected response (#{response.status}): #{response.body}"
262
292
  end
263
293
  end
264
294
 
@@ -268,7 +298,7 @@ module Langfuse
268
298
  sleep(5) # Flush every 5 seconds
269
299
  begin
270
300
  flush unless @event_queue.empty?
271
- rescue => e
301
+ rescue StandardError => e
272
302
  puts "Error in flush thread: #{e.message}" if @debug
273
303
  end
274
304
  end
@@ -67,7 +67,7 @@ module Langfuse
67
67
  end
68
68
 
69
69
  def evaluate(input, output, expected: nil, context: nil)
70
- raise NotImplementedError, "Subclasses must implement evaluate method"
70
+ raise NotImplementedError, 'Subclasses must implement evaluate method'
71
71
  end
72
72
 
73
73
  protected
@@ -129,7 +129,7 @@ module Langfuse
129
129
  length = output.to_s.length
130
130
 
131
131
  if @min_length && @max_length
132
- score = (length >= @min_length && length <= @max_length) ? 1 : 0
132
+ score = length >= @min_length && length <= @max_length ? 1 : 0
133
133
  comment = score == 1 ? "Length #{length} within range" : "Length #{length} outside range #{@min_length}-#{@max_length}"
134
134
  elsif @min_length
135
135
  score = length >= @min_length ? 1 : 0
@@ -151,7 +151,7 @@ module Langfuse
151
151
  end
152
152
 
153
153
  class RegexEvaluator < BaseEvaluator
154
- def initialize(name: 'regex', description: 'Regex evaluator', pattern:)
154
+ def initialize(pattern:, name: 'regex', description: 'Regex evaluator')
155
155
  super(name: name, description: description)
156
156
  @pattern = pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern)
157
157
  end
@@ -205,11 +205,11 @@ module Langfuse
205
205
 
206
206
  (1..str1.length).each do |i|
207
207
  (1..str2.length).each do |j|
208
- cost = str1[i-1] == str2[j-1] ? 0 : 1
208
+ cost = str1[i - 1] == str2[j - 1] ? 0 : 1
209
209
  matrix[i][j] = [
210
- matrix[i-1][j] + 1, # deletion
211
- matrix[i][j-1] + 1, # insertion
212
- matrix[i-1][j-1] + cost # substitution
210
+ matrix[i - 1][j] + 1, # deletion
211
+ matrix[i][j - 1] + 1, # insertion
212
+ matrix[i - 1][j - 1] + cost # substitution
213
213
  ].min
214
214
  end
215
215
  end
@@ -219,7 +219,8 @@ module Langfuse
219
219
  end
220
220
 
221
221
  class LLMEvaluator < BaseEvaluator
222
- def initialize(name: 'llm_evaluator', description: 'LLM-based evaluator', client:, model: 'gpt-3.5-turbo', prompt_template: nil)
222
+ def initialize(client:, name: 'llm_evaluator', description: 'LLM-based evaluator', model: 'gpt-3.5-turbo',
223
+ prompt_template: nil)
223
224
  super(name: name, description: description)
224
225
  @client = client
225
226
  @model = model
@@ -61,7 +61,7 @@ module Langfuse
61
61
  def text_to_langchain_prompt
62
62
  # Convert text prompt to LangChain PromptTemplate format
63
63
  {
64
- _type: "prompt",
64
+ _type: 'prompt',
65
65
  input_variables: extract_variables(@prompt),
66
66
  template: @prompt
67
67
  }
@@ -78,7 +78,7 @@ module Langfuse
78
78
  end
79
79
 
80
80
  {
81
- _type: "chat",
81
+ _type: 'chat',
82
82
  messages: messages,
83
83
  input_variables: messages.flat_map { |m| m[:input_variables] }.uniq
84
84
  }
@@ -1,3 +1,3 @@
1
1
  module Langfuse
2
- VERSION = "0.1.0"
2
+ VERSION = '0.1.1'
3
3
  end
data/lib/langfuse.rb CHANGED
@@ -1,13 +1,16 @@
1
- require_relative "langfuse/version"
2
- require_relative "langfuse/client"
3
- require_relative "langfuse/trace"
4
- require_relative "langfuse/span"
5
- require_relative "langfuse/generation"
6
- require_relative "langfuse/prompt"
7
- require_relative "langfuse/evaluation"
8
- require_relative "langfuse/errors"
9
- require_relative "langfuse/utils"
1
+ # frozen_string_literal: true
10
2
 
3
+ require_relative 'langfuse/version'
4
+ require_relative 'langfuse/client'
5
+ require_relative 'langfuse/trace'
6
+ require_relative 'langfuse/span'
7
+ require_relative 'langfuse/generation'
8
+ require_relative 'langfuse/prompt'
9
+ require_relative 'langfuse/evaluation'
10
+ require_relative 'langfuse/errors'
11
+ require_relative 'langfuse/utils'
12
+
13
+ # Ruby SDK for Langfuse - Open source LLM engineering platform
11
14
  module Langfuse
12
15
  class << self
13
16
  # Configure the Langfuse client with default settings
@@ -25,13 +28,14 @@ module Langfuse
25
28
  end
26
29
  end
27
30
 
31
+ # Configuration class for Langfuse client settings
28
32
  class Configuration
29
33
  attr_accessor :public_key, :secret_key, :host, :debug, :timeout, :retries
30
34
 
31
35
  def initialize
32
36
  @public_key = nil
33
37
  @secret_key = nil
34
- @host = "https://cloud.langfuse.com"
38
+ @host = 'https://cloud.langfuse.com'
35
39
  @debug = false
36
40
  @timeout = 30
37
41
  @retries = 3
data/scripts/release.sh CHANGED
@@ -116,5 +116,5 @@ echo " 3. Announce the release"
116
116
  echo
117
117
  echo "🔗 Useful links:"
118
118
  echo " - RubyGems: https://rubygems.org/gems/langfuse"
119
- echo " - GitHub: https://github.com/your-username/langfuse-ruby"
120
- echo " - Documentation: https://github.com/your-username/langfuse-ruby#readme"
119
+ echo " - GitHub: https://github.com/ai-firstly/langfuse-ruby"
120
+ echo " - Documentation: https://github.com/ai-firstly/langfuse-ruby#readme"
@@ -135,5 +135,5 @@ end
135
135
 
136
136
  puts "\n🔗 Useful links:"
137
137
  puts ' - RubyGems page: https://rubygems.org/gems/langfuse'
138
- puts ' - Documentation: https://github.com/your-username/langfuse-ruby'
139
- puts ' - Issues: https://github.com/your-username/langfuse-ruby/issues'
138
+ puts ' - Documentation: https://github.com/ai-firstly/langfuse-ruby'
139
+ puts ' - Issues: https://github.com/ai-firstly/langfuse-ruby/issues'
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: langfuse-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
- - Your Name
7
+ - Richard Sun
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
@@ -167,7 +167,7 @@ dependencies:
167
167
  description: Ruby client library for Langfuse, providing tracing, prompt management,
168
168
  and evaluation capabilities for LLM applications
169
169
  email:
170
- - your.email@example.com
170
+ - richard.sun@ai-firstly.com
171
171
  executables: []
172
172
  extensions: []
173
173
  extra_rdoc_files: []
@@ -175,16 +175,18 @@ files:
175
175
  - ".github/workflows/ci.yml"
176
176
  - ".github/workflows/release.yml"
177
177
  - ".gitignore"
178
- - CHANGELOG.md
179
- - FINAL_SUMMARY.md
180
178
  - Gemfile
181
179
  - Gemfile.lock
182
180
  - LICENSE
183
- - PROJECT_SUMMARY.md
184
- - PUBLISH_GUIDE.md
181
+ - PROMPT_TROUBLESHOOTING.md
185
182
  - README.md
186
- - RELEASE_CHECKLIST.md
187
183
  - Rakefile
184
+ - docs/CHANGELOG.md
185
+ - docs/FINAL_SUMMARY.md
186
+ - docs/PROJECT_SUMMARY.md
187
+ - docs/PUBLISH_GUIDE.md
188
+ - docs/README.md
189
+ - docs/RELEASE_CHECKLIST.md
188
190
  - examples/basic_tracing.rb
189
191
  - examples/prompt_management.rb
190
192
  - langfuse-ruby.gemspec
@@ -202,14 +204,16 @@ files:
202
204
  - scripts/verify_release.rb
203
205
  - test_basic.rb
204
206
  - test_offline.rb
205
- homepage: https://github.com/your-username/langfuse-ruby
207
+ homepage: https://langfuse.com
206
208
  licenses:
207
209
  - MIT
208
210
  metadata:
209
211
  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
212
+ homepage_uri: https://langfuse.com/docs/sdk/ruby
213
+ source_code_uri: https://github.com/ai-firstly/langfuse-ruby
214
+ changelog_uri: https://github.com/ai-firstly/langfuse-ruby/blob/main/CHANGELOG.md
215
+ documentation_uri: https://rubydoc.info/gems/langfuse-ruby
216
+ bug_tracker_uri: https://github.com/ai-firstly/langfuse-ruby/issues
213
217
  post_install_message:
214
218
  rdoc_options: []
215
219
  require_paths:
File without changes
File without changes