Adapters
Choose explicit channel and infrastructure providers for an MD-first agent.
Adapters are typed runtime contracts supplied by plugins. They answer which
model provider runs the loop, where the agent runs and stores durable data,
where isolated work executes, and how messages arrive. Their plugin selection
remains explicit at the field that consumes the role, separate from additive
capability selection under capabilities:.
Current provider matrix
| Role | Supported | Preview |
|---|---|---|
| Model | OpenRouter, OpenAI, Pi-native OpenAI Codex subscription | None |
| Channels | Slack, Discord, Telegram, Microsoft Teams, Photon/Spectrum | None |
| Sandbox | local, Docker, Daytona, E2B | Modal |
| Blob | local, R2, generic S3-compatible | None |
| State | local files, Postgres; Neon, Railway, and Supabase profiles | None |
| Scheduling | Kernel polling or authenticated external tick; state-backed coordination | None |
| Channel audio | OpenRouter transcription (default), OpenAI transcription | None |
| Gateway/deploy | local, Railway, Hetzner | Docker, Fly |
| Runtime | Node | None |
| Secrets | process environment, 1Password | None |
“Supported” means the provider has a real runtime construction path, compiler metadata, documentation, and regression coverage. “Preview” means the public contract and local coverage exist but additional live-provider hardening is still required.
Selecting plugins
The ordinary form is intentionally short:
deploy: railway
state: neon
blob: r2
sandbox: e2b
channels: [photon]Each singular scalar selects a deterministic, versioned plugin. Use a single-key mapping only for a real exception:
sandbox:
e2b:
internet: enabled
channels:
photon:
audio: openai
slack: {}internet and channel audio are closed common exceptions. Every provider
mapping is also closed to its documented typed options. Package,
required-environment, capability, route, and provider metadata values are
owned by the selected provider, not copied into the agent. See
Declarative Reference.
The resolved manifest contains the expanded GatewayDefinition, package,
required environment, provider capabilities, routes, and preflight. Changing a
plugin's effective defaults changes build identity.
The default E2B profile blocks outbound internet. Set internet: enabled only
for an agent that requires egress.
model uses the same ownership rule through its provider prefix:
model: openrouter/openai/gpt-5.4-miniThe locked OpenRouter plugin supplies Pi registration, model discovery,
authentication, request semantics, embeddings, accounting, and deployment
requirements. OpenAI and openai-codex are swappable packages with the same
contract; Pi itself contains no provider catalog.
Install or select a provider with:
assembly-line add docker ./agent --role sandbox
assembly-line add slack ./agent --role channelThe CLI updates structured frontmatter without dropping existing exceptions.
Deploy and runtime
deploy chooses the deployment target. The selected plugin owns ingress,
release publication, rollback, and host-specific defaults. The MD-first runtime
is always Node.
deploy: hetznerVPS addresses, SSH identity, host fingerprints, and ingress namespace stay in
deployment inventory. The plugin's typed YAML mapping may select an inventory
name and declare agent-level resource, database, ingress, and monitoring
policy. assembly-line inspect --resolved and deploy dry-run expose them before activation.
Select the named host with the typed deploy.hetzner.host option or
ASSEMBLY_LINE_HETZNER_HOST.
The address and SSH details remain in assembly-line.hosts.json.
Durable state
All production state profiles resolve to the existing Postgres state contract; the profile name describes placement and defaults:
state: postgresProvider-specific Postgres profiles are neon, railway, and supabase.
The adapter persists runs, events, checkpoints, capability snapshots, approvals, conversations, schedules, automation reservations, memory, dynamic capabilities, workspaces, usage, and delivery obligations. Surface scopes keep subagent memory, state, and learned skills isolated even though the physical database adapter is shared by the deployed service.
Local files remain appropriate for development and tests, not multi-replica production.
Blob storage
Blob adapters hold attachments, extracted text, immutable generated artifacts, large checkpoints, and content-addressed workspace objects:
blob: r2R2 uses the generic S3-compatible implementation underneath. Credentials and bucket configuration come from the provider environment and preflight, not the agent source.
Sandboxes
Sandbox profiles provide an isolated filesystem and command boundary:
sandbox: e2bAssembly Line supports direct and sandboxed plugin tools. A tool declared with
execution: sandbox runs its complete implementation and model-output
projection inside the selected sandbox. The runtime brokers only scoped state,
memory, connection, approval, delivery, and filesystem APIs.
Custom immutable environments live in sandbox/<name>.yaml with optional
contained build context. They remain source and are content-hashed. The
portable /workspace contract and environment allowlist stay consistent
across local, Docker, Daytona, E2B, and Modal implementations.
Scheduling
Scheduling is kernel orchestration, not an adapter plugin or an agent.md
selector. The runtime consumes normalized cron registrations and coordinates
claims through the selected state adapter's scheduling-store capabilities.
The Node host starts its in-process polling loop unless it is disabled with
ASSEMBLY_LINE_SCHEDULER_ENABLED; an authenticated external scheduler may call
the tick endpoint instead. The runtime never parses the plain-language DSL.
Channels
Channels remain explicit because they expose routes and delivery authority:
channels:
slack: {}
photon:
default: trueProvider modules own ingress authentication, signature verification, normalization, attachments, streaming, typing indicators, and outbound delivery. A provider event becomes a run only when an authored automation subscribes to it.
Custom channel behavior may be supplied by a local plugin, but the channel selection remains visible:
channels:
photon:
hooks:
before-first-send: coachgpt.first-contact-cardChannel audio and secrets
Attachment-capable channels select their pre-model audio processor. Photon, Slack, Telegram, and Teams default to OpenRouter transcription, so the common case stays concise:
channels: [photon]
secrets: 1passwordThe 1Password package must be installed and pinned; assembly-line add 1password agent --role secrets performs both steps and selects the field.
Set channels.<name>.audio to openai, openrouter, or disabled only when
that channel differs from its default. Audio processing stores private
transcript evidence and exposes bounded model context according to policy. A
secrets adapter resolves only a credential declared by the active authorized
connection (or a trusted gateway/bootstrap consumer). Secrets never enter
agent.md, plugins.lock, authored-tool context, or model context.
Connections are not adapters in authoring
The runtime still has a connection subsystem because it owns accounts, credentials, grants, protocols, events, and approval. In MD-first authoring, external connections arrive through capability plugins:
capabilities:
- mirror
- githubThis avoids a second composition system without pretending that connections and tools are the same internally.
Custom providers
A third-party infrastructure or channel package is a complete Agent Plugins v1
package. Its static providers or channels contribution owns selection and
authority; its runtime module exports assemblyLineProvider. Its metadata declares role, kind, package, stability,
required environment, capabilities, setup, and genuine host constraints. Its
factory receives resolved options and environment and returns the matching
adapter contract.
The compiler copies plugin-owned provider metadata into the manifest and
preflight; the runtime and deploy command resolve the same registration. Typed
provider plugins do not belong in capabilities: unless that same plugin also
ships an additive tool, connection, hook, lifecycle, or composition surface.
They are still plugins: their typed field activates them.
The field grammar is closed, while the provider set is plugin-extensible.
Making a provider selectable requires a locked providers contribution with
its name, role, runtime kind, package binding, defaults, and JSON Schema. It
does not require a compiler registry edit, and agents cannot supply a package
or metadata envelope themselves.
See Authoring Plugins for the typed contract.
Provider documentation
- Slack Events API
- Discord interactions
- Telegram Bot API
- Microsoft Bot Connector authentication
- Docker containers
- Daytona sandboxes
- E2B sandboxes
- Modal sandboxes
- R2 S3 compatibility
- Neon Postgres
- Supabase Postgres
- Railway CLI
- Fly deploy