langfuse-ruby 0.1.1 → 0.1.2

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: d97c16de061cdf52403a05086a90aaac149b9fe9dc6d771e36709e763abcb3eb
4
- data.tar.gz: c254257501aff83671377cc50ea8f25c143d8dca6fa0f40d157fcfa6eb3d75b9
3
+ metadata.gz: 0bb8cc1f797c0b240830c5f909665dde61bb8a5540f1db8a04393ae0d741ee44
4
+ data.tar.gz: bc5b9e1dc24e2861ac66955bec4dccd25bbadaf1a3c5f59ddbacd784a50b2180
5
5
  SHA512:
6
- metadata.gz: f2cf7c8a6d72bb5a81b73ba6a5a110e9e6312b09e9a790a14d566a41b1e7d4a8ce40c53fb8d0d74b4c12c9cd06bd20e03680b6829505f69aa7b80dee3ecf6750
7
- data.tar.gz: c880f859cf2f0d6fc9586ceada7c7488ff25a8be4c3fbf4740443477e592b8eee20895e24c69c371a8f0a96c60fd40d1a66de2126b762378ea41115665de3666
6
+ metadata.gz: d5486239447652d3b97eb6200bc2f24ee829bef24da86409747f6a250fcc1126ce68841673b0e67da56a75e08ff4ec1bc9edf4b241c3431b855abdf2befdd7b9
7
+ data.tar.gz: 88b61075d0a394629dec59bbec509a7f4c80b0269a887dcef866b3a8a250fd75b362fe84fc6247e72b5305935702a7175c1db825461bb05270145912d6e8f79e
data/CHANGELOG.md ADDED
@@ -0,0 +1,44 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.1] - 2025-01-12
9
+
10
+ ### Fixed
11
+ - Improved error handling for `get_prompt` method when prompt doesn't exist
12
+ - Better error messages for 404 responses that return HTML instead of JSON
13
+ - Enhanced debugging capabilities with detailed request/response logging
14
+
15
+ ### Added
16
+ - Comprehensive troubleshooting guide for prompt management issues
17
+ - Better detection of HTML responses vs JSON responses
18
+ - More specific error types for different failure scenarios
19
+
20
+ ### Changed
21
+ - Updated gemspec metadata to avoid RubyGems warnings
22
+ - Improved documentation with clearer error handling examples
23
+
24
+ ## [0.1.0] - 2025-01-12
25
+
26
+ ### Added
27
+ - Initial release of Langfuse Ruby SDK
28
+ - Complete tracing capabilities with traces, spans, and generations
29
+ - Prompt management with versioning and caching
30
+ - Built-in evaluators (exact match, similarity, length, contains, regex)
31
+ - Custom scoring and evaluation pipeline support
32
+ - Async event processing with automatic batching
33
+ - Comprehensive error handling and validation
34
+ - Framework integration examples (Rails, Sidekiq)
35
+ - Full test suite with RSpec
36
+ - Documentation and examples
37
+
38
+ ### Features
39
+ - **Tracing**: Full observability for LLM applications
40
+ - **Prompt Management**: Version control and deployment of prompts
41
+ - **Evaluation**: Multiple built-in evaluators and custom scoring
42
+ - **Async Processing**: Background event processing with batching
43
+ - **Type Safety**: Comprehensive error handling
44
+ - **Integration**: Easy integration with Ruby frameworks
data/Gemfile CHANGED
@@ -1,9 +1,9 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in langfuse.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake", "~> 13.0"
7
- gem "rspec", "~> 3.0"
8
- gem "rubocop", "~> 1.21"
9
- gem "yard", "~> 0.9"
6
+ gem 'rake', '~> 13.0'
7
+ gem 'rspec', '~> 3.0'
8
+ gem 'rubocop', '~> 1.21'
9
+ gem 'yard', '~> 0.9'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- langfuse-ruby (0.1.1)
4
+ langfuse-ruby (0.1.2)
5
5
  concurrent-ruby (~> 1.0)
6
6
  faraday (~> 2.0)
7
7
  faraday-net_http (~> 3.0)
@@ -108,10 +108,10 @@ chmod 0600 ~/.gem/credentials
108
108
 
109
109
  ```bash
110
110
  # 构建最新版本
111
- gem build langfuse.gemspec
111
+ gem build langfuse-ruby.gemspec
112
112
 
113
113
  # 发布到 RubyGems
114
- gem push langfuse-ruby-0.1.0.gem
114
+ gem push langfuse-ruby-0.1.x.gem
115
115
  ```
116
116
 
117
117
  ## 📊 发布后验证
data/docs/README.md CHANGED
@@ -7,10 +7,6 @@
7
7
  ### 开发和发布
8
8
  - [📋 发布指南](PUBLISH_GUIDE.md) - 详细的 gem 发布流程
9
9
  - [✅ 发布检查清单](RELEASE_CHECKLIST.md) - 发布前的检查项目
10
- - [📝 变更日志](CHANGELOG.md) - 版本更新记录
11
-
12
- ### 项目概览
13
- - [📊 项目总结](PROJECT_SUMMARY.md) - 项目整体介绍
14
10
  - [🎯 最终总结](FINAL_SUMMARY.md) - 项目完成情况总结
15
11
 
