@yeaft/webchat-agent 0.1.780 → 0.1.781
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 +1 -1
- package/unify/session.js +45 -2
package/package.json
CHANGED
package/unify/session.js
CHANGED
|
@@ -50,7 +50,7 @@ import { openSegmentIndex } from './memory/index-db.js';
|
|
|
50
50
|
import { syncAll as syncSegmentIndex } from './memory/segment-sync.js';
|
|
51
51
|
import { openAmsRegistry } from './memory/ams-registry.js';
|
|
52
52
|
import { join } from 'path';
|
|
53
|
-
import { existsSync as existsSyncSafe, readFileSync as readFileSyncSafe } from 'fs';
|
|
53
|
+
import { existsSync as existsSyncSafe, readFileSync as readFileSyncSafe, mkdirSync as mkdirSyncSafe } from 'fs';
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* @typedef {Object} SessionOptions
|
|
@@ -80,6 +80,33 @@ import { existsSync as existsSyncSafe, readFileSync as readFileSyncSafe } from '
|
|
|
80
80
|
* @property {() => Promise<void>} shutdown — Graceful shutdown
|
|
81
81
|
*/
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Eagerly create `<yeaftDir>/stats/` and surface failures as a warn.
|
|
85
|
+
*
|
|
86
|
+
* Returns the resolved path either way — the caller can still pass it
|
|
87
|
+
* to `ToolUsageStats`, which keeps an in-memory counter path even when
|
|
88
|
+
* the disk is read-only.
|
|
89
|
+
*
|
|
90
|
+
* NOTE: this knowledge ("stats lives under `stats/`") belongs inside
|
|
91
|
+
* `ToolUsageStats.init()`. Once that exists, delete this helper and
|
|
92
|
+
* the call site collapses to `await toolStats.init(yeaftDir)`.
|
|
93
|
+
*
|
|
94
|
+
* @param {string} yeaftDir
|
|
95
|
+
* @returns {string} statsDir
|
|
96
|
+
*/
|
|
97
|
+
function prepareToolStatsDir(yeaftDir) {
|
|
98
|
+
const statsDir = join(yeaftDir, 'stats');
|
|
99
|
+
try {
|
|
100
|
+
mkdirSyncSafe(statsDir, { recursive: true });
|
|
101
|
+
} catch (err) {
|
|
102
|
+
console.warn(
|
|
103
|
+
`[Unify] Could not create stats dir ${statsDir}: ${err?.message || err}. ` +
|
|
104
|
+
`Tool-usage counters will live in memory only.`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
return statsDir;
|
|
108
|
+
}
|
|
109
|
+
|
|
83
110
|
/**
|
|
84
111
|
* Load (or initialize) a Yeaft session.
|
|
85
112
|
*
|
|
@@ -320,8 +347,24 @@ export async function loadSession(options = {}) {
|
|
|
320
347
|
// Tool-call usage statistics: persisted to <yeaftDir>/stats/tool-usage.json.
|
|
321
348
|
// Loaded synchronously at boot so the first turn already sees prior counts.
|
|
322
349
|
// Threaded into the engine so it can `record` each tool_exec event.
|
|
350
|
+
//
|
|
351
|
+
// 2026-05-16: eagerly create the `stats/` directory at boot. The
|
|
352
|
+
// ToolUsageStats writer does `fsp.mkdir(..., {recursive:true})` lazily
|
|
353
|
+
// inside `#doFlush()` and swallows any mkdir error, which meant an
|
|
354
|
+
// unwritable parent (perm denied, ENOSPC) was silently invisible
|
|
355
|
+
// until the user filed a support ticket. Doing it here surfaces the
|
|
356
|
+
// failure as a console.warn while still leaving the in-memory
|
|
357
|
+
// counter path functional — the engine keeps recording even if the
|
|
358
|
+
// disk is read-only.
|
|
359
|
+
//
|
|
360
|
+
// FOLLOW-UP: this leaks `ToolUsageStats`'s storage layout (its
|
|
361
|
+
// directory name) into the session orchestrator. The right home is
|
|
362
|
+
// a `ToolUsageStats.init()` that owns the mkdir + the warn + a
|
|
363
|
+
// `writesDisabled` flag. Tracking as future work; for now the helper
|
|
364
|
+
// below visually quarantines the leak so the migration is one delete.
|
|
365
|
+
const statsDir = prepareToolStatsDir(yeaftDir);
|
|
323
366
|
const toolStats = new ToolUsageStats({
|
|
324
|
-
path: join(
|
|
367
|
+
path: join(statsDir, 'tool-usage.json'),
|
|
325
368
|
});
|
|
326
369
|
toolStats.loadSync();
|
|
327
370
|
const engine = new Engine({
|