feat: 优化 Claude 模型缓存费用计算,支持 5 分钟和 1 小时两种缓存类型

- 在 pricingService 中硬编码 1 小时缓存价格(Opus: $30/MTok, Sonnet: $6/MTok, Haiku: $1.6/MTok)
- 更新 usage 捕获逻辑以分别记录 ephemeral_5m 和 ephemeral_1h 缓存 tokens
- 改进费用计算逻辑,正确计算两种缓存类型的费用
- 新增 recordUsageWithDetails 方法支持详细的缓存数据
- 保持向后兼容性,支持旧的数据格式
- 删除测试脚本 test-openai-refresh.js
- 修复 OpenAI token 刷新逻辑

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
shaw
2025-08-16 22:31:20 +08:00
parent b1344fef8c
commit 681cb8cd82
8 changed files with 312 additions and 137 deletions

View File

@@ -1,103 +0,0 @@
#!/usr/bin/env node
/**
* OpenAI Token 刷新功能测试脚本
* 用于测试 openaiAccountService 的 token 刷新功能
*/
const openaiAccountService = require('../src/services/openaiAccountService')
const logger = require('../src/utils/logger')
// 测试配置(可以通过环境变量或命令行参数传入)
const TEST_REFRESH_TOKEN = process.env.OPENAI_REFRESH_TOKEN || process.argv[2]
async function testRefreshToken() {
if (!TEST_REFRESH_TOKEN) {
console.error('❌ 请提供 refresh token 作为参数或设置环境变量 OPENAI_REFRESH_TOKEN')
console.log('使用方法:')
console.log(' node scripts/test-openai-refresh.js <refresh_token>')
console.log(' 或')
console.log(' OPENAI_REFRESH_TOKEN=<token> node scripts/test-openai-refresh.js')
process.exit(1)
}
console.log('🔄 开始测试 OpenAI token 刷新功能...\n')
try {
// 测试不带代理的刷新
console.log('1⃣ 测试直接刷新(无代理)...')
const result = await openaiAccountService.refreshAccessToken(TEST_REFRESH_TOKEN)
console.log('✅ 刷新成功!')
console.log(' Access Token:', result.access_token ? result.access_token.substring(0, 30) + '...' : 'N/A')
console.log(' ID Token:', result.id_token ? result.id_token.substring(0, 30) + '...' : 'N/A')
console.log(' Refresh Token:', result.refresh_token ? result.refresh_token.substring(0, 30) + '...' : 'N/A')
console.log(' 有效期:', result.expires_in, '秒')
console.log(' 过期时间:', new Date(result.expiry_date).toLocaleString())
// 如果返回了新的 refresh token
if (result.refresh_token && result.refresh_token !== TEST_REFRESH_TOKEN) {
console.log('\n⚠ 注意:收到了新的 refresh token请保存以供后续使用')
}
// 测试带代理的刷新(如果配置了代理)
if (process.env.PROXY_HOST && process.env.PROXY_PORT) {
console.log('\n2⃣ 测试通过代理刷新...')
const proxy = {
type: process.env.PROXY_TYPE || 'http',
host: process.env.PROXY_HOST,
port: parseInt(process.env.PROXY_PORT),
username: process.env.PROXY_USERNAME,
password: process.env.PROXY_PASSWORD
}
console.log(' 代理配置:', `${proxy.type}://${proxy.host}:${proxy.port}`)
const proxyResult = await openaiAccountService.refreshAccessToken(
result.refresh_token || TEST_REFRESH_TOKEN,
proxy
)
console.log('✅ 通过代理刷新成功!')
console.log(' Access Token:', proxyResult.access_token ? proxyResult.access_token.substring(0, 30) + '...' : 'N/A')
}
// 测试完整的账户刷新流程如果提供了账户ID
if (process.env.OPENAI_ACCOUNT_ID) {
console.log('\n3⃣ 测试账户刷新流程...')
console.log(' 账户ID:', process.env.OPENAI_ACCOUNT_ID)
try {
const account = await openaiAccountService.getAccount(process.env.OPENAI_ACCOUNT_ID)
if (account) {
console.log(' 账户名称:', account.name)
console.log(' 当前过期时间:', account.expiresAt)
const refreshResult = await openaiAccountService.refreshAccountToken(process.env.OPENAI_ACCOUNT_ID)
console.log('✅ 账户 token 刷新成功!')
console.log(' 新的过期时间:', new Date(refreshResult.expiry_date).toLocaleString())
}
} catch (error) {
console.log('⚠️ 账户刷新测试失败:', error.message)
}
}
console.log('\n✅ 所有测试完成!')
} catch (error) {
console.error('\n❌ 测试失败:', error.message)
if (error.response) {
console.error('响应状态:', error.response.status)
console.error('响应数据:', error.response.data)
}
process.exit(1)
}
}
// 运行测试
testRefreshToken().then(() => {
process.exit(0)
}).catch((error) => {
console.error('Unexpected error:', error)
process.exit(1)
})