@appkit/llamacpp-cli 1.10.1 → 1.12.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/CHANGELOG.md +10 -0
- package/README.md +356 -3
- package/dist/cli.js +99 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/admin/config.d.ts +10 -0
- package/dist/commands/admin/config.d.ts.map +1 -0
- package/dist/commands/admin/config.js +100 -0
- package/dist/commands/admin/config.js.map +1 -0
- package/dist/commands/admin/logs.d.ts +10 -0
- package/dist/commands/admin/logs.d.ts.map +1 -0
- package/dist/commands/admin/logs.js +114 -0
- package/dist/commands/admin/logs.js.map +1 -0
- package/dist/commands/admin/restart.d.ts +2 -0
- package/dist/commands/admin/restart.d.ts.map +1 -0
- package/dist/commands/admin/restart.js +29 -0
- package/dist/commands/admin/restart.js.map +1 -0
- package/dist/commands/admin/start.d.ts +2 -0
- package/dist/commands/admin/start.d.ts.map +1 -0
- package/dist/commands/admin/start.js +30 -0
- package/dist/commands/admin/start.js.map +1 -0
- package/dist/commands/admin/status.d.ts +2 -0
- package/dist/commands/admin/status.d.ts.map +1 -0
- package/dist/commands/admin/status.js +82 -0
- package/dist/commands/admin/status.js.map +1 -0
- package/dist/commands/admin/stop.d.ts +2 -0
- package/dist/commands/admin/stop.d.ts.map +1 -0
- package/dist/commands/admin/stop.js +21 -0
- package/dist/commands/admin/stop.js.map +1 -0
- package/dist/commands/logs.d.ts +1 -0
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +22 -0
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/server-show.js +1 -1
- package/dist/commands/server-show.js.map +1 -1
- package/dist/lib/admin-manager.d.ts +111 -0
- package/dist/lib/admin-manager.d.ts.map +1 -0
- package/dist/lib/admin-manager.js +413 -0
- package/dist/lib/admin-manager.js.map +1 -0
- package/dist/lib/admin-server.d.ts +148 -0
- package/dist/lib/admin-server.d.ts.map +1 -0
- package/dist/lib/admin-server.js +1161 -0
- package/dist/lib/admin-server.js.map +1 -0
- package/dist/lib/download-job-manager.d.ts +64 -0
- package/dist/lib/download-job-manager.d.ts.map +1 -0
- package/dist/lib/download-job-manager.js +164 -0
- package/dist/lib/download-job-manager.js.map +1 -0
- package/dist/tui/MultiServerMonitorApp.js +2 -2
- package/dist/tui/MultiServerMonitorApp.js.map +1 -1
- package/dist/types/admin-config.d.ts +19 -0
- package/dist/types/admin-config.d.ts.map +1 -0
- package/dist/types/admin-config.js +3 -0
- package/dist/types/admin-config.js.map +1 -0
- package/dist/utils/format-utils.d.ts +6 -0
- package/dist/utils/format-utils.d.ts.map +1 -1
- package/dist/utils/format-utils.js +18 -0
- package/dist/utils/format-utils.js.map +1 -1
- package/dist/utils/log-parser.d.ts +9 -0
- package/dist/utils/log-parser.d.ts.map +1 -1
- package/dist/utils/log-parser.js +11 -0
- package/dist/utils/log-parser.js.map +1 -1
- package/docs/images/web-ui-servers.png +0 -0
- package/package.json +1 -1
- package/src/cli.ts +100 -0
- package/src/commands/admin/config.ts +121 -0
- package/src/commands/admin/logs.ts +91 -0
- package/src/commands/admin/restart.ts +26 -0
- package/src/commands/admin/start.ts +27 -0
- package/src/commands/admin/status.ts +84 -0
- package/src/commands/admin/stop.ts +16 -0
- package/src/commands/logs.ts +24 -0
- package/src/commands/server-show.ts +2 -2
- package/src/lib/admin-manager.ts +435 -0
- package/src/lib/admin-server.ts +1243 -0
- package/src/lib/download-job-manager.ts +213 -0
- package/src/tui/MultiServerMonitorApp.ts +3 -3
- package/src/types/admin-config.ts +25 -0
- package/src/utils/format-utils.ts +18 -0
- package/src/utils/log-parser.ts +13 -0
- package/web/README.md +429 -0
- package/web/eslint.config.js +23 -0
- package/web/index.html +13 -0
- package/web/llamacpp-web-dist.tar.gz +0 -0
- package/web/package-lock.json +4017 -0
- package/web/package.json +38 -0
- package/web/postcss.config.js +6 -0
- package/web/public/vite.svg +1 -0
- package/web/src/App.css +42 -0
- package/web/src/App.tsx +86 -0
- package/web/src/assets/react.svg +1 -0
- package/web/src/components/ApiKeyPrompt.tsx +71 -0
- package/web/src/components/CreateServerModal.tsx +372 -0
- package/web/src/components/DownloadProgress.tsx +123 -0
- package/web/src/components/Nav.tsx +89 -0
- package/web/src/components/RouterConfigModal.tsx +240 -0
- package/web/src/components/SearchModal.tsx +306 -0
- package/web/src/components/ServerConfigModal.tsx +291 -0
- package/web/src/hooks/useApi.ts +259 -0
- package/web/src/index.css +42 -0
- package/web/src/lib/api.ts +226 -0
- package/web/src/main.tsx +10 -0
- package/web/src/pages/Dashboard.tsx +103 -0
- package/web/src/pages/Models.tsx +258 -0
- package/web/src/pages/Router.tsx +270 -0
- package/web/src/pages/RouterLogs.tsx +201 -0
- package/web/src/pages/ServerLogs.tsx +553 -0
- package/web/src/pages/Servers.tsx +358 -0
- package/web/src/types/api.ts +140 -0
- package/web/tailwind.config.js +31 -0
- package/web/tsconfig.app.json +28 -0
- package/web/tsconfig.json +7 -0
- package/web/tsconfig.node.json +26 -0
- package/web/vite.config.ts +25 -0
- package/MONITORING-ACCURACY-FIX.md +0 -199
- package/PER-PROCESS-METRICS.md +0 -190
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type AdminStatus = 'running' | 'stopped' | 'crashed';
|
|
2
|
+
export interface AdminConfig {
|
|
3
|
+
id: 'admin';
|
|
4
|
+
port: number;
|
|
5
|
+
host: string;
|
|
6
|
+
apiKey: string;
|
|
7
|
+
status: AdminStatus;
|
|
8
|
+
pid?: number;
|
|
9
|
+
createdAt: string;
|
|
10
|
+
lastStarted?: string;
|
|
11
|
+
lastStopped?: string;
|
|
12
|
+
plistPath: string;
|
|
13
|
+
label: 'com.llama.admin';
|
|
14
|
+
stdoutPath: string;
|
|
15
|
+
stderrPath: string;
|
|
16
|
+
requestTimeout: number;
|
|
17
|
+
verbose: boolean;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=admin-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-config.d.ts","sourceRoot":"","sources":["../../src/types/admin-config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IAGf,MAAM,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,iBAAiB,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IAGnB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-config.js","sourceRoot":"","sources":["../../src/types/admin-config.ts"],"names":[],"mappings":""}
|
|
@@ -26,4 +26,10 @@ export declare function truncate(str: string, maxLength: number): string;
|
|
|
26
26
|
* Pad a string to a specific length
|
|
27
27
|
*/
|
|
28
28
|
export declare function pad(str: string, length: number, char?: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Format context size to human-readable format
|
|
31
|
+
* Uses "k" suffix for clean multiples of 1024 (e.g., 32768 → "32k")
|
|
32
|
+
* Falls back to full number with "tokens" for non-standard sizes
|
|
33
|
+
*/
|
|
34
|
+
export declare function formatContextSize(tokens: number): string;
|
|
29
35
|
//# sourceMappingURL=format-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-utils.d.ts","sourceRoot":"","sources":["../../src/utils/format-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAStD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAM3D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAgBtD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,MAAM,CAEnE"}
|
|
1
|
+
{"version":3,"file":"format-utils.d.ts","sourceRoot":"","sources":["../../src/utils/format-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAStD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAM3D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAgBtD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,MAAM,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWxD"}
|
|
@@ -6,6 +6,7 @@ exports.formatDateShort = formatDateShort;
|
|
|
6
6
|
exports.formatUptime = formatUptime;
|
|
7
7
|
exports.truncate = truncate;
|
|
8
8
|
exports.pad = pad;
|
|
9
|
+
exports.formatContextSize = formatContextSize;
|
|
9
10
|
/**
|
|
10
11
|
* Format bytes to human-readable size
|
|
11
12
|
* Example: 1900000000 → "1.9 GB"
|
|
@@ -79,4 +80,21 @@ function truncate(str, maxLength) {
|
|
|
79
80
|
function pad(str, length, char = ' ') {
|
|
80
81
|
return str.padEnd(length, char);
|
|
81
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Format context size to human-readable format
|
|
85
|
+
* Uses "k" suffix for clean multiples of 1024 (e.g., 32768 → "32k")
|
|
86
|
+
* Falls back to full number with "tokens" for non-standard sizes
|
|
87
|
+
*/
|
|
88
|
+
function formatContextSize(tokens) {
|
|
89
|
+
// Check if it's a clean multiple of 1024
|
|
90
|
+
if (tokens % 1024 === 0) {
|
|
91
|
+
const k = tokens / 1024;
|
|
92
|
+
// Only use "k" format for reasonable sizes (1k to 1024k i.e., up to 1M)
|
|
93
|
+
if (k >= 1 && k <= 1024) {
|
|
94
|
+
return `${k}k`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// For non-standard sizes or very large values, show full number
|
|
98
|
+
return `${tokens.toLocaleString()} tokens`;
|
|
99
|
+
}
|
|
82
100
|
//# sourceMappingURL=format-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-utils.js","sourceRoot":"","sources":["../../src/utils/format-utils.ts"],"names":[],"mappings":";;AAIA,kCAWC;AAMD,gCASC;AAMD,0CAMC;AAMD,oCAgBC;AAKD,4BAGC;AAKD,kBAEC;
|
|
1
|
+
{"version":3,"file":"format-utils.js","sourceRoot":"","sources":["../../src/utils/format-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
export declare class LogParser {
|
|
5
5
|
private buffer;
|
|
6
6
|
private isBuffering;
|
|
7
|
+
/**
|
|
8
|
+
* Health check endpoints to filter out by default
|
|
9
|
+
* These are polled frequently by the TUI and generate excessive log noise
|
|
10
|
+
*/
|
|
11
|
+
private static readonly HEALTH_CHECK_ENDPOINTS;
|
|
12
|
+
/**
|
|
13
|
+
* Check if a log line represents a health check request
|
|
14
|
+
*/
|
|
15
|
+
isHealthCheckRequest(line: string): boolean;
|
|
7
16
|
/**
|
|
8
17
|
* Check if line is a request status line (contains method/endpoint/status, no JSON)
|
|
9
18
|
* Handles both old and new formats:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-parser.d.ts","sourceRoot":"","sources":["../../src/utils/log-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAS;IAE5B;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAQ3B;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAsCxE;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAcpD;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAsD1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAa1B;AAGD,eAAO,MAAM,SAAS,WAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"log-parser.d.ts","sourceRoot":"","sources":["../../src/utils/log-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAS;IAE5B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAmC;IAEjF;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI3C;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAQ3B;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAsCxE;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAcpD;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAsD1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAa1B;AAGD,eAAO,MAAM,SAAS,WAAkB,CAAC"}
|
package/dist/utils/log-parser.js
CHANGED
|
@@ -9,6 +9,12 @@ class LogParser {
|
|
|
9
9
|
this.buffer = [];
|
|
10
10
|
this.isBuffering = false;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Check if a log line represents a health check request
|
|
14
|
+
*/
|
|
15
|
+
isHealthCheckRequest(line) {
|
|
16
|
+
return LogParser.HEALTH_CHECK_ENDPOINTS.some(ep => line.includes(`GET ${ep} `));
|
|
17
|
+
}
|
|
12
18
|
/**
|
|
13
19
|
* Check if line is a request status line (contains method/endpoint/status, no JSON)
|
|
14
20
|
* Handles both old and new formats:
|
|
@@ -238,6 +244,11 @@ class LogParser {
|
|
|
238
244
|
}
|
|
239
245
|
}
|
|
240
246
|
exports.LogParser = LogParser;
|
|
247
|
+
/**
|
|
248
|
+
* Health check endpoints to filter out by default
|
|
249
|
+
* These are polled frequently by the TUI and generate excessive log noise
|
|
250
|
+
*/
|
|
251
|
+
LogParser.HEALTH_CHECK_ENDPOINTS = ['/health', '/slots', '/props'];
|
|
241
252
|
// Export singleton instance
|
|
242
253
|
exports.logParser = new LogParser();
|
|
243
254
|
//# sourceMappingURL=log-parser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-parser.js","sourceRoot":"","sources":["../../src/utils/log-parser.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAcH,MAAa,SAAS;IAAtB;QACU,WAAM,GAAa,EAAE,CAAC;QACtB,gBAAW,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"log-parser.js","sourceRoot":"","sources":["../../src/utils/log-parser.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -25,6 +25,12 @@ import { routerStatusCommand } from './commands/router/status';
|
|
|
25
25
|
import { routerRestartCommand } from './commands/router/restart';
|
|
26
26
|
import { routerConfigCommand } from './commands/router/config';
|
|
27
27
|
import { routerLogsCommand } from './commands/router/logs';
|
|
28
|
+
import { adminStartCommand } from './commands/admin/start';
|
|
29
|
+
import { adminStopCommand } from './commands/admin/stop';
|
|
30
|
+
import { adminStatusCommand } from './commands/admin/status';
|
|
31
|
+
import { adminRestartCommand } from './commands/admin/restart';
|
|
32
|
+
import { adminConfigCommand } from './commands/admin/config';
|
|
33
|
+
import { adminLogsCommand } from './commands/admin/logs';
|
|
28
34
|
import packageJson from '../package.json';
|
|
29
35
|
|
|
30
36
|
const program = new Command();
|
|
@@ -299,6 +305,7 @@ server
|
|
|
299
305
|
.option('--clear-archived', 'Delete only archived logs (preserves current logs)')
|
|
300
306
|
.option('--clear-all', 'Clear current logs AND delete all archived logs')
|
|
301
307
|
.option('--rotate', 'Rotate log file with timestamp (preserves old logs)')
|
|
308
|
+
.option('--include-health', 'Include health check requests (/health, /slots, /props) - filtered by default')
|
|
302
309
|
.action(async (identifier: string, options) => {
|
|
303
310
|
try {
|
|
304
311
|
await logsCommand(identifier, options);
|
|
@@ -419,5 +426,98 @@ router
|
|
|
419
426
|
}
|
|
420
427
|
});
|
|
421
428
|
|
|
429
|
+
// Admin management commands
|
|
430
|
+
const admin = program
|
|
431
|
+
.command('admin')
|
|
432
|
+
.description('Manage the admin REST API service');
|
|
433
|
+
|
|
434
|
+
// Start admin
|
|
435
|
+
admin
|
|
436
|
+
.command('start')
|
|
437
|
+
.description('Start the admin service')
|
|
438
|
+
.action(async () => {
|
|
439
|
+
try {
|
|
440
|
+
await adminStartCommand();
|
|
441
|
+
} catch (error) {
|
|
442
|
+
console.error(chalk.red('❌ Error:'), (error as Error).message);
|
|
443
|
+
process.exit(1);
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
// Stop admin
|
|
448
|
+
admin
|
|
449
|
+
.command('stop')
|
|
450
|
+
.description('Stop the admin service')
|
|
451
|
+
.action(async () => {
|
|
452
|
+
try {
|
|
453
|
+
await adminStopCommand();
|
|
454
|
+
} catch (error) {
|
|
455
|
+
console.error(chalk.red('❌ Error:'), (error as Error).message);
|
|
456
|
+
process.exit(1);
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// Show admin status
|
|
461
|
+
admin
|
|
462
|
+
.command('status')
|
|
463
|
+
.description('Show admin service status and configuration')
|
|
464
|
+
.action(async () => {
|
|
465
|
+
try {
|
|
466
|
+
await adminStatusCommand();
|
|
467
|
+
} catch (error) {
|
|
468
|
+
console.error(chalk.red('❌ Error:'), (error as Error).message);
|
|
469
|
+
process.exit(1);
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
// Restart admin
|
|
474
|
+
admin
|
|
475
|
+
.command('restart')
|
|
476
|
+
.description('Restart the admin service')
|
|
477
|
+
.action(async () => {
|
|
478
|
+
try {
|
|
479
|
+
await adminRestartCommand();
|
|
480
|
+
} catch (error) {
|
|
481
|
+
console.error(chalk.red('❌ Error:'), (error as Error).message);
|
|
482
|
+
process.exit(1);
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
// Configure admin
|
|
487
|
+
admin
|
|
488
|
+
.command('config')
|
|
489
|
+
.description('Update admin service configuration')
|
|
490
|
+
.option('-p, --port <number>', 'Update port number', parseInt)
|
|
491
|
+
.option('-h, --host <address>', 'Update bind address')
|
|
492
|
+
.option('--regenerate-key', 'Generate a new API key')
|
|
493
|
+
.option('-v, --verbose [boolean]', 'Enable/disable verbose logging', (val) => val === 'true' || val === '1')
|
|
494
|
+
.option('-r, --restart', 'Automatically restart admin service if running')
|
|
495
|
+
.action(async (options) => {
|
|
496
|
+
try {
|
|
497
|
+
await adminConfigCommand(options);
|
|
498
|
+
} catch (error) {
|
|
499
|
+
console.error(chalk.red('❌ Error:'), (error as Error).message);
|
|
500
|
+
process.exit(1);
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
// Admin logs
|
|
505
|
+
admin
|
|
506
|
+
.command('logs')
|
|
507
|
+
.description('View admin service logs')
|
|
508
|
+
.option('-f, --follow', 'Follow logs in real-time (like tail -f)')
|
|
509
|
+
.option('-n, --lines <number>', 'Number of lines to show (default: 100)', parseInt)
|
|
510
|
+
.option('--stdout', 'Show activity logs (stdout)')
|
|
511
|
+
.option('--stderr', 'Show system logs (stderr)')
|
|
512
|
+
.option('--clear', 'Clear the log files')
|
|
513
|
+
.action(async (options) => {
|
|
514
|
+
try {
|
|
515
|
+
await adminLogsCommand(options);
|
|
516
|
+
} catch (error) {
|
|
517
|
+
console.error(chalk.red('❌ Error:'), (error as Error).message);
|
|
518
|
+
process.exit(1);
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
|
|
422
522
|
// Parse arguments
|
|
423
523
|
program.parse();
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { adminManager } from '../../lib/admin-manager';
|
|
3
|
+
|
|
4
|
+
interface ConfigOptions {
|
|
5
|
+
port?: number;
|
|
6
|
+
host?: string;
|
|
7
|
+
regenerateKey?: boolean;
|
|
8
|
+
verbose?: boolean;
|
|
9
|
+
restart?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function adminConfigCommand(options: ConfigOptions): Promise<void> {
|
|
13
|
+
try {
|
|
14
|
+
const result = await adminManager.getStatus();
|
|
15
|
+
|
|
16
|
+
if (!result) {
|
|
17
|
+
console.error(chalk.red('✗ Admin service is not configured'));
|
|
18
|
+
console.log(chalk.gray('\nRun: llamacpp admin start'));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const { config, status } = result;
|
|
23
|
+
|
|
24
|
+
// Check if any options were provided
|
|
25
|
+
const hasChanges = options.port || options.host || options.regenerateKey !== undefined || options.verbose !== undefined;
|
|
26
|
+
if (!hasChanges) {
|
|
27
|
+
console.error(chalk.red('✗ No configuration options provided'));
|
|
28
|
+
console.log(chalk.gray('\nAvailable options:'));
|
|
29
|
+
console.log(chalk.gray(' --port <port> Change port'));
|
|
30
|
+
console.log(chalk.gray(' --host <host> Change host'));
|
|
31
|
+
console.log(chalk.gray(' --regenerate-key Generate new API key'));
|
|
32
|
+
console.log(chalk.gray(' --verbose Enable verbose logging'));
|
|
33
|
+
console.log(chalk.gray(' --restart Restart after config change'));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Display what will change
|
|
38
|
+
console.log(chalk.bold('Configuration Changes:'));
|
|
39
|
+
console.log();
|
|
40
|
+
|
|
41
|
+
const updates: Partial<typeof config> = {};
|
|
42
|
+
|
|
43
|
+
if (options.port !== undefined) {
|
|
44
|
+
console.log(chalk.bold(' Port: '), chalk.gray(config.port.toString()), chalk.gray('→'), chalk.cyan(options.port.toString()));
|
|
45
|
+
updates.port = options.port;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (options.host !== undefined) {
|
|
49
|
+
console.log(chalk.bold(' Host: '), chalk.gray(config.host), chalk.gray('→'), chalk.cyan(options.host));
|
|
50
|
+
updates.host = options.host;
|
|
51
|
+
|
|
52
|
+
// Warn if binding to non-localhost
|
|
53
|
+
if (options.host !== '127.0.0.1' && options.host !== 'localhost') {
|
|
54
|
+
console.log();
|
|
55
|
+
console.log(chalk.yellow(' ⚠ Warning: Binding to non-localhost address exposes admin API to network'));
|
|
56
|
+
console.log(chalk.yellow(' ⚠ Ensure your firewall is properly configured'));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (options.verbose !== undefined) {
|
|
61
|
+
console.log(chalk.bold(' Verbose: '), chalk.gray(config.verbose ? 'enabled' : 'disabled'), chalk.gray('→'), chalk.cyan(options.verbose ? 'enabled' : 'disabled'));
|
|
62
|
+
updates.verbose = options.verbose;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let newApiKey: string | undefined;
|
|
66
|
+
if (options.regenerateKey) {
|
|
67
|
+
newApiKey = await adminManager.regenerateApiKey();
|
|
68
|
+
console.log(chalk.bold(' API Key: '), chalk.gray('*********************'), chalk.gray('→'), chalk.yellow(newApiKey));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log();
|
|
72
|
+
|
|
73
|
+
// Check if restart is needed
|
|
74
|
+
const isRunning = status.isRunning;
|
|
75
|
+
const needsRestart = isRunning && (options.port !== undefined || options.host !== undefined);
|
|
76
|
+
|
|
77
|
+
if (needsRestart && !options.restart) {
|
|
78
|
+
console.log(chalk.yellow('⚠ Admin service is running. Changes require restart.'));
|
|
79
|
+
console.log(chalk.gray(' Add --restart flag to restart automatically\n'));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Apply changes
|
|
83
|
+
if (Object.keys(updates).length > 0) {
|
|
84
|
+
await adminManager.updateConfig(updates);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Restart if requested and needed
|
|
88
|
+
if (options.restart && needsRestart) {
|
|
89
|
+
console.log(chalk.blue('🔄 Restarting admin service...\n'));
|
|
90
|
+
|
|
91
|
+
// Regenerate plist with new config
|
|
92
|
+
const updatedConfig = await adminManager.loadConfig();
|
|
93
|
+
if (updatedConfig) {
|
|
94
|
+
await adminManager.createPlist(updatedConfig);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
await adminManager.restart();
|
|
98
|
+
|
|
99
|
+
console.log(chalk.green('✓ Admin service restarted successfully'));
|
|
100
|
+
} else {
|
|
101
|
+
console.log(chalk.green('✓ Configuration updated'));
|
|
102
|
+
|
|
103
|
+
if (needsRestart && !options.restart) {
|
|
104
|
+
console.log(chalk.gray('\nRestart with: llamacpp admin restart'));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log();
|
|
109
|
+
|
|
110
|
+
// Show new API key prominently if regenerated
|
|
111
|
+
if (newApiKey) {
|
|
112
|
+
console.log(chalk.bold('New API Key:'), chalk.yellow(newApiKey));
|
|
113
|
+
console.log(chalk.gray('Store this key securely - it cannot be retrieved later'));
|
|
114
|
+
console.log();
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error(chalk.red('✗ Failed to update admin configuration'));
|
|
118
|
+
console.error(chalk.gray((error as Error).message));
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import * as fs from 'fs/promises';
|
|
4
|
+
import { adminManager } from '../../lib/admin-manager';
|
|
5
|
+
import { fileExists } from '../../utils/file-utils';
|
|
6
|
+
|
|
7
|
+
interface LogsOptions {
|
|
8
|
+
stdout?: boolean;
|
|
9
|
+
stderr?: boolean;
|
|
10
|
+
follow?: boolean;
|
|
11
|
+
clear?: boolean;
|
|
12
|
+
lines?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function adminLogsCommand(options: LogsOptions): Promise<void> {
|
|
16
|
+
try {
|
|
17
|
+
const result = await adminManager.getStatus();
|
|
18
|
+
|
|
19
|
+
if (!result) {
|
|
20
|
+
console.error(chalk.red('✗ Admin service is not configured'));
|
|
21
|
+
console.log(chalk.gray('\nRun: llamacpp admin start'));
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const { config } = result;
|
|
26
|
+
|
|
27
|
+
// Default to stdout if neither specified
|
|
28
|
+
const showStdout = options.stdout || (!options.stdout && !options.stderr);
|
|
29
|
+
const showStderr = options.stderr || (!options.stdout && !options.stderr);
|
|
30
|
+
|
|
31
|
+
// Handle clear operation
|
|
32
|
+
if (options.clear) {
|
|
33
|
+
if (showStdout && (await fileExists(config.stdoutPath))) {
|
|
34
|
+
await fs.writeFile(config.stdoutPath, '');
|
|
35
|
+
console.log(chalk.green('✓ Cleared stdout log'));
|
|
36
|
+
}
|
|
37
|
+
if (showStderr && (await fileExists(config.stderrPath))) {
|
|
38
|
+
await fs.writeFile(config.stderrPath, '');
|
|
39
|
+
console.log(chalk.green('✓ Cleared stderr log'));
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Determine which logs to show
|
|
45
|
+
const logPaths: string[] = [];
|
|
46
|
+
if (showStdout) logPaths.push(config.stdoutPath);
|
|
47
|
+
if (showStderr) logPaths.push(config.stderrPath);
|
|
48
|
+
|
|
49
|
+
// Check if log files exist
|
|
50
|
+
for (const logPath of logPaths) {
|
|
51
|
+
if (!(await fileExists(logPath))) {
|
|
52
|
+
console.log(chalk.yellow(`Log file does not exist: ${logPath}`));
|
|
53
|
+
console.log(chalk.gray('No logs available yet'));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Follow mode (tail -f)
|
|
59
|
+
if (options.follow) {
|
|
60
|
+
console.log(chalk.blue(`📋 Following admin logs (Ctrl+C to exit)\n`));
|
|
61
|
+
|
|
62
|
+
const tailArgs = ['-f', ...logPaths];
|
|
63
|
+
const tail = spawn('tail', tailArgs, { stdio: 'inherit' });
|
|
64
|
+
|
|
65
|
+
// Handle Ctrl+C gracefully
|
|
66
|
+
process.on('SIGINT', () => {
|
|
67
|
+
tail.kill();
|
|
68
|
+
console.log(chalk.gray('\n\nStopped following logs'));
|
|
69
|
+
process.exit(0);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
tail.on('exit', (code) => {
|
|
73
|
+
process.exit(code || 0);
|
|
74
|
+
});
|
|
75
|
+
} else {
|
|
76
|
+
// Static mode (tail -n)
|
|
77
|
+
const lines = options.lines || 100;
|
|
78
|
+
const tailArgs = ['-n', lines.toString(), ...logPaths];
|
|
79
|
+
|
|
80
|
+
const tail = spawn('tail', tailArgs, { stdio: 'inherit' });
|
|
81
|
+
|
|
82
|
+
tail.on('exit', (code) => {
|
|
83
|
+
process.exit(code || 0);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error(chalk.red('✗ Failed to read admin logs'));
|
|
88
|
+
console.error(chalk.gray((error as Error).message));
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { adminManager } from '../../lib/admin-manager';
|
|
3
|
+
|
|
4
|
+
export async function adminRestartCommand(): Promise<void> {
|
|
5
|
+
try {
|
|
6
|
+
console.log(chalk.blue('🔄 Restarting admin service...\n'));
|
|
7
|
+
|
|
8
|
+
await adminManager.restart();
|
|
9
|
+
|
|
10
|
+
const result = await adminManager.getStatus();
|
|
11
|
+
if (!result) {
|
|
12
|
+
throw new Error('Failed to retrieve admin status after restart');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { config, status } = result;
|
|
16
|
+
|
|
17
|
+
console.log(chalk.green('✓ Admin service restarted successfully\n'));
|
|
18
|
+
console.log(chalk.bold(' Endpoint:'), chalk.cyan(`http://${config.host}:${config.port}`));
|
|
19
|
+
console.log(chalk.bold(' PID: '), status.pid);
|
|
20
|
+
console.log();
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error(chalk.red('✗ Failed to restart admin service'));
|
|
23
|
+
console.error(chalk.gray((error as Error).message));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { adminManager } from '../../lib/admin-manager';
|
|
3
|
+
|
|
4
|
+
export async function adminStartCommand(): Promise<void> {
|
|
5
|
+
try {
|
|
6
|
+
console.log(chalk.blue('🚀 Starting admin service...\n'));
|
|
7
|
+
|
|
8
|
+
await adminManager.start();
|
|
9
|
+
|
|
10
|
+
const result = await adminManager.getStatus();
|
|
11
|
+
if (!result) {
|
|
12
|
+
throw new Error('Failed to retrieve admin status after start');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { config, status } = result;
|
|
16
|
+
|
|
17
|
+
console.log(chalk.green('✓ Admin service started successfully\n'));
|
|
18
|
+
console.log(chalk.bold(' Endpoint:'), chalk.cyan(`http://${config.host}:${config.port}`));
|
|
19
|
+
console.log(chalk.bold(' API Key: '), chalk.yellow(config.apiKey), chalk.gray('(use for authentication)'));
|
|
20
|
+
console.log(chalk.bold(' PID: '), status.pid);
|
|
21
|
+
console.log();
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error(chalk.red('✗ Failed to start admin service'));
|
|
24
|
+
console.error(chalk.gray((error as Error).message));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { adminManager } from '../../lib/admin-manager';
|
|
3
|
+
|
|
4
|
+
function formatUptime(lastStarted: string): string {
|
|
5
|
+
const start = new Date(lastStarted).getTime();
|
|
6
|
+
const now = Date.now();
|
|
7
|
+
const uptimeSeconds = Math.floor((now - start) / 1000);
|
|
8
|
+
|
|
9
|
+
const hours = Math.floor(uptimeSeconds / 3600);
|
|
10
|
+
const minutes = Math.floor((uptimeSeconds % 3600) / 60);
|
|
11
|
+
|
|
12
|
+
if (hours > 0) {
|
|
13
|
+
return `${hours}h ${minutes}m`;
|
|
14
|
+
}
|
|
15
|
+
return `${minutes}m`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function adminStatusCommand(): Promise<void> {
|
|
19
|
+
try {
|
|
20
|
+
const result = await adminManager.getStatus();
|
|
21
|
+
|
|
22
|
+
if (!result) {
|
|
23
|
+
console.log(chalk.yellow('Admin service is not configured'));
|
|
24
|
+
console.log(chalk.gray('\nRun: llamacpp admin start'));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const { config, status } = result;
|
|
29
|
+
|
|
30
|
+
console.log(chalk.bold.underline('Admin Service Status'));
|
|
31
|
+
console.log();
|
|
32
|
+
|
|
33
|
+
// Status
|
|
34
|
+
if (status.isRunning) {
|
|
35
|
+
console.log(chalk.bold(' Status: '), chalk.green('● RUNNING'));
|
|
36
|
+
console.log(chalk.bold(' PID: '), status.pid);
|
|
37
|
+
if (config.lastStarted) {
|
|
38
|
+
console.log(chalk.bold(' Uptime: '), formatUptime(config.lastStarted));
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
console.log(chalk.bold(' Status: '), chalk.gray('○ STOPPED'));
|
|
42
|
+
if (status.lastExitReason) {
|
|
43
|
+
console.log(chalk.bold(' Last Exit:'), chalk.yellow(status.lastExitReason));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log(chalk.bold(' Port: '), config.port);
|
|
48
|
+
console.log(chalk.bold(' Host: '), config.host);
|
|
49
|
+
console.log(chalk.bold(' API Key: '), chalk.yellow(config.apiKey));
|
|
50
|
+
console.log();
|
|
51
|
+
|
|
52
|
+
// Endpoints
|
|
53
|
+
if (status.isRunning) {
|
|
54
|
+
console.log(chalk.bold(' Endpoints:'));
|
|
55
|
+
console.log(chalk.bold(' Health: '), chalk.cyan(`GET http://${config.host}:${config.port}/health`));
|
|
56
|
+
console.log(chalk.bold(' Servers: '), chalk.cyan(`GET http://${config.host}:${config.port}/api/servers`));
|
|
57
|
+
console.log(chalk.bold(' Models: '), chalk.cyan(`GET http://${config.host}:${config.port}/api/models`));
|
|
58
|
+
console.log();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Configuration
|
|
62
|
+
console.log(chalk.bold(' Configuration:'));
|
|
63
|
+
console.log(chalk.bold(' Config: '), chalk.gray(config.plistPath.replace(process.env.HOME || '', '~')));
|
|
64
|
+
console.log(chalk.bold(' Plist: '), chalk.gray(config.plistPath.replace(process.env.HOME || '', '~')));
|
|
65
|
+
console.log(chalk.bold(' Logs: '), chalk.gray(config.stdoutPath.replace('.stdout', '.{stdout,stderr}').replace(process.env.HOME || '', '~')));
|
|
66
|
+
console.log();
|
|
67
|
+
|
|
68
|
+
// Quick commands
|
|
69
|
+
console.log(chalk.bold(' Quick Commands:'));
|
|
70
|
+
if (status.isRunning) {
|
|
71
|
+
console.log(chalk.bold(' Stop: '), chalk.gray('llamacpp admin stop'));
|
|
72
|
+
console.log(chalk.bold(' Restart: '), chalk.gray('llamacpp admin restart'));
|
|
73
|
+
console.log(chalk.bold(' Logs: '), chalk.gray('llamacpp admin logs --follow'));
|
|
74
|
+
} else {
|
|
75
|
+
console.log(chalk.bold(' Start: '), chalk.gray('llamacpp admin start'));
|
|
76
|
+
console.log(chalk.bold(' Logs: '), chalk.gray('llamacpp admin logs'));
|
|
77
|
+
}
|
|
78
|
+
console.log();
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error(chalk.red('✗ Failed to get admin status'));
|
|
81
|
+
console.error(chalk.gray((error as Error).message));
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|