mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-25 00:23:53 +08:00
feat: improve agent snapshot history
This commit is contained in:
@@ -2,7 +2,11 @@ import type {
|
||||
Agent,
|
||||
AgentCreateData,
|
||||
AgentDetail,
|
||||
AgentSnapshot,
|
||||
AgentSnapshotPageParams,
|
||||
CorrectWordFile,
|
||||
ModelOption,
|
||||
PageData,
|
||||
RoleTemplate,
|
||||
} from './types'
|
||||
import { http } from '@/http/request/alova'
|
||||
@@ -100,7 +104,7 @@ export function getTTSVoices(ttsModelId: string, voiceName: string = '') {
|
||||
}
|
||||
|
||||
// 更新智能体
|
||||
export function updateAgent(id: string, data: Partial<AgentDetail>) {
|
||||
export function updateAgent(id: string, data: Partial<AgentDetail> & { tagNames?: string[] }) {
|
||||
return http.Put(`/agent/${id}`, data, {
|
||||
meta: {
|
||||
ignoreAuth: false,
|
||||
@@ -220,3 +224,63 @@ export function getAllLanguage(modelId: string) {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 获取智能体历史版本列表
|
||||
export function getAgentSnapshots(agentId: string, params: AgentSnapshotPageParams) {
|
||||
return http.Get<PageData<AgentSnapshot>>(`/agent/${agentId}/snapshots`, {
|
||||
params,
|
||||
meta: {
|
||||
ignoreAuth: false,
|
||||
toast: false,
|
||||
},
|
||||
cacheFor: {
|
||||
expire: 0,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 获取智能体历史版本详情
|
||||
export function getAgentSnapshot(agentId: string, snapshotId: string) {
|
||||
return http.Get<AgentSnapshot>(`/agent/${agentId}/snapshots/${snapshotId}`, {
|
||||
meta: {
|
||||
ignoreAuth: false,
|
||||
toast: false,
|
||||
},
|
||||
cacheFor: {
|
||||
expire: 0,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 恢复智能体历史版本
|
||||
export function restoreAgentSnapshot(agentId: string, snapshotId: string) {
|
||||
return http.Post(`/agent/${agentId}/snapshots/${snapshotId}/restore`, {}, {
|
||||
meta: {
|
||||
ignoreAuth: false,
|
||||
toast: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 删除智能体历史版本
|
||||
export function deleteAgentSnapshot(agentId: string, snapshotId: string) {
|
||||
return http.Delete(`/agent/${agentId}/snapshots/${snapshotId}`, {
|
||||
meta: {
|
||||
ignoreAuth: false,
|
||||
toast: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 获取所有替换词文件
|
||||
export function getCorrectWordFiles() {
|
||||
return http.Get<CorrectWordFile[]>('/correct-word/file/select', {
|
||||
meta: {
|
||||
ignoreAuth: false,
|
||||
toast: false,
|
||||
},
|
||||
cacheFor: {
|
||||
expire: 0,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -44,10 +44,12 @@ export interface AgentDetail {
|
||||
createdAt: string
|
||||
updater: string
|
||||
updatedAt: string
|
||||
ttsLanguage: string
|
||||
ttsVolume: number
|
||||
ttsRate: number
|
||||
ttsPitch: number
|
||||
ttsLanguage: string | null
|
||||
ttsVolume: number | null
|
||||
ttsRate: number | null
|
||||
ttsPitch: number | null
|
||||
currentVersionNo?: number | null
|
||||
tagNames?: string[]
|
||||
functions: AgentFunction[]
|
||||
contextProviders: Providers[]
|
||||
}
|
||||
@@ -67,6 +69,49 @@ export interface AgentFunction {
|
||||
paramInfo: Record<string, string | number | boolean> | null
|
||||
}
|
||||
|
||||
export interface PageData<T> {
|
||||
list: T[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface AgentSnapshotData extends Partial<AgentDetail> {
|
||||
correctWordFileIds?: string[]
|
||||
tagNames?: string[]
|
||||
tags?: Array<{
|
||||
tagName?: string
|
||||
[key: string]: any
|
||||
}>
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface AgentSnapshot {
|
||||
id: string
|
||||
agentId: string
|
||||
userId?: number
|
||||
versionNo: number
|
||||
changedFields?: string[]
|
||||
fieldOrder?: string[]
|
||||
source?: string
|
||||
restoreFromSnapshotId?: string | null
|
||||
restoreFromVersionNo?: number | null
|
||||
creator?: number
|
||||
createdAt?: string
|
||||
snapshotData?: AgentSnapshotData
|
||||
afterSnapshotData?: AgentSnapshotData
|
||||
}
|
||||
|
||||
export interface AgentSnapshotPageParams {
|
||||
page?: number
|
||||
limit?: number
|
||||
maxVersionNo?: number
|
||||
}
|
||||
|
||||
export interface CorrectWordFile {
|
||||
id: string
|
||||
fileName: string
|
||||
wordCount?: number
|
||||
}
|
||||
|
||||
// 角色模板数据类型
|
||||
export interface RoleTemplate {
|
||||
id: string
|
||||
@@ -78,6 +123,7 @@ export interface RoleTemplate {
|
||||
vllmModelId: string
|
||||
ttsModelId: string
|
||||
ttsVoiceId: string
|
||||
ttsLanguage?: string | null
|
||||
memModelId: string
|
||||
intentModelId: string
|
||||
chatHistoryConf: number
|
||||
|
||||
@@ -146,6 +146,81 @@ export default {
|
||||
'agent.speedHint': '-100=langsamst, 0=Standard, 100=schnellst',
|
||||
'agent.pitchHint': '-100=tiefst, 0=Standard, 100=höchst',
|
||||
|
||||
// Agent-Versionsverlauf
|
||||
'agentSnapshot.title': 'Versionsverlauf',
|
||||
'agentSnapshot.empty': 'Noch keine Versionen',
|
||||
'agentSnapshot.emptyTip': 'Gespeicherte Konfigurationen erscheinen hier',
|
||||
'agentSnapshot.version': 'Version',
|
||||
'agentSnapshot.createdAt': 'Gespeichert am',
|
||||
'agentSnapshot.source': 'Quelle',
|
||||
'agentSnapshot.changedFields': 'Änderungen',
|
||||
'agentSnapshot.view': 'Ansehen',
|
||||
'agentSnapshot.restore': 'Wiederherstellen',
|
||||
'agentSnapshot.delete': 'Löschen',
|
||||
'agentSnapshot.loadMore': 'Mehr laden',
|
||||
'agentSnapshot.detailTitle': 'Änderungsdetails',
|
||||
'agentSnapshot.restorePreviewTitle': 'Wiederherstellungsvorschau',
|
||||
'agentSnapshot.confirmRestore': 'Wiederherstellung bestätigen',
|
||||
'agentSnapshot.currentVersion': 'Aktuelle Version',
|
||||
'agentSnapshot.beforeChange': 'Vorher',
|
||||
'agentSnapshot.afterChange': 'Nachher',
|
||||
'agentSnapshot.beforeRestore': 'Vor der Wiederherstellung',
|
||||
'agentSnapshot.afterRestore': 'Nach der Wiederherstellung',
|
||||
'agentSnapshot.configValue': 'Konfigurationswert',
|
||||
'agentSnapshot.emptyValue': 'Keine',
|
||||
'agentSnapshot.secretRedacted': 'Geheimnis verborgen',
|
||||
'agentSnapshot.noChangedContent': 'Keine anzeigbaren Änderungen',
|
||||
'agentSnapshot.restoreConfirm': 'Version #{version} wiederherstellen? Die aktuelle Konfiguration wird zuerst als neue Version gespeichert.',
|
||||
'agentSnapshot.restoreMemoryWarning': 'Beim Wiederherstellen einer Version ohne Speicher wird der Chatverlauf dieses Agenten gelöscht. Bitte Risiko bestätigen.',
|
||||
'agentSnapshot.restoreSuccess': 'Version wurde wiederhergestellt',
|
||||
'agentSnapshot.restoreFailed': 'Version konnte nicht wiederhergestellt werden',
|
||||
'agentSnapshot.deleteConfirm': 'Version #{version} löschen? Dies kann nicht rückgängig gemacht werden.',
|
||||
'agentSnapshot.deleteSuccess': 'Version gelöscht',
|
||||
'agentSnapshot.deleteFailed': 'Version konnte nicht gelöscht werden',
|
||||
'agentSnapshot.fetchFailed': 'Versionsverlauf konnte nicht abgerufen werden',
|
||||
'agentSnapshot.detailFailed': 'Versionsdetails konnten nicht abgerufen werden',
|
||||
'agentSnapshot.correctWordCount': '{count} Ersatzwörter',
|
||||
'agentSnapshot.source.config': 'Konfiguration gespeichert',
|
||||
'agentSnapshot.source.current': 'Aktuelle Konfiguration',
|
||||
'agentSnapshot.source.restore': 'Vor der Wiederherstellung',
|
||||
'agentSnapshot.source.initial': 'Initialversion',
|
||||
'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': 'Speichermodus',
|
||||
'agentSnapshot.field.intentModelId': 'Absichtserkennung',
|
||||
'agentSnapshot.field.chatHistoryConf': 'Chatverlauf-Konfiguration',
|
||||
'agentSnapshot.field.systemPrompt': 'Rollenbeschreibung',
|
||||
'agentSnapshot.field.summaryMemory': 'Speicher',
|
||||
'agentSnapshot.field.langCode': 'Sprachcode',
|
||||
'agentSnapshot.field.language': 'Interaktionssprache',
|
||||
'agentSnapshot.field.sort': 'Sortierung',
|
||||
'agentSnapshot.field.functions': 'Plugins',
|
||||
'agentSnapshot.field.contextProviders': 'Kontextquellen',
|
||||
'agentSnapshot.field.correctWordFileIds': 'Ersatzwörter',
|
||||
'agentSnapshot.field.tagNames': 'Agent-Labels',
|
||||
'agentSnapshot.chatHistoryConf.none': 'Chatverlauf nicht aufzeichnen',
|
||||
'agentSnapshot.chatHistoryConf.text': 'Text melden',
|
||||
'agentSnapshot.chatHistoryConf.textVoice': 'Text und Sprache melden',
|
||||
'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',
|
||||
|
||||
// Context provider dialog related
|
||||
'contextProviderDialog.title': 'Quelle bearbeiten',
|
||||
'contextProviderDialog.noContextApi': 'Keine Kontext-API',
|
||||
|
||||
@@ -146,6 +146,81 @@ export default {
|
||||
'agent.speedHint': '-100=Slower, 0=Standard, 100=Faster',
|
||||
'agent.pitchHint': '-100=Lowest, 0=Standard, 100=Highest',
|
||||
|
||||
// Agent snapshots
|
||||
'agentSnapshot.title': 'Version History',
|
||||
'agentSnapshot.empty': 'No versions yet',
|
||||
'agentSnapshot.emptyTip': 'Saved configs will appear here',
|
||||
'agentSnapshot.version': 'Version',
|
||||
'agentSnapshot.createdAt': 'Saved At',
|
||||
'agentSnapshot.source': 'Source',
|
||||
'agentSnapshot.changedFields': 'Changes',
|
||||
'agentSnapshot.view': 'View',
|
||||
'agentSnapshot.restore': 'Restore',
|
||||
'agentSnapshot.delete': 'Delete',
|
||||
'agentSnapshot.loadMore': 'Load More',
|
||||
'agentSnapshot.detailTitle': 'Change Details',
|
||||
'agentSnapshot.restorePreviewTitle': 'Restore Preview',
|
||||
'agentSnapshot.confirmRestore': 'Confirm Restore',
|
||||
'agentSnapshot.currentVersion': 'Current Version',
|
||||
'agentSnapshot.beforeChange': 'Before',
|
||||
'agentSnapshot.afterChange': 'After',
|
||||
'agentSnapshot.beforeRestore': 'Before Restore',
|
||||
'agentSnapshot.afterRestore': 'After Restore',
|
||||
'agentSnapshot.configValue': 'Config Value',
|
||||
'agentSnapshot.emptyValue': 'None',
|
||||
'agentSnapshot.secretRedacted': 'Secret hidden',
|
||||
'agentSnapshot.noChangedContent': 'No displayable changes',
|
||||
'agentSnapshot.restoreConfirm': 'Restore to version #{version}? The current config will be saved as a new version first.',
|
||||
'agentSnapshot.restoreMemoryWarning': 'Restoring to a no-memory version will clear this agent\'s chat history. Please confirm the risk.',
|
||||
'agentSnapshot.restoreSuccess': 'Version restored',
|
||||
'agentSnapshot.restoreFailed': 'Failed to restore version',
|
||||
'agentSnapshot.deleteConfirm': 'Delete version #{version}? This cannot be undone.',
|
||||
'agentSnapshot.deleteSuccess': 'Version deleted',
|
||||
'agentSnapshot.deleteFailed': 'Failed to delete version',
|
||||
'agentSnapshot.fetchFailed': 'Failed to fetch versions',
|
||||
'agentSnapshot.detailFailed': 'Failed to fetch version details',
|
||||
'agentSnapshot.correctWordCount': '{count} replacement words',
|
||||
'agentSnapshot.source.config': 'Config Save',
|
||||
'agentSnapshot.source.current': 'Current Config',
|
||||
'agentSnapshot.source.restore': 'Before Restore',
|
||||
'agentSnapshot.source.initial': 'Initial Version',
|
||||
'agentSnapshot.field.initial': 'Initial Snapshot',
|
||||
'agentSnapshot.field.agentCode': 'Agent Code',
|
||||
'agentSnapshot.field.agentName': 'Nickname',
|
||||
'agentSnapshot.field.asrModelId': 'Speech Recognition',
|
||||
'agentSnapshot.field.vadModelId': 'Voice Activity Detection',
|
||||
'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 Mode',
|
||||
'agentSnapshot.field.intentModelId': 'Intent Recognition',
|
||||
'agentSnapshot.field.chatHistoryConf': 'Chat History Config',
|
||||
'agentSnapshot.field.systemPrompt': 'Role Description',
|
||||
'agentSnapshot.field.summaryMemory': 'Memory',
|
||||
'agentSnapshot.field.langCode': 'Language Code',
|
||||
'agentSnapshot.field.language': 'Interaction Language',
|
||||
'agentSnapshot.field.sort': 'Sort',
|
||||
'agentSnapshot.field.functions': 'Plugins',
|
||||
'agentSnapshot.field.contextProviders': 'Context Sources',
|
||||
'agentSnapshot.field.correctWordFileIds': 'Replacement Words',
|
||||
'agentSnapshot.field.tagNames': 'Agent Tags',
|
||||
'agentSnapshot.chatHistoryConf.none': 'Do not record chat history',
|
||||
'agentSnapshot.chatHistoryConf.text': 'Report text',
|
||||
'agentSnapshot.chatHistoryConf.textVoice': 'Report text and voice',
|
||||
'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',
|
||||
|
||||
// Context provider dialog related
|
||||
'contextProviderDialog.title': 'Edit Source',
|
||||
'contextProviderDialog.noContextApi': 'No Context API',
|
||||
|
||||
@@ -146,6 +146,81 @@ export default {
|
||||
'agent.speedHint': '-100=Slower, 0=Standard, 100=Faster',
|
||||
'agent.pitchHint': '-100=Lowest, 0=Standard, 100=Highest',
|
||||
|
||||
// Histórico de versões do agente
|
||||
'agentSnapshot.title': 'Histórico de Versões',
|
||||
'agentSnapshot.empty': 'Ainda sem versões',
|
||||
'agentSnapshot.emptyTip': 'Configurações salvas aparecerão aqui',
|
||||
'agentSnapshot.version': 'Versão',
|
||||
'agentSnapshot.createdAt': 'Salvo em',
|
||||
'agentSnapshot.source': 'Origem',
|
||||
'agentSnapshot.changedFields': 'Alterações',
|
||||
'agentSnapshot.view': 'Ver',
|
||||
'agentSnapshot.restore': 'Restaurar',
|
||||
'agentSnapshot.delete': 'Excluir',
|
||||
'agentSnapshot.loadMore': 'Carregar Mais',
|
||||
'agentSnapshot.detailTitle': 'Detalhes da Alteração',
|
||||
'agentSnapshot.restorePreviewTitle': 'Prévia da Restauração',
|
||||
'agentSnapshot.confirmRestore': 'Confirmar Restauração',
|
||||
'agentSnapshot.currentVersion': 'Versão Atual',
|
||||
'agentSnapshot.beforeChange': 'Antes',
|
||||
'agentSnapshot.afterChange': 'Depois',
|
||||
'agentSnapshot.beforeRestore': 'Antes da Restauração',
|
||||
'agentSnapshot.afterRestore': 'Depois da Restauração',
|
||||
'agentSnapshot.configValue': 'Valor da Configuração',
|
||||
'agentSnapshot.emptyValue': 'Nenhum',
|
||||
'agentSnapshot.secretRedacted': 'Segredo oculto',
|
||||
'agentSnapshot.noChangedContent': 'Nenhuma alteração exibível',
|
||||
'agentSnapshot.restoreConfirm': 'Restaurar para a versão #{version}? A configuração atual será salva como uma nova versão primeiro.',
|
||||
'agentSnapshot.restoreMemoryWarning': 'Restaurar para uma versão sem memória limpará o histórico de chat deste agente. Confirme o risco.',
|
||||
'agentSnapshot.restoreSuccess': 'Versão restaurada',
|
||||
'agentSnapshot.restoreFailed': 'Falha ao restaurar versão',
|
||||
'agentSnapshot.deleteConfirm': 'Excluir versão #{version}? Esta ação não pode ser desfeita.',
|
||||
'agentSnapshot.deleteSuccess': 'Versão excluída',
|
||||
'agentSnapshot.deleteFailed': 'Falha ao excluir versão',
|
||||
'agentSnapshot.fetchFailed': 'Falha ao buscar versões',
|
||||
'agentSnapshot.detailFailed': 'Falha ao buscar detalhes da versão',
|
||||
'agentSnapshot.correctWordCount': '{count} palavras de substituição',
|
||||
'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.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 Voz',
|
||||
'agentSnapshot.field.llmModelId': 'Modelo Principal',
|
||||
'agentSnapshot.field.slmModelId': 'Modelo Pequeno',
|
||||
'agentSnapshot.field.vllmModelId': 'Modelo Visual',
|
||||
'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': 'Tonalidade',
|
||||
'agentSnapshot.field.memModelId': 'Modo de Memória',
|
||||
'agentSnapshot.field.intentModelId': 'Reconhecimento de Intenção',
|
||||
'agentSnapshot.field.chatHistoryConf': 'Configuração do Histórico',
|
||||
'agentSnapshot.field.systemPrompt': 'Descrição do Papel',
|
||||
'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': 'Plugins',
|
||||
'agentSnapshot.field.contextProviders': 'Fontes de Contexto',
|
||||
'agentSnapshot.field.correctWordFileIds': 'Palavras de Substituição',
|
||||
'agentSnapshot.field.tagNames': 'Tags do Agente',
|
||||
'agentSnapshot.chatHistoryConf.none': 'Não registrar histórico de chat',
|
||||
'agentSnapshot.chatHistoryConf.text': 'Reportar texto',
|
||||
'agentSnapshot.chatHistoryConf.textVoice': 'Reportar texto e voz',
|
||||
'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': 'Apenas reportar',
|
||||
'agentSnapshot.model.Intent_nointent': 'Sem reconhecimento de intenção',
|
||||
'agentSnapshot.model.Intent_intent_llm': 'Reconhecimento por LLM externo',
|
||||
'agentSnapshot.model.Intent_function_call': 'Chamada de função por LLM',
|
||||
|
||||
// Diálogo de provedor de contexto
|
||||
'contextProviderDialog.title': 'Editar Fonte',
|
||||
'contextProviderDialog.noContextApi': 'Sem API de Contexto',
|
||||
|
||||
@@ -146,6 +146,81 @@ export default {
|
||||
'agent.speedHint': '-100=Slowest, 0=Standard, 100=Fastest',
|
||||
'agent.pitchHint': '-100=Lowest, 0=Standard, 100=Highest',
|
||||
|
||||
// Lịch sử phiên bản đại lý
|
||||
'agentSnapshot.title': 'Lịch sử phiên bản',
|
||||
'agentSnapshot.empty': 'Chưa có phiên bản',
|
||||
'agentSnapshot.emptyTip': 'Cấu hình đã lưu sẽ xuất hiện ở đây',
|
||||
'agentSnapshot.version': 'Phiên bản',
|
||||
'agentSnapshot.createdAt': 'Thời gian lưu',
|
||||
'agentSnapshot.source': 'Nguồn',
|
||||
'agentSnapshot.changedFields': 'Thay đổi',
|
||||
'agentSnapshot.view': 'Xem',
|
||||
'agentSnapshot.restore': 'Khôi phục',
|
||||
'agentSnapshot.delete': 'Xóa',
|
||||
'agentSnapshot.loadMore': 'Tải thêm',
|
||||
'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.currentVersion': 'Phiên bản hiện tại',
|
||||
'agentSnapshot.beforeChange': 'Trước',
|
||||
'agentSnapshot.afterChange': 'Sau',
|
||||
'agentSnapshot.beforeRestore': 'Trước khôi phục',
|
||||
'agentSnapshot.afterRestore': 'Sau khôi phục',
|
||||
'agentSnapshot.configValue': 'Giá trị cấu hình',
|
||||
'agentSnapshot.emptyValue': 'Không có',
|
||||
'agentSnapshot.secretRedacted': 'Đã ẩn khóa bí mật',
|
||||
'agentSnapshot.noChangedContent': 'Không có thay đổi để hiển thị',
|
||||
'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.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 đại lý này. Vui lòng xác nhận rủi ro.',
|
||||
'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.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',
|
||||
'agentSnapshot.deleteFailed': 'Xóa phiên bản thất bại',
|
||||
'agentSnapshot.fetchFailed': 'Lấy lịch sử phiên bản thất bại',
|
||||
'agentSnapshot.detailFailed': 'Lấy chi tiết phiên bản thất bại',
|
||||
'agentSnapshot.correctWordCount': '{count} từ thay thế',
|
||||
'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 khôi phục',
|
||||
'agentSnapshot.source.initial': 'Phiên bản khởi tạo',
|
||||
'agentSnapshot.field.initial': 'Ảnh chụp ban đầu',
|
||||
'agentSnapshot.field.agentCode': 'Mã đại lý',
|
||||
'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': 'Tổng hợp giọng nói',
|
||||
'agentSnapshot.field.ttsVoiceId': 'Giọng',
|
||||
'agentSnapshot.field.ttsLanguage': 'Ngôn ngữ',
|
||||
'agentSnapshot.field.ttsVolume': 'Âm lượng',
|
||||
'agentSnapshot.field.ttsRate': 'Tốc độ',
|
||||
'agentSnapshot.field.ttsPitch': 'Tone',
|
||||
'agentSnapshot.field.memModelId': 'Chế độ bộ nhớ',
|
||||
'agentSnapshot.field.intentModelId': 'Nhận dạng ý định',
|
||||
'agentSnapshot.field.chatHistoryConf': 'Cấu hình lịch sử chat',
|
||||
'agentSnapshot.field.systemPrompt': 'Mô tả vai trò',
|
||||
'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': 'Plugin',
|
||||
'agentSnapshot.field.contextProviders': 'Nguồn ngữ cảnh',
|
||||
'agentSnapshot.field.correctWordFileIds': 'Từ thay thế',
|
||||
'agentSnapshot.field.tagNames': 'Nhãn đại lý',
|
||||
'agentSnapshot.chatHistoryConf.none': 'Không ghi lịch sử chat',
|
||||
'agentSnapshot.chatHistoryConf.text': 'Gửi văn bản',
|
||||
'agentSnapshot.chatHistoryConf.textVoice': 'Gửi văn bản và giọng nói',
|
||||
'agentSnapshot.model.Memory_nomem': 'Không có bộ nhớ',
|
||||
'agentSnapshot.model.Memory_mem_local_short': 'Bộ nhớ ngắn hạn cục bộ',
|
||||
'agentSnapshot.model.Memory_mem0ai': 'Bộ nhớ Mem0AI',
|
||||
'agentSnapshot.model.Memory_mem_report_only': 'Chỉ gửi báo cáo',
|
||||
'agentSnapshot.model.Intent_nointent': 'Không nhận dạng ý định',
|
||||
'agentSnapshot.model.Intent_intent_llm': 'Nhận dạng ý định LLM ngoài',
|
||||
'agentSnapshot.model.Intent_function_call': 'Gọi hàm bằng LLM',
|
||||
|
||||
// Context provider dialog related
|
||||
'contextProviderDialog.title': 'Chỉnh sửa nguồn',
|
||||
'contextProviderDialog.noContextApi': 'Không có API ngữ cảnh',
|
||||
@@ -507,4 +582,4 @@ export default {
|
||||
'voiceprint.audioNotExist': 'Âm thanh không tồn tại',
|
||||
'voiceprint.getAudioFailed': 'Không thể lấy âm thanh',
|
||||
'voiceprint.audioPlayFailed': 'Phát âm thanh thất bại',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +146,81 @@ export default {
|
||||
'agent.speedHint': '-100=最慢, 0=标准, 100=最快',
|
||||
'agent.pitchHint': '-100=最低, 0=标准, 100=最高',
|
||||
|
||||
// 智能体历史版本
|
||||
'agentSnapshot.title': '历史版本',
|
||||
'agentSnapshot.empty': '暂无历史版本',
|
||||
'agentSnapshot.emptyTip': '保存配置后会生成历史版本',
|
||||
'agentSnapshot.version': '版本',
|
||||
'agentSnapshot.createdAt': '保存时间',
|
||||
'agentSnapshot.source': '来源',
|
||||
'agentSnapshot.changedFields': '变更内容',
|
||||
'agentSnapshot.view': '查看',
|
||||
'agentSnapshot.restore': '恢复',
|
||||
'agentSnapshot.delete': '删除',
|
||||
'agentSnapshot.loadMore': '加载更多',
|
||||
'agentSnapshot.detailTitle': '变更详情',
|
||||
'agentSnapshot.restorePreviewTitle': '恢复预览',
|
||||
'agentSnapshot.confirmRestore': '确认恢复',
|
||||
'agentSnapshot.currentVersion': '当前版本',
|
||||
'agentSnapshot.beforeChange': '变化前',
|
||||
'agentSnapshot.afterChange': '变化后',
|
||||
'agentSnapshot.beforeRestore': '恢复前',
|
||||
'agentSnapshot.afterRestore': '恢复后',
|
||||
'agentSnapshot.configValue': '配置值',
|
||||
'agentSnapshot.emptyValue': '无',
|
||||
'agentSnapshot.secretRedacted': '密钥已隐藏',
|
||||
'agentSnapshot.noChangedContent': '无可显示变更',
|
||||
'agentSnapshot.restoreConfirm': '确定恢复到版本 #{version}?当前配置会先保存为新的历史版本。',
|
||||
'agentSnapshot.restoreMemoryWarning': '恢复到无记忆版本会清空该智能体聊天记录,请确认风险。',
|
||||
'agentSnapshot.restoreSuccess': '版本已恢复',
|
||||
'agentSnapshot.restoreFailed': '版本恢复失败',
|
||||
'agentSnapshot.deleteConfirm': '确定删除版本 #{version}?此操作不可撤销。',
|
||||
'agentSnapshot.deleteSuccess': '历史版本已删除',
|
||||
'agentSnapshot.deleteFailed': '历史版本删除失败',
|
||||
'agentSnapshot.fetchFailed': '获取历史版本失败',
|
||||
'agentSnapshot.detailFailed': '获取版本详情失败',
|
||||
'agentSnapshot.correctWordCount': '共 {count} 个替换词',
|
||||
'agentSnapshot.source.config': '配置保存',
|
||||
'agentSnapshot.source.current': '当前配置',
|
||||
'agentSnapshot.source.restore': '恢复前备份',
|
||||
'agentSnapshot.source.initial': '初始版本',
|
||||
'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.chatHistoryConf.none': '不记录聊天记录',
|
||||
'agentSnapshot.chatHistoryConf.text': '上报文字',
|
||||
'agentSnapshot.chatHistoryConf.textVoice': '上报文字+语音',
|
||||
'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': '大模型函数调用',
|
||||
|
||||
// 上下文源对话框相关
|
||||
'contextProviderDialog.title': '编辑源',
|
||||
'contextProviderDialog.noContextApi': '暂无上下文API',
|
||||
|
||||
@@ -167,6 +167,81 @@ export default {
|
||||
'agent.speedHint': '-100=最慢, 0=標準, 100=最快',
|
||||
'agent.pitchHint': '-100=最低, 0=標準, 100=最高',
|
||||
|
||||
// 智能體歷史版本
|
||||
'agentSnapshot.title': '歷史版本',
|
||||
'agentSnapshot.empty': '暫無歷史版本',
|
||||
'agentSnapshot.emptyTip': '保存配置後會生成歷史版本',
|
||||
'agentSnapshot.version': '版本',
|
||||
'agentSnapshot.createdAt': '保存時間',
|
||||
'agentSnapshot.source': '來源',
|
||||
'agentSnapshot.changedFields': '變更內容',
|
||||
'agentSnapshot.view': '查看',
|
||||
'agentSnapshot.restore': '恢復',
|
||||
'agentSnapshot.delete': '刪除',
|
||||
'agentSnapshot.loadMore': '載入更多',
|
||||
'agentSnapshot.detailTitle': '變更詳情',
|
||||
'agentSnapshot.restorePreviewTitle': '恢復預覽',
|
||||
'agentSnapshot.confirmRestore': '確認恢復',
|
||||
'agentSnapshot.currentVersion': '當前版本',
|
||||
'agentSnapshot.beforeChange': '變化前',
|
||||
'agentSnapshot.afterChange': '變化後',
|
||||
'agentSnapshot.beforeRestore': '恢復前',
|
||||
'agentSnapshot.afterRestore': '恢復後',
|
||||
'agentSnapshot.configValue': '配置值',
|
||||
'agentSnapshot.emptyValue': '無',
|
||||
'agentSnapshot.secretRedacted': '密鑰已隱藏',
|
||||
'agentSnapshot.noChangedContent': '無可顯示變更',
|
||||
'agentSnapshot.restoreConfirm': '確定恢復到版本 #{version}?當前配置會先保存為新的歷史版本。',
|
||||
'agentSnapshot.restoreMemoryWarning': '恢復到無記憶版本會清空該智能體聊天記錄,請確認風險。',
|
||||
'agentSnapshot.restoreSuccess': '版本已恢復',
|
||||
'agentSnapshot.restoreFailed': '版本恢復失敗',
|
||||
'agentSnapshot.deleteConfirm': '確定刪除版本 #{version}?此操作不可復原。',
|
||||
'agentSnapshot.deleteSuccess': '歷史版本已刪除',
|
||||
'agentSnapshot.deleteFailed': '歷史版本刪除失敗',
|
||||
'agentSnapshot.fetchFailed': '獲取歷史版本失敗',
|
||||
'agentSnapshot.detailFailed': '獲取版本詳情失敗',
|
||||
'agentSnapshot.correctWordCount': '共 {count} 個替換詞',
|
||||
'agentSnapshot.source.config': '配置保存',
|
||||
'agentSnapshot.source.current': '當前配置',
|
||||
'agentSnapshot.source.restore': '恢復前備份',
|
||||
'agentSnapshot.source.initial': '初始版本',
|
||||
'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.chatHistoryConf.none': '不記錄聊天記錄',
|
||||
'agentSnapshot.chatHistoryConf.text': '上報文字',
|
||||
'agentSnapshot.chatHistoryConf.textVoice': '上報文字+語音',
|
||||
'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': '大模型函數調用',
|
||||
|
||||
// 上下文源对话框相关
|
||||
'contextProviderDialog.title': '編輯源',
|
||||
'contextProviderDialog.noContextApi': '暫無上下文API',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"globalStyle": {
|
||||
"navigationStyle": "default",
|
||||
"navigationBarTitleText": "智控台",
|
||||
"navigationBarTitleText": "小智",
|
||||
"navigationBarBackgroundColor": "#f8f8f8",
|
||||
"navigationBarTextStyle": "black",
|
||||
"backgroundColor": "#FFFFFF"
|
||||
@@ -74,6 +74,24 @@
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/agent/provider",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationBarTitleText": "编辑源",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/agent/speedPitch",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationBarTitleText": "语音设置",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/agent/tools",
|
||||
"type": "page",
|
||||
@@ -126,6 +144,42 @@
|
||||
"navigationBarTitleText": "Login"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/privacy-policy-en",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "Privacy Policy"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/privacy-policy-zh",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "隐私政策"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/user-agreement-en",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "User Agreement"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/user-agreement-zh",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "用户协议"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/register/index",
|
||||
"type": "page",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import type { AgentDetail, ModelOption, PluginDefinition, RoleTemplate } from '@/api/agent/types'
|
||||
import { computed, nextTick, onMounted, ref, watch } from 'vue'
|
||||
import { getAgentDetail, getAgentTags, getAllLanguage, getModelOptions, getPluginFunctions, getRoleTemplates, updateAgent, updateAgentTags } from '@/api/agent/agent'
|
||||
import { getAgentDetail, getAgentTags, getAllLanguage, getModelOptions, getPluginFunctions, getRoleTemplates, updateAgent } from '@/api/agent/agent'
|
||||
import { t } from '@/i18n'
|
||||
import { usePluginStore, useProvider, useSpeedPitch } from '@/store'
|
||||
import { toast } from '@/utils/toast'
|
||||
import AgentSnapshotPanel from './components/AgentSnapshotPanel.vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'AgentEdit',
|
||||
@@ -64,6 +65,8 @@ const selectedTemplateId = ref('')
|
||||
// 加载状态
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const showSnapshotPanel = ref(false)
|
||||
const currentVersionNo = ref<number | null>(null)
|
||||
|
||||
// 模型选项数据
|
||||
const modelOptions = ref<{
|
||||
@@ -79,9 +82,9 @@ const modelOptions = ref<{
|
||||
})
|
||||
|
||||
// 音色选项数据
|
||||
const voiceOptions = ref([])
|
||||
const voiceOptions = ref<any[]>([])
|
||||
// 保存完整的音色信息
|
||||
const voiceDetails = ref({})
|
||||
const voiceDetails = ref<Record<string, any>>({})
|
||||
|
||||
// 上报模式选项数据
|
||||
const reportOptions = [
|
||||
@@ -110,9 +113,15 @@ const allFunctions = ref<PluginDefinition[]>([])
|
||||
const dynamicTags = ref([])
|
||||
const inputValue = ref('')
|
||||
const inputVisible = ref(false)
|
||||
const languageOptions = ref([])
|
||||
const languageOptions = ref<any[]>([])
|
||||
const isVisibleReport = ref(false)
|
||||
const tempSummaryMemory = ref('')
|
||||
const selectedTtsLanguage = ref('')
|
||||
const ttsLanguageTouched = ref(false)
|
||||
const ttsVoiceTouched = ref(false)
|
||||
const ttsOptionsLoading = ref(false)
|
||||
const originalTagNames = ref<string[]>([])
|
||||
let ttsOptionsRequestSequence = 0
|
||||
|
||||
// 音频播放相关
|
||||
const audioRef = ref<UniApp.InnerAudioContext | null>(null)
|
||||
@@ -212,9 +221,14 @@ async function loadAgentDetail() {
|
||||
try {
|
||||
loading.value = true
|
||||
tempSummaryMemory.value = ''
|
||||
ttsLanguageTouched.value = false
|
||||
ttsVoiceTouched.value = false
|
||||
ttsOptionsRequestSequence += 1
|
||||
ttsOptionsLoading.value = false
|
||||
const detail = await getAgentDetail(agentId.value)
|
||||
const normalizedFunctions = normalizeAgentFunctions(detail.functions || [])
|
||||
formData.value = { ...detail, functions: normalizedFunctions }
|
||||
currentVersionNo.value = detail.currentVersionNo || null
|
||||
|
||||
// 更新插件store
|
||||
pluginStore.setCurrentAgentId(agentId.value)
|
||||
@@ -222,17 +236,27 @@ async function loadAgentDetail() {
|
||||
|
||||
// 更新语速音调
|
||||
speedPitchStore.updateSpeedPitch({
|
||||
ttsVolume: detail.ttsVolume || 0,
|
||||
ttsRate: detail.ttsRate || 0,
|
||||
ttsPitch: detail.ttsPitch || 0,
|
||||
ttsVolume: detail.ttsVolume ?? 0,
|
||||
ttsRate: detail.ttsRate ?? 0,
|
||||
ttsPitch: detail.ttsPitch ?? 0,
|
||||
})
|
||||
speedPitchStore.resetChangedFields()
|
||||
|
||||
// 加载上下文配置
|
||||
providerStore.updateProviders(detail.contextProviders || [])
|
||||
|
||||
// 如果有TTS模型,加载对应的音色选项
|
||||
if (detail.ttsModelId) {
|
||||
await fetchAllLanguag(detail.ttsModelId)
|
||||
await fetchAllLanguag(detail.ttsModelId, {
|
||||
preferredLanguage: detail.ttsLanguage,
|
||||
preferredVoiceId: detail.ttsVoiceId,
|
||||
})
|
||||
}
|
||||
else {
|
||||
voiceOptions.value = []
|
||||
voiceDetails.value = {}
|
||||
languageOptions.value = []
|
||||
selectedTtsLanguage.value = ''
|
||||
}
|
||||
|
||||
// 等待模型选项加载完成后再更新显示名称
|
||||
@@ -344,7 +368,13 @@ async function loadModelOptions() {
|
||||
}
|
||||
|
||||
// 根据语言筛选音色
|
||||
function filterVoicesByLanguage() {
|
||||
interface VoiceSelectionOptions {
|
||||
autoSelectVoice?: boolean
|
||||
preferredLanguage?: string | null
|
||||
preferredVoiceId?: string | null
|
||||
}
|
||||
|
||||
function filterVoicesByLanguage(options: VoiceSelectionOptions = {}) {
|
||||
if (!voiceDetails.value || Object.keys(voiceDetails.value).length === 0) {
|
||||
voiceOptions.value = []
|
||||
return
|
||||
@@ -358,7 +388,7 @@ function filterVoicesByLanguage() {
|
||||
return false
|
||||
}
|
||||
const languagesArray = voice.languages.split(/[、;;,,]/).map(lang => lang.trim()).filter(lang => lang)
|
||||
return languagesArray.includes(formData.value.language)
|
||||
return languagesArray.includes(selectedTtsLanguage.value)
|
||||
})
|
||||
|
||||
voiceOptions.value = filteredVoices.map(voice => ({
|
||||
@@ -374,26 +404,37 @@ function filterVoicesByLanguage() {
|
||||
const currentVoiceSupportsLanguage = formData.value.ttsVoiceId
|
||||
&& filteredVoices.some(voice => voice.id === formData.value.ttsVoiceId)
|
||||
|
||||
if (!currentVoiceSupportsLanguage) {
|
||||
if (!currentVoiceSupportsLanguage && options.autoSelectVoice) {
|
||||
formData.value.ttsVoiceId = filteredVoices.length > 0 ? filteredVoices[0].id : ''
|
||||
displayNames.value.voiceprint = filteredVoices.length > 0 ? filteredVoices[0].name : ''
|
||||
ttsVoiceTouched.value = true
|
||||
}
|
||||
else {
|
||||
displayNames.value.voiceprint = filteredVoices.find(item => item.id === formData.value.ttsVoiceId)?.name
|
||||
|| getVoiceDisplayName(formData.value.ttsVoiceId)
|
||||
}
|
||||
}
|
||||
|
||||
// 同步到ttsSettings(如果值为null,使用0作为显示默认值,但不修改form中的值)
|
||||
speedPitchStore.updateSpeedPitch({
|
||||
ttsVolume: formData.value.ttsVolume !== null && formData.value.ttsVolume !== undefined ? formData.value.ttsVolume : 0,
|
||||
ttsRate: formData.value.ttsRate !== null && formData.value.ttsRate !== undefined ? formData.value.ttsRate : 0,
|
||||
ttsPitch: formData.value.ttsPitch !== null && formData.value.ttsPitch !== undefined ? formData.value.ttsPitch : 0,
|
||||
})
|
||||
function getVoiceDefaultLanguage(ttsVoiceId: string) {
|
||||
if (!ttsVoiceId || !voiceDetails.value?.[ttsVoiceId]?.languages) {
|
||||
return ''
|
||||
}
|
||||
const languages = voiceDetails.value[ttsVoiceId].languages
|
||||
.split(/[、;;,,]/)
|
||||
.map(lang => lang.trim())
|
||||
.filter(Boolean)
|
||||
return languages[0] || ''
|
||||
}
|
||||
|
||||
// 根据语音合成模型加载语言
|
||||
async function fetchAllLanguag(ttsModelId: string) {
|
||||
async function fetchAllLanguag(ttsModelId: string, options: VoiceSelectionOptions = {}) {
|
||||
const requestId = ++ttsOptionsRequestSequence
|
||||
ttsOptionsLoading.value = true
|
||||
try {
|
||||
const res = await getAllLanguage(ttsModelId)
|
||||
if (requestId !== ttsOptionsRequestSequence) {
|
||||
return
|
||||
}
|
||||
// 保存完整的音色信息
|
||||
voiceDetails.value = res.reduce((acc, voice) => {
|
||||
acc[voice.id] = voice
|
||||
@@ -412,21 +453,46 @@ async function fetchAllLanguag(ttsModelId: string) {
|
||||
name: lang,
|
||||
}))
|
||||
|
||||
// 使用后端返回的用户选择的语言,如果没有则使用第一个语言选项
|
||||
if (formData.value.ttsLanguage && languageOptions.value.some(option => option.value === formData.value.ttsLanguage)) {
|
||||
formData.value.language = formData.value.ttsLanguage
|
||||
const requestedLanguage = options.preferredLanguage
|
||||
const preferredVoiceLanguage = options.preferredVoiceId
|
||||
? getVoiceDefaultLanguage(options.preferredVoiceId)
|
||||
: ''
|
||||
// 优先使用调用方指定的语言或音色默认语言,再回退到智能体当前配置
|
||||
if (requestedLanguage && languageOptions.value.some(option => option.value === requestedLanguage)) {
|
||||
selectedTtsLanguage.value = requestedLanguage
|
||||
displayNames.value.language = requestedLanguage
|
||||
}
|
||||
else if (preferredVoiceLanguage && languageOptions.value.some(option => option.value === preferredVoiceLanguage)) {
|
||||
selectedTtsLanguage.value = preferredVoiceLanguage
|
||||
displayNames.value.language = preferredVoiceLanguage
|
||||
}
|
||||
else if (formData.value.ttsLanguage && languageOptions.value.some(option => option.value === formData.value.ttsLanguage)) {
|
||||
selectedTtsLanguage.value = formData.value.ttsLanguage
|
||||
displayNames.value.language = formData.value.ttsLanguage
|
||||
}
|
||||
else if (getVoiceDefaultLanguage(formData.value.ttsVoiceId)) {
|
||||
selectedTtsLanguage.value = getVoiceDefaultLanguage(formData.value.ttsVoiceId)
|
||||
displayNames.value.language = selectedTtsLanguage.value
|
||||
}
|
||||
else if (languageOptions.value.length > 0) {
|
||||
formData.value.language = languageOptions.value[0].value
|
||||
selectedTtsLanguage.value = languageOptions.value[0].value
|
||||
displayNames.value.language = languageOptions.value[0].value
|
||||
}
|
||||
|
||||
// 根据选中的语言筛选音色
|
||||
filterVoicesByLanguage()
|
||||
filterVoicesByLanguage(options)
|
||||
}
|
||||
catch {
|
||||
languageOptions.value = []
|
||||
if (requestId === ttsOptionsRequestSequence) {
|
||||
voiceOptions.value = []
|
||||
voiceDetails.value = {}
|
||||
languageOptions.value = []
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (requestId === ttsOptionsRequestSequence) {
|
||||
ttsOptionsLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +523,8 @@ function selectRoleTemplate(templateId: string) {
|
||||
selectedTemplateId.value = templateId
|
||||
const template = roleTemplates.value.find(t => t.id === templateId)
|
||||
if (template) {
|
||||
const templateTtsLanguage = template.ttsLanguage?.trim() || ''
|
||||
const hasTemplateTtsLanguage = Boolean(templateTtsLanguage)
|
||||
formData.value = {
|
||||
...formData.value,
|
||||
systemPrompt: template.systemPrompt || formData.value.systemPrompt,
|
||||
@@ -469,18 +537,34 @@ function selectRoleTemplate(templateId: string) {
|
||||
memModelId: template.memModelId || formData.value.memModelId,
|
||||
ttsModelId: template.ttsModelId || formData.value.ttsModelId,
|
||||
ttsVoiceId: template.ttsVoiceId || formData.value.ttsVoiceId,
|
||||
ttsLanguage: hasTemplateTtsLanguage ? templateTtsLanguage : formData.value.ttsLanguage,
|
||||
agentName: template.agentName || formData.value.agentName,
|
||||
chatHistoryConf: template.chatHistoryConf || formData.value.chatHistoryConf,
|
||||
summaryMemory: template.summaryMemory || formData.value.summaryMemory,
|
||||
langCode: template.langCode || formData.value.langCode,
|
||||
}
|
||||
fetchAllLanguag(template.ttsModelId || formData.value.ttsModelId)
|
||||
if (hasTemplateTtsLanguage) {
|
||||
selectedTtsLanguage.value = templateTtsLanguage
|
||||
displayNames.value.language = templateTtsLanguage
|
||||
}
|
||||
if (template.ttsModelId || template.ttsVoiceId || hasTemplateTtsLanguage) {
|
||||
ttsLanguageTouched.value = true
|
||||
ttsVoiceTouched.value = true
|
||||
}
|
||||
fetchAllLanguag(template.ttsModelId || formData.value.ttsModelId, {
|
||||
autoSelectVoice: true,
|
||||
preferredLanguage: hasTemplateTtsLanguage ? templateTtsLanguage : '',
|
||||
preferredVoiceId: template.ttsVoiceId,
|
||||
})
|
||||
updateDisplayNames()
|
||||
}
|
||||
}
|
||||
|
||||
// 打开选择器
|
||||
function openPicker(type: string) {
|
||||
if (ttsOptionsLoading.value && (type === 'tts' || type === 'language' || type === 'voiceprint')) {
|
||||
return
|
||||
}
|
||||
pickerShow.value[type] = true
|
||||
}
|
||||
|
||||
@@ -526,16 +610,28 @@ async function onPickerConfirm(type: string, value: any, name: string) {
|
||||
tempSummaryMemory.value = ''
|
||||
}
|
||||
break
|
||||
case 'tts':
|
||||
case 'tts': {
|
||||
const preferredLanguage = selectedTtsLanguage.value
|
||||
formData.value.ttsModelId = value
|
||||
await fetchAllLanguag(value)
|
||||
ttsLanguageTouched.value = true
|
||||
ttsVoiceTouched.value = true
|
||||
formData.value.ttsVoiceId = ''
|
||||
await fetchAllLanguag(value, { autoSelectVoice: true, preferredLanguage })
|
||||
break
|
||||
}
|
||||
case 'language':
|
||||
formData.value.language = value
|
||||
filterVoicesByLanguage()
|
||||
selectedTtsLanguage.value = value
|
||||
formData.value.ttsLanguage = value
|
||||
ttsLanguageTouched.value = true
|
||||
filterVoicesByLanguage({ autoSelectVoice: true })
|
||||
break
|
||||
case 'voiceprint':
|
||||
formData.value.ttsVoiceId = value
|
||||
ttsVoiceTouched.value = true
|
||||
if (selectedTtsLanguage.value) {
|
||||
formData.value.ttsLanguage = selectedTtsLanguage.value
|
||||
ttsLanguageTouched.value = true
|
||||
}
|
||||
displayNames.value.voiceprint = name // 确保显示名称正确更新
|
||||
break
|
||||
case 'report':
|
||||
@@ -623,6 +719,9 @@ function getModelDisplayName(modelType: string, modelId: string) {
|
||||
|
||||
// 保存智能体
|
||||
async function saveAgent() {
|
||||
if (ttsOptionsLoading.value) {
|
||||
return
|
||||
}
|
||||
if (!formData.value.agentName?.trim()) {
|
||||
toast.warning(t('agent.pleaseInputAgentName'))
|
||||
return
|
||||
@@ -633,26 +732,46 @@ async function saveAgent() {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await handleUpdateAgentTags()
|
||||
}
|
||||
catch (err) {
|
||||
toast.error(err)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
saving.value = true
|
||||
const tagNames = dynamicTags.value.map(tag => tag.tagName)
|
||||
const tagsChanged = !isSameStringList(tagNames, originalTagNames.value)
|
||||
// 构建保存数据,包含上下文配置和语音设置
|
||||
const saveData = {
|
||||
const saveData: Record<string, any> = {
|
||||
...formData.value,
|
||||
...speedPitchStore.speedPitch,
|
||||
ttsLanguage: formData.value.language,
|
||||
contextProviders: providerStore.providers,
|
||||
functions: normalizeAgentFunctions(formData.value.functions || []),
|
||||
}
|
||||
delete saveData.ttsVolume
|
||||
delete saveData.ttsRate
|
||||
delete saveData.ttsPitch
|
||||
delete saveData.ttsLanguage
|
||||
delete saveData.ttsVoiceId
|
||||
if (ttsLanguageTouched.value) {
|
||||
saveData.ttsLanguage = selectedTtsLanguage.value
|
||||
}
|
||||
if (ttsVoiceTouched.value) {
|
||||
saveData.ttsVoiceId = formData.value.ttsVoiceId
|
||||
}
|
||||
const changedTtsFields = new Set(speedPitchStore.changedFields)
|
||||
if (changedTtsFields.has('ttsVolume')) {
|
||||
saveData.ttsVolume = speedPitchStore.speedPitch.ttsVolume
|
||||
}
|
||||
if (changedTtsFields.has('ttsRate')) {
|
||||
saveData.ttsRate = speedPitchStore.speedPitch.ttsRate
|
||||
}
|
||||
if (changedTtsFields.has('ttsPitch')) {
|
||||
saveData.ttsPitch = speedPitchStore.speedPitch.ttsPitch
|
||||
}
|
||||
if (tagsChanged) {
|
||||
saveData.tagNames = tagNames
|
||||
}
|
||||
await updateAgent(agentId.value, saveData)
|
||||
loadAgentDetail()
|
||||
if (tagsChanged) {
|
||||
originalTagNames.value = [...tagNames]
|
||||
}
|
||||
speedPitchStore.resetChangedFields()
|
||||
await loadAgentDetail()
|
||||
|
||||
toast.success(t('agent.saveSuccess'))
|
||||
}
|
||||
@@ -700,14 +819,23 @@ async function loadAgentTags() {
|
||||
try {
|
||||
const res = await getAgentTags(agentId.value)
|
||||
dynamicTags.value = res || []
|
||||
originalTagNames.value = dynamicTags.value.map(tag => tag.tagName)
|
||||
}
|
||||
catch (error) {}
|
||||
}
|
||||
|
||||
// 更新智能体标签
|
||||
async function handleUpdateAgentTags() {
|
||||
const tagNames = dynamicTags.value.map(tag => tag.tagName)
|
||||
await updateAgentTags(agentId.value, { tagNames })
|
||||
async function handleSnapshotRestored() {
|
||||
await Promise.all([
|
||||
loadAgentDetail(),
|
||||
loadAgentTags(),
|
||||
])
|
||||
}
|
||||
|
||||
function isSameStringList(left: string[], right: string[]) {
|
||||
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) {
|
||||
return false
|
||||
}
|
||||
return left.every((value, index) => value === right[index])
|
||||
}
|
||||
|
||||
// 监听store中的插件配置变化
|
||||
@@ -734,6 +862,25 @@ onMounted(async () => {
|
||||
|
||||
<template>
|
||||
<view class="bg-[#f5f7fb] px-[20rpx]">
|
||||
<view class="mb-[24rpx] flex items-center justify-between border border-[#eeeeee] rounded-[20rpx] bg-white p-[24rpx]" style="box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);">
|
||||
<view>
|
||||
<text class="block text-[32rpx] text-[#232338] font-bold">
|
||||
{{ t('agent.editTitle') }}
|
||||
</text>
|
||||
<text v-if="currentVersionNo" class="mt-[8rpx] block text-[24rpx] text-[#65686f]">
|
||||
{{ t('agentSnapshot.currentVersion') }} #{{ currentVersionNo }}
|
||||
</text>
|
||||
</view>
|
||||
<wd-button
|
||||
size="small"
|
||||
type="primary"
|
||||
custom-class="!bg-[#336cff] !h-[64rpx] !rounded-[32rpx]"
|
||||
@click="showSnapshotPanel = true"
|
||||
>
|
||||
{{ t('agentSnapshot.title') }}
|
||||
</wd-button>
|
||||
</view>
|
||||
|
||||
<!-- 基础信息标题
|
||||
<view class="pb-[20rpx] first:pt-[20rpx]">
|
||||
<text class="text-[32rpx] text-[#232338] font-bold">
|
||||
@@ -1008,7 +1155,7 @@ onMounted(async () => {
|
||||
<wd-button
|
||||
type="primary"
|
||||
:loading="saving"
|
||||
:disabled="saving"
|
||||
:disabled="saving || ttsOptionsLoading"
|
||||
custom-class="w-full h-[80rpx] rounded-[16rpx] text-[30rpx] font-semibold bg-[#336cff] active:bg-[#2d5bd1]"
|
||||
@click="saveAgent"
|
||||
>
|
||||
@@ -1109,6 +1256,12 @@ onMounted(async () => {
|
||||
@close="onPickerCancel('report')"
|
||||
@select="({ item }) => onPickerConfirm('report', item.value, item.name)"
|
||||
/>
|
||||
<AgentSnapshotPanel
|
||||
v-model:visible="showSnapshotPanel"
|
||||
:agent-id="agentId"
|
||||
:current-version-no="currentVersionNo"
|
||||
@restored="handleSnapshotRestored"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ defineOptions({
|
||||
})
|
||||
|
||||
const speedPitchStore = useSpeedPitch()
|
||||
const SPEED_PITCH_FIELDS = ['ttsVolume', 'ttsRate', 'ttsPitch'] as const
|
||||
|
||||
const localSettings = ref({
|
||||
ttsVolume: 0,
|
||||
@@ -25,7 +26,10 @@ const localSettings = ref({
|
||||
})
|
||||
|
||||
function handleConfirm() {
|
||||
speedPitchStore.updateSpeedPitch(localSettings.value)
|
||||
const changedFields = SPEED_PITCH_FIELDS.filter((field) => {
|
||||
return localSettings.value[field] !== speedPitchStore.speedPitch[field]
|
||||
})
|
||||
speedPitchStore.updateSpeedPitch(localSettings.value, { changedFields })
|
||||
goBack()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,37 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
const SPEED_PITCH_FIELDS = ['ttsVolume', 'ttsRate', 'ttsPitch'] as const
|
||||
|
||||
type SpeedPitchField = typeof SPEED_PITCH_FIELDS[number]
|
||||
type SpeedPitchSettings = Record<SpeedPitchField, number>
|
||||
|
||||
export const useSpeedPitch = defineStore('speedPitch', () => {
|
||||
const speedPitch = ref({
|
||||
const speedPitch = ref<SpeedPitchSettings>({
|
||||
ttsVolume: 0,
|
||||
ttsRate: 0,
|
||||
ttsPitch: 0,
|
||||
})
|
||||
const changedFields = ref<SpeedPitchField[]>([])
|
||||
|
||||
const updateSpeedPitch = (val: typeof speedPitch.value) => {
|
||||
const updateSpeedPitch = (val: SpeedPitchSettings, options: { changedFields?: SpeedPitchField[] } = {}) => {
|
||||
speedPitch.value = val
|
||||
if (options.changedFields) {
|
||||
changedFields.value = Array.from(new Set([
|
||||
...changedFields.value,
|
||||
...options.changedFields,
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
const resetChangedFields = () => {
|
||||
changedFields.value = []
|
||||
}
|
||||
|
||||
return {
|
||||
speedPitch,
|
||||
changedFields,
|
||||
updateSpeedPitch,
|
||||
resetChangedFields,
|
||||
}
|
||||
}, {
|
||||
persist: {
|
||||
|
||||
Reference in New Issue
Block a user