braintrust 0.0.166 → 0.0.168
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.d.mts +184 -41
- package/dist/browser.d.ts +184 -41
- package/dist/browser.js +348 -101
- package/dist/browser.mjs +349 -103
- package/dist/cli.js +397 -85
- package/dist/index.d.mts +186 -44
- package/dist/index.d.ts +186 -44
- package/dist/index.js +369 -105
- package/dist/index.mjs +370 -107
- package/package.json +7 -2
- package/typedoc.json +1 -0
package/dist/index.mjs
CHANGED
|
@@ -274,7 +274,8 @@ import {
|
|
|
274
274
|
promptDataSchema,
|
|
275
275
|
promptSchema,
|
|
276
276
|
toolsSchema,
|
|
277
|
-
gitMetadataSettingsSchema
|
|
277
|
+
gitMetadataSettingsSchema,
|
|
278
|
+
BRAINTRUST_ATTACHMENT
|
|
278
279
|
} from "@braintrust/core/typespecs";
|
|
279
280
|
|
|
280
281
|
// src/util.ts
|
|
@@ -325,7 +326,7 @@ var LazyValue = class {
|
|
|
325
326
|
|
|
326
327
|
// src/logger.ts
|
|
327
328
|
import Mustache from "mustache";
|
|
328
|
-
import { z as z2 } from "zod";
|
|
329
|
+
import { z as z2, ZodError } from "zod";
|
|
329
330
|
|
|
330
331
|
// src/functions/stream.ts
|
|
331
332
|
import {
|
|
@@ -615,6 +616,9 @@ var NoopSpan = class {
|
|
|
615
616
|
async export() {
|
|
616
617
|
return "";
|
|
617
618
|
}
|
|
619
|
+
async permalink() {
|
|
620
|
+
return "";
|
|
621
|
+
}
|
|
618
622
|
async flush() {
|
|
619
623
|
}
|
|
620
624
|
close(args) {
|
|
@@ -756,11 +760,11 @@ var BraintrustState = class _BraintrustState {
|
|
|
756
760
|
state.loginReplaceApiConn(state.apiConn());
|
|
757
761
|
return state;
|
|
758
762
|
}
|
|
759
|
-
setFetch(
|
|
760
|
-
this.loginParams.fetch =
|
|
761
|
-
this.fetch =
|
|
762
|
-
this._apiConn?.setFetch(
|
|
763
|
-
this._appConn?.setFetch(
|
|
763
|
+
setFetch(fetch2) {
|
|
764
|
+
this.loginParams.fetch = fetch2;
|
|
765
|
+
this.fetch = fetch2;
|
|
766
|
+
this._apiConn?.setFetch(fetch2);
|
|
767
|
+
this._appConn?.setFetch(fetch2);
|
|
764
768
|
}
|
|
765
769
|
async login(loginParams) {
|
|
766
770
|
if (this.apiUrl && !loginParams.forceLogin) {
|
|
@@ -849,15 +853,15 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
849
853
|
token;
|
|
850
854
|
headers;
|
|
851
855
|
fetch;
|
|
852
|
-
constructor(base_url,
|
|
856
|
+
constructor(base_url, fetch2) {
|
|
853
857
|
this.base_url = base_url;
|
|
854
858
|
this.token = null;
|
|
855
859
|
this.headers = {};
|
|
856
860
|
this._reset();
|
|
857
|
-
this.fetch =
|
|
861
|
+
this.fetch = fetch2;
|
|
858
862
|
}
|
|
859
|
-
setFetch(
|
|
860
|
-
this.fetch =
|
|
863
|
+
setFetch(fetch2) {
|
|
864
|
+
this.fetch = fetch2;
|
|
861
865
|
}
|
|
862
866
|
async ping() {
|
|
863
867
|
try {
|
|
@@ -893,12 +897,14 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
893
897
|
([k, v]) => v !== void 0 ? typeof v === "string" ? [[k, v]] : v.map((x) => [k, x]) : []
|
|
894
898
|
) : []
|
|
895
899
|
).toString();
|
|
900
|
+
const this_fetch = this.fetch;
|
|
901
|
+
const this_headers = this.headers;
|
|
896
902
|
return await checkResponse(
|
|
897
903
|
// Using toString() here makes it work with isomorphic fetch
|
|
898
|
-
await
|
|
904
|
+
await this_fetch(url.toString(), {
|
|
899
905
|
headers: {
|
|
900
906
|
Accept: "application/json",
|
|
901
|
-
...
|
|
907
|
+
...this_headers,
|
|
902
908
|
...headers
|
|
903
909
|
},
|
|
904
910
|
keepalive: true,
|
|
@@ -908,13 +914,16 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
908
914
|
}
|
|
909
915
|
async post(path3, params, config) {
|
|
910
916
|
const { headers, ...rest } = config || {};
|
|
917
|
+
const this_fetch = this.fetch;
|
|
918
|
+
const this_base_url = this.base_url;
|
|
919
|
+
const this_headers = this.headers;
|
|
911
920
|
return await checkResponse(
|
|
912
|
-
await
|
|
921
|
+
await this_fetch(_urljoin(this_base_url, path3), {
|
|
913
922
|
method: "POST",
|
|
914
923
|
headers: {
|
|
915
924
|
Accept: "application/json",
|
|
916
925
|
"Content-Type": "application/json",
|
|
917
|
-
...
|
|
926
|
+
...this_headers,
|
|
918
927
|
...headers
|
|
919
928
|
},
|
|
920
929
|
body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
|
|
@@ -947,6 +956,167 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
947
956
|
return await resp.json();
|
|
948
957
|
}
|
|
949
958
|
};
|
|
959
|
+
var Attachment = class {
|
|
960
|
+
/**
|
|
961
|
+
* The object that replaces this `Attachment` at upload time.
|
|
962
|
+
*/
|
|
963
|
+
reference;
|
|
964
|
+
uploader;
|
|
965
|
+
data;
|
|
966
|
+
state;
|
|
967
|
+
// For debug logging only.
|
|
968
|
+
dataDebugString;
|
|
969
|
+
/**
|
|
970
|
+
* Construct an attachment.
|
|
971
|
+
*
|
|
972
|
+
* @param data A string representing the path of the file on disk, or a
|
|
973
|
+
* `Blob`/`ArrayBuffer` with the file's contents. The caller is responsible
|
|
974
|
+
* for ensuring the file/blob/buffer is not modified until upload is complete.
|
|
975
|
+
*
|
|
976
|
+
* @param filename The desired name of the file in Braintrust after uploading.
|
|
977
|
+
* This parameter is for visualization purposes only and has no effect on
|
|
978
|
+
* attachment storage.
|
|
979
|
+
*
|
|
980
|
+
* @param contentType The MIME type of the file.
|
|
981
|
+
*
|
|
982
|
+
* @param state (Optional) For internal use.
|
|
983
|
+
*/
|
|
984
|
+
constructor({ data, filename, contentType, state }) {
|
|
985
|
+
this.reference = {
|
|
986
|
+
type: BRAINTRUST_ATTACHMENT,
|
|
987
|
+
filename,
|
|
988
|
+
content_type: contentType,
|
|
989
|
+
key: newId()
|
|
990
|
+
};
|
|
991
|
+
this.state = state;
|
|
992
|
+
this.dataDebugString = typeof data === "string" ? data : "<in-memory data>";
|
|
993
|
+
this.data = this.initData(data);
|
|
994
|
+
this.uploader = this.initUploader();
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* On first access, (1) reads the attachment from disk if needed, (2)
|
|
998
|
+
* authenticates with the data plane to request a signed URL, (3) uploads to
|
|
999
|
+
* object store, and (4) updates the attachment.
|
|
1000
|
+
*
|
|
1001
|
+
* @returns The attachment status.
|
|
1002
|
+
*/
|
|
1003
|
+
async upload() {
|
|
1004
|
+
return await this.uploader.get();
|
|
1005
|
+
}
|
|
1006
|
+
/**
|
|
1007
|
+
* A human-readable description for logging and debugging.
|
|
1008
|
+
*
|
|
1009
|
+
* @returns The debug object. The return type is not stable and may change in
|
|
1010
|
+
* a future release.
|
|
1011
|
+
*/
|
|
1012
|
+
debugInfo() {
|
|
1013
|
+
return {
|
|
1014
|
+
inputData: this.dataDebugString,
|
|
1015
|
+
reference: this.reference,
|
|
1016
|
+
state: this.state
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
initUploader() {
|
|
1020
|
+
const doUpload = async (conn, orgId) => {
|
|
1021
|
+
const requestParams = {
|
|
1022
|
+
key: this.reference.key,
|
|
1023
|
+
filename: this.reference.filename,
|
|
1024
|
+
content_type: this.reference.content_type,
|
|
1025
|
+
org_id: orgId
|
|
1026
|
+
};
|
|
1027
|
+
const [metadataPromiseResult, dataPromiseResult] = await Promise.allSettled([
|
|
1028
|
+
conn.post("/attachment", requestParams),
|
|
1029
|
+
this.data.get()
|
|
1030
|
+
]);
|
|
1031
|
+
if (metadataPromiseResult.status === "rejected") {
|
|
1032
|
+
const errorStr = JSON.stringify(metadataPromiseResult.reason);
|
|
1033
|
+
throw new Error(
|
|
1034
|
+
`Failed to request signed URL from API server: ${errorStr}`
|
|
1035
|
+
);
|
|
1036
|
+
}
|
|
1037
|
+
if (dataPromiseResult.status === "rejected") {
|
|
1038
|
+
const errorStr = JSON.stringify(dataPromiseResult.reason);
|
|
1039
|
+
throw new Error(`Failed to read file: ${errorStr}`);
|
|
1040
|
+
}
|
|
1041
|
+
const metadataResponse = metadataPromiseResult.value;
|
|
1042
|
+
const data = dataPromiseResult.value;
|
|
1043
|
+
let signedUrl;
|
|
1044
|
+
let headers;
|
|
1045
|
+
try {
|
|
1046
|
+
({ signedUrl, headers } = z2.object({
|
|
1047
|
+
signedUrl: z2.string().url(),
|
|
1048
|
+
headers: z2.record(z2.string())
|
|
1049
|
+
}).parse(await metadataResponse.json()));
|
|
1050
|
+
} catch (error2) {
|
|
1051
|
+
if (error2 instanceof ZodError) {
|
|
1052
|
+
const errorStr = JSON.stringify(error2.flatten());
|
|
1053
|
+
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
1054
|
+
}
|
|
1055
|
+
throw error2;
|
|
1056
|
+
}
|
|
1057
|
+
let objectStoreResponse;
|
|
1058
|
+
try {
|
|
1059
|
+
objectStoreResponse = await checkResponse(
|
|
1060
|
+
await fetch(signedUrl, {
|
|
1061
|
+
method: "PUT",
|
|
1062
|
+
headers,
|
|
1063
|
+
body: data
|
|
1064
|
+
})
|
|
1065
|
+
);
|
|
1066
|
+
} catch (error2) {
|
|
1067
|
+
if (error2 instanceof FailedHTTPResponse) {
|
|
1068
|
+
throw new Error(
|
|
1069
|
+
`Failed to upload attachment to object store: ${error2.status} ${error2.text} ${error2.data}`
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1072
|
+
throw error2;
|
|
1073
|
+
}
|
|
1074
|
+
return { signedUrl, metadataResponse, objectStoreResponse };
|
|
1075
|
+
};
|
|
1076
|
+
const errorWrapper = async () => {
|
|
1077
|
+
const status = { upload_status: "done" };
|
|
1078
|
+
const state = this.state ?? _globalState;
|
|
1079
|
+
await state.login({});
|
|
1080
|
+
const conn = state.apiConn();
|
|
1081
|
+
const orgId = state.orgId ?? "";
|
|
1082
|
+
try {
|
|
1083
|
+
await doUpload(conn, orgId);
|
|
1084
|
+
} catch (error2) {
|
|
1085
|
+
status.upload_status = "error";
|
|
1086
|
+
status.error_message = error2 instanceof Error ? error2.message : JSON.stringify(error2);
|
|
1087
|
+
}
|
|
1088
|
+
const requestParams = {
|
|
1089
|
+
key: this.reference.key,
|
|
1090
|
+
org_id: orgId,
|
|
1091
|
+
status
|
|
1092
|
+
};
|
|
1093
|
+
const statusResponse = await conn.post(
|
|
1094
|
+
"/attachment/status",
|
|
1095
|
+
requestParams
|
|
1096
|
+
);
|
|
1097
|
+
if (!statusResponse.ok) {
|
|
1098
|
+
const errorStr = JSON.stringify(statusResponse);
|
|
1099
|
+
throw new Error(`Couldn't log attachment status: ${errorStr}`);
|
|
1100
|
+
}
|
|
1101
|
+
return status;
|
|
1102
|
+
};
|
|
1103
|
+
return new LazyValue(errorWrapper);
|
|
1104
|
+
}
|
|
1105
|
+
initData(data) {
|
|
1106
|
+
if (typeof data === "string") {
|
|
1107
|
+
const readFile2 = isomorph_default.readFile;
|
|
1108
|
+
if (!readFile2) {
|
|
1109
|
+
throw new Error(
|
|
1110
|
+
`This platform does not support reading the filesystem. Construct the Attachment
|
|
1111
|
+
with a Blob/ArrayBuffer, or run the program on Node.js.`
|
|
1112
|
+
);
|
|
1113
|
+
}
|
|
1114
|
+
return new LazyValue(async () => new Blob([await readFile2(data)]));
|
|
1115
|
+
} else {
|
|
1116
|
+
return new LazyValue(async () => new Blob([data]));
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
};
|
|
950
1120
|
function logFeedbackImpl(state, parentObjectType, parentObjectId, {
|
|
951
1121
|
id,
|
|
952
1122
|
expected,
|
|
@@ -971,7 +1141,7 @@ function logFeedbackImpl(state, parentObjectType, parentObjectId, {
|
|
|
971
1141
|
expected,
|
|
972
1142
|
tags
|
|
973
1143
|
});
|
|
974
|
-
let { metadata, ...updateEvent } = validatedEvent;
|
|
1144
|
+
let { metadata, ...updateEvent } = deepCopyEvent(validatedEvent);
|
|
975
1145
|
updateEvent = Object.fromEntries(
|
|
976
1146
|
Object.entries(updateEvent).filter(([_, v]) => !isEmpty(v))
|
|
977
1147
|
);
|
|
@@ -1020,10 +1190,12 @@ function updateSpanImpl({
|
|
|
1020
1190
|
id,
|
|
1021
1191
|
event
|
|
1022
1192
|
}) {
|
|
1023
|
-
const updateEvent =
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1193
|
+
const updateEvent = deepCopyEvent(
|
|
1194
|
+
validateAndSanitizeExperimentLogPartialArgs({
|
|
1195
|
+
id,
|
|
1196
|
+
...event
|
|
1197
|
+
})
|
|
1198
|
+
);
|
|
1027
1199
|
const parentIds = async () => new SpanComponentsV3({
|
|
1028
1200
|
object_type: parentObjectType,
|
|
1029
1201
|
object_id: await parentObjectId.get()
|
|
@@ -1224,7 +1396,7 @@ var Logger = class {
|
|
|
1224
1396
|
* @param event.id: (Optional) a unique identifier for the event. If you don't provide one, BrainTrust will generate one for you.
|
|
1225
1397
|
* @param options Additional logging options
|
|
1226
1398
|
* @param options.allowConcurrentWithSpans in rare cases where you need to log at the top level separately from spans on the logger elsewhere, set this to true.
|
|
1227
|
-
*
|
|
1399
|
+
* @returns The `id` of the logged event.
|
|
1228
1400
|
*/
|
|
1229
1401
|
log(event, options) {
|
|
1230
1402
|
if (this.calledStartSpan && !options?.allowConcurrentWithSpans) {
|
|
@@ -1247,7 +1419,7 @@ var Logger = class {
|
|
|
1247
1419
|
/**
|
|
1248
1420
|
* Create a new toplevel span underneath the logger. The name defaults to "root".
|
|
1249
1421
|
*
|
|
1250
|
-
* See
|
|
1422
|
+
* See {@link Span.traced} for full details.
|
|
1251
1423
|
*/
|
|
1252
1424
|
traced(callback, args) {
|
|
1253
1425
|
const { setCurrent, ...argsRest } = args ?? {};
|
|
@@ -1281,7 +1453,7 @@ var Logger = class {
|
|
|
1281
1453
|
* where you cannot use callbacks. However, spans started with `startSpan` will not be marked as the "current span",
|
|
1282
1454
|
* so `currentSpan()` and `traced()` will be no-ops. If you want to mark a span as current, use `traced` instead.
|
|
1283
1455
|
*
|
|
1284
|
-
* See
|
|
1456
|
+
* See {@link traced} for full details.
|
|
1285
1457
|
*/
|
|
1286
1458
|
startSpan(args) {
|
|
1287
1459
|
this.calledStartSpan = true;
|
|
@@ -1321,7 +1493,7 @@ var Logger = class {
|
|
|
1321
1493
|
* Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
|
|
1322
1494
|
* since otherwise updates to the span may conflict with the original span.
|
|
1323
1495
|
*
|
|
1324
|
-
* @param event The event data to update the span with. Must include `id`. See
|
|
1496
|
+
* @param event The event data to update the span with. Must include `id`. See {@link Experiment.log} for a full list of valid fields.
|
|
1325
1497
|
*/
|
|
1326
1498
|
updateSpan(event) {
|
|
1327
1499
|
const { id, ...eventRest } = event;
|
|
@@ -1337,7 +1509,9 @@ var Logger = class {
|
|
|
1337
1509
|
});
|
|
1338
1510
|
}
|
|
1339
1511
|
/**
|
|
1340
|
-
* Return a serialized representation of the logger that can be used to start subspans in other places.
|
|
1512
|
+
* Return a serialized representation of the logger that can be used to start subspans in other places.
|
|
1513
|
+
*
|
|
1514
|
+
* See {@link Span.startSpan} for more details.
|
|
1341
1515
|
*/
|
|
1342
1516
|
async export() {
|
|
1343
1517
|
return new SpanComponentsV3({
|
|
@@ -1377,6 +1551,7 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1377
1551
|
activeFlush = Promise.resolve();
|
|
1378
1552
|
activeFlushResolved = true;
|
|
1379
1553
|
activeFlushError = void 0;
|
|
1554
|
+
onFlushError;
|
|
1380
1555
|
syncFlush = false;
|
|
1381
1556
|
// 6 MB for the AWS lambda gateway (from our own testing).
|
|
1382
1557
|
maxRequestSize = 6 * 1024 * 1024;
|
|
@@ -1440,6 +1615,7 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1440
1615
|
await this.flush();
|
|
1441
1616
|
});
|
|
1442
1617
|
}
|
|
1618
|
+
this.onFlushError = opts.onFlushError;
|
|
1443
1619
|
}
|
|
1444
1620
|
log(items) {
|
|
1445
1621
|
const [addedItems, droppedItems] = (() => {
|
|
@@ -1471,14 +1647,16 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1471
1647
|
if (this.activeFlushError) {
|
|
1472
1648
|
const err = this.activeFlushError;
|
|
1473
1649
|
this.activeFlushError = void 0;
|
|
1474
|
-
|
|
1650
|
+
if (this.syncFlush) {
|
|
1651
|
+
throw err;
|
|
1652
|
+
}
|
|
1475
1653
|
}
|
|
1476
1654
|
}
|
|
1477
1655
|
async flushOnce(args) {
|
|
1478
1656
|
const batchSize = args?.batchSize ?? this.defaultBatchSize;
|
|
1479
1657
|
const wrappedItems = this.items;
|
|
1480
1658
|
this.items = [];
|
|
1481
|
-
const allItems = await this.unwrapLazyValues(wrappedItems);
|
|
1659
|
+
const [allItems, attachments] = await this.unwrapLazyValues(wrappedItems);
|
|
1482
1660
|
if (allItems.length === 0) {
|
|
1483
1661
|
return;
|
|
1484
1662
|
}
|
|
@@ -1510,6 +1688,23 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1510
1688
|
);
|
|
1511
1689
|
}
|
|
1512
1690
|
}
|
|
1691
|
+
const attachmentErrors = [];
|
|
1692
|
+
for (const attachment of attachments) {
|
|
1693
|
+
try {
|
|
1694
|
+
const result = await attachment.upload();
|
|
1695
|
+
if (result.upload_status === "error" && result.error_message) {
|
|
1696
|
+
attachmentErrors.push(new Error(result.error_message));
|
|
1697
|
+
}
|
|
1698
|
+
} catch (error2) {
|
|
1699
|
+
attachmentErrors.push(error2);
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
if (attachmentErrors.length > 0) {
|
|
1703
|
+
throw new AggregateError(
|
|
1704
|
+
attachmentErrors,
|
|
1705
|
+
`Encountered the following errors while uploading attachments:`
|
|
1706
|
+
);
|
|
1707
|
+
}
|
|
1513
1708
|
if (this.items.length > 0) {
|
|
1514
1709
|
await this.flushOnce(args);
|
|
1515
1710
|
}
|
|
@@ -1517,8 +1712,10 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1517
1712
|
async unwrapLazyValues(wrappedItems) {
|
|
1518
1713
|
for (let i = 0; i < this.numTries; ++i) {
|
|
1519
1714
|
try {
|
|
1520
|
-
const
|
|
1521
|
-
|
|
1715
|
+
const items = await Promise.all(wrappedItems.map((x) => x.get()));
|
|
1716
|
+
const attachments = [];
|
|
1717
|
+
items.forEach((item) => extractAttachments(item, attachments));
|
|
1718
|
+
return [mergeRowBatch(items), attachments];
|
|
1522
1719
|
} catch (e) {
|
|
1523
1720
|
let errmsg = "Encountered error when constructing records to flush";
|
|
1524
1721
|
const isRetrying = i + 1 < this.numTries;
|
|
@@ -1526,7 +1723,10 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1526
1723
|
errmsg += ". Retrying";
|
|
1527
1724
|
}
|
|
1528
1725
|
console.warn(errmsg);
|
|
1529
|
-
if (!isRetrying
|
|
1726
|
+
if (!isRetrying) {
|
|
1727
|
+
console.warn(
|
|
1728
|
+
`Failed to construct log records to flush after ${this.numTries} attempts. Dropping batch`
|
|
1729
|
+
);
|
|
1530
1730
|
throw e;
|
|
1531
1731
|
} else {
|
|
1532
1732
|
console.warn(e);
|
|
@@ -1534,10 +1734,7 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1534
1734
|
}
|
|
1535
1735
|
}
|
|
1536
1736
|
}
|
|
1537
|
-
|
|
1538
|
-
`Failed to construct log records to flush after ${this.numTries} attempts. Dropping batch`
|
|
1539
|
-
);
|
|
1540
|
-
return [];
|
|
1737
|
+
throw new Error("Impossible");
|
|
1541
1738
|
}
|
|
1542
1739
|
async submitLogsRequest(items) {
|
|
1543
1740
|
const conn = await this.apiConn.get();
|
|
@@ -1553,16 +1750,14 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1553
1750
|
let error2 = void 0;
|
|
1554
1751
|
try {
|
|
1555
1752
|
await conn.post_json("logs3", dataStr);
|
|
1556
|
-
} catch
|
|
1753
|
+
} catch {
|
|
1557
1754
|
try {
|
|
1558
1755
|
const legacyDataS = constructJsonArray(
|
|
1559
|
-
items.map(
|
|
1560
|
-
(r) => JSON.stringify(makeLegacyEvent(JSON.parse(r)))
|
|
1561
|
-
)
|
|
1756
|
+
items.map((r) => JSON.stringify(makeLegacyEvent(JSON.parse(r))))
|
|
1562
1757
|
);
|
|
1563
1758
|
await conn.post_json("logs", legacyDataS);
|
|
1564
|
-
} catch (
|
|
1565
|
-
error2 =
|
|
1759
|
+
} catch (e) {
|
|
1760
|
+
error2 = e;
|
|
1566
1761
|
}
|
|
1567
1762
|
}
|
|
1568
1763
|
if (error2 === void 0) {
|
|
@@ -1586,7 +1781,10 @@ Error: ${errorText}`;
|
|
|
1586
1781
|
});
|
|
1587
1782
|
this.logFailedPayloadsDir();
|
|
1588
1783
|
}
|
|
1589
|
-
if (!isRetrying
|
|
1784
|
+
if (!isRetrying) {
|
|
1785
|
+
console.warn(
|
|
1786
|
+
`log request failed after ${this.numTries} retries. Dropping batch`
|
|
1787
|
+
);
|
|
1590
1788
|
throw new Error(errMsg);
|
|
1591
1789
|
} else {
|
|
1592
1790
|
console.warn(errMsg);
|
|
@@ -1595,10 +1793,6 @@ Error: ${errorText}`;
|
|
|
1595
1793
|
}
|
|
1596
1794
|
}
|
|
1597
1795
|
}
|
|
1598
|
-
console.warn(
|
|
1599
|
-
`log request failed after ${this.numTries} retries. Dropping batch`
|
|
1600
|
-
);
|
|
1601
|
-
return;
|
|
1602
1796
|
}
|
|
1603
1797
|
registerDroppedItemCount(numItems) {
|
|
1604
1798
|
if (numItems <= 0) {
|
|
@@ -1626,15 +1820,17 @@ Error: ${errorText}`;
|
|
|
1626
1820
|
return;
|
|
1627
1821
|
}
|
|
1628
1822
|
try {
|
|
1629
|
-
const allItems = await this.unwrapLazyValues(wrappedItems);
|
|
1823
|
+
const [allItems, allAttachments] = await this.unwrapLazyValues(wrappedItems);
|
|
1630
1824
|
const dataStr = constructLogs3Data(
|
|
1631
1825
|
allItems.map((x) => JSON.stringify(x))
|
|
1632
1826
|
);
|
|
1827
|
+
const attachmentStr = JSON.stringify(
|
|
1828
|
+
allAttachments.map((a) => a.debugInfo())
|
|
1829
|
+
);
|
|
1830
|
+
const payload = `{"data": ${dataStr}, "attachments": ${attachmentStr}}
|
|
1831
|
+
`;
|
|
1633
1832
|
for (const payloadDir of publishPayloadsDir) {
|
|
1634
|
-
await _BackgroundLogger.writePayloadToDir({
|
|
1635
|
-
payloadDir,
|
|
1636
|
-
payload: dataStr
|
|
1637
|
-
});
|
|
1833
|
+
await _BackgroundLogger.writePayloadToDir({ payloadDir, payload });
|
|
1638
1834
|
}
|
|
1639
1835
|
} catch (e) {
|
|
1640
1836
|
console.error(e);
|
|
@@ -1673,6 +1869,13 @@ Error: ${errorText}`;
|
|
|
1673
1869
|
try {
|
|
1674
1870
|
await this.flushOnce();
|
|
1675
1871
|
} catch (err) {
|
|
1872
|
+
if (err instanceof AggregateError) {
|
|
1873
|
+
for (const e of err.errors) {
|
|
1874
|
+
this.onFlushError?.(e);
|
|
1875
|
+
}
|
|
1876
|
+
} else {
|
|
1877
|
+
this.onFlushError?.(err);
|
|
1878
|
+
}
|
|
1676
1879
|
this.activeFlushError = err;
|
|
1677
1880
|
} finally {
|
|
1678
1881
|
this.activeFlushResolved = true;
|
|
@@ -1715,7 +1918,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
1715
1918
|
apiKey,
|
|
1716
1919
|
orgName,
|
|
1717
1920
|
forceLogin,
|
|
1718
|
-
fetch,
|
|
1921
|
+
fetch: fetch2,
|
|
1719
1922
|
metadata,
|
|
1720
1923
|
gitMetadataSettings,
|
|
1721
1924
|
projectId,
|
|
@@ -1733,7 +1936,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
1733
1936
|
}
|
|
1734
1937
|
const lazyMetadata2 = new LazyValue(
|
|
1735
1938
|
async () => {
|
|
1736
|
-
await state.login({ apiKey, appUrl, orgName, fetch, forceLogin });
|
|
1939
|
+
await state.login({ apiKey, appUrl, orgName, fetch: fetch2, forceLogin });
|
|
1737
1940
|
const args = {
|
|
1738
1941
|
project_name: project,
|
|
1739
1942
|
project_id: projectId,
|
|
@@ -1904,7 +2107,7 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
1904
2107
|
appUrl,
|
|
1905
2108
|
apiKey,
|
|
1906
2109
|
orgName,
|
|
1907
|
-
fetch,
|
|
2110
|
+
fetch: fetch2,
|
|
1908
2111
|
forceLogin,
|
|
1909
2112
|
projectId,
|
|
1910
2113
|
metadata,
|
|
@@ -1918,7 +2121,7 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
1918
2121
|
orgName,
|
|
1919
2122
|
apiKey,
|
|
1920
2123
|
appUrl,
|
|
1921
|
-
fetch,
|
|
2124
|
+
fetch: fetch2,
|
|
1922
2125
|
forceLogin
|
|
1923
2126
|
});
|
|
1924
2127
|
const args = {
|
|
@@ -2000,7 +2203,7 @@ function initLogger(options = {}) {
|
|
|
2000
2203
|
apiKey,
|
|
2001
2204
|
orgName,
|
|
2002
2205
|
forceLogin,
|
|
2003
|
-
fetch,
|
|
2206
|
+
fetch: fetch2,
|
|
2004
2207
|
state: stateArg
|
|
2005
2208
|
} = options || {};
|
|
2006
2209
|
const computeMetadataArgs = {
|
|
@@ -2015,7 +2218,7 @@ function initLogger(options = {}) {
|
|
|
2015
2218
|
apiKey,
|
|
2016
2219
|
appUrl,
|
|
2017
2220
|
forceLogin,
|
|
2018
|
-
fetch
|
|
2221
|
+
fetch: fetch2
|
|
2019
2222
|
});
|
|
2020
2223
|
return computeLoggerMetadata(state, computeMetadataArgs);
|
|
2021
2224
|
}
|
|
@@ -2039,7 +2242,7 @@ async function loadPrompt({
|
|
|
2039
2242
|
appUrl,
|
|
2040
2243
|
apiKey,
|
|
2041
2244
|
orgName,
|
|
2042
|
-
fetch,
|
|
2245
|
+
fetch: fetch2,
|
|
2043
2246
|
forceLogin,
|
|
2044
2247
|
state: stateArg
|
|
2045
2248
|
}) {
|
|
@@ -2054,7 +2257,7 @@ async function loadPrompt({
|
|
|
2054
2257
|
orgName,
|
|
2055
2258
|
apiKey,
|
|
2056
2259
|
appUrl,
|
|
2057
|
-
fetch,
|
|
2260
|
+
fetch: fetch2,
|
|
2058
2261
|
forceLogin
|
|
2059
2262
|
});
|
|
2060
2263
|
const args = {
|
|
@@ -2105,7 +2308,7 @@ async function loginToState(options = {}) {
|
|
|
2105
2308
|
appUrl = isomorph_default.getEnv("BRAINTRUST_APP_URL") || "https://www.braintrust.dev",
|
|
2106
2309
|
apiKey = isomorph_default.getEnv("BRAINTRUST_API_KEY"),
|
|
2107
2310
|
orgName = isomorph_default.getEnv("BRAINTRUST_ORG_NAME"),
|
|
2108
|
-
fetch = globalThis.fetch
|
|
2311
|
+
fetch: fetch2 = globalThis.fetch
|
|
2109
2312
|
} = options || {};
|
|
2110
2313
|
const appPublicUrl = isomorph_default.getEnv("BRAINTRUST_APP_PUBLIC_URL") || appUrl;
|
|
2111
2314
|
const state = new BraintrustState(options);
|
|
@@ -2115,7 +2318,7 @@ async function loginToState(options = {}) {
|
|
|
2115
2318
|
let conn = null;
|
|
2116
2319
|
if (apiKey !== void 0) {
|
|
2117
2320
|
const resp = await checkResponse(
|
|
2118
|
-
await
|
|
2321
|
+
await fetch2(_urljoin(state.appUrl, `/api/apikey/login`), {
|
|
2119
2322
|
method: "POST",
|
|
2120
2323
|
headers: {
|
|
2121
2324
|
"Content-Type": "application/json",
|
|
@@ -2283,8 +2486,8 @@ async function flush(options) {
|
|
|
2283
2486
|
const state = options?.state ?? _globalState;
|
|
2284
2487
|
return await state.bgLogger().flush();
|
|
2285
2488
|
}
|
|
2286
|
-
function setFetch(
|
|
2287
|
-
_globalState.setFetch(
|
|
2489
|
+
function setFetch(fetch2) {
|
|
2490
|
+
_globalState.setFetch(fetch2);
|
|
2288
2491
|
}
|
|
2289
2492
|
function startSpanAndIsLogger(args) {
|
|
2290
2493
|
const state = args?.state ?? _globalState;
|
|
@@ -2412,6 +2615,47 @@ function validateAndSanitizeExperimentLogPartialArgs(event) {
|
|
|
2412
2615
|
return { ...event };
|
|
2413
2616
|
}
|
|
2414
2617
|
}
|
|
2618
|
+
function deepCopyEvent(event) {
|
|
2619
|
+
const attachments = [];
|
|
2620
|
+
const IDENTIFIER = "_bt_internal_saved_attachment";
|
|
2621
|
+
const savedAttachmentSchema = z2.strictObject({ [IDENTIFIER]: z2.number() });
|
|
2622
|
+
const serialized = JSON.stringify(event, (_k, v) => {
|
|
2623
|
+
if (v instanceof SpanImpl || v instanceof NoopSpan) {
|
|
2624
|
+
return `<span>`;
|
|
2625
|
+
} else if (v instanceof Experiment) {
|
|
2626
|
+
return `<experiment>`;
|
|
2627
|
+
} else if (v instanceof Dataset) {
|
|
2628
|
+
return `<dataset>`;
|
|
2629
|
+
} else if (v instanceof Logger) {
|
|
2630
|
+
return `<logger>`;
|
|
2631
|
+
} else if (v instanceof Attachment) {
|
|
2632
|
+
const idx = attachments.push(v);
|
|
2633
|
+
return { [IDENTIFIER]: idx - 1 };
|
|
2634
|
+
}
|
|
2635
|
+
return v;
|
|
2636
|
+
});
|
|
2637
|
+
const x = JSON.parse(serialized, (_k, v) => {
|
|
2638
|
+
const parsedAttachment = savedAttachmentSchema.safeParse(v);
|
|
2639
|
+
if (parsedAttachment.success) {
|
|
2640
|
+
return attachments[parsedAttachment.data[IDENTIFIER]];
|
|
2641
|
+
}
|
|
2642
|
+
return v;
|
|
2643
|
+
});
|
|
2644
|
+
return x;
|
|
2645
|
+
}
|
|
2646
|
+
function extractAttachments(event, attachments) {
|
|
2647
|
+
for (const [key, value] of Object.entries(event)) {
|
|
2648
|
+
if (value instanceof Attachment) {
|
|
2649
|
+
attachments.push(value);
|
|
2650
|
+
event[key] = value.reference;
|
|
2651
|
+
continue;
|
|
2652
|
+
}
|
|
2653
|
+
if (!(value instanceof Object)) {
|
|
2654
|
+
continue;
|
|
2655
|
+
}
|
|
2656
|
+
extractAttachments(value, attachments);
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2415
2659
|
function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
|
|
2416
2660
|
if ("input" in event && !isEmpty(event.input) && "inputs" in event && !isEmpty(event.inputs) || !("input" in event) && !("inputs" in event)) {
|
|
2417
2661
|
throw new Error(
|
|
@@ -2542,10 +2786,9 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2542
2786
|
* @param event.metrics: (Optional) a dictionary of metrics to log. The following keys are populated automatically: "start", "end".
|
|
2543
2787
|
* @param event.id: (Optional) a unique identifier for the event. If you don't provide one, BrainTrust will generate one for you.
|
|
2544
2788
|
* @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.
|
|
2545
|
-
* @param event.inputs: (Deprecated) the same as `input` (will be removed in a future version).
|
|
2546
2789
|
* @param options Additional logging options
|
|
2547
2790
|
* @param options.allowConcurrentWithSpans in rare cases where you need to log at the top level separately from spans on the experiment elsewhere, set this to true.
|
|
2548
|
-
*
|
|
2791
|
+
* @returns The `id` of the logged event.
|
|
2549
2792
|
*/
|
|
2550
2793
|
log(event, options) {
|
|
2551
2794
|
if (this.calledStartSpan && !options?.allowConcurrentWithSpans) {
|
|
@@ -2561,7 +2804,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2561
2804
|
/**
|
|
2562
2805
|
* Create a new toplevel span underneath the experiment. The name defaults to "root".
|
|
2563
2806
|
*
|
|
2564
|
-
* See
|
|
2807
|
+
* See {@link Span.traced} for full details.
|
|
2565
2808
|
*/
|
|
2566
2809
|
traced(callback, args) {
|
|
2567
2810
|
const { setCurrent, ...argsRest } = args ?? {};
|
|
@@ -2587,7 +2830,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2587
2830
|
* where you cannot use callbacks. However, spans started with `startSpan` will not be marked as the "current span",
|
|
2588
2831
|
* so `currentSpan()` and `traced()` will be no-ops. If you want to mark a span as current, use `traced` instead.
|
|
2589
2832
|
*
|
|
2590
|
-
* See
|
|
2833
|
+
* See {@link traced} for full details.
|
|
2591
2834
|
*/
|
|
2592
2835
|
startSpan(args) {
|
|
2593
2836
|
this.calledStartSpan = true;
|
|
@@ -2699,7 +2942,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2699
2942
|
* Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
|
|
2700
2943
|
* since otherwise updates to the span may conflict with the original span.
|
|
2701
2944
|
*
|
|
2702
|
-
* @param event The event data to update the span with. Must include `id`. See
|
|
2945
|
+
* @param event The event data to update the span with. Must include `id`. See {@link Experiment.log} for a full list of valid fields.
|
|
2703
2946
|
*/
|
|
2704
2947
|
updateSpan(event) {
|
|
2705
2948
|
const { id, ...eventRest } = event;
|
|
@@ -2715,7 +2958,9 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2715
2958
|
});
|
|
2716
2959
|
}
|
|
2717
2960
|
/**
|
|
2718
|
-
* Return a serialized representation of the experiment that can be used to start subspans in other places.
|
|
2961
|
+
* Return a serialized representation of the experiment that can be used to start subspans in other places.
|
|
2962
|
+
*
|
|
2963
|
+
* See {@link Span.startSpan} for more details.
|
|
2719
2964
|
*/
|
|
2720
2965
|
async export() {
|
|
2721
2966
|
return new SpanComponentsV3({
|
|
@@ -2730,7 +2975,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2730
2975
|
return await this.state.bgLogger().flush();
|
|
2731
2976
|
}
|
|
2732
2977
|
/**
|
|
2733
|
-
* This function is deprecated. You can simply remove it from your code.
|
|
2978
|
+
* @deprecated This function is deprecated. You can simply remove it from your code.
|
|
2734
2979
|
*/
|
|
2735
2980
|
async close() {
|
|
2736
2981
|
console.warn(
|
|
@@ -2872,27 +3117,14 @@ var SpanImpl = class _SpanImpl {
|
|
|
2872
3117
|
event,
|
|
2873
3118
|
internalData
|
|
2874
3119
|
});
|
|
2875
|
-
|
|
3120
|
+
const partialRecord = deepCopyEvent({
|
|
2876
3121
|
id: this.id,
|
|
2877
3122
|
span_id: this.spanId,
|
|
2878
3123
|
root_span_id: this.rootSpanId,
|
|
2879
3124
|
span_parents: this.spanParents,
|
|
2880
3125
|
...serializableInternalData,
|
|
2881
3126
|
[IS_MERGE_FIELD]: this.isMerge
|
|
2882
|
-
};
|
|
2883
|
-
const serializedPartialRecord = JSON.stringify(partialRecord, (_k, v) => {
|
|
2884
|
-
if (v instanceof _SpanImpl) {
|
|
2885
|
-
return `<span>`;
|
|
2886
|
-
} else if (v instanceof Experiment) {
|
|
2887
|
-
return `<experiment>`;
|
|
2888
|
-
} else if (v instanceof Dataset) {
|
|
2889
|
-
return `<dataset>`;
|
|
2890
|
-
} else if (v instanceof Logger) {
|
|
2891
|
-
return `<logger>`;
|
|
2892
|
-
}
|
|
2893
|
-
return v;
|
|
2894
3127
|
});
|
|
2895
|
-
partialRecord = JSON.parse(serializedPartialRecord);
|
|
2896
3128
|
if (partialRecord.metrics?.end) {
|
|
2897
3129
|
this.loggedEndTime = partialRecord.metrics?.end;
|
|
2898
3130
|
}
|
|
@@ -2978,6 +3210,11 @@ var SpanImpl = class _SpanImpl {
|
|
|
2978
3210
|
propagated_event: this.propagatedEvent
|
|
2979
3211
|
}).toStr();
|
|
2980
3212
|
}
|
|
3213
|
+
async permalink() {
|
|
3214
|
+
return await permalink(await this.export(), {
|
|
3215
|
+
state: this.state
|
|
3216
|
+
});
|
|
3217
|
+
}
|
|
2981
3218
|
async flush() {
|
|
2982
3219
|
return await this.state.bgLogger().flush();
|
|
2983
3220
|
}
|
|
@@ -3127,15 +3364,17 @@ var Dataset = class extends ObjectFetcher {
|
|
|
3127
3364
|
}) {
|
|
3128
3365
|
this.validateEvent({ metadata, expected, output, tags });
|
|
3129
3366
|
const rowId = id || uuidv4();
|
|
3130
|
-
const args = this.createArgs(
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3367
|
+
const args = this.createArgs(
|
|
3368
|
+
deepCopyEvent({
|
|
3369
|
+
id: rowId,
|
|
3370
|
+
input,
|
|
3371
|
+
expected,
|
|
3372
|
+
metadata,
|
|
3373
|
+
tags,
|
|
3374
|
+
output,
|
|
3375
|
+
isMerge: false
|
|
3376
|
+
})
|
|
3377
|
+
);
|
|
3139
3378
|
this.state.bgLogger().log([args]);
|
|
3140
3379
|
return rowId;
|
|
3141
3380
|
}
|
|
@@ -3160,14 +3399,16 @@ var Dataset = class extends ObjectFetcher {
|
|
|
3160
3399
|
id
|
|
3161
3400
|
}) {
|
|
3162
3401
|
this.validateEvent({ metadata, expected, tags });
|
|
3163
|
-
const args = this.createArgs(
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3402
|
+
const args = this.createArgs(
|
|
3403
|
+
deepCopyEvent({
|
|
3404
|
+
id,
|
|
3405
|
+
input,
|
|
3406
|
+
expected,
|
|
3407
|
+
metadata,
|
|
3408
|
+
tags,
|
|
3409
|
+
isMerge: true
|
|
3410
|
+
})
|
|
3411
|
+
);
|
|
3171
3412
|
this.state.bgLogger().log([args]);
|
|
3172
3413
|
return id;
|
|
3173
3414
|
}
|
|
@@ -3222,7 +3463,7 @@ var Dataset = class extends ObjectFetcher {
|
|
|
3222
3463
|
return await this.state.bgLogger().flush();
|
|
3223
3464
|
}
|
|
3224
3465
|
/**
|
|
3225
|
-
* This function is deprecated. You can simply remove it from your code.
|
|
3466
|
+
* @deprecated This function is deprecated. You can simply remove it from your code.
|
|
3226
3467
|
*/
|
|
3227
3468
|
async close() {
|
|
3228
3469
|
console.warn(
|
|
@@ -3386,6 +3627,7 @@ var Prompt = class {
|
|
|
3386
3627
|
return this.parsedPromptData;
|
|
3387
3628
|
}
|
|
3388
3629
|
};
|
|
3630
|
+
var _exportsForTestingOnly = { extractAttachments, deepCopyEvent };
|
|
3389
3631
|
|
|
3390
3632
|
// src/node.ts
|
|
3391
3633
|
function configureNode() {
|
|
@@ -3401,12 +3643,14 @@ function configureNode() {
|
|
|
3401
3643
|
isomorph_default.pathDirname = path.dirname;
|
|
3402
3644
|
isomorph_default.mkdir = fs.mkdir;
|
|
3403
3645
|
isomorph_default.writeFile = fs.writeFile;
|
|
3646
|
+
isomorph_default.readFile = fs.readFile;
|
|
3404
3647
|
_internalSetInitialState();
|
|
3405
3648
|
}
|
|
3406
3649
|
|
|
3407
3650
|
// src/exports-node.ts
|
|
3408
3651
|
var exports_node_exports = {};
|
|
3409
3652
|
__export(exports_node_exports, {
|
|
3653
|
+
Attachment: () => Attachment,
|
|
3410
3654
|
BaseExperiment: () => BaseExperiment,
|
|
3411
3655
|
BraintrustState: () => BraintrustState,
|
|
3412
3656
|
BraintrustStream: () => BraintrustStream,
|
|
@@ -3429,6 +3673,7 @@ __export(exports_node_exports, {
|
|
|
3429
3673
|
SpanImpl: () => SpanImpl,
|
|
3430
3674
|
ToolBuilder: () => ToolBuilder,
|
|
3431
3675
|
X_CACHED_HEADER: () => X_CACHED_HEADER,
|
|
3676
|
+
_exportsForTestingOnly: () => _exportsForTestingOnly,
|
|
3432
3677
|
_internalGetGlobalState: () => _internalGetGlobalState,
|
|
3433
3678
|
_internalSetInitialState: () => _internalSetInitialState,
|
|
3434
3679
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
@@ -3484,7 +3729,7 @@ async function invoke(args) {
|
|
|
3484
3729
|
apiKey,
|
|
3485
3730
|
appUrl,
|
|
3486
3731
|
forceLogin,
|
|
3487
|
-
fetch,
|
|
3732
|
+
fetch: fetch2,
|
|
3488
3733
|
input,
|
|
3489
3734
|
messages,
|
|
3490
3735
|
parent: parentArg,
|
|
@@ -3500,7 +3745,7 @@ async function invoke(args) {
|
|
|
3500
3745
|
apiKey,
|
|
3501
3746
|
appUrl,
|
|
3502
3747
|
forceLogin,
|
|
3503
|
-
fetch
|
|
3748
|
+
fetch: fetch2
|
|
3504
3749
|
});
|
|
3505
3750
|
const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await getSpanParentObject().export();
|
|
3506
3751
|
const functionId = functionIdSchema.safeParse({
|
|
@@ -4751,6 +4996,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
4751
4996
|
}
|
|
4752
4997
|
if (globalThis._lazy_load) {
|
|
4753
4998
|
globalThis._evals.evaluators[evalName] = {
|
|
4999
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
4754
5000
|
evaluator: {
|
|
4755
5001
|
evalName,
|
|
4756
5002
|
projectName: name,
|
|
@@ -4789,7 +5035,8 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
4789
5035
|
baseExperiment: evaluator.baseExperimentName ?? defaultBaseExperiment,
|
|
4790
5036
|
baseExperimentId: evaluator.baseExperimentId,
|
|
4791
5037
|
gitMetadataSettings: evaluator.gitMetadataSettings,
|
|
4792
|
-
repoInfo: evaluator.repoInfo
|
|
5038
|
+
repoInfo: evaluator.repoInfo,
|
|
5039
|
+
dataset: data instanceof Dataset ? data : void 0
|
|
4793
5040
|
});
|
|
4794
5041
|
if (options.onStart) {
|
|
4795
5042
|
experiment.summarize({ summarizeScores: false }).then(options.onStart);
|
|
@@ -4835,7 +5082,10 @@ function serializeJSONWithPlainString(v) {
|
|
|
4835
5082
|
function evaluateFilter(object, filter2) {
|
|
4836
5083
|
const { path: path3, pattern } = filter2;
|
|
4837
5084
|
const key = path3.reduce(
|
|
4838
|
-
(acc, p) => typeof acc === "object" && acc !== null ?
|
|
5085
|
+
(acc, p) => typeof acc === "object" && acc !== null ? (
|
|
5086
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
5087
|
+
acc[p]
|
|
5088
|
+
) : void 0,
|
|
4839
5089
|
object
|
|
4840
5090
|
);
|
|
4841
5091
|
if (key === void 0) {
|
|
@@ -4942,7 +5192,12 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
4942
5192
|
}
|
|
4943
5193
|
);
|
|
4944
5194
|
rootSpan.log({ output, metadata });
|
|
4945
|
-
const scoringArgs = {
|
|
5195
|
+
const scoringArgs = {
|
|
5196
|
+
input: datum.input,
|
|
5197
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
5198
|
+
metadata,
|
|
5199
|
+
output
|
|
5200
|
+
};
|
|
4946
5201
|
const scorerNames = evaluator.scores.map(scorerName);
|
|
4947
5202
|
const scoreResults = await Promise.all(
|
|
4948
5203
|
evaluator.scores.map(async (score, score_idx) => {
|
|
@@ -5069,7 +5324,13 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
5069
5324
|
event: {
|
|
5070
5325
|
input: datum.input,
|
|
5071
5326
|
expected: "expected" in datum ? datum.expected : void 0,
|
|
5072
|
-
tags: datum.tags
|
|
5327
|
+
tags: datum.tags,
|
|
5328
|
+
origin: experiment.dataset && datum.id && datum._xact_id ? {
|
|
5329
|
+
object_type: "dataset",
|
|
5330
|
+
object_id: await experiment.dataset.id,
|
|
5331
|
+
id: datum.id,
|
|
5332
|
+
_xact_id: datum._xact_id
|
|
5333
|
+
} : void 0
|
|
5073
5334
|
}
|
|
5074
5335
|
});
|
|
5075
5336
|
}
|
|
@@ -5931,6 +6192,7 @@ function postProcessOutput(text, tool_calls, finish_reason) {
|
|
|
5931
6192
|
configureNode();
|
|
5932
6193
|
var src_default = exports_node_exports;
|
|
5933
6194
|
export {
|
|
6195
|
+
Attachment,
|
|
5934
6196
|
BaseExperiment,
|
|
5935
6197
|
BraintrustState,
|
|
5936
6198
|
BraintrustStream,
|
|
@@ -5953,6 +6215,7 @@ export {
|
|
|
5953
6215
|
SpanImpl,
|
|
5954
6216
|
ToolBuilder,
|
|
5955
6217
|
X_CACHED_HEADER,
|
|
6218
|
+
_exportsForTestingOnly,
|
|
5956
6219
|
_internalGetGlobalState,
|
|
5957
6220
|
_internalSetInitialState,
|
|
5958
6221
|
braintrustStreamChunkSchema,
|