Skip to main content

Sentinel SDK

License: MIT PyPI version

Oversight infrastructure for AI agents.

Sentinel adds human-in-the-loop approval to any Python function your agent calls. Wrap the function with @oversight, and the SDK pauses execution, requests approval, and only runs once a human approves.

Install

pip install sentinel-oversight

Quick start

# 1. Create an account at https://app.pauseapi.app/signup
#    Copy the API key it returns.

# 2. Wrap your function:
from sentinel import configure, oversight

configure(api_key="sk_live_…")

@oversight(
    risk_level="high",
    approvers=["sms:+15551234567", "alice@acme.com"],
    timeout_seconds=300,
)
def transfer_funds(amount: int, recipient: str):
    return stripe.transfers.create(amount=amount, destination=recipient)

When your agent calls transfer_funds(1000, "acct_xyz"):

  1. Sentinel pauses execution and creates an approval on the backend.
  2. Notifications fire to every approver in the list (rules below).
  3. A human clicks Approve from a signed text/email link or the dashboard.
  4. The wrapped function runs, and its return value flows back to the caller.

If rejected → ApprovalRejected(reason) is raised. If no response within timeout_secondsApprovalTimeout is raised (unless fallback="execute").

Approver formats

Each entry in approvers=[...] is a string. The format determines the channel.

Format Channel Example
name@company.com Email alice@acme.com
mailto:name@company.com Email (explicit) mailto:alice@acme.com
sms:+15551234567 SMS (Twilio) sms:+14155550123 — requires consent, see SMS approvers

You can mix formats — every approver receives a notification, the first decision wins.

Notification routing

  • Email — fires if RESEND_API_KEY is set AND any approver looks like an email address. Email contains signed approve/reject links (HMAC-SHA256, scoped to that action_id and timeout window).
  • SMS — fires if Twilio credentials are set AND an approver uses sms:.

By default, emails send from onboarding@resend.dev. To get branded approvals@yourdomain.app email, verify your domain in Resend (Pro plan).

SMS approvers — TCPA consent

To use sms:+1... approvers you must first register an opt-in record for each phone number. Sentinel won't create an approval whose approvers include an SMS destination without an active consent record — the API returns 400 SMS approver requires active SMS consent contact.

from sentinel import SentinelClient
client = SentinelClient()

# One-time, per phone number, after you've collected a real opt-in:
client.register_sms_contact(
    phone_number="+15551234567",
    display_name="Maya (CTO)",
    consent_source="onboarding_checkbox",       # e.g. "signed_form", "captured_web_form"
    consent_note="Checked the SMS opt-in box during signup on 2026-05-25",
)

Other helpers:

client.list_sms_contacts()           # all active + revoked contacts for this tenant
client.revoke_sms_contact("con_…")   # marks consent revoked; future SMS won't send

The customer can also reply STOP to any Sentinel SMS — the Twilio inbound webhook (/webhooks/twilio/inbound) automatically revokes their consent record. HELP returns a description and contact info. These two keywords are TCPA-mandated.

Default approvers

If you don't want to pass approvers=[...] on every decorator, set a default on your tenant. The API falls back to the tenant's default_approvers when the caller's list is empty.

from sentinel import SentinelClient
client = SentinelClient()

client.set_default_approvers(["sms:+15551234567", "ops@yourcompany.com"])
# now any @oversight(...) call without approvers uses these

Read or override via the web UI at https://app.pauseapi.app/contacts.

Resolution order when an approval is created:

  1. The caller's explicit approvers=[...] (if non-empty)
  2. The tenant's saved default_approvers
  3. The global DEFAULT_APPROVERS env var on the API
  4. 400 error if all three are empty

Risk levels

risk_level is a string the dashboard uses for prioritization. Allowed values: low, medium, high, critical. Required.

Configuration

Set via configure(...) or environment variables:

Variable Default Description
SENTINEL_API_URL https://api.pauseapi.app Base URL of the Sentinel backend
SENTINEL_API_KEY required Your tenant API key
SENTINEL_TIMEOUT 300 Default timeout_seconds
SENTINEL_POLL_INTERVAL 2 Seconds between status polls
SENTINEL_FALLBACK reject reject or execute on timeout

Exceptions

  • SentinelError — base class for all Sentinel errors.
  • SentinelConfigError — SDK was used without an api_key.
  • SentinelAPIError(status_code, message, url) — backend returned a non-2xx.
  • ApprovalRejected(reason, action_id) — a human rejected the request.
  • ApprovalTimeout(action_id, timeout_seconds) — no decision before deadline.

Async

The decorator transparently supports async def functions:

@oversight(risk_level="medium", approvers=["alice@acme.com"])
async def send_email(to, body):
    await mailgun.send(to=to, body=body)

Audit log

Every approval creates a hash-chained audit trail. Fetch it:

from sentinel import SentinelClient
client = SentinelClient()
events = client.list_audit_events(action_id="act_…")  # or omit for full log

Each event has prev_hash and event_hash (SHA-256). Chain integrity can be verified by recomputing sha256(prev_hash + json(payload)).

LangChain

from sentinel.adapters.langchain import SentinelCallbackHandler

agent.run("…", callbacks=[SentinelCallbackHandler(risk_level="high")])

Install with pip install sentinel-oversight[langchain].

Links

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sentinel_oversight-0.1.9.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sentinel_oversight-0.1.9-py3-none-any.whl (15.0 kB view details)

Uploaded Python 3

File details

Details for the file sentinel_oversight-0.1.9.tar.gz.

File metadata

  • Download URL: sentinel_oversight-0.1.9.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sentinel_oversight-0.1.9.tar.gz
Algorithm Hash digest
SHA256 f36f1517666a0e7474d0a5755a13996269c70fb0b00f33cec419aa6ca255e282
MD5 e494bdacbaad4cb44f63678cc5633d33
BLAKE2b-256 7d22e67db9fd15019210fb612000109eed1d14885467b175a8b8cd8643ad3180

See more details on using hashes here.

Provenance

The following attestation bundles were made for sentinel_oversight-0.1.9.tar.gz:

Publisher: publish.yml on PetrefiedThunder/sentinel-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sentinel_oversight-0.1.9-py3-none-any.whl.

File metadata

File hashes

Hashes for sentinel_oversight-0.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 454d1e49872162633c6bde3da13faa19cc4abfa9ed8b3368914dc381f4ac1e41
MD5 0795fd61ef1e05b44b1a5541a3107ad9
BLAKE2b-256 33f2d1c5abc9c241e8c0b0138ed577e7cb83241a470429beba50132e028af69f

See more details on using hashes here.

Provenance

The following attestation bundles were made for sentinel_oversight-0.1.9-py3-none-any.whl:

Publisher: publish.yml on PetrefiedThunder/sentinel-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.9 This release

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page