By default AI generated software is verified in the environment and context that it was built. This frequently leads to agents claiming it worked due to context poisoning, leaving issues unsolved since they are not forced to consider deployment details, or specific setup present on the dev machine. This leaves a gap between "tests pass" and "this actually meets all the requirements and works in a real-world scenario."
Let's take integrating with an app like Teams as an example. We might build something that integrates with it and for our day-to-day use we would have to make an account, an app registration, etc. In a software factory, agents are constantly creating new app registrations, which may exceed rate limits, require manual setup, etc. Having a mocked Teams service in a digital twin universe allows us to development against it without issue. It also allows us to instrument such or add additional testing hooks and so on to help with our development/visibility needs, etc.
Amplifier Digital Twin Universe is made to close that gap: a complete, isolated environment, stood up on demand from a declarative profile, that simulates the world the code will live in, so consumers can clone, install, run, and experience it like a real user. It answers "What reality will be like if this was actually deployed?" in a way that an everyday person can understand and interact without deep technical knowledge or special setup.
Example Uses:
- "I want to try out amplifier-chat as a real user would, with everything provisioned for me, without touching my local setup."
- "I want to develop multiple Amplifier components in parallel without them modifying my system installation."
A DTU is defined by a profile which is a YAML file that declares the
services, networking, and provisioning needed to launch a complete environment.
To share profiles alongside a repo, .amplifier/digital-twin-universe/profiles/ is the convention.
For example, we have a sample profile for validating this repo locally at .amplifier/digital-twin-universe/profiles/dtu-host-in-incus.yaml
which launches a DTU containing the full DTU host stack (Incus, Docker, Amplifier CLI, and the DTU + Gitea bundles) so the bundle itself can be exercised in isolation.
See docs/profiles.md for the full profile reference and profiles/ for examples.
Profiles can include mock services as Docker sidecars with transparent DNS rewriting. See docs/mock-authoring.md for how to build a mock and a list of community mocks.
The amplifier-user-sim profile simulates an Amplifier user environment: LLM API passthrough, repos served from Gitea, the Amplifier CLI installed, and the Anthropic provider pre-configured so Amplifier is ready to use immediately. See the launch flow diagram for details.
The amplifier-chat profile launches a browser-accessible
amplifier-chat UI backed by amplifierd.
It installs the app from upstream, configures the Anthropic provider,
and uses access.ports to forward port 8410 to localhost so you can open
http://localhost:8410/chat/ in your browser immediately after launch.
amplifier-digital-twin launch amplifier-chat
# => {"access": [{"label": "Chat UI", "url": "http://localhost:8410/chat/"}], ...}- Python 3.11+
- uv (package manager and runner)
- Incus (container runtime) -- see docs/installing-incus.md
- Docker Engine (for Gitea repos and mock service sidecars) -- see docs/installing-docker.md
- (Optional)
avahi-daemon+avahi-utilsfor.localhostname support --sudo apt install avahi-daemon avahi-utils
uv tool install git+https://github.com/microsoft/amplifier-bundle-digital-twin-universe@mainThis repo is also an Amplifier bundle. The bundle provides a digital-twin-universe skill and context awareness so the AI model knows how to use the amplifier-digital-twin CLI. The CLI must be installed separately (see above).
If you use amplifier-foundation, this bundle is included automatically (transitively via amplifier-bundle-amplifier-tester). No additional install is needed.
To compose into a custom bundle (without foundation), reference the behavior:
amplifier bundle add "git+https://github.com/microsoft/amplifier-bundle-digital-twin-universe@main#subdirectory=behaviors/digital-twin-universe.yaml" --app--app composes the bundle onto every Amplifier session. Remove it to only register the bundle for later activation with amplifier bundle use.
This bundle doesn't ship a runtime (no provider, orchestrator, or tools) — it must be composed onto a bundle that does, like amplifier-foundation.
# Launch an environment from a profile
amplifier-digital-twin launch amplifier-user-sim
# Execute a command inside it
amplifier-digital-twin exec dtu-a1b2c3d4 -- amplifier --version
# Push files into the environment
# Single file:
amplifier-digital-twin file-push dtu-a1b2c3d4 ./config.yaml /root/config.yaml
# Directory (use -r; source basename is preserved inside dest):
amplifier-digital-twin file-push -r dtu-a1b2c3d4 ./data/ /root/app/
# Pull files out of the environment
amplifier-digital-twin file-pull dtu-a1b2c3d4 /root/output.log ./output.log
amplifier-digital-twin file-pull -r dtu-a1b2c3d4 /root/results/ ./
# Update provisioned software without restarting the environment
amplifier-digital-twin update dtu-a1b2c3d4
# Interactive shell
amplifier-digital-twin exec dtu-a1b2c3d4
# Check environment status
amplifier-digital-twin status dtu-a1b2c3d4
# List all managed environments on this machine
amplifier-digital-twin list
# Tear down a specific environment (use the id from your launch output)
amplifier-digital-twin destroy dtu-a1b2c3d4All commands return JSON to stdout. See docs/api-reference.md for the full API.
-
Profile-driven environments. A single YAML profile declares the services, networking, and provisioning for a complete environment. Profiles are self-contained and launchable on their own.
-
Passthrough for real APIs. External services that are stateless or read-only (LLM APIs, package registries, etc.) are proxied through the environment boundary with forwarded credentials rather than mocked.
-
DNS rewriting. Services within the environment can be addressed by their real-world hostnames. DNS rewriting and URL redirection make mock services feel like the real thing to code running inside.
-
Human access. Profiles can declare
access.portsto forward ports from the container tolocalhoston the host via Incus proxy devices. This works seamlessly on WSL2 (Windows auto-forwards WSL2 localhost ports to the Windows host). Users can open a browser and interact with web apps running inside the environment as if they were local. -
Agent interaction surfaces. Agents can reach into the environment from the outside and drive "as a user" experiences via browser-tester, terminal-tester, and similar mechanisms. Mock services can advertise affordances (coordinates, API hooks) so agents interact through the same surfaces as human users.
-
Ephemeral lifecycle. Environments are created, used, and destroyed on demand. Consumers can wipe and restart for a clean simulation at any time.
-
In-place updates. Profiles can define an
updatesection with commands to pull fresh code and reinstall without destroying the environment. PyPI overrides can be rebuilt automatically. This enables a fastlaunch->update->testiteration loop. -
CLI-first, JSON output. All lifecycle commands (launch, update, status, list, destroy) return JSON to stdout for programmatic consumption.
-
Amplifier agents. The bundle includes agents for working with DTU environments within Amplifier sessions.
dtu-profile-builderexplores a user's project repository, generates a complete DTU profile, launches the environment, and hands back access details.
-
Amplifier skill. The bundle ships a
digital-twin-universeskill for help installing the CLI, understanding profiles, and using environments within Amplifier sessions. -
Mock service sidecars. Profiles can declare
mock_servicesthat are resolved (cloned or local), built into Docker images, and started as sidecar containers alongside the Incus environment. mitmproxy routes traffic for declared domains from inside the environment to the mock, including WebSocket upgrades. See docs/profiles.md for themock_servicesschema and mock manifest format. -
Mock service catalog (TBD). A catalog of pre-built mock images for common external services (M365, Slack, GSuite, etc.) allowing for testing without rate limits, manual app registration overhead, etc.
On macOS hosts running colima with the default macOS Virtualization.framework networking, amplifier-digital-twin list reports access URLs in http://localhost:<PORT>/... form, but those URLs are not reachable from the macOS host.
Cause: the DTU's Incus proxy device binds to 0.0.0.0:<PORT> inside the colima Linux VM. Under Virtualization.framework, localhost on the macOS host is not bridged into the VM's listening sockets.
Workaround: substitute the colima VM's IP for localhost. On a default colima install:
http://192.168.64.2:<PORT>/api/health # instead of http://localhost:<PORT>/api/health
Find the VM IP via colima status (look for the address line) or colima ls -j (the address field). For non-default colima profiles, substitute that profile's VM address.
Proper fix: the engine should detect the colima/Linux-VM topology when the calling host is non-Linux and emit VM-routable URLs in the access output of amplifier-digital-twin list. Tracking this here for now since the repo does not have issues enabled.
For development setup and test workflows, see docs/development.md.
For a full manual walkthrough of spinning up Gitea, mirroring repos, launching an environment, and using Amplifier inside it, see docs/manual_verification.md.
Note
This project is not currently accepting external contributions, but we're actively working toward opening this up. We value community input and look forward to collaborating in the future. For now, feel free to fork and experiment!
Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit Contributor License Agreements.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.