From 4fd3c4fb27c39ca6854b67d08c59ec9aa38ee21e Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Sat, 2 May 2026 00:44:02 +0200 Subject: [PATCH] Inject dynamic registry subagents into the main prompt and simplify connector discovery. --- .../main_agent/runtime/factory.py | 20 +++++++++----- .../system_prompt/builder/compose.py | 8 +++--- .../builder/sections/registry_subagents.py | 27 +++++++++++++++++++ .../markdown/main_agent_tool_routing.md | 2 ++ 4 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/builder/sections/registry_subagents.py diff --git a/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/runtime/factory.py b/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/runtime/factory.py index 9c9abd664..72e09edab 100644 --- a/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/runtime/factory.py +++ b/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/runtime/factory.py @@ -24,12 +24,13 @@ from app.agents.new_chat.feature_flags import AgentFeatureFlags, get_flags from app.agents.new_chat.filesystem_backends import build_backend_resolver from app.agents.new_chat.filesystem_selection import FilesystemMode, FilesystemSelection from app.agents.new_chat.llm_config import AgentConfig +from app.agents.multi_agent_with_deepagents.subagents import ( + get_subagents_to_exclude, + main_prompt_registry_subagent_lines, +) from ..system_prompt import build_main_agent_system_prompt from app.agents.new_chat.tools.invalid_tool import INVALID_TOOL_NAME, invalid_tool -from app.agents.new_chat.tools.registry import ( - build_tools_async, - get_connector_gated_tools, -) +from app.agents.new_chat.tools.registry import build_tools_async from app.db import ChatVisibility from app.services.connector_service import ConnectorService from app.utils.perf import get_perf_logger @@ -73,8 +74,7 @@ async def create_surfsense_deep_agent( connector_types = await connector_service.get_available_connectors( search_space_id ) - if connector_types: - available_connectors = _map_connectors_to_searchable_types(connector_types) + available_connectors = _map_connectors_to_searchable_types(connector_types) available_document_types = await connector_service.get_available_document_types( search_space_id @@ -119,7 +119,6 @@ async def create_surfsense_deep_agent( ) modified_disabled_tools = list(disabled_tools) if disabled_tools else [] - modified_disabled_tools.extend(get_connector_gated_tools(available_connectors)) if "search_knowledge_base" not in modified_disabled_tools: modified_disabled_tools.append("search_knowledge_base") @@ -160,6 +159,11 @@ async def create_surfsense_deep_agent( if isinstance(prof, str): _model_name = prof + _connector_exclude = get_subagents_to_exclude(available_connectors) + _registry_subagent_prompt_lines = main_prompt_registry_subagent_lines( + _connector_exclude + ) + if agent_config is not None: system_prompt = build_main_agent_system_prompt( today=None, @@ -170,6 +174,7 @@ async def create_surfsense_deep_agent( use_default_system_instructions=agent_config.use_default_system_instructions, citations_enabled=agent_config.citations_enabled, model_name=_model_name or getattr(agent_config, "model_name", None), + registry_subagent_prompt_lines=_registry_subagent_prompt_lines, ) else: system_prompt = build_main_agent_system_prompt( @@ -178,6 +183,7 @@ async def create_surfsense_deep_agent( disabled_tool_names=_user_disabled_tool_names, citations_enabled=True, model_name=_model_name, + registry_subagent_prompt_lines=_registry_subagent_prompt_lines, ) _perf_log.info( "[create_agent] System prompt built in %.3fs", time.perf_counter() - _t0 diff --git a/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/builder/compose.py b/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/builder/compose.py index 31b0adb01..5f09b9cac 100644 --- a/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/builder/compose.py +++ b/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/builder/compose.py @@ -1,8 +1,7 @@ """Assemble the **main-agent** deep-agent system string only. -Sections (order matters): core instructions → provider flavour → **citations policy** -→ SurfSense tool docs. Citations come before ```` so citation on/off rules -apply before any tool text that mentions attribution. +Sections (order matters): core instructions → provider → citations → dynamic +```` → SurfSense ````. """ from __future__ import annotations @@ -13,6 +12,7 @@ from app.db import ChatVisibility from .sections.citations import build_citations_section from .sections.provider import build_provider_section +from .sections.registry_subagents import build_registry_subagents_section from .sections.system_instruction import build_default_system_instruction_xml from .sections.tools import build_tools_section @@ -27,6 +27,7 @@ def build_main_agent_system_prompt( use_default_system_instructions: bool = True, citations_enabled: bool = True, model_name: str | None = None, + registry_subagent_prompt_lines: list[tuple[str, str]] | None = None, ) -> str: resolved_today = (today or datetime.now(UTC)).astimezone(UTC).date().isoformat() visibility = thread_visibility or ChatVisibility.PRIVATE @@ -43,6 +44,7 @@ def build_main_agent_system_prompt( system_block += build_provider_section(model_name=model_name) system_block += build_citations_section(citations_enabled=citations_enabled) + system_block += build_registry_subagents_section(registry_subagent_prompt_lines) system_block += build_tools_section( visibility=visibility, enabled_tool_names=enabled_tool_names, diff --git a/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/builder/sections/registry_subagents.py b/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/builder/sections/registry_subagents.py new file mode 100644 index 000000000..90f4cc2d6 --- /dev/null +++ b/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/builder/sections/registry_subagents.py @@ -0,0 +1,27 @@ +"""Dynamic ```` block: **task** specialists actually built for this workspace.""" + +from __future__ import annotations + + +def build_registry_subagents_section( + registry_subagent_lines: list[tuple[str, str]] | None, +) -> str: + if registry_subagent_lines is None: + return "" + if not registry_subagent_lines: + return ( + "\n\n" + "No registry specialists are listed for **task** in this workspace.\n" + "\n" + ) + bullets = "\n".join( + f"- **{name}** — {desc}" for name, desc in registry_subagent_lines + ) + return ( + "\n\n" + "These specialists are registered for **task** (routes without a matching connector are omitted).\n" + f"{bullets}\n" + "The runtime may also offer a general-purpose **task** helper with your tools in a separate context.\n" + "Pick the specialist by **name**. Put full instructions in the task prompt; they do not see this thread.\n" + "\n" + ) diff --git a/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/markdown/main_agent_tool_routing.md b/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/markdown/main_agent_tool_routing.md index 21b6d3254..d31e24ce9 100644 --- a/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/markdown/main_agent_tool_routing.md +++ b/surfsense_backend/app/agents/multi_agent_with_deepagents/main_agent/system_prompt/markdown/main_agent_tool_routing.md @@ -2,6 +2,8 @@ Use **task** for anything beyond your direct SurfSense tools: calendar, mail, chat, tickets, documents in third-party systems, connector-specific discovery, deliverables (reports, podcasts, images, etc.), and other specialized routes. +The live list of specialists you may target with **task** for this workspace is in +`` (later in this prompt). Your **direct** SurfSense tools are only: **update_memory**, **web_search**, **scrape_webpage**, and **search_surfsense_docs**. The runtime may also attach