Customizing Agents
Customize MD-first agents without reintroducing composition glue.
Start with agent.md. Use profile exceptions for data, Skills for procedures,
and a conforming plugin only when the capability requires executable code.
There are no root agent.ts, gateway.ts, tools/, connections/, or
hooks/ customization paths.
Context
The default context includes permanent instructions, the active event, bounded history, memory, files, attachments, compact skill and capability catalogs, visible tool summaries, channels, and trust boundaries.
Select or configure a static context profile in agent.md:
context:
default:
recentHistory:
maxMessages: 12If a context policy needs trusted code, declare it in a plugin's contexts
section and select the qualified contribution:
context: company-context.privateThe compiled policy and source hash appear in resolved inspection. Subagents use the context policy compiled for their own surface.
Runtime filesystem
Every run sees the stable logical filesystem:
/memory durable memory
/history read-only conversation history
/files read-only inputs and attachments
/workspace writable artifacts and modified copies
/skills loaded skill procedures and resourcesSandboxes are acquired lazily. Normal model turns, skill activation, memory access, and final delivery do not require a sandbox unless an active capability does.
Infrastructure profiles
Common infrastructure is one line per role:
deploy: railway
state: postgres
blob: r2
sandbox: e2bUse single-key mapping form only for a real exception:
sandbox:
e2b:
internet: enabledThe scalar E2B profile blocks outbound internet by default.
Scheduling is kernel orchestration over the selected state adapter; it is not an authorable provider field. The resolved view exposes the chosen runtime, state, blob, sandbox, provider metadata, required environment, and deployment plan.
Models and conditional composition
Static model and reasoning choices stay in frontmatter:
model: openrouter/openai/gpt-5.4-mini
reasoning: medium
maxReasoning: highUse the constrained composition DSL for ordinary conditions:
composition:
- when:
principal.roles:
includes: finance
model: openrouter/openai/gpt-5.4
capabilities:
enable: [billing_issue_refund]
- otherwise: true
model: openrouter/openai/gpt-5.4-mini
capabilities:
disable: [billing_issue_refund]The condition language supports reviewed run identity, channel, audience, attachment, and bounded persistent-state checks. It never evaluates JavaScript. For genuinely arbitrary synchronous selection, use a named plugin composition contribution. The contribution must declare static ceilings for every model, reasoning level, capability, sandbox, subagent, connection, and state key it may select.
The runtime still persists the complete snapshot before model execution and re-evaluates after control-state changes.
Tools and connections
Framework-safe tools load automatically. There is no tools: frontmatter
field. A plugin contributes native tools or MCP servers; the resolved manifest
shows schemas, visibility, execution boundary, side effects, approvals, source,
version, and integrity.
External connections are also plugin capabilities. Their implementations may use MCP, A2A, OpenAPI, direct HTTP, SDKs, CLIs, or credential-only materialization. The runtime keeps authorization, grants, account subjects, events, approvals, and credentials separate even though authoring uses one plugin concept.
Use plugin-owned config for schema-validated behavioral options and exceptions to narrow reviewed contribution policy:
capabilities:
private-search:
config:
catalog: design
connections:
search_api:
disable: [catalog_request]
approval:
rebuild_index: alwaysCredentials and account bindings stay outside Git. Connection-specific
exceptions belong under connections.<contribution>; plugin config never
contains credential values or untyped runtime bindings.
Automations and schedules
Keep short automations where they are inspectable:
automations:
weekly-review:
schedule: sunday at 18:00
timezone: America/Chicago
skill: weekly-performance-review
delivery: openuiSchedules use a deterministic grammar, never a model. Event automations name a
plugin event and optional filter. Complex trusted prepare or finalize code
belongs to a plugin lifecycle contribution referenced by qualified name.
Large collections may use automations.include, but resolved inspection always
shows one combined set.
Hooks
An after-persist hook belongs in the plugin for the capability it observes. Generic retries, durability, approvals, state transitions, and delivery stay in the framework. If a hook cannot answer “which removable capability owns me?”, it is probably agent logic that belongs in an automation, Skill, or framework feature instead.
Mutability
The deployed build and plugin code are immutable. agent.md declares the
maximum durable overlay the agent may change:
mutability:
automations: approvalOmitted mapping keys keep the baseline: Skills stay autonomous and external connections stay disabled. Enable external connections only with an explicit mode and host allowlist.
autonomouspermits changes within the compiled ceiling without repeated approval.approvalparks the operation until approved.disabledremoves the API.
Use mutability: static to disable all three. Runtime mutation never rewrites
agent.md or trusted plugin source.
The runtime mirrors accepted skill and memory changes into a private Git audit
repository under <artifactRoot>/evolution. The durable stores remain
authoritative; this history exists to answer what the agent changed and when.
It is managed entirely by the runtime, is not mounted into the model's logical
filesystem, and does not add Git or approval-management tools to the agent.
Approval-gated skill edits are committed only when accepted. See Evolution
History.
Subagents
The parent lists child names and each child owns a nested agent.md:
subagents: [researcher, coder]Child plugins, Skills, capabilities, memory, state, workspace, and learned skills are isolated by recursive surface path. Shared capabilities are selected independently on every surface that needs them.
Custom providers
Models, channels, and infrastructure remain explicit typed locations rather
than entries under capabilities:. Their implementations are Agent Plugins. A
reusable infrastructure package declares a locked providers or channels
contribution and exports assemblyLineProvider; a model package declares
models and exports assemblyLineModelProvider. A custom channel is selected
by its unique contribution name, while a model is selected by its provider
prefix. See Authoring Plugins
and Adapters.
Verify every customization
Use:
assembly-line validate ./agent
assembly-line inspect ./agent
assembly-line inspect ./agent --resolved
assembly-line explain plugins.treg ./agentThe source view exposes convention-discovered Skills and local plugins. The resolved view expands profiles, framework defaults, package locks, authority, routes, automations, preflight, and the synthetic initial capability snapshot.
Use the Declarative Reference for every accepted customization, type, and default.