feat: Enhance DeepSeek API integration with retries and timeout handling

- Updated API key environment variable from DEEPL_API_KEY to DEEPSEEK_API_KEY
- Increased maximum text chunk length from 5000 to 8000 characters
- Implemented request timeout and retry logic for API calls
- Added handling for rate limiting responses (HTTP 429)
- Improved error handling for API responses
This commit is contained in:
Harvey Zhao committed 2026-03-08 13:00:57 +08:00
1 parent 562cfe18db
commit 3adff76edf
2 files changed
+2032 -1298

No files matched your search

+1994 -1293
View File
File diff suppressed because it is too large. Load diff
+38 -5
View File
@@ -12,11 +12,13 @@ const rootDir = path.resolve(__dirname, '../packages/artplayer-vitepress')
const dostDir = path.resolve(__dirname, '../docs') const dostDir = path.resolve(__dirname, '../docs')
const outputFile = path.resolve(__dirname, '../docs/llms.txt') const outputFile = path.resolve(__dirname, '../docs/llms.txt')
const API_URL = 'https://api.deepseek.com/v1/chat/completions' const API_URL = 'https://api.deepseek.com/v1/chat/completions'
const API_KEY = process.env.DEEPL_API_KEY const API_KEY = process.env.DEEPSEEK_API_KEY
const MAX_CONCURRENT_REQUESTS = 3 // 每类并发请求数 const MAX_CONCURRENT_REQUESTS = 3 // 每类并发请求数
const REQUEST_TIMEOUT = 60000 // 请求超时时间 60秒
const MAX_RETRIES = 3 // 最大重试次数
if (!API_KEY) { if (!API_KEY) {
console.error('❌ Missing DEEPL_API_KEY in .env file') console.error('❌ Missing DEEPSEEK_API_KEY in .env file')
process.exit(1) process.exit(1)
} }
@@ -35,7 +37,7 @@ function readFiles(files) {
return content return content
} }
function splitText(text, maxLen = 5000) { function splitText(text, maxLen = 8000) {
const paragraphs = text.split(/\n{2,}/) const paragraphs = text.split(/\n{2,}/)
const chunks = [] const chunks = []
let buffer = '' let buffer = ''
@@ -52,9 +54,15 @@ function splitText(text, maxLen = 5000) {
} }
async function askDeepSeek(prompt, text, tag, id) { async function askDeepSeek(prompt, text, tag, id) {
console.log(`🧠 [${tag}] Sending chunk ${id}`) for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
try {
console.log(`🧠 [${tag}] Sending chunk ${id} (attempt ${attempt}/${MAX_RETRIES})`)
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT)
const res = await fetch(API_URL, { const res = await fetch(API_URL, {
method: 'POST', method: 'POST',
signal: controller.signal,
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`, 'Authorization': `Bearer ${API_KEY}`,
@@ -68,6 +76,15 @@ async function askDeepSeek(prompt, text, tag, id) {
temperature: 0.3, temperature: 0.3,
}), }),
}) })
clearTimeout(timeout)
// 处理限流情况
if (res.status === 429) {
const delay = Math.pow(2, attempt) * 1000
console.log(`⏳ [${tag}] Rate limited, waiting ${delay}ms...`)
await new Promise(r => setTimeout(r, delay))
continue
}
if (!res.ok) { if (!res.ok) {
const err = await res.text() const err = await res.text()
@@ -76,7 +93,23 @@ async function askDeepSeek(prompt, text, tag, id) {
} }
const data = await res.json() const data = await res.json()
return data.choices?.[0]?.message?.content?.trim() || '' if (!data.choices || !data.choices[0]) {
throw new Error('Invalid API response: missing choices')
}
return data.choices[0].message?.content?.trim() || ''
}
catch (err) {
if (err.name === 'AbortError') {
console.error(`[${tag}] Request timeout for chunk ${id}`)
}
if (attempt === MAX_RETRIES) {
throw err
}
const delay = 1000 * attempt
console.log(`⚠️ [${tag}] Retry ${attempt}/${MAX_RETRIES} after ${delay}ms...`)
await new Promise(r => setTimeout(r, delay))
}
}
} }
async function runConcurrent(tasks, limit = MAX_CONCURRENT_REQUESTS) { async function runConcurrent(tasks, limit = MAX_CONCURRENT_REQUESTS) {