fix: 修复喵崽多适配器工具箱登录;移除crypto依赖

This commit is contained in:
ikechan8370 2023-11-21 16:31:29 +08:00
parent 2b19302b87
commit 46d88c2669
5 changed files with 216 additions and 255 deletions

View file

@ -820,6 +820,7 @@ export async function getImageOcrText (e) {
// logger.warn('resultArr', resultArr)
return resultArr
} catch (err) {
logger.warn('OCR失败可能使用的适配器不支持OCR')
return false
// logger.error(err)
}

View file

@ -144,7 +144,7 @@ const defaultConfig = {
serpSource: 'ikechan8370',
extraUrl: 'https://cpe.ikechan8370.com',
smartMode: false,
bingCaptchaOneShotUrl: 'http://bingcaptcha.ikechan8370.com/bing',
bingCaptchaOneShotUrl: '',
// claude2
claudeAIOrganizationId: '',
claudeAISessionKey: '',

View file

@ -3,6 +3,7 @@ import { Config } from '../config.js'
import { createParser } from 'eventsource-parser'
import https from 'https'
import WebSocket from 'ws'
import { createHmac } from 'crypto'
const referer = atob('aHR0cHM6Ly94aW5naHVvLnhmeXVuLmNuL2NoYXQ/aWQ9')
const origin = atob('aHR0cHM6Ly94aW5naHVvLnhmeXVuLmNu')
@ -14,13 +15,7 @@ try {
} catch (err) {
logger.warn('未安装form-data无法使用星火模式')
}
let crypto
try {
crypto = (await import('crypto')).default
} catch (err) {
logger.warn('未安装crypto无法使用星火api模式')
}
async function getKeyv() {
async function getKeyv () {
let Keyv
try {
Keyv = (await import('keyv')).default
@ -30,7 +25,7 @@ async function getKeyv() {
return Keyv
}
export default class XinghuoClient {
constructor(opts) {
constructor (opts) {
this.cache = opts.cache
this.ssoSessionId = opts.ssoSessionId
this.headers = {
@ -41,7 +36,7 @@ export default class XinghuoClient {
}
}
apiErrorInfo(code) {
apiErrorInfo (code) {
switch (code) {
case 10000: return '升级为ws出现错误'
case 10001: return '通过ws读取用户的消息出错'
@ -74,7 +69,7 @@ export default class XinghuoClient {
}
}
async initCache() {
async initCache () {
if (!this.conversationsCache) {
const cacheOptions = this.cache || {}
cacheOptions.namespace = cacheOptions.namespace || 'xh'
@ -83,38 +78,37 @@ export default class XinghuoClient {
}
}
async getWsUrl() {
if (!crypto) return false
async getWsUrl () {
const APISecret = Config.xhAPISecret
const APIKey = Config.xhAPIKey
let APILink = '/v1.1/chat'
if (Config.xhmode == 'apiv2') {
if (Config.xhmode === 'apiv2') {
APILink = '/v2.1/chat'
} else if (Config.xhmode == 'apiv3') {
} else if (Config.xhmode === 'apiv3') {
APILink = '/v3.1/chat'
}
const date = new Date().toGMTString()
const algorithm = 'hmac-sha256'
const headers = 'host date request-line'
const signatureOrigin = `host: spark-api.xf-yun.com\ndate: ${date}\nGET ${APILink} HTTP/1.1`
const hmac = crypto.createHmac('sha256', APISecret)
const hmac = createHmac('sha256', APISecret)
hmac.update(signatureOrigin)
const signature = hmac.digest('base64')
const authorizationOrigin = `api_key="${APIKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
const authorization = Buffer.from(authorizationOrigin).toString('base64')
const v = {
authorization: authorization,
date: date,
host: "spark-api.xf-yun.com"
authorization,
date,
host: 'spark-api.xf-yun.com'
}
const url = `wss://spark-api.xf-yun.com${APILink}?${Object.keys(v).map(key => `${key}=${v[key]}`).join('&')}`
return url
}
async uploadImage(url) {
async uploadImage (url) {
// 获取图片
let response = await fetch(url, {
method: 'GET',
method: 'GET'
})
const blob = await response.blob()
const arrayBuffer = await blob.arrayBuffer()
@ -125,7 +119,7 @@ export default class XinghuoClient {
const respOss = await fetch('https://xinghuo.xfyun.cn/iflygpt/oss/sign', {
method: 'POST',
headers: {
Cookie: 'ssoSessionId=' + this.ssoSessionId + ';',
Cookie: 'ssoSessionId=' + this.ssoSessionId + ';'
},
body: formData
})
@ -167,7 +161,7 @@ export default class XinghuoClient {
}
}
async apiMessage(prompt, chatId, ePrompt = []) {
async apiMessage (prompt, chatId, ePrompt = []) {
if (!chatId) chatId = (Math.floor(Math.random() * 1000000) + 100000).toString()
// 初始化缓存
@ -180,12 +174,9 @@ export default class XinghuoClient {
// 获取ws链接
const wsUrl = Config.xhmode == 'assistants' ? Config.xhAssistants : await this.getWsUrl()
if (!wsUrl) throw new Error('缺少依赖crypto。请安装依赖后重试')
if (!wsUrl) throw new Error('获取ws链接失败')
let domain = 'general'
if (Config.xhmode == 'apiv2')
domain = "generalv2"
else if (Config.xhmode == 'apiv3')
domain = "generalv3"
if (Config.xhmode == 'apiv2') { domain = 'generalv2' } else if (Config.xhmode == 'apiv3') { domain = 'generalv3' }
// 编写消息内容
const wsSendData = {
header: {
@ -194,7 +185,7 @@ export default class XinghuoClient {
},
parameter: {
chat: {
domain: domain,
domain,
temperature: Config.xhTemperature, // 核采样阈值
max_tokens: Config.xhMaxTokens, // tokens最大长度
chat_id: chatId,
@ -203,10 +194,10 @@ export default class XinghuoClient {
},
payload: {
message: {
"text": [
text: [
...ePrompt,
...conversation.messages,
{ "role": "user", "content": prompt }
{ role: 'user', content: prompt }
]
}
}
@ -229,8 +220,8 @@ export default class XinghuoClient {
const half = Math.floor(conversation.messages.length / 2)
conversation.messages.splice(0, half)
await this.conversationsCache.set(conversationKey, conversation)
resolve({
id: (Math.floor(Math.random() * 1000000) + 100000).toString() ,
resolve({
id: (Math.floor(Math.random() * 1000000) + 100000).toString(),
response: '对话以达到上限,已自动清理对话,请重试'
})
} else {
@ -256,8 +247,8 @@ export default class XinghuoClient {
conversation.messages.splice(0, half)
}
await this.conversationsCache.set(conversationKey, conversation)
resolve({
id: chatId ,
resolve({
id: chatId,
response: resMessage
})
}
@ -271,7 +262,7 @@ export default class XinghuoClient {
})
}
async webMessage(prompt, chatId, botId) {
async webMessage (prompt, chatId, botId) {
if (!FormData) {
throw new Error('缺少依赖form-data。请安装依赖后重试')
}
@ -281,7 +272,7 @@ export default class XinghuoClient {
formData.append('clientType', '2')
formData.append('chatId', chatId)
if (prompt.image) {
prompt.text = prompt.text.replace("[图片]", "") // 清理消息中中首个被使用的图片
prompt.text = prompt.text.replace('[图片]', '') // 清理消息中中首个被使用的图片
const imgdata = await this.uploadImage(prompt.image)
if (imgdata) {
formData.append('fileUrl', imgdata.url)
@ -313,7 +304,7 @@ export default class XinghuoClient {
logger.error('星火statusCode' + statusCode)
}
let response = ''
function onMessage(data) {
function onMessage (data) {
// console.log(data)
if (data === '<end>') {
return resolve({
@ -380,7 +371,7 @@ export default class XinghuoClient {
})
}
async sendMessage(prompt, option) {
async sendMessage (prompt, option) {
let chatId = option?.chatId
let image = option?.image
@ -396,9 +387,9 @@ export default class XinghuoClient {
logger.warn('星火设定序列化失败,本次对话不附带设定')
}
} else {
Prompt = Config.xhPrompt ? [{ "role": "user", "content": Config.xhPrompt }] : []
Prompt = Config.xhPrompt ? [{ role: 'user', content: Config.xhPrompt }] : []
}
if(Config.xhPromptEval) {
if (Config.xhPromptEval) {
Prompt.forEach(obj => {
try {
obj.content = obj.content.replace(/{{(.*?)}}/g, (match, variable) => {
@ -427,7 +418,7 @@ export default class XinghuoClient {
if (!chatId) {
chatId = (await this.createChatList()).chatListId
}
let { response } = await this.webMessage({ text: prompt, image: image }, chatId, botId)
let { response } = await this.webMessage({ text: prompt, image }, chatId, botId)
// logger.info(response)
// let responseText = atob(response)
// 处理图片
@ -451,14 +442,14 @@ export default class XinghuoClient {
return {
conversationId: chatId,
text: response,
images: images
images
}
} else {
throw new Error('星火模式错误')
}
}
async createChatList(bot = false) {
async createChatList (bot = false) {
let createChatListRes = await fetch(createChatUrl, {
method: 'POST',
headers: Object.assign(this.headers, {
@ -487,6 +478,6 @@ export default class XinghuoClient {
}
}
function atob(s) {
function atob (s) {
return Buffer.from(s, 'base64').toString()
}