# Agent Markup Language — complete documentation This file concatenates every published AML documentation page for language models, search tools, and offline reference. For the shorter project and editorial overview, see https://agent-markup-language.com/llms.txt. For the navigable documentation website, see https://agent-markup-language.com/docs/. CLI guide: https://agent-markup-language.com/docs/cli/ Install the CLI beside the SDK with `npm install @aml-jsx/sdk && npm install --save-dev @aml-jsx/cli`. Run an exported workflow with `npx aml run ./workflow.tsx`; the file is positional and `--entry` selects a named export. Pages included: 80 --- # AML documentation Build, understand, and operate typed agent workflows with Agent Markup Language. Canonical: https://agent-markup-language.com/docs/ Documentation index: https://agent-markup-language.com/docs/ Complete documentation: https://agent-markup-language.com/docs/llms.txt **Documentation shortcuts** - [FAQ](https://agent-markup-language.com/docs/faq/) - [Examples](https://agent-markup-language.com/docs/examples/) - [CLI](https://agent-markup-language.com/docs/cli/) - [Agent skill](https://agent-markup-language.com/docs/agent-skill/) - [Providers](https://agent-markup-language.com/docs/providers/) - [Cookbook](https://agent-markup-language.com/docs/cookbook/) - [Reference](https://agent-markup-language.com/docs/reference/) - [Full documentation for agents](https://agent-markup-language.com/docs/llms.txt) — Give an agent the complete AML documentation in one plain-text file. - [Project llms.txt](https://agent-markup-language.com/llms.txt) — Share the concise project overview and links to the full agent documentation. AML is an asynchronous TypeScript and JSX runtime for building executable agent workflows. JSX describes the dependency tree; [`AmlRuntime`](https://agent-markup-language.com/docs/reference/runtime/) evaluates it, opens scoped resources, runs provider sessions, and cleans up in reverse order. It is not a UI framework or a second workflow language—ordinary TypeScript owns control flow, while [``](https://agent-markup-language.com/docs/reference/primitives/parallel/) explicitly marks independent AML branches. ## Install AML **Application runtime** ### Install the SDK Add the public ESM package to a Node.js 26+ TypeScript project. ```sh npm install @aml-jsx/sdk ``` Prefer an executable workflow file without application glue? Use the [experimental AML CLI](https://agent-markup-language.com/docs/cli/). [Configure TSX and run a credential-free workflow →](https://agent-markup-language.com/docs/getting-started/) **Coding agents** ### Install the AML authoring skill Give a compatible coding agent the repository-backed AML API, composition, provider, and security guidance. ```sh npx skills add \ we-are-singular/aml \ --skill aml-jsx ``` The skill guides the agent; your project still needs the SDK and its selected provider executables. [Install, verify, and use the skill →](https://agent-markup-language.com/docs/agent-skill/) Start with the [credential-free tutorial](https://agent-markup-language.com/docs/getting-started/), then use the provider guides and cookbook to assemble a production workflow. Search the complete documentation with `Ctrl` + `K`. --- # AML authoring skill Install, verify, and use AML's repository-backed guidance with coding agents. Canonical: https://agent-markup-language.com/docs/agent-skill/ Documentation index: https://agent-markup-language.com/docs/ Complete documentation: https://agent-markup-language.com/docs/llms.txt The AML authoring skill gives a compatible coding agent the project’s current API, composition rules, provider boundaries, and security guidance. It is useful when an agent is creating or reviewing AML code; it is not a runtime dependency and does not install the SDK or provider executables for your application. ## Install the skill Run the project-local install from the repository where you want an agent to use AML: ```sh title="Terminal" npx skills add we-are-singular/aml \ --skill aml-jsx ``` The Skills CLI detects compatible clients and asks where to install when a choice is required. To target a supported client explicitly, pass its client identifier: ```sh title="Terminal" npx skills add we-are-singular/aml \ --skill aml-jsx \ --agent codex ``` Use a global install only when you want the skill available across projects: ```sh title="Terminal" npx skills add we-are-singular/aml \ --skill aml-jsx \ --global ``` **Note — Client support changes independently** The skill is a portable `SKILL.md`, but automatic discovery depends on the coding client and the installed Skills CLI version. Let the CLI auto-detect your clients, or use `--agent` with an identifier accepted by `npx skills --help`. Project-local installation is the safer default because it travels with the repository context instead of affecting every project. ## Verify the installation List project-local skills as machine-readable output: ```sh title="Terminal" npx skills list --json ``` For a global installation: ```sh title="Terminal" npx skills list --global --json ``` Confirm that the result contains `aml-jsx`. If you targeted one client, you can also filter the listing with `--agent `. The canonical source remains [`skills/aml-jsx/SKILL.md`](https://github.com/we-are-singular/aml/blob/main/skills/aml-jsx/SKILL.md). Review that file when you need to confirm exactly what an installed copy teaches an agent. ## What the skill asks an agent to do 1. **Preflight the project.** Confirm Node.js, ESM, TypeScript, JSX runtime configuration, and the public `@aml-jsx/sdk` package boundary. 2. **Choose explicit providers.** Separate the [Agent, Sandbox, and Workspace responsibilities](https://agent-markup-language.com/docs/providers/) and check each provider’s prerequisites. 3. **Author the smallest complete tree.** Keep ordinary branching and concurrency in TypeScript while AML owns dependency resolution and resource scopes. 4. **Review authority and lifecycle.** Treat [Sandbox isolation](https://agent-markup-language.com/docs/production/security/), credentials, Workspace publication, cancellation, and cleanup as explicit application decisions. 5. **Verify against public contracts.** Use public SDK imports, compile the workflow, and distinguish deterministic checks from vendor integration evidence. The skill routes an agent to focused references for composition, capabilities, resources, providers, and security. It deliberately tells the agent not to invent SDK exports or silently add infrastructure. ## What the skill does not do **It does not install AML** Your application still needs `npm install @aml-jsx/sdk`, an ESM/TSX configuration, and a way to execute or compile TypeScript. **It does not install providers** Codex ACP, GitHub Copilot CLI, OpenCode, Pi, Docker, and remote provider clients remain explicit deployment prerequisites. **It does not grant authority** A skill can guide code generation, but only your selected Sandbox and deployment policy control processes, files, network access, and credentials. **It does not replace these docs** Provider versions and public contracts can change while AML is pre-stable. Use the linked documentation and source as the current authority. ## A useful first prompt After installation, give the agent a concrete provider and safety boundary instead of asking only for “an AML workflow”: ```text Use the aml-jsx skill to create a credential-free AML workflow first. Then show the smallest change required to run it with Codex inside Docker. Keep secrets outside the AML tree and explain the Workspace save policy. ``` This prompt forces the important choices into the open: deterministic versus live execution, Agent provider, Sandbox authority, and durable state. ## Update or remove Refresh the installed copy when the SDK or docs change: ```sh title="Terminal" npx skills update aml-jsx ``` Remove the project-local skill with the interactive remover, or name it directly: ```sh title="Terminal" npx skills remove aml-jsx ``` For a global installation, add `--global` to the update or remove command. ## Continue from here - [Install the SDK and run the credential-free tutorial](https://agent-markup-language.com/docs/getting-started/). - [Choose an Agent, Sandbox, and Workspace](https://agent-markup-language.com/docs/providers/). - [Read the canonical execution model](https://agent-markup-language.com/docs/concepts/). - [Review production security boundaries](https://agent-markup-language.com/docs/production/security/). --- # Getting started Install AML and resolve a credential-free workflow before connecting a real Agent provider. Canonical: https://agent-markup-language.com/docs/getting-started/ Documentation index: https://agent-markup-language.com/docs/ Complete documentation: https://agent-markup-language.com/docs/llms.txt This guide gives you a deterministic first success: no API key, ACP executable, Docker daemon, or remote account required. The main path shows an application-owned [`AmlRuntime`](https://agent-markup-language.com/docs/reference/runtime/); an optional CLI path then runs an exported tree without application glue. You will finally swap in a real [Agent provider](https://agent-markup-language.com/docs/providers/agents/) without changing the authored AML tree. ## Prerequisites - Node.js **26 or newer** - an ESM project (`"type": "module"` in `package.json`) - TypeScript if you author `.tsx` **Caution — AML is ESM-only** CommonJS `require()` is not a supported package entrypoint. Use ESM imports and a TSX-capable runner or compile the project before running it. If a coding agent will author or review the workflow, optionally install the [AML authoring skill](https://agent-markup-language.com/docs/agent-skill/). The skill teaches the agent the current public API and safety boundaries; it does not replace the SDK installation below. ## 1. Create a project **npm** ```sh title="Terminal" mkdir aml-first-workflow cd aml-first-workflow npm init -y npm pkg set type=module npm install @aml-jsx/sdk npm install --save-dev typescript vite-node ``` **pnpm** ```sh title="Terminal" mkdir aml-first-workflow cd aml-first-workflow pnpm init pnpm add @aml-jsx/sdk pnpm add --save-dev typescript vite-node ``` Add `"type": "module"` to `package.json`. **Note — pnpm may require build-script approval** pnpm 11 can stop the install with `ERR_PNPM_IGNORED_BUILDS` when it blocks transitive native build scripts. Run `pnpm approve-builds`, approve the dependencies named by pnpm, then run `pnpm install` again. This is pnpm's installation policy; AML does not execute those scripts at runtime. Create `tsconfig.json`: ```json title="tsconfig.json" { "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext", "target": "ES2024", "strict": true, "skipLibCheck": true, "jsx": "react-jsx", "jsxImportSource": "@aml-jsx/sdk" } } ``` The automatic JSX runtime turns AML elements into AML nodes. React is not installed or involved. `skipLibCheck` skips checking upstream declaration files loaded by the bundled provider adapters while preserving strict checks for your project source. Add one repeatable command to the generated `package.json`: ```json title="package.json" { "type": "module", "scripts": { "aml": "vite-node src/first-workflow.tsx" } } ``` Keep the dependencies added by your package manager when you merge this snippet into the generated file. ## 2. Evaluate your first tree Create `src/first-workflow.tsx`: ```tsx title="src/first-workflow.tsx" import { Agent, AmlRuntime } from "@aml-jsx/sdk" import { DeterministicAgentProvider } from "@aml-jsx/sdk/testing" const agentProvider = new DeterministicAgentProvider({ name: "first-workflow", respond: request => ({ text: `Resolved: ${request.prompt}` }), }) const runtime = new AmlRuntime({ agentProvider }) const result = await runtime.evaluate(Explain what AML evaluates.) console.log(result) ``` Run it with the script you just added: ```sh title="Terminal" npm run aml # or: pnpm aml ``` Expected output: ```text title="Output" Resolved: Explain what AML evaluates. ``` 1. JSX creates an AML node tree; it does not run `` during rendering. 2. `AmlRuntime.evaluate()` validates and resolves the tree. 3. [``](https://agent-markup-language.com/docs/reference/primitives/agent/) builds a normalized request from its system text, prompt, capabilities, and effective scopes. 4. The selected provider returns an `AgentResponse`; the runtime returns its text from the root. 5. The runtime releases acquired resources in reverse order. The [`DeterministicAgentProvider`](https://agent-markup-language.com/docs/reference/testing/#deterministicagentprovider) deliberately echoes a known result and records calls. It is part of the public testing entrypoint, making it useful for tutorials, examples, and workflow tests—not just AML's own test suite. ### Run the same tree with the CLI The application above constructs `AmlRuntime` because it owns the process. For a standalone workflow file, install the experimental CLI beside the SDK: ```sh title="Terminal" npm install --save-dev @aml-jsx/cli ``` Create `src/cli-workflow.tsx`. Put the provider directly on [``](https://agent-markup-language.com/docs/reference/primitives/agent/), export the tree, and let the CLI create and instrument the runtime: ```tsx title="src/cli-workflow.tsx" import { Agent } from "@aml-jsx/sdk" import { DeterministicAgentProvider } from "@aml-jsx/sdk/testing" const provider = new DeterministicAgentProvider({ name: "cli-workflow", respond: request => ({ text: `Resolved: ${request.prompt}` }), }) export default Explain what AML evaluates. ``` Run the exported workflow: ```sh title="Terminal" npx aml run ./src/cli-workflow.tsx ``` Expected output on standard output: ```text title="Output" Resolved: Explain what AML evaluates. ``` **Caution — Do not create a second runtime inside a CLI workflow** Export the AML tree itself. Calling `new AmlRuntime().evaluate(...)` inside the exported function creates a separate nested evaluation, so the CLI cannot trace, cancel, or configure the Agent work it was intended to own. The complete export, environment, and output contract is in the [CLI guide](https://agent-markup-language.com/docs/cli/). ## 3. Connect a real Agent The authored node remains the same. Replace the contents of `src/first-workflow.tsx` with one complete tab below, then run the same `aml` script. **Note — There is no universal default provider** Start with the coding harness and model account you already operate. The Codex tab is the shortest path when you have an OpenAI API key; choose OpenCode for its model catalog and native tool policy, or Pi for its extensible Tool and MCP path. The provider comparison explains the trade-offs in detail. **Codex** ```tsx title="src/first-workflow.tsx" import { Agent, AmlRuntime, codexAgent } from "@aml-jsx/sdk" const apiKey = process.env.OPENAI_API_KEY if (!apiKey) throw new Error("OPENAI_API_KEY is required") const runtime = new AmlRuntime({ agentProvider: codexAgent({ apiKey, model: "gpt-5.6-luna", reasoningEffort: "low", }), }) const result = await runtime.evaluate(Describe this project in three bullets.) console.log(result) ``` Install and verify the ACP adapter version exercised by this repository, then supply a credential through your shell or secret manager: ```sh npm install --global @agentclientprotocol/codex-acp@1.4.0 @openai/codex@0.147.0 codex-acp --help codex --version export OPENAI_API_KEY="your-development-key" npm run aml ``` Do not commit the key or place it in a Workspace. See the [Codex guide](https://agent-markup-language.com/docs/providers/agents/codex/) for executable overrides, `CODEX_API_KEY`, model precedence, permissions, and Sandbox compatibility. **OpenCode** ```tsx title="src/first-workflow.tsx" import { Agent, AmlRuntime, opencodeAgent } from "@aml-jsx/sdk" const apiKey = process.env.OPENCODE_API_KEY if (!apiKey) throw new Error("OPENCODE_API_KEY is required") const runtime = new AmlRuntime({ agentProvider: opencodeAgent({ env: { OPENCODE_API_KEY: apiKey }, model: "opencode-go/deepseek-v4-flash", }), }) const result = await runtime.evaluate(Describe this project in three bullets.) console.log(result) ``` Install and verify the OpenCode executable, then configure a model provider: ```sh npm install --global opencode-ai@1.18.18 opencode --version export OPENCODE_API_KEY="your-development-key" npm run aml ``` This tab deliberately uses an environment credential so the complete path is visible. OpenCode also supports native `opencode auth login`; if you use that path, remove the explicit key guard and environment mapping and select a model configured for the logged-in account. The [OpenCode guide](https://agent-markup-language.com/docs/providers/agents/opencode/) documents both approaches, its generated profile, permission mapping, and state isolation. **Pi** ```tsx title="src/first-workflow.tsx" import { Agent, AmlRuntime, piAgent } from "@aml-jsx/sdk" const apiKey = process.env.OPENCODE_API_KEY if (!apiKey) throw new Error("OPENCODE_API_KEY is required") const runtime = new AmlRuntime({ agentProvider: piAgent({ command: "pi-acp", env: { OPENCODE_API_KEY: apiKey }, model: "opencode-go/deepseek-v4-flash", piCommand: "pi", }), }) const result = await runtime.evaluate(Describe this project in three bullets.) console.log(result) ``` Install and verify the ACP bridge and Pi CLI: ```sh npm install --global pi-acp@0.0.33 @earendil-works/pi-coding-agent@0.84.2 pi --version command -v pi-acp export OPENCODE_API_KEY="your-development-key" npm run aml ``` This follows the repository smoke path with DeepSeek V4 Flash through OpenCode Go. If you select another Pi model provider, change the model identifier and forward that provider's credential instead. The [Pi guide](https://agent-markup-language.com/docs/providers/agents/pi/) explains when AML generates a wrapper and how to install `pi-mcp-adapter` for Tools, authored MCP servers, or structured output. **Tip — Provider selection is lexical too** Set a default on `AmlRuntime`, or pass `provider` directly to an `` when one subtree needs a different model harness. A direct prop wins over the runtime default. Compare the built-in profiles in [Choose an Agent](/docs/providers/agents/). ## 4. Add files and command execution [``](https://agent-markup-language.com/docs/reference/primitives/file/) writes through the nearest active [``](https://agent-markup-language.com/docs/reference/primitives/workspace/) or [``](https://agent-markup-language.com/docs/reference/primitives/sandbox/) filesystem. [` ) ``` The inline shell starts a child process and waits for it. `AML_PROCESS_SAFETY_PID_FILE` is optional; when set, it records the child PID so cleanup can be checked independently. The Sandbox lease tracks the shell process, and local spawning creates a process group, so releasing the lease terminates the shell and its `sleep` descendant rather than abandoning the child. The command does not install its own cleanup abstraction. Process lifetime belongs to the Sandbox provider, and application interruption belongs to the runner. ## Main file: export the tree The maintained file combines the imports and the two blocks above, then exports the AML value directly: ```tsx title="cli-process-safety.tsx" import { cwd } from "node:process" import { localSandbox, Sandbox, Script } from "@aml-jsx/sdk" // LongRunningProcess is the AML tree defined above. export default LongRunningProcess ``` Do not construct `AmlRuntime` in this file. `aml run` must own the runtime for its signal controller to cover the Script, Sandbox release, diagnostics, and final exit code as one lifecycle. ## Run and interrupt it From the repository root: ```sh title="Terminal" npm run build --workspace=@aml-jsx/cli AML_PROCESS_SAFETY_PID_FILE=/tmp/aml-process-safety.pid \ node apps/cli/dist/index.js run ./examples/src/operations/cli-process-safety.tsx --trace ``` Wait for `/tmp/aml-process-safety.pid` to appear, then press `Ctrl`+`C` once. The CLI starts graceful cancellation and allows up to ten seconds for cleanup. A second interrupt explicitly stops waiting; it cannot guarantee JavaScript cleanup completed. Check the conventional status and recorded child PID: ```sh title="Terminal" status=$? pid=$(cat /tmp/aml-process-safety.pid) printf 'exit=%s child=%s\n' "$status" "$pid" kill -0 "$pid" ``` Expected: `exit=130 ...`, and `kill -0` fails because the child no longer exists. If you send `SIGTERM` from another terminal, expect status `143`. ## What happens on the first signal 1. The CLI's process-signal owner aborts the signal passed to `runtime.evaluate()` and starts its ten-second forced-exit deadline. 2. The active Script receives cancellation through the Sandbox command signal. The local provider terminates the tracked process group. 3. AML unwinds the evaluation and releases the acquired Sandbox lease. Release is still called even though the Script did not complete normally. 4. Only after evaluation cleanup settles does the CLI dispose its signal listeners and deadline, set the conventional exit code, and return control to Node. ## Failure and safety boundaries **Caution — Graceful process safety is not crash recovery** `SIGKILL`, a runtime crash, host loss, and power failure cannot execute JavaScript cleanup. Remote or durable providers still need platform TTLs, reapers, and incident detection. - `localSandbox()` executes trusted host commands. Replace it with an appropriately configured container or remote Sandbox for hostile code. - The ten-second deadline bounds shutdown; it does not prove a remote provider reached a terminal state before forced exit. - A second signal is an operator override. Use it only when stopping immediately is more important than completing cleanup. - Application code using `AmlRuntime` directly can use [`ProcessSignalCancellation`](https://agent-markup-language.com/docs/runtime/#process-signal-cancellation). Do not add a second signal owner around `aml run`. - Remove the optional PID file after the walkthrough; it is verification state, not an AML resource. ## Source and API links - [Maintained CLI process-safety example](https://github.com/we-are-singular/aml/blob/main/examples/src/operations/cli-process-safety.tsx) - [CLI interruption contract](https://agent-markup-language.com/docs/cli/#interrupting-a-run) - [`` and provider cleanup](https://agent-markup-language.com/docs/reference/primitives/sandbox/) - [` ) return await new AmlRuntime({ agentProvider: reviewer }).evaluate( Review only this diagnostic output. Do not claim to have inspected files that are not listed: {evidence} ) } console.log(await TriageRepository()) ``` ## Run it Save the complete source as `recipe.tsx` in a project configured as shown in [Getting started](https://agent-markup-language.com/docs/getting-started/). Verify the required image, then run that exact workflow: ```sh title="Terminal" docker image inspect node:26 npx vite-node recipe.tsx ``` A successful run prints JSON evidence from the container and then a reviewer message containing that evidence. File names vary with the directory from which the program is launched. ## Observable result The diagnostic emits a line shaped like: ```text {"files":["README.md","package.json"]} ``` The final `` receives that line as ordinary prompt data. Docker Sandbox is acquired and released around the ` , ) console.log(await readFile(join(directory, "output.txt"), "utf8")) ``` For a real Agent, replace the image with one that contains the ACP executable and use the corresponding Agent provider inside the same [``](https://agent-markup-language.com/docs/reference/primitives/sandbox/). Do not use a public tutorial image as evidence that your Agent/Sandbox pair is deployable. ## Lifecycle 1. AML resolves the active Workspace directory or the configured fallback. 2. Docker starts a named detached container with `--rm`, the selected image, optional runtime user, `/workspace` bind mount, logical guest cwd, and a keepalive `sh` process. 3. If startup fails, AML attempts to remove the named container and aggregates startup and cleanup failures when both fail. 4. The optional setup command runs after the mount is ready. A non-zero result rejects acquisition and triggers container cleanup. 5. `exec()` invokes `docker exec` with the logical guest cwd and explicit environment values. 6. `spawn()` invokes a process-group wrapper inside the container, captures output from the beginning, and can kill the remote process group. 7. Complete-file reads and writes use confined guest paths plus `docker cp`; writes upload a temporary file and rename it over the destination. Agent staging uses a unique writable directory under `/tmp`. 8. Timeout or cancellation of `docker exec` removes the disposable container because the remote command may otherwise survive the local client process. 9. Release removes the container. Because the Workspace is a same-host mount, writes are already present in the host materialization; Workspace save/revision behavior remains the Workspace provider’s responsibility. ## Read-only behavior Docker is the built-in provider that can execute commands with a read-only Workspace mount. AML passes the mount as `/workspace:ro` and still permits `exec()` and `spawn()` against the image filesystem. The Agent may still need writable state outside `/workspace`; its process permissions and image filesystem are separate concerns. Read-only does not mean “no side effects anywhere in the container.” It protects the mounted Workspace. Container-level filesystem, network, process, and credential behavior depends on the image and Docker daemon configuration. ## Security posture The adapter invokes `docker run` with an image, `--detach`, `--rm`, a bind mount, a working directory, and a shell entrypoint. It does not configure: - network isolation or egress policy; - Linux capabilities, seccomp, AppArmor, or SELinux policy; - rootless daemon mode or automatic container-user selection; `user` only passes an explicit identity to Docker; - CPU, memory, PID, or disk limits; - a read-only root filesystem; - secret injection or credential redaction at the Docker daemon boundary. Treat the Docker daemon and selected image as part of your security boundary. Pin trusted image digests, use a hardened daemon/runtime policy, choose a non-root image where appropriate, configure network and resource limits outside AML, and do not mount sensitive host directories. Do not run untrusted model-generated code with a default Docker installation and call that complete hostile-code isolation. ## Failure modes and troubleshooting | Symptom | Cause | What to check | | ------------------------------------ | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | | `docker: command not found` | The Docker CLI is absent from the host. | Install/configure the CLI in the application environment. | | Cannot connect to the Docker daemon | The daemon socket or context is unavailable. | Check `docker info` as the same user that runs AML. | | Container exits before acquisition | Image lacks `sh`, cannot start, or has incompatible architecture/permissions. | Run the image manually with the expected user and shell. | | Agent executable not found | The image does not contain the selected ACP command. | Install it in the image or use a trusted setup hook; AML does not install it. | | `Workspace` mount fails | Host source is missing, not a directory, or inaccessible to the Docker daemon. | Verify the active/fallback path and daemon access to the host filesystem. | | Workspace permission denied | The image user cannot access the host-owned bind mount. | Set `user` to the Workspace owner's `UID:GID`, or align ownership in the image. | | `exec` exits with code 126/127 | Command is not executable or not found inside the image. | Check image PATH, executable permissions, architecture, and runtime dependencies. | | Output limit exceeded | Combined command output exceeded `maxOutputBytes`. | Reduce output, use `spawn()`, or raise the limit deliberately. | | Remote command survives cancellation | Docker exec cannot always clean up the child independently. | AML removes the disposable container; inspect daemon logs if termination is delayed. | | Files changed remotely are missing | The container was released before a same-host mount write completed or the command wrote outside `/workspace`. | Keep writes below the mounted root and wait for command completion. | ## References - [Sandbox provider overview](https://agent-markup-language.com/docs/providers/sandboxes/) - [Docker’s security documentation](https://docs.docker.com/engine/security/) - [Docker image and container reference](https://docs.docker.com/reference/) - [AML Docker provider implementation](https://github.com/we-are-singular/aml/blob/main/providers/sandboxes/docker/src/docker-sandbox.ts) - [AML Docker provider tests](https://github.com/we-are-singular/aml/blob/main/providers/sandboxes/docker/tests/docker-sandbox.test.ts) - [Sandboxing architecture](https://github.com/we-are-singular/aml/blob/main/SANDBOXING.md) - [AML specification: Sandbox composition](https://github.com/we-are-singular/aml/blob/main/SPEC.md) --- # Alternative and custom Sandbox images Evaluate third-party images, custom image recipes, and compatibility requirements for AML Sandbox providers. Canonical: https://agent-markup-language.com/docs/providers/sandboxes/images/ Documentation index: https://agent-markup-language.com/docs/ Complete documentation: https://agent-markup-language.com/docs/llms.txt AML's own full and single-Agent images, Docker Hub tags, bleeding-edge GHCR channel, usage, and extension model are documented in [AML Agent Sandbox images](https://agent-markup-language.com/docs/sandbox-images/). Start there unless a third-party image or provider-native recipe is an explicit deployment requirement. This page covers alternatives we have inspected and the compatibility checks required before replacing AML's image. A public image containing the desired Agent is useful evidence, but it does not prove model credentials, network policy, Workspace transfer, entrypoint behavior, or production isolation. ## Replacement image baseline An alternative or custom image must provide the complete executable chain required by the selected Agent plus the tools required by its Sandbox provider: - `sh`, `mkdir`, and `rm` for every image-backed provider; - `tar` for Daytona and Modal Workspace transfer; - the selected ACP Agent executable and its language/native runtime; - a writable home and Workspace path for the configured user; - project dependencies and every command launched by ` ``` ## Result and failures Successful standard output becomes AML text for later composition. A non-zero exit code rejects with `EvaluationError` and includes trimmed stderr detail when available. AML bounds, cancels, and reaps host execution directly; inside a Sandbox, its provider owns those runtime details. Trace spans report `environment="host"` or `environment="sandbox"`. Generated source is executable authority. If [``](https://agent-markup-language.com/docs/reference/primitives/agent/) produces the children of `