v0.2.3 Core tier 10/5/5 split + dynamic health version

This commit is contained in:
local
2026-05-11 21:53:50 -05:00
parent 07fe14010c
commit 6797aae404
8 changed files with 138 additions and 15 deletions
+26 -3
View File
@@ -8,9 +8,10 @@
// {
// install_id: "uuid",
// tier_snapshot: "core" | "pro" | "max", // last-seen tier
// lifetime_consumed: number, // for Core lifetime cap
// lifetime_consumed: number, // total Core credits ever used
// lifetime_gemini_consumed: number, // Core credits served by Gemini
// month: "YYYY-MM", // calendar-month key
// monthly_consumed: number, // total this month
// monthly_consumed: number, // total this month (paid tiers)
// monthly_gemini_consumed: number, // Gemini-only this month
// last_active_at: ISO-8601 string,
// }
@@ -63,6 +64,7 @@ function blankRow(installId) {
install_id: installId,
tier_snapshot: "core",
lifetime_consumed: 0,
lifetime_gemini_consumed: 0,
month: currentMonthKey(),
monthly_consumed: 0,
monthly_gemini_consumed: 0,
@@ -103,16 +105,31 @@ export async function getOrCreateRow(installId) {
// Returns:
// { remaining: number | null, capped: "lifetime" | "monthly" | "none", gemini_remaining: number | null }
// `null` for remaining means "unlimited" (Max tier total).
// `null` for gemini_remaining means "no Gemini cap on this tier" — the
// router can always pick Gemini.
export function computeRemaining(row, quota) {
const tier = row.tier_snapshot;
const tierQuota = quota[tier] || quota.core;
if (tierQuota.lifetime != null) {
const remaining = Math.max(0, tierQuota.lifetime - (row.lifetime_consumed || 0));
// Core tier may carve out a portion of the lifetime budget for
// Gemini specifically (geminiCapLifetime). When set, remaining
// Gemini credits = cap - lifetime_gemini_consumed; the rest of
// the lifetime budget falls through to operator hardware. When
// null, lifetime tier ignores the Gemini/hardware split and uses
// whichever backend is available.
const geminiRemaining =
tierQuota.geminiCapLifetime == null
? null
: Math.max(
0,
tierQuota.geminiCapLifetime - (row.lifetime_gemini_consumed || 0)
);
return {
remaining,
capped: "lifetime",
gemini_remaining: null, // lifetime tier doesn't split Gemini/hardware
gemini_remaining: geminiRemaining,
};
}
@@ -158,11 +175,17 @@ export function planBackend(row, quota, { hasHardware }) {
}
// Debit one credit on a successful call. Persists immediately.
// Tracks Gemini-vs-hardware separately for Core (lifetime_gemini_consumed)
// and paid tiers (monthly_gemini_consumed) so the planner can enforce
// the per-tier Gemini cap.
export async function commitCredit(installId, { backend, tier }) {
const row = await getOrCreateRow(installId);
row.tier_snapshot = tier;
if (tier === "core") {
row.lifetime_consumed = (row.lifetime_consumed || 0) + 1;
if (backend === "gemini") {
row.lifetime_gemini_consumed = (row.lifetime_gemini_consumed || 0) + 1;
}
} else {
row.monthly_consumed = (row.monthly_consumed || 0) + 1;
if (backend === "gemini") {