22
33import dev .braintrust .api .BraintrustApiClient ;
44import dev .braintrust .config .BraintrustConfig ;
5+ import dev .braintrust .eval .Eval ;
56import dev .braintrust .prompt .BraintrustPromptLoader ;
7+ import dev .braintrust .trace .BraintrustTracing ;
68import io .opentelemetry .api .OpenTelemetry ;
79import io .opentelemetry .sdk .logs .SdkLoggerProviderBuilder ;
810import io .opentelemetry .sdk .metrics .SdkMeterProviderBuilder ;
911import io .opentelemetry .sdk .trace .SdkTracerProviderBuilder ;
1012import java .net .URI ;
13+ import java .util .concurrent .atomic .AtomicReference ;
1114import javax .annotation .Nonnull ;
1215import lombok .Getter ;
1316import lombok .experimental .Accessors ;
17+ import lombok .extern .slf4j .Slf4j ;
1418
1519/**
1620 * Main entry point for the Braintrust SDK.
3034 * @see #openTelemetryEnable(SdkTracerProviderBuilder, SdkLoggerProviderBuilder,
3135 * SdkMeterProviderBuilder)
3236 */
37+ @ Slf4j
3338public class Braintrust {
39+ private static final String SDK_VERSION = SDKMain .loadVersionFromProperties ();
40+ private static final AtomicReference <Braintrust > instance = new AtomicReference <>();
41+
3442 /**
3543 * get or create the global braintrust instance. Most users will want to use this method to
3644 * access the Braintrust SDK.
3745 */
3846 public static Braintrust get () {
39- throw new RuntimeException ("TODO" );
47+ var current = instance .get ();
48+ if (null == current ) {
49+ return get (BraintrustConfig .fromEnvironment ());
50+ } else {
51+ return current ;
52+ }
4053 }
4154
4255 /** get or create the global braintrust instance from the given config */
4356 public static Braintrust get (BraintrustConfig config ) {
44- throw new RuntimeException ("TODO" );
57+ var current = instance .get ();
58+ if (null == current ) {
59+ var success = instance .compareAndSet (null , of (config ));
60+ if (success ) {
61+ log .info ("initialized global Braintrust sdk {}" , SDK_VERSION );
62+ }
63+ return instance .get ();
64+ } else {
65+ return current ;
66+ }
4567 }
4668
4769 /** Create a new Braintrust instance from the given config */
4870 public static Braintrust of (BraintrustConfig config ) {
49- throw new RuntimeException ("TODO" );
71+ BraintrustApiClient apiClient = BraintrustApiClient .of (config );
72+ BraintrustPromptLoader promptLoader = BraintrustPromptLoader .of (config , apiClient );
73+ return new Braintrust (config , apiClient , promptLoader );
5074 }
5175
5276 @ Getter
@@ -71,21 +95,53 @@ private Braintrust(
7195 }
7296
7397 public URI projectUri () {
74- throw new RuntimeException ("TODO" );
98+ // TODO cache?
99+ return config .fetchProjectURI ();
75100 }
76101
102+ /**
103+ * Quick start method that sets up global OpenTelemetry with this Braintrust. <br>
104+ * <br>
105+ * If you're looking for more options for configuring Braintrust/OpenTelemetry, consult the
106+ * `enable` method.
107+ */
77108 public OpenTelemetry openTelemetryCreate () {
78- throw new RuntimeException ( "TODO" );
109+ return openTelemetryCreate ( true );
79110 }
80111
112+ /**
113+ * Quick start method that sets up OpenTelemetry with this Braintrust. <br>
114+ * <br>
115+ * If you're looking for more options for configuring Braintrust and OpenTelemetry, consult the
116+ * `enable` method.
117+ */
81118 public OpenTelemetry openTelemetryCreate (boolean registerGlobal ) {
82- throw new RuntimeException ( "TODO" );
119+ return BraintrustTracing . of ( this . config , registerGlobal );
83120 }
84121
122+ /**
123+ * Add braintrust to existing open telemetry builders <br>
124+ * <br>
125+ * This method provides the most options for configuring Braintrust and OpenTelemetry. If you're
126+ * looking for a more user-friendly setup, consult the `quickstart` methods. <br>
127+ * <br>
128+ * NOTE: if your otel setup does not have any particular builder, pass an instance of the
129+ * default provider builder. E.g. `SdkMeterProvider.builder()` <br>
130+ * <br>
131+ * NOTE: This method should only be invoked once. Enabling Braintrust multiple times is
132+ * unsupported and may lead to undesired behavior
133+ */
85134 public void openTelemetryEnable (
86135 @ Nonnull SdkTracerProviderBuilder tracerProviderBuilder ,
87136 @ Nonnull SdkLoggerProviderBuilder loggerProviderBuilder ,
88137 @ Nonnull SdkMeterProviderBuilder meterProviderBuilder ) {
89- throw new RuntimeException ("TODO" );
138+ BraintrustTracing .enable (
139+ this .config , tracerProviderBuilder , loggerProviderBuilder , meterProviderBuilder );
140+ }
141+
142+ /** Create a new eval builder */
143+ public <INPUT , OUTPUT > Eval .Builder <INPUT , OUTPUT > evalBuilder () {
144+ return (Eval .Builder <INPUT , OUTPUT >)
145+ Eval .builder ().config (this .config ).apiClient (this .apiClient );
90146 }
91147}
0 commit comments