braintrust 0.0.183 → 0.0.185

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
@@ -65,6 +65,8 @@ __export(src_exports, {
65
65
  currentLogger: () => currentLogger,
66
66
  currentSpan: () => currentSpan,
67
67
  default: () => src_default,
68
+ defaultErrorScoreHandler: () => defaultErrorScoreHandler,
69
+ deserializePlainStringAsJSON: () => deserializePlainStringAsJSON,
68
70
  devNullWritableStream: () => devNullWritableStream,
69
71
  flush: () => flush,
70
72
  getSpanParentObject: () => getSpanParentObject,
@@ -84,6 +86,7 @@ __export(src_exports, {
84
86
  permalink: () => permalink,
85
87
  projects: () => projects,
86
88
  renderMessage: () => renderMessage,
89
+ renderPromptParams: () => renderPromptParams,
87
90
  reportFailures: () => reportFailures,
88
91
  runEvaluator: () => runEvaluator,
89
92
  setFetch: () => setFetch,
@@ -310,7 +313,7 @@ async function repoInfo() {
310
313
  // src/stackutil.ts
311
314
  function getStackTrace() {
312
315
  const trace = new Error().stack;
313
- if (trace === void 0) {
316
+ if (typeof trace !== "string") {
314
317
  return [];
315
318
  }
316
319
  const traceLines = trace.split("\n");
@@ -354,54 +357,7 @@ function getCallerLocation() {
354
357
  var import_uuid = require("uuid");
355
358
  var import_core = require("@braintrust/core");
356
359
  var import_typespecs2 = require("@braintrust/core/typespecs");
357
-
358
- // src/util.ts
359
- var GLOBAL_PROJECT = "Global";
360
- function runCatchFinally(f, catchF, finallyF) {
361
- let runSyncCleanup = true;
362
- try {
363
- const ret = f();
364
- if (ret instanceof Promise) {
365
- runSyncCleanup = false;
366
- return ret.catch(catchF).finally(finallyF);
367
- } else {
368
- return ret;
369
- }
370
- } catch (e) {
371
- return catchF(e);
372
- } finally {
373
- if (runSyncCleanup) {
374
- finallyF();
375
- }
376
- }
377
- }
378
- function getCurrentUnixTimestamp() {
379
- return (/* @__PURE__ */ new Date()).getTime() / 1e3;
380
- }
381
- function isEmpty(a) {
382
- return a === void 0 || a === null;
383
- }
384
- var LazyValue = class {
385
- callable;
386
- value = {
387
- hasComputed: false
388
- };
389
- constructor(callable) {
390
- this.callable = callable;
391
- }
392
- get() {
393
- if (this.value.hasComputed) {
394
- return this.value.val;
395
- }
396
- this.value = { hasComputed: true, val: this.callable() };
397
- return this.value.val;
398
- }
399
- get hasComputed() {
400
- return this.value.hasComputed;
401
- }
402
- };
403
-
404
- // src/logger.ts
360
+ var import_functions = require("@vercel/functions");
405
361
  var import_mustache = __toESM(require("mustache"));
406
362
  var import_zod2 = require("zod");
407
363
 
@@ -659,61 +615,6 @@ function devNullWritableStream() {
659
615
  });
660
616
  }
661
617
 
662
- // src/logger.ts
663
- var import_functions = require("@vercel/functions");
664
-
665
- // src/prompt-cache/prompt-cache.ts
666
- function createCacheKey(key) {
667
- const prefix = key.projectId ?? key.projectName;
668
- if (!prefix) {
669
- throw new Error("Either projectId or projectName must be provided");
670
- }
671
- return `${prefix}:${key.slug}:${key.version}`;
672
- }
673
- var PromptCache = class {
674
- memoryCache;
675
- diskCache;
676
- constructor(options) {
677
- this.memoryCache = options.memoryCache;
678
- this.diskCache = options.diskCache;
679
- }
680
- /**
681
- * Retrieves a prompt from the cache.
682
- * First checks the in-memory LRU cache, then falls back to checking the disk cache if available.
683
- */
684
- async get(key) {
685
- const cacheKey = createCacheKey(key);
686
- const memoryPrompt = this.memoryCache.get(cacheKey);
687
- if (memoryPrompt !== void 0) {
688
- return memoryPrompt;
689
- }
690
- if (this.diskCache) {
691
- const diskPrompt = await this.diskCache.get(cacheKey);
692
- if (!diskPrompt) {
693
- return void 0;
694
- }
695
- this.memoryCache.set(cacheKey, diskPrompt);
696
- return diskPrompt;
697
- }
698
- return void 0;
699
- }
700
- /**
701
- * Stores a prompt in the cache.
702
- * Writes to the in-memory cache and the disk cache if available.
703
- *
704
- * @param key - The key to store the value under.
705
- * @param value - The value to store in the cache.
706
- * @throws If there is an error writing to the disk cache.
707
- */
708
- async set(key, value) {
709
- const cacheKey = createCacheKey(key);
710
- this.memoryCache.set(cacheKey, value);
711
- if (this.diskCache) {
712
- await this.diskCache.set(cacheKey, value);
713
- }
714
- }
715
- };
716
-
717
618
  // src/prompt-cache/disk-cache.ts
718
619
  function canUseDiskCache() {
719
620
  return !!(isomorph_default.gunzip && isomorph_default.gzip && isomorph_default.stat && isomorph_default.readFile && isomorph_default.writeFile && isomorph_default.utimes && isomorph_default.readdir && isomorph_default.mkdir && isomorph_default.unlink && isomorph_default.homedir);
@@ -851,12 +752,129 @@ var LRUCache = class {
851
752
  }
852
753
  };
853
754
 
755
+ // src/prompt-cache/prompt-cache.ts
756
+ function createCacheKey(key) {
757
+ const prefix = key.projectId ?? key.projectName;
758
+ if (!prefix) {
759
+ throw new Error("Either projectId or projectName must be provided");
760
+ }
761
+ return `${prefix}:${key.slug}:${key.version}`;
762
+ }
763
+ var PromptCache = class {
764
+ memoryCache;
765
+ diskCache;
766
+ constructor(options) {
767
+ this.memoryCache = options.memoryCache;
768
+ this.diskCache = options.diskCache;
769
+ }
770
+ /**
771
+ * Retrieves a prompt from the cache.
772
+ * First checks the in-memory LRU cache, then falls back to checking the disk cache if available.
773
+ */
774
+ async get(key) {
775
+ const cacheKey = createCacheKey(key);
776
+ const memoryPrompt = this.memoryCache.get(cacheKey);
777
+ if (memoryPrompt !== void 0) {
778
+ return memoryPrompt;
779
+ }
780
+ if (this.diskCache) {
781
+ const diskPrompt = await this.diskCache.get(cacheKey);
782
+ if (!diskPrompt) {
783
+ return void 0;
784
+ }
785
+ this.memoryCache.set(cacheKey, diskPrompt);
786
+ return diskPrompt;
787
+ }
788
+ return void 0;
789
+ }
790
+ /**
791
+ * Stores a prompt in the cache.
792
+ * Writes to the in-memory cache and the disk cache if available.
793
+ *
794
+ * @param key - The key to store the value under.
795
+ * @param value - The value to store in the cache.
796
+ * @throws If there is an error writing to the disk cache.
797
+ */
798
+ async set(key, value) {
799
+ const cacheKey = createCacheKey(key);
800
+ this.memoryCache.set(cacheKey, value);
801
+ if (this.diskCache) {
802
+ await this.diskCache.set(cacheKey, value);
803
+ }
804
+ }
805
+ };
806
+
807
+ // src/util.ts
808
+ var GLOBAL_PROJECT = "Global";
809
+ function runCatchFinally(f, catchF, finallyF) {
810
+ let runSyncCleanup = true;
811
+ try {
812
+ const ret = f();
813
+ if (ret instanceof Promise) {
814
+ runSyncCleanup = false;
815
+ return ret.catch(catchF).finally(finallyF);
816
+ } else {
817
+ return ret;
818
+ }
819
+ } catch (e) {
820
+ return catchF(e);
821
+ } finally {
822
+ if (runSyncCleanup) {
823
+ finallyF();
824
+ }
825
+ }
826
+ }
827
+ function getCurrentUnixTimestamp() {
828
+ return (/* @__PURE__ */ new Date()).getTime() / 1e3;
829
+ }
830
+ function isEmpty(a) {
831
+ return a === void 0 || a === null;
832
+ }
833
+ var LazyValue = class {
834
+ callable;
835
+ value = {
836
+ computedState: "uninitialized"
837
+ };
838
+ constructor(callable) {
839
+ this.callable = callable;
840
+ }
841
+ get() {
842
+ if (this.value.computedState !== "uninitialized") {
843
+ return this.value.val;
844
+ }
845
+ this.value = {
846
+ computedState: "in_progress",
847
+ val: this.callable().then((x) => {
848
+ this.value.computedState = "succeeded";
849
+ return x;
850
+ })
851
+ };
852
+ return this.value.val;
853
+ }
854
+ // If this is true, the caller should be able to obtain the LazyValue without
855
+ // it throwing.
856
+ get hasSucceeded() {
857
+ return this.value.computedState === "succeeded";
858
+ }
859
+ };
860
+ function addAzureBlobHeaders(headers, url) {
861
+ if (url.includes("blob.core.windows.net")) {
862
+ headers["x-ms-blob-type"] = "BlockBlob";
863
+ }
864
+ }
865
+
854
866
  // src/logger.ts
855
867
  var NoopSpan = class {
856
868
  id;
869
+ spanId;
870
+ rootSpanId;
871
+ spanParents;
857
872
  kind = "span";
858
873
  constructor() {
859
874
  this.id = "";
875
+ this.spanId = "";
876
+ this.rootSpanId = "";
877
+ this.spanParents = [];
860
878
  }
861
879
  log(_) {
862
880
  }
@@ -1331,6 +1349,7 @@ var Attachment = class {
1331
1349
  }
1332
1350
  throw error2;
1333
1351
  }
1352
+ addAzureBlobHeaders(headers, signedUrl);
1334
1353
  let objectStoreResponse;
1335
1354
  try {
1336
1355
  objectStoreResponse = await checkResponse(
@@ -1872,7 +1891,7 @@ var Logger = class {
1872
1891
  async export() {
1873
1892
  return new import_core.SpanComponentsV3({
1874
1893
  object_type: this.parentObjectType(),
1875
- ...this.computeMetadataArgs && !this.lazyId.hasComputed ? { compute_object_metadata_args: this.computeMetadataArgs } : { object_id: await this.lazyId.get() }
1894
+ ...this.computeMetadataArgs && !this.lazyId.hasSucceeded ? { compute_object_metadata_args: this.computeMetadataArgs } : { object_id: await this.lazyId.get() }
1876
1895
  }).toStr();
1877
1896
  }
1878
1897
  /*
@@ -2404,6 +2423,7 @@ function init(projectOrOptions, optionalOptions) {
2404
2423
  experiment: {
2405
2424
  id: response.experiment.id,
2406
2425
  name: response.experiment.name,
2426
+ created: response.experiment.created,
2407
2427
  fullInfo: response.experiment
2408
2428
  }
2409
2429
  };
@@ -2470,7 +2490,8 @@ function initDataset(projectOrOptions, optionalOptions) {
2470
2490
  projectId,
2471
2491
  metadata,
2472
2492
  useOutput: legacy,
2473
- state: stateArg
2493
+ state: stateArg,
2494
+ _internal_btql
2474
2495
  } = options;
2475
2496
  const state = stateArg ?? _globalState;
2476
2497
  const lazyMetadata = new LazyValue(
@@ -2505,7 +2526,13 @@ function initDataset(projectOrOptions, optionalOptions) {
2505
2526
  };
2506
2527
  }
2507
2528
  );
2508
- return new Dataset(stateArg ?? _globalState, lazyMetadata, version, legacy);
2529
+ return new Dataset(
2530
+ stateArg ?? _globalState,
2531
+ lazyMetadata,
2532
+ version,
2533
+ legacy,
2534
+ _internal_btql
2535
+ );
2509
2536
  }
2510
2537
  function withDataset(project, callback, options = {}) {
2511
2538
  console.warn(
@@ -3082,10 +3109,11 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
3082
3109
  return event;
3083
3110
  }
3084
3111
  var ObjectFetcher = class {
3085
- constructor(objectType, pinnedVersion, mutateRecord) {
3112
+ constructor(objectType, pinnedVersion, mutateRecord, _internal_btql) {
3086
3113
  this.objectType = objectType;
3087
3114
  this.pinnedVersion = pinnedVersion;
3088
3115
  this.mutateRecord = mutateRecord;
3116
+ this._internal_btql = _internal_btql;
3089
3117
  }
3090
3118
  _fetchedData = void 0;
3091
3119
  get id() {
@@ -3106,14 +3134,46 @@ var ObjectFetcher = class {
3106
3134
  async fetchedData() {
3107
3135
  if (this._fetchedData === void 0) {
3108
3136
  const state = await this.getState();
3109
- const resp = await state.apiConn().get(
3110
- `v1/${this.objectType}/${await this.id}/fetch`,
3111
- {
3112
- version: this.pinnedVersion
3113
- },
3114
- { headers: { "Accept-Encoding": "gzip" } }
3115
- );
3116
- const data = (await resp.json()).events;
3137
+ let data = null;
3138
+ if (this._internal_btql) {
3139
+ const resp = await state.apiConn().post(
3140
+ `btql`,
3141
+ {
3142
+ query: {
3143
+ ...this._internal_btql,
3144
+ select: [
3145
+ {
3146
+ op: "star"
3147
+ }
3148
+ ],
3149
+ from: {
3150
+ op: "function",
3151
+ name: {
3152
+ op: "ident",
3153
+ name: [this.objectType]
3154
+ },
3155
+ args: [
3156
+ {
3157
+ op: "literal",
3158
+ value: await this.id
3159
+ }
3160
+ ]
3161
+ }
3162
+ }
3163
+ },
3164
+ { headers: { "Accept-Encoding": "gzip" } }
3165
+ );
3166
+ data = (await resp.json()).data;
3167
+ } else {
3168
+ const resp = await state.apiConn().get(
3169
+ `v1/${this.objectType}/${await this.id}/fetch`,
3170
+ {
3171
+ version: this.pinnedVersion
3172
+ },
3173
+ { headers: { "Accept-Encoding": "gzip" } }
3174
+ );
3175
+ data = (await resp.json()).events;
3176
+ }
3117
3177
  this._fetchedData = this.mutateRecord ? data?.map(this.mutateRecord) : data;
3118
3178
  }
3119
3179
  return this._fetchedData || [];
@@ -3445,9 +3505,9 @@ var SpanImpl = class _SpanImpl {
3445
3505
  parentObjectId;
3446
3506
  parentComputeObjectMetadataArgs;
3447
3507
  _id;
3448
- spanId;
3449
- rootSpanId;
3450
- spanParents;
3508
+ _spanId;
3509
+ _rootSpanId;
3510
+ _spanParents;
3451
3511
  kind = "span";
3452
3512
  constructor(args) {
3453
3513
  this.state = args.state;
@@ -3492,13 +3552,13 @@ var SpanImpl = class _SpanImpl {
3492
3552
  created: (/* @__PURE__ */ new Date()).toISOString()
3493
3553
  };
3494
3554
  this._id = eventId ?? (0, import_uuid.v4)();
3495
- this.spanId = (0, import_uuid.v4)();
3555
+ this._spanId = (0, import_uuid.v4)();
3496
3556
  if (args.parentSpanIds) {
3497
- this.rootSpanId = args.parentSpanIds.rootSpanId;
3498
- this.spanParents = [args.parentSpanIds.spanId];
3557
+ this._rootSpanId = args.parentSpanIds.rootSpanId;
3558
+ this._spanParents = [args.parentSpanIds.spanId];
3499
3559
  } else {
3500
- this.rootSpanId = this.spanId;
3501
- this.spanParents = void 0;
3560
+ this._rootSpanId = this._spanId;
3561
+ this._spanParents = void 0;
3502
3562
  }
3503
3563
  this.isMerge = false;
3504
3564
  this.logInternal({ event, internalData });
@@ -3507,6 +3567,15 @@ var SpanImpl = class _SpanImpl {
3507
3567
  get id() {
3508
3568
  return this._id;
3509
3569
  }
3570
+ get spanId() {
3571
+ return this._spanId;
3572
+ }
3573
+ get rootSpanId() {
3574
+ return this._rootSpanId;
3575
+ }
3576
+ get spanParents() {
3577
+ return this._spanParents ?? [];
3578
+ }
3510
3579
  setAttributes(args) {
3511
3580
  this.logInternal({ internalData: { span_attributes: args } });
3512
3581
  }
@@ -3523,16 +3592,16 @@ var SpanImpl = class _SpanImpl {
3523
3592
  });
3524
3593
  const partialRecord = deepCopyEvent({
3525
3594
  id: this.id,
3526
- span_id: this.spanId,
3527
- root_span_id: this.rootSpanId,
3528
- span_parents: this.spanParents,
3595
+ span_id: this._spanId,
3596
+ root_span_id: this._rootSpanId,
3597
+ span_parents: this._spanParents,
3529
3598
  ...serializableInternalData,
3530
3599
  [import_core.IS_MERGE_FIELD]: this.isMerge
3531
3600
  });
3532
3601
  if (partialRecord.metrics?.end) {
3533
3602
  this.loggedEndTime = partialRecord.metrics?.end;
3534
3603
  }
3535
- if ((partialRecord.tags ?? []).length > 0 && this.spanParents?.length) {
3604
+ if ((partialRecord.tags ?? []).length > 0 && this._spanParents?.length) {
3536
3605
  throw new Error("Tags can only be logged to the root span");
3537
3606
  }
3538
3607
  const computeRecord = async () => ({
@@ -3577,7 +3646,7 @@ var SpanImpl = class _SpanImpl {
3577
3646
  );
3578
3647
  }
3579
3648
  startSpan(args) {
3580
- const parentSpanIds = args?.parent ? void 0 : { spanId: this.spanId, rootSpanId: this.rootSpanId };
3649
+ const parentSpanIds = args?.parent ? void 0 : { spanId: this._spanId, rootSpanId: this._rootSpanId };
3581
3650
  return new _SpanImpl({
3582
3651
  state: this.state,
3583
3652
  ...args,
@@ -3607,10 +3676,10 @@ var SpanImpl = class _SpanImpl {
3607
3676
  async export() {
3608
3677
  return new import_core.SpanComponentsV3({
3609
3678
  object_type: this.parentObjectType,
3610
- ...this.parentComputeObjectMetadataArgs && !this.parentObjectId.hasComputed ? { compute_object_metadata_args: this.parentComputeObjectMetadataArgs } : { object_id: await this.parentObjectId.get() },
3679
+ ...this.parentComputeObjectMetadataArgs && !this.parentObjectId.hasSucceeded ? { compute_object_metadata_args: this.parentComputeObjectMetadataArgs } : { object_id: await this.parentObjectId.get() },
3611
3680
  row_id: this.id,
3612
- span_id: this.spanId,
3613
- root_span_id: this.rootSpanId,
3681
+ span_id: this._spanId,
3682
+ root_span_id: this._rootSpanId,
3614
3683
  propagated_event: this.propagatedEvent
3615
3684
  }).toStr();
3616
3685
  }
@@ -3657,7 +3726,7 @@ function splitLoggingData({
3657
3726
  return [serializableInternalData, lazyInternalData];
3658
3727
  }
3659
3728
  var Dataset = class extends ObjectFetcher {
3660
- constructor(state, lazyMetadata, pinnedVersion, legacy) {
3729
+ constructor(state, lazyMetadata, pinnedVersion, legacy, _internal_btql) {
3661
3730
  const isLegacyDataset = legacy ?? import_core.DEFAULT_IS_LEGACY_DATASET;
3662
3731
  if (isLegacyDataset) {
3663
3732
  console.warn(
@@ -3667,13 +3736,15 @@ var Dataset = class extends ObjectFetcher {
3667
3736
  super(
3668
3737
  "dataset",
3669
3738
  pinnedVersion,
3670
- (r) => (0, import_core.ensureDatasetRecord)(enrichAttachments(r), isLegacyDataset)
3739
+ (r) => (0, import_core.ensureDatasetRecord)(enrichAttachments(r), isLegacyDataset),
3740
+ _internal_btql
3671
3741
  );
3672
3742
  this.state = state;
3673
3743
  this.lazyMetadata = lazyMetadata;
3674
3744
  }
3675
3745
  lazyMetadata;
3676
3746
  __braintrust_dataset_marker = true;
3747
+ newRecords = 0;
3677
3748
  get id() {
3678
3749
  return (async () => {
3679
3750
  return (await this.lazyMetadata.get()).dataset.id;
@@ -3781,6 +3852,7 @@ var Dataset = class extends ObjectFetcher {
3781
3852
  })
3782
3853
  );
3783
3854
  this.state.bgLogger().log([args]);
3855
+ this.newRecords++;
3784
3856
  return rowId;
3785
3857
  }
3786
3858
  /**
@@ -3843,15 +3915,23 @@ var Dataset = class extends ObjectFetcher {
3843
3915
  const datasetUrl = `${projectUrl}/datasets/${encodeURIComponent(
3844
3916
  await this.name
3845
3917
  )}`;
3846
- let dataSummary = void 0;
3918
+ let dataSummary;
3847
3919
  if (summarizeData) {
3848
- dataSummary = await state.apiConn().get_json(
3849
- "dataset-summary",
3850
- {
3851
- dataset_id: await this.id
3852
- },
3853
- 3
3920
+ const rawDataSummary = import_zod2.z.object({
3921
+ total_records: import_zod2.z.number()
3922
+ }).parse(
3923
+ await state.apiConn().get_json(
3924
+ "dataset-summary",
3925
+ {
3926
+ dataset_id: await this.id
3927
+ },
3928
+ 3
3929
+ )
3854
3930
  );
3931
+ dataSummary = {
3932
+ newRecords: this.newRecords,
3933
+ totalRecords: rawDataSummary.total_records
3934
+ };
3855
3935
  }
3856
3936
  return {
3857
3937
  projectName: (await this.project).name,
@@ -3919,6 +3999,65 @@ function renderMessage(render, message) {
3919
3999
  } : {}
3920
4000
  };
3921
4001
  }
4002
+ function deserializePlainStringAsJSON(s) {
4003
+ if (s.trim() === "") {
4004
+ return { value: null, error: void 0 };
4005
+ }
4006
+ try {
4007
+ return { value: JSON.parse(s), error: void 0 };
4008
+ } catch (e) {
4009
+ return { value: s, error: e };
4010
+ }
4011
+ }
4012
+ function renderTemplatedObject(obj, args) {
4013
+ if (typeof obj === "string") {
4014
+ return import_mustache.default.render(obj, args, void 0, {
4015
+ escape: (value) => {
4016
+ if (typeof value === "string") {
4017
+ return value;
4018
+ } else {
4019
+ return JSON.stringify(value);
4020
+ }
4021
+ }
4022
+ });
4023
+ } else if ((0, import_core.isArray)(obj)) {
4024
+ return obj.map((item) => renderTemplatedObject(item, args));
4025
+ } else if ((0, import_core.isObject)(obj)) {
4026
+ return Object.fromEntries(
4027
+ Object.entries(obj).map(([key, value]) => [
4028
+ key,
4029
+ renderTemplatedObject(value, args)
4030
+ ])
4031
+ );
4032
+ }
4033
+ return obj;
4034
+ }
4035
+ function renderPromptParams(params, args) {
4036
+ const schemaParsed = import_zod2.z.object({
4037
+ response_format: import_zod2.z.object({
4038
+ type: import_zod2.z.literal("json_schema"),
4039
+ json_schema: import_typespecs2.responseFormatJsonSchemaSchema.omit({ schema: true }).extend({
4040
+ schema: import_zod2.z.unknown()
4041
+ })
4042
+ })
4043
+ }).safeParse(params);
4044
+ if (schemaParsed.success) {
4045
+ const rawSchema = schemaParsed.data.response_format.json_schema.schema;
4046
+ const templatedSchema = renderTemplatedObject(rawSchema, args);
4047
+ const parsedSchema = typeof templatedSchema === "string" ? deserializePlainStringAsJSON(templatedSchema).value : templatedSchema;
4048
+ return {
4049
+ ...params,
4050
+ response_format: {
4051
+ ...schemaParsed.data.response_format,
4052
+ json_schema: {
4053
+ ...schemaParsed.data.response_format.json_schema,
4054
+ schema: parsedSchema
4055
+ }
4056
+ }
4057
+ };
4058
+ }
4059
+ return params;
4060
+ }
3922
4061
  var Prompt = class {
3923
4062
  constructor(metadata, defaults, noTrace) {
3924
4063
  this.metadata = metadata;
@@ -4015,7 +4154,7 @@ var Prompt = class {
4015
4154
  ...options.messages ?? []
4016
4155
  ];
4017
4156
  return {
4018
- ...params,
4157
+ ...renderPromptParams(params, variables),
4019
4158
  ...spanInfo,
4020
4159
  messages,
4021
4160
  ...prompt.tools?.trim() ? {
@@ -4034,7 +4173,7 @@ var Prompt = class {
4034
4173
  );
4035
4174
  }
4036
4175
  return {
4037
- ...params,
4176
+ ...renderPromptParams(params, variables),
4038
4177
  ...spanInfo,
4039
4178
  prompt: import_mustache.default.render(prompt.content, variables)
4040
4179
  };
@@ -4116,6 +4255,8 @@ __export(exports_node_exports, {
4116
4255
  currentExperiment: () => currentExperiment,
4117
4256
  currentLogger: () => currentLogger,
4118
4257
  currentSpan: () => currentSpan,
4258
+ defaultErrorScoreHandler: () => defaultErrorScoreHandler,
4259
+ deserializePlainStringAsJSON: () => deserializePlainStringAsJSON,
4119
4260
  devNullWritableStream: () => devNullWritableStream,
4120
4261
  flush: () => flush,
4121
4262
  getSpanParentObject: () => getSpanParentObject,
@@ -4135,6 +4276,7 @@ __export(exports_node_exports, {
4135
4276
  permalink: () => permalink,
4136
4277
  projects: () => projects,
4137
4278
  renderMessage: () => renderMessage,
4279
+ renderPromptParams: () => renderPromptParams,
4138
4280
  reportFailures: () => reportFailures,
4139
4281
  runEvaluator: () => runEvaluator,
4140
4282
  setFetch: () => setFetch,
@@ -5593,6 +5735,15 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters, st
5593
5735
  }
5594
5736
  return winner;
5595
5737
  }
5738
+ var defaultErrorScoreHandler = ({
5739
+ rootSpan,
5740
+ data,
5741
+ unhandledScores
5742
+ }) => {
5743
+ const scores = Object.fromEntries(unhandledScores.map((s) => [s, 0]));
5744
+ rootSpan.log({ scores });
5745
+ return scores;
5746
+ };
5596
5747
  async function runEvaluatorInternal(experiment, evaluator, progressReporter, filters, stream) {
5597
5748
  if (typeof evaluator.data === "string") {
5598
5749
  throw new Error("Unimplemented: string data paths");
@@ -5654,6 +5805,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
5654
5805
  object_type: "dataset",
5655
5806
  object_id: await eventDataset.id,
5656
5807
  id: datum.id,
5808
+ created: datum.created,
5657
5809
  _xact_id: datum._xact_id
5658
5810
  } : void 0,
5659
5811
  ...datum.upsert_id ? { id: datum.upsert_id } : {}
@@ -5667,6 +5819,8 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
5667
5819
  let output = void 0;
5668
5820
  let error2 = void 0;
5669
5821
  const scores = {};
5822
+ const scorerNames = evaluator.scores.map(scorerName);
5823
+ let unhandledScores = scorerNames;
5670
5824
  try {
5671
5825
  const meta = (o) => metadata = { ...metadata, ...o };
5672
5826
  await rootSpan.traced(
@@ -5706,7 +5860,6 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
5706
5860
  metadata,
5707
5861
  output
5708
5862
  };
5709
- const scorerNames = evaluator.scores.map(scorerName);
5710
5863
  const scoreResults = await Promise.all(
5711
5864
  evaluator.scores.map(async (score, score_idx) => {
5712
5865
  try {
@@ -5773,22 +5926,18 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
5773
5926
  }
5774
5927
  })
5775
5928
  );
5776
- const passingScorersAndResults = [];
5777
5929
  const failingScorersAndResults = [];
5778
5930
  scoreResults.forEach((results2, i) => {
5779
5931
  const name = scorerNames[i];
5780
5932
  if (results2.kind === "score") {
5781
5933
  (results2.value || []).forEach((result) => {
5782
- passingScorersAndResults.push({
5783
- name: result.name,
5784
- score: result
5785
- });
5786
5934
  scores[result.name] = result.score;
5787
5935
  });
5788
5936
  } else {
5789
5937
  failingScorersAndResults.push({ name, error: results2.value });
5790
5938
  }
5791
5939
  });
5940
+ unhandledScores = null;
5792
5941
  if (failingScorersAndResults.length) {
5793
5942
  const scorerErrors = Object.fromEntries(
5794
5943
  failingScorersAndResults.map(({ name, error: error3 }) => [
@@ -5797,9 +5946,12 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
5797
5946
  ])
5798
5947
  );
5799
5948
  metadata["scorer_errors"] = scorerErrors;
5800
- rootSpan.log({ metadata: { scorer_errors: scorerErrors } });
5949
+ rootSpan.log({
5950
+ metadata: { scorer_errors: scorerErrors }
5951
+ });
5801
5952
  const names = Object.keys(scorerErrors).join(", ");
5802
5953
  const errors = failingScorersAndResults.map((item) => item.error);
5954
+ unhandledScores = Object.keys(scorerErrors);
5803
5955
  throw new AggregateError(
5804
5956
  errors,
5805
5957
  `Found exceptions for the following scorers: ${names}`
@@ -5817,7 +5969,14 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
5817
5969
  output,
5818
5970
  tags: datum.tags,
5819
5971
  metadata,
5820
- scores,
5972
+ scores: {
5973
+ ...evaluator.errorScoreHandler && unhandledScores ? evaluator.errorScoreHandler({
5974
+ rootSpan,
5975
+ data: datum,
5976
+ unhandledScores
5977
+ }) : void 0,
5978
+ ...scores
5979
+ },
5821
5980
  error: error2
5822
5981
  });
5823
5982
  };
@@ -6780,14 +6939,16 @@ function postProcessPrompt(prompt) {
6780
6939
  {
6781
6940
  role: "assistant",
6782
6941
  content: textPart?.text,
6783
- tool_calls: toolCallParts.map((part) => ({
6784
- id: part.toolCallId,
6785
- function: {
6786
- name: part.toolName,
6787
- arguments: JSON.stringify(part.args)
6788
- },
6789
- type: "function"
6790
- }))
6942
+ ...toolCallParts.length > 0 ? {
6943
+ tool_calls: toolCallParts.map((part) => ({
6944
+ id: part.toolCallId,
6945
+ function: {
6946
+ name: part.toolName,
6947
+ arguments: JSON.stringify(part.args)
6948
+ },
6949
+ type: "function"
6950
+ }))
6951
+ } : {}
6791
6952
  }
6792
6953
  ];
6793
6954
  case "user":
@@ -6875,6 +7036,8 @@ var src_default = exports_node_exports;
6875
7036
  currentExperiment,
6876
7037
  currentLogger,
6877
7038
  currentSpan,
7039
+ defaultErrorScoreHandler,
7040
+ deserializePlainStringAsJSON,
6878
7041
  devNullWritableStream,
6879
7042
  flush,
6880
7043
  getSpanParentObject,
@@ -6894,6 +7057,7 @@ var src_default = exports_node_exports;
6894
7057
  permalink,
6895
7058
  projects,
6896
7059
  renderMessage,
7060
+ renderPromptParams,
6897
7061
  reportFailures,
6898
7062
  runEvaluator,
6899
7063
  setFetch,