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.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
- } else {
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 = z.strictObject({
251
- appUrl: z.string(),
252
- appPublicUrl: z.string(),
253
- orgName: z.string(),
254
- logUrl: z.string(),
255
- proxyUrl: z.string(),
256
- loginToken: z.string(),
257
- orgId: z.string().nullish(),
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.logConn();
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 logConn inside the logger.
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
- logUrl = null;
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.logUrl = null;
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.logUrl = other.logUrl;
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.logUrl || !this.proxyUrl || !this.orgName || !this.loginToken || !this.loggedIn) {
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
- logUrl: this.logUrl,
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.loginReplaceLogConn(state.logConn());
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.logUrl && !loginParams.forceLogin) {
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
- apiConn() {
392
- if (!this._apiConn) {
454
+ appConn() {
455
+ if (!this._appConn) {
393
456
  if (!this.appUrl) {
394
- throw new Error("Must initialize appUrl before requesting apiConn");
457
+ throw new Error("Must initialize appUrl before requesting appConn");
395
458
  }
396
- this._apiConn = new HTTPConnection(this.appUrl, this.fetch);
459
+ this._appConn = new HTTPConnection(this.appUrl, this.fetch);
397
460
  }
398
- return this._apiConn;
461
+ return this._appConn;
399
462
  }
400
- logConn() {
401
- if (!this._logConn) {
402
- if (!this.logUrl) {
403
- throw new Error("Must initialize logUrl before requesting logConn");
463
+ apiConn() {
464
+ if (!this._apiConn) {
465
+ if (!this.apiUrl) {
466
+ throw new Error("Must initialize apiUrl before requesting apiConn");
404
467
  }
405
- this._logConn = new HTTPConnection(this.logUrl, this.fetch);
468
+ this._apiConn = new HTTPConnection(this.apiUrl, this.fetch);
406
469
  }
407
- return this._logConn;
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
- loginReplaceLogConn(logConn) {
423
- this._bgLogger.internalReplaceLogConn(logConn);
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
- logConn;
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(logConn) {
901
- this.logConn = logConn;
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.logConn.get();
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
- internalReplaceLogConn(logConn) {
1192
- this.logConn = new LazyValue(async () => logConn);
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.apiConn().post_json("api/experiment/get", args);
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.apiConn().post_json("api/experiment/register", args);
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.apiConn().post_json("api/dataset/register", args);
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.apiConn().post_json("api/project/register", {
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.apiConn().get_json("api/project", {
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.logConn().get_json("v1/prompt", args);
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.logConn();
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.apiConn().set_token(apiKey);
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.loginReplaceLogConn(conn);
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, isLogger } = startSpanAndIsLogger(args);
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 (isLogger) {
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
- isLogger: components.objectType === SpanObjectTypeV2.PROJECT_LOGS
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 { span, isLogger: parentObject.kind === "logger" };
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.logUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
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.logConn().get(
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.apiConn();
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.logConn().get_json(
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 sanitized = validateAndSanitizeExperimentLogPartialArgs(event ?? {});
2328
- let sanitizedAndInternalData = { ...internalData };
2329
- mergeDicts(sanitizedAndInternalData, sanitized);
2330
- const serializableInternalData = {};
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.logConn().get_json(
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 = z.record(z.unknown()).safeParse(buildArgs);
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
- arg,
2831
+ input,
2768
2832
  parent: parentArg,
2769
2833
  state: stateArg,
2770
2834
  stream,
2771
2835
  schema,
2772
- ...functionId
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 currentSpan().export();
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
- arg,
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,