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.
@@ -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,2 @@
1
+ veritera>=0.2.0
2
+ langchain-core>=0.3.0
@@ -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*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+