Skip to main content
These capabilities are host capabilities: their providers get live objects of piloop. Most are the home’s choice, in $PILOOP_HOME/config.toml, and take effect at piloop restart. The VCS and memory are a campaign’s, in piloop.toml.

Executors

An executor decides where each job runs: an agent session or an evaluation. The daemon submits the job, and the executor reports how it ended.

Example: run each job in a thread of the daemon

pyproject.toml
piloop_inline/__init__.py
Select it in $PILOOP_HOME/config.toml, then run piloop restart:

The contract

The entry point names a subclass of ExecutorConfig: its fields are the other keys of [plugins.executor]. The daemon calls its open(host) once, when it starts, to make the Executor. The live limits reach it through configure, and a network says who may call the routes of its contribution. A job’s end goes to host.results: finished or lost, in a session that the executor commits. Core raises Settled for a job whose row is closed already. An executor whose workers can report late uses leases to refuse those reports; inline needs none. run_agent and run_evaluation run one job on this machine.

Built in

workers, the default, runs every job on a lease, taken by its worker in piloop serve or by a worker on another machine. Its routes are the lease calls. Its keys are in the configuration reference.

Leases

A lease is a time-limited claim on one job by one worker. Any executor can use leases: Leases in piloop.capabilities. workers runs every job on one. Workers sets up pools and says what happens when a worker goes silent.

Networks

A network says how other machines reach the server of piloop serve --listen, and who each caller is. Only an executor with routes needs one.

Example: trust a tailnet

This network is https, and it lets every caller from one address range act without a token:

The contract

The entry point names a subclass of NetworkConfig: its fields are the other keys of [plugins.network]. Its client finds this machine’s credential itself, or raises NoCredential with what to set: piloop worker dials with it. The daemon calls its open(host) once, when it starts, to make the server’s Network. A request that identify refuses gets 401.

Built in

https, the default, knows no caller other than the tokens of piloop token, and its client sends the one in PILOOP_HTTPS_TOKEN. An address that is not loopback needs tls: a certificate, or "proxy" when a reverse proxy or an SSH tunnel ends TLS. Its keys are in the configuration reference.

Provisioners

A provisioner starts and stops workers on a platform, for a pool whose jobs wait. A pool’s [plugins.executor.pools.<name>.provisioner.compute] table selects it: there is no default. Workers that the server starts sets one up.

Example: workers in Docker containers

The worker’s credential goes to docker in its environment, never in its argv. Entry point group: piloop.provisioners. The provider’s open makes its live side, which lists, starts and stops instances. It tags each instance with the server’s id, and lists only those, so two servers on one account never stop each other’s. modal is built in. It needs the modal extra: uv tool install --reinstall 'piloop[modal]'.

CAS providers

The CAS is the content-addressed store that archived files and manifests live in. A provider decides where its blobs go: a directory, a bucket, or a cache over another provider.

Example: covalence’s SQLite store

This provider keeps the blobs in one SQLite file. Its store is covalence’s Cas.sqlite, as it is:
pyproject.toml
piloop_sqlite_cas/__init__.py
Install it, then select it in $PILOOP_HOME/config.toml and restart the daemon (piloop restart):

The contract

A provider is a pydantic model, a subclass of CasProvider: the name of its entry point is its provider, and its fields are the other keys of [plugins.cas]. A key whose value is another provider’s table, as the remote of cached, is a Annotated[CasProvider, CAS.entry] field. The store is a Cas: the methods of covalence’s Python Cas that piloop calls, with the same signatures, so a covalence.Cas is a store as it is. A blob’s address is a raw BLAKE3 CID of its content. A missing blob reads as None, and bytes that do not match their CID raise covalence’s IntegrityError. A store with a local tier over a remote one also implements Upkeep, which piloop store and the daemon’s hourly upkeep use. A store that can be such a local tier is Evictable. Its provider is a LocalProvider, and an Annotated[LocalProvider, CAS.entry] key, as cached’s local, takes only those. ObjectsCas (piloop.plugins.cas.kit.objects) is a store of compressed objects over anything that puts, opens and finds whole files by key: disk, s3 and gcs are three. check_cas(cas, scratch) runs the contract against a store, as piloop’s tests do with each built-in provider and with covalence’s Cas.memory(). It never deletes, so point it at a store that you can empty.

Built in

VCS

The VCS provider keeps a campaign’s versions: it saves, merges, checks out and moves them between machines through the CAS. [plugins.vcs] in piloop.toml selects it. git, built in, is the default and the only one. Most changes start from git and change one method. This one adds a line to the implementers’ brief on how to save their work:

Secrets

The secrets provider stores the values of piloop secret set. [plugins.secrets] in config.toml selects it. local, built in and the default, keeps them in the home’s database. piloop records who set a secret and when as events, so a provider stores only the values.

Archive

The archive moves the finished parts of campaign workspaces into the CAS, and writes them back on piloop restore. [plugins.archive] in config.toml selects it. local, built in and the default, records each archiving in its archives table. Its archiver is a consumer of the daemon’s loop. The archive and the CAS describes what it does. local, in piloop/plugins/archive/local/, is the model for another provider.

Memory

The memory provider keeps what past campaigns leave for the next ones. [plugins.memory] in piloop.toml selects it. local, built in and the default, has the lessons, documents and journal tables, the piloop journal command and its route: Tables, commands, routes and consumers shows how. Its contract has one method, sync. Memory describes it. This provider is local with other default documents:

Campaign types

A campaign type is what one kind of campaign stores, and campaigns.type names it. optimization, built in, is the research model: its schema has the ideas, runs, candidates and evaluations. Every campaign is of this type. Its contract has no methods.