braintrust 3.21.0 → 3.22.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/dev/dist/index.js CHANGED
@@ -2510,19 +2510,30 @@ var CallEvent = _v3.z.union([
2510
2510
  var ChatCompletionContentPartTextWithTitle = _v3.z.object({
2511
2511
  text: _v3.z.string().default(""),
2512
2512
  type: _v3.z.literal("text"),
2513
- cache_control: _v3.z.object({ type: _v3.z.literal("ephemeral") }).optional()
2513
+ cache_control: _v3.z.object({
2514
+ type: _v3.z.literal("ephemeral"),
2515
+ ttl: _v3.z.enum(["5m", "1h"]).optional()
2516
+ }).optional()
2514
2517
  });
2515
2518
  var ChatCompletionContentPartImageWithTitle = _v3.z.object({
2516
2519
  image_url: _v3.z.object({
2517
2520
  url: _v3.z.string(),
2518
2521
  detail: _v3.z.union([_v3.z.literal("auto"), _v3.z.literal("low"), _v3.z.literal("high")]).optional()
2519
2522
  }),
2520
- type: _v3.z.literal("image_url")
2523
+ type: _v3.z.literal("image_url"),
2524
+ cache_control: _v3.z.object({
2525
+ type: _v3.z.literal("ephemeral"),
2526
+ ttl: _v3.z.enum(["5m", "1h"]).optional()
2527
+ }).optional()
2521
2528
  });
2522
2529
  var ChatCompletionContentPartFileFile = _v3.z.object({ file_data: _v3.z.string(), filename: _v3.z.string(), file_id: _v3.z.string() }).partial();
2523
2530
  var ChatCompletionContentPartFileWithTitle = _v3.z.object({
2524
2531
  file: ChatCompletionContentPartFileFile,
2525
- type: _v3.z.literal("file")
2532
+ type: _v3.z.literal("file"),
2533
+ cache_control: _v3.z.object({
2534
+ type: _v3.z.literal("ephemeral"),
2535
+ ttl: _v3.z.enum(["5m", "1h"]).optional()
2536
+ }).optional()
2526
2537
  });
2527
2538
  var ChatCompletionContentPart = _v3.z.union([
2528
2539
  ChatCompletionContentPartTextWithTitle,
@@ -2532,7 +2543,10 @@ var ChatCompletionContentPart = _v3.z.union([
2532
2543
  var ChatCompletionContentPartText = _v3.z.object({
2533
2544
  text: _v3.z.string().default(""),
2534
2545
  type: _v3.z.literal("text"),
2535
- cache_control: _v3.z.object({ type: _v3.z.literal("ephemeral") }).optional()
2546
+ cache_control: _v3.z.object({
2547
+ type: _v3.z.literal("ephemeral"),
2548
+ ttl: _v3.z.enum(["5m", "1h"]).optional()
2549
+ }).optional()
2536
2550
  });
2537
2551
  var ChatCompletionMessageToolCall = _v3.z.object({
2538
2552
  id: _v3.z.string(),
@@ -4585,13 +4599,23 @@ var LRUCache = class {
4585
4599
  * @returns The cached value if found, undefined otherwise.
4586
4600
  */
4587
4601
  get(key) {
4588
- const value = this.cache.get(key);
4589
- if (value === void 0) {
4602
+ const entry = this.cache.get(key);
4603
+ if (entry === void 0) {
4590
4604
  return void 0;
4591
4605
  }
4592
4606
  this.cache.delete(key);
4593
- this.cache.set(key, value);
4594
- return value;
4607
+ this.cache.set(key, entry);
4608
+ return entry.value;
4609
+ }
4610
+ /**
4611
+ * Checks whether a key exists and marks it as most recently used.
4612
+ */
4613
+ has(key) {
4614
+ if (!this.cache.has(key)) {
4615
+ return false;
4616
+ }
4617
+ this.get(key);
4618
+ return true;
4595
4619
  }
4596
4620
  /**
4597
4621
  * Stores a value in the cache.
@@ -4608,7 +4632,38 @@ var LRUCache = class {
4608
4632
  const first = this.cache.keys().next().value;
4609
4633
  this.cache.delete(first);
4610
4634
  }
4611
- this.cache.set(key, value);
4635
+ this.cache.set(key, { value });
4636
+ }
4637
+ /**
4638
+ * Removes an item from the cache.
4639
+ */
4640
+ delete(key) {
4641
+ return this.cache.delete(key);
4642
+ }
4643
+ /**
4644
+ * Iterates over cache entries from least to most recently used.
4645
+ */
4646
+ *entries() {
4647
+ for (const [key, entry] of this.cache) {
4648
+ yield [key, entry.value];
4649
+ }
4650
+ }
4651
+ /**
4652
+ * Iterates over cache keys from least to most recently used.
4653
+ */
4654
+ keys() {
4655
+ return this.cache.keys();
4656
+ }
4657
+ /**
4658
+ * Iterates over cache values from least to most recently used.
4659
+ */
4660
+ *values() {
4661
+ for (const entry of this.cache.values()) {
4662
+ yield entry.value;
4663
+ }
4664
+ }
4665
+ [Symbol.iterator]() {
4666
+ return this.entries();
4612
4667
  }
4613
4668
  /**
4614
4669
  * Removes all items from the cache.
@@ -5166,6 +5221,9 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
5166
5221
  return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
5167
5222
  }
5168
5223
  }
5224
+ var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
5225
+ "braintrust.initial-span-write-as-merge"
5226
+ );
5169
5227
  var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
5170
5228
  "braintrust.currentSpanStore"
5171
5229
  );
@@ -8984,7 +9042,7 @@ var SpanImpl = (_class13 = class _SpanImpl {
8984
9042
  this._spanId = resolvedIds.spanId;
8985
9043
  this._rootSpanId = resolvedIds.rootSpanId;
8986
9044
  this._spanParents = resolvedIds.spanParents;
8987
- this.isMerge = false;
9045
+ this.isMerge = args[INITIAL_SPAN_WRITE_AS_MERGE] === true;
8988
9046
  this.logInternal({ event, internalData });
8989
9047
  this.isMerge = true;
8990
9048
  }
@@ -30835,7 +30893,13 @@ var BraintrustObservabilityExporter = (_class29 = class {
30835
30893
  const args = {
30836
30894
  name: exported.name,
30837
30895
  spanAttributes: { type: spanTypeFor(exported.type) },
30838
- startTime: epochSeconds(exported.startTime)
30896
+ startTime: epochSeconds(exported.startTime),
30897
+ // Use the Mastra span id as the Braintrust row id so that
30898
+ // `logFeedback({ id: <mastra span id> })` (and Mastra's score events)
30899
+ // attach to the right row. Without this, `SpanImpl` auto-generates a
30900
+ // row id (`this._id = eventId ?? idGenerator.getSpanId()`) that no
30901
+ // external caller could know.
30902
+ event: { id: exported.id }
30839
30903
  };
30840
30904
  const parentRecord = exported.parentSpanId ? this.spans.get(exported.parentSpanId) : void 0;
30841
30905
  if (!this.capturedParent) {
@@ -2510,19 +2510,30 @@ var CallEvent = z6.union([
2510
2510
  var ChatCompletionContentPartTextWithTitle = z6.object({
2511
2511
  text: z6.string().default(""),
2512
2512
  type: z6.literal("text"),
2513
- cache_control: z6.object({ type: z6.literal("ephemeral") }).optional()
2513
+ cache_control: z6.object({
2514
+ type: z6.literal("ephemeral"),
2515
+ ttl: z6.enum(["5m", "1h"]).optional()
2516
+ }).optional()
2514
2517
  });
2515
2518
  var ChatCompletionContentPartImageWithTitle = z6.object({
2516
2519
  image_url: z6.object({
2517
2520
  url: z6.string(),
2518
2521
  detail: z6.union([z6.literal("auto"), z6.literal("low"), z6.literal("high")]).optional()
2519
2522
  }),
2520
- type: z6.literal("image_url")
2523
+ type: z6.literal("image_url"),
2524
+ cache_control: z6.object({
2525
+ type: z6.literal("ephemeral"),
2526
+ ttl: z6.enum(["5m", "1h"]).optional()
2527
+ }).optional()
2521
2528
  });
2522
2529
  var ChatCompletionContentPartFileFile = z6.object({ file_data: z6.string(), filename: z6.string(), file_id: z6.string() }).partial();
2523
2530
  var ChatCompletionContentPartFileWithTitle = z6.object({
2524
2531
  file: ChatCompletionContentPartFileFile,
2525
- type: z6.literal("file")
2532
+ type: z6.literal("file"),
2533
+ cache_control: z6.object({
2534
+ type: z6.literal("ephemeral"),
2535
+ ttl: z6.enum(["5m", "1h"]).optional()
2536
+ }).optional()
2526
2537
  });
2527
2538
  var ChatCompletionContentPart = z6.union([
2528
2539
  ChatCompletionContentPartTextWithTitle,
@@ -2532,7 +2543,10 @@ var ChatCompletionContentPart = z6.union([
2532
2543
  var ChatCompletionContentPartText = z6.object({
2533
2544
  text: z6.string().default(""),
2534
2545
  type: z6.literal("text"),
2535
- cache_control: z6.object({ type: z6.literal("ephemeral") }).optional()
2546
+ cache_control: z6.object({
2547
+ type: z6.literal("ephemeral"),
2548
+ ttl: z6.enum(["5m", "1h"]).optional()
2549
+ }).optional()
2536
2550
  });
2537
2551
  var ChatCompletionMessageToolCall = z6.object({
2538
2552
  id: z6.string(),
@@ -4585,13 +4599,23 @@ var LRUCache = class {
4585
4599
  * @returns The cached value if found, undefined otherwise.
4586
4600
  */
4587
4601
  get(key) {
4588
- const value = this.cache.get(key);
4589
- if (value === void 0) {
4602
+ const entry = this.cache.get(key);
4603
+ if (entry === void 0) {
4590
4604
  return void 0;
4591
4605
  }
4592
4606
  this.cache.delete(key);
4593
- this.cache.set(key, value);
4594
- return value;
4607
+ this.cache.set(key, entry);
4608
+ return entry.value;
4609
+ }
4610
+ /**
4611
+ * Checks whether a key exists and marks it as most recently used.
4612
+ */
4613
+ has(key) {
4614
+ if (!this.cache.has(key)) {
4615
+ return false;
4616
+ }
4617
+ this.get(key);
4618
+ return true;
4595
4619
  }
4596
4620
  /**
4597
4621
  * Stores a value in the cache.
@@ -4608,7 +4632,38 @@ var LRUCache = class {
4608
4632
  const first = this.cache.keys().next().value;
4609
4633
  this.cache.delete(first);
4610
4634
  }
4611
- this.cache.set(key, value);
4635
+ this.cache.set(key, { value });
4636
+ }
4637
+ /**
4638
+ * Removes an item from the cache.
4639
+ */
4640
+ delete(key) {
4641
+ return this.cache.delete(key);
4642
+ }
4643
+ /**
4644
+ * Iterates over cache entries from least to most recently used.
4645
+ */
4646
+ *entries() {
4647
+ for (const [key, entry] of this.cache) {
4648
+ yield [key, entry.value];
4649
+ }
4650
+ }
4651
+ /**
4652
+ * Iterates over cache keys from least to most recently used.
4653
+ */
4654
+ keys() {
4655
+ return this.cache.keys();
4656
+ }
4657
+ /**
4658
+ * Iterates over cache values from least to most recently used.
4659
+ */
4660
+ *values() {
4661
+ for (const entry of this.cache.values()) {
4662
+ yield entry.value;
4663
+ }
4664
+ }
4665
+ [Symbol.iterator]() {
4666
+ return this.entries();
4612
4667
  }
4613
4668
  /**
4614
4669
  * Removes all items from the cache.
@@ -5166,6 +5221,9 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
5166
5221
  return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
5167
5222
  }
5168
5223
  }
5224
+ var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
5225
+ "braintrust.initial-span-write-as-merge"
5226
+ );
5169
5227
  var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
5170
5228
  "braintrust.currentSpanStore"
5171
5229
  );
@@ -8984,7 +9042,7 @@ var SpanImpl = class _SpanImpl {
8984
9042
  this._spanId = resolvedIds.spanId;
8985
9043
  this._rootSpanId = resolvedIds.rootSpanId;
8986
9044
  this._spanParents = resolvedIds.spanParents;
8987
- this.isMerge = false;
9045
+ this.isMerge = args[INITIAL_SPAN_WRITE_AS_MERGE] === true;
8988
9046
  this.logInternal({ event, internalData });
8989
9047
  this.isMerge = true;
8990
9048
  }
@@ -30835,7 +30893,13 @@ var BraintrustObservabilityExporter = class {
30835
30893
  const args = {
30836
30894
  name: exported.name,
30837
30895
  spanAttributes: { type: spanTypeFor(exported.type) },
30838
- startTime: epochSeconds(exported.startTime)
30896
+ startTime: epochSeconds(exported.startTime),
30897
+ // Use the Mastra span id as the Braintrust row id so that
30898
+ // `logFeedback({ id: <mastra span id> })` (and Mastra's score events)
30899
+ // attach to the right row. Without this, `SpanImpl` auto-generates a
30900
+ // row id (`this._id = eventId ?? idGenerator.getSpanId()`) that no
30901
+ // external caller could know.
30902
+ event: { id: exported.id }
30839
30903
  };
30840
30904
  const parentRecord = exported.parentSpanId ? this.spans.get(exported.parentSpanId) : void 0;
30841
30905
  if (!this.capturedParent) {
@@ -2127,19 +2127,30 @@ var CallEvent = z6.union([
2127
2127
  var ChatCompletionContentPartTextWithTitle = z6.object({
2128
2128
  text: z6.string().default(""),
2129
2129
  type: z6.literal("text"),
2130
- cache_control: z6.object({ type: z6.literal("ephemeral") }).optional()
2130
+ cache_control: z6.object({
2131
+ type: z6.literal("ephemeral"),
2132
+ ttl: z6.enum(["5m", "1h"]).optional()
2133
+ }).optional()
2131
2134
  });
2132
2135
  var ChatCompletionContentPartImageWithTitle = z6.object({
2133
2136
  image_url: z6.object({
2134
2137
  url: z6.string(),
2135
2138
  detail: z6.union([z6.literal("auto"), z6.literal("low"), z6.literal("high")]).optional()
2136
2139
  }),
2137
- type: z6.literal("image_url")
2140
+ type: z6.literal("image_url"),
2141
+ cache_control: z6.object({
2142
+ type: z6.literal("ephemeral"),
2143
+ ttl: z6.enum(["5m", "1h"]).optional()
2144
+ }).optional()
2138
2145
  });
2139
2146
  var ChatCompletionContentPartFileFile = z6.object({ file_data: z6.string(), filename: z6.string(), file_id: z6.string() }).partial();
2140
2147
  var ChatCompletionContentPartFileWithTitle = z6.object({
2141
2148
  file: ChatCompletionContentPartFileFile,
2142
- type: z6.literal("file")
2149
+ type: z6.literal("file"),
2150
+ cache_control: z6.object({
2151
+ type: z6.literal("ephemeral"),
2152
+ ttl: z6.enum(["5m", "1h"]).optional()
2153
+ }).optional()
2143
2154
  });
2144
2155
  var ChatCompletionContentPart = z6.union([
2145
2156
  ChatCompletionContentPartTextWithTitle,
@@ -2149,7 +2160,10 @@ var ChatCompletionContentPart = z6.union([
2149
2160
  var ChatCompletionContentPartText = z6.object({
2150
2161
  text: z6.string().default(""),
2151
2162
  type: z6.literal("text"),
2152
- cache_control: z6.object({ type: z6.literal("ephemeral") }).optional()
2163
+ cache_control: z6.object({
2164
+ type: z6.literal("ephemeral"),
2165
+ ttl: z6.enum(["5m", "1h"]).optional()
2166
+ }).optional()
2153
2167
  });
2154
2168
  var ChatCompletionMessageToolCall = z6.object({
2155
2169
  id: z6.string(),
@@ -4174,13 +4188,23 @@ var LRUCache = class {
4174
4188
  * @returns The cached value if found, undefined otherwise.
4175
4189
  */
4176
4190
  get(key) {
4177
- const value = this.cache.get(key);
4178
- if (value === void 0) {
4191
+ const entry = this.cache.get(key);
4192
+ if (entry === void 0) {
4179
4193
  return void 0;
4180
4194
  }
4181
4195
  this.cache.delete(key);
4182
- this.cache.set(key, value);
4183
- return value;
4196
+ this.cache.set(key, entry);
4197
+ return entry.value;
4198
+ }
4199
+ /**
4200
+ * Checks whether a key exists and marks it as most recently used.
4201
+ */
4202
+ has(key) {
4203
+ if (!this.cache.has(key)) {
4204
+ return false;
4205
+ }
4206
+ this.get(key);
4207
+ return true;
4184
4208
  }
4185
4209
  /**
4186
4210
  * Stores a value in the cache.
@@ -4197,7 +4221,38 @@ var LRUCache = class {
4197
4221
  const first = this.cache.keys().next().value;
4198
4222
  this.cache.delete(first);
4199
4223
  }
4200
- this.cache.set(key, value);
4224
+ this.cache.set(key, { value });
4225
+ }
4226
+ /**
4227
+ * Removes an item from the cache.
4228
+ */
4229
+ delete(key) {
4230
+ return this.cache.delete(key);
4231
+ }
4232
+ /**
4233
+ * Iterates over cache entries from least to most recently used.
4234
+ */
4235
+ *entries() {
4236
+ for (const [key, entry] of this.cache) {
4237
+ yield [key, entry.value];
4238
+ }
4239
+ }
4240
+ /**
4241
+ * Iterates over cache keys from least to most recently used.
4242
+ */
4243
+ keys() {
4244
+ return this.cache.keys();
4245
+ }
4246
+ /**
4247
+ * Iterates over cache values from least to most recently used.
4248
+ */
4249
+ *values() {
4250
+ for (const entry of this.cache.values()) {
4251
+ yield entry.value;
4252
+ }
4253
+ }
4254
+ [Symbol.iterator]() {
4255
+ return this.entries();
4201
4256
  }
4202
4257
  /**
4203
4258
  * Removes all items from the cache.
@@ -4755,6 +4810,9 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
4755
4810
  return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
4756
4811
  }
4757
4812
  }
4813
+ var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
4814
+ "braintrust.initial-span-write-as-merge"
4815
+ );
4758
4816
  var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
4759
4817
  "braintrust.currentSpanStore"
4760
4818
  );
@@ -7959,7 +8017,7 @@ var SpanImpl = class _SpanImpl {
7959
8017
  this._spanId = resolvedIds.spanId;
7960
8018
  this._rootSpanId = resolvedIds.rootSpanId;
7961
8019
  this._spanParents = resolvedIds.spanParents;
7962
- this.isMerge = false;
8020
+ this.isMerge = args[INITIAL_SPAN_WRITE_AS_MERGE] === true;
7963
8021
  this.logInternal({ event, internalData });
7964
8022
  this.isMerge = true;
7965
8023
  }
@@ -8786,7 +8844,13 @@ var BraintrustObservabilityExporter = class {
8786
8844
  const args = {
8787
8845
  name: exported.name,
8788
8846
  spanAttributes: { type: spanTypeFor(exported.type) },
8789
- startTime: epochSeconds(exported.startTime)
8847
+ startTime: epochSeconds(exported.startTime),
8848
+ // Use the Mastra span id as the Braintrust row id so that
8849
+ // `logFeedback({ id: <mastra span id> })` (and Mastra's score events)
8850
+ // attach to the right row. Without this, `SpanImpl` auto-generates a
8851
+ // row id (`this._id = eventId ?? idGenerator.getSpanId()`) that no
8852
+ // external caller could know.
8853
+ event: { id: exported.id }
8790
8854
  };
8791
8855
  const parentRecord = exported.parentSpanId ? this.spans.get(exported.parentSpanId) : void 0;
8792
8856
  if (!this.capturedParent) {