multi_agent_chat/subagents: expose knowledge_base as ask_knowledge_base tool for siblings

This commit is contained in:
CREDO23 2026-05-12 20:03:59 +02:00
parent f2f62c1c05
commit 379cc992f4
12 changed files with 339 additions and 77 deletions

View file

@ -16,6 +16,7 @@ def build_filesystem_mw(
search_space_id: int,
user_id: str | None,
thread_id: int | None,
read_only: bool = False,
) -> SurfSenseFilesystemMiddleware:
return SurfSenseFilesystemMiddleware(
backend=backend_resolver,
@ -23,4 +24,5 @@ def build_filesystem_mw(
search_space_id=search_space_id,
created_by_id=user_id,
thread_id=thread_id,
read_only=read_only,
)

View file

@ -28,6 +28,7 @@ from ..tools import (
)
from ..tools.glob.description import select_description as glob_description
from ..tools.grep.description import select_description as grep_description
from .read_only_policy import READ_ONLY_TOOL_NAMES
class SurfSenseFilesystemMiddleware(FilesystemMiddleware):
@ -44,12 +45,16 @@ class SurfSenseFilesystemMiddleware(FilesystemMiddleware):
created_by_id: str | None = None,
thread_id: int | str | None = None,
tool_token_limit_before_evict: int | None = 20000,
read_only: bool = False,
) -> None:
self._filesystem_mode = filesystem_mode
self._search_space_id = search_space_id
self._created_by_id = created_by_id
self._thread_id = thread_id
self._sandbox_available = is_sandbox_enabled() and thread_id is not None
self._read_only = read_only
self._sandbox_available = (
is_sandbox_enabled() and thread_id is not None and not read_only
)
system_prompt = build_system_prompt(
filesystem_mode,
@ -72,6 +77,9 @@ class SurfSenseFilesystemMiddleware(FilesystemMiddleware):
if self._sandbox_available:
self.tools.append(create_execute_code_tool(self))
if read_only:
self.tools = [t for t in self.tools if t.name in READ_ONLY_TOOL_NAMES]
# ----------------------------------------- base-class tool overrides
def _create_ls_tool(self) -> BaseTool:

View file

@ -0,0 +1,7 @@
"""Allowlist consulted by ``SurfSenseFilesystemMiddleware`` when ``read_only=True``."""
from __future__ import annotations
READ_ONLY_TOOL_NAMES = frozenset(
{"ls", "read_file", "glob", "grep", "list_tree", "pwd", "cd"}
)

View file

@ -15,6 +15,7 @@ from typing import Any
from deepagents import SubAgent
from deepagents.backends import StateBackend
from langchain.agents import create_agent
from langchain_core.language_models import BaseChatModel
from langchain_core.tools import BaseTool
from langgraph.types import Checkpointer
@ -23,6 +24,13 @@ from app.agents.multi_agent_chat.subagents import (
build_subagents,
get_subagents_to_exclude,
)
from app.agents.multi_agent_chat.subagents.builtins.knowledge_base.agent import (
READONLY_NAME as KB_READONLY_NAME,
build_readonly_subagent as build_kb_readonly_subagent,
)
from app.agents.multi_agent_chat.subagents.builtins.knowledge_base.ask_knowledge_base_tool import (
build_ask_knowledge_base_tool,
)
from app.agents.multi_agent_chat.subagents.shared.permissions import ToolsPermissions
from app.agents.new_chat.feature_flags import AgentFeatureFlags
from app.agents.new_chat.filesystem_selection import FilesystemMode
@ -93,14 +101,31 @@ def build_main_agent_deepagent_middleware(
"backend_resolver": backend_resolver,
"filesystem_mode": filesystem_mode,
}
shared_subagent_middleware = build_subagent_middleware_stack(resilience=resilience)
kb_readonly_spec = build_kb_readonly_subagent(
dependencies=subagent_dependencies,
model=llm,
middleware_stack=shared_subagent_middleware,
)
kb_readonly_runnable = create_agent(
llm,
system_prompt=kb_readonly_spec["system_prompt"],
tools=kb_readonly_spec["tools"],
middleware=kb_readonly_spec["middleware"],
name=KB_READONLY_NAME,
checkpointer=checkpointer,
)
ask_kb_tool = build_ask_knowledge_base_tool(kb_readonly_runnable)
subagents: list[SubAgent] = build_subagents(
dependencies=subagent_dependencies,
model=llm,
middleware_stack=build_subagent_middleware_stack(resilience=resilience),
middleware_stack=shared_subagent_middleware,
mcp_tools_by_agent=mcp_tools_by_agent or {},
exclude=get_subagents_to_exclude(available_connectors),
disabled_tools=disabled_tools,
ask_kb_tool=ask_kb_tool,
)
logging.debug("Subagents registry: %s", [s["name"] for s in subagents])