Module: Braintrust::Functions

Defined in:
lib/braintrust/functions.rb

Overview

Functions provides remote function execution capabilities. Allows calling prompts hosted on Braintrust servers as tasks or scorers.

Class Method Summary collapse

Class Method Details

.scorer(project: nil, slug: nil, id: nil, version: nil, state: nil, tracer_provider: nil) ⇒ Scorer

Create a scorer that invokes a remote function. Resolve by project + slug, or by function UUID (id).

Parameters:

  • project (String, nil) (defaults to: nil)

    Project name (used with slug)

  • slug (String, nil) (defaults to: nil)

    Function slug (used with project)

  • id (String, nil) (defaults to: nil)

    Function UUID (alternative to project + slug)

  • version (String, nil) (defaults to: nil)

    Optional version to pin to (used with id)

  • state (State, nil) (defaults to: nil)

    Braintrust state (defaults to global)

  • tracer_provider (TracerProvider, nil) (defaults to: nil)

    OpenTelemetry tracer provider

Returns:

  • (Scorer)

    Scorer object that invokes remote function

Raises:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/braintrust/functions.rb', line 64

def scorer(project: nil, slug: nil, id: nil, version: nil, state: nil, tracer_provider: nil)
  has_id = !id.nil?
  has_project_slug = !project.nil? && !slug.nil?

  unless has_id || has_project_slug
    raise ArgumentError, "scorer requires either id: or both project: and slug:"
  end

  state ||= Braintrust.current_state
  raise Error, "No state available" unless state

  api = API.new(state: state)

   = if id
    api.
    api.functions.get(id: id, version: version)
  else
    resolve_function(api, project, slug)
  end

  function_id = ["id"]
  function_name = ["name"] || id || slug

  tracer_provider ||= OpenTelemetry.tracer_provider
  tracer = tracer_provider.tracer("braintrust.functions")

  build_scorer(function_id: function_id, function_name: function_name, api: api, tracer: tracer)
end

.task(project:, slug:, state: nil, tracer_provider: nil) ⇒ Task

Create a Task that invokes a remote function

Parameters:

  • project (String)

    Project name

  • slug (String)

    Function slug

  • state (State, nil) (defaults to: nil)

    Braintrust state (defaults to global)

  • tracer_provider (TracerProvider, nil) (defaults to: nil)

    OpenTelemetry tracer provider

Returns:

  • (Task)

    Task object that invokes remote function

Raises:



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/braintrust/functions.rb', line 20

def task(project:, slug:, state: nil, tracer_provider: nil)
  state ||= Braintrust.current_state
  raise Error, "No state available" unless state

  # Resolve function ID from project + slug
  api = API.new(state: state)
   = resolve_function(api, project, slug)
  function_id = ["id"]
  function_name = ["name"] || slug

  # Get tracer for creating spans
  tracer_provider ||= OpenTelemetry.tracer_provider
  tracer = tracer_provider.tracer("braintrust.functions")

  Task.new(function_name) do |input:|
    tracer.in_span("function: #{slug}") do |span|
      span.set_attribute("braintrust.span_attributes", JSON.dump({type: "function"}))
      span.set_attribute("braintrust.input_json", JSON.dump(input))
      span.set_attribute("braintrust.function.name", function_name)
      span.set_attribute("braintrust.function.id", function_id)
      span.set_attribute("braintrust.function.slug", slug)

      begin
        output = api.functions.invoke(id: function_id, input: input)
        span.set_attribute("braintrust.output_json", JSON.dump(output))
        output
      rescue => e
        span.record_exception(e)
        span.status = OpenTelemetry::Trace::Status.error(e.message)
        raise
      end
    end
  end
end