Skip to content

Add note on publishing the agent#29

Closed
jimbanach wants to merge 106 commits intodavebirr:mainfrom
jimbanach:patch-1
Closed

Add note on publishing the agent#29
jimbanach wants to merge 106 commits intodavebirr:mainfrom
jimbanach:patch-1

Conversation

@jimbanach
Copy link
Contributor

Added a note about publishing the agent after creation.

Pull Request

📋 Description

🔗 Related Issues

  • Fixes #
  • Relates to #

🎯 Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🔧 Refactoring (no functional changes)
  • ⚡ Performance improvement
  • 🧪 Test additions or improvements
  • 🚀 CI/CD improvements
  • 🏗️ Infrastructure changes

🧪 Testing

Test Results

  • ✅ All existing tests pass (dotnet test FabrikamTests/)
  • ✅ New tests added for new functionality
  • ✅ Manual testing completed
  • ✅ API endpoints tested (via api-tests.http)
  • ✅ MCP tools tested (via Test-Development.ps1 -McpOnly)
  • ✅ Integration tests pass (Test-Development.ps1 -Verbose)

Test Commands Run

# List the commands you used to test
.\Test-Development.ps1 -Quick
.\Test-Development.ps1 -ApiOnly
.\Test-Development.ps1 -McpOnly
dotnet test FabrikamTests/

📸 Screenshots/Demos

🔧 Technical Details

API Changes

  • New endpoints added
  • Existing endpoints modified
  • Database schema changes
  • DTO/model changes
  • Configuration changes

MCP Changes

  • New MCP tools added
  • Existing tools modified
  • Tool descriptions updated
  • Error handling improved

Infrastructure Changes

  • Azure resource changes
  • GitHub Actions workflow changes
  • Environment configuration changes
  • Port/networking changes

📚 Documentation

  • Code is self-documenting with clear method/class names
  • XML documentation comments added/updated
  • README.md updated (if needed)
  • API documentation updated (if needed)
  • MCP tool descriptions are clear and helpful

✅ Quality Checklist

  • Code follows the project's coding standards
  • Async/await patterns used consistently
  • Proper error handling implemented
  • Structured logging added where appropriate
  • No hardcoded values (using configuration)
  • Security considerations addressed
  • Performance impact considered
  • Backward compatibility maintained (or breaking changes documented)

🚀 Deployment Considerations

  • Changes are compatible with Azure App Service deployment
  • Environment variables/configuration documented
  • Database migration needed (if applicable)
  • No impact on existing production data
  • Rollback plan considered

👥 Review Notes

📋 Post-Merge Tasks

  • Update production configuration
  • Monitor deployment logs
  • Update project documentation
  • Notify stakeholders

Reviewer Guidelines:

  • 🔍 Check that all tests pass
  • 📖 Verify code follows project standards
  • 🧪 Test the changes locally if possible
  • 💭 Consider the impact on other developers
  • 🚀 Ensure production readiness

davebirr and others added 30 commits October 29, 2025 12:09
…leshooting

✅ Native user provisioning complete (20 proctors created)
- Add Provision-WorkshopUsers-REST.ps1 (REST API provisioning, bypasses Graph SDK)
- Add workshop-user-mapping.csv (fictitious persona mappings - NO PASSWORDS)
- Fix participant-assignments.csv (Júlia UPN: JúliaR→JuliaR, special char fix)

�� Email templates for credential distribution
- Add proctor-credential-email.md (Teams chat password delivery workaround)
- Add proctor-test-drive-email.md (MCP validation with full agent instructions)

🔧 Troubleshooting documentation
- Add SHARED-CONNECTOR-PERMISSIONS-FIX.md (403 errors, Azure AD sync timing)

📜 Additional infrastructure scripts
- Add Provision-Complete.ps1, Provision-WorkshopB2B.ps1, Provision-WorkshopTenant.ps1
- Add Remove-WorkshopResources.ps1, Setup-MCP-ServicePrincipal.ps1, Test-WorkshopReadiness.ps1

