braintrust 0.0.113 → 0.0.115

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,6 +4949,7 @@ var require_pluralize = __commonJS({
4949
4949
  var src_exports = {};
4950
4950
  __export(src_exports, {
4951
4951
  BaseExperiment: () => BaseExperiment,
4952
+ Dataset: () => Dataset,
4952
4953
  Eval: () => Eval,
4953
4954
  Experiment: () => Experiment,
4954
4955
  Logger: () => Logger,
@@ -4956,9 +4957,11 @@ __export(src_exports, {
4956
4957
  NoopSpan: () => NoopSpan,
4957
4958
  Prompt: () => Prompt,
4958
4959
  ReadonlyExperiment: () => ReadonlyExperiment,
4960
+ Reporter: () => Reporter,
4959
4961
  SpanImpl: () => SpanImpl,
4960
4962
  _internalGetGlobalState: () => _internalGetGlobalState,
4961
4963
  _internalSetInitialState: () => _internalSetInitialState,
4964
+ buildLocalSummary: () => buildLocalSummary,
4962
4965
  currentExperiment: () => currentExperiment,
4963
4966
  currentLogger: () => currentLogger,
4964
4967
  currentSpan: () => currentSpan,
@@ -4970,6 +4973,7 @@ __export(src_exports, {
4970
4973
  loadPrompt: () => loadPrompt,
4971
4974
  log: () => log,
4972
4975
  login: () => login,
4976
+ reportFailures: () => reportFailures,
4973
4977
  startSpan: () => startSpan,
4974
4978
  summarize: () => summarize,
4975
4979
  traced: () => traced,
@@ -9466,6 +9470,88 @@ function makeLegacyEvent(e) {
9466
9470
  }
9467
9471
  return event;
9468
9472
  }
9473
+ var SpanParentObjectType = /* @__PURE__ */ ((SpanParentObjectType2) => {
9474
+ SpanParentObjectType2["EXPERIMENT"] = "experiment";
9475
+ SpanParentObjectType2["PROJECT_LOGS"] = "project_logs";
9476
+ return SpanParentObjectType2;
9477
+ })(SpanParentObjectType || {});
9478
+ var _OBJECT_TYPE_TO_PREFIX = {
9479
+ [
9480
+ "experiment"
9481
+ /* EXPERIMENT */
9482
+ ]: "ex",
9483
+ [
9484
+ "project_logs"
9485
+ /* PROJECT_LOGS */
9486
+ ]: "pl"
9487
+ };
9488
+ var _PREFIX_TO_OBJECT_TYPE = Object.fromEntries(
9489
+ Object.entries(_OBJECT_TYPE_TO_PREFIX).map(([k, v]) => [v, k])
9490
+ );
9491
+ var _SEP = ":";
9492
+ var SpanParentComponents = class _SpanParentComponents {
9493
+ constructor(args) {
9494
+ this.objectType = args.objectType;
9495
+ this.objectId = args.objectId;
9496
+ this.rowId = args.rowId;
9497
+ if (!(typeof this.objectType === "string")) {
9498
+ throw new Error("objectType must be a string");
9499
+ }
9500
+ if (!(typeof this.objectId === "string")) {
9501
+ throw new Error("objectId must be a string");
9502
+ }
9503
+ if (!(typeof this.rowId === "string")) {
9504
+ throw new Error("rowId must be a string");
9505
+ }
9506
+ const objectTypePrefix = _OBJECT_TYPE_TO_PREFIX[this.objectType];
9507
+ if (objectTypePrefix.includes(_SEP)) {
9508
+ throw new Error(
9509
+ `objectType prefix ${objectTypePrefix} may not contain separator character ${_SEP}`
9510
+ );
9511
+ }
9512
+ if (this.objectId.includes(_SEP)) {
9513
+ throw new Error(
9514
+ `objectId ${this.objectId} may not contain separator character ${_SEP}`
9515
+ );
9516
+ }
9517
+ }
9518
+ toStr() {
9519
+ return [
9520
+ _OBJECT_TYPE_TO_PREFIX[this.objectType],
9521
+ this.objectId,
9522
+ this.rowId
9523
+ ].join(_SEP);
9524
+ }
9525
+ static fromStr(s) {
9526
+ const items = s.split(_SEP);
9527
+ if (items.length < 3) {
9528
+ throw new Error(
9529
+ `Serialized parent components string must have at least three components. Provided string ${s} has only ${items.length}`
9530
+ );
9531
+ }
9532
+ return new _SpanParentComponents({
9533
+ objectType: _PREFIX_TO_OBJECT_TYPE[items[0]],
9534
+ objectId: items[1],
9535
+ rowId: items.slice(2).join(_SEP)
9536
+ });
9537
+ }
9538
+ asDict() {
9539
+ const out = (() => {
9540
+ switch (this.objectType) {
9541
+ case "experiment":
9542
+ return { experiment_id: this.objectId };
9543
+ case "project_logs":
9544
+ return { project_id: this.objectId, log_id: "g" };
9545
+ default:
9546
+ throw new Error("Impossible");
9547
+ }
9548
+ })();
9549
+ if (this.rowId) {
9550
+ out[PARENT_ID_FIELD] = this.rowId;
9551
+ }
9552
+ return out;
9553
+ }
9554
+ };
9469
9555
  var SpanTypeAttribute = /* @__PURE__ */ ((SpanTypeAttribute22) => {
9470
9556
  SpanTypeAttribute22["LLM"] = "llm";
9471
9557
  SpanTypeAttribute22["SCORE"] = "score";
@@ -13278,62 +13364,66 @@ var modeToTypes = {
13278
13364
  }
13279
13365
  };
13280
13366
  var customTypes = modeToTypes[mode];
13281
- var chatCompletionSystemMessageParamSchema = z.object({
13282
- content: z.string(),
13367
+ var chatCompletionSystemMessageParamSchema = z.strictObject({
13368
+ content: z.string().default(""),
13283
13369
  role: z.literal("system"),
13284
13370
  name: z.string().optional()
13285
13371
  });
13286
- var chatCompletionContentPartTextSchema = z.object({
13287
- text: z.string(),
13372
+ var chatCompletionContentPartTextSchema = z.strictObject({
13373
+ text: z.string().default(""),
13288
13374
  type: z.literal("text")
13289
13375
  });
13290
- var functionCallSchema = z.object({
13376
+ var imageURLSchema = z.strictObject({
13377
+ url: z.string(),
13378
+ detail: z.union([z.literal("auto"), z.literal("low"), z.literal("high")]).optional()
13379
+ });
13380
+ var chatCompletionContentPartImageSchema = z.strictObject({
13381
+ image_url: imageURLSchema,
13382
+ type: z.literal("image_url")
13383
+ });
13384
+ var chatCompletionContentPartSchema = z.union([
13385
+ chatCompletionContentPartTextSchema,
13386
+ chatCompletionContentPartImageSchema
13387
+ ]);
13388
+ var chatCompletionContentSchema = z.union([
13389
+ z.string().default(""),
13390
+ z.array(chatCompletionContentPartSchema)
13391
+ ]);
13392
+ var chatCompletionUserMessageParamSchema = z.strictObject({
13393
+ content: chatCompletionContentSchema,
13394
+ role: z.literal("user"),
13395
+ name: z.string().optional()
13396
+ });
13397
+ var functionCallSchema = z.strictObject({
13291
13398
  arguments: z.string(),
13292
13399
  name: z.string()
13293
13400
  });
13294
- var functionSchema = z.object({
13401
+ var functionSchema = z.strictObject({
13295
13402
  arguments: z.string(),
13296
13403
  name: z.string()
13297
13404
  });
13298
- var imageURLSchema = z.object({
13299
- url: z.string(),
13300
- detail: z.union([z.literal("auto"), z.literal("low"), z.literal("high")]).optional()
13301
- });
13302
- var chatCompletionToolMessageParamSchema = z.object({
13303
- content: z.string(),
13405
+ var chatCompletionToolMessageParamSchema = z.strictObject({
13406
+ content: z.string().default(""),
13304
13407
  role: z.literal("tool"),
13305
13408
  tool_call_id: z.string()
13306
13409
  });
13307
- var chatCompletionFunctionMessageParamSchema = z.object({
13308
- content: z.string().nullable(),
13410
+ var chatCompletionFunctionMessageParamSchema = z.strictObject({
13411
+ content: z.string().default(""),
13309
13412
  name: z.string(),
13310
13413
  role: z.literal("function")
13311
13414
  });
13312
- var chatCompletionContentPartImageSchema = z.object({
13313
- image_url: imageURLSchema,
13314
- type: z.literal("image_url")
13315
- });
13316
- var chatCompletionMessageToolCallSchema = z.object({
13415
+ var chatCompletionMessageToolCallSchema = z.strictObject({
13317
13416
  id: z.string(),
13318
13417
  function: functionSchema,
13319
13418
  type: z.literal("function")
13320
13419
  });
13321
- var chatCompletionContentPartSchema = z.union([
13322
- chatCompletionContentPartTextSchema,
13323
- chatCompletionContentPartImageSchema
13324
- ]);
13325
- var chatCompletionAssistantMessageParamSchema = z.object({
13420
+ var chatCompletionAssistantMessageParamSchema = z.strictObject({
13326
13421
  role: z.literal("assistant"),
13327
- content: z.string().optional().nullable(),
13422
+ content: z.string().nullish(),
13328
13423
  function_call: functionCallSchema.optional(),
13329
13424
  name: z.string().optional(),
13330
13425
  tool_calls: z.array(chatCompletionMessageToolCallSchema).optional()
13331
13426
  });
13332
- var chatCompletionUserMessageParamSchema = z.object({
13333
- content: z.union([z.string(), z.array(chatCompletionContentPartSchema)]),
13334
- role: z.literal("user"),
13335
- name: z.string().optional()
13336
- });
13337
13427
  var chatCompletionMessageParamSchema = z.union([
13338
13428
  chatCompletionSystemMessageParamSchema,
13339
13429
  chatCompletionUserMessageParamSchema,
@@ -13342,12 +13432,12 @@ var chatCompletionMessageParamSchema = z.union([
13342
13432
  chatCompletionFunctionMessageParamSchema
13343
13433
  ]);
13344
13434
  var functionParametersSchema = z.record(z.unknown());
13345
- var functionDefinitionSchema = z.object({
13435
+ var functionDefinitionSchema = z.strictObject({
13346
13436
  name: z.string(),
13347
13437
  description: z.string().optional(),
13348
13438
  parameters: functionParametersSchema.optional()
13349
13439
  });
13350
- var chatCompletionToolSchema = z.object({
13440
+ var chatCompletionToolSchema = z.strictObject({
13351
13441
  function: functionDefinitionSchema,
13352
13442
  type: z.literal("function")
13353
13443
  });
@@ -13361,69 +13451,71 @@ var messageRoleSchema = z.enum([
13361
13451
  "model"
13362
13452
  ]);
13363
13453
  var promptBlockDataSchema = z.union([
13364
- z.object({
13454
+ z.strictObject({
13365
13455
  type: z.literal("completion"),
13366
13456
  content: z.string()
13367
13457
  }),
13368
- z.object({
13458
+ z.strictObject({
13369
13459
  type: z.literal("chat"),
13370
13460
  messages: z.array(chatCompletionMessageParamSchema),
13371
13461
  tools: z.string().optional()
13372
13462
  })
13373
13463
  ]);
13374
- var braintrustModelParamsSchema = z.object({
13464
+ var braintrustModelParamsSchema = z.strictObject({
13375
13465
  use_cache: z.boolean().optional()
13376
13466
  });
13377
13467
  var BRAINTRUST_PARAMS = Object.keys(braintrustModelParamsSchema.shape);
13378
- var openAIModelParamsSchema = z.object({
13379
- temperature: z.number(),
13468
+ var openAIModelParamsSchema = z.strictObject({
13469
+ temperature: z.number().optional(),
13380
13470
  top_p: z.number().optional(),
13381
13471
  max_tokens: z.number().optional(),
13382
13472
  frequency_penalty: z.number().optional(),
13383
13473
  presence_penalty: z.number().optional(),
13384
- response_format: z.union([z.literal(null), z.object({ type: z.literal("json_object") })]).optional(),
13474
+ response_format: z.union([
13475
+ z.literal(null),
13476
+ z.strictObject({ type: z.literal("json_object") })
13477
+ ]).optional(),
13385
13478
  tool_choice: z.union([
13386
13479
  z.literal("auto"),
13387
13480
  z.literal("none"),
13388
- z.object({
13481
+ z.strictObject({
13389
13482
  type: z.literal("function"),
13390
- function: z.object({ name: z.string() })
13483
+ function: z.strictObject({ name: z.string() })
13391
13484
  })
13392
13485
  ]).optional()
13393
13486
  });
13394
- var anthropicModelParamsSchema = z.object({
13487
+ var anthropicModelParamsSchema = z.strictObject({
13395
13488
  max_tokens: z.number(),
13396
13489
  temperature: z.number(),
13397
13490
  top_p: z.number().optional(),
13398
13491
  top_k: z.number().optional(),
13399
13492
  max_tokens_to_sample: z.number().optional().describe("This is a legacy parameter that should not be used.")
13400
13493
  });
13401
- var googleModelParamsSchema = z.object({
13494
+ var googleModelParamsSchema = z.strictObject({
13402
13495
  temperature: z.number(),
13403
13496
  maxOutputTokens: z.number().optional(),
13404
13497
  topP: z.number().optional(),
13405
13498
  topK: z.number().optional()
13406
13499
  });
13407
- var jsCompletionParamsSchema = z.object({});
13408
- var modelParamsSchema = braintrustModelParamsSchema.and(
13409
- z.union([
13410
- openAIModelParamsSchema,
13411
- anthropicModelParamsSchema,
13412
- googleModelParamsSchema,
13413
- jsCompletionParamsSchema
13414
- ])
13415
- );
13416
- var anyModelParamsSchema = openAIModelParamsSchema.and(anthropicModelParamsSchema).and(googleModelParamsSchema).and(braintrustModelParamsSchema);
13417
- var promptOptionsSchema = z.object({
13500
+ var jsCompletionParamsSchema = z.strictObject({});
13501
+ var modelParamsSchema = z.union([
13502
+ braintrustModelParamsSchema.merge(openAIModelParamsSchema),
13503
+ braintrustModelParamsSchema.merge(anthropicModelParamsSchema),
13504
+ braintrustModelParamsSchema.merge(googleModelParamsSchema),
13505
+ braintrustModelParamsSchema.merge(jsCompletionParamsSchema)
13506
+ ]);
13507
+ var anyModelParamsSchema = openAIModelParamsSchema.merge(anthropicModelParamsSchema).merge(googleModelParamsSchema).merge(braintrustModelParamsSchema);
13508
+ var promptOptionsSchema = z.strictObject({
13418
13509
  model: z.string().optional(),
13419
13510
  params: modelParamsSchema.optional(),
13420
13511
  position: z.string().optional()
13421
13512
  });
13422
- var promptDataSchema = z.object({
13513
+ var promptDataSchema = z.strictObject({
13423
13514
  prompt: promptBlockDataSchema.nullish(),
13424
13515
  options: promptOptionsSchema.nullish(),
13425
- origin: z.object({
13516
+ origin: z.strictObject({
13426
13517
  prompt_id: z.string().optional(),
13518
+ project_id: z.string().optional(),
13427
13519
  prompt_version: z.string().optional()
13428
13520
  }).nullish()
13429
13521
  }).openapi("PromptData");
@@ -13433,7 +13525,7 @@ function generateBaseTableSchema(objectName, opts) {
13433
13525
  if (opts == null ? void 0 : opts.uniqueName) {
13434
13526
  nameDescription += `. Within a project, ${objectName} names are unique`;
13435
13527
  }
13436
- return z.object({
13528
+ return z.strictObject({
13437
13529
  id: z.string().uuid().describe(`Unique identifier for the ${objectName}`),
13438
13530
  project_id: z.string().uuid().describe(
13439
13531
  `Unique identifier for the project that the ${objectName} belongs under`
@@ -13449,7 +13541,7 @@ function generateBaseTableSchema(objectName, opts) {
13449
13541
  });
13450
13542
  }
13451
13543
  var userBaseSchema = generateBaseTableSchema("user");
13452
- var userSchema = z.object({
13544
+ var userSchema = z.strictObject({
13453
13545
  id: userBaseSchema.shape.id,
13454
13546
  auth_id: z.string().uuid().nullish().describe("Internal authentication token used to identify the user"),
13455
13547
  given_name: z.string().nullish().describe("Given name of the user"),
@@ -13457,29 +13549,29 @@ var userSchema = z.object({
13457
13549
  email: z.string().nullish().describe("The user's email"),
13458
13550
  avatar_url: z.string().nullish().describe("URL of the user's Avatar image"),
13459
13551
  created: userBaseSchema.shape.created
13460
- }).strict().openapi("User");
13552
+ }).openapi("User");
13461
13553
  var organizationBaseSchema = generateBaseTableSchema("organization");
13462
- var organizationSchema = z.object({
13554
+ var organizationSchema = z.strictObject({
13463
13555
  id: organizationBaseSchema.shape.id,
13464
13556
  name: organizationBaseSchema.shape.name.nullish(),
13465
13557
  api_url: z.string().nullish(),
13466
13558
  created: organizationBaseSchema.shape.created
13467
- }).strict().openapi("Organization");
13468
- var memberSchema = z.object({
13559
+ }).openapi("Organization");
13560
+ var memberSchema = z.strictObject({
13469
13561
  org_id: organizationSchema.shape.id,
13470
13562
  user_id: userSchema.shape.id
13471
- }).strict().openapi("Member");
13472
- var meSchema = z.object({
13563
+ }).openapi("Member");
13564
+ var meSchema = z.strictObject({
13473
13565
  id: userSchema.shape.id,
13474
13566
  // By filtering by auth_id equality, we will ensure this is not-null.
13475
13567
  auth_id: userSchema.shape.auth_id.unwrap().unwrap(),
13476
- organizations: z.object({
13568
+ organizations: z.strictObject({
13477
13569
  id: memberSchema.shape.org_id,
13478
13570
  name: organizationSchema.shape.name
13479
13571
  }).array()
13480
- }).strict().openapi("Me");
13572
+ }).openapi("Me");
13481
13573
  var apiKeyBaseSchema = generateBaseTableSchema("api key");
13482
- var apiKeySchema = z.object({
13574
+ var apiKeySchema = z.strictObject({
13483
13575
  id: apiKeyBaseSchema.shape.id,
13484
13576
  created: apiKeyBaseSchema.shape.created,
13485
13577
  key_hash: z.string(),
@@ -13487,9 +13579,9 @@ var apiKeySchema = z.object({
13487
13579
  preview_name: z.string(),
13488
13580
  user_id: userSchema.shape.id.nullish(),
13489
13581
  org_id: organizationSchema.shape.id.nullish()
13490
- }).strict().openapi("ApiKey");
13582
+ }).openapi("ApiKey");
13491
13583
  var projectBaseSchema = generateBaseTableSchema("project");
13492
- var projectSchema = z.object({
13584
+ var projectSchema = z.strictObject({
13493
13585
  id: projectBaseSchema.shape.id,
13494
13586
  org_id: z.string().uuid().describe(
13495
13587
  "Unique id for the organization that the project belongs under"
@@ -13498,11 +13590,11 @@ var projectSchema = z.object({
13498
13590
  created: projectBaseSchema.shape.created,
13499
13591
  deleted_at: projectBaseSchema.shape.deleted_at,
13500
13592
  user_id: projectBaseSchema.shape.user_id
13501
- }).strict().openapi("Project");
13593
+ }).openapi("Project");
13502
13594
  var datasetBaseSchema = generateBaseTableSchema("dataset", {
13503
13595
  uniqueName: true
13504
13596
  });
13505
- var datasetSchema = z.object({
13597
+ var datasetSchema = z.strictObject({
13506
13598
  id: datasetBaseSchema.shape.id,
13507
13599
  project_id: datasetBaseSchema.shape.project_id.nullish(),
13508
13600
  name: datasetBaseSchema.shape.name,
@@ -13510,22 +13602,26 @@ var datasetSchema = z.object({
13510
13602
  created: datasetBaseSchema.shape.created,
13511
13603
  deleted_at: datasetBaseSchema.shape.deleted_at,
13512
13604
  user_id: datasetBaseSchema.shape.user_id
13513
- }).strict().openapi("Dataset");
13605
+ }).openapi("Dataset");
13514
13606
  var promptBaseSchema = generateBaseTableSchema("prompt");
13515
- var promptSchema = z.object({
13607
+ var promptSchema = z.strictObject({
13516
13608
  id: promptBaseSchema.shape.id,
13517
13609
  // This has to be copy/pasted because zod blows up when there are circular dependencies
13518
13610
  _xact_id: z.string().describe(
13519
13611
  `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)`
13520
13612
  ),
13521
13613
  project_id: promptBaseSchema.shape.project_id,
13614
+ log_id: z.literal("p").describe("A literal 'p' which identifies the object as a project prompt"),
13615
+ org_id: organizationSchema.shape.id,
13522
13616
  name: promptBaseSchema.shape.name,
13523
13617
  slug: z.string().describe("Unique identifier for the prompt"),
13524
13618
  description: promptBaseSchema.shape.description,
13619
+ created: promptBaseSchema.shape.created,
13525
13620
  prompt_data: promptDataSchema.nullish().describe("The prompt, model, and its parameters"),
13526
- tags: z.array(z.string()).nullish().describe("A list of tags for the prompt")
13621
+ tags: z.array(z.string()).nullish().describe("A list of tags for the prompt"),
13622
+ metadata: promptBaseSchema.shape.metadata
13527
13623
  });
13528
- var repoInfoSchema = z.object({
13624
+ var repoInfoSchema = z.strictObject({
13529
13625
  commit: z.string().nullish().describe("SHA of most recent commit"),
13530
13626
  branch: z.string().nullish().describe("Name of the branch the most recent commit belongs to"),
13531
13627
  tag: z.string().nullish().describe("Name of the tag on the most recent commit"),
@@ -13545,7 +13641,7 @@ var repoInfoSchema = z.object({
13545
13641
  var experimentBaseSchema = generateBaseTableSchema("experiment", {
13546
13642
  uniqueName: true
13547
13643
  });
13548
- var experimentSchema = z.object({
13644
+ var experimentSchema = z.strictObject({
13549
13645
  id: experimentBaseSchema.shape.id,
13550
13646
  project_id: experimentBaseSchema.shape.project_id,
13551
13647
  name: experimentBaseSchema.shape.name,
@@ -13568,10 +13664,10 @@ var experimentSchema = z.object({
13568
13664
  ),
13569
13665
  user_id: experimentBaseSchema.shape.user_id,
13570
13666
  metadata: experimentBaseSchema.shape.metadata
13571
- }).strict().openapi("Experiment");
13667
+ }).openapi("Experiment");
13572
13668
  var appLimitSchema = z.number().int().nonnegative().describe("Limit the number of objects to return");
13573
13669
  function generateBaseTableOpSchema(objectName) {
13574
- return z.object({
13670
+ return z.strictObject({
13575
13671
  org_name: z.string().nullish().describe(
13576
13672
  `For nearly all users, this parameter should be unnecessary. But in the rare case that your API key belongs to multiple organizations, you may specify the name of the organization the ${objectName} belongs in.`
13577
13673
  )
@@ -13590,14 +13686,14 @@ var endingBeforeSchema = z.string().uuid().describe(
13590
13686
  ].join("\n\n")
13591
13687
  ).openapi("EndingBefore");
13592
13688
  var createProjectBaseSchema = generateBaseTableOpSchema("project");
13593
- var createProjectSchema = z.object({
13689
+ var createProjectSchema = z.strictObject({
13594
13690
  name: projectSchema.shape.name,
13595
13691
  org_name: createProjectBaseSchema.shape.org_name
13596
- }).strict().openapi("CreateProject");
13597
- var patchProjectSchema = z.object({
13692
+ }).openapi("CreateProject");
13693
+ var patchProjectSchema = z.strictObject({
13598
13694
  name: projectSchema.shape.name.nullish()
13599
- }).strict().openapi("PatchProject");
13600
- var createExperimentSchema = z.object({
13695
+ }).openapi("PatchProject");
13696
+ var createExperimentSchema = z.strictObject({
13601
13697
  project_id: experimentSchema.shape.project_id,
13602
13698
  name: experimentSchema.shape.name.nullish(),
13603
13699
  description: experimentSchema.shape.description,
@@ -13607,21 +13703,28 @@ var createExperimentSchema = z.object({
13607
13703
  dataset_version: experimentSchema.shape.dataset_version,
13608
13704
  public: experimentSchema.shape.public.nullish(),
13609
13705
  metadata: experimentSchema.shape.metadata
13610
- }).strict().openapi("CreateExperiment");
13611
- var patchExperimentSchema = createExperimentSchema.omit({ project_id: true }).strict().openapi("PatchExperiment");
13612
- var createDatasetSchema = z.object({
13706
+ }).openapi("CreateExperiment");
13707
+ var patchExperimentSchema = createExperimentSchema.omit({ project_id: true }).openapi("PatchExperiment");
13708
+ var createDatasetSchema = z.strictObject({
13613
13709
  project_id: datasetSchema.shape.project_id,
13614
13710
  name: datasetSchema.shape.name,
13615
13711
  description: datasetSchema.shape.description
13616
- }).strict().openapi("CreateDataset");
13617
- var patchDatasetSchema = createDatasetSchema.omit({ project_id: true }).strict().openapi("PatchDataset");
13618
- var createPromptSchema = promptSchema.omit({ id: true, _xact_id: true }).strict().openapi("CreatePrompt");
13619
- var patchPromptSchema = z.object({
13712
+ }).openapi("CreateDataset");
13713
+ var patchDatasetSchema = createDatasetSchema.omit({ project_id: true }).openapi("PatchDataset");
13714
+ var createPromptSchema = promptSchema.omit({
13715
+ id: true,
13716
+ _xact_id: true,
13717
+ org_id: true,
13718
+ log_id: true,
13719
+ created: true,
13720
+ metadata: true
13721
+ }).openapi("CreatePrompt");
13722
+ var patchPromptSchema = z.strictObject({
13620
13723
  name: promptSchema.shape.name.nullish(),
13621
13724
  description: promptSchema.shape.description.nullish(),
13622
13725
  prompt_data: promptSchema.shape.prompt_data.nullish(),
13623
13726
  tags: promptSchema.shape.tags.nullish()
13624
- }).strict().openapi("PatchPrompt");
13727
+ }).openapi("PatchPrompt");
13625
13728
  function capitalize(s, sep) {
13626
13729
  const items = sep ? s.split(sep) : [s];
13627
13730
  return items.map((s2) => s2 ? s2.charAt(0).toUpperCase() + s2.slice(1) : s2).join(sep || "");
@@ -13645,7 +13748,7 @@ var SpanTypeAttribute2 = /* @__PURE__ */ ((SpanTypeAttribute22) => {
13645
13748
  var auditSourcesSchema = z.enum(VALID_SOURCES2);
13646
13749
  function generateBaseEventOpSchema(objectType2) {
13647
13750
  const eventDescription = getEventObjectDescription(objectType2);
13648
- return z.object({
13751
+ return z.strictObject({
13649
13752
  id: z.string().describe(
13650
13753
  `A unique identifier for the ${eventDescription} event. If you don't provide one, BrainTrust will generate one for you`
13651
13754
  ),
@@ -13661,7 +13764,7 @@ function generateBaseEventOpSchema(objectType2) {
13661
13764
  metadata: z.record(customTypes.any).nullish().describe(
13662
13765
  "A dictionary with additional data about the test example, model outputs, or just about anything else that's relevant, that you can use to help find and analyze examples later. For example, you could log the `prompt`, example's `id`, or anything else that would be useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys must be strings"
13663
13766
  ),
13664
- metrics: z.object({
13767
+ metrics: z.strictObject({
13665
13768
  start: z.number().nullish().describe(
13666
13769
  `A unix timestamp recording when the section of code which produced the ${eventDescription} event started`
13667
13770
  ),
@@ -13671,7 +13774,7 @@ function generateBaseEventOpSchema(objectType2) {
13671
13774
  }).catchall(customTypes.any).nullish().describe(
13672
13775
  `Metrics are numerical measurements tracking the execution of the code that produced the ${eventDescription} event. Use "start" and "end" to track the time span over which the ${eventDescription} event was produced`
13673
13776
  ),
13674
- context: z.object({
13777
+ context: z.strictObject({
13675
13778
  caller_functionname: z.string().nullish().describe(
13676
13779
  `The function in code which created the ${eventDescription} event`
13677
13780
  ),
@@ -13693,7 +13796,7 @@ function generateBaseEventOpSchema(objectType2) {
13693
13796
  root_span_id: z.string().describe(
13694
13797
  `The \`span_id\` of the root of the trace this ${eventDescription} event belongs to`
13695
13798
  ),
13696
- span_attributes: z.object({
13799
+ span_attributes: z.strictObject({
13697
13800
  name: z.string().nullish().describe("Name of the span, for display purposes only"),
13698
13801
  type: z.nativeEnum(SpanTypeAttribute2).nullish().describe("Type of the span, for display purposes only")
13699
13802
  }).catchall(customTypes.any).nullish().describe(
@@ -13707,7 +13810,7 @@ function generateBaseEventOpSchema(objectType2) {
13707
13810
  function generateBaseEventFeedbackSchema(objectType2) {
13708
13811
  const eventObjectType = getEventObjectType(objectType2);
13709
13812
  const eventDescription = getEventObjectDescription(objectType2);
13710
- return z.object({
13813
+ return z.strictObject({
13711
13814
  id: z.string().describe(
13712
13815
  `The id of the ${eventDescription} event to log feedback for. This is the row \`id\` returned by \`POST /v1/${eventObjectType}/{${objectType2}_id}/insert\``
13713
13816
  ),
@@ -13748,7 +13851,7 @@ var versionSchema = z.string().describe(
13748
13851
  "The version id is essentially a filter on the latest event transaction id. You can use the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch."
13749
13852
  ].join("\n\n")
13750
13853
  );
13751
- var pathTypeFilterSchema = z.object({
13854
+ var pathTypeFilterSchema = z.strictObject({
13752
13855
  type: z.literal("path_lookup").describe("Denotes the type of filter as a path-lookup filter"),
13753
13856
  path: z.string().array().describe(
13754
13857
  'List of fields describing the path to the value to be checked against. For instance, if you wish to filter on the value of `c` in `{"input": {"a": {"b": {"c": "hello"}}}}`, pass `path=["input", "a", "b", "c"]`'
@@ -13759,7 +13862,7 @@ var pathTypeFilterSchema = z.object({
13759
13862
  }).describe(
13760
13863
  'A path-lookup filter describes an equality comparison against a specific sub-field in the event row. For instance, if you wish to filter on the value of `c` in `{"input": {"a": {"b": {"c": "hello"}}}}`, pass `path=["input", "a", "b", "c"]` and `value="hello"`'
13761
13864
  ).openapi("PathLookupFilter");
13762
- var sqlTypeFilterSchema = z.object({
13865
+ var sqlTypeFilterSchema = z.strictObject({
13763
13866
  type: z.literal("sql_filter").describe("Denotes the type of filter as a sql-type filter"),
13764
13867
  expr: z.string().describe(
13765
13868
  `A SQL expression in [duckDB syntax](https://duckdb.org/docs/sql/expressions/overview). For instance, if you wish to fuzzy-match the value of \`c\` in \`{"input": {"a": {"b": {"c": "hello"}}}}\`, pass \`expr="input->'a'->'b'->>'c' LIKE '%el%'"\`.`
@@ -13773,24 +13876,24 @@ var allFetchFiltersSchema = z.union([pathTypeFilterSchema, sqlTypeFilterSchema])
13773
13876
  var fetchFiltersSchema = pathTypeFilterSchema.array().describe(
13774
13877
  "A list of filters on the events to fetch. Currently, only path-lookup type filters are supported, but we may add more in the future"
13775
13878
  ).openapi("FetchEventsFilters");
13776
- var fetchEventsRequestSchema = z.object({
13879
+ var fetchEventsRequestSchema = z.strictObject({
13777
13880
  limit: fetchLimitSchema.nullish(),
13778
13881
  max_xact_id: maxXactIdSchema.nullish(),
13779
13882
  max_root_span_id: maxRootSpanIdSchema.nullish(),
13780
13883
  filters: fetchFiltersSchema.nullish(),
13781
13884
  version: versionSchema.nullish()
13782
- }).strict().openapi("FetchEventsRequest");
13885
+ }).openapi("FetchEventsRequest");
13783
13886
  function makeFetchEventsResponseSchema(objectType2, eventSchema) {
13784
13887
  const eventName = capitalize(getEventObjectType(objectType2), "_").replace(
13785
13888
  "_",
13786
13889
  ""
13787
13890
  );
13788
- return z.object({
13891
+ return z.strictObject({
13789
13892
  events: eventSchema.array().describe("A list of fetched events")
13790
- }).strict().openapi(`Fetch${eventName}EventsResponse`);
13893
+ }).openapi(`Fetch${eventName}EventsResponse`);
13791
13894
  }
13792
13895
  var experimentEventBaseSchema = generateBaseEventOpSchema("experiment");
13793
- var experimentEventSchema = z.object({
13896
+ var experimentEventSchema = z.strictObject({
13794
13897
  id: experimentEventBaseSchema.shape.id,
13795
13898
  dataset_record_id: z.string().nullish().describe(
13796
13899
  "If the experiment is associated to a dataset, this is the event-level dataset id this experiment event is tied to"
@@ -13819,9 +13922,9 @@ var experimentEventSchema = z.object({
13819
13922
  span_parents: experimentEventBaseSchema.shape.span_parents,
13820
13923
  root_span_id: experimentEventBaseSchema.shape.root_span_id,
13821
13924
  span_attributes: experimentEventBaseSchema.shape.span_attributes
13822
- }).strict().openapi("ExperimentEvent");
13925
+ }).openapi("ExperimentEvent");
13823
13926
  var datasetEventBaseSchema = generateBaseEventOpSchema("dataset");
13824
- var datasetEventSchema = z.object({
13927
+ var datasetEventSchema = z.strictObject({
13825
13928
  id: datasetEventBaseSchema.shape.id,
13826
13929
  [TRANSACTION_ID_FIELD2]: datasetEventBaseSchema.shape[TRANSACTION_ID_FIELD2],
13827
13930
  created: datasetEventBaseSchema.shape.created,
@@ -13837,9 +13940,9 @@ var datasetEventSchema = z.object({
13837
13940
  tags: datasetEventBaseSchema.shape.tags,
13838
13941
  span_id: datasetEventBaseSchema.shape.span_id,
13839
13942
  root_span_id: datasetEventBaseSchema.shape.root_span_id
13840
- }).strict().openapi("DatasetEvent");
13943
+ }).openapi("DatasetEvent");
13841
13944
  var projectLogsEventBaseSchema = generateBaseEventOpSchema("project");
13842
- var projectLogsEventSchema = z.object({
13945
+ var projectLogsEventSchema = z.strictObject({
13843
13946
  id: projectLogsEventBaseSchema.shape.id,
13844
13947
  [TRANSACTION_ID_FIELD2]: projectLogsEventBaseSchema.shape[TRANSACTION_ID_FIELD2],
13845
13948
  created: projectLogsEventBaseSchema.shape.created,
@@ -13866,12 +13969,12 @@ var projectLogsEventSchema = z.object({
13866
13969
  span_parents: projectLogsEventBaseSchema.shape.span_parents,
13867
13970
  root_span_id: projectLogsEventBaseSchema.shape.root_span_id,
13868
13971
  span_attributes: projectLogsEventBaseSchema.shape.span_attributes
13869
- }).strict().openapi("ProjectLogsEvent");
13972
+ }).openapi("ProjectLogsEvent");
13870
13973
  var isMergeDescription = [
13871
13974
  "The `_is_merge` field controls how the row is merged with any existing row with the same id in the DB. By default (or when set to `false`), the existing row is completely replaced by the new row. When set to `true`, the new row is deep-merged into the existing row",
13872
13975
  'For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be `{"id": "foo", "input": {"b": 11, "c": 20}}`'
13873
13976
  ].join("\n\n");
13874
- var mergeEventSchema = z.object({
13977
+ var mergeEventSchema = z.strictObject({
13875
13978
  [IS_MERGE_FIELD2]: customTypes.literalTrue.describe(isMergeDescription),
13876
13979
  [MERGE_PATHS_FIELD2]: z.string().array().array().nullish().describe(
13877
13980
  [
@@ -13880,7 +13983,7 @@ var mergeEventSchema = z.object({
13880
13983
  ].join("\n\n")
13881
13984
  )
13882
13985
  });
13883
- var replacementEventSchema = z.object({
13986
+ var replacementEventSchema = z.strictObject({
13884
13987
  [IS_MERGE_FIELD2]: customTypes.literalFalse.nullish().describe(isMergeDescription),
13885
13988
  [PARENT_ID_FIELD2]: z.string().nullish().describe(
13886
13989
  [
@@ -13896,25 +13999,25 @@ function makeInsertEventSchemas(objectType2, insertSchema) {
13896
13999
  getEventObjectType(objectType2),
13897
14000
  "_"
13898
14001
  ).replace("_", "");
13899
- const replaceVariantSchema = insertSchema.merge(replacementEventSchema).strict().openapi(`Insert${eventSchemaName}EventReplace`);
13900
- const mergeVariantSchema = insertSchema.merge(mergeEventSchema).strict().openapi(`Insert${eventSchemaName}EventMerge`);
14002
+ const replaceVariantSchema = insertSchema.merge(replacementEventSchema).openapi(`Insert${eventSchemaName}EventReplace`);
14003
+ const mergeVariantSchema = insertSchema.merge(mergeEventSchema).openapi(`Insert${eventSchemaName}EventMerge`);
13901
14004
  const eventSchema = z.union([replaceVariantSchema, mergeVariantSchema]).describe(`${capitalize(article)} ${eventDescription} event`).openapi(`Insert${eventSchemaName}Event`);
13902
- const requestSchema = z.object({
14005
+ const requestSchema = z.strictObject({
13903
14006
  events: eventSchema.array().describe(`A list of ${eventDescription} events to insert`)
13904
- }).strict().openapi(`Insert${eventSchemaName}EventRequest`);
14007
+ }).openapi(`Insert${eventSchemaName}EventRequest`);
13905
14008
  return { eventSchema, requestSchema };
13906
14009
  }
13907
- var insertEventsResponseSchema = z.object({
14010
+ var insertEventsResponseSchema = z.strictObject({
13908
14011
  row_ids: z.string().array().describe(
13909
14012
  "The ids of all rows that were inserted, aligning one-to-one with the rows provided as input"
13910
14013
  )
13911
- }).strict().openapi("InsertEventsResponse");
14014
+ }).openapi("InsertEventsResponse");
13912
14015
  var {
13913
14016
  eventSchema: insertExperimentEventSchema,
13914
14017
  requestSchema: insertExperimentEventsRequestSchema
13915
14018
  } = makeInsertEventSchemas(
13916
14019
  "experiment",
13917
- z.object({
14020
+ z.strictObject({
13918
14021
  input: experimentEventSchema.shape.input,
13919
14022
  output: experimentEventSchema.shape.output,
13920
14023
  expected: experimentEventSchema.shape.expected,
@@ -13927,28 +14030,28 @@ var {
13927
14030
  id: experimentEventSchema.shape.id.nullish(),
13928
14031
  dataset_record_id: experimentEventSchema.shape.dataset_record_id,
13929
14032
  [OBJECT_DELETE_FIELD]: experimentEventBaseSchema.shape[OBJECT_DELETE_FIELD]
13930
- }).strict()
14033
+ })
13931
14034
  );
13932
14035
  var {
13933
14036
  eventSchema: insertDatasetEventSchema,
13934
14037
  requestSchema: insertDatasetEventsRequestSchema
13935
14038
  } = makeInsertEventSchemas(
13936
14039
  "dataset",
13937
- z.object({
14040
+ z.strictObject({
13938
14041
  input: datasetEventSchema.shape.input,
13939
14042
  expected: datasetEventSchema.shape.expected,
13940
14043
  metadata: datasetEventSchema.shape.metadata,
13941
14044
  tags: datasetEventSchema.shape.tags,
13942
14045
  id: datasetEventSchema.shape.id.nullish(),
13943
14046
  [OBJECT_DELETE_FIELD]: datasetEventBaseSchema.shape[OBJECT_DELETE_FIELD]
13944
- }).strict()
14047
+ })
13945
14048
  );
13946
14049
  var {
13947
14050
  eventSchema: insertProjectLogsEventSchema,
13948
14051
  requestSchema: insertProjectLogsEventsRequestSchema
13949
14052
  } = makeInsertEventSchemas(
13950
14053
  "project",
13951
- z.object({
14054
+ z.strictObject({
13952
14055
  input: projectLogsEventSchema.shape.input,
13953
14056
  output: projectLogsEventSchema.shape.output,
13954
14057
  expected: projectLogsEventSchema.shape.expected,
@@ -13960,7 +14063,7 @@ var {
13960
14063
  span_attributes: projectLogsEventSchema.shape.span_attributes,
13961
14064
  id: projectLogsEventSchema.shape.id.nullish(),
13962
14065
  [OBJECT_DELETE_FIELD]: projectLogsEventBaseSchema.shape[OBJECT_DELETE_FIELD]
13963
- }).strict()
14066
+ })
13964
14067
  );
13965
14068
  function makeFeedbackRequestSchema(objectType2, feedbackSchema) {
13966
14069
  const eventDescription = getEventObjectDescription(objectType2);
@@ -13968,54 +14071,54 @@ function makeFeedbackRequestSchema(objectType2, feedbackSchema) {
13968
14071
  getEventObjectType(objectType2),
13969
14072
  "_"
13970
14073
  ).replace("_", "");
13971
- return z.object({
14074
+ return z.strictObject({
13972
14075
  feedback: feedbackSchema.array().describe(`A list of ${eventDescription} feedback items`)
13973
- }).strict().openapi(`Feedback${eventSchemaName}EventRequest`);
14076
+ }).openapi(`Feedback${eventSchemaName}EventRequest`);
13974
14077
  }
13975
14078
  var feedbackExperimentRequestBaseSchema = generateBaseEventFeedbackSchema("experiment");
13976
- var feedbackExperimentItemSchema = z.object({
14079
+ var feedbackExperimentItemSchema = z.strictObject({
13977
14080
  id: feedbackExperimentRequestBaseSchema.shape.id,
13978
14081
  scores: feedbackExperimentRequestBaseSchema.shape.scores,
13979
14082
  expected: feedbackExperimentRequestBaseSchema.shape.expected,
13980
14083
  comment: feedbackExperimentRequestBaseSchema.shape.comment,
13981
14084
  metadata: feedbackExperimentRequestBaseSchema.shape.metadata,
13982
14085
  source: feedbackExperimentRequestBaseSchema.shape.source
13983
- }).strict().openapi("FeedbackExperimentItem");
14086
+ }).openapi("FeedbackExperimentItem");
13984
14087
  var feedbackExperimentRequestSchema = makeFeedbackRequestSchema(
13985
14088
  "experiment",
13986
14089
  feedbackExperimentItemSchema
13987
14090
  );
13988
14091
  var feedbackDatasetRequestBaseSchema = generateBaseEventFeedbackSchema("dataset");
13989
- var feedbackDatasetItemSchema = z.object({
14092
+ var feedbackDatasetItemSchema = z.strictObject({
13990
14093
  id: feedbackDatasetRequestBaseSchema.shape.id,
13991
14094
  comment: feedbackDatasetRequestBaseSchema.shape.comment,
13992
14095
  metadata: feedbackDatasetRequestBaseSchema.shape.metadata,
13993
14096
  source: feedbackDatasetRequestBaseSchema.shape.source
13994
- }).strict().openapi("FeedbackDatasetItem");
14097
+ }).openapi("FeedbackDatasetItem");
13995
14098
  var feedbackDatasetRequestSchema = makeFeedbackRequestSchema(
13996
14099
  "dataset",
13997
14100
  feedbackDatasetItemSchema
13998
14101
  );
13999
14102
  var feedbackProjectLogsRequestBaseSchema = generateBaseEventFeedbackSchema("project");
14000
- var feedbackProjectLogsItemSchema = z.object({
14103
+ var feedbackProjectLogsItemSchema = z.strictObject({
14001
14104
  id: feedbackProjectLogsRequestBaseSchema.shape.id,
14002
14105
  scores: feedbackProjectLogsRequestBaseSchema.shape.scores,
14003
14106
  expected: feedbackProjectLogsRequestBaseSchema.shape.expected,
14004
14107
  comment: feedbackProjectLogsRequestBaseSchema.shape.comment,
14005
14108
  metadata: feedbackProjectLogsRequestBaseSchema.shape.metadata,
14006
14109
  source: feedbackProjectLogsRequestBaseSchema.shape.source
14007
- }).strict().openapi("FeedbackProjectLogsItem");
14110
+ }).openapi("FeedbackProjectLogsItem");
14008
14111
  var feedbackProjectLogsRequestSchema = makeFeedbackRequestSchema(
14009
14112
  "project",
14010
14113
  feedbackProjectLogsItemSchema
14011
14114
  );
14012
14115
  var feedbackPromptRequestBaseSchema = generateBaseEventFeedbackSchema("prompt");
14013
- var feedbackPromptItemSchema = z.object({
14116
+ var feedbackPromptItemSchema = z.strictObject({
14014
14117
  id: feedbackPromptRequestBaseSchema.shape.id,
14015
14118
  comment: feedbackPromptRequestBaseSchema.shape.comment,
14016
14119
  metadata: feedbackPromptRequestBaseSchema.shape.metadata,
14017
14120
  source: feedbackPromptRequestBaseSchema.shape.source
14018
- }).strict().openapi("FeedbackPromptItem");
14121
+ }).openapi("FeedbackPromptItem");
14019
14122
  var feedbackPromptRequestSchema = makeFeedbackRequestSchema(
14020
14123
  "prompt",
14021
14124
  feedbackPromptItemSchema
@@ -14060,12 +14163,12 @@ function makeCrossObjectIndividualRequestSchema(objectType2) {
14060
14163
  const eventObjectType = getEventObjectType(objectType2);
14061
14164
  const eventDescription = getEventObjectDescription(objectType2);
14062
14165
  const eventObjectSchema = eventObjectSchemas[eventObjectType];
14063
- const insertObject = z.object({
14166
+ const insertObject = z.strictObject({
14064
14167
  ...eventObjectSchema.insertEvent ? {
14065
14168
  events: eventObjectSchema.insertEvent.array().nullish().describe(`A list of ${eventDescription} events to insert`)
14066
14169
  } : {},
14067
14170
  feedback: eventObjectSchema.feedbackItem.array().nullish().describe(`A list of ${eventDescription} feedback items`)
14068
- }).strict();
14171
+ });
14069
14172
  return z.record(z.string().uuid(), insertObject).nullish().describe(
14070
14173
  `A mapping from ${objectType2} id to a set of log events and feedback items to insert`
14071
14174
  );
@@ -14075,18 +14178,16 @@ function makeCrossObjectIndividualResponseSchema(objectType2) {
14075
14178
  `A mapping from ${objectType2} id to row ids for inserted \`events\``
14076
14179
  );
14077
14180
  }
14078
- var crossObjectInsertRequestSchema = z.object({
14181
+ var crossObjectInsertRequestSchema = z.strictObject({
14079
14182
  experiment: makeCrossObjectIndividualRequestSchema("experiment"),
14080
14183
  dataset: makeCrossObjectIndividualRequestSchema("dataset"),
14081
- project_logs: makeCrossObjectIndividualRequestSchema("project"),
14082
- prompt: makeCrossObjectIndividualRequestSchema("prompt")
14083
- }).strict().openapi("CrossObjectInsertRequest");
14084
- var crossObjectInsertResponseSchema = z.object({
14184
+ project_logs: makeCrossObjectIndividualRequestSchema("project")
14185
+ }).openapi("CrossObjectInsertRequest");
14186
+ var crossObjectInsertResponseSchema = z.strictObject({
14085
14187
  experiment: makeCrossObjectIndividualResponseSchema("experiment"),
14086
14188
  dataset: makeCrossObjectIndividualResponseSchema("dataset"),
14087
- project_logs: makeCrossObjectIndividualResponseSchema("project"),
14088
- prompt: makeCrossObjectIndividualResponseSchema("prompt")
14089
- }).strict().openapi("CrossObjectInsertResponse");
14189
+ project_logs: makeCrossObjectIndividualResponseSchema("project")
14190
+ }).openapi("CrossObjectInsertResponse");
14090
14191
  var summarizeScoresParamSchema = z.boolean().describe(
14091
14192
  "Whether to summarize the scores and metrics. If false (or omitted), only the metadata will be returned."
14092
14193
  );
@@ -14096,14 +14197,14 @@ var comparisonExperimentIdParamSchema = z.string().uuid().describe(
14096
14197
  var summarizeDataParamSchema = z.boolean().describe(
14097
14198
  "Whether to summarize the data. If false (or omitted), only the metadata will be returned."
14098
14199
  );
14099
- var summarizeExperimentResponseSchema = z.object({
14200
+ var summarizeExperimentResponseSchema = z.strictObject({
14100
14201
  project_name: z.string().describe("Name of the project that the experiment belongs to"),
14101
14202
  experiment_name: z.string().describe("Name of the experiment"),
14102
14203
  project_url: z.string().url().describe("URL to the project's page in the Braintrust app"),
14103
14204
  experiment_url: z.string().url().describe("URL to the experiment's page in the Braintrust app"),
14104
14205
  comparison_experiment_name: z.string().nullish().describe("The experiment which scores are baselined against"),
14105
14206
  scores: z.record(
14106
- z.object({
14207
+ z.strictObject({
14107
14208
  name: z.string().describe("Name of the score"),
14108
14209
  score: z.number().min(0).max(1).describe("Average score across all examples"),
14109
14210
  diff: z.number().min(-1).max(1).describe(
@@ -14114,7 +14215,7 @@ var summarizeExperimentResponseSchema = z.object({
14114
14215
  }).describe("Summary of a score's performance").openapi("ScoreSummary")
14115
14216
  ).nullish().describe("Summary of the experiment's scores"),
14116
14217
  metrics: z.record(
14117
- z.object({
14218
+ z.strictObject({
14118
14219
  name: z.string().describe("Name of the metric"),
14119
14220
  metric: z.number().describe("Average metric across all examples"),
14120
14221
  unit: z.string().describe("Unit label for the metric"),
@@ -14125,16 +14226,16 @@ var summarizeExperimentResponseSchema = z.object({
14125
14226
  regressions: z.number().int().min(0).describe("Number of regressions in the metric")
14126
14227
  }).describe("Summary of a metric's performance").openapi("MetricSummary")
14127
14228
  ).nullish().describe("Summary of the experiment's metrics")
14128
- }).strict().describe("Summary of an experiment").openapi("SummarizeExperimentResponse");
14129
- var summarizeDatasetResponseSchema = z.object({
14229
+ }).describe("Summary of an experiment").openapi("SummarizeExperimentResponse");
14230
+ var summarizeDatasetResponseSchema = z.strictObject({
14130
14231
  project_name: z.string().describe("Name of the project that the dataset belongs to"),
14131
14232
  dataset_name: z.string().describe("Name of the dataset"),
14132
14233
  project_url: z.string().url().describe("URL to the project's page in the Braintrust app"),
14133
14234
  dataset_url: z.string().url().describe("URL to the dataset's page in the Braintrust app"),
14134
- data_summary: z.object({
14235
+ data_summary: z.strictObject({
14135
14236
  total_records: z.number().int().min(0).describe("Total number of records in the dataset")
14136
14237
  }).nullish().describe("Summary of a dataset's data").openapi("DataSummary")
14137
- }).strict().describe("Summary of a dataset").openapi("SummarizeDatasetResponse");
14238
+ }).describe("Summary of a dataset").openapi("SummarizeDatasetResponse");
14138
14239
 
14139
14240
  // src/util.ts
14140
14241
  var GLOBAL_PROJECT = "Global";
@@ -14648,7 +14749,7 @@ var NoopSpan = class {
14648
14749
  }
14649
14750
  log(_) {
14650
14751
  }
14651
- logFeedback(event) {
14752
+ logFeedback(_event) {
14652
14753
  }
14653
14754
  traced(callback, _1) {
14654
14755
  return callback(this);
@@ -14662,6 +14763,8 @@ var NoopSpan = class {
14662
14763
  close(args) {
14663
14764
  return this.end(args);
14664
14765
  }
14766
+ async flush() {
14767
+ }
14665
14768
  };
14666
14769
  var NOOP_SPAN = new NoopSpan();
14667
14770
  var BraintrustState = class {
@@ -14671,7 +14774,12 @@ var BraintrustState = class {
14671
14774
  // (safely) dynamically cast it whenever retrieving the logger.
14672
14775
  currentLogger;
14673
14776
  currentSpan;
14777
+ // For operations not tied to a particular data object instance, we maintain a
14778
+ // global BackgroundLogger which is refreshed anytime we log in with different
14779
+ // credentials.
14780
+ _globalBgLogger = void 0;
14674
14781
  appUrl = null;
14782
+ appPublicUrl = null;
14675
14783
  loginToken = null;
14676
14784
  orgId = null;
14677
14785
  orgName = null;
@@ -14680,6 +14788,7 @@ var BraintrustState = class {
14680
14788
  gitMetadataSettings;
14681
14789
  _apiConn = null;
14682
14790
  _logConn = null;
14791
+ _globalBgLoggerDirty = true;
14683
14792
  constructor() {
14684
14793
  this.id = v4_default();
14685
14794
  this.currentExperiment = void 0;
@@ -14698,6 +14807,7 @@ var BraintrustState = class {
14698
14807
  this.gitMetadataSettings = void 0;
14699
14808
  this._apiConn = null;
14700
14809
  this._logConn = null;
14810
+ this._globalBgLoggerDirty = true;
14701
14811
  }
14702
14812
  apiConn() {
14703
14813
  if (!this._apiConn) {
@@ -14717,6 +14827,18 @@ var BraintrustState = class {
14717
14827
  }
14718
14828
  return this._logConn;
14719
14829
  }
14830
+ globalBgLogger() {
14831
+ if (this._globalBgLogger === void 0 || this._globalBgLoggerDirty) {
14832
+ const getLogConn = async () => {
14833
+ await login();
14834
+ this._globalBgLoggerDirty = false;
14835
+ return this.logConn();
14836
+ };
14837
+ this._globalBgLogger = new BackgroundLogger(new LazyValue(getLogConn));
14838
+ this._globalBgLoggerDirty = false;
14839
+ }
14840
+ return this._globalBgLogger;
14841
+ }
14720
14842
  };
14721
14843
  var _state;
14722
14844
  function _internalSetInitialState() {
@@ -14839,7 +14961,7 @@ var HTTPConnection = class _HTTPConnection {
14839
14961
  return await resp.json();
14840
14962
  }
14841
14963
  };
14842
- function logFeedbackImpl(bgLogger, parentIds, {
14964
+ function logFeedbackImpl(bgLogger, parentObjectType, parentObjectId, {
14843
14965
  id,
14844
14966
  expected,
14845
14967
  scores,
@@ -14867,16 +14989,17 @@ function logFeedbackImpl(bgLogger, parentIds, {
14867
14989
  updateEvent = Object.fromEntries(
14868
14990
  Object.entries(updateEvent).filter(([_, v]) => !isEmpty(v))
14869
14991
  );
14870
- const trueParentIds = new LazyValue(async () => {
14871
- const { kind, ...ids } = await parentIds.get();
14872
- return ids;
14873
- });
14992
+ const parentIds = async () => new SpanParentComponents({
14993
+ objectType: parentObjectType,
14994
+ objectId: await parentObjectId.get(),
14995
+ rowId: ""
14996
+ }).asDict();
14874
14997
  if (Object.keys(updateEvent).length > 0) {
14875
14998
  const record = new LazyValue(async () => {
14876
14999
  return {
14877
15000
  id,
14878
15001
  ...updateEvent,
14879
- ...await trueParentIds.get(),
15002
+ ...await parentIds(),
14880
15003
  [AUDIT_SOURCE_FIELD]: source,
14881
15004
  [AUDIT_METADATA_FIELD]: metadata,
14882
15005
  [IS_MERGE_FIELD]: true
@@ -14897,7 +15020,7 @@ function logFeedbackImpl(bgLogger, parentIds, {
14897
15020
  comment: {
14898
15021
  text: comment
14899
15022
  },
14900
- ...await trueParentIds.get(),
15023
+ ...await parentIds(),
14901
15024
  [AUDIT_SOURCE_FIELD]: source,
14902
15025
  [AUDIT_METADATA_FIELD]: metadata
14903
15026
  };
@@ -14905,11 +15028,48 @@ function logFeedbackImpl(bgLogger, parentIds, {
14905
15028
  bgLogger.log([record]);
14906
15029
  }
14907
15030
  }
15031
+ function startSpanParentArgs(args) {
15032
+ if (args.parent && args.parentId) {
15033
+ throw new Error(
15034
+ "Cannot specify both `parent` and `parentId`. Prefer `parent"
15035
+ );
15036
+ }
15037
+ let parentObjectId = void 0;
15038
+ let parentRowId = void 0;
15039
+ if (args.parent) {
15040
+ const parentComponents = SpanParentComponents.fromStr(args.parent);
15041
+ if (args.spanParentObjectType !== parentComponents.objectType) {
15042
+ throw new Error(
15043
+ `Mismatch between expected span parent object type ${args.spanParentObjectType} and provided type ${parentComponents.objectType}`
15044
+ );
15045
+ }
15046
+ const computeParentObjectId = async () => {
15047
+ if (await args.spanParentObjectId.get() !== parentComponents.objectId) {
15048
+ throw new Error(
15049
+ `Mismatch between expected span parent object id ${await args.spanParentObjectId.get()} and provided id ${parentComponents.objectId}`
15050
+ );
15051
+ }
15052
+ return await args.spanParentObjectId.get();
15053
+ };
15054
+ parentObjectId = new LazyValue(computeParentObjectId);
15055
+ parentRowId = parentComponents.rowId;
15056
+ } else {
15057
+ parentObjectId = args.spanParentObjectId;
15058
+ parentRowId = args.parentId ?? "";
15059
+ }
15060
+ return {
15061
+ parentObjectType: args.spanParentObjectType,
15062
+ parentObjectId,
15063
+ parentRowId
15064
+ };
15065
+ }
14908
15066
  var Logger = class {
14909
15067
  lazyMetadata;
14910
15068
  logOptions;
14911
15069
  bgLogger;
14912
15070
  lastStartTime;
15071
+ lazyId;
15072
+ calledStartSpan;
14913
15073
  // For type identification.
14914
15074
  kind = "logger";
14915
15075
  constructor(lazyMetadata, logOptions = {}) {
@@ -14920,6 +15080,8 @@ var Logger = class {
14920
15080
  );
14921
15081
  this.bgLogger = new BackgroundLogger(logConn);
14922
15082
  this.lastStartTime = getCurrentUnixTimestamp();
15083
+ this.lazyId = new LazyValue(async () => await this.id);
15084
+ this.calledStartSpan = false;
14923
15085
  }
14924
15086
  get org_id() {
14925
15087
  return (async () => {
@@ -14931,6 +15093,12 @@ var Logger = class {
14931
15093
  return (await this.lazyMetadata.get()).project;
14932
15094
  })();
14933
15095
  }
15096
+ get id() {
15097
+ return (async () => (await this.project).id)();
15098
+ }
15099
+ spanParentObjectType() {
15100
+ return SpanParentObjectType.PROJECT_LOGS;
15101
+ }
14934
15102
  async getState() {
14935
15103
  await this.lazyMetadata.get();
14936
15104
  return _state;
@@ -14947,19 +15115,16 @@ var Logger = class {
14947
15115
  * @param event.metrics: (Optional) a dictionary of metrics to log. The following keys are populated automatically: "start", "end".
14948
15116
  * @param event.id: (Optional) a unique identifier for the event. If you don't provide one, BrainTrust will generate one for you.
14949
15117
  * @param options Additional logging options
14950
- * @param options.allowLogConcurrentWithActiveSpan in rare cases where you need to log at the top level separately from an active span on the logger, set this to true.
15118
+ * @param options.allowConcurrentWithSpans in rare cases where you need to log at the top level separately from spans on the logger elsewhere, set this to true.
14951
15119
  * :returns: The `id` of the logged event.
14952
15120
  */
14953
15121
  log(event, options) {
14954
- if (!options?.allowLogConcurrentWithActiveSpan) {
14955
- const checkCurrentSpan = currentSpan();
14956
- if (checkCurrentSpan instanceof SpanImpl && checkCurrentSpan.parentObject === this) {
14957
- throw new Error(
14958
- "Cannot run toplevel Logger.log method while there is an active span. To log to the span, use Span.log"
14959
- );
14960
- }
15122
+ if (this.calledStartSpan && !options?.allowConcurrentWithSpans) {
15123
+ throw new Error(
15124
+ "Cannot run toplevel `log` method while using spans. To log to the span, call `logger.traced` and then log with `span.log`"
15125
+ );
14961
15126
  }
14962
- const span = this.startSpan({ startTime: this.lastStartTime, event });
15127
+ const span = this.startSpanImpl({ startTime: this.lastStartTime, event });
14963
15128
  this.lastStartTime = span.end();
14964
15129
  const ret = span.id;
14965
15130
  if (this.logOptions.asyncFlush === true) {
@@ -14999,14 +15164,6 @@ var Logger = class {
14999
15164
  })();
15000
15165
  }
15001
15166
  }
15002
- async lazyParentIds() {
15003
- return {
15004
- kind: "project_log",
15005
- org_id: await this.org_id,
15006
- project_id: (await this.project).id,
15007
- log_id: "g"
15008
- };
15009
- }
15010
15167
  /**
15011
15168
  * Lower-level alternative to `traced`. This allows you to start a span yourself, and can be useful in situations
15012
15169
  * where you cannot use callbacks. However, spans started with `startSpan` will not be marked as the "current span",
@@ -15015,13 +15172,20 @@ var Logger = class {
15015
15172
  * See `traced` for full details.
15016
15173
  */
15017
15174
  startSpan(args) {
15018
- const { name, ...argsRest } = args ?? {};
15175
+ this.calledStartSpan = true;
15176
+ return this.startSpanImpl(args);
15177
+ }
15178
+ startSpanImpl(args) {
15019
15179
  return new SpanImpl({
15020
- parentObject: this,
15021
- parentIds: new LazyValue(() => this.lazyParentIds()),
15180
+ ...startSpanParentArgs({
15181
+ parent: args?.parent,
15182
+ parentId: args?.parentId,
15183
+ spanParentObjectType: this.spanParentObjectType(),
15184
+ spanParentObjectId: this.lazyId
15185
+ }),
15186
+ ...args,
15022
15187
  bgLogger: this.bgLogger,
15023
- name: name ?? "root",
15024
- ...argsRest
15188
+ defaultRootType: SpanTypeAttribute.TASK
15025
15189
  });
15026
15190
  }
15027
15191
  /**
@@ -15038,10 +15202,21 @@ var Logger = class {
15038
15202
  logFeedback(event) {
15039
15203
  logFeedbackImpl(
15040
15204
  this.bgLogger,
15041
- new LazyValue(() => this.lazyParentIds()),
15205
+ this.spanParentObjectType(),
15206
+ this.lazyId,
15042
15207
  event
15043
15208
  );
15044
15209
  }
15210
+ /**
15211
+ * Return a serialized representation of the logger that can be used to start subspans in other places. See `Span.start_span` for more details.
15212
+ */
15213
+ async export() {
15214
+ return new SpanParentComponents({
15215
+ objectType: this.spanParentObjectType(),
15216
+ objectId: await this.id,
15217
+ rowId: ""
15218
+ }).toStr();
15219
+ }
15045
15220
  /*
15046
15221
  * Flush any pending logs to the server.
15047
15222
  */
@@ -15631,8 +15806,10 @@ async function login(options = {}) {
15631
15806
  apiKey = isomorph_default.getEnv("BRAINTRUST_API_KEY"),
15632
15807
  orgName = isomorph_default.getEnv("BRAINTRUST_ORG_NAME")
15633
15808
  } = options || {};
15809
+ const appPublicUrl = isomorph_default.getEnv("BRAINTRUST_APP_PUBLIC_URL") || appUrl;
15634
15810
  _state.resetLoginInfo();
15635
15811
  _state.appUrl = appUrl;
15812
+ _state.appPublicUrl = appPublicUrl;
15636
15813
  let conn = null;
15637
15814
  if (apiKey !== void 0) {
15638
15815
  const resp = await checkResponse(
@@ -15708,7 +15885,33 @@ function getSpanParentObject(options) {
15708
15885
  return NOOP_SPAN;
15709
15886
  }
15710
15887
  function traced(callback, args) {
15711
- const { span, parentObject } = startSpanReturnParent(args);
15888
+ const { span, isLogger } = (() => {
15889
+ if (args?.parent) {
15890
+ if (args?.parentId) {
15891
+ throw new Error(
15892
+ "Cannot specify both `parent` and `parent_id`. Prefer `parent`"
15893
+ );
15894
+ }
15895
+ const components = SpanParentComponents.fromStr(args?.parent);
15896
+ const span2 = new SpanImpl({
15897
+ ...args,
15898
+ parentObjectType: components.objectType,
15899
+ parentObjectId: new LazyValue(async () => components.objectId),
15900
+ parentRowId: components.rowId,
15901
+ bgLogger: _state.globalBgLogger()
15902
+ });
15903
+ return {
15904
+ span: span2,
15905
+ isLogger: components.objectType === SpanParentObjectType.PROJECT_LOGS
15906
+ };
15907
+ } else {
15908
+ const parentObject = getSpanParentObject({
15909
+ asyncFlush: args?.asyncFlush
15910
+ });
15911
+ const span2 = parentObject.startSpan(args);
15912
+ return { span: span2, isLogger: parentObject.kind === "logger" };
15913
+ }
15914
+ })();
15712
15915
  const ret = runFinally(
15713
15916
  () => {
15714
15917
  if (args?.setCurrent ?? true) {
@@ -15724,23 +15927,17 @@ function traced(callback, args) {
15724
15927
  } else {
15725
15928
  return (async () => {
15726
15929
  const awaitedRet = await ret;
15727
- if (parentObject.kind === "logger") {
15728
- await parentObject.flush();
15930
+ if (isLogger) {
15931
+ await span.flush();
15729
15932
  }
15730
15933
  return awaitedRet;
15731
15934
  })();
15732
15935
  }
15733
15936
  }
15734
15937
  function startSpan(args) {
15735
- return startSpanReturnParent(args).span;
15736
- }
15737
- function startSpanReturnParent(args) {
15738
- const parentObject = getSpanParentObject({
15938
+ return getSpanParentObject({
15739
15939
  asyncFlush: args?.asyncFlush
15740
- });
15741
- const { name: nameOpt, ...argsRest } = args ?? {};
15742
- const name = parentObject.kind === "span" ? nameOpt : nameOpt ?? "root";
15743
- return { span: parentObject.startSpan({ name, ...argsRest }), parentObject };
15940
+ }).startSpan(args);
15744
15941
  }
15745
15942
  function withCurrent(span, callback) {
15746
15943
  return _state.currentSpan.run(span, () => callback(span));
@@ -15922,6 +16119,8 @@ var Experiment = class extends ObjectFetcher {
15922
16119
  dataset;
15923
16120
  bgLogger;
15924
16121
  lastStartTime;
16122
+ lazyId;
16123
+ calledStartSpan;
15925
16124
  // For type identification.
15926
16125
  kind = "experiment";
15927
16126
  constructor(lazyMetadata, dataset) {
@@ -15933,6 +16132,8 @@ var Experiment = class extends ObjectFetcher {
15933
16132
  );
15934
16133
  this.bgLogger = new BackgroundLogger(logConn);
15935
16134
  this.lastStartTime = getCurrentUnixTimestamp();
16135
+ this.lazyId = new LazyValue(async () => await this.id);
16136
+ this.calledStartSpan = false;
15936
16137
  }
15937
16138
  get id() {
15938
16139
  return (async () => {
@@ -15949,6 +16150,9 @@ var Experiment = class extends ObjectFetcher {
15949
16150
  return (await this.lazyMetadata.get()).project;
15950
16151
  })();
15951
16152
  }
16153
+ spanParentObjectType() {
16154
+ return SpanParentObjectType.EXPERIMENT;
16155
+ }
15952
16156
  async getState() {
15953
16157
  await this.lazyMetadata.get();
15954
16158
  return _state;
@@ -15967,20 +16171,17 @@ var Experiment = class extends ObjectFetcher {
15967
16171
  * @param event.dataset_record_id: (Optional) the id of the dataset record that this event is associated with. This field is required if and only if the experiment is associated with a dataset.
15968
16172
  * @param event.inputs: (Deprecated) the same as `input` (will be removed in a future version).
15969
16173
  * @param options Additional logging options
15970
- * @param options.allowLogConcurrentWithActiveSpan in rare cases where you need to log at the top level separately from an active span on the experiment, set this to true.
16174
+ * @param options.allowConcurrentWithSpans in rare cases where you need to log at the top level separately from spans on the experiment elsewhere, set this to true.
15971
16175
  * :returns: The `id` of the logged event.
15972
16176
  */
15973
16177
  log(event, options) {
15974
- if (!options?.allowLogConcurrentWithActiveSpan) {
15975
- const checkCurrentSpan = currentSpan();
15976
- if (checkCurrentSpan instanceof SpanImpl && checkCurrentSpan.parentObject === this) {
15977
- throw new Error(
15978
- "Cannot run toplevel Experiment.log method while there is an active span. To log to the span, use Span.log"
15979
- );
15980
- }
16178
+ if (this.calledStartSpan && !options?.allowConcurrentWithSpans) {
16179
+ throw new Error(
16180
+ "Cannot run toplevel `log` method while using spans. To log to the span, call `experiment.traced` and then log with `span.log`"
16181
+ );
15981
16182
  }
15982
16183
  event = validateAndSanitizeExperimentLogFullArgs(event, !!this.dataset);
15983
- const span = this.startSpan({ startTime: this.lastStartTime, event });
16184
+ const span = this.startSpanImpl({ startTime: this.lastStartTime, event });
15984
16185
  this.lastStartTime = span.end();
15985
16186
  return span.id;
15986
16187
  }
@@ -16003,13 +16204,6 @@ var Experiment = class extends ObjectFetcher {
16003
16204
  () => span.end()
16004
16205
  );
16005
16206
  }
16006
- async lazyParentIds() {
16007
- return {
16008
- kind: "experiment",
16009
- project_id: (await this.project).id,
16010
- experiment_id: await this.id
16011
- };
16012
- }
16013
16207
  /**
16014
16208
  * Lower-level alternative to `traced`. This allows you to start a span yourself, and can be useful in situations
16015
16209
  * where you cannot use callbacks. However, spans started with `startSpan` will not be marked as the "current span",
@@ -16018,13 +16212,20 @@ var Experiment = class extends ObjectFetcher {
16018
16212
  * See `traced` for full details.
16019
16213
  */
16020
16214
  startSpan(args) {
16021
- const { name, ...argsRest } = args ?? {};
16215
+ this.calledStartSpan = true;
16216
+ return this.startSpanImpl(args);
16217
+ }
16218
+ startSpanImpl(args) {
16022
16219
  return new SpanImpl({
16023
- parentObject: this,
16024
- parentIds: new LazyValue(() => this.lazyParentIds()),
16220
+ ...startSpanParentArgs({
16221
+ parent: args?.parent,
16222
+ parentId: args?.parentId,
16223
+ spanParentObjectType: this.spanParentObjectType(),
16224
+ spanParentObjectId: this.lazyId
16225
+ }),
16226
+ ...args,
16025
16227
  bgLogger: this.bgLogger,
16026
- name: name ?? "root",
16027
- ...argsRest
16228
+ defaultRootType: SpanTypeAttribute.EVAL
16028
16229
  });
16029
16230
  }
16030
16231
  async fetchBaseExperiment() {
@@ -16059,10 +16260,10 @@ var Experiment = class extends ObjectFetcher {
16059
16260
  let { summarizeScores = true, comparisonExperimentId = void 0 } = options || {};
16060
16261
  await this.bgLogger.flush();
16061
16262
  const state = await this.getState();
16062
- const projectUrl = `${state.appUrl}/app/${encodeURIComponent(
16263
+ const projectUrl = `${state.appPublicUrl}/app/${encodeURIComponent(
16063
16264
  state.orgName
16064
16265
  )}/p/${encodeURIComponent((await this.project).name)}`;
16065
- const experimentUrl = `${projectUrl}/${encodeURIComponent(
16266
+ const experimentUrl = `${projectUrl}/experiments/${encodeURIComponent(
16066
16267
  await this.name
16067
16268
  )}`;
16068
16269
  let scores = void 0;
@@ -16095,7 +16296,7 @@ var Experiment = class extends ObjectFetcher {
16095
16296
  projectUrl,
16096
16297
  experimentUrl,
16097
16298
  comparisonExperimentName,
16098
- scores,
16299
+ scores: scores ?? {},
16099
16300
  metrics
16100
16301
  };
16101
16302
  }
@@ -16113,10 +16314,21 @@ var Experiment = class extends ObjectFetcher {
16113
16314
  logFeedback(event) {
16114
16315
  logFeedbackImpl(
16115
16316
  this.bgLogger,
16116
- new LazyValue(() => this.lazyParentIds()),
16317
+ this.spanParentObjectType(),
16318
+ this.lazyId,
16117
16319
  event
16118
16320
  );
16119
16321
  }
16322
+ /**
16323
+ * Return a serialized representation of the experiment that can be used to start subspans in other places. See `Span.start_span` for more details.
16324
+ */
16325
+ async export() {
16326
+ return new SpanParentComponents({
16327
+ objectType: this.spanParentObjectType(),
16328
+ objectId: await this.id,
16329
+ rowId: ""
16330
+ }).toStr();
16331
+ }
16120
16332
  /**
16121
16333
  * Flush any pending rows to the server.
16122
16334
  */
@@ -16184,20 +16396,26 @@ var SpanImpl = class _SpanImpl {
16184
16396
  isMerge;
16185
16397
  loggedEndTime;
16186
16398
  // For internal use only.
16187
- parentObject;
16188
- // These fields are logged to every span row.
16189
- parentIds;
16190
- rowIds;
16399
+ parentObjectType;
16400
+ parentObjectId;
16401
+ parentRowId;
16402
+ _id;
16191
16403
  kind = "span";
16192
- // root_experiment should only be specified for a root span. parent_span
16193
- // should only be specified for non-root spans.
16194
16404
  constructor(args) {
16405
+ const spanAttributes = args.spanAttributes ?? {};
16406
+ const event = args.event ?? {};
16407
+ const type = args.type ?? (args.parentRowId ? void 0 : args.defaultRootType);
16195
16408
  this.loggedEndTime = void 0;
16409
+ this.parentObjectType = args.parentObjectType;
16410
+ this.parentObjectId = args.parentObjectId;
16411
+ this.parentRowId = args.parentRowId;
16196
16412
  this.bgLogger = args.bgLogger;
16197
16413
  const callerLocation = isomorph_default.getCallerLocation();
16198
16414
  const name = (() => {
16199
16415
  if (args.name)
16200
16416
  return args.name;
16417
+ if (!args.parentRowId)
16418
+ return "root";
16201
16419
  if (callerLocation) {
16202
16420
  const pathComponents = callerLocation.caller_filename.split("/");
16203
16421
  const filename = pathComponents[pathComponents.length - 1];
@@ -16213,71 +16431,52 @@ var SpanImpl = class _SpanImpl {
16213
16431
  },
16214
16432
  context: { ...callerLocation },
16215
16433
  span_attributes: {
16216
- ...args.spanAttributes,
16217
16434
  name,
16435
+ type,
16436
+ ...spanAttributes,
16218
16437
  exec_counter: executionCounter++
16219
16438
  },
16220
16439
  created: (/* @__PURE__ */ new Date()).toISOString()
16221
16440
  };
16222
- this.parentObject = args.parentObject;
16223
- this.parentIds = args.parentIds;
16224
- const id = args.event?.id ?? v4_default();
16225
- this.rowIds = { id };
16226
- const parentSpanInfo = "parentSpanInfo" in args ? args.parentSpanInfo : void 0;
16227
- const parentId = "parentId" in args ? args.parentId : void 0;
16228
- if (parentSpanInfo && parentId) {
16229
- throw new Error(
16230
- "Only one of parentSpanInfo and parentId may be specified"
16231
- );
16232
- }
16233
- if (parentId) {
16234
- this.rowIds[PARENT_ID_FIELD] = parentId;
16235
- } else {
16236
- this.rowIds.span_id = v4_default();
16237
- if (parentSpanInfo) {
16238
- this.rowIds.root_span_id = parentSpanInfo.root_span_id;
16239
- this.internalData.span_parents = [parentSpanInfo.span_id];
16240
- } else {
16241
- this.rowIds.root_span_id = this.rowIds.span_id;
16242
- }
16243
- }
16441
+ this._id = event.id ?? v4_default();
16244
16442
  this.isMerge = false;
16245
- const { id: _id, ...eventRest } = args.event ?? {};
16443
+ const { id: _id, ...eventRest } = event;
16246
16444
  this.log(eventRest);
16247
16445
  this.isMerge = true;
16248
16446
  }
16249
16447
  get id() {
16250
- return this.rowIds.id;
16448
+ return this._id;
16251
16449
  }
16252
16450
  log(event) {
16253
16451
  const sanitized = validateAndSanitizeExperimentLogPartialArgs(event);
16254
16452
  let sanitizedAndInternalData = { ...this.internalData };
16255
16453
  mergeDicts(sanitizedAndInternalData, sanitized);
16256
16454
  this.internalData = {};
16257
- if (sanitizedAndInternalData.tags && sanitizedAndInternalData.tags.length > 0 && this.rowIds.span_id !== this.rowIds.root_span_id) {
16258
- throw new Error("Tags can only be logged to the root span");
16259
- }
16260
16455
  let partialRecord = {
16261
16456
  ...sanitizedAndInternalData,
16262
- ...this.rowIds,
16263
16457
  [IS_MERGE_FIELD]: this.isMerge
16264
16458
  };
16459
+ const serializedPartialRecord = JSON.stringify(partialRecord);
16460
+ partialRecord = JSON.parse(serializedPartialRecord);
16265
16461
  if (partialRecord.metrics?.end) {
16266
16462
  this.loggedEndTime = partialRecord.metrics?.end;
16267
16463
  }
16268
- const serializedPartialRecord = JSON.stringify(partialRecord);
16269
- partialRecord = JSON.parse(serializedPartialRecord);
16270
- const record = new LazyValue(async () => {
16271
- const { kind, ...parentIds } = await this.parentIds.get();
16272
- return {
16273
- ...partialRecord,
16274
- ...parentIds
16275
- };
16464
+ if ((partialRecord.tags ?? []).length > 0 && this.parentRowId) {
16465
+ throw new Error("Tags can only be logged to the root span");
16466
+ }
16467
+ const computeRecord = async () => ({
16468
+ ...partialRecord,
16469
+ ...new SpanParentComponents({
16470
+ objectType: this.parentObjectType,
16471
+ objectId: await this.parentObjectId.get(),
16472
+ rowId: this.parentRowId
16473
+ }).asDict(),
16474
+ id: this.id
16276
16475
  });
16277
- this.bgLogger.log([record]);
16476
+ this.bgLogger.log([new LazyValue(computeRecord)]);
16278
16477
  }
16279
16478
  logFeedback(event) {
16280
- logFeedbackImpl(this.bgLogger, this.parentIds, {
16479
+ logFeedbackImpl(this.bgLogger, this.parentObjectType, this.parentObjectId, {
16281
16480
  ...event,
16282
16481
  id: this.id
16283
16482
  });
@@ -16297,25 +16496,15 @@ var SpanImpl = class _SpanImpl {
16297
16496
  );
16298
16497
  }
16299
16498
  startSpan(args) {
16300
- const parentId = args?.parentId ?? (this.rowIds[PARENT_ID_FIELD] ? this.id : void 0);
16301
- const parentSpanInfo = (() => {
16302
- if (parentId)
16303
- return void 0;
16304
- if (!(this.rowIds.span_id && this.rowIds.root_span_id)) {
16305
- throw new Error("Impossible");
16306
- }
16307
- return {
16308
- span_id: this.rowIds.span_id,
16309
- root_span_id: this.rowIds.root_span_id
16310
- };
16311
- })();
16312
16499
  return new _SpanImpl({
16313
- parentObject: this.parentObject,
16314
- parentIds: this.parentIds,
16315
- bgLogger: this.bgLogger,
16316
- parentSpanInfo,
16317
- parentId,
16318
- ...args
16500
+ ...args,
16501
+ ...startSpanParentArgs({
16502
+ parent: args?.parent,
16503
+ parentId: args?.parentId ?? (args?.parent ? void 0 : this.id),
16504
+ spanParentObjectType: this.parentObjectType,
16505
+ spanParentObjectId: this.parentObjectId
16506
+ }),
16507
+ bgLogger: this.bgLogger
16319
16508
  });
16320
16509
  }
16321
16510
  end(args) {
@@ -16329,9 +16518,22 @@ var SpanImpl = class _SpanImpl {
16329
16518
  this.log({});
16330
16519
  return endTime;
16331
16520
  }
16521
+ /**
16522
+ * Return a serialized representation of the span that can be used to start subspans in other places. See `Span.start_span` for more details.
16523
+ */
16524
+ async export() {
16525
+ return new SpanParentComponents({
16526
+ objectType: this.parentObjectType,
16527
+ objectId: await this.parentObjectId.get(),
16528
+ rowId: this.id
16529
+ }).toStr();
16530
+ }
16332
16531
  close(args) {
16333
16532
  return this.end(args);
16334
16533
  }
16534
+ async flush() {
16535
+ return await this.bgLogger.flush();
16536
+ }
16335
16537
  };
16336
16538
  var Dataset = class extends ObjectFetcher {
16337
16539
  lazyMetadata;
@@ -16418,7 +16620,6 @@ var Dataset = class extends ObjectFetcher {
16418
16620
  input,
16419
16621
  expected: expected === void 0 ? output : expected,
16420
16622
  tags,
16421
- project_id: (await this.project).id,
16422
16623
  dataset_id: await this.id,
16423
16624
  created: (/* @__PURE__ */ new Date()).toISOString(),
16424
16625
  metadata
@@ -16429,7 +16630,6 @@ var Dataset = class extends ObjectFetcher {
16429
16630
  delete(id) {
16430
16631
  const args = new LazyValue(async () => ({
16431
16632
  id,
16432
- project_id: (await this.project).id,
16433
16633
  dataset_id: await this.id,
16434
16634
  created: (/* @__PURE__ */ new Date()).toISOString(),
16435
16635
  _object_delete: true
@@ -16447,10 +16647,12 @@ var Dataset = class extends ObjectFetcher {
16447
16647
  let { summarizeData = true } = options || {};
16448
16648
  await this.bgLogger.flush();
16449
16649
  const state = await this.getState();
16450
- const projectUrl = `${state.appUrl}/app/${encodeURIComponent(
16650
+ const projectUrl = `${state.appPublicUrl}/app/${encodeURIComponent(
16451
16651
  state.orgName
16452
16652
  )}/p/${encodeURIComponent((await this.project).name)}`;
16453
- const datasetUrl = `${projectUrl}/d/${encodeURIComponent(await this.name)}`;
16653
+ const datasetUrl = `${projectUrl}/datasets/${encodeURIComponent(
16654
+ await this.name
16655
+ )}`;
16454
16656
  let dataSummary = void 0;
16455
16657
  if (summarizeData) {
16456
16658
  dataSummary = await state.logConn().get_json(
@@ -16530,7 +16732,7 @@ var Prompt = class {
16530
16732
  ...this.defaults,
16531
16733
  ...Object.fromEntries(
16532
16734
  Object.entries(this.options.params || {}).filter(
16533
- ([k, v]) => !BRAINTRUST_PARAMS.includes(k)
16735
+ ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
16534
16736
  )
16535
16737
  ),
16536
16738
  ...!isEmpty(this.options.model) ? {
@@ -16564,9 +16766,14 @@ var Prompt = class {
16564
16766
  "Prompt is a completion prompt. Use buildCompletion() instead"
16565
16767
  );
16566
16768
  }
16769
+ const render3 = (template) => mustache_default.render(template, buildArgs, void 0, {
16770
+ escape: (v) => typeof v === "string" ? v : JSON.stringify(v)
16771
+ });
16567
16772
  const messages = (prompt.messages || []).map((m) => ({
16568
16773
  ...m,
16569
- ..."content" in m && typeof m.content === "string" ? { content: mustache_default.render(m.content, buildArgs) } : {}
16774
+ ..."content" in m ? {
16775
+ content: typeof m.content === "string" ? render3(m.content) : JSON.parse(render3(JSON.stringify(m.content)))
16776
+ } : {}
16570
16777
  }));
16571
16778
  return {
16572
16779
  ...params,
@@ -16662,25 +16869,37 @@ function initExperiment2(projectName, options = {}) {
16662
16869
  setCurrent: false
16663
16870
  });
16664
16871
  }
16665
- globalThis._evals = {};
16666
- async function Eval(name, evaluator) {
16872
+ globalThis._evals = {
16873
+ evaluators: {},
16874
+ reporters: {}
16875
+ };
16876
+ async function Eval(name, evaluator, reporter) {
16667
16877
  let evalName = makeEvalName(name, evaluator.experimentName);
16668
- if (_evals[evalName]) {
16878
+ if (_evals.evaluators[evalName]) {
16669
16879
  evalName = `${evalName}_${Object.keys(_evals).length}`;
16670
16880
  }
16671
16881
  if (globalThis._lazy_load) {
16672
- _evals[evalName] = { evalName, projectName: name, ...evaluator };
16882
+ _evals.evaluators[evalName] = {
16883
+ evaluator: { evalName, projectName: name, ...evaluator },
16884
+ reporter
16885
+ };
16673
16886
  return {
16674
- projectName: "_lazy_load",
16675
- experimentName: "_lazy_load",
16676
- projectUrl: "",
16677
- experimentUrl: "",
16678
- comparisonExperimentName: "",
16679
- scores: {},
16680
- metrics: {}
16887
+ summary: {
16888
+ scores: {},
16889
+ metrics: {},
16890
+ projectName: "",
16891
+ experimentName: ""
16892
+ },
16893
+ results: []
16681
16894
  };
16682
16895
  }
16683
16896
  const progressReporter = new BarProgressReporter();
16897
+ if (typeof reporter === "string") {
16898
+ throw new Error(
16899
+ "Must specify a reporter object, not a name. Can only specify reporter names when running 'braintrust eval'"
16900
+ );
16901
+ }
16902
+ const resolvedReporter = reporter || defaultReporter;
16684
16903
  try {
16685
16904
  const experiment = initExperiment2(name, {
16686
16905
  experiment: evaluator.experimentName,
@@ -16688,18 +16907,17 @@ async function Eval(name, evaluator) {
16688
16907
  isPublic: evaluator.isPublic
16689
16908
  });
16690
16909
  try {
16691
- const ret = await runEvaluator(
16692
- experiment,
16693
- {
16694
- evalName,
16695
- projectName: name,
16696
- ...evaluator
16697
- },
16698
- progressReporter,
16699
- []
16700
- );
16701
- reportEvaluatorResult(name, ret, { verbose: true, jsonl: false });
16702
- return ret.summary;
16910
+ const evalDef = {
16911
+ evalName,
16912
+ projectName: name,
16913
+ ...evaluator
16914
+ };
16915
+ const ret = await runEvaluator(experiment, evalDef, progressReporter, []);
16916
+ resolvedReporter.reportEval(evalDef, ret, {
16917
+ verbose: true,
16918
+ jsonl: false
16919
+ });
16920
+ return ret;
16703
16921
  } finally {
16704
16922
  experiment.flush();
16705
16923
  }
@@ -16707,6 +16925,16 @@ async function Eval(name, evaluator) {
16707
16925
  progressReporter.stop();
16708
16926
  }
16709
16927
  }
16928
+ function Reporter(name, reporter) {
16929
+ const ret = { name, ...reporter };
16930
+ if (_evals.reporters[name]) {
16931
+ throw new Error(`Reporter ${name} already exists`);
16932
+ }
16933
+ if (globalThis._lazy_load) {
16934
+ _evals.reporters[name] = ret;
16935
+ }
16936
+ return ret;
16937
+ }
16710
16938
  function serializeJSONWithPlainString(v) {
16711
16939
  if (typeof v === "string") {
16712
16940
  return v;
@@ -16799,27 +17027,54 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters) {
16799
17027
  const scoreResults = await Promise.all(
16800
17028
  evaluator.scores.map(async (score, score_idx) => {
16801
17029
  try {
16802
- const result = await rootSpan.traced(
17030
+ const results2 = await rootSpan.traced(
16803
17031
  async (span) => {
16804
17032
  const scoreResult = score(scoringArgs);
16805
17033
  const scoreValue = scoreResult instanceof Promise ? await scoreResult : scoreResult;
16806
17034
  if (scoreValue === null) {
16807
17035
  return null;
16808
17036
  }
16809
- const result2 = typeof scoreValue === "object" ? scoreValue : { name: scorerNames[score_idx], score: scoreValue };
16810
- const {
16811
- metadata: resultMetadata,
16812
- name,
16813
- ...resultRest
16814
- } = result2;
17037
+ if (Array.isArray(scoreValue)) {
17038
+ for (const s of scoreValue) {
17039
+ if (!(typeof s === "object" && !isEmpty(s))) {
17040
+ throw new Error(
17041
+ `When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(
17042
+ s
17043
+ )}`
17044
+ );
17045
+ }
17046
+ }
17047
+ }
17048
+ const results3 = Array.isArray(scoreValue) ? scoreValue : typeof scoreValue === "object" && !isEmpty(scoreValue) ? [scoreValue] : [
17049
+ {
17050
+ name: scorerNames[score_idx],
17051
+ score: scoreValue
17052
+ }
17053
+ ];
17054
+ const getOtherFields = (s) => {
17055
+ const { metadata: metadata2, name, ...rest } = s;
17056
+ return rest;
17057
+ };
17058
+ const resultMetadata = results3.length === 1 ? results3[0].metadata : results3.reduce(
17059
+ (prev, s) => mergeDicts(prev, {
17060
+ [s.name]: s.metadata
17061
+ }),
17062
+ {}
17063
+ );
17064
+ const resultOutput = results3.length === 1 ? getOtherFields(results3[0]) : results3.reduce(
17065
+ (prev, s) => mergeDicts(prev, { [s.name]: getOtherFields(s) }),
17066
+ {}
17067
+ );
17068
+ const scores2 = results3.reduce(
17069
+ (prev, s) => mergeDicts(prev, { [s.name]: s.score }),
17070
+ {}
17071
+ );
16815
17072
  span.log({
16816
- output: resultRest,
17073
+ output: resultOutput,
16817
17074
  metadata: resultMetadata,
16818
- scores: {
16819
- [name]: resultRest.score
16820
- }
17075
+ scores: scores2
16821
17076
  });
16822
- return result2;
17077
+ return results3;
16823
17078
  },
16824
17079
  {
16825
17080
  name: scorerNames[score_idx],
@@ -16829,7 +17084,7 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters) {
16829
17084
  event: { input: scoringArgs }
16830
17085
  }
16831
17086
  );
16832
- return { kind: "score", value: result };
17087
+ return { kind: "score", value: results2 };
16833
17088
  } catch (e) {
16834
17089
  return { kind: "error", value: e };
16835
17090
  }
@@ -16837,12 +17092,18 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters) {
16837
17092
  );
16838
17093
  const passingScorersAndResults = [];
16839
17094
  const failingScorersAndResults = [];
16840
- scoreResults.forEach((result, i) => {
17095
+ scoreResults.forEach((results2, i) => {
16841
17096
  const name = scorerNames[i];
16842
- if (result.kind === "score") {
16843
- passingScorersAndResults.push({ name, score: result.value });
17097
+ if (results2.kind === "score") {
17098
+ (results2.value || []).forEach((result) => {
17099
+ passingScorersAndResults.push({
17100
+ name: result.name,
17101
+ score: result
17102
+ });
17103
+ scores[result.name] = result.score;
17104
+ });
16844
17105
  } else {
16845
- failingScorersAndResults.push({ name, error: result.value });
17106
+ failingScorersAndResults.push({ name, error: results2.value });
16846
17107
  }
16847
17108
  });
16848
17109
  if (failingScorersAndResults.length) {
@@ -16867,7 +17128,10 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters) {
16867
17128
  progressReporter.increment(evaluator.evalName);
16868
17129
  }
16869
17130
  return {
17131
+ input: datum.input,
17132
+ ..."expected" in datum ? { expected: datum.expected } : {},
16870
17133
  output,
17134
+ tags: datum.tags,
16871
17135
  metadata,
16872
17136
  scores,
16873
17137
  error: error2
@@ -16890,10 +17154,10 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters) {
16890
17154
  }
16891
17155
  });
16892
17156
  const results = await Promise.all(evals);
16893
- const summary = experiment ? await experiment.summarize() : null;
17157
+ const summary = experiment ? await experiment.summarize() : buildLocalSummary(evaluator, results);
16894
17158
  return {
16895
- results,
16896
- summary
17159
+ summary,
17160
+ results
16897
17161
  };
16898
17162
  }
16899
17163
  var error = import_chalk.default.bold.red;
@@ -16905,28 +17169,46 @@ function logError(e, verbose) {
16905
17169
  console.error(e);
16906
17170
  }
16907
17171
  }
16908
- function reportEvaluatorResult(evaluatorName, evaluatorResult, {
16909
- verbose,
16910
- jsonl
16911
- }) {
16912
- const { results, summary } = evaluatorResult;
16913
- const failingResults = results.filter(
16914
- (r) => r.error !== void 0
16915
- );
17172
+ function buildLocalSummary(evaluator, results) {
17173
+ const scoresByName = {};
17174
+ for (const result of results) {
17175
+ for (const [name, score] of Object.entries(result.scores)) {
17176
+ const { total, count } = scoresByName[name] || { total: 0, count: 0 };
17177
+ if (score === null) {
17178
+ continue;
17179
+ }
17180
+ scoresByName[name] = { total: total + score, count: count + 1 };
17181
+ }
17182
+ }
17183
+ return {
17184
+ projectName: evaluator.projectName,
17185
+ experimentName: evaluator.evalName,
17186
+ scores: Object.fromEntries(
17187
+ Object.entries(scoresByName).map(([name, { total, count }]) => [
17188
+ name,
17189
+ {
17190
+ name,
17191
+ score: total / count
17192
+ }
17193
+ ])
17194
+ )
17195
+ };
17196
+ }
17197
+ function reportFailures(evaluator, failingResults, { verbose, jsonl }) {
16916
17198
  if (failingResults.length > 0) {
16917
17199
  console.error(
16918
17200
  warning(
16919
- `Evaluator ${evaluatorName} failed with ${(0, import_pluralize.default)(
17201
+ `Evaluator ${evaluator.evalName} failed with ${(0, import_pluralize.default)(
16920
17202
  "error",
16921
17203
  failingResults.length,
16922
17204
  true
16923
- )}. This evaluation ("${evaluatorName}") will not be fully logged.`
17205
+ )}. This evaluation ("${evaluator.evalName}") will not be fully logged.`
16924
17206
  )
16925
17207
  );
16926
17208
  if (jsonl) {
16927
17209
  console.log(
16928
17210
  JSON.stringify({
16929
- evaluatorName,
17211
+ evaluatorName: evaluator.evalName,
16930
17212
  errors: failingResults.map(
16931
17213
  (r) => `${r.error instanceof Error ? r.error.stack : r.error}`
16932
17214
  )
@@ -16941,33 +17223,24 @@ function reportEvaluatorResult(evaluatorName, evaluatorResult, {
16941
17223
  console.error(warning("Add --verbose to see full stack traces."));
16942
17224
  }
16943
17225
  }
16944
- if (summary) {
16945
- console.log(jsonl ? JSON.stringify(summary) : summary);
16946
- } else {
16947
- const scoresByName = {};
16948
- for (const result of results) {
16949
- for (const [name, score] of Object.entries(result.scores)) {
16950
- const { total, count } = scoresByName[name] || { total: 0, count: 0 };
16951
- if (score === null) {
16952
- continue;
16953
- }
16954
- scoresByName[name] = { total: total + score, count: count + 1 };
16955
- }
17226
+ }
17227
+ var defaultReporter = {
17228
+ name: "Braintrust default reporter",
17229
+ async reportEval(evaluator, result, { verbose, jsonl }) {
17230
+ const { results, summary } = result;
17231
+ const failingResults = results.filter(
17232
+ (r) => r.error !== void 0
17233
+ );
17234
+ if (failingResults.length > 0) {
17235
+ reportFailures(evaluator, failingResults, { verbose, jsonl });
16956
17236
  }
16957
- const summary2 = {
16958
- scores: Object.fromEntries(
16959
- Object.entries(scoresByName).map(([name, { total, count }]) => [
16960
- name,
16961
- {
16962
- name,
16963
- score: total / count
16964
- }
16965
- ])
16966
- )
16967
- };
16968
- console.log(jsonl ? JSON.stringify(summary2) : summary2);
17237
+ console.log(jsonl ? JSON.stringify(summary) : summary);
17238
+ return failingResults.length === 0;
17239
+ },
17240
+ async reportRun(evalReports) {
17241
+ return evalReports.every((r) => r);
16969
17242
  }
16970
- }
17243
+ };
16971
17244
 
16972
17245
  // src/oai.ts
16973
17246
  function wrapOpenAI(openai) {
@@ -17085,7 +17358,7 @@ function wrapBetaChatCompletion(completion) {
17085
17358
  });
17086
17359
  ret.on("chatCompletion", (completion2) => {
17087
17360
  span.log({
17088
- output: completion2.choices[0]
17361
+ output: completion2.choices
17089
17362
  });
17090
17363
  });
17091
17364
  ret.on("end", () => {
@@ -17113,8 +17386,8 @@ function wrapChatCompletion(completion) {
17113
17386
  span_info || {}
17114
17387
  )
17115
17388
  });
17389
+ const startTime = getCurrentUnixTimestamp();
17116
17390
  if (params.stream) {
17117
- const startTime = getCurrentUnixTimestamp();
17118
17391
  const ret = await completion(
17119
17392
  params,
17120
17393
  options
@@ -17134,8 +17407,9 @@ function wrapChatCompletion(completion) {
17134
17407
  metadata: {
17135
17408
  ...rest2
17136
17409
  },
17137
- output: ret.choices[0],
17410
+ output: ret.choices,
17138
17411
  metrics: {
17412
+ time_to_first_token: getCurrentUnixTimestamp() - startTime,
17139
17413
  tokens: ret.usage?.total_tokens,
17140
17414
  prompt_tokens: ret.usage?.prompt_tokens,
17141
17415
  completion_tokens: ret.usage?.completion_tokens
@@ -17185,6 +17459,52 @@ function wrapEmbeddings(create) {
17185
17459
  );
17186
17460
  };
17187
17461
  }
17462
+ function postprocessStreamingResults(allResults) {
17463
+ let role = void 0;
17464
+ let content = void 0;
17465
+ let tool_calls = void 0;
17466
+ let finish_reason = void 0;
17467
+ for (const result of allResults) {
17468
+ const delta = result.choices?.[0]?.delta;
17469
+ if (!delta) {
17470
+ continue;
17471
+ }
17472
+ if (!role && delta.role) {
17473
+ role = delta.role;
17474
+ }
17475
+ if (delta.finish_reason) {
17476
+ finish_reason = delta.finish_reason;
17477
+ }
17478
+ if (delta.content) {
17479
+ content = (content || "") + delta.content;
17480
+ }
17481
+ if (delta.tool_calls) {
17482
+ if (!tool_calls) {
17483
+ tool_calls = [
17484
+ {
17485
+ id: delta.tool_calls[0].id,
17486
+ type: delta.tool_calls[0].type,
17487
+ function: delta.tool_calls[0].function
17488
+ }
17489
+ ];
17490
+ } else {
17491
+ tool_calls[0].function.arguments += delta.tool_calls[0].function.arguments;
17492
+ }
17493
+ }
17494
+ }
17495
+ return [
17496
+ {
17497
+ index: 0,
17498
+ message: {
17499
+ role,
17500
+ content,
17501
+ tool_calls
17502
+ },
17503
+ logprobs: null,
17504
+ finish_reason
17505
+ }
17506
+ ];
17507
+ }
17188
17508
  var WrapperStream = class {
17189
17509
  span;
17190
17510
  iter;
@@ -17212,7 +17532,7 @@ var WrapperStream = class {
17212
17532
  yield item;
17213
17533
  }
17214
17534
  this.span.log({
17215
- output: allResults
17535
+ output: postprocessStreamingResults(allResults)
17216
17536
  });
17217
17537
  } finally {
17218
17538
  this.span.end();
@@ -17225,6 +17545,7 @@ configureNode();
17225
17545
  // Annotate the CommonJS export names for ESM import in node:
17226
17546
  0 && (module.exports = {
17227
17547
  BaseExperiment,
17548
+ Dataset,
17228
17549
  Eval,
17229
17550
  Experiment,
17230
17551
  Logger,
@@ -17232,9 +17553,11 @@ configureNode();
17232
17553
  NoopSpan,
17233
17554
  Prompt,
17234
17555
  ReadonlyExperiment,
17556
+ Reporter,
17235
17557
  SpanImpl,
17236
17558
  _internalGetGlobalState,
17237
17559
  _internalSetInitialState,
17560
+ buildLocalSummary,
17238
17561
  currentExperiment,
17239
17562
  currentLogger,
17240
17563
  currentSpan,
@@ -17246,6 +17569,7 @@ configureNode();
17246
17569
  loadPrompt,
17247
17570
  log,
17248
17571
  login,
17572
+ reportFailures,
17249
17573
  startSpan,
17250
17574
  summarize,
17251
17575
  traced,