Skip to main content
prysm1 subclasses openai.OpenAI, so all your existing OpenAI code works unchanged — plus helpers for routing previews, usage, savings, proof verification, and BRAIN.md auto-discovery.
pip install prysm1

Drop-in replacement for OpenAI

from prysm import Prysm

client = Prysm()  # api_key from $PRYSM_API_KEY, base_url from $PRYSM_BASE_URL

resp = client.chat.completions.create(
    model="auto",                       # let PRYSM pick the best model
    messages=[{"role": "user", "content": "Write a Python quicksort"}],
)
print(resp.choices[0].message.content)
Already using openai? You don’t have to install prysm1 at all — just point the official client at PRYSM’s base URL. The SDK is for the extra ergonomics below.

Access the PRYSM extensions

Every response carries a prysm block (routing, cost, latency, proof). Use extension() for clean dot-access:
import prysm

ext = prysm.extension(resp)
print(ext.routing.model_display)  # "DeepSeek V3.2"
print(ext.routing.reason)         # why this model was chosen
print(ext.cost.total_usd)         # 0.000042
print(ext.proof.proof_hash)       # "sha256:a1b2c3d4..."
extension() returns None for responses without a prysm block, so it’s safe to call on any completion.

BRAIN.md auto-discovery

Drop a BRAIN.md in your project root and the SDK finds it automatically, applying your routing rules, cost caps, and blocked models:
client = Prysm()                                   # discovers ./BRAIN.md (walks up from cwd)
resp = client.complete("Summarize this contract")  # BRAIN.md applied
Point it explicitly, pass a dict, or disable:
Prysm(brain="path/to/BRAIN.md")
Prysm(brain={"max_cost": 0.005, "model": "deepseek-v3.2"})
Prysm(brain=None)                # ignore BRAIN.md

Orchestration (v2)

Beyond routing to one model, orchestrate() runs a prompt across several models — cascading, ensembling, decomposing, or debating — and returns one synthesized answer plus a PrysmProof v2. Pick the objective with a policy; PRYSM plans the strategy (or you force one). See How orchestration works.
r = client.orchestrate(
    "Compare three database designs for a 40-person team",
    policy="depth",            # "efficiency" | "balanced" | "depth"
)
print(r["choices"][0]["message"]["content"])
print(r["prysm"]["orchestration"]["models_used"])  # which models contributed
print(r["prysm"]["orchestration"]["agreement"])    # how strongly they agreed
Force a strategy, widen the ensemble, or cap spend:
r = client.orchestrate(
    "Prove that the square root of 2 is irrational",
    policy="depth",
    strategy="debate",         # single | cascade | ensemble_moa | rank_fuse |
                               # decompose_and_route | self_consistency | debate
    k=3,                       # ensemble / sample width
    max_cost_usd=0.05,         # soft budget hint, USD
)

Code Mode (v2)

code() writes code, reviews it with a separate critic model, and repairs against that feedback until the review passes or a budget/iteration cap is hit. In depth, several diverse coders run in parallel and the best candidate is kept. PRYSM never executes the generated code. See How Code Mode works.
r = client.code(
    "Write a thread-safe LRU cache in Python with tests",
    policy="depth",            # "efficiency" | "balanced" | "depth"
)
for f in r["files"]:
    print(f["path"]); print(f["content"])
print(r["passed"])                              # did the critic pass?
print(r["prysm"]["code"]["coder_models"])       # who wrote it
print(r["prysm"]["proof"]["proof_hash"])        # verifiable proof
Force the models, cap iterations, or skip the critic loop for a single shot:
r = client.code(
    "Implement rate limiting middleware",
    coder_model="claude-sonnet-4.5",   # who writes the code
    reviewer_model="deepseek-r1",      # who critiques it
    max_iters=4,                       # generate + up to 3 repairs
    max_cost_usd=0.10,                 # soft budget hint, USD
)

quick = client.code("Write a Python hello world", review=False)  # single shot, no critic

Compliance (v2)

Load the providers your organization approves and PRYSM routes only to models that satisfy your policy — non-compliant models are filtered out before scoring. See compliance routing. compliance_preview() is a pure dry-run (no model call, no keys needed): it shows which models a policy allows vs excludes, the Compliance Cost Premium, and a sample attestation.
p = client.compliance_preview(
    "summarize this report",
    compliance={"jurisdiction": ["EU"], "frameworks": ["GDPR"], "data_residency": ["EU"]},
)
print(p["allowed_models"])           # only EU/GDPR providers survive
print(p["compliance_cost_premium"])  # what compliance costs vs. unrestricted
Then enforce the same policy on a real run — orchestrate() (and complete()) accept a compliance= spec. Excluded models can never be selected, and the result carries a compliance decision plus an attestation in its PrysmProof:
r = client.orchestrate(
    "Explain photosynthesis.",
    policy="balanced",
    compliance={"provider_allowlist": ["anthropic"]},  # confine to approved providers
)
print(r["prysm"]["compliance"])                  # the exclusion decision
print(r["prysm"]["proof"]["compliance"])         # the attestation
Prefer to declare it once and version it: put a compliance: block in your BRAIN.md and it applies to every request automatically.

Helpers

MethodDescription
client.complete(prompt, ...)One-shot chat with model="auto" + BRAIN.md auto-applied.
client.orchestrate(prompt, policy=..., strategy=...)Multi-model orchestration (v2): cascade / ensemble / debate + PrysmProof.
client.code(task, policy=..., review=...)Code Mode (v2): self-correcting, multi-model code generation + PrysmProof.
client.compliance_preview(prompt, compliance=...)Compliance preview (v2): dry-run the policy gate — allowed/excluded models, CCP, attestation. No model call.
client.route(prompt, mode=None)Dry run: which model + estimated cost, no model call.
client.usage()Usage stats for your key.
client.savings(baseline="gpt-5.2")Estimated $ saved vs. an all-premium baseline.
client.verify_proof(request_id)Verify a PrysmProof.
client.validate_brain(text_or_dict)Validate a BRAIN.md config.
client.models_catalog()The 19-model catalog with pricing.
client.route("debug this function")     # dry-run: which model, est. cost (no call)
client.usage()                          # your usage stats
client.savings(baseline="gpt-5.2")      # est. $ saved vs. an all-premium baseline
client.verify_proof(request_id)         # verify a PrysmProof
client.models_catalog()                 # 21 models with pricing

Validate a BRAIN.md before shipping

print(client.validate_brain(open("BRAIN.md").read()))
# {'valid': True, 'errors': [], 'warnings': [], 'normalized': {...}}

Configuration

SettingArgumentEnv varDefault
API keyapi_key=PRYSM_API_KEY
Base URLbase_url=PRYSM_BASE_URLhttps://api.prysm1.com/v1
BRAIN.mdbrain="auto" (discover)
If PRYSM_API_KEY is unset, the SDK falls back to OPENAI_API_KEY — so migrating existing code can be a one-line base-URL change.

Next steps

CLI

prysm1 ships a prysm command for routing, models, validation, and usage.

API reference

The endpoints these helpers call, documented field by field.