Write the workflow as reusable components
Package agents, prompts, capabilities, and control flow as ordinary async JSX components. Compose them into larger workflows without hiding how data moves.
agent markup language | async JSX runtime
Write the workflow you mean. AML brings agents, tools, sandboxes, persistent files, and multi-step logic into one async JSX tree — without tying that workflow to one provider.
AmlRuntime · example leaves-first resolution tree
<Agent provider={codex}>
<Mcp use={slack} />
post our weekly standup:
{synthesis}
</Agent>
A framework for building complex, provider-agnostic agent workflows.
why aml
Most AI SDKs are designed around chat: send a message, call a model, stream a response. Agentic workflows need much more around that conversation — tools, permissions, sandboxed execution, persistent files, multiple agents, and clear control over how work moves between them. AML brings those pieces into one provider-agnostic runtime, expressed as composable, human-readable XML trees that developers can read, reason about, and reuse.
Package agents, prompts, capabilities, and control flow as ordinary async JSX components. Compose them into larger workflows without hiding how data moves.
Move between OpenCode, Codex, and Pi — or use a deterministic test provider — without rebuilding the workflow around a new SDK.
Attach sandboxes and persistent workspaces exactly where they’re needed. AML manages their scope, lifecycle, and cleanup.
Every run emits structured lifecycle and trace events, so you can inspect a workflow today and build better tooling around it tomorrow.
how it works
AML gives JSX a new job. Instead of describing a user interface, the tree describes an agent workflow—and the runtime resolves it from the leaves up. There’s no new DSL to learn: editors already understand JSX, TypeScript already checks it, and language models already know how to write it.
<Review /> resolution order
under the hood
When an
<Agent/>
node resolves, the AML Runtime preloads a
<Workspace/>
into a safe
<Sandbox/>
and prompts the agent sdk through
Agent Client Protocol. The Agent reads files, edits code, and runs commands inside the Sandbox. When the work is done, AML
collects the result and saves the Workspace changes. Because every built-in Agent uses the same ACP
connection, you can switch Agents or Sandboxes without rewriting the tree.
integrations
Every built-in Agent runs across every built-in Sandbox. Use OpenCode, Codex, or Pi with trusted local execution, Docker, Daytona, or Modal, then keep files locally or in S3-compatible object storage without rewriting the Agent tree.
agents
harnesses & model runtimes
sandboxes
ephemeral execution
workspaces
durable object storage
runtime packages
all from @aml-jsx/sdk
agent
sandbox
workspace
any agent on any sandbox with durable files
import { Agent, AmlRuntime, Sandbox, Workspace, opencodeAgent, localSandbox, s3Workspace,} from "@aml-jsx/sdk" const provider = opencodeAgent({ model: "opencode-go/glm-5.1" })const sandbox = localSandbox({ workspace: "./project" })const workspace = s3Workspace({ bucket: "agent-workspaces" })const runtime = new AmlRuntime() await runtime.evaluate( <Workspace id="thread-42" load save={{ include: ["**/*.md"] }} provider={workspace}> <Sandbox provider={sandbox}> <Agent provider={provider}>Summarize this repository.</Agent> </Sandbox> </Workspace>,)
bring your own
The same contracts are open to custom providers.
reference
Eleven primitives and a focused set of runtime APIs. Everything else is ordinary JavaScript — control flow, concurrency, and data flow included.
get started
AML is under active development. These examples show the intended API shape and may differ from the current implementation.
step 1
$ npm install @aml-jsx/sdk
Coding with an agent?
$ npx skills add we-are-singular/aml --skill aml-jsx
step 2
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@aml-jsx/sdk"
}
}
step 3
import { Agent, AmlRuntime, opencodeAgent } from "@aml-jsx/sdk"
const OpenCode = opencodeAgent({})
const runtime = new AmlRuntime()
await runtime.evaluate(
<Agent provider={OpenCode}>Summarize this repository.</Agent>,
)
contributing
Want to build a provider, sharpen the runtime semantics, improve the developer experience, or argue for a better API? This is the useful stage to show up: the important decisions are still being made.
help create provider adapters · shape the runtime · improve examples, docs, and tooling
Help build AML