Skip to content

Commit 0a66175

Browse files
authored
Remove get_reputation and release 2.7.0 (#96)
## Summary `GET /v1/reputation` was retired on 2026-09-30 along with the transaction pipeline, and the API now answers 404 on it. This removes `get_reputation()` / `aget_reputation()` and the types only they returned, and releases 2.7.0. - `get_reputation()` and `aget_reputation()` are removed. - The reputation response types are removed from `agentscore.types` and the package exports: `ReputationResponse`, `Reputation`, `Score`, `ChainScore`, `ChainEntry`, `Classification`, `RedactedClassification`, `Subject`, `Identity`, `Activity`, `EvidenceSummary`, `OperatorScore`, `AgentSummary`, `Grade`, `EntityType`, `ReputationStatus`. `AssessResponse` is unchanged. - The `create_session` docstrings no longer call it "an assessment session for deferred scoring". - README, `.claude/CLAUDE.md` and the package keywords no longer describe a reputation lookup. - Dependencies: ruff 0.16.10, python-dotenv 1.2.4, lefthook 2.1.16. Workflows move to uv 0.12.22. Versioned as a minor on purpose: the method has returned 404 since the endpoint was retired, so no working call changes behavior. Code that still references it raises `AttributeError` after upgrading. ## Type of change - [ ] Bug fix (no breaking change) - [ ] New feature (no breaking change) - [x] Breaking change (existing callers must update) - [ ] Docs, tests, or internal maintenance only ## Public API `AgentScore.get_reputation()`, `AgentScore.aget_reputation()` and the reputation types listed above are removed. Migration: drop the call. The endpoint behind it no longer exists, so there is no replacement; `assess()` / `aassess()` remain the identity and compliance check. ## Test plan - The generic request tests (error mapping, context managers, concurrency, retries) used `get_reputation` as their vehicle and now run through `list_credentials()` / `alist_credentials()`, so that coverage is kept. - The assess and session-poll fixtures now carry the shapes the API returns, not score and chain bodies. A policy test that sent a nonexistent `min_score` key now sends `require_kyc`. - A new test pins that both methods are absent from the client. - `uv run pytest` (177 passed, 2 integration skipped without credentials, 99.8% coverage), `ruff check`, `ruff format --check`, `ty check` and `vulture` all pass locally. The OSV scan of `uv.lock` is clean. Worked with Varun. ## Checklist - [x] Tests cover the new behavior, and the suite passes locally - [x] Lint, format, and type checks pass - [x] Docs and README examples updated if the public surface changed - [x] No secrets, credentials, or personal data in the diff or the tests
1 parent 151327b commit 0a66175

12 files changed

Lines changed: 122 additions & 521 deletions

File tree

‎.claude/CLAUDE.md‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ Two identity paths: `X-Wallet-Address` (wallet-based) and `X-Operator-Token` (cr
88

99
## Methods (sync + async)
1010

11-
- `get_reputation` / `aget_reputation` — cached reputation lookup (free)
1211
- `assess` / `aassess` — identity gate with policy (paid). Accepts `operator_token` for non-wallet agents. Response includes `linked_wallets[]` and `resolved_operator`. Optional `signer: { address, network }` opts into server-side wallet-signer-match AND OFAC SDN wallet-address screening — the response then carries both a `signer_match` block (wallet-binding verdict: `pass` / `wallet_signer_mismatch` / `wallet_auth_requires_wallet_signing`) and a `signer_sanctions` block (discriminated union: `{status: "clear"}` | `{sanctioned: True, ofac_label, sdn_uid, listed_at}` | `{status: "unavailable"}`). Wallet-OFAC SDN enforcement on the `signer` block is unconditional whenever a signer is supplied — no `policy.require_sanctions_clear` opt-in required. A `sanctioned: True` OR `status: "unavailable"` verdict flips the response `decision` to `deny` with `decision_reasons` including `sanctions_flagged` or `sanctions_check_unavailable` respectively (fail-closed; OFAC strict-liability). `policy.require_sanctions_clear` is the separate NAME-based screen on the resolved operator's KYC identity.
1312
- `create_session` / `acreate_session` — create verification session. Returns `agent_memory` + `next_steps`.
1413
- `poll_session` / `apoll_session` — poll session status, returns credential when verified, plus `next_steps.action`.

‎.github/workflows/ci.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- uses: useblacksmith/checkout@v1
2323
- uses: astral-sh/setup-uv@v10.2.0
2424
with:
25-
version: "0.12.20"
25+
version: "0.12.22"
2626
- run: uv python install 3.12
2727
- uses: actions/cache@v6
2828
with:
@@ -49,7 +49,7 @@ jobs:
4949
- uses: useblacksmith/checkout@v1
5050
- uses: astral-sh/setup-uv@v10.2.0
5151
with:
52-
version: "0.12.20"
52+
version: "0.12.22"
5353
- run: uv python install ${{ matrix.python }}
5454
- run: uv sync --frozen --all-extras --all-groups --python ${{ matrix.python }}
5555
- run: uv run --python ${{ matrix.python }} pytest tests/ -q

‎.github/workflows/publish.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121

2222
- uses: astral-sh/setup-uv@v10.2.0
2323
with:
24-
version: "0.12.20"
24+
version: "0.12.22"
2525

2626
- name: Set version from tag
2727
run: sed -i "s/^version = .*/version = \"${GITHUB_REF_NAME#v}\"/" pyproject.toml

‎.github/workflows/security.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
- uses: useblacksmith/checkout@v1
3939
- uses: astral-sh/setup-uv@v10.2.0
4040
with:
41-
version: "0.12.20"
41+
version: "0.12.22"
4242
- uses: actions/setup-python@v7
4343
with:
4444
python-version: "3.13"

‎README.md‎

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@ from agentscore import AgentScore
1818

1919
client = AgentScore(api_key="as_live_...")
2020

21-
# Look up cached reputation (free)
22-
rep = client.get_reputation("0x1234...")
23-
print(rep["score"]["value"], rep["score"]["grade"])
24-
25-
# Filter to a specific chain
26-
base_rep = client.get_reputation("0x1234...", chain="base")
27-
2821
# Identity gate with policy (paid)
2922
gated = client.assess(
3023
"0x1234...",
@@ -39,9 +32,8 @@ if gated["decision"] == "deny":
3932
print(gated["decision_reasons"]) # ["kyc_required"]
4033
print(gated.get("verify_url")) # URL for operator verification
4134

42-
# Check verification level
43-
rep = client.get_reputation("0x1234...")
44-
print(rep.get("verification_level")) # "none" | "wallet_claimed" | "kyc_verified"
35+
# Verification level of the operator behind the wallet
36+
print(gated["operator_verification"]["level"]) # "none" | "kyc_verified"
4537
```
4638

4739
### Credential-Based Identity
@@ -75,7 +67,7 @@ client.create_session(kind="sign_in") # registration-only: account sign-in, no
7567

7668
### Wallet resolution
7769

78-
`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; the network is auto-detected from the address shape.
70+
`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()` accepts either format; the network is auto-detected from the address shape.
7971

8072
### Server-side signer-match + sanctions screening
8173

@@ -138,7 +130,6 @@ All methods have async variants prefixed with `a`:
138130

139131
```python
140132
async with AgentScore(api_key="as_live_...") as client:
141-
rep = await client.aget_reputation("0x1234...")
142133
result = await client.aassess("0x1234...", policy={"require_kyc": True})
143134

144135
# Identity model methods
@@ -158,7 +149,7 @@ async with AgentScore(api_key="as_live_...") as client:
158149

159150
```python
160151
with AgentScore(api_key="as_live_...") as client:
161-
rep = client.get_reputation("0x1234...")
152+
result = client.assess("0x1234...")
162153
```
163154

164155
## Configuration
@@ -178,7 +169,7 @@ with AgentScore(api_key="as_live_...") as client:
178169
from agentscore import AgentScore, AgentScoreError
179170

180171
try:
181-
rep = client.get_reputation("0xinvalid")
172+
client.assess("0xinvalid")
182173
except AgentScoreError as e:
183174
print(e.code, e.status_code, str(e))
184175
```

‎agentscore/__init__.py‎

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,12 @@
1313
from agentscore.test_mode import AGENTSCORE_TEST_ADDRESSES, is_agentscore_test_address
1414
from agentscore.types import (
1515
AccountVerification,
16-
Activity,
1716
AgentMemoryHint,
1817
AgentMemoryIdentityPaths,
19-
AgentSummary,
2018
AipProvenance,
2119
AipSignatureMaterial,
2220
AssessResponse,
2321
AssociateWalletResponse,
24-
ChainEntry,
25-
ChainScore,
26-
Classification,
2722
CredentialCreateErrorNextSteps,
2823
CredentialCreateErrorResponse,
2924
CredentialCreateResponse,
@@ -32,23 +27,13 @@
3227
CredentialRevokeResponse,
3328
DecisionPolicy,
3429
DenialCode,
35-
EntityType,
36-
EvidenceSummary,
37-
Grade,
38-
Identity,
3930
Network,
4031
NextStepsAction,
41-
OperatorScore,
4232
OperatorVerification,
4333
PolicyCheck,
4434
PolicyExplanation,
4535
PolicyResult,
4636
QuotaInfo,
47-
RedactedClassification,
48-
Reputation,
49-
ReputationResponse,
50-
ReputationStatus,
51-
Score,
5237
SessionCreateNextSteps,
5338
SessionCreateRequest,
5439
SessionCreateResponse,
@@ -60,7 +45,6 @@
6045
SignerSanctionsClear,
6146
SignerSanctionsHit,
6247
SignerSanctionsUnavailable,
63-
Subject,
6448
VerificationLevel,
6549
WalletAuthRequiresSigningBody,
6650
WalletAuthRequiresSigningNextSteps,
@@ -73,19 +57,14 @@
7357
__all__ = [
7458
"AGENTSCORE_TEST_ADDRESSES",
7559
"AccountVerification",
76-
"Activity",
7760
"AgentMemoryHint",
7861
"AgentMemoryIdentityPaths",
7962
"AgentScore",
8063
"AgentScoreError",
81-
"AgentSummary",
8264
"AipProvenance",
8365
"AipSignatureMaterial",
8466
"AssessResponse",
8567
"AssociateWalletResponse",
86-
"ChainEntry",
87-
"ChainScore",
88-
"Classification",
8968
"CredentialCreateErrorNextSteps",
9069
"CredentialCreateErrorResponse",
9170
"CredentialCreateResponse",
@@ -94,14 +73,9 @@
9473
"CredentialRevokeResponse",
9574
"DecisionPolicy",
9675
"DenialCode",
97-
"EntityType",
98-
"EvidenceSummary",
99-
"Grade",
100-
"Identity",
10176
"InvalidCredentialError",
10277
"Network",
10378
"NextStepsAction",
104-
"OperatorScore",
10579
"OperatorVerification",
10680
"PaymentRequiredError",
10781
"PolicyCheck",
@@ -110,11 +84,6 @@
11084
"QuotaExceededError",
11185
"QuotaInfo",
11286
"RateLimitedError",
113-
"RedactedClassification",
114-
"Reputation",
115-
"ReputationResponse",
116-
"ReputationStatus",
117-
"Score",
11887
"SessionCreateNextSteps",
11988
"SessionCreateRequest",
12089
"SessionCreateResponse",
@@ -126,7 +95,6 @@
12695
"SignerSanctionsClear",
12796
"SignerSanctionsHit",
12897
"SignerSanctionsUnavailable",
129-
"Subject",
13098
"TimeoutError",
13199
"TokenExpiredError",
132100
"VerificationLevel",

‎agentscore/client.py‎

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ def _build_error_from_response(response: httpx.Response) -> AgentScoreError:
141141
CredentialRevokeResponse,
142142
DecisionPolicy,
143143
Network,
144-
ReputationResponse,
145144
SessionCreateResponse,
146145
SessionPollResponse,
147146
Signer,
@@ -247,14 +246,6 @@ def _handle_response(self, response: httpx.Response) -> Any:
247246

248247
# --- Sync methods ---
249248

250-
def get_reputation(self, address: str, chain: str | None = None) -> ReputationResponse:
251-
"""Get cached reputation for an address (free, read-only). Optionally filter by chain."""
252-
params: dict[str, str] = {}
253-
if chain:
254-
params["chain"] = chain
255-
client = self._get_sync_client()
256-
return self._send_sync(lambda: client.get(f"/v1/reputation/{address}", params=params))
257-
258249
def assess(
259250
self,
260251
address: str | None = None,
@@ -310,7 +301,7 @@ def create_session(
310301
operator_token: str | None = None,
311302
kind: Literal["kyc", "sign_in"] | None = None,
312303
) -> SessionCreateResponse:
313-
"""Create an assessment session for deferred scoring.
304+
"""Create a verification or sign-in session.
314305
315306
``address`` pre-associates the session with a known wallet (EVM ``0x...`` or
316307
Solana base58). ``operator_token`` pre-associates with an existing ``opc_...`` —
@@ -404,14 +395,6 @@ def associate_wallet(
404395

405396
# --- Async methods ---
406397

407-
async def aget_reputation(self, address: str, chain: str | None = None) -> ReputationResponse:
408-
"""Get cached reputation for an address (free, read-only). Optionally filter by chain."""
409-
params: dict[str, str] = {}
410-
if chain:
411-
params["chain"] = chain
412-
client = self._get_async_client()
413-
return await self._send_async(lambda: client.get(f"/v1/reputation/{address}", params=params))
414-
415398
async def aassess(
416399
self,
417400
address: str | None = None,
@@ -460,7 +443,7 @@ async def acreate_session(
460443
operator_token: str | None = None,
461444
kind: Literal["kyc", "sign_in"] | None = None,
462445
) -> SessionCreateResponse:
463-
"""Create an assessment session for deferred scoring.
446+
"""Create a verification or sign-in session.
464447
465448
``address`` pre-associates the session with a known wallet (EVM ``0x...`` or
466449
Solana base58). ``operator_token`` pre-associates with an existing ``opc_...`` —

0 commit comments

Comments
 (0)