@braintrust/pi-extension 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -108,6 +108,8 @@ Example:
108
108
  | `additional_metadata` | `BRAINTRUST_ADDITIONAL_METADATA` | `{}` |
109
109
  | `log_file` | `BRAINTRUST_LOG_FILE` | unset |
110
110
  | `state_dir` | `BRAINTRUST_STATE_DIR` | `~/.pi/agent/state/braintrust-pi-extension` |
111
+ | `show_ui` | `BRAINTRUST_SHOW_UI` | `true` |
112
+ | `show_trace_link` | `BRAINTRUST_SHOW_TRACE_LINK` | `true` |
111
113
  | `parent_span_id` | `PI_PARENT_SPAN_ID` | unset |
112
114
  | `root_span_id` | `PI_ROOT_SPAN_ID` | unset |
113
115
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@braintrust/pi-extension",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Braintrust extension for pi. Includes automatic tracing for pi sessions, turns, LLM calls, and tool executions to Braintrust.",
5
5
  "keywords": [
6
6
  "braintrust",
@@ -16,6 +16,8 @@ const ENV_KEYS = [
16
16
  "BRAINTRUST_DEBUG",
17
17
  "BRAINTRUST_LOG_FILE",
18
18
  "BRAINTRUST_STATE_DIR",
19
+ "BRAINTRUST_SHOW_UI",
20
+ "BRAINTRUST_SHOW_TRACE_LINK",
19
21
  "PI_PARENT_SPAN_ID",
20
22
  "PI_ROOT_SPAN_ID",
21
23
  "BRAINTRUST_ADDITIONAL_METADATA",
@@ -257,6 +259,53 @@ describe("loadConfig", () => {
257
259
  });
258
260
  });
259
261
 
