The client's quickstart
The client, stalwart_agents.client, in five minutes. To build an agent instead, start with
Build an agent.
Install the package, set your key, and activate the licensed runtime once:
pip install stalwart-agents
export QLS_API_KEY=qls_live_...
stalwart licence activate
The runtime reads each turn and checks each tool call on this machine. Where it cannot run,
set QLS_ROUTER_URL to the enterprise qls-router you run in your own environment.
Route a conversation
from stalwart_agents.client import Client
client = Client()
version = client.register_catalogue(mcp_tools_list, agent="desk")
chat = client.session("desk", catalogue=version)
plan = chat.read("show me the stock in depot HB-7")
for step in plan.steps:
if step.kind == "tool":
print("call", step.selection.tool, dict(step.selection.arguments))
elif step.kind == "ask":
print("ask", step.selection.question)
Each step names the rule that made it in step.decided_by. A plan whose outcome is
declined runs nothing.
Stream a long solve
for event in client.verify_guardrail("policy.co", "execute_transfer_funds", "is_authenticated",
profile="enumerate", stream=True):
print(event.type, event.data)
The iterator ends at the job's terminal event. A dropped connection is resumed where it
stopped; if streaming keeps failing through your network, the iterator yields one
stream_degraded event and carries on by polling.
Test your routing offline
from stalwart_agents.client.testing import replay
with Client(api_key="unused", router_url="https://qls-router.internal", transport=replay(cassette_path)) as offline:
plan = offline.session("desk", catalogue=catalogue, session_id="s1").read("show me the stock")
Record the cassette once against your router, with stalwart_agents.client.testing.record(path)
as the transport; a replay sends nothing, so any router URL does. A
turn that was not recorded raises CassetteMiss; a catalogue that has moved since raises
CassetteStale.