Skip to content

Commit cbc17ba

Browse files
vvillait88claude
andauthored
Bump dev tooling and release 2.5.13 (#96)
Dependency refresh plus a version bump for release. ## What changed - `ruff` 0.15.22 to 0.16.0, `ty` 0.0.62 to 0.0.63, and `aiohttp`, `annotated-types`, `h2`, `httpcore2`, `httpx2` moving with the resolver - Version 2.5.12 to 2.5.13 - README example formatting (see below) - Dependabot hold on `ty` lifted Declared runtime dependencies are unchanged. ## Ruff 0.16.0 formats Markdown code blocks That reformats the README examples. Applied rather than excluding Markdown from `ruff format --check`, since narrowing the gate to avoid the tool's own style is the worse trade. ## ty hold lifted `ty` was dependabot-ignored because a pre-1.0 type checker's new rules churned CI. That problem is fixed, so it now updates on the routine cadence, and this repo matches its sibling, which never carried the ignore. ## Verification - `ruff check`, `ruff format --check`, `ty check`, `pytest` all exit 0 - 1841 tests pass, 95.36% coverage (95% floor) - `vulture agentscore_commerce/ --min-confidence 80` clean Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent c97d4f8 commit cbc17ba

4 files changed

Lines changed: 223 additions & 179 deletions

File tree

‎.github/dependabot.yml‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ updates:
1515
groups:
1616
minor-patch:
1717
update-types: ["minor", "patch"]
18-
ignore:
19-
# ty is exact-pinned: pre-1.0 type checker whose new rules churn CI;
20-
# bump deliberately, not in routine passes (2026-07-11)
21-
- dependency-name: "ty"
22-
2318
- package-ecosystem: "github-actions"
2419
directory: "/"
2520
cooldown:

‎README.md‎

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ _gate = AgentScoreGate(
7676
# proving identity. Identity is verified at settle time on the retry leg.
7777
from agentscore_commerce.payment import has_payment_header
7878

79+
7980
async def gate_on_settle(request: Request) -> None:
8081
if not has_payment_header(request):
8182
return None
@@ -97,14 +98,22 @@ async def purchase(request: Request, assess=Depends(get_agentscore_data)):
9798
```python
9899
from fastapi import FastAPI, Request
99100
from agentscore_commerce import (
100-
Checkout, CheckoutGateConfig, DiscoveryProbeConfig, PricingResult, pricing_result,
101-
SolanaMppRailSpec, StripeRailSpec, TempoRailSpec, X402BaseRailSpec,
101+
Checkout,
102+
CheckoutGateConfig,
103+
DiscoveryProbeConfig,
104+
PricingResult,
105+
pricing_result,
106+
SolanaMppRailSpec,
107+
StripeRailSpec,
108+
TempoRailSpec,
109+
X402BaseRailSpec,
102110
validate_shipping_against_policy,
103111
)
104112
from agentscore_commerce.discovery import default_a2a_services
105113

106114
app = FastAPI()
107115

116+
108117
async def _pre_validate(ctx):
109118
body = ctx.request.body or {}
110119
product = await lookup_product(body.get("product_slug"))
@@ -116,6 +125,7 @@ async def _pre_validate(ctx):
116125
)
117126
return {"product": product}
118127

128+
119129
async def _compute_pricing(ctx) -> PricingResult:
120130
return pricing_result(
121131
subtotal_cents=ctx.state["product"]["price_cents"],
@@ -124,15 +134,17 @@ async def _compute_pricing(ctx) -> PricingResult:
124134
tax_state=ctx.state["product"]["tax_state"],
125135
)
126136

137+
127138
async def _on_settled(ctx, outcome):
128139
return {"ok": True, "order_id": ctx.reference_id, "tx_hash": outcome.tx_hash}
129140

141+
130142
checkout = Checkout(
131143
rails={
132-
"tempo": TempoRailSpec(recipient=os.environ["TEMPO_RECIPIENT"]),
144+
"tempo": TempoRailSpec(recipient=os.environ["TEMPO_RECIPIENT"]),
133145
"x402_base": X402BaseRailSpec(recipient=os.environ["X402_BASE_RECIPIENT"], network="eip155:8453"),
134-
"solana_mpp":SolanaMppRailSpec(recipient=os.environ["SOLANA_RECIPIENT"], network="solana:mainnet"),
135-
"stripe": StripeRailSpec(profile_id=os.environ["STRIPE_PROFILE_ID"]),
146+
"solana_mpp": SolanaMppRailSpec(recipient=os.environ["SOLANA_RECIPIENT"], network="solana:mainnet"),
147+
"stripe": StripeRailSpec(profile_id=os.environ["STRIPE_PROFILE_ID"]),
136148
},
137149
url="https://merchant.example/purchase",
138150
pre_validate=_pre_validate,
@@ -144,7 +156,10 @@ checkout = Checkout(
144156
gate=CheckoutGateConfig(
145157
api_key=os.environ["AGENTSCORE_API_KEY"],
146158
merchant_name="Merchant",
147-
require_kyc=True, require_sanctions_clear=True, min_age=21, allowed_jurisdictions=["US"],
159+
require_kyc=True,
160+
require_sanctions_clear=True,
161+
min_age=21,
162+
allowed_jurisdictions=["US"],
148163
),
149164
# Optional: empty-body POSTs without a payment header auto-route to a sample 402
150165
# so x402 crawlers (awal x402 details, x402-proxy, ...) can discover the surface.
@@ -165,6 +180,7 @@ checkout.mount_ucp_routes_fastapi(
165180
signing_kid="merchant-2026-05",
166181
)
167182

183+
168184
@app.post("/purchase")
169185
async def purchase(request: Request):
170186
return await checkout.handle_fastapi(request)
@@ -192,10 +208,18 @@ from agentscore_commerce.payment import (
192208
# Build paymentauth.org directives by symbolic rail name (decimals + currency from registry)
193209
directives = [
194210
build_payment_directive(
195-
rail="tempo-mainnet", id="chg_t", realm="ex.com", recipient=TEMPO_ADDR, amount_usd=0.01,
211+
rail="tempo-mainnet",
212+
id="chg_t",
213+
realm="ex.com",
214+
recipient=TEMPO_ADDR,
215+
amount_usd=0.01,
196216
),
197217
build_payment_directive(
198-
rail="x402-base-mainnet", id="chg_b", realm="ex.com", recipient=BASE_ADDR, amount_usd=0.01,
218+
rail="x402-base-mainnet",
219+
id="chg_b",
220+
realm="ex.com",
221+
recipient=BASE_ADDR,
222+
amount_usd=0.01,
199223
),
200224
]
201225
www_auth = www_authenticate_header(directives)
@@ -229,7 +253,9 @@ from agentscore_commerce.challenge import (
229253
# build_accepted_methods + build_how_to_pay are async (they resolve per-order recipients).
230254
accepted = await build_accepted_methods(tempo=TempoRailSpec(recipient=TEMPO_ADDR))
231255
how_to_pay = await build_how_to_pay(
232-
url="https://my.merchant/buy", retry_body_json="{}", total_usd="10.00",
256+
url="https://my.merchant/buy",
257+
retry_body_json="{}",
258+
total_usd="10.00",
233259
rails={"tempo": TempoRailSpec(recipient=TEMPO_ADDR)},
234260
)
235261
body = build_402_body(
@@ -313,7 +339,7 @@ card = build_a2a_agent_card(
313339
# Google Universal Commerce Protocol. Publish at /.well-known/ucp.
314340
# Output shape: {"ucp": {"version", "services", "capabilities",
315341
# "payment_handlers", "name?", "supported_versions?"}, "signing_keys": [...]}
316-
#, services / capabilities / payment_handlers are MAPS keyed by reverse-DNS
342+
# , services / capabilities / payment_handlers are MAPS keyed by reverse-DNS
317343
# service / capability / handler name (UCP spec §3 + §6).
318344
profile = build_ucp_profile(
319345
name="My Service",
@@ -338,7 +364,9 @@ profile = build_ucp_profile(
338364
# binding inside the public profile. Static policy declaration only, no per-operator
339365
# claims. Per-operator identity attestation flows through the AP2 risk-signal endpoint.
340366
agentscore_gate=AgentScoreGatePolicy(
341-
require_kyc=True, min_age=21, allowed_jurisdictions=["US"],
367+
require_kyc=True,
368+
min_age=21,
369+
allowed_jurisdictions=["US"],
342370
),
343371
)
344372
```
@@ -452,6 +480,7 @@ from agentscore_commerce.payment import (
452480
# Boot-time guard. Raises if a configured network isn't supported.
453481
validate_x402_network_config(base_network=X402_BASE)
454482

483+
455484
@app.post("/purchase")
456485
async def purchase(request: Request):
457486
# Path A: agent presented an x402 X-Payment header
@@ -467,15 +496,24 @@ async def purchase(request: Request):
467496
settle = await process_x402_settle(
468497
x402_server=x402_server,
469498
payload=verified.payload,
470-
resource_config={"scheme": "exact", "network": verified.signed_network, "price": f"${total}", "payTo": verified.signed_pay_to, "maxTimeoutSeconds": 300},
499+
resource_config={
500+
"scheme": "exact",
501+
"network": verified.signed_network,
502+
"price": f"${total}",
503+
"payTo": verified.signed_pay_to,
504+
"maxTimeoutSeconds": 300,
505+
},
471506
resource_meta={"url": str(request.url), "mimeType": "application/json"},
472507
)
473508
classified = classify_x402_settle_result(settle)
474509
if classified is not None:
475510
# Log raw `settle` server-side; return controlled phase-based response to the agent.
476511
logger.error("x402-settle failed phase=%s raw=%r", settle.phase, settle)
477512
return JSONResponse(
478-
{"error": {"code": classified.code, "message": classified.message}, "next_steps": classified.next_steps},
513+
{
514+
"error": {"code": classified.code, "message": classified.message},
515+
"next_steps": classified.next_steps,
516+
},
479517
status_code=classified.status,
480518
)
481519

@@ -487,8 +525,18 @@ async def purchase(request: Request):
487525
# `body` is the dict from build_402_body; `x402` carries the payment_required_header kwargs.
488526
result = respond_402(
489527
mppx_challenge_headers=pympp_challenge_headers,
490-
body=build_402_body(accepted_methods=accepted, agent_instructions=instructions, pricing=pricing, amount_usd=total, retry_body=body),
491-
x402={"x402_version": 2, "accepts": x402_accepts, "resource": {"url": str(request.url), "mimeType": "application/json"}},
528+
body=build_402_body(
529+
accepted_methods=accepted,
530+
agent_instructions=instructions,
531+
pricing=pricing,
532+
amount_usd=total,
533+
retry_body=body,
534+
),
535+
x402={
536+
"x402_version": 2,
537+
"accepts": x402_accepts,
538+
"resource": {"url": str(request.url), "mimeType": "application/json"},
539+
},
492540
)
493541
return JSONResponse(result.body, status_code=result.status, headers=result.headers)
494542
```
@@ -504,6 +552,7 @@ from agentscore_commerce.identity.fastapi import AgentScoreGate, get_gate_degrad
504552
app = FastAPI()
505553
gate = AgentScoreGate(api_key=os.environ["AGENTSCORE_API_KEY"], fail_open=True)
506554

555+
507556
@app.post("/purchase", dependencies=[Depends(gate)])
508557
async def purchase(request: Request):
509558
state = get_gate_degraded_state(request)

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "agentscore-commerce"
7-
version = "2.5.12"
7+
version = "2.5.13"
88
description = "Agent commerce SDK for Python — identity middleware (FastAPI, Flask, Django, AIOHTTP, Sanic, ASGI) + payment helpers + 402 builders + discovery + Stripe multichain. The full merchant-side toolkit for AgentScore-powered agent commerce."
99
readme = "README.md"
1010
license = "MIT"

0 commit comments

Comments
 (0)