🔒 Security updates
- Update .gitignore to exclude workshop-user-credentials.csv (contains passwords)
- Update .gitignore to exclude proctor-mail-merge.csv (contains real emails)

All real-world issues documented: Email security blocks, 403 connector errors,
provisioning delays, Azure AD sync lag. Ready to scale to 117 participants.
✨ New Features:
- Added POST /api/SupportTickets endpoint (create tickets)
- Added PATCH /api/SupportTickets/{id}/status endpoint (update status/priority/assignment)
- Added POST /api/SupportTickets/{id}/notes endpoint (add notes)
- Enabled GetSupportTickets MCP tool with JsonDocument approach
- Added CreateSupportTicket MCP tool for escalation scenarios
- Added UpdateTicketStatus MCP tool
- Added AddTicketNote MCP tool

🔧 Configuration:
- Set Authentication:Mode to Disabled for workshop environment
- Updated API to use GUID-based user tracking

🧪 Testing:
- Added comprehensive Test-SupportTickets.ps1 script
- Added support ticket tests to api-tests.http
- All endpoints tested and working

📝 Documentation:
- Support ticket API requests in api-tests.http
- Test script with examples for all new endpoints

This completes the core functionality needed for the beginner customer service challenge.
Workshop participants can now:
- Query support tickets (find open/urgent issues)
- View ticket details (customer info, order details, notes)
- Create tickets (escalate complex issues)
- Update status (mark in-progress, resolved)
- Add notes (document resolution steps)
✨ Enhanced Seed Data:
- Added 45 new customers across 12 demographic categories
  (Young Professionals, Growing Families, Empty Nesters, Investors, Business Owners,
   Rural/Agricultural, Urban Professionals, International, Military, First Responders,
   Healthcare, Educators)
- Expanded orders from 15 to 75 with realistic scenarios
- Improved support tickets from 20 to 60 with detailed categories
- Added 3 new products (Smart Home, Hardwood Flooring, Energy Efficiency packages)
- Implemented realistic status distribution based on order age
- Added progressive tax rates by state
- Enhanced shipping logic based on order value
- Added realistic delivery timelines
- More detailed support ticket scenarios per category
- Realistic support agent assignments

📚 Workshop Documentation:
- Workshop tenant access guide
- MCP connector B2B setup documentation
- MCP connector quick fix guide
- Microsoft attendees roster
- Participant quickstart guide
- Team roster

🚀 Deployment Infrastructure:
- Full-stack deployment workflow
- Service principal configuration for GitHub Actions
- November 6 sprint progress tracking
- Remove 30-day default filter from GetOrders tool (FabrikamSalesTools.cs)
- Remove default status filter from GetSupportTickets tool (FabrikamCustomerServiceTools.cs)
- Update tool descriptions to clarify 'returns ALL items' behavior
- Extend orders.json from 46 to 58 orders (added Sep-Nov 2025 data)
- Extend supporttickets.json from 30 to 40 tickets (added Sep-Nov 2025 data)
- Add comprehensive documentation for troubleshooting and changes

Fixes production issue where get_orders returned 0 results due to hidden date filtering.
Enables historical data queries (5-10+ years) and provides fresh demo data for workshops.
… MCP sessions

- Add Microsoft.AspNetCore.DataProtection 9.0.0 package
- Add Microsoft.AspNetCore.DataProtection.Extensions 9.0.0 package
- Configure Data Protection in Program.cs to enable stateless HTTP sessions
- Fixes Copilot Studio sequential tool call failures (error -32001)

This implements the solution from modelcontextprotocol/csharp-sdk#814
Without Data Protection, MCP sessions are stateful but stored in-memory only,
causing 'Session not found' errors when Copilot Studio sends session IDs
from previous requests that are no longer in memory.

With Data Protection enabled, the MCP library can maintain session state
across HTTP requests using encrypted cookies/tokens, allowing stateless
operation compatible with load balancers and multi-instance deployments.
…e challenge

- Created example solution (beginner-customer-service-example.md):
  * Copilot Studio configuration and system prompt
  * Three conversation scenarios (30pt, 60pt, 100pt)
  * Tool usage patterns and error handling
  * Detailed scoring breakdown

- Created proctor guide (beginner-customer-service-proctor-guide.md):
  * Detailed scoring rubric with evaluation criteria
  * Three-level progressive hint system
  * Testing protocol and validation scenarios
  * Common mistakes and troubleshooting
  * Evaluation examples with feedback templates

These materials support facilitators and participants in the 90-120 minute
beginner customer service challenge, providing both a reference implementation
and comprehensive evaluation framework.
…r service guidance

Major improvements:
1. Added orderNumber parameter to get_orders tool
   - Accepts order numbers like 'FAB-2025-047' directly
   - Searches through orders to find matching order number
   - Returns detailed order info just like orderId parameter
   - Fixes Copilot Studio issue where it tried to pass orderNumber as Record

2. Enhanced order detail responses for better customer service
   - Added status-specific guidance (Pending, InProduction, Shipped, Delivered)
   - Shows days since order placed
   - Displays estimated timelines based on status
   - Added 'Need Help?' section with support ticket guidance
   - Includes estimated completion times for in-production orders
   - Shows delivery tracking information for shipped orders

3. Updated tool descriptions and documentation
   - Updated tool description to mention orderNumber parameter
   - Fixed MCP tool names in README (update_ticket_status, add_ticket_note)
   - Updated workshop example with correct tool names

These changes make the tool more intuitive for AI agents like Copilot Studio,
which naturally extract order numbers from customer messages and now can use
them directly without requiring numeric IDs.
Created new microservice in monorepo to solve static seed data problem
and make workshops feel dynamic.

Features:
- OrderProgressionWorker: Moves orders through lifecycle stages
  * Pending (3-5 days) -> InProduction (30 days) -> Shipped (10 days) -> Delivered
  * Configurable intervals and thresholds with randomization
  * Fixes issue where Sep 2 orders still Pending on Oct 29

- OrderGeneratorWorker: Creates new customer orders
  * 1-3 orders per hour (configurable)
  * Randomly selects existing customers and products
  * Realistic order data generation

- TicketGeneratorWorker: Generates support tickets
  * 1-2 tickets per hour (configurable)
  * 10 realistic scenarios (damage, delivery, billing, etc)
  * Links tickets to recent orders

- SimulatorController: REST API for dashboard integration
  * Start/stop individual simulators
  * Get status and configuration
  * CORS-enabled for web dashboard

Architecture:
- Separate microservice in monorepo alongside Api/Mcp
- Three BackgroundService workers with shared state service
- Configuration-driven intervals and behavior
- HttpClient calls to FabrikamApi for data operations
- Swagger documentation for dashboard developer

Configuration:
- Development: Fast intervals (2-15 min) for testing
- Production: Realistic intervals (5-60 min)
- All simulators enabled by default
- Can be toggled via API without restart

