能否加入 Azure OpenAI 的相关支持 #471 (#536)

* 能否加入 Azure OpenAI 的相关支持 #471

* Azure OpenAI 锅巴配置

* 增加Azure OpenAI依赖

* 动态加载Azure OpenAI依赖

---------

Co-authored-by: sigeisment <zvdfka@gmail.com>
Co-authored-by: ikechan8370 <geyinchibuaa@gmail.com>
This commit is contained in:
sigeisment 2023-08-24 22:35:29 +08:00 committed by GitHub
parent c2c6ea43de
commit 502cc810bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 0 deletions

View file

@ -69,6 +69,12 @@ import { SendMessageToSpecificGroupOrUserTool } from '../utils/tools/SendMessage
import { SetTitleTool } from '../utils/tools/SetTitleTool.js' import { SetTitleTool } from '../utils/tools/SetTitleTool.js'
import { createCaptcha, solveCaptcha, solveCaptchaOneShot } from '../utils/bingCaptcha.js' import { createCaptcha, solveCaptcha, solveCaptchaOneShot } from '../utils/bingCaptcha.js'
try {
await import('@azure/openai')
} catch (err) {
logger.warn('【Azure-Openai】依赖@azure/openai未安装Azure OpenAI不可用 请执行pnpm install @azure/openai安装')
}
try { try {
await import('emoji-strip') await import('emoji-strip')
} catch (err) { } catch (err) {
@ -1034,6 +1040,10 @@ export class chatgpt extends plugin {
key = `CHATGPT:CONVERSATIONS_BARD:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}` key = `CHATGPT:CONVERSATIONS_BARD:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`
break break
} }
case 'azure': {
key = `CHATGPT:CONVERSATIONS_AZURE:${e.sender.user_id}`
break
}
} }
let ctime = new Date() let ctime = new Date()
previousConversation = (key ? await redis.get(key) : null) || JSON.stringify({ previousConversation = (key ? await redis.get(key) : null) || JSON.stringify({
@ -1041,6 +1051,7 @@ export class chatgpt extends plugin {
ctime, ctime,
utime: ctime, utime: ctime,
num: 0, num: 0,
messages: [{ role: 'system', content: 'You are an AI assistant that helps people find information.' }],
conversation: {} conversation: {}
}) })
previousConversation = JSON.parse(previousConversation) previousConversation = JSON.parse(previousConversation)
@ -1048,6 +1059,7 @@ export class chatgpt extends plugin {
logger.info({ previousConversation }) logger.info({ previousConversation })
} }
conversation = { conversation = {
messages: previousConversation.messages,
conversationId: previousConversation.conversation?.conversationId, conversationId: previousConversation.conversation?.conversationId,
parentMessageId: previousConversation.parentMessageId, parentMessageId: previousConversation.parentMessageId,
clientId: previousConversation.clientId, clientId: previousConversation.clientId,
@ -1093,6 +1105,11 @@ export class chatgpt extends plugin {
} }
} else if (chatMessage.id) { } else if (chatMessage.id) {
previousConversation.parentMessageId = chatMessage.id previousConversation.parentMessageId = chatMessage.id
} else if (chatMessage.message) {
if (previousConversation.messages.length > 10) {
previousConversation.messages.shift()
}
previousConversation.messages.push(chatMessage.message)
} }
if (use === 'bard' && !chatMessage.error) { if (use === 'bard' && !chatMessage.error) {
previousConversation.parentMessageId = chatMessage.responseID previousConversation.parentMessageId = chatMessage.responseID
@ -1901,6 +1918,23 @@ export class chatgpt extends plugin {
let response = await client.sendMessage(prompt, conversation?.conversationId, image ? image[0] : undefined) let response = await client.sendMessage(prompt, conversation?.conversationId, image ? image[0] : undefined)
return response return response
} }
case 'azure': {
let azureModel
try {
azureModel = await import('@azure/openai')
} catch (error) {
throw new Error('未安装@azure/openai包请执行pnpm install @azure/openai安装')
}
let OpenAIClient = azureModel.OpenAIClient
let AzureKeyCredential = azureModel.AzureKeyCredential
let msg = conversation.messages
let content = { role: 'user', content: prompt }
msg.push(content)
const client = new OpenAIClient(Config.azureUrl, new AzureKeyCredential(Config.apiKey))
const deploymentName = Config.azureDeploymentName
const { choices } = await client.getChatCompletions(deploymentName, msg)
let completion = choices[0].message;
return {'text' : completion.content, 'message': completion}
case 'bard': { case 'bard': {
// 处理cookie // 处理cookie
const matchesPSID = /__Secure-1PSID=([^;]+)/.exec(Config.bardPsid) const matchesPSID = /__Secure-1PSID=([^;]+)/.exec(Config.bardPsid)

View file

@ -108,6 +108,11 @@ export class ChatgptManagement extends plugin {
fnc: 'useXinghuoBasedSolution', fnc: 'useXinghuoBasedSolution',
permission: 'master' permission: 'master'
}, },
{
reg: '^#chatgpt切换azure$',
fnc: 'useAzureBasedSolution',
permission: 'master'
},
{ {
reg: '^#chatgpt切换(Bard|bard)$', reg: '^#chatgpt切换(Bard|bard)$',
fnc: 'useBardBasedSolution', fnc: 'useBardBasedSolution',
@ -838,6 +843,15 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
await this.reply('当前已经是星火模式了') await this.reply('当前已经是星火模式了')
} }
} }
async useAzureBasedSolution () {
let use = await redis.get('CHATGPT:USE')
if (use !== 'azure') {
await redis.set('CHATGPT:USE', 'azure')
await this.reply('已切换到基于Azure的解决方案')
} else {
await this.reply('当前已经是Azure模式了')
}
}
async useBardBasedSolution () { async useBardBasedSolution () {
let use = await redis.get('CHATGPT:USE') let use = await redis.get('CHATGPT:USE')
@ -894,6 +908,7 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
let mode = await redis.get('CHATGPT:USE') let mode = await redis.get('CHATGPT:USE')
const modeMap = { const modeMap = {
browser: '浏览器', browser: '浏览器',
azure: 'Azure',
// apiReverse: 'API2', // apiReverse: 'API2',
api: 'API', api: 'API',
bing: '必应', bing: '必应',

View file

@ -19,6 +19,8 @@
"openAiBaseUrl": "https://mondstadt.d201.eu.org/v1", "openAiBaseUrl": "https://mondstadt.d201.eu.org/v1",
"OpenAiPlatformRefreshToken": "", "OpenAiPlatformRefreshToken": "",
"openAiForceUseReverse": false, "openAiForceUseReverse": false,
"azureDeploymentName":"",
"azureUrl":"",
"drawCD": 30, "drawCD": 30,
"model": "", "model": "",
"temperature": 0.8, "temperature": 0.8,

View file

@ -849,6 +849,28 @@ export function supportGuoba () {
label: '合成emoji的API地址默认谷歌厨房', label: '合成emoji的API地址默认谷歌厨房',
component: 'Input' component: 'Input'
}, },
{
label: '以下为Azure chatGPT的配置',
component: 'Divider'
},
{
field: 'apiKey',
label: 'Azure API Key',
bottomHelpMessage: '管理密钥用于访问Azure的API接口',
component: 'InputPassword'
},
{
field: 'azureUrl',
label: '端点地址',
bottomHelpMessage: 'https://xxxx.openai.azure.com/',
component: 'Input'
},
{
field: 'azureDeploymentName',
label: '部署名称',
bottomHelpMessage: '创建部署时输入的名称',
component: 'Input'
},
{ {
label: '以下为后台与渲染相关配置', label: '以下为后台与渲染相关配置',
component: 'Divider' component: 'Divider'

View file

@ -3,6 +3,7 @@
"type": "module", "type": "module",
"author": "ikechan8370", "author": "ikechan8370",
"dependencies": { "dependencies": {
"@azure/openai": "^1.0.0-beta.1",
"@fastify/cookie": "^8.3.0", "@fastify/cookie": "^8.3.0",
"@fastify/cors": "^8.2.0", "@fastify/cors": "^8.2.0",
"@fastify/static": "^6.9.0", "@fastify/static": "^6.9.0",

View file

@ -717,6 +717,7 @@ export async function getUserData (user) {
chat: [], chat: [],
mode: '', mode: '',
cast: { cast: {
azure: '',
api: '', // API设定 api: '', // API设定
bing: '', // 必应设定 bing: '', // 必应设定
bing_resource: '', // 必应扩展资料 bing_resource: '', // 必应扩展资料