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.
- package/.claude-flow/queen/queen-memory.db +0 -0
- package/.claude-flow/queen-test/test-memory.db +0 -0
- package/.claude-flow/queen-test/test-memory.db-agents +0 -0
- package/.claude-flow/queen-test/test-memory.db-import +0 -0
- package/.claude-flow/queen-test/test-memory.db-memory +0 -0
- package/.claude-flow/queen-test/test-memory.db-neural +0 -0
- package/CLAUDE.md +111 -8
- package/README.md +117 -50
- package/deploy.sh +366 -0
- package/dist/cli.js +226 -0
- package/dist/cli.js.map +1 -1
- package/dist/mcp/http-transport-wrapper.d.ts +29 -0
- package/dist/mcp/http-transport-wrapper.d.ts.map +1 -0
- package/dist/mcp/http-transport-wrapper.js +318 -0
- package/dist/mcp/http-transport-wrapper.js.map +1 -0
- package/dist/mcp/service-discovery-client.d.ts +83 -0
- package/dist/mcp/service-discovery-client.d.ts.map +1 -0
- package/dist/mcp/service-discovery-client.js +211 -0
- package/dist/mcp/service-discovery-client.js.map +1 -0
- package/dist/mcp/servicenow-deployment-mcp.js +262 -29
- package/dist/mcp/servicenow-deployment-mcp.js.map +1 -1
- package/dist/mcp/servicenow-intelligent-mcp.js +252 -18
- package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -1
- package/dist/mcp/servicenow-operations-mcp.js +274 -46
- package/dist/mcp/servicenow-operations-mcp.js.map +1 -1
- package/dist/orchestration/discovery/service-discovery.d.ts +81 -0
- package/dist/orchestration/discovery/service-discovery.d.ts.map +1 -0
- package/dist/orchestration/discovery/service-discovery.js +808 -0
- package/dist/orchestration/discovery/service-discovery.js.map +1 -0
- package/dist/orchestration/distributed-orchestrator.d.ts +131 -0
- package/dist/orchestration/distributed-orchestrator.d.ts.map +1 -0
- package/dist/orchestration/distributed-orchestrator.js +712 -0
- package/dist/orchestration/distributed-orchestrator.js.map +1 -0
- package/dist/orchestration/distribution/task-distribution-engine.d.ts +53 -0
- package/dist/orchestration/distribution/task-distribution-engine.d.ts.map +1 -0
- package/dist/orchestration/distribution/task-distribution-engine.js +586 -0
- package/dist/orchestration/distribution/task-distribution-engine.js.map +1 -0
- package/dist/orchestration/interfaces/distributed-orchestration.interface.d.ts +606 -0
- package/dist/orchestration/interfaces/distributed-orchestration.interface.d.ts.map +1 -0
- package/dist/orchestration/interfaces/distributed-orchestration.interface.js +65 -0
- package/dist/orchestration/interfaces/distributed-orchestration.interface.js.map +1 -0
- package/dist/orchestration/protocols/mcpx-protocol.d.ts +71 -0
- package/dist/orchestration/protocols/mcpx-protocol.d.ts.map +1 -0
- package/dist/orchestration/protocols/mcpx-protocol.js +668 -0
- package/dist/orchestration/protocols/mcpx-protocol.js.map +1 -0
- package/dist/orchestration/state/distributed-state-manager.d.ts +89 -0
- package/dist/orchestration/state/distributed-state-manager.d.ts.map +1 -0
- package/dist/orchestration/state/distributed-state-manager.js +716 -0
- package/dist/orchestration/state/distributed-state-manager.js.map +1 -0
- package/dist/queen/advanced-integration-test.d.ts +48 -0
- package/dist/queen/advanced-integration-test.d.ts.map +1 -0
- package/dist/queen/advanced-integration-test.js +474 -0
- package/dist/queen/advanced-integration-test.js.map +1 -0
- package/dist/queen/agent-factory.d.ts +40 -0
- package/dist/queen/agent-factory.d.ts.map +1 -0
- package/dist/queen/agent-factory.js +433 -0
- package/dist/queen/agent-factory.js.map +1 -0
- package/dist/queen/index.d.ts +58 -0
- package/dist/queen/index.d.ts.map +1 -0
- package/dist/queen/index.js +79 -0
- package/dist/queen/index.js.map +1 -0
- package/dist/queen/integration-example.d.ts +82 -0
- package/dist/queen/integration-example.d.ts.map +1 -0
- package/dist/queen/integration-example.js +220 -0
- package/dist/queen/integration-example.js.map +1 -0
- package/dist/queen/integration-test.d.ts +72 -0
- package/dist/queen/integration-test.d.ts.map +1 -0
- package/dist/queen/integration-test.js +564 -0
- package/dist/queen/integration-test.js.map +1 -0
- package/dist/queen/mock-mcp-client.d.ts +66 -0
- package/dist/queen/mock-mcp-client.d.ts.map +1 -0
- package/dist/queen/mock-mcp-client.js +297 -0
- package/dist/queen/mock-mcp-client.js.map +1 -0
- package/dist/queen/neural-learning.d.ts +28 -0
- package/dist/queen/neural-learning.d.ts.map +1 -0
- package/dist/queen/neural-learning.js +244 -0
- package/dist/queen/neural-learning.js.map +1 -0
- package/dist/queen/queen-memory.d.ts +25 -0
- package/dist/queen/queen-memory.d.ts.map +1 -0
- package/dist/queen/queen-memory.js +273 -0
- package/dist/queen/queen-memory.js.map +1 -0
- package/dist/queen/run-integration-tests.d.ts +9 -0
- package/dist/queen/run-integration-tests.d.ts.map +1 -0
- package/dist/queen/run-integration-tests.js +28 -0
- package/dist/queen/run-integration-tests.js.map +1 -0
- package/dist/queen/servicenow-queen.d.ts +56 -0
- package/dist/queen/servicenow-queen.d.ts.map +1 -0
- package/dist/queen/servicenow-queen.js +659 -0
- package/dist/queen/servicenow-queen.js.map +1 -0
- package/dist/queen/types.d.ts +58 -0
- package/dist/queen/types.d.ts.map +1 -0
- package/dist/queen/types.js +7 -0
- package/dist/queen/types.js.map +1 -0
- package/dist/version.d.ts +3 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +27 -2
- package/dist/version.js.map +1 -1
- package/docker/base/Dockerfile.base +45 -0
- package/docker/generate-services.js +244 -0
- package/docker/nginx/Dockerfile +71 -0
- package/docker/nginx/consul-template.hcl +64 -0
- package/docker/nginx/healthcheck.sh +178 -0
- package/docker/nginx/nginx.conf +210 -0
- package/docker/nginx/supervisord.conf +57 -0
- package/docker/nginx/templates/upstreams.conf.tpl +48 -0
- package/docker/services/automation-mcp/Dockerfile +32 -0
- package/docker/services/automation-mcp/config/service.json +28 -0
- package/docker/services/automation-mcp/entrypoint.js +51 -0
- package/docker/services/deployment-mcp/Dockerfile +32 -0
- package/docker/services/deployment-mcp/entrypoint.js +51 -0
- package/docker/services/flow-composer-mcp/Dockerfile +32 -0
- package/docker/services/flow-composer-mcp/config/service.json +28 -0
- package/docker/services/flow-composer-mcp/entrypoint.js +51 -0
- package/docker/services/graph-memory-mcp/Dockerfile +32 -0
- package/docker/services/graph-memory-mcp/config/service.json +28 -0
- package/docker/services/graph-memory-mcp/entrypoint.js +51 -0
- package/docker/services/integration-mcp/Dockerfile +32 -0
- package/docker/services/integration-mcp/config/service.json +28 -0
- package/docker/services/integration-mcp/entrypoint.js +51 -0
- package/docker/services/intelligent-mcp/Dockerfile +32 -0
- package/docker/services/intelligent-mcp/config/service.json +28 -0
- package/docker/services/intelligent-mcp/entrypoint.js +51 -0
- package/docker/services/operations-mcp/Dockerfile +32 -0
- package/docker/services/operations-mcp/config/service.json +28 -0
- package/docker/services/operations-mcp/entrypoint.js +51 -0
- package/docker/services/platform-development-mcp/Dockerfile +32 -0
- package/docker/services/platform-development-mcp/config/service.json +28 -0
- package/docker/services/platform-development-mcp/entrypoint.js +51 -0
- package/docker/services/reporting-analytics-mcp/Dockerfile +32 -0
- package/docker/services/reporting-analytics-mcp/config/service.json +28 -0
- package/docker/services/reporting-analytics-mcp/entrypoint.js +51 -0
- package/docker/services/security-compliance-mcp/Dockerfile +32 -0
- package/docker/services/security-compliance-mcp/config/service.json +28 -0
- package/docker/services/security-compliance-mcp/entrypoint.js +51 -0
- package/docker/services/update-set-mcp/Dockerfile +32 -0
- package/docker/services/update-set-mcp/config/service.json +28 -0
- package/docker/services/update-set-mcp/entrypoint.js +51 -0
- package/docker-compose.override.yml +132 -0
- package/docker-compose.prod.yml +340 -0
- package/docker-compose.yml +579 -0
- package/k8s/automation-mcp.yaml +232 -0
- package/k8s/configmap.yaml +237 -0
- package/k8s/deployment-mcp.yaml +232 -0
- package/k8s/flow-composer-mcp.yaml +232 -0
- package/k8s/generate-k8s-manifests.js +453 -0
- package/k8s/graph-memory-mcp.yaml +232 -0
- package/k8s/infrastructure.yaml +456 -0
- package/k8s/ingress.yaml +361 -0
- package/k8s/integration-mcp.yaml +232 -0
- package/k8s/intelligent-mcp.yaml +232 -0
- package/k8s/kustomization.yaml +111 -0
- package/k8s/mcp-services.yaml +2552 -0
- package/k8s/monitoring.yaml +515 -0
- package/k8s/namespace.yaml +80 -0
- package/k8s/operations-mcp.yaml +232 -0
- package/k8s/platform-development-mcp.yaml +232 -0
- package/k8s/rbac.yaml +140 -0
- package/k8s/reporting-analytics-mcp.yaml +232 -0
- package/k8s/security-compliance-mcp.yaml +232 -0
- package/k8s/update-set-mcp.yaml +232 -0
- package/package.json +2 -2
|
@@ -1634,12 +1634,52 @@ class ServiceNowOperationsMCP {
|
|
|
1634
1634
|
};
|
|
1635
1635
|
}
|
|
1636
1636
|
async analyzeUserBehavior(dateFilter) {
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
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
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
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
|
-
|
|
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', `
|
|
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
|
-
|
|
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 (
|
|
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 (
|
|
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 (
|
|
2314
|
+
if (lowerQuery.includes('phone') || lowerQuery.includes('mobile')) {
|
|
2166
2315
|
variations.push('smartphone', 'android', 'samsung', 'pixel');
|
|
2167
2316
|
}
|
|
2168
|
-
|
|
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
|
-
|
|
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 (
|
|
2353
|
+
else if (lowerQuery.includes('laptop')) {
|
|
2176
2354
|
suggestions.push('notebook', 'computer', 'workstation', 'MacBook', 'ThinkPad');
|
|
2177
2355
|
}
|
|
2178
|
-
else if (
|
|
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
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
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;
|