pi-lilac-provider 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -398,8 +398,10 @@ function transformApiModel(apiModel: any): JsonModel | null {
398
398
  const hasImage = modalities.includes("image");
399
399
  const pricing = apiModel.pricing || {};
400
400
 
401
- // Lilac API returns per-token pricing (e.g. "0.0000007" = $0.70/M tokens)
402
- const toPerM = (v: any) => Math.round((typeof v === "string" ? parseFloat(v) : (v || 0)) * 1_000_000 * 100) / 100;
401
+ // Lilac API returns per-token pricing (e.g. "0.0000007" = $0.70/M tokens).
402
+ // Convert to $/M then round to 6 decimals: normalizes float noise from the ×1e6
403
+ // multiply and preserves sub-cent cache prices like 0.003 ($/M).
404
+ const toPerM = (v: any) => Math.round((typeof v === "string" ? parseFloat(v) : (v || 0)) * 1_000_000 * 1e6) / 1e6;
403
405
 
404
406
  const inputTypes: string[] = ["text"];
405
407
  if (hasImage) inputTypes.push("image");
@@ -491,9 +493,20 @@ function mergeWithEmbedded(liveModels: JsonModel[], embeddedModels: JsonModel[])
491
493
  const embedded = embeddedMap.get(liveModel.id);
492
494
  seen.add(liveModel.id);
493
495
  if (embedded) {
496
+ // Self-heal: live API pricing is authoritative field-by-field. Prefer the
497
+ // live cost when the API reports it (non-zero); fall back to embedded when
498
+ // the API is silent (0) so curated cacheRead/cacheWrite isn't clobbered and
499
+ // providers whose /models endpoint exposes no pricing keep their curated
500
+ // cost. Curation (reasoning/input/compat/name) still wins via ...embedded.
494
501
  result.push({
495
502
  ...liveModel,
496
503
  ...embedded,
504
+ cost: {
505
+ input: liveModel.cost.input || embedded.cost.input,
506
+ output: liveModel.cost.output || embedded.cost.output,
507
+ cacheRead: liveModel.cost.cacheRead || embedded.cost.cacheRead,
508
+ cacheWrite: liveModel.cost.cacheWrite || embedded.cost.cacheWrite,
509
+ },
497
510
  contextWindow: liveModel.contextWindow || embedded.contextWindow,
498
511
  });
499
512
  } else {
@@ -561,7 +574,9 @@ function applyDiscounts(models: JsonModel[], discounts: Map<string, JsonDiscount
561
574
  // E.g. "0.75" means pay 75% of list price. For MiniMax with "1.00" there's no discount.
562
575
  // discountPercent is informational (it equals (1 - creditMultiplier) * 100).
563
576
  const factor = discount.creditMultiplier;
564
- const applyFactor = (n: number) => n > 0 ? Math.round(n * factor * 10000) / 10000 : n;
577
+ // Round to 6 decimals of $/M so a discounted sub-cent cache price
578
+ // (e.g. 0.003 × 0.75 = 0.00225) survives; 4-decimal rounding trimmed it to 0.0023.
579
+ const applyFactor = (n: number) => n > 0 ? Math.round(n * factor * 1e6) / 1e6 : n;
565
580
  return {
566
581
  ...model,
567
582
  cost: {
@@ -604,7 +619,8 @@ function applyDiscountInPlace(
604
619
  // discount was removed since it was last priced.
605
620
  const rawFactor = discounts?.get(model.id)?.creditMultiplier;
606
621
  const factor = Number.isFinite(rawFactor) && rawFactor !== undefined ? rawFactor : 1;
607
- const applyFactor = (n: number) => n > 0 ? Math.round(n * factor * 10000) / 10000 : n;
622
+ // Round to 6 decimals of $/M so a discounted sub-cent cache price survives.
623
+ const applyFactor = (n: number) => n > 0 ? Math.round(n * factor * 1e6) / 1e6 : n;
608
624
  model.cost.input = applyFactor(list.cost.input);
609
625
  model.cost.output = applyFactor(list.cost.output);
610
626
  model.cost.cacheRead = applyFactor(list.cost.cacheRead);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-lilac-provider",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "Lilac provider extension for pi - Access Kimi K2.6, GLM 5.1, and Gemma 4 models through Lilac's OpenAI-compatible API on idle GPUs",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -55,7 +55,9 @@ function saveJson(filePath, data) {
55
55
  // Convert per-token pricing from API to per-million-tokens
56
56
  function toPerMillion(val) {
57
57
  if (val === '' || val === null || val === undefined) return null;
58
- return Math.round(parseFloat(val) * 1_000_000 * 100) / 100;
58
+ // Round to 6 decimals of $/M: normalizes float noise from the ×1e6 multiply
59
+ // and preserves sub-cent cache prices like 0.003 ($/M).
60
+ return Math.round(parseFloat(val) * 1_000_000 * 1e6) / 1e6;
59
61
  }
60
62
 
61
63
  // ─── API fetch ───────────────────────────────────────────────────────────────