Skip to content

38 · Licences, running offline, and what needs the network

The stalwart-agents package carries Stalwart's runtime, compiled: the reader that turns each turn into a plan, the tool check, the reply checks, retrieval, the code checks, the licence and the meters. It runs in your process, on your machine. A licence is what lets it run there: this machine, activated once against your account. This chapter is what runs on the machine and what needs our service, how a licence is activated, kept and released, and what happens when it lapses.

Language support

The selector understands turns written in English. Portuguese is its next grammar, and has not shipped yet; until it does, a turn written in Portuguese is not read as Portuguese.

What runs where

Where the runtime is installed, a turn and a tool call need no network: the runtime answers both on the machine that runs your agent.

What happens once, before deployment or in the background may use our service. Each row is tied to the code that does the work, the runtime's operation or the service's route, and generated from it:

Work Where it runs Network
reading a turn into a plan the runtime, in your process none
checking a tool call: the catalogue, the arguments, the history, the order rules, the rulebook's gate, the marks, the confirmation tokens the runtime, in your process none
holding a reply to what was done, and screening turns and replies for personal data the runtime, in your process none
indexing your documents, retrieving passages and checking an answer against them the runtime, in your process none; compose calls your own model, with your key
the code checks of stalwart verify the runtime, in your process none; only the counts by rule go with the registration
linting a catalogue the runtime, in your process none
the guarded tool step, undoing a failed run, the rewind, pauses for a person and their resume the package, over the runtime, in your process none, except the calls your own tools make
the gateway's checks the package, over the runtime, in your process none, except the calls it passes on to your tool servers
a calculation: your model writes the function and the sandbox image runs it, on your machine the package, over the runtime, in your process your model's call; the function itself runs with no network
registering a catalogue and its rulebook our service at stalwart verify and at an agent's start-up, when the newest version does not hold it
the hunt and the proof of an agent's graph our service before deployment: at stalwart verify, and once per graph before an agent's first turn
activating the licence and refreshing the lease our service once at activation, then in the background; the runtime runs on through the grace period without it
reporting usage: counts only our service in the background, with the lease refresh
the vocabulary and the catalogue bundles the runtime reads our service in the background; a new bundle is taken at a lease refresh, never mid-conversation
your users' thumbs, for the miner our service only where you post them

Activating

$ export QLS_API_KEY=qls_live_...
$ stalwart licence activate        # once on each machine
$ stalwart licence status          # the licence, the lease, the grace and what is left of each cap
$ stalwart licence release         # frees this machine's place, for another to take

Activation makes this machine's installation -- a random id and a key pair, never a hardware fingerprint -- and exchanges your key for your organisation's licence and a first lease: the runtime's permission to run here until a date. Your plan sets how many machines may hold a lease at once, how long a lease runs, the grace period after it, and whether a machine can be activated with no connection at all:

The local runtime's licence Free Paid Enterprise
installations: machines holding a lease at once 1 5 50
lease_days: days a lease runs before it is renewed 7 7 7
offline_grace_days: days the runtime keeps working past its lease without reaching us 7 30 30
offline_activation: activating a machine that never reaches the network, by request file no no yes

Nothing in the package works without a key and an activated licence, except activating it, stalwart doctor and stalwart check. Without them a command stops with LicenceRequired, naming stalwart licence activate.

The lease, its refresh and the grace period

The first answer the runtime gives in a process refreshes the lease with our service, so a cancelled plan or a revoked licence stops the runtime at once; the same refresh fetches the catalogue and vocabulary bundles and reports the counts. Where the service cannot be reached, the runtime opens the last lease as it stands: within its term, and then within the grace period, it answers as usual, and stalwart doctor and stalwart licence status show the state, active or grace, and the dates the lease and the grace end.

Running offline

The shop agent of chapter 30. It starts with the network, which proves its graph and registers its catalogue:

desk = Agent.from_file("agent.yaml")
desk.chat("show me order 4412", user="u-0")     # start-up, with the network: the proof and the registration

Then the network is cut, every socket refused, and the agent goes on:

# The network is cut here: from now on nothing leaves the machine.
reply = desk.chat("show me order 4411", user="u-17")
print(reply.text)
reply = desk.chat("charge order 4411 40.00", user="u-17")
print(reply.waiting[0].tool, "waits:", reply.waiting[0].wording)
reply = desk.confirm("u-17", "approve")
print(reply.text)
{"card": "visa-0019", "customer": "c-208", "order_id": "4411", "status": "unpaid", "total": "40.00"}
charge_card waits: Run charge_card?
{"amount": "40", "charge_id": "ch-4411", "order_id": "4411"}

The read was answered, the charge checked and asked about, and the approved charge run, with nothing leaving the machine but the call to the shop's own tool.

When the licence lapses

A lease and its grace both past, or the licence expired, is a lapsed licence. A safety product must not fail open, and a production agent must not stop without warning, so a lapse degrades by your organisation's on_licence_lapse setting:

  • reads_only, the default: turns are read as usual, reads are checked as usual, and every write is refused as licence_lapsed.
  • refuse: every operation is refused as licence_lapsed, with the date the lapse began.

The same agent, after its licence lapsed:

# The licence has lapsed, and the organisation's setting is `reads_only`.
reply = desk.chat("show me order 4411", user="u-18")
print(reply.text)
reply = desk.chat("charge order 4411 40.00", user="u-18")
print(reply.text)
{"card": "visa-0019", "customer": "c-208", "order_id": "4411", "status": "unpaid", "total": "40.00"}
The licence for this agent has lapsed, so charge_card was not run.

Nothing is ever allowed under a lapse that a licensed runtime would have refused.

Machines with no connection

Where your plan allows offline activation, a machine that never reaches Stalwart is activated by file, through one that does:

$ stalwart licence request                          # on the machine to activate: writes activation-request.json
$ stalwart licence answer activation-request.json   # on a machine that reaches Stalwart: writes activation-answer.json
$ stalwart licence install activation-answer.json   # back on the first machine

The answer holds the licence and a lease for the licence's whole term. An enterprise can instead run qls-licence-server in its own network, which issues leases to its machines as the licence service does.

Releasing a seat

stalwart licence release frees this machine's place on the licence, so another machine can take it: what a CI job does last (chapter 46).

What is counted, and what is reported

The runtime counts each meter your plan names -- plan_calls, tool_checks, answer_calls and the reply checks' counts among them -- in its own state, on its own clock. Past a cap, it answers quota_exhausted, naming the meter, as the service does. Counts, and only counts, are reported: never a turn, an argument, a result, a reply or a document. Your plan's caps are in chapter 16.

stalwart doctor and stalwart licence

  • stalwart doctor prints the base URL, whether a key is set (never the key), which side answers plans and tool checks -- the local runtime or your qls-router -- with the licence's state, the round trip to the service, your tier, its entitlements and this month's use of each meter, and whether streaming reaches you through your network. It works with no licence, to say what is missing.
  • stalwart licence takes activate, request, answer, install, release and status.

The limits

  • Compiled code and encrypted bundles deter reading; they do not prevent it. A determined party with a licensed installation can extract what it runs. The licence terms and your contract are what stop that.
  • Some work still needs our service: the hunt and the proof of an agent's graph, registering a catalogue and its rulebook, activating and refreshing a licence, and the miner. An agent's first start proves its graph and registers its catalogue there; a machine that never reaches the service runs on its lease and grace alone.
  • Where the runtime is not installed -- a platform the wheel does not ship for -- plans and tool checks come from your own qls-router, and our hosted API answers neither.