fix: 消除会话列表解析阻塞并按需加载工具详情

This commit is contained in:
shiyue
2026-10-19 10:58:22 +08:00
parent fb2c3360c9
commit 99cc807f4b
35 changed files with 1468 additions and 214 deletions

View File

@@ -39,7 +39,11 @@ function createServerHarness(sessionsDir, options = {}) {
'findSessionMessage',
'saveSession', 'sessionHistoryCacheKey', 'cacheSessionHistory', 'loadNativeSessionHistory',
'resolveSessionHistory',
'listSessionFiles', 'refreshSessionSnapshotCache', 'prepareNativeHistoryImport',
'listSessionFiles', 'loadSessionMetaFromFile', 'prepareNativeHistoryImport',
'isJsonWhitespace', 'skipJsonWhitespace', 'readJsonStringEnd', 'readJsonContainerEnd', 'readJsonValueEnd',
'parseJsonTopLevelPrefixFields', 'skipJsonWhitespaceBackward', 'readJsonStringStart', 'readJsonValueStart',
'parseJsonTopLevelSuffixFields', 'readSessionPreviewTopLevelFields', 'previewStringField', 'previewBooleanField',
'previewCreatedFromKind', 'normalizeCreatedFromSourceSessionId', 'readSessionPreview',
'handleSlashCommand', 'handleDeleteSession', 'findCcwebPromptMessage', 'removeCcwebPromptMessage',
'rollbackPersistedCodexAppSteerMessage', 'handleLoadHistoryPage',
'buildSessionInfoPayload', 'handleResumeSession',
@@ -47,6 +51,8 @@ function createServerHarness(sessionsDir, options = {}) {
const api = new Function('fs', 'path', 'crypto', 'SESSIONS_DIR', 'sessionHistoryStore', 'rollouts', 'options', 'logs', `
const SESSION_MAX_JSON_BYTES = options.snapshotMaxBytes || 512 * 1024;
const SESSION_LOAD_MAX_BYTES = 32 * 1024 * 1024;
const SESSION_META_FULL_PARSE_MAX_BYTES = 512 * 1024;
const SESSION_META_PREVIEW_BYTES = 128 * 1024;
const SESSION_PERSIST_MAX_MESSAGES = options.snapshotMaxMessages || 180;
const SESSION_MESSAGE_CONTENT_MAX_CHARS = 96 * 1024;
const SESSION_TOOL_INPUT_MAX_CHARS = 16 * 1024;
@@ -107,6 +113,9 @@ function createServerHarness(sessionsDir, options = {}) {
}
function isCodexLikeSession(session) { return session.agent === 'codex' || session.agent === 'codexapp'; }
function getSessionAgent(session) { return session.agent || 'claude'; }
function sessionCreatedFromKind(session) { return session.createdFrom?.kind || null; }
function normalizeGiteaSource(value) { return value || null; }
function isCodexThreadGoalActive(value) { return value?.status === 'active'; }
function getCodexRolloutFiles() { return options.nativeFiles || []; }
function resolveClaudeSessionLocalMeta() { return null; }
const parseCodexRolloutFile = rollouts.parseCodexRolloutFile;
@@ -119,7 +128,7 @@ function createServerHarness(sessionsDir, options = {}) {
? loadOptions.full : options.fullHistory !== false && !explicitWindow;
return loadSession(id, { ...loadOptions, full });
},
saveSession, resolveSessionHistory, listSessionFiles, refreshSessionSnapshotCache, findSessionMessage,
saveSession, resolveSessionHistory, listSessionFiles, loadSessionMetaFromFile, findSessionMessage,
prepareNativeHistoryImport, handleSlashCommand, handleDeleteSession, removeCcwebPromptMessage,
rollbackPersistedCodexAppSteerMessage, handleLoadHistoryPage, responses, logs, sessionHistoryStore,
buildSessionInfoPayload, handleResumeSession,
@@ -294,7 +303,7 @@ check('完整归档成功而快照失败仍返回成功并恢复最新元数据'
assert.equal(reloaded.codexAppThreadId, loaded.codexAppThreadId);
});
check('首次快照失败的孤立档案重开后仍可读取并参与列表且缓存恢复有界', dir => {
check('首次快照失败的孤立档案重开后仍可读取并参与列表且不重建正文快照', dir => {
const filesystem = new Proxy(fs, {
get(target, key) {
if (key === 'renameSync') return (from, to) => {
@@ -310,11 +319,11 @@ check('首次快照失败的孤立档案重开后仍可读取并参与列表且
const failedCacheApi = createServerHarness(dir, { fs: filesystem });
assert.deepEqual(failedCacheApi.loadSession('orphan').messages, original.messages);
assert(failedCacheApi.listSessionFiles().includes('orphan.json'));
assert(failedCacheApi.refreshSessionSnapshotCache('orphan').session.messages.length <= 181);
assert.equal(failedCacheApi.loadSessionMetaFromFile(path.join(dir, 'orphan.json')).id, 'orphan');
const reopened = createServerHarness(dir);
assert(reopened.listSessionFiles().includes('orphan.json'));
assert(reopened.refreshSessionSnapshotCache('orphan').session.messages.length <= 181);
assert(fs.existsSync(path.join(dir, 'orphan.json')));
assert.equal(reopened.loadSessionMetaFromFile(path.join(dir, 'orphan.json')).id, 'orphan');
assert.equal(fs.existsSync(path.join(dir, 'orphan.json')), false);
});
check('运行态保留目录和同名旧文件不会干扰完整归档与会话列表', dir => {