16
12
  ## 🔗 相关链接
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/langfuse'
4
+
5
+ puts '🚀 Langfuse Ruby SDK 连接配置演示'
6
+ puts '=' * 50
7
+
8
+ # 显示默认配置
9
+ puts "\n📋 默认配置信息:"
10
+ puts " 默认主机: #{Langfuse.configuration.host}"
11
+ puts " 默认超时: #{Langfuse.configuration.timeout}秒"
12
+ puts " 默认重试: #{Langfuse.configuration.retries}次"
13
+
14
+ # 方法 1: 使用测试密钥创建客户端(仅用于演示)
15
+ puts "\n📝 方法 1: 直接参数配置"
16
+ puts '代码示例:'
17
+ puts 'client = Langfuse.new('
18
+ puts " public_key: 'pk-lf-your-public-key',"
19
+ puts " secret_key: 'sk-lf-your-secret-key',"
20
+ puts " host: 'https://us.cloud.langfuse.com'"
21
+ puts ')'
22
+
23
+ # 使用测试密钥创建客户端
24
+ test_client = Langfuse.new(
25
+ public_key: 'test-public-key',
26
+ secret_key: 'test-secret-key',
27
+ host: 'https://us.cloud.langfuse.com'
28
+ )
29
+
30
+ puts '✅ 客户端配置成功'
31
+ puts " 主机: #{test_client.host}"
32
+ puts " 超时: #{test_client.timeout}秒"
33
+ puts " 重试: #{test_client.retries}次"
34
+
35
+ # 方法 2: 全局配置
36
+ puts "\n📝 方法 2: 全局配置"
37
+ puts '代码示例:'
38
+ puts 'Langfuse.configure do |config|'
39
+ puts " config.public_key = 'pk-lf-your-public-key'"
40
+ puts " config.secret_key = 'sk-lf-your-secret-key'"
41
+ puts " config.host = 'https://us.cloud.langfuse.com'"
42
+ puts ' config.debug = true'
43
+ puts 'end'
44
+
45
+ Langfuse.configure do |config|
46
+ config.public_key = 'test-public-key'
47
+ config.secret_key = 'test-secret-key'
48
+ config.host = 'https://us.cloud.langfuse.com'
49
+ config.debug = true
50
+ config.timeout = 60
51
+ config.retries = 5
52
+ end
53
+
54
+ global_client = Langfuse.new
55
+ puts '✅ 全局配置成功'
56
+ puts " 主机: #{global_client.host}"
57
+ puts " 调试模式: #{global_client.debug}"
58
+ puts " 超时: #{global_client.timeout}秒"
59
+ puts " 重试: #{global_client.retries}次"
60
+
61
+ # 方法 3: 环境变量配置
62
+ puts "\n📝 方法 3: 环境变量配置"
63
+ puts '设置环境变量:'
64
+ puts "export LANGFUSE_PUBLIC_KEY='pk-lf-your-public-key'"
65
+ puts "export LANGFUSE_SECRET_KEY='sk-lf-your-secret-key'"
66
+ puts "export LANGFUSE_HOST='https://us.cloud.langfuse.com'"
67
+ puts ''
68
+ puts '然后使用:'
69
+ puts 'client = Langfuse.new'
70
+
71
+ if ENV['LANGFUSE_PUBLIC_KEY'] && ENV['LANGFUSE_SECRET_KEY']
72
+ env_client = Langfuse.new
73
+ puts '✅ 环境变量配置成功'
74
+ puts " 主机: #{env_client.host}"
75
+ else
76
+ puts '⚠️ 环境变量未设置,跳过此示例'
77
+ end
78
+
79
+ # 连接配置详情
80
+ puts "\n🔧 连接配置详情:"
81
+ puts '根据 Langfuse 官方文档:'
82
+ puts '1. 认证方式: HTTP Basic Auth'
83
+ puts '2. 用户名: Langfuse Public Key (pk-lf-...)'
84
+ puts '3. 密码: Langfuse Secret Key (sk-lf-...)'
85
+ puts '4. 默认服务器: https://us.cloud.langfuse.com'
86
+ puts '5. 内容类型: application/json'
87
+ puts "6. User-Agent: langfuse-ruby/#{Langfuse::VERSION}"
88
+
89
+ # 创建测试 trace(不发送到服务器)
90
+ puts "\n🧪 创建测试 Trace(离线):"
91
+ begin
92
+ trace = test_client.trace(
93
+ name: 'connection-test',
94
+ user_id: 'demo-user',
95
+ input: { message: '测试连接配置' },
96
+ metadata: { demo: true }
97
+ )
98
+
99
+ puts '✅ Trace 创建成功'
100
+ puts " ID: #{trace.id}"
101
+ puts " 名称: #{trace.name}"
102
+ puts " 用户ID: #{trace.user_id}"
103
+
104
+ # 添加 generation
105
+ generation = trace.generation(
106
+ name: 'demo-generation',
107
+ model: 'gpt-3.5-turbo',
108
+ input: [{ role: 'user', content: 'Hello!' }],
109
+ output: { content: '你好!' },
110
+ usage: { prompt_tokens: 5, completion_tokens: 3, total_tokens: 8 }
111
+ )
112
+
113
+ puts '✅ Generation 创建成功'
114
+ puts " ID: #{generation.id}"
115
+ puts " 模型: #{generation.model}"
116
+ rescue StandardError => e
117
+ puts "❌ 测试失败: #{e.message}"
118
+ end
119
+
120
+ puts "\n📚 使用提示:"
121
+ puts "1. 替换示例中的 'test-public-key' 和 'test-secret-key' 为您的真实 API 密钥"
122
+ puts '2. 确保网络连接正常'
123
+ puts '3. 启用 debug 模式可以查看详细的请求日志'
124
+ puts '4. 调用 client.flush 来发送事件到服务器'
125
+ puts '5. 使用 client.shutdown 来优雅地关闭客户端'
126
+
127
+ puts "\n🎉 连接配置演示完成!"
@@ -9,7 +9,7 @@ client = Langfuse.new(
9
9
  host: ENV['LANGFUSE_HOST'] || 'https://cloud.langfuse.com'
10
10
  )
