fix: Codex 自动压缩不触发 —— 接管时链接模型目录(绝对路径)进 config.toml (hot 1.5.83)
This commit is contained in:
+20
-11
@@ -9,6 +9,10 @@ const CODEX_HOME = process.env.CODEX_HOME || path.join(os.homedir(), ".codex");
|
||||
const SESSIONS_ROOT = path.join(CODEX_HOME, "sessions");
|
||||
const RESET_PATH = path.join(CODEX_HOME, ".tokendun-token-reset.json");
|
||||
const fileCache = new Map();
|
||||
const fsp = fs.promises;
|
||||
// 正在增长(流式生成中)的会话文件每次变化都会导致全量重读,阻塞主进程事件循环。
|
||||
// 给同一文件加最小重读间隔:5 秒内即使变了也复用上次结果,token 统计允许秒级延迟。
|
||||
const MIN_REREAD_MS = 5000;
|
||||
|
||||
function clean(n) {
|
||||
n = Number(n);
|
||||
@@ -61,19 +65,24 @@ function snapshotAt(line) {
|
||||
return usage.total > 0 ? { timestamp, usage } : null;
|
||||
}
|
||||
|
||||
function parseSessionFile(file) {
|
||||
async function parseSessionFile(file) {
|
||||
try {
|
||||
const stat = fs.statSync(file);
|
||||
const stat = await fsp.stat(file);
|
||||
const cached = fileCache.get(file);
|
||||
if (cached && cached.size === stat.size && cached.mtimeMs === stat.mtimeMs) return cached.value;
|
||||
if (cached) {
|
||||
// 未变化 → 直接用缓存
|
||||
if (cached.size === stat.size && cached.mtimeMs === stat.mtimeMs) return cached.value;
|
||||
// 变化了但距上次读太近 → 复用缓存,避免流式生成期间反复全量读盘阻塞主进程
|
||||
if (Date.now() - cached.readAt < MIN_REREAD_MS) return cached.value;
|
||||
}
|
||||
const text = await fsp.readFile(file, "utf8");
|
||||
const snapshots = [];
|
||||
const text = fs.readFileSync(file, "utf8");
|
||||
for (const line of text.split("\n")) {
|
||||
const snapshot = snapshotAt(line);
|
||||
if (snapshot) snapshots.push(snapshot);
|
||||
}
|
||||
const value = { snapshots };
|
||||
fileCache.set(file, { size: stat.size, mtimeMs: stat.mtimeMs, value });
|
||||
fileCache.set(file, { size: stat.size, mtimeMs: stat.mtimeMs, value, readAt: Date.now() });
|
||||
return value;
|
||||
} catch {
|
||||
return { snapshots: [] };
|
||||
@@ -132,7 +141,7 @@ function applyReset(value) {
|
||||
};
|
||||
}
|
||||
|
||||
function readDailyRaw(now = new Date()) {
|
||||
async function readDailyRaw(now = new Date()) {
|
||||
const date = dayKey(now);
|
||||
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
|
||||
@@ -140,7 +149,7 @@ function readDailyRaw(now = new Date()) {
|
||||
result.available = fs.existsSync(SESSIONS_ROOT);
|
||||
|
||||
for (const file of sessionFilesForDay(start, end)) {
|
||||
const snapshots = parseSessionFile(file).snapshots;
|
||||
const snapshots = (await parseSessionFile(file)).snapshots;
|
||||
let before = null;
|
||||
let current = null;
|
||||
for (const snapshot of snapshots) {
|
||||
@@ -159,12 +168,12 @@ function readDailyRaw(now = new Date()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function readDaily(now = new Date()) {
|
||||
return applyReset(readDailyRaw(now));
|
||||
async function readDaily(now = new Date()) {
|
||||
return applyReset(await readDailyRaw(now));
|
||||
}
|
||||
|
||||
function reset(now = new Date()) {
|
||||
const value = readDailyRaw(now);
|
||||
async function reset(now = new Date()) {
|
||||
const value = await readDailyRaw(now);
|
||||
fs.mkdirSync(path.dirname(RESET_PATH), { recursive: true });
|
||||
fs.writeFileSync(RESET_PATH, JSON.stringify({ ...value, date: dayKey(now) }), "utf8");
|
||||
return blank(dayKey(now));
|
||||
|
||||
Reference in New Issue
Block a user