Metadata-Version: 2.4
Name: aer1-crewai
Version: 0.1.0
Summary: AER-1 verifiable workflow receipts for CrewAI
License: Apache-2.0
Project-URL: Homepage, https://datatracker.ietf.org/doc/draft-zambo-aer1/
Keywords: aer-1,crewai,ai-agents,verifiable-receipts,audit,tracing
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: crewai>=1.0.0

# aer1-crewai

AER-1 verifiable workflow receipts for [CrewAI](https://github.com/crewAIInc/crewAI).

Attach one listener and every crew run emits a hash-chained,
offline-verifiable **verifiable workflow receipt** (AER-1, Section 8):
what the crew did, in what order, with per-step hashes and a Merkle root
over the whole run. It hooks CrewAI's own event bus, so there is no
monkey-patching, no behavior change, and no network calls. The listener
only observes. It complements CrewAI's built-in observability; it does
not replace it.

## Install

```bash
pip install aer1-crewai
```

## Use it (two lines)

```python
from aer1_crewai import AER1CrewAIListener
from crewai import Crew

listener = AER1CrewAIListener(goal="Research AER-1 adoption")  # line 1

crew = Crew(agents=[...], tasks=[...])
result = crew.kickoff()
receipt = listener.finalize(final_answer=result.raw)            # line 2
assert listener.verify(receipt) == []                           # VALID
listener.save("receipt.json", workflow=receipt)
```

Keep the `listener` referenced for the whole process. Constructing it
registers its handlers on CrewAI's global event bus; dropping the
reference can unregister them.

That is the whole integration. The receipt is a plain JSON object you
can store, ship to an auditor, or render in a UI.

## What gets recorded

One receipt step per observed event, in arrival order:

- `ToolUsageFinishedEvent` becomes a step named for the tool, with the
  tool arguments, output, agent role, and task name hashed in, and
  `started_at` / `ended_at` taken from the event's own timestamps.
- `ToolUsageErrorEvent` becomes the same step with `status: "error"`.
- `TaskCompletedEvent` / `TaskFailedEvent` become `tool: "task"` steps
  carrying the task name and output.

## What the receipt contains

Workflow level (AER-1 Section 8, Table 2):

- `type`, `version`, `workflow_id`, `receipt_id`, `session_id`
- `goal`, `status`
- `steps`: one record per observed event, seq 1..n in order
- `merkle_root`: Section 8.1 root over the ordered step receipt ids
- `output_hash`: SHA-256 of the final answer
- `verify_url`: where the verification procedure is documented

Step level (AER-1 Section 8, Table 3):

- `seq`, `receipt_id`, `tool`, `receipt_hash`, `started_at`, `ended_at`, `status`

Each step `receipt_hash` is SHA-256 over the canonical JSON of what the
step actually did. The hash commits to the content; the receipt stays
compact.

## Verification

`listener.verify(receipt)` runs the full offline check and returns a
list of failure reasons, empty when valid:

- all Table 2 / Table 3 members present and well-formed
- `seq` values exactly 1..n in order, no gaps
- no two steps share a `receipt_id` (MM-1)
- `merkle_root` matches the recomputed Section 8.1 root
- strict RFC 3339 timestamps, lowercase UUIDs, 64-char hex digests

Tamper with any field and verification fails. Try it:

```python
receipt["steps"][0]["tool"] = ""
assert listener.verify(receipt) != []  # fails, as it should
```

## Notes

- One listener observes every crew run in the process. Call `reset()`
  between runs if you want one receipt per run from a shared listener.
- `session_id` defaults to a fresh UUID per listener; pass your own to
  correlate receipts across runs.
- `verify_url` defaults to the AER-1 specification page; point it at
  your own verifier in production.
- If `final_answer` is omitted, `finalize()` uses the output captured
  from the crew kickoff completed event when available.

## Spec

AER-1: Agent Execution Receipts, `draft-zambo-aer1`,
https://datatracker.ietf.org/doc/draft-zambo-aer1/

## License

Apache-2.0
