snow-flow 1.1.74 → 1.1.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/.claude-flow/queen/queen-memory.db +0 -0
  2. package/.claude-flow/queen-test/test-memory.db +0 -0
  3. package/.claude-flow/queen-test/test-memory.db-agents +0 -0
  4. package/.claude-flow/queen-test/test-memory.db-import +0 -0
  5. package/.claude-flow/queen-test/test-memory.db-memory +0 -0
  6. package/.claude-flow/queen-test/test-memory.db-neural +0 -0
  7. package/CLAUDE.md +111 -8
  8. package/README.md +117 -50
  9. package/deploy.sh +366 -0
  10. package/dist/cli.js +226 -0
  11. package/dist/cli.js.map +1 -1
  12. package/dist/mcp/http-transport-wrapper.d.ts +29 -0
  13. package/dist/mcp/http-transport-wrapper.d.ts.map +1 -0
  14. package/dist/mcp/http-transport-wrapper.js +318 -0
  15. package/dist/mcp/http-transport-wrapper.js.map +1 -0
  16. package/dist/mcp/service-discovery-client.d.ts +83 -0
  17. package/dist/mcp/service-discovery-client.d.ts.map +1 -0
  18. package/dist/mcp/service-discovery-client.js +211 -0
  19. package/dist/mcp/service-discovery-client.js.map +1 -0
  20. package/dist/mcp/servicenow-deployment-mcp.js +262 -29
  21. package/dist/mcp/servicenow-deployment-mcp.js.map +1 -1
  22. package/dist/mcp/servicenow-intelligent-mcp.js +252 -18
  23. package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -1
  24. package/dist/mcp/servicenow-operations-mcp.js +274 -46
  25. package/dist/mcp/servicenow-operations-mcp.js.map +1 -1
  26. package/dist/orchestration/discovery/service-discovery.d.ts +81 -0
  27. package/dist/orchestration/discovery/service-discovery.d.ts.map +1 -0
  28. package/dist/orchestration/discovery/service-discovery.js +808 -0
  29. package/dist/orchestration/discovery/service-discovery.js.map +1 -0
  30. package/dist/orchestration/distributed-orchestrator.d.ts +131 -0
  31. package/dist/orchestration/distributed-orchestrator.d.ts.map +1 -0
  32. package/dist/orchestration/distributed-orchestrator.js +712 -0
  33. package/dist/orchestration/distributed-orchestrator.js.map +1 -0
  34. package/dist/orchestration/distribution/task-distribution-engine.d.ts +53 -0
  35. package/dist/orchestration/distribution/task-distribution-engine.d.ts.map +1 -0
  36. package/dist/orchestration/distribution/task-distribution-engine.js +586 -0
  37. package/dist/orchestration/distribution/task-distribution-engine.js.map +1 -0
  38. package/dist/orchestration/interfaces/distributed-orchestration.interface.d.ts +606 -0
  39. package/dist/orchestration/interfaces/distributed-orchestration.interface.d.ts.map +1 -0
  40. package/dist/orchestration/interfaces/distributed-orchestration.interface.js +65 -0
  41. package/dist/orchestration/interfaces/distributed-orchestration.interface.js.map +1 -0
  42. package/dist/orchestration/protocols/mcpx-protocol.d.ts +71 -0
  43. package/dist/orchestration/protocols/mcpx-protocol.d.ts.map +1 -0
  44. package/dist/orchestration/protocols/mcpx-protocol.js +668 -0
  45. package/dist/orchestration/protocols/mcpx-protocol.js.map +1 -0
  46. package/dist/orchestration/state/distributed-state-manager.d.ts +89 -0
  47. package/dist/orchestration/state/distributed-state-manager.d.ts.map +1 -0
  48. package/dist/orchestration/state/distributed-state-manager.js +716 -0
  49. package/dist/orchestration/state/distributed-state-manager.js.map +1 -0
  50. package/dist/queen/advanced-integration-test.d.ts +48 -0
  51. package/dist/queen/advanced-integration-test.d.ts.map +1 -0
  52. package/dist/queen/advanced-integration-test.js +474 -0
  53. package/dist/queen/advanced-integration-test.js.map +1 -0
  54. package/dist/queen/agent-factory.d.ts +40 -0
  55. package/dist/queen/agent-factory.d.ts.map +1 -0
  56. package/dist/queen/agent-factory.js +433 -0
  57. package/dist/queen/agent-factory.js.map +1 -0
  58. package/dist/queen/index.d.ts +58 -0
  59. package/dist/queen/index.d.ts.map +1 -0
  60. package/dist/queen/index.js +79 -0
  61. package/dist/queen/index.js.map +1 -0
  62. package/dist/queen/integration-example.d.ts +82 -0
  63. package/dist/queen/integration-example.d.ts.map +1 -0
  64. package/dist/queen/integration-example.js +220 -0
  65. package/dist/queen/integration-example.js.map +1 -0
  66. package/dist/queen/integration-test.d.ts +72 -0
  67. package/dist/queen/integration-test.d.ts.map +1 -0
  68. package/dist/queen/integration-test.js +564 -0
  69. package/dist/queen/integration-test.js.map +1 -0
  70. package/dist/queen/mock-mcp-client.d.ts +66 -0
  71. package/dist/queen/mock-mcp-client.d.ts.map +1 -0
  72. package/dist/queen/mock-mcp-client.js +297 -0
  73. package/dist/queen/mock-mcp-client.js.map +1 -0
  74. package/dist/queen/neural-learning.d.ts +28 -0
  75. package/dist/queen/neural-learning.d.ts.map +1 -0
  76. package/dist/queen/neural-learning.js +244 -0
  77. package/dist/queen/neural-learning.js.map +1 -0
  78. package/dist/queen/queen-memory.d.ts +25 -0
  79. package/dist/queen/queen-memory.d.ts.map +1 -0
  80. package/dist/queen/queen-memory.js +273 -0
  81. package/dist/queen/queen-memory.js.map +1 -0
  82. package/dist/queen/run-integration-tests.d.ts +9 -0
  83. package/dist/queen/run-integration-tests.d.ts.map +1 -0
  84. package/dist/queen/run-integration-tests.js +28 -0
  85. package/dist/queen/run-integration-tests.js.map +1 -0
  86. package/dist/queen/servicenow-queen.d.ts +56 -0
  87. package/dist/queen/servicenow-queen.d.ts.map +1 -0
  88. package/dist/queen/servicenow-queen.js +659 -0
  89. package/dist/queen/servicenow-queen.js.map +1 -0
  90. package/dist/queen/types.d.ts +58 -0
  91. package/dist/queen/types.d.ts.map +1 -0
  92. package/dist/queen/types.js +7 -0
  93. package/dist/queen/types.js.map +1 -0
  94. package/dist/version.d.ts +3 -1
  95. package/dist/version.d.ts.map +1 -1
  96. package/dist/version.js +27 -2
  97. package/dist/version.js.map +1 -1
  98. package/docker/base/Dockerfile.base +45 -0
  99. package/docker/generate-services.js +244 -0
  100. package/docker/nginx/Dockerfile +71 -0
  101. package/docker/nginx/consul-template.hcl +64 -0
  102. package/docker/nginx/healthcheck.sh +178 -0
  103. package/docker/nginx/nginx.conf +210 -0
  104. package/docker/nginx/supervisord.conf +57 -0
  105. package/docker/nginx/templates/upstreams.conf.tpl +48 -0
  106. package/docker/services/automation-mcp/Dockerfile +32 -0
  107. package/docker/services/automation-mcp/config/service.json +28 -0
  108. package/docker/services/automation-mcp/entrypoint.js +51 -0
  109. package/docker/services/deployment-mcp/Dockerfile +32 -0
  110. package/docker/services/deployment-mcp/entrypoint.js +51 -0
  111. package/docker/services/flow-composer-mcp/Dockerfile +32 -0
  112. package/docker/services/flow-composer-mcp/config/service.json +28 -0
  113. package/docker/services/flow-composer-mcp/entrypoint.js +51 -0
  114. package/docker/services/graph-memory-mcp/Dockerfile +32 -0
  115. package/docker/services/graph-memory-mcp/config/service.json +28 -0
  116. package/docker/services/graph-memory-mcp/entrypoint.js +51 -0
  117. package/docker/services/integration-mcp/Dockerfile +32 -0
  118. package/docker/services/integration-mcp/config/service.json +28 -0
  119. package/docker/services/integration-mcp/entrypoint.js +51 -0
  120. package/docker/services/intelligent-mcp/Dockerfile +32 -0
  121. package/docker/services/intelligent-mcp/config/service.json +28 -0
  122. package/docker/services/intelligent-mcp/entrypoint.js +51 -0
  123. package/docker/services/operations-mcp/Dockerfile +32 -0
  124. package/docker/services/operations-mcp/config/service.json +28 -0
  125. package/docker/services/operations-mcp/entrypoint.js +51 -0
  126. package/docker/services/platform-development-mcp/Dockerfile +32 -0
  127. package/docker/services/platform-development-mcp/config/service.json +28 -0
  128. package/docker/services/platform-development-mcp/entrypoint.js +51 -0
  129. package/docker/services/reporting-analytics-mcp/Dockerfile +32 -0
  130. package/docker/services/reporting-analytics-mcp/config/service.json +28 -0
  131. package/docker/services/reporting-analytics-mcp/entrypoint.js +51 -0
  132. package/docker/services/security-compliance-mcp/Dockerfile +32 -0
  133. package/docker/services/security-compliance-mcp/config/service.json +28 -0
  134. package/docker/services/security-compliance-mcp/entrypoint.js +51 -0
  135. package/docker/services/update-set-mcp/Dockerfile +32 -0
  136. package/docker/services/update-set-mcp/config/service.json +28 -0
  137. package/docker/services/update-set-mcp/entrypoint.js +51 -0
  138. package/docker-compose.override.yml +132 -0
  139. package/docker-compose.prod.yml +340 -0
  140. package/docker-compose.yml +579 -0
  141. package/k8s/automation-mcp.yaml +232 -0
  142. package/k8s/configmap.yaml +237 -0
  143. package/k8s/deployment-mcp.yaml +232 -0
  144. package/k8s/flow-composer-mcp.yaml +232 -0
  145. package/k8s/generate-k8s-manifests.js +453 -0
  146. package/k8s/graph-memory-mcp.yaml +232 -0
  147. package/k8s/infrastructure.yaml +456 -0
  148. package/k8s/ingress.yaml +361 -0
  149. package/k8s/integration-mcp.yaml +232 -0
  150. package/k8s/intelligent-mcp.yaml +232 -0
  151. package/k8s/kustomization.yaml +111 -0
  152. package/k8s/mcp-services.yaml +2552 -0
  153. package/k8s/monitoring.yaml +515 -0
  154. package/k8s/namespace.yaml +80 -0
  155. package/k8s/operations-mcp.yaml +232 -0
  156. package/k8s/platform-development-mcp.yaml +232 -0
  157. package/k8s/rbac.yaml +140 -0
  158. package/k8s/reporting-analytics-mcp.yaml +232 -0
  159. package/k8s/security-compliance-mcp.yaml +232 -0
  160. package/k8s/update-set-mcp.yaml +232 -0
  161. package/package.json +2 -2
