diff --git a/backend/package/yuxi/agents/backends/knowledge_base_backend.py b/backend/package/yuxi/agents/backends/knowledge_base_backend.py index 729a942d..0d08f6a1 100644 --- a/backend/package/yuxi/agents/backends/knowledge_base_backend.py +++ b/backend/package/yuxi/agents/backends/knowledge_base_backend.py @@ -127,11 +127,6 @@ async def resolve_visible_knowledge_bases_for_context(context) -> list[dict[str, setattr(context, "_visible_knowledge_bases", []) return [] - enabled_names = {str(name).strip() for name in (getattr(context, "knowledges", None) or []) if str(name).strip()} - if not enabled_names: - setattr(context, "_visible_knowledge_bases", []) - return [] - try: raw_user_id = int(user_id) except (TypeError, ValueError): @@ -139,7 +134,12 @@ async def resolve_visible_knowledge_bases_for_context(context) -> list[dict[str, return [] result = await knowledge_base.get_databases_by_raw_id(raw_user_id) - databases = [db for db in (result.get("databases") or []) if str(db.get("name") or "").strip() in enabled_names] + databases = result.get("databases") or [] + enabled_knowledges = getattr(context, "knowledges", None) + if enabled_knowledges is not None: + enabled_names = {str(name).strip() for name in enabled_knowledges if str(name).strip()} + databases = [db for db in databases if str(db.get("name") or "").strip() in enabled_names] + setattr(context, "_visible_knowledge_bases", databases) return databases diff --git a/backend/package/yuxi/agents/context.py b/backend/package/yuxi/agents/context.py index 4009fa03..851780b6 100644 --- a/backend/package/yuxi/agents/context.py +++ b/backend/package/yuxi/agents/context.py @@ -55,11 +55,11 @@ class BaseContext: }, ) - knowledges: Annotated[list[str], {"__template_metadata__": {"kind": "knowledges"}}] = field( - default_factory=list, + knowledges: Annotated[list[str] | None, {"__template_metadata__": {"kind": "knowledges"}}] = field( + default=None, metadata={ "name": "知识库", - "description": "知识库列表,可以在左侧知识库页面中创建知识库。", + "description": "知识库列表,可以在左侧知识库页面中创建知识库。默认选择当前用户可访问的全部知识库。", "type": "list", # Explicitly mark as list type for frontend if needed }, ) diff --git a/backend/package/yuxi/agents/toolkits/kbs/tools.py b/backend/package/yuxi/agents/toolkits/kbs/tools.py index 62daa0af..e572ba4e 100644 --- a/backend/package/yuxi/agents/toolkits/kbs/tools.py +++ b/backend/package/yuxi/agents/toolkits/kbs/tools.py @@ -39,8 +39,7 @@ async def list_kbs(dummy: str, runtime: ToolRuntime) -> str: # Now has 2 params # 打印 runtime—context 中的所有信息以进行调试 logger.debug(f"Runtime context: {runtime_context.__dict__}") - # 获取用户在当前对话中启用的知识库列表 - enabled_kb_names = getattr(runtime_context, "knowledges", []) or [] + enabled_kb_names = getattr(runtime_context, "knowledges", None) # 获取用户可访问的知识库列表(包含名称和描述) try: @@ -55,8 +54,10 @@ async def list_kbs(dummy: str, runtime: ToolRuntime) -> str: # Now has 2 params logger.debug(f"用户 {user_id} 可访问的知识库列表: {all_kb_names}") logger.debug(f"用户 {user_id} 当前对话启用的知识库列表: {enabled_kb_names}") - # 与启用的知识库取交集 - available_kbs = [kb for kb in all_kbs if kb["name"] in enabled_kb_names] + if enabled_kb_names is None: + available_kbs = all_kbs + else: + available_kbs = [kb for kb in all_kbs if kb["name"] in enabled_kb_names] if not available_kbs: return "当前没有可访问的知识库" diff --git a/docs/develop-guides/roadmap.md b/docs/develop-guides/roadmap.md index 59b8442d..1eb7cad8 100644 --- a/docs/develop-guides/roadmap.md +++ b/docs/develop-guides/roadmap.md @@ -19,7 +19,6 @@ - 前置任务,多知识库并行检索(扩展 query_kb) - 新增 query_keywords 工具,专门用于基于关键词命中的排序,也结合词频(和 BM25 的区别?) - 评估,基于 Agent 的评估,这里应该是结合 Langfuse 实现 -- 知识库选择,修改为默认选择所有知识库(dev2) ### Bugs - 目前的知识库的图片存在公开访问风险 @@ -37,6 +36,7 @@ ### 0.6.2 开发记录 +- 调整 Agent 知识库默认选择:未显式配置知识库时默认启用当前用户可访问的全部知识库,显式保存空列表仍表示不启用知识库。 - 优化评估基准自动生成:仅支持 commonrag/Milvus 知识库,默认参考 chunks 数量改为 1;多 chunk 场景复用知识库向量检索选择相似 chunks,不再对全量 chunks 重新计算 embedding,并移除前端 Embedding 模型选择。 - 修复知识库文档入库状态回退:当已解析文件缺失 `markdown_file` 解析产物时,索引流程会将文件状态恢复为未解析,便于重新解析而不是停留在索引失败。 - 优化 Agent 输入框文件 mention:用户级 workspace 文件候选改为从独立 workspace API 递归加载,不再依赖 active thread;插入时仍转换为 `/home/gem/user-data/workspace/` 沙盒虚拟路径,并修复附件上传后未立即刷新 mention 候选的问题。 diff --git a/web/src/components/AgentConfigSidebar.vue b/web/src/components/AgentConfigSidebar.vue index fcf8f6df..dcf1a53f 100644 --- a/web/src/components/AgentConfigSidebar.vue +++ b/web/src/components/AgentConfigSidebar.vue @@ -824,6 +824,9 @@ const handleModelChange = (key, spec) => { // 多选相关方法 const ensureArray = (key) => { const config = agentConfig.value || {} + if (config[key] === null && configurableItems.value[key]?.template_metadata?.kind === 'knowledges') { + return getConfigOptions(configurableItems.value[key]).map((option) => getOptionValue(option)) + } if (!config[key] || !Array.isArray(config[key])) { return [] } @@ -891,8 +894,7 @@ const openSelectionModal = async (key) => { if (configurableItems.value[key]?.template_metadata?.kind === 'subagents') { await loadSubagentOptions() } - const currentValues = agentConfig.value[key] || [] - tempSelectedValues.value = [...currentValues] + tempSelectedValues.value = [...ensureArray(key)] selectionModalOpen.value = true } diff --git a/web/src/composables/useAgentMentionConfig.js b/web/src/composables/useAgentMentionConfig.js index 3ce5442e..6db965fe 100644 --- a/web/src/composables/useAgentMentionConfig.js +++ b/web/src/composables/useAgentMentionConfig.js @@ -91,6 +91,7 @@ export function useAgentMentionConfig({ const configItems = configurableItems.value || {} const currentConfig = agentConfig.value || {} + let includeAllKnowledgeBases = false const allowedKbNames = new Set() const allowedMcpNames = new Set() const allowedSkillNames = new Set() @@ -101,7 +102,9 @@ export function useAgentMentionConfig({ const kind = item?.template_metadata?.kind const val = currentConfig[key] - if (Array.isArray(val)) { + if (kind === 'knowledges' && val === null) { + includeAllKnowledgeBases = true + } else if (Array.isArray(val)) { if (kind === 'knowledges') { val.forEach((v) => allowedKbNames.add(v)) } else if (kind === 'mcps') { @@ -133,7 +136,9 @@ export function useAgentMentionConfig({ } }) - const knowledgeBases = availableKnowledgeBases.value.filter((kb) => allowedKbNames.has(kb.name)) + const knowledgeBases = includeAllKnowledgeBases + ? availableKnowledgeBases.value + : availableKnowledgeBases.value.filter((kb) => allowedKbNames.has(kb.name)) const mcps = availableMcps.value.filter((mcp) => allowedMcpNames.has(mcp.name)) const skills = availableSkills.value.filter((skill) => { const skillName = skill.name || ''