fix: merge

This commit is contained in:
ikechan8370 2025-03-24 12:52:30 +08:00
commit eb71222ed8
5 changed files with 355 additions and 7 deletions

View file

@ -40,9 +40,9 @@ export class bym extends plugin {
.find(item => item.keywords.find(keyword => e.msg?.includes(keyword))) .find(item => item.keywords.find(keyword => e.msg?.includes(keyword)))
if (option) { if (option) {
presetId = option.presetId presetId = option.presetId
}
recall = !!option.recall recall = !!option.recall
} }
}
const presetManager = Chaite.getInstance().getChatPresetManager() const presetManager = Chaite.getInstance().getChatPresetManager()
let preset = await presetManager.getInstance(presetId) let preset = await presetManager.getInstance(presetId)

View file

@ -3,6 +3,7 @@ import { Chaite, SendMessageOption } from 'chaite'
import { getPreset, intoUserMessage, toYunzai } from '../utils/message.js' import { getPreset, intoUserMessage, toYunzai } from '../utils/message.js'
import { YunzaiUserState } from '../models/chaite/user_state_storage.js' import { YunzaiUserState } from '../models/chaite/user_state_storage.js'
import { getGroupContextPrompt, getGroupHistory } from '../utils/group.js' import { getGroupContextPrompt, getGroupHistory } from '../utils/group.js'
import * as crypto from 'node:crypto'
export class Chat extends plugin { export class Chat extends plugin {
constructor () { constructor () {
@ -31,6 +32,9 @@ export class Chat extends plugin {
state = new YunzaiUserState(e.sender.user_id, e.sender.nickname, e.sender.card) state = new YunzaiUserState(e.sender.user_id, e.sender.nickname, e.sender.card)
await Chaite.getInstance().getUserStateStorage().setItem(e.sender.user_id + '', state) await Chaite.getInstance().getUserStateStorage().setItem(e.sender.user_id + '', state)
} }
if (!state.current.conversationId) {
state.current.conversationId = crypto.randomUUID()
}
const preset = await getPreset(e, state?.settings.preset || Config.llm.defaultChatPresetId, Config.basic.toggleMode, Config.basic.togglePrefix) const preset = await getPreset(e, state?.settings.preset || Config.llm.defaultChatPresetId, Config.basic.toggleMode, Config.basic.togglePrefix)
if (!preset) { if (!preset) {
logger.debug('不满足对话触发条件或未找到预设,不进入对话') logger.debug('不满足对话触发条件或未找到预设,不进入对话')

View file

@ -90,13 +90,13 @@ export class ChatGPTManagement extends plugin {
const userStates = await Chaite.getInstance().getUserStateStorage().listItems() const userStates = await Chaite.getInstance().getUserStateStorage().listItems()
let num = 0 let num = 0
for (const userState of userStates) { for (const userState of userStates) {
if (userState.current.conversationId) { if (userState.current.conversationId && userState.current.messageId) {
num++ num++
} userState.current.conversationId = crypto.randomUUID()
userState.current.conversationId = ''
userState.current.messageId = '' userState.current.messageId = ''
await Chaite.getInstance().getUserStateStorage().setItem(userState.userId + '', userState) await Chaite.getInstance().getUserStateStorage().setItem(userState.userId + '', userState)
} }
}
this.reply(`已结束${num}个用户的对话`) this.reply(`已结束${num}个用户的对话`)
} else { } else {
const state = await Chaite.getInstance().getUserStateStorage().getItem(e.sender.user_id + '') const state = await Chaite.getInstance().getUserStateStorage().getItem(e.sender.user_id + '')

344
apps/update.js Normal file
View file

@ -0,0 +1,344 @@
// modified from StarRail-plugin | 已经过StarRail-plugin作者本人同意
import plugin from '../../../lib/plugins/plugin.js'
import { createRequire } from 'module'
import _ from 'lodash'
import { Restart } from '../../other/restart.js'
import ChatGPTConfig from '../config/config.js'
const require = createRequire(import.meta.url)
const { exec, execSync } = require('child_process')
// 是否在更新中
let uping = false
/**
* 处理插件更新
*/
export class Update extends plugin {
constructor () {
const cmdPrefix = ChatGPTConfig.basic.commandPrefix
super({
name: 'chatgpt更新插件',
event: 'message',
priority: 1000,
rule: [
{
reg: `^${cmdPrefix}?(强制)?更新$`,
fnc: 'update'
}
]
})
}
/**
* rule - 更新chatgpt插件
* @returns
*/
async update () {
if (!this.e.isMaster) return false
/** 检查是否正在更新中 */
if (uping) {
await this.reply('已有命令更新中..请勿重复操作')
return
}
/** 检查git安装 */
if (!(await this.checkGit())) return
const isForce = this.e.msg.includes('强制')
/** 执行更新 */
await this.runUpdate(isForce)
/** 是否需要重启 */
if (this.isUp) {
// await this.reply("更新完毕,请重启云崽后生效")
setTimeout(() => this.restart(), 2000)
}
}
restart () {
new Restart(this.e).restart()
}
/**
* chatgpt插件更新函数
* @param {boolean} isForce 是否为强制更新
* @returns
*/
async runUpdate (isForce) {
let command = 'git -C ./plugins/chatgpt-plugin/ pull --no-rebase'
if (isForce) {
command = `git -C ./plugins/chatgpt-plugin/ checkout . && ${command}`
this.e.reply('正在执行强制更新操作,请稍等')
} else {
this.e.reply('正在执行更新操作,请稍等')
}
/** 获取上次提交的commitId用于获取日志时判断新增的更新日志 */
this.oldCommitId = await this.getcommitId('chatgpt-plugin')
uping = true
let ret = await this.execSync(command)
if (ret.error) {
logger.mark(`${this.e.logFnc} 更新失败chatgpt-plugin`)
this.gitErr(ret.error, ret.stdout)
return false
}
// Check if pnpm is available
let packageManager = await this.checkPnpm()
await this.reply(`正在使用 ${packageManager} 更新 chaite 依赖...`)
let npmRet = await this.execSync(`cd ./plugins/chatgpt-plugin/ && ${packageManager} update chaite`)
logger.info(JSON.stringify(npmRet))
if (npmRet.error) {
logger.mark(`${this.e.logFnc} 更新失败chaite 依赖`)
await this.reply(`chaite 依赖更新失败:\n${npmRet.error.toString()}`)
uping = false
return false
}
uping = false
/** 获取插件提交的最新时间 */
let time = await this.getTime('chatgpt-plugin')
if (/(Already up[ -]to[ -]date|已经是最新的)/.test(ret.stdout)) {
await this.reply(`chatgpt-plugin已经是最新版本\n最后更新时间:${time}`)
} else {
let updateMsg = `chatgpt-plugin\n最后更新时间:${time}`
// Add npm update information if available
if (npmRet.stdout.includes('chaite')) {
updateMsg += `\n已使用${packageManager}更新chaite依赖`
}
await this.reply(updateMsg)
this.isUp = true
/** 获取chatgpt组件的更新日志 */
let log = await this.getLog('chatgpt-plugin')
await this.reply(log)
}
logger.mark(`${this.e.logFnc} 最后更新时间:${time}`)
return true
}
/**
* 获取chatgpt插件的更新日志
* @param {string} plugin 插件名称
* @returns
*/
async getLog (plugin = '') {
let cm = `cd ./plugins/${plugin}/ && git log -20 --oneline --pretty=format:"%h||[%cd] %s" --date=format:"%m-%d %H:%M"`
let logAll
try {
logAll = await execSync(cm, { encoding: 'utf-8' })
} catch (error) {
logger.error(error.toString())
this.reply(error.toString())
}
if (!logAll) return false
logAll = logAll.split('\n')
let log = []
for (let str of logAll) {
str = str.split('||')
if (str[0] == this.oldCommitId) break
if (str[1].includes('Merge branch')) continue
log.push(str[1])
}
let line = log.length
log = log.join('\n\n')
if (log.length <= 0) return ''
let end = ''
end =
'更多详细信息请前往github查看\nhttps://github.com/ikechan8370/chatgpt-plugin'
log = await this.makeForwardMsg(`chatgpt-plugin更新日志${line}`, log, end)
return log
}
/**
* 获取上次提交的commitId
* @param {string} plugin 插件名称
* @returns
*/
async getcommitId (plugin = '') {
let cm = `git -C ./plugins/${plugin}/ rev-parse --short HEAD`
let commitId = await execSync(cm, { encoding: 'utf-8' })
commitId = _.trim(commitId)
return commitId
}
/**
* 获取本次更新插件的最后一次提交时间
* @param {string} plugin 插件名称
* @returns
*/
async getTime (plugin = '') {
let cm = `cd ./plugins/${plugin}/ && git log -1 --oneline --pretty=format:"%cd" --date=format:"%m-%d %H:%M"`
let time = ''
try {
time = await execSync(cm, { encoding: 'utf-8' })
time = _.trim(time)
} catch (error) {
logger.error(error.toString())
time = '获取时间失败'
}
return time
}
/**
* 制作转发消息
* @param {string} title 标题 - 首条消息
* @param {string} msg 日志信息
* @param {string} end 最后一条信息
* @returns
*/
async makeForwardMsg (title, msg, end) {
const _bot = this.e.bot ?? Bot
let nickname = _bot.nickname
if (this.e.isGroup) {
let info = await _bot?.pickMember?.(this.e.group_id, _bot.uin) || await _bot?.getGroupMemberInfo?.(this.e.group_id, _bot.uin)
nickname = info.card || info.nickname
}
let userInfo = {
user_id: _bot.uin,
nickname
}
let forwardMsg = [
{
...userInfo,
message: title
},
{
...userInfo,
message: msg
}
]
if (end) {
forwardMsg.push({
...userInfo,
message: end
})
}
/** 制作转发内容 */
if (this.e.group?.makeForwardMsg) {
forwardMsg = await this.e.group.makeForwardMsg(forwardMsg)
} else if (this.e?.friend?.makeForwardMsg) {
forwardMsg = await this.e.friend.makeForwardMsg(forwardMsg)
} else {
return msg.join('\n')
}
let dec = 'chatgpt-plugin 更新日志'
/** 处理描述 */
if (typeof (forwardMsg.data) === 'object') {
let detail = forwardMsg.data?.meta?.detail
if (detail) {
detail.news = [{ text: dec }]
}
} else {
forwardMsg.data = forwardMsg.data
.replace(/\n/g, '')
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
.replace(/___+/, `<title color="#777777" size="26">${dec}</title>`)
}
return forwardMsg
}
/**
* 检查是否安装pnpm
* @returns {Promise<string>} 返回 'pnpm' 'npm'
*/
async checkPnpm () {
let npm = 'npm'
let ret = await this.execSync('pnpm -v')
if (ret.stdout) npm = 'pnpm'
return npm
}
/**
* 处理更新失败的相关函数
* @param {string} err
* @param {string} stdout
* @returns
*/
async gitErr (err, stdout) {
let msg = '更新失败!'
let errMsg = err.toString()
stdout = stdout.toString()
if (errMsg.includes('Timed out')) {
let remote = errMsg.match(/'(.+?)'/g)[0].replace(/'/g, '')
await this.reply(msg + `\n连接超时:${remote}`)
return
}
if (/Failed to connect|unable to access/g.test(errMsg)) {
let remote = errMsg.match(/'(.+?)'/g)[0].replace(/'/g, '')
await this.reply(msg + `\n连接失败:${remote}`)
return
}
if (errMsg.includes('be overwritten by merge')) {
await this.reply(
msg +
`存在冲突:\n${errMsg}\n` +
'请解决冲突后再更新,或者执行#强制更新,放弃本地修改'
)
return
}
if (stdout.includes('CONFLICT')) {
await this.reply([
msg + '存在冲突\n',
errMsg,
stdout,
'\n请解决冲突后再更新或者执行#强制更新,放弃本地修改'
])
return
}
await this.reply([errMsg, stdout])
}
/**
* 异步执行git相关命令
* @param {string} cmd git命令
* @returns
*/
async execSync (cmd) {
return new Promise((resolve, reject) => {
exec(cmd, { windowsHide: true }, (error, stdout, stderr) => {
resolve({ error, stdout, stderr })
})
})
}
/**
* 检查git是否安装
* @returns
*/
async checkGit () {
let ret = await execSync('git --version', { encoding: 'utf-8' })
if (!ret || !ret.includes('git version')) {
await this.reply('请先安装git')
return false
}
return true
}
}

View file

@ -186,7 +186,7 @@ export async function toYunzai (e, contents) {
for (let content of contents) { for (let content of contents) {
switch (content.type) { switch (content.type) {
case 'text': { case 'text': {
msgs.push((/** @type {import('chaite').TextContent} **/ content).text) msgs.push((/** @type {import('chaite').TextContent} **/ content).text?.trim() || '')
break break
} }
case 'image': { case 'image': {
@ -208,6 +208,6 @@ export async function toYunzai (e, contents) {
} }
} }
return { return {
msgs, forward msgs: msgs.filter(i => !!i), forward
} }
} }