ADK Web Compatibility Layer

Copy Markdown View Source

This guide explains how to use ADK Elixir as a drop-in backend replacement for the adk-web React frontend.

Overview

The ADK.Phoenix.WebRouter module provides HTTP endpoints that match the Python ADK's adk web FastAPI server exactly, enabling the adk-web frontend to work with an Elixir backend without modification.

Quick Start

1. Add Dependencies

Ensure your mix.exs includes:

{:adk, path: "../adk-elixir"},  # or from hex
{:plug, "~> 1.14"},
{:jason, "~> 1.4"},
{:bandit, "~> 1.0"},  # or {:plug_cowboy, "~> 2.5"}

2. Define Your Agents

Create an agent loader — either a map or a module:

# Simple map-based loader
agents = %{
  "my_agent" => ADK.Agent.LlmAgent.new(
    name: "assistant",
    model: "gemini-flash-latest",
    instruction: "You are a helpful assistant."
  )
}

# Or a module-based loader
defmodule MyApp.AgentLoader do
  def list_agents, do: ["my_agent"]

  def list_agents_detailed do
    [%{
      name: "my_agent",
      root_agent_name: "assistant",
      description: "A helpful assistant",
      language: "elixir",
      is_computer_use: false
    }]
  end

  def load_agent("my_agent") do
    ADK.Agent.LlmAgent.new(
      name: "assistant",
      model: "gemini-flash-latest",
      instruction: "You are a helpful assistant."
    )
  end

  def load_agent(_), do: nil
end

3. Start the Server

# Standalone with Bandit
opts = [
  agent_loader: agents,  # or MyApp.AgentLoader
  session_store: {ADK.Session.Store.InMemory, []}
]

Bandit.start_link(
  plug: {ADK.Phoenix.WebRouter, opts},
  port: 8000
)

Or in a Phoenix router:

# In your router.ex
forward "/api", ADK.Phoenix.WebRouter,
  agent_loader: MyApp.AgentLoader,
  session_store: {ADK.Session.Store.InMemory, []}

4. Connect adk-web Frontend

Point the adk-web frontend at your Elixir server:

# Clone adk-web
git clone https://github.com/google/adk-web
cd adk-web

# Set the backend URL
echo "VITE_API_URL=http://localhost:8000" > .env.local

# Start the frontend
npm install && npm run dev

Endpoints

MethodPathDescription
GET/healthHealth check
GET/versionVersion info
GET/list-appsList available agents
GET/apps/:app/users/:user/sessionsList sessions
POST/apps/:app/users/:user/sessionsCreate session
GET/apps/:app/users/:user/sessions/:idGet session
DELETE/apps/:app/users/:user/sessions/:idDelete session
POST/runRun agent (JSON response)
POST/run_sseRun agent (SSE streaming)

Request/Response Shapes

All shapes match the Python ADK exactly. See the test file at test/adk/phoenix/web_router_test.exs for examples.

POST /run_sse

Request body:

{
  "app_name": "my_agent",
  "user_id": "user123",
  "session_id": "sess456",
  "new_message": {
    "parts": [{"text": "Hello!"}]
  },
  "streaming": false
}

Response: SSE stream with data: {event_json}\n\n lines.

POST /apps/:app/users/:user/sessions

Request body:

{
  "session_id": "optional-custom-id",
  "state": {"key": "value"}
}

CORS

CORS headers (Access-Control-Allow-Origin: *) are included on all responses by default. The OPTIONS preflight is handled automatically.

Session Persistence

By default, sessions use ADK.Session.Store.InMemory (ETS-backed). For production, use ADK.Session.Store.Ecto with a database backend.