agent.ts
agent.ts default-exports defineAgent({ ... }) and is one of the two required
files. Use it whenever you set the model, a stable id, default tools, or a
runtime capability policy.
Minimal Example
The only required field is model:
import { defineAgent } from "@assemblyline-agents/core";
export default defineAgent({
model: "openai/gpt-5.4-mini"
});
Full Options
| Field | Type / values | Default | Effect |
|---|---|---|---|
model | string (required) | — | Model spec, usually <provider>/<model>. |
id | string | — | Stable logical identity for durable learned state across revisions. |
reasoning | off | minimal | low | medium | high | xhigh | medium | Provider-agnostic reasoning effort. |
name | string | — | Display name. |
description | string | — | Human and manifest metadata. |
outputSchema | JSON Schema | — | Runtime-enforced schema for the final response. |
maxIterations | positive number | 25 (ASSEMBLY_LINE_MAX_MODEL_ITERATIONS) | Agent-loop iteration budget, including structured-output correction retries. |
context | ContextPolicy | defaultContext() | Context bundle policy; see context.ts. |
defaultTools | string[] | [] | Authored tools visible up front instead of behind deferred discovery. |
selfImprovement | { writable?, writeApproval?, externalDirs? } | writable: true, writeApproval: false | Skill self-authoring controls. |
dynamicAutomations | { dynamic?, approval? } | dynamic: true, approval: false | Runtime time-based automation creation controls. |
dynamicConnections | { dynamic?, approval?, allowedHosts? } | dynamic: false, approval: true | Runtime connection adoption; allowedHosts is required non-empty when dynamic is enabled. |
metadata | JSON object | — | Structured app-specific metadata. |
A kitchen-sink example with every policy declared:
import { defineAgent } from "@assemblyline-agents/core";
export default defineAgent({
id: "travel-concierge",
model: "openai/gpt-5.4-mini",
reasoning: "medium",
name: "Travel Concierge",
description: "Plans and maintains travel research.",
defaultTools: ["search_places"],
maxIterations: 12,
outputSchema: {
type: "object",
properties: { answer: { type: "string" } },
required: ["answer"]
},
selfImprovement: { writable: true, writeApproval: false },
dynamicAutomations: { dynamic: true, approval: false },
dynamicConnections: {
dynamic: true,
approval: true,
allowedHosts: ["api.example.com"]
}
});
Structured Outputs And Loop Bounds
Declare portable structured output with outputSchema; Assembly Line enforces it in
the runtime, so it works with every harness rather than depending on one model
provider's JSON mode:
export default defineAgent({
model: "openai/gpt-5.4-mini",
maxIterations: 12,
outputSchema: {
type: "object",
properties: {
answer: { type: "string" },
confidence: { type: "number", minimum: 0, maximum: 1 }
},
required: ["answer", "confidence"],
additionalProperties: false
}
});
The model receives the schema as part of its trusted system prompt. The runtime
accepts plain or whole-response fenced JSON, normalizes it to a JSON string,
validates it, and retries through the existing continuation when needed.
Exhausted validation retries and iteration caps mark the run failed; they
never silently deliver a partial answer. RunAgentResult.response is the
normalized JSON text, while RunAgentResult.output is the parsed value.
Subagents may declare their own outputSchema and maxIterations. The env
defaults are ASSEMBLY_LINE_MAX_MODEL_ITERATIONS=25 and
ASSEMBLY_LINE_OUTPUT_VALIDATION_MAX_RETRIES=2.
Stable IDs
Set id for production agents that learn skills or keep durable state across
deploy revisions. Without a stable id, learned state follows the compiled
agent revision more tightly and is less suitable for long-lived products.
export default defineAgent({
id: "support-agent",
model: "openai/gpt-5.4-mini",
selfImprovement: { writable: true }
});
Primary Engine
Pi is the default primary engine. Top-level agents do not choose a harness:
agent.ts has no harness slot, and declaring one fails validation with
harness-not-configurable. The Node host also recognizes the preview
openai-codex/* model prefix and routes it through the official Codex
app-server using the CLI session from codex login. That is a built-in model
provider route, not a configurable harness: slot.
Subagents use Pi as well. LiveKit and similar service-specific surfaces are modeled as connections and typed tools, not delegate engines.
Conventions
- Do not put secrets, databases, blob stores, channel parsing, or deployment
choices here. The
provider/modelprefix is the only provider routing authored in this file. - Put deployment and shared adapter choices in
gateway.ts. - Keep
defaultToolsshort; leave the rest of the tool surface behind deferred discovery.
Assembly Line uses conversation for long-lived history, run for one durable
execution, and iteration for one model/harness invocation plus its resulting
tool calls. Because other agent frameworks assign conflicting meanings to
turn, Assembly Line avoids the unqualified term in public contracts.