Merge upstream/dev into feature/multi-agent

This commit is contained in:
CREDO23 2026-05-05 01:44:46 +02:00
commit 5119915f4f
278 changed files with 34669 additions and 8970 deletions

View file

@ -13,7 +13,9 @@ from .resume import create_generate_resume_tool
from .video_presentation import create_generate_video_presentation_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
resolved_dependencies = {**(dependencies or {}), **kwargs}
podcast = create_generate_podcast_tool(
search_space_id=resolved_dependencies["search_space_id"],

View file

@ -10,7 +10,9 @@ from app.db import ChatVisibility
from .update_memory import create_update_memory_tool, create_update_team_memory_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
resolved_dependencies = {**(dependencies or {}), **kwargs}
if resolved_dependencies.get("thread_visibility") == ChatVisibility.SEARCH_SPACE:
mem = create_update_team_memory_tool(
@ -18,7 +20,10 @@ def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) ->
db_session=resolved_dependencies["db_session"],
llm=resolved_dependencies.get("llm"),
)
return {"allow": [{"name": getattr(mem, "name", "") or "", "tool": mem}], "ask": []}
return {
"allow": [{"name": getattr(mem, "name", "") or "", "tool": mem}],
"ask": [],
}
mem = create_update_memory_tool(
user_id=resolved_dependencies["user_id"],
db_session=resolved_dependencies["db_session"],

View file

@ -11,14 +11,20 @@ from .search_surfsense_docs import create_search_surfsense_docs_tool
from .web_search import create_web_search_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
resolved_dependencies = {**(dependencies or {}), **kwargs}
web = create_web_search_tool(
search_space_id=resolved_dependencies.get("search_space_id"),
available_connectors=resolved_dependencies.get("available_connectors"),
)
scrape = create_scrape_webpage_tool(firecrawl_api_key=resolved_dependencies.get("firecrawl_api_key"))
docs = create_search_surfsense_docs_tool(db_session=resolved_dependencies["db_session"])
scrape = create_scrape_webpage_tool(
firecrawl_api_key=resolved_dependencies.get("firecrawl_api_key")
)
docs = create_search_surfsense_docs_tool(
db_session=resolved_dependencies["db_session"]
)
return {
"allow": [
{"name": getattr(web, "name", "") or "", "tool": web},

View file

@ -7,6 +7,8 @@ from app.agents.multi_agent_chat.subagents.shared.permissions import (
)
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
_ = {**(dependencies or {}), **kwargs}
return {"allow": [], "ask": []}

View file

@ -12,7 +12,9 @@ from .search_events import create_search_calendar_events_tool
from .update_event import create_update_calendar_event_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
resolved_dependencies = {**(dependencies or {}), **kwargs}
session_dependencies = {
"db_session": resolved_dependencies["db_session"],

View file

@ -7,6 +7,8 @@ from app.agents.multi_agent_chat.subagents.shared.permissions import (
)
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
_ = {**(dependencies or {}), **kwargs}
return {"allow": [], "ask": []}

View file

@ -11,7 +11,9 @@ from .delete_page import create_delete_confluence_page_tool
from .update_page import create_update_confluence_page_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
resolved_dependencies = {**(dependencies or {}), **kwargs}
session_dependencies = {
"db_session": resolved_dependencies["db_session"],

View file

@ -11,7 +11,9 @@ from .read_messages import create_read_discord_messages_tool
from .send_message import create_send_discord_message_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -10,7 +10,9 @@ from .create_file import create_create_dropbox_file_tool
from .trash_file import create_delete_dropbox_file_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -14,7 +14,9 @@ from .trash_email import create_trash_gmail_email_tool
from .update_draft import create_update_gmail_draft_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -10,7 +10,9 @@ from .create_file import create_create_google_drive_file_tool
from .trash_file import create_delete_google_drive_file_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -11,7 +11,9 @@ from .delete_issue import create_delete_jira_issue_tool
from .update_issue import create_update_jira_issue_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -11,7 +11,9 @@ from .delete_issue import create_delete_linear_issue_tool
from .update_issue import create_update_linear_issue_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -11,7 +11,9 @@ from .list_events import create_list_luma_events_tool
from .read_event import create_read_luma_event_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -11,7 +11,9 @@ from .delete_page import create_delete_notion_page_tool
from .update_page import create_update_notion_page_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -10,7 +10,9 @@ from .create_file import create_create_onedrive_file_tool
from .trash_file import create_delete_onedrive_file_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -7,6 +7,8 @@ from app.agents.multi_agent_chat.subagents.shared.permissions import (
)
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
_ = {**(dependencies or {}), **kwargs}
return {"allow": [], "ask": []}

View file

@ -11,7 +11,9 @@ from .read_messages import create_read_teams_messages_tool
from .send_message import create_send_teams_message_tool
def load_tools(*, dependencies: dict[str, Any] | None = None, **kwargs: Any) -> ToolsPermissions:
def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> ToolsPermissions:
d = {**(dependencies or {}), **kwargs}
common = {
"db_session": d["db_session"],

View file

@ -31,6 +31,7 @@ logger = logging.getLogger(__name__)
## Helper functions for fetching connector metadata maps
async def fetch_mcp_connector_metadata_maps(
session: AsyncSession,
search_space_id: int,
@ -58,6 +59,7 @@ async def fetch_mcp_connector_metadata_maps(
## Helper functions for partitioning tools by connector agent
def partition_mcp_tools_by_connector(
tools: Sequence[BaseTool],
connector_id_to_type: dict[int, str],
@ -104,8 +106,10 @@ def partition_mcp_tools_by_connector(
return dict(buckets)
## Helper functions for splitting tools by permissions
def _get_mcp_tool_name(tool: BaseTool) -> str:
meta: dict[str, Any] = getattr(tool, "metadata", None) or {}
orig = meta.get("mcp_original_tool_name")
@ -139,6 +143,7 @@ def _split_tools_by_permissions(
## Main function to load MCP tools and split them by permissions for each connector agent
async def load_mcp_tools_by_connector(
session: AsyncSession,
search_space_id: int,
@ -148,9 +153,7 @@ async def load_mcp_tools_by_connector(
Pass ``bypass_internal_hitl=True`` so the subagent's
``HumanInTheLoopMiddleware`` is the single HITL gate.
"""
flat = await load_mcp_tools(
session, search_space_id, bypass_internal_hitl=True
)
flat = await load_mcp_tools(session, search_space_id, bypass_internal_hitl=True)
id_map, name_map = await fetch_mcp_connector_metadata_maps(session, search_space_id)
buckets = partition_mcp_tools_by_connector(flat, id_map, name_map)
return {

View file

@ -8,6 +8,9 @@ from typing import Any, Protocol
from deepagents import SubAgent
from langchain_core.language_models import BaseChatModel
from app.agents.multi_agent_chat.constants import (
SUBAGENT_TO_REQUIRED_CONNECTOR_MAP,
)
from app.agents.multi_agent_chat.subagents.builtins.deliverables.agent import (
build_subagent as build_deliverables_subagent,
)
@ -62,9 +65,6 @@ from app.agents.multi_agent_chat.subagents.connectors.slack.agent import (
from app.agents.multi_agent_chat.subagents.connectors.teams.agent import (
build_subagent as build_teams_subagent,
)
from app.agents.multi_agent_chat.constants import (
SUBAGENT_TO_REQUIRED_CONNECTOR_MAP,
)
from app.agents.multi_agent_chat.subagents.shared.md_file_reader import (
read_md_file,
)
@ -105,6 +105,7 @@ SUBAGENT_BUILDERS_BY_NAME: dict[str, SubagentBuilder] = {
"teams": build_teams_subagent,
}
def _route_resource_package(builder: SubagentBuilder) -> str:
mod = builder.__module__
return mod[: -len(".agent")] if mod.endswith(".agent") else mod.rsplit(".", 1)[0]