fix: update Grok media default rate card

This commit is contained in:
Heatherm Huang
2026-07-08 13:50:49 +08:00
parent 4d702e3234
commit 376e03ded1
6 changed files with 276 additions and 18 deletions
+33 -16
View File
@@ -843,7 +843,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.134"
:placeholder="getImagePricePlaceholder(createForm.platform, 'image_price_1k')"
/>
</div>
<div>
@@ -854,7 +854,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.201"
:placeholder="getImagePricePlaceholder(createForm.platform, 'image_price_2k')"
/>
</div>
<div>
@@ -865,7 +865,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.268"
:placeholder="getImagePricePlaceholder(createForm.platform, 'image_price_4k')"
/>
</div>
</div>
@@ -987,7 +987,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.201"
:placeholder="getVideoPricePlaceholder(createForm.platform, 'video_price_480p')"
/>
</div>
<div>
@@ -998,7 +998,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.201"
:placeholder="getVideoPricePlaceholder(createForm.platform, 'video_price_720p')"
/>
</div>
<div>
@@ -1009,7 +1009,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.201"
:placeholder="getVideoPricePlaceholder(createForm.platform, 'video_price_1080p')"
/>
</div>
</div>
@@ -2322,7 +2322,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.134"
:placeholder="getImagePricePlaceholder(editForm.platform, 'image_price_1k')"
/>
</div>
<div>
@@ -2333,7 +2333,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.201"
:placeholder="getImagePricePlaceholder(editForm.platform, 'image_price_2k')"
/>
</div>
<div>
@@ -2344,7 +2344,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.268"
:placeholder="getImagePricePlaceholder(editForm.platform, 'image_price_4k')"
/>
</div>
</div>
@@ -2466,7 +2466,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.201"
:placeholder="getVideoPricePlaceholder(editForm.platform, 'video_price_480p')"
/>
</div>
<div>
@@ -2477,7 +2477,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.201"
:placeholder="getVideoPricePlaceholder(editForm.platform, 'video_price_720p')"
/>
</div>
<div>
@@ -2488,7 +2488,7 @@
step="0.001"
min="0"
class="input"
placeholder="0.201"
:placeholder="getVideoPricePlaceholder(editForm.platform, 'video_price_1080p')"
/>
</div>
</div>
@@ -3497,6 +3497,10 @@ import {
import { createModelsListCandidatesTracker } from "./groupsModelsListCandidates";
import { normalizeSupportedModelScopesForPlatform } from "./groupsSupportedModelScopes";
import {
getDefaultImagePreviewPrice,
getDefaultVideoPreviewPrice,
getImagePricePlaceholder,
getVideoPricePlaceholder,
imagePricingI18nKey,
supportsImagePricingPlatform,
supportsVideoPricingPlatform,
@@ -4244,6 +4248,7 @@ type ImagePricingFormState = {
};
type VideoPricingFormState = {
platform: GroupPlatform;
rate_multiplier: number;
video_rate_independent: boolean;
video_rate_multiplier: number;
@@ -4272,6 +4277,14 @@ const normalizePreviewNumber = (value: number | string | null | undefined, fallb
return Number.isFinite(parsed) ? parsed : fallback;
};
const parsePreviewPrice = (value: number | string | null | undefined) => {
if (value === null || value === undefined || value === "") {
return null;
}
const parsed = Number(value);
return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
};
const formatImagePricePreview = (value: number | string | null | undefined) => {
if (value === null || value === undefined || value === "") {
return t("admin.groups.imagePricing.notConfigured");
@@ -4300,10 +4313,12 @@ const buildImageFinalPricePreview = (form: ImagePricingFormState) => {
: normalizePreviewNumber(form.rate_multiplier, 1);
const multiplier = imageMultiplier;
return imagePricingTiers.map((tier) => {
const basePrice = normalizePreviewNumber(form[tier.key]);
const basePrice =
parsePreviewPrice(form[tier.key]) ??
getDefaultImagePreviewPrice(form.platform, tier.key);
return {
label: tier.label,
value: basePrice > 0
value: basePrice !== null
? formatImagePricePreview(basePrice * multiplier)
: t("admin.groups.imagePricing.notConfigured"),
};
@@ -4315,10 +4330,12 @@ const buildVideoFinalPricePreview = (form: VideoPricingFormState) => {
? normalizePreviewNumber(form.video_rate_multiplier, 1)
: normalizePreviewNumber(form.rate_multiplier, 1);
return videoPricingTiers.map((tier) => {
const basePrice = normalizePreviewNumber(form[tier.key]);
const basePrice =
parsePreviewPrice(form[tier.key]) ??
getDefaultVideoPreviewPrice(form.platform, tier.key);
return {
label: tier.label,
value: basePrice > 0
value: basePrice !== null
? formatVideoPricePreview(basePrice * multiplier)
: t("admin.groups.videoPricing.notConfigured"),
};
@@ -1,6 +1,10 @@
import { describe, expect, it } from "vitest";
import {
getDefaultImagePreviewPrice,
getDefaultVideoPreviewPrice,
getImagePricePlaceholder,
getVideoPricePlaceholder,
imagePricingPlatforms,
imagePricingI18nKey,
supportsImagePricingPlatform,
@@ -29,4 +33,18 @@ describe("groups image pricing platform support", () => {
);
expect(videoPricingI18nKey("title")).toBe("admin.groups.videoPricing.title");
});
it("uses Grok media defaults instead of generic image fallback placeholders", () => {
expect(getImagePricePlaceholder("grok", "image_price_1k")).toBe("0.02");
expect(getImagePricePlaceholder("grok", "image_price_2k")).toBe("0.02");
expect(getVideoPricePlaceholder("grok", "video_price_480p")).toBe("0.08");
expect(getVideoPricePlaceholder("grok", "video_price_720p")).toBe("0.14");
expect(getVideoPricePlaceholder("grok", "video_price_1080p")).toBe("0.25");
});
it("keeps non-Grok image placeholders on the generic image card", () => {
expect(getImagePricePlaceholder("openai", "image_price_1k")).toBe("0.134");
expect(getDefaultImagePreviewPrice("openai", "image_price_2k")).toBe(0.201);
expect(getDefaultVideoPreviewPrice("openai", "video_price_480p")).toBeNull();
});
});
@@ -16,3 +16,76 @@ export const imagePricingI18nKey = (_platform: string, key: string): string =>
export const videoPricingI18nKey = (key: string): string =>
`admin.groups.videoPricing.${key}`;
type ImagePricingTierKey = "image_price_1k" | "image_price_2k" | "image_price_4k";
type VideoPricingTierKey =
| "video_price_480p"
| "video_price_720p"
| "video_price_1080p";
const defaultImagePricePlaceholders: Record<
string,
Record<ImagePricingTierKey, string>
> = {
default: {
image_price_1k: "0.134",
image_price_2k: "0.201",
image_price_4k: "0.268",
},
grok: {
image_price_1k: "0.02",
image_price_2k: "0.02",
image_price_4k: "0.02",
},
};
const defaultVideoPricePlaceholders: Record<
string,
Record<VideoPricingTierKey, string>
> = {
grok: {
video_price_480p: "0.08",
video_price_720p: "0.14",
video_price_1080p: "0.25",
},
};
export const getImagePricePlaceholder = (
platform: string,
tier: ImagePricingTierKey,
): string => {
const card = defaultImagePricePlaceholders[platform] ?? defaultImagePricePlaceholders.default;
return card[tier];
};
export const getVideoPricePlaceholder = (
platform: string,
tier: VideoPricingTierKey,
): string => {
const card = defaultVideoPricePlaceholders[platform];
return card?.[tier] ?? "";
};
export const getDefaultImagePreviewPrice = (
platform: string,
tier: ImagePricingTierKey,
): number | null => {
const placeholder = getImagePricePlaceholder(platform, tier);
if (placeholder === "") {
return null;
}
const value = Number(placeholder);
return Number.isFinite(value) ? value : null;
};
export const getDefaultVideoPreviewPrice = (
platform: string,
tier: VideoPricingTierKey,
): number | null => {
const placeholder = getVideoPricePlaceholder(platform, tier);
if (placeholder === "") {
return null;
}
const value = Number(placeholder);
return Number.isFinite(value) ? value : null;
};