diff --git a/README.md b/README.md index 213a8d82..7fc0854d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -# 语析 - 基于大模型的知识库与知识图谱智能体开发平台 +# 📚 语析 - 基于大模型的知识库与知识图谱智能体开发平台 -
+ +
+ Yuxi-Know | Trendshift [![Stable](https://img.shields.io/badge/stable-v0.3.0-blue.svg)](https://github.com/xerrors/Yuxi-Know/tree/v0.3.0) [![](https://img.shields.io/badge/Docker-2496ED?style=flat&logo=docker&logoColor=ffffff)](https://github.com/xerrors/Yuxi-Know/blob/main/docker-compose.yml) @@ -9,7 +11,11 @@ [![DeepWiki](https://img.shields.io/badge/DeepWiki-blue.svg)](https://deepwiki.com/xerrors/Yuxi-Know) [![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/xerrors/Yuxi-Know) [![demo](https://img.shields.io/badge/demo-00A1D6.svg?style=flat&logo=bilibili&logoColor=white)](https://www.bilibili.com/video/BV1DF14BTETq/) -![](https://img.shields.io/github/stars/xerrors/Yuxi-Know) + +
+ +📄 [**文档中心**](https://xerrors.github.io/Yuxi-Know/) | +📽️ [**视频演示**](https://www.bilibili.com/video/BV1DF14BTETq/)
@@ -20,11 +26,6 @@ image - -> [!tip] -> 详细文档请查看全新的 📄[**文档中心**](https://xerrors.github.io/Yuxi-Know/), -> 哔哩哔哩观看 📽️[**视频演示**](https://www.bilibili.com/video/BV1DF14BTETq/) - --- **🎉 最新动态** diff --git a/docs/latest/advanced/branding.md b/docs/latest/advanced/branding.md index 84bb38dc..6a841cfc 100644 --- a/docs/latest/advanced/branding.md +++ b/docs/latest/advanced/branding.md @@ -53,4 +53,8 @@ YUXI_BRAND_FILE_PATH=src/config/static/info.local.yaml ``` -**此外**,`web/src/stores/theme.js` 中也包含了主题相关的配置(需要修改 `colorPrimary`),可根据需要修改。 \ No newline at end of file +**此外**,`web/src/stores/theme.js` 中也包含了主题相关的配置(需要修改 `colorPrimary`),可根据需要修改。 + +## 修改首页 + +首页提供了一个插槽组件 `web/src/components/ProjectOverview.vue`,可以在该组件中自定义项目介绍,当前为空文件。(借助 AI 编程可以设计出更好看的首页的) diff --git a/server/routers/mindmap_router.py b/server/routers/mindmap_router.py index b68b2d21..91e0d3e6 100644 --- a/server/routers/mindmap_router.py +++ b/server/routers/mindmap_router.py @@ -362,38 +362,4 @@ async def get_database_mindmap(db_id: str, current_user: User = Depends(get_admi raise HTTPException(status_code=500, detail=f"获取思维导图失败: {str(e)}") -@mindmap.post("/database/{db_id}") -async def save_database_mindmap( - db_id: str, - mindmap: dict = Body(..., description="思维导图数据"), - current_user: User = Depends(get_admin_user), -): - """ - 保存思维导图到知识库 - Args: - db_id: 知识库ID - mindmap: 思维导图数据 - - Returns: - 保存结果 - """ - try: - # 检查知识库是否存在 - db_info = knowledge_base.get_database_info(db_id) - if not db_info: - raise HTTPException(status_code=404, detail=f"知识库 {db_id} 不存在") - - # TODO: 将思维导图保存到知识库元数据中 - # 这里需要实现一个方法来更新知识库的元数据 - - return { - "message": "success", - "db_id": db_id, - } - - except HTTPException: - raise - except Exception as e: - logger.error(f"保存思维导图失败: {e}, {traceback.format_exc()}") - raise HTTPException(status_code=500, detail=f"保存思维导图失败: {str(e)}") diff --git a/src/agents/chatbot/context.py b/src/agents/chatbot/context.py index 4e12e44a..8892cde1 100644 --- a/src/agents/chatbot/context.py +++ b/src/agents/chatbot/context.py @@ -13,12 +13,16 @@ class Context(BaseContext): default_factory=list, metadata={ "name": "工具", - "options": gen_tool_info(get_tools()), # 这里的选择是所有的工具 + "options": lambda: gen_tool_info(get_tools()), # 这里的选择是所有的工具 "description": "工具列表", }, ) mcps: list[str] = field( default_factory=list, - metadata={"name": "MCP服务器", "options": list(MCP_SERVERS.keys()), "description": "MCP服务器列表"}, + metadata={ + "name": "MCP服务器", + "options": lambda: list(MCP_SERVERS.keys()), + "description": "MCP服务器列表", + }, ) diff --git a/src/agents/chatbot/tools.py b/src/agents/chatbot/tools.py index c19d7707..b6eabce6 100644 --- a/src/agents/chatbot/tools.py +++ b/src/agents/chatbot/tools.py @@ -6,7 +6,6 @@ import requests from langchain.tools import tool from src.agents.common import get_buildin_tools -from src.agents.common.toolkits.mysql import get_mysql_tools from src.storage.minio import aupload_file_to_minio from src.utils import logger @@ -52,5 +51,4 @@ def get_tools() -> list[Any]: """获取所有可运行的工具(给大模型使用)""" tools = get_buildin_tools() tools.append(text_to_img_demo) - tools.extend(get_mysql_tools()) return tools diff --git a/src/agents/common/context.py b/src/agents/common/context.py index 36b3f851..d7d4e35e 100644 --- a/src/agents/common/context.py +++ b/src/agents/common/context.py @@ -107,10 +107,14 @@ class BaseContext: # 提取 Annotated 的元数据 template_metadata = cls._extract_template_metadata(field_type) + options = f.metadata.get("options", []) + if callable(options): + options = options() + configurable_items[f.name] = { "type": type_name, "name": f.metadata.get("name", f.name), - "options": f.metadata.get("options", []), + "options": options, "default": f.default if f.default is not MISSING else f.default_factory() diff --git a/src/config/static/info.template.yaml b/src/config/static/info.template.yaml index 8be02cbe..85fb0116 100644 --- a/src/config/static/info.template.yaml +++ b/src/config/static/info.template.yaml @@ -16,15 +16,15 @@ branding: features: - label: "GitHub Stars" - value: "2600+" + value: "3000+" description: "开发者社区的认可与支持" icon: "stars" - label: "已解决 Issues" - value: "210+" + value: "250+" description: "持续改进和问题解决能力" icon: "issues" - label: "累计 Commits" - value: "1000+" + value: "1100+" description: "活跃的开发迭代和功能更新" icon: "commits" - label: "开源协议" diff --git a/src/storage/db/manager.py b/src/storage/db/manager.py index 003e4d59..1330c6cd 100644 --- a/src/storage/db/manager.py +++ b/src/storage/db/manager.py @@ -22,9 +22,6 @@ except ImportError: def validate_database_schema(db_path): return True, [] -# TODO:[已完成]为DBManager添加异步支持 -# TODO:[已完成]为DBManager添加单例模式 - class DBManager(metaclass=SingletonMeta): """数据库管理器 - 提供异步数据库连接和会话管理""" diff --git a/web/src/apis/mindmap_api.js b/web/src/apis/mindmap_api.js index 4615485c..f38c7d04 100644 --- a/web/src/apis/mindmap_api.js +++ b/web/src/apis/mindmap_api.js @@ -49,18 +49,6 @@ export const mindmapApi = { */ getByDatabase: async (dbId) => { return apiAdminGet(`/api/mindmap/database/${dbId}`) - }, - - /** - * 保存思维导图到知识库 - * @param {string} dbId - 知识库ID - * @param {Object} mindmapData - 思维导图数据 - * @returns {Promise} - 保存结果 - */ - saveToDatabase: async (dbId, mindmapData) => { - return apiAdminPost(`/api/mindmap/database/${dbId}`, { - mindmap: mindmapData - }) } } diff --git a/web/src/components/AgentChatComponent.vue b/web/src/components/AgentChatComponent.vue index 52612625..4235d46a 100644 --- a/web/src/components/AgentChatComponent.vue +++ b/web/src/components/AgentChatComponent.vue @@ -1043,7 +1043,7 @@ watch(conversations, () => { .floating-sidebar { position: absolute !important; - z-index: 100; + z-index: 101; height: 100%; left: 0; top: 0; diff --git a/web/src/components/AgentConfigSidebar.vue b/web/src/components/AgentConfigSidebar.vue index fabd44a4..d742ff8e 100644 --- a/web/src/components/AgentConfigSidebar.vue +++ b/web/src/components/AgentConfigSidebar.vue @@ -221,10 +221,6 @@ 保存配置 - -
@@ -424,6 +420,10 @@ const getToolNameById = (toolId) => { const openToolsModal = async () => { console.log("availableTools.value", availableTools.value) try { + // 强制刷新智能体详情以获取最新工具列表 + if (selectedAgentId.value) { + await agentStore.fetchAgentDetail(selectedAgentId.value, true); + } selectedTools.value = [...(agentConfig.value?.tools || [])]; toolsModalOpen.value = true; } catch (error) { diff --git a/web/src/components/AgentPopover.vue b/web/src/components/AgentPopover.vue index 0fb8e197..83ea1bca 100644 --- a/web/src/components/AgentPopover.vue +++ b/web/src/components/AgentPopover.vue @@ -39,17 +39,13 @@ :key="index" class="todo-item" > - - - - - - - - - - - +
+ + + + + +
{{ todo.content }} @@ -110,6 +106,13 @@ + + diff --git a/web/src/components/ToolCallingResult/ToolResultRenderer.vue b/web/src/components/ToolCallingResult/ToolResultRenderer.vue index 86a37940..0058622c 100644 --- a/web/src/components/ToolCallingResult/ToolResultRenderer.vue +++ b/web/src/components/ToolCallingResult/ToolResultRenderer.vue @@ -19,6 +19,12 @@ ref="graphResultRef" /> + + + { return props.resultContent }) +const todoListData = computed(() => { + if (props.toolName !== 'write_todos') return [] + + const raw = props.resultContent + + // 1. Try from parsedData (JSON object) + const data = parsedData.value + if (data && typeof data === 'object') { + if (Array.isArray(data)) return data + if (data.todos && Array.isArray(data.todos)) return data.todos + } + + // 2. Try parsing string if it matches specific pattern + if (typeof raw === 'string') { + let str = raw + if (str.startsWith('Updated todo list to ')) { + str = str.replace('Updated todo list to ', '') + } + + // Try regex parsing for Python-like string + const items = [] + // Matches {'content': '...', 'status': '...'} with escaped quotes support + // content might contain escaped quotes + const contentRegex = /'content':\s*'((?:[^'\\]|\\.)*)'/ + const statusRegex = /'status':\s*'((?:[^'\\]|\\.)*)'/ + + // Split by "}, {" roughly, or just look for objects + // Since it is a list of dicts, we can match individual dicts + const dictRegex = /\{.*?\}/g + const dictMatches = str.match(dictRegex) + + if (dictMatches) { + for (const dictStr of dictMatches) { + const contentMatch = dictStr.match(contentRegex) + const statusMatch = dictStr.match(statusRegex) + + if (contentMatch && statusMatch) { + items.push({ + content: contentMatch[1].replace(/\\'/g, "'").replace(/\\\\/g, "\\"), + status: statusMatch[1] + }) + } + } + } + if (items.length > 0) return items + } + + return [] +}) + +const isTodoListResult = computed(() => { + return props.toolName === 'write_todos' && todoListData.value.length > 0 +}) + // 判断是否为网页搜索结果 const isWebSearchResult = computed(() => { const toolNameLower = props.toolName.toLowerCase() diff --git a/web/src/stores/agent.js b/web/src/stores/agent.js index 2ea597db..61c92ff6 100644 --- a/web/src/stores/agent.js +++ b/web/src/stores/agent.js @@ -146,11 +146,11 @@ export const useAgentStore = defineStore('agent', () => { * 获取单个智能体的详细信息(包含配置选项) * @param {string} agentId - 智能体ID */ - async function fetchAgentDetail(agentId) { + async function fetchAgentDetail(agentId, forceRefresh = false) { if (!agentId) return - // 如果已经缓存了详细信息,直接返回 - if (agentDetails.value[agentId]) { + // 如果已经缓存了详细信息且不强制刷新,直接返回 + if (!forceRefresh && agentDetails.value[agentId]) { return agentDetails.value[agentId] } diff --git a/web/src/stores/info.js b/web/src/stores/info.js index fade5d61..d4e5e53d 100644 --- a/web/src/stores/info.js +++ b/web/src/stores/info.js @@ -27,17 +27,17 @@ export const useInfoStore = defineStore('info', () => { // 计算属性 - 功能特性 const features = computed(() => infoConfig.value.features || [{ label: "GitHub Stars", - value: "2600+", + value: "3000+", description: "开发者社区的认可与支持", icon: "stars" }, { label: "已解决 Issues", - value: "200+", + value: "250+", description: "持续改进和问题解决能力", icon: "issues" }, { label: "累计 Commits", - value: "1000+", + value: "1100+", description: "活跃的开发迭代和功能更新", icon: "commits" }, { diff --git a/web/src/views/HomeView.vue b/web/src/views/HomeView.vue index e839d886..9fced927 100644 --- a/web/src/views/HomeView.vue +++ b/web/src/views/HomeView.vue @@ -75,6 +75,8 @@ + +