Catalog PyPI
PACKAGE EXPLORERView in registry

agaas-sdk

PyPI

Official Python SDK for AGaaS — the Autonomous Governance Gateway. Ask before you act.

agaasagentsai-safetycalibrationgovernance
Versions collected1
Direct dependencies4From release 0.1.3
Last observed20 Oct, 21:18 UTC

README

Version 0.1.3 documentation

agaas-sdk

Official Python SDK for AGaaS — the Autonomous Governance Gateway.

AGaaS answers one question about an autonomous action: should it proceed? The engines behind that answer are allowed to refuse, and this SDK is built so a refusal is impossible to mistake for approval.

pip install agaas-sdk          # no dependencies
from agaas_sdk import AgaasClient

with AgaasClient(api_key="agaas_live_…") as agaas:
    resp = agaas.caf_gate("acme", "checkout-agent", state, action)
    if resp:
        do_it()                       # allow
    else:
        hold(resp.verdict.reasons)    # abstain — every cause, not just the first

One call; your manifest decides. Which judges run is declared in your manifest — not in this code and not on your API key — so the key needs only caf:gate. Every decision lands in a tamper-evident chain (resp.audit_seq locates it), and an abstain is returned, not raised: it is a verdict you must act on, and the reasons say why.

The ten measurement engines are also callable directly, for calibration and analysis — see Direct engine calls. The four judges are not: they are reachable only through the gate.


Getting started from zero

The snippet above assumes you already hold a key. If you don't:

1. Create an account at https://agaas.phy357ai.com and add credits. Calls are metered — including calls that get refused, which is the main reason to care about the pre-flight section below.

2. Turn on the engines you intend to use, in the dashboard under Settings → Engines. This is per ACCOUNT, not per key. An engine that is off is refused with 403 engine_not_enabled wherever it could be reached.

3. Create the key under API Keys. It asks for a name and nothing else — the key inherits the operations enabled in Settings → Scopes, and follows them if you change your mind later. The secret is shown once.

4. Call something.

export AGAAS_API_KEY="agaas_live_…"
from agaas_sdk import AgaasClient

with AgaasClient() as agaas:
    print(agaas.limits())            # what this deployment will accept
    v = agaas.measure_transport(reference=yesterday, candidate=today)
    print(v.wasserstein)

Which door each engine is behind

Two kinds of engine, reached two different ways. This is the thing to get right before writing any code:

engineshow you call itgoverned by
JudgesCPE, Concord, Arrow, Covenantcaf_gate() onlyyour manifest and Settings → Engines
Measuresthe other tendirectlySettings → Engines

A judge produces a verdict, so the path it is reached by is the product: your manifest names which judges run, and the answer is hash-chained and replayable. Calling one directly would return the same number with no manifest and no chain, so it is refused:

agaas.govern_risk(...)      # 403 direct_engine_call — submit it to caf_gate()

A measure returns a number with no verdict and no abstain, and a manifest has no syntax to declare one — so the account switch is its whole security axis.

methodkind
govern_risk · govern_coherence · govern_driven · measure_guaranteejudge — via caf_gate()
govern_coherence_relative · certify_reach · measure_signature · measure_spectrum · measure_coordination · measure_transport · measure_topology · measure_topology_drift · measure_entropy_production · measure_consensusmeasure — direct

Note measure_guarantee (Covenant) is a judge despite the measure: prefix — it is judged, not measured. Grouping by prefix is the one mistake this table exists to prevent.

Which engine answers which question

No type can encode this, so it is the part worth reading rather than autocompleting:

you want to knowcall
is this action's near-term risk acceptable?govern_risk
is my agent swarm still aligned?govern_coherence
…and is this unusual for us specifically?govern_coherence_relative
is something really driving this, or is it noise?govern_driven
can I prove the system never reaches an unsafe state?certify_reach
are these actors coordinating, above chance?measure_coordination
how far has this distribution moved?measure_transport
do my prediction intervals still hold?measure_guarantee

Direct engine calls

The ten measurement engines can be called on their own — the right tool for calibration, analysis, or when you deliberately want one number rather than a governed verdict. They need no scope on the key; what they need is to be enabled for the account in Settings → Engines.

v = agaas.measure_transport(reference=last_week, candidate=today)

The four judges are not available this way. govern_risk, govern_coherence, govern_driven and measure_guarantee answer 403 direct_engine_call — submit the decision to caf_gate() and let your manifest declare which of them run.

What makes this different from a generated client

An AGaaS engine can decline to answer. Most SDKs have nowhere to put that, so it arrives as an error to swallow or a zero to misread. Three rules follow.

A refusal never looks like a number. sigma_above_null and divergence are unions on the wire — a float, or {"abstain": "reason"}. A binding typed as float works in testing and breaks in production the first time an engine declines. Here they are MetricValue, which is falsy when withheld and raises on arithmetic rather than reading as 0.0.

