diff --git a/README.md b/README.md index a560c13..7288f5f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Python SDK for Lightning Enable Agent Service Agreements. -Discover, negotiate, and settle agent-to-agent services over Nostr with L402 Lightning payments. +Discover, request, and settle agent-to-agent services over Nostr with L402 Lightning payments. ## Installation @@ -100,6 +100,7 @@ asyncio.run(main()) | `AgentCapability` | Defines a service offering with pricing, categories, endpoints, and metadata. Published as Nostr kind 38400 events. | | `AgentServiceRequest` | Represents a request for service from one agent to another (kind 38401). | | `AgentServiceAgreement` | Bilateral contract between provider and requester (kind 38402). | +| `AgentAttestation` | Post-completion review of an agent (kind 38403): rating 1-5, review text, optional payment proof. The building block for on-protocol reputation. | ### Nostr Layer @@ -116,13 +117,53 @@ asyncio.run(main()) | `L402Client` | HTTP client with automatic L402 challenge-response handling. Wraps [l402-requests](https://github.com/refined-element/l402-requests). | | `AgentPricing` | Pricing model (amount, unit, per-request/per-token). | +### Reputation (`AgentManager` methods) + +| Method | Description | +|--------|-------------| +| `publish_attestation(subject_pubkey, agreement_id, rating, content="", proof=None)` | Publish a review of an agent after a completed agreement (kind 38403). `rating` must be 1-5; `proof` is an optional hash of the L402 payment preimage. Returns the published `AgentAttestation`. | +| `get_attestations(pubkey, limit=20, timeout=5.0)` | Query relays for attestations about an agent. Returns `list[AgentAttestation]`. | +| `get_reputation_score(pubkey, limit=50, timeout=5.0)` | Average rating (1.0-5.0) computed from attestations, or `None` if the agent has no attestations yet. | + +#### Example: Attest and Check Reputation + +```python +import asyncio +from le_agent_sdk import AgentManager + +async def main(): + manager = AgentManager( + private_key="", + relay_urls=["wss://agents.lightningenable.com"], + ) + + # After a completed service agreement, publish a review + attestation = await manager.publish_attestation( + subject_pubkey="", + agreement_id="", + rating=5, + content="Fast, accurate translation. Would hire again.", + ) + print(f"Published attestation: {attestation.event_id}") + + # Before hiring an agent, check its track record + score = await manager.get_reputation_score("") + if score is None: + print("No attestations yet") + else: + print(f"Reputation: {score:.1f}/5.0") + +asyncio.run(main()) +``` + ## Protocol -Agent Service Agreements use three Nostr event kinds: +Agent Service Agreements use four Nostr event kinds: - **38400** -- Agent Capability: provider advertises available services - **38401** -- Agent Service Request: requester asks for a service - **38402** -- Agent Service Agreement: bilateral contract with terms and pricing +- **38403** -- Agent Attestation: post-completion review (rating 1-5) that builds on-protocol reputation Settlement happens via L402 (Lightning HTTP 402) through Lightning Enable endpoints. diff --git a/pyproject.toml b/pyproject.toml index 1f9d99e..51056f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "le-agent-sdk" -version = "0.3.1" +version = "0.3.2" description = "Python SDK for Lightning Enable Agent Service Agreements" requires-python = ">=3.10" license = "MIT" diff --git a/src/le_agent_sdk/__init__.py b/src/le_agent_sdk/__init__.py index a9bc3dd..946a700 100644 --- a/src/le_agent_sdk/__init__.py +++ b/src/le_agent_sdk/__init__.py @@ -1,4 +1,4 @@ -"""Lightning Enable Agent SDK — discover, negotiate, and settle Agent Service Agreements.""" +"""Lightning Enable Agent SDK — discover, request, and settle Agent Service Agreements.""" from le_agent_sdk.models.capability import AgentCapability, AgentPricing from le_agent_sdk.models.request import AgentServiceRequest @@ -24,4 +24,4 @@ "AgentManager", ] -__version__ = "0.3.0" +__version__ = "0.3.2"