mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-11 18:42:54 +00:00
perf: 支持自定义AI个人提示词
This commit is contained in:
parent
65e75f974d
commit
df917001d3
@ -19,6 +19,7 @@ use App\Models\AbstractModel;
|
|||||||
use App\Models\WebSocketDialog;
|
use App\Models\WebSocketDialog;
|
||||||
use App\Models\WebSocketDialogMsg;
|
use App\Models\WebSocketDialogMsg;
|
||||||
use App\Models\WebSocketDialogUser;
|
use App\Models\WebSocketDialogUser;
|
||||||
|
use App\Models\WebSocketDialogConfig;
|
||||||
use App\Models\WebSocketDialogMsgRead;
|
use App\Models\WebSocketDialogMsgRead;
|
||||||
use App\Models\WebSocketDialogMsgTodo;
|
use App\Models\WebSocketDialogMsgTodo;
|
||||||
use App\Models\WebSocketDialogMsgTranslate;
|
use App\Models\WebSocketDialogMsgTranslate;
|
||||||
@ -2771,4 +2772,86 @@ class DialogController extends AbstractController
|
|||||||
'list' => Extranet::sticker($key)
|
'list' => Extranet::sticker($key)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/dialog/config 57. 获取会话配置
|
||||||
|
*
|
||||||
|
* @apiDescription 需要token身份
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup dialog
|
||||||
|
* @apiName config
|
||||||
|
*
|
||||||
|
* @apiParam {Number} dialog_id 对话ID
|
||||||
|
* @apiParam {String} type 配置类型
|
||||||
|
*
|
||||||
|
* @apiSuccess {String} value 配置值
|
||||||
|
*/
|
||||||
|
public function config()
|
||||||
|
{
|
||||||
|
$user = User::auth();
|
||||||
|
|
||||||
|
$dialog_id = intval(Request::input('dialog_id'));
|
||||||
|
$type = Request::input('type');
|
||||||
|
|
||||||
|
if (!$dialog_id || !$type) {
|
||||||
|
return Base::retError('参数错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSocketDialog::checkDialog($dialog_id);
|
||||||
|
|
||||||
|
$config = WebSocketDialogConfig::where('dialog_id', $dialog_id)
|
||||||
|
->where('userid', $user->userid)
|
||||||
|
->where('type', $type)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
return Base::retSuccess('success', [
|
||||||
|
'value' => $config?->value
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} api/dialog/config/save 58. 保存会话配置
|
||||||
|
*
|
||||||
|
* @apiDescription 需要token身份
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup dialog
|
||||||
|
* @apiName config__save
|
||||||
|
*
|
||||||
|
* @apiParam {Number} dialog_id 对话ID
|
||||||
|
* @apiParam {String} type 配置类型
|
||||||
|
* @apiParam {String} value 配置值
|
||||||
|
*
|
||||||
|
* @apiSuccess {String} msg 成功提示
|
||||||
|
*/
|
||||||
|
public function config__save()
|
||||||
|
{
|
||||||
|
$user = User::auth();
|
||||||
|
|
||||||
|
$dialog_id = intval(Request::input('dialog_id'));
|
||||||
|
$type = Request::input('type');
|
||||||
|
$value = Request::input('value');
|
||||||
|
|
||||||
|
if (!$dialog_id || !$type) {
|
||||||
|
return Base::retError('参数错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSocketDialog::checkDialog($dialog_id);
|
||||||
|
|
||||||
|
if (WebSocketDialogConfig::updateOrCreate(
|
||||||
|
[
|
||||||
|
'dialog_id' => $dialog_id,
|
||||||
|
'userid' => $user->userid,
|
||||||
|
'type' => $type,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'value' => $value,
|
||||||
|
]
|
||||||
|
)) {
|
||||||
|
WebSocketDialogMsg::sendMsg(null, $dialog_id, 'notice', [
|
||||||
|
'notice' => $value ? ("修改提示词:" . $value) : "取消提示词",
|
||||||
|
], User::userid(), true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Base::retSuccess('保存成功');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,7 @@ class SystemController extends AbstractController
|
|||||||
if (env("SYSTEM_SETTING") == 'disabled') {
|
if (env("SYSTEM_SETTING") == 'disabled') {
|
||||||
return Base::retError('当前环境禁止修改');
|
return Base::retError('当前环境禁止修改');
|
||||||
}
|
}
|
||||||
|
Base::checkClientVersion('0.41.11');
|
||||||
User::auth('admin');
|
User::auth('admin');
|
||||||
$all = Request::input();
|
$all = Request::input();
|
||||||
foreach ($all AS $key => $value) {
|
foreach ($all AS $key => $value) {
|
||||||
@ -296,7 +297,7 @@ class SystemController extends AbstractController
|
|||||||
if (env("SYSTEM_SETTING") == 'disabled') {
|
if (env("SYSTEM_SETTING") == 'disabled') {
|
||||||
return Base::retError('当前环境禁止修改');
|
return Base::retError('当前环境禁止修改');
|
||||||
}
|
}
|
||||||
Base::checkClientVersion('0.40.79');
|
Base::checkClientVersion('0.41.11');
|
||||||
$backup = $setting;
|
$backup = $setting;
|
||||||
$all = Request::input();
|
$all = Request::input();
|
||||||
foreach ($all as $key => $value) {
|
foreach ($all as $key => $value) {
|
||||||
|
|||||||
64
app/Models/WebSocketDialogConfig.php
Normal file
64
app/Models/WebSocketDialogConfig.php
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App\Models\WebSocketDialogConfig
|
||||||
|
*
|
||||||
|
* @property int $id
|
||||||
|
* @property int $dialog_id 对话ID
|
||||||
|
* @property int $userid 用户ID
|
||||||
|
* @property string $type 配置类型
|
||||||
|
* @property string|null $value 配置值
|
||||||
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
|
* @property-read \App\Models\WebSocketDialog|null $dialog
|
||||||
|
* @property-read \App\Models\User|null $user
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelAppend()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelHidden()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel change($array)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig newModelQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig newQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig query()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel remove()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig whereCreatedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig whereDialogId($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig whereId($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig whereType($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig whereUpdatedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig whereUserid($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogConfig whereValue($value)
|
||||||
|
* @mixin \Eloquent
|
||||||
|
*/
|
||||||
|
class WebSocketDialogConfig extends AbstractModel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 可以批量赋值的属性
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'dialog_id',
|
||||||
|
'userid',
|
||||||
|
'type',
|
||||||
|
'value',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取关联的对话
|
||||||
|
*/
|
||||||
|
public function dialog()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(WebSocketDialog::class, 'dialog_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取关联的用户
|
||||||
|
*/
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'userid');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ namespace App\Tasks;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\UserBot;
|
use App\Models\UserBot;
|
||||||
use App\Models\WebSocketDialog;
|
use App\Models\WebSocketDialog;
|
||||||
|
use App\Models\WebSocketDialogConfig;
|
||||||
use App\Models\WebSocketDialogMsg;
|
use App\Models\WebSocketDialogMsg;
|
||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use App\Module\Doo;
|
use App\Module\Doo;
|
||||||
@ -429,8 +430,16 @@ class BotReceiveMsgTask extends AbstractTask
|
|||||||
if (empty($extras['api_key'])) {
|
if (empty($extras['api_key'])) {
|
||||||
$errorContent = '机器人未启用。';
|
$errorContent = '机器人未启用。';
|
||||||
}
|
}
|
||||||
if (in_array($this->client['platform'], ['win', 'mac', 'web']) && !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
|
if (in_array($this->client['platform'], ['win', 'mac', 'web']) && !Base::judgeClientVersion("0.41.11", $this->client['version'])) {
|
||||||
$errorContent = '当前客户端版本低(所需版本≥v0.29.11)。';
|
$errorContent = '当前客户端版本低(所需版本≥v0.41.11)。';
|
||||||
|
}
|
||||||
|
$aiPrompt = WebSocketDialogConfig::where([
|
||||||
|
'dialog_id' => $dialog->id,
|
||||||
|
'userid' => $msg->userid,
|
||||||
|
'type' => 'ai_prompt',
|
||||||
|
])->value('value');
|
||||||
|
if ($aiPrompt) {
|
||||||
|
$extras['system_message'] = $aiPrompt;
|
||||||
}
|
}
|
||||||
$webhookUrl = "{$serverUrl}/ai/chat";
|
$webhookUrl = "{$serverUrl}/ai/chat";
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateWebSocketDialogConfigsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
if (!Schema::hasTable('web_socket_dialog_configs')) {
|
||||||
|
Schema::create('web_socket_dialog_configs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->bigInteger('dialog_id')->unsigned()->index()->comment('对话ID');
|
||||||
|
$table->bigInteger('userid')->unsigned()->index()->comment('用户ID');
|
||||||
|
$table->string('type', 50)->default('')->comment('配置类型');
|
||||||
|
$table->text('value')->nullable()->comment('配置值');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('web_socket_dialog_configs');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -86,6 +86,9 @@
|
|||||||
<EDropdownItem v-if="isManageBot" command="modifyNormal">
|
<EDropdownItem v-if="isManageBot" command="modifyNormal">
|
||||||
<div>{{$L('修改资料')}}</div>
|
<div>{{$L('修改资料')}}</div>
|
||||||
</EDropdownItem>
|
</EDropdownItem>
|
||||||
|
<EDropdownItem v-if="isAiBot" command="modifyAi">
|
||||||
|
<div>{{$L('修改提示词')}}</div>
|
||||||
|
</EDropdownItem>
|
||||||
<EDropdownItem command="openCreate">
|
<EDropdownItem command="openCreate">
|
||||||
<div>{{$L('创建群组')}}</div>
|
<div>{{$L('创建群组')}}</div>
|
||||||
</EDropdownItem>
|
</EDropdownItem>
|
||||||
@ -438,6 +441,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
<!--修改提示词-->
|
||||||
|
<Modal
|
||||||
|
v-model="modifyAiShow"
|
||||||
|
:title="$L('修改提示词')"
|
||||||
|
:mask-closable="false">
|
||||||
|
<Form :model="modifyData" @submit.native.prevent>
|
||||||
|
<FormItem prop="value" style="margin-bottom: 16px">
|
||||||
|
<Input
|
||||||
|
:maxlength="500"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{minRows:3,maxRows:5}"
|
||||||
|
v-model="modifyData.value"
|
||||||
|
:placeholder="$L('例如:你是一个人开发的AI助手')"/>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
<div slot="footer" class="adaption">
|
||||||
|
<Button type="default" @click="modifyAiShow=false">{{$L('取消')}}</Button>
|
||||||
|
<Button type="primary" :loading="modifyLoad > 0" @click="onAiModify">{{$L('保存')}}</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<!-- 转发选择 -->
|
<!-- 转发选择 -->
|
||||||
<UserSelect
|
<UserSelect
|
||||||
ref="forwardSelect"
|
ref="forwardSelect"
|
||||||
@ -759,6 +783,7 @@ export default {
|
|||||||
searchResult: [],
|
searchResult: [],
|
||||||
|
|
||||||
modifyShow: false,
|
modifyShow: false,
|
||||||
|
modifyAiShow: false,
|
||||||
modifyData: {},
|
modifyData: {},
|
||||||
modifyLoad: 0,
|
modifyLoad: 0,
|
||||||
|
|
||||||
@ -1122,6 +1147,14 @@ export default {
|
|||||||
return dialogData.dialog_user && dialogData.dialog_user.userid == dialogData.bot && userIsAdmin
|
return dialogData.dialog_user && dialogData.dialog_user.userid == dialogData.bot && userIsAdmin
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isAiBot() {
|
||||||
|
const {dialogData} = this;
|
||||||
|
if (!dialogData.bot || dialogData.type !== 'user') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return /^ai-(.*?)@bot\.system/.test(dialogData.email)
|
||||||
|
},
|
||||||
|
|
||||||
isMute() {
|
isMute() {
|
||||||
if (this.dialogData.dialog_mute === 'close') {
|
if (this.dialogData.dialog_mute === 'close') {
|
||||||
return !this.userIsAdmin
|
return !this.userIsAdmin
|
||||||
@ -2543,6 +2576,23 @@ export default {
|
|||||||
this.modifyShow = true
|
this.modifyShow = true
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "modifyAi":
|
||||||
|
this.modifyData = {
|
||||||
|
dialog_id: this.dialogData.id,
|
||||||
|
type: 'ai_prompt'
|
||||||
|
}
|
||||||
|
this.modifyLoad++;
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'dialog/config',
|
||||||
|
data: this.modifyData,
|
||||||
|
}).then(({data}) => {
|
||||||
|
this.modifyData.value = data.value
|
||||||
|
}).finally(() => {
|
||||||
|
this.modifyLoad--;
|
||||||
|
})
|
||||||
|
this.modifyAiShow = true
|
||||||
|
break;
|
||||||
|
|
||||||
case "modifyAdmin":
|
case "modifyAdmin":
|
||||||
this.modifyData = {
|
this.modifyData = {
|
||||||
dialog_id: this.dialogData.id,
|
dialog_id: this.dialogData.id,
|
||||||
@ -2712,6 +2762,23 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onAiModify() {
|
||||||
|
this.modifyLoad++;
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'dialog/config/save',
|
||||||
|
data: this.modifyData
|
||||||
|
}).then(({data, msg}) => {
|
||||||
|
$A.messageSuccess(msg);
|
||||||
|
this.$store.dispatch("saveDialog", data);
|
||||||
|
this.modifyAiShow = false;
|
||||||
|
this.modifyData = {};
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError(msg);
|
||||||
|
}).finally(_ => {
|
||||||
|
this.modifyLoad--;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
onForwardBefore() {
|
onForwardBefore() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.forwardData = this.$refs.forwardSelect.formatSelect(this.$refs.forwardSelect.selects);
|
this.forwardData = this.$refs.forwardSelect.formatSelect(this.$refs.forwardSelect.selects);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user