@sleep2agi/commhub-server 0.8.1-preview.4 → 0.8.1-preview.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleep2agi/commhub-server",
3
- "version": "0.8.1-preview.4",
3
+ "version": "0.8.1-preview.5",
4
4
  "description": "CommHub Server — AI Agent communication hub with MCP protocol, multi-network isolation, user auth, and 17 MCP tools.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/db.ts CHANGED
@@ -28,6 +28,7 @@ db.exec(`
28
28
  disk_used_gb REAL,
29
29
  disk_avail_gb REAL,
30
30
  process_rss_bytes INTEGER,
31
+ process_rss_mb REAL,
31
32
  process_cpu_pct REAL,
32
33
  process_uptime_seconds REAL,
33
34
  process_in_flight_count INTEGER,
@@ -84,6 +85,7 @@ for (const col of [
84
85
  { name: "disk_used_gb", def: "REAL" },
85
86
  { name: "disk_avail_gb", def: "REAL" },
86
87
  { name: "process_rss_bytes", def: "INTEGER" },
88
+ { name: "process_rss_mb", def: "REAL" },
87
89
  { name: "process_cpu_pct", def: "REAL" },
88
90
  { name: "process_uptime_seconds", def: "REAL" },
89
91
  { name: "process_in_flight_count", def: "INTEGER" },
@@ -108,6 +110,7 @@ db.exec(`
108
110
  disk_used_gb REAL,
109
111
  disk_avail_gb REAL,
110
112
  process_rss_bytes INTEGER,
113
+ process_rss_mb REAL,
111
114
  process_cpu_pct REAL,
112
115
  process_uptime_seconds REAL,
113
116
  process_in_flight_count INTEGER,
@@ -439,6 +442,7 @@ function migrateSessionsNetworkAliasUnique() {
439
442
  disk_used_gb REAL,
440
443
  disk_avail_gb REAL,
441
444
  process_rss_bytes INTEGER,
445
+ process_rss_mb REAL,
442
446
  process_cpu_pct REAL,
443
447
  process_uptime_seconds REAL,
444
448
  process_in_flight_count INTEGER,
@@ -452,7 +456,7 @@ function migrateSessionsNetworkAliasUnique() {
452
456
  status, task, output, progress, score, registered_at, updated_at, node_id,
453
457
  session_id, config_path, channels, last_seen_at, model, cpu_load_1min,
454
458
  cpu_cores, mem_total_gb, mem_used_gb, mem_avail_gb, disk_total_gb,
455
- disk_used_gb, disk_avail_gb, process_rss_bytes, process_cpu_pct,
459
+ disk_used_gb, disk_avail_gb, process_rss_bytes, process_rss_mb, process_cpu_pct,
456
460
  process_uptime_seconds, process_in_flight_count, network_id
457
461
  )
458
462
  SELECT
@@ -460,7 +464,7 @@ function migrateSessionsNetworkAliasUnique() {
460
464
  status, task, output, progress, score, registered_at, updated_at, node_id,
461
465
  session_id, config_path, channels, last_seen_at, model, cpu_load_1min,
462
466
  cpu_cores, mem_total_gb, mem_used_gb, mem_avail_gb, disk_total_gb,
463
- disk_used_gb, disk_avail_gb, process_rss_bytes, process_cpu_pct,
467
+ disk_used_gb, disk_avail_gb, process_rss_bytes, process_rss_mb, process_cpu_pct,
464
468
  process_uptime_seconds, process_in_flight_count,
465
469
  COALESCE(NULLIF(network_id, ''), 'default')
466
470
  FROM sessions
package/src/index.ts CHANGED
@@ -928,6 +928,25 @@ Bun.serve({
928
928
  ...s,
929
929
  model: s.model ?? null,
930
930
  runtime: normalizeRuntime(s.agent),
931
+ host: {
932
+ hostname: s.hostname ?? null,
933
+ ip: s.ip ?? null,
934
+ cpu_load_1min: s.cpu_load_1min ?? null,
935
+ cpu_cores: s.cpu_cores ?? null,
936
+ mem_total_gb: s.mem_total_gb ?? null,
937
+ mem_used_gb: s.mem_used_gb ?? null,
938
+ mem_avail_gb: s.mem_avail_gb ?? null,
939
+ disk_total_gb: s.disk_total_gb ?? null,
940
+ disk_used_gb: s.disk_used_gb ?? null,
941
+ disk_avail_gb: s.disk_avail_gb ?? null,
942
+ },
943
+ process_telemetry: {
944
+ rss_bytes: s.process_rss_bytes ?? null,
945
+ rss_mb: s.process_rss_mb ?? null,
946
+ cpu_pct: s.process_cpu_pct ?? null,
947
+ uptime_seconds: s.process_uptime_seconds ?? null,
948
+ in_flight_count: s.process_in_flight_count ?? null,
949
+ },
931
950
  }));
932
951
  const summary = sessions.reduce((acc: any, session: any) => {
933
952
  const raw = String(session.status || "").toLowerCase();
@@ -1010,7 +1029,7 @@ Bun.serve({
1010
1029
  SELECT alias, agent, status, task, progress, model, hostname, ip,
1011
1030
  cpu_load_1min, cpu_cores, mem_avail_gb, mem_used_gb, mem_total_gb,
1012
1031
  disk_avail_gb, disk_used_gb, disk_total_gb,
1013
- process_rss_bytes, process_cpu_pct, process_uptime_seconds, process_in_flight_count,
1032
+ process_rss_bytes, process_rss_mb, process_cpu_pct, process_uptime_seconds, process_in_flight_count,
1014
1033
  COALESCE(last_seen_at, updated_at) AS last_seen
1015
1034
  FROM sessions
1016
1035
  WHERE (hostname = ?1 OR ip = ?2)
@@ -1040,10 +1059,18 @@ Bun.serve({
1040
1059
  disk_used_gb: s.disk_used_gb ?? null,
1041
1060
  disk_avail_gb: s.disk_avail_gb ?? null,
1042
1061
  process_rss_bytes: s.process_rss_bytes ?? null,
1062
+ process_rss_mb: s.process_rss_mb ?? null,
1043
1063
  process_cpu_pct: s.process_cpu_pct ?? null,
1044
1064
  process_uptime_seconds: s.process_uptime_seconds ?? null,
1045
1065
  process_in_flight_count: s.process_in_flight_count ?? null,
1046
1066
  },
1067
+ process_telemetry: {
1068
+ rss_bytes: s.process_rss_bytes ?? null,
1069
+ rss_mb: s.process_rss_mb ?? null,
1070
+ cpu_pct: s.process_cpu_pct ?? null,
1071
+ uptime_seconds: s.process_uptime_seconds ?? null,
1072
+ in_flight_count: s.process_in_flight_count ?? null,
1073
+ },
1047
1074
  }));
1048
1075
  if (agents.length === 0) return withCors(req, Response.json({ ok: false, error: "server not found" }, { status: 404 }));
1049
1076
  return withCors(req, Response.json({ ok: true, host, agent_count: agents.length, agents }));
package/src/tools.ts CHANGED
@@ -132,6 +132,8 @@ export function registerTools(server: McpServer, clientIP?: string, enforceNetwo
132
132
  disk_avail_gb: z.number().nullable().optional(),
133
133
  }).optional().describe("Host telemetry reported by agent-node"),
134
134
  process_telemetry: z.object({
135
+ rss_bytes: z.number().nullable().optional(),
136
+ rss_mb: z.number().nullable().optional(),
135
137
  rss: z.number().nullable().optional(),
136
138
  cpu_pct: z.number().nullable().optional(),
137
139
  uptime_seconds: z.number().nullable().optional(),
@@ -159,17 +161,39 @@ export function registerTools(server: McpServer, clientIP?: string, enforceNetwo
159
161
  const diskTotalGb = typeof host?.disk_total_gb === "number" ? host.disk_total_gb : null;
160
162
  const diskUsedGb = typeof host?.disk_used_gb === "number" ? host.disk_used_gb : null;
161
163
  const diskAvailGb = typeof host?.disk_avail_gb === "number" ? host.disk_avail_gb : null;
162
- const processRssBytes = typeof proc?.rss === "number" ? proc.rss : null;
164
+ const processRssBytes = typeof proc?.rss_bytes === "number" ? proc.rss_bytes : (typeof proc?.rss === "number" ? proc.rss : null);
165
+ const processRssMb = typeof proc?.rss_mb === "number"
166
+ ? proc.rss_mb
167
+ : (typeof processRssBytes === "number" ? Math.round((processRssBytes / 1024 / 1024) * 10) / 10 : null);
163
168
  const processCpuPct = typeof proc?.cpu_pct === "number" ? proc.cpu_pct : null;
164
169
  const processUptimeSeconds = typeof proc?.uptime_seconds === "number" ? proc.uptime_seconds : null;
165
170
  const processInFlightCount = typeof proc?.in_flight_count === "number" ? proc.in_flight_count : null;
171
+ const statusHostTelemetry = host ? {
172
+ hostname: hostHostname,
173
+ ip: hostIp,
174
+ cpu_load_1min: cpuLoad1m,
175
+ cpu_cores: cpuCores,
176
+ mem_total_gb: memTotalGb,
177
+ mem_used_gb: memUsedGb,
178
+ mem_avail_gb: memAvailGb,
179
+ disk_total_gb: diskTotalGb,
180
+ disk_used_gb: diskUsedGb,
181
+ disk_avail_gb: diskAvailGb,
182
+ } : null;
183
+ const statusProcessTelemetry = proc ? {
184
+ rss_bytes: processRssBytes,
185
+ rss_mb: processRssMb,
186
+ cpu_pct: processCpuPct,
187
+ uptime_seconds: processUptimeSeconds,
188
+ in_flight_count: processInFlightCount,
189
+ } : null;
166
190
 
167
191
  db.transaction(() => {
168
192
  // Only delete same-alias sessions within the same network
169
193
  db.run("DELETE FROM sessions WHERE alias = ?1 AND resume_id != ?2 AND network_id = ?3", [alias, resume_id, sessionNetId]);
170
194
  db.run(
171
- `INSERT INTO sessions (resume_id, alias, tmux_name, server, ip, hostname, agent, project_dir, version, status, task, output, progress, score, node_id, session_id, config_path, channels, network_id, model, cpu_load_1min, cpu_cores, mem_total_gb, mem_used_gb, mem_avail_gb, disk_total_gb, disk_used_gb, disk_avail_gb, process_rss_bytes, process_cpu_pct, process_uptime_seconds, process_in_flight_count, last_seen_at, updated_at)
172
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32, datetime('now'), datetime('now'))
195
+ `INSERT INTO sessions (resume_id, alias, tmux_name, server, ip, hostname, agent, project_dir, version, status, task, output, progress, score, node_id, session_id, config_path, channels, network_id, model, cpu_load_1min, cpu_cores, mem_total_gb, mem_used_gb, mem_avail_gb, disk_total_gb, disk_used_gb, disk_avail_gb, process_rss_bytes, process_rss_mb, process_cpu_pct, process_uptime_seconds, process_in_flight_count, last_seen_at, updated_at)
196
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32, ?33, datetime('now'), datetime('now'))
173
197
  ON CONFLICT(resume_id) DO UPDATE SET
174
198
  alias = COALESCE(?2, sessions.alias), tmux_name = COALESCE(?3, sessions.tmux_name),
175
199
  server = COALESCE(?4, sessions.server), ip = COALESCE(?5, sessions.ip),
@@ -190,20 +214,29 @@ export function registerTools(server: McpServer, clientIP?: string, enforceNetwo
190
214
  disk_used_gb = COALESCE(?27, sessions.disk_used_gb),
191
215
  disk_avail_gb = COALESCE(?28, sessions.disk_avail_gb),
192
216
  process_rss_bytes = COALESCE(?29, sessions.process_rss_bytes),
193
- process_cpu_pct = COALESCE(?30, sessions.process_cpu_pct),
194
- process_uptime_seconds = COALESCE(?31, sessions.process_uptime_seconds),
195
- process_in_flight_count = COALESCE(?32, sessions.process_in_flight_count),
217
+ process_rss_mb = COALESCE(?30, sessions.process_rss_mb),
218
+ process_cpu_pct = COALESCE(?31, sessions.process_cpu_pct),
219
+ process_uptime_seconds = COALESCE(?32, sessions.process_uptime_seconds),
220
+ process_in_flight_count = COALESCE(?33, sessions.process_in_flight_count),
196
221
  last_seen_at = datetime('now'), updated_at = datetime('now')`,
197
- [resume_id, alias, tmux ?? null, srv ?? null, hostIp, hostHostname, ag ?? null, pd ?? null, ver ?? null, status, task ?? null, trimmedOutput ?? null, progress ?? null, score ?? null, node_id ?? null, session_id ?? null, config_path ?? null, channels ?? null, sessionNetId, mdl ?? null, cpuLoad1m, cpuCores, memTotalGb, memUsedGb, memAvailGb, diskTotalGb, diskUsedGb, diskAvailGb, processRssBytes, processCpuPct, processUptimeSeconds, processInFlightCount]
222
+ [resume_id, alias, tmux ?? null, srv ?? null, hostIp, hostHostname, ag ?? null, pd ?? null, ver ?? null, status, task ?? null, trimmedOutput ?? null, progress ?? null, score ?? null, node_id ?? null, session_id ?? null, config_path ?? null, channels ?? null, sessionNetId, mdl ?? null, cpuLoad1m, cpuCores, memTotalGb, memUsedGb, memAvailGb, diskTotalGb, diskUsedGb, diskAvailGb, processRssBytes, processRssMb, processCpuPct, processUptimeSeconds, processInFlightCount]
198
223
  );
199
224
  if (host || proc) {
200
225
  db.run(
201
- `INSERT INTO agent_telemetry (id, network_id, resume_id, alias, hostname, ip, cpu_load_1min, cpu_cores, mem_total_gb, mem_used_gb, mem_avail_gb, disk_total_gb, disk_used_gb, disk_avail_gb, process_rss_bytes, process_cpu_pct, process_uptime_seconds, process_in_flight_count, created_at)
202
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, datetime('now'))`,
203
- [uuidv4(), sessionNetId, resume_id, alias, hostHostname, hostIp, cpuLoad1m, cpuCores, memTotalGb, memUsedGb, memAvailGb, diskTotalGb, diskUsedGb, diskAvailGb, processRssBytes, processCpuPct, processUptimeSeconds, processInFlightCount]
226
+ `INSERT INTO agent_telemetry (id, network_id, resume_id, alias, hostname, ip, cpu_load_1min, cpu_cores, mem_total_gb, mem_used_gb, mem_avail_gb, disk_total_gb, disk_used_gb, disk_avail_gb, process_rss_bytes, process_rss_mb, process_cpu_pct, process_uptime_seconds, process_in_flight_count, created_at)
227
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, datetime('now'))`,
228
+ [uuidv4(), sessionNetId, resume_id, alias, hostHostname, hostIp, cpuLoad1m, cpuCores, memTotalGb, memUsedGb, memAvailGb, diskTotalGb, diskUsedGb, diskAvailGb, processRssBytes, processRssMb, processCpuPct, processUptimeSeconds, processInFlightCount]
204
229
  );
205
230
  }
206
231
  });
232
+ pushEvent(alias, {
233
+ type: "status_update",
234
+ alias,
235
+ status,
236
+ progress: progress ?? null,
237
+ host: statusHostTelemetry,
238
+ process_telemetry: statusProcessTelemetry,
239
+ }, sessionNetId);
207
240
 
208
241
  // V2: sync tasks table — report_status(working) → tasks.running
209
242
  if (status === "working" && task) {