lf-cli 1.0.0 → 1.0.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 +4 -4
- data/CHANGELOG.md +38 -9
- data/README.md +197 -19
- data/lib/langfuse/cli/client.rb +20 -3
- data/lib/langfuse/cli/commands/config.rb +20 -10
- data/lib/langfuse/cli/commands/metrics.rb +23 -18
- data/lib/langfuse/cli/commands/observations.rb +26 -23
- data/lib/langfuse/cli/commands/scores.rb +23 -20
- data/lib/langfuse/cli/commands/sessions.rb +23 -20
- data/lib/langfuse/cli/commands/traces.rb +36 -28
- data/lib/langfuse/cli/config.rb +75 -23
- data/lib/langfuse/cli/formatters/csv_formatter.rb +1 -0
- data/lib/langfuse/cli/formatters/table_formatter.rb +22 -6
- data/lib/langfuse/cli/types.rb +0 -1
- data/lib/langfuse/cli/version.rb +1 -1
- data/lib/langfuse/cli.rb +17 -12
- metadata +3 -4
- data/lib/langfuse/cli/formatters/markdown_formatter.rb +0 -56
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
require 'terminal-table'
|
|
2
|
+
require 'date'
|
|
3
|
+
require 'sorbet-runtime'
|
|
2
4
|
|
|
3
5
|
module Langfuse
|
|
4
6
|
module CLI
|
|
5
7
|
module Formatters
|
|
6
8
|
class TableFormatter
|
|
7
|
-
|
|
9
|
+
extend T::Sig
|
|
10
|
+
|
|
11
|
+
DEFAULT_MAX_CELL_BYTES = 2048
|
|
12
|
+
|
|
13
|
+
sig { params(data: T.untyped, max_cell_bytes: Integer).returns(String) }
|
|
14
|
+
def self.format(data, max_cell_bytes: DEFAULT_MAX_CELL_BYTES)
|
|
8
15
|
return "No data to display" if data.nil? || (data.is_a?(Array) && data.empty?)
|
|
9
16
|
|
|
10
17
|
# Convert single hash to array for consistent handling
|
|
@@ -15,7 +22,7 @@ module Langfuse
|
|
|
15
22
|
|
|
16
23
|
# Build rows
|
|
17
24
|
rows = data.map do |row|
|
|
18
|
-
headers.map { |header| format_value(row[header]) }
|
|
25
|
+
headers.map { |header| format_value(row[header], max_cell_bytes: max_cell_bytes) }
|
|
19
26
|
end
|
|
20
27
|
|
|
21
28
|
# Create table
|
|
@@ -25,18 +32,27 @@ module Langfuse
|
|
|
25
32
|
|
|
26
33
|
private
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
sig { params(value: T.untyped, max_cell_bytes: Integer).returns(String) }
|
|
36
|
+
def self.format_value(value, max_cell_bytes:)
|
|
29
37
|
case value
|
|
30
38
|
when nil
|
|
31
39
|
''
|
|
32
40
|
when Hash, Array
|
|
33
|
-
value.to_json
|
|
41
|
+
truncate(value.to_json, max_cell_bytes)
|
|
34
42
|
when Time, DateTime
|
|
35
|
-
value.iso8601
|
|
43
|
+
truncate(value.iso8601, max_cell_bytes)
|
|
36
44
|
else
|
|
37
|
-
value.to_s
|
|
45
|
+
truncate(value.to_s, max_cell_bytes)
|
|
38
46
|
end
|
|
39
47
|
end
|
|
48
|
+
|
|
49
|
+
sig { params(value: String, max_cell_bytes: Integer).returns(String) }
|
|
50
|
+
def self.truncate(value, max_cell_bytes)
|
|
51
|
+
return value if value.bytesize <= max_cell_bytes
|
|
52
|
+
|
|
53
|
+
visible = value.byteslice(0, max_cell_bytes)
|
|
54
|
+
"#{visible}...[truncated #{value.bytesize - max_cell_bytes} bytes]"
|
|
55
|
+
end
|
|
40
56
|
end
|
|
41
57
|
end
|
|
42
58
|
end
|
data/lib/langfuse/cli/types.rb
CHANGED
data/lib/langfuse/cli/version.rb
CHANGED
data/lib/langfuse/cli.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'thor'
|
|
2
|
+
require 'json'
|
|
2
3
|
require_relative 'cli/version'
|
|
3
4
|
require_relative 'cli/config'
|
|
4
5
|
require_relative 'cli/client'
|
|
@@ -27,8 +28,8 @@ module Langfuse
|
|
|
27
28
|
class_option :format,
|
|
28
29
|
type: :string,
|
|
29
30
|
aliases: '-f',
|
|
30
|
-
enum: %w[table
|
|
31
|
-
default: '
|
|
31
|
+
enum: %w[json table csv],
|
|
32
|
+
default: 'json',
|
|
32
33
|
desc: 'Output format'
|
|
33
34
|
class_option :output,
|
|
34
35
|
type: :string,
|
|
@@ -91,7 +92,7 @@ module Langfuse
|
|
|
91
92
|
config = load_config
|
|
92
93
|
unless config.valid?
|
|
93
94
|
error_message = "Missing required configuration: #{config.missing_fields.join(', ')}"
|
|
94
|
-
error_message += "\n\nPlease set environment variables or run:
|
|
95
|
+
error_message += "\n\nPlease set environment variables or run: lf config setup"
|
|
95
96
|
raise Error, error_message
|
|
96
97
|
end
|
|
97
98
|
Client.new(config)
|
|
@@ -110,33 +111,37 @@ module Langfuse
|
|
|
110
111
|
end
|
|
111
112
|
|
|
112
113
|
def output_result(data)
|
|
113
|
-
|
|
114
|
+
format_type = options[:format] || 'json'
|
|
114
115
|
|
|
115
116
|
if options[:output]
|
|
116
|
-
|
|
117
|
+
write_output(options[:output], data, format_type)
|
|
117
118
|
puts "Output written to #{options[:output]}" if options[:verbose]
|
|
118
119
|
else
|
|
119
|
-
puts
|
|
120
|
+
puts format_output(data, format_type: format_type)
|
|
120
121
|
end
|
|
121
122
|
end
|
|
122
123
|
|
|
123
|
-
def format_output(data)
|
|
124
|
-
case
|
|
124
|
+
def format_output(data, format_type: 'json')
|
|
125
|
+
case format_type
|
|
125
126
|
when 'json'
|
|
126
|
-
require 'json'
|
|
127
127
|
JSON.pretty_generate(data)
|
|
128
128
|
when 'csv'
|
|
129
129
|
# CSV formatting will be implemented in formatters
|
|
130
130
|
require_relative 'cli/formatters/csv_formatter'
|
|
131
131
|
Formatters::CSVFormatter.format(data)
|
|
132
|
-
when 'markdown'
|
|
133
|
-
require_relative 'cli/formatters/markdown_formatter'
|
|
134
|
-
Formatters::MarkdownFormatter.format(data)
|
|
135
132
|
else # table
|
|
136
133
|
require_relative 'cli/formatters/table_formatter'
|
|
137
134
|
Formatters::TableFormatter.format(data)
|
|
138
135
|
end
|
|
139
136
|
end
|
|
137
|
+
|
|
138
|
+
def write_output(path, data, format_type)
|
|
139
|
+
if format_type == 'json'
|
|
140
|
+
File.open(path, 'w') { |file| JSON.dump(data, file) }
|
|
141
|
+
else
|
|
142
|
+
File.write(path, format_output(data, format_type: format_type))
|
|
143
|
+
end
|
|
144
|
+
end
|
|
140
145
|
end
|
|
141
146
|
end
|
|
142
147
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lf-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vicente Reig Rincon de Arellano
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: thor
|
|
@@ -271,7 +271,6 @@ files:
|
|
|
271
271
|
- lib/langfuse/cli/commands/traces.rb
|
|
272
272
|
- lib/langfuse/cli/config.rb
|
|
273
273
|
- lib/langfuse/cli/formatters/csv_formatter.rb
|
|
274
|
-
- lib/langfuse/cli/formatters/markdown_formatter.rb
|
|
275
274
|
- lib/langfuse/cli/formatters/table_formatter.rb
|
|
276
275
|
- lib/langfuse/cli/types.rb
|
|
277
276
|
- lib/langfuse/cli/version.rb
|
|
@@ -297,7 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
297
296
|
- !ruby/object:Gem::Version
|
|
298
297
|
version: '0'
|
|
299
298
|
requirements: []
|
|
300
|
-
rubygems_version: 3.6.
|
|
299
|
+
rubygems_version: 3.6.9
|
|
301
300
|
specification_version: 4
|
|
302
301
|
summary: An open-source CLI for Langfuse®
|
|
303
302
|
test_files: []
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
require 'json'
|
|
2
|
-
|
|
3
|
-
module Langfuse
|
|
4
|
-
module CLI
|
|
5
|
-
module Formatters
|
|
6
|
-
class MarkdownFormatter
|
|
7
|
-
def self.format(data)
|
|
8
|
-
return "No data to display" if data.nil? || (data.is_a?(Array) && data.empty?)
|
|
9
|
-
|
|
10
|
-
# Convert single hash to array for consistent handling
|
|
11
|
-
data = [data] unless data.is_a?(Array)
|
|
12
|
-
|
|
13
|
-
# Get all unique keys from all rows
|
|
14
|
-
headers = data.flat_map(&:keys).uniq
|
|
15
|
-
|
|
16
|
-
# Build markdown table
|
|
17
|
-
output = []
|
|
18
|
-
|
|
19
|
-
# Header row
|
|
20
|
-
output << "| #{headers.join(' | ')} |"
|
|
21
|
-
|
|
22
|
-
# Separator row
|
|
23
|
-
output << "| #{headers.map { '---' }.join(' | ')} |"
|
|
24
|
-
|
|
25
|
-
# Data rows
|
|
26
|
-
data.each do |row|
|
|
27
|
-
values = headers.map { |header| escape_pipes(format_value(row[header])) }
|
|
28
|
-
output << "| #{values.join(' | ')} |"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
output.join("\n")
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
def self.format_value(value)
|
|
37
|
-
case value
|
|
38
|
-
when nil
|
|
39
|
-
''
|
|
40
|
-
when Hash, Array
|
|
41
|
-
value.to_json
|
|
42
|
-
when Time, DateTime
|
|
43
|
-
value.iso8601
|
|
44
|
-
else
|
|
45
|
-
value.to_s
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def self.escape_pipes(str)
|
|
50
|
-
# Escape pipe characters for markdown tables
|
|
51
|
-
str.gsub('|', '\\|')
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|