amp
OfficialSourcegraph Amp CLI. amp_execute runs amp -x; amp_version and amp_setup_check do not need a key. Package @ampcode/cli@0.0.1792022479-ge66e24.
Install
abx template deploy ./amp -y --alias amp
abx create --template amp
# TemplateID from `abx --json template deploy` is also acceptedOn each provider
Express publishes this directory with abx template deploy. The other providers do not declare templates.build, so they do not register this directory.
| Provider | Status | How |
|---|---|---|
| Alibaba Cloud Agent Sandbox Express Edition | Deploys on Express | Use → |
| Alibaba Cloud Agent Sandbox Container Edition | Existing template id | Use → |
| CubeSandbox | Existing template id | Use → |
| E2B | Existing template id | Use → |
| OpenSandbox | Image URI, not this directory | Use → |
About
Sourcegraph Amp CLI in an Agent Sandbox. The image pins @ampcode/cli and serves named commands on port 9000.
What it does
Installs the Amp CLI (amp) and registers four commands:
| Command | What it runs |
|---|---|
amp_version |
amp version |
amp_setup_check |
amp version, then writes the settings file described below |
amp_execute |
amp --dangerously-allow-all --no-color --no-notifications --no-ide -x <prompt> |
amp |
The previous name of amp_execute. Same arguments. |
amp_execute adds --stream-json when stream_json is true. The HTTP response is the full stdout after the process exits. It is not a live stream.
amp_execute checks AMP_API_KEY before it starts the CLI. If the variable is missing or blank, the command returns an error that names AMP_API_KEY and says the CLI would otherwise start a device-login flow. Probed on 2026-10-15: amp -x with no key prints a device-login URL and waits. This command does not do that.
Amp does not accept a DashScope key, ABX_LLM_API_KEY, or an OpenAI-compatible base URL. The token is an Amp access token from ampcode.com settings.
--dangerously-allow-all is a flag the 0.0.1792022479-ge66e24 binary accepts. amp --help on that version does not list it in the options section. The help text documents the settings key amp.dangerouslyAllowAll. amp_execute passes the flag and amp_setup_check writes the settings key.
Stack
- Base image
fc-e2b-registry.<region>.cr.aliyuncs.com/runtime/base:<tag>.abx template deployreplaces<region>withALIBABA_CLOUD_REGION_IDorcn-hangzhou, and<tag>withABX_BASE_IMAGE_TAGorv0.0.49. - Node.js 20 from that image, used only to run
npm. Theampbinary is a glibc ELF from the optional package@ampcode/cli-linux-x64at the same version. @ampcode/cli@0.0.1792022479-ge66e24, fromnpm view @ampcode/cli versionon 2026-10-15. The previous directory pin was0.0.1791964847-g13f24a. The base image sets npm's registry toregistry.npmmirror.com, which returned 404 for@ampcode/cli-linux-x64at this version, so the Dockerfile installs fromhttps://registry.npmjs.org.amp versionruns in the image build and fails the build if the native binary was not unpacked.agent-sandbox-serverfrom python-sdk commit61c43e0be65a1f57aa09186d578e7b399e48429b(PR #21). That distribution is not on PyPI.- git and ripgrep.
- Work directory
/home/user/app. Runtime useruser. The platform startsstart_cmd. The Dockerfile has noCMDorENTRYPOINT.
Problem solved
A generation-2 sandbox can run a pinned Amp CLI without a TUI, report the version and the settings file without a key, and refuse a live turn when AMP_API_KEY is absent instead of blocking on device login.
Quick start (CLI)
From a checkout of this repository, with Express credentials in the environment:
abx template deploy ./amp -y --generation 2 \
--start-cmd 'agent-sandbox-server serve --port 9000 --commands /home/user/app/commands.py' \
--ready-cmd 'agent-sandbox-server healthcheck --port 9000'
abx create --template <template-id> -y
abx run <sandbox-id> amp_version
abx run <sandbox-id> amp_setup_check
template.yaml already stores generation, start_cmd, and ready_cmd. A live turn needs an Amp access token. Pass it at create time. Do not bake it into the image:
abx create --template <template-id> -y --env AMP_API_KEY=<amp-access-token>
abx run <sandbox-id> amp_execute --arg prompt='Reply with exactly: ABX_E2E_OK'
stream_json is a boolean. Pass it with --json-args:
abx run <sandbox-id> amp_execute --json-args '{"prompt":"Reply with exactly: ABX_E2E_OK","stream_json":true}'
Remove the sandbox and the template when you are done:
abx kill <sandbox-id> -y
abx template delete <template-id> -y
python3 scripts/express_e2e.py amp deploys a unique alias, runs the smoke commands (amp_version and amp_setup_check) through abx run and the Python SDK, writes evidence only after a pass, and deletes that sandbox and that template.
Quick start (Python SDK)
Install the client from PyPI as agent-sandbox-client (python3 -m pip install agent-sandbox-client). The import is agent_sandbox. pip install agent-sandbox is an unrelated project.
import asyncio
from agent_sandbox import Sandbox
async def main() -> None:
sb = await Sandbox.create(template="<template-id>", timeout=300)
try:
print(await sb.run("amp_version"))
print(await sb.run("amp_setup_check"))
# AMP_API_KEY is an Amp access token, not a DashScope key.
# print(await sb.run("amp_execute", prompt="Reply with exactly: ABX_E2E_OK"))
finally:
await sb.kill()
asyncio.run(main())
Create with the key when you want amp_execute:
sb = await Sandbox.create(
template="<template-id>",
timeout=300,
envs={"AMP_API_KEY": "<amp-access-token>"},
)
text = await sb.run("amp_execute", prompt="Reply with exactly: ABX_E2E_OK", stream_json=False)
await sb.run(...) returns the command's result value. sb.commands.run is a shell command, not one of these names. Sandbox.create_sync raises TypeError on python-sdk 0.3.0 (python-sdk#22); use await Sandbox.create.
Command reference
| Command | Parameters | Returns | Description |
|---|---|---|---|
amp_version |
none | string | First token of amp version, for example 0.0.1792022479-ge66e24. |
amp_setup_check |
none | object | installed, package, version, api_key_set, settings_path, dangerously_allow_all, updates_mode. |
amp_execute |
prompt string, required. stream_json boolean, optional, default false. |
string | Stdout of amp -x. --stream-json when stream_json is true. |
amp |
same as amp_execute |
string | Previous command name. |
POST /commands/amp_execute with {"prompt":"hi"} returns {"result":"<stdout>"} when the CLI exits 0. A missing prompt is HTTP 400. A missing AMP_API_KEY, a missing binary, or a non-zero amp exit is HTTP 500 {"error","type"}. api_key_set is a boolean. The secret is not returned. RuntimeError text has the key redacted when it was set.
amp_setup_check writes this JSON (merging into an existing object):
{
"amp.dangerouslyAllowAll": true,
"amp.updates.mode": "disabled",
"amp.notifications.enabled": false
}
The path is AMP_SETTINGS_FILE, or $WORKSPACE/.e2e_amp/settings.json when WORKSPACE is set, or /home/user/.config/amp/settings.json when HOME is /home/user. The image sets AMP_SETTINGS_FILE=/home/user/.config/amp/settings.json.
Configuration
| Name | Required | Default | Purpose |
|---|---|---|---|
AMP_API_KEY |
for amp_execute |
empty | Amp access token. Not a DashScope or OpenAI key. Declared empty in template.yaml. |
AMP_URL |
no | https://ampcode.com/ |
Amp service URL. The CLI's own default. Not set by the image. |
AMP_SETTINGS_FILE |
no | /home/user/.config/amp/settings.json in the image |
Settings file amp_setup_check writes. |
AMP_LOG_FILE |
no | /home/user/.cache/amp/logs/cli.log in the image |
CLI log path. |
ABX_SERVER_TOKEN |
no | empty | When set inside the sandbox, clients send Authorization: Bearer. |
ABX_SERVER_PORT |
no | 9000 |
Port for a local python3 commands.py. |
Set secrets on abx create --env or Sandbox.create(envs=...). Do not write them into the image or the log.
Outside the image, set AMP_SETTINGS_FILE or WORKSPACE before starting commands.py. Otherwise a process whose HOME is not /home/user writes .e2e_amp/settings.json in the current directory.
Resources
| Resource | Value |
|---|---|
| cpu | 2 vCPU |
| memory | 2048 MB |
| port | 9000 |
| disk | platform rootfs, about 10G on Express |
A live agent turn with tools was not measured. The keyless commands (amp_version, amp_setup_check) fit this size. The amp binary is about 130 MB.
Verified
| Provider | Date (UTC) | Template version | SDK | What passed |
|---|---|---|---|---|
| alicloud-express | 2026-10-15 | 1.1.0 | 0.3.0 | L2. python3 scripts/express_e2e.py amp deployed generation 2, reached READY, and ran amp_version and amp_setup_check through abx run and Sandbox.run. |
L1: docker build of this Dockerfile printed 0.0.1792022479-ge66e24 from amp version and installed agent-sandbox-server from python-sdk commit 61c43e0be65a1f57aa09186d578e7b399e48429b.
L0: e2e_test.py passed with amp on PATH (version and settings) and without it (the not-found error). python3 scripts/run_local_e2e.py passed this directory.
L3 was not run. This environment has no AMP_API_KEY. A DashScope or OpenAI-compatible key was not sent to Amp.
Secondary development
The version pin is @ampcode/cli@0.0.1792022479-ge66e24 in the Dockerfile (AMP_CLI_VERSION) and the amp_version smoke expect in template.yaml. After npm view @ampcode/cli version, update both, plus PINNED_VERSION in e2e_test.py, and re-run amp version so the smoke string is the first token of that output.
amp_execute builds an argv list. Do not interpolate the prompt into a shell string. Keep the AMP_API_KEY check in front of subprocess so a missing key cannot block on device login.
To add a command, register another @command function that calls amp with an argv list. start() stays under if __name__ == "__main__".
Contributing
CONTRIBUTING.md and docs/template-spec.md. Design notes are in docs/design/amp.md.
Issues
| Topic | Repository |
|---|---|
| This template, the spec, the checker | awesome-templates |
Python SDK or agent-sandbox-server |
python-sdk, title prefix [templates] |
abx CLI |
agent-sandbox, title prefix [templates] |
License
Apache-2.0, the same license as this repository. See LICENSE.