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/browser.mjs
CHANGED
|
@@ -93,29 +93,81 @@ var LazyValue = class {
|
|
|
93
93
|
return this.value.hasComputed;
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
|
+
function _urljoin(...parts) {
|
|
97
|
+
return parts.map(
|
|
98
|
+
(x, i) => x.replace(/^\//, "").replace(i < parts.length - 1 ? /\/$/ : "", "")
|
|
99
|
+
).filter((x) => x.trim() !== "").join("/");
|
|
100
|
+
}
|
|
96
101
|
|
|
97
102
|
// src/logger.ts
|
|
98
103
|
import Mustache from "mustache";
|
|
99
|
-
import { z } from "zod";
|
|
104
|
+
import { z as z2 } from "zod";
|
|
100
105
|
|
|
101
|
-
// src/stream.ts
|
|
106
|
+
// src/functions/stream.ts
|
|
102
107
|
import { callEventSchema } from "@braintrust/core/typespecs";
|
|
103
108
|
import {
|
|
104
109
|
createParser
|
|
105
110
|
} from "eventsource-parser";
|
|
111
|
+
import { z } from "zod";
|
|
112
|
+
var braintrustStreamChunkSchema = z.union([
|
|
113
|
+
z.object({
|
|
114
|
+
type: z.literal("text_delta"),
|
|
115
|
+
data: z.string()
|
|
116
|
+
}),
|
|
117
|
+
z.object({
|
|
118
|
+
type: z.literal("json_delta"),
|
|
119
|
+
data: z.string()
|
|
120
|
+
})
|
|
121
|
+
]);
|
|
106
122
|
var BraintrustStream = class _BraintrustStream {
|
|
107
123
|
stream;
|
|
124
|
+
memoizedFinalValue;
|
|
108
125
|
constructor(baseStream) {
|
|
109
126
|
this.stream = baseStream.pipeThrough(btStreamParser());
|
|
110
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Copy the stream. This returns a new stream that shares the same underlying
|
|
130
|
+
* stream (via `tee`). Since streams are consumed in Javascript, use `copy()` if you
|
|
131
|
+
* need to use the stream multiple times.
|
|
132
|
+
*
|
|
133
|
+
* @returns A new stream that you can independently consume.
|
|
134
|
+
*/
|
|
111
135
|
copy() {
|
|
112
136
|
const [newStream, copyStream] = this.stream.tee();
|
|
113
137
|
this.stream = copyStream;
|
|
114
138
|
return new _BraintrustStream(newStream);
|
|
115
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Get the underlying ReadableStream.
|
|
142
|
+
*
|
|
143
|
+
* @returns The underlying ReadableStream<BraintrustStreamChunk>.
|
|
144
|
+
*/
|
|
116
145
|
toReadableStream() {
|
|
117
146
|
return this.stream;
|
|
118
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Get the final value of the stream. The final value is the concatenation of all
|
|
150
|
+
* the chunks in the stream, deserialized into a string or JSON object, depending on
|
|
151
|
+
* the value's type.
|
|
152
|
+
*
|
|
153
|
+
* This function returns a promise that resolves when the stream is closed, and
|
|
154
|
+
* contains the final value. Multiple calls to `finalValue()` will return the same
|
|
155
|
+
* promise, so it is safe to call this multiple times.
|
|
156
|
+
*
|
|
157
|
+
* This function consumes the stream, so if you need to use the stream multiple
|
|
158
|
+
* times, you should call `copy()` first.
|
|
159
|
+
*
|
|
160
|
+
* @returns A promise that resolves with the final value of the stream or `undefined` if the stream is empty.
|
|
161
|
+
*/
|
|
162
|
+
finalValue() {
|
|
163
|
+
if (this.memoizedFinalValue) {
|
|
164
|
+
return this.memoizedFinalValue;
|
|
165
|
+
}
|
|
166
|
+
this.memoizedFinalValue = new Promise((resolve, reject) => {
|
|
167
|
+
const stream = this.stream.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
168
|
+
});
|
|
169
|
+
return this.memoizedFinalValue;
|
|
170
|
+
}
|
|
119
171
|
};
|
|
120
172
|
function btStreamParser() {
|
|
121
173
|
const decoder = new TextDecoder();
|
|
@@ -170,9 +222,17 @@ function createFinalValuePassThroughStream(onFinal) {
|
|
|
170
222
|
transform(chunk, controller) {
|
|
171
223
|
if (typeof chunk === "string") {
|
|
172
224
|
textChunks.push(chunk);
|
|
225
|
+
controller.enqueue({
|
|
226
|
+
type: "text_delta",
|
|
227
|
+
data: chunk
|
|
228
|
+
});
|
|
173
229
|
} else if (chunk instanceof Uint8Array) {
|
|
174
230
|
textChunks.push(decoder.decode(chunk));
|
|
175
|
-
|
|
231
|
+
controller.enqueue({
|
|
232
|
+
type: "text_delta",
|
|
233
|
+
data: decoder.decode(chunk)
|
|
234
|
+
});
|
|
235
|
+
} else if (braintrustStreamChunkSchema.safeParse(chunk).success) {
|
|
176
236
|
const chunkType = chunk.type;
|
|
177
237
|
switch (chunkType) {
|
|
178
238
|
case "text_delta":
|
|
@@ -186,6 +246,8 @@ function createFinalValuePassThroughStream(onFinal) {
|
|
|
186
246
|
throw new Error(`Unknown chunk type ${_type}`);
|
|
187
247
|
}
|
|
188
248
|
controller.enqueue(chunk);
|
|
249
|
+
} else {
|
|
250
|
+
throw new Error(`Unknown chunk type ${chunk}`);
|
|
189
251
|
}
|
|
190
252
|
},
|
|
191
253
|
flush(controller) {
|
|
@@ -247,14 +309,14 @@ var NoopSpan = class {
|
|
|
247
309
|
}
|
|
248
310
|
};
|
|
249
311
|
var NOOP_SPAN = new NoopSpan();
|
|
250
|
-
var loginSchema =
|
|
251
|
-
appUrl:
|
|
252
|
-
appPublicUrl:
|
|
253
|
-
orgName:
|
|
254
|
-
|
|
255
|
-
proxyUrl:
|
|
256
|
-
loginToken:
|
|
257
|
-
orgId:
|
|
312
|
+
var loginSchema = z2.strictObject({
|
|
313
|
+
appUrl: z2.string(),
|
|
314
|
+
appPublicUrl: z2.string(),
|
|
315
|
+
orgName: z2.string(),
|
|
316
|
+
apiUrl: z2.string(),
|
|
317
|
+
proxyUrl: z2.string(),
|
|
318
|
+
loginToken: z2.string(),
|
|
319
|
+
orgId: z2.string().nullish(),
|
|
258
320
|
gitMetadataSettings: gitMetadataSettingsSchema.nullish()
|
|
259
321
|
});
|
|
260
322
|
var BraintrustState = class _BraintrustState {
|
|
@@ -269,7 +331,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
269
331
|
}
|
|
270
332
|
const defaultGetLogConn = async () => {
|
|
271
333
|
await this.login({});
|
|
272
|
-
return this.
|
|
334
|
+
return this.apiConn();
|
|
273
335
|
};
|
|
274
336
|
this._bgLogger = new BackgroundLogger(new LazyValue(defaultGetLogConn));
|
|
275
337
|
this.resetLoginInfo();
|
|
@@ -280,7 +342,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
280
342
|
// (safely) dynamically cast it whenever retrieving the logger.
|
|
281
343
|
currentLogger;
|
|
282
344
|
currentSpan;
|
|
283
|
-
// Any time we re-log in, we directly update the
|
|
345
|
+
// Any time we re-log in, we directly update the apiConn inside the logger.
|
|
284
346
|
// This is preferable to replacing the whole logger, which would create the
|
|
285
347
|
// possibility of multiple loggers floating around, which may not log in a
|
|
286
348
|
// deterministic order.
|
|
@@ -290,13 +352,13 @@ var BraintrustState = class _BraintrustState {
|
|
|
290
352
|
loginToken = null;
|
|
291
353
|
orgId = null;
|
|
292
354
|
orgName = null;
|
|
293
|
-
|
|
355
|
+
apiUrl = null;
|
|
294
356
|
proxyUrl = null;
|
|
295
357
|
loggedIn = false;
|
|
296
358
|
gitMetadataSettings;
|
|
297
359
|
fetch = globalThis.fetch;
|
|
360
|
+
_appConn = null;
|
|
298
361
|
_apiConn = null;
|
|
299
|
-
_logConn = null;
|
|
300
362
|
_proxyConn = null;
|
|
301
363
|
resetLoginInfo() {
|
|
302
364
|
this.appUrl = null;
|
|
@@ -304,12 +366,12 @@ var BraintrustState = class _BraintrustState {
|
|
|
304
366
|
this.loginToken = null;
|
|
305
367
|
this.orgId = null;
|
|
306
368
|
this.orgName = null;
|
|
307
|
-
this.
|
|
369
|
+
this.apiUrl = null;
|
|
308
370
|
this.proxyUrl = null;
|
|
309
371
|
this.loggedIn = false;
|
|
310
372
|
this.gitMetadataSettings = void 0;
|
|
373
|
+
this._appConn = null;
|
|
311
374
|
this._apiConn = null;
|
|
312
|
-
this._logConn = null;
|
|
313
375
|
this._proxyConn = null;
|
|
314
376
|
}
|
|
315
377
|
copyLoginInfo(other) {
|
|
@@ -318,12 +380,12 @@ var BraintrustState = class _BraintrustState {
|
|
|
318
380
|
this.loginToken = other.loginToken;
|
|
319
381
|
this.orgId = other.orgId;
|
|
320
382
|
this.orgName = other.orgName;
|
|
321
|
-
this.
|
|
383
|
+
this.apiUrl = other.apiUrl;
|
|
322
384
|
this.proxyUrl = other.proxyUrl;
|
|
323
385
|
this.loggedIn = other.loggedIn;
|
|
324
386
|
this.gitMetadataSettings = other.gitMetadataSettings;
|
|
387
|
+
this._appConn = other._appConn;
|
|
325
388
|
this._apiConn = other._apiConn;
|
|
326
|
-
this._logConn = other._logConn;
|
|
327
389
|
this._proxyConn = other._proxyConn;
|
|
328
390
|
}
|
|
329
391
|
serialize() {
|
|
@@ -332,7 +394,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
332
394
|
"Cannot serialize BraintrustState without being logged in"
|
|
333
395
|
);
|
|
334
396
|
}
|
|
335
|
-
if (!this.appUrl || !this.appPublicUrl || !this.
|
|
397
|
+
if (!this.appUrl || !this.appPublicUrl || !this.apiUrl || !this.proxyUrl || !this.orgName || !this.loginToken || !this.loggedIn) {
|
|
336
398
|
throw new Error(
|
|
337
399
|
"Cannot serialize BraintrustState without all login attributes"
|
|
338
400
|
);
|
|
@@ -343,7 +405,7 @@ var BraintrustState = class _BraintrustState {
|
|
|
343
405
|
loginToken: this.loginToken,
|
|
344
406
|
orgId: this.orgId,
|
|
345
407
|
orgName: this.orgName,
|
|
346
|
-
|
|
408
|
+
apiUrl: this.apiUrl,
|
|
347
409
|
proxyUrl: this.proxyUrl,
|
|
348
410
|
gitMetadataSettings: this.gitMetadataSettings
|
|
349
411
|
};
|
|
@@ -364,22 +426,23 @@ var BraintrustState = class _BraintrustState {
|
|
|
364
426
|
"Cannot deserialize BraintrustState without a login token"
|
|
365
427
|
);
|
|
366
428
|
}
|
|
367
|
-
state.logConn().set_token(state.loginToken);
|
|
368
|
-
state.logConn().make_long_lived();
|
|
369
429
|
state.apiConn().set_token(state.loginToken);
|
|
430
|
+
state.apiConn().make_long_lived();
|
|
431
|
+
state.appConn().set_token(state.loginToken);
|
|
432
|
+
state.proxyConn().make_long_lived();
|
|
370
433
|
state.proxyConn().set_token(state.loginToken);
|
|
371
434
|
state.loggedIn = true;
|
|
372
|
-
state.
|
|
435
|
+
state.loginReplaceApiConn(state.apiConn());
|
|
373
436
|
return state;
|
|
374
437
|
}
|
|
375
438
|
setFetch(fetch) {
|
|
376
439
|
this.loginParams.fetch = fetch;
|
|
377
440
|
this.fetch = fetch;
|
|
378
|
-
this._logConn?.setFetch(fetch);
|
|
379
441
|
this._apiConn?.setFetch(fetch);
|
|
442
|
+
this._appConn?.setFetch(fetch);
|
|
380
443
|
}
|
|
381
444
|
async login(loginParams) {
|
|
382
|
-
if (this.
|
|
445
|
+
if (this.apiUrl && !loginParams.forceLogin) {
|
|
383
446
|
return;
|
|
384
447
|
}
|
|
385
448
|
const newState = await loginToState({
|
|
@@ -388,23 +451,23 @@ var BraintrustState = class _BraintrustState {
|
|
|
388
451
|
});
|
|
389
452
|
this.copyLoginInfo(newState);
|
|
390
453
|
}
|
|
391
|
-
|
|
392
|
-
if (!this.
|
|
454
|
+
appConn() {
|
|
455
|
+
if (!this._appConn) {
|
|
393
456
|
if (!this.appUrl) {
|
|
394
|
-
throw new Error("Must initialize appUrl before requesting
|
|
457
|
+
throw new Error("Must initialize appUrl before requesting appConn");
|
|
395
458
|
}
|
|
396
|
-
this.
|
|
459
|
+
this._appConn = new HTTPConnection(this.appUrl, this.fetch);
|
|
397
460
|
}
|
|
398
|
-
return this.
|
|
461
|
+
return this._appConn;
|
|
399
462
|
}
|
|
400
|
-
|
|
401
|
-
if (!this.
|
|
402
|
-
if (!this.
|
|
403
|
-
throw new Error("Must initialize
|
|
463
|
+
apiConn() {
|
|
464
|
+
if (!this._apiConn) {
|
|
465
|
+
if (!this.apiUrl) {
|
|
466
|
+
throw new Error("Must initialize apiUrl before requesting apiConn");
|
|
404
467
|
}
|
|
405
|
-
this.
|
|
468
|
+
this._apiConn = new HTTPConnection(this.apiUrl, this.fetch);
|
|
406
469
|
}
|
|
407
|
-
return this.
|
|
470
|
+
return this._apiConn;
|
|
408
471
|
}
|
|
409
472
|
proxyConn() {
|
|
410
473
|
if (!this._proxyConn) {
|
|
@@ -419,8 +482,8 @@ var BraintrustState = class _BraintrustState {
|
|
|
419
482
|
return this._bgLogger;
|
|
420
483
|
}
|
|
421
484
|
// Should only be called by the login function.
|
|
422
|
-
|
|
423
|
-
this._bgLogger.
|
|
485
|
+
loginReplaceApiConn(apiConn) {
|
|
486
|
+
this._bgLogger.internalReplaceApiConn(apiConn);
|
|
424
487
|
}
|
|
425
488
|
};
|
|
426
489
|
var _globalState;
|
|
@@ -727,11 +790,6 @@ var Logger = class {
|
|
|
727
790
|
parentObjectType() {
|
|
728
791
|
return SpanObjectTypeV2.PROJECT_LOGS;
|
|
729
792
|
}
|
|
730
|
-
triggerWaitUntilFlush() {
|
|
731
|
-
if (!this.state.bgLogger().syncFlush) {
|
|
732
|
-
return waitUntil(this.state.bgLogger().flush());
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
793
|
/**
|
|
736
794
|
* Log a single event. The event will be batched and uploaded behind the scenes if `logOptions.asyncFlush` is true.
|
|
737
795
|
*
|
|
@@ -757,7 +815,6 @@ var Logger = class {
|
|
|
757
815
|
this.lastStartTime = span.end();
|
|
758
816
|
const ret = span.id;
|
|
759
817
|
if (this.asyncFlush === true) {
|
|
760
|
-
this.triggerWaitUntilFlush();
|
|
761
818
|
return ret;
|
|
762
819
|
} else {
|
|
763
820
|
return (async () => {
|
|
@@ -785,7 +842,6 @@ var Logger = class {
|
|
|
785
842
|
() => span.end()
|
|
786
843
|
);
|
|
787
844
|
if (this.asyncFlush) {
|
|
788
|
-
this.triggerWaitUntilFlush();
|
|
789
845
|
return ret;
|
|
790
846
|
} else {
|
|
791
847
|
return (async () => {
|
|
@@ -865,7 +921,7 @@ var Logger = class {
|
|
|
865
921
|
function castLogger(logger, asyncFlush) {
|
|
866
922
|
if (logger === void 0)
|
|
867
923
|
return void 0;
|
|
868
|
-
if (asyncFlush && !!asyncFlush !== !!logger.asyncFlush) {
|
|
924
|
+
if (asyncFlush !== void 0 && !!asyncFlush !== !!logger.asyncFlush) {
|
|
869
925
|
throw new Error(
|
|
870
926
|
`Asserted asyncFlush setting ${asyncFlush} does not match stored logger's setting ${logger.asyncFlush}`
|
|
871
927
|
);
|
|
@@ -879,7 +935,7 @@ function now() {
|
|
|
879
935
|
return (/* @__PURE__ */ new Date()).getTime();
|
|
880
936
|
}
|
|
881
937
|
var BackgroundLogger = class _BackgroundLogger {
|
|
882
|
-
|
|
938
|
+
apiConn;
|
|
883
939
|
items = [];
|
|
884
940
|
activeFlush = Promise.resolve();
|
|
885
941
|
activeFlushResolved = true;
|
|
@@ -897,8 +953,8 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
897
953
|
numDropped: 0,
|
|
898
954
|
lastLoggedTimestamp: 0
|
|
899
955
|
};
|
|
900
|
-
constructor(
|
|
901
|
-
this.
|
|
956
|
+
constructor(apiConn) {
|
|
957
|
+
this.apiConn = apiConn;
|
|
902
958
|
const syncFlushEnv = Number(isomorph_default.getEnv("BRAINTRUST_SYNC_FLUSH"));
|
|
903
959
|
if (!isNaN(syncFlushEnv)) {
|
|
904
960
|
this.syncFlush = Boolean(syncFlushEnv);
|
|
@@ -1044,7 +1100,7 @@ var BackgroundLogger = class _BackgroundLogger {
|
|
|
1044
1100
|
return [];
|
|
1045
1101
|
}
|
|
1046
1102
|
async submitLogsRequest(items) {
|
|
1047
|
-
const conn = await this.
|
|
1103
|
+
const conn = await this.apiConn.get();
|
|
1048
1104
|
const dataStr = constructLogs3Data(items);
|
|
1049
1105
|
if (this.allPublishPayloadsDir) {
|
|
1050
1106
|
await _BackgroundLogger.writePayloadToDir({
|
|
@@ -1182,14 +1238,15 @@ Error: ${errorText}`;
|
|
|
1182
1238
|
this.activeFlushResolved = true;
|
|
1183
1239
|
}
|
|
1184
1240
|
})();
|
|
1241
|
+
waitUntil(this.activeFlush);
|
|
1185
1242
|
}
|
|
1186
1243
|
}
|
|
1187
1244
|
logFailedPayloadsDir() {
|
|
1188
1245
|
console.warn(`Logging failed payloads to ${this.failedPublishPayloadsDir}`);
|
|
1189
1246
|
}
|
|
1190
1247
|
// Should only be called by BraintrustState.
|
|
1191
|
-
|
|
1192
|
-
this.
|
|
1248
|
+
internalReplaceApiConn(apiConn) {
|
|
1249
|
+
this.apiConn = new LazyValue(async () => apiConn);
|
|
1193
1250
|
}
|
|
1194
1251
|
};
|
|
1195
1252
|
function init(projectOrOptions, optionalOptions) {
|
|
@@ -1243,7 +1300,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
1243
1300
|
org_name: state.orgName,
|
|
1244
1301
|
experiment_name: experiment
|
|
1245
1302
|
};
|
|
1246
|
-
const response = await state.
|
|
1303
|
+
const response = await state.appConn().post_json("api/experiment/get", args);
|
|
1247
1304
|
if (response.length === 0) {
|
|
1248
1305
|
throw new Error(
|
|
1249
1306
|
`Experiment ${experiment} not found in project ${projectId ?? project}.`
|
|
@@ -1324,7 +1381,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
1324
1381
|
let response = null;
|
|
1325
1382
|
while (true) {
|
|
1326
1383
|
try {
|
|
1327
|
-
response = await state.
|
|
1384
|
+
response = await state.appConn().post_json("api/experiment/register", args);
|
|
1328
1385
|
break;
|
|
1329
1386
|
} catch (e) {
|
|
1330
1387
|
if (args["base_experiment"] && `${"data" in e && e.data}`.includes("base experiment")) {
|
|
@@ -1430,7 +1487,7 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
1430
1487
|
dataset_name: dataset,
|
|
1431
1488
|
description
|
|
1432
1489
|
};
|
|
1433
|
-
const response = await state.
|
|
1490
|
+
const response = await state.appConn().post_json("api/dataset/register", args);
|
|
1434
1491
|
return {
|
|
1435
1492
|
project: {
|
|
1436
1493
|
id: response.project.id,
|
|
@@ -1460,7 +1517,7 @@ async function computeLoggerMetadata(state, {
|
|
|
1460
1517
|
}) {
|
|
1461
1518
|
const org_id = state.orgId;
|
|
1462
1519
|
if (isEmpty(project_id)) {
|
|
1463
|
-
const response = await state.
|
|
1520
|
+
const response = await state.appConn().post_json("api/project/register", {
|
|
1464
1521
|
project_name: project_name || GLOBAL_PROJECT,
|
|
1465
1522
|
org_id
|
|
1466
1523
|
});
|
|
@@ -1473,7 +1530,7 @@ async function computeLoggerMetadata(state, {
|
|
|
1473
1530
|
}
|
|
1474
1531
|
};
|
|
1475
1532
|
} else if (isEmpty(project_name)) {
|
|
1476
|
-
const response = await state.
|
|
1533
|
+
const response = await state.appConn().get_json("api/project", {
|
|
1477
1534
|
id: project_id
|
|
1478
1535
|
});
|
|
1479
1536
|
return {
|
|
@@ -1563,7 +1620,7 @@ async function loadPrompt({
|
|
|
1563
1620
|
slug,
|
|
1564
1621
|
version
|
|
1565
1622
|
};
|
|
1566
|
-
const response = await state.
|
|
1623
|
+
const response = await state.apiConn().get_json("v1/prompt", args);
|
|
1567
1624
|
if (!("objects" in response) || response.objects.length === 0) {
|
|
1568
1625
|
throw new Error(
|
|
1569
1626
|
`Prompt ${slug} not found in ${[projectName ?? projectId]}`
|
|
@@ -1625,7 +1682,7 @@ async function loginToState(options = {}) {
|
|
|
1625
1682
|
);
|
|
1626
1683
|
const info = await resp.json();
|
|
1627
1684
|
_check_org_info(state, info.org_info, orgName);
|
|
1628
|
-
conn = state.
|
|
1685
|
+
conn = state.apiConn();
|
|
1629
1686
|
conn.set_token(apiKey);
|
|
1630
1687
|
} else {
|
|
1631
1688
|
throw new Error(
|
|
@@ -1636,11 +1693,11 @@ async function loginToState(options = {}) {
|
|
|
1636
1693
|
throw new Error("Conn should be set at this point (a bug)");
|
|
1637
1694
|
}
|
|
1638
1695
|
conn.make_long_lived();
|
|
1639
|
-
state.
|
|
1696
|
+
state.appConn().set_token(apiKey);
|
|
1640
1697
|
state.proxyConn().set_token(apiKey);
|
|
1641
1698
|
state.loginToken = conn.token;
|
|
1642
1699
|
state.loggedIn = true;
|
|
1643
|
-
state.
|
|
1700
|
+
state.loginReplaceApiConn(conn);
|
|
1644
1701
|
return state;
|
|
1645
1702
|
}
|
|
1646
1703
|
function log(event) {
|
|
@@ -1692,7 +1749,7 @@ function getSpanParentObject(options) {
|
|
|
1692
1749
|
return NOOP_SPAN;
|
|
1693
1750
|
}
|
|
1694
1751
|
function traced(callback, args) {
|
|
1695
|
-
const { span,
|
|
1752
|
+
const { span, isSyncFlushLogger } = startSpanAndIsLogger(args);
|
|
1696
1753
|
const ret = runFinally(
|
|
1697
1754
|
() => {
|
|
1698
1755
|
if (args?.setCurrent ?? true) {
|
|
@@ -1708,7 +1765,7 @@ function traced(callback, args) {
|
|
|
1708
1765
|
} else {
|
|
1709
1766
|
return (async () => {
|
|
1710
1767
|
const awaitedRet = await ret;
|
|
1711
|
-
if (
|
|
1768
|
+
if (isSyncFlushLogger) {
|
|
1712
1769
|
await span.flush();
|
|
1713
1770
|
}
|
|
1714
1771
|
return awaitedRet;
|
|
@@ -1787,14 +1844,19 @@ function startSpanAndIsLogger(args) {
|
|
|
1787
1844
|
});
|
|
1788
1845
|
return {
|
|
1789
1846
|
span,
|
|
1790
|
-
|
|
1847
|
+
isSyncFlushLogger: components.objectType === SpanObjectTypeV2.PROJECT_LOGS && // Since there's no parent logger here, we're free to choose the async flush
|
|
1848
|
+
// behavior, and therefore propagate along whatever we get from the arguments
|
|
1849
|
+
!args?.asyncFlush
|
|
1791
1850
|
};
|
|
1792
1851
|
} else {
|
|
1793
1852
|
const parentObject = getSpanParentObject({
|
|
1794
1853
|
asyncFlush: args?.asyncFlush
|
|
1795
1854
|
});
|
|
1796
1855
|
const span = parentObject.startSpan(args);
|
|
1797
|
-
return {
|
|
1856
|
+
return {
|
|
1857
|
+
span,
|
|
1858
|
+
isSyncFlushLogger: parentObject.kind === "logger" && !parentObject.asyncFlush
|
|
1859
|
+
};
|
|
1798
1860
|
}
|
|
1799
1861
|
}
|
|
1800
1862
|
function withCurrent(span, callback, state = _globalState) {
|
|
@@ -1808,13 +1870,8 @@ function _check_org_info(state, org_info, org_name) {
|
|
|
1808
1870
|
if (org_name === void 0 || org.name === org_name) {
|
|
1809
1871
|
state.orgId = org.id;
|
|
1810
1872
|
state.orgName = org.name;
|
|
1811
|
-
state.
|
|
1873
|
+
state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
|
|
1812
1874
|
state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
|
|
1813
|
-
if (state.proxyUrl) {
|
|
1814
|
-
const url = new URL(state.proxyUrl);
|
|
1815
|
-
url.pathname = "";
|
|
1816
|
-
state.proxyUrl = url.toString();
|
|
1817
|
-
}
|
|
1818
1875
|
state.gitMetadataSettings = org.git_metadata || void 0;
|
|
1819
1876
|
break;
|
|
1820
1877
|
}
|
|
@@ -1825,11 +1882,6 @@ function _check_org_info(state, org_info, org_name) {
|
|
|
1825
1882
|
);
|
|
1826
1883
|
}
|
|
1827
1884
|
}
|
|
1828
|
-
function _urljoin(...parts) {
|
|
1829
|
-
return parts.map(
|
|
1830
|
-
(x, i) => x.replace(/^\//, "").replace(i < parts.length - 1 ? /\/$/ : "", "")
|
|
1831
|
-
).join("/");
|
|
1832
|
-
}
|
|
1833
1885
|
function validateTags(tags) {
|
|
1834
1886
|
const seen = /* @__PURE__ */ new Set();
|
|
1835
1887
|
for (const tag of tags) {
|
|
@@ -1943,7 +1995,7 @@ var ObjectFetcher = class {
|
|
|
1943
1995
|
async fetchedData() {
|
|
1944
1996
|
if (this._fetchedData === void 0) {
|
|
1945
1997
|
const state = await this.getState();
|
|
1946
|
-
const resp = await state.
|
|
1998
|
+
const resp = await state.apiConn().get(
|
|
1947
1999
|
`v1/${this.objectType}/${await this.id}/fetch`,
|
|
1948
2000
|
{
|
|
1949
2001
|
version: this.pinnedVersion
|
|
@@ -2089,7 +2141,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2089
2141
|
}
|
|
2090
2142
|
async fetchBaseExperiment() {
|
|
2091
2143
|
const state = await this.getState();
|
|
2092
|
-
const conn = state.
|
|
2144
|
+
const conn = state.appConn();
|
|
2093
2145
|
try {
|
|
2094
2146
|
const resp = await conn.post("/api/base_experiment/get_id", {
|
|
2095
2147
|
id: await this.id
|
|
@@ -2136,7 +2188,7 @@ var Experiment = class extends ObjectFetcher {
|
|
|
2136
2188
|
comparisonExperimentName = baseExperiment.name;
|
|
2137
2189
|
}
|
|
2138
2190
|
}
|
|
2139
|
-
const results = await state.
|
|
2191
|
+
const results = await state.apiConn().get_json(
|
|
2140
2192
|
"/experiment-comparison2",
|
|
2141
2193
|
{
|
|
2142
2194
|
experiment_id: await this.id,
|
|
@@ -2324,29 +2376,10 @@ var SpanImpl = class _SpanImpl {
|
|
|
2324
2376
|
event,
|
|
2325
2377
|
internalData
|
|
2326
2378
|
}) {
|
|
2327
|
-
const
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
const lazyInternalData = {};
|
|
2332
|
-
for (const [key, value] of Object.entries(sanitizedAndInternalData)) {
|
|
2333
|
-
if (value instanceof BraintrustStream) {
|
|
2334
|
-
const streamCopy = value.copy();
|
|
2335
|
-
lazyInternalData[key] = new LazyValue(async () => {
|
|
2336
|
-
return await new Promise((resolve) => {
|
|
2337
|
-
streamCopy.toReadableStream().pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2338
|
-
});
|
|
2339
|
-
});
|
|
2340
|
-
} else if (value instanceof ReadableStream) {
|
|
2341
|
-
lazyInternalData[key] = new LazyValue(async () => {
|
|
2342
|
-
return await new Promise((resolve) => {
|
|
2343
|
-
value.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2344
|
-
});
|
|
2345
|
-
});
|
|
2346
|
-
} else {
|
|
2347
|
-
serializableInternalData[key] = value;
|
|
2348
|
-
}
|
|
2349
|
-
}
|
|
2379
|
+
const [serializableInternalData, lazyInternalData] = splitLoggingData({
|
|
2380
|
+
event,
|
|
2381
|
+
internalData
|
|
2382
|
+
});
|
|
2350
2383
|
let partialRecord = {
|
|
2351
2384
|
id: this.id,
|
|
2352
2385
|
span_id: this.spanId,
|
|
@@ -2464,6 +2497,36 @@ var SpanImpl = class _SpanImpl {
|
|
|
2464
2497
|
return this.end(args);
|
|
2465
2498
|
}
|
|
2466
2499
|
};
|
|
2500
|
+
function splitLoggingData({
|
|
2501
|
+
event,
|
|
2502
|
+
internalData
|
|
2503
|
+
}) {
|
|
2504
|
+
const sanitized = validateAndSanitizeExperimentLogPartialArgs(event ?? {});
|
|
2505
|
+
const sanitizedAndInternalData = {};
|
|
2506
|
+
mergeDicts(sanitizedAndInternalData, internalData || {});
|
|
2507
|
+
mergeDicts(sanitizedAndInternalData, sanitized);
|
|
2508
|
+
const serializableInternalData = {};
|
|
2509
|
+
const lazyInternalData = {};
|
|
2510
|
+
for (const [key, value] of Object.entries(sanitizedAndInternalData)) {
|
|
2511
|
+
if (value instanceof BraintrustStream) {
|
|
2512
|
+
const streamCopy = value.copy();
|
|
2513
|
+
lazyInternalData[key] = new LazyValue(async () => {
|
|
2514
|
+
return await new Promise((resolve) => {
|
|
2515
|
+
streamCopy.toReadableStream().pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2516
|
+
});
|
|
2517
|
+
});
|
|
2518
|
+
} else if (value instanceof ReadableStream) {
|
|
2519
|
+
lazyInternalData[key] = new LazyValue(async () => {
|
|
2520
|
+
return await new Promise((resolve) => {
|
|
2521
|
+
value.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
|
|
2522
|
+
});
|
|
2523
|
+
});
|
|
2524
|
+
} else {
|
|
2525
|
+
serializableInternalData[key] = value;
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
return [serializableInternalData, lazyInternalData];
|
|
2529
|
+
}
|
|
2467
2530
|
var Dataset = class extends ObjectFetcher {
|
|
2468
2531
|
constructor(state, lazyMetadata, pinnedVersion, legacy) {
|
|
2469
2532
|
const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
|
|
@@ -2580,7 +2643,7 @@ var Dataset = class extends ObjectFetcher {
|
|
|
2580
2643
|
)}`;
|
|
2581
2644
|
let dataSummary = void 0;
|
|
2582
2645
|
if (summarizeData) {
|
|
2583
|
-
dataSummary = await state.
|
|
2646
|
+
dataSummary = await state.apiConn().get_json(
|
|
2584
2647
|
"dataset-summary",
|
|
2585
2648
|
{
|
|
2586
2649
|
dataset_id: await this.id
|
|
@@ -2686,7 +2749,7 @@ var Prompt = class {
|
|
|
2686
2749
|
if (!prompt) {
|
|
2687
2750
|
throw new Error("Empty prompt");
|
|
2688
2751
|
}
|
|
2689
|
-
const dictArgParsed =
|
|
2752
|
+
const dictArgParsed = z2.record(z2.unknown()).safeParse(buildArgs);
|
|
2690
2753
|
const variables = {
|
|
2691
2754
|
input: buildArgs,
|
|
2692
2755
|
...dictArgParsed.success ? dictArgParsed.data : {}
|
|
@@ -2755,7 +2818,8 @@ function configureBrowser() {
|
|
|
2755
2818
|
|
|
2756
2819
|
// src/functions/invoke.ts
|
|
2757
2820
|
import {
|
|
2758
|
-
INVOKE_API_VERSION
|
|
2821
|
+
INVOKE_API_VERSION,
|
|
2822
|
+
functionIdSchema
|
|
2759
2823
|
} from "@braintrust/core/typespecs";
|
|
2760
2824
|
async function invoke(args) {
|
|
2761
2825
|
const {
|
|
@@ -2764,12 +2828,12 @@ async function invoke(args) {
|
|
|
2764
2828
|
appUrl,
|
|
2765
2829
|
forceLogin,
|
|
2766
2830
|
fetch,
|
|
2767
|
-
|
|
2831
|
+
input,
|
|
2768
2832
|
parent: parentArg,
|
|
2769
2833
|
state: stateArg,
|
|
2770
2834
|
stream,
|
|
2771
2835
|
schema,
|
|
2772
|
-
...
|
|
2836
|
+
...functionIdArgs
|
|
2773
2837
|
} = args;
|
|
2774
2838
|
const state = stateArg ?? _internalGetGlobalState();
|
|
2775
2839
|
await state.login({
|
|
@@ -2778,10 +2842,16 @@ async function invoke(args) {
|
|
|
2778
2842
|
appUrl,
|
|
2779
2843
|
forceLogin
|
|
2780
2844
|
});
|
|
2781
|
-
const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await
|
|
2845
|
+
const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await getSpanParentObject().export();
|
|
2846
|
+
const functionId = functionIdSchema.safeParse(functionIdArgs);
|
|
2847
|
+
if (!functionId.success) {
|
|
2848
|
+
throw new Error(
|
|
2849
|
+
`Invalid function ID arguments: ${functionId.error.message}`
|
|
2850
|
+
);
|
|
2851
|
+
}
|
|
2782
2852
|
const request = {
|
|
2783
|
-
...functionId,
|
|
2784
|
-
|
|
2853
|
+
...functionId.data,
|
|
2854
|
+
input,
|
|
2785
2855
|
parent,
|
|
2786
2856
|
stream,
|
|
2787
2857
|
api_version: INVOKE_API_VERSION
|
|
@@ -3171,6 +3241,7 @@ export {
|
|
|
3171
3241
|
X_CACHED_HEADER,
|
|
3172
3242
|
_internalGetGlobalState,
|
|
3173
3243
|
_internalSetInitialState,
|
|
3244
|
+
braintrustStreamChunkSchema,
|
|
3174
3245
|
createFinalValuePassThroughStream,
|
|
3175
3246
|
currentExperiment,
|
|
3176
3247
|
currentLogger,
|