agent markup language | async JSX runtime

Agent workflows
authored as <markup />

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

resolving running resolved cycle 1

<Agent provider={codex}>

<Mcp use={slack} />

post our weekly standup:

{synthesis}

</Agent>

A framework for building complex, provider-agnostic agent workflows.

why aml

Your agent isn’t enough.

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.

</>

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.

Change providers without starting over

Move from OpenCode to Codex — or replace both with a deterministic test provider — without rebuilding the workflow around a new SDK.

Give agents a real place to work

Attach sandboxes and persistent workspaces exactly where they’re needed. AML manages their scope, lifecycle, and cleanup.

See what happened

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

Start at the leaves. Work your way back.

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

    integrations

    Bring your own agent, sandbox, or storage.

    AML defines the contracts and stays out of the way. Choose the implementations that fit your stack, then swap them without rewriting the workflow.

    agents

    harnesses & model runtimes

    roadmap →

    sandboxes

    ephemeral execution

    roadmap →

    workspaces

    durable object storage

    roadmap →

    runtime packages

    agent

    opencodeAgent({})

    Runs OpenCode sessions with model overrides, JavaScript tools, MCP grants, follow-ups, cancellation, and structured output.

    from @aml-jsx/sdk

    agent

    codexAgent({})

    Runs Codex SDK threads with model overrides, read-only host tools, JavaScript tools, MCP grants, and follow-ups.

    from @aml-jsx/sdk

    sandbox

    dockerSandbox({})

    Confined Docker container leases with explicit filesystem, network, identity, capability, and resource policies.

    from @aml-jsx/sdk

    workspace

    localWorkspace({})

    Uses an existing local directory as a durable workspace with cross-process writer locking.

    from @aml-jsx/sdk

    testing

    @aml-jsx/sdk/testing

    Deterministic Agent, Sandbox, and Workspace providers plus reusable conformance suites for examples, adapter development, and tests.

    DeterministicAgentProvider

    yours?

    defineAgentProvider()

    Implement the provider contract and any agent harness — yours included — can run inside an AML tree.

    read the contract ↗

    reference

    Small enough to learn in one sitting

    Nine primitives and a handful of runtime APIs. Everything else is ordinary JavaScript — control flow, concurrency, and data flow included.

    
                    

    get started

    From install to first run in three files

    AML is under active development. These examples show the intended API shape and may differ from the current implementation.

    step 1

    Install the runtime

    $ npm install @aml-jsx/sdk

    step 2

    Point JSX at AML

    {
      "compilerOptions": {
        "jsx": "react-jsx",
        "jsxImportSource": "@aml-jsx/sdk"
      }
    }

    step 3

    Evaluate a tree

    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

    AML is early. Help shape what it becomes.

    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