diff --git a/astrbot/core/astr_main_agent.py b/astrbot/core/astr_main_agent.py index fddde68d9a..7883dca8fd 100644 --- a/astrbot/core/astr_main_agent.py +++ b/astrbot/core/astr_main_agent.py @@ -42,7 +42,6 @@ from astrbot.core.platform.astr_message_event import AstrMessageEvent from astrbot.core.provider import Provider from astrbot.core.provider.entities import ProviderRequest -from astrbot.core.provider.manager import llm_tools from astrbot.core.skills.skill_manager import SkillManager, build_skills_prompt from astrbot.core.star.context import Context from astrbot.core.star.star_handler import star_map @@ -770,14 +769,6 @@ def _plugin_tool_fix(event: AstrMessageEvent, req: ProviderRequest) -> None: if plugin.name in event.plugins_name or plugin.reserved: new_tool_set.add_tool(tool) req.func_tool = new_tool_set - else: - # mcp tools - tool_set = req.func_tool - if not tool_set: - tool_set = ToolSet() - for tool in llm_tools.func_list: - if isinstance(tool, MCPTool): - tool_set.add_tool(tool) async def _handle_webchat( diff --git a/dashboard/src/components/shared/AstrBotConfigV4.vue b/dashboard/src/components/shared/AstrBotConfigV4.vue index b4ab52f8ce..9c86c419a6 100644 --- a/dashboard/src/components/shared/AstrBotConfigV4.vue +++ b/dashboard/src/components/shared/AstrBotConfigV4.vue @@ -4,6 +4,7 @@ import { VueMonacoEditor } from '@guolao/vue-monaco-editor' import { ref, computed } from 'vue' import ConfigItemRenderer from './ConfigItemRenderer.vue' import TemplateListEditor from './TemplateListEditor.vue' +import PersonaQuickPreview from './PersonaQuickPreview.vue' import { useI18n, useModuleI18n } from '@/i18n/composables' @@ -274,6 +275,16 @@ function getSpecialSubtype(value) { + + + + + + + @@ -433,6 +444,15 @@ function getSpecialSubtype(value) { padding: 0 8px; } +.persona-preview-row { + margin: 16px; + margin-top: 0; +} + +.persona-preview-display { + padding: 0 8px; +} + .selected-plugins-full-width { background-color: rgba(var(--v-theme-primary), 0.05); border: 1px solid rgba(var(--v-theme-primary), 0.1); diff --git a/dashboard/src/components/shared/PersonaQuickPreview.vue b/dashboard/src/components/shared/PersonaQuickPreview.vue new file mode 100644 index 0000000000..2eb21647a1 --- /dev/null +++ b/dashboard/src/components/shared/PersonaQuickPreview.vue @@ -0,0 +1,287 @@ + + + + + diff --git a/dashboard/src/components/shared/PersonaSelector.vue b/dashboard/src/components/shared/PersonaSelector.vue index a77f27640b..07a5358d3c 100644 --- a/dashboard/src/components/shared/PersonaSelector.vue +++ b/dashboard/src/components/shared/PersonaSelector.vue @@ -188,10 +188,16 @@ function openEditPersona(persona: Persona) { // 人格保存成功(创建或编辑) async function handlePersonaSaved(message: string) { console.log('人格保存成功:', message) + const savedPersonaId = editingPersona.value?.persona_id || '' showPersonaDialog.value = false editingPersona.value = null // 刷新当前文件夹的人格列表 await loadPersonasInFolder(currentFolderId.value) + window.dispatchEvent( + new CustomEvent('astrbot:persona-saved', { + detail: { persona_id: savedPersonaId } + }) + ) } // 错误处理 diff --git a/dashboard/src/i18n/locales/en-US/core/shared.json b/dashboard/src/i18n/locales/en-US/core/shared.json index cc4b81094e..d3c3e59fed 100644 --- a/dashboard/src/i18n/locales/en-US/core/shared.json +++ b/dashboard/src/i18n/locales/en-US/core/shared.json @@ -62,6 +62,23 @@ "rootFolder": "All Personas", "emptyFolder": "This folder is empty" }, + "personaQuickPreview": { + "title": "Quick Persona Preview", + "loading": "Loading...", + "noPersonaSelected": "No persona selected", + "personaNotFound": "Persona details not found", + "systemPromptLabel": "System Prompt", + "toolsLabel": "Tools", + "skillsLabel": "Skills", + "originLabel": "Origin", + "originNameLabel": "Origin Name", + "allTools": "All tools available", + "allToolsWithCount": "All tools available ({count})", + "noTools": "No tools configured", + "allSkills": "All Skills available", + "allSkillsWithCount": "All Skills available ({count})", + "noSkills": "No Skills configured" + }, "t2iTemplateEditor": { "buttonText": "Customize T2I Template", "dialogTitle": "Customize Text-to-Image HTML Template", diff --git a/dashboard/src/i18n/locales/en-US/features/subagent.json b/dashboard/src/i18n/locales/en-US/features/subagent.json index b72ef1b40c..355d923c95 100644 --- a/dashboard/src/i18n/locales/en-US/features/subagent.json +++ b/dashboard/src/i18n/locales/en-US/features/subagent.json @@ -19,7 +19,8 @@ "enabled": "When on: the main LLM keeps its own tools and mounts transfer_to_* delegate tools. With deduplication, tools overlapping with SubAgents are removed from the main tool set." }, "section": { - "title": "SubAgents" + "title": "SubAgents", + "globalSettings": "Global Settings" }, "cards": { "statusEnabled": "Enabled", diff --git a/dashboard/src/i18n/locales/zh-CN/core/shared.json b/dashboard/src/i18n/locales/zh-CN/core/shared.json index 9831b4eb11..74b7fa20ba 100644 --- a/dashboard/src/i18n/locales/zh-CN/core/shared.json +++ b/dashboard/src/i18n/locales/zh-CN/core/shared.json @@ -62,6 +62,23 @@ "rootFolder": "全部人格", "emptyFolder": "此文件夹为空" }, + "personaQuickPreview": { + "title": "快速预览", + "loading": "加载中...", + "noPersonaSelected": "未选择人格", + "personaNotFound": "未找到该人格的详情", + "systemPromptLabel": "系统提示词", + "toolsLabel": "工具", + "skillsLabel": "技能(Skills)", + "originLabel": "来源", + "originNameLabel": "来源名称", + "allTools": "全部工具可用", + "allToolsWithCount": "全部工具可用({count})", + "noTools": "未配置工具", + "allSkills": "全部 Skills 可用", + "allSkillsWithCount": "全部 Skills 可用({count})", + "noSkills": "未配置 Skills" + }, "t2iTemplateEditor": { "buttonText": "自定义 T2I 模板", "dialogTitle": "自定义文转图 HTML 模板", diff --git a/dashboard/src/i18n/locales/zh-CN/features/persona.json b/dashboard/src/i18n/locales/zh-CN/features/persona.json index ac1f9f1466..b2484844e7 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/persona.json +++ b/dashboard/src/i18n/locales/zh-CN/features/persona.json @@ -24,7 +24,7 @@ "presetDialogsHelp": "添加一些预设的对话来帮助机器人更好地理解角色设定。", "userMessage": "用户消息", "assistantMessage": "AI 回答", - "tools": "工具选择", + "tools": "工具 / MCP 工具选择", "toolsHelp": "为这个人格选择可用的外部工具。外部工具给了 AI 接触外部环境的能力,如搜索、计算、获取信息等。", "toolsSelection": "工具选择操作", "selectAllTools": "选择所有工具", diff --git a/dashboard/src/i18n/locales/zh-CN/features/subagent.json b/dashboard/src/i18n/locales/zh-CN/features/subagent.json index 2e210720ba..014422780b 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/subagent.json +++ b/dashboard/src/i18n/locales/zh-CN/features/subagent.json @@ -19,7 +19,8 @@ "enabled": "启动:主 LLM 会保留自身工具并挂载 transfer_to_* 委派工具。若开启“去重重复工具”,与 SubAgent 指定的工具重叠部分会从主 LLM 工具集中移除。" }, "section": { - "title": "SubAgents" + "title": "SubAgents 配置", + "globalSettings": "全局设置" }, "cards": { "statusEnabled": "启用", @@ -28,7 +29,8 @@ "transferPrefix": "transfer_to_{name}", "switchLabel": "启用", "previewTitle": "预览:主 LLM 将看到的 handoff 工具", - "personaChip": "Persona: {id}" + "personaChip": "Persona: {id}", + "noDescription": "暂无描述" }, "form": { "nameLabel": "Agent 名称(用于 transfer_to_{name})", diff --git a/dashboard/src/views/ConversationPage.vue b/dashboard/src/views/ConversationPage.vue index ff53301b1b..3d25855f32 100644 --- a/dashboard/src/views/ConversationPage.vue +++ b/dashboard/src/views/ConversationPage.vue @@ -1121,7 +1121,7 @@ export default { .text-truncate { display: inline-block; - max-width: 100px; + /* max-width: 100px; */ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; diff --git a/dashboard/src/views/SubAgentPage.vue b/dashboard/src/views/SubAgentPage.vue index 3870f2d0cc..18e057e837 100644 --- a/dashboard/src/views/SubAgentPage.vue +++ b/dashboard/src/views/SubAgentPage.vue @@ -1,155 +1,249 @@ @@ -158,9 +252,12 @@ import { computed, onMounted, ref } from 'vue' import axios from 'axios' import ProviderSelector from '@/components/shared/ProviderSelector.vue' +import PersonaSelector from '@/components/shared/PersonaSelector.vue' +import PersonaQuickPreview from '@/components/shared/PersonaQuickPreview.vue' import { useModuleI18n } from '@/i18n/composables' type SubAgentItem = { + __key: string name: string persona_id: string @@ -196,9 +293,6 @@ const cfg = ref({ agents: [] }) -const personaOptions = ref<{ title: string; value: string }[]>([]) -const personaLoading = ref(false) - const mainStateDescription = computed(() => cfg.value.main_enable ? tm('description.enabled') : tm('description.disabled') ) @@ -244,24 +338,6 @@ async function loadConfig() { } } -async function loadPersonas() { - personaLoading.value = true - try { - const res = await axios.get('/api/persona/list') - if (res.data.status === 'ok') { - const list = Array.isArray(res.data.data) ? res.data.data : [] - personaOptions.value = list.map((p: any) => ({ - title: p.persona_id, - value: p.persona_id - })) - } - } catch (e: any) { - toast(e?.response?.data?.message || tm('messages.loadPersonaFailed'), 'error') - } finally { - personaLoading.value = false - } -} - function addAgent() { cfg.value.agents.push({ __key: `${Date.now()}_${Math.random().toString(16).slice(2)}`, @@ -333,7 +409,7 @@ async function save() { } async function reload() { - await Promise.all([loadConfig(), loadPersonas()]) + await Promise.all([loadConfig()]) } onMounted(() => { @@ -343,101 +419,21 @@ onMounted(() => { - -