mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-17 18:35:19 +02:00
multi_agent_chat/shared: drop bucket types and helpers
This commit is contained in:
parent
014801c764
commit
31d6b43a42
7 changed files with 2 additions and 173 deletions
|
|
@ -5,19 +5,13 @@ from __future__ import annotations
|
|||
from app.agents.multi_agent_chat.subagents.shared.md_file_reader import (
|
||||
read_md_file,
|
||||
)
|
||||
from app.agents.multi_agent_chat.subagents.shared.spec import SurfSenseSubagentSpec
|
||||
from app.agents.multi_agent_chat.subagents.shared.subagent_builder import (
|
||||
pack_subagent,
|
||||
)
|
||||
from app.agents.multi_agent_chat.subagents.shared.tool_kinds import (
|
||||
ToolPermissionItem,
|
||||
ToolsPermissions,
|
||||
merge_tools_permissions,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"ToolPermissionItem",
|
||||
"ToolsPermissions",
|
||||
"merge_tools_permissions",
|
||||
"SurfSenseSubagentSpec",
|
||||
"pack_subagent",
|
||||
"read_md_file",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
"""Middleware-gated approval primitives — interception via langchain middlewares.
|
||||
|
||||
Public surface:
|
||||
- :func:`middleware_gated_tool_permission_row` — tag a tool's row for interception.
|
||||
- :func:`middleware_gated_interrupt_on` — build the ``interrupt_on`` map fed
|
||||
into ``HumanInTheLoopMiddleware``.
|
||||
|
||||
The actual ``HumanInTheLoopMiddleware`` and ``PermissionMiddleware`` instances
|
||||
that consume these helpers live under
|
||||
``middleware/shared/permissions/`` (rule-engine slice).
|
||||
"""
|
||||
|
||||
from .interrupt_on import middleware_gated_interrupt_on
|
||||
from .tool_row import middleware_gated_tool_permission_row
|
||||
|
||||
__all__ = [
|
||||
"middleware_gated_interrupt_on",
|
||||
"middleware_gated_tool_permission_row",
|
||||
]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
"""Build the ``interrupt_on`` map fed into ``HumanInTheLoopMiddleware``.
|
||||
|
||||
The map keys are tool names whose execution must be intercepted before
|
||||
the call runs. Self-gated rows are intentionally excluded: their bodies
|
||||
already pause via :func:`request_approval`, and intercepting them too
|
||||
would double-prompt the user.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from app.agents.multi_agent_chat.subagents.shared.tool_kinds import ToolsPermissions
|
||||
|
||||
|
||||
def middleware_gated_interrupt_on(bucket: ToolsPermissions) -> dict[str, bool]:
|
||||
"""``interrupt_on`` map for ``ask`` rows whose bodies don't self-gate."""
|
||||
return {
|
||||
r["name"]: True
|
||||
for r in bucket["ask"]
|
||||
if r.get("name") and r.get("kind") == "middleware_gated"
|
||||
}
|
||||
|
||||
|
||||
__all__ = ["middleware_gated_interrupt_on"]
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
"""Row builder tagging a tool for middleware-gated approval.
|
||||
|
||||
Used by MCP tool loading (``mcp_tools/index.py``) so each row carries
|
||||
``kind="middleware_gated"`` and surfaces in :func:`middleware_gated_interrupt_on`.
|
||||
Self-gated factories don't call this — they build rows inline with the
|
||||
default ``kind`` (which collapses to self-gated).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from langchain_core.tools import BaseTool
|
||||
|
||||
from app.agents.multi_agent_chat.subagents.shared.tool_kinds import (
|
||||
ToolPermissionItem,
|
||||
)
|
||||
|
||||
|
||||
def middleware_gated_tool_permission_row(tool: BaseTool) -> ToolPermissionItem:
|
||||
"""Build one allow/ask row tagged ``kind="middleware_gated"``."""
|
||||
return {
|
||||
"name": getattr(tool, "name", "") or "",
|
||||
"tool": tool,
|
||||
"kind": "middleware_gated",
|
||||
}
|
||||
|
||||
|
||||
__all__ = ["middleware_gated_tool_permission_row"]
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
Public surface:
|
||||
- :func:`request_approval` — entry point for sensitive tool bodies.
|
||||
- :func:`self_gated_tool_permission_row` — build an allow/ask row for a self-gated tool.
|
||||
- :class:`HITLResult` — outcome contract.
|
||||
- ``DEFAULT_AUTO_APPROVED_TOOLS`` — safe-by-construction allowlist.
|
||||
"""
|
||||
|
|
@ -10,11 +9,9 @@ Public surface:
|
|||
from .auto_approved import DEFAULT_AUTO_APPROVED_TOOLS
|
||||
from .request import request_approval
|
||||
from .result import HITLResult
|
||||
from .tool_row import self_gated_tool_permission_row
|
||||
|
||||
__all__ = [
|
||||
"DEFAULT_AUTO_APPROVED_TOOLS",
|
||||
"HITLResult",
|
||||
"request_approval",
|
||||
"self_gated_tool_permission_row",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
"""Row builder for tools that self-gate via :func:`request_approval`.
|
||||
|
||||
The default ``kind`` is omitted on purpose: ``ToolPermissionItem`` defaults
|
||||
to ``self_gated`` when ``kind`` is absent, so the row stays compact while
|
||||
keeping the type system honest. Symmetric with
|
||||
:mod:`hitl.approvals.middleware_gated.tool_row` so connector factories can
|
||||
read the same way for either kind.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from langchain_core.tools import BaseTool
|
||||
|
||||
from app.agents.multi_agent_chat.subagents.shared.tool_kinds import (
|
||||
ToolPermissionItem,
|
||||
)
|
||||
|
||||
|
||||
def self_gated_tool_permission_row(tool: BaseTool) -> ToolPermissionItem:
|
||||
"""Build one allow/ask row for a self-gated tool (body calls ``request_approval``)."""
|
||||
return {"name": getattr(tool, "name", "") or "", "tool": tool}
|
||||
|
||||
|
||||
__all__ = ["self_gated_tool_permission_row"]
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
"""Cross-kind primitives for tool permission rows.
|
||||
|
||||
Subagents classify their tools into ``allow`` and ``ask`` buckets, and each
|
||||
row may be either *self-gated* (the tool body calls
|
||||
:func:`request_approval`) or *middleware-gated* (a middleware intercepts
|
||||
the call). This module owns the shared types both kinds need:
|
||||
|
||||
- :data:`ToolKind` — the discriminator literal.
|
||||
- :class:`ToolPermissionItem` — one row in an allow/ask bucket.
|
||||
- :class:`ToolsPermissions` — the bucket pair.
|
||||
- :func:`merge_tools_permissions` — concatenates two buckets (typically a
|
||||
self-gated factory bucket and a middleware-gated MCP bucket).
|
||||
|
||||
Kind-specific helpers live under ``hitl/approvals/`` next to their gating
|
||||
mechanism:
|
||||
|
||||
- ``hitl/approvals/self_gated/`` — body-level ``request_approval`` primitive.
|
||||
- ``hitl/approvals/middleware_gated/`` — row builder + ``interrupt_on`` map.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Literal, NotRequired, TypedDict
|
||||
|
||||
from langchain_core.tools import BaseTool
|
||||
|
||||
ToolKind = Literal["self_gated", "middleware_gated"]
|
||||
|
||||
|
||||
class ToolPermissionItem(TypedDict):
|
||||
"""One allow/ask row.
|
||||
|
||||
``name`` is always set; ``tool`` is present when a bound BaseTool exists
|
||||
(absent for name-only MCP allow/ask rows). ``kind`` defaults to
|
||||
``self_gated`` when absent so existing connector factories keep working
|
||||
without explicit tagging.
|
||||
"""
|
||||
|
||||
name: str
|
||||
tool: NotRequired[BaseTool]
|
||||
kind: NotRequired[ToolKind]
|
||||
|
||||
|
||||
class ToolsPermissions(TypedDict):
|
||||
"""Allow/ask buckets shared by self-gated factories and middleware-gated MCP rows."""
|
||||
|
||||
allow: list[ToolPermissionItem]
|
||||
ask: list[ToolPermissionItem]
|
||||
|
||||
|
||||
def merge_tools_permissions(
|
||||
base: ToolsPermissions,
|
||||
extra: ToolsPermissions | None,
|
||||
) -> ToolsPermissions:
|
||||
"""Concatenate allow/ask lists (e.g. self-gated factory + middleware-gated MCP) before building HITL maps."""
|
||||
if not extra:
|
||||
return base
|
||||
return {
|
||||
"allow": [*base["allow"], *extra["allow"]],
|
||||
"ask": [*base["ask"], *extra["ask"]],
|
||||
}
|
||||
|
||||
|
||||
__all__ = [
|
||||
"ToolKind",
|
||||
"ToolPermissionItem",
|
||||
"ToolsPermissions",
|
||||
"merge_tools_permissions",
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue