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 +97 -28
- package/dist/cli.js +172 -91
- package/dist/framework.d.ts +1 -1
- package/dist/index.js +192 -94
- package/dist/logger.d.ts +12 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
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
|
|
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",
|
|
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: ${
|
|
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(
|
|
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;
|