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/index.mjs CHANGED
@@ -312,29 +312,81 @@ var LazyValue = class {
312
312
  return this.value.hasComputed;
313
313
  }
314
314
  };
315
+ function _urljoin(...parts) {
316
+ return parts.map(
317
+ (x, i) => x.replace(/^\//, "").replace(i < parts.length - 1 ? /\/$/ : "", "")
318
+ ).filter((x) => x.trim() !== "").join("/");
319
+ }
315
320
 
316
321
  // src/logger.ts
317
322
  import Mustache from "mustache";
318
- import { z } from "zod";
323
+ import { z as z2 } from "zod";
319
324
 
320
- // src/stream.ts
325
+ // src/functions/stream.ts
321
326
  import { callEventSchema } from "@braintrust/core/typespecs";
322
327
  import {
323
328
  createParser
324
329
  } from "eventsource-parser";
330
+ import { z } from "zod";
331
+ var braintrustStreamChunkSchema = z.union([
332
+ z.object({
333
+ type: z.literal("text_delta"),
334
+ data: z.string()
335
+ }),
336
+ z.object({
337
+ type: z.literal("json_delta"),
338
+ data: z.string()
339
+ })
340
+ ]);
325
341
  var BraintrustStream = class _BraintrustStream {
326
342
  stream;
343
+ memoizedFinalValue;
327
344
  constructor(baseStream) {
328
345
  this.stream = baseStream.pipeThrough(btStreamParser());
329
346
  }
347
+ /**
348
+ * Copy the stream. This returns a new stream that shares the same underlying
349
+ * stream (via `tee`). Since streams are consumed in Javascript, use `copy()` if you
350
+ * need to use the stream multiple times.
351
+ *
352
+ * @returns A new stream that you can independently consume.
353
+ */
330
354
  copy() {
331
355
  const [newStream, copyStream] = this.stream.tee();
332
356
  this.stream = copyStream;
333
357
  return new _BraintrustStream(newStream);
334
358
  }
359
+ /**
360
+ * Get the underlying ReadableStream.
361
+ *
362
+ * @returns The underlying ReadableStream<BraintrustStreamChunk>.
363
+ */
335
364
  toReadableStream() {
336
365
  return this.stream;
337
366
  }
367
+ /**
368
+ * Get the final value of the stream. The final value is the concatenation of all
369
+ * the chunks in the stream, deserialized into a string or JSON object, depending on
370
+ * the value's type.
371
+ *
372
+ * This function returns a promise that resolves when the stream is closed, and
373
+ * contains the final value. Multiple calls to `finalValue()` will return the same
374
+ * promise, so it is safe to call this multiple times.
375
+ *
376
+ * This function consumes the stream, so if you need to use the stream multiple
377
+ * times, you should call `copy()` first.
378
+ *
379
+ * @returns A promise that resolves with the final value of the stream or `undefined` if the stream is empty.
380
+ */
381
+ finalValue() {
382
+ if (this.memoizedFinalValue) {
383
+ return this.memoizedFinalValue;
384
+ }
385
+ this.memoizedFinalValue = new Promise((resolve, reject2) => {
386
+ const stream = this.stream.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
387
+ });
388
+ return this.memoizedFinalValue;
389
+ }
338
390
  };
339
391
  function btStreamParser() {
340
392
  const decoder = new TextDecoder();
@@ -389,9 +441,17 @@ function createFinalValuePassThroughStream(onFinal) {
389
441
  transform(chunk, controller) {
390
442
  if (typeof chunk === "string") {
391
443
  textChunks.push(chunk);
444
+ controller.enqueue({
445
+ type: "text_delta",
446
+ data: chunk
447
+ });
392
448
  } else if (chunk instanceof Uint8Array) {
393
449
  textChunks.push(decoder.decode(chunk));
394
- } else {
450
+ controller.enqueue({
451
+ type: "text_delta",
452
+ data: decoder.decode(chunk)
453
+ });
454
+ } else if (braintrustStreamChunkSchema.safeParse(chunk).success) {
395
455
  const chunkType = chunk.type;
396
456
  switch (chunkType) {
397
457
  case "text_delta":
@@ -405,6 +465,8 @@ function createFinalValuePassThroughStream(onFinal) {
405
465
  throw new Error(`Unknown chunk type ${_type}`);
406
466
  }
407
467
  controller.enqueue(chunk);
468
+ } else {
469
+ throw new Error(`Unknown chunk type ${chunk}`);
408
470
  }
409
471
  },
410
472
  flush(controller) {
@@ -466,14 +528,14 @@ var NoopSpan = class {
466
528
  }
467
529
  };
468
530
  var NOOP_SPAN = new NoopSpan();
469
- var loginSchema = z.strictObject({
470
- appUrl: z.string(),
471
- appPublicUrl: z.string(),
472
- orgName: z.string(),
473
- logUrl: z.string(),
474
- proxyUrl: z.string(),
475
- loginToken: z.string(),
476
- orgId: z.string().nullish(),
531
+ var loginSchema = z2.strictObject({
532
+ appUrl: z2.string(),
533
+ appPublicUrl: z2.string(),
534
+ orgName: z2.string(),
535
+ apiUrl: z2.string(),
536
+ proxyUrl: z2.string(),
537
+ loginToken: z2.string(),
538
+ orgId: z2.string().nullish(),
477
539
  gitMetadataSettings: gitMetadataSettingsSchema.nullish()
478
540
  });
479
541
  var BraintrustState = class _BraintrustState {
@@ -488,7 +550,7 @@ var BraintrustState = class _BraintrustState {
488
550
  }
489
551
  const defaultGetLogConn = async () => {
490
552
  await this.login({});
491
- return this.logConn();
553
+ return this.apiConn();
492
554
  };
493
555
  this._bgLogger = new BackgroundLogger(new LazyValue(defaultGetLogConn));
494
556
  this.resetLoginInfo();
@@ -499,7 +561,7 @@ var BraintrustState = class _BraintrustState {
499
561
  // (safely) dynamically cast it whenever retrieving the logger.
500
562
  currentLogger;
501
563
  currentSpan;
502
- // Any time we re-log in, we directly update the logConn inside the logger.
564
+ // Any time we re-log in, we directly update the apiConn inside the logger.
503
565
  // This is preferable to replacing the whole logger, which would create the
504
566
  // possibility of multiple loggers floating around, which may not log in a
505
567
  // deterministic order.
@@ -509,13 +571,13 @@ var BraintrustState = class _BraintrustState {
509
571
  loginToken = null;
510
572
  orgId = null;
511
573
  orgName = null;
512
- logUrl = null;
574
+ apiUrl = null;
513
575
  proxyUrl = null;
514
576
  loggedIn = false;
515
577
  gitMetadataSettings;
516
578
  fetch = globalThis.fetch;
579
+ _appConn = null;
517
580
  _apiConn = null;
518
- _logConn = null;
519
581
  _proxyConn = null;
520
582
  resetLoginInfo() {
521
583
  this.appUrl = null;
@@ -523,12 +585,12 @@ var BraintrustState = class _BraintrustState {
523
585
  this.loginToken = null;
524
586
  this.orgId = null;
525
587
  this.orgName = null;
526
- this.logUrl = null;
588
+ this.apiUrl = null;
527
589
  this.proxyUrl = null;
528
590
  this.loggedIn = false;
529
591
  this.gitMetadataSettings = void 0;
592
+ this._appConn = null;
530
593
  this._apiConn = null;
531
- this._logConn = null;
532
594
  this._proxyConn = null;
533
595
  }
534
596
  copyLoginInfo(other) {
@@ -537,12 +599,12 @@ var BraintrustState = class _BraintrustState {
537
599
  this.loginToken = other.loginToken;
538
600
  this.orgId = other.orgId;
539
601
  this.orgName = other.orgName;
540
- this.logUrl = other.logUrl;
602
+ this.apiUrl = other.apiUrl;
541
603
  this.proxyUrl = other.proxyUrl;
542
604
  this.loggedIn = other.loggedIn;
543
605
  this.gitMetadataSettings = other.gitMetadataSettings;
606
+ this._appConn = other._appConn;
544
607
  this._apiConn = other._apiConn;
545
- this._logConn = other._logConn;
546
608
  this._proxyConn = other._proxyConn;
547
609
  }
548
610
  serialize() {
@@ -551,7 +613,7 @@ var BraintrustState = class _BraintrustState {
551
613
  "Cannot serialize BraintrustState without being logged in"
552
614
  );
553
615
  }
554
- if (!this.appUrl || !this.appPublicUrl || !this.logUrl || !this.proxyUrl || !this.orgName || !this.loginToken || !this.loggedIn) {
616
+ if (!this.appUrl || !this.appPublicUrl || !this.apiUrl || !this.proxyUrl || !this.orgName || !this.loginToken || !this.loggedIn) {
555
617
  throw new Error(
556
618
  "Cannot serialize BraintrustState without all login attributes"
557
619
  );
@@ -562,7 +624,7 @@ var BraintrustState = class _BraintrustState {
562
624
  loginToken: this.loginToken,
563
625
  orgId: this.orgId,
564
626
  orgName: this.orgName,
565
- logUrl: this.logUrl,
627
+ apiUrl: this.apiUrl,
566
628
  proxyUrl: this.proxyUrl,
567
629
  gitMetadataSettings: this.gitMetadataSettings
568
630
  };
@@ -583,22 +645,23 @@ var BraintrustState = class _BraintrustState {
583
645
  "Cannot deserialize BraintrustState without a login token"
584
646
  );
585
647
  }
586
- state.logConn().set_token(state.loginToken);
587
- state.logConn().make_long_lived();
588
648
  state.apiConn().set_token(state.loginToken);
649
+ state.apiConn().make_long_lived();
650
+ state.appConn().set_token(state.loginToken);
651
+ state.proxyConn().make_long_lived();
589
652
  state.proxyConn().set_token(state.loginToken);
590
653
  state.loggedIn = true;
591
- state.loginReplaceLogConn(state.logConn());
654
+ state.loginReplaceApiConn(state.apiConn());
592
655
  return state;
593
656
  }
594
657
  setFetch(fetch) {
595
658
  this.loginParams.fetch = fetch;
596
659
  this.fetch = fetch;
597
- this._logConn?.setFetch(fetch);
598
660
  this._apiConn?.setFetch(fetch);
661
+ this._appConn?.setFetch(fetch);
599
662
  }
600
663
  async login(loginParams) {
601
- if (this.logUrl && !loginParams.forceLogin) {
664
+ if (this.apiUrl && !loginParams.forceLogin) {
602
665
  return;
603
666
  }
604
667
  const newState = await loginToState({
@@ -607,23 +670,23 @@ var BraintrustState = class _BraintrustState {
607
670
  });
608
671
  this.copyLoginInfo(newState);
609
672
  }
610
- apiConn() {
611
- if (!this._apiConn) {
673
+ appConn() {
674
+ if (!this._appConn) {
612
675
  if (!this.appUrl) {
613
- throw new Error("Must initialize appUrl before requesting apiConn");
676
+ throw new Error("Must initialize appUrl before requesting appConn");
614
677
  }
615
- this._apiConn = new HTTPConnection(this.appUrl, this.fetch);
678
+ this._appConn = new HTTPConnection(this.appUrl, this.fetch);
616
679
  }
617
- return this._apiConn;
680
+ return this._appConn;
618
681
  }
619
- logConn() {
620
- if (!this._logConn) {
621
- if (!this.logUrl) {
622
- throw new Error("Must initialize logUrl before requesting logConn");
682
+ apiConn() {
683
+ if (!this._apiConn) {
684
+ if (!this.apiUrl) {
685
+ throw new Error("Must initialize apiUrl before requesting apiConn");
623
686
  }
624
- this._logConn = new HTTPConnection(this.logUrl, this.fetch);
687
+ this._apiConn = new HTTPConnection(this.apiUrl, this.fetch);
625
688
  }
626
- return this._logConn;
689
+ return this._apiConn;
627
690
  }
628
691
  proxyConn() {
629
692
  if (!this._proxyConn) {
@@ -638,8 +701,8 @@ var BraintrustState = class _BraintrustState {
638
701
  return this._bgLogger;
639
702
  }
640
703
  // Should only be called by the login function.
641
- loginReplaceLogConn(logConn) {
642
- this._bgLogger.internalReplaceLogConn(logConn);
704
+ loginReplaceApiConn(apiConn) {
705
+ this._bgLogger.internalReplaceApiConn(apiConn);
643
706
  }
644
707
  };
645
708
  var _globalState;
@@ -946,11 +1009,6 @@ var Logger = class {
946
1009
  parentObjectType() {
947
1010
  return SpanObjectTypeV2.PROJECT_LOGS;
948
1011
  }
949
- triggerWaitUntilFlush() {
950
- if (!this.state.bgLogger().syncFlush) {
951
- return waitUntil(this.state.bgLogger().flush());
952
- }
953
- }
954
1012
  /**
955
1013
  * Log a single event. The event will be batched and uploaded behind the scenes if `logOptions.asyncFlush` is true.
956
1014
  *
@@ -976,7 +1034,6 @@ var Logger = class {
976
1034
  this.lastStartTime = span.end();
977
1035
  const ret = span.id;
978
1036
  if (this.asyncFlush === true) {
979
- this.triggerWaitUntilFlush();
980
1037
  return ret;
981
1038
  } else {
982
1039
  return (async () => {
@@ -1004,7 +1061,6 @@ var Logger = class {
1004
1061
  () => span.end()
1005
1062
  );
1006
1063
  if (this.asyncFlush) {
1007
- this.triggerWaitUntilFlush();
1008
1064
  return ret;
1009
1065
  } else {
1010
1066
  return (async () => {
@@ -1084,7 +1140,7 @@ var Logger = class {
1084
1140
  function castLogger(logger, asyncFlush) {
1085
1141
  if (logger === void 0)
1086
1142
  return void 0;
1087
- if (asyncFlush && !!asyncFlush !== !!logger.asyncFlush) {
1143
+ if (asyncFlush !== void 0 && !!asyncFlush !== !!logger.asyncFlush) {
1088
1144
  throw new Error(
1089
1145
  `Asserted asyncFlush setting ${asyncFlush} does not match stored logger's setting ${logger.asyncFlush}`
1090
1146
  );
@@ -1098,7 +1154,7 @@ function now() {
1098
1154
  return (/* @__PURE__ */ new Date()).getTime();
1099
1155
  }
1100
1156
  var BackgroundLogger = class _BackgroundLogger {
1101
- logConn;
1157
+ apiConn;
1102
1158
  items = [];
1103
1159
  activeFlush = Promise.resolve();
1104
1160
  activeFlushResolved = true;
@@ -1116,8 +1172,8 @@ var BackgroundLogger = class _BackgroundLogger {
1116
1172
  numDropped: 0,
1117
1173
  lastLoggedTimestamp: 0
1118
1174
  };
1119
- constructor(logConn) {
1120
- this.logConn = logConn;
1175
+ constructor(apiConn) {
1176
+ this.apiConn = apiConn;
1121
1177
  const syncFlushEnv = Number(isomorph_default.getEnv("BRAINTRUST_SYNC_FLUSH"));
1122
1178
  if (!isNaN(syncFlushEnv)) {
1123
1179
  this.syncFlush = Boolean(syncFlushEnv);
@@ -1263,7 +1319,7 @@ var BackgroundLogger = class _BackgroundLogger {
1263
1319
  return [];
1264
1320
  }
1265
1321
  async submitLogsRequest(items) {
1266
- const conn = await this.logConn.get();
1322
+ const conn = await this.apiConn.get();
1267
1323
  const dataStr = constructLogs3Data(items);
1268
1324
  if (this.allPublishPayloadsDir) {
1269
1325
  await _BackgroundLogger.writePayloadToDir({
@@ -1401,14 +1457,15 @@ Error: ${errorText}`;
1401
1457
  this.activeFlushResolved = true;
1402
1458
  }
1403
1459
  })();
1460
+ waitUntil(this.activeFlush);
1404
1461
  }
1405
1462
  }
1406
1463
  logFailedPayloadsDir() {
1407
1464
  console.warn(`Logging failed payloads to ${this.failedPublishPayloadsDir}`);
1408
1465
  }
1409
1466
  // Should only be called by BraintrustState.
1410
- internalReplaceLogConn(logConn) {
1411
- this.logConn = new LazyValue(async () => logConn);
1467
+ internalReplaceApiConn(apiConn) {
1468
+ this.apiConn = new LazyValue(async () => apiConn);
1412
1469
  }
1413
1470
  };
1414
1471
  function init(projectOrOptions, optionalOptions) {
@@ -1462,7 +1519,7 @@ function init(projectOrOptions, optionalOptions) {
1462
1519
  org_name: state.orgName,
1463
1520
  experiment_name: experiment
1464
1521
  };
1465
- const response = await state.apiConn().post_json("api/experiment/get", args);
1522
+ const response = await state.appConn().post_json("api/experiment/get", args);
1466
1523
  if (response.length === 0) {
1467
1524
  throw new Error(
1468
1525
  `Experiment ${experiment} not found in project ${projectId ?? project}.`
@@ -1543,7 +1600,7 @@ function init(projectOrOptions, optionalOptions) {
1543
1600
  let response = null;
1544
1601
  while (true) {
1545
1602
  try {
1546
- response = await state.apiConn().post_json("api/experiment/register", args);
1603
+ response = await state.appConn().post_json("api/experiment/register", args);
1547
1604
  break;
1548
1605
  } catch (e) {
1549
1606
  if (args["base_experiment"] && `${"data" in e && e.data}`.includes("base experiment")) {
@@ -1649,7 +1706,7 @@ function initDataset(projectOrOptions, optionalOptions) {
1649
1706
  dataset_name: dataset,
1650
1707
  description
1651
1708
  };
1652
- const response = await state.apiConn().post_json("api/dataset/register", args);
1709
+ const response = await state.appConn().post_json("api/dataset/register", args);
1653
1710
  return {
1654
1711
  project: {
1655
1712
  id: response.project.id,
@@ -1679,7 +1736,7 @@ async function computeLoggerMetadata(state, {
1679
1736
  }) {
1680
1737
  const org_id = state.orgId;
1681
1738
  if (isEmpty(project_id)) {
1682
- const response = await state.apiConn().post_json("api/project/register", {
1739
+ const response = await state.appConn().post_json("api/project/register", {
1683
1740
  project_name: project_name || GLOBAL_PROJECT,
1684
1741
  org_id
1685
1742
  });
@@ -1692,7 +1749,7 @@ async function computeLoggerMetadata(state, {
1692
1749
  }
1693
1750
  };
1694
1751
  } else if (isEmpty(project_name)) {
1695
- const response = await state.apiConn().get_json("api/project", {
1752
+ const response = await state.appConn().get_json("api/project", {
1696
1753
  id: project_id
1697
1754
  });
1698
1755
  return {
@@ -1782,7 +1839,7 @@ async function loadPrompt({
1782
1839
  slug,
1783
1840
  version
1784
1841
  };
1785
- const response = await state.logConn().get_json("v1/prompt", args);
1842
+ const response = await state.apiConn().get_json("v1/prompt", args);
1786
1843
  if (!("objects" in response) || response.objects.length === 0) {
1787
1844
  throw new Error(
1788
1845
  `Prompt ${slug} not found in ${[projectName ?? projectId]}`
@@ -1844,7 +1901,7 @@ async function loginToState(options = {}) {
1844
1901
  );
1845
1902
  const info = await resp.json();
1846
1903
  _check_org_info(state, info.org_info, orgName);
1847
- conn = state.logConn();
1904
+ conn = state.apiConn();
1848
1905
  conn.set_token(apiKey);
1849
1906
  } else {
1850
1907
  throw new Error(
@@ -1855,11 +1912,11 @@ async function loginToState(options = {}) {
1855
1912
  throw new Error("Conn should be set at this point (a bug)");
1856
1913
  }
1857
1914
  conn.make_long_lived();
1858
- state.apiConn().set_token(apiKey);
1915
+ state.appConn().set_token(apiKey);
1859
1916
  state.proxyConn().set_token(apiKey);
1860
1917
  state.loginToken = conn.token;
1861
1918
  state.loggedIn = true;
1862
- state.loginReplaceLogConn(conn);
1919
+ state.loginReplaceApiConn(conn);
1863
1920
  return state;
1864
1921
  }
1865
1922
  function log(event) {
@@ -1911,7 +1968,7 @@ function getSpanParentObject(options) {
1911
1968
  return NOOP_SPAN;
1912
1969
  }
1913
1970
  function traced(callback, args) {
1914
- const { span, isLogger } = startSpanAndIsLogger(args);
1971
+ const { span, isSyncFlushLogger } = startSpanAndIsLogger(args);
1915
1972
  const ret = runFinally(
1916
1973
  () => {
1917
1974
  if (args?.setCurrent ?? true) {
@@ -1927,7 +1984,7 @@ function traced(callback, args) {
1927
1984
  } else {
1928
1985
  return (async () => {
1929
1986
  const awaitedRet = await ret;
1930
- if (isLogger) {
1987
+ if (isSyncFlushLogger) {
1931
1988
  await span.flush();
1932
1989
  }
1933
1990
  return awaitedRet;
@@ -2006,14 +2063,19 @@ function startSpanAndIsLogger(args) {
2006
2063
  });
2007
2064
  return {
2008
2065
  span,
2009
- isLogger: components.objectType === SpanObjectTypeV2.PROJECT_LOGS
2066
+ isSyncFlushLogger: components.objectType === SpanObjectTypeV2.PROJECT_LOGS && // Since there's no parent logger here, we're free to choose the async flush
2067
+ // behavior, and therefore propagate along whatever we get from the arguments
2068
+ !args?.asyncFlush
2010
2069
  };
2011
2070
  } else {
2012
2071
  const parentObject = getSpanParentObject({
2013
2072
  asyncFlush: args?.asyncFlush
2014
2073
  });
2015
2074
  const span = parentObject.startSpan(args);
2016
- return { span, isLogger: parentObject.kind === "logger" };
2075
+ return {
2076
+ span,
2077
+ isSyncFlushLogger: parentObject.kind === "logger" && !parentObject.asyncFlush
2078
+ };
2017
2079
  }
2018
2080
  }
2019
2081
  function withCurrent(span, callback, state = _globalState) {
@@ -2027,13 +2089,8 @@ function _check_org_info(state, org_info, org_name) {
2027
2089
  if (org_name === void 0 || org.name === org_name) {
2028
2090
  state.orgId = org.id;
2029
2091
  state.orgName = org.name;
2030
- state.logUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
2092
+ state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
2031
2093
  state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
2032
- if (state.proxyUrl) {
2033
- const url = new URL(state.proxyUrl);
2034
- url.pathname = "";
2035
- state.proxyUrl = url.toString();
2036
- }
2037
2094
  state.gitMetadataSettings = org.git_metadata || void 0;
2038
2095
  break;
2039
2096
  }
@@ -2044,11 +2101,6 @@ function _check_org_info(state, org_info, org_name) {
2044
2101
  );
2045
2102
  }
2046
2103
  }
2047
- function _urljoin(...parts) {
2048
- return parts.map(
2049
- (x, i) => x.replace(/^\//, "").replace(i < parts.length - 1 ? /\/$/ : "", "")
2050
- ).join("/");
2051
- }
2052
2104
  function validateTags(tags) {
2053
2105
  const seen = /* @__PURE__ */ new Set();
2054
2106
  for (const tag of tags) {
@@ -2162,7 +2214,7 @@ var ObjectFetcher = class {
2162
2214
  async fetchedData() {
2163
2215
  if (this._fetchedData === void 0) {
2164
2216
  const state = await this.getState();
2165
- const resp = await state.logConn().get(
2217
+ const resp = await state.apiConn().get(
2166
2218
  `v1/${this.objectType}/${await this.id}/fetch`,
2167
2219
  {
2168
2220
  version: this.pinnedVersion
@@ -2308,7 +2360,7 @@ var Experiment = class extends ObjectFetcher {
2308
2360
  }
2309
2361
  async fetchBaseExperiment() {
2310
2362
  const state = await this.getState();
2311
- const conn = state.apiConn();
2363
+ const conn = state.appConn();
2312
2364
  try {
2313
2365
  const resp = await conn.post("/api/base_experiment/get_id", {
2314
2366
  id: await this.id
@@ -2355,7 +2407,7 @@ var Experiment = class extends ObjectFetcher {
2355
2407
  comparisonExperimentName = baseExperiment.name;
2356
2408
  }
2357
2409
  }
2358
- const results = await state.logConn().get_json(
2410
+ const results = await state.apiConn().get_json(
2359
2411
  "/experiment-comparison2",
2360
2412
  {
2361
2413
  experiment_id: await this.id,
@@ -2543,29 +2595,10 @@ var SpanImpl = class _SpanImpl {
2543
2595
  event,
2544
2596
  internalData
2545
2597
  }) {
2546
- const sanitized = validateAndSanitizeExperimentLogPartialArgs(event ?? {});
2547
- let sanitizedAndInternalData = { ...internalData };
2548
- mergeDicts(sanitizedAndInternalData, sanitized);
2549
- const serializableInternalData = {};
2550
- const lazyInternalData = {};
2551
- for (const [key, value] of Object.entries(sanitizedAndInternalData)) {
2552
- if (value instanceof BraintrustStream) {
2553
- const streamCopy = value.copy();
2554
- lazyInternalData[key] = new LazyValue(async () => {
2555
- return await new Promise((resolve) => {
2556
- streamCopy.toReadableStream().pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
2557
- });
2558
- });
2559
- } else if (value instanceof ReadableStream) {
2560
- lazyInternalData[key] = new LazyValue(async () => {
2561
- return await new Promise((resolve) => {
2562
- value.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
2563
- });
2564
- });
2565
- } else {
2566
- serializableInternalData[key] = value;
2567
- }
2568
- }
2598
+ const [serializableInternalData, lazyInternalData] = splitLoggingData({
2599
+ event,
2600
+ internalData
2601
+ });
2569
2602
  let partialRecord = {
2570
2603
  id: this.id,
2571
2604
  span_id: this.spanId,
@@ -2683,6 +2716,36 @@ var SpanImpl = class _SpanImpl {
2683
2716
  return this.end(args);
2684
2717
  }
2685
2718
  };
2719
+ function splitLoggingData({
2720
+ event,
2721
+ internalData
2722
+ }) {
2723
+ const sanitized = validateAndSanitizeExperimentLogPartialArgs(event ?? {});
2724
+ const sanitizedAndInternalData = {};
2725
+ mergeDicts(sanitizedAndInternalData, internalData || {});
2726
+ mergeDicts(sanitizedAndInternalData, sanitized);
2727
+ const serializableInternalData = {};
2728
+ const lazyInternalData = {};
2729
+ for (const [key, value] of Object.entries(sanitizedAndInternalData)) {
2730
+ if (value instanceof BraintrustStream) {
2731
+ const streamCopy = value.copy();
2732
+ lazyInternalData[key] = new LazyValue(async () => {
2733
+ return await new Promise((resolve) => {
2734
+ streamCopy.toReadableStream().pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
2735
+ });
2736
+ });
2737
+ } else if (value instanceof ReadableStream) {
2738
+ lazyInternalData[key] = new LazyValue(async () => {
2739
+ return await new Promise((resolve) => {
2740
+ value.pipeThrough(createFinalValuePassThroughStream(resolve)).pipeTo(devNullWritableStream());
2741
+ });
2742
+ });
2743
+ } else {
2744
+ serializableInternalData[key] = value;
2745
+ }
2746
+ }
2747
+ return [serializableInternalData, lazyInternalData];
2748
+ }
2686
2749
  var Dataset = class extends ObjectFetcher {
2687
2750
  constructor(state, lazyMetadata, pinnedVersion, legacy) {
2688
2751
  const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
@@ -2799,7 +2862,7 @@ var Dataset = class extends ObjectFetcher {
2799
2862
  )}`;
2800
2863
  let dataSummary = void 0;
2801
2864
  if (summarizeData) {
2802
- dataSummary = await state.logConn().get_json(
2865
+ dataSummary = await state.apiConn().get_json(
2803
2866
  "dataset-summary",
2804
2867
  {
2805
2868
  dataset_id: await this.id
@@ -2905,7 +2968,7 @@ var Prompt = class {
2905
2968
  if (!prompt) {
2906
2969
  throw new Error("Empty prompt");
2907
2970
  }
2908
- const dictArgParsed = z.record(z.unknown()).safeParse(buildArgs);
2971
+ const dictArgParsed = z2.record(z2.unknown()).safeParse(buildArgs);
2909
2972
  const variables = {
2910
2973
  input: buildArgs,
2911
2974
  ...dictArgParsed.success ? dictArgParsed.data : {}
@@ -2969,7 +3032,8 @@ function configureNode() {
2969
3032
 
2970
3033
  // src/functions/invoke.ts
2971
3034
  import {
2972
- INVOKE_API_VERSION
3035
+ INVOKE_API_VERSION,
3036
+ functionIdSchema
2973
3037
  } from "@braintrust/core/typespecs";
2974
3038
  async function invoke(args) {
2975
3039
  const {
@@ -2978,12 +3042,12 @@ async function invoke(args) {
2978
3042
  appUrl,
2979
3043
  forceLogin,
2980
3044
  fetch,
2981
- arg,
3045
+ input,
2982
3046
  parent: parentArg,
2983
3047
  state: stateArg,
2984
3048
  stream,
2985
3049
  schema,
2986
- ...functionId
3050
+ ...functionIdArgs
2987
3051
  } = args;
2988
3052
  const state = stateArg ?? _internalGetGlobalState();
2989
3053
  await state.login({
@@ -2992,10 +3056,16 @@ async function invoke(args) {
2992
3056
  appUrl,
2993
3057
  forceLogin
2994
3058
  });
2995
- const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await currentSpan().export();
3059
+ const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await getSpanParentObject().export();
3060
+ const functionId = functionIdSchema.safeParse(functionIdArgs);
3061
+ if (!functionId.success) {
3062
+ throw new Error(
3063
+ `Invalid function ID arguments: ${functionId.error.message}`
3064
+ );
3065
+ }
2996
3066
  const request = {
2997
- ...functionId,
2998
- arg,
3067
+ ...functionId.data,
3068
+ input,
2999
3069
  parent,
3000
3070
  stream,
3001
3071
  api_version: INVOKE_API_VERSION
@@ -3060,7 +3130,7 @@ var BarProgressReporter = class {
3060
3130
  // src/framework.ts
3061
3131
  import pluralize from "pluralize";
3062
3132
 
3063
- // ../node_modules/.pnpm/async@3.2.5/node_modules/async/dist/async.mjs
3133
+ // ../../node_modules/.pnpm/async@3.2.5/node_modules/async/dist/async.mjs
3064
3134
  function initialParams(fn) {
3065
3135
  return function(...args) {
3066
3136
  var callback = args.pop();
@@ -5175,6 +5245,7 @@ export {
5175
5245
  X_CACHED_HEADER,
5176
5246
  _internalGetGlobalState,
5177
5247
  _internalSetInitialState,
5248
+ braintrustStreamChunkSchema,
5178
5249
  buildLocalSummary,
5179
5250
  createFinalValuePassThroughStream,
5180
5251
  currentExperiment,