snow-flow 2.7.1 → 2.7.3

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.
@@ -548,7 +548,8 @@ class ServiceNowMachineLearningMCP {
548
548
  return await this.trainWithStreaming(args);
549
549
  }
550
550
  // For smaller datasets, use the original approach but with optimizations
551
- const incidents = await this.fetchIncidentData(Math.min(sample_size, batch_size * 5), {
551
+ // šŸ”“ CRITICAL FIX: Use full sample_size, not artificially limited amount
552
+ const incidents = await this.fetchIncidentData(sample_size, {
552
553
  query,
553
554
  intelligent_selection,
554
555
  focus_categories
@@ -1091,7 +1092,9 @@ class ServiceNowMachineLearningMCP {
1091
1092
  finalQuery = 'ORDERBYDESCsys_created_on';
1092
1093
  }
1093
1094
  // Use searchRecords for proper authentication handling
1095
+ // šŸ”“ CRITICAL FIX: Use the actual limit parameter, not default of 10
1094
1096
  const response = await this.client.searchRecords('incident', finalQuery, limit);
1097
+ this.logger.info(`Attempting to fetch ${limit} incidents with query: ${finalQuery}`);
1095
1098
  if (!response.success || !response.data?.result) {
1096
1099
  throw new Error('Failed to fetch incident data. Ensure you have read access to the incident table.');
1097
1100
  }
@@ -1450,7 +1453,9 @@ class ServiceNowMachineLearningMCP {
1450
1453
  finalQuery += '^ORDERBYDESCsys_created_on';
1451
1454
  }
1452
1455
  // ServiceNow API supports offset through sysparm_offset
1456
+ // šŸ”“ CRITICAL FIX: Ensure we're using the right limit for batches
1453
1457
  const response = await this.client.searchRecordsWithOffset('incident', finalQuery, limit, offset);
1458
+ this.logger.info(`Fetching batch: limit=${limit}, offset=${offset}, query=${finalQuery}`);
1454
1459
  if (!response.success || !response.data?.result) {
1455
1460
  return [];
1456
1461
  }
@@ -781,8 +781,17 @@ class ServiceNowOperationsMCP {
781
781
  const incidents = await this.client.searchRecords('incident', processedQuery, limit);
782
782
  let result = {
783
783
  total_results: incidents.success ? incidents.data.result.length : 0,
784
- incidents: incidents.success ? incidents.data.result : []
784
+ // šŸ”“ PERFORMANCE FIX: Only include full incident data if specifically requested via fields
785
+ incidents: (fields && fields.length > 0) ? (incidents.success ? incidents.data.result : []) : []
785
786
  };
787
+ // Add basic summary instead of full data for performance
788
+ if (incidents.success && incidents.data.result.length > 0 && (!fields || fields.length === 0)) {
789
+ result.summary = {
790
+ first_incident: incidents.data.result[0].number || 'Unknown',
791
+ sample_categories: [...new Set(incidents.data.result.slice(0, 5).map((inc) => inc.category || 'none'))],
792
+ sample_priorities: [...new Set(incidents.data.result.slice(0, 5).map((inc) => inc.priority || 'none'))]
793
+ };
794
+ }
786
795
  // Add intelligent _analysis if requested
787
796
  if (include__analysis && incidents.success && incidents.data.result.length > 0) {
788
797
  const _analysis = await this.analyzeIncidents(incidents.data.result);
@@ -1096,6 +1105,11 @@ class ServiceNowOperationsMCP {
1096
1105
  processNaturalLanguageQuery(query, context) {
1097
1106
  // Convert natural language to ServiceNow encoded query
1098
1107
  const lowerQuery = query.toLowerCase();
1108
+ // If already a ServiceNow encoded query, return as-is
1109
+ if (query.includes('=') || query.includes('!=') || query.includes('^') || query.includes('LIKE')) {
1110
+ logger_js_1.logger.info(`Using raw ServiceNow query: ${query}`);
1111
+ return query;
1112
+ }
1099
1113
  // Common ServiceNow query patterns
1100
1114
  if (lowerQuery.includes('high priority')) {
1101
1115
  return 'priority=1';
@@ -1109,6 +1123,9 @@ class ServiceNowOperationsMCP {
1109
1123
  if (lowerQuery.includes('closed') || lowerQuery.includes('resolved')) {
1110
1124
  return 'state=6^ORstate=7';
1111
1125
  }
1126
+ if (lowerQuery.includes('all') || lowerQuery === '') {
1127
+ return ''; // Empty query returns all records
1128
+ }
1112
1129
  if (lowerQuery.includes('today')) {
1113
1130
  return 'sys_created_onONToday@javascript:gs.daysAgoStart(0)@javascript:gs.daysAgoEnd(0)';
1114
1131
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-fetch-incidents.d.ts.map
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const servicenow_client_js_1 = require("./utils/servicenow-client.js");
4
+ const logger_js_1 = require("./utils/logger.js");
5
+ // Test fetchIncidentData like the ML MCP does
6
+ async function testFetchIncidents() {
7
+ const logger = new logger_js_1.Logger('FetchIncidentsTest');
8
+ const client = new servicenow_client_js_1.ServiceNowClient();
9
+ console.log('šŸ”„ Testing fetchIncidentData with 2000 samples...');
10
+ // Simulate exactly what the ML MCP fetchIncidentData method does
11
+ const sample_size = 2000;
12
+ const intelligent_selection = true;
13
+ const focus_categories = [];
14
+ const query = '';
15
+ let finalQuery = query;
16
+ // If intelligent selection is enabled and no custom query provided
17
+ if (intelligent_selection && !query) {
18
+ // Build an intelligent query that gets a balanced dataset
19
+ const queries = [];
20
+ // Get mix of recent and older incidents
21
+ queries.push('sys_created_onONLast 6 months');
22
+ // Get mix of priorities
23
+ queries.push('(priority=1^ORpriority=2^ORpriority=3^ORpriority=4)');
24
+ // Get mix of active and resolved
25
+ queries.push('(active=true^ORactive=false)');
26
+ // Focus on specific categories if provided
27
+ if (focus_categories.length > 0) {
28
+ const categoryQuery = focus_categories.map(cat => `category=${cat}`).join('^OR');
29
+ queries.push(`(${categoryQuery})`);
30
+ }
31
+ else {
32
+ // Get diverse categories
33
+ queries.push('categoryISNOTEMPTY');
34
+ }
35
+ // Combine all queries
36
+ finalQuery = queries.join('^');
37
+ logger.info(`Using intelligent query selection: ${finalQuery}`);
38
+ }
39
+ else if (query) {
40
+ logger.info(`Using custom query: ${query}`);
41
+ }
42
+ // Always order by sys_created_on DESC to get most recent first
43
+ if (finalQuery && !finalQuery.includes('ORDERBY')) {
44
+ finalQuery += '^ORDERBYDESCsys_created_on';
45
+ }
46
+ else if (!finalQuery) {
47
+ finalQuery = 'ORDERBYDESCsys_created_on';
48
+ }
49
+ logger.info(`Attempting to fetch ${sample_size} incidents with query: ${finalQuery}`);
50
+ try {
51
+ // šŸ”“ CRITICAL: Use the actual sample_size parameter, not default of 10
52
+ const response = await client.searchRecords('incident', finalQuery, sample_size);
53
+ if (!response.success || !response.data?.result) {
54
+ throw new Error('Failed to fetch incident data. Ensure you have read access to the incident table.');
55
+ }
56
+ logger.info(`āœ… SUCCESS: Fetched ${response.data.result.length} incidents for ML training (requested: ${sample_size})`);
57
+ // Show data distribution like the ML MCP does
58
+ if (response.data.result.length > 0) {
59
+ const categoryDistribution = {};
60
+ const priorityDistribution = {};
61
+ response.data.result.forEach((inc) => {
62
+ const category = inc.category || 'uncategorized';
63
+ const priority = inc.priority || '3';
64
+ categoryDistribution[category] = (categoryDistribution[category] || 0) + 1;
65
+ priorityDistribution[priority] = (priorityDistribution[priority] || 0) + 1;
66
+ });
67
+ logger.info('Data distribution:');
68
+ logger.info(`Categories: ${JSON.stringify(categoryDistribution)}`);
69
+ logger.info(`Priorities: ${JSON.stringify(priorityDistribution)}`);
70
+ // Check if we have enough for training
71
+ if (response.data.result.length >= 100) {
72
+ logger.info('āœ… Sufficient data for ML training (need at least 100 incidents)');
73
+ }
74
+ else {
75
+ logger.warn(`āš ļø Insufficient data for training (need at least 100 incidents, got ${response.data.result.length})`);
76
+ }
77
+ }
78
+ }
79
+ catch (error) {
80
+ logger.error('āŒ fetchIncidentData failed:', error);
81
+ }
82
+ }
83
+ testFetchIncidents().catch(console.error);
84
+ //# sourceMappingURL=test-fetch-incidents.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-incident-access.d.ts.map
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const servicenow_client_js_1 = require("./utils/servicenow-client.js");
4
+ const logger_js_1 = require("./utils/logger.js");
5
+ async function testIncidentAccess() {
6
+ const logger = new logger_js_1.Logger('IncidentAccessTest');
7
+ const client = new servicenow_client_js_1.ServiceNowClient();
8
+ logger.info('Testing incident table access...');
9
+ // Test 1: Empty query (get all)
10
+ try {
11
+ logger.info('Test 1: Fetching ALL incidents with empty query...');
12
+ const allIncidents = await client.searchRecords('incident', '', 10);
13
+ logger.info(`Result: ${allIncidents.success ? 'SUCCESS' : 'FAILED'}`);
14
+ logger.info(`Count: ${allIncidents.data?.result?.length || 0}`);
15
+ if (allIncidents.data?.result?.length > 0) {
16
+ logger.info('Sample incident states:');
17
+ allIncidents.data.result.slice(0, 5).forEach((inc) => {
18
+ logger.info(`- ${inc.number}: state=${inc.state}, active=${inc.active}`);
19
+ });
20
+ }
21
+ }
22
+ catch (error) {
23
+ logger.error('Test 1 failed:', error);
24
+ }
25
+ // Test 2: State not equal to 7
26
+ try {
27
+ logger.info('\nTest 2: Fetching incidents where state!=7...');
28
+ const notClosedIncidents = await client.searchRecords('incident', 'state!=7', 10);
29
+ logger.info(`Result: ${notClosedIncidents.success ? 'SUCCESS' : 'FAILED'}`);
30
+ logger.info(`Count: ${notClosedIncidents.data?.result?.length || 0}`);
31
+ }
32
+ catch (error) {
33
+ logger.error('Test 2 failed:', error);
34
+ }
35
+ // Test 3: Active incidents
36
+ try {
37
+ logger.info('\nTest 3: Fetching active incidents...');
38
+ const activeIncidents = await client.searchRecords('incident', 'active=true', 10);
39
+ logger.info(`Result: ${activeIncidents.success ? 'SUCCESS' : 'FAILED'}`);
40
+ logger.info(`Count: ${activeIncidents.data?.result?.length || 0}`);
41
+ }
42
+ catch (error) {
43
+ logger.error('Test 3 failed:', error);
44
+ }
45
+ // Test 4: All states
46
+ try {
47
+ logger.info('\nTest 4: Checking incident states...');
48
+ const states = ['1', '2', '3', '4', '5', '6', '7', '8'];
49
+ for (const state of states) {
50
+ const stateIncidents = await client.searchRecords('incident', `state=${state}`, 1);
51
+ if (stateIncidents.success && stateIncidents.data?.result?.length > 0) {
52
+ logger.info(`State ${state}: Found incidents`);
53
+ }
54
+ }
55
+ }
56
+ catch (error) {
57
+ logger.error('Test 4 failed:', error);
58
+ }
59
+ // Test 5: User permissions
60
+ try {
61
+ logger.info('\nTest 5: Testing user permissions...');
62
+ const userInfo = await client.get('/api/now/table/sys_user/me');
63
+ logger.info(`Current user: ${userInfo.data?.result?.user_name || 'Unknown'}`);
64
+ logger.info(`Roles: ${userInfo.data?.result?.roles || 'Unknown'}`);
65
+ }
66
+ catch (error) {
67
+ logger.error('Failed to get user info:', error);
68
+ }
69
+ }
70
+ // Run the test
71
+ testIncidentAccess().catch(console.error);
72
+ //# sourceMappingURL=test-incident-access.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-limit-problem.d.ts.map
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const servicenow_client_js_1 = require("./utils/servicenow-client.js");
4
+ const logger_js_1 = require("./utils/logger.js");
5
+ async function testLimitProblem() {
6
+ const logger = new logger_js_1.Logger('LimitTest');
7
+ const client = new servicenow_client_js_1.ServiceNowClient();
8
+ logger.info('Testing incident limits...');
9
+ // Test different limits
10
+ const limits = [10, 50, 100, 500, 1000];
11
+ for (const limit of limits) {
12
+ try {
13
+ logger.info(`\nTesting with limit ${limit}...`);
14
+ const result = await client.searchRecords('incident', 'state!=7', limit);
15
+ logger.info(`Result: ${result.success ? 'SUCCESS' : 'FAILED'}`);
16
+ logger.info(`Requested: ${limit}, Got: ${result.data?.result?.length || 0}`);
17
+ }
18
+ catch (error) {
19
+ logger.error(`Test with limit ${limit} failed:`, error);
20
+ }
21
+ }
22
+ // Test with empty query (should get all incidents)
23
+ try {
24
+ logger.info(`\nTesting all incidents with limit 1000...`);
25
+ const result = await client.searchRecords('incident', '', 1000);
26
+ logger.info(`Result: ${result.success ? 'SUCCESS' : 'FAILED'}`);
27
+ logger.info(`Total incidents found: ${result.data?.result?.length || 0}`);
28
+ if (result.data?.result?.length > 0) {
29
+ const states = new Map();
30
+ const priorities = new Map();
31
+ result.data.result.forEach((inc) => {
32
+ const state = inc.state || 'unknown';
33
+ const priority = inc.priority || 'unknown';
34
+ states.set(state, (states.get(state) || 0) + 1);
35
+ priorities.set(priority, (priorities.get(priority) || 0) + 1);
36
+ });
37
+ logger.info('State distribution:', Object.fromEntries(states));
38
+ logger.info('Priority distribution:', Object.fromEntries(priorities));
39
+ // Count active incidents (state != 6 and state != 7)
40
+ const activeIncidents = result.data.result.filter((inc) => inc.state !== '6' && inc.state !== '7');
41
+ logger.info(`Active incidents (state not 6 or 7): ${activeIncidents.length}`);
42
+ }
43
+ }
44
+ catch (error) {
45
+ logger.error('All incidents test failed:', error);
46
+ }
47
+ // Test what the ML training was actually requesting
48
+ try {
49
+ logger.info(`\nTesting ML training scenario (sample_size 2000)...`);
50
+ const result = await client.searchRecords('incident', 'state!=7', 2000);
51
+ logger.info(`ML training result: ${result.success ? 'SUCCESS' : 'FAILED'}`);
52
+ logger.info(`ML would get: ${result.data?.result?.length || 0} incidents out of requested 2000`);
53
+ }
54
+ catch (error) {
55
+ logger.error('ML training test failed:', error);
56
+ }
57
+ }
58
+ // Run the test
59
+ testLimitProblem().catch(console.error);
60
+ //# sourceMappingURL=test-limit-problem.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-ml-batch-fix.d.ts.map
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const servicenow_client_js_1 = require("./utils/servicenow-client.js");
4
+ const logger_js_1 = require("./utils/logger.js");
5
+ // Test of ML training nu correct batch sizes gebruikt
6
+ async function testMLBatchFix() {
7
+ const logger = new logger_js_1.Logger('MLBatchFixTest');
8
+ const client = new servicenow_client_js_1.ServiceNowClient();
9
+ console.log('šŸ” Testing ML training batch size fix...');
10
+ // Simuleer ML fetchIncidentData methode met verschillende batch sizes
11
+ async function testFetchIncidentData(sample_size, description) {
12
+ logger.info(`\n--- ${description} ---`);
13
+ logger.info(`Requesting ${sample_size} incidents`);
14
+ const intelligent_selection = true;
15
+ const focus_categories = [];
16
+ const query = '';
17
+ let finalQuery = '';
18
+ if (intelligent_selection && !query) {
19
+ const queries = [];
20
+ queries.push('sys_created_onONLast 6 months');
21
+ queries.push('(priority=1^ORpriority=2^ORpriority=3^ORpriority=4)');
22
+ queries.push('(active=true^ORactive=false)');
23
+ queries.push('categoryISNOTEMPTY');
24
+ finalQuery = queries.join('^') + '^ORDERBYDESCsys_created_on';
25
+ }
26
+ try {
27
+ const start = Date.now();
28
+ // šŸ”“ KEY TEST: Use the actual sample_size parameter
29
+ const response = await client.searchRecords('incident', finalQuery, sample_size);
30
+ const duration = Date.now() - start;
31
+ if (response.success) {
32
+ const actualCount = response.data?.result?.length || 0;
33
+ logger.info(`āœ… SUCCESS: Got ${actualCount}/${sample_size} incidents (${duration}ms)`);
34
+ if (actualCount === Math.min(sample_size, 1000)) { // ServiceNow might limit to 1000
35
+ logger.info(`āœ… Correct batch size used`);
36
+ }
37
+ else if (actualCount === 10) {
38
+ logger.error(`āŒ STILL USING DEFAULT LIMIT OF 10!`);
39
+ }
40
+ else {
41
+ logger.info(`ā„¹ļø Got ${actualCount} incidents (might be limited by data available)`);
42
+ }
43
+ return actualCount;
44
+ }
45
+ else {
46
+ logger.error(`āŒ FAILED: Could not fetch incidents`);
47
+ return 0;
48
+ }
49
+ }
50
+ catch (error) {
51
+ logger.error(`āŒ ERROR:`, error);
52
+ return 0;
53
+ }
54
+ }
55
+ // Test verschillende batch sizes
56
+ const testCases = [
57
+ { size: 50, desc: "Small batch (50)" },
58
+ { size: 100, desc: "Medium batch (100)" },
59
+ { size: 200, desc: "Large batch (200)" },
60
+ { size: 500, desc: "XL batch (500)" }
61
+ ];
62
+ console.log(`\n🧪 Testing different batch sizes:`);
63
+ const results = [];
64
+ for (const testCase of testCases) {
65
+ const count = await testFetchIncidentData(testCase.size, testCase.desc);
66
+ results.push({ requested: testCase.size, actual: count });
67
+ }
68
+ console.log(`\nšŸ“Š Batch Size Results:`);
69
+ results.forEach(r => {
70
+ const success = r.actual > 10 && r.actual >= Math.min(r.requested, 100); // At least more than default 10
71
+ console.log(` ${r.requested} requested → ${r.actual} actual ${success ? 'āœ…' : 'āŒ'}`);
72
+ });
73
+ // Test streaming batches
74
+ console.log(`\n🌊 Testing streaming batch functionality:`);
75
+ const totalSample = 300;
76
+ const batchSize = 100;
77
+ const totalBatches = Math.ceil(totalSample / batchSize);
78
+ let streamingTotal = 0;
79
+ for (let batchNum = 0; batchNum < totalBatches; batchNum++) {
80
+ const offset = batchNum * batchSize;
81
+ const currentBatchSize = Math.min(batchSize, totalSample - offset);
82
+ logger.info(`Streaming batch ${batchNum + 1}/${totalBatches}: offset=${offset}, size=${currentBatchSize}`);
83
+ try {
84
+ const response = await client.searchRecordsWithOffset('incident', 'sys_created_onONLast 6 months^categoryISNOTEMPTY^ORDERBYDESCsys_created_on', currentBatchSize, offset);
85
+ if (response.success) {
86
+ const batchActual = response.data?.result?.length || 0;
87
+ streamingTotal += batchActual;
88
+ logger.info(` āœ… Batch got ${batchActual}/${currentBatchSize} incidents`);
89
+ if (batchActual < currentBatchSize) {
90
+ logger.info(` šŸ“‹ End of data reached`);
91
+ break;
92
+ }
93
+ }
94
+ }
95
+ catch (error) {
96
+ logger.error(` āŒ Streaming batch ${batchNum + 1} failed:`, error);
97
+ }
98
+ }
99
+ console.log(`\nšŸŽÆ Streaming Results:`);
100
+ console.log(` Total streamed: ${streamingTotal}/${totalSample}`);
101
+ console.log(` Batch functionality: ${streamingTotal > 10 ? 'āœ… Working' : 'āŒ Still limited to 10'}`);
102
+ }
103
+ testMLBatchFix().catch(console.error);
104
+ //# sourceMappingURL=test-ml-batch-fix.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-ml-batch.d.ts.map
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const servicenow_client_js_1 = require("./utils/servicenow-client.js");
4
+ const logger_js_1 = require("./utils/logger.js");
5
+ // Test ML batch functionality met realistische sizes
6
+ async function testMLBatch() {
7
+ const logger = new logger_js_1.Logger('MLBatchTest');
8
+ const client = new servicenow_client_js_1.ServiceNowClient();
9
+ console.log('šŸ”„ Testing ML batch functionality with realistic batch sizes...');
10
+ // ML training parameters (zoals ML daadwerkelijk gebruikt)
11
+ const sample_size = 1000; // Totaal aantal incidenten
12
+ const batch_size = 200; // Per batch
13
+ const intelligent_selection = true;
14
+ const focus_categories = [];
15
+ const query = '';
16
+ // Build intelligent query (zoals ML doet)
17
+ let finalQuery = '';
18
+ if (intelligent_selection && !query) {
19
+ const queries = [];
20
+ queries.push('sys_created_onONLast 6 months');
21
+ queries.push('(priority=1^ORpriority=2^ORpriority=3^ORpriority=4)');
22
+ queries.push('(active=true^ORactive=false)');
23
+ queries.push('categoryISNOTEMPTY');
24
+ finalQuery = queries.join('^') + '^ORDERBYDESCsys_created_on';
25
+ }
26
+ logger.info(`Testing ML batch training:`);
27
+ logger.info(`- Sample size: ${sample_size}`);
28
+ logger.info(`- Batch size: ${batch_size}`);
29
+ logger.info(`- Query: ${finalQuery}`);
30
+ // Test batch processing zoals ML training doet
31
+ const totalBatches = Math.ceil(sample_size / batch_size);
32
+ let totalProcessed = 0;
33
+ console.log(`\nšŸ“¦ Processing ${totalBatches} batches...`);
34
+ for (let batchNum = 0; batchNum < totalBatches; batchNum++) {
35
+ const offset = batchNum * batch_size;
36
+ const currentBatchSize = Math.min(batch_size, sample_size - offset);
37
+ logger.info(`\n--- Batch ${batchNum + 1}/${totalBatches} ---`);
38
+ logger.info(`Offset: ${offset}, Size: ${currentBatchSize}`);
39
+ try {
40
+ // Test searchRecordsWithOffset (zoals ML streaming doet)
41
+ const start = Date.now();
42
+ const response = await client.searchRecordsWithOffset('incident', finalQuery, currentBatchSize, offset);
43
+ const duration = Date.now() - start;
44
+ if (response.success && response.data?.result) {
45
+ const actualCount = response.data.result.length;
46
+ totalProcessed += actualCount;
47
+ logger.info(`āœ… Success: ${actualCount}/${currentBatchSize} incidents (${duration}ms)`);
48
+ // Sample categories for this batch
49
+ const categories = new Set(response.data.result.slice(0, 5).map((inc) => inc.category || 'none'));
50
+ logger.info(`Categories sample: ${Array.from(categories).join(', ')}`);
51
+ // If we got fewer than requested, we've reached the end
52
+ if (actualCount < currentBatchSize) {
53
+ logger.info(`šŸ“‹ Reached end of data (got ${actualCount} < ${currentBatchSize})`);
54
+ break;
55
+ }
56
+ }
57
+ else {
58
+ logger.error(`āŒ Batch ${batchNum + 1} failed`);
59
+ break;
60
+ }
61
+ }
62
+ catch (error) {
63
+ logger.error(`āŒ Batch ${batchNum + 1} error:`, error);
64
+ break;
65
+ }
66
+ }
67
+ console.log(`\nšŸŽÆ ML Batch Results:`);
68
+ console.log(`- Total processed: ${totalProcessed}/${sample_size} incidents`);
69
+ console.log(`- Success rate: ${((totalProcessed / sample_size) * 100).toFixed(1)}%`);
70
+ console.log(`- Ready for ML training: ${totalProcessed >= 100 ? 'āœ… Yes' : 'āŒ No (need 100+ incidents)'}`);
71
+ // Test normal single batch (non-streaming)
72
+ console.log(`\nšŸ”„ Testing single batch (non-streaming mode):`);
73
+ try {
74
+ const singleBatch = await client.searchRecords('incident', finalQuery, batch_size);
75
+ if (singleBatch.success) {
76
+ logger.info(`āœ… Single batch: ${singleBatch.data?.result?.length || 0}/${batch_size} incidents`);
77
+ }
78
+ else {
79
+ logger.error(`āŒ Single batch failed`);
80
+ }
81
+ }
82
+ catch (error) {
83
+ logger.error(`āŒ Single batch error:`, error);
84
+ }
85
+ }
86
+ testMLBatch().catch(console.error);
87
+ //# sourceMappingURL=test-ml-batch.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-ml-query.d.ts.map
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const servicenow_client_js_1 = require("./utils/servicenow-client.js");
4
+ const logger_js_1 = require("./utils/logger.js");
5
+ async function testMLQuery() {
6
+ const logger = new logger_js_1.Logger('MLQueryTest');
7
+ const client = new servicenow_client_js_1.ServiceNowClient();
8
+ logger.info('Testing ML training query...');
9
+ // Build the exact same intelligent query as ML training
10
+ const queries = [];
11
+ queries.push('sys_created_onONLast 6 months');
12
+ queries.push('(priority=1^ORpriority=2^ORpriority=3^ORpriority=4)');
13
+ queries.push('(active=true^ORactive=false)');
14
+ queries.push('categoryISNOTEMPTY');
15
+ const finalQuery = queries.join('^');
16
+ logger.info(`Using ML intelligent query: ${finalQuery}`);
17
+ // Test 1: Without ordering
18
+ try {
19
+ logger.info('\nTest 1: Query without ordering...');
20
+ const result1 = await client.searchRecords('incident', finalQuery, 10);
21
+ logger.info(`Result: ${result1.success ? 'SUCCESS' : 'FAILED'}`);
22
+ logger.info(`Count: ${result1.data?.result?.length || 0}`);
23
+ if (result1.data?.result?.length > 0) {
24
+ logger.info('Sample incidents:');
25
+ result1.data.result.slice(0, 3).forEach((inc) => {
26
+ logger.info(`- ${inc.number}: created=${inc.sys_created_on}, priority=${inc.priority}, category=${inc.category || 'none'}`);
27
+ });
28
+ }
29
+ }
30
+ catch (error) {
31
+ logger.error('Test 1 failed:', error);
32
+ }
33
+ // Test 2: With ordering (as ML uses)
34
+ try {
35
+ logger.info('\nTest 2: Query with ordering...');
36
+ const orderedQuery = finalQuery + '^ORDERBYDESCsys_created_on';
37
+ const result2 = await client.searchRecords('incident', orderedQuery, 10);
38
+ logger.info(`Result: ${result2.success ? 'SUCCESS' : 'FAILED'}`);
39
+ logger.info(`Count: ${result2.data?.result?.length || 0}`);
40
+ }
41
+ catch (error) {
42
+ logger.error('Test 2 failed:', error);
43
+ }
44
+ // Test 3: With offset (for streaming)
45
+ try {
46
+ logger.info('\nTest 3: Query with offset...');
47
+ const orderedQuery = finalQuery + '^ORDERBYDESCsys_created_on';
48
+ const result3 = await client.searchRecordsWithOffset('incident', orderedQuery, 10, 0);
49
+ logger.info(`Result: ${result3.success ? 'SUCCESS' : 'FAILED'}`);
50
+ logger.info(`Count: ${result3.data?.result?.length || 0}`);
51
+ }
52
+ catch (error) {
53
+ logger.error('Test 3 failed:', error);
54
+ }
55
+ // Test 4: Simplify query to find the issue
56
+ try {
57
+ logger.info('\nTest 4: Testing each query part separately...');
58
+ const testQueries = [
59
+ 'sys_created_onONLast 6 months',
60
+ 'priority=1^ORpriority=2^ORpriority=3^ORpriority=4',
61
+ 'active=true^ORactive=false',
62
+ 'categoryISNOTEMPTY',
63
+ 'category!=null',
64
+ 'categoryISNOT EMPTY',
65
+ '' // empty query
66
+ ];
67
+ for (const q of testQueries) {
68
+ const result = await client.searchRecords('incident', q, 5);
69
+ logger.info(`Query "${q}" -> ${result.data?.result?.length || 0} results`);
70
+ }
71
+ }
72
+ catch (error) {
73
+ logger.error('Test 4 failed:', error);
74
+ }
75
+ // Test 5: Check if categoryISNOTEMPTY is the problem
76
+ try {
77
+ logger.info('\nTest 5: Testing without category filter...');
78
+ const queriesWithoutCategory = [
79
+ 'sys_created_onONLast 6 months',
80
+ '(priority=1^ORpriority=2^ORpriority=3^ORpriority=4)',
81
+ '(active=true^ORactive=false)'
82
+ ];
83
+ const queryWithoutCategory = queriesWithoutCategory.join('^');
84
+ logger.info(`Query without category: ${queryWithoutCategory}`);
85
+ const result5 = await client.searchRecords('incident', queryWithoutCategory, 10);
86
+ logger.info(`Result: ${result5.success ? 'SUCCESS' : 'FAILED'}`);
87
+ logger.info(`Count: ${result5.data?.result?.length || 0}`);
88
+ if (result5.data?.result?.length > 0) {
89
+ logger.info('Categories in results:');
90
+ const categories = new Set(result5.data.result.map((inc) => inc.category || 'empty'));
91
+ logger.info(`Unique categories: ${Array.from(categories).join(', ')}`);
92
+ }
93
+ }
94
+ catch (error) {
95
+ logger.error('Test 5 failed:', error);
96
+ }
97
+ }
98
+ // Run the test
99
+ testMLQuery().catch(console.error);
100
+ //# sourceMappingURL=test-ml-query.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-ml-training.d.ts.map
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const servicenow_machine_learning_mcp_js_1 = require("./mcp/servicenow-machine-learning-mcp.js");
4
+ async function testMLTraining() {
5
+ console.log('šŸ”„ Testing ML training with 2000+ incidents...');
6
+ try {
7
+ // Test the ML training directly
8
+ const result = await (0, servicenow_machine_learning_mcp_js_1.mcp__servicenow_machine_learning__ml_train_incident_classifier)({
9
+ sample_size: 2000,
10
+ query: '', // Use intelligent selection
11
+ intelligent_selection: true,
12
+ streaming_mode: false, // Test non-streaming first
13
+ batch_size: 200,
14
+ epochs: 50,
15
+ validation_split: 0.2,
16
+ max_vocabulary_size: 10000,
17
+ focus_categories: []
18
+ });
19
+ console.log('āœ… ML Training Result:');
20
+ console.log(JSON.stringify(JSON.parse(result.content[0].text), null, 2));
21
+ }
22
+ catch (error) {
23
+ console.error('āŒ ML Training failed:', error);
24
+ // If it fails, show more details
25
+ if (error instanceof Error) {
26
+ console.error('Error message:', error.message);
27
+ console.error('Stack trace:', error.stack);
28
+ }
29
+ }
30
+ }
31
+ testMLTraining().catch(console.error);
32
+ //# sourceMappingURL=test-ml-training.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-operations-query.d.ts.map
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const servicenow_client_js_1 = require("./utils/servicenow-client.js");
4
+ const logger_js_1 = require("./utils/logger.js");
5
+ async function testOperationsQuery() {
6
+ const logger = new logger_js_1.Logger('OperationsQueryTest');
7
+ const client = new servicenow_client_js_1.ServiceNowClient();
8
+ logger.info('Testing operations query processing...');
9
+ // Test processNaturalLanguageQuery logic
10
+ const testQuery = (query) => {
11
+ const lowerQuery = query.toLowerCase();
12
+ // If already a ServiceNow encoded query, return as-is
13
+ if (query.includes('=') || query.includes('!=') || query.includes('^') || query.includes('LIKE')) {
14
+ logger.info(`Recognized as ServiceNow query: ${query}`);
15
+ return query;
16
+ }
17
+ logger.info(`Treating as natural language: ${query}`);
18
+ return `short_descriptionLIKE${query}^ORdescriptionLIKE${query}`;
19
+ };
20
+ // Test queries
21
+ const queries = [
22
+ 'state!=7',
23
+ 'active=true',
24
+ 'priority=1',
25
+ 'all incidents',
26
+ 'high priority',
27
+ ''
28
+ ];
29
+ logger.info('\n--- Testing Query Processing ---');
30
+ for (const query of queries) {
31
+ const processed = testQuery(query);
32
+ logger.info(`Input: "${query}" -> Output: "${processed}"`);
33
+ }
34
+ logger.info('\n--- Testing Actual Queries ---');
35
+ // Test 1: Raw ServiceNow query
36
+ try {
37
+ logger.info('\nTest 1: Testing with state!=7...');
38
+ const result1 = await client.searchRecords('incident', 'state!=7', 10);
39
+ logger.info(`Result: ${result1.success ? 'SUCCESS' : 'FAILED'}`);
40
+ logger.info(`Count: ${result1.data?.result?.length || 0}`);
41
+ }
42
+ catch (error) {
43
+ logger.error('Test 1 failed:', error);
44
+ }
45
+ // Test 2: Empty query
46
+ try {
47
+ logger.info('\nTest 2: Testing with empty query...');
48
+ const result2 = await client.searchRecords('incident', '', 10);
49
+ logger.info(`Result: ${result2.success ? 'SUCCESS' : 'FAILED'}`);
50
+ logger.info(`Count: ${result2.data?.result?.length || 0}`);
51
+ }
52
+ catch (error) {
53
+ logger.error('Test 2 failed:', error);
54
+ }
55
+ // Test 3: Complex query
56
+ try {
57
+ logger.info('\nTest 3: Testing with complex query...');
58
+ const result3 = await client.searchRecords('incident', 'active=true^state!=6^state!=7', 10);
59
+ logger.info(`Result: ${result3.success ? 'SUCCESS' : 'FAILED'}`);
60
+ logger.info(`Count: ${result3.data?.result?.length || 0}`);
61
+ }
62
+ catch (error) {
63
+ logger.error('Test 3 failed:', error);
64
+ }
65
+ // Test 4: Test natural language conversion
66
+ try {
67
+ logger.info('\nTest 4: Testing natural language conversion...');
68
+ const nlQuery = 'high priority';
69
+ const processedQuery = testQuery(nlQuery);
70
+ logger.info(`Natural language: "${nlQuery}" -> "${processedQuery}"`);
71
+ // Now test the actual operations MCP logic
72
+ const operationsQuery = nlQuery.toLowerCase().includes('high priority') ? 'priority=1' : processedQuery;
73
+ logger.info(`Operations MCP would use: "${operationsQuery}"`);
74
+ const result4 = await client.searchRecords('incident', operationsQuery, 10);
75
+ logger.info(`Result: ${result4.success ? 'SUCCESS' : 'FAILED'}`);
76
+ logger.info(`Count: ${result4.data?.result?.length || 0}`);
77
+ }
78
+ catch (error) {
79
+ logger.error('Test 4 failed:', error);
80
+ }
81
+ }
82
+ // Run the test
83
+ testOperationsQuery().catch(console.error);
84
+ //# sourceMappingURL=test-operations-query.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-snow-query-incidents.d.ts.map
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const servicenow_client_js_1 = require("./utils/servicenow-client.js");
4
+ const logger_js_1 = require("./utils/logger.js");
5
+ // Test exact same logic as snow_query_incidents MCP tool
6
+ async function testSnowQueryIncidents() {
7
+ const logger = new logger_js_1.Logger('SnowQueryIncidentsTest');
8
+ const client = new servicenow_client_js_1.ServiceNowClient();
9
+ console.log('šŸ” Testing snow_query_incidents MCP logic...');
10
+ // Simulate handleQueryIncidents exactly
11
+ const query = 'state!=7';
12
+ const limit = 5;
13
+ logger.info(`Querying incidents with: ${query}`);
14
+ try {
15
+ // Step 1: processNaturalLanguageQuery (from operations MCP)
16
+ const processNaturalLanguageQuery = (query, context) => {
17
+ const lowerQuery = query.toLowerCase();
18
+ // If already a ServiceNow encoded query, return as-is
19
+ if (query.includes('=') || query.includes('!=') || query.includes('^') || query.includes('LIKE')) {
20
+ logger.info(`Using raw ServiceNow query: ${query}`);
21
+ return query;
22
+ }
23
+ // Other processing would go here...
24
+ logger.info(`Treating as natural language: ${query}`);
25
+ return `short_descriptionLIKE${query}^ORdescriptionLIKE${query}`;
26
+ };
27
+ // Step 2: Process the query
28
+ const processedQuery = processNaturalLanguageQuery(query, 'incident');
29
+ logger.info(`Processed query: "${processedQuery}"`);
30
+ // Step 3: Execute the search (exact same as MCP)
31
+ const incidents = await client.searchRecords('incident', processedQuery, limit);
32
+ logger.info(`Search result: success=${incidents.success}, count=${incidents.data?.result?.length || 0}`);
33
+ // Step 4: Build result object (exact same as MCP)
34
+ let result = {
35
+ total_results: incidents.success ? incidents.data.result.length : 0,
36
+ incidents: incidents.success ? incidents.data.result : []
37
+ };
38
+ // Step 5: Format output (exact same as MCP)
39
+ const output = `Found ${incidents.success ? incidents.data.result.length : 0} incidents matching query: "${query}"\n\n${JSON.stringify(result, null, 2)}`;
40
+ console.log('\nšŸ“‹ MCP Output would be:');
41
+ console.log(output);
42
+ if (!incidents.success || incidents.data.result.length === 0) {
43
+ logger.error('🚨 This matches the problem! MCP would return 0 incidents');
44
+ }
45
+ else {
46
+ logger.info('āœ… This would work correctly in MCP');
47
+ }
48
+ }
49
+ catch (error) {
50
+ logger.error('āŒ Error in snow_query_incidents simulation:', error);
51
+ }
52
+ // Direct test without MCP processing
53
+ console.log('\nšŸ”„ Direct test without MCP processing:');
54
+ try {
55
+ const directResult = await client.searchRecords('incident', 'state!=7', limit);
56
+ logger.info(`Direct result: success=${directResult.success}, count=${directResult.data?.result?.length || 0}`);
57
+ if (directResult.success && directResult.data?.result?.length > 0) {
58
+ logger.info('āœ… Direct call works - problem is in MCP processing');
59
+ }
60
+ }
61
+ catch (error) {
62
+ logger.error('āŒ Direct call also fails:', error);
63
+ }
64
+ }
65
+ testSnowQueryIncidents().catch(console.error);
66
+ //# sourceMappingURL=test-snow-query-incidents.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snow-flow",
3
- "version": "2.7.1",
3
+ "version": "2.7.3",
4
4
  "description": "Snow-Flow: ServiceNow Advanced Intelligence Platform - 100+ real MCP tools with AI-powered swarm orchestration and neural networks. Dynamic task categorization using AI. Machine learning for incident classification, change risk prediction, and anomaly detection. Zero Mock Data, 100% Real API Integration.",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",