Use server prices for text billing estimates
Web Quality / verify (push) Has been cancelled

This commit is contained in:
2026-06-10 14:12:55 +08:00
parent bfb70bab26
commit d28889fd0c
7 changed files with 482 additions and 10 deletions
+30 -1
View File
@@ -40,6 +40,7 @@ import { useGenerationTasks } from "../../hooks/useGenerationTasks";
import { conversationClient, type ConversationSummary } from "../../api/conversationClient";
import { modelCapabilitiesClient } from "../../api/modelCapabilitiesClient";
import { publicPricingClient, type PublicModelPrice } from "../../api/publicPricingClient";
import type { CreatePreviewTaskInput } from "../../api/webGenerationGateway";
import type { WebProjectSummary } from "../../types";
import {
@@ -58,6 +59,8 @@ import {
import { translateTaskError } from "../../utils/translateTaskError";
import {
buildLocalTimeoutMessage,
FALLBACK_TEXT_TOKEN_CREDIT_RATE,
formatTextTokenCreditRule,
getTaskTimeoutPolicy,
isTaskLocallyTimedOut,
} from "../../utils/taskLifecycle";
@@ -70,6 +73,7 @@ import { isViduModel } from "../../utils/viduRouting";
import { isPixverseModel } from "../../utils/pixverseRouting";
import { resolveVideoRequestModel } from "../../utils/resolveVideoModel";
import { calculateEnterpriseVideoCredits, ENTERPRISE_DEFAULT_VIDEO_MODEL } from "../../utils/enterpriseVideoPolicy";
import { resolveTextTokenCreditRate } from "../../utils/modelPricing";
import {
getImageQualityOptionsForContext,
getDefaultImageQuality,
@@ -403,9 +407,27 @@ function WorkbenchPage({
const [videoQuality, setVideoQuality] = useState(() => getDefaultVideoQuality(VIDEO_MODEL_OPTIONS[0].value));
const [chatModel, setChatModel] = useState(CHAT_MODEL_OPTIONS[0].value);
const [modelPrices, setModelPrices] = useState<PublicModelPrice[]>([]);
const [thinkingSpeed, setThinkingSpeed] = useState(THINKING_SPEED_OPTIONS[0].value);
const [thinkingDepth, setThinkingDepth] = useState(THINKING_DEPTH_OPTIONS[0].value);
useEffect(() => {
let cancelled = false;
publicPricingClient
.getPrices()
.then((prices) => {
if (!cancelled) setModelPrices(prices);
})
.catch(() => {
if (!cancelled) setModelPrices([]);
});
return () => {
cancelled = true;
};
}, []);
useEffect(() => {
let cancelled = false;
@@ -524,6 +546,10 @@ function WorkbenchPage({
const videoQualityLabel = getVideoQualityLabel(videoModel, videoQuality);
const imageSettingsSummary = `${imageRatio} / ${imageQuality}`;
const selectedChatTokenRate = useMemo(
() => resolveTextTokenCreditRate(modelPrices, chatModel) || FALLBACK_TEXT_TOKEN_CREDIT_RATE,
[chatModel, modelPrices],
);
const billingEstimate = useMemo(() => {
if (activeMode === "image") {
return {
@@ -552,9 +578,11 @@ function WorkbenchPage({
};
}
}
const textBillingPrefix =
selectedChatTokenRate.source === "server" ? "文本计费" : "服务端价格暂不可用,按默认预估";
return {
label: "按 Token 结算",
title: "文本对话按输入、输出 Token 实际用量结算,完成后显示本次积分",
title: `${textBillingPrefix}${activeModel}${formatTextTokenCreditRule(selectedChatTokenRate)}`,
};
}, [
activeMode,
@@ -562,6 +590,7 @@ function WorkbenchPage({
activeModelValue,
imageSettingsSummary,
referenceItems,
selectedChatTokenRate,
videoDuration,
videoQuality,
videoQualityLabel,