Skip to content

feat(samples): add TrustBoost PII sanitization sample for AP2 + x402 …#267

Open
teodorofodocrispin-cmyk wants to merge 5 commits into
google-agentic-commerce:mainfrom
teodorofodocrispin-cmyk:feat/add-trustboost-pii-sanitization-sample
Open

feat(samples): add TrustBoost PII sanitization sample for AP2 + x402 …#267
teodorofodocrispin-cmyk wants to merge 5 commits into
google-agentic-commerce:mainfrom
teodorofodocrispin-cmyk:feat/add-trustboost-pii-sanitization-sample

Conversation

@teodorofodocrispin-cmyk
Copy link
Copy Markdown

Description

Adds a Python sample showing how an autonomous AI agent sanitizes PII
with TrustBoost before completing an AP2 + x402 payment on Solana —
no human intervention required.

AP2 defines how agents pay. TrustBoost defines how agents protect the
payload before the LLM sees it. Together they complete the privacy +
payment stack for autonomous agents.

  • Agent discovers TrustBoost via /.well-known/agent-card.json (AP2 compatible)
  • Agent calls /sanitize without payment -> receives HTTP 402 with x402 instructions
  • Agent pays autonomously in USDC on Solana and retries
  • TrustBoost sanitizes PII and anchors proof on Solana mainnet
  • Proof verifiable at /verify/{anchor_tx} — EU AI Act compliant

8 languages: EN, ES-LATAM, PT-BR, DE, JA, FR, IT, KO
LATAM identifiers (RFC, CPF, CUIT) not covered by standard regex tools.

Health check: curl https://api.trustboost.dev/health
→ {"status":"ok","version":"2.6.0"}

Fixes #N/A — new sample addition

@teodorofodocrispin-cmyk teodorofodocrispin-cmyk requested a review from a team as a code owner May 24, 2026 04:48
@google-cla
Copy link
Copy Markdown

google-cla Bot commented May 24, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a Python sample demonstrating PII sanitization via the TrustBoost API and the x402 protocol. The review feedback suggests refactoring the sanitization flow to eliminate redundant network requests and prevent potential index errors. Additionally, it recommends using safer dictionary access to avoid key errors and catching specific exceptions rather than a broad exception class for better error handling.

Comment on lines +25 to +37
# x402 flow: call without payment -> HTTP 402 -> pay -> retry
probe = requests.post(f"{TRUSTBOOST_URL}/sanitize", json={"text": text}, timeout=10)
if probe.status_code == 402:
x402 = probe.json().get("x402", {})
accepts = x402.get("accepts", [{}])[0]
print(f"[x402] HTTP 402 - {accepts.get('amount')} {accepts.get('currency')} on {accepts.get('network')}")
print(f"[x402] Paying autonomously with tx_hash={TX_HASH}")

r = requests.post(
f"{TRUSTBOOST_URL}/sanitize",
json={"text": text, "tx_hash": TX_HASH, "wallet_address": WALLET, "context": context},
timeout=30
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation always performs a second POST request even if the first one succeeds (e.g., in trial mode). Additionally, the first request is missing the context parameter, and there is a risk of an IndexError if the accepts list is empty. Refactoring the logic to reuse the first response and ensuring the context is sent initially improves efficiency and robustness.

    # x402 flow: call without payment -> HTTP 402 -> pay -> retry
    payload = {"text": text, "context": context}
    r = requests.post(f"{TRUSTBOOST_URL}/sanitize", json=payload, timeout=10)
    if r.status_code == 402:
        x402 = r.json().get("x402", {})
        accepts_list = x402.get("accepts", [])
        if accepts_list:
            acc = accepts_list[0]
            print(f"[x402] HTTP 402 - {acc.get('amount')} {acc.get('currency')} on {acc.get('network')}")
        print(f"[x402] Paying autonomously with tx_hash={TX_HASH}")
        payload.update({"tx_hash": TX_HASH, "wallet_address": WALLET})
        r = requests.post(f"{TRUSTBOOST_URL}/sanitize", json=payload, timeout=30)

Comment on lines +16 to +18
print(f"[TrustBoost] {card['name']} v{card['version']}")
print(f"[TrustBoost] Languages: {card['languages']}")
print(f"[TrustBoost] Compliance: {card['compliance']}")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

Accessing dictionary keys directly can raise a KeyError if the API response is missing expected fields. Using .get() provides a safer way to handle potentially missing data in this sample.

Suggested change
print(f"[TrustBoost] {card['name']} v{card['version']}")
print(f"[TrustBoost] Languages: {card['languages']}")
print(f"[TrustBoost] Compliance: {card['compliance']}")
print(f"[TrustBoost] {card.get('name', 'Unknown')} v{card.get('version', '?')}")
print(f"[TrustBoost] Languages: {card.get('languages', [])}")
print(f"[TrustBoost] Compliance: {card.get('compliance', [])}")

print(f"\n[{t['lang']}] {t['text']}")
try:
sanitize_pii(t["text"], t["ctx"])
except Exception as e:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

Catching the broad Exception class is generally discouraged as it can hide unexpected bugs. It is better to catch specific exceptions like requests.exceptions.RequestException to handle expected network or API errors.

Suggested change
except Exception as e:
except requests.exceptions.RequestException as e:

@teodorofodocrispin-cmyk
Copy link
Copy Markdown
Author

Note for reviewers — BIOME_LINT failure is pre-existing.

All lint errors are in code/web-client/src/ — TypeScript/React
files that existed before this PR was opened.

This PR only adds Python files:
→ agent.py ✅ (Python — not in scope for BIOME_LINT)
→ README.md ✅ (MARKDOWN now passing)
→ requirements.txt ✅ (plain text)

Checks directly related to this PR:
✅ SPELL_CODESPELL — Pass
✅ MARKDOWN — Pass
✅ GITLEAKS — Pass
✅ GIT_MERGE_CONFLICT_MARKERS — Pass
✅ PRE_COMMIT — Pass

The BIOME_LINT errors are pre-existing in the repository
and not introduced by this contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant