feat: support image edit model mapping

(cherry picked from commit 1a869d8ad77f262ee27675ec2deaf451b1743eb7)
This commit is contained in:
CaIon
2025-04-24 21:41:38 +08:00
parent f9f32a0158
commit 487ef35c58
5 changed files with 235 additions and 63 deletions

View File

@@ -987,7 +987,9 @@ const LogsTable = () => {
other?.group_ratio,
other?.cache_tokens || 0,
other?.cache_ratio || 1.0,
);
other?.image || false,
other?.image_ratio || 0,
other?.image_output || 0,);
}
expandDataLocal.push({
key: t('计费过程'),

View File

@@ -314,6 +314,9 @@ export function renderModelPrice(
groupRatio,
cacheTokens = 0,
cacheRatio = 1.0,
image = false,
imageRatio = 1.0,
imageOutputTokens = 0,
) {
if (modelPrice !== -1) {
return i18next.t(
@@ -331,10 +334,15 @@ export function renderModelPrice(
let inputRatioPrice = modelRatio * 2.0;
let completionRatioPrice = modelRatio * 2.0 * completionRatio;
let cacheRatioPrice = modelRatio * 2.0 * cacheRatio;
let imageRatioPrice = modelRatio * 2.0 * imageRatio;
// Calculate effective input tokens (non-cached + cached with ratio applied)
const effectiveInputTokens =
let effectiveInputTokens =
inputTokens - cacheTokens + cacheTokens * cacheRatio;
// Handle image tokens if present
if (image && imageOutputTokens > 0) {
effectiveInputTokens = inputTokens - imageOutputTokens + imageOutputTokens * imageRatio;
}
let price =
(effectiveInputTokens / 1000000) * inputRatioPrice * groupRatio +
@@ -344,13 +352,13 @@ export function renderModelPrice(
<>
<article>
<p>
{i18next.t('提示价格:${{price}} / 1M tokens', {
{i18next.t('输入价格:${{price}} / 1M tokens', {
price: inputRatioPrice,
})}
</p>
<p>
{i18next.t(
'补全价格:${{price}} * {{completionRatio}} = ${{total}} / 1M tokens (补全倍率: {{completionRatio}})',
'输出价格:${{price}} * {{completionRatio}} = ${{total}} / 1M tokens (补全倍率: {{completionRatio}})',
{
price: inputRatioPrice,
total: completionRatioPrice,
@@ -370,11 +378,24 @@ export function renderModelPrice(
)}
</p>
)}
{image && imageOutputTokens > 0 && (
<p>
{i18next.t(
'图片输入价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens (图片倍率: {{imageRatio}})',
{
price: imageRatioPrice,
ratio: groupRatio,
total: imageRatioPrice * groupRatio,
imageRatio: imageRatio,
},
)}
</p>
)}
<p></p>
<p>
{cacheTokens > 0
{cacheTokens > 0 && !image
? i18next.t(
'提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
'输入 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 输出 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
{
nonCacheInput: inputTokens - cacheTokens,
cacheInput: cacheTokens,
@@ -386,8 +407,22 @@ export function renderModelPrice(
total: price.toFixed(6),
},
)
: image && imageOutputTokens > 0
? i18next.t(
'输入 {{nonImageInput}} tokens + 图片输入 {{imageInput}} tokens * {{imageRatio}} / 1M tokens * ${{price}} + 输出 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
{
nonImageInput: inputTokens - imageOutputTokens,
imageInput: imageOutputTokens,
imageRatio: imageRatio,
price: inputRatioPrice,
completion: completionTokens,
compPrice: completionRatioPrice,
ratio: groupRatio,
total: price.toFixed(6),
},
)
: i18next.t(
'提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
'输入 {{input}} tokens / 1M tokens * ${{price}} + 输出 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
{
input: inputTokens,
price: inputRatioPrice,
@@ -405,12 +440,53 @@ export function renderModelPrice(
}
}
export function renderLogContent(
modelRatio,
completionRatio,
modelPrice = -1,
groupRatio,
user_group_ratio,
image = false,
imageRatio = 1.0,
) {
const useUserGroupRatio = isValidGroupRatio(user_group_ratio);
const ratioLabel = useUserGroupRatio ? i18next.t('专属倍率') : i18next.t('分组倍率');
const ratio = useUserGroupRatio ? user_group_ratio : groupRatio;
if (modelPrice !== -1) {
return i18next.t('模型价格 ${{price}}{{ratioType}} {{ratio}}', {
price: modelPrice,
ratioType: ratioLabel,
ratio
});
} else {
if (image) {
return i18next.t('模型倍率 {{modelRatio}},输出倍率 {{completionRatio}},图片输入倍率 {{imageRatio}}{{ratioType}} {{ratio}}', {
modelRatio: modelRatio,
completionRatio: completionRatio,
imageRatio: imageRatio,
ratioType: ratioLabel,
ratio
});
} else {
return i18next.t('模型倍率 {{modelRatio}},输出倍率 {{completionRatio}}{{ratioType}} {{ratio}}', {
modelRatio: modelRatio,
completionRatio: completionRatio,
ratioType: ratioLabel,
ratio
});
}
}
}
export function renderModelPriceSimple(
modelRatio,
modelPrice = -1,
groupRatio,
cacheTokens = 0,
cacheRatio = 1.0,
image = false,
imageRatio = 1.0,
) {
if (modelPrice !== -1) {
return i18next.t('价格:${{price}} * 分组:{{ratio}}', {
@@ -418,7 +494,28 @@ export function renderModelPriceSimple(
ratio: groupRatio,
});
} else {
if (cacheTokens !== 0) {
if (image && cacheTokens !== 0) {
return i18next.t(
'模型: {{ratio}} * {{ratioType}}: {{groupRatio}} * 缓存倍率: {{cacheRatio}} * 图片输入倍率: {{imageRatio}}',
{
ratio: modelRatio,
ratioType: ratioLabel,
groupRatio: groupRatio,
cacheRatio: cacheRatio,
imageRatio: imageRatio,
},
);
} else if (image) {
return i18next.t(
'模型: {{ratio}} * {{ratioType}}: {{groupRatio}} * 图片输入倍率: {{imageRatio}}',
{
ratio: modelRatio,
ratioType: ratioLabel,
groupRatio: groupRatio,
imageRatio: imageRatio,
},
);
} else if (cacheTokens !== 0) {
return i18next.t(
'模型: {{ratio}} * 分组: {{groupRatio}} * 缓存: {{cacheRatio}}',
{
@@ -882,7 +979,7 @@ export function renderClaudeLogContent(
});
} else {
return i18next.t(
'模型倍率 {{modelRatio}}补全倍率 {{completionRatio}},缓存倍率 {{cacheRatio}},缓存创建倍率 {{cacheCreationRatio}}{{ratioType}} {{ratio}}',
'模型倍率 {{modelRatio}}输出倍率 {{completionRatio}},缓存倍率 {{cacheRatio}},缓存创建倍率 {{cacheCreationRatio}}{{ratioType}} {{ratio}}',
{
modelRatio: modelRatio,
completionRatio: completionRatio,
@@ -933,30 +1030,3 @@ export function renderClaudeModelPriceSimple(
}
}
}
export function renderLogContent(
modelRatio,
completionRatio,
modelPrice = -1,
groupRatio,
) {
const ratioLabel = false ? i18next.t('专属倍率') : i18next.t('分组倍率');
if (modelPrice !== -1) {
return i18next.t('模型价格 ${{price}}{{ratioType}} {{ratio}}', {
price: modelPrice,
ratioType: ratioLabel,
ratio: groupRatio,
});
} else {
return i18next.t(
'模型倍率 {{modelRatio}},补全倍率 {{completionRatio}}{{ratioType}} {{ratio}}',
{
modelRatio: modelRatio,
completionRatio: completionRatio,
ratioType: ratioLabel,
ratio: groupRatio,
},
);
}
}

View File

@@ -679,7 +679,10 @@
"当前分组可用": "Available in current group",
"当前分组不可用": "The current group is unavailable",
"提示:": "input:",
"输入:": "input:",
"补全:": "output:",
"输出:": "output:",
"图片输出:": "Image output:",
"模型价格:": "Model price:",
"模型:": "Model:",
"分组:": "Grouping:",
@@ -1054,14 +1057,16 @@
"等级": "grade",
"钉钉": "DingTalk",
"模型价格:${{price}} * 分组倍率:{{ratio}} = ${{total}}": "Model price: ${{price}} * Group ratio: {{ratio}} = ${{total}}",
"提示${{price}} * {{ratio}} = ${{total}} / 1M tokens": "Prompt: ${{price}} * {{ratio}} = ${{total}} / 1M tokens",
"补全${{price}} * {{ratio}} = ${{total}} / 1M tokens": "Completion: ${{price}} * {{ratio}} = ${{total}} / 1M tokens",
"音频提示${{price}} * {{ratio}} * {{audioRatio}} = ${{total}} / 1M tokens": "Audio prompt: ${{price}} * {{ratio}} * {{audioRatio}} = ${{total}} / 1M tokens",
"输入${{price}} * {{ratio}} = ${{total}} / 1M tokens": "Prompt: ${{price}} * {{ratio}} = ${{total}} / 1M tokens",
"输出${{price}} * {{ratio}} = ${{total}} / 1M tokens": "Completion: ${{price}} * {{ratio}} = ${{total}} / 1M tokens",
"图片输入${{price}} * {{ratio}} = ${{total}} / 1M tokens (图片倍率: {{imageRatio}})": "Image input: ${{price}} * {{ratio}} = ${{total}} / 1M tokens (Image ratio: {{imageRatio}})",
"音频输入:${{price}} * {{ratio}} * {{audioRatio}} = ${{total}} / 1M tokens": "Audio prompt: ${{price}} * {{ratio}} * {{audioRatio}} = ${{total}} / 1M tokens",
"音频提示 {{input}} tokens / 1M tokens * ${{price}} * {{audioRatio}} + 音频补全 {{completion}} tokens / 1M tokens * ${{price}} * {{audioRatio}} * {{audioCompRatio}}": "Audio prompt {{input}} tokens / 1M tokens * ${{price}} * {{audioRatio}} + Audio completion {{completion}} tokens / 1M tokens * ${{price}} * {{audioRatio}} * {{audioCompRatio}}",
"音频补全${{price}} * {{ratio}} * {{audioRatio}} * {{audioCompRatio}} = ${{total}} / 1M tokens": "Audio completion: ${{price}} * {{ratio}} * {{audioRatio}} * {{audioCompRatio}} = ${{total}} / 1M tokens",
"音频输出${{price}} * {{ratio}} * {{audioRatio}} * {{audioCompRatio}} = ${{total}} / 1M tokens": "Audio completion: ${{price}} * {{ratio}} * {{audioRatio}} * {{audioCompRatio}} = ${{total}} / 1M tokens",
"输入 {{nonImageInput}} tokens + 图片输入 {{imageInput}} tokens * {{imageRatio}} / 1M tokens * ${{price}} + 输出 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}": "Input {{nonImageInput}} tokens + Image input {{imageInput}} tokens * {{imageRatio}} / 1M tokens * ${{price}} + Output {{completion}} tokens / 1M tokens * ${{compPrice}} * Group {{ratio}} = ${{total}}",
"(文字 + 音频)* 分组倍率 {{ratio}} = ${{total}}": "(Text + Audio) * Group ratio {{ratio}} = ${{total}}",
"文字提示 {{input}} tokens / 1M tokens * ${{price}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} +": "Text prompt {{input}} tokens / 1M tokens * ${{price}} + Text completion {{completion}} tokens / 1M tokens * ${{compPrice}} +",
"提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}": "Prompt {{input}} tokens / 1M tokens * ${{price}} + Completion {{completion}} tokens / 1M tokens * ${{compPrice}} * Group {{ratio}} = ${{total}}",
"输入 {{input}} tokens / 1M tokens * ${{price}} + 输出 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}": "Prompt {{input}} tokens / 1M tokens * ${{price}} + Completion {{completion}} tokens / 1M tokens * ${{compPrice}} * Group {{ratio}} = ${{total}}",
"价格:${{price}} * 分组:{{ratio}}": "Price: ${{price}} * Group: {{ratio}}",
"模型: {{ratio}} * 分组: {{groupRatio}}": "Model: {{ratio}} * Group: {{groupRatio}}",
"统计额度": "Statistical quota",