argus-shield 0.1.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.
- argus_shield-0.1.0/.gitignore +179 -0
- argus_shield-0.1.0/DOCUMENTATION.md +278 -0
- argus_shield-0.1.0/PKG-INFO +101 -0
- argus_shield-0.1.0/README.md +91 -0
- argus_shield-0.1.0/pyproject.toml +27 -0
- argus_shield-0.1.0/src/argus/__init__.py +21 -0
- argus_shield-0.1.0/src/argus/client.py +133 -0
- argus_shield-0.1.0/src/argus/decorators.py +110 -0
- argus_shield-0.1.0/src/argus/exceptions.py +28 -0
- argus_shield-0.1.0/src/argus/integrations/autogen.py +16 -0
- argus_shield-0.1.0/src/argus/integrations/crewai.py +62 -0
- argus_shield-0.1.0/src/argus/integrations/langchain.py +101 -0
- argus_shield-0.1.0/src/argus/integrations/pydantic_ai.py +33 -0
- argus_shield-0.1.0/src/argus/local_engine.py +251 -0
- argus_shield-0.1.0/src/argus/session.py +150 -0
- argus_shield-0.1.0/src/argus_sdk/__init__.py +2 -0
- argus_shield-0.1.0/src/argus_sdk/py.typed +0 -0
- argus_shield-0.1.0/tests/test_client.py +127 -0
- argus_shield-0.1.0/tests/test_decorators.py +89 -0
- argus_shield-0.1.0/tests/test_integrations.py +225 -0
- argus_shield-0.1.0/tests/test_local_mode.py +57 -0
- argus_shield-0.1.0/tests/test_session.py +54 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# ========== Python ==========
|
|
2
|
+
|
|
3
|
+
# Byte-compiled / optimized / DLL files
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.py[cod]
|
|
6
|
+
*$py.class
|
|
7
|
+
|
|
8
|
+
# C extensions
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
build/
|
|
14
|
+
develop-eggs/
|
|
15
|
+
dist/
|
|
16
|
+
downloads/
|
|
17
|
+
eggs/
|
|
18
|
+
.eggs/
|
|
19
|
+
lib64/
|
|
20
|
+
parts/
|
|
21
|
+
sdist/
|
|
22
|
+
var/
|
|
23
|
+
wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# Virtual environments
|
|
30
|
+
venv/
|
|
31
|
+
ENV/
|
|
32
|
+
env/
|
|
33
|
+
.venv/
|
|
34
|
+
|
|
35
|
+
# PyInstaller
|
|
36
|
+
*.manifest
|
|
37
|
+
*.spec
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.coverage
|
|
43
|
+
.coverage.*
|
|
44
|
+
.cache
|
|
45
|
+
nosetests.xml
|
|
46
|
+
coverage.xml
|
|
47
|
+
*.cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
|
|
51
|
+
# Environments
|
|
52
|
+
.env
|
|
53
|
+
.env.local
|
|
54
|
+
.env.*.local
|
|
55
|
+
*.env
|
|
56
|
+
|
|
57
|
+
# IDEs
|
|
58
|
+
.vscode/
|
|
59
|
+
.idea/
|
|
60
|
+
*.swp
|
|
61
|
+
*.swo
|
|
62
|
+
*~
|
|
63
|
+
.DS_Store
|
|
64
|
+
|
|
65
|
+
# Logs
|
|
66
|
+
*.log
|
|
67
|
+
logs/
|
|
68
|
+
pip-log.txt
|
|
69
|
+
pip-delete-this-directory.txt
|
|
70
|
+
|
|
71
|
+
# Database
|
|
72
|
+
*.db
|
|
73
|
+
*.sqlite
|
|
74
|
+
*.sqlite3
|
|
75
|
+
|
|
76
|
+
# Jupyter Notebook
|
|
77
|
+
.ipynb_checkpoints
|
|
78
|
+
|
|
79
|
+
# pyenv
|
|
80
|
+
.python-version
|
|
81
|
+
|
|
82
|
+
# mypy
|
|
83
|
+
.mypy_cache/
|
|
84
|
+
.dmypy.json
|
|
85
|
+
dmypy.json
|
|
86
|
+
|
|
87
|
+
# Ruff
|
|
88
|
+
.ruff_cache/
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# ========== Node.js / React (argus-dashboard) ==========
|
|
92
|
+
|
|
93
|
+
# Dependencies
|
|
94
|
+
node_modules/
|
|
95
|
+
npm-debug.log*
|
|
96
|
+
yarn-debug.log*
|
|
97
|
+
yarn-error.log*
|
|
98
|
+
pnpm-debug.log*
|
|
99
|
+
lerna-debug.log*
|
|
100
|
+
|
|
101
|
+
# Build outputs
|
|
102
|
+
dist/
|
|
103
|
+
dist-ssr/
|
|
104
|
+
build/
|
|
105
|
+
*.tsbuildinfo
|
|
106
|
+
|
|
107
|
+
# Production
|
|
108
|
+
.parcel-cache/
|
|
109
|
+
.next/
|
|
110
|
+
out/
|
|
111
|
+
.nuxt/
|
|
112
|
+
.cache/
|
|
113
|
+
|
|
114
|
+
# Testing
|
|
115
|
+
coverage/
|
|
116
|
+
|
|
117
|
+
# Misc
|
|
118
|
+
.DS_Store
|
|
119
|
+
*.local
|
|
120
|
+
|
|
121
|
+
# Environment variables
|
|
122
|
+
.env.local
|
|
123
|
+
.env.development.local
|
|
124
|
+
.env.test.local
|
|
125
|
+
.env.production.local
|
|
126
|
+
|
|
127
|
+
# Vite
|
|
128
|
+
.vite/
|
|
129
|
+
vite.config.ts.timestamp-*
|
|
130
|
+
vite.config.ts.timestamp.*
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# ========== General / OS ==========
|
|
134
|
+
|
|
135
|
+
# OS
|
|
136
|
+
.DS_Store
|
|
137
|
+
Thumbs.db
|
|
138
|
+
ehthumbs.db
|
|
139
|
+
Desktop.ini
|
|
140
|
+
|
|
141
|
+
# Temporary files
|
|
142
|
+
*.tmp
|
|
143
|
+
*.temp
|
|
144
|
+
*.bak
|
|
145
|
+
*.swp
|
|
146
|
+
*~
|
|
147
|
+
|
|
148
|
+
# Archives
|
|
149
|
+
*.zip
|
|
150
|
+
*.tar.gz
|
|
151
|
+
*.rar
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
# ========== Project Specific ==========
|
|
155
|
+
|
|
156
|
+
# Backend
|
|
157
|
+
*.csv
|
|
158
|
+
*.json
|
|
159
|
+
!sample.json
|
|
160
|
+
!argus-dashboard/vercel.json
|
|
161
|
+
uploads/
|
|
162
|
+
temp/
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
# Sensitive files (should never be committed)
|
|
166
|
+
*.pem
|
|
167
|
+
*.key
|
|
168
|
+
|
|
169
|
+
# ========== Keep These =========
|
|
170
|
+
|
|
171
|
+
# Keep these files in git
|
|
172
|
+
!requirements.txt
|
|
173
|
+
!.env.example
|
|
174
|
+
|
|
175
|
+
lobster-trap
|
|
176
|
+
lobstertrap/.git/
|
|
177
|
+
|
|
178
|
+
test_agent.py
|
|
179
|
+
test_gemini.py
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# ARGUS Python SDK Developer Manual
|
|
2
|
+
|
|
3
|
+
Welcome to the official developer documentation for the **ARGUS Python SDK** (`argus-sdk`).
|
|
4
|
+
|
|
5
|
+
ARGUS (**Agent Runtime Guardrail & Unauthorized-action Stopper**) is a real-time, active security guardrail for AI agents. Rather than classifying prompts or relying on fragile system instructions, ARGUS secures the **runtime execution boundary** by intercepting dangerous tool calls *before* they run.
|
|
6
|
+
|
|
7
|
+
This guide covers everything you need to build secure, production-grade AI agents using the ARGUS ecosystem.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Table of Contents
|
|
12
|
+
1. [System Architecture](#system-architecture)
|
|
13
|
+
2. [Getting Started E2E](#getting-started-e2e)
|
|
14
|
+
3. [Core SDK Concepts](#core-sdk-concepts)
|
|
15
|
+
4. [Vanilla Python Decorators](#vanilla-python-decorators)
|
|
16
|
+
5. [Framework Integrations](#framework-integrations)
|
|
17
|
+
- [LangChain](#langchain)
|
|
18
|
+
- [PydanticAI](#pydanticai)
|
|
19
|
+
- [CrewAI / AutoGen](#crewai--autogen)
|
|
20
|
+
6. [Security Paradigms](#security-paradigms)
|
|
21
|
+
7. [API Reference](#api-reference)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## System Architecture
|
|
26
|
+
|
|
27
|
+
ARGUS operates as a **Security Gateway Pattern**:
|
|
28
|
+
|
|
29
|
+
```mermaid
|
|
30
|
+
sequenceDiagram
|
|
31
|
+
autonumber
|
|
32
|
+
participant App as Agent Application
|
|
33
|
+
participant SDK as ARGUS SDK (Client)
|
|
34
|
+
participant GW as ARGUS Gateway (Backend)
|
|
35
|
+
participant LLM as Model Provider (OpenAI/Gemini/Anthropic)
|
|
36
|
+
|
|
37
|
+
App->>SDK: Establish argus.Session(user_prompt)
|
|
38
|
+
SDK->>GW: POST /api/intent/extract (prompt)
|
|
39
|
+
GW->>LLM: Analyze intent & compile Intent Manifest
|
|
40
|
+
LLM-->>GW: Return Manifest (Permissions Slip)
|
|
41
|
+
GW-->>SDK: Return Session ID + Manifest
|
|
42
|
+
|
|
43
|
+
Note over App, SDK: Agent loop begins execution...
|
|
44
|
+
|
|
45
|
+
App->>SDK: Invoke @argus.protect tool (params)
|
|
46
|
+
SDK->>GW: POST /api/evaluate (action, target, params)
|
|
47
|
+
Note over GW: Lobster Trap engine checks policy
|
|
48
|
+
|
|
49
|
+
alt Action Authorized
|
|
50
|
+
GW-->>SDK: ALLOW
|
|
51
|
+
SDK-->>App: Permit execution of raw Python code
|
|
52
|
+
else Action Violates Intent
|
|
53
|
+
GW-->>SDK: QUARANTINE / DENY
|
|
54
|
+
Note over GW: Layer 3 generates explanation
|
|
55
|
+
SDK-->>App: Raise ArgusQuarantineException (Block!)
|
|
56
|
+
end
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The **Gateway** manages heavy safety logic, model orchestrations, and telemetry. The **SDK** is a lightweight, zero-dependency client that developer-protects local execution blocks.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Getting Started E2E
|
|
64
|
+
|
|
65
|
+
Follow these steps to secure your first AI agent.
|
|
66
|
+
|
|
67
|
+
### 1. Start the ARGUS Security Gateway
|
|
68
|
+
Clone the central ARGUS repository and spin up the gateway server on your machine or private cloud.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Clone and setup
|
|
72
|
+
git clone https://github.com/tanishra/argus.git
|
|
73
|
+
cd argus
|
|
74
|
+
cp .env.example .env
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Configure your gateway `.env` with your preferred LLM provider. ARGUS is completely model-agnostic thanks to LiteLLM:
|
|
78
|
+
|
|
79
|
+
```ini
|
|
80
|
+
# --- LLM API Keys ---
|
|
81
|
+
OPENAI_API_KEY=sk-proj-xxxxxx...
|
|
82
|
+
# GEMINI_API_KEY=AIzaSy...
|
|
83
|
+
|
|
84
|
+
# --- Model Selection (LiteLLM Format) ---
|
|
85
|
+
ARGUS_LLM_MODEL=openai/gpt-4o-mini
|
|
86
|
+
ARGUS_PRO_MODEL=openai/gpt-4o
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Start the gateway:
|
|
90
|
+
```bash
|
|
91
|
+
uv run uvicorn src.main:app --port 8000 --reload
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 2. Install the SDK in Your Project
|
|
95
|
+
In your separate AI agent codebase, install the lightweight client:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pip install argus-sdk
|
|
99
|
+
# or using uv
|
|
100
|
+
uv add argus-sdk
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Configure your environment to point to your self-hosted Gateway:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
export ARGUS_BASE_URL="http://localhost:8000"
|
|
107
|
+
export ARGUS_API_KEY="your-gateway-secret-key"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Core SDK Concepts
|
|
113
|
+
|
|
114
|
+
ARGUS relies on two simple steps to enforce bulletproof guardrails:
|
|
115
|
+
|
|
116
|
+
1. **The Session Context**: Wraps the agent's lifetime. It translates what the user *asked* into an immutable "Permission Slip" (Intent Manifest) stored securely in Redis.
|
|
117
|
+
2. **The Interceptor (Decorator/Wrapper)**: Wraps the agent's *tools*. When the agent tries to call a tool, it grabs the active Session, sends the parameters to the Gateway, and blocks execution if it violates the manifest.
|
|
118
|
+
|
|
119
|
+
> [!IMPORTANT]
|
|
120
|
+
> **Failsafe Design:** If an agent attempts to execute a protected tool *without* an active `argus.Session` context, ARGUS fails closed by throwing an `ArgusException`. This prevents developers from accidentally running dangerous tools unprotected.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Vanilla Python Decorators
|
|
125
|
+
|
|
126
|
+
For custom tools you write yourself, use the `@argus.protect` decorator. This is completely framework-agnostic and intercepts function execution in plain Python.
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
import argus
|
|
130
|
+
from argus import ArgusQuarantineException
|
|
131
|
+
|
|
132
|
+
@argus.protect(action_type="delete_record", target_arg="record_id", target_type="database")
|
|
133
|
+
def delete_database_record(record_id: str, table: str):
|
|
134
|
+
# This core code will NOT run unless ARGUS approves it first
|
|
135
|
+
db.query(f"DELETE FROM {table} WHERE id = {record_id}")
|
|
136
|
+
return True
|
|
137
|
+
|
|
138
|
+
# Running the agent safely
|
|
139
|
+
user_prompt = "Delete records associated with user session #12"
|
|
140
|
+
|
|
141
|
+
with argus.Session(user_prompt=user_prompt):
|
|
142
|
+
try:
|
|
143
|
+
# ✅ ALLOWED: record_id aligns with user intent
|
|
144
|
+
delete_database_record(record_id="12", table="users")
|
|
145
|
+
|
|
146
|
+
# ❌ BLOCKED: Agent goes rogue and tries to wipe the admin config!
|
|
147
|
+
# Raises ArgusQuarantineException instantly
|
|
148
|
+
delete_database_record(record_id="admin_config", table="system_settings")
|
|
149
|
+
|
|
150
|
+
except ArgusQuarantineException as e:
|
|
151
|
+
print(f"🛑 Security Boundary Violated: {e.explanation}")
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Framework Integrations
|
|
157
|
+
|
|
158
|
+
### LangChain
|
|
159
|
+
LangChain uses structured `BaseTool` objects. Since you import many pre-built tools directly from LangChain's ecosystem, you cannot add decorators directly to their source code. Use our native `wrap_langchain_tool` helper:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
from langchain_community.tools import ShellTool
|
|
163
|
+
from argus.integrations.langchain import wrap_langchain_tool
|
|
164
|
+
import argus
|
|
165
|
+
|
|
166
|
+
# 1. Instantiate the tool
|
|
167
|
+
raw_shell_tool = ShellTool()
|
|
168
|
+
|
|
169
|
+
# 2. Wrap it with ARGUS
|
|
170
|
+
protected_shell = wrap_langchain_tool(
|
|
171
|
+
tool=raw_shell_tool,
|
|
172
|
+
action_type="execute_code",
|
|
173
|
+
target_type="shell"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# 3. Use it in LangChain agents normally!
|
|
177
|
+
with argus.Session("List files in the current directory"):
|
|
178
|
+
# This will succeed
|
|
179
|
+
protected_shell.run({"commands": ["ls -la"]})
|
|
180
|
+
|
|
181
|
+
# This will raise ArgusQuarantineException and block
|
|
182
|
+
protected_shell.run({"commands": ["rm -rf /"]})
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### PydanticAI
|
|
188
|
+
PydanticAI agent tools are standard python functions decorated with `@agent.tool`. Stack the `@argus.protect` decorator underneath the tool registration to secure it:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from pydantic_ai import Agent
|
|
192
|
+
import argus
|
|
193
|
+
|
|
194
|
+
agent = Agent('openai:gpt-4o')
|
|
195
|
+
|
|
196
|
+
@argus.protect(action_type="read_file", target_arg="filepath", target_type="file")
|
|
197
|
+
@agent.tool
|
|
198
|
+
def read_system_file(ctx, filepath: str) -> str:
|
|
199
|
+
with open(filepath, 'r') as f:
|
|
200
|
+
return f.read()
|
|
201
|
+
|
|
202
|
+
# Execute securely
|
|
203
|
+
with argus.Session("Read my diary.txt"):
|
|
204
|
+
agent.run_sync("Read my diary.txt") # Succeeds or Fails depending on prompt
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### CrewAI / AutoGen
|
|
210
|
+
CrewAI agents use class-based tools. We can easily wrap standard CrewAI tools by wrapping their `_run` methods or decorating their initialization:
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from crewai.tools import BaseTool
|
|
214
|
+
import argus
|
|
215
|
+
|
|
216
|
+
class CustomWriteTool(BaseTool):
|
|
217
|
+
name: str = "Write File"
|
|
218
|
+
description: str = "Writes a file to disk."
|
|
219
|
+
|
|
220
|
+
def _run(self, filename: str, content: str) -> str:
|
|
221
|
+
with open(filename, 'w') as f:
|
|
222
|
+
f.write(content)
|
|
223
|
+
return "Success"
|
|
224
|
+
|
|
225
|
+
# Secure the tool class at runtime
|
|
226
|
+
protected_tool = CustomWriteTool()
|
|
227
|
+
# Dynamically monkeypatch or wrap the execution
|
|
228
|
+
protected_tool._run = argus.protect(action_type="write_file", target_arg="filename")(protected_tool._run)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Security Paradigms
|
|
234
|
+
|
|
235
|
+
ARGUS utilizes a **Multi-Layer Defense Matrix**:
|
|
236
|
+
|
|
237
|
+
| Layer | Component | Defense Type | Execution Speed |
|
|
238
|
+
| :--- | :--- | :--- | :--- |
|
|
239
|
+
| **Layer 1** | Intent Extraction | Pre-Action Intent Mapping | Sub-300ms |
|
|
240
|
+
| **Layer 2** | Lobster Trap | Local Semantic Policies | Sub-10ms |
|
|
241
|
+
| **Layer 3** | Explanation Engine | Deep Post-Flag Reasoning | Async Background |
|
|
242
|
+
| **Layer 4** | Human Gate | Manual Action Quarantine | Human Speed |
|
|
243
|
+
|
|
244
|
+
### The Quarantine Lifecycle
|
|
245
|
+
When an action is flagged by **Layer 2 (Lobster Trap)**:
|
|
246
|
+
1. The tool execution is **immediately blocked** in Python (an exception is raised).
|
|
247
|
+
2. The blocked action payload is saved to the Gateway database as `QUARANTINE`.
|
|
248
|
+
3. The explanation engine runs in the background to provide a detailed, plain-text security report explaining *why* it was blocked.
|
|
249
|
+
4. The action appears in the **ARGUS Dashboard Review Queue**, where security administrators can manually audit the prompt, inspect the parameters, and decide to `APPROVE` or `DENY` future runs.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## API Reference
|
|
254
|
+
|
|
255
|
+
### `argus.Session`
|
|
256
|
+
Context manager for establishing a security boundary.
|
|
257
|
+
```python
|
|
258
|
+
with argus.Session(user_prompt: str, user_id: Optional[str] = None):
|
|
259
|
+
# Agent operations here
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### `@argus.protect`
|
|
263
|
+
Function decorator to intercept execution.
|
|
264
|
+
```python
|
|
265
|
+
@argus.protect(
|
|
266
|
+
action_type: str,
|
|
267
|
+
target_arg: Optional[str] = None,
|
|
268
|
+
target_type: str = "api"
|
|
269
|
+
)
|
|
270
|
+
```
|
|
271
|
+
* `action_type`: The category of action (e.g., `send_email`, `write_file`).
|
|
272
|
+
* `target_arg`: The name of the function parameter containing the target resource (e.g., `filepath`).
|
|
273
|
+
* `target_type`: The resource type (e.g., `file`, `email`, `database`).
|
|
274
|
+
|
|
275
|
+
### `ArgusQuarantineException`
|
|
276
|
+
Exception thrown when an action is blocked.
|
|
277
|
+
* `explanation`: Plain-text justification of why the action violated user intent.
|
|
278
|
+
* `raw_response`: Direct JSON response dictionary from the ARGUS Gateway.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: argus-shield
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ARGUS Python SDK - Framework-agnostic AI agent guardrails and safety tool
|
|
5
|
+
Author-email: Tanish Rajput <tanishrajput9@gmail.com>
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Requires-Dist: httpx>=0.28.1
|
|
8
|
+
Requires-Dist: pydantic>=2.13.4
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# ARGUS Python SDK
|
|
12
|
+
|
|
13
|
+
The official Python SDK for [ARGUS](https://github.com/tanishra/argus) — the Agent Runtime Guardrail & Unauthorized-action Stopper.
|
|
14
|
+
|
|
15
|
+
Securing what AI agents **do** — not just what they hear.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
You can install the SDK via pip:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install argus-sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or using `uv`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
uv add argus-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### 1. Set your Environment Variables
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
export ARGUS_API_KEY="your-api-key"
|
|
37
|
+
export ARGUS_BASE_URL="http://localhost:8000"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Protect Your Tools
|
|
41
|
+
|
|
42
|
+
Wrap your critical agent tools with the `@argus.protect` decorator.
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import argus
|
|
46
|
+
|
|
47
|
+
@argus.protect(action_type="send_email", target_type="email")
|
|
48
|
+
def send_email(to_address: str, subject: str, body: str):
|
|
49
|
+
# This function will ONLY execute if ARGUS approves the action
|
|
50
|
+
print(f"Sending email to {to_address}...")
|
|
51
|
+
return True
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 3. Run the Agent within a Session
|
|
55
|
+
|
|
56
|
+
When a user submits a prompt, wrap the execution in an `argus.Session`. This automatically extracts the user's intent and establishes a temporary authorization boundary.
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
import argus
|
|
60
|
+
from argus import ArgusQuarantineException
|
|
61
|
+
|
|
62
|
+
prompt = "Send the Q3 report to alice@example.com"
|
|
63
|
+
|
|
64
|
+
# 1. Extract Intent and start session
|
|
65
|
+
with argus.Session(user_prompt=prompt):
|
|
66
|
+
try:
|
|
67
|
+
# Agent decides to execute the tool
|
|
68
|
+
send_email(to_address="alice@example.com", subject="Q3 Report", body="Attached.")
|
|
69
|
+
print("Success!")
|
|
70
|
+
|
|
71
|
+
# If the agent goes rogue and tries to email someone else:
|
|
72
|
+
send_email(to_address="eve@example.com", subject="Q3 Report", body="Attached.")
|
|
73
|
+
|
|
74
|
+
except ArgusQuarantineException as e:
|
|
75
|
+
print(f"Agent was stopped! Reason: {e.explanation}")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Integrations
|
|
79
|
+
|
|
80
|
+
### LangChain
|
|
81
|
+
|
|
82
|
+
ARGUS provides native wrappers for LangChain tools.
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from argus.integrations.langchain import wrap_langchain_tool
|
|
86
|
+
from langchain_core.tools import tool
|
|
87
|
+
|
|
88
|
+
@tool
|
|
89
|
+
def read_patient_record(patient_id: str) -> str:
|
|
90
|
+
"""Reads a patient record."""
|
|
91
|
+
return "Patient Data"
|
|
92
|
+
|
|
93
|
+
# Wrap the tool
|
|
94
|
+
protected_tool = wrap_langchain_tool(
|
|
95
|
+
tool=read_patient_record,
|
|
96
|
+
action_type="read_patient_record",
|
|
97
|
+
target_type="patient_record"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Use it within an argus.Session normally!
|
|
101
|
+
```
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# ARGUS Python SDK
|
|
2
|
+
|
|
3
|
+
The official Python SDK for [ARGUS](https://github.com/tanishra/argus) — the Agent Runtime Guardrail & Unauthorized-action Stopper.
|
|
4
|
+
|
|
5
|
+
Securing what AI agents **do** — not just what they hear.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
You can install the SDK via pip:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install argus-sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or using `uv`:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
uv add argus-sdk
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Set your Environment Variables
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
export ARGUS_API_KEY="your-api-key"
|
|
27
|
+
export ARGUS_BASE_URL="http://localhost:8000"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. Protect Your Tools
|
|
31
|
+
|
|
32
|
+
Wrap your critical agent tools with the `@argus.protect` decorator.
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import argus
|
|
36
|
+
|
|
37
|
+
@argus.protect(action_type="send_email", target_type="email")
|
|
38
|
+
def send_email(to_address: str, subject: str, body: str):
|
|
39
|
+
# This function will ONLY execute if ARGUS approves the action
|
|
40
|
+
print(f"Sending email to {to_address}...")
|
|
41
|
+
return True
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 3. Run the Agent within a Session
|
|
45
|
+
|
|
46
|
+
When a user submits a prompt, wrap the execution in an `argus.Session`. This automatically extracts the user's intent and establishes a temporary authorization boundary.
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import argus
|
|
50
|
+
from argus import ArgusQuarantineException
|
|
51
|
+
|
|
52
|
+
prompt = "Send the Q3 report to alice@example.com"
|
|
53
|
+
|
|
54
|
+
# 1. Extract Intent and start session
|
|
55
|
+
with argus.Session(user_prompt=prompt):
|
|
56
|
+
try:
|
|
57
|
+
# Agent decides to execute the tool
|
|
58
|
+
send_email(to_address="alice@example.com", subject="Q3 Report", body="Attached.")
|
|
59
|
+
print("Success!")
|
|
60
|
+
|
|
61
|
+
# If the agent goes rogue and tries to email someone else:
|
|
62
|
+
send_email(to_address="eve@example.com", subject="Q3 Report", body="Attached.")
|
|
63
|
+
|
|
64
|
+
except ArgusQuarantineException as e:
|
|
65
|
+
print(f"Agent was stopped! Reason: {e.explanation}")
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Integrations
|
|
69
|
+
|
|
70
|
+
### LangChain
|
|
71
|
+
|
|
72
|
+
ARGUS provides native wrappers for LangChain tools.
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from argus.integrations.langchain import wrap_langchain_tool
|
|
76
|
+
from langchain_core.tools import tool
|
|
77
|
+
|
|
78
|
+
@tool
|
|
79
|
+
def read_patient_record(patient_id: str) -> str:
|
|
80
|
+
"""Reads a patient record."""
|
|
81
|
+
return "Patient Data"
|
|
82
|
+
|
|
83
|
+
# Wrap the tool
|
|
84
|
+
protected_tool = wrap_langchain_tool(
|
|
85
|
+
tool=read_patient_record,
|
|
86
|
+
action_type="read_patient_record",
|
|
87
|
+
target_type="patient_record"
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Use it within an argus.Session normally!
|
|
91
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "argus-shield"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "ARGUS Python SDK - Framework-agnostic AI agent guardrails and safety tool"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Tanish Rajput", email = "tanishrajput9@gmail.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"httpx>=0.28.1",
|
|
12
|
+
"pydantic>=2.13.4",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[build-system]
|
|
16
|
+
requires = ["hatchling"]
|
|
17
|
+
build-backend = "hatchling.build"
|
|
18
|
+
|
|
19
|
+
[tool.hatch.build.targets.wheel]
|
|
20
|
+
packages = ["src/argus"]
|
|
21
|
+
|
|
22
|
+
[dependency-groups]
|
|
23
|
+
dev = [
|
|
24
|
+
"pytest>=9.0.3",
|
|
25
|
+
"pytest-asyncio>=1.3.0",
|
|
26
|
+
]
|
|
27
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ARGUS Python SDK
|
|
3
|
+
Securing what AI agents do, not just what they hear.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .client import ArgusClient, AsyncArgusClient
|
|
7
|
+
from .decorators import protect
|
|
8
|
+
from .exceptions import ArgusException, ArgusQuarantineException, ArgusAPIError
|
|
9
|
+
from .session import Session, AsyncSession, get_current_session
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"ArgusClient",
|
|
13
|
+
"AsyncArgusClient",
|
|
14
|
+
"protect",
|
|
15
|
+
"ArgusException",
|
|
16
|
+
"ArgusQuarantineException",
|
|
17
|
+
"ArgusAPIError",
|
|
18
|
+
"Session",
|
|
19
|
+
"AsyncSession",
|
|
20
|
+
"get_current_session",
|
|
21
|
+
]
|