braintrust 0.0.1.alpha.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 +7 -0
- data/README.md +24 -0
- data/lib/braintrust/api/datasets.rb +198 -0
- data/lib/braintrust/api/functions.rb +152 -0
- data/lib/braintrust/api/internal/auth.rb +97 -0
- data/lib/braintrust/api.rb +29 -0
- data/lib/braintrust/config.rb +30 -0
- data/lib/braintrust/eval/case.rb +12 -0
- data/lib/braintrust/eval/cases.rb +58 -0
- data/lib/braintrust/eval/functions.rb +137 -0
- data/lib/braintrust/eval/result.rb +53 -0
- data/lib/braintrust/eval/scorer.rb +108 -0
- data/lib/braintrust/eval.rb +418 -0
- data/lib/braintrust/internal/experiments.rb +129 -0
- data/lib/braintrust/logger.rb +32 -0
- data/lib/braintrust/state.rb +121 -0
- data/lib/braintrust/trace/openai.rb +87 -0
- data/lib/braintrust/trace/span_processor.rb +71 -0
- data/lib/braintrust/trace.rb +108 -0
- data/lib/braintrust/version.rb +5 -0
- data/lib/braintrust.rb +110 -0
- metadata +176 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "opentelemetry/sdk"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
module Braintrust
|
|
7
|
+
module Trace
|
|
8
|
+
module OpenAI
|
|
9
|
+
# Wrap an OpenAI::Client to automatically create spans for chat completions
|
|
10
|
+
# @param client [OpenAI::Client] the OpenAI client to wrap
|
|
11
|
+
# @param tracer_provider [OpenTelemetry::SDK::Trace::TracerProvider] the tracer provider (defaults to global)
|
|
12
|
+
def self.wrap(client, tracer_provider: nil)
|
|
13
|
+
tracer_provider ||= ::OpenTelemetry.tracer_provider
|
|
14
|
+
|
|
15
|
+
# Create a wrapper module that intercepts chat.completions.create
|
|
16
|
+
wrapper = Module.new do
|
|
17
|
+
define_method(:create) do |**params|
|
|
18
|
+
tracer = tracer_provider.tracer("braintrust")
|
|
19
|
+
|
|
20
|
+
tracer.in_span("openai.chat.completions.create") do |span|
|
|
21
|
+
# Initialize metadata hash
|
|
22
|
+
metadata = {
|
|
23
|
+
"provider" => "openai",
|
|
24
|
+
"endpoint" => "/v1/chat/completions"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Capture request metadata fields
|
|
28
|
+
metadata_fields = %i[
|
|
29
|
+
model frequency_penalty logit_bias logprobs max_tokens n
|
|
30
|
+
presence_penalty response_format seed service_tier stop
|
|
31
|
+
stream stream_options temperature top_p top_logprobs
|
|
32
|
+
tools tool_choice parallel_tool_calls user functions function_call
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
metadata_fields.each do |field|
|
|
36
|
+
metadata[field.to_s] = params[field] if params.key?(field)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Set input messages as JSON
|
|
40
|
+
if params[:messages]
|
|
41
|
+
messages_array = params[:messages].map do |msg|
|
|
42
|
+
{role: msg[:role].to_s, content: msg[:content]}
|
|
43
|
+
end
|
|
44
|
+
span.set_attribute("braintrust.input_json", JSON.generate(messages_array))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Call the original method
|
|
48
|
+
response = super(**params)
|
|
49
|
+
|
|
50
|
+
# Set output (choices) as JSON
|
|
51
|
+
# Use to_h to get the raw structure with all fields (including tool_calls)
|
|
52
|
+
if response.respond_to?(:choices) && response.choices&.any?
|
|
53
|
+
choices_array = response.choices.map(&:to_h)
|
|
54
|
+
span.set_attribute("braintrust.output_json", JSON.generate(choices_array))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Set metrics (token usage)
|
|
58
|
+
if response.respond_to?(:usage) && response.usage
|
|
59
|
+
metrics = {}
|
|
60
|
+
metrics["prompt_tokens"] = response.usage.prompt_tokens if response.usage.prompt_tokens
|
|
61
|
+
metrics["completion_tokens"] = response.usage.completion_tokens if response.usage.completion_tokens
|
|
62
|
+
metrics["tokens"] = response.usage.total_tokens if response.usage.total_tokens
|
|
63
|
+
span.set_attribute("braintrust.metrics", JSON.generate(metrics))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Add response metadata fields
|
|
67
|
+
metadata["id"] = response.id if response.respond_to?(:id) && response.id
|
|
68
|
+
metadata["created"] = response.created if response.respond_to?(:created) && response.created
|
|
69
|
+
metadata["system_fingerprint"] = response.system_fingerprint if response.respond_to?(:system_fingerprint) && response.system_fingerprint
|
|
70
|
+
metadata["service_tier"] = response.service_tier if response.respond_to?(:service_tier) && response.service_tier
|
|
71
|
+
|
|
72
|
+
# Set metadata ONCE at the end with complete hash
|
|
73
|
+
span.set_attribute("braintrust.metadata", JSON.generate(metadata))
|
|
74
|
+
|
|
75
|
+
response
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Prepend the wrapper to the completions resource
|
|
81
|
+
client.chat.completions.singleton_class.prepend(wrapper)
|
|
82
|
+
|
|
83
|
+
client
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "opentelemetry/sdk"
|
|
4
|
+
|
|
5
|
+
module Braintrust
|
|
6
|
+
module Trace
|
|
7
|
+
# Custom span processor that adds Braintrust-specific attributes to spans
|
|
8
|
+
class SpanProcessor
|
|
9
|
+
PARENT_ATTR_KEY = "braintrust.parent"
|
|
10
|
+
ORG_ATTR_KEY = "braintrust.org"
|
|
11
|
+
APP_URL_ATTR_KEY = "braintrust.app_url"
|
|
12
|
+
|
|
13
|
+
def initialize(wrapped_processor, state)
|
|
14
|
+
@wrapped = wrapped_processor
|
|
15
|
+
@state = state
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def on_start(span, parent_context)
|
|
19
|
+
# Add default parent if span doesn't already have one
|
|
20
|
+
has_parent = span.respond_to?(:attributes) && span.attributes&.key?(PARENT_ATTR_KEY)
|
|
21
|
+
|
|
22
|
+
unless has_parent
|
|
23
|
+
# Try to inherit parent from parent span in context
|
|
24
|
+
parent_value = get_parent_from_context(parent_context) || default_parent
|
|
25
|
+
span.set_attribute(PARENT_ATTR_KEY, parent_value)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Always add org and app_url
|
|
29
|
+
span.set_attribute(ORG_ATTR_KEY, @state.org_name) if @state.org_name
|
|
30
|
+
span.set_attribute(APP_URL_ATTR_KEY, @state.app_url) if @state.app_url
|
|
31
|
+
|
|
32
|
+
# Delegate to wrapped processor
|
|
33
|
+
@wrapped.on_start(span, parent_context)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Called when a span ends
|
|
37
|
+
def on_finish(span)
|
|
38
|
+
@wrapped.on_finish(span)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Shutdown the processor
|
|
42
|
+
def shutdown(timeout: nil)
|
|
43
|
+
@wrapped.shutdown(timeout: timeout)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Force flush any buffered spans
|
|
47
|
+
def force_flush(timeout: nil)
|
|
48
|
+
@wrapped.force_flush(timeout: timeout)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def default_parent
|
|
54
|
+
@state.default_parent || "project_name:ruby-sdk-default-project"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Get parent attribute from parent span in context
|
|
58
|
+
def get_parent_from_context(parent_context)
|
|
59
|
+
return nil unless parent_context
|
|
60
|
+
|
|
61
|
+
# Get the current span from the context (the parent span)
|
|
62
|
+
parent_span = OpenTelemetry::Trace.current_span(parent_context)
|
|
63
|
+
return nil unless parent_span
|
|
64
|
+
return nil unless parent_span.respond_to?(:attributes)
|
|
65
|
+
|
|
66
|
+
# Return the parent attribute from the parent span
|
|
67
|
+
parent_span.attributes&.[](PARENT_ATTR_KEY)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "opentelemetry/sdk"
|
|
4
|
+
require "opentelemetry/exporter/otlp"
|
|
5
|
+
require_relative "trace/span_processor"
|
|
6
|
+
require_relative "trace/openai"
|
|
7
|
+
require_relative "logger"
|
|
8
|
+
|
|
9
|
+
module Braintrust
|
|
10
|
+
module Trace
|
|
11
|
+
def self.enable(tracer_provider, state: nil, exporter: nil)
|
|
12
|
+
state ||= Braintrust.current_state
|
|
13
|
+
raise Error, "No state available" unless state
|
|
14
|
+
|
|
15
|
+
# Create OTLP HTTP exporter unless override provided
|
|
16
|
+
exporter ||= OpenTelemetry::Exporter::OTLP::Exporter.new(
|
|
17
|
+
endpoint: "#{state.api_url}/otel/v1/traces",
|
|
18
|
+
headers: {
|
|
19
|
+
"Authorization" => "Bearer #{state.api_key}"
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# Wrap in batch processor
|
|
24
|
+
batch_processor = OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(exporter)
|
|
25
|
+
|
|
26
|
+
# Wrap batch processor in our custom span processor to add Braintrust attributes
|
|
27
|
+
processor = SpanProcessor.new(batch_processor, state)
|
|
28
|
+
|
|
29
|
+
# Register with tracer provider
|
|
30
|
+
tracer_provider.add_span_processor(processor)
|
|
31
|
+
|
|
32
|
+
# Console debug if enabled
|
|
33
|
+
if ENV["BRAINTRUST_ENABLE_TRACE_CONSOLE_LOG"]
|
|
34
|
+
console_exporter = OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new
|
|
35
|
+
console_processor = OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(console_exporter)
|
|
36
|
+
tracer_provider.add_span_processor(console_processor)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Generate a permalink URL for a span to view in the Braintrust UI
|
|
43
|
+
# Returns an empty string if the permalink cannot be generated
|
|
44
|
+
# @param span [OpenTelemetry::Trace::Span] The span to generate a permalink for
|
|
45
|
+
# @return [String] The permalink URL, or empty string if an error occurs
|
|
46
|
+
def self.permalink(span)
|
|
47
|
+
return "" if span.nil?
|
|
48
|
+
|
|
49
|
+
# Extract required attributes from span
|
|
50
|
+
span_context = span.context
|
|
51
|
+
trace_id = span_context.hex_trace_id
|
|
52
|
+
span_id = span_context.hex_span_id
|
|
53
|
+
|
|
54
|
+
# Get Braintrust attributes
|
|
55
|
+
attributes = span.attributes if span.respond_to?(:attributes)
|
|
56
|
+
unless attributes
|
|
57
|
+
Log.error("Span does not support attributes")
|
|
58
|
+
return ""
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
app_url = attributes[SpanProcessor::APP_URL_ATTR_KEY]
|
|
62
|
+
org_name = attributes[SpanProcessor::ORG_ATTR_KEY]
|
|
63
|
+
parent = attributes[SpanProcessor::PARENT_ATTR_KEY]
|
|
64
|
+
|
|
65
|
+
# Validate required attributes
|
|
66
|
+
unless app_url
|
|
67
|
+
Log.error("Missing required attribute: #{SpanProcessor::APP_URL_ATTR_KEY}")
|
|
68
|
+
return ""
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
unless org_name
|
|
72
|
+
Log.error("Missing required attribute: #{SpanProcessor::ORG_ATTR_KEY}")
|
|
73
|
+
return ""
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
unless parent
|
|
77
|
+
Log.error("Missing required attribute: #{SpanProcessor::PARENT_ATTR_KEY}")
|
|
78
|
+
return ""
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Parse parent to determine URL format
|
|
82
|
+
parent_type, parent_id = parent.split(":", 2)
|
|
83
|
+
unless parent_type && parent_id
|
|
84
|
+
Log.error("Invalid parent format: #{parent}")
|
|
85
|
+
return ""
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Build the permalink URL based on parent type
|
|
89
|
+
if parent_type == "experiment_id"
|
|
90
|
+
# For experiments: {app_url}/app/{org}/p/{project}/experiments/{experiment_id}?r={trace_id}&s={span_id}
|
|
91
|
+
project_name, experiment_id = parent_id.split("/", 2)
|
|
92
|
+
unless project_name && experiment_id
|
|
93
|
+
Log.error("Invalid experiment parent format: #{parent_id}")
|
|
94
|
+
return ""
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
"#{app_url}/app/#{org_name}/p/#{project_name}/experiments/#{experiment_id}?r=#{trace_id}&s=#{span_id}"
|
|
98
|
+
else
|
|
99
|
+
# For projects: {app_url}/app/{org}/p/{project}/logs?r={trace_id}&s={span_id}
|
|
100
|
+
# parent_type is typically "project_name"
|
|
101
|
+
"#{app_url}/app/#{org_name}/p/#{parent_id}/logs?r=#{trace_id}&s=#{span_id}"
|
|
102
|
+
end
|
|
103
|
+
rescue => e
|
|
104
|
+
Log.error("Failed to generate permalink: #{e.message}")
|
|
105
|
+
""
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
data/lib/braintrust.rb
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "braintrust/version"
|
|
4
|
+
require_relative "braintrust/config"
|
|
5
|
+
require_relative "braintrust/state"
|
|
6
|
+
require_relative "braintrust/trace"
|
|
7
|
+
require_relative "braintrust/api"
|
|
8
|
+
require_relative "braintrust/internal/experiments"
|
|
9
|
+
require_relative "braintrust/eval"
|
|
10
|
+
|
|
11
|
+
# Braintrust Ruby SDK
|
|
12
|
+
#
|
|
13
|
+
# OpenTelemetry-based SDK for Braintrust with tracing, OpenAI integration, and evals.
|
|
14
|
+
#
|
|
15
|
+
# @example Initialize with global state
|
|
16
|
+
# Braintrust.init(
|
|
17
|
+
# api_key: ENV['BRAINTRUST_API_KEY'],
|
|
18
|
+
# project: "my-project"
|
|
19
|
+
# )
|
|
20
|
+
#
|
|
21
|
+
# @example Initialize with explicit state
|
|
22
|
+
# state = Braintrust.init(
|
|
23
|
+
# api_key: ENV['BRAINTRUST_API_KEY'],
|
|
24
|
+
# set_global: false
|
|
25
|
+
# )
|
|
26
|
+
module Braintrust
|
|
27
|
+
class Error < StandardError; end
|
|
28
|
+
|
|
29
|
+
# Initialize Braintrust SDK
|
|
30
|
+
# Creates a State from config (ENV + options) and optionally sets it as global
|
|
31
|
+
#
|
|
32
|
+
# By default, kicks off an async background login that retries indefinitely.
|
|
33
|
+
# Use blocking_login: true to login synchronously before returning.
|
|
34
|
+
#
|
|
35
|
+
# @param set_global [Boolean] whether to set as global state (default: true)
|
|
36
|
+
# @param blocking_login [Boolean] whether to block and login synchronously (default: false, which starts async login)
|
|
37
|
+
# @param tracing [Boolean] whether to enable OpenTelemetry tracing (default: true)
|
|
38
|
+
# @param tracer_provider [TracerProvider, nil] Optional tracer provider to use instead of creating one
|
|
39
|
+
# @param api_key [String, nil] Braintrust API key (overrides BRAINTRUST_API_KEY env var)
|
|
40
|
+
# @param org_name [String, nil] Organization name (overrides BRAINTRUST_ORG_NAME env var)
|
|
41
|
+
# @param default_parent [String, nil] Default parent for spans (overrides BRAINTRUST_DEFAULT_PROJECT env var, format: "project_name:my-project" or "project_id:uuid")
|
|
42
|
+
# @param app_url [String, nil] App URL (overrides BRAINTRUST_APP_URL env var, default: https://www.braintrust.dev)
|
|
43
|
+
# @param api_url [String, nil] API URL (overrides BRAINTRUST_API_URL env var, default: https://api.braintrust.dev)
|
|
44
|
+
# @return [State] the created state
|
|
45
|
+
def self.init(set_global: true, blocking_login: false, tracing: true, tracer_provider: nil, **options)
|
|
46
|
+
config = Config.from_env(**options)
|
|
47
|
+
state = State.new(
|
|
48
|
+
api_key: config.api_key,
|
|
49
|
+
org_name: config.org_name,
|
|
50
|
+
default_parent: config.default_parent,
|
|
51
|
+
app_url: config.app_url,
|
|
52
|
+
api_url: config.api_url
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
State.global = state if set_global
|
|
56
|
+
|
|
57
|
+
# Login: either blocking (synchronous) or async (background thread with retries)
|
|
58
|
+
if blocking_login
|
|
59
|
+
state.login
|
|
60
|
+
else
|
|
61
|
+
state.login_in_thread # Default: async background login
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
setup_tracing(state, tracer_provider) if tracing
|
|
65
|
+
|
|
66
|
+
state
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Get the current global state
|
|
70
|
+
# @return [State, nil] the global state, or nil if not set
|
|
71
|
+
def self.current_state
|
|
72
|
+
State.global
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
class << self
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
# Set up OpenTelemetry tracing with Braintrust
|
|
79
|
+
# @param state [State] Braintrust state
|
|
80
|
+
# @param explicit_provider [TracerProvider, nil] Optional explicit tracer provider
|
|
81
|
+
# @return [void]
|
|
82
|
+
def setup_tracing(state, explicit_provider = nil)
|
|
83
|
+
require "opentelemetry/sdk"
|
|
84
|
+
|
|
85
|
+
if explicit_provider
|
|
86
|
+
# Use the explicitly provided tracer provider
|
|
87
|
+
# DO NOT set as global - user is managing it themselves
|
|
88
|
+
Log.debug("Using explicitly provided OpenTelemetry tracer provider")
|
|
89
|
+
tracer_provider = explicit_provider
|
|
90
|
+
else
|
|
91
|
+
# Check if global tracer provider is already a real TracerProvider
|
|
92
|
+
current_provider = OpenTelemetry.tracer_provider
|
|
93
|
+
|
|
94
|
+
if current_provider.is_a?(OpenTelemetry::SDK::Trace::TracerProvider)
|
|
95
|
+
# Use existing provider
|
|
96
|
+
Log.debug("Using existing OpenTelemetry tracer provider")
|
|
97
|
+
tracer_provider = current_provider
|
|
98
|
+
else
|
|
99
|
+
# Create new provider and set as global
|
|
100
|
+
tracer_provider = OpenTelemetry::SDK::Trace::TracerProvider.new
|
|
101
|
+
OpenTelemetry.tracer_provider = tracer_provider
|
|
102
|
+
Log.debug("Created OpenTelemetry tracer provider")
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Enable Braintrust tracing (adds span processor)
|
|
107
|
+
Trace.enable(tracer_provider, state: state)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: braintrust
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1.alpha.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Braintrust
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: opentelemetry-sdk
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: opentelemetry-exporter-otlp
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0.28'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.28'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: openssl
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 3.3.1
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 3.3.1
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: minitest
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '5.0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '5.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rake
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '13.0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '13.0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: standard
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '1.0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '1.0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: simplecov
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0.22'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0.22'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: openai
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0.34'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0.34'
|
|
124
|
+
description: OpenTelemetry-based SDK for Braintrust with tracing, OpenAI integration,
|
|
125
|
+
and evals
|
|
126
|
+
email:
|
|
127
|
+
- info@braintrust.dev
|
|
128
|
+
executables: []
|
|
129
|
+
extensions: []
|
|
130
|
+
extra_rdoc_files: []
|
|
131
|
+
files:
|
|
132
|
+
- README.md
|
|
133
|
+
- lib/braintrust.rb
|
|
134
|
+
- lib/braintrust/api.rb
|
|
135
|
+
- lib/braintrust/api/datasets.rb
|
|
136
|
+
- lib/braintrust/api/functions.rb
|
|
137
|
+
- lib/braintrust/api/internal/auth.rb
|
|
138
|
+
- lib/braintrust/config.rb
|
|
139
|
+
- lib/braintrust/eval.rb
|
|
140
|
+
- lib/braintrust/eval/case.rb
|
|
141
|
+
- lib/braintrust/eval/cases.rb
|
|
142
|
+
- lib/braintrust/eval/functions.rb
|
|
143
|
+
- lib/braintrust/eval/result.rb
|
|
144
|
+
- lib/braintrust/eval/scorer.rb
|
|
145
|
+
- lib/braintrust/internal/experiments.rb
|
|
146
|
+
- lib/braintrust/logger.rb
|
|
147
|
+
- lib/braintrust/state.rb
|
|
148
|
+
- lib/braintrust/trace.rb
|
|
149
|
+
- lib/braintrust/trace/openai.rb
|
|
150
|
+
- lib/braintrust/trace/span_processor.rb
|
|
151
|
+
- lib/braintrust/version.rb
|
|
152
|
+
homepage: https://github.com/braintrustdata/braintrust-sdk-ruby
|
|
153
|
+
licenses:
|
|
154
|
+
- Apache-2.0
|
|
155
|
+
metadata:
|
|
156
|
+
homepage_uri: https://github.com/braintrustdata/braintrust-sdk-ruby
|
|
157
|
+
source_code_uri: https://github.com/braintrustdata/braintrust-sdk-ruby
|
|
158
|
+
changelog_uri: https://github.com/braintrustdata/braintrust-sdk-ruby/blob/main/CHANGELOG.md
|
|
159
|
+
rdoc_options: []
|
|
160
|
+
require_paths:
|
|
161
|
+
- lib
|
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: 3.2.0
|
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
|
+
requirements:
|
|
169
|
+
- - ">="
|
|
170
|
+
- !ruby/object:Gem::Version
|
|
171
|
+
version: '0'
|
|
172
|
+
requirements: []
|
|
173
|
+
rubygems_version: 3.6.9
|
|
174
|
+
specification_version: 4
|
|
175
|
+
summary: Ruby SDK for Braintrust
|
|
176
|
+
test_files: []
|