Metadata-Version: 2.4
Name: autogen-rubric
Version: 1.11.0
Summary: Post-quantum AI decision attestation for AutoGen, LlamaIndex, and any Python AI pipeline
Author-email: Scott Sims <Scott@Rubric-Protocol.com>
License: MIT
Project-URL: Homepage, https://rubric-protocol.com
Project-URL: Documentation, https://rubric-protocol.com/docs
Project-URL: Repository, https://github.com/0xsims/autogen-rubric
Keywords: ai,attestation,compliance,autogen,llamaindex,post-quantum,hedera,eu-ai-act,ml-dsa,audit
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Provides-Extra: autogen
Requires-Dist: pyautogen>=0.2.0; extra == "autogen"
Provides-Extra: llama
Requires-Dist: llama-index>=0.10.0; extra == "llama"
Provides-Extra: haystack
Requires-Dist: haystack-ai>=2.0; extra == "haystack"
Requires-Dist: httpx; extra == "haystack"
Provides-Extra: sk
Requires-Dist: semantic-kernel>=1.0; extra == "sk"
Provides-Extra: pydantic
Requires-Dist: pydantic-ai-slim>=0.1; extra == "pydantic"
Requires-Dist: httpx; extra == "pydantic"
Provides-Extra: agents
Requires-Dist: openai-agents>=0.1; extra == "agents"
Requires-Dist: httpx; extra == "agents"
Provides-Extra: adk
Requires-Dist: google-adk>=1.0; extra == "adk"
Requires-Dist: httpx; extra == "adk"
Provides-Extra: strands
Requires-Dist: strands-agents>=1.0; extra == "strands"
Requires-Dist: httpx; extra == "strands"
Provides-Extra: all
Requires-Dist: pyautogen>=0.2.0; extra == "all"
Requires-Dist: llama-index>=0.10.0; extra == "all"
Requires-Dist: haystack-ai>=2.0; extra == "all"
Requires-Dist: semantic-kernel>=1.0; extra == "all"
Requires-Dist: pydantic-ai-slim>=0.1; extra == "all"
Requires-Dist: openai-agents>=0.1; extra == "all"
Requires-Dist: google-adk>=1.0; extra == "all"
Requires-Dist: strands-agents>=1.0; extra == "all"
Requires-Dist: httpx; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Provides-Extra: cva-sign
Requires-Dist: eth-account>=0.10; extra == "cva-sign"

# autogen-rubric

**One line. Every AI decision attested.**

Post-quantum attestation for OpenAI, Anthropic, LlamaIndex, LangChain, AutoGen, CrewAI, and more — anchored permanently to Hedera Consensus Service. Built for EU AI Act Article 12 compliance.

    pip install autogen-rubric


## Get a free API key

    https://rubric-protocol.com/get-started

Takes 10 seconds. Key is shown instantly — no waiting for email.



## Auto-Instrumentation

Add one line at app startup. Every AI decision is attested automatically.

    import autogen_rubric as rubric

    rubric.instrument(
        api_key="your-rubric-api-key",
        pipeline_id="my-ai-app",
    )

    # Everything below is now attested automatically
    # OpenAI, Anthropic, LlamaIndex, LangChain, AutoGen, CrewAI...

Rubric detects which frameworks are installed and patches them at the framework level. Every LLM call, every agent decision, every tool use is cryptographically signed, Merkle-aggregated, and anchored to Hedera Consensus Service.

Get a free API key at rubric-protocol.com.

## What instrument() does

- Detects installed frameworks automatically
- Patches each at the class level — no per-call code required
- Submits attestations asynchronously — zero latency impact
- Stores payload keys to ./rubric_keys/ by default (configurable)
- Returns an Instrumentation object for status and shutdown

## Supported Frameworks

    # Auto-detects and instruments any of:
    # openai, anthropic, langchain, llama_index,
    # autogen, crewai, langgraph, dspy,
    # pydantic_ai, google.adk, openai-agents

    # NOT auto-instrumented - use the explicit integrations:
    #   Haystack:        RubricHaystackComponent / rubric_haystack_callback
    #   Semantic Kernel: get_sk_rubric_plugin / rubric_semantic_kernel_filter
    #   Strands:         instrument_strands / RubricStrandsHooks

## Configuration

    rubric.instrument(
        api_key="your-rubric-api-key",
        pipeline_id="loan-underwriting",
        node="eu",
        tier="standard",  # or "developer", "enterprise"
        enterprise=True,  # legacy alias
        payload_key_dir="/secure/keys",
        on_payload_key=my_vault_store,
        background_queue=True,
        flush_interval=5.0,
    )

## Payload Key Storage

Every attestation is encrypted with a customer-held AES-256-GCM key. The key is returned once and never stored by Rubric. By default keys are written to ./rubric_keys/{attestation_id}.key

For production, provide a custom handler:

    def store_in_vault(attestation_id, payload_key):
        my_secrets_manager.store(f"rubric:{attestation_id}", payload_key)

    rubric.instrument(api_key="...", on_payload_key=store_in_vault)

Never log the payload key. Never store it next to the attestation record.

## Explicit Attestation

For custom inference layers or fine-grained control:

    from autogen_rubric import RubricClient

    client = RubricClient(api_key="your-key", tier="standard", background_queue=True)

    result = client.attest(
        agent_id="custom-model-v2",
        output="Application approved. Confidence: 0.94.",
        confidence=0.94,
        pipeline_id="loan-underwriting",
    )

