ciscollm-cli 1.3.3 → 1.3.5
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/README.md +19 -25
- package/dist/cli/commands/daemonCommand.d.ts +4 -0
- package/dist/cli/commands/daemonCommand.js +68 -0
- package/dist/cli/commands/daemonCommand.js.map +1 -0
- package/dist/cli/commands/monitorCommand.js +17 -1
- package/dist/cli/commands/monitorCommand.js.map +1 -1
- package/dist/cli/commands/runCommand.d.ts +1 -3
- package/dist/cli/commands/runCommand.js +177 -470
- package/dist/cli/commands/runCommand.js.map +1 -1
- package/dist/cli/ui/interactiveWizard.d.ts +1 -0
- package/dist/cli/ui/interactiveWizard.js +429 -0
- package/dist/cli/ui/interactiveWizard.js.map +1 -0
- package/dist/cli/ui/ui.js +0 -5
- package/dist/cli/ui/ui.js.map +1 -1
- package/dist/core/agent/AgentLoop.d.ts +15 -3
- package/dist/core/agent/AgentLoop.js +196 -67
- package/dist/core/agent/AgentLoop.js.map +1 -1
- package/dist/core/agent/AutoRemediationEngine.d.ts +14 -0
- package/dist/core/agent/AutoRemediationEngine.js +75 -0
- package/dist/core/agent/AutoRemediationEngine.js.map +1 -0
- package/dist/core/agent/DigitalTwin.d.ts +10 -0
- package/dist/core/agent/DigitalTwin.js +41 -0
- package/dist/core/agent/DigitalTwin.js.map +1 -0
- package/dist/core/agent/IntentTranslator.d.ts +8 -0
- package/dist/core/agent/IntentTranslator.js +63 -0
- package/dist/core/agent/IntentTranslator.js.map +1 -0
- package/dist/core/agent/MemoryManager.d.ts +14 -0
- package/dist/core/agent/MemoryManager.js +89 -0
- package/dist/core/agent/MemoryManager.js.map +1 -0
- package/dist/core/agent/MultiAgentCoordinator.js +0 -2
- package/dist/core/agent/MultiAgentCoordinator.js.map +1 -1
- package/dist/core/agent/NetworkPlanner.d.ts +9 -0
- package/dist/core/agent/NetworkPlanner.js +111 -0
- package/dist/core/agent/NetworkPlanner.js.map +1 -0
- package/dist/core/agent/PromptEngine.d.ts +1 -1
- package/dist/core/agent/PromptEngine.js +23 -13
- package/dist/core/agent/PromptEngine.js.map +1 -1
- package/dist/core/guardrails/NetworkAudit.js +1 -1
- package/dist/core/guardrails/NetworkAudit.js.map +1 -1
- package/dist/core/plugins/PluginManager.d.ts +17 -0
- package/dist/core/plugins/PluginManager.js +108 -0
- package/dist/core/plugins/PluginManager.js.map +1 -0
- package/dist/core/rollback/TransactionManager.js +0 -5
- package/dist/core/rollback/TransactionManager.js.map +1 -1
- package/dist/index.js +36 -61
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/llm/LLMClient.d.ts +1 -0
- package/dist/infrastructure/llm/LLMClient.js +33 -9
- package/dist/infrastructure/llm/LLMClient.js.map +1 -1
- package/dist/infrastructure/protocols/SshSession.d.ts +1 -0
- package/dist/infrastructure/protocols/SshSession.js +5 -4
- package/dist/infrastructure/protocols/SshSession.js.map +1 -1
- package/dist/infrastructure/protocols/TelnetSession.d.ts +1 -0
- package/dist/infrastructure/protocols/TelnetSession.js +5 -1
- package/dist/infrastructure/protocols/TelnetSession.js.map +1 -1
- package/dist/server/devices/ASADevice.d.ts +17 -0
- package/dist/server/devices/ASADevice.js +160 -0
- package/dist/server/devices/ASADevice.js.map +1 -0
- package/dist/server/devices/BaseDevice.d.ts +11 -0
- package/dist/server/devices/BaseDevice.js +19 -0
- package/dist/server/devices/BaseDevice.js.map +1 -0
- package/dist/server/devices/IOSDevice.d.ts +100 -0
- package/dist/server/devices/IOSDevice.js +1561 -0
- package/dist/server/devices/IOSDevice.js.map +1 -0
- package/dist/server/devices/LinuxServerDevice.d.ts +8 -0
- package/dist/server/devices/LinuxServerDevice.js +71 -0
- package/dist/server/devices/LinuxServerDevice.js.map +1 -0
- package/dist/server/devices/PCDevice.d.ts +20 -0
- package/dist/server/devices/PCDevice.js +86 -0
- package/dist/server/devices/PCDevice.js.map +1 -0
- package/dist/server/devices/RouterDevice.d.ts +4 -0
- package/dist/server/devices/RouterDevice.js +11 -0
- package/dist/server/devices/RouterDevice.js.map +1 -0
- package/dist/server/devices/SwitchDevice.d.ts +4 -0
- package/dist/server/devices/SwitchDevice.js +11 -0
- package/dist/server/devices/SwitchDevice.js.map +1 -0
- package/dist/server/devices/WLCDevice.d.ts +15 -0
- package/dist/server/devices/WLCDevice.js +88 -0
- package/dist/server/devices/WLCDevice.js.map +1 -0
- package/dist/server/index.js +47 -22
- package/dist/server/index.js.map +1 -1
- package/dist/server/shell-simulator.js +1 -2
- package/dist/server/shell-simulator.js.map +1 -1
- package/dist/server/ssh.d.ts +2 -1
- package/dist/server/ssh.js +22 -9
- package/dist/server/ssh.js.map +1 -1
- package/dist/server/telnet.d.ts +3 -2
- package/dist/server/telnet.js +10 -42
- package/dist/server/telnet.js.map +1 -1
- package/dist/shared/bootBanner.d.ts +1 -0
- package/dist/shared/bootBanner.js +93 -0
- package/dist/shared/bootBanner.js.map +1 -0
- package/dist/shared/constants.js +1 -1
- package/dist/shared/constants.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/commands/dashboardCommand.d.ts +0 -1
- package/dist/cli/commands/dashboardCommand.js +0 -16
- package/dist/cli/commands/dashboardCommand.js.map +0 -1
- package/dist/cli/commands/shellCommand.d.ts +0 -1
- package/dist/cli/commands/shellCommand.js +0 -44
- package/dist/cli/commands/shellCommand.js.map +0 -1
- package/dist/infrastructure/protocols/CmlSession.d.ts +0 -26
- package/dist/infrastructure/protocols/CmlSession.js +0 -448
- package/dist/infrastructure/protocols/CmlSession.js.map +0 -1
- package/dist/infrastructure/protocols/NetconfSession.d.ts +0 -74
- package/dist/infrastructure/protocols/NetconfSession.js +0 -553
- package/dist/infrastructure/protocols/NetconfSession.js.map +0 -1
- package/dist/server/dashboard.d.ts +0 -3
- package/dist/server/dashboard.js +0 -1149
- package/dist/server/dashboard.js.map +0 -1
|
@@ -7,6 +7,7 @@ exports.runAction = runAction;
|
|
|
7
7
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
10
11
|
const MultiAgentCoordinator_1 = require("../../core/agent/MultiAgentCoordinator");
|
|
11
12
|
const PlinkSerial_1 = require("../../infrastructure/protocols/PlinkSerial");
|
|
12
13
|
const SshSession_1 = require("../../infrastructure/protocols/SshSession");
|
|
@@ -14,8 +15,10 @@ const TelnetSession_1 = require("../../infrastructure/protocols/TelnetSession");
|
|
|
14
15
|
const LLMClient_1 = require("../../infrastructure/llm/LLMClient");
|
|
15
16
|
const AgentLoop_1 = require("../../core/agent/AgentLoop");
|
|
16
17
|
const ui_1 = require("../ui/ui");
|
|
17
|
-
const
|
|
18
|
-
|
|
18
|
+
const interactiveWizard_1 = require("../ui/interactiveWizard");
|
|
19
|
+
const NetworkPlanner_1 = require("../../core/agent/NetworkPlanner");
|
|
20
|
+
const IntentTranslator_1 = require("../../core/agent/IntentTranslator");
|
|
21
|
+
async function runAction(options, coordinatorWrapper, cleanup) {
|
|
19
22
|
let provider = options.provider;
|
|
20
23
|
let localType = options.localType;
|
|
21
24
|
if (localType) {
|
|
@@ -46,7 +49,6 @@ async function runAction(options, coordinatorWrapper, dashboardWrapper, cleanup)
|
|
|
46
49
|
let refTelemetry = options.refTelemetry !== false;
|
|
47
50
|
let nonInteractive = options.nonInteractive === true;
|
|
48
51
|
let rbacRole = options.rbacRole || 'admin';
|
|
49
|
-
let dashboardPort = options.dashboardPort ? parseInt(options.dashboardPort, 10) : 3000;
|
|
50
52
|
if (nonInteractive) {
|
|
51
53
|
process.env.CISCOLLM_NON_INTERACTIVE = 'true';
|
|
52
54
|
}
|
|
@@ -78,463 +80,76 @@ async function runAction(options, coordinatorWrapper, dashboardWrapper, cleanup)
|
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
if (!localType)
|
|
81
|
-
localType = '
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
localType: localType || 'ollama',
|
|
89
|
-
apiKey: apiKey || '',
|
|
90
|
-
model: model || '',
|
|
91
|
-
endpoint: endpoint || '',
|
|
92
|
-
protocol: protocol || 'serial',
|
|
93
|
-
com: com || '',
|
|
94
|
-
baud: baud || '9600',
|
|
95
|
-
host: host || '',
|
|
96
|
-
port: port || '',
|
|
97
|
-
username: username || '',
|
|
98
|
-
password: password || '',
|
|
99
|
-
goal: ''
|
|
100
|
-
};
|
|
101
|
-
const goForward = (nextStep) => {
|
|
102
|
-
history.push(currentStep);
|
|
103
|
-
currentStep = nextStep;
|
|
104
|
-
};
|
|
105
|
-
const goBack = () => {
|
|
106
|
-
if (history.length > 0) {
|
|
107
|
-
currentStep = history.pop();
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
ui_1.logger.warn('Already at the first step.');
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
const refreshConsole = () => {
|
|
114
|
-
console.clear();
|
|
115
|
-
ui_1.logger.banner();
|
|
116
|
-
if (detectedComs.length > 0) {
|
|
117
|
-
ui_1.logger.info('Detected active COM ports on system:');
|
|
118
|
-
for (const port of detectedComs) {
|
|
119
|
-
console.log(` ${chalk_1.default.yellow('•')} ${chalk_1.default.yellow(port)}`);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
console.log('');
|
|
123
|
-
};
|
|
124
|
-
while (currentStep !== 'CONFIRMATION') {
|
|
125
|
-
refreshConsole();
|
|
126
|
-
switch (currentStep) {
|
|
127
|
-
case 'PROVIDER': {
|
|
128
|
-
const ans = await inquirer_1.default.prompt([
|
|
129
|
-
{
|
|
130
|
-
type: 'list',
|
|
131
|
-
name: 'provider',
|
|
132
|
-
message: 'Select LLM Provider:',
|
|
133
|
-
choices: [
|
|
134
|
-
{ name: 'Local (Ollama / LM Studio)', value: 'local' },
|
|
135
|
-
{ name: 'Cloud (OpenRouter)', value: 'cloud' }
|
|
136
|
-
],
|
|
137
|
-
default: answers.provider
|
|
138
|
-
}
|
|
139
|
-
]);
|
|
140
|
-
answers.provider = ans.provider;
|
|
141
|
-
if (answers.provider === 'local') {
|
|
142
|
-
goForward('LOCAL_TYPE');
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
goForward('API_KEY');
|
|
146
|
-
}
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
case 'LOCAL_TYPE': {
|
|
150
|
-
const ans = await inquirer_1.default.prompt([
|
|
151
|
-
{
|
|
152
|
-
type: 'list',
|
|
153
|
-
name: 'localType',
|
|
154
|
-
message: 'Select Local LLM Service:',
|
|
155
|
-
choices: [
|
|
156
|
-
{ name: 'Ollama', value: 'ollama' },
|
|
157
|
-
{ name: 'LM Studio', value: 'lmstudio' },
|
|
158
|
-
{ name: chalk_1.default.dim('< Go Back'), value: '__back__' }
|
|
159
|
-
],
|
|
160
|
-
default: answers.localType
|
|
161
|
-
}
|
|
162
|
-
]);
|
|
163
|
-
if (ans.localType === '__back__') {
|
|
164
|
-
goBack();
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
answers.localType = ans.localType;
|
|
168
|
-
goForward('MODEL');
|
|
169
|
-
}
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
case 'API_KEY': {
|
|
173
|
-
const ans = await inquirer_1.default.prompt([
|
|
174
|
-
{
|
|
175
|
-
type: 'input',
|
|
176
|
-
name: 'apiKey',
|
|
177
|
-
message: 'Enter OpenRouter API Key (or type "back" to go back):',
|
|
178
|
-
default: answers.apiKey || undefined
|
|
179
|
-
}
|
|
180
|
-
]);
|
|
181
|
-
if (ans.apiKey.trim().toLowerCase() === 'back') {
|
|
182
|
-
goBack();
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
answers.apiKey = ans.apiKey;
|
|
186
|
-
goForward('MODEL');
|
|
187
|
-
}
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
case 'MODEL': {
|
|
191
|
-
const defaultModel = answers.model || (answers.provider === 'cloud'
|
|
192
|
-
? 'nvidia/nemotron-3-super-120b-a12b:free'
|
|
193
|
-
: 'qwen3.5:4b');
|
|
194
|
-
const ans = await inquirer_1.default.prompt([
|
|
195
|
-
{
|
|
196
|
-
type: 'input',
|
|
197
|
-
name: 'model',
|
|
198
|
-
message: 'Enter LLM Model Name (or type "back" to go back):',
|
|
199
|
-
default: defaultModel
|
|
200
|
-
}
|
|
201
|
-
]);
|
|
202
|
-
if (ans.model.trim().toLowerCase() === 'back') {
|
|
203
|
-
goBack();
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
answers.model = ans.model;
|
|
207
|
-
goForward('ENDPOINT');
|
|
208
|
-
}
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
case 'ENDPOINT': {
|
|
212
|
-
const defaultEndpoint = answers.endpoint || (answers.provider === 'cloud'
|
|
213
|
-
? 'https://openrouter.ai/api/v1'
|
|
214
|
-
: (answers.localType === 'lmstudio'
|
|
215
|
-
? 'http://127.0.0.1:1234/v1'
|
|
216
|
-
: 'http://127.0.0.1:11434/v1'));
|
|
217
|
-
const ans = await inquirer_1.default.prompt([
|
|
218
|
-
{
|
|
219
|
-
type: 'input',
|
|
220
|
-
name: 'endpoint',
|
|
221
|
-
message: 'Enter LLM API Endpoint URL (or type "back" to go back):',
|
|
222
|
-
default: defaultEndpoint
|
|
223
|
-
}
|
|
224
|
-
]);
|
|
225
|
-
if (ans.endpoint.trim().toLowerCase() === 'back') {
|
|
226
|
-
goBack();
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
answers.endpoint = ans.endpoint;
|
|
230
|
-
goForward('PROTOCOL');
|
|
231
|
-
}
|
|
232
|
-
break;
|
|
233
|
-
}
|
|
234
|
-
case 'PROTOCOL': {
|
|
235
|
-
const ans = await inquirer_1.default.prompt([
|
|
236
|
-
{
|
|
237
|
-
type: 'list',
|
|
238
|
-
name: 'protocol',
|
|
239
|
-
message: 'Select Connection Protocol:',
|
|
240
|
-
choices: [
|
|
241
|
-
{ name: 'serial', value: 'serial' },
|
|
242
|
-
{ name: 'ssh', value: 'ssh' },
|
|
243
|
-
{ name: 'telnet', value: 'telnet' },
|
|
244
|
-
{ name: chalk_1.default.dim('< Go Back'), value: '__back__' }
|
|
245
|
-
],
|
|
246
|
-
default: answers.protocol
|
|
247
|
-
}
|
|
248
|
-
]);
|
|
249
|
-
if (ans.protocol === '__back__') {
|
|
250
|
-
goBack();
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
answers.protocol = ans.protocol;
|
|
254
|
-
if (answers.protocol === 'serial') {
|
|
255
|
-
goForward('SERIAL_COM');
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
goForward('IP_HOST');
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
break;
|
|
262
|
-
}
|
|
263
|
-
case 'SERIAL_COM': {
|
|
264
|
-
if (detectedComs.length > 0) {
|
|
265
|
-
const choices = detectedComs.map(port => {
|
|
266
|
-
const match = /^(COM\d+)\b/i.exec(port);
|
|
267
|
-
const portValue = match ? match[1].toUpperCase() : port;
|
|
268
|
-
return { name: port, value: portValue };
|
|
269
|
-
});
|
|
270
|
-
choices.push({ name: 'Enter COM port(s) manually', value: '__manual__' });
|
|
271
|
-
choices.push({ name: chalk_1.default.dim('< Go Back'), value: '__back__' });
|
|
272
|
-
const ans = await inquirer_1.default.prompt([
|
|
273
|
-
{
|
|
274
|
-
type: 'checkbox',
|
|
275
|
-
name: 'coms',
|
|
276
|
-
message: 'Select COM Port(s) (Use Space to select, Enter to confirm):',
|
|
277
|
-
choices: choices,
|
|
278
|
-
validate: (input) => {
|
|
279
|
-
if (input.length === 0) {
|
|
280
|
-
return 'You must select at least one option.';
|
|
281
|
-
}
|
|
282
|
-
if (input.includes('__back__') && input.length > 1) {
|
|
283
|
-
return 'Cannot select "< Go Back" along with other ports.';
|
|
284
|
-
}
|
|
285
|
-
if (input.includes('__manual__') && input.length > 1) {
|
|
286
|
-
return 'Cannot select "Enter COM port(s) manually" along with other ports.';
|
|
287
|
-
}
|
|
288
|
-
return true;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
]);
|
|
292
|
-
if (ans.coms.includes('__back__')) {
|
|
293
|
-
goBack();
|
|
294
|
-
}
|
|
295
|
-
else if (ans.coms.includes('__manual__')) {
|
|
296
|
-
const manualAns = await inquirer_1.default.prompt([
|
|
297
|
-
{
|
|
298
|
-
type: 'input',
|
|
299
|
-
name: 'com',
|
|
300
|
-
message: 'Enter COM Port name(s) (comma-separated, e.g. COM3 or COM3,COM4):',
|
|
301
|
-
validate: (input) => input.trim().length > 0 ? true : 'COM port is required.'
|
|
302
|
-
}
|
|
303
|
-
]);
|
|
304
|
-
answers.com = manualAns.com;
|
|
305
|
-
goForward('SERIAL_BAUD');
|
|
306
|
-
}
|
|
307
|
-
else {
|
|
308
|
-
answers.com = ans.coms.join(',');
|
|
309
|
-
goForward('SERIAL_BAUD');
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
const ans = await inquirer_1.default.prompt([
|
|
314
|
-
{
|
|
315
|
-
type: 'input',
|
|
316
|
-
name: 'com',
|
|
317
|
-
message: 'Enter COM Port name(s) (comma-separated, e.g. COM3 or COM3,COM4) (or type "back" to go back):',
|
|
318
|
-
default: answers.com || undefined,
|
|
319
|
-
validate: (input) => {
|
|
320
|
-
if (input.trim().toLowerCase() === 'back')
|
|
321
|
-
return true;
|
|
322
|
-
return input.trim().length > 0 ? true : 'COM port is required.';
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
]);
|
|
326
|
-
if (ans.com.trim().toLowerCase() === 'back') {
|
|
327
|
-
goBack();
|
|
328
|
-
}
|
|
329
|
-
else {
|
|
330
|
-
answers.com = ans.com;
|
|
331
|
-
goForward('SERIAL_BAUD');
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
break;
|
|
335
|
-
}
|
|
336
|
-
case 'SERIAL_BAUD': {
|
|
337
|
-
const ans = await inquirer_1.default.prompt([
|
|
338
|
-
{
|
|
339
|
-
type: 'list',
|
|
340
|
-
name: 'baud',
|
|
341
|
-
message: 'Select Serial Baud Rate:',
|
|
342
|
-
choices: [
|
|
343
|
-
'9600', '19200', '38400', '57600', '115200',
|
|
344
|
-
{ name: chalk_1.default.dim('< Go Back'), value: '__back__' }
|
|
345
|
-
],
|
|
346
|
-
default: answers.baud
|
|
347
|
-
}
|
|
348
|
-
]);
|
|
349
|
-
if (ans.baud === '__back__') {
|
|
350
|
-
goBack();
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
answers.baud = ans.baud;
|
|
354
|
-
goForward('GOAL');
|
|
355
|
-
}
|
|
356
|
-
break;
|
|
357
|
-
}
|
|
358
|
-
case 'IP_HOST': {
|
|
359
|
-
const ans = await inquirer_1.default.prompt([
|
|
360
|
-
{
|
|
361
|
-
type: 'input',
|
|
362
|
-
name: 'host',
|
|
363
|
-
message: 'Enter Target IP address(es) / Hostname(s) (comma-separated) (or type "back" to go back):',
|
|
364
|
-
default: answers.host || undefined,
|
|
365
|
-
validate: (input) => {
|
|
366
|
-
if (input.trim().toLowerCase() === 'back')
|
|
367
|
-
return true;
|
|
368
|
-
return input.trim().length > 0 ? true : 'Host address is required.';
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
]);
|
|
372
|
-
if (ans.host.trim().toLowerCase() === 'back') {
|
|
373
|
-
goBack();
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
answers.host = ans.host;
|
|
377
|
-
goForward('IP_PORT');
|
|
378
|
-
}
|
|
379
|
-
break;
|
|
380
|
-
}
|
|
381
|
-
case 'IP_PORT': {
|
|
382
|
-
const ans = await inquirer_1.default.prompt([
|
|
383
|
-
{
|
|
384
|
-
type: 'input',
|
|
385
|
-
name: 'port',
|
|
386
|
-
message: 'Enter Connection Port (leave empty for default) (or type "back" to go back):',
|
|
387
|
-
default: answers.port || undefined
|
|
388
|
-
}
|
|
389
|
-
]);
|
|
390
|
-
if (ans.port.trim().toLowerCase() === 'back') {
|
|
391
|
-
goBack();
|
|
392
|
-
}
|
|
393
|
-
else {
|
|
394
|
-
answers.port = ans.port;
|
|
395
|
-
goForward('IP_USER');
|
|
396
|
-
}
|
|
397
|
-
break;
|
|
398
|
-
}
|
|
399
|
-
case 'IP_USER': {
|
|
400
|
-
const ans = await inquirer_1.default.prompt([
|
|
401
|
-
{
|
|
402
|
-
type: 'input',
|
|
403
|
-
name: 'username',
|
|
404
|
-
message: 'Enter Device Username (leave empty if none) (or type "back" to go back):',
|
|
405
|
-
default: answers.username || undefined
|
|
406
|
-
}
|
|
407
|
-
]);
|
|
408
|
-
if (ans.username.trim().toLowerCase() === 'back') {
|
|
409
|
-
goBack();
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
answers.username = ans.username;
|
|
413
|
-
goForward('IP_PASS');
|
|
414
|
-
}
|
|
415
|
-
break;
|
|
416
|
-
}
|
|
417
|
-
case 'IP_PASS': {
|
|
418
|
-
const ans = await inquirer_1.default.prompt([
|
|
419
|
-
{
|
|
420
|
-
type: 'password',
|
|
421
|
-
name: 'password',
|
|
422
|
-
message: 'Enter Device Password (or type "back" to go back):',
|
|
423
|
-
default: answers.password || undefined
|
|
424
|
-
}
|
|
425
|
-
]);
|
|
426
|
-
if (ans.password === 'back') {
|
|
427
|
-
goBack();
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
430
|
-
answers.password = ans.password;
|
|
431
|
-
goForward('GOAL');
|
|
432
|
-
}
|
|
433
|
-
break;
|
|
434
|
-
}
|
|
435
|
-
case 'GOAL': {
|
|
436
|
-
const ans = await inquirer_1.default.prompt([
|
|
437
|
-
{
|
|
438
|
-
type: 'input',
|
|
439
|
-
name: 'goal',
|
|
440
|
-
message: 'Enter Execution Goal / Intent (or type "back" to go back):',
|
|
441
|
-
default: answers.goal || undefined,
|
|
442
|
-
validate: (input) => {
|
|
443
|
-
if (input.trim().toLowerCase() === 'back')
|
|
444
|
-
return true;
|
|
445
|
-
return input.trim().length > 0 ? true : 'Execution goal is required.';
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
]);
|
|
449
|
-
if (ans.goal.trim().toLowerCase() === 'back') {
|
|
450
|
-
goBack();
|
|
451
|
-
}
|
|
452
|
-
else {
|
|
453
|
-
answers.goal = ans.goal;
|
|
454
|
-
goForward('CONFIRMATION');
|
|
455
|
-
}
|
|
456
|
-
break;
|
|
457
|
-
}
|
|
458
|
-
case 'CONFIRMATION':
|
|
459
|
-
break;
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
// Show configuration confirmation wizard summary
|
|
463
|
-
refreshConsole();
|
|
464
|
-
console.log(chalk_1.default.bold.yellow('=== CISCOLLM CONFIGURATION CONFIRMATION ==='));
|
|
465
|
-
console.log(`• Provider: ${chalk_1.default.green(answers.provider.toUpperCase())}`);
|
|
466
|
-
if (answers.provider === 'local') {
|
|
467
|
-
console.log(`• Local Type: ${chalk_1.default.green(answers.localType.toUpperCase())}`);
|
|
468
|
-
}
|
|
469
|
-
console.log(`• Model: ${chalk_1.default.green(answers.model || 'qwen3.5:4b')}`);
|
|
470
|
-
console.log(`• Endpoint URL: ${chalk_1.default.green(answers.endpoint)}`);
|
|
471
|
-
console.log(`• Protocol: ${chalk_1.default.green(answers.protocol.toUpperCase())}`);
|
|
472
|
-
if (answers.protocol === 'serial') {
|
|
473
|
-
console.log(`• COM Port(s): ${chalk_1.default.green(answers.com)}`);
|
|
474
|
-
console.log(`• Baud Rate: ${chalk_1.default.green(answers.baud)}`);
|
|
475
|
-
}
|
|
476
|
-
else {
|
|
477
|
-
console.log(`• Host IP(s): ${chalk_1.default.green(answers.host)}`);
|
|
478
|
-
console.log(`• Connection Port: ${chalk_1.default.green(answers.port || '(default)')}`);
|
|
479
|
-
console.log(`• Login Username: ${chalk_1.default.green(answers.username || '(none)')}`);
|
|
83
|
+
localType = 'lmstudio';
|
|
84
|
+
let sessionName = options.sessions;
|
|
85
|
+
const sessionsFilePath = (0, path_1.join)(process.cwd(), 'sessions.json');
|
|
86
|
+
let savedSessions = {};
|
|
87
|
+
if ((0, fs_1.existsSync)(sessionsFilePath)) {
|
|
88
|
+
try {
|
|
89
|
+
savedSessions = JSON.parse((0, fs_1.readFileSync)(sessionsFilePath, 'utf8'));
|
|
480
90
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
91
|
+
catch (e) { }
|
|
92
|
+
}
|
|
93
|
+
if (sessionName && savedSessions[sessionName]) {
|
|
94
|
+
const s = savedSessions[sessionName];
|
|
95
|
+
provider = provider || s.provider;
|
|
96
|
+
localType = localType || s.localType;
|
|
97
|
+
apiKey = apiKey || s.apiKey;
|
|
98
|
+
model = model || s.model;
|
|
99
|
+
endpoint = endpoint || s.endpoint;
|
|
100
|
+
protocol = protocol || s.protocol;
|
|
101
|
+
com = com || s.com;
|
|
102
|
+
baud = baud || s.baud;
|
|
103
|
+
host = host || s.host;
|
|
104
|
+
port = port || s.port;
|
|
105
|
+
username = username || s.username;
|
|
106
|
+
password = password || s.password;
|
|
107
|
+
ui_1.logger.info(`Loaded session '${sessionName}' from ${sessionsFilePath}`);
|
|
108
|
+
}
|
|
109
|
+
options.provider = provider;
|
|
110
|
+
options.localType = localType;
|
|
111
|
+
options.apiKey = apiKey;
|
|
112
|
+
options.model = model;
|
|
113
|
+
options.endpoint = endpoint;
|
|
114
|
+
options.protocol = protocol;
|
|
115
|
+
options.com = com;
|
|
116
|
+
options.baud = baud;
|
|
117
|
+
options.host = host;
|
|
118
|
+
options.port = port;
|
|
119
|
+
options.username = username;
|
|
120
|
+
options.password = password;
|
|
121
|
+
if (!com && !host) {
|
|
122
|
+
const answers = await (0, interactiveWizard_1.runInteractiveWizard)(options, false);
|
|
123
|
+
provider = answers.provider;
|
|
124
|
+
localType = answers.localType;
|
|
125
|
+
apiKey = answers.apiKey;
|
|
126
|
+
model = answers.model;
|
|
127
|
+
endpoint = answers.endpoint;
|
|
128
|
+
protocol = answers.protocol;
|
|
129
|
+
com = answers.com;
|
|
130
|
+
baud = answers.baud;
|
|
131
|
+
host = answers.host;
|
|
132
|
+
port = answers.port;
|
|
133
|
+
username = answers.username;
|
|
134
|
+
password = answers.password;
|
|
135
|
+
if (answers.goal)
|
|
509
136
|
goal = answers.goal;
|
|
137
|
+
}
|
|
138
|
+
if (sessionName) {
|
|
139
|
+
savedSessions[sessionName] = {
|
|
140
|
+
provider, localType, apiKey, model, endpoint, protocol, com, baud, host, port, username, password
|
|
141
|
+
};
|
|
142
|
+
try {
|
|
143
|
+
(0, fs_1.writeFileSync)(sessionsFilePath, JSON.stringify(savedSessions, null, 2), 'utf8');
|
|
144
|
+
ui_1.logger.info(`Session setup saved to '${sessionName}' in ${sessionsFilePath}`);
|
|
510
145
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
currentStep = 'GOAL';
|
|
514
|
-
// Loop back to prompt goal
|
|
515
|
-
// Wait, we need to restart the wizard loop! Let's re-run this function or let the while loop run.
|
|
516
|
-
// Because currentStep is set to 'GOAL' and answers are preserved, calling runAction again is easiest.
|
|
517
|
-
options.goal = undefined;
|
|
518
|
-
return runAction(options, coordinatorWrapper, dashboardWrapper, cleanup);
|
|
519
|
-
}
|
|
520
|
-
else if (confirmAns.confirm === 'restart') {
|
|
521
|
-
options.goal = undefined;
|
|
522
|
-
return runAction({ ...options, provider: undefined, localType: undefined, model: undefined, endpoint: undefined, protocol: undefined, com: undefined, host: undefined, username: undefined, password: undefined }, coordinatorWrapper, dashboardWrapper, cleanup);
|
|
523
|
-
}
|
|
524
|
-
else {
|
|
525
|
-
ui_1.logger.info('Configuration wizard cancelled.');
|
|
526
|
-
process.exit(0);
|
|
146
|
+
catch (err) {
|
|
147
|
+
ui_1.logger.warn(`Failed to save session: ${err.message}`);
|
|
527
148
|
}
|
|
528
149
|
}
|
|
529
150
|
ui_1.logger.info(`Initializing system link in [${provider.toUpperCase()}] mode using ${protocol.toUpperCase()}...`);
|
|
530
151
|
ui_1.logger.info(`Command reference policy: strict=${strictCommandRef ? 'on' : 'off'}, telemetry=${refTelemetry ? 'on' : 'off'}`);
|
|
531
152
|
coordinatorWrapper.active = new MultiAgentCoordinator_1.MultiAgentCoordinator();
|
|
532
|
-
try {
|
|
533
|
-
dashboardWrapper.server = (0, dashboard_1.startDashboardServer)(coordinatorWrapper.active, dashboardPort);
|
|
534
|
-
}
|
|
535
|
-
catch (e) {
|
|
536
|
-
ui_1.logger.warn(`Failed to auto-start live Visual Control Dashboard: ${e.message}`);
|
|
537
|
-
}
|
|
538
153
|
try {
|
|
539
154
|
if (protocol === 'serial') {
|
|
540
155
|
if (!com) {
|
|
@@ -552,13 +167,28 @@ async function runAction(options, coordinatorWrapper, dashboardWrapper, cleanup)
|
|
|
552
167
|
}
|
|
553
168
|
const hosts = host.split(',').map((h) => h.trim()).filter((h) => h.length > 0);
|
|
554
169
|
for (const h of hosts) {
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
170
|
+
if (provider === 'local' && (h === '127.0.0.1' || h === 'localhost')) {
|
|
171
|
+
const basePort = port ? parseInt(port, 10) : 2222;
|
|
172
|
+
for (let i = 0; i < 6; i++) {
|
|
173
|
+
const currentPort = basePort + i;
|
|
174
|
+
const session = new SshSession_1.SshSession({
|
|
175
|
+
host: h,
|
|
176
|
+
port: currentPort,
|
|
177
|
+
username: username,
|
|
178
|
+
password: password
|
|
179
|
+
});
|
|
180
|
+
coordinatorWrapper.active.registerSession(`${h}:${currentPort}`, session);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
const session = new SshSession_1.SshSession({
|
|
185
|
+
host: h,
|
|
186
|
+
port: port ? parseInt(port, 10) : 22,
|
|
187
|
+
username: username,
|
|
188
|
+
password: password
|
|
189
|
+
});
|
|
190
|
+
coordinatorWrapper.active.registerSession(h, session);
|
|
191
|
+
}
|
|
562
192
|
}
|
|
563
193
|
}
|
|
564
194
|
else if (protocol === 'telnet') {
|
|
@@ -580,14 +210,14 @@ async function runAction(options, coordinatorWrapper, dashboardWrapper, cleanup)
|
|
|
580
210
|
throw new Error(`Unsupported connection protocol type: ${protocol}`);
|
|
581
211
|
}
|
|
582
212
|
if (provider === 'local' && !endpoint) {
|
|
583
|
-
if (localType === '
|
|
584
|
-
endpoint = 'http://127.0.0.1:1234/v1';
|
|
585
|
-
ui_1.logger.info(`LM Studio endpoint: ${chalk_1.default.cyan(endpoint)}`);
|
|
586
|
-
}
|
|
587
|
-
else {
|
|
213
|
+
if (localType === 'ollama') {
|
|
588
214
|
endpoint = 'http://127.0.0.1:11434/v1';
|
|
589
215
|
ui_1.logger.info(`Ollama endpoint: ${chalk_1.default.cyan(endpoint)}`);
|
|
590
216
|
}
|
|
217
|
+
else {
|
|
218
|
+
endpoint = 'http://127.0.0.1:1234/v1';
|
|
219
|
+
ui_1.logger.info(`LM Studio endpoint: ${chalk_1.default.cyan(endpoint)}`);
|
|
220
|
+
}
|
|
591
221
|
}
|
|
592
222
|
const localAIClient = new LLMClient_1.LLMClient(provider, endpoint, model, apiKey, localType);
|
|
593
223
|
const llmSpinner = (0, ui_1.createSpinner)('Preflight check: validating LLM endpoint reachability...').start();
|
|
@@ -616,12 +246,89 @@ async function runAction(options, coordinatorWrapper, dashboardWrapper, cleanup)
|
|
|
616
246
|
connSpinner.fail('Connection failed.');
|
|
617
247
|
throw err;
|
|
618
248
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
249
|
+
if (!goal) {
|
|
250
|
+
const { chatGoal } = await inquirer_1.default.prompt([
|
|
251
|
+
{
|
|
252
|
+
type: 'input',
|
|
253
|
+
name: 'chatGoal',
|
|
254
|
+
message: 'Enter your goal or instruction:',
|
|
255
|
+
validate: (input) => input.trim().length > 0 ? true : 'Goal cannot be empty.'
|
|
256
|
+
}
|
|
257
|
+
]);
|
|
258
|
+
goal = chatGoal;
|
|
259
|
+
}
|
|
260
|
+
const classSpinner = (0, ui_1.createSpinner)('Analyzing intent complexity...').start();
|
|
261
|
+
const complexity = await IntentTranslator_1.IntentTranslator.categorizeComplexityWithLLM(localAIClient, goal);
|
|
262
|
+
classSpinner.stop();
|
|
263
|
+
let currentGoal = goal;
|
|
264
|
+
if (complexity === 'QUERY_ONLY') {
|
|
265
|
+
ui_1.logger.info(chalk_1.default.cyan('🔍 Network Query Mode Enabled. Read-only commands expected.'));
|
|
266
|
+
const agent = new AgentLoop_1.CiscoAgentLoop(localAIClient, coordinatorWrapper.active, {
|
|
267
|
+
strictReferenceMode: strictCommandRef,
|
|
268
|
+
referenceTelemetry: refTelemetry,
|
|
269
|
+
rbacRole: rbacRole,
|
|
270
|
+
fastTrack: true,
|
|
271
|
+
queryOnly: true,
|
|
272
|
+
safeMode: options.safeMode === true
|
|
273
|
+
});
|
|
274
|
+
await agent.run(`User Query (Read-Only): ${currentGoal}`);
|
|
275
|
+
}
|
|
276
|
+
else if (complexity === 'FAST_TRACK') {
|
|
277
|
+
ui_1.logger.info(chalk_1.default.green('🚀 Fast Track Execution Mode Enabled. Bypassing planner & backups.'));
|
|
278
|
+
const agent = new AgentLoop_1.CiscoAgentLoop(localAIClient, coordinatorWrapper.active, {
|
|
279
|
+
strictReferenceMode: strictCommandRef,
|
|
280
|
+
referenceTelemetry: refTelemetry,
|
|
281
|
+
rbacRole: rbacRole,
|
|
282
|
+
fastTrack: true,
|
|
283
|
+
safeMode: options.safeMode === true
|
|
284
|
+
});
|
|
285
|
+
await agent.run(`User Goal (Fast Track): ${currentGoal}`);
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
const agent = new AgentLoop_1.CiscoAgentLoop(localAIClient, coordinatorWrapper.active, {
|
|
289
|
+
strictReferenceMode: strictCommandRef,
|
|
290
|
+
referenceTelemetry: refTelemetry,
|
|
291
|
+
rbacRole: rbacRole,
|
|
292
|
+
safeMode: options.safeMode === true
|
|
293
|
+
});
|
|
294
|
+
const planner = new NetworkPlanner_1.NetworkPlanner(localAIClient, coordinatorWrapper.active);
|
|
295
|
+
let planApproved = false;
|
|
296
|
+
while (!planApproved) {
|
|
297
|
+
const plan = await planner.generatePlan(currentGoal);
|
|
298
|
+
const impact = await planner.simulateImpact(plan);
|
|
299
|
+
const { planAction } = await inquirer_1.default.prompt([
|
|
300
|
+
{
|
|
301
|
+
type: 'list',
|
|
302
|
+
name: 'planAction',
|
|
303
|
+
message: chalk_1.default.cyan('Review the Orchestration Plan above. What would you like to do?'),
|
|
304
|
+
choices: [
|
|
305
|
+
{ name: 'Approve and Execute', value: 'approve' },
|
|
306
|
+
{ name: 'Provide Feedback / Revise Plan', value: 'revise' },
|
|
307
|
+
{ name: 'Cancel Execution', value: 'cancel' }
|
|
308
|
+
]
|
|
309
|
+
}
|
|
310
|
+
]);
|
|
311
|
+
if (planAction === 'approve') {
|
|
312
|
+
planApproved = true;
|
|
313
|
+
currentGoal = `Approved Execution Blueprint:\n${plan}\n\nUser Goal: ${currentGoal}`;
|
|
314
|
+
}
|
|
315
|
+
else if (planAction === 'revise') {
|
|
316
|
+
const { feedback } = await inquirer_1.default.prompt([
|
|
317
|
+
{
|
|
318
|
+
type: 'input',
|
|
319
|
+
name: 'feedback',
|
|
320
|
+
message: 'Enter your feedback to revise the plan:'
|
|
321
|
+
}
|
|
322
|
+
]);
|
|
323
|
+
currentGoal = `${currentGoal}\nFeedback for revision: ${feedback}`;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
ui_1.logger.info('Execution cancelled by user.');
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
await agent.run(currentGoal);
|
|
331
|
+
}
|
|
625
332
|
}
|
|
626
333
|
catch (err) {
|
|
627
334
|
ui_1.logger.critical(`Execution Error: ${err.message}`);
|