@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.
Files changed (221) hide show
  1. package/bin/agent/local/Agent.d.ts +6 -1
  2. package/bin/agent/local/Agent.d.ts.map +1 -1
  3. package/bin/agent/local/Agent.js +30 -3
  4. package/bin/agent/local/Agent.js.map +1 -1
  5. package/bin/agent/local/services/AgentSessions.d.ts +23 -0
  6. package/bin/agent/local/services/AgentSessions.d.ts.map +1 -1
  7. package/bin/agent/local/services/AgentSessions.js +44 -0
  8. package/bin/agent/local/services/AgentSessions.js.map +1 -1
  9. package/bin/agent/remote/RemoteSession.d.ts +2 -0
  10. package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
  11. package/bin/agent/remote/RemoteSession.js +4 -0
  12. package/bin/agent/remote/RemoteSession.js.map +1 -1
  13. package/bin/agent/remote/RemoteTransport.d.ts +2 -0
  14. package/bin/agent/remote/RemoteTransport.d.ts.map +1 -1
  15. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +1 -0
  16. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -1
  17. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +11 -7
  18. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +1 -1
  19. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +1 -0
  20. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -1
  21. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +3 -0
  22. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +1 -1
  23. package/bin/executor/Executor.d.ts +43 -0
  24. package/bin/executor/Executor.d.ts.map +1 -1
  25. package/bin/executor/Executor.js +127 -7
  26. package/bin/executor/Executor.js.map +1 -1
  27. package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts +10 -0
  28. package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts.map +1 -1
  29. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts +0 -10
  30. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts.map +1 -1
  31. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js +4 -34
  32. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js.map +1 -1
  33. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +1 -3
  34. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
  35. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +7 -59
  36. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
  37. package/bin/executor/core-engine/CoreEngineContextCompaction.d.ts +38 -0
  38. package/bin/executor/core-engine/CoreEngineContextCompaction.d.ts.map +1 -0
  39. package/bin/executor/core-engine/CoreEngineContextCompaction.js +392 -0
  40. package/bin/executor/core-engine/CoreEngineContextCompaction.js.map +1 -0
  41. package/bin/executor/core-engine/CoreEngineMessageState.d.ts +15 -0
  42. package/bin/executor/core-engine/CoreEngineMessageState.d.ts.map +1 -1
  43. package/bin/executor/core-engine/CoreEngineMessageState.js +20 -0
  44. package/bin/executor/core-engine/CoreEngineMessageState.js.map +1 -1
  45. package/bin/executor/core-engine/CoreEngineRunner.d.ts +15 -0
  46. package/bin/executor/core-engine/CoreEngineRunner.d.ts.map +1 -1
  47. package/bin/executor/core-engine/CoreEngineRunner.js +150 -35
  48. package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
  49. package/bin/executor/store/history/SessionHistoryStore.d.ts +7 -23
  50. package/bin/executor/store/history/SessionHistoryStore.d.ts.map +1 -1
  51. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
  52. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +2 -4
  53. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
  54. package/bin/executor/tools/plugin/PluginToolBridge.d.ts.map +1 -1
  55. package/bin/executor/tools/plugin/PluginToolBridge.js +4 -2
  56. package/bin/executor/tools/plugin/PluginToolBridge.js.map +1 -1
  57. package/bin/executor/types/SessionRun.d.ts +8 -0
  58. package/bin/executor/types/SessionRun.d.ts.map +1 -1
  59. package/bin/index.d.ts +3 -2
  60. package/bin/index.d.ts.map +1 -1
  61. package/bin/index.js +2 -2
  62. package/bin/index.js.map +1 -1
  63. package/bin/model/CityModelAdapter.d.ts +6 -0
  64. package/bin/model/CityModelAdapter.d.ts.map +1 -1
  65. package/bin/model/CityModelAdapter.js +13 -0
  66. package/bin/model/CityModelAdapter.js.map +1 -1
  67. package/bin/plugin/core/PluginLocalExecution.js +3 -3
  68. package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
  69. package/bin/plugin/core/PluginRegistry.d.ts +41 -2
  70. package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
  71. package/bin/plugin/core/PluginRegistry.js +145 -6
  72. package/bin/plugin/core/PluginRegistry.js.map +1 -1
  73. package/bin/rpc/Client.d.ts +4 -0
  74. package/bin/rpc/Client.d.ts.map +1 -1
  75. package/bin/rpc/Client.js +11 -0
  76. package/bin/rpc/Client.js.map +1 -1
  77. package/bin/session/Session.d.ts +15 -1
  78. package/bin/session/Session.d.ts.map +1 -1
  79. package/bin/session/Session.js +83 -11
  80. package/bin/session/Session.js.map +1 -1
  81. package/bin/session/SessionSystemBuilder.d.ts.map +1 -1
  82. package/bin/session/SessionSystemBuilder.js +3 -1
  83. package/bin/session/SessionSystemBuilder.js.map +1 -1
  84. package/bin/session/browse/Browse.d.ts +0 -8
  85. package/bin/session/browse/Browse.d.ts.map +1 -1
  86. package/bin/session/browse/Browse.js +72 -57
  87. package/bin/session/browse/Browse.js.map +1 -1
  88. package/bin/session/recorder/JsonlSessionMessageStore.d.ts +69 -16
  89. package/bin/session/recorder/JsonlSessionMessageStore.d.ts.map +1 -1
  90. package/bin/session/recorder/JsonlSessionMessageStore.js +283 -60
  91. package/bin/session/recorder/JsonlSessionMessageStore.js.map +1 -1
  92. package/bin/session/recorder/SessionRecorder.d.ts +20 -2
  93. package/bin/session/recorder/SessionRecorder.d.ts.map +1 -1
  94. package/bin/session/recorder/SessionRecorder.js +91 -46
  95. package/bin/session/recorder/SessionRecorder.js.map +1 -1
  96. package/bin/session/recorder/SessionRecorderCompaction.d.ts +3 -3
  97. package/bin/session/recorder/SessionRecorderCompaction.d.ts.map +1 -1
  98. package/bin/session/recorder/SessionRecorderCompaction.js +118 -88
  99. package/bin/session/recorder/SessionRecorderCompaction.js.map +1 -1
  100. package/bin/session/recorder/SessionRecorderHistoryStore.d.ts +2 -2
  101. package/bin/session/recorder/SessionRecorderHistoryStore.d.ts.map +1 -1
  102. package/bin/session/recorder/SessionRecorderHistoryStore.js +31 -36
  103. package/bin/session/recorder/SessionRecorderHistoryStore.js.map +1 -1
  104. package/bin/session/runtime/SessionPromptRuntime.d.ts +21 -1
  105. package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
  106. package/bin/session/runtime/SessionPromptRuntime.js +65 -8
  107. package/bin/session/runtime/SessionPromptRuntime.js.map +1 -1
  108. package/bin/session/services/SessionStateService.d.ts +19 -1
  109. package/bin/session/services/SessionStateService.d.ts.map +1 -1
  110. package/bin/session/services/SessionStateService.js +70 -40
  111. package/bin/session/services/SessionStateService.js.map +1 -1
  112. package/bin/session/services/SessionTurnService.d.ts +15 -0
  113. package/bin/session/services/SessionTurnService.d.ts.map +1 -1
  114. package/bin/session/services/SessionTurnService.js +104 -7
  115. package/bin/session/services/SessionTurnService.js.map +1 -1
  116. package/bin/session/services/SessionViewService.d.ts +1 -5
  117. package/bin/session/services/SessionViewService.d.ts.map +1 -1
  118. package/bin/session/services/SessionViewService.js +4 -34
  119. package/bin/session/services/SessionViewService.js.map +1 -1
  120. package/bin/session/storage/Paths.d.ts +3 -15
  121. package/bin/session/storage/Paths.d.ts.map +1 -1
  122. package/bin/session/storage/Paths.js +5 -21
  123. package/bin/session/storage/Paths.js.map +1 -1
  124. package/bin/types/agent/SessionActor.d.ts +8 -0
  125. package/bin/types/agent/SessionActor.d.ts.map +1 -1
  126. package/bin/types/agent/SessionTypes.d.ts +2 -24
  127. package/bin/types/agent/SessionTypes.d.ts.map +1 -1
  128. package/bin/types/executor/SessionRunContext.d.ts +29 -0
  129. package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
  130. package/bin/types/plugin/PluginRuntime.d.ts +59 -2
  131. package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
  132. package/bin/types/plugin/PluginState.d.ts +10 -0
  133. package/bin/types/plugin/PluginState.d.ts.map +1 -1
  134. package/bin/types/rpc/RpcProtocol.d.ts +10 -0
  135. package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
  136. package/bin/types/runtime/agent/AgentContext.d.ts +17 -5
  137. package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
  138. package/bin/types/runtime/agent/AgentContext.js +29 -6
  139. package/bin/types/runtime/agent/AgentContext.js.map +1 -1
  140. package/bin/types/session/SessionLocalState.d.ts +8 -0
  141. package/bin/types/session/SessionLocalState.d.ts.map +1 -1
  142. package/bin/types/session/SessionMessage.d.ts +16 -12
  143. package/bin/types/session/SessionMessage.d.ts.map +1 -1
  144. package/bin/types/session/SessionMutation.d.ts +1 -1
  145. package/bin/types/session/SessionMutation.js +1 -1
  146. package/bin/types/session/SessionOptions.d.ts +16 -0
  147. package/bin/types/session/SessionOptions.d.ts.map +1 -1
  148. package/bin/types/session/SessionQueueCommand.d.ts +68 -0
  149. package/bin/types/session/SessionQueueCommand.d.ts.map +1 -0
  150. package/bin/types/session/SessionQueueCommand.js +10 -0
  151. package/bin/types/session/SessionQueueCommand.js.map +1 -0
  152. package/bin/types/session/SessionSegment.d.ts +57 -0
  153. package/bin/types/session/SessionSegment.d.ts.map +1 -0
  154. package/bin/types/session/SessionSegment.js +8 -0
  155. package/bin/types/session/SessionSegment.js.map +1 -0
  156. package/bin/utils/logger/Logger.d.ts +7 -9
  157. package/bin/utils/logger/Logger.d.ts.map +1 -1
  158. package/bin/utils/logger/Logger.js +11 -9
  159. package/bin/utils/logger/Logger.js.map +1 -1
  160. package/package.json +3 -3
  161. package/scripts/city-model-tool-loop.test.mjs +32 -0
  162. package/scripts/core-engine-context-compaction.test.mjs +411 -0
  163. package/scripts/logger-isolation.test.mjs +55 -0
  164. package/scripts/multi-agent-plugin-isolation.test.mjs +289 -0
  165. package/scripts/plugin-tool-bridge.test.mjs +52 -0
  166. package/scripts/remote-session-reconnect.test.mjs +18 -0
  167. package/scripts/session-action-message.test.mjs +59 -13
  168. package/scripts/session-compaction-context-window.test.mjs +96 -0
  169. package/scripts/session-config-turn-boundary.test.mjs +278 -0
  170. package/scripts/session-list-title.test.mjs +21 -3
  171. package/scripts/session-prompt-runtime.test.mjs +93 -0
  172. package/scripts/session-recorder.test.mjs +335 -15
  173. package/src/agent/local/Agent.ts +34 -3
  174. package/src/agent/local/services/AgentSessions.ts +61 -0
  175. package/src/agent/remote/RemoteSession.ts +5 -0
  176. package/src/agent/remote/RemoteTransport.ts +2 -0
  177. package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +15 -5
  178. package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +4 -0
  179. package/src/executor/Executor.ts +161 -7
  180. package/src/executor/composer/compaction/SessionCompactionComposer.ts +12 -0
  181. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.ts +4 -55
  182. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +8 -66
  183. package/src/executor/core-engine/CoreEngineContextCompaction.ts +477 -0
  184. package/src/executor/core-engine/CoreEngineMessageState.ts +29 -0
  185. package/src/executor/core-engine/CoreEngineRunner.ts +211 -43
  186. package/src/executor/store/history/SessionHistoryStore.ts +7 -26
  187. package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +2 -4
  188. package/src/executor/tools/plugin/PluginToolBridge.ts +4 -2
  189. package/src/executor/types/SessionRun.ts +9 -0
  190. package/src/index.ts +9 -1
  191. package/src/model/CityModelAdapter.ts +15 -0
  192. package/src/plugin/core/PluginLocalExecution.ts +3 -3
  193. package/src/plugin/core/PluginRegistry.ts +187 -6
  194. package/src/rpc/Client.ts +12 -0
  195. package/src/session/Session.ts +97 -11
  196. package/src/session/SessionSystemBuilder.ts +4 -1
  197. package/src/session/browse/Browse.ts +73 -69
  198. package/src/session/recorder/JsonlSessionMessageStore.ts +378 -60
  199. package/src/session/recorder/SessionRecorder.ts +116 -49
  200. package/src/session/recorder/SessionRecorderCompaction.ts +131 -108
  201. package/src/session/recorder/SessionRecorderHistoryStore.ts +29 -49
  202. package/src/session/runtime/SessionPromptRuntime.ts +86 -10
  203. package/src/session/services/SessionStateService.ts +89 -45
  204. package/src/session/services/SessionTurnService.ts +112 -7
  205. package/src/session/services/SessionViewService.ts +4 -50
  206. package/src/session/storage/Paths.ts +5 -38
  207. package/src/types/agent/SessionActor.ts +9 -0
  208. package/src/types/agent/SessionTypes.ts +2 -24
  209. package/src/types/executor/SessionRunContext.ts +34 -0
  210. package/src/types/plugin/PluginRuntime.ts +63 -2
  211. package/src/types/plugin/PluginState.ts +10 -0
  212. package/src/types/rpc/RpcProtocol.ts +11 -0
  213. package/src/types/runtime/agent/AgentContext.ts +32 -7
  214. package/src/types/session/SessionLocalState.ts +9 -0
  215. package/src/types/session/SessionMessage.ts +16 -12
  216. package/src/types/session/SessionMutation.ts +1 -1
  217. package/src/types/session/SessionOptions.ts +21 -0
  218. package/src/types/session/SessionQueueCommand.ts +78 -0
  219. package/src/types/session/SessionSegment.ts +62 -0
  220. package/src/utils/logger/Logger.ts +10 -10
  221. 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 = filePath.replace(/messages\.jsonl$/, "assistant_message.json");
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 = messages
464
- ? messages.length
465
- : input.metadata.messageCount || 0;
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 摘要,不扫描 messages.jsonl。
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 history_bytes = await fs.stat(input.messagesPath)
511
- .then((file_stat) => file_stat.size)
512
- .catch(() => 0);
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: messages.length,
481
+ messageCount: storage_stats.message_count,
533
482
  historyBytes: history_bytes,
534
- ...(preview_text ? { previewText: 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