braintrust 0.0.135 → 0.0.136

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
@@ -4949,9 +4949,11 @@ var require_pluralize = __commonJS({
4949
4949
  var src_exports = {};
4950
4950
  __export(src_exports, {
4951
4951
  BaseExperiment: () => BaseExperiment,
4952
+ BraintrustState: () => BraintrustState,
4952
4953
  Dataset: () => Dataset,
4953
4954
  Eval: () => Eval,
4954
4955
  Experiment: () => Experiment,
4956
+ LEGACY_CACHED_HEADER: () => LEGACY_CACHED_HEADER,
4955
4957
  LazyValue: () => LazyValue,
4956
4958
  Logger: () => Logger,
4957
4959
  NOOP_SPAN: () => NOOP_SPAN,
@@ -4976,6 +4978,7 @@ __export(src_exports, {
4976
4978
  loadPrompt: () => loadPrompt,
4977
4979
  log: () => log,
4978
4980
  login: () => login,
4981
+ loginToState: () => loginToState,
4979
4982
  newId: () => newId,
4980
4983
  parseCachedHeader: () => parseCachedHeader,
4981
4984
  reportFailures: () => reportFailures,
@@ -13266,8 +13269,8 @@ function tryMakeUuid(s) {
13266
13269
  var ENCODING_VERSION_NUMBER = 1;
13267
13270
  var INVALID_ENCODING_ERRMSG = "SpanComponents string is not properly encoded. This may be due to a version mismatch between the SDK library used to export the span and the library used to decode it. Please make sure you are using the same SDK version across the board";
13268
13271
  var SpanObjectTypeV1 = /* @__PURE__ */ ((SpanObjectTypeV12) => {
13269
- SpanObjectTypeV12[SpanObjectTypeV12["EXPERIMENT"] = 0] = "EXPERIMENT";
13270
- SpanObjectTypeV12[SpanObjectTypeV12["PROJECT_LOGS"] = 1] = "PROJECT_LOGS";
13272
+ SpanObjectTypeV12[SpanObjectTypeV12["EXPERIMENT"] = 1] = "EXPERIMENT";
13273
+ SpanObjectTypeV12[SpanObjectTypeV12["PROJECT_LOGS"] = 2] = "PROJECT_LOGS";
13271
13274
  return SpanObjectTypeV12;
13272
13275
  })(SpanObjectTypeV1 || {});
13273
13276
  var SpanObjectTypeV1EnumSchema = z.nativeEnum(SpanObjectTypeV1);
@@ -13367,9 +13370,9 @@ var SpanComponentsV1 = class _SpanComponentsV1 {
13367
13370
  }
13368
13371
  objectIdFields() {
13369
13372
  switch (this.objectType) {
13370
- case 0:
13371
- return { experiment_id: this.objectId };
13372
13373
  case 1:
13374
+ return { experiment_id: this.objectId };
13375
+ case 2:
13373
13376
  return { project_id: this.objectId, log_id: "g" };
13374
13377
  default:
13375
13378
  throw new Error("Impossible");
@@ -13399,8 +13402,8 @@ var ENCODING_VERSION_NUMBER2 = 2;
13399
13402
  var INVALID_ENCODING_ERRMSG2 = `SpanComponents string is not properly encoded. This library only supports encoding versions up to ${ENCODING_VERSION_NUMBER2}. Please make sure the SDK library used to decode the SpanComponents is at least as new as any library used to encode it.`;
13400
13403
  var INTEGER_ENCODING_NUM_BYTES = 4;
13401
13404
  var SpanObjectTypeV2 = /* @__PURE__ */ ((SpanObjectTypeV22) => {
13402
- SpanObjectTypeV22[SpanObjectTypeV22["EXPERIMENT"] = 0] = "EXPERIMENT";
13403
- SpanObjectTypeV22[SpanObjectTypeV22["PROJECT_LOGS"] = 1] = "PROJECT_LOGS";
13405
+ SpanObjectTypeV22[SpanObjectTypeV22["EXPERIMENT"] = 1] = "EXPERIMENT";
13406
+ SpanObjectTypeV22[SpanObjectTypeV22["PROJECT_LOGS"] = 2] = "PROJECT_LOGS";
13404
13407
  return SpanObjectTypeV22;
13405
13408
  })(SpanObjectTypeV2 || {});
13406
13409
  var SpanObjectTypeV2EnumSchema = z.nativeEnum(SpanObjectTypeV2);
@@ -13571,9 +13574,9 @@ var SpanComponentsV2 = class _SpanComponentsV2 {
13571
13574
  );
13572
13575
  }
13573
13576
  switch (this.objectType) {
13574
- case 0:
13575
- return { experiment_id: this.objectId };
13576
13577
  case 1:
13578
+ return { experiment_id: this.objectId };
13579
+ case 2:
13577
13580
  return { project_id: this.objectId, log_id: "g" };
13578
13581
  default:
13579
13582
  throw new Error("Impossible");
@@ -14005,6 +14008,10 @@ var functionDataSchema = z.union([
14005
14008
  z.strictObject({
14006
14009
  type: z.literal("code"),
14007
14010
  data: codeBundleSchema
14011
+ }),
14012
+ z.strictObject({
14013
+ type: z.literal("global"),
14014
+ name: z.string()
14008
14015
  })
14009
14016
  ]);
14010
14017
  var functionSchema2 = promptSchemaObject.merge(
@@ -14093,8 +14100,6 @@ var aclObjectTypeEnum = z.enum([
14093
14100
  "dataset",
14094
14101
  "prompt",
14095
14102
  "prompt_session",
14096
- "project_score",
14097
- "project_tag",
14098
14103
  "group",
14099
14104
  "role",
14100
14105
  "org_member",
@@ -15526,9 +15531,25 @@ var NoopSpan = class {
15526
15531
  close(args) {
15527
15532
  return this.end(args);
15528
15533
  }
15534
+ setAttributes(_args) {
15535
+ }
15529
15536
  };
15530
15537
  var NOOP_SPAN = new NoopSpan();
15531
15538
  var BraintrustState = class {
15539
+ constructor(loginParams) {
15540
+ this.loginParams = loginParams;
15541
+ this.id = (/* @__PURE__ */ new Date()).toLocaleString();
15542
+ this.currentExperiment = void 0;
15543
+ this.currentLogger = void 0;
15544
+ this.currentSpan = isomorph_default.newAsyncLocalStorage();
15545
+ const defaultGetLogConn = async () => {
15546
+ await this.login({});
15547
+ return this.logConn();
15548
+ };
15549
+ this._bgLogger = new BackgroundLogger(new LazyValue(defaultGetLogConn));
15550
+ this.resetLoginInfo();
15551
+ globalThis.__inherited_braintrust_state = this;
15552
+ }
15532
15553
  id;
15533
15554
  currentExperiment;
15534
15555
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -15539,7 +15560,7 @@ var BraintrustState = class {
15539
15560
  // This is preferable to replacing the whole logger, which would create the
15540
15561
  // possibility of multiple loggers floating around, which may not log in a
15541
15562
  // deterministic order.
15542
- _globalBgLogger;
15563
+ _bgLogger;
15543
15564
  appUrl = null;
15544
15565
  appPublicUrl = null;
15545
15566
  loginToken = null;
@@ -15550,23 +15571,9 @@ var BraintrustState = class {
15550
15571
  gitMetadataSettings;
15551
15572
  _apiConn = null;
15552
15573
  _logConn = null;
15553
- constructor() {
15554
- this.id = v4_default();
15555
- this.currentExperiment = void 0;
15556
- this.currentLogger = void 0;
15557
- this.currentSpan = isomorph_default.newAsyncLocalStorage();
15558
- const defaultGetLogConn = async () => {
15559
- await login();
15560
- return this.logConn();
15561
- };
15562
- this._globalBgLogger = new BackgroundLogger(
15563
- new LazyValue(defaultGetLogConn)
15564
- );
15565
- this.resetLoginInfo();
15566
- globalThis.__inherited_braintrust_state = this;
15567
- }
15568
15574
  resetLoginInfo() {
15569
15575
  this.appUrl = null;
15576
+ this.appPublicUrl = null;
15570
15577
  this.loginToken = null;
15571
15578
  this.orgId = null;
15572
15579
  this.orgName = null;
@@ -15576,6 +15583,28 @@ var BraintrustState = class {
15576
15583
  this._apiConn = null;
15577
15584
  this._logConn = null;
15578
15585
  }
15586
+ copyLoginInfo(other) {
15587
+ this.appUrl = other.appUrl;
15588
+ this.appPublicUrl = other.appPublicUrl;
15589
+ this.loginToken = other.loginToken;
15590
+ this.orgId = other.orgId;
15591
+ this.orgName = other.orgName;
15592
+ this.logUrl = other.logUrl;
15593
+ this.loggedIn = other.loggedIn;
15594
+ this.gitMetadataSettings = other.gitMetadataSettings;
15595
+ this._apiConn = other._apiConn;
15596
+ this._logConn = other._logConn;
15597
+ }
15598
+ async login(loginParams) {
15599
+ if (this.logUrl && !loginParams.forceLogin) {
15600
+ return;
15601
+ }
15602
+ const newState = await loginToState({
15603
+ ...this.loginParams,
15604
+ ...loginParams
15605
+ });
15606
+ this.copyLoginInfo(newState);
15607
+ }
15579
15608
  apiConn() {
15580
15609
  if (!this._apiConn) {
15581
15610
  if (!this.appUrl) {
@@ -15594,22 +15623,24 @@ var BraintrustState = class {
15594
15623
  }
15595
15624
  return this._logConn;
15596
15625
  }
15597
- globalBgLogger() {
15598
- return this._globalBgLogger;
15626
+ bgLogger() {
15627
+ return this._bgLogger;
15599
15628
  }
15600
15629
  // Should only be called by the login function.
15601
15630
  loginReplaceLogConn(logConn) {
15602
- this._globalBgLogger.internalReplaceLogConn(logConn);
15631
+ this._bgLogger.internalReplaceLogConn(logConn);
15603
15632
  }
15604
15633
  };
15605
- var _state;
15634
+ var _globalState;
15606
15635
  function _internalSetInitialState() {
15607
- if (_state) {
15636
+ if (_globalState) {
15608
15637
  throw new Error("Cannot set initial state more than once");
15609
15638
  }
15610
- _state = globalThis.__inherited_braintrust_state || new BraintrustState();
15639
+ _globalState = globalThis.__inherited_braintrust_state || new BraintrustState({
15640
+ /*empty login options*/
15641
+ });
15611
15642
  }
15612
- var _internalGetGlobalState = () => _state;
15643
+ var _internalGetGlobalState = () => _globalState;
15613
15644
  var FailedHTTPResponse = class extends Error {
15614
15645
  status;
15615
15646
  text;
@@ -15730,7 +15761,7 @@ var HTTPConnection = class _HTTPConnection {
15730
15761
  return await resp.json();
15731
15762
  }
15732
15763
  };
15733
- function logFeedbackImpl(parentObjectType, parentObjectId, {
15764
+ function logFeedbackImpl(state, parentObjectType, parentObjectId, {
15734
15765
  id,
15735
15766
  expected,
15736
15767
  scores,
@@ -15773,7 +15804,7 @@ function logFeedbackImpl(parentObjectType, parentObjectId, {
15773
15804
  [IS_MERGE_FIELD]: true
15774
15805
  };
15775
15806
  });
15776
- _state.globalBgLogger().log([record]);
15807
+ state.bgLogger().log([record]);
15777
15808
  }
15778
15809
  if (!isEmpty(comment)) {
15779
15810
  const record = new LazyValue(async () => {
@@ -15793,10 +15824,10 @@ function logFeedbackImpl(parentObjectType, parentObjectId, {
15793
15824
  [AUDIT_METADATA_FIELD]: metadata
15794
15825
  };
15795
15826
  });
15796
- _state.globalBgLogger().log([record]);
15827
+ state.bgLogger().log([record]);
15797
15828
  }
15798
15829
  }
15799
- function spanComponentsToObjectIdLambda(components) {
15830
+ function spanComponentsToObjectIdLambda(state, components) {
15800
15831
  if (components.objectId) {
15801
15832
  const ret = components.objectId;
15802
15833
  return async () => ret;
@@ -15812,8 +15843,9 @@ function spanComponentsToObjectIdLambda(components) {
15812
15843
  "Impossible: computeObjectMetadataArgs not supported for experiments"
15813
15844
  );
15814
15845
  case SpanObjectTypeV2.PROJECT_LOGS:
15815
- const args = components.computeObjectMetadataArgs;
15816
- return async () => (await computeLoggerMetadata(args)).project.id;
15846
+ return async () => (await computeLoggerMetadata(state, {
15847
+ ...components.computeObjectMetadataArgs
15848
+ })).project.id;
15817
15849
  default:
15818
15850
  const x = components.objectType;
15819
15851
  throw new Error(`Unknown object type: ${x}`);
@@ -15832,7 +15864,10 @@ function startSpanParentArgs(args) {
15832
15864
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.objectType}`
15833
15865
  );
15834
15866
  }
15835
- const parentComponentsObjectIdLambda = spanComponentsToObjectIdLambda(parentComponents);
15867
+ const parentComponentsObjectIdLambda = spanComponentsToObjectIdLambda(
15868
+ args.state,
15869
+ parentComponents
15870
+ );
15836
15871
  const computeParentObjectId = async () => {
15837
15872
  const parentComponentsObjectId = await parentComponentsObjectIdLambda();
15838
15873
  if (await args.parentObjectId.get() !== parentComponentsObjectId) {
@@ -15861,6 +15896,7 @@ function startSpanParentArgs(args) {
15861
15896
  };
15862
15897
  }
15863
15898
  var Logger = class {
15899
+ state;
15864
15900
  lazyMetadata;
15865
15901
  _asyncFlush;
15866
15902
  computeMetadataArgs;
@@ -15869,13 +15905,14 @@ var Logger = class {
15869
15905
  calledStartSpan;
15870
15906
  // For type identification.
15871
15907
  kind = "logger";
15872
- constructor(lazyMetadata, logOptions = {}) {
15908
+ constructor(state, lazyMetadata, logOptions = {}) {
15873
15909
  this.lazyMetadata = lazyMetadata;
15874
15910
  this._asyncFlush = logOptions.asyncFlush;
15875
15911
  this.computeMetadataArgs = logOptions.computeMetadataArgs;
15876
15912
  this.lastStartTime = getCurrentUnixTimestamp();
15877
15913
  this.lazyId = new LazyValue(async () => await this.id);
15878
15914
  this.calledStartSpan = false;
15915
+ this.state = state;
15879
15916
  }
15880
15917
  get org_id() {
15881
15918
  return (async () => {
@@ -15967,7 +16004,9 @@ var Logger = class {
15967
16004
  }
15968
16005
  startSpanImpl(args) {
15969
16006
  return new SpanImpl({
16007
+ state: this.state,
15970
16008
  ...startSpanParentArgs({
16009
+ state: this.state,
15971
16010
  parent: args?.parent,
15972
16011
  parentObjectType: this.parentObjectType(),
15973
16012
  parentObjectId: this.lazyId,
@@ -15990,7 +16029,7 @@ var Logger = class {
15990
16029
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
15991
16030
  */
15992
16031
  logFeedback(event) {
15993
- logFeedbackImpl(this.parentObjectType(), this.lazyId, event);
16032
+ logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
15994
16033
  }
15995
16034
  /**
15996
16035
  * Return a serialized representation of the logger that can be used to start subspans in other places. See `Span.start_span` for more details.
@@ -16013,7 +16052,7 @@ var Logger = class {
16013
16052
  * Flush any pending logs to the server.
16014
16053
  */
16015
16054
  async flush() {
16016
- return await _state.globalBgLogger().flush();
16055
+ return await this.state.bgLogger().flush();
16017
16056
  }
16018
16057
  get asyncFlush() {
16019
16058
  return this._asyncFlush;
@@ -16378,29 +16417,27 @@ function init(projectOrOptions, optionalOptions) {
16378
16417
  gitMetadataSettings,
16379
16418
  projectId,
16380
16419
  baseExperimentId,
16381
- repoInfo: repoInfo2
16420
+ repoInfo: repoInfo2,
16421
+ state: stateArg
16382
16422
  } = options;
16383
16423
  if (open && update) {
16384
16424
  throw new Error("Cannot open and update an experiment at the same time");
16385
16425
  }
16426
+ const state = stateArg ?? _globalState;
16386
16427
  if (open) {
16387
16428
  if (isEmpty(experiment)) {
16388
16429
  throw new Error(`Cannot open an experiment without specifying its name`);
16389
16430
  }
16390
16431
  const lazyMetadata2 = new LazyValue(
16391
16432
  async () => {
16392
- await login({
16393
- orgName,
16394
- apiKey,
16395
- appUrl
16396
- });
16433
+ await state.login({ apiKey, appUrl, orgName });
16397
16434
  const args = {
16398
16435
  project_name: project,
16399
16436
  project_id: projectId,
16400
- org_name: _state.orgName,
16437
+ org_name: state.orgName,
16401
16438
  experiment_name: experiment
16402
16439
  };
16403
- const response = await _state.apiConn().post_json("api/experiment/get", args);
16440
+ const response = await state.apiConn().post_json("api/experiment/get", args);
16404
16441
  if (response.length === 0) {
16405
16442
  throw new Error(
16406
16443
  `Experiment ${experiment} not found in project ${projectId ?? project}.`
@@ -16422,20 +16459,17 @@ function init(projectOrOptions, optionalOptions) {
16422
16459
  }
16423
16460
  );
16424
16461
  return new ReadonlyExperiment(
16462
+ stateArg ?? _globalState,
16425
16463
  lazyMetadata2
16426
16464
  );
16427
16465
  }
16428
16466
  const lazyMetadata = new LazyValue(
16429
16467
  async () => {
16430
- await login({
16431
- orgName,
16432
- apiKey,
16433
- appUrl
16434
- });
16468
+ await state.login({ apiKey, appUrl, orgName });
16435
16469
  const args = {
16436
16470
  project_name: project,
16437
16471
  project_id: projectId,
16438
- org_id: _state.orgId,
16472
+ org_id: state.orgId,
16439
16473
  update
16440
16474
  };
16441
16475
  if (experiment) {
@@ -16449,7 +16483,7 @@ function init(projectOrOptions, optionalOptions) {
16449
16483
  return repoInfo2;
16450
16484
  }
16451
16485
  let mergedGitMetadataSettings = {
16452
- ..._state.gitMetadataSettings || {
16486
+ ...state.gitMetadataSettings || {
16453
16487
  collect: "all"
16454
16488
  }
16455
16489
  };
@@ -16484,7 +16518,7 @@ function init(projectOrOptions, optionalOptions) {
16484
16518
  let response = null;
16485
16519
  while (true) {
16486
16520
  try {
16487
- response = await _state.apiConn().post_json("api/experiment/register", args);
16521
+ response = await state.apiConn().post_json("api/experiment/register", args);
16488
16522
  break;
16489
16523
  } catch (e) {
16490
16524
  if (args["base_experiment"] && `${"data" in e && e.data}`.includes("base experiment")) {
@@ -16511,9 +16545,9 @@ function init(projectOrOptions, optionalOptions) {
16511
16545
  };
16512
16546
  }
16513
16547
  );
16514
- const ret = new Experiment(lazyMetadata, dataset);
16548
+ const ret = new Experiment(state, lazyMetadata, dataset);
16515
16549
  if (options.setCurrent ?? true) {
16516
- _state.currentExperiment = ret;
16550
+ state.currentExperiment = ret;
16517
16551
  }
16518
16552
  return ret;
16519
16553
  }
@@ -16568,23 +16602,25 @@ function initDataset(projectOrOptions, optionalOptions) {
16568
16602
  apiKey,
16569
16603
  orgName,
16570
16604
  projectId,
16571
- useOutput: legacy
16605
+ useOutput: legacy,
16606
+ state: stateArg
16572
16607
  } = options;
16608
+ const state = stateArg ?? _globalState;
16573
16609
  const lazyMetadata = new LazyValue(
16574
16610
  async () => {
16575
- await login({
16611
+ await state.login({
16576
16612
  orgName,
16577
16613
  apiKey,
16578
16614
  appUrl
16579
16615
  });
16580
16616
  const args = {
16581
- org_id: _state.orgId,
16617
+ org_id: state.orgId,
16582
16618
  project_name: project,
16583
16619
  project_id: projectId,
16584
16620
  dataset_name: dataset,
16585
16621
  description
16586
16622
  };
16587
- const response = await _state.apiConn().post_json("api/dataset/register", args);
16623
+ const response = await state.apiConn().post_json("api/dataset/register", args);
16588
16624
  return {
16589
16625
  project: {
16590
16626
  id: response.project.id,
@@ -16599,7 +16635,7 @@ function initDataset(projectOrOptions, optionalOptions) {
16599
16635
  };
16600
16636
  }
16601
16637
  );
16602
- return new Dataset(lazyMetadata, version, legacy);
16638
+ return new Dataset(stateArg ?? _globalState, lazyMetadata, version, legacy);
16603
16639
  }
16604
16640
  function withDataset(project, callback, options = {}) {
16605
16641
  console.warn(
@@ -16608,14 +16644,13 @@ function withDataset(project, callback, options = {}) {
16608
16644
  const dataset = initDataset(project, options);
16609
16645
  return callback(dataset);
16610
16646
  }
16611
- async function computeLoggerMetadata({
16647
+ async function computeLoggerMetadata(state, {
16612
16648
  project_name,
16613
16649
  project_id
16614
16650
  }) {
16615
- await login();
16616
- const org_id = _state.orgId;
16617
- if (project_id === void 0) {
16618
- const response = await _state.apiConn().post_json("api/project/register", {
16651
+ const org_id = state.orgId;
16652
+ if (isEmpty(project_id)) {
16653
+ const response = await state.apiConn().post_json("api/project/register", {
16619
16654
  project_name: project_name || GLOBAL_PROJECT,
16620
16655
  org_id
16621
16656
  });
@@ -16627,8 +16662,8 @@ async function computeLoggerMetadata({
16627
16662
  fullInfo: response.project
16628
16663
  }
16629
16664
  };
16630
- } else if (project_name === void 0) {
16631
- const response = await _state.apiConn().get_json("api/project", {
16665
+ } else if (isEmpty(project_name)) {
16666
+ const response = await state.apiConn().get_json("api/project", {
16632
16667
  id: project_id
16633
16668
  });
16634
16669
  return {
@@ -16654,29 +16689,31 @@ function initLogger(options = {}) {
16654
16689
  appUrl,
16655
16690
  apiKey,
16656
16691
  orgName,
16657
- forceLogin
16692
+ forceLogin,
16693
+ state: stateArg
16658
16694
  } = options || {};
16659
16695
  const computeMetadataArgs = {
16660
16696
  project_name: projectName,
16661
16697
  project_id: projectId
16662
16698
  };
16699
+ const state = stateArg ?? _globalState;
16663
16700
  const lazyMetadata = new LazyValue(
16664
16701
  async () => {
16665
- await login({
16702
+ await state.login({
16666
16703
  orgName,
16667
16704
  apiKey,
16668
16705
  appUrl,
16669
16706
  forceLogin
16670
16707
  });
16671
- return computeLoggerMetadata(computeMetadataArgs);
16708
+ return computeLoggerMetadata(state, computeMetadataArgs);
16672
16709
  }
16673
16710
  );
16674
- const ret = new Logger(lazyMetadata, {
16711
+ const ret = new Logger(state, lazyMetadata, {
16675
16712
  asyncFlush,
16676
16713
  computeMetadataArgs
16677
16714
  });
16678
16715
  if (options.setCurrent ?? true) {
16679
- _state.currentLogger = ret;
16716
+ state.currentLogger = ret;
16680
16717
  }
16681
16718
  return ret;
16682
16719
  }
@@ -16689,7 +16726,8 @@ async function loadPrompt({
16689
16726
  noTrace = false,
16690
16727
  appUrl,
16691
16728
  apiKey,
16692
- orgName
16729
+ orgName,
16730
+ state: stateArg
16693
16731
  }) {
16694
16732
  if (isEmpty(projectName) && isEmpty(projectId)) {
16695
16733
  throw new Error("Must specify either projectName or projectId");
@@ -16697,7 +16735,8 @@ async function loadPrompt({
16697
16735
  if (isEmpty(slug)) {
16698
16736
  throw new Error("Must specify slug");
16699
16737
  }
16700
- await login({
16738
+ const state = stateArg ?? _globalState;
16739
+ state.login({
16701
16740
  orgName,
16702
16741
  apiKey,
16703
16742
  appUrl
@@ -16708,7 +16747,7 @@ async function loadPrompt({
16708
16747
  slug,
16709
16748
  version
16710
16749
  };
16711
- const response = await _state.logConn().get_json("v1/prompt", args);
16750
+ const response = await state.logConn().get_json("v1/prompt", args);
16712
16751
  if (!("objects" in response) || response.objects.length === 0) {
16713
16752
  throw new Error(
16714
16753
  `Prompt ${slug} not found in ${[projectName ?? projectId]}`
@@ -16723,7 +16762,7 @@ async function loadPrompt({
16723
16762
  }
16724
16763
  async function login(options = {}) {
16725
16764
  let { forceLogin = false } = options || {};
16726
- if (_state.loggedIn && !forceLogin) {
16765
+ if (_globalState.loggedIn && !forceLogin) {
16727
16766
  let checkUpdatedParam2 = function(varname, arg, orig) {
16728
16767
  if (!isEmpty(arg) && !isEmpty(orig) && arg !== orig) {
16729
16768
  throw new Error(
@@ -16732,28 +16771,32 @@ async function login(options = {}) {
16732
16771
  }
16733
16772
  };
16734
16773
  var checkUpdatedParam = checkUpdatedParam2;
16735
- checkUpdatedParam2("appUrl", options.appUrl, _state.appUrl);
16774
+ checkUpdatedParam2("appUrl", options.appUrl, _globalState.appUrl);
16736
16775
  checkUpdatedParam2(
16737
16776
  "apiKey",
16738
16777
  options.apiKey ? HTTPConnection.sanitize_token(options.apiKey) : void 0,
16739
- _state.loginToken
16778
+ _globalState.loginToken
16740
16779
  );
16741
- checkUpdatedParam2("orgName", options.orgName, _state.orgName);
16742
- return;
16780
+ checkUpdatedParam2("orgName", options.orgName, _globalState.orgName);
16781
+ return _globalState;
16743
16782
  }
16783
+ await _globalState.login(options);
16784
+ }
16785
+ async function loginToState(options = {}) {
16744
16786
  const {
16745
16787
  appUrl = isomorph_default.getEnv("BRAINTRUST_APP_URL") || "https://www.braintrust.dev",
16746
16788
  apiKey = isomorph_default.getEnv("BRAINTRUST_API_KEY"),
16747
16789
  orgName = isomorph_default.getEnv("BRAINTRUST_ORG_NAME")
16748
16790
  } = options || {};
16749
16791
  const appPublicUrl = isomorph_default.getEnv("BRAINTRUST_APP_PUBLIC_URL") || appUrl;
16750
- _state.resetLoginInfo();
16751
- _state.appUrl = appUrl;
16752
- _state.appPublicUrl = appPublicUrl;
16792
+ const state = new BraintrustState(options);
16793
+ state.resetLoginInfo();
16794
+ state.appUrl = appUrl;
16795
+ state.appPublicUrl = appPublicUrl;
16753
16796
  let conn = null;
16754
16797
  if (apiKey !== void 0) {
16755
16798
  const resp = await checkResponse(
16756
- await fetch(_urljoin(_state.appUrl, `/api/apikey/login`), {
16799
+ await fetch(_urljoin(state.appUrl, `/api/apikey/login`), {
16757
16800
  method: "POST",
16758
16801
  headers: {
16759
16802
  "Content-Type": "application/json"
@@ -16764,8 +16807,8 @@ async function login(options = {}) {
16764
16807
  })
16765
16808
  );
16766
16809
  const info = await resp.json();
16767
- _check_org_info(info.org_info, orgName);
16768
- conn = _state.logConn();
16810
+ _check_org_info(state, info.org_info, orgName);
16811
+ conn = state.logConn();
16769
16812
  conn.set_token(apiKey);
16770
16813
  } else {
16771
16814
  throw new Error(
@@ -16776,10 +16819,11 @@ async function login(options = {}) {
16776
16819
  throw new Error("Conn should be set at this point (a bug)");
16777
16820
  }
16778
16821
  conn.make_long_lived();
16779
- _state.apiConn().set_token(apiKey);
16780
- _state.loginToken = conn.token;
16781
- _state.loggedIn = true;
16782
- _state.loginReplaceLogConn(conn);
16822
+ state.apiConn().set_token(apiKey);
16823
+ state.loginToken = conn.token;
16824
+ state.loggedIn = true;
16825
+ state.loginReplaceLogConn(conn);
16826
+ return state;
16783
16827
  }
16784
16828
  function log(event) {
16785
16829
  console.warn(
@@ -16801,17 +16845,21 @@ async function summarize(options = {}) {
16801
16845
  }
16802
16846
  return await e.summarize(options);
16803
16847
  }
16804
- function currentExperiment() {
16805
- return _state.currentExperiment;
16848
+ function currentExperiment(options) {
16849
+ const state = options?.state ?? _globalState;
16850
+ return state.currentExperiment;
16806
16851
  }
16807
16852
  function currentLogger(options) {
16808
- return castLogger(_state.currentLogger, options?.asyncFlush);
16853
+ const state = options?.state ?? _globalState;
16854
+ return castLogger(state.currentLogger, options?.asyncFlush);
16809
16855
  }
16810
- function currentSpan() {
16811
- return _state.currentSpan.getStore() ?? NOOP_SPAN;
16856
+ function currentSpan(options) {
16857
+ const state = options?.state ?? _globalState;
16858
+ return state.currentSpan.getStore() ?? NOOP_SPAN;
16812
16859
  }
16813
16860
  function getSpanParentObject(options) {
16814
- const parentSpan = currentSpan();
16861
+ const state = options?.state ?? _globalState;
16862
+ const parentSpan = currentSpan({ state });
16815
16863
  if (!Object.is(parentSpan, NOOP_SPAN)) {
16816
16864
  return parentSpan;
16817
16865
  }
@@ -16852,10 +16900,12 @@ function traced(callback, args) {
16852
16900
  function startSpan(args) {
16853
16901
  return startSpanAndIsLogger(args).span;
16854
16902
  }
16855
- async function flush() {
16856
- return await _state.globalBgLogger().flush();
16903
+ async function flush(options) {
16904
+ const state = options?.state ?? _globalState;
16905
+ return await state.bgLogger().flush();
16857
16906
  }
16858
16907
  function startSpanAndIsLogger(args) {
16908
+ const state = args?.state ?? _globalState;
16859
16909
  if (args?.parent) {
16860
16910
  const components = SpanComponentsV2.fromStr(args?.parent);
16861
16911
  const parentSpanIds = components.rowIds ? {
@@ -16863,9 +16913,12 @@ function startSpanAndIsLogger(args) {
16863
16913
  rootSpanId: components.rowIds.rootSpanId
16864
16914
  } : void 0;
16865
16915
  const span = new SpanImpl({
16916
+ state,
16866
16917
  ...args,
16867
16918
  parentObjectType: components.objectType,
16868
- parentObjectId: new LazyValue(spanComponentsToObjectIdLambda(components)),
16919
+ parentObjectId: new LazyValue(
16920
+ spanComponentsToObjectIdLambda(state, components)
16921
+ ),
16869
16922
  parentComputeObjectMetadataArgs: components.computeObjectMetadataArgs,
16870
16923
  parentSpanIds
16871
16924
  });
@@ -16881,23 +16934,23 @@ function startSpanAndIsLogger(args) {
16881
16934
  return { span, isLogger: parentObject.kind === "logger" };
16882
16935
  }
16883
16936
  }
16884
- function withCurrent(span, callback) {
16885
- return _state.currentSpan.run(span, () => callback(span));
16937
+ function withCurrent(span, callback, state = _globalState) {
16938
+ return state.currentSpan.run(span, () => callback(span));
16886
16939
  }
16887
- function _check_org_info(org_info, org_name) {
16940
+ function _check_org_info(state, org_info, org_name) {
16888
16941
  if (org_info.length === 0) {
16889
16942
  throw new Error("This user is not part of any organizations.");
16890
16943
  }
16891
16944
  for (const org of org_info) {
16892
16945
  if (org_name === void 0 || org.name === org_name) {
16893
- _state.orgId = org.id;
16894
- _state.orgName = org.name;
16895
- _state.logUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
16896
- _state.gitMetadataSettings = org.git_metadata || void 0;
16946
+ state.orgId = org.id;
16947
+ state.orgName = org.name;
16948
+ state.logUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
16949
+ state.gitMetadataSettings = org.git_metadata || void 0;
16897
16950
  break;
16898
16951
  }
16899
16952
  }
16900
- if (_state.orgId === void 0) {
16953
+ if (state.orgId === void 0) {
16901
16954
  throw new Error(
16902
16955
  `Organization ${org_name} not found. Must be one of ${org_info.map((x) => x.name).join(", ")}`
16903
16956
  );
@@ -17056,15 +17109,17 @@ var Experiment = class extends ObjectFetcher {
17056
17109
  lastStartTime;
17057
17110
  lazyId;
17058
17111
  calledStartSpan;
17112
+ state;
17059
17113
  // For type identification.
17060
17114
  kind = "experiment";
17061
- constructor(lazyMetadata, dataset) {
17115
+ constructor(state, lazyMetadata, dataset) {
17062
17116
  super("experiment", void 0);
17063
17117
  this.lazyMetadata = lazyMetadata;
17064
17118
  this.dataset = dataset;
17065
17119
  this.lastStartTime = getCurrentUnixTimestamp();
17066
17120
  this.lazyId = new LazyValue(async () => await this.id);
17067
17121
  this.calledStartSpan = false;
17122
+ this.state = state;
17068
17123
  }
17069
17124
  get id() {
17070
17125
  return (async () => {
@@ -17086,7 +17141,7 @@ var Experiment = class extends ObjectFetcher {
17086
17141
  }
17087
17142
  async getState() {
17088
17143
  await this.lazyMetadata.get();
17089
- return _state;
17144
+ return this.state;
17090
17145
  }
17091
17146
  /**
17092
17147
  * Log a single event to the experiment. The event will be batched and uploaded behind the scenes.
@@ -17148,7 +17203,9 @@ var Experiment = class extends ObjectFetcher {
17148
17203
  }
17149
17204
  startSpanImpl(args) {
17150
17205
  return new SpanImpl({
17206
+ state: this.state,
17151
17207
  ...startSpanParentArgs({
17208
+ state: this.state,
17152
17209
  parent: args?.parent,
17153
17210
  parentObjectType: this.parentObjectType(),
17154
17211
  parentObjectId: this.lazyId,
@@ -17242,7 +17299,7 @@ var Experiment = class extends ObjectFetcher {
17242
17299
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
17243
17300
  */
17244
17301
  logFeedback(event) {
17245
- logFeedbackImpl(this.parentObjectType(), this.lazyId, event);
17302
+ logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
17246
17303
  }
17247
17304
  /**
17248
17305
  * Return a serialized representation of the experiment that can be used to start subspans in other places. See `Span.start_span` for more details.
@@ -17257,7 +17314,7 @@ var Experiment = class extends ObjectFetcher {
17257
17314
  * Flush any pending rows to the server.
17258
17315
  */
17259
17316
  async flush() {
17260
- return await _state.globalBgLogger().flush();
17317
+ return await this.state.bgLogger().flush();
17261
17318
  }
17262
17319
  /**
17263
17320
  * This function is deprecated. You can simply remove it from your code.
@@ -17270,8 +17327,9 @@ var Experiment = class extends ObjectFetcher {
17270
17327
  }
17271
17328
  };
17272
17329
  var ReadonlyExperiment = class extends ObjectFetcher {
17273
- constructor(lazyMetadata) {
17330
+ constructor(state, lazyMetadata) {
17274
17331
  super("experiment", void 0);
17332
+ this.state = state;
17275
17333
  this.lazyMetadata = lazyMetadata;
17276
17334
  }
17277
17335
  get id() {
@@ -17286,7 +17344,7 @@ var ReadonlyExperiment = class extends ObjectFetcher {
17286
17344
  }
17287
17345
  async getState() {
17288
17346
  await this.lazyMetadata.get();
17289
- return _state;
17347
+ return this.state;
17290
17348
  }
17291
17349
  async *asDataset() {
17292
17350
  const records = this.fetch();
@@ -17316,9 +17374,9 @@ function newId() {
17316
17374
  return v4_default();
17317
17375
  }
17318
17376
  var SpanImpl = class _SpanImpl {
17377
+ state;
17319
17378
  // `internalData` contains fields that are not part of the "user-sanitized"
17320
17379
  // set of fields which we want to log in just one of the span rows.
17321
- internalData;
17322
17380
  isMerge;
17323
17381
  loggedEndTime;
17324
17382
  // For internal use only.
@@ -17331,6 +17389,7 @@ var SpanImpl = class _SpanImpl {
17331
17389
  spanParents;
17332
17390
  kind = "span";
17333
17391
  constructor(args) {
17392
+ this.state = args.state;
17334
17393
  const spanAttributes = args.spanAttributes ?? {};
17335
17394
  const event = args.event ?? {};
17336
17395
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -17353,7 +17412,7 @@ var SpanImpl = class _SpanImpl {
17353
17412
  }
17354
17413
  return "subspan";
17355
17414
  })();
17356
- this.internalData = {
17415
+ const internalData = {
17357
17416
  metrics: {
17358
17417
  start: args.startTime ?? getCurrentUnixTimestamp()
17359
17418
  },
@@ -17377,17 +17436,25 @@ var SpanImpl = class _SpanImpl {
17377
17436
  }
17378
17437
  this.isMerge = false;
17379
17438
  const { id: _id, ...eventRest } = event;
17380
- this.log(eventRest);
17439
+ this.logInternal({ event: eventRest, internalData });
17381
17440
  this.isMerge = true;
17382
17441
  }
17383
17442
  get id() {
17384
17443
  return this._id;
17385
17444
  }
17445
+ setAttributes(args) {
17446
+ this.logInternal({ internalData: { span_attributes: args } });
17447
+ }
17386
17448
  log(event) {
17387
- const sanitized = validateAndSanitizeExperimentLogPartialArgs(event);
17388
- let sanitizedAndInternalData = { ...this.internalData };
17449
+ this.logInternal({ event });
17450
+ }
17451
+ logInternal({
17452
+ event,
17453
+ internalData
17454
+ }) {
17455
+ const sanitized = validateAndSanitizeExperimentLogPartialArgs(event ?? {});
17456
+ let sanitizedAndInternalData = { ...internalData };
17389
17457
  mergeDicts(sanitizedAndInternalData, sanitized);
17390
- this.internalData = {};
17391
17458
  let partialRecord = {
17392
17459
  id: this.id,
17393
17460
  span_id: this.spanId,
@@ -17411,10 +17478,10 @@ var SpanImpl = class _SpanImpl {
17411
17478
  objectId: await this.parentObjectId.get()
17412
17479
  }).objectIdFields()
17413
17480
  });
17414
- _state.globalBgLogger().log([new LazyValue(computeRecord)]);
17481
+ this.state.bgLogger().log([new LazyValue(computeRecord)]);
17415
17482
  }
17416
17483
  logFeedback(event) {
17417
- logFeedbackImpl(this.parentObjectType, this.parentObjectId, {
17484
+ logFeedbackImpl(this.state, this.parentObjectType, this.parentObjectId, {
17418
17485
  ...event,
17419
17486
  id: this.id
17420
17487
  });
@@ -17436,8 +17503,10 @@ var SpanImpl = class _SpanImpl {
17436
17503
  startSpan(args) {
17437
17504
  const parentSpanIds = args?.parent ? void 0 : { spanId: this.spanId, rootSpanId: this.rootSpanId };
17438
17505
  return new _SpanImpl({
17506
+ state: this.state,
17439
17507
  ...args,
17440
17508
  ...startSpanParentArgs({
17509
+ state: this.state,
17441
17510
  parent: args?.parent,
17442
17511
  parentObjectType: this.parentObjectType,
17443
17512
  parentObjectId: this.parentObjectId,
@@ -17448,13 +17517,14 @@ var SpanImpl = class _SpanImpl {
17448
17517
  }
17449
17518
  end(args) {
17450
17519
  let endTime;
17520
+ let internalData = {};
17451
17521
  if (!this.loggedEndTime) {
17452
17522
  endTime = args?.endTime ?? getCurrentUnixTimestamp();
17453
- this.internalData = { metrics: { end: endTime } };
17523
+ internalData = { metrics: { end: endTime } };
17454
17524
  } else {
17455
17525
  endTime = this.loggedEndTime;
17456
17526
  }
17457
- this.log({});
17527
+ this.logInternal({ internalData });
17458
17528
  return endTime;
17459
17529
  }
17460
17530
  async export() {
@@ -17477,15 +17547,14 @@ var SpanImpl = class _SpanImpl {
17477
17547
  }).toStr();
17478
17548
  }
17479
17549
  async flush() {
17480
- return await _state.globalBgLogger().flush();
17550
+ return await this.state.bgLogger().flush();
17481
17551
  }
17482
17552
  close(args) {
17483
17553
  return this.end(args);
17484
17554
  }
17485
17555
  };
17486
17556
  var Dataset = class extends ObjectFetcher {
17487
- lazyMetadata;
17488
- constructor(lazyMetadata, pinnedVersion, legacy) {
17557
+ constructor(state, lazyMetadata, pinnedVersion, legacy) {
17489
17558
  const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
17490
17559
  if (isLegacyDataset) {
17491
17560
  console.warn(
@@ -17497,8 +17566,10 @@ var Dataset = class extends ObjectFetcher {
17497
17566
  pinnedVersion,
17498
17567
  (r) => ensureDatasetRecord(r, isLegacyDataset)
17499
17568
  );
17569
+ this.state = state;
17500
17570
  this.lazyMetadata = lazyMetadata;
17501
17571
  }
17572
+ lazyMetadata;
17502
17573
  get id() {
17503
17574
  return (async () => {
17504
17575
  return (await this.lazyMetadata.get()).dataset.id;
@@ -17516,7 +17587,7 @@ var Dataset = class extends ObjectFetcher {
17516
17587
  }
17517
17588
  async getState() {
17518
17589
  await this.lazyMetadata.get();
17519
- return _state;
17590
+ return this.state;
17520
17591
  }
17521
17592
  /**
17522
17593
  * Insert a single record to the dataset. The record will be batched and uploaded behind the scenes. If you pass in an `id`,
@@ -17567,7 +17638,7 @@ var Dataset = class extends ObjectFetcher {
17567
17638
  created: (/* @__PURE__ */ new Date()).toISOString(),
17568
17639
  metadata
17569
17640
  }));
17570
- _state.globalBgLogger().log([args]);
17641
+ this.state.bgLogger().log([args]);
17571
17642
  return rowId;
17572
17643
  }
17573
17644
  delete(id) {
@@ -17577,7 +17648,7 @@ var Dataset = class extends ObjectFetcher {
17577
17648
  created: (/* @__PURE__ */ new Date()).toISOString(),
17578
17649
  _object_delete: true
17579
17650
  }));
17580
- _state.globalBgLogger().log([args]);
17651
+ this.state.bgLogger().log([args]);
17581
17652
  return id;
17582
17653
  }
17583
17654
  /**
@@ -17618,7 +17689,7 @@ var Dataset = class extends ObjectFetcher {
17618
17689
  * Flush any pending rows to the server.
17619
17690
  */
17620
17691
  async flush() {
17621
- return await _state.globalBgLogger().flush();
17692
+ return await this.state.bgLogger().flush();
17622
17693
  }
17623
17694
  /**
17624
17695
  * This function is deprecated. You can simply remove it from your code.
@@ -17703,13 +17774,18 @@ var Prompt = class {
17703
17774
  if (!prompt) {
17704
17775
  throw new Error("Empty prompt");
17705
17776
  }
17777
+ const dictArgParsed = z.record(z.unknown()).safeParse(buildArgs);
17778
+ const variables = {
17779
+ input: buildArgs,
17780
+ ...dictArgParsed.success ? dictArgParsed.data : {}
17781
+ };
17706
17782
  if (flavor === "chat") {
17707
17783
  if (prompt.type !== "chat") {
17708
17784
  throw new Error(
17709
17785
  "Prompt is a completion prompt. Use buildCompletion() instead"
17710
17786
  );
17711
17787
  }
17712
- const render3 = (template) => mustache_default.render(template, buildArgs, void 0, {
17788
+ const render3 = (template) => mustache_default.render(template, variables, void 0, {
17713
17789
  escape: (v) => typeof v === "string" ? v : JSON.stringify(v)
17714
17790
  });
17715
17791
  const messages = (prompt.messages || []).map((m) => ({
@@ -17724,7 +17800,7 @@ var Prompt = class {
17724
17800
  messages,
17725
17801
  ...prompt.tools ? {
17726
17802
  tools: toolsSchema.parse(
17727
- JSON.parse(mustache_default.render(prompt.tools, buildArgs))
17803
+ JSON.parse(mustache_default.render(prompt.tools, variables))
17728
17804
  )
17729
17805
  } : void 0
17730
17806
  };
@@ -17735,7 +17811,7 @@ var Prompt = class {
17735
17811
  return {
17736
17812
  ...params,
17737
17813
  ...spanInfo,
17738
- prompt: mustache_default.render(prompt.content, buildArgs)
17814
+ prompt: mustache_default.render(prompt.content, variables)
17739
17815
  };
17740
17816
  } else {
17741
17817
  throw new Error("never!");
@@ -17812,8 +17888,9 @@ function makeEvalName(projectName, experimentName) {
17812
17888
  }
17813
17889
  return out;
17814
17890
  }
17815
- function initExperiment2(projectName, options = {}) {
17816
- return init(projectName, {
17891
+ function initExperiment2(state, options = {}) {
17892
+ return init({
17893
+ state,
17817
17894
  ...options,
17818
17895
  setCurrent: false
17819
17896
  });
@@ -17851,7 +17928,8 @@ async function Eval(name, evaluator, reporter) {
17851
17928
  }
17852
17929
  const resolvedReporter = reporter || defaultReporter;
17853
17930
  try {
17854
- const experiment = initExperiment2(name, {
17931
+ const experiment = initExperiment2(evaluator.state, {
17932
+ ...evaluator.projectId ? { projectId: evaluator.projectId } : { project: name },
17855
17933
  experiment: evaluator.experimentName,
17856
17934
  metadata: evaluator.metadata,
17857
17935
  isPublic: evaluator.isPublic,
@@ -17950,7 +18028,8 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
17950
18028
  }
17951
18029
  name = baseExperiment.name;
17952
18030
  }
17953
- dataResult = initExperiment2(evaluator.projectName, {
18031
+ dataResult = initExperiment2(evaluator.state, {
18032
+ ...evaluator.projectId ? { projectId: evaluator.projectId } : { project: evaluator.projectName },
17954
18033
  experiment: name,
17955
18034
  open: true
17956
18035
  }).asDataset();
@@ -18370,20 +18449,29 @@ function wrapBetaChatCompletion(completion) {
18370
18449
  return ret;
18371
18450
  };
18372
18451
  }
18373
- var X_CACHED_HEADER = "x-cached";
18452
+ var LEGACY_CACHED_HEADER = "x-cached";
18453
+ var X_CACHED_HEADER = "x-bt-cached";
18374
18454
  function parseCachedHeader(value) {
18375
- return isEmpty(value) ? void 0 : value.toLowerCase() === "true" ? 1 : 0;
18455
+ return isEmpty(value) ? void 0 : ["true", "hit"].includes(value.toLowerCase()) ? 1 : 0;
18376
18456
  }
18377
18457
  function logHeaders(response, span) {
18378
18458
  const cachedHeader = response.headers.get(X_CACHED_HEADER);
18379
18459
  if (isEmpty(cachedHeader)) {
18380
- return;
18381
- }
18382
- span.log({
18383
- metrics: {
18384
- cached: parseCachedHeader(cachedHeader)
18460
+ const legacyCacheHeader = response.headers.get(LEGACY_CACHED_HEADER);
18461
+ if (!isEmpty(legacyCacheHeader)) {
18462
+ span.log({
18463
+ metrics: {
18464
+ cached: parseCachedHeader(legacyCacheHeader)
18465
+ }
18466
+ });
18385
18467
  }
18386
- });
18468
+ } else {
18469
+ span.log({
18470
+ metrics: {
18471
+ cached: parseCachedHeader(cachedHeader)
18472
+ }
18473
+ });
18474
+ }
18387
18475
  }
18388
18476
  function wrapChatCompletion(completion) {
18389
18477
  return async (allParams, options) => {
@@ -18503,7 +18591,16 @@ function postprocessStreamingResults(allResults) {
18503
18591
  let content = void 0;
18504
18592
  let tool_calls = void 0;
18505
18593
  let finish_reason = void 0;
18594
+ let metrics = {};
18506
18595
  for (const result of allResults) {
18596
+ if (result.usage) {
18597
+ metrics = {
18598
+ ...metrics,
18599
+ tokens: result.usage.total_tokens,
18600
+ prompt_tokens: result.usage.prompt_tokens,
18601
+ completion_tokens: result.usage.completion_tokens
18602
+ };
18603
+ }
18507
18604
  const delta = result.choices?.[0]?.delta;
18508
18605
  if (!delta) {
18509
18606
  continue;
@@ -18531,18 +18628,21 @@ function postprocessStreamingResults(allResults) {
18531
18628
  }
18532
18629
  }
18533
18630
  }
18534
- return [
18535
- {
18536
- index: 0,
18537
- message: {
18538
- role,
18539
- content,
18540
- tool_calls
18541
- },
18542
- logprobs: null,
18543
- finish_reason
18544
- }
18545
- ];
18631
+ return {
18632
+ metrics,
18633
+ output: [
18634
+ {
18635
+ index: 0,
18636
+ message: {
18637
+ role,
18638
+ content,
18639
+ tool_calls
18640
+ },
18641
+ logprobs: null,
18642
+ finish_reason
18643
+ }
18644
+ ]
18645
+ };
18546
18646
  }
18547
18647
  var WrapperStream = class {
18548
18648
  span;
@@ -18571,7 +18671,7 @@ var WrapperStream = class {
18571
18671
  yield item;
18572
18672
  }
18573
18673
  this.span.log({
18574
- output: postprocessStreamingResults(allResults)
18674
+ ...postprocessStreamingResults(allResults)
18575
18675
  });
18576
18676
  } finally {
18577
18677
  this.span.end();
@@ -18631,7 +18731,7 @@ var BraintrustLanguageModelWrapper = class {
18631
18731
  prompt_tokens: ret.usage?.promptTokens,
18632
18732
  completion_tokens: ret.usage?.completionTokens,
18633
18733
  cached: parseCachedHeader(
18634
- ret.rawResponse?.headers?.[X_CACHED_HEADER]
18734
+ ret.rawResponse?.headers?.[X_CACHED_HEADER] ?? ret.rawResponse?.headers?.[LEGACY_CACHED_HEADER]
18635
18735
  )
18636
18736
  }
18637
18737
  });
@@ -18725,7 +18825,7 @@ var BraintrustLanguageModelWrapper = class {
18725
18825
  prompt_tokens: usage?.promptTokens,
18726
18826
  completion_tokens: usage?.completionTokens,
18727
18827
  cached: parseCachedHeader(
18728
- ret.rawResponse?.headers?.[X_CACHED_HEADER]
18828
+ ret.rawResponse?.headers?.[X_CACHED_HEADER] ?? ret.rawResponse?.headers?.[LEGACY_CACHED_HEADER]
18729
18829
  )
18730
18830
  }
18731
18831
  });
@@ -18762,9 +18862,11 @@ configureNode();
18762
18862
  // Annotate the CommonJS export names for ESM import in node:
18763
18863
  0 && (module.exports = {
18764
18864
  BaseExperiment,
18865
+ BraintrustState,
18765
18866
  Dataset,
18766
18867
  Eval,
18767
18868
  Experiment,
18869
+ LEGACY_CACHED_HEADER,
18768
18870
  LazyValue,
18769
18871
  Logger,
18770
18872
  NOOP_SPAN,
@@ -18789,6 +18891,7 @@ configureNode();
18789
18891
  loadPrompt,
18790
18892
  log,
18791
18893
  login,
18894
+ loginToState,
18792
18895
  newId,
18793
18896
  parseCachedHeader,
18794
18897
  reportFailures,