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)
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stateset_nsr-0.9.1.tar.gz.
File metadata
- Download URL: stateset_nsr-0.9.1.tar.gz
- Upload date:
- Size: 43.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec581f7a84d4a244ba2b00aa6e8d373975daf4b28750dabd578256b89d3698c3
|
|
| MD5 |
1334a51dba9f2943cb61de4ddd6b8b25
|
|
| BLAKE2b-256 |
3f4ef16b27fab1828cb379a6e1a89d00d845b361658797d9f92acd35649ec8f5
|
File details
Details for the file stateset_nsr-0.9.1-py3-none-any.whl.
File metadata
- Download URL: stateset_nsr-0.9.1-py3-none-any.whl
- Upload date:
- Size: 34.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63f17c71a7b8b274c43621a1a2f93be05bf974a2230aa678b50c1d01e1028d35
|
|
| MD5 |
321696eb6e55e7e5ce952a0f0c318c8e
|
|
| BLAKE2b-256 |
1765130f9314f7a8804d0ce22cf49915df226c16b0c46063e6eecc6159198691
|