if result.divergence.available:
    use(float(result.divergence))
else:
    log(result.divergence.reason)

An abstain is never retried. A 422 is a verdict on your input, so the same payload abstains forever. Retrying bills you again to be refused again. The SDK retries 429, engine_at_capacity, infrastructure 503s and pre-response transport failures — nothing else.

Your key never touches a plaintext connection. A non-loopback http:// base URL raises at construction, before any I/O. http://127.0.0.1 stays allowed, because that traffic never reaches a wire.


The 422 trap

AGaaS returns two error formats that share status codes:

bodymeans
422 + {"error": …}JSON envelopethe engine abstained — valid input, refused answer
422 + plain textbare stringyour payload is malformed — a field has the wrong type

The second comes from the web framework before AGaaS code runs, so no envelope exists. Discriminating on status alone reports a client bug as a server verdict. This SDK discriminates on body shape (not Content-Type, which a proxy may rewrite) and raises AbstainedError vs BadRequestError accordingly.


Don't wait to be refused

Over-cap requests abstain. That costs no credits — an abstain returns before the audit commit, and the usage event rides that commit — but it still costs a round trip, a rate-limit token, and the time of whatever was waiting on the verdict. Pre-flight validation is on by default and catches them locally, using the server's own vocabulary:

agaas.govern_coherence({"solo": [1.0, 2.0]})
# LimitViolation: coherence: too_few_agents — got 1, graph connectivity needs >= 3

Nothing was sent. Offline, and free:

agaas-calibrate check coherence payload.json
agaas-calibrate limits --offline

Is my setup right? — doctor

The first-run failures look alike from the outside and have completely different fixes: a dead key (401), an engine switched off (403), a judge you tried to call directly (403, different reason), and an empty balance (402). Finding them one at a time through failed calls is a poor introduction to a governance API.

agaas-calibrate doctor
server   https://agaas.phy357ai.com
reach    ok
key      valid
caps     12 engines, live from server

engines
  [ok]        measure:transport
  [gate]      govern:risk          judge — call it through caf_gate()
  [off]       measure:spectrum     off for this account (AGaaS Settings → Engines)

summary  1 callable, 4 via the gate, 9 off

It costs no credits, and that is checkable rather than a promise. The guard decides before the rate limit and long before the handler, so a refused probe consumes nothing; a permitted one passes the guard and the deliberately unparseable probe body is rejected by the JSON extractor — no handler runs, no audit is committed, and the usage event rides that same commit.

None of [gate], [off] or [absent] is an error: a judge being gate-only is the design, and an engine switched off is a deliberate choice. For CI, name what you actually need:

agaas-calibrate doctor --require measure_transport,measure_spectrum

That fails the build before your workload meets its first 403 in production.

Server compatibility. Older deployments refuse GET /v1/limits. When a server does, limits() falls back to an embedded snapshot and sets .stale = True — an SDK cannot assume the deployment it is pointed at has been upgraded. Check that flag before treating a cap as authoritative.


Calibration

Several engines are relative: they answer "is this unusual for you", which is unanswerable until they know what usual looks like. The full guide — which engine needs what, and the mistakes that silently disable a gate — is in CALIBRATION.md. In short, skipping calibration gives you one of two quiet failures:

  • a gate that abstains forever (never enough history), or
  • a gate that never fires — a baseline so wide nothing is anomalous.

The second is the dangerous one. A governance gate that approves everything is indistinguishable from a working one until the day it was meant to stop something.

agaas-calibrate run history.json -o baselines.json   # offline, free
agaas-calibrate verify baselines.json                # one real call per engine
from agaas_sdk import calibrate_coherence

cal = calibrate_coherence(past_coherence_values)
if not cal.ready:
    print(cal.missing)   # "22 more observations (have 8, want >= 30)"

Everything is computed from data you supply. There is no synthetic default and no "typical" baseline, because one copied from someone else's traffic produces confident verdicts about a distribution that was never observed. Where history is insufficient, calibration refuses and says what is missing — the same stance the engines take. run exits non-zero if anything is blocked, so CI can gate on it.

Two failures it catches that are otherwise silent:

  • Constant history. Zero variance means the z-score divides by zero and nothing can ever be anomalous.
  • Arrow's null band on the wrong scale. govern_driven compares the engine's entropy-production rate of your live series against a null band, so the band must be entropy-production rates too — build it with measure_null_scores, which measures each equilibrium window through the engine. A locally-invented statistic miscalibrates the gate. (Arrow is also the one calibrator that sends data to the service — see CALIBRATION.md.)

Design

Hexagonal, with three ports (Transport, Clock, CredentialStore) as structural Protocols. Supply your own by shape — no subclassing.

client = AgaasClient(key, transport=MyRecordingTransport(), clock=FakeClock())

