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

# aer1-openai-agents

AER-1 verifiable workflow receipts for the OpenAI Agents SDK. One line of
integration turns any traced agent run into an offline-verifiable receipt
(draft-zambo-aer1, Section 8) covering every model call, tool call, and
agent step.

## The AER-1 framework collector family

The OpenAI Agents SDK collector in the AER-1 framework collector family. Any agent running on these frameworks can emit verifiable AER-1 execution receipts: every step recorded, hash-chained, one Merkle root over the whole run.

- [aer1-smolagents](https://pypi.org/project/aer1-smolagents/) — SmolAgents agents via step callbacks
- [aer1-openai-agents](https://pypi.org/project/aer1-openai-agents/) — the OpenAI Agents SDK via its TracingProcessor
- [aer1-crewai](https://pypi.org/project/aer1-crewai/) — CrewAI crews via the event bus
- [aer1-langgraph](https://pypi.org/project/aer1-langgraph/) — LangGraph swarms via callback handler
- [aer1-autogen](https://pypi.org/project/aer1-autogen/) — AutoGen multi-agent chats

Plus the [`aer1`](https://pypi.org/project/aer1/) metapackage: `pip install aer1`, then `import aer1; aer1.instrument()`. One line, zero config, auto-detects your framework.

## Install

```bash
pip install aer1-openai-agents
```

## Use (copy, paste, run — no API keys needed)

```python
# pip install aer1-openai-agents
import asyncio
from agents import Agent, Runner, function_tool
from agents.testing.model import ScriptedModel, assistant_message, function_call
from aer1_openai_agents import install

@function_tool
def get_weather(city: str) -> str:
    """Get the weather for a city."""
    return f"Sunny in {city}"

async def main():
    processor = install(goal="Check the weather")
    scripted = ScriptedModel(steps=[
        [function_call("get_weather", {"city": "Austin"}, call_id="call_1")],
        [assistant_message("It is sunny in Austin.")],
    ])
    agent = Agent(name="weather", instructions="Answer briefly.",
                  tools=[get_weather])
    agent.model = scripted  # swap for your real model in production

    result = await Runner.run(agent, "What is the weather in Austin?")
    receipt = processor.finalize(final_answer=result.final_output)
    assert processor.verify(receipt) == []  # VALID
    processor.save("receipt.json", receipt)

asyncio.run(main())
```

`install()` registers the receipt processor directly. Prefer the
standard path in production if you also want the SDK's own tracing
dashboard:

```python
from agents.tracing import add_trace_processor
from aer1_openai_agents import AER1TracingProcessor

processor = AER1TracingProcessor(goal="Summarize the quarterly report")
add_trace_processor(processor)
```

`install()` additionally skips the SDK's backend trace exporter, so no
trace data leaves your machine and proxy-heavy environments cannot fail
at registration time. Either way the integration is: register the
processor, run the agent, finalize. The processor implements the SDK's
`TracingProcessor` interface, the same pattern other observability
integrations use.

## What you get

A JSON receipt with the AER-1 Section 8 workflow members:

- `type`, `version`, `workflow_id`, `receipt_id`, `session_id`
- `goal`, `status`, `output_hash`, `verify_url`
- `steps`: one per ended SDK span (model calls, tool calls, agent
  boundaries, handoffs), each with `seq`, `receipt_id`, `tool`,
  `receipt_hash`, `started_at`, `ended_at`, `status`
- `merkle_root`: the Section 8.1 root over the ordered step receipt ids

Each step's `receipt_hash` is SHA-256 over the canonical JSON of the
span's observed content, so the hash commits to what the agent actually
did. `verify()` re-checks everything offline: all 14 Table 2/3 member
requirements, seq ordering 1..n, no duplicate step receipt ids, and the
Merkle root recomputed.

## Verify

```python
from aer1_openai_agents import verify_workflow_receipt

failures = verify_workflow_receipt(receipt)
assert failures == []  # empty means valid
```

The processor never touches the network and never changes agent behavior.
It only observes.

## Spec

Based on draft-zambo-aer1, Section 8 (verifiable workflow receipts).
Verification procedure documented at
https://datatracker.ietf.org/doc/draft-zambo-aer1/
