braintrust 3.12.0 → 3.13.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.
Files changed (49) hide show
  1. package/dev/dist/index.d.mts +25 -6
  2. package/dev/dist/index.d.ts +25 -6
  3. package/dev/dist/index.js +134 -43
  4. package/dev/dist/index.mjs +113 -22
  5. package/dist/apply-auto-instrumentation.js +170 -170
  6. package/dist/apply-auto-instrumentation.mjs +1 -1
  7. package/dist/auto-instrumentations/bundler/esbuild.cjs +1 -0
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/next.cjs +1 -0
  10. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  11. package/dist/auto-instrumentations/bundler/rollup.cjs +1 -0
  12. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  13. package/dist/auto-instrumentations/bundler/vite.cjs +1 -0
  14. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  15. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +1 -0
  16. package/dist/auto-instrumentations/bundler/webpack.cjs +1 -0
  17. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  18. package/dist/auto-instrumentations/{chunk-2DPA74KK.mjs → chunk-E5DUYJWK.mjs} +1 -0
  19. package/dist/auto-instrumentations/{chunk-73BZUKVI.mjs → chunk-GJOO4ESL.mjs} +1 -1
  20. package/dist/auto-instrumentations/{chunk-AFXRW7I7.mjs → chunk-WFEUJACP.mjs} +1 -1
  21. package/dist/auto-instrumentations/hook.mjs +1 -0
  22. package/dist/auto-instrumentations/index.cjs +1 -0
  23. package/dist/auto-instrumentations/index.mjs +1 -1
  24. package/dist/browser.d.mts +149 -21
  25. package/dist/browser.d.ts +149 -21
  26. package/dist/browser.js +114 -24
  27. package/dist/browser.mjs +114 -24
  28. package/dist/{chunk-BW4DF4CY.js → chunk-26JGOELH.js} +1 -0
  29. package/dist/{chunk-MSLBGITU.mjs → chunk-75IQCUB2.mjs} +1 -0
  30. package/dist/cli.js +121 -44
  31. package/dist/edge-light.d.mts +1 -1
  32. package/dist/edge-light.d.ts +1 -1
  33. package/dist/edge-light.js +114 -24
  34. package/dist/edge-light.mjs +114 -24
  35. package/dist/index.d.mts +149 -21
  36. package/dist/index.d.ts +149 -21
  37. package/dist/index.js +529 -394
  38. package/dist/index.mjs +161 -26
  39. package/dist/instrumentation/index.d.mts +40 -3
  40. package/dist/instrumentation/index.d.ts +40 -3
  41. package/dist/instrumentation/index.js +15 -2
  42. package/dist/instrumentation/index.mjs +15 -2
  43. package/dist/workerd.d.mts +1 -1
  44. package/dist/workerd.d.ts +1 -1
  45. package/dist/workerd.js +114 -24
  46. package/dist/workerd.mjs +114 -24
  47. package/package.json +3 -17
  48. package/util/dist/index.d.mts +3 -1
  49. package/util/dist/index.d.ts +3 -1
@@ -118,6 +118,7 @@ declare const ObjectReference$1: z.ZodObject<{
118
118
  created?: string | null | undefined;
119
119
  _xact_id?: string | null | undefined;
120
120
  }>;
121
+ type ObjectReferenceType$1 = z.infer<typeof ObjectReference$1>;
121
122
 
