868
};
869
}
871
>
// New Quota Snapshot
872
>
if (entitlementsData.quota_snapshots) {
873
>
for (const quotaType of ['chat', 'completions', 'premium_interactions'] as const) {
874
>
const rawQuotaSnapshot = entitlementsData.quota_snapshots[quotaType];
875
>
if (!rawQuotaSnapshot) {
876
continue;
877
}
878
>
const parsedEntitlement = rawQuotaSnapshot.entitlement !== undefined ? Number(rawQuotaSnapshot.entitlement) : undefined;
chatEntitlementService.ts
879
>
const parsedCreditsUsed = rawQuotaSnapshot.credits_used !== undefined ? Number(rawQuotaSnapshot.credits_used) : undefined;
880
>
881
>
// Skip snapshots where the user has no allocated entitlement for this
882
>
// category (e.g. free tier premium_interactions with 0 credits). Under
883
>
// TBB, has_quota is always false at the per-snapshot level so we cannot
884
>
// rely on it; instead check the actual entitlement value.
885
>
if (!rawQuotaSnapshot.unlimited && parsedEntitlement === 0) {
886
continue;
887
}
889
>
const parsedQuotaRemaining = rawQuotaSnapshot.quota_remaining !== undefined ? Number(rawQuotaSnapshot.quota_remaining) : undefined;
890
>
const quotaSnapshot: IQuotaSnapshot = {
891
>
percentRemaining: Math.min(100, Math.max(0, rawQuotaSnapshot.percent_remaining)),
892
>
unlimited: rawQuotaSnapshot.unlimited,
893
>
hasQuota: rawQuotaSnapshot.has_quota,
894
>
usageBasedBilling: entitlementsData.token_based_billing,
895
>
resetAt: rawQuotaSnapshot.quota_reset_at || undefined,
896
>
entitlement: parsedEntitlement !== undefined && Number.isFinite(parsedEntitlement) && parsedEntitlement >= 0 ? parsedEntitlement : undefined,
897
>
quotaRemaining: parsedQuotaRemaining !== undefined && Number.isFinite(parsedQuotaRemaining) && parsedQuotaRemaining >= 0 ? parsedQuotaRemaining : undefined,
898
>
creditsUsed: parsedCreditsUsed !== undefined && Number.isFinite(parsedCreditsUsed) && parsedCreditsUsed >= 0 ? parsedCreditsUsed : undefined,
899
>
};
900
>
901
>
switch (quotaType) {
902
>
case 'chat':
903
quotas.chat = quotaSnapshot;
904
break;
906
quotas.completions = quotaSnapshot;
907
break;
909
quotas.premiumChat = quotaSnapshot;
910
break;
912
>
}
913
>
914
>
const overageSource = entitlementsData.quota_snapshots['premium_interactions'];
915
>
quotas.additionalUsageEnabled = overageSource?.overage_permitted ?? false;
916
>
quotas.additionalUsageCount = overageSource?.overage_count ?? 0;
917
>
quotas.additionalUsageEntitlement = overageSource?.overage_entitlement ?? 0;
918
>
}
919
>
return quotas;
920
>
}
921
922
export class ChatEntitlementRequests extends Disposable {