@appkit/llamacpp-cli 1.4.1 → 1.6.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 (91) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/MONITORING-ACCURACY-FIX.md +199 -0
  3. package/PER-PROCESS-METRICS.md +190 -0
  4. package/README.md +136 -1
  5. package/dist/cli.js +21 -4
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/create.d.ts.map +1 -1
  8. package/dist/commands/create.js +12 -3
  9. package/dist/commands/create.js.map +1 -1
  10. package/dist/commands/monitor.d.ts +2 -0
  11. package/dist/commands/monitor.d.ts.map +1 -0
  12. package/dist/commands/monitor.js +126 -0
  13. package/dist/commands/monitor.js.map +1 -0
  14. package/dist/commands/ps.d.ts +3 -1
  15. package/dist/commands/ps.d.ts.map +1 -1
  16. package/dist/commands/ps.js +75 -5
  17. package/dist/commands/ps.js.map +1 -1
  18. package/dist/commands/server-show.d.ts.map +1 -1
  19. package/dist/commands/server-show.js +10 -3
  20. package/dist/commands/server-show.js.map +1 -1
  21. package/dist/commands/start.d.ts.map +1 -1
  22. package/dist/commands/start.js +14 -2
  23. package/dist/commands/start.js.map +1 -1
  24. package/dist/lib/history-manager.d.ts +46 -0
  25. package/dist/lib/history-manager.d.ts.map +1 -0
  26. package/dist/lib/history-manager.js +157 -0
  27. package/dist/lib/history-manager.js.map +1 -0
  28. package/dist/lib/metrics-aggregator.d.ts +40 -0
  29. package/dist/lib/metrics-aggregator.d.ts.map +1 -0
  30. package/dist/lib/metrics-aggregator.js +211 -0
  31. package/dist/lib/metrics-aggregator.js.map +1 -0
  32. package/dist/lib/system-collector.d.ts +80 -0
  33. package/dist/lib/system-collector.d.ts.map +1 -0
  34. package/dist/lib/system-collector.js +311 -0
  35. package/dist/lib/system-collector.js.map +1 -0
  36. package/dist/tui/HistoricalMonitorApp.d.ts +5 -0
  37. package/dist/tui/HistoricalMonitorApp.d.ts.map +1 -0
  38. package/dist/tui/HistoricalMonitorApp.js +490 -0
  39. package/dist/tui/HistoricalMonitorApp.js.map +1 -0
  40. package/dist/tui/MonitorApp.d.ts +4 -0
  41. package/dist/tui/MonitorApp.d.ts.map +1 -0
  42. package/dist/tui/MonitorApp.js +315 -0
  43. package/dist/tui/MonitorApp.js.map +1 -0
  44. package/dist/tui/MultiServerMonitorApp.d.ts +4 -0
  45. package/dist/tui/MultiServerMonitorApp.d.ts.map +1 -0
  46. package/dist/tui/MultiServerMonitorApp.js +712 -0
  47. package/dist/tui/MultiServerMonitorApp.js.map +1 -0
  48. package/dist/types/history-types.d.ts +30 -0
  49. package/dist/types/history-types.d.ts.map +1 -0
  50. package/dist/types/history-types.js +11 -0
  51. package/dist/types/history-types.js.map +1 -0
  52. package/dist/types/monitor-types.d.ts +123 -0
  53. package/dist/types/monitor-types.d.ts.map +1 -0
  54. package/dist/types/monitor-types.js +3 -0
  55. package/dist/types/monitor-types.js.map +1 -0
  56. package/dist/types/server-config.d.ts +1 -0
  57. package/dist/types/server-config.d.ts.map +1 -1
  58. package/dist/types/server-config.js.map +1 -1
  59. package/dist/utils/downsample-utils.d.ts +35 -0
  60. package/dist/utils/downsample-utils.d.ts.map +1 -0
  61. package/dist/utils/downsample-utils.js +107 -0
  62. package/dist/utils/downsample-utils.js.map +1 -0
  63. package/dist/utils/file-utils.d.ts +6 -0
  64. package/dist/utils/file-utils.d.ts.map +1 -1
  65. package/dist/utils/file-utils.js +38 -0
  66. package/dist/utils/file-utils.js.map +1 -1
  67. package/dist/utils/process-utils.d.ts +35 -2
  68. package/dist/utils/process-utils.d.ts.map +1 -1
  69. package/dist/utils/process-utils.js +220 -25
  70. package/dist/utils/process-utils.js.map +1 -1
  71. package/docs/images/.gitkeep +1 -0
  72. package/package.json +5 -1
  73. package/src/cli.ts +21 -4
  74. package/src/commands/create.ts +14 -4
  75. package/src/commands/monitor.ts +110 -0
  76. package/src/commands/ps.ts +88 -5
  77. package/src/commands/server-show.ts +10 -3
  78. package/src/commands/start.ts +15 -2
  79. package/src/lib/history-manager.ts +172 -0
  80. package/src/lib/metrics-aggregator.ts +257 -0
  81. package/src/lib/system-collector.ts +315 -0
  82. package/src/tui/HistoricalMonitorApp.ts +548 -0
  83. package/src/tui/MonitorApp.ts +386 -0
  84. package/src/tui/MultiServerMonitorApp.ts +792 -0
  85. package/src/types/history-types.ts +39 -0
  86. package/src/types/monitor-types.ts +162 -0
  87. package/src/types/server-config.ts +1 -0
  88. package/src/utils/downsample-utils.ts +128 -0
  89. package/src/utils/file-utils.ts +40 -0
  90. package/src/utils/process-utils.ts +243 -25
  91. package/test-load.sh +100 -0
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HistoryManager = void 0;
4
+ const promises_1 = require("fs/promises");
5
+ const path_1 = require("path");
6
+ const os_1 = require("os");
7
+ const history_types_js_1 = require("../types/history-types.js");
8
+ class HistoryManager {
9
+ constructor(serverId) {
10
+ this.MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours
11
+ this.serverId = serverId;
12
+ this.historyDir = (0, path_1.join)((0, os_1.homedir)(), '.llamacpp', 'history');
13
+ this.historyPath = (0, path_1.join)(this.historyDir, `${serverId}.json`);
14
+ }
15
+ /**
16
+ * Append a new snapshot to history (with auto-pruning)
17
+ */
18
+ async appendSnapshot(serverMetrics, systemMetrics) {
19
+ try {
20
+ // Ensure history directory exists
21
+ await (0, promises_1.mkdir)(this.historyDir, { recursive: true });
22
+ // Load existing history
23
+ const historyData = await this.loadHistoryData();
24
+ // Create new snapshot
25
+ const snapshot = {
26
+ timestamp: Date.now(),
27
+ server: {
28
+ healthy: serverMetrics.healthy,
29
+ uptime: serverMetrics.uptime,
30
+ activeSlots: serverMetrics.activeSlots,
31
+ idleSlots: serverMetrics.idleSlots,
32
+ totalSlots: serverMetrics.totalSlots,
33
+ avgPromptSpeed: serverMetrics.avgPromptSpeed,
34
+ avgGenerateSpeed: serverMetrics.avgGenerateSpeed,
35
+ processMemory: serverMetrics.processMemory,
36
+ processCpuUsage: serverMetrics.processCpuUsage,
37
+ },
38
+ system: systemMetrics ? {
39
+ gpuUsage: systemMetrics.gpuUsage,
40
+ cpuUsage: systemMetrics.cpuUsage,
41
+ aneUsage: systemMetrics.aneUsage,
42
+ temperature: systemMetrics.temperature,
43
+ memoryUsed: systemMetrics.memoryUsed,
44
+ memoryTotal: systemMetrics.memoryTotal,
45
+ } : undefined,
46
+ };
47
+ // Append new snapshot
48
+ historyData.snapshots.push(snapshot);
49
+ // Prune old snapshots (keep only last 24h)
50
+ historyData.snapshots = this.pruneOldSnapshots(historyData.snapshots, this.MAX_AGE_MS);
51
+ // Atomic write: write to temp file in same directory, then rename
52
+ // This prevents read collisions during concurrent access
53
+ // IMPORTANT: temp file MUST be in same directory as destination for rename to work across filesystems
54
+ const tempPath = (0, path_1.join)(this.historyDir, `.${this.serverId}-${Date.now()}.tmp`);
55
+ await (0, promises_1.writeFile)(tempPath, JSON.stringify(historyData, null, 2), 'utf-8');
56
+ await (0, promises_1.rename)(tempPath, this.historyPath);
57
+ }
58
+ catch (error) {
59
+ // Silent failure - don't interrupt monitoring
60
+ // Don't throw - just return silently to avoid polluting console
61
+ return;
62
+ }
63
+ }
64
+ /**
65
+ * Load all snapshots within specified time window
66
+ */
67
+ async loadHistory(windowHours) {
68
+ // Retry logic for file I/O collisions during concurrent read/write
69
+ const maxRetries = 3;
70
+ let lastError = null;
71
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
72
+ try {
73
+ const historyData = await this.loadHistoryData();
74
+ return this.filterByTimeWindow(historyData.snapshots, windowHours);
75
+ }
76
+ catch (error) {
77
+ lastError = error;
78
+ // Wait briefly before retry (exponential backoff)
79
+ if (attempt < maxRetries - 1) {
80
+ await new Promise(resolve => setTimeout(resolve, 50 * Math.pow(2, attempt)));
81
+ }
82
+ }
83
+ }
84
+ // All retries failed - throw error so it can be handled upstream
85
+ throw new Error(`Failed to load history after ${maxRetries} attempts: ${lastError?.message || 'Unknown error'}`);
86
+ }
87
+ /**
88
+ * Load history for specific time window type
89
+ */
90
+ async loadHistoryByWindow(window) {
91
+ return this.loadHistory(history_types_js_1.TIME_WINDOW_HOURS[window]);
92
+ }
93
+ /**
94
+ * Get file path for server history
95
+ */
96
+ getHistoryPath() {
97
+ return this.historyPath;
98
+ }
99
+ /**
100
+ * Check if history file exists
101
+ */
102
+ async hasHistory() {
103
+ try {
104
+ await (0, promises_1.access)(this.historyPath);
105
+ return true;
106
+ }
107
+ catch {
108
+ return false;
109
+ }
110
+ }
111
+ /**
112
+ * Clear all history for server
113
+ */
114
+ async clearHistory() {
115
+ const emptyHistory = {
116
+ serverId: this.serverId,
117
+ snapshots: [],
118
+ };
119
+ await (0, promises_1.mkdir)(this.historyDir, { recursive: true });
120
+ // Atomic write - temp file in same directory as destination
121
+ const tempPath = (0, path_1.join)(this.historyDir, `.${this.serverId}-${Date.now()}.tmp`);
122
+ await (0, promises_1.writeFile)(tempPath, JSON.stringify(emptyHistory, null, 2), 'utf-8');
123
+ await (0, promises_1.rename)(tempPath, this.historyPath);
124
+ }
125
+ /**
126
+ * Load full history data from file
127
+ */
128
+ async loadHistoryData() {
129
+ try {
130
+ const content = await (0, promises_1.readFile)(this.historyPath, 'utf-8');
131
+ return JSON.parse(content);
132
+ }
133
+ catch (error) {
134
+ // File doesn't exist or is corrupted, return empty history
135
+ return {
136
+ serverId: this.serverId,
137
+ snapshots: [],
138
+ };
139
+ }
140
+ }
141
+ /**
142
+ * Prune snapshots older than maxAge
143
+ */
144
+ pruneOldSnapshots(snapshots, maxAgeMs) {
145
+ const cutoff = Date.now() - maxAgeMs;
146
+ return snapshots.filter(s => s.timestamp >= cutoff);
147
+ }
148
+ /**
149
+ * Filter snapshots by time window
150
+ */
151
+ filterByTimeWindow(snapshots, windowHours) {
152
+ const cutoff = Date.now() - (windowHours * 60 * 60 * 1000);
153
+ return snapshots.filter(s => s.timestamp >= cutoff);
154
+ }
155
+ }
156
+ exports.HistoryManager = HistoryManager;
157
+ //# sourceMappingURL=history-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-manager.js","sourceRoot":"","sources":["../../src/lib/history-manager.ts"],"names":[],"mappings":";;;AAAA,0CAAyE;AACzE,+BAA4B;AAC5B,2BAA6B;AAE7B,gEAAwG;AAExG,MAAa,cAAc;IAMzB,YAAY,QAAgB;QAFX,eAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW;QAG5D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,IAAA,WAAI,EAAC,IAAA,YAAO,GAAE,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QAC1D,IAAI,CAAC,WAAW,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,UAAU,EAAE,GAAG,QAAQ,OAAO,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,aAA4B,EAAE,aAA6B;QAC9E,IAAI,CAAC;YACH,kCAAkC;YAClC,MAAM,IAAA,gBAAK,EAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAElD,wBAAwB;YACxB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YAEjD,sBAAsB;YACtB,MAAM,QAAQ,GAAoB;gBAChC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,MAAM,EAAE;oBACN,OAAO,EAAE,aAAa,CAAC,OAAO;oBAC9B,MAAM,EAAE,aAAa,CAAC,MAAM;oBAC5B,WAAW,EAAE,aAAa,CAAC,WAAW;oBACtC,SAAS,EAAE,aAAa,CAAC,SAAS;oBAClC,UAAU,EAAE,aAAa,CAAC,UAAU;oBACpC,cAAc,EAAE,aAAa,CAAC,cAAc;oBAC5C,gBAAgB,EAAE,aAAa,CAAC,gBAAgB;oBAChD,aAAa,EAAE,aAAa,CAAC,aAAa;oBAC1C,eAAe,EAAE,aAAa,CAAC,eAAe;iBAC/C;gBACD,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;oBACtB,QAAQ,EAAE,aAAa,CAAC,QAAQ;oBAChC,QAAQ,EAAE,aAAa,CAAC,QAAQ;oBAChC,QAAQ,EAAE,aAAa,CAAC,QAAQ;oBAChC,WAAW,EAAE,aAAa,CAAC,WAAW;oBACtC,UAAU,EAAE,aAAa,CAAC,UAAU;oBACpC,WAAW,EAAE,aAAa,CAAC,WAAW;iBACvC,CAAC,CAAC,CAAC,SAAS;aACd,CAAC;YAEF,sBAAsB;YACtB,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAErC,2CAA2C;YAC3C,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YAEvF,kEAAkE;YAClE,yDAAyD;YACzD,sGAAsG;YACtG,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC9E,MAAM,IAAA,oBAAS,EAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACzE,MAAM,IAAA,iBAAM,EAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,8CAA8C;YAC9C,gEAAgE;YAChE,OAAO;QACT,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,WAAmB;QACnC,mEAAmE;QACnE,MAAM,UAAU,GAAG,CAAC,CAAC;QACrB,IAAI,SAAS,GAAiB,IAAI,CAAC;QAEnC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YACtD,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;gBACjD,OAAO,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YACrE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,SAAS,GAAG,KAAc,CAAC;gBAC3B,kDAAkD;gBAClD,IAAI,OAAO,GAAG,UAAU,GAAG,CAAC,EAAE,CAAC;oBAC7B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC/E,CAAC;YACH,CAAC;QACH,CAAC;QAED,iEAAiE;QACjE,MAAM,IAAI,KAAK,CAAC,gCAAgC,UAAU,cAAc,SAAS,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;IACnH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB,CAAC,MAAkB;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAC,oCAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,MAAM,IAAA,iBAAM,EAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAChB,MAAM,YAAY,GAAgB;YAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,EAAE;SACd,CAAC;QAEF,MAAM,IAAA,gBAAK,EAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAElD,4DAA4D;QAC5D,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC9E,MAAM,IAAA,oBAAS,EAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1E,MAAM,IAAA,iBAAM,EAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAA,mBAAQ,EAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,2DAA2D;YAC3D,OAAO;gBACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS,EAAE,EAAE;aACd,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,SAA4B,EAAE,QAAgB;QACtE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC;QACrC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,SAA4B,EAAE,WAAmB;QAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3D,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;IACtD,CAAC;CACF;AArKD,wCAqKC"}
@@ -0,0 +1,40 @@
1
+ import { ServerConfig } from '../types/server-config.js';
2
+ import { ServerMetrics, MonitorData } from '../types/monitor-types.js';
3
+ /**
4
+ * Aggregates metrics from llama.cpp server API endpoints
5
+ * Combines server health, slot status, and model properties
6
+ */
7
+ export declare class MetricsAggregator {
8
+ private serverUrl;
9
+ private timeout;
10
+ private previousSlots;
11
+ constructor(server: ServerConfig, timeout?: number);
12
+ /**
13
+ * Fetch data from llama.cpp API with timeout
14
+ */
15
+ private fetchWithTimeout;
16
+ /**
17
+ * Get server health status
18
+ */
19
+ private getHealth;
20
+ /**
21
+ * Get server properties (model info, context size, etc.)
22
+ */
23
+ private getProps;
24
+ /**
25
+ * Get active slots information with calculated tok/s
26
+ */
27
+ private getSlots;
28
+ /**
29
+ * Aggregate all server metrics
30
+ * @param server - Server configuration
31
+ * @param processMemory - Optional pre-fetched process memory (for batch collection)
32
+ * @param processCpuUsage - Optional pre-fetched process CPU usage (for batch collection)
33
+ */
34
+ collectServerMetrics(server: ServerConfig, processMemory?: number | null, processCpuUsage?: number | null): Promise<ServerMetrics>;
35
+ /**
36
+ * Collect complete monitoring data (server + system metrics)
37
+ */
38
+ collectMonitorData(server: ServerConfig, updateInterval?: number): Promise<MonitorData>;
39
+ }
40
+ //# sourceMappingURL=metrics-aggregator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-aggregator.d.ts","sourceRoot":"","sources":["../../src/lib/metrics-aggregator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAY,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAKjF;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAoE;gBAE7E,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,MAAa;IAOxD;;OAEG;YACW,gBAAgB;IA0B9B;;OAEG;YACW,SAAS;IAKvB;;OAEG;YACW,QAAQ;IAItB;;OAEG;YACW,QAAQ;IAyDtB;;;;;OAKG;IACG,oBAAoB,CACxB,MAAM,EAAE,YAAY,EACpB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,EAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,OAAO,CAAC,aAAa,CAAC;IAmGzB;;OAEG;IACG,kBAAkB,CACtB,MAAM,EAAE,YAAY,EACpB,cAAc,GAAE,MAAa,GAC5B,OAAO,CAAC,WAAW,CAAC;CAexB"}
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MetricsAggregator = void 0;
4
+ const status_checker_js_1 = require("./status-checker.js");
5
+ const system_collector_js_1 = require("./system-collector.js");
6
+ const process_utils_js_1 = require("../utils/process-utils.js");
7
+ /**
8
+ * Aggregates metrics from llama.cpp server API endpoints
9
+ * Combines server health, slot status, and model properties
10
+ */
11
+ class MetricsAggregator {
12
+ constructor(server, timeout = 5000) {
13
+ this.previousSlots = new Map();
14
+ // Handle null host (legacy configs) by defaulting to 127.0.0.1
15
+ const host = server.host || '127.0.0.1';
16
+ this.serverUrl = `http://${host}:${server.port}`;
17
+ this.timeout = timeout;
18
+ }
19
+ /**
20
+ * Fetch data from llama.cpp API with timeout
21
+ */
22
+ async fetchWithTimeout(endpoint, customTimeout) {
23
+ try {
24
+ const controller = new AbortController();
25
+ const timeoutMs = customTimeout ?? this.timeout;
26
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
27
+ const response = await fetch(`${this.serverUrl}${endpoint}`, {
28
+ signal: controller.signal,
29
+ });
30
+ clearTimeout(timeoutId);
31
+ if (!response.ok) {
32
+ return null;
33
+ }
34
+ return await response.json();
35
+ }
36
+ catch (err) {
37
+ // Network error, timeout, or parse error
38
+ return null;
39
+ }
40
+ }
41
+ /**
42
+ * Get server health status
43
+ */
44
+ async getHealth() {
45
+ const health = await this.fetchWithTimeout('/health');
46
+ return health !== null && health.status === 'ok';
47
+ }
48
+ /**
49
+ * Get server properties (model info, context size, etc.)
50
+ */
51
+ async getProps() {
52
+ return await this.fetchWithTimeout('/props');
53
+ }
54
+ /**
55
+ * Get active slots information with calculated tok/s
56
+ */
57
+ async getSlots() {
58
+ const data = await this.fetchWithTimeout('/slots');
59
+ if (!data || !Array.isArray(data)) {
60
+ return [];
61
+ }
62
+ const now = Date.now();
63
+ return data.map((slot) => {
64
+ const slotId = slot.id;
65
+ const n_decoded = slot.next_token?.[0]?.n_decoded || 0;
66
+ const isProcessing = slot.is_processing;
67
+ // Calculate tokens per second by comparing with previous poll
68
+ let predicted_per_second;
69
+ if (isProcessing && n_decoded > 0) {
70
+ const previous = this.previousSlots.get(slotId);
71
+ if (previous && previous.n_decoded < n_decoded) {
72
+ const tokensGenerated = n_decoded - previous.n_decoded;
73
+ const timeElapsed = (now - previous.timestamp) / 1000; // Convert to seconds
74
+ if (timeElapsed > 0) {
75
+ predicted_per_second = tokensGenerated / timeElapsed;
76
+ }
77
+ }
78
+ // Store current state for next comparison
79
+ this.previousSlots.set(slotId, { n_decoded, timestamp: now });
80
+ }
81
+ else if (!isProcessing) {
82
+ // Clear history when slot becomes idle
83
+ this.previousSlots.delete(slotId);
84
+ }
85
+ return {
86
+ id: slotId,
87
+ state: isProcessing ? 'processing' : 'idle',
88
+ n_prompt_tokens: slot.n_prompt_tokens,
89
+ n_decoded,
90
+ n_ctx: slot.n_ctx || 0,
91
+ timings: predicted_per_second
92
+ ? {
93
+ prompt_n: 0,
94
+ prompt_ms: 0,
95
+ prompt_per_token_ms: 0,
96
+ prompt_per_second: 0,
97
+ predicted_n: n_decoded,
98
+ predicted_ms: 0,
99
+ predicted_per_token_ms: 0,
100
+ predicted_per_second,
101
+ }
102
+ : undefined,
103
+ };
104
+ });
105
+ }
106
+ /**
107
+ * Aggregate all server metrics
108
+ * @param server - Server configuration
109
+ * @param processMemory - Optional pre-fetched process memory (for batch collection)
110
+ * @param processCpuUsage - Optional pre-fetched process CPU usage (for batch collection)
111
+ */
112
+ async collectServerMetrics(server, processMemory, processCpuUsage) {
113
+ const now = Date.now();
114
+ // Check basic server status first
115
+ const status = await status_checker_js_1.statusChecker.checkServer(server);
116
+ // Calculate uptime if server is running and has lastStarted
117
+ let uptime;
118
+ if (status.isRunning && server.lastStarted) {
119
+ const startTime = new Date(server.lastStarted).getTime();
120
+ const uptimeSeconds = Math.floor((now - startTime) / 1000);
121
+ const hours = Math.floor(uptimeSeconds / 3600);
122
+ const minutes = Math.floor((uptimeSeconds % 3600) / 60);
123
+ const seconds = uptimeSeconds % 60;
124
+ uptime = `${hours}h ${minutes}m ${seconds}s`;
125
+ }
126
+ // If server not running, return minimal data
127
+ if (!status.isRunning) {
128
+ return {
129
+ server,
130
+ healthy: false,
131
+ modelLoaded: false,
132
+ modelName: server.modelName,
133
+ contextSize: server.ctxSize,
134
+ totalSlots: 0,
135
+ activeSlots: 0,
136
+ idleSlots: 0,
137
+ slots: [],
138
+ timestamp: now,
139
+ stale: false,
140
+ };
141
+ }
142
+ // Fetch detailed metrics in parallel
143
+ // If processMemory/CPU were pre-fetched (batch mode), use them; otherwise fetch individually
144
+ const [healthy, props, slots, fetchedMemory, fetchedCpu] = await Promise.all([
145
+ this.getHealth(),
146
+ this.getProps(),
147
+ this.getSlots(),
148
+ processMemory !== undefined
149
+ ? Promise.resolve(processMemory)
150
+ : (server.pid ? (0, process_utils_js_1.getProcessMemory)(server.pid) : Promise.resolve(null)),
151
+ processCpuUsage !== undefined
152
+ ? Promise.resolve(processCpuUsage)
153
+ : (server.pid ? (0, process_utils_js_1.getProcessCpu)(server.pid) : Promise.resolve(null)),
154
+ ]);
155
+ // Calculate slot statistics
156
+ const activeSlots = slots.filter((s) => s.state === 'processing').length;
157
+ const idleSlots = slots.filter((s) => s.state === 'idle').length;
158
+ const totalSlots = props?.total_slots || slots.length;
159
+ // Calculate average speeds (only from processing slots)
160
+ const processingSlots = slots.filter((s) => s.state === 'processing' && s.timings);
161
+ const avgPromptSpeed = processingSlots.length > 0
162
+ ? processingSlots.reduce((sum, s) => sum + (s.timings?.prompt_per_second || 0), 0) / processingSlots.length
163
+ : undefined;
164
+ const avgGenerateSpeed = processingSlots.length > 0
165
+ ? processingSlots.reduce((sum, s) => sum + (s.timings?.predicted_per_second || 0), 0) / processingSlots.length
166
+ : undefined;
167
+ // Calculate total memory (CPU + Metal GPU memory if available)
168
+ let totalMemory = fetchedMemory ?? undefined;
169
+ if (totalMemory !== undefined && server.metalMemoryMB) {
170
+ // Add Metal memory (convert MB to bytes)
171
+ totalMemory += server.metalMemoryMB * 1024 * 1024;
172
+ }
173
+ return {
174
+ server,
175
+ healthy,
176
+ uptime,
177
+ modelLoaded: props !== null,
178
+ modelName: server.modelName,
179
+ contextSize: props?.default_generation_settings?.n_ctx || server.ctxSize,
180
+ totalSlots,
181
+ activeSlots,
182
+ idleSlots,
183
+ slots,
184
+ avgPromptSpeed,
185
+ avgGenerateSpeed,
186
+ processMemory: totalMemory,
187
+ processCpuUsage: fetchedCpu ?? undefined,
188
+ timestamp: now,
189
+ stale: false,
190
+ };
191
+ }
192
+ /**
193
+ * Collect complete monitoring data (server + system metrics)
194
+ */
195
+ async collectMonitorData(server, updateInterval = 2000) {
196
+ // Collect server and system metrics in parallel
197
+ const [serverMetrics, systemMetrics] = await Promise.all([
198
+ this.collectServerMetrics(server),
199
+ system_collector_js_1.systemCollector.collectSystemMetrics(),
200
+ ]);
201
+ return {
202
+ server: serverMetrics,
203
+ system: systemMetrics,
204
+ lastUpdated: new Date(),
205
+ updateInterval,
206
+ consecutiveFailures: 0,
207
+ };
208
+ }
209
+ }
210
+ exports.MetricsAggregator = MetricsAggregator;
211
+ //# sourceMappingURL=metrics-aggregator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-aggregator.js","sourceRoot":"","sources":["../../src/lib/metrics-aggregator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { SystemMetrics } from '../types/monitor-types.js';
2
+ /**
3
+ * System metrics collector using macmon (optional) and vm_stat (fallback)
4
+ * Provides GPU, CPU, ANE, and memory metrics on macOS
5
+ */
6
+ export declare class SystemCollector {
7
+ private macmonPath;
8
+ private macmonAvailable;
9
+ private lastSystemMetrics;
10
+ private lastCollectionTime;
11
+ private readonly CACHE_TTL_MS;
12
+ private collectingLock;
13
+ private pCoreCount;
14
+ private eCoreCount;
15
+ private totalCores;
16
+ constructor(macmonPath?: string);
17
+ /**
18
+ * Get CPU core counts for weighted average calculation
19
+ */
20
+ private initializeCoreCount;
21
+ /**
22
+ * Check if macmon is available
23
+ */
24
+ private checkMacmonAvailability;
25
+ /**
26
+ * Parse macmon JSON output
27
+ * Expected format from 'macmon pipe':
28
+ * {
29
+ * "gpu_usage": [count, percentage],
30
+ * "pcpu_usage": [count, percentage],
31
+ * "ecpu_usage": [count, percentage],
32
+ * "ane_power": number,
33
+ * "temp": {"cpu_temp_avg": number, "gpu_temp_avg": number}
34
+ * }
35
+ */
36
+ private parseMacmonJson;
37
+ /**
38
+ * Collect macmon metrics (GPU, CPU, ANE)
39
+ * Uses 'macmon pipe' which outputs one JSON line per update
40
+ * Spawns macmon, reads one line, and kills it to prevent process leaks
41
+ */
42
+ private getMacmonMetrics;
43
+ /**
44
+ * Parse vm_stat output for memory metrics
45
+ * Expected format:
46
+ * Pages free: 123456.
47
+ * Pages active: 234567.
48
+ * Pages inactive: 345678.
49
+ * Pages speculative: 45678.
50
+ * Pages throttled: 0.
51
+ * Pages wired down: 123456.
52
+ * Pages purgeable count: 0.
53
+ * "Translation faults": 12345678.
54
+ * Pages copy-on-write: 123456.
55
+ * ...
56
+ */
57
+ private parseVmStatOutput;
58
+ /**
59
+ * Get total system memory from sysctl
60
+ * Returns installed RAM size in bytes
61
+ */
62
+ private getTotalMemory;
63
+ /**
64
+ * Collect vm_stat memory metrics + total system memory from sysctl
65
+ */
66
+ private getMemoryMetrics;
67
+ /**
68
+ * Collect all system metrics
69
+ * Attempts macmon first (GPU/CPU/ANE), always gets memory from vm_stat + sysctl
70
+ * Caches results for 4s to prevent spawning multiple macmon processes
71
+ */
72
+ collectSystemMetrics(): Promise<SystemMetrics>;
73
+ /**
74
+ * Internal method to actually collect system metrics
75
+ * Called by collectSystemMetrics with caching/locking
76
+ */
77
+ private doCollectSystemMetrics;
78
+ }
79
+ export declare const systemCollector: SystemCollector;
80
+ //# sourceMappingURL=system-collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-collector.d.ts","sourceRoot":"","sources":["../../src/lib/system-collector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAwB;IAC/C,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAa;gBAEnB,UAAU,GAAE,MAAmC;IAK3D;;OAEG;YACW,mBAAmB;IA4BjC;;OAEG;YACW,uBAAuB;IAerC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IAiDvB;;;;OAIG;YACW,gBAAgB;IA2B9B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;;OAGG;YACW,cAAc;IAS5B;;OAEG;YACW,gBAAgB;IAmB9B;;;;OAIG;IACG,oBAAoB,IAAI,OAAO,CAAC,aAAa,CAAC;IA0BpD;;;OAGG;YACW,sBAAsB;CAkCrC;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}