Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions core/llm/utils/starterCredits.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { describe, expect, it } from "vitest";
import { CreditStatus } from "../../control-plane/client";
import { isOutOfStarterCredits } from "./starterCredits";

describe("isOutOfStarterCredits", () => {
it("should return true for free trial users who have run out of credits", () => {
const creditStatus: CreditStatus = {
optedInToFreeTrial: true,
hasCredits: false,
creditBalance: 0,
hasPurchasedCredits: false,
};

expect(isOutOfStarterCredits(true, creditStatus)).toBe(true);
});

it("should return false for paid users who have run out of credits", () => {
const creditStatus: CreditStatus = {
optedInToFreeTrial: true,
hasCredits: false,
creditBalance: 0,
hasPurchasedCredits: true,
};

expect(isOutOfStarterCredits(true, creditStatus)).toBe(false);
});

it("should return false for free trial users who still have credits", () => {
const creditStatus: CreditStatus = {
optedInToFreeTrial: true,
hasCredits: true,
creditBalance: 1000,
hasPurchasedCredits: false,
};

expect(isOutOfStarterCredits(true, creditStatus)).toBe(false);
});

it("should return false for paid users who still have credits", () => {
const creditStatus: CreditStatus = {
optedInToFreeTrial: true,
hasCredits: true,
creditBalance: 5000,
hasPurchasedCredits: true,
};

expect(isOutOfStarterCredits(true, creditStatus)).toBe(false);
});

it("should return false when not using credits-based API key", () => {
const creditStatus: CreditStatus = {
optedInToFreeTrial: true,
hasCredits: false,
creditBalance: 0,
hasPurchasedCredits: false,
};

expect(isOutOfStarterCredits(false, creditStatus)).toBe(false);
});

it("should return false for users who did not opt into free trial", () => {
const creditStatus: CreditStatus = {
optedInToFreeTrial: false,
hasCredits: false,
creditBalance: 0,
hasPurchasedCredits: false,
};

expect(isOutOfStarterCredits(true, creditStatus)).toBe(false);
});

it("should return false for paid users who never opted into free trial", () => {
const creditStatus: CreditStatus = {
optedInToFreeTrial: false,
hasCredits: false,
creditBalance: 0,
hasPurchasedCredits: true,
};

expect(isOutOfStarterCredits(true, creditStatus)).toBe(false);
});
});
13 changes: 13 additions & 0 deletions core/llm/utils/starterCredits.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import { CreditStatus } from "../../control-plane/client";

/**
* Determines if a user has exhausted their free trial starter credits.
* This should ONLY return true for users who:
* 1. Are using credits-based API keys (free trial or models add-on)
* 2. Have no credits remaining
* 3. Have NOT purchased credits (i.e., are still on free trial)
* 4. Have opted into the free trial
*
* Paid users who have exhausted their purchased credits should NOT trigger this.
*/
export function isOutOfStarterCredits(
usingModelsAddOnApiKey: boolean,
creditStatus: CreditStatus,
): boolean {
// Only show onboarding for free trial users who have run out of credits
// Do NOT show for paid users who have purchased credits, even if they've run out
return (
usingModelsAddOnApiKey &&
creditStatus.optedInToFreeTrial &&
!creditStatus.hasCredits &&
!creditStatus.hasPurchasedCredits
);
Expand Down
Loading