Stateset NSR Python SDK
Python client for the Stateset NSR AI platform — neuro-symbolic recursive reasoning.
Install
pip install stateset-nsr # (publishing soon — not yet on PyPI; install from this repo for now)
pip install stateset-nsr[async] # with the aiohttp-based async client
From this repo:
pip install ./sdks/python
Quick Start
from stateset_nsr import NSRClient
client = NSRClient(
api_key="nsr_your_api_key", # or set NSR_API_KEY
org_id="org_your_org_id", # or set NSR_ORG_ID
)
Credentials fall back to the NSR_API_KEY / NSR_ORG_ID environment
variables; explicit arguments always win.
# Send a customer message
response = client.chat("I want to cancel my subscription")
print(response.reply)
# "We offer the option to pause your subscription..."
print(response.top_category)
# "subscription_management"
print(response.confidence)
# 0.61
# Execute ready tool calls
for tc in response.ready_tool_calls:
print(f"{tc.function}() — rule: {tc.policy.rule_name}")
# offer_pause() — rule: offer_pause_before_cancel
Verified Decisions
# One auditable decision: approved | denied | refused, with a cited proof chain.
decision = client.decide(
"Can order A1 be refunded?",
action="issue_refund",
)
print(decision["decision"], decision["proof"]["cited_rules"])
# Score a whole portfolio in one call — each item metered independently.
batch = client.decide_batch([
{"query": "Can order A1 be refunded?", "action": "issue_refund"},
{"query": "Can order A2 be returned?"},
])
print(batch["summary"])
# Items past the server's time budget return error code
# "batch_deadline_exceeded" — never evaluated, never billed. Retry those in
# a smaller batch.
See examples/verified_decision.py for a self-contained runnable version
with inline rules and facts.
Knowledge Base
# Add products
client.add_entity("Pro Plan", "product", {"price": "99.00"})
# Add business rules
client.add_rule(
name="offer_pause_before_cancel",
head_predicate="offer_pause",
head_args=["?subscription"],
body=[{"predicate": "cancel_request", "args": ["?subscription"]}],
confidence=0.95,
)
# Check KB stats
print(client.kb_stats())
NSR Machine
# Provision
client.provision_machine(seed_from_gss=True)
# Train
client.train_machine([
{"input": "cancel my plan", "expected_category": "subscription_management"},
{"input": "where is my order", "expected_category": "order_management"},
])
# Check status
status = client.machine_status()
print(f"Vocabulary: {status.vocabulary_size}")
print(f"Programs: {status.programs_learned}")
Advanced Reasoning
response = client.chat("Is this safe during pregnancy?")
# Check if human review needed
if response.completion.needs_human_review:
print("Route to human agent")
# Inspect the reasoning
ar = response.completion.grounding.advanced_reasoning
if ar:
print(f"Strategy: {ar.recommended_strategy}")
print(f"Confidence: {ar.machine_confidence}")
print(f"Thoughts: {ar.thought_count}")
print(f"Features: {ar.enabled_features}")
if ar.uncertainty:
print(f"Epistemic: {ar.uncertainty.epistemic}")
print(f"Calibration: {ar.uncertainty.calibration_score}")
Verifying webhooks
from stateset_nsr import verify_webhook_signature
# In your handler: raw request body + the X-NSR-Signature header.
if not verify_webhook_signature(signing_secret, raw_body, signature_header):
return abort(400)
Constant-time, case-insensitive hex comparison with a 5-minute replay window
by default (tolerance_secs=None disables the timestamp check). The HMAC is
computed over the raw t= token exactly as the server signed it; multiple
v1= signatures are accepted (any match passes — the key-rotation case) and
headers with a duplicated t= are rejected.
Reliability
- Retries with exponential backoff + jitter on 5xx, 429, and connection
errors (
max_retries, default 3). - Every mutating request (POST/PATCH/PUT/DELETE) automatically carries an
Idempotency-Key, generated once per logical call and stable across its retries — a retried request can never re-execute or re-bill server-side. Pass your own key viaidempotency_key=ondecide/decide_batch/reply. Retry-Afteron 429 is honored in both its delta-seconds and HTTP-date forms (garbage falls back to backoff), capped at 60 seconds, and 429 retries respectmax_retries.
Async client
AsyncNSRClient (extra: pip install stateset-nsr[async]) has full
method-for-method parity with NSRClient — enforced by an introspection test
in tests/test_async_client.py. Its exceptions subclass the sync ones, so
except NSRError catches failures from either client.
from stateset_nsr import AsyncNSRClient
async with AsyncNSRClient() as client: # env-var credentials
decision = await client.decide("Can order A1 be refunded?")
Audit & observability lookups
client.get_decision("dec_abc123") # resolve a decision_id from a response/webhook
client.gss_seed_info() # {"grounded": true, "source": "embedded", ...}
Brand machine onboarding
The full GSS lifecycle for your org — see BRAND_MACHINE_ONBOARDING.md:
seed = client.seed_machine_pack({"catalog": [...], "policies": [...]})
spec = client.compile_machine_pack({"seed_id": seed["id"]})
report = client.evaluate_machine_seed({"compiled_id": spec["id"]})
client.activate_machine_pack({"compiled_id": spec["id"]})
Webhooks & templates
hook = client.create_webhook("https://yourapp.com/hook", ["outcome.produced"])
store(hook["signing_secret"]) # shown ONLY at creation
client.webhook_deliveries(hook["id"]) # delivery log (status, attempts)
client.apply_template("ecommerce-returns") # one-call KB seeding
Coverage
Route groups covered by both clients (sync and async):
- Chat:
/api/v1/nsr/chat(+SSE stream), OpenAI-compatible/v1/chat/completions, Anthropic-compatible/v1/messages - Verified decisions:
/v1/decisions(+batch, recent, stats, rule-stats, refusal-gaps, refusal-roadmap, calibration, export,{id}, outcome, outcome-by-ref), proof re-verification/v1/proofs/verify - Replies & macros:
/api/v1/replies,/api/v1/macrosCRUD + batch + render - Auth:
/api/v1/auth/signup|login|session, API-key list/create/revoke - Knowledge base: entities (CRUD, batch, search), rules (create/list), triples + triple evidence,
/api/v1/kb/stats|history - Reasoning:
/api/v1/reason,/api/v1/reason/induce-rules, forward/backward chain, explain, RAG query - Machines: provision/train/evaluate/infer/status/list + brand-machine pack lifecycle (seed/compile/evaluate-seed/activate)
- Webhooks (register/list/revoke/deliveries + signature verification), industry templates
- Sessions, conversations, flywheel (feedback/stats/train/demote-noisy), NSR-L, sandbox, agents (list/start/stop)
- Billing: usage/subscription/plans/credits/purchase/invoices
- Metering & marketplace: entitlement link/get, AWS + Azure marketplace registration
- Health:
/health,/ready
Route groups NOT yet covered (call client._request(method, path, ...) as an
escape hatch if you need them today):
/api/v1/answer+/api/v1/answer/batch(ticket answering surface)- Rule mutation beyond create/list (get/patch/delete/lint/batch), entity patch/soft-delete/batch-delete, triple patch/delete
/api/v1/kb/graph,/api/v1/audit/deletions,/api/v1/reason/strategy-stats, timestampedGET /api/v1/reason/v1/messages/count_tokens, low-level/api/v1/nsr/infer(+ensemble)- Flywheel candidates/curve analytics, model checkpoint management, WorkOS/admin routes
- Beliefs (
/api/v1/beliefs/*, 8 routes) and emulator (/api/v1/emulator/*, 8 routes) - Types & predicates (
/api/v1/types,/api/v1/types/predicates[/{name}],/api/v1/types/subtypes,/api/v1/types/validate) - Constraints (
/api/v1/constraintsCRUD +/api/v1/constraints/validate) - Policy tooling (
/api/v1/policy/evaluate|infer|train|vocab/init,/api/v1/policy/sandbox/evaluate) - Jobs (
/api/v1/jobs,/api/v1/jobs/batch-infer,/api/v1/jobs/{id}[/cancel]), standalone evidence (/api/v1/evidence[/{id}[/chain]],/api/v1/evidence/stats), codegen (/api/v1/codegen/generate|index|verify), sources (/api/v1/sources[/{id}]) - NSR internals:
/api/v1/nsr/got/*,/api/v1/nsr/vsa/*, symbol/program mutation & evaluation (/api/v1/nsr/symbolsbatch,/api/v1/nsr/programs[/evaluate|/{symbol_id}]),/api/v1/nsr/uncertainty,/api/v1/nsr/validate(+batch, validation cases/runs),/api/v1/nsr/recommend-strategy - NSR-L versioning (
/api/v1/nsrl/versions[/{id}[/rollback]]) POST /v1/metering/gcp/pubsub(inbound Google push endpoint — not client-callable)
Metadata
Release files for stateset-nsr 0.9.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| stateset_nsr-0.9.1.tar.gz | 43.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| stateset_nsr-0.9.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 78.5 kB
Release files / stateset_nsr-0.9.1.tar.gz
| Download URL | stateset_nsr-0.9.1.tar.gz |
|---|---|
| Size | 43.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ec581f7a84d4a244ba2b00aa6e8d373975daf4b28750dabd578256b89d3698c3
|
|
BLAKE2b-256 checksum How to use checksums |
3f4ef16b27fab1828cb379a6e1a89d00d845b361658797d9f92acd35649ec8f5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.8.10
|
Release files / stateset_nsr-0.9.1-py3-none-any.whl
| Download URL | stateset_nsr-0.9.1-py3-none-any.whl |
|---|---|
| Size | 34.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
63f17c71a7b8b274c43621a1a2f93be05bf974a2230aa678b50c1d01e1028d35
|
|
BLAKE2b-256 checksum How to use checksums |
1765130f9314f7a8804d0ce22cf49915df226c16b0c46063e6eecc6159198691
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.8.10
|