Skip to main content

Official Python client for the PsiGuard guarded-chat API.

Project description

PsiGuard Python SDK

The official Python client for the PsiGuard guarded-chat API.

PsiGuard wraps a language model with a live structural monitor. You send it a prompt; it runs the model, watches the generation as it happens, and hands you back a clean answer plus one coarse signal telling you whether it had to step in. Everything about how it decides stays on PsiGuard's servers — this client only ever sees the answer and that one signal.

Install

pip install psiguard

The only dependency is requests. The whole client is a single module, so you can also just drop psiguard.py into your project and import it.

Quick start

from psiguard import Client

client = Client(api_key="psg_live_your_key_here")

result = client.guard("What is your return policy?")
print(result.answer)        # the reply to show your user
print(result.protection)    # "safe" | "caution" | "intervened"

Set PSIGUARD_API_KEY in your environment and you can skip passing the key:

client = Client()           # reads PSIGUARD_API_KEY

Get a key from your dashboard at psiguard.net/dashboard/keys.

Give your assistant a personality

result = client.guard(
    "Do you ship to Canada?",
    system_prompt="You are a friendly support agent for Acme Tools.",
    conversation_id="cust-8472",
)

Multi-turn conversations

Reuse one thread so monitoring keeps context across the chat. The Conversation helper manages the id and transcript for you:

chat = client.conversation(system_prompt="You are Acme's support assistant.")

chat.send("Hi, my order hasn't arrived.")
reply = chat.send("It's order 1234.")   # remembers the turn before it

print(reply.answer)

Reading the protection signal

Every turn comes back with one of three values. A simple integration can ignore it and just show answer.

value meaning
safe Clean run. PsiGuard didn't need to act.
caution PsiGuard steered the response back on course. answer is the corrected one.
intervened PsiGuard withheld the response. answer is a neutral refusal, safe to show as-is.
result = client.guard(prompt)
if result.intervened:
    log.info("PsiGuard stepped in on this turn")
show_to_user(result.answer)

Seeing the status in your terminal

When you're the one at the keyboard — a script, a smoke test, a support tool — the protection value is easy to miss in a wall of plain white text. These optional helpers make it impossible to miss:

from psiguard import Client, format_result

result = Client().guard("What is your return policy?")
print(format_result(result))
● SAFE  clean run — PsiGuard didn't need to act
│ Our return policy allows returns within 30 days of delivery...

▲ CAUTION  steered back on course mid-answer
│ I'd check with support on that specific case...

■ INTERVENED  response withheld — the answer below is a refusal
│ I'm not able to help with that.

Green dot, amber triangle, red square — so it still reads when it's colorless or when the reader is colorblind. badge(result.protection) gives you just the chip if you'd rather build your own layout around it.

The client never prints, and never puts color inside result.answer. That string is what your user sees, and it may end up in a log file, a database, or a web page — where terminal color codes turn into visible junk like ←[32m. So color lives only in these display helpers, which you call when you want them. format_result also turns color off by itself when output isn't a real terminal (piped to a file, running in CI), and honors the standard NO_COLOR environment variable. Set PSIGUARD_COLOR=1 to force it on.

Handling errors

Everything the client raises inherits from PsiGuardError, so you can catch broadly or narrowly:

from psiguard import (
    Client, UsageLimitError, RateLimitError,
    AuthenticationError, PsiGuardError,
)

try:
    result = client.guard(prompt)
except AuthenticationError:
    ...   # key missing, invalid, or revoked
except RateLimitError:
    ...   # too many requests — slow down and retry shortly
except UsageLimitError as e:
    ...   # monthly cap or provider budget reached — a stop sign, not a retry
          # e.scope, e.plan, e.provider, e.used, e.limit, e.month
except PsiGuardError as e:
    ...   # anything else

The client automatically retries the failures that are safe to retry (connection errors and 5xx), and never retries the ones that aren't (4xx and usage caps). Tune it with Client(..., max_retries=2, timeout=60).

Verify a key

who = client.whoami()       # runs no model, isn't metered
print(who.account)

Configuration reference

Parameter Default Notes
api_key $PSIGUARD_API_KEY Your psg_live_… key.
base_url $PSIGUARD_BASE_URL or https://psiguard.net Your PsiGuard host.
timeout 60 Per-request timeout in seconds.
max_retries 2 Extra attempts for retryable failures only.

The client keeps a connection pool open; reuse one Client for the life of your process, and use it as a context manager to close the pool when done:

with Client() as client:
    client.guard("hello")

A note on what's inside

This client is a courier, not the engine. It contains none of PsiGuard's internal workings — no metrics, no thresholds, no scoring. It speaks only the public contract: a prompt goes out, an answer and a protection signal come back. PsiGuard's monitoring framework is proprietary and confidential, protected as a trade secret of PsiCo, LLC.


© PsiCo, LLC. Licensed for use through the PsiGuard API.

Project details


Download files

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

Source Distribution

psiguard-1.1.0.tar.gz (12.0 kB view details)

Uploaded Source

Built Distribution

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

psiguard-1.1.0-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file psiguard-1.1.0.tar.gz.

File metadata

  • Download URL: psiguard-1.1.0.tar.gz
  • Upload date:
  • Size: 12.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for psiguard-1.1.0.tar.gz
Algorithm Hash digest
SHA256 6eeacbfef953e62a2cdfa136ad1fffd6cc5a5737dbe075c8b9a7844399c04380
MD5 41c91c5ad7cb4ba6c31a8683f6a376c5
BLAKE2b-256 e69a78f103d7ec2328ac47c728fe2d0defe8eae5b3145fc21f51a2d2b817010b

See more details on using hashes here.

File details

Details for the file psiguard-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: psiguard-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for psiguard-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8818629d9a54c14b0ee1c405571d4364fea43de84ee2a30a9bd07c41b8752c57
MD5 0e593e05a7bfef9a037dc46ffb0d12c9
BLAKE2b-256 dbe974154e824fa18a2908623871df8b45658fa6cd772bbb8f75af12fe7774c0

See more details on using hashes here.

Supported by

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