agentproof-sim 0.1.1__py3-none-any.whl
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.
- agentproof/__init__.py +41 -0
- agentproof/adapters/__init__.py +14 -0
- agentproof/adapters/base.py +19 -0
- agentproof/adapters/langchain.py +95 -0
- agentproof/adapters/native.py +23 -0
- agentproof/adapters/openai_agents.py +62 -0
- agentproof/api.py +99 -0
- agentproof/cli.py +172 -0
- agentproof/core/clock.py +18 -0
- agentproof/core/effects.py +109 -0
- agentproof/core/events.py +63 -0
- agentproof/core/faults.py +294 -0
- agentproof/core/invariant.py +109 -0
- agentproof/core/redaction.py +32 -0
- agentproof/core/result.py +109 -0
- agentproof/core/runner.py +216 -0
- agentproof/core/scenario.py +13 -0
- agentproof/core/trace.py +58 -0
- agentproof/core/world.py +126 -0
- agentproof/invariants/__init__.py +21 -0
- agentproof/invariants/builtin.py +96 -0
- agentproof/invariants/temporal.py +5 -0
- agentproof/mutations/__init__.py +61 -0
- agentproof/mutations/base.py +57 -0
- agentproof/mutations/duplication.py +15 -0
- agentproof/mutations/ordering.py +10 -0
- agentproof/mutations/state.py +15 -0
- agentproof/mutations/timing.py +9 -0
- agentproof/mutations/tool_faults.py +58 -0
- agentproof/py.typed +1 -0
- agentproof/pytest_plugin.py +40 -0
- agentproof/replay/player.py +74 -0
- agentproof/replay/recorder.py +29 -0
- agentproof/replay/schema.py +24 -0
- agentproof/reporting/__init__.py +7 -0
- agentproof/reporting/console.py +34 -0
- agentproof/reporting/json_report.py +47 -0
- agentproof/reporting/junit.py +66 -0
- agentproof/tools/definition.py +26 -0
- agentproof/tools/invocation.py +11 -0
- agentproof/tools/registry.py +154 -0
- agentproof_sim-0.1.1.dist-info/METADATA +407 -0
- agentproof_sim-0.1.1.dist-info/RECORD +46 -0
- agentproof_sim-0.1.1.dist-info/WHEEL +4 -0
- agentproof_sim-0.1.1.dist-info/entry_points.txt +5 -0
- agentproof_sim-0.1.1.dist-info/licenses/LICENSE +18 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: agentproof-sim
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Stateful simulation and fault-injection testing for AI agents that take actions through tools.
|
|
5
|
+
Project-URL: Homepage, https://github.com/rohansonawane/agentproof
|
|
6
|
+
Project-URL: Documentation, https://github.com/rohansonawane/agentproof/tree/main/docs
|
|
7
|
+
Project-URL: Issues, https://github.com/rohansonawane/agentproof/issues
|
|
8
|
+
Author-email: Rohan Sonawane <rohansonawane28@gmail.com>
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,fault-injection,reliability,simulation,testing
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Testing
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: click<9,>=8.1
|
|
22
|
+
Requires-Dist: pydantic<3,>=2.12
|
|
23
|
+
Requires-Dist: rich<16,>=13
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: build<2,>=1.2; extra == 'dev'
|
|
26
|
+
Requires-Dist: httpx2[brotli]<3,>=2.12; extra == 'dev'
|
|
27
|
+
Requires-Dist: langchain<2,>=1.3; extra == 'dev'
|
|
28
|
+
Requires-Dist: langgraph<2,>=1.2; extra == 'dev'
|
|
29
|
+
Requires-Dist: mypy<2,>=1.13; extra == 'dev'
|
|
30
|
+
Requires-Dist: openai-agents<1,>=0.22; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-asyncio<2,>=0.24; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest-cov<8,>=5; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest<10,>=8; extra == 'dev'
|
|
34
|
+
Requires-Dist: ruff<1,>=0.8; extra == 'dev'
|
|
35
|
+
Requires-Dist: twine<8,>=7; extra == 'dev'
|
|
36
|
+
Provides-Extra: langchain
|
|
37
|
+
Requires-Dist: langchain<2,>=1.3; extra == 'langchain'
|
|
38
|
+
Requires-Dist: langgraph<2,>=1.2; extra == 'langchain'
|
|
39
|
+
Provides-Extra: openai
|
|
40
|
+
Requires-Dist: httpx2[brotli]<3,>=2.12; extra == 'openai'
|
|
41
|
+
Requires-Dist: openai-agents<1,>=0.22; extra == 'openai'
|
|
42
|
+
Provides-Extra: test
|
|
43
|
+
Requires-Dist: pytest-asyncio<2,>=0.24; extra == 'test'
|
|
44
|
+
Requires-Dist: pytest-cov<8,>=5; extra == 'test'
|
|
45
|
+
Requires-Dist: pytest<10,>=8; extra == 'test'
|
|
46
|
+
Description-Content-Type: text/markdown
|
|
47
|
+
|
|
48
|
+
# AgentProof
|
|
49
|
+
|
|
50
|
+
[](https://github.com/rohansonawane/agentproof/actions/workflows/ci.yml)
|
|
51
|
+
|
|
52
|
+
AgentProof is a Python testing framework for AI agents that take actions through tools.
|
|
53
|
+
|
|
54
|
+
It helps you answer a practical release question:
|
|
55
|
+
|
|
56
|
+
> If a tool call times out, returns bad data, gets retried, or receives stale state, does my agent still protect the real world?
|
|
57
|
+
|
|
58
|
+
AgentProof creates an isolated simulated world, exposes tools to your agent, injects realistic faults, records the side effects that actually commit, and checks deterministic invariants over the result.
|
|
59
|
+
|
|
60
|
+
It is useful for agents that can change things:
|
|
61
|
+
|
|
62
|
+
- refunding payments;
|
|
63
|
+
- booking or canceling appointments;
|
|
64
|
+
- sending emails or support replies;
|
|
65
|
+
- changing CRM records;
|
|
66
|
+
- modifying files or repositories;
|
|
67
|
+
- running internal operations or DevOps workflows.
|
|
68
|
+
|
|
69
|
+
See [Real-World Use Cases](docs/use-cases.md) for concrete examples and invariants.
|
|
70
|
+
See [Real-Project Evidence](docs/real-project-evidence.md) for pinned public
|
|
71
|
+
agent-related projects that AgentProof has been run against.
|
|
72
|
+
|
|
73
|
+
AgentProof does not prove that an agent is universally safe or correct. It gives you repeatable tests for dangerous action-level failures before they reach production.
|
|
74
|
+
|
|
75
|
+
## Why This Exists
|
|
76
|
+
|
|
77
|
+
Most agent evaluations look at text: Was the answer helpful? Did the model choose the right response?
|
|
78
|
+
|
|
79
|
+
That is not enough for tool-using agents. The embarrassing failures are often stateful:
|
|
80
|
+
|
|
81
|
+
- the refund succeeded, but the agent saw a timeout and refunded again;
|
|
82
|
+
- the appointment was booked twice after a retry;
|
|
83
|
+
- the approval record changed after the agent read it;
|
|
84
|
+
- a malformed tool response caused the agent to act on the wrong amount;
|
|
85
|
+
- a duplicate event caused the same email or webhook to be sent twice.
|
|
86
|
+
|
|
87
|
+
AgentProof tests those failure modes by separating two things that production systems often blur:
|
|
88
|
+
|
|
89
|
+
- the side effect committed;
|
|
90
|
+
- the agent observed success.
|
|
91
|
+
|
|
92
|
+
That separation is what lets `timeout_after_commit` catch duplicate refunds, bookings, and similar bugs.
|
|
93
|
+
|
|
94
|
+
## Install
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pip install agentproof-sim
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The PyPI distribution is `agentproof-sim` because `agentproof` is already occupied by an unrelated package. The Python import and CLI remain stable:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
import agentproof
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Optional framework adapters are installed separately:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
pip install "agentproof-sim[openai]"
|
|
110
|
+
pip install "agentproof-sim[langchain]"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Five-Minute Quickstart
|
|
114
|
+
|
|
115
|
+
Save this as `refund_demo.py` and run `python refund_demo.py`.
|
|
116
|
+
|
|
117
|
+
The agent below is intentionally unsafe: if a refund commits but the response times out, it retries without an idempotency key.
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
import asyncio
|
|
121
|
+
from typing import Any
|
|
122
|
+
|
|
123
|
+
from agentproof import AgentTest, World, invariant
|
|
124
|
+
from agentproof.core.effects import EffectDraft
|
|
125
|
+
from agentproof.mutations import TimeoutAfterCommit
|
|
126
|
+
from agentproof.tools.definition import ToolOutcome
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
async def refund_agent(user_input: str, tools: Any) -> str:
|
|
130
|
+
del user_input
|
|
131
|
+
order = await tools.call("get_order", order_id="123")
|
|
132
|
+
try:
|
|
133
|
+
await tools.call("refund_order", order_id="123", amount=order["total"])
|
|
134
|
+
except TimeoutError:
|
|
135
|
+
# Unsafe on purpose: this retry can duplicate the refund if the first
|
|
136
|
+
# tool call committed before the timeout reached the agent.
|
|
137
|
+
await tools.call("refund_order", order_id="123", amount=order["total"])
|
|
138
|
+
return "Done"
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
suite = AgentTest(
|
|
142
|
+
agent=refund_agent,
|
|
143
|
+
adapter="native",
|
|
144
|
+
mutations=[TimeoutAfterCommit(target="refund_order", severity="high")],
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@suite.scenario(name="refund_delivered_order")
|
|
149
|
+
async def delivered_refund(world: World) -> None:
|
|
150
|
+
world.state["orders"] = {"123": {"id": "123", "status": "delivered", "total": 49.0}}
|
|
151
|
+
world.input("Refund order 123")
|
|
152
|
+
|
|
153
|
+
async def get_order(world: World, order_id: str) -> dict[str, Any]:
|
|
154
|
+
return dict(world.state["orders"][order_id])
|
|
155
|
+
|
|
156
|
+
async def refund_order(world: World, order_id: str, amount: float) -> ToolOutcome:
|
|
157
|
+
refund_id = world.next_id("refund")
|
|
158
|
+
return ToolOutcome(
|
|
159
|
+
value={"refund_id": refund_id},
|
|
160
|
+
effects=[
|
|
161
|
+
# Effects should describe work that actually committed in the
|
|
162
|
+
# simulated service. Do not infer them from tool calls alone.
|
|
163
|
+
EffectDraft(
|
|
164
|
+
type="refund.created",
|
|
165
|
+
operation="create",
|
|
166
|
+
resource=f"order:{order_id}",
|
|
167
|
+
data={"refund_id": refund_id, "order_id": order_id, "amount": amount},
|
|
168
|
+
)
|
|
169
|
+
],
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
world.tools.register(
|
|
173
|
+
name="get_order",
|
|
174
|
+
description="Return an order.",
|
|
175
|
+
input_schema={
|
|
176
|
+
"type": "object",
|
|
177
|
+
"properties": {"order_id": {"type": "string"}},
|
|
178
|
+
"required": ["order_id"],
|
|
179
|
+
},
|
|
180
|
+
handler=get_order,
|
|
181
|
+
effect="read",
|
|
182
|
+
)
|
|
183
|
+
world.tools.register(
|
|
184
|
+
name="refund_order",
|
|
185
|
+
description="Refund an order.",
|
|
186
|
+
input_schema={
|
|
187
|
+
"type": "object",
|
|
188
|
+
"properties": {"order_id": {"type": "string"}, "amount": {"type": "number"}},
|
|
189
|
+
"required": ["order_id", "amount"],
|
|
190
|
+
},
|
|
191
|
+
handler=refund_order,
|
|
192
|
+
effect="financial",
|
|
193
|
+
idempotent=False,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@invariant
|
|
198
|
+
def no_double_refunds(world: World) -> None:
|
|
199
|
+
total = world.effects.sum(type="refund.created", where={"order_id": "123"}, field="amount")
|
|
200
|
+
assert total <= 49.0, f"refunded ${total:.2f}, expected <= $49.00"
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
async def main() -> None:
|
|
204
|
+
result = await suite.run(store_artifacts=False)
|
|
205
|
+
failure = result.failures[0]
|
|
206
|
+
print(failure.status)
|
|
207
|
+
print(failure.violated_invariants)
|
|
208
|
+
print(sum(effect.data["amount"] for effect in failure.effects))
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
if __name__ == "__main__":
|
|
212
|
+
asyncio.run(main())
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Expected output includes:
|
|
216
|
+
|
|
217
|
+
```text
|
|
218
|
+
INVARIANT_FAILURE
|
|
219
|
+
['no_double_refunds']
|
|
220
|
+
98.0
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
In plain English: the first refund happened, AgentProof hid the success response and returned a timeout, the agent retried, and the invariant caught that the customer received `$98` instead of `$49`.
|
|
224
|
+
|
|
225
|
+
## How It Works
|
|
226
|
+
|
|
227
|
+
AgentProof has five core concepts:
|
|
228
|
+
|
|
229
|
+
- `World`: isolated simulated state, virtual tools, virtual clock, event queue, effect ledger, trace, and installed faults.
|
|
230
|
+
- `Tool`: the action boundary exposed to an agent.
|
|
231
|
+
- `Effect`: an explicit committed side effect such as `refund.created` or `appointment.booked`.
|
|
232
|
+
- `Mutation`: a serializable fault such as `timeout_after_commit`, `missing_field`, or `duplicate_event`.
|
|
233
|
+
- `Invariant`: deterministic Python logic that decides whether the final state is acceptable.
|
|
234
|
+
|
|
235
|
+
The effect ledger is intentionally explicit. Tool handlers return `ToolOutcome` effects after simulated work commits. AgentProof does not guess side effects merely because a tool was called.
|
|
236
|
+
|
|
237
|
+
## What AgentProof Can Catch
|
|
238
|
+
|
|
239
|
+
AgentProof is designed for failures that happen around action boundaries:
|
|
240
|
+
|
|
241
|
+
- duplicate side effects after retries;
|
|
242
|
+
- partial success hidden behind a timeout;
|
|
243
|
+
- malformed, missing, or stale tool responses;
|
|
244
|
+
- rate limits and transient tool errors;
|
|
245
|
+
- permission denial paths;
|
|
246
|
+
- duplicated user requests;
|
|
247
|
+
- delayed or duplicated scheduled events;
|
|
248
|
+
- regressions where a previously idempotent action becomes unsafe.
|
|
249
|
+
|
|
250
|
+
The most important pattern is retry-after-commit:
|
|
251
|
+
|
|
252
|
+
```text
|
|
253
|
+
1. Agent calls refund_order.
|
|
254
|
+
2. The simulated refund commits.
|
|
255
|
+
3. AgentProof raises TimeoutError instead of returning success.
|
|
256
|
+
4. The agent retries.
|
|
257
|
+
5. A second refund commits.
|
|
258
|
+
6. The invariant fails.
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Using It Safely
|
|
262
|
+
|
|
263
|
+
AgentProof runs your test code. It is not a sandbox for untrusted code.
|
|
264
|
+
|
|
265
|
+
Use it against virtual tools, fakes, local simulators, or carefully isolated staging services. Do not point AgentProof tests at production refund, email, file deletion, deployment, payment, or account-management APIs.
|
|
266
|
+
|
|
267
|
+
Recommended safety rules:
|
|
268
|
+
|
|
269
|
+
- Replace destructive real tools with AgentProof virtual tools.
|
|
270
|
+
- Keep live model tests opt-in.
|
|
271
|
+
- Use least-privilege credentials when a live provider is required.
|
|
272
|
+
- Never commit API keys, tokens, customer data, or production payloads.
|
|
273
|
+
- Review JSON, JUnit, replay, and trace artifacts before sharing them.
|
|
274
|
+
- Treat redaction as a safety net, not a full data-loss-prevention system.
|
|
275
|
+
|
|
276
|
+
AgentProof redacts obvious secret fields such as `api_key`, `authorization`, `token`, `password`, and `secret` in traces and reports. It cannot know every sensitive business field in your domain. See [SECURITY.md](SECURITY.md) for the full security model.
|
|
277
|
+
|
|
278
|
+
## Stable Mutations
|
|
279
|
+
|
|
280
|
+
Stable in this technical preview:
|
|
281
|
+
|
|
282
|
+
- `tool_timeout`
|
|
283
|
+
- `timeout_after_commit`
|
|
284
|
+
- `tool_error`
|
|
285
|
+
- `tool_latency`
|
|
286
|
+
- `rate_limited`
|
|
287
|
+
- `malformed_response`
|
|
288
|
+
- `missing_field`
|
|
289
|
+
- `duplicate_user_request`
|
|
290
|
+
- `stale_state`
|
|
291
|
+
- `state_changed_after_read`
|
|
292
|
+
- `permission_denied`
|
|
293
|
+
- `delayed_event`
|
|
294
|
+
- `duplicate_event`
|
|
295
|
+
|
|
296
|
+
Experimental:
|
|
297
|
+
|
|
298
|
+
- `duplicate_tool_result`, because agent-loop semantics differ by framework.
|
|
299
|
+
- `reorder_tool_results`, currently rejected unless a future controlled parallel result scheduler is available.
|
|
300
|
+
|
|
301
|
+
## Framework Integrations
|
|
302
|
+
|
|
303
|
+
The core package has no OpenAI or LangChain dependency.
|
|
304
|
+
|
|
305
|
+
- Native Python callables are supported by default.
|
|
306
|
+
- OpenAI Agents SDK tools are wrapped as real SDK `FunctionTool` objects.
|
|
307
|
+
- LangChain/LangGraph tools are wrapped as real LangChain `StructuredTool` objects and tested through a compiled LangGraph `StateGraph`/`ToolNode`.
|
|
308
|
+
|
|
309
|
+
Live LLM tests are opt-in only:
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
# Set OPENAI_API_KEY through your shell, CI secret manager, or local secret manager first.
|
|
313
|
+
AGENTPROOF_RUN_LIVE_TESTS=1 pytest -m live -v
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Do not put API keys in source files, shell history, issue comments, or README examples. Prefer temporary environment variables or a secret manager.
|
|
317
|
+
|
|
318
|
+
## Replay
|
|
319
|
+
|
|
320
|
+
Deterministic native failures write `repro.json` artifacts containing schema version, seed, mutation spec, initial snapshot, trace, and violated invariants.
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
agentproof replay .agentproof/runs/<run-id>/repro.json
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Replay is for deterministic reproduction of saved failures. Live LLM behavior can vary by model, provider, and time, so live results should be treated as smoke tests rather than exact replay guarantees.
|
|
327
|
+
|
|
328
|
+
## Reports And CI
|
|
329
|
+
|
|
330
|
+
Use the CLI in CI:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
agentproof run examples/refund_native/suite.py --fail-on high --json report.json --junit report.xml
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
The command exits nonzero when a failure at or above the configured severity is reproduced. That lets CI fail when AgentProof finds a high-risk behavior.
|
|
337
|
+
|
|
338
|
+
JSON and JUnit reports include scenario names, mutation names, statuses, violated invariants, failure messages, and committed effects.
|
|
339
|
+
|
|
340
|
+
For the local release-hardening gate used by this repository:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
python scripts/release_hardening.py
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
External-account checks are deliberately separate:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
# Set OPENAI_API_KEY outside the command before running the live gate.
|
|
350
|
+
AGENTPROOF_RUN_LIVE_TESTS=1 python scripts/release_hardening.py --live
|
|
351
|
+
python scripts/release_hardening.py --github
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## Real-App Smoke Test
|
|
355
|
+
|
|
356
|
+
This repository includes a repeatable smoke test against a real external LangChain app:
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
python scripts/real_project_booking_smoke.py
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
That command clones [aniket-work/Lets-Build-Online-Booking-System-Using-AI-Agents](https://github.com/aniket-work/Lets-Build-Online-Booking-System-Using-AI-Agents), checks out a pinned commit, wraps its real `book_appointment` tool, and verifies AgentProof catches duplicate bookings caused by retry-after-timeout.
|
|
363
|
+
|
|
364
|
+
Expected summary:
|
|
365
|
+
|
|
366
|
+
```text
|
|
367
|
+
baseline: 1 appointment, PASS
|
|
368
|
+
timeout_after_commit: 2 appointments, INVARIANT_FAILURE
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
The failure is expected. It means AgentProof detected a real duplicate side effect in a real app integration.
|
|
372
|
+
|
|
373
|
+
## Production Use
|
|
374
|
+
|
|
375
|
+
AgentProof can be used in production engineering workflows as a pre-release and regression-testing tool. It should not be used as a runtime safety boundary for live autonomous agents.
|
|
376
|
+
|
|
377
|
+
Before relying on it for a real app, define virtual or staging versions of every destructive tool, add invariants for every high-risk action, run deterministic tests in CI without API keys, and keep live model checks opt-in.
|
|
378
|
+
|
|
379
|
+
See [Production Readiness](docs/production-readiness.md) for the full checklist and current limits.
|
|
380
|
+
|
|
381
|
+
## Development
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
python -m pip install -e ".[dev]"
|
|
385
|
+
ruff format .
|
|
386
|
+
ruff check .
|
|
387
|
+
mypy src/agentproof
|
|
388
|
+
pytest -q
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Build and validate a wheel:
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
python -m build
|
|
395
|
+
twine check dist/*
|
|
396
|
+
python -m venv /tmp/agentproof-wheel-smoke
|
|
397
|
+
/tmp/agentproof-wheel-smoke/bin/python -m pip install dist/agentproof_sim-*.whl
|
|
398
|
+
/tmp/agentproof-wheel-smoke/bin/agentproof mutations
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Status
|
|
402
|
+
|
|
403
|
+
AgentProof is a `0.1.1` technical preview. Deterministic native execution, report generation, replay, adapter-boundary tests, clean wheel install, and CI are automated. Live model validation remains opt-in and depends on user-supplied credentials.
|
|
404
|
+
|
|
405
|
+
## License
|
|
406
|
+
|
|
407
|
+
Apache-2.0.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
agentproof/__init__.py,sha256=LC_lCLpmdWH73mPYgTcYi7maYqjceWO9r7r7FYS6jE4,1048
|
|
2
|
+
agentproof/api.py,sha256=_P23tsd9mleJo19gP2Wdf0GzjdWuf7zwyL_S8wTEyS8,3318
|
|
3
|
+
agentproof/cli.py,sha256=Ljn8bvw91Z0RuT8CdyKcg6kvwi1LFXvXDwjQFkvjAn0,5939
|
|
4
|
+
agentproof/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
5
|
+
agentproof/pytest_plugin.py,sha256=o_9zmdhTdIXus82HVA9e2KkjkjwuACgKKhV5DUMa5Tw,1305
|
|
6
|
+
agentproof/adapters/__init__.py,sha256=A5P5wZmpW67gHLN0-HDFA77rTEUhs9gtqY1mrir--x8,409
|
|
7
|
+
agentproof/adapters/base.py,sha256=B5r8vRB3kGLGuRqONd1q7cwgG5Uwto8h6gPOh_mrLQs,471
|
|
8
|
+
agentproof/adapters/langchain.py,sha256=FQ14dyfkeaSE9t3Tm59T1z_8qJb-Y-6wiVn_op5JZBY,3280
|
|
9
|
+
agentproof/adapters/native.py,sha256=PnfBs4psS0W6sRLtUpnwjo1NDPVIA6WnJQ91Oi8OSME,726
|
|
10
|
+
agentproof/adapters/openai_agents.py,sha256=8Cfb-mRfFM_v1oGRg2A-CLMgdcC7HgbkM3J_y9NKJyA,2140
|
|
11
|
+
agentproof/core/clock.py,sha256=OQ7-cVyJT0AwqfbCJIlr2Bn7l8-icCK9pU_aCaY-I_c,474
|
|
12
|
+
agentproof/core/effects.py,sha256=Nue40ZvVo0b9EXpfGMy-1ZNFVcGxWEWuLbjQc0aYR1Q,3308
|
|
13
|
+
agentproof/core/events.py,sha256=EWAArVaw7qp7hQJKqLQdLUk_cheltROx8OrusqR91x0,2233
|
|
14
|
+
agentproof/core/faults.py,sha256=ROpECY-LjKKYCIGWfDcYwIIFsJjmVtiMwyOKFzyP8vY,10598
|
|
15
|
+
agentproof/core/invariant.py,sha256=6fAWK9l6vDl6j_PchNPxnDjJwGKpt0Tjt2E2W8kS_fA,3649
|
|
16
|
+
agentproof/core/redaction.py,sha256=nT5Z_QWnubEMwWzySkkRZNiChALTfrH_X2OE9XN7e1c,1098
|
|
17
|
+
agentproof/core/result.py,sha256=m283g-ZXudRQgWwoCxl4fft9NrmKvUhnit9sGJ6G1Os,2940
|
|
18
|
+
agentproof/core/runner.py,sha256=auB8aeEfqdUN6fyG0R1in5MMz5VMky8JAjDYX34skLo,8114
|
|
19
|
+
agentproof/core/scenario.py,sha256=b4ZqudHvBRj9LOL5Hd6HAiC6TZ6TeVurXE-vTK7p7Ss,276
|
|
20
|
+
agentproof/core/trace.py,sha256=NJIc0NSyaUYyhsNyVG3Gz3GJHrG1k25KzimUJGnTSwU,1381
|
|
21
|
+
agentproof/core/world.py,sha256=qZB4aeLtjRI2zDUsVJRH87DKWzE5nWAik8TyPmN1kow,4387
|
|
22
|
+
agentproof/invariants/__init__.py,sha256=iTQmgeFZ69Q_5gZA6VamcyLflirDuIjVqP2smE3gsRY,395
|
|
23
|
+
agentproof/invariants/builtin.py,sha256=bSJ1u0oDGALFP9Dg34J6iYBG2_sbzEAE76BVrlxBKyY,3248
|
|
24
|
+
agentproof/invariants/temporal.py,sha256=uCnD3pTFjYAJGEZhC9GZxIxtunqfURX_hcKqLro32tY,125
|
|
25
|
+
agentproof/mutations/__init__.py,sha256=Z0j9bYR2iDSpark5ZO6pYcMue06GHrb_o3rt_HzZlUI,1727
|
|
26
|
+
agentproof/mutations/base.py,sha256=j6HKU11YxR815aywA9ypkVI7yuZxaLqoVc6bGJViOWY,1504
|
|
27
|
+
agentproof/mutations/duplication.py,sha256=cEBp2hdEieeUBQx782LOBxXilE3wGLpLtdah0vdwS0M,440
|
|
28
|
+
agentproof/mutations/ordering.py,sha256=qGZtffA2NxK8B_yecn2viVag_bGnQMptk7JjSU3QztQ,309
|
|
29
|
+
agentproof/mutations/state.py,sha256=CQe0BT6BvAZQc4dN937ui8xQ4suROxnknDuid0goe3A,489
|
|
30
|
+
agentproof/mutations/timing.py,sha256=xmFCwkUlKPk7wZq2nVQKVAoTtjF0UYUqfazw7wxbtC0,257
|
|
31
|
+
agentproof/mutations/tool_faults.py,sha256=aLtA8NdC1NEeUuRcVg2zSuon0-tPAiz4DKMdrQ8gcAs,1682
|
|
32
|
+
agentproof/replay/player.py,sha256=Mw03oD5SFXK4qIjO7ZMctmPPeApCdDjgTD1lVIa5DAs,2772
|
|
33
|
+
agentproof/replay/recorder.py,sha256=8SBO-ClzJBz60RTXevTj3PX5V270b3E2ob7JW58tQhw,958
|
|
34
|
+
agentproof/replay/schema.py,sha256=5q4AYd83DPV4QzICx9e_-T1B1IZ8POfCj11N84-EFyo,647
|
|
35
|
+
agentproof/reporting/__init__.py,sha256=RvxaSbJ17YqyLoj_pPkf-DIY6CO5oXm7Lrq-zoGBjss,328
|
|
36
|
+
agentproof/reporting/console.py,sha256=vI7L27Q1UFdLQddADpcFVAV5gv0rPTFWuKY8r37_rUc,1385
|
|
37
|
+
agentproof/reporting/json_report.py,sha256=R1AM7PUCN82nNrNzHL8YWyQQnhcfituVSGR6_Al-CGs,1802
|
|
38
|
+
agentproof/reporting/junit.py,sha256=uuAZJVduuWCQCiqeA0Y0HqD1axADZX1HTEi60nlHX3w,2332
|
|
39
|
+
agentproof/tools/definition.py,sha256=vYijUF56XUKUiIkxa73O4GxC9Z9ydmG6qalSXPgz8M8,695
|
|
40
|
+
agentproof/tools/invocation.py,sha256=G5-VrG8yVtT9vFjBU0DzytGCpnc568qlJrb7hpWEstc,271
|
|
41
|
+
agentproof/tools/registry.py,sha256=RErwrRQDtx_dsGJGtrbWjoLL1vBBULVjXAO08-I2isE,5107
|
|
42
|
+
agentproof_sim-0.1.1.dist-info/METADATA,sha256=FELEOznUq3qtv4BABAbYymOes8imRRN1TYaP-bfYl0g,15019
|
|
43
|
+
agentproof_sim-0.1.1.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
44
|
+
agentproof_sim-0.1.1.dist-info/entry_points.txt,sha256=Y82NugGARcfr8boKCqgdmvjqAzcP3I2OR2qcJx051Dk,101
|
|
45
|
+
agentproof_sim-0.1.1.dist-info/licenses/LICENSE,sha256=uxNmen3mAnYFCBKwENGBiACZwGBF0d7FxfQzzD-owZM,641
|
|
46
|
+
agentproof_sim-0.1.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
https://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Copyright 2026 AgentProof Contributors
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
https://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
|
18
|
+
|