@downcity/agent 1.1.228 → 1.1.236
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/bin/agent/local/Agent.d.ts +6 -1
- package/bin/agent/local/Agent.d.ts.map +1 -1
- package/bin/agent/local/Agent.js +30 -3
- package/bin/agent/local/Agent.js.map +1 -1
- package/bin/agent/local/services/AgentSessions.d.ts +23 -0
- package/bin/agent/local/services/AgentSessions.d.ts.map +1 -1
- package/bin/agent/local/services/AgentSessions.js +44 -0
- package/bin/agent/local/services/AgentSessions.js.map +1 -1
- package/bin/agent/remote/RemoteSession.d.ts +2 -0
- package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
- package/bin/agent/remote/RemoteSession.js +4 -0
- package/bin/agent/remote/RemoteSession.js.map +1 -1
- package/bin/agent/remote/RemoteTransport.d.ts +2 -0
- package/bin/agent/remote/RemoteTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +1 -0
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +11 -7
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +1 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +1 -0
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +3 -0
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +1 -1
- package/bin/executor/Executor.d.ts +43 -0
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +127 -7
- package/bin/executor/Executor.js.map +1 -1
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts +10 -0
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts +0 -10
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js +4 -34
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +1 -3
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +7 -59
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineContextCompaction.d.ts +38 -0
- package/bin/executor/core-engine/CoreEngineContextCompaction.d.ts.map +1 -0
- package/bin/executor/core-engine/CoreEngineContextCompaction.js +392 -0
- package/bin/executor/core-engine/CoreEngineContextCompaction.js.map +1 -0
- package/bin/executor/core-engine/CoreEngineMessageState.d.ts +15 -0
- package/bin/executor/core-engine/CoreEngineMessageState.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineMessageState.js +20 -0
- package/bin/executor/core-engine/CoreEngineMessageState.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.d.ts +15 -0
- package/bin/executor/core-engine/CoreEngineRunner.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.js +150 -35
- package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
- package/bin/executor/store/history/SessionHistoryStore.d.ts +7 -23
- package/bin/executor/store/history/SessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +2 -4
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
- package/bin/executor/tools/plugin/PluginToolBridge.d.ts.map +1 -1
- package/bin/executor/tools/plugin/PluginToolBridge.js +4 -2
- package/bin/executor/tools/plugin/PluginToolBridge.js.map +1 -1
- package/bin/executor/types/SessionRun.d.ts +8 -0
- package/bin/executor/types/SessionRun.d.ts.map +1 -1
- package/bin/index.d.ts +3 -2
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +2 -2
- package/bin/index.js.map +1 -1
- package/bin/model/CityModelAdapter.d.ts +6 -0
- package/bin/model/CityModelAdapter.d.ts.map +1 -1
- package/bin/model/CityModelAdapter.js +13 -0
- package/bin/model/CityModelAdapter.js.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.js +3 -3
- package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
- package/bin/plugin/core/PluginRegistry.d.ts +41 -2
- package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
- package/bin/plugin/core/PluginRegistry.js +145 -6
- package/bin/plugin/core/PluginRegistry.js.map +1 -1
- package/bin/rpc/Client.d.ts +4 -0
- package/bin/rpc/Client.d.ts.map +1 -1
- package/bin/rpc/Client.js +11 -0
- package/bin/rpc/Client.js.map +1 -1
- package/bin/session/Session.d.ts +15 -1
- package/bin/session/Session.d.ts.map +1 -1
- package/bin/session/Session.js +83 -11
- package/bin/session/Session.js.map +1 -1
- package/bin/session/SessionSystemBuilder.d.ts.map +1 -1
- package/bin/session/SessionSystemBuilder.js +3 -1
- package/bin/session/SessionSystemBuilder.js.map +1 -1
- package/bin/session/browse/Browse.d.ts +0 -8
- package/bin/session/browse/Browse.d.ts.map +1 -1
- package/bin/session/browse/Browse.js +72 -57
- package/bin/session/browse/Browse.js.map +1 -1
- package/bin/session/recorder/JsonlSessionMessageStore.d.ts +69 -16
- package/bin/session/recorder/JsonlSessionMessageStore.d.ts.map +1 -1
- package/bin/session/recorder/JsonlSessionMessageStore.js +283 -60
- package/bin/session/recorder/JsonlSessionMessageStore.js.map +1 -1
- package/bin/session/recorder/SessionRecorder.d.ts +20 -2
- package/bin/session/recorder/SessionRecorder.d.ts.map +1 -1
- package/bin/session/recorder/SessionRecorder.js +91 -46
- package/bin/session/recorder/SessionRecorder.js.map +1 -1
- package/bin/session/recorder/SessionRecorderCompaction.d.ts +3 -3
- package/bin/session/recorder/SessionRecorderCompaction.d.ts.map +1 -1
- package/bin/session/recorder/SessionRecorderCompaction.js +118 -88
- package/bin/session/recorder/SessionRecorderCompaction.js.map +1 -1
- package/bin/session/recorder/SessionRecorderHistoryStore.d.ts +2 -2
- package/bin/session/recorder/SessionRecorderHistoryStore.d.ts.map +1 -1
- package/bin/session/recorder/SessionRecorderHistoryStore.js +31 -36
- package/bin/session/recorder/SessionRecorderHistoryStore.js.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.d.ts +21 -1
- package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.js +65 -8
- package/bin/session/runtime/SessionPromptRuntime.js.map +1 -1
- package/bin/session/services/SessionStateService.d.ts +19 -1
- package/bin/session/services/SessionStateService.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.js +70 -40
- package/bin/session/services/SessionStateService.js.map +1 -1
- package/bin/session/services/SessionTurnService.d.ts +15 -0
- package/bin/session/services/SessionTurnService.d.ts.map +1 -1
- package/bin/session/services/SessionTurnService.js +104 -7
- package/bin/session/services/SessionTurnService.js.map +1 -1
- package/bin/session/services/SessionViewService.d.ts +1 -5
- package/bin/session/services/SessionViewService.d.ts.map +1 -1
- package/bin/session/services/SessionViewService.js +4 -34
- package/bin/session/services/SessionViewService.js.map +1 -1
- package/bin/session/storage/Paths.d.ts +3 -15
- package/bin/session/storage/Paths.d.ts.map +1 -1
- package/bin/session/storage/Paths.js +5 -21
- package/bin/session/storage/Paths.js.map +1 -1
- package/bin/types/agent/SessionActor.d.ts +8 -0
- package/bin/types/agent/SessionActor.d.ts.map +1 -1
- package/bin/types/agent/SessionTypes.d.ts +2 -24
- package/bin/types/agent/SessionTypes.d.ts.map +1 -1
- package/bin/types/executor/SessionRunContext.d.ts +29 -0
- package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
- package/bin/types/plugin/PluginRuntime.d.ts +59 -2
- package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
- package/bin/types/plugin/PluginState.d.ts +10 -0
- package/bin/types/plugin/PluginState.d.ts.map +1 -1
- package/bin/types/rpc/RpcProtocol.d.ts +10 -0
- package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
- package/bin/types/runtime/agent/AgentContext.d.ts +17 -5
- package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
- package/bin/types/runtime/agent/AgentContext.js +29 -6
- package/bin/types/runtime/agent/AgentContext.js.map +1 -1
- package/bin/types/session/SessionLocalState.d.ts +8 -0
- package/bin/types/session/SessionLocalState.d.ts.map +1 -1
- package/bin/types/session/SessionMessage.d.ts +16 -12
- package/bin/types/session/SessionMessage.d.ts.map +1 -1
- package/bin/types/session/SessionMutation.d.ts +1 -1
- package/bin/types/session/SessionMutation.js +1 -1
- package/bin/types/session/SessionOptions.d.ts +16 -0
- package/bin/types/session/SessionOptions.d.ts.map +1 -1
- package/bin/types/session/SessionQueueCommand.d.ts +68 -0
- package/bin/types/session/SessionQueueCommand.d.ts.map +1 -0
- package/bin/types/session/SessionQueueCommand.js +10 -0
- package/bin/types/session/SessionQueueCommand.js.map +1 -0
- package/bin/types/session/SessionSegment.d.ts +57 -0
- package/bin/types/session/SessionSegment.d.ts.map +1 -0
- package/bin/types/session/SessionSegment.js +8 -0
- package/bin/types/session/SessionSegment.js.map +1 -0
- package/bin/utils/logger/Logger.d.ts +7 -9
- package/bin/utils/logger/Logger.d.ts.map +1 -1
- package/bin/utils/logger/Logger.js +11 -9
- package/bin/utils/logger/Logger.js.map +1 -1
- package/package.json +3 -3
- package/scripts/city-model-tool-loop.test.mjs +32 -0
- package/scripts/core-engine-context-compaction.test.mjs +411 -0
- package/scripts/logger-isolation.test.mjs +55 -0
- package/scripts/multi-agent-plugin-isolation.test.mjs +289 -0
- package/scripts/plugin-tool-bridge.test.mjs +52 -0
- package/scripts/remote-session-reconnect.test.mjs +18 -0
- package/scripts/session-action-message.test.mjs +59 -13
- package/scripts/session-compaction-context-window.test.mjs +96 -0
- package/scripts/session-config-turn-boundary.test.mjs +278 -0
- package/scripts/session-list-title.test.mjs +21 -3
- package/scripts/session-prompt-runtime.test.mjs +93 -0
- package/scripts/session-recorder.test.mjs +335 -15
- package/src/agent/local/Agent.ts +34 -3
- package/src/agent/local/services/AgentSessions.ts +61 -0
- package/src/agent/remote/RemoteSession.ts +5 -0
- package/src/agent/remote/RemoteTransport.ts +2 -0
- package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +15 -5
- package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +4 -0
- package/src/executor/Executor.ts +161 -7
- package/src/executor/composer/compaction/SessionCompactionComposer.ts +12 -0
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.ts +4 -55
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +8 -66
- package/src/executor/core-engine/CoreEngineContextCompaction.ts +477 -0
- package/src/executor/core-engine/CoreEngineMessageState.ts +29 -0
- package/src/executor/core-engine/CoreEngineRunner.ts +211 -43
- package/src/executor/store/history/SessionHistoryStore.ts +7 -26
- package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +2 -4
- package/src/executor/tools/plugin/PluginToolBridge.ts +4 -2
- package/src/executor/types/SessionRun.ts +9 -0
- package/src/index.ts +9 -1
- package/src/model/CityModelAdapter.ts +15 -0
- package/src/plugin/core/PluginLocalExecution.ts +3 -3
- package/src/plugin/core/PluginRegistry.ts +187 -6
- package/src/rpc/Client.ts +12 -0
- package/src/session/Session.ts +97 -11
- package/src/session/SessionSystemBuilder.ts +4 -1
- package/src/session/browse/Browse.ts +73 -69
- package/src/session/recorder/JsonlSessionMessageStore.ts +378 -60
- package/src/session/recorder/SessionRecorder.ts +116 -49
- package/src/session/recorder/SessionRecorderCompaction.ts +131 -108
- package/src/session/recorder/SessionRecorderHistoryStore.ts +29 -49
- package/src/session/runtime/SessionPromptRuntime.ts +86 -10
- package/src/session/services/SessionStateService.ts +89 -45
- package/src/session/services/SessionTurnService.ts +112 -7
- package/src/session/services/SessionViewService.ts +4 -50
- package/src/session/storage/Paths.ts +5 -38
- package/src/types/agent/SessionActor.ts +9 -0
- package/src/types/agent/SessionTypes.ts +2 -24
- package/src/types/executor/SessionRunContext.ts +34 -0
- package/src/types/plugin/PluginRuntime.ts +63 -2
- package/src/types/plugin/PluginState.ts +10 -0
- package/src/types/rpc/RpcProtocol.ts +11 -0
- package/src/types/runtime/agent/AgentContext.ts +32 -7
- package/src/types/session/SessionLocalState.ts +9 -0
- package/src/types/session/SessionMessage.ts +16 -12
- package/src/types/session/SessionMutation.ts +1 -1
- package/src/types/session/SessionOptions.ts +21 -0
- package/src/types/session/SessionQueueCommand.ts +78 -0
- package/src/types/session/SessionSegment.ts +62 -0
- package/src/utils/logger/Logger.ts +10 -10
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -94,13 +94,6 @@ type SessionBrowseBaseInput = {
|
|
|
94
94
|
executing?: boolean;
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
-
type SessionArchiveFileV1 = {
|
|
98
|
-
v?: unknown;
|
|
99
|
-
sessionId?: unknown;
|
|
100
|
-
archivedAt?: unknown;
|
|
101
|
-
messages?: unknown;
|
|
102
|
-
};
|
|
103
|
-
|
|
104
97
|
function decodeMaybe(input: string): string {
|
|
105
98
|
try {
|
|
106
99
|
return decodeURIComponent(input);
|
|
@@ -140,11 +133,6 @@ function encodeCursor(offset: number): string | undefined {
|
|
|
140
133
|
return String(Math.floor(offset));
|
|
141
134
|
}
|
|
142
135
|
|
|
143
|
-
function normalizeArchiveId(input: unknown): string | undefined {
|
|
144
|
-
const value = String(input || "").trim();
|
|
145
|
-
return value || undefined;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
136
|
function stringifyForDisplay(input: unknown, maxChars = 2400): string {
|
|
149
137
|
if (input === undefined) return "";
|
|
150
138
|
if (input === null) return "null";
|
|
@@ -344,7 +332,7 @@ export async function loadSessionMessagesFromPath(
|
|
|
344
332
|
}
|
|
345
333
|
}
|
|
346
334
|
|
|
347
|
-
const inflight_path =
|
|
335
|
+
const inflight_path = path.join(path.dirname(filePath), "assistant_message.json");
|
|
348
336
|
if (await fs.pathExists(inflight_path)) {
|
|
349
337
|
try {
|
|
350
338
|
const message = (await fs.readJson(inflight_path)) as SessionMessage;
|
|
@@ -395,52 +383,12 @@ function project_canonical_message_record(message: SessionMessage): SessionRecor
|
|
|
395
383
|
}];
|
|
396
384
|
}
|
|
397
385
|
|
|
398
|
-
/**
|
|
399
|
-
* 读取 compact archive 文件中的消息。
|
|
400
|
-
*
|
|
401
|
-
* 关键点(中文)
|
|
402
|
-
* - archive 是 compact 时被覆盖的“上一层历史”,不是当前运行态事实源。
|
|
403
|
-
* - 这里不读取 inflight,因为 archive 层永远是已完成的历史快照。
|
|
404
|
-
*/
|
|
405
|
-
export async function loadSessionArchiveMessagesFromPath(
|
|
406
|
-
filePath: string,
|
|
407
|
-
): Promise<SessionRecordV1[]> {
|
|
408
|
-
try {
|
|
409
|
-
const raw = (await fs.readJson(filePath)) as SessionArchiveFileV1 | null;
|
|
410
|
-
const items = Array.isArray(raw?.messages) ? raw.messages : [];
|
|
411
|
-
return items.filter((item): item is SessionRecordV1 => {
|
|
412
|
-
if (!item || typeof item !== "object") return false;
|
|
413
|
-
const candidate = item as { type?: unknown; role?: unknown; parts?: unknown };
|
|
414
|
-
return (
|
|
415
|
-
(
|
|
416
|
-
candidate.type === "action" ||
|
|
417
|
-
candidate.role === "user" ||
|
|
418
|
-
candidate.role === "assistant"
|
|
419
|
-
) &&
|
|
420
|
-
(candidate.type === "action" || Array.isArray(candidate.parts))
|
|
421
|
-
);
|
|
422
|
-
});
|
|
423
|
-
} catch {
|
|
424
|
-
return [];
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
386
|
function isCompactSummaryMessage(message: SessionRecordV1): boolean {
|
|
429
387
|
if (!is_session_message_record(message)) return false;
|
|
430
388
|
const metadata = (message.metadata || null) as SessionMetadataV1 | null;
|
|
431
389
|
return metadata?.source === "compact" || metadata?.kind === "summary";
|
|
432
390
|
}
|
|
433
391
|
|
|
434
|
-
function resolvePreviousArchiveId(messages: SessionRecordV1[]): string | undefined {
|
|
435
|
-
for (const message of messages) {
|
|
436
|
-
if (!isCompactSummaryMessage(message)) continue;
|
|
437
|
-
const metadata = (message.metadata || null) as SessionMetadataV1 | null;
|
|
438
|
-
const archiveId = normalizeArchiveId(metadata?.archiveId);
|
|
439
|
-
if (archiveId) return archiveId;
|
|
440
|
-
}
|
|
441
|
-
return undefined;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
392
|
function filterUserVisibleHistoryMessages(
|
|
445
393
|
messages: SessionRecordV1[],
|
|
446
394
|
): SessionRecordV1[] {
|
|
@@ -460,9 +408,11 @@ export function buildSessionInfo(
|
|
|
460
408
|
180,
|
|
461
409
|
)
|
|
462
410
|
: input.metadata.previewText;
|
|
463
|
-
const message_count =
|
|
464
|
-
?
|
|
465
|
-
:
|
|
411
|
+
const message_count = typeof input.metadata.messageCount === "number"
|
|
412
|
+
? input.metadata.messageCount
|
|
413
|
+
: messages
|
|
414
|
+
? filterUserVisibleHistoryMessages(messages).length
|
|
415
|
+
: 0;
|
|
466
416
|
const title =
|
|
467
417
|
typeof input.metadata.title === "string" && input.metadata.title.trim()
|
|
468
418
|
? input.metadata.title.trim()
|
|
@@ -494,7 +444,7 @@ export function buildSessionInfo(
|
|
|
494
444
|
* 读取列表所需的轻量 session 摘要。
|
|
495
445
|
*
|
|
496
446
|
* 关键点(中文)
|
|
497
|
-
* - 新记录直接使用 metadata 摘要,不扫描
|
|
447
|
+
* - 新记录直接使用 metadata 摘要,不扫描 active.jsonl。
|
|
498
448
|
* - 旧记录或执行中记录回退读取一次完整历史,并把摘要补写回 metadata。
|
|
499
449
|
*/
|
|
500
450
|
async function resolve_session_summary_metadata(input: {
|
|
@@ -507,10 +457,9 @@ async function resolve_session_summary_metadata(input: {
|
|
|
507
457
|
/** 是否强制刷新摘要。 */
|
|
508
458
|
refresh: boolean;
|
|
509
459
|
}): Promise<SessionHistoryMetaV1> {
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
const inflight_path = `${input.messagesPath.slice(0, -"messages.jsonl".length)}assistant_message.json`;
|
|
460
|
+
const storage_stats = await resolve_session_disk_stats(input.messagesPath);
|
|
461
|
+
const history_bytes = storage_stats.history_bytes;
|
|
462
|
+
const inflight_path = path.join(path.dirname(input.messagesPath), "assistant_message.json");
|
|
514
463
|
const has_inflight = await fs.pathExists(inflight_path);
|
|
515
464
|
if (
|
|
516
465
|
!input.refresh &&
|
|
@@ -529,9 +478,11 @@ async function resolve_session_summary_metadata(input: {
|
|
|
529
478
|
void _previous_preview;
|
|
530
479
|
const next_metadata: SessionHistoryMetaV1 = {
|
|
531
480
|
...metadata_without_preview,
|
|
532
|
-
messageCount:
|
|
481
|
+
messageCount: storage_stats.message_count,
|
|
533
482
|
historyBytes: history_bytes,
|
|
534
|
-
...(preview_text
|
|
483
|
+
...(preview_text || input.metadata.previewText
|
|
484
|
+
? { previewText: preview_text || input.metadata.previewText }
|
|
485
|
+
: {}),
|
|
535
486
|
};
|
|
536
487
|
const temp_path = `${input.metaPath}.${process.pid}.${Date.now()}.tmp`;
|
|
537
488
|
await fs.ensureDir(path.dirname(input.metaPath));
|
|
@@ -540,6 +491,65 @@ async function resolve_session_summary_metadata(input: {
|
|
|
540
491
|
return next_metadata;
|
|
541
492
|
}
|
|
542
493
|
|
|
494
|
+
/**
|
|
495
|
+
* 只读取 Active 和 Segment 文件索引,计算列表所需的持久化统计。
|
|
496
|
+
*
|
|
497
|
+
* 关键点(中文)
|
|
498
|
+
* - Segment 的结束 sequence 直接来自文件名,不解析历史正文。
|
|
499
|
+
* - Active 需要逐行读取,以同时覆盖 revision 行与运行中 Assistant sequence。
|
|
500
|
+
*/
|
|
501
|
+
async function resolve_session_disk_stats(messages_path: string) {
|
|
502
|
+
const messages_dir_path = path.dirname(messages_path);
|
|
503
|
+
const segments_dir_path = path.join(messages_dir_path, "segments");
|
|
504
|
+
const segment_entries = await fs.readdir(segments_dir_path, { withFileTypes: true })
|
|
505
|
+
.catch(() => []);
|
|
506
|
+
const segment_files = segment_entries.flatMap((entry) => {
|
|
507
|
+
if (!entry.isFile()) return [];
|
|
508
|
+
const match = /^(\d+)-(\d+)\.jsonl$/.exec(entry.name);
|
|
509
|
+
if (!match) return [];
|
|
510
|
+
return [{
|
|
511
|
+
file_path: path.join(segments_dir_path, entry.name),
|
|
512
|
+
end_sequence: Number(match[2]),
|
|
513
|
+
}];
|
|
514
|
+
});
|
|
515
|
+
const active_raw = await fs.readFile(messages_path, "utf8").catch(() => "");
|
|
516
|
+
let latest_active_sequence = 0;
|
|
517
|
+
for (const line of active_raw.split("\n")) {
|
|
518
|
+
if (!line.trim()) continue;
|
|
519
|
+
try {
|
|
520
|
+
const message = JSON.parse(line) as Partial<SessionMessage>;
|
|
521
|
+
if (Number.isInteger(message.sequence)) {
|
|
522
|
+
latest_active_sequence = Math.max(latest_active_sequence, Number(message.sequence));
|
|
523
|
+
}
|
|
524
|
+
} catch {
|
|
525
|
+
// 单行损坏不阻断 Session 列表,其正文读取时会按既有规则忽略。
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
const inflight_path = path.join(messages_dir_path, "assistant_message.json");
|
|
529
|
+
try {
|
|
530
|
+
const inflight = await fs.readJson(inflight_path) as Partial<SessionMessage>;
|
|
531
|
+
if (Number.isInteger(inflight.sequence)) {
|
|
532
|
+
latest_active_sequence = Math.max(latest_active_sequence, Number(inflight.sequence));
|
|
533
|
+
}
|
|
534
|
+
} catch {
|
|
535
|
+
// 草稿不存在或损坏时只统计已完成历史。
|
|
536
|
+
}
|
|
537
|
+
const segment_sizes = await Promise.all(
|
|
538
|
+
segment_files.map(({ file_path }) => fs.stat(file_path)
|
|
539
|
+
.then((file_stat) => file_stat.size)
|
|
540
|
+
.catch(() => 0)),
|
|
541
|
+
);
|
|
542
|
+
const latest_segment_sequence = segment_files.reduce(
|
|
543
|
+
(latest, segment) => Math.max(latest, segment.end_sequence),
|
|
544
|
+
0,
|
|
545
|
+
);
|
|
546
|
+
return {
|
|
547
|
+
history_bytes: Buffer.byteLength(active_raw, "utf8") +
|
|
548
|
+
segment_sizes.reduce((total, size) => total + size, 0),
|
|
549
|
+
message_count: Math.max(latest_segment_sequence, latest_active_sequence),
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
543
553
|
/**
|
|
544
554
|
* 基于完整消息列表构建 session records 分页结果。
|
|
545
555
|
*/
|
|
@@ -552,8 +562,6 @@ export function buildSessionRecordsPage(params: {
|
|
|
552
562
|
const order = params.input?.order || "asc";
|
|
553
563
|
const limit = normalizeLimit(params.input?.limit, 50, 500);
|
|
554
564
|
const cursor = normalizeCursor(params.input?.cursor);
|
|
555
|
-
const archive_id = normalizeArchiveId(params.input?.archive_id);
|
|
556
|
-
const previous_archive_id = resolvePreviousArchiveId(params.messages);
|
|
557
565
|
const visibleMessages = filterUserVisibleHistoryMessages(params.messages);
|
|
558
566
|
|
|
559
567
|
if (view === "timeline") {
|
|
@@ -570,8 +578,6 @@ export function buildSessionRecordsPage(params: {
|
|
|
570
578
|
? { next_cursor: encodeCursor(nextOffset) }
|
|
571
579
|
: {}),
|
|
572
580
|
has_more: nextOffset < orderedEvents.length,
|
|
573
|
-
...(archive_id ? { archive_id } : {}),
|
|
574
|
-
...(previous_archive_id ? { previous_archive_id } : {}),
|
|
575
581
|
};
|
|
576
582
|
}
|
|
577
583
|
|
|
@@ -588,8 +594,6 @@ export function buildSessionRecordsPage(params: {
|
|
|
588
594
|
? { next_cursor: encodeCursor(nextOffset) }
|
|
589
595
|
: {}),
|
|
590
596
|
has_more: nextOffset < orderedMessages.length,
|
|
591
|
-
...(archive_id ? { archive_id } : {}),
|
|
592
|
-
...(previous_archive_id ? { previous_archive_id } : {}),
|
|
593
597
|
};
|
|
594
598
|
}
|
|
595
599
|
|