+
+* A **Foundry Account** and **Foundry Project** with model deployments for `gpt-5.4`, `gpt-5.4-mini`, and `text-embedding-3-large`
+* **API Management** with API proxies that read data from Cosmos DB
+* **Cosmos DB** with containers for machines, thresholds, telemetry, the knowledge base, parts inventory, technicians, and work orders
+* A **Storage account** with knowledge base wiki articles in Markdown
+* **Azure AI Search** to query the wiki knowledge base
+* **Application Insights** and **Log Analytics** for observability
+* **Container Registry** and a **Container Apps Environment** for the agents you deploy in later challenges
+
+
+
+### Model Context Protocol (MCP)
+
+You will use **Model Context Protocol (MCP)** to connect the agents with remote tools. MCP is a standard way for an agent to discover and invoke external capabilities ("tools") through a consistent interface.
+
+
+
+Let's break down the key components shown in the diagram:
+
+#### ❶ MCP Host and MCP Client
+
+An **MCP Host** is the application that runs agents and manages MCP connections. Inside the host lives one or more **MCP Clients** that handle communication with MCP servers. Examples include:
+
+| MCP Host | MCP Client | Description |
+|----------|------------|-------------|
+| VS Code | GitHub Copilot extension | Copilot acts as the MCP client, connecting to servers for code tools |
+| Your Python script | Agent SDK client | The agents you build in this challenge — the `MCPTool` object creates an MCP client |
+
+#### ❷ Remote MCP Server (HTTPS)
+
+A **remote MCP server** runs in the cloud and communicates over HTTPS. This is ideal for enterprise APIs that need to be accessed securely, shared services used by multiple agents, and APIs that require authentication and rate limiting. In this challenge, you expose APIs via **API Management** as remote MCP servers.
+
+#### ❸ Tools and Data
+
+MCP servers provide access to **tools** (actions the agent can invoke) and **data** (information the agent can retrieve). The server defines tool names and descriptions, input/output schemas (JSON Schema), and the actual implementation that fetches data or performs actions.
+
+#### ❹ Local MCP Server (stdio)
+
+A **local MCP server** runs on the same machine as the host and communicates via standard input/output (stdio). Useful for development and testing, tools that need local file system access, and quick prototyping without cloud deployment.
+
+#### ❺ MCP Server Internals
+
+Whether remote or local, every MCP server implements the same protocol:
+
+| Component | Purpose |
+|-----------|---------|
+| Discovery API | `GET /mcp` — returns available tools with their schemas |
+| Invocation API | `POST /mcp/tools/{tool}` — executes a specific tool |
+| SDKs | Libraries in Python, TypeScript, and C# to simplify building servers |
+
+While you *could* build an MCP server yourself using an SDK, there are easier ways of doing it *without writing any code*. The next section shows how API Management lets you expose existing APIs as MCP servers.
+
+### API Management as AI gateway
+
+In this challenge, the tools live behind remote MCP servers hosted in **API Management** that expose existing API operations. Why use API Management here:
+
+* **Decouples the agent from integrations**: the agent calls a tool by name and schema, not by hardcoding HTTP requests.
+* **Reusable and portable**: the same agent code can work across environments as long as the MCP server URL/connection is configured.
+* **Governance hooks**: tools can be allow-listed and can require (or skip) approval depending on your scenario.
+
+The diagram below illustrates how API Management serves as an AI gateway, bridging traditional API patterns with the new requirements of agentic applications.
+
+
+
+| # | Component | Description |
+|---|-----------|-------------|
+| ❶ | Traditional Application | APIs have been used for many years to integrate applications with remote systems. This is the foundation we build upon. |
+| ❷ | API Proxy (APIM) | API Management is a mature platform that shields backend systems and adds quality-of-service capabilities such as throttling, security, and caching. |
+| ❸ | Traditional Backend APIs | Backend services exposed via REST, SOAP, GraphQL, and other protocols that your applications consume. |
+| ❹ | Agentic Application | We use APIs just like traditional applications to build the full solution. However, agentic applications introduce new requirements around AI model integration and tool discovery. |
+| ❺ | AI APIs | Model APIs where APIM policies enable token limiting, token metrics emission, model load balancing, and content safety — all using built-in APIM functionality applied in new ways for AI workloads. |
+| ❻ | MCP in APIM | A standard API can easily be exposed in APIM as an MCP server without writing any code. This is exactly what you will do in this challenge — turning existing APIs into tools that agents can discover and invoke. |
+
+### Grounding with Foundry IQ
+
+You will also ground the Fault Diagnosis Agent with data using **Foundry IQ**, a retrieval-augmented generation (RAG) capability in Microsoft Foundry that enables agents to access and reason over your enterprise data. It provides a managed knowledge retrieval layer powered by Azure AI Search, letting your agent retrieve relevant chunks from your own documents at runtime instead of pasting wiki content into prompts.
+
+Key benefits of Foundry IQ:
+
+* **Simplified development**: no need to build custom RAG pipelines — Foundry IQ handles chunking, indexing, and retrieval for you.
+* **Flexible data integration**: connect multiple data sources to a single knowledge base.
+* **Enhanced agent capabilities**: agents can access up-to-date enterprise knowledge without retraining the model.
+
+Foundry IQ consists of two main concepts:
+
+| Concept | Description |
+|---------|-------------|
+| Knowledge Sources | The *what* to retrieve — connections to your data. These define where the content comes from. |
+| Knowledge Bases | The *how* to retrieve — the retrieval configuration that combines one or more knowledge sources into a queryable endpoint. |
+
+
+
+| # | Component | Description |
+|---|-----------|-------------|
+| ❶ | End User | The agent receives questions from the end user and processes them. |
+| ❷ | Large Language Model | The agent uses a large language model to reason about the question and determine the next action. |
+| ❸ | Knowledge Base | Foundry IQ provides a knowledge base with several knowledge sources that the agent can query. |
+| ❹ | Indexed Sources | Pre-indexed sources like Azure AI Search indexes, Azure Blob Storage, and Azure Data Lake. Content is indexed ahead of time for fast vector and keyword retrieval. |
+| ❺ | Remote Sources | On-demand sources like SharePoint and Bing that are queried at runtime. Useful for real-time data that changes frequently. |
+
+In this challenge, you will use Foundry IQ to make the machine wiki available to the Fault Diagnosis Agent via an MCP tool.
+
+## ✅ Tasks
+
+### Task 1: Create and test the initial Anomaly Classification Agent
+
+As a first step, create an agent to interpret and classify anomalies and raise maintenance alerts if certain thresholds have been violated. The agent takes anomalies for specific machines as input and checks them against thresholds for that machine type by using JSON data stored in Cosmos DB.
+
+#### Task 1.1: Review the initial code
+
+Examine the Python code in [`src/agents/anomaly_classification_agent.py`](../src/agents/anomaly_classification_agent.py). A few things to observe:
+
+* The agent uses two function tools: `get_thresholds` retrieves specific metric threshold values for certain machine types, and `get_machine_data` fetches details about machines such as id, model, and maintenance history.
+* The agent is instructed to output both structured alert data in a specific format and a human-readable summary.
+* The code creates the agent and runs a sample query against it.
+
+#### Task 1.2: Run the code
+
+```bash
+python src/agents/anomaly_classification_agent.py
+```
+
+Verify that the agent responds with a reasonable answer that classifies the sample anomaly and includes a human-readable summary.
+
+### Task 2: Equip the agent with MCP tools
+
+Machine and threshold information is typically stored in a central system and exposed through an API. Adjust the data access to use existing Machine and Maintenance APIs instead of accessing Cosmos DB directly, by exposing those APIs as MCP servers.
+
+#### Task 2.1: Test the Machine API
+
+The Machine API and Maintenance API are already available in API Management and contain endpoints for getting details about a specific machine and thresholds for certain machine types. Try the APIs:
+
+```bash
+# Get all machines
+curl -fsSL "$APIM_GATEWAY_URL/machine" -H "Ocp-Apim-Subscription-Key: $APIM_SUBSCRIPTION_KEY" -H "Accept: application/json"
+
+# Get a specific machine
+curl -fsSL "$APIM_GATEWAY_URL/machine/machine-001" -H "Ocp-Apim-Subscription-Key: $APIM_SUBSCRIPTION_KEY" -H "Accept: application/json"
+
+# Get thresholds for a machine type
+curl -fsSL "$APIM_GATEWAY_URL/maintenance/tire_curing_press" -H "Ocp-Apim-Subscription-Key: $APIM_SUBSCRIPTION_KEY" -H "Accept: application/json"
+```
+
+#### Task 2.2: Expose APIs as MCP servers
+
+API Management provides an easy way to expose APIs as MCP servers without writing any additional wrapper code.
+
+❶ Navigate to your API Management instance in the [Azure portal](https://portal.azure.com).
+
+❷ Choose **APIs** and notice that the *Machine API* and *Maintenance API* you tested earlier are available.
+
+
+
+❸ Navigate to the **MCP Servers** section.
+
+❹ Select **Create MCP Server** and **Expose an API as MCP Server**.
+
+❺ Select the API, operations, and provide the following details:
+
+* **API**: *Machine API*
+* **API Operations**: *Get Machine*
+* **Display Name**: *Get Machine Data*
+* **Name**: `get-machine-data`
+* **Description**: *Gets details about a specific machine*
+
+
+
+❻ Select **Create**.
+
+❼ Copy the *MCP Server URL* of the newly created MCP server.
+
+
+
+❽ Add a new entry to the `.env` file: `MACHINE_MCP_SERVER_ENDPOINT="
+
+❷ Select the **Build** tab to list available agents.
+
+
+
+❸ Examine the configuration details for `AnomalyClassificationAgent`.
+
+
+
+> [!NOTE]
+> There are two versions of the Anomaly Classification Agent: one for the initial agent with local tools, and one for the version that uses MCP tools.
+
+❹ Select the Anomaly Classification Agent and try out some additional questions in the playground:
+
+* Normal condition (no maintenance needed). Use the query `Hello, can you classify the following metric for machine-002: [{"metric": "drum_vibration", "value": 2.1}]`
+
+
+
+* Critical anomaly. Use the query `Hello, can you classify the following metric for machine-005: [{"metric": "mixing_temperature", "value": 175}]`
+
+### Task 3: Understand root cause with the Fault Diagnosis Agent and Foundry IQ
+
+The **Fault Diagnosis Agent** is tasked with understanding the actual root cause of the issues raised by the Anomaly Classification Agent. Besides machine data and maintenance history, add a machine wiki as a tool for the agent by using Foundry IQ.
+
+#### Task 3.1: Examine the machine data wiki
+
+The machine wiki contains knowledge (common issues, repair instructions, and repair details) about different machine types. The wiki pages are available as markdown files in Azure Blob Storage.
+
+❶ Navigate to the [Azure portal](https://portal.azure.com) and locate the storage account.
+
+❷ Select **Storage browser** > **Blob containers** and select the `machine-wiki` container.
+
+❸ Select a wiki article and select the **Edit** tab to preview the content.
+
+
+
+#### Task 3.2: Expose the machine wiki data as a knowledge base
+
+Foundry IQ consists of knowledge sources (*what* to retrieve) and knowledge bases (*how* to retrieve). Knowledge sources are created as standalone objects and then referenced in a knowledge base.
+
+> [!NOTE]
+> Foundry Agent Service orchestrates calls to the knowledge base via the MCP tool and synthesizes the final answer. At runtime, the agent calls only the knowledge base, not the data platform (Azure Blob Storage in this case) that underlies the knowledge source. The knowledge base handles all retrieval operations.
+
+Create a knowledge source and knowledge base by following the steps in [`src/create_knowledge_base.ipynb`](../src/create_knowledge_base.ipynb).
+
+> [!TIP]
+> When running the notebook you will be asked to select an environment. Pick the user-installed Python environment.
+>
+>
+
+#### Task 3.3: Create the Fault Diagnosis Agent
+
+Create the Fault Diagnosis Agent and use the newly created Foundry IQ knowledge base.
+
+Examine the Python code in [`src/agents/fault_diagnosis_agent.py`](../src/agents/fault_diagnosis_agent.py). Currently only one tool, `machine_data`, is available. Your task is to add the knowledge base MCP tool to the agent so the machine wiki content can be used when diagnosing the root cause of the anomaly.
+
+❶ Locate the placeholder comment `# TODO: add Foundry IQ MCP tool` in `src/agents/fault_diagnosis_agent.py`.
+
+❷ Add the knowledge base as an `MCPTool` by replacing the placeholder with:
+
+```python
+MCPTool(
+ server_label="machine-wiki",
+ server_url=machine_wiki_mcp_endpoint,
+ require_approval="never",
+ project_connection_id="machine-wiki-connection"
+)
+```
+
+A few things to observe:
+
+* The agent now uses two MCP tools: `knowledge_base` retrieves machine wiki information for root cause analysis, and `machine_data` fetches details about machines.
+* The agent is clearly instructed to use the machine knowledge base instead of its own knowledge.
+
+Run the code:
+
+```bash
+python src/agents/fault_diagnosis_agent.py
+```
+
+Verify that the agent's answer includes a root cause, severity, and a knowledge base reference from the machine wiki.
+
+🎉 Congratulations! You've successfully built two agents and equipped them with enterprise tools to perform their tasks.
+
+## 🚀 Go Further
+
+> [!NOTE]
+> Finished early? These tasks are **optional** extras for exploration. Feel free to move on to the next challenge — you can always come back later!
+
+
+
+The agent had a system prompt with instructions on how to behave, and two *local* tools to query Cosmos DB data. When running the Python script, the tools executed locally in the Python process — if you asked the same questions in the Foundry portal playground, the agent wouldn't be able to answer since the tools are not available there.
+
+> [!NOTE]
+> **When do you need an agent?** This particular example could be solved *without* an agent — it's mainly mapping metrics to thresholds. The only thing AI is used for here is generating a human-readable summary of the issue. However, using an agent (besides being a learning exercise) means you can add more tools in the future for more advanced reasoning, plus built-in observability and memory (conversation history), which you'll examine in Challenge 4.
+>
+> You don't always need a full agent — you can call a model directly through the Azure AI Inference SDK when your use case is simpler. And agents and traditional code work well together: an agent doesn't have to perform every step in a workflow. Traditional code is often better suited for deterministic logic like validation, filtering, or data transformation. A good rule of thumb: if your agent's system instructions are becoming very long and detailed with step-by-step rules, that's often a sign that some of that logic belongs in code rather than in the prompt. Use agents for reasoning, interpretation, and decisions that benefit from flexibility, and use code for everything else.
+
+In Task 2, you published the APIs as MCP servers in API Management and connected them to the Foundry project.
+
+
+
+The Anomaly Classification Agent could then run fully in Agent Service, so the questions asked in the Foundry playground worked.
+
+Finally, in Task 3, you created the Fault Diagnosis Agent and grounded it with data via AI Search exposed as an MCP server.
+
+
+
+This agent also runs fully in Agent Service and can use the tools when answering questions in the playground. Note that the content from Blob Storage isn't fetched on demand — instead, it's indexed ahead of time, and retrieval queries are executed against AI Search.
+
+If you want to learn more about what you covered in this challenge, check out the links below:
+
+* [Model Context Protocol](https://modelcontextprotocol.io/)
+* [Expose an API as an MCP server in API Management](https://learn.microsoft.com/azure/api-management/export-rest-mcp-server)
+* [Foundry IQ overview](https://learn.microsoft.com/azure/ai-foundry/concepts/foundry-iq)
+* [Azure AI Search documentation](https://learn.microsoft.com/azure/search/)
+
+**Next:** [Challenge 3 - Repair Planner Agent and AI-Driven Development](challenge-03.md)
diff --git a/03-Azure/01-04-AI/08_Predictive_Maintenance/challenges/challenge-03.md b/03-Azure/01-04-AI/08_Predictive_Maintenance/challenges/challenge-03.md
new file mode 100644
index 000000000..7881c4362
--- /dev/null
+++ b/03-Azure/01-04-AI/08_Predictive_Maintenance/challenges/challenge-03.md
@@ -0,0 +1,382 @@
+# Challenge 3 - Repair Planner Agent and AI-Driven Development
+
+**[Home](../README.md)** | [Previous challenge](challenge-02.md) | [Next challenge](challenge-04.md)
+
+> [!TIP]
+> Stuck on a step? See the [Challenge 3 walkthrough](../walkthrough/challenge-03/solution-03.md) for exact commands, expected output, and a validation checklist.
+
+## 🎯 Objective
+
+The goals for this challenge are:
+
+* Pair program with GitHub Copilot to build an agent from scratch
+* Create a .NET agent using the Foundry Agents SDK
+* Understand the similarities between a coding assistant (like GitHub Copilot) and a Foundry Agent — both use instructions, tools, and an LLM to accomplish tasks
+
+## 🧭 Context and Background
+
+
+
+The **Repair Planner Agent** is the third component in the multi-agent system. After a fault has been diagnosed, this agent determines what repair tasks need to be performed, finds technicians with the required skills, checks parts inventory, and creates a structured work order.
+
+You will implement the Repair Planner Agent as a .NET application that reads information about `Technicians` and `PartsInventory` from Cosmos DB. The final work order is also saved in Cosmos DB. The following diagram illustrates the target solution.
+
+
+
+❶ The **Repair Planner** is a .NET console application with `Program.cs` as its entry point.
+
+❷ The `RepairPlannerAgent.cs` class registers the agent and orchestrates calls to other services.
+
+❸ The `CosmosDbService.cs` class encapsulates Cosmos DB data access.
+
+❹ In this exercise, the mappings between faults and required skills/parts are done as a static mapping in `FaultMappingService.cs`. In a real-world application, this would be fetched from another system.
+
+> [!TIP]
+> This is just one way to structure the solution — there are many valid approaches! If you have experience with .NET, feel free to experiment with a different architecture (for example dependency injection, separate class libraries, or different layering patterns). The goal, though, is to have GitHub Copilot write the majority of the code while you provide guidance and review.
+
+The following mappings are used in this exercise. The `agentplanning` agent already knows these mappings, so you don't need to copy them manually.
+
+
+
+#### Task 2.1: Architecture planning
+
+Start with the following prompt to understand the proposed setup for the Repair Planner Agent.
+
+💬 Ask the agent:
+
+```
+I need to build a Repair Planner Agent in .NET for Challenge 3
+using the Foundry Agents SDK. Can you explain the architecture?
+```
+
+#### Task 2.2: Create data models
+
+Now let the agent create the data models.
+
+💬 Ask the agent:
+
+```
+Create all data models for the Repair Planner Agent:
+- DiagnosedFault (input from previous agent)
+- Technician (with skills and availability)
+- Part (inventory items)
+- WorkOrder (output with tasks)
+- RepairTask (individual repair steps)
+- WorkOrderPartUsage (parts needed)
+
+Use dual JSON attributes for Cosmos DB compatibility.
+```
+
+#### Task 2.3: Create FaultMappingService
+
+Create a service for mapping between fault/skills and fault/parts. In this exercise, it will be a static mapping of values, but in a real-world scenario this would be fetched from a dedicated system.
+
+💬 Ask the agent:
+
+```
+Create a FaultMappingService that maps fault types to required skills and parts using hardcoded dictionaries.
+```
+
+#### Task 2.4: Create CosmosDbService
+
+Let's create the data access service.
+
+💬 Ask the agent:
+
+```
+Create a CosmosDbService that:
+- Queries available technicians by skills
+- Fetches parts by part numbers
+- Creates work orders
+Include error handling and logging.
+```
+
+#### Task 2.5: Create the main agent
+
+💬 Ask the agent:
+
+```
+Create the RepairPlannerAgent class that orchestrates the entire workflow.
+It should register the agent, determine required skills, query technicians and parts,
+and save the work order.
+```
+
+#### Task 2.6: Create the main program
+
+Finally, let the `agentplanning` agent update `Program.cs` to initialize all services and run a sample fault.
+
+💬 Ask the agent:
+
+```
+Update Program.cs to initialize all services, create a sample fault,
+and demonstrate the repair planning workflow.
+```
+
+Your completed project could look similar to this:
+
+```text
+RepairPlanner/
+├── RepairPlanner.csproj
+├── Program.cs
+├── RepairPlannerAgent.cs
+├── Models/
+│ ├── DiagnosedFault.cs
+│ ├── Technician.cs
+│ ├── Part.cs
+│ ├── WorkOrder.cs
+│ ├── RepairTask.cs
+│ └── WorkOrderPartUsage.cs
+└── Services/
+ ├── CosmosDbService.cs
+ ├── CosmosDbOptions.cs
+ └── FaultMappingService.cs
+```
+
+### Task 3: Test your agent
+
+Try out your agent.
+
+```bash
+export $(grep -v '^#' ../../.env | xargs)
+dotnet run
+```
+
+Verify that the agent logs finding available technicians, fetching parts, and saving a work order with a generated work order number.
+
+🎉 Congratulations! You've built a Repair Planner Agent in .NET using GitHub Copilot.
+
+## 🚀 Go Further
+
+> [!NOTE]
+> Finished early? These tasks are **optional** extras for exploration. Feel free to move on to the next challenge — you can always come back later!
+
+
+
+The diagram above illustrates how GitHub Copilot combines multiple inputs to generate contextual responses:
+
+❶ **Your prompt** — the primary instruction you provide to the agent (for example "Create the RepairPlannerAgent class..."). This is your direct request that drives the conversation.
+
+❷ **Custom instructions** — two types of instruction files shape Copilot's behavior:
+
+* [`copilot-instructions.md`](../.github/copilot-instructions.md) — general workspace-wide instructions applied to all chat requests (SDK constraints, pinned package versions, environment variables, and so on)
+* [`agentplanning.agent.md`](../.github/agents/agentplanning.agent.md) — the specific role and persona for the `agentplanning` agent, discovered by VS Code from `.github/agents/*.agent.md` and selectable from the Agents dropdown
+
+❸ **Workspace context** — Copilot examines files in your workspace to understand structure and data, such as `README.md`, `technicians.json`, `work-orders.json`, and your existing code files. This helps it generate code that fits your project.
+
+❹ **Tools and data (MCP)** — Copilot can be equipped with additional tools exposed via the Model Context Protocol (MCP) to accomplish more complex tasks. This is very similar to how the agents in [Challenge 2](challenge-02.md) were equipped with tools — just as you gave the Fault Diagnosis Agent access to Cosmos DB queries and a knowledge base, you can extend Copilot with external data sources and capabilities.
+
+### Taking it further with Spec Kit
+
+In this challenge, you used custom instructions and a guided agent to build a single component. But what happens when you need to build entire features or complete applications with AI assistance?
+
+[Spec Kit](https://github.com/github/spec-kit) is an open-source toolkit that takes AI-assisted development to the next level through Spec-Driven Development (SDD). Instead of generating code directly from prompts, SDD flips the traditional approach: specifications become executable, directly generating working implementations rather than just guiding them.
+
+**Why this matters for larger projects:**
+
+| Traditional approach | Spec-Driven Development |
+|---------------------|------------------------|
+| Code is the source of truth | Specifications are the source of truth |
+| Specs drift from implementation | Specs generate implementation |
+| One-shot prompt → code | Multi-step: specify → plan → tasks → implement |
+| Hard to review AI output | Structured artifacts at each stage |
+
+Spec Kit provides slash commands that structure AI-assisted development:
+
+* `/speckit.constitution` — establish project principles and architectural guidelines
+* `/speckit.specify` — create functional specifications (focus on *what* and *why*, not *how*)
+* `/speckit.plan` — generate technical implementation plans with your chosen tech stack
+* `/speckit.tasks` — break down into actionable, parallelizable tasks
+* `/speckit.implement` — execute tasks according to the plan
+
+The key insight is that specifications become living documents that generate code, tests, and documentation, rather than artifacts that are written once and ignored. When requirements change, you update the spec and regenerate, maintaining alignment between intent and implementation.
+
+This approach is particularly valuable when building complete features or applications (not just single files), working on teams where specifications need review and approval, maintaining long-lived projects where requirements evolve, or wanting reproducible, auditable AI-assisted development.
+
+If you want to expand your knowledge on what you covered in this challenge, have a look at the content below:
+
+* [Custom agents in VS Code](https://code.visualstudio.com/docs/copilot/customization/custom-agents)
+* [Custom instructions in VS Code](https://code.visualstudio.com/docs/copilot/customization/custom-instructions)
+* [Use MCP servers in VS Code](https://code.visualstudio.com/docs/copilot/customization/mcp-servers)
+* [Microsoft Learn MCP server](https://github.com/microsoftdocs/mcp)
+* [Spec Kit on GitHub](https://github.com/github/spec-kit)
+* [Spec-Driven Development blog post](https://developer.microsoft.com/blog/spec-driven-development-spec-kit)
+
+**Next:** [Challenge 4 - Maintenance Scheduler and Parts Ordering Agents](challenge-04.md)
diff --git a/03-Azure/01-04-AI/08_Predictive_Maintenance/challenges/challenge-04.md b/03-Azure/01-04-AI/08_Predictive_Maintenance/challenges/challenge-04.md
new file mode 100644
index 000000000..9df7afb1c
--- /dev/null
+++ b/03-Azure/01-04-AI/08_Predictive_Maintenance/challenges/challenge-04.md
@@ -0,0 +1,277 @@
+# Challenge 4 - Maintenance Scheduler & Parts Ordering Agents
+
+**[Home](../README.md)** | [Previous challenge](challenge-03.md) | [Next challenge](challenge-05.md)
+
+> [!TIP]
+> Stuck on a step? See the [Challenge 4 walkthrough](../walkthrough/challenge-04/solution-04.md) for exact commands, expected output, and a validation checklist.
+
+## 🎯 Objective
+
+The goals for this challenge are:
+
+* Use **agent memory** to maintain context across multiple interactions
+* Implement **observability** with Azure AI tracing to monitor and debug agent behavior
+
+## 🧭 Context and Background
+
+
+
+The **Maintenance Scheduler Agent** analyzes work orders and historical maintenance data to find optimal maintenance windows that minimize production disruption. The **Parts Ordering Agent** checks inventory levels for required parts, evaluates supplier performance and lead times, and generates optimized parts orders with cost analysis.
+
+You will use the Azure resources highlighted in the image below.
+
+
+
+Both agents interact with **Cosmos DB** as their primary data store.
+
+
+
+You can examine metrics for *token usage*, *agent runs*, *tool calls*, and potential *errors*.
+
+#### Task 3.3: View traces in Application Insights
+
+The **Foundry** project is connected to **Application Insights**, where the monitoring data is stored. Select **Open in Azure Monitor** in the upper right corner.
+
+
+
+This opens **Application Insights**, where you'll see similar monitoring details as in the **Foundry** portal, but you can also drill further into traces for troubleshooting purposes.
+
+
+
+🎉 Congratulations! You've successfully worked with two agents that integrate with **Cosmos DB** and include production-ready observability.
+
+## 🚀 Go Further
+
+> [!NOTE]
+> Finished early? These tasks are **optional** extras for exploration. Feel free to move on to the next challenge — you can always come back later!
+
+
+
+The agent used its memory of prior maintenance discussions for the same machine to inform its recommendation, rather than reasoning about the machine from scratch on every run.
+
+In Task 2, you ran the Parts Ordering Agent, which evaluates supplier reliability, lead time, and cost to generate an order.
+
+
+
+Notice how the agent produced a different outcome (order parts vs. mark the work order ready) depending purely on the current inventory state read from Cosmos DB.
+
+Finally, in Task 3, you generated trace data and explored it in the Foundry portal and Application Insights.
+
+
+
+> [!NOTE]
+> **Why observability matters for agents:** unlike traditional deterministic code, an agent's behavior depends on the model's reasoning, which can vary between runs. Tracing lets you inspect *why* an agent made a particular decision — not just *whether* it succeeded — which is essential once you move an agentic solution from a demo into production.
+
+If you want to learn more about what you covered in this challenge, check out the links below:
+
+* [Azure Monitor OpenTelemetry](https://learn.microsoft.com/azure/azure-monitor/app/opentelemetry-overview)
+* [Trace your application with Azure AI Foundry](https://learn.microsoft.com/azure/ai-foundry/concepts/observability)
+* [Azure Cosmos DB documentation](https://learn.microsoft.com/azure/cosmos-db/)
+
+**Next:** [Challenge 5 - Multi-Agent Orchestration](challenge-05.md)
diff --git a/03-Azure/01-04-AI/08_Predictive_Maintenance/challenges/challenge-05.md b/03-Azure/01-04-AI/08_Predictive_Maintenance/challenges/challenge-05.md
new file mode 100644
index 000000000..e1b3b6b8f
--- /dev/null
+++ b/03-Azure/01-04-AI/08_Predictive_Maintenance/challenges/challenge-05.md
@@ -0,0 +1,352 @@
+# Challenge 5 - Multi-Agent Orchestration with Aspire
+
+**[Home](../README.md)** | [Previous challenge](challenge-04.md) | [Next: Wrap-up](finish.md)
+
+> [!TIP]
+> Stuck on a step? See the [Challenge 5 walkthrough](../walkthrough/challenge-05/solution-05.md) for exact commands, expected output, and a validation checklist.
+
+## 🎯 Objective
+
+The goals for this challenge are:
+
+* Run an Aspire-hosted **Agent Framework** workflow end-to-end
+* Understand how different agent types and hosting models work together
+* Observe execution via the Aspire dashboard and traces
+
+## 🧭 Context and Background
+
+
+
+At a high level, each agent contributes a specific capability to the workflow:
+
+* **Anomaly Classification Agent**: determines whether incoming telemetry indicates an anomaly, and classifies severity.
+* **Fault Diagnosis Agent**: interprets the anomaly signals and proposes likely root causes and next checks.
+* **Repair Planner Agent**: drafts a repair plan (tasks, parts, and recommended technician actions), with direct access to operational data.
+* **Maintenance Scheduler Agent**: selects maintenance windows and assigns technicians based on availability.
+* **Parts Ordering Agent**: reserves/requests required parts from inventory or suppliers.
+
+This challenge demonstrates how a "real application" can orchestrate multiple agents in a workflow — where agents are not the product UI, but capabilities that enhance the solution.
+
+Now we put all previously used Azure resources in action.
+
+
+
+### Why Aspire (workflow host)
+
+We use **.NET Aspire** as the host for the workflow. Aspire is an opinionated framework for building distributed applications, and it's a good fit here because:
+
+* It gives a consistent developer experience for running multi-service apps locally.
+* It provides a built-in dashboard for observability.
+* It supports polyglot solutions (this project includes both .NET and Python components).
+
+In practice, that means Aspire can orchestrate both .NET services and Python processes side-by-side, which is exactly what we need for this multi-agent workflow.
+
+In other words, Aspire is the "glue" that runs the workflow host, API, UI, and agent processes together and gives you one place to see logs, health, and traces. For agentic systems, that observability is especially useful because a single user action can fan out into multiple agent calls and tool invocations.
+
+### Agent-to-Agent (A2A) invocation
+
+This solution includes different types of agents:
+
+* **Anomaly Classification Agent** and **Fault Diagnosis Agent**
+ * Defined in Python
+ * Running fully in **Foundry Agent Service** (no local execution)
+* **Repair Planner Agent**
+ * Implemented in C#
+ * Runs with local logic and direct access to data sources like **Cosmos DB**
+ * Invoked from the workflow using **Agent-to-Agent (A2A)**
+* **Maintenance Scheduler Agent** and **Parts Ordering Agent**
+ * Python agents with local logic
+ * Invoked with A2A similar to the **Repair Planner Agent**
+
+**A2A** is a pattern for letting a workflow invoke an agent through a consistent interface, so you can combine independently implemented agents without tightly coupling everything together.
+
+This matters in a polyglot setup: the workflow can call an agent implemented in a different language (or hosted in a different process) the same way it calls any other agent. It also gives you a clean boundary between orchestration (the workflow) and capabilities (the agents), which makes the system easier to evolve over time.
+
+#### Publishing agents via Azure API Management
+
+In Challenge 2, we explored how to use [API Management as an AI gateway](challenge-02.md#api-management-as-ai-gateway) for governing and securing access to AI services. **Azure API Management** can also be used to publish agents as A2A endpoints, enabling governed agent-to-agent communication at scale.
+
+With **API Management** as an A2A gateway, you get:
+
+* **Centralized agent discovery**: agents can be registered and discovered through a unified gateway.
+* **Security and authentication**: apply consistent authentication, authorization, and rate limiting policies across all agent endpoints.
+* **Observability**: monitor agent invocations, latencies, and errors through APIM's built-in analytics.
+* **Protocol translation**: APIM can handle protocol differences and provide a consistent A2A interface regardless of the underlying agent implementation.
+
+This approach is particularly valuable in enterprise scenarios where you need to expose agents to multiple consumers while maintaining governance and control over how agents are accessed and invoked.
+
+### Agent Framework workflows
+
+The **Microsoft Agent Framework** provides *orchestrations* — pre-built workflow patterns with specially-built executors that allow developers to quickly create complex workflows by simply plugging in their own AI agents.
+
+#### Why workflows matter
+
+Traditional single-agent systems are limited in their ability to handle complex, multi-faceted tasks. By orchestrating multiple agents, each with specialized skills or roles, you can create systems that are more robust, adaptive, and capable of solving real-world problems collaboratively.
+
+#### Supported orchestrations
+
+The **Agent Framework** supports several orchestration patterns, each suited to different scenarios:
+
+| Pattern | Description | Typical use case |
+|---------|-------------|-------------------|
+| **Concurrent** | A task is broadcast to all agents and processed concurrently | Parallel analysis, independent subtasks, ensemble decision making |
+| **Sequential** | Passes the result from one agent to the next in a defined order | Step-by-step workflows, pipelines, multi-stage processing |
+| **Group Chat** | Assembles agents in a star topology with a manager controlling the flow of conversation | Iterative refinement, collaborative problem-solving, content review |
+| **Magentic** | A variant of group chat with a planner-based manager (inspired by MagenticOne) | Complex, generalist multi-agent collaboration |
+| **Handoff** | Assembles agents in a mesh topology where agents can dynamically pass control based on context without a central manager | Dynamic workflows, escalation, fallback, or expert handoff scenarios |
+
+This challenge uses the **Sequential** pattern — see [Conclusion and Reflection](#-conclusion-and-reflection) for why that fits this scenario.
+
+## ✅ Tasks
+
+> [!IMPORTANT]
+> This workflow expects the **Anomaly Classification** and **Fault Diagnosis** agents to be hosted in **Foundry Agent Service**. Make sure you've completed [Challenge 2](challenge-02.md) before starting the workflow.
+
+### Task 1: Start Aspire
+
+```bash
+cd src/agent-workflow
+aspire run
+```
+
+### Task 2: Make the workflow API port public (Codespaces)
+
+The workflow API runs on port `5231`. In VS Code / **GitHub Codespaces**:
+
+
+
+* Open the *Ports* tab
+* Find port `5231`
+* Set *Port Visibility* to *Public*
+
+> This allows the frontend to call the API from the browser.
+
+### Task 3: Open the frontend
+
+Once Aspire is running, it provides links in the output.
+
+* Click the *frontend* link — you should see an app similar to the screenshot below
+
+
+
+* Click the link (using Alt+Click)
+
+The Factory Workflow UI opens in your browser:
+
+
+
+### Task 4: Run the workflow
+
+Click the *Trigger Anomaly* button. In the frontend, watch the *Agent Workflow* panel as the workflow progresses through:
+
+* **Anomaly Classification Agent**
+* **Fault Diagnosis Agent**
+* **Repair Planner Agent**
+* **Maintenance Scheduler Agent**
+* **Parts Ordering Agent**
+
+
+
+You should see steps move through states (queued/working/done/error). You can expand the tool call details and agent output:
+
+
+
+When finished, you should see something similar to this:
+
+
+
+### Task 5: View the dashboard
+
+Aspire includes a dashboard to observe running services.
+
+* In the Aspire output, click the *dashboard* link (using Alt+Click)
+
+
+
+The dashboard starts in your browser and shows the resources:
+
+
+
+* Click *Console* to see the invocation chain in the workflow
+
+
+
+* Click *Traces* to see call duration details
+
+
+
+🎉 Congratulations! You've successfully completed the final challenge.
+
+## 🚀 Go Further
+
+> [!NOTE]
+> Finished early? These tasks are **optional** extras for exploration.
+
+++i6=<*ir&!rxNK-h`YpGm&SU=$+aTzDC+T?9CWP0
zu03+TYnLs?sm^c1pdkcm509w5makvbDq!0{VzppPW(Ooe7I|)7qmv;bHb$Vbi5q00
zRGERAQZRH>$7FhVuxa~c>^b9Px*bT12p}T5UIPT8-$cp~C6wvYeTA^|iN2g+X`~B-
zRg?4GNQ+CEUXuv}tp%%9AB8&s(kuh@EVihV v82fs)z%i_K9b9~OiU`Jf*bPDXHbvZ&tgbviD>q@EvLv9Z~>%@|u*
z`sOmLCJv1dJ@bHvn*Xd(zF_1KnM8%oiT2Ps4nF7n{7e@I4*F(pRc^{ZtbK3;0v6z
zWwF{g`OHk75sG5`@Ri^$Xe88q4DEsOmQaI-GkZ%))W=@|>Y}hK4Ab-JVsyu`nQy-?
zx?9mB08%?ZV-%`J4F^+bg>m&b1wpOWS9~>-IhZ(9sx_;@cb73q0;4^Dwg
i%8_QokCYC+1>0ay_}n9C(u4cDwe3jw(pRQJbwNTud?a|FUB
zMe@N3ps-0rvGc_n>4-JKmWcHnN#$J#5aEo*(-Z@Uq*ue0Nk;H^_u2EF=X%l=Vj1as
zJCI?Z4_0JNHU$Xc9+WH=OOhRgCe);EwE6#46>zJkYPXySL}Vh?gf^yI{7Ew_%0&~l
z6sLf4$*FXj399_&1;gAjCoNeMttBVd9Y>C`kjN
@o9p)CX7+gmfp_S)
zkC^SrP_1U>Y!lg0^CwJXUT>gJs6mtNm^uX_opJ}u0@m&42pPAyG$w(vd
zU&;DN%9Vbb80sY6>E-9-7W^7QKWQ1
b6oO*Kt%KAgbVx4{RN#ZHlivQeB2!?)wl-!2t^8VjXRx)ZlczMfecu5P
z!MXFt^V6^1>8hE<(WUkkQ!@1N3sjEzG}7iVZOo9rRF8-As_>q
d}5>Qz8OsplE-w+XdTcs7`Lj8sc|3UqHl)C1Z-yUx#1;gJc-
z*F8DF{YcRjQbIcrgPojSOvx-{dGYSu