11
11
 
12
- puts "🚀 Starting prompt management example..."
12
+ puts '🚀 Starting prompt management example...'
13
13
 
14
14
  # Example 1: Create and use text prompts
15
15
  puts "\n📝 Example 1: Create and use text prompts"
@@ -17,9 +17,9 @@ puts "\n📝 Example 1: Create and use text prompts"
17
17
  begin
18
18
  # Create a text prompt
19
19
  text_prompt = client.create_prompt(
20
- name: "greeting-prompt",
21
- prompt: "Hello {{user_name}}! Welcome to {{service_name}}. How can I help you with {{topic}} today?",
22
- labels: ["greeting", "customer-service"],
20
+ name: 'greeting-prompt',
21
+ prompt: 'Hello {{user_name}}! Welcome to {{service_name}}. How can I help you with {{topic}} today?',
22
+ labels: %w[greeting customer-service],
23
23
  config: {
24
24
  temperature: 0.7,
25
25
  max_tokens: 100
@@ -27,24 +27,22 @@ begin
27
27
  )
28
28
 
29
29
  puts "Created text prompt: #{text_prompt.name} (Version: #{text_prompt.version})"
30
-
31
30
  rescue Langfuse::APIError => e
32
31
  puts "Note: Prompt might already exist - #{e.message}"
33
32
  end
34
33
 
35
34
  # Get and use the prompt
36
35
  begin
37
- prompt = client.get_prompt("greeting-prompt")
36
+ prompt = client.get_prompt('greeting-prompt')
38
37
 
39
38
  # Compile prompt with variables
40
39
  compiled_text = prompt.compile(
41
- user_name: "Alice",
42
- service_name: "AI Assistant",
43
- topic: "machine learning"
40
+ user_name: 'Alice',
41
+ service_name: 'AI Assistant',
42
+ topic: 'machine learning'
44
43
  )
45
44
 
46
45
  puts "Compiled prompt: #{compiled_text}"
47
-
48
46
  rescue Langfuse::APIError => e
49
47
  puts "Could not retrieve prompt: #{e.message}"
50
48
  end
@@ -55,18 +53,18 @@ puts "\n💬 Example 2: Create and use chat prompts"
55
53
  begin
56
54
  # Create a chat prompt
57
55
  chat_prompt = client.create_prompt(
58
- name: "ai-assistant-chat",
56
+ name: 'ai-assistant-chat',
59
57
  prompt: [
60
58
  {
61
- role: "system",
62
- content: "You are a helpful AI assistant specialized in {{domain}}. Always be {{tone}} and provide {{detail_level}} answers."
59
+ role: 'system',
60
+ content: 'You are a helpful AI assistant specialized in {{domain}}. Always be {{tone}} and provide {{detail_level}} answers.'
63
61
  },
64
62
  {
65
- role: "user",
66
- content: "{{user_message}}"
63
+ role: 'user',
64
+ content: '{{user_message}}'
67
65
  }
68
66
  ],
69
- labels: ["chat", "assistant", "ai"],
67
+ labels: %w[chat assistant ai],
70
68
  config: {
71
69
  temperature: 0.8,
72
70
  max_tokens: 200
@@ -74,28 +72,26 @@ begin
74
72
  )
75
73
 
76
74
  puts "Created chat prompt: #{chat_prompt.name}"
77
-
78
75
  rescue Langfuse::APIError => e
79
76
  puts "Note: Chat prompt might already exist - #{e.message}"
80
77
  end
81
78
 
82
79
  # Get and use the chat prompt
83
80
  begin
84
- chat_prompt = client.get_prompt("ai-assistant-chat")
81
+ chat_prompt = client.get_prompt('ai-assistant-chat')
85
82
 
86
83
  # Compile chat prompt with variables
87
84
  compiled_messages = chat_prompt.compile(
88
- domain: "software development",
89
- tone: "friendly and professional",
90
- detail_level: "detailed",
91
- user_message: "How do I implement a REST API in Ruby?"
85
+ domain: 'software development',
86
+ tone: 'friendly and professional',
87
+ detail_level: 'detailed',
88
+ user_message: 'How do I implement a REST API in Ruby?'
92
89
  )
93
90
 
94
- puts "Compiled chat messages:"
91
+ puts 'Compiled chat messages:'
95
92
  compiled_messages.each_with_index do |message, index|
96
93
  puts " #{index + 1}. #{message[:role]}: #{message[:content]}"
97
94
  end
98
-
99
95
  rescue Langfuse::APIError => e
100
96
  puts "Could not retrieve chat prompt: #{e.message}"
101
97
  end
@@ -112,34 +108,34 @@ puts "Template variables: #{translation_template.input_variables}"
112
108
 
113
109
  # Use the template
114
110
  translated_prompt = translation_template.format(
115
- source_language: "English",
116
- target_language: "Spanish",
117
- text: "Hello, how are you today?"
111
+ source_language: 'English',
112
+ target_language: 'Spanish',
113
+ text: 'Hello, how are you today?'
118
114
  )
119
115
 
120
116
  puts "Translation prompt: #{translated_prompt}"
121
117
 
122
118
  # Create a reusable chat template
123
119
  coding_template = Langfuse::ChatPromptTemplate.from_messages([
124
- {
125
- role: "system",
126
- content: "You are an expert {{language}} developer. Provide clean, well-commented code examples."
127
- },
128
- {
129
- role: "user",
130
- content: "{{request}}"
131
- }
132
- ])
120
+ {
121
+ role: 'system',
122
+ content: 'You are an expert {{language}} developer. Provide clean, well-commented code examples.'
123
+ },
124
+ {
125
+ role: 'user',
126
+ content: '{{request}}'
127
+ }
128
+ ])
133
129
 
