Use the DIAL-to-DIAL adapter for local development
In this tutorial, you will run DIAL locally and reach the models and applications configured in a remote DIAL Core, using your remote API key. The DIAL-to-DIAL adapter forwards requests from your local DIAL Core to the remote one, so you can develop against real models without deploying or paying for provider adapters locally. By the end, you will chat with remote models through local DIAL Chat at http://localhost:3000.
Prerequisites
- Docker Engine with Docker Compose v2.20.0 or higher. See the Docker documentation.
- Python 3 installed — the config generator runs a short Python script.
- The URL of a remote DIAL Core that already has models configured, for example
https://core.your-company.com. - An API key for that remote DIAL Core.
- Free TCP ports
3000(DIAL Chat) and8080(DIAL Core) on your machine.
What you'll build
A local DIAL stack — DIAL Core, DIAL Chat, Redis, themes, and the DIAL-to-DIAL adapter — where the models you see in Chat are served by a remote DIAL Core. Selecting a model routes the request from local Chat, through your local DIAL Core, to the adapter-dial container, which forwards it to the remote Core authenticated with your remote API key.
Project structure
This setup lives in the epam/ai-dial-adapter-dial repository, under docker-compose/local:
ai-dial-adapter-dial/
└── docker-compose/
├── generate-config/
│ ├── app.py
│ └── requirements.txt
└── local/
├── docker-compose.yml
├── generate_config_from_listing.sh
├── generate_config_from_template.sh
├── config_template.json
└── settings/
├── gflog.xml
└── settings.json
generate_config_from_listing.sh queries the remote Core's model and application listing and writes a local core/config.json for you. The docker-compose.yml includes the adapter-dial service alongside the standard DIAL components.
Step 1: Get the adapter repository
Clone the adapter repository and change into the local setup directory:
git clone https://github.com/epam/ai-dial-adapter-dial.git
cd ai-dial-adapter-dial/docker-compose/local
Verify: the directory contains docker-compose.yml and generate_config_from_listing.sh.
Step 2: Set the remote DIAL Core credentials
Create a .env file in the local directory with the remote Core URL and your API key:
REMOTE_DIAL_URL="https://<YOUR_REMOTE_DIAL_HOST>"
REMOTE_DIAL_API_KEY="<YOUR_REMOTE_DIAL_API_KEY>"
Verify: the .env file exists and both variables are set.
The .env file and the generated config.json contain a live API key. Do not commit them to version control.
Step 3: Generate the local configuration
Run the generator. It reads the remote Core's available deployments and writes them to core/config.json:
./generate_config_from_listing.sh
The script bootstraps a Python virtual environment and calls the remote Core's listing endpoints. Each remote model and application becomes a local deployment whose upstreams entry points back at the remote Core through the adapter.
Verify: a core/config.json file now exists in the local directory and lists the remote deployments.
If you cannot run the Python generator, use the static template instead: ./generate_config_from_template.sh. It produces a minimal core/config.json with a single gpt-4 model from config_template.json, substituting your REMOTE_DIAL_URL and REMOTE_DIAL_API_KEY.
Step 4: Launch DIAL
Start the stack. If you are not running as root, pass your user ID so DIAL Core can write its data and log directories:
UID=$(id -u) docker compose up --abort-on-container-exit
The compose file references the moving epam/ai-dial-adapter-dial:development image tag. To pin a released version, set the adapter image to epam/ai-dial-adapter-dial:0.14.0 in docker-compose.yml before starting.
Verify: the core, chat, and adapter-dial services start with no errors.
Step 5: Chat with a remote model
- Open
http://localhost:3000in your browser. - Open the Catalog and select one of the listed deployments. Models discovered from the remote Core carry an
(Adapter)suffix in their display name. - Send a prompt.
Verify: the model responds. The request was served by the remote DIAL Core, proxied through your local stack.
How it fits together
Each generated deployment points its endpoint at the local adapter and its upstreams at the remote Core:
"gpt-4-adapter": {
"type": "chat",
"displayName": "GPT-4 (Adapter)",
"endpoint": "http://adapter-dial:5000/openai/deployments/gpt-4/chat/completions",
"forwardAuthToken": true,
"upstreams": [
{
"endpoint": "https://<YOUR_REMOTE_DIAL_HOST>/openai/deployments/gpt-4/chat/completions",
"key": "<YOUR_REMOTE_DIAL_API_KEY>"
}
]
}
The local deployment ID intentionally differs from the remote one — the -adapter suffix shows that local and remote IDs need not match. Because the adapter speaks the Unified API on both sides, your local applications call remote models exactly as they would call a local one.
What you learned
- How the DIAL-to-DIAL adapter lets a local DIAL Core use models hosted on a remote Core
- How to generate a local
config.jsonfrom a remote Core's deployment listing - How
upstreamsandforwardAuthTokenroute a local request to the remote Core
Further reading
- Run DIAL with the echo application — develop a local application against these remote models
- What are adapters — how adapters connect DIAL to any provider
- DIAL Core configuration — the
config.jsonthe generator produces