snow-flow 2.7.0 โ 2.7.1
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/dist/mcp/servicenow-machine-learning-mcp.d.ts +24 -0
- package/dist/mcp/servicenow-machine-learning-mcp.js +270 -10
- package/dist/utils/servicenow-client.d.ts +4 -0
- package/dist/utils/servicenow-client.js +28 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +10 -0
- package/package.json +1 -1
|
@@ -61,6 +61,30 @@ export declare class ServiceNowMachineLearningMCP {
|
|
|
61
61
|
private fetchIncidentVolumeHistory;
|
|
62
62
|
private prepareTimeSeriesData;
|
|
63
63
|
private fetchSingleIncident;
|
|
64
|
+
/**
|
|
65
|
+
* Train model using streaming to handle large datasets efficiently
|
|
66
|
+
*/
|
|
67
|
+
private trainWithStreaming;
|
|
68
|
+
/**
|
|
69
|
+
* Fetch a batch of incidents with offset for streaming
|
|
70
|
+
*/
|
|
71
|
+
private fetchIncidentBatch;
|
|
72
|
+
/**
|
|
73
|
+
* Create feature hasher for memory-efficient vocabulary management
|
|
74
|
+
*/
|
|
75
|
+
private createFeatureHasher;
|
|
76
|
+
/**
|
|
77
|
+
* Process batch with feature hashing
|
|
78
|
+
*/
|
|
79
|
+
private processBatchWithHashing;
|
|
80
|
+
/**
|
|
81
|
+
* Create optimized model for memory efficiency
|
|
82
|
+
*/
|
|
83
|
+
private createOptimizedModel;
|
|
84
|
+
/**
|
|
85
|
+
* Optimized data preparation with feature hashing
|
|
86
|
+
*/
|
|
87
|
+
private prepareIncidentDataOptimized;
|
|
64
88
|
private detectAnomalies;
|
|
65
89
|
private predictChangeRisk;
|
|
66
90
|
private evaluateModel;
|
|
@@ -141,6 +141,21 @@ class ServiceNowMachineLearningMCP {
|
|
|
141
141
|
type: 'array',
|
|
142
142
|
items: { type: 'string' },
|
|
143
143
|
description: 'Specific categories to focus on for training (optional)'
|
|
144
|
+
},
|
|
145
|
+
batch_size: {
|
|
146
|
+
type: 'number',
|
|
147
|
+
description: 'Process data in batches to prevent memory overload',
|
|
148
|
+
default: 100
|
|
149
|
+
},
|
|
150
|
+
max_vocabulary_size: {
|
|
151
|
+
type: 'number',
|
|
152
|
+
description: 'Maximum vocabulary size using feature hashing',
|
|
153
|
+
default: 10000
|
|
154
|
+
},
|
|
155
|
+
streaming_mode: {
|
|
156
|
+
type: 'boolean',
|
|
157
|
+
description: 'Enable streaming mode for very large datasets',
|
|
158
|
+
default: true
|
|
144
159
|
}
|
|
145
160
|
}
|
|
146
161
|
},
|
|
@@ -490,7 +505,7 @@ class ServiceNowMachineLearningMCP {
|
|
|
490
505
|
* Uses PI if available, otherwise uses custom TensorFlow.js
|
|
491
506
|
*/
|
|
492
507
|
async trainIncidentClassifier(args) {
|
|
493
|
-
const { sample_size = 1000, epochs = 50, validation_split = 0.2, query = '', intelligent_selection = true, focus_categories = [] } = args;
|
|
508
|
+
const { sample_size = 1000, epochs = 50, validation_split = 0.2, query = '', intelligent_selection = true, focus_categories = [], batch_size = 100, max_vocabulary_size = 10000, streaming_mode = true } = args;
|
|
494
509
|
try {
|
|
495
510
|
// Wait for ML API check if not complete
|
|
496
511
|
if (!this.mlAPICheckComplete) {
|
|
@@ -526,19 +541,24 @@ class ServiceNowMachineLearningMCP {
|
|
|
526
541
|
}
|
|
527
542
|
}
|
|
528
543
|
// Use custom TensorFlow.js neural network
|
|
529
|
-
this.logger.info(`Training custom LSTM neural network
|
|
530
|
-
|
|
531
|
-
|
|
544
|
+
this.logger.info(`Training custom LSTM neural network with intelligent memory management...`);
|
|
545
|
+
this.logger.info(`Settings: batch_size=${batch_size}, max_vocabulary=${max_vocabulary_size}, streaming=${streaming_mode}`);
|
|
546
|
+
// If streaming mode is enabled, process data in batches
|
|
547
|
+
if (streaming_mode && sample_size > batch_size * 2) {
|
|
548
|
+
return await this.trainWithStreaming(args);
|
|
549
|
+
}
|
|
550
|
+
// For smaller datasets, use the original approach but with optimizations
|
|
551
|
+
const incidents = await this.fetchIncidentData(Math.min(sample_size, batch_size * 5), {
|
|
532
552
|
query,
|
|
533
553
|
intelligent_selection,
|
|
534
554
|
focus_categories
|
|
535
555
|
});
|
|
536
|
-
this.logger.info(`Retrieved ${incidents.length} incidents
|
|
556
|
+
this.logger.info(`Retrieved ${incidents.length} incidents for initial training`);
|
|
537
557
|
if (incidents.length < 100) {
|
|
538
558
|
throw new Error(`Insufficient data for training (need at least 100 incidents, got ${incidents.length})`);
|
|
539
559
|
}
|
|
540
|
-
// Prepare training data
|
|
541
|
-
const { features, labels, tokenizer, categories } = await this.
|
|
560
|
+
// Prepare training data with memory optimization
|
|
561
|
+
const { features, labels, tokenizer, categories } = await this.prepareIncidentDataOptimized(incidents, max_vocabulary_size);
|
|
542
562
|
// Create neural network model
|
|
543
563
|
const model = tf.sequential({
|
|
544
564
|
layers: [
|
|
@@ -866,7 +886,18 @@ class ServiceNowMachineLearningMCP {
|
|
|
866
886
|
}
|
|
867
887
|
// Prepare input for custom neural network
|
|
868
888
|
const text = `${incidentData.short_description} ${incidentData.description}`;
|
|
869
|
-
|
|
889
|
+
let tokenized;
|
|
890
|
+
// Check if using feature hashing (streaming mode) or traditional tokenizer
|
|
891
|
+
if (this.incidentClassifier.tokenizer.has('_vocabulary_size')) {
|
|
892
|
+
// Using feature hashing
|
|
893
|
+
const vocabularySize = this.incidentClassifier.tokenizer.get('_vocabulary_size');
|
|
894
|
+
const hasher = this.createFeatureHasher(vocabularySize);
|
|
895
|
+
tokenized = hasher(text);
|
|
896
|
+
}
|
|
897
|
+
else {
|
|
898
|
+
// Using traditional tokenizer
|
|
899
|
+
tokenized = this.tokenizeText(text, this.incidentClassifier.tokenizer, this.incidentClassifier.maxLength);
|
|
900
|
+
}
|
|
870
901
|
const input = tf.tensor2d([tokenized]);
|
|
871
902
|
// Predict
|
|
872
903
|
const prediction = this.incidentClassifier.model.predict(input);
|
|
@@ -987,8 +1018,11 @@ class ServiceNowMachineLearningMCP {
|
|
|
987
1018
|
status.incident_classifier = this.incidentClassifier ? {
|
|
988
1019
|
status: 'trained',
|
|
989
1020
|
categories: this.incidentClassifier.categories.length,
|
|
990
|
-
vocabulary_size: this.incidentClassifier.tokenizer.
|
|
991
|
-
|
|
1021
|
+
vocabulary_size: this.incidentClassifier.tokenizer.has('_vocabulary_size')
|
|
1022
|
+
? this.incidentClassifier.tokenizer.get('_vocabulary_size')
|
|
1023
|
+
: this.incidentClassifier.tokenizer.size,
|
|
1024
|
+
model_size: await this.getModelSize(this.incidentClassifier.model),
|
|
1025
|
+
memory_efficient: this.incidentClassifier.tokenizer.has('_vocabulary_size')
|
|
992
1026
|
} : { status: 'not_trained' };
|
|
993
1027
|
}
|
|
994
1028
|
if (model === 'all' || model === 'change_risk') {
|
|
@@ -1311,6 +1345,232 @@ class ServiceNowMachineLearningMCP {
|
|
|
1311
1345
|
(new Date(inc.resolved_at).getTime() - new Date(inc.sys_created_on).getTime()) / 1000 : undefined
|
|
1312
1346
|
};
|
|
1313
1347
|
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Train model using streaming to handle large datasets efficiently
|
|
1350
|
+
*/
|
|
1351
|
+
async trainWithStreaming(args) {
|
|
1352
|
+
const { sample_size, batch_size, epochs, validation_split, query, intelligent_selection, focus_categories, max_vocabulary_size } = args;
|
|
1353
|
+
this.logger.info(`Starting streaming training with batch size ${batch_size}`);
|
|
1354
|
+
// Create feature hasher for vocabulary management
|
|
1355
|
+
const featureHasher = this.createFeatureHasher(max_vocabulary_size);
|
|
1356
|
+
// Initialize model with proper architecture
|
|
1357
|
+
const model = this.createOptimizedModel(max_vocabulary_size);
|
|
1358
|
+
// Process data in batches
|
|
1359
|
+
const totalBatches = Math.ceil(sample_size / batch_size);
|
|
1360
|
+
let processedSamples = 0;
|
|
1361
|
+
let allCategories = new Set();
|
|
1362
|
+
for (let batchNum = 0; batchNum < totalBatches; batchNum++) {
|
|
1363
|
+
const offset = batchNum * batch_size;
|
|
1364
|
+
const currentBatchSize = Math.min(batch_size, sample_size - offset);
|
|
1365
|
+
this.logger.info(`Processing batch ${batchNum + 1}/${totalBatches} (${currentBatchSize} samples)`);
|
|
1366
|
+
// Fetch batch of incidents
|
|
1367
|
+
const batchIncidents = await this.fetchIncidentBatch(currentBatchSize, offset, {
|
|
1368
|
+
query,
|
|
1369
|
+
intelligent_selection,
|
|
1370
|
+
focus_categories
|
|
1371
|
+
});
|
|
1372
|
+
if (batchIncidents.length === 0)
|
|
1373
|
+
break;
|
|
1374
|
+
// Extract categories
|
|
1375
|
+
batchIncidents.forEach(inc => allCategories.add(inc.category));
|
|
1376
|
+
// Process batch with feature hashing
|
|
1377
|
+
const { features, labels } = this.processBatchWithHashing(batchIncidents, Array.from(allCategories), featureHasher);
|
|
1378
|
+
// Train on batch
|
|
1379
|
+
await model.fit(features, labels, {
|
|
1380
|
+
epochs: Math.ceil(epochs / totalBatches), // Distribute epochs across batches
|
|
1381
|
+
batchSize: 32,
|
|
1382
|
+
verbose: 0,
|
|
1383
|
+
callbacks: {
|
|
1384
|
+
onBatchEnd: async (batch, logs) => {
|
|
1385
|
+
if (batch % 10 === 0) {
|
|
1386
|
+
this.logger.info(`Batch ${batch}: loss=${logs?.loss?.toFixed(4)}`);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
});
|
|
1391
|
+
// Clean up tensors to free memory
|
|
1392
|
+
features.dispose();
|
|
1393
|
+
labels.dispose();
|
|
1394
|
+
processedSamples += batchIncidents.length;
|
|
1395
|
+
// Force garbage collection hint
|
|
1396
|
+
if (global.gc) {
|
|
1397
|
+
global.gc();
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
this.logger.info(`Streaming training completed. Processed ${processedSamples} samples in ${totalBatches} batches`);
|
|
1401
|
+
// Save model
|
|
1402
|
+
const modelId = `incident_classifier_${Date.now()}`;
|
|
1403
|
+
const modelInfo = {
|
|
1404
|
+
id: modelId,
|
|
1405
|
+
categories: Array.from(allCategories),
|
|
1406
|
+
vocabulary_size: max_vocabulary_size,
|
|
1407
|
+
training_samples: processedSamples,
|
|
1408
|
+
batch_size: batch_size,
|
|
1409
|
+
created_at: new Date().toISOString()
|
|
1410
|
+
};
|
|
1411
|
+
return {
|
|
1412
|
+
content: [{
|
|
1413
|
+
type: 'text',
|
|
1414
|
+
text: JSON.stringify({
|
|
1415
|
+
success: true,
|
|
1416
|
+
model_id: modelId,
|
|
1417
|
+
model_info: modelInfo,
|
|
1418
|
+
training_stats: {
|
|
1419
|
+
total_samples: processedSamples,
|
|
1420
|
+
batches_processed: totalBatches,
|
|
1421
|
+
memory_efficient: true
|
|
1422
|
+
}
|
|
1423
|
+
}, null, 2)
|
|
1424
|
+
}]
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Fetch a batch of incidents with offset for streaming
|
|
1429
|
+
*/
|
|
1430
|
+
async fetchIncidentBatch(limit, offset, options) {
|
|
1431
|
+
const { query, intelligent_selection, focus_categories } = options;
|
|
1432
|
+
let finalQuery = query;
|
|
1433
|
+
if (intelligent_selection && !query) {
|
|
1434
|
+
// Build intelligent query (same as before)
|
|
1435
|
+
const queries = [];
|
|
1436
|
+
queries.push('sys_created_onONLast 6 months');
|
|
1437
|
+
queries.push('(priority=1^ORpriority=2^ORpriority=3^ORpriority=4)');
|
|
1438
|
+
queries.push('(active=true^ORactive=false)');
|
|
1439
|
+
if (focus_categories.length > 0) {
|
|
1440
|
+
const categoryQuery = focus_categories.map((cat) => `category=${cat}`).join('^OR');
|
|
1441
|
+
queries.push(`(${categoryQuery})`);
|
|
1442
|
+
}
|
|
1443
|
+
else {
|
|
1444
|
+
queries.push('categoryISNOTEMPTY');
|
|
1445
|
+
}
|
|
1446
|
+
finalQuery = queries.join('^');
|
|
1447
|
+
}
|
|
1448
|
+
// Add offset for pagination
|
|
1449
|
+
if (finalQuery && !finalQuery.includes('ORDERBY')) {
|
|
1450
|
+
finalQuery += '^ORDERBYDESCsys_created_on';
|
|
1451
|
+
}
|
|
1452
|
+
// ServiceNow API supports offset through sysparm_offset
|
|
1453
|
+
const response = await this.client.searchRecordsWithOffset('incident', finalQuery, limit, offset);
|
|
1454
|
+
if (!response.success || !response.data?.result) {
|
|
1455
|
+
return [];
|
|
1456
|
+
}
|
|
1457
|
+
return response.data.result.map((inc) => ({
|
|
1458
|
+
short_description: inc.short_description || '',
|
|
1459
|
+
description: inc.description || '',
|
|
1460
|
+
category: inc.category || 'uncategorized',
|
|
1461
|
+
subcategory: inc.subcategory || '',
|
|
1462
|
+
priority: parseInt(inc.priority) || 3,
|
|
1463
|
+
impact: parseInt(inc.impact) || 2,
|
|
1464
|
+
urgency: parseInt(inc.urgency) || 2,
|
|
1465
|
+
resolved: inc.resolved === 'true'
|
|
1466
|
+
}));
|
|
1467
|
+
}
|
|
1468
|
+
/**
|
|
1469
|
+
* Create feature hasher for memory-efficient vocabulary management
|
|
1470
|
+
*/
|
|
1471
|
+
createFeatureHasher(maxFeatures) {
|
|
1472
|
+
return (text) => {
|
|
1473
|
+
const words = text.toLowerCase().split(/\s+/);
|
|
1474
|
+
const features = new Array(100).fill(0); // Fixed sequence length
|
|
1475
|
+
words.slice(0, 100).forEach((word, idx) => {
|
|
1476
|
+
// Simple hash function
|
|
1477
|
+
let hash = 0;
|
|
1478
|
+
for (let i = 0; i < word.length; i++) {
|
|
1479
|
+
hash = ((hash << 5) - hash) + word.charCodeAt(i);
|
|
1480
|
+
hash = hash & hash; // Convert to 32-bit integer
|
|
1481
|
+
}
|
|
1482
|
+
// Map to vocabulary size
|
|
1483
|
+
features[idx] = Math.abs(hash) % maxFeatures;
|
|
1484
|
+
});
|
|
1485
|
+
return features;
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
/**
|
|
1489
|
+
* Process batch with feature hashing
|
|
1490
|
+
*/
|
|
1491
|
+
processBatchWithHashing(incidents, categories, hasher) {
|
|
1492
|
+
const sequences = [];
|
|
1493
|
+
const labels = [];
|
|
1494
|
+
for (const incident of incidents) {
|
|
1495
|
+
const text = `${incident.short_description} ${incident.description}`;
|
|
1496
|
+
const sequence = hasher(text);
|
|
1497
|
+
sequences.push(sequence);
|
|
1498
|
+
// One-hot encode category
|
|
1499
|
+
const categoryIndex = categories.indexOf(incident.category);
|
|
1500
|
+
const label = new Array(categories.length).fill(0);
|
|
1501
|
+
if (categoryIndex >= 0) {
|
|
1502
|
+
label[categoryIndex] = 1;
|
|
1503
|
+
}
|
|
1504
|
+
labels.push(label);
|
|
1505
|
+
}
|
|
1506
|
+
return {
|
|
1507
|
+
features: tf.tensor2d(sequences),
|
|
1508
|
+
labels: tf.tensor2d(labels)
|
|
1509
|
+
};
|
|
1510
|
+
}
|
|
1511
|
+
/**
|
|
1512
|
+
* Create optimized model for memory efficiency
|
|
1513
|
+
*/
|
|
1514
|
+
createOptimizedModel(vocabularySize) {
|
|
1515
|
+
return tf.sequential({
|
|
1516
|
+
layers: [
|
|
1517
|
+
// Use embedding with smaller dimensions
|
|
1518
|
+
tf.layers.embedding({
|
|
1519
|
+
inputDim: vocabularySize,
|
|
1520
|
+
outputDim: 64, // Reduced from 128
|
|
1521
|
+
inputLength: 100
|
|
1522
|
+
}),
|
|
1523
|
+
// Smaller LSTM
|
|
1524
|
+
tf.layers.lstm({
|
|
1525
|
+
units: 32, // Reduced from 64
|
|
1526
|
+
returnSequences: false,
|
|
1527
|
+
dropout: 0.2,
|
|
1528
|
+
recurrentDropout: 0.2
|
|
1529
|
+
}),
|
|
1530
|
+
// Smaller dense layer
|
|
1531
|
+
tf.layers.dense({
|
|
1532
|
+
units: 16, // Reduced from 32
|
|
1533
|
+
activation: 'relu'
|
|
1534
|
+
}),
|
|
1535
|
+
tf.layers.dropout({ rate: 0.3 }),
|
|
1536
|
+
// Output layer (dynamic based on categories)
|
|
1537
|
+
tf.layers.dense({
|
|
1538
|
+
units: 10, // Will be adjusted based on actual categories
|
|
1539
|
+
activation: 'softmax'
|
|
1540
|
+
})
|
|
1541
|
+
]
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* Optimized data preparation with feature hashing
|
|
1546
|
+
*/
|
|
1547
|
+
async prepareIncidentDataOptimized(incidents, maxVocabularySize) {
|
|
1548
|
+
const hasher = this.createFeatureHasher(maxVocabularySize);
|
|
1549
|
+
const categories = [...new Set(incidents.map(i => i.category))];
|
|
1550
|
+
const sequences = [];
|
|
1551
|
+
const labels = [];
|
|
1552
|
+
for (const incident of incidents) {
|
|
1553
|
+
const text = `${incident.short_description} ${incident.description}`;
|
|
1554
|
+
const sequence = hasher(text);
|
|
1555
|
+
sequences.push(sequence);
|
|
1556
|
+
// One-hot encode category
|
|
1557
|
+
const categoryIndex = categories.indexOf(incident.category);
|
|
1558
|
+
const label = new Array(categories.length).fill(0);
|
|
1559
|
+
if (categoryIndex >= 0) {
|
|
1560
|
+
label[categoryIndex] = 1;
|
|
1561
|
+
}
|
|
1562
|
+
labels.push(label);
|
|
1563
|
+
}
|
|
1564
|
+
// Create a minimal Map for compatibility
|
|
1565
|
+
const tokenizerMap = new Map();
|
|
1566
|
+
tokenizerMap.set('_vocabulary_size', maxVocabularySize);
|
|
1567
|
+
return {
|
|
1568
|
+
features: tf.tensor2d(sequences),
|
|
1569
|
+
labels: tf.tensor2d(labels),
|
|
1570
|
+
tokenizer: tokenizerMap,
|
|
1571
|
+
categories
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1314
1574
|
async detectAnomalies(args) {
|
|
1315
1575
|
// Implement anomaly detection
|
|
1316
1576
|
return {
|
|
@@ -159,6 +159,10 @@ export declare class ServiceNowClient {
|
|
|
159
159
|
* Search records in a table using encoded query
|
|
160
160
|
*/
|
|
161
161
|
searchRecords(table: string, query: string, limit?: number): Promise<ServiceNowAPIResponse<any>>;
|
|
162
|
+
/**
|
|
163
|
+
* Search records with offset for pagination/streaming
|
|
164
|
+
*/
|
|
165
|
+
searchRecordsWithOffset(table: string, query: string, limit?: number, offset?: number): Promise<ServiceNowAPIResponse<any>>;
|
|
162
166
|
/**
|
|
163
167
|
* Create a record in any ServiceNow table
|
|
164
168
|
*/
|
|
@@ -1000,6 +1000,34 @@ class ServiceNowClient {
|
|
|
1000
1000
|
};
|
|
1001
1001
|
}
|
|
1002
1002
|
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Search records with offset for pagination/streaming
|
|
1005
|
+
*/
|
|
1006
|
+
async searchRecordsWithOffset(table, query, limit = 10, offset = 0) {
|
|
1007
|
+
try {
|
|
1008
|
+
await this.ensureAuthenticated();
|
|
1009
|
+
const response = await this.client.get(`${this.getBaseUrl()}/api/now/table/${table}`, {
|
|
1010
|
+
params: {
|
|
1011
|
+
sysparm_query: query,
|
|
1012
|
+
sysparm_limit: limit,
|
|
1013
|
+
sysparm_offset: offset
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
1016
|
+
return {
|
|
1017
|
+
success: true,
|
|
1018
|
+
data: {
|
|
1019
|
+
result: response.data.result || []
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
catch (error) {
|
|
1024
|
+
console.error(`Failed to search records in ${table} with offset ${offset}:`, error);
|
|
1025
|
+
return {
|
|
1026
|
+
success: false,
|
|
1027
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1003
1031
|
/**
|
|
1004
1032
|
* Create a record in any ServiceNow table
|
|
1005
1033
|
*/
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -14,6 +14,16 @@ exports.VERSION_INFO = {
|
|
|
14
14
|
name: 'Snow-Flow',
|
|
15
15
|
description: 'ServiceNow Queen Agent - Hive-Mind Intelligence for ServiceNow Development',
|
|
16
16
|
features: {
|
|
17
|
+
'2.7.1': [
|
|
18
|
+
'๐พ MEMORY-EFFICIENT ML: Streaming training for large datasets prevents memory overload',
|
|
19
|
+
'๐ฆ BATCH PROCESSING: Process data in configurable batches (default 100 records)',
|
|
20
|
+
'๐๏ธ FEATURE HASHING: Reduces vocabulary from unlimited to fixed size (default 10K)',
|
|
21
|
+
'๐ PROGRESSIVE LOADING: Only loads data as needed during training',
|
|
22
|
+
'๐งน AUTOMATIC CLEANUP: Disposes tensors after each batch to free memory',
|
|
23
|
+
'๐ SCALABLE TRAINING: Can handle datasets of any size without crashing',
|
|
24
|
+
'โก OPTIMIZED MODELS: Smaller but effective neural networks for memory efficiency',
|
|
25
|
+
'๐ REAL-TIME PROGRESS: Shows batch-by-batch training progress',
|
|
26
|
+
],
|
|
17
27
|
'2.7.0': [
|
|
18
28
|
'๐ง INTELLIGENT ML DATA SELECTION: Snow-Flow now intelligently selects balanced training data',
|
|
19
29
|
'๐ฏ CUSTOM QUERIES: Added query parameter for full control over ML training data selection',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snow-flow",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.1",
|
|
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",
|