SurfSense/surfsense_backend/app/agents/new_chat/filesystem_backends.py
2026-04-28 04:32:52 -07:00

63 lines
2.2 KiB
Python

"""Filesystem backend resolver for cloud and desktop-local modes."""
from __future__ import annotations
from collections.abc import Callable
from functools import lru_cache
from deepagents.backends.protocol import BackendProtocol
from deepagents.backends.state import StateBackend
from langgraph.prebuilt.tool_node import ToolRuntime
from app.agents.new_chat.filesystem_selection import FilesystemMode, FilesystemSelection
from app.agents.new_chat.middleware.kb_postgres_backend import KBPostgresBackend
from app.agents.new_chat.middleware.multi_root_local_folder_backend import (
MultiRootLocalFolderBackend,
)
@lru_cache(maxsize=64)
def _cached_multi_root_backend(
mounts: tuple[tuple[str, str], ...],
) -> MultiRootLocalFolderBackend:
return MultiRootLocalFolderBackend(mounts)
def build_backend_resolver(
selection: FilesystemSelection,
*,
search_space_id: int | None = None,
) -> Callable[[ToolRuntime], BackendProtocol]:
"""Create deepagents backend resolver for the selected filesystem mode.
In cloud mode the resolver returns a fresh :class:`KBPostgresBackend`
bound to the current ``runtime`` so the backend can read staging state
(``staged_dirs``, ``pending_moves``, ``files`` cache, ``kb_anon_doc``,
``kb_matched_chunk_ids``) for each tool call. When no ``search_space_id``
is provided, the resolver falls back to :class:`StateBackend` (used by
sub-agents and tests that don't need DB-backed reads).
Desktop-local mode unchanged.
"""
if selection.mode == FilesystemMode.DESKTOP_LOCAL_FOLDER and selection.local_mounts:
def _resolve_local(_runtime: ToolRuntime) -> MultiRootLocalFolderBackend:
mounts = tuple(
(entry.mount_id, entry.root_path) for entry in selection.local_mounts
)
return _cached_multi_root_backend(mounts)
return _resolve_local
if search_space_id is not None:
def _resolve_kb(runtime: ToolRuntime) -> BackendProtocol:
return KBPostgresBackend(search_space_id, runtime)
return _resolve_kb
def _resolve_state(runtime: ToolRuntime) -> StateBackend:
return StateBackend(runtime)
return _resolve_state