Skip to content

Repository files navigation

Agentic AI Chatbot for public websites

Overview

Public-facing Agentic AI chatbot sample. The solution includes working citations, a dual-agent setup (primary + fallback), a floating widget frontend, a FastAPI backend, and production deployment assets.

The backend uses the Foundry Responses API pattern with agent_reference (name/version).

Current Status

  • Public documents are indexed in Azure AI Search or use Azure Web IQ
  • Citations resolve to real document URLs.
  • Dual-agent behavior is implemented (primary + optional fallback).
  • URL mapping from document IDs to public URLs is implemented.
  • Docker and Terraform deployment assets are available.

Completed Features

  1. Fixed HTML links across local pages.
  2. FastAPI backend with chat and search endpoints.
  3. Azure AI Search integration.
  4. Dual-agent routing behavior.
  5. Working citations (no doc_0 placeholders in final links).
  6. URL mapping utility for citations.
  7. Floating, responsive chat widget.
  8. Chat mode and search mode.
  9. Conversation continuity using previous_response_id mapped to browser thread IDs.
  10. Native search integration from page search forms to widget search.
  11. Enhanced citation cards in the widget.
  12. Resizable widget UI.
  13. Request logging for diagnostics.
  14. Docker + Terraform deployment assets.

Project Structure

va-chat/
├── backend/
│   ├── main.py                      # FastAPI + Foundry Responses API + dual-agent routing
│   └── foundry-agent/               # Agent configuration files
├── frontend/
│   ├── va-chat-widget.css
│   ├── va-chat-widget.js
│   ├── va-chat-injector.js
│   └── simple-integration.html
├── utilities/
│   ├── mapping.csv                  # Document ID to URL mappings
│   └── map_sourceurl2_foundryIQ_kstore.py
├── sample-site/
│   ├── *.html
│   ├── va-chat-widget.css
│   ├── va-chat-widget.js
│   ├── va-search-integration.js
│   └── test-chat-widget.html
├── scripts/
│   ├── fix-links.py
│   ├── serve-samplesite.py          # Dev static server for sample-site/
│   ├── build-and-push.ps1
│   ├── build-and-push.sh
│   └── inject-widget.ps1
├── terraform/
│   ├── main.tf
│   ├── variables.tf
│   └── outputs.tf
├── experiments/
├── .env
├── requirements.txt
└── Dockerfile

Getting Started

Prerequisites

  • Python 3.11+
  • Azure CLI authenticated (az login)
  • Azure Foundry project and agent configured

Installation

  1. Activate virtual environment.
.\.venv\Scripts\Activate.ps1
  1. Install dependencies.
pip install -r requirements.txt
  1. Configure environment variables (.env).
AZURE_FOUNDRY_PROJECT_ENDPOINT=your-endpoint
AZURE_FOUNDRY_AGENT_NAME=your-primary-agent-name
AZURE_FOUNDRY_AGENT_VERSION=optional-version-or-latest

# Optional fallback agent
AZURE_FOUNDRY_FALLBACK_AGENT_NAME=your-fallback-agent-name
AZURE_FOUNDRY_FALLBACK_AGENT_VERSION=optional-version-or-latest

# Model deployment name (preferred)
FOUNDRY_MODEL=gpt-5.4-mini-1

# Optional backward-compatible alias
AZURE_FOUNDRY_DEPLOYMENT_NAME=gpt-5.4-mini-1

# Optional OpenAI API version passed when supported
OPENAI_API_VERSION=2024-10-21

PORT=8080
LOG_LEVEL=INFO
UVICORN_RELOAD=false

Notes:

  • AZURE_FOUNDRY_PROJECT_ENDPOINT is required.
  • AZURE_FOUNDRY_AGENT_NAME is required.
  • AZURE_FOUNDRY_AGENT_VERSION is optional; latest is used when omitted.
  • Fallback agent settings are optional.
  • Auth is handled by DefaultAzureCredential.

Running the Application

Use two terminals.

Terminal 1: Backend

C:/code/va-chat/.venv/Scripts/python.exe backend/main.py
C:/code/va-chat/.venv/Scripts/python.exe backend/main.py

Terminal 2: Frontend Sample Site

