fix: display effective pricing rounding policy

This commit is contained in:
Abhishek Kumar 2026-07-13 14:19:12 +05:30
parent 4cf41b101e
commit 16417ceace
3 changed files with 64 additions and 7 deletions

View file

@ -22,6 +22,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { VoiceSelectorModal } from "@/components/VoiceSelectorModal";
import { LANGUAGE_DISPLAY_NAMES } from "@/constants/languages";
import { formatRoundingPolicy } from "@/lib/billingDisplay";
type ModelMode = "realtime" | "dograh" | "byok";
@ -296,6 +297,25 @@ function formatPricePerMinute(price: ModelConfigurationMetricPrice): string {
}).format(price.price_per_minute);
}
function MetricPrice({
label,
price,
}: {
label: string;
price: ModelConfigurationMetricPrice;
}) {
return (
<div className="space-y-0.5">
<p className="text-muted-foreground">
{label}: <span className="font-medium text-foreground">{formatPricePerMinute(price)}/{price.unit}</span>
</p>
<p className="text-xs text-muted-foreground">
{formatRoundingPolicy(price.rounding_policy)}
</p>
</div>
);
}
function PricingSummary({
pricing,
includeDograhModel,
@ -314,21 +334,16 @@ function PricingSummary({
<CardContent className="space-y-2 pt-5 text-sm">
<p className="font-medium">Usage pricing</p>
{platformPrice && (
<p className="text-muted-foreground">
Platform usage: <span className="font-medium text-foreground">{formatPricePerMinute(platformPrice)}/{platformPrice.unit}</span>
</p>
<MetricPrice label="Platform usage" price={platformPrice} />
)}
{dograhModelPrice && (
<p className="text-muted-foreground">
Dograh model usage: <span className="font-medium text-foreground">{formatPricePerMinute(dograhModelPrice)}/{dograhModelPrice.unit}</span>
</p>
<MetricPrice label="Dograh model usage" price={dograhModelPrice} />
)}
{thirdPartyModels && (
<p className="text-muted-foreground">
Your selected model provider may charge separately for its usage.
</p>
)}
<p className="text-xs text-muted-foreground">Usage is rounded up to whole minutes per call.</p>
</CardContent>
</Card>
);

View file

@ -0,0 +1,18 @@
import { describe, expect, it } from "vitest";
import { formatRoundingPolicy } from "@/lib/billingDisplay";
describe("formatRoundingPolicy", () => {
it.each([
["ceil_minute", "Rounded up to whole minutes per call."],
["ceil_1_minute", "Rounded up to whole minutes per call."],
["ceil_15_seconds", "Rounded up in 15-second increments per call."],
["ceil_30_second", "Rounded up in 30-second increments per call."],
["ceil_2_minutes", "Rounded up in 2-minute increments per call."],
["none", "Billed using exact measured usage."],
["custom_contract", "Billing policy: custom contract."],
["", "Billing policy details are unavailable."],
])("formats %s", (policy, expected) => {
expect(formatRoundingPolicy(policy)).toBe(expected);
});
});

View file

@ -0,0 +1,24 @@
export function formatRoundingPolicy(roundingPolicy: string): string {
const normalizedPolicy = roundingPolicy.trim().toLowerCase();
if (!normalizedPolicy) {
return "Billing policy details are unavailable.";
}
if (normalizedPolicy === "ceil_minute" || normalizedPolicy === "ceil_1_minute") {
return "Rounded up to whole minutes per call.";
}
if (normalizedPolicy === "none") {
return "Billed using exact measured usage.";
}
const secondsMatch = normalizedPolicy.match(/^ceil_(\d+)_seconds?$/);
if (secondsMatch) {
return `Rounded up in ${Number(secondsMatch[1])}-second increments per call.`;
}
const minutesMatch = normalizedPolicy.match(/^ceil_(\d+)_minutes?$/);
if (minutesMatch) {
return `Rounded up in ${Number(minutesMatch[1])}-minute increments per call.`;
}
return `Billing policy: ${roundingPolicy.replaceAll("_", " ")}.`;
}