Welcome to Challenge 2!
In this challenge, you will create an intelligent Repair Planner Agent using .NET that generates comprehensive repair plans and work orders when faults are detected in tire manufacturing equipment. You'll leverage the @agentplanning GitHub Copilot agent to guide your development and generate production-ready code.
Expected Duration: 30 minutes
Prerequisites: Challenge 0 successfully completed
Tip
If you hit PermissionDenied, auth errors, or missing environment variables:
- Run
az login --use-device-code - Re-load env vars with
export $(cat ../.env | xargs) - If roles were just assigned, wait 5-10 minutes and run both commands again
The goals for this challenge are:
- Pair program with GitHub Copilot
- Create a .NET Agent using the Foundry Agents SDK
The Repair Planner Agent is the third component in our 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
- Creates a structured Work Order
You will implement Repair Planner Agent as a .NET application that reads information about Technicians and Parts from Cosmos DB. The final work order is also saved in Cosmos DB.
Mappings between fault β skills and fault β parts are implemented with a static dictionary.
Fault β Required Skills
- `curing_temperature_excessive` β `tire_curing_press`, `temperature_control`, `instrumentation`, `electrical_systems`, `plc_troubleshooting`, `mold_maintenance` - `curing_cycle_time_deviation` β `tire_curing_press`, `plc_troubleshooting`, `mold_maintenance`, `bladder_replacement`, `hydraulic_systems`, `instrumentation` - `building_drum_vibration` β `tire_building_machine`, `vibration_analysis`, `bearing_replacement`, `alignment`, `precision_alignment`, `drum_balancing`, `mechanical_systems` - `ply_tension_excessive` β `tire_building_machine`, `tension_control`, `servo_systems`, `precision_alignment`, `sensor_alignment`, `plc_programming` - `extruder_barrel_overheating` β `tire_extruder`, `temperature_control`, `rubber_processing`, `screw_maintenance`, `instrumentation`, `electrical_systems`, `motor_drives` - `low_material_throughput` β `tire_extruder`, `rubber_processing`, `screw_maintenance`, `motor_drives`, `temperature_control` - `high_radial_force_variation` β `tire_uniformity_machine`, `data_analysis`, `measurement_systems`, `tire_building_machine`, `tire_curing_press` - `load_cell_drift` β `tire_uniformity_machine`, `load_cell_calibration`, `measurement_systems`, `sensor_alignment`, `instrumentation` - `mixing_temperature_excessive` β `banbury_mixer`, `temperature_control`, `rubber_processing`, `instrumentation`, `electrical_systems`, `mechanical_systems` - `excessive_mixer_vibration` β `banbury_mixer`, `vibration_analysis`, `bearing_replacement`, `alignment`, `mechanical_systems`, `preventive_maintenance`Fault β Required Parts
- `curing_temperature_excessive` β `TCP-HTR-4KW`, `GEN-TS-K400` - `curing_cycle_time_deviation` β `TCP-BLD-800`, `TCP-SEAL-200` - `building_drum_vibration` β `TBM-BRG-6220` - `ply_tension_excessive` β `TBM-LS-500N`, `TBM-SRV-5KW` - `extruder_barrel_overheating` β `EXT-HTR-BAND`, `GEN-TS-K400` - `low_material_throughput` β `EXT-SCR-250`, `EXT-DIE-TR` - `high_radial_force_variation` β (empty array) - `load_cell_drift` β `TUM-LC-2KN`, `TUM-ENC-5000` - `mixing_temperature_excessive` β `BMX-TIP-500`, `GEN-TS-K400` - `excessive_mixer_vibration` β `BMX-BRG-22320`, `BMX-SEAL-DP`GitHub Copilot custom agents in VS Code are reusable, task-specific chat personas. A custom agent bundles (1) a set of instructions (how Copilot should behave) and (2) an allowed set of tools (what Copilot can do). This makes it easy to switch into a consistent βmodeβ (for example, planning vs. implementation) without re-explaining context each time. In a workspace, custom agents are typically defined as .agent.md files under .github/agents.
This repository includes a specialized GitHub Copilot agent called agentplanning that knows:
- Foundry Agents SDK patterns (
Azure.AI.Projects+Microsoft.Agents.AI) - .NET and C# best practices
- Cosmos DB integration
- The faultβskills/parts mappings for this workshop
Follow this workflow when using the agent planner:
- Ask the agent to plan the component architecture
- Request code generation with specific requirements
- Review and refine the generated code
- Ask for improvements or additional features
- Request tests to validate functionality
Important
The outcome depends on which model GitHub Copilot uses. Larger models (GPT-5.2, Claude Sonnet 4.5) may handle more complex prompts. Smaller models work better with focused, single-file requests.
Create a new empty .NET application that will host your agent.
# Navigate to challenge-2 directory
cd challenge-2
# Create a new console application
dotnet new console -n RepairPlanner
# Navigate into project
cd RepairPlanner
Open GitHub Copilot Chat (Ctrl+Shift+I or Cmd+Shift+I) and select the agentplanning agent in the agent dropdown.
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 2
using the Foundry Agents SDK. Can you explain the architecture?
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.
π The agent will generate code similar to this structure
using System.Text.Json.Serialization;
using Newtonsoft.Json;
public sealed class WorkOrder
{
[JsonPropertyName("id")]
[JsonProperty("id")]
public string Id { get; set; } = string.Empty;
// ... more properties
}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.
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.
π The agent will generate code similar to this:
using Microsoft.Azure.Cosmos;
using RepairPlannerAgent.Models;
namespace RepairPlannerAgent.Services
{
public class CosmosDbService
{
private readonly CosmosClient _client;
private readonly Container _techniciansContainer;
private readonly Container _partsContainer;
private readonly Container _machinesContainer;
private readonly Container _workOrdersContainer;
public CosmosDbService(string endpoint, string key, string databaseName)
{
_client = new CosmosClient(endpoint, key);
var database = _client.GetDatabase(databaseName);
_techniciansContainer = database.GetContainer("Technicians");
_partsContainer = database.GetContainer("PartsInventory");
_machinesContainer = database.GetContainer("Machines");
_workOrdersContainer = database.GetContainer("WorkOrders");
}
public async Task<List<Technician>> GetAvailableTechniciansWithSkillsAsync(List<string> requiredSkills)
{
// query logic
}
public async Task<List<Part>> GetPartsInventoryAsync(List<string> partNumbers)
{
// query logic
}
public async Task<string> CreateWorkOrderAsync(WorkOrder workOrder)
{
// query logic
}
}
}π¬ 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
π The agent will generate code similar to this:
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Microsoft.Agents.AI;
public sealed class RepairPlannerAgent(
AIProjectClient projectClient,
CosmosDbService cosmosDb,
IFaultMappingService faultMapping,
string modelDeploymentName,
ILogger<RepairPlannerAgent> logger)
{
private const string AgentName = "RepairPlannerAgent";
public async Task EnsureAgentVersionAsync(CancellationToken ct = default)
{
var definition = new PromptAgentDefinition(model: modelDeploymentName)
{
Instructions = "..."
};
await projectClient.Agents.CreateAgentVersionAsync(
AgentName,
new AgentVersionCreationOptions(definition),
ct);
}
public async Task<WorkOrder> PlanAndCreateWorkOrderAsync(DiagnosedFault fault, CancellationToken ct = default)
{
// 1. Get skills/parts from mapping
// 2. Query Cosmos DB
// 3. Build prompt and invoke agent
// 4. Parse and save work order
}
}Finally, let agentplanning 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:
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
Try out your agent.
# Load environment variables
export $(cat ../.env | xargs)
dotnet runExpected Output:
12:34:56 info: RepairPlannerAgent[0] Creating agent 'RepairPlannerAgent' with model 'gpt-4o'
12:34:57 info: RepairPlannerAgent[0] Agent version: abc123
12:34:57 info: RepairPlannerAgent[0] Planning repair for machine-001, fault=curing_temperature_excessive
12:34:58 info: CosmosDbService[0] Found 3 available technicians matching skills
12:34:58 info: CosmosDbService[0] Fetched 2 parts
12:34:58 info: RepairPlannerAgent[0] Invoking agent 'RepairPlannerAgent'
12:35:05 info: Program[0] Saved work order WO-2026-001 (id=xxx, status=new, assignedTo=tech-001)
{
"id": "...",
"workOrderNumber": "WO-2026-001",
"machineId": "machine-001",
"title": "Repair Curing Temperature Issue",
...
}
Once the basic agent works, try adding:
Add priority calculation based on fault severity
Add better error handling for when no technicians are available
Add structured output using AIJsonUtilities.CreateJsonSchema
and ChatResponseFormat.ForJsonSchema for type-safe responses
Problem: Preview API warnings
Add this to your .csproj:
<NoWarn>$(NoWarn);CA2252</NoWarn>Problem: JSON parsing errors with numbers
LLMs sometimes return "60" instead of 60. Use:
NumberHandling = JsonNumberHandling.AllowReadingFromStringProblem: Cosmos DB errors
Ensure you're using both [JsonPropertyName] and [JsonProperty] attributes on models.
Problem: Agent not invoking correctly
Make sure you call EnsureAgentVersionAsync() before PlanAndCreateWorkOrderAsync().
π Congratulations! You've built a Repair Planner Agent in .NET using GitHub Copilot.
Letβs reflect on a few things
We used .NET (C#) in this challenge and Python in the previous one β both are first-class for building agents with modern AI/agent SDKs (including the Foundry Agents SDK patterns used in this workshop). Agent solutions quickly become application development (integration, data access, security, ops), so teams typically choose the language that best fits their existing stack and skills β Python often excels for rapid iteration, while .NET is common in larger enterprises for long-lived, well-governed services.
This repo uses VS Code Copilot customization so the agent behaves consistently during the workshop.
Tip
Using guided agents (clear instructions + constrained tools + repeatable steps) helps avoid βvibe codingβ, where solutions can drift, skip requirements, or become hard to review. A lightweight, guided approach keeps changes aligned with the goal and makes agent output easier to validate.
Whatβs being used in this repo:
This workshop includes a workspace custom agent at agentplanning.agent.md, discovered by VS Code from .github/agents/*.agent.md and selectable from the Copilot Chat Agents dropdown. It also includes workspace-wide custom instructions in copilot-instructions.md, which (when instruction files are enabled) are applied automatically to chat requests to enforce the workshop constraints (SDK choice, pinned package versions, environment variables, etc.).
If you want to expand your knowledge on what weβve covered in this challenge, have a look at the content below:
Next step: Challenge 3 - Maintenance Scheduler & Parts Ordering Agents

