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/browser.js CHANGED
@@ -5461,8 +5461,8 @@ function tryMakeUuid(s) {
5461
5461
  var ENCODING_VERSION_NUMBER = 1;
5462
5462
  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";
5463
5463
  var SpanObjectTypeV1 = /* @__PURE__ */ ((SpanObjectTypeV12) => {
5464
- SpanObjectTypeV12[SpanObjectTypeV12["EXPERIMENT"] = 0] = "EXPERIMENT";
5465
- SpanObjectTypeV12[SpanObjectTypeV12["PROJECT_LOGS"] = 1] = "PROJECT_LOGS";
5464
+ SpanObjectTypeV12[SpanObjectTypeV12["EXPERIMENT"] = 1] = "EXPERIMENT";
5465
+ SpanObjectTypeV12[SpanObjectTypeV12["PROJECT_LOGS"] = 2] = "PROJECT_LOGS";
5466
5466
  return SpanObjectTypeV12;
5467
5467
  })(SpanObjectTypeV1 || {});
5468
5468
  var SpanObjectTypeV1EnumSchema = z.nativeEnum(SpanObjectTypeV1);
@@ -5562,9 +5562,9 @@ var SpanComponentsV1 = class _SpanComponentsV1 {
5562
5562
  }
5563
5563
  objectIdFields() {
5564
5564
  switch (this.objectType) {
5565
- case 0:
5566
- return { experiment_id: this.objectId };
5567
5565
  case 1:
5566
+ return { experiment_id: this.objectId };
5567
+ case 2:
5568
5568
  return { project_id: this.objectId, log_id: "g" };
5569
5569
  default:
5570
5570
  throw new Error("Impossible");
@@ -5594,8 +5594,8 @@ var ENCODING_VERSION_NUMBER2 = 2;
5594
5594
  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.`;
5595
5595
  var INTEGER_ENCODING_NUM_BYTES = 4;
5596
5596
  var SpanObjectTypeV2 = /* @__PURE__ */ ((SpanObjectTypeV22) => {
5597
- SpanObjectTypeV22[SpanObjectTypeV22["EXPERIMENT"] = 0] = "EXPERIMENT";
5598
- SpanObjectTypeV22[SpanObjectTypeV22["PROJECT_LOGS"] = 1] = "PROJECT_LOGS";
5597
+ SpanObjectTypeV22[SpanObjectTypeV22["EXPERIMENT"] = 1] = "EXPERIMENT";
5598
+ SpanObjectTypeV22[SpanObjectTypeV22["PROJECT_LOGS"] = 2] = "PROJECT_LOGS";
5599
5599
  return SpanObjectTypeV22;
5600
5600
  })(SpanObjectTypeV2 || {});
5601
5601
  var SpanObjectTypeV2EnumSchema = z.nativeEnum(SpanObjectTypeV2);
@@ -5766,9 +5766,9 @@ var SpanComponentsV2 = class _SpanComponentsV2 {
5766
5766
  );
5767
5767
  }
5768
5768
  switch (this.objectType) {
5769
- case 0:
5770
- return { experiment_id: this.objectId };
5771
5769
  case 1:
5770
+ return { experiment_id: this.objectId };
5771
+ case 2:
5772
5772
  return { project_id: this.objectId, log_id: "g" };
5773
5773
  default:
5774
5774
  throw new Error("Impossible");
@@ -6200,6 +6200,10 @@ var functionDataSchema = z.union([
6200
6200
  z.strictObject({
6201
6201
  type: z.literal("code"),
6202
6202
  data: codeBundleSchema
6203
+ }),
6204
+ z.strictObject({
6205
+ type: z.literal("global"),
6206
+ name: z.string()
6203
6207
  })
6204
6208
  ]);
6205
6209
  var functionSchema2 = promptSchemaObject.merge(
@@ -6288,8 +6292,6 @@ var aclObjectTypeEnum = z.enum([
6288
6292
  "dataset",
6289
6293
  "prompt",
6290
6294
  "prompt_session",
6291
- "project_score",
6292
- "project_tag",
6293
6295
  "group",
6294
6296
  "role",
6295
6297
  "org_member",
@@ -7721,9 +7723,25 @@ var NoopSpan = class {
7721
7723
  close(args) {
7722
7724
  return this.end(args);
7723
7725
  }
7726
+ setAttributes(_args) {
7727
+ }
7724
7728
  };
7725
7729
  var NOOP_SPAN = new NoopSpan();
7726
7730
  var BraintrustState = class {
7731
+ constructor(loginParams) {
7732
+ this.loginParams = loginParams;
7733
+ this.id = (/* @__PURE__ */ new Date()).toLocaleString();
7734
+ this.currentExperiment = void 0;
7735
+ this.currentLogger = void 0;
7736
+ this.currentSpan = isomorph_default.newAsyncLocalStorage();
7737
+ const defaultGetLogConn = async () => {
7738
+ await this.login({});
7739
+ return this.logConn();
7740
+ };
7741
+ this._bgLogger = new BackgroundLogger(new LazyValue(defaultGetLogConn));
7742
+ this.resetLoginInfo();
7743
+ globalThis.__inherited_braintrust_state = this;
7744
+ }
7727
7745
  id;
7728
7746
  currentExperiment;
7729
7747
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -7734,7 +7752,7 @@ var BraintrustState = class {
7734
7752
  // This is preferable to replacing the whole logger, which would create the
7735
7753
  // possibility of multiple loggers floating around, which may not log in a
7736
7754
  // deterministic order.
7737
- _globalBgLogger;
7755
+ _bgLogger;
7738
7756
  appUrl = null;
7739
7757
  appPublicUrl = null;
7740
7758
  loginToken = null;
@@ -7745,23 +7763,9 @@ var BraintrustState = class {
7745
7763
  gitMetadataSettings;
7746
7764
  _apiConn = null;
7747
7765
  _logConn = null;
7748
- constructor() {
7749
- this.id = v4_default();
7750
- this.currentExperiment = void 0;
7751
- this.currentLogger = void 0;
7752
- this.currentSpan = isomorph_default.newAsyncLocalStorage();
7753
- const defaultGetLogConn = async () => {
7754
- await login();
7755
- return this.logConn();
7756
- };
7757
- this._globalBgLogger = new BackgroundLogger(
7758
- new LazyValue(defaultGetLogConn)
7759
- );
7760
- this.resetLoginInfo();
7761
- globalThis.__inherited_braintrust_state = this;
7762
- }
7763
7766
  resetLoginInfo() {
7764
7767
  this.appUrl = null;
7768
+ this.appPublicUrl = null;
7765
7769
  this.loginToken = null;
7766
7770
  this.orgId = null;
7767
7771
  this.orgName = null;
@@ -7771,6 +7775,28 @@ var BraintrustState = class {
7771
7775
  this._apiConn = null;
7772
7776
  this._logConn = null;
7773
7777
  }
7778
+ copyLoginInfo(other) {
7779
+ this.appUrl = other.appUrl;
7780
+ this.appPublicUrl = other.appPublicUrl;
7781
+ this.loginToken = other.loginToken;
7782
+ this.orgId = other.orgId;
7783
+ this.orgName = other.orgName;
7784
+ this.logUrl = other.logUrl;
7785
+ this.loggedIn = other.loggedIn;
7786
+ this.gitMetadataSettings = other.gitMetadataSettings;
7787
+ this._apiConn = other._apiConn;
7788
+ this._logConn = other._logConn;
7789
+ }
7790
+ async login(loginParams) {
7791
+ if (this.logUrl && !loginParams.forceLogin) {
7792
+ return;
7793
+ }
7794
+ const newState = await loginToState({
7795
+ ...this.loginParams,
7796
+ ...loginParams
7797
+ });
7798
+ this.copyLoginInfo(newState);
7799
+ }
7774
7800
  apiConn() {
7775
7801
  if (!this._apiConn) {
7776
7802
  if (!this.appUrl) {
@@ -7789,22 +7815,24 @@ var BraintrustState = class {
7789
7815
  }
7790
7816
  return this._logConn;
7791
7817
  }
7792
- globalBgLogger() {
7793
- return this._globalBgLogger;
7818
+ bgLogger() {
7819
+ return this._bgLogger;
7794
7820
  }
7795
7821
  // Should only be called by the login function.
7796
7822
  loginReplaceLogConn(logConn) {
7797
- this._globalBgLogger.internalReplaceLogConn(logConn);
7823
+ this._bgLogger.internalReplaceLogConn(logConn);
7798
7824
  }
7799
7825
  };
7800
- var _state;
7826
+ var _globalState;
7801
7827
  function _internalSetInitialState() {
7802
- if (_state) {
7828
+ if (_globalState) {
7803
7829
  throw new Error("Cannot set initial state more than once");
7804
7830
  }
7805
- _state = globalThis.__inherited_braintrust_state || new BraintrustState();
7831
+ _globalState = globalThis.__inherited_braintrust_state || new BraintrustState({
7832
+ /*empty login options*/
7833
+ });
7806
7834
  }
7807
- var _internalGetGlobalState = () => _state;
7835
+ var _internalGetGlobalState = () => _globalState;
7808
7836
  var FailedHTTPResponse = class extends Error {
7809
7837
  status;
7810
7838
  text;
@@ -7925,7 +7953,7 @@ var HTTPConnection = class _HTTPConnection {
7925
7953
  return await resp.json();
7926
7954
  }
7927
7955
  };
7928
- function logFeedbackImpl(parentObjectType, parentObjectId, {
7956
+ function logFeedbackImpl(state, parentObjectType, parentObjectId, {
7929
7957
  id,
7930
7958
  expected,
7931
7959
  scores,
@@ -7968,7 +7996,7 @@ function logFeedbackImpl(parentObjectType, parentObjectId, {
7968
7996
  [IS_MERGE_FIELD]: true
7969
7997
  };
7970
7998
  });
7971
- _state.globalBgLogger().log([record]);
7999
+ state.bgLogger().log([record]);
7972
8000
  }
7973
8001
  if (!isEmpty(comment)) {
7974
8002
  const record = new LazyValue(async () => {
@@ -7988,10 +8016,10 @@ function logFeedbackImpl(parentObjectType, parentObjectId, {
7988
8016
  [AUDIT_METADATA_FIELD]: metadata
7989
8017
  };
7990
8018
  });
7991
- _state.globalBgLogger().log([record]);
8019
+ state.bgLogger().log([record]);
7992
8020
  }
7993
8021
  }
7994
- function spanComponentsToObjectIdLambda(components) {
8022
+ function spanComponentsToObjectIdLambda(state, components) {
7995
8023
  if (components.objectId) {
7996
8024
  const ret = components.objectId;
7997
8025
  return async () => ret;
@@ -8007,8 +8035,9 @@ function spanComponentsToObjectIdLambda(components) {
8007
8035
  "Impossible: computeObjectMetadataArgs not supported for experiments"
8008
8036
  );
8009
8037
  case SpanObjectTypeV2.PROJECT_LOGS:
8010
- const args = components.computeObjectMetadataArgs;
8011
- return async () => (await computeLoggerMetadata(args)).project.id;
8038
+ return async () => (await computeLoggerMetadata(state, {
8039
+ ...components.computeObjectMetadataArgs
8040
+ })).project.id;
8012
8041
  default:
8013
8042
  const x = components.objectType;
8014
8043
  throw new Error(`Unknown object type: ${x}`);
@@ -8027,7 +8056,10 @@ function startSpanParentArgs(args) {
8027
8056
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.objectType}`
8028
8057
  );
8029
8058
  }
8030
- const parentComponentsObjectIdLambda = spanComponentsToObjectIdLambda(parentComponents);
8059
+ const parentComponentsObjectIdLambda = spanComponentsToObjectIdLambda(
8060
+ args.state,
8061
+ parentComponents
8062
+ );
8031
8063
  const computeParentObjectId = async () => {
8032
8064
  const parentComponentsObjectId = await parentComponentsObjectIdLambda();
8033
8065
  if (await args.parentObjectId.get() !== parentComponentsObjectId) {
@@ -8056,6 +8088,7 @@ function startSpanParentArgs(args) {
8056
8088
  };
8057
8089
  }
8058
8090
  var Logger = class {
8091
+ state;
8059
8092
  lazyMetadata;
8060
8093
  _asyncFlush;
8061
8094
  computeMetadataArgs;
@@ -8064,13 +8097,14 @@ var Logger = class {
8064
8097
  calledStartSpan;
8065
8098
  // For type identification.
8066
8099
  kind = "logger";
8067
- constructor(lazyMetadata, logOptions = {}) {
8100
+ constructor(state, lazyMetadata, logOptions = {}) {
8068
8101
  this.lazyMetadata = lazyMetadata;
8069
8102
  this._asyncFlush = logOptions.asyncFlush;
8070
8103
  this.computeMetadataArgs = logOptions.computeMetadataArgs;
8071
8104
  this.lastStartTime = getCurrentUnixTimestamp();
8072
8105
  this.lazyId = new LazyValue(async () => await this.id);
8073
8106
  this.calledStartSpan = false;
8107
+ this.state = state;
8074
8108
  }
8075
8109
  get org_id() {
8076
8110
  return (async () => {
@@ -8162,7 +8196,9 @@ var Logger = class {
8162
8196
  }
8163
8197
  startSpanImpl(args) {
8164
8198
  return new SpanImpl({
8199
+ state: this.state,
8165
8200
  ...startSpanParentArgs({
8201
+ state: this.state,
8166
8202
  parent: args?.parent,
8167
8203
  parentObjectType: this.parentObjectType(),
8168
8204
  parentObjectId: this.lazyId,
@@ -8185,7 +8221,7 @@ var Logger = class {
8185
8221
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
8186
8222
  */
8187
8223
  logFeedback(event) {
8188
- logFeedbackImpl(this.parentObjectType(), this.lazyId, event);
8224
+ logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
8189
8225
  }
8190
8226
  /**
8191
8227
  * Return a serialized representation of the logger that can be used to start subspans in other places. See `Span.start_span` for more details.
@@ -8208,7 +8244,7 @@ var Logger = class {
8208
8244
  * Flush any pending logs to the server.
8209
8245
  */
8210
8246
  async flush() {
8211
- return await _state.globalBgLogger().flush();
8247
+ return await this.state.bgLogger().flush();
8212
8248
  }
8213
8249
  get asyncFlush() {
8214
8250
  return this._asyncFlush;
@@ -8573,29 +8609,27 @@ function init(projectOrOptions, optionalOptions) {
8573
8609
  gitMetadataSettings,
8574
8610
  projectId,
8575
8611
  baseExperimentId,
8576
- repoInfo
8612
+ repoInfo,
8613
+ state: stateArg
8577
8614
  } = options;
8578
8615
  if (open && update) {
8579
8616
  throw new Error("Cannot open and update an experiment at the same time");
8580
8617
  }
8618
+ const state = stateArg ?? _globalState;
8581
8619
  if (open) {
8582
8620
  if (isEmpty(experiment)) {
8583
8621
  throw new Error(`Cannot open an experiment without specifying its name`);
8584
8622
  }
8585
8623
  const lazyMetadata2 = new LazyValue(
8586
8624
  async () => {
8587
- await login({
8588
- orgName,
8589
- apiKey,
8590
- appUrl
8591
- });
8625
+ await state.login({ apiKey, appUrl, orgName });
8592
8626
  const args = {
8593
8627
  project_name: project,
8594
8628
  project_id: projectId,
8595
- org_name: _state.orgName,
8629
+ org_name: state.orgName,
8596
8630
  experiment_name: experiment
8597
8631
  };
8598
- const response = await _state.apiConn().post_json("api/experiment/get", args);
8632
+ const response = await state.apiConn().post_json("api/experiment/get", args);
8599
8633
  if (response.length === 0) {
8600
8634
  throw new Error(
8601
8635
  `Experiment ${experiment} not found in project ${projectId ?? project}.`
@@ -8617,20 +8651,17 @@ function init(projectOrOptions, optionalOptions) {
8617
8651
  }
8618
8652
  );
8619
8653
  return new ReadonlyExperiment(
8654
+ stateArg ?? _globalState,
8620
8655
  lazyMetadata2
8621
8656
  );
8622
8657
  }
8623
8658
  const lazyMetadata = new LazyValue(
8624
8659
  async () => {
8625
- await login({
8626
- orgName,
8627
- apiKey,
8628
- appUrl
8629
- });
8660
+ await state.login({ apiKey, appUrl, orgName });
8630
8661
  const args = {
8631
8662
  project_name: project,
8632
8663
  project_id: projectId,
8633
- org_id: _state.orgId,
8664
+ org_id: state.orgId,
8634
8665
  update
8635
8666
  };
8636
8667
  if (experiment) {
@@ -8644,7 +8675,7 @@ function init(projectOrOptions, optionalOptions) {
8644
8675
  return repoInfo;
8645
8676
  }
8646
8677
  let mergedGitMetadataSettings = {
8647
- ..._state.gitMetadataSettings || {
8678
+ ...state.gitMetadataSettings || {
8648
8679
  collect: "all"
8649
8680
  }
8650
8681
  };
@@ -8679,7 +8710,7 @@ function init(projectOrOptions, optionalOptions) {
8679
8710
  let response = null;
8680
8711
  while (true) {
8681
8712
  try {
8682
- response = await _state.apiConn().post_json("api/experiment/register", args);
8713
+ response = await state.apiConn().post_json("api/experiment/register", args);
8683
8714
  break;
8684
8715
  } catch (e) {
8685
8716
  if (args["base_experiment"] && `${"data" in e && e.data}`.includes("base experiment")) {
@@ -8706,9 +8737,9 @@ function init(projectOrOptions, optionalOptions) {
8706
8737
  };
8707
8738
  }
8708
8739
  );
8709
- const ret = new Experiment(lazyMetadata, dataset);
8740
+ const ret = new Experiment(state, lazyMetadata, dataset);
8710
8741
  if (options.setCurrent ?? true) {
8711
- _state.currentExperiment = ret;
8742
+ state.currentExperiment = ret;
8712
8743
  }
8713
8744
  return ret;
8714
8745
  }
@@ -8763,23 +8794,25 @@ function initDataset(projectOrOptions, optionalOptions) {
8763
8794
  apiKey,
8764
8795
  orgName,
8765
8796
  projectId,
8766
- useOutput: legacy
8797
+ useOutput: legacy,
8798
+ state: stateArg
8767
8799
  } = options;
8800
+ const state = stateArg ?? _globalState;
8768
8801
  const lazyMetadata = new LazyValue(
8769
8802
  async () => {
8770
- await login({
8803
+ await state.login({
8771
8804
  orgName,
8772
8805
  apiKey,
8773
8806
  appUrl
8774
8807
  });
8775
8808
  const args = {
8776
- org_id: _state.orgId,
8809
+ org_id: state.orgId,
8777
8810
  project_name: project,
8778
8811
  project_id: projectId,
8779
8812
  dataset_name: dataset,
8780
8813
  description
8781
8814
  };
8782
- const response = await _state.apiConn().post_json("api/dataset/register", args);
8815
+ const response = await state.apiConn().post_json("api/dataset/register", args);
8783
8816
  return {
8784
8817
  project: {
8785
8818
  id: response.project.id,
@@ -8794,7 +8827,7 @@ function initDataset(projectOrOptions, optionalOptions) {
8794
8827
  };
8795
8828
  }
8796
8829
  );
8797
- return new Dataset(lazyMetadata, version, legacy);
8830
+ return new Dataset(stateArg ?? _globalState, lazyMetadata, version, legacy);
8798
8831
  }
8799
8832
  function withDataset(project, callback, options = {}) {
8800
8833
  console.warn(
@@ -8803,14 +8836,13 @@ function withDataset(project, callback, options = {}) {
8803
8836
  const dataset = initDataset(project, options);
8804
8837
  return callback(dataset);
8805
8838
  }
8806
- async function computeLoggerMetadata({
8839
+ async function computeLoggerMetadata(state, {
8807
8840
  project_name,
8808
8841
  project_id
8809
8842
  }) {
8810
- await login();
8811
- const org_id = _state.orgId;
8812
- if (project_id === void 0) {
8813
- const response = await _state.apiConn().post_json("api/project/register", {
8843
+ const org_id = state.orgId;
8844
+ if (isEmpty(project_id)) {
8845
+ const response = await state.apiConn().post_json("api/project/register", {
8814
8846
  project_name: project_name || GLOBAL_PROJECT,
8815
8847
  org_id
8816
8848
  });
@@ -8822,8 +8854,8 @@ async function computeLoggerMetadata({
8822
8854
  fullInfo: response.project
8823
8855
  }
8824
8856
  };
8825
- } else if (project_name === void 0) {
8826
- const response = await _state.apiConn().get_json("api/project", {
8857
+ } else if (isEmpty(project_name)) {
8858
+ const response = await state.apiConn().get_json("api/project", {
8827
8859
  id: project_id
8828
8860
  });
8829
8861
  return {
@@ -8849,29 +8881,31 @@ function initLogger(options = {}) {
8849
8881
  appUrl,
8850
8882
  apiKey,
8851
8883
  orgName,
8852
- forceLogin
8884
+ forceLogin,
8885
+ state: stateArg
8853
8886
  } = options || {};
8854
8887
  const computeMetadataArgs = {
8855
8888
  project_name: projectName,
8856
8889
  project_id: projectId
8857
8890
  };
8891
+ const state = stateArg ?? _globalState;
8858
8892
  const lazyMetadata = new LazyValue(
8859
8893
  async () => {
8860
- await login({
8894
+ await state.login({
8861
8895
  orgName,
8862
8896
  apiKey,
8863
8897
  appUrl,
8864
8898
  forceLogin
8865
8899
  });
8866
- return computeLoggerMetadata(computeMetadataArgs);
8900
+ return computeLoggerMetadata(state, computeMetadataArgs);
8867
8901
  }
8868
8902
  );
8869
- const ret = new Logger(lazyMetadata, {
8903
+ const ret = new Logger(state, lazyMetadata, {
8870
8904
  asyncFlush,
8871
8905
  computeMetadataArgs
8872
8906
  });
8873
8907
  if (options.setCurrent ?? true) {
8874
- _state.currentLogger = ret;
8908
+ state.currentLogger = ret;
8875
8909
  }
8876
8910
  return ret;
8877
8911
  }
@@ -8884,7 +8918,8 @@ async function loadPrompt({
8884
8918
  noTrace = false,
8885
8919
  appUrl,
8886
8920
  apiKey,
8887
- orgName
8921
+ orgName,
8922
+ state: stateArg
8888
8923
  }) {
8889
8924
  if (isEmpty(projectName) && isEmpty(projectId)) {
8890
8925
  throw new Error("Must specify either projectName or projectId");
@@ -8892,7 +8927,8 @@ async function loadPrompt({
8892
8927
  if (isEmpty(slug)) {
8893
8928
  throw new Error("Must specify slug");
8894
8929
  }
8895
- await login({
8930
+ const state = stateArg ?? _globalState;
8931
+ state.login({
8896
8932
  orgName,
8897
8933
  apiKey,
8898
8934
  appUrl
@@ -8903,7 +8939,7 @@ async function loadPrompt({
8903
8939
  slug,
8904
8940
  version
8905
8941
  };
8906
- const response = await _state.logConn().get_json("v1/prompt", args);
8942
+ const response = await state.logConn().get_json("v1/prompt", args);
8907
8943
  if (!("objects" in response) || response.objects.length === 0) {
8908
8944
  throw new Error(
8909
8945
  `Prompt ${slug} not found in ${[projectName ?? projectId]}`
@@ -8918,7 +8954,7 @@ async function loadPrompt({
8918
8954
  }
8919
8955
  async function login(options = {}) {
8920
8956
  let { forceLogin = false } = options || {};
8921
- if (_state.loggedIn && !forceLogin) {
8957
+ if (_globalState.loggedIn && !forceLogin) {
8922
8958
  let checkUpdatedParam2 = function(varname, arg, orig) {
8923
8959
  if (!isEmpty(arg) && !isEmpty(orig) && arg !== orig) {
8924
8960
  throw new Error(
@@ -8927,28 +8963,32 @@ async function login(options = {}) {
8927
8963
  }
8928
8964
  };
8929
8965
  var checkUpdatedParam = checkUpdatedParam2;
8930
- checkUpdatedParam2("appUrl", options.appUrl, _state.appUrl);
8966
+ checkUpdatedParam2("appUrl", options.appUrl, _globalState.appUrl);
8931
8967
  checkUpdatedParam2(
8932
8968
  "apiKey",
8933
8969
  options.apiKey ? HTTPConnection.sanitize_token(options.apiKey) : void 0,
8934
- _state.loginToken
8970
+ _globalState.loginToken
8935
8971
  );
8936
- checkUpdatedParam2("orgName", options.orgName, _state.orgName);
8937
- return;
8972
+ checkUpdatedParam2("orgName", options.orgName, _globalState.orgName);
8973
+ return _globalState;
8938
8974
  }
8975
+ await _globalState.login(options);
8976
+ }
8977
+ async function loginToState(options = {}) {
8939
8978
  const {
8940
8979
  appUrl = isomorph_default.getEnv("BRAINTRUST_APP_URL") || "https://www.braintrust.dev",
8941
8980
  apiKey = isomorph_default.getEnv("BRAINTRUST_API_KEY"),
8942
8981
  orgName = isomorph_default.getEnv("BRAINTRUST_ORG_NAME")
8943
8982
  } = options || {};
8944
8983
  const appPublicUrl = isomorph_default.getEnv("BRAINTRUST_APP_PUBLIC_URL") || appUrl;
8945
- _state.resetLoginInfo();
8946
- _state.appUrl = appUrl;
8947
- _state.appPublicUrl = appPublicUrl;
8984
+ const state = new BraintrustState(options);
8985
+ state.resetLoginInfo();
8986
+ state.appUrl = appUrl;
8987
+ state.appPublicUrl = appPublicUrl;
8948
8988
  let conn = null;
8949
8989
  if (apiKey !== void 0) {
8950
8990
  const resp = await checkResponse(
8951
- await fetch(_urljoin(_state.appUrl, `/api/apikey/login`), {
8991
+ await fetch(_urljoin(state.appUrl, `/api/apikey/login`), {
8952
8992
  method: "POST",
8953
8993
  headers: {
8954
8994
  "Content-Type": "application/json"
@@ -8959,8 +8999,8 @@ async function login(options = {}) {
8959
8999
  })
8960
9000
  );
8961
9001
  const info = await resp.json();
8962
- _check_org_info(info.org_info, orgName);
8963
- conn = _state.logConn();
9002
+ _check_org_info(state, info.org_info, orgName);
9003
+ conn = state.logConn();
8964
9004
  conn.set_token(apiKey);
8965
9005
  } else {
8966
9006
  throw new Error(
@@ -8971,10 +9011,11 @@ async function login(options = {}) {
8971
9011
  throw new Error("Conn should be set at this point (a bug)");
8972
9012
  }
8973
9013
  conn.make_long_lived();
8974
- _state.apiConn().set_token(apiKey);
8975
- _state.loginToken = conn.token;
8976
- _state.loggedIn = true;
8977
- _state.loginReplaceLogConn(conn);
9014
+ state.apiConn().set_token(apiKey);
9015
+ state.loginToken = conn.token;
9016
+ state.loggedIn = true;
9017
+ state.loginReplaceLogConn(conn);
9018
+ return state;
8978
9019
  }
8979
9020
  function log(event) {
8980
9021
  console.warn(
@@ -8996,17 +9037,21 @@ async function summarize(options = {}) {
8996
9037
  }
8997
9038
  return await e.summarize(options);
8998
9039
  }
8999
- function currentExperiment() {
9000
- return _state.currentExperiment;
9040
+ function currentExperiment(options) {
9041
+ const state = options?.state ?? _globalState;
9042
+ return state.currentExperiment;
9001
9043
  }
9002
9044
  function currentLogger(options) {
9003
- return castLogger(_state.currentLogger, options?.asyncFlush);
9045
+ const state = options?.state ?? _globalState;
9046
+ return castLogger(state.currentLogger, options?.asyncFlush);
9004
9047
  }
9005
- function currentSpan() {
9006
- return _state.currentSpan.getStore() ?? NOOP_SPAN;
9048
+ function currentSpan(options) {
9049
+ const state = options?.state ?? _globalState;
9050
+ return state.currentSpan.getStore() ?? NOOP_SPAN;
9007
9051
  }
9008
9052
  function getSpanParentObject(options) {
9009
- const parentSpan = currentSpan();
9053
+ const state = options?.state ?? _globalState;
9054
+ const parentSpan = currentSpan({ state });
9010
9055
  if (!Object.is(parentSpan, NOOP_SPAN)) {
9011
9056
  return parentSpan;
9012
9057
  }
@@ -9047,10 +9092,12 @@ function traced(callback, args) {
9047
9092
  function startSpan(args) {
9048
9093
  return startSpanAndIsLogger(args).span;
9049
9094
  }
9050
- async function flush() {
9051
- return await _state.globalBgLogger().flush();
9095
+ async function flush(options) {
9096
+ const state = options?.state ?? _globalState;
9097
+ return await state.bgLogger().flush();
9052
9098
  }
9053
9099
  function startSpanAndIsLogger(args) {
9100
+ const state = args?.state ?? _globalState;
9054
9101
  if (args?.parent) {
9055
9102
  const components = SpanComponentsV2.fromStr(args?.parent);
9056
9103
  const parentSpanIds = components.rowIds ? {
@@ -9058,9 +9105,12 @@ function startSpanAndIsLogger(args) {
9058
9105
  rootSpanId: components.rowIds.rootSpanId
9059
9106
  } : void 0;
9060
9107
  const span = new SpanImpl({
9108
+ state,
9061
9109
  ...args,
9062
9110
  parentObjectType: components.objectType,
9063
- parentObjectId: new LazyValue(spanComponentsToObjectIdLambda(components)),
9111
+ parentObjectId: new LazyValue(
9112
+ spanComponentsToObjectIdLambda(state, components)
9113
+ ),
9064
9114
  parentComputeObjectMetadataArgs: components.computeObjectMetadataArgs,
9065
9115
  parentSpanIds
9066
9116
  });
@@ -9076,23 +9126,23 @@ function startSpanAndIsLogger(args) {
9076
9126
  return { span, isLogger: parentObject.kind === "logger" };
9077
9127
  }
9078
9128
  }
9079
- function withCurrent(span, callback) {
9080
- return _state.currentSpan.run(span, () => callback(span));
9129
+ function withCurrent(span, callback, state = _globalState) {
9130
+ return state.currentSpan.run(span, () => callback(span));
9081
9131
  }
9082
- function _check_org_info(org_info, org_name) {
9132
+ function _check_org_info(state, org_info, org_name) {
9083
9133
  if (org_info.length === 0) {
9084
9134
  throw new Error("This user is not part of any organizations.");
9085
9135
  }
9086
9136
  for (const org of org_info) {
9087
9137
  if (org_name === void 0 || org.name === org_name) {
9088
- _state.orgId = org.id;
9089
- _state.orgName = org.name;
9090
- _state.logUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
9091
- _state.gitMetadataSettings = org.git_metadata || void 0;
9138
+ state.orgId = org.id;
9139
+ state.orgName = org.name;
9140
+ state.logUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
9141
+ state.gitMetadataSettings = org.git_metadata || void 0;
9092
9142
  break;
9093
9143
  }
9094
9144
  }
9095
- if (_state.orgId === void 0) {
9145
+ if (state.orgId === void 0) {
9096
9146
  throw new Error(
9097
9147
  `Organization ${org_name} not found. Must be one of ${org_info.map((x) => x.name).join(", ")}`
9098
9148
  );
@@ -9251,15 +9301,17 @@ var Experiment = class extends ObjectFetcher {
9251
9301
  lastStartTime;
9252
9302
  lazyId;
9253
9303
  calledStartSpan;
9304
+ state;
9254
9305
  // For type identification.
9255
9306
  kind = "experiment";
9256
- constructor(lazyMetadata, dataset) {
9307
+ constructor(state, lazyMetadata, dataset) {
9257
9308
  super("experiment", void 0);
9258
9309
  this.lazyMetadata = lazyMetadata;
9259
9310
  this.dataset = dataset;
9260
9311
  this.lastStartTime = getCurrentUnixTimestamp();
9261
9312
  this.lazyId = new LazyValue(async () => await this.id);
9262
9313
  this.calledStartSpan = false;
9314
+ this.state = state;
9263
9315
  }
9264
9316
  get id() {
9265
9317
  return (async () => {
@@ -9281,7 +9333,7 @@ var Experiment = class extends ObjectFetcher {
9281
9333
  }
9282
9334
  async getState() {
9283
9335
  await this.lazyMetadata.get();
9284
- return _state;
9336
+ return this.state;
9285
9337
  }
9286
9338
  /**
9287
9339
  * Log a single event to the experiment. The event will be batched and uploaded behind the scenes.
@@ -9343,7 +9395,9 @@ var Experiment = class extends ObjectFetcher {
9343
9395
  }
9344
9396
  startSpanImpl(args) {
9345
9397
  return new SpanImpl({
9398
+ state: this.state,
9346
9399
  ...startSpanParentArgs({
9400
+ state: this.state,
9347
9401
  parent: args?.parent,
9348
9402
  parentObjectType: this.parentObjectType(),
9349
9403
  parentObjectId: this.lazyId,
@@ -9437,7 +9491,7 @@ var Experiment = class extends ObjectFetcher {
9437
9491
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
9438
9492
  */
9439
9493
  logFeedback(event) {
9440
- logFeedbackImpl(this.parentObjectType(), this.lazyId, event);
9494
+ logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
9441
9495
  }
9442
9496
  /**
9443
9497
  * Return a serialized representation of the experiment that can be used to start subspans in other places. See `Span.start_span` for more details.
@@ -9452,7 +9506,7 @@ var Experiment = class extends ObjectFetcher {
9452
9506
  * Flush any pending rows to the server.
9453
9507
  */
9454
9508
  async flush() {
9455
- return await _state.globalBgLogger().flush();
9509
+ return await this.state.bgLogger().flush();
9456
9510
  }
9457
9511
  /**
9458
9512
  * This function is deprecated. You can simply remove it from your code.
@@ -9465,8 +9519,9 @@ var Experiment = class extends ObjectFetcher {
9465
9519
  }
9466
9520
  };
9467
9521
  var ReadonlyExperiment = class extends ObjectFetcher {
9468
- constructor(lazyMetadata) {
9522
+ constructor(state, lazyMetadata) {
9469
9523
  super("experiment", void 0);
9524
+ this.state = state;
9470
9525
  this.lazyMetadata = lazyMetadata;
9471
9526
  }
9472
9527
  get id() {
@@ -9481,7 +9536,7 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9481
9536
  }
9482
9537
  async getState() {
9483
9538
  await this.lazyMetadata.get();
9484
- return _state;
9539
+ return this.state;
9485
9540
  }
9486
9541
  async *asDataset() {
9487
9542
  const records = this.fetch();
@@ -9511,9 +9566,9 @@ function newId() {
9511
9566
  return v4_default();
9512
9567
  }
9513
9568
  var SpanImpl = class _SpanImpl {
9569
+ state;
9514
9570
  // `internalData` contains fields that are not part of the "user-sanitized"
9515
9571
  // set of fields which we want to log in just one of the span rows.
9516
- internalData;
9517
9572
  isMerge;
9518
9573
  loggedEndTime;
9519
9574
  // For internal use only.
@@ -9526,6 +9581,7 @@ var SpanImpl = class _SpanImpl {
9526
9581
  spanParents;
9527
9582
  kind = "span";
9528
9583
  constructor(args) {
9584
+ this.state = args.state;
9529
9585
  const spanAttributes = args.spanAttributes ?? {};
9530
9586
  const event = args.event ?? {};
9531
9587
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -9548,7 +9604,7 @@ var SpanImpl = class _SpanImpl {
9548
9604
  }
9549
9605
  return "subspan";
9550
9606
  })();
9551
- this.internalData = {
9607
+ const internalData = {
9552
9608
  metrics: {
9553
9609
  start: args.startTime ?? getCurrentUnixTimestamp()
9554
9610
  },
@@ -9572,17 +9628,25 @@ var SpanImpl = class _SpanImpl {
9572
9628
  }
9573
9629
  this.isMerge = false;
9574
9630
  const { id: _id, ...eventRest } = event;
9575
- this.log(eventRest);
9631
+ this.logInternal({ event: eventRest, internalData });
9576
9632
  this.isMerge = true;
9577
9633
  }
9578
9634
  get id() {
9579
9635
  return this._id;
9580
9636
  }
9637
+ setAttributes(args) {
9638
+ this.logInternal({ internalData: { span_attributes: args } });
9639
+ }
9581
9640
  log(event) {
9582
- const sanitized = validateAndSanitizeExperimentLogPartialArgs(event);
9583
- let sanitizedAndInternalData = { ...this.internalData };
9641
+ this.logInternal({ event });
9642
+ }
9643
+ logInternal({
9644
+ event,
9645
+ internalData
9646
+ }) {
9647
+ const sanitized = validateAndSanitizeExperimentLogPartialArgs(event ?? {});
9648
+ let sanitizedAndInternalData = { ...internalData };
9584
9649
  mergeDicts(sanitizedAndInternalData, sanitized);
9585
- this.internalData = {};
9586
9650
  let partialRecord = {
9587
9651
  id: this.id,
9588
9652
  span_id: this.spanId,
@@ -9606,10 +9670,10 @@ var SpanImpl = class _SpanImpl {
9606
9670
  objectId: await this.parentObjectId.get()
9607
9671
  }).objectIdFields()
9608
9672
  });
9609
- _state.globalBgLogger().log([new LazyValue(computeRecord)]);
9673
+ this.state.bgLogger().log([new LazyValue(computeRecord)]);
9610
9674
  }
9611
9675
  logFeedback(event) {
9612
- logFeedbackImpl(this.parentObjectType, this.parentObjectId, {
9676
+ logFeedbackImpl(this.state, this.parentObjectType, this.parentObjectId, {
9613
9677
  ...event,
9614
9678
  id: this.id
9615
9679
  });
@@ -9631,8 +9695,10 @@ var SpanImpl = class _SpanImpl {
9631
9695
  startSpan(args) {
9632
9696
  const parentSpanIds = args?.parent ? void 0 : { spanId: this.spanId, rootSpanId: this.rootSpanId };
9633
9697
  return new _SpanImpl({
9698
+ state: this.state,
9634
9699
  ...args,
9635
9700
  ...startSpanParentArgs({
9701
+ state: this.state,
9636
9702
  parent: args?.parent,
9637
9703
  parentObjectType: this.parentObjectType,
9638
9704
  parentObjectId: this.parentObjectId,
@@ -9643,13 +9709,14 @@ var SpanImpl = class _SpanImpl {
9643
9709
  }
9644
9710
  end(args) {
9645
9711
  let endTime;
9712
+ let internalData = {};
9646
9713
  if (!this.loggedEndTime) {
9647
9714
  endTime = args?.endTime ?? getCurrentUnixTimestamp();
9648
- this.internalData = { metrics: { end: endTime } };
9715
+ internalData = { metrics: { end: endTime } };
9649
9716
  } else {
9650
9717
  endTime = this.loggedEndTime;
9651
9718
  }
9652
- this.log({});
9719
+ this.logInternal({ internalData });
9653
9720
  return endTime;
9654
9721
  }
9655
9722
  async export() {
@@ -9672,15 +9739,14 @@ var SpanImpl = class _SpanImpl {
9672
9739
  }).toStr();
9673
9740
  }
9674
9741
  async flush() {
9675
- return await _state.globalBgLogger().flush();
9742
+ return await this.state.bgLogger().flush();
9676
9743
  }
9677
9744
  close(args) {
9678
9745
  return this.end(args);
9679
9746
  }
9680
9747
  };
9681
9748
  var Dataset = class extends ObjectFetcher {
9682
- lazyMetadata;
9683
- constructor(lazyMetadata, pinnedVersion, legacy) {
9749
+ constructor(state, lazyMetadata, pinnedVersion, legacy) {
9684
9750
  const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
9685
9751
  if (isLegacyDataset) {
9686
9752
  console.warn(
@@ -9692,8 +9758,10 @@ var Dataset = class extends ObjectFetcher {
9692
9758
  pinnedVersion,
9693
9759
  (r) => ensureDatasetRecord(r, isLegacyDataset)
9694
9760
  );
9761
+ this.state = state;
9695
9762
  this.lazyMetadata = lazyMetadata;
9696
9763
  }
9764
+ lazyMetadata;
9697
9765
  get id() {
9698
9766
  return (async () => {
9699
9767
  return (await this.lazyMetadata.get()).dataset.id;
@@ -9711,7 +9779,7 @@ var Dataset = class extends ObjectFetcher {
9711
9779
  }
9712
9780
  async getState() {
9713
9781
  await this.lazyMetadata.get();
9714
- return _state;
9782
+ return this.state;
9715
9783
  }
9716
9784
  /**
9717
9785
  * Insert a single record to the dataset. The record will be batched and uploaded behind the scenes. If you pass in an `id`,
@@ -9762,7 +9830,7 @@ var Dataset = class extends ObjectFetcher {
9762
9830
  created: (/* @__PURE__ */ new Date()).toISOString(),
9763
9831
  metadata
9764
9832
  }));
9765
- _state.globalBgLogger().log([args]);
9833
+ this.state.bgLogger().log([args]);
9766
9834
  return rowId;
9767
9835
  }
9768
9836
  delete(id) {
@@ -9772,7 +9840,7 @@ var Dataset = class extends ObjectFetcher {
9772
9840
  created: (/* @__PURE__ */ new Date()).toISOString(),
9773
9841
  _object_delete: true
9774
9842
  }));
9775
- _state.globalBgLogger().log([args]);
9843
+ this.state.bgLogger().log([args]);
9776
9844
  return id;
9777
9845
  }
9778
9846
  /**
@@ -9813,7 +9881,7 @@ var Dataset = class extends ObjectFetcher {
9813
9881
  * Flush any pending rows to the server.
9814
9882
  */
9815
9883
  async flush() {
9816
- return await _state.globalBgLogger().flush();
9884
+ return await this.state.bgLogger().flush();
9817
9885
  }
9818
9886
  /**
9819
9887
  * This function is deprecated. You can simply remove it from your code.
@@ -9898,13 +9966,18 @@ var Prompt = class {
9898
9966
  if (!prompt) {
9899
9967
  throw new Error("Empty prompt");
9900
9968
  }
9969
+ const dictArgParsed = z.record(z.unknown()).safeParse(buildArgs);
9970
+ const variables = {
9971
+ input: buildArgs,
9972
+ ...dictArgParsed.success ? dictArgParsed.data : {}
9973
+ };
9901
9974
  if (flavor === "chat") {
9902
9975
  if (prompt.type !== "chat") {
9903
9976
  throw new Error(
9904
9977
  "Prompt is a completion prompt. Use buildCompletion() instead"
9905
9978
  );
9906
9979
  }
9907
- const render3 = (template) => mustache_default.render(template, buildArgs, void 0, {
9980
+ const render3 = (template) => mustache_default.render(template, variables, void 0, {
9908
9981
  escape: (v) => typeof v === "string" ? v : JSON.stringify(v)
9909
9982
  });
9910
9983
  const messages = (prompt.messages || []).map((m) => ({
@@ -9919,7 +9992,7 @@ var Prompt = class {
9919
9992
  messages,
9920
9993
  ...prompt.tools ? {
9921
9994
  tools: toolsSchema.parse(
9922
- JSON.parse(mustache_default.render(prompt.tools, buildArgs))
9995
+ JSON.parse(mustache_default.render(prompt.tools, variables))
9923
9996
  )
9924
9997
  } : void 0
9925
9998
  };
@@ -9930,7 +10003,7 @@ var Prompt = class {
9930
10003
  return {
9931
10004
  ...params,
9932
10005
  ...spanInfo,
9933
- prompt: mustache_default.render(prompt.content, buildArgs)
10006
+ prompt: mustache_default.render(prompt.content, variables)
9934
10007
  };
9935
10008
  } else {
9936
10009
  throw new Error("never!");
@@ -10080,20 +10153,29 @@ function wrapBetaChatCompletion(completion) {
10080
10153
  return ret;
10081
10154
  };
10082
10155
  }
10083
- var X_CACHED_HEADER = "x-cached";
10156
+ var LEGACY_CACHED_HEADER = "x-cached";
10157
+ var X_CACHED_HEADER = "x-bt-cached";
10084
10158
  function parseCachedHeader(value) {
10085
- return isEmpty(value) ? void 0 : value.toLowerCase() === "true" ? 1 : 0;
10159
+ return isEmpty(value) ? void 0 : ["true", "hit"].includes(value.toLowerCase()) ? 1 : 0;
10086
10160
  }
10087
10161
  function logHeaders(response, span) {
10088
10162
  const cachedHeader = response.headers.get(X_CACHED_HEADER);
10089
10163
  if (isEmpty(cachedHeader)) {
10090
- return;
10091
- }
10092
- span.log({
10093
- metrics: {
10094
- cached: parseCachedHeader(cachedHeader)
10164
+ const legacyCacheHeader = response.headers.get(LEGACY_CACHED_HEADER);
10165
+ if (!isEmpty(legacyCacheHeader)) {
10166
+ span.log({
10167
+ metrics: {
10168
+ cached: parseCachedHeader(legacyCacheHeader)
10169
+ }
10170
+ });
10095
10171
  }
10096
- });
10172
+ } else {
10173
+ span.log({
10174
+ metrics: {
10175
+ cached: parseCachedHeader(cachedHeader)
10176
+ }
10177
+ });
10178
+ }
10097
10179
  }
10098
10180
  function wrapChatCompletion(completion) {
10099
10181
  return async (allParams, options) => {
@@ -10213,7 +10295,16 @@ function postprocessStreamingResults(allResults) {
10213
10295
  let content = void 0;
10214
10296
  let tool_calls = void 0;
10215
10297
  let finish_reason = void 0;
10298
+ let metrics = {};
10216
10299
  for (const result of allResults) {
10300
+ if (result.usage) {
10301
+ metrics = {
10302
+ ...metrics,
10303
+ tokens: result.usage.total_tokens,
10304
+ prompt_tokens: result.usage.prompt_tokens,
10305
+ completion_tokens: result.usage.completion_tokens
10306
+ };
10307
+ }
10217
10308
  const delta = result.choices?.[0]?.delta;
10218
10309
  if (!delta) {
10219
10310
  continue;
@@ -10241,18 +10332,21 @@ function postprocessStreamingResults(allResults) {
10241
10332
  }
10242
10333
  }
10243
10334
  }
10244
- return [
10245
- {
10246
- index: 0,
10247
- message: {
10248
- role,
10249
- content,
10250
- tool_calls
10251
- },
10252
- logprobs: null,
10253
- finish_reason
10254
- }
10255
- ];
10335
+ return {
10336
+ metrics,
10337
+ output: [
10338
+ {
10339
+ index: 0,
10340
+ message: {
10341
+ role,
10342
+ content,
10343
+ tool_calls
10344
+ },
10345
+ logprobs: null,
10346
+ finish_reason
10347
+ }
10348
+ ]
10349
+ };
10256
10350
  }
10257
10351
  var WrapperStream = class {
10258
10352
  span;
@@ -10281,7 +10375,7 @@ var WrapperStream = class {
10281
10375
  yield item;
10282
10376
  }
10283
10377
  this.span.log({
10284
- output: postprocessStreamingResults(allResults)
10378
+ ...postprocessStreamingResults(allResults)
10285
10379
  });
10286
10380
  } finally {
10287
10381
  this.span.end();
@@ -10292,8 +10386,10 @@ var WrapperStream = class {
10292
10386
  // src/browser.ts
10293
10387
  configureBrowser();
10294
10388
  export {
10389
+ BraintrustState,
10295
10390
  Dataset,
10296
10391
  Experiment,
10392
+ LEGACY_CACHED_HEADER,
10297
10393
  Logger,
10298
10394
  NOOP_SPAN,
10299
10395
  NoopSpan,
@@ -10315,6 +10411,7 @@ export {
10315
10411
  loadPrompt,
10316
10412
  log,
10317
10413
  login,
10414
+ loginToState,
10318
10415
  newId,
10319
10416
  parseCachedHeader,
10320
10417
  startSpan,