Skip to content

<Agent />

<Agent /> is AML’s model-session boundary. AML resolves the complete authored plan first, then asks the selected Agent provider to run one session.

import { Agent, AmlRuntime, System } from "@aml-jsx/sdk"
import { DeterministicAgentProvider } from "@aml-jsx/sdk/testing"
const provider = new DeterministicAgentProvider({
respond: request => ({ text: `${request.system}\n${request.prompt}` }),
})
const runtime = new AmlRuntime({ agentProvider: provider })
const result = await runtime.evaluate(
<Agent name="authorization-review" model="reviewer" timeoutMs={30_000}>
<System>Use only evidence supplied in the prompt.</System>
Review the authorization change.
</Agent>
)

For a live session, replace the deterministic provider with Codex, GitHub Copilot, OpenCode, or Pi.

PropTypeDefaultMeaning
childrenAmlRenderableemptyInitial prompt text plus Agent-scoped descriptors.
cwdstringactive Sandbox cwdAgent-local logical cwd. Requires an enclosing <Sandbox />; it does not create one.
modelstringprovider defaultProvider-owned model identifier passed through by AML.
namestringOptional diagnostic metadata; non-unique and never included in prompts.
permissionspartial permissionsread-write filesystem, network and shell enabledRequested native harness controls; an active Sandbox may narrow them.
providerAgentProviderruntime agentProviderProvider for this session.
schemaAmlModelSchemaValidates this Agent’s result and renders it as canonical JSON text in ordinary composition.
systemstringemptyFixed system text, placed after runtime system text and before child <System /> blocks.
timeoutMsnumberPositive safe integer that bounds this provider session; caller cancellation and cleanup semantics are described below.

name is optional diagnostic metadata for relating traces and failures to the authored workflow. It must be a non-empty normalized string when supplied. Names are not unique: structural identities such as trace span IDs continue to distinguish Agents with the same name. AML includes the name in observability and diagnostics only; it never adds it to the prompt or system instructions sent to the provider.

timeoutMs, when present, is a positive safe integer that bounds the provider session after it acquires an Agent scheduler slot. AML derives a session signal that aborts when either this timeout expires or the enclosing evaluation is cancelled; the earliest cause wins, and nested Agents retain independent scopes. Expiry follows the same provider cancellation path as caller cancellation. AML awaits provider-owned abort and cleanup before settling the Agent, and preserves both the cancellation cause and any later cleanup failure.

AML resolves child <Agent /> components, text, <Block />, <Include />, <System />, <Skill />, <Tool />, <Mcp />, and <FollowUp /> descriptors before the provider session begins. Prompt and system fragments are trimmed at the session boundary; ordinary child text is otherwise concatenated without inserted separators. Skills are staged before the session, remain available for all turns, and never insert their instruction body into the prompt automatically.

The provider returns an AgentResponse. Normal evaluation contributes its text to the surrounding AML value. With schema, AML instead validates the structured response and renders the transformed value as canonical JSON text with deterministically ordered object keys. Transformations that produce non-JSON values, including undefined, reject because ordinary AML composition is a text channel.

Component-local evaluate() remains the typed collector: pass its schema as the second argument when TypeScript needs the inferred value. Do not also set the Agent schema prop; one Agent has one schema owner.

Return a child <Agent /> when its result should naturally occupy one authored position in the surrounding AML tree. AML resolves that child first and passes its result upward; the component that returned it does not receive the text in a local variable.

Use await evaluate(<Agent />) inside an active async component when later TypeScript must inspect or transform the result before deciding what AML to return:

async function Review() {
const finding = await evaluate(<Agent>Inspect the change.</Agent>)
if (!finding.includes("concrete evidence")) return "No supported finding."
return (
<Agent>
Synthesize the accepted finding.
<Block tag="accepted-finding">{finding}</Block>
</Agent>
)
}

The component body runs when AML descends into Review, not when <Review /> is initially authored. The awaited Agent and its cleanup finish before the body continues to the if statement and final return. See Component bodies descend; results ascend for the complete mental model.

  • <Agent /> may be the root value, a child of another <Agent />, or a descendant of <Sandbox /> or <Workspace />.
  • <Agent /> capabilities belong only to their nearest containing <Agent />. Siblings do not inherit them.
  • Child <Agent /> results become parent input at their authored position; they are separate provider sessions.
  • cwd does not create a Sandbox. It only narrows the cwd of an already active Sandbox session.

An Agent trace contains one agent.session span, one ordered agent.turn span for the initial prompt and each <FollowUp />, and one agent.cleanup span. Built-in ACP providers stream acp.session.update events inside the active turn and attach the final ACP stop reason and optional usage to the successful turn end.

One Agent turn is one provider runTurn() call. It normally maps to one ACP session/prompt request, but a schema-bearing final turn may contain one additional repair prompt when the Agent omits the result Tool. It must not be interpreted as one underlying model API call. See Observability for the lifecycle tree, content policy, and ACP limitations.

See Agent provider selection, Sandbox compatibility, and the code-review workflow for complete compositions.