feat: refine terminal ai assistant settings (#12315)

This commit is contained in:
ssongliu
2026-03-24 09:10:07 +00:00
committed by GitHub
parent 2cb2058cfa
commit 6fb41dc711
14 changed files with 97 additions and 225 deletions
+4 -7
View File
@@ -1395,18 +1395,15 @@ const message = {
cursorBar: 'Bar',
scrollback: 'Scrollback',
scrollSensitivity: 'Scroll Sensitivity',
aiStatus: 'AI Terminal',
aiSettings: 'AI Terminal Settings',
aiAssistant: 'AI Assistant',
aiAccountHelper:
'Use the selected model account to generate and fill commands. For local models like Ollama and vLLM, use a custom model account.',
aiAccountRequired: 'Please select an available AI account first.',
aiPrefix: 'Trigger Prefix',
aiPrefixHelper: 'Enter this prefix and press Enter to trigger AI command generation.',
aiPrefixHelper:
'Enter the specified prefix and press Enter to trigger AI command generation, for example: {0} help me check disk usage.',
aiRiskCommands: 'Risk Command Interception',
aiRiskCommandsHelper:
'Generated commands matching any of these fragments will be blocked and filled back as comments. Leave empty to disable interception. Supports add, edit, and delete.',
aiAddRiskCommand: 'Add Risk Command',
aiRemoveRiskCommand: 'Delete',
'Configure risky commands to intercept, one per line. When matched, generation will be blocked and filled back as comments.',
aiSummary: 'When a line starts with the {0} prefix and you press Enter, AI command generation is triggered.',
aiPrefixAsciiVisible:
'Only ASCII visible characters are supported. Spaces, CJK characters, and full-width symbols are not allowed.',
+4 -6
View File
@@ -1434,17 +1434,15 @@ const message = {
cursorBar: 'Barra',
scrollback: 'Scrollback',
scrollSensitivity: 'Sensibilidad de scroll',
aiStatus: 'Terminal de IA',
aiSettings: 'Configuración del terminal de IA',
aiAssistant: 'Asistente de IA',
aiAccountHelper:
'Use la cuenta de modelo seleccionada para generar y rellenar comandos. Para modelos locales como Ollama y vLLM, use una cuenta de modelo personalizada.',
aiPrefix: 'Prefijo de activación',
aiPrefixHelper: 'Introduzca este prefijo y pulse Enter para activar la generación de comandos por IA.',
aiPrefixHelper:
'Introduzca el prefijo indicado y pulse Enter para activar la generación de comandos por IA; por ejemplo: {0} ayúdame a consultar la información del disco.',
aiRiskCommands: 'Intercepción de comandos de riesgo',
aiRiskCommandsHelper:
'Los comandos generados que coincidan con cualquiera de estos fragmentos se bloquearán y se devolverán como comentarios. Déjelo vacío para desactivar la intercepción. Admite añadir, editar y eliminar.',
aiAddRiskCommand: 'Añadir comando de riesgo',
aiRemoveRiskCommand: 'Eliminar',
'Configure los comandos de riesgo que se deben interceptar, uno por línea. Si coinciden, se bloqueará la generación y se devolverán como comentarios.',
aiSummary:
'Cuando una línea comienza con el prefijo {0} y pulsa Enter, se activa la generación de comandos por IA.',
aiPrefixAsciiVisible:
+4 -6
View File
@@ -1405,17 +1405,15 @@ const message = {
cursorBar: 'バー',
scrollback: 'スクロールバック',
scrollSensitivity: 'スクロール感度',
aiStatus: 'AI ターミナル',
aiSettings: 'AI ターミナル設定',
aiAssistant: 'AI アシスタント',
aiAccountHelper:
'選択したモデルアカウントでコマンドを生成して補完しますOllama vLLM などのローカルモデルはカスタムモデルアカウントを使用してください',
aiPrefix: 'トリガープレフィックス',
aiPrefixHelper: 'このプレフィックスを入力して Enter を押すとAI コマンド生成がトリガーされます',
aiPrefixHelper:
'指定したプレフィックスを入力して Enter を押すとAI コマンド生成がトリガーされます: {0} ディスク情報を確認して',
aiRiskCommands: '危険コマンドの遮断',
aiRiskCommandsHelper:
'これらの断片のいずれかに一致する生成コマンドはブロックされコメントとして埋め戻されます空欄にすると遮断を無効化できます追加編集削除に対応しています',
aiAddRiskCommand: '危険コマンドを追加',
aiRemoveRiskCommand: '削除',
'ブロック対象の危険コマンドを設定します1 行に 1 一致した場合生成を停止しコメントとして埋め戻します',
aiSummary: '行が {0} プレフィックスで始まり Enter を押すとAI コマンド生成がトリガーされます',
aiPrefixAsciiVisible: 'ASCII の表示可能文字のみ対応していますスペースCJK 文字全角記号は使用できません',
saveHelper: '現在のターミナル設定を保存してもよろしいですか',
+4 -6
View File
@@ -1379,17 +1379,15 @@ const message = {
cursorBar: '막대',
scrollback: '스크롤백',
scrollSensitivity: '스크롤 감도',
aiStatus: 'AI 터미널',
aiSettings: 'AI 터미널 설정',
aiAssistant: 'AI 도우미',
aiAccountHelper:
'선택한 모델 계정으로 명령을 생성하고 채웁니다. Ollama, vLLM 같은 로컬 모델은 사용자 지정 모델 계정을 사용하세요.',
aiPrefix: '트리거 접두사',
aiPrefixHelper: ' 접두사를 입력하고 Enter를 누르면 AI 명령 생성이 트리거됩니다.',
aiPrefixHelper:
'지정한 접두사를 입력하고 Enter를 누르면 AI 명령 생성이 시작됩니다. : {0} 디스크 정보를 조회해줘.',
aiRiskCommands: '위험 명령 차단',
aiRiskCommandsHelper:
' 조각들 하나와 일치하는 생성 명령은 차단되고 주석으로 다시 채워집니다. 비워 두면 차단이 비활성화됩니다. 추가, 수정, 삭제를 지원합니다.',
aiAddRiskCommand: '위험 명령 추가',
aiRemoveRiskCommand: '삭제',
'차단할 위험 명령을 설정하세요( 줄에 하나씩). 일치하면 생성이 차단되고 주석으로 다시 채워집니다.',
aiSummary: '{0} 접두사로 시작하는 줄에서 Enter를 누르면 AI 명령 생성이 트리거됩니다.',
aiPrefixAsciiVisible: 'ASCII 표시 가능 문자만 지원합니다. 공백, CJK 문자 전각 기호는 사용할 없습니다.',
saveHelper: '현재 터미널 설정을 저장하시겠습니까?',
+4 -6
View File
@@ -1419,17 +1419,15 @@ const message = {
cursorBar: 'Bar',
scrollback: 'Skrol balik',
scrollSensitivity: 'Kepekaan skrol',
aiStatus: 'Terminal AI',
aiSettings: 'Tetapan terminal AI',
aiAssistant: 'Pembantu AI',
aiAccountHelper:
'Gunakan akaun model yang dipilih untuk menjana dan mengisi arahan. Untuk model tempatan seperti Ollama dan vLLM, gunakan akaun model tersuai.',
aiPrefix: 'Awalan pencetus',
aiPrefixHelper: 'Masukkan awalan ini dan tekan Enter untuk mencetuskan penjanaan arahan AI.',
aiPrefixHelper:
'Masukkan awalan yang ditetapkan dan tekan Enter untuk mencetuskan penjanaan arahan AI, contohnya: {0} bantu saya semak maklumat cakera.',
aiRiskCommands: 'Pencegatan arahan berisiko',
aiRiskCommandsHelper:
'Arahan yang dijana dan sepadan dengan mana-mana fragmen ini akan disekat dan diisi semula sebagai komen. Biarkan kosong untuk mematikan pencegatan. Menyokong tambah, ubah suai dan padam.',
aiAddRiskCommand: 'Tambah arahan berisiko',
aiRemoveRiskCommand: 'Padam',
'Konfigurasikan arahan berisiko yang perlu dipintas, satu bagi setiap baris. Apabila sepadan, penjanaan akan disekat dan diisi semula sebagai komen.',
aiSummary:
'Apabila baris bermula dengan awalan {0} dan anda menekan Enter, penjanaan arahan AI akan dicetuskan.',
aiPrefixAsciiVisible:
+4 -6
View File
@@ -1427,17 +1427,15 @@ const message = {
cursorBar: 'Barra',
scrollback: 'Scrollback',
scrollSensitivity: 'Sensibilidade de rolagem',
aiStatus: 'Terminal de IA',
aiSettings: 'Configurações do terminal de IA',
aiAssistant: 'Assistente de IA',
aiAccountHelper:
'Use a conta de modelo selecionada para gerar e preencher comandos. Para modelos locais como Ollama e vLLM, use uma conta de modelo personalizada.',
aiPrefix: 'Prefixo de disparo',
aiPrefixHelper: 'Digite este prefixo e pressione Enter para acionar a geração de comandos por IA.',
aiPrefixHelper:
'Digite o prefixo especificado e pressione Enter para acionar a geração de comandos por IA, por exemplo: {0} me ajude a consultar as informações do disco.',
aiRiskCommands: 'Intercepção de comandos de risco',
aiRiskCommandsHelper:
'Os comandos gerados que corresponderem a qualquer um destes fragmentos serão bloqueados e preenchidos de volta como comentários. Deixe em branco para desativar a intercepção. Suporta adicionar, editar e excluir.',
aiAddRiskCommand: 'Adicionar comando de risco',
aiRemoveRiskCommand: 'Excluir',
'Configure os comandos de risco que devem ser interceptados, um por linha. Quando houver correspondência, a geração será bloqueada e preenchida de volta como comentário.',
aiSummary:
'Quando uma linha começa com o prefixo {0} e você pressiona Enter, a geração de comandos por IA é acionada.',
aiPrefixAsciiVisible:
+4 -6
View File
@@ -1412,17 +1412,15 @@ const message = {
cursorBar: 'Полоса',
scrollback: 'Буфер прокрутки',
scrollSensitivity: 'Чувствительность прокрутки',
aiStatus: 'AI-терминал',
aiSettings: 'Настройки AI-терминала',
aiAssistant: 'AI-помощник',
aiAccountHelper:
'Используйте выбранный модельный аккаунт для генерации и подстановки команд. Для локальных моделей, таких как Ollama и vLLM, используйте пользовательский модельный аккаунт.',
aiPrefix: 'Префикс запуска',
aiPrefixHelper: 'Введите этот префикс и нажмите Enter, чтобы запустить генерацию команд ИИ.',
aiPrefixHelper:
'Введите указанный префикс и нажмите Enter, чтобы запустить генерацию команд ИИ, например: {0} помоги мне показать информацию о диске.',
aiRiskCommands: 'Перехват опасных команд',
aiRiskCommandsHelper:
'Сгенерированные команды, совпадающие с любым из этих фрагментов, будут заблокированы и подставлены обратно в виде комментариев. Оставьте пустым, чтобы отключить перехват. Поддерживаются добавление, редактирование и удаление.',
aiAddRiskCommand: 'Добавить опасную команду',
aiRemoveRiskCommand: 'Удалить',
'Настройте опасные команды для перехвата, по одной в каждой строке. При совпадении генерация будет заблокирована, а команда подставлена обратно в виде комментария.',
aiSummary: 'Когда строка начинается с префикса {0} и вы нажимаете Enter, запускается генерация команд ИИ.',
aiPrefixAsciiVisible:
'Поддерживаются только видимые символы ASCII. Пробелы, символы CJK и полноширинные знаки не допускаются.',
+4 -6
View File
@@ -1416,17 +1416,15 @@ const message = {
cursorBar: 'Çubuk',
scrollback: 'Geri Kaydırma',
scrollSensitivity: 'Kaydırma Hassasiyeti',
aiStatus: 'AI Terminali',
aiSettings: 'AI terminal ayarları',
aiAssistant: 'AI Asistani',
aiAccountHelper:
'Komut üretmek ve doldurmak için seçili model hesabını kullanın. Ollama ve vLLM gibi yerel modeller için özel model hesabı kullanın.',
aiPrefix: 'Tetikleme öneki',
aiPrefixHelper: 'Bu öneki girip Enter tuşuna bastığınızda AI komut üretimi tetiklenir.',
aiPrefixHelper:
'Belirtilen öneki girip Enter tuşuna bastığınızda AI komut üretimi tetiklenir; örneğin: {0} disk bilgisini sorgulamama yardım et.',
aiRiskCommands: 'Riskli komut engelleme',
aiRiskCommandsHelper:
'Bu parçalardan herhangi biriyle eşleşen üretilmiş komutlar engellenir ve yorum olarak geri doldurulur. Engellemeyi kapatmak için boş bırakın. Ekleme, düzenleme ve silme desteklenir.',
aiAddRiskCommand: 'Riskli komut ekle',
aiRemoveRiskCommand: 'Sil',
'Engellenecek riskli komutlari yapılandırın, her satıra bir tane gelecek şekilde. Eşleşme olduğunda üretim durdurulur ve yorum olarak geri doldurulur.',
aiSummary: 'Bir satır {0} önekiyle başladığında ve Enter tuşuna bastığınızda AI komut üretimi tetiklenir.',
aiPrefixAsciiVisible:
'Yalnızca görünür ASCII karakterleri desteklenir. Boşluklara, CJK karakterlerine ve tam genişlikli sembollere izin verilmez.',
+3 -6
View File
@@ -1317,15 +1317,12 @@ const message = {
cursorBar: '條形',
scrollback: '滾動行數',
scrollSensitivity: '滾動速度',
aiStatus: 'AI 終端',
aiSettings: 'AI 終端設定',
aiAssistant: 'AI 助手',
aiAccountHelper: '使用所選模型帳號生成並回填命令OllamavLLM 本地模型請使用自訂模型帳號',
aiPrefix: '觸發前綴',
aiPrefixHelper: '輸入前綴並按下 Enter 將觸發 AI 指令生成',
aiPrefixHelper: '輸入指定前綴並按下 Enter 將觸發 AI 指令生成例如{0} 幫我查詢磁碟資訊',
aiRiskCommands: '風險命令攔截',
aiRiskCommandsHelper: '命中以下片段的生成命令會被攔截並以註解形式回填留空表示不攔截支援增刪改',
aiAddRiskCommand: '新增風險命令',
aiRemoveRiskCommand: '刪除',
aiRiskCommandsHelper: '配置需攔截的風險命令每行一條命中後將阻止生成並以註解回填',
aiSummary: ' {0} 前綴開頭並按下 Enter 會觸發 AI 命令生成',
aiPrefixAsciiVisible: '僅支援 ASCII 可見字元不支援空格中文或全形符號',
saveHelper: '是否確認儲存目前終端設定',
+3 -6
View File
@@ -1326,15 +1326,12 @@ const message = {
cursorBar: '条形',
scrollback: '滚动行数',
scrollSensitivity: '滚动速度',
aiStatus: 'AI 终端',
aiSettings: 'AI 终端设置',
aiAssistant: 'AI 助手',
aiAccountHelper: '使用所选模型账号生成并回填命令OllamavLLM 本地模型请用自定义模型账号',
aiPrefix: '触发前缀',
aiPrefixHelper: '输入前缀并按回车后将触发 AI 命令生成',
aiPrefixHelper: '输入指定前缀并按回车后将触发 AI 命令生成例如{0} 帮我查询磁盘信息',
aiRiskCommands: '风险命令拦截',
aiRiskCommandsHelper: '命中以下片段的生成命令会被拦截并以注释形式回填留空表示不拦截支持增删改',
aiAddRiskCommand: '新增风险命令',
aiRemoveRiskCommand: '删除',
aiRiskCommandsHelper: '配置需拦截的风险命令每行一条命中后将阻止生成并以注释回填',
aiSummary: ' {0} 前缀开头并回车时会触发 AI 命令生成',
aiPrefixAsciiVisible: '仅支持 ASCII 可见字符不支持空格中文或全角符号',
saveHelper: '是否确认保存当前终端配置',
@@ -12,7 +12,10 @@ export const parseRiskCommands = (value: string): string[] => {
}
return parsed.map((item) => String(item).trim()).filter((item) => item.length > 0);
} catch {
return [];
return value
.split(/\r?\n/)
.map((item) => String(item).trim())
.filter((item) => item.length > 0);
}
};
@@ -29,3 +32,7 @@ export const normalizeRiskCommands = (riskCommands: string[]): string[] => {
}
return result;
};
export const formatRiskCommandsText = (riskCommands: string[]): string => {
return normalizeRiskCommands(riskCommands).join('\n');
};
+46 -119
View File
@@ -1,18 +1,12 @@
<template>
<el-form-item :label="$t('terminal.aiSettings')">
<el-input :value="aiSummary" disabled>
<template #append>
<el-button @click="openDrawer" icon="Setting">
{{ $t('commons.button.set') }}
</el-button>
</template>
</el-input>
</el-form-item>
<el-button @click="openDrawer" type="primary">
{{ $t('terminal.aiAssistant') }}
</el-button>
<DrawerPro v-model="drawerVisible" :header="$t('terminal.aiSettings')" size="60%" @close="handleClose">
<DrawerPro v-model="drawerVisible" :header="$t('terminal.aiAssistant')" size="60%" @close="handleClose">
<div v-loading="loading">
<el-form ref="formRef" :model="formModel" label-position="top">
<el-form-item :label="$t('terminal.aiStatus')">
<el-form-item :label="$t('terminal.aiAssistant')">
<el-switch v-model="formModel.status" active-value="Enable" inactive-value="Disable" />
</el-form-item>
<el-form-item
@@ -47,20 +41,18 @@
<el-select class="formInput" v-model="formModel.prefix">
<el-option v-for="item in prefixOptions" :key="item" :label="item" :value="item" />
</el-select>
<span class="input-help">{{ $t('terminal.aiPrefixHelper') }}</span>
<span class="input-help">
{{ $t('terminal.aiPrefixHelper', [formModel.prefix || DEFAULT_AI_PREFIX]) }}
</span>
</el-form-item>
<el-form-item :label="$t('terminal.aiRiskCommands')" prop="riskCommands" :rules="riskCommandRules">
<div class="risk-command-list">
<div class="risk-command-item" v-for="(command, index) in formModel.riskCommands" :key="index">
<el-input :model-value="command" @update:model-value="updateRiskCommand(index, $event)" />
<el-button link type="danger" @click="removeRiskCommand(index)">
{{ $t('terminal.aiRemoveRiskCommand') }}
</el-button>
</div>
<div class="risk-command-actions">
<el-button plain @click="addRiskCommand">{{ $t('terminal.aiAddRiskCommand') }}</el-button>
</div>
</div>
<el-form-item :label="$t('terminal.aiRiskCommands')">
<CodemirrorPro
v-model="formModel.riskCommands"
mode="shell"
line-wrapping
:height-diff="560"
:min-height="180"
></CodemirrorPro>
<span class="input-help">{{ $t('terminal.aiRiskCommandsHelper') }}</span>
</el-form-item>
</el-form>
@@ -78,14 +70,21 @@
</template>
<script lang="ts" setup>
import { computed, nextTick, reactive, ref, watch } from 'vue';
import { nextTick, reactive, ref } from 'vue';
import type { ElForm } from 'element-plus';
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { pageAgentAccounts } from '@/api/modules/ai';
import { updateAgentTerminalAIInfo } from '@/api/modules/setting';
import { getAgentTerminalAIInfo, updateAgentTerminalAIInfo } from '@/api/modules/setting';
import { MsgSuccess } from '@/utils/message';
import { AI_PREFIX_OPTIONS, DEFAULT_AI_PREFIX, normalizeRiskCommands } from '@/views/terminal/setting/ai/helper';
import {
AI_PREFIX_OPTIONS,
DEFAULT_AI_PREFIX,
formatRiskCommandsText,
normalizeRiskCommands,
parseRiskCommands,
} from '@/views/terminal/setting/ai/helper';
interface AgentAccountOption {
id: number | string;
@@ -95,63 +94,37 @@ interface AgentAccountOption {
verified?: boolean;
}
const props = defineProps<{
status: string;
accountId: string;
prefix: string;
riskCommands: string[];
defaultRiskCommands: string[];
}>();
const emit = defineEmits<{
(e: 'refresh'): void;
}>();
type FormInstance = InstanceType<typeof ElForm>;
const formRef = ref<FormInstance>();
const drawerVisible = ref(false);
const loading = ref(false);
const agentAccountOptions = ref<AgentAccountOption[]>([]);
const defaultRiskCommands = ref<string[]>([]);
const prefixOptions = AI_PREFIX_OPTIONS;
const formModel = reactive({
status: props.status,
accountId: props.accountId,
prefix: props.prefix,
riskCommands: [...props.riskCommands],
status: 'Disable',
accountId: '',
prefix: DEFAULT_AI_PREFIX,
riskCommands: '',
});
const syncFormFromProps = () => {
formModel.status = props.status;
formModel.accountId = props.accountId;
formModel.prefix = props.prefix;
formModel.riskCommands = [...props.riskCommands];
const loadTerminalAISettings = async () => {
const res = await getAgentTerminalAIInfo();
formModel.status = res.data.aiStatus || 'Disable';
formModel.accountId = res.data.aiAccountId || '';
formModel.prefix = res.data.aiPrefix || DEFAULT_AI_PREFIX;
formModel.riskCommands = formatRiskCommandsText(parseRiskCommands(res.data.aiRiskCommands || ''));
defaultRiskCommands.value = parseRiskCommands(res.data.aiRiskCommandsDefault || '');
};
const openDrawer = () => {
syncFormFromProps();
loadAgentAccounts();
drawerVisible.value = true;
loading.value = true;
Promise.all([loadTerminalAISettings(), loadAgentAccounts()]).finally(() => {
loading.value = false;
});
};
watch(
() => [props.status, props.accountId, props.prefix, props.riskCommands],
() => {
if (drawerVisible.value) {
return;
}
syncFormFromProps();
},
{ deep: true },
);
const aiSummary = computed(() => {
if (props.status !== 'Enable') {
return i18n.global.t('setting.unSetting');
}
const prefix = String(props.prefix || '').trim();
return i18n.global.t('terminal.aiSummary', [prefix]);
});
const isVerificationSkipped = (provider?: string) => {
const key = (provider || '').toLowerCase();
return key === 'custom' || key === 'vllm' || key === 'ollama' || key === 'kimi-coding';
@@ -199,37 +172,9 @@ const accountRules = [
},
];
const riskCommandRules = [
{
validator: (_rule, value, callback) => {
const commands = Array.isArray(value) ? value : [];
if (commands.some((item) => String(item ?? '').trim().length === 0)) {
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
return;
}
callback();
},
trigger: 'blur',
},
];
const addRiskCommand = () => {
formModel.riskCommands = [...formModel.riskCommands, ''];
};
const updateRiskCommand = (index: number, value: string) => {
formModel.riskCommands = formModel.riskCommands.map((item, currentIndex) =>
currentIndex === index ? value : item,
);
};
const removeRiskCommand = (index: number) => {
formModel.riskCommands = formModel.riskCommands.filter((_, currentIndex) => currentIndex !== index);
};
const resetRiskCommands = () => {
formModel.prefix = DEFAULT_AI_PREFIX;
formModel.riskCommands = [...props.defaultRiskCommands];
formModel.riskCommands = formatRiskCommandsText(defaultRiskCommands.value);
};
const handleConfirm = async () => {
@@ -248,8 +193,9 @@ const handleConfirm = async () => {
aiStatus: formModel.status,
aiAccountId: formModel.status === 'Enable' ? formModel.accountId : '',
aiPrefix: formModel.prefix.trim() || DEFAULT_AI_PREFIX,
aiRiskCommands: JSON.stringify(normalizeRiskCommands(formModel.riskCommands)),
aiRiskCommands: JSON.stringify(normalizeRiskCommands(parseRiskCommands(formModel.riskCommands))),
});
await loadTerminalAISettings();
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
drawerVisible.value = false;
} finally {
@@ -258,8 +204,7 @@ const handleConfirm = async () => {
};
const handleClose = () => {
syncFormFromProps();
emit('refresh');
formRef.value?.clearValidate();
};
</script>
@@ -268,24 +213,6 @@ const handleClose = () => {
width: 100%;
}
.risk-command-list {
width: 100%;
display: flex;
flex-direction: column;
gap: 8px;
}
.risk-command-actions {
display: flex;
gap: 8px;
}
.risk-command-item {
display: flex;
gap: 8px;
align-items: center;
}
.account-option {
display: flex;
align-items: center;
+1 -38
View File
@@ -114,17 +114,6 @@
<el-divider border-style="dashed" />
<AiSetting
:status="aiForm.aiStatus"
:account-id="aiForm.aiAccountId"
:prefix="aiForm.aiPrefix"
:risk-commands="aiForm.aiRiskCommands"
:default-risk-commands="aiForm.aiRiskCommandsDefault"
@refresh="loadAISettings"
/>
<el-divider border-style="dashed" />
<el-form-item :label="$t('terminal.defaultConn')">
<el-switch v-model="form.showDefaultConn" @change="changeShow" />
</el-form-item>
@@ -158,11 +147,9 @@
<script lang="ts" setup>
import { ref, reactive, watch, onMounted, onBeforeUnmount } from 'vue';
import { getAgentTerminalAIInfo, getTerminalInfo, UpdateTerminalInfo } from '@/api/modules/setting';
import { getTerminalInfo, UpdateTerminalInfo } from '@/api/modules/setting';
import { Terminal } from '@xterm/xterm';
import OperateDialog from '@/views/terminal/setting/default_conn/index.vue';
import AiSetting from '@/views/terminal/setting/ai/index.vue';
import { DEFAULT_AI_PREFIX, parseRiskCommands } from '@/views/terminal/setting/ai/helper';
import '@xterm/xterm/css/xterm.css';
import { FitAddon } from '@xterm/addon-fit';
import i18n from '@/lang';
@@ -208,14 +195,6 @@ const form = reactive({
showDefaultConn: false,
defaultConn: '',
});
const aiForm = reactive({
aiStatus: 'Disable',
aiAccountId: '',
aiPrefix: '',
aiRiskCommands: [],
aiRiskCommandsDefault: [],
});
const resetConn = ref(false);
const opRef = ref();
@@ -252,7 +231,6 @@ watch(
const acceptParams = () => {
search(true);
loadAISettings();
loadConnShow();
iniTerm();
};
@@ -298,21 +276,6 @@ const search = async (withReset?: boolean) => {
});
};
const loadAISettings = async () => {
loading.value = true;
await getAgentTerminalAIInfo()
.then((res) => {
aiForm.aiStatus = res.data.aiStatus || 'Disable';
aiForm.aiAccountId = res.data.aiAccountId || '';
aiForm.aiPrefix = res.data.aiPrefix || DEFAULT_AI_PREFIX;
aiForm.aiRiskCommands = parseRiskCommands(res.data.aiRiskCommands || '');
aiForm.aiRiskCommandsDefault = parseRiskCommands(res.data.aiRiskCommandsDefault || '');
})
.finally(() => {
loading.value = false;
});
};
const loadConnShow = async () => {
await loadLocalConn().then((res) => {
form.showDefaultConn = res.data.localSSHConnShow === 'Enable';
@@ -110,12 +110,9 @@
</div>
</transition>
<div class="flex items-center gap-3 w-full py-2 flex-wrap">
<el-button
@click="cmdPanelVisible = !cmdPanelVisible"
type="primary"
class="min-w-[120px] max-w-[150px] shrink-0"
>
<div class="flex items-center gap-2 w-full py-2 flex-wrap">
<AiSetting v-if="!mobile" class="shrink-0" />
<el-button @click="cmdPanelVisible = !cmdPanelVisible" class="min-w-[120px] max-w-[150px] shrink-0">
{{ $t('terminal.quickCommand') }}
<el-icon class="ml-1">
<component :is="cmdPanelVisible ? 'ArrowUp' : 'ArrowDown'" />
@@ -283,6 +280,7 @@ import { GlobalStore } from '@/store';
import router from '@/routers';
import { getCommandTree } from '@/api/modules/command';
import { getAgentSettingByKey } from '@/api/modules/setting';
import AiSetting from '@/views/terminal/setting/ai/index.vue';
const dialogRef = ref();
const ctx = getCurrentInstance() as any;