braintrust 0.1.3 → 0.2.0
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/README.md +71 -2
- data/lib/braintrust/api/datasets.rb +13 -3
- data/lib/braintrust/api/functions.rb +2 -3
- data/lib/braintrust/api/internal/auth.rb +2 -6
- data/lib/braintrust/api/internal/experiments.rb +7 -5
- data/lib/braintrust/api/internal/projects.rb +2 -3
- data/lib/braintrust/dataset.rb +10 -6
- data/lib/braintrust/eval/evaluator.rb +72 -0
- data/lib/braintrust/eval/functions.rb +56 -13
- data/lib/braintrust/eval/runner.rb +55 -13
- data/lib/braintrust/eval/scorer.rb +4 -0
- data/lib/braintrust/eval.rb +108 -45
- data/lib/braintrust/internal/http.rb +97 -0
- data/lib/braintrust/server/auth/clerk_token.rb +68 -0
- data/lib/braintrust/server/auth/no_auth.rb +14 -0
- data/lib/braintrust/server/handlers/eval.rb +217 -0
- data/lib/braintrust/server/handlers/health.rb +16 -0
- data/lib/braintrust/server/handlers/list.rb +74 -0
- data/lib/braintrust/server/middleware/auth.rb +29 -0
- data/lib/braintrust/server/middleware/cors.rb +87 -0
- data/lib/braintrust/server/rack/app.rb +38 -0
- data/lib/braintrust/server/rack.rb +36 -0
- data/lib/braintrust/server/router.rb +37 -0
- data/lib/braintrust/server/sse.rb +52 -0
- data/lib/braintrust/server.rb +8 -0
- data/lib/braintrust/trace/attachment.rb +3 -1
- data/lib/braintrust/trace/span_exporter.rb +36 -0
- data/lib/braintrust/trace.rb +3 -4
- data/lib/braintrust/version.rb +1 -1
- metadata +16 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Braintrust
|
|
6
|
+
module Server
|
|
7
|
+
module Handlers
|
|
8
|
+
# GET/POST /list — returns all evaluators keyed by name.
|
|
9
|
+
#
|
|
10
|
+
# Response format (Braintrust dev server protocol):
|
|
11
|
+
# {
|
|
12
|
+
# "evaluator-name": {
|
|
13
|
+
# "parameters": { # optional
|
|
14
|
+
# "type": "braintrust.staticParameters",
|
|
15
|
+
# "schema": {
|
|
16
|
+
# "param_name": { "type": "data", "schema": {...}, "default": ..., "description": ... }
|
|
17
|
+
# },
|
|
18
|
+
# "source": null
|
|
19
|
+
# },
|
|
20
|
+
# "scores": [{ "name": "scorer_name" }, ...]
|
|
21
|
+
# }
|
|
22
|
+
# }
|
|
23
|
+
class List
|
|
24
|
+
def initialize(evaluators)
|
|
25
|
+
@evaluators = evaluators
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def call(_env)
|
|
29
|
+
result = {}
|
|
30
|
+
@evaluators.each do |name, evaluator|
|
|
31
|
+
scores = (evaluator.scorers || []).each_with_index.map do |scorer, i|
|
|
32
|
+
scorer_name = scorer.respond_to?(:name) ? scorer.name : "score_#{i}"
|
|
33
|
+
{"name" => scorer_name}
|
|
34
|
+
end
|
|
35
|
+
entry = {"scores" => scores}
|
|
36
|
+
params = serialize_parameters(evaluator.parameters)
|
|
37
|
+
entry["parameters"] = params if params
|
|
38
|
+
result[name] = entry
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
[200, {"content-type" => "application/json"},
|
|
42
|
+
[JSON.dump(result)]]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# Convert user-defined parameters to the dev server protocol format.
|
|
48
|
+
# Wraps in a staticParameters container with "data" typed entries.
|
|
49
|
+
def serialize_parameters(parameters)
|
|
50
|
+
return nil unless parameters && !parameters.empty?
|
|
51
|
+
|
|
52
|
+
schema = {}
|
|
53
|
+
parameters.each do |name, spec|
|
|
54
|
+
spec = spec.transform_keys(&:to_s) if spec.is_a?(Hash)
|
|
55
|
+
if spec.is_a?(Hash)
|
|
56
|
+
schema[name.to_s] = {
|
|
57
|
+
"type" => "data",
|
|
58
|
+
"schema" => {"type" => spec["type"] || "string"},
|
|
59
|
+
"default" => spec["default"],
|
|
60
|
+
"description" => spec["description"]
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
{
|
|
66
|
+
"type" => "braintrust.staticParameters",
|
|
67
|
+
"schema" => schema,
|
|
68
|
+
"source" => nil
|
|
69
|
+
}
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Braintrust
|
|
6
|
+
module Server
|
|
7
|
+
module Middleware
|
|
8
|
+
# Auth middleware that validates requests using a pluggable strategy.
|
|
9
|
+
# Sets env["braintrust.auth"] with the authentication result on success.
|
|
10
|
+
class Auth
|
|
11
|
+
def initialize(app, strategy:)
|
|
12
|
+
@app = app
|
|
13
|
+
@strategy = strategy
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call(env)
|
|
17
|
+
auth_result = @strategy.authenticate(env)
|
|
18
|
+
unless auth_result
|
|
19
|
+
return [401, {"content-type" => "application/json"},
|
|
20
|
+
[JSON.dump({"error" => "Unauthorized"})]]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
env["braintrust.auth"] = auth_result
|
|
24
|
+
@app.call(env)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Braintrust
|
|
4
|
+
module Server
|
|
5
|
+
module Middleware
|
|
6
|
+
# CORS middleware allowing requests from *.braintrust.dev origins.
|
|
7
|
+
# Handles preflight OPTIONS requests and adds CORS headers to all responses.
|
|
8
|
+
class Cors
|
|
9
|
+
ALLOWED_ORIGIN_PATTERN = /\Ahttps?:\/\/([\w-]+\.)*braintrust\.dev\z/
|
|
10
|
+
|
|
11
|
+
HEADER_ALLOW_ORIGIN = "access-control-allow-origin"
|
|
12
|
+
HEADER_ALLOW_CREDENTIALS = "access-control-allow-credentials"
|
|
13
|
+
HEADER_ALLOW_METHODS = "access-control-allow-methods"
|
|
14
|
+
HEADER_ALLOW_HEADERS = "access-control-allow-headers"
|
|
15
|
+
HEADER_MAX_AGE = "access-control-max-age"
|
|
16
|
+
HEADER_ALLOW_PRIVATE_NETWORK = "access-control-allow-private-network"
|
|
17
|
+
HEADER_EXPOSE_HEADERS = "access-control-expose-headers"
|
|
18
|
+
EXPOSED_HEADERS = "x-bt-cursor, x-bt-found-existing-experiment, x-bt-span-id, x-bt-span-export"
|
|
19
|
+
|
|
20
|
+
ALLOWED_HEADERS = %w[
|
|
21
|
+
content-type
|
|
22
|
+
authorization
|
|
23
|
+
x-amz-date
|
|
24
|
+
x-api-key
|
|
25
|
+
x-amz-security-token
|
|
26
|
+
x-bt-auth-token
|
|
27
|
+
x-bt-parent
|
|
28
|
+
x-bt-org-name
|
|
29
|
+
x-bt-project-id
|
|
30
|
+
x-bt-stream-fmt
|
|
31
|
+
x-bt-use-cache
|
|
32
|
+
x-bt-use-gateway
|
|
33
|
+
x-stainless-os
|
|
34
|
+
x-stainless-lang
|
|
35
|
+
x-stainless-package-version
|
|
36
|
+
x-stainless-runtime
|
|
37
|
+
x-stainless-runtime-version
|
|
38
|
+
x-stainless-arch
|
|
39
|
+
].freeze
|
|
40
|
+
|
|
41
|
+
def initialize(app)
|
|
42
|
+
@app = app
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def call(env)
|
|
46
|
+
origin = env["HTTP_ORIGIN"]
|
|
47
|
+
|
|
48
|
+
if env["REQUEST_METHOD"] == "OPTIONS"
|
|
49
|
+
return handle_preflight(env, origin)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
status, headers, body = @app.call(env)
|
|
53
|
+
add_cors_headers(headers, origin)
|
|
54
|
+
[status, headers, body]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def handle_preflight(env, origin)
|
|
60
|
+
headers = {}
|
|
61
|
+
add_cors_headers(headers, origin)
|
|
62
|
+
headers[HEADER_ALLOW_METHODS] = "GET, POST, OPTIONS"
|
|
63
|
+
headers[HEADER_ALLOW_HEADERS] = ALLOWED_HEADERS.join(", ")
|
|
64
|
+
headers[HEADER_MAX_AGE] = "86400"
|
|
65
|
+
|
|
66
|
+
if env["HTTP_ACCESS_CONTROL_REQUEST_PRIVATE_NETWORK"] == "true"
|
|
67
|
+
headers[HEADER_ALLOW_PRIVATE_NETWORK] = "true"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
[204, headers, []]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def add_cors_headers(headers, origin)
|
|
74
|
+
return unless origin && allowed_origin?(origin)
|
|
75
|
+
|
|
76
|
+
headers[HEADER_ALLOW_ORIGIN] = origin
|
|
77
|
+
headers[HEADER_ALLOW_CREDENTIALS] = "true"
|
|
78
|
+
headers[HEADER_EXPOSE_HEADERS] = EXPOSED_HEADERS
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def allowed_origin?(origin)
|
|
82
|
+
ALLOWED_ORIGIN_PATTERN.match?(origin)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Braintrust
|
|
4
|
+
module Server
|
|
5
|
+
module Rack
|
|
6
|
+
# Builds the Rack middleware stack for the eval server.
|
|
7
|
+
class App
|
|
8
|
+
def self.build(evaluators: {}, auth: :clerk_token)
|
|
9
|
+
router = Router.new
|
|
10
|
+
router.add("GET", "/", Handlers::Health.new)
|
|
11
|
+
list_handler = Handlers::List.new(evaluators)
|
|
12
|
+
router.add("GET", "/list", list_handler)
|
|
13
|
+
router.add("POST", "/list", list_handler)
|
|
14
|
+
router.add("POST", "/eval", Handlers::Eval.new(evaluators))
|
|
15
|
+
|
|
16
|
+
auth_strategy = resolve_auth(auth)
|
|
17
|
+
|
|
18
|
+
app = router
|
|
19
|
+
app = Middleware::Auth.new(app, strategy: auth_strategy)
|
|
20
|
+
Middleware::Cors.new(app)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.resolve_auth(auth)
|
|
24
|
+
case auth
|
|
25
|
+
when :none
|
|
26
|
+
Auth::NoAuth.new
|
|
27
|
+
when :clerk_token
|
|
28
|
+
Auth::ClerkToken.new
|
|
29
|
+
else
|
|
30
|
+
auth
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private_class_method :resolve_auth
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require "rack"
|
|
5
|
+
rescue LoadError
|
|
6
|
+
raise LoadError,
|
|
7
|
+
"The 'rack' gem is required for the Braintrust server. " \
|
|
8
|
+
"Add `gem 'rack'` to your Gemfile."
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
require "json"
|
|
12
|
+
require_relative "../eval"
|
|
13
|
+
require_relative "sse"
|
|
14
|
+
require_relative "auth/no_auth"
|
|
15
|
+
require_relative "auth/clerk_token"
|
|
16
|
+
require_relative "middleware/cors"
|
|
17
|
+
require_relative "middleware/auth"
|
|
18
|
+
require_relative "handlers/health"
|
|
19
|
+
require_relative "handlers/list"
|
|
20
|
+
require_relative "handlers/eval"
|
|
21
|
+
require_relative "router"
|
|
22
|
+
require_relative "rack/app"
|
|
23
|
+
|
|
24
|
+
module Braintrust
|
|
25
|
+
module Server
|
|
26
|
+
module Rack
|
|
27
|
+
# Build the Rack application for the eval server.
|
|
28
|
+
# @param evaluators [Hash<String, Evaluator>] Named evaluators ({ "name" => instance })
|
|
29
|
+
# @param auth [:clerk_token, :none, Object] Auth strategy (default: :clerk_token)
|
|
30
|
+
# @return [#call] Rack application
|
|
31
|
+
def self.app(evaluators: {}, auth: :clerk_token)
|
|
32
|
+
App.build(evaluators: evaluators, auth: auth)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Braintrust
|
|
6
|
+
module Server
|
|
7
|
+
# Simple request router that dispatches to handlers based on method + path.
|
|
8
|
+
# Returns 405 for known paths with wrong method, 404 for unknown paths.
|
|
9
|
+
class Router
|
|
10
|
+
def initialize
|
|
11
|
+
@routes = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def add(method, path, handler)
|
|
15
|
+
@routes["#{method} #{path}"] = handler
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def call(env)
|
|
20
|
+
method = env["REQUEST_METHOD"]
|
|
21
|
+
path = env["PATH_INFO"]
|
|
22
|
+
|
|
23
|
+
handler = @routes["#{method} #{path}"]
|
|
24
|
+
return handler.call(env) if handler
|
|
25
|
+
|
|
26
|
+
# Path exists but wrong method
|
|
27
|
+
if @routes.any? { |key, _| key.end_with?(" #{path}") }
|
|
28
|
+
return [405, {"content-type" => "application/json"},
|
|
29
|
+
[JSON.dump({"error" => "Method not allowed"})]]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
[404, {"content-type" => "application/json"},
|
|
33
|
+
[JSON.dump({"error" => "Not found"})]]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Braintrust
|
|
4
|
+
module Server
|
|
5
|
+
# Rack-compatible response body that streams SSE events via `each`.
|
|
6
|
+
#
|
|
7
|
+
# Works with Puma (immediate writes), Passenger, and rack-test.
|
|
8
|
+
# WEBrick buffers the entire body and is unsuitable for SSE.
|
|
9
|
+
#
|
|
10
|
+
# Falcon buffers `each`-based bodies as Enumerable; use SSEStreamBody instead.
|
|
11
|
+
class SSEBody
|
|
12
|
+
def initialize(&block)
|
|
13
|
+
@block = block
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def each
|
|
17
|
+
writer = SSEWriter.new { |chunk| yield chunk }
|
|
18
|
+
@block.call(writer)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Rack 3 streaming response body that writes SSE events via `call(stream)`.
|
|
23
|
+
#
|
|
24
|
+
# Required for servers using the protocol-rack adapter (e.g. Falcon), which
|
|
25
|
+
# dispatches `each`-based bodies through a buffered Enumerable path. Bodies
|
|
26
|
+
# that respond only to `call` are dispatched through the Streaming path for
|
|
27
|
+
# true async writes.
|
|
28
|
+
class SSEStreamBody
|
|
29
|
+
def initialize(&block)
|
|
30
|
+
@block = block
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def call(stream)
|
|
34
|
+
writer = SSEWriter.new { |chunk| stream.write(chunk) }
|
|
35
|
+
@block.call(writer)
|
|
36
|
+
ensure
|
|
37
|
+
stream.close
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Writes formatted SSE events.
|
|
42
|
+
class SSEWriter
|
|
43
|
+
def initialize(&block)
|
|
44
|
+
@write = block
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def event(type, data = "")
|
|
48
|
+
@write.call("event: #{type}\ndata: #{data}\n\n")
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "net/http"
|
|
4
4
|
require_relative "../internal/encoding"
|
|
5
|
+
require_relative "../internal/http"
|
|
5
6
|
require "uri"
|
|
6
7
|
|
|
7
8
|
module Braintrust
|
|
@@ -91,7 +92,8 @@ module Braintrust
|
|
|
91
92
|
# att = Braintrust::Trace::Attachment.from_url("https://example.com/image.png")
|
|
92
93
|
def self.from_url(url)
|
|
93
94
|
uri = URI.parse(url)
|
|
94
|
-
|
|
95
|
+
request = Net::HTTP::Get.new(uri)
|
|
96
|
+
response = Braintrust::Internal::Http.with_redirects(uri, request)
|
|
95
97
|
|
|
96
98
|
unless response.is_a?(Net::HTTPSuccess)
|
|
97
99
|
raise StandardError, "Failed to fetch URL: #{response.code} #{response.message}"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "opentelemetry/exporter/otlp"
|
|
4
|
+
|
|
5
|
+
module Braintrust
|
|
6
|
+
module Trace
|
|
7
|
+
# Custom OTLP exporter that groups spans by braintrust.parent attribute
|
|
8
|
+
# and sets the x-bt-parent HTTP header per group. This is required for
|
|
9
|
+
# the Braintrust OTLP backend to route spans to the correct experiment/project.
|
|
10
|
+
#
|
|
11
|
+
# Thread safety: BatchSpanProcessor serializes export() calls via its
|
|
12
|
+
# @export_mutex, so @headers mutation here is safe.
|
|
13
|
+
class SpanExporter < OpenTelemetry::Exporter::OTLP::Exporter
|
|
14
|
+
PARENT_ATTR_KEY = SpanProcessor::PARENT_ATTR_KEY
|
|
15
|
+
PARENT_HEADER = "x-bt-parent"
|
|
16
|
+
|
|
17
|
+
SUCCESS = OpenTelemetry::SDK::Trace::Export::SUCCESS
|
|
18
|
+
FAILURE = OpenTelemetry::SDK::Trace::Export::FAILURE
|
|
19
|
+
|
|
20
|
+
def initialize(endpoint:, api_key:)
|
|
21
|
+
super(endpoint: endpoint, headers: {"Authorization" => "Bearer #{api_key}"})
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def export(span_data, timeout: nil)
|
|
25
|
+
failed = false
|
|
26
|
+
span_data.group_by { |sd| sd.attributes&.[](PARENT_ATTR_KEY) }.each do |parent_value, spans|
|
|
27
|
+
@headers[PARENT_HEADER] = parent_value if parent_value
|
|
28
|
+
failed = true unless super(spans, timeout: timeout) == SUCCESS
|
|
29
|
+
ensure
|
|
30
|
+
@headers.delete(PARENT_HEADER)
|
|
31
|
+
end
|
|
32
|
+
failed ? FAILURE : SUCCESS
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/braintrust/trace.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "opentelemetry/sdk"
|
|
4
4
|
require "opentelemetry/exporter/otlp"
|
|
5
5
|
require_relative "trace/span_processor"
|
|
6
|
+
require_relative "trace/span_exporter"
|
|
6
7
|
require_relative "trace/span_filter"
|
|
7
8
|
require_relative "internal/env"
|
|
8
9
|
require_relative "logger"
|
|
@@ -88,11 +89,9 @@ module Braintrust
|
|
|
88
89
|
config ||= state.respond_to?(:config) ? state.config : nil
|
|
89
90
|
|
|
90
91
|
# Create OTLP HTTP exporter unless override provided
|
|
91
|
-
exporter ||=
|
|
92
|
+
exporter ||= SpanExporter.new(
|
|
92
93
|
endpoint: "#{state.api_url}/otel/v1/traces",
|
|
93
|
-
|
|
94
|
-
"Authorization" => "Bearer #{state.api_key}"
|
|
95
|
-
}
|
|
94
|
+
api_key: state.api_key
|
|
96
95
|
)
|
|
97
96
|
|
|
98
97
|
# Use SimpleSpanProcessor for InMemorySpanExporter (testing), BatchSpanProcessor for production
|
data/lib/braintrust/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: braintrust
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Braintrust
|
|
@@ -234,6 +234,7 @@ files:
|
|
|
234
234
|
- lib/braintrust/eval.rb
|
|
235
235
|
- lib/braintrust/eval/case.rb
|
|
236
236
|
- lib/braintrust/eval/cases.rb
|
|
237
|
+
- lib/braintrust/eval/evaluator.rb
|
|
237
238
|
- lib/braintrust/eval/formatter.rb
|
|
238
239
|
- lib/braintrust/eval/functions.rb
|
|
239
240
|
- lib/braintrust/eval/result.rb
|
|
@@ -242,16 +243,30 @@ files:
|
|
|
242
243
|
- lib/braintrust/eval/summary.rb
|
|
243
244
|
- lib/braintrust/internal/encoding.rb
|
|
244
245
|
- lib/braintrust/internal/env.rb
|
|
246
|
+
- lib/braintrust/internal/http.rb
|
|
245
247
|
- lib/braintrust/internal/origin.rb
|
|
246
248
|
- lib/braintrust/internal/template.rb
|
|
247
249
|
- lib/braintrust/internal/thread_pool.rb
|
|
248
250
|
- lib/braintrust/internal/time.rb
|
|
249
251
|
- lib/braintrust/logger.rb
|
|
250
252
|
- lib/braintrust/prompt.rb
|
|
253
|
+
- lib/braintrust/server.rb
|
|
254
|
+
- lib/braintrust/server/auth/clerk_token.rb
|
|
255
|
+
- lib/braintrust/server/auth/no_auth.rb
|
|
256
|
+
- lib/braintrust/server/handlers/eval.rb
|
|
257
|
+
- lib/braintrust/server/handlers/health.rb
|
|
258
|
+
- lib/braintrust/server/handlers/list.rb
|
|
259
|
+
- lib/braintrust/server/middleware/auth.rb
|
|
260
|
+
- lib/braintrust/server/middleware/cors.rb
|
|
261
|
+
- lib/braintrust/server/rack.rb
|
|
262
|
+
- lib/braintrust/server/rack/app.rb
|
|
263
|
+
- lib/braintrust/server/router.rb
|
|
264
|
+
- lib/braintrust/server/sse.rb
|
|
251
265
|
- lib/braintrust/setup.rb
|
|
252
266
|
- lib/braintrust/state.rb
|
|
253
267
|
- lib/braintrust/trace.rb
|
|
254
268
|
- lib/braintrust/trace/attachment.rb
|
|
269
|
+
- lib/braintrust/trace/span_exporter.rb
|
|
255
270
|
- lib/braintrust/trace/span_filter.rb
|
|
256
271
|
- lib/braintrust/trace/span_processor.rb
|
|
257
272
|
- lib/braintrust/vendor/mustache.rb
|