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.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 import_zod = require("zod");
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
- } else {
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 = import_zod.z.strictObject({
304
- appUrl: import_zod.z.string(),
305
- appPublicUrl: import_zod.z.string(),
306
- orgName: import_zod.z.string(),
307
- logUrl: import_zod.z.string(),
308
- proxyUrl: import_zod.z.string(),
309
- loginToken: import_zod.z.string(),
310
- orgId: import_zod.z.string().nullish(),
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.logConn();
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 logConn inside the logger.
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
- logUrl = null;
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.logUrl = null;
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.logUrl = other.logUrl;
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.logUrl || !this.proxyUrl || !this.orgName || !this.loginToken || !this.loggedIn) {
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
- logUrl: this.logUrl,
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.loginReplaceLogConn(state.logConn());
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.logUrl && !loginParams.forceLogin) {
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
- apiConn() {
445
- if (!this._apiConn) {
508
+ appConn() {
509
+ if (!this._appConn) {
446
510
  if (!this.appUrl) {
447
- throw new Error("Must initialize appUrl before requesting apiConn");
511
+ throw new Error("Must initialize appUrl before requesting appConn");
448
512
  }
449
- this._apiConn = new HTTPConnection(this.appUrl, this.fetch);
513
+ this._appConn = new HTTPConnection(this.appUrl, this.fetch);
450
514
  }
451
- return this._apiConn;
515
+ return this._appConn;
452
516
  }
453
- logConn() {
454
- if (!this._logConn) {
455
- if (!this.logUrl) {
456
- throw new Error("Must initialize logUrl before requesting logConn");
517
+ apiConn() {
518
+ if (!this._apiConn) {
519
+ if (!this.apiUrl) {
520
+ throw new Error("Must initialize apiUrl before requesting apiConn");
457
521
  }
458
- this._logConn = new HTTPConnection(this.logUrl, this.fetch);
522
+ this._apiConn = new HTTPConnection(this.apiUrl, this.fetch);
459
523
  }
460
- return this._logConn;
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
- loginReplaceLogConn(logConn) {
476
- this._bgLogger.internalReplaceLogConn(logConn);
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
- logConn;
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(logConn) {
954
- this.logConn = logConn;
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.logConn.get();
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
- internalReplaceLogConn(logConn) {
1245
- this.logConn = new LazyValue(async () => logConn);
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.apiConn().post_json("api/experiment/get", args);
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.apiConn().post_json("api/experiment/register", args);
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.apiConn().post_json("api/dataset/register", args);
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.apiConn().post_json("api/project/register", {
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.apiConn().get_json("api/project", {
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.logConn().get_json("v1/prompt", args);
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.logConn();
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.apiConn().set_token(apiKey);
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.loginReplaceLogConn(conn);
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, isLogger } = startSpanAndIsLogger(args);
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 (isLogger) {
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
- isLogger: components.objectType === import_core.SpanObjectTypeV2.PROJECT_LOGS
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 { span, isLogger: parentObject.kind === "logger" };
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.logUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
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.logConn().get(
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.apiConn();
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.logConn().get_json(
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 sanitized = validateAndSanitizeExperimentLogPartialArgs(event ?? {});
2381
- let sanitizedAndInternalData = { ...internalData };
2382
- (0, import_core.mergeDicts)(sanitizedAndInternalData, sanitized);
2383
- const serializableInternalData = {};
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.logConn().get_json(
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 = import_zod.z.record(import_zod.z.unknown()).safeParse(buildArgs);
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
- arg,
2882
+ input,
2819
2883
  parent: parentArg,
2820
2884
  state: stateArg,
2821
2885
  stream,
2822
2886
  schema,
2823
- ...functionId
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 currentSpan().export();
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
- arg,
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,