134
130
  puts "Chat template variables: #{coding_template.input_variables}"
135
131
 
136
132
  # Use the chat template
137
133
  coding_messages = coding_template.format(
138
- language: "Ruby",
139
- request: "Show me how to create a simple HTTP server"
134
+ language: 'Ruby',
135
+ request: 'Show me how to create a simple HTTP server'
140
136
  )
141
137
 
142
- puts "Coding chat messages:"
138
+ puts 'Coding chat messages:'
143
139
  coding_messages.each_with_index do |message, index|
144
140
  puts " #{index + 1}. #{message[:role]}: #{message[:content]}"
145
141
  end
@@ -149,17 +145,16 @@ puts "\n🔄 Example 4: Prompt versioning and caching"
149
145
 
150
146
  # Get specific version of a prompt
151
147
  begin
152
- versioned_prompt = client.get_prompt("greeting-prompt", version: 1)
148
+ versioned_prompt = client.get_prompt('greeting-prompt', version: 1)
153
149
  puts "Retrieved prompt version: #{versioned_prompt.version}"
154
150
 
155
151
  # Get latest version (cached)
156
- latest_prompt = client.get_prompt("greeting-prompt")
152
+ latest_prompt = client.get_prompt('greeting-prompt')
157
153
  puts "Latest prompt version: #{latest_prompt.version}"
158
154
 
159
155
  # Get with label
160
- labeled_prompt = client.get_prompt("greeting-prompt", label: "production")
156
+ labeled_prompt = client.get_prompt('greeting-prompt', label: 'production')
161
157
  puts "Labeled prompt: #{labeled_prompt.labels}"
162
-
163
158
  rescue Langfuse::APIError => e
164
159
  puts "Could not retrieve versioned prompt: #{e.message}"
165
160
  end
@@ -169,27 +164,27 @@ puts "\n🔗 Example 5: Using prompts in tracing"
169
164
 
170
165
  begin
171
166
  # Get a prompt for use in generation
172
- system_prompt = client.get_prompt("ai-assistant-chat")
167
+ system_prompt = client.get_prompt('ai-assistant-chat')
173
168
 
174
169
  # Create a trace
175
170
  trace = client.trace(
176
- name: "prompt-based-chat",
177
- user_id: "user-789",
178
- input: { message: "Explain Ruby blocks" }
171
+ name: 'prompt-based-chat',
172
+ user_id: 'user-789',
173
+ input: { message: 'Explain Ruby blocks' }
179
174
  )
180
175
 
181
176
  # Compile the prompt
182
177
  messages = system_prompt.compile(
183
- domain: "Ruby programming",
184
- tone: "educational and clear",
185
- detail_level: "beginner-friendly",
186
- user_message: "Explain Ruby blocks"
178
+ domain: 'Ruby programming',
179
+ tone: 'educational and clear',
180
+ detail_level: 'beginner-friendly',
181
+ user_message: 'Explain Ruby blocks'
187
182
  )
188
183
 
189
184
  # Create generation with prompt
