forge-openai 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,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: forge-openai
3
+ Version: 0.1.0
4
+ Summary: Forge Verify guardrail for OpenAI Agents SDK — 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/forge-openai
10
+ Keywords: veritera,forge,openai,agents,guardrail,verification,ai-safety
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: openai-agents>=0.1.0
21
+
22
+ # forge-openai
23
+
24
+ Forge Verify guardrail for the [OpenAI Agents SDK](https://github.com/openai/openai-agents-python). Verifies every AI agent tool call against your policies **before** execution.
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ pip install forge-openai
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ```python
35
+ import os
36
+ from agents import Agent, Runner, function_tool
37
+ from forge_openai import forge_tool_guardrail, forge_protect
38
+
39
+ os.environ["VERITERA_API_KEY"] = "vt_live_..."
40
+ os.environ["OPENAI_API_KEY"] = "sk-..."
41
+
42
+ # Define your tools
43
+ @function_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
+ @function_tool
49
+ def delete_record(record_id: str) -> str:
50
+ """Delete a database record."""
51
+ return f"Deleted {record_id}"
52
+
53
+ @function_tool
54
+ def read_balance() -> str:
55
+ """Check account balance."""
56
+ return "Balance: $50,000"
57
+
58
+ # Protect all tools with Forge — one line
59
+ agent = Agent(
60
+ name="finance-bot",
61
+ instructions="You help with financial operations.",
62
+ tools=forge_protect(
63
+ send_payment, delete_record, read_balance,
64
+ policy="finance-controls",
65
+ skip_actions=["read_balance"], # read-only tools don't need verification
66
+ ),
67
+ )
68
+
69
+ # Run the agent — Forge checks every tool call automatically
70
+ result = await Runner.run(agent, "Send $500 to vendor@acme.com")
71
+ ```
72
+
73
+ ## How It Works
74
+
75
+ 1. Your agent decides to call a tool (e.g. `send_payment`)
76
+ 2. **Before execution**, Forge checks the action against your policies
77
+ 3. If **approved**: the tool runs normally
78
+ 4. If **denied**: the LLM receives a denial message and can explain why to the user
79
+
80
+ No tool ever executes without verification. Every decision is logged with a cryptographic proof.
81
+
82
+ ## Per-Tool Guardrail
83
+
84
+ ```python
85
+ from forge_openai import forge_tool_guardrail
86
+
87
+ guardrail = forge_tool_guardrail(policy="email-controls")
88
+
89
+ @function_tool(tool_input_guardrails=[guardrail])
90
+ def send_email(to: str, subject: str, body: str) -> str:
91
+ """Send an email."""
92
+ return f"Email sent to {to}"
93
+ ```
94
+
95
+ ## Full Control
96
+
97
+ ```python
98
+ from forge_openai import ForgeGuardrail
99
+
100
+ forge = ForgeGuardrail(
101
+ api_key="vt_live_...",
102
+ agent_id="prod-finance-bot",
103
+ policy="finance-controls",
104
+ fail_closed=True,
105
+ skip_actions=["read_balance", "get_time"],
106
+ on_blocked=lambda action, reason, result: print(f"BLOCKED: {action} — {reason}"),
107
+ on_verified=lambda action, result: print(f"APPROVED: {action}"),
108
+ )
109
+
110
+ agent = Agent(
111
+ name="finance-bot",
112
+ tools=forge.protect(send_payment, delete_record),
113
+ input_guardrails=[forge.input_guardrail()], # also screen agent input
114
+ )
115
+ ```
116
+
117
+ ## Environment Variables
118
+
119
+ | Variable | Description |
120
+ |----------|-------------|
121
+ | `VERITERA_API_KEY` | Your Forge API key (starts with `vt_live_` or `vt_test_`) |
122
+
123
+ ## License
124
+
125
+ MIT — [Veritera AI](https://veritera.ai)
@@ -0,0 +1,104 @@
1
+ # forge-openai
2
+
3
+ Forge Verify guardrail for the [OpenAI Agents SDK](https://github.com/openai/openai-agents-python). Verifies every AI agent tool call against your policies **before** execution.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install forge-openai
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ import os
15
+ from agents import Agent, Runner, function_tool
16
+ from forge_openai import forge_tool_guardrail, forge_protect
17
+
18
+ os.environ["VERITERA_API_KEY"] = "vt_live_..."
19
+ os.environ["OPENAI_API_KEY"] = "sk-..."
20
+
21
+ # Define your tools
22
+ @function_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
+ @function_tool
28
+ def delete_record(record_id: str) -> str:
29
+ """Delete a database record."""
30
+ return f"Deleted {record_id}"
31
+
32
+ @function_tool
33
+ def read_balance() -> str:
34
+ """Check account balance."""
35
+ return "Balance: $50,000"
36
+
37
+ # Protect all tools with Forge — one line
38
+ agent = Agent(
39
+ name="finance-bot",
40
+ instructions="You help with financial operations.",
41
+ tools=forge_protect(
42
+ send_payment, delete_record, read_balance,
43
+ policy="finance-controls",
44
+ skip_actions=["read_balance"], # read-only tools don't need verification
45
+ ),
46
+ )
47
+
48
+ # Run the agent — Forge checks every tool call automatically
49
+ result = await Runner.run(agent, "Send $500 to vendor@acme.com")
50
+ ```
51
+
52
+ ## How It Works
53
+
54
+ 1. Your agent decides to call a tool (e.g. `send_payment`)
55
+ 2. **Before execution**, Forge checks the action against your policies
56
+ 3. If **approved**: the tool runs normally
57
+ 4. If **denied**: the LLM receives a denial message and can explain why to the user
58
+
59
+ No tool ever executes without verification. Every decision is logged with a cryptographic proof.
60
+
61
+ ## Per-Tool Guardrail
62
+
63
+ ```python
64
+ from forge_openai import forge_tool_guardrail
65
+
66
+ guardrail = forge_tool_guardrail(policy="email-controls")
67
+
68
+ @function_tool(tool_input_guardrails=[guardrail])
69
+ def send_email(to: str, subject: str, body: str) -> str:
70
+ """Send an email."""
71
+ return f"Email sent to {to}"
72
+ ```
73
+
74
+ ## Full Control
75
+
76
+ ```python
77
+ from forge_openai import ForgeGuardrail
78
+
79
+ forge = ForgeGuardrail(
80
+ api_key="vt_live_...",
81
+ agent_id="prod-finance-bot",
82
+ policy="finance-controls",
83
+ fail_closed=True,
84
+ skip_actions=["read_balance", "get_time"],
85
+ on_blocked=lambda action, reason, result: print(f"BLOCKED: {action} — {reason}"),
86
+ on_verified=lambda action, result: print(f"APPROVED: {action}"),
87
+ )
88
+
89
+ agent = Agent(
90
+ name="finance-bot",
91
+ tools=forge.protect(send_payment, delete_record),
92
+ input_guardrails=[forge.input_guardrail()], # also screen agent input
93
+ )
94
+ ```
95
+
96
+ ## Environment Variables
97
+
98
+ | Variable | Description |
99
+ |----------|-------------|
100
+ | `VERITERA_API_KEY` | Your Forge API key (starts with `vt_live_` or `vt_test_`) |
101
+
102
+ ## License
103
+
104
+ MIT — [Veritera AI](https://veritera.ai)
@@ -0,0 +1,36 @@
1
+ """Forge Verify guardrail for OpenAI Agents SDK.
2
+
3
+ Verify every AI agent tool call against your policies before execution.
4
+
5
+ Usage:
6
+ from forge_openai import forge_tool_guardrail, forge_protect
7
+
8
+ # Option 1: Attach guardrail to individual tools
9
+ guardrail = forge_tool_guardrail(policy="finance-controls")
10
+
11
+ @function_tool(tool_input_guardrails=[guardrail])
12
+ def send_payment(amount: float, to: str) -> str:
13
+ ...
14
+
15
+ # Option 2: Protect all tools at once
16
+ agent = Agent(
17
+ name="finance-bot",
18
+ tools=forge_protect(send_payment, read_balance, policy="finance-controls"),
19
+ )
20
+ """
21
+
22
+ __version__ = "0.1.0"
23
+
24
+ from .guardrail import (
25
+ ForgeGuardrail,
26
+ forge_tool_guardrail,
27
+ forge_protect,
28
+ forge_input_guardrail,
29
+ )
30
+
31
+ __all__ = [
32
+ "ForgeGuardrail",
33
+ "forge_tool_guardrail",
34
+ "forge_protect",
35
+ "forge_input_guardrail",
36
+ ]
@@ -0,0 +1,312 @@
1
+ """Forge Verify guardrails for OpenAI Agents SDK.
2
+
3
+ Provides ToolInputGuardrail (pre-tool) and InputGuardrail (pre-agent)
4
+ that call the Forge /v1/verify API before execution proceeds.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import copy
10
+ import json
11
+ import logging
12
+ import os
13
+ from typing import Any, Optional
14
+
15
+ from veritera import Forge, ForgeError
16
+
17
+ from agents import (
18
+ Agent,
19
+ FunctionTool,
20
+ GuardrailFunctionOutput,
21
+ InputGuardrail,
22
+ RunContextWrapper,
23
+ ToolInputGuardrail,
24
+ ToolInputGuardrailData,
25
+ ToolGuardrailFunctionOutput,
26
+ )
27
+
28
+ logger = logging.getLogger("forge_openai")
29
+
30
+
31
+ class ForgeGuardrail:
32
+ """Configurable Forge verification client for OpenAI Agents SDK.
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: Default policy to evaluate against.
39
+ fail_closed: If True (default), deny actions when Forge API is unreachable.
40
+ timeout: Request timeout in seconds.
41
+ skip_actions: Tool names to skip verification for (e.g. read-only tools).
42
+ on_verified: Callback(action, result) when a tool call is approved.
43
+ on_blocked: Callback(action, reason, result) when a tool call is 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 = "openai-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[Any] = None,
56
+ on_blocked: Optional[Any] = 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 tool_guardrail(self) -> ToolInputGuardrail:
77
+ """Create a ToolInputGuardrail that verifies each tool call through Forge.
78
+
79
+ Attach to individual tools:
80
+ @function_tool(tool_input_guardrails=[guard.tool_guardrail()])
81
+ def send_email(...): ...
82
+
83
+ Or use forge_protect() to attach to multiple tools at once.
84
+ """
85
+
86
+ async def _verify_tool(
87
+ data: ToolInputGuardrailData,
88
+ ) -> ToolGuardrailFunctionOutput:
89
+ tool_name = data.context.tool_name
90
+
91
+ # Skip configured actions
92
+ if tool_name in self.skip_actions:
93
+ return ToolGuardrailFunctionOutput.allow(
94
+ output_info={"skipped": True, "action": tool_name}
95
+ )
96
+
97
+ # Parse tool arguments
98
+ try:
99
+ params = (
100
+ json.loads(data.context.tool_arguments)
101
+ if data.context.tool_arguments
102
+ else {}
103
+ )
104
+ except (json.JSONDecodeError, TypeError):
105
+ params = {"raw": data.context.tool_arguments}
106
+
107
+ # Call Forge /v1/verify
108
+ try:
109
+ result = await self._client.verify_decision(
110
+ agent_id=self.agent_id,
111
+ action=tool_name,
112
+ params=params,
113
+ policy=self.policy,
114
+ )
115
+ except Exception as exc:
116
+ logger.error("Forge verify error for %s: %s", tool_name, exc)
117
+ if self.fail_closed:
118
+ if self.on_blocked:
119
+ self.on_blocked(tool_name, str(exc), None)
120
+ return ToolGuardrailFunctionOutput.reject_content(
121
+ message=f"Action '{tool_name}' blocked — policy verification unavailable.",
122
+ output_info={"error": str(exc), "fail_mode": "closed"},
123
+ )
124
+ return ToolGuardrailFunctionOutput.allow(
125
+ output_info={"error": str(exc), "fail_mode": "open"}
126
+ )
127
+
128
+ if result.verified:
129
+ logger.debug("Forge APPROVED: %s (proof=%s)", tool_name, result.proof_id)
130
+ if self.on_verified:
131
+ self.on_verified(tool_name, result)
132
+ return ToolGuardrailFunctionOutput.allow(
133
+ output_info={
134
+ "verified": True,
135
+ "proof_id": result.proof_id,
136
+ "latency_ms": result.latency_ms,
137
+ }
138
+ )
139
+
140
+ reason = result.reason or "Policy violation"
141
+ logger.warning("Forge DENIED: %s — %s", tool_name, reason)
142
+ if self.on_blocked:
143
+ self.on_blocked(tool_name, reason, result)
144
+ return ToolGuardrailFunctionOutput.reject_content(
145
+ message=f"Action '{tool_name}' denied by Forge: {reason}",
146
+ output_info={
147
+ "verified": False,
148
+ "reason": reason,
149
+ "proof_id": result.proof_id,
150
+ "latency_ms": result.latency_ms,
151
+ },
152
+ )
153
+
154
+ return ToolInputGuardrail(
155
+ guardrail_function=_verify_tool,
156
+ name="forge_verify",
157
+ )
158
+
159
+ def input_guardrail(self) -> InputGuardrail:
160
+ """Create an InputGuardrail that screens agent input through Forge.
161
+
162
+ Useful for blocking entire conversation turns based on policy.
163
+ """
164
+
165
+ async def _screen_input(
166
+ ctx: RunContextWrapper, agent: Agent, input: Any
167
+ ) -> GuardrailFunctionOutput:
168
+ input_text = str(input) if input else ""
169
+ try:
170
+ result = await self._client.verify_decision(
171
+ agent_id=self.agent_id,
172
+ action="agent.input",
173
+ params={"input": input_text[:2000]},
174
+ policy=self.policy,
175
+ )
176
+ return GuardrailFunctionOutput(
177
+ output_info={
178
+ "verified": result.verified,
179
+ "reason": result.reason,
180
+ },
181
+ tripwire_triggered=not result.verified,
182
+ )
183
+ except Exception as exc:
184
+ logger.error("Forge input guardrail error: %s", exc)
185
+ return GuardrailFunctionOutput(
186
+ output_info={"error": str(exc)},
187
+ tripwire_triggered=self.fail_closed,
188
+ )
189
+
190
+ return InputGuardrail(
191
+ guardrail_function=_screen_input,
192
+ name="forge_input_screen",
193
+ )
194
+
195
+ def protect(self, *tools: FunctionTool, policy: Optional[str] = None) -> list[FunctionTool]:
196
+ """Attach Forge guardrail to multiple tools at once.
197
+
198
+ Returns new tool instances — originals are not mutated.
199
+ """
200
+ guardrail = self.tool_guardrail()
201
+ if policy and policy != self.policy:
202
+ # Create a separate guardrail with the override policy
203
+ original_policy = self.policy
204
+ self.policy = policy
205
+ guardrail = self.tool_guardrail()
206
+ self.policy = original_policy
207
+
208
+ protected = []
209
+ for tool in tools:
210
+ t = copy.copy(tool)
211
+ existing = list(t.tool_input_guardrails or [])
212
+ existing.append(guardrail)
213
+ t.tool_input_guardrails = existing
214
+ protected.append(t)
215
+ return protected
216
+
217
+
218
+ # ── Convenience functions ──
219
+
220
+
221
+ def forge_tool_guardrail(
222
+ api_key: Optional[str] = None,
223
+ base_url: str = "https://veritera.ai",
224
+ agent_id: str = "openai-agent",
225
+ policy: Optional[str] = None,
226
+ fail_closed: bool = True,
227
+ timeout: float = 10.0,
228
+ skip_actions: Optional[list[str]] = None,
229
+ on_verified: Optional[Any] = None,
230
+ on_blocked: Optional[Any] = None,
231
+ ) -> ToolInputGuardrail:
232
+ """Create a ToolInputGuardrail that verifies tool calls through Forge.
233
+
234
+ Usage:
235
+ guardrail = forge_tool_guardrail(policy="finance-controls")
236
+
237
+ @function_tool(tool_input_guardrails=[guardrail])
238
+ def send_payment(amount: float, recipient: str) -> str:
239
+ \"\"\"Send a payment.\"\"\"
240
+ return process_payment(amount, recipient)
241
+ """
242
+ guard = ForgeGuardrail(
243
+ api_key=api_key,
244
+ base_url=base_url,
245
+ agent_id=agent_id,
246
+ policy=policy,
247
+ fail_closed=fail_closed,
248
+ timeout=timeout,
249
+ skip_actions=skip_actions,
250
+ on_verified=on_verified,
251
+ on_blocked=on_blocked,
252
+ )
253
+ return guard.tool_guardrail()
254
+
255
+
256
+ def forge_input_guardrail(
257
+ api_key: Optional[str] = None,
258
+ base_url: str = "https://veritera.ai",
259
+ agent_id: str = "openai-agent",
260
+ policy: Optional[str] = None,
261
+ fail_closed: bool = True,
262
+ ) -> InputGuardrail:
263
+ """Create an InputGuardrail that screens agent input through Forge.
264
+
265
+ Usage:
266
+ agent = Agent(
267
+ name="my-agent",
268
+ input_guardrails=[forge_input_guardrail(policy="content-policy")],
269
+ tools=[...],
270
+ )
271
+ """
272
+ guard = ForgeGuardrail(
273
+ api_key=api_key,
274
+ base_url=base_url,
275
+ agent_id=agent_id,
276
+ policy=policy,
277
+ fail_closed=fail_closed,
278
+ )
279
+ return guard.input_guardrail()
280
+
281
+
282
+ def forge_protect(
283
+ *tools: FunctionTool,
284
+ api_key: Optional[str] = None,
285
+ base_url: str = "https://veritera.ai",
286
+ agent_id: str = "openai-agent",
287
+ policy: Optional[str] = None,
288
+ fail_closed: bool = True,
289
+ timeout: float = 10.0,
290
+ skip_actions: Optional[list[str]] = None,
291
+ ) -> list[FunctionTool]:
292
+ """Attach Forge verification to multiple tools at once.
293
+
294
+ Usage:
295
+ agent = Agent(
296
+ name="finance-bot",
297
+ tools=forge_protect(
298
+ send_payment, read_balance, delete_record,
299
+ policy="finance-controls",
300
+ ),
301
+ )
302
+ """
303
+ guard = ForgeGuardrail(
304
+ api_key=api_key,
305
+ base_url=base_url,
306
+ agent_id=agent_id,
307
+ policy=policy,
308
+ fail_closed=fail_closed,
309
+ timeout=timeout,
310
+ skip_actions=skip_actions,
311
+ )
312
+ return guard.protect(*tools)
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: forge-openai
3
+ Version: 0.1.0
4
+ Summary: Forge Verify guardrail for OpenAI Agents SDK — 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/forge-openai
10
+ Keywords: veritera,forge,openai,agents,guardrail,verification,ai-safety
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: openai-agents>=0.1.0
21
+
22
+ # forge-openai
23
+
24
+ Forge Verify guardrail for the [OpenAI Agents SDK](https://github.com/openai/openai-agents-python). Verifies every AI agent tool call against your policies **before** execution.
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ pip install forge-openai
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ```python
35
+ import os
36
+ from agents import Agent, Runner, function_tool
37
+ from forge_openai import forge_tool_guardrail, forge_protect
38
+
39
+ os.environ["VERITERA_API_KEY"] = "vt_live_..."
40
+ os.environ["OPENAI_API_KEY"] = "sk-..."
41
+
42
+ # Define your tools
43
+ @function_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
+ @function_tool
49
+ def delete_record(record_id: str) -> str:
50
+ """Delete a database record."""
51
+ return f"Deleted {record_id}"
52
+
53
+ @function_tool
54
+ def read_balance() -> str:
55
+ """Check account balance."""
56
+ return "Balance: $50,000"
57
+
58
+ # Protect all tools with Forge — one line
59
+ agent = Agent(
60
+ name="finance-bot",
61
+ instructions="You help with financial operations.",
62
+ tools=forge_protect(
63
+ send_payment, delete_record, read_balance,
64
+ policy="finance-controls",
65
+ skip_actions=["read_balance"], # read-only tools don't need verification
66
+ ),
67
+ )
68
+
69
+ # Run the agent — Forge checks every tool call automatically
70
+ result = await Runner.run(agent, "Send $500 to vendor@acme.com")
71
+ ```
72
+
73
+ ## How It Works
74
+
75
+ 1. Your agent decides to call a tool (e.g. `send_payment`)
76
+ 2. **Before execution**, Forge checks the action against your policies
77
+ 3. If **approved**: the tool runs normally
78
+ 4. If **denied**: the LLM receives a denial message and can explain why to the user
79
+
80
+ No tool ever executes without verification. Every decision is logged with a cryptographic proof.
81
+
82
+ ## Per-Tool Guardrail
83
+
84
+ ```python
85
+ from forge_openai import forge_tool_guardrail
86
+
87
+ guardrail = forge_tool_guardrail(policy="email-controls")
88
+
89
+ @function_tool(tool_input_guardrails=[guardrail])
90
+ def send_email(to: str, subject: str, body: str) -> str:
91
+ """Send an email."""
92
+ return f"Email sent to {to}"
93
+ ```
94
+
95
+ ## Full Control
96
+
97
+ ```python
98
+ from forge_openai import ForgeGuardrail
99
+
100
+ forge = ForgeGuardrail(
101
+ api_key="vt_live_...",
102
+ agent_id="prod-finance-bot",
103
+ policy="finance-controls",
104
+ fail_closed=True,
105
+ skip_actions=["read_balance", "get_time"],
106
+ on_blocked=lambda action, reason, result: print(f"BLOCKED: {action} — {reason}"),
107
+ on_verified=lambda action, result: print(f"APPROVED: {action}"),
108
+ )
109
+
110
+ agent = Agent(
111
+ name="finance-bot",
112
+ tools=forge.protect(send_payment, delete_record),
113
+ input_guardrails=[forge.input_guardrail()], # also screen agent input
114
+ )
115
+ ```
116
+
117
+ ## Environment Variables
118
+
119
+ | Variable | Description |
120
+ |----------|-------------|
121
+ | `VERITERA_API_KEY` | Your Forge API key (starts with `vt_live_` or `vt_test_`) |
122
+
123
+ ## License
124
+
125
+ MIT — [Veritera AI](https://veritera.ai)
@@ -0,0 +1,9 @@
1
+ README.md
2
+ pyproject.toml
3
+ forge_openai/__init__.py
4
+ forge_openai/guardrail.py
5
+ forge_openai.egg-info/PKG-INFO
6
+ forge_openai.egg-info/SOURCES.txt
7
+ forge_openai.egg-info/dependency_links.txt
8
+ forge_openai.egg-info/requires.txt
9
+ forge_openai.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ veritera>=0.2.0
2
+ openai-agents>=0.1.0
@@ -0,0 +1 @@
1
+ forge_openai
@@ -0,0 +1,33 @@
1
+ [project]
2
+ name = "forge-openai"
3
+ version = "0.1.0"
4
+ description = "Forge Verify guardrail for OpenAI Agents SDK — 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", "openai", "agents", "guardrail", "verification", "ai-safety"]
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
+ "openai-agents>=0.1.0",
21
+ ]
22
+
23
+ [project.urls]
24
+ Homepage = "https://veritera.ai"
25
+ Documentation = "https://veritera.ai/docs"
26
+ Repository = "https://github.com/VeriteraAI/forge-openai"
27
+
28
+ [build-system]
29
+ requires = ["setuptools>=68.0"]
30
+ build-backend = "setuptools.build_meta"
31
+
32
+ [tool.setuptools.packages.find]
33
+ include = ["forge_openai*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+