Fix agent snapshot history issues

This commit is contained in:
Tyke Chen
2026-07-08 15:15:26 +08:00
parent 35ec3ba803
commit c82b351457
39 changed files with 2268 additions and 373 deletions
+15
View File
@@ -127,6 +127,21 @@ export default {
});
}).send();
},
// 删除智能体配置快照
deleteAgentSnapshot(agentId, snapshotId, callback) {
RequestService.sendRequest()
.url(`${getServiceUrl()}/agent/${agentId}/snapshots/${snapshotId}`)
.method('DELETE')
.success((res) => {
RequestService.clearRequestTime();
callback(res);
})
.networkFail(() => {
RequestService.reAjaxFun(() => {
this.deleteAgentSnapshot(agentId, snapshotId, callback);
});
}).send();
},
// 新增方法:获取智能体模板
getAgentTemplate(callback) { // 移除templateName参数
RequestService.sendRequest()
@@ -5,7 +5,7 @@
:visible="visible"
width="760px"
class="agent-snapshot-dialog"
@open="fetchSnapshots"
@open="open"
@close="close"
>
<el-table
@@ -66,7 +66,7 @@
<span v-else class="field-tags-empty"></span>
</template>
</el-table-column>
<el-table-column :label="$t('agentSnapshot.actions')" width="150" fixed="right">
<el-table-column :label="$t('agentSnapshot.actions')" width="190" fixed="right">
<template slot-scope="scope">
<el-button
v-if="canViewSnapshot(scope.row)"
@@ -84,6 +84,16 @@
>
{{ $t('agentSnapshot.restore') }}
</el-button>
<el-button
v-if="canDeleteSnapshot(scope.row)"
type="text"
size="small"
class="snapshot-delete-button"
:loading="deletingSnapshotId === scope.row.id"
@click="deleteSnapshot(scope.row)"
>
{{ $t('agentSnapshot.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
@@ -185,7 +195,7 @@
</div>
</div>
</div>
<div v-else class="value-empty">功能配置无变化</div>
<div v-else class="value-empty">{{ $t('agentSnapshot.noFunctionChange') }}</div>
</div>
<div v-else class="diff-values" :class="{ 'is-complex': item.complex }">
<div class="diff-pane diff-before">
@@ -306,7 +316,7 @@
</div>
</div>
</div>
<div v-else class="value-empty">功能配置无变化</div>
<div v-else class="value-empty">{{ $t('agentSnapshot.noFunctionChange') }}</div>
</div>
<div v-else class="diff-values" :class="{ 'is-complex': item.complex }">
<div class="diff-pane diff-before">
@@ -339,6 +349,22 @@
:description="$t('agentSnapshot.noChangedContent')"
:image-size="80"
/>
<el-alert
v-if="restorePreviewSnapshot"
class="restore-risk-alert"
type="info"
:closable="false"
show-icon
:title="$t('agentSnapshot.restoreConfirm', { version: restoreTargetVersion })"
/>
<el-alert
v-if="restoreWillClearChatHistory"
class="restore-risk-alert"
type="warning"
:closable="false"
show-icon
:title="$t('agentSnapshot.restoreMemoryWarning')"
/>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="restorePreviewVisible = false">
@@ -361,33 +387,33 @@
import Api from "@/apis/api";
import { formatDate } from "@/utils/date";
const FALLBACK_PLUGIN_NAMES = {
SYSTEM_PLUGIN_WEATHER: "天气查询",
SYSTEM_PLUGIN_MUSIC: "服务器音乐播放",
SYSTEM_PLUGIN_NEWS_CHINANEWS: "中新网新闻",
SYSTEM_PLUGIN_NEWS_NEWSNOW: "newsnow新闻聚合",
SYSTEM_PLUGIN_HA_GET_STATE: "HomeAssistant设备状态查询",
SYSTEM_PLUGIN_HA_SET_STATE: "HomeAssistant设备状态修改",
SYSTEM_PLUGIN_HA_PLAY_MUSIC: "HomeAssistant音乐播放",
SYSTEM_PLUGIN_WEB_SEARCH: "联网搜索",
SYSTEM_PLUGIN_CALL_DEVICE: "设备呼叫设备"
const FALLBACK_PLUGIN_NAME_KEYS = {
SYSTEM_PLUGIN_WEATHER: "agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER",
SYSTEM_PLUGIN_MUSIC: "agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC",
SYSTEM_PLUGIN_NEWS_CHINANEWS: "agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS",
SYSTEM_PLUGIN_NEWS_NEWSNOW: "agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW",
SYSTEM_PLUGIN_HA_GET_STATE: "agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE",
SYSTEM_PLUGIN_HA_SET_STATE: "agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE",
SYSTEM_PLUGIN_HA_PLAY_MUSIC: "agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC",
SYSTEM_PLUGIN_WEB_SEARCH: "agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH",
SYSTEM_PLUGIN_CALL_DEVICE: "agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE"
};
const FALLBACK_FIELD_LABELS = {
url: "接口地址",
news_sources: "新闻源配置",
default_rss_url: "默认 RSS 源",
society_rss_url: "社会新闻 RSS 地址",
world_rss_url: "国际新闻 RSS 地址",
finance_rss_url: "财经新闻 RSS 地址",
api_key: "API 密钥",
default_location: "默认查询城市",
api_host: "开发者 API Host",
base_url: "服务器地址",
devices: "设备列表",
provider: "搜索源",
description: "工具描述",
max_results: "返回数量"
const FALLBACK_FIELD_LABEL_KEYS = {
url: "agentSnapshot.pluginField.url",
news_sources: "agentSnapshot.pluginField.news_sources",
default_rss_url: "agentSnapshot.pluginField.default_rss_url",
society_rss_url: "agentSnapshot.pluginField.society_rss_url",
world_rss_url: "agentSnapshot.pluginField.world_rss_url",
finance_rss_url: "agentSnapshot.pluginField.finance_rss_url",
api_key: "agentSnapshot.pluginField.api_key",
default_location: "agentSnapshot.pluginField.default_location",
api_host: "agentSnapshot.pluginField.api_host",
base_url: "agentSnapshot.pluginField.base_url",
devices: "agentSnapshot.pluginField.devices",
provider: "agentSnapshot.pluginField.provider",
description: "agentSnapshot.pluginField.description",
max_results: "agentSnapshot.pluginField.max_results"
};
const MODEL_FIELD_TYPES = {
@@ -403,29 +429,29 @@ const MODEL_FIELD_TYPES = {
const MODEL_TYPES = ["ASR", "VAD", "LLM", "SLM", "VLLM", "TTS", "Memory", "Intent"];
const FALLBACK_MODEL_NAMES = {
Memory_nomem: "无记忆",
Memory_mem_local_short: "本地短记忆",
Memory_mem0ai: "Mem0AI记忆",
Memory_mem_report_only: "仅上报记忆",
Intent_nointent: "无意图识别",
Intent_intent_llm: "外挂的大模型意图识别",
Intent_function_call: "大模型自主函数调用"
const FALLBACK_MODEL_NAME_KEYS = {
Memory_nomem: "agentSnapshot.model.Memory_nomem",
Memory_mem_local_short: "agentSnapshot.model.Memory_mem_local_short",
Memory_mem0ai: "agentSnapshot.model.Memory_mem0ai",
Memory_mem_report_only: "agentSnapshot.model.Memory_mem_report_only",
Intent_nointent: "agentSnapshot.model.Intent_nointent",
Intent_intent_llm: "agentSnapshot.model.Intent_intent_llm",
Intent_function_call: "agentSnapshot.model.Intent_function_call"
};
const FALLBACK_VOICE_NAMES = {
TTS_EdgeTTS0001: "EdgeTTS女声-晓晓",
TTS_EdgeTTS0002: "EdgeTTS男声-云扬",
TTS_EdgeTTS0003: "EdgeTTS女声-晓伊",
TTS_EdgeTTS0004: "EdgeTTS男声-云健",
TTS_EdgeTTS0005: "EdgeTTS男声-云希",
TTS_EdgeTTS0006: "EdgeTTS男声-云夏"
const FALLBACK_VOICE_NAME_KEYS = {
TTS_EdgeTTS0001: "agentSnapshot.voice.TTS_EdgeTTS0001",
TTS_EdgeTTS0002: "agentSnapshot.voice.TTS_EdgeTTS0002",
TTS_EdgeTTS0003: "agentSnapshot.voice.TTS_EdgeTTS0003",
TTS_EdgeTTS0004: "agentSnapshot.voice.TTS_EdgeTTS0004",
TTS_EdgeTTS0005: "agentSnapshot.voice.TTS_EdgeTTS0005",
TTS_EdgeTTS0006: "agentSnapshot.voice.TTS_EdgeTTS0006"
};
const CHAT_HISTORY_CONF_LABELS = {
0: "不记录聊天记录",
1: "上报文字",
2: "上报文字+语音"
const CHAT_HISTORY_CONF_LABEL_KEYS = {
0: "agentSnapshot.chatHistoryConf.none",
1: "agentSnapshot.chatHistoryConf.text",
2: "agentSnapshot.chatHistoryConf.textVoice"
};
export default {
@@ -456,16 +482,22 @@ export default {
currentSnapshot: null,
restorePreviewSnapshot: null,
restorePreviewRow: null,
deletingSnapshotId: null,
pluginMetadata: {},
pluginMetadataLoaded: false,
pluginMetadataLoading: null,
modelNameMap: {},
modelMetadataLoaded: false,
modelMetadataLoading: null,
voiceNameMap: { ...FALLBACK_VOICE_NAMES },
voiceNameMap: {},
voiceMetadataLoading: {},
loadedVoiceModelIds: {},
snapshotFetchSeq: 0,
detailFetchSeq: 0,
restorePreviewFetchSeq: 0,
restoreActionSeq: 0,
deleteActionSeq: 0,
historyAnchorVersionNo: null,
historyTotal: 0,
page: 1,
limit: 10,
@@ -503,10 +535,11 @@ export default {
const beforeData = this.currentSnapshot.snapshotData || {};
const afterData = this.currentSnapshot.afterSnapshotData || {};
return this.buildDiffs(beforeData, afterData, this.currentSnapshot.changedFields || [], {
beforeLabel: "变化前",
afterLabel: "变化后",
beforeLabel: this.$t("agentSnapshot.beforeChange"),
afterLabel: this.$t("agentSnapshot.afterChange"),
beforeVersionNo: this.currentSnapshot.beforeVersionNo,
afterVersionNo: this.currentSnapshot.afterVersionNo || this.currentSnapshot.versionNo
afterVersionNo: this.currentSnapshot.afterVersionNo || this.currentSnapshot.versionNo,
fieldOrder: this.currentSnapshot.fieldOrder
});
},
restorePreviewDiffs() {
@@ -519,17 +552,35 @@ export default {
this.restorePreviewSnapshot.afterSnapshotData || {},
[],
{
beforeLabel: "恢复前",
afterLabel: "恢复后",
beforeLabel: this.$t("agentSnapshot.beforeRestore"),
afterLabel: this.$t("agentSnapshot.afterRestore"),
beforeVersionNo: this.restorePreviewSnapshot.beforeVersionNo || this.resolveCurrentVersionNo(),
afterVersionNo: this.restorePreviewSnapshot.afterVersionNo || this.restorePreviewSnapshot.versionNo
afterVersionNo: this.restorePreviewSnapshot.afterVersionNo || this.restorePreviewSnapshot.versionNo,
fieldOrder: this.restorePreviewSnapshot.fieldOrder
}
);
},
restoreWillClearChatHistory() {
return this.restorePreviewSnapshot?.afterSnapshotData?.memModelId === "Memory_nomem";
},
restoreTargetVersion() {
return this.restorePreviewSnapshot?.versionNo || this.restorePreviewRow?.versionNo || "";
}
},
watch: {
currentVersionNo(newValue, oldValue) {
if (this.visible && newValue !== oldValue) {
this.historyAnchorVersionNo = null;
this.fetchSnapshots({ clearTable: false });
}
}
},
beforeDestroy() {
this.cancelPendingSnapshotRequests();
},
methods: {
buildDiffs(beforeData, afterData, changedFields, options = {}) {
const fields = this.resolveDiffFields(beforeData, afterData, changedFields);
const fields = this.resolveDiffFields(beforeData, afterData, changedFields, options.fieldOrder);
return fields.map((field) => {
const beforeValue = this.getFieldValue(beforeData, field);
const afterValue = this.getFieldValue(afterData, field);
@@ -552,10 +603,27 @@ export default {
});
},
close() {
this.snapshotFetchSeq += 1;
this.loading = false;
this.cancelPendingSnapshotRequests();
this.historyAnchorVersionNo = null;
this.$emit("update:visible", false);
},
open() {
this.historyAnchorVersionNo = null;
this.page = 1;
this.fetchSnapshots();
},
cancelPendingSnapshotRequests() {
this.snapshotFetchSeq += 1;
this.detailFetchSeq += 1;
this.restorePreviewFetchSeq += 1;
this.restoreActionSeq += 1;
this.deleteActionSeq += 1;
this.loading = false;
this.detailLoading = false;
this.restorePreviewLoading = false;
this.restoring = false;
this.deletingSnapshotId = null;
},
snapshotRowKey(row) {
if (row?.isCurrentVersion) {
return "current-version";
@@ -566,11 +634,14 @@ export default {
return row?.isCurrentVersion ? "current-version-row" : "";
},
canViewSnapshot(row) {
return Number(row?.versionNo) > 1;
return !!row && (row.isCurrentVersion || row.previousSnapshotId || row.previousVersionNo);
},
canRestoreSnapshot(row) {
return !!row && !row.isCurrentVersion;
},
canDeleteSnapshot(row) {
return !!row && !row.isCurrentVersion && !row.isLatestSnapshot;
},
fetchSnapshots(options = {}) {
if (!this.agentId) {
this.snapshots = [];
@@ -582,7 +653,7 @@ export default {
const requestSeq = ++this.snapshotFetchSeq;
const displayStart = (this.page - 1) * this.limit;
const displayEnd = displayStart + this.limit;
const historyFetchLimit = Math.max(displayEnd, this.limit, 1);
const historyFetchLimit = Math.max(displayEnd + 1, this.limit, 1);
this.ensurePluginMetadata();
this.ensureModelMetadata();
this.loading = true;
@@ -591,24 +662,32 @@ export default {
}
Api.agent.getAgentSnapshots(
this.agentId,
{ page: "1", limit: String(historyFetchLimit) },
this.snapshotQueryParams({ page: "1", limit: String(historyFetchLimit) }),
({ data }) => {
if (requestSeq !== this.snapshotFetchSeq) {
return;
}
this.loading = false;
if (data.code === 0) {
const historyRows = data.data?.list || [];
const historyRows = this.decorateSnapshotRows(data.data?.list || []);
if (!this.historyAnchorVersionNo && historyRows[0]?.versionNo) {
this.historyAnchorVersionNo = Number(historyRows[0].versionNo);
}
const currentRow = this.buildCurrentVersionRow(historyRows[0]);
const historyOffset = currentRow ? 1 : 0;
this.historyTotal = data.data?.total || 0;
this.total = this.historyTotal + 1;
this.total = this.historyTotal + historyOffset;
if (this.page === 1) {
const firstPageRows = historyRows.slice(0, currentRow ? this.limit - 1 : this.limit);
this.snapshots = [
this.buildCurrentVersionRow(historyRows[0]),
...this.applyPreviousChangedFields(historyRows.slice(0, this.limit - 1), historyRows)
...(currentRow ? [currentRow] : []),
...this.applyPreviousChangedFields(firstPageRows, historyRows)
];
} else {
const historyStart = Math.max(displayStart - historyOffset, 0);
const historyEnd = Math.max(displayEnd - historyOffset, 0);
this.snapshots = this.applyPreviousChangedFields(
historyRows.slice(displayStart - 1, displayEnd - 1),
historyRows.slice(historyStart, historyEnd),
historyRows
);
}
@@ -629,18 +708,27 @@ export default {
this.detailVisible = true;
this.detailLoading = true;
this.currentSnapshot = null;
const requestSeq = ++this.detailFetchSeq;
this.ensurePluginMetadata();
this.ensureModelMetadata();
this.buildVersionDiffSnapshot(row)
.then((snapshot) => this.ensureDisplayMetadata(snapshot).then(() => snapshot))
.then((snapshot) => {
if (requestSeq !== this.detailFetchSeq) {
return;
}
this.currentSnapshot = snapshot;
})
.catch(() => {
if (requestSeq !== this.detailFetchSeq) {
return;
}
this.$message.error(this.$t("agentSnapshot.detailFailed"));
})
.finally(() => {
this.detailLoading = false;
if (requestSeq === this.detailFetchSeq) {
this.detailLoading = false;
}
});
},
restoreSnapshot(row) {
@@ -651,6 +739,7 @@ export default {
this.restorePreviewLoading = true;
this.restorePreviewRow = row;
this.restorePreviewSnapshot = null;
const requestSeq = ++this.restorePreviewFetchSeq;
this.ensurePluginMetadata();
this.ensureModelMetadata();
@@ -658,41 +747,97 @@ export default {
this.fetchSnapshotDetail(row.id),
this.fetchCurrentAgentData()
]).then(([targetSnapshot, currentData]) => {
if (requestSeq !== this.restorePreviewFetchSeq) {
return Promise.resolve();
}
const previewSnapshot = {
...targetSnapshot,
beforeSnapshotData: currentData,
afterSnapshotData: targetSnapshot.snapshotData || {},
beforeVersionNo: this.resolveCurrentVersionNo(),
afterVersionNo: targetSnapshot.versionNo
afterVersionNo: targetSnapshot.versionNo,
fieldOrder: targetSnapshot.fieldOrder || []
};
return this.ensureDisplayMetadata(previewSnapshot).then(() => {
if (requestSeq !== this.restorePreviewFetchSeq) {
return;
}
this.restorePreviewSnapshot = previewSnapshot;
});
}).catch(() => {
if (requestSeq !== this.restorePreviewFetchSeq) {
return;
}
this.restorePreviewVisible = false;
this.$message.error(this.$t("agentSnapshot.detailFailed"));
}).finally(() => {
this.restorePreviewLoading = false;
if (requestSeq === this.restorePreviewFetchSeq) {
this.restorePreviewLoading = false;
}
});
},
decorateSnapshotRows(rows) {
return (rows || []).map((row, index) => ({
...row,
isLatestSnapshot: index === 0
}));
},
confirmRestoreSnapshot() {
if (!this.restorePreviewRow) {
return;
}
this.restoring = true;
const requestSeq = ++this.restoreActionSeq;
Api.agent.restoreAgentSnapshot(this.agentId, this.restorePreviewRow.id, ({ data }) => {
if (requestSeq !== this.restoreActionSeq) {
return;
}
this.restoring = false;
if (data.code === 0) {
this.$message.success(this.$t("agentSnapshot.restoreSuccess"));
this.restorePreviewVisible = false;
this.detailVisible = false;
this.$emit("restored");
this.historyAnchorVersionNo = null;
this.fetchSnapshots();
} else {
this.$message.error(data.msg || this.$t("agentSnapshot.restoreFailed"));
this.$message.error(this.restoreFailedMessage(data));
}
});
},
deleteSnapshot(row) {
if (!this.canDeleteSnapshot(row)) {
return;
}
this.$confirm(
this.$t("agentSnapshot.deleteConfirm", { version: row.versionNo }),
this.$t("common.warning"),
{
confirmButtonText: this.$t("common.confirm"),
cancelButtonText: this.$t("common.cancel"),
type: "warning"
}
).then(() => {
const requestSeq = ++this.deleteActionSeq;
this.deletingSnapshotId = row.id;
Api.agent.deleteAgentSnapshot(this.agentId, row.id, ({ data }) => {
if (requestSeq !== this.deleteActionSeq) {
return;
}
this.deletingSnapshotId = null;
if (data.code === 0) {
this.$message.success(this.$t("agentSnapshot.deleteSuccess"));
const savedRowsOnPage = this.snapshots.filter((item) => !item.isCurrentVersion);
if (savedRowsOnPage.length <= 1 && this.page > 1) {
this.page -= 1;
}
this.fetchSnapshots();
} else {
this.$message.error(data.msg || this.$t("agentSnapshot.deleteFailed"));
}
});
}).catch(() => {});
},
hasAfterSnapshotData(snapshot) {
return !!(
snapshot &&
@@ -701,8 +846,9 @@ export default {
);
},
resolveCurrentVersionNo() {
if (this.currentVersionNo) {
return this.currentVersionNo;
const propVersionNo = Number(this.currentVersionNo);
if (Number.isFinite(propVersionNo) && propVersionNo > 0) {
return propVersionNo;
}
const currentRow = this.snapshots.find((item) => item.isCurrentVersion);
@@ -710,12 +856,7 @@ export default {
return currentRow.versionNo;
}
const maxVersionNo = Math.max(
...this.snapshots
.filter((item) => !item.isCurrentVersion)
.map((item) => Number(item.versionNo) || 0)
);
return maxVersionNo > 0 ? maxVersionNo + 1 : 1;
return null;
},
formatPaneTitle(label, versionNo) {
return versionNo ? `${label} #${versionNo}` : label;
@@ -745,7 +886,7 @@ export default {
},
fetchSnapshotRows(params) {
return new Promise((resolve, reject) => {
Api.agent.getAgentSnapshots(this.agentId, params, ({ data }) => {
Api.agent.getAgentSnapshots(this.agentId, this.snapshotQueryParams(params), ({ data }) => {
if (data.code === 0) {
resolve(data.data || { list: [], total: 0 });
} else {
@@ -754,6 +895,15 @@ export default {
});
});
},
snapshotQueryParams(params = {}) {
if (!this.historyAnchorVersionNo) {
return params;
}
return {
...params,
maxVersionNo: String(this.historyAnchorVersionNo)
};
},
applyPreviousChangedFields(rows, sourceRows) {
return rows.map((row) => {
const versionNo = Number(row.versionNo);
@@ -763,27 +913,38 @@ export default {
changedFields: []
};
}
const previousRow = sourceRows.find((item) => Number(item.versionNo) === versionNo - 1);
const previousRow = this.findPreviousSnapshotRow(row, sourceRows);
return {
...row,
previousSnapshotId: previousRow?.id || null,
previousVersionNo: previousRow?.versionNo || null,
changedFields: previousRow?.changedFields || []
};
});
},
findPreviousSnapshotRow(row, sourceRows) {
const versionNo = Number(row?.versionNo);
if (!Number.isFinite(versionNo)) {
return null;
}
return (sourceRows || []).find((item) => {
return !item.isCurrentVersion && Number(item.versionNo) < versionNo;
}) || null;
},
buildCurrentVersionRow(latestSnapshot) {
const latestVersionNo = Number(latestSnapshot?.versionNo) || 0;
const propVersionNo = Number(this.currentVersionNo);
const inferredVersionNo = latestVersionNo + 1 || 1;
const currentVersionNo = Number.isFinite(propVersionNo) && propVersionNo > latestVersionNo
? propVersionNo
: inferredVersionNo;
if (!Number.isFinite(propVersionNo) || propVersionNo <= latestVersionNo) {
return null;
}
return {
id: "__current__",
agentId: this.agentId,
versionNo: currentVersionNo,
versionNo: propVersionNo,
source: "current",
createdAt: latestSnapshot?.createdAt || null,
changedFields: latestSnapshot?.changedFields || [],
fieldOrder: latestSnapshot?.fieldOrder || [],
isCurrentVersion: true,
previousVersionNo: latestVersionNo || null,
previousSnapshotId: latestSnapshot?.id || null
@@ -797,9 +958,8 @@ export default {
},
buildCurrentVersionDiffSnapshot(row) {
const currentVersionNo = Number(row.versionNo);
const previousVersionNo = currentVersionNo - 1;
return Promise.all([
this.fetchSnapshotDetailByVersion(previousVersionNo),
this.fetchPreviousSnapshotDetail(row),
this.fetchCurrentAgentData()
]).then(([previousSnapshot, currentData]) => ({
...row,
@@ -807,26 +967,41 @@ export default {
changedFields: previousSnapshot.changedFields || [],
snapshotData: previousSnapshot.snapshotData || {},
afterSnapshotData: currentData,
beforeVersionNo: previousVersionNo,
afterVersionNo: currentVersionNo
beforeVersionNo: previousSnapshot.versionNo,
afterVersionNo: currentVersionNo,
fieldOrder: previousSnapshot.fieldOrder || row.fieldOrder || []
}));
},
buildSavedVersionDiffSnapshot(row) {
const versionNo = Number(row.versionNo);
const previousVersionNo = versionNo - 1;
return Promise.all([
this.fetchSnapshotDetail(row.id),
this.fetchSnapshotDetailByVersion(previousVersionNo)
this.fetchPreviousSnapshotDetail(row)
]).then(([selectedSnapshot, previousSnapshot]) => ({
...selectedSnapshot,
versionNo,
changedFields: previousSnapshot.changedFields || [],
snapshotData: previousSnapshot.snapshotData || {},
afterSnapshotData: selectedSnapshot.snapshotData || {},
beforeVersionNo: previousVersionNo,
afterVersionNo: versionNo
beforeVersionNo: previousSnapshot.versionNo,
afterVersionNo: versionNo,
fieldOrder: selectedSnapshot.fieldOrder || previousSnapshot.fieldOrder || row.fieldOrder || []
}));
},
fetchPreviousSnapshotDetail(row) {
if (row?.previousSnapshotId) {
return this.fetchSnapshotDetail(row.previousSnapshotId);
}
if (row?.previousVersionNo) {
return this.fetchSnapshotDetailByVersion(row.previousVersionNo);
}
return this.fetchSnapshotRowBeforeVersion(row?.versionNo).then((previousRow) => {
if (!previousRow?.id) {
return Promise.reject(new Error("previous snapshot not found"));
}
return this.fetchSnapshotDetail(previousRow.id);
});
},
fetchSnapshotDetailByVersion(versionNo) {
return this.fetchSnapshotRowByVersion(versionNo).then((row) => {
if (!row?.id) {
@@ -867,6 +1042,17 @@ export default {
});
});
},
fetchSnapshotRowBeforeVersion(versionNo) {
const cached = this.findPreviousSnapshotRow({ versionNo }, this.snapshots);
if (cached) {
return Promise.resolve(cached);
}
return this.fetchSnapshotRows({
page: "1",
limit: String(Math.max(this.historyTotal, this.limit, 1))
}).then((data) => this.findPreviousSnapshotRow({ versionNo }, data.list || []));
},
ensurePluginMetadata() {
if (this.pluginMetadataLoaded) {
return Promise.resolve();
@@ -927,7 +1113,7 @@ export default {
this.modelMetadataLoading = Promise.all(fetchers)
.then((groups) => {
const metadata = { ...FALLBACK_MODEL_NAMES };
const metadata = {};
groups.flat().forEach((item) => {
if (item.id) {
metadata[item.id] = item.name || item.id;
@@ -1166,13 +1352,13 @@ export default {
const name = this.functionDisplayName(pluginId);
const statusMap = {
added: {
badge: "已开启"
badge: this.$t("agentSnapshot.function.added")
},
removed: {
badge: "已关闭"
badge: this.$t("agentSnapshot.function.removed")
},
updated: {
badge: "参数变更"
badge: this.$t("agentSnapshot.function.updated")
}
};
return {
@@ -1188,18 +1374,18 @@ export default {
if (!func) {
return {
active: false,
status: "未开启",
status: this.$t("agentSnapshot.function.disabled"),
params: [],
note: "未开启此功能"
note: this.$t("agentSnapshot.function.disabledNote")
};
}
const params = this.functionParamRows(pluginId, func.params, changedParamKeys);
return {
active: true,
status: "已开启",
status: this.$t("agentSnapshot.function.enabled"),
params,
note: params.length ? "" : "无需配置参数"
note: params.length ? "" : this.$t("agentSnapshot.function.noParams")
};
},
changedFunctionParamKeys(pluginId, beforeParams, afterParams) {
@@ -1235,11 +1421,12 @@ export default {
},
functionDisplayName(pluginId) {
const meta = this.resolveFunctionMeta(pluginId);
return meta?.name || FALLBACK_PLUGIN_NAMES[pluginId] || pluginId || this.$t("agentSnapshot.emptyValue");
return meta?.name || this.translateKey(FALLBACK_PLUGIN_NAME_KEYS[pluginId], pluginId)
|| pluginId || this.$t("agentSnapshot.emptyValue");
},
functionParamLabel(pluginId, key) {
const field = this.functionFields(pluginId).find((item) => item.key === key);
return field?.label || FALLBACK_FIELD_LABELS[key] || key;
return field?.label || this.translateKey(FALLBACK_FIELD_LABEL_KEYS[key], key) || key;
},
functionFields(pluginId) {
const meta = this.resolveFunctionMeta(pluginId);
@@ -1273,7 +1460,7 @@ export default {
const lines = String(value).replace(/\r\n/g, "\n").split("\n");
const html = [];
let paragraph = [];
let listType = null;
const listStack = [];
const closeParagraph = () => {
if (paragraph.length) {
@@ -1281,59 +1468,89 @@ export default {
paragraph = [];
}
};
const closeList = () => {
if (listType) {
html.push(`</${listType}>`);
listType = null;
const closeOneList = () => {
const list = listStack.pop();
if (!list) {
return;
}
if (list.liOpen) {
html.push("</li>");
}
html.push(`</${list.type}>`);
};
const closeLists = () => {
while (listStack.length) {
closeOneList();
}
};
const openList = (type) => {
if (listType !== type) {
closeList();
html.push(`<${type}>`);
listType = type;
const openList = (type, indent) => {
html.push(`<${type}>`);
listStack.push({ type, indent, liOpen: false });
};
const alignList = (type, indent) => {
while (listStack.length && indent < listStack[listStack.length - 1].indent) {
closeOneList();
}
let current = listStack[listStack.length - 1];
if (current && indent === current.indent && type !== current.type) {
closeOneList();
}
current = listStack[listStack.length - 1];
if (!current || indent > current.indent || indent !== current.indent) {
openList(type, indent);
}
};
const addListItem = (type, indent, text) => {
closeParagraph();
alignList(type, indent);
const current = listStack[listStack.length - 1];
if (current.liOpen) {
html.push("</li>");
}
html.push(`<li>${this.renderInlineMarkdown(text)}`);
current.liOpen = true;
};
lines.forEach((rawLine) => {
const line = rawLine.trim();
const normalizedLine = rawLine.replace(/\t/g, " ");
const line = normalizedLine.trim();
if (!line) {
closeParagraph();
closeList();
closeLists();
return;
}
const heading = line.match(/^(#{1,6})\s+(.+)$/);
if (heading) {
closeParagraph();
closeList();
closeLists();
const level = Math.min(heading[1].length, 4);
html.push(`<h${level}>${this.renderInlineMarkdown(heading[2])}</h${level}>`);
return;
}
const unordered = line.match(/^[-*+]\s+(.+)$/);
const indent = normalizedLine.match(/^ */)[0].length;
const listContent = normalizedLine.slice(indent);
const unordered = listContent.match(/^[-*+]\s+(.+)$/);
if (unordered) {
closeParagraph();
openList("ul");
html.push(`<li>${this.renderInlineMarkdown(unordered[1])}</li>`);
addListItem("ul", indent, unordered[1]);
return;
}
const ordered = line.match(/^\d+\.\s+(.+)$/);
const ordered = listContent.match(/^\d+\.\s+(.+)$/);
if (ordered) {
closeParagraph();
openList("ol");
html.push(`<li>${this.renderInlineMarkdown(ordered[1])}</li>`);
addListItem("ol", indent, ordered[1]);
return;
}
closeList();
closeLists();
paragraph.push(line);
});
closeParagraph();
closeList();
closeLists();
return html.join("");
},
renderInlineMarkdown(value) {
@@ -1351,13 +1568,19 @@ export default {
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;");
},
resolveDiffFields(beforeData, afterData, changedFields) {
const directFields = changedFields
restoreFailedMessage(data) {
return data?.msg
? `${this.$t("agentSnapshot.restoreFailedRollback")}: ${data.msg}`
: this.$t("agentSnapshot.restoreFailedRollback");
},
resolveDiffFields(beforeData, afterData, changedFields = [], fieldOrder = []) {
const safeChangedFields = Array.isArray(changedFields) ? changedFields : [];
const directFields = safeChangedFields
.filter((field) => field && field !== "restore")
.map((field) => this.canonicalField(field));
const candidates = directFields.length > 0 && !changedFields.includes("restore")
const candidates = directFields.length > 0 && !safeChangedFields.includes("restore")
? directFields
: this.snapshotFieldOrder();
: this.snapshotFieldOrder(fieldOrder, beforeData, afterData);
return Array.from(new Set(candidates)).filter((field) => {
return !this.isSameValue(
@@ -1366,38 +1589,19 @@ export default {
);
});
},
snapshotFieldOrder() {
return [
"agentCode",
"agentName",
"asrModelId",
"vadModelId",
"llmModelId",
"slmModelId",
"vllmModelId",
"ttsModelId",
"ttsVoiceId",
"ttsLanguage",
"ttsVolume",
"ttsRate",
"ttsPitch",
"memModelId",
"intentModelId",
"chatHistoryConf",
"systemPrompt",
"summaryMemory",
"langCode",
"language",
"sort",
"functions",
"contextProviders",
"correctWordFileIds",
"tagNames",
"tagIds"
];
snapshotFieldOrder(fieldOrder = [], beforeData = {}, afterData = {}) {
const backendOrder = Array.isArray(fieldOrder) ? fieldOrder : [];
if (backendOrder.length) {
return backendOrder.map((field) => this.canonicalField(field));
}
const dataFields = [
...Object.keys(beforeData || {}),
...Object.keys(afterData || {})
].map((field) => this.canonicalField(field));
return Array.from(new Set(dataFields)).filter((field) => field !== "tags");
},
canonicalField(field) {
return field === "tags" ? "tagNames" : field;
return field === "tags" || field === "tagIds" ? "tagNames" : field;
},
getFieldValue(data, field) {
if (!data) {
@@ -1434,7 +1638,8 @@ export default {
return this.voiceDisplayName(data.ttsModelId, value);
}
if (field === "chatHistoryConf") {
return CHAT_HISTORY_CONF_LABELS[value] || CHAT_HISTORY_CONF_LABELS[Number(value)] || this.formatValue(value);
return this.translateKey(CHAT_HISTORY_CONF_LABEL_KEYS[value] || CHAT_HISTORY_CONF_LABEL_KEYS[Number(value)])
|| this.formatValue(value);
}
return this.formatValue(value);
},
@@ -1442,13 +1647,14 @@ export default {
if (value === null || value === undefined || value === "") {
return this.$t("agentSnapshot.emptyValue");
}
return this.modelNameMap[value] || FALLBACK_MODEL_NAMES[value] || String(value);
return this.modelNameMap[value] || this.translateKey(FALLBACK_MODEL_NAME_KEYS[value], String(value)) || String(value);
},
voiceDisplayName(modelId, value) {
if (value === null || value === undefined || value === "") {
return this.$t("agentSnapshot.emptyValue");
}
return this.voiceNameMap[`${modelId}:${value}`] || this.voiceNameMap[value] || String(value);
return this.voiceNameMap[`${modelId}:${value}`] || this.voiceNameMap[value]
|| this.translateKey(FALLBACK_VOICE_NAME_KEYS[value], String(value)) || String(value);
},
formatValue(value) {
if (value === null || value === undefined || value === "") {
@@ -1481,6 +1687,9 @@ export default {
fieldLabel(field) {
const key = `agentSnapshot.field.${field}`;
return this.$te && this.$te(key) ? this.$t(key) : field;
},
translateKey(key, fallback = "") {
return key && this.$te && this.$te(key) ? this.$t(key) : fallback;
}
}
};
@@ -1540,6 +1749,10 @@ export default {
background: #fbfffa;
}
.snapshot-delete-button {
color: #f56c6c;
}
.field-tags {
display: flex;
flex-wrap: wrap;
@@ -1564,6 +1777,10 @@ export default {
@include scrollbar-style;
}
.restore-risk-alert {
margin-top: 14px;
}
.detail-summary {
display: flex;
flex-wrap: wrap;
+115 -1
View File
@@ -806,12 +806,126 @@ export default {
'roleConfig.addTag': 'Neues Label hinzufügen',
'roleConfig.restartNotice': 'Neustart nach Konfigurationsspeichern zur Aktivierung.',
'roleConfig.saveConfig': 'Konfiguration speichern',
'roleConfig.snapshotHistory': 'Versionsverlauf',
'roleConfig.currentVersion': 'Aktuelle Version {version}',
'roleConfig.functionName': 'Funktionsname',
'roleConfig.reset': 'Zurücksetzen',
'roleConfig.agentName': 'Spitzname',
'roleConfig.roleTemplate': 'Vorlage',
'roleConfig.roleIntroduction': 'Einführung',
'roleConfig.languageCode': 'Sprachcode',
'roleConfig.interactionLanguage': 'Interaktionssprache',
'agentSnapshot.title': 'Versionsverlauf',
'agentSnapshot.empty': 'Noch keine Versionen',
'agentSnapshot.version': 'Version',
'agentSnapshot.createdAt': 'Gespeichert am',
'agentSnapshot.source': 'Quelle',
'agentSnapshot.changedFields': 'Änderungen',
'agentSnapshot.actions': 'Aktionen',
'agentSnapshot.view': 'Anzeigen',
'agentSnapshot.restore': 'Wiederherstellen',
'agentSnapshot.delete': 'Löschen',
'agentSnapshot.detailTitle': 'Änderungsdetails',
'agentSnapshot.restorePreviewTitle': 'Wiederherstellungsvorschau',
'agentSnapshot.confirmRestore': 'Wiederherstellung bestätigen',
'agentSnapshot.before': 'Vorher',
'agentSnapshot.after': 'Nachher',
'agentSnapshot.emptyValue': 'Keine',
'agentSnapshot.noChangedContent': 'Keine anzeigbaren Änderungen',
'agentSnapshot.noFunctionChange': 'Keine Funktionsänderungen',
'agentSnapshot.beforeChange': 'Vor der Änderung',
'agentSnapshot.afterChange': 'Nach der Änderung',
'agentSnapshot.beforeRestore': 'Vor der Wiederherstellung',
'agentSnapshot.afterRestore': 'Nach der Wiederherstellung',
'agentSnapshot.restoreMemoryWarning': 'Beim Wiederherstellen einer Version ohne Speicher wird der Chatverlauf dieses Agenten gelöscht. Fahren Sie nur fort, wenn Sie dieses Risiko bestätigt haben.',
'agentSnapshot.restoreConfirm': 'Version {version} wiederherstellen? Die aktuelle Konfiguration wird zuerst als neue Version gespeichert.',
'agentSnapshot.restoreSuccess': 'Version wurde wiederhergestellt',
'agentSnapshot.restoreFailed': 'Version konnte nicht wiederhergestellt werden',
'agentSnapshot.restoreFailedRollback': 'Version konnte nicht wiederhergestellt werden. Die Transaktion wurde zurueckgerollt und die aktuelle Konfiguration wurde nicht geaendert',
'agentSnapshot.deleteConfirm': 'Version {version} löschen? Dies kann nicht rückgängig gemacht werden.',
'agentSnapshot.deleteSuccess': 'Verlaufsversion gelöscht',
'agentSnapshot.deleteFailed': 'Verlaufsversion konnte nicht gelöscht werden',
'agentSnapshot.fetchFailed': 'Versionsverlauf konnte nicht abgerufen werden',
'agentSnapshot.detailFailed': 'Snapshot-Details konnten nicht abgerufen werden',
'agentSnapshot.currentVersion': 'Aktuelle Version',
'agentSnapshot.source.config': 'Konfiguration gespeichert',
'agentSnapshot.source.current': 'Aktuelle Konfiguration',
'agentSnapshot.source.restore': 'Vor der Wiederherstellung',
'agentSnapshot.source.initial': 'Initialversion',
'agentSnapshot.field.restore': 'Wiederherstellung',
'agentSnapshot.field.initial': 'Initialer Snapshot',
'agentSnapshot.field.agentCode': 'Agent-Code',
'agentSnapshot.field.agentName': 'Spitzname',
'agentSnapshot.field.asrModelId': 'Spracherkennung',
'agentSnapshot.field.vadModelId': 'Sprachaktivitätserkennung',
'agentSnapshot.field.llmModelId': 'Hauptsprachmodell',
'agentSnapshot.field.slmModelId': 'Kleines Sprachmodell',
'agentSnapshot.field.vllmModelId': 'Vision-Modell',
'agentSnapshot.field.ttsModelId': 'Text-zu-Sprache',
'agentSnapshot.field.ttsVoiceId': 'Stimme',
'agentSnapshot.field.ttsLanguage': 'Sprache',
'agentSnapshot.field.ttsVolume': 'Lautstärke',
'agentSnapshot.field.ttsRate': 'Geschwindigkeit',
'agentSnapshot.field.ttsPitch': 'Tonhöhe',
'agentSnapshot.field.memModelId': 'Speichermodell',
'agentSnapshot.field.intentModelId': 'Absichtserkennung',
'agentSnapshot.field.chatHistoryConf': 'Chatverlauf',
'agentSnapshot.field.systemPrompt': 'Einführung',
'agentSnapshot.field.summaryMemory': 'Speicher',
'agentSnapshot.field.langCode': 'Sprachcode',
'agentSnapshot.field.language': 'Interaktionssprache',
'agentSnapshot.field.sort': 'Sortierung',
'agentSnapshot.field.functions': 'Funktionen',
'agentSnapshot.field.contextProviders': 'Kontextquellen',
'agentSnapshot.field.correctWordFileIds': 'Ersatzwörter',
'agentSnapshot.field.tagNames': 'Labels',
'agentSnapshot.field.tagIds': 'Label-IDs',
'agentSnapshot.function.added': 'Aktiviert',
'agentSnapshot.function.removed': 'Deaktiviert',
'agentSnapshot.function.updated': 'Parameter geändert',
'agentSnapshot.function.enabled': 'Aktiviert',
'agentSnapshot.function.disabled': 'Deaktiviert',
'agentSnapshot.function.disabledNote': 'Diese Funktion ist deaktiviert',
'agentSnapshot.function.noParams': 'Keine Parameter erforderlich',
'agentSnapshot.chatHistoryConf.none': 'Chatverlauf nicht aufzeichnen',
'agentSnapshot.chatHistoryConf.text': 'Text melden',
'agentSnapshot.chatHistoryConf.textVoice': 'Text und Sprache melden',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': 'Wetter',
'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': 'Server-Musikplayer',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': 'China News',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'NewsNow-Aggregation',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'HomeAssistant-Statusabfrage',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'HomeAssistant-Statusaktualisierung',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'HomeAssistant-Musikplayer',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': 'Websuche',
'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': 'Geräteanruf',
'agentSnapshot.pluginField.url': 'Endpunkt-URL',
'agentSnapshot.pluginField.news_sources': 'Nachrichtenquellen',
'agentSnapshot.pluginField.default_rss_url': 'Standard-RSS-URL',
'agentSnapshot.pluginField.society_rss_url': 'RSS-URL für Gesellschaft',
'agentSnapshot.pluginField.world_rss_url': 'RSS-URL für Welt',
'agentSnapshot.pluginField.finance_rss_url': 'RSS-URL für Finanzen',
'agentSnapshot.pluginField.api_key': 'API-Schlüssel',
'agentSnapshot.pluginField.default_location': 'Standardstadt',
'agentSnapshot.pluginField.api_host': 'Entwickler-API-Host',
'agentSnapshot.pluginField.base_url': 'Server-URL',
'agentSnapshot.pluginField.devices': 'Geräte',
'agentSnapshot.pluginField.provider': 'Suchanbieter',
'agentSnapshot.pluginField.description': 'Werkzeugbeschreibung',
'agentSnapshot.pluginField.max_results': 'Ergebnisanzahl',
'agentSnapshot.model.Memory_nomem': 'Kein Speicher',
'agentSnapshot.model.Memory_mem_local_short': 'Lokaler Kurzzeitspeicher',
'agentSnapshot.model.Memory_mem0ai': 'Mem0AI-Speicher',
'agentSnapshot.model.Memory_mem_report_only': 'Nur melden',
'agentSnapshot.model.Intent_nointent': 'Keine Absichtserkennung',
'agentSnapshot.model.Intent_intent_llm': 'Externe LLM-Absichtserkennung',
'agentSnapshot.model.Intent_function_call': 'LLM-Funktionsaufruf',
'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS weiblich - Xiaoxiao',
'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS männlich - Yunyang',
'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS weiblich - Xiaoyi',
'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS männlich - Yunjian',
'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS männlich - Yunxi',
'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS männlich - Yunxia',
'roleConfig.vad': 'VAD',
'roleConfig.asr': 'ASR',
'roleConfig.llm': 'Hauptsprachmodell (LLM)',
@@ -1554,4 +1668,4 @@ export default {
// Header navigation
'header.addressBook': 'Adressbuch',
}
}
+62 -1
View File
@@ -807,6 +807,8 @@ export default {
'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.currentVersion': 'Current Version {version}',
'roleConfig.functionName': 'Function Name',
'roleConfig.reset': 'Reset',
'roleConfig.agentName': 'Nickname',
'roleConfig.roleTemplate': 'Template',
@@ -873,6 +875,7 @@ export default {
'agentSnapshot.actions': 'Actions',
'agentSnapshot.view': 'View',
'agentSnapshot.restore': 'Restore',
'agentSnapshot.delete': 'Delete',
'agentSnapshot.detailTitle': 'Change Details',
'agentSnapshot.restorePreviewTitle': 'Restore Preview',
'agentSnapshot.confirmRestore': 'Confirm Restore',
@@ -880,16 +883,28 @@ export default {
'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.noFunctionChange': 'No function changes',
'agentSnapshot.beforeChange': 'Before Change',
'agentSnapshot.afterChange': 'After Change',
'agentSnapshot.beforeRestore': 'Before Restore',
'agentSnapshot.afterRestore': 'After Restore',
'agentSnapshot.restoreMemoryWarning': 'Restoring to a no-memory version will clear this agent\'s chat history. Continue only after confirming this risk.',
'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.restoreFailedRollback': 'Failed to restore version. The transaction was rolled back and the current configuration was not changed',
'agentSnapshot.deleteConfirm': 'Delete version {version}? This cannot be undone.',
'agentSnapshot.deleteSuccess': 'History version deleted',
'agentSnapshot.deleteFailed': 'Failed to delete history 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.source.initial': 'Initial Version',
'agentSnapshot.field.restore': 'Restore',
'agentSnapshot.field.initial': 'Initial Snapshot',
'agentSnapshot.field.agentCode': 'Agent Code',
'agentSnapshot.field.agentName': 'Nickname',
'agentSnapshot.field.asrModelId': 'Speech Recognition',
@@ -916,6 +931,52 @@ export default {
'agentSnapshot.field.correctWordFileIds': 'Replacement Words',
'agentSnapshot.field.tagNames': 'Tags',
'agentSnapshot.field.tagIds': 'Tag IDs',
'agentSnapshot.function.added': 'Enabled',
'agentSnapshot.function.removed': 'Disabled',
'agentSnapshot.function.updated': 'Parameters changed',
'agentSnapshot.function.enabled': 'Enabled',
'agentSnapshot.function.disabled': 'Disabled',
'agentSnapshot.function.disabledNote': 'This function is disabled',
'agentSnapshot.function.noParams': 'No parameters required',
'agentSnapshot.chatHistoryConf.none': 'Do not record chat history',
'agentSnapshot.chatHistoryConf.text': 'Report text',
'agentSnapshot.chatHistoryConf.textVoice': 'Report text and voice',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': 'Weather',
'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': 'Server music player',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': 'China News',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'NewsNow aggregation',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'HomeAssistant state query',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'HomeAssistant state update',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'HomeAssistant music player',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': 'Web search',
'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': 'Device-to-device call',
'agentSnapshot.pluginField.url': 'Endpoint URL',
'agentSnapshot.pluginField.news_sources': 'News sources',
'agentSnapshot.pluginField.default_rss_url': 'Default RSS URL',
'agentSnapshot.pluginField.society_rss_url': 'Society RSS URL',
'agentSnapshot.pluginField.world_rss_url': 'World RSS URL',
'agentSnapshot.pluginField.finance_rss_url': 'Finance RSS URL',
'agentSnapshot.pluginField.api_key': 'API key',
'agentSnapshot.pluginField.default_location': 'Default city',
'agentSnapshot.pluginField.api_host': 'Developer API host',
'agentSnapshot.pluginField.base_url': 'Server URL',
'agentSnapshot.pluginField.devices': 'Devices',
'agentSnapshot.pluginField.provider': 'Search provider',
'agentSnapshot.pluginField.description': 'Tool description',
'agentSnapshot.pluginField.max_results': 'Result count',
'agentSnapshot.model.Memory_nomem': 'No memory',
'agentSnapshot.model.Memory_mem_local_short': 'Local short memory',
'agentSnapshot.model.Memory_mem0ai': 'Mem0AI memory',
'agentSnapshot.model.Memory_mem_report_only': 'Report only',
'agentSnapshot.model.Intent_nointent': 'No intent recognition',
'agentSnapshot.model.Intent_intent_llm': 'External LLM intent recognition',
'agentSnapshot.model.Intent_function_call': 'LLM function calling',
'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS female - Xiaoxiao',
'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS male - Yunyang',
'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS female - Xiaoyi',
'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS male - Yunjian',
'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS male - Yunxi',
'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS male - Yunxia',
// Form field Tooltip descriptions
'roleConfig.tooltip.agentName': 'Set the name of your AI agent for identification and recognition',
+115 -1
View File
@@ -806,12 +806,126 @@ export default {
'roleConfig.addTag': 'Adicionar Novo Rótulo',
'roleConfig.restartNotice': 'Reinicie após salvar a configuração para ativação.',
'roleConfig.saveConfig': 'Salvar Configuração',
'roleConfig.snapshotHistory': 'Histórico de Versões',
'roleConfig.currentVersion': 'Versão Atual {version}',
'roleConfig.functionName': 'Nome da Função',
'roleConfig.reset': 'Redefinir',
'roleConfig.agentName': 'Apelido',
'roleConfig.roleTemplate': 'Modelo',
'roleConfig.roleIntroduction': 'Introdução',
'roleConfig.languageCode': 'Código do Idioma',
'roleConfig.interactionLanguage': 'Idioma de Interação',
'agentSnapshot.title': 'Histórico de Versões',
'agentSnapshot.empty': 'Ainda sem versões',
'agentSnapshot.version': 'Versão',
'agentSnapshot.createdAt': 'Salvo em',
'agentSnapshot.source': 'Origem',
'agentSnapshot.changedFields': 'Alterações',
'agentSnapshot.actions': 'Ações',
'agentSnapshot.view': 'Ver',
'agentSnapshot.restore': 'Restaurar',
'agentSnapshot.delete': 'Excluir',
'agentSnapshot.detailTitle': 'Detalhes da Alteração',
'agentSnapshot.restorePreviewTitle': 'Prévia da Restauração',
'agentSnapshot.confirmRestore': 'Confirmar Restauração',
'agentSnapshot.before': 'Antes',
'agentSnapshot.after': 'Depois',
'agentSnapshot.emptyValue': 'Nenhum',
'agentSnapshot.noChangedContent': 'Nenhuma alteração para exibir',
'agentSnapshot.noFunctionChange': 'Sem alterações de função',
'agentSnapshot.beforeChange': 'Antes da Alteração',
'agentSnapshot.afterChange': 'Depois da Alteração',
'agentSnapshot.beforeRestore': 'Antes da Restauração',
'agentSnapshot.afterRestore': 'Depois da Restauração',
'agentSnapshot.restoreMemoryWarning': 'Restaurar para uma versão sem memória apagará o histórico de conversa deste agente. Continue somente após confirmar esse risco.',
'agentSnapshot.restoreConfirm': 'Restaurar para a versão {version}? A configuração atual será salva primeiro como uma nova versão.',
'agentSnapshot.restoreSuccess': 'Versão restaurada',
'agentSnapshot.restoreFailed': 'Falha ao restaurar versão',
'agentSnapshot.restoreFailedRollback': 'Falha ao restaurar versão. A transação foi revertida e a configuração atual não foi alterada',
'agentSnapshot.deleteConfirm': 'Excluir a versão {version}? Esta ação não pode ser desfeita.',
'agentSnapshot.deleteSuccess': 'Versão do histórico excluída',
'agentSnapshot.deleteFailed': 'Falha ao excluir a versão do histórico',
'agentSnapshot.fetchFailed': 'Falha ao buscar versões',
'agentSnapshot.detailFailed': 'Falha ao buscar detalhes do snapshot',
'agentSnapshot.currentVersion': 'Versão Atual',
'agentSnapshot.source.config': 'Configuração Salva',
'agentSnapshot.source.current': 'Configuração Atual',
'agentSnapshot.source.restore': 'Antes da Restauração',
'agentSnapshot.source.initial': 'Versão inicial',
'agentSnapshot.field.restore': 'Restauração',
'agentSnapshot.field.initial': 'Snapshot inicial',
'agentSnapshot.field.agentCode': 'Código do Agente',
'agentSnapshot.field.agentName': 'Apelido',
'agentSnapshot.field.asrModelId': 'Reconhecimento de Fala',
'agentSnapshot.field.vadModelId': 'Detecção de Atividade de Voz',
'agentSnapshot.field.llmModelId': 'Modelo de Linguagem Principal',
'agentSnapshot.field.slmModelId': 'Modelo de Linguagem Pequeno',
'agentSnapshot.field.vllmModelId': 'Modelo de Visão',
'agentSnapshot.field.ttsModelId': 'Texto para Fala',
'agentSnapshot.field.ttsVoiceId': 'Voz',
'agentSnapshot.field.ttsLanguage': 'Idioma',
'agentSnapshot.field.ttsVolume': 'Volume',
'agentSnapshot.field.ttsRate': 'Velocidade',
'agentSnapshot.field.ttsPitch': 'Tom',
'agentSnapshot.field.memModelId': 'Modelo de Memória',
'agentSnapshot.field.intentModelId': 'Reconhecimento de Intenção',
'agentSnapshot.field.chatHistoryConf': 'Histórico de Conversa',
'agentSnapshot.field.systemPrompt': 'Introdução',
'agentSnapshot.field.summaryMemory': 'Memória',
'agentSnapshot.field.langCode': 'Código do Idioma',
'agentSnapshot.field.language': 'Idioma de Interação',
'agentSnapshot.field.sort': 'Ordenação',
'agentSnapshot.field.functions': 'Funções',
'agentSnapshot.field.contextProviders': 'Provedores de Contexto',
'agentSnapshot.field.correctWordFileIds': 'Palavras de Substituição',
'agentSnapshot.field.tagNames': 'Rótulos',
'agentSnapshot.field.tagIds': 'IDs dos Rótulos',
'agentSnapshot.function.added': 'Ativado',
'agentSnapshot.function.removed': 'Desativado',
'agentSnapshot.function.updated': 'Parâmetros alterados',
'agentSnapshot.function.enabled': 'Ativado',
'agentSnapshot.function.disabled': 'Desativado',
'agentSnapshot.function.disabledNote': 'Esta função está desativada',
'agentSnapshot.function.noParams': 'Nenhum parâmetro necessário',
'agentSnapshot.chatHistoryConf.none': 'Não registrar histórico de conversa',
'agentSnapshot.chatHistoryConf.text': 'Enviar texto',
'agentSnapshot.chatHistoryConf.textVoice': 'Enviar texto e voz',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': 'Clima',
'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': 'Reprodutor de música do servidor',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': 'China News',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'Agregação NewsNow',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'Consulta de estado do HomeAssistant',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'Atualização de estado do HomeAssistant',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'Reprodutor de música do HomeAssistant',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': 'Pesquisa na web',
'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': 'Chamada entre dispositivos',
'agentSnapshot.pluginField.url': 'URL do endpoint',
'agentSnapshot.pluginField.news_sources': 'Fontes de notícias',
'agentSnapshot.pluginField.default_rss_url': 'URL RSS padrão',
'agentSnapshot.pluginField.society_rss_url': 'URL RSS de sociedade',
'agentSnapshot.pluginField.world_rss_url': 'URL RSS mundial',
'agentSnapshot.pluginField.finance_rss_url': 'URL RSS financeiro',
'agentSnapshot.pluginField.api_key': 'Chave de API',
'agentSnapshot.pluginField.default_location': 'Cidade padrão',
'agentSnapshot.pluginField.api_host': 'Host da API de desenvolvedor',
'agentSnapshot.pluginField.base_url': 'URL do servidor',
'agentSnapshot.pluginField.devices': 'Dispositivos',
'agentSnapshot.pluginField.provider': 'Provedor de pesquisa',
'agentSnapshot.pluginField.description': 'Descrição da ferramenta',
'agentSnapshot.pluginField.max_results': 'Quantidade de resultados',
'agentSnapshot.model.Memory_nomem': 'Sem memória',
'agentSnapshot.model.Memory_mem_local_short': 'Memória curta local',
'agentSnapshot.model.Memory_mem0ai': 'Memória Mem0AI',
'agentSnapshot.model.Memory_mem_report_only': 'Somente relatório',
'agentSnapshot.model.Intent_nointent': 'Sem reconhecimento de intenção',
'agentSnapshot.model.Intent_intent_llm': 'Reconhecimento de intenção por LLM externo',
'agentSnapshot.model.Intent_function_call': 'Chamada de função por LLM',
'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS feminino - Xiaoxiao',
'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS masculino - Yunyang',
'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS feminino - Xiaoyi',
'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS masculino - Yunjian',
'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS masculino - Yunxi',
'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS masculino - Yunxia',
'roleConfig.vad': 'Detecção de Voz',
'roleConfig.asr': 'Reconhecimento de Fala',
'roleConfig.llm': 'Modelo de Linguagem Principal',
@@ -1554,4 +1668,4 @@ export default {
// Header navigation
'header.addressBook': 'Lista de Contatos',
}
}
+115 -1
View File
@@ -806,12 +806,126 @@ export default {
'roleConfig.addTag': 'Thêm mới nhãn',
'roleConfig.restartNotice': 'Sau khi lưu cấu hình, bạn cần khởi động lại thiết bị để cấu hình mới có hiệu lực.',
'roleConfig.saveConfig': 'Lưu cấu hình',
'roleConfig.snapshotHistory': 'Lịch sử phiên bản',
'roleConfig.currentVersion': 'Phiên bản hiện tại {version}',
'roleConfig.functionName': 'Tên chức năng',
'roleConfig.reset': 'Đặt lại',
'roleConfig.agentName': 'Biệt danh',
'roleConfig.roleTemplate': 'Mẫu',
'roleConfig.roleIntroduction': 'Giới thiệu',
'roleConfig.languageCode': 'Mã ngôn ngữ',
'roleConfig.interactionLanguage': 'Ngôn ngữ tương tác',
'agentSnapshot.title': 'Lịch sử phiên bản',
'agentSnapshot.empty': 'Chưa có phiên bản',
'agentSnapshot.version': 'Phiên bản',
'agentSnapshot.createdAt': 'Lưu lúc',
'agentSnapshot.source': 'Nguồn',
'agentSnapshot.changedFields': 'Thay đổi',
'agentSnapshot.actions': 'Thao tác',
'agentSnapshot.view': 'Xem',
'agentSnapshot.restore': 'Khôi phục',
'agentSnapshot.delete': 'Xóa',
'agentSnapshot.detailTitle': 'Chi tiết thay đổi',
'agentSnapshot.restorePreviewTitle': 'Xem trước khôi phục',
'agentSnapshot.confirmRestore': 'Xác nhận khôi phục',
'agentSnapshot.before': 'Trước',
'agentSnapshot.after': 'Sau',
'agentSnapshot.emptyValue': 'Không có',
'agentSnapshot.noChangedContent': 'Không có thay đổi để hiển thị',
'agentSnapshot.noFunctionChange': 'Không có thay đổi chức năng',
'agentSnapshot.beforeChange': 'Trước thay đổi',
'agentSnapshot.afterChange': 'Sau thay đổi',
'agentSnapshot.beforeRestore': 'Trước khi khôi phục',
'agentSnapshot.afterRestore': 'Sau khi khôi phục',
'agentSnapshot.restoreMemoryWarning': 'Khôi phục về phiên bản không có bộ nhớ sẽ xóa lịch sử trò chuyện của tác nhân này. Chỉ tiếp tục sau khi xác nhận rủi ro này.',
'agentSnapshot.restoreConfirm': 'Khôi phục về phiên bản {version}? Cấu hình hiện tại sẽ được lưu thành phiên bản mới trước.',
'agentSnapshot.restoreSuccess': 'Đã khôi phục phiên bản',
'agentSnapshot.restoreFailed': 'Khôi phục phiên bản thất bại',
'agentSnapshot.restoreFailedRollback': 'Khôi phục phiên bản thất bại. Giao dịch đã được hoàn tác và cấu hình hiện tại chưa thay đổi',
'agentSnapshot.deleteConfirm': 'Xóa phiên bản {version}? Không thể hoàn tác thao tác này.',
'agentSnapshot.deleteSuccess': 'Đã xóa phiên bản lịch sử',
'agentSnapshot.deleteFailed': 'Xóa phiên bản lịch sử thất bại',
'agentSnapshot.fetchFailed': 'Không thể tải lịch sử phiên bản',
'agentSnapshot.detailFailed': 'Không thể tải chi tiết snapshot',
'agentSnapshot.currentVersion': 'Phiên bản hiện tại',
'agentSnapshot.source.config': 'Lưu cấu hình',
'agentSnapshot.source.current': 'Cấu hình hiện tại',
'agentSnapshot.source.restore': 'Trước khi khôi phục',
'agentSnapshot.source.initial': 'Phiên bản ban đầu',
'agentSnapshot.field.restore': 'Khôi phục',
'agentSnapshot.field.initial': 'Snapshot ban đầu',
'agentSnapshot.field.agentCode': 'Mã tác nhân',
'agentSnapshot.field.agentName': 'Biệt danh',
'agentSnapshot.field.asrModelId': 'Nhận dạng giọng nói',
'agentSnapshot.field.vadModelId': 'Phát hiện hoạt động giọng nói',
'agentSnapshot.field.llmModelId': 'Mô hình ngôn ngữ chính',
'agentSnapshot.field.slmModelId': 'Mô hình ngôn ngữ nhỏ',
'agentSnapshot.field.vllmModelId': 'Mô hình thị giác',
'agentSnapshot.field.ttsModelId': 'Văn bản thành giọng nói',
'agentSnapshot.field.ttsVoiceId': 'Giọng nói',
'agentSnapshot.field.ttsLanguage': 'Ngôn ngữ',
'agentSnapshot.field.ttsVolume': 'Âm lượng',
'agentSnapshot.field.ttsRate': 'Tốc độ',
'agentSnapshot.field.ttsPitch': 'Cao độ',
'agentSnapshot.field.memModelId': 'Mô hình bộ nhớ',
'agentSnapshot.field.intentModelId': 'Nhận dạng ý định',
'agentSnapshot.field.chatHistoryConf': 'Lịch sử trò chuyện',
'agentSnapshot.field.systemPrompt': 'Giới thiệu',
'agentSnapshot.field.summaryMemory': 'Bộ nhớ',
'agentSnapshot.field.langCode': 'Mã ngôn ngữ',
'agentSnapshot.field.language': 'Ngôn ngữ tương tác',
'agentSnapshot.field.sort': 'Sắp xếp',
'agentSnapshot.field.functions': 'Chức năng',
'agentSnapshot.field.contextProviders': 'Nguồn ngữ cảnh',
'agentSnapshot.field.correctWordFileIds': 'Từ thay thế',
'agentSnapshot.field.tagNames': 'Nhãn',
'agentSnapshot.field.tagIds': 'ID nhãn',
'agentSnapshot.function.added': 'Đã bật',
'agentSnapshot.function.removed': 'Đã tắt',
'agentSnapshot.function.updated': 'Tham số đã thay đổi',
'agentSnapshot.function.enabled': 'Đã bật',
'agentSnapshot.function.disabled': 'Đã tắt',
'agentSnapshot.function.disabledNote': 'Chức năng này đang tắt',
'agentSnapshot.function.noParams': 'Không cần cấu hình tham số',
'agentSnapshot.chatHistoryConf.none': 'Không ghi lịch sử trò chuyện',
'agentSnapshot.chatHistoryConf.text': 'Báo cáo văn bản',
'agentSnapshot.chatHistoryConf.textVoice': 'Báo cáo văn bản và giọng nói',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': 'Thời tiết',
'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': 'Trình phát nhạc máy chủ',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': 'Tin tức China News',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'Tổng hợp NewsNow',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'Truy vấn trạng thái HomeAssistant',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'Cập nhật trạng thái HomeAssistant',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'Trình phát nhạc HomeAssistant',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': 'Tìm kiếm web',
'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': 'Gọi thiết bị',
'agentSnapshot.pluginField.url': 'URL điểm cuối',
'agentSnapshot.pluginField.news_sources': 'Nguồn tin',
'agentSnapshot.pluginField.default_rss_url': 'URL RSS mặc định',
'agentSnapshot.pluginField.society_rss_url': 'URL RSS xã hội',
'agentSnapshot.pluginField.world_rss_url': 'URL RSS thế giới',
'agentSnapshot.pluginField.finance_rss_url': 'URL RSS tài chính',
'agentSnapshot.pluginField.api_key': 'Khóa API',
'agentSnapshot.pluginField.default_location': 'Thành phố mặc định',
'agentSnapshot.pluginField.api_host': 'Máy chủ API nhà phát triển',
'agentSnapshot.pluginField.base_url': 'URL máy chủ',
'agentSnapshot.pluginField.devices': 'Thiết bị',
'agentSnapshot.pluginField.provider': 'Nhà cung cấp tìm kiếm',
'agentSnapshot.pluginField.description': 'Mô tả công cụ',
'agentSnapshot.pluginField.max_results': 'Số lượng kết quả',
'agentSnapshot.model.Memory_nomem': 'Không có bộ nhớ',
'agentSnapshot.model.Memory_mem_local_short': 'Bộ nhớ ngắn cục bộ',
'agentSnapshot.model.Memory_mem0ai': 'Bộ nhớ Mem0AI',
'agentSnapshot.model.Memory_mem_report_only': 'Chỉ báo cáo bộ nhớ',
'agentSnapshot.model.Intent_nointent': 'Không nhận dạng ý định',
'agentSnapshot.model.Intent_intent_llm': 'Nhận dạng ý định bằng LLM bên ngoài',
'agentSnapshot.model.Intent_function_call': 'LLM gọi hàm',
'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS nữ - Xiaoxiao',
'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS nam - Yunyang',
'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS nữ - Xiaoyi',
'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS nam - Yunjian',
'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS nam - Yunxi',
'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS nam - Yunxia',
'roleConfig.vad': 'Phát hiện giọng nói',
'roleConfig.asr': 'Nhận dạng giọng nói',
'roleConfig.llm': 'Mô hình ngôn ngữ chính',
@@ -1554,4 +1668,4 @@ export default {
// Header navigation
'header.addressBook': 'Danh bạ',
}
}
+64 -3
View File
@@ -807,6 +807,8 @@ export default {
'roleConfig.restartNotice': '保存配置后,需要重启设备,新的配置才会生效。',
'roleConfig.saveConfig': '保存配置',
'roleConfig.snapshotHistory': '历史版本',
'roleConfig.currentVersion': '当前版本 {version}',
'roleConfig.functionName': '功能名称',
'roleConfig.reset': '重置',
'roleConfig.agentName': '助手昵称',
'roleConfig.roleTemplate': '角色模版',
@@ -816,7 +818,7 @@ export default {
'roleConfig.vad': '语音活动检测(VAD)',
'roleConfig.asr': '语音识别(ASR)',
'roleConfig.llm': '主语言模型(LLM)',
"roleConfig.slm": "小参数模型(SLM)",
'roleConfig.slm': '小参数模型(SLM)',
'roleConfig.vllm': '视觉大模型(VLLM)',
'roleConfig.intent': '意图识别(Intent)',
'roleConfig.memoryHis': '记忆',
@@ -873,6 +875,7 @@ export default {
'agentSnapshot.actions': '操作',
'agentSnapshot.view': '查看',
'agentSnapshot.restore': '恢复',
'agentSnapshot.delete': '删除',
'agentSnapshot.detailTitle': '变更详情',
'agentSnapshot.restorePreviewTitle': '恢复确认',
'agentSnapshot.confirmRestore': '确认恢复',
@@ -880,16 +883,28 @@ export default {
'agentSnapshot.after': '变化后',
'agentSnapshot.emptyValue': '无',
'agentSnapshot.noChangedContent': '暂无可展示的变更内容',
'agentSnapshot.restoreConfirm': '确定恢复到版本 #{version} 吗?当前配置会先自动保存为新的历史版本。',
'agentSnapshot.noFunctionChange': '功能配置无变化',
'agentSnapshot.beforeChange': '变化前',
'agentSnapshot.afterChange': '变化后',
'agentSnapshot.beforeRestore': '恢复前',
'agentSnapshot.afterRestore': '恢复后',
'agentSnapshot.restoreMemoryWarning': '恢复到无记忆版本会清空该智能体的聊天记录,请确认后再继续。',
'agentSnapshot.restoreConfirm': '确定恢复到版本 {version} 吗?当前配置会先自动保存为新的历史版本。',
'agentSnapshot.restoreSuccess': '已恢复历史版本',
'agentSnapshot.restoreFailed': '恢复历史版本失败',
'agentSnapshot.restoreFailedRollback': '恢复历史版本失败,事务已回滚,当前配置未改变',
'agentSnapshot.deleteConfirm': '确定删除版本 {version} 吗?删除后不可恢复。',
'agentSnapshot.deleteSuccess': '已删除历史版本',
'agentSnapshot.deleteFailed': '删除历史版本失败',
'agentSnapshot.fetchFailed': '获取历史版本失败',
'agentSnapshot.detailFailed': '获取快照详情失败',
'agentSnapshot.currentVersion': '当前版本',
'agentSnapshot.source.config': '配置保存',
'agentSnapshot.source.current': '当前配置',
'agentSnapshot.source.restore': '恢复前',
'agentSnapshot.source.initial': '初始版本',
'agentSnapshot.field.restore': '恢复操作',
'agentSnapshot.field.initial': '初始快照',
'agentSnapshot.field.agentCode': '助手编码',
'agentSnapshot.field.agentName': '助手昵称',
'agentSnapshot.field.asrModelId': '语音识别',
@@ -916,6 +931,52 @@ export default {
'agentSnapshot.field.correctWordFileIds': '替换词',
'agentSnapshot.field.tagNames': '标签',
'agentSnapshot.field.tagIds': '标签ID',
'agentSnapshot.function.added': '已开启',
'agentSnapshot.function.removed': '已关闭',
'agentSnapshot.function.updated': '参数变更',
'agentSnapshot.function.enabled': '已开启',
'agentSnapshot.function.disabled': '未开启',
'agentSnapshot.function.disabledNote': '未开启此功能',
'agentSnapshot.function.noParams': '无需配置参数',
'agentSnapshot.chatHistoryConf.none': '不记录聊天记录',
'agentSnapshot.chatHistoryConf.text': '上报文字',
'agentSnapshot.chatHistoryConf.textVoice': '上报文字+语音',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': '天气查询',
'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': '服务器音乐播放',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': '中新网新闻',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'newsnow新闻聚合',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'HomeAssistant设备状态查询',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'HomeAssistant设备状态修改',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'HomeAssistant音乐播放',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': '联网搜索',
'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': '设备呼叫设备',
'agentSnapshot.pluginField.url': '接口地址',
'agentSnapshot.pluginField.news_sources': '新闻源配置',
'agentSnapshot.pluginField.default_rss_url': '默认 RSS 源',
'agentSnapshot.pluginField.society_rss_url': '社会新闻 RSS 地址',
'agentSnapshot.pluginField.world_rss_url': '国际新闻 RSS 地址',
'agentSnapshot.pluginField.finance_rss_url': '财经新闻 RSS 地址',
'agentSnapshot.pluginField.api_key': 'API 密钥',
'agentSnapshot.pluginField.default_location': '默认查询城市',
'agentSnapshot.pluginField.api_host': '开发者 API Host',
'agentSnapshot.pluginField.base_url': '服务器地址',
'agentSnapshot.pluginField.devices': '设备列表',
'agentSnapshot.pluginField.provider': '搜索源',
'agentSnapshot.pluginField.description': '工具描述',
'agentSnapshot.pluginField.max_results': '返回数量',
'agentSnapshot.model.Memory_nomem': '无记忆',
'agentSnapshot.model.Memory_mem_local_short': '本地短记忆',
'agentSnapshot.model.Memory_mem0ai': 'Mem0AI记忆',
'agentSnapshot.model.Memory_mem_report_only': '仅上报记忆',
'agentSnapshot.model.Intent_nointent': '无意图识别',
'agentSnapshot.model.Intent_intent_llm': '外挂的大模型意图识别',
'agentSnapshot.model.Intent_function_call': '大模型自主函数调用',
'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS女声-晓晓',
'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS男声-云扬',
'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS女声-晓伊',
'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS男声-云健',
'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS男声-云希',
'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS男声-云夏',
// 表单字段 Tooltip 提示说明
'roleConfig.tooltip.agentName': '设置智能体的名称,用于标识和识别您的AI助手',
@@ -928,7 +989,7 @@ export default {
'roleConfig.tooltip.vad': '语音活动检测(Voice Activity Detection):检测用户何时开始或结束说话,用于判断对话的开始和结束,实现打断功能',
'roleConfig.tooltip.asr': '自动语音识别(Automatic Speech Recognition):将用户的语音转换为文字,是人机对话的第一步,支持多语言识别',
'roleConfig.tooltip.llm': '主语言模型(Large Language Model):AI助手的"大脑",负责理解用户意图、生成回答和执行各种任务',
"roleConfig.tooltip.slm": '小参数模型(Small Language Model):用于智能体唤醒,生成记忆总结标题',
'roleConfig.tooltip.slm': '小参数模型(Small Language Model):用于智能体唤醒,生成记忆总结标题',
'roleConfig.tooltip.vllm': '视觉大语言模型(Visual LLM):处理图像和视频理解,使AI助手能够分析和描述摄像头捕获的画面内容',
'roleConfig.tooltip.intent': '意图识别(Intent Detection):分析用户语音或文本,判断用户的真实意图,如查询、聊天、控制设备等',
'roleConfig.tooltip.memory': '记忆模型(Memory Model):管理对话历史的存储和摘要,决定AI能否记住之前的对话内容,实现长期记忆功能',
+115 -1
View File
@@ -806,12 +806,126 @@ export default {
'roleConfig.addTag': '添加新標籤',
'roleConfig.restartNotice': '保存配置後,需要重啟設備,新的配置才會生效。',
'roleConfig.saveConfig': '保存配置',
'roleConfig.snapshotHistory': '歷史版本',
'roleConfig.currentVersion': '目前版本 {version}',
'roleConfig.functionName': '功能名稱',
'roleConfig.reset': '重置',
'roleConfig.agentName': '助手暱稱',
'roleConfig.roleTemplate': '角色模版',
'roleConfig.roleIntroduction': '角色介紹',
'roleConfig.languageCode': '語言編碼',
'roleConfig.interactionLanguage': '交互語種',
'agentSnapshot.title': '歷史版本',
'agentSnapshot.empty': '暫無歷史版本',
'agentSnapshot.version': '版本',
'agentSnapshot.createdAt': '保存時間',
'agentSnapshot.source': '來源',
'agentSnapshot.changedFields': '變更內容',
'agentSnapshot.actions': '操作',
'agentSnapshot.view': '查看',
'agentSnapshot.restore': '恢復',
'agentSnapshot.delete': '刪除',
'agentSnapshot.detailTitle': '變更詳情',
'agentSnapshot.restorePreviewTitle': '恢復確認',
'agentSnapshot.confirmRestore': '確認恢復',
'agentSnapshot.before': '之前',
'agentSnapshot.after': '之後',
'agentSnapshot.emptyValue': '無',
'agentSnapshot.noChangedContent': '暫無可展示的變更內容',
'agentSnapshot.noFunctionChange': '功能配置無變化',
'agentSnapshot.beforeChange': '變化前',
'agentSnapshot.afterChange': '變化後',
'agentSnapshot.beforeRestore': '恢復前',
'agentSnapshot.afterRestore': '恢復後',
'agentSnapshot.restoreMemoryWarning': '恢復到無記憶版本會清空該智能體的聊天記錄,請確認後再繼續。',
'agentSnapshot.restoreConfirm': '確定恢復到版本 {version} 嗎?目前配置會先自動保存為新的歷史版本。',
'agentSnapshot.restoreSuccess': '已恢復歷史版本',
'agentSnapshot.restoreFailed': '恢復歷史版本失敗',
'agentSnapshot.restoreFailedRollback': '恢復歷史版本失敗,交易已回滾,目前配置未改變',
'agentSnapshot.deleteConfirm': '確定刪除版本 {version} 嗎?刪除後無法復原。',
'agentSnapshot.deleteSuccess': '已刪除歷史版本',
'agentSnapshot.deleteFailed': '刪除歷史版本失敗',
'agentSnapshot.fetchFailed': '獲取歷史版本失敗',
'agentSnapshot.detailFailed': '獲取快照詳情失敗',
'agentSnapshot.currentVersion': '目前版本',
'agentSnapshot.source.config': '配置保存',
'agentSnapshot.source.current': '目前配置',
'agentSnapshot.source.restore': '恢復前',
'agentSnapshot.source.initial': '初始版本',
'agentSnapshot.field.restore': '恢復操作',
'agentSnapshot.field.initial': '初始快照',
'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',
'agentSnapshot.function.added': '已開啟',
'agentSnapshot.function.removed': '已關閉',
'agentSnapshot.function.updated': '參數變更',
'agentSnapshot.function.enabled': '已開啟',
'agentSnapshot.function.disabled': '未開啟',
'agentSnapshot.function.disabledNote': '未開啟此功能',
'agentSnapshot.function.noParams': '無需配置參數',
'agentSnapshot.chatHistoryConf.none': '不記錄聊天記錄',
'agentSnapshot.chatHistoryConf.text': '上報文字',
'agentSnapshot.chatHistoryConf.textVoice': '上報文字+語音',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEATHER': '天氣查詢',
'agentSnapshot.plugin.SYSTEM_PLUGIN_MUSIC': '伺服器音樂播放',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_CHINANEWS': '中新網新聞',
'agentSnapshot.plugin.SYSTEM_PLUGIN_NEWS_NEWSNOW': 'newsnow新聞聚合',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_GET_STATE': 'HomeAssistant設備狀態查詢',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_SET_STATE': 'HomeAssistant設備狀態修改',
'agentSnapshot.plugin.SYSTEM_PLUGIN_HA_PLAY_MUSIC': 'HomeAssistant音樂播放',
'agentSnapshot.plugin.SYSTEM_PLUGIN_WEB_SEARCH': '聯網搜尋',
'agentSnapshot.plugin.SYSTEM_PLUGIN_CALL_DEVICE': '設備呼叫設備',
'agentSnapshot.pluginField.url': '接口地址',
'agentSnapshot.pluginField.news_sources': '新聞源配置',
'agentSnapshot.pluginField.default_rss_url': '預設 RSS 源',
'agentSnapshot.pluginField.society_rss_url': '社會新聞 RSS 地址',
'agentSnapshot.pluginField.world_rss_url': '國際新聞 RSS 地址',
'agentSnapshot.pluginField.finance_rss_url': '財經新聞 RSS 地址',
'agentSnapshot.pluginField.api_key': 'API 密鑰',
'agentSnapshot.pluginField.default_location': '預設查詢城市',
'agentSnapshot.pluginField.api_host': '開發者 API Host',
'agentSnapshot.pluginField.base_url': '伺服器地址',
'agentSnapshot.pluginField.devices': '設備列表',
'agentSnapshot.pluginField.provider': '搜尋源',
'agentSnapshot.pluginField.description': '工具描述',
'agentSnapshot.pluginField.max_results': '返回數量',
'agentSnapshot.model.Memory_nomem': '無記憶',
'agentSnapshot.model.Memory_mem_local_short': '本地短記憶',
'agentSnapshot.model.Memory_mem0ai': 'Mem0AI記憶',
'agentSnapshot.model.Memory_mem_report_only': '僅上報記憶',
'agentSnapshot.model.Intent_nointent': '無意圖識別',
'agentSnapshot.model.Intent_intent_llm': '外掛的大模型意圖識別',
'agentSnapshot.model.Intent_function_call': '大模型自主函式呼叫',
'agentSnapshot.voice.TTS_EdgeTTS0001': 'EdgeTTS女聲-曉曉',
'agentSnapshot.voice.TTS_EdgeTTS0002': 'EdgeTTS男聲-雲揚',
'agentSnapshot.voice.TTS_EdgeTTS0003': 'EdgeTTS女聲-曉伊',
'agentSnapshot.voice.TTS_EdgeTTS0004': 'EdgeTTS男聲-雲健',
'agentSnapshot.voice.TTS_EdgeTTS0005': 'EdgeTTS男聲-雲希',
'agentSnapshot.voice.TTS_EdgeTTS0006': 'EdgeTTS男聲-雲夏',
'roleConfig.vad': '語音活動檢測(VAD)',
'roleConfig.asr': '語音識別(ASR)',
'roleConfig.llm': '主語言模型(LLM)',
@@ -1553,4 +1667,4 @@ export default {
'addressBookManagement.monthsAgo': '{months}個月前',
'addressBookManagement.yearsAgo': '{years}年前',
}
}
+36 -23
View File
@@ -17,7 +17,7 @@
</div>
<span class="header-title">{{ form.agentName }}</span>
<span v-if="currentVersionNo" class="current-version-tag">
当前版本 #{{ currentVersionNo }}
{{ $t("roleConfig.currentVersion", { version: currentVersionNo }) }}
</span>
</div>
<div class="header-tags">
@@ -319,7 +319,7 @@
placement="top"
>
<div slot="content">
<div><strong>功能名称:</strong> {{ func.name }}</div>
<div><strong>{{ $t("roleConfig.functionName") }}:</strong> {{ func.name }}</div>
</div>
<div class="icon-dot">
{{ getFunctionDisplayChar(func.name) }}
@@ -562,6 +562,7 @@ export default {
asr: false, // 语音识别功能状态
},
dynamicTags: [],
originalTagNames: [],
inputVisible: false,
inputValue: '',
checkedReplacementWordIds: []
@@ -618,8 +619,12 @@ export default {
}),
contextProviders: this.currentContextProviders,
correctWordFileIds: this.checkedReplacementWordIds,
tagNames: this.dynamicTags.map(tag => tag.tagName),
};
const tagNames = this.dynamicTags.map(tag => tag.tagName);
const tagsChanged = !this.isSameStringList(tagNames, this.originalTagNames);
if (tagsChanged) {
configData.tagNames = tagNames;
}
// 只在用户设置了TTS参数时才传递(不为null/undefined
if (this.form.ttsVolume !== null && this.form.ttsVolume !== undefined) {
@@ -631,13 +636,20 @@ export default {
if (this.form.ttsPitch !== null && this.form.ttsPitch !== undefined) {
configData.ttsPitch = this.form.ttsPitch;
}
Api.agent.updateAgentConfig(this.$route.query.agentId, configData, ({ data }) => {
const agentId = this.$route.query.agentId;
Api.agent.updateAgentConfig(agentId, configData, ({ data }) => {
if (data.code === 0) {
this.$message.success({
message: i18n.t("roleConfig.saveSuccess"),
showClose: true,
});
this.fetchCurrentVersion(this.$route.query.agentId);
const afterSave = () => {
if (tagsChanged) {
this.originalTagNames = [...tagNames];
}
this.$message.success({
message: i18n.t("roleConfig.saveSuccess"),
showClose: true,
});
this.fetchCurrentVersion(agentId);
};
afterSave();
} else {
this.$message.error({
message: data.msg || i18n.t("roleConfig.saveFailed"),
@@ -661,17 +673,11 @@ export default {
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;
}
Api.agent.getDeviceConfig(agentId, ({ data }) => {
if (data.code === 0) {
this.currentVersionNo = data.data?.currentVersionNo || null;
}
);
});
},
resetConfig() {
this.$confirm(i18n.t("roleConfig.confirmReset"), i18n.t("message.info"), {
@@ -862,7 +868,7 @@ export default {
});
this.$set(this.modelOptions, model.type, LLMdata);
} else {
this.$message.error(data.msg || "获取LLM模型列表失败");
this.$message.error(data.msg || i18n.t("roleConfig.fetchModelsFailed"));
}
});
}
@@ -1385,7 +1391,7 @@ export default {
handleInputConfirm() {
let inputValue = this.inputValue;
if (inputValue) {
const tag = { id: new Date().getTime(), tagName: inputValue };
const tag = { id: `tmp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, tagName: inputValue };
this.dynamicTags.push(tag);
}
this.inputVisible = false;
@@ -1395,14 +1401,21 @@ export default {
Api.agent.getAgentTags(agentId, ({ data }) => {
if (data.code === 0) {
this.dynamicTags = data.data || [];
this.originalTagNames = this.dynamicTags.map(tag => tag.tagName);
}
});
},
handleSaveAgentTags(agentId) {
isSameStringList(left, right) {
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) {
return false;
}
return left.every((value, index) => value === right[index]);
},
handleSaveAgentTags(agentId, tagNames = this.dynamicTags.map(tag => tag.tagName)) {
return new Promise((resolve, reject) => {
const tagNames = this.dynamicTags.map(tag => tag.tagName);
Api.agent.saveAgentTags(agentId, { tagNames }, ({ data }) => {
if (data.code === 0) {
this.originalTagNames = [...tagNames];
resolve();
} else {
reject(data.msg);