modelfuzz 0.1.1__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- modelfuzz-0.1.2/.claude/settings.local.json +27 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/PKG-INFO +1 -1
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/pyproject.toml +1 -1
- modelfuzz-0.1.2/src/modelfuzz/decorator.py +64 -0
- modelfuzz-0.1.1/.claude/settings.local.json +0 -12
- modelfuzz-0.1.1/src/modelfuzz/decorator.py +0 -45
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/.github/workflows/ci.yml +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/.gitignore +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/.pre-commit-config.yaml +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/CONTRIBUTING.md +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/LICENSE +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/README.md +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/demo.py +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/src/modelfuzz/__init__.py +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/src/modelfuzz/cli.py +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/src/modelfuzz/engine.py +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/src/modelfuzz/exceptions.py +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/src/modelfuzz/rules.py +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/tests/test_decorator.py +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/tests/test_engine.py +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/tests/test_rules.py +0 -0
- {modelfuzz-0.1.1 → modelfuzz-0.1.2}/uv.lock +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(git -C /Users/gagandeep/agentshield status --short --branch)",
|
|
5
|
+
"Bash(uv --version)",
|
|
6
|
+
"Bash(uv sync *)",
|
|
7
|
+
"Bash(uv run python -c ' *)",
|
|
8
|
+
"Bash(uv run *)",
|
|
9
|
+
"Bash(git add *)",
|
|
10
|
+
"Bash(python3 -c \"import modelfuzz; print\\(modelfuzz.__file__\\)\")",
|
|
11
|
+
"Bash(pip show *)",
|
|
12
|
+
"Bash(python3 test_agent.py)",
|
|
13
|
+
"Bash(python3 -c \"import sys; print\\(sys.path\\)\")",
|
|
14
|
+
"Bash(pip list *)",
|
|
15
|
+
"Bash(python3 -c \"import sys,site; print\\(site.getsitepackages\\(\\)\\)\")",
|
|
16
|
+
"Bash(find / -maxdepth 6 -iname \"modelfuzz*\" -not -path \"*/modelfuzz/*\")",
|
|
17
|
+
"Bash(./.venv/bin/pip show *)",
|
|
18
|
+
"Bash(./.venv/bin/python3 test_agent.py)",
|
|
19
|
+
"Bash(python3 -c ' *)",
|
|
20
|
+
"Bash(python3 -m pytest -q)",
|
|
21
|
+
"Bash(./.venv/bin/pip install *)",
|
|
22
|
+
"Bash(./.venv/bin/python test_agent.py)",
|
|
23
|
+
"Bash(python3 -m pip show build twine)",
|
|
24
|
+
"Bash(env)"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Decorators for shielding agent tool functions."""
|
|
2
|
+
|
|
3
|
+
import functools
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from typing import ParamSpec, TypeVar, overload
|
|
6
|
+
|
|
7
|
+
from modelfuzz.engine import PolicyEngine
|
|
8
|
+
from modelfuzz.exceptions import ModelFuzzBlockError
|
|
9
|
+
from modelfuzz.rules import SensitiveDataFilter
|
|
10
|
+
|
|
11
|
+
P = ParamSpec("P")
|
|
12
|
+
R = TypeVar("R")
|
|
13
|
+
|
|
14
|
+
# Default policy engine for the decorator
|
|
15
|
+
default_policies = [SensitiveDataFilter()]
|
|
16
|
+
_default_engine = PolicyEngine(default_policies)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@overload
|
|
20
|
+
def shield_tool(engine: Callable[P, R]) -> Callable[P, R]: ...
|
|
21
|
+
@overload
|
|
22
|
+
def shield_tool(
|
|
23
|
+
engine: PolicyEngine | None = None,
|
|
24
|
+
) -> Callable[[Callable[P, R]], Callable[P, R]]: ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def shield_tool(engine=None):
|
|
28
|
+
"""Wrap a tool function so every call is intercepted before execution.
|
|
29
|
+
|
|
30
|
+
Usable bare (``@shield_tool``) or called (``@shield_tool()`` /
|
|
31
|
+
``@shield_tool(engine)``).
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
engine: The policy engine to use for validation. If None, a default
|
|
35
|
+
engine with a SensitiveDataFilter is used. When applied bare,
|
|
36
|
+
this receives the function being decorated instead.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
The wrapped function, or a decorator that produces it.
|
|
40
|
+
"""
|
|
41
|
+
if callable(engine) and not isinstance(engine, PolicyEngine):
|
|
42
|
+
return _wrap(engine, _default_engine)
|
|
43
|
+
|
|
44
|
+
actual_engine = engine if engine is not None else _default_engine
|
|
45
|
+
|
|
46
|
+
def decorator(func: Callable[P, R]) -> Callable[P, R]:
|
|
47
|
+
return _wrap(func, actual_engine)
|
|
48
|
+
|
|
49
|
+
return decorator
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _wrap(func: Callable[P, R], actual_engine: PolicyEngine) -> Callable[P, R]:
|
|
53
|
+
@functools.wraps(func)
|
|
54
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
55
|
+
# Check all arguments against the policy engine
|
|
56
|
+
for arg in list(args) + list(kwargs.values()):
|
|
57
|
+
result = actual_engine.run(arg)
|
|
58
|
+
if not result.allowed:
|
|
59
|
+
raise ModelFuzzBlockError(result.reason or "Call blocked by policy")
|
|
60
|
+
|
|
61
|
+
print(f"ModelFuzz Intercepted: {func.__name__}")
|
|
62
|
+
return func(*args, **kwargs)
|
|
63
|
+
|
|
64
|
+
return wrapper
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"""Decorators for shielding agent tool functions."""
|
|
2
|
-
|
|
3
|
-
import functools
|
|
4
|
-
from collections.abc import Callable
|
|
5
|
-
from typing import ParamSpec, TypeVar
|
|
6
|
-
|
|
7
|
-
from modelfuzz.engine import PolicyEngine
|
|
8
|
-
from modelfuzz.exceptions import ModelFuzzBlockError
|
|
9
|
-
from modelfuzz.rules import SensitiveDataFilter
|
|
10
|
-
|
|
11
|
-
P = ParamSpec("P")
|
|
12
|
-
R = TypeVar("R")
|
|
13
|
-
|
|
14
|
-
# Default policy engine for the decorator
|
|
15
|
-
default_policies = [SensitiveDataFilter()]
|
|
16
|
-
_default_engine = PolicyEngine(default_policies)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def shield_tool(engine: PolicyEngine | None = None) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
20
|
-
"""Wrap a tool function so every call is intercepted before execution.
|
|
21
|
-
|
|
22
|
-
Args:
|
|
23
|
-
engine: The policy engine to use for validation. If None, a default
|
|
24
|
-
engine with a SensitiveDataFilter is used.
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
A decorator that wraps the function.
|
|
28
|
-
"""
|
|
29
|
-
actual_engine = engine if engine is not None else _default_engine
|
|
30
|
-
|
|
31
|
-
def decorator(func: Callable[P, R]) -> Callable[P, R]:
|
|
32
|
-
@functools.wraps(func)
|
|
33
|
-
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
34
|
-
# Check all arguments against the policy engine
|
|
35
|
-
for arg in list(args) + list(kwargs.values()):
|
|
36
|
-
result = actual_engine.run(arg)
|
|
37
|
-
if not result.allowed:
|
|
38
|
-
raise ModelFuzzBlockError(result.reason or "Call blocked by policy")
|
|
39
|
-
|
|
40
|
-
print(f"ModelFuzz Intercepted: {func.__name__}")
|
|
41
|
-
return func(*args, **kwargs)
|
|
42
|
-
|
|
43
|
-
return wrapper
|
|
44
|
-
|
|
45
|
-
return decorator
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|