小橘 d1a2ee876a fix: hermesRun command and tester verdict via llmExtract
- Fix hermes invocation: 'hermes -q' → 'hermes chat -q' with proper flags
- Replace fragile string.includes('PASS') with llmExtract judge
  (previous false positive: matched '--pass-session-id' in usage text)

小橘 🍊(NEKO Team)
2026-04-23 12:20:11 +00:00

121 lines
2.7 KiB
JavaScript

import { readFile } from "node:fs/promises";
import { linuxTcpSocketStats } from "./schema.ts";
const SOCKSTAT_PATH = "/proc/net/sockstat";
const RAW_MAX = 4096;
function parseInt10(s) {
const n = Number.parseInt(String(s), 10);
return Number.isFinite(n) ? Math.trunc(n) : NaN;
}
function parseSockstat(content) {
let socketsUsed = 0;
let tcpInuse = 0;
let tcpOrphan = 0;
let tcpTw = 0;
let tcpAlloc = 0;
let tcpMemPages = 0;
let parseOk = 1;
let socketsOk = false;
let tcpOk = false;
for (const line of content.split("\n")) {
const trimmed = line.trim();
if (trimmed.startsWith("sockets:")) {
const parts = trimmed.split(/\s+/);
const usedIdx = parts.indexOf("used");
if (usedIdx !== -1 && usedIdx + 1 < parts.length) {
const v = parseInt10(parts[usedIdx + 1]);
if (Number.isFinite(v)) {
socketsUsed = v;
socketsOk = true;
}
}
} else if (trimmed.startsWith("TCP:")) {
const parts = trimmed.split(/\s+/);
const map = {};
for (let i = 1; i + 1 < parts.length; i += 2) {
map[parts[i]] = parseInt10(parts[i + 1]);
}
const keys = ["inuse", "orphan", "tw", "alloc", "mem"];
if (keys.every((k) => Number.isFinite(map[k]))) {
tcpInuse = map.inuse;
tcpOrphan = map.orphan;
tcpTw = map.tw;
tcpAlloc = map.alloc;
tcpMemPages = map.mem;
tcpOk = true;
}
}
}
if (!socketsOk || !tcpOk) {
parseOk = 0;
socketsUsed = 0;
tcpInuse = 0;
tcpOrphan = 0;
tcpTw = 0;
tcpAlloc = 0;
tcpMemPages = 0;
}
return {
socketsUsed,
tcpInuse,
tcpOrphan,
tcpTw,
tcpAlloc,
tcpMemPages,
parseOk,
};
}
export async function compute(db, _peers) {
const ts = Date.now();
let rawSockstat = "";
let row = {
socketsUsed: 0,
tcpInuse: 0,
tcpOrphan: 0,
tcpTw: 0,
tcpAlloc: 0,
tcpMemPages: 0,
parseOk: 0,
};
try {
const content = await readFile(SOCKSTAT_PATH, "utf8");
rawSockstat =
content.length > RAW_MAX ? content.slice(0, RAW_MAX) : content;
row = parseSockstat(content);
} catch {
rawSockstat = "";
}
await db.insert(linuxTcpSocketStats).values({
ts,
socketsUsed: row.socketsUsed,
tcpInuse: row.tcpInuse,
tcpOrphan: row.tcpOrphan,
tcpTw: row.tcpTw,
tcpAlloc: row.tcpAlloc,
tcpMemPages: row.tcpMemPages,
parseOk: row.parseOk,
rawSockstat,
});
return {
ts,
socketsUsed: row.socketsUsed,
tcpInuse: row.tcpInuse,
tcpOrphan: row.tcpOrphan,
tcpTw: row.tcpTw,
tcpAlloc: row.tcpAlloc,
tcpMemPages: row.tcpMemPages,
parseOk: row.parseOk,
rawSockstat,
};
}