@@ -1634,12 +1634,52 @@ class ServiceNowOperationsMCP {
1634
1634
  };
1635
1635
  }
1636
1636
  async analyzeUserBehavior(dateFilter) {
1637
- // This would require analyzing user activity across multiple tables
1638
- // For now, return a basic analysis
1639
- return {
1640
- message: 'User behavior analysis requires additional data collection and processing',
1641
- available_metrics: ['login_patterns', 'request_frequency', 'incident_reporting']
1642
- };
1637
+ try {
1638
+ // Query actual user activity data from ServiceNow
1639
+ const activities = [];
1640
+ // Get recent incidents created by users
1641
+ const incidents = await this.client.searchRecords('incident', `sys_created_on>=${dateFilter}^caller_idISNOTEMPTY`, 100);
1642
+ if (incidents.success && incidents.data) {
1643
+ const incidentData = Array.isArray(incidents.data) ? incidents.data : [incidents.data];
1644
+ const userIncidents = new Map();
1645
+ incidentData.forEach(inc => {
1646
+ const userId = inc.caller_id?.value || inc.caller_id;
1647
+ if (userId) {
1648
+ userIncidents.set(userId, (userIncidents.get(userId) || 0) + 1);
1649
+ }
1650
+ });
1651
+ activities.push({
1652
+ metric: 'incident_reporting',
1653
+ total_incidents: incidentData.length,
1654
+ unique_users: userIncidents.size,
1655
+ avg_per_user: userIncidents.size > 0 ? Math.round(incidentData.length / userIncidents.size * 10) / 10 : 0
1656
+ });
1657
+ }
1658
+ // Get service requests
1659
+ const requests = await this.client.searchRecords('sc_request', `sys_created_on>=${dateFilter}^requested_forISNOTEMPTY`, 100);
1660
+ if (requests.success && requests.data) {
1661
+ const requestData = Array.isArray(requests.data) ? requests.data : [requests.data];
1662
+ activities.push({
1663
+ metric: 'request_frequency',
1664
+ total_requests: requestData.length,
1665
+ period: dateFilter
1666
+ });
1667
+ }
1668
+ return {
1669
+ analysis_period: dateFilter,
1670
+ generated_at: new Date().toISOString(),
1671
+ user_activities: activities,
1672
+ summary: `Analyzed ${activities.length} activity metrics for period: ${dateFilter}`,
1673
+ note: 'Analysis based on actual ServiceNow data from incident and request tables'
1674
+ };
1675
+ }
1676
+ catch (error) {
1677
+ return {
1678
+ error: 'User behavior analysis failed',
1679
+ message: error instanceof Error ? error.message : String(error),
1680
+ available_metrics: ['incident_reporting', 'request_frequency']
1681
+ };
1682
+ }
1643
1683
  }
