stalwart-agents
Declare an agent in one file: its tools, its rules and its users. Then check it and run it. You don't need to learn an agent framework for any of this.
$ pip install stalwart-agents # everything: the agents, the client, the gateway, the runtime
$ pip install "stalwart-agents[anthropic]" # with a model provider: anthropic, openai, google, mistral or ollama
$ pip install "stalwart-agents[all]" # with every provider
The local runtime ships for Linux (x86-64 and arm64), macOS on Apple silicon and Windows (x86-64). Anywhere else -- an Intel Mac, Alpine, Windows on ARM -- the same command installs the package without it, and the Stalwart service answers its plans and checks.
# agent.yaml
agents:
desk:
model: "anthropic:claude-sonnet-5-5" # your provider and key, from your environment
tools: [get_order, charge_card, refund_card, read_inbox]
hands_off_to: [billing]
billing:
privilege: high
tools: [issue_refund]
tools:
- python: shop.tools # plain functions, schemas from their type hints
- mcp: https://tools.internal/mcp # an MCP server's tools/list
receipts: true # behind a gateway that admits a call on the agent's own check
- openapi: ./crm.yaml # each HTTP operation a tool
- name: refund_card
writes: true
rulebook: ./policy.co # Colang 1.0 or 2.x
runs: atomic # a failed run is undone
storage: sqlite:///runs.db # where runs are kept; postgres://... for several workers
Or in Python, with the same meaning:
from stalwart_agents import Agent, tool
@tool(writes=True, undo="refund_card")
def charge_card(order_id: str, amount: Decimal) -> dict: ...
desk = Agent("desk", tools=[get_order, charge_card, refund_card], rulebook="policy.co",
model="anthropic:claude-sonnet-5-5")
reply = desk.chat("refund order 4411", user="u-17")
if reply.waiting: # a write waits for the person
reply = desk.confirm("u-17", "approve")
Before a turn runs, the agents' graph is proved once (verify=False runs it unproved).
A turn nothing reads is asked to be said again once; then on_unread decides: refuse,
model, or ask, where the person says whether the model may have it
(desk.confirm(user, "approve") or "decline").
A person's thumb on a reply is feedback the hosted miner learns your users' words from:
reply = desk.chat("what is in order 4411?", user="u-17")
desk.thumbs(reply, up=False) # one record: the turn's words, the tool, the router's verdict and rule
The record holds the rated turn's words and the router's reading of them -- the tool, its
verdict and deciding rule, the tools the agent could reach -- and nothing else: no reply
text, argument value, tool result or earlier turn. A turn the router could not read and
the model answered records the verdict unread and the tool the model called. The same
thumb twice is one record. Some thumbs are refused with ThumbRefused, saying what to
thumb instead: a turn of several instructions is thumbed one step at a time
(step=0, step=1, ...), and the reply after a confirmation is thumbed on the turn
that named the tool. stalwart serve takes the same thumb at
POST /threads/{id}/feedback, from the session that was shown the reply only.
An MCP server's tools are called in an MCP session per user: the user a turn names,
or its thread under stalwart serve. What a server keeps for one session never reaches
another user. desk.close() ends every session; stalwart serve ends them when it stops.
A tool's words are plain: writes, undo, irreversible, retry_safe,
reads_outside, sends_out, after, not_after, at_most, and the words the bug
hunter's OWASP rules read (argument_kinds, sandboxed, confidential, ...).
A model is provider:model, resolved with your own key from your environment. A
missing key is named before anything is sent. A model can also be a plain function
that takes the conversation and returns the reply.
| Command | Does |
|---|---|
stalwart verify agent.yaml |
registers the catalogue, verifies the graph the agents run and hunts the rulebook; exits 1 when the gate fails. --export-only FILE writes the export for CI; --replay replays each graph finding's witness on the agents, every tool a stub, and fails the gate on one that does not reproduce |
stalwart serve agent.yaml |
runs the agents over HTTP: turns, confirmations resumed on any worker, the step stream, an operator's rollback, a person's thumb on a reply (POST /threads/{id}/feedback), and the interface at / |
stalwart trace show|html|diff |
renders a run from its spans, or from the run store alone |
stalwart redteam agent.yaml --findings f.json |
attacker campaigns at what verify found, every tool a stub |
stalwart gateway --config gateway.yaml |
the MCP gateway: every tool call an agent makes, checked on its way to the tool (the gateway) |
stalwart doctor |
the key, the service and its latency, whether streaming gets through your network, and whether the local runtime or the service answers, with the licence, the lease and the quota left |
stalwart check certificate.json |
a certificate checked here, offline, by the carried reference checker |
stalwart licence activate|request|answer|install|release|status |
this machine's licence, offline activation included |
Nothing on stalwart_agents' own surface names LangChain or LangGraph: no name,
signature, error or message. A test holds the package to that. stalwart_agents.langchain
is there for a team already on LangGraph. desk.graph() is the one way to reach the graph that
runs underneath, for a team that wants to extend it.
The same install carries the rest, each documented on its own page:
| Page | What |
|---|---|
| The client | stalwart_agents.client: the Stalwart API from Python -- routing, tool checks, guardrail, agent graph and random forest verification, and the bug hunter |
| LangChain and LangGraph | stalwart_agents.langchain: the middlewares, the graph parts and Guard, for a team already on LangGraph |
| The gateway | stalwart gateway: the MCP gateway, its container and network policy, and the Kong recipe |
| The runtime | the compiled runtime the wheel carries, and its licence |
| Quickstart | the client in five minutes |
Metadata
Release files for stalwart-agents 1.0.45
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| stalwart_agents-1.0.45-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| stalwart_agents-1.0.45-py3-none-manylinux_2_28_x86_64.whl | Python 3 | none | Linux glibc 2.28+ x86-64 | Details |
| stalwart_agents-1.0.45-py3-none-manylinux_2_28_aarch64.whl | Python 3 | none | Linux glibc 2.28+ ARM64 | Details |
| stalwart_agents-1.0.45-py3-none-macosx_12_0_arm64.whl | Python 3 | none | macOS 12.0+ ARM64 | Details |
| stalwart_agents-1.0.45-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.1 MB
Release files / stalwart_agents-1.0.45-py3-none-win_amd64.whl
| Download URL | stalwart_agents-1.0.45-py3-none-win_amd64.whl |
|---|---|
| Size | 5.4 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
e032f54d9ef3261927e7e8a8d5b730ff08efddefbc05d83c8ac8cc230bdd5d79
|
|
BLAKE2b-256 checksum How to use checksums |
0f0d4dd5811b52c47894adee12763a00080ad74acb15f750bd44a0afa7d55dc7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logRelease files / stalwart_agents-1.0.45-py3-none-manylinux_2_28_x86_64.whl
| Download URL | stalwart_agents-1.0.45-py3-none-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.7 MB |
| Tags | Linux glibc 2.28+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
136c96123c30d6983fc87eff5e42f8de7c5270c6c36dffb5e6b7ac9d42523e73
|
|
BLAKE2b-256 checksum How to use checksums |
0cbd7302cfc65d0e782c475756acf4dd430ca3c3fdeaa6349935c0d7919a64ac
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logRelease files / stalwart_agents-1.0.45-py3-none-manylinux_2_28_aarch64.whl
| Download URL | stalwart_agents-1.0.45-py3-none-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 5.5 MB |
| Tags | Linux glibc 2.28+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
19207ae11a9347fa7abd257d0ddda08fbc97295d93cfa4f3c421afbf3c8ae22b
|
|
BLAKE2b-256 checksum How to use checksums |
36095d98b1e56f49d74299567d240fa8676f585aab27534f3c08ba9ef0e97f4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logRelease files / stalwart_agents-1.0.45-py3-none-macosx_12_0_arm64.whl
| Download URL | stalwart_agents-1.0.45-py3-none-macosx_12_0_arm64.whl |
|---|---|
| Size | 5.2 MB |
| Tags | Python 3 macOS 12.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
1a04a40f47289b7a3a87da89480399738743eb8a27c11133bd5b1ef510f3d11d
|
|
BLAKE2b-256 checksum How to use checksums |
64f931c8aa60828e23d484208f3119635243cf0e577f081f2e9420ea4c08c4ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logRelease files / stalwart_agents-1.0.45-py3-none-any.whl
| Download URL | stalwart_agents-1.0.45-py3-none-any.whl |
|---|---|
| Size | 297.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
80309032ffd4a5e29675fbafb1abc284050106465d77a1bb393ad561ce1cda57
|
|
BLAKE2b-256 checksum How to use checksums |
c09282957aff43d15156341aae8d90a5b05ad29f548fa225cec732db909e534f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency log