mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-04-19 03:07:27 +00:00
feat: logs cache field (#2920)
* feat: logs cache field * feat: logs cache field * feat: logs cache field
This commit is contained in:
@@ -286,6 +286,44 @@ function renderModelName(record, copyText, t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toTokenNumber(value) {
|
||||||
|
const parsed = Number(value);
|
||||||
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTokenCount(value) {
|
||||||
|
return toTokenNumber(value).toLocaleString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPromptCacheSummary(other) {
|
||||||
|
if (!other || typeof other !== 'object') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheReadTokens = toTokenNumber(other.cache_tokens);
|
||||||
|
const cacheCreationTokens = toTokenNumber(other.cache_creation_tokens);
|
||||||
|
const cacheCreationTokens5m = toTokenNumber(other.cache_creation_tokens_5m);
|
||||||
|
const cacheCreationTokens1h = toTokenNumber(other.cache_creation_tokens_1h);
|
||||||
|
|
||||||
|
const hasSplitCacheCreation =
|
||||||
|
cacheCreationTokens5m > 0 || cacheCreationTokens1h > 0;
|
||||||
|
const cacheWriteTokens = hasSplitCacheCreation
|
||||||
|
? cacheCreationTokens5m + cacheCreationTokens1h
|
||||||
|
: cacheCreationTokens;
|
||||||
|
|
||||||
|
if (cacheReadTokens <= 0 && cacheWriteTokens <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
cacheReadTokens,
|
||||||
|
cacheWriteTokens,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const getLogsColumns = ({
|
export const getLogsColumns = ({
|
||||||
t,
|
t,
|
||||||
COLUMN_KEYS,
|
COLUMN_KEYS,
|
||||||
@@ -524,11 +562,56 @@ export const getLogsColumns = ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: COLUMN_KEYS.PROMPT,
|
key: COLUMN_KEYS.PROMPT,
|
||||||
title: t('输入'),
|
title: (
|
||||||
|
<div className='flex items-center gap-1'>
|
||||||
|
{t('输入')}
|
||||||
|
<Tooltip
|
||||||
|
content={t(
|
||||||
|
'根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<IconHelpCircle className='text-gray-400 cursor-help' />
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
dataIndex: 'prompt_tokens',
|
dataIndex: 'prompt_tokens',
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
|
const other = getLogOther(record.other);
|
||||||
|
const cacheSummary = getPromptCacheSummary(other);
|
||||||
|
const hasCacheRead = (cacheSummary?.cacheReadTokens || 0) > 0;
|
||||||
|
const hasCacheWrite = (cacheSummary?.cacheWriteTokens || 0) > 0;
|
||||||
|
let cacheText = '';
|
||||||
|
if (hasCacheRead && hasCacheWrite) {
|
||||||
|
cacheText = `${t('缓存读')} ${formatTokenCount(cacheSummary.cacheReadTokens)} · ${t('写')} ${formatTokenCount(cacheSummary.cacheWriteTokens)}`;
|
||||||
|
} else if (hasCacheRead) {
|
||||||
|
cacheText = `${t('缓存读')} ${formatTokenCount(cacheSummary.cacheReadTokens)}`;
|
||||||
|
} else if (hasCacheWrite) {
|
||||||
|
cacheText = `${t('缓存写')} ${formatTokenCount(cacheSummary.cacheWriteTokens)}`;
|
||||||
|
}
|
||||||
|
|
||||||
return record.type === 0 || record.type === 2 || record.type === 5 ? (
|
return record.type === 0 || record.type === 2 || record.type === 5 ? (
|
||||||
<>{<span> {text} </span>}</>
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'inline-flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
lineHeight: 1.2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span>{text}</span>
|
||||||
|
{cacheText ? (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginTop: 2,
|
||||||
|
fontSize: 11,
|
||||||
|
color: 'var(--semi-color-text-2)',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{cacheText}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2845,6 +2845,10 @@
|
|||||||
"填写服务器地址后自动生成:": "Auto-generated after entering server address: ",
|
"填写服务器地址后自动生成:": "Auto-generated after entering server address: ",
|
||||||
"自动生成:": "Auto-generated: ",
|
"自动生成:": "Auto-generated: ",
|
||||||
"请先填写服务器地址,以自动生成完整的端点 URL": "Please enter the server address first to auto-generate full endpoint URLs",
|
"请先填写服务器地址,以自动生成完整的端点 URL": "Please enter the server address first to auto-generate full endpoint URLs",
|
||||||
"端点 URL 必须是完整地址(以 http:// 或 https:// 开头)": "Endpoint URL must be a full address (starting with http:// or https://)"
|
"端点 URL 必须是完整地址(以 http:// 或 https:// 开头)": "Endpoint URL must be a full address (starting with http:// or https://)",
|
||||||
|
"缓存读": "Cache Read",
|
||||||
|
"缓存写": "Cache Write",
|
||||||
|
"写": "Write",
|
||||||
|
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Per Anthropic conventions, /v1/messages input tokens count only non-cached input and exclude cache read/write tokens."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2719,6 +2719,10 @@
|
|||||||
"套餐名称": "Nom du plan",
|
"套餐名称": "Nom du plan",
|
||||||
"应付金额": "Montant à payer",
|
"应付金额": "Montant à payer",
|
||||||
"支付": "Payer",
|
"支付": "Payer",
|
||||||
"管理员未开启在线支付功能,请联系管理员配置。": "Le paiement en ligne n'est pas activé par l'administrateur. Veuillez contacter l'administrateur."
|
"管理员未开启在线支付功能,请联系管理员配置。": "Le paiement en ligne n'est pas activé par l'administrateur. Veuillez contacter l'administrateur.",
|
||||||
|
"缓存读": "Lecture cache",
|
||||||
|
"缓存写": "Écriture cache",
|
||||||
|
"写": "Écriture",
|
||||||
|
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Selon la convention Anthropic, les tokens d'entrée de /v1/messages ne comptent que les entrées non mises en cache et excluent les tokens de lecture/écriture du cache."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2702,6 +2702,10 @@
|
|||||||
"套餐名称": "プラン名",
|
"套餐名称": "プラン名",
|
||||||
"应付金额": "支払金額",
|
"应付金额": "支払金額",
|
||||||
"支付": "支払う",
|
"支付": "支払う",
|
||||||
"管理员未开启在线支付功能,请联系管理员配置。": "管理者がオンライン決済を有効にしていません。管理者に連絡してください。"
|
"管理员未开启在线支付功能,请联系管理员配置。": "管理者がオンライン決済を有効にしていません。管理者に連絡してください。",
|
||||||
|
"缓存读": "キャッシュ読取",
|
||||||
|
"缓存写": "キャッシュ書込",
|
||||||
|
"写": "書込",
|
||||||
|
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Anthropic の仕様により、/v1/messages の入力 tokens は非キャッシュ入力のみを集計し、キャッシュ読み取り/書き込み tokens は含みません。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2732,6 +2732,10 @@
|
|||||||
"套餐名称": "Название плана",
|
"套餐名称": "Название плана",
|
||||||
"应付金额": "К оплате",
|
"应付金额": "К оплате",
|
||||||
"支付": "Оплатить",
|
"支付": "Оплатить",
|
||||||
"管理员未开启在线支付功能,请联系管理员配置。": "Онлайн-оплата не включена администратором. Пожалуйста, свяжитесь с администратором."
|
"管理员未开启在线支付功能,请联系管理员配置。": "Онлайн-оплата не включена администратором. Пожалуйста, свяжитесь с администратором.",
|
||||||
|
"缓存读": "Чтение кэша",
|
||||||
|
"缓存写": "Запись в кэш",
|
||||||
|
"写": "Запись",
|
||||||
|
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Согласно соглашению Anthropic, входные токены /v1/messages учитывают только некэшированный ввод и не включают токены чтения/записи кэша."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3280,6 +3280,10 @@
|
|||||||
"套餐名称": "Tên gói",
|
"套餐名称": "Tên gói",
|
||||||
"应付金额": "Số tiền phải trả",
|
"应付金额": "Số tiền phải trả",
|
||||||
"支付": "Thanh toán",
|
"支付": "Thanh toán",
|
||||||
"管理员未开启在线支付功能,请联系管理员配置。": "Quản trị viên chưa bật thanh toán trực tuyến, vui lòng liên hệ quản trị viên."
|
"管理员未开启在线支付功能,请联系管理员配置。": "Quản trị viên chưa bật thanh toán trực tuyến, vui lòng liên hệ quản trị viên.",
|
||||||
|
"缓存读": "Đọc bộ nhớ đệm",
|
||||||
|
"缓存写": "Ghi bộ nhớ đệm",
|
||||||
|
"写": "Ghi",
|
||||||
|
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Theo quy ước của Anthropic, input tokens của /v1/messages chỉ tính phần đầu vào không dùng cache và không bao gồm tokens đọc/ghi cache."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2790,6 +2790,10 @@
|
|||||||
"填写服务器地址后自动生成:": "填写服务器地址后自动生成:",
|
"填写服务器地址后自动生成:": "填写服务器地址后自动生成:",
|
||||||
"自动生成:": "自动生成:",
|
"自动生成:": "自动生成:",
|
||||||
"请先填写服务器地址,以自动生成完整的端点 URL": "请先填写服务器地址,以自动生成完整的端点 URL",
|
"请先填写服务器地址,以自动生成完整的端点 URL": "请先填写服务器地址,以自动生成完整的端点 URL",
|
||||||
"端点 URL 必须是完整地址(以 http:// 或 https:// 开头)": "端点 URL 必须是完整地址(以 http:// 或 https:// 开头)"
|
"端点 URL 必须是完整地址(以 http:// 或 https:// 开头)": "端点 URL 必须是完整地址(以 http:// 或 https:// 开头)",
|
||||||
|
"缓存读": "缓存读",
|
||||||
|
"缓存写": "缓存写",
|
||||||
|
"写": "写",
|
||||||
|
"根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user