braintrust 0.0.141-dev1 → 0.0.141
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 +144 -23
- package/dist/browser.d.ts +144 -23
- package/dist/browser.js +181 -110
- package/dist/browser.mjs +182 -111
- package/dist/cli.js +221 -161
- package/dist/index.d.mts +144 -23
- package/dist/index.d.ts +144 -23
- package/dist/index.js +182 -111
- package/dist/index.mjs +183 -112
- package/package.json +12 -10
- package/.turbo/turbo-build.log +0 -42
- package/.turbo/turbo-watch.log +0 -1843
- package/LICENSE +0 -201
package/dist/index.js
CHANGED
|
@@ -48,6 +48,7 @@ __export(src_exports, {
|
|
|
48
48
|
X_CACHED_HEADER: () => X_CACHED_HEADER,
|
|
49
49
|
_internalGetGlobalState: () => _internalGetGlobalState,
|
|
50
50
|
_internalSetInitialState: () => _internalSetInitialState,
|
|
51
|
+
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
51
52
|
buildLocalSummary: () => buildLocalSummary,
|
|
52
53
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
53
54
|
currentExperiment: () => currentExperiment,
|
|
@@ -374,27 +375,79 @@ var LazyValue = class {
|
|
|
374
375
|
return this.value.hasComputed;
|
|
375
376
|
}
|
|
376
377
|
};
|
|
378
|
+
function _urljoin(...parts) {
|
|
379
|
+
return parts.map(
|
|
380
|
+
(x, i) => x.replace(/^\//, "").replace(i < parts.length - 1 ? /\/$/ : "", "")
|
|
381
|
+
).filter((x) => x.trim() !== "").join("/");
|
|
382
|
+
}
|
|
377
383
|
|
|
378
384
|
// src/logger.ts
|
|
379
385
|
var import_mustache = __toESM(require("mustache"));
|
|
380
|
-
var
|
|
386
|
+
var import_zod2 = require("zod");
|
|
381
387
|
|
|
382
|
-
// src/stream.ts
|
|
388
|
+
// src/functions/stream.ts
|
|
383
389
|
var import_typespecs = require("@braintrust/core/typespecs");
|
|
384
390
|
var import_eventsource_parser = require("eventsource-parser");
|
|
391
|
+
var import_zod = require("zod");
|
|
392
|
+
var braintrustStreamChunkSchema = import_zod.z.union([
|
|
393
|
+
import_zod.z.object({
|
|
394
|
+
type: import_zod.z.literal("text_delta"),
|
|
395
|
+
data: import_zod.z.string()
|
|
396
|
+
}),
|
|
397
|
+
import_zod.z.object({
|
|
398
|
+
type: import_zod.z.literal("json_delta"),
|
|
399
|
+
data: import_zod.z.string()
|
|
400
|
+
})
|
|
401
|
+
]);
|
|
385
402
|
var BraintrustStream = class _BraintrustStream {
|
|
386
403
|
stream;
|
|
404
|
+
memoizedFinalValue;
|
|
387
405
|
constructor(baseStream) {
|
|
388
406
|
this.stream = baseStream.pipeThrough(btStreamParser());
|
|
389
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* Copy the stream. This returns a new stream that shares the same underlying
|
|
410
|
+
* stream (via `tee`). Since streams are consumed in Javascript, use `copy()` if you
|
|
411
|
+
* need to use the stream multiple times.
|
|
412
|
+
*
|
|
413
|
+
* @returns A new stream that you can independently consume.
|
|
414
|
+
*/
|
|
390
415
|
copy() {
|
|
391
416
|
const [newStream, copyStream] = this.stream.tee();
|
|
392
417
|
this.stream = copyStream;
|
|
393
418
|
return new _BraintrustStream(newStream);
|
|
394
419
|
}
|
|
420
|
+
/**
|
|
421
|
+
* Get the underlying ReadableStream.
|
|
422
|
+
*
|
|
423
|
+
* @returns The underlying ReadableStream<BraintrustStreamChunk>.
|
|
424
|
+
*/
|
|
395
425
|
toReadableStream() {
|
|
396
426
|
return this.stream;
|
|
397
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Get the final value of the stream. The final value is the concatenation of all
|
|
430
|
+
* the chunks in the stream, deserialized into a string or JSON object, depending on
|
|
431
|
+
* the value's type.
|
|
432
|
+
*
|
|
433
|
+
* This function returns a promise that resolves when the stream is closed, and
|
|
434
|
+
* contains the final value. Multiple calls to `finalValue()` will return the same
|
|
435
|
+
* promise, so it is safe to call this multiple times.
|
|
436
|
+
*
|
|
437
|
+
* This function consumes the stream, so if you need to use the stream multiple
|
|
438
|
+
* times, you should call `copy()` first.
|
|
439
|
+
*
|
|
440
|
+
* @returns A promise that resolves with the final value of the stream or `undefined` if the stream is empty.
|
|
441
|
+
*/
|
|
442
|
+
finalValue() {
|
|
443
|
+
if (this.memoizedFinalValue) {
|
|
444
|
+
return this.memoizedFinalValue;
|
|
445
|
+
}
|
|
446
|
+
this.memoizedFinalValue = new Promise((resolve, reject2) => {
|
|
447
|
+
const stream = this.stream.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
448
|
+
});
|
|
449
|
+
return this.memoizedFinalValue;
|
|
450
|
+
}
|
|
398
451
|
};
|
|
399
452
|
function btStreamParser() {
|
|
400
453
|
const decoder = new TextDecoder();
|
|
@@ -449,9 +502,17 @@ function createFinalValuePassThroughStream(onFinal) {
|
|
|
449
502
|
transform(chunk, controller) {
|
|
450
503
|
if (typeof chunk === "string") {
|
|
451
504
|
textChunks.push(chunk);
|
|
505
|
+
controller.enqueue({
|
|
506
|
+
type: "text_delta",
|
|
507
|
+
data: chunk
|
|
508
|
+
});
|
|
452
509
|
} else if (chunk instanceof Uint8Array) {
|
|
453
510
|
textChunks.push(decoder.decode(chunk));
|
|
454
|
-
|
|
511
|
+
controller.enqueue({
|
|
512
|
+
type: "text_delta",
|
|
513
|
+
data: decoder.decode(chunk)
|
|
514
|
+
});
|
|
515
|
+
} else if (braintrustStreamChunkSchema.safeParse(chunk).success) {
|
|
455
516
|
const chunkType = chunk.type;
|
|
456
517
|
switch (chunkType) {
|
|
457
518
|
case "text_delta":
|
|
@@ -465,6 +526,8 @@ function createFinalValuePassThroughStream(onFinal) {
|
|
|
465
526
|
throw new Error(`Unknown chunk type ${_type}`);
|
|
466
527
|
}
|
|
467
528
|
controller.enqueue(chunk);
|
|
529
|
+
} else {
|
|
530
|
+
throw new Error(`Unknown chunk type ${chunk}`);
|
|
468
531
|
}
|
|
469
532
|
},
|
|
470
533
|
flush(controller) {
|
|
@@ -526,14 +589,14 @@ var NoopSpan = class {
|
|
|
526
589
|
}
|
|
527
590
|
};
|
|
528
591
|
var NOOP_SPAN = new NoopSpan();
|
|
529
|
-
var loginSchema =
|
|
530
|
-
appUrl:
|
|
531
|
-
appPublicUrl:
|
|
532
|
-
orgName:
|
|
533
|
-
|
|
534
|
-
proxyUrl:
|
|
535
|
-
loginToken:
|
|
536
|
-
orgId:
|
|
592
|
+
var loginSchema = import_zod2.z.strictObject({
|
|
593
|
+
appUrl: import_zod2.z.string(),
|
|
594
|
+
appPublicUrl: import_zod2.z.string(),
|
|
595
|
+
orgName: import_zod2.z.string(),
|
|
596
|
+
apiUrl: import_zod2.z.string(),
|
|
597
|
+
proxyUrl: import_zod2.z.string(),
|
|
598
|
+
loginToken: import_zod2.z.string(),
|
|
599
|
+
orgId: import_zod2.z.string().nullish(),
|
|
537
600
|
gitMetadataSettings: import_core.gitMetadataSettingsSchema.nullish()
|
|
538
601
|
});
|
|
539
602
|
var BraintrustState = class _BraintrustState {
|
|
@@ -548,7 +611,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
548
611
|
}
|
|
549
612
|
const defaultGetLogConn = async () => {
|
|
550
613
|
await this.login({});
|
|
551
|
-
return this.
|
|
614
|
+
return this.apiConn();
|
|
552
615
|
};
|
|
553
616
|
this._bgLogger = new BackgroundLogger(new LazyValue(defaultGetLogConn));
|
|
554
617
|
this.resetLoginInfo();
|
|
@@ -559,7 +622,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
559
622
|
// (safely) dynamically cast it whenever retrieving the logger.
|
|
560
623
|
currentLogger;
|
|
561
624
|
currentSpan;
|
|
562
|
-
// Any time we re-log in, we directly update the
|
|
625
|
+
// Any time we re-log in, we directly update the apiConn inside the logger.
|
|
563
626
|
// This is preferable to replacing the whole logger, which would create the
|
|
564
627
|
// possibility of multiple loggers floating around, which may not log in a
|
|
565
628
|
// deterministic order.
|
|
@@ -569,13 +632,13 @@ var BraintrustState = class _BraintrustState {
|
|
|
569
632
|
loginToken = null;
|
|
570
633
|
orgId = null;
|
|
571
634
|
orgName = null;
|
|
572
|
-
|
|
635
|
+
apiUrl = null;
|
|
573
636
|
proxyUrl = null;
|
|
574
637
|
loggedIn = false;
|
|
575
638
|
gitMetadataSettings;
|
|
576
639
|
fetch = globalThis.fetch;
|
|
640
|
+
_appConn = null;
|
|
577
641
|
_apiConn = null;
|
|
578
|
-
_logConn = null;
|
|
579
642
|
_proxyConn = null;
|
|
580
643
|
resetLoginInfo() {
|
|
581
644
|
this.appUrl = null;
|
|
@@ -583,12 +646,12 @@ var BraintrustState = class _BraintrustState {
|
|
|
583
646
|
this.loginToken = null;
|
|
584
647
|
this.orgId = null;
|
|
585
648
|
this.orgName = null;
|
|
586
|
-
this.
|
|
649
|
+
this.apiUrl = null;
|
|
587
650
|
this.proxyUrl = null;
|
|
588
651
|
this.loggedIn = false;
|
|
589
652
|
this.gitMetadataSettings = void 0;
|
|
653
|
+
this._appConn = null;
|
|
590
654
|
this._apiConn = null;
|
|
591
|
-
this._logConn = null;
|
|
592
655
|
this._proxyConn = null;
|
|
593
656
|
}
|
|
594
657
|
copyLoginInfo(other) {
|
|
@@ -597,12 +660,12 @@ var BraintrustState = class _BraintrustState {
|
|
|
597
660
|
this.loginToken = other.loginToken;
|
|
598
661
|
this.orgId = other.orgId;
|
|
599
662
|
this.orgName = other.orgName;
|
|
600
|
-
this.
|
|
663
|
+
this.apiUrl = other.apiUrl;
|
|
601
664
|
this.proxyUrl = other.proxyUrl;
|
|
602
665
|
this.loggedIn = other.loggedIn;
|
|
603
666
|
this.gitMetadataSettings = other.gitMetadataSettings;
|
|
667
|
+
this._appConn = other._appConn;
|
|
604
668
|
this._apiConn = other._apiConn;
|
|
605
|
-
this._logConn = other._logConn;
|
|
606
669
|
this._proxyConn = other._proxyConn;
|
|
607
670
|
}
|
|
608
671
|
serialize() {
|
|
@@ -611,7 +674,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
611
674
|
"Cannot serialize BraintrustState without being logged in"
|
|
612
675
|
);
|
|
613
676
|
}
|
|
614
|
-
if (!this.appUrl || !this.appPublicUrl || !this.
|
|
677
|
+
if (!this.appUrl || !this.appPublicUrl || !this.apiUrl || !this.proxyUrl || !this.orgName || !this.loginToken || !this.loggedIn) {
|
|
615
678
|
throw new Error(
|
|
616
679
|
"Cannot serialize BraintrustState without all login attributes"
|
|
617
680
|
);
|
|
@@ -622,7 +685,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
622
685
|
loginToken: this.loginToken,
|
|
623
686
|
orgId: this.orgId,
|
|
624
687
|
orgName: this.orgName,
|
|
625
|
-
|
|
688
|
+
apiUrl: this.apiUrl,
|
|
626
689
|
proxyUrl: this.proxyUrl,
|
|
627
690
|
gitMetadataSettings: this.gitMetadataSettings
|
|
628
691
|
};
|
|
@@ -643,22 +706,23 @@ var BraintrustState = class _BraintrustState {
|
|
|
643
706
|
"Cannot deserialize BraintrustState without a login token"
|
|
644
707
|
);
|
|
645
708
|
}
|
|
646
|
-
state.logConn().set_token(state.loginToken);
|
|
647
|
-
state.logConn().make_long_lived();
|
|
648
709
|
state.apiConn().set_token(state.loginToken);
|
|
710
|
+
state.apiConn().make_long_lived();
|
|
711
|
+
state.appConn().set_token(state.loginToken);
|
|
712
|
+
state.proxyConn().make_long_lived();
|
|
649
713
|
state.proxyConn().set_token(state.loginToken);
|
|
650
714
|
state.loggedIn = true;
|
|
651
|
-
state.
|
|
715
|
+
state.loginReplaceApiConn(state.apiConn());
|
|
652
716
|
return state;
|
|
653
717
|
}
|
|
654
718
|
setFetch(fetch) {
|
|
655
719
|
this.loginParams.fetch = fetch;
|
|
656
720
|
this.fetch = fetch;
|
|
657
|
-
this._logConn?.setFetch(fetch);
|
|
658
721
|
this._apiConn?.setFetch(fetch);
|
|
722
|
+
this._appConn?.setFetch(fetch);
|
|
659
723
|
}
|
|
660
724
|
async login(loginParams) {
|
|
661
|
-
if (this.
|
|
725
|
+
if (this.apiUrl && !loginParams.forceLogin) {
|
|
662
726
|
return;
|
|
663
727
|
}
|
|
664
728
|
const newState = await loginToState({
|
|
@@ -667,23 +731,23 @@ var BraintrustState = class _BraintrustState {
|
|
|
667
731
|
});
|
|
668
732
|
this.copyLoginInfo(newState);
|
|
669
733
|
}
|
|
670
|
-
|
|
671
|
-
if (!this.
|
|
734
|
+
appConn() {
|
|
735
|
+
if (!this._appConn) {
|
|
672
736
|
if (!this.appUrl) {
|
|
673
|
-
throw new Error("Must initialize appUrl before requesting
|
|
737
|
+
throw new Error("Must initialize appUrl before requesting appConn");
|
|
674
738
|
}
|
|
675
|
-
this.
|
|
739
|
+
this._appConn = new HTTPConnection(this.appUrl, this.fetch);
|
|
676
740
|
}
|
|
677
|
-
return this.
|
|
741
|
+
return this._appConn;
|
|
678
742
|
}
|
|
679
|
-
|
|
680
|
-
if (!this.
|
|
681
|
-
if (!this.
|
|
682
|
-
throw new Error("Must initialize
|
|
743
|
+
apiConn() {
|
|
744
|
+
if (!this._apiConn) {
|
|
745
|
+
if (!this.apiUrl) {
|
|
746
|
+
throw new Error("Must initialize apiUrl before requesting apiConn");
|
|
683
747
|
}
|
|
684
|
-
this.
|
|
748
|
+
this._apiConn = new HTTPConnection(this.apiUrl, this.fetch);
|
|
685
749
|
}
|
|
686
|
-
return this.
|
|
750
|
+
return this._apiConn;
|
|
687
751
|
}
|
|
688
752
|
proxyConn() {
|
|
689
753
|
if (!this._proxyConn) {
|
|
@@ -698,8 +762,8 @@ var BraintrustState = class _BraintrustState {
|
|
|
698
762
|
return this._bgLogger;
|
|
699
763
|
}
|
|
700
764
|
// Should only be called by the login function.
|
|
701
|
-
|
|
702
|
-
this._bgLogger.
|
|
765
|
+
loginReplaceApiConn(apiConn) {
|
|
766
|
+
this._bgLogger.internalReplaceApiConn(apiConn);
|
|
703
767
|
}
|
|
704
768
|
};
|
|
705
769
|
var _globalState;
|
|
@@ -1006,11 +1070,6 @@ var Logger = class {
|
|
|
1006
1070
|
parentObjectType() {
|
|
1007
1071
|
return import_core.SpanObjectTypeV2.PROJECT_LOGS;
|
|
1008
1072
|
}
|
|
1009
|
-
triggerWaitUntilFlush() {
|
|
1010
|
-
if (!this.state.bgLogger().syncFlush) {
|
|
1011
|
-
return (0, import_functions.waitUntil)(this.state.bgLogger().flush());
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
1073
|
/**
|
|
1015
1074
|
* Log a single event. The event will be batched and uploaded behind the scenes if `logOptions.asyncFlush` is true.
|
|
1016
1075
|
*
|
|
@@ -1036,7 +1095,6 @@ var Logger = class {
|
|
|
1036
1095
|
this.lastStartTime = span.end();
|
|
1037
1096
|
const ret = span.id;
|
|
1038
1097
|
if (this.asyncFlush === true) {
|
|
1039
|
-
this.triggerWaitUntilFlush();
|
|
1040
1098
|
return ret;
|
|
1041
1099
|
} else {
|
|
1042
1100
|
return (async () => {
|
|
@@ -1064,7 +1122,6 @@ var Logger = class {
|
|
|
1064
1122
|
() => span.end()
|
|
1065
1123
|
);
|
|
1066
1124
|
if (this.asyncFlush) {
|
|
1067
|
-
this.triggerWaitUntilFlush();
|
|
1068
1125
|
return ret;
|
|
1069
1126
|
} else {
|
|
1070
1127
|
return (async () => {
|
|
@@ -1144,7 +1201,7 @@ var Logger = class {
|
|
|
1144
1201
|
function castLogger(logger, asyncFlush) {
|
|
1145
1202
|
if (logger === void 0)
|
|
1146
1203
|
return void 0;
|
|
1147
|
-
if (asyncFlush && !!asyncFlush !== !!logger.asyncFlush) {
|
|
1204
|
+
if (asyncFlush !== void 0 && !!asyncFlush !== !!logger.asyncFlush) {
|
|
1148
1205
|
throw new Error(
|
|
1149
1206
|
`Asserted asyncFlush setting ${asyncFlush} does not match stored logger's setting ${logger.asyncFlush}`
|
|
1150
1207
|
);
|
|
@@ -1158,7 +1215,7 @@ function now() {
|
|
|
1158
1215
|
return (/* @__PURE__ */ new Date()).getTime();
|
|
1159
1216
|
}
|
|
1160
1217
|
var BackgroundLogger = class _BackgroundLogger {
|
|
1161
|
-
|
|
1218
|
+
apiConn;
|
|
1162
1219
|
items = [];
|
|
1163
1220
|
activeFlush = Promise.resolve();
|
|
1164
1221
|
activeFlushResolved = true;
|
|
@@ -1176,8 +1233,8 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1176
1233
|
numDropped: 0,
|
|
1177
1234
|
lastLoggedTimestamp: 0
|
|
1178
1235
|
};
|
|
1179
|
-
constructor(
|
|
1180
|
-
this.
|
|
1236
|
+
constructor(apiConn) {
|
|
1237
|
+
this.apiConn = apiConn;
|
|
1181
1238
|
const syncFlushEnv = Number(isomorph_default.getEnv("BRAINTRUST_SYNC_FLUSH"));
|
|
1182
1239
|
if (!isNaN(syncFlushEnv)) {
|
|
1183
1240
|
this.syncFlush = Boolean(syncFlushEnv);
|
|
@@ -1323,7 +1380,7 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1323
1380
|
return [];
|
|
1324
1381
|
}
|
|
1325
1382
|
async submitLogsRequest(items) {
|
|
1326
|
-
const conn = await this.
|
|
1383
|
+
const conn = await this.apiConn.get();
|
|
1327
1384
|
const dataStr = constructLogs3Data(items);
|
|
1328
1385
|
if (this.allPublishPayloadsDir) {
|
|
1329
1386
|
await _BackgroundLogger.writePayloadToDir({
|
|
@@ -1461,14 +1518,15 @@ Error: ${errorText}`;
|
|
|
1461
1518
|
this.activeFlushResolved = true;
|
|
1462
1519
|
}
|
|
1463
1520
|
})();
|
|
1521
|
+
(0, import_functions.waitUntil)(this.activeFlush);
|
|
1464
1522
|
}
|
|
1465
1523
|
}
|
|
1466
1524
|
logFailedPayloadsDir() {
|
|
1467
1525
|
console.warn(`Logging failed payloads to ${this.failedPublishPayloadsDir}`);
|
|
1468
1526
|
}
|
|
1469
1527
|
// Should only be called by BraintrustState.
|
|
1470
|
-
|
|
1471
|
-
this.
|
|
1528
|
+
internalReplaceApiConn(apiConn) {
|
|
1529
|
+
this.apiConn = new LazyValue(async () => apiConn);
|
|
1472
1530
|
}
|
|
1473
1531
|
};
|
|
1474
1532
|
function init(projectOrOptions, optionalOptions) {
|
|
@@ -1522,7 +1580,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
1522
1580
|
org_name: state.orgName,
|
|
1523
1581
|
experiment_name: experiment
|
|
1524
1582
|
};
|
|
1525
|
-
const response = await state.
|
|
1583
|
+
const response = await state.appConn().post_json("api/experiment/get", args);
|
|
1526
1584
|
if (response.length === 0) {
|
|
1527
1585
|
throw new Error(
|
|
1528
1586
|
`Experiment ${experiment} not found in project ${projectId ?? project}.`
|
|
@@ -1603,7 +1661,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
1603
1661
|
let response = null;
|
|
1604
1662
|
while (true) {
|
|
1605
1663
|
try {
|
|
1606
|
-
response = await state.
|
|
1664
|
+
response = await state.appConn().post_json("api/experiment/register", args);
|
|
1607
1665
|
break;
|
|
1608
1666
|
} catch (e) {
|
|
1609
1667
|
if (args["base_experiment"] && `${"data" in e && e.data}`.includes("base experiment")) {
|
|
@@ -1709,7 +1767,7 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
1709
1767
|
dataset_name: dataset,
|
|
1710
1768
|
description
|
|
1711
1769
|
};
|
|
1712
|
-
const response = await state.
|
|
1770
|
+
const response = await state.appConn().post_json("api/dataset/register", args);
|
|
1713
1771
|
return {
|
|
1714
1772
|
project: {
|
|
1715
1773
|
id: response.project.id,
|
|
@@ -1739,7 +1797,7 @@ async function computeLoggerMetadata(state, {
|
|
|
1739
1797
|
}) {
|
|
1740
1798
|
const org_id = state.orgId;
|
|
1741
1799
|
if (isEmpty(project_id)) {
|
|
1742
|
-
const response = await state.
|
|
1800
|
+
const response = await state.appConn().post_json("api/project/register", {
|
|
1743
1801
|
project_name: project_name || GLOBAL_PROJECT,
|
|
1744
1802
|
org_id
|
|
1745
1803
|
});
|
|
@@ -1752,7 +1810,7 @@ async function computeLoggerMetadata(state, {
|
|
|
1752
1810
|
}
|
|
1753
1811
|
};
|
|
1754
1812
|
} else if (isEmpty(project_name)) {
|
|
1755
|
-
const response = await state.
|
|
1813
|
+
const response = await state.appConn().get_json("api/project", {
|
|
1756
1814
|
id: project_id
|
|
1757
1815
|
});
|
|
1758
1816
|
return {
|
|
@@ -1842,7 +1900,7 @@ async function loadPrompt({
|
|
|
1842
1900
|
slug,
|
|
1843
1901
|
version
|
|
1844
1902
|
};
|
|
1845
|
-
const response = await state.
|
|
1903
|
+
const response = await state.apiConn().get_json("v1/prompt", args);
|
|
1846
1904
|
if (!("objects" in response) || response.objects.length === 0) {
|
|
1847
1905
|
throw new Error(
|
|
1848
1906
|
`Prompt ${slug} not found in ${[projectName ?? projectId]}`
|
|
@@ -1904,7 +1962,7 @@ async function loginToState(options = {}) {
|
|
|
1904
1962
|
);
|
|
1905
1963
|
const info = await resp.json();
|
|
1906
1964
|
_check_org_info(state, info.org_info, orgName);
|
|
1907
|
-
conn = state.
|
|
1965
|
+
conn = state.apiConn();
|
|
1908
1966
|
conn.set_token(apiKey);
|
|
1909
1967
|
} else {
|
|
1910
1968
|
throw new Error(
|
|
@@ -1915,11 +1973,11 @@ async function loginToState(options = {}) {
|
|
|
1915
1973
|
throw new Error("Conn should be set at this point (a bug)");
|
|
1916
1974
|
}
|
|
1917
1975
|
conn.make_long_lived();
|
|
1918
|
-
state.
|
|
1976
|
+
state.appConn().set_token(apiKey);
|
|
1919
1977
|
state.proxyConn().set_token(apiKey);
|
|
1920
1978
|
state.loginToken = conn.token;
|
|
1921
1979
|
state.loggedIn = true;
|
|
1922
|
-
state.
|
|
1980
|
+
state.loginReplaceApiConn(conn);
|
|
1923
1981
|
return state;
|
|
1924
1982
|
}
|
|
1925
1983
|
function log(event) {
|
|
@@ -1971,7 +2029,7 @@ function getSpanParentObject(options) {
|
|
|
1971
2029
|
return NOOP_SPAN;
|
|
1972
2030
|
}
|
|
1973
2031
|
function traced(callback, args) {
|
|
1974
|
-
const { span,
|
|
2032
|
+
const { span, isSyncFlushLogger } = startSpanAndIsLogger(args);
|
|
1975
2033
|
const ret = runFinally(
|
|
1976
2034
|
() => {
|
|
1977
2035
|
if (args?.setCurrent ?? true) {
|
|
@@ -1987,7 +2045,7 @@ function traced(callback, args) {
|
|
|
1987
2045
|
} else {
|
|
1988
2046
|
return (async () => {
|
|
1989
2047
|
const awaitedRet = await ret;
|
|
1990
|
-
if (
|
|
2048
|
+
if (isSyncFlushLogger) {
|
|
1991
2049
|
await span.flush();
|
|
1992
2050
|
}
|
|
1993
2051
|
return awaitedRet;
|
|
@@ -2066,14 +2124,19 @@ function startSpanAndIsLogger(args) {
|
|
|
2066
2124
|
});
|
|
2067
2125
|
return {
|
|
2068
2126
|
span,
|
|
2069
|
-
|
|
2127
|
+
isSyncFlushLogger: components.objectType === import_core.SpanObjectTypeV2.PROJECT_LOGS && // Since there's no parent logger here, we're free to choose the async flush
|
|
2128
|
+
// behavior, and therefore propagate along whatever we get from the arguments
|
|
2129
|
+
!args?.asyncFlush
|
|
2070
2130
|
};
|
|
2071
2131
|
} else {
|
|
2072
2132
|
const parentObject = getSpanParentObject({
|
|
2073
2133
|
asyncFlush: args?.asyncFlush
|
|
2074
2134
|
});
|
|
2075
2135
|
const span = parentObject.startSpan(args);
|
|
2076
|
-
return {
|
|
2136
|
+
return {
|
|
2137
|
+
span,
|
|
2138
|
+
isSyncFlushLogger: parentObject.kind === "logger" && !parentObject.asyncFlush
|
|
2139
|
+
};
|
|
2077
2140
|
}
|
|
2078
2141
|
}
|
|
2079
2142
|
function withCurrent(span, callback, state = _globalState) {
|
|
@@ -2087,13 +2150,8 @@ function _check_org_info(state, org_info, org_name) {
|
|
|
2087
2150
|
if (org_name === void 0 || org.name === org_name) {
|
|
2088
2151
|
state.orgId = org.id;
|
|
2089
2152
|
state.orgName = org.name;
|
|
2090
|
-
state.
|
|
2153
|
+
state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
|
|
2091
2154
|
state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
|
|
2092
|
-
if (state.proxyUrl) {
|
|
2093
|
-
const url = new URL(state.proxyUrl);
|
|
2094
|
-
url.pathname = "";
|
|
2095
|
-
state.proxyUrl = url.toString();
|
|
2096
|
-
}
|
|
2097
2155
|
state.gitMetadataSettings = org.git_metadata || void 0;
|
|
2098
2156
|
break;
|
|
2099
2157
|
}
|
|
@@ -2104,11 +2162,6 @@ function _check_org_info(state, org_info, org_name) {
|
|
|
2104
2162
|
);
|
|
2105
2163
|
}
|
|
2106
2164
|
}
|
|
2107
|
-
function _urljoin(...parts) {
|
|
2108
|
-
return parts.map(
|
|
2109
|
-
(x, i) => x.replace(/^\//, "").replace(i < parts.length - 1 ? /\/$/ : "", "")
|
|
2110
|
-
).join("/");
|
|
2111
|
-
}
|
|
2112
2165
|
function validateTags(tags) {
|
|
2113
2166
|
const seen = /* @__PURE__ */ new Set();
|
|
2114
2167
|
for (const tag of tags) {
|
|
@@ -2222,7 +2275,7 @@ var ObjectFetcher = class {
|
|
|
2222
2275
|
async fetchedData() {
|
|
2223
2276
|
if (this._fetchedData === void 0) {
|
|
2224
2277
|
const state = await this.getState();
|
|
2225
|
-
const resp = await state.
|
|
2278
|
+
const resp = await state.apiConn().get(
|
|
2226
2279
|
`v1/${this.objectType}/${await this.id}/fetch`,
|
|
2227
2280
|
{
|
|
2228
2281
|
version: this.pinnedVersion
|
|
@@ -2368,7 +2421,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2368
2421
|
}
|
|
2369
2422
|
async fetchBaseExperiment() {
|
|
2370
2423
|
const state = await this.getState();
|
|
2371
|
-
const conn = state.
|
|
2424
|
+
const conn = state.appConn();
|
|
2372
2425
|
try {
|
|
2373
2426
|
const resp = await conn.post("/api/base_experiment/get_id", {
|
|
2374
2427
|
id: await this.id
|
|
@@ -2415,7 +2468,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2415
2468
|
comparisonExperimentName = baseExperiment.name;
|
|
2416
2469
|
}
|
|
2417
2470
|
}
|
|
2418
|
-
const results = await state.
|
|
2471
|
+
const results = await state.apiConn().get_json(
|
|
2419
2472
|
"/experiment-comparison2",
|
|
2420
2473
|
{
|
|
2421
2474
|
experiment_id: await this.id,
|
|
@@ -2603,29 +2656,10 @@ var SpanImpl = class _SpanImpl {
|
|
|
2603
2656
|
event,
|
|
2604
2657
|
internalData
|
|
2605
2658
|
}) {
|
|
2606
|
-
const
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
const lazyInternalData = {};
|
|
2611
|
-
for (const [key, value] of Object.entries(sanitizedAndInternalData)) {
|
|
2612
|
-
if (value instanceof BraintrustStream) {
|
|
2613
|
-
const streamCopy = value.copy();
|
|
2614
|
-
lazyInternalData[key] = new LazyValue(async () => {
|
|
2615
|
-
return await new Promise((resolve) => {
|
|
2616
|
-
streamCopy.toReadableStream().pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2617
|
-
});
|
|
2618
|
-
});
|
|
2619
|
-
} else if (value instanceof ReadableStream) {
|
|
2620
|
-
lazyInternalData[key] = new LazyValue(async () => {
|
|
2621
|
-
return await new Promise((resolve) => {
|
|
2622
|
-
value.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2623
|
-
});
|
|
2624
|
-
});
|
|
2625
|
-
} else {
|
|
2626
|
-
serializableInternalData[key] = value;
|
|
2627
|
-
}
|
|
2628
|
-
}
|
|
2659
|
+
const [serializableInternalData, lazyInternalData] = splitLoggingData({
|
|
2660
|
+
event,
|
|
2661
|
+
internalData
|
|
2662
|
+
});
|
|
2629
2663
|
let partialRecord = {
|
|
2630
2664
|
id: this.id,
|
|
2631
2665
|
span_id: this.spanId,
|
|
@@ -2743,6 +2777,36 @@ var SpanImpl = class _SpanImpl {
|
|
|
2743
2777
|
return this.end(args);
|
|
2744
2778
|
}
|
|
2745
2779
|
};
|
|
2780
|
+
function splitLoggingData({
|
|
2781
|
+
event,
|
|
2782
|
+
internalData
|
|
2783
|
+
}) {
|
|
2784
|
+
const sanitized = validateAndSanitizeExperimentLogPartialArgs(event ?? {});
|
|
2785
|
+
const sanitizedAndInternalData = {};
|
|
2786
|
+
(0, import_core.mergeDicts)(sanitizedAndInternalData, internalData || {});
|
|
2787
|
+
(0, import_core.mergeDicts)(sanitizedAndInternalData, sanitized);
|
|
2788
|
+
const serializableInternalData = {};
|
|
2789
|
+
const lazyInternalData = {};
|
|
2790
|
+
for (const [key, value] of Object.entries(sanitizedAndInternalData)) {
|
|
2791
|
+
if (value instanceof BraintrustStream) {
|
|
2792
|
+
const streamCopy = value.copy();
|
|
2793
|
+
lazyInternalData[key] = new LazyValue(async () => {
|
|
2794
|
+
return await new Promise((resolve) => {
|
|
2795
|
+
streamCopy.toReadableStream().pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2796
|
+
});
|
|
2797
|
+
});
|
|
2798
|
+
} else if (value instanceof ReadableStream) {
|
|
2799
|
+
lazyInternalData[key] = new LazyValue(async () => {
|
|
2800
|
+
return await new Promise((resolve) => {
|
|
2801
|
+
value.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2802
|
+
});
|
|
2803
|
+
});
|
|
2804
|
+
} else {
|
|
2805
|
+
serializableInternalData[key] = value;
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
return [serializableInternalData, lazyInternalData];
|
|
2809
|
+
}
|
|
2746
2810
|
var Dataset = class extends ObjectFetcher {
|
|
2747
2811
|
constructor(state, lazyMetadata, pinnedVersion, legacy) {
|
|
2748
2812
|
const isLegacyDataset = legacy ?? import_core.DEFAULT_IS_LEGACY_DATASET;
|
|
@@ -2859,7 +2923,7 @@ var Dataset = class extends ObjectFetcher {
|
|
|
2859
2923
|
)}`;
|
|
2860
2924
|
let dataSummary = void 0;
|
|
2861
2925
|
if (summarizeData) {
|
|
2862
|
-
dataSummary = await state.
|
|
2926
|
+
dataSummary = await state.apiConn().get_json(
|
|
2863
2927
|
"dataset-summary",
|
|
2864
2928
|
{
|
|
2865
2929
|
dataset_id: await this.id
|
|
@@ -2965,7 +3029,7 @@ var Prompt = class {
|
|
|
2965
3029
|
if (!prompt) {
|
|
2966
3030
|
throw new Error("Empty prompt");
|
|
2967
3031
|
}
|
|
2968
|
-
const dictArgParsed =
|
|
3032
|
+
const dictArgParsed = import_zod2.z.record(import_zod2.z.unknown()).safeParse(buildArgs);
|
|
2969
3033
|
const variables = {
|
|
2970
3034
|
input: buildArgs,
|
|
2971
3035
|
...dictArgParsed.success ? dictArgParsed.data : {}
|
|
@@ -3036,12 +3100,12 @@ async function invoke(args) {
|
|
|
3036
3100
|
appUrl,
|
|
3037
3101
|
forceLogin,
|
|
3038
3102
|
fetch,
|
|
3039
|
-
|
|
3103
|
+
input,
|
|
3040
3104
|
parent: parentArg,
|
|
3041
3105
|
state: stateArg,
|
|
3042
3106
|
stream,
|
|
3043
3107
|
schema,
|
|
3044
|
-
...
|
|
3108
|
+
...functionIdArgs
|
|
3045
3109
|
} = args;
|
|
3046
3110
|
const state = stateArg ?? _internalGetGlobalState();
|
|
3047
3111
|
await state.login({
|
|
@@ -3050,10 +3114,16 @@ async function invoke(args) {
|
|
|
3050
3114
|
appUrl,
|
|
3051
3115
|
forceLogin
|
|
3052
3116
|
});
|
|
3053
|
-
const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await
|
|
3117
|
+
const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await getSpanParentObject().export();
|
|
3118
|
+
const functionId = import_typespecs3.functionIdSchema.safeParse(functionIdArgs);
|
|
3119
|
+
if (!functionId.success) {
|
|
3120
|
+
throw new Error(
|
|
3121
|
+
`Invalid function ID arguments: ${functionId.error.message}`
|
|
3122
|
+
);
|
|
3123
|
+
}
|
|
3054
3124
|
const request = {
|
|
3055
|
-
...functionId,
|
|
3056
|
-
|
|
3125
|
+
...functionId.data,
|
|
3126
|
+
input,
|
|
3057
3127
|
parent,
|
|
3058
3128
|
stream,
|
|
3059
3129
|
api_version: import_typespecs3.INVOKE_API_VERSION
|
|
@@ -3118,7 +3188,7 @@ var BarProgressReporter = class {
|
|
|
3118
3188
|
// src/framework.ts
|
|
3119
3189
|
var import_pluralize = __toESM(require("pluralize"));
|
|
3120
3190
|
|
|
3121
|
-
//
|
|
3191
|
+
// ../../node_modules/.pnpm/async@3.2.5/node_modules/async/dist/async.mjs
|
|
3122
3192
|
function initialParams(fn) {
|
|
3123
3193
|
return function(...args) {
|
|
3124
3194
|
var callback = args.pop();
|
|
@@ -5234,6 +5304,7 @@ configureNode();
|
|
|
5234
5304
|
X_CACHED_HEADER,
|
|
5235
5305
|
_internalGetGlobalState,
|
|
5236
5306
|
_internalSetInitialState,
|
|
5307
|
+
braintrustStreamChunkSchema,
|
|
5237
5308
|
buildLocalSummary,
|
|
5238
5309
|
createFinalValuePassThroughStream,
|
|
5239
5310
|
currentExperiment,
|