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