langchain-forge 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.
- langchain_forge-0.1.0/PKG-INFO +100 -0
- langchain_forge-0.1.0/README.md +79 -0
- langchain_forge-0.1.0/forge_langgraph/__init__.py +21 -0
- langchain_forge-0.1.0/forge_langgraph/middleware.py +168 -0
- langchain_forge-0.1.0/langchain_forge.egg-info/PKG-INFO +100 -0
- langchain_forge-0.1.0/langchain_forge.egg-info/SOURCES.txt +9 -0
- langchain_forge-0.1.0/langchain_forge.egg-info/dependency_links.txt +1 -0
- langchain_forge-0.1.0/langchain_forge.egg-info/requires.txt +2 -0
- langchain_forge-0.1.0/langchain_forge.egg-info/top_level.txt +1 -0
- langchain_forge-0.1.0/pyproject.toml +33 -0
- langchain_forge-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: langchain-forge
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Forge Verify middleware for LangGraph/LangChain — verify every tool call before execution
|
|
5
|
+
Author-email: Veritera AI <engineering@veritera.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://veritera.ai
|
|
8
|
+
Project-URL: Documentation, https://veritera.ai/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/VeriteraAI/langchain-forge
|
|
10
|
+
Keywords: veritera,forge,langchain,langgraph,middleware,guardrail,verification
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Security
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: veritera>=0.2.0
|
|
20
|
+
Requires-Dist: langchain-core>=0.3.0
|
|
21
|
+
|
|
22
|
+
# langchain-forge
|
|
23
|
+
|
|
24
|
+
Forge Verify middleware for [LangGraph](https://github.com/langchain-ai/langgraph) and [LangChain](https://github.com/langchain-ai/langchain). Verifies every AI agent tool call against your policies **before** execution.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install langchain-forge
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import os
|
|
36
|
+
from langgraph.prebuilt import create_react_agent
|
|
37
|
+
from langchain_core.tools import tool
|
|
38
|
+
from forge_langgraph import ForgeVerifyMiddleware
|
|
39
|
+
|
|
40
|
+
os.environ["VERITERA_API_KEY"] = "vt_live_..."
|
|
41
|
+
os.environ["OPENAI_API_KEY"] = "sk-..."
|
|
42
|
+
|
|
43
|
+
@tool
|
|
44
|
+
def send_payment(amount: float, recipient: str) -> str:
|
|
45
|
+
"""Send a payment to a recipient."""
|
|
46
|
+
return f"Sent ${amount} to {recipient}"
|
|
47
|
+
|
|
48
|
+
@tool
|
|
49
|
+
def delete_record(record_id: str) -> str:
|
|
50
|
+
"""Delete a database record."""
|
|
51
|
+
return f"Deleted {record_id}"
|
|
52
|
+
|
|
53
|
+
# Add Forge middleware — one line
|
|
54
|
+
middleware = ForgeVerifyMiddleware(policy="finance-controls")
|
|
55
|
+
|
|
56
|
+
agent = create_react_agent(
|
|
57
|
+
model="gpt-4.1",
|
|
58
|
+
tools=[send_payment, delete_record],
|
|
59
|
+
middleware=[middleware],
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Every tool call is verified before execution
|
|
63
|
+
result = agent.invoke({"messages": [("user", "Send $500 to vendor@acme.com")]})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## How It Works
|
|
67
|
+
|
|
68
|
+
1. LangGraph decides to call a tool
|
|
69
|
+
2. **Before execution**, the middleware calls Forge `/v1/verify`
|
|
70
|
+
3. If **approved**: the tool runs normally
|
|
71
|
+
4. If **denied**: the LLM receives a denial message and can explain why
|
|
72
|
+
|
|
73
|
+
## Standalone Tool
|
|
74
|
+
|
|
75
|
+
If you prefer the LLM to call verification explicitly:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from forge_langgraph import forge_verify_tool
|
|
79
|
+
|
|
80
|
+
verify = forge_verify_tool(policy="finance-controls")
|
|
81
|
+
agent = create_react_agent(model, tools=[send_payment, verify])
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Configuration
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
middleware = ForgeVerifyMiddleware(
|
|
88
|
+
api_key="vt_live_...", # or VERITERA_API_KEY env var
|
|
89
|
+
agent_id="prod-finance-bot",
|
|
90
|
+
policy="finance-controls",
|
|
91
|
+
fail_closed=True, # deny when API is unreachable
|
|
92
|
+
skip_actions=["read_balance"], # skip read-only tools
|
|
93
|
+
on_blocked=lambda a, r: print(f"BLOCKED: {a} — {r}"),
|
|
94
|
+
on_verified=lambda a, r: print(f"APPROVED: {a}"),
|
|
95
|
+
)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT — [Veritera AI](https://veritera.ai)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# langchain-forge
|
|
2
|
+
|
|
3
|
+
Forge Verify middleware for [LangGraph](https://github.com/langchain-ai/langgraph) and [LangChain](https://github.com/langchain-ai/langchain). Verifies every AI agent tool call against your policies **before** execution.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install langchain-forge
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import os
|
|
15
|
+
from langgraph.prebuilt import create_react_agent
|
|
16
|
+
from langchain_core.tools import tool
|
|
17
|
+
from forge_langgraph import ForgeVerifyMiddleware
|
|
18
|
+
|
|
19
|
+
os.environ["VERITERA_API_KEY"] = "vt_live_..."
|
|
20
|
+
os.environ["OPENAI_API_KEY"] = "sk-..."
|
|
21
|
+
|
|
22
|
+
@tool
|
|
23
|
+
def send_payment(amount: float, recipient: str) -> str:
|
|
24
|
+
"""Send a payment to a recipient."""
|
|
25
|
+
return f"Sent ${amount} to {recipient}"
|
|
26
|
+
|
|
27
|
+
@tool
|
|
28
|
+
def delete_record(record_id: str) -> str:
|
|
29
|
+
"""Delete a database record."""
|
|
30
|
+
return f"Deleted {record_id}"
|
|
31
|
+
|
|
32
|
+
# Add Forge middleware — one line
|
|
33
|
+
middleware = ForgeVerifyMiddleware(policy="finance-controls")
|
|
34
|
+
|
|
35
|
+
agent = create_react_agent(
|
|
36
|
+
model="gpt-4.1",
|
|
37
|
+
tools=[send_payment, delete_record],
|
|
38
|
+
middleware=[middleware],
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Every tool call is verified before execution
|
|
42
|
+
result = agent.invoke({"messages": [("user", "Send $500 to vendor@acme.com")]})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## How It Works
|
|
46
|
+
|
|
47
|
+
1. LangGraph decides to call a tool
|
|
48
|
+
2. **Before execution**, the middleware calls Forge `/v1/verify`
|
|
49
|
+
3. If **approved**: the tool runs normally
|
|
50
|
+
4. If **denied**: the LLM receives a denial message and can explain why
|
|
51
|
+
|
|
52
|
+
## Standalone Tool
|
|
53
|
+
|
|
54
|
+
If you prefer the LLM to call verification explicitly:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from forge_langgraph import forge_verify_tool
|
|
58
|
+
|
|
59
|
+
verify = forge_verify_tool(policy="finance-controls")
|
|
60
|
+
agent = create_react_agent(model, tools=[send_payment, verify])
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
middleware = ForgeVerifyMiddleware(
|
|
67
|
+
api_key="vt_live_...", # or VERITERA_API_KEY env var
|
|
68
|
+
agent_id="prod-finance-bot",
|
|
69
|
+
policy="finance-controls",
|
|
70
|
+
fail_closed=True, # deny when API is unreachable
|
|
71
|
+
skip_actions=["read_balance"], # skip read-only tools
|
|
72
|
+
on_blocked=lambda a, r: print(f"BLOCKED: {a} — {r}"),
|
|
73
|
+
on_verified=lambda a, r: print(f"APPROVED: {a}"),
|
|
74
|
+
)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
MIT — [Veritera AI](https://veritera.ai)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Forge Verify middleware for LangGraph / LangChain.
|
|
2
|
+
|
|
3
|
+
Intercepts every tool call and verifies it against Forge policies before execution.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
from forge_langgraph import ForgeVerifyMiddleware
|
|
7
|
+
|
|
8
|
+
middleware = ForgeVerifyMiddleware(policy="finance-controls")
|
|
9
|
+
|
|
10
|
+
agent = create_react_agent(
|
|
11
|
+
model="gpt-4.1",
|
|
12
|
+
tools=[send_payment, read_balance],
|
|
13
|
+
middleware=[middleware],
|
|
14
|
+
)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
__version__ = "0.1.0"
|
|
18
|
+
|
|
19
|
+
from .middleware import ForgeVerifyMiddleware, forge_verify_tool
|
|
20
|
+
|
|
21
|
+
__all__ = ["ForgeVerifyMiddleware", "forge_verify_tool"]
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""Forge Verify middleware for LangGraph / LangChain.
|
|
2
|
+
|
|
3
|
+
Two integration approaches:
|
|
4
|
+
|
|
5
|
+
1. AgentMiddleware (recommended) — intercepts ALL tool calls automatically:
|
|
6
|
+
middleware = ForgeVerifyMiddleware(policy="finance-controls")
|
|
7
|
+
agent = create_react_agent(model, tools, middleware=[middleware])
|
|
8
|
+
|
|
9
|
+
2. Standalone tool — the LLM calls forge_verify explicitly:
|
|
10
|
+
tool = forge_verify_tool(policy="finance-controls")
|
|
11
|
+
agent = create_react_agent(model, tools=[send_payment, tool])
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
import os
|
|
18
|
+
from collections.abc import Callable
|
|
19
|
+
from typing import Any, Optional
|
|
20
|
+
|
|
21
|
+
from veritera import Forge
|
|
22
|
+
|
|
23
|
+
from langchain_core.tools import BaseTool, tool
|
|
24
|
+
from langchain_core.messages import ToolMessage
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger("forge_langgraph")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ForgeVerifyMiddleware:
|
|
30
|
+
"""LangGraph/LangChain middleware that verifies every tool call through Forge.
|
|
31
|
+
|
|
32
|
+
Works with create_react_agent and any LangGraph agent that accepts middleware.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
api_key: Forge API key (or set VERITERA_API_KEY env var).
|
|
36
|
+
base_url: Forge API endpoint.
|
|
37
|
+
agent_id: Identifier for this agent in Forge audit logs.
|
|
38
|
+
policy: Policy to evaluate actions against.
|
|
39
|
+
fail_closed: If True (default), deny when Forge API is unreachable.
|
|
40
|
+
timeout: Request timeout in seconds.
|
|
41
|
+
skip_actions: Tool names to skip verification for.
|
|
42
|
+
on_verified: Callback(action, result) when approved.
|
|
43
|
+
on_blocked: Callback(action, reason) when denied.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
api_key: Optional[str] = None,
|
|
49
|
+
base_url: str = "https://veritera.ai",
|
|
50
|
+
agent_id: str = "langgraph-agent",
|
|
51
|
+
policy: Optional[str] = None,
|
|
52
|
+
fail_closed: bool = True,
|
|
53
|
+
timeout: float = 10.0,
|
|
54
|
+
skip_actions: Optional[list[str]] = None,
|
|
55
|
+
on_verified: Optional[Callable] = None,
|
|
56
|
+
on_blocked: Optional[Callable] = None,
|
|
57
|
+
):
|
|
58
|
+
key = api_key or os.environ.get("VERITERA_API_KEY", "")
|
|
59
|
+
if not key:
|
|
60
|
+
raise ValueError(
|
|
61
|
+
"Forge API key required. Pass api_key= or set VERITERA_API_KEY env var."
|
|
62
|
+
)
|
|
63
|
+
self._client = Forge(
|
|
64
|
+
api_key=key,
|
|
65
|
+
base_url=base_url,
|
|
66
|
+
timeout=timeout,
|
|
67
|
+
fail_closed=fail_closed,
|
|
68
|
+
)
|
|
69
|
+
self.agent_id = agent_id
|
|
70
|
+
self.policy = policy
|
|
71
|
+
self.fail_closed = fail_closed
|
|
72
|
+
self.skip_actions = set(skip_actions or [])
|
|
73
|
+
self.on_verified = on_verified
|
|
74
|
+
self.on_blocked = on_blocked
|
|
75
|
+
|
|
76
|
+
def wrap_tool_call(self, request: Any, handler: Callable) -> Any:
|
|
77
|
+
"""Middleware entry point — called by LangGraph before each tool execution.
|
|
78
|
+
|
|
79
|
+
If Forge approves: calls handler(request) to execute the tool.
|
|
80
|
+
If Forge denies: returns a ToolMessage with the denial reason.
|
|
81
|
+
"""
|
|
82
|
+
tool_name = request.tool_call.get("name", "unknown")
|
|
83
|
+
tool_args = request.tool_call.get("args", {})
|
|
84
|
+
tool_call_id = request.tool_call.get("id", "")
|
|
85
|
+
|
|
86
|
+
# Skip configured actions
|
|
87
|
+
if tool_name in self.skip_actions:
|
|
88
|
+
return handler(request)
|
|
89
|
+
|
|
90
|
+
# Verify through Forge (sync)
|
|
91
|
+
try:
|
|
92
|
+
result = self._client.verify_sync(
|
|
93
|
+
action=tool_name,
|
|
94
|
+
agent_id=self.agent_id,
|
|
95
|
+
params=tool_args if isinstance(tool_args, dict) else {"raw": str(tool_args)},
|
|
96
|
+
policy=self.policy,
|
|
97
|
+
)
|
|
98
|
+
except Exception as exc:
|
|
99
|
+
logger.error("Forge verify error for %s: %s", tool_name, exc)
|
|
100
|
+
if self.fail_closed:
|
|
101
|
+
if self.on_blocked:
|
|
102
|
+
self.on_blocked(tool_name, str(exc))
|
|
103
|
+
return ToolMessage(
|
|
104
|
+
content=f"Action '{tool_name}' blocked — policy verification unavailable.",
|
|
105
|
+
tool_call_id=tool_call_id,
|
|
106
|
+
)
|
|
107
|
+
return handler(request)
|
|
108
|
+
|
|
109
|
+
if result.verified:
|
|
110
|
+
logger.debug("Forge APPROVED: %s (proof=%s)", tool_name, result.proof_id)
|
|
111
|
+
if self.on_verified:
|
|
112
|
+
self.on_verified(tool_name, result)
|
|
113
|
+
return handler(request)
|
|
114
|
+
|
|
115
|
+
reason = result.reason or "Policy violation"
|
|
116
|
+
logger.warning("Forge DENIED: %s — %s", tool_name, reason)
|
|
117
|
+
if self.on_blocked:
|
|
118
|
+
self.on_blocked(tool_name, reason)
|
|
119
|
+
return ToolMessage(
|
|
120
|
+
content=f"Action '{tool_name}' denied by Forge: {reason}",
|
|
121
|
+
tool_call_id=tool_call_id,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def forge_verify_tool(
|
|
126
|
+
api_key: Optional[str] = None,
|
|
127
|
+
base_url: str = "https://veritera.ai",
|
|
128
|
+
agent_id: str = "langgraph-agent",
|
|
129
|
+
policy: Optional[str] = None,
|
|
130
|
+
) -> BaseTool:
|
|
131
|
+
"""Create a LangChain tool that the LLM can call to verify actions.
|
|
132
|
+
|
|
133
|
+
This is an alternative to the middleware approach — the LLM decides
|
|
134
|
+
when to call verification explicitly.
|
|
135
|
+
|
|
136
|
+
Usage:
|
|
137
|
+
verify = forge_verify_tool(policy="finance-controls")
|
|
138
|
+
agent = create_react_agent(model, tools=[send_payment, verify])
|
|
139
|
+
"""
|
|
140
|
+
key = api_key or os.environ.get("VERITERA_API_KEY", "")
|
|
141
|
+
client = Forge(api_key=key, base_url=base_url, fail_closed=True)
|
|
142
|
+
|
|
143
|
+
@tool
|
|
144
|
+
def forge_verify(action: str, params: str = "{}") -> str:
|
|
145
|
+
"""Verify an AI agent action against Forge security policies before executing it.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
action: The action identifier to verify (e.g. 'payment.create')
|
|
149
|
+
params: JSON string of action parameters
|
|
150
|
+
"""
|
|
151
|
+
import json as _json
|
|
152
|
+
|
|
153
|
+
try:
|
|
154
|
+
parsed = _json.loads(params)
|
|
155
|
+
except _json.JSONDecodeError:
|
|
156
|
+
parsed = {"raw": params}
|
|
157
|
+
|
|
158
|
+
result = client.verify_sync(
|
|
159
|
+
action=action,
|
|
160
|
+
agent_id=agent_id,
|
|
161
|
+
params=parsed,
|
|
162
|
+
policy=policy,
|
|
163
|
+
)
|
|
164
|
+
if result.verified:
|
|
165
|
+
return f"APPROVED: {result.verdict} | proof_id: {result.proof_id} | latency: {result.latency_ms}ms"
|
|
166
|
+
return f"DENIED: {result.reason} | proof_id: {result.proof_id}"
|
|
167
|
+
|
|
168
|
+
return forge_verify
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: langchain-forge
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Forge Verify middleware for LangGraph/LangChain — verify every tool call before execution
|
|
5
|
+
Author-email: Veritera AI <engineering@veritera.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://veritera.ai
|
|
8
|
+
Project-URL: Documentation, https://veritera.ai/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/VeriteraAI/langchain-forge
|
|
10
|
+
Keywords: veritera,forge,langchain,langgraph,middleware,guardrail,verification
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Security
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: veritera>=0.2.0
|
|
20
|
+
Requires-Dist: langchain-core>=0.3.0
|
|
21
|
+
|
|
22
|
+
# langchain-forge
|
|
23
|
+
|
|
24
|
+
Forge Verify middleware for [LangGraph](https://github.com/langchain-ai/langgraph) and [LangChain](https://github.com/langchain-ai/langchain). Verifies every AI agent tool call against your policies **before** execution.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install langchain-forge
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import os
|
|
36
|
+
from langgraph.prebuilt import create_react_agent
|
|
37
|
+
from langchain_core.tools import tool
|
|
38
|
+
from forge_langgraph import ForgeVerifyMiddleware
|
|
39
|
+
|
|
40
|
+
os.environ["VERITERA_API_KEY"] = "vt_live_..."
|
|
41
|
+
os.environ["OPENAI_API_KEY"] = "sk-..."
|
|
42
|
+
|
|
43
|
+
@tool
|
|
44
|
+
def send_payment(amount: float, recipient: str) -> str:
|
|
45
|
+
"""Send a payment to a recipient."""
|
|
46
|
+
return f"Sent ${amount} to {recipient}"
|
|
47
|
+
|
|
48
|
+
@tool
|
|
49
|
+
def delete_record(record_id: str) -> str:
|
|
50
|
+
"""Delete a database record."""
|
|
51
|
+
return f"Deleted {record_id}"
|
|
52
|
+
|
|
53
|
+
# Add Forge middleware — one line
|
|
54
|
+
middleware = ForgeVerifyMiddleware(policy="finance-controls")
|
|
55
|
+
|
|
56
|
+
agent = create_react_agent(
|
|
57
|
+
model="gpt-4.1",
|
|
58
|
+
tools=[send_payment, delete_record],
|
|
59
|
+
middleware=[middleware],
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Every tool call is verified before execution
|
|
63
|
+
result = agent.invoke({"messages": [("user", "Send $500 to vendor@acme.com")]})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## How It Works
|
|
67
|
+
|
|
68
|
+
1. LangGraph decides to call a tool
|
|
69
|
+
2. **Before execution**, the middleware calls Forge `/v1/verify`
|
|
70
|
+
3. If **approved**: the tool runs normally
|
|
71
|
+
4. If **denied**: the LLM receives a denial message and can explain why
|
|
72
|
+
|
|
73
|
+
## Standalone Tool
|
|
74
|
+
|
|
75
|
+
If you prefer the LLM to call verification explicitly:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from forge_langgraph import forge_verify_tool
|
|
79
|
+
|
|
80
|
+
verify = forge_verify_tool(policy="finance-controls")
|
|
81
|
+
agent = create_react_agent(model, tools=[send_payment, verify])
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Configuration
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
middleware = ForgeVerifyMiddleware(
|
|
88
|
+
api_key="vt_live_...", # or VERITERA_API_KEY env var
|
|
89
|
+
agent_id="prod-finance-bot",
|
|
90
|
+
policy="finance-controls",
|
|
91
|
+
fail_closed=True, # deny when API is unreachable
|
|
92
|
+
skip_actions=["read_balance"], # skip read-only tools
|
|
93
|
+
on_blocked=lambda a, r: print(f"BLOCKED: {a} — {r}"),
|
|
94
|
+
on_verified=lambda a, r: print(f"APPROVED: {a}"),
|
|
95
|
+
)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT — [Veritera AI](https://veritera.ai)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
forge_langgraph/__init__.py
|
|
4
|
+
forge_langgraph/middleware.py
|
|
5
|
+
langchain_forge.egg-info/PKG-INFO
|
|
6
|
+
langchain_forge.egg-info/SOURCES.txt
|
|
7
|
+
langchain_forge.egg-info/dependency_links.txt
|
|
8
|
+
langchain_forge.egg-info/requires.txt
|
|
9
|
+
langchain_forge.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
forge_langgraph
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "langchain-forge"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Forge Verify middleware for LangGraph/LangChain — verify every tool call before execution"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = {text = "MIT"}
|
|
7
|
+
requires-python = ">=3.10"
|
|
8
|
+
authors = [{name = "Veritera AI", email = "engineering@veritera.ai"}]
|
|
9
|
+
keywords = ["veritera", "forge", "langchain", "langgraph", "middleware", "guardrail", "verification"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 4 - Beta",
|
|
12
|
+
"Intended Audience :: Developers",
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Topic :: Security",
|
|
16
|
+
"Topic :: Software Development :: Libraries",
|
|
17
|
+
]
|
|
18
|
+
dependencies = [
|
|
19
|
+
"veritera>=0.2.0",
|
|
20
|
+
"langchain-core>=0.3.0",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://veritera.ai"
|
|
25
|
+
Documentation = "https://veritera.ai/docs"
|
|
26
|
+
Repository = "https://github.com/VeriteraAI/langchain-forge"
|
|
27
|
+
|
|
28
|
+
[build-system]
|
|
29
|
+
requires = ["setuptools>=68.0"]
|
|
30
|
+
build-backend = "setuptools.build_meta"
|
|
31
|
+
|
|
32
|
+
[tool.setuptools.packages.find]
|
|
33
|
+
include = ["forge_langgraph*"]
|