262
+ it("defaults showUi and showTraceLink to true", () => {
263
+ const home = makeTempDir("pi-extension-home-");
264
+ process.env.HOME = home;
265
+ process.env.BRAINTRUST_STATE_DIR = join(home, "state");
266
+
267
+ const config = loadConfig(home);
268
+
269
+ expect(config.showUi).toBe(true);
270
+ expect(config.showTraceLink).toBe(true);
271
+ });
272
+
273
+ it("applies show_ui and show_trace_link from config files", () => {
274
+ const home = makeTempDir("pi-extension-home-");
275
+ const cwd = join(home, "workspace");
276
+
277
+ process.env.HOME = home;
278
+ process.env.BRAINTRUST_STATE_DIR = join(home, "state");
279
+
280
+ writeJson(join(home, ".pi", "agent", "braintrust.json"), {
281
+ show_ui: false,
282
+ });
283
+
284
+ const config = loadConfig(cwd);
285
+
286
+ expect(config.showUi).toBe(false);
287
+ expect(config.showTraceLink).toBe(true);
288
+ });
289
+
290
+ it("overrides show_ui and show_trace_link from environment variables", () => {
291
+ const home = makeTempDir("pi-extension-home-");
292
+ const cwd = join(home, "workspace");
293
+
294
+ process.env.HOME = home;
295
+ process.env.BRAINTRUST_STATE_DIR = join(home, "state");
296
+ process.env.BRAINTRUST_SHOW_UI = "true";
297
+ process.env.BRAINTRUST_SHOW_TRACE_LINK = "false";
298
+
299
+ writeJson(join(home, ".pi", "agent", "braintrust.json"), {
300
+ show_ui: false,
301
+ });
302
+
303
+ const config = loadConfig(cwd);
304
+
305
+ expect(config.showUi).toBe(true);
306
+ expect(config.showTraceLink).toBe(false);
307
+ });
308
+
260
309
  it("warns when tracing is enabled without an API key", () => {
261
310
  const home = makeTempDir("pi-extension-home-");
262
311
  process.env.HOME = home;
@@ -290,6 +339,8 @@ describe("createLogger", () => {
290
339
  additionalMetadata: {},
291
340
  parentSpanId: undefined,
292
341
  rootSpanId: undefined,
342
+ showUi: true,
343
+ showTraceLink: true,
293
344
  configIssues: [],
294
345
  };
295
346
 
package/src/config.ts CHANGED
@@ -218,6 +218,17 @@ function applyConfig(
218
218
  );
219
219
  if (additionalMetadata !== undefined) target.additionalMetadata = additionalMetadata;
220
220
 
221
+ const showUi = validateOptionalBoolean(source.show_ui, issues, path, "show_ui");
222
+ if (showUi !== undefined) target.showUi = showUi;
223
+
224
+ const showTraceLink = validateOptionalBoolean(
225
+ source.show_trace_link,
226
+ issues,
227
+ path,
228
+ "show_trace_link",
229
+ );
230
+ if (showTraceLink !== undefined) target.showTraceLink = showTraceLink;
231
+
221
232
  return {
222
233
  parentSpanConfigured: parentSpanId !== undefined,
223
234
  rootSpanConfigured: rootSpanId !== undefined,
@@ -238,6 +249,8 @@ export function loadConfig(cwd = process.cwd()): TraceConfig {
238
249
  additionalMetadata: {},
239
250
  parentSpanId: undefined,
240
251
  rootSpanId: undefined,
252
+ showUi: true,
253
+ showTraceLink: true,
241
254
  configIssues: [],
242
255
  };
243
256
 
@@ -344,6 +357,22 @@ export function loadConfig(cwd = process.cwd()): TraceConfig {
344
357
  );
345
358
  if (envStateDir !== undefined) config.stateDir = envStateDir;
346
359
 
360
+ const envShowUi = validateOptionalBoolean(
361
+ process.env.BRAINTRUST_SHOW_UI,
362
+ config.configIssues,
363
+ "BRAINTRUST_SHOW_UI",
364
+ "BRAINTRUST_SHOW_UI",
365
+ );
366
+ if (envShowUi !== undefined) config.showUi = envShowUi;
367
+
368
+ const envShowTraceLink = validateOptionalBoolean(
369
+ process.env.BRAINTRUST_SHOW_TRACE_LINK,
370
+ config.configIssues,
371
+ "BRAINTRUST_SHOW_TRACE_LINK",
372
+ "BRAINTRUST_SHOW_TRACE_LINK",
373
+ );
374
+ if (envShowTraceLink !== undefined) config.showTraceLink = envShowTraceLink;
375
+
347
376
  const envParentSpanId = validateOptionalNonEmptyString(
348
377
  process.env.PI_PARENT_SPAN_ID,
349
378
  config.configIssues,
package/src/index.test.ts CHANGED
@@ -22,6 +22,8 @@ const mockState = vi.hoisted(() => ({
22
22
  additionalMetadata: {},
23
23
  parentSpanId: undefined,
24
24
  rootSpanId: undefined,
25
+ showUi: true,
26
+ showTraceLink: true,
25
27
  configIssues: [] as Array<{ path: string; message: string; severity: "error" | "warning" }>,
26
28
  },
27
29
  }));
@@ -117,6 +119,8 @@ beforeEach(() => {
117
119
  additionalMetadata: {},
118
120
  parentSpanId: undefined,
119
121
  rootSpanId: undefined,
122
+ showUi: true,
123
+ showTraceLink: true,
120
124
  configIssues: [],
121
125
  };
122
126
  vi.resetModules();
@@ -406,4 +410,49 @@ describe("braintrustPiExtension", () => {
406
410
  undefined,
407
411
  );
408
412
  });
413
+
414
+ it("hides all UI when showUi is false", async () => {
415
+ mockState.config.showUi = false;
416
+
417
+ const { emit } = await createHarness();
418
+
419
+ await emit("session_start");
420
+ await emit("before_agent_start", {
421
+ prompt: "Inspect the package",
422
+ images: [],
423
+ });
424
+
425
+ const statusUpdates = mockState.statuses.filter(
426
+ (s) => s.key === "braintrust-tracing" && s.text !== undefined,
427
+ );
428
+ const widgetUpdates = mockState.widgets.filter(
429
+ (w) => w.key === "braintrust-trace-link" && w.content !== undefined,
430
+ );
431
+
432
+ expect(statusUpdates).toEqual([]);
433
+ expect(widgetUpdates).toEqual([]);
434
+ });
435
+
436
+ it("hides just the trace link when showTraceLink is false", async () => {
437
+ mockState.config.showTraceLink = false;
438
+
439
+ const { emit } = await createHarness();
440
+
441
+ await emit("session_start");
442
+ await emit("before_agent_start", {
443
+ prompt: "Inspect the package",
444
+ images: [],
445
+ });
446
+
447
+ const statusUpdates = mockState.statuses.filter(
448
+ (s) => s.key === "braintrust-tracing" && s.text !== undefined,
449
+ );
450
+ expect(statusUpdates.length).toBeGreaterThan(0);
451
+ expect(statusUpdates[0]?.text).toContain("Braintrust");
452
+
453
+ const widgetUpdates = mockState.widgets.filter(
454
+ (w) => w.key === "braintrust-trace-link" && w.content !== undefined,
455
+ );
456
+ expect(widgetUpdates).toEqual([]);
457
+ });
409
458
  });
package/src/index.ts CHANGED
@@ -193,7 +193,10 @@ function setTracingStatus(
193
193
  configIssue?: ConfigIssue;
194
194
  },
195
195
  ): void {
196
- if (!ctx.hasUI) return;
196
+ if (!ctx.hasUI || !config.showUi) {
197
+ if (ctx.hasUI) ctx.ui.setStatus(TRACING_STATUS_KEY, undefined);
198
+ return;
199
+ }
197
200
 
198
201
  const theme = ctx.ui.theme;
199
202
 
@@ -269,15 +272,19 @@ function displayPath(path: string): string {
269
272
 
270
273
  function setTraceWidget(
271
274
  ctx: ExtensionContext,
275
+ config: TraceConfig,
272
276
  traceUrl: string | undefined,
273
277
  configIssue: ConfigIssue | undefined,
274
278
  ): void {
275
- if (!ctx.hasUI) return;
279
+ if (!ctx.hasUI || !config.showUi) {
280
+ if (ctx.hasUI) ctx.ui.setWidget(TRACING_WIDGET_KEY, undefined);
281
+ return;
282
+ }
276
283
 
277
284
  const theme = ctx.ui.theme;
278
285
  const lines: string[] = [];
279
286
 
280
- if (traceUrl) {
287
+ if (traceUrl && config.showTraceLink) {
281
288
  const label = makeHyperlink(
282
289
  traceUrl,
283
290
  theme.fg("accent", theme.underline("Braintrust trace ↗")),
@@ -334,7 +341,7 @@ export default function braintrustPiExtension(pi: ExtensionAPI): void {
334
341
  missingApiKey: Boolean(config.enabled && !config.apiKey),
335
342
  configIssue,
336
343
  });
337
- setTraceWidget(ctx, activeSession?.traceUrl, configIssue);
344
+ setTraceWidget(ctx, config, activeSession?.traceUrl, configIssue);
338
345
  }
339
346
 
340
347
  function persistTraceUrl(session: ActiveSession, traceUrl: string): void {
package/src/types.ts CHANGED
@@ -26,6 +26,8 @@ export interface TraceConfig {
26
26
  additionalMetadata: JsonObject;
27
27
  parentSpanId?: string;
28
28
  rootSpanId?: string;
29
+ showUi: boolean;
30
+ showTraceLink: boolean;
29
31
  configIssues: ConfigIssue[];
30
32
  }
31
33