## EU AI Act Article 12

Every attested decision receives:
- ML-DSA-65 post-quantum signature (NIST FIPS 204)
- Merkle inclusion in a SHA3-256 forest
- HCS consensus timestamp from an independent network
- Poseidon2 ZK inclusion proof (customer-retrievable)
- AES-256-GCM encrypted payload (customer-held key)

The audit trail is independently verifiable without Rubric involvement.

## C2PA verdict attestation — Google Credentio (since 1.11.0)

Google's Credentio validates C2PA Content Credentials locally. The verdict dies with the process. These helpers make it durable: post-quantum signed, anchored to Hedera, verifiable by anyone forever.

```python
from autogen_rubric import build_claim, sign_claim, attest_claim

# verdict: Credentio crjson output (or a normalized {code, statusCodes} dict)
claim = build_claim(
    verdict,
    asset_bytes=open("photo.jpg", "rb").read(),
    media_type="image/jpeg",
    trust_list_path="c2pa-trust-list.pem",
    engine_version="live-at-head",
    engine_commit="4ac69fc5",
)

# optional: eip191-sign so the record reads eip191-verified, not
# recorded-not-verified. pip install autogen-rubric[cva-sign]
sign_claim(claim, private_key=EVM_KEY)

# $0.05 USDC over x402. `post` is any x402-capable callable:
# post(url, json_body) handling the 402 challenge -> retry handshake.
receipt = attest_claim(claim, post=my_x402_post)
print(receipt["attestationId"], receipt["verify"])
```

The record carries the trust list hash, engine commit, signer chain fingerprint, and verdict codes verbatim. Tier A ($0.25, Rubric runs Credentio server-side as validator of record) is a raw POST to `/v1/c2pa/verdict-attest` — no SDK needed. Spec: rubric-cva/0.1.

## Links

- Documentation: https://rubric-protocol.com/docs
- API keys: https://rubric-protocol.com/get-started
- Website: https://rubric-protocol.com
- Support: Scott@Rubric-Protocol.com
## Agent payment attestation — AWS Bedrock AgentCore Payments (since 1.10.0)

AgentCore Payments gives a Bedrock agent a wallet, a spend policy and an audit trail. The trail is logs: written by the same account that made the payment, after the payment, and self-asserted — the same gap that makes any agent's own record of its own spending weak evidence in a dispute.

`attest_before_spend` wraps the payment callable and writes the decision **before** the money moves. In the default `mode="enforce"`, a decision attestation that cannot be written blocks the spend: there is no path where value moves and no record exists. A log written afterwards can always be the one that never got written.

```python
from autogen_rubric import attest_before_spend

# Any payment callable: an AgentCore Payments client method, an x402 fetch
# wrapper, a treasury API. The binding point is the function, not the vendor.
pay = attest_before_spend(
    agentcore_payments.pay,          # payment_fn(params, ctx) -> result
    api_key="YOUR_RUBRIC_API_KEY",
    agent_id="procurement-agent",
    mandate_ref="mandate-8841",      # ties every spend to the authorization
    rail="x402",
    mode="enforce",                  # no attestation, no payment
)

out = pay({"to": "0xaB67...54ca", "amount": "100000"},
          intent="renew data subscription",
          payee="acme-data", amount="100000", currency="USDC")
```

Two attestations per spend: `AGENT_SPEND_DECISION` before the call and `AGENT_SPEND_RECEIPT` after it, so an authorized-but-never-settled payment is distinguishable from one that went through — a distinction the wallet balance alone cannot make.

Payment parameters are encrypted at rest under a per-attestation key Rubric returns and does not retain; `paramsHash` is the public commitment. You can prove to a counterparty exactly what the agent was instructed to pay without disclosing the instruction to anyone else, and `verify_spend_commitment(record, payload_key, expected_commitment)` checks it offline.

Any `mode` other than `"enforce"` — `"observe"`, say — records without gating while you evaluate. Everything else — wallet custody, spend limits, approval policy — stays with AgentCore; this adds the evidence layer those controls are judged against.

## Sandbox execution attestation (new in 1.8.1)

Agent sandboxes (LangSmith Sandboxes, E2B, Modal, Daytona) contain the blast radius of agent-executed code. `RubricSandbox` proves what happened inside: every command and output digest, every artifact hash, and the base snapshot — signed with ML-DSA-65 and anchored to Hedera at teardown. Sandboxes are the containment layer; this is the flight recorder.

```python
from langsmith.sandbox import SandboxClient
from autogen_rubric import RubricClient, RubricSandbox

rubric = RubricClient(api_key="YOUR_RUBRIC_API_KEY")

with SandboxClient().sandbox() as sb:
    with RubricSandbox(rubric, sb, agent_id="analysis-agent", snapshot_ref="img:py3.12-base") as rsb:
        rsb.run("python clean_dataset.py")
        rsb.run("python generate_report.py")
        rsb.register_artifact("report.pdf", open("report.pdf", "rb").read())
# On exit: one SANDBOX_RUN attestation — command digests, artifact hashes, snapshot lineage —
# independently verifiable at rubric-protocol.com/verify, years after the sandbox is gone.
```

Works with any sandbox object exposing `run()`; all other methods pass through untouched. For already-completed runs, `attest_sandbox_run(client, commands, artifacts=...)` is the one-shot form.
