Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
77f65ac
feat: 1.9.0 — new denial codes + agent_memory type (TEC-226/218/227)
vvillait88 Apr 24, 2026
02a0a4a
feat: AssessResponse.linked_wallets field (TEC-226 review-2 N1)
vvillait88 Apr 24, 2026
1229e95
chore: review-cycle cleanup + CredentialCreateResponse parity fix
vvillait88 Apr 24, 2026
62c0e1a
chore: raise coverage bar 94 → 95 (Tier A standard)
vvillait88 Apr 24, 2026
43a4b62
docs(claude): document wallet-auth response fields across methods
vvillait88 Apr 24, 2026
dadf015
feat: add probe-strategy NextStepsAction values to the Literal
vvillait88 Apr 24, 2026
d2a1d96
feat(types): CredentialRevokeResponse TypedDict parity with node-sdk
vvillait88 Apr 24, 2026
b9db953
feat(types): describe both gate-default and merchant-override denial …
vvillait88 Apr 24, 2026
60eda67
feat(types): close parity gaps vs node-sdk
vvillait88 Apr 24, 2026
6694328
chore: homepage URL → agentscore.sh (product landing, not docs subdom…
vvillait88 Apr 24, 2026
5925bf0
style: ruff format — identity_method Literal line wrap
vvillait88 Apr 24, 2026
ec4ce16
feat(types): drop token_revoked from DenialCode Literal
vvillait88 Apr 24, 2026
a8057f5
feat(types): drop mint_new_credential from NextStepsAction Literal
vvillait88 Apr 24, 2026
5696540
chore: bump ruff to 0.15.12
vvillait88 Apr 24, 2026
c6986d6
chore(ci): bump actions/cache v4→v5, osv-scanner v2.3.2→v2.3.5, setup…
vvillait88 Apr 25, 2026
ed922de
fix(ci): osv-scanner binary must be _linux_arm64 (Blacksmith runners …
vvillait88 Apr 25, 2026
25558f5
docs: note Solana wallet address support + linked_wallets may mix EVM…
vvillait88 Apr 25, 2026
3a052de
feat(client): retry once on 429 honoring retry-after — parity with no…
vvillait88 Apr 26, 2026
e82f1fb
feat(sdk): add verify_webhook_signature + AgentScoreError.status alias
vvillait88 Apr 26, 2026
51617ae
docs(readme): add verify_webhook_signature section + .status alias note
vvillait88 Apr 26, 2026
70f3b47
feat: add is_agentscore_test_address + AGENTSCORE_TEST_ADDRESSES
vvillait88 Apr 26, 2026
e2ba1d6
style: ruff format webhooks.py
vvillait88 Apr 26, 2026
88775c2
chore(deps): add lefthook to dev group + document one-time setup
vvillait88 Apr 27, 2026
3517955
chore(deps): bump transitive packaging 26.1 → 26.2
vvillait88 Apr 27, 2026
6bae07f
feat(sdk): preserve response-body fields on AgentScoreError + accept …
vvillait88 Apr 27, 2026
c951646
feat(sdk)!: drop verify_webhook_signature — AgentScore emits no webhooks
vvillait88 Apr 27, 2026
8e9db86
docs(readme): document AgentScoreError.details + create_session ident…
vvillait88 Apr 27, 2026
4416bea
chore(release): bump to 2.0.0
vvillait88 Apr 27, 2026
f5836c3
docs: drop "mirrors node-sdk" framing in client.py comments
vvillait88 Apr 27, 2026
24770a1
chore: bump ty 0.0.32→0.0.33 (Astral type checker patch)
vvillait88 Apr 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ Python client for the AgentScore trust and reputation API.

## Identity Model

Two identity paths: `X-Wallet-Address` (wallet-based) and `X-Operator-Token` (credential-based). Wallet addresses accept both EVM (`0x...` 40-hex) and Solana (base58, 32–44 chars) formats — network is auto-detected from the address shape. `assess` responses include `resolved_operator` and `linked_wallets[]` (same-operator sibling wallets, normalized per network — EVM lowercased, Solana base58 verbatim; may mix chains for cross-chain operators). `create_session` and `create_credential` responses include an `agent_memory` cross-merchant pattern hint. `create_session` also returns `next_steps.action="deliver_verify_url_and_poll"` + polling instructions. `poll_session` returns `next_steps.action` values: `continue_polling`, `retry_merchant_request_with_operator_token`, `use_stored_operator_token`, `create_new_session`, `verification_failed`, `contact_support`.

## Methods (sync + async)

- `get_reputation` / `aget_reputation` — cached reputation lookup (free)
- `assess` / `aassess` — identity gate with policy (paid). Accepts `operator_token` for non-wallet agents.
- `create_session` / `acreate_session` — create verification session
- `poll_session` / `apoll_session` — poll session status, returns credential when verified
- `create_credential` / `acreate_credential` — create operator credential (24h TTL default)
- `assess` / `aassess` — identity gate with policy (paid). Accepts `operator_token` for non-wallet agents. Response includes `linked_wallets[]` and `resolved_operator`.
- `create_session` / `acreate_session` — create verification session. Returns `agent_memory` + `next_steps`.
- `poll_session` / `apoll_session` — poll session status, returns credential when verified, plus `next_steps.action`.
- `create_credential` / `acreate_credential` — create operator credential (24h TTL default). Response includes `agent_memory`.
- `list_credentials` / `alist_credentials` — list active credentials
- `revoke_credential` / `arevoke_credential` — revoke a credential
- `associate_wallet` / `aassociate_wallet` — report a signer wallet seen paying under a credential (TEC-189). Accepts optional `idempotency_key` (payment intent id / tx hash) so retries don't inflate transaction_count.
- `associate_wallet` / `aassociate_wallet` — report a signer wallet seen paying under a credential. Accepts optional `idempotency_key` (payment intent id / tx hash) so retries don't inflate transaction_count.

## Architecture

Expand All @@ -37,6 +39,7 @@ Single-package Python library published to PyPI.

```bash
uv sync --all-extras
uv run lefthook install # one-time per clone — wires pre-commit + pre-push
uv run ruff check .
uv run ruff format .
uv run ty check agentscore/
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ jobs:
timeout-minutes: 10
steps:
- uses: useblacksmith/checkout@v1
- uses: astral-sh/setup-uv@v7
- uses: astral-sh/setup-uv@v8.1.0
- run: uv python install 3.12
- uses: actions/cache@v4
- uses: actions/cache@v5
with:
path: |
~/.cache/uv
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
steps:
- uses: actions/checkout@v6

- uses: astral-sh/setup-uv@v7
- uses: astral-sh/setup-uv@v8.1.0

- name: Set version from tag
run: sed -i "s/^version = .*/version = \"${GITHUB_REF_NAME#v}\"/" pyproject.toml
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@ jobs:

- name: Install osv-scanner
run: |
curl -fsSL https://github.com/google/osv-scanner/releases/download/v2.3.2/osv-scanner_linux_amd64 -o osv-scanner
curl -fsSL https://github.com/google/osv-scanner/releases/download/v2.3.5/osv-scanner_linux_arm64 -o osv-scanner
chmod +x osv-scanner

- name: Scan dependencies
run: ./osv-scanner --lockfile=uv.lock --format=table || true
run: ./osv-scanner scan source --lockfile=uv.lock --format=table

pip-audit:
name: Python Audit
runs-on: blacksmith-2vcpu-ubuntu-2404-arm
timeout-minutes: 5
steps:
- uses: useblacksmith/checkout@v1
- uses: astral-sh/setup-uv@v7
- uses: astral-sh/setup-uv@v8.1.0
- uses: actions/setup-python@v6
with:
python-version: "3.13"
Expand All @@ -46,5 +46,5 @@ jobs:
- name: Audit dependencies
run: |
uv export --format requirements-txt --no-hashes > requirements.txt
pip-audit -r requirements.txt --disable-pip --no-deps || true
pip-audit -r requirements.txt --disable-pip --no-deps

26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,27 @@ print(result["decision"]) # "allow" | "deny"

### Verification Sessions

Bootstrap identity for first-time agents:
Bootstrap identity for first-time agents. The success body carries structured `next_steps` (with `action: "deliver_verify_url_and_poll"`) and a cross-merchant `agent_memory` hint. Poll responses carry `next_steps.action` from the typed `NextStepsAction` Literal (`continue_polling`, `retry_merchant_request_with_operator_token`, `use_stored_operator_token`, `create_new_session`, `verification_failed`, `contact_support`).

```python
session = client.create_session()
print(session["verify_url"], session["poll_url"], session["poll_secret"])
print(session["next_steps"]["action"]) # "deliver_verify_url_and_poll"

status = client.poll_session(session["session_id"], session["poll_secret"])
if status["status"] == "verified":
print(status["operator_token"]) # "opc_..." — use for future requests

# Optional pre-association: attach the session to a known wallet or refresh KYC
# for an existing operator credential.
client.create_session(address="0x...")
client.create_session(operator_token="opc_...") # KYC refresh
```

### Wallet resolution

`assess()` responses include `resolved_operator` and `linked_wallets` — all same-operator sibling wallets (claimed via SIWE or captured via prior `associate_wallet`). The list may mix EVM addresses (`0x...` lowercased) and Solana addresses (base58, case-preserved) for cross-chain operators; merchants doing wallet-signer-match checks should accept a payment signed by any address in the list, regardless of chain. The `address` parameter on `assess()` and `get_reputation()` accepts either format — network is auto-detected from the address shape.

### Credential Management

```python
Expand Down Expand Up @@ -124,6 +134,8 @@ with AgentScore(api_key="as_live_...") as client:
| `timeout` | `10.0` | Request timeout (seconds)|
| `user_agent` | `None` | Prepended to the default `User-Agent` as `"{user_agent} (agentscore-py/{version})"`. Use to attribute API calls to your app. |

`AgentScoreError.status` is a property aliasing `.status_code` so polyglot codebases can use the same attribute name regardless of which SDK raised the error.

## Error Handling

```python
Expand All @@ -135,6 +147,18 @@ except AgentScoreError as e:
print(e.code, e.status_code, str(e))
```

`AgentScoreError.details` carries the rest of the response body — `verify_url`, `linked_wallets`, `claimed_operator`, `actual_signer`, `expected_signer`, `reasons`, `agent_memory` — so callers can branch on granular denial codes without re-parsing:

```python
try:
client.assess("0xabc...", policy={"require_kyc": True})
except AgentScoreError as e:
if e.code == "wallet_signer_mismatch":
print("Re-sign from one of:", e.details.get("linked_wallets"))
elif e.code == "token_expired":
print("Verify at:", e.details.get("verify_url"))
```

## Documentation

- [API Reference](https://docs.agentscore.sh)
Expand Down
21 changes: 21 additions & 0 deletions agentscore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@

from agentscore.client import AgentScore
from agentscore.errors import AgentScoreError
from agentscore.test_mode import AGENTSCORE_TEST_ADDRESSES, is_agentscore_test_address
from agentscore.types import (
AccountVerification,
AgentMemoryHint,
AgentMemoryIdentityPaths,
AssessResponse,
AssociateWalletResponse,
CredentialCreateErrorResponse,
CredentialCreateResponse,
CredentialItem,
CredentialListResponse,
CredentialRevokeResponse,
DecisionPolicy,
DenialCode,
EntityType,
Grade,
Network,
NextStepsAction,
OperatorVerification,
Reputation,
ReputationResponse,
Expand All @@ -20,22 +28,32 @@
SessionCreateResponse,
SessionPollResponse,
VerificationLevel,
WalletAuthRequiresSigningBody,
WalletSignerMismatchBody,
)

__version__ = _pkg_version("agentscore-py")

__all__ = [
"AGENTSCORE_TEST_ADDRESSES",
"AccountVerification",
"AgentMemoryHint",
"AgentMemoryIdentityPaths",
"AgentScore",
"AgentScoreError",
"AssessResponse",
"AssociateWalletResponse",
"CredentialCreateErrorResponse",
"CredentialCreateResponse",
"CredentialItem",
"CredentialListResponse",
"CredentialRevokeResponse",
"DecisionPolicy",
"DenialCode",
"EntityType",
"Grade",
"Network",
"NextStepsAction",
"OperatorVerification",
"Reputation",
"ReputationResponse",
Expand All @@ -44,5 +62,8 @@
"SessionCreateResponse",
"SessionPollResponse",
"VerificationLevel",
"WalletAuthRequiresSigningBody",
"WalletSignerMismatchBody",
"__version__",
"is_agentscore_test_address",
]
Loading
Loading