The whole test suite runs with no network and no wall-clock time.

Zero required dependencies. The default transport is urllib. This package carries a credential, and every transitive dependency is code that could read it. pip install agaas-sdk[httpx] adds pooling and HTTP/2; agaas-sdk[async] adds AsyncAgaasClient.

Request construction lives in one module shared by both clients, and the calibration CLI ships inside the SDK rather than beside it. Splitting them puts the same credential handling in two codebases, where a fix applied to one can silently miss the other.


Coverage

All 14 engines: govern_risk · govern_coherence · govern_coherence_relative · govern_driven · certify_reach · measure_signature · measure_spectrum · measure_coordination · measure_transport · measure_topology · measure_topology_drift · measure_entropy_production · measure_guarantee · measure_consensus

Errors

exceptionstatusretried
AbstainedError422 + envelopenever — same input abstains forever
BadRequestError400 / 415 / 422 plainnever — the bug is local
AuthenticationError401no
PermissionError_403no
PaymentRequiredError402no — carries topup_url
PayloadTooLargeError413no
RateLimitError429yes, honouring Retry-After
CapacityError503 engine_at_capacityyes — clears in ~1 s
ServiceUnavailableError503 infrayes, backing off hard
ServerError500no — deterministic engines fail identically
TransportErrorno responseyes

Backoff jitter is derived by hashing (key, attempt): reproducible for one client, decorrelated across clients, so a fleet does not retry in lockstep after a shared outage.


Support and security

Questions, bugs: scitechfamily357@gmail.com (agaas-sdk in the subject).

Security issues: report them privately to the same address — see SECURITY.md. This package handles API credentials, so a public report exposes every installed copy before a fixed version can ship, and a released version on an index can never be overwritten, only superseded.

Never include a real API key in a report. If one leaked, rotate it in the dashboard first — that is faster and more certain than any fix.

License

MIT

Downloads & popularity

1downloads
1-day window · source-reported counts15 Oct 2026
17587.50
2026-07-28: 175 · observed 2026-10-20T21:57:12.5218116Z · period 2026-07-28–2026-07-282026-07-29: 34 · observed 2026-10-20T21:57:12.5218116Z · period 2026-07-29–2026-07-292026-07-31: 92 · observed 2026-10-20T21:57:12.5218116Z · period 2026-07-31–2026-07-312026-08-01: 12 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-01–2026-08-012026-08-02: 6 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-02–2026-08-022026-08-03: 15 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-03–2026-08-032026-08-04: 6 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-04–2026-08-042026-08-05: 4 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-05–2026-08-052026-08-06: 102 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-06–2026-08-062026-08-07: 4 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-07–2026-08-072026-08-08: 5 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-08–2026-08-082026-08-09: 6 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-09–2026-08-092026-08-11: 21 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-11–2026-08-112026-08-13: 7 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-13–2026-08-132026-08-14: 6 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-14–2026-08-142026-08-17: 10 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-17–2026-08-172026-08-18: 4 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-18–2026-08-182026-08-20: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-20–2026-08-202026-08-22: 4 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-22–2026-08-222026-08-23: 3 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-23–2026-08-232026-08-24: 6 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-24–2026-08-242026-08-27: 9 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-27–2026-08-272026-08-28: 10 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-28–2026-08-282026-08-31: 2 · observed 2026-10-20T21:57:12.5218116Z · period 2026-08-31–2026-08-312026-09-01: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-01–2026-09-012026-09-04: 2 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-04–2026-09-042026-09-07: 5 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-07–2026-09-072026-09-10: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-10–2026-09-102026-09-12: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-12–2026-09-122026-09-13: 9 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-13–2026-09-132026-09-14: 10 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-14–2026-09-142026-09-15: 2 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-15–2026-09-152026-09-16: 9 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-16–2026-09-162026-09-18: 2 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-18–2026-09-182026-09-20: 8 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-20–2026-09-202026-09-21: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-21–2026-09-212026-09-22: 5 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-22–2026-09-222026-09-23: 2 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-23–2026-09-232026-09-26: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-26–2026-09-262026-09-27: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-27–2026-09-272026-09-28: 2 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-28–2026-09-282026-09-30: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-09-30–2026-09-302026-10-01: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-01–2026-10-012026-10-02: 3 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-02–2026-10-022026-10-03: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-03–2026-10-032026-10-04: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-04–2026-10-042026-10-06: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-06–2026-10-062026-10-07: 11 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-07–2026-10-072026-10-09: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-09–2026-10-092026-10-10: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-10–2026-10-102026-10-11: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-11–2026-10-112026-10-12: 2 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-12–2026-10-122026-10-13: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-13–2026-10-132026-10-15: 1 · observed 2026-10-20T21:57:12.5218116Z · period 2026-10-15–2026-10-15
28 Jul15 Oct

