-
Notifications
You must be signed in to change notification settings - Fork 9
docs(skills): point sdk-install guides at per-language install pages #358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Jesse Seldess (jseldess)
merged 2 commits into
main
from
sdk-install-language-specific-urls
Sep 10, 2026
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,155 +1,10 @@ | ||
| # C# SDK Install | ||
|
|
||
| Reference guide for installing the Braintrust C# SDK. | ||
| **Read https://www.braintrust.dev/docs/sdks/csharp/install-and-instrument and follow it.** | ||
|
|
||
| - SDK repo: https://github.com/braintrustdata/braintrust-sdk-dotnet | ||
| - NuGet: https://www.nuget.org/packages/Braintrust.Sdk | ||
| - Requires .NET 8.0+ | ||
|
|
||
| ## Find the latest version of the SDK | ||
|
|
||
| Look up the latest version from NuGet **without installing anything**. Do not guess -- use a read-only query so the environment stays unchanged until you write the version into the project file. | ||
|
|
||
| ```bash | ||
| dotnet package search Braintrust.Sdk --exact-match | ||
| ``` | ||
|
|
||
| Then install that version (the latest published release): | ||
|
|
||
| ### .NET CLI | ||
|
|
||
| ```bash | ||
| dotnet add package Braintrust.Sdk --version <VERSION> | ||
| ``` | ||
|
|
||
| ### Or add to .csproj | ||
|
|
||
| ```xml | ||
| <ItemGroup> | ||
| <PackageReference Include="Braintrust.Sdk" Version="<VERSION>" /> | ||
| </ItemGroup> | ||
| ``` | ||
|
|
||
| ## Initialize the SDK | ||
|
|
||
| ```csharp | ||
| using Braintrust.Sdk; | ||
| using Braintrust.Sdk.Config; | ||
|
|
||
| var apiKey = Environment.GetEnvironmentVariable("BRAINTRUST_API_KEY"); | ||
| Braintrust? braintrust = null; | ||
| System.Diagnostics.ActivitySource? activitySource = null; | ||
|
|
||
| if (!string.IsNullOrEmpty(apiKey)) | ||
| { | ||
| // Set the project name in code (do NOT require an env var for project name). | ||
| var config = BraintrustConfig.Of( | ||
| ("BRAINTRUST_API_KEY", apiKey), | ||
| ("BRAINTRUST_DEFAULT_PROJECT_NAME", "my-project") | ||
| ); | ||
|
|
||
| braintrust = Braintrust.Get(config); | ||
| activitySource = braintrust.GetActivitySource(); | ||
| } | ||
| ``` | ||
|
|
||
| `Braintrust.Get(config)` is the main entry point. The SDK requires an API key to be present, so initialize Braintrust conditionally and run the application normally when `BRAINTRUST_API_KEY` is missing. `GetActivitySource()` returns the `System.Diagnostics.ActivitySource` used to create spans. | ||
|
|
||
| ## Install instrumentation | ||
|
|
||
| The C# SDK instruments LLM clients by wrapping them. Only instrument clients that are actually present in the project. | ||
|
|
||
| ### OpenAI (`OpenAI` NuGet package) | ||
|
|
||
| ```bash | ||
| dotnet add package OpenAI | ||
| ``` | ||
|
|
||
| Create an instrumented OpenAI client: | ||
| That page is the source of truth for installing and instrumenting the Braintrust C# SDK -- package installation, initialization, and the supported LLM client wrappers. Do not install or instrument from remembered snippets; they go stale. | ||
|
|
||
| ```csharp | ||
| using Braintrust.Sdk; | ||
| using Braintrust.Sdk.Config; | ||
| using Braintrust.Sdk.Instrumentation.OpenAI; | ||
| Supporting references, if you need them: | ||
|
|
||
| var btApiKey = Environment.GetEnvironmentVariable("BRAINTRUST_API_KEY"); | ||
| var openAIApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY"); | ||
|
|
||
| if (!string.IsNullOrEmpty(btApiKey) && !string.IsNullOrEmpty(openAIApiKey)) | ||
| { | ||
| var config = BraintrustConfig.Of( | ||
| ("BRAINTRUST_API_KEY", btApiKey), | ||
| ("BRAINTRUST_DEFAULT_PROJECT_NAME", "my-project") | ||
| ); | ||
| var braintrust = Braintrust.Get(config); | ||
| var activitySource = braintrust.GetActivitySource(); | ||
| var client = BraintrustOpenAI.WrapOpenAI(activitySource, openAIApiKey); | ||
|
|
||
| // Optional: create a root activity so you can generate a permalink. | ||
| using var activity = activitySource.StartActivity("braintrust-openai-example"); | ||
|
|
||
| var chatClient = client.GetChatClient("gpt-5-mini"); | ||
| var response = await chatClient.CompleteChatAsync( | ||
| new ChatMessage[] | ||
| { | ||
| new SystemChatMessage("You are a helpful assistant."), | ||
| new UserChatMessage("What is the capital of France?") | ||
| } | ||
| ); | ||
|
|
||
| if (activity != null) | ||
| { | ||
| var projectUri = await braintrust.GetProjectUriAsync(); | ||
| var url = $"{projectUri}/logs?r={activity.TraceId}&s={activity.SpanId}"; | ||
| Console.WriteLine($"View your data in Braintrust: {url}"); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Custom spans | ||
|
|
||
| For business logic that isn't an LLM call, create spans manually with the `ActivitySource`: | ||
|
|
||
| ```csharp | ||
| using (var activity = activitySource.StartActivity("my-operation")) | ||
| { | ||
| activity?.SetTag("some.attribute", "value"); | ||
| // LLM calls inside here are automatically nested under this span | ||
| } | ||
| ``` | ||
|
|
||
| ## Run the application | ||
|
|
||
| Try to figure out how to run the application from the project structure: | ||
|
|
||
| - **dotnet run**: `dotnet run` or `dotnet run --project path/to/Project.csproj` | ||
| - **ASP.NET**: `dotnet run` (typically starts Kestrel) | ||
| - **Published app**: `dotnet path/to/app.dll` | ||
| - **Visual Studio / Rider**: run from IDE | ||
|
|
||
| If you can't determine how to run the app, ask the user. | ||
|
|
||
| ## Generate a permalink (required) | ||
|
|
||
| The installer must produce a permalink to the emitted trace/logs in its final output. | ||
|
|
||
| In .NET, the most reliable permalink can be generated from the root Activity's TraceId/SpanId: | ||
|
|
||
| ```csharp | ||
| if (braintrust != null && activitySource != null) | ||
| { | ||
| using var activity = activitySource.StartActivity("braintrust-install-verify"); | ||
| if (activity != null) | ||
| { | ||
| // Perform a real operation that triggers LLM spans / instrumentation here. | ||
|
|
||
| var projectUri = await braintrust.GetProjectUriAsync(); | ||
| var url = $"{projectUri}/logs?r={activity.TraceId}&s={activity.SpanId}"; | ||
| Console.WriteLine($"View your data in Braintrust: {url}"); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The final assistant response must include the printed URL. | ||
|
|
||
| If the SDK-generated URL is not available, construct the permalink manually using the URL format documented in `braintrust-url-formats.md` as described in the agent task (Step 5). | ||
| - SDK repo: https://github.com/braintrustdata/braintrust-sdk-dotnet | ||
| - NuGet: https://www.nuget.org/packages/Braintrust.Sdk | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,151 +1,10 @@ | ||
| # Go SDK Install | ||
|
|
||
| Reference guide for installing the Braintrust Go SDK. | ||
| **Read https://www.braintrust.dev/docs/sdks/go/install-and-instrument and follow it.** | ||
|
|
||
| - SDK repo: https://github.com/braintrustdata/braintrust-sdk-go | ||
| - pkg.go.dev: https://pkg.go.dev/github.com/braintrustdata/braintrust-sdk-go | ||
| - Requires Go 1.22+ | ||
|
|
||
| ## Install the SDK | ||
|
|
||
| Install the latest Braintrust SDK. Do not hard-pin the SDK version unless the user asks -- `go get` without a version suffix is fine and will record whatever version `go mod tidy` resolves. | ||
|
|
||
| ```bash | ||
| go get github.com/braintrustdata/braintrust-sdk-go | ||
| ``` | ||
|
|
||
| If you need to know what the latest version is: | ||
|
|
||
| ```bash | ||
| go list -m -versions github.com/braintrustdata/braintrust-sdk-go | ||
| ``` | ||
|
|
||
| **Note:** Orchestrion, the build-time instrumentation tool described below, **must** be pinned to an exact version. That requirement is separate from the SDK itself. | ||
|
|
||
| ## Instrument the application | ||
|
|
||
| **You must read https://www.braintrust.dev/docs/instrument/trace-llm-calls before instrumenting anything.** That page is the source of truth for supported providers and setup, and may have changed since this guide was written. | ||
|
|
||
| ### Prefer automatic instrumentation (Orchestrion) | ||
|
|
||
| **Automatic instrumentation via [Orchestrion](https://github.com/DataDog/orchestrion) is the recommended path and should be used whenever possible.** It injects tracing at compile time with no wrapper code in the application, so LLM client calls are traced automatically across your codebase and third-party code. | ||
|
|
||
| Manual span/wrapper code should only be used as a **last resort** -- e.g. for bespoke business-logic spans, or when a provider isn't yet supported by the Orchestrion contrib packages. Don't reach for manual tracing before confirming Orchestrion can do the job. | ||
|
|
||
| ### Quick start | ||
|
|
||
| Every Go project needs OpenTelemetry setup and a Braintrust client. | ||
|
|
||
| ```go | ||
| package main | ||
|
|
||
| import ( | ||
| "log" | ||
|
|
||
| "github.com/braintrustdata/braintrust-sdk-go" | ||
| "go.opentelemetry.io/otel" | ||
| "go.opentelemetry.io/otel/sdk/trace" | ||
| ) | ||
|
|
||
| func main() { | ||
| tp := trace.NewTracerProvider() | ||
| otel.SetTracerProvider(tp) | ||
|
|
||
| _, err := braintrust.New(tp, braintrust.WithProject("my-project")) | ||
| if err != nil { | ||
| log.Fatal(err) | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| `braintrust.New` reads `BRAINTRUST_API_KEY` from the environment automatically. | ||
|
|
||
| ### Requirement: persist Orchestrion into the normal build/run path | ||
|
|
||
| Auto-instrumentation requires the project to be built and run with Orchestrion. A one-off `orchestrion go build` during verification is **not enough** if the next developer, CI job, or deploy will go back to plain `go build` / `go run`. | ||
|
|
||
| **1. Resolve and pin an exact Orchestrion version:** | ||
|
|
||
| Orchestrion is a build-time dependency that modifies the Go toolchain, so it **must** be pinned to an exact version for reproducible builds -- this is different from the Braintrust SDK itself. | ||
|
|
||
| ```bash | ||
| go list -m -versions github.com/DataDog/orchestrion | ||
| go install github.com/DataDog/orchestrion@vX.Y.Z | ||
| ``` | ||
|
|
||
| Do not use `@latest`. Prefer the newest version that is compatible with the project's existing `go` / `toolchain` version. If Orchestrion would require bumping the project's Go version or toolchain, ask the user before making that change. | ||
|
|
||
| **2. Create `orchestrion.tool.go` in the module root (the same directory as `go.mod`):** | ||
| That page is the source of truth for installing and instrumenting the Braintrust Go SDK -- supported providers, their `trace/contrib/` import paths, and build-time instrumentation setup. Do not install or instrument from remembered snippets; they go stale. | ||
|
|
||
| Prefer importing only the integrations the project actually uses. Use `trace/contrib/all` only if provider detection is genuinely unclear or the project uses many supported integrations. | ||
| Supporting references, if you need them: | ||
|
|
||
| To instrument all supported providers: | ||
|
|
||
| ```go | ||
| //go:build tools | ||
|
|
||
| package main | ||
|
|
||
| import ( | ||
| _ "github.com/DataDog/orchestrion" | ||
| _ "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/all" | ||
| ) | ||
| ``` | ||
|
|
||
| Or import only the integrations the project actually uses: | ||
|
|
||
| ```go | ||
| //go:build tools | ||
|
|
||
| package main | ||
|
|
||
| import ( | ||
| _ "github.com/DataDog/orchestrion" | ||
| _ "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/anthropic" // anthropic-sdk-go | ||
| _ "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/genai" // Google GenAI | ||
| _ "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/github.com/sashabaranov/go-openai" // sashabaranov/go-openai | ||
| _ "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/langchaingo" // LangChainGo | ||
| _ "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/openai" // openai-go | ||
| ) | ||
| ``` | ||
|
|
||
| Then run `go mod tidy` so the exact Orchestrion and contrib versions are recorded in `go.mod` / `go.sum`. | ||
|
|
||
| **3. Persist Orchestrion into the project's actual workflow:** | ||
|
|
||
| Update the command the project already expects developers or CI to use: | ||
|
|
||
| - `Makefile` / `justfile` / shell scripts: change `go build`, `go run`, and `go test` invocations to `orchestrion go ...` where appropriate. | ||
| - `Dockerfile`: change build steps to use Orchestrion. | ||
| - Bootstrap / CI / devcontainer setup: if the repo already has a checked-in way to install required tooling, add Orchestrion there too so future users do not hit `orchestrion: command not found`. | ||
| - Repo-local env/config files: if the project already uses a checked-in mechanism for env vars, set `GOFLAGS="-toolexec=orchestrion toolexec"` there. | ||
|
|
||
| A shell-local `export GOFLAGS=...` in the current terminal does **not** satisfy this requirement by itself, because it will not help the next user or CI run. | ||
|
|
||
| If you add `orchestrion.tool.go` but do **not** modify any persisted build/run path, treat the installation as incomplete. | ||
|
|
||
| **4. Verify using the same persisted command:** | ||
|
|
||
| After wiring Orchestrion into the normal workflow, run that exact command and confirm traces are emitted. Do not verify with a custom one-off command that the project will not use later. | ||
|
|
||
| After this, LLM client calls are automatically traced with no application wrapper code. | ||
|
|
||
| ### Supported providers | ||
|
|
||
| For the current list of supported providers and their `trace/contrib/` import paths, see https://www.braintrust.dev/docs/instrument/trace-llm-calls. | ||
|
|
||
| ## Run the application | ||
|
|
||
| Prefer the project's existing build/run entrypoint, and make sure that entrypoint now goes through Orchestrion. | ||
|
|
||
| Try to figure out how the project is normally run from the project structure: | ||
|
|
||
| - **Makefile / justfile / scripts**: prefer `make run`, `just run`, or the existing repo script if present | ||
| - **go run**: if the project is normally run directly, update that path to `orchestrion go run .` or `orchestrion go run ./cmd/myapp` | ||
| - **Docker**: check for a `Dockerfile` or container build script | ||
|
|
||
| If you can't determine how the app is supposed to be built or run in normal use, ask the user before proceeding. | ||
|
|
||
| ## Generate a permalink (required) | ||
|
|
||
| Follow the permalink generation steps in the agent task (Step 5). Use the project name you configured in code above. | ||
| - SDK repo: https://github.com/braintrustdata/braintrust-sdk-go | ||
| - pkg.go.dev: https://pkg.go.dev/github.com/braintrustdata/braintrust-sdk-go |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
bt setup instrumentlaunches a sandboxed or otherwise web-restricted coding agent, this stub leaves it without installation instructions. The setup prefetch only downloads URLs recognized bysrc/setup/docs.rs::workflow_from_urlas/docs/instrument/...; these new/docs/sdks/...pages are excluded, whilesdk_install_docs::write_sdk_install_docsmerely writes this link into the temporary directory. Thus the CLI can report that the latest docs were fetched successfully and then require a second network access the agent may not have, causing installation to abort or be guessed. Add these language pages to the CLI's prefetch set and point the guides at the downloaded copies.Useful? React with 👍 / 👎.