C:/code/va-chat/.venv/Scripts/python.exe scripts/serve-samplesite.py

Testing

  1. Open a page:
  1. Click the chat button in the bottom-right corner.

  2. Try test prompts:

  • What services do you provide?
  • How do I apply for a job?
  • Tell me about public education programs.
  1. Test both modes:
  • Chat mode: conversational answers + citations
  • Search mode: structured search-style results

API Endpoints

POST /api/chat

Request:

{
  "message": "What services are available?",
  "thread_id": "optional-thread-id",
  "mode": "chat"
}

Response:

{
  "message": "The organization provides...",
  "thread_id": "2f7f0dfd-9f12-44d1-9a80-98f7ac4e4f56",
  "mode": "chat",
  "citations": [
    {
      "title": "Our Services",
      "url": "https://example.gov",
      "snippet": "..."
    }
  ]
}

POST /api/search

Alias for /api/chat with mode: "search".

GET /api/health

Health endpoint.

Integration Guide

To add the widget to a page:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="frontend/va-chat-widget.css">
</head>
<body>
  <!-- page content -->
  <script src="frontend/va-chat-widget.js"></script>
  <!-- optional, if page has search forms -->
  <script src="sample-site/va-search-integration.js"></script>
</body>
</html>

Architecture

System Diagram

