@@ -697,24 +697,20 @@ jobs:
697697
698698 // Prompt for customer impact data if not a simple question
699699 if (issueType === 'needs-investigation' || issueType === 'feature-request') {
700- const bodyLower = (issue.body || '').toLowerCase();
701- // Tightened regex: require "affected" or "impacted" to appear with the number
702- // This avoids false positives like "Android 14 device"
703- const hasImpactInfo = /\d+\s*(?:device|user|customer)s?\s+(?:affected|impacted)/i.test(issue.body || '') ||
704- /(?:affected|impacted)[^\d]*\d+\s*(?:device|user|customer)/i.test(issue.body || '') ||
705- bodyLower.includes('p0') || bodyLower.includes('p1') ||
706- bodyLower.includes('codered') || bodyLower.includes('high priority');
700+ // Use simple check - just look for any number that might indicate impact
701+ // AI will do the real analysis in PING-COPILOT responses
702+ const hasAnyNumber = /\d{2,}/.test(issue.body || '');
703+ const hasPriorityKeyword = (issue.body || '').toLowerCase().includes('p0') ||
704+ (issue.body || '').toLowerCase().includes('p1') ||
705+ (issue.body || '').toLowerCase().includes('priority');
707706
708- if (!hasImpactInfo ) {
707+ if (!hasAnyNumber && !hasPriorityKeyword ) {
709708 response += `### 📊 Help Us Prioritize\n\n`;
710709 response += `To help the team prioritize this issue, please provide information about customer impact:\n\n`;
711710 response += `\`\`\`\n`;
712711 response += `PING-COPILOT: We have <number> devices/users affected by this issue\n`;
713712 response += `\`\`\`\n\n`;
714- response += `Or if this is blocking production or critical scenarios:\n`;
715- response += `\`\`\`\n`;
716- response += `PING-COPILOT: This is a production-blocking/critical issue affecting <specific impact details>\n`;
717- response += `\`\`\`\n\n`;
713+ response += `The AI will analyze your impact information and apply the appropriate priority label based on device count thresholds.\n\n`;
718714 response += `---\n\n`;
719715 }
720716 }
@@ -775,7 +771,7 @@ jobs:
775771 core.setOutput('has_request', 'false');
776772 }
777773
778- - name : Detect Customer Impact and Apply Priority
774+ - name : Detect Customer Impact with AI
779775 if : steps.extract_request.outputs.has_request == 'true'
780776 id : detect_impact
781777 uses : actions/github-script@v7
@@ -785,55 +781,131 @@ jobs:
785781 script : |
786782 const userRequest = process.env.USER_REQUEST;
787783 const issue = context.payload.issue;
788- const requestLower = userRequest.toLowerCase();
789784
790- // Detect customer impact indicators
785+ // Use AI to detect customer impact from the user's request
786+ // Focus on device count as primary indicator, as per guidelines
791787 let priorityLevel = null;
792788 let impactReason = '';
789+ let deviceCount = null;
793790
794- // Check for numeric impact (devices/users)
795- const deviceMatch = userRequest.match(/(\d+)\s*(device|user|customer|install|affected|impacted)/i);
796- if (deviceMatch) {
797- const count = parseInt(deviceMatch[1], 10);
798- if (count >= 10000) {
791+ try {
792+ // Construct AI prompt to extract impact information
793+ const impactPrompt = "Analyze the following text and extract customer impact information. " +
794+ "Focus on finding the NUMBER of devices or users affected. " +
795+ "Respond with ONLY a JSON object in this format: " +
796+ '{"deviceCount": <number or null>, "hasExplicitPriority": <boolean>, "explicitPriority": "<p0|p1|null>"}. ' +
797+ "Examples:\n" +
798+ '- "We have 500 devices affected" → {"deviceCount": 500, "hasExplicitPriority": false, "explicitPriority": null}\n' +
799+ '- "This is a p0 issue" → {"deviceCount": null, "hasExplicitPriority": true, "explicitPriority": "p0"}\n' +
800+ '- "Critical question about config" → {"deviceCount": null, "hasExplicitPriority": false, "explicitPriority": null}\n' +
801+ "Text to analyze: " + userRequest;
802+
803+ const response = await github.request('POST /models/chat/completions', {
804+ model: 'gpt-4o-mini',
805+ messages: [
806+ {
807+ role: 'system',
808+ content: 'You are a data extraction assistant. Extract impact information and respond with only valid JSON. No explanations, just JSON.'
809+ },
810+ {
811+ role: 'user',
812+ content: impactPrompt
813+ }
814+ ],
815+ temperature: 0.1,
816+ max_tokens: 200
817+ });
818+
819+ const aiResult = response.data.choices[0].message.content.trim();
820+ console.log('AI impact detection result:', aiResult);
821+
822+ // Parse AI response
823+ const extracted = JSON.parse(aiResult);
824+ deviceCount = extracted.deviceCount;
825+
826+ // Apply priority based on device count (primary method)
827+ if (deviceCount !== null && deviceCount > 0) {
828+ if (deviceCount >= 10000) {
829+ priorityLevel = 'p0-CodeRed';
830+ impactReason = `${deviceCount} devices/users affected`;
831+ } else if (deviceCount >= 1000) {
832+ priorityLevel = 'p1-High';
833+ impactReason = `${deviceCount} devices/users affected`;
834+ } else if (deviceCount >= 300) {
835+ priorityLevel = 'p2-Medium';
836+ impactReason = `${deviceCount} devices/users affected`;
837+ } else if (deviceCount >= 100) {
838+ priorityLevel = 'p3-Low';
839+ impactReason = `${deviceCount} devices/users affected`;
840+ } else {
841+ priorityLevel = 'p4-Minor';
842+ impactReason = `${deviceCount} devices/users affected`;
843+ }
844+ }
845+
846+ // Check for explicit priority mentions (secondary method)
847+ if (extracted.hasExplicitPriority && extracted.explicitPriority) {
848+ const explicitPri = extracted.explicitPriority.toLowerCase();
849+ if (explicitPri === 'p0' || explicitPri === 'codered') {
850+ priorityLevel = 'p0-CodeRed';
851+ if (!impactReason) impactReason = 'Customer explicitly requested priority p0/CodeRed';
852+ } else if (explicitPri === 'p1') {
853+ if (!priorityLevel || priorityLevel === 'p2-Medium' || priorityLevel === 'p3-Low' || priorityLevel === 'p4-Minor') {
854+ priorityLevel = 'p1-High';
855+ if (!impactReason) impactReason = 'Customer explicitly requested priority p1/High';
856+ }
857+ }
858+ }
859+
860+ } catch (error) {
861+ console.log('AI impact detection failed, using fallback regex:', error.message);
862+
863+ // Fallback to simple regex if AI fails
864+ const deviceMatch = userRequest.match(/(\d+)\s*(device|user|customer|install|affected|impacted)/i);
865+ if (deviceMatch) {
866+ const count = parseInt(deviceMatch[1], 10);
867+ deviceCount = count;
868+
869+ if (count >= 10000) {
870+ priorityLevel = 'p0-CodeRed';
871+ impactReason = `${count} ${deviceMatch[2]}s affected`;
872+ } else if (count >= 1000) {
873+ priorityLevel = 'p1-High';
874+ impactReason = `${count} ${deviceMatch[2]}s affected`;
875+ } else if (count >= 300) {
876+ priorityLevel = 'p2-Medium';
877+ impactReason = `${count} ${deviceMatch[2]}s affected`;
878+ } else if (count >= 100) {
879+ priorityLevel = 'p3-Low';
880+ impactReason = `${count} ${deviceMatch[2]}s affected`;
881+ } else if (count > 0) {
882+ priorityLevel = 'p4-Minor';
883+ impactReason = `${count} ${deviceMatch[2]}s affected`;
884+ }
885+ }
886+
887+ // Check for explicit priority mentions
888+ if (requestLower.includes('p0') || requestLower.includes('codered')) {
799889 priorityLevel = 'p0-CodeRed';
800- impactReason = `${count} ${deviceMatch[2]}s affected`;
801- } else if (count >= 1000) {
890+ if (!impactReason) impactReason = 'Customer explicitly requested priority p0/CodeRed';
891+ }
892+
893+ if (!priorityLevel && (requestLower.includes('p1') || requestLower.includes('high priority'))) {
802894 priorityLevel = 'p1-High';
803- impactReason = `${count} ${deviceMatch[2]}s affected`;
804- } else if (count >= 300) {
805- priorityLevel = 'p2-Medium';
806- impactReason = `${count} ${deviceMatch[2]}s affected`;
807- } else if (count >= 100) {
808- priorityLevel = 'p3-Low';
809- impactReason = `${count} ${deviceMatch[2]}s affected`;
810- } else if (count > 0) {
811- priorityLevel = 'p4-Minor';
812- impactReason = `${count} ${deviceMatch[2]}s affected`;
895+ if (!impactReason) impactReason = 'High priority issue reported';
813896 }
814897 }
815898
816- // Check for explicit p0-CodeRed indicators (always set p0-CodeRed if detected, as it should override other priorities)
817- // Restrict to explicit priority mentions to avoid false positives from general urgency words
818- if (requestLower.includes('p0') || requestLower.includes('codered')) {
819- priorityLevel = 'p0-CodeRed';
820- if (!impactReason) impactReason = 'Customer explicitly requested priority p0/CodeRed';
821- }
822-
823- // Check for p1-High indicators (only if no higher priority already set)
824- if (!priorityLevel && (requestLower.includes('p1') || requestLower.includes('high') ||
825- requestLower.includes('major'))) {
826- priorityLevel = 'p1-High';
827- if (!impactReason) impactReason = 'High priority issue reported';
828- }
829-
830899 core.setOutput('has_impact', priorityLevel ? 'true' : 'false');
831900 core.setOutput('priority_level', priorityLevel || '');
832901 core.setOutput('impact_reason', impactReason);
902+ core.setOutput('device_count', deviceCount !== null ? deviceCount.toString() : '');
833903
834904 if (priorityLevel) {
835905 console.log(`Customer impact detected: ${priorityLevel} - ${impactReason}`);
836906 }
907+
908+ }
837909
838910 - name : Apply Priority Label
839911 if : steps.detect_impact.outputs.has_impact == 'true'
@@ -931,6 +1003,7 @@ jobs:
9311003 HAS_IMPACT : ${{ steps.detect_impact.outputs.has_impact }}
9321004 PRIORITY_LEVEL : ${{ steps.detect_impact.outputs.priority_level }}
9331005 IMPACT_REASON : ${{ steps.detect_impact.outputs.impact_reason }}
1006+ DEVICE_COUNT : ${{ steps.detect_impact.outputs.device_count }}
9341007 COPILOT_INSTRUCTIONS : ${{ steps.fetch_guidance.outputs.copilot_instructions }}
9351008 COMMON_ISSUES : ${{ steps.fetch_guidance.outputs.common_issues }}
9361009 with :
@@ -939,6 +1012,7 @@ jobs:
9391012 const hasImpact = process.env.HAS_IMPACT === 'true';
9401013 const priorityLevel = process.env.PRIORITY_LEVEL;
9411014 const impactReason = process.env.IMPACT_REASON;
1015+ const deviceCount = process.env.DEVICE_COUNT;
9421016 const copilotInstructions = process.env.COPILOT_INSTRUCTIONS;
9431017 const commonIssues = process.env.COMMON_ISSUES;
9441018 const issue = context.payload.issue;
@@ -1007,6 +1081,7 @@ jobs:
10071081 "Title: " + issueTitle + "\n" +
10081082 "Description: " + issueBody + "\n\n" +
10091083 "User Question: " + sanitizedUserRequest + "\n\n" +
1084+ (deviceCount ? "Customer Impact: " + deviceCount + " devices/users affected\n\n" : "") +
10101085 "MSAL Latest Version: " + latestVersion + "\n\n" +
10111086 "Please provide a detailed, helpful response to the user's question based on the guidance documents. Focus on practical solutions and include relevant examples.";
10121087
0 commit comments