Skip to content

A starter template for building AI-powered agents with the GitHub Copilot SDK deployed to Azure Container Apps.

License

Notifications You must be signed in to change notification settings

jongio/copilot-sdk-agent

Copilot SDK Agent

A starter template for building AI-powered agents with the GitHub Copilot SDK deployed to Azure Container Apps.

Overview

Copilot SDK Agent is a full-stack TypeScript application that demonstrates how to build a conversational AI agent using the GitHub Copilot SDK. It pairs an Express API backend with a React frontend to deliver a chat interface that streams responses from a Copilot-powered agent with custom tool support.

  • Backend (src/api/) — Express server that creates a Copilot SDK session, registers custom tools, and streams responses over Server-Sent Events (SSE).
  • Frontend (src/web/) — React + Vite single-page app with a chat window, message input, and dark/light mode support.

Features

  • Streaming SSE chat — Real-time token-by-token responses via the Copilot SDK
  • Custom tool support — Extensible tool system using defineTool() (see src/api/tools/)
  • React frontend — Modern chat UI with dark/light mode and responsive design
  • One-command local dev — Run all services with azd app run via azd app
  • One-command Azure deployment — Deploy to Azure Container Apps with azd up
  • Foundry AI agent — Optional Foundry-hosted agent via the azd ai agent extension with BYOM (Bring Your Own Model) support
  • Docker-based containerization — Multi-stage Dockerfile for optimized production builds
  • Automatic GitHub token provisioning — Preprovision hook retrieves your token via gh CLI

Prerequisites

Tool Version Purpose
pnpm 10+ Fast, disk-efficient package manager
Node.js 24+ Runtime for the API and build tooling
GitHub CLI (gh) Latest Provides the GITHUB_TOKEN for the Copilot SDK
Azure Developer CLI (azd) Latest Provisions and deploys Azure resources
Docker Latest (Optional) Local container testing

GitHub CLI setup:

gh auth login
gh auth refresh --scopes copilot

Quick Start

2. Install the azd app extension

azd config set alpha.extensions on
azd extension source add -n jongio -t url -l https://jongio.github.io/azd-extensions/registry.json
azd extension install jongio.azd.app

3. Init and run

azd init -t jongio/copilot-sdk-agent
azd app run

The prerun hook automatically retrieves your GITHUB_TOKEN from the gh CLI via scripts/get-github-token.mjs (the same script also runs as a preprovision hook during azd up). azd app installs dependencies, starts both services, and provides a real-time dashboard. Open the URL shown in the dashboard output to start chatting.

4. Use with GitHub Codespaces

This repo includes a devcontainer configuration for one-click setup:

Open in GitHub Codespaces

The devcontainer automatically installs Node.js 24, pnpm, Azure Developer CLI (azd), Azure CLI, GitHub CLI, Docker, and all recommended VS Code extensions. After opening, authenticate the GitHub CLI with the copilot scope, then run:

gh auth login
gh auth refresh --scopes copilot
azd app run
Run services manually (without azd app)
# Set your GitHub token
export GITHUB_TOKEN=$(gh auth token)

# Install dependencies
cd src/api && pnpm install && cd ../web && pnpm install && cd ../..

# Start the API server (in one terminal)
cd src/api && pnpm dev

# Start the web dev server (in another terminal)
cd src/web && pnpm dev

Project Structure

copilot-sdk-agent/
├── src/
│   ├── agent/                   # Foundry hosted agent
│   │   ├── agent.yaml           # Agent definition (model, instructions, tools)
│   │   ├── app.py               # Agent entry point
│   │   ├── Dockerfile           # Agent container (Python 3.12)
│   │   └── requirements.txt     # Python dependencies
│   ├── api/                    # Express backend
│   │   ├── index.ts            # App entry point — Express setup, CORS, SPA fallback
│   │   ├── routes/
│   │   │   ├── chat.ts         # POST /chat — Copilot SDK session & SSE streaming
│   │   │   └── health.ts       # GET /health — Health check endpoint
│   │   ├── tools/
│   │   │   └── greet.ts        # Example custom tool using defineTool()
│   │   ├── Dockerfile          # API container (Node.js + pnpm)
│   │   ├── package.json        # API dependencies
│   │   └── tsconfig.json       # TypeScript config (server)
│   └── web/                    # React frontend
│       ├── App.tsx             # Root component
│       ├── App.css             # App styles with dark/light mode
│       ├── main.tsx            # React entry point
│       ├── index.html          # HTML shell
│       ├── index.css           # Global styles & CSS custom properties
│       ├── types.ts            # Shared TypeScript types
│       ├── components/
│       │   ├── ChatWindow.tsx  # Message display with streaming indicator
│       │   ├── MessageInput.tsx# Input field with submit handling
│       │   └── ThemeToggle.tsx # Dark/light mode toggle
│       ├── hooks/
│       │   ├── useChat.ts      # Chat state management & SSE consumption
│       │   └── useTheme.ts     # Theme preference with localStorage
│       ├── Dockerfile          # Web container (Vite build + nginx)
│       ├── package.json        # Web dependencies
│       └── vite.config.ts      # Vite configuration
├── infra/                      # Azure infrastructure (Bicep)
│   ├── main.bicep              # Subscription-scoped deployment
│   ├── main.parameters.json    # Parameter mappings for azd
│   ├── resources.bicep         # All Azure resources (ACR, Container Apps, Key Vault, etc.)
│   └── ...
├── scripts/                    # Automation scripts
│   └── get-github-token.mjs    # Hook: injects GITHUB_TOKEN from gh CLI (runs on prerun and preprovision)
├── azure.yaml                  # Azure Developer CLI service definition
├── LICENSE                     # MIT License
├── CONTRIBUTING.md             # Contribution guidelines
└── README.md

Adding Custom Tools

Tools let the Copilot agent call your own functions. To add a new tool:

1. Create a tool file in src/api/tools/:

// src/api/tools/weather.ts
import { defineTool } from "@github/copilot-sdk";

export const weather = defineTool("weather", {
  description: "Get the current weather for a city",
  parameters: {
    type: "object",
    properties: {
      city: { type: "string", description: "City name" },
    },
    required: ["city"],
  },
  handler: async (args: { city: string }) => {
    // Replace with a real API call
    return { temperature: "72°F", condition: "Sunny", city: args.city };
  },
});

2. Register the tool in src/api/routes/chat.ts:

import { greet } from "../tools/greet.js";
import { weather } from "../tools/weather.js";

// In createSession():
const session = await client.createSession({
  model: "gpt-4o",
  systemMessage: { mode: "append", content: "..." },
  tools: [greet, weather],
});

The agent will automatically discover and use the new tool based on its description and parameter schema.

Foundry AI Agent

This template includes a Foundry-hosted agent (src/agent/) deployed via the azd ai agent extension. When the AZURE_AI_FOUNDRY_PROJECT_ENDPOINT environment variable is set, the API backend automatically uses BYOM (Bring Your Own Model) to route requests through your Foundry-deployed model instead of the default Copilot model.

The Foundry agent is defined in src/agent/agent.yaml and deployed as a CopilotAgent service. Infrastructure provisioning creates an Azure AI Services account and project in infra/resources.bicep.

Deploy to Azure

azd up

This single command handles the entire deployment pipeline:

  1. Preprovision hook — Retrieves your GITHUB_TOKEN from the gh CLI and stores it in the azd environment
  2. Provisions infrastructure — Creates Azure Container Registry, Container Apps Environment, Key Vault, Application Insights, and a managed identity (using Azure Verified Modules)
  3. Builds and pushes — Builds the Docker image and pushes it to the provisioned ACR
  4. Deploys — Deploys the container to Azure Container Apps with the GITHUB_TOKEN securely referenced from Key Vault

To initialize from the template without cloning:

azd init --template jongio/copilot-sdk-agent
azd up

Development

The easiest way to run locally is with azd app, which starts all services, installs dependencies, and provides a real-time dashboard:

azd app run

You can also run services individually:

Command Directory Description
azd app run repo root Start all services with auto-dependency install and dashboard
pnpm dev src/api Start the Express server with hot reload (via tsx --watch)
pnpm dev src/web Start the Vite dev server with HMR for the React frontend
pnpm build src/api Compile the Express server
pnpm build src/web Bundle the React frontend

Architecture

graph LR
    User -->|SSE streaming| ReactUI["React UI<br/>(Vite SPA)"]
    ReactUI -->|SSE streaming| API["Express API<br/>POST /chat"]
    API -->|Tool execution| Tools["Custom Tools<br/>(defineTool)"]
    API --> SDK["Copilot SDK<br/>createSession"]
    SDK --> Copilot["GitHub Copilot<br/>Service"]
Loading

Azure deployment topology:

graph TB
    subgraph Azure Resource Group
        subgraph Container Apps Environment
            Agent["Agent App"]
        end
        ACR["Container Registry<br/>(ACR)"]
        KV["Azure Key Vault<br/>(GITHUB_TOKEN)"]
        MI["Managed Identity"]
        AI["App Insights"]
    end

    Agent -->|pulls images| ACR
    Agent -->|reads secrets| KV
    MI -->|authenticates| Agent
    Agent -->|sends telemetry| AI
Loading

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the MIT License — see the LICENSE file for details.

About

A starter template for building AI-powered agents with the GitHub Copilot SDK deployed to Azure Container Apps.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages