braintrust 3.12.0 → 3.14.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 (55) hide show
  1. package/dev/dist/index.d.mts +31 -14
  2. package/dev/dist/index.d.ts +31 -14
  3. package/dev/dist/index.js +919 -485
  4. package/dev/dist/index.mjs +480 -46
  5. package/dist/apply-auto-instrumentation.js +204 -174
  6. package/dist/apply-auto-instrumentation.mjs +35 -5
  7. package/dist/auto-instrumentations/bundler/esbuild.cjs +226 -1
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +3 -2
  9. package/dist/auto-instrumentations/bundler/next.cjs +226 -1
  10. package/dist/auto-instrumentations/bundler/next.mjs +4 -3
  11. package/dist/auto-instrumentations/bundler/rollup.cjs +226 -1
  12. package/dist/auto-instrumentations/bundler/rollup.mjs +3 -2
  13. package/dist/auto-instrumentations/bundler/vite.cjs +226 -1
  14. package/dist/auto-instrumentations/bundler/vite.mjs +3 -2
  15. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +9 -0
  16. package/dist/auto-instrumentations/bundler/webpack.cjs +226 -1
  17. package/dist/auto-instrumentations/bundler/webpack.mjs +4 -3
  18. package/dist/auto-instrumentations/{chunk-2DPA74KK.mjs → chunk-E5DUYJWK.mjs} +1 -0
  19. package/dist/auto-instrumentations/chunk-J57YF7WS.mjs +208 -0
  20. package/dist/auto-instrumentations/{chunk-AFXRW7I7.mjs → chunk-OTUQ7KH5.mjs} +1 -1
  21. package/dist/auto-instrumentations/chunk-QFMACSOL.mjs +280 -0
  22. package/dist/auto-instrumentations/{chunk-73BZUKVI.mjs → chunk-XKAAVWT6.mjs} +24 -2
  23. package/dist/auto-instrumentations/hook.mjs +7981 -7
  24. package/dist/auto-instrumentations/index.cjs +1 -0
  25. package/dist/auto-instrumentations/index.mjs +1 -1
  26. package/dist/auto-instrumentations/loader/cjs-patch.cjs +194 -4
  27. package/dist/auto-instrumentations/loader/cjs-patch.mjs +13 -27
  28. package/dist/auto-instrumentations/loader/esm-hook.mjs +24 -10
  29. package/dist/browser.d.mts +274 -30
  30. package/dist/browser.d.ts +274 -30
  31. package/dist/browser.js +407 -48
  32. package/dist/browser.mjs +407 -48
  33. package/dist/{chunk-BW4DF4CY.js → chunk-NKD77KGB.js} +180 -1
  34. package/dist/{chunk-MSLBGITU.mjs → chunk-NU2GSPHX.mjs} +180 -1
  35. package/dist/cli.js +494 -94
  36. package/dist/edge-light.d.mts +1 -1
  37. package/dist/edge-light.d.ts +1 -1
  38. package/dist/edge-light.js +407 -48
  39. package/dist/edge-light.mjs +407 -48
  40. package/dist/index.d.mts +274 -30
  41. package/dist/index.d.ts +274 -30
  42. package/dist/index.js +1267 -857
  43. package/dist/index.mjs +465 -55
  44. package/dist/instrumentation/index.d.mts +47 -11
  45. package/dist/instrumentation/index.d.ts +47 -11
  46. package/dist/instrumentation/index.js +116 -26
  47. package/dist/instrumentation/index.mjs +116 -26
  48. package/dist/workerd.d.mts +1 -1
  49. package/dist/workerd.d.ts +1 -1
  50. package/dist/workerd.js +407 -48
  51. package/dist/workerd.mjs +407 -48
  52. package/package.json +3 -23
  53. package/util/dist/index.d.mts +3 -1
  54. package/util/dist/index.d.ts +3 -1
  55. package/dist/auto-instrumentations/chunk-MWZXZQUO.mjs +0 -81
@@ -38,6 +38,7 @@ __export(edge_light_exports, {
38
38
  BaseExperiment: () => BaseExperiment,
39
39
  BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
40
40
  BraintrustMiddleware: () => BraintrustMiddleware,
41
+ BraintrustObservabilityExporter: () => BraintrustObservabilityExporter,
41
42
  BraintrustState: () => BraintrustState,
42
43
  BraintrustStream: () => BraintrustStream,
43
44
  CachedSpanFetcher: () => CachedSpanFetcher,
@@ -47,6 +48,7 @@ __export(edge_light_exports, {
47
48
  DEFAULT_FETCH_BATCH_SIZE: () => DEFAULT_FETCH_BATCH_SIZE,
48
49
  DEFAULT_MAX_REQUEST_SIZE: () => DEFAULT_MAX_REQUEST_SIZE,
49
50
  Dataset: () => Dataset2,
51
+ DatasetPipeline: () => DatasetPipeline,
50
52
  ERR_PERMALINK: () => ERR_PERMALINK,
51
53
  Eval: () => Eval,
52
54
  EvalResultWithSummary: () => EvalResultWithSummary,
@@ -267,6 +269,7 @@ var iso = {
267
269
  getRepoInfo: async (_settings) => void 0,
268
270
  getPastNAncestors: async () => [],
269
271
  getEnv: (_name) => void 0,
272
+ getBraintrustApiKey: async () => void 0,
270
273
  getCallerLocation: () => void 0,
271
274
  newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
272
275
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -4110,6 +4113,76 @@ var LRUCache = class {
4110
4113
  }
4111
4114
  };
4112
4115
 
4116
+ // src/prompt-cache/cache-config.ts
4117
+ var CACHE_LOCATION_ENV_VAR = "BRAINTRUST_CACHE_LOCATION";
4118
+ var DEFAULT_CACHE_MEMORY_MAX = 1 << 10;
4119
+ var DEFAULT_CACHE_DISK_MAX = 1 << 20;
4120
+ var warnedInvalidCacheModeEnvValue = false;
4121
+ var warnedUnavailableDiskCacheMode = false;
4122
+ function warnInvalidCacheMode(value) {
4123
+ if (warnedInvalidCacheModeEnvValue) {
4124
+ return;
4125
+ }
4126
+ warnedInvalidCacheModeEnvValue = true;
4127
+ debugLogger.warn(
4128
+ `Invalid ${CACHE_LOCATION_ENV_VAR} value "${value}". Expected "mixed", "memory", "disk", or "none". Falling back to "mixed".`
4129
+ );
4130
+ }
4131
+ function warnUnavailableDiskCache() {
4132
+ if (warnedUnavailableDiskCacheMode) {
4133
+ return;
4134
+ }
4135
+ warnedUnavailableDiskCacheMode = true;
4136
+ debugLogger.warn(
4137
+ `Disk cache is not supported on this platform, so ${CACHE_LOCATION_ENV_VAR}="disk" disables prompt and parameters caching.`
4138
+ );
4139
+ }
4140
+ function parseCacheMode() {
4141
+ const value = isomorph_default.getEnv(CACHE_LOCATION_ENV_VAR);
4142
+ const normalized = value?.trim().toLowerCase();
4143
+ if (!normalized) {
4144
+ return "mixed";
4145
+ }
4146
+ if (normalized === "mixed" || normalized === "memory" || normalized === "disk" || normalized === "none") {
4147
+ return normalized;
4148
+ }
4149
+ warnInvalidCacheMode(value ?? "");
4150
+ return "mixed";
4151
+ }
4152
+ function parsePositiveIntegerEnv(envVar, defaultValue) {
4153
+ const value = Number(isomorph_default.getEnv(envVar));
4154
+ return Number.isInteger(value) && value > 0 ? value : defaultValue;
4155
+ }
4156
+ function createCacheLayers({
4157
+ memoryMaxEnvVar,
4158
+ diskCacheDirEnvVar,
4159
+ diskMaxEnvVar,
4160
+ getDefaultDiskCacheDir
4161
+ }) {
4162
+ const mode = parseCacheMode();
4163
+ const memoryCache = mode === "mixed" || mode === "memory" ? new LRUCache({
4164
+ max: parsePositiveIntegerEnv(
4165
+ memoryMaxEnvVar,
4166
+ DEFAULT_CACHE_MEMORY_MAX
4167
+ )
4168
+ }) : void 0;
4169
+ let diskCache;
4170
+ if (mode === "mixed" || mode === "disk") {
4171
+ if (canUseDiskCache()) {
4172
+ diskCache = new DiskCache({
4173
+ cacheDir: isomorph_default.getEnv(diskCacheDirEnvVar) ?? getDefaultDiskCacheDir(),
4174
+ max: parsePositiveIntegerEnv(diskMaxEnvVar, DEFAULT_CACHE_DISK_MAX)
4175
+ });
4176
+ } else if (mode === "disk") {
4177
+ warnUnavailableDiskCache();
4178
+ }
4179
+ }
4180
+ if (diskCache) {
4181
+ return { memoryCache, diskCache };
4182
+ }
4183
+ return { memoryCache };
4184
+ }
4185
+
4113
4186
  // src/prompt-cache/prompt-cache.ts
4114
4187
  function createCacheKey(key) {
4115
4188
  if (key.id) {
@@ -4137,16 +4210,18 @@ var PromptCache = class {
4137
4210
  */
4138
4211
  async get(key) {
4139
4212
  const cacheKey = createCacheKey(key);
4140
- const memoryPrompt = this.memoryCache.get(cacheKey);
4141
- if (memoryPrompt !== void 0) {
4142
- return memoryPrompt;
4213
+ if (this.memoryCache) {
4214
+ const memoryPrompt = this.memoryCache.get(cacheKey);
4215
+ if (memoryPrompt !== void 0) {
4216
+ return memoryPrompt;
4217
+ }
4143
4218
  }
4144
4219
  if (this.diskCache) {
4145
4220
  const diskPrompt = await this.diskCache.get(cacheKey);
4146
4221
  if (!diskPrompt) {
4147
4222
  return void 0;
4148
4223
  }
4149
- this.memoryCache.set(cacheKey, diskPrompt);
4224
+ this.memoryCache?.set(cacheKey, diskPrompt);
4150
4225
  return diskPrompt;
4151
4226
  }
4152
4227
  return void 0;
@@ -4161,7 +4236,7 @@ var PromptCache = class {
4161
4236
  */
4162
4237
  async set(key, value) {
4163
4238
  const cacheKey = createCacheKey(key);
4164
- this.memoryCache.set(cacheKey, value);
4239
+ this.memoryCache?.set(cacheKey, value);
4165
4240
  if (this.diskCache) {
4166
4241
  await this.diskCache.set(cacheKey, value);
4167
4242
  }
@@ -4191,23 +4266,25 @@ var ParametersCache = class {
4191
4266
  }
4192
4267
  async get(key) {
4193
4268
  const cacheKey = createCacheKey2(key);
4194
- const memoryParams = this.memoryCache.get(cacheKey);
4195
- if (memoryParams !== void 0) {
4196
- return memoryParams;
4269
+ if (this.memoryCache) {
4270
+ const memoryParams = this.memoryCache.get(cacheKey);
4271
+ if (memoryParams !== void 0) {
4272
+ return memoryParams;
4273
+ }
4197
4274
  }
4198
4275
  if (this.diskCache) {
4199
4276
  const diskParams = await this.diskCache.get(cacheKey);
4200
4277
  if (!diskParams) {
4201
4278
  return void 0;
4202
4279
  }
4203
- this.memoryCache.set(cacheKey, diskParams);
4280
+ this.memoryCache?.set(cacheKey, diskParams);
4204
4281
  return diskParams;
4205
4282
  }
4206
4283
  return void 0;
4207
4284
  }
4208
4285
  async set(key, value) {
4209
4286
  const cacheKey = createCacheKey2(key);
4210
- this.memoryCache.set(cacheKey, value);
4287
+ this.memoryCache?.set(cacheKey, value);
4211
4288
  if (this.diskCache) {
4212
4289
  await this.diskCache.set(cacheKey, value);
4213
4290
  }
@@ -4739,21 +4816,22 @@ var BraintrustState = class _BraintrustState {
4739
4816
  setGlobalDebugLogLevel(void 0);
4740
4817
  }
4741
4818
  this.resetLoginInfo();
4742
- const memoryCache = new LRUCache({
4743
- max: Number(isomorph_default.getEnv("BRAINTRUST_PROMPT_CACHE_MEMORY_MAX")) ?? 1 << 10
4819
+ const { memoryCache, diskCache } = createCacheLayers({
4820
+ memoryMaxEnvVar: "BRAINTRUST_PROMPT_CACHE_MEMORY_MAX",
4821
+ diskCacheDirEnvVar: "BRAINTRUST_PROMPT_CACHE_DIR",
4822
+ diskMaxEnvVar: "BRAINTRUST_PROMPT_CACHE_DISK_MAX",
4823
+ getDefaultDiskCacheDir: () => `${isomorph_default.getEnv("HOME") ?? isomorph_default.homedir()}/.braintrust/prompt_cache`
4744
4824
  });
4745
- const diskCache = canUseDiskCache() ? new DiskCache({
4746
- cacheDir: isomorph_default.getEnv("BRAINTRUST_PROMPT_CACHE_DIR") ?? `${isomorph_default.getEnv("HOME") ?? isomorph_default.homedir()}/.braintrust/prompt_cache`,
4747
- max: Number(isomorph_default.getEnv("BRAINTRUST_PROMPT_CACHE_DISK_MAX")) ?? 1 << 20
4748
- }) : void 0;
4749
4825
  this.promptCache = new PromptCache({ memoryCache, diskCache });
4750
- const parametersMemoryCache = new LRUCache({
4751
- max: Number(isomorph_default.getEnv("BRAINTRUST_PARAMETERS_CACHE_MEMORY_MAX")) ?? 1 << 10
4826
+ const {
4827
+ memoryCache: parametersMemoryCache,
4828
+ diskCache: parametersDiskCache
4829
+ } = createCacheLayers({
4830
+ memoryMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_MEMORY_MAX",
4831
+ diskCacheDirEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DIR",
4832
+ diskMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DISK_MAX",
4833
+ getDefaultDiskCacheDir: () => `${isomorph_default.getEnv("HOME") ?? isomorph_default.homedir()}/.braintrust/parameters_cache`
4752
4834
  });
4753
- const parametersDiskCache = canUseDiskCache() ? new DiskCache({
4754
- cacheDir: isomorph_default.getEnv("BRAINTRUST_PARAMETERS_CACHE_DIR") ?? `${isomorph_default.getEnv("HOME") ?? isomorph_default.homedir()}/.braintrust/parameters_cache`,
4755
- max: Number(isomorph_default.getEnv("BRAINTRUST_PARAMETERS_CACHE_DISK_MAX")) ?? 1 << 20
4756
- }) : void 0;
4757
4835
  this.parametersCache = new ParametersCache({
4758
4836
  memoryCache: parametersMemoryCache,
4759
4837
  diskCache: parametersDiskCache
@@ -5606,6 +5684,19 @@ var JSONAttachment = class extends Attachment {
5606
5684
  */
5607
5685
  constructor(data, options) {
5608
5686
  const { filename = "data.json", pretty = false, state } = options ?? {};
5687
+ const deferredJsonAttachment = globalThis.__BT_DATASET_PIPELINE_DEFER_JSON_ATTACHMENT__;
5688
+ if (deferredJsonAttachment) {
5689
+ super({
5690
+ data: new Blob([]),
5691
+ filename,
5692
+ contentType: "application/json",
5693
+ state
5694
+ });
5695
+ return deferredJsonAttachment(data, {
5696
+ filename,
5697
+ pretty
5698
+ });
5699
+ }
5609
5700
  const jsonString = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
5610
5701
  const blob = new Blob([jsonString], { type: "application/json" });
5611
5702
  super({
@@ -7598,10 +7689,11 @@ async function login(options = {}) {
7598
7689
  async function loginToState(options = {}) {
7599
7690
  const {
7600
7691
  appUrl = isomorph_default.getEnv("BRAINTRUST_APP_URL") || "https://www.braintrust.dev",
7601
- apiKey = isomorph_default.getEnv("BRAINTRUST_API_KEY"),
7692
+ apiKey: apiKeyArg,
7602
7693
  orgName = isomorph_default.getEnv("BRAINTRUST_ORG_NAME"),
7603
7694
  fetch: fetch2 = globalThis.fetch
7604
7695
  } = options || {};
7696
+ const apiKey = apiKeyArg !== void 0 ? apiKeyArg : await isomorph_default.getBraintrustApiKey();
7605
7697
  const appPublicUrl = isomorph_default.getEnv("BRAINTRUST_APP_PUBLIC_URL") || appUrl;
7606
7698
  const state = new BraintrustState(options);
7607
7699
  state.resetLoginInfo();
@@ -8842,9 +8934,15 @@ var SpanImpl = class _SpanImpl {
8842
8934
  const cachedSpan = {
8843
8935
  input: partialRecord.input,
8844
8936
  output: partialRecord.output,
8937
+ expected: partialRecord.expected,
8938
+ error: partialRecord.error,
8939
+ scores: partialRecord.scores,
8940
+ metrics: partialRecord.metrics,
8845
8941
  metadata: partialRecord.metadata,
8942
+ tags: partialRecord.tags,
8846
8943
  span_id: this._spanId,
8847
8944
  span_parents: this._spanParents,
8945
+ is_root: this._spanId === this._rootSpanId,
8848
8946
  span_attributes: partialRecord.span_attributes
8849
8947
  };
8850
8948
  this._state.spanCache.queueWrite(
@@ -9180,6 +9278,7 @@ var Dataset2 = class extends ObjectFetcher {
9180
9278
  metadata,
9181
9279
  tags,
9182
9280
  output,
9281
+ origin,
9183
9282
  isMerge
9184
9283
  }) {
9185
9284
  return new LazyValue(async () => {
@@ -9194,6 +9293,7 @@ var Dataset2 = class extends ObjectFetcher {
9194
9293
  created: !isMerge ? (/* @__PURE__ */ new Date()).toISOString() : void 0,
9195
9294
  //if we're merging/updating an event we will not add this ts
9196
9295
  metadata,
9296
+ origin,
9197
9297
  ...!!isMerge ? {
9198
9298
  [IS_MERGE_FIELD]: true
9199
9299
  } : {}
@@ -9213,6 +9313,7 @@ var Dataset2 = class extends ObjectFetcher {
9213
9313
  * about anything else that's relevant, that you can use to help find and analyze examples later. For example, you could log the
9214
9314
  * `prompt`, example's `id`, or anything else that would be useful to slice/dice later. The values in `metadata` can be any
9215
9315
  * JSON-serializable type, but its keys must be strings.
9316
+ * @param event.origin (Optional) a reference to the source object this dataset record was derived from.
9216
9317
  * @param event.id (Optional) a unique identifier for the event. If you don't provide one, Braintrust will generate one for you.
9217
9318
  * @param event.output: (Deprecated) The output of your application. Use `expected` instead.
9218
9319
  * @returns The `id` of the logged record.
@@ -9223,7 +9324,8 @@ var Dataset2 = class extends ObjectFetcher {
9223
9324
  metadata,
9224
9325
  tags,
9225
9326
  id,
9226
- output
9327
+ output,
9328
+ origin
9227
9329
  }) {
9228
9330
  this.validateEvent({ metadata, expected, output, tags });
9229
9331
  const rowId = id || (0, import_uuid2.v4)();
@@ -9235,6 +9337,7 @@ var Dataset2 = class extends ObjectFetcher {
9235
9337
  metadata,
9236
9338
  tags,
9237
9339
  output,
9340
+ origin,
9238
9341
  isMerge: false
9239
9342
  })
9240
9343
  );
@@ -25868,7 +25971,7 @@ var BraintrustPlugin = class extends BasePlugin {
25868
25971
  this.config = config;
25869
25972
  }
25870
25973
  onEnable() {
25871
- const integrations = this.config.integrations || {};
25974
+ const integrations = this.config.integrations ?? {};
25872
25975
  if (integrations.openai !== false) {
25873
25976
  this.openaiPlugin = new OpenAIPlugin();
25874
25977
  this.openaiPlugin.enable();
@@ -25933,7 +26036,7 @@ var BraintrustPlugin = class extends BasePlugin {
25933
26036
  this.genkitPlugin = new GenkitPlugin();
25934
26037
  this.genkitPlugin.enable();
25935
26038
  }
25936
- if (getIntegrationConfig(integrations, "gitHubCopilot") !== false) {
26039
+ if (integrations.gitHubCopilot !== false) {
25937
26040
  this.gitHubCopilotPlugin = new GitHubCopilotPlugin();
25938
26041
  this.gitHubCopilotPlugin.enable();
25939
26042
  }
@@ -26046,6 +26149,7 @@ var envIntegrationAliases = {
26046
26149
  cursorsdk: "cursorSDK",
26047
26150
  flue: "flue",
26048
26151
  "flue-runtime": "flue",
26152
+ mastra: "mastra",
26049
26153
  "openai-agents": "openAIAgents",
26050
26154
  openaiagents: "openAIAgents",
26051
26155
  "openai-agents-core": "openAIAgents",
@@ -26088,6 +26192,7 @@ function getDefaultInstrumentationIntegrations() {
26088
26192
  cursor: true,
26089
26193
  cursorSDK: true,
26090
26194
  flue: true,
26195
+ mastra: true,
26091
26196
  openAIAgents: true,
26092
26197
  openrouter: true,
26093
26198
  openrouterAgent: true,
@@ -26230,6 +26335,10 @@ function configureEdgeLight() {
26230
26335
  }
26231
26336
  return process.env[name];
26232
26337
  };
26338
+ isomorph_default.getBraintrustApiKey = async () => {
26339
+ const value = isomorph_default.getEnv("BRAINTRUST_API_KEY");
26340
+ return value?.trim() ? value : void 0;
26341
+ };
26233
26342
  isomorph_default.hash = (data) => {
26234
26343
  let hash = 0;
26235
26344
  for (let i = 0; i < data.length; i++) {
@@ -26256,6 +26365,7 @@ __export(exports_exports, {
26256
26365
  BaseExperiment: () => BaseExperiment,
26257
26366
  BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
26258
26367
  BraintrustMiddleware: () => BraintrustMiddleware,
26368
+ BraintrustObservabilityExporter: () => BraintrustObservabilityExporter,
26259
26369
  BraintrustState: () => BraintrustState,
26260
26370
  BraintrustStream: () => BraintrustStream,
26261
26371
  CachedSpanFetcher: () => CachedSpanFetcher,
@@ -26265,6 +26375,7 @@ __export(exports_exports, {
26265
26375
  DEFAULT_FETCH_BATCH_SIZE: () => DEFAULT_FETCH_BATCH_SIZE,
26266
26376
  DEFAULT_MAX_REQUEST_SIZE: () => DEFAULT_MAX_REQUEST_SIZE,
26267
26377
  Dataset: () => Dataset2,
26378
+ DatasetPipeline: () => DatasetPipeline,
26268
26379
  ERR_PERMALINK: () => ERR_PERMALINK,
26269
26380
  Eval: () => Eval,
26270
26381
  EvalResultWithSummary: () => EvalResultWithSummary,
@@ -27871,6 +27982,196 @@ function toolRunnerProxy(toolRunner, anthropic, channel2) {
27871
27982
  }
27872
27983
 
27873
27984
  // src/wrappers/mastra.ts
27985
+ var MASTRA_BRAINTRUST_EXPORTER_NAME = "braintrust";
27986
+ var SPAN_TYPE_MAP = {
27987
+ agent_run: "task" /* TASK */,
27988
+ model_generation: "llm" /* LLM */,
27989
+ model_step: "llm" /* LLM */,
27990
+ model_chunk: "llm" /* LLM */,
27991
+ tool_call: "tool" /* TOOL */,
27992
+ mcp_tool_call: "tool" /* TOOL */,
27993
+ workflow_run: "task" /* TASK */,
27994
+ workflow_step: "function" /* FUNCTION */,
27995
+ workflow_conditional: "function" /* FUNCTION */,
27996
+ workflow_conditional_eval: "function" /* FUNCTION */,
27997
+ workflow_parallel: "function" /* FUNCTION */,
27998
+ workflow_loop: "function" /* FUNCTION */,
27999
+ workflow_sleep: "function" /* FUNCTION */,
28000
+ workflow_wait_event: "function" /* FUNCTION */,
28001
+ memory_operation: "function" /* FUNCTION */,
28002
+ workspace_action: "function" /* FUNCTION */,
28003
+ rag_ingestion: "task" /* TASK */,
28004
+ rag_embedding: "llm" /* LLM */,
28005
+ rag_vector_operation: "function" /* FUNCTION */,
28006
+ rag_action: "function" /* FUNCTION */,
28007
+ graph_action: "function" /* FUNCTION */,
28008
+ scorer_run: "score" /* SCORE */,
28009
+ scorer_step: "score" /* SCORE */,
28010
+ processor_run: "function" /* FUNCTION */,
28011
+ generic: "function" /* FUNCTION */
28012
+ };
28013
+ function spanTypeFor(mastraType) {
28014
+ return SPAN_TYPE_MAP[mastraType] ?? "function" /* FUNCTION */;
28015
+ }
28016
+ function epochSeconds(value) {
28017
+ if (value === void 0) return void 0;
28018
+ const ms = value instanceof Date ? value.getTime() : typeof value === "number" ? value : Date.parse(value);
28019
+ return Number.isFinite(ms) ? ms / 1e3 : void 0;
28020
+ }
28021
+ function modelMetrics(attributes) {
28022
+ if (!isObject(attributes)) return void 0;
28023
+ const usage = isObject(attributes.usage) ? attributes.usage : void 0;
28024
+ if (!usage) return void 0;
28025
+ const out = {};
28026
+ if (typeof usage.inputTokens === "number")
28027
+ out.prompt_tokens = usage.inputTokens;
28028
+ if (typeof usage.outputTokens === "number")
28029
+ out.completion_tokens = usage.outputTokens;
28030
+ if (typeof usage.inputTokens === "number" && typeof usage.outputTokens === "number") {
28031
+ out.tokens = usage.inputTokens + usage.outputTokens;
28032
+ }
28033
+ const inputDetails = isObject(usage.inputDetails) ? usage.inputDetails : void 0;
28034
+ const outputDetails = isObject(usage.outputDetails) ? usage.outputDetails : void 0;
28035
+ if (inputDetails && typeof inputDetails.cacheRead === "number") {
28036
+ out.prompt_cached_tokens = inputDetails.cacheRead;
28037
+ }
28038
+ if (inputDetails && typeof inputDetails.cacheWrite === "number") {
28039
+ out.prompt_cache_creation_tokens = inputDetails.cacheWrite;
28040
+ }
28041
+ if (outputDetails && typeof outputDetails.reasoning === "number") {
28042
+ out.completion_reasoning_tokens = outputDetails.reasoning;
28043
+ }
28044
+ return Object.keys(out).length > 0 ? out : void 0;
28045
+ }
28046
+ function buildMetadata(exported) {
28047
+ const out = {};
28048
+ if (exported.entityId !== void 0) out.entity_id = exported.entityId;
28049
+ if (exported.entityName !== void 0) out.entity_name = exported.entityName;
28050
+ if (exported.entityType !== void 0) out.entity_type = exported.entityType;
28051
+ if (exported.metadata && isObject(exported.metadata)) {
28052
+ Object.assign(out, exported.metadata);
28053
+ }
28054
+ if (exported.attributes && isObject(exported.attributes)) {
28055
+ for (const [key, value] of Object.entries(exported.attributes)) {
28056
+ if (key === "usage") continue;
28057
+ if (value !== void 0) out[key] = value;
28058
+ }
28059
+ }
28060
+ if (exported.tags && exported.tags.length > 0) {
28061
+ out.tags = exported.tags;
28062
+ }
28063
+ if (exported.requestContext && isObject(exported.requestContext)) {
28064
+ out.request_context = exported.requestContext;
28065
+ }
28066
+ return out;
28067
+ }
28068
+ var BraintrustObservabilityExporter = class {
28069
+ name = MASTRA_BRAINTRUST_EXPORTER_NAME;
28070
+ spans = /* @__PURE__ */ new Map();
28071
+ // Captured at the first SPAN_STARTED event. Mastra's observability bus may
28072
+ // dispatch later events outside the user's AsyncLocalStorage context, where
28073
+ // `currentSpan()` returns NOOP_SPAN — which would make our `startSpan()`
28074
+ // calls go to a no-op logger and silently drop. Anchoring on the parent
28075
+ // we observe while still in-context keeps the whole Mastra subtree under
28076
+ // the user's traced scenario.
28077
+ capturedParent;
28078
+ constructor() {
28079
+ _internalSetInitialState();
28080
+ }
28081
+ async exportTracingEvent(event) {
28082
+ const exported = event.exportedSpan;
28083
+ if (exported.isInternal === true) return;
28084
+ try {
28085
+ switch (event.type) {
28086
+ case "span_started":
28087
+ this.onStart(exported);
28088
+ break;
28089
+ case "span_updated":
28090
+ this.onUpdate(exported);
28091
+ break;
28092
+ case "span_ended":
28093
+ this.onEnd(exported);
28094
+ break;
28095
+ }
28096
+ } catch (err) {
28097
+ logExporterError(err);
28098
+ }
28099
+ }
28100
+ async flush() {
28101
+ const state = _internalGetGlobalState();
28102
+ if (state) {
28103
+ await state.bgLogger().flush();
28104
+ }
28105
+ }
28106
+ async shutdown() {
28107
+ await this.flush();
28108
+ this.spans.clear();
28109
+ }
28110
+ onStart(exported) {
28111
+ if (this.spans.has(exported.id)) return;
28112
+ const args = {
28113
+ name: exported.name,
28114
+ spanAttributes: { type: spanTypeFor(exported.type) },
28115
+ startTime: epochSeconds(exported.startTime)
28116
+ };
28117
+ const parentRecord = exported.parentSpanId ? this.spans.get(exported.parentSpanId) : void 0;
28118
+ if (!this.capturedParent) {
28119
+ const probe = currentSpan();
28120
+ if (probe && probe.spanId) {
28121
+ this.capturedParent = probe;
28122
+ }
28123
+ }
28124
+ const span = parentRecord ? parentRecord.span.startSpan(args) : this.capturedParent ? this.capturedParent.startSpan(args) : startSpan(args);
28125
+ const record = { span, hasLoggedInput: false };
28126
+ this.logPayload(record, exported);
28127
+ this.spans.set(exported.id, record);
28128
+ if (exported.isEvent === true) {
28129
+ span.end({ endTime: args.startTime });
28130
+ this.spans.delete(exported.id);
28131
+ }
28132
+ }
28133
+ onUpdate(exported) {
28134
+ const record = this.spans.get(exported.id);
28135
+ if (!record) return;
28136
+ this.logPayload(record, exported);
28137
+ }
28138
+ onEnd(exported) {
28139
+ const record = this.spans.get(exported.id);
28140
+ if (!record) return;
28141
+ this.logPayload(record, exported);
28142
+ if (exported.errorInfo) {
28143
+ record.span.log({
28144
+ error: exported.errorInfo.message || exported.errorInfo.name || "Unknown Mastra error"
28145
+ });
28146
+ }
28147
+ record.span.end({ endTime: epochSeconds(exported.endTime) });
28148
+ this.spans.delete(exported.id);
28149
+ }
28150
+ logPayload(record, exported) {
28151
+ const event = {};
28152
+ if (exported.input !== void 0) {
28153
+ event.input = exported.input;
28154
+ record.hasLoggedInput = true;
28155
+ }
28156
+ if (exported.output !== void 0) {
28157
+ event.output = exported.output;
28158
+ }
28159
+ const metadata = buildMetadata(exported);
28160
+ if (Object.keys(metadata).length > 0) {
28161
+ event.metadata = metadata;
28162
+ }
28163
+ const metrics = modelMetrics(exported.attributes);
28164
+ if (metrics) {
28165
+ event.metrics = metrics;
28166
+ }
28167
+ if (Object.keys(event).length > 0) {
28168
+ record.span.log(event);
28169
+ }
28170
+ }
28171
+ };
28172
+ function logExporterError(err) {
28173
+ debugLogger.warn("Mastra exporter failure:", err);
28174
+ }
27874
28175
  function wrapMastraAgent(agent, _options) {
27875
28176
  return agent;
27876
28177
  }
@@ -29523,10 +29824,12 @@ function formatExperimentSummary(summary) {
29523
29824
  // src/wrappers/shared/flush.ts
29524
29825
  async function summarizeAndFlush(experiment, options) {
29525
29826
  const shouldDisplay = options.displaySummary ?? true;
29526
- const summary = await experiment.summarize();
29527
- if (shouldDisplay) {
29528
- console.log(formatExperimentSummary(summary));
29827
+ if (!shouldDisplay) {
29828
+ await experiment.flush();
29829
+ return;
29529
29830
  }
29831
+ const summary = await experiment.summarize();
29832
+ console.log(formatExperimentSummary(summary));
29530
29833
  }
29531
29834
 
29532
29835
  // src/wrappers/vitest/flush-manager.ts
@@ -31390,8 +31693,12 @@ var waterfall$1 = awaitify(waterfall);
31390
31693
 
31391
31694
  // src/trace.ts
31392
31695
  var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
31393
- constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter) {
31394
- const filterExpr = _SpanFetcher.buildFilter(rootSpanId, spanTypeFilter);
31696
+ constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false) {
31697
+ const filterExpr = _SpanFetcher.buildFilter(
31698
+ rootSpanId,
31699
+ spanTypeFilter,
31700
+ includeScorers
31701
+ );
31395
31702
  super(objectType, void 0, void 0, {
31396
31703
  filter: filterExpr
31397
31704
  });
@@ -31400,16 +31707,17 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
31400
31707
  this._state = _state;
31401
31708
  this.spanTypeFilter = spanTypeFilter;
31402
31709
  }
31403
- static buildFilter(rootSpanId, spanTypeFilter) {
31710
+ static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
31404
31711
  const children = [
31405
31712
  // Base filter: root_span_id = 'value'
31406
31713
  {
31407
31714
  op: "eq",
31408
31715
  left: { op: "ident", name: ["root_span_id"] },
31409
31716
  right: { op: "literal", value: rootSpanId }
31410
- },
31411
- // Exclude span_attributes.purpose = 'score'
31412
- {
31717
+ }
31718
+ ];
31719
+ if (!includeScorers) {
31720
+ children.push({
31413
31721
  op: "or",
31414
31722
  children: [
31415
31723
  {
@@ -31422,8 +31730,8 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
31422
31730
  right: { op: "literal", value: "scorer" }
31423
31731
  }
31424
31732
  ]
31425
- }
31426
- ];
31733
+ });
31734
+ }
31427
31735
  if (spanTypeFilter && spanTypeFilter.length > 0) {
31428
31736
  children.push({
31429
31737
  op: "in",
@@ -31449,35 +31757,49 @@ var CachedSpanFetcher = class {
31449
31757
  fetchFn;
31450
31758
  constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {
31451
31759
  if (typeof objectTypeOrFetchFn === "function") {
31452
- this.fetchFn = objectTypeOrFetchFn;
31760
+ this.fetchFn = (spanType) => objectTypeOrFetchFn(spanType);
31453
31761
  } else {
31454
31762
  const objectType = objectTypeOrFetchFn;
31455
- this.fetchFn = async (spanType) => {
31763
+ this.fetchFn = async (spanType, includeScorers) => {
31456
31764
  const state = await getState();
31457
31765
  const fetcher = new SpanFetcher(
31458
31766
  objectType,
31459
31767
  objectId,
31460
31768
  rootSpanId,
31461
31769
  state,
31462
- spanType
31770
+ spanType,
31771
+ includeScorers
31463
31772
  );
31464
31773
  const rows = await fetcher.fetchedData();
31465
- return rows.filter((row) => row.span_attributes?.purpose !== "scorer").map((row) => ({
31774
+ return rows.map((row) => ({
31466
31775
  input: row.input,
31467
31776
  output: row.output,
31777
+ expected: row.expected,
31778
+ error: row.error,
31779
+ scores: row.scores,
31780
+ metrics: row.metrics,
31468
31781
  metadata: row.metadata,
31469
31782
  span_id: row.span_id,
31470
31783
  span_parents: row.span_parents,
31784
+ is_root: row.is_root,
31471
31785
  span_attributes: row.span_attributes,
31472
31786
  id: row.id,
31473
31787
  _xact_id: row._xact_id,
31474
31788
  _pagination_key: row._pagination_key,
31475
- root_span_id: row.root_span_id
31789
+ root_span_id: row.root_span_id,
31790
+ created: row.created,
31791
+ tags: row.tags
31476
31792
  }));
31477
31793
  };
31478
31794
  }
31479
31795
  }
31480
- async getSpans({ spanType } = {}) {
31796
+ async getSpans({
31797
+ spanType,
31798
+ includeScorers = false
31799
+ } = {}) {
31800
+ if (includeScorers) {
31801
+ return this.fetchFn(spanType, true);
31802
+ }
31481
31803
  if (this.allFetched) {
31482
31804
  return this.getFromCache(spanType);
31483
31805
  }
@@ -31494,7 +31816,7 @@ var CachedSpanFetcher = class {
31494
31816
  return this.getFromCache(spanType);
31495
31817
  }
31496
31818
  async fetchSpans(spanType) {
31497
- const spans = await this.fetchFn(spanType);
31819
+ const spans = await this.fetchFn(spanType, false);
31498
31820
  for (const span of spans) {
31499
31821
  const type = span.span_attributes?.type ?? "";
31500
31822
  const existing = this.spanCache.get(type) ?? [];
@@ -31572,10 +31894,13 @@ var LocalTrace = class {
31572
31894
  * First checks the local span cache for recently logged spans, then falls
31573
31895
  * back to CachedSpanFetcher which handles BTQL fetching and caching.
31574
31896
  */
31575
- async getSpans({ spanType } = {}) {
31897
+ async getSpans({
31898
+ spanType,
31899
+ includeScorers = false
31900
+ } = {}) {
31576
31901
  const cachedSpans = this.state.spanCache.getByRootSpanId(this.rootSpanId);
31577
31902
  if (cachedSpans && cachedSpans.length > 0) {
31578
- let spans = cachedSpans.filter(
31903
+ let spans = includeScorers ? cachedSpans : cachedSpans.filter(
31579
31904
  (span) => span.span_attributes?.purpose !== "scorer"
31580
31905
  );
31581
31906
  if (spanType && spanType.length > 0) {
@@ -31586,13 +31911,19 @@ var LocalTrace = class {
31586
31911
  return spans.map((span) => ({
31587
31912
  input: span.input,
31588
31913
  output: span.output,
31914
+ expected: span.expected,
31915
+ error: span.error,
31916
+ scores: span.scores,
31917
+ metrics: span.metrics,
31589
31918
  metadata: span.metadata,
31590
31919
  span_id: span.span_id,
31591
31920
  span_parents: span.span_parents,
31592
- span_attributes: span.span_attributes
31921
+ is_root: span.is_root,
31922
+ span_attributes: span.span_attributes,
31923
+ tags: span.tags
31593
31924
  }));
31594
31925
  }
31595
- return this.cachedFetcher.getSpans({ spanType });
31926
+ return this.cachedFetcher.getSpans({ spanType, includeScorers });
31596
31927
  }
31597
31928
  /**
31598
31929
  * Get the thread (preprocessed messages) for this trace.
@@ -32781,6 +33112,34 @@ var defaultReporter = {
32781
33112
  }
32782
33113
  };
32783
33114
 
33115
+ // src/dataset-pipeline.ts
33116
+ function DatasetPipeline(definition) {
33117
+ if (!globalThis.__braintrust_dataset_pipelines) {
33118
+ globalThis.__braintrust_dataset_pipelines = [];
33119
+ }
33120
+ const storedDefinition = {
33121
+ name: definition.name,
33122
+ source: {
33123
+ projectId: definition.source.projectId,
33124
+ projectName: definition.source.projectName,
33125
+ orgName: definition.source.orgName,
33126
+ filter: definition.source.filter,
33127
+ scope: definition.source.scope ?? "span"
33128
+ },
33129
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
33130
+ transform: definition.transform,
33131
+ target: {
33132
+ projectId: definition.target.projectId,
33133
+ projectName: definition.target.projectName,
33134
+ orgName: definition.target.orgName,
33135
+ datasetName: definition.target.datasetName,
33136
+ description: definition.target.description,
33137
+ metadata: definition.target.metadata
33138
+ }
33139
+ };
33140
+ globalThis.__braintrust_dataset_pipelines.push(storedDefinition);
33141
+ }
33142
+
32784
33143
  // src/framework2.ts
32785
33144
  var import_v312 = require("zod/v3");
32786
33145
  var currentFilename = typeof __filename !== "undefined" ? __filename : "unknown";