strathon 1.2.2__tar.gz → 1.2.3__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.
- {strathon-1.2.2/src/strathon.egg-info → strathon-1.2.3}/PKG-INFO +3 -3
- {strathon-1.2.2 → strathon-1.2.3}/pyproject.toml +3 -3
- strathon-1.2.3/src/strathon/_version.py +1 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/client.py +1 -1
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/config.py +1 -1
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/heartbeat.py +1 -1
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/openai_agents.py +1 -2
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/policy/approval.py +1 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/policy/enforcer.py +15 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/policy/steer.py +0 -2
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/policy/types.py +4 -3
- {strathon-1.2.2 → strathon-1.2.3/src/strathon.egg-info}/PKG-INFO +3 -3
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon.egg-info/requires.txt +2 -2
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_smoke.py +1 -1
- strathon-1.2.2/src/strathon/_version.py +0 -1
- {strathon-1.2.2 → strathon-1.2.3}/LICENSE +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/NOTICE +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/README.md +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/setup.cfg +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/__init__.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/exceptions.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/exporter/__init__.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/exporter/otlp.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/__init__.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/anthropic.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/autogen.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/claude_agent.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/crewai.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/google_adk.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/langchain.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/langgraph.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/openai.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/instrumentation/pydantic_ai.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/intervention/__init__.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/intervention/hooks.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/policy/__init__.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/policy/expression.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/policy/halt_enforcer.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/policy/throttle.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon/py.typed +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon.egg-info/SOURCES.txt +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon.egg-info/dependency_links.txt +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/src/strathon.egg-info/top_level.txt +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_allow_list_mode.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_approval_sdk.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_crewai.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_crewai_intervention.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_enforcement_matrix.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_fail_closed.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_framework_upgrades.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_google_adk.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_halt_enforcer.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_instrumentation_hooks.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_instrumentation_stubs.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_langgraph.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_openai_agents.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_openai_agents_intervention.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_openai_agents_steer.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_policy_enforcer.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_policy_expression.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_policy_integration.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_policy_time.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_pydantic_ai.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_steer.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_steer_halt.py +0 -0
- {strathon-1.2.2 → strathon-1.2.3}/tests/test_throttle.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: strathon
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.3
|
|
4
4
|
Summary: Open-source AI agent firewall. Blocks dangerous agent tool calls before they execute, with in-process CEL enforcement at the tool-call boundary.
|
|
5
5
|
Author-email: Strathon <hello@getstrathon.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -39,7 +39,7 @@ Requires-Dist: openai-agents>=0.17.5; extra == "openai-agents"
|
|
|
39
39
|
Provides-Extra: anthropic
|
|
40
40
|
Requires-Dist: anthropic>=0.40.0; extra == "anthropic"
|
|
41
41
|
Provides-Extra: claude-agent
|
|
42
|
-
Requires-Dist: claude-agent-sdk>=0.1.
|
|
42
|
+
Requires-Dist: claude-agent-sdk>=0.1.81; extra == "claude-agent"
|
|
43
43
|
Requires-Dist: anthropic>=0.40.0; extra == "claude-agent"
|
|
44
44
|
Provides-Extra: langchain
|
|
45
45
|
Requires-Dist: langchain-core>=0.3.0; extra == "langchain"
|
|
@@ -59,7 +59,7 @@ Provides-Extra: all
|
|
|
59
59
|
Requires-Dist: openai>=1.0.0; extra == "all"
|
|
60
60
|
Requires-Dist: openai-agents>=0.17.5; extra == "all"
|
|
61
61
|
Requires-Dist: anthropic>=0.40.0; extra == "all"
|
|
62
|
-
Requires-Dist: claude-agent-sdk>=0.1.
|
|
62
|
+
Requires-Dist: claude-agent-sdk>=0.1.81; extra == "all"
|
|
63
63
|
Requires-Dist: langchain-core>=0.3.0; extra == "all"
|
|
64
64
|
Requires-Dist: crewai>=1.14.7; extra == "all"
|
|
65
65
|
Requires-Dist: autogen-agentchat>=0.7.0; extra == "all"
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "strathon"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.3"
|
|
8
8
|
description = "Open-source AI agent firewall. Blocks dangerous agent tool calls before they execute, with in-process CEL enforcement at the tool-call boundary."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -40,7 +40,7 @@ dependencies = [
|
|
|
40
40
|
openai = ["openai>=1.0.0"]
|
|
41
41
|
openai-agents = ["openai-agents>=0.17.5"]
|
|
42
42
|
anthropic = ["anthropic>=0.40.0"]
|
|
43
|
-
claude-agent = ["claude-agent-sdk>=0.1.
|
|
43
|
+
claude-agent = ["claude-agent-sdk>=0.1.81", "anthropic>=0.40.0"]
|
|
44
44
|
langchain = ["langchain-core>=0.3.0"]
|
|
45
45
|
langgraph = ["langchain-core>=0.3.0"]
|
|
46
46
|
crewai = ["crewai>=1.14.7"]
|
|
@@ -52,7 +52,7 @@ all = [
|
|
|
52
52
|
"openai>=1.0.0",
|
|
53
53
|
"openai-agents>=0.17.5",
|
|
54
54
|
"anthropic>=0.40.0",
|
|
55
|
-
"claude-agent-sdk>=0.1.
|
|
55
|
+
"claude-agent-sdk>=0.1.81",
|
|
56
56
|
"langchain-core>=0.3.0",
|
|
57
57
|
"crewai>=1.14.7",
|
|
58
58
|
"autogen-agentchat>=0.7.0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.2.3"
|
|
@@ -138,7 +138,7 @@ class Client:
|
|
|
138
138
|
trace.set_tracer_provider(self._tracer_provider)
|
|
139
139
|
|
|
140
140
|
# Named tracer for instrumentations and manual span emission
|
|
141
|
-
self._tracer = self._tracer_provider.get_tracer("strathon", "1.2.
|
|
141
|
+
self._tracer = self._tracer_provider.get_tracer("strathon", "1.2.3")
|
|
142
142
|
|
|
143
143
|
# Runtime intervention: optional policy enforcer
|
|
144
144
|
self._policy_enforcer = None
|
|
@@ -840,8 +840,7 @@ def _build_strathon_guardrail_function(client):
|
|
|
840
840
|
# The guardrail is async, so we do REAL interactive approval:
|
|
841
841
|
# wait for the operator off the event loop. Approved -> allow the
|
|
842
842
|
# tool to run; denied/expired/timed out -> raise_exception so the
|
|
843
|
-
# tool body never runs.
|
|
844
|
-
# allow() here (a silent-allow gap).
|
|
843
|
+
# tool body never runs.
|
|
845
844
|
from strathon.policy import await_for_approval
|
|
846
845
|
try:
|
|
847
846
|
await await_for_approval(
|
|
@@ -57,6 +57,7 @@ def request_approval(
|
|
|
57
57
|
"tool_name": attrs.get("gen_ai.tool.name") or attrs.get("strathon.tool.name"),
|
|
58
58
|
"tool_args": attrs.get("strathon.tool.args"),
|
|
59
59
|
"timeout_seconds": decision.timeout_seconds or 300,
|
|
60
|
+
"approvers_required": decision.approvers_required or 1,
|
|
60
61
|
}).encode("utf-8")
|
|
61
62
|
|
|
62
63
|
api_key = getattr(client, "_api_key", None)
|
|
@@ -281,6 +281,20 @@ class PolicyEnforcer:
|
|
|
281
281
|
timeout = int(raw_timeout)
|
|
282
282
|
if timeout <= 0:
|
|
283
283
|
timeout = 300
|
|
284
|
+
# approvers_required (the N in N-of-M). Same fail-safe posture:
|
|
285
|
+
# an invalid value must never raise out of check_policy, so it
|
|
286
|
+
# falls back to 1 (single sign-off) rather than disabling the
|
|
287
|
+
# policy. The receiver enforces the threshold and dedupes
|
|
288
|
+
# distinct approvers.
|
|
289
|
+
raw_approvers = (policy.action_config or {}).get(
|
|
290
|
+
"approvers_required", 1
|
|
291
|
+
)
|
|
292
|
+
if isinstance(raw_approvers, bool) or not isinstance(
|
|
293
|
+
raw_approvers, int
|
|
294
|
+
):
|
|
295
|
+
approvers_required = 1
|
|
296
|
+
else:
|
|
297
|
+
approvers_required = raw_approvers if raw_approvers >= 1 else 1
|
|
284
298
|
return PolicyDecision(
|
|
285
299
|
action="require_approval",
|
|
286
300
|
policy_id=policy.id,
|
|
@@ -290,6 +304,7 @@ class PolicyEnforcer:
|
|
|
290
304
|
or f"Tool call requires approval per policy '{policy.name}'"
|
|
291
305
|
),
|
|
292
306
|
timeout_seconds=timeout,
|
|
307
|
+
approvers_required=approvers_required,
|
|
293
308
|
)
|
|
294
309
|
# steer
|
|
295
310
|
replacement = (
|
|
@@ -709,8 +709,6 @@ def _install_class_patch(cls: Type[Any]) -> None:
|
|
|
709
709
|
# Route through the async dispatcher so this surface enforces the
|
|
710
710
|
# full action set — halt check, block, throttle, steer, AND real
|
|
711
711
|
# interactive require_approval — identically to the sync path.
|
|
712
|
-
# Previously this hand-rolled only block/throttle/steer and ran the
|
|
713
|
-
# body for approval/halt (a silent-allow gap).
|
|
714
712
|
return await dispatch_policy_decision_async(
|
|
715
713
|
client,
|
|
716
714
|
span_name=span_name,
|
|
@@ -27,9 +27,9 @@ class Policy:
|
|
|
27
27
|
priority: int = 0
|
|
28
28
|
description: Optional[str] = None
|
|
29
29
|
# Shadow policies are evaluated and recorded server-side but must never
|
|
30
|
-
# enforce.
|
|
31
|
-
#
|
|
32
|
-
#
|
|
30
|
+
# enforce in-process. This field is carried through parse so a shadow
|
|
31
|
+
# block policy stays observe-only instead of blocking for real, honoring
|
|
32
|
+
# the "test without enforcing" contract.
|
|
33
33
|
shadow: bool = False
|
|
34
34
|
|
|
35
35
|
def to_dict(self) -> Dict[str, Any]:
|
|
@@ -92,6 +92,7 @@ class PolicyDecision:
|
|
|
92
92
|
retry_after_seconds: Optional[float] = None
|
|
93
93
|
approval_id: Optional[str] = None
|
|
94
94
|
timeout_seconds: Optional[int] = None
|
|
95
|
+
approvers_required: Optional[int] = None
|
|
95
96
|
|
|
96
97
|
@property
|
|
97
98
|
def is_allow(self) -> bool:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: strathon
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.3
|
|
4
4
|
Summary: Open-source AI agent firewall. Blocks dangerous agent tool calls before they execute, with in-process CEL enforcement at the tool-call boundary.
|
|
5
5
|
Author-email: Strathon <hello@getstrathon.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -39,7 +39,7 @@ Requires-Dist: openai-agents>=0.17.5; extra == "openai-agents"
|
|
|
39
39
|
Provides-Extra: anthropic
|
|
40
40
|
Requires-Dist: anthropic>=0.40.0; extra == "anthropic"
|
|
41
41
|
Provides-Extra: claude-agent
|
|
42
|
-
Requires-Dist: claude-agent-sdk>=0.1.
|
|
42
|
+
Requires-Dist: claude-agent-sdk>=0.1.81; extra == "claude-agent"
|
|
43
43
|
Requires-Dist: anthropic>=0.40.0; extra == "claude-agent"
|
|
44
44
|
Provides-Extra: langchain
|
|
45
45
|
Requires-Dist: langchain-core>=0.3.0; extra == "langchain"
|
|
@@ -59,7 +59,7 @@ Provides-Extra: all
|
|
|
59
59
|
Requires-Dist: openai>=1.0.0; extra == "all"
|
|
60
60
|
Requires-Dist: openai-agents>=0.17.5; extra == "all"
|
|
61
61
|
Requires-Dist: anthropic>=0.40.0; extra == "all"
|
|
62
|
-
Requires-Dist: claude-agent-sdk>=0.1.
|
|
62
|
+
Requires-Dist: claude-agent-sdk>=0.1.81; extra == "all"
|
|
63
63
|
Requires-Dist: langchain-core>=0.3.0; extra == "all"
|
|
64
64
|
Requires-Dist: crewai>=1.14.7; extra == "all"
|
|
65
65
|
Requires-Dist: autogen-agentchat>=0.7.0; extra == "all"
|
|
@@ -9,7 +9,7 @@ cel-python>=0.5.0
|
|
|
9
9
|
openai>=1.0.0
|
|
10
10
|
openai-agents>=0.17.5
|
|
11
11
|
anthropic>=0.40.0
|
|
12
|
-
claude-agent-sdk>=0.1.
|
|
12
|
+
claude-agent-sdk>=0.1.81
|
|
13
13
|
langchain-core>=0.3.0
|
|
14
14
|
crewai>=1.14.7
|
|
15
15
|
autogen-agentchat>=0.7.0
|
|
@@ -23,7 +23,7 @@ anthropic>=0.40.0
|
|
|
23
23
|
autogen-agentchat>=0.7.0
|
|
24
24
|
|
|
25
25
|
[claude-agent]
|
|
26
|
-
claude-agent-sdk>=0.1.
|
|
26
|
+
claude-agent-sdk>=0.1.81
|
|
27
27
|
anthropic>=0.40.0
|
|
28
28
|
|
|
29
29
|
[crewai]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.2.2"
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|