Skip to content

feat(python-sdk): samvad 0.1.0 — Python port of the SAMVAD protocol SDK#2

Merged
w3rc merged 37 commits intomainfrom
feat/python-sdk
Apr 14, 2026
Merged

feat(python-sdk): samvad 0.1.0 — Python port of the SAMVAD protocol SDK#2
w3rc merged 37 commits intomainfrom
feat/python-sdk

Conversation

@w3rc
Copy link
Copy Markdown
Owner

@w3rc w3rc commented Apr 14, 2026

Summary

  • Adds packages/sdk-python/ — a complete Python port of @samvad-protocol/sdk 0.5.0, published as samvad on PyPI
  • Protocol v1.2 parity: RFC 9421 HTTP Message Signatures (Ed25519), canonical JSON, 5-step security pipeline, sync/async/SSE modes, delegation JWTs, injection scanning
  • 147 tests passing; cross-SDK test vectors prove wire compatibility between TypeScript and Python
  • Adds examples/basic-agent-py/ (Starlette, no FastAPI) and CI matrix for Python 3.10/3.11/3.12

What's in this PR

New package: packages/sdk-python/ (samvad on PyPI)

Mirrors the TypeScript SDK module-for-module:

Module What it does
errors.py SamvadError + ErrorCode enum
types.py Pydantic v2 envelope/card/skill models
keys.py Ed25519 keypair load/generate, raw sign/verify
signing.py RFC 9421 HTTP Message Signatures + canonical JSON
nonce_store.py Replay protection (5-min window, split check/commit)
rate_limiter.py Per-sender sliding window + daily token budget
skill_registry.py Skill registration + validated dispatch
injection_scanner.py Regex first-pass + optional async LLM classifier
delegation.py EdDSA JWT tokens with scope + depth enforcement
card.py AgentCard builder
task_store.py Async task state with 1h TTL
stream.py SSE helpers with 15s keep-alive
verify_middleware.py 5-step pipeline in the security-mandated order
server.py Starlette ASGI app factory
agent.py Fluent Agent builder
agent_client.py AgentClient with call/task/stream
verify_middleware.py create_verify_middleware for framework-agnostic use

Security pipeline

Same ordering as the TypeScript SDK — cheap rejections first, expensive last:

  1. Nonce check() (non-mutating — prevents nonce burn before auth)
  2. Rate limit
  3. Ed25519 signature verify
  4. Nonce commit() (only after sig passes)
  5. Injection scan
  6. Trust tier enforcement

Cross-SDK wire compatibility

spec/test-vectors/vectors.json contains 3 cases signed by the TypeScript SDK. tests/test_cross_sdk_vectors.py verifies them with the Python implementation. All pass.

New files

  • packages/sdk-python/ — full SDK
  • spec/test-vectors/vectors.json — cross-SDK signing vectors
  • examples/basic-agent-py/ — minimal echo agent
  • .github/workflows/ci.yml — Python 3.10/3.11/3.12 matrix job

Test plan

  • cd packages/sdk-python && pip install -e ".[dev]" && pytest -v → 147 tests pass
  • ruff check src tests → clean
  • CI green on all 3 Python versions
  • Cross-SDK vectors test: pytest tests/test_cross_sdk_vectors.py -v
  • Integration test: pytest tests/test_integration.py -v (happy path, replay rejection, unknown peer)
  • Wheel check: python -m build && twine check dist/*

🤖 Generated with Claude Code

w3rc added 30 commits April 14, 2026 11:21
Adds spec/test-vectors/ with a generator (generate.mts) that calls the
actual TS SDK signRequest, and vectors.json with 3 signed cases covering
ASCII, UTF-8, and nested JSON bodies. The Python SDK will verify these in
Task 6 to prove wire compatibility.
…r sanitization

- Add NonceStore.check() (non-mutating) and commit() methods; check_and_add() now delegates to both
- Update verify_middleware pipeline: call check at step 1, commit after signature passes (step 3.5) so failed rate-limit/sig checks don't burn the nonce slot
- Add test_bad_signature_rejected: known peer signed with wrong key must return AUTH_FAILED
- Move import datetime to module-level (fix 3)
- Sanitize SCHEMA_INVALID envelope error — no longer leaks Pydantic field details (fix 4)
- Fix malformed timestamp error code: REPLAY_DETECTED → SCHEMA_INVALID (fix 5)
Expands __init__.py to re-export all public symbols (Agent, AgentClient,
SamvadError, ErrorCode, create_verify_middleware, VerifyResult, and all
types). Adds test_integration.py with three ASGI round-trip tests covering
the happy path, replay rejection, and unknown-peer rejection.
w3rc added 2 commits April 14, 2026 14:57
Add PyPI badge, Python SDK section to repo layout, Python dev commands.
Update sdk-python/README.md with full quickstart and AgentClient example.
@w3rc w3rc force-pushed the feat/python-sdk branch from 5c0fa66 to 876d9a9 Compare April 14, 2026 09:33
w3rc and others added 5 commits April 14, 2026 15:16
…Limiter/TaskStore

InMemoryNonceStore.check() now atomically reserves the nonce slot under
asyncio.Lock, eliminating the TOCTOU race between check() and commit().
Added rollback() so rate-limited requests release the reservation (allowing
client retry with the same nonce). RateLimiter and TaskStore guard all
mutating methods with threading.Lock for safety under threading and future
refactors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e compat, isawaitable

- verify_middleware: add Step 3.7 delegation token verification (checks issuer is known peer, sub matches sender, skill is in scope); replace hasattr(__await__) with inspect.isawaitable
- server: add Content-Digest guard to agent_stream endpoint (matching agent_message/agent_task); expand health to return protocolVersion/agentVersion/uptime; rewrite intro as text/markdown matching TypeScript SDK
- tests: add test_valid_delegation_token_passes, test_forged_delegation_token_rejected, test_delegation_scope_mismatch_rejected; update test_intro_200 for text/markdown response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…er AssertionError, dynamic vector parametrize
@w3rc w3rc merged commit 8ab1dc8 into main Apr 14, 2026
2 of 5 checks passed
@w3rc w3rc deleted the feat/python-sdk branch April 14, 2026 13:42
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