mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-06 22:32:39 +02:00
Add main-agent tool allowlist plus permission and prune helpers.
This commit is contained in:
parent
d9c873b2e1
commit
083a9f7946
9 changed files with 153 additions and 0 deletions
|
|
@ -0,0 +1,5 @@
|
|||
"""SurfSense main-agent package (factory export added when runtime lands)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__: list[str] = []
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
"""Tool-name pruning for context editing (exclude lists without dropping protected tools)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .prune_tool_names import PRUNE_PROTECTED_TOOL_NAMES, safe_exclude_tools
|
||||
|
||||
__all__ = ["PRUNE_PROTECTED_TOOL_NAMES", "safe_exclude_tools"]
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
"""Tool names excluded from context-editing prune when bound."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from langchain_core.tools import BaseTool
|
||||
|
||||
PRUNE_PROTECTED_TOOL_NAMES: frozenset[str] = frozenset(
|
||||
{
|
||||
"generate_report",
|
||||
"generate_resume",
|
||||
"generate_podcast",
|
||||
"generate_video_presentation",
|
||||
"generate_image",
|
||||
"read_email",
|
||||
"search_emails",
|
||||
"invalid",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def safe_exclude_tools(tools: Sequence[BaseTool]) -> tuple[str, ...]:
|
||||
"""Names from ``PRUNE_PROTECTED_TOOL_NAMES`` that appear in ``tools``."""
|
||||
enabled = {t.name for t in tools}
|
||||
return tuple(n for n in PRUNE_PROTECTED_TOOL_NAMES if n in enabled)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
"""Connector-gated tool deny rules and small permission helpers for the main-agent graph."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .connector_deny_rules import synthesize_connector_deny_rules
|
||||
from .connector_gated_tool_names import iter_connector_gated_tools
|
||||
from .rule import Rule
|
||||
|
||||
__all__ = [
|
||||
"Rule",
|
||||
"iter_connector_gated_tools",
|
||||
"synthesize_connector_deny_rules",
|
||||
]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
"""Synthesized PermissionMiddleware deny rules for tools gated by connector."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .connector_gated_tool_names import iter_connector_gated_tools
|
||||
from .rule import Rule
|
||||
|
||||
|
||||
def synthesize_connector_deny_rules(
|
||||
*,
|
||||
available_connectors: list[str] | None,
|
||||
enabled_tool_names: set[str],
|
||||
) -> list[Rule]:
|
||||
available = set(available_connectors or [])
|
||||
deny: list[Rule] = []
|
||||
for name, required in iter_connector_gated_tools():
|
||||
if name not in enabled_tool_names:
|
||||
continue
|
||||
if required not in available:
|
||||
deny.append(Rule(permission=name, pattern="*", action="deny"))
|
||||
return deny
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
"""Tool name → required searchable connector type (keep in sync with new_chat ``BUILTIN_TOOLS``)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
# Synced from ``app.agents.new_chat.tools.registry`` ToolDefinition.required_connector entries.
|
||||
_CONNECTOR_GATED: tuple[tuple[str, str], ...] = (
|
||||
("create_notion_page", "NOTION_CONNECTOR"),
|
||||
("update_notion_page", "NOTION_CONNECTOR"),
|
||||
("delete_notion_page", "NOTION_CONNECTOR"),
|
||||
("create_google_drive_file", "GOOGLE_DRIVE_FILE"),
|
||||
("delete_google_drive_file", "GOOGLE_DRIVE_FILE"),
|
||||
("create_dropbox_file", "DROPBOX_FILE"),
|
||||
("delete_dropbox_file", "DROPBOX_FILE"),
|
||||
("create_onedrive_file", "ONEDRIVE_FILE"),
|
||||
("delete_onedrive_file", "ONEDRIVE_FILE"),
|
||||
("search_calendar_events", "GOOGLE_CALENDAR_CONNECTOR"),
|
||||
("create_calendar_event", "GOOGLE_CALENDAR_CONNECTOR"),
|
||||
("update_calendar_event", "GOOGLE_CALENDAR_CONNECTOR"),
|
||||
("delete_calendar_event", "GOOGLE_CALENDAR_CONNECTOR"),
|
||||
("search_gmail", "GOOGLE_GMAIL_CONNECTOR"),
|
||||
("read_gmail_email", "GOOGLE_GMAIL_CONNECTOR"),
|
||||
("create_gmail_draft", "GOOGLE_GMAIL_CONNECTOR"),
|
||||
("send_gmail_email", "GOOGLE_GMAIL_CONNECTOR"),
|
||||
("trash_gmail_email", "GOOGLE_GMAIL_CONNECTOR"),
|
||||
("update_gmail_draft", "GOOGLE_GMAIL_CONNECTOR"),
|
||||
("create_confluence_page", "CONFLUENCE_CONNECTOR"),
|
||||
("update_confluence_page", "CONFLUENCE_CONNECTOR"),
|
||||
("delete_confluence_page", "CONFLUENCE_CONNECTOR"),
|
||||
("list_discord_channels", "DISCORD_CONNECTOR"),
|
||||
("read_discord_messages", "DISCORD_CONNECTOR"),
|
||||
("send_discord_message", "DISCORD_CONNECTOR"),
|
||||
("list_teams_channels", "TEAMS_CONNECTOR"),
|
||||
("read_teams_messages", "TEAMS_CONNECTOR"),
|
||||
("send_teams_message", "TEAMS_CONNECTOR"),
|
||||
("list_luma_events", "LUMA_CONNECTOR"),
|
||||
("read_luma_event", "LUMA_CONNECTOR"),
|
||||
("create_luma_event", "LUMA_CONNECTOR"),
|
||||
)
|
||||
|
||||
|
||||
def iter_connector_gated_tools() -> tuple[tuple[str, str], ...]:
|
||||
return _CONNECTOR_GATED
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
"""Minimal permission rule type (mirrors OpenCode semantics used by PermissionMiddleware)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
|
||||
RuleAction = Literal["allow", "deny", "ask"]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Rule:
|
||||
permission: str
|
||||
pattern: str
|
||||
action: RuleAction
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
"""Main-agent SurfSense tool allowlist."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .index import MAIN_AGENT_SURFSENSE_TOOL_NAMES, MAIN_AGENT_SURFSENSE_TOOL_NAMES_ORDERED
|
||||
|
||||
__all__ = ["MAIN_AGENT_SURFSENSE_TOOL_NAMES", "MAIN_AGENT_SURFSENSE_TOOL_NAMES_ORDERED"]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
"""Main-agent SurfSense builtin tool names (not full ``new_chat``).
|
||||
|
||||
Connector integrations, MCP, deliverables, etc. are delegated via ``task`` subagents.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
MAIN_AGENT_SURFSENSE_TOOL_NAMES_ORDERED: tuple[str, ...] = (
|
||||
"search_surfsense_docs",
|
||||
"web_search",
|
||||
"scrape_webpage",
|
||||
"update_memory",
|
||||
)
|
||||
|
||||
MAIN_AGENT_SURFSENSE_TOOL_NAMES: frozenset[str] = frozenset(
|
||||
MAIN_AGENT_SURFSENSE_TOOL_NAMES_ORDERED,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue