- {{ tm('form.mcpServersQuickSelect') }}
+ {{ tm("form.mcpServersQuickSelect") }}
-
- mdi-server
-
+ mdi-server
{{ server.name }}
-
+
({{ server.tools.length }})
@@ -225,16 +202,11 @@
v-else-if="!loadingTools && availableTools.length === 0"
class="text-center pa-4"
>
-
+
mdi-tools
- {{ tm('form.noToolsAvailable')
- }}
+ {{ tm("form.noToolsAvailable") }}
@@ -242,51 +214,43 @@
v-else-if="!loadingTools && filteredTools.length === 0"
class="text-center pa-4"
>
-
+
mdi-magnify
- {{ tm('form.noToolsFound') }}
+ {{ tm("form.noToolsFound") }}
-
+
+
- {{ tm('form.loadingTools')
- }}
+ {{ tm("form.loadingTools") }}
- {{ tm('form.selectedTools') }}
+ {{ tm("form.selectedTools") }}
- ({{ tm('form.allSelected') }})
+ ({{ tm("form.allSelected") }})
({{ personaForm.tools.length }})
-
- {{ tm('form.noToolsSelected') }}
+
+ {{ tm("form.noToolsSelected") }}
@@ -314,12 +275,13 @@
-
- mdi-lightning-bolt
-
- {{ tm('form.skills') }}
+ mdi-lightning-bolt
+ {{ tm("form.skills") }}
- {{ tm('form.skillsHelp') }}
+ {{ tm("form.skillsHelp") }}
@@ -399,67 +361,60 @@
-
+
mdi-lightning-bolt
- {{ tm('form.noSkillsAvailable') }}
+ {{ tm("form.noSkillsAvailable") }}
-
+
mdi-magnify
- {{ tm('form.noSkillsFound') }}
+ {{ tm("form.noSkillsFound") }}
-
+
+
- {{ tm('form.loadingSkills') }}
+ {{ tm("form.loadingSkills") }}
- {{ tm('form.selectedSkills') }}
+ {{ tm("form.selectedSkills") }}
- ({{ tm('form.allSelected') }})
+ ({{ tm("form.allSelected") }})
({{ personaForm.skills.length }})
-
- {{ tm('form.noSkillsSelected') }}
+
+ {{ tm("form.noSkillsSelected") }}
@@ -487,10 +439,8 @@
-
- mdi-chat
-
- {{ tm('form.presetDialogs') }}
+ mdi-chat
+ {{ tm("form.presetDialogs") }}
- {{ tm('form.presetDialogsHelp') }}
+ {{ tm("form.presetDialogsHelp") }}
@@ -516,7 +466,11 @@
>
- {{ tm('buttons.addDialogPair') }}
+ {{ tm("buttons.addDialogPair") }}
@@ -557,15 +511,11 @@
variant="text"
@click="deletePersona"
>
- {{ tm('buttons.delete') }}
+ {{ tm("buttons.delete") }}
-
- {{ tm('buttons.cancel') }}
+
+ {{ tm("buttons.cancel") }}
- {{ tm('buttons.save') }}
+ {{ tm("buttons.save") }}
@@ -582,597 +532,692 @@
diff --git a/dashboard/src/composables/useSessions.ts b/dashboard/src/composables/useSessions.ts
index b5a7054da..3d9cfb242 100644
--- a/dashboard/src/composables/useSessions.ts
+++ b/dashboard/src/composables/useSessions.ts
@@ -173,8 +173,8 @@ export function useSessions(chatboxMode = false) {
);
const currentSessionDeleted = Boolean(
currentSessionId &&
- sessionIds.includes(currentSessionId) &&
- !failedSessionIds.has(currentSessionId),
+ sessionIds.includes(currentSessionId) &&
+ !failedSessionIds.has(currentSessionId),
);
if (currentSessionDeleted) {
diff --git a/dashboard/src/layouts/full/FullLayout.vue b/dashboard/src/layouts/full/FullLayout.vue
index c1374cc3c..74ed9a83e 100644
--- a/dashboard/src/layouts/full/FullLayout.vue
+++ b/dashboard/src/layouts/full/FullLayout.vue
@@ -17,6 +17,7 @@ const customizer = useCustomizerStore();
const { locale } = useI18n();
const route = useRoute();
const routerLoadingStore = useRouterLoadingStore();
+const isCurrentChatRoute = computed(() => route.path === '/chat' || route.path.startsWith('/chat/'));
const isChatPage = computed(() => {
return route.path.startsWith("/chat");
@@ -127,7 +128,7 @@ onMounted(() => {
({
folderTree: [] as FolderTreeNode[],
currentFolderId: null as string | null,
@@ -59,9 +59,11 @@ export const usePersonaStore = defineStore('persona', {
// 当前文件夹名称
currentFolderName(): string {
if (this.breadcrumbPath.length === 0) {
- return '根目录';
+ return "根目录";
}
- return this.breadcrumbPath[this.breadcrumbPath.length - 1]?.name || '根目录';
+ return (
+ this.breadcrumbPath[this.breadcrumbPath.length - 1]?.name || "根目录"
+ );
},
},
@@ -96,11 +98,11 @@ export const usePersonaStore = defineStore('persona', {
async loadFolderTree(): Promise {
this.treeLoading = true;
try {
- const response = await axios.get('/api/persona/folder/tree');
- if (response.data.status === 'ok') {
+ const response = await axios.get("/api/persona/folder/tree");
+ if (response.data.status === "ok") {
this.folderTree = response.data.data || [];
} else {
- throw new Error(response.data.message || '获取文件夹树失败');
+ throw new Error(response.data.message || "获取文件夹树失败");
}
} finally {
this.treeLoading = false;
@@ -117,19 +119,19 @@ export const usePersonaStore = defineStore('persona', {
// 并行加载子文件夹和 Persona
const [foldersRes, personasRes] = await Promise.all([
- axios.get('/api/persona/folder/list', {
- params: { parent_id: folderId ?? '' }
+ axios.get("/api/persona/folder/list", {
+ params: { parent_id: folderId ?? "" },
}),
- axios.get('/api/persona/list', {
- params: { folder_id: folderId ?? '' }
+ axios.get("/api/persona/list", {
+ params: { folder_id: folderId ?? "" },
}),
]);
- if (foldersRes.data.status === 'ok') {
+ if (foldersRes.data.status === "ok") {
this.currentFolders = foldersRes.data.data || [];
}
- if (personasRes.data.status === 'ok') {
+ if (personasRes.data.status === "ok") {
this.currentPersonas = personasRes.data.data || [];
}
@@ -179,41 +181,41 @@ export const usePersonaStore = defineStore('persona', {
/**
* 移动 Persona 到文件夹
*/
- async movePersonaToFolder(personaId: string, targetFolderId: string | null): Promise {
- const response = await axios.post('/api/persona/move', {
+ async movePersonaToFolder(
+ personaId: string,
+ targetFolderId: string | null,
+ ): Promise {
+ const response = await axios.post("/api/persona/move", {
persona_id: personaId,
- folder_id: targetFolderId
+ folder_id: targetFolderId,
});
- if (response.data.status !== 'ok') {
- throw new Error(response.data.message || '移动人格失败');
+ if (response.data.status !== "ok") {
+ throw new Error(response.data.message || "移动人格失败");
}
// 刷新当前文件夹内容和文件夹树
- await Promise.all([
- this.refreshCurrentFolder(),
- this.loadFolderTree(),
- ]);
+ await Promise.all([this.refreshCurrentFolder(), this.loadFolderTree()]);
},
/**
* 移动文件夹到另一个文件夹
*/
- async moveFolderToFolder(folderId: string, targetParentId: string | null): Promise {
- const response = await axios.post('/api/persona/folder/update', {
+ async moveFolderToFolder(
+ folderId: string,
+ targetParentId: string | null,
+ ): Promise {
+ const response = await axios.post("/api/persona/folder/update", {
folder_id: folderId,
- parent_id: targetParentId
+ parent_id: targetParentId,
});
- if (response.data.status !== 'ok') {
- throw new Error(response.data.message || '移动文件夹失败');
+ if (response.data.status !== "ok") {
+ throw new Error(response.data.message || "移动文件夹失败");
}
// 刷新当前文件夹内容和文件夹树
- await Promise.all([
- this.refreshCurrentFolder(),
- this.loadFolderTree(),
- ]);
+ await Promise.all([this.refreshCurrentFolder(), this.loadFolderTree()]);
},
/**
@@ -224,20 +226,17 @@ export const usePersonaStore = defineStore('persona', {
parent_id?: string | null;
description?: string;
}): Promise {
- const response = await axios.post('/api/persona/folder/create', {
+ const response = await axios.post("/api/persona/folder/create", {
...data,
parent_id: data.parent_id ?? this.currentFolderId,
});
- if (response.data.status !== 'ok') {
- throw new Error(response.data.message || '创建文件夹失败');
+ if (response.data.status !== "ok") {
+ throw new Error(response.data.message || "创建文件夹失败");
}
// 刷新当前文件夹内容和文件夹树
- await Promise.all([
- this.refreshCurrentFolder(),
- this.loadFolderTree(),
- ]);
+ await Promise.all([this.refreshCurrentFolder(), this.loadFolderTree()]);
return response.data.data.folder;
},
@@ -250,48 +249,42 @@ export const usePersonaStore = defineStore('persona', {
name?: string;
description?: string;
}): Promise {
- const response = await axios.post('/api/persona/folder/update', data);
+ const response = await axios.post("/api/persona/folder/update", data);
- if (response.data.status !== 'ok') {
- throw new Error(response.data.message || '更新文件夹失败');
+ if (response.data.status !== "ok") {
+ throw new Error(response.data.message || "更新文件夹失败");
}
// 刷新当前文件夹内容和文件夹树
- await Promise.all([
- this.refreshCurrentFolder(),
- this.loadFolderTree(),
- ]);
+ await Promise.all([this.refreshCurrentFolder(), this.loadFolderTree()]);
},
/**
* 删除文件夹
*/
async deleteFolder(folderId: string): Promise {
- const response = await axios.post('/api/persona/folder/delete', {
- folder_id: folderId
+ const response = await axios.post("/api/persona/folder/delete", {
+ folder_id: folderId,
});
- if (response.data.status !== 'ok') {
- throw new Error(response.data.message || '删除文件夹失败');
+ if (response.data.status !== "ok") {
+ throw new Error(response.data.message || "删除文件夹失败");
}
// 刷新当前文件夹内容和文件夹树
- await Promise.all([
- this.refreshCurrentFolder(),
- this.loadFolderTree(),
- ]);
+ await Promise.all([this.refreshCurrentFolder(), this.loadFolderTree()]);
},
/**
* 删除 Persona
*/
async deletePersona(personaId: string): Promise {
- const response = await axios.post('/api/persona/delete', {
- persona_id: personaId
+ const response = await axios.post("/api/persona/delete", {
+ persona_id: personaId,
});
- if (response.data.status !== 'ok') {
- throw new Error(response.data.message || '删除人格失败');
+ if (response.data.status !== "ok") {
+ throw new Error(response.data.message || "删除人格失败");
}
// 刷新当前文件夹内容
@@ -301,14 +294,17 @@ export const usePersonaStore = defineStore('persona', {
/**
* 克隆 Persona
*/
- async clonePersona(sourcePersonaId: string, newPersonaId: string): Promise {
- const response = await axios.post('/api/persona/clone', {
+ async clonePersona(
+ sourcePersonaId: string,
+ newPersonaId: string,
+ ): Promise {
+ const response = await axios.post("/api/persona/clone", {
source_persona_id: sourcePersonaId,
- new_persona_id: newPersonaId
+ new_persona_id: newPersonaId,
});
- if (response.data.status !== 'ok') {
- throw new Error(response.data.message || '克隆人格失败');
+ if (response.data.status !== "ok") {
+ throw new Error(response.data.message || "克隆人格失败");
}
// 刷新当前文件夹内容
@@ -321,10 +317,10 @@ export const usePersonaStore = defineStore('persona', {
* 批量更新排序
*/
async reorderItems(items: ReorderItem[]): Promise {
- const response = await axios.post('/api/persona/reorder', { items });
+ const response = await axios.post("/api/persona/reorder", { items });
- if (response.data.status !== 'ok') {
- throw new Error(response.data.message || '更新排序失败');
+ if (response.data.status !== "ok") {
+ throw new Error(response.data.message || "更新排序失败");
}
// 刷新当前文件夹内容
@@ -354,7 +350,7 @@ export const usePersonaStore = defineStore('persona', {
* 导入人格数据
*/
async importPersona(data: Partial): Promise {
- const response = await axios.post('/api/persona/create', {
+ const response = await axios.post("/api/persona/create", {
persona_id: data.persona_id,
system_prompt: data.system_prompt,
begin_dialogs: data.begin_dialogs || [],
@@ -362,8 +358,8 @@ export const usePersonaStore = defineStore('persona', {
skills: data.skills,
});
- if (response.data.status !== 'ok') {
- throw new Error(response.data.message || '导入人格失败');
+ if (response.data.status !== "ok") {
+ throw new Error(response.data.message || "导入人格失败");
}
// 刷新当前文件夹内容
@@ -371,5 +367,5 @@ export const usePersonaStore = defineStore('persona', {
return response.data.data.persona;
},
- }
+ },
});
diff --git a/dashboard/src/views/persona/PersonaCard.vue b/dashboard/src/views/persona/PersonaCard.vue
index db8cc9733..cd6de044c 100644
--- a/dashboard/src/views/persona/PersonaCard.vue
+++ b/dashboard/src/views/persona/PersonaCard.vue
@@ -1,7 +1,7 @@
-
- mdi-pencil
-
+ mdi-pencil
- {{ tm('buttons.edit') }}
+ {{ tm("buttons.edit") }}
-
- mdi-content-copy
-
+ mdi-content-copy
- {{ tm('buttons.clone') }}
+ {{ tm("buttons.clone") }}
-
- mdi-folder-move
-
+ mdi-folder-move
- {{ tm('persona.contextMenu.moveTo') }}
+ {{
+ tm("persona.contextMenu.moveTo")
+ }}
-
- mdi-download
-
+ mdi-download
- {{ tm('persona.contextMenu.export') }}
+ {{
+ tm("persona.contextMenu.export")
+ }}
-
+
-
- mdi-delete
-
+ mdi-delete
- {{ tm('buttons.delete') }}
+ {{ tm("buttons.delete") }}
@@ -89,7 +77,11 @@
variant="tonal"
prepend-icon="mdi-chat"
>
- {{ tm('labels.presetDialogs', { count: persona.begin_dialogs.length / 2 }) }}
+ {{
+ tm("labels.presetDialogs", {
+ count: persona.begin_dialogs.length / 2,
+ })
+ }}
- {{ tm('form.allToolsAvailable') }}
+ {{ tm("form.allToolsAvailable") }}
- {{ persona.tools.length }} {{ tm('persona.toolsCount') }}
+ {{ persona.tools.length }} {{ tm("persona.toolsCount") }}
- {{ tm('form.allSkillsAvailable') }}
+ {{ tm("form.allSkillsAvailable") }}
- {{ persona.skills.length }} {{ tm('persona.skillsCount') }}
+ {{ persona.skills.length }} {{ tm("persona.skillsCount") }}
- {{ tm('labels.createdAt') }}: {{ formatDate(persona.created_at) }}
+ {{ tm("labels.createdAt") }}: {{ formatDate(persona.created_at) }}
-
- mdi-account
-
+
+ mdi-account
{{ persona.persona_id }}
diff --git a/dashboard/src/views/persona/PersonaManager.vue b/dashboard/src/views/persona/PersonaManager.vue
index 945c3942a..23e1e58e9 100644
--- a/dashboard/src/views/persona/PersonaManager.vue
+++ b/dashboard/src/views/persona/PersonaManager.vue
@@ -1,268 +1,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- mdi-folder
- {{ tm('folder.foldersTitle') }} ({{ currentFolders.length }})
-
-
-
-
-
-
-
-
-
-
-
- mdi-account-heart
- {{ tm('persona.personasTitle') }} ({{ currentPersonas.length }})
-
-
-
-
-
-
-
-
-
-
-
- mdi-folder-open-outline
- {{ tm('empty.folderEmpty') }}
- {{ tm('empty.folderEmptyDescription') }}
-
-
- {{ tm('buttons.create') }}
-
-
- {{ tm('folder.createButton') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ viewingPersona.persona_id }}
-
-
-
-
-
-
{{ tm('form.systemPrompt') }}
-
{{ viewingPersona.system_prompt }}
-
-
-
-
{{ tm('form.presetDialogs') }}
-
-
- {{ index % 2 === 0 ? tm('form.userMessage') : tm('form.assistantMessage') }}
-
-
{{ dialog }}
-
-
-
-
-
{{ tm('form.tools') }}
-
-
- {{ tm('form.allToolsAvailable') }}
-
-
-
-
- {{ toolName }}
-
-
-
- {{ tm('form.noToolsSelected') }}
-
-
-
-
-
{{ tm('form.skills') }}
-
-
- {{ tm('form.allSkillsAvailable') }}
-
-
-
-
- {{ skillName }}
-
-
-
- {{ tm('form.noSkillsSelected') }}
-
-
-
-
-
{{ tm('labels.createdAt') }}: {{ formatDate(viewingPersona.created_at) }}
-
{{ tm('labels.updatedAt') }}:
- {{ formatDate(viewingPersona.updated_at) }}
-
-
-
-
-
-
-
-
-
-
-
- {{ tm('folder.renameDialog.title') }}
-
-
-
-
-
-
- {{ tm('buttons.cancel') }}
-
-
- {{ tm('buttons.save') }}
-
-
-
-
-
-
-
-
-
-
-
-
- mdi-alert
- {{ tm('folder.deleteDialog.title') }}
-
-
- {{ tm('folder.deleteDialog.message', { name: deleteFolderData?.name ?? '' }) }}
-
- mdi-information
- {{ tm('folder.deleteDialog.warning') }}
-
-
-
-
-
- {{ tm('buttons.cancel') }}
-
-
- {{ tm('buttons.delete') }}
-
-
-
-
-
-
-
- {{ message }}
-
+