fix(chat): 修复知识库权限过滤逻辑

TODO: 前端还未完成过滤
This commit is contained in:
Wenjie Zhang 2026-01-22 11:16:15 +08:00
parent 5f90385ad0
commit 5cb6e4402f
5 changed files with 35 additions and 39 deletions

View File

@ -48,7 +48,7 @@ class BaseContext:
metadata={"name": "部门ID", "configurable": False, "description": "用来唯一标识一个部门"},
)
system_prompt: str = field(
system_prompt: Annotated[str, {"__template_metadata__": {"kind": "prompt"}}] = field(
default="You are a helpful assistant.",
metadata={"name": "系统提示词", "description": "用来描述智能体的角色和行为"},
)
@ -71,7 +71,7 @@ class BaseContext:
},
)
knowledges: list[str] = field(
knowledges: Annotated[list[str], {"__template_metadata__": {"kind": "knowledges"}}] = field(
default_factory=list,
metadata={
"name": "知识库",
@ -81,7 +81,7 @@ class BaseContext:
},
)
mcps: list[str] = field(
mcps: Annotated[list[str], {"__template_metadata__": {"kind": "mcps"}}] = field(
default_factory=list,
metadata={
"name": "MCP服务器",

View File

@ -7,7 +7,7 @@ from collections.abc import AsyncIterator
from langchain.messages import AIMessage, AIMessageChunk, HumanMessage
from langgraph.types import Command
from src import config as conf
from src import config as conf, knowledge_base
from src.agents import agent_manager
from src.plugins.guard import content_guard
from src.repositories.agent_config_repository import AgentConfigRepository
@ -294,19 +294,19 @@ async def stream_agent_chat(
)
agent_config_id = config_item.id
thread_id = config.get("thread_id")
if not (thread_id := config.get("thread_id")):
thread_id = str(uuid.uuid4())
logger.warning(f"No thread_id provided, generated new thread_id: {thread_id}")
agent_config = (config_item.config_json or {}).get("context", {})
input_context = {
"user_id": user_id,
"thread_id": thread_id,
"department_id": department_id,
"agent_config_id": agent_config_id,
"agent_config": (config_item.config_json or {}).get("context", config_item.config_json or {}),
"agent_config": agent_config,
}
if not thread_id:
thread_id = str(uuid.uuid4())
logger.warning(f"No thread_id provided, generated new thread_id: {thread_id}")
input_context["thread_id"] = thread_id
try:
conv_repo = ConversationRepository(db)
@ -332,7 +332,8 @@ async def stream_agent_chat(
input_context["attachments"] = []
# 根据用户权限过滤知识库
requested_knowledge_names = input_context.get("knowledges")
requested_knowledge_names = input_context["agent_config"].get("knowledges")
logger.info(f"Requesting knowledges: {requested_knowledge_names}")
if requested_knowledge_names and isinstance(requested_knowledge_names, list) and requested_knowledge_names:
user_info = {"role": "user", "department_id": department_id}
accessible_databases = await knowledge_base.get_databases_by_user(user_info)
@ -341,13 +342,15 @@ async def stream_agent_chat(
for db in accessible_databases.get("databases", [])
if isinstance(db, dict) and db.get("name")
}
logger.info(f"Accessible knowledges: {accessible_kb_names}")
filtered_knowledge_names = [kb for kb in requested_knowledge_names if kb in accessible_kb_names]
blocked_knowledge_names = [kb for kb in requested_knowledge_names if kb not in accessible_kb_names]
if blocked_knowledge_names:
logger.warning(
f"用户 {user_id} 无权访问知识库: {blocked_knowledge_names}, 已自动过滤"
)
input_context["knowledges"] = filtered_knowledge_names
input_context["agent_config"]["knowledges"] = filtered_knowledge_names
full_msg = None
accumulated_content = []

View File

@ -1373,7 +1373,7 @@ watch(
height: 32px;
justify-content: center;
align-items: center;
border-radius: 8px;
border-radius: 6px;
color: var(--gray-900);
cursor: pointer;
width: auto;

View File

@ -57,7 +57,7 @@
</div>
<!-- 系统提示词 -->
<div v-else-if="key === 'system_prompt'" class="system-prompt-container">
<div v-else-if="value.template_metadata.kind === 'prompt'" class="system-prompt-container">
<!-- 编辑模式 -->
<a-textarea
v-if="systemPromptEditMode"
@ -82,7 +82,7 @@
</div>
<!-- 工具选择 -->
<div v-else-if="value.template_metadata.kind === 'tools'" class="tools-selector">
<!-- <div v-else-if="value.template_metadata.kind === 'tools'" class="tools-selector">
<div class="tools-summary">
<div class="tools-summary-info">
<span class="tools-count">已选择 {{ getSelectedCount(key) }} 个工具</span>
@ -116,7 +116,7 @@
{{ getToolNameById(toolId) }}
</a-tag>
</div>
</div>
</div> -->
<!-- 布尔类型 -->
<a-switch
@ -368,14 +368,12 @@ const isDeletingConfig = ref(false)
const hasOtherConfigs = computed(() => {
if (isEmptyConfig.value) return false
return Object.entries(configurableItems.value).some(([key, value]) => {
// basic (System Prompt, LLM)
const isBasic = key === 'system_prompt' || value.template_metadata?.kind === 'llm'
// tools (mcps, knowledges, tools)
const isBasic = value.template_metadata?.kind === 'prompt' || value.template_metadata?.kind === 'llm'
const isTools =
key === 'mcps' ||
key === 'knowledges' ||
value.template_metadata?.kind === 'tools' ||
key === 'tools'
value.template_metadata?.kind === 'mcps' ||
value.template_metadata?.kind === 'knowledges' ||
value.template_metadata?.kind === 'tools'
return !isBasic && !isTools
})
})
@ -408,25 +406,20 @@ const filteredTools = computed(() => {
//
const shouldShowConfig = (key, value) => {
const isBasic = value.template_metadata?.kind === 'prompt' || value.template_metadata?.kind === 'llm'
const isTools =
value.template_metadata?.kind === 'mcps' ||
value.template_metadata?.kind === 'knowledges' ||
value.template_metadata?.kind === 'tools'
if (activeTab.value === 'basic') {
// System Prompt, LLM Model
return key === 'system_prompt' || value.template_metadata?.kind === 'llm'
return isBasic
} else if (activeTab.value === 'tools') {
// Tools, MCPs, Knowledges
return (
key === 'mcps' ||
key === 'knowledges' ||
value.template_metadata?.kind === 'tools' ||
key === 'tools'
)
return isTools
} else {
//
const isBasic = key === 'system_prompt' || value.template_metadata?.kind === 'llm'
const isTools =
key === 'mcps' ||
key === 'knowledges' ||
value.template_metadata?.kind === 'tools' ||
key === 'tools'
return !isBasic && !isTools
}
}

View File

@ -343,11 +343,11 @@ onMounted(async () => {
<style lang="less">
.agent-nav-btn {
display: flex;
gap: 10px;
padding: 6px 14px;
gap: 6px;
padding: 6px 8px;
justify-content: center;
align-items: center;
border-radius: 12px;
border-radius: 6px;
color: var(--gray-900);
cursor: pointer;
width: auto;