diff --git a/.workshop_instance/.workshop-state.json b/.workshop_instance/.workshop-state.json
index 557d016..3f5e43d 100644
--- a/.workshop_instance/.workshop-state.json
+++ b/.workshop_instance/.workshop-state.json
@@ -1 +1,4 @@
-{"current_step": 0, "schema_version": 1}
+{
+ "current_step": 0,
+ "schema_version": 1
+}
diff --git a/.workshop_instance/workshop_backups/reset-20260818184435/.azdignore b/.workshop_instance/workshop_backups/reset-20260818184435/.azdignore
new file mode 100644
index 0000000..4a74eab
--- /dev/null
+++ b/.workshop_instance/workshop_backups/reset-20260818184435/.azdignore
@@ -0,0 +1,3 @@
+agent.manifest.yaml
+agent.yaml
+.env.example
diff --git a/.workshop_instance/workshop_backups/reset-20260818184435/.dockerignore b/.workshop_instance/workshop_backups/reset-20260818184435/.dockerignore
new file mode 100644
index 0000000..31ed562
--- /dev/null
+++ b/.workshop_instance/workshop_backups/reset-20260818184435/.dockerignore
@@ -0,0 +1,7 @@
+.venv
+__pycache__
+*.pyc
+*.pyo
+*.pyd
+.Python
+.env
diff --git a/.workshop_instance/workshop_backups/reset-20260818184435/.gitkeep b/.workshop_instance/workshop_backups/reset-20260818184435/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/.workshop_instance/workshop_backups/reset-20260818184435/Dockerfile b/.workshop_instance/workshop_backups/reset-20260818184435/Dockerfile
new file mode 100644
index 0000000..d2e7aa5
--- /dev/null
+++ b/.workshop_instance/workshop_backups/reset-20260818184435/Dockerfile
@@ -0,0 +1,12 @@
+FROM python:3.12-slim
+
+WORKDIR /app
+
+COPY . user_agent/
+WORKDIR /app/user_agent
+
+RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; else echo "No requirements.txt found"; fi
+
+EXPOSE 8088
+
+CMD ["python", "main.py"]
diff --git a/.workshop_instance/workshop_backups/reset-20260818184435/STEP_README.md b/.workshop_instance/workshop_backups/reset-20260818184435/STEP_README.md
new file mode 100644
index 0000000..c0e856b
--- /dev/null
+++ b/.workshop_instance/workshop_backups/reset-20260818184435/STEP_README.md
@@ -0,0 +1 @@
+You're now on step 01. The TravelBuddy agent files are present: `agent.yaml` and `agent.manifest.yaml` are ready to use, and you complete one small edit — write TravelBuddy's instructions in `main.py`. The `Dockerfile`, `.dockerignore`, and `.azdignore` that package and deploy the agent are also included (read-only) and explained in the Step 1 doc. The model you deployed in Step 0 is used at runtime via `AZURE_AI_MODEL_DEPLOYMENT_NAME`, so there's no model to provision here. Follow Step 1 in the root `README.md`.
diff --git a/.workshop_instance/workshop_backups/reset-20260818184435/agent.manifest.yaml b/.workshop_instance/workshop_backups/reset-20260818184435/agent.manifest.yaml
new file mode 100644
index 0000000..ee3a9f8
--- /dev/null
+++ b/.workshop_instance/workshop_backups/reset-20260818184435/agent.manifest.yaml
@@ -0,0 +1,42 @@
+# travel_assistant/agent.manifest.yaml — AgentManifest: a parameterized template
+# that deployment tooling (azd ai agent init / Foundry Toolkit) reads to scaffold
+# your hosted agent. It has top-level metadata (name, description, tags), a
+# `template` block (the hosted-agent definition), and a `resources` list.
+# This file is provided ready to use — skim it so you know what it declares.
+# Reference (each field explained):
+# https://learn.microsoft.com/azure/foundry/agents/concepts/agent-yaml-reference
+# NOTE: `name` (and `template.name` below) must be a hardcoded literal here — do
+# NOT use ${VAR} or {{VAR}}. `azd ai agent init` reads and validates the agent
+# name as-is, BEFORE any substitution: it never expands ${VAR} (those resolve later
+# at deploy/run from .env / Bicep outputs) and only substitutes {{VAR}} for values
+# declared under a `parameters:` block, which happens AFTER the name is validated.
+# The validator rejects `$`, `{`, and `}`, so a placeholder here fails with
+# "invalid agent name". The runtime-configurable prefix still lives in agent.yaml's
+# `name` and in the WORKSHOP_RESOURCE_PREFIX environment variable below.
+name: travel-buddy
+description: >
+ A basic Agent Framework travel assistant hosted by Foundry.
+metadata:
+ tags:
+ - Agent Framework
+ - AI Agent Hosting
+ - Azure AI AgentServer
+ - Responses Protocol
+ - Travel Assistant
+template:
+ name: travel-buddy
+ kind: hosted
+ protocols:
+ - protocol: responses
+ version: 2.0.0
+ environment_variables:
+ - name: AZURE_AI_PROJECT_ENDPOINT
+ value: ${AZURE_AI_PROJECT_ENDPOINT}
+ - name: AZURE_AI_MODEL_DEPLOYMENT_NAME
+ value: ${AZURE_AI_MODEL_DEPLOYMENT_NAME}
+ - name: WORKSHOP_RESOURCE_PREFIX
+ value: ${WORKSHOP_RESOURCE_PREFIX}
+# No provisioned resources: you already deployed a model in setup (Step 0), and the
+# agent selects it at runtime through the AZURE_AI_MODEL_DEPLOYMENT_NAME env var
+# above — so we don't declare a `kind: model` resource for azd to create.
+resources: []
diff --git a/.workshop_instance/workshop_backups/reset-20260818184435/agent.yaml b/.workshop_instance/workshop_backups/reset-20260818184435/agent.yaml
new file mode 100644
index 0000000..be6fccd
--- /dev/null
+++ b/.workshop_instance/workshop_backups/reset-20260818184435/agent.yaml
@@ -0,0 +1,25 @@
+# travel_assistant/agent.yaml — AgentDefinition (kind: hosted): the concrete
+# runtime definition for your agent. It names the hosted agent, declares the
+# `responses` protocol, sets a small CPU/memory shape, and lists the environment
+# variables the container needs. This file is ready to run as-is — skim it so you
+# understand each block. Reference:
+# https://learn.microsoft.com/azure/foundry/agents/concepts/agent-yaml-reference
+# yaml-language-server: $schema=https://raw.githubusercontent.com/microsoft/AgentSchema/refs/heads/main/schemas/v1.0/ContainerAgent.yaml
+kind: hosted
+name: ${WORKSHOP_RESOURCE_PREFIX}-travel-buddy
+protocols:
+ - protocol: responses
+ version: 2.0.0
+resources:
+ cpu: "0.25"
+ memory: "0.5Gi"
+environment_variables:
+ # These values come from your .env at run/deploy time — keep the ${...} refs as-is.
+ - name: AZURE_AI_PROJECT_ENDPOINT
+ value: ${AZURE_AI_PROJECT_ENDPOINT}
+ - name: AZURE_AI_MODEL_DEPLOYMENT_NAME
+ value: ${AZURE_AI_MODEL_DEPLOYMENT_NAME}
+ # WORKSHOP_RESOURCE_PREFIX keeps your agent's name unique so it doesn't collide
+ # with other attendees deploying into a shared project.
+ - name: WORKSHOP_RESOURCE_PREFIX
+ value: ${WORKSHOP_RESOURCE_PREFIX}
diff --git a/.workshop_instance/workshop_backups/reset-20260818184435/main.py b/.workshop_instance/workshop_backups/reset-20260818184435/main.py
new file mode 100644
index 0000000..fbd6b85
--- /dev/null
+++ b/.workshop_instance/workshop_backups/reset-20260818184435/main.py
@@ -0,0 +1,38 @@
+# travel_assistant/main.py — Python entry point that hosts TravelBuddy: it creates
+# the Foundry model client, defines the agent, and starts the Responses server.
+# Complete the one TODO inside main() below.
+import os
+
+from agent_framework import Agent
+from agent_framework.foundry import FoundryChatClient
+from agent_framework_foundry_hosting import ResponsesHostServer
+from azure.identity import DefaultAzureCredential
+from dotenv import load_dotenv
+
+load_dotenv(override=True)
+
+
+def main() -> None:
+ # Foundry model client, built from your .env settings.
+ client = FoundryChatClient(
+ project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
+ model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
+ credential=DefaultAzureCredential(),
+ )
+
+ # TODO: write TravelBuddy's system instructions. Describe a friendly travel
+ # assistant that gives practical, concise trip-planning advice — local context,
+ # budget awareness, and safety-minded tips.
+ agent = Agent(
+ client=client,
+ name="travel-buddy",
+ instructions="TODO: write TravelBuddy's system instructions here.",
+ # History is managed by the hosting infrastructure, so don't store it server-side.
+ default_options={"store": False},
+ )
+
+ ResponsesHostServer(agent).run()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/README.md b/README.md
index eb82ae4..e5fb36b 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,33 @@
# Foundry hosted agents with Agent Framework — Travel Assistant Workshop
+Built on the upstream [foundry-samples](https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents/agent-framework/responses).
+
+> **Progress:** Step `00` of `9` — **Setup**
+> ▱▱▱▱▱▱▱▱▱▱
+
-This repository is the **template source** for the workshop. It is not a live Step 00 instance.
+
+Workshop map
+
+- **Step 00 — Setup**
+- Step 01 — Basic hosted agent
+- Step 02 — Function tools
+- Step 03 — MCP integration
+- Step 04 — Foundry Toolbox
+- Step 05 — RAG (Azure AI Search)
+- Step 06 — Skills
+- Step 07 — Multi-agent
+- Step 08 — Workflow (experimental)
+- Step 09 — Memory (experimental)
+- Step 99 — Cleanup
+
+
-After you create your own copy from this template, initialization runs automatically and your copy rewrites `README.md` to the real Step 00 content with progress/status and step navigation.
+If something looks broken see [Troubleshooting](.workshop/docs/steps/00-intro.md#troubleshooting).
+
+
+> **Welcome — start here.** Step 0 has no agent code. It introduces the workshop, walks you through creating your own copy of the repository, and gets your local toolchain ready so Step 1 can jump straight into building the first agent.
## What this workshop is about
@@ -23,14 +46,219 @@ This is a **GitHub template repository**. You must create your own copy before d
> 💡 **Already in your own copy?** If the green button at the top reads "Open" rather than "Use this template", you're already in a workshop instance. Continue below.
+## Open your repo
+
+Pick one of the two paths — the rest of the workshop works the same either way.
+
+### Option A — GitHub Codespaces (recommended)
+
+In your new repo, click **Code → Codespaces → Create codespace on `main`**. The first build takes ~2 minutes; after that the included devcontainer has everything pre-installed:
+
+- Python 3.12, `az` CLI (with Bicep), `azd` CLI, `uv`, `git`, `gh`, Node.js, GitHub Copilot CLI (`copilot`)
+- VS Code extensions: **Python**, **Pylance**, **Python Debugger**, **Foundry Toolkit**, **Bicep**, **Azure MCP Server (Azure Skills)**, **YAML**, **GitHub Pull Requests**
+- The **Azure Skills** plugin for the GitHub Copilot CLI is installed (its Azure MCP + Foundry MCP tools require `az login` at use time)
+- The post-create step has already created `.venv/` and installed workshop dependencies from `travel_assistant/requirements.txt` (or `.workshop/step_files/00/requirements.txt`) plus `.workshop/scripts/requirements.txt`
+
+> ⚠️ **Wait for "Initialize workshop" to finish first.** If you create the Codespace before that Action has applied step 0, the container falls back to `.workshop/step_files/00/requirements.txt` for workshop deps. After the Action turns green, rebuild the Codespace (Command Palette → **Codespaces: Rebuild Container**) so it picks up `travel_assistant/requirements.txt`.
+
+If you go this route, **skip the "Install the tools you'll need" section** below and jump straight to **"Set up your local environment (one-time)"**.
+👉 Direct link: [Set up your local environment (one-time)](#set-up-your-local-environment-one-time)
+
+### Option B — Clone locally
+
+```bash
+git clone https://github.com//.git
+cd
+```
+
+Then continue with **"Install the tools you'll need"** below to install Python, `az`, `azd`, and (optionally) `uv` on your machine.
+
+## Install the tools you'll need
+
+> 💡 **In a Codespace?** Skip this section — the devcontainer already installed all of these. Jump to **"Set up your local environment (one-time)"**.
+
+**Prerequisites at a glance:**
+
+- **Azure subscription** with access to a Foundry project and a deployed model such as `gpt-4o-mini` or `gpt-4.1-mini`. See [Create a Foundry project](https://learn.microsoft.com/azure/ai-foundry/how-to/create-projects).
+- **A role that lets you *use* the project** — **`Foundry User`** (formerly *Azure AI User*) on the Foundry project. This is the least-privilege role for *using* a project — prefer it over broader roles like Owner or Contributor. If you created the project you already have at least this. Some steps assign extra roles as needed (Step 5 adds Azure AI Search roles; Step 6 reuses `Foundry User` for the Skills API and grants it to the deployed agent's identity).
+- **Python 3.10 or newer** (the devcontainer ships 3.12).
+- **Azure CLI (`az`)** — used by `DefaultAzureCredential` for local auth.
+- **Azure Developer CLI (`azd`)** with the [`microsoft.foundry` extension](https://learn.microsoft.com/azure/foundry/agents/how-to/install-cli-foundry-extensions) — used to scaffold, provision, run, and deploy hosted agents.
+- **VS Code + [Foundry Toolkit](https://marketplace.visualstudio.com/items?itemName=ms-windows-ai-studio.windows-ai-studio)** *(optional, recommended)* — UI alternative to `azd` for running, debugging, and deploying hosted agents.
+- **[GitHub Copilot CLI](https://github.com/github/copilot-cli) (`copilot`)** *(optional, recommended)* — AI-powered CLI assistant. Install with `npm install -g @github/copilot` (the devcontainer installs it automatically via the `copilot-cli` feature).
+- **[Bicep](https://learn.microsoft.com/azure/azure-resource-manager/bicep/install)** *(optional, recommended)* — infrastructure-as-code language for the `azd`-generated `infra/`. Install the CLI with `az bicep install` and the [Bicep VS Code extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-bicep) for language support.
+- **[Azure Skills](https://github.com/microsoft/azure-skills)** *(optional, recommended)* — Azure skills and MCP server configurations for AI coding assistants. In VS Code install the [Azure MCP extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azure-mcp-server); for the GitHub Copilot CLI run `/plugin marketplace add microsoft/azure-skills` then `/plugin install azure@azure-skills`. Requires **Node.js 18+** (the MCP servers run via `npx`) and an authenticated `az login` for the Azure tools.
+- **[`uv`](https://docs.astral.sh/uv/)** *(optional)* — a faster drop-in for `pip`/`venv`. Anywhere this workshop says `pip` or `python -m venv` you can use `uv pip` or `uv venv` instead.
+
+### Python 3.10+
+
+- **Windows:**
+ ```powershell
+ winget install --id Python.Python.3.12 -e
+ ```
+- **macOS:** install from [python.org](https://www.python.org/downloads/) or `brew install python@3.12`.
+- **Linux (Ubuntu/Debian):**
+ ```bash
+ sudo apt update && sudo apt install -y python3 python3-venv python3-pip
+ ```
+
+Verify:
+
+```bash
+python --version # or `python3 --version`
+```
+
+### Azure CLI (`az`)
+
+Full instructions: [Install the Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli).
+
+- **Windows:**
+ ```powershell
+ winget install --id Microsoft.AzureCLI -e
+ ```
+- **macOS:**
+ ```bash
+ brew update && brew install azure-cli
+ ```
+- **Linux (Ubuntu/Debian):**
+ ```bash
+ curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
+ ```
+
+Verify:
+
+```bash
+az --version
+```
+
+### Azure Developer CLI (`azd`)
+
+Full instructions: [Install the Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd).
+
+- **Windows:**
+ ```powershell
+ winget install --id Microsoft.Azd -e
+ ```
+- **macOS:**
+ ```bash
+ brew tap azure/azd && brew install azd
+ ```
+- **Linux:**
+ ```bash
+ curl -fsSL https://aka.ms/install-azd.sh | bash
+ ```
+
+Verify:
+
+```bash
+azd version
+```
+
+### Optional: `uv` (faster Python package manager)
+
+Full instructions: [Install `uv`](https://docs.astral.sh/uv/getting-started/installation/).
+
+- **Windows:**
+ ```powershell
+ winget install --id=astral-sh.uv -e
+ ```
+- **macOS / Linux:**
+ ```bash
+ curl -LsSf https://astral.sh/uv/install.sh | sh
+ ```
+
+## Set up your local environment (one-time)
+
+> 💡 **In a Codespace?** The devcontainer already handled the venv and the `pip install` (substeps 3 and 5 below) — but you still need to do **substeps 1, 2, 4, and 6** (`az login`, `azd auth login` + ext install, copy `.env`, run preflight). Authentication and your `.env` can't be baked into the container.
+
+1. **Sign in to Azure**:
+ ```bash
+ az login
+ ```
+ If needed, select a subscription:
+ ```bash
+ az account set -s
+ ```
+2. **Sign in to azd and install the Foundry extension** (one-time):
+ ```bash
+ azd auth login
+ azd ext install microsoft.foundry
+ ```
+ This adds the `azd ai agent ...` subcommands used from Step 1 onward to scaffold `azure.yaml`/`infra/`, provision Foundry resources, run the agent locally, deploy, and invoke. `microsoft.foundry` is a meta-package that installs all the Foundry `azd ai` extensions — see [Install the Azure Developer CLI Foundry extensions](https://learn.microsoft.com/azure/foundry/agents/how-to/install-cli-foundry-extensions) for details. If you'd rather drive everything from VS Code, the **Foundry Toolkit** extension exposes the same operations as palette commands and a sidebar. If you have a Python virtual environment active (next substep), the Foundry Toolkit picks it up automatically when you press **F5** to debug.
+3. **Create and activate a Python virtual environment.**
+
+ Pick one of the two options below. Option A uses the Python stdlib `venv` module and matches the rest of the workshop; Option B uses [`uv`](https://docs.astral.sh/uv/), which is significantly faster but requires installing `uv` first (see above). Both options create the environment at `.venv/`, so the activation commands are the same.
+
+ **Option A — `python -m venv` (default)**
+ ```bash
+ python -m venv .venv
+ ```
+
+ **Option B — `uv venv`**
+ ```bash
+ uv venv .venv
+ ```
+
+ Then activate it:
+
+ - macOS / Linux:
+ ```bash
+ source .venv/bin/activate
+ ```
+ - Windows (PowerShell):
+ ```powershell
+ .\.venv\Scripts\Activate.ps1
+ ```
+
+ > 💡 **`uv` users:** activation is optional. `uv pip install`, `uv run`, and `uv` itself auto-discover `.venv/` in the current directory. If you skip activation, prefix later Python commands with `uv run` (e.g. `uv run python .workshop/scripts/preflight.py`) so they use the venv's interpreter.
+4. **Configure environment**: setup and every later step read their configuration from a repo-root `.env` file, so create it **before** running preflight — copy the template, then fill it in:
+
+ ```bash
+ # bash / zsh
+ cp .env.example .env
+ ```
+
+ ```powershell
+ # PowerShell
+ Copy-Item .env.example .env
+ ```
+
+ Then edit `.env`:
+ - `AZURE_AI_PROJECT_ENDPOINT` — from your Foundry project's overview page.
+ - `AZURE_AI_MODEL_DEPLOYMENT_NAME` — your deployment name, for example `gpt-4o-mini`.
+ - `WORKSHOP_RESOURCE_PREFIX` — this prefixes **every** Azure/Foundry resource the workshop creates (and is how `.workshop/scripts/cleanup.py` finds them later). If you're working solo in your own subscription, leave the default `foundry-workshop`. But if you **share the Foundry project or subscription** with other people running this workshop, change it to a value unique to you (for example `foundry-workshop-`) so your resource names don't **collide** with a teammate's — otherwise provisioning can fail on name conflicts, and cleanup could delete each other's resources.
+ - Leave step-specific variables empty for now; the README will tell you when to fill them.
+5. **Install dependencies** (use the option that matches your venv choice above):
+
+ **Option A — `pip`**
+ ```bash
+ pip install -r travel_assistant/requirements.txt
+ pip install -r .workshop/scripts/requirements.txt
+ ```
+
+ **Option B — `uv pip`**
+ ```bash
+ uv pip install -r travel_assistant/requirements.txt
+ uv pip install -r .workshop/scripts/requirements.txt
+ ```
+6. **Run preflight**:
+ ```bash
+ # If you activated .venv
+ python .workshop/scripts/preflight.py
+
+ # If you're using uv without activation
+ uv run python .workshop/scripts/preflight.py
+ ```
+ Fix any ❌. ⚠️ items are usually safe to ignore until later steps.
+
## How the workshop works
This workshop has one important contract: **`README.md` is the current step**. Each time you advance, the repository rewrites `README.md` so the next set of instructions appears in place.
-- **Leaving Setup (Step 0):** click the **▶ Start the workshop** button at the bottom of that step. It opens the workshop's GitHub Action — click **Run workflow** to move to Step 1.
-- **Every step after that:** there is no button. When you finish a step, **commit your work and push it to `main`**. The push triggers the **Advance workshop on push to main** Action, which loads the next step (each landed push advances one step).
+- **Leaving Setup (this step):** click the **▶ Start the workshop** button at the bottom. It opens the workshop's GitHub Action — click **Run workflow**, and it moves you from Setup to Step 1.
+- **Every step after that:** there is no button. When you finish a step, **commit the files you created and push them to `main`**. The push triggers the **Advance workshop on push to main** Action, which loads the next step. Each landed push advances by exactly **one** step, so push once — when the step is done.
- After the Action finishes, run **`git pull`** locally. If you are reading in the GitHub UI, refresh the page to see the new `README.md`.
-- Advancing lays the next step's canonical starter files **on top of** your `travel_assistant/` directory. Your previous edits are saved to `.workshop_instance/workshop_backups/step-/` in the same commit.
+- Advancing lays the next step's canonical files **on top of** your `travel_assistant/` directory. Files from earlier steps that the next step doesn't touch are kept as-is — nothing is deleted. Files the next step ships are refreshed to that step's version, and your current edits are first saved to `.workshop_instance/workshop_backups/step-/` in the same commit so you can recover your own wording.
## What you'll build
@@ -46,13 +274,11 @@ This workshop has one important contract: **`README.md` is the current step**. E
## When you're ready
-Initialization is automatic in your own copy.
+Make sure `python .workshop/scripts/preflight.py` is green (or `uv run python .workshop/scripts/preflight.py` if you're using `uv` without activation), then click the button below to open the workflow — and click **Run workflow** in the dialog that appears:
-- **Using GitHub Actions:** create your repo from this template and push once. The **Initialize workshop** workflow runs automatically.
-- **If it didn't run:** open **Actions → Initialize workshop → Run workflow** manually.
-- **Working fully locally (no Actions):** run `python .workshop/scripts/advance_step.py --init` from the repository root.
+[](https://github.com/frostbyte74/foundry-hosted-agents-workshop/actions/workflows/start-workshop.yml)
-After initialization completes, refresh/pull. The README switches to Step 00 with the **Start the workshop** button; from Step 1 on you advance by pushing to `main`.
+Click **Run workflow** to move from Setup to Step 1. Pull after the action completes. From Step 1 onward you advance by committing your work and pushing to `main` — there is no button. With setup already done, Step 1 jumps straight into authoring `agent.yaml`, `agent.manifest.yaml`, and `main.py` for your first hosted TravelBuddy agent.
## Working fully locally (no GitHub Actions)
@@ -76,18 +302,40 @@ python .workshop/scripts/advance_step.py --reset --auto-commit
Your previous `travel_assistant/` is preserved under `.workshop_instance/workshop_backups/reset-/`.
+**Pull the latest workshop machinery (without advancing):**
+
+```bash
+python .workshop/scripts/sync_template.py --auto-commit # add --push to push too
+```
+
+Occasionally the upstream template ships fixes to the workshop machinery (the authoring material under `.workshop/` and the GitHub configuration under `.github/`). This pulls those into your instance **without moving to the next step** and without touching your `travel_assistant/`, your `.workshop_instance/` state, `README.md`, or `.env`. The commit carries a `[skip-advance]` marker, so pushing it never advances you. A local run also refreshes `.github/workflows/`; the automated CI sync deliberately skips workflow files so it stays tokenless (no Personal Access Token required).
+
+**Reset the current step (re-lay its clean starter files):**
+
+```bash
+python .workshop/scripts/advance_step.py --reset-current --auto-commit
+```
+
+Re-lays the **current** step's clean starter files and re-renders its `README.md`, staying on the current step — unlike `--reset`, which returns you to step 0. Your previous `travel_assistant/` is backed up under `.workshop_instance/workshop_backups/reset-current--/` first. Pair it with a sync when you want the current step's delivery refreshed too: **sync first, then reset the current step**. (If you sync just before advancing, you don't need this — advancing already lays down fresh files.)
+
**Re-run preflight:**
```bash
+# If you activated .venv
python .workshop/scripts/preflight.py
+
+# If you're using uv without activation
+uv run python .workshop/scripts/preflight.py
```
-**Shortcuts (optional):** the repo ships a `Makefile` with three aliases:
+**Shortcuts (optional):** the repo ships a `Makefile` with these aliases:
```bash
-make advance # advance to the next step (auto-commits workshop paths)
-make reset # reset to step 0 (auto-commits workshop paths)
-make preflight # run environment checks
+make advance # advance to the next step (auto-commits workshop paths)
+make reset # reset to step 0 (auto-commits workshop paths)
+make reset-current # re-lay the current step's clean files (auto-commits)
+make preflight # run environment checks
+make sync-template # pull latest .workshop/ + .github/ from the template
```
When `make` is not available (e.g. on a clean Windows install), just run the equivalent `python .workshop/scripts/...` commands above.
@@ -121,7 +369,7 @@ This workshop does not use marketplace actions for advancing steps; it uses the
### "My push didn't advance the step"
-Auto-advance only runs for pushes to `main` in your own (non-template) repo, and it skips pushes that only changed workshop bookkeeping such as `.workshop_instance/.workshop-state.json`. Check the **Actions** tab for the **Advance workshop on push to main** run. If it was skipped, make sure you pushed a real change to `main` and that the previous advance already finished. If several quick pushes collapsed into a single advance, that's expected — each *landed* push advances one step.
+Auto-advance only runs for pushes to `main` in your own (non-template) repo, and it skips a few kinds of push that aren't step progress: pushes that only changed workshop bookkeeping such as `.workshop_instance/.workshop-state.json`, pushes whose commit carries a `[skip-advance]` marker (what a template sync adds), and pushes that changed **only** workshop machinery or platform files (`.github/`, `.workshop/`, `Makefile`, `.devcontainer/`, `README.md`, …) and never your delivery (`travel_assistant/` or its sibling folders like `travel_toolbox/`). That last case means you can pull the latest machinery from upstream and push it — even manually, without the `[skip-advance]` marker — without being bumped to the next step. Check the **Actions** tab for the **Advance workshop on push to main** run. If it was skipped, make sure your push touched a delivery file and that the previous advance already finished. If several quick pushes collapsed into a single advance, that's expected — each *landed* push advances one step.
### "Codespace can't reach my Foundry project"
@@ -139,12 +387,28 @@ They were backed up to `.workshop_instance/workshop_backups/step-/` in
When you finish, or if you want to abandon the workshop, step 99 runs `python .workshop/scripts/cleanup.py --apply` to delete all workshop-created Azure resources. The script only touches resources whose names start with `WORKSHOP_RESOURCE_PREFIX`. If you used `azd` to provision hosted-agent resources, you can alternatively run `azd down` to tear down the resources `azd` created.
+## Solution
+
+This step has no code to write — it's intro and setup of your repo from the template.
+
+
---
-**Initialization is automatic:** in your own copy, push once and let **Initialize workshop** run.
+
+
+
+[](https://github.com/frostbyte74/foundry-hosted-agents-workshop/actions/workflows/start-workshop.yml)
+
+**Next:** Step 01 — Basic hosted agent
+
+Click the badge to open **Start the workshop**, then click **Run workflow**. It moves you from Setup to Step 01. Pull after the action completes.
+
+Or open **Actions → Start the workshop → Run workflow** manually.
+
+From Step 01 onward you don't click a button to advance — you just **commit your work and push to `main`**, and the next step loads automatically.
-**If needed:** run **Actions → Initialize workshop** manually.
+> 💡 **Button returns 404?** Your repo's one-time **Initialize workshop** Action hasn't run yet. Open the **Actions** tab, run **Initialize workshop → Run workflow**, then refresh this page.
-**Prefer local only?** Run `python .workshop/scripts/advance_step.py --init`.
+> **Prefer to stay local?** Run `python .workshop/scripts/advance_step.py --expected-current-step 0 --auto-commit` (or `make advance`) instead of clicking the button. See [Working fully locally](.workshop/docs/steps/00-intro.md#5-working-fully-locally-no-github-actions) for the full local flow.
-Then refresh/pull: your README will be rewritten to Step 00 and from there you can advance normally.
+Made a mistake? Use the [Reset workshop](https://github.com/frostbyte74/foundry-hosted-agents-workshop/actions/workflows/reset-workshop.yml) workflow, or run `python .workshop/scripts/advance_step.py --reset --auto-commit` locally.
diff --git a/travel_assistant/STEP_README.md b/travel_assistant/STEP_README.md
new file mode 100644
index 0000000..e94bd97
--- /dev/null
+++ b/travel_assistant/STEP_README.md
@@ -0,0 +1,3 @@
+You're now on step 00. This minimal snapshot sets up the workshop requirements; advance to step 01 to complete the TravelBuddy scaffold.
+
+The devcontainer for this workshop also provisions the recommended tooling: the **GitHub Copilot CLI** (`copilot`), the **Bicep** CLI + VS Code extension, and the **Azure Skills** plugin / **Azure MCP Server** VS Code extension. See `.workshop/docs/steps/00-intro.md` for how to install them locally.
diff --git a/travel_assistant/requirements.txt b/travel_assistant/requirements.txt
new file mode 100644
index 0000000..85a926b
--- /dev/null
+++ b/travel_assistant/requirements.txt
@@ -0,0 +1,15 @@
+# ---- Agent Framework with Microsoft Foundry ----
+agent-framework-foundry
+agent-framework-foundry-hosting>=1.0.0a260630
+
+# ---- Step 7: Multi-agent orchestration (HandoffBuilder) ----
+agent-framework-orchestrations
+
+# ---- Local Debugging in Foundry Toolkit ----
+debugpy
+
+# ---- RAG (Azure AI Search) ----
+agent-framework-azure-ai-search
+
+# ---- Step 6: Skills ----
+azure-ai-projects
\ No newline at end of file