mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 21:37:11 +00:00
fix: 添加基于LLM的翻译
This commit is contained in:
parent
e5e85621d9
commit
e1d40ba009
6 changed files with 341 additions and 215 deletions
|
|
@ -1942,7 +1942,8 @@ export class chatgpt extends plugin {
|
||||||
let response = await client.sendMessage(prompt, {
|
let response = await client.sendMessage(prompt, {
|
||||||
e,
|
e,
|
||||||
chatId: conversation?.conversationId,
|
chatId: conversation?.conversationId,
|
||||||
image: image ? image[0] : undefined
|
image: image ? image[0] : undefined,
|
||||||
|
system: Config.xhPrompt
|
||||||
})
|
})
|
||||||
return response
|
return response
|
||||||
} else if (use === 'azure') {
|
} else if (use === 'azure') {
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ export class Entertainment extends plugin {
|
||||||
fnc: 'wordcloud_new'
|
fnc: 'wordcloud_new'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
reg: '^#((寄批踢|gpt|GPT)?翻.*|chatgpt翻译帮助)',
|
reg: '^#((寄批踢|gpt|GPT)?翻[sS]*|chatgpt翻译帮助)',
|
||||||
fnc: 'translate'
|
fnc: 'translate'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
440
guoba.support.js
440
guoba.support.js
|
|
@ -27,184 +27,6 @@ export function supportGuoba () {
|
||||||
configInfo: {
|
configInfo: {
|
||||||
// 配置项 schemas
|
// 配置项 schemas
|
||||||
schemas: [
|
schemas: [
|
||||||
{
|
|
||||||
field: 'blockWords',
|
|
||||||
label: '输出黑名单',
|
|
||||||
bottomHelpMessage: '检查输出结果中是否有违禁词,如果存在黑名单中的违禁词则不输出。英文逗号隔开',
|
|
||||||
component: 'InputTextArea'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'promptBlockWords',
|
|
||||||
label: '输入黑名单',
|
|
||||||
bottomHelpMessage: '检查输入结果中是否有违禁词,如果存在黑名单中的违禁词则不输出。英文逗号隔开',
|
|
||||||
component: 'InputTextArea'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'whitelist',
|
|
||||||
label: '对话白名单',
|
|
||||||
bottomHelpMessage: '默认设置为添加群号。优先级高于黑名单。\n' +
|
|
||||||
'注意:需要添加QQ号时在前面添加^(例如:^123456),此全局添加白名单,即除白名单以外的所有人都不能使用插件对话。\n' +
|
|
||||||
'如果需要在某个群里独享moment,即群聊中只有白名单上的qq号能用,则使用(群号^qq)的格式(例如:123456^123456)。\n' +
|
|
||||||
'白名单优先级:混合制 > qq > 群号。\n' +
|
|
||||||
'黑名单优先级: 群号 > qq > 混合制。',
|
|
||||||
component: 'Input'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'blacklist',
|
|
||||||
label: '对话黑名单',
|
|
||||||
bottomHelpMessage: '参考白名单设置规则。',
|
|
||||||
component: 'Input'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'imgOcr',
|
|
||||||
label: '图片识别',
|
|
||||||
bottomHelpMessage: '是否识别消息中图片的文字内容,需要同时包含图片和消息才生效',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'enablePrivateChat',
|
|
||||||
label: '是否允许私聊机器人',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'defaultUsePicture',
|
|
||||||
label: '全局图片模式',
|
|
||||||
bottomHelpMessage: '全局默认以图片形式回复',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'defaultUseTTS',
|
|
||||||
label: '全局语音模式',
|
|
||||||
bottomHelpMessage: '全局默认以语音形式回复,使用默认角色音色',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'ttsMode',
|
|
||||||
label: '语音模式源',
|
|
||||||
bottomHelpMessage: '语音模式下使用何种语音源进行文本->音频转换',
|
|
||||||
component: 'Select',
|
|
||||||
componentProps: {
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: 'vits-uma-genshin-honkai',
|
|
||||||
value: 'vits-uma-genshin-honkai'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '微软Azure',
|
|
||||||
value: 'azure'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'VoiceVox',
|
|
||||||
value: 'voicevox'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'defaultTTSRole',
|
|
||||||
label: 'vits默认角色',
|
|
||||||
bottomHelpMessage: 'vits-uma-genshin-honkai语音模式下,未指定角色时使用的角色。若留空,将使用随机角色回复。若用户通过指令指定了角色,将忽略本设定',
|
|
||||||
component: 'Select',
|
|
||||||
componentProps: {
|
|
||||||
options: [{
|
|
||||||
label: '随机',
|
|
||||||
value: '随机'
|
|
||||||
}].concat(speakers.map(s => { return { label: s, value: s } }))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'azureTTSSpeaker',
|
|
||||||
label: 'Azure默认角色',
|
|
||||||
bottomHelpMessage: '微软Azure语音模式下,未指定角色时使用的角色。若用户通过指令指定了角色,将忽略本设定',
|
|
||||||
component: 'Select',
|
|
||||||
componentProps: {
|
|
||||||
options: [{
|
|
||||||
label: '随机',
|
|
||||||
value: '随机'
|
|
||||||
},
|
|
||||||
...azureRoleList.flatMap(item => [
|
|
||||||
item.roleInfo
|
|
||||||
]).map(s => ({
|
|
||||||
label: s,
|
|
||||||
value: s
|
|
||||||
}))]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'voicevoxTTSSpeaker',
|
|
||||||
label: 'VoiceVox默认角色',
|
|
||||||
bottomHelpMessage: 'VoiceVox语音模式下,未指定角色时使用的角色。若留空,将使用随机角色回复。若用户通过指令指定了角色,将忽略本设定',
|
|
||||||
component: 'Select',
|
|
||||||
componentProps: {
|
|
||||||
options: [{
|
|
||||||
label: '随机',
|
|
||||||
value: '随机'
|
|
||||||
},
|
|
||||||
...voxRoleList.flatMap(item => [
|
|
||||||
...item.styles.map(style => `${item.name}-${style.name}`),
|
|
||||||
item.name
|
|
||||||
]).map(s => ({
|
|
||||||
label: s,
|
|
||||||
value: s
|
|
||||||
}))]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'ttsRegex',
|
|
||||||
label: '语音过滤正则表达式',
|
|
||||||
bottomHelpMessage: '语音模式下,配置此项以过滤不想被读出来的内容。表达式测试地址:https://www.runoob.com/regexp/regexp-syntax.html',
|
|
||||||
component: 'Input'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'ttsAutoFallbackThreshold',
|
|
||||||
label: '语音转文字阈值',
|
|
||||||
helpMessage: '语音模式下,字数超过这个阈值就降级为文字',
|
|
||||||
bottomHelpMessage: '语音转为文字的阈值',
|
|
||||||
component: 'InputNumber',
|
|
||||||
componentProps: {
|
|
||||||
min: 0,
|
|
||||||
max: 299
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'alsoSendText',
|
|
||||||
label: '语音同时发送文字',
|
|
||||||
bottomHelpMessage: '语音模式下,同时发送文字版,避免音质较低听不懂',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'autoJapanese',
|
|
||||||
label: 'vits模式日语输出',
|
|
||||||
bottomHelpMessage: '使用vits语音时,将机器人的文字回复翻译成日文后获取语音。' +
|
|
||||||
'若想使用插件的翻译功能,发送"#chatgpt翻译帮助"查看使用方法,支持图片翻译,引用翻译...',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'autoUsePicture',
|
|
||||||
label: '长文本自动转图片',
|
|
||||||
bottomHelpMessage: '字数大于阈值会自动用图片发送,即使是文本模式',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'autoUsePictureThreshold',
|
|
||||||
label: '自动转图片阈值',
|
|
||||||
helpMessage: '长文本自动转图片开启后才生效',
|
|
||||||
bottomHelpMessage: '自动转图片的字数阈值',
|
|
||||||
component: 'InputNumber',
|
|
||||||
componentProps: {
|
|
||||||
min: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'conversationPreserveTime',
|
|
||||||
label: '对话保留时长',
|
|
||||||
helpMessage: '单位:秒',
|
|
||||||
bottomHelpMessage: '每个人发起的对话保留时长。超过这个时长没有进行对话,再进行对话将开启新的对话。',
|
|
||||||
component: 'InputNumber',
|
|
||||||
componentProps: {
|
|
||||||
min: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
field: 'toggleMode',
|
field: 'toggleMode',
|
||||||
label: '触发方式',
|
label: '触发方式',
|
||||||
|
|
@ -217,45 +39,12 @@ export function supportGuoba () {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
field: 'groupMerge',
|
|
||||||
label: '群组消息合并',
|
|
||||||
bottomHelpMessage: '开启后,群聊消息将被视为同一对话',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
field: 'allowOtherMode',
|
field: 'allowOtherMode',
|
||||||
label: '允许其他模式',
|
label: '允许其他模式',
|
||||||
bottomHelpMessage: '开启后,则允许用户使用#chat1/#chat3/#chatglm/#bing等命令无视全局模式进行聊天',
|
bottomHelpMessage: '开启后,则允许用户使用#chat1/#chat3/#chatglm/#bing等命令无视全局模式进行聊天',
|
||||||
component: 'Switch'
|
component: 'Switch'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
field: 'quoteReply',
|
|
||||||
label: '图片引用消息',
|
|
||||||
bottomHelpMessage: '在回复图片时引用原始消息',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'showQRCode',
|
|
||||||
label: '启用二维码',
|
|
||||||
bottomHelpMessage: '在图片模式中启用二维码。该对话内容将被发送至第三方服务器以进行渲染展示,如果不希望对话内容被上传到第三方服务器请关闭此功能',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'drawCD',
|
|
||||||
label: '绘图CD',
|
|
||||||
helpMessage: '单位:秒',
|
|
||||||
bottomHelpMessage: '绘图指令的CD时间,主人不受限制',
|
|
||||||
component: 'InputNumber',
|
|
||||||
componentProps: {
|
|
||||||
min: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'enableDraw',
|
|
||||||
label: '绘图功能开关',
|
|
||||||
component: 'Switch'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
field: 'proxy',
|
field: 'proxy',
|
||||||
label: '代理服务器地址',
|
label: '代理服务器地址',
|
||||||
|
|
@ -268,6 +57,20 @@ export function supportGuoba () {
|
||||||
bottomHelpMessage: '将输出更多调试信息,如果不希望控制台刷屏的话,可以关闭',
|
bottomHelpMessage: '将输出更多调试信息,如果不希望控制台刷屏的话,可以关闭',
|
||||||
component: 'Switch'
|
component: 'Switch'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'translateSource',
|
||||||
|
label: '翻译来源',
|
||||||
|
bottomHelpMessage: '#gpt翻译使用的AI来源',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: 'OpenAI', value: 'openai' },
|
||||||
|
{ label: 'Gemini', value: 'gemini' },
|
||||||
|
{ label: '星火', value: 'xh' },
|
||||||
|
{ label: '通义千问', value: 'qwen' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '以下为服务超时配置。',
|
label: '以下为服务超时配置。',
|
||||||
component: 'Divider'
|
component: 'Divider'
|
||||||
|
|
@ -792,6 +595,221 @@ export function supportGuoba () {
|
||||||
bottomHelpMessage: '对https://generativelanguage.googleapis.com的反代',
|
bottomHelpMessage: '对https://generativelanguage.googleapis.com的反代',
|
||||||
component: 'Input'
|
component: 'Input'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '以下为一些杂项配置。',
|
||||||
|
component: 'Divider'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'blockWords',
|
||||||
|
label: '输出黑名单',
|
||||||
|
bottomHelpMessage: '检查输出结果中是否有违禁词,如果存在黑名单中的违禁词则不输出。英文逗号隔开',
|
||||||
|
component: 'InputTextArea'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'promptBlockWords',
|
||||||
|
label: '输入黑名单',
|
||||||
|
bottomHelpMessage: '检查输入结果中是否有违禁词,如果存在黑名单中的违禁词则不输出。英文逗号隔开',
|
||||||
|
component: 'InputTextArea'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'whitelist',
|
||||||
|
label: '对话白名单',
|
||||||
|
bottomHelpMessage: '默认设置为添加群号。优先级高于黑名单。\n' +
|
||||||
|
'注意:需要添加QQ号时在前面添加^(例如:^123456),此全局添加白名单,即除白名单以外的所有人都不能使用插件对话。\n' +
|
||||||
|
'如果需要在某个群里独享moment,即群聊中只有白名单上的qq号能用,则使用(群号^qq)的格式(例如:123456^123456)。\n' +
|
||||||
|
'白名单优先级:混合制 > qq > 群号。\n' +
|
||||||
|
'黑名单优先级: 群号 > qq > 混合制。',
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'blacklist',
|
||||||
|
label: '对话黑名单',
|
||||||
|
bottomHelpMessage: '参考白名单设置规则。',
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'imgOcr',
|
||||||
|
label: '图片识别',
|
||||||
|
bottomHelpMessage: '是否识别消息中图片的文字内容,需要同时包含图片和消息才生效',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'enablePrivateChat',
|
||||||
|
label: '是否允许私聊机器人',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'defaultUsePicture',
|
||||||
|
label: '全局图片模式',
|
||||||
|
bottomHelpMessage: '全局默认以图片形式回复',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'defaultUseTTS',
|
||||||
|
label: '全局语音模式',
|
||||||
|
bottomHelpMessage: '全局默认以语音形式回复,使用默认角色音色',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ttsMode',
|
||||||
|
label: '语音模式源',
|
||||||
|
bottomHelpMessage: '语音模式下使用何种语音源进行文本->音频转换',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'vits-uma-genshin-honkai',
|
||||||
|
value: 'vits-uma-genshin-honkai'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '微软Azure',
|
||||||
|
value: 'azure'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'VoiceVox',
|
||||||
|
value: 'voicevox'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'defaultTTSRole',
|
||||||
|
label: 'vits默认角色',
|
||||||
|
bottomHelpMessage: 'vits-uma-genshin-honkai语音模式下,未指定角色时使用的角色。若留空,将使用随机角色回复。若用户通过指令指定了角色,将忽略本设定',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [{
|
||||||
|
label: '随机',
|
||||||
|
value: '随机'
|
||||||
|
}].concat(speakers.map(s => { return { label: s, value: s } }))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'azureTTSSpeaker',
|
||||||
|
label: 'Azure默认角色',
|
||||||
|
bottomHelpMessage: '微软Azure语音模式下,未指定角色时使用的角色。若用户通过指令指定了角色,将忽略本设定',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [{
|
||||||
|
label: '随机',
|
||||||
|
value: '随机'
|
||||||
|
},
|
||||||
|
...azureRoleList.flatMap(item => [
|
||||||
|
item.roleInfo
|
||||||
|
]).map(s => ({
|
||||||
|
label: s,
|
||||||
|
value: s
|
||||||
|
}))]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'voicevoxTTSSpeaker',
|
||||||
|
label: 'VoiceVox默认角色',
|
||||||
|
bottomHelpMessage: 'VoiceVox语音模式下,未指定角色时使用的角色。若留空,将使用随机角色回复。若用户通过指令指定了角色,将忽略本设定',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [{
|
||||||
|
label: '随机',
|
||||||
|
value: '随机'
|
||||||
|
},
|
||||||
|
...voxRoleList.flatMap(item => [
|
||||||
|
...item.styles.map(style => `${item.name}-${style.name}`),
|
||||||
|
item.name
|
||||||
|
]).map(s => ({
|
||||||
|
label: s,
|
||||||
|
value: s
|
||||||
|
}))]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ttsRegex',
|
||||||
|
label: '语音过滤正则表达式',
|
||||||
|
bottomHelpMessage: '语音模式下,配置此项以过滤不想被读出来的内容。表达式测试地址:https://www.runoob.com/regexp/regexp-syntax.html',
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ttsAutoFallbackThreshold',
|
||||||
|
label: '语音转文字阈值',
|
||||||
|
helpMessage: '语音模式下,字数超过这个阈值就降级为文字',
|
||||||
|
bottomHelpMessage: '语音转为文字的阈值',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
min: 0,
|
||||||
|
max: 299
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'alsoSendText',
|
||||||
|
label: '语音同时发送文字',
|
||||||
|
bottomHelpMessage: '语音模式下,同时发送文字版,避免音质较低听不懂',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'autoJapanese',
|
||||||
|
label: 'vits模式日语输出',
|
||||||
|
bottomHelpMessage: '使用vits语音时,将机器人的文字回复翻译成日文后获取语音。' +
|
||||||
|
'若想使用插件的翻译功能,发送"#chatgpt翻译帮助"查看使用方法,支持图片翻译,引用翻译...',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'autoUsePicture',
|
||||||
|
label: '长文本自动转图片',
|
||||||
|
bottomHelpMessage: '字数大于阈值会自动用图片发送,即使是文本模式',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'autoUsePictureThreshold',
|
||||||
|
label: '自动转图片阈值',
|
||||||
|
helpMessage: '长文本自动转图片开启后才生效',
|
||||||
|
bottomHelpMessage: '自动转图片的字数阈值',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
min: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'conversationPreserveTime',
|
||||||
|
label: '对话保留时长',
|
||||||
|
helpMessage: '单位:秒',
|
||||||
|
bottomHelpMessage: '每个人发起的对话保留时长。超过这个时长没有进行对话,再进行对话将开启新的对话。',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
min: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'groupMerge',
|
||||||
|
label: '群组消息合并',
|
||||||
|
bottomHelpMessage: '开启后,群聊消息将被视为同一对话',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'quoteReply',
|
||||||
|
label: '图片引用消息',
|
||||||
|
bottomHelpMessage: '在回复图片时引用原始消息',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'showQRCode',
|
||||||
|
label: '启用二维码',
|
||||||
|
bottomHelpMessage: '在图片模式中启用二维码。该对话内容将被发送至第三方服务器以进行渲染展示,如果不希望对话内容被上传到第三方服务器请关闭此功能',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'drawCD',
|
||||||
|
label: '绘图CD',
|
||||||
|
helpMessage: '单位:秒',
|
||||||
|
bottomHelpMessage: '绘图指令的CD时间,主人不受限制',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
min: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'enableDraw',
|
||||||
|
label: '绘图功能开关',
|
||||||
|
component: 'Switch'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '以下为Suno音乐合成的配置。',
|
label: '以下为Suno音乐合成的配置。',
|
||||||
component: 'Divider'
|
component: 'Divider'
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,7 @@ const defaultConfig = {
|
||||||
chatglmRefreshToken: '',
|
chatglmRefreshToken: '',
|
||||||
sunoSessToken: '',
|
sunoSessToken: '',
|
||||||
sunoClientToken: '',
|
sunoClientToken: '',
|
||||||
|
translateSource: 'openai',
|
||||||
version: 'v2.7.10'
|
version: 'v2.7.10'
|
||||||
}
|
}
|
||||||
const _path = process.cwd()
|
const _path = process.cwd()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
import md5 from 'md5'
|
import md5 from 'md5'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import { Config } from './config.js'
|
||||||
|
import { ChatGPTAPI } from './openai/chatgpt-api.js'
|
||||||
|
import { newFetch } from './proxy.js'
|
||||||
|
import { CustomGoogleGeminiClient } from '../client/CustomGoogleGeminiClient.js'
|
||||||
|
import XinghuoClient from './xinghuo/xinghuo.js'
|
||||||
|
import {getImg, getMessageById, upsertMessage} from './common.js'
|
||||||
|
import {QwenApi} from "./alibaba/qwen-api.js";
|
||||||
|
import {v4 as uuid} from "uuid";
|
||||||
|
|
||||||
// 代码参考:https://github.com/yeyang52/yenai-plugin/blob/b50b11338adfa5a4ef93912eefd2f1f704e8b990/model/api/funApi.js#L25
|
// 代码参考:https://github.com/yeyang52/yenai-plugin/blob/b50b11338adfa5a4ef93912eefd2f1f704e8b990/model/api/funApi.js#L25
|
||||||
export const translateLangSupports = [
|
export const translateLangSupports = [
|
||||||
|
|
@ -20,7 +28,7 @@ export const translateLangSupports = [
|
||||||
{ code: 'zh-CHS', label: '中文', abbr: '中', alphabet: 'Z' }
|
{ code: 'zh-CHS', label: '中文', abbr: '中', alphabet: 'Z' }
|
||||||
]
|
]
|
||||||
const API_ERROR = '出了点小问题,待会再试试吧'
|
const API_ERROR = '出了点小问题,待会再试试吧'
|
||||||
export async function translate (msg, to = 'auto') {
|
export async function translateOld (msg, to = 'auto') {
|
||||||
let from = 'auto'
|
let from = 'auto'
|
||||||
if (to !== 'auto') to = translateLangSupports.find(item => item.abbr == to)?.code
|
if (to !== 'auto') to = translateLangSupports.find(item => item.abbr == to)?.code
|
||||||
if (!to) return `未找到翻译的语种,支持的语言为:\n${translateLangSupports.map(item => item.abbr).join(',')}\n`
|
if (!to) return `未找到翻译的语种,支持的语言为:\n${translateLangSupports.map(item => item.abbr).join(',')}\n`
|
||||||
|
|
@ -95,3 +103,101 @@ export async function translate (msg, to = 'auto') {
|
||||||
return API_ERROR
|
return API_ERROR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param msg 要翻译的
|
||||||
|
* @param from 语种
|
||||||
|
* @param to 语种
|
||||||
|
* @param ai ai来源,支持openai, gemini, xh, qwen
|
||||||
|
* @returns {Promise<*|string>}
|
||||||
|
*/
|
||||||
|
export async function translate (msg, to = '中', from = 'auto', ai = Config.translateSource) {
|
||||||
|
try {
|
||||||
|
const lang = translateLangSupports.find(item => item.abbr == to)?.code
|
||||||
|
if (!lang) return `未找到翻译的语种,支持的语言为:\n${translateLangSupports.map(item => item.abbr).join(',')}\n`
|
||||||
|
// if ai is not in the list, throw error
|
||||||
|
if (!['openai', 'gemini', 'xh', 'qwen'].includes(ai)) throw new Error('ai来源错误')
|
||||||
|
let system = `You will be provided with a sentence in the language with language code [${from}], and your task is to translate it into [${lang}]. Just print the result without any other words.`
|
||||||
|
switch (ai) {
|
||||||
|
case 'openai': {
|
||||||
|
let api = new ChatGPTAPI({
|
||||||
|
apiBaseUrl: Config.openAiBaseUrl,
|
||||||
|
apiKey: Config.apiKey,
|
||||||
|
fetch: newFetch
|
||||||
|
})
|
||||||
|
const res = await api.sendMessage(msg, {
|
||||||
|
systemMessage: system,
|
||||||
|
completionParams: {
|
||||||
|
model: 'gpt-3.5-turbo'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return res.text
|
||||||
|
}
|
||||||
|
case 'gemini': {
|
||||||
|
let client = new CustomGoogleGeminiClient({
|
||||||
|
key: Config.geminiKey,
|
||||||
|
model: Config.geminiModel,
|
||||||
|
baseUrl: Config.geminiBaseUrl,
|
||||||
|
debug: Config.debug
|
||||||
|
})
|
||||||
|
let option = {
|
||||||
|
stream: false,
|
||||||
|
onProgress: (data) => {
|
||||||
|
if (Config.debug) {
|
||||||
|
logger.info(data)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
system
|
||||||
|
}
|
||||||
|
let res = await client.sendMessage(msg, option)
|
||||||
|
return res.text
|
||||||
|
}
|
||||||
|
case 'xh': {
|
||||||
|
let client = new XinghuoClient({
|
||||||
|
ssoSessionId: Config.xinghuoToken
|
||||||
|
})
|
||||||
|
let response = await client.sendMessage(msg, { system })
|
||||||
|
return response.text
|
||||||
|
}
|
||||||
|
case 'qwen': {
|
||||||
|
let completionParams = {
|
||||||
|
parameters: {
|
||||||
|
top_p: Config.qwenTopP || 0.5,
|
||||||
|
top_k: Config.qwenTopK || 50,
|
||||||
|
seed: Config.qwenSeed > 0 ? Config.qwenSeed : Math.floor(Math.random() * 114514),
|
||||||
|
temperature: Config.qwenTemperature || 1,
|
||||||
|
enable_search: !!Config.qwenEnableSearch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Config.qwenModel) {
|
||||||
|
completionParams.model = Config.qwenModel
|
||||||
|
}
|
||||||
|
let opts = {
|
||||||
|
apiKey: Config.qwenApiKey,
|
||||||
|
debug: false,
|
||||||
|
systemMessage: system,
|
||||||
|
completionParams,
|
||||||
|
fetch: newFetch
|
||||||
|
}
|
||||||
|
let client = new QwenApi(opts)
|
||||||
|
let option = {
|
||||||
|
timeoutMs: 600000,
|
||||||
|
completionParams
|
||||||
|
}
|
||||||
|
let result
|
||||||
|
try {
|
||||||
|
result = await client.sendMessage(msg, option)
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(err)
|
||||||
|
throw new Error(err)
|
||||||
|
}
|
||||||
|
return result.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(e)
|
||||||
|
logger.info('基于LLM的翻译失败,转用老版翻译')
|
||||||
|
return await translateOld(msg, to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,7 @@ export default class XinghuoClient {
|
||||||
logger.warn('星火设定序列化失败,本次对话不附带设定')
|
logger.warn('星火设定序列化失败,本次对话不附带设定')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Prompt = Config.xhPrompt ? [{ role: 'system', content: Config.xhPrompt }] : []
|
Prompt = option.system ? [{ role: 'system', content: option.system }] : []
|
||||||
}
|
}
|
||||||
if (Config.xhPromptEval) {
|
if (Config.xhPromptEval) {
|
||||||
Prompt.forEach(obj => {
|
Prompt.forEach(obj => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue