Skip to content

Latest commit

Β 

History

History
452 lines (320 loc) Β· 15.1 KB

File metadata and controls

452 lines (320 loc) Β· 15.1 KB

Challenge 2: Building the Repair Planner Agent with GitHub Copilot

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

🎯 Objective

The goals for this challenge are:

  • Pair program with GitHub Copilot
  • Create a .NET Agent using the Foundry Agents SDK

🧭 Context and Background

Challenge 2 Scenario 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.

Challenge 2 Azure Resources

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`

Using the Custom GitHub Copilot Agent (agentplanning)

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

Agent-driven development workflow

Follow this workflow when using the agent planner:

  1. Ask the agent to plan the component architecture
  2. Request code generation with specific requirements
  3. Review and refine the generated code
  4. Ask for improvements or additional features
  5. Request tests to validate functionality

βœ… Tasks

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.


Task 1: Project Setup

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

Task 2: Create RepairPlanner agent with agentplanning

Open GitHub Copilot Chat (Ctrl+Shift+I or Cmd+Shift+I) and select the agentplanning agent in the agent dropdown.

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 2 
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.
πŸ“‹ 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
}

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.
πŸ“‹ 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 
        }
    }
}

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
πŸ“‹ 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
    }
}

Task 2.6: Create the main program

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

Task 3: Test Your Agent

Try out your agent.

# Load environment variables
export $(cat ../.env | xargs)

dotnet run

Expected 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",
  ...
}

Task 4 (Optional): Enhancements

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

πŸ› οΈ Troubleshooting

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.AllowReadingFromString
Problem: 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().


🧠 Conclusion and reflection

πŸŽ‰ Congratulations! You've built a Repair Planner Agent in .NET using GitHub Copilot.

Let’s reflect on a few things

C# vs Python

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.

GitHub Copilot instructions

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.

GitHub Copilot instructions

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