ambral 0.5.0 → 0.6.0

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.
Files changed (2) hide show
  1. package/dist/ambral.js +1924 -898
  2. package/package.json +1 -1
package/dist/ambral.js CHANGED
@@ -18582,6 +18582,56 @@ __export(exports_SchemaTransformation, {
18582
18582
  });
18583
18583
 
18584
18584
  // ../../node_modules/.bun/effect@4.0.3/node_modules/effect/dist/BigDecimal.js
18585
+ var exports_BigDecimal = {};
18586
+ __export(exports_BigDecimal, {
18587
+ truncate: () => truncate,
18588
+ toNumberUnsafe: () => toNumberUnsafe,
18589
+ toExponential: () => toExponential,
18590
+ sumAll: () => sumAll,
18591
+ sum: () => sum3,
18592
+ subtract: () => subtract4,
18593
+ sign: () => sign,
18594
+ scale: () => scale,
18595
+ roundTerminal: () => roundTerminal,
18596
+ round: () => round2,
18597
+ remainderUnsafe: () => remainderUnsafe,
18598
+ remainder: () => remainder2,
18599
+ normalize: () => normalize2,
18600
+ negate: () => negate2,
18601
+ multiplyAll: () => multiplyAll,
18602
+ multiply: () => multiply,
18603
+ min: () => min9,
18604
+ max: () => max9,
18605
+ makeNormalizedUnsafe: () => makeNormalizedUnsafe,
18606
+ make: () => make25,
18607
+ isZero: () => isZero2,
18608
+ isPositive: () => isPositive2,
18609
+ isNegative: () => isNegative2,
18610
+ isLessThanOrEqualTo: () => isLessThanOrEqualTo6,
18611
+ isLessThan: () => isLessThan6,
18612
+ isInteger: () => isInteger,
18613
+ isGreaterThanOrEqualTo: () => isGreaterThanOrEqualTo6,
18614
+ isGreaterThan: () => isGreaterThan6,
18615
+ isBigDecimal: () => isBigDecimal,
18616
+ fromStringUnsafe: () => fromStringUnsafe2,
18617
+ fromString: () => fromString2,
18618
+ fromNumberUnsafe: () => fromNumberUnsafe,
18619
+ fromNumber: () => fromNumber2,
18620
+ fromBigInt: () => fromBigInt,
18621
+ format: () => format6,
18622
+ floor: () => floor,
18623
+ equals: () => equals4,
18624
+ divideUnsafe: () => divideUnsafe2,
18625
+ divide: () => divide2,
18626
+ digitAt: () => digitAt,
18627
+ clamp: () => clamp6,
18628
+ ceil: () => ceil,
18629
+ between: () => between5,
18630
+ abs: () => abs2,
18631
+ Order: () => Order6,
18632
+ Equivalence: () => Equivalence6
18633
+ });
18634
+ var DEFAULT_PRECISION = 100;
18585
18635
  var FINITE_INT_REGEXP = /^[+-]?\d+$/;
18586
18636
  var TypeId30 = "~effect/BigDecimal";
