eternity-agentshield 2.0.0__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.
@@ -0,0 +1,183 @@
1
+ Metadata-Version: 2.4
2
+ Name: eternity-agentshield
3
+ Version: 2.0.0
4
+ Summary: ETERNITY : AgentShield 2.0 — Enterprise Security Middleware & Guardrails SDK for Autonomous AI Agents
5
+ Home-page: https://github.com/yashnishad-0923/agentshield
6
+ Author: ETERNITY Security Team
7
+ Author-email: ETERNITY Security Team <security@agentshield.ai>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/agentshield/agentshield
10
+ Project-URL: Documentation, https://docs.agentshield.ai
11
+ Project-URL: Repository, https://github.com/agentshield/agentshield
12
+ Keywords: ai-agent,security,guardrails,langchain,crewai,autogen,openai,prompt-injection,cybersecurity,llm-firewall
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Information Technology
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Security
25
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+ Provides-Extra: langchain
29
+ Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
30
+ Provides-Extra: crewai
31
+ Requires-Dist: crewai>=0.1.0; extra == "crewai"
32
+ Provides-Extra: openai
33
+ Requires-Dist: openai>=1.0.0; extra == "openai"
34
+ Provides-Extra: all
35
+ Requires-Dist: langchain-core>=0.1.0; extra == "all"
36
+ Requires-Dist: crewai>=0.1.0; extra == "all"
37
+ Requires-Dist: openai>=1.0.0; extra == "all"
38
+ Dynamic: author
39
+ Dynamic: home-page
40
+ Dynamic: requires-python
41
+
42
+ # 🛡️ AgentShield Python Developer SDK (`agentshield`)
43
+ ### Enterprise Security Middleware & Guardrails for Autonomous AI Agents
44
+
45
+ [![PyPI version](https://img.shields.io/badge/pypi-v2.0.0-blue.svg)](https://pypi.org/project/agentshield/)
46
+ [![Python](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
47
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
48
+
49
+ **AgentShield** is an inline action-authorization firewall for autonomous AI agents (LangChain, CrewAI, AutoGen, OpenAI Assistants). It evaluates planned tool calls across **6 analytical detection layers in under 6 milliseconds**, blocks prompt injection, prevents zero-day shell wipeouts, redacts confidential credentials in-flight, and manages human-in-the-loop approvals.
50
+
51
+ ---
52
+
53
+ ## 📦 Installation
54
+
55
+ ```bash
56
+ pip install eternity-agentshield
57
+ ```
58
+
59
+ *In your Python code, import as:*
60
+ ```python
61
+ from agentshield import agentshield_protect, SecurityBlockedException
62
+ ```
63
+
64
+ Or install locally in development mode:
65
+ ```bash
66
+ pip install -e ./sdk
67
+ ```
68
+
69
+ ---
70
+
71
+ ## ⚡ 30-Second Quickstart
72
+
73
+ ### 1. Protect Any Python Function with a 1-Line Decorator
74
+ ```python
75
+ from agentshield import agentshield_protect, SecurityBlockedException
76
+
77
+ # Wrap any function that an AI agent has permission to execute
78
+ @agentshield_protect(agent_id="research_agent")
79
+ def read_project_report(file: str):
80
+ with open(file, "r") as f:
81
+ return f.read()
82
+
83
+ # Malicious or unauthorized calls raise SecurityBlockedException
84
+ try:
85
+ read_project_report(file="/etc/shadow")
86
+ except SecurityBlockedException as e:
87
+ print(f"Action Blocked: {e.primary_driver} (Risk Score: {e.risk_score}/100)")
88
+ print(f"Remediation: {e.recommendation}")
89
+ ```
90
+
91
+ ---
92
+
93
+ ## 🤖 Framework Integrations
94
+
95
+ ### 1. LangChain & LangGraph
96
+ ```python
97
+ from langchain.tools import tool
98
+ from agentshield import LangChainTool
99
+
100
+ shield = LangChainTool(agent_id="support_agent")
101
+
102
+ @tool
103
+ def query_database(sql: str) -> str:
104
+ """Executes a SQL query under AgentShield inspection."""
105
+ return shield.execute("database_query", {"query": sql})
106
+ ```
107
+
108
+ ### 2. CrewAI
109
+ ```python
110
+ from crewai.tools import BaseTool
111
+ from agentshield import CrewAITool
112
+
113
+ class SecureEmailTool(BaseTool):
114
+ name: str = "send_email"
115
+ description: str = "Dispatches customer emails with AgentShield inspection."
116
+ shield: CrewAITool = CrewAITool(agent_id="support_agent")
117
+
118
+ def _run(self, to: str, body: str) -> str:
119
+ return self.shield.run_protected("send_email", {"to": to, "body": body})
120
+ ```
121
+
122
+ ### 3. OpenAI Function Calling & Assistants API
123
+ ```python
124
+ from openai import OpenAI
125
+ from agentshield import AgentShieldOpenAIInterceptor
126
+
127
+ client = OpenAI()
128
+ interceptor = AgentShieldOpenAIInterceptor(agent_id="customer_copilot")
129
+
130
+ response = client.chat.completions.create(
131
+ model="gpt-4o",
132
+ messages=[{"role": "user", "content": "Dump the users table"}],
133
+ tools=tools
134
+ )
135
+
136
+ # Intercept before execution
137
+ tool_outputs = interceptor.process_tool_calls(
138
+ response.choices[0].message.tool_calls,
139
+ user_context="Dump the users table"
140
+ )
141
+ ```
142
+
143
+ ---
144
+
145
+ ## ⚙️ Configuration
146
+
147
+ Set the environment variable or configure programmatically:
148
+
149
+ ```bash
150
+ export AGENTSHIELD_API="http://localhost:8000"
151
+ export AGENTSHIELD_API_KEY="ag_live_your_api_key_here"
152
+ ```
153
+
154
+ Or in Python:
155
+ ```python
156
+ import agentshield
157
+
158
+ agentshield.configure(
159
+ base_url="https://api.agentshield.your-company.com",
160
+ api_key="your-api-key"
161
+ )
162
+ ```
163
+
164
+ ---
165
+
166
+ ## 🖥️ Command Line Interface (CLI)
167
+
168
+ Verify your gateway connection right from the terminal:
169
+ ```bash
170
+ # Check connection
171
+ agentshield status
172
+
173
+ # List pending approvals in the human-in-the-loop queue
174
+ agentshield approvals
175
+
176
+ # Test a tool call
177
+ agentshield test --agent research_agent --tool read_file --args '{"file": "test.txt"}'
178
+ ```
179
+
180
+ ---
181
+
182
+ ## 📄 License
183
+ MIT License.
@@ -0,0 +1,142 @@
1
+ # 🛡️ AgentShield Python Developer SDK (`agentshield`)
2
+ ### Enterprise Security Middleware & Guardrails for Autonomous AI Agents
3
+
4
+ [![PyPI version](https://img.shields.io/badge/pypi-v2.0.0-blue.svg)](https://pypi.org/project/agentshield/)
5
+ [![Python](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
6
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
7
+
8
+ **AgentShield** is an inline action-authorization firewall for autonomous AI agents (LangChain, CrewAI, AutoGen, OpenAI Assistants). It evaluates planned tool calls across **6 analytical detection layers in under 6 milliseconds**, blocks prompt injection, prevents zero-day shell wipeouts, redacts confidential credentials in-flight, and manages human-in-the-loop approvals.
9
+
10
+ ---
11
+
12
+ ## 📦 Installation
13
+
14
+ ```bash
15
+ pip install eternity-agentshield
16
+ ```
17
+
18
+ *In your Python code, import as:*
19
+ ```python
20
+ from agentshield import agentshield_protect, SecurityBlockedException
21
+ ```
22
+
23
+ Or install locally in development mode:
24
+ ```bash
25
+ pip install -e ./sdk
26
+ ```
27
+
28
+ ---
29
+
30
+ ## ⚡ 30-Second Quickstart
31
+
32
+ ### 1. Protect Any Python Function with a 1-Line Decorator
33
+ ```python
34
+ from agentshield import agentshield_protect, SecurityBlockedException
35
+
36
+ # Wrap any function that an AI agent has permission to execute
37
+ @agentshield_protect(agent_id="research_agent")
38
+ def read_project_report(file: str):
39
+ with open(file, "r") as f:
40
+ return f.read()
41
+
42
+ # Malicious or unauthorized calls raise SecurityBlockedException
43
+ try:
44
+ read_project_report(file="/etc/shadow")
45
+ except SecurityBlockedException as e:
46
+ print(f"Action Blocked: {e.primary_driver} (Risk Score: {e.risk_score}/100)")
47
+ print(f"Remediation: {e.recommendation}")
48
+ ```
49
+
50
+ ---
51
+
52
+ ## 🤖 Framework Integrations
53
+
54
+ ### 1. LangChain & LangGraph
55
+ ```python
56
+ from langchain.tools import tool
57
+ from agentshield import LangChainTool
58
+
59
+ shield = LangChainTool(agent_id="support_agent")
60
+
61
+ @tool
62
+ def query_database(sql: str) -> str:
63
+ """Executes a SQL query under AgentShield inspection."""
64
+ return shield.execute("database_query", {"query": sql})
65
+ ```
66
+
67
+ ### 2. CrewAI
68
+ ```python
69
+ from crewai.tools import BaseTool
70
+ from agentshield import CrewAITool
71
+
72
+ class SecureEmailTool(BaseTool):
73
+ name: str = "send_email"
74
+ description: str = "Dispatches customer emails with AgentShield inspection."
75
+ shield: CrewAITool = CrewAITool(agent_id="support_agent")
76
+
77
+ def _run(self, to: str, body: str) -> str:
78
+ return self.shield.run_protected("send_email", {"to": to, "body": body})
79
+ ```
80
+
81
+ ### 3. OpenAI Function Calling & Assistants API
82
+ ```python
83
+ from openai import OpenAI
84
+ from agentshield import AgentShieldOpenAIInterceptor
85
+
86
+ client = OpenAI()
87
+ interceptor = AgentShieldOpenAIInterceptor(agent_id="customer_copilot")
88
+
89
+ response = client.chat.completions.create(
90
+ model="gpt-4o",
91
+ messages=[{"role": "user", "content": "Dump the users table"}],
92
+ tools=tools
93
+ )
94
+
95
+ # Intercept before execution
96
+ tool_outputs = interceptor.process_tool_calls(
97
+ response.choices[0].message.tool_calls,
98
+ user_context="Dump the users table"
99
+ )
100
+ ```
101
+
102
+ ---
103
+
104
+ ## ⚙️ Configuration
105
+
106
+ Set the environment variable or configure programmatically:
107
+
108
+ ```bash
109
+ export AGENTSHIELD_API="http://localhost:8000"
110
+ export AGENTSHIELD_API_KEY="ag_live_your_api_key_here"
111
+ ```
112
+
113
+ Or in Python:
114
+ ```python
115
+ import agentshield
116
+
117
+ agentshield.configure(
118
+ base_url="https://api.agentshield.your-company.com",
119
+ api_key="your-api-key"
120
+ )
121
+ ```
122
+
123
+ ---
124
+
125
+ ## 🖥️ Command Line Interface (CLI)
126
+
127
+ Verify your gateway connection right from the terminal:
128
+ ```bash
129
+ # Check connection
130
+ agentshield status
131
+
132
+ # List pending approvals in the human-in-the-loop queue
133
+ agentshield approvals
134
+
135
+ # Test a tool call
136
+ agentshield test --agent research_agent --tool read_file --args '{"file": "test.txt"}'
137
+ ```
138
+
139
+ ---
140
+
141
+ ## 📄 License
142
+ MIT License.
@@ -0,0 +1,37 @@
1
+ """
2
+ ================================================================================
3
+ 🛡️ ETERNITY : AGENTSHIELD 2.0 — ENTERPRISE PYTHON SDK
4
+ ================================================================================
5
+ Inline action-authorization firewall for autonomous AI agents.
6
+ Protects LangChain, CrewAI, AutoGen, and OpenAI function calling with sub-6ms latency.
7
+ ================================================================================
8
+ """
9
+
10
+ from .client import AgentShield, AgentShieldClient, get_default_client, configure
11
+ from .decorators import protect, agentshield_protect
12
+ from .exceptions import (
13
+ AgentShieldException,
14
+ SecurityBlockedException,
15
+ ApprovalPendingException,
16
+ ConnectionException,
17
+ )
18
+ from .integrations.langchain import AgentShieldTool as LangChainTool
19
+ from .integrations.crewai import AgentShieldCrewTool as CrewAITool
20
+ from .integrations.openai_interceptor import AgentShieldOpenAIInterceptor
21
+
22
+ __version__ = "2.0.0"
23
+ __all__ = [
24
+ "AgentShield",
25
+ "AgentShieldClient",
26
+ "get_default_client",
27
+ "configure",
28
+ "protect",
29
+ "agentshield_protect",
30
+ "SecurityBlockedException",
31
+ "ApprovalPendingException",
32
+ "AgentShieldException",
33
+ "ConnectionException",
34
+ "LangChainTool",
35
+ "CrewAITool",
36
+ "AgentShieldOpenAIInterceptor",
37
+ ]
@@ -0,0 +1,80 @@
1
+ """
2
+ AgentShield Command Line Interface (CLI).
3
+ """
4
+
5
+ import argparse
6
+ import json
7
+ import sys
8
+
9
+ if sys.platform == "win32":
10
+ try:
11
+ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
12
+ sys.stderr.reconfigure(encoding='utf-8', errors='replace')
13
+ except Exception:
14
+ pass
15
+
16
+ if __package__:
17
+ from .client import get_default_client
18
+ else:
19
+ try:
20
+ from agentshield.client import get_default_client
21
+ except ImportError:
22
+ from client import get_default_client
23
+
24
+ def main():
25
+ parser = argparse.ArgumentParser(description="ETERNITY : AgentShield 2.0 CLI")
26
+ subparsers = parser.add_subparsers(dest="command", help="Available commands")
27
+
28
+ # Command: status
29
+ subparsers.add_parser("status", help="Check AgentShield Gateway connection health")
30
+
31
+ # Command: approvals
32
+ appr_parser = subparsers.add_parser("approvals", help="Inspect pending approvals")
33
+ appr_parser.add_argument("--resolve", type=int, help="Resolve approval by analysis ID")
34
+ appr_parser.add_argument("--action", choices=["APPROVE", "REJECT"], default="APPROVE", help="Action to perform")
35
+
36
+ # Command: test
37
+ test_parser = subparsers.add_parser("test", help="Test intercepting a tool call")
38
+ test_parser.add_argument("--agent", default="research_agent", help="Agent identifier")
39
+ test_parser.add_argument("--tool", default="read_file", help="Target tool name")
40
+ test_parser.add_argument("--args", default="{\"file\": \"test.txt\"}", help="JSON tool arguments")
41
+
42
+ args = parser.parse_args()
43
+
44
+ client = get_default_client()
45
+
46
+ if args.command == "status":
47
+ try:
48
+ health = client.check_health()
49
+ print(f"✅ Connected to AgentShield Gateway at {client.base_url}")
50
+ print(f" Status: {health.get('status')}")
51
+ except Exception as e:
52
+ print(f"❌ Connection failed: {e}")
53
+ sys.exit(1)
54
+
55
+ elif args.command == "approvals":
56
+ if args.resolve:
57
+ res = client.resolve_approval(args.resolve, action=args.action)
58
+ print(f"Resolved Approval #{args.resolve}: {res}")
59
+ else:
60
+ pending = client.get_pending_approvals()
61
+ print(f"📋 Active Pending Approvals ({len(pending)}):")
62
+ for p in pending:
63
+ print(f" • #{p.get('id')} [{p.get('agent_identifier')}] -> Tool: {p.get('tool_name')} (Risk: {p.get('risk_score')})")
64
+
65
+ elif args.command == "test":
66
+ try:
67
+ parsed_args = json.loads(args.args)
68
+ except Exception:
69
+ parsed_args = {"raw": args.args}
70
+ res = client.intercept(args.agent, args.tool, parsed_args)
71
+ print(f"🛡️ Evaluation Result:")
72
+ print(f" Decision: {res.get('decision')}")
73
+ print(f" Risk Score: {res.get('risk_score')} / 100")
74
+ print(f" Driver: {(res.get('explanation') or {}).get('primary_driver')}")
75
+
76
+ else:
77
+ parser.print_help()
78
+
79
+ if __name__ == "__main__":
80
+ main()
@@ -0,0 +1,168 @@
1
+ """
2
+ Core AgentShield HTTP Client.
3
+ Handles request interception, cryptographic verification, and approval lifecycle.
4
+ """
5
+
6
+ import json
7
+ import os
8
+ import time
9
+ import urllib.error
10
+ import urllib.request
11
+ from typing import Any, Dict, List, Optional
12
+ from .exceptions import ConnectionException
13
+
14
+ class AgentShieldClient:
15
+ """
16
+ Client for the ETERNITY : AgentShield 2.0 Security Gateway.
17
+ """
18
+
19
+ def __init__(
20
+ self,
21
+ base_url: Optional[str] = None,
22
+ api_key: Optional[str] = None,
23
+ timeout: float = 10.0
24
+ ):
25
+ self.base_url = (
26
+ base_url
27
+ or os.environ.get("AGENTSHIELD_API")
28
+ or "http://localhost:8000"
29
+ ).rstrip("/")
30
+ self.api_key = api_key or os.environ.get("AGENTSHIELD_API_KEY")
31
+ self.timeout = timeout
32
+
33
+ def _headers(self) -> Dict[str, str]:
34
+ headers = {
35
+ "Content-Type": "application/json",
36
+ "User-Agent": "AgentShield-Python-SDK/2.0.0"
37
+ }
38
+ if self.api_key:
39
+ headers["Authorization"] = f"Bearer {self.api_key}"
40
+ return headers
41
+
42
+ def check_health(self) -> Dict[str, Any]:
43
+ """Verifies connection to the AgentShield Gateway."""
44
+ req = urllib.request.Request(f"{self.base_url}/health", headers=self._headers())
45
+ try:
46
+ with urllib.request.urlopen(req, timeout=self.timeout) as resp:
47
+ return json.loads(resp.read().decode("utf-8"))
48
+ except Exception as e:
49
+ raise ConnectionException(f"Cannot reach AgentShield at {self.base_url}: {e}")
50
+
51
+ def intercept(
52
+ self,
53
+ agent_id: str,
54
+ tool_name: str,
55
+ tool_args: Dict[str, Any],
56
+ context: Any = ""
57
+ ) -> Dict[str, Any]:
58
+ """
59
+ Intercepts and evaluates an autonomous agent's tool execution attempt.
60
+
61
+ Returns:
62
+ Dict containing:
63
+ - decision: 'ALLOWED' | 'BLOCKED' | 'PENDING'
64
+ - risk_score: float (0.0 to 100.0)
65
+ - risk_level: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
66
+ - execution_result: Sandboxed execution data (if ALLOWED)
67
+ - explanation: Explainable AI breakdown
68
+ - redacted_input: In-flight sanitized payload
69
+ - analysis_id: Unique audit trace identifier
70
+ """
71
+ payload = {
72
+ "agent_id": agent_id,
73
+ "tool_name": tool_name,
74
+ "tool_args": tool_args,
75
+ "context": context if isinstance(context, str) else json.dumps(context)
76
+ }
77
+
78
+ req = urllib.request.Request(
79
+ f"{self.base_url}/agent/request",
80
+ data=json.dumps(payload).encode("utf-8"),
81
+ headers=self._headers()
82
+ )
83
+
84
+ try:
85
+ with urllib.request.urlopen(req, timeout=self.timeout) as resp:
86
+ return json.loads(resp.read().decode("utf-8"))
87
+ except urllib.error.HTTPError as e:
88
+ try:
89
+ body = json.loads(e.read().decode("utf-8"))
90
+ except Exception:
91
+ body = {"detail": str(e)}
92
+ return {
93
+ "status": "error",
94
+ "decision": "BLOCKED",
95
+ "risk_score": 100.0,
96
+ "risk_level": "CRITICAL",
97
+ "explanation": {
98
+ "primary_driver": "GATEWAY_HTTP_ERROR",
99
+ "reasons": [str(body.get("detail", body))]
100
+ }
101
+ }
102
+ except Exception as e:
103
+ raise ConnectionException(f"Failed to connect to AgentShield: {e}")
104
+
105
+ def get_pending_approvals(self) -> List[Dict[str, Any]]:
106
+ """Retrieves list of active human-in-the-loop pending requests."""
107
+ req = urllib.request.Request(f"{self.base_url}/approvals/pending", headers=self._headers())
108
+ with urllib.request.urlopen(req, timeout=self.timeout) as resp:
109
+ return json.loads(resp.read().decode("utf-8"))
110
+
111
+ def resolve_approval(
112
+ self,
113
+ analysis_id: int,
114
+ action: str = "APPROVE",
115
+ reason: str = "Approved by operator"
116
+ ) -> Dict[str, Any]:
117
+ """Programmatically approves or rejects a pending request."""
118
+ payload = {"action": action.upper(), "reason": reason}
119
+ req = urllib.request.Request(
120
+ f"{self.base_url}/approvals/{analysis_id}/resolve",
121
+ data=json.dumps(payload).encode("utf-8"),
122
+ headers=self._headers()
123
+ )
124
+ with urllib.request.urlopen(req, timeout=self.timeout) as resp:
125
+ return json.loads(resp.read().decode("utf-8"))
126
+
127
+ def wait_for_approval(
128
+ self,
129
+ analysis_id: int,
130
+ timeout_seconds: int = 180,
131
+ poll_interval: float = 2.0
132
+ ) -> Dict[str, Any]:
133
+ """
134
+ Polls the gateway until a human operator authorizes or rejects the pending action.
135
+ """
136
+ start = time.time()
137
+ while time.time() - start < timeout_seconds:
138
+ req = urllib.request.Request(f"{self.base_url}/dashboard/logs/{analysis_id}", headers=self._headers())
139
+ try:
140
+ with urllib.request.urlopen(req, timeout=self.timeout) as resp:
141
+ log = json.loads(resp.read().decode("utf-8"))
142
+ decision = log.get("decision")
143
+ if decision in ["APPROVED", "ALLOWED"]:
144
+ return {"approved": True, "execution_result": log.get("execution_result")}
145
+ elif decision in ["REJECTED", "BLOCKED", "EXPIRED"]:
146
+ return {"approved": False, "reason": f"Decision resolved as {decision}"}
147
+ except Exception:
148
+ pass
149
+ time.sleep(poll_interval)
150
+ return {"approved": False, "reason": f"Approval timed out after {timeout_seconds} seconds"}
151
+
152
+ # Global singleton client
153
+ _default_client: Optional[AgentShieldClient] = None
154
+
155
+ def get_default_client() -> AgentShieldClient:
156
+ global _default_client
157
+ if _default_client is None:
158
+ _default_client = AgentShieldClient()
159
+ return _default_client
160
+
161
+ def configure(base_url: Optional[str] = None, api_key: Optional[str] = None):
162
+ """Configures the default AgentShield SDK client."""
163
+ global _default_client
164
+ _default_client = AgentShieldClient(base_url=base_url, api_key=api_key)
165
+ return _default_client
166
+
167
+ # Alias
168
+ AgentShield = AgentShieldClient
@@ -0,0 +1,102 @@
1
+ """
2
+ Python Decorators for protecting tools and functions.
3
+ """
4
+
5
+ import functools
6
+ import inspect
7
+ from typing import Callable, Optional
8
+ from .client import get_default_client, AgentShieldClient
9
+ from .exceptions import SecurityBlockedException, ApprovalPendingException
10
+
11
+ def protect(
12
+ agent_id: str,
13
+ tool_name: Optional[str] = None,
14
+ on_blocked: str = "raise", # "raise" | "return_error"
15
+ client: Optional[AgentShieldClient] = None
16
+ ):
17
+ """
18
+ Python Function Decorator: Automatically intercepts execution with AgentShield.
19
+
20
+ Args:
21
+ agent_id: Identifier of the autonomous agent executing the tool (e.g. 'support_agent')
22
+ tool_name: Optional tool name override (defaults to function name)
23
+ on_blocked: 'raise' (raises SecurityBlockedException) or 'return_error' (returns dict for LLM)
24
+ client: Optional custom AgentShieldClient instance
25
+
26
+ Example:
27
+ @protect(agent_id="research_agent")
28
+ def read_file(filepath: str):
29
+ ...
30
+ """
31
+ def decorator(func: Callable):
32
+ t_name = tool_name or func.__name__
33
+ cli = client or get_default_client()
34
+
35
+ @functools.wraps(func)
36
+ def wrapper(*args, **kwargs):
37
+ # 1. Bind arguments into structured dictionary
38
+ sig = inspect.signature(func)
39
+ bound = sig.bind_partial(*args, **kwargs)
40
+ bound.apply_defaults()
41
+ tool_args = bound.arguments.copy()
42
+
43
+ # Pop special internal context if passed
44
+ context = kwargs.pop("__context__", f"Function '{t_name}' invoked by agent '{agent_id}'.")
45
+
46
+ # 2. Intercept with AgentShield Security Gateway
47
+ evaluation = cli.intercept(
48
+ agent_id=agent_id,
49
+ tool_name=t_name,
50
+ tool_args=tool_args,
51
+ context=context
52
+ )
53
+
54
+ decision = evaluation.get("decision")
55
+ score = evaluation.get("risk_score", 0.0)
56
+ level = evaluation.get("risk_level", "LOW")
57
+ explanation = evaluation.get("explanation") or {}
58
+
59
+ # 3. Handle Decision
60
+ if decision == "ALLOWED":
61
+ # If AgentShield already executed in sandbox, return that; else run local func
62
+ if evaluation.get("execution_result") is not None:
63
+ return evaluation["execution_result"]
64
+ return func(*args, **kwargs)
65
+
66
+ elif decision == "PENDING":
67
+ analysis_id = evaluation.get("analysis_id", 0)
68
+ if on_blocked == "raise":
69
+ raise ApprovalPendingException(
70
+ message=f"Action held for human operator review in Approval Queue (Analysis #{analysis_id}).",
71
+ analysis_id=analysis_id,
72
+ risk_score=score
73
+ )
74
+ return {
75
+ "status": "pending_human_approval",
76
+ "analysis_id": analysis_id,
77
+ "message": "Action held for human operator review in AgentShield Approval Queue."
78
+ }
79
+
80
+ else:
81
+ # BLOCKED
82
+ driver = explanation.get("primary_driver", "POLICY_VIOLATION")
83
+ if on_blocked == "raise":
84
+ raise SecurityBlockedException(
85
+ message=f"[AgentShield Firewall] Tool '{t_name}' blocked. Reason: {driver}",
86
+ risk_score=score,
87
+ risk_level=level,
88
+ explanation=explanation,
89
+ analysis_id=evaluation.get("analysis_id")
90
+ )
91
+ return {
92
+ "error": "EXECUTION_DENIED_BY_SECURITY_POLICY",
93
+ "driver": driver,
94
+ "risk_score": score,
95
+ "recommendation": explanation.get("recommendation", "Action denied by least-privilege security policy.")
96
+ }
97
+
98
+ return wrapper
99
+ return decorator
100
+
101
+ # Alias
102
+ agentshield_protect = protect
@@ -0,0 +1,62 @@
1
+ """
2
+ AgentShield SDK Custom Exceptions.
3
+ """
4
+
5
+ from typing import Dict, Any, Optional
6
+
7
+ class AgentShieldException(Exception):
8
+ """Base exception for all AgentShield errors."""
9
+ pass
10
+
11
+ class ConnectionException(AgentShieldException):
12
+ """Raised when the SDK cannot reach the AgentShield Gateway server."""
13
+ pass
14
+
15
+ class SecurityBlockedException(AgentShieldException):
16
+ """
17
+ Raised when an autonomous agent action is BLOCKED by AgentShield firewall.
18
+ Contains granular explainability telemetry, risk score, and primary driver.
19
+ """
20
+ def __init__(
21
+ self,
22
+ message: str,
23
+ risk_score: float,
24
+ risk_level: str,
25
+ explanation: Optional[Dict[str, Any]] = None,
26
+ analysis_id: Optional[int] = None
27
+ ):
28
+ super().__init__(message)
29
+ self.risk_score = risk_score
30
+ self.risk_level = risk_level
31
+ self.explanation = explanation or {}
32
+ self.analysis_id = analysis_id
33
+
34
+ @property
35
+ def primary_driver(self) -> str:
36
+ return self.explanation.get("primary_driver", "SECURITY_POLICY_VIOLATION")
37
+
38
+ @property
39
+ def recommendation(self) -> str:
40
+ return self.explanation.get("recommendation", "Review agent permission policies.")
41
+
42
+ @property
43
+ def reasons(self) -> list:
44
+ return self.explanation.get("reasons", [])
45
+
46
+ def to_llm_response(self) -> Dict[str, Any]:
47
+ """Formats safe feedback to return directly into the LLM conversation context."""
48
+ return {
49
+ "error": "EXECUTION_DENIED_BY_SECURITY_POLICY",
50
+ "driver": self.primary_driver,
51
+ "message": f"Action blocked: {self.args[0]}",
52
+ "risk_score": self.risk_score
53
+ }
54
+
55
+ class ApprovalPendingException(AgentShieldException):
56
+ """
57
+ Raised when an action requires human review and is held in the Approval Queue.
58
+ """
59
+ def __init__(self, message: str, analysis_id: int, risk_score: float):
60
+ super().__init__(message)
61
+ self.analysis_id = analysis_id
62
+ self.risk_score = risk_score
@@ -0,0 +1,13 @@
1
+ """
2
+ AgentShield Integrations for external AI agent frameworks.
3
+ """
4
+
5
+ from .langchain import AgentShieldTool
6
+ from .crewai import AgentShieldCrewTool
7
+ from .openai_interceptor import AgentShieldOpenAIInterceptor
8
+
9
+ __all__ = [
10
+ "AgentShieldTool",
11
+ "AgentShieldCrewTool",
12
+ "AgentShieldOpenAIInterceptor"
13
+ ]
@@ -0,0 +1,42 @@
1
+ """
2
+ CrewAI BaseTool Adapter for AgentShield.
3
+ """
4
+
5
+ from typing import Any, Dict, Optional
6
+ from ..client import get_default_client, AgentShieldClient
7
+
8
+ class AgentShieldCrewTool:
9
+ """
10
+ CrewAI Tool Interceptor.
11
+ Can be used inside any CrewAI BaseTool._run() method.
12
+ """
13
+
14
+ def __init__(
15
+ self,
16
+ agent_id: str,
17
+ client: Optional[AgentShieldClient] = None
18
+ ):
19
+ self.agent_id = agent_id
20
+ self.client = client or get_default_client()
21
+
22
+ def run_protected(
23
+ self,
24
+ tool_name: str,
25
+ tool_args: Dict[str, Any],
26
+ context: str = ""
27
+ ) -> str:
28
+ res = self.client.intercept(
29
+ agent_id=self.agent_id,
30
+ tool_name=tool_name,
31
+ tool_args=tool_args,
32
+ context=context
33
+ )
34
+
35
+ decision = res.get("decision")
36
+ if decision == "ALLOWED":
37
+ return str(res.get("execution_result"))
38
+ elif decision == "PENDING":
39
+ return f"HELD FOR HUMAN REVIEW: Approval ID #{res.get('analysis_id')}"
40
+ else:
41
+ driver = (res.get("explanation") or {}).get("primary_driver", "SECURITY_POLICY_VIOLATION")
42
+ return f"BLOCKED BY AGENTSHIELD FIREWALL: {driver}"
@@ -0,0 +1,69 @@
1
+ """
2
+ LangChain & LangGraph Tool Adapter for AgentShield.
3
+ """
4
+
5
+ from typing import Any, Dict, Optional
6
+ from ..client import get_default_client, AgentShieldClient
7
+
8
+ class AgentShieldTool:
9
+ """
10
+ Drop-in tool adapter to secure any LangChain or LangGraph agent tool call.
11
+
12
+ Usage:
13
+ shield = AgentShieldTool(agent_id="support_agent")
14
+
15
+ # In your LangChain tool function:
16
+ @tool
17
+ def query_database(query: str) -> str:
18
+ return shield.execute("database_query", {"query": query})
19
+ """
20
+
21
+ def __init__(
22
+ self,
23
+ agent_id: str,
24
+ client: Optional[AgentShieldClient] = None,
25
+ return_direct_error: bool = True
26
+ ):
27
+ self.agent_id = agent_id
28
+ self.client = client or get_default_client()
29
+ self.return_direct_error = return_direct_error
30
+
31
+ def execute(
32
+ self,
33
+ tool_name: str,
34
+ tool_args: Dict[str, Any],
35
+ context: str = ""
36
+ ) -> Any:
37
+ """
38
+ Intercepts tool call, evaluates security rules, and returns sanitized result.
39
+ """
40
+ eval_result = self.client.intercept(
41
+ agent_id=self.agent_id,
42
+ tool_name=tool_name,
43
+ tool_args=tool_args,
44
+ context=context
45
+ )
46
+
47
+ decision = eval_result.get("decision")
48
+
49
+ if decision == "ALLOWED":
50
+ return eval_result.get("execution_result", {"status": "success", "executed": True})
51
+
52
+ elif decision == "PENDING":
53
+ analysis_id = eval_result.get("analysis_id")
54
+ return (
55
+ f"Action Paused: This sensitive operation (Risk Score: {eval_result.get('risk_score')}) "
56
+ f"requires human supervisor approval (Approval ID: #{analysis_id})."
57
+ )
58
+
59
+ else:
60
+ # BLOCKED
61
+ driver = (eval_result.get("explanation") or {}).get("primary_driver", "POLICY_VIOLATION")
62
+ reasons = (eval_result.get("explanation") or {}).get("reasons", [])
63
+ reason_str = "; ".join(reasons) if reasons else "Violated security least-privilege boundary"
64
+
65
+ if not self.return_direct_error:
66
+ raise RuntimeError(f"AgentShield Blocked [{driver}]: {reason_str}")
67
+
68
+ # Return graceful error string so the LLM continues safely
69
+ return f"Security Policy Refusal: Cannot execute '{tool_name}' ({driver}: {reason_str})."
@@ -0,0 +1,76 @@
1
+ """
2
+ OpenAI Function Calling & Assistants API Interceptor.
3
+ """
4
+
5
+ import json
6
+ from typing import Any, Dict, List, Optional
7
+ from ..client import get_default_client, AgentShieldClient
8
+
9
+ class AgentShieldOpenAIInterceptor:
10
+ """
11
+ Inspects tool_calls generated by OpenAI Chat Completions (GPT-4o, etc.)
12
+ before any actual local execution occurs.
13
+ """
14
+
15
+ def __init__(
16
+ self,
17
+ agent_id: str,
18
+ client: Optional[AgentShieldClient] = None
19
+ ):
20
+ self.agent_id = agent_id
21
+ self.client = client or get_default_client()
22
+
23
+ def process_tool_calls(
24
+ self,
25
+ tool_calls: List[Any],
26
+ user_context: str = ""
27
+ ) -> List[Dict[str, Any]]:
28
+ """
29
+ Takes raw tool_calls from OpenAI response, evaluates each through AgentShield,
30
+ and returns formatted tool_outputs ready to submit back to OpenAI.
31
+ """
32
+ tool_outputs = []
33
+
34
+ for call in tool_calls:
35
+ call_id = getattr(call, "id", None) or call.get("id")
36
+ func = getattr(call, "function", None) or call.get("function", {})
37
+ func_name = getattr(func, "name", None) or func.get("name")
38
+ raw_args = getattr(func, "arguments", None) or func.get("arguments", "{}")
39
+
40
+ try:
41
+ args = json.loads(raw_args) if isinstance(raw_args, str) else raw_args
42
+ except Exception:
43
+ args = {"raw_args": raw_args}
44
+
45
+ # Intercept with AgentShield
46
+ eval_result = self.client.intercept(
47
+ agent_id=self.agent_id,
48
+ tool_name=func_name,
49
+ tool_args=args,
50
+ context=user_context
51
+ )
52
+
53
+ decision = eval_result.get("decision")
54
+
55
+ if decision == "ALLOWED":
56
+ output = json.dumps(eval_result.get("execution_result", {"status": "success"}))
57
+ elif decision == "PENDING":
58
+ output = json.dumps({
59
+ "status": "pending_human_approval",
60
+ "analysis_id": eval_result.get("analysis_id"),
61
+ "message": "Action held for human operator review in AgentShield Approval Queue."
62
+ })
63
+ else:
64
+ driver = (eval_result.get("explanation") or {}).get("primary_driver", "POLICY_VIOLATION")
65
+ output = json.dumps({
66
+ "error": "SECURITY_POLICY_VIOLATION",
67
+ "driver": driver,
68
+ "risk_score": eval_result.get("risk_score")
69
+ })
70
+
71
+ tool_outputs.append({
72
+ "tool_call_id": call_id,
73
+ "output": output
74
+ })
75
+
76
+ return tool_outputs
@@ -0,0 +1,183 @@
1
+ Metadata-Version: 2.4
2
+ Name: eternity-agentshield
3
+ Version: 2.0.0
4
+ Summary: ETERNITY : AgentShield 2.0 — Enterprise Security Middleware & Guardrails SDK for Autonomous AI Agents
5
+ Home-page: https://github.com/yashnishad-0923/agentshield
6
+ Author: ETERNITY Security Team
7
+ Author-email: ETERNITY Security Team <security@agentshield.ai>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/agentshield/agentshield
10
+ Project-URL: Documentation, https://docs.agentshield.ai
11
+ Project-URL: Repository, https://github.com/agentshield/agentshield
12
+ Keywords: ai-agent,security,guardrails,langchain,crewai,autogen,openai,prompt-injection,cybersecurity,llm-firewall
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Information Technology
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Security
25
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+ Provides-Extra: langchain
29
+ Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
30
+ Provides-Extra: crewai
31
+ Requires-Dist: crewai>=0.1.0; extra == "crewai"
32
+ Provides-Extra: openai
33
+ Requires-Dist: openai>=1.0.0; extra == "openai"
34
+ Provides-Extra: all
35
+ Requires-Dist: langchain-core>=0.1.0; extra == "all"
36
+ Requires-Dist: crewai>=0.1.0; extra == "all"
37
+ Requires-Dist: openai>=1.0.0; extra == "all"
38
+ Dynamic: author
39
+ Dynamic: home-page
40
+ Dynamic: requires-python
41
+
42
+ # 🛡️ AgentShield Python Developer SDK (`agentshield`)
43
+ ### Enterprise Security Middleware & Guardrails for Autonomous AI Agents
44
+
45
+ [![PyPI version](https://img.shields.io/badge/pypi-v2.0.0-blue.svg)](https://pypi.org/project/agentshield/)
46
+ [![Python](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
47
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
48
+
49
+ **AgentShield** is an inline action-authorization firewall for autonomous AI agents (LangChain, CrewAI, AutoGen, OpenAI Assistants). It evaluates planned tool calls across **6 analytical detection layers in under 6 milliseconds**, blocks prompt injection, prevents zero-day shell wipeouts, redacts confidential credentials in-flight, and manages human-in-the-loop approvals.
50
+
51
+ ---
52
+
53
+ ## 📦 Installation
54
+
55
+ ```bash
56
+ pip install eternity-agentshield
57
+ ```
58
+
59
+ *In your Python code, import as:*
60
+ ```python
61
+ from agentshield import agentshield_protect, SecurityBlockedException
62
+ ```
63
+
64
+ Or install locally in development mode:
65
+ ```bash
66
+ pip install -e ./sdk
67
+ ```
68
+
69
+ ---
70
+
71
+ ## ⚡ 30-Second Quickstart
72
+
73
+ ### 1. Protect Any Python Function with a 1-Line Decorator
74
+ ```python
75
+ from agentshield import agentshield_protect, SecurityBlockedException
76
+
77
+ # Wrap any function that an AI agent has permission to execute
78
+ @agentshield_protect(agent_id="research_agent")
79
+ def read_project_report(file: str):
80
+ with open(file, "r") as f:
81
+ return f.read()
82
+
83
+ # Malicious or unauthorized calls raise SecurityBlockedException
84
+ try:
85
+ read_project_report(file="/etc/shadow")
86
+ except SecurityBlockedException as e:
87
+ print(f"Action Blocked: {e.primary_driver} (Risk Score: {e.risk_score}/100)")
88
+ print(f"Remediation: {e.recommendation}")
89
+ ```
90
+
91
+ ---
92
+
93
+ ## 🤖 Framework Integrations
94
+
95
+ ### 1. LangChain & LangGraph
96
+ ```python
97
+ from langchain.tools import tool
98
+ from agentshield import LangChainTool
99
+
100
+ shield = LangChainTool(agent_id="support_agent")
101
+
102
+ @tool
103
+ def query_database(sql: str) -> str:
104
+ """Executes a SQL query under AgentShield inspection."""
105
+ return shield.execute("database_query", {"query": sql})
106
+ ```
107
+
108
+ ### 2. CrewAI
109
+ ```python
110
+ from crewai.tools import BaseTool
111
+ from agentshield import CrewAITool
112
+
113
+ class SecureEmailTool(BaseTool):
114
+ name: str = "send_email"
115
+ description: str = "Dispatches customer emails with AgentShield inspection."
116
+ shield: CrewAITool = CrewAITool(agent_id="support_agent")
117
+
118
+ def _run(self, to: str, body: str) -> str:
119
+ return self.shield.run_protected("send_email", {"to": to, "body": body})
120
+ ```
121
+
122
+ ### 3. OpenAI Function Calling & Assistants API
123
+ ```python
124
+ from openai import OpenAI
125
+ from agentshield import AgentShieldOpenAIInterceptor
126
+
127
+ client = OpenAI()
128
+ interceptor = AgentShieldOpenAIInterceptor(agent_id="customer_copilot")
129
+
130
+ response = client.chat.completions.create(
131
+ model="gpt-4o",
132
+ messages=[{"role": "user", "content": "Dump the users table"}],
133
+ tools=tools
134
+ )
135
+
136
+ # Intercept before execution
137
+ tool_outputs = interceptor.process_tool_calls(
138
+ response.choices[0].message.tool_calls,
139
+ user_context="Dump the users table"
140
+ )
141
+ ```
142
+
143
+ ---
144
+
145
+ ## ⚙️ Configuration
146
+
147
+ Set the environment variable or configure programmatically:
148
+
149
+ ```bash
150
+ export AGENTSHIELD_API="http://localhost:8000"
151
+ export AGENTSHIELD_API_KEY="ag_live_your_api_key_here"
152
+ ```
153
+
154
+ Or in Python:
155
+ ```python
156
+ import agentshield
157
+
158
+ agentshield.configure(
159
+ base_url="https://api.agentshield.your-company.com",
160
+ api_key="your-api-key"
161
+ )
162
+ ```
163
+
164
+ ---
165
+
166
+ ## 🖥️ Command Line Interface (CLI)
167
+
168
+ Verify your gateway connection right from the terminal:
169
+ ```bash
170
+ # Check connection
171
+ agentshield status
172
+
173
+ # List pending approvals in the human-in-the-loop queue
174
+ agentshield approvals
175
+
176
+ # Test a tool call
177
+ agentshield test --agent research_agent --tool read_file --args '{"file": "test.txt"}'
178
+ ```
179
+
180
+ ---
181
+
182
+ ## 📄 License
183
+ MIT License.
@@ -0,0 +1,18 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ agentshield/__init__.py
5
+ agentshield/cli.py
6
+ agentshield/client.py
7
+ agentshield/decorators.py
8
+ agentshield/exceptions.py
9
+ agentshield/integrations/__init__.py
10
+ agentshield/integrations/crewai.py
11
+ agentshield/integrations/langchain.py
12
+ agentshield/integrations/openai_interceptor.py
13
+ eternity_agentshield.egg-info/PKG-INFO
14
+ eternity_agentshield.egg-info/SOURCES.txt
15
+ eternity_agentshield.egg-info/dependency_links.txt
16
+ eternity_agentshield.egg-info/entry_points.txt
17
+ eternity_agentshield.egg-info/requires.txt
18
+ eternity_agentshield.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ agentshield = agentshield.cli:main
@@ -0,0 +1,14 @@
1
+
2
+ [all]
3
+ langchain-core>=0.1.0
4
+ crewai>=0.1.0
5
+ openai>=1.0.0
6
+
7
+ [crewai]
8
+ crewai>=0.1.0
9
+
10
+ [langchain]
11
+ langchain-core>=0.1.0
12
+
13
+ [openai]
14
+ openai>=1.0.0
@@ -0,0 +1,60 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "eternity-agentshield"
7
+ version = "2.0.0"
8
+ description = "ETERNITY : AgentShield 2.0 — Enterprise Security Middleware & Guardrails SDK for Autonomous AI Agents"
9
+ readme = "README.md"
10
+ authors = [
11
+ { name = "ETERNITY Security Team", email = "security@agentshield.ai" }
12
+ ]
13
+ license = { text = "MIT" }
14
+ requires-python = ">=3.8"
15
+ keywords = [
16
+ "ai-agent",
17
+ "security",
18
+ "guardrails",
19
+ "langchain",
20
+ "crewai",
21
+ "autogen",
22
+ "openai",
23
+ "prompt-injection",
24
+ "cybersecurity",
25
+ "llm-firewall"
26
+ ]
27
+ classifiers = [
28
+ "Development Status :: 5 - Production/Stable",
29
+ "Intended Audience :: Developers",
30
+ "Intended Audience :: Information Technology",
31
+ "License :: OSI Approved :: MIT License",
32
+ "Programming Language :: Python :: 3",
33
+ "Programming Language :: Python :: 3.8",
34
+ "Programming Language :: Python :: 3.9",
35
+ "Programming Language :: Python :: 3.10",
36
+ "Programming Language :: Python :: 3.11",
37
+ "Programming Language :: Python :: 3.12",
38
+ "Programming Language :: Python :: 3.13",
39
+ "Topic :: Security",
40
+ "Topic :: Scientific/Engineering :: Artificial Intelligence"
41
+ ]
42
+ dependencies = []
43
+
44
+ [project.optional-dependencies]
45
+ langchain = ["langchain-core>=0.1.0"]
46
+ crewai = ["crewai>=0.1.0"]
47
+ openai = ["openai>=1.0.0"]
48
+ all = [
49
+ "langchain-core>=0.1.0",
50
+ "crewai>=0.1.0",
51
+ "openai>=1.0.0"
52
+ ]
53
+
54
+ [project.scripts]
55
+ agentshield = "agentshield.cli:main"
56
+
57
+ [project.urls]
58
+ Homepage = "https://github.com/agentshield/agentshield"
59
+ Documentation = "https://docs.agentshield.ai"
60
+ Repository = "https://github.com/agentshield/agentshield"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env python
2
+ from setuptools import setup, find_packages
3
+ import os
4
+
5
+ readme_path = os.path.join(os.path.dirname(__file__), "README.md")
6
+ long_description = ""
7
+ if os.path.exists(readme_path):
8
+ with open(readme_path, encoding="utf-8") as f:
9
+ long_description = f.read()
10
+
11
+ setup(
12
+ name="eternity-agentshield",
13
+ version="2.0.0",
14
+ description="ETERNITY : AgentShield 2.0 — Enterprise Security Middleware & Guardrails SDK for Autonomous AI Agents",
15
+ long_description=long_description,
16
+ long_description_content_type="text/markdown",
17
+ author="ETERNITY Security Team",
18
+ author_email="security@agentshield.ai",
19
+ url="https://github.com/yashnishad-0923/agentshield",
20
+ project_urls={
21
+ "Documentation": "https://github.com/yashnishad-0923/agentshield#readme",
22
+ "Source": "https://github.com/yashnishad-0923/agentshield",
23
+ "Tracker": "https://github.com/yashnishad-0923/agentshield/issues",
24
+ },
25
+ license="MIT",
26
+ classifiers=[
27
+ "Development Status :: 5 - Production/Stable",
28
+ "Intended Audience :: Developers",
29
+ "License :: OSI Approved :: MIT License",
30
+ "Programming Language :: Python :: 3",
31
+ "Programming Language :: Python :: 3.8",
32
+ "Programming Language :: Python :: 3.9",
33
+ "Programming Language :: Python :: 3.10",
34
+ "Programming Language :: Python :: 3.11",
35
+ "Programming Language :: Python :: 3.12",
36
+ "Topic :: Security",
37
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
38
+ ],
39
+ packages=find_packages(),
40
+ python_requires=">=3.8",
41
+ install_requires=[],
42
+ entry_points={
43
+ "console_scripts": [
44
+ "agentshield=agentshield.cli:main",
45
+ ],
46
+ },
47
+ )