122
123
  type IdField = {
123
124
  id: string;
@@ -138,7 +139,7 @@ type OtherExperimentLogFields = {
138
139
  metadata: Record<string, unknown>;
139
140
  metrics: Record<string, unknown>;
140
141
  datasetRecordId: string;
141
- origin: z.infer<typeof ObjectReference$1>;
142
+ origin: ObjectReferenceType$1;
142
143
  span_attributes: Record<string, unknown>;
143
144
  [ASYNC_SCORING_CONTROL_FIELD]: AsyncScoringControlType;
144
145
  [MERGE_PATHS_FIELD]: string[][];
@@ -180,6 +181,7 @@ type DatasetEvent = {
180
181
  tags?: string[];
181
182
  metadata?: unknown;
182
183
  created?: string;
184
+ origin?: ObjectReferenceType$1;
183
185
  id: string;
184
186
  dataset_id: string;
185
187
  } & ({
@@ -8921,9 +8923,15 @@ declare class ParametersCache {
8921
8923
  interface CachedSpan {
8922
8924
  input?: unknown;
8923
8925
  output?: unknown;
8926
+ expected?: unknown;
8927
+ error?: unknown;
8928
+ scores?: Record<string, unknown>;
8929
+ metrics?: Record<string, unknown>;
8924
8930
  metadata?: Record<string, unknown>;
8931
+ tags?: string[];
8925
8932
  span_id: string;
8926
8933
  span_parents?: string[];
8934
+ is_root?: boolean | null;
8927
8935
  span_attributes?: {
8928
8936
  name?: string;
8929
8937
  type?: string;
@@ -11212,6 +11220,13 @@ interface LogOptions<IsAsyncFlush> {
11212
11220
  linkArgs?: LinkArgs;
11213
11221
  }
11214
11222
  type PromiseUnless<B, R> = B extends true ? R : Promise<Awaited<R>>;
11223
+ type DatasetPipelineDeferredJSONAttachmentHook = (data: unknown, options?: {
11224
+ filename?: string;
11225
+ pretty?: boolean;
11226
+ }) => object;
11227
+ declare global {
11228
+ var __BT_DATASET_PIPELINE_DEFER_JSON_ATTACHMENT__: DatasetPipelineDeferredJSONAttachmentHook | undefined;
11229
+ }
11215
11230
  interface ParentSpanIds {
11216
11231
  spanId: string;
11217
11232
  rootSpanId: string;
@@ -11385,7 +11400,7 @@ interface LoginOptions {
11385
11400
  */
11386
11401
  appUrl?: string;
11387
11402
  /**
11388
- * The API key to use. If the parameter is not specified, will try to use the `BRAINTRUST_API_KEY` environment variable.
11403
+ * The API key to use. If the parameter is not specified, will try to use the `BRAINTRUST_API_KEY` environment variable. In Node.js, if that is unset, will try the nearest `.env.braintrust` file in the current working directory or parent directories.
11389
11404
  */
11390
11405
  apiKey?: string;
11391
11406
  /**
@@ -11660,17 +11675,19 @@ declare class Dataset<IsLegacyDataset extends boolean = typeof DEFAULT_IS_LEGACY
11660
11675
  * about anything else that's relevant, that you can use to help find and analyze examples later. For example, you could log the
11661
11676
  * `prompt`, example's `id`, or anything else that would be useful to slice/dice later. The values in `metadata` can be any
11662
11677
  * JSON-serializable type, but its keys must be strings.
11678
+ * @param event.origin (Optional) a reference to the source object this dataset record was derived from.
11663
11679
  * @param event.id (Optional) a unique identifier for the event. If you don't provide one, Braintrust will generate one for you.
11664
11680
  * @param event.output: (Deprecated) The output of your application. Use `expected` instead.
11665
11681
  * @returns The `id` of the logged record.
11666
11682
  */
11667
- insert({ input, expected, metadata, tags, id, output, }: {
11683
+ insert({ input, expected, metadata, tags, id, output, origin, }: {
11668
11684
  readonly input?: unknown;
11669
11685
  readonly expected?: unknown;
11670
11686
  readonly tags?: string[];
11671
11687
  readonly metadata?: Record<string, unknown>;
11672
11688
  readonly id?: string;
11673
11689
  readonly output?: unknown;
11690
+ readonly origin?: ObjectReferenceType;
11674
11691
  }): string;
11675
11692
  /**
11676
11693
  * Update fields of a single record in the dataset. The updated fields will be batched and uploaded behind the scenes.
@@ -11952,6 +11969,10 @@ interface GetThreadOptions {
11952
11969
  */
11953
11970
  preprocessor?: string;
11954
11971
  }
11972
+ interface GetSpansOptions {
11973
+ spanType?: string[];
11974
+ includeScorers?: boolean;
11975
+ }
11955
11976
  /**
11956
11977
  * Interface for trace objects that can be used by scorers.
11957
11978
  * Both the SDK's LocalTrace class and the API wrapper's WrapperTrace implement this.
@@ -11962,9 +11983,7 @@ interface Trace {
11962
11983
  object_id: string;
11963
11984
  root_span_id: string;
11964
11985
  };
11965
- getSpans(options?: {
11966
- spanType?: string[];
11967
- }): Promise<SpanData[]>;
11986
+ getSpans(options?: GetSpansOptions): Promise<SpanData[]>;
11968
11987
  /**
11969
11988
  * Get the thread (preprocessed messages) for this trace.
11970
11989
  * Uses the project default preprocessor, falling back to the global "thread" preprocessor.
@@ -118,6 +118,7 @@ declare const ObjectReference$1: z.ZodObject<{
118
118
  created?: string | null | undefined;
119
119
  _xact_id?: string | null | undefined;
120
120
  }>;
121
+ type ObjectReferenceType$1 = z.infer<typeof ObjectReference$1>;
121
122
 
122
123
  type IdField = {
123
124
  id: string;
@@ -138,7 +139,7 @@ type OtherExperimentLogFields = {
138
139
  metadata: Record<string, unknown>;
139
140
  metrics: Record<string, unknown>;
140
141
  datasetRecordId: string;
141
- origin: z.infer<typeof ObjectReference$1>;
142
+ origin: ObjectReferenceType$1;
142
143
  span_attributes: Record<string, unknown>;
143
144
  [ASYNC_SCORING_CONTROL_FIELD]: AsyncScoringControlType;
144
145
  [MERGE_PATHS_FIELD]: string[][];
@@ -180,6 +181,7 @@ type DatasetEvent = {
180
181
  tags?: string[];
181
182
  metadata?: unknown;
182
183
  created?: string;
184
+ origin?: ObjectReferenceType$1;
183
185
  id: string;
184
186
  dataset_id: string;
185
187
  } & ({
@@ -8921,9 +8923,15 @@ declare class ParametersCache {
8921
8923
  interface CachedSpan {
8922
8924
  input?: unknown;
8923
8925
  output?: unknown;
8926
+ expected?: unknown;
8927
+ error?: unknown;
8928
+ scores?: Record<string, unknown>;
8929
+ metrics?: Record<string, unknown>;
8924
8930
  metadata?: Record<string, unknown>;
8931
+ tags?: string[];
8925
8932
  span_id: string;
8926
8933
  span_parents?: string[];
8934
+ is_root?: boolean | null;
8927
8935
  span_attributes?: {
8928
8936
  name?: string;
8929
8937
  type?: string;
@@ -11212,6 +11220,13 @@ interface LogOptions<IsAsyncFlush> {
11212
11220
  linkArgs?: LinkArgs;
11213
11221
  }
11214
11222
  type PromiseUnless<B, R> = B extends true ? R : Promise<Awaited<R>>;
11223
+ type DatasetPipelineDeferredJSONAttachmentHook = (data: unknown, options?: {
11224
+ filename?: string;
11225
+ pretty?: boolean;
11226
+ }) => object;
11227
+ declare global {
11228
+ var __BT_DATASET_PIPELINE_DEFER_JSON_ATTACHMENT__: DatasetPipelineDeferredJSONAttachmentHook | undefined;
11229
+ }
11215
11230
  interface ParentSpanIds {
11216
11231
  spanId: string;
11217
11232
  rootSpanId: string;
@@ -11385,7 +11400,7 @@ interface LoginOptions {
11385
11400
  */
11386
11401
  appUrl?: string;
11387
11402
  /**
11388
- * The API key to use. If the parameter is not specified, will try to use the `BRAINTRUST_API_KEY` environment variable.
11403
+ * The API key to use. If the parameter is not specified, will try to use the `BRAINTRUST_API_KEY` environment variable. In Node.js, if that is unset, will try the nearest `.env.braintrust` file in the current working directory or parent directories.
11389
11404
  */
11390
11405
  apiKey?: string;
11391
11406
  /**
@@ -11660,17 +11675,19 @@ declare class Dataset<IsLegacyDataset extends boolean = typeof DEFAULT_IS_LEGACY
11660
11675
  * about anything else that's relevant, that you can use to help find and analyze examples later. For example, you could log the
11661
11676
  * `prompt`, example's `id`, or anything else that would be useful to slice/dice later. The values in `metadata` can be any
11662
11677
  * JSON-serializable type, but its keys must be strings.
11678
+ * @param event.origin (Optional) a reference to the source object this dataset record was derived from.
11663
11679
  * @param event.id (Optional) a unique identifier for the event. If you don't provide one, Braintrust will generate one for you.
11664
11680
  * @param event.output: (Deprecated) The output of your application. Use `expected` instead.
11665
11681
  * @returns The `id` of the logged record.
11666
11682
  */
11667
- insert({ input, expected, metadata, tags, id, output, }: {
11683
+ insert({ input, expected, metadata, tags, id, output, origin, }: {
11668
11684
  readonly input?: unknown;
11669
11685
  readonly expected?: unknown;
11670
11686
  readonly tags?: string[];
11671
11687
  readonly metadata?: Record<string, unknown>;
11672
11688
  readonly id?: string;
11673
11689
  readonly output?: unknown;
11690
+ readonly origin?: ObjectReferenceType;
11674
11691
  }): string;
11675
11692
  /**
11676
11693
  * Update fields of a single record in the dataset. The updated fields will be batched and uploaded behind the scenes.
@@ -11952,6 +11969,10 @@ interface GetThreadOptions {
11952
11969
  */
11953
11970
  preprocessor?: string;
11954
11971
  }
11972
+ interface GetSpansOptions {
11973
+ spanType?: string[];
11974
+ includeScorers?: boolean;
11975
+ }
11955
11976
  /**
11956
11977
  * Interface for trace objects that can be used by scorers.
11957
11978
  * Both the SDK's LocalTrace class and the API wrapper's WrapperTrace implement this.
@@ -11962,9 +11983,7 @@ interface Trace {
11962
11983
  object_id: string;
11963
11984
  root_span_id: string;
11964
11985
  };
11965
- getSpans(options?: {
11966
- spanType?: string[];
11967
- }): Promise<SpanData[]>;
11986
+ getSpans(options?: GetSpansOptions): Promise<SpanData[]>;
11968
11987
  /**
11969
11988
  * Get the thread (preprocessed messages) for this trace.
11970
11989
  * Uses the project default preprocessor, falling back to the global "thread" preprocessor.
package/dev/dist/index.js CHANGED
@@ -96,6 +96,7 @@ var _nodefs = require('node:fs'); var fsSync = _interopRequireWildcard(_nodefs);
96
96
  var _nodecrypto = require('node:crypto'); var crypto = _interopRequireWildcard(_nodecrypto);
97
97
  var _nodeutil = require('node:util');
98
98
  var _nodezlib = require('node:zlib'); var zlib = _interopRequireWildcard(_nodezlib);
99
+ var _dotenv = require('dotenv'); var dotenv = _interopRequireWildcard(_dotenv);
99
100
 
100
101
  // src/isomorph.ts
101
102
  var DefaultAsyncLocalStorage = class {
@@ -182,6 +183,7 @@ var iso = {
182
183
  getRepoInfo: async (_settings) => void 0,
183
184
  getPastNAncestors: async () => [],
184
185
  getEnv: (_name) => void 0,
186
+ getBraintrustApiKey: async () => void 0,
185
187
  getCallerLocation: () => void 0,
186
188
  newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
187
189
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -7266,10 +7268,11 @@ async function login(options = {}) {
7266
7268
  async function loginToState(options = {}) {
7267
7269
  const {
7268
7270
  appUrl = isomorph_default.getEnv("BRAINTRUST_APP_URL") || "https://www.braintrust.dev",
7269
- apiKey = isomorph_default.getEnv("BRAINTRUST_API_KEY"),
7271
+ apiKey: apiKeyArg,
7270
7272
  orgName = isomorph_default.getEnv("BRAINTRUST_ORG_NAME"),
7271
7273
  fetch: fetch2 = globalThis.fetch
7272
7274
  } = options || {};
7275
+ const apiKey = apiKeyArg !== void 0 ? apiKeyArg : await isomorph_default.getBraintrustApiKey();
7273
7276
  const appPublicUrl = isomorph_default.getEnv("BRAINTRUST_APP_PUBLIC_URL") || appUrl;
7274
7277
  const state = new BraintrustState(options);
7275
7278
  state.resetLoginInfo();
@@ -8288,9 +8291,15 @@ var SpanImpl = (_class13 = class _SpanImpl {
8288
8291
  const cachedSpan = {
8289
8292
  input: partialRecord.input,
8290
8293
  output: partialRecord.output,
8294
+ expected: partialRecord.expected,
8295
+ error: partialRecord.error,
8296
+ scores: partialRecord.scores,
8297
+ metrics: partialRecord.metrics,
8291
8298
  metadata: partialRecord.metadata,
8299
+ tags: partialRecord.tags,
8292
8300
  span_id: this._spanId,
8293
8301
  span_parents: this._spanParents,
8302
+ is_root: this._spanId === this._rootSpanId,
8294
8303
  span_attributes: partialRecord.span_attributes
8295
8304
  };
8296
8305
  this._state.spanCache.queueWrite(
@@ -8626,6 +8635,7 @@ var Dataset2 = (_class14 = class extends ObjectFetcher {
8626
8635
  metadata,
8627
8636
  tags,
8628
8637
  output,
8638
+ origin,
8629
8639
  isMerge
8630
8640
  }) {
8631
8641
  return new LazyValue(async () => {
@@ -8640,6 +8650,7 @@ var Dataset2 = (_class14 = class extends ObjectFetcher {
8640
8650
  created: !isMerge ? (/* @__PURE__ */ new Date()).toISOString() : void 0,
8641
8651
  //if we're merging/updating an event we will not add this ts
8642
8652
  metadata,
8653
+ origin,
8643
8654
  ...!!isMerge ? {
8644
8655
  [IS_MERGE_FIELD]: true
8645
8656
  } : {}
@@ -8659,6 +8670,7 @@ var Dataset2 = (_class14 = class extends ObjectFetcher {
8659
8670
  * about anything else that's relevant, that you can use to help find and analyze examples later. For example, you could log the
8660
8671
  * `prompt`, example's `id`, or anything else that would be useful to slice/dice later. The values in `metadata` can be any
8661
8672
  * JSON-serializable type, but its keys must be strings.
8673
+ * @param event.origin (Optional) a reference to the source object this dataset record was derived from.
8662
8674
  * @param event.id (Optional) a unique identifier for the event. If you don't provide one, Braintrust will generate one for you.
8663
8675
  * @param event.output: (Deprecated) The output of your application. Use `expected` instead.
8664
8676
  * @returns The `id` of the logged record.
@@ -8669,7 +8681,8 @@ var Dataset2 = (_class14 = class extends ObjectFetcher {
8669
8681
  metadata,
8670
8682
  tags,
8671
8683
  id,
8672
- output
8684
+ output,
8685
+ origin
8673
8686
  }) {
8674
8687
  this.validateEvent({ metadata, expected, output, tags });
8675
8688
  const rowId = id || _uuid.v4.call(void 0, );
@@ -8681,6 +8694,7 @@ var Dataset2 = (_class14 = class extends ObjectFetcher {
8681
8694
  metadata,
8682
8695
  tags,
8683
8696
  output,
8697
+ origin,
8684
8698
  isMerge: false
8685
8699
  })
8686
8700
  );
@@ -25411,11 +25425,60 @@ var PluginRegistry = (_class26 = class {constructor() { _class26.prototype.__ini
25411
25425
  var registry = new PluginRegistry();
25412
25426
 
25413
25427
  // src/node/config.ts
25428
+ var BRAINTRUST_ENV_SEARCH_PARENT_LIMIT = 64;
25414
25429
  function configureNode() {
25415
25430
  isomorph_default.buildType = "node";
25416
25431
  isomorph_default.getRepoInfo = getRepoInfo;
25417
25432
  isomorph_default.getPastNAncestors = getPastNAncestors;
25418
- isomorph_default.getEnv = (name) => process.env[name];
25433
+ isomorph_default.getEnv = (name) => {
25434
+ const value = process.env[name];
25435
+ return name === "BRAINTRUST_API_KEY" && !_optionalChain([value, 'optionalAccess', _642 => _642.trim, 'call', _643 => _643()]) ? void 0 : value;
25436
+ };
25437
+ isomorph_default.getBraintrustApiKey = async () => {
25438
+ const value = process.env.BRAINTRUST_API_KEY;
25439
+ if (_optionalChain([value, 'optionalAccess', _644 => _644.trim, 'call', _645 => _645()])) {
25440
+ return value;
25441
+ }
25442
+ const envPaths = [];
25443
+ for (let dir2 = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir2 = path.dirname(dir2), depth++) {
25444
+ envPaths.push(path.join(dir2, ".env.braintrust"));
25445
+ if (path.dirname(dir2) === dir2) {
25446
+ break;
25447
+ }
25448
+ }
25449
+ const pending = /* @__PURE__ */ new Map();
25450
+ envPaths.forEach((envPath, index) => {
25451
+ pending.set(
25452
+ index,
25453
+ fs.readFile(envPath, "utf8").then(
25454
+ (contents) => ({ contents, envPath, index }),
25455
+ (error) => ({ error, envPath, index })
25456
+ )
25457
+ );
25458
+ });
25459
+ const results = [];
25460
+ let nearestUnresolvedIndex = 0;
25461
+ while (pending.size > 0) {
25462
+ const result = await Promise.race(pending.values());
25463
+ pending.delete(result.index);
25464
+ results[result.index] = result;
25465
+ while (results[nearestUnresolvedIndex]) {
25466
+ const nearestResult = results[nearestUnresolvedIndex];
25467
+ if ("contents" in nearestResult) {
25468
+ const parsed = dotenv.parse(nearestResult.contents);
25469
+ const apiKey = parsed.BRAINTRUST_API_KEY;
25470
+ return _optionalChain([apiKey, 'optionalAccess', _646 => _646.trim, 'call', _647 => _647()]) ? apiKey : void 0;
25471
+ }
25472
+ const e = nearestResult.error;
25473
+ if (typeof e === "object" && e !== null && "code" in e && e.code === "ENOENT") {
25474
+ nearestUnresolvedIndex++;
25475
+ continue;
25476
+ }
25477
+ return void 0;
25478
+ }
25479
+ }
25480
+ return void 0;
25481
+ };
25419
25482
  isomorph_default.getCallerLocation = getCallerLocation;
25420
25483
  isomorph_default.newAsyncLocalStorage = () => new (0, _nodeasync_hooks.AsyncLocalStorage)();
25421
25484
  isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
@@ -26570,8 +26633,12 @@ async function invoke(args) {
26570
26633
 
26571
26634
  // src/trace.ts
26572
26635
  var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
26573
- constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter) {
26574
- const filterExpr = _SpanFetcher.buildFilter(rootSpanId, spanTypeFilter);
26636
+ constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false) {
26637
+ const filterExpr = _SpanFetcher.buildFilter(
26638
+ rootSpanId,
26639
+ spanTypeFilter,
26640
+ includeScorers
26641
+ );
26575
26642
  super(objectType, void 0, void 0, {
26576
26643
  filter: filterExpr
26577
26644
  });
@@ -26580,16 +26647,17 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
26580
26647
  this._state = _state;
26581
26648
  this.spanTypeFilter = spanTypeFilter;
26582
26649
  }
26583
- static buildFilter(rootSpanId, spanTypeFilter) {
26650
+ static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
26584
26651
  const children = [
26585
26652
  // Base filter: root_span_id = 'value'
26586
26653
  {
26587
26654
  op: "eq",
26588
26655
  left: { op: "ident", name: ["root_span_id"] },
26589
26656
  right: { op: "literal", value: rootSpanId }
26590
- },
26591
- // Exclude span_attributes.purpose = 'score'
26592
- {
26657
+ }
26658
+ ];
26659
+ if (!includeScorers) {
26660
+ children.push({
26593
26661
  op: "or",
26594
26662
  children: [
26595
26663
  {
@@ -26602,8 +26670,8 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
26602
26670
  right: { op: "literal", value: "scorer" }
26603
26671
  }
26604
26672
  ]
26605
- }
26606
- ];
26673
+ });
26674
+ }
26607
26675
  if (spanTypeFilter && spanTypeFilter.length > 0) {
26608
26676
  children.push({
26609
26677
  op: "in",
@@ -26629,35 +26697,49 @@ var CachedSpanFetcher = (_class27 = class {
26629
26697
 
26630
26698
  constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {;_class27.prototype.__init107.call(this);_class27.prototype.__init108.call(this);
26631
26699
  if (typeof objectTypeOrFetchFn === "function") {
26632
- this.fetchFn = objectTypeOrFetchFn;
26700
+ this.fetchFn = (spanType) => objectTypeOrFetchFn(spanType);
26633
26701
  } else {
26634
26702
  const objectType = objectTypeOrFetchFn;
26635
- this.fetchFn = async (spanType) => {
26703
+ this.fetchFn = async (spanType, includeScorers) => {
26636
26704
  const state = await getState();
26637
26705
  const fetcher = new SpanFetcher(
26638
26706
  objectType,
26639
26707
  objectId,
26640
26708
  rootSpanId,
26641
26709
  state,
26642
- spanType
26710
+ spanType,
26711
+ includeScorers
26643
26712
  );
26644
26713
  const rows = await fetcher.fetchedData();
26645
- return rows.filter((row) => _optionalChain([row, 'access', _642 => _642.span_attributes, 'optionalAccess', _643 => _643.purpose]) !== "scorer").map((row) => ({
26714
+ return rows.map((row) => ({
26646
26715
  input: row.input,
26647
26716
  output: row.output,
26717
+ expected: row.expected,
26718
+ error: row.error,
26719
+ scores: row.scores,
26720
+ metrics: row.metrics,
26648
26721
  metadata: row.metadata,
26649
26722
  span_id: row.span_id,
26650
26723
  span_parents: row.span_parents,
26724
+ is_root: row.is_root,
26651
26725
  span_attributes: row.span_attributes,
26652
26726
  id: row.id,
26653
26727
  _xact_id: row._xact_id,
26654
26728
  _pagination_key: row._pagination_key,
26655
- root_span_id: row.root_span_id
26729
+ root_span_id: row.root_span_id,
26730
+ created: row.created,
26731
+ tags: row.tags
26656
26732
  }));
26657
26733
  };
26658
26734
  }
26659
26735
  }
26660
- async getSpans({ spanType } = {}) {
26736
+ async getSpans({
26737
+ spanType,
26738
+ includeScorers = false
26739
+ } = {}) {
26740
+ if (includeScorers) {
26741
+ return this.fetchFn(spanType, true);
26742
+ }
26661
26743
  if (this.allFetched) {
26662
26744
  return this.getFromCache(spanType);
26663
26745
  }
@@ -26674,9 +26756,9 @@ var CachedSpanFetcher = (_class27 = class {
26674
26756
  return this.getFromCache(spanType);
26675
26757
  }
26676
26758
  async fetchSpans(spanType) {
26677
- const spans = await this.fetchFn(spanType);
26759
+ const spans = await this.fetchFn(spanType, false);
26678
26760
  for (const span of spans) {
26679
- const type = _nullishCoalesce(_optionalChain([span, 'access', _644 => _644.span_attributes, 'optionalAccess', _645 => _645.type]), () => ( ""));
26761
+ const type = _nullishCoalesce(_optionalChain([span, 'access', _648 => _648.span_attributes, 'optionalAccess', _649 => _649.type]), () => ( ""));
26680
26762
  const existing = _nullishCoalesce(this.spanCache.get(type), () => ( []));
26681
26763
  existing.push(span);
26682
26764
  this.spanCache.set(type, existing);
@@ -26752,34 +26834,43 @@ var LocalTrace = (_class28 = class {
26752
26834
  * First checks the local span cache for recently logged spans, then falls
26753
26835
  * back to CachedSpanFetcher which handles BTQL fetching and caching.
26754
26836
  */
26755
- async getSpans({ spanType } = {}) {
26837
+ async getSpans({
26838
+ spanType,
26839
+ includeScorers = false
26840
+ } = {}) {
26756
26841
  const cachedSpans = this.state.spanCache.getByRootSpanId(this.rootSpanId);
26757
26842
  if (cachedSpans && cachedSpans.length > 0) {
26758
- let spans = cachedSpans.filter(
26759
- (span) => _optionalChain([span, 'access', _646 => _646.span_attributes, 'optionalAccess', _647 => _647.purpose]) !== "scorer"
26843
+ let spans = includeScorers ? cachedSpans : cachedSpans.filter(
26844
+ (span) => _optionalChain([span, 'access', _650 => _650.span_attributes, 'optionalAccess', _651 => _651.purpose]) !== "scorer"
26760
26845
  );
26761
26846
  if (spanType && spanType.length > 0) {
26762
26847
  spans = spans.filter(
26763
- (span) => spanType.includes(_nullishCoalesce(_optionalChain([span, 'access', _648 => _648.span_attributes, 'optionalAccess', _649 => _649.type]), () => ( "")))
26848
+ (span) => spanType.includes(_nullishCoalesce(_optionalChain([span, 'access', _652 => _652.span_attributes, 'optionalAccess', _653 => _653.type]), () => ( "")))
26764
26849
  );
26765
26850
  }
26766
26851
  return spans.map((span) => ({
26767
26852
  input: span.input,
26768
26853
  output: span.output,
26854
+ expected: span.expected,
26855
+ error: span.error,
26856
+ scores: span.scores,
26857
+ metrics: span.metrics,
26769
26858
  metadata: span.metadata,
26770
26859
  span_id: span.span_id,
26771
26860
  span_parents: span.span_parents,
26772
- span_attributes: span.span_attributes
26861
+ is_root: span.is_root,
26862
+ span_attributes: span.span_attributes,
26863
+ tags: span.tags
26773
26864
  }));
26774
26865
  }
26775
- return this.cachedFetcher.getSpans({ spanType });
26866
+ return this.cachedFetcher.getSpans({ spanType, includeScorers });
26776
26867
  }
26777
26868
  /**
26778
26869
  * Get the thread (preprocessed messages) for this trace.
26779
26870
  * Calls the API with the project_default preprocessor (which falls back to "thread").
26780
26871
  */
26781
26872
  async getThread(options) {
26782
- const cacheKey = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _650 => _650.preprocessor]), () => ( "project_default"));
26873
+ const cacheKey = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _654 => _654.preprocessor]), () => ( "project_default"));
26783
26874
  if (!this.threadCache.has(cacheKey)) {
26784
26875
  const promise = this.fetchThread(options);
26785
26876
  this.threadCache.set(cacheKey, promise);
@@ -26790,7 +26881,7 @@ var LocalTrace = (_class28 = class {
26790
26881
  await this.ensureSpansReady();
26791
26882
  await this.state.login({});
26792
26883
  const result = await invoke({
26793
- globalFunction: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _651 => _651.preprocessor]), () => ( "project_default")),
26884
+ globalFunction: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _655 => _655.preprocessor]), () => ( "project_default")),
26794
26885
  functionType: "preprocessor",
26795
26886
  input: {
26796
26887
  trace_ref: {
@@ -26966,10 +27057,10 @@ function validateParametersWithJsonSchema(parameters, schema) {
26966
27057
  const ajv = new (0, _ajv2.default)({ coerceTypes: true, useDefaults: true, strict: false });
26967
27058
  const validate = ajv.compile(schema);
26968
27059
  if (!validate(parameters)) {
26969
- const errorMessages = _optionalChain([validate, 'access', _652 => _652.errors, 'optionalAccess', _653 => _653.map, 'call', _654 => _654((err) => {
27060
+ const errorMessages = _optionalChain([validate, 'access', _656 => _656.errors, 'optionalAccess', _657 => _657.map, 'call', _658 => _658((err) => {
26970
27061
  const path2 = err.instancePath || "root";
26971
27062
  return `${path2}: ${err.message}`;
26972
- }), 'access', _655 => _655.join, 'call', _656 => _656(", ")]);
27063
+ }), 'access', _659 => _659.join, 'call', _660 => _660(", ")]);
26973
27064
  throw Error(`Invalid parameters: ${errorMessages}`);
26974
27065
  }
26975
27066
  return rehydrateRemoteParameters(parameters, schema);
@@ -27309,7 +27400,7 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters, st
27309
27400
  }
27310
27401
  async function runEvaluatorInternal(experiment, evaluator, progressReporter, filters, stream, parameters, collectResults, enableCache) {
27311
27402
  if (enableCache) {
27312
- _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _657 => _657.spanCache, 'optionalAccess', _658 => _658.start, 'call', _659 => _659()]);
27403
+ _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _661 => _661.spanCache, 'optionalAccess', _662 => _662.start, 'call', _663 => _663()]);
27313
27404
  }
27314
27405
  try {
27315
27406
  if (typeof evaluator.data === "string") {
@@ -27420,7 +27511,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
27420
27511
  objectType: parentComponents ? spanObjectTypeV3ToTypedString(
27421
27512
  parentComponents.data.object_type
27422
27513
  ) : "experiment",
27423
- objectId: await _asyncNullishCoalesce(await _asyncOptionalChain([parentComponents, 'optionalAccess', async _660 => _660.data, 'access', async _661 => _661.object_id]), async () => ( (experimentIdPromise ? await _asyncNullishCoalesce(await experimentIdPromise, async () => ( "")) : ""))),
27514
+ objectId: await _asyncNullishCoalesce(await _asyncOptionalChain([parentComponents, 'optionalAccess', async _664 => _664.data, 'access', async _665 => _665.object_id]), async () => ( (experimentIdPromise ? await _asyncNullishCoalesce(await experimentIdPromise, async () => ( "")) : ""))),
27424
27515
  rootSpanId: rootSpan.rootSpanId,
27425
27516
  ensureSpansFlushed,
27426
27517
  state
@@ -27450,10 +27541,10 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
27450
27541
  span,
27451
27542
  parameters: _nullishCoalesce(parameters, () => ( {})),
27452
27543
  reportProgress: (event) => {
27453
- _optionalChain([stream, 'optionalCall', _662 => _662({
27544
+ _optionalChain([stream, 'optionalCall', _666 => _666({
27454
27545
  ...event,
27455
27546
  id: rootSpan.id,
27456
- origin: _optionalChain([baseEvent, 'access', _663 => _663.event, 'optionalAccess', _664 => _664.origin]),
27547
+ origin: _optionalChain([baseEvent, 'access', _667 => _667.event, 'optionalAccess', _668 => _668.origin]),
27457
27548
  name: evaluator.evalName,
27458
27549
  object_type: "task"
27459
27550
  })]);
@@ -27641,7 +27732,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
27641
27732
  tags: tags.length ? tags : void 0,
27642
27733
  metadata,
27643
27734
  error,
27644
- origin: _optionalChain([baseEvent, 'access', _665 => _665.event, 'optionalAccess', _666 => _666.origin])
27735
+ origin: _optionalChain([baseEvent, 'access', _669 => _669.event, 'optionalAccess', _670 => _670.origin])
27645
27736
  };
27646
27737
  collectedResults.push({
27647
27738
  ...baseResult,
@@ -27681,7 +27772,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
27681
27772
  break;
27682
27773
  }
27683
27774
  scheduledTrials++;
27684
- _optionalChain([progressReporter, 'access', _667 => _667.setTotal, 'optionalCall', _668 => _668(evaluator.evalName, scheduledTrials)]);
27775
+ _optionalChain([progressReporter, 'access', _671 => _671.setTotal, 'optionalCall', _672 => _672(evaluator.evalName, scheduledTrials)]);
27685
27776
  q.pushAsync({ datum, trialIndex }).catch((e) => {
27686
27777
  if (queueErrors.length < 5) {
27687
27778
  queueErrors.push(e);
@@ -27766,9 +27857,9 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
27766
27857
  );
27767
27858
  } finally {
27768
27859
  if (enableCache) {
27769
- const spanCache = _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _669 => _669.spanCache]);
27770
- _optionalChain([spanCache, 'optionalAccess', _670 => _670.dispose, 'call', _671 => _671()]);
27771
- _optionalChain([spanCache, 'optionalAccess', _672 => _672.stop, 'call', _673 => _673()]);
27860
+ const spanCache = _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _673 => _673.spanCache]);
27861
+ _optionalChain([spanCache, 'optionalAccess', _674 => _674.dispose, 'call', _675 => _675()]);
27862
+ _optionalChain([spanCache, 'optionalAccess', _676 => _676.stop, 'call', _677 => _677()]);
27772
27863
  }
27773
27864
  }
27774
27865
  }
@@ -28008,7 +28099,7 @@ async function cachedLogin(options) {
28008
28099
  }
28009
28100
  function makeCheckAuthorized(allowedOrgName) {
28010
28101
  return async (req, _res, next) => {
28011
- if (!_optionalChain([req, 'access', _674 => _674.ctx, 'optionalAccess', _675 => _675.token])) {
28102
+ if (!_optionalChain([req, 'access', _678 => _678.ctx, 'optionalAccess', _679 => _679.token])) {
28012
28103
  return next(_httperrors2.default.call(void 0, 401, "Unauthorized"));
28013
28104
  }
28014
28105
  try {
@@ -28021,7 +28112,7 @@ function makeCheckAuthorized(allowedOrgName) {
28021
28112
  return next(_httperrors2.default.call(void 0, 403, errorMessage2));
28022
28113
  }
28023
28114
  const state = await cachedLogin({
28024
- apiKey: _optionalChain([req, 'access', _676 => _676.ctx, 'optionalAccess', _677 => _677.token]),
28115
+ apiKey: _optionalChain([req, 'access', _680 => _680.ctx, 'optionalAccess', _681 => _681.token]),
28025
28116
  orgName
28026
28117
  });
28027
28118
  req.ctx.state = state;
@@ -28776,7 +28867,7 @@ function runDevServer(evaluators, opts) {
28776
28867
  scores,
28777
28868
  stream
28778
28869
  } = evalBodySchema.parse(req.body);
28779
- if (!_optionalChain([req, 'access', _678 => _678.ctx, 'optionalAccess', _679 => _679.state])) {
28870
+ if (!_optionalChain([req, 'access', _682 => _682.ctx, 'optionalAccess', _683 => _683.state])) {
28780
28871
  res.status(500).json({ error: "Braintrust state not initialized in request" });
28781
28872
  return;
28782
28873
  }
@@ -28827,12 +28918,12 @@ function runDevServer(evaluators, opts) {
28827
28918
  ...evaluator,
28828
28919
  data: evalData.data,
28829
28920
  scores: (_nullishCoalesce(evaluator.scores, () => ( []))).concat(
28830
- _nullishCoalesce(_optionalChain([scores, 'optionalAccess', _680 => _680.map, 'call', _681 => _681(
28921
+ _nullishCoalesce(_optionalChain([scores, 'optionalAccess', _684 => _684.map, 'call', _685 => _685(
28831
28922
  (score) => makeScorer(
28832
28923
  state,
28833
28924
  score.name,
28834
28925
  score.function_id,
28835
- _optionalChain([req, 'access', _682 => _682.ctx, 'optionalAccess', _683 => _683.projectId])
28926
+ _optionalChain([req, 'access', _686 => _686.ctx, 'optionalAccess', _687 => _687.projectId])
28836
28927
  )
28837
28928
  )]), () => ( []))
28838
28929
  ),