@ols-cli/lightspeed 0.1.1 → 0.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/ols.js +84 -51
- package/package.json +3 -6
package/bin/ols.js
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* ols — OpenShift Lightspeed CLI
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* ols Interactive mode
|
|
7
|
-
* ols "how do I scale?" One-shot query
|
|
8
|
-
* ols health Check OLS health
|
|
9
|
-
* ols conversations List conversations
|
|
10
|
-
* ols config set <key> <val> Set config
|
|
11
|
-
* ols config show Show config
|
|
4
|
+
* AI-powered assistant with OLS + NVIDIA NIM backends
|
|
12
5
|
*/
|
|
13
|
-
const { OLSClient, loadOLSConfig, saveOLSConfig } = require("@ols-cli/client");
|
|
6
|
+
const { OLSClient, smartQuery, loadOLSConfig, saveOLSConfig } = require("@ols-cli/client");
|
|
14
7
|
|
|
15
8
|
const cyan = "\x1b[36m";
|
|
16
9
|
const green = "\x1b[32m";
|
|
@@ -24,7 +17,11 @@ function configCmd(args) {
|
|
|
24
17
|
const cmd = args[0];
|
|
25
18
|
if (!cmd || cmd === "show") {
|
|
26
19
|
const cfg = loadOLSConfig();
|
|
27
|
-
|
|
20
|
+
// Mask API keys
|
|
21
|
+
const safe = { ...cfg };
|
|
22
|
+
if (safe.nimApiKey) safe.nimApiKey = safe.nimApiKey.slice(0, 8) + "...";
|
|
23
|
+
if (safe._conversationId) delete safe._conversationId;
|
|
24
|
+
console.log(JSON.stringify(safe, null, 2));
|
|
28
25
|
return;
|
|
29
26
|
}
|
|
30
27
|
if (cmd === "set" && args[1] && args[2] !== undefined) {
|
|
@@ -37,34 +34,60 @@ function configCmd(args) {
|
|
|
37
34
|
}
|
|
38
35
|
if (cmd === "init") {
|
|
39
36
|
console.log(`${cyan}OpenShift Lightspeed CLI Configuration${reset}\n`);
|
|
37
|
+
console.log(" # Option 1: OpenShift Lightspeed Service");
|
|
40
38
|
console.log(" ols config set serviceUrl https://lightspeed-service.example.com:8443");
|
|
41
|
-
console.log("
|
|
42
|
-
console.log("
|
|
39
|
+
console.log("");
|
|
40
|
+
console.log(" # Option 2: NVIDIA NIM (works without OLS)");
|
|
41
|
+
console.log(" ols config set nimApiKey nvapi-xxxxx");
|
|
42
|
+
console.log(" ols config set nimModel nvidia/llama-3.1-nemotron-70b-instruct");
|
|
43
|
+
console.log("");
|
|
44
|
+
console.log(" # Auth from kubeconfig (for OLS): oc login");
|
|
43
45
|
return;
|
|
44
46
|
}
|
|
45
47
|
console.log("Usage: ols config [show|set|init]");
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
async function healthCmd() {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
51
|
+
const cfg = loadOLSConfig();
|
|
52
|
+
console.log(`\n${bold}Health Check${reset}\n`);
|
|
53
|
+
|
|
54
|
+
// Check OLS
|
|
55
|
+
if (cfg.serviceUrl) {
|
|
56
|
+
try {
|
|
57
|
+
const client = new OLSClient(cfg);
|
|
58
|
+
const h = await client.health();
|
|
59
|
+
console.log(` ${green}✓${reset} OLS: ${h.status}`);
|
|
60
|
+
} catch (e) {
|
|
61
|
+
console.log(` ${red}✗${reset} OLS: ${e.message}`);
|
|
58
62
|
}
|
|
59
|
-
}
|
|
60
|
-
console.
|
|
61
|
-
|
|
63
|
+
} else {
|
|
64
|
+
console.log(` ${yellow}○${reset} OLS: not configured`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check NIM
|
|
68
|
+
if (cfg.nimApiKey) {
|
|
69
|
+
try {
|
|
70
|
+
const { NIMClient } = require("@ols-cli/client");
|
|
71
|
+
const nim = new NIMClient(cfg);
|
|
72
|
+
const resp = await nim.chat([{ role: "user", content: "ping" }]);
|
|
73
|
+
console.log(` ${green}✓${reset} NIM: connected (${cfg.nimModel || "default model"})`);
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.log(` ${red}✗${reset} NIM: ${e.message}`);
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
console.log(` ${yellow}○${reset} NIM: not configured (set nimApiKey)`);
|
|
62
79
|
}
|
|
80
|
+
console.log();
|
|
63
81
|
}
|
|
64
82
|
|
|
65
83
|
async function conversationsCmd() {
|
|
84
|
+
const cfg = loadOLSConfig();
|
|
85
|
+
if (!cfg.serviceUrl) {
|
|
86
|
+
console.log(`${yellow}OLS not configured. Set serviceUrl first.${reset}`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
66
89
|
try {
|
|
67
|
-
const client = new OLSClient(
|
|
90
|
+
const client = new OLSClient(cfg);
|
|
68
91
|
const convos = await client.listConversations();
|
|
69
92
|
if (convos.length === 0) {
|
|
70
93
|
console.log(`${dim}No conversations found.${reset}`);
|
|
@@ -77,38 +100,37 @@ async function conversationsCmd() {
|
|
|
77
100
|
}
|
|
78
101
|
} catch (e) {
|
|
79
102
|
console.error(`${red}✗${reset} ${e.message}`);
|
|
80
|
-
process.exit(1);
|
|
81
103
|
}
|
|
82
104
|
}
|
|
83
105
|
|
|
84
106
|
async function queryCmd(question) {
|
|
85
107
|
try {
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
console.log(`\n${
|
|
89
|
-
if (
|
|
108
|
+
const cfg = loadOLSConfig();
|
|
109
|
+
const result = await smartQuery(question, cfg, []);
|
|
110
|
+
console.log(`\n${result.response}\n`);
|
|
111
|
+
if (result.references && result.references.length) {
|
|
90
112
|
console.log(`${dim}References:${reset}`);
|
|
91
|
-
for (const doc of
|
|
113
|
+
for (const doc of result.references) {
|
|
92
114
|
console.log(` ${cyan}→${reset} ${doc.title} ${dim}(${doc.url})${reset}`);
|
|
93
115
|
}
|
|
94
116
|
console.log();
|
|
95
117
|
}
|
|
96
|
-
|
|
97
|
-
console.log(`${dim}Conversation: ${resp.conversation_id}${reset}`);
|
|
98
|
-
}
|
|
118
|
+
console.log(`${dim}via ${result.source}${reset}`);
|
|
99
119
|
} catch (e) {
|
|
100
120
|
console.error(`${red}✗${reset} ${e.message}`);
|
|
101
|
-
process.exit(1);
|
|
102
121
|
}
|
|
103
122
|
}
|
|
104
123
|
|
|
105
124
|
async function interactiveMode() {
|
|
106
125
|
const readline = require("readline");
|
|
126
|
+
const cfg = loadOLSConfig();
|
|
127
|
+
|
|
128
|
+
const backend = cfg.nimApiKey ? (cfg.serviceUrl ? "OLS + NIM" : "NIM") : "OLS";
|
|
107
129
|
|
|
108
|
-
console.log(`\n${bold}${cyan}OpenShift Lightspeed CLI${reset} v0.
|
|
130
|
+
console.log(`\n${bold}${cyan}OpenShift Lightspeed CLI${reset} v0.2.0 ${dim}[${backend}]${reset}`);
|
|
109
131
|
console.log(`${dim}Type your question, or 'quit' to exit.${reset}\n`);
|
|
110
132
|
|
|
111
|
-
|
|
133
|
+
const history = [];
|
|
112
134
|
|
|
113
135
|
const rl = readline.createInterface({
|
|
114
136
|
input: process.stdin,
|
|
@@ -127,19 +149,22 @@ async function interactiveMode() {
|
|
|
127
149
|
}
|
|
128
150
|
if (input === "health") { await healthCmd(); rl.prompt(); return; }
|
|
129
151
|
if (input === "conversations") { await conversationsCmd(); rl.prompt(); return; }
|
|
152
|
+
if (input === "config") { configCmd(["show"]); rl.prompt(); return; }
|
|
130
153
|
|
|
131
154
|
try {
|
|
132
|
-
const
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
155
|
+
const currentCfg = loadOLSConfig();
|
|
156
|
+
const result = await smartQuery(input, currentCfg, history);
|
|
157
|
+
history.push({ role: "user", content: input });
|
|
158
|
+
history.push({ role: "assistant", content: result.response });
|
|
159
|
+
console.log(`\n${result.response}\n`);
|
|
160
|
+
if (result.references && result.references.length) {
|
|
137
161
|
console.log(`${dim}References:${reset}`);
|
|
138
|
-
for (const doc of
|
|
162
|
+
for (const doc of result.references) {
|
|
139
163
|
console.log(` ${cyan}→${reset} ${doc.title}`);
|
|
140
164
|
}
|
|
141
165
|
console.log();
|
|
142
166
|
}
|
|
167
|
+
console.log(`${dim}via ${result.source}${reset}`);
|
|
143
168
|
} catch (e) {
|
|
144
169
|
console.error(`${red}✗${reset} ${e.message}`);
|
|
145
170
|
}
|
|
@@ -149,26 +174,34 @@ async function interactiveMode() {
|
|
|
149
174
|
|
|
150
175
|
async function main() {
|
|
151
176
|
const args = process.argv.slice(2);
|
|
152
|
-
|
|
153
|
-
if (args.length === 0) {
|
|
154
|
-
return interactiveMode();
|
|
155
|
-
}
|
|
177
|
+
if (args.length === 0) return interactiveMode();
|
|
156
178
|
|
|
157
179
|
const cmd = args[0];
|
|
158
|
-
|
|
159
180
|
if (cmd === "config") return configCmd(args.slice(1));
|
|
160
181
|
if (cmd === "health") return await healthCmd();
|
|
161
182
|
if (cmd === "conversations" || cmd === "convos") return await conversationsCmd();
|
|
162
183
|
if (cmd === "--help" || cmd === "-h" || cmd === "help") {
|
|
163
|
-
console.log(`${bold}
|
|
184
|
+
console.log(`${bold}OpenShift Lightspeed CLI${reset}
|
|
185
|
+
|
|
186
|
+
${bold}Usage:${reset}
|
|
164
187
|
ols Interactive mode
|
|
165
188
|
ols "your question" One-shot query
|
|
166
|
-
ols health Check
|
|
167
|
-
ols conversations List
|
|
189
|
+
ols health Check backends health
|
|
190
|
+
ols conversations List OLS conversations
|
|
168
191
|
ols config show Show configuration
|
|
169
192
|
ols config set <key> <val> Set config value
|
|
170
193
|
ols config init Setup help
|
|
171
194
|
ols help This help
|
|
195
|
+
|
|
196
|
+
${bold}Config keys:${reset}
|
|
197
|
+
serviceUrl OLS service URL
|
|
198
|
+
nimApiKey NVIDIA NIM API key (fallback LLM)
|
|
199
|
+
nimModel NIM model name
|
|
200
|
+
nimBaseUrl NIM API base URL
|
|
201
|
+
|
|
202
|
+
${bold}Backends:${reset}
|
|
203
|
+
1. OLS (OpenShift Lightspeed Service) — primary
|
|
204
|
+
2. NVIDIA NIM (OpenAI-compatible) — fallback
|
|
172
205
|
`);
|
|
173
206
|
return;
|
|
174
207
|
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ols-cli/lightspeed",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "OpenShift Lightspeed CLI — AI-powered assistant for OpenShift from your terminal",
|
|
5
|
-
"type": "module",
|
|
6
5
|
"bin": {
|
|
7
6
|
"ols": "./bin/ols.js"
|
|
8
7
|
},
|
|
9
|
-
"main": "./src/index.js",
|
|
10
8
|
"files": [
|
|
11
9
|
"bin",
|
|
12
|
-
"src",
|
|
13
10
|
"skills",
|
|
14
11
|
"README.md",
|
|
15
12
|
"CHANGELOG.md"
|
|
@@ -19,7 +16,7 @@
|
|
|
19
16
|
},
|
|
20
17
|
"keywords": [
|
|
21
18
|
"openshift", "lightspeed", "ols", "kubernetes", "cli",
|
|
22
|
-
"ai-agent", "assistant", "terminal", "devops"
|
|
19
|
+
"ai-agent", "assistant", "terminal", "devops", "nvidia", "nim"
|
|
23
20
|
],
|
|
24
21
|
"author": "Chin (kcns008)",
|
|
25
22
|
"license": "Apache-2.0",
|
|
@@ -38,6 +35,6 @@
|
|
|
38
35
|
"access": "public"
|
|
39
36
|
},
|
|
40
37
|
"dependencies": {
|
|
41
|
-
"@ols-cli/client": "^0.
|
|
38
|
+
"@ols-cli/client": "^0.2.0"
|
|
42
39
|
}
|
|
43
40
|
}
|