braintrust 0.0.94 → 0.0.95
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 +160 -92
- package/dist/cli.js +196 -223
- package/dist/framework.d.ts +21 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +212 -98
- package/dist/logger.d.ts +50 -45
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/dist/browser.js
CHANGED
|
@@ -704,6 +704,7 @@ function init(project, options = {}) {
|
|
|
704
704
|
dataset,
|
|
705
705
|
baseExperiment,
|
|
706
706
|
isPublic,
|
|
707
|
+
open,
|
|
707
708
|
update,
|
|
708
709
|
appUrl,
|
|
709
710
|
apiKey,
|
|
@@ -711,6 +712,41 @@ function init(project, options = {}) {
|
|
|
711
712
|
metadata,
|
|
712
713
|
gitMetadataSettings
|
|
713
714
|
} = options || {};
|
|
715
|
+
if (open) {
|
|
716
|
+
if (isEmpty(experiment)) {
|
|
717
|
+
throw new Error("Cannot open an experiment without specifying its name");
|
|
718
|
+
}
|
|
719
|
+
if (update) {
|
|
720
|
+
throw new Error("Cannot open and update an experiment at the same time");
|
|
721
|
+
}
|
|
722
|
+
const lazyMetadata2 = new LazyValue(async () => {
|
|
723
|
+
await login({
|
|
724
|
+
orgName,
|
|
725
|
+
apiKey,
|
|
726
|
+
appUrl
|
|
727
|
+
});
|
|
728
|
+
const args = {
|
|
729
|
+
project_name: project,
|
|
730
|
+
org_name: _state.orgName,
|
|
731
|
+
experiment_name: experiment
|
|
732
|
+
};
|
|
733
|
+
const response = await _state.apiConn().post_json("api/experiment/get", args);
|
|
734
|
+
if (response.length === 0) {
|
|
735
|
+
throw new Error(
|
|
736
|
+
`Experiment ${experiment} not found in project ${project}.`
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
const info = response[0];
|
|
740
|
+
return {
|
|
741
|
+
id: info.id,
|
|
742
|
+
name: info.name,
|
|
743
|
+
fullInfo: info
|
|
744
|
+
};
|
|
745
|
+
});
|
|
746
|
+
return new ReadonlyExperiment(
|
|
747
|
+
lazyMetadata2
|
|
748
|
+
);
|
|
749
|
+
}
|
|
714
750
|
const lazyMetadata = new LazyValue(
|
|
715
751
|
async () => {
|
|
716
752
|
await login({
|
|
@@ -752,7 +788,7 @@ function init(project, options = {}) {
|
|
|
752
788
|
args["ancestor_commits"] = await isomorph_default.getPastNAncestors();
|
|
753
789
|
}
|
|
754
790
|
if (dataset !== void 0) {
|
|
755
|
-
args["dataset_id"] = dataset.id;
|
|
791
|
+
args["dataset_id"] = await dataset.id;
|
|
756
792
|
args["dataset_version"] = await dataset.version();
|
|
757
793
|
}
|
|
758
794
|
if (isPublic !== void 0) {
|
|
@@ -1107,15 +1143,15 @@ function validateAndSanitizeExperimentLogPartialArgs(event) {
|
|
|
1107
1143
|
}
|
|
1108
1144
|
}
|
|
1109
1145
|
function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
|
|
1110
|
-
if ("input" in event && event.input && "inputs" in event && event.inputs || !("input" in event) && !("inputs" in event)) {
|
|
1146
|
+
if ("input" in event && !isEmpty(event.input) && "inputs" in event && !isEmpty(event.inputs) || !("input" in event) && !("inputs" in event)) {
|
|
1111
1147
|
throw new Error(
|
|
1112
1148
|
"Exactly one of input or inputs (deprecated) must be specified. Prefer input."
|
|
1113
1149
|
);
|
|
1114
1150
|
}
|
|
1115
|
-
if (
|
|
1151
|
+
if (isEmpty(event.output)) {
|
|
1116
1152
|
throw new Error("output must be specified");
|
|
1117
1153
|
}
|
|
1118
|
-
if (
|
|
1154
|
+
if (isEmpty(event.scores)) {
|
|
1119
1155
|
throw new Error("scores must be specified");
|
|
1120
1156
|
}
|
|
1121
1157
|
if (hasDataset && event.datasetRecordId === void 0) {
|
|
@@ -1127,8 +1163,61 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
|
|
|
1127
1163
|
}
|
|
1128
1164
|
return event;
|
|
1129
1165
|
}
|
|
1130
|
-
var
|
|
1166
|
+
var ObjectFetcher = class {
|
|
1167
|
+
constructor(objectType, pinnedVersion) {
|
|
1168
|
+
this.objectType = objectType;
|
|
1169
|
+
this.pinnedVersion = pinnedVersion;
|
|
1170
|
+
this._fetchedData = void 0;
|
|
1171
|
+
}
|
|
1172
|
+
get id() {
|
|
1173
|
+
throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
|
|
1174
|
+
}
|
|
1175
|
+
async getState() {
|
|
1176
|
+
throw new Error("ObjectFetcher subclasses must have a 'getState' method");
|
|
1177
|
+
}
|
|
1178
|
+
async *fetch() {
|
|
1179
|
+
const records = await this.fetchedData();
|
|
1180
|
+
for (const record of records) {
|
|
1181
|
+
yield record;
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
[Symbol.iterator]() {
|
|
1185
|
+
return this.fetch();
|
|
1186
|
+
}
|
|
1187
|
+
async fetchedData() {
|
|
1188
|
+
if (this._fetchedData === void 0) {
|
|
1189
|
+
const state = await this.getState();
|
|
1190
|
+
const resp = await state.logConn().get(`object/${this.objectType}`, {
|
|
1191
|
+
id: await this.id,
|
|
1192
|
+
fmt: "json2",
|
|
1193
|
+
version: this.pinnedVersion
|
|
1194
|
+
});
|
|
1195
|
+
this._fetchedData = await resp.json();
|
|
1196
|
+
}
|
|
1197
|
+
return this._fetchedData || [];
|
|
1198
|
+
}
|
|
1199
|
+
clearCache() {
|
|
1200
|
+
this._fetchedData = void 0;
|
|
1201
|
+
}
|
|
1202
|
+
async version() {
|
|
1203
|
+
if (this.pinnedVersion !== void 0) {
|
|
1204
|
+
return this.pinnedVersion;
|
|
1205
|
+
} else {
|
|
1206
|
+
const fetchedData = await this.fetchedData();
|
|
1207
|
+
let maxVersion = void 0;
|
|
1208
|
+
for (const record of fetchedData) {
|
|
1209
|
+
const xactId = record[TRANSACTION_ID_FIELD];
|
|
1210
|
+
if (maxVersion === void 0 || (xactId ?? xactId > maxVersion)) {
|
|
1211
|
+
maxVersion = xactId;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
return maxVersion;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
var Experiment = class extends ObjectFetcher {
|
|
1131
1219
|
constructor(lazyMetadata, dataset) {
|
|
1220
|
+
super("experiment", void 0);
|
|
1132
1221
|
// For type identification.
|
|
1133
1222
|
this.kind = "experiment";
|
|
1134
1223
|
this.lazyMetadata = lazyMetadata;
|
|
@@ -1221,6 +1310,26 @@ var Experiment = class {
|
|
|
1221
1310
|
...argsRest
|
|
1222
1311
|
});
|
|
1223
1312
|
}
|
|
1313
|
+
async fetchBaseExperiment() {
|
|
1314
|
+
const state = await this.getState();
|
|
1315
|
+
const conn = state.apiConn();
|
|
1316
|
+
try {
|
|
1317
|
+
const resp = await conn.post("/api/base_experiment/get_id", {
|
|
1318
|
+
id: await this.id
|
|
1319
|
+
});
|
|
1320
|
+
const base = await resp.json();
|
|
1321
|
+
return {
|
|
1322
|
+
id: base["base_exp_id"],
|
|
1323
|
+
name: base["base_exp_name"]
|
|
1324
|
+
};
|
|
1325
|
+
} catch (e) {
|
|
1326
|
+
if (e instanceof FailedHTTPResponse && e.status === 400) {
|
|
1327
|
+
return null;
|
|
1328
|
+
} else {
|
|
1329
|
+
throw e;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1224
1333
|
/**
|
|
1225
1334
|
* Summarize the experiment, including the scores (compared to the closest reference experiment) and metadata.
|
|
1226
1335
|
*
|
|
@@ -1244,14 +1353,10 @@ var Experiment = class {
|
|
|
1244
1353
|
let comparisonExperimentName = void 0;
|
|
1245
1354
|
if (summarizeScores) {
|
|
1246
1355
|
if (comparisonExperimentId === void 0) {
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
const base_experiments = await resp.json();
|
|
1252
|
-
if (base_experiments.length > 0) {
|
|
1253
|
-
comparisonExperimentId = base_experiments[0]["base_exp_id"];
|
|
1254
|
-
comparisonExperimentName = base_experiments[0]["base_exp_name"];
|
|
1356
|
+
const baseExperiment = await this.fetchBaseExperiment();
|
|
1357
|
+
if (baseExperiment !== null) {
|
|
1358
|
+
comparisonExperimentId = baseExperiment.id;
|
|
1359
|
+
comparisonExperimentName = baseExperiment.name;
|
|
1255
1360
|
}
|
|
1256
1361
|
}
|
|
1257
1362
|
if (comparisonExperimentId !== void 0) {
|
|
@@ -1311,6 +1416,40 @@ var Experiment = class {
|
|
|
1311
1416
|
return this.id;
|
|
1312
1417
|
}
|
|
1313
1418
|
};
|
|
1419
|
+
var ReadonlyExperiment = class extends ObjectFetcher {
|
|
1420
|
+
constructor(lazyMetadata) {
|
|
1421
|
+
super("experiment", void 0);
|
|
1422
|
+
this.lazyMetadata = lazyMetadata;
|
|
1423
|
+
}
|
|
1424
|
+
get id() {
|
|
1425
|
+
return (async () => {
|
|
1426
|
+
return (await this.lazyMetadata.get()).id;
|
|
1427
|
+
})();
|
|
1428
|
+
}
|
|
1429
|
+
get name() {
|
|
1430
|
+
return (async () => {
|
|
1431
|
+
return (await this.lazyMetadata.get()).name;
|
|
1432
|
+
})();
|
|
1433
|
+
}
|
|
1434
|
+
async getState() {
|
|
1435
|
+
await this.lazyMetadata.get();
|
|
1436
|
+
return _state;
|
|
1437
|
+
}
|
|
1438
|
+
async *asDataset() {
|
|
1439
|
+
const records = this.fetch();
|
|
1440
|
+
for await (const record of records) {
|
|
1441
|
+
if (record.root_span_id !== record.span_id) {
|
|
1442
|
+
continue;
|
|
1443
|
+
}
|
|
1444
|
+
const { output, expected } = record;
|
|
1445
|
+
yield {
|
|
1446
|
+
input: record.input,
|
|
1447
|
+
expected: expected ?? output
|
|
1448
|
+
};
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
};
|
|
1452
|
+
var executionCounter = 0;
|
|
1314
1453
|
var SpanImpl = class _SpanImpl {
|
|
1315
1454
|
// root_experiment should only be specified for a root span. parent_span
|
|
1316
1455
|
// should only be specified for non-root spans.
|
|
@@ -1336,7 +1475,11 @@ var SpanImpl = class _SpanImpl {
|
|
|
1336
1475
|
start: args.startTime ?? getCurrentUnixTimestamp()
|
|
1337
1476
|
},
|
|
1338
1477
|
context: { ...callerLocation },
|
|
1339
|
-
span_attributes: {
|
|
1478
|
+
span_attributes: {
|
|
1479
|
+
...args.spanAttributes,
|
|
1480
|
+
name,
|
|
1481
|
+
exec_counter: executionCounter++
|
|
1482
|
+
},
|
|
1340
1483
|
created: (/* @__PURE__ */ new Date()).toISOString()
|
|
1341
1484
|
};
|
|
1342
1485
|
this.parentIds = args.parentIds;
|
|
@@ -1434,11 +1577,10 @@ var SpanImpl = class _SpanImpl {
|
|
|
1434
1577
|
return this.end(args);
|
|
1435
1578
|
}
|
|
1436
1579
|
};
|
|
1437
|
-
var Dataset = class {
|
|
1580
|
+
var Dataset = class extends ObjectFetcher {
|
|
1438
1581
|
constructor(lazyMetadata, pinnedVersion) {
|
|
1439
|
-
|
|
1582
|
+
super("dataset", pinnedVersion);
|
|
1440
1583
|
this.lazyMetadata = lazyMetadata;
|
|
1441
|
-
this.pinnedVersion = pinnedVersion;
|
|
1442
1584
|
const logConn = new LazyValue(
|
|
1443
1585
|
() => this.getState().then((state) => state.logConn())
|
|
1444
1586
|
);
|
|
@@ -1546,81 +1688,6 @@ var Dataset = class {
|
|
|
1546
1688
|
dataSummary
|
|
1547
1689
|
};
|
|
1548
1690
|
}
|
|
1549
|
-
/**
|
|
1550
|
-
* Fetch all records in the dataset.
|
|
1551
|
-
*
|
|
1552
|
-
* @example
|
|
1553
|
-
* ```
|
|
1554
|
-
* // Use an async iterator to fetch all records in the dataset.
|
|
1555
|
-
* for await (const record of dataset.fetch()) {
|
|
1556
|
-
* console.log(record);
|
|
1557
|
-
* }
|
|
1558
|
-
*
|
|
1559
|
-
* // You can also iterate over the dataset directly.
|
|
1560
|
-
* for await (const record of dataset) {
|
|
1561
|
-
* console.log(record);
|
|
1562
|
-
* }
|
|
1563
|
-
* ```
|
|
1564
|
-
*
|
|
1565
|
-
* @returns An iterator over the dataset's records.
|
|
1566
|
-
*/
|
|
1567
|
-
async *fetch() {
|
|
1568
|
-
const records = await this.fetchedData();
|
|
1569
|
-
for (const record of records) {
|
|
1570
|
-
yield {
|
|
1571
|
-
id: record.id,
|
|
1572
|
-
input: record.input && JSON.parse(record.input),
|
|
1573
|
-
output: record.input && JSON.parse(record.output),
|
|
1574
|
-
metadata: record.metadata && JSON.parse(record.metadata)
|
|
1575
|
-
};
|
|
1576
|
-
}
|
|
1577
|
-
this.clearCache();
|
|
1578
|
-
}
|
|
1579
|
-
/**
|
|
1580
|
-
* Fetch all records in the dataset.
|
|
1581
|
-
*
|
|
1582
|
-
* @example
|
|
1583
|
-
* ```
|
|
1584
|
-
* // Use an async iterator to fetch all records in the dataset.
|
|
1585
|
-
* for await (const record of dataset) {
|
|
1586
|
-
* console.log(record);
|
|
1587
|
-
* }
|
|
1588
|
-
* ```
|
|
1589
|
-
*/
|
|
1590
|
-
[Symbol.asyncIterator]() {
|
|
1591
|
-
return this.fetch();
|
|
1592
|
-
}
|
|
1593
|
-
async fetchedData() {
|
|
1594
|
-
if (this._fetchedData === void 0) {
|
|
1595
|
-
const state = await this.getState();
|
|
1596
|
-
const resp = await state.logConn().get("object/dataset", {
|
|
1597
|
-
id: await this.id,
|
|
1598
|
-
fmt: "json",
|
|
1599
|
-
version: this.pinnedVersion
|
|
1600
|
-
});
|
|
1601
|
-
const text = await resp.text();
|
|
1602
|
-
this._fetchedData = text.split("\n").filter((x) => x.trim() !== "").map((x) => JSON.parse(x));
|
|
1603
|
-
}
|
|
1604
|
-
return this._fetchedData || [];
|
|
1605
|
-
}
|
|
1606
|
-
clearCache() {
|
|
1607
|
-
this._fetchedData = void 0;
|
|
1608
|
-
}
|
|
1609
|
-
async version() {
|
|
1610
|
-
if (this.pinnedVersion !== void 0) {
|
|
1611
|
-
return this.pinnedVersion;
|
|
1612
|
-
} else {
|
|
1613
|
-
const fetchedData = await this.fetchedData();
|
|
1614
|
-
let maxVersion = void 0;
|
|
1615
|
-
for (const record of fetchedData) {
|
|
1616
|
-
const xactId = record[TRANSACTION_ID_FIELD];
|
|
1617
|
-
if (maxVersion === void 0 || (xactId ?? xactId > maxVersion)) {
|
|
1618
|
-
maxVersion = xactId;
|
|
1619
|
-
}
|
|
1620
|
-
}
|
|
1621
|
-
return maxVersion;
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
1691
|
/**
|
|
1625
1692
|
* Flush any pending rows to the server.
|
|
1626
1693
|
*/
|
|
@@ -1891,6 +1958,7 @@ export {
|
|
|
1891
1958
|
Logger,
|
|
1892
1959
|
NOOP_SPAN,
|
|
1893
1960
|
NoopSpan,
|
|
1961
|
+
ReadonlyExperiment,
|
|
1894
1962
|
SpanImpl,
|
|
1895
1963
|
_internalGetGlobalState,
|
|
1896
1964
|
_internalSetInitialState,
|