pyrtan
Open-source total automation: a core set of expandable services that act on all forms of I/O through inspectable decision trees. It answers like an assistant. Inside, there is no model.
$ pyrtan run "what's the weather in Oslo" --trees examples
trace: weather
geocode (observe): GET https://geocoding-api.open-meteo.com/v1/search?name=Oslo… -> 200 -> found
found (decide) [exists True]: state.hit = {…} -> forecast
forecast (observe): GET https://api.open-meteo.com/v1/forecast?latitude=59.91… -> 200 -> have-temp
sky (decide) [between [51, 67]]: state.code = 61 -> rain
reply (done): Oslo, Norway: 4.2°C, raining, humidity 80%, wind 12.3 km/h.
The trade
A model generalises to sentences nobody wrote a tree for; Pyrtan does not, and says so. In return every run is deterministic, costs nothing, works offline against recorded responses, cannot reach a host its author did not list, and can always explain itself: the trace names each observation and the condition that chose each branch.
Trees
One TOML file: the sentences it answers to, the hosts it may touch, what it observes, how it decides. No code, no loops, no model.
Swarm
Services hold trees; a hub routes between them and shows each peer's link. One process or many, the callers never change.
Gaps
A decision that meets a value no branch covers is recorded, not guessed at. The list of gaps is the list of what to write next.
Catalog
Trees others wrote, as static files anyone can mirror. pyrtan pull NAME verifies the file against the index before writing it.
Install
uv tool install git+https://github.com/b-i-t-8/pyrtan # or: pip install git+https://github.com/b-i-t-8/pyrtan pyrtan search weather pyrtan pull weather --dir trees pyrtan serve trees --port 8701 # then open http://127.0.0.1:8701/
Python 3.12 or later, no runtime dependencies. Runs on a laptop, a NAS or a container; deployment notes.
The console
Every hub and service serves the console at /. The same console is at pyrtan.com/console: point it at your own hub, started with --token and --cors https://pyrtan.com, and ask it from anywhere. Nothing about your swarm passes through this site; the page talks to your hub directly.
The directory
Hubs find each other without a server. A hub started --listed announces itself to the hubs it follows and that follow it; every hub keeps what it hears and passes it on. This is the default network, the one pyrtan join puts a hub in; any hub can also start a network of its own and share its invite, and a private network's hubs never show here. pyrtan.com runs no hub of its own: it is static pages. This page asks the hubs on its hub list from your browser and shows what they know; when none answers, it shows the snapshot pyrtan.com takes every hour from every hub it can reach. An entry is a hint, not a route: to use a hub, follow it from your own.
| Heard | Hub | Holds | |
|---|---|---|---|
| Asking the hubs… | |||
pyrtan hub --federate --advertise https://your-hub --listed --token … # your hub, behind a tunnel or TLS pyrtan join --at https://your-hub --token … # be in the default network pyrtan network new home --at https://your-hub --token … # or start your own: prints its invite pyrtan directory # who the swarm knows
To be on the hub list, add your hub's URL to site/rendezvous/hubs.json by pull request. It need not be up all the time: the hourly snapshot keeps the directory from every hub it can reach.
Hosting
Self-hosting is the product. A hosted option, running the same open-source hub per customer with secrets, retention, scheduled re-runs and alerts around it, is planned; it will speak the same API, so a swarm can move either way without changing a caller.