18587
18637
  var BigDecimalProto = {
@@ -18625,10 +18675,21 @@ var makeNormalized = (value, scale) => {
18625
18675
  o.normalized = o;
18626
18676
  return o;
18627
18677
  };
18678
+ var makeNormalizedUnsafe = (value, scale) => {
18679
+ if (value !== bigint05 && value % bigint102 === bigint05) {
18680
+ throw new RangeError("Value must be normalized");
18681
+ }
18682
+ return makeNormalized(value, scale);
18683
+ };
18628
18684
  var bigint05 = /* @__PURE__ */ BigInt(0);
18629
18685
  var bigint13 = /* @__PURE__ */ BigInt(1);
18686
+ var bigint_1 = /* @__PURE__ */ BigInt(-1);
18687
+ var bigint22 = /* @__PURE__ */ BigInt(2);
18688
+ var bigint5 = /* @__PURE__ */ BigInt(5);
18689
+ var bigint_5 = /* @__PURE__ */ BigInt(-5);
18630
18690
  var bigint102 = /* @__PURE__ */ BigInt(10);
18631
18691
  var zero3 = /* @__PURE__ */ makeNormalized(bigint05, 0);
18692
+ var one = /* @__PURE__ */ makeNormalizedUnsafe(bigint13, 0);
18632
18693
  var normalize2 = (self) => {
18633
18694
  if (self.normalized === undefined) {
18634
18695
  if (self.value === bigint05) {
@@ -18643,6 +18704,128 @@ var normalize2 = (self) => {
18643
18704
  }
18644
18705
  return self.normalized;
18645
18706
  };
18707
+ var scale = /* @__PURE__ */ dual(2, (self, scale2) => {
18708
+ if (scale2 > self.scale) {
18709
+ return make25(self.value * bigint102 ** BigInt(scale2 - self.scale), scale2);
18710
+ }
18711
+ if (scale2 < self.scale) {
18712
+ return make25(self.value / bigint102 ** BigInt(self.scale - scale2), scale2);
18713
+ }
18714
+ return self;
18715
+ });
18716
+ var sum3 = /* @__PURE__ */ dual(2, (self, that) => {
18717
+ if (that.value === bigint05) {
18718
+ return self;
18719
+ }
18720
+ if (self.value === bigint05) {
18721
+ return that;
18722
+ }
18723
+ if (self.scale > that.scale) {
18724
+ return make25(scale(that, self.scale).value + self.value, self.scale);
18725
+ }
18726
+ if (self.scale < that.scale) {
18727
+ return make25(scale(self, that.scale).value + that.value, that.scale);
18728
+ }
18729
+ return make25(self.value + that.value, self.scale);
18730
+ });
18731
+ var sumAll = (collection) => {
18732
+ let out = zero3;
18733
+ for (const n of collection) {
18734
+ out = sum3(out, n);
18735
+ }
18736
+ return out;
18737
+ };
18738
+ var multiply = /* @__PURE__ */ dual(2, (self, that) => {
18739
+ if (that.value === bigint05 || self.value === bigint05) {
18740
+ return zero3;
18741
+ }
18742
+ return make25(self.value * that.value, self.scale + that.scale);
18743
+ });
18744
+ var multiplyAll = (collection) => {
18745
+ let out = one;
18746
+ for (const n of collection) {
18747
+ if (n.value === bigint05) {
18748
+ return zero3;
18749
+ }
18750
+ out = multiply(out, n);
18751
+ }
18752
+ return out;
18753
+ };
18754
+ var subtract4 = /* @__PURE__ */ dual(2, (self, that) => {
18755
+ if (that.value === bigint05) {
18756
+ return self;
18757
+ }
18758
+ if (self.value === bigint05) {
18759
+ return make25(-that.value, that.scale);
18760
+ }
18761
+ if (self.scale > that.scale) {
18762
+ return make25(self.value - scale(that, self.scale).value, self.scale);
18763
+ }
18764
+ if (self.scale < that.scale) {
18765
+ return make25(scale(self, that.scale).value - that.value, that.scale);
18766
+ }
18767
+ return make25(self.value - that.value, self.scale);
18768
+ });
18769
+ var divideWithPrecision = (num, den, scale2, precision) => {
18770
+ const numNegative = num < bigint05;
18771
+ const denNegative = den < bigint05;
18772
+ const negateResult = numNegative !== denNegative;
18773
+ num = numNegative ? -num : num;
18774
+ den = denNegative ? -den : den;
18775
+ while (num < den) {
18776
+ num *= bigint102;
18777
+ scale2++;
18778
+ }
18779
+ let quotient = num / den;
18780
+ let remainder2 = num % den;
18781
+ if (remainder2 === bigint05) {
18782
+ return make25(negateResult ? -quotient : quotient, scale2);
18783
+ }
18784
+ let count = `${quotient}`.length;
18785
+ remainder2 *= bigint102;
18786
+ while (remainder2 !== bigint05 && count < precision) {
18787
+ const q = remainder2 / den;
18788
+ const r = remainder2 % den;
18789
+ quotient = quotient * bigint102 + q;
18790
+ remainder2 = r * bigint102;
18791
+ count++;
18792
+ scale2++;
18793
+ }
18794
+ if (remainder2 !== bigint05) {
18795
+ quotient += roundTerminal(remainder2 / den);
18796
+ }
18797
+ return make25(negateResult ? -quotient : quotient, scale2);
18798
+ };
18799
+ var roundTerminal = (n) => {
18800
+ const pos = n >= bigint05 ? 0 : 1;
18801
+ return Number(`${n}`[pos]) < 5 ? bigint05 : bigint13;
18802
+ };
18803
+ var divide2 = /* @__PURE__ */ dual(2, (self, that) => {
18804
+ if (that.value === bigint05) {
18805
+ return none2();
18806
+ }
18807
+ if (self.value === bigint05) {
18808
+ return some3(zero3);
18809
+ }
18810
+ const scale2 = self.scale - that.scale;
18811
+ if (self.value === that.value) {
18812
+ return some3(make25(bigint13, scale2));
18813
+ }
18814
+ return some3(divideWithPrecision(self.value, that.value, scale2, DEFAULT_PRECISION));
18815
+ });
18816
+ var divideUnsafe2 = /* @__PURE__ */ dual(2, (self, that) => {
18817
+ if (that.value === bigint05) {
18818
+ throw new RangeError("Division by zero");
18819
+ }
18820
+ if (self.value === bigint05) {
18821
+ return zero3;
18822
+ }
18823
+ const scale2 = self.scale - that.scale;
18824
+ if (self.value === that.value) {
18825
+ return make25(bigint13, scale2);
18826
+ }
18827
+ return divideWithPrecision(self.value, that.value, scale2, DEFAULT_PRECISION);
18828
+ });
18646
18829
  var MAX_COMPARISON_SCALE_ALIGNMENT = 100;
18647
18830
  var comparisonPowersOfTen = [bigint13];
18648
18831
  var compareBigInt = (self, that) => self === that ? 0 : self < that ? -1 : 1;
@@ -18673,7 +18856,48 @@ var compare = (self, that) => {
18673
18856
  return scaleDifference > 0 ? compareBigInt(self.value, that.value * powerOfTen) : compareBigInt(self.value * powerOfTen, that.value);
18674
18857
  };
18675
18858
  var Order6 = /* @__PURE__ */ make4(compare);
18859
+ var isLessThan6 = /* @__PURE__ */ isLessThan(Order6);
18860
+ var isLessThanOrEqualTo6 = /* @__PURE__ */ isLessThanOrEqualTo(Order6);
18861
+ var isGreaterThan6 = /* @__PURE__ */ isGreaterThan(Order6);
18862
+ var isGreaterThanOrEqualTo6 = /* @__PURE__ */ isGreaterThanOrEqualTo(Order6);
18863
+ var between5 = /* @__PURE__ */ isBetween(Order6);
18864
+ var clamp6 = /* @__PURE__ */ clamp(Order6);
18865
+ var min9 = /* @__PURE__ */ min2(Order6);
18866
+ var max9 = /* @__PURE__ */ max2(Order6);
18676
18867
  var sign = (n) => n.value === bigint05 ? 0 : n.value < bigint05 ? -1 : 1;
18868
+ var abs2 = (n) => n.value < bigint05 ? make25(-n.value, n.scale) : n;
18869
+ var negate2 = (n) => make25(-n.value, n.scale);
18870
+ var remainder2 = /* @__PURE__ */ dual(2, (self, divisor) => {
18871
+ if (divisor.value === bigint05) {
18872
+ return none2();
18873
+ }
18874
+ const max10 = Math.max(self.scale, divisor.scale);
18875
+ return some3(make25(scale(self, max10).value % scale(divisor, max10).value, max10));
18876
+ });
18877
+ var remainderUnsafe = /* @__PURE__ */ dual(2, (self, divisor) => {
18878
+ if (divisor.value === bigint05) {
18879
+ throw new RangeError("Division by zero");
18880
+ }
18881
+ const max10 = Math.max(self.scale, divisor.scale);
18882
+ return make25(scale(self, max10).value % scale(divisor, max10).value, max10);
18883
+ });
18884
+ var Equivalence6 = /* @__PURE__ */ make3((self, that) => compare(self, that) === 0);
18885
+ var equals4 = /* @__PURE__ */ dual(2, (self, that) => Equivalence6(self, that));
18886
+ var fromBigInt = (n) => make25(n, 0);
18887
+ var fromNumberUnsafe = (n) => {
18888
+ return getOrThrowWith(fromNumber2(n), () => new RangeError(`Number must be finite, got ${n}`));
18889
+ };
18890
+ var fromNumber2 = (n) => {
18891
+ if (!Number.isFinite(n)) {
18892
+ return none2();
18893
+ }
18894
+ const string2 = `${n}`;
18895
+ if (string2.includes("e")) {
18896
+ return fromString2(string2);
18897
+ }
18898
+ const [lead, trail = ""] = string2.split(".");
18899
+ return some3(make25(BigInt(`${lead}${trail}`), trail.length));
18900
+ };
18677
18901
  var fromString2 = (s) => {
18678
18902
  if (s === "") {
18679
18903
  return some3(zero3);
@@ -18707,11 +18931,14 @@ var fromString2 = (s) => {
18707
18931
  if (!FINITE_INT_REGEXP.test(digits)) {
18708
18932
  return none2();
18709
18933
  }
18710
- const scale = offset - exp;
18711
- if (!Number.isSafeInteger(scale)) {
18934
+ const scale2 = offset - exp;
18935
+ if (!Number.isSafeInteger(scale2)) {
18712
18936
  return none2();
18713
18937
  }
18714
- return some3(make25(BigInt(digits), scale));
18938
+ return some3(make25(BigInt(digits), scale2));
18939
+ };
18940
+ var fromStringUnsafe2 = (s) => {
18941
+ return getOrThrowWith(fromString2(s), () => new Error(`Invalid numerical string: ${s}`));
18715
18942
  };
18716
18943
  var format6 = (n) => {
18717
18944
  const normalized = normalize2(n);
@@ -18737,7 +18964,70 @@ var toExponential = (n) => {
18737
18964
  const exp = tail2.length - normalized.scale;
18738
18965
  return `${head4}${tail2 === "" ? "" : `.${tail2}`}e${exp >= 0 ? "+" : ""}${exp}`;
18739
18966
  };
18967
+ var toNumberUnsafe = (n) => Number(format6(n));
18968
+ var isInteger = (n) => normalize2(n).scale <= 0;
18740
18969
  var isZero2 = (n) => n.value === bigint05;
18970
+ var isNegative2 = (n) => n.value < bigint05;
18971
+ var isPositive2 = (n) => n.value > bigint05;
18972
+ var isBigDecimalArgs = (args2) => isBigDecimal(args2[0]);
18973
+ var round2 = /* @__PURE__ */ dual(isBigDecimalArgs, (self, options) => {
18974
+ const mode = options?.mode ?? "half-from-zero";
18975
+ const scale2 = options?.scale ?? 0;
18976
+ switch (mode) {
18977
+ case "ceil":
18978
+ return ceil(self, scale2);
18979
+ case "floor":
18980
+ return floor(self, scale2);
18981
+ case "to-zero":
18982
+ return truncate(self, scale2);
18983
+ case "from-zero":
18984
+ return isPositive2(self) ? ceil(self, scale2) : floor(self, scale2);
18985
+ case "half-ceil":
18986
+ return floor(sum3(self, make25(bigint5, scale2 + 1)), scale2);
18987
+ case "half-floor":
18988
+ return ceil(sum3(self, make25(bigint_5, scale2 + 1)), scale2);
18989
+ case "half-to-zero":
18990
+ return isNegative2(self) ? floor(sum3(self, make25(bigint5, scale2 + 1)), scale2) : ceil(sum3(self, make25(bigint_5, scale2 + 1)), scale2);
18991
+ case "half-from-zero":
18992
+ return isNegative2(self) ? ceil(sum3(self, make25(bigint_5, scale2 + 1)), scale2) : floor(sum3(self, make25(bigint5, scale2 + 1)), scale2);
18993
+ }
18994
+ const halfCeil = floor(sum3(self, make25(bigint5, scale2 + 1)), scale2);
18995
+ const halfFloor = ceil(sum3(self, make25(bigint_5, scale2 + 1)), scale2);
18996
+ const digit = digitAt(halfCeil, scale2);
18997
+ switch (mode) {
18998
+ case "half-even":
18999
+ return equals4(halfCeil, halfFloor) ? halfCeil : digit % bigint22 === bigint05 ? halfCeil : halfFloor;
19000
+ case "half-odd":
19001
+ return equals4(halfCeil, halfFloor) ? halfCeil : digit % bigint22 === bigint05 ? halfFloor : halfCeil;
19002
+ }
19003
+ });
19004
+ var truncate = /* @__PURE__ */ dual(isBigDecimalArgs, (self, scale2 = 0) => {
19005
+ if (self.scale <= scale2) {
19006
+ return self;
19007
+ }
19008
+ return make25(self.value / bigint102 ** BigInt(self.scale - scale2), scale2);
19009
+ });
19010
+ var ceil = /* @__PURE__ */ dual(isBigDecimalArgs, (self, scale2 = 0) => {
19011
+ const truncated = truncate(self, scale2);
19012
+ if (isPositive2(self) && isLessThan6(truncated, self)) {
19013
+ return sum3(truncated, make25(bigint13, scale2));
19014
+ }
19015
+ return truncated;
19016
+ });
19017
+ var digitAt = /* @__PURE__ */ dual(2, (self, scale2) => {
19018
+ if (self.scale < scale2) {
19019
+ return bigint05;
19020
+ }
19021
+ const scaled = self.value / bigint102 ** BigInt(self.scale - scale2);
19022
+ return scaled % bigint102;
19023
+ });
19024
+ var floor = /* @__PURE__ */ dual(isBigDecimalArgs, (self, scale2 = 0) => {
19025
+ const truncated = truncate(self, scale2);
19026
+ if (isNegative2(self) && isGreaterThan6(truncated, self)) {
19027
+ return sum3(truncated, make25(bigint_1, scale2));
19028
+ }
19029
+ return truncated;
19030
+ });
18741
19031
 
18742
19032
  // ../../node_modules/.bun/effect@4.0.3/node_modules/effect/dist/SchemaTransformation.js
18743
19033
  var Middleware = class extends Class {
@@ -21731,9 +22021,9 @@ var make29 = /* @__PURE__ */ gen4(function* () {
21731
22021
  if (additionalFds.length === 0) {
21732
22022
  return stdio;
21733
22023
  }
21734
- const maxFd = additionalFds.reduce((max9, {
22024
+ const maxFd = additionalFds.reduce((max10, {
21735
22025
  fd
21736
- }) => Math.max(max9, fd), 2);
22026
+ }) => Math.max(max10, fd), 2);
21737
22027
  for (let i = 3;i <= maxFd; i++) {
21738
22028
  stdio[i] = "ignore";
21739
22029
  }
@@ -22227,12 +22517,12 @@ var make30 = (impl) => {
22227
22517
  random: sync3(() => nextDoubleUnsafe()),
22228
22518
  randomBoolean: sync3(() => nextDoubleUnsafe() > 0.5),
22229
22519
  randomInt: sync3(() => nextIntUnsafe()),
22230
- randomBetween: (min9, max9) => sync3(() => nextBetween(min9, max9, nextDoubleUnsafe())),
22231
- randomIntBetween(min9, max9, options) {
22520
+ randomBetween: (min10, max10) => sync3(() => nextBetween(min10, max10, nextDoubleUnsafe())),
22521
+ randomIntBetween(min10, max10, options) {
22232
22522
  const extra = options?.halfOpen === true ? 0 : 1;
22233
22523
  return sync3(() => {
22234
- const minInt = Math.ceil(min9);
22235
- const maxInt = Math.floor(max9);
22524
+ const minInt = Math.ceil(min10);
22525
+ const maxInt = Math.floor(max10);
22236
22526
  return Math.floor(nextDoubleUnsafe() * (maxInt - minInt + extra)) + minInt;
22237
22527
  });
22238
22528
  },
@@ -22671,7 +22961,7 @@ var symlink2 = /* @__PURE__ */ (() => {
22671
22961
  const nodeSymlink = /* @__PURE__ */ effectify(NFS.symlink, /* @__PURE__ */ handleErrnoException("FileSystem", "symlink"), /* @__PURE__ */ handleBadArgument("symlink"));
22672
22962
  return (target, path) => nodeSymlink(target, path);
22673
22963
  })();
22674
- var truncate2 = /* @__PURE__ */ (() => {
22964
+ var truncate3 = /* @__PURE__ */ (() => {
22675
22965
  const nodeTruncate = /* @__PURE__ */ effectify(NFS.truncate, /* @__PURE__ */ handleErrnoException("FileSystem", "truncate"), /* @__PURE__ */ handleBadArgument("truncate"));
22676
22966
  return (path, length2) => nodeTruncate(path, length2);
22677
22967
  })();
@@ -22763,7 +23053,7 @@ var makeFileSystem = /* @__PURE__ */ map9(/* @__PURE__ */ serviceOption2(WatchBa
22763
23053
  rename: rename2,
22764
23054
  stat: stat2,
22765
23055
  symlink: symlink2,
22766
- truncate: truncate2,
23056
+ truncate: truncate3,
22767
23057
  utimes: utimes2,
22768
23058
  watch(path, options) {
22769
23059
  return watch2(backend, path, options);
@@ -22973,22 +23263,22 @@ __export(exports_Schema, {
22973
23263
  isLessThanOrEqualToDate: () => isLessThanOrEqualToDate,
22974
23264
  isLessThanOrEqualToBigInt: () => isLessThanOrEqualToBigInt,
22975
23265
  isLessThanOrEqualToBigDecimal: () => isLessThanOrEqualToBigDecimal,
22976
- isLessThanOrEqualTo: () => isLessThanOrEqualTo6,
23266
+ isLessThanOrEqualTo: () => isLessThanOrEqualTo7,
22977
23267
  isLessThanDate: () => isLessThanDate,
22978
23268
  isLessThanBigInt: () => isLessThanBigInt,
22979
23269
  isLessThanBigDecimal: () => isLessThanBigDecimal,
22980
- isLessThan: () => isLessThan6,
23270
+ isLessThan: () => isLessThan7,
22981
23271
  isInt32: () => isInt32,
22982
23272
  isInt: () => isInt,
22983
23273
  isIncluding: () => isIncluding,
22984
23274
  isGreaterThanOrEqualToDate: () => isGreaterThanOrEqualToDate,
22985
23275
  isGreaterThanOrEqualToBigInt: () => isGreaterThanOrEqualToBigInt,
22986
23276
  isGreaterThanOrEqualToBigDecimal: () => isGreaterThanOrEqualToBigDecimal,
22987
- isGreaterThanOrEqualTo: () => isGreaterThanOrEqualTo6,
23277
+ isGreaterThanOrEqualTo: () => isGreaterThanOrEqualTo7,
22988
23278
  isGreaterThanDate: () => isGreaterThanDate,
22989
23279
  isGreaterThanBigInt: () => isGreaterThanBigInt,
22990
23280
  isGreaterThanBigDecimal: () => isGreaterThanBigDecimal,
22991
- isGreaterThan: () => isGreaterThan6,
23281
+ isGreaterThan: () => isGreaterThan7,
22992
23282
  isGUID: () => isGUID,
22993
23283
  isFinite: () => isFinite3,
22994
23284
  isEndingWith: () => isEndingWith,
@@ -24407,7 +24697,7 @@ __export(exports_Headers, {
24407
24697
  fromInput: () => fromInput3,
24408
24698
  empty: () => empty13,
24409
24699
  TypeId: () => TypeId38,
24410
- Equivalence: () => Equivalence6,
24700
+ Equivalence: () => Equivalence7,
24411
24701
  CurrentRedactedNames: () => CurrentRedactedNames
24412
24702
  });
24413
24703
 
@@ -24474,7 +24764,7 @@ var Proto7 = /* @__PURE__ */ Object.defineProperties(/* @__PURE__ */ Object.crea
24474
24764
  },
24475
24765
  [symbol2]: {
24476
24766
  value(that) {
24477
- return Equivalence6(this, that);
24767
+ return Equivalence7(this, that);
24478
24768
  }
24479
24769
  },
24480
24770
  [symbol]: {
@@ -24490,7 +24780,7 @@ var Proto7 = /* @__PURE__ */ Object.defineProperties(/* @__PURE__ */ Object.crea
24490
24780
  }
24491
24781
  });
24492
24782
  var make36 = (input) => Object.assign(Object.create(Proto7), input);
24493
- var Equivalence6 = /* @__PURE__ */ makeEquivalence4(/* @__PURE__ */ strictEqual());
24783
+ var Equivalence7 = /* @__PURE__ */ makeEquivalence4(/* @__PURE__ */ strictEqual());
24494
24784
  var empty13 = /* @__PURE__ */ Object.create(Proto7);
24495
24785
  var fromInput3 = (input) => {
24496
24786
  if (input === undefined) {
@@ -24601,7 +24891,7 @@ var Proto8 = {
24601
24891
  };
24602
24892
  },
24603
24893
  [symbol2](that) {
24604
- return Equivalence7(this, that);
24894
+ return Equivalence8(this, that);
24605
24895
  },
24606
24896
  [symbol]() {
24607
24897
  return array(this.params.flat());
@@ -24649,7 +24939,7 @@ var fromInputNested = (input) => {
24649
24939
  }
24650
24940
  return out;
24651
24941
  };
24652
- var Equivalence7 = /* @__PURE__ */ make3((a, b) => arrayEquivalence(a.params, b.params));
24942
+ var Equivalence8 = /* @__PURE__ */ make3((a, b) => arrayEquivalence(a.params, b.params));
24653
24943
  var arrayEquivalence = /* @__PURE__ */ makeEquivalence5(/* @__PURE__ */ makeEquivalence3([/* @__PURE__ */ strictEqual(), /* @__PURE__ */ strictEqual()]));
24654
24944
  var empty14 = /* @__PURE__ */ make37([]);
24655
24945
  var getFirst = /* @__PURE__ */ dual(2, (self, key) => findFirst3(self.params, ([k]) => k === key).pipe(map(([, value3]) => value3)));
@@ -28533,10 +28823,10 @@ var addressError = (input, message) => fail2(new NetAddressError({
28533
28823
  input,
28534
28824
  message
28535
28825
  }));
28536
- var allIntegersInRange = (values3, max9) => {
28826
+ var allIntegersInRange = (values3, max10) => {
28537
28827
  for (let i = 0;i < values3.length; i++) {
28538
28828
  const n = values3[i];
28539
- if (!Number.isInteger(n) || n < 0 || n > max9)
28829
+ if (!Number.isInteger(n) || n < 0 || n > max10)
28540
28830
  return false;
28541
28831
  }
28542
28832
  return true;
@@ -29223,9 +29513,9 @@ var interfaceError = (input, message) => fail2(new NetAddressError({
29223
29513
  message
29224
29514
  }));
29225
29515
  var make42 = (address, prefixLength) => {
29226
- const max9 = width(address);
29227
- if (!Number.isInteger(prefixLength) || prefixLength < 0 || prefixLength > max9) {
29228
- return interfaceError(address, `prefix length must be an integer from 0 through ${max9}`);
29516
+ const max10 = width(address);
29517
+ if (!Number.isInteger(prefixLength) || prefixLength < 0 || prefixLength > max10) {
29518
+ return interfaceError(address, `prefix length must be an integer from 0 through ${max10}`);
29229
29519
  }
29230
29520
  const self = Object.assign(Object.create(IpInterfaceProto), {
29231
29521
  address,
@@ -29721,11 +30011,11 @@ var NonEmptyArray = /* @__PURE__ */ lambda((schema) => make44(new Arrays(false,
29721
30011
  function ArrayEnsure(schema) {
29722
30012
  const many = ArraySchema(schema);
29723
30013
  const to = ArraySchema(toType2(schema));
29724
- const one = decodeTo2(Tuple4([Unknown2]), transform2({
30014
+ const one2 = decodeTo2(Tuple4([Unknown2]), transform2({
29725
30015
  decode: (value3) => [value3],
29726
30016
  encode: ([value3]) => value3
29727
30017
  }))(schema);
29728
- return make44(Union2([one, many]).pipe(decodeTo2(to)).ast, {
30018
+ return make44(Union2([one2, many]).pipe(decodeTo2(to)).ast, {
29729
30019
  from: Union2([schema, many]),
29730
30020
  to
29731
30021
  });
@@ -30449,7 +30739,7 @@ function encodeNumberPayload(number3) {
30449
30739
  }
30450
30740
  return number3;
30451
30741
  }
30452
- var isGreaterThan6 = /* @__PURE__ */ makeIsGreaterThan({
30742
+ var isGreaterThan7 = /* @__PURE__ */ makeIsGreaterThan({
30453
30743
  order: Number3,
30454
30744
  annotate: (exclusiveMinimum) => ({
30455
30745
  representation: {
@@ -30466,7 +30756,7 @@ var isGreaterThan6 = /* @__PURE__ */ makeIsGreaterThan({
30466
30756
  })
30467
30757
  })
30468
30758
  });
30469
- var isGreaterThanOrEqualTo6 = /* @__PURE__ */ makeIsGreaterThanOrEqualTo({
30759
+ var isGreaterThanOrEqualTo7 = /* @__PURE__ */ makeIsGreaterThanOrEqualTo({
30470
30760
  order: Number3,
30471
30761
  annotate: (minimum) => ({
30472
30762
  representation: {
@@ -30483,7 +30773,7 @@ var isGreaterThanOrEqualTo6 = /* @__PURE__ */ makeIsGreaterThanOrEqualTo({
30483
30773
  })
30484
30774
  })
30485
30775
  });
30486
- var isLessThan6 = /* @__PURE__ */ makeIsLessThan({
30776
+ var isLessThan7 = /* @__PURE__ */ makeIsLessThan({
30487
30777
  order: Number3,
30488
30778
  annotate: (exclusiveMaximum) => ({
30489
30779
  representation: {
@@ -30500,7 +30790,7 @@ var isLessThan6 = /* @__PURE__ */ makeIsLessThan({
30500
30790
  })
30501
30791
  })
30502
30792
  });
30503
- var isLessThanOrEqualTo6 = /* @__PURE__ */ makeIsLessThanOrEqualTo({
30793
+ var isLessThanOrEqualTo7 = /* @__PURE__ */ makeIsLessThanOrEqualTo({
30504
30794
  order: Number3,
30505
30795
  annotate: (maximum) => ({
30506
30796
  representation: {
@@ -30591,7 +30881,7 @@ function isInt(annotations2) {
30591
30881
  });
30592
30882
  }
30593
30883
  var Int = /* @__PURE__ */ Number7.check(/* @__PURE__ */ isInt());
30594
- var Natural = /* @__PURE__ */ Int.check(/* @__PURE__ */ isGreaterThanOrEqualTo6(0));
30884
+ var Natural = /* @__PURE__ */ Int.check(/* @__PURE__ */ isGreaterThanOrEqualTo7(0));
30595
30885
  function isInt32(annotations2) {
30596
30886
  return new FilterGroup([isInt(), isBetween2({
30597
30887
  minimum: -2147483648,
@@ -32744,7 +33034,7 @@ var Headers = /* @__PURE__ */ declare(isHeaders, {
32744
33034
  importDeclarations: [`import * as Headers from "effect/http/Headers"`]
32745
33035
  }),
32746
33036
  expected: "Headers",
32747
- toEquivalence: () => Equivalence6,
33037
+ toEquivalence: () => Equivalence7,
32748
33038
  toCodec: () => link3()(Record3(String7, String7), transform2({
32749
33039
  decode: fromInput3,
32750
33040
  encode: (headers) => ({
@@ -32763,7 +33053,7 @@ var UrlParams = /* @__PURE__ */ declare(isUrlParams, {
32763
33053
  importDeclarations: [`import * as UrlParams from "effect/http/UrlParams"`]
32764
33054
  }),
32765
33055
  expected: "UrlParams",
32766
- toEquivalence: () => Equivalence7,
33056
+ toEquivalence: () => Equivalence8,
32767
33057
  toCodec: () => link3()(ArraySchema(Tuple4([String7, String7])), transform2({
32768
33058
  decode: make37,
32769
33059
  encode: (self) => self.params
@@ -34157,12 +34447,12 @@ var randomWith = (f) => withFiber2((fiber3) => succeed6(f(fiber3.getRef(Random2)
34157
34447
  var next2 = /* @__PURE__ */ randomWith((r) => r.nextDoubleUnsafe());
34158
34448
  var nextBoolean = /* @__PURE__ */ randomWith((r) => r.nextDoubleUnsafe() > 0.5);
34159
34449
  var nextInt = /* @__PURE__ */ randomWith((r) => r.nextIntUnsafe());
34160
- var nextBetween2 = (min9, max9) => randomWith((r) => nextBetween(min9, max9, r.nextDoubleUnsafe()));
34161
- var nextIntBetween = (min9, max9, options) => {
34450
+ var nextBetween2 = (min10, max10) => randomWith((r) => nextBetween(min10, max10, r.nextDoubleUnsafe()));
34451
+ var nextIntBetween = (min10, max10, options) => {
34162
34452
  const extra = options?.halfOpen === true ? 0 : 1;
34163
34453
  return randomWith((r) => {
34164
- const minInt = Math.ceil(min9);
34165
- const maxInt = Math.floor(max9);
34454
+ const minInt = Math.ceil(min10);
34455
+ const maxInt = Math.floor(max10);
34166
34456
  return Math.floor(r.nextDoubleUnsafe() * (maxInt - minInt + extra)) + minInt;
34167
34457
  });
34168
34458
  };
@@ -40071,7 +40361,7 @@ __export(exports_Argument, {
40071
40361
  map: () => map18,
40072
40362
  filterMap: () => filterMap9,
40073
40363
  filter: () => filter13,
40074
- between: () => between6,
40364
+ between: () => between7,
40075
40365
  atMost: () => atMost2,
40076
40366
  atLeast: () => atLeast2,
40077
40367
  String: () => String13,
@@ -43233,12 +43523,12 @@ var handleToggleProcess = (input, state) => {
43233
43523
  }
43234
43524
  };
43235
43525
  var entriesToDisplay = (cursor, total, maxVisible) => {
43236
- const max9 = maxVisible === undefined ? total : maxVisible;
43237
- let startIndex = Math.min(total - max9, cursor - Math.floor(max9 / 2));
43526
+ const max10 = maxVisible === undefined ? total : maxVisible;
43527
+ let startIndex = Math.min(total - max10, cursor - Math.floor(max10 / 2));
43238
43528
  if (startIndex < 0) {
43239
43529
  startIndex = 0;
43240
43530
  }
43241
- const endIndex = Math.min(startIndex + max9, total);
43531
+ const endIndex = Math.min(startIndex + max10, total);
43242
43532
  return {
43243
43533
  startIndex,
43244
43534
  endIndex
@@ -43459,32 +43749,32 @@ var variadic = (self, options3) => {
43459
43749
  parse: parse7
43460
43750
  });
43461
43751
  };
43462
- var between5 = /* @__PURE__ */ dual(3, (self, min9, max9) => {
43463
- if (min9 < 0) {
43752
+ var between6 = /* @__PURE__ */ dual(3, (self, min10, max10) => {
43753
+ if (min10 < 0) {
43464
43754
  throw new Error("between: min must be non-negative");
43465
43755
  }
43466
- if (max9 < min9) {
43756
+ if (max10 < min10) {
43467
43757
  throw new Error("between: max must be greater than or equal to min");
43468
43758
  }
43469
43759
  return variadic(self, {
43470
- min: min9,
43471
- max: max9
43760
+ min: min10,
43761
+ max: max10
43472
43762
  });
43473
43763
  });
43474
- var atMost = /* @__PURE__ */ dual(2, (self, max9) => {
43475
- if (max9 < 0) {
43764
+ var atMost = /* @__PURE__ */ dual(2, (self, max10) => {
43765
+ if (max10 < 0) {
43476
43766
  throw new Error("atMost: max must be non-negative");
43477
43767
  }
43478
43768
  return variadic(self, {
43479
- max: max9
43769
+ max: max10
43480
43770
  });
43481
43771
  });
43482
- var atLeast = /* @__PURE__ */ dual(2, (self, min9) => {
43483
- if (min9 < 0) {
43772
+ var atLeast = /* @__PURE__ */ dual(2, (self, min10) => {
43773
+ if (min10 < 0) {
43484
43774
  throw new Error("atLeast: min must be non-negative");
43485
43775
  }
43486
43776
  return variadic(self, {
43487
- min: min9
43777
+ min: min10
43488
43778
  });
43489
43779
  });
43490
43780
  var filterMap8 = /* @__PURE__ */ dual(3, (self, filter12, onNone) => mapEffect4(self, fnUntraced2(function* (a) {
@@ -43705,9 +43995,9 @@ var variadic2 = /* @__PURE__ */ dual((args2) => isParam(args2[0]), (self, option
43705
43995
  var map18 = /* @__PURE__ */ dual(2, (self, f) => map17(self, f));
43706
43996
  var mapEffect5 = /* @__PURE__ */ dual(2, (self, f) => mapEffect4(self, f));
43707
43997
  var mapTryCatch2 = /* @__PURE__ */ dual(3, (self, f, onError5) => mapTryCatch(self, f, onError5));
43708
- var atLeast2 = /* @__PURE__ */ dual(2, (self, min9) => atLeast(self, min9));
43709
- var atMost2 = /* @__PURE__ */ dual(2, (self, max9) => atMost(self, max9));
43710
- var between6 = /* @__PURE__ */ dual(3, (self, min9, max9) => between5(self, min9, max9));
43998
+ var atLeast2 = /* @__PURE__ */ dual(2, (self, min10) => atLeast(self, min10));
43999
+ var atMost2 = /* @__PURE__ */ dual(2, (self, max10) => atMost(self, max10));
44000
+ var between7 = /* @__PURE__ */ dual(3, (self, min10, max10) => between6(self, min10, max10));
43711
44001
  var withSchema2 = /* @__PURE__ */ dual(2, (self, schema2) => withSchema(self, schema2));
43712
44002
  var ChoiceWithValue2 = (name, choices) => ChoiceWithValue(argumentKind, name, choices);
43713
44003
  var withMetavar2 = /* @__PURE__ */ dual(2, (self, metavar) => withMetavar(self, metavar));
@@ -44909,7 +45199,7 @@ __export(exports_Flag, {
44909
45199
  map: () => map19,
44910
45200
  filterMap: () => filterMap10,
44911
45201
  filter: () => filter14,
44912
- between: () => between7,
45202
+ between: () => between8,
44913
45203
  atMost: () => atMost3,
44914
45204
  atLeast: () => atLeast3,
44915
45205
  String: () => String14,
@@ -44956,9 +45246,9 @@ var withFallbackPrompt3 = /* @__PURE__ */ dual(2, (self, prompt) => withFallback
44956
45246
  var map19 = /* @__PURE__ */ dual(2, (self, f) => map17(self, f));
44957
45247
  var mapEffect6 = /* @__PURE__ */ dual(2, (self, f) => mapEffect4(self, f));
44958
45248
  var mapTryCatch3 = /* @__PURE__ */ dual(3, (self, f, onError5) => mapTryCatch(self, f, onError5));
44959
- var atLeast3 = /* @__PURE__ */ dual(2, (self, min9) => atLeast(self, min9));
44960
- var atMost3 = /* @__PURE__ */ dual(2, (self, max9) => atMost(self, max9));
44961
- var between7 = /* @__PURE__ */ dual(3, (self, min9, max9) => between5(self, min9, max9));
45249
+ var atLeast3 = /* @__PURE__ */ dual(2, (self, min10) => atLeast(self, min10));
45250
+ var atMost3 = /* @__PURE__ */ dual(2, (self, max10) => atMost(self, max10));
45251
+ var between8 = /* @__PURE__ */ dual(3, (self, min10, max10) => between6(self, min10, max10));
44962
45252
  var filterMap10 = /* @__PURE__ */ dual(3, (self, f, onNone) => filterMap8(self, f, onNone));
44963
45253
  var filter14 = /* @__PURE__ */ dual(3, (self, predicate, onFalse) => filter12(self, predicate, onFalse));
44964
45254
  var orElse8 = /* @__PURE__ */ dual(2, (self, that) => orElse6(self, that));
@@ -45103,7 +45393,7 @@ var makeCommand = (options3) => {
45103
45393
  name: single.name,
45104
45394
  type: single.typeName ?? getTypeName(single.primitiveType),
45105
45395
  description: single.description,
45106
- required: !metadata.isOptional && (!metadata.isVariadic || exists(metadata.variadicMin, (min9) => min9 > 0)),
45396
+ required: !metadata.isOptional && (!metadata.isVariadic || exists(metadata.variadicMin, (min10) => min10 > 0)),
45107
45397
  variadic: metadata.isVariadic
45108
45398
  });
45109
45399
  }
@@ -45919,17 +46209,17 @@ var consumeFlagValueWithTokens = (cursor, token, spec, negated = false) => {
45919
46209
  };
45920
46210
  var consumeKnownFlags = (tokens, registry) => {
45921
46211
  const flagMap = createEmptyFlagMap(registry.params);
45922
- const remainder2 = [];
46212
+ const remainder3 = [];
45923
46213
  const errors = [];
45924
46214
  const cursor = makeCursor(tokens);
45925
46215
  for (let t = cursor.take();t; t = cursor.take()) {
45926
46216
  if (!isFlagToken(t)) {
45927
- remainder2.push(t);
46217
+ remainder3.push(t);
45928
46218
  continue;
45929
46219
  }
45930
46220
  const resolved = resolveFlag(t, registry);
45931
46221
  if (!resolved) {
45932
- remainder2.push(t);
46222
+ remainder3.push(t);
45933
46223
  continue;
45934
46224
  }
45935
46225
  const consumed = consumeFlagValue(cursor, t, resolved.param, resolved.negated);
@@ -45943,7 +46233,7 @@ var consumeKnownFlags = (tokens, registry) => {
45943
46233
  }
45944
46234
  return {
45945
46235
  flagMap,
45946
- remainder: remainder2,
46236
+ remainder: remainder3,
45947
46237
  errors
45948
46238
  };
45949
46239
  };
@@ -45966,10 +46256,10 @@ var resolveFromRegistries = (token, registries) => {
45966
46256
  }
45967
46257
  return;
45968
46258
  };
45969
- var preserveFlag = (remainder2, cursor, token, resolved) => {
45970
- remainder2.push(token);
46259
+ var preserveFlag = (remainder3, cursor, token, resolved) => {
46260
+ remainder3.push(token);
45971
46261
  const consumed = consumeFlagValueWithTokens(cursor, token, resolved.param, resolved.negated);
45972
- remainder2.push(...consumed.tokens);
46262
+ remainder3.push(...consumed.tokens);
45973
46263
  };
45974
46264
  var localFlagWouldPrecedeSubcommand = (token, remainingTokens, resolved, subIndex, registries) => {
45975
46265
  const cursor = makeCursor(remainingTokens);
@@ -45996,25 +46286,25 @@ var consumeGlobalFlags = (tokens, command, registry) => {
45996
46286
  const inheritedRegistry = createFlagRegistry(extractContextFlagParams(command2));
45997
46287
  const subIndex = buildSubcommandIndex(command2.subcommands);
45998
46288
  const cursor = makeCursor(tokens2);
45999
- const remainder2 = [];
46289
+ const remainder3 = [];
46000
46290
  let awaitingFirstValue = true;
46001
46291
  for (let token = cursor.take();token; token = cursor.take()) {
46002
46292
  if (isFlagToken(token)) {
46003
46293
  const ignored = resolveFromRegistries(token, ignoredRegistries);
46004
46294
  if (ignored !== undefined) {
46005
- preserveFlag(remainder2, cursor, token, ignored);
46295
+ preserveFlag(remainder3, cursor, token, ignored);
46006
46296
  continue;
46007
46297
  }
46008
46298
  const inherited = resolveFlag(token, inheritedRegistry);
46009
46299
  if (inherited !== undefined) {
46010
- preserveFlag(remainder2, cursor, token, inherited);
46300
+ preserveFlag(remainder3, cursor, token, inherited);
46011
46301
  continue;
46012
46302
  }
46013
46303
  const local = resolveFlag(token, localRegistry);
46014
46304
  const global = resolveFlag(token, registry);
46015
46305
  if (local !== undefined) {
46016
46306
  if (global === undefined || !awaitingFirstValue || !localFlagWouldPrecedeSubcommand(token, cursor.rest(), local, subIndex, [localRegistry, inheritedRegistry, registry])) {
46017
- preserveFlag(remainder2, cursor, token, local);
46307
+ preserveFlag(remainder3, cursor, token, local);
46018
46308
  continue;
46019
46309
  }
46020
46310
  }
@@ -46029,21 +46319,21 @@ var consumeGlobalFlags = (tokens, command, registry) => {
46029
46319
  }
46030
46320
  continue;
46031
46321
  }
46032
- remainder2.push(token);
46322
+ remainder3.push(token);
46033
46323
  continue;
46034
46324
  }
46035
46325
  if (token._tag === "Value" && awaitingFirstValue) {
46036
46326
  const sub = subIndex.get(token.value);
46037
46327
  if (sub !== undefined) {
46038
- remainder2.push(token);
46039
- remainder2.push(...consumeLevel(cursor.rest(), sub, [...ignoredRegistries, inheritedRegistry]));
46040
- return remainder2;
46328
+ remainder3.push(token);
46329
+ remainder3.push(...consumeLevel(cursor.rest(), sub, [...ignoredRegistries, inheritedRegistry]));
46330
+ return remainder3;
46041
46331
  }
46042
46332
  awaitingFirstValue = false;
46043
46333
  }
46044
- remainder2.push(token);
46334
+ remainder3.push(token);
46045
46335
  }
46046
- return remainder2;
46336
+ return remainder3;
46047
46337
  };
46048
46338
  return {
46049
46339
  flagMap,
@@ -46685,7 +46975,7 @@ var runWith2 = (command, config) => {
46685
46975
  const globalRegistry = createFlagRegistry(allFlagParams.filter(isFlagParam));
46686
46976
  const {
46687
46977
  flagMap,
46688
- remainder: remainder2,
46978
+ remainder: remainder3,
46689
46979
  errors: globalFlagErrors
46690
46980
  } = consumeGlobalFlags(tokens, command, globalRegistry);
46691
46981
  const emptyArgs = {
@@ -46693,7 +46983,7 @@ var runWith2 = (command, config) => {
46693
46983
  arguments: []
46694
46984
  };
46695
46985
  const parsedArgs = yield* parseArgs({
46696
- tokens: remainder2,
46986
+ tokens: remainder3,
46697
46987
  trailingOperands
46698
46988
  }, command);
46699
46989
  const commandPath = [command.name, ...getCommandPath(parsedArgs)];
@@ -46785,7 +47075,7 @@ var runWith2 = (command, config) => {
46785
47075
  // package.json
46786
47076
  var package_default = {
46787
47077
  name: "ambral",
46788
- version: "0.5.0",
47078
+ version: "0.6.0",
46789
47079
  license: "UNLICENSED",
46790
47080
  type: "module",
46791
47081
  description: "The `ambral` command: signs in through the browser, then calls the platform API as that person.",
@@ -50214,9 +50504,9 @@ var read2 = exports_Effect.fnUntraced(function* (schema2, org) {
50214
50504
  // ../core/src/Org/OrgAccess.ts
50215
50505
  var Slug = exports_Schema.NonEmptyString.pipe(exports_Schema.brand("OrgSlug")).annotate({ identifier: "OrgSlug" });
50216
50506
  var Name = exports_Schema.NonEmptyString.pipe(exports_Schema.brand("OrgName")).annotate({ identifier: "OrgName" });
50217
- var State3 = exports_Schema.Literals(["pending", "active", "suspended"]).annotate({ identifier: "OrgAccessState" });
50507
+ var State3 = exports_Schema.Literals(["active", "suspended"]).annotate({ identifier: "OrgAccessState" });
50218
50508
  var fields = {
50219
- access: State3.pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed("pending")))
50509
+ access: State3.pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed("active")))
50220
50510
  };
50221
50511
  var Fields = exports_Schema.Struct(fields);
50222
50512
 
@@ -50333,7 +50623,7 @@ class Unauthorized extends exports_Schema.TaggedError()("Unauthorized", {}, {
50333
50623
  }
50334
50624
 
50335
50625
  class OrgNotEnabled extends exports_Schema.TaggedError()("OrgNotEnabled", {
50336
- state: State3.pick(["pending", "suspended"])
50626
+ state: State3.pick(["suspended"])
50337
50627
  }, { httpApiStatus: 403 }) {
50338
50628
  }
50339
50629
 
@@ -51001,7 +51291,7 @@ var isRelease = (version) => version.pre === undefined;
51001
51291
  var header = "ambral-cli-version";
51002
51292
  var minimumHeader = "ambral-cli-minimum";
51003
51293
  var Version4 = exports_Schema.String.check(exports_Schema.makeFilter((version) => exports_Option.isSome(parse7(version)) || "a semantic version")).pipe(exports_Schema.brand("CliVersion")).annotate({ identifier: "CliVersion" });
51004
- var minimum = undefined;
51294
+ var minimum = Version4.make("0.6.0");
51005
51295
 
51006
51296
  class Outdated extends exports_Schema.TaggedError()("CliOutdated", {
51007
51297
  minimum: Version4
@@ -51033,10 +51323,10 @@ var exports_ApiKey = {};
51033
51323
  __export(exports_ApiKey, {
51034
51324
  unavailable: () => unavailable3,
51035
51325
  unauthorized: () => unauthorized,
51326
+ sync: () => sync7,
51036
51327
  suspend: () => suspend7,
51037
51328
  start: () => start2,
51038
51329
  revoke: () => revoke,
51039
- retrySyncs: () => retrySyncs,
51040
51330
  prefix: () => prefix4,
51041
51331
  list: () => list6,
51042
51332
  issue: () => issue,
@@ -51052,20 +51342,16 @@ __export(exports_ApiKey, {
51052
51342
  Summary: () => Summary3,
51053
51343
  Start: () => Start,
51054
51344
  START_LENGTH: () => START_LENGTH,
51055
- RetryError: () => RetryError,
51056
51345
  Plaintext: () => Plaintext2,
51057
51346
  NotFound: () => NotFound7,
51058
51347
  Name: () => Name3,
51059
51348
  NAME_MAX_LENGTH: () => NAME_MAX_LENGTH,
51060
- LIVE_PASS: () => LIVE_PASS,
51061
51349
  Kind: () => Kind,
51062
51350
  KEY_LENGTH: () => KEY_LENGTH,
51063
51351
  InferenceEntry: () => InferenceEntry,
51064
51352
  Hash: () => Hash2,
51065
- GRACE: () => GRACE,
51066
51353
  Created: () => Created3,
51067
- CreateInput: () => CreateInput2,
51068
- BATCH: () => BATCH
51354
+ CreateInput: () => CreateInput2
51069
51355
  });
51070
51356
 
51071
51357
  // ../../node_modules/.bun/@noble+hashes@2.4.0/node_modules/@noble/hashes/_u64.js
@@ -51138,9 +51424,9 @@ function aexists(instance, checkFinished = true) {
51138
51424
  }
51139
51425
  function aoutput(out, instance) {
51140
51426
  abytes(out, undefined, "output");
51141
- const min9 = instance.outputLen;
51142
- if (!(out.length >= min9)) {
51143
- throw new RangeError('"output" expected length >= ' + min9);
51427
+ const min10 = instance.outputLen;
51428
+ if (!(out.length >= min10)) {
51429
+ throw new RangeError('"output" expected length >= ' + min10);
51144
51430
  }
51145
51431
  }
51146
51432
  function u32(arr) {
@@ -51476,373 +51762,179 @@ class _SHA256 extends SHA2_32B {
51476
51762
  }
51477
51763
  }
51478
51764
  var sha256 = /* @__PURE__ */ createHasher(() => new _SHA256, /* @__PURE__ */ oidNist(1));
51479
- // ../../node_modules/.bun/effect@4.0.3/node_modules/effect/dist/persistence/KeyValueStore.js
51480
- var exports_KeyValueStore = {};
51481
- __export(exports_KeyValueStore, {
51482
- toSchemaStore: () => toSchemaStore,
51483
- prefix: () => prefix3,
51484
- makeStringOnly: () => makeStringOnly,
51485
- make: () => make69,
51486
- layerStorage: () => layerStorage,
51487
- layerSql: () => layerSql,
51488
- layerMemory: () => layerMemory,
51489
- layerFileSystem: () => layerFileSystem,
51490
- KeyValueStoreError: () => KeyValueStoreError,
51491
- KeyValueStore: () => KeyValueStore
51492
- });
51493
- var TypeId74 = "~effect/persistence/KeyValueStore";
51494
- var ErrorTypeId = "~effect/persistence/KeyValueStore/KeyValueStoreError";
51765
+ // ../core/src/internal/uuid.ts
51766
+ var uuid = exports_Crypto.Crypto.use((crypto2) => crypto2.randomUUIDv4()).pipe(exports_Effect.orDie);
51495
51767
 
51496
- class KeyValueStoreError extends (/* @__PURE__ */ TaggedError2("KeyValueStoreError")) {
51497
- [ErrorTypeId] = ErrorTypeId;
51498
- }
51499
- var KeyValueStore = /* @__PURE__ */ Service("effect/persistence/KeyValueStore");
51500
- var make69 = (options4) => KeyValueStore.of({
51501
- [TypeId74]: TypeId74,
51502
- has: (key) => map9(options4.get(key), isNotUndefined),
51503
- isEmpty: map9(options4.size, (size8) => size8 === 0),
51504
- modify: (key, f) => flatMap6(options4.get(key), (o) => {
51505
- if (o === undefined) {
51506
- return undefined_2;
51507
- }
51508
- const newValue = f(o);
51509
- return as3(options4.set(key, newValue), newValue);
51510
- }),
51511
- modifyUint8Array: (key, f) => flatMap6(options4.getUint8Array(key), (o) => {
51512
- if (o === undefined) {
51513
- return undefined_2;
51514
- }
51515
- const newValue = f(o);
51516
- return as3(options4.set(key, newValue), newValue);
51517
- }),
51518
- ...options4
51519
- });
51520
- var makeStringOnly = (options4) => {
51521
- const encoder6 = new TextEncoder;
51522
- return make69({
51523
- ...options4,
51524
- getUint8Array: (key) => options4.get(key).pipe(map9(map20((value5) => match2(decode2(value5), {
51525
- onFailure: () => encoder6.encode(value5),
51526
- onSuccess: identity
51527
- })))),
51528
- set: (key, value5) => typeof value5 === "string" ? options4.set(key, value5) : suspend3(() => options4.set(key, encode2(value5)))
51768
+ // ../core/src/Billing/Pricing.ts
51769
+ var Usd = exports_Schema.BigDecimalFromString.check(exports_Schema.isGreaterThanOrEqualToBigDecimal(exports_BigDecimal.fromBigInt(0n))).pipe(exports_Schema.brand("Usd")).annotate({ identifier: "Usd" });
51770
+ var Price = exports_Schema.Struct({
51771
+ inputPerMTok: Usd,
51772
+ outputPerMTok: Usd,
51773
+ cacheReadPerMTok: exports_Schema.optional(Usd),
51774
+ cacheWritePerMTok: exports_Schema.optional(Usd)
51775
+ }).annotate({ identifier: "Price" });
51776
+ var TokenCount = exports_Schema.Int.check(exports_Schema.isGreaterThanOrEqualTo(0)).pipe(exports_Schema.brand("TokenCount")).annotate({
51777
+ identifier: "TokenCount"
51778
+ });
51779
+ var Tokens = exports_Schema.Struct({
51780
+ input: TokenCount,
51781
+ output: TokenCount,
51782
+ cacheRead: TokenCount,
51783
+ cacheWrite: TokenCount
51784
+ }).annotate({ identifier: "Tokens" });
51785
+ var tokenCount = (count2) => TokenCount.make(Math.max(0, count2));
51786
+ var tokensOf = (usage) => {
51787
+ const cacheRead = usage.prompt_tokens_details?.cached_tokens ?? 0;
51788
+ const cacheWrite = usage.prompt_tokens_details?.cache_write_tokens ?? 0;
51789
+ return {
51790
+ input: tokenCount(usage.prompt_tokens - cacheRead - cacheWrite),
51791
+ output: tokenCount(usage.completion_tokens),
51792
+ cacheRead: tokenCount(cacheRead),
51793
+ cacheWrite: tokenCount(cacheWrite)
51794
+ };
51795
+ };
51796
+ var CHARGE_DECIMAL_PLACES = 12;
51797
+ var PER_MILLION_SCALE = 6;
51798
+ var costOf = (count2, perMTok) => exports_BigDecimal.multiply(exports_BigDecimal.fromBigInt(BigInt(count2)), perMTok);
51799
+ var charge = (tokens, price) => {
51800
+ const perMillion = exports_BigDecimal.sum(exports_BigDecimal.sum(costOf(tokens.input, price.inputPerMTok), costOf(tokens.output, price.outputPerMTok)), exports_BigDecimal.sum(costOf(tokens.cacheRead, price.cacheReadPerMTok ?? price.inputPerMTok), costOf(tokens.cacheWrite, price.cacheWritePerMTok ?? price.inputPerMTok)));
51801
+ const total = exports_BigDecimal.make(perMillion.value, perMillion.scale + PER_MILLION_SCALE);
51802
+ return Usd.make(exports_BigDecimal.normalize(exports_BigDecimal.round(total, { scale: CHARGE_DECIMAL_PLACES, mode: "half-from-zero" })));
51803
+ };
51804
+ var PriceId = exports_Schema.NonEmptyString.pipe(exports_Schema.brand("PriceId")).annotate({ identifier: "PriceId" });
51805
+ var Note = exports_Schema.NonEmptyString.pipe(exports_Schema.brand("PriceNote")).annotate({ identifier: "PriceNote" });
51806
+ var Basis = exports_Schema.TaggedUnion({
51807
+ PassThrough: {},
51808
+ Set: { actor: Actor, note: Note }
51809
+ }).annotate({ identifier: "PriceBasis" });
51810
+ var Row = exports_Schema.Struct({
51811
+ id: PriceId,
51812
+ model: ModelId,
51813
+ effectiveAt: EpochMillis,
51814
+ price: Price,
51815
+ listPrice: exports_Schema.optional(Price),
51816
+ basis: Basis
51817
+ }).annotate({ identifier: "PriceRow" });
51818
+ var Decided2 = Row.mapFields(exports_Struct.pick(["price", "listPrice", "basis"]));
51819
+ var samePrice = exports_Schema.toEquivalence(Price);
51820
+ var next3 = (current, listed) => {
51821
+ if (listed === undefined)
51822
+ return exports_Option.none();
51823
+ const passThrough = exports_Option.some({
51824
+ price: listed,
51825
+ listPrice: listed,
51826
+ basis: Basis.cases.PassThrough.make({})
51827
+ });
51828
+ if (current === undefined)
51829
+ return passThrough;
51830
+ return exports_Match.valueTags(current.basis, {
51831
+ PassThrough: () => current.listPrice !== undefined && samePrice(current.listPrice, listed) ? exports_Option.none() : passThrough,
51832
+ Set: () => exports_Option.none()
51529
51833
  });
51530
51834
  };
51531
- var prefix3 = /* @__PURE__ */ dual(2, (self, prefix4) => ({
51532
- ...self,
51533
- get: (key) => self.get(`${prefix4}${key}`),
51534
- getUint8Array: (key) => self.getUint8Array(`${prefix4}${key}`),
51535
- set: (key, value5) => self.set(`${prefix4}${key}`, value5),
51536
- remove: (key) => self.remove(`${prefix4}${key}`),
51537
- has: (key) => self.has(`${prefix4}${key}`),
51538
- modify: (key, f) => self.modify(`${prefix4}${key}`, f),
51539
- modifyUint8Array: (key, f) => self.modifyUint8Array(`${prefix4}${key}`, f)
51835
+ var ListPrice = exports_Schema.Struct({
51836
+ model: ModelId,
51837
+ listPrice: exports_Schema.optional(Price)
51838
+ }).annotate({ identifier: "ModelListPrice" });
51839
+ var Columns = Row.mapFields((fields2) => ({
51840
+ ...fields2,
51841
+ effectiveAt: Timestamp,
51842
+ listPrice: nullAsAbsent(Price)
51540
51843
  }));
51541
- var layerMemory = /* @__PURE__ */ sync2(KeyValueStore)(() => {
51542
- const store = new Map;
51543
- const encoder6 = new TextEncoder;
51544
- return make69({
51545
- get: (key) => sync3(() => {
51546
- const value5 = store.get(key);
51547
- return value5 === undefined ? undefined : typeof value5 === "string" ? value5 : encode2(value5);
51548
- }),
51549
- getUint8Array: (key) => sync3(() => {
51550
- const value5 = store.get(key);
51551
- return value5 === undefined ? undefined : typeof value5 === "string" ? encoder6.encode(value5) : value5;
51552
- }),
51553
- set: (key, value5) => sync3(() => store.set(key, value5)),
51554
- remove: (key) => sync3(() => store.delete(key)),
51555
- clear: sync3(() => store.clear()),
51556
- size: sync3(() => store.size)
51557
- });
51844
+ var encodeWritten = exports_Schema.encodeSync(Row.mapFields((fields2) => ({
51845
+ ...fields2,
51846
+ effectiveAt: Timestamp,
51847
+ price: exports_Schema.fromJsonString(Price),
51848
+ listPrice: nullAsAbsent(exports_Schema.fromJsonString(Price)),
51849
+ basis: exports_Schema.fromJsonString(Basis)
51850
+ })));
51851
+ var selected = (sql) => sql`p.id, p.model_id AS model, p.effective_at AS "effectiveAt", p.price, p.list_price AS "listPrice", p.basis`;
51852
+ var latest = exports_Effect.fn("Pricing.latest")(function* (models) {
51853
+ if (models.length === 0)
51854
+ return new Map;
51855
+ const sql = yield* exports_SqlClient.SqlClient;
51856
+ const rows = yield* exports_SqlSchema.findAll({
51857
+ Request: exports_Schema.Void,
51858
+ Result: Columns,
51859
+ execute: () => sql`
51860
+ SELECT DISTINCT ON (p.model_id) ${selected(sql)}
51861
+ FROM model_prices p
51862
+ WHERE p.model_id IN ${sql.in(models)}
51863
+ ORDER BY p.model_id, p.effective_at DESC, p.seq DESC
51864
+ `
51865
+ })(undefined).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
51866
+ return new Map(rows.map((row) => [row.model, row]));
51558
51867
  });
51559
- var layerFileSystem = (directory) => effect(KeyValueStore)(gen4(function* () {
51560
- const fs = yield* FileSystem;
51561
- const path = yield* Path;
51562
- const withKeyPath = (method, key, f) => key.length === 0 || key === "." || key === ".." ? fail6(new KeyValueStoreError({
51563
- method,
51564
- key,
51565
- message: `Invalid key ${key}`
51566
- })) : f(path.join(directory, encodeURIComponent(key)));
51567
- if (!(yield* fs.exists(directory))) {
51568
- yield* fs.makeDirectory(directory, {
51569
- recursive: true
51570
- });
51571
- }
51572
- return make69({
51573
- get: (key) => withKeyPath("get", key, (path2) => catchTag3(fs.readFileString(path2), "PlatformError", (cause) => cause.reason._tag === "NotFound" ? undefined_2 : fail6(new KeyValueStoreError({
51574
- method: "get",
51575
- key,
51576
- message: `Unable to get item with key ${key}`,
51577
- cause
51578
- })))),
51579
- getUint8Array: (key) => withKeyPath("getUint8Array", key, (path2) => catchTag3(fs.readFile(path2), "PlatformError", (cause) => cause.reason._tag === "NotFound" ? undefined_2 : fail6(new KeyValueStoreError({
51580
- method: "getUint8Array",
51581
- key,
51582
- message: `Unable to get item with key ${key}`,
51583
- cause
51584
- })))),
51585
- set: (key, value5) => withKeyPath("set", key, (path2) => mapError4(typeof value5 === "string" ? fs.writeFileString(path2, value5) : fs.writeFile(path2, value5), (cause) => new KeyValueStoreError({
51586
- method: "set",
51587
- key,
51588
- message: `Unable to set item with key ${key}`,
51589
- cause
51590
- }))),
51591
- remove: (key) => withKeyPath("remove", key, (path2) => mapError4(fs.remove(path2), (cause) => new KeyValueStoreError({
51592
- method: "remove",
51593
- key,
51594
- message: `Unable to remove item with key ${key}`,
51595
- cause
51596
- }))),
51597
- has: (key) => withKeyPath("has", key, (path2) => mapError4(fs.exists(path2), (cause) => new KeyValueStoreError({
51598
- method: "has",
51599
- key,
51600
- message: `Unable to check existence of item with key ${key}`,
51601
- cause
51602
- }))),
51603
- clear: mapError4(andThen4(fs.remove(directory, {
51604
- recursive: true
51605
- }), fs.makeDirectory(directory, {
51606
- recursive: true
51607
- })), (cause) => new KeyValueStoreError({
51608
- method: "clear",
51609
- message: `Unable to clear storage`,
51610
- cause
51611
- })),
51612
- size: matchEffect3(fs.readDirectory(directory), {
51613
- onSuccess: (files) => succeed6(files.length),
51614
- onFailure: (cause) => fail6(new KeyValueStoreError({
51615
- method: "size",
51616
- message: `Unable to get size`,
51617
- cause
51618
- }))
51619
- })
51620
- });
51621
- }));
51622
- var layerSql = (options4 = {}) => effect(KeyValueStore)(gen4(function* () {
51623
- const sql = (yield* SqlClient).withoutTransforms();
51624
- const table2 = sql(options4.table ?? "effect_key_value_store");
51625
- yield* sql.onDialectOrElse({
51626
- mysql: () => sql`
51627
- CREATE TABLE IF NOT EXISTS ${table2} (
51628
- id VARCHAR(191) PRIMARY KEY,
51629
- value BLOB NOT NULL,
51630
- value_type SMALLINT NOT NULL
51631
- )
51632
- `,
51633
- pg: () => sql`
51634
- CREATE TABLE IF NOT EXISTS ${table2} (
51635
- id TEXT PRIMARY KEY,
51636
- value BYTEA NOT NULL,
51637
- value_type SMALLINT NOT NULL
51638
- )
51639
- `,
51640
- mssql: () => sql`
51641
- IF NOT EXISTS (SELECT * FROM sysobjects WHERE name=${table2} AND xtype='U')
51642
- CREATE TABLE ${table2} (
51643
- id NVARCHAR(450) PRIMARY KEY,
51644
- value VARBINARY(MAX) NOT NULL,
51645
- value_type SMALLINT NOT NULL
51646
- )
51647
- `,
51648
- orElse: () => sql`
51649
- CREATE TABLE IF NOT EXISTS ${table2} (
51650
- id TEXT PRIMARY KEY,
51651
- value BLOB NOT NULL,
51652
- value_type INTEGER NOT NULL
51653
- )
51868
+ var Called = exports_Schema.Struct({ model: ModelId, at: EpochMillis });
51869
+ var encodeCalls = exports_Schema.encodeSync(exports_Schema.fromJsonString(exports_Schema.Array(Called)));
51870
+ var InEffect = Columns.mapFields((fields2) => ({ ...fields2, index: exports_Schema.Int }));
51871
+ var inEffect = exports_Effect.fn("Pricing.inEffect")(function* (calls) {
51872
+ if (calls.length === 0)
51873
+ return [];
51874
+ const sql = yield* exports_SqlClient.SqlClient;
51875
+ const found = yield* exports_SqlSchema.findAll({
51876
+ Request: exports_Schema.Void,
51877
+ Result: InEffect,
51878
+ execute: () => sql`
51879
+ SELECT (c.n - 1)::int AS index, ${selected(sql)}
51880
+ FROM jsonb_array_elements(${encodeCalls(calls)}::jsonb) WITH ORDINALITY AS c(call, n)
51881
+ JOIN LATERAL (
51882
+ SELECT * FROM model_prices
51883
+ WHERE model_id = c.call ->> 'model'
51884
+ AND effective_at <= 'epoch'::timestamptz + (c.call ->> 'at')::bigint * interval '1 millisecond'
51885
+ ORDER BY effective_at DESC, seq DESC
51886
+ LIMIT 1
51887
+ ) p ON true
51654
51888
  `
51655
- }).pipe(orDie3);
51656
- const upsert = sql.onDialectOrElse({
51657
- pg: () => (entry) => sql`
51658
- INSERT INTO ${table2} (id, value, value_type) VALUES (${entry.id}, ${entry.value}, ${entry.value_type})
51659
- ON CONFLICT (id) DO UPDATE SET value=EXCLUDED.value, value_type=EXCLUDED.value_type
51660
- `.unprepared,
51661
- mysql: () => (entry) => sql`
51662
- INSERT INTO ${table2} (id, value, value_type) VALUES (${entry.id}, ${entry.value}, ${entry.value_type})
51663
- ON DUPLICATE KEY UPDATE value=VALUES(value), value_type=VALUES(value_type)
51664
- `,
51665
- mssql: () => (entry) => sql`
51666
- MERGE ${table2} AS target
51667
- USING (SELECT ${entry.id} AS id, ${entry.value} AS value, ${entry.value_type} AS value_type) AS source
51668
- ON target.id = source.id
51669
- WHEN MATCHED THEN UPDATE SET value = source.value, value_type = source.value_type
51670
- WHEN NOT MATCHED THEN INSERT (id, value, value_type)
51671
- VALUES (source.id, source.value, source.value_type);
51672
- `,
51673
- orElse: () => (entry) => sql`
51674
- INSERT INTO ${table2} (id, value, value_type) VALUES (${entry.id}, ${entry.value}, ${entry.value_type})
51675
- ON CONFLICT(id) DO UPDATE SET value=excluded.value, value_type=excluded.value_type
51676
- `.unprepared
51677
- });
51678
- const encoder6 = new TextEncoder;
51679
- const decoder4 = new TextDecoder;
51680
- const ValueTypeString = 0;
51681
- const ValueTypeUint8Array = 1;
51682
- return make69({
51683
- get: (key) => sql`SELECT value, value_type FROM ${table2} WHERE id = ${key}`.pipe(mapError4((cause) => new KeyValueStoreError({
51684
- method: "get",
51685
- key,
51686
- message: `Unable to get item with key ${key}`,
51687
- cause
51688
- })), flatMap6((rows) => {
51689
- if (rows.length === 0) {
51690
- return undefined_2;
51691
- }
51692
- const row = rows[0];
51693
- switch (row.value_type) {
51694
- case ValueTypeString:
51695
- return succeed6(decoder4.decode(row.value));
51696
- case ValueTypeUint8Array:
51697
- return succeed6(encode2(row.value));
51698
- default:
51699
- return fail6(new KeyValueStoreError({
51700
- method: "get",
51701
- key,
51702
- message: `Invalid stored value type for key ${key}: ${row.value_type}`
51703
- }));
51704
- }
51705
- })),
51706
- getUint8Array: (key) => sql`SELECT value, value_type FROM ${table2} WHERE id = ${key}`.pipe(mapError4((cause) => new KeyValueStoreError({
51707
- method: "getUint8Array",
51708
- key,
51709
- message: `Unable to get item with key ${key}`,
51710
- cause
51711
- })), flatMap6((rows) => {
51712
- if (rows.length === 0) {
51713
- return undefined_2;
51714
- }
51715
- const row = rows[0];
51716
- switch (row.value_type) {
51717
- case ValueTypeString:
51718
- return succeed6(row.value);
51719
- case ValueTypeUint8Array:
51720
- return succeed6(row.value);
51721
- default:
51722
- return fail6(new KeyValueStoreError({
51723
- method: "getUint8Array",
51724
- key,
51725
- message: `Invalid stored value type for key ${key}: ${row.value_type}`
51726
- }));
51727
- }
51728
- })),
51729
- set: (key, value5) => upsert({
51730
- id: key,
51731
- value: typeof value5 === "string" ? encoder6.encode(value5) : value5,
51732
- value_type: typeof value5 === "string" ? ValueTypeString : ValueTypeUint8Array
51733
- }).pipe(mapError4((cause) => new KeyValueStoreError({
51734
- method: "set",
51735
- key,
51736
- message: `Unable to set item with key ${key}`,
51737
- cause
51738
- })), asVoid4),
51739
- remove: (key) => sql`DELETE FROM ${table2} WHERE id = ${key}`.pipe(mapError4((cause) => new KeyValueStoreError({
51740
- method: "remove",
51741
- key,
51742
- message: `Unable to remove item with key ${key}`,
51743
- cause
51744
- })), asVoid4),
51745
- clear: sql`DELETE FROM ${table2}`.pipe(mapError4((cause) => new KeyValueStoreError({
51746
- method: "clear",
51747
- message: `Unable to clear storage`,
51748
- cause
51749
- })), asVoid4),
51750
- size: sql`SELECT COUNT(*) as count FROM ${table2}`.pipe(mapError4((cause) => new KeyValueStoreError({
51751
- method: "size",
51752
- message: `Unable to get size`,
51753
- cause
51754
- })), map9((rows) => rows.length === 0 ? 0 : Number(rows[0].count)))
51755
- });
51756
- }));
51757
- var SchemaStoreTypeId = "~effect/persistence/KeyValueStore/SchemaStore";
51758
- var toSchemaStore = (self, schema2) => {
51759
- const serializer = toCodecJson2(schema2);
51760
- const jsonSchema2 = fromJsonString2(serializer);
51761
- const decode7 = decodeEffect2(jsonSchema2);
51762
- const encode6 = encodeEffect2(jsonSchema2);
51763
- const get18 = (key) => flatMap6(self.get(key), match10({
51764
- onUndefined: () => succeedNone3,
51765
- onDefined: (value5) => asSome2(decode7(value5))
51766
- }));
51767
- const set9 = (key, value5) => flatMap6(encode6(value5), (json3) => self.set(key, json3));
51768
- const modify6 = (key, f) => flatMap6(get18(key), (o) => {
51769
- if (isNone2(o)) {
51770
- return succeedNone3;
51771
- }
51772
- const newValue = f(o.value);
51773
- return as3(set9(key, newValue), some3(newValue));
51774
- });
51775
- return {
51776
- [SchemaStoreTypeId]: SchemaStoreTypeId,
51777
- get: get18,
51778
- set: set9,
51779
- modify: modify6,
51780
- remove: self.remove,
51781
- clear: self.clear,
51782
- size: self.size,
51783
- has: self.has,
51784
- isEmpty: self.isEmpty
51785
- };
51786
- };
51787
- var layerStorage = (evaluate2) => sync2(KeyValueStore)(() => {
51788
- const storage = evaluate2();
51789
- return makeStringOnly({
51790
- get: (key) => try_3({
51791
- try: () => storage.getItem(key) ?? undefined,
51792
- catch: (cause) => new KeyValueStoreError({
51793
- key,
51794
- method: "get",
51795
- message: `Unable to get item with key ${key}`,
51796
- cause
51797
- })
51798
- }),
51799
- set: (key, value5) => try_3({
51800
- try: () => storage.setItem(key, value5),
51801
- catch: (cause) => new KeyValueStoreError({
51802
- key,
51803
- method: "set",
51804
- message: `Unable to set item with key ${key}`,
51805
- cause
51806
- })
51807
- }),
51808
- remove: (key) => try_3({
51809
- try: () => storage.removeItem(key),
51810
- catch: (cause) => new KeyValueStoreError({
51811
- key,
51812
- method: "remove",
51813
- message: `Unable to remove item with key ${key}`,
51814
- cause
51815
- })
51816
- }),
51817
- clear: try_3({
51818
- try: () => storage.clear(),
51819
- catch: (cause) => new KeyValueStoreError({
51820
- method: "clear",
51821
- message: `Unable to clear storage`,
51822
- cause
51823
- })
51824
- }),
51825
- size: try_3({
51826
- try: () => storage.length,
51827
- catch: (cause) => new KeyValueStoreError({
51828
- method: "size",
51829
- message: `Unable to get size`,
51830
- cause
51831
- })
51832
- })
51889
+ })(undefined).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
51890
+ const byIndex = new Map(found.map(({ index: index2, ...row }) => [index2, row]));
51891
+ return calls.map((_, index2) => byIndex.get(index2));
51892
+ });
51893
+ var chargeAt = (tokens, row) => row === undefined || tokens === undefined ? Usd.make(exports_BigDecimal.fromBigInt(0n)) : charge(tokens, row.price);
51894
+ var chargesOf = exports_Effect.fn("Pricing.chargesOf")(function* (calls) {
51895
+ const metered = calls.flatMap((call) => call === undefined ? [] : [call]);
51896
+ const rows = yield* inEffect(metered.map(({ model, at }) => ({ model, at })));
51897
+ const charges = new Map(metered.map((call, index2) => [call, chargeAt(call.tokens, rows[index2])]));
51898
+ return calls.map((call) => call === undefined ? undefined : charges.get(call));
51899
+ });
51900
+ var withCharge = (call, charged) => charged === undefined || call.usage == null ? call : { ...call, usage: { ...call.usage, cost: exports_BigDecimal.toNumberUnsafe(charged) } };
51901
+ var listed = exports_Effect.fn("Pricing.listed")(function* (at, listings) {
51902
+ const current = yield* latest(listings.map(({ model }) => model));
51903
+ const decided = listings.flatMap(({ model, listPrice }) => exports_Option.toArray(exports_Option.map(next3(current.get(model), listPrice), (terms) => ({ model, terms }))));
51904
+ const rows = yield* exports_Effect.forEach(decided, ({ model, terms }) => exports_Effect.map(uuid, (id2) => ({ id: PriceId.make(id2), model, effectiveAt: at, ...terms })));
51905
+ yield* append4(rows);
51906
+ return rows;
51907
+ });
51908
+ var append4 = exports_Effect.fnUntraced(function* (rows) {
51909
+ if (rows.length === 0)
51910
+ return;
51911
+ const sql = yield* exports_SqlClient.SqlClient;
51912
+ const encoded = rows.map((row) => {
51913
+ const written = encodeWritten(row);
51914
+ return {
51915
+ id: written.id,
51916
+ model_id: written.model,
51917
+ effective_at: written.effectiveAt,
51918
+ price: written.price,
51919
+ list_price: written.listPrice,
51920
+ basis: written.basis
51921
+ };
51833
51922
  });
51923
+ yield* sql`INSERT INTO model_prices ${sql.insert(encoded)}`;
51834
51924
  });
51835
- // ../core/src/internal/uuid.ts
51836
- var uuid = exports_Crypto.Crypto.use((crypto2) => crypto2.randomUUIDv4()).pipe(exports_Effect.orDie);
51837
51925
 
51838
51926
  // ../core/src/Org/OrgBilling.ts
51839
- var BillTo = exports_Schema.Literals(["org", "ambral"]).annotate({ identifier: "OrgBillTo" });
51927
+ var BillTo = exports_Schema.Literals(["byok", "credits", "ambral"]).annotate({ identifier: "OrgBillTo" });
51840
51928
  var fields2 = {
51841
- billTo: BillTo.pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed("org")))
51929
+ billTo: BillTo.pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed("credits"))),
51930
+ allowance: Usd.pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed("0")))
51842
51931
  };
51843
51932
  var Fields2 = exports_Schema.Struct(fields2);
51844
51933
  var billTo = exports_Effect.fn("OrgBilling.billTo")(function* (org) {
51845
- return (yield* read2(Fields2, org)).billTo;
51934
+ return (yield* get18(org)).billTo;
51935
+ });
51936
+ var get18 = exports_Effect.fn("OrgBilling.get")(function* (org) {
51937
+ return yield* read2(Fields2, org);
51846
51938
  });
51847
51939
 
51848
51940
  // ../core/src/Org/OrgSettings.ts
@@ -51855,7 +51947,10 @@ var SetAccess = exports_Schema.TaggedStruct("SetAccess", { state: State3 }).anno
51855
51947
  var SetBillTo = exports_Schema.TaggedStruct("SetBillTo", { billTo: BillTo }).annotate({
51856
51948
  identifier: "SetBillTo"
51857
51949
  });
51858
- var Change = exports_Schema.Union([SetAccess, SetBillTo]).annotate({ identifier: "OrgChange" });
51950
+ var SetAllowance = exports_Schema.TaggedStruct("SetAllowance", { allowance: Usd }).annotate({
51951
+ identifier: "SetAllowance"
51952
+ });
51953
+ var Change = exports_Schema.Union([SetAccess, SetBillTo, SetAllowance]).annotate({ identifier: "OrgChange" });
51859
51954
  var Changed = exports_Schema.Struct({
51860
51955
  org: OrgId,
51861
51956
  change: Change,
@@ -51866,13 +51961,14 @@ var Changed = exports_Schema.Struct({
51866
51961
  }).annotate({ identifier: "OrgChanged" });
51867
51962
  var apply2 = (settings, change) => exports_Match.valueTags(change, {
51868
51963
  SetAccess: ({ state: state2 }) => ({ ...settings, access: state2 }),
51869
- SetBillTo: ({ billTo: billTo2 }) => ({ ...settings, billTo: billTo2 })
51964
+ SetBillTo: ({ billTo: billTo2 }) => ({ ...settings, billTo: billTo2 }),
51965
+ SetAllowance: ({ allowance }) => ({ ...settings, allowance })
51870
51966
  });
51871
51967
  var encodeSettings = exports_Schema.encodeSync(Settings);
51872
51968
  var json3 = (value5) => JSON.stringify(value5);
51873
51969
  var encodeChangedRow = exports_Schema.encodeSync(Changed.mapFields((fields3) => ({ ...fields3, at: Timestamp })));
51874
51970
  var defaults2 = exports_Schema.decodeSync(Settings)({});
51875
- var get18 = exports_Effect.fn("OrgSettings.get")(function* (org) {
51971
+ var get19 = exports_Effect.fn("OrgSettings.get")(function* (org) {
51876
51972
  return yield* read2(Settings, org);
51877
51973
  });
51878
51974
  var lock = exports_Effect.fn("OrgSettings.lock")(function* (org) {
@@ -52020,7 +52116,8 @@ var Usage = loose({
52020
52116
  completion_tokens: exports_Schema.Int,
52021
52117
  total_tokens: exports_Schema.optionalKey(exports_Schema.Int),
52022
52118
  prompt_tokens_details: exports_Schema.optionalKey(exports_Schema.NullOr(loose({
52023
- cached_tokens: exports_Schema.optionalKey(exports_Schema.NullOr(exports_Schema.Int))
52119
+ cached_tokens: exports_Schema.optionalKey(exports_Schema.NullOr(exports_Schema.Int)),
52120
+ cache_write_tokens: exports_Schema.optionalKey(exports_Schema.NullOr(exports_Schema.Int))
52024
52121
  }))),
52025
52122
  completion_tokens_details: exports_Schema.optionalKey(exports_Schema.NullOr(loose({
52026
52123
  reasoning_tokens: exports_Schema.optionalKey(exports_Schema.NullOr(exports_Schema.Int))
@@ -52097,15 +52194,15 @@ __export(exports_Model, {
52097
52194
  lockUpstream: () => lockUpstream,
52098
52195
  list: () => list2,
52099
52196
  getStored: () => getStored,
52100
- get: () => get19,
52197
+ get: () => get20,
52101
52198
  Stored: () => Stored,
52102
52199
  ReservedId: () => ReservedId,
52103
- Price: () => Price,
52200
+ Offered: () => Offered,
52104
52201
  NotOffered: () => NotOffered,
52105
52202
  NotFound: () => NotFound3,
52106
52203
  Model: () => Model,
52107
52204
  Family: () => Family,
52108
- Columns: () => Columns,
52205
+ Columns: () => Columns2,
52109
52206
  Base: () => Base
52110
52207
  });
52111
52208
 
@@ -52113,19 +52210,11 @@ __export(exports_Model, {
52113
52210
  var Transformation2 = exports_Schema.Union([]).annotate({ identifier: "Transformation" });
52114
52211
 
52115
52212
  // ../core/src/Model/Model.ts
52116
- var UsdPerMTok = exports_Schema.Finite.check(exports_Schema.isGreaterThanOrEqualTo(0));
52117
- var Price = exports_Schema.Struct({
52118
- inputPerMTok: UsdPerMTok,
52119
- outputPerMTok: UsdPerMTok,
52120
- cacheReadPerMTok: exports_Schema.optional(UsdPerMTok),
52121
- cacheWritePerMTok: exports_Schema.optional(UsdPerMTok)
52122
- }).annotate({ identifier: "Price" });
52123
52213
  var Family = exports_Schema.NonEmptyString.pipe(exports_Schema.brand("ModelFamily")).annotate({ identifier: "ModelFamily" });
52124
52214
  var Base = exports_Schema.Struct({
52125
52215
  upstream: UpstreamId,
52126
52216
  upstreamModelId: UpstreamModelId,
52127
- family: Family,
52128
- price: Price
52217
+ family: Family
52129
52218
  }).annotate({ identifier: "ModelBase" });
52130
52219
  var Model = exports_Schema.Struct({
52131
52220
  id: ModelId,
@@ -52134,6 +52223,10 @@ var Model = exports_Schema.Struct({
52134
52223
  parent: exports_Schema.optional(ModelId),
52135
52224
  provenance: exports_Schema.optional(exports_Schema.Json)
52136
52225
  }).annotate({ identifier: "Model" });
52226
+ var Offered = exports_Schema.Struct({
52227
+ model: Model,
52228
+ price: Price
52229
+ }).annotate({ identifier: "ModelOffered" });
52137
52230
  var Stored = exports_Schema.Struct({
52138
52231
  model: Model,
52139
52232
  withdrawn: exports_Schema.optional(EpochMillis)
@@ -52151,12 +52244,12 @@ class NotOffered extends exports_Schema.TaggedError()("ModelNotOffered", {
52151
52244
  }, { httpApiStatus: 409 }) {
52152
52245
  }
52153
52246
  var ReservedId = exports_Schema.Literals(["production"]).annotate({ identifier: "ReservedModelId" });
52154
- var Columns = Model.mapFields((fields3) => ({
52247
+ var Columns2 = Model.mapFields((fields3) => ({
52155
52248
  ...fields3,
52156
52249
  parent: nullAsAbsent(ModelId),
52157
52250
  provenance: nullAsAbsent(exports_Schema.Json)
52158
52251
  }));
52159
- var StoredRow = exports_Schema.Struct({ model: Columns, withdrawn: nullAsAbsent(Timestamp) });
52252
+ var StoredRow = exports_Schema.Struct({ model: Columns2, withdrawn: nullAsAbsent(Timestamp) });
52160
52253
  var findAll2 = exports_Effect.fnUntraced(function* (where, options4 = { lock: false }) {
52161
52254
  const sql = yield* exports_SqlClient.SqlClient;
52162
52255
  const query4 = exports_SqlSchema.findAll({
@@ -52183,7 +52276,7 @@ var getStored = exports_Effect.fn("Model.getStored")(function* (id2) {
52183
52276
  return yield* new NotFound3({ model: id2 });
52184
52277
  return stored;
52185
52278
  });
52186
- var get19 = exports_Effect.fn("Model.get")(function* (id2) {
52279
+ var get20 = exports_Effect.fn("Model.get")(function* (id2) {
52187
52280
  return (yield* getStored(id2)).model;
52188
52281
  });
52189
52282
  var list2 = exports_Effect.fn("Model.list")(function* () {
@@ -52210,7 +52303,7 @@ __export(exports_TraceRecording, {
52210
52303
  productionTrace: () => productionTrace,
52211
52304
  planTurn: () => planTurn,
52212
52305
  outcome: () => outcome,
52213
- get: () => get20,
52306
+ get: () => get21,
52214
52307
  flushAt: () => flushAt,
52215
52308
  attempt: () => attempt,
52216
52309
  Turn: () => Turn,
@@ -52224,13 +52317,96 @@ __export(exports_TraceRecording, {
52224
52317
  Outcome: () => Outcome,
52225
52318
  NotFound: () => NotFound4,
52226
52319
  INFO_KEY: () => INFO_KEY,
52227
- FlushMessage: () => FlushMessage,
52320
+ FlushMessage: () => FlushMessage2,
52228
52321
  ExplicitSession: () => ExplicitSession,
52229
52322
  Delta: () => Delta2,
52230
- Cursor: () => Cursor,
52323
+ Cursor: () => Cursor2,
52231
52324
  AmbralInfo: () => AmbralInfo
52232
52325
  });
52233
52326
 
52327
+ // ../core/src/Billing/Meter.ts
52328
+ var CallId = exports_Schema.NonEmptyString.pipe(exports_Schema.brand("CallId")).annotate({ identifier: "CallId" });
52329
+ var ProviderCostUsd = exports_Schema.Finite.pipe(exports_Schema.brand("ProviderCostUsd")).annotate({
52330
+ identifier: "ProviderCostUsd"
52331
+ });
52332
+ var Supply = exports_Schema.Struct({
52333
+ upstream: UpstreamId,
52334
+ upstreamModelId: UpstreamModelId,
52335
+ providerCost: exports_Schema.optional(ProviderCostUsd)
52336
+ }).annotate({ identifier: "MeterSupply" });
52337
+ var Burns = exports_Schema.Boolean.pipe(exports_Schema.brand("MeterBurns")).annotate({ identifier: "MeterBurns" });
52338
+ var Line = exports_Schema.Struct({
52339
+ callId: CallId,
52340
+ model: ModelId,
52341
+ at: EpochMillis,
52342
+ burns: Burns,
52343
+ supply: Supply,
52344
+ tokens: exports_Schema.optional(Tokens)
52345
+ }).annotate({ identifier: "MeterLine" });
52346
+ var burnsBy = {
52347
+ Credits: exports_Option.some(Burns.make(true)),
52348
+ Ambral: exports_Option.some(Burns.make(false)),
52349
+ Byok: exports_Option.none()
52350
+ };
52351
+ var isSuccess7 = (status3) => status3 >= 200 && status3 < 300;
52352
+ var lineOf = (call) => exports_Option.map(exports_Option.filter(burnsBy[call.paidBy], () => isSuccess7(call.observed.status)), (burns) => ({
52353
+ callId: call.callId,
52354
+ model: call.model,
52355
+ at: call.at,
52356
+ burns,
52357
+ supply: {
52358
+ ...call.supply,
52359
+ providerCost: exports_Option.getOrUndefined(exports_Option.map(exports_Option.fromNullishOr(call.observed.response?.usage?.cost), ProviderCostUsd.make))
52360
+ },
52361
+ tokens: call.observed.tokens
52362
+ }));
52363
+ var Cursor = exports_Schema.Int.check(exports_Schema.isGreaterThanOrEqualTo(0)).pipe(exports_Schema.brand("MeterCursor")).annotate({
52364
+ identifier: "MeterCursor"
52365
+ });
52366
+ var byCursor = exports_Order.Number;
52367
+ var State5 = exports_Schema.Struct({
52368
+ recorded: Cursor,
52369
+ acked: Cursor,
52370
+ alarmAt: exports_Schema.optional(EpochMillis)
52371
+ }).check(exports_Schema.makeFilter((state2) => state2.acked <= state2.recorded || { path: ["acked"], issue: "a flush acknowledges only lines recorded" })).annotate({ identifier: "MeterState" });
52372
+ var FLUSH_EVERY = exports_Duration.seconds(5);
52373
+ var flushEvery = exports_Config.Duration("CREDIT_FLUSH_EVERY").pipe(exports_Config.withDefault(FLUSH_EVERY));
52374
+ var Range = exports_Schema.Struct({ after: Cursor, upTo: Cursor }).annotate({ identifier: "MeterRange" });
52375
+ var FlushMessage = exports_Schema.Struct({ org: OrgId, cursor: Cursor }).annotate({ identifier: "MeterFlushMessage" });
52376
+ var Batch = exports_Schema.Struct({
52377
+ org: OrgId,
52378
+ lines: exports_Schema.Array(Line),
52379
+ cursor: Cursor
52380
+ }).annotate({ identifier: "MeterBatch" });
52381
+
52382
+ class MeterError extends exports_Schema.TaggedError()("MeterError", {
52383
+ reason: exports_Schema.Literals(["Unavailable"]),
52384
+ cause: exports_Schema.Defect()
52385
+ }) {
52386
+ }
52387
+
52388
+ class CreditMeter extends exports_Context.Service()("@ambral/core/Billing/CreditMeter") {
52389
+ }
52390
+ var CHARGE_RETRY = exports_Schedule.exponential("200 millis");
52391
+ var CHARGE_RETRIES = 3;
52392
+ var charge2 = exports_Effect.fn("Meter.charge")(function* (org, line) {
52393
+ const meter = yield* CreditMeter;
52394
+ yield* meter.charge(org, line).pipe(exports_Effect.retry({ schedule: CHARGE_RETRY, times: CHARGE_RETRIES }));
52395
+ });
52396
+ var chargeCall = exports_Effect.fn("Meter.chargeCall")(function* (org, call) {
52397
+ const line = lineOf(call);
52398
+ if (exports_Option.isNone(line))
52399
+ return;
52400
+ if (line.value.tokens === undefined) {
52401
+ yield* exports_Effect.logWarning("A call on Ambral's key ended without its usage, so it is free", {
52402
+ org,
52403
+ model: call.model,
52404
+ reason: call.observed.error?.code
52405
+ });
52406
+ }
52407
+ yield* charge2(org, line.value).pipe(exports_Effect.catchCause((cause) => exports_Effect.logWarning("Meter.charge failed", cause)));
52408
+ });
52409
+
52234
52410
  // ../../node_modules/.bun/@noble+hashes@2.4.0/node_modules/@noble/hashes/_blake.js
52235
52411
  var BSIGMA = /* @__PURE__ */ Uint8Array.from([
52236
52412
  0,
@@ -53664,13 +53840,13 @@ var addToolCall = (calls, delta) => {
53664
53840
  const existing = calls.get(index2);
53665
53841
  const slot = { natives: new Map, input: "", ...existing, id: delta.id || existing?.id || "" };
53666
53842
  const kind = delta.type ?? (delta["custom"] != null ? "custom" : delta.function != null ? "function" : slot.type);
53667
- const next3 = new Map(calls);
53843
+ const next4 = new Map(calls);
53668
53844
  if (kind === undefined)
53669
- return next3.set(index2, slot);
53845
+ return next4.set(index2, slot);
53670
53846
  const deltaNative = delta[kind];
53671
53847
  const streamed = isObject2(deltaNative) ? deltaNative : {};
53672
53848
  const piece = streamed[kind === "custom" ? "input" : "arguments"];
53673
- return next3.set(index2, {
53849
+ return next4.set(index2, {
53674
53850
  ...slot,
53675
53851
  type: kind,
53676
53852
  natives: new Map(slot.natives).set(kind, nativeOf(slot.natives.get(kind) ?? { name: "" }, streamed)),
@@ -53695,8 +53871,8 @@ var addChoice = (parser, choice2) => {
53695
53871
  };
53696
53872
  };
53697
53873
  var feed = (parser, chunk) => {
53698
- const next3 = { ...parser, head: parser.head ?? chunk, usage: chunk.usage ?? parser.usage };
53699
- return chunk.choices.filter((choice2) => choice2.index === 0).reduce(addChoice, next3);
53874
+ const next4 = { ...parser, head: parser.head ?? chunk, usage: chunk.usage ?? parser.usage };
53875
+ return chunk.choices.filter((choice2) => choice2.index === 0).reduce(addChoice, next4);
53700
53876
  };
53701
53877
  var toolCallWire = (slot) => {
53702
53878
  if (slot.type === undefined || !CLIENT_TOOL_TYPES.has(slot.type))
@@ -53748,7 +53924,8 @@ var ObservedResponse = exports_Schema.Struct({
53748
53924
  firstByteMs: exports_Schema.optional(Millis),
53749
53925
  durationMs: Millis,
53750
53926
  error: exports_Schema.optional(Error5),
53751
- response: exports_Schema.optional(Response2)
53927
+ response: exports_Schema.optional(Response2),
53928
+ tokens: exports_Schema.optional(Tokens)
53752
53929
  }).annotate({ identifier: "ObservedResponse" });
53753
53930
  var END_ERRORS = {
53754
53931
  done: undefined,
@@ -53818,12 +53995,12 @@ var concat3 = (a, b) => {
53818
53995
  return joined;
53819
53996
  };
53820
53997
  var drain4 = (state2) => {
53821
- let next3 = state2;
53822
- for (let bounds = eventEnd(next3.pending);bounds !== undefined; bounds = eventEnd(next3.pending)) {
53823
- const event = next3.pending.subarray(0, bounds.end);
53824
- next3 = Events({ ...onEvent(next3, event), pending: next3.pending.subarray(bounds.next) });
53998
+ let next4 = state2;
53999
+ for (let bounds = eventEnd(next4.pending);bounds !== undefined; bounds = eventEnd(next4.pending)) {
54000
+ const event = next4.pending.subarray(0, bounds.end);
54001
+ next4 = Events({ ...onEvent(next4, event), pending: next4.pending.subarray(bounds.next) });
53825
54002
  }
53826
- return next3;
54003
+ return next4;
53827
54004
  };
53828
54005
  var feed2 = (state2, chunk, at) => {
53829
54006
  const firstByteAt = state2.firstByteAt ?? (chunk.length > 0 ? at : undefined);
@@ -53836,10 +54013,11 @@ var bodyText2 = (chunks2) => {
53836
54013
  const streaming = new TextDecoder;
53837
54014
  return chunks2.map((chunk) => streaming.decode(chunk, { stream: true })).join("") + streaming.decode();
53838
54015
  };
53839
- var isSuccess7 = (status3) => status3 >= 200 && status3 < 300;
54016
+ var isSuccess8 = (status3) => status3 >= 200 && status3 < 300;
54017
+ var tokensOf2 = (usage) => usage == null ? undefined : tokensOf(usage);
53840
54018
  var readBody = (state2) => {
53841
54019
  const text3 = bodyText2(state2.chunks);
53842
- if (!isSuccess7(state2.status)) {
54020
+ if (!isSuccess8(state2.status)) {
53843
54021
  return {
53844
54022
  error: exports_Option.match(decodeProviderError(text3), {
53845
54023
  onNone: () => ({ code: ErrorCode.make(String(state2.status)), message: "" }),
@@ -53847,16 +54025,18 @@ var readBody = (state2) => {
53847
54025
  })
53848
54026
  };
53849
54027
  }
53850
- return exports_Option.match(exports_Option.flatMap(decodeCompletion(text3), responseFromWire), {
54028
+ const completion = decodeCompletion(text3);
54029
+ return exports_Option.match(exports_Option.flatMap(completion, responseFromWire), {
53851
54030
  onNone: () => ({ error: malformed("The body") }),
53852
- onSome: (response) => ({ response })
54031
+ onSome: (response) => ({ response, tokens: tokensOf2(exports_Option.getOrUndefined(completion)?.usage) })
53853
54032
  });
53854
54033
  };
53855
54034
  var readEvents = (state2, end3, at) => {
53856
54035
  const final = end3 === "done" && state2.pending.length > 0 ? onEvent(state2, state2.pending) : state2;
53857
54036
  return {
53858
54037
  response: final.parser.head === undefined ? undefined : finish(final.parser, at),
53859
- error: final.error
54038
+ error: final.error,
54039
+ tokens: tokensOf2(final.parser.usage)
53860
54040
  };
53861
54041
  };
53862
54042
  var elapsed = (from, to) => Millis.make(Math.max(0, to - from));
@@ -53870,7 +54050,8 @@ var finish2 = (state2, end3, at) => {
53870
54050
  firstByteMs: state2.firstByteAt === undefined ? undefined : elapsed(state2.receivedAt, state2.firstByteAt),
53871
54051
  durationMs: elapsed(state2.receivedAt, at),
53872
54052
  error: read3.error ?? END_ERRORS[end3],
53873
- response: read3.response
54053
+ response: read3.response,
54054
+ tokens: read3.tokens
53874
54055
  };
53875
54056
  };
53876
54057
  var modelCall = (request3, upstreamModel, observed, startedAt) => compact2({
@@ -53931,47 +54112,47 @@ var NodeKey = exports_Schema.Struct({
53931
54112
  var lookup3 = (index2, parent, toolsHash, message) => index2.get(key(parent, parent === null ? toolsHash : null, hash3(message)));
53932
54113
  var prepareTurn = (index2, prompt, tools) => {
53933
54114
  const toolsHash = hash2(tools);
53934
- const prefix4 = [];
54115
+ const prefix3 = [];
53935
54116
  for (const message of prompt) {
53936
- const existing = lookup3(index2, prefix4.at(-1) ?? null, toolsHash, message);
54117
+ const existing = lookup3(index2, prefix3.at(-1) ?? null, toolsHash, message);
53937
54118
  if (existing === undefined)
53938
54119
  break;
53939
- prefix4.push(existing);
54120
+ prefix3.push(existing);
53940
54121
  }
53941
- return { prompt, tools, toolsHash, prefix: prefix4 };
54122
+ return { prompt, tools, toolsHash, prefix: prefix3 };
53942
54123
  };
53943
54124
  var appending = (index2, turn, nextId) => {
53944
- const next3 = new Map(index2);
54125
+ const next4 = new Map(index2);
53945
54126
  const nodes = [];
53946
- const prefix4 = [...turn.prefix];
53947
- while (prefix4.length < turn.prompt.length) {
53948
- const existing = lookup3(next3, prefix4.at(-1) ?? null, turn.toolsHash, turn.prompt[prefix4.length]);
54127
+ const prefix3 = [...turn.prefix];
54128
+ while (prefix3.length < turn.prompt.length) {
54129
+ const existing = lookup3(next4, prefix3.at(-1) ?? null, turn.toolsHash, turn.prompt[prefix3.length]);
53949
54130
  if (existing === undefined)
53950
54131
  break;
53951
- prefix4.push(existing);
54132
+ prefix3.push(existing);
53952
54133
  }
53953
- let parent = prefix4.at(-1) ?? null;
53954
- const append4 = (message, sampled) => {
54134
+ let parent = prefix3.at(-1) ?? null;
54135
+ const append5 = (message, sampled) => {
53955
54136
  const id2 = NodeId.make(nextId + nodes.length);
53956
54137
  const messageHash = hash3(message);
53957
54138
  const root = parent === null ? { toolsHash: turn.toolsHash, tools: turn.tools } : null;
53958
54139
  const node = fromStored({ message, parent: parent ?? undefined, tools: root?.tools, sampled });
53959
54140
  nodes.push({ id: id2, node, messageHash, root });
53960
- next3.set(key(parent, root?.toolsHash ?? null, messageHash), id2);
54141
+ next4.set(key(parent, root?.toolsHash ?? null, messageHash), id2);
53961
54142
  return id2;
53962
54143
  };
53963
- for (const message of turn.prompt.slice(prefix4.length))
53964
- parent = append4(message, false);
53965
- return { next: next3, nodes, parent, append: append4 };
54144
+ for (const message of turn.prompt.slice(prefix3.length))
54145
+ parent = append5(message, false);
54146
+ return { next: next4, nodes, parent, append: append5 };
53966
54147
  };
53967
54148
  var commitTurn = (index2, turn, reply, nextId) => {
53968
- const { next: next3, nodes, parent, append: append4 } = appending(index2, turn, nextId);
53969
- const node = lookup3(next3, parent, turn.toolsHash, reply) ?? append4(reply, true);
53970
- return { nodes, node, index: next3 };
54149
+ const { next: next4, nodes, parent, append: append5 } = appending(index2, turn, nextId);
54150
+ const node = lookup3(next4, parent, turn.toolsHash, reply) ?? append5(reply, true);
54151
+ return { nodes, node, index: next4 };
53971
54152
  };
53972
54153
  var commitPrompt = (index2, turn, nextId) => {
53973
- const { next: next3, nodes, parent } = appending(index2, turn, nextId);
53974
- return { nodes, node: parent ?? undefined, index: next3 };
54154
+ const { next: next4, nodes, parent } = appending(index2, turn, nextId);
54155
+ return { nodes, node: parent ?? undefined, index: next4 };
53975
54156
  };
53976
54157
  var toolIdentity = (tool) => JSON.stringify([tool.namespace ?? null, tool.name, tool.type ?? "function"]);
53977
54158
  var mergeTools = (existing, added) => [
@@ -54186,7 +54367,7 @@ class MessageStore extends exports_Context.Service()("@ambral/core/Trace/Message
54186
54367
  }
54187
54368
  var encoder7 = new TextEncoder;
54188
54369
  var unavailable = (cause) => new StoreError({ reason: "Unavailable", cause });
54189
- var layerSql2 = exports_Layer.effect(MessageStore, exports_Effect.gen(function* () {
54370
+ var layerSql = exports_Layer.effect(MessageStore, exports_Effect.gen(function* () {
54190
54371
  const sql = yield* exports_SqlClient.SqlClient;
54191
54372
  const find2 = exports_SqlSchema.findAll({
54192
54373
  Request: exports_Schema.Array(MessageHash),
@@ -54290,6 +54471,7 @@ var Turn = exports_Schema.Struct({
54290
54471
  tools: exports_Schema.Array(Tool2),
54291
54472
  reply: exports_Schema.optional(Assistant),
54292
54473
  call: ModelCall,
54474
+ charged: exports_Schema.optional(Line),
54293
54475
  at: EpochMillis
54294
54476
  }).annotate({ identifier: "TraceRecordingTurn" });
54295
54477
  var promptVersion = (messages, tools) => {
@@ -54338,7 +54520,8 @@ var turnOf = (input) => {
54338
54520
  return {
54339
54521
  ...input.recordable.turn,
54340
54522
  reply: input.observed.response?.message,
54341
- call: modelCall(input.request, input.recordable.upstreamModel, input.observed, input.recordable.turn.at)
54523
+ call: modelCall(input.request, input.recordable.upstreamModel, input.observed, input.recordable.turn.at),
54524
+ charged: input.charged
54342
54525
  };
54343
54526
  };
54344
54527
  var planTurn = (graph, tools, turn) => {
@@ -54357,10 +54540,10 @@ var planTurn = (graph, tools, turn) => {
54357
54540
  return { nodes: commit.nodes, call: { ...turn.call, node: commit.node }, tools: merged };
54358
54541
  });
54359
54542
  };
54360
- var Cursor = exports_Schema.Int.check(exports_Schema.isGreaterThanOrEqualTo(0)).pipe(exports_Schema.brand("TraceRecordingCursor")).annotate({ identifier: "TraceRecordingCursor" });
54361
- var FlushMessage = exports_Schema.Struct({
54543
+ var Cursor2 = exports_Schema.Int.check(exports_Schema.isGreaterThanOrEqualTo(0)).pipe(exports_Schema.brand("TraceRecordingCursor")).annotate({ identifier: "TraceRecordingCursor" });
54544
+ var FlushMessage2 = exports_Schema.Struct({
54362
54545
  traceId: TraceId,
54363
- cursor: Cursor
54546
+ cursor: Cursor2
54364
54547
  }).annotate({ identifier: "FlushMessage" });
54365
54548
 
54366
54549
  class RecorderError extends exports_Schema.TaggedError()("TraceRecorderError", {
@@ -54380,8 +54563,8 @@ var Delta2 = exports_Schema.Struct({
54380
54563
  status: Status4,
54381
54564
  settledAt: exports_Schema.optional(EpochMillis),
54382
54565
  nodes: exports_Schema.Array(exports_Schema.Struct({ id: NodeId, node: MessageNode })),
54383
- calls: exports_Schema.Array(exports_Schema.Struct({ index: CallIndex, ...StoredCall.fields })),
54384
- cursor: Cursor
54566
+ calls: exports_Schema.Array(exports_Schema.Struct({ index: CallIndex, ...StoredCall.fields, charged: exports_Schema.optional(Line) })),
54567
+ cursor: Cursor2
54385
54568
  }).check(settledAtMatchesStatus).annotate({ identifier: "TraceRecordingDelta" });
54386
54569
  var PublicId = exports_Schema.String.check(exports_Schema.isPattern(/^tr_[0-9a-f]{16}$/)).pipe(exports_Schema.brand("TracePublicId")).annotate({ identifier: "TracePublicId" });
54387
54570
 
@@ -54419,7 +54602,7 @@ var attempt = (made) => {
54419
54602
  info: { [INFO_KEY]: encodeInfo(info2) }
54420
54603
  };
54421
54604
  };
54422
- var wholeDelta = (org, trace3, at) => {
54605
+ var wholeDelta = (org, trace3, at, charged = []) => {
54423
54606
  const { nodes = [], calls = [], ...rest } = trace3;
54424
54607
  return {
54425
54608
  org,
@@ -54427,10 +54610,12 @@ var wholeDelta = (org, trace3, at) => {
54427
54610
  status: "settled",
54428
54611
  settledAt: at,
54429
54612
  nodes: nodes.map((node, id2) => ({ id: NodeId.make(id2), node })),
54430
- calls: calls.map((call, index2) => ({ index: CallIndex.make(index2), call })),
54431
- cursor: Cursor.make(1)
54613
+ calls: calls.map((call, index2) => ({ index: CallIndex.make(index2), call, charged: charged[index2] })),
54614
+ cursor: Cursor2.make(1)
54432
54615
  };
54433
54616
  };
54617
+ var unavailable2 = (cause) => new StoreError({ reason: "Unavailable", cause });
54618
+ var priced = (calls) => chargesOf(calls.map(({ charged }) => charged)).pipe(exports_Effect.map((charges) => calls.map((entry, position) => ({ ...entry, call: withCharge(entry.call, charges[position]) }))), exports_Effect.mapError(unavailable2));
54434
54619
  var StoredNode = MessageNode.mapFields((fields3) => exports_Struct.omit(fields3, ["message"]));
54435
54620
  var encodeTrace = exports_Schema.encodeSync(StoredTrace);
54436
54621
  var encodeNode = exports_Schema.encodeSync(StoredNode);
@@ -54451,7 +54636,7 @@ var write2 = exports_Effect.fn("TraceRecording.write")(function* (delta) {
54451
54636
  message_hash: hash3(message),
54452
54637
  tools_hash: node.parent == null ? hash2(node.tools ?? []) : null
54453
54638
  }));
54454
- const calls = delta.calls.map(({ index: index2, call, prompt }) => ({
54639
+ const calls = (yield* priced(delta.calls)).map(({ index: index2, call, prompt }) => ({
54455
54640
  trace_id: id2,
54456
54641
  idx: index2,
54457
54642
  call: json4(encodeCall(call)),
@@ -54479,7 +54664,7 @@ var write2 = exports_Effect.fn("TraceRecording.write")(function* (delta) {
54479
54664
  WHERE trace_id = ${id2} AND node_id IN ${sql.in(replies)} AND NOT sampled
54480
54665
  `;
54481
54666
  }
54482
- })).pipe(exports_Effect.mapError((cause) => new StoreError({ reason: "Unavailable", cause })));
54667
+ })).pipe(exports_Effect.mapError(unavailable2));
54483
54668
  });
54484
54669
  var TraceRow = exports_Schema.Struct({ trace: StoredTrace });
54485
54670
  var NodeRow = exports_Schema.Struct({ node_id: NodeId, message_hash: MessageHash, node: StoredNode });
@@ -54492,8 +54677,7 @@ var graphOf = (id2, rows, bodies) => {
54492
54677
  return nodes.length === rows.length ? exports_Effect.succeed(nodes) : exports_Effect.die(`TraceRecording: trace ${id2}'s graph is incomplete`);
54493
54678
  };
54494
54679
  var TraceRequest = exports_Schema.Struct({ org: OrgId, id: TraceId });
54495
- var unavailable2 = (cause) => new StoreError({ reason: "Unavailable", cause });
54496
- var get20 = exports_Effect.fn("TraceRecording.get")(function* (org, id2) {
54680
+ var get21 = exports_Effect.fn("TraceRecording.get")(function* (org, id2) {
54497
54681
  const sql = yield* exports_SqlClient.SqlClient;
54498
54682
  const store = yield* MessageStore;
54499
54683
  yield* exports_Effect.annotateCurrentSpan({ org, traceId: id2 });
@@ -54532,9 +54716,9 @@ var exports_Workload = {};
54532
54716
  __export(exports_Workload, {
54533
54717
  routeOf: () => routeOf,
54534
54718
  movesRoute: () => movesRoute,
54535
- make: () => make70,
54719
+ make: () => make71,
54536
54720
  list: () => list5,
54537
- get: () => get23,
54721
+ get: () => get24,
54538
54722
  create: () => create,
54539
54723
  changes: () => changes2,
54540
54724
  change: () => change2,
@@ -54560,12 +54744,15 @@ __export(exports_Inference, {
54560
54744
  retryAfter: () => retryAfter,
54561
54745
  requestOf: () => requestOf,
54562
54746
  produce: () => produce,
54747
+ paidByOf: () => paidByOf,
54563
54748
  completionOf: () => completionOf,
54564
54749
  Unavailable: () => Unavailable2,
54565
54750
  Request: () => Request4,
54566
54751
  ProviderKeys: () => ProviderKeys,
54567
54752
  Prompt: () => Prompt2,
54568
54753
  ProduceError: () => ProduceError,
54754
+ PaidBy: () => PaidBy,
54755
+ OutOfCredit: () => OutOfCredit,
54569
54756
  KeyRequired: () => KeyRequired,
54570
54757
  Inference: () => Inference,
54571
54758
  Credential: () => Credential
@@ -54583,15 +54770,24 @@ class Unavailable2 extends exports_Schema.TaggedError()("InferenceUnavailable",
54583
54770
  cause: exports_Schema.Defect()
54584
54771
  }) {
54585
54772
  }
54773
+ var PaidBy = exports_Schema.Literals(["Credits", "Ambral", "Byok"]).annotate({ identifier: "InferencePaidBy" });
54774
+ var StageKeyPaidBy = PaidBy.pick(["Credits", "Ambral"]);
54586
54775
 
54587
54776
  class KeyRequired extends exports_Schema.TaggedError()("InferenceKeyRequired", {
54588
54777
  upstream: UpstreamId
54589
54778
  }) {
54590
54779
  }
54591
54780
 
54781
+ class OutOfCredit extends exports_Schema.TaggedError()("InferenceOutOfCredit", {}) {
54782
+ }
54783
+
54592
54784
  class Inference extends exports_Context.Service()("@ambral/core/Inference/Inference") {
54593
54785
  }
54594
54786
  var Credential = exports_Data.taggedEnum();
54787
+ var paidByOf = (credential) => exports_Match.valueTags(credential, {
54788
+ Ambral: ({ paidBy }) => paidBy,
54789
+ Org: () => "Byok"
54790
+ });
54595
54791
 
54596
54792
  class ProviderKeys extends exports_Context.Service()("@ambral/core/Inference/ProviderKeys") {
54597
54793
  }
@@ -54603,7 +54799,7 @@ var Prompt2 = exports_Schema.Struct({
54603
54799
 
54604
54800
  class ProduceError extends exports_Schema.TaggedError()("ProduceError", {
54605
54801
  model: ModelId,
54606
- reason: exports_Schema.Literals(["Unavailable", "KeyRequired", "Rejected", "Malformed"]),
54802
+ reason: exports_Schema.Literals(["Unavailable", "KeyRequired", "OutOfCredit", "Rejected", "Malformed"]),
54607
54803
  rejection: exports_Schema.optional(exports_Schema.Struct({
54608
54804
  status: Status3,
54609
54805
  error: Error5,
@@ -54656,21 +54852,817 @@ var produce = exports_Effect.fn("Inference.produce")(function* (model, prompt, o
54656
54852
  const body = yield* encodeRequest(request3).pipe(exports_Effect.orDie);
54657
54853
  const unavailable3 = (cause) => new ProduceError({ model: model.id, reason: "Unavailable", cause });
54658
54854
  const startedAt = yield* now3;
54659
- const response = yield* inference.send({
54660
- upstream: model.base.upstream,
54661
- endpoint: "/chat/completions",
54662
- body,
54663
- requireParameters: true,
54664
- org
54665
- }).pipe(exports_Effect.mapError((error2) => exports_Match.valueTags(error2, {
54666
- InferenceUnavailable: unavailable3,
54667
- InferenceKeyRequired: (cause) => new ProduceError({ model: model.id, reason: "KeyRequired", cause })
54668
- })));
54669
- const contentType = exports_Option.getOrUndefined(exports_Headers.get(response.headers, "content-type"));
54670
- const read3 = yield* exports_Stream.runFoldEffect(response.body, () => start(response.status, contentType, startedAt), (state2, chunk) => exports_Effect.map(now3, (at) => feed2(state2, chunk, at))).pipe(exports_Effect.mapError(unavailable3));
54671
- const finishedAt = yield* now3;
54672
- const observed = finish2(read3, "done", finishedAt);
54673
- return yield* exports_Effect.fromResult(completionOf(model, request3, observed, startedAt, retryAfter(response.headers, finishedAt)));
54855
+ return yield* exports_Effect.uninterruptibleMask((restore) => exports_Effect.gen(function* () {
54856
+ const response = yield* restore(inference.send({
54857
+ upstream: model.base.upstream,
54858
+ endpoint: "/chat/completions",
54859
+ body,
54860
+ requireParameters: true,
54861
+ org
54862
+ })).pipe(exports_Effect.mapError((error2) => exports_Match.valueTags(error2, {
54863
+ InferenceUnavailable: unavailable3,
54864
+ InferenceKeyRequired: (cause) => new ProduceError({ model: model.id, reason: "KeyRequired", cause }),
54865
+ InferenceOutOfCredit: (cause) => new ProduceError({ model: model.id, reason: "OutOfCredit", cause })
54866
+ })));
54867
+ const contentType = exports_Option.getOrUndefined(exports_Headers.get(response.headers, "content-type"));
54868
+ const read3 = yield* exports_Ref.make(start(response.status, contentType, startedAt));
54869
+ const streamed = yield* restore(exports_Stream.runForEach(response.body, (chunk) => exports_Effect.flatMap(now3, (at) => exports_Ref.update(read3, (state2) => feed2(state2, chunk, at))))).pipe(exports_Effect.mapError(unavailable3), exports_Effect.exit);
54870
+ const finishedAt = yield* now3;
54871
+ const observed = finish2(yield* exports_Ref.get(read3), exports_Exit.isSuccess(streamed) ? "done" : "failed", finishedAt);
54872
+ const call = {
54873
+ callId: CallId.make(yield* uuid),
54874
+ model: model.id,
54875
+ paidBy: response.paidBy,
54876
+ supply: { upstream: model.base.upstream, upstreamModelId: model.base.upstreamModelId },
54877
+ observed,
54878
+ at: startedAt
54879
+ };
54880
+ yield* chargeCall(org, call);
54881
+ yield* streamed;
54882
+ const completion = yield* exports_Effect.fromResult(completionOf(model, request3, observed, startedAt, retryAfter(response.headers, finishedAt)));
54883
+ return { ...completion, charged: exports_Option.getOrUndefined(lineOf(call)) };
54884
+ }));
54885
+ });
54886
+
54887
+ // ../../node_modules/.bun/effect@4.0.3/node_modules/effect/dist/persistence/KeyValueStore.js
54888
+ var exports_KeyValueStore = {};
54889
+ __export(exports_KeyValueStore, {
54890
+ toSchemaStore: () => toSchemaStore,
54891
+ prefix: () => prefix3,
54892
+ makeStringOnly: () => makeStringOnly,
54893
+ make: () => make69,
54894
+ layerStorage: () => layerStorage,
54895
+ layerSql: () => layerSql2,
54896
+ layerMemory: () => layerMemory,
54897
+ layerFileSystem: () => layerFileSystem,
54898
+ KeyValueStoreError: () => KeyValueStoreError,
54899
+ KeyValueStore: () => KeyValueStore
54900
+ });
54901
+ var TypeId74 = "~effect/persistence/KeyValueStore";
54902
+ var ErrorTypeId = "~effect/persistence/KeyValueStore/KeyValueStoreError";
54903
+
54904
+ class KeyValueStoreError extends (/* @__PURE__ */ TaggedError2("KeyValueStoreError")) {
54905
+ [ErrorTypeId] = ErrorTypeId;
54906
+ }
54907
+ var KeyValueStore = /* @__PURE__ */ Service("effect/persistence/KeyValueStore");
54908
+ var make69 = (options4) => KeyValueStore.of({
54909
+ [TypeId74]: TypeId74,
54910
+ has: (key2) => map9(options4.get(key2), isNotUndefined),
54911
+ isEmpty: map9(options4.size, (size8) => size8 === 0),
54912
+ modify: (key2, f) => flatMap6(options4.get(key2), (o) => {
54913
+ if (o === undefined) {
54914
+ return undefined_2;
54915
+ }
54916
+ const newValue = f(o);
54917
+ return as3(options4.set(key2, newValue), newValue);
54918
+ }),
54919
+ modifyUint8Array: (key2, f) => flatMap6(options4.getUint8Array(key2), (o) => {
54920
+ if (o === undefined) {
54921
+ return undefined_2;
54922
+ }
54923
+ const newValue = f(o);
54924
+ return as3(options4.set(key2, newValue), newValue);
54925
+ }),
54926
+ ...options4
54927
+ });
54928
+ var makeStringOnly = (options4) => {
54929
+ const encoder8 = new TextEncoder;
54930
+ return make69({
54931
+ ...options4,
54932
+ getUint8Array: (key2) => options4.get(key2).pipe(map9(map20((value5) => match2(decode2(value5), {
54933
+ onFailure: () => encoder8.encode(value5),
54934
+ onSuccess: identity
54935
+ })))),
54936
+ set: (key2, value5) => typeof value5 === "string" ? options4.set(key2, value5) : suspend3(() => options4.set(key2, encode2(value5)))
54937
+ });
54938
+ };
54939
+ var prefix3 = /* @__PURE__ */ dual(2, (self, prefix4) => ({
54940
+ ...self,
54941
+ get: (key2) => self.get(`${prefix4}${key2}`),
54942
+ getUint8Array: (key2) => self.getUint8Array(`${prefix4}${key2}`),
54943
+ set: (key2, value5) => self.set(`${prefix4}${key2}`, value5),
54944
+ remove: (key2) => self.remove(`${prefix4}${key2}`),
54945
+ has: (key2) => self.has(`${prefix4}${key2}`),
54946
+ modify: (key2, f) => self.modify(`${prefix4}${key2}`, f),
54947
+ modifyUint8Array: (key2, f) => self.modifyUint8Array(`${prefix4}${key2}`, f)
54948
+ }));
54949
+ var layerMemory = /* @__PURE__ */ sync2(KeyValueStore)(() => {
54950
+ const store = new Map;
54951
+ const encoder8 = new TextEncoder;
54952
+ return make69({
54953
+ get: (key2) => sync3(() => {
54954
+ const value5 = store.get(key2);
54955
+ return value5 === undefined ? undefined : typeof value5 === "string" ? value5 : encode2(value5);
54956
+ }),
54957
+ getUint8Array: (key2) => sync3(() => {
54958
+ const value5 = store.get(key2);
54959
+ return value5 === undefined ? undefined : typeof value5 === "string" ? encoder8.encode(value5) : value5;
54960
+ }),
54961
+ set: (key2, value5) => sync3(() => store.set(key2, value5)),
54962
+ remove: (key2) => sync3(() => store.delete(key2)),
54963
+ clear: sync3(() => store.clear()),
54964
+ size: sync3(() => store.size)
54965
+ });
54966
+ });
54967
+ var layerFileSystem = (directory) => effect(KeyValueStore)(gen4(function* () {
54968
+ const fs = yield* FileSystem;
54969
+ const path = yield* Path;
54970
+ const withKeyPath = (method, key2, f) => key2.length === 0 || key2 === "." || key2 === ".." ? fail6(new KeyValueStoreError({
54971
+ method,
54972
+ key: key2,
54973
+ message: `Invalid key ${key2}`
54974
+ })) : f(path.join(directory, encodeURIComponent(key2)));
54975
+ if (!(yield* fs.exists(directory))) {
54976
+ yield* fs.makeDirectory(directory, {
54977
+ recursive: true
54978
+ });
54979
+ }
54980
+ return make69({
54981
+ get: (key2) => withKeyPath("get", key2, (path2) => catchTag3(fs.readFileString(path2), "PlatformError", (cause) => cause.reason._tag === "NotFound" ? undefined_2 : fail6(new KeyValueStoreError({
54982
+ method: "get",
54983
+ key: key2,
54984
+ message: `Unable to get item with key ${key2}`,
54985
+ cause
54986
+ })))),
54987
+ getUint8Array: (key2) => withKeyPath("getUint8Array", key2, (path2) => catchTag3(fs.readFile(path2), "PlatformError", (cause) => cause.reason._tag === "NotFound" ? undefined_2 : fail6(new KeyValueStoreError({
54988
+ method: "getUint8Array",
54989
+ key: key2,
54990
+ message: `Unable to get item with key ${key2}`,
54991
+ cause
54992
+ })))),
54993
+ set: (key2, value5) => withKeyPath("set", key2, (path2) => mapError4(typeof value5 === "string" ? fs.writeFileString(path2, value5) : fs.writeFile(path2, value5), (cause) => new KeyValueStoreError({
54994
+ method: "set",
54995
+ key: key2,
54996
+ message: `Unable to set item with key ${key2}`,
54997
+ cause
54998
+ }))),
54999
+ remove: (key2) => withKeyPath("remove", key2, (path2) => mapError4(fs.remove(path2), (cause) => new KeyValueStoreError({
55000
+ method: "remove",
55001
+ key: key2,
55002
+ message: `Unable to remove item with key ${key2}`,
55003
+ cause
55004
+ }))),
55005
+ has: (key2) => withKeyPath("has", key2, (path2) => mapError4(fs.exists(path2), (cause) => new KeyValueStoreError({
55006
+ method: "has",
55007
+ key: key2,
55008
+ message: `Unable to check existence of item with key ${key2}`,
55009
+ cause
55010
+ }))),
55011
+ clear: mapError4(andThen4(fs.remove(directory, {
55012
+ recursive: true
55013
+ }), fs.makeDirectory(directory, {
55014
+ recursive: true
55015
+ })), (cause) => new KeyValueStoreError({
55016
+ method: "clear",
55017
+ message: `Unable to clear storage`,
55018
+ cause
55019
+ })),
55020
+ size: matchEffect3(fs.readDirectory(directory), {
55021
+ onSuccess: (files) => succeed6(files.length),
55022
+ onFailure: (cause) => fail6(new KeyValueStoreError({
55023
+ method: "size",
55024
+ message: `Unable to get size`,
55025
+ cause
55026
+ }))
55027
+ })
55028
+ });
55029
+ }));
55030
+ var layerSql2 = (options4 = {}) => effect(KeyValueStore)(gen4(function* () {
55031
+ const sql = (yield* SqlClient).withoutTransforms();
55032
+ const table2 = sql(options4.table ?? "effect_key_value_store");
55033
+ yield* sql.onDialectOrElse({
55034
+ mysql: () => sql`
55035
+ CREATE TABLE IF NOT EXISTS ${table2} (
55036
+ id VARCHAR(191) PRIMARY KEY,
55037
+ value BLOB NOT NULL,
55038
+ value_type SMALLINT NOT NULL
55039
+ )
55040
+ `,
55041
+ pg: () => sql`
55042
+ CREATE TABLE IF NOT EXISTS ${table2} (
55043
+ id TEXT PRIMARY KEY,
55044
+ value BYTEA NOT NULL,
55045
+ value_type SMALLINT NOT NULL
55046
+ )
55047
+ `,
55048
+ mssql: () => sql`
55049
+ IF NOT EXISTS (SELECT * FROM sysobjects WHERE name=${table2} AND xtype='U')
55050
+ CREATE TABLE ${table2} (
55051
+ id NVARCHAR(450) PRIMARY KEY,
55052
+ value VARBINARY(MAX) NOT NULL,
55053
+ value_type SMALLINT NOT NULL
55054
+ )
55055
+ `,
55056
+ orElse: () => sql`
55057
+ CREATE TABLE IF NOT EXISTS ${table2} (
55058
+ id TEXT PRIMARY KEY,
55059
+ value BLOB NOT NULL,
55060
+ value_type INTEGER NOT NULL
55061
+ )
55062
+ `
55063
+ }).pipe(orDie3);
55064
+ const upsert = sql.onDialectOrElse({
55065
+ pg: () => (entry) => sql`
55066
+ INSERT INTO ${table2} (id, value, value_type) VALUES (${entry.id}, ${entry.value}, ${entry.value_type})
55067
+ ON CONFLICT (id) DO UPDATE SET value=EXCLUDED.value, value_type=EXCLUDED.value_type
55068
+ `.unprepared,
55069
+ mysql: () => (entry) => sql`
55070
+ INSERT INTO ${table2} (id, value, value_type) VALUES (${entry.id}, ${entry.value}, ${entry.value_type})
55071
+ ON DUPLICATE KEY UPDATE value=VALUES(value), value_type=VALUES(value_type)
55072
+ `,
55073
+ mssql: () => (entry) => sql`
55074
+ MERGE ${table2} AS target
55075
+ USING (SELECT ${entry.id} AS id, ${entry.value} AS value, ${entry.value_type} AS value_type) AS source
55076
+ ON target.id = source.id
55077
+ WHEN MATCHED THEN UPDATE SET value = source.value, value_type = source.value_type
55078
+ WHEN NOT MATCHED THEN INSERT (id, value, value_type)
55079
+ VALUES (source.id, source.value, source.value_type);
55080
+ `,
55081
+ orElse: () => (entry) => sql`
55082
+ INSERT INTO ${table2} (id, value, value_type) VALUES (${entry.id}, ${entry.value}, ${entry.value_type})
55083
+ ON CONFLICT(id) DO UPDATE SET value=excluded.value, value_type=excluded.value_type
55084
+ `.unprepared
55085
+ });
55086
+ const encoder8 = new TextEncoder;
55087
+ const decoder5 = new TextDecoder;
55088
+ const ValueTypeString = 0;
55089
+ const ValueTypeUint8Array = 1;
55090
+ return make69({
55091
+ get: (key2) => sql`SELECT value, value_type FROM ${table2} WHERE id = ${key2}`.pipe(mapError4((cause) => new KeyValueStoreError({
55092
+ method: "get",
55093
+ key: key2,
55094
+ message: `Unable to get item with key ${key2}`,
55095
+ cause
55096
+ })), flatMap6((rows) => {
55097
+ if (rows.length === 0) {
55098
+ return undefined_2;
55099
+ }
55100
+ const row = rows[0];
55101
+ switch (row.value_type) {
55102
+ case ValueTypeString:
55103
+ return succeed6(decoder5.decode(row.value));
55104
+ case ValueTypeUint8Array:
55105
+ return succeed6(encode2(row.value));
55106
+ default:
55107
+ return fail6(new KeyValueStoreError({
55108
+ method: "get",
55109
+ key: key2,
55110
+ message: `Invalid stored value type for key ${key2}: ${row.value_type}`
55111
+ }));
55112
+ }
55113
+ })),
55114
+ getUint8Array: (key2) => sql`SELECT value, value_type FROM ${table2} WHERE id = ${key2}`.pipe(mapError4((cause) => new KeyValueStoreError({
55115
+ method: "getUint8Array",
55116
+ key: key2,
55117
+ message: `Unable to get item with key ${key2}`,
55118
+ cause
55119
+ })), flatMap6((rows) => {
55120
+ if (rows.length === 0) {
55121
+ return undefined_2;
55122
+ }
55123
+ const row = rows[0];
55124
+ switch (row.value_type) {
55125
+ case ValueTypeString:
55126
+ return succeed6(row.value);
55127
+ case ValueTypeUint8Array:
55128
+ return succeed6(row.value);
55129
+ default:
55130
+ return fail6(new KeyValueStoreError({
55131
+ method: "getUint8Array",
55132
+ key: key2,
55133
+ message: `Invalid stored value type for key ${key2}: ${row.value_type}`
55134
+ }));
55135
+ }
55136
+ })),
55137
+ set: (key2, value5) => upsert({
55138
+ id: key2,
55139
+ value: typeof value5 === "string" ? encoder8.encode(value5) : value5,
55140
+ value_type: typeof value5 === "string" ? ValueTypeString : ValueTypeUint8Array
55141
+ }).pipe(mapError4((cause) => new KeyValueStoreError({
55142
+ method: "set",
55143
+ key: key2,
55144
+ message: `Unable to set item with key ${key2}`,
55145
+ cause
55146
+ })), asVoid4),
55147
+ remove: (key2) => sql`DELETE FROM ${table2} WHERE id = ${key2}`.pipe(mapError4((cause) => new KeyValueStoreError({
55148
+ method: "remove",
55149
+ key: key2,
55150
+ message: `Unable to remove item with key ${key2}`,
55151
+ cause
55152
+ })), asVoid4),
55153
+ clear: sql`DELETE FROM ${table2}`.pipe(mapError4((cause) => new KeyValueStoreError({
55154
+ method: "clear",
55155
+ message: `Unable to clear storage`,
55156
+ cause
55157
+ })), asVoid4),
55158
+ size: sql`SELECT COUNT(*) as count FROM ${table2}`.pipe(mapError4((cause) => new KeyValueStoreError({
55159
+ method: "size",
55160
+ message: `Unable to get size`,
55161
+ cause
55162
+ })), map9((rows) => rows.length === 0 ? 0 : Number(rows[0].count)))
55163
+ });
55164
+ }));
55165
+ var SchemaStoreTypeId = "~effect/persistence/KeyValueStore/SchemaStore";
55166
+ var toSchemaStore = (self, schema2) => {
55167
+ const serializer = toCodecJson2(schema2);
55168
+ const jsonSchema2 = fromJsonString2(serializer);
55169
+ const decode7 = decodeEffect2(jsonSchema2);
55170
+ const encode6 = encodeEffect2(jsonSchema2);
55171
+ const get22 = (key2) => flatMap6(self.get(key2), match10({
55172
+ onUndefined: () => succeedNone3,
55173
+ onDefined: (value5) => asSome2(decode7(value5))
55174
+ }));
55175
+ const set9 = (key2, value5) => flatMap6(encode6(value5), (json5) => self.set(key2, json5));
55176
+ const modify6 = (key2, f) => flatMap6(get22(key2), (o) => {
55177
+ if (isNone2(o)) {
55178
+ return succeedNone3;
55179
+ }
55180
+ const newValue = f(o.value);
55181
+ return as3(set9(key2, newValue), some3(newValue));
55182
+ });
55183
+ return {
55184
+ [SchemaStoreTypeId]: SchemaStoreTypeId,
55185
+ get: get22,
55186
+ set: set9,
55187
+ modify: modify6,
55188
+ remove: self.remove,
55189
+ clear: self.clear,
55190
+ size: self.size,
55191
+ has: self.has,
55192
+ isEmpty: self.isEmpty
55193
+ };
55194
+ };
55195
+ var layerStorage = (evaluate2) => sync2(KeyValueStore)(() => {
55196
+ const storage = evaluate2();
55197
+ return makeStringOnly({
55198
+ get: (key2) => try_3({
55199
+ try: () => storage.getItem(key2) ?? undefined,
55200
+ catch: (cause) => new KeyValueStoreError({
55201
+ key: key2,
55202
+ method: "get",
55203
+ message: `Unable to get item with key ${key2}`,
55204
+ cause
55205
+ })
55206
+ }),
55207
+ set: (key2, value5) => try_3({
55208
+ try: () => storage.setItem(key2, value5),
55209
+ catch: (cause) => new KeyValueStoreError({
55210
+ key: key2,
55211
+ method: "set",
55212
+ message: `Unable to set item with key ${key2}`,
55213
+ cause
55214
+ })
55215
+ }),
55216
+ remove: (key2) => try_3({
55217
+ try: () => storage.removeItem(key2),
55218
+ catch: (cause) => new KeyValueStoreError({
55219
+ key: key2,
55220
+ method: "remove",
55221
+ message: `Unable to remove item with key ${key2}`,
55222
+ cause
55223
+ })
55224
+ }),
55225
+ clear: try_3({
55226
+ try: () => storage.clear(),
55227
+ catch: (cause) => new KeyValueStoreError({
55228
+ method: "clear",
55229
+ message: `Unable to clear storage`,
55230
+ cause
55231
+ })
55232
+ }),
55233
+ size: try_3({
55234
+ try: () => storage.length,
55235
+ catch: (cause) => new KeyValueStoreError({
55236
+ method: "size",
55237
+ message: `Unable to get size`,
55238
+ cause
55239
+ })
55240
+ })
55241
+ });
55242
+ });
55243
+ // ../core/src/Storage/EdgeSync.ts
55244
+ var TableName = exports_Schema.NonEmptyString.pipe(exports_Schema.brand("EdgeSyncTableName")).annotate({
55245
+ identifier: "EdgeSyncTableName"
55246
+ });
55247
+ var IdColumn = exports_Schema.NonEmptyString.pipe(exports_Schema.brand("EdgeSyncIdColumn")).annotate({
55248
+ identifier: "EdgeSyncIdColumn"
55249
+ });
55250
+ var LIVE_PASS = Millis.make(60 * 1000);
55251
+ var GRACE = Millis.make(3 * 60 * 1000);
55252
+ var BATCH = 100;
55253
+ var KEPT_FOR_LAST = 25;
55254
+ var RUN_BUDGET = Millis.make(30 * 1000);
55255
+ var KV_WAIT = Millis.make(10 * 1000);
55256
+
55257
+ class RetryError extends exports_Schema.TaggedError()("EdgeSyncRetryError", {
55258
+ table: TableName,
55259
+ reason: exports_Schema.Literals(["Unavailable"]),
55260
+ cause: exports_Schema.Defect()
55261
+ }) {
55262
+ }
55263
+ var put4 = exports_Effect.fn("EdgeSync.put")(function* (write3, deadline) {
55264
+ yield* exports_Effect.annotateCurrentSpan({ key: write3.key });
55265
+ const kv = yield* exports_KeyValueStore.KeyValueStore;
55266
+ const attempt2 = exports_Effect.gen(function* () {
55267
+ if ((yield* now3) >= deadline) {
55268
+ return yield* new exports_Cause.TimeoutError("A KV write wasn't sent within LIVE_PASS of its read");
55269
+ }
55270
+ yield* kv.set(write3.key, write3.value).pipe(exports_Effect.timeout(exports_Duration.millis(KV_WAIT)));
55271
+ });
55272
+ yield* attempt2.pipe(exports_Effect.retry({
55273
+ schedule: exports_Schedule.spaced("1 second"),
55274
+ times: 3,
55275
+ while: () => exports_Effect.map(now3, (now4) => now4 < deadline)
55276
+ }));
55277
+ });
55278
+ var Recorded = exports_Schema.Int.pipe(exports_Schema.brand("EdgeSyncRecorded")).annotate({ identifier: "EdgeSyncRecorded" });
55279
+ var Due = exports_Schema.Boolean.pipe(exports_Schema.brand("EdgeSyncDue")).annotate({ identifier: "EdgeSyncDue" });
55280
+ var Pending2 = exports_Schema.Struct({
55281
+ recorded: Recorded,
55282
+ due: Due
55283
+ }).annotate({ identifier: "EdgeSyncPending" });
55284
+ var isDue = (sql) => sql`s.changed_at + ${GRACE} * interval '1 millisecond' <= clock_timestamp()`;
55285
+ var make70 = (table2, kvWriteOf) => {
55286
+ const ids = (statement2) => exports_SqlSchema.findAll({
55287
+ Request: exports_Schema.Void,
55288
+ Result: exports_Schema.Struct({ id: table2.Id }),
55289
+ execute: () => statement2
55290
+ })(undefined).pipe(exports_Effect.map(exports_Array.map(({ id: id2 }) => id2)), exports_Effect.catchTag("SchemaError", exports_Effect.die));
55291
+ const record3 = exports_Effect.fn("EdgeSync.record")(function* (changed) {
55292
+ yield* exports_Effect.annotateCurrentSpan({ table: table2.name, ids: changed.length });
55293
+ if (changed.length === 0)
55294
+ return;
55295
+ const sql = yield* exports_SqlClient.SqlClient;
55296
+ yield* sql`
55297
+ INSERT INTO ${sql(table2.name)} AS s (${sql(table2.id)}, changed_at, attempted_at)
55298
+ SELECT x.id, clock_timestamp(), clock_timestamp()
55299
+ FROM (VALUES ${sql.csv(changed.map((id2) => sql`(${id2})`))}) AS x (id)
55300
+ ON CONFLICT (${sql(table2.id)}) DO UPDATE
55301
+ SET recorded = s.recorded + 1, changed_at = clock_timestamp(), synced_at = NULL
55302
+ `;
55303
+ });
55304
+ const syncOne = exports_Effect.fn("EdgeSync.syncOne")(function* (id2) {
55305
+ yield* exports_Effect.annotateCurrentSpan({ table: table2.name, id: id2 });
55306
+ const sql = yield* exports_SqlClient.SqlClient;
55307
+ const deadline = EpochMillis.make((yield* now3) + LIVE_PASS);
55308
+ const row = yield* exports_SqlSchema.findOneOption({
55309
+ Request: table2.Id,
55310
+ Result: Pending2,
55311
+ execute: (request3) => sql`
55312
+ SELECT s.recorded, ${isDue(sql)} AS due
55313
+ FROM ${sql(table2.name)} s
55314
+ WHERE s.${sql(table2.id)} = ${request3}
55315
+ `
55316
+ })(id2).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
55317
+ if (exports_Option.isNone(row))
55318
+ return;
55319
+ const { due, recorded } = row.value;
55320
+ const write3 = yield* kvWriteOf(id2);
55321
+ if (exports_Option.isSome(write3))
55322
+ yield* put4(write3.value, deadline);
55323
+ const where = sql`${sql(table2.id)} = ${id2} AND recorded = ${recorded}`;
55324
+ yield* due ? sql`DELETE FROM ${sql(table2.name)} WHERE ${where}` : sql`UPDATE ${sql(table2.name)} SET synced_at = now() WHERE ${where}`;
55325
+ });
55326
+ const syncAll = (pending, until) => exports_Effect.map(exports_Effect.forEach(pending, (id2) => exports_Effect.flatMap(now3, (now4) => until !== undefined && now4 >= until ? exports_Effect.succeedNone : exports_Effect.asSome(exports_Effect.map(exports_Effect.exit(syncOne(id2)), (exit3) => ({ id: id2, exit: exit3 })))), { concurrency: 4 }), exports_Array.getSomes);
55327
+ const failures = (synced) => synced.filter(({ exit: exit3 }) => exports_Exit.isFailure(exit3));
55328
+ const syncNow = exports_Effect.fn("EdgeSync.syncNow")(function* (changed) {
55329
+ yield* exports_Effect.annotateCurrentSpan({ table: table2.name, ids: changed.length });
55330
+ const failed = failures(yield* syncAll(changed));
55331
+ if (failed.length > 0) {
55332
+ yield* exports_Effect.logWarning("KV entries weren't synced; the retry syncs them", {
55333
+ table: table2.name,
55334
+ failed: failed.length,
55335
+ cause: failed[0]?.exit
55336
+ });
55337
+ }
55338
+ });
55339
+ const nextBatch = exports_Effect.fn("EdgeSync.nextBatch")(function* () {
55340
+ const sql = yield* exports_SqlClient.SqlClient;
55341
+ const oldest = (where) => ids(sql`
55342
+ SELECT s.${sql(table2.id)} AS id FROM ${sql(table2.name)} s
55343
+ WHERE ${where}
55344
+ ORDER BY s.attempted_at, s.${sql(table2.id)}
55345
+ LIMIT ${BATCH}
55346
+ FOR UPDATE SKIP LOCKED
55347
+ `);
55348
+ return yield* exports_Effect.gen(function* () {
55349
+ const unsynced = yield* oldest(sql`s.synced_at IS NULL`);
55350
+ const last2 = yield* oldest(sql`s.synced_at IS NOT NULL AND ${isDue(sql)}`);
55351
+ const first = unsynced.slice(0, BATCH - Math.min(KEPT_FOR_LAST, last2.length));
55352
+ const batch = [...first, ...last2.slice(0, BATCH - first.length)];
55353
+ if (batch.length > 0) {
55354
+ yield* sql`UPDATE ${sql(table2.name)} SET attempted_at = now() WHERE ${sql(table2.id)} IN ${sql.in(batch)}`;
55355
+ }
55356
+ yield* exports_Effect.annotateCurrentSpan({ table: table2.name, ids: batch.length });
55357
+ return batch;
55358
+ }).pipe(sql.withTransaction);
55359
+ });
55360
+ const retry6 = exports_Effect.gen(function* () {
55361
+ const until = EpochMillis.make((yield* now3) + RUN_BUDGET);
55362
+ let synced = 0;
55363
+ let kept = [];
55364
+ while (true) {
55365
+ const batch = yield* nextBatch();
55366
+ const outcomes = yield* syncAll(batch, until);
55367
+ const failed = failures(outcomes);
55368
+ synced += outcomes.length - failed.length;
55369
+ kept = failed;
55370
+ if (outcomes.length < BATCH || failed.length === outcomes.length)
55371
+ break;
55372
+ }
55373
+ if (synced > 0)
55374
+ yield* exports_Effect.logDebug("Synced KV entries", { table: table2.name, synced });
55375
+ if (kept.length > 0) {
55376
+ yield* exports_Effect.logError("KV refuses to sync entries; they are retried", {
55377
+ table: table2.name,
55378
+ kept: kept.length,
55379
+ cause: kept[0]?.exit
55380
+ });
55381
+ }
55382
+ }).pipe(exports_Effect.mapError((cause) => new RetryError({ table: table2.name, reason: "Unavailable", cause })), exports_Effect.withSpan("EdgeSync.retry", { attributes: { table: table2.name } }));
55383
+ return { record: record3, syncNow, retry: retry6 };
55384
+ };
55385
+
55386
+ // ../core/src/Billing/Ledger.ts
55387
+ var SignedUsd = exports_Schema.BigDecimalFromString.pipe(exports_Schema.brand("SignedUsd")).annotate({
55388
+ identifier: "SignedUsd"
55389
+ });
55390
+ var MAX_DECIMAL_PLACES = 12;
55391
+ var AMOUNT_CEILING = exports_BigDecimal.fromBigInt(10n ** 12n);
55392
+ var Amount = exports_Schema.BigDecimalFromString.check(exports_Schema.makeFilter((amount) => !exports_BigDecimal.isZero(amount) || "a non-zero amount"), exports_Schema.makeFilter((amount) => exports_BigDecimal.isLessThan(exports_BigDecimal.abs(amount), AMOUNT_CEILING) || "under 1000000000000 either way"), exports_Schema.makeFilter((amount) => exports_BigDecimal.normalize(amount).scale <= MAX_DECIMAL_PLACES || `at most ${MAX_DECIMAL_PLACES} decimal places`)).pipe(exports_Schema.brand("CreditAmount")).annotate({ identifier: "CreditAmount" });
55393
+ var Note2 = exports_Schema.Trimmed.check(exports_Schema.isNonEmpty()).pipe(exports_Schema.brand("CreditNote")).annotate({
55394
+ identifier: "CreditNote"
55395
+ });
55396
+ var Seq = exports_Schema.Int.check(exports_Schema.isGreaterThan(0)).pipe(exports_Schema.brand("CreditSeq")).annotate({
55397
+ identifier: "CreditSeq"
55398
+ });
55399
+ var Event2 = exports_Schema.TaggedUnion({
55400
+ Grant: { note: Note2, actor: Actor },
55401
+ Correction: { note: Note2, actor: Actor },
55402
+ Usage: { line: Line, priceId: exports_Schema.optional(PriceId), charge: Usd }
55403
+ }).annotate({ identifier: "CreditEvent" });
55404
+ var Entry2 = exports_Schema.Struct({
55405
+ org: OrgId,
55406
+ seq: Seq,
55407
+ at: EpochMillis,
55408
+ event: Event2,
55409
+ amount: SignedUsd,
55410
+ balanceAfter: SignedUsd
55411
+ }).annotate({ identifier: "CreditEntry" });
55412
+ var Credited = Entry2.mapFields((fields3) => ({
55413
+ ...fields3,
55414
+ event: exports_Schema.Union([Event2.cases.Grant, Event2.cases.Correction])
55415
+ })).annotate({ identifier: "CreditedEntry" });
55416
+ var eventOf = (amount, note, actor) => exports_BigDecimal.isPositive(amount) ? Event2.cases.Grant.make({ note, actor }) : Event2.cases.Correction.make({ note, actor });
55417
+ var CreditedRow = Credited.mapFields((fields3) => ({ ...fields3, at: Timestamp }));
55418
+ var selected2 = (sql) => sql`org_id AS org, seq::float8 AS seq, at, event, amount::text AS amount, balance_after::text AS "balanceAfter"`;
55419
+ var encodeAt = exports_Schema.encodeSync(Timestamp);
55420
+ var encodeEvent = exports_Schema.encodeSync(exports_Schema.fromJsonString(Event2));
55421
+ var encodeAmount = exports_Schema.encodeSync(Amount);
55422
+ var add7 = exports_Effect.fn("Ledger.add")(function* (outbox, org, amount, note, actor) {
55423
+ yield* exports_Effect.annotateCurrentSpan({ org, actor });
55424
+ const sql = yield* exports_SqlClient.SqlClient;
55425
+ const at = yield* now3;
55426
+ const moved = encodeAmount(amount);
55427
+ return yield* sql.withTransaction(exports_Effect.gen(function* () {
55428
+ if (exports_Option.isNone(yield* lock(org)))
55429
+ return yield* new NotFound({ org });
55430
+ yield* sql`
55431
+ INSERT INTO org_credit (org_id, balance) VALUES (${org}, ${moved}::numeric)
55432
+ ON CONFLICT (org_id) DO UPDATE SET balance = org_credit.balance + excluded.balance
55433
+ `;
55434
+ const entry = yield* exports_SqlSchema.findOne({
55435
+ Request: exports_Schema.Void,
55436
+ Result: CreditedRow,
55437
+ execute: () => sql`
55438
+ INSERT INTO credit_events (org_id, seq, at, event, amount, balance_after)
55439
+ SELECT ${org}, coalesce((SELECT max(seq) FROM credit_events WHERE org_id = ${org}), 0) + 1,
55440
+ ${encodeAt(at)}, ${encodeEvent(eventOf(amount, note, actor))}::jsonb, ${moved}::numeric, c.balance
55441
+ FROM org_credit c WHERE c.org_id = ${org}
55442
+ RETURNING ${selected2(sql)}
55443
+ `
55444
+ })(undefined).pipe(exports_Effect.catchTags({ SchemaError: exports_Effect.die, NoSuchElementError: exports_Effect.die }));
55445
+ yield* outbox.record([org]);
55446
+ return entry;
55447
+ }));
55448
+ });
55449
+ var Balance = exports_Schema.Struct({ balance: SignedUsd });
55450
+ var balance = exports_Effect.fn("Ledger.balance")(function* (org) {
55451
+ const sql = yield* exports_SqlClient.SqlClient;
55452
+ const found = yield* exports_SqlSchema.findOne({
55453
+ Request: OrgId,
55454
+ Result: Balance,
55455
+ execute: (request3) => sql`SELECT coalesce((SELECT balance FROM org_credit WHERE org_id = ${request3}), 0)::text AS balance`
55456
+ })(org).pipe(exports_Effect.catchTags({ SchemaError: exports_Effect.die, NoSuchElementError: exports_Effect.die }));
55457
+ return found.balance;
55458
+ });
55459
+ var Totals = exports_Schema.Struct({
55460
+ balance: SignedUsd,
55461
+ added: SignedUsd,
55462
+ spent: Usd
55463
+ }).annotate({ identifier: "CreditTotals" });
55464
+ var Sums = Totals.mapFields(exports_Struct.pick(["balance", "added"]));
55465
+ var totals = exports_Effect.fn("Ledger.totals")(function* (org) {
55466
+ const sql = yield* exports_SqlClient.SqlClient;
55467
+ const sums = yield* exports_SqlSchema.findOneOption({
55468
+ Request: OrgId,
55469
+ Result: Sums,
55470
+ execute: (request3) => sql`
55471
+ SELECT coalesce(c.balance, 0)::text AS balance,
55472
+ coalesce((
55473
+ SELECT sum(e.amount) FROM credit_events e WHERE e.org_id = o.id AND e.kind IN ('Grant', 'Correction')
55474
+ ), 0)::text AS added
55475
+ FROM orgs o LEFT JOIN org_credit c ON c.org_id = o.id
55476
+ WHERE o.id = ${request3}
55477
+ `
55478
+ })(org).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
55479
+ if (exports_Option.isNone(sums))
55480
+ return yield* new NotFound({ org });
55481
+ return {
55482
+ ...sums.value,
55483
+ spent: Usd.make(exports_BigDecimal.subtract(sums.value.added, sums.value.balance))
55484
+ };
55485
+ });
55486
+ var PAGE = 50;
55487
+ var history = exports_Effect.fn("Ledger.history")(function* (org, before) {
55488
+ const sql = yield* exports_SqlClient.SqlClient;
55489
+ return yield* exports_SqlSchema.findAll({
55490
+ Request: OrgId,
55491
+ Result: CreditedRow,
55492
+ execute: (request3) => sql`
55493
+ SELECT ${selected2(sql)} FROM credit_events
55494
+ WHERE ${sql.and([
55495
+ sql`org_id = ${request3}`,
55496
+ sql`kind IN ('Grant', 'Correction')`,
55497
+ ...before === undefined ? [] : [sql`seq < ${before}`]
55498
+ ])}
55499
+ ORDER BY seq DESC LIMIT ${PAGE}
55500
+ `
55501
+ })(org).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
55502
+ });
55503
+ var zero4 = exports_BigDecimal.fromBigInt(0n);
55504
+ var encodeSigned = exports_Schema.encodeSync(SignedUsd);
55505
+ var encodeUsd = exports_Schema.encodeSync(Usd);
55506
+ var freshOf = (lines2, logged) => {
55507
+ const seen = new Set(logged);
55508
+ const fresh2 = [];
55509
+ for (const line of lines2) {
55510
+ if (seen.has(line.callId))
55511
+ continue;
55512
+ seen.add(line.callId);
55513
+ fresh2.push(line);
55514
+ }
55515
+ return fresh2;
55516
+ };
55517
+ var chargedOf = (line, row) => ({
55518
+ line,
55519
+ row,
55520
+ charge: chargeAt(line.tokens, row)
55521
+ });
55522
+ var usageOf = (org, seq, before, charged) => {
55523
+ let balanceAfter = before;
55524
+ return charged.map(({ line, row, charge: charge3 }, index2) => {
55525
+ const amount = line.burns ? exports_BigDecimal.negate(charge3) : zero4;
55526
+ balanceAfter = exports_BigDecimal.sum(balanceAfter, amount);
55527
+ return {
55528
+ org,
55529
+ seq: Seq.make(seq + index2),
55530
+ at: line.at,
55531
+ event: Event2.cases.Usage.make({ line, priceId: row?.id, charge: charge3 }),
55532
+ amount: SignedUsd.make(amount),
55533
+ balanceAfter: SignedUsd.make(balanceAfter)
55534
+ };
55535
+ });
55536
+ };
55537
+ var isCalendarDay = (text3) => {
55538
+ const at = Date.parse(text3);
55539
+ return !Number.isNaN(at) && new Date(at).toISOString().slice(0, 10) === text3;
55540
+ };
55541
+ var Day2 = exports_Schema.String.check(exports_Schema.isPattern(/^\d{4}-\d{2}-\d{2}$/), exports_Schema.makeFilter((text3) => isCalendarDay(text3) || "a calendar day")).pipe(exports_Schema.brand("Day")).annotate({ identifier: "Day" });
55542
+ var dayOf = (at) => Day2.make(exports_DateTime.formatIsoDateUtc(toDateTime(at)));
55543
+ var SpendDay = exports_Schema.Struct({
55544
+ day: Day2,
55545
+ model: ModelId,
55546
+ amount: Usd,
55547
+ tokens: Tokens
55548
+ }).annotate({ identifier: "SpendDay" });
55549
+ var addTokens = (a, b) => ({
55550
+ input: TokenCount.make(a.input + b.input),
55551
+ output: TokenCount.make(a.output + b.output),
55552
+ cacheRead: TokenCount.make(a.cacheRead + b.cacheRead),
55553
+ cacheWrite: TokenCount.make(a.cacheWrite + b.cacheWrite)
55554
+ });
55555
+ var noTokens = {
55556
+ input: TokenCount.make(0),
55557
+ output: TokenCount.make(0),
55558
+ cacheRead: TokenCount.make(0),
55559
+ cacheWrite: TokenCount.make(0)
55560
+ };
55561
+ var spentOf = (charged) => {
55562
+ const days2 = new Map;
55563
+ for (const { line, charge: charge3 } of charged) {
55564
+ if (!line.burns || line.tokens === undefined)
55565
+ continue;
55566
+ const day = dayOf(line.at);
55567
+ const key2 = `${day} ${line.model}`;
55568
+ const before = days2.get(key2) ?? { day, model: line.model, amount: Usd.make(zero4), tokens: noTokens };
55569
+ days2.set(key2, {
55570
+ ...before,
55571
+ amount: Usd.make(exports_BigDecimal.sum(before.amount, charge3)),
55572
+ tokens: addTokens(before.tokens, line.tokens)
55573
+ });
55574
+ }
55575
+ return [...days2.values()];
55576
+ };
55577
+ var Logged = exports_Schema.Struct({ callId: CallId });
55578
+ var append5 = exports_Effect.fn("Ledger.append")(function* (outbox, batch) {
55579
+ const { org, lines: lines2 } = batch;
55580
+ yield* exports_Effect.annotateCurrentSpan({ org, lines: lines2.length });
55581
+ const sql = yield* exports_SqlClient.SqlClient;
55582
+ return yield* sql.withTransaction(exports_Effect.gen(function* () {
55583
+ if (exports_Option.isNone(yield* lock(org))) {
55584
+ yield* exports_Effect.logWarning("Ledger.append: the org is gone, so its lines are dropped", { org });
55585
+ return [];
55586
+ }
55587
+ const logged = lines2.length === 0 ? [] : yield* exports_SqlSchema.findAll({
55588
+ Request: exports_Schema.Void,
55589
+ Result: Logged,
55590
+ execute: () => sql`SELECT call_id AS "callId" FROM credit_events WHERE call_id IN ${sql.in(lines2.map((l) => l.callId))}`
55591
+ })(undefined).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
55592
+ const fresh2 = freshOf(lines2, new Set(logged.map(({ callId }) => callId)));
55593
+ if (fresh2.length === 0)
55594
+ return [];
55595
+ const prices = yield* inEffect(fresh2.map(({ model, at }) => ({ model, at })));
55596
+ const next4 = yield* exports_SqlSchema.findOne({
55597
+ Request: OrgId,
55598
+ Result: exports_Schema.Struct({ seq: exports_Schema.Int }),
55599
+ execute: (request3) => sql`SELECT (coalesce(max(seq), 0) + 1)::int AS seq FROM credit_events WHERE org_id = ${request3}`
55600
+ })(org).pipe(exports_Effect.catchTags({ SchemaError: exports_Effect.die, NoSuchElementError: exports_Effect.die }));
55601
+ const charged = fresh2.map((line, index2) => chargedOf(line, prices[index2]));
55602
+ const unpriced = charged.flatMap(({ line, row }) => row === undefined ? [line.model] : []);
55603
+ if (unpriced.length > 0) {
55604
+ yield* exports_Effect.logWarning("Ledger.append: calls to a model with no price are charged nothing", { org, unpriced });
55605
+ }
55606
+ const entries3 = usageOf(org, next4.seq, yield* balance(org), charged);
55607
+ yield* sql`
55608
+ INSERT INTO credit_events ${sql.insert(entries3.map((entry) => ({
55609
+ org_id: org,
55610
+ seq: entry.seq,
55611
+ at: encodeAt(entry.at),
55612
+ event: encodeEvent(entry.event),
55613
+ amount: encodeSigned(entry.amount),
55614
+ balance_after: encodeSigned(entry.balanceAfter)
55615
+ })))}
55616
+ `;
55617
+ const spent = spentOf(charged);
55618
+ if (spent.length > 0) {
55619
+ yield* sql`
55620
+ INSERT INTO usage_days ${sql.insert(spent.map(({ day, model, amount, tokens }) => ({
55621
+ org_id: org,
55622
+ day,
55623
+ model_id: model,
55624
+ amount: encodeUsd(amount),
55625
+ input: tokens.input,
55626
+ output: tokens.output,
55627
+ cache_read: tokens.cacheRead,
55628
+ cache_write: tokens.cacheWrite
55629
+ })))}
55630
+ ON CONFLICT (org_id, day, model_id) DO UPDATE SET
55631
+ amount = usage_days.amount + excluded.amount,
55632
+ input = usage_days.input + excluded.input,
55633
+ output = usage_days.output + excluded.output,
55634
+ cache_read = usage_days.cache_read + excluded.cache_read,
55635
+ cache_write = usage_days.cache_write + excluded.cache_write
55636
+ `;
55637
+ }
55638
+ const moved = entries3.reduce((sum4, { amount }) => exports_BigDecimal.sum(sum4, amount), zero4);
55639
+ yield* sql`
55640
+ INSERT INTO org_credit (org_id, balance) VALUES (${org}, ${encodeSigned(SignedUsd.make(moved))}::numeric)
55641
+ ON CONFLICT (org_id) DO UPDATE SET balance = org_credit.balance + excluded.balance
55642
+ `;
55643
+ yield* outbox.record([org]);
55644
+ return entries3;
55645
+ }));
55646
+ });
55647
+ var SPEND_DAYS = 30;
55648
+ var spend = exports_Effect.fn("Ledger.spend")(function* (org, from, to) {
55649
+ const sql = yield* exports_SqlClient.SqlClient;
55650
+ const end3 = to === undefined ? toDateTime(yield* now3) : exports_DateTime.makeUnsafe(Date.parse(to));
55651
+ const last2 = Day2.make(exports_DateTime.formatIsoDateUtc(end3));
55652
+ const first = from ?? Day2.make(exports_DateTime.formatIsoDateUtc(exports_DateTime.subtract(end3, { days: SPEND_DAYS - 1 })));
55653
+ return yield* exports_SqlSchema.findAll({
55654
+ Request: OrgId,
55655
+ Result: SpendDay,
55656
+ execute: (request3) => sql`
55657
+ SELECT day::text AS day, model_id AS model, amount::text AS amount,
55658
+ jsonb_build_object(
55659
+ 'input', input, 'output', output, 'cacheRead', cache_read, 'cacheWrite', cache_write
55660
+ ) AS tokens
55661
+ FROM usage_days
55662
+ WHERE org_id = ${request3} AND day BETWEEN ${first}::date AND ${last2}::date
55663
+ ORDER BY day DESC, model_id
55664
+ `
55665
+ })(org).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
54674
55666
  });
54675
55667
 
54676
55668
  // ../core/src/Billing/ProviderKey.ts
@@ -54754,88 +55746,121 @@ var remove10 = exports_Effect.fn("ProviderKey.remove")(function* (org, upstream)
54754
55746
  });
54755
55747
 
54756
55748
  // ../core/src/Billing/Billing.ts
54757
- var Entry2 = exports_Schema.TaggedUnion({
55749
+ var Keys = exports_Schema.Record(UpstreamId, Sealed).pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed({})));
55750
+ var Blocked = exports_Schema.Boolean.pipe(exports_Schema.brand("BillingBlocked")).annotate({ identifier: "BillingBlocked" });
55751
+ var Entry3 = exports_Schema.TaggedUnion({
54758
55752
  Ambral: {},
54759
- Org: {
54760
- keys: exports_Schema.Record(UpstreamId, Sealed).pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed({})))
54761
- }
55753
+ Byok: { keys: Keys },
55754
+ Credits: { blocked: Blocked }
54762
55755
  }).annotate({ identifier: "BillingEntry" });
54763
55756
  var Payer = exports_Data.taggedEnum();
55757
+ var missing2 = Entry3.cases.Credits.make({ blocked: Blocked.make(true) });
54764
55758
  var entries3 = {
54765
- org: (keys5) => Entry2.cases.Org.make({ keys: keys5 }),
54766
- ambral: () => Entry2.cases.Ambral.make({})
55759
+ byok: (keys5) => Entry3.cases.Byok.make({ keys: keys5 }),
55760
+ credits: (_, blocked) => Entry3.cases.Credits.make({ blocked }),
55761
+ ambral: () => Entry3.cases.Ambral.make({})
54767
55762
  };
54768
- var entryOf = (billTo2, keys5) => entries3[billTo2](keys5);
55763
+ var entryOf = (billTo2, keys5, blocked) => entries3[billTo2](keys5, blocked);
54769
55764
  var payerOf = (entry, upstream) => exports_Match.valueTags(entry, {
54770
55765
  Ambral: () => exports_Result.succeed(Payer.Ambral()),
54771
- Org: ({ keys: keys5 }) => exports_Option.match(exports_Record.get(keys5, upstream), {
55766
+ Byok: ({ keys: keys5 }) => exports_Option.match(exports_Record.get(keys5, upstream), {
54772
55767
  onNone: () => exports_Result.fail(new KeyRequired({ upstream })),
54773
- onSome: (sealed) => exports_Result.succeed(Payer.Org({ sealed }))
54774
- })
55768
+ onSome: (sealed) => exports_Result.succeed(Payer.Byok({ sealed }))
55769
+ }),
55770
+ Credits: ({ blocked }) => blocked ? exports_Result.fail(new OutOfCredit) : exports_Result.succeed(Payer.Credits())
54775
55771
  });
55772
+ var isBlocked = (balance2, allowance) => Blocked.make(exports_BigDecimal.isLessThanOrEqualTo(balance2, exports_BigDecimal.negate(allowance)));
54776
55773
  var KV_PROPAGATION = exports_Duration.seconds(60);
54777
55774
  var KEPT_PAYING = exports_Duration.seconds(30);
54778
55775
  var KEPT_NOT_PAYING = exports_Duration.seconds(5);
54779
55776
  var lag = exports_Duration.sum(KV_PROPAGATION, exports_Duration.max(KEPT_PAYING, KEPT_NOT_PAYING));
54780
- var Stored3 = exports_Schema.fromJsonString(Entry2);
55777
+ var Org2 = exports_Schema.TaggedStruct("Org", { keys: Keys });
55778
+ var LegacyByok = Org2.pipe(exports_Schema.decodeTo(exports_Schema.toType(Entry3.cases.Byok), exports_SchemaTransformation.transform({
55779
+ decode: ({ keys: keys5 }) => Entry3.cases.Byok.make({ keys: keys5 }),
55780
+ encode: ({ keys: keys5 }) => Org2.make({ keys: keys5 })
55781
+ })));
55782
+ var Stored3 = exports_Schema.fromJsonString(exports_Schema.Union([Entry3, LegacyByok]));
54781
55783
  var encode6 = exports_Schema.encodeEffect(Stored3);
54782
55784
  var decode7 = exports_Schema.decodeEffect(Stored3);
54783
- var get21 = exports_Effect.fn("Billing.get")(function* (org) {
55785
+ var get22 = exports_Effect.fn("Billing.get")(function* (org) {
54784
55786
  const keys5 = yield* list3(org);
54785
- return entryOf(yield* billTo(org), Object.fromEntries(keys5.map(({ sealed, upstream }) => [upstream, sealed])));
55787
+ const { billTo: billTo2, allowance } = yield* get18(org);
55788
+ return entryOf(billTo2, Object.fromEntries(keys5.map(({ sealed, upstream }) => [upstream, sealed])), isBlocked(yield* balance(org), allowance));
54786
55789
  });
54787
- var project = exports_Effect.fn("Billing.project")(function* (org) {
54788
- yield* exports_Effect.annotateCurrentSpan({ org });
55790
+ var sync6 = make70({ name: TableName.make("billing_syncs"), id: IdColumn.make("org_id"), Id: OrgId }, exports_Effect.fnUntraced(function* (org) {
55791
+ const value5 = yield* encode6(yield* get22(org)).pipe(exports_Effect.orDie);
55792
+ return exports_Option.some({ key: kvKey.billing(org), value: KvValue.make(value5) });
55793
+ }));
55794
+ var setBillTo = exports_Effect.fn("Billing.setBillTo")(function* (org, billTo2, actor) {
54789
55795
  const sql = yield* exports_SqlClient.SqlClient;
54790
- const store = yield* exports_KeyValueStore.KeyValueStore;
54791
- yield* sql.withTransaction(exports_Effect.gen(function* () {
54792
- yield* sql`SELECT org_id FROM org_settings WHERE org_id = ${org} FOR UPDATE`;
54793
- const text3 = yield* encode6(yield* get21(org)).pipe(exports_Effect.orDie);
54794
- yield* store.set(kvKey.billing(org), text3);
54795
- }));
55796
+ const changed = yield* change(org, SetBillTo.make({ billTo: billTo2 }), actor).pipe(exports_Effect.tap(sync6.record([org])), sql.withTransaction);
55797
+ yield* sync6.syncNow([org]);
55798
+ return changed;
54796
55799
  });
54797
- var setBillTo = exports_Effect.fn("Billing.setBillTo")(function* (org, billTo2, actor) {
54798
- const changed = yield* change(org, SetBillTo.make({ billTo: billTo2 }), actor);
54799
- yield* project(org);
55800
+ var addCredit = exports_Effect.fn("Billing.addCredit")(function* (org, amount, note, actor) {
55801
+ const entry = yield* add7(sync6, org, amount, note, actor);
55802
+ yield* sync6.syncNow([org]);
55803
+ return entry;
55804
+ });
55805
+ var setAllowance = exports_Effect.fn("Billing.setAllowance")(function* (org, allowance, actor) {
55806
+ const sql = yield* exports_SqlClient.SqlClient;
55807
+ const changed = yield* change(org, SetAllowance.make({ allowance }), actor).pipe(exports_Effect.tap(sync6.record([org])), sql.withTransaction);
55808
+ yield* sync6.syncNow([org]);
54800
55809
  return changed;
54801
55810
  });
54802
55811
  var saveKey = exports_Effect.fn("Billing.saveKey")(function* (org, upstream, key2, actor) {
54803
55812
  yield* exports_Effect.annotateCurrentSpan({ org, upstream, actor });
55813
+ const sql = yield* exports_SqlClient.SqlClient;
54804
55814
  const label = yield* Providers.use((providers) => providers.check(upstream, key2));
54805
55815
  const sealed = yield* Seal.use((seal) => seal.seal(org, upstream, key2));
54806
- const stored = yield* save(org, upstream, sealed, label, actor);
54807
- yield* project(org);
55816
+ const stored = yield* save(org, upstream, sealed, label, actor).pipe(exports_Effect.tap(sync6.record([org])), sql.withTransaction);
55817
+ yield* sync6.syncNow([org]);
54808
55818
  return exports_Struct.omit(stored, ["org", "sealed"]);
54809
55819
  });
54810
55820
  var removeKey = exports_Effect.fn("Billing.removeKey")(function* (org, upstream) {
54811
55821
  yield* exports_Effect.annotateCurrentSpan({ org, upstream });
55822
+ const sql = yield* exports_SqlClient.SqlClient;
54812
55823
  const { all: all6 } = yield* Providers;
54813
55824
  if (!all6.some((provider) => provider.upstream === upstream))
54814
55825
  return yield* new NotFound5({ upstream });
54815
- yield* remove10(org, upstream);
54816
- yield* project(org);
55826
+ yield* remove10(org, upstream).pipe(exports_Effect.andThen(sync6.record([org])), sql.withTransaction);
55827
+ yield* sync6.syncNow([org]);
54817
55828
  });
54818
55829
  var Configured = exports_Schema.Struct({
54819
55830
  provider: Provider,
54820
55831
  key: exports_Schema.optional(Saved)
54821
55832
  }).annotate({ identifier: "BillingProvider" });
54822
- var Summary2 = exports_Schema.Struct({
54823
- billTo: BillTo,
54824
- providers: exports_Schema.Array(Configured)
55833
+ var Credit = exports_Schema.Struct({
55834
+ totals: Totals,
55835
+ allowance: Usd
55836
+ }).annotate({ identifier: "BillingCredit" });
55837
+ var creditOf = exports_Effect.fn("Billing.creditOf")(function* (org) {
55838
+ const { allowance } = yield* get18(org);
55839
+ return { totals: yield* totals(org), allowance };
55840
+ });
55841
+ var Summary2 = exports_Schema.TaggedUnion({
55842
+ Credits: { balance: SignedUsd },
55843
+ ProviderKeys: { providers: exports_Schema.Array(Configured) },
55844
+ Ambral: {}
54825
55845
  }).annotate({ identifier: "BillingSummary" });
54826
- var summaryOf = (billTo2, providers, stored) => ({
54827
- billTo: billTo2,
54828
- providers: providers.map((provider) => {
54829
- const key2 = stored.find(({ upstream }) => upstream === provider.upstream);
54830
- return compact2({
54831
- provider,
54832
- key: key2 === undefined ? undefined : exports_Struct.omit(key2, ["org", "sealed"])
54833
- });
54834
- })
55846
+ var providersOf = (providers, stored) => providers.map((provider) => {
55847
+ const key2 = stored.find(({ upstream }) => upstream === provider.upstream);
55848
+ return compact2({
55849
+ provider,
55850
+ key: key2 === undefined ? undefined : exports_Struct.omit(key2, ["org", "sealed"])
55851
+ });
54835
55852
  });
55853
+ var summaries = {
55854
+ credits: (org) => exports_Effect.map(balance(org), (balance2) => Summary2.cases.Credits.make({ balance: balance2 })),
55855
+ byok: exports_Effect.fnUntraced(function* (org) {
55856
+ const { all: all6 } = yield* Providers;
55857
+ return Summary2.cases.ProviderKeys.make({ providers: providersOf(all6, yield* list3(org)) });
55858
+ }),
55859
+ ambral: () => exports_Effect.succeed(Summary2.cases.Ambral.make({}))
55860
+ };
54836
55861
  var summary = exports_Effect.fn("Billing.summary")(function* (org) {
54837
- const { all: all6 } = yield* Providers;
54838
- return summaryOf(yield* billTo(org), all6, yield* list3(org));
55862
+ const { billTo: billTo2 } = yield* get18(org);
55863
+ return yield* summaries[billTo2](org);
54839
55864
  });
54840
55865
 
54841
55866
  // ../core/src/Model/Offer.ts
@@ -54844,20 +55869,28 @@ var check2 = (entry, stored) => {
54844
55869
  const refused = (reason) => new NotOffered({ model: model.id, upstream: model.base.upstream, reason });
54845
55870
  if (stored.withdrawn !== undefined)
54846
55871
  return exports_Result.fail(refused("Withdrawn"));
54847
- return exports_Result.mapBoth(payerOf(entry, model.base.upstream), {
54848
- onFailure: () => refused("KeyRequired"),
54849
- onSuccess: () => model
55872
+ return exports_Result.match(payerOf(entry, model.base.upstream), {
55873
+ onFailure: (refusal) => exports_Match.valueTags(refusal, {
55874
+ InferenceKeyRequired: () => exports_Result.fail(refused("KeyRequired")),
55875
+ InferenceOutOfCredit: () => exports_Result.succeed(model)
55876
+ }),
55877
+ onSuccess: () => exports_Result.succeed(model)
54850
55878
  });
54851
55879
  };
54852
55880
  var list4 = exports_Effect.fn("Offer.list")(function* (org) {
54853
55881
  yield* exports_Effect.annotateCurrentSpan({ org });
54854
- const entry = yield* get21(org);
54855
- return (yield* list2()).filter((model) => exports_Result.isSuccess(check2(entry, { model })));
55882
+ const entry = yield* get22(org);
55883
+ const offered = (yield* list2()).filter((model) => exports_Result.isSuccess(check2(entry, { model })));
55884
+ const prices = yield* latest(offered.map(({ id: id2 }) => id2));
55885
+ return offered.flatMap((model) => {
55886
+ const row = prices.get(model.id);
55887
+ return row === undefined ? [] : [{ model, price: row.price }];
55888
+ });
54856
55889
  });
54857
- var get22 = exports_Effect.fn("Offer.get")(function* (org, id2) {
55890
+ var get23 = exports_Effect.fn("Offer.get")(function* (org, id2) {
54858
55891
  yield* exports_Effect.annotateCurrentSpan({ org, model: id2 });
54859
55892
  const stored = yield* getStored(id2);
54860
- return yield* exports_Effect.fromResult(check2(yield* get21(org), stored));
55893
+ return yield* exports_Effect.fromResult(check2(yield* get22(org), stored));
54861
55894
  });
54862
55895
 
54863
55896
  // ../core/src/Route/RoutePublisher.ts
@@ -54950,7 +55983,7 @@ var applyChange = (pool, change2) => exports_Match.valueTags(change2, {
54950
55983
  }
54951
55984
  });
54952
55985
  var movesRoute = (before, after) => before.primary !== after.primary || before.baseline !== after.baseline;
54953
- var make70 = (org, input, id2) => ({
55986
+ var make71 = (org, input, id2) => ({
54954
55987
  id: id2,
54955
55988
  org,
54956
55989
  name: input.name,
@@ -55010,7 +56043,7 @@ var routeOf = (workload, catalog, version) => {
55010
56043
  };
55011
56044
  var currentRoute = exports_Effect.fnUntraced(function* (workload) {
55012
56045
  const pointers = new Set([workload.pool.primary, workload.pool.baseline]);
55013
- const catalog = yield* exports_Effect.forEach(pointers, (model) => get19(model));
56046
+ const catalog = yield* exports_Effect.forEach(pointers, (model) => get20(model));
55014
56047
  return yield* exports_Effect.fromResult(routeOf(workload, catalog, yield* historyLength(workload.id)));
55015
56048
  });
55016
56049
  var republish = exports_Effect.fnUntraced(function* (org, name) {
@@ -55024,13 +56057,13 @@ var republish = exports_Effect.fnUntraced(function* (org, name) {
55024
56057
  var create = exports_Effect.fn("Workload.create")(function* (org, input, actor) {
55025
56058
  const sql = yield* exports_SqlClient.SqlClient;
55026
56059
  const routes = yield* RoutePublisher;
55027
- const workload = make70(org, input, WorkloadId.make(yield* uuid));
56060
+ const workload = make71(org, input, WorkloadId.make(yield* uuid));
55028
56061
  const changeId = ChangeId.make(yield* uuid);
55029
56062
  yield* exports_Effect.annotateCurrentSpan({ org, workload: input.name, workloadId: workload.id });
55030
56063
  const at = yield* now3;
55031
56064
  let publishing = false;
55032
56065
  yield* sql.withTransaction(exports_Effect.gen(function* () {
55033
- const model = yield* get22(org, input.model);
56066
+ const model = yield* get23(org, input.model);
55034
56067
  const inserted = yield* sql`
55035
56068
  INSERT INTO workloads (id, org_id, name, primary_model_id, baseline_model_id)
55036
56069
  VALUES (${workload.id}, ${workload.org}, ${workload.name}, ${workload.pool.primary}, ${workload.pool.baseline})
@@ -55065,7 +56098,7 @@ var change2 = exports_Effect.fn("Workload.change")(function* (org, name, request
55065
56098
  const { id: id2, pool: before } = yield* lock2(org, name);
55066
56099
  const after = yield* exports_Effect.fromResult(applyChange(before, requested));
55067
56100
  yield* exports_Match.valueTags(requested, {
55068
- AddToPool: ({ model }) => get22(org, model).pipe(exports_Effect.andThen(sql`INSERT INTO workload_pool (workload_id, model_id) VALUES (${id2}, ${model})`)),
56101
+ AddToPool: ({ model }) => get23(org, model).pipe(exports_Effect.andThen(sql`INSERT INTO workload_pool (workload_id, model_id) VALUES (${id2}, ${model})`)),
55069
56102
  RemoveFromPool: ({ model }) => sql`DELETE FROM workload_pool WHERE workload_id = ${id2} AND model_id = ${model}`,
55070
56103
  SetPrimary: ({ model }) => sql`UPDATE workloads SET primary_model_id = ${model}, baseline_model_id = ${model} WHERE id = ${id2}`
55071
56104
  });
@@ -55087,7 +56120,7 @@ var select = (sql, filter15) => sql`
55087
56120
  ${filter15.id === undefined ? sql`` : sql`AND w.id = ${filter15.id}`}
55088
56121
  ORDER BY w.name
55089
56122
  `;
55090
- var get23 = exports_Effect.fn("Workload.get")(function* (org, name) {
56123
+ var get24 = exports_Effect.fn("Workload.get")(function* (org, name) {
55091
56124
  yield* exports_Effect.annotateCurrentSpan({ org, workload: name });
55092
56125
  const sql = yield* exports_SqlClient.SqlClient;
55093
56126
  const found = yield* exports_SqlSchema.findOneOption({
@@ -55151,6 +56184,7 @@ var RouteRequest = exports_Schema.Struct({
55151
56184
  }).annotate({ identifier: "RouteRequest" });
55152
56185
  var decodeHeaders = exports_Schema.decodeUnknownResult(RequestHeaders);
55153
56186
  var KvKey = exports_Schema.NonEmptyString.pipe(exports_Schema.brand("KvKey")).annotate({ identifier: "KvKey" });
56187
+ var KvValue = exports_Schema.String.pipe(exports_Schema.brand("KvValue")).annotate({ identifier: "KvValue" });
55154
56188
  var kvKey = {
55155
56189
  inferenceKey: (hash4) => KvKey.make(`k:${hash4}`),
55156
56190
  route: (org, workload) => KvKey.make(`r:${org}:${workload}`),
@@ -55315,76 +56349,41 @@ var disable = exports_Effect.fnUntraced(function* (org, id2) {
55315
56349
  WHERE org_id = ${org} AND id = ${id2}
55316
56350
  `;
55317
56351
  });
55318
- var LIVE_PASS = Millis.make(60 * 1000);
55319
- var GRACE = Millis.make(3 * 60 * 1000);
55320
- var KV_WAIT = Millis.make(10 * 1000);
55321
- var putEntry = exports_Effect.fnUntraced(function* (keyHash, entry, deadline) {
55322
- const kv = yield* exports_KeyValueStore.KeyValueStore;
55323
- const text3 = yield* encodeInferenceEntry(entry).pipe(exports_Effect.orDie);
55324
- const attempt2 = exports_Effect.gen(function* () {
55325
- if ((yield* now3) >= deadline) {
55326
- return yield* new exports_Cause.TimeoutError("A key's entry wasn't sent within LIVE_PASS of its read");
55327
- }
55328
- yield* kv.set(kvKey.inferenceKey(keyHash), text3).pipe(exports_Effect.timeout(exports_Duration.millis(KV_WAIT)));
55329
- });
55330
- yield* attempt2.pipe(exports_Effect.retry({
55331
- schedule: exports_Schedule.spaced("1 second"),
55332
- times: 3,
55333
- while: () => exports_Effect.map(now3, (now4) => now4 < deadline)
55334
- }));
55335
- });
55336
56352
  var withEntries = Kind.literals.filter((kind) => hasInferenceEntry[kind]);
55337
- var record3 = (sql, keys5) => exports_SqlSchema.findAll({
55338
- Request: exports_Schema.Void,
55339
- Result: exports_Schema.Struct({ id: ApiKeyId }),
55340
- execute: () => sql`
55341
- INSERT INTO key_entry_syncs AS s (key_id, changed_at, attempted_at)
55342
- SELECT id, clock_timestamp(), clock_timestamp() FROM api_keys
55343
- WHERE ${keys5} AND kind IN ${sql.in(withEntries)}
55344
- ON CONFLICT (key_id) DO UPDATE SET recorded = s.recorded + 1, changed_at = clock_timestamp(), synced_at = NULL
55345
- RETURNING s.key_id AS id
55346
- `
55347
- })(undefined).pipe(exports_Effect.map(exports_Array.map(({ id: id2 }) => id2)), exports_Effect.catchTag("SchemaError", exports_Effect.die));
55348
- var Pending2 = exports_Schema.Struct({
56353
+ var KeyRow = exports_Schema.Struct({
55349
56354
  keyId: ApiKeyId,
55350
56355
  org: OrgId,
55351
56356
  hash: Hash2,
55352
- disabledAt: nullAsAbsent(Timestamp),
55353
- recorded: exports_Schema.Int,
55354
- due: exports_Schema.Boolean
55355
- }).annotate({ identifier: "ApiKeyPending" });
55356
- var isDue = (sql) => sql`s.changed_at + ${GRACE} * interval '1 millisecond' <= clock_timestamp()`;
55357
- var syncEntry = exports_Effect.fnUntraced(function* (id2) {
56357
+ disabledAt: nullAsAbsent(Timestamp)
56358
+ }).annotate({ identifier: "ApiKeyRow" });
56359
+ var kvEntryOf = exports_Effect.fnUntraced(function* (id2) {
55358
56360
  const sql = yield* exports_SqlClient.SqlClient;
55359
- const deadline = EpochMillis.make((yield* now3) + LIVE_PASS);
55360
56361
  const row = yield* exports_SqlSchema.findOneOption({
55361
56362
  Request: ApiKeyId,
55362
- Result: Pending2,
56363
+ Result: KeyRow,
55363
56364
  execute: (request3) => sql`
55364
56365
  SELECT k.id AS "keyId", k.org_id AS org, k.hash,
55365
- CASE WHEN k.enabled THEN NULL ELSE coalesce(k.disabled_at, s.changed_at) END AS "disabledAt",
55366
- s.recorded, ${isDue(sql)} AS due
55367
- FROM key_entry_syncs s JOIN api_keys k ON k.id = s.key_id
55368
- WHERE s.key_id = ${request3}
56366
+ CASE WHEN k.enabled THEN NULL ELSE coalesce(k.disabled_at, s.changed_at, now()) END AS "disabledAt"
56367
+ FROM api_keys k LEFT JOIN key_entry_syncs s ON s.key_id = k.id
56368
+ WHERE k.id = ${request3}
55369
56369
  `
55370
56370
  })(id2).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
55371
56371
  if (exports_Option.isNone(row))
55372
- return;
56372
+ return exports_Option.none();
55373
56373
  const key2 = row.value;
55374
56374
  const access4 = yield* exports_Effect.fromOption(exports_Array.head(yield* access3([key2.org]))).pipe(exports_Effect.orDie);
55375
- yield* putEntry(key2.hash, entryFor(key2, access4), deadline);
55376
- yield* key2.due ? sql`DELETE FROM key_entry_syncs WHERE key_id = ${key2.keyId} AND recorded = ${key2.recorded}` : sql`UPDATE key_entry_syncs SET synced_at = now() WHERE key_id = ${key2.keyId} AND recorded = ${key2.recorded}`;
56375
+ const value5 = yield* encodeInferenceEntry(entryFor(key2, access4)).pipe(exports_Effect.orDie);
56376
+ return exports_Option.some({ key: kvKey.inferenceKey(key2.hash), value: KvValue.make(value5) });
55377
56377
  });
55378
- var syncAll = (keys5, until) => exports_Effect.map(exports_Effect.forEach(keys5, (key2) => exports_Effect.flatMap(now3, (now4) => until !== undefined && now4 >= until ? exports_Effect.succeedNone : exports_Effect.asSome(exports_Effect.map(exports_Effect.exit(syncEntry(key2)), (exit3) => ({ key: key2, exit: exit3 })))), { concurrency: 4 }), exports_Array.getSomes);
55379
- var failures = (synced) => synced.filter(({ exit: exit3 }) => exports_Exit.isFailure(exit3));
55380
- var syncNow = exports_Effect.fnUntraced(function* (keys5) {
55381
- const failed = failures(yield* syncAll(keys5));
55382
- if (failed.length > 0) {
55383
- yield* exports_Effect.logWarning("Keys' entries weren't synced; the retry syncs them", {
55384
- failed: failed.length,
55385
- cause: failed[0]?.exit
55386
- });
55387
- }
56378
+ var sync7 = make70({ name: TableName.make("key_entry_syncs"), id: IdColumn.make("key_id"), Id: ApiKeyId }, kvEntryOf);
56379
+ var record3 = exports_Effect.fnUntraced(function* (sql, keys5) {
56380
+ const ids = yield* exports_SqlSchema.findAll({
56381
+ Request: exports_Schema.Void,
56382
+ Result: exports_Schema.Struct({ id: ApiKeyId }),
56383
+ execute: () => sql`SELECT id FROM api_keys WHERE ${keys5} AND kind IN ${sql.in(withEntries)}`
56384
+ })(undefined).pipe(exports_Effect.map(exports_Array.map(({ id: id2 }) => id2)), exports_Effect.catchTag("SchemaError", exports_Effect.die));
56385
+ yield* sync7.record(ids);
56386
+ return ids;
55388
56387
  });
55389
56388
  var issue = exports_Effect.fn("ApiKey.issue")(function* (org, user2, input, deployed) {
55390
56389
  yield* exports_Effect.annotateCurrentSpan({ org, kind: input.kind });
@@ -55393,8 +56392,8 @@ var issue = exports_Effect.fn("ApiKey.issue")(function* (org, user2, input, depl
55393
56392
  const id2 = ApiKeyId.make(yield* uuid);
55394
56393
  const created = { id: id2, ...input, start: start2(key2), key: key2 };
55395
56394
  const recorded = yield* exports_Effect.gen(function* () {
55396
- const settings = yield* lock(org);
55397
- const state2 = exports_Option.isNone(settings) ? "pending" : settings.value.settings.access;
56395
+ const settings = yield* exports_Effect.fromOption(yield* lock(org)).pipe(exports_Effect.orDie);
56396
+ const state2 = settings.settings.access;
55398
56397
  if (state2 !== "active")
55399
56398
  return yield* new OrgNotEnabled({ state: state2 });
55400
56399
  yield* insert(org, {
@@ -55408,7 +56407,7 @@ var issue = exports_Effect.fn("ApiKey.issue")(function* (org, user2, input, depl
55408
56407
  });
55409
56408
  return yield* record3(sql, sql`id = ${id2}`);
55410
56409
  }).pipe(sql.withTransaction);
55411
- yield* syncNow(recorded);
56410
+ yield* sync7.syncNow(recorded);
55412
56411
  return created;
55413
56412
  });
55414
56413
  var list6 = exports_Effect.fn("ApiKey.list")(function* (org) {
@@ -55420,7 +56419,7 @@ var revoke = exports_Effect.fn("ApiKey.revoke")(function* (org, id2) {
55420
56419
  if (exports_Option.isNone(yield* find2(org, id2)))
55421
56420
  return yield* new NotFound7({ apiKey: id2 });
55422
56421
  const recorded = yield* disable(org, id2).pipe(exports_Effect.andThen(record3(sql, sql`id = ${id2}`)), sql.withTransaction);
55423
- yield* syncNow(recorded);
56422
+ yield* sync7.syncNow(recorded);
55424
56423
  });
55425
56424
  var changeAccess = exports_Effect.fnUntraced(function* (org, state2, actor) {
55426
56425
  const sql = yield* exports_SqlClient.SqlClient;
@@ -55428,7 +56427,7 @@ var changeAccess = exports_Effect.fnUntraced(function* (org, state2, actor) {
55428
56427
  change(org, SetAccess.make({ state: state2 }), actor),
55429
56428
  record3(sql, sql`org_id = ${org} AND enabled`)
55430
56429
  ]).pipe(sql.withTransaction);
55431
- yield* syncNow(recorded);
56430
+ yield* sync7.syncNow(recorded);
55432
56431
  return changed;
55433
56432
  });
55434
56433
  var suspend7 = exports_Effect.fn("ApiKey.suspend")(function* (org, actor) {
@@ -55437,60 +56436,6 @@ var suspend7 = exports_Effect.fn("ApiKey.suspend")(function* (org, actor) {
55437
56436
  var enable = exports_Effect.fn("ApiKey.enable")(function* (org, actor) {
55438
56437
  return yield* changeAccess(org, "active", actor);
55439
56438
  });
55440
- var BATCH = 100;
55441
- var KEPT_FOR_LAST = 25;
55442
- var RUN_BUDGET = Millis.make(30 * 1000);
55443
-
55444
- class RetryError extends exports_Schema.TaggedError()("ApiKeyRetryError", {
55445
- reason: exports_Schema.Literals(["Unavailable"]),
55446
- cause: exports_Schema.Defect()
55447
- }) {
55448
- }
55449
- var nextBatch = exports_Effect.fnUntraced(function* () {
55450
- const sql = yield* exports_SqlClient.SqlClient;
55451
- const oldest = (where) => exports_SqlSchema.findAll({
55452
- Request: exports_Schema.Void,
55453
- Result: exports_Schema.Struct({ id: ApiKeyId }),
55454
- execute: () => sql`
55455
- SELECT s.key_id AS id FROM key_entry_syncs s
55456
- WHERE ${where}
55457
- ORDER BY s.attempted_at, s.key_id
55458
- LIMIT ${BATCH}
55459
- FOR UPDATE SKIP LOCKED
55460
- `
55461
- })(undefined).pipe(exports_Effect.map(exports_Array.map(({ id: id2 }) => id2)), exports_Effect.catchTag("SchemaError", exports_Effect.die));
55462
- return yield* exports_Effect.gen(function* () {
55463
- const unsynced = yield* oldest(sql`s.synced_at IS NULL`);
55464
- const last2 = yield* oldest(sql`s.synced_at IS NOT NULL AND ${isDue(sql)}`);
55465
- const first = unsynced.slice(0, BATCH - Math.min(KEPT_FOR_LAST, last2.length));
55466
- const batch = [...first, ...last2.slice(0, BATCH - first.length)];
55467
- if (batch.length > 0)
55468
- yield* sql`UPDATE key_entry_syncs SET attempted_at = now() WHERE key_id IN ${sql.in(batch)}`;
55469
- return batch;
55470
- }).pipe(sql.withTransaction);
55471
- });
55472
- var retrySyncs = exports_Effect.fn("ApiKey.retrySyncs")(function* () {
55473
- const until = EpochMillis.make((yield* now3) + RUN_BUDGET);
55474
- let synced = 0;
55475
- let kept = [];
55476
- while (true) {
55477
- const batch = yield* nextBatch();
55478
- const outcomes = yield* syncAll(batch, until);
55479
- const failed = failures(outcomes);
55480
- synced += outcomes.length - failed.length;
55481
- kept = failed;
55482
- if (outcomes.length < BATCH || failed.length === outcomes.length)
55483
- break;
55484
- }
55485
- if (synced > 0)
55486
- yield* exports_Effect.logDebug("Synced keys' entries", { synced });
55487
- if (kept.length > 0) {
55488
- yield* exports_Effect.logError("KV refuses to sync keys' entries; they are retried", {
55489
- kept: kept.length,
55490
- cause: kept[0]?.exit
55491
- });
55492
- }
55493
- }, exports_Effect.mapError((cause) => new RetryError({ reason: "Unavailable", cause })));
55494
56439
  // ../core/src/Api/PlatformApi.ts
55495
56440
  var exports_PlatformApi = {};
55496
56441
  __export(exports_PlatformApi, {
@@ -55568,7 +56513,7 @@ var values4 = (meanings) => {
55568
56513
  `);
55569
56514
  };
55570
56515
  var literals = (meanings) => exports_Record.toEntries(meanings).map(([value5, meaning]) => [exports_Formatter.format(value5), meaning]);
55571
- var listed = (set9, conjunction) => {
56516
+ var listed2 = (set9, conjunction) => {
55572
56517
  const each = set9.map((literal2) => exports_Formatter.format(literal2));
55573
56518
  return each.length < 2 ? each.join("") : `${each.slice(0, -1).join(", ")} ${conjunction} ${each.at(-1)}`;
55574
56519
  };
@@ -55595,7 +56540,7 @@ var JudgeCall = exports_Schema.Struct({
55595
56540
  request: JudgeRequest,
55596
56541
  response: JudgeResponse
55597
56542
  }).annotate({ identifier: "JudgeCall" });
55598
- var make71 = (name, model, messages, completion, parsed) => {
56543
+ var make72 = (name, model, messages, completion, parsed) => {
55599
56544
  const usage = completion.call.usage;
55600
56545
  return {
55601
56546
  name,
@@ -55731,7 +56676,7 @@ var Data = TaskData.schema.mapFields(exports_Struct.assign({
55731
56676
  workload: WorkloadId,
55732
56677
  source_prompt_version: exports_Schema.optionalKey(PromptVersion)
55733
56678
  })).annotate({ identifier: "ReplayTaskData" });
55734
- var Recorded = exports_Schema.Struct({
56679
+ var Recorded2 = exports_Schema.Struct({
55735
56680
  model: ModelId,
55736
56681
  calls: exports_Schema.Array(exports_Schema.NullOr(ModelCall))
55737
56682
  }).annotate({ identifier: "ReplayTaskRecorded" });
@@ -55838,11 +56783,11 @@ var failsRequired = ({ metrics, rewards }, required2) => required2.some((name) =
55838
56783
  return score != null && score < 1;
55839
56784
  });
55840
56785
  var normalize4 = ({ metrics, rewards }, required2) => {
55841
- const total = exports_Record.values(rewards).reduce((sum3, reward2) => sum3 + (reward2 === null ? 0 : reward2.weight ?? 1), 0);
56786
+ const total = exports_Record.values(rewards).reduce((sum4, reward2) => sum4 + (reward2 === null ? 0 : reward2.weight ?? 1), 0);
55842
56787
  const zeroed = failsRequired({ metrics, rewards }, required2) || total === 0;
55843
56788
  return exports_Record.map(rewards, (reward2) => reward2 === null ? null : { score: reward2.score, weight: zeroed ? 0 : (reward2.weight ?? 1) / total });
55844
56789
  };
55845
- var mean = (scores) => Score.make(scores.reduce((sum3, score) => sum3 + score, 0) / scores.length);
56790
+ var mean = (scores) => Score.make(scores.reduce((sum4, score) => sum4 + score, 0) / scores.length);
55846
56791
  var modes = {
55847
56792
  mean: { gives: "their mean", combine: mean },
55848
56793
  min: { gives: "the lowest of them", combine: (scores) => Score.make(Math.min(...scores)) },
@@ -56542,13 +57487,15 @@ var usageSum = (sql, usage2) => sql`
56542
57487
 
56543
57488
  // ../core/src/Scoring/JudgeRecording.ts
56544
57489
  var encodeCall2 = exports_Schema.encodeSync(JudgeCall);
56545
- var write3 = exports_Effect.fn("JudgeRecording.write")(function* (org, run6, call) {
57490
+ var write3 = exports_Effect.fn("JudgeRecording.write")(function* (org, run6, call, charged) {
56546
57491
  const id2 = JudgeCallId.make(yield* uuid);
56547
57492
  yield* exports_Effect.annotateCurrentSpan({ org, runId: run6, judgeCallId: id2, judge: call.name });
56548
57493
  const sql = yield* exports_SqlClient.SqlClient;
57494
+ const [charge3] = yield* chargesOf([charged]);
57495
+ const priced2 = { ...call, response: withCharge(call.response, charge3) };
56549
57496
  const stored = yield* sql`
56550
57497
  INSERT INTO judge_calls (id, run_id, call)
56551
- SELECT ${id2}, r.id, ${JSON.stringify(encodeCall2(call))}::jsonb
57498
+ SELECT ${id2}, r.id, ${JSON.stringify(encodeCall2(priced2))}::jsonb
56552
57499
  FROM score_runs r JOIN workloads w ON w.id = r.workload_id
56553
57500
  WHERE w.org_id = ${org} AND r.id = ${run6}
56554
57501
  RETURNING id
@@ -56559,7 +57506,7 @@ var write3 = exports_Effect.fn("JudgeRecording.write")(function* (org, run6, cal
56559
57506
  return id2;
56560
57507
  });
56561
57508
  var Stored4 = exports_Schema.Struct({ id: JudgeCallId, call: JudgeCall });
56562
- var get24 = exports_Effect.fn("JudgeRecording.get")(function* (org, ids) {
57509
+ var get25 = exports_Effect.fn("JudgeRecording.get")(function* (org, ids) {
56563
57510
  yield* exports_Effect.annotateCurrentSpan({ org, judgeCalls: ids.length });
56564
57511
  const sql = yield* exports_SqlClient.SqlClient;
56565
57512
  if (ids.length === 0)
@@ -56770,7 +57717,7 @@ var sessionBlock = ({ prompt, system }, { maxChars, messages }) => messages ===
56770
57717
  var TURNS = "Which points it judges, picked by the recorded turn at each point, not by the reply given in its place: `kinds`, " + "whether that turn called a tool or answered in text, and `final`, whether it is the trace's last. Default {}: " + "every point.";
56771
57718
  var TurnFilter = exports_Schema.Struct({
56772
57719
  kinds: exports_Schema.NonEmptyArray(TurnKind).check(exports_Schema.isUnique()).annotateKey({
56773
- description: "The points it judges by what the recorded turn there did: called a tool, answered in text, or " + `either; any of ${listed(TurnKind.literals, "and")}. ` + `Default ${exports_Formatter.format(TurnKind.literals)}: either.`
57720
+ description: "The points it judges by what the recorded turn there did: called a tool, answered in text, or " + `either; any of ${listed2(TurnKind.literals, "and")}. ` + `Default ${exports_Formatter.format(TurnKind.literals)}: either.`
56774
57721
  }).pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed(TurnKind.literals))),
56775
57722
  final: exports_Schema.NullOr(exports_Schema.Boolean).annotateKey({
56776
57723
  description: "Whether it judges the point at the trace's last recorded turn: true for that point only, false for " + "every point before it, null for either. Default null."
@@ -56886,7 +57833,7 @@ var ExplainedCriterion = Criterion.mapFields(({ text: text3 }) => ({
56886
57833
  }).pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed(null)))
56887
57834
  })).check(exports_Schema.makeFilter(({ choices, meanings }) => exports_Record.keys(meanings).flatMap((choice2) => choices.includes(choice2) ? [] : [{
56888
57835
  path: ["meanings", choice2],
56889
- issue: `"${choice2}" is not one of the criterion's choices (${listed(choices, "or")})`
57836
+ issue: `"${choice2}" is not one of the criterion's choices (${listed2(choices, "or")})`
56890
57837
  }]))).annotate({ identifier: "ExplainedCriterion" });
56891
57838
  var criteriaIssues = (criteria) => {
56892
57839
  const seen = new Set;
@@ -56977,8 +57924,8 @@ var groupScore = (criteria, scores) => {
56977
57924
  const score = scoreOf(scores, name);
56978
57925
  return score === null ? [] : [{ score, weight }];
56979
57926
  });
56980
- const total = applied.reduce((sum3, { weight }) => sum3 + weight, 0);
56981
- return total > 0 ? Score.make(applied.reduce((sum3, { score, weight }) => sum3 + score * weight, 0) / total) : null;
57927
+ const total = applied.reduce((sum4, { weight }) => sum4 + weight, 0);
57928
+ return total > 0 ? Score.make(applied.reduce((sum4, { score, weight }) => sum4 + score * weight, 0) / total) : null;
56982
57929
  };
56983
57930
  var decodeCriteria = exports_Schema.decodeUnknownEffect(CriteriaSettings);
56984
57931
  var decodeNames = exports_Schema.decodeUnknownSync(exports_Schema.Struct({ criteria: exports_Schema.Array(exports_Schema.Struct({ name: ScorerName })) }));
@@ -57116,7 +58063,7 @@ var turnsOf = exports_Effect.fnUntraced(function* (attempt3) {
57116
58063
  system: system_prompt ?? undefined
57117
58064
  };
57118
58065
  });
57119
- var modelOf = (name, id2) => get19(id2).pipe(exports_Effect.catchTags({
58066
+ var modelOf = (name, id2) => get20(id2).pipe(exports_Effect.catchTags({
57120
58067
  ModelNotFound: (error2) => exports_Effect.fail(unsupported2(name, error2)),
57121
58068
  SqlError: (cause) => exports_Effect.fail(new VerifierError({ reason: "Unavailable", scorer: name, cause }))
57122
58069
  }));
@@ -57124,7 +58071,7 @@ var verdictOf = exports_Effect.fnUntraced(function* (org, run6, name, model, ver
57124
58071
  const failed = (reason) => (cause) => new VerifierError({ reason, scorer: name, cause });
57125
58072
  const completion = yield* produce(model, prompt, org);
57126
58073
  const read5 = verdicts.read(completion.reply.content ?? "");
57127
- const call = yield* write3(org, run6, make71(name, model.id, prompt.messages, completion, exports_Result.getOrUndefined(read5)?.answer ?? null)).pipe(exports_Effect.mapError(failed("Unavailable")));
58074
+ const call = yield* write3(org, run6, make72(name, model.id, prompt.messages, completion, exports_Result.getOrUndefined(read5)?.answer ?? null), completion.charged).pipe(exports_Effect.mapError(failed("Unavailable")));
57128
58075
  const { recorded } = yield* exports_Effect.fromResult(read5).pipe(exports_Effect.mapError(failed("Failed")));
57129
58076
  return { recorded, call };
57130
58077
  });
@@ -57251,7 +58198,7 @@ var Weight2 = Weight.annotateKey({
57251
58198
  description: "How much it counts beside the others, from 0 to 1000. Default 1."
57252
58199
  }).pipe(exports_Schema.withDecodingDefaultKey(exports_Effect.succeed(1)));
57253
58200
  var scorerOf = (set9) => set9.annotateKey({
57254
- description: `Which scorer it is: ${listed(set9.literals, "or")}, as listed under the group.`
58201
+ description: `Which scorer it is: ${listed2(set9.literals, "or")}, as listed under the group.`
57255
58202
  });
57256
58203
  var RewardScorer = exports_Schema.Struct({
57257
58204
  scorer: scorerOf(FunctionName),
@@ -57445,15 +58392,15 @@ var uncounted = (config) => {
57445
58392
  const scoredBy = exports_Record.keys(EpisodeScorerConfigs.fields).filter((name) => rewards[name] !== null);
57446
58393
  if (scoredBy.length > 0 && rewards.replies === null) {
57447
58394
  const by = `the trace scores only by \`episode.rewards\` (${scoredBy.map((name) => `\`${name}\``).join(", ")})`;
57448
- const add7 = metrics.replies === null ? "add `episode.rewards.replies` to count it" : "move `replies` from `episode.metrics` to `episode.rewards` to count it";
58395
+ const add8 = metrics.replies === null ? "add `episode.rewards.replies` to count it" : "move `replies` from `episode.metrics` to `episode.rewards` to count it";
57449
58396
  return [
57450
58397
  ...scorers.map(({ movesToMetrics, path }) => ({
57451
58398
  path,
57452
- message: `Counts toward each reply's score, but ${by}; ${add7}` + (movesToMetrics ? ", or move it to `metrics` to record it." : ".")
58399
+ message: `Counts toward each reply's score, but ${by}; ${add8}` + (movesToMetrics ? ", or move it to `metrics` to record it." : ".")
57453
58400
  })),
57454
58401
  ...config.required.map((_, i) => ({
57455
58402
  path: ["required", i],
57456
- message: `Zeroes the score of a reply where it fails, but ${by}; ${add7}.`
58403
+ message: `Zeroes the score of a reply where it fails, but ${by}; ${add8}.`
57457
58404
  }))
57458
58405
  ];
57459
58406
  }
@@ -57585,7 +58532,7 @@ var run6 = exports_Effect.fn("ReplayEnv.run")(function* (config, task, replier,
57585
58532
  prompt: promptAt(task.data, point.index),
57586
58533
  completion
57587
58534
  });
57588
- yield* write2(wholeDelta(owner.org, trace3, yield* now3));
58535
+ yield* write2(wholeDelta(owner.org, trace3, yield* now3, [completion.charged]));
57589
58536
  const scores = yield* verifiers2.score({
57590
58537
  config: judgesAt(scorers, point.reference),
57591
58538
  attempt: trace3,
@@ -57611,8 +58558,8 @@ var run6 = exports_Effect.fn("ReplayEnv.run")(function* (config, task, replier,
57611
58558
  candidate: () => judgeTrajectory(trajectoryJudge2, judge, task, steps, owner)
57612
58559
  }));
57613
58560
  const verdict = exports_Result.getOrUndefined(trajectory2);
57614
- const failures2 = exports_Result.isFailure(trajectory2) ? [...pointFailures, trajectory2.failure] : pointFailures;
57615
- const errors = failures2.map(toError2);
58561
+ const failures = exports_Result.isFailure(trajectory2) ? [...pointFailures, trajectory2.failure] : pointFailures;
58562
+ const errors = failures.map(toError2);
57616
58563
  const outcome2 = compact2({
57617
58564
  attempts,
57618
58565
  scores: compact2({ ...scored.scores, trajectory: verdict?.score }),
@@ -57621,7 +58568,7 @@ var run6 = exports_Effect.fn("ReplayEnv.run")(function* (config, task, replier,
57621
58568
  errors: exports_Array.isArrayNonEmpty(errors) ? errors : undefined,
57622
58569
  judgeCalls: verdict?.call === undefined ? undefined : [verdict.call]
57623
58570
  });
57624
- return { outcome: outcome2, failures: failures2 };
58571
+ return { outcome: outcome2, failures };
57625
58572
  });
57626
58573
  var encodeCall3 = exports_Schema.encodeSync(JudgeCall);
57627
58574
  var stored = (got, key3, what) => {
@@ -57675,12 +58622,13 @@ __export(exports_Run, {
57675
58622
  readout: () => readout,
57676
58623
  plan: () => plan,
57677
58624
  list: () => list10,
57678
- get: () => get26,
58625
+ get: () => get27,
57679
58626
  fail: () => fail12,
57680
58627
  episodes: () => episodes,
57681
58628
  encodeTrial: () => encodeTrial,
57682
58629
  create: () => create3,
57683
58630
  consume: () => consume,
58631
+ cancel: () => cancel,
57684
58632
  VerdictPage: () => VerdictPage,
57685
58633
  VerdictNotFound: () => VerdictNotFound,
57686
58634
  VerdictFilter: () => VerdictFilter,
@@ -57701,6 +58649,7 @@ __export(exports_Run, {
57701
58649
  Readout: () => Readout,
57702
58650
  Page: () => Page2,
57703
58651
  NothingToScore: () => NothingToScore,
58652
+ NotRunning: () => NotRunning,
57704
58653
  NotFound: () => NotFound11,
57705
58654
  Judgment: () => Judgment,
57706
58655
  Filter: () => Filter4,
@@ -57774,9 +58723,9 @@ var latestBranch = (nodes) => {
57774
58723
  const leaf = latestLeaf(nodes);
57775
58724
  return leaf === undefined ? [] : walk(nodes, leaf);
57776
58725
  };
57777
- var previewOf = (row, nodes, latest) => {
57778
- const replies = latest.flatMap((message) => message.role === "assistant" ? [message] : []);
57779
- const firstUser = latest.find((message) => message.role === "user");
58726
+ var previewOf = (row, nodes, latest2) => {
58727
+ const replies = latest2.flatMap((message) => message.role === "assistant" ? [message] : []);
58728
+ const firstUser = latest2.find((message) => message.role === "user");
57780
58729
  const firstUserText = firstUser === undefined ? "" : textOf3(firstUser.content);
57781
58730
  return compact2({
57782
58731
  id: row.id,
@@ -57907,7 +58856,7 @@ var list8 = exports_Effect.fn("TraceReading.list")(function* (org, workload, opt
57907
58856
  const misplaced = [...graphs.values()].some((graph) => graph.some((node, position) => node.node_id !== position));
57908
58857
  if (misplaced)
57909
58858
  return yield* exports_Effect.die("TraceReading.list: a trace's graph is incomplete");
57910
- const latest = page.map((row) => {
58859
+ const latest2 = page.map((row) => {
57911
58860
  const graph = graphs.get(row.trace) ?? [];
57912
58861
  return {
57913
58862
  row,
@@ -57915,8 +58864,8 @@ var list8 = exports_Effect.fn("TraceReading.list")(function* (org, workload, opt
57915
58864
  branch: latestBranch(graph).map(({ node }) => node.message_hash)
57916
58865
  };
57917
58866
  });
57918
- const bodies = yield* store.getMany([...new Set(latest.flatMap(({ branch }) => branch))]);
57919
- const traces = yield* exports_Effect.forEach(latest, ({ row, graph, branch }) => {
58867
+ const bodies = yield* store.getMany([...new Set(latest2.flatMap(({ branch }) => branch))]);
58868
+ const traces = yield* exports_Effect.forEach(latest2, ({ row, graph, branch }) => {
57920
58869
  const messages = branch.flatMap((hash5) => {
57921
58870
  const body = bodies.get(hash5);
57922
58871
  return body === undefined ? [] : [body.message];
@@ -57943,7 +58892,7 @@ var production = exports_Effect.fnUntraced(function* (org, id2) {
57943
58892
  })({ org, id: id2 }).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die), exports_Effect.mapError(unavailable4));
57944
58893
  if (exports_Option.isNone(row))
57945
58894
  return yield* new NotFound9({ trace: id2 });
57946
- const trace3 = yield* get20(org, row.value.trace).pipe(exports_Effect.catchTag("TraceNotFound", exports_Effect.die));
58895
+ const trace3 = yield* get21(org, row.value.trace).pipe(exports_Effect.catchTag("TraceNotFound", exports_Effect.die));
57947
58896
  return { row: row.value, trace: trace3 };
57948
58897
  });
57949
58898
  var PromptRow = exports_Schema.Struct({ idx: CallIndex, prompt: NodeId });
@@ -57971,11 +58920,11 @@ var find4 = exports_Effect.fn("TraceReading.find")(function* (org, ref) {
57971
58920
  const { prompts, tasksets } = yield* placing(row.trace);
57972
58921
  const nodes = trace3.nodes ?? [];
57973
58922
  const calls2 = (trace3.calls ?? []).map((call, idx) => ({ call, prompt: prompts.get(CallIndex.make(idx)) }));
57974
- const latest = latestLeaf(nodes);
58923
+ const latest2 = latestLeaf(nodes);
57975
58924
  const leaf = ref.leaf;
57976
58925
  if (leaf !== undefined && nodes[leaf] === undefined)
57977
58926
  return yield* new BranchNotFound({ trace: ref.trace, leaf });
57978
- const ends = leaf === undefined ? [...latest === undefined ? [] : [latest], ...leaves(nodes).toReversed().filter((end3) => end3 !== latest)] : [leaf];
58927
+ const ends = leaf === undefined ? [...latest2 === undefined ? [] : [latest2], ...leaves(nodes).toReversed().filter((end3) => end3 !== latest2)] : [leaf];
57979
58928
  const info2 = compact2(yield* decodeInfo(trace3.info?.[INFO_KEY]).pipe(exports_Effect.orDie));
57980
58929
  return compact2({
57981
58930
  preview: previewOf(row, nodes, latestBranch(nodes).map(({ node }) => node.message)),
@@ -57983,7 +58932,7 @@ var find4 = exports_Effect.fn("TraceReading.find")(function* (org, ref) {
57983
58932
  status: row.status,
57984
58933
  settledAt: row.settledAt,
57985
58934
  turns: row.turns,
57986
- latest,
58935
+ latest: latest2,
57987
58936
  branches: ends.map((end3) => conversationOf(nodes, calls2, end3, tasksets)),
57988
58937
  unplaced: calls2.flatMap(({ call, prompt }) => call.node == null && prompt === undefined ? [call] : [])
57989
58938
  });
@@ -58052,8 +59001,8 @@ var alternativesOf = (ast) => {
58052
59001
  };
58053
59002
  var expected = (alternatives, got) => {
58054
59003
  const each = exports_Array.dedupe(alternatives);
58055
- const listed2 = each.length < 2 ? each.join("") : `${each.slice(0, -1).join(", ")} or ${each.at(-1)}`;
58056
- return `Expected ${listed2}, got ${got}`;
59004
+ const listed3 = each.length < 2 ? each.join("") : `${each.slice(0, -1).join(", ")} or ${each.at(-1)}`;
59005
+ return `Expected ${listed3}, got ${got}`;
58057
59006
  };
58058
59007
  var mismatch = (issue2) => exports_Match.value(issue2).pipe(exports_Match.tags({
58059
59008
  AnyOf: ({ ast }) => alternativesOf(ast) !== undefined,
@@ -58113,11 +59062,11 @@ var decodeConfig = exports_Schema.decodeUnknownResult(EnvConfig, {
58113
59062
  var decode8 = (file3) => decodeConfig(file3).pipe(exports_Result.mapError((error2) => new Invalid2({ issues: issuesOf(error2) })));
58114
59063
  var warnings = (config) => uncounted(config).map(({ message, path }) => ({ path: pathOf(path), message }));
58115
59064
  var check3 = exports_Effect.fn("ScoringCheck.check")(function* (config) {
58116
- const missing2 = yield* exports_Effect.forEach(models(config), ({ path, model }) => get19(model).pipe(exports_Effect.as([]), exports_Effect.catchTag("ModelNotFound", () => exports_Effect.succeed([{
59065
+ const missing3 = yield* exports_Effect.forEach(models(config), ({ path, model }) => get20(model).pipe(exports_Effect.as([]), exports_Effect.catchTag("ModelNotFound", () => exports_Effect.succeed([{
58117
59066
  path: pathOf(path),
58118
59067
  message: `The catalog has no model ${model}`
58119
59068
  }]))));
58120
- const issues = missing2.flat();
59069
+ const issues = missing3.flat();
58121
59070
  if (exports_Array.isArrayNonEmpty(issues))
58122
59071
  return yield* new Invalid2({ issues });
58123
59072
  return config;
@@ -58132,7 +59081,7 @@ __export(exports_Taskset, {
58132
59081
  load: () => load,
58133
59082
  list: () => list9,
58134
59083
  inWorkload: () => inWorkload,
58135
- get: () => get25,
59084
+ get: () => get26,
58136
59085
  create: () => create2,
58137
59086
  checkScoring: () => checkScoring,
58138
59087
  Unscorable: () => Unscorable,
@@ -58253,7 +59202,7 @@ var create2 = exports_Effect.fn("Taskset.create")(function* (org, workload, inpu
58253
59202
  const createdAt = yield* now3;
58254
59203
  yield* exports_Effect.annotateCurrentSpan({ org, workload, tasksetId: id2, traces: input.traces.length });
58255
59204
  return yield* sql.withTransaction(exports_Effect.gen(function* () {
58256
- const { id: workloadId } = yield* get23(org, workload);
59205
+ const { id: workloadId } = yield* get24(org, workload);
58257
59206
  const found = yield* exports_SqlSchema.findAll({
58258
59207
  Request: exports_Schema.Array(PublicId),
58259
59208
  Result: exports_Schema.Struct({ id: TraceId, public: PublicId }),
@@ -58329,8 +59278,8 @@ var select2 = (sql, filter15) => sql`
58329
59278
  ORDER BY t.created_at DESC, t.id
58330
59279
  `;
58331
59280
  var ByAddress = exports_Schema.Struct({ org: OrgId, workload: WorkloadName, name: TasksetName });
58332
- var missing2 = (org, address) => get23(org, address.workload).pipe(exports_Effect.andThen(exports_Effect.fail(new NotFound10({ taskset: address }))));
58333
- var get25 = exports_Effect.fn("Taskset.get")(function* (org, address) {
59281
+ var missing3 = (org, address) => get24(org, address.workload).pipe(exports_Effect.andThen(exports_Effect.fail(new NotFound10({ taskset: address }))));
59282
+ var get26 = exports_Effect.fn("Taskset.get")(function* (org, address) {
58334
59283
  yield* exports_Effect.annotateCurrentSpan({ org, workload: address.workload, taskset: address.taskset });
58335
59284
  const sql = yield* exports_SqlClient.SqlClient;
58336
59285
  const found = yield* exports_SqlSchema.findOneOption({
@@ -58339,10 +59288,10 @@ var get25 = exports_Effect.fn("Taskset.get")(function* (org, address) {
58339
59288
  execute: (request3) => select2(sql, request3)
58340
59289
  })({ org, workload: address.workload, name: address.taskset }).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
58341
59290
  if (exports_Option.isNone(found))
58342
- return yield* missing2(org, address);
59291
+ return yield* missing3(org, address);
58343
59292
  return found.value;
58344
59293
  });
58345
- var listed2 = (org, workload) => exports_Effect.gen(function* () {
59294
+ var listed3 = (org, workload) => exports_Effect.gen(function* () {
58346
59295
  const sql = yield* exports_SqlClient.SqlClient;
58347
59296
  return yield* exports_SqlSchema.findAll({
58348
59297
  Request: exports_Schema.Struct({ org: OrgId, workload: exports_Schema.optional(WorkloadName) }),
@@ -58352,13 +59301,13 @@ var listed2 = (org, workload) => exports_Effect.gen(function* () {
58352
59301
  });
58353
59302
  var list9 = exports_Effect.fn("Taskset.list")(function* (org) {
58354
59303
  yield* exports_Effect.annotateCurrentSpan({ org });
58355
- return yield* listed2(org);
59304
+ return yield* listed3(org);
58356
59305
  });
58357
59306
  var inWorkload = exports_Effect.fn("Taskset.inWorkload")(function* (org, workload) {
58358
59307
  yield* exports_Effect.annotateCurrentSpan({ org, workload });
58359
- const found = yield* listed2(org, workload);
59308
+ const found = yield* listed3(org, workload);
58360
59309
  if (found.length === 0)
58361
- yield* get23(org, workload);
59310
+ yield* get24(org, workload);
58362
59311
  return found;
58363
59312
  });
58364
59313
  var idOf = exports_Effect.fnUntraced(function* (org, address, options4) {
@@ -58373,7 +59322,7 @@ var idOf = exports_Effect.fnUntraced(function* (org, address, options4) {
58373
59322
  `
58374
59323
  })({ org, workload: address.workload, name: address.taskset }).pipe(exports_Effect.catchTag("SchemaError", exports_Effect.die));
58375
59324
  if (exports_Option.isNone(found))
58376
- return yield* missing2(org, address);
59325
+ return yield* missing3(org, address);
58377
59326
  return found.value.id;
58378
59327
  });
58379
59328
  var checkScoring = exports_Effect.fn("Taskset.checkScoring")(function* (org, address, config) {
@@ -58436,7 +59385,7 @@ var toolsOf = (nodes, leaf) => {
58436
59385
  var decodeInfo2 = exports_Schema.decodeUnknownEffect(AmbralInfo);
58437
59386
  var load = exports_Effect.fn("Taskset.load")(function* (org, workload, member2, helpers) {
58438
59387
  yield* exports_Effect.annotateCurrentSpan({ org, traceId: member2.traceId, leafNodeId: member2.leafNodeId });
58439
- const trace3 = yield* get20(org, member2.traceId).pipe(exports_Effect.catchTag("TraceNotFound", exports_Effect.die));
59388
+ const trace3 = yield* get21(org, member2.traceId).pipe(exports_Effect.catchTag("TraceNotFound", exports_Effect.die));
58440
59389
  const info2 = yield* decodeInfo2(trace3.info?.[INFO_KEY]).pipe(exports_Effect.orDie);
58441
59390
  const replies = new Map;
58442
59391
  for (const call of trace3.calls ?? [])
@@ -58468,7 +59417,7 @@ var load = exports_Effect.fn("Taskset.load")(function* (org, workload, member2,
58468
59417
  var RunConfig = exports_Schema.Struct({
58469
59418
  scoring: exports_Schema.optional(EnvConfig)
58470
59419
  }).annotate({ identifier: "RunConfig" });
58471
- var Status5 = exports_Schema.Literals(["running", "completed", "failed"]).annotate({ identifier: "RunStatus" });
59420
+ var Status5 = exports_Schema.Literals(["running", "completed", "failed", "cancelled"]).annotate({ identifier: "RunStatus" });
58472
59421
  var Production = exports_Schema.TaggedStruct("production", {}).annotate({ identifier: "RunProduction" });
58473
59422
  var Candidate = exports_Schema.TaggedStruct("candidate", { model: ModelId }).annotate({ identifier: "RunCandidate" });
58474
59423
  var PRODUCTION = "production";
@@ -58556,6 +59505,12 @@ class NotFound11 extends exports_Schema.TaggedError()("RunNotFound", {
58556
59505
  }, { httpApiStatus: 404 }) {
58557
59506
  }
58558
59507
 
59508
+ class NotRunning extends exports_Schema.TaggedError()("RunNotRunning", {
59509
+ run: RunId,
59510
+ status: Status5
59511
+ }, { httpApiStatus: 409 }) {
59512
+ }
59513
+
58559
59514
  class SubjectNotInPool extends exports_Schema.TaggedError()("RunSubjectNotInPool", {
58560
59515
  workload: WorkloadName,
58561
59516
  model: ModelId
@@ -58577,9 +59532,9 @@ var outsidePool = (workload, subjects) => subjects.flatMap((subject) => exports_
58577
59532
  candidate: ({ model }) => workload.pool.models.includes(model) ? [] : [model]
58578
59533
  }));
58579
59534
  var plan = (workload, taskset, input, start3) => {
58580
- const [missing3] = outsidePool(workload, input.subjects);
58581
- if (missing3 !== undefined)
58582
- return exports_Result.fail(new SubjectNotInPool({ workload: workload.name, model: missing3 }));
59535
+ const [missing4] = outsidePool(workload, input.subjects);
59536
+ if (missing4 !== undefined)
59537
+ return exports_Result.fail(new SubjectNotInPool({ workload: workload.name, model: missing4 }));
58583
59538
  if (input.scoring === undefined && taskset.scoringVersion === undefined) {
58584
59539
  return exports_Result.fail(new ScoringMissing({ taskset: input.taskset }));
58585
59540
  }
@@ -58639,16 +59594,16 @@ var create3 = exports_Effect.fn("Run.create")(function* (org, input) {
58639
59594
  taskset: input.taskset.taskset,
58640
59595
  subjects: input.subjects.length
58641
59596
  });
58642
- const taskset = yield* get25(org, input.taskset);
58643
- const workload = yield* get23(org, taskset.workload).pipe(exports_Effect.catchTag("WorkloadNotFound", exports_Effect.die));
59597
+ const taskset = yield* get26(org, input.taskset);
59598
+ const workload = yield* get24(org, taskset.workload).pipe(exports_Effect.catchTag("WorkloadNotFound", exports_Effect.die));
58644
59599
  const planned = yield* exports_Effect.fromResult(plan(workload, taskset, input, { id: id2, at }));
58645
59600
  const config = yield* check3(yield* scoring2(org, planned.run, taskset));
58646
59601
  if (scoresNothing(input.subjects, config))
58647
59602
  return yield* new NothingToScore({ taskset: input.taskset });
58648
59603
  const judges2 = models(config).map(({ model }) => model);
58649
59604
  const candidates = input.subjects.flatMap((subject) => exports_Match.valueTags(subject, { production: () => [], candidate: ({ model }) => [model] }));
58650
- const called = yield* exports_Effect.forEach(exports_Array.dedupe([...candidates, ...judges2]), (model) => get19(model).pipe(exports_Effect.catchTag("ModelNotFound", exports_Effect.die)));
58651
- const entry = yield* get21(org);
59605
+ const called = yield* exports_Effect.forEach(exports_Array.dedupe([...candidates, ...judges2]), (model) => get20(model).pipe(exports_Effect.catchTag("ModelNotFound", exports_Effect.die)));
59606
+ const entry = yield* get22(org);
58652
59607
  yield* exports_Effect.forEach(called, (model) => exports_Effect.fromResult(payerOf(entry, model.base.upstream)), {
58653
59608
  discard: true
58654
59609
  });
@@ -58681,7 +59636,7 @@ var select3 = (sql, org, filter15) => sql`
58681
59636
  ORDER BY r.created_at DESC, r.id DESC
58682
59637
  ${filter15.limit === undefined ? sql`` : sql`LIMIT ${filter15.limit}`}
58683
59638
  `;
58684
- var get26 = exports_Effect.fn("Run.get")(function* (org, id2) {
59639
+ var get27 = exports_Effect.fn("Run.get")(function* (org, id2) {
58685
59640
  yield* exports_Effect.annotateCurrentSpan({ org, runId: id2 });
58686
59641
  const sql = yield* exports_SqlClient.SqlClient;
58687
59642
  const found = yield* exports_SqlSchema.findOneOption({
@@ -58720,9 +59675,9 @@ var list10 = exports_Effect.fn("Run.list")(function* (org, filter15, cursor) {
58720
59675
  const runs = rows.slice(0, PAGE_SIZE2);
58721
59676
  if (runs.length === 0 && cursor === undefined) {
58722
59677
  if (filter15.taskset !== undefined)
58723
- yield* get25(org, filter15.taskset);
59678
+ yield* get26(org, filter15.taskset);
58724
59679
  if (filter15.workload !== undefined)
58725
- yield* get23(org, filter15.workload);
59680
+ yield* get24(org, filter15.workload);
58726
59681
  }
58727
59682
  return compact2({ runs, next: rows.length > PAGE_SIZE2 ? runs.at(-1)?.id : undefined });
58728
59683
  });
@@ -58736,7 +59691,20 @@ var fail12 = exports_Effect.fn("Run.fail")(function* (org, id2) {
58736
59691
  RETURNING r.id
58737
59692
  `;
58738
59693
  if (failed.length === 0)
58739
- yield* get26(org, id2);
59694
+ yield* get27(org, id2);
59695
+ });
59696
+ var cancel = exports_Effect.fn("Run.cancel")(function* (org, id2) {
59697
+ yield* exports_Effect.annotateCurrentSpan({ org, runId: id2 });
59698
+ const sql = yield* exports_SqlClient.SqlClient;
59699
+ yield* sql`
59700
+ UPDATE score_runs r SET status = 'cancelled'
59701
+ FROM workloads w
59702
+ WHERE w.id = r.workload_id AND w.org_id = ${org} AND r.id = ${id2} AND r.status = 'running'
59703
+ `;
59704
+ const run7 = yield* get27(org, id2);
59705
+ if (run7.status !== "cancelled")
59706
+ return yield* new NotRunning({ run: id2, status: run7.status });
59707
+ return run7;
58740
59708
  });
58741
59709
  var start3 = exports_Effect.fn("Run.start")(function* (org, input) {
58742
59710
  const queue = yield* ScoreQueue;
@@ -58744,8 +59712,8 @@ var start3 = exports_Effect.fn("Run.start")(function* (org, input) {
58744
59712
  yield* queue.send(trials).pipe(exports_Effect.tapError(() => fail12(org, run7.id).pipe(exports_Effect.catchTag("RunNotFound", exports_Effect.die))));
58745
59713
  return run7;
58746
59714
  });
58747
- var tasksetOf = (org, run7) => get25(org, run7.taskset).pipe(exports_Effect.catchTags({ WorkloadNotFound: exports_Effect.die, TasksetNotFound: exports_Effect.die }));
58748
- var workloadOf = (org, run7) => get23(org, run7.taskset.workload).pipe(exports_Effect.catchTag("WorkloadNotFound", exports_Effect.die));
59715
+ var tasksetOf = (org, run7) => get26(org, run7.taskset).pipe(exports_Effect.catchTags({ WorkloadNotFound: exports_Effect.die, TasksetNotFound: exports_Effect.die }));
59716
+ var workloadOf = (org, run7) => get24(org, run7.taskset.workload).pipe(exports_Effect.catchTag("WorkloadNotFound", exports_Effect.die));
58749
59717
  var scoring2 = (org, run7, taskset) => {
58750
59718
  if (run7.config.scoring !== undefined)
58751
59719
  return exports_Effect.succeed(run7.config.scoring);
@@ -58780,21 +59748,24 @@ var settle = exports_Effect.fn("Run.settle")(function* (org, id2) {
58780
59748
  AND (SELECT count(*) FROM trial_results t WHERE t.run_id = r.id)
58781
59749
  >= jsonb_array_length(r.subjects) * (SELECT count(*) FROM taskset_traces m WHERE m.taskset_id = r.taskset_id)
58782
59750
  `;
58783
- yield* get26(org, id2);
59751
+ yield* get27(org, id2);
58784
59752
  });
58785
59753
  var Answer2 = exports_Data.taggedEnum();
58786
59754
  var KEY_LAG = Seconds2.make(Math.ceil(exports_Duration.toSeconds(lag)));
59755
+ var CREDIT_WAIT = Seconds2.make(300);
58787
59756
  var MAX_RETRY_AFTER = Seconds2.make(300);
58788
59757
  var waitOf = (failure) => {
58789
59758
  if (!exports_Predicate.isTagged(failure, "ProduceError"))
58790
59759
  return [];
58791
59760
  if (failure.reason === "KeyRequired")
58792
59761
  return [KEY_LAG];
59762
+ if (failure.reason === "OutOfCredit")
59763
+ return [CREDIT_WAIT];
58793
59764
  const asked = failure.rejection?.retryAfter;
58794
59765
  return asked === undefined ? [] : [Seconds2.make(Math.min(asked, MAX_RETRY_AFTER))];
58795
59766
  };
58796
- var retryOf = (failures2) => {
58797
- const waits = failures2.flatMap(waitOf);
59767
+ var retryOf = (failures) => {
59768
+ const waits = failures.flatMap(waitOf);
58798
59769
  return waits.length === 0 ? Answer2.Retry({}) : Answer2.Retry({ delay: Seconds2.make(Math.max(...waits)) });
58799
59770
  };
58800
59771
  var failed = (failure) => ({
@@ -58811,16 +59782,16 @@ var score = exports_Effect.fn("Run.score")(function* (trial, delivery) {
58811
59782
  attempts: delivery.attempts
58812
59783
  });
58813
59784
  const last2 = delivery.attempts > delivery.maxRetries;
58814
- const found = yield* exports_Effect.result(get26(trial.org, trial.runId));
59785
+ const found = yield* exports_Effect.result(get27(trial.org, trial.runId));
58815
59786
  if (exports_Result.isSuccess(found) && found.success.status !== "running")
58816
59787
  return Answer2.Done();
58817
- const { outcome: outcome2, failures: failures2 } = yield* exports_Effect.fromResult(found).pipe(exports_Effect.flatMap((run7) => exports_Effect.gen(function* () {
59788
+ const { outcome: outcome2, failures } = yield* exports_Effect.fromResult(found).pipe(exports_Effect.flatMap((run7) => exports_Effect.gen(function* () {
58818
59789
  const config = yield* scoring2(trial.org, run7, yield* tasksetOf(trial.org, run7));
58819
59790
  const workload = yield* workloadOf(trial.org, run7);
58820
59791
  const { task, recorded } = yield* load(trial.org, workload, trial.task, config.taskset);
58821
59792
  const replier = yield* exports_Match.valueTags(trial.subject, {
58822
59793
  production: () => exports_Effect.succeed(Replier.production({ recorded })),
58823
- candidate: ({ model }) => exports_Effect.map(get19(model), (read5) => Replier.candidate({ model: read5 }))
59794
+ candidate: ({ model }) => exports_Effect.map(get20(model), (read5) => Replier.candidate({ model: read5 }))
58824
59795
  });
58825
59796
  return yield* run6(config, task, replier, { org: trial.org, run: run7.id, workload });
58826
59797
  })), exports_Effect.catch((failure) => exports_Effect.succeed(failed(failure))), exports_Effect.catchCauseIf(exports_Cause.hasDies, (cause) => exports_Effect.logError("A trial died", cause).pipe(exports_Effect.as({
@@ -58829,7 +59800,7 @@ var score = exports_Effect.fn("Run.score")(function* (trial, delivery) {
58829
59800
  }))));
58830
59801
  if (outcome2.errors !== undefined && !last2) {
58831
59802
  yield* exports_Effect.logWarning("A trial failed; it will be retried", { errors: outcome2.errors });
58832
- return retryOf(failures2);
59803
+ return retryOf(failures);
58833
59804
  }
58834
59805
  return yield* writeResult(toResult(trial, outcome2)).pipe(exports_Effect.andThen(settle(trial.org, trial.runId)), exports_Effect.as(Answer2.Done()), exports_Effect.catchTags({
58835
59806
  RunNotFound: () => exports_Effect.succeed(Answer2.Done()),
@@ -58968,7 +59939,7 @@ var replyUsage = exports_Effect.fnUntraced(function* (org, id2) {
58968
59939
  });
58969
59940
  var readout = exports_Effect.fn("Run.readout")(function* (org, id2) {
58970
59941
  yield* exports_Effect.annotateCurrentSpan({ org, runId: id2 });
58971
- const run7 = yield* get26(org, id2);
59942
+ const run7 = yield* get27(org, id2);
58972
59943
  const taskset = yield* tasksetOf(org, run7);
58973
59944
  const config = yield* scoring2(org, run7, taskset);
58974
59945
  const results2 = yield* selectResults(org, id2);
@@ -59116,7 +60087,7 @@ var callIdsOf = (results2) => results2.flatMap(({ outcome: outcome2 }) => [
59116
60087
  var verdicts = exports_Effect.fn("Run.verdicts")(function* (org, id2, filter15, cursor) {
59117
60088
  yield* exports_Effect.annotateCurrentSpan({ org, runId: id2, cursor });
59118
60089
  const sql = yield* exports_SqlClient.SqlClient;
59119
- const run7 = yield* get26(org, id2);
60090
+ const run7 = yield* get27(org, id2);
59120
60091
  const taskset = yield* tasksetOf(org, run7);
59121
60092
  const config = yield* scoring2(org, run7, taskset);
59122
60093
  yield* unknownIn(run7, taskset, config, filter15);
@@ -59227,7 +60198,7 @@ var branchOf = (config, task, branch, scored, traces, calls2) => {
59227
60198
  var TRACE_READS = 4;
59228
60199
  var traceDetail = exports_Effect.fn("Run.traceDetail")(function* (org, id2, ref) {
59229
60200
  yield* exports_Effect.annotateCurrentSpan({ org, runId: id2, trace: ref.trace, leaf: ref.leaf });
59230
- const run7 = yield* get26(org, id2);
60201
+ const run7 = yield* get27(org, id2);
59231
60202
  const taskset = yield* tasksetOf(org, run7);
59232
60203
  const config = yield* scoring2(org, run7, taskset);
59233
60204
  const workload = yield* workloadOf(org, run7);
@@ -59235,7 +60206,7 @@ var traceDetail = exports_Effect.fn("Run.traceDetail")(function* (org, id2, ref)
59235
60206
  if (!exports_Array.isArrayNonEmpty(members2))
59236
60207
  return yield* new TraceNotFound({ run: id2, trace: ref });
59237
60208
  const read5 = yield* selectResults(org, id2, { trace: ref });
59238
- const whole = yield* get24(org, callIdsOf(read5));
60209
+ const whole = yield* get25(org, callIdsOf(read5));
59239
60210
  const calls2 = {
59240
60211
  answered: new Map(Array.from(whole, ([callId, call]) => [callId, { name: call.name, parsed: call.response.parsed }])),
59241
60212
  whole
@@ -59244,7 +60215,7 @@ var traceDetail = exports_Effect.fn("Run.traceDetail")(function* (org, id2, ref)
59244
60215
  const { task } = yield* load(org, workload, member2, config.taskset);
59245
60216
  const mine = read5.filter(({ trial }) => trial.task.leafNodeId === member2.leafNodeId);
59246
60217
  const ids = mine.flatMap(({ outcome: outcome2 }) => outcome2.attempts.map((attempt3) => attempt3.trace));
59247
- const traces = yield* exports_Effect.forEach(ids, (attempt3) => get20(org, attempt3).pipe(exports_Effect.catchTag("TraceNotFound", exports_Effect.die)), { concurrency: TRACE_READS });
60218
+ const traces = yield* exports_Effect.forEach(ids, (attempt3) => get21(org, attempt3).pipe(exports_Effect.catchTag("TraceNotFound", exports_Effect.die)), { concurrency: TRACE_READS });
59248
60219
  return branchOf(config, task.data, member2.leafNodeId, mine, new Map(exports_Array.zip(ids, traces)), calls2);
59249
60220
  }));
59250
60221
  return { run: id2, trace: ref.trace, branches };
@@ -59253,8 +60224,8 @@ var EPISODES_PAGE = 25;
59253
60224
  var episodeOf = exports_Effect.fnUntraced(function* (org, workload, config, result6) {
59254
60225
  const { attempts, judgeCalls = [] } = result6.outcome;
59255
60226
  const { task } = yield* load(org, workload, result6.trial.task, config.taskset);
59256
- const traces = yield* exports_Effect.forEach(attempts, ({ trace: trace3 }) => get20(org, trace3).pipe(exports_Effect.catchTag("TraceNotFound", exports_Effect.die)));
59257
- const calls2 = yield* get24(org, [
60227
+ const traces = yield* exports_Effect.forEach(attempts, ({ trace: trace3 }) => get21(org, trace3).pipe(exports_Effect.catchTag("TraceNotFound", exports_Effect.die)));
60228
+ const calls2 = yield* get25(org, [
59258
60229
  ...attempts.flatMap(({ scores }) => scores.judgeCalls ?? []),
59259
60230
  ...judgeCalls
59260
60231
  ]);
@@ -59263,7 +60234,7 @@ var episodeOf = exports_Effect.fnUntraced(function* (org, workload, config, resu
59263
60234
  var episodes = exports_Effect.fn("Run.episodes")(function* (org, id2) {
59264
60235
  yield* exports_Effect.annotateCurrentSpan({ org, runId: id2 });
59265
60236
  const sql = yield* exports_SqlClient.SqlClient;
59266
- const run7 = yield* get26(org, id2);
60237
+ const run7 = yield* get27(org, id2);
59267
60238
  const workload = yield* workloadOf(org, run7);
59268
60239
  const config = yield* scoring2(org, run7, yield* tasksetOf(org, run7));
59269
60240
  const page = exports_SqlSchema.findAll({
@@ -59437,7 +60408,7 @@ class Traces extends exports_HttpApiGroup.make("traces").add(exports_HttpApiEndp
59437
60408
 
59438
60409
  class Models extends exports_HttpApiGroup.make("models").add(exports_HttpApiEndpoint.get("list", "/", {
59439
60410
  params: InOrg.fields,
59440
- success: exports_Schema.Array(Model)
60411
+ success: exports_Schema.Array(Offered)
59441
60412
  })).middleware(Authorization).middleware(Membership2).middleware(Connection).middleware(SignedIn).prefix("/orgs/:org/models").annotateMerge(exports_OpenApi.annotations({
59442
60413
  title: "Models",
59443
60414
  description: "The models available to the org"
@@ -59517,11 +60488,12 @@ class Runs extends exports_HttpApiGroup.make("runs").add(exports_HttpApiEndpoint
59517
60488
  ScoringMissing,
59518
60489
  NothingToScore,
59519
60490
  Invalid2,
59520
- KeyRequired.pipe(exports_HttpApiSchema.status(409))
60491
+ KeyRequired.pipe(exports_HttpApiSchema.status(409)),
60492
+ OutOfCredit.pipe(exports_HttpApiSchema.status(409))
59521
60493
  ]
59522
60494
  }).annotateMerge(exports_OpenApi.annotations({
59523
60495
  summary: "Start a score run",
59524
- description: "Of a taskset, `<workload>/<taskset>`, for its `subjects`: `production`, the replies its traces " + "recorded, and models of the workload's pool (`RunSubjectNotInPool` when one isn't), whose replies are " + "judged. Production alone needs a config with criteria groups, which are all that score it " + "(`RunNothingToScore`). Answers with the run as started: " + "`running`, with its trials enqueued. It scores under its own `scoring` when sent, and otherwise under the " + "taskset's current config; a taskset with none needs one sent (`RunScoringMissing`). Its own config is " + "checked as saving it would be (`ScoringInvalid`). An org billed for its own calls needs a provider key for " + "every model the run calls, subjects and judges (`InferenceKeyRequired`)."
60496
+ description: "Of a taskset, `<workload>/<taskset>`, for its `subjects`: `production`, the replies its traces " + "recorded, and models of the workload's pool (`RunSubjectNotInPool` when one isn't), whose replies are " + "judged. Production alone needs a config with criteria groups, which are all that score it " + "(`RunNothingToScore`). Answers with the run as started: " + "`running`, with its trials enqueued. It scores under its own `scoring` when sent, and otherwise under the " + "taskset's current config; a taskset with none needs one sent (`RunScoringMissing`). Its own config is " + "checked as saving it would be (`ScoringInvalid`). The org must be able to pay for every model the run " + "calls."
59525
60497
  })), exports_HttpApiEndpoint.get("list", "/", {
59526
60498
  params: InOrg.fields,
59527
60499
  query: { ...Filter4.fields, cursor: exports_Schema.optional(RunId) },
@@ -59537,6 +60509,13 @@ class Runs extends exports_HttpApiGroup.make("runs").add(exports_HttpApiEndpoint
59537
60509
  }).annotateMerge(exports_OpenApi.annotations({
59538
60510
  summary: "Read a score run",
59539
60511
  description: "As it stands: its status, how many of its trials have a result, what they found per subject " + "(its points, scores and what its replies cost), each trial that failed, and what its judge calls cost."
60512
+ })), exports_HttpApiEndpoint.post("cancel", "/:run/cancel", {
60513
+ params: { ...InOrg.fields, run: RunId },
60514
+ success: Run,
60515
+ error: [NotFound11, NotRunning]
60516
+ }).annotateMerge(exports_OpenApi.annotations({
60517
+ summary: "Cancel a score run",
60518
+ description: "Stops a `running` run: answers it `cancelled`, and its trials not yet scoring are skipped. A trial " + "already scoring finishes, and its result is kept. A run already cancelled answers as it is; one that " + "completed or failed is `RunNotRunning`."
59540
60519
  })), exports_HttpApiEndpoint.get("verdicts", "/:run/verdicts", {
59541
60520
  params: { ...InOrg.fields, run: RunId },
59542
60521
  query: { ...VerdictFilter.fields, cursor: exports_Schema.optional(TrialResultId) },
@@ -59578,7 +60557,7 @@ class Export extends exports_HttpApiGroup.make("export").add(exports_HttpApiEndp
59578
60557
  })) {
59579
60558
  }
59580
60559
 
59581
- class Keys extends exports_HttpApiGroup.make("keys").add(exports_HttpApiEndpoint.post("create", "/", {
60560
+ class Keys2 extends exports_HttpApiGroup.make("keys").add(exports_HttpApiEndpoint.post("create", "/", {
59582
60561
  params: InOrg.fields,
59583
60562
  payload: CreateInput2,
59584
60563
  success: Created3
@@ -59604,13 +60583,27 @@ class Keys extends exports_HttpApiGroup.make("keys").add(exports_HttpApiEndpoint
59604
60583
  })) {
59605
60584
  }
59606
60585
 
59607
- class Providers2 extends exports_HttpApiGroup.make("providers").add(exports_HttpApiEndpoint.get("summary", "/", {
60586
+ class BillingGroup extends exports_HttpApiGroup.make("billing").add(exports_HttpApiEndpoint.get("summary", "/billing", {
59608
60587
  params: InOrg.fields,
59609
60588
  success: Summary2
59610
60589
  }).annotateMerge(exports_OpenApi.annotations({
59611
- summary: "Read who the org is billed to, and its provider keys",
59612
- description: "Every provider the stage supports, in the stage's order, each with the label of the key the " + "org saved for it, and who saved it when. Never the key itself. An org billed to Ambral may still have " + "keys saved: they are kept, and used again if it is billed to itself."
59613
- })), exports_HttpApiEndpoint.put("save", "/:upstream/key", {
60590
+ summary: "Read the org's billing",
60591
+ description: "How the org pays for its model calls, as its members see it. A provider key is described by its " + "label and who saved it when, never by the key itself."
60592
+ })), exports_HttpApiEndpoint.get("credits", "/billing/credits", {
60593
+ params: InOrg.fields,
60594
+ query: { before: exports_Schema.optionalKey(exports_Schema.NumberFromString.pipe(exports_Schema.decodeTo(Seq))) },
60595
+ success: exports_Schema.Array(Credited)
60596
+ }).annotateMerge(exports_OpenApi.annotations({
60597
+ summary: "List the credit added to the org",
60598
+ description: "Each time credit was added to the org or taken back, newest first, one page at a time. With " + "`before`, the page before that entry."
60599
+ })), exports_HttpApiEndpoint.get("spend", "/billing/spend", {
60600
+ params: InOrg.fields,
60601
+ query: { from: exports_Schema.optionalKey(Day2), to: exports_Schema.optionalKey(Day2) },
60602
+ success: exports_Schema.Array(SpendDay)
60603
+ }).annotateMerge(exports_OpenApi.annotations({
60604
+ summary: "List the org's spend",
60605
+ description: "What the org spent per day and model, newest day first, from `from` to `to`. By default, the " + "last 30 days."
60606
+ })), exports_HttpApiEndpoint.put("save", "/providers/:upstream/key", {
59614
60607
  params: { ...InOrg.fields, upstream: UpstreamId },
59615
60608
  payload: SaveInput,
59616
60609
  success: Saved,
@@ -59618,16 +60611,17 @@ class Providers2 extends exports_HttpApiGroup.make("providers").add(exports_Http
59618
60611
  }).annotateMerge(exports_OpenApi.annotations({
59619
60612
  summary: "Save the org's key for a provider",
59620
60613
  description: "Replaces any key the org saved for it. The provider checks the key first: one it refuses is " + "`ProviderKeyRejected`, and nothing is stored. The key is stored sealed and never shown again; the answer " + "carries the provider's label for it. Calls to the provider start using it within about a minute."
59621
- })), exports_HttpApiEndpoint.delete("remove", "/:upstream/key", {
60614
+ })), exports_HttpApiEndpoint.delete("remove", "/providers/:upstream/key", {
59622
60615
  params: { ...InOrg.fields, upstream: UpstreamId },
59623
60616
  success: exports_HttpApiSchema.NoContent,
59624
60617
  error: NotFound5
59625
60618
  }).annotateMerge(exports_OpenApi.annotations({
59626
60619
  summary: "Remove the org's key for a provider",
59627
- description: "While the org is billed to itself, its calls to the provider are refused again within about a " + "minute. Removing a key the org hasn't saved changes nothing."
59628
- }))).middleware(Authorization).middleware(Membership2).middleware(Connection).middleware(SignedIn).prefix("/orgs/:org/providers").annotateMerge(exports_OpenApi.annotations({
59629
- title: "Providers",
59630
- description: "The org's own keys for the model providers the stage supports, which pay for its model calls"
60620
+ description: "While the org pays its providers directly, its calls to the provider are refused again within " + "about a minute. Removing a key the org hasn't saved changes nothing."
60621
+ }))).middleware(Authorization).middleware(Membership2).middleware(Connection).middleware(SignedIn).prefix("/orgs/:org").annotateMerge(exports_OpenApi.annotations({
60622
+ exclude: true,
60623
+ title: "Billing",
60624
+ description: "How the org pays for its model calls"
59631
60625
  })) {
59632
60626
  }
59633
60627
  var OfMember = { ...InOrg.fields, member: MemberId };
@@ -59733,12 +60727,12 @@ class Accepting extends exports_HttpApiGroup.make("accepting").add(exports_HttpA
59733
60727
  })) {
59734
60728
  }
59735
60729
 
59736
- class Api2 extends exports_HttpApi.make("ambral-platform").add(Orgs).add(Workloads).add(Traces).add(Models).add(Tasksets).add(Runs).add(Export).add(Keys).add(Providers2).add(OrgMembers).add(OwnMembership).add(OrgInvitations).add(OpenInvitation).add(Accepting).prefix("/api").annotateMerge(exports_OpenApi.annotations({ title: "Ambral Platform API" })).annotate(exports_HttpApi.PayloadParseOptions, { onExcessProperty: "error" }) {
60730
+ class Api2 extends exports_HttpApi.make("ambral-platform").add(Orgs).add(Workloads).add(Traces).add(Models).add(Tasksets).add(Runs).add(Export).add(Keys2).add(BillingGroup).add(OrgMembers).add(OwnMembership).add(OrgInvitations).add(OpenInvitation).add(Accepting).prefix("/api").annotateMerge(exports_OpenApi.annotations({ title: "Ambral Platform API" })).annotate(exports_HttpApi.PayloadParseOptions, { onExcessProperty: "error" }) {
59737
60731
  }
59738
60732
  // ../core/src/Scoring/ScoringPresets.ts
59739
60733
  var exports_ScoringPresets = {};
59740
60734
  __export(exports_ScoringPresets, {
59741
- summaries: () => summaries,
60735
+ summaries: () => summaries2,
59742
60736
  config: () => config,
59743
60737
  TakesNoJudge: () => TakesNoJudge,
59744
60738
  Summary: () => Summary5,
@@ -59879,7 +60873,7 @@ var Summary5 = exports_Schema.Struct({
59879
60873
  use: exports_Schema.String,
59880
60874
  judge: exports_Schema.Boolean
59881
60875
  }).annotate({ identifier: "ScoringPresetSummary" });
59882
- var summaries = exports_Record.toEntries(presets).map(([name, preset]) => ({
60876
+ var summaries2 = exports_Record.toEntries(presets).map(([name, preset]) => ({
59883
60877
  name,
59884
60878
  use: preset.use,
59885
60879
  judge: exports_Match.valueTags(preset, { Judged: () => true, Unjudged: () => false })
@@ -59954,7 +60948,7 @@ var layer19 = exports_Layer.effect(Credentials, exports_Effect.gen(function* ()
59954
60948
  const directory = path.join(config2, "ambral", "sessions");
59955
60949
  const file3 = path.join(directory, `${encodeURIComponent(url.origin)}.json`);
59956
60950
  const failed2 = (reason) => (cause) => new CredentialsError({ reason, file: file3, cause });
59957
- const get27 = exports_Effect.gen(function* () {
60951
+ const get28 = exports_Effect.gen(function* () {
59958
60952
  if (!(yield* fs.exists(file3)))
59959
60953
  return {};
59960
60954
  const text3 = yield* fs.readFileString(file3);
@@ -59967,7 +60961,7 @@ var layer19 = exports_Layer.effect(Credentials, exports_Effect.gen(function* ()
59967
60961
  yield* write4(file3, text3, { mode: FILE_MODE });
59968
60962
  }, exports_Effect.provideService(exports_FileSystem.FileSystem, fs));
59969
60963
  const set9 = (session) => (Object.values(session).every((value5) => value5 === undefined) ? fs.remove(file3, { force: true }) : write5(session)).pipe(exports_Effect.mapError(failed2("write")));
59970
- return Credentials.of({ get: get27, set: set9 });
60964
+ return Credentials.of({ get: get28, set: set9 });
59971
60965
  }));
59972
60966
 
59973
60967
  // src/Ambral.ts
@@ -60007,7 +61001,6 @@ var signedOut = exports_Layer.effect(SignIn2, exports_Effect.gen(function* () {
60007
61001
  var Json3 = exports_GlobalFlag.Setting("json")({
60008
61002
  flag: exports_Flag.Boolean("json").pipe(exports_Flag.withDescription("Print the result, or the failure, as JSON"), exports_Flag.withDefault(false))
60009
61003
  });
60010
- var PENDING_NOTE = "Ambral currently enables new orgs manually; reach out to founders@ambral.com for platform access.";
60011
61004
  var table2 = (rows) => {
60012
61005
  const widths = rows[0]?.map((_, column) => Math.max(...rows.map((row) => row[column]?.length ?? 0))) ?? [];
60013
61006
  return rows.map((row) => row.map((cell, column) => cell.padEnd(widths[column] ?? 0)).join(" ").trimEnd()).join(`
@@ -60110,7 +61103,7 @@ var layer20 = exports_Layer.effect(ProjectLink, exports_Effect.gen(function* ()
60110
61103
  const text3 = yield* fs.readFileString(file3);
60111
61104
  return yield* exports_Schema.decodeEffect(LinksFile)(text3).pipe(exports_Effect.mapError(() => new ProjectLinkError({ reason: "unreadable", file: file3 })));
60112
61105
  }).pipe(exports_Effect.catchTag("PlatformError", (cause) => exports_Effect.fail(new ProjectLinkError({ reason: "read", file: file3, cause }))));
60113
- const get27 = exports_Effect.gen(function* () {
61106
+ const get28 = exports_Effect.gen(function* () {
60114
61107
  const directory = yield* nearest3;
60115
61108
  if (directory === undefined)
60116
61109
  return;
@@ -60132,20 +61125,17 @@ var layer20 = exports_Layer.effect(ProjectLink, exports_Effect.gen(function* ()
60132
61125
  yield* write5(directory, { ...links, [url.origin]: link4 }).pipe(exports_Effect.mapError((cause) => new ProjectLinkError({ reason: "write", file: fileIn(directory), cause })));
60133
61126
  return directory;
60134
61127
  });
60135
- return ProjectLink.of({ get: get27, set: set9 });
61128
+ return ProjectLink.of({ get: get28, set: set9 });
60136
61129
  }));
60137
61130
 
60138
61131
  // src/Orgs/Orgs.ts
60139
- var Org2 = exports_GlobalFlag.Setting("org")({
61132
+ var Org3 = exports_GlobalFlag.Setting("org")({
60140
61133
  flag: exports_Flag.String("org").pipe(exports_Flag.withSchema(exports_OrgAccess.Slug), exports_Flag.withDescription("The org to act in, by slug, in place of the one this project is linked to"), exports_Flag.optional)
60141
61134
  });
60142
61135
  var table3 = (memberships2, marked) => table2([
60143
61136
  ["ORG", "NAME", "ROLE", "STATUS", ""],
60144
61137
  ...memberships2.map(({ org, slug, name, role, state: state2 }) => [slug, name, role, state2, org === marked ? "linked" : ""])
60145
61138
  ]);
60146
- var noteFor = (memberships2) => memberships2.some(({ state: state2 }) => state2 === "pending") ? `
60147
-
60148
- ${PENDING_NOTE}` : "";
60149
61139
  var yours = (memberships2) => memberships2.length === 0 ? "You aren't a member of any org." : `Your orgs:
60150
61140
 
60151
61141
  ${table3(memberships2)}`;
@@ -60174,7 +61164,7 @@ var bySlug = exports_Effect.fnUntraced(function* (slug) {
60174
61164
  return yield* exports_Array.findFirst(all6, (membership) => membership.slug === slug).pipe(exports_Effect.fromOption, exports_Effect.mapError(() => new UnknownOrg({ slug, memberships: all6 })));
60175
61165
  });
60176
61166
  var current = exports_Effect.gen(function* () {
60177
- const named = yield* Org2;
61167
+ const named = yield* Org3;
60178
61168
  if (exports_Option.isSome(named))
60179
61169
  return yield* bySlug(named.value);
60180
61170
  const link4 = yield* (yield* ProjectLink).get;
@@ -60186,52 +61176,52 @@ var current = exports_Effect.gen(function* () {
60186
61176
  var acting = exports_Effect.filterOrElse(current, exports_Predicate.isNotUndefined, () => exports_Effect.flatMap(memberships2, (all6) => exports_Effect.fail(new NotLinked({ memberships: all6 }))));
60187
61177
  var inProject = layer20.pipe(exports_Layer.provideMerge(signedIn));
60188
61178
  var Listed = exports_Schema.Struct({ membership: exports_OrgAccess.Membership, linked: exports_Schema.Boolean });
60189
- var listed3 = {
61179
+ var listed4 = {
60190
61180
  schema: exports_Schema.Array(Listed),
60191
61181
  text: (rows) => {
60192
61182
  const all6 = rows.map(({ membership }) => membership);
60193
61183
  const linked = rows.find((row) => row.linked)?.membership.org;
60194
- return all6.length === 0 ? "You aren't a member of any org. Run `ambral orgs create <name>` to create one." : `${table3(all6, linked)}${noteFor(all6)}`;
61184
+ return all6.length === 0 ? "You aren't a member of any org. Run `ambral orgs create <name>` to create one." : table3(all6, linked);
60195
61185
  }
60196
61186
  };
60197
61187
  var Used = exports_Schema.Struct({ membership: exports_OrgAccess.Membership, project: exports_Schema.String });
60198
61188
  var used = {
60199
61189
  schema: Used,
60200
- text: ({ membership, project: project2 }) => `Linked this project (${project2}) to ${membership.name}.${noteFor([membership])}`
61190
+ text: ({ membership, project }) => `Linked this project (${project}) to ${membership.name}.`
60201
61191
  };
60202
61192
  var Created4 = exports_Schema.Struct({ membership: exports_OrgAccess.Membership, project: exports_Schema.optional(exports_Schema.String) });
60203
61193
  var created = {
60204
61194
  schema: Created4,
60205
- text: ({ membership, project: project2 }) => `Created ${membership.name} (${membership.slug})${project2 === undefined ? "" : ` and linked this project (${project2}) to it`}.
60206
- Status: ${membership.state}${noteFor([membership])}`
61195
+ text: ({ membership, project }) => `Created ${membership.name} (${membership.slug})${project === undefined ? "" : ` and linked this project (${project}) to it`}.
61196
+ Status: ${membership.state}`
60207
61197
  };
60208
61198
  var list11 = exports_Command.make("list", {}, () => exports_Effect.gen(function* () {
60209
61199
  const all6 = yield* memberships2;
60210
61200
  const link4 = yield* (yield* ProjectLink).get;
60211
- yield* print(listed3, all6.map((membership) => ({ membership, linked: membership.org === link4?.org })));
61201
+ yield* print(listed4, all6.map((membership) => ({ membership, linked: membership.org === link4?.org })));
60212
61202
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("List your orgs, with your role and each org's status"));
60213
61203
  var use2 = exports_Command.make("use", {
60214
61204
  slug: exports_Argument.String("slug").pipe(exports_Argument.withDescription("The org's slug, as `ambral orgs list` shows it"), exports_Argument.withSchema(exports_OrgAccess.Slug))
60215
61205
  }, ({ slug }) => exports_Effect.gen(function* () {
60216
61206
  const membership = yield* bySlug(slug);
60217
- const project2 = yield* (yield* ProjectLink).set(exports_Struct.pick(membership, ["org", "slug"]));
60218
- yield* print(used, { membership, project: project2 });
61207
+ const project = yield* (yield* ProjectLink).set(exports_Struct.pick(membership, ["org", "slug"]));
61208
+ yield* print(used, { membership, project });
60219
61209
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("Link this project to an org: commands run in it act in that org"));
60220
61210
  var create4 = exports_Command.make("create", {
60221
61211
  name: exports_Argument.String("name").pipe(exports_Argument.withDescription("The org's name; its slug is derived from it"), exports_Argument.withSchema(exports_OrgAccess.Name))
60222
61212
  }, ({ name }) => exports_Effect.gen(function* () {
60223
- const project2 = yield* ProjectLink;
60224
- const unlinked = (yield* project2.get) === undefined;
61213
+ const project = yield* ProjectLink;
61214
+ const unlinked = (yield* project.get) === undefined;
60225
61215
  const membership = yield* (yield* Ambral).platform.orgs.create({ payload: { name } });
60226
61216
  yield* print(created, {
60227
61217
  membership,
60228
- project: unlinked ? yield* project2.set(exports_Struct.pick(membership, ["org", "slug"])) : undefined
61218
+ project: unlinked ? yield* project.set(exports_Struct.pick(membership, ["org", "slug"])) : undefined
60229
61219
  });
60230
61220
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("Create an org you own; links this project to it if it isn't linked yet"));
60231
61221
  var orgs = exports_Command.make("orgs").pipe(exports_Command.withDescription("List your orgs, create one, and link this project to one"), exports_Command.withSubcommands([list11, use2, create4]));
60232
61222
 
60233
61223
  // src/Keys/Keys.ts
60234
- var listed4 = {
61224
+ var listed5 = {
60235
61225
  schema: exports_Schema.Array(exports_ApiKey.Summary),
60236
61226
  text: (keys5) => keys5.length === 0 ? "This org has no keys. Create one in the web app." : table2([
60237
61227
  ["NAME", "KIND", "KEY", "CREATED BY", "CREATED", "STATUS"],
@@ -60248,7 +61238,7 @@ var listed4 = {
60248
61238
  var list12 = exports_Command.make("list", {}, () => exports_Effect.gen(function* () {
60249
61239
  const { platform } = yield* Ambral;
60250
61240
  const { org } = yield* acting;
60251
- yield* print(listed4, yield* platform.keys.list({ params: { org } }));
61241
+ yield* print(listed5, yield* platform.keys.list({ params: { org } }));
60252
61242
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("List the org's API keys: their names and starts, never their secrets"));
60253
61243
  var keys5 = exports_Command.make("keys").pipe(exports_Command.withDescription("List the org's API keys"), exports_Command.withSubcommands([list12]));
60254
61244
  // src/Login/Login.ts
@@ -60265,7 +61255,7 @@ var Refusal = exports_Schema.Union([
60265
61255
  ]);
60266
61256
  var Step2 = exports_Data.taggedEnum();
60267
61257
  var SLOW_DOWN = exports_Time.Seconds.make(5);
60268
- var next3 = (pending, answer, now4) => {
61258
+ var next4 = (pending, answer, now4) => {
60269
61259
  const wait = (interval, delay3 = interval) => now4 >= pending.expiresAt ? Step2.Fail({ reason: "expired" }) : Step2.Wait({ pending: { ...pending, interval }, delay: delay3 });
60270
61260
  return exports_Result.match(answer, {
60271
61261
  onSuccess: ({ access_token }) => Step2.Done({ token: access_token }),
@@ -60324,7 +61314,7 @@ var SignedOut2 = {
60324
61314
  text: ({ address }) => `Signed out of ${address}.`
60325
61315
  };
60326
61316
  var signingIn = exports_Layer.mergeAll(signedOut, layer19).pipe(exports_Layer.provideMerge(layer18));
60327
- var readable = exports_Effect.flatMap(Credentials, ({ get: get27 }) => get27.pipe(exports_Effect.catchIf((error2) => error2.reason === "unreadable", () => exports_Effect.succeed({}))));
61317
+ var readable = exports_Effect.flatMap(Credentials, ({ get: get28 }) => get28.pipe(exports_Effect.catchIf((error2) => error2.reason === "unreadable", () => exports_Effect.succeed({}))));
60328
61318
  var start4 = exports_Effect.gen(function* () {
60329
61319
  const signIn = yield* SignIn2;
60330
61320
  const credentials = yield* Credentials;
@@ -60358,9 +61348,9 @@ var redeem = exports_Effect.fnUntraced(function* (pending) {
60358
61348
  });
60359
61349
  var poll2 = (pending, delay3 = pending.interval) => exports_Effect.gen(function* () {
60360
61350
  yield* exports_Effect.sleep(exports_Duration.seconds(delay3));
60361
- const step = next3(pending, yield* redeem(pending), yield* exports_Time.now);
61351
+ const step = next4(pending, yield* redeem(pending), yield* exports_Time.now);
60362
61352
  return yield* Step2.$match(step, {
60363
- Wait: ({ pending: later, delay: next4 }) => exports_Effect.andThen(later.interval === pending.interval ? exports_Effect.void : exports_Effect.asVoid(settle2(pending, { pending: later })), poll2(later, next4)),
61353
+ Wait: ({ pending: later, delay: next5 }) => exports_Effect.andThen(later.interval === pending.interval ? exports_Effect.void : exports_Effect.asVoid(settle2(pending, { pending: later })), poll2(later, next5)),
60364
61354
  Done: ({ token }) => exports_Effect.succeed(token),
60365
61355
  Fail: ({ reason }) => settle2(pending, {}).pipe(exports_Effect.andThen(exports_Effect.fail(reason === "denied" ? new SignInDenied : new SignInExpired)))
60366
61356
  });
@@ -60422,22 +61412,22 @@ var whoami = exports_Command.make("whoami", {}, () => exports_Effect.gen(functio
60422
61412
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("Show the account this CLI is signed in as, the Ambral address, and the org it acts in"));
60423
61413
 
60424
61414
  // src/Models/Models.ts
60425
- var listed5 = {
60426
- schema: exports_Schema.Array(exports_Model.Model),
60427
- text: (models2) => models2.length === 0 ? "No models are available to this org. If it pays for its own model calls, an owner or admin can save a " + "provider key on its Providers page in the Ambral web app." : table2([
61415
+ var listed6 = {
61416
+ schema: exports_Schema.Array(exports_Model.Offered),
61417
+ text: (models2) => models2.length === 0 ? "No models are available to this org. Its Billing page in the Ambral web app shows how it pays for " + "them." : table2([
60428
61418
  ["MODEL", "FAMILY", "INPUT $/MTOK", "OUTPUT $/MTOK"],
60429
- ...models2.map(({ id: id2, base }) => [
60430
- id2,
60431
- base.family,
60432
- String(base.price.inputPerMTok),
60433
- String(base.price.outputPerMTok)
61419
+ ...models2.map(({ model, price }) => [
61420
+ model.id,
61421
+ model.base.family,
61422
+ exports_BigDecimal.format(price.inputPerMTok),
61423
+ exports_BigDecimal.format(price.outputPerMTok)
60434
61424
  ])
60435
61425
  ])
60436
61426
  };
60437
61427
  var list13 = exports_Command.make("list", {}, () => exports_Effect.gen(function* () {
60438
61428
  const { platform: platform2 } = yield* Ambral;
60439
61429
  const { org } = yield* acting;
60440
- yield* print(listed5, yield* platform2.models.list({ params: { org } }));
61430
+ yield* print(listed6, yield* platform2.models.list({ params: { org } }));
60441
61431
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("List the models available to this org, with their prices"), exports_Command.withExamples([{ command: "ambral models list --json", description: "Every available model, as JSON" }]));
60442
61432
  var models2 = exports_Command.make("models").pipe(exports_Command.withDescription("List the models workloads can serve"), exports_Command.withSubcommands([list13]));
60443
61433
 
@@ -60603,9 +61593,9 @@ var fillable = (value5, field, indent, seen) => {
60603
61593
  };
60604
61594
  var entry = (key3, value5, field, indent, spaced2, seen = new Set) => {
60605
61595
  const pad3 = " ".repeat(indent);
60606
- const one = inline(value5);
61596
+ const one2 = inline(value5);
60607
61597
  const above = [...spaced2 ? [""] : [], ...comment(keyDescription(field), pad3)];
60608
- return one === undefined ? [...above, `${pad3}${keyOf(key3)}:`, ...block(value5, field, indent + 2, seen)] : [...above, `${pad3}${keyOf(key3)}: ${one}`, ...fillable(value5, field, indent, seen)];
61598
+ return one2 === undefined ? [...above, `${pad3}${keyOf(key3)}:`, ...block(value5, field, indent + 2, seen)] : [...above, `${pad3}${keyOf(key3)}: ${one2}`, ...fillable(value5, field, indent, seen)];
60609
61599
  };
60610
61600
  var block = (value5, ast, indent, seen = new Set) => {
60611
61601
  const pad3 = " ".repeat(indent);
@@ -60614,9 +61604,9 @@ var block = (value5, ast, indent, seen = new Set) => {
60614
61604
  return [];
60615
61605
  if (isArray2(value5)) {
60616
61606
  return value5.flatMap((item, index2) => {
60617
- const one = inline(item) ?? (isArray2(item) ? JSON.stringify(item) : undefined);
60618
- if (one !== undefined)
60619
- return [`${pad3}- ${one}`];
61607
+ const one2 = inline(item) ?? (isArray2(item) ? JSON.stringify(item) : undefined);
61608
+ if (one2 !== undefined)
61609
+ return [`${pad3}- ${one2}`];
60620
61610
  return dashed(block(item, itemOf(schema2, index2), indent + 2, seen), pad3);
60621
61611
  });
60622
61612
  }
@@ -60665,7 +61655,7 @@ var annotated = (header2, config2) => [
60665
61655
  emit(encodeConfig2(config2), exports_Env.EnvConfig).trimEnd()
60666
61656
  ].join(`
60667
61657
  `);
60668
- var listed6 = {
61658
+ var listed7 = {
60669
61659
  schema: exports_Schema.Array(exports_ScoringPresets.Summary),
60670
61660
  text: (presets2) => [
60671
61661
  table2([
@@ -60713,7 +61703,7 @@ var presetCommand = exports_Command.make("preset", {
60713
61703
  if (exports_Option.isNone(name)) {
60714
61704
  if (exports_Option.isSome(judge))
60715
61705
  return yield* new JudgeWithoutPreset({ judge: judge.value });
60716
- return yield* print(listed6, exports_ScoringPresets.summaries);
61706
+ return yield* print(listed7, exports_ScoringPresets.summaries);
60717
61707
  }
60718
61708
  const config2 = yield* exports_Effect.fromResult(exports_ScoringPresets.config(name.value, exports_Option.getOrUndefined(judge)));
60719
61709
  yield* print(preset(name.value), config2);
@@ -60724,7 +61714,7 @@ var presetCommand = exports_Command.make("preset", {
60724
61714
  description: "Start a scoring file from the balanced preset, its judges asking that model"
60725
61715
  }
60726
61716
  ]));
60727
- var get27 = exports_Command.make("get", { taskset: addressArgument }, ({ taskset }) => exports_Effect.gen(function* () {
61717
+ var get28 = exports_Command.make("get", { taskset: addressArgument }, ({ taskset }) => exports_Effect.gen(function* () {
60728
61718
  const { platform: platform2 } = yield* Ambral;
60729
61719
  const { org } = yield* acting;
60730
61720
  yield* print(fetched(taskset), yield* platform2.tasksets.getScoring({ params: { org, workload: taskset.workload, taskset: taskset.taskset } }));
@@ -60756,15 +61746,15 @@ var set9 = exports_Command.make("set", {
60756
61746
  description: "Save it as the next version"
60757
61747
  }
60758
61748
  ]));
60759
- var scoring3 = exports_Command.make("scoring").pipe(exports_Command.withDescription("Read and set how a taskset is scored"), exports_Command.withSubcommands([presetCommand, get27, set9]));
61749
+ var scoring3 = exports_Command.make("scoring").pipe(exports_Command.withDescription("Read and set how a taskset is scored"), exports_Command.withSubcommands([presetCommand, get28, set9]));
60760
61750
 
60761
61751
  // src/Traces/Traces.ts
60762
61752
  var GENERATED = "(generated)";
60763
61753
  var QUOTED_CHARS = 40;
60764
61754
  var quoted = (text3) => JSON.stringify(text3.length > QUOTED_CHARS ? `${text3.slice(0, QUOTED_CHARS - 1)}…` : text3);
60765
- var listed7 = (workload) => ({
61755
+ var listed8 = (workload) => ({
60766
61756
  schema: exports_TraceReading.Page,
60767
- text: ({ traces, next: next4 }) => {
61757
+ text: ({ traces, next: next5 }) => {
60768
61758
  if (traces.length === 0) {
60769
61759
  return `No traces recorded for ${workload} yet. A session is stored once it has gone quiet for a ` + `little while; see how to connect an agent with \`ambral workloads get ${workload}\`.`;
60770
61760
  }
@@ -60780,7 +61770,7 @@ var listed7 = (workload) => ({
60780
61770
  ])
60781
61771
  ]);
60782
61772
  const generated2 = traces.some((trace3) => trace3.session === undefined) ? ["", `A ${GENERATED} session sent no x-session-id, so each of its requests is a trace of its own.`] : [];
60783
- const more = next4 === undefined ? [] : ["", `Older traces: \`ambral traces list ${workload} --cursor ${next4}\``];
61773
+ const more = next5 === undefined ? [] : ["", `Older traces: \`ambral traces list ${workload} --cursor ${next5}\``];
60784
61774
  return [rows, ...generated2, ...more].join(`
60785
61775
  `);
60786
61776
  }
@@ -60810,7 +61800,7 @@ var dollars = new Intl.NumberFormat("en-US", {
60810
61800
  currency: "USD",
60811
61801
  maximumSignificantDigits: 4
60812
61802
  });
60813
- var tokensOf = (usage3) => {
61803
+ var tokensOf3 = (usage3) => {
60814
61804
  if (usage3 == null)
60815
61805
  return [];
60816
61806
  const cached3 = usage3.cached_input_tokens ?? 0;
@@ -60827,7 +61817,7 @@ var callLines = (call) => {
60827
61817
  [
60828
61818
  call.model ?? "unknown model",
60829
61819
  call.finish_reason ?? "no finish reason",
60830
- ...tokensOf(call.usage),
61820
+ ...tokensOf3(call.usage),
60831
61821
  ...latencyOf(call.time),
60832
61822
  ...call.endpoint == null ? [] : [call.endpoint]
60833
61823
  ].join(" · "),
@@ -60847,11 +61837,11 @@ var stepLines = ({ id: id2, node, calls: calls2 }) => [
60847
61837
  `))] : indented(" ", callLines(call).join(`
60848
61838
  `)))
60849
61839
  ];
60850
- var plural2 = (count2, one, many) => `${count2} ${count2 === 1 ? one : many}`;
61840
+ var plural2 = (count2, one2, many) => `${count2} ${count2 === 1 ? one2 : many}`;
60851
61841
  var sessionOf2 = (session) => session === undefined ? "no session" : session.source === "unspecified" ? `session ${session.id} ${GENERATED}` : `session ${session.id} (via ${session.via})`;
60852
61842
  var read5 = {
60853
61843
  schema: exports_TraceReading.Detail,
60854
- text: ({ preview: preview2, info: info2, status: status3, settledAt, turns, latest, branches, unplaced }) => [
61844
+ text: ({ preview: preview2, info: info2, status: status3, settledAt, turns, latest: latest2, branches, unplaced }) => [
60855
61845
  `Trace ${preview2.id} · ${sessionOf2(info2.session)} · recorded ${minuteOf(preview2.recordedAt)} UTC · ` + `${preview2.steps} steps · ${preview2.branches} ${preview2.branches === 1 ? "branch" : "branches"}`,
60856
61846
  `${settledAt === undefined ? status3 : `settled ${minuteOf(settledAt)} UTC`} · ${turns} turns recorded`,
60857
61847
  `Workload ${info2.workload} ` + (info2.workloadId === undefined ? "(no id: recorded before it existed, or as a passthrough)" : `(${info2.workloadId})`) + ` · requested ${info2.requestedModel} · served by ${info2.modelId} · prompt version ${info2.sourcePromptVersion}`,
@@ -60860,7 +61850,7 @@ var read5 = {
60860
61850
  `))),
60861
61851
  ...branches.flatMap(({ leaf, tools, continuedBy, tasksets, steps }) => [
60862
61852
  "",
60863
- `Branch ${preview2.id}:${leaf}${leaf === latest ? " (latest)" : ""}` + (continuedBy.length === 0 ? "" : ` · continued by ${continuedBy.map((end3) => `${preview2.id}:${end3}`).join(", ")}`),
61853
+ `Branch ${preview2.id}:${leaf}${leaf === latest2 ? " (latest)" : ""}` + (continuedBy.length === 0 ? "" : ` · continued by ${continuedBy.map((end3) => `${preview2.id}:${end3}`).join(", ")}`),
60864
61854
  `Tools offered: ${tools.length === 0 ? "none" : tools.map((tool) => tool.name).join(", ")}`,
60865
61855
  ...tasksets.length === 0 ? [] : [`In tasksets: ${tasksets.map(({ id: id2, name, leaf: end3 }) => `${name} (${id2}, to [${end3}])`).join(", ")}`],
60866
61856
  ...steps.flatMap(stepLines)
@@ -60886,14 +61876,14 @@ var list14 = exports_Command.make("list", {
60886
61876
  const { org } = yield* acting;
60887
61877
  const page = yield* platform2.traces.list({
60888
61878
  params: { org, workload },
60889
- query: exports_Option.match(cursor, { onNone: () => ({}), onSome: (next4) => ({ cursor: next4 }) })
61879
+ query: exports_Option.match(cursor, { onNone: () => ({}), onSome: (next5) => ({ cursor: next5 }) })
60890
61880
  });
60891
- yield* print(listed7(workload), page);
61881
+ yield* print(listed8(workload), page);
60892
61882
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("List a workload's recorded traces, newest first: each one's id, session, steps, the tools it called and its " + "first user message"), exports_Command.withExamples([
60893
61883
  { command: "ambral traces list support-agent", description: "Check that an agent's sessions are recorded" },
60894
61884
  { command: "ambral traces list support-agent --json", description: "As JSON, with each page's `next`" }
60895
61885
  ]));
60896
- var get28 = exports_Command.make("get", {
61886
+ var get29 = exports_Command.make("get", {
60897
61887
  trace: exports_Argument.String("trace").pipe(exports_Argument.withDescription("The trace's id, as `ambral traces list` shows it (tr_…), or one of its branches, as this command names " + "them (tr_…:<leaf>)"), exports_Argument.withSchema(exports_TraceReading.Ref)),
60898
61888
  raw: exports_Flag.Boolean("raw").pipe(exports_Flag.withDescription("Print the trace as stored, every node and call, as JSON in verifiers' trace format, which verifiers loads. " + "It is the whole trace, so name the trace (tr_…), not a branch. Its `id` is the recording key, not tr_…"), exports_Flag.withDefault(false))
60899
61889
  }, ({ trace: trace3, raw: raw4 }) => exports_Effect.gen(function* () {
@@ -60916,12 +61906,15 @@ var get28 = exports_Command.make("get", {
60916
61906
  description: "The whole trace as stored, in verifiers' trace format"
60917
61907
  }
60918
61908
  ]));
60919
- var traces = exports_Command.make("traces").pipe(exports_Command.withDescription("List and read a workload's recorded sessions"), exports_Command.withSubcommands([list14, get28]));
61909
+ var traces = exports_Command.make("traces").pipe(exports_Command.withDescription("List and read a workload's recorded sessions"), exports_Command.withSubcommands([list14, get29]));
60920
61910
 
60921
61911
  // src/Runs/Runs.ts
60922
61912
  class RunFailed extends exports_Schema.TaggedError()("RunFailed", { readout: exports_Run.Readout }) {
60923
61913
  }
60924
61914
 
61915
+ class RunCancelled extends exports_Schema.TaggedError()("RunCancelled", { run: exports_Ids.RunId }) {
61916
+ }
61917
+
60925
61918
  class WaitTimedOut extends exports_Schema.TaggedError()("RunWaitTimedOut", { run: exports_Ids.RunId }) {
60926
61919
  }
60927
61920
  var Subjects2 = of5(exports_Run.Subjects);
@@ -60950,7 +61943,7 @@ var columnOrder = { production: 0, candidate: 1 };
60950
61943
  var columnsOf = (subjects) => subjects.toSorted((a, b) => columnOrder[a.subject._tag] - columnOrder[b.subject._tag]);
60951
61944
  var meanOf = (summary3) => summary3 === undefined ? "–" : `${summary3.mean.toFixed(2)} (${summary3.count})`;
60952
61945
  var summaryRows = (scorers, subjects) => [TRACE_SCORE, ...scorerRows(scorers), ...POINT_ROWS].flatMap(({ label, of: of6 }) => subjects.some((subject) => of6(subject) !== undefined) ? [[label, ...subjects.map((subject) => meanOf(of6(subject)))]] : []);
60953
- var usageText = (usage3) => usage3 === undefined ? "–" : tokensOf(usage3).join(" · ");
61946
+ var usageText = (usage3) => usage3 === undefined ? "–" : tokensOf3(usage3).join(" · ");
60954
61947
  var costLabel = { production: " (paid)", candidate: "" };
60955
61948
  var costRow = (subjects) => [
60956
61949
  "reply cost",
@@ -60996,9 +61989,9 @@ var started2 = {
60996
61989
  text: (run7) => `Started run ${run7.id} of ${encodeAddress2(run7.taskset)} for ${run7.subjects.map((subject) => subjectName(subject)).join(", ")}, under ${scoringOf(run7)}.
60997
61990
  Follow it with \`ambral runs show ${run7.id}\`.`
60998
61991
  };
60999
- var listed8 = {
61992
+ var listed9 = {
61000
61993
  schema: exports_Run.Page,
61001
- text: ({ runs, next: next4 }) => runs.length === 0 ? "No runs yet. Start one with `ambral runs start <workload>/<taskset> --subjects production,<model>`." : [
61994
+ text: ({ runs, next: next5 }) => runs.length === 0 ? "No runs yet. Start one with `ambral runs start <workload>/<taskset> --subjects production,<model>`." : [
61002
61995
  table2([
61003
61996
  ["RUN", "TASKSET", "SUBJECTS", "SCORING", "STATUS", "STARTED (UTC)"],
61004
61997
  ...runs.map((run7) => [
@@ -61010,7 +62003,7 @@ var listed8 = {
61010
62003
  minuteOf(run7.createdAt)
61011
62004
  ])
61012
62005
  ]),
61013
- ...next4 === undefined ? [] : ["", `Older runs: \`ambral runs list --cursor ${next4}\`, with the same filters.`]
62006
+ ...next5 === undefined ? [] : ["", `Older runs: \`ambral runs list --cursor ${next5}\`, with the same filters.`]
61014
62007
  ].join(`
61015
62008
  `)
61016
62009
  };
@@ -61047,9 +62040,11 @@ var start5 = exports_Command.make("start", {
61047
62040
  return yield* new WaitTimedOut({ run: run7.id });
61048
62041
  if (last2.run.status === "failed")
61049
62042
  return yield* new RunFailed({ readout: last2 });
62043
+ if (last2.run.status === "cancelled")
62044
+ return yield* new RunCancelled({ run: run7.id });
61050
62045
  yield* print(shown, last2);
61051
62046
  }).pipe(exports_Effect.ensuring(warned));
61052
- })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("Start a score run of a taskset: each of its traces is replayed for each subject, and each reply scored. It " + "scores under the taskset's current scoring config, or --scoring's. Production's replies are the ones the " + "taskset's traces recorded, so scorers that compare a reply with those record nothing for it. A run takes " + "minutes, longer with more subjects, traces and points, and judge calls at each: three subjects over ten short " + "traces can take more than ten minutes. Without --wait it prints the run's id at once; read it with " + "`ambral runs show <run> --json` until its `run.status` is no longer `running` (it ends `completed` or " + "`failed`), and find it again with `ambral runs list --taskset <workload>/<taskset>`"), exports_Command.withExamples([
62047
+ })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("Start a score run of a taskset: each of its traces is replayed for each subject, and each reply scored. It " + "scores under the taskset's current scoring config, or --scoring's. Production's replies are the ones the " + "taskset's traces recorded, so scorers that compare a reply with those record nothing for it. A run takes " + "minutes, longer with more subjects, traces and points, and judge calls at each: three subjects over ten short " + "traces can take more than ten minutes. Without --wait it prints the run's id at once; read it with " + "`ambral runs show <run> --json` until its `run.status` is no longer `running` (it ends `completed`, " + "`failed` or `cancelled`), and find it again with `ambral runs list --taskset <workload>/<taskset>`"), exports_Command.withExamples([
61053
62048
  {
61054
62049
  command: "ambral runs start support-agent/refunds --subjects production,openai/gpt-6-luna --wait",
61055
62050
  description: "Score one pool model on the taskset beside production's own replies, and print the summary once " + "it ends"
@@ -61079,7 +62074,7 @@ var list15 = exports_Command.make("list", {
61079
62074
  taskset: exports_Option.getOrUndefined(taskset),
61080
62075
  cursor: exports_Option.getOrUndefined(cursor)
61081
62076
  });
61082
- yield* print(listed8, yield* platform2.runs.list({ params: { org }, query: query4 }));
62077
+ yield* print(listed9, yield* platform2.runs.list({ params: { org }, query: query4 }));
61083
62078
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("List the org's score runs, newest first, a page at a time, or a workload's or a taskset's"), exports_Command.withExamples([{
61084
62079
  command: "ambral runs list --taskset support-agent/refunds",
61085
62080
  description: "The runs of support-agent's refunds taskset"
@@ -61102,7 +62097,7 @@ var reasonCell = (reason) => {
61102
62097
  var refOf = ({ branch, trace: trace3 }) => branchName({ trace: trace3, leaf: branch });
61103
62098
  var verdictsListed = (run7) => ({
61104
62099
  schema: exports_Run.VerdictPage,
61105
- text: ({ next: next4, verdicts: verdicts2 }) => {
62100
+ text: ({ next: next5, verdicts: verdicts2 }) => {
61106
62101
  if (verdicts2.length === 0) {
61107
62102
  return `No verdicts match. See every check's with \`ambral runs verdicts ${run7}\`, without filters.`;
61108
62103
  }
@@ -61122,7 +62117,7 @@ var verdictsListed = (run7) => ({
61122
62117
  "",
61123
62118
  `Their traces: ${exports_Array.dedupe(verdicts2.map(refOf)).join(",")}`,
61124
62119
  `Read one reply by reply, each judge's whole call included, with \`ambral runs trace ${run7} <tr_…>\`.`,
61125
- ...next4 === undefined ? [] : [`More: \`ambral runs verdicts ${run7} --cursor ${next4}\`, with the same filters.`]
62120
+ ...next5 === undefined ? [] : [`More: \`ambral runs verdicts ${run7} --cursor ${next5}\`, with the same filters.`]
61126
62121
  ].join(`
61127
62122
  `);
61128
62123
  }
@@ -61229,7 +62224,19 @@ var exportCommand = exports_Command.make("export", { run: runArgument }, ({ run:
61229
62224
  const episodes2 = yield* platform2.export.run({ params: { org, run: run7 } });
61230
62225
  yield* episodes2.pipe(exports_Stream.decodeText(), exports_Stream.splitLines, exports_Stream.runForEach((line) => exports_Console.log(line)));
61231
62226
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("Print a run's results in verifiers' episode format, one JSON object a line, which verifiers and prime-rl " + "load from `traces.jsonl`"), exports_Command.withExamples([{ command: "ambral runs export <run> > traces.jsonl", description: "Save them to a file" }]));
61232
- var runs = exports_Command.make("runs").pipe(exports_Command.withDescription("Start score runs of a taskset, and read what they found"), exports_Command.withSubcommands([start5, list15, show, verdictsCommand, traceCommand, exportCommand]));
62227
+ var cancelled = {
62228
+ schema: exports_Run.Run,
62229
+ text: (run7) => `Cancelled run ${run7.id} of ${encodeAddress2(run7.taskset)}. Its trials not yet scoring are skipped; any ` + `already scoring finish, and \`ambral runs show ${run7.id}\` reads what they scored.`
62230
+ };
62231
+ var cancel2 = exports_Command.make("cancel", { run: runArgument }, ({ run: run7 }) => exports_Effect.gen(function* () {
62232
+ const { platform: platform2 } = yield* Ambral;
62233
+ const { org } = yield* acting;
62234
+ yield* print(cancelled, yield* platform2.runs.cancel({ params: { org, run: run7 } }));
62235
+ })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("Cancel a run that is still running: it ends `cancelled`, and its trials not yet scoring are skipped, so they " + "call no model. A trial already scoring finishes, and its result is kept. Cancelling a cancelled run again " + "changes nothing; a run that completed or failed can't be cancelled"), exports_Command.withExamples([{
62236
+ command: "ambral runs cancel <run>",
62237
+ description: "Stop a run started by mistake, or one no longer needed"
62238
+ }]));
62239
+ var runs = exports_Command.make("runs").pipe(exports_Command.withDescription("Start score runs of a taskset, read what they found, and cancel those still running"), exports_Command.withSubcommands([start5, list15, show, verdictsCommand, traceCommand, exportCommand, cancel2]));
61233
62240
 
61234
62241
  // skill/references/evals.md
61235
62242
  var evals_default = `# Building and running an eval
@@ -61331,8 +62338,8 @@ asked for it.
61331
62338
 
61332
62339
  If your commands time out sooner than a run takes (an agent's shell often stops a command after a few minutes),
61333
62340
  start it without \`--wait\`: it prints the run's id at once. Then read it every minute or so with
61334
- \`ambral runs show <run> --json\` until its \`run.status\` is no longer \`running\`: it ends \`completed\` or \`failed\`,
61335
- and \`progress.completed\` of \`progress.trials\` says how far it has got. \`ambral runs list --taskset
62341
+ \`ambral runs show <run> --json\` until its \`run.status\` is no longer \`running\`: it ends \`completed\`, \`failed\` or
62342
+ \`cancelled\`, and \`progress.completed\` of \`progress.trials\` says how far it has got. \`ambral runs list --taskset
61336
62343
  <workload>/<taskset>\` finds a run's id again, newest first.
61337
62344
 
61338
62345
  While a run is in flight, wait for it: starting the same run again then only pays for the same replies twice. Once
@@ -61340,6 +62347,11 @@ asked for it.
61340
62347
  little differently each run. A run that ends \`failed\` exits 1 under \`--wait\`, and \`runs show\` lists each failed
61341
62348
  trial's error.
61342
62349
 
62350
+ To stop a run in flight (one started with the wrong subjects, taskset or config, or no longer needed), ask the
62351
+ user, then \`ambral runs cancel <run>\`. Its trials not yet scoring are skipped and call no model; one already
62352
+ scoring finishes, and \`runs show\` reads what scored before it stopped. A run that completed or failed can't be
62353
+ cancelled. A \`--wait\` on a cancelled run exits 1.
62354
+
61343
62355
  3. **Trying a scoring change.** \`--scoring <file>\` scores this run alone under that file, without saving it to the
61344
62356
  taskset, so you can compare a draft with the saved version before saving it as the next one. The file is
61345
62357
  checked as \`tasksets scoring set --check\` checks it, before the run starts.
@@ -62063,7 +63075,7 @@ var isStale = (text3, current2) => exports_Option.match(exports_Option.all([expo
62063
63075
  onNone: () => false,
62064
63076
  onSome: ([installed, running]) => exports_Order.isLessThan(exports_Semver.precedence)(installed, running)
62065
63077
  });
62066
- var failures2 = {
63078
+ var failures = {
62067
63079
  check: "Couldn't check for the folder",
62068
63080
  directory: "Couldn't make the folder",
62069
63081
  remove: "Couldn't remove the old folder",
@@ -62071,12 +63083,12 @@ var failures2 = {
62071
63083
  };
62072
63084
 
62073
63085
  class InstallError extends exports_Schema.TaggedError()("SkillInstallError", {
62074
- reason: exports_Schema.Literals(exports_Record.keys(failures2)),
63086
+ reason: exports_Schema.Literals(exports_Record.keys(failures)),
62075
63087
  file: exports_Schema.String,
62076
63088
  cause: exports_Schema.Defect()
62077
63089
  }) {
62078
63090
  get message() {
62079
- return `${failures2[this.reason]} ${this.file}: ${String(this.cause)}`;
63091
+ return `${failures[this.reason]} ${this.file}: ${String(this.cause)}`;
62080
63092
  }
62081
63093
  }
62082
63094
  var failing = (reason, file3) => exports_Effect.mapError((cause) => new InstallError({ reason, file: file3, cause }));
@@ -62100,12 +63112,12 @@ var installed = {
62100
63112
  var install = exports_Command.make("install", {}, () => exports_Effect.gen(function* () {
62101
63113
  const fs = yield* exports_FileSystem.FileSystem;
62102
63114
  const path = yield* exports_Path.Path;
62103
- const project2 = yield* root;
63115
+ const project = yield* root;
62104
63116
  const main = yield* stamp(SKILL_default, package_default.version);
62105
- const claudeSkills = path.join(project2, ...claude.folder);
63117
+ const claudeSkills = path.join(project, ...claude.folder);
62106
63118
  const createdClaudeSkills = !(yield* fs.exists(claudeSkills).pipe(failing("check", claudeSkills)));
62107
63119
  const copies = yield* exports_Effect.forEach(destinations, ({ folder, readers }) => {
62108
- const target = path.join(project2, ...folder, FOLDER2);
63120
+ const target = path.join(project, ...folder, FOLDER2);
62109
63121
  const referenceFolder = path.join(target, REFERENCES);
62110
63122
  return exports_Effect.gen(function* () {
62111
63123
  yield* fs.makeDirectory(target, { recursive: true }).pipe(failing("directory", target));
@@ -62122,13 +63134,13 @@ var install = exports_Command.make("install", {}, () => exports_Effect.gen(funct
62122
63134
  }).pipe(exports_Effect.onError(() => exports_Effect.ignore(fs.remove(staging, { recursive: true, force: true }))));
62123
63135
  yield* write4(path.join(target, MAIN), main).pipe(failing("write", path.join(target, MAIN)));
62124
63136
  return {
62125
- folder: path.relative(project2, target),
63137
+ folder: path.relative(project, target),
62126
63138
  readers,
62127
63139
  files: [MAIN, ...Object.keys(references).map((name) => path.join(REFERENCES, name))]
62128
63140
  };
62129
63141
  });
62130
63142
  });
62131
- yield* print(installed, { version: package_default.version, project: project2, copies, createdClaudeSkills });
63143
+ yield* print(installed, { version: package_default.version, project, copies, createdClaudeSkills });
62132
63144
  })).pipe(exports_Command.withDescription("Install the ambral skill into this project, for Claude Code and other coding agents: how to run Ambral's " + "loop with this CLI. Run it again after updating ambral"));
62133
63145
  var skill = exports_Command.make("skill").pipe(exports_Command.withDescription("Install the skill that teaches a coding agent to use ambral"), exports_Command.withSubcommands([install]));
62134
63146
  var Stale = exports_Schema.Struct({
@@ -62146,8 +63158,8 @@ var hint = exports_Layer.effectDiscard(exports_Effect.gen(function* () {
62146
63158
  const json6 = yield* Json3;
62147
63159
  const cli = package_default.version;
62148
63160
  const staleVersion = exports_Effect.gen(function* () {
62149
- const project2 = yield* root;
62150
- const versions = yield* exports_Effect.forEach(destinations, ({ folder }) => fs.readFileString(path.join(project2, ...folder, FOLDER2, MAIN)).pipe(exports_Effect.map((text3) => isStale(text3, cli) ? versionOf(text3) : exports_Option.none()), exports_Effect.orElseSucceed(() => exports_Option.none())));
63161
+ const project = yield* root;
63162
+ const versions = yield* exports_Effect.forEach(destinations, ({ folder }) => fs.readFileString(path.join(project, ...folder, FOLDER2, MAIN)).pipe(exports_Effect.map((text3) => isStale(text3, cli) ? versionOf(text3) : exports_Option.none()), exports_Effect.orElseSucceed(() => exports_Option.none())));
62151
63163
  return exports_Option.firstSomeOf(versions);
62152
63164
  }).pipe(exports_Effect.orElseSucceed(() => exports_Option.none()));
62153
63165
  yield* exports_Effect.addFinalizer(() => exports_Effect.flatMap(staleVersion, (stale) => exports_Option.match(stale, {
@@ -62199,13 +63211,15 @@ var Failures = exports_Schema.Union([
62199
63211
  exports_Run.TraceNotFound,
62200
63212
  exports_Run.VerdictNotFound,
62201
63213
  exports_Run.VerdictCursorNotFound,
63214
+ exports_Run.NotRunning,
62202
63215
  exports_Inference.KeyRequired,
63216
+ exports_Inference.OutOfCredit,
62203
63217
  RunFailed,
63218
+ RunCancelled,
62204
63219
  WaitTimedOut,
62205
63220
  InstallError
62206
63221
  ]);
62207
63222
  var notEnabled = {
62208
- pending: `This org is pending. ${PENDING_NOTE}`,
62209
63223
  suspended: "This org is suspended. Reach out to founders@ambral.com."
62210
63224
  };
62211
63225
  var rejected = {
@@ -62226,8 +63240,8 @@ var notOffered = {
62226
63240
  remedy: "See the models this org can use with `ambral models list`."
62227
63241
  },
62228
63242
  KeyRequired: {
62229
- message: (model, upstream) => `This org pays for its own model calls and has no key for ${upstream}, the provider of ${model}.`,
62230
- remedy: "Ask an owner or admin of the org to save one on its Providers page in the Ambral web app, then try again."
63243
+ message: (model, upstream) => `This org pays with its own provider keys and has no key for ${upstream}, the provider of ${model}.`,
63244
+ remedy: "Ask an owner or admin of the org to save one on its Billing page in the Ambral web app, then try again."
62231
63245
  }
62232
63246
  };
62233
63247
  var branchOf2 = exports_Schema.encodeSync(exports_TraceReading.Ref);
@@ -62378,13 +63392,25 @@ var advise = (failure) => exports_Match.valueTags(failure, {
62378
63392
  remedy: "Pass the `next` a page printed, with the same filters, or list from the first without --cursor."
62379
63393
  }),
62380
63394
  InferenceKeyRequired: ({ upstream }) => ({
62381
- message: `This org pays for its own model calls and has no key for ${upstream}, the provider of a model this run calls.`,
62382
- remedy: "Ask an owner or admin of the org to save one on its Providers page in the Ambral web app, then start the run again."
63395
+ message: `This org pays with its own provider keys and has no key for ${upstream}, the provider of a model this run calls.`,
63396
+ remedy: "Ask an owner or admin of the org to save one on its Billing page in the Ambral web app, then start the run again."
63397
+ }),
63398
+ InferenceOutOfCredit: () => ({
63399
+ message: "This org is out of Ambral credit, so it can't start a run.",
63400
+ remedy: "Ask an owner or admin of the org about adding credit; its balance is on its Billing page in the Ambral " + "web app. Then start the run again."
62383
63401
  }),
62384
63402
  RunFailed: ({ readout: readout2 }) => ({
62385
63403
  message: readoutText(readout2),
62386
63404
  remedy: `The run failed: each failed trial is listed above. Read it again with \`ambral runs show ${readout2.run.id}\`.`
62387
63405
  }),
63406
+ RunNotRunning: ({ run: run7, status: status3 }) => ({
63407
+ message: `Run ${run7} already ended ${status3}, so there is nothing to cancel.`,
63408
+ remedy: `Read what it found with \`ambral runs show ${run7}\`.`
63409
+ }),
63410
+ RunCancelled: ({ run: run7 }) => ({
63411
+ message: `Run ${run7} was cancelled while this waited for it.`,
63412
+ remedy: `Read what it scored before then with \`ambral runs show ${run7}\`.`
63413
+ }),
62388
63414
  RunWaitTimedOut: ({ run: run7 }) => ({
62389
63415
  message: `Stopped waiting for run ${run7}, which is still running.`,
62390
63416
  remedy: `Follow it with \`ambral runs show ${run7}\`, or wait longer next time with \`--timeout\`.`
@@ -62406,7 +63432,7 @@ var created2 = {
62406
63432
  ].join(`
62407
63433
  `)
62408
63434
  };
62409
- var listed9 = {
63435
+ var listed10 = {
62410
63436
  schema: exports_Schema.Array(exports_Taskset.Taskset),
62411
63437
  text: (tasksets) => tasksets.length === 0 ? "No tasksets yet. Create one with `ambral tasksets create <workload>/<name> --traces <tr_…>,<tr_…>`." : table2([
62412
63438
  ["TASKSET", "TRACES", "SCORING", "CREATED (UTC)"],
@@ -62418,7 +63444,7 @@ var listed9 = {
62418
63444
  ])
62419
63445
  ])
62420
63446
  };
62421
- var one = {
63447
+ var one2 = {
62422
63448
  schema: exports_Taskset.Taskset,
62423
63449
  text: (taskset) => [
62424
63450
  `Taskset ${addressOf(taskset)} · ${traces2(taskset.tasks.length)} · ${scoringOf2(taskset)} · ` + `created ${minuteOf(taskset.createdAt)} UTC`,
@@ -62452,20 +63478,20 @@ var list16 = exports_Command.make("list", {
62452
63478
  onNone: () => platform2.tasksets.listAll({ params: { org } }),
62453
63479
  onSome: (name) => platform2.tasksets.list({ params: { org, workload: name } })
62454
63480
  });
62455
- yield* print(listed9, found);
63481
+ yield* print(listed10, found);
62456
63482
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("List the org's tasksets, or one workload's, newest first, with each one's scoring version"), exports_Command.withExamples([{ command: "ambral tasksets list support-agent", description: "support-agent's tasksets" }]));
62457
- var get29 = exports_Command.make("get", { taskset: addressArgument }, ({ taskset }) => exports_Effect.gen(function* () {
63483
+ var get30 = exports_Command.make("get", { taskset: addressArgument }, ({ taskset }) => exports_Effect.gen(function* () {
62458
63484
  const { platform: platform2 } = yield* Ambral;
62459
63485
  const { org } = yield* acting;
62460
- yield* print(one, yield* platform2.tasksets.get({ params: { org, workload: taskset.workload, taskset: taskset.taskset } }));
63486
+ yield* print(one2, yield* platform2.tasksets.get({ params: { org, workload: taskset.workload, taskset: taskset.taskset } }));
62461
63487
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("Show a taskset: each of its traces' branches, and its scoring version"), exports_Command.withExamples([{ command: "ambral tasksets get support-agent/refunds --json", description: "As JSON" }]));
62462
- var tasksets = exports_Command.make("tasksets").pipe(exports_Command.withDescription("Create and read a workload's tasksets, and set how they're scored"), exports_Command.withSubcommands([create5, list16, get29, scoring3]));
63488
+ var tasksets = exports_Command.make("tasksets").pipe(exports_Command.withDescription("Create and read a workload's tasksets, and set how they're scored"), exports_Command.withSubcommands([create5, list16, get30, scoring3]));
62463
63489
 
62464
63490
  // src/Workloads/Workloads.ts
62465
63491
  var nameArgument = exports_Argument.String("name").pipe(exports_Argument.withDescription("The workload's name, as its requests send it in `x-workload`"), exports_Argument.withSchema(exports_Ids.WorkloadName));
62466
63492
  var modelArgument = exports_Argument.String("model").pipe(exports_Argument.withDescription("A catalog model's id, as `ambral models list` shows it"), exports_Argument.withSchema(exports_Ids.ModelId));
62467
63493
  var poolOf2 = (pool) => [pool.primary, ...pool.models.filter((member2) => member2 !== pool.primary)].join(", ");
62468
- var one2 = {
63494
+ var one3 = {
62469
63495
  schema: exports_WorkloadConnection.Details,
62470
63496
  text: ({ workload, connection }) => [
62471
63497
  table2([
@@ -62491,7 +63517,7 @@ var created3 = {
62491
63517
  text: (workload) => `Created ${workload.name}, serving ${workload.pool.primary}.
62492
63518
  ` + `Add a model to its pool with \`ambral workloads pool add ${workload.name} <model>\`.`
62493
63519
  };
62494
- var listed10 = {
63520
+ var listed11 = {
62495
63521
  schema: exports_Schema.Array(exports_Workload.Workload),
62496
63522
  text: (workloads) => workloads.length === 0 ? "This org has no workloads. Create one with `ambral workloads create <name> --model <model>`." : table2([
62497
63523
  ["WORKLOAD", "PRIMARY", "POOL"],
@@ -62525,14 +63551,14 @@ var create6 = exports_Command.make("create", {
62525
63551
  var list17 = exports_Command.make("list", {}, () => exports_Effect.gen(function* () {
62526
63552
  const { platform: platform2 } = yield* Ambral;
62527
63553
  const { org } = yield* acting;
62528
- yield* print(listed10, yield* platform2.workloads.list({ params: { org } }));
63554
+ yield* print(listed11, yield* platform2.workloads.list({ params: { org } }));
62529
63555
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("List the org's workloads, by name, with each one's primary model and pool"));
62530
- var get30 = exports_Command.make("get", { name: nameArgument }, ({ name }) => exports_Effect.gen(function* () {
63556
+ var get31 = exports_Command.make("get", { name: nameArgument }, ({ name }) => exports_Effect.gen(function* () {
62531
63557
  const { platform: platform2 } = yield* Ambral;
62532
63558
  const { org } = yield* acting;
62533
- yield* print(one2, yield* platform2.workloads.get({ params: { org, workload: name } }));
63559
+ yield* print(one3, yield* platform2.workloads.get({ params: { org, workload: name } }));
62534
63560
  })).pipe(exports_Command.provide(inProject), exports_Command.withDescription("Show a workload: its primary model, its pool, and how an agent connects to it through the Gateway"), exports_Command.withExamples([{ command: "ambral workloads get support-agent --json", description: "As JSON" }]));
62535
- var add7 = exports_Command.make("add", { name: nameArgument, model: modelArgument }, ({ name, model }) => exports_Effect.gen(function* () {
63561
+ var add8 = exports_Command.make("add", { name: nameArgument, model: modelArgument }, ({ name, model }) => exports_Effect.gen(function* () {
62536
63562
  const { platform: platform2 } = yield* Ambral;
62537
63563
  const { org } = yield* acting;
62538
63564
  yield* print(changed(name), yield* platform2.workloads.addToPool({ params: { org, workload: name, model } }));
@@ -62559,8 +63585,8 @@ var setPrimary = exports_Command.make("set-primary", { name: nameArgument, model
62559
63585
  description: "Roll back to the model it served before"
62560
63586
  }
62561
63587
  ]));
62562
- var pool = exports_Command.make("pool").pipe(exports_Command.withDescription("Add models to a workload's pool, or remove them"), exports_Command.withSubcommands([add7, remove11]));
62563
- var workloads = exports_Command.make("workloads").pipe(exports_Command.withDescription("Create, list and show the org's workloads, change their model pools, and choose the model that serves each"), exports_Command.withSubcommands([create6, list17, get30, setPrimary, pool]));
63588
+ var pool = exports_Command.make("pool").pipe(exports_Command.withDescription("Add models to a workload's pool, or remove them"), exports_Command.withSubcommands([add8, remove11]));
63589
+ var workloads = exports_Command.make("workloads").pipe(exports_Command.withDescription("Create, list and show the org's workloads, change their model pools, and choose the model that serves each"), exports_Command.withSubcommands([create6, list17, get31, setPrimary, pool]));
62564
63590
 
62565
63591
  // src/Cli.ts
62566
63592
  var ambral = exports_Command.make("ambral").pipe(exports_Command.withDescription("Use Ambral from a terminal"), exports_Command.withSubcommands([
@@ -62575,7 +63601,7 @@ var ambral = exports_Command.make("ambral").pipe(exports_Command.withDescription
62575
63601
  runs,
62576
63602
  keys5,
62577
63603
  skill
62578
- ]), exports_Command.provide(reporting(Failures, advise).pipe(exports_Layer.provide(layer18), exports_Layer.provideMerge(hint))), exports_Command.withGlobalFlags([Json3, Org2]));
63604
+ ]), exports_Command.provide(reporting(Failures, advise).pipe(exports_Layer.provide(layer18), exports_Layer.provideMerge(hint))), exports_Command.withGlobalFlags([Json3, Org3]));
62579
63605
  var main = exports_Command.run(ambral, { version: package_default.version }).pipe(exports_Effect.catchTag("ShowHelp", (help) => help.errors.length === 0 ? exports_Effect.void : exports_Effect.fail(help)));
62580
63606
 
62581
63607
  // src/bin.ts