Skip to main content

Overview

Plugins are where your business logic lives. The engine is generic — it doesn’t know what a customer is or what a subscription tier means. You teach it through plugins. There are three plugin types: All live under a single plugins/ package, described by one manifest file.

File layout

Run generate --config agents.yml (see Quickstart) to create all stubs from your YAML.

Resolver plugins

Resolvers fill prompt variables. They run before the agent, they’re chosen by the engine (not the LLM), and they cost no tokens.

Declaration

Implementation

The generate command produces the file layout. Fill in the methods:
Resolver inherits current_date and customer_name from SharedResolver. Only account_tier (agent-scoped) needs an implementation here.

Generation modes

See CLI Reference for how to run these via Docker or a local install. Without --force, existing method bodies are preserved — only missing stubs are added.

Manifest

The plugins.toml manifest maps plugin ids to class paths. Generated automatically:

Access plugin

Marks certain nodes as protected and gates them behind your own access logic. Protected nodes are hidden from the router entirely if access is denied — the model never knows they exist.

Declaration

Implementation

When any node has protected: true, the engine requires plugins/access.py:
ctx carries request headers and metadata — use whatever your auth system provides. The engine calls this before routing and removes any node where can_access returns False.
protected: true without plugins/access.py is a startup error. The engine won’t serve requests until it’s provided.

Making plugins importable

If commands run from different working directories, declare import_roots so Python can always find your package:
This is the recommended approach. Alternatively, install your package with pip install -e ..