braintrust 0.0.141-dev → 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/browser.js
CHANGED
|
@@ -44,6 +44,7 @@ __export(browser_exports, {
|
|
|
44
44
|
X_CACHED_HEADER: () => X_CACHED_HEADER,
|
|
45
45
|
_internalGetGlobalState: () => _internalGetGlobalState,
|
|
46
46
|
_internalSetInitialState: () => _internalSetInitialState,
|
|
47
|
+
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
47
48
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
48
49
|
currentExperiment: () => currentExperiment,
|
|
49
50
|
currentLogger: () => currentLogger,
|
|
@@ -148,27 +149,79 @@ var LazyValue = class {
|
|
|
148
149
|
return this.value.hasComputed;
|
|
149
150
|
}
|
|
150
151
|
};
|
|
152
|
+
function _urljoin(...parts) {
|
|
153
|
+
return parts.map(
|
|
154
|
+
(x, i) => x.replace(/^\//, "").replace(i < parts.length - 1 ? /\/$/ : "", "")
|
|
155
|
+
).filter((x) => x.trim() !== "").join("/");
|
|
156
|
+
}
|
|
151
157
|
|
|
152
158
|
// src/logger.ts
|
|
153
159
|
var import_mustache = __toESM(require("mustache"));
|
|
154
|
-
var
|
|
160
|
+
var import_zod2 = require("zod");
|
|
155
161
|
|
|
156
|
-
// src/stream.ts
|
|
162
|
+
// src/functions/stream.ts
|
|
157
163
|
var import_typespecs = require("@braintrust/core/typespecs");
|
|
158
164
|
var import_eventsource_parser = require("eventsource-parser");
|
|
165
|
+
var import_zod = require("zod");
|
|
166
|
+
var braintrustStreamChunkSchema = import_zod.z.union([
|
|
167
|
+
import_zod.z.object({
|
|
168
|
+
type: import_zod.z.literal("text_delta"),
|
|
169
|
+
data: import_zod.z.string()
|
|
170
|
+
}),
|
|
171
|
+
import_zod.z.object({
|
|
172
|
+
type: import_zod.z.literal("json_delta"),
|
|
173
|
+
data: import_zod.z.string()
|
|
174
|
+
})
|
|
175
|
+
]);
|
|
159
176
|
var BraintrustStream = class _BraintrustStream {
|
|
160
177
|
stream;
|
|
178
|
+
memoizedFinalValue;
|
|
161
179
|
constructor(baseStream) {
|
|
162
180
|
this.stream = baseStream.pipeThrough(btStreamParser());
|
|
163
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Copy the stream. This returns a new stream that shares the same underlying
|
|
184
|
+
* stream (via `tee`). Since streams are consumed in Javascript, use `copy()` if you
|
|
185
|
+
* need to use the stream multiple times.
|
|
186
|
+
*
|
|
187
|
+
* @returns A new stream that you can independently consume.
|
|
188
|
+
*/
|
|
164
189
|
copy() {
|
|
165
190
|
const [newStream, copyStream] = this.stream.tee();
|
|
166
191
|
this.stream = copyStream;
|
|
167
192
|
return new _BraintrustStream(newStream);
|
|
168
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Get the underlying ReadableStream.
|
|
196
|
+
*
|
|
197
|
+
* @returns The underlying ReadableStream<BraintrustStreamChunk>.
|
|
198
|
+
*/
|
|
169
199
|
toReadableStream() {
|
|
170
200
|
return this.stream;
|
|
171
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Get the final value of the stream. The final value is the concatenation of all
|
|
204
|
+
* the chunks in the stream, deserialized into a string or JSON object, depending on
|
|
205
|
+
* the value's type.
|
|
206
|
+
*
|
|
207
|
+
* This function returns a promise that resolves when the stream is closed, and
|
|
208
|
+
* contains the final value. Multiple calls to `finalValue()` will return the same
|
|
209
|
+
* promise, so it is safe to call this multiple times.
|
|
210
|
+
*
|
|
211
|
+
* This function consumes the stream, so if you need to use the stream multiple
|
|
212
|
+
* times, you should call `copy()` first.
|
|
213
|
+
*
|
|
214
|
+
* @returns A promise that resolves with the final value of the stream or `undefined` if the stream is empty.
|
|
215
|
+
*/
|
|
216
|
+
finalValue() {
|
|
217
|
+
if (this.memoizedFinalValue) {
|
|
218
|
+
return this.memoizedFinalValue;
|
|
219
|
+
}
|
|
220
|
+
this.memoizedFinalValue = new Promise((resolve, reject) => {
|
|
221
|
+
const stream = this.stream.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
222
|
+
});
|
|
223
|
+
return this.memoizedFinalValue;
|
|
224
|
+
}
|
|
172
225
|
};
|
|
173
226
|
function btStreamParser() {
|
|
174
227
|
const decoder = new TextDecoder();
|
|
@@ -223,9 +276,17 @@ function createFinalValuePassThroughStream(onFinal) {
|
|
|
223
276
|
transform(chunk, controller) {
|
|
224
277
|
if (typeof chunk === "string") {
|
|
225
278
|
textChunks.push(chunk);
|
|
279
|
+
controller.enqueue({
|
|
280
|
+
type: "text_delta",
|
|
281
|
+
data: chunk
|
|
282
|
+
});
|
|
226
283
|
} else if (chunk instanceof Uint8Array) {
|
|
227
284
|
textChunks.push(decoder.decode(chunk));
|
|
228
|
-
|
|
285
|
+
controller.enqueue({
|
|
286
|
+
type: "text_delta",
|
|
287
|
+
data: decoder.decode(chunk)
|
|
288
|
+
});
|
|
289
|
+
} else if (braintrustStreamChunkSchema.safeParse(chunk).success) {
|
|
229
290
|
const chunkType = chunk.type;
|
|
230
291
|
switch (chunkType) {
|
|
231
292
|
case "text_delta":
|
|
@@ -239,6 +300,8 @@ function createFinalValuePassThroughStream(onFinal) {
|
|
|
239
300
|
throw new Error(`Unknown chunk type ${_type}`);
|
|
240
301
|
}
|
|
241
302
|
controller.enqueue(chunk);
|
|
303
|
+
} else {
|
|
304
|
+
throw new Error(`Unknown chunk type ${chunk}`);
|
|
242
305
|
}
|
|
243
306
|
},
|
|
244
307
|
flush(controller) {
|
|
@@ -300,14 +363,14 @@ var NoopSpan = class {
|
|
|
300
363
|
}
|
|
301
364
|
};
|
|
302
365
|
var NOOP_SPAN = new NoopSpan();
|
|
303
|
-
var loginSchema =
|
|
304
|
-
appUrl:
|
|
305
|
-
appPublicUrl:
|
|
306
|
-
orgName:
|
|
307
|
-
|
|
308
|
-
proxyUrl:
|
|
309
|
-
loginToken:
|
|
310
|
-
orgId:
|
|
366
|
+
var loginSchema = import_zod2.z.strictObject({
|
|
367
|
+
appUrl: import_zod2.z.string(),
|
|
368
|
+
appPublicUrl: import_zod2.z.string(),
|
|
369
|
+
orgName: import_zod2.z.string(),
|
|
370
|
+
apiUrl: import_zod2.z.string(),
|
|
371
|
+
proxyUrl: import_zod2.z.string(),
|
|
372
|
+
loginToken: import_zod2.z.string(),
|
|
373
|
+
orgId: import_zod2.z.string().nullish(),
|
|
311
374
|
gitMetadataSettings: import_core.gitMetadataSettingsSchema.nullish()
|
|
312
375
|
});
|
|
313
376
|
var BraintrustState = class _BraintrustState {
|
|
@@ -322,7 +385,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
322
385
|
}
|
|
323
386
|
const defaultGetLogConn = async () => {
|
|
324
387
|
await this.login({});
|
|
325
|
-
return this.
|
|
388
|
+
return this.apiConn();
|
|
326
389
|
};
|
|
327
390
|
this._bgLogger = new BackgroundLogger(new LazyValue(defaultGetLogConn));
|
|
328
391
|
this.resetLoginInfo();
|
|
@@ -333,7 +396,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
333
396
|
// (safely) dynamically cast it whenever retrieving the logger.
|
|
334
397
|
currentLogger;
|
|
335
398
|
currentSpan;
|
|
336
|
-
// Any time we re-log in, we directly update the
|
|
399
|
+
// Any time we re-log in, we directly update the apiConn inside the logger.
|
|
337
400
|
// This is preferable to replacing the whole logger, which would create the
|
|
338
401
|
// possibility of multiple loggers floating around, which may not log in a
|
|
339
402
|
// deterministic order.
|
|
@@ -343,13 +406,13 @@ var BraintrustState = class _BraintrustState {
|
|
|
343
406
|
loginToken = null;
|
|
344
407
|
orgId = null;
|
|
345
408
|
orgName = null;
|
|
346
|
-
|
|
409
|
+
apiUrl = null;
|
|
347
410
|
proxyUrl = null;
|
|
348
411
|
loggedIn = false;
|
|
349
412
|
gitMetadataSettings;
|
|
350
413
|
fetch = globalThis.fetch;
|
|
414
|
+
_appConn = null;
|
|
351
415
|
_apiConn = null;
|
|
352
|
-
_logConn = null;
|
|
353
416
|
_proxyConn = null;
|
|
354
417
|
resetLoginInfo() {
|
|
355
418
|
this.appUrl = null;
|
|
@@ -357,12 +420,12 @@ var BraintrustState = class _BraintrustState {
|
|
|
357
420
|
this.loginToken = null;
|
|
358
421
|
this.orgId = null;
|
|
359
422
|
this.orgName = null;
|
|
360
|
-
this.
|
|
423
|
+
this.apiUrl = null;
|
|
361
424
|
this.proxyUrl = null;
|
|
362
425
|
this.loggedIn = false;
|
|
363
426
|
this.gitMetadataSettings = void 0;
|
|
427
|
+
this._appConn = null;
|
|
364
428
|
this._apiConn = null;
|
|
365
|
-
this._logConn = null;
|
|
366
429
|
this._proxyConn = null;
|
|
367
430
|
}
|
|
368
431
|
copyLoginInfo(other) {
|
|
@@ -371,12 +434,12 @@ var BraintrustState = class _BraintrustState {
|
|
|
371
434
|
this.loginToken = other.loginToken;
|
|
372
435
|
this.orgId = other.orgId;
|
|
373
436
|
this.orgName = other.orgName;
|
|
374
|
-
this.
|
|
437
|
+
this.apiUrl = other.apiUrl;
|
|
375
438
|
this.proxyUrl = other.proxyUrl;
|
|
376
439
|
this.loggedIn = other.loggedIn;
|
|
377
440
|
this.gitMetadataSettings = other.gitMetadataSettings;
|
|
441
|
+
this._appConn = other._appConn;
|
|
378
442
|
this._apiConn = other._apiConn;
|
|
379
|
-
this._logConn = other._logConn;
|
|
380
443
|
this._proxyConn = other._proxyConn;
|
|
381
444
|
}
|
|
382
445
|
serialize() {
|
|
@@ -385,7 +448,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
385
448
|
"Cannot serialize BraintrustState without being logged in"
|
|
386
449
|
);
|
|
387
450
|
}
|
|
388
|
-
if (!this.appUrl || !this.appPublicUrl || !this.
|
|
451
|
+
if (!this.appUrl || !this.appPublicUrl || !this.apiUrl || !this.proxyUrl || !this.orgName || !this.loginToken || !this.loggedIn) {
|
|
389
452
|
throw new Error(
|
|
390
453
|
"Cannot serialize BraintrustState without all login attributes"
|
|
391
454
|
);
|
|
@@ -396,7 +459,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
396
459
|
loginToken: this.loginToken,
|
|
397
460
|
orgId: this.orgId,
|
|
398
461
|
orgName: this.orgName,
|
|
399
|
-
|
|
462
|
+
apiUrl: this.apiUrl,
|
|
400
463
|
proxyUrl: this.proxyUrl,
|
|
401
464
|
gitMetadataSettings: this.gitMetadataSettings
|
|
402
465
|
};
|
|
@@ -417,22 +480,23 @@ var BraintrustState = class _BraintrustState {
|
|
|
417
480
|
"Cannot deserialize BraintrustState without a login token"
|
|
418
481
|
);
|
|
419
482
|
}
|
|
420
|
-
state.logConn().set_token(state.loginToken);
|
|
421
|
-
state.logConn().make_long_lived();
|
|
422
483
|
state.apiConn().set_token(state.loginToken);
|
|
484
|
+
state.apiConn().make_long_lived();
|
|
485
|
+
state.appConn().set_token(state.loginToken);
|
|
486
|
+
state.proxyConn().make_long_lived();
|
|
423
487
|
state.proxyConn().set_token(state.loginToken);
|
|
424
488
|
state.loggedIn = true;
|
|
425
|
-
state.
|
|
489
|
+
state.loginReplaceApiConn(state.apiConn());
|
|
426
490
|
return state;
|
|
427
491
|
}
|
|
428
492
|
setFetch(fetch) {
|
|
429
493
|
this.loginParams.fetch = fetch;
|
|
430
494
|
this.fetch = fetch;
|
|
431
|
-
this._logConn?.setFetch(fetch);
|
|
432
495
|
this._apiConn?.setFetch(fetch);
|
|
496
|
+
this._appConn?.setFetch(fetch);
|
|
433
497
|
}
|
|
434
498
|
async login(loginParams) {
|
|
435
|
-
if (this.
|
|
499
|
+
if (this.apiUrl && !loginParams.forceLogin) {
|
|
436
500
|
return;
|
|
437
501
|
}
|
|
438
502
|
const newState = await loginToState({
|
|
@@ -441,23 +505,23 @@ var BraintrustState = class _BraintrustState {
|
|
|
441
505
|
});
|
|
442
506
|
this.copyLoginInfo(newState);
|
|
443
507
|
}
|
|
444
|
-
|
|
445
|
-
if (!this.
|
|
508
|
+
appConn() {
|
|
509
|
+
if (!this._appConn) {
|
|
446
510
|
if (!this.appUrl) {
|
|
447
|
-
throw new Error("Must initialize appUrl before requesting
|
|
511
|
+
throw new Error("Must initialize appUrl before requesting appConn");
|
|
448
512
|
}
|
|
449
|
-
this.
|
|
513
|
+
this._appConn = new HTTPConnection(this.appUrl, this.fetch);
|
|
450
514
|
}
|
|
451
|
-
return this.
|
|
515
|
+
return this._appConn;
|
|
452
516
|
}
|
|
453
|
-
|
|
454
|
-
if (!this.
|
|
455
|
-
if (!this.
|
|
456
|
-
throw new Error("Must initialize
|
|
517
|
+
apiConn() {
|
|
518
|
+
if (!this._apiConn) {
|
|
519
|
+
if (!this.apiUrl) {
|
|
520
|
+
throw new Error("Must initialize apiUrl before requesting apiConn");
|
|
457
521
|
}
|
|
458
|
-
this.
|
|
522
|
+
this._apiConn = new HTTPConnection(this.apiUrl, this.fetch);
|
|
459
523
|
}
|
|
460
|
-
return this.
|
|
524
|
+
return this._apiConn;
|
|
461
525
|
}
|
|
462
526
|
proxyConn() {
|
|
463
527
|
if (!this._proxyConn) {
|
|
@@ -472,8 +536,8 @@ var BraintrustState = class _BraintrustState {
|
|
|
472
536
|
return this._bgLogger;
|
|
473
537
|
}
|
|
474
538
|
// Should only be called by the login function.
|
|
475
|
-
|
|
476
|
-
this._bgLogger.
|
|
539
|
+
loginReplaceApiConn(apiConn) {
|
|
540
|
+
this._bgLogger.internalReplaceApiConn(apiConn);
|
|
477
541
|
}
|
|
478
542
|
};
|
|
479
543
|
var _globalState;
|
|
@@ -780,11 +844,6 @@ var Logger = class {
|
|
|
780
844
|
parentObjectType() {
|
|
781
845
|
return import_core.SpanObjectTypeV2.PROJECT_LOGS;
|
|
782
846
|
}
|
|
783
|
-
triggerWaitUntilFlush() {
|
|
784
|
-
if (!this.state.bgLogger().syncFlush) {
|
|
785
|
-
return (0, import_functions.waitUntil)(this.state.bgLogger().flush());
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
847
|
/**
|
|
789
848
|
* Log a single event. The event will be batched and uploaded behind the scenes if `logOptions.asyncFlush` is true.
|
|
790
849
|
*
|
|
@@ -810,7 +869,6 @@ var Logger = class {
|
|
|
810
869
|
this.lastStartTime = span.end();
|
|
811
870
|
const ret = span.id;
|
|
812
871
|
if (this.asyncFlush === true) {
|
|
813
|
-
this.triggerWaitUntilFlush();
|
|
814
872
|
return ret;
|
|
815
873
|
} else {
|
|
816
874
|
return (async () => {
|
|
@@ -838,7 +896,6 @@ var Logger = class {
|
|
|
838
896
|
() => span.end()
|
|
839
897
|
);
|
|
840
898
|
if (this.asyncFlush) {
|
|
841
|
-
this.triggerWaitUntilFlush();
|
|
842
899
|
return ret;
|
|
843
900
|
} else {
|
|
844
901
|
return (async () => {
|
|
@@ -918,7 +975,7 @@ var Logger = class {
|
|
|
918
975
|
function castLogger(logger, asyncFlush) {
|
|
919
976
|
if (logger === void 0)
|
|
920
977
|
return void 0;
|
|
921
|
-
if (asyncFlush && !!asyncFlush !== !!logger.asyncFlush) {
|
|
978
|
+
if (asyncFlush !== void 0 && !!asyncFlush !== !!logger.asyncFlush) {
|
|
922
979
|
throw new Error(
|
|
923
980
|
`Asserted asyncFlush setting ${asyncFlush} does not match stored logger's setting ${logger.asyncFlush}`
|
|
924
981
|
);
|
|
@@ -932,7 +989,7 @@ function now() {
|
|
|
932
989
|
return (/* @__PURE__ */ new Date()).getTime();
|
|
933
990
|
}
|
|
934
991
|
var BackgroundLogger = class _BackgroundLogger {
|
|
935
|
-
|
|
992
|
+
apiConn;
|
|
936
993
|
items = [];
|
|
937
994
|
activeFlush = Promise.resolve();
|
|
938
995
|
activeFlushResolved = true;
|
|
@@ -950,8 +1007,8 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
950
1007
|
numDropped: 0,
|
|
951
1008
|
lastLoggedTimestamp: 0
|
|
952
1009
|
};
|
|
953
|
-
constructor(
|
|
954
|
-
this.
|
|
1010
|
+
constructor(apiConn) {
|
|
1011
|
+
this.apiConn = apiConn;
|
|
955
1012
|
const syncFlushEnv = Number(isomorph_default.getEnv("BRAINTRUST_SYNC_FLUSH"));
|
|
956
1013
|
if (!isNaN(syncFlushEnv)) {
|
|
957
1014
|
this.syncFlush = Boolean(syncFlushEnv);
|
|
@@ -1097,7 +1154,7 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1097
1154
|
return [];
|
|
1098
1155
|
}
|
|
1099
1156
|
async submitLogsRequest(items) {
|
|
1100
|
-
const conn = await this.
|
|
1157
|
+
const conn = await this.apiConn.get();
|
|
1101
1158
|
const dataStr = constructLogs3Data(items);
|
|
1102
1159
|
if (this.allPublishPayloadsDir) {
|
|
1103
1160
|
await _BackgroundLogger.writePayloadToDir({
|
|
@@ -1235,14 +1292,15 @@ Error: ${errorText}`;
|
|
|
1235
1292
|
this.activeFlushResolved = true;
|
|
1236
1293
|
}
|
|
1237
1294
|
})();
|
|
1295
|
+
(0, import_functions.waitUntil)(this.activeFlush);
|
|
1238
1296
|
}
|
|
1239
1297
|
}
|
|
1240
1298
|
logFailedPayloadsDir() {
|
|
1241
1299
|
console.warn(`Logging failed payloads to ${this.failedPublishPayloadsDir}`);
|
|
1242
1300
|
}
|
|
1243
1301
|
// Should only be called by BraintrustState.
|
|
1244
|
-
|
|
1245
|
-
this.
|
|
1302
|
+
internalReplaceApiConn(apiConn) {
|
|
1303
|
+
this.apiConn = new LazyValue(async () => apiConn);
|
|
1246
1304
|
}
|
|
1247
1305
|
};
|
|
1248
1306
|
function init(projectOrOptions, optionalOptions) {
|
|
@@ -1296,7 +1354,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
1296
1354
|
org_name: state.orgName,
|
|
1297
1355
|
experiment_name: experiment
|
|
1298
1356
|
};
|
|
1299
|
-
const response = await state.
|
|
1357
|
+
const response = await state.appConn().post_json("api/experiment/get", args);
|
|
1300
1358
|
if (response.length === 0) {
|
|
1301
1359
|
throw new Error(
|
|
1302
1360
|
`Experiment ${experiment} not found in project ${projectId ?? project}.`
|
|
@@ -1377,7 +1435,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
1377
1435
|
let response = null;
|
|
1378
1436
|
while (true) {
|
|
1379
1437
|
try {
|
|
1380
|
-
response = await state.
|
|
1438
|
+
response = await state.appConn().post_json("api/experiment/register", args);
|
|
1381
1439
|
break;
|
|
1382
1440
|
} catch (e) {
|
|
1383
1441
|
if (args["base_experiment"] && `${"data" in e && e.data}`.includes("base experiment")) {
|
|
@@ -1483,7 +1541,7 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
1483
1541
|
dataset_name: dataset,
|
|
1484
1542
|
description
|
|
1485
1543
|
};
|
|
1486
|
-
const response = await state.
|
|
1544
|
+
const response = await state.appConn().post_json("api/dataset/register", args);
|
|
1487
1545
|
return {
|
|
1488
1546
|
project: {
|
|
1489
1547
|
id: response.project.id,
|
|
@@ -1513,7 +1571,7 @@ async function computeLoggerMetadata(state, {
|
|
|
1513
1571
|
}) {
|
|
1514
1572
|
const org_id = state.orgId;
|
|
1515
1573
|
if (isEmpty(project_id)) {
|
|
1516
|
-
const response = await state.
|
|
1574
|
+
const response = await state.appConn().post_json("api/project/register", {
|
|
1517
1575
|
project_name: project_name || GLOBAL_PROJECT,
|
|
1518
1576
|
org_id
|
|
1519
1577
|
});
|
|
@@ -1526,7 +1584,7 @@ async function computeLoggerMetadata(state, {
|
|
|
1526
1584
|
}
|
|
1527
1585
|
};
|
|
1528
1586
|
} else if (isEmpty(project_name)) {
|
|
1529
|
-
const response = await state.
|
|
1587
|
+
const response = await state.appConn().get_json("api/project", {
|
|
1530
1588
|
id: project_id
|
|
1531
1589
|
});
|
|
1532
1590
|
return {
|
|
@@ -1616,7 +1674,7 @@ async function loadPrompt({
|
|
|
1616
1674
|
slug,
|
|
1617
1675
|
version
|
|
1618
1676
|
};
|
|
1619
|
-
const response = await state.
|
|
1677
|
+
const response = await state.apiConn().get_json("v1/prompt", args);
|
|
1620
1678
|
if (!("objects" in response) || response.objects.length === 0) {
|
|
1621
1679
|
throw new Error(
|
|
1622
1680
|
`Prompt ${slug} not found in ${[projectName ?? projectId]}`
|
|
@@ -1678,7 +1736,7 @@ async function loginToState(options = {}) {
|
|
|
1678
1736
|
);
|
|
1679
1737
|
const info = await resp.json();
|
|
1680
1738
|
_check_org_info(state, info.org_info, orgName);
|
|
1681
|
-
conn = state.
|
|
1739
|
+
conn = state.apiConn();
|
|
1682
1740
|
conn.set_token(apiKey);
|
|
1683
1741
|
} else {
|
|
1684
1742
|
throw new Error(
|
|
@@ -1689,11 +1747,11 @@ async function loginToState(options = {}) {
|
|
|
1689
1747
|
throw new Error("Conn should be set at this point (a bug)");
|
|
1690
1748
|
}
|
|
1691
1749
|
conn.make_long_lived();
|
|
1692
|
-
state.
|
|
1750
|
+
state.appConn().set_token(apiKey);
|
|
1693
1751
|
state.proxyConn().set_token(apiKey);
|
|
1694
1752
|
state.loginToken = conn.token;
|
|
1695
1753
|
state.loggedIn = true;
|
|
1696
|
-
state.
|
|
1754
|
+
state.loginReplaceApiConn(conn);
|
|
1697
1755
|
return state;
|
|
1698
1756
|
}
|
|
1699
1757
|
function log(event) {
|
|
@@ -1745,7 +1803,7 @@ function getSpanParentObject(options) {
|
|
|
1745
1803
|
return NOOP_SPAN;
|
|
1746
1804
|
}
|
|
1747
1805
|
function traced(callback, args) {
|
|
1748
|
-
const { span,
|
|
1806
|
+
const { span, isSyncFlushLogger } = startSpanAndIsLogger(args);
|
|
1749
1807
|
const ret = runFinally(
|
|
1750
1808
|
() => {
|
|
1751
1809
|
if (args?.setCurrent ?? true) {
|
|
@@ -1761,7 +1819,7 @@ function traced(callback, args) {
|
|
|
1761
1819
|
} else {
|
|
1762
1820
|
return (async () => {
|
|
1763
1821
|
const awaitedRet = await ret;
|
|
1764
|
-
if (
|
|
1822
|
+
if (isSyncFlushLogger) {
|
|
1765
1823
|
await span.flush();
|
|
1766
1824
|
}
|
|
1767
1825
|
return awaitedRet;
|
|
@@ -1840,14 +1898,19 @@ function startSpanAndIsLogger(args) {
|
|
|
1840
1898
|
});
|
|
1841
1899
|
return {
|
|
1842
1900
|
span,
|
|
1843
|
-
|
|
1901
|
+
isSyncFlushLogger: components.objectType === import_core.SpanObjectTypeV2.PROJECT_LOGS && // Since there's no parent logger here, we're free to choose the async flush
|
|
1902
|
+
// behavior, and therefore propagate along whatever we get from the arguments
|
|
1903
|
+
!args?.asyncFlush
|
|
1844
1904
|
};
|
|
1845
1905
|
} else {
|
|
1846
1906
|
const parentObject = getSpanParentObject({
|
|
1847
1907
|
asyncFlush: args?.asyncFlush
|
|
1848
1908
|
});
|
|
1849
1909
|
const span = parentObject.startSpan(args);
|
|
1850
|
-
return {
|
|
1910
|
+
return {
|
|
1911
|
+
span,
|
|
1912
|
+
isSyncFlushLogger: parentObject.kind === "logger" && !parentObject.asyncFlush
|
|
1913
|
+
};
|
|
1851
1914
|
}
|
|
1852
1915
|
}
|
|
1853
1916
|
function withCurrent(span, callback, state = _globalState) {
|
|
@@ -1861,13 +1924,8 @@ function _check_org_info(state, org_info, org_name) {
|
|
|
1861
1924
|
if (org_name === void 0 || org.name === org_name) {
|
|
1862
1925
|
state.orgId = org.id;
|
|
1863
1926
|
state.orgName = org.name;
|
|
1864
|
-
state.
|
|
1927
|
+
state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
|
|
1865
1928
|
state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
|
|
1866
|
-
if (state.proxyUrl) {
|
|
1867
|
-
const url = new URL(state.proxyUrl);
|
|
1868
|
-
url.pathname = "";
|
|
1869
|
-
state.proxyUrl = url.toString();
|
|
1870
|
-
}
|
|
1871
1929
|
state.gitMetadataSettings = org.git_metadata || void 0;
|
|
1872
1930
|
break;
|
|
1873
1931
|
}
|
|
@@ -1878,11 +1936,6 @@ function _check_org_info(state, org_info, org_name) {
|
|
|
1878
1936
|
);
|
|
1879
1937
|
}
|
|
1880
1938
|
}
|
|
1881
|
-
function _urljoin(...parts) {
|
|
1882
|
-
return parts.map(
|
|
1883
|
-
(x, i) => x.replace(/^\//, "").replace(i < parts.length - 1 ? /\/$/ : "", "")
|
|
1884
|
-
).join("/");
|
|
1885
|
-
}
|
|
1886
1939
|
function validateTags(tags) {
|
|
1887
1940
|
const seen = /* @__PURE__ */ new Set();
|
|
1888
1941
|
for (const tag of tags) {
|
|
@@ -1996,7 +2049,7 @@ var ObjectFetcher = class {
|
|
|
1996
2049
|
async fetchedData() {
|
|
1997
2050
|
if (this._fetchedData === void 0) {
|
|
1998
2051
|
const state = await this.getState();
|
|
1999
|
-
const resp = await state.
|
|
2052
|
+
const resp = await state.apiConn().get(
|
|
2000
2053
|
`v1/${this.objectType}/${await this.id}/fetch`,
|
|
2001
2054
|
{
|
|
2002
2055
|
version: this.pinnedVersion
|
|
@@ -2142,7 +2195,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2142
2195
|
}
|
|
2143
2196
|
async fetchBaseExperiment() {
|
|
2144
2197
|
const state = await this.getState();
|
|
2145
|
-
const conn = state.
|
|
2198
|
+
const conn = state.appConn();
|
|
2146
2199
|
try {
|
|
2147
2200
|
const resp = await conn.post("/api/base_experiment/get_id", {
|
|
2148
2201
|
id: await this.id
|
|
@@ -2189,7 +2242,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2189
2242
|
comparisonExperimentName = baseExperiment.name;
|
|
2190
2243
|
}
|
|
2191
2244
|
}
|
|
2192
|
-
const results = await state.
|
|
2245
|
+
const results = await state.apiConn().get_json(
|
|
2193
2246
|
"/experiment-comparison2",
|
|
2194
2247
|
{
|
|
2195
2248
|
experiment_id: await this.id,
|
|
@@ -2377,29 +2430,10 @@ var SpanImpl = class _SpanImpl {
|
|
|
2377
2430
|
event,
|
|
2378
2431
|
internalData
|
|
2379
2432
|
}) {
|
|
2380
|
-
const
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
const lazyInternalData = {};
|
|
2385
|
-
for (const [key, value] of Object.entries(sanitizedAndInternalData)) {
|
|
2386
|
-
if (value instanceof BraintrustStream) {
|
|
2387
|
-
const streamCopy = value.copy();
|
|
2388
|
-
lazyInternalData[key] = new LazyValue(async () => {
|
|
2389
|
-
return await new Promise((resolve) => {
|
|
2390
|
-
streamCopy.toReadableStream().pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2391
|
-
});
|
|
2392
|
-
});
|
|
2393
|
-
} else if (value instanceof ReadableStream) {
|
|
2394
|
-
lazyInternalData[key] = new LazyValue(async () => {
|
|
2395
|
-
return await new Promise((resolve) => {
|
|
2396
|
-
value.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2397
|
-
});
|
|
2398
|
-
});
|
|
2399
|
-
} else {
|
|
2400
|
-
serializableInternalData[key] = value;
|
|
2401
|
-
}
|
|
2402
|
-
}
|
|
2433
|
+
const [serializableInternalData, lazyInternalData] = splitLoggingData({
|
|
2434
|
+
event,
|
|
2435
|
+
internalData
|
|
2436
|
+
});
|
|
2403
2437
|
let partialRecord = {
|
|
2404
2438
|
id: this.id,
|
|
2405
2439
|
span_id: this.spanId,
|
|
@@ -2517,6 +2551,36 @@ var SpanImpl = class _SpanImpl {
|
|
|
2517
2551
|
return this.end(args);
|
|
2518
2552
|
}
|
|
2519
2553
|
};
|
|
2554
|
+
function splitLoggingData({
|
|
2555
|
+
event,
|
|
2556
|
+
internalData
|
|
2557
|
+
}) {
|
|
2558
|
+
const sanitized = validateAndSanitizeExperimentLogPartialArgs(event ?? {});
|
|
2559
|
+
const sanitizedAndInternalData = {};
|
|
2560
|
+
(0, import_core.mergeDicts)(sanitizedAndInternalData, internalData || {});
|
|
2561
|
+
(0, import_core.mergeDicts)(sanitizedAndInternalData, sanitized);
|
|
2562
|
+
const serializableInternalData = {};
|
|
2563
|
+
const lazyInternalData = {};
|
|
2564
|
+
for (const [key, value] of Object.entries(sanitizedAndInternalData)) {
|
|
2565
|
+
if (value instanceof BraintrustStream) {
|
|
2566
|
+
const streamCopy = value.copy();
|
|
2567
|
+
lazyInternalData[key] = new LazyValue(async () => {
|
|
2568
|
+
return await new Promise((resolve) => {
|
|
2569
|
+
streamCopy.toReadableStream().pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2570
|
+
});
|
|
2571
|
+
});
|
|
2572
|
+
} else if (value instanceof ReadableStream) {
|
|
2573
|
+
lazyInternalData[key] = new LazyValue(async () => {
|
|
2574
|
+
return await new Promise((resolve) => {
|
|
2575
|
+
value.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2576
|
+
});
|
|
2577
|
+
});
|
|
2578
|
+
} else {
|
|
2579
|
+
serializableInternalData[key] = value;
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
return [serializableInternalData, lazyInternalData];
|
|
2583
|
+
}
|
|
2520
2584
|
var Dataset = class extends ObjectFetcher {
|
|
2521
2585
|
constructor(state, lazyMetadata, pinnedVersion, legacy) {
|
|
2522
2586
|
const isLegacyDataset = legacy ?? import_core.DEFAULT_IS_LEGACY_DATASET;
|
|
@@ -2633,7 +2697,7 @@ var Dataset = class extends ObjectFetcher {
|
|
|
2633
2697
|
)}`;
|
|
2634
2698
|
let dataSummary = void 0;
|
|
2635
2699
|
if (summarizeData) {
|
|
2636
|
-
dataSummary = await state.
|
|
2700
|
+
dataSummary = await state.apiConn().get_json(
|
|
2637
2701
|
"dataset-summary",
|
|
2638
2702
|
{
|
|
2639
2703
|
dataset_id: await this.id
|
|
@@ -2739,7 +2803,7 @@ var Prompt = class {
|
|
|
2739
2803
|
if (!prompt) {
|
|
2740
2804
|
throw new Error("Empty prompt");
|
|
2741
2805
|
}
|
|
2742
|
-
const dictArgParsed =
|
|
2806
|
+
const dictArgParsed = import_zod2.z.record(import_zod2.z.unknown()).safeParse(buildArgs);
|
|
2743
2807
|
const variables = {
|
|
2744
2808
|
input: buildArgs,
|
|
2745
2809
|
...dictArgParsed.success ? dictArgParsed.data : {}
|
|
@@ -2815,12 +2879,12 @@ async function invoke(args) {
|
|
|
2815
2879
|
appUrl,
|
|
2816
2880
|
forceLogin,
|
|
2817
2881
|
fetch,
|
|
2818
|
-
|
|
2882
|
+
input,
|
|
2819
2883
|
parent: parentArg,
|
|
2820
2884
|
state: stateArg,
|
|
2821
2885
|
stream,
|
|
2822
2886
|
schema,
|
|
2823
|
-
...
|
|
2887
|
+
...functionIdArgs
|
|
2824
2888
|
} = args;
|
|
2825
2889
|
const state = stateArg ?? _internalGetGlobalState();
|
|
2826
2890
|
await state.login({
|
|
@@ -2829,10 +2893,16 @@ async function invoke(args) {
|
|
|
2829
2893
|
appUrl,
|
|
2830
2894
|
forceLogin
|
|
2831
2895
|
});
|
|
2832
|
-
const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await
|
|
2896
|
+
const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await getSpanParentObject().export();
|
|
2897
|
+
const functionId = import_typespecs3.functionIdSchema.safeParse(functionIdArgs);
|
|
2898
|
+
if (!functionId.success) {
|
|
2899
|
+
throw new Error(
|
|
2900
|
+
`Invalid function ID arguments: ${functionId.error.message}`
|
|
2901
|
+
);
|
|
2902
|
+
}
|
|
2833
2903
|
const request = {
|
|
2834
|
-
...functionId,
|
|
2835
|
-
|
|
2904
|
+
...functionId.data,
|
|
2905
|
+
input,
|
|
2836
2906
|
parent,
|
|
2837
2907
|
stream,
|
|
2838
2908
|
api_version: import_typespecs3.INVOKE_API_VERSION
|
|
@@ -3223,6 +3293,7 @@ configureBrowser();
|
|
|
3223
3293
|
X_CACHED_HEADER,
|
|
3224
3294
|
_internalGetGlobalState,
|
|
3225
3295
|
_internalSetInitialState,
|
|
3296
|
+
braintrustStreamChunkSchema,
|
|
3226
3297
|
createFinalValuePassThroughStream,
|
|
3227
3298
|
currentExperiment,
|
|
3228
3299
|
currentLogger,
|