safentic 1.0.2__tar.gz → 1.0.4__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.
- {safentic-1.0.2/safentic.egg-info → safentic-1.0.4}/PKG-INFO +2 -2
- {safentic-1.0.2 → safentic-1.0.4}/requirements.txt +1 -1
- {safentic-1.0.2 → safentic-1.0.4}/safentic/__init__.py +1 -1
- {safentic-1.0.2 → safentic-1.0.4}/safentic/layer.py +16 -10
- safentic-1.0.4/safentic/policies/policy.yaml +49 -0
- {safentic-1.0.2 → safentic-1.0.4/safentic.egg-info}/PKG-INFO +2 -2
- {safentic-1.0.2 → safentic-1.0.4}/safentic.egg-info/requires.txt +1 -1
- {safentic-1.0.2 → safentic-1.0.4}/setup.py +2 -2
- safentic-1.0.2/safentic/policies/policy.yaml +0 -25
- {safentic-1.0.2 → safentic-1.0.4}/MANIFEST.in +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/README.md +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/LICENSE.txt +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/config.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/engine.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/helper/__init__.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/helper/auth.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/logger/__init__.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/logger/audit.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/policies/.gitkeep +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/policies/__init__.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/policies/example_policy.txt +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/policy.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/verifiers/__init__.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic/verifiers/sentence_verifier.py +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic.egg-info/SOURCES.txt +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic.egg-info/dependency_links.txt +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/safentic.egg-info/top_level.txt +0 -0
- {safentic-1.0.2 → safentic-1.0.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: safentic
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.4
|
4
4
|
Summary: Safentic SDK for behavior analysis
|
5
5
|
Home-page: https://safentic.com
|
6
6
|
Author: Safentic
|
@@ -11,7 +11,7 @@ Classifier: License :: Other/Proprietary License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
12
12
|
Description-Content-Type: text/markdown
|
13
13
|
Requires-Dist: requests
|
14
|
-
Requires-Dist: PyYAML
|
14
|
+
Requires-Dist: PyYAML
|
15
15
|
Requires-Dist: sentence-transformers==3.2.1
|
16
16
|
Requires-Dist: sqlalchemy
|
17
17
|
Requires-Dist: python-dotenv
|
@@ -6,24 +6,30 @@ class SafenticError(Exception):
|
|
6
6
|
"""Raised when Safentic blocks an action."""
|
7
7
|
pass
|
8
8
|
|
9
|
+
class InvalidAPIKeyError(Exception):
|
10
|
+
"""Raised when an invalid API key is used."""
|
11
|
+
pass
|
9
12
|
|
10
|
-
class SafetyLayer
|
13
|
+
class SafetyLayer:
|
11
14
|
"""
|
12
15
|
Safentic runtime enforcement wrapper for agent actions.
|
13
|
-
|
14
|
-
Example:
|
15
|
-
safety.protect("send_email", {"body": "..."})
|
16
|
-
# Raises SafenticError if blocked
|
16
|
+
Requires a valid API key to function.
|
17
17
|
"""
|
18
18
|
|
19
|
-
def __init__(self, api_key: str, agent_id: str, enforcer: PolicyEnforcer = None, raise_on_block: bool = True):
|
19
|
+
def __init__(self, api_key: str = "", agent_id: str = "", enforcer: PolicyEnforcer = None, raise_on_block: bool = True):
|
20
|
+
if not api_key:
|
21
|
+
raise InvalidAPIKeyError("Missing API key")
|
22
|
+
|
23
|
+
validation_response = validate_api_key(api_key)
|
24
|
+
if not validation_response or validation_response.get("status") != "valid":
|
25
|
+
raise InvalidAPIKeyError("Invalid or unauthorized API key")
|
26
|
+
|
27
|
+
self.api_key = api_key
|
20
28
|
self.agent_id = agent_id
|
21
29
|
self.raise_on_block = raise_on_block
|
22
30
|
self.logger = AuditLogger()
|
23
31
|
|
24
|
-
# If no custom enforcer is provided, instantiate one with the API key
|
25
32
|
self.enforcer = enforcer or PolicyEnforcer()
|
26
|
-
self.api_key = validate_api_key(api_key)
|
27
33
|
self.enforcer.reset(agent_id)
|
28
34
|
|
29
35
|
def protect(self, tool_name: str, tool_args: dict) -> dict:
|
@@ -31,6 +37,7 @@ class SafetyLayer():
|
|
31
37
|
Checks whether a tool action is allowed.
|
32
38
|
Raises SafenticError if blocked (default), or returns result if raise_on_block=False.
|
33
39
|
"""
|
40
|
+
|
34
41
|
result = self.enforcer.enforce(self.agent_id, tool_name, tool_args)
|
35
42
|
|
36
43
|
# Log structured event
|
@@ -41,10 +48,9 @@ class SafetyLayer():
|
|
41
48
|
reason=result["reason"] if not result["allowed"] else None
|
42
49
|
)
|
43
50
|
|
44
|
-
# Raise or return based on outcome and config
|
45
51
|
if not result["allowed"]:
|
46
52
|
if self.raise_on_block:
|
47
53
|
raise SafenticError(result["reason"])
|
48
54
|
return result
|
49
55
|
|
50
|
-
return result
|
56
|
+
return result
|
@@ -0,0 +1,49 @@
|
|
1
|
+
tools:
|
2
|
+
send_email:
|
3
|
+
checks:
|
4
|
+
- type: deny_phrase
|
5
|
+
phrases:
|
6
|
+
- "one device per subscription"
|
7
|
+
- "24 hours"
|
8
|
+
- "apology"
|
9
|
+
- "apologize"
|
10
|
+
- "sorry"
|
11
|
+
- "refund"
|
12
|
+
- "refund delay"
|
13
|
+
- type: semantic
|
14
|
+
trigger_phrases:
|
15
|
+
- "refund policy"
|
16
|
+
- "guarantee"
|
17
|
+
- "our policy"
|
18
|
+
reference_file: "example_policy.txt"
|
19
|
+
|
20
|
+
issue_refund:
|
21
|
+
checks:
|
22
|
+
- type: deny_phrase
|
23
|
+
phrases:
|
24
|
+
- "refund"
|
25
|
+
- "refunding"
|
26
|
+
- "issue refund"
|
27
|
+
- "send refund"
|
28
|
+
- "credit customer"
|
29
|
+
- "reverse charge"
|
30
|
+
- "double charge"
|
31
|
+
- "processed refund"
|
32
|
+
- "grant compensation"
|
33
|
+
- "money back"
|
34
|
+
- type: semantic
|
35
|
+
trigger_phrases:
|
36
|
+
- "we've sent your refund"
|
37
|
+
- "your money is on the way"
|
38
|
+
reference_file: "refund_statement.txt"
|
39
|
+
|
40
|
+
update_ticket:
|
41
|
+
checks: [] # Explicitly allow all
|
42
|
+
|
43
|
+
log_to_crm:
|
44
|
+
checks: [] # Explicitly allow all
|
45
|
+
|
46
|
+
logging:
|
47
|
+
level: INFO
|
48
|
+
destination: "safentic/logs/txt_logs/safentic_audit.log"
|
49
|
+
jsonl: "safentic/logs/json_logs/safentic_audit.jsonl"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: safentic
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.4
|
4
4
|
Summary: Safentic SDK for behavior analysis
|
5
5
|
Home-page: https://safentic.com
|
6
6
|
Author: Safentic
|
@@ -11,7 +11,7 @@ Classifier: License :: Other/Proprietary License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
12
12
|
Description-Content-Type: text/markdown
|
13
13
|
Requires-Dist: requests
|
14
|
-
Requires-Dist: PyYAML
|
14
|
+
Requires-Dist: PyYAML
|
15
15
|
Requires-Dist: sentence-transformers==3.2.1
|
16
16
|
Requires-Dist: sqlalchemy
|
17
17
|
Requires-Dist: python-dotenv
|
@@ -2,11 +2,11 @@ from setuptools import setup, find_packages
|
|
2
2
|
|
3
3
|
setup(
|
4
4
|
name="safentic",
|
5
|
-
version="1.0.
|
5
|
+
version="1.0.4",
|
6
6
|
packages=find_packages(),
|
7
7
|
install_requires=[
|
8
8
|
"requests",
|
9
|
-
"PyYAML
|
9
|
+
"PyYAML",
|
10
10
|
"sentence-transformers==3.2.1",
|
11
11
|
"sqlalchemy",
|
12
12
|
"python-dotenv"
|
@@ -1,25 +0,0 @@
|
|
1
|
-
tools:
|
2
|
-
send_email:
|
3
|
-
checks:
|
4
|
-
- type: deny_phrase
|
5
|
-
phrases:
|
6
|
-
- "one device per subscription"
|
7
|
-
- "24 hours"
|
8
|
-
|
9
|
-
- type: semantic
|
10
|
-
trigger_phrases:
|
11
|
-
- "refund policy"
|
12
|
-
- "guarantee"
|
13
|
-
- "our policy"
|
14
|
-
reference_file: "example_policy.txt"
|
15
|
-
|
16
|
-
update_ticket:
|
17
|
-
checks: [] # Explicitly allow all — no policy checks
|
18
|
-
|
19
|
-
log_to_crm:
|
20
|
-
checks: [] # Explicitly allow all — no policy checks
|
21
|
-
|
22
|
-
logging:
|
23
|
-
level: INFO
|
24
|
-
destination: "safentic/logs/txt_logs/safentic_audit.log"
|
25
|
-
jsonl: "safentic/logs/json_logs/safentic_audit.jsonl"
|
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
|