1644
1684
  async calculateKnowledgeRelevance(articles, incident) {
1645
1685
  const relevanceScores = [];
@@ -1661,33 +1701,131 @@ class ServiceNowOperationsMCP {
1661
1701
  return relevanceScores.sort((a, b) => b.relevance_score - a.relevance_score);
1662
1702
  }
1663
1703
  async performPredictiveAnalysis(predictionType, timeframe) {
1664
- // This would require machine learning models and historical data analysis
1665
- // For now, return basic predictions based on current trends
1666
- const currentDate = new Date();
1667
- const predictions = {
1668
- prediction_type: predictionType,
1669
- timeframe: timeframe,
1670
- generated_at: currentDate.toISOString(),
1671
- confidence: 0.7,
1672
- predictions: []
1673
- };
1674
- switch (predictionType) {
1675
- case 'incident_volume':
1676
- predictions.predictions = await this.predictIncidentVolume(timeframe);
1677
- break;
1678
- case 'system_failure':
1679
- predictions.predictions = await this.predictSystemFailure(timeframe);
1680
- break;
1681
- case 'resource_exhaustion':
1682
- predictions.predictions = await this.predictResourceExhaustion(timeframe);
1683
- break;
1684
- case 'user_impact':
1685
- predictions.predictions = await this.predictUserImpact(timeframe);
1686
- break;
1687
- default:
1688
- predictions.predictions = [{ error: 'Unknown prediction type' }];
1704
+ try {
1705
+ const currentDate = new Date();
1706
+ const analysis = {
1707
+ prediction_type: predictionType,
1708
+ timeframe: timeframe,
1709
+ generated_at: currentDate.toISOString(),
1710
+ analysis_method: 'trend_analysis',
1711
+ data_points: []
1712
+ };
1713
+ switch (predictionType) {
1714
+ case 'incident_volume':
1715
+ analysis.data_points = await this.analyzeIncidentTrends(timeframe);
1716
+ analysis.interpretation = 'Based on recent incident creation patterns';
1717
+ break;
1718
+ case 'system_failure':
1719
+ analysis.data_points = await this.analyzeSystemHealthTrends(timeframe);
1720
+ analysis.interpretation = 'Based on critical incident patterns and system health indicators';
1721
+ break;
1722
+ case 'resource_exhaustion':
1723
+ analysis.data_points = await this.analyzeResourceTrends(timeframe);
1724
+ analysis.interpretation = 'Based on request volumes and capacity indicators';
1725
+ break;
1726
+ case 'user_impact':
1727
+ analysis.data_points = await this.analyzeUserImpactTrends(timeframe);
1728
+ analysis.interpretation = 'Based on user-reported incidents and service requests';
1729
+ break;
1730
+ default:
1731
+ analysis.data_points = [{ error: 'Unknown prediction type', supported_types: ['incident_volume', 'system_failure', 'resource_exhaustion', 'user_impact'] }];
1732
+ analysis.interpretation = 'Unsupported analysis type';
1733
+ }
1734
+ return analysis;
1735
+ }
1736
+ catch (error) {
1737
+ return {
1738
+ prediction_type: predictionType,
1739
+ timeframe: timeframe,
1740
+ error: 'Analysis failed',
1741
+ message: error instanceof Error ? error.message : String(error),
1742
+ generated_at: new Date().toISOString()
1743
+ };
1689
1744
  }
1690
- return predictions;
1745
+ }
1746
+ // New trend analysis methods
1747
+ async analyzeIncidentTrends(timeframe) {
1748
+ try {
1749
+ const incidents = await this.client.searchRecords('incident', 'sys_created_onONToday@javascript:gs.daysAgoStart(7)@javascript:gs.daysAgoEnd(0)', 100);
1750
+ if (incidents.success && incidents.data) {
1751
+ const incidentData = Array.isArray(incidents.data) ? incidents.data : [incidents.data];
1752
+ const dailyCounts = new Map();
1753
+ incidentData.forEach(incident => {
1754
+ const date = new Date(incident.sys_created_on).toDateString();
1755
+ dailyCounts.set(date, (dailyCounts.get(date) || 0) + 1);
1756
+ });
1757
+ return Array.from(dailyCounts.entries()).map(([date, count]) => ({
1758
+ date,
1759
+ incident_count: count,
1760
+ trend: count > 5 ? 'increasing' : 'stable'
1761
+ }));
1762
+ }
1763
+ }
1764
+ catch (error) {
1765
+ return [{ error: 'Failed to analyze incident trends', message: String(error) }];
1766
+ }
1767
+ return [{ message: 'No incident data available for analysis' }];
1768
+ }
1769
+ async analyzeSystemHealthTrends(timeframe) {
1770
+ try {
1771
+ const criticalIncidents = await this.client.searchRecords('incident', 'priority=1^sys_created_onONToday@javascript:gs.daysAgoStart(7)@javascript:gs.daysAgoEnd(0)', 50);
1772
+ if (criticalIncidents.success && criticalIncidents.data) {
1773
+ const criticalData = Array.isArray(criticalIncidents.data) ? criticalIncidents.data : [criticalIncidents.data];
1774
+ return [{
1775
+ metric: 'critical_incidents',
1776
+ count: criticalData.length,
1777
+ health_indicator: criticalData.length > 3 ? 'at_risk' : 'stable',
1778
+ recent_issues: criticalData.slice(0, 3).map(inc => inc.short_description)
1779
+ }];
1780
+ }
1781
+ }
1782
+ catch (error) {
1783
+ return [{ error: 'Failed to analyze system health trends', message: String(error) }];
1784
+ }
1785
+ return [{ message: 'No system health data available' }];
1786
+ }
1787
+ async analyzeResourceTrends(timeframe) {
1788
+ try {
1789
+ const requests = await this.client.searchRecords('sc_request', 'sys_created_onONToday@javascript:gs.daysAgoStart(7)@javascript:gs.daysAgoEnd(0)', 100);
1790
+ if (requests.success && requests.data) {
1791
+ const requestData = Array.isArray(requests.data) ? requests.data : [requests.data];
1792
+ return [{
1793
+ metric: 'request_volume',
1794
+ total_requests: requestData.length,
1795
+ resource_pressure: requestData.length > 20 ? 'high' : 'normal',
1796
+ trend: 'stable'
1797
+ }];
1798
+ }
1799
+ }
1800
+ catch (error) {
1801
+ return [{ error: 'Failed to analyze resource trends', message: String(error) }];
1802
+ }
1803
+ return [{ message: 'No resource usage data available' }];
1804
+ }
1805
+ async analyzeUserImpactTrends(timeframe) {
1806
+ try {
1807
+ const userIncidents = await this.client.searchRecords('incident', 'caller_idISNOTEMPTY^sys_created_onONToday@javascript:gs.daysAgoStart(7)@javascript:gs.daysAgoEnd(0)', 100);
1808
+ if (userIncidents.success && userIncidents.data) {
1809
+ const incidentData = Array.isArray(userIncidents.data) ? userIncidents.data : [userIncidents.data];
1810
+ const impactCounts = new Map();
1811
+ incidentData.forEach(incident => {
1812
+ const impact = incident.impact || 'unknown';
1813
+ impactCounts.set(impact, (impactCounts.get(impact) || 0) + 1);
1814
+ });
1815
+ return [{
1816
+ metric: 'user_impact_distribution',
1817
+ high_impact: impactCounts.get('1') || 0,
1818
+ medium_impact: impactCounts.get('2') || 0,
1819
+ low_impact: impactCounts.get('3') || 0,
1820
+ total_affected_users: incidentData.length,
1821
+ impact_trend: (impactCounts.get('1') || 0) > 5 ? 'increasing' : 'stable'
1822
+ }];
1823
+ }
1824
+ }
1825
+ catch (error) {
1826
+ return [{ error: 'Failed to analyze user impact trends', message: String(error) }];
1827
+ }
1828
+ return [{ message: 'No user impact data available' }];
1691
1829
  }
1692
1830
  async predictIncidentVolume(timeframe) {
1693
1831
  // Get historical incident data
@@ -2032,9 +2170,12 @@ class ServiceNowOperationsMCP {
2032
2170
  let categoryFilter = '';
2033
2171
  if (category_filter) {
2034
2172
  // First try to find the category
2035
- const categoryResult = await this.client.searchRecords('sc_category', `name=${category_filter}^ORsys_id=${category_filter}`, 1);
2173
+ const categoryResult = await this.client.searchRecords('sc_category', `nameLIKE${category_filter}^ORtitle=${category_filter}^ORsys_id=${category_filter}`, 10);
2036
2174
  if (categoryResult.success && categoryResult.data?.result?.length > 0) {
2037
- categoryFilter = `^sc_categories=${categoryResult.data.result[0].sys_id}`;
2175
+ // Try to find the most relevant category
2176
+ const exactMatch = categoryResult.data.result.find((c) => c.name.toLowerCase() === category_filter.toLowerCase());
2177
+ const category = exactMatch || categoryResult.data.result[0];
2178
+ categoryFilter = `^sc_categoriesLIKE${category.sys_id}`;
2038
2179
  }
2039
2180
  }
2040
2181
  // Execute searches
@@ -2045,6 +2186,13 @@ class ServiceNowOperationsMCP {
2045
2186
  if (result.success && result.data?.result) {
2046
2187
  result.data.result.forEach((item) => {
2047
2188
  if (!allResults.has(item.sys_id)) {
2189
+ // Filter out items that don't make sense for the search
2190
+ const itemName = (item.name || '').toLowerCase();
2191
+ const itemDesc = (item.short_description || '').toLowerCase();
2192
+ // Skip items that are clearly not what the user is looking for
2193
+ if (this.shouldExcludeItem(query, itemName, itemDesc)) {
2194
+ return;
2195
+ }
2048
2196
  allResults.set(item.sys_id, {
2049
2197
  sys_id: item.sys_id,
2050
2198
  name: item.name,
@@ -2143,8 +2291,9 @@ class ServiceNowOperationsMCP {
2143
2291
  }
2144
2292
  generateSearchVariations(query) {
2145
2293
  const variations = [];
2294
+ const lowerQuery = query.toLowerCase();
2146
2295
  // Handle common product variations
2147
- if (query.toLowerCase().includes('iphone')) {
2296
+ if (lowerQuery.includes('iphone')) {
2148
2297
  // Add variations without spaces, with different numbers
2149
2298
  const baseModel = query.replace(/iphone\s*/i, 'iPhone ');
2150
2299
  variations.push(baseModel);
@@ -2158,33 +2307,112 @@ class ServiceNowOperationsMCP {
2158
2307
  }
2159
2308
  }
2160
2309
  // Handle laptop/computer variations
2161
- if (query.toLowerCase().includes('laptop') || query.toLowerCase().includes('computer')) {
2310
+ if (lowerQuery.includes('laptop') || lowerQuery.includes('computer')) {
2162
2311
  variations.push('notebook', 'macbook', 'thinkpad', 'dell', 'hp');
2163
2312
  }
2164
2313
  // Handle phone variations
2165
- if (query.toLowerCase().includes('phone') || query.toLowerCase().includes('mobile')) {
2314
+ if (lowerQuery.includes('phone') || lowerQuery.includes('mobile')) {
2166
2315
  variations.push('smartphone', 'android', 'samsung', 'pixel');
2167
2316
  }
2168
- return variations;
2317
+ // Handle monitor/display variations
2318
+ if (lowerQuery.includes('monitor') || lowerQuery.includes('display') ||
2319
+ lowerQuery.includes('screen') || lowerQuery.includes('lcd')) {
2320
+ variations.push('monitor', 'display', 'screen', 'lcd', 'led', 'desktop monitor', 'computer monitor', 'external display', 'lcd monitor', 'led monitor', 'dell monitor', 'hp monitor', 'samsung monitor', 'lg monitor');
2321
+ }
2322
+ // Handle desktop/workstation variations
2323
+ if (lowerQuery.includes('desktop') || lowerQuery.includes('workstation')) {
2324
+ variations.push('desktop computer', 'workstation', 'pc', 'desktop pc', 'dell desktop', 'hp desktop', 'lenovo desktop');
2325
+ }
2326
+ // Handle specific hardware terms
2327
+ if (lowerQuery.includes('hardware') || lowerQuery.includes('equipment')) {
2328
+ // Extract specific items from the query
2329
+ const specificItems = [];
2330
+ if (lowerQuery.includes('monitor') || lowerQuery.includes('display') || lowerQuery.includes('screen')) {
2331
+ specificItems.push('monitor', 'display');
2332
+ }
2333
+ if (lowerQuery.includes('desktop')) {
2334
+ specificItems.push('desktop', 'computer');
2335
+ }
2336
+ if (lowerQuery.includes('laptop')) {
2337
+ specificItems.push('laptop', 'notebook');
2338
+ }
2339
+ // If we found specific items, use those instead of generic "hardware"
2340
+ if (specificItems.length > 0) {
2341
+ variations.push(...specificItems);
2342
+ }
2343
+ }
2344
+ // Remove duplicates and empty strings
2345
+ return [...new Set(variations)].filter(v => v && v.length > 0);
2169
2346
  }
2170
2347
  generateSearchSuggestions(query) {
2171
2348
  const suggestions = [];
2172
- if (query.toLowerCase().includes('iphone')) {
2349
+ const lowerQuery = query.toLowerCase();
2350
+ if (lowerQuery.includes('iphone')) {
2173
2351
  suggestions.push('iPhone', 'Apple iPhone', 'iOS device', 'Apple mobile');
2174
2352
  }
2175
- else if (query.toLowerCase().includes('laptop')) {
2353
+ else if (lowerQuery.includes('laptop')) {
2176
2354
  suggestions.push('notebook', 'computer', 'workstation', 'MacBook', 'ThinkPad');
2177
2355
  }
2178
- else if (query.toLowerCase().includes('software')) {
2356
+ else if (lowerQuery.includes('software')) {
2179
2357
  suggestions.push('license', 'application', 'subscription', 'SaaS');
2180
2358
  }
2359
+ else if (lowerQuery.includes('monitor') || lowerQuery.includes('display') ||
2360
+ lowerQuery.includes('screen') || lowerQuery.includes('lcd')) {
2361
+ suggestions.push('monitor', 'display', 'external monitor', 'desktop monitor', 'Dell monitor', 'HP monitor', 'Samsung monitor');
2362
+ }
2363
+ else if (lowerQuery.includes('desktop')) {
2364
+ suggestions.push('desktop computer', 'workstation', 'PC', 'desktop PC', 'Dell desktop', 'HP desktop');
2365
+ }
2366
+ else if (lowerQuery.includes('hardware')) {
2367
+ // For hardware searches, suggest specific item types
2368
+ suggestions.push('monitor', 'keyboard', 'mouse', 'laptop', 'desktop', 'printer', 'scanner', 'docking station', 'headset');
2369
+ }
2181
2370
  else {
2182
- // Generic suggestions
2183
- suggestions.push(query.split(' ')[0], // First word only
2184
- query.substring(0, Math.floor(query.length / 2)), // First half
2185
- 'hardware', 'software', 'equipment', 'device');
2371
+ // Generic suggestions based on the query
2372
+ const words = query.split(' ');
2373
+ if (words.length > 1) {
2374
+ // Try individual words
2375
+ suggestions.push(...words.filter(w => w.length > 3));
2376
+ // Try first and last word
2377
+ suggestions.push(words[0], words[words.length - 1]);
2378
+ }
2379
+ // Add generic category suggestions
2380
+ suggestions.push('hardware', 'software', 'equipment', 'device', 'accessory');
2186
2381
  }
2187
- return [...new Set(suggestions)].filter(s => s && s !== query);
2382
+ return [...new Set(suggestions)].filter(s => s && s !== query && s.length > 0);
2383
+ }
2384
+ shouldExcludeItem(query, itemName, itemDesc) {
2385
+ const lowerQuery = query.toLowerCase();
2386
+ // If searching for hardware/monitors/displays, exclude service/process items
2387
+ if ((lowerQuery.includes('hardware') || lowerQuery.includes('monitor') ||
2388
+ lowerQuery.includes('display') || lowerQuery.includes('screen') ||
2389
+ lowerQuery.includes('desktop') || lowerQuery.includes('equipment')) &&
2390
+ (itemName.includes('decommission') || itemName.includes('service') ||
2391
+ itemName.includes('process') || itemName.includes('request') ||
2392
+ itemName.includes('removal') || itemName.includes('decomm') ||
2393
+ itemDesc.includes('decommission') || itemDesc.includes('service process'))) {
2394
+ return true;
2395
+ }
2396
+ // If searching for specific hardware, exclude unrelated items
2397
+ if (lowerQuery.includes('monitor') || lowerQuery.includes('display') || lowerQuery.includes('screen')) {
2398
+ // Exclude items that are clearly not monitors
2399
+ if ((itemName.includes('server') || itemName.includes('controller') ||
2400
+ itemName.includes('software') || itemName.includes('license') ||
2401
+ itemName.includes('training') || itemName.includes('support')) &&
2402
+ !itemName.includes('monitor') && !itemName.includes('display') &&
2403
+ !itemName.includes('screen')) {
2404
+ return true;
2405
+ }
2406
+ }
2407
+ // If searching for desktops, exclude non-desktop items
2408
+ if (lowerQuery.includes('desktop')) {
2409
+ if ((itemName.includes('mobile') || itemName.includes('phone') ||
2410
+ itemName.includes('tablet') || itemName.includes('service')) &&
2411
+ !itemName.includes('desktop')) {
2412
+ return true;
2413
+ }
2414
+ }
2415
+ return false;
2188
2416
  }
2189
2417
  async handleTestFlowWithMock(args) {
2190
2418
  const { flow_id, create_test_user = true, test_user_data, mock_catalog_items = true, mock_catalog_data, test_inputs = {}, simulate_approvals = true, cleanup_after_test = true } = args;