🐛Fix: T4 & T5 & T6 累积更新
This commit is contained in:
@@ -89,16 +89,17 @@ const loadConfiguredPlatforms = () => {
|
||||
const getPlatformName = (platformId) => {
|
||||
const platforms = [
|
||||
{ id: 'openai', name: 'OpenAI' },
|
||||
{ id: 'anthropic', name: 'Anthropic' },
|
||||
{ id: 'google', name: 'Google (Gemini)' },
|
||||
{ id: 'qwen', name: '通义千问(阿里云)' },
|
||||
{ id: 'wenxin', name: '文心一言(百度)' }
|
||||
{ id: 'zhipu', name: '智谱' },
|
||||
{ id: 'deepseek', name: 'DeepSeek' },
|
||||
{ id: 'qwen', name: '通义千问' },
|
||||
{ id: 'siliconflow', name: '硅基流动' }
|
||||
]
|
||||
const platform = platforms.find(p => p.id === platformId)
|
||||
return platform ? platform.name : platformId
|
||||
}
|
||||
|
||||
// 发送消息
|
||||
// TODO 需要将用户配置(端点、密钥)和用户消息发送给后端统一处理
|
||||
const sendMessage = async () => {
|
||||
if (!canSend.value) return
|
||||
|
||||
@@ -125,6 +126,7 @@ const sendMessage = async () => {
|
||||
throw new Error('未找到厂商配置')
|
||||
}
|
||||
|
||||
// TODO 这里无需解密,应该交由后端解密
|
||||
// 解密密钥
|
||||
const apiKey = decrypt(config.apiKey)
|
||||
|
||||
@@ -142,146 +144,9 @@ const sendMessage = async () => {
|
||||
}
|
||||
|
||||
// 调用AI平台API
|
||||
// TODO 此处由后端统一处理
|
||||
const callAIPlatform = async (platformId, apiKey, endpoint, message) => {
|
||||
// 根据不同平台调用不同的API
|
||||
switch (platformId) {
|
||||
case 'openai':
|
||||
return await callOpenAI(apiKey, endpoint, message)
|
||||
case 'anthropic':
|
||||
return await callAnthropic(apiKey, endpoint, message)
|
||||
case 'google':
|
||||
return await callGoogle(apiKey, endpoint, message)
|
||||
case 'qwen':
|
||||
return await callQwen(apiKey, endpoint, message)
|
||||
case 'wenxin':
|
||||
return await callWenxin(apiKey, endpoint, message)
|
||||
default:
|
||||
throw new Error(`不支持的厂商: ${platformId}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 调用OpenAI API
|
||||
const callOpenAI = async (apiKey, endpoint, message) => {
|
||||
const response = await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${apiKey}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'gpt-3.5-turbo',
|
||||
messages: [{ role: 'user', content: message }],
|
||||
temperature: 0.7
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
throw new Error(`OpenAI API 调用失败 (${response.status}): ${errorData.error?.message || '未知错误'}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.choices[0]?.message?.content || '未获取到响应内容'
|
||||
}
|
||||
|
||||
// 调用Anthropic API
|
||||
const callAnthropic = async (apiKey, endpoint, message) => {
|
||||
const response = await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-api-key': apiKey,
|
||||
'anthropic-version': '2023-06-01'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'claude-3-haiku-20240307',
|
||||
messages: [{ role: 'user', content: message }],
|
||||
max_tokens: 1024
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
throw new Error(`Anthropic API 调用失败 (${response.status}): ${errorData.error?.message || '未知错误'}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.content[0]?.text || '未获取到响应内容'
|
||||
}
|
||||
|
||||
// 调用Google Gemini API
|
||||
const callGoogle = async (apiKey, endpoint, message) => {
|
||||
const response = await fetch(`${endpoint}?key=${apiKey}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
contents: [{
|
||||
parts: [
|
||||
{ text: message }
|
||||
]
|
||||
}]
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
throw new Error(`Google API 调用失败 (${response.status}): ${errorData.error?.message || '未知错误'}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.candidates[0]?.content?.parts[0]?.text || '未获取到响应内容'
|
||||
}
|
||||
|
||||
// 调用通义千问API
|
||||
const callQwen = async (apiKey, endpoint, message) => {
|
||||
const response = await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'X-DashScope-Scene': 'chat'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'qwen-plus',
|
||||
input: {
|
||||
messages: [{ role: 'user', content: message }]
|
||||
},
|
||||
parameters: {
|
||||
result_format: 'message'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
throw new Error(`通义千问 API 调用失败 (${response.status}): ${errorData.error?.message || '未知错误'}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.output?.choices[0]?.message?.content || '未获取到响应内容'
|
||||
}
|
||||
|
||||
// 调用文心一言API
|
||||
const callWenxin = async (apiKey, endpoint, message) => {
|
||||
const response = await fetch(`${endpoint}?access_token=${apiKey}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
messages: [{ role: 'user', content: message }]
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
throw new Error(`文心一言 API 调用失败 (${response.status}): ${errorData.error?.message || '未知错误'}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.result || '未获取到响应内容'
|
||||
// TODO 待完善
|
||||
}
|
||||
|
||||
// 初始化
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<!-- TODO 保存后应该使得 ChatPanel 组件刷新,使得能够选择厂商 -->
|
||||
<div class="form-group">
|
||||
<button @click="saveConfig" :disabled="!canSave" class="save-btn">
|
||||
保存配置
|
||||
@@ -60,7 +61,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { encrypt, decrypt } from '../utils/encryption'
|
||||
import { encrypt } from '../utils/encryption'
|
||||
|
||||
// 厂商配置预设
|
||||
const platforms = [
|
||||
@@ -72,31 +73,31 @@ const platforms = [
|
||||
keyType: 'api_key'
|
||||
},
|
||||
{
|
||||
id: 'anthropic',
|
||||
name: 'Anthropic',
|
||||
endpoint: 'https://api.anthropic.com/v1/messages',
|
||||
id: 'zhipu',
|
||||
name: '智谱',
|
||||
endpoint: 'https://open.bigmodel.cn/api/paas/v4/chat/completions',
|
||||
keyPlaceholder: 'sk-...',
|
||||
keyType: 'api_key'
|
||||
},
|
||||
{
|
||||
id: 'google',
|
||||
name: 'Google (Gemini)',
|
||||
endpoint: 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent',
|
||||
keyPlaceholder: 'AIza...',
|
||||
id: 'deepseek',
|
||||
name: 'DeepSeek',
|
||||
endpoint: 'https://api.deepseek.com/chat/completions',
|
||||
keyPlaceholder: 'sk-...',
|
||||
keyType: 'api_key'
|
||||
},
|
||||
{
|
||||
id: 'qwen',
|
||||
name: '通义千问(阿里云)',
|
||||
endpoint: 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation',
|
||||
name: '通义千问',
|
||||
endpoint: 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions',
|
||||
keyPlaceholder: 'sk-...',
|
||||
keyType: 'api_key'
|
||||
},
|
||||
{
|
||||
id: 'wenxin',
|
||||
name: '文心一言(百度)',
|
||||
endpoint: 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie_bot',
|
||||
keyPlaceholder: 'your_api_key',
|
||||
id: 'siliconflow',
|
||||
name: '硅基流动',
|
||||
endpoint: 'https://api.siliconflow.cn/v1/chat/completions',
|
||||
keyPlaceholder: 'sk-...',
|
||||
keyType: 'api_key'
|
||||
}
|
||||
]
|
||||
@@ -196,14 +197,9 @@ const validateApiKey = () => {
|
||||
if (!platform) return true
|
||||
|
||||
// 根据厂商类型验证密钥格式
|
||||
if (platform.id === 'openai' || platform.id === 'qwen' || platform.id === 'anthropic') {
|
||||
if (!key.startsWith('sk-')) {
|
||||
showValidation('OpenAI/通义千问密钥应以 "sk-" 开头', 'error')
|
||||
return false
|
||||
}
|
||||
} else if (platform.id === 'google') {
|
||||
if (!key.startsWith('AIza')) {
|
||||
showValidation('Google密钥应以 "AIza" 开头', 'error')
|
||||
if (platform.keyType === 'api_key') {
|
||||
if (!key.startsWith('sk-') || key.length < 20) {
|
||||
showValidation('API 密钥格式不正确,应以 "sk-" 开头且长度不少于20位', 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user