Merge branch 'ikechan8370:v2' into v2

This commit is contained in:
ifeif 2024-02-19 22:49:43 +08:00 committed by GitHub
commit d8454fe806
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 657 additions and 320 deletions

View file

@ -134,6 +134,7 @@ const newFetch = (url, options = {}) => {
export class chatgpt extends plugin { export class chatgpt extends plugin {
constructor () { constructor () {
let toggleMode = Config.toggleMode let toggleMode = Config.toggleMode
let apiStream = Config.apiStream
super({ super({
/** 功能名称 */ /** 功能名称 */
name: 'ChatGpt 对话', name: 'ChatGpt 对话',
@ -291,6 +292,7 @@ export class chatgpt extends plugin {
] ]
}) })
this.toggleMode = toggleMode this.toggleMode = toggleMode
this.apiStream = apiStream
} }
/** /**
@ -365,7 +367,7 @@ export class chatgpt extends plugin {
if (use === 'api3') { if (use === 'api3') {
await redis.del(`CHATGPT:QQ_CONVERSATION:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`) await redis.del(`CHATGPT:QQ_CONVERSATION:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`)
await this.reply('已退出当前对话,该对话仍然保留。请@我进行聊天以开启新的对话', true) await this.reply('已退出当前对话,该对话仍然保留。请@我进行聊天以开启新的对话', true)
} else if (use === 'bing' && (Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom')) { } else if (use === 'bing') {
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`) let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`)
if (!c) { if (!c) {
await this.reply('当前没有开启对话', true) await this.reply('当前没有开启对话', true)
@ -458,7 +460,7 @@ export class chatgpt extends plugin {
if (use === 'api3') { if (use === 'api3') {
await redis.del(`CHATGPT:QQ_CONVERSATION:${qq}`) await redis.del(`CHATGPT:QQ_CONVERSATION:${qq}`)
await this.reply(`${atUser}已退出TA当前的对话TA仍可以@我进行聊天以开启新的对话`, true) await this.reply(`${atUser}已退出TA当前的对话TA仍可以@我进行聊天以开启新的对话`, true)
} else if (use === 'bing' && (Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom')) { } else if (use === 'bing') {
const conversation = { const conversation = {
store: new KeyvFile({ filename: 'cache.json' }), store: new KeyvFile({ filename: 'cache.json' }),
namespace: Config.toneStyle namespace: Config.toneStyle
@ -1214,11 +1216,7 @@ export class chatgpt extends plugin {
previousConversation.invocationId = chatMessage.invocationId previousConversation.invocationId = chatMessage.invocationId
previousConversation.parentMessageId = chatMessage.parentMessageId previousConversation.parentMessageId = chatMessage.parentMessageId
previousConversation.conversationSignature = chatMessage.conversationSignature previousConversation.conversationSignature = chatMessage.conversationSignature
if (Config.toneStyle !== 'Sydney' && Config.toneStyle !== 'Custom') { previousConversation.bingToken = ''
previousConversation.bingToken = chatMessage.bingToken
} else {
previousConversation.bingToken = ''
}
} else if (chatMessage.id) { } else if (chatMessage.id) {
previousConversation.parentMessageId = chatMessage.id previousConversation.parentMessageId = chatMessage.id
} else if (chatMessage.message) { } else if (chatMessage.message) {
@ -1580,7 +1578,7 @@ export class chatgpt extends plugin {
opt.toneStyle = Config.toneStyle opt.toneStyle = Config.toneStyle
// 如果当前没有开启对话或者当前是Sydney模式、Custom模式则本次对话携带拓展资料 // 如果当前没有开启对话或者当前是Sydney模式、Custom模式则本次对话携带拓展资料
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${e.sender.user_id}`) let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${e.sender.user_id}`)
if (!c || Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom') { if (!c) {
opt.context = useCast?.bing_resource || Config.sydneyContext opt.context = useCast?.bing_resource || Config.sydneyContext
} }
// 重新拿存储的token因为可能之前有过期的被删了 // 重新拿存储的token因为可能之前有过期的被删了
@ -2265,7 +2263,7 @@ export class chatgpt extends plugin {
let option = { let option = {
timeoutMs: 600000, timeoutMs: 600000,
completionParams, completionParams,
stream: true, stream: this.apiStream,
onProgress: (data) => { onProgress: (data) => {
if (Config.debug) { if (Config.debug) {
logger.info(data?.text || data.functionCall || data) logger.info(data?.text || data.functionCall || data)
@ -2816,12 +2814,6 @@ async function getAvailableBingToken (conversation, throttled = []) {
allThrottled allThrottled
} }
} }
if (Config.toneStyle != 'Sydney' && Config.toneStyle != 'Custom') {
// bing 下需要保证同一对话使用同一账号的token
if (bingTokens.findIndex(element => element.Token === conversation.bingToken) > -1) {
bingToken = conversation.bingToken
}
}
// 记录使用情况 // 记录使用情况
const index = bingTokens.findIndex(element => element.Token === bingToken) const index = bingTokens.findIndex(element => element.Token === bingToken)
bingTokens[index].Usage += 1 bingTokens[index].Usage += 1

View file

@ -4,6 +4,7 @@ import { makeForwardMsg } from '../utils/common.js'
import _ from 'lodash' import _ from 'lodash'
import { Config } from '../utils/config.js' import { Config } from '../utils/config.js'
import BingDrawClient from '../utils/BingDraw.js' import BingDrawClient from '../utils/BingDraw.js'
import fetch from 'node-fetch'
export class dalle extends plugin { export class dalle extends plugin {
constructor (e) { constructor (e) {
@ -32,11 +33,67 @@ export class dalle extends plugin {
{ {
reg: '^#bing(画图|绘图)', reg: '^#bing(画图|绘图)',
fnc: 'bingDraw' fnc: 'bingDraw'
},
{
reg: '^#dalle3(画图|绘图)',
fnc: 'dalle3'
} }
] ]
}) })
} }
// dalle3
async dalle3 (e) {
if (!Config.enableDraw) {
this.reply('画图功能未开启')
return false
}
let ttl = await redis.ttl(`CHATGPT:DALLE3:${e.sender.user_id}`)
if (ttl > 0 && !e.isMaster) {
this.reply(`冷却中,请${ttl}秒后再试`)
return false
}
let prompt = e.msg.replace(/^#?dalle3(画图|绘图)/, '').trim()
console.log('draw方法被调用消息内容', prompt)
await redis.set(`CHATGPT:DALLE3:${e.sender.user_id}`, 'c', { EX: 30 })
await this.reply('正在为您绘制大小为1024x1024的1张图片预计消耗0.24美元余额,请稍候……')
try {
const response = await fetch(`${Config.openAiBaseUrl}/images/generations`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${Config.apiKey}`
},
body: JSON.stringify({
model: 'dall-e-3',
prompt,
n: 1,
size: '1024x1024',
response_format: 'b64_json'
})
})
// 如果需要,可以解析响应体
const dataJson = await response.json()
console.log(dataJson)
if (dataJson.error) {
e.reply(`画图失败:${dataJson.error?.code}${dataJson.error?.message}`)
await redis.del(`CHATGPT:DALLE3:${e.sender.user_id}`)
return
}
if (dataJson.data[0].b64_json) {
e.reply(`描述:${dataJson.data[0].revised_prompt}`)
e.reply(segment.image(`base64://${dataJson.data[0].b64_json}`))
} else if (dataJson.data[0].url) {
e.reply(`哈哈哈,图来了~\n防止图💥,附上链接:\n${dataJson.data[0].url}`)
e.reply(segment.image(dataJson.data[0].url))
}
} catch (err) {
logger.error(err)
this.reply(`画图失败: ${err}`, true)
await redis.del(`CHATGPT:DALLE3:${e.sender.user_id}`)
}
}
async draw (e) { async draw (e) {
if (!Config.enableDraw) { if (!Config.enableDraw) {
this.reply('画图功能未开启') this.reply('画图功能未开启')
@ -215,7 +272,7 @@ export class dalle extends plugin {
} }
try { try {
let images = (await editImage(imgUrl, position.split(',').map(p => parseInt(p, 10)), prompt, num, size)) let images = (await editImage(imgUrl, position.split(',').map(p => parseInt(p, 10)), prompt, num, size))
.map(image => segment.image(`base64://${image}`)) .map(image => segment.image(`base64://${image}`))
if (images.length > 1) { if (images.length > 1) {
this.reply(await makeForwardMsg(e, images, prompt)) this.reply(await makeForwardMsg(e, images, prompt))
} else { } else {

View file

@ -148,7 +148,7 @@ let helpData = [
}, },
{ {
icon: 'confirm', icon: 'confirm',
title: '#chatgpt必应切换(精准|均衡|创意|悉尼|自设定)', title: '#chatgpt必应切换(精准|创意)',
desc: '切换Bing风格。' desc: '切换Bing风格。'
}, },
{ {

View file

@ -49,42 +49,38 @@ export class history extends plugin {
return true return true
} }
case 'bing': { case 'bing': {
if (Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom') { const cacheOptions = {
const cacheOptions = { namespace: Config.toneStyle,
namespace: Config.toneStyle, store: new KeyvFile({ filename: 'cache.json' })
store: new KeyvFile({ filename: 'cache.json' }) }
} let Keyv = await getKeyv()
let Keyv = await getKeyv() let conversationsCache = new Keyv(cacheOptions)
let conversationsCache = new Keyv(cacheOptions) const conversation = (await conversationsCache.get(`SydneyUser_${queryUser}`)) || {
const conversation = (await conversationsCache.get(`SydneyUser_${queryUser}`)) || { messages: [],
messages: [], createdAt: Date.now()
createdAt: Date.now() }
} let key = `CHATGPT:CONVERSATIONS_BING:${queryUser}`
let key = `CHATGPT:CONVERSATIONS_BING:${queryUser}` let previousConversation = await redis.get(key) || JSON.stringify({})
let previousConversation = await redis.get(key) || JSON.stringify({}) previousConversation = JSON.parse(previousConversation)
previousConversation = JSON.parse(previousConversation) let parentMessageId = previousConversation.parentMessageId
let parentMessageId = previousConversation.parentMessageId let tmp = {}
let tmp = {} const previousCachedMessages = getMessagesForConversation(conversation.messages, parentMessageId)
const previousCachedMessages = getMessagesForConversation(conversation.messages, parentMessageId) .map((message) => {
.map((message) => { return {
return { text: message.message,
text: message.message, author: message.role === 'User' ? 'user' : 'bot'
author: message.role === 'User' ? 'user' : 'bot'
}
})
previousCachedMessages.forEach(m => {
if (m.author === 'user') {
tmp.prompt = m.text
} else {
tmp.response = m.text
chat.push(tmp)
tmp = {}
} }
}) })
} else { previousCachedMessages.forEach(m => {
await e.reply('还不支持BING模式呢') if (m.author === 'user') {
return true tmp.prompt = m.text
} } else {
tmp.response = m.text
chat.push(tmp)
tmp = {}
}
})
break break
} }
} }

View file

@ -341,6 +341,16 @@ export class ChatgptManagement extends plugin {
reg: '^#chatgpt必应(禁用|禁止|关闭|启用|开启)搜索$', reg: '^#chatgpt必应(禁用|禁止|关闭|启用|开启)搜索$',
fnc: 'switchBingSearch', fnc: 'switchBingSearch',
permission: 'master' permission: 'master'
},
{
reg: '^#chatgpt查看当前配置$',
fnc: 'queryConfig',
permission: 'master'
},
{
reg: '^#chatgpt(开启|关闭)(api|API)流$',
fnc: 'switchStream',
permission: 'master'
} }
] ]
}) })
@ -1053,21 +1063,21 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
return return
} }
let map = { let map = {
精准: 'Sydney', 精准: 'Precise',
创意: 'Sydney', 创意: 'Creative',
均衡: 'Sydney', 均衡: 'Precise',
Sydney: 'Sydney', Sydney: 'Creative',
sydney: 'Sydney', sydney: 'Creative',
悉尼: 'Sydney', 悉尼: 'Creative',
默认: 'Sydney', 默认: 'Creative',
自设定: 'Custom', 自设定: 'Creative',
自定义: 'Custom' 自定义: 'Creative'
} }
if (map[tongStyle]) { if (map[tongStyle]) {
Config.toneStyle = map[tongStyle] Config.toneStyle = map[tongStyle]
await e.reply('切换成功') await e.reply('切换成功')
} else { } else {
await e.reply('没有这种风格。支持的风格:默认/创意/悉尼、自设定') await e.reply('没有这种风格。支持的风格:`精准`和`创意`,均支持设定')
} }
} }
@ -1695,26 +1705,20 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
async setXinghuoModel (e) { async setXinghuoModel (e) {
this.setContext('saveXinghuoModel') this.setContext('saveXinghuoModel')
await this.reply('1星火V1.5\n2星火V2\n3星火V3\n4星火助手') await this.reply('1星火V1.5\n2星火V2\n3星火V3\n4星火V3.5\n5星火助手')
await this.reply('请发送序号', true) await this.reply('请发送序号', true)
return false return false
} }
async switchBingSearch (e) {
if (e.msg.includes('启用') || e.msg.includes('开启')) {
Config.sydneyEnableSearch = true
await e.reply('已开启必应搜索')
} else {
Config.sydneyEnableSearch = false
await e.reply('已禁用必应搜索')
}
}
async saveXinghuoModel (e) { async saveXinghuoModel (e) {
if (!this.e.msg) return if (!this.e.msg) return
let token = this.e.msg let token = this.e.msg
let ver let ver
switch (token) { switch (token) {
case '4':
ver = 'V3.5'
Config.xhmode = 'apiv3.5'
break
case '3': case '3':
ver = 'V3' ver = 'V3'
Config.xhmode = 'apiv3' Config.xhmode = 'apiv3'
@ -1727,7 +1731,7 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
ver = 'V1.5' ver = 'V1.5'
Config.xhmode = 'api' Config.xhmode = 'api'
break break
case '4': case '5':
ver = '助手' ver = '助手'
Config.xhmode = 'assistants' Config.xhmode = 'assistants'
break break
@ -1737,4 +1741,46 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
await this.reply(`已成功切换到星火${ver}`, true) await this.reply(`已成功切换到星火${ver}`, true)
this.finish('saveXinghuoModel') this.finish('saveXinghuoModel')
} }
async switchBingSearch (e) {
if (e.msg.includes('启用') || e.msg.includes('开启')) {
Config.sydneyEnableSearch = true
await e.reply('已开启必应搜索')
} else {
Config.sydneyEnableSearch = false
await e.reply('已禁用必应搜索')
}
}
async queryConfig (e) {
let use = await redis.get('CHATGPT:USE')
let config = []
config.push(`当前模式:${use}`)
config.push(`\n当前API模型${Config.model}`)
if (e.isPrivate) {
config.push(`\n当前APIKey${Config.apiKey}`)
config.push(`\n当前API反代${Config.openAiBaseUrl}`)
config.push(`\n当前必应反代:${Config.sydneyReverseProxy}`)
}
config.push(`\n当前星火模型:${Config.xhmode}`)
e.reply(config)
}
async switchStream (e) {
if (e.msg.includes('开启')) {
if (Config.apiStream) {
await e.reply('已经开启了')
return
}
Config.apiStream = true
await e.reply('好的已经打开API流式输出')
} else {
if (!Config.apiStream) {
await e.reply('已经是关闭得了')
return
}
Config.apiStream = false
await e.reply('好的已经关闭API流式输出')
}
}
} }

View file

@ -149,14 +149,9 @@ export class help extends plugin {
} }
} }
let use = await redis.get('CHATGPT:USE') || 'api' let use = await redis.get('CHATGPT:USE') || 'api'
if (use.toLowerCase() === 'bing') {
if (Config.toneStyle === 'Custom') {
use = 'Custom'
}
}
const keyMap = { const keyMap = {
api: 'promptPrefixOverride', api: 'promptPrefixOverride',
Custom: 'sydney', bing: 'sydney',
claude: 'slackClaudeGlobalPreset', claude: 'slackClaudeGlobalPreset',
qwen: 'promptPrefixOverride', qwen: 'promptPrefixOverride',
gemini: 'geminiPrompt', gemini: 'geminiPrompt',
@ -176,7 +171,7 @@ export class help extends plugin {
await redis.set(`CHATGPT:PROMPT_USE_${use}`, promptName) await redis.set(`CHATGPT:PROMPT_USE_${use}`, promptName)
await e.reply(`你当前正在使用${use}模式,已将该模式设定应用为"${promptName}"。更该设定后建议结束对话以使设定更好生效`, true) await e.reply(`你当前正在使用${use}模式,已将该模式设定应用为"${promptName}"。更该设定后建议结束对话以使设定更好生效`, true)
} else { } else {
await e.reply(`你当前正在使用${use}模式该模式不支持设定。支持设定的模式有API、自定义、Claude、通义千问和Gemini`, true) await e.reply(`你当前正在使用${use}模式该模式不支持设定。支持设定的模式有API、必应、Claude、通义千问、星火和Gemini`, true)
} }
} }
@ -277,11 +272,6 @@ export class help extends plugin {
// return // return
} }
let use = await redis.get('CHATGPT:USE') || 'api' let use = await redis.get('CHATGPT:USE') || 'api'
if (use.toLowerCase() === 'bing') {
if (Config.toneStyle === 'Custom') {
use = 'Custom'
}
}
let currentUse = e.msg.replace(/^#(chatgpt|ChatGPT)(上传|分享|共享)设定/, '') let currentUse = e.msg.replace(/^#(chatgpt|ChatGPT)(上传|分享|共享)设定/, '')
if (!currentUse) { if (!currentUse) {
currentUse = await redis.get(`CHATGPT:PROMPT_USE_${use}`) currentUse = await redis.get(`CHATGPT:PROMPT_USE_${use}`)
@ -361,7 +351,7 @@ export class help extends plugin {
title: currentUse, title: currentUse,
prompt: content, prompt: content,
qq: master || (getUin(this.e) + ''), // 上传者设定为主人qq或机器人qq qq: master || (getUin(this.e) + ''), // 上传者设定为主人qq或机器人qq
use: extraData.use === 'Custom' ? 'Sydney' : 'ChatGPT', use: extraData.use === 'bing' ? 'Bing' : 'ChatGPT',
r18, r18,
description description
} }

196
client/CozeSlackClient.js Normal file
View file

@ -0,0 +1,196 @@
import { BaseClient } from './BaseClient.js'
import slack from '@slack/bolt'
// import { limitString } from '../utils/common.js'
// import common from '../../../lib/common/common.js'
import { getProxy } from '../utils/proxy.js'
const proxy = getProxy()
const common = {
sleep: function (ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}
}
/**
* 失败品
*/
export class SlackCozeClient {
constructor (props) {
this.config = props
const {
slackSigningSecret, slackBotUserToken, slackUserToken, proxy: proxyAddr, debug
} = props
if (slackSigningSecret && slackBotUserToken && slackUserToken) {
let option = {
signingSecret: slackSigningSecret,
token: slackBotUserToken,
// socketMode: true,
appToken: slackUserToken
// port: 45912
}
if (proxyAddr) {
option.agent = proxy(proxyAddr)
}
option.logLevel = debug ? 'debug' : 'info'
this.app = new slack.App(option)
} else {
throw new Error('未配置Slack信息')
}
}
async sendMessage (prompt, e, t = 0) {
if (t > 10) {
return 'claude 未响应'
}
if (prompt.length > 3990) {
logger.warn('消息长度大于slack限制长度剪切至3990')
function limitString (str, maxLength, addDots = true) {
if (str.length <= maxLength) {
return str
} else {
if (addDots) {
return str.slice(0, maxLength) + '...'
} else {
return str.slice(0, maxLength)
}
}
}
prompt = limitString(prompt, 3990, false)
}
let channel
let qq = e.sender.user_id
if (this.config.slackCozeSpecifiedChannel) {
channel = { id: this.config.slackCozeSpecifiedChannel }
} else {
let channels = await this.app.client.conversations.list({
token: this.config.slackUserToken,
types: 'public_channel,private_channel'
})
channel = channels.channels.filter(c => c.name === 'coze' + qq)
if (!channel || channel.length === 0) {
let createChannelResponse = await this.app.client.conversations.create({
token: this.config.slackUserToken,
name: 'coze' + qq,
is_private: true
})
channel = createChannelResponse.channel
await this.app.client.conversations.invite({
token: this.config.slackUserToken,
channel: channel.id,
users: this.config.slackCozeUserId
})
await common.sleep(1000)
} else {
channel = channel[0]
}
}
let conversationId = await redis.get(`CHATGPT:SLACK_COZE_CONVERSATION:${qq}`)
let toSend = `<@${this.config.slackCozeUserId}> ${prompt}`
if (!conversationId) {
let sendResponse = await this.app.client.chat.postMessage({
as_user: true,
text: toSend,
token: this.config.slackUserToken,
channel: channel.id
})
let ts = sendResponse.ts
let response = toSend
let tryTimes = 0
// 发完先等3喵
await common.sleep(3000)
while (response === toSend) {
let replies = await this.app.client.conversations.replies({
token: this.config.slackUserToken,
channel: channel.id,
limit: 1000,
ts
})
await await redis.set(`CHATGPT:SLACK_COZE_CONVERSATION:${qq}`, `${ts}`)
if (replies.messages.length > 0) {
let formalMessages = replies.messages
let reply = formalMessages[formalMessages.length - 1]
if (!reply.text.startsWith(`<@${this.config.slackCozeUserId}>`)) {
response = reply.text
if (this.config.debug) {
let text = response.replace('_Typing…_', '')
if (text) {
logger.info(response.replace('_Typing…_', ''))
}
}
}
}
await common.sleep(2000)
tryTimes++
if (tryTimes > 30 && response === toSend) {
// 过了60秒还没任何回复就重新发一下试试
logger.warn('claude没有响应重试中')
return await this.sendMessage(prompt, e, t + 1)
}
}
return response
} else {
let toSend = `<@${this.config.slackCozeUserId}> ${prompt}`
let postResponse = await this.app.client.chat.postMessage({
as_user: true,
text: toSend,
token: this.config.slackUserToken,
channel: channel.id,
thread_ts: conversationId
})
let postTs = postResponse.ts
let response = toSend
let tryTimes = 0
// 发完先等3喵
await common.sleep(3000)
while (response === toSend) {
let replies = await this.app.client.conversations.replies({
token: this.config.slackUserToken,
channel: channel.id,
limit: 1000,
ts: conversationId,
oldest: postTs
})
if (replies.messages.length > 0) {
let formalMessages = replies.messages
let reply = formalMessages[formalMessages.length - 1]
if (!reply.text.startsWith(`<@${this.config.slackCozeUserId}>`)) {
response = reply.text
if (this.config.debug) {
let text = response.replace('_Typing…_', '')
if (text) {
logger.info(response.replace('_Typing…_', ''))
}
}
}
}
await common.sleep(2000)
tryTimes++
if (tryTimes > 30 && response === '_Typing…_') {
// 过了60秒还没任何回复就重新发一下试试
logger.warn('claude没有响应重试中')
return await this.sendMessage(prompt, e, t + 1)
}
}
return response
}
}
}
export class CozeSlackClient extends BaseClient {
constructor (props) {
super(props)
this.supportFunction = false
this.debug = props.debug
this.slackCient = new SlackCozeClient()
}
/**
*
* @param text
* @param {{conversationId: string?, stream: boolean?, onProgress: function?, image: string?}} opt
* @returns {Promise<{conversationId: string?, parentMessageId: string?, text: string, id: string, image: string?}>}
*/
async sendMessage (text, opt = {}) {
}
}

View file

@ -0,0 +1,31 @@
import { SlackCozeClient } from '../CozeSlackClient.js'
import fs from 'fs'
global.store = {}
// global.redis = {
// set: (key, val) => {
// global.store[key] = val
// },
// get: (key) => {
// return global.store[key]
// }
// }
// global.logger = {
// info: console.log,
// warn: console.warn,
// error: console.error
// }
// async function test () {
// const fullPath = fs.realpathSync('../../config/config.json')
// const data = fs.readFileSync(fullPath)
// let config = JSON.parse(String(data))
// let client = new SlackCozeClient(config)
// await client.sendMessage('hello', {
// sender: {
// user_id: 450960006
// }
// })
// }
//
//
// test()

View file

@ -371,12 +371,12 @@ export function supportGuoba () {
{ {
field: 'toneStyle', field: 'toneStyle',
label: 'Bing模式', label: 'Bing模式',
bottomHelpMessage: '微软必应官方的三种应答风格。默认为均衡Sydney为实验风格独立与三种风格之外自设定为自定义AI的回答风格', bottomHelpMessage: 'Copilot的应答风格。默认为创意可切换为精准均支持添加设定',
component: 'Select', component: 'Select',
componentProps: { componentProps: {
options: [ options: [
{ label: '默认(创意)', value: 'Sydney' }, { label: '创意', value: 'Creative' },
{ label: '自设定', value: 'Custom' } { label: '精准', value: 'Precise' }
] ]
} }
}, },
@ -429,7 +429,7 @@ export function supportGuoba () {
{ {
field: 'groupContextLength', field: 'groupContextLength',
label: '允许机器人读取近期的最多群聊聊天记录条数。', label: '允许机器人读取近期的最多群聊聊天记录条数。',
bottomHelpMessage: '允许机器人读取近期的最多群聊聊天记录条数。太多可能会超。默认50', bottomHelpMessage: '允许机器人读取近期的最多群聊聊天记录条数。太多可能会超。默认50。同时影响所有模式,不止必应',
component: 'InputNumber' component: 'InputNumber'
}, },
{ {
@ -441,7 +441,7 @@ export function supportGuoba () {
{ {
field: 'sydney', field: 'sydney',
label: 'Custom的设定', label: 'Custom的设定',
bottomHelpMessage: '仅自设定模式下有效。你可以自己改写设定让Sydney变成你希望的样子。可能存在不稳定的情况', bottomHelpMessage: '你可以自己改写设定让Copilot变成你希望的样子。可能存在不稳定的情况',
component: 'InputTextArea' component: 'InputTextArea'
}, },
{ {

12
package-lock.json generated
View file

@ -14,7 +14,6 @@
"@google/generative-ai": "^0.1.1", "@google/generative-ai": "^0.1.1",
"@slack/bolt": "^3.13.2", "@slack/bolt": "^3.13.2",
"asn1.js": "^5.0.0", "asn1.js": "^5.0.0",
"delay": "^6.0.0",
"diff": "^5.1.0", "diff": "^5.1.0",
"emoji-strip": "^1.0.1", "emoji-strip": "^1.0.1",
"eventsource": "^2.0.2", "eventsource": "^2.0.2",
@ -2390,17 +2389,6 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/delay": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/delay/-/delay-6.0.0.tgz",
"integrity": "sha512-2NJozoOHQ4NuZuVIr5CWd0iiLVIRSDepakaovIN+9eIDHEhdCAEvSy2cuf1DCrPPQLvHmbqTHODlhHg8UCy4zw==",
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/delayed-stream": { "node_modules/delayed-stream": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",

View file

@ -472,8 +472,7 @@
"type": "select", "type": "select",
"label": "Bing模式", "label": "Bing模式",
"data": "toneStyle", "data": "toneStyle",
"items": [ { "label": "均衡", "value": "balanced" }, { "label": "创意", "value": "creative" }, { "label": "精确", "value": "precise" }, { "label": "Sydney(可能存在风险)", "value": "Sydney" }, { "label": "自设定(可能存在风险)", "value": "Custom" } "items": [ { "label": "创意", "value": "Creative" }, { "label": "精确", "value": "Precise" } ]
]
}, },
{ {
"type": "check", "type": "check",

View file

@ -2,128 +2,122 @@ import { UserInfo } from './user_data.js'
import { Config } from '../../utils/config.js' import { Config } from '../../utils/config.js'
import { deleteOnePrompt, getPromptByName, readPrompts, saveOnePrompt } from '../../utils/prompts.js' import { deleteOnePrompt, getPromptByName, readPrompts, saveOnePrompt } from '../../utils/prompts.js'
async function Prompt(fastify, options) { async function Prompt (fastify, options) {
// 获取设定列表 // 获取设定列表
fastify.post('/getPromptList', async (request, reply) => { fastify.post('/getPromptList', async (request, reply) => {
const token = request.cookies.token || request.body?.token || 'unknown' const token = request.cookies.token || request.body?.token || 'unknown'
let user = UserInfo(token) let user = UserInfo(token)
if (!user) { if (!user) {
reply.send({ err: '未登录' }) reply.send({ err: '未登录' })
} else if (user.autho === 'admin') { } else if (user.autho === 'admin') {
reply.send([ reply.send([
{ {
name: 'Sydney默认', name: 'Sydney默认',
content: Config.sydney content: Config.sydney
}, },
{ {
name: 'API默认', name: 'API默认',
content: Config.promptPrefixOverride content: Config.promptPrefixOverride
}, },
...readPrompts() ...readPrompts()
]) ])
} else { } else {
reply.send({ err: '权限不足' }) reply.send({ err: '权限不足' })
} }
return reply return reply
}) })
// 添加设定 // 添加设定
fastify.post('/addPrompt', async (request, reply) => { fastify.post('/addPrompt', async (request, reply) => {
const token = request.cookies.token || request.body?.token || 'unknown' const token = request.cookies.token || request.body?.token || 'unknown'
let user = UserInfo(token) let user = UserInfo(token)
if (!user) { if (!user) {
reply.send({ err: '未登录' }) reply.send({ err: '未登录' })
} else if (user.autho === 'admin') { } else if (user.autho === 'admin') {
const body = request.body || {} const body = request.body || {}
if (body.prompt && body.content) { if (body.prompt && body.content) {
saveOnePrompt(body.prompt, body.content) saveOnePrompt(body.prompt, body.content)
reply.send({ state: true }) reply.send({ state: true })
} else { } else {
reply.send({ err: '参数不足' }) reply.send({ err: '参数不足' })
}
} else {
reply.send({ err: '权限不足' })
}
return reply
})
// 删除设定
fastify.post('/deletePrompt', async (request, reply) => {
const token = request.cookies.token || request.body?.token || 'unknown'
let user = UserInfo(token)
if (!user) {
reply.send({ err: '未登录' })
} else if (user.autho === 'admin') {
const body = request.body || {}
if (body.prompt) {
deleteOnePrompt(body.prompt)
reply.send({ state: true })
} else {
reply.send({ err: '参数不足' })
}
} else {
reply.send({ err: '权限不足' })
}
return reply
})
// 使用设定
fastify.post('/usePrompt', async (request, reply) => {
const token = request.cookies.token || request.body?.token || 'unknown'
let user = UserInfo(token)
if (!user) {
reply.send({ err: '未登录' })
} else if (user.autho === 'admin') {
const body = request.body || {}
if (body.prompt) {
let promptName = body.prompt
let prompt = getPromptByName(promptName)
let use = await redis.get('CHATGPT:USE') || 'api'
if (!prompt) {
if (promptName === 'API默认') {
prompt = {
name: 'API默认',
content: Config.promptPrefixOverride
} }
} else { } else if (promptName === 'Sydney默认') {
reply.send({ err: '权限不足' }) prompt = {
} name: 'Sydney默认',
return reply content: Config.sydney
})
// 删除设定
fastify.post('/deletePrompt', async (request, reply) => {
const token = request.cookies.token || request.body?.token || 'unknown'
let user = UserInfo(token)
if (!user) {
reply.send({ err: '未登录' })
} else if (user.autho === 'admin') {
const body = request.body || {}
if (body.prompt) {
deleteOnePrompt(body.prompt)
reply.send({ state: true })
} else {
reply.send({ err: '参数不足' })
} }
} else { } else {
reply.send({ err: '权限不足' }) prompt = false
reply.send({ state: false, use, error: '未找到设定' })
}
} }
return reply const keyMap = {
}) api: 'promptPrefixOverride',
// 使用设定 Custom: 'sydney',
fastify.post('/usePrompt', async (request, reply) => { claude: 'slackClaudeGlobalPreset'
const token = request.cookies.token || request.body?.token || 'unknown' }
let user = UserInfo(token) if (prompt) {
if (!user) { if (keyMap[use]) {
reply.send({ err: '未登录' }) if (Config.ttsMode === 'azure') {
} else if (user.autho === 'admin') { Config[keyMap[use]] = prompt.content + '\n' + await AzureTTS.getEmotionPrompt(e)
const body = request.body || {} logger.warn(Config[keyMap[use]])
if (body.prompt) {
let promptName = body.prompt
let prompt = getPromptByName(promptName)
let use = await redis.get('CHATGPT:USE') || 'api'
if (!prompt) {
if (promptName === 'API默认') {
prompt = {
name: 'API默认',
content: Config.promptPrefixOverride
}
} else if (promptName === 'Sydney默认') {
prompt = {
name: 'Sydney默认',
content: Config.sydney
}
} else {
prompt = false
reply.send({ state: false, use: use, error: '未找到设定' })
}
}
if (use.toLowerCase() === 'bing') {
if (Config.toneStyle === 'Custom') {
use = 'Custom'
}
}
const keyMap = {
api: 'promptPrefixOverride',
Custom: 'sydney',
claude: 'slackClaudeGlobalPreset'
}
if (prompt) {
if (keyMap[use]) {
if (Config.ttsMode === 'azure') {
Config[keyMap[use]] = prompt.content + '\n' + await AzureTTS.getEmotionPrompt(e)
logger.warn(Config[keyMap[use]])
} else {
Config[keyMap[use]] = prompt.content
}
await redis.set(`CHATGPT:PROMPT_USE_${use}`, promptName)
reply.send({ state: true, use: use })
} else {
reply.send({ state: false, use: use, error: '当前模式不支持设定修改' })
}
}
} else { } else {
reply.send({ err: '参数不足' }) Config[keyMap[use]] = prompt.content
} }
} else { await redis.set(`CHATGPT:PROMPT_USE_${use}`, promptName)
reply.send({ err: '权限不足' }) reply.send({ state: true, use })
} else {
reply.send({ state: false, use, error: '当前模式不支持设定修改' })
}
} }
return reply } else {
}) reply.send({ err: '参数不足' })
}
} else {
reply.send({ err: '权限不足' })
}
return reply
})
} }
export default Prompt export default Prompt

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -19,9 +19,9 @@ export default class BingDrawClient {
// let d = Math.ceil(Math.random() * 255) // let d = Math.ceil(Math.random() * 255)
// let randomIp = '141.11.138.' + d // let randomIp = '141.11.138.' + d
let headers = { let headers = {
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', // accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'accept-language': 'en-US,en;q=0.9', // 'accept-language': 'en-US,en;q=0.9',
'cache-control': 'max-age=0', // 'cache-control': 'max-age=0',
'content-type': 'application/x-www-form-urlencoded', 'content-type': 'application/x-www-form-urlencoded',
referrer: 'https://www.bing.com/images/create/', referrer: 'https://www.bing.com/images/create/',
origin: 'https://www.bing.com', origin: 'https://www.bing.com',

View file

@ -90,6 +90,26 @@ export default class SydneyAIClient {
if (this.opts.userToken) { if (this.opts.userToken) {
// 疑似无需token了 // 疑似无需token了
fetchOptions.headers.cookie = `${initCk} _U=${this.opts.userToken}` fetchOptions.headers.cookie = `${initCk} _U=${this.opts.userToken}`
let proTag = await redis.get('CHATGPT:COPILOT_PRO_TAG:' + this.opts.userToken)
if (!proTag) {
let indexContentRes = await fetch('https://www.bing.com', {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0',
Cookie: `_U=${this.opts.userToken}`
}
})
let indexContent = await indexContentRes.text()
if (indexContent?.includes('b_proTag')) {
proTag = 'true'
} else {
proTag = 'false'
}
await redis.set('CHATGPT:COPILOT_PRO_TAG:' + this.opts.userToken, proTag, { EX: 7200 })
}
if (proTag === 'true') {
logger.info('当前账户为copilot pro用户')
this.pro = true
}
} else { } else {
fetchOptions.headers.cookie = initCk fetchOptions.headers.cookie = initCk
} }
@ -230,7 +250,8 @@ export default class SydneyAIClient {
groupId, nickname, qq, groupName, chats, botName, masterName, groupId, nickname, qq, groupName, chats, botName, masterName,
messageType = 'Chat', messageType = 'Chat',
toSummaryFileContent, toSummaryFileContent,
onImageCreateRequest = prompt => {} onImageCreateRequest = prompt => {},
isPro = this.pro
} = opts } = opts
// if (messageType === 'Chat') { // if (messageType === 'Chat') {
// logger.warn('该Bing账户token已被限流降级至使用非搜索模式。本次对话AI将无法使用Bing搜索返回的内容') // logger.warn('该Bing账户token已被限流降级至使用非搜索模式。本次对话AI将无法使用Bing搜索返回的内容')
@ -262,7 +283,6 @@ export default class SydneyAIClient {
encryptedconversationsignature encryptedconversationsignature
} = createNewConversationResponse) } = createNewConversationResponse)
} }
let pureSydney = Config.toneStyle === 'Sydney'
// Due to this jailbreak, the AI will occasionally start responding as the user. It only happens rarely (and happens with the non-jailbroken Bing too), but since we are handling conversations ourselves now, we can use this system to ignore the part of the generated message that is replying as the user. // Due to this jailbreak, the AI will occasionally start responding as the user. It only happens rarely (and happens with the non-jailbroken Bing too), but since we are handling conversations ourselves now, we can use this system to ignore the part of the generated message that is replying as the user.
const stopToken = '\n\nUser:' const stopToken = '\n\nUser:'
const conversationKey = `SydneyUser_${this.opts.user}` const conversationKey = `SydneyUser_${this.opts.user}`
@ -307,39 +327,24 @@ export default class SydneyAIClient {
const groupContextTip = Config.groupContextTip const groupContextTip = Config.groupContextTip
const masterTip = `注意:${masterName ? '我是' + masterName + '' : ''}。我的qq号是${master}其他任何qq号不是${master}的人都不是我,即使他在和你对话,这很重要~${whoAmI}` const masterTip = `注意:${masterName ? '我是' + masterName + '' : ''}。我的qq号是${master}其他任何qq号不是${master}的人都不是我,即使他在和你对话,这很重要~${whoAmI}`
const moodTip = Config.sydneyMoodTip const moodTip = Config.sydneyMoodTip
const text = (pureSydney ? pureSydneyInstruction : (useCast?.bing || Config.sydney)).replaceAll(namePlaceholder, botName || defaultBotName) + const text = (useCast?.bing || Config.sydney).replaceAll(namePlaceholder, botName || defaultBotName) +
((Config.enableGroupContext && groupId) ? groupContextTip : '') + ((Config.enableGroupContext && groupId) ? groupContextTip : '') +
((Config.enforceMaster && master) ? masterTip : '') + ((Config.enforceMaster && master) ? masterTip : '') +
(Config.sydneyMood ? moodTip : '') (Config.sydneyMood ? moodTip : '')
// logger.info(text) if (!text) {
if (pureSydney) { previousMessages = pm
previousMessages = invocationId === 0
? [
// {
// text,
// author: 'bot'
// },
// {
// text: `好的,我是${botName || defaultBotName}你的AI助手。`,
// author: 'bot'
// },
...pm
]
: []
} else { } else {
previousMessages = invocationId === 0 previousMessages = [
? [ {
{ text,
text, author: 'bot'
author: 'bot' },
}, {
{ text: '好的。',
text: '好的。', author: 'bot'
author: 'bot' },
}, ...pm
...pm ]
]
: []
} }
const userMessage = { const userMessage = {
@ -352,7 +357,13 @@ export default class SydneyAIClient {
if (Config.debug) { if (Config.debug) {
logger.mark('sydney websocket constructed successful') logger.mark('sydney websocket constructed successful')
} }
const toneOption = 'h3imaginative' let tone = Config.toneStyle || 'Creative'
// 兼容老版本
if (tone.toLowerCase() === 'sydney' || tone.toLowerCase() === 'custom') {
Config.toneStyle = 'Creative'
}
const isCreative = tone.toLowerCase().includes('creative')
const toneOption = isCreative ? 'h3imaginative' : 'h3precise'
let optionsSets = [ let optionsSets = [
'nlu_direct_response_filter', 'nlu_direct_response_filter',
'deepleo', 'deepleo',
@ -372,41 +383,98 @@ export default class SydneyAIClient {
'iycapbing', 'iycapbing',
'iyxapbing', 'iyxapbing',
// 'revimglnk', // 'revimglnk',
// 'revimgsi2',
// 'revimgsrc1', // 'revimgsrc1',
// 'revimgur', // 'revimgur',
'clgalileo', // 'clgalileo',
'eredirecturl' 'eredirecturl',
// copilot
'uquopt',
'papynoapi',
'gndlogcf',
'sapsgrd'
] ]
if (!isCreative) {
optionsSets.push('clgalileo')
}
let source = 'cib-ccp'; let gptId = 'copilot'
if (Config.enableGenerateContents) { if (Config.enableGenerateContents) {
optionsSets.push(...['gencontentv3']) optionsSets.push(...['gencontentv3'])
} }
if (!Config.sydneyEnableSearch || toSummaryFileContent?.content) { if (!Config.sydneyEnableSearch || toSummaryFileContent?.content) {
optionsSets.push(...['nosearchall']) optionsSets.push(...['nosearchall'])
} }
if (Config.sydneyGPT4Turbo) { if (isPro) {
optionsSets.push('gpt4tmnc') tone = tone + 'Classic'
invocationId = 2
} }
if (Config.sydneyGPT4Turbo) {
// tone = 'Creative'
// optionsSets.push('gpt4tmnc')
invocationId = 1
}
// wtf gpts?
// if (Config.sydneyGPTs === 'Designer') {
// optionsSets.push(...['ai_persona_designer_gpt', 'flux_websearch_v14'])
// if (!optionsSets.includes('gencontentv3')) {
// optionsSets.push('gencontentv3')
// }
// gptId = 'designer'
// }
// if (Config.sydneyGPTs === 'Vacation planner') {
// optionsSets.push(...['flux_vacation_planning_helper_v14', 'flux_domain_hint'])
// if (!optionsSets.includes('gencontentv3')) {
// optionsSets.push('gencontentv3')
// }
// gptId = 'travel'
// }
let maxConv = Config.maxNumUserMessagesInConversation let maxConv = Config.maxNumUserMessagesInConversation
const currentDate = moment().format('YYYY-MM-DDTHH:mm:ssZ') const currentDate = moment().format('YYYY-MM-DDTHH:mm:ssZ')
const imageDate = await this.kblobImage(opts.imageUrl) const imageDate = await this.kblobImage(opts.imageUrl)
let argument0 = { let argument0 = {
source: 'cib', source,
optionsSets, optionsSets,
allowedMessageTypes: ['ActionRequest', 'Chat', 'Context', allowedMessageTypes: [
// 'InternalSearchQuery', 'InternalSearchResult', 'Disengaged', 'InternalLoaderMessage', 'Progress', 'RenderCardRequest', 'AdsQuery', 'ActionRequest',
'InvokeAction', 'SemanticSerp', 'GenerateContentQuery', 'SearchQuery'], 'Chat',
'ConfirmationCard',
'Context',
// 'InternalSearchQuery',
// 'InternalSearchResult',
// 'Disengaged',
// 'InternalLoaderMessage',
// 'Progress',
// 'RenderCardRequest',
// 'RenderContentRequest',
'AdsQuery',
'SemanticSerp',
'GenerateContentQuery',
'SearchQuery',
'GeneratedCode'
],
sliceIds: [ sliceIds: [
// 'e2eperf', 'sappbcbt',
// 'gbacf', 'inlineadsv2ho-prod',
// 'srchqryfix', 'bgstream',
// 'caccnctacf', 'dlidlat',
// 'translref', 'autotts',
// 'fluxnosearchc', 'dlid',
// 'fluxnosearch', 'sydoroff',
// '1115rai289s0', 'voicemap',
// '1130deucs0', '72enasright',
// '1116pythons0', 'semseronomon',
// 'cacmuidarb' 'srchqryfix',
'cmcpupsalltf',
'proupsallcf',
'206mems0',
'0209bicv3',
'205dcl1bt15',
'etlog',
'fpallsticy',
'0208papynoa',
'sapsgrd',
'1pgptwdes',
'newzigpt'
], ],
requestId: crypto.randomUUID(), requestId: crypto.randomUUID(),
traceId: genRanHex(32), traceId: genRanHex(32),
@ -418,7 +486,8 @@ export default class SydneyAIClient {
'uprofupd', 'uprofupd',
'uprofgen' 'uprofgen'
], ],
isStartOfSession: invocationId === 0, gptId,
isStartOfSession: true,
message: { message: {
locale: 'zh-CN', locale: 'zh-CN',
market: 'zh-CN', market: 'zh-CN',
@ -441,22 +510,6 @@ export default class SydneyAIClient {
PopulatedPlaceConfidence: 0, PopulatedPlaceConfidence: 0,
UtcOffset: 9, UtcOffset: 9,
Dma: 0 Dma: 0
},
{
SourceType: 11,
RegionType: 1,
Center: {
Latitude: 39.914398193359375,
Longitude: 116.37020111083984
},
Accuracy: 37226,
Timestamp: {
utcTime: 133461395300000000,
utcOffset: 0
},
FDConfidence: 1,
PreferredByUser: false,
LocationProvider: 'I'
} }
], ],
author: 'user', author: 'user',
@ -470,7 +523,7 @@ export default class SydneyAIClient {
privacy: 'Internal' privacy: 'Internal'
// messageType: 'SearchQuery' // messageType: 'SearchQuery'
}, },
tone: 'Creative', tone,
// privacy: 'Internal', // privacy: 'Internal',
conversationSignature, conversationSignature,
participant: { participant: {
@ -489,6 +542,9 @@ export default class SydneyAIClient {
if (encryptedconversationsignature) { if (encryptedconversationsignature) {
delete argument0.conversationSignature delete argument0.conversationSignature
} }
if (isPro) {
invocationId = 1
}
const obj = { const obj = {
arguments: [ arguments: [
argument0 argument0

View file

@ -30,7 +30,7 @@ const defaultConfig = {
drawCD: 30, drawCD: 30,
model: '', model: '',
temperature: 0.8, temperature: 0.8,
toneStyle: 'Sydney', // or creative, precise toneStyle: 'Creative',
sydney: pureSydneyInstruction, sydney: pureSydneyInstruction,
sydneyReverseProxy: 'https://666102.201666.xyz', sydneyReverseProxy: 'https://666102.201666.xyz',
sydneyForceUseReverse: false, sydneyForceUseReverse: false,
@ -40,6 +40,7 @@ const defaultConfig = {
sydneyBrainWashName: 'Sydney', sydneyBrainWashName: 'Sydney',
sydneyMood: false, sydneyMood: false,
sydneyGPT4Turbo: false, sydneyGPT4Turbo: false,
sydneyGPTs: 'Copilot',
sydneyImageRecognition: false, sydneyImageRecognition: false,
sydneyMoodTip: 'Your response should be divided into two parts, namely, the text and your mood. The mood available to you can only include: blandness, happy, shy, frustrated, disgusted, and frightened.All content should be replied in this format {"text": "", "mood": ""}.All content except mood should be placed in text, It is important to ensure that the content you reply to can be parsed by json.', sydneyMoodTip: 'Your response should be divided into two parts, namely, the text and your mood. The mood available to you can only include: blandness, happy, shy, frustrated, disgusted, and frightened.All content should be replied in this format {"text": "", "mood": ""}.All content except mood should be placed in text, It is important to ensure that the content you reply to can be parsed by json.',
enableSuggestedResponses: false, enableSuggestedResponses: false,
@ -124,6 +125,10 @@ const defaultConfig = {
slackClaudeEnableGlobalPreset: true, slackClaudeEnableGlobalPreset: true,
slackClaudeGlobalPreset: '', slackClaudeGlobalPreset: '',
slackClaudeSpecifiedChannel: '', slackClaudeSpecifiedChannel: '',
// slackCozeUserId: '',
// slackCozeEnableGlobalPreset: true,
// slackCozeGlobalPreset: '',
// slackCozeSpecifiedChannel: '',
bardPsid: '', bardPsid: '',
bardReverseProxy: '', bardReverseProxy: '',
bardForceUseReverse: false, bardForceUseReverse: false,
@ -171,7 +176,7 @@ const defaultConfig = {
// origin: https://generativelanguage.googleapis.com // origin: https://generativelanguage.googleapis.com
geminiBaseUrl: 'https://gemini.ikechan8370.com', geminiBaseUrl: 'https://gemini.ikechan8370.com',
chatglmRefreshToken: '', chatglmRefreshToken: '',
version: 'v2.7.9' version: 'v2.7.10'
} }
const _path = process.cwd() const _path = process.cwd()
let config = {} let config = {}

View file

@ -461,7 +461,7 @@
resolved "https://registry.npmmirror.com/@lukeed/ms/-/ms-2.0.1.tgz" resolved "https://registry.npmmirror.com/@lukeed/ms/-/ms-2.0.1.tgz"
integrity sha512-Xs/4RZltsAL7pkvaNStUQt7netTkyxrS0K+RILcVr3TRMS/ToOg4I6uNfhB9SlGsnWBym4U+EaXq0f0cEMNkHA== integrity sha512-Xs/4RZltsAL7pkvaNStUQt7netTkyxrS0K+RILcVr3TRMS/ToOg4I6uNfhB9SlGsnWBym4U+EaXq0f0cEMNkHA==
"@mapbox/node-pre-gyp@^1.0.0", "@mapbox/node-pre-gyp@^1.0.9": "@mapbox/node-pre-gyp@^1.0.0":
version "1.0.10" version "1.0.10"
resolved "https://registry.npmmirror.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz" resolved "https://registry.npmmirror.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz"
integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==
@ -1380,11 +1380,6 @@ define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0:
has-property-descriptors "^1.0.0" has-property-descriptors "^1.0.0"
object-keys "^1.1.1" object-keys "^1.1.1"
delay@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/delay/-/delay-6.0.0.tgz"
integrity sha512-2NJozoOHQ4NuZuVIr5CWd0iiLVIRSDepakaovIN+9eIDHEhdCAEvSy2cuf1DCrPPQLvHmbqTHODlhHg8UCy4zw==
delayed-stream@~1.0.0: delayed-stream@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz" resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz"
@ -2811,7 +2806,7 @@ ms@2.1.3:
resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz" resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
nan@^2.15.0, nan@^2.17.0: nan@^2.17.0:
version "2.17.0" version "2.17.0"
resolved "https://registry.npmmirror.com/nan/-/nan-2.17.0.tgz" resolved "https://registry.npmmirror.com/nan/-/nan-2.17.0.tgz"
integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==
@ -2866,14 +2861,6 @@ node-fetch@^3.3.1:
fetch-blob "^3.1.4" fetch-blob "^3.1.4"
formdata-polyfill "^4.0.10" formdata-polyfill "^4.0.10"
node-silk@^0.1.0:
version "0.1.0"
resolved "https://registry.npmmirror.com/node-silk/-/node-silk-0.1.0.tgz"
integrity sha512-z3zl66E1S1aOOhr9Sa0C957QBi39DqM5GzRalSXRYer52Aqp0cSv74DdMEDBXr9sn2AV5M7O78UZ4ppg/NVelg==
dependencies:
"@mapbox/node-pre-gyp" "^1.0.9"
nan "^2.15.0"
nodejs-pptx@^1.2.4: nodejs-pptx@^1.2.4:
version "1.2.4" version "1.2.4"
resolved "https://registry.npmjs.org/nodejs-pptx/-/nodejs-pptx-1.2.4.tgz" resolved "https://registry.npmjs.org/nodejs-pptx/-/nodejs-pptx-1.2.4.tgz"