mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 23:23:55 +08:00
Add agent configuration history
This commit is contained in:
@@ -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
@@ -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',
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}年前',
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user