feat: Enhance API testing to allow sending actual chat messages to specific accounts and display AI replies.

This commit is contained in:
CJACK
2026-02-01 03:19:25 +08:00
parent 5ac472626e
commit a6d89876ba
2 changed files with 155 additions and 7 deletions

View File

@@ -287,8 +287,12 @@ async def validate_all_accounts(_: bool = Depends(verify_admin)):
# ----------------------------------------------------------------------
# 账号 API 测试(实际发送请求)
# ----------------------------------------------------------------------
async def test_account_api(account: dict, model: str = "deepseek-chat") -> dict:
"""测试单个账号的 API 调用能力"""
async def test_account_api(account: dict, model: str = "deepseek-chat", message: str = "") -> dict:
"""测试单个账号的 API 调用能力
如果提供了 message会发送实际请求并返回 AI 回复;
否则只测试创建会话(快速测试)。
"""
from curl_cffi import requests as cffi_requests
from core.deepseek import DEEPSEEK_CREATE_SESSION_URL, DEEPSEEK_CHAT_COMPLETION_URL, BASE_HEADERS
from core.pow import get_pow_response_direct
@@ -300,6 +304,7 @@ async def test_account_api(account: dict, model: str = "deepseek-chat") -> dict:
"response_time": 0,
"message": "",
"model": model,
"reply": "", # AI 回复内容
}
import time
@@ -339,9 +344,70 @@ async def test_account_api(account: dict, model: str = "deepseek-chat") -> dict:
return result
session_id = session_data["data"]["biz_data"]["id"]
# 如果没有消息,只测试会话创建
if not message:
result["success"] = True
result["message"] = "API 测试成功"
result["response_time"] = round((time.time() - start_time) * 1000)
return result
# 2. 发送实际请求
from core.pow import get_pow_response_direct
pow_resp = get_pow_response_direct(headers)
if not pow_resp:
result["message"] = "获取 PoW 失败"
return result
chat_headers = {**headers, "x-ds-pow-response": pow_resp}
thinking_enabled = "reasoner" in model.lower()
search_enabled = "search" in model.lower()
payload = {
"chat_session_id": session_id,
"parent_message_id": None,
"prompt": message,
"ref_file_ids": [],
"thinking_enabled": thinking_enabled,
"search_enabled": search_enabled,
}
chat_resp = cffi_requests.post(
DEEPSEEK_CHAT_COMPLETION_URL,
headers=chat_headers,
json=payload,
impersonate="safari15_3",
timeout=60,
stream=True,
)
if chat_resp.status_code != 200:
result["message"] = f"对话请求失败: HTTP {chat_resp.status_code}"
return result
# 解析流式响应获取回复
reply_text = ""
for line in chat_resp.iter_lines():
try:
line_str = line.decode("utf-8")
if line_str.startswith("data:"):
data_str = line_str[5:].strip()
if data_str == "[DONE]":
break
import json
chunk = json.loads(data_str)
choices = chunk.get("choices", [])
if choices:
delta = choices[0].get("delta", {})
if delta.get("type") == "text":
reply_text += delta.get("content", "")
except:
pass
result["success"] = True
result["message"] = "API 测试成功"
result["response_time"] = round((time.time() - start_time) * 1000) # ms
result["reply"] = reply_text[:500] # 限制长度
result["response_time"] = round((time.time() - start_time) * 1000)
except Exception as e:
result["message"] = f"测试失败: {str(e)}"
@@ -351,10 +417,15 @@ async def test_account_api(account: dict, model: str = "deepseek-chat") -> dict:
@router.post("/accounts/test")
async def test_single_account(request: Request, _: bool = Depends(verify_admin)):
"""测试单个账号的 API 调用"""
"""测试单个账号的 API 调用
如果提供 message会发送实际请求并返回 AI 回复;
否则只快速测试创建会话。
"""
data = await request.json()
identifier = data.get("identifier", "")
model = data.get("model", "deepseek-chat")
message = data.get("message", "")
if not identifier:
raise HTTPException(status_code=400, detail="需要账号标识email 或 mobile")
@@ -369,7 +440,7 @@ async def test_single_account(request: Request, _: bool = Depends(verify_admin))
if not account:
raise HTTPException(status_code=404, detail="账号不存在")
result = await test_account_api(account, model)
result = await test_account_api(account, model, message)
# 保存可能更新的 token
save_config(CONFIG)

View File

@@ -11,9 +11,13 @@ export default function ApiTester({ config, onMessage }) {
const [model, setModel] = useState('deepseek-chat')
const [message, setMessage] = useState('你好,请用一句话介绍你自己。')
const [apiKey, setApiKey] = useState('')
const [selectedAccount, setSelectedAccount] = useState('') // 空为随机
const [response, setResponse] = useState(null)
const [loading, setLoading] = useState(false)
// 获取账号列表
const accounts = config.accounts || []
const testApi = async () => {
setLoading(true)
setResponse(null)
@@ -84,6 +88,48 @@ export default function ApiTester({ config, onMessage }) {
}
}
// 智能测试:根据是否选择账号决定测试方式
const sendTest = async () => {
setLoading(true)
setResponse(null)
// 如果选择了指定账号,使用账号测试接口
if (selectedAccount) {
try {
const res = await fetch('/admin/accounts/test', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
identifier: selectedAccount,
model,
message,
}),
})
const data = await res.json()
setResponse({
success: data.success,
status_code: res.status,
response: data,
account: selectedAccount,
})
if (data.success) {
onMessage('success', `${selectedAccount}: 测试成功 (${data.response_time}ms)`)
} else {
onMessage('error', `${selectedAccount}: ${data.message}`)
}
} catch (e) {
onMessage('error', '网络错误: ' + e.message)
setResponse({ error: e.message })
} finally {
setLoading(false)
}
return
}
// 随机账号:使用标准 API
directTest()
}
return (
<div className="section">
<div className="card">
@@ -102,6 +148,21 @@ export default function ApiTester({ config, onMessage }) {
</select>
</div>
<div className="form-group">
<label className="form-label">账号指定测试哪个账号</label>
<select
className="form-input"
value={selectedAccount}
onChange={e => setSelectedAccount(e.target.value)}
>
<option value="">🎲 随机选择</option>
{accounts.map((acc, i) => {
const id = acc.email || acc.mobile
return <option key={i} value={id}>{id} {acc.has_token ? '✅' : '⚠️'}</option>
})}
</select>
</div>
<div className="form-group">
<label className="form-label">API Key留空使用第一个配置的 Key</label>
<input
@@ -124,8 +185,9 @@ export default function ApiTester({ config, onMessage }) {
</div>
<div className="btn-group">
<button className="btn btn-primary" onClick={directTest} disabled={loading}>
{loading ? <span className="loading"></span> : '🚀 发送请求'}
<button className="btn btn-primary" onClick={sendTest} disabled={loading}>
{loading ? <span className="loading"></span> :
selectedAccount ? `🚀 使用 ${selectedAccount} 发送` : '🚀 发送请求'}
</button>
</div>
</div>
@@ -155,6 +217,21 @@ export default function ApiTester({ config, onMessage }) {
</div>
</div>
)}
{/* 指定账号测试的回复 */}
{response.success && response.response?.reply && (
<div style={{ marginTop: '1rem' }}>
<div className="form-label">AI 回复 ({response.account})</div>
<div style={{
padding: '1rem',
background: 'var(--bg-tertiary)',
borderRadius: 'var(--radius)',
whiteSpace: 'pre-wrap'
}}>
{response.response.reply}
</div>
</div>
)}
</div>
)}
</div>