190
185
  generation = trace.generation(
191
- name: "openai-chat-with-prompt",
192
- model: "gpt-3.5-turbo",
186
+ name: 'openai-chat-with-prompt',
187
+ model: 'gpt-3.5-turbo',
193
188
  input: messages,
194
189
  output: {
195
190
  content: "Ruby blocks are pieces of code that can be passed to methods. They're defined using either do...end or curly braces {}. Blocks are commonly used with iterators like .each, .map, and .select."
@@ -207,7 +202,6 @@ begin
207
202
 
208
203
  puts "Created generation with prompt: #{generation.id}"
209
204
  puts "Trace URL: #{trace.get_url}"
210
-
211
205
  rescue Langfuse::APIError => e
212
206
  puts "Could not use prompt in tracing: #{e.message}"
213
207
  end
@@ -218,12 +212,12 @@ puts "\n🎯 Example 6: Advanced prompt features"
218
212
  # Create a prompt with complex templating
219
213
  begin
220
214
  complex_prompt = client.create_prompt(
221
- name: "code-review-prompt",
215
+ name: 'code-review-prompt',
222
216
  prompt: {
223
- system: "You are a senior {{language}} developer reviewing code. Focus on {{review_aspects}}.",
217
+ system: 'You are a senior {{language}} developer reviewing code. Focus on {{review_aspects}}.',
224
218
  user: "Please review this {{language}} code:\n\n```{{language}}\n{{code}}\n```\n\nProvide feedback on: {{specific_feedback}}"
225
219
  },
226
- labels: ["code-review", "development"],
220
+ labels: %w[code-review development],
227
221
  config: {
228
222
  temperature: 0.3,
229
223
  max_tokens: 500
@@ -231,7 +225,6 @@ begin
231
225
  )
232
226
 
233
227
  puts "Created complex prompt: #{complex_prompt.name}"
234
-
235
228
  rescue Langfuse::APIError => e
236
229
  puts "Note: Complex prompt might already exist - #{e.message}"
237
230
  end
@@ -239,16 +232,14 @@ end
239
232
  # Create a prompt with conditional logic (using Ruby)
240
233
  class ConditionalPrompt
241
234
  def self.generate(user_level:, topic:, include_examples: true)
242
- base_prompt = "Explain {{topic}} for a {{user_level}} audience."
235
+ base_prompt = 'Explain {{topic}} for a {{user_level}} audience.'
243
236
 
244
- if include_examples
245
- base_prompt += " Include practical examples."
246
- end
237
+ base_prompt += ' Include practical examples.' if include_examples
247
238
 
248
- if user_level == "beginner"
249
- base_prompt += " Use simple language and avoid jargon."
250
- elsif user_level == "advanced"
251
- base_prompt += " Feel free to use technical terminology."
239
+ if user_level == 'beginner'
240
+ base_prompt += ' Use simple language and avoid jargon.'
241
+ elsif user_level == 'advanced'
242
+ base_prompt += ' Feel free to use technical terminology.'
252
243
  end
253
244
 
254
245
  base_prompt
@@ -256,8 +247,8 @@ class ConditionalPrompt
256
247
  end
257
248
 
258
249
  conditional_prompt_text = ConditionalPrompt.generate(
259
- user_level: "beginner",
260
- topic: "machine learning",
250
+ user_level: 'beginner',
251
+ topic: 'machine learning',
261
252
  include_examples: true
262
253
  )
263
254
 
@@ -266,8 +257,8 @@ puts "Conditional prompt: #{conditional_prompt_text}"
266
257
  # Use with template
267
258
  conditional_template = Langfuse::PromptTemplate.from_template(conditional_prompt_text)
268
259
  formatted_prompt = conditional_template.format(
269
- topic: "neural networks",
270
- user_level: "beginner"
260
+ topic: 'neural networks',
261
+ user_level: 'beginner'
271
262
  )
272
263
 
273
264
  puts "Formatted conditional prompt: #{formatted_prompt}"
@@ -277,7 +268,7 @@ puts "\n🔄 Flushing events..."
277
268
  client.flush
278
269
 
279
270
  puts "\n✅ Prompt management example completed!"
280
- puts "Check your Langfuse dashboard to see the prompts and traces."
271
+ puts 'Check your Langfuse dashboard to see the prompts and traces.'
281
272
 
282
273
  # Shutdown client
283
274
  client.shutdown
@@ -99,7 +99,7 @@ module Langfuse
99
99
  return cached_prompt[:prompt]
100
100
  end
101
101
 
102
- path = "/api/public/prompts/#{name}"
102
+ path = "/api/public/v2/prompts/#{name}"
103
103
  params = {}
104
104
  params[:version] = version if version
105
105
  params[:label] = label if label
@@ -138,7 +138,7 @@ module Langfuse
138
138
  **kwargs
139
139
  }
140
140
 
141
- response = post('/api/public/prompts', data)
141
+ response = post('/api/public/v2/prompts', data)
142
142
  Prompt.new(response.body)
143
143
  end
144
144
 
@@ -227,15 +227,24 @@ module Langfuse
227
227
 
228
228
  def build_connection
229
229
  Faraday.new(url: @host) do |conn|
230
- conn.request :authorization, :basic, @public_key, @secret_key
230
+ # 配置请求和响应处理
231
231
  conn.request :json
232
- # 更宽松的 JSON 响应处理,支持更多 content-type
233
232
  conn.response :json, content_type: /\bjson$/
234
- conn.adapter Faraday.default_adapter
233
+
234
+ # 设置 User-Agent 头部
235
+ conn.headers['User-Agent'] = "langfuse-ruby/#{Langfuse::VERSION}"
236
+ # 根据 Langfuse 文档配置 Basic Auth
237
+ # username: Langfuse Public Key, password: Langfuse Secret Key
238
+ conn.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{@public_key}:#{@secret_key}")}"
239
+
240
+ # 设置超时
235
241
  conn.options.timeout = @timeout
236
242
 
237
- # 添加响应中间件来处理错误响应
243
+ # 添加调试日志
238
244
  conn.response :logger if @debug
245
+
246
+ # 使用默认适配器
247
+ conn.adapter Faraday.default_adapter
239
248
  end
240
249
  end
241
250
 
@@ -1,3 +1,3 @@
1
1
  module Langfuse
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
3
  end
data/lib/langfuse.rb CHANGED
@@ -35,7 +35,7 @@ module Langfuse
35
35
  def initialize
36
36
  @public_key = nil
37
37
  @secret_key = nil
38
- @host = 'https://cloud.langfuse.com'
38
+ @host = 'https://us.cloud.langfuse.com'
39
39
  @debug = false
40
40
  @timeout = 30
41
41
  @retries = 3
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: langfuse-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Sun
@@ -175,19 +175,18 @@ files:
175
175
  - ".github/workflows/ci.yml"
176
176
  - ".github/workflows/release.yml"
177
177
  - ".gitignore"
178
+ - CHANGELOG.md
178
179
  - Gemfile
179
180
  - Gemfile.lock
180
181
  - LICENSE
181
- - PROMPT_TROUBLESHOOTING.md
182
182
  - README.md
183
183
  - Rakefile
184
- - docs/CHANGELOG.md
185
184
  - docs/FINAL_SUMMARY.md
186
- - docs/PROJECT_SUMMARY.md
187
185
  - docs/PUBLISH_GUIDE.md
188
186
  - docs/README.md
189
187
  - docs/RELEASE_CHECKLIST.md
190
188
  - examples/basic_tracing.rb
189
+ - examples/connection_config_demo.rb
191
190
  - examples/prompt_management.rb
192
191
  - langfuse-ruby.gemspec
193
192
  - lib/langfuse.rb
@@ -202,7 +201,6 @@ files:
202
201
  - lib/langfuse/version.rb
203
202
  - scripts/release.sh
204
203
  - scripts/verify_release.rb
205
- - test_basic.rb
206
204
  - test_offline.rb
207
205
  homepage: https://langfuse.com
208
206
  licenses:
@@ -1,206 +0,0 @@
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/docs/CHANGELOG.md DELETED
@@ -1,49 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [Unreleased]
9
-
10
- ## [0.1.0] - 2025-01-09
11
-
12
- ### Added
13
- - Initial release of Langfuse Ruby SDK
14
- - Complete tracing functionality with traces, spans, and generations
15
- - Prompt management with version control and caching
16
- - Built-in evaluation system with multiple evaluators
17
- - Comprehensive error handling and validation
18
- - Automatic event batching and background processing
19
- - Support for environment variable configuration
20
- - Extensive documentation and examples
21
- - Full test coverage with RSpec
22
- - Framework integration examples (Rails, Sidekiq)
23
-
24
- ### Features
25
- - **Tracing**: Create and manage traces with nested spans and generations
26
- - **Prompt Management**: Create, retrieve, and compile prompts with variable substitution
27
- - **Evaluation**: Built-in evaluators for exact match, similarity, length, regex, and custom scoring
28
- - **Client Management**: Robust HTTP client with retries, timeouts, and authentication
29
- - **Event Processing**: Asynchronous event queue with automatic flushing
30
- - **Error Handling**: Comprehensive error types with detailed messages
31
- - **Utilities**: Helper methods for ID generation, timestamps, and data transformation
32
-
33
- ### Dependencies
34
- - faraday (~> 2.0) - HTTP client library
35
- - faraday-net_http (~> 3.0) - Net::HTTP adapter for Faraday
36
- - json (~> 2.0) - JSON parsing and generation
37
- - concurrent-ruby (~> 1.0) - Thread-safe data structures
38
-
39
- ### Development Dependencies
40
- - bundler (~> 2.0)
41
- - rake (~> 13.0)
42
- - rspec (~> 3.0)
43
- - webmock (~> 3.0)
44
- - vcr (~> 6.0)
45
- - rubocop (~> 1.0)
46
- - yard (~> 0.9)
47
-
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
@@ -1,263 +0,0 @@
1
- # Langfuse Ruby SDK - 项目总结
2
-
3
- ## 🎉 项目完成状态
4
-
5
- ✅ **项目已完成** - 所有核心功能已实现并通过测试
6
-
7
- ## 📋 功能清单
8
-
9
- ### ✅ 已实现的功能
10
-
11
- 1. **核心架构**
12
- - [x] 模块化设计
13
- - [x] 完整的错误处理系统
14
- - [x] 配置管理
15
- - [x] 工具类和辅助方法
16
-
17
- 2. **客户端管理**
18
- - [x] HTTP 客户端(基于 Faraday)
19
- - [x] 认证系统(Basic Auth)
20
- - [x] 自动重试机制
21
- - [x] 超时处理
22
- - [x] 错误分类和处理
23
-
24
- 3. **追踪功能**
25
- - [x] Trace 创建和管理
26
- - [x] Span 创建和嵌套
27
- - [x] Generation 追踪(LLM 调用)
28
- - [x] 事件队列和批处理
29
- - [x] 后台线程自动刷新
30
-
31
- 4. **提示管理**
32
- - [x] 提示创建和获取
33
- - [x] 版本控制
34
- - [x] 缓存机制
35
- - [x] 变量编译({{variable}} 格式)
36
- - [x] 文本和聊天提示支持
37
- - [x] 提示模板类
38
-
39
- 5. **评估系统**
40
- - [x] 基础评估器框架
41
- - [x] 精确匹配评估器
42
- - [x] 相似度评估器(Levenshtein 距离)
43
- - [x] 长度评估器
44
- - [x] 包含评估器
45
- - [x] 正则表达式评估器
46
- - [x] 自定义评分系统
47
-
48
- 6. **测试和文档**
49
- - [x] 完整的测试套件
50
- - [x] 详细的 README 文档
51
- - [x] 使用示例
52
- - [x] API 文档
53
- - [x] 变更日志
54
-
55
- ## 🏗️ 项目结构
56
-
57
- ```
58
- langfuse/
59
- ├── lib/
60
- │ └── langfuse/
61
- │ ├── client.rb # 核心客户端
62
- │ ├── trace.rb # 追踪功能
63
- │ ├── span.rb # Span 管理
64
- │ ├── generation.rb # Generation 管理
65
- │ ├── prompt.rb # 提示管理
66
- │ ├── evaluation.rb # 评估系统
67
- │ ├── errors.rb # 错误定义
68
- │ ├── utils.rb # 工具类
69
- │ └── version.rb # 版本信息
70
- ├── spec/ # 测试文件
71
- ├── examples/ # 使用示例
72
- ├── langfuse.gemspec # Gem 规范
73
- ├── README.md # 项目文档
74
- ├── CHANGELOG.md # 变更日志
75
- └── LICENSE # 许可证
76
- ```
77
-
78
- ## 🔧 技术栈
79
-
80
- - **Ruby**: >= 2.7.0
81
- - **HTTP 客户端**: Faraday 2.0+
82
- - **并发处理**: concurrent-ruby 1.0+
83
- - **JSON 处理**: json 2.0+
84
- - **测试框架**: RSpec 3.0+
85
- - **代码质量**: RuboCop 1.0+
86
-
87
- ## 🚀 核心特性
88
-
89
- ### 1. 追踪系统
90
- - 支持嵌套的 traces、spans 和 generations
91
- - 自动 ID 生成和时间戳
92
- - 元数据和标签支持
93
- - 异步事件处理
94
-
95
- ### 2. 提示管理
96
- - 版本控制和缓存
97
- - 变量替换系统
98
- - 多种提示格式支持
99
- - LangChain 兼容性
100
-
101
- ### 3. 评估框架
102
- - 多种内置评估器
103
- - 可扩展的评估系统
104
- - 自定义评分支持
105
- - 详细的评估结果
106
-
107
- ### 4. 企业级特性
108
- - 完整的错误处理
109
- - 配置管理
110
- - 环境变量支持
111
- - 框架集成示例
112
-
113
- ## 📊 测试结果
114
-
115
- ```
116
- 🚀 Testing Langfuse Ruby SDK (Offline Mode)...
117
-
118
- ✅ Configuration successful
119
- ✅ Client initialization successful
120
- ✅ Trace creation successful
121
- ✅ Generation creation successful
122
- ✅ Prompt template successful
123
- ✅ Chat prompt template successful
124
- ✅ Evaluators successful (5/5)
125
- ✅ Utils successful
126
- ✅ Event queue successful
127
- ✅ Complex workflow successful
128
- ✅ Error handling successful
129
-
130
- 🎉 All offline tests completed successfully!
131
- ```
132
-
133
- ## 📚 使用示例
134
-
135
- ### 基本用法
136
- ```ruby
137
- require 'langfuse'
138
-
139
- client = Langfuse.new(
140
- public_key: "pk-lf-...",
141
- secret_key: "sk-lf-..."
142
- )
143
-
144
- trace = client.trace(
145
- name: "chat-completion",
146
- user_id: "user123",
147
- input: { message: "Hello!" }
148
- )
149
-
150
- generation = trace.generation(
151
- name: "openai-chat",
152
- model: "gpt-3.5-turbo",
153
- input: [{ role: "user", content: "Hello!" }],
154
- output: { content: "Hi there!" }
155
- )
156
-
157
- client.flush
158
- ```
159
-
160
- ### 提示管理
161
- ```ruby
162
- # 获取提示
163
- prompt = client.get_prompt("greeting-prompt")
164
-
165
- # 编译提示
166
- compiled = prompt.compile(
167
- user_name: "Alice",
168
- topic: "AI"
169
- )
170
- ```
171
-
172
- ### 评估系统
173
- ```ruby
174
- evaluator = Langfuse::Evaluators::ExactMatchEvaluator.new
175
- result = evaluator.evaluate(
176
- "What is 2+2?",
177
- "4",
178
- expected: "4"
179
- )
180
- ```
181
-
182
- ## 🔄 与官方 SDK 对比
183
-
184
- | 功能 | Python SDK | JS SDK | Ruby SDK |
185
- |------|------------|--------|----------|
186
- | 基础追踪 | ✅ | ✅ | ✅ |
187
- | 提示管理 | ✅ | ✅ | ✅ |
188
- | 评估系统 | ✅ | ✅ | ✅ |
189
- | 异步处理 | ✅ | ✅ | ✅ |
190
- | 错误处理 | ✅ | ✅ | ✅ |
191
- | 框架集成 | ✅ | ✅ | ✅ |
192
-
193
- ## 📦 发布准备
194
-
195
- ### Gem 规范
196
- - 名称: `langfuse`
197
- - 版本: `0.1.0`
198
- - 许可证: MIT
199
- - Ruby 版本: >= 2.7.0
200
-
201
- ### 依赖项
202
- ```ruby
203
- spec.add_dependency "faraday", "~> 2.0"
204
- spec.add_dependency "faraday-net_http", "~> 3.0"
205
- spec.add_dependency "json", "~> 2.0"
206
- spec.add_dependency "concurrent-ruby", "~> 1.0"
207
- ```
208
-
209
- ## 🛠️ 开发指南
210
-
211
- ### 安装依赖
212
- ```bash
213
- bundle install
214
- ```
215
-
216
- ### 运行测试
217
- ```bash
218
- bundle exec rspec
219
- ```
220
-
221
- ### 离线测试
222
- ```bash
223
- ruby test_offline.rb
224
- ```
225
-
226
- ## 🔮 未来扩展
227
-
228
- ### 可能的改进
229
- 1. **性能优化**
230
- - 连接池管理
231
- - 更高效的批处理
232
- - 内存优化
233
-
234
- 2. **功能扩展**
235
- - 更多评估器
236
- - 数据集管理
237
- - 实验功能
238
-
239
- 3. **集成支持**
240
- - Rails 集成 gem
241
- - Sidekiq 中间件
242
- - 更多框架支持
243
-
244
- ## 📄 许可证
245
-
246
- MIT License - 允许商业和开源使用
247
-
248
- ## 🤝 贡献指南
249
-
250
- 1. Fork 项目
251
- 2. 创建功能分支
252
- 3. 提交更改
253
- 4. 创建 Pull Request
254
-
255
- ## 📞 支持
256
-
257
- - GitHub Issues: 报告 bug 和功能请求
258
- - 文档: 详细的使用指南
259
- - 示例: 完整的使用示例
260
-
261
- ---
262
-
263
- **总结**: 这个 Langfuse Ruby SDK 是一个功能完整、测试充分的生产级 SDK,完全兼容 Langfuse API,可以立即用于生产环境。它提供了与官方 Python 和 JavaScript SDK 相同的功能,并且遵循 Ruby 社区的最佳实践。
data/test_basic.rb DELETED
@@ -1,183 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative 'lib/langfuse'
4
-
5
- puts "🚀 Testing Langfuse Ruby SDK..."
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 = true
14
- end
15
-
16
- puts "✅ Configuration successful"
17
- puts " Public key: #{Langfuse.configuration.public_key}"
18
- puts " Host: #{Langfuse.configuration.host}"
19
-
20
- # Test 2: Client initialization
21
- puts "\n2. Testing client initialization..."
22
- begin
23
- client = Langfuse.new(
24
- public_key: "test_key",
25
- secret_key: "test_secret",
26
- host: "https://test.langfuse.com"
27
- )
28
- puts "✅ Client initialization successful"
29
- puts " Client class: #{client.class}"
30
- puts " Public key: #{client.public_key}"
31
- rescue => e
32
- puts "❌ Client initialization failed: #{e.message}"
33
- end
34
-
35
- # Test 3: Trace creation
36
- puts "\n3. Testing trace creation..."
37
- begin
38
- trace = client.trace(
39
- name: "test-trace",
40
- user_id: "test-user",
41
- input: { message: "Hello, world!" }
42
- )
43
- puts "✅ Trace creation successful"
44
- puts " Trace ID: #{trace.id}"
45
- puts " Trace name: #{trace.name}"
46
- rescue => e
47
- puts "❌ Trace creation failed: #{e.message}"
48
- end
49
-
50
- # Test 4: Generation creation
51
- puts "\n4. Testing generation creation..."
52
- begin
53
- generation = trace.generation(
54
- name: "test-generation",
55
- model: "gpt-3.5-turbo",
56
- input: [{ role: "user", content: "Hello!" }],
57
- output: { content: "Hi there!" }
58
- )
59
- puts "✅ Generation creation successful"
60
- puts " Generation ID: #{generation.id}"
61
- puts " Model: #{generation.model}"
62
- rescue => e
63
- puts "❌ Generation creation failed: #{e.message}"
64
- end
65
-
66
- # Test 5: Span creation
67
- puts "\n5. Testing span creation..."
68
- begin
69
- span = trace.span(
70
- name: "test-span",
71
- input: { query: "test query" }
72
- )
73
- puts "✅ Span creation successful"
74
- puts " Span ID: #{span.id}"
75
- puts " Span name: #{span.name}"
76
- rescue => e
77
- puts "❌ Span creation failed: #{e.message}"
78
- end
79
-
80
- # Test 6: Prompt template
81
- puts "\n6. Testing prompt template..."
82
- begin
83
- template = Langfuse::PromptTemplate.from_template(
84
- "Hello {{name}}! How are you feeling {{mood}} today?"
85
- )
86
-
87
- formatted = template.format(
88
- name: "Alice",
89
- mood: "happy"
90
- )
91
-
92
- puts "✅ Prompt template successful"
93
- puts " Template variables: #{template.input_variables}"
94
- puts " Formatted: #{formatted}"
95
- rescue => e
96
- puts "❌ Prompt template failed: #{e.message}"
97
- end
98
-
99
- # Test 7: Chat prompt template
100
- puts "\n7. Testing chat prompt template..."
101
- begin
102
- chat_template = Langfuse::ChatPromptTemplate.from_messages([
103
- { role: "system", content: "You are a helpful {{role}} assistant." },
104
- { role: "user", content: "{{user_input}}" }
105
- ])
106
-
107
- messages = chat_template.format(
108
- role: "coding",
109
- user_input: "Help me with Ruby"
110
- )
111
-
112
- puts "✅ Chat prompt template successful"
113
- puts " Template variables: #{chat_template.input_variables}"
114
- puts " Messages count: #{messages.length}"
115
- rescue => e
116
- puts "❌ Chat prompt template failed: #{e.message}"
117
- end
118
-
119
- # Test 8: Evaluators
120
- puts "\n8. Testing evaluators..."
121
- begin
122
- # Exact match evaluator
123
- exact_match = Langfuse::Evaluators::ExactMatchEvaluator.new
124
- result = exact_match.evaluate(
125
- input: "What is 2+2?",
126
- output: "4",
127
- expected: "4"
128
- )
129
- puts "✅ Exact match evaluator successful"
130
- puts " Result: #{result}"
131
-
132
- # Similarity evaluator
133
- similarity = Langfuse::Evaluators::SimilarityEvaluator.new
134
- result = similarity.evaluate(
135
- input: "What is AI?",
136
- output: "Artificial Intelligence",
137
- expected: "AI is artificial intelligence"
138
- )
139
- puts "✅ Similarity evaluator successful"
140
- puts " Result: #{result}"
141
- rescue => e
142
- puts "❌ Evaluator failed: #{e.message}"
143
- end
144
-
145
- # Test 9: Utils
146
- puts "\n9. Testing utilities..."
147
- begin
148
- id = Langfuse::Utils.generate_id
149
- timestamp = Langfuse::Utils.current_timestamp
150
-
151
- puts "✅ Utils successful"
152
- puts " Generated ID: #{id}"
153
- puts " Timestamp: #{timestamp}"
154
- rescue => e
155
- puts "❌ Utils failed: #{e.message}"
156
- end
157
-
158
- # Test 10: Event queue
159
- puts "\n10. Testing event queue..."
160
- begin
161
- queue_size_before = client.instance_variable_get(:@event_queue).length
162
-
163
- client.score(
164
- trace_id: trace.id,
165
- name: "test-score",
166
- value: 0.9
167
- )
168
-
169
- queue_size_after = client.instance_variable_get(:@event_queue).length
170
-
171
- puts "✅ Event queue successful"
172
- puts " Queue size before: #{queue_size_before}"
173
- puts " Queue size after: #{queue_size_after}"
174
- rescue => e
175
- puts "❌ Event queue failed: #{e.message}"
176
- end
177
-
178
- puts "\n🎉 All tests completed!"
179
- puts " This SDK is ready for use with Langfuse!"
180
- puts " Remember to set your real API keys when using in production."
181
-
182
- # Clean shutdown
183
- client.shutdown