Ready for workshop in 6 days - simple, focused, effective!
- Add RuntimeConfigService for runtime configuration management
- Add StressTestMode toggle (150+ tickets/day vs normal 24-48/day)
- Add stress test configuration to appsettings (5 min intervals, 5-10 tickets)
- Update TicketGeneratorWorker to support dual modes
- Add escalation-worthy ticket scenarios (15% of tickets)
- Add stress test API endpoints: GET/POST /api/simulator/stresstest/*
- Update VS Code task to use Start-Services.ps1 script
- Weighted ticket scenario selection (85% AI-solvable, 15% escalation)

This enables workshop facilitators to demonstrate AI agent value under high support ticket volume.
Complete guide for workshop facilitators on using stress test mode:
- API endpoint reference with examples
- Ticket generation rates (normal vs stress test)
- Workshop usage scenario and timeline
- Monitoring and troubleshooting tips
- Runtime override vs configuration file behavior
Changes based on workshop preparation feedback:
- Remove fork/deployment section - environment is pre-deployed
- Add agent naming guidance (30 char limit + username suggestion)
- Rewrite MCP connection section for both beginners and experienced
  * Clear path for using pre-configured connection
  * Optional path for creating own connection
  * Promotes curiosity and exploration
- Expand topics section with explanation and suggestions (not prescriptive)
- Transform tools section into exploration/learning opportunity
  * Emphasize tool discovery and selective enabling
  * Encourage experimentation
  * Support both beginner and experienced builders

Tone: Welcoming for first-timers, interesting for experienced builders
Aligns proctor reference implementation with beginner challenge changes:
- Update agent name to respect 30 character limit (FabrikamCS-Hero)
- Correct MCP connection location: Tools (not Knowledge Sources)
- Provide both pre-configured and custom connection options
- Add team-specific URL guidance with proctor example
- Note: Exact URL varies by team/environment
- Add Topics section explaining conversation flows
- Update setup notes for pre-deployed environment
- Emphasize tool selection flexibility

Corrections:
- MCP now under Tools in Copilot Studio
- URL format varies by deployment (team-specific)
- Shared connection available for quick start
- Custom connection option for learning
Resolves 'Session not found' errors in Copilot Studio:
- Add AddSession() configuration with 30-minute idle timeout
- Add UseSession() middleware before MCP endpoint mapping
- Keep AddDataProtection() for session encryption
- Remove invalid RequireSession option (not available in SDK 0.4.0-preview.3)
- Set cookie policies for cross-request session persistence

Root cause: First MCP call initializes session, but subsequent calls
failed because session expired or wasn't properly persisted. The 30-minute
timeout and explicit session middleware ensure sessions survive between
Copilot Studio tool calls.

Fixes: -32001 'Session not found' JSON-RPC error after first successful call
Add REST API endpoints to support simulator operations:
- POST /api/orders - Create new orders with items
- PATCH /api/orders/{id}/status - Update order status and dates

These endpoints enable the OrderGenerator and OrderProgression workers
to create and progress orders through their lifecycle.
Session middleware requires IDistributedCache to be registered.
Added AddDistributedMemoryCache() to fix startup crash:
'Unable to resolve service for type IDistributedCache'

This fixes the Azure MCP deployment that crashed after adding
session management in commit c09698f.
MCP servers must be stateless per Microsoft Azure documentation.
The 'Session not found' -32001 error is coming from the MCP SDK,
not ASP.NET Core. Removing session middleware to allow MCP to
handle its own protocol-level session management.

This reverts the session management added in commits c09698f and 63dfcd3.
The MCP SDK will manage its own stateless request handling.
Copilot Studio expects session continuity for MCP protocol handshake
(tool registration, capabilities, schema negotiation), even though
MCP business logic must remain stateless.

Key distinctions:
- Protocol layer: Needs minimal session for capabilities negotiation
- Business logic: Remains fully stateless (no business data in session)
- Session timeout: 10 minutes (protocol only, not long conversations)
- Cookie name: .Fabrikam.McpProtocol (explicit protocol session)

This addresses 'Session not found' -32001 errors on 3rd+ requests
while maintaining stateless business operations per Azure MCP guidelines.

For production multi-instance: Replace AddDistributedMemoryCache()
with Redis (AddStackExchangeRedisCache) for shared protocol state.
Copilot Studio may have longer delays between tool calls than expected.
Increasing from 10 to 30 minutes to accommodate user thinking time
and Copilot Studio's internal processing delays.

This should prevent 'Session not found' -32001 errors during normal
conversational workflows with the MCP server.
API Changes (SupportTicketsController.cs):
- Fixed hardcoded TicketCategory validation (now uses Enum.GetNames)
- Fixed hardcoded TicketStatus validation (now uses Enum.GetNames)
- Fixed hardcoded TicketPriority validation (now uses Enum.GetNames)
- All enum validations now dynamic and self-updating

MCP Tool Changes (FabrikamCustomerServiceTools.cs):
- Enhanced create_support_ticket description to emphasize customerId requirement
- Added parameter descriptions for all fields
- Clarified: must call get_orders first to extract customerId
- Updated default category from 'Other' to 'General' (valid enum value)
- Better guidance on priority levels and category selection

Workshop Example Improvements (beginner-customer-service-example.md):
- Corrected all category values to match actual API enums
- Added explicit customerId extraction instructions
- Updated Pattern 4 with 8-step sequence including customerId extraction
- Enhanced AUTOMATIC TICKET CREATION with customerId guidance
- Updated Topic generation examples with customerId mapping
- Updated Scenario 1 with customerId annotation (from order data)
- All examples now show: customerId: X (from order.customerId)

Valid Categories (Corrected):
- OrderInquiry (not OrderStatus)
- DeliveryIssue ✓
- ProductDefect ✓
- Installation ✓
- Billing ✓
- Technical (not in original docs)
- General (not Other)
- Complaint (not in original docs)

Impact: Fixes 'Customer with ID 0 not found' error by making it clear
agents must extract customerId from order data before creating tickets.
MCP Tool Enhancement (FabrikamCustomerServiceTools.cs):
- Added intelligent customerId lookup when only orderId is provided
- If customerId=0 but orderId is provided, automatically fetch order and extract customerId
- Provides helpful error message if neither customerId nor orderId is provided
- Reduces agent complexity - can create tickets with just orderId now

Logic Flow:
1. Check if customerId is missing (0) but orderId is provided
2. Call GET /api/orders/{orderId} to retrieve order data
3. Extract customerId from order.customerId property
4. Proceed with ticket creation using looked-up customerId
5. If still no customerId, return clear error message

Benefits:
- Fixes 'Customer with ID 0 not found' error
- Makes tool more forgiving - orderId alone is now sufficient
- Reduces cognitive load on Copilot Studio agents
- Maintains backward compatibility (customerId still works)
- Better error messages guide agents to provide required data

Error Handling:
- Clear message: 'Either provide customerId directly, or provide orderId'
- Gracefully handles order lookup failures
- Validates customerId before attempting ticket creation
Created comprehensive branching strategy documentation for Agent-a-thon workshop.

Branch Structure:
- main: Rapid development, continuous commits, auto-deploy to -development
- workshop-stable: Production baseline for 20 team instances, batched updates

Workflow:
- Daily development on main
- Periodic merge to workshop-stable (tested features only)
- Emergency hotfixes via cherry-pick
- Semantic versioning tags for releases

Workshop Timeline:
- Created: 2025-10-31 (4 days before workshop)
- Workshop: Nov 4-5, 2025
- Freeze workshop-stable during event
- Continue main development for post-workshop improvements

Testing Checklist:
- All automated tests passing
- 5+ consecutive MCP calls succeed
- Support ticket creation validated
- Workshop scenarios tested in Copilot Studio

Includes:
- Rollback strategies
- Communication protocol
- Team responsibilities
- Quick reference commands
- Version tagging guidelines
Implements GitHub Actions matrix deployment strategy for 20 workshop team instances.

New Files:
- .github/workflows/deploy-workshop-instances.yml
- docs/deployment/MULTI-INSTANCE-WORKSHOP-DEPLOYMENT.md
- scripts/Provision-Workshop-Instances.ps1

GitHub Actions Workflow (deploy-workshop-instances.yml):
- Matrix deployment to 20 teams × 3 services = 60 instances
- Build once, deploy many strategy
- Parallel deployment (max 10 at a time to avoid rate limits)
- Automated health checks post-deployment
- Selective deployment via workflow_dispatch (deploy specific teams)
- Deployment summary with team URLs
- Estimated deployment time: ~25 minutes for all instances

Infrastructure Provisioning (Provision-Workshop-Instances.ps1):
- Automated Azure resource creation
- Single shared App Service Plan (cost optimization)
- Creates: 1 RG + 1 ASP + 60 App Services
- Per-team configuration (TeamId, API URLs)
- WhatIf mode for dry-run testing
- Error handling and progress reporting

Deployment Strategy Documentation:
- Instance naming: fabrikam-{api|mcp|sim}-team-{01-20}
- Shared App Service Plan for cost efficiency (~\/month)
- Workshop-specific settings (Workshop environment)
- Post-deployment validation scripts
- Team URL generation
- Cleanup procedures

Branch Strategy:
- workshop-stable: Deploys to all 20 team instances
- main: Deploys to -development instances (rapid iteration)
- Batched updates to workshop-stable (1-2x per day)
- Tagged releases (v1.0.0-workshop baseline created)

Cost Optimization:
- Single B2 App Service Plan shared by all instances
- In-memory databases (no Azure SQL)
- Temporary deployment (delete after workshop)
- Total cost: ~\ for 2-day workshop

Timeline:
- Nov 1: Provision infrastructure
- Nov 2: Deploy baseline and freeze
- Nov 4-5: Workshop (no deploys unless critical)
- Nov 6+: Cleanup and merge hotfixes

Ready for: Infrastructure provisioning and GitHub secrets configuration
- Changed from 3 separate ASPs to 1 shared ASP (cost: ~/month vs ~)
- Removed Application Insights (not needed for workshop)
- Removed Log Analytics workspace (workshop-optimized)
- Updated Provision-Workshop-Instances.ps1 for per-team RG deployment
- Maintains same deployment consistency via ARM templates
- All apps (API, MCP, SIM) share single B2 App Service Plan
- Per-team isolation via dedicated resource groups

Workshop-optimized architecture:
- Each team: 1 RG + 1 ASP (B2) + 3 Apps
- Cost per team: ~/month (vs  with 3 separate plans)
- 21 teams total cost: ~/month for 2-day workshop
- Simple cleanup: Delete team RG removes all resources
- Changed all references from 'System Prompt' to 'Instructions'
- Updated README.md, hints.md, and partial-solution.md
- Makes terminology more accessible for beginners
- Aligns with Copilot Studio UI which uses 'Instructions'
- Add note that built-in topics (Goodbye, Greeting, Start Over, Thank you) are fine
- Emphasize focus on Instructions rather than custom topics
- Prevents confusion about deleting default Copilot Studio topics
- Clearer guidance for beginner agent builders
Major improvements for first-time Copilot Studio users:
- Add welcoming message acknowledging this is new for many
- Emphasize 20 proctors available to help
- Set expectation: feeling overwhelmed is normal initially
- Reassure: confidence builds after ~1 hour
- Encourage asking for help without hesitation
- Break down steps into smaller, clearer chunks
- Add 'What you're doing' explanations for each step
- Include visual guidance hints (what you'll see)
- Add quick troubleshooting section for common issues
- Simplify language throughout
- Remove intimidating advanced content from initial view

Goal: Reduce anxiety and increase success for beginners
Major improvements to prevent AI from using order ID instead of customer ID:

1. **Enhanced MCP Tool Schema** (FabrikamSalesTools.cs):
   - Added explicit descriptions in outputSchema for customer.id field
   - Schema now guides: 'use this for customerId parameter, NOT the order ID!'

2. **Step-by-Step Instructions** (full-solution.md):
   - Added numbered extraction steps for getting correct IDs
   - Used actual test scenario (Order 42, Customer 3) as example
   - Multiple WRONG vs CORRECT examples throughout
   - Clear navigation guidance: 'Navigate INTO orderData.customer object'

3. **Visual Clarification** (partial-solution.md):
   - Step-by-step ID extraction process
   - Inline comments showing which ID is which
   - Consistent examples using test scenario data

4. **Updated Test Scenarios** (README.md):
   - Fixed Scenario 1: Uses order FAB-2025-037 (exists in seed data)
   - Fixed Scenario 2: Uses order FAB-2025-042 (Johanna Lorenz, severely delayed)
   - Added explicit customer ID validation in expected behaviors
   - Scenarios now use different orders for better test coverage

Changes address recurring issue where Copilot Studio was extracting
orderData.id (42) instead of orderData.customer.id (3) when calling
create_support_ticket tool.
Scenario 4 improvements to prevent premature ticket creation:

1. **Updated Expected Behavior** (README.md):
   - Added explicit requirement to ASK for order number
   - Added requirement to ASK for damage details
   - Clarified agent must gather info BEFORE creating ticket
   - Added ProductDefect category specification
   - Added 'Key Test' reminder about asking questions

2. **Enhanced Instructions** (full-solution.md):
   - Added new 'GATHER INFORMATION BEFORE TAKING ACTION' section
   - Provides step-by-step process for handling complaints
   - Includes example dialogue showing question-asking pattern
   - Explicit warnings: 'DO NOT assume information from previous conversations'
   - Prevents agent from using context from earlier in chat session

Issue: Agent was creating tickets immediately without asking for
order number or damage details, instead using information from
previous conversation (Johanna Lorenz, FAB-2025-049).

Fix ensures agent follows proper customer service protocol:
Empathize → Ask Questions → Gather Details → Take Action
- Added specific responses for order number and damage details
- Helps testers understand what information to provide when agent asks questions
- Validates information-gathering pattern before ticket creation
- Update GitHub Actions workflow to auto-discover actual app names from resource groups
- Fix Deploy-Workshop-Team.ps1 to use absolute path for ARM template
- Fix Deploy-AllTeamInstances.ps1 to check for actual resources, not just empty RGs
- Update team matrix to include all 25 teams (00-24)
- Change MCP health check to use /status endpoint

This enables CI/CD deployment to all team instances with dynamic naming.
… Power Fx parser

- Changed parenthetical descriptions with colons to dash-separated format
- Fixes InvokeMCP 'Unexpected characters (:)' error in Teams 01-24
- Maintains helpful parameter guidance without Power Fx incompatibility
- Team-00 working because deployed before Nov 5th schema enhancement commit
…atibility

PROBLEM:
- Copilot Studio Power Fx parser treats colons as formula separators
- 'REQUIRED:' and 'Optional:' in parameter descriptions cause parse errors
- Error: 'Unexpected characters. Characters are used in the formula in an unexpected way.' (:)

ROOT CAUSE:
- Oct 31 commits (4aee0e4, 761fcef) added REQUIRED:/Optional: labels
- Team-00 deployed before these commits (works fine)
- Teams 01-24 deployed after these commits (InvokeMCP fails)

FIX:
- Changed 'REQUIRED:' to 'REQUIRED -' (dash instead of colon)
- Changed 'Optional:' to 'Optional -' (dash instead of colon)
- Changed 'IMPORTANT:' to 'IMPORTANT -' in tool descriptions
- Maintains clarity while avoiding Power Fx reserved characters

IMPACT:
- Fixes InvokeMCP failures for all 24 teams in Copilot Studio
- No functional changes, only punctuation in descriptions
- Preserves parameter guidance for AI agents
- Replace colons with dashes in CreateGuidValidationErrorResponse
- Prevents Power Fx parser issues in Copilot Studio
- Changes:
  - 'How to provide GUID:' → 'How to provide GUID -'
  - 'Via parameter:' → 'Via parameter -'
  - 'Via header:' → 'Via header -'
  - 'Expected format:' → 'Expected format -'
  - 'Example:' → 'Example -'

This ensures that if GUID validation errors are ever triggered,
they won't break Copilot Studio schema parsing.
- Created deploy-team-24-main.yml to deploy from main branch
- Updated deploy-workshop-instances.yml to exclude team-24
- Team-24 now deploys from main for latest development testing
- Team-00 and teams 01-23 continue deploying from workshop-stable
- Added CICD-DEPLOYMENT-STRATEGY.md documentation
- Added Authentication__Mode parameter to dashboard app settings in ARM template
- Fixed Dashboard__ServiceGuid format (removed 'dashboard-' prefix)
- Updated Team-24 CI/CD workflow to auto-configure dashboard settings post-deployment
- Updated workshop instances CI/CD workflow with same dashboard configuration
- Created comprehensive deployment strategy documentation

This resolves the dashboard perpetual loading issue where dashboard couldn't
send X-Tracking-Guid header to API due to missing authentication mode setting.
- Changed DataPollingService broadcast log from Debug to Information level
- Added detailed SignalR connection logging in Home.razor
- Added Console.WriteLine for browser console visibility
- Log SignalR connection state, data received, and any errors

This will help diagnose why dashboard isn't displaying data even though
backend is successfully fetching from API every 5 seconds.
…dashboard

- Enable webSocketsEnabled: true in dashboard siteConfig
- Enable clientAffinityEnabled: true for sticky sessions
- Required for Blazor Server SignalR communication per Microsoft docs
- Fixes dashboard perpetual loading issue (SignalR couldn't establish connection)
- Reference: https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/server/#azure-app-service
- Create singleton DashboardStateService to share state across circuits
- Update DataPollingService to use state service instead of just SignalR
- Register state service in Program.cs
- This fixes the issue where Blazor Server components can't use client-side SignalR connections
- Components subscribe to OnDataChanged event instead of creating HubConnection

This solves the dashboard issue: server broadcasts data but clients can't receive it.
Blazor Server components run on the server and share state through services, not SignalR hubs.
- Remove client-side HubConnection creation (doesn't work in Blazor Server)
- Subscribe to DashboardStateService.OnDataChanged event
- Get initial data from CurrentData property
- Components now share state through singleton service
- Fixes dashboard not displaying data: Blazor Server components run on server,
  can't create client-side SignalR connections to their own server

Root cause: Mixing Blazor Server circuit (already uses SignalR) with custom SignalR hub.
Solution: Use Blazor's recommended pattern - shared singleton service with events.
Features:
- New Support Tickets page (/support-tickets route)
- Filtering by status (All, Open, InProgress, Resolved, Closed)
- Filtering by priority (All, Critical, High, Medium, Low)
- Stats cards showing ticket counts by status
- Table view with ticket details (ID, customer, category, subject, priority, status, date)
- Category icons and priority/status badges
- Loading, error, and empty states

Dashboard Integration:
- Enhanced MetricCard component to support optional click handlers
- Made 'Open Tickets' metric clickable, navigates to Support Tickets page
- Added hover effects and arrow indicator for clickable metrics
- Integrated CSS for professional styling

Technical Details:
- Uses SupportTicketListItemDto from FabrikamContracts
- Fetches data via ApiClient.GetSupportTicketsAsync()
- Responsive design with mobile-friendly filters
- Consistent styling with dashboard theme

Aligned with beginner challenge requirements for customer service scenarios.
- Created Orders.razor page with filtering by status and region
- Created orders.css with responsive table styling
- Updated NavMenu to show Orders and Support Tickets instead of Counter/Weather
- Removed sample Counter.razor and Weather.razor pages
- Added orders.css reference to App.razor
- Orders page shows stats cards and filterable table of all orders
- After toggling a simulator worker, immediately fetch fresh status
- Update local dashboard data with new simulator state
- Trigger UI refresh with InvokeAsync(StateHasChanged)
- Increased delay to 1 second to ensure simulator has updated
- Fixes issue where buttons would react but state wouldn't change until next 5s poll
This was the root cause of simulator buttons never working!

Without @rendermode directive, Blazor pages run in static SSR mode where:
- Event handlers don't work (@OnClick does nothing)
- No SignalR connection is established
- Buttons visually react but no code executes on server

Added @rendermode InteractiveServer to:
- Home.razor (dashboard with simulator controls)
- Orders.razor (order filtering page)
- SupportTickets.razor (ticket management page)

This enables full Blazor Server interactivity with working buttons,
real-time updates, and SignalR-based communication.
- Added OnClick handler to Active Orders card (navigates to /orders)
- Added NavigateToOrders() method matching NavigateToSupportTickets() pattern
- Now both Active Orders and Open Tickets cards show pointer cursor and are clickable
- Provides consistent UX across metric cards
@davebirr davebirr self-requested a review November 11, 2025 06:32
davebirr
davebirr previously approved these changes Nov 11, 2025
@jimbanach jimbanach dismissed davebirr’s stale review December 1, 2025 13:45

The merge-base changed after approval.

@jimbanach jimbanach closed this by deleting the head repository Dec 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants