braintrust 0.0.134 → 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");
@@ -5841,13 +5841,15 @@ var objectTypes = z.enum([
5841
5841
  "acl",
5842
5842
  "user",
5843
5843
  "project_score",
5844
- "project_tag"
5844
+ "project_tag",
5845
+ "function"
5845
5846
  ]);
5846
5847
  var objectTypesWithEvent = z.enum([
5847
5848
  "project",
5848
5849
  "experiment",
5849
5850
  "dataset",
5850
5851
  "prompt",
5852
+ "function",
5851
5853
  "prompt_session"
5852
5854
  ]);
5853
5855
  function getEventObjectType(objectType2) {
@@ -6147,17 +6149,20 @@ var datasetSchema = z.strictObject({
6147
6149
  deleted_at: datasetBaseSchema.shape.deleted_at,
6148
6150
  user_id: datasetBaseSchema.shape.user_id
6149
6151
  }).openapi("Dataset");
6152
+ var validRuntimesEnum = z.enum(["node"]);
6153
+ var runtimeContextSchema = z.strictObject({
6154
+ runtime: validRuntimesEnum,
6155
+ version: z.string()
6156
+ });
6150
6157
  var promptBaseSchema = generateBaseTableSchema("prompt");
6151
- var promptSchema = z.strictObject({
6158
+ var promptSchemaObject = z.strictObject({
6152
6159
  id: promptBaseSchema.shape.id,
6153
6160
  // This has to be copy/pasted because zod blows up when there are circular dependencies
6154
6161
  _xact_id: z.string().describe(
6155
6162
  `The transaction id of an event is unique to the network operation that processed the event insertion. Transaction ids are monotonically increasing over time and can be used to retrieve a versioned snapshot of the prompt (see the \`version\` parameter)`
6156
6163
  ),
6157
6164
  project_id: promptBaseSchema.shape.project_id,
6158
- log_id: z.literal("p").describe(
6159
- "A literal 'p' which identifies the object as a project prompt"
6160
- ),
6165
+ log_id: z.literal("p").describe("A literal 'p' which identifies the object as a project prompt"),
6161
6166
  org_id: organizationSchema.shape.id,
6162
6167
  name: promptBaseSchema.shape.name,
6163
6168
  slug: z.string().describe("Unique identifier for the prompt"),
@@ -6166,7 +6171,46 @@ var promptSchema = z.strictObject({
6166
6171
  prompt_data: promptDataSchema.nullish().describe("The prompt, model, and its parameters"),
6167
6172
  tags: z.array(z.string()).nullish().describe("A list of tags for the prompt"),
6168
6173
  metadata: promptBaseSchema.shape.metadata
6169
- }).openapi("Prompt");
6174
+ });
6175
+ var promptSchema = promptSchemaObject.openapi("Prompt");
6176
+ var codeBundleSchema = z.strictObject({
6177
+ runtime_context: z.strictObject({
6178
+ runtime: validRuntimesEnum,
6179
+ version: z.string()
6180
+ }),
6181
+ // This should be a union, once we support code living in different places
6182
+ // Other options should be:
6183
+ // - a "handler" function that has some signature [does AWS lambda assume it's always called "handler"?]
6184
+ location: z.strictObject({
6185
+ type: z.literal("experiment"),
6186
+ eval_name: z.string(),
6187
+ position: z.union([
6188
+ z.literal("task"),
6189
+ z.strictObject({ score: z.number() })
6190
+ ])
6191
+ }),
6192
+ bundle_id: z.string()
6193
+ });
6194
+ var functionDataSchema = z.union([
6195
+ z.strictObject({
6196
+ type: z.literal("prompt")
6197
+ // For backwards compatibility reasons, this is hoisted out and stored
6198
+ // in the outer object
6199
+ }),
6200
+ z.strictObject({
6201
+ type: z.literal("code"),
6202
+ data: codeBundleSchema
6203
+ }),
6204
+ z.strictObject({
6205
+ type: z.literal("global"),
6206
+ name: z.string()
6207
+ })
6208
+ ]);
6209
+ var functionSchema2 = promptSchemaObject.merge(
6210
+ z.strictObject({
6211
+ function_data: functionDataSchema
6212
+ })
6213
+ ).openapi("Function");
6170
6214
  var repoInfoSchema = z.strictObject({
6171
6215
  commit: z.string().nullish().describe("SHA of most recent commit"),
6172
6216
  branch: z.string().nullish().describe("Name of the branch the most recent commit belongs to"),
@@ -6248,8 +6292,6 @@ var aclObjectTypeEnum = z.enum([
6248
6292
  "dataset",
6249
6293
  "prompt",
6250
6294
  "prompt_session",
6251
- "project_score",
6252
- "project_tag",
6253
6295
  "group",
6254
6296
  "role",
6255
6297
  "org_member",
@@ -6456,12 +6498,27 @@ var createPromptSchema = promptSchema.omit({
6456
6498
  created: true,
6457
6499
  metadata: true
6458
6500
  }).openapi("CreatePrompt");
6501
+ var createFunctionSchema = functionSchema2.omit({
6502
+ id: true,
6503
+ _xact_id: true,
6504
+ org_id: true,
6505
+ log_id: true,
6506
+ created: true,
6507
+ metadata: true
6508
+ }).openapi("CreateFunction");
6459
6509
  var patchPromptSchema = z.strictObject({
6460
6510
  name: promptSchema.shape.name.nullish(),
6461
6511
  description: promptSchema.shape.description.nullish(),
6462
6512
  prompt_data: promptSchema.shape.prompt_data.nullish(),
6463
6513
  tags: promptSchema.shape.tags.nullish()
6464
6514
  }).openapi("PatchPrompt");
6515
+ var patchFunctionSchema = z.strictObject({
6516
+ name: functionSchema2.shape.name.nullish(),
6517
+ description: functionSchema2.shape.description.nullish(),
6518
+ prompt_data: functionSchema2.shape.prompt_data.nullish(),
6519
+ function_data: functionSchema2.shape.function_data.nullish(),
6520
+ tags: functionSchema2.shape.tags.nullish()
6521
+ }).openapi("PatchFunction");
6465
6522
  var createRoleBaseSchema = generateBaseTableOpSchema("role");
6466
6523
  var createRoleSchema = z.strictObject({
6467
6524
  name: roleSchema.shape.name,
@@ -6793,6 +6850,7 @@ var promptSessionEventSchema = z.strictObject({
6793
6850
  completion: customTypes.any.describe("Data about the completion"),
6794
6851
  tags: promptSessionEventBaseSchema.shape.tags
6795
6852
  }).openapi("PromptSessionEvent");
6853
+ var functionEventBaseSchema = generateBaseEventOpSchema("function");
6796
6854
  var projectLogsEventBaseSchema = generateBaseEventOpSchema("project");
6797
6855
  var projectLogsEventSchema = z.strictObject({
6798
6856
  id: projectLogsEventBaseSchema.shape.id,
@@ -6975,6 +7033,17 @@ var feedbackPromptRequestSchema = makeFeedbackRequestSchema(
6975
7033
  "prompt",
6976
7034
  feedbackPromptItemSchema
6977
7035
  );
7036
+ var feedbackFunctionRequestBaseSchema = generateBaseEventFeedbackSchema("function");
7037
+ var feedbackFunctionItemSchema = z.strictObject({
7038
+ id: feedbackFunctionRequestBaseSchema.shape.id,
7039
+ comment: feedbackFunctionRequestBaseSchema.shape.comment,
7040
+ metadata: feedbackFunctionRequestBaseSchema.shape.metadata,
7041
+ source: feedbackFunctionRequestBaseSchema.shape.source
7042
+ }).openapi("FeedbackFunctionItem");
7043
+ var feedbackFunctionRequestSchema = makeFeedbackRequestSchema(
7044
+ "function",
7045
+ feedbackFunctionItemSchema
7046
+ );
6978
7047
  var feedbackPromptSessionRequestBaseSchema = generateBaseEventFeedbackSchema("prompt_session");
6979
7048
  var feedbackPromptSessionItemSchema = z.strictObject({
6980
7049
  id: feedbackPromptSessionRequestBaseSchema.shape.id,
@@ -7025,6 +7094,14 @@ var eventObjectSchemas = {
7025
7094
  feedbackItem: feedbackPromptItemSchema,
7026
7095
  feedbackRequest: feedbackPromptRequestSchema
7027
7096
  },
7097
+ function: {
7098
+ event: functionSchema2,
7099
+ fetchResponse: void 0,
7100
+ insertEvent: void 0,
7101
+ insertRequest: void 0,
7102
+ feedbackItem: feedbackFunctionItemSchema,
7103
+ feedbackRequest: feedbackFunctionRequestSchema
7104
+ },
7028
7105
  prompt_session: {
7029
7106
  event: promptSessionEventSchema,
7030
7107
  fetchResponse: void 0,
@@ -7646,9 +7723,25 @@ var NoopSpan = class {
7646
7723
  close(args) {
7647
7724
  return this.end(args);
7648
7725
  }
7726
+ setAttributes(_args) {
7727
+ }
7649
7728
  };
7650
7729
  var NOOP_SPAN = new NoopSpan();
7651
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
+ }
7652
7745
  id;
7653
7746
  currentExperiment;
7654
7747
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -7659,7 +7752,7 @@ var BraintrustState = class {
7659
7752
  // This is preferable to replacing the whole logger, which would create the
7660
7753
  // possibility of multiple loggers floating around, which may not log in a
7661
7754
  // deterministic order.
7662
- _globalBgLogger;
7755
+ _bgLogger;
7663
7756
  appUrl = null;
7664
7757
  appPublicUrl = null;
7665
7758
  loginToken = null;
@@ -7670,23 +7763,9 @@ var BraintrustState = class {
7670
7763
  gitMetadataSettings;
7671
7764
  _apiConn = null;
7672
7765
  _logConn = null;
7673
- constructor() {
7674
- this.id = v4_default();
7675
- this.currentExperiment = void 0;
7676
- this.currentLogger = void 0;
7677
- this.currentSpan = isomorph_default.newAsyncLocalStorage();
7678
- const defaultGetLogConn = async () => {
7679
- await login();
7680
- return this.logConn();
7681
- };
7682
- this._globalBgLogger = new BackgroundLogger(
7683
- new LazyValue(defaultGetLogConn)
7684
- );
7685
- this.resetLoginInfo();
7686
- globalThis.__inherited_braintrust_state = this;
7687
- }
7688
7766
  resetLoginInfo() {
7689
7767
  this.appUrl = null;
7768
+ this.appPublicUrl = null;
7690
7769
  this.loginToken = null;
7691
7770
  this.orgId = null;
7692
7771
  this.orgName = null;
@@ -7696,6 +7775,28 @@ var BraintrustState = class {
7696
7775
  this._apiConn = null;
7697
7776
  this._logConn = null;
7698
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
+ }
7699
7800
  apiConn() {
7700
7801
  if (!this._apiConn) {
7701
7802
  if (!this.appUrl) {
@@ -7714,22 +7815,24 @@ var BraintrustState = class {
7714
7815
  }
7715
7816
  return this._logConn;
7716
7817
  }
7717
- globalBgLogger() {
7718
- return this._globalBgLogger;
7818
+ bgLogger() {
7819
+ return this._bgLogger;
7719
7820
  }
7720
7821
  // Should only be called by the login function.
7721
7822
  loginReplaceLogConn(logConn) {
7722
- this._globalBgLogger.internalReplaceLogConn(logConn);
7823
+ this._bgLogger.internalReplaceLogConn(logConn);
7723
7824
  }
7724
7825
  };
7725
- var _state;
7826
+ var _globalState;
7726
7827
  function _internalSetInitialState() {
7727
- if (_state) {
7828
+ if (_globalState) {
7728
7829
  throw new Error("Cannot set initial state more than once");
7729
7830
  }
7730
- _state = globalThis.__inherited_braintrust_state || new BraintrustState();
7831
+ _globalState = globalThis.__inherited_braintrust_state || new BraintrustState({
7832
+ /*empty login options*/
7833
+ });
7731
7834
  }
7732
- var _internalGetGlobalState = () => _state;
7835
+ var _internalGetGlobalState = () => _globalState;
7733
7836
  var FailedHTTPResponse = class extends Error {
7734
7837
  status;
7735
7838
  text;
@@ -7850,7 +7953,7 @@ var HTTPConnection = class _HTTPConnection {
7850
7953
  return await resp.json();
7851
7954
  }
7852
7955
  };
7853
- function logFeedbackImpl(parentObjectType, parentObjectId, {
7956
+ function logFeedbackImpl(state, parentObjectType, parentObjectId, {
7854
7957
  id,
7855
7958
  expected,
7856
7959
  scores,
@@ -7893,7 +7996,7 @@ function logFeedbackImpl(parentObjectType, parentObjectId, {
7893
7996
  [IS_MERGE_FIELD]: true
7894
7997
  };
7895
7998
  });
7896
- _state.globalBgLogger().log([record]);
7999
+ state.bgLogger().log([record]);
7897
8000
  }
7898
8001
  if (!isEmpty(comment)) {
7899
8002
  const record = new LazyValue(async () => {
@@ -7913,10 +8016,10 @@ function logFeedbackImpl(parentObjectType, parentObjectId, {
7913
8016
  [AUDIT_METADATA_FIELD]: metadata
7914
8017
  };
7915
8018
  });
7916
- _state.globalBgLogger().log([record]);
8019
+ state.bgLogger().log([record]);
7917
8020
  }
7918
8021
  }
7919
- function spanComponentsToObjectIdLambda(components) {
8022
+ function spanComponentsToObjectIdLambda(state, components) {
7920
8023
  if (components.objectId) {
7921
8024
  const ret = components.objectId;
7922
8025
  return async () => ret;
@@ -7932,8 +8035,9 @@ function spanComponentsToObjectIdLambda(components) {
7932
8035
  "Impossible: computeObjectMetadataArgs not supported for experiments"
7933
8036
  );
7934
8037
  case SpanObjectTypeV2.PROJECT_LOGS:
7935
- const args = components.computeObjectMetadataArgs;
7936
- return async () => (await computeLoggerMetadata(args)).project.id;
8038
+ return async () => (await computeLoggerMetadata(state, {
8039
+ ...components.computeObjectMetadataArgs
8040
+ })).project.id;
7937
8041
  default:
7938
8042
  const x = components.objectType;
7939
8043
  throw new Error(`Unknown object type: ${x}`);
@@ -7952,7 +8056,10 @@ function startSpanParentArgs(args) {
7952
8056
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.objectType}`
7953
8057
  );
7954
8058
  }
7955
- const parentComponentsObjectIdLambda = spanComponentsToObjectIdLambda(parentComponents);
8059
+ const parentComponentsObjectIdLambda = spanComponentsToObjectIdLambda(
8060
+ args.state,
8061
+ parentComponents
8062
+ );
7956
8063
  const computeParentObjectId = async () => {
7957
8064
  const parentComponentsObjectId = await parentComponentsObjectIdLambda();
7958
8065
  if (await args.parentObjectId.get() !== parentComponentsObjectId) {
@@ -7981,6 +8088,7 @@ function startSpanParentArgs(args) {
7981
8088
  };
7982
8089
  }
7983
8090
  var Logger = class {
8091
+ state;
7984
8092
  lazyMetadata;
7985
8093
  _asyncFlush;
7986
8094
  computeMetadataArgs;
@@ -7989,13 +8097,14 @@ var Logger = class {
7989
8097
  calledStartSpan;
7990
8098
  // For type identification.
7991
8099
  kind = "logger";
7992
- constructor(lazyMetadata, logOptions = {}) {
8100
+ constructor(state, lazyMetadata, logOptions = {}) {
7993
8101
  this.lazyMetadata = lazyMetadata;
7994
8102
  this._asyncFlush = logOptions.asyncFlush;
7995
8103
  this.computeMetadataArgs = logOptions.computeMetadataArgs;
7996
8104
  this.lastStartTime = getCurrentUnixTimestamp();
7997
8105
  this.lazyId = new LazyValue(async () => await this.id);
7998
8106
  this.calledStartSpan = false;
8107
+ this.state = state;
7999
8108
  }
8000
8109
  get org_id() {
8001
8110
  return (async () => {
@@ -8087,7 +8196,9 @@ var Logger = class {
8087
8196
  }
8088
8197
  startSpanImpl(args) {
8089
8198
  return new SpanImpl({
8199
+ state: this.state,
8090
8200
  ...startSpanParentArgs({
8201
+ state: this.state,
8091
8202
  parent: args?.parent,
8092
8203
  parentObjectType: this.parentObjectType(),
8093
8204
  parentObjectId: this.lazyId,
@@ -8110,7 +8221,7 @@ var Logger = class {
8110
8221
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
8111
8222
  */
8112
8223
  logFeedback(event) {
8113
- logFeedbackImpl(this.parentObjectType(), this.lazyId, event);
8224
+ logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
8114
8225
  }
8115
8226
  /**
8116
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.
@@ -8133,7 +8244,7 @@ var Logger = class {
8133
8244
  * Flush any pending logs to the server.
8134
8245
  */
8135
8246
  async flush() {
8136
- return await _state.globalBgLogger().flush();
8247
+ return await this.state.bgLogger().flush();
8137
8248
  }
8138
8249
  get asyncFlush() {
8139
8250
  return this._asyncFlush;
@@ -8498,29 +8609,27 @@ function init(projectOrOptions, optionalOptions) {
8498
8609
  gitMetadataSettings,
8499
8610
  projectId,
8500
8611
  baseExperimentId,
8501
- repoInfo
8612
+ repoInfo,
8613
+ state: stateArg
8502
8614
  } = options;
8503
8615
  if (open && update) {
8504
8616
  throw new Error("Cannot open and update an experiment at the same time");
8505
8617
  }
8618
+ const state = stateArg ?? _globalState;
8506
8619
  if (open) {
8507
8620
  if (isEmpty(experiment)) {
8508
8621
  throw new Error(`Cannot open an experiment without specifying its name`);
8509
8622
  }
8510
8623
  const lazyMetadata2 = new LazyValue(
8511
8624
  async () => {
8512
- await login({
8513
- orgName,
8514
- apiKey,
8515
- appUrl
8516
- });
8625
+ await state.login({ apiKey, appUrl, orgName });
8517
8626
  const args = {
8518
8627
  project_name: project,
8519
8628
  project_id: projectId,
8520
- org_name: _state.orgName,
8629
+ org_name: state.orgName,
8521
8630
  experiment_name: experiment
8522
8631
  };
8523
- const response = await _state.apiConn().post_json("api/experiment/get", args);
8632
+ const response = await state.apiConn().post_json("api/experiment/get", args);
8524
8633
  if (response.length === 0) {
8525
8634
  throw new Error(
8526
8635
  `Experiment ${experiment} not found in project ${projectId ?? project}.`
@@ -8542,20 +8651,17 @@ function init(projectOrOptions, optionalOptions) {
8542
8651
  }
8543
8652
  );
8544
8653
  return new ReadonlyExperiment(
8654
+ stateArg ?? _globalState,
8545
8655
  lazyMetadata2
8546
8656
  );
8547
8657
  }
8548
8658
  const lazyMetadata = new LazyValue(
8549
8659
  async () => {
8550
- await login({
8551
- orgName,
8552
- apiKey,
8553
- appUrl
8554
- });
8660
+ await state.login({ apiKey, appUrl, orgName });
8555
8661
  const args = {
8556
8662
  project_name: project,
8557
8663
  project_id: projectId,
8558
- org_id: _state.orgId,
8664
+ org_id: state.orgId,
8559
8665
  update
8560
8666
  };
8561
8667
  if (experiment) {
@@ -8569,7 +8675,7 @@ function init(projectOrOptions, optionalOptions) {
8569
8675
  return repoInfo;
8570
8676
  }
8571
8677
  let mergedGitMetadataSettings = {
8572
- ..._state.gitMetadataSettings || {
8678
+ ...state.gitMetadataSettings || {
8573
8679
  collect: "all"
8574
8680
  }
8575
8681
  };
@@ -8604,7 +8710,7 @@ function init(projectOrOptions, optionalOptions) {
8604
8710
  let response = null;
8605
8711
  while (true) {
8606
8712
  try {
8607
- response = await _state.apiConn().post_json("api/experiment/register", args);
8713
+ response = await state.apiConn().post_json("api/experiment/register", args);
8608
8714
  break;
8609
8715
  } catch (e) {
8610
8716
  if (args["base_experiment"] && `${"data" in e && e.data}`.includes("base experiment")) {
@@ -8631,9 +8737,9 @@ function init(projectOrOptions, optionalOptions) {
8631
8737
  };
8632
8738
  }
8633
8739
  );
8634
- const ret = new Experiment(lazyMetadata, dataset);
8740
+ const ret = new Experiment(state, lazyMetadata, dataset);
8635
8741
  if (options.setCurrent ?? true) {
8636
- _state.currentExperiment = ret;
8742
+ state.currentExperiment = ret;
8637
8743
  }
8638
8744
  return ret;
8639
8745
  }
@@ -8688,23 +8794,25 @@ function initDataset(projectOrOptions, optionalOptions) {
8688
8794
  apiKey,
8689
8795
  orgName,
8690
8796
  projectId,
8691
- useOutput: legacy
8797
+ useOutput: legacy,
8798
+ state: stateArg
8692
8799
  } = options;
8800
+ const state = stateArg ?? _globalState;
8693
8801
  const lazyMetadata = new LazyValue(
8694
8802
  async () => {
8695
- await login({
8803
+ await state.login({
8696
8804
  orgName,
8697
8805
  apiKey,
8698
8806
  appUrl
8699
8807
  });
8700
8808
  const args = {
8701
- org_id: _state.orgId,
8809
+ org_id: state.orgId,
8702
8810
  project_name: project,
8703
8811
  project_id: projectId,
8704
8812
  dataset_name: dataset,
8705
8813
  description
8706
8814
  };
8707
- const response = await _state.apiConn().post_json("api/dataset/register", args);
8815
+ const response = await state.apiConn().post_json("api/dataset/register", args);
8708
8816
  return {
8709
8817
  project: {
8710
8818
  id: response.project.id,
@@ -8719,7 +8827,7 @@ function initDataset(projectOrOptions, optionalOptions) {
8719
8827
  };
8720
8828
  }
8721
8829
  );
8722
- return new Dataset(lazyMetadata, version, legacy);
8830
+ return new Dataset(stateArg ?? _globalState, lazyMetadata, version, legacy);
8723
8831
  }
8724
8832
  function withDataset(project, callback, options = {}) {
8725
8833
  console.warn(
@@ -8728,14 +8836,13 @@ function withDataset(project, callback, options = {}) {
8728
8836
  const dataset = initDataset(project, options);
8729
8837
  return callback(dataset);
8730
8838
  }
8731
- async function computeLoggerMetadata({
8839
+ async function computeLoggerMetadata(state, {
8732
8840
  project_name,
8733
8841
  project_id
8734
8842
  }) {
8735
- await login();
8736
- const org_id = _state.orgId;
8737
- if (project_id === void 0) {
8738
- 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", {
8739
8846
  project_name: project_name || GLOBAL_PROJECT,
8740
8847
  org_id
8741
8848
  });
@@ -8747,8 +8854,8 @@ async function computeLoggerMetadata({
8747
8854
  fullInfo: response.project
8748
8855
  }
8749
8856
  };
8750
- } else if (project_name === void 0) {
8751
- 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", {
8752
8859
  id: project_id
8753
8860
  });
8754
8861
  return {
@@ -8774,29 +8881,31 @@ function initLogger(options = {}) {
8774
8881
  appUrl,
8775
8882
  apiKey,
8776
8883
  orgName,
8777
- forceLogin
8884
+ forceLogin,
8885
+ state: stateArg
8778
8886
  } = options || {};
8779
8887
  const computeMetadataArgs = {
8780
8888
  project_name: projectName,
8781
8889
  project_id: projectId
8782
8890
  };
8891
+ const state = stateArg ?? _globalState;
8783
8892
  const lazyMetadata = new LazyValue(
8784
8893
  async () => {
8785
- await login({
8894
+ await state.login({
8786
8895
  orgName,
8787
8896
  apiKey,
8788
8897
  appUrl,
8789
8898
  forceLogin
8790
8899
  });
8791
- return computeLoggerMetadata(computeMetadataArgs);
8900
+ return computeLoggerMetadata(state, computeMetadataArgs);
8792
8901
  }
8793
8902
  );
8794
- const ret = new Logger(lazyMetadata, {
8903
+ const ret = new Logger(state, lazyMetadata, {
8795
8904
  asyncFlush,
8796
8905
  computeMetadataArgs
8797
8906
  });
8798
8907
  if (options.setCurrent ?? true) {
8799
- _state.currentLogger = ret;
8908
+ state.currentLogger = ret;
8800
8909
  }
8801
8910
  return ret;
8802
8911
  }
@@ -8809,7 +8918,8 @@ async function loadPrompt({
8809
8918
  noTrace = false,
8810
8919
  appUrl,
8811
8920
  apiKey,
8812
- orgName
8921
+ orgName,
8922
+ state: stateArg
8813
8923
  }) {
8814
8924
  if (isEmpty(projectName) && isEmpty(projectId)) {
8815
8925
  throw new Error("Must specify either projectName or projectId");
@@ -8817,7 +8927,8 @@ async function loadPrompt({
8817
8927
  if (isEmpty(slug)) {
8818
8928
  throw new Error("Must specify slug");
8819
8929
  }
8820
- await login({
8930
+ const state = stateArg ?? _globalState;
8931
+ state.login({
8821
8932
  orgName,
8822
8933
  apiKey,
8823
8934
  appUrl
@@ -8828,7 +8939,7 @@ async function loadPrompt({
8828
8939
  slug,
8829
8940
  version
8830
8941
  };
8831
- const response = await _state.logConn().get_json("v1/prompt", args);
8942
+ const response = await state.logConn().get_json("v1/prompt", args);
8832
8943
  if (!("objects" in response) || response.objects.length === 0) {
8833
8944
  throw new Error(
8834
8945
  `Prompt ${slug} not found in ${[projectName ?? projectId]}`
@@ -8843,7 +8954,7 @@ async function loadPrompt({
8843
8954
  }
8844
8955
  async function login(options = {}) {
8845
8956
  let { forceLogin = false } = options || {};
8846
- if (_state.loggedIn && !forceLogin) {
8957
+ if (_globalState.loggedIn && !forceLogin) {
8847
8958
  let checkUpdatedParam2 = function(varname, arg, orig) {
8848
8959
  if (!isEmpty(arg) && !isEmpty(orig) && arg !== orig) {
8849
8960
  throw new Error(
@@ -8852,28 +8963,32 @@ async function login(options = {}) {
8852
8963
  }
8853
8964
  };
8854
8965
  var checkUpdatedParam = checkUpdatedParam2;
8855
- checkUpdatedParam2("appUrl", options.appUrl, _state.appUrl);
8966
+ checkUpdatedParam2("appUrl", options.appUrl, _globalState.appUrl);
8856
8967
  checkUpdatedParam2(
8857
8968
  "apiKey",
8858
8969
  options.apiKey ? HTTPConnection.sanitize_token(options.apiKey) : void 0,
8859
- _state.loginToken
8970
+ _globalState.loginToken
8860
8971
  );
8861
- checkUpdatedParam2("orgName", options.orgName, _state.orgName);
8862
- return;
8972
+ checkUpdatedParam2("orgName", options.orgName, _globalState.orgName);
8973
+ return _globalState;
8863
8974
  }
8975
+ await _globalState.login(options);
8976
+ }
8977
+ async function loginToState(options = {}) {
8864
8978
  const {
8865
8979
  appUrl = isomorph_default.getEnv("BRAINTRUST_APP_URL") || "https://www.braintrust.dev",
8866
8980
  apiKey = isomorph_default.getEnv("BRAINTRUST_API_KEY"),
8867
8981
  orgName = isomorph_default.getEnv("BRAINTRUST_ORG_NAME")
8868
8982
  } = options || {};
8869
8983
  const appPublicUrl = isomorph_default.getEnv("BRAINTRUST_APP_PUBLIC_URL") || appUrl;
8870
- _state.resetLoginInfo();
8871
- _state.appUrl = appUrl;
8872
- _state.appPublicUrl = appPublicUrl;
8984
+ const state = new BraintrustState(options);
8985
+ state.resetLoginInfo();
8986
+ state.appUrl = appUrl;
8987
+ state.appPublicUrl = appPublicUrl;
8873
8988
  let conn = null;
8874
8989
  if (apiKey !== void 0) {
8875
8990
  const resp = await checkResponse(
8876
- await fetch(_urljoin(_state.appUrl, `/api/apikey/login`), {
8991
+ await fetch(_urljoin(state.appUrl, `/api/apikey/login`), {
8877
8992
  method: "POST",
8878
8993
  headers: {
8879
8994
  "Content-Type": "application/json"
@@ -8884,8 +8999,8 @@ async function login(options = {}) {
8884
8999
  })
8885
9000
  );
8886
9001
  const info = await resp.json();
8887
- _check_org_info(info.org_info, orgName);
8888
- conn = _state.logConn();
9002
+ _check_org_info(state, info.org_info, orgName);
9003
+ conn = state.logConn();
8889
9004
  conn.set_token(apiKey);
8890
9005
  } else {
8891
9006
  throw new Error(
@@ -8896,10 +9011,11 @@ async function login(options = {}) {
8896
9011
  throw new Error("Conn should be set at this point (a bug)");
8897
9012
  }
8898
9013
  conn.make_long_lived();
8899
- _state.apiConn().set_token(apiKey);
8900
- _state.loginToken = conn.token;
8901
- _state.loggedIn = true;
8902
- _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;
8903
9019
  }
8904
9020
  function log(event) {
8905
9021
  console.warn(
@@ -8921,17 +9037,21 @@ async function summarize(options = {}) {
8921
9037
  }
8922
9038
  return await e.summarize(options);
8923
9039
  }
8924
- function currentExperiment() {
8925
- return _state.currentExperiment;
9040
+ function currentExperiment(options) {
9041
+ const state = options?.state ?? _globalState;
9042
+ return state.currentExperiment;
8926
9043
  }
8927
9044
  function currentLogger(options) {
8928
- return castLogger(_state.currentLogger, options?.asyncFlush);
9045
+ const state = options?.state ?? _globalState;
9046
+ return castLogger(state.currentLogger, options?.asyncFlush);
8929
9047
  }
8930
- function currentSpan() {
8931
- return _state.currentSpan.getStore() ?? NOOP_SPAN;
9048
+ function currentSpan(options) {
9049
+ const state = options?.state ?? _globalState;
9050
+ return state.currentSpan.getStore() ?? NOOP_SPAN;
8932
9051
  }
8933
9052
  function getSpanParentObject(options) {
8934
- const parentSpan = currentSpan();
9053
+ const state = options?.state ?? _globalState;
9054
+ const parentSpan = currentSpan({ state });
8935
9055
  if (!Object.is(parentSpan, NOOP_SPAN)) {
8936
9056
  return parentSpan;
8937
9057
  }
@@ -8972,10 +9092,12 @@ function traced(callback, args) {
8972
9092
  function startSpan(args) {
8973
9093
  return startSpanAndIsLogger(args).span;
8974
9094
  }
8975
- async function flush() {
8976
- return await _state.globalBgLogger().flush();
9095
+ async function flush(options) {
9096
+ const state = options?.state ?? _globalState;
9097
+ return await state.bgLogger().flush();
8977
9098
  }
8978
9099
  function startSpanAndIsLogger(args) {
9100
+ const state = args?.state ?? _globalState;
8979
9101
  if (args?.parent) {
8980
9102
  const components = SpanComponentsV2.fromStr(args?.parent);
8981
9103
  const parentSpanIds = components.rowIds ? {
@@ -8983,9 +9105,12 @@ function startSpanAndIsLogger(args) {
8983
9105
  rootSpanId: components.rowIds.rootSpanId
8984
9106
  } : void 0;
8985
9107
  const span = new SpanImpl({
9108
+ state,
8986
9109
  ...args,
8987
9110
  parentObjectType: components.objectType,
8988
- parentObjectId: new LazyValue(spanComponentsToObjectIdLambda(components)),
9111
+ parentObjectId: new LazyValue(
9112
+ spanComponentsToObjectIdLambda(state, components)
9113
+ ),
8989
9114
  parentComputeObjectMetadataArgs: components.computeObjectMetadataArgs,
8990
9115
  parentSpanIds
8991
9116
  });
@@ -9001,23 +9126,23 @@ function startSpanAndIsLogger(args) {
9001
9126
  return { span, isLogger: parentObject.kind === "logger" };
9002
9127
  }
9003
9128
  }
9004
- function withCurrent(span, callback) {
9005
- return _state.currentSpan.run(span, () => callback(span));
9129
+ function withCurrent(span, callback, state = _globalState) {
9130
+ return state.currentSpan.run(span, () => callback(span));
9006
9131
  }
9007
- function _check_org_info(org_info, org_name) {
9132
+ function _check_org_info(state, org_info, org_name) {
9008
9133
  if (org_info.length === 0) {
9009
9134
  throw new Error("This user is not part of any organizations.");
9010
9135
  }
9011
9136
  for (const org of org_info) {
9012
9137
  if (org_name === void 0 || org.name === org_name) {
9013
- _state.orgId = org.id;
9014
- _state.orgName = org.name;
9015
- _state.logUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
9016
- _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;
9017
9142
  break;
9018
9143
  }
9019
9144
  }
9020
- if (_state.orgId === void 0) {
9145
+ if (state.orgId === void 0) {
9021
9146
  throw new Error(
9022
9147
  `Organization ${org_name} not found. Must be one of ${org_info.map((x) => x.name).join(", ")}`
9023
9148
  );
@@ -9176,15 +9301,17 @@ var Experiment = class extends ObjectFetcher {
9176
9301
  lastStartTime;
9177
9302
  lazyId;
9178
9303
  calledStartSpan;
9304
+ state;
9179
9305
  // For type identification.
9180
9306
  kind = "experiment";
9181
- constructor(lazyMetadata, dataset) {
9307
+ constructor(state, lazyMetadata, dataset) {
9182
9308
  super("experiment", void 0);
9183
9309
  this.lazyMetadata = lazyMetadata;
9184
9310
  this.dataset = dataset;
9185
9311
  this.lastStartTime = getCurrentUnixTimestamp();
9186
9312
  this.lazyId = new LazyValue(async () => await this.id);
9187
9313
  this.calledStartSpan = false;
9314
+ this.state = state;
9188
9315
  }
9189
9316
  get id() {
9190
9317
  return (async () => {
@@ -9206,7 +9333,7 @@ var Experiment = class extends ObjectFetcher {
9206
9333
  }
9207
9334
  async getState() {
9208
9335
  await this.lazyMetadata.get();
9209
- return _state;
9336
+ return this.state;
9210
9337
  }
9211
9338
  /**
9212
9339
  * Log a single event to the experiment. The event will be batched and uploaded behind the scenes.
@@ -9268,7 +9395,9 @@ var Experiment = class extends ObjectFetcher {
9268
9395
  }
9269
9396
  startSpanImpl(args) {
9270
9397
  return new SpanImpl({
9398
+ state: this.state,
9271
9399
  ...startSpanParentArgs({
9400
+ state: this.state,
9272
9401
  parent: args?.parent,
9273
9402
  parentObjectType: this.parentObjectType(),
9274
9403
  parentObjectId: this.lazyId,
@@ -9362,7 +9491,7 @@ var Experiment = class extends ObjectFetcher {
9362
9491
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
9363
9492
  */
9364
9493
  logFeedback(event) {
9365
- logFeedbackImpl(this.parentObjectType(), this.lazyId, event);
9494
+ logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
9366
9495
  }
9367
9496
  /**
9368
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.
@@ -9377,7 +9506,7 @@ var Experiment = class extends ObjectFetcher {
9377
9506
  * Flush any pending rows to the server.
9378
9507
  */
9379
9508
  async flush() {
9380
- return await _state.globalBgLogger().flush();
9509
+ return await this.state.bgLogger().flush();
9381
9510
  }
9382
9511
  /**
9383
9512
  * This function is deprecated. You can simply remove it from your code.
@@ -9390,8 +9519,9 @@ var Experiment = class extends ObjectFetcher {
9390
9519
  }
9391
9520
  };
9392
9521
  var ReadonlyExperiment = class extends ObjectFetcher {
9393
- constructor(lazyMetadata) {
9522
+ constructor(state, lazyMetadata) {
9394
9523
  super("experiment", void 0);
9524
+ this.state = state;
9395
9525
  this.lazyMetadata = lazyMetadata;
9396
9526
  }
9397
9527
  get id() {
@@ -9406,7 +9536,7 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9406
9536
  }
9407
9537
  async getState() {
9408
9538
  await this.lazyMetadata.get();
9409
- return _state;
9539
+ return this.state;
9410
9540
  }
9411
9541
  async *asDataset() {
9412
9542
  const records = this.fetch();
@@ -9432,10 +9562,13 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9432
9562
  }
9433
9563
  };
9434
9564
  var executionCounter = 0;
9565
+ function newId() {
9566
+ return v4_default();
9567
+ }
9435
9568
  var SpanImpl = class _SpanImpl {
9569
+ state;
9436
9570
  // `internalData` contains fields that are not part of the "user-sanitized"
9437
9571
  // set of fields which we want to log in just one of the span rows.
9438
- internalData;
9439
9572
  isMerge;
9440
9573
  loggedEndTime;
9441
9574
  // For internal use only.
@@ -9448,6 +9581,7 @@ var SpanImpl = class _SpanImpl {
9448
9581
  spanParents;
9449
9582
  kind = "span";
9450
9583
  constructor(args) {
9584
+ this.state = args.state;
9451
9585
  const spanAttributes = args.spanAttributes ?? {};
9452
9586
  const event = args.event ?? {};
9453
9587
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -9470,7 +9604,7 @@ var SpanImpl = class _SpanImpl {
9470
9604
  }
9471
9605
  return "subspan";
9472
9606
  })();
9473
- this.internalData = {
9607
+ const internalData = {
9474
9608
  metrics: {
9475
9609
  start: args.startTime ?? getCurrentUnixTimestamp()
9476
9610
  },
@@ -9494,17 +9628,25 @@ var SpanImpl = class _SpanImpl {
9494
9628
  }
9495
9629
  this.isMerge = false;
9496
9630
  const { id: _id, ...eventRest } = event;
9497
- this.log(eventRest);
9631
+ this.logInternal({ event: eventRest, internalData });
9498
9632
  this.isMerge = true;
9499
9633
  }
9500
9634
  get id() {
9501
9635
  return this._id;
9502
9636
  }
9637
+ setAttributes(args) {
9638
+ this.logInternal({ internalData: { span_attributes: args } });
9639
+ }
9503
9640
  log(event) {
9504
- const sanitized = validateAndSanitizeExperimentLogPartialArgs(event);
9505
- 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 };
9506
9649
  mergeDicts(sanitizedAndInternalData, sanitized);
9507
- this.internalData = {};
9508
9650
  let partialRecord = {
9509
9651
  id: this.id,
9510
9652
  span_id: this.spanId,
@@ -9528,10 +9670,10 @@ var SpanImpl = class _SpanImpl {
9528
9670
  objectId: await this.parentObjectId.get()
9529
9671
  }).objectIdFields()
9530
9672
  });
9531
- _state.globalBgLogger().log([new LazyValue(computeRecord)]);
9673
+ this.state.bgLogger().log([new LazyValue(computeRecord)]);
9532
9674
  }
9533
9675
  logFeedback(event) {
9534
- logFeedbackImpl(this.parentObjectType, this.parentObjectId, {
9676
+ logFeedbackImpl(this.state, this.parentObjectType, this.parentObjectId, {
9535
9677
  ...event,
9536
9678
  id: this.id
9537
9679
  });
@@ -9553,8 +9695,10 @@ var SpanImpl = class _SpanImpl {
9553
9695
  startSpan(args) {
9554
9696
  const parentSpanIds = args?.parent ? void 0 : { spanId: this.spanId, rootSpanId: this.rootSpanId };
9555
9697
  return new _SpanImpl({
9698
+ state: this.state,
9556
9699
  ...args,
9557
9700
  ...startSpanParentArgs({
9701
+ state: this.state,
9558
9702
  parent: args?.parent,
9559
9703
  parentObjectType: this.parentObjectType,
9560
9704
  parentObjectId: this.parentObjectId,
@@ -9565,13 +9709,14 @@ var SpanImpl = class _SpanImpl {
9565
9709
  }
9566
9710
  end(args) {
9567
9711
  let endTime;
9712
+ let internalData = {};
9568
9713
  if (!this.loggedEndTime) {
9569
9714
  endTime = args?.endTime ?? getCurrentUnixTimestamp();
9570
- this.internalData = { metrics: { end: endTime } };
9715
+ internalData = { metrics: { end: endTime } };
9571
9716
  } else {
9572
9717
  endTime = this.loggedEndTime;
9573
9718
  }
9574
- this.log({});
9719
+ this.logInternal({ internalData });
9575
9720
  return endTime;
9576
9721
  }
9577
9722
  async export() {
@@ -9594,15 +9739,14 @@ var SpanImpl = class _SpanImpl {
9594
9739
  }).toStr();
9595
9740
  }
9596
9741
  async flush() {
9597
- return await _state.globalBgLogger().flush();
9742
+ return await this.state.bgLogger().flush();
9598
9743
  }
9599
9744
  close(args) {
9600
9745
  return this.end(args);
9601
9746
  }
9602
9747
  };
9603
9748
  var Dataset = class extends ObjectFetcher {
9604
- lazyMetadata;
9605
- constructor(lazyMetadata, pinnedVersion, legacy) {
9749
+ constructor(state, lazyMetadata, pinnedVersion, legacy) {
9606
9750
  const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
9607
9751
  if (isLegacyDataset) {
9608
9752
  console.warn(
@@ -9614,8 +9758,10 @@ var Dataset = class extends ObjectFetcher {
9614
9758
  pinnedVersion,
9615
9759
  (r) => ensureDatasetRecord(r, isLegacyDataset)
9616
9760
  );
9761
+ this.state = state;
9617
9762
  this.lazyMetadata = lazyMetadata;
9618
9763
  }
9764
+ lazyMetadata;
9619
9765
  get id() {
9620
9766
  return (async () => {
9621
9767
  return (await this.lazyMetadata.get()).dataset.id;
@@ -9633,7 +9779,7 @@ var Dataset = class extends ObjectFetcher {
9633
9779
  }
9634
9780
  async getState() {
9635
9781
  await this.lazyMetadata.get();
9636
- return _state;
9782
+ return this.state;
9637
9783
  }
9638
9784
  /**
9639
9785
  * Insert a single record to the dataset. The record will be batched and uploaded behind the scenes. If you pass in an `id`,
@@ -9684,7 +9830,7 @@ var Dataset = class extends ObjectFetcher {
9684
9830
  created: (/* @__PURE__ */ new Date()).toISOString(),
9685
9831
  metadata
9686
9832
  }));
9687
- _state.globalBgLogger().log([args]);
9833
+ this.state.bgLogger().log([args]);
9688
9834
  return rowId;
9689
9835
  }
9690
9836
  delete(id) {
@@ -9694,7 +9840,7 @@ var Dataset = class extends ObjectFetcher {
9694
9840
  created: (/* @__PURE__ */ new Date()).toISOString(),
9695
9841
  _object_delete: true
9696
9842
  }));
9697
- _state.globalBgLogger().log([args]);
9843
+ this.state.bgLogger().log([args]);
9698
9844
  return id;
9699
9845
  }
9700
9846
  /**
@@ -9735,7 +9881,7 @@ var Dataset = class extends ObjectFetcher {
9735
9881
  * Flush any pending rows to the server.
9736
9882
  */
9737
9883
  async flush() {
9738
- return await _state.globalBgLogger().flush();
9884
+ return await this.state.bgLogger().flush();
9739
9885
  }
9740
9886
  /**
9741
9887
  * This function is deprecated. You can simply remove it from your code.
@@ -9820,13 +9966,18 @@ var Prompt = class {
9820
9966
  if (!prompt) {
9821
9967
  throw new Error("Empty prompt");
9822
9968
  }
9969
+ const dictArgParsed = z.record(z.unknown()).safeParse(buildArgs);
9970
+ const variables = {
9971
+ input: buildArgs,
9972
+ ...dictArgParsed.success ? dictArgParsed.data : {}
9973
+ };
9823
9974
  if (flavor === "chat") {
9824
9975
  if (prompt.type !== "chat") {
9825
9976
  throw new Error(
9826
9977
  "Prompt is a completion prompt. Use buildCompletion() instead"
9827
9978
  );
9828
9979
  }
9829
- const render3 = (template) => mustache_default.render(template, buildArgs, void 0, {
9980
+ const render3 = (template) => mustache_default.render(template, variables, void 0, {
9830
9981
  escape: (v) => typeof v === "string" ? v : JSON.stringify(v)
9831
9982
  });
9832
9983
  const messages = (prompt.messages || []).map((m) => ({
@@ -9841,7 +9992,7 @@ var Prompt = class {
9841
9992
  messages,
9842
9993
  ...prompt.tools ? {
9843
9994
  tools: toolsSchema.parse(
9844
- JSON.parse(mustache_default.render(prompt.tools, buildArgs))
9995
+ JSON.parse(mustache_default.render(prompt.tools, variables))
9845
9996
  )
9846
9997
  } : void 0
9847
9998
  };
@@ -9852,7 +10003,7 @@ var Prompt = class {
9852
10003
  return {
9853
10004
  ...params,
9854
10005
  ...spanInfo,
9855
- prompt: mustache_default.render(prompt.content, buildArgs)
10006
+ prompt: mustache_default.render(prompt.content, variables)
9856
10007
  };
9857
10008
  } else {
9858
10009
  throw new Error("never!");
@@ -10002,20 +10153,29 @@ function wrapBetaChatCompletion(completion) {
10002
10153
  return ret;
10003
10154
  };
10004
10155
  }
10005
- var X_CACHED_HEADER = "x-cached";
10156
+ var LEGACY_CACHED_HEADER = "x-cached";
10157
+ var X_CACHED_HEADER = "x-bt-cached";
10006
10158
  function parseCachedHeader(value) {
10007
- return isEmpty(value) ? void 0 : value.toLowerCase() === "true" ? 1 : 0;
10159
+ return isEmpty(value) ? void 0 : ["true", "hit"].includes(value.toLowerCase()) ? 1 : 0;
10008
10160
  }
10009
10161
  function logHeaders(response, span) {
10010
10162
  const cachedHeader = response.headers.get(X_CACHED_HEADER);
10011
10163
  if (isEmpty(cachedHeader)) {
10012
- return;
10013
- }
10014
- span.log({
10015
- metrics: {
10016
- 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
+ });
10017
10171
  }
10018
- });
10172
+ } else {
10173
+ span.log({
10174
+ metrics: {
10175
+ cached: parseCachedHeader(cachedHeader)
10176
+ }
10177
+ });
10178
+ }
10019
10179
  }
10020
10180
  function wrapChatCompletion(completion) {
10021
10181
  return async (allParams, options) => {
@@ -10135,7 +10295,16 @@ function postprocessStreamingResults(allResults) {
10135
10295
  let content = void 0;
10136
10296
  let tool_calls = void 0;
10137
10297
  let finish_reason = void 0;
10298
+ let metrics = {};
10138
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
+ }
10139
10308
  const delta = result.choices?.[0]?.delta;
10140
10309
  if (!delta) {
10141
10310
  continue;
@@ -10163,18 +10332,21 @@ function postprocessStreamingResults(allResults) {
10163
10332
  }
10164
10333
  }
10165
10334
  }
10166
- return [
10167
- {
10168
- index: 0,
10169
- message: {
10170
- role,
10171
- content,
10172
- tool_calls
10173
- },
10174
- logprobs: null,
10175
- finish_reason
10176
- }
10177
- ];
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
+ };
10178
10350
  }
10179
10351
  var WrapperStream = class {
10180
10352
  span;
@@ -10203,7 +10375,7 @@ var WrapperStream = class {
10203
10375
  yield item;
10204
10376
  }
10205
10377
  this.span.log({
10206
- output: postprocessStreamingResults(allResults)
10378
+ ...postprocessStreamingResults(allResults)
10207
10379
  });
10208
10380
  } finally {
10209
10381
  this.span.end();
@@ -10214,8 +10386,10 @@ var WrapperStream = class {
10214
10386
  // src/browser.ts
10215
10387
  configureBrowser();
10216
10388
  export {
10389
+ BraintrustState,
10217
10390
  Dataset,
10218
10391
  Experiment,
10392
+ LEGACY_CACHED_HEADER,
10219
10393
  Logger,
10220
10394
  NOOP_SPAN,
10221
10395
  NoopSpan,
@@ -10237,6 +10411,8 @@ export {
10237
10411
  loadPrompt,
10238
10412
  log,
10239
10413
  login,
10414
+ loginToState,
10415
+ newId,
10240
10416
  parseCachedHeader,
10241
10417
  startSpan,
10242
10418
  summarize,