Add agent configuration history

This commit is contained in:
mie
2026-07-07 17:49:34 +08:00
parent 209fd3fbc8
commit 35ec3ba803
24 changed files with 3079 additions and 62 deletions
+46
View File
@@ -81,6 +81,52 @@ export default {
});
}).send();
},
// 获取智能体配置快照列表
getAgentSnapshots(agentId, params, callback) {
RequestService.sendRequest()
.url(`${getServiceUrl()}/agent/${agentId}/snapshots`)
.method('GET')
.data(params)
.success((res) => {
RequestService.clearRequestTime();
callback(res);
})
.networkFail(() => {
RequestService.reAjaxFun(() => {
this.getAgentSnapshots(agentId, params, callback);
});
}).send();
},
// 获取智能体配置快照详情
getAgentSnapshot(agentId, snapshotId, callback) {
RequestService.sendRequest()
.url(`${getServiceUrl()}/agent/${agentId}/snapshots/${snapshotId}`)
.method('GET')
.success((res) => {
RequestService.clearRequestTime();
callback(res);
})
.networkFail(() => {
RequestService.reAjaxFun(() => {
this.getAgentSnapshot(agentId, snapshotId, callback);
});
}).send();
},
// 恢复智能体配置快照
restoreAgentSnapshot(agentId, snapshotId, callback) {
RequestService.sendRequest()
.url(`${getServiceUrl()}/agent/${agentId}/snapshots/${snapshotId}/restore`)
.method('POST')
.success((res) => {
RequestService.clearRequestTime();
callback(res);
})
.networkFail(() => {
RequestService.reAjaxFun(() => {
this.restoreAgentSnapshot(agentId, snapshotId, callback);
});
}).send();
},
// 新增方法:获取智能体模板
getAgentTemplate(callback) { // 移除templateName参数
RequestService.sendRequest()
File diff suppressed because it is too large Load Diff
+55 -1
View File
@@ -806,6 +806,7 @@ export default {
'roleConfig.addTag': 'Add New Tag',
'roleConfig.restartNotice': 'After saving the configuration, you need to restart the device for the new configuration to take effect.',
'roleConfig.saveConfig': 'Save Configuration',
'roleConfig.snapshotHistory': 'History',
'roleConfig.reset': 'Reset',
'roleConfig.agentName': 'Nickname',
'roleConfig.roleTemplate': 'Template',
@@ -863,6 +864,59 @@ export default {
'roleConfig.cannotPlayAudio': 'Cannot play audio',
'roleConfig.audioPlayError': 'Error occurred during audio playback',
'agentSnapshot.title': 'Version History',
'agentSnapshot.empty': 'No versions yet',
'agentSnapshot.version': 'Version',
'agentSnapshot.createdAt': 'Saved At',
'agentSnapshot.source': 'Source',
'agentSnapshot.changedFields': 'Changes',
'agentSnapshot.actions': 'Actions',
'agentSnapshot.view': 'View',
'agentSnapshot.restore': 'Restore',
'agentSnapshot.detailTitle': 'Change Details',
'agentSnapshot.restorePreviewTitle': 'Restore Preview',
'agentSnapshot.confirmRestore': 'Confirm Restore',
'agentSnapshot.before': 'Before',
'agentSnapshot.after': 'After',
'agentSnapshot.emptyValue': 'None',
'agentSnapshot.noChangedContent': 'No changes to display',
'agentSnapshot.restoreConfirm': 'Restore to version #{version}? The current configuration will be saved as a new version first.',
'agentSnapshot.restoreSuccess': 'Version restored',
'agentSnapshot.restoreFailed': 'Failed to restore version',
'agentSnapshot.fetchFailed': 'Failed to fetch versions',
'agentSnapshot.detailFailed': 'Failed to fetch snapshot details',
'agentSnapshot.currentVersion': 'Current Version',
'agentSnapshot.source.config': 'Config Save',
'agentSnapshot.source.current': 'Current Config',
'agentSnapshot.source.restore': 'Before Restore',
'agentSnapshot.field.restore': 'Restore',
'agentSnapshot.field.agentCode': 'Agent Code',
'agentSnapshot.field.agentName': 'Nickname',
'agentSnapshot.field.asrModelId': 'Speech Recognition',
'agentSnapshot.field.vadModelId': 'Voice Detect',
'agentSnapshot.field.llmModelId': 'Main Language Model',
'agentSnapshot.field.slmModelId': 'Small Language Model',
'agentSnapshot.field.vllmModelId': 'Vision Model',
'agentSnapshot.field.ttsModelId': 'Text-to-Speech',
'agentSnapshot.field.ttsVoiceId': 'Voice',
'agentSnapshot.field.ttsLanguage': 'Language',
'agentSnapshot.field.ttsVolume': 'Volume',
'agentSnapshot.field.ttsRate': 'Speed',
'agentSnapshot.field.ttsPitch': 'Pitch',
'agentSnapshot.field.memModelId': 'Memory Model',
'agentSnapshot.field.intentModelId': 'Intent Recognition',
'agentSnapshot.field.chatHistoryConf': 'Chat History',
'agentSnapshot.field.systemPrompt': 'Introduction',
'agentSnapshot.field.summaryMemory': 'Memory',
'agentSnapshot.field.langCode': 'Language Code',
'agentSnapshot.field.language': 'Interaction Language',
'agentSnapshot.field.sort': 'Sort',
'agentSnapshot.field.functions': 'Functions',
'agentSnapshot.field.contextProviders': 'Context Providers',
'agentSnapshot.field.correctWordFileIds': 'Replacement Words',
'agentSnapshot.field.tagNames': 'Tags',
'agentSnapshot.field.tagIds': 'Tag IDs',
// Form field Tooltip descriptions
'roleConfig.tooltip.agentName': 'Set the name of your AI agent for identification and recognition',
'roleConfig.tooltip.roleTemplate': 'Choose from preset role templates to quickly configure your agent\'s basic settings',
@@ -1554,4 +1608,4 @@ export default {
// Header navigation
'header.addressBook': 'Address Book',
}
}
+55 -1
View File
@@ -806,6 +806,7 @@ export default {
'roleConfig.addTag': '添加新标签',
'roleConfig.restartNotice': '保存配置后,需要重启设备,新的配置才会生效。',
'roleConfig.saveConfig': '保存配置',
'roleConfig.snapshotHistory': '历史版本',
'roleConfig.reset': '重置',
'roleConfig.agentName': '助手昵称',
'roleConfig.roleTemplate': '角色模版',
@@ -863,6 +864,59 @@ export default {
'roleConfig.cannotPlayAudio': '无法播放音频',
'roleConfig.audioPlayError': '播放音频过程出错',
'agentSnapshot.title': '历史版本',
'agentSnapshot.empty': '暂无历史版本',
'agentSnapshot.version': '版本',
'agentSnapshot.createdAt': '保存时间',
'agentSnapshot.source': '来源',
'agentSnapshot.changedFields': '变更内容',
'agentSnapshot.actions': '操作',
'agentSnapshot.view': '查看',
'agentSnapshot.restore': '恢复',
'agentSnapshot.detailTitle': '变更详情',
'agentSnapshot.restorePreviewTitle': '恢复确认',
'agentSnapshot.confirmRestore': '确认恢复',
'agentSnapshot.before': '变化前',
'agentSnapshot.after': '变化后',
'agentSnapshot.emptyValue': '无',
'agentSnapshot.noChangedContent': '暂无可展示的变更内容',
'agentSnapshot.restoreConfirm': '确定恢复到版本 #{version} 吗?当前配置会先自动保存为新的历史版本。',
'agentSnapshot.restoreSuccess': '已恢复历史版本',
'agentSnapshot.restoreFailed': '恢复历史版本失败',
'agentSnapshot.fetchFailed': '获取历史版本失败',
'agentSnapshot.detailFailed': '获取快照详情失败',
'agentSnapshot.currentVersion': '当前版本',
'agentSnapshot.source.config': '配置保存',
'agentSnapshot.source.current': '当前配置',
'agentSnapshot.source.restore': '恢复前',
'agentSnapshot.field.restore': '恢复操作',
'agentSnapshot.field.agentCode': '助手编码',
'agentSnapshot.field.agentName': '助手昵称',
'agentSnapshot.field.asrModelId': '语音识别',
'agentSnapshot.field.vadModelId': '语音活动检测',
'agentSnapshot.field.llmModelId': '主语言模型',
'agentSnapshot.field.slmModelId': '小参数模型',
'agentSnapshot.field.vllmModelId': '视觉大模型',
'agentSnapshot.field.ttsModelId': '语音合成',
'agentSnapshot.field.ttsVoiceId': '声音音色',
'agentSnapshot.field.ttsLanguage': '对话语言',
'agentSnapshot.field.ttsVolume': '音量',
'agentSnapshot.field.ttsRate': '语速',
'agentSnapshot.field.ttsPitch': '音调',
'agentSnapshot.field.memModelId': '记忆模式',
'agentSnapshot.field.intentModelId': '意图识别',
'agentSnapshot.field.chatHistoryConf': '聊天记录配置',
'agentSnapshot.field.systemPrompt': '角色介绍',
'agentSnapshot.field.summaryMemory': '记忆',
'agentSnapshot.field.langCode': '语言编码',
'agentSnapshot.field.language': '交互语种',
'agentSnapshot.field.sort': '排序',
'agentSnapshot.field.functions': '功能插件',
'agentSnapshot.field.contextProviders': '上下文源',
'agentSnapshot.field.correctWordFileIds': '替换词',
'agentSnapshot.field.tagNames': '标签',
'agentSnapshot.field.tagIds': '标签ID',
// 表单字段 Tooltip 提示说明
'roleConfig.tooltip.agentName': '设置智能体的名称,用于标识和识别您的AI助手',
'roleConfig.tooltip.roleTemplate': '从预设的角色模板中选择,快速配置智能体的基础设定',
@@ -1551,4 +1605,4 @@ export default {
'addressBookManagement.monthsAgo': '{months}个月前',
'addressBookManagement.yearsAgo': '{years}年前',
}
}
+1
View File
@@ -39,6 +39,7 @@ function formatDateTool(date, fmt) {
const o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'H+': date.getHours(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
+89 -10
View File
@@ -16,6 +16,9 @@
<img loading="lazy" src="@/assets/home/setting-user.png" alt="" />
</div>
<span class="header-title">{{ form.agentName }}</span>
<span v-if="currentVersionNo" class="current-version-tag">
当前版本 #{{ currentVersionNo }}
</span>
</div>
<div class="header-tags">
<el-tag
@@ -45,6 +48,9 @@
<img loading="lazy" src="@/assets/home/info.png" alt="" />
<span>{{ $t("roleConfig.restartNotice") }}</span>
</div>
<el-button class="history-btn" @click="showSnapshotDialog = true">
{{ $t("roleConfig.snapshotHistory") }}
</el-button>
<el-button type="primary" class="save-btn" @click="saveConfig">
{{ $t("roleConfig.saveConfig") }}
</el-button>
@@ -457,6 +463,13 @@
:checked-replacement-word-ids="checkedReplacementWordIds"
@save="handleTtsSettingsSave"
/>
<agent-snapshot-dialog
v-if="$route.query.agentId"
:visible.sync="showSnapshotDialog"
:agent-id="$route.query.agentId"
:current-version-no="currentVersionNo"
@restored="handleSnapshotRestored"
/>
<el-footer>
<version-footer />
</el-footer>
@@ -470,6 +483,7 @@ import RequestService from "@/apis/httpRequest";
import FunctionDialog from "@/components/FunctionDialog.vue";
import ContextProviderDialog from "@/components/ContextProviderDialog.vue";
import TtsAdvancedSettings from "@/components/TtsAdvancedSettings.vue";
import AgentSnapshotDialog from "@/components/AgentSnapshotDialog.vue";
import HeaderBar from "@/components/HeaderBar.vue";
import i18n from "@/i18n";
import featureManager from "@/utils/featureManager";
@@ -477,11 +491,12 @@ import VersionFooter from "@/components/VersionFooter.vue";
export default {
name: "RoleConfigPage",
components: { HeaderBar, FunctionDialog, ContextProviderDialog, TtsAdvancedSettings, VersionFooter },
components: { HeaderBar, FunctionDialog, ContextProviderDialog, TtsAdvancedSettings, AgentSnapshotDialog, VersionFooter },
data() {
return {
showContextProviderDialog: false,
showTtsAdvancedDialog: false,
showSnapshotDialog: false,
ttsSettings: {
volume: 0,
speed: 0,
@@ -529,6 +544,7 @@ export default {
voiceOptions: [],
voiceDetails: {}, // 保存完整的音色信息
showFunctionDialog: false,
currentVersionNo: null,
currentFunctions: [],
currentContextProviders: [],
allFunctions: [],
@@ -555,14 +571,26 @@ export default {
goToHome() {
this.$router.push("/home");
},
async saveConfig() {
try {
await this.handleSaveAgentTags(this.$route.query.agentId);
} catch (error) {
console.error('保存标签失败:', error);
return;
normalizeFunctionParams(params, fallback = {}) {
if (params === null || params === undefined || params === '') {
return { ...fallback };
}
if (typeof params === 'string') {
try {
const parsed = JSON.parse(params);
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
? parsed
: { ...fallback };
} catch (error) {
return { ...fallback };
}
}
if (typeof params === 'object' && !Array.isArray(params)) {
return { ...params };
}
return { ...fallback };
},
async saveConfig() {
const configData = {
agentCode: this.form.agentCode,
agentName: this.form.agentName,
@@ -585,11 +613,12 @@ export default {
functions: this.currentFunctions.map((item) => {
return {
pluginId: item.id,
paramInfo: item.params,
paramInfo: this.normalizeFunctionParams(item.params),
};
}),
contextProviders: this.currentContextProviders,
correctWordFileIds: this.checkedReplacementWordIds,
tagNames: this.dynamicTags.map(tag => tag.tagName),
};
// 只在用户设置了TTS参数时才传递(不为null/undefined
@@ -608,6 +637,7 @@ export default {
message: i18n.t("roleConfig.saveSuccess"),
showClose: true,
});
this.fetchCurrentVersion(this.$route.query.agentId);
} else {
this.$message.error({
message: data.msg || i18n.t("roleConfig.saveFailed"),
@@ -617,6 +647,32 @@ export default {
});
},
handleSnapshotRestored() {
const agentId = this.$route.query.agentId;
if (agentId) {
this.fetchAgentConfig(agentId);
this.getAgentTags(agentId);
this.fetchCurrentVersion(agentId);
}
},
fetchCurrentVersion(agentId) {
if (!agentId) {
this.currentVersionNo = null;
return;
}
Api.agent.getAgentSnapshots(
agentId,
{ page: "1", limit: "1" },
({ data }) => {
if (data.code === 0) {
const latest = data.data?.list?.[0];
const latestVersionNo = Number(latest?.versionNo) || 0;
this.currentVersionNo = latestVersionNo + 1;
}
}
);
},
resetConfig() {
this.$confirm(i18n.t("roleConfig.confirmReset"), i18n.t("message.info"), {
confirmButtonText: i18n.t("button.ok"),
@@ -754,7 +810,7 @@ export default {
id: mapping.pluginId,
name: meta.name,
// 后端如果还有 paramInfo 字段就用 mapping.paramInfo,否则用 meta.params 默认值
params: mapping.paramInfo || { ...meta.params },
params: this.normalizeFunctionParams(mapping.paramInfo, meta.params),
fieldsMeta: meta.fieldsMeta, // 保留以便对话框渲染 tooltip
};
});
@@ -1382,6 +1438,7 @@ export default {
this.fetchAgentConfig(agentId);
this.getAgentTags(agentId);
this.fetchAllFunctions();
this.fetchCurrentVersion(agentId);
}
this.fetchModelOptions();
this.fetchTemplates();
@@ -1507,6 +1564,18 @@ export default {
flex-shrink: 0;
}
.current-version-tag {
flex-shrink: 0;
padding: 3px 9px;
border: 1px solid #dfe7ff;
border-radius: 999px;
background: #f4f7ff;
color: #5778ff;
font-size: 12px;
font-weight: 500;
line-height: 1.5;
}
.more-tag {
cursor: pointer;
flex-shrink: 0;
@@ -1785,6 +1854,16 @@ export default {
font-size: 14px;
}
.header-actions .history-btn {
background: #ffffff;
color: #4d5b7c;
border: 1px solid #d8dce8;
border-radius: 18px;
padding: 8px 16px;
height: 32px;
font-size: 14px;
}
.header-actions .reset-btn {
background: #e6ebff;
color: #5778ff;