braintrust 0.0.98 → 0.0.100

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/dist/browser.js CHANGED
@@ -233,10 +233,11 @@ function isEmpty(a) {
233
233
  return a === void 0 || a === null;
234
234
  }
235
235
  var LazyValue = class {
236
+ callable;
237
+ value = {
238
+ hasComputed: false
239
+ };
236
240
  constructor(callable) {
237
- this.value = {
238
- hasComputed: false
239
- };
240
241
  this.callable = callable;
241
242
  }
242
243
  async get() {
@@ -250,8 +251,11 @@ var LazyValue = class {
250
251
 
251
252
  // src/logger.ts
252
253
  var NoopSpan = class {
254
+ id;
255
+ span_id;
256
+ root_span_id;
257
+ kind = "span";
253
258
  constructor() {
254
- this.kind = "span";
255
259
  this.id = "";
256
260
  this.span_id = "";
257
261
  this.root_span_id = "";
@@ -275,15 +279,22 @@ var NoopSpan = class {
275
279
  };
276
280
  var NOOP_SPAN = new NoopSpan();
277
281
  var BraintrustState = class {
282
+ id;
283
+ currentExperiment;
284
+ // Note: the value of IsAsyncFlush doesn't really matter here, since we
285
+ // (safely) dynamically cast it whenever retrieving the logger.
286
+ currentLogger;
287
+ currentSpan;
288
+ appUrl = null;
289
+ loginToken = null;
290
+ orgId = null;
291
+ orgName = null;
292
+ logUrl = null;
293
+ loggedIn = false;
294
+ gitMetadataSettings;
295
+ _apiConn = null;
296
+ _logConn = null;
278
297
  constructor() {
279
- this.appUrl = null;
280
- this.loginToken = null;
281
- this.orgId = null;
282
- this.orgName = null;
283
- this.logUrl = null;
284
- this.loggedIn = false;
285
- this._apiConn = null;
286
- this._logConn = null;
287
298
  this.id = v4_default();
288
299
  this.currentExperiment = void 0;
289
300
  this.currentLogger = void 0;
@@ -330,6 +341,9 @@ function _internalSetInitialState() {
330
341
  }
331
342
  var _internalGetGlobalState = () => _state;
332
343
  var FailedHTTPResponse = class extends Error {
344
+ status;
345
+ text;
346
+ data;
333
347
  constructor(status, text, data = null) {
334
348
  super(`${status}: ${text}`);
335
349
  this.status = status;
@@ -349,6 +363,9 @@ async function checkResponse(resp) {
349
363
  }
350
364
  }
351
365
  var HTTPConnection = class _HTTPConnection {
366
+ base_url;
367
+ token;
368
+ headers;
352
369
  constructor(base_url) {
353
370
  this.base_url = base_url;
354
371
  this.token = null;
@@ -500,9 +517,13 @@ function logFeedbackImpl(bgLogger, parentIds, {
500
517
  }
501
518
  }
502
519
  var Logger = class {
520
+ lazyMetadata;
521
+ logOptions;
522
+ bgLogger;
523
+ lastStartTime;
524
+ // For type identification.
525
+ kind = "logger";
503
526
  constructor(lazyMetadata, logOptions = {}) {
504
- // For type identification.
505
- this.kind = "logger";
506
527
  this.lazyMetadata = lazyMetadata;
507
528
  this.logOptions = logOptions;
508
529
  const logConn = new LazyValue(
@@ -536,9 +557,19 @@ var Logger = class {
536
557
  * @param event.metadata: (Optional) a dictionary with additional data about the test example, model outputs, or just about anything else that's relevant, that you can use to help find and analyze examples later. For example, you could log the `prompt`, example's `id`, or anything else that would be useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys must be strings.
537
558
  * @param event.metrics: (Optional) a dictionary of metrics to log. The following keys are populated automatically: "start", "end".
538
559
  * @param event.id: (Optional) a unique identifier for the event. If you don't provide one, BrainTrust will generate one for you.
560
+ * @param options Additional logging options
561
+ * @param options.allowLogConcurrentWithActiveSpan in rare cases where you need to log at the top level separately from an active span on the logger, set this to true.
539
562
  * :returns: The `id` of the logged event.
540
563
  */
541
- log(event) {
564
+ log(event, options) {
565
+ if (!options?.allowLogConcurrentWithActiveSpan) {
566
+ const checkCurrentSpan = currentSpan();
567
+ if (checkCurrentSpan instanceof SpanImpl && checkCurrentSpan.parentObject === this) {
568
+ throw new Error(
569
+ "Cannot run toplevel Logger.log method while there is an active span. To log to the span, use Span.log"
570
+ );
571
+ }
572
+ }
542
573
  const span = this.startSpan({ startTime: this.lastStartTime, event });
543
574
  this.lastStartTime = span.end();
544
575
  const ret = span.id;
@@ -597,6 +628,7 @@ var Logger = class {
597
628
  startSpan(args) {
598
629
  const { name, ...argsRest } = args ?? {};
599
630
  return new SpanImpl({
631
+ parentObject: this,
600
632
  parentIds: new LazyValue(() => this.lazyParentIds()),
601
633
  bgLogger: this.bgLogger,
602
634
  name: name ?? "root",
@@ -654,10 +686,11 @@ function now() {
654
686
  return (/* @__PURE__ */ new Date()).getTime();
655
687
  }
656
688
  var BackgroundLogger = class {
689
+ logConn;
690
+ items = [];
691
+ active_flush = Promise.resolve([]);
692
+ active_flush_resolved = true;
657
693
  constructor(logConn) {
658
- this.items = [];
659
- this.active_flush = Promise.resolve([]);
660
- this.active_flush_resolved = true;
661
694
  this.logConn = logConn;
662
695
  isomorph_default.processOn("beforeExit", async () => {
663
696
  await this.flush();
@@ -706,12 +739,12 @@ var BackgroundLogger = class {
706
739
  }
707
740
  postPromises.push(
708
741
  (async () => {
709
- const dataS = constructLogs3Data(items);
742
+ const dataStr = constructLogs3Data(items);
710
743
  for (let i = 0; i < NumRetries; i++) {
711
744
  const startTime = now();
712
745
  try {
713
746
  try {
714
- return (await (await this.logConn.get()).post_json("logs3", dataS)).ids.map((res) => res.id);
747
+ return (await (await this.logConn.get()).post_json("logs3", dataStr)).ids.map((res) => res.id);
715
748
  } catch (e) {
716
749
  const legacyDataS = constructJsonArray(
717
750
  items.map(
@@ -730,7 +763,7 @@ var BackgroundLogger = class {
730
763
  }
731
764
  })();
732
765
  console.warn(
733
- `log request failed. Elapsed time: ${(now() - startTime) / 1e3} seconds. Payload size: ${dataS.length}. Error: ${errMsg}.${retryingText}`
766
+ `log request failed. Elapsed time: ${(now() - startTime) / 1e3} seconds. Payload size: ${dataStr.length}. Error: ${errMsg}.${retryingText}`
734
767
  );
735
768
  }
736
769
  }
@@ -1098,9 +1131,12 @@ async function login(options = {}) {
1098
1131
  }
1099
1132
  };
1100
1133
  var checkUpdatedParam = checkUpdatedParam2;
1101
- ;
1102
1134
  checkUpdatedParam2("appUrl", options.appUrl, _state.appUrl);
1103
- checkUpdatedParam2("apiKey", options.apiKey ? HTTPConnection.sanitize_token(options.apiKey) : void 0, _state.loginToken);
1135
+ checkUpdatedParam2(
1136
+ "apiKey",
1137
+ options.apiKey ? HTTPConnection.sanitize_token(options.apiKey) : void 0,
1138
+ _state.loginToken
1139
+ );
1104
1140
  checkUpdatedParam2("orgName", options.orgName, _state.orgName);
1105
1141
  return;
1106
1142
  }
@@ -1321,8 +1357,8 @@ var ObjectFetcher = class {
1321
1357
  this.objectType = objectType;
1322
1358
  this.pinnedVersion = pinnedVersion;
1323
1359
  this.mutateRecord = mutateRecord;
1324
- this._fetchedData = void 0;
1325
1360
  }
1361
+ _fetchedData = void 0;
1326
1362
  get id() {
1327
1363
  throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
1328
1364
  }
@@ -1382,10 +1418,14 @@ var ObjectFetcher = class {
1382
1418
  }
1383
1419
  };
1384
1420
  var Experiment = class extends ObjectFetcher {
1421
+ lazyMetadata;
1422
+ dataset;
1423
+ bgLogger;
1424
+ lastStartTime;
1425
+ // For type identification.
1426
+ kind = "experiment";
1385
1427
  constructor(lazyMetadata, dataset) {
1386
1428
  super("experiment", void 0);
1387
- // For type identification.
1388
- this.kind = "experiment";
1389
1429
  this.lazyMetadata = lazyMetadata;
1390
1430
  this.dataset = dataset;
1391
1431
  const logConn = new LazyValue(
@@ -1426,9 +1466,19 @@ var Experiment = class extends ObjectFetcher {
1426
1466
  * @param event.id: (Optional) a unique identifier for the event. If you don't provide one, BrainTrust will generate one for you.
1427
1467
  * @param event.dataset_record_id: (Optional) the id of the dataset record that this event is associated with. This field is required if and only if the experiment is associated with a dataset.
1428
1468
  * @param event.inputs: (Deprecated) the same as `input` (will be removed in a future version).
1469
+ * @param options Additional logging options
1470
+ * @param options.allowLogConcurrentWithActiveSpan in rare cases where you need to log at the top level separately from an active span on the experiment, set this to true.
1429
1471
  * :returns: The `id` of the logged event.
1430
1472
  */
1431
- log(event) {
1473
+ log(event, options) {
1474
+ if (!options?.allowLogConcurrentWithActiveSpan) {
1475
+ const checkCurrentSpan = currentSpan();
1476
+ if (checkCurrentSpan instanceof SpanImpl && checkCurrentSpan.parentObject === this) {
1477
+ throw new Error(
1478
+ "Cannot run toplevel Experiment.log method while there is an active span. To log to the span, use Span.log"
1479
+ );
1480
+ }
1481
+ }
1432
1482
  event = validateAndSanitizeExperimentLogFullArgs(event, !!this.dataset);
1433
1483
  const span = this.startSpan({ startTime: this.lastStartTime, event });
1434
1484
  this.lastStartTime = span.end();
@@ -1470,6 +1520,7 @@ var Experiment = class extends ObjectFetcher {
1470
1520
  startSpan(args) {
1471
1521
  const { name, ...argsRest } = args ?? {};
1472
1522
  return new SpanImpl({
1523
+ parentObject: this,
1473
1524
  parentIds: new LazyValue(() => this.lazyParentIds()),
1474
1525
  bgLogger: this.bgLogger,
1475
1526
  name: name ?? "root",
@@ -1624,10 +1675,21 @@ var ReadonlyExperiment = class extends ObjectFetcher {
1624
1675
  };
1625
1676
  var executionCounter = 0;
1626
1677
  var SpanImpl = class _SpanImpl {
1678
+ bgLogger;
1679
+ // `internalData` contains fields that are not part of the "user-sanitized"
1680
+ // set of fields which we want to log in just one of the span rows.
1681
+ internalData;
1682
+ isMerge;
1683
+ loggedEndTime;
1684
+ // For internal use only.
1685
+ parentObject;
1686
+ // These fields are logged to every span row.
1687
+ parentIds;
1688
+ rowIds;
1689
+ kind = "span";
1627
1690
  // root_experiment should only be specified for a root span. parent_span
1628
1691
  // should only be specified for non-root spans.
1629
1692
  constructor(args) {
1630
- this.kind = "span";
1631
1693
  this.loggedEndTime = void 0;
1632
1694
  this.bgLogger = args.bgLogger;
1633
1695
  const callerLocation = isomorph_default.getCallerLocation();
@@ -1655,6 +1717,7 @@ var SpanImpl = class _SpanImpl {
1655
1717
  },
1656
1718
  created: (/* @__PURE__ */ new Date()).toISOString()
1657
1719
  };
1720
+ this.parentObject = args.parentObject;
1658
1721
  this.parentIds = args.parentIds;
1659
1722
  const id = args.event?.id ?? v4_default();
1660
1723
  const span_id = v4_default();
@@ -1726,6 +1789,7 @@ var SpanImpl = class _SpanImpl {
1726
1789
  }
1727
1790
  startSpan(args) {
1728
1791
  return new _SpanImpl({
1792
+ parentObject: this.parentObject,
1729
1793
  parentIds: this.parentIds,
1730
1794
  bgLogger: this.bgLogger,
1731
1795
  parentSpanInfo: {
@@ -1751,6 +1815,8 @@ var SpanImpl = class _SpanImpl {
1751
1815
  }
1752
1816
  };
1753
1817
  var Dataset = class extends ObjectFetcher {
1818
+ lazyMetadata;
1819
+ bgLogger;
1754
1820
  constructor(lazyMetadata, pinnedVersion, legacy) {
1755
1821
  const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
1756
1822
  if (isLegacyDataset) {
@@ -2111,6 +2177,9 @@ function wrapEmbeddings(create) {
2111
2177
  };
2112
2178
  }
2113
2179
  var WrapperStream = class {
2180
+ span;
2181
+ iter;
2182
+ startTime;
2114
2183
  constructor(span, startTime, iter) {
2115
2184
  this.span = span;
2116
2185
  this.iter = iter;