mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 13:27:08 +00:00
添加图片识别功能 (#191)
* 修复引用转发,默认bing模式并发 * 开启stream增加稳定性 * fix: remove queue element only in non-bing mode * 使用chatgpt-api自带的超时逻辑,文字过多时启动切换到图片输出防止被吞 * Update chat.js * 添加Bing专用的图片输出样式 * 添加chatgpt的新图片模式,临时处理切换api导致的对话异常 * 修改bing样式表 * 为图片添加外部页面缓存 * 为图片模式添加MathJax * feat: add switch for qrcode * 防止script攻击 * 修复网页模板错误 * 修复bing页面引用错误 * 缓存服务器异常时处理 * 添加默认配置加载 * 修复配置文件路径错误 * 删除重复的模板文件,修复二维码地址错误 * 修正图片渲染错误 * 修复引用渲染错误 * 二维码网址统一改为使用本地配置 * 添加关闭思考提示的配置项 * 修复在Windows上无法载入配置文件的问题 * 修复关闭qr的情况下渲染错误 * 改为使用base64传递返回数据 * 当异常过多时使用图片输出 * 添加锅巴面板配置支持 * 补充遗漏的默认配置 * 修复qr模式下引用未被传递的问题 * 修复未将引用数据传输给缓存服务器的问题 * 删除无用的bingTimeoutMs配置项 * 添加消息队列超时弹出 * 优化图片模式处理,解决对话队列卡住的问题 * 添加对图片ocr的支持 * 添加图片识别配置项 * 添加黑名单配置项 --------- Co-authored-by: ikechan8370 <geyinchibuaa@gmail.com>
This commit is contained in:
parent
7192a8c6fa
commit
1247aef5bb
4 changed files with 58 additions and 1 deletions
34
apps/chat.js
34
apps/chat.js
|
|
@ -267,6 +267,40 @@ export class chatgpt extends plugin {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (Config.imgOcr) {
|
||||||
|
// 取消息中的图片、at的头像、回复的图片,放入e.img
|
||||||
|
if (e.at && !e.source) {
|
||||||
|
e.img = [`https://q1.qlogo.cn/g?b=qq&s=0&nk=${e.at}`];
|
||||||
|
}
|
||||||
|
if (e.source) {
|
||||||
|
let reply;
|
||||||
|
if (e.isGroup) {
|
||||||
|
reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message;
|
||||||
|
} else {
|
||||||
|
reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message;
|
||||||
|
}
|
||||||
|
if (reply) {
|
||||||
|
for (let val of reply) {
|
||||||
|
if (val.type == "image") {
|
||||||
|
e.img = [val.url];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e.img) {
|
||||||
|
try {
|
||||||
|
const imgorc = await Bot.imageOcr(e.img[0])
|
||||||
|
if (imgorc.language === 'zh' || imgorc.language === 'en') {
|
||||||
|
let imgtext = ''
|
||||||
|
for (let text of imgorc.wordslist) {
|
||||||
|
imgtext += `${text.words}\n`
|
||||||
|
}
|
||||||
|
prompt = imgtext + prompt
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
// 检索是否有屏蔽词
|
// 检索是否有屏蔽词
|
||||||
const promtBlockWord = promptBlockWords.find(word => prompt.toLowerCase().includes(word.toLowerCase()))
|
const promtBlockWord = promptBlockWords.find(word => prompt.toLowerCase().includes(word.toLowerCase()))
|
||||||
if (promtBlockWord) {
|
if (promtBlockWord) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ export default {
|
||||||
// blockWords: ['屏蔽词1', '屏蔽词b'],
|
// blockWords: ['屏蔽词1', '屏蔽词b'],
|
||||||
// 问题中如果触发屏蔽词,也会拒绝回答
|
// 问题中如果触发屏蔽词,也会拒绝回答
|
||||||
// promptBlockWords: ['屏蔽词1', '屏蔽词b'],
|
// promptBlockWords: ['屏蔽词1', '屏蔽词b'],
|
||||||
|
// imgOcr: true,
|
||||||
// 改为true后,全局默认以图片形式回复,并自动发出Continue命令补全回答。长回复可能会有bug。
|
// 改为true后,全局默认以图片形式回复,并自动发出Continue命令补全回答。长回复可能会有bug。
|
||||||
// defaultUsePicture: false,
|
// defaultUsePicture: false,
|
||||||
// 如果true,字数大于阈值(autoUsePictureThreshold)会自动用图片发送,即使是文本模式。
|
// 如果true,字数大于阈值(autoUsePictureThreshold)会自动用图片发送,即使是文本模式。
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,24 @@ export function supportGuoba() {
|
||||||
configInfo: {
|
configInfo: {
|
||||||
// 配置项 schemas
|
// 配置项 schemas
|
||||||
schemas: [
|
schemas: [
|
||||||
|
{
|
||||||
|
field: 'blockWords',
|
||||||
|
label: '输出黑名单',
|
||||||
|
bottomHelpMessage: '检查输出结果中是否有违禁词,如果存在黑名单中的违禁词则不输出',
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'promptBlockWords',
|
||||||
|
label: '输入黑名单',
|
||||||
|
bottomHelpMessage: '检查输入结果中是否有违禁词,如果存在黑名单中的违禁词则不输出',
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'imgOcr',
|
||||||
|
label: '图片识别',
|
||||||
|
bottomHelpMessage: '是否识别消息中图片的文字内容,需要同时包含图片和消息才生效',
|
||||||
|
component: 'Switch',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'defaultUsePicture',
|
field: 'defaultUsePicture',
|
||||||
label: '全局图片模式',
|
label: '全局图片模式',
|
||||||
|
|
@ -241,6 +259,9 @@ export function supportGuoba() {
|
||||||
// 设置配置的方法(前端点确定后调用的方法)
|
// 设置配置的方法(前端点确定后调用的方法)
|
||||||
setConfigData(data, {Result}) {
|
setConfigData(data, {Result}) {
|
||||||
for (let [keyPath, value] of Object.entries(data)) {
|
for (let [keyPath, value] of Object.entries(data)) {
|
||||||
|
// 处理黑名单
|
||||||
|
if (keyPath === 'blockWords' || keyPath === 'promptBlockWords')
|
||||||
|
value = value.toString().split(/[,,;;\|]/)
|
||||||
if (Config[keyPath] != value)
|
if (Config[keyPath] != value)
|
||||||
Config[keyPath] = value
|
Config[keyPath] = value
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import lodash from 'lodash'
|
||||||
const defaultConfig = {
|
const defaultConfig = {
|
||||||
blockWords: ['屏蔽词1', '屏蔽词b'],
|
blockWords: ['屏蔽词1', '屏蔽词b'],
|
||||||
promptBlockWords: ['屏蔽词1', '屏蔽词b'],
|
promptBlockWords: ['屏蔽词1', '屏蔽词b'],
|
||||||
|
imgOcr: true,
|
||||||
defaultUsePicture: false,
|
defaultUsePicture: false,
|
||||||
autoUsePicture: true,
|
autoUsePicture: true,
|
||||||
autoUsePictureThreshold: 1200,
|
autoUsePictureThreshold: 1200,
|
||||||
|
|
@ -47,7 +48,7 @@ export const Config = new Proxy(config, {
|
||||||
target[property] = value;
|
target[property] = value;
|
||||||
const change = lodash.transform(target, function(result, value, key) {
|
const change = lodash.transform(target, function(result, value, key) {
|
||||||
if (!lodash.isEqual(value, defaultConfig[key])) {
|
if (!lodash.isEqual(value, defaultConfig[key])) {
|
||||||
result[key] = (lodash.isObject(value) && lodash.isObject(defaultConfig[key])) ? changes(value, defaultConfig[key]) : value;
|
result[key] = value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue