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