@codnx/mlxd 1.0.0
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/LICENSE +40 -0
- package/README.md +212 -0
- package/data/dataset.csv +3 -0
- package/mlxd/LICENSE +40 -0
- package/mlxd/README.md +212 -0
- package/mlxd/config.yaml +17 -0
- package/mlxd/data/dataset.csv +3 -0
- package/mlxd/index.bundle.js +2 -0
- package/mlxd/index.bundle.js.LICENSE.txt +6 -0
- package/mlxd/python/model_inference.py +71 -0
- package/package.json +58 -0
- package/postinstall.js +65 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
import sys
|
3
|
+
import json
|
4
|
+
import numpy as np
|
5
|
+
from sklearn.metrics import accuracy_score, f1_score, mean_squared_error
|
6
|
+
|
7
|
+
# Optional: import real ML libraries
|
8
|
+
# from transformers import AutoModelForSequenceClassification, AutoTokenizer
|
9
|
+
# import torch
|
10
|
+
|
11
|
+
|
12
|
+
def load_dataset(data_path: str):
|
13
|
+
# Replace this logic to load an actual dataset (CSV, JSON, etc.)
|
14
|
+
# Here, we're just simulating random predictions & labels for demo purposes.
|
15
|
+
preds = np.random.randint(0, 2, 100)
|
16
|
+
labels = np.random.randint(0, 2, 100)
|
17
|
+
return preds, labels
|
18
|
+
|
19
|
+
|
20
|
+
def validate_dataset(preds, labels):
|
21
|
+
# Example: Check if we got enough samples or if data is empty.
|
22
|
+
if len(preds) == 0 or len(labels) == 0:
|
23
|
+
return False, "No data found for predictions or labels."
|
24
|
+
if len(preds) != len(labels):
|
25
|
+
return False, "Predictions and labels have different lengths."
|
26
|
+
return True, ""
|
27
|
+
|
28
|
+
|
29
|
+
def load_model(model_path: str):
|
30
|
+
# In a real scenario, load your ML model here (e.g., GPT-Neo, BERT).
|
31
|
+
# Example (commented out):
|
32
|
+
# model = AutoModelForSequenceClassification.from_pretrained(model_path)
|
33
|
+
# tokenizer = AutoTokenizer.from_pretrained(model_path)
|
34
|
+
return None
|
35
|
+
|
36
|
+
|
37
|
+
def main():
|
38
|
+
# CLI arguments:
|
39
|
+
# 1) Metric name (e.g., "accuracy", "f1", "rmse").
|
40
|
+
# 2) Optional dataset path (default: "my_real_dataset.csv").
|
41
|
+
# 3) Optional model path (default: None).
|
42
|
+
metric_name = sys.argv[1] if len(sys.argv) > 1 else "accuracy"
|
43
|
+
data_path = sys.argv[2] if len(sys.argv) > 2 else "my_real_dataset.csv"
|
44
|
+
model_path = sys.argv[3] if len(sys.argv) > 3 else None
|
45
|
+
|
46
|
+
# Load data (predictions & labels) and validate.
|
47
|
+
preds, labels = load_dataset(data_path)
|
48
|
+
passed, message = validate_dataset(preds, labels)
|
49
|
+
if not passed:
|
50
|
+
print(json.dumps({"error": f"Data validation failed: {message}"}))
|
51
|
+
sys.exit(1)
|
52
|
+
|
53
|
+
# Load the model if needed (inference logic not shown in this sample).
|
54
|
+
model = load_model(model_path)
|
55
|
+
|
56
|
+
# Calculate the requested metric.
|
57
|
+
if metric_name == "accuracy":
|
58
|
+
value = accuracy_score(labels, preds)
|
59
|
+
elif metric_name == "f1":
|
60
|
+
value = f1_score(labels, preds)
|
61
|
+
elif metric_name == "rmse":
|
62
|
+
value = mean_squared_error(labels, preds, squared=False)
|
63
|
+
else:
|
64
|
+
value = 0.0
|
65
|
+
|
66
|
+
# Output metric as JSON for the CLI to parse.
|
67
|
+
print(json.dumps({"metric": metric_name, "value": float(value)}))
|
68
|
+
|
69
|
+
|
70
|
+
if __name__ == "__main__":
|
71
|
+
main()
|
package/package.json
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
{
|
2
|
+
"name": "@codnx/mlxd",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "CI/CD Testing Tool for ML",
|
5
|
+
"author": "codin.io",
|
6
|
+
"license": "ISC",
|
7
|
+
"main": "mlxd/index.js",
|
8
|
+
"bin": {
|
9
|
+
"mlxd": "./mlxd/index.bundle.js"
|
10
|
+
},
|
11
|
+
"scripts": {
|
12
|
+
"build": "webpack && rm -rf mlxd/python && cp -r python mlxd/ && cp config.yaml mlxd/ && cp README.md mlxd/ && cp LICENSE mlxd/ && rm -rf mlxd/data && cp -r data mlxd/data",
|
13
|
+
"test": "jest",
|
14
|
+
"postbuild": "node add-shebang.js",
|
15
|
+
"prepublishOnly": "npm run build",
|
16
|
+
"dev": "ts-node src/index.ts",
|
17
|
+
"postinstall": "node postinstall.js"
|
18
|
+
},
|
19
|
+
"files": [
|
20
|
+
"LICENSE",
|
21
|
+
"mlxd/**",
|
22
|
+
"postinstall.js",
|
23
|
+
"data/**"
|
24
|
+
],
|
25
|
+
"devDependencies": {
|
26
|
+
"@types/axios": "^0.14.4",
|
27
|
+
"@types/dotenv": "^8.2.3",
|
28
|
+
"@types/jest": "^29.5.14",
|
29
|
+
"@types/js-yaml": "^4.0.9",
|
30
|
+
"@types/markdown-pdf": "^9.0.5",
|
31
|
+
"@types/mocha": "^10.0.10",
|
32
|
+
"@types/node": "^22.10.5",
|
33
|
+
"@types/nodemailer": "^6.4.17",
|
34
|
+
"@types/papaparse": "^5.3.15",
|
35
|
+
"jest": "^29.7.0",
|
36
|
+
"terser": "^5.37.0",
|
37
|
+
"terser-webpack-plugin": "^5.3.11",
|
38
|
+
"ts-jest": "^29.2.5",
|
39
|
+
"ts-loader": "^9.5.1",
|
40
|
+
"ts-node": "^10.9.2",
|
41
|
+
"typescript": "^4.9.5",
|
42
|
+
"webpack": "^5.97.1",
|
43
|
+
"webpack-cli": "^6.0.1",
|
44
|
+
"webpack-obfuscator": "^3.5.1"
|
45
|
+
},
|
46
|
+
"dependencies": {
|
47
|
+
"axios": "^1.7.9",
|
48
|
+
"dotenv": "^16.4.7",
|
49
|
+
"fs-extra": "^11.2.0",
|
50
|
+
"handlebars": "^4.7.8",
|
51
|
+
"js-yaml": "^4.1.0",
|
52
|
+
"markdown-pdf": "^11.0.0",
|
53
|
+
"nodemailer": "^6.9.16",
|
54
|
+
"papaparse": "^5.4.1",
|
55
|
+
"rimraf": "^5.0.0",
|
56
|
+
"uuid": "^9.0.0"
|
57
|
+
}
|
58
|
+
}
|
package/postinstall.js
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
const fs = require("fs-extra");
|
2
|
+
const path = require("path");
|
3
|
+
|
4
|
+
try {
|
5
|
+
console.log("\n=== Starting postinstall script ===");
|
6
|
+
|
7
|
+
// Get npm_config_local_prefix which points to the actual project root
|
8
|
+
const projectRoot =
|
9
|
+
process.env.INIT_CWD ||
|
10
|
+
process.env.npm_config_local_prefix ||
|
11
|
+
process.cwd();
|
12
|
+
console.log("Project root:", projectRoot);
|
13
|
+
|
14
|
+
// Package root is where postinstall.js is located
|
15
|
+
const packageRoot = __dirname;
|
16
|
+
console.log("Package root:", packageRoot);
|
17
|
+
|
18
|
+
const sourceDir = path.join(packageRoot, "mlxd");
|
19
|
+
const targetDir = path.join(projectRoot, "mlxd");
|
20
|
+
|
21
|
+
console.log("Source directory:", sourceDir);
|
22
|
+
console.log("Target directory:", targetDir);
|
23
|
+
|
24
|
+
// List what's in the package directory
|
25
|
+
console.log("\nPackage directory contents:");
|
26
|
+
console.log(fs.readdirSync(packageRoot));
|
27
|
+
|
28
|
+
if (!fs.existsSync(sourceDir)) {
|
29
|
+
throw new Error(`Source mlxd directory not found at: ${sourceDir}`);
|
30
|
+
}
|
31
|
+
|
32
|
+
if (!fs.existsSync(targetDir)) {
|
33
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
34
|
+
}
|
35
|
+
|
36
|
+
fs.copySync(sourceDir, targetDir, {
|
37
|
+
overwrite: true,
|
38
|
+
errorOnExist: false,
|
39
|
+
});
|
40
|
+
|
41
|
+
// Install mlxd directory as a separate package
|
42
|
+
// const mlxdPackage = require(path.join(targetDir, "package.json"));
|
43
|
+
const mlxdPath = path.join(projectRoot, "node_modules", "mlxd");
|
44
|
+
fs.mkdirSync(mlxdPath, { recursive: true });
|
45
|
+
fs.copySync(targetDir, mlxdPath, {
|
46
|
+
overwrite: true,
|
47
|
+
errorOnExist: false,
|
48
|
+
});
|
49
|
+
|
50
|
+
// Update package.json to include mlxd as a dependency
|
51
|
+
const packageJson = require(path.join(projectRoot, "package.json"));
|
52
|
+
// packageJson.dependencies["@codin-io/mlxd"] = mlxdPackage.version;
|
53
|
+
fs.writeFileSync(
|
54
|
+
path.join(projectRoot, "package.json"),
|
55
|
+
JSON.stringify(packageJson, null, 2)
|
56
|
+
);
|
57
|
+
|
58
|
+
console.log(
|
59
|
+
"\n✅ Successfully copied mlxd to project root and installed as a separate package:",
|
60
|
+
mlxdPath
|
61
|
+
);
|
62
|
+
} catch (error) {
|
63
|
+
console.error("\n❌ Error during postinstall:", error);
|
64
|
+
process.exit(1);
|
65
|
+
}
|