pypistats · 54 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-15 – 2026-10-1512026-10-20T21:57:12.5218116Z
2026-10-13 – 2026-10-1312026-10-20T21:57:12.5218116Z
2026-10-12 – 2026-10-1222026-10-20T21:57:12.5218116Z
2026-10-11 – 2026-10-1112026-10-20T21:57:12.5218116Z
2026-10-10 – 2026-10-1012026-10-20T21:57:12.5218116Z
2026-10-09 – 2026-10-0912026-10-20T21:57:12.5218116Z
2026-10-07 – 2026-10-07112026-10-20T21:57:12.5218116Z
2026-10-06 – 2026-10-0612026-10-20T21:57:12.5218116Z
2026-10-04 – 2026-10-0412026-10-20T21:57:12.5218116Z
2026-10-03 – 2026-10-0312026-10-20T21:57:12.5218116Z
2026-10-02 – 2026-10-0232026-10-20T21:57:12.5218116Z
2026-10-01 – 2026-10-0112026-10-20T21:57:12.5218116Z
2026-09-30 – 2026-09-3012026-10-20T21:57:12.5218116Z
2026-09-28 – 2026-09-2822026-10-20T21:57:12.5218116Z
2026-09-27 – 2026-09-2712026-10-20T21:57:12.5218116Z
2026-09-26 – 2026-09-2612026-10-20T21:57:12.5218116Z
2026-09-23 – 2026-09-2322026-10-20T21:57:12.5218116Z
2026-09-22 – 2026-09-2252026-10-20T21:57:12.5218116Z
2026-09-21 – 2026-09-2112026-10-20T21:57:12.5218116Z
2026-09-20 – 2026-09-2082026-10-20T21:57:12.5218116Z
2026-09-18 – 2026-09-1822026-10-20T21:57:12.5218116Z
2026-09-16 – 2026-09-1692026-10-20T21:57:12.5218116Z
2026-09-15 – 2026-09-1522026-10-20T21:57:12.5218116Z
2026-09-14 – 2026-09-14102026-10-20T21:57:12.5218116Z
2026-09-13 – 2026-09-1392026-10-20T21:57:12.5218116Z
2026-09-12 – 2026-09-1212026-10-20T21:57:12.5218116Z
2026-09-10 – 2026-09-1012026-10-20T21:57:12.5218116Z
2026-09-07 – 2026-09-0752026-10-20T21:57:12.5218116Z
2026-09-04 – 2026-09-0422026-10-20T21:57:12.5218116Z
2026-09-01 – 2026-09-0112026-10-20T21:57:12.5218116Z
2026-08-31 – 2026-08-3122026-10-20T21:57:12.5218116Z
2026-08-28 – 2026-08-28102026-10-20T21:57:12.5218116Z
2026-08-27 – 2026-08-2792026-10-20T21:57:12.5218116Z
2026-08-24 – 2026-08-2462026-10-20T21:57:12.5218116Z
2026-08-23 – 2026-08-2332026-10-20T21:57:12.5218116Z
2026-08-22 – 2026-08-2242026-10-20T21:57:12.5218116Z
2026-08-20 – 2026-08-2012026-10-20T21:57:12.5218116Z
2026-08-18 – 2026-08-1842026-10-20T21:57:12.5218116Z
2026-08-17 – 2026-08-17102026-10-20T21:57:12.5218116Z
2026-08-14 – 2026-08-1462026-10-20T21:57:12.5218116Z
2026-08-13 – 2026-08-1372026-10-20T21:57:12.5218116Z
2026-08-11 – 2026-08-11212026-10-20T21:57:12.5218116Z
2026-08-09 – 2026-08-0962026-10-20T21:57:12.5218116Z
2026-08-08 – 2026-08-0852026-10-20T21:57:12.5218116Z
2026-08-07 – 2026-08-0742026-10-20T21:57:12.5218116Z
2026-08-06 – 2026-08-061022026-10-20T21:57:12.5218116Z
2026-08-05 – 2026-08-0542026-10-20T21:57:12.5218116Z
2026-08-04 – 2026-08-0462026-10-20T21:57:12.5218116Z
2026-08-03 – 2026-08-03152026-10-20T21:57:12.5218116Z
2026-08-02 – 2026-08-0262026-10-20T21:57:12.5218116Z
2026-08-01 – 2026-08-01122026-10-20T21:57:12.5218116Z
2026-07-31 – 2026-07-31922026-10-20T21:57:12.5218116Z
2026-07-29 – 2026-07-29342026-10-20T21:57:12.5218116Z
2026-07-28 – 2026-07-281752026-10-20T21:57:12.5218116Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.36 Aug 20264

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:18 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:251a5d4c07626992f4621edcaea4b877ceab0801a44ef413dc5412b0a5a52a75