diff --git a/.changeset/evals-otel-compat.md b/.changeset/evals-otel-compat.md new file mode 100644 index 0000000000..0a31940bc1 --- /dev/null +++ b/.changeset/evals-otel-compat.md @@ -0,0 +1,5 @@ +--- +"@browserbasehq/stagehand-evals": minor +--- + +Adds OpenTelemetry (OTEL) compatibility to the evals CLI diff --git a/packages/evals/cli.ts b/packages/evals/cli.ts index 575f210eb9..a607042db5 100644 --- a/packages/evals/cli.ts +++ b/packages/evals/cli.ts @@ -86,6 +86,15 @@ const args = process.argv.slice(2); } catch { // ignore } + try { + const { resolveTraceTransport } = await import("./framework/langsmith.js"); + if (resolveTraceTransport() === "otel") { + try { + const { shutdownTracing } = await import("./framework/otel.js"); + await shutdownTracing(); + } catch {} + } + } catch {} process.exit(code); }; process.on("SIGINT", () => void handleSignal("SIGINT")); diff --git a/packages/evals/tui/commands/doctor.ts b/packages/evals/tui/commands/doctor.ts index ec5affbc42..bd231036a2 100644 --- a/packages/evals/tui/commands/doctor.ts +++ b/packages/evals/tui/commands/doctor.ts @@ -308,6 +308,10 @@ function renderHuman(report: DoctorReport): void { }`, ); console.log(keyRow("BRAINTRUST_API_KEY", r.keys.braintrust, "(needed for `experiments`)")); + const langsmithLabel = r.keys.langsmith.var ?? "LANGSMITH_API_KEY"; + console.log( + keyRow(langsmithLabel, r.keys.langsmith, "(optional; LANGCHAIN_API_KEY also supported)"), + ); console.log(""); console.log(` ${bold("Status")}`); diff --git a/packages/evals/tui/welcomeStatus.ts b/packages/evals/tui/welcomeStatus.ts index 1e49466778..7337330ac2 100644 --- a/packages/evals/tui/welcomeStatus.ts +++ b/packages/evals/tui/welcomeStatus.ts @@ -32,6 +32,11 @@ export type GoogleKeyEntry = ProviderKeyEntry & { var: "GOOGLE_GENERATIVE_AI_API_KEY" | "GEMINI_API_KEY" | null; }; +export type LangSmithKeyEntry = ProviderKeyEntry & { + /** Which env var actually held the value, or null if missing. */ + var: "LANGSMITH_API_KEY" | "LANGCHAIN_API_KEY" | null; +}; + export type BrowserbaseKeyEntry = { apiKey: KeyState; projectId: KeyState; @@ -45,6 +50,7 @@ export type EnvSnapshot = { google: GoogleKeyEntry; browserbase: BrowserbaseKeyEntry; braintrust: ProviderKeyEntry; + langsmith: LangSmithKeyEntry; }; // --------------------------------------------------------------------------- @@ -104,6 +110,16 @@ function providerEntry(name: string): ProviderKeyEntry { }; } +function langSmithEntry(): LangSmithKeyEntry { + const primary = providerEntry("LANGSMITH_API_KEY"); + if (primary.state === "set") return { ...primary, var: "LANGSMITH_API_KEY" }; + const fallback = providerEntry("LANGCHAIN_API_KEY"); + return { + ...fallback, + var: fallback.state === "set" ? "LANGCHAIN_API_KEY" : null, + }; +} + function googleEntry(): GoogleKeyEntry { // Prefer the canonical GOOGLE_GENERATIVE_AI_API_KEY name; fall back to GEMINI_API_KEY. const a = resolveKey("GOOGLE_GENERATIVE_AI_API_KEY"); @@ -166,6 +182,7 @@ export function snapshotEnv(): EnvSnapshot { google: googleEntry(), browserbase: browserbaseEntry(), braintrust: providerEntry("BRAINTRUST_API_KEY"), + langsmith: langSmithEntry(), }; }