Metadata-Version: 2.4
Name: agentsecure-sdk
Version: 0.1.0
Summary: AgentSecure SDK — LLM DLP proxy for Python
Project-URL: Homepage, https://agentsecure.io
Project-URL: Repository, https://github.com/utpalkh/agentsecure
Project-URL: Bug Tracker, https://github.com/utpalkh/agentsecure/issues
License: MIT
Keywords: ai,anthropic,dlp,llm,openai,proxy,security
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Provides-Extra: all
Requires-Dist: anthropic>=0.20.0; extra == 'all'
Requires-Dist: langchain-anthropic>=0.1.0; extra == 'all'
Requires-Dist: langchain-openai>=0.1.0; extra == 'all'
Requires-Dist: llama-index-llms-anthropic>=0.1.0; extra == 'all'
Requires-Dist: llama-index-llms-openai>=0.1.0; extra == 'all'
Requires-Dist: openai>=1.0.0; extra == 'all'
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.20.0; extra == 'anthropic'
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Provides-Extra: langchain
Requires-Dist: langchain-anthropic>=0.1.0; extra == 'langchain'
Requires-Dist: langchain-openai>=0.1.0; extra == 'langchain'
Provides-Extra: llamaindex
Requires-Dist: llama-index-llms-anthropic>=0.1.0; extra == 'llamaindex'
Requires-Dist: llama-index-llms-openai>=0.1.0; extra == 'llamaindex'
Provides-Extra: openai
Requires-Dist: openai>=1.0.0; extra == 'openai'
Description-Content-Type: text/markdown

# agentsecure

Python SDK for [AgentSecure](https://agentsecure.io) — drop-in LLM DLP proxy.

Every prompt routed through AgentSecure is scanned for PII before it reaches the model. SSNs, credit cards, and medical records are blocked. Emails, phone numbers, and names are redacted. Everything is logged in your audit trail.

---

## Installation

```bash
# OpenAI only
pip install agentsecure-sdk[openai]

# Anthropic only
pip install agentsecure-sdk[anthropic]

# LangChain
pip install agentsecure-sdk[langchain]

# LlamaIndex
pip install agentsecure-sdk[llamaindex]

# Everything
pip install agentsecure-sdk[all]
```

---

## Quick Start

Get your API key from the [AgentSecure dashboard](https://agentsecure.vercel.app) → API Keys.

```bash
export AGENTSECURE_KEY=as_xxxxxxxxxxxx
```

### OpenAI

```python
import agentsecure

client = agentsecure.openai(api_key="sk-...")
# Pass agentsecure_key= directly, or set AGENTSECURE_KEY env var

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "My SSN is 123-45-6789. Is that safe?"}],
)
print(response.choices[0].message.content)
# → blocked before reaching OpenAI (400 with matched pattern types)
```

The returned client is a plain `openai.OpenAI` instance — all methods, streaming, and async work exactly as documented by OpenAI.

### Anthropic

```python
import agentsecure

client = agentsecure.anthropic(api_key="sk-ant-...")

message = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Call John at 555-867-5309."}],
)
print(message.content[0].text)
# → phone number redacted; Claude sees [REDACTED]
```

### Async

```python
import agentsecure

aclient = agentsecure.async_openai(api_key="sk-...")
aclient_ant = agentsecure.async_anthropic(api_key="sk-ant-...")
```

### Other providers (Groq, Mistral, Together AI, xAI, Perplexity…)

All OpenAI-compatible providers route through the OpenAI client:

```python
import agentsecure

groq = agentsecure.client("groq", api_key="gsk_...")

response = groq.chat.completions.create(
    model="llama-3.1-70b-versatile",
    messages=[{"role": "user", "content": "Hello"}],
)
```

Supported provider names: `openai`, `anthropic`, `groq`, `mistral`, `gemini`,
`perplexity`, `together`, `xai`, `cohere`, `huggingface`.

---

## LangChain

```python
from agentsecure.langchain import AgentSecureChatOpenAI, AgentSecureChatAnthropic

llm = AgentSecureChatOpenAI(model="gpt-4o", openai_api_key="sk-...")
llm = AgentSecureChatAnthropic(model="claude-opus-4-7", anthropic_api_key="sk-ant-...")
```

These are factory functions that return standard `ChatOpenAI` / `ChatAnthropic` instances — chains, agents, and tools work without modification.

```python
from langchain_core.prompts import ChatPromptTemplate
from agentsecure.langchain import AgentSecureChatOpenAI

chain = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."),
    ("human", "{question}"),
]) | AgentSecureChatOpenAI(model="gpt-4o-mini")

result = chain.invoke({"question": "Summarise quantum computing in one sentence."})
```

---

## LlamaIndex

```python
from agentsecure.llamaindex import AgentSecureOpenAI

llm = AgentSecureOpenAI(model="gpt-4o", api_key="sk-...")
```

---

## What gets detected

| Pattern | Action |
|---|---|
| SSN, passport, driver's license, bank account, credit card | Block — 400, request never reaches the LLM |
| Medical record numbers, NPI | Block |
| Email, phone, IP address, date of birth | Redact — replaced with `[REDACTED]` |
| Person names, organisation names (NER) | Redact — on-device BERT model |

Blocked requests raise an `openai.BadRequestError` (status 400) with the matched pattern types in the response body. Redacted requests return normally — the model sees the cleaned prompt.

---

## Session tracking (Features 1 & 2)

Pass `session_id` to enable synthetic entity substitution and session-level accumulation detection:

```python
import agentsecure

client = agentsecure.openai(
    api_key="sk-...",
    session_id="conv-abc123",   # stable per conversation
    user_id="user@acme.com",    # optional: per-user attribution in audit log
)
```

With `session_id` set, the proxy replaces real names/orgs/locations with consistent synthetic equivalents before forwarding to the LLM, and reverses the substitution in the response. The model never sees real entities; the audit log and your app always do.

---

## Configuration

| Parameter | Env var | Description |
|---|---|---|
| `agentsecure_key=` | `AGENTSECURE_KEY` | Your AgentSecure API key (`as_...`) |
| `session_id=` | — | Conversation ID — enables Features 1 & 2 |
| `user_id=` | — | End-user identifier for audit attribution |
| `base_url=` | — | Override proxy URL (for self-hosted deployments) |

All other keyword arguments are passed through to the underlying client unchanged.

---

## Dashboard

View blocked requests, redacted patterns, and full audit logs at
[agentsecure.vercel.app](https://agentsecure.vercel.app).
