SDKs
AI
CopilotKit
Getting Started
Run the Demo

Run the Demo

The demo is a self-contained chat app that shows Adzen delivering contextual ads inside an AI assistant conversation. By default it uses mock agent responses and a mock Adzen API. Optionally, set environment variables to connect to a real LLM and/or the real Adzen ad API.

The demo lives inside the @adzenai/ai package at packages/ai/src/copilotkit/demo/.

What The Demo Shows

  • A chat UI where you type any message and receive a streamed response
  • AdzenAsyncMiddleware processing the AG-UI event stream in real time
  • An AdzenCard rendering a contextual ad in the chin (between the chat area and the input)
  • Client-side impression beacons (GET requests) fired directly to the delivery API
  • Viewability tracking firing view beacons after the ad is visible (logged to the console)
  • The full data flow: agent → middleware → event bridge → React

Prerequisites

  • Node.js >=18
  • pnpm >=9

Install Dependencies

From the workspace root:

pnpm install

This installs all workspace packages including @adzenai/ai and @adzenai/core.

Configure Environment

The demo supports three modes controlled by two optional environment variables. Create a .env file in packages/ai/src/copilotkit/demo/ (copy from .env.example):

cp packages/ai/src/copilotkit/demo/.env.example packages/ai/src/copilotkit/demo/.env
OPENAI_KEYADZEN_KEYAgentAd API
unsetunsetMock canned responsesMock sample ads
setunsetgpt-4.1-mini streamingMock sample ads
unsetsetMock canned responsesReal Adzen API
setsetgpt-4.1-mini streamingReal Adzen API

Mock mode (default)

No .env file needed. The demo uses canned multi-chunk text responses and rotates through fictional sample ads with mock impression URLs. No network calls are made.

Real LLM mode

Set OPENAI_KEY in your .env:

OPENAI_KEY=sk-...

The demo streams responses from OpenAI's gpt-4.1-mini model. Requests are proxied through the Vite dev server to avoid CORS.

Real ad API mode

Set ADZEN_KEY in your .env:

ADZEN_KEY=your_adzen_key

The demo calls the real Adzen API at https://api.adzen.ai/v1/ai/process. The middleware consumes the API response directly (no transformation needed). Requests are proxied through the Vite dev server.

Both

Set both variables to use a real LLM for agent responses and the real Adzen API for ad matching.

Run The Demo

From the packages/ai directory:

pnpm demo

Open http://localhost:5188/ (opens in a new tab) in your browser. The header bar shows which mode is active (e.g., "Agent: gpt-4.1-mini · Ads: live API" or "Agent: mock · Ads: mock").

How It Works

The demo wires four components together:

ComponentFileRole
Agentdemo/mockAgent.ts or demo/openaiAgent.tsProduces AG-UI event streams (mock canned chunks or real OpenAI SSE)
Ad APIdemo/mockAdApi.ts or demo/liveAdApi.tsMock fetch interceptor returning ProcessResponse shape, or passthrough to real API
Middleware../middleware.tsAdzenAsyncMiddleware — buffers text, calls /process, emits adzen_placement events
Chat UIdemo/App.tsxRenders messages, bridges events to the browser, displays AdzenCard in the chin

Data Flow

User types prompt
  → agentStream() yields AG-UI events (mock or OpenAI)
    → AdzenAsyncMiddleware.processEvent() buffers text, fetches ad
      → dispatchPlacementEvents() bridges to browser CustomEvents
        → useAdzenPlacement() picks up placement
          → AdzenCard renders ad in the chin
            → GET render_impression_url (on mount)
            → observeViewability() → GET view_impression_url (after 1s visible)

Test Manually

Mock mode

  1. Type any message.
  2. Watch the canned response stream in chunks.
  3. After the message completes, an ad appears in the chin below the chat.
  4. Open the browser console to see impression beacon logs:
[adzen-demo] Impression beacon fired: render 1001
[adzen-demo] Impression beacon fired: view 1001

Each message shows a different sample ad (the mock API rotates through three fictitious creatives).

Real LLM + real ad API mode

  1. Set both OPENAI_KEY and ADZEN_KEY in .env and restart the demo.
  2. Type a natural prompt (e.g., "What's a good recipe for pizza dough?").
  3. The assistant response streams from gpt-4.1-mini.
  4. After the response completes, a contextual ad from the Adzen API appears in the chin.
  5. The ad is matched to the assistant's response content.
  6. Check the Network tab — impression beacons are GET requests to delivery.adzen.ai.

Build Verification

To verify the package builds cleanly:

pnpm run build --filter=@adzenai/ai
pnpm run typecheck --filter=@adzenai/ai

Next Steps