packages/opencode/src/bundled-skills/predictive-intelligence/SKILL.md
This skill should be used when the user asks to "predictive intelligence", "machine learning", "ML", "classification", "similarity", "clustering", "prediction", "AI", or any ServiceNow Predictive Intelligence development.
npx skillsauth add groeimetai/snow-flow predictive-intelligenceInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Predictive Intelligence uses machine learning to automate categorization, routing, and recommendations.
| Capability | Use Case | | ------------------ | -------------------------------- | | Classification | Auto-categorize incidents, cases | | Similarity | Find similar records | | Clustering | Group related items | | Regression | Predict numeric values | | Recommendation | Suggest next actions |
| Table | Purpose |
| -------------------------- | ----------------------- |
| ml_solution | ML solution definitions |
| ml_solution_definition | Solution configuration |
| ml_capability_definition | Capability settings |
| ml_model | Trained models |
| ml_prediction_result | Prediction results |
// Create classification solution (ES5 ONLY!)
// Note: Usually done via UI, shown for understanding
var solution = new GlideRecord("ml_solution")
solution.initialize()
solution.setValue("name", "Incident Category Classifier")
solution.setValue("label", "Incident Category Classifier")
solution.setValue("table", "incident")
solution.setValue("active", true)
// Capability type
solution.setValue("capability", "classification")
// Target field to predict
solution.setValue("target_field", "category")
// Input fields for training
solution.setValue("input_fields", "short_description,description")
solution.insert()
// Get classification prediction for record (ES5 ONLY!)
function getClassificationPrediction(tableName, recordSysId, solutionName) {
var predictor = new sn_ml.ClassificationPredictor(solutionName)
var gr = new GlideRecord(tableName)
if (!gr.get(recordSysId)) {
return null
}
try {
var result = predictor.predict(gr)
return {
predicted_value: result.getPredictedValue(),
confidence: result.getConfidence(),
top_predictions: result.getTopPredictions(5),
}
} catch (e) {
gs.error("Prediction failed: " + e.message)
return null
}
}
// Auto-apply classification prediction (ES5 ONLY!)
// Business Rule: before, insert, incident
;(function executeRule(current, previous) {
// Skip if already categorized
if (current.category) {
return
}
var solutionName = "incident_category_classifier"
try {
var predictor = new sn_ml.ClassificationPredictor(solutionName)
var result = predictor.predict(current)
// Only apply if confidence is high enough
if (result.getConfidence() >= 0.8) {
current.category = result.getPredictedValue()
current.work_notes =
"Category auto-assigned by Predictive Intelligence " +
"(Confidence: " +
Math.round(result.getConfidence() * 100) +
"%)"
}
} catch (e) {
gs.warn("Classification prediction failed: " + e.message)
}
})(current, previous)
// Find similar incidents (ES5 ONLY!)
function findSimilarIncidents(incidentSysId, maxResults) {
maxResults = maxResults || 5
var incident = new GlideRecord("incident")
if (!incident.get(incidentSysId)) {
return []
}
try {
var similarity = new sn_ml.SimilarityPredictor("incident_similarity")
var results = similarity.findSimilar(incident, maxResults)
var similar = []
for (var i = 0; i < results.length; i++) {
var match = results[i]
similar.push({
sys_id: match.getRecordSysId(),
similarity_score: match.getSimilarityScore(),
record: match.getRecord(),
})
}
return similar
} catch (e) {
gs.error("Similarity search failed: " + e.message)
return []
}
}
// Widget Server Script for similar records (ES5 ONLY!)
;(function () {
if (!input || !input.table || !input.sys_id) {
data.similar = []
return
}
var solutionName = input.table + "_similarity"
try {
var gr = new GlideRecord(input.table)
if (!gr.get(input.sys_id)) {
data.similar = []
return
}
var similarity = new sn_ml.SimilarityPredictor(solutionName)
var results = similarity.findSimilar(gr, 5)
data.similar = []
for (var i = 0; i < results.length; i++) {
var match = results[i]
var record = match.getRecord()
data.similar.push({
sys_id: match.getRecordSysId(),
score: Math.round(match.getSimilarityScore() * 100),
number: record.getValue("number"),
short_description: record.getValue("short_description"),
state: record.state.getDisplayValue(),
})
}
} catch (e) {
data.error = "Similarity search unavailable"
data.similar = []
}
})()
// Get cluster for record (ES5 ONLY!)
function getClusterAssignment(tableName, recordSysId, solutionName) {
var gr = new GlideRecord(tableName)
if (!gr.get(recordSysId)) {
return null
}
try {
var clustering = new sn_ml.ClusteringPredictor(solutionName)
var result = clustering.predict(gr)
return {
cluster_id: result.getClusterId(),
cluster_label: result.getClusterLabel(),
confidence: result.getConfidence(),
}
} catch (e) {
gs.error("Clustering failed: " + e.message)
return null
}
}
// Get cluster statistics (ES5 ONLY!)
function getClusterStats(solutionName) {
var stats = []
var cluster = new GlideRecord("ml_cluster")
cluster.addQuery("solution.name", solutionName)
cluster.query()
while (cluster.next()) {
stats.push({
cluster_id: cluster.getValue("cluster_id"),
label: cluster.getValue("label"),
size: parseInt(cluster.getValue("record_count"), 10),
keywords: cluster.getValue("keywords"),
})
}
return stats
}
// Trigger retraining of ML solution (ES5 ONLY!)
function retrainSolution(solutionName) {
var solution = new GlideRecord("ml_solution")
if (!solution.get("name", solutionName)) {
gs.error("Solution not found: " + solutionName)
return false
}
try {
// Queue training job
var trainer = new sn_ml.MLTrainer()
trainer.train(solution.getUniqueValue())
gs.info("Training queued for solution: " + solutionName)
return true
} catch (e) {
gs.error("Training failed: " + e.message)
return false
}
}
// Check model training status (ES5 ONLY!)
function getTrainingStatus(solutionName) {
var model = new GlideRecord("ml_model")
model.addQuery("solution.name", solutionName)
model.orderByDesc("sys_created_on")
model.setLimit(1)
model.query()
if (model.next()) {
return {
model_id: model.getUniqueValue(),
status: model.getValue("state"),
accuracy: model.getValue("accuracy"),
trained_on: model.getValue("sys_created_on"),
record_count: model.getValue("training_record_count"),
}
}
return null
}
// Record prediction feedback for model improvement (ES5 ONLY!)
function recordPredictionFeedback(predictionSysId, wasCorrect, actualValue) {
var prediction = new GlideRecord("ml_prediction_result")
if (!prediction.get(predictionSysId)) {
return false
}
prediction.setValue("feedback", wasCorrect ? "correct" : "incorrect")
prediction.setValue("actual_value", actualValue)
prediction.setValue("feedback_date", new GlideDateTime())
prediction.setValue("feedback_user", gs.getUserID())
prediction.update()
return true
}
// Get prediction accuracy stats (ES5 ONLY!)
function getPredictionAccuracy(solutionName, days) {
days = days || 30
var startDate = new GlideDateTime()
startDate.addDaysLocalTime(-days)
var ga = new GlideAggregate("ml_prediction_result")
ga.addQuery("solution.name", solutionName)
ga.addQuery("sys_created_on", ">=", startDate)
ga.addNotNullQuery("feedback")
ga.addAggregate("COUNT")
ga.groupBy("feedback")
ga.query()
var stats = { correct: 0, incorrect: 0 }
while (ga.next()) {
var feedback = ga.getValue("feedback")
var count = parseInt(ga.getAggregate("COUNT"), 10)
stats[feedback] = count
}
var total = stats.correct + stats.incorrect
stats.accuracy = total > 0 ? Math.round((stats.correct / total) * 100) : 0
stats.total = total
return stats
}
| Tool | Purpose |
| --------------------------------- | ------------------- |
| snow_query_table | Query ML tables |
| snow_execute_script_with_output | Test predictions |
| ml_predict_change_risk | Predict change risk |
| ml_detect_anomalies | Anomaly detection |
// 1. Query ML solutions
await snow_query_table({
table: "ml_solution",
query: "active=true",
fields: "name,table,capability,target_field",
})
// 2. Check model status
await snow_query_table({
table: "ml_model",
query: "solution.active=true",
fields: "solution,state,accuracy,sys_created_on",
})
// 3. Test prediction
await snow_execute_script_with_output({
script: `
var result = getClassificationPrediction('incident', 'inc_sys_id', 'incident_classifier');
gs.info(JSON.stringify(result));
`,
})
development
This skill should be used when the user asks to "App Engine Studio", "workspace builder", "custom workspace", "AES", "low code", "app development", "studio", or any ServiceNow App Engine Studio development.
tools
This skill should be used when the user asks to "create a widget", "build a widget", "service portal widget", "sp_widget", "fix widget", "widget not working", "ng-click not working", or any Service Portal widget development.
development
This skill should be used when the user asks to "create chatbot", "virtual agent", "VA topic", "NLU", "conversation", "chat flow", "topic block", or any ServiceNow Virtual Agent development.
development
This skill should be used when the user asks to "vendor", "supplier", "contract", "procurement", "SLA", "vendor risk", "vendor performance", or any ServiceNow Vendor Management development.