stalwart_agents.client
stalwart_agents.client: the client for the Stalwart API.
from stalwart_agents.client import Client
client = Client() # QLS_API_KEY
chat = client.session("desk", catalogue=catalogue)
plan = chat.read("show me the stock in depot HB-7")
The selector first -- catalogues, plans and sessions, computations, tool checks,
feedback and the hosted vocabulary -- then the guardrail solver, the bug hunter and the random forest
verifier. The Python carries no selector code: a turn is read by the licensed local
runtime, or by an enterprise qls-router the customer runs, never here and never by
Stalwart's hosted API. A plan's compute step runs on the customer's host as well, in
the sandbox image (Client.compute). A request bound for Stalwart's servers is scanned
for personal data first, and not sent on a match (PersonalDataError).
check_certificate checks a certificate on this machine, offline, with no key;
it is importable where nothing but the standard library is installed.
The event the iterator yields once when it falls back to polling.
One artefact of a job, fetched through the client that read the job.
An earlier job's artefact, passed as an input by its id.
One artefact of a job, fetched through the async client that read the job.
The Stalwart API, over HTTP, with plans and tool checks answered on your own host.
Args:
api_key: else QLS_API_KEY; else ConfigurationError naming the variable.
base_url: else QLS_BASE_URL; else https://api.stalwart.it: the solvers, the
catalogues, the licence and its bundles.
timeout: per HTTP request, not per solve.
max_retries: for the calls that are safe to repeat (see _core.retry_delay).
user_agent_suffix: appended to the user agent, so a customer's tooling is
identifiable in the service's logs.
runtime: who answers plans and tool checks. auto, the licensed local runtime
where it is installed and licensed, and the router otherwise; local, the
runtime alone; router, the router alone.
router_url: else QLS_ROUTER_URL: the enterprise qls-router you run in your own
environment, which answers plans and tool checks over HTTP. With neither a
usable runtime nor a router, a plan or a check raises SelectorUnavailableError.
own_identifiers: identifiers of your own that must never reach Stalwart's servers,
each a string (matched ignoring case) or a compiled pattern.
transport: an httpx transport, such as stalwart_agents.client.testing.replay(path).
The enterprise qls-router this client asks plans and tool checks of, where it names one.
Close the client's connections. async with AsyncClient() as client: does it for you.
Opens this machine's lease in the runtime, as Client.licensed does.
Raises: LicenceRequired: no licence is activated here, the service refused it, or it has lapsed.
Activates this machine's local runtime, once: its installation, the licence, the first lease.
Frees this machine's seat on the licence, so another installation can take it.
An air-gapped machine's activation request: its installation id and public key, for a file.
Carry the file to a machine that reaches the service and pass it to offline_lease there.
For an air-gapped machine's request file: its licence and a lease for the licence's whole term.
On the air-gapped machine: the licence and lease offline_lease answered, kept and opened.
Which side answers plans and checks -- local, router or none -- and the licence's state.
A calculation no tool answers, run on this host, as Client.compute runs it. The model is
called, and the sandbox waited on, off the event loop.
A conversation: the context the service returns, carried to the next turn.
session_id names the tool check's history chain; a fresh one by default. A
test replaying a cassette names it, so the recorded checks are the same requests.
Where on_unread is not given, the first turn takes the console's setting, or refuse.
One tool call checked, statelessly: history is the History the caller carries.
Registers the tools -- an MCP tools/list, LangChain tool schemas or an OpenAPI document -- as a new version.
A tool's declarations the bug hunter reads (argument_kinds, confidential,
retrieves, persists, source, server, ...) ride in its own metadata;
stores, budget and modules are the catalogue's own. The lint report says
where a declaration is missing or names a store that is not declared. A retry of
the same registration is one version.
rulebook is an agent's Colang rulebook (1.0 or 2.x) as text: the service compiles
it to the record the tool check evaluates, so the rules the agent is proved against
are the rules it runs under. rulebook_ir is that record compiled already, which
a tenant whose own build emits IR sends instead.
A rule sheet compiled to rulebook IR, with its catalogue overlay and its lints against the newest catalogue. Nothing is kept.
Compiles the sheet, saves it, and registers it on the newest catalogue as a new version. A retry of the same save is one version.
The sheet in force, with its text, and the versions saved before it.
Every registered version, newest first.
One version in full, or the newest; None where none is registered.
Registers an older version again, as the newest.
A user's thumb, or several, in the toolkit's record format. A retry is one record.
Screened before it is sent, as Client.feedback is: a record holding personal data
raises PersonalDataError, and nothing is sent.
What an attempt on a finding did: digests and the outcome, never a text. A retry is one attempt.
The tenant's live hosted vocabulary.
Queues the hosted miner over the tenant's feedback; read the run with ledger(run).
A learning run: its state, what it applied and its ledger.
Makes the version before the live one live again.
This key's tier, entitlements, limits and this month's use of each meter.
The commit, each image's version and digest, the solver's binary_version and the host this deployment runs.
Can action fire without context? An UNSAT verdict says no, with a certificate; SAT says how, with a repair.
A SAT verdict is the answer to the question and raises nothing.
enumerate_contexts is the wire's enumerate (a builtin in Python).
Asks your own model for the policy, then verifies it: the draft, its verdict, a repair, the shipping candidate.
The model's key comes from api_key or the environment variable api_key_env
names. It travels with this one request, and the SDK neither stores nor logs it.
A whole property table: one record per row, with counters derived from the records.
if result: is refused -- read .all_passed or .hard_failures.
The smallest pin sets under which each obligation holds; incomparable sets are all reported.
Candidate obligations read off the policy: rows with no id, expect or gate, for review.
The expectation table a sweep's rows derive, against a rulebook.
Asks the service to replay a certificate. To check one here, offline, use check_certificate().
replay is replayed, failed or out_of_scope; out of scope is a sound
refutation of a kind replay does not check, not an error.
An exported agent graph, verified before it is deployed: findings in the hunter's form.
The guardrail bug hunter: every way through to a forbidden action, each a finding with its fix.
dependencies is the file that pins what you install -- requirements.txt,
pyproject.toml, uv.lock or poetry.lock -- so a library rail a rails config
names is checked against an advisory's range at the version you run. inputs
carries any other input role the hunt takes (rails_config, intents,
vocabulary, probes, corpus, ...), by its role name.
A stall on this side concludes nothing: it is not evidence that a property holds.
Checks a trained forest (an ONNX-ML file or a Treelite JSON dump, sent as it is) against robustness, monotonicity, fairness and reachability properties.
Counterexamples searched around real records: proposals with no expect or gate, verdicts only.
This key's jobs, newest first, filtered by state and mode; cursor reads the next page.
Ask the service to cancel job job_id. A job already finished is left as it is.
The async iterator await client.stream(job_id) returns.
A submitted job, for wait=False: read it, wait for it, stream it, or cancel it.
Fetch the job again: its envelope, also kept on envelope.
A conversation over an AsyncClient. Made by client.session(...).
Report the calls a plan's chain asked for, and read the turn again with their results.
None when the results do not answer the chain.
Post the person's thumb on a plan's step step as one feedback record; corrected is the tool they meant.
Check one tool call against the catalogue, the rulebook and the session's history: allow, confirm or refuse.
401: no key, or a key that does not verify.
verify_batch: one record per row, and counters derived from the records.
A request the cassette does not hold.
A cassette recorded under a catalogue or vocabulary digest that has since moved.
What the checker established: verified, not_self_contained or failed, and why.
Returned for every outcome, a failed one included: an unverifiable certificate
is an answer, not an exception. scope is the sentence that travels with it --
a check establishes a derivation or a refutation, never that a policy is safe.
The Stalwart API, over HTTP, with plans and tool checks answered on your own host.
Args:
api_key: else QLS_API_KEY; else ConfigurationError naming the variable.
base_url: else QLS_BASE_URL; else https://api.stalwart.it: the solvers, the
catalogues, the licence and its bundles.
timeout: per HTTP request, not per solve.
max_retries: for the calls that are safe to repeat (see _core.retry_delay).
user_agent_suffix: appended to the user agent, so a customer's tooling is
identifiable in the service's logs.
runtime: who answers plans and tool checks. auto, the licensed local runtime
where it is installed and licensed, and the router otherwise; local, the
runtime alone; router, the router alone.
router_url: else QLS_ROUTER_URL: the enterprise qls-router you run in your own
environment, which answers plans and tool checks over HTTP. With neither a
usable runtime nor a router, a plan or a check raises SelectorUnavailableError.
own_identifiers: identifiers of your own that must never reach Stalwart's servers
-- a customer-number format, a name -- each a string (matched ignoring case) or
a compiled pattern. They are scanned for with the personal data.
transport: an httpx transport, such as stalwart_agents.client.testing.replay(path).
The enterprise qls-router this client asks plans and tool checks of, where it names one.
Opens this machine's lease in the runtime, refreshing it with the service where one is due, and returns where it stands. Everything the runtime computes needs it: the code checks, the sources' index, the reply checks and answers, a catalogue's lints.
Raises: LicenceRequired: no licence is activated here, the service refused it, or it has lapsed.
Activates this machine's local runtime, once: its installation, the licence, the first lease.
Frees this machine's seat on the licence, so another installation can take it.
An air-gapped machine's activation request: its installation id and public key, for a file.
Carry the file to a machine that reaches the service and pass it to offline_lease there.
For an air-gapped machine's request file: its licence and a lease for the licence's whole term.
On the air-gapped machine: the licence and lease offline_lease answered, kept and opened.
Which side answers plans and checks -- local, router or none -- and the licence's state.
A calculation no tool answers, run on this host: written by the caller's own model, admitted by
the runtime and run in the sandbox image. See stalwart_agents.compute.
step is a plan's compute step (or its instruction); sources the results of the read steps it
draws on, each {"tool", "result"}. model is any callable taking the prompt (a str) and
returning the function's source; the SDK holds no credential and calls no provider. Nothing of
the step is sent anywhere: the run is counted, and the count goes in the usage report.
Raises:
LicenceRequired: no licence is activated here, the service refused it, or it has lapsed.
QuotaExceededError: this month's compute_runs or compute_seconds are spent.
A conversation: the context the service returns, carried to the next turn.
session_id names the tool check's history chain; a fresh one by default. A
test replaying a cassette names it, so the recorded checks are the same requests.
Where on_unread is not given, the first turn takes the console's setting, or refuse.
One tool call checked, statelessly: history is the History the caller carries.
Registers the tools -- an MCP tools/list, LangChain tool schemas or an OpenAPI document -- as a new version.
A tool's declarations the bug hunter reads (argument_kinds, confidential,
retrieves, persists, source, server, ...) ride in its own metadata;
stores, budget and modules are the catalogue's own. The lint report says
where a declaration is missing or names a store that is not declared. A retry of
the same registration is one version.
rulebook is an agent's Colang rulebook (1.0 or 2.x) as text: the service compiles
it to the record the tool check evaluates, so the rules the agent is proved against
are the rules it runs under. rulebook_ir is that record compiled already, which
a tenant whose own build emits IR sends instead.
A rule sheet compiled to rulebook IR, with its catalogue overlay and its lints against the newest catalogue. Nothing is kept.
Compiles the sheet, saves it, and registers it on the newest catalogue as a new version. A retry of the same save is one version.
The sheet in force, with its text, and the versions saved before it.
Every registered version, newest first.
One version in full, or the newest; None where none is registered.
Registers an older version again, as the newest.
A user's thumb, or several, in the toolkit's record format. A retry is one record.
A record carries the words of the turn it rates, which the miner learns from, so it is
screened before it is sent: one holding personal data raises PersonalDataError, and
nothing is sent.
What an attempt on a finding did: digests and the outcome, never a text. A retry is one attempt.
The tenant's live hosted vocabulary.
Queues the hosted miner over the tenant's feedback; read the run with ledger(run).
A learning run: its state, what it applied and its ledger.
Makes the version before the live one live again.
This key's tier, entitlements, limits and this month's use of each meter.
The commit, each image's version and digest, the solver's binary_version and the host this deployment runs.
Can action fire without context? An UNSAT verdict says no, with a certificate; SAT says how, with a repair.
A SAT verdict is the answer to the question and raises nothing.
enumerate_contexts is the wire's enumerate (a builtin in Python).
Asks your own model for the policy, then verifies it: the draft, its verdict, a repair, the shipping candidate.
The model's key comes from api_key or the environment variable api_key_env
names. It travels with this one request, and the SDK neither stores nor logs it.
A whole property table: one record per row, with counters derived from the records.
if result: is refused -- read .all_passed or .hard_failures.
The smallest pin sets under which each obligation holds; incomparable sets are all reported.
Candidate obligations read off the policy: rows with no id, expect or gate, for review.
The expectation table a sweep's rows derive, against a rulebook.
Asks the service to replay a certificate. To check one here, offline, use check_certificate().
replay is replayed, failed or out_of_scope; out of scope is a sound
refutation of a kind replay does not check, not an error.
An exported agent graph, verified before it is deployed: findings in the hunter's form.
The guardrail bug hunter: every way through to a forbidden action, each a finding with its fix.
dependencies is the file that pins what you install -- requirements.txt,
pyproject.toml, uv.lock or poetry.lock -- so a library rail a rails config
names is checked against an advisory's range at the version you run. inputs
carries any other input role the hunt takes (rails_config, intents,
vocabulary, probes, corpus, ...), by its role name.
A stall on this side concludes nothing: it is not evidence that a property holds.
Checks a trained forest (an ONNX-ML file or a Treelite JSON dump, sent as it is) against robustness, monotonicity, fairness and reachability properties.
Counterexamples searched around real records: proposals with no expect or gate, verdicts only.
This key's jobs, newest first, filtered by state and mode; cursor reads the next page.
Ask the service to cancel job job_id. A job already finished is left as it is.
The prompt the runtime built for a calculation: the text a model is given, and its parts.
A str, so a model callable that takes one string works as it is: it is the
system part and the user part, in that order. system, user and schema are
there for a callable that sends roles. The schema is the sources' shape -- field
names and JSON types -- and never a value of theirs.
429: every concurrent slot is taken. Retried, honouring Retry-After, before it is raised.
No key, a bad base URL, or a runtime asked for that is not there.
What a confirm answer hands back, for the call once a person approved it. Opaque.
enumerate_counterexamples: proposals with no expect or gate, verdicts only.
derive_expectations: the derived table.
derive_pins: the obligations and their pin sets; the caveat is in caveats.
A download whose bytes do not hash to the digest the service named. No file is left behind.
enumerate_properties: candidate rows with no id, expect or gate; the caveat is in caveats.
One frame: its type, its place in the job's sequence, when, and its body.
The sync iterator client.stream(job_id) returns.
One hunt or graph finding: its rule, severity, location, witness, fix, replay state and OWASP entries.
verify_forest: one record per property. A stall on this side concludes nothing.
verify_guardrail and generate_and_verify.
The checks a session has made: entries of names and digests, and the token covering them.
Opaque: the SDK carries it and records the caller's report of what ran. An
entry edited by hand fails the next check with history_invalid.
The history as the wire carries it, to store and restore with from_dict.
hunt and verify_graph: findings, the coverage statement and the assumptions the scan used.
The OWASP coverage statement, at the policy level: the entries the hunter has rules for, those with no finding in this scan, and the one it has no rule for, with the reason.
The rules that raised nothing because nothing they read was declared, each with why.
409: an idempotency key spent on a different request.
413: an input past its cap. limit_bytes is the cap.
400: a request of the wrong shape. field names it where the service did.
A submitted job, for wait=False: read it, wait for it, stream it, or cancel it.
A job that ended failed: no payload. cause is the classified reason.
403: the key lacks a grant. entitlement names it.
404: no such object for this tenant.
One OWASP entry a finding realises: its list, its edition-qualified id, title and link.
A request bound for Stalwart's servers holds personal data, so nothing was sent.
findings lists each match by its kind and its field path, never its value; the
message says the same in words.
One match: its kind (a key of KINDS) and where it is. Never the value.
One step of a plan: a tool, ask, compute, decline or unread step, and the rule that made it.
A compute step carries its calculation in compute: the instruction, the result type
and the indices of the steps whose results it reads (sources).
Every error the SDK raises.
429 on a monthly meter: waiting will not help until it resets. Never retried.
429: a per-minute or per-stream limit. Retried, honouring Retry-After, before it is raised.
409 refused: a combination of choices that cannot answer the question asked.
slug is the registry's (REFUSALS), so code can branch on it without
matching English; explanation is the binary's own sentence.
replay_certificate, run by the service: replay is replayed, failed or out_of_scope.
Every job's answer: the verdict, its caveats, its artefacts and the binary's own object.
The reader's answer to one instruction: the call, or the question to ask instead.
5xx, after the retries. request_id is the service's, where it sent one.
A conversation over a Client. Made by client.session(...).
One turn, read with the session's context; the next context is kept.
The first turn takes the console's settings where the host gave none (see the module).
What the host's calls returned, each {"tool", "arguments", "result"}.
Where they are the chain the asking step named, they are sent now and the
plan they make is returned; otherwise they travel with the next read.
The user's thumb on a plan, posted as a feedback record; a retry is one record.
A tool call checked with the session's history, turns and agent; the history moves on.
A stream that could not be resumed, by streaming or by polling.
One tool call's answer: allow, confirm or refuse. No truth value: confirm is neither.
A turn read into steps, with the session's next context.
outcome is run, ask, declined or unread. A plan has no truth value:
"did it work" means four different things here. compute is what the host asked
for a calculation, run or off: a compute step in a plan asked off runs nowhere.
The unread steps the host's setting hands to its model; none on a declined plan.
The package's version: 1.0.
A session to_json wrote, restored over an async client.
Runs here, offline: checks a certificate on this machine with the vendored reference checker.
@p certificate is a path or the document's bytes. For an external_proof
certificate the CNF its proof_log names is read from cnf, or from beside a
certificate given by path.
A session to_json wrote, restored over @p client.