@appkit/llamacpp-cli 1.8.0 → 1.9.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +80 -0
  3. package/dist/cli.js +79 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/router/config.d.ts +10 -0
  6. package/dist/commands/router/config.d.ts.map +1 -0
  7. package/dist/commands/router/config.js +95 -0
  8. package/dist/commands/router/config.js.map +1 -0
  9. package/dist/commands/router/restart.d.ts +2 -0
  10. package/dist/commands/router/restart.d.ts.map +1 -0
  11. package/dist/commands/router/restart.js +39 -0
  12. package/dist/commands/router/restart.js.map +1 -0
  13. package/dist/commands/router/start.d.ts +2 -0
  14. package/dist/commands/router/start.d.ts.map +1 -0
  15. package/dist/commands/router/start.js +60 -0
  16. package/dist/commands/router/start.js.map +1 -0
  17. package/dist/commands/router/status.d.ts +2 -0
  18. package/dist/commands/router/status.d.ts.map +1 -0
  19. package/dist/commands/router/status.js +116 -0
  20. package/dist/commands/router/status.js.map +1 -0
  21. package/dist/commands/router/stop.d.ts +2 -0
  22. package/dist/commands/router/stop.d.ts.map +1 -0
  23. package/dist/commands/router/stop.js +36 -0
  24. package/dist/commands/router/stop.js.map +1 -0
  25. package/dist/lib/router-manager.d.ts +103 -0
  26. package/dist/lib/router-manager.d.ts.map +1 -0
  27. package/dist/lib/router-manager.js +393 -0
  28. package/dist/lib/router-manager.js.map +1 -0
  29. package/dist/lib/router-server.d.ts +52 -0
  30. package/dist/lib/router-server.d.ts.map +1 -0
  31. package/dist/lib/router-server.js +373 -0
  32. package/dist/lib/router-server.js.map +1 -0
  33. package/dist/types/router-config.d.ts +18 -0
  34. package/dist/types/router-config.d.ts.map +1 -0
  35. package/dist/types/router-config.js +3 -0
  36. package/dist/types/router-config.js.map +1 -0
  37. package/package.json +1 -1
  38. package/src/cli.ts +80 -0
  39. package/src/commands/router/config.ts +109 -0
  40. package/src/commands/router/restart.ts +36 -0
  41. package/src/commands/router/start.ts +60 -0
  42. package/src/commands/router/status.ts +119 -0
  43. package/src/commands/router/stop.ts +33 -0
  44. package/src/lib/router-manager.ts +413 -0
  45. package/src/lib/router-server.ts +407 -0
  46. package/src/types/router-config.ts +24 -0