flowchart TB
  subgraph browser[Browser Client]
    page[Rendered Website]
    widget[Chat Widget]
    search[Search Integration]
    page --> widget
    search --> widget
  end

  subgraph edge[Azure Edge]
    frontdoor[Azure Front Door]
  end

  subgraph web[Website Hosting]
    staticweb[Static Web App]
    siteassets[Public Website HTML, JS, CSS]
    staticweb --> siteassets
  end

  subgraph app[Azure Application]
    containerapp[Container App]
    fastapi[FastAPI Backend]
    identity[Managed Identity]
    logs[Log Analytics]
    containerapp --> fastapi
    identity --> fastapi
    containerapp --> logs
  end

  subgraph ai[Azure AI Services]
    foundry[Foundry Responses API]
    agent[Agent]
    bing[Grounding with Bing Tool]
    fallback[Optional Fallback Agent]
    foundryiq[Azure Foundry IQ Knowledge Source]
    foundry --> agent
    agent --> bing
    foundry -.->|optional fallback| fallback
    fallback --> foundryiq
  end

  subgraph deployment[Deployment Pipeline]
    docker[Docker Build]
    acr[Container Registry]
    terraform[Terraform IaC]
    docker --> acr
    acr --> containerapp
    terraform --> containerapp
    terraform --> identity
  end

  page -->|requests site| frontdoor
  frontdoor -->|/*| staticweb
  siteassets -->|rendered in browser| page
  widget -->|/api/*| frontdoor
  frontdoor -->|/api/*| containerapp
  fastapi --> foundry

  classDef browserNode fill:#E8F1FB,stroke:#2F6B9A,color:#12344D,stroke-width:1.5px;
  classDef edgeNode fill:#D9F3F0,stroke:#1E7F78,color:#0F403B,stroke-width:1.5px;
  classDef webNode fill:#E7F6E8,stroke:#4E8B57,color:#1F4628,stroke-width:1.5px;
  classDef appNode fill:#FFF0D9,stroke:#B7791F,color:#5F370E,stroke-width:1.5px;
  classDef aiNode fill:#FBE7E7,stroke:#B85C5C,color:#5C2424,stroke-width:1.5px;
  classDef deployNode fill:#ECECEC,stroke:#6B7280,color:#1F2937,stroke-width:1.5px;

  class page,widget,search browserNode;
  class frontdoor edgeNode;
  class staticweb,siteassets webNode;
  class containerapp,fastapi,identity,logs appNode;
  class foundry,agent,bing,fallback,foundryiq aiNode;
  class docker,acr,terraform deployNode;

  style browser fill:#F7FBFF,stroke:#2F6B9A,stroke-width:2px,color:#12344D;
  style edge fill:#EEFBF9,stroke:#1E7F78,stroke-width:2px,color:#0F403B;
  style web fill:#F4FBF4,stroke:#4E8B57,stroke-width:2px,color:#1F4628;
  style app fill:#FFF8ED,stroke:#B7791F,stroke-width:2px,color:#5F370E;
  style ai fill:#FFF4F4,stroke:#B85C5C,stroke-width:2px,color:#5C2424;
  style deployment fill:#F7F7F7,stroke:#6B7280,stroke-width:2px,color:#1F2937;
Loading

Production hosting for the mini-site stack is Browser -> Azure Front Door -> Static Web App for site assets and Browser -> Azure Front Door -> Container App for /api/*. The browser renders the site, but Static Web App hosts the public website assets. Local development still uses direct localhost access.

Authentication Flow

sequenceDiagram
    participant Browser
    participant FrontDoor as Azure Front Door
    participant FastAPI
    participant Identity as Managed Identity
    participant EntraID as Microsoft Entra ID
    participant Foundry as Foundry Responses API

    Browser->>FrontDoor: POST /api/chat
    FrontDoor->>FastAPI: Route /api/* to Container App backend
    FastAPI->>Identity: Request credentials
    Identity->>EntraID: Authenticate
    EntraID-->>Identity: Access token
    Identity-->>FastAPI: Credentials
    FastAPI->>Foundry: responses.create(model, input, agent_reference)
    Foundry->>Foundry: Continue with previous_response_id when available
    Foundry-->>FastAPI: Response + citations
    FastAPI-->>FrontDoor: JSON response
    FrontDoor-->>Browser: JSON response
Loading

Data Flow

Chat Mode

  1. User sends message from widget.
  2. Widget calls /api/chat.
  3. Backend maps thread ID to prior response_id.
  4. Backend calls primary named agent reference.
  5. Response and citations are returned to widget.

Search Mode

  1. User submits search query.
  2. Widget calls /api/search.
  3. Backend adds search-oriented instruction text.
  4. Backend runs primary and optional fallback flows.
  5. Results are merged and rendered as search results.

Features in Detail

Chat Widget

  • Floating/minimizable bubble
  • Expand/collapse transitions
  • Responsive design for desktop/mobile
  • Accessibility-oriented markup
  • Thread persistence in browser state

Native Search Integration

  • Intercepts form.search submissions
  • Opens widget directly in search mode
  • Avoids page reloads for results
  • Provides search functionality where native search is unavailable

Deployment

The repo includes Terraform for Azure Container Apps deployment.

Quick Deploy

  1. Configure Terraform.
cd terraform
Copy-Item terraform.tfvars.example terraform.tfvars
notepad terraform.tfvars
  1. Build and push image.
cd ..
.\scripts\build-and-push.ps1
  1. Deploy infra.
cd terraform
terraform init
terraform apply

See DEPLOYMENT.md for full deployment steps.

Troubleshooting

Backend won’t start

  • Verify Azure auth: az account show
  • Verify .env endpoint, agent name, and model
  • Verify port 8080 is free

Widget doesn’t appear

  • Check browser console
  • Confirm backend is running on 8080
  • Confirm frontend is running on 9000

Chat returns errors

  • Check backend logs
  • Verify agent name/version values in .env
  • Test SDK access with utilities/foundry2_agent_test.py

Links not working

  • Run python scripts/fix-links.py
  • Ensure sample pages are under sample-site/

Scripts

scripts/fix-links.py

Updates local HTML links.

python scripts/fix-links.py

scripts/serve-samplesite.py

Serves sample-site/ on port 9000.

python scripts/serve-samplesite.py

Development Tips

  1. Reload is off by default in backend/main.py; set UVICORN_RELOAD=true for live reload.
  2. Keep backend and frontend terminals separate.
  3. Use venv python explicitly on Windows if shell activation behaves inconsistently.
  4. Use FastAPI docs at http://localhost:8080/docs.

Support

  • Agent test utility: utilities/foundry2_agent_test.py
  • Backend logs: terminal output from backend process

Status: Phase 1A Complete + Azure AI Search Integration Last Updated: June 8, 2026 Version: 1.3.0

About

AI-powered chatbot with floating widget, FastAPI backend, Azure AI Foundry agent integration grounded with Azure AI search and Bing custom grounding

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages