Skip to content

Commit 5a7dc09

Browse files
committed
api outline
1 parent 3e3afe5 commit 5a7dc09

6 files changed

Lines changed: 201 additions & 7 deletions

File tree

‎examples/src/main/java/dev/braintrust/examples/OpenAIInstrumentationExample.java‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
import com.openai.models.ChatModel;
66
import com.openai.models.chat.completions.ChatCompletionCreateParams;
77
import com.openai.models.chat.completions.ChatCompletionStreamOptions;
8-
import dev.braintrust.config.BraintrustConfig;
8+
import dev.braintrust.Braintrust;
99
import dev.braintrust.instrumentation.openai.BraintrustOpenAI;
10-
import dev.braintrust.trace.BraintrustTracing;
1110

1211
/** Basic OTel + OpenAI instrumentation example */
1312
public class OpenAIInstrumentationExample {
@@ -16,20 +15,23 @@ public static void main(String[] args) throws Exception {
1615
System.err.println(
1716
"\nWARNING envar OPEN_AI_API_KEY not found. This example will likely fail.\n");
1817
}
19-
var braintrustConfig = BraintrustConfig.fromEnvironment();
20-
var openTelemetry = BraintrustTracing.of(braintrustConfig, true);
21-
var tracer = BraintrustTracing.getTracer(openTelemetry);
18+
var braintrust = Braintrust.get();
19+
var openTelemetry = braintrust.openTelemetryCreate();
2220
OpenAIClient openAIClient =
2321
BraintrustOpenAI.wrapOpenAI(openTelemetry, OpenAIOkHttpClient.fromEnv());
24-
var rootSpan = tracer.spanBuilder("openai-java-instrumentation-example").startSpan();
22+
var rootSpan =
23+
openTelemetry
24+
.getTracer("my-instrumentation")
25+
.spanBuilder("openai-java-instrumentation-example")
26+
.startSpan();
2527
try (var ignored = rootSpan.makeCurrent()) {
2628
chatCompletionsExample(openAIClient);
2729
// chatCompletionsStreamingExample(openAIClient);
2830
} finally {
2931
rootSpan.end();
3032
}
3133
var url =
32-
braintrustConfig.fetchProjectURI()
34+
braintrust.projectUri()
3335
+ "/logs?r=%s&s=%s"
3436
.formatted(
3537
rootSpan.getSpanContext().getTraceId(),
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package dev.braintrust.examples;
2+
3+
import static dev.braintrust.instrumentation.openai.BraintrustOpenAI.buildChatCompletionsPrompt;
4+
import static dev.braintrust.instrumentation.openai.BraintrustOpenAI.wrapOpenAI;
5+
6+
import com.openai.client.OpenAIClient;
7+
import com.openai.client.okhttp.OpenAIOkHttpClient;
8+
import dev.braintrust.Braintrust;
9+
import dev.braintrust.prompt.BraintrustPromptLoader.PromptLoadRequest;
10+
11+
public class PromptFetchingExample {
12+
public static void main(String... args) {
13+
if (null == System.getenv("OPENAI_API_KEY")) {
14+
System.err.println(
15+
"\nWARNING envar OPEN_AI_API_KEY not found. This example will likely fail.\n");
16+
}
17+
var braintrust = Braintrust.get();
18+
var openTelemetry = braintrust.openTelemetryCreate();
19+
20+
OpenAIClient openAIClient = wrapOpenAI(openTelemetry, OpenAIOkHttpClient.fromEnv());
21+
22+
{ // simple example
23+
var prompt = braintrust.promptLoader().load("my-prompt-slug");
24+
var response =
25+
openAIClient.chat().completions().create(buildChatCompletionsPrompt(prompt));
26+
System.out.println("got response: %s".formatted(response));
27+
}
28+
{ // more complex prompt options
29+
var prompt =
30+
braintrust
31+
.promptLoader()
32+
.load(
33+
PromptLoadRequest.builder()
34+
.projectName("my-project")
35+
.promptSlug("my-prompt-slug")
36+
.version("5878bd218351fb8e")
37+
.defaults("model", "gpt-3.5-turbo")
38+
.build());
39+
var response =
40+
openAIClient.chat().completions().create(buildChatCompletionsPrompt(prompt));
41+
System.out.println("got response: %s".formatted(response));
42+
}
43+
44+
System.out.println(
45+
"\n\n Example complete! View your data in Braintrust: %s\n"
46+
.formatted(braintrust.projectUri() + "/logs"));
47+
}
48+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package dev.braintrust;
2+
3+
import dev.braintrust.api.BraintrustApiClient;
4+
import dev.braintrust.config.BraintrustConfig;
5+
import dev.braintrust.prompt.BraintrustPromptLoader;
6+
import io.opentelemetry.api.OpenTelemetry;
7+
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
8+
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
9+
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
10+
import java.net.URI;
11+
import javax.annotation.Nonnull;
12+
import lombok.Getter;
13+
import lombok.experimental.Accessors;
14+
15+
/**
16+
* Main entry point for the Braintrust SDK.
17+
*
18+
* <p>This class provides access to all Braintrust functionality. Most users will interact with a
19+
* singleton instance via {@link #get()}, though you can create independent instances if needed.
20+
*
21+
* <p>The Braintrust instance also provides methods for enabling Braintrust in open telemetry
22+
* builders.
23+
*
24+
* <p>Additionally, vendor-specific instrumentation or functionality is provided by {@code
25+
* Braintrust<Vendor Name>}. E.g. {@code BraintrustOpenAI}, {@code BraintrustAnthropic}, etc.
26+
*
27+
* @see #get()
28+
* @see BraintrustConfig
29+
* @see #openTelemetryCreate()
30+
* @see #openTelemetryEnable(SdkTracerProviderBuilder, SdkLoggerProviderBuilder,
31+
* SdkMeterProviderBuilder)
32+
*/
33+
public class Braintrust {
34+
/**
35+
* get or create the global braintrust instance. Most users will want to use this method to
36+
* access the Braintrust SDK.
37+
*/
38+
public static Braintrust get() {
39+
throw new RuntimeException("TODO");
40+
}
41+
42+
/** get or create the global braintrust instance from the given config */
43+
public static Braintrust get(BraintrustConfig config) {
44+
throw new RuntimeException("TODO");
45+
}
46+
47+
/** Create a new Braintrust instance from the given config */
48+
public static Braintrust of(BraintrustConfig config) {
49+
throw new RuntimeException("TODO");
50+
}
51+
52+
@Getter
53+
@Accessors(fluent = true)
54+
private final BraintrustConfig config;
55+
56+
@Getter
57+
@Accessors(fluent = true)
58+
private final BraintrustApiClient apiClient;
59+
60+
@Getter
61+
@Accessors(fluent = true)
62+
private final BraintrustPromptLoader promptLoader;
63+
64+
private Braintrust(
65+
BraintrustConfig config,
66+
BraintrustApiClient apiClient,
67+
BraintrustPromptLoader promptLoader) {
68+
this.config = config;
69+
this.apiClient = apiClient;
70+
this.promptLoader = promptLoader;
71+
}
72+
73+
public URI projectUri() {
74+
throw new RuntimeException("TODO");
75+
}
76+
77+
public OpenTelemetry openTelemetryCreate() {
78+
throw new RuntimeException("TODO");
79+
}
80+
81+
public OpenTelemetry openTelemetryCreate(boolean registerGlobal) {
82+
throw new RuntimeException("TODO");
83+
}
84+
85+
public void openTelemetryEnable(
86+
@Nonnull SdkTracerProviderBuilder tracerProviderBuilder,
87+
@Nonnull SdkLoggerProviderBuilder loggerProviderBuilder,
88+
@Nonnull SdkMeterProviderBuilder meterProviderBuilder) {
89+
throw new RuntimeException("TODO");
90+
}
91+
}

‎src/main/java/dev/braintrust/instrumentation/openai/BraintrustOpenAI.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package dev.braintrust.instrumentation.openai;
22

33
import com.openai.client.OpenAIClient;
4+
import com.openai.models.chat.completions.ChatCompletionCreateParams;
45
import dev.braintrust.instrumentation.openai.otel.OpenAITelemetry;
6+
import dev.braintrust.prompt.BraintrustPrompt;
57
import io.opentelemetry.api.OpenTelemetry;
68

79
/** Braintrust OpenAI client instrumentation. */
@@ -21,4 +23,8 @@ public static OpenAIClient wrapOpenAI(OpenTelemetry openTelemetry, OpenAIClient
2123
.wrap(openAIClient);
2224
}
2325
}
26+
27+
public static ChatCompletionCreateParams buildChatCompletionsPrompt(BraintrustPrompt prompt) {
28+
throw new RuntimeException("TODO");
29+
}
2430
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package dev.braintrust.prompt;
2+
3+
public class BraintrustPrompt {
4+
// TODO
5+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package dev.braintrust.prompt;
2+
3+
import dev.braintrust.config.BraintrustConfig;
4+
import java.util.Map;
5+
import javax.annotation.Nonnull;
6+
import javax.annotation.Nullable;
7+
import lombok.Builder;
8+
9+
public class BraintrustPromptLoader {
10+
public static BraintrustPromptLoader of(BraintrustConfig config) {
11+
throw new RuntimeException("TODO");
12+
}
13+
14+
public BraintrustPrompt load(String promptSlug) {
15+
PromptLoadRequest.builder().promptSlug(promptSlug);
16+
throw new RuntimeException("TODO");
17+
}
18+
19+
public BraintrustPrompt load(PromptLoadRequest promptLoadRequest) {
20+
throw new RuntimeException("TODO");
21+
}
22+
23+
@Builder
24+
public static class PromptLoadRequest {
25+
private @Nonnull String promptSlug;
26+
private @Nullable String projectName;
27+
private @Nullable String version;
28+
private @Nonnull @Builder.Default Map<String, String> defaults = Map.of();
29+
30+
public static class PromptLoadRequestBuilder {
31+
public PromptLoadRequestBuilder defaults(String... keyValuePairDefaults) {
32+
throw new RuntimeException("TODO");
33+
}
34+
}
35+
}
36+
37+
// TODO: what default values are allowed? Do we want to use an enum or is that too constrictive?
38+
public static class PromptLoadDefaultKeys {
39+
public static String MODEL = "model";
40+
public static String TEMPERATURE = "temperature";
41+
}
42+
}

0 commit comments

Comments
 (0)