@@ -0,0 +1,109 @@
1
+ import chalk from 'chalk';
2
+ import { routerManager } from '../../lib/router-manager';
3
+
4
+ interface ConfigOptions {
5
+ port?: number;
6
+ host?: string;
7
+ timeout?: number;
8
+ healthInterval?: number;
9
+ restart?: boolean;
10
+ }
11
+
12
+ export async function routerConfigCommand(options: ConfigOptions): Promise<void> {
13
+ try {
14
+ // Check if router exists
15
+ const config = await routerManager.loadConfig();
16
+ if (!config) {
17
+ throw new Error('Router configuration not found. Use "llamacpp router start" to create it.');
18
+ }
19
+
20
+ // Check if any options were provided
21
+ const hasOptions = options.port || options.host || options.timeout || options.healthInterval;
22
+ if (!hasOptions) {
23
+ throw new Error('No configuration options provided. Use --port, --host, --timeout, or --health-interval');
24
+ }
25
+
26
+ const isRunning = config.status === 'running';
27
+
28
+ // Warn if running and no restart flag
29
+ if (isRunning && !options.restart) {
30
+ console.log(chalk.yellow('⚠️ Router is running. Changes will take effect after restart.'));
31
+ console.log(chalk.dim(' Use --restart flag to apply changes immediately.\n'));
32
+ }
33
+
34
+ // Prepare updates
35
+ const updates: any = {};
36
+ const changes: string[] = [];
37
+
38
+ if (options.port !== undefined) {
39
+ changes.push(`Port: ${config.port} → ${options.port}`);
40
+ updates.port = options.port;
41
+ }
42
+
43
+ if (options.host !== undefined) {
44
+ changes.push(`Host: ${config.host} → ${options.host}`);
45
+ updates.host = options.host;
46
+ }
47
+
48
+ if (options.timeout !== undefined) {
49
+ changes.push(`Request Timeout: ${config.requestTimeout}ms → ${options.timeout}ms`);
50
+ updates.requestTimeout = options.timeout;
51
+ }
52
+
53
+ if (options.healthInterval !== undefined) {
54
+ changes.push(`Health Check Interval: ${config.healthCheckInterval}ms → ${options.healthInterval}ms`);
55
+ updates.healthCheckInterval = options.healthInterval;
56
+ }
57
+
58
+ // Display changes
59
+ console.log(chalk.blue('📝 Configuration changes:'));
60
+ console.log();
61
+ changes.forEach(change => {
62
+ console.log(chalk.dim(` ${change}`));
63
+ });
64
+ console.log();
65
+
66
+ // Apply changes
67
+ if (isRunning && options.restart) {
68
+ console.log(chalk.blue('⏹️ Stopping router...'));
69
+ await routerManager.stop();
70
+ }
71
+
72
+ // Update config
73
+ await routerManager.updateConfig(updates);
74
+
75
+ // Regenerate plist if port or host changed
76
+ if (options.port !== undefined || options.host !== undefined) {
77
+ const updatedConfig = await routerManager.loadConfig();
78
+ if (updatedConfig) {
79
+ await routerManager.createPlist(updatedConfig);
80
+ }
81
+ }
82
+
83
+ // Restart if requested
84
+ if (isRunning && options.restart) {
85
+ console.log(chalk.blue('▶️ Starting router...'));
86
+ await routerManager.start();
87
+
88
+ const finalConfig = await routerManager.loadConfig();
89
+ console.log();
90
+ console.log(chalk.green('✅ Router restarted with new configuration'));
91
+ console.log();
92
+ console.log(chalk.dim(`Endpoint: http://${finalConfig?.host}:${finalConfig?.port}`));
93
+ } else {
94
+ console.log(chalk.green('✅ Configuration updated'));
95
+
96
+ if (isRunning) {
97
+ console.log();
98
+ console.log(chalk.yellow('⚠️ Restart required to apply changes:'));
99
+ console.log(chalk.dim(' llamacpp router restart'));
100
+ } else {
101
+ console.log();
102
+ console.log(chalk.dim('Start router to use new configuration:'));
103
+ console.log(chalk.dim(' llamacpp router start'));
104
+ }
105
+ }
106
+ } catch (error) {
107
+ throw new Error(`Failed to update router configuration: ${(error as Error).message}`);
108
+ }
109
+ }
@@ -0,0 +1,36 @@
1
+ import chalk from 'chalk';
2
+ import { routerManager } from '../../lib/router-manager';
3
+
4
+ export async function routerRestartCommand(): Promise<void> {
5
+ console.log(chalk.blue('🔄 Restarting router...'));
6
+
7
+ try {
8
+ // Check if router exists
9
+ const config = await routerManager.loadConfig();
10
+ if (!config) {
11
+ throw new Error('Router configuration not found. Use "llamacpp router start" to create it.');
12
+ }
13
+
14
+ // Restart router
15
+ await routerManager.restart();
16
+
17
+ // Get updated config
18
+ const updatedConfig = await routerManager.loadConfig();
19
+ if (!updatedConfig) {
20
+ throw new Error('Failed to load router configuration after restart');
21
+ }
22
+
23
+ // Display success
24
+ console.log();
25
+ console.log(chalk.green('✅ Router restarted successfully!'));
26
+ console.log();
27
+ console.log(chalk.dim(`Endpoint: http://${updatedConfig.host}:${updatedConfig.port}`));
28
+ console.log();
29
+ console.log(chalk.dim('Quick commands:'));
30
+ console.log(chalk.dim(' Status: llamacpp router status'));
31
+ console.log(chalk.dim(' Stop: llamacpp router stop'));
32
+ console.log(chalk.dim(` Logs: tail -f ${updatedConfig.stderrPath}`));
33
+ } catch (error) {
34
+ throw new Error(`Failed to restart router: ${(error as Error).message}`);
35
+ }
36
+ }
@@ -0,0 +1,60 @@
1
+ import chalk from 'chalk';
2
+ import { routerManager } from '../../lib/router-manager';
3
+ import { stateManager } from '../../lib/state-manager';
4
+
5
+ export async function routerStartCommand(): Promise<void> {
6
+ console.log(chalk.blue('▶️ Starting router...'));
7
+
8
+ try {
9
+ // Initialize
10
+ await routerManager.initialize();
11
+ await stateManager.initialize();
12
+
13
+ // Check if router already exists
14
+ const existingConfig = await routerManager.loadConfig();
15
+ if (existingConfig && existingConfig.status === 'running') {
16
+ console.log(chalk.yellow(`⚠️ Router is already running on port ${existingConfig.port}`));
17
+ return;
18
+ }
19
+
20
+ // Start router
21
+ await routerManager.start();
22
+
23
+ // Get updated config
24
+ const config = await routerManager.loadConfig();
25
+ if (!config) {
26
+ throw new Error('Failed to load router configuration after start');
27
+ }
28
+
29
+ // Get running servers to show available models
30
+ const servers = await stateManager.getAllServers();
31
+ const runningServers = servers.filter(s => s.status === 'running');
32
+
33
+ // Display success
34
+ console.log();
35
+ console.log(chalk.green('✅ Router started successfully!'));
36
+ console.log();
37
+ console.log(chalk.dim(`Endpoint: http://${config.host}:${config.port}`));
38
+ console.log(chalk.dim(`Available models: ${runningServers.length}`));
39
+
40
+ if (runningServers.length > 0) {
41
+ console.log();
42
+ console.log(chalk.dim('Models:'));
43
+ runningServers.forEach(server => {
44
+ console.log(chalk.dim(` • ${server.modelName} (port ${server.port})`));
45
+ });
46
+ } else {
47
+ console.log();
48
+ console.log(chalk.yellow('⚠️ No running servers found. Start a server first:'));
49
+ console.log(chalk.dim(' llamacpp server create <model>'));
50
+ }
51
+
52
+ console.log();
53
+ console.log(chalk.dim('Quick commands:'));
54
+ console.log(chalk.dim(` Status: llamacpp router status`));
55
+ console.log(chalk.dim(` Stop: llamacpp router stop`));
56
+ console.log(chalk.dim(` Logs: tail -f ${config.stderrPath}`));
57
+ } catch (error) {
58
+ throw new Error(`Failed to start router: ${(error as Error).message}`);
59
+ }
60
+ }
@@ -0,0 +1,119 @@
1
+ import chalk from 'chalk';
2
+ import { routerManager } from '../../lib/router-manager';
3
+ import { stateManager } from '../../lib/state-manager';
4
+
5
+ export async function routerStatusCommand(): Promise<void> {
6
+ try {
7
+ // Get router status
8
+ const result = await routerManager.getStatus();
9
+ if (!result) {
10
+ console.log(chalk.yellow('Router not configured'));
11
+ console.log();
12
+ console.log(chalk.dim('Create and start router:'));
13
+ console.log(chalk.dim(' llamacpp router start'));
14
+ return;
15
+ }
16
+
17
+ const { config, status } = result;
18
+
19
+ // Calculate uptime if running
20
+ let uptime = 'N/A';
21
+ if (status.isRunning && config.lastStarted) {
22
+ const startTime = new Date(config.lastStarted).getTime();
23
+ const now = Date.now();
24
+ const uptimeSeconds = Math.floor((now - startTime) / 1000);
25
+ const hours = Math.floor(uptimeSeconds / 3600);
26
+ const minutes = Math.floor((uptimeSeconds % 3600) / 60);
27
+ const seconds = uptimeSeconds % 60;
28
+
29
+ if (hours > 0) {
30
+ uptime = `${hours}h ${minutes}m`;
31
+ } else if (minutes > 0) {
32
+ uptime = `${minutes}m ${seconds}s`;
33
+ } else {
34
+ uptime = `${seconds}s`;
35
+ }
36
+ }
37
+
38
+ // Get running servers
39
+ const servers = await stateManager.getAllServers();
40
+ const runningServers = servers.filter(s => s.status === 'running');
41
+
42
+ // Display status
43
+ console.log();
44
+ console.log(chalk.bold('Router Status'));
45
+ console.log(chalk.dim('─'.repeat(50)));
46
+ console.log();
47
+
48
+ // Status badge
49
+ const statusColor = status.isRunning ? chalk.green : chalk.gray;
50
+ const statusBadge = status.isRunning ? '● RUN' : '○ OFF';
51
+ console.log(`Status: ${statusColor(statusBadge)}`);
52
+
53
+ if (status.isRunning) {
54
+ console.log(`PID: ${status.pid || 'N/A'}`);
55
+ console.log(`Uptime: ${uptime}`);
56
+ }
57
+
58
+ console.log(`Port: ${config.port}`);
59
+ console.log(`Host: ${config.host}`);
60
+ console.log(`Endpoint: http://${config.host}:${config.port}`);
61
+ console.log();
62
+
63
+ // Available models
64
+ console.log(chalk.bold('Available Models'));
65
+ console.log(chalk.dim('─'.repeat(50)));
66
+ console.log();
67
+
68
+ if (runningServers.length === 0) {
69
+ console.log(chalk.dim('No running servers found'));
70
+ console.log();
71
+ console.log(chalk.yellow('⚠️ Start a server first:'));
72
+ console.log(chalk.dim(' llamacpp server create <model>'));
73
+ } else {
74
+ runningServers.forEach(server => {
75
+ console.log(` ${chalk.green('●')} ${server.modelName}`);
76
+ console.log(chalk.dim(` Port: ${server.port}`));
77
+ console.log(chalk.dim(` Backend: http://${server.host}:${server.port}`));
78
+ console.log();
79
+ });
80
+ }
81
+
82
+ // Configuration
83
+ console.log(chalk.bold('Configuration'));
84
+ console.log(chalk.dim('─'.repeat(50)));
85
+ console.log();
86
+ console.log(`Health Check Interval: ${config.healthCheckInterval}ms`);
87
+ console.log(`Request Timeout: ${config.requestTimeout}ms`);
88
+ console.log();
89
+
90
+ // System paths
91
+ console.log(chalk.bold('System Paths'));
92
+ console.log(chalk.dim('─'.repeat(50)));
93
+ console.log();
94
+ console.log(chalk.dim(`Config: ${config.plistPath.replace(config.label + '.plist', 'router.json').replace('LaunchAgents', '.llamacpp')}`));
95
+ console.log(chalk.dim(`Plist: ${config.plistPath}`));
96
+ console.log(chalk.dim(`Stdout: ${config.stdoutPath}`));
97
+ console.log(chalk.dim(`Stderr: ${config.stderrPath}`));
98
+ console.log();
99
+
100
+ // Quick commands
101
+ console.log(chalk.bold('Quick Commands'));
102
+ console.log(chalk.dim('─'.repeat(50)));
103
+ console.log();
104
+
105
+ if (status.isRunning) {
106
+ console.log(chalk.dim(' Stop: llamacpp router stop'));
107
+ console.log(chalk.dim(' Restart: llamacpp router restart'));
108
+ console.log(chalk.dim(` Logs: tail -f ${config.stderrPath}`));
109
+ console.log(chalk.dim(' Config: llamacpp router config --port <port> --restart'));
110
+ } else {
111
+ console.log(chalk.dim(' Start: llamacpp router start'));
112
+ console.log(chalk.dim(' Config: llamacpp router config --port <port>'));
113
+ console.log(chalk.dim(` Logs: cat ${config.stderrPath}`));
114
+ }
115
+ console.log();
116
+ } catch (error) {
117
+ throw new Error(`Failed to get router status: ${(error as Error).message}`);
118
+ }
119
+ }
@@ -0,0 +1,33 @@
1
+ import chalk from 'chalk';
2
+ import { routerManager } from '../../lib/router-manager';
3
+
4
+ export async function routerStopCommand(): Promise<void> {
5
+ console.log(chalk.blue('⏹️ Stopping router...'));
6
+
7
+ try {
8
+ // Check if router exists
9
+ const config = await routerManager.loadConfig();
10
+ if (!config) {
11
+ throw new Error('Router configuration not found. Use "llamacpp router start" to create it.');
12
+ }
13
+
14
+ // Check if already stopped
15
+ if (config.status !== 'running') {
16
+ console.log(chalk.yellow('⚠️ Router is not running'));
17
+ return;
18
+ }
19
+
20
+ // Stop router
21
+ await routerManager.stop();
22
+
23
+ // Display success
24
+ console.log();
25
+ console.log(chalk.green('✅ Router stopped successfully'));
26
+ console.log();
27
+ console.log(chalk.dim('Quick commands:'));
28
+ console.log(chalk.dim(' Start: llamacpp router start'));
29
+ console.log(chalk.dim(' Status: llamacpp router status'));
30
+ } catch (error) {
31
+ throw new Error(`Failed to stop router: ${(error as Error).message}`);
32
+ }
33
+ }