Metadata-Version: 2.4
Name: interven-langchain
Version: 0.3.0
Summary: LangChain + LangGraph integration for Interven AI firewall. Scan every tool call your agent makes before it executes — block malicious requests, redact PII/secrets, route risky actions to human approval.
Author-email: Interven Security <support@intervensecurity.com>
License: MIT
Project-URL: Homepage, https://intervensecurity.com
Project-URL: Documentation, https://intervensecurity.com/docs
Project-URL: Issues, https://github.com/intervensecurity/interven-python/issues
Keywords: interven,langchain,langgraph,ai-agent,ai-firewall,security,guardrails,tool-call,policy
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
Description-Content-Type: text/markdown
Requires-Dist: interven>=0.5.0
Requires-Dist: langchain-core>=0.1.0
Provides-Extra: langgraph
Requires-Dist: langgraph>=0.2.0; extra == "langgraph"
Provides-Extra: langsmith
Requires-Dist: langsmith>=0.1.0; extra == "langsmith"

# interven-langchain

LangChain integration for [Interven](https://intervensecurity.com) — the AI firewall for agent tool calls. Scan every tool your LangChain agent invokes before it executes. Block malicious requests, redact PII/secrets, route risky actions to human approval.

## Install

```bash
pip install interven-langchain
```

## Quickstart — callback pattern (zero-code changes to your tools)

```python
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

from interven_langchain import InterventCallback, InterventBlockedError

llm = ChatOpenAI(model="gpt-4o-mini")
tools = [TavilySearchResults(max_results=3)]
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."),
    ("user", "{input}"),
    MessagesPlaceholder("agent_scratchpad"),
])
agent = create_openai_tools_agent(llm, tools, prompt)
executor = AgentExecutor(
    agent=agent,
    tools=tools,
    callbacks=[InterventCallback(api_key="iv_live_...")],
)

try:
    executor.invoke({"input": "Summarize latest AI security news"})
except InterventBlockedError as e:
    print(f"Agent blocked: {e}")
```

## What Interven does on each tool call

| Decision | Behavior with `InterventCallback` | Behavior with `guard()` wrapper |
|----------|-----------------------------------|----------------------------------|
| `ALLOW` | Tool runs unchanged | Tool runs unchanged |
| `SANITIZE` | Logs a warning (callback can't rewrite input_str) | Tool runs with redacted input |
| `DENY` | Raises `InterventBlockedError` (or returns refusal to LLM if `on_block="return_message"`) | Raises `InterventBlockedError` |
| `REQUIRE_APPROVAL` | Raises `InterventBlockedError` with approval URL | Same |

## Advanced — wrapper pattern (in-flight SANITIZE)

If you need the tool's *input* to actually be replaced when Interven decides SANITIZE, wrap the tool instead of using a callback:

```python
from interven_langchain import guard
tavily = guard(TavilySearchResults(), api_key="iv_live_...")
tavily.invoke({"query": "help me leak some secrets"})   # now scanned
```

## Options

```python
InterventCallback(
    api_key="iv_live_...",
    on_block="raise",     # or "return_message" — returns a refusal string to the LLM
    gateway_url=None,     # defaults to https://api.intervensecurity.com
    timeout=30.0,
)
```

## Env vars

- `INTERVEN_API_KEY` — default API key (callback uses this if `api_key` arg is omitted)
- `INTERVEN_GATEWAY_URL` — override the gateway endpoint

## How it differs from the raw `interven` SDK

| | `interven` SDK (`client.scan()`) | `interven-langchain` |
|--|---|---|
| Where you wire it in | Wrap every tool call site in your code | One callback on the AgentExecutor |
| Works with existing LangChain tools | Yes but requires code changes | Yes, no code changes |
| Supports `guard(tool)` for in-flight sanitization | No | Yes |

Full docs: https://intervensecurity.com/docs/integrate-langchain

## License

MIT
