mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-08 20:25:19 +02:00
refactor(agents): unify permissions into one vertical-slice package
Per-file verification of the slice-3 candidates showed receipts/ and
date_filters.py are shared contracts (consumed by shared/state + shared
middleware + subagents), so they correctly stay put.
permissions was the real misfit: the rule *model* lived at shared/permissions.py
while its enforcement lived at shared/middleware/permissions/. Unify them into a
single self-contained subsystem:
shared/permissions.py -> shared/permissions/model.py
shared/middleware/permissions/{deny,ask,middleware}
-> shared/permissions/{deny,ask,middleware}
The package __init__ re-exports the model API + build_permission_mw, so the 32
external model consumers keep importing `from ...shared.permissions import Rule`
unchanged; only the 8 internal files redirect to `.model` (cycle-safe, model
loaded before middleware).
This commit is contained in:
parent
f2a61bc0ef
commit
84b775c0ac
27 changed files with 75 additions and 42 deletions
|
|
@ -35,13 +35,13 @@ from app.agents.chat.multi_agent_chat.shared.middleware.memory import build_memo
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.patch_tool_calls import (
|
from app.agents.chat.multi_agent_chat.shared.middleware.patch_tool_calls import (
|
||||||
build_patch_tool_calls_mw,
|
build_patch_tool_calls_mw,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
|
|
||||||
build_permission_mw,
|
|
||||||
)
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.resilience import (
|
from app.agents.chat.multi_agent_chat.shared.middleware.resilience import (
|
||||||
build_resilience_middlewares,
|
build_resilience_middlewares,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.todos import build_todos_mw
|
from app.agents.chat.multi_agent_chat.shared.middleware.todos import build_todos_mw
|
||||||
|
from app.agents.chat.multi_agent_chat.shared.permissions import (
|
||||||
|
build_permission_mw,
|
||||||
|
)
|
||||||
from app.agents.chat.multi_agent_chat.subagents import (
|
from app.agents.chat.multi_agent_chat.subagents import (
|
||||||
build_subagents,
|
build_subagents,
|
||||||
get_subagents_to_exclude,
|
get_subagents_to_exclude,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
"""Pattern-based allow/deny/ask middleware with HITL fallback (vertical slice).
|
|
||||||
|
|
||||||
Public surface (one entry point only — every other symbol is an internal of
|
|
||||||
the rule engine and stays inside ``middleware/``, ``ask/``, or ``deny.py``):
|
|
||||||
|
|
||||||
- :func:`build_permission_mw` — construction recipe shared by every stack.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .middleware.factory import build_permission_mw
|
|
||||||
|
|
||||||
__all__ = ["build_permission_mw"]
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
"""Permissions vertical slice: rule model + allow/deny/ask enforcement.
|
||||||
|
|
||||||
|
Self-contained subsystem combining the permission rule engine (:mod:`.model`)
|
||||||
|
with the pattern-based allow/deny/ask middleware and its HITL fallback
|
||||||
|
(:mod:`.middleware`, :mod:`.ask`, :mod:`.deny`).
|
||||||
|
|
||||||
|
Public surface:
|
||||||
|
- rule model: ``Rule``, ``Ruleset``, ``RuleAction`` and the ``evaluate`` /
|
||||||
|
``evaluate_many`` / ``aggregate_action`` / ``wildcard_match`` helpers.
|
||||||
|
- middleware: ``build_permission_mw`` — the construction recipe shared by
|
||||||
|
every agent stack.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# isort: off
|
||||||
|
# Import order matters: the rule model must be bound on this package before the
|
||||||
|
# middleware loads, because the middleware transitively imports consumers (e.g.
|
||||||
|
# app.services.user_tool_allowlist) that re-import ``Rule``/``Ruleset`` from this
|
||||||
|
# package root. Loading ``.model`` first avoids a partially-initialized cycle.
|
||||||
|
from .model import (
|
||||||
|
Rule,
|
||||||
|
RuleAction,
|
||||||
|
Ruleset,
|
||||||
|
aggregate_action,
|
||||||
|
evaluate,
|
||||||
|
evaluate_many,
|
||||||
|
wildcard_match,
|
||||||
|
)
|
||||||
|
from .middleware.factory import build_permission_mw
|
||||||
|
|
||||||
|
# isort: on
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Rule",
|
||||||
|
"RuleAction",
|
||||||
|
"Ruleset",
|
||||||
|
"aggregate_action",
|
||||||
|
"build_permission_mw",
|
||||||
|
"evaluate",
|
||||||
|
"evaluate_many",
|
||||||
|
"wildcard_match",
|
||||||
|
]
|
||||||
|
|
@ -6,7 +6,7 @@ from typing import Any
|
||||||
|
|
||||||
from langchain_core.tools import BaseTool
|
from langchain_core.tools import BaseTool
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule
|
from app.agents.chat.multi_agent_chat.shared.permissions.model import Rule
|
||||||
from app.agents.chat.multi_agent_chat.subagents.shared.hitl.wire import (
|
from app.agents.chat.multi_agent_chat.subagents.shared.hitl.wire import (
|
||||||
LC_DECISION_APPROVE,
|
LC_DECISION_APPROVE,
|
||||||
LC_DECISION_EDIT,
|
LC_DECISION_EDIT,
|
||||||
|
|
@ -16,7 +16,7 @@ from typing import Any
|
||||||
from langchain_core.tools import BaseTool
|
from langchain_core.tools import BaseTool
|
||||||
from langgraph.types import interrupt
|
from langgraph.types import interrupt
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule
|
from app.agents.chat.multi_agent_chat.shared.permissions.model import Rule
|
||||||
from app.observability import metrics as ot_metrics, otel as ot
|
from app.observability import metrics as ot_metrics, otel as ot
|
||||||
|
|
||||||
from .decision import normalize_permission_decision
|
from .decision import normalize_permission_decision
|
||||||
|
|
@ -11,7 +11,7 @@ from typing import Any
|
||||||
|
|
||||||
from langchain_core.messages import ToolMessage
|
from langchain_core.messages import ToolMessage
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule
|
from app.agents.chat.multi_agent_chat.shared.permissions.model import Rule
|
||||||
from app.agents.chat.runtime.errors import StreamingError
|
from app.agents.chat.runtime.errors import StreamingError
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ from langchain_core.messages import AIMessage, ToolMessage
|
||||||
from langchain_core.tools import BaseTool
|
from langchain_core.tools import BaseTool
|
||||||
from langgraph.runtime import Runtime
|
from langgraph.runtime import Runtime
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Ruleset
|
from app.agents.chat.multi_agent_chat.shared.permissions.model import Ruleset
|
||||||
from app.agents.chat.runtime.errors import CorrectedError, RejectedError
|
from app.agents.chat.runtime.errors import CorrectedError, RejectedError
|
||||||
from app.services.user_tool_allowlist import TrustedToolSaver
|
from app.services.user_tool_allowlist import TrustedToolSaver
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ from __future__ import annotations
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import (
|
from app.agents.chat.multi_agent_chat.shared.permissions.model import (
|
||||||
Rule,
|
Rule,
|
||||||
RuleAction,
|
RuleAction,
|
||||||
Ruleset,
|
Ruleset,
|
||||||
|
|
@ -28,7 +28,7 @@ from collections.abc import Sequence
|
||||||
from langchain_core.tools import BaseTool
|
from langchain_core.tools import BaseTool
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset
|
from app.agents.chat.multi_agent_chat.shared.permissions.model import Rule, Ruleset
|
||||||
from app.services.user_tool_allowlist import TrustedToolSaver
|
from app.services.user_tool_allowlist import TrustedToolSaver
|
||||||
|
|
||||||
from .core import PermissionMiddleware
|
from .core import PermissionMiddleware
|
||||||
|
|
@ -9,7 +9,7 @@ newly-promoted rules apply to subsequent calls.
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import (
|
from app.agents.chat.multi_agent_chat.shared.permissions.model import (
|
||||||
Ruleset,
|
Ruleset,
|
||||||
aggregate_action,
|
aggregate_action,
|
||||||
evaluate_many,
|
evaluate_many,
|
||||||
|
|
@ -7,7 +7,7 @@ is the streaming layer's job — this module keeps the in-memory copy only.
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset
|
from app.agents.chat.multi_agent_chat.shared.permissions.model import Rule, Ruleset
|
||||||
|
|
||||||
|
|
||||||
def persist_always(
|
def persist_always(
|
||||||
|
|
@ -27,10 +27,10 @@ from app.agents.chat.multi_agent_chat.shared.middleware.kb_context_projection im
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.patch_tool_calls import (
|
from app.agents.chat.multi_agent_chat.shared.middleware.patch_tool_calls import (
|
||||||
build_patch_tool_calls_mw,
|
build_patch_tool_calls_mw,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
|
from app.agents.chat.multi_agent_chat.shared.permissions import (
|
||||||
|
Ruleset,
|
||||||
build_permission_mw,
|
build_permission_mw,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Ruleset
|
|
||||||
|
|
||||||
|
|
||||||
def _kb_user_allowlist(
|
def _kb_user_allowlist(
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ from __future__ import annotations
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
|
|
||||||
build_permission_mw,
|
|
||||||
)
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.resilience import (
|
from app.agents.chat.multi_agent_chat.shared.middleware.resilience import (
|
||||||
ResilienceMiddlewares,
|
ResilienceMiddlewares,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.todos import build_todos_mw
|
from app.agents.chat.multi_agent_chat.shared.middleware.todos import build_todos_mw
|
||||||
|
from app.agents.chat.multi_agent_chat.shared.permissions import (
|
||||||
|
build_permission_mw,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def build_subagent_middleware_stack(
|
def build_subagent_middleware_stack(
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ from deepagents.middleware.patch_tool_calls import PatchToolCallsMiddleware
|
||||||
from langchain_core.language_models import BaseChatModel
|
from langchain_core.language_models import BaseChatModel
|
||||||
from langchain_core.tools import BaseTool
|
from langchain_core.tools import BaseTool
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
|
from app.agents.chat.multi_agent_chat.shared.permissions import (
|
||||||
|
Ruleset,
|
||||||
build_permission_mw,
|
build_permission_mw,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Ruleset
|
|
||||||
from app.agents.chat.multi_agent_chat.subagents.shared.md_file_reader import (
|
from app.agents.chat.multi_agent_chat.subagents.shared.md_file_reader import (
|
||||||
read_shared_snippet,
|
read_shared_snippet,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,10 @@ from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagen
|
||||||
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
|
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
|
||||||
build_task_tool_with_parent_config,
|
build_task_tool_with_parent_config,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions.ask.request import (
|
from app.agents.chat.multi_agent_chat.shared.permissions import Rule
|
||||||
|
from app.agents.chat.multi_agent_chat.shared.permissions.ask.request import (
|
||||||
request_permission_decision,
|
request_permission_decision,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule
|
|
||||||
from app.agents.chat.multi_agent_chat.subagents.shared.hitl.approvals.self_gated import (
|
from app.agents.chat.multi_agent_chat.subagents.shared.hitl.approvals.self_gated import (
|
||||||
request_approval,
|
request_approval,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ from langgraph.graph import END, START, StateGraph
|
||||||
from langgraph.types import Command
|
from langgraph.types import Command
|
||||||
from typing_extensions import TypedDict
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions.ask.request import (
|
from app.agents.chat.multi_agent_chat.shared.permissions import Rule
|
||||||
|
from app.agents.chat.multi_agent_chat.shared.permissions.ask.request import (
|
||||||
request_permission_decision,
|
request_permission_decision,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule
|
|
||||||
|
|
||||||
|
|
||||||
class _State(TypedDict, total=False):
|
class _State(TypedDict, total=False):
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,14 @@ from pydantic import BaseModel
|
||||||
from typing_extensions import TypedDict
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
|
from app.agents.chat.multi_agent_chat.shared.permissions import (
|
||||||
|
Rule,
|
||||||
|
Ruleset,
|
||||||
build_permission_mw,
|
build_permission_mw,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions.ask.payload import (
|
from app.agents.chat.multi_agent_chat.shared.permissions.ask.payload import (
|
||||||
build_permission_ask_payload,
|
build_permission_ask_payload,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset
|
|
||||||
|
|
||||||
|
|
||||||
class _NoArgs(BaseModel):
|
class _NoArgs(BaseModel):
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,11 @@ from langgraph.types import Command
|
||||||
from typing_extensions import TypedDict
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
|
from app.agents.chat.multi_agent_chat.shared.permissions import (
|
||||||
|
Rule,
|
||||||
|
Ruleset,
|
||||||
build_permission_mw,
|
build_permission_mw,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset
|
|
||||||
|
|
||||||
|
|
||||||
def _kb_style_ruleset() -> Ruleset:
|
def _kb_style_ruleset() -> Ruleset:
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,11 @@ from pydantic import BaseModel
|
||||||
from typing_extensions import TypedDict
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
|
from app.agents.chat.multi_agent_chat.shared.permissions import (
|
||||||
|
Rule,
|
||||||
|
Ruleset,
|
||||||
build_permission_mw,
|
build_permission_mw,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset
|
|
||||||
|
|
||||||
|
|
||||||
class _NoArgs(BaseModel):
|
class _NoArgs(BaseModel):
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
|
||||||
from langchain_core.outputs import ChatGeneration, ChatResult
|
from langchain_core.outputs import ChatGeneration, ChatResult
|
||||||
|
|
||||||
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
|
||||||
from app.agents.chat.multi_agent_chat.shared.middleware.permissions.middleware.core import (
|
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset, evaluate
|
||||||
|
from app.agents.chat.multi_agent_chat.shared.permissions.middleware.core import (
|
||||||
PermissionMiddleware,
|
PermissionMiddleware,
|
||||||
)
|
)
|
||||||
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset, evaluate
|
|
||||||
from app.agents.chat.multi_agent_chat.subagents.shared.subagent_builder import (
|
from app.agents.chat.multi_agent_chat.subagents.shared.subagent_builder import (
|
||||||
pack_subagent,
|
pack_subagent,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue