Metadata-Version: 2.4
Name: aer1-smolagents
Version: 0.1.0
Summary: AER-1 verifiable workflow receipts for HuggingFace SmolAgents
License: Apache-2.0
Project-URL: Homepage, https://datatracker.ietf.org/doc/draft-zambo-aer1/
Keywords: aer-1,smolagents,ai-agents,verifiable-receipts,audit,tracing
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: smolagents>=1.0.0

# aer1-smolagents

AER-1 verifiable workflow receipts for [HuggingFace SmolAgents](https://github.com/huggingface/smolagents).

Attach one collector to your agent and every run emits a hash-chained,
offline-verifiable **verifiable workflow receipt** (AER-1, Section 8):
what the agent did, in what order, with per-step hashes and a Merkle root
over the whole run. No network calls, no behavior changes, the collector
only observes.

## Install

```bash
pip install aer1-smolagents
```

## Use it (two lines)

```python
from aer1_smolagents import AER1ReceiptCollector
from smolagents import ToolCallingAgent, TaskStep, ActionStep

collector = AER1ReceiptCollector(goal="Summarize the quarterly report")

agent = ToolCallingAgent(
    tools=[...],
    model=...,
    step_callbacks={TaskStep: collector, ActionStep: collector},  # line 1
)

answer = agent.run("Summarize the quarterly report")
receipt = collector.finalize(final_answer=answer)                  # line 2
assert collector.verify(receipt) == []                             # VALID
collector.save("receipt.json", workflow=receipt)
```

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 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 agent step, 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: tool name, arguments, observations, action output, and
error if any. The hash commits to the content; the receipt stays compact.

## Verification

`collector.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 collector.verify(receipt) != []  # fails, as it should
```

## Notes

- Works with `ToolCallingAgent` and `CodeAgent`. Planning steps are
  recorded as `tool: "plan"` when the agent emits them.
- Pass `goal=` to the collector; SmolAgents does not forward the task
  text through step callbacks in current versions, so the constructor
  is the reliable place for it.
- `session_id` defaults to a fresh UUID per collector; 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.

## Spec

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

## License

Apache-2.0
