powergrid-ai 1.2.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/bin/powergrid.js +132 -0
- package/lib/setup.js +79 -0
- package/package.json +40 -0
package/bin/powergrid.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PowerGrid CLI — Node.js wrapper for the Python powergrid-ai package.
|
|
5
|
+
*
|
|
6
|
+
* Detects Python, ensures powergrid-ai is installed via pip, then proxies
|
|
7
|
+
* all CLI arguments to the Python `powergrid` command.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { spawn, execSync } = require("child_process");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Helpers
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
function findPython() {
|
|
18
|
+
const candidates =
|
|
19
|
+
process.platform === "win32"
|
|
20
|
+
? ["python", "python3", "py"]
|
|
21
|
+
: ["python3", "python", "python3.12", "python3.11"];
|
|
22
|
+
|
|
23
|
+
for (const cmd of candidates) {
|
|
24
|
+
try {
|
|
25
|
+
const out = execSync(`${cmd} -c "import sys; print(sys.version_info[:2])"`, {
|
|
26
|
+
encoding: "utf8",
|
|
27
|
+
timeout: 5000,
|
|
28
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
29
|
+
}).trim();
|
|
30
|
+
// out looks like "(3, 12)"
|
|
31
|
+
const match = out.match(/\((\d+),\s*(\d+)\)/);
|
|
32
|
+
if (match) {
|
|
33
|
+
const major = parseInt(match[1], 10);
|
|
34
|
+
const minor = parseInt(match[2], 10);
|
|
35
|
+
if (major >= 3 && minor >= 11) {
|
|
36
|
+
return { cmd, version: `${major}.${minor}` };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
// not found or too old, try next
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isPowergridInstalled(pythonCmd) {
|
|
47
|
+
try {
|
|
48
|
+
execSync(`${pythonCmd} -m powergrid --help`, {
|
|
49
|
+
encoding: "utf8",
|
|
50
|
+
timeout: 5000,
|
|
51
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
52
|
+
});
|
|
53
|
+
return true;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function installPowergrid(pythonCmd) {
|
|
60
|
+
console.log("powergrid-ai: Installing Python package via pip...");
|
|
61
|
+
try {
|
|
62
|
+
execSync(`${pythonCmd} -m pip install powergrid-ai --quiet`, {
|
|
63
|
+
encoding: "utf8",
|
|
64
|
+
timeout: 120000,
|
|
65
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
66
|
+
});
|
|
67
|
+
console.log("powergrid-ai: Installed successfully!");
|
|
68
|
+
return true;
|
|
69
|
+
} catch (e) {
|
|
70
|
+
console.error(`powergrid-ai: Failed to install — ${e.message}`);
|
|
71
|
+
console.error("powergrid-ai: Try manually: pip install powergrid-ai");
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Main
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
function main() {
|
|
81
|
+
const args = process.argv.slice(2);
|
|
82
|
+
|
|
83
|
+
// --help from the wrapper itself
|
|
84
|
+
if (args.includes("--version") && !args.includes("--help")) {
|
|
85
|
+
console.log("powergrid-ai (npm wrapper) v1.1.0");
|
|
86
|
+
try {
|
|
87
|
+
const pyVer = execSync("python -c \"import powergrid; print(powergrid.__version__)\"", {
|
|
88
|
+
encoding: "utf8",
|
|
89
|
+
timeout: 5000,
|
|
90
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
91
|
+
}).trim();
|
|
92
|
+
console.log(`powergrid (python) v${pyVer}`);
|
|
93
|
+
} catch {
|
|
94
|
+
console.log("powergrid (python) — not installed yet");
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Find Python
|
|
100
|
+
const python = findPython();
|
|
101
|
+
if (!python) {
|
|
102
|
+
console.error("powergrid-ai: Python 3.11+ is required but not found.");
|
|
103
|
+
console.error("powergrid-ai: Install Python from https://python.org/downloads");
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Check if powergrid is installed, install if not
|
|
108
|
+
if (!isPowergridInstalled(python.cmd)) {
|
|
109
|
+
console.log(`powergrid-ai: Python ${python.version} found (${python.cmd})`);
|
|
110
|
+
if (!installPowergrid(python.cmd)) {
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Proxy to the Python CLI
|
|
116
|
+
const child = spawn(python.cmd, ["-m", "powergrid", ...args], {
|
|
117
|
+
stdio: "inherit",
|
|
118
|
+
cwd: process.cwd(),
|
|
119
|
+
env: process.env,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
child.on("exit", (code) => {
|
|
123
|
+
process.exit(code ?? 0);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
child.on("error", (e) => {
|
|
127
|
+
console.error(`powergrid-ai: Failed to run — ${e.message}`);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
main();
|
package/lib/setup.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Post-install script — ensures the Python powergrid-ai package is installed.
|
|
5
|
+
* Runs automatically after `npm install powergrid-ai`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { execSync } = require("child_process");
|
|
9
|
+
|
|
10
|
+
function findPython() {
|
|
11
|
+
const candidates =
|
|
12
|
+
process.platform === "win32"
|
|
13
|
+
? ["python", "python3", "py"]
|
|
14
|
+
: ["python3", "python", "python3.12", "python3.11"];
|
|
15
|
+
|
|
16
|
+
for (const cmd of candidates) {
|
|
17
|
+
try {
|
|
18
|
+
const out = execSync(`${cmd} -c "import sys; print(sys.version_info[:2])"`, {
|
|
19
|
+
encoding: "utf8",
|
|
20
|
+
timeout: 5000,
|
|
21
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
22
|
+
}).trim();
|
|
23
|
+
const match = out.match(/\((\d+),\s*(\d+)\)/);
|
|
24
|
+
if (match) {
|
|
25
|
+
const major = parseInt(match[1], 10);
|
|
26
|
+
const minor = parseInt(match[2], 10);
|
|
27
|
+
if (major >= 3 && minor >= 11) return cmd;
|
|
28
|
+
}
|
|
29
|
+
} catch {
|
|
30
|
+
// continue
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function main() {
|
|
37
|
+
// Skip if in CI or if --ignore-scripts
|
|
38
|
+
if (process.env.CI || process.env.npm_config_ignore_scripts) return;
|
|
39
|
+
|
|
40
|
+
const python = findPython();
|
|
41
|
+
if (!python) {
|
|
42
|
+
console.log("");
|
|
43
|
+
console.log("powergrid-ai: Python 3.11+ not found.");
|
|
44
|
+
console.log("powergrid-ai: Install Python from https://python.org/downloads");
|
|
45
|
+
console.log("powergrid-ai: Then run: pip install powergrid-ai");
|
|
46
|
+
console.log("");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Check if already installed
|
|
51
|
+
try {
|
|
52
|
+
execSync(`${python} -m powergrid --help`, {
|
|
53
|
+
encoding: "utf8",
|
|
54
|
+
timeout: 5000,
|
|
55
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
56
|
+
});
|
|
57
|
+
// Already installed
|
|
58
|
+
return;
|
|
59
|
+
} catch {
|
|
60
|
+
// Not installed, install it
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log(`powergrid-ai: Python ${python} found. Installing Python package...`);
|
|
64
|
+
try {
|
|
65
|
+
execSync(`${python} -m pip install powergrid-ai --quiet`, {
|
|
66
|
+
encoding: "utf8",
|
|
67
|
+
timeout: 120000,
|
|
68
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
69
|
+
});
|
|
70
|
+
console.log("powergrid-ai: Ready! Run: powergrid --help");
|
|
71
|
+
} catch (e) {
|
|
72
|
+
console.log("");
|
|
73
|
+
console.log("powergrid-ai: Auto-install failed. Install manually:");
|
|
74
|
+
console.log(` ${python} -m pip install powergrid-ai`);
|
|
75
|
+
console.log("");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "powergrid-ai",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Local-first AI routing runtime — one AI, many engines. Wraps the Python powergrid-ai package.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"routing",
|
|
8
|
+
"llm",
|
|
9
|
+
"openai",
|
|
10
|
+
"local-first",
|
|
11
|
+
"multi-provider",
|
|
12
|
+
"failover",
|
|
13
|
+
"groq",
|
|
14
|
+
"gemini",
|
|
15
|
+
"cerebras"
|
|
16
|
+
],
|
|
17
|
+
"author": "Michael Moses",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/micymike/powergrid"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/micymike/powergrid#readme",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/micymike/powergrid/issues"
|
|
26
|
+
},
|
|
27
|
+
"bin": {
|
|
28
|
+
"powergrid": "bin/powergrid.js"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"bin",
|
|
35
|
+
"lib"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"postinstall": "node lib/setup.js"
|
|
39
|
+
}
|
|
40
|
+
}
|