@downcity/agent 1.1.430 → 1.1.438

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 (488) hide show
  1. package/README.md +13 -11
  2. package/bin/agent/Agent.d.ts +3 -3
  3. package/bin/agent/Agent.d.ts.map +1 -1
  4. package/bin/agent/Agent.js +38 -8
  5. package/bin/agent/Agent.js.map +1 -1
  6. package/bin/agent/AgentInstructions.js +2 -2
  7. package/bin/agent/AgentInstructions.js.map +1 -1
  8. package/bin/agent/AgentMemoryStorage.d.ts.map +1 -1
  9. package/bin/agent/AgentMemoryStorage.js +1 -0
  10. package/bin/agent/AgentMemoryStorage.js.map +1 -1
  11. package/bin/agent/AgentSessions.d.ts +5 -1
  12. package/bin/agent/AgentSessions.d.ts.map +1 -1
  13. package/bin/agent/AgentSessions.js +17 -9
  14. package/bin/agent/AgentSessions.js.map +1 -1
  15. package/bin/executor/Executor.d.ts +9 -27
  16. package/bin/executor/Executor.d.ts.map +1 -1
  17. package/bin/executor/Executor.js +32 -127
  18. package/bin/executor/Executor.js.map +1 -1
  19. package/bin/executor/composer/system/default/SystemPromptAssets.d.ts +0 -4
  20. package/bin/executor/composer/system/default/SystemPromptAssets.d.ts.map +1 -1
  21. package/bin/executor/composer/system/default/SystemPromptAssets.js +0 -5
  22. package/bin/executor/composer/system/default/SystemPromptAssets.js.map +1 -1
  23. package/bin/executor/core-engine/CoreEngineContextCompaction.d.ts +3 -9
  24. package/bin/executor/core-engine/CoreEngineContextCompaction.d.ts.map +1 -1
  25. package/bin/executor/core-engine/CoreEngineContextCompaction.js +4 -130
  26. package/bin/executor/core-engine/CoreEngineContextCompaction.js.map +1 -1
  27. package/bin/executor/core-engine/CoreEngineRunner.d.ts +3 -30
  28. package/bin/executor/core-engine/CoreEngineRunner.d.ts.map +1 -1
  29. package/bin/executor/core-engine/CoreEngineRunner.js +38 -194
  30. package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
  31. package/bin/executor/core-engine/CoreEngineSignals.d.ts +6 -6
  32. package/bin/executor/core-engine/CoreEngineSignals.d.ts.map +1 -1
  33. package/bin/executor/core-engine/CoreEngineSignals.js +1 -1
  34. package/bin/executor/core-engine/CoreEngineSignals.js.map +1 -1
  35. package/bin/executor/messages/SessionAttachmentMapper.d.ts +2 -2
  36. package/bin/executor/messages/SessionAttachmentMapper.d.ts.map +1 -1
  37. package/bin/executor/messages/SessionAttachmentMapper.js.map +1 -1
  38. package/bin/executor/messages/SessionMessageLog.d.ts +3 -3
  39. package/bin/executor/messages/SessionMessageLog.d.ts.map +1 -1
  40. package/bin/executor/messages/SessionMessageLog.js.map +1 -1
  41. package/bin/executor/messages/SessionModelMessages.d.ts +0 -3
  42. package/bin/executor/messages/SessionModelMessages.d.ts.map +1 -1
  43. package/bin/executor/messages/SessionModelMessages.js +80 -97
  44. package/bin/executor/messages/SessionModelMessages.js.map +1 -1
  45. package/bin/executor/model/ModelStepRunner.d.ts +2 -6
  46. package/bin/executor/model/ModelStepRunner.d.ts.map +1 -1
  47. package/bin/executor/model/ModelStepRunner.js +0 -28
  48. package/bin/executor/model/ModelStepRunner.js.map +1 -1
  49. package/bin/executor/services/ExecutorRecoveryPolicy.d.ts +7 -64
  50. package/bin/executor/services/ExecutorRecoveryPolicy.d.ts.map +1 -1
  51. package/bin/executor/services/ExecutorRecoveryPolicy.js +29 -45
  52. package/bin/executor/services/ExecutorRecoveryPolicy.js.map +1 -1
  53. package/bin/executor/types/SessionHistoryMeta.d.ts +1 -3
  54. package/bin/executor/types/SessionHistoryMeta.d.ts.map +1 -1
  55. package/bin/executor/types/SessionHistoryMeta.js +1 -1
  56. package/bin/index.d.ts +9 -13
  57. package/bin/index.d.ts.map +1 -1
  58. package/bin/index.js +2 -4
  59. package/bin/index.js.map +1 -1
  60. package/bin/session/DefaultSessionComposer.d.ts +13 -7
  61. package/bin/session/DefaultSessionComposer.d.ts.map +1 -1
  62. package/bin/session/DefaultSessionComposer.js +26 -21
  63. package/bin/session/DefaultSessionComposer.js.map +1 -1
  64. package/bin/session/Session.d.ts +12 -19
  65. package/bin/session/Session.d.ts.map +1 -1
  66. package/bin/session/Session.js +70 -202
  67. package/bin/session/Session.js.map +1 -1
  68. package/bin/session/SessionComposition.d.ts +0 -2
  69. package/bin/session/SessionComposition.d.ts.map +1 -1
  70. package/bin/session/SessionComposition.js +30 -54
  71. package/bin/session/SessionComposition.js.map +1 -1
  72. package/bin/session/SessionLoop.d.ts +17 -16
  73. package/bin/session/SessionLoop.d.ts.map +1 -1
  74. package/bin/session/SessionLoop.js +217 -320
  75. package/bin/session/SessionLoop.js.map +1 -1
  76. package/bin/session/SessionMessages.d.ts +52 -44
  77. package/bin/session/SessionMessages.d.ts.map +1 -1
  78. package/bin/session/SessionMessages.js +285 -187
  79. package/bin/session/SessionMessages.js.map +1 -1
  80. package/bin/session/SessionQueue.d.ts +1 -1
  81. package/bin/session/SessionQueue.d.ts.map +1 -1
  82. package/bin/session/SessionQueue.js +2 -1
  83. package/bin/session/SessionQueue.js.map +1 -1
  84. package/bin/session/SessionState.d.ts +3 -7
  85. package/bin/session/SessionState.d.ts.map +1 -1
  86. package/bin/session/SessionState.js +50 -89
  87. package/bin/session/SessionState.js.map +1 -1
  88. package/bin/session/SessionSystem.d.ts +5 -1
  89. package/bin/session/SessionSystem.d.ts.map +1 -1
  90. package/bin/session/SessionSystem.js +40 -0
  91. package/bin/session/SessionSystem.js.map +1 -1
  92. package/bin/session/SessionTitle.d.ts +3 -3
  93. package/bin/session/SessionTitle.d.ts.map +1 -1
  94. package/bin/session/SessionTitle.js +2 -2
  95. package/bin/session/browse/Browse.d.ts +32 -46
  96. package/bin/session/browse/Browse.d.ts.map +1 -1
  97. package/bin/session/browse/Browse.js +104 -360
  98. package/bin/session/browse/Browse.js.map +1 -1
  99. package/bin/session/browse/SessionMessageTimeline.d.ts.map +1 -1
  100. package/bin/session/browse/SessionMessageTimeline.js +61 -37
  101. package/bin/session/browse/SessionMessageTimeline.js.map +1 -1
  102. package/bin/session/composer/policies/AdaptivePartContextPolicy.d.ts +35 -0
  103. package/bin/session/composer/policies/AdaptivePartContextPolicy.d.ts.map +1 -0
  104. package/bin/session/composer/policies/AdaptivePartContextPolicy.js +256 -0
  105. package/bin/session/composer/policies/AdaptivePartContextPolicy.js.map +1 -0
  106. package/bin/session/composer/policies/FullHistoryContextPolicy.d.ts +24 -0
  107. package/bin/session/composer/policies/FullHistoryContextPolicy.d.ts.map +1 -0
  108. package/bin/session/composer/policies/FullHistoryContextPolicy.js +31 -0
  109. package/bin/session/composer/policies/FullHistoryContextPolicy.js.map +1 -0
  110. package/bin/session/composer/policies/SessionSummaryPrompts.d.ts +16 -0
  111. package/bin/session/composer/policies/SessionSummaryPrompts.d.ts.map +1 -0
  112. package/bin/session/composer/policies/SessionSummaryPrompts.js +32 -0
  113. package/bin/session/composer/policies/SessionSummaryPrompts.js.map +1 -0
  114. package/bin/session/execution/SessionAssistantOutputAdapter.d.ts +15 -4
  115. package/bin/session/execution/SessionAssistantOutputAdapter.d.ts.map +1 -1
  116. package/bin/session/execution/SessionAssistantOutputAdapter.js +7 -3
  117. package/bin/session/execution/SessionAssistantOutputAdapter.js.map +1 -1
  118. package/bin/session/messages/{SessionActionMessageWriter.d.ts → SessionAgentActionPartWriter.d.ts} +7 -7
  119. package/bin/session/messages/SessionAgentActionPartWriter.d.ts.map +1 -0
  120. package/bin/session/messages/{SessionActionMessageWriter.js → SessionAgentActionPartWriter.js} +7 -7
  121. package/bin/session/messages/SessionAgentActionPartWriter.js.map +1 -0
  122. package/bin/session/messages/SessionAgentContent.d.ts +10 -0
  123. package/bin/session/messages/SessionAgentContent.d.ts.map +1 -0
  124. package/bin/session/messages/SessionAgentContent.js +44 -0
  125. package/bin/session/messages/SessionAgentContent.js.map +1 -0
  126. package/bin/session/messages/SessionAgentMessageState.d.ts +50 -0
  127. package/bin/session/messages/SessionAgentMessageState.d.ts.map +1 -0
  128. package/bin/session/messages/SessionAgentMessageState.js +283 -0
  129. package/bin/session/messages/SessionAgentMessageState.js.map +1 -0
  130. package/bin/session/messages/{SessionAssistantMessageWriter.d.ts → SessionAgentMessageWriter.d.ts} +22 -8
  131. package/bin/session/messages/SessionAgentMessageWriter.d.ts.map +1 -0
  132. package/bin/session/messages/{SessionAssistantMessageWriter.js → SessionAgentMessageWriter.js} +54 -42
  133. package/bin/session/messages/SessionAgentMessageWriter.js.map +1 -0
  134. package/bin/session/messages/SessionForkMessageFiles.d.ts +11 -0
  135. package/bin/session/messages/SessionForkMessageFiles.d.ts.map +1 -1
  136. package/bin/session/messages/SessionForkMessageFiles.js +8 -2
  137. package/bin/session/messages/SessionForkMessageFiles.js.map +1 -1
  138. package/bin/session/messages/SessionMessageInteractionWriter.d.ts +6 -6
  139. package/bin/session/messages/SessionMessageInteractionWriter.d.ts.map +1 -1
  140. package/bin/session/messages/SessionMessageInteractionWriter.js +4 -4
  141. package/bin/session/messages/SessionMessageInteractionWriter.js.map +1 -1
  142. package/bin/session/messages/SessionMessageText.d.ts +3 -3
  143. package/bin/session/messages/SessionMessageText.d.ts.map +1 -1
  144. package/bin/session/messages/SessionMessageText.js +0 -2
  145. package/bin/session/messages/SessionMessageText.js.map +1 -1
  146. package/bin/session/messages/SessionTurnFileDiffData.d.ts +3 -3
  147. package/bin/session/messages/SessionTurnFileDiffData.d.ts.map +1 -1
  148. package/bin/session/messages/SessionTurnFileDiffData.js.map +1 -1
  149. package/bin/session/messages/SessionUserMessage.d.ts +3 -3
  150. package/bin/session/messages/SessionUserMessage.d.ts.map +1 -1
  151. package/bin/session/messages/SessionUserMessage.js +6 -3
  152. package/bin/session/messages/SessionUserMessage.js.map +1 -1
  153. package/bin/session/preview/SessionMessagePreview.d.ts.map +1 -1
  154. package/bin/session/preview/SessionMessagePreview.js +25 -9
  155. package/bin/session/preview/SessionMessagePreview.js.map +1 -1
  156. package/bin/session/runtime/SessionTurnCompletion.d.ts +15 -0
  157. package/bin/session/runtime/SessionTurnCompletion.d.ts.map +1 -0
  158. package/bin/session/runtime/SessionTurnCompletion.js +126 -0
  159. package/bin/session/runtime/SessionTurnCompletion.js.map +1 -0
  160. package/bin/session/runtime/SessionTurnContext.d.ts.map +1 -1
  161. package/bin/session/runtime/SessionTurnContext.js +14 -19
  162. package/bin/session/runtime/SessionTurnContext.js.map +1 -1
  163. package/bin/session/runtime/SessionTurnFileDiff.d.ts +12 -0
  164. package/bin/session/runtime/SessionTurnFileDiff.d.ts.map +1 -0
  165. package/bin/session/runtime/SessionTurnFileDiff.js +71 -0
  166. package/bin/session/runtime/SessionTurnFileDiff.js.map +1 -0
  167. package/bin/session/storage/LocalSessionDataStore.d.ts +6 -41
  168. package/bin/session/storage/LocalSessionDataStore.d.ts.map +1 -1
  169. package/bin/session/storage/LocalSessionDataStore.js +19 -101
  170. package/bin/session/storage/LocalSessionDataStore.js.map +1 -1
  171. package/bin/session/storage/LocalSessionStore.d.ts +13 -5
  172. package/bin/session/storage/LocalSessionStore.d.ts.map +1 -1
  173. package/bin/session/storage/LocalSessionStore.js +153 -30
  174. package/bin/session/storage/LocalSessionStore.js.map +1 -1
  175. package/bin/session/storage/LocalStorePaths.d.ts +4 -16
  176. package/bin/session/storage/LocalStorePaths.d.ts.map +1 -1
  177. package/bin/session/storage/LocalStorePaths.js +7 -31
  178. package/bin/session/storage/LocalStorePaths.js.map +1 -1
  179. package/bin/session/storage/Metadata.d.ts +4 -4
  180. package/bin/session/storage/Metadata.d.ts.map +1 -1
  181. package/bin/session/storage/Metadata.js +3 -11
  182. package/bin/session/storage/Metadata.js.map +1 -1
  183. package/bin/session/storage/RuntimeSessionPort.d.ts +4 -4
  184. package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
  185. package/bin/session/storage/RuntimeSessionPort.js +3 -3
  186. package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
  187. package/bin/session/storage/SessionStorageCodec.d.ts +59 -0
  188. package/bin/session/storage/SessionStorageCodec.d.ts.map +1 -0
  189. package/bin/session/storage/SessionStorageCodec.js +331 -0
  190. package/bin/session/storage/SessionStorageCodec.js.map +1 -0
  191. package/bin/session/storage/SessionStorageSchema.d.ts +11 -0
  192. package/bin/session/storage/SessionStorageSchema.d.ts.map +1 -0
  193. package/bin/session/storage/SessionStorageSchema.js +131 -0
  194. package/bin/session/storage/SessionStorageSchema.js.map +1 -0
  195. package/bin/session/storage/SqliteSessionStorage.d.ts +120 -0
  196. package/bin/session/storage/SqliteSessionStorage.d.ts.map +1 -0
  197. package/bin/session/storage/SqliteSessionStorage.js +581 -0
  198. package/bin/session/storage/SqliteSessionStorage.js.map +1 -0
  199. package/bin/tools/ask/AskQuestionsTool.d.ts.map +1 -1
  200. package/bin/tools/ask/AskQuestionsTool.js +3 -1
  201. package/bin/tools/ask/AskQuestionsTool.js.map +1 -1
  202. package/bin/types/action/ActionResult.d.ts +9 -9
  203. package/bin/types/action/ActionResult.d.ts.map +1 -1
  204. package/bin/types/action/ActionResult.js +1 -1
  205. package/bin/types/agent/AgentOptions.d.ts +10 -0
  206. package/bin/types/agent/AgentOptions.d.ts.map +1 -1
  207. package/bin/types/agent/AgentStorage.d.ts +3 -1
  208. package/bin/types/agent/AgentStorage.d.ts.map +1 -1
  209. package/bin/types/agent/SessionActor.d.ts +0 -9
  210. package/bin/types/agent/SessionActor.d.ts.map +1 -1
  211. package/bin/types/agent/SessionTypes.d.ts +5 -5
  212. package/bin/types/agent/SessionTypes.d.ts.map +1 -1
  213. package/bin/types/executor/SessionAssistantOutput.d.ts +15 -4
  214. package/bin/types/executor/SessionAssistantOutput.d.ts.map +1 -1
  215. package/bin/types/executor/SessionTurnContext.d.ts +17 -19
  216. package/bin/types/executor/SessionTurnContext.d.ts.map +1 -1
  217. package/bin/types/sdk/AgentSessionAction.d.ts +1 -1
  218. package/bin/types/sdk/AgentSessionAction.js +1 -1
  219. package/bin/types/sdk/AgentSessionPrompt.d.ts +14 -5
  220. package/bin/types/sdk/AgentSessionPrompt.d.ts.map +1 -1
  221. package/bin/types/sdk/AgentSessionPrompt.js +1 -1
  222. package/bin/types/sdk/AgentSessionPrompt.js.map +1 -1
  223. package/bin/types/session/AdaptivePartContextPolicy.d.ts +31 -0
  224. package/bin/types/session/AdaptivePartContextPolicy.d.ts.map +1 -0
  225. package/bin/types/session/AdaptivePartContextPolicy.js +7 -0
  226. package/bin/types/session/AdaptivePartContextPolicy.js.map +1 -0
  227. package/bin/types/session/{SessionAssistantMessageState.d.ts → SessionAgentMessageState.d.ts} +7 -7
  228. package/bin/types/session/SessionAgentMessageState.d.ts.map +1 -0
  229. package/bin/types/session/{SessionAssistantMessageState.js → SessionAgentMessageState.js} +1 -1
  230. package/bin/types/session/SessionAgentMessageState.js.map +1 -0
  231. package/bin/types/session/SessionCommand.d.ts +19 -7
  232. package/bin/types/session/SessionCommand.d.ts.map +1 -1
  233. package/bin/types/session/SessionComposer.d.ts +43 -43
  234. package/bin/types/session/SessionComposer.d.ts.map +1 -1
  235. package/bin/types/session/SessionComposer.js +2 -2
  236. package/bin/types/session/SessionComposition.d.ts +2 -5
  237. package/bin/types/session/SessionComposition.d.ts.map +1 -1
  238. package/bin/types/session/SessionContextPolicy.d.ts +70 -0
  239. package/bin/types/session/SessionContextPolicy.d.ts.map +1 -0
  240. package/bin/types/session/SessionContextPolicy.js +8 -0
  241. package/bin/types/session/SessionContextPolicy.js.map +1 -0
  242. package/bin/types/session/SessionExecution.d.ts +5 -32
  243. package/bin/types/session/SessionExecution.d.ts.map +1 -1
  244. package/bin/types/session/SessionLoop.d.ts +3 -5
  245. package/bin/types/session/SessionLoop.d.ts.map +1 -1
  246. package/bin/types/session/SessionMessages.d.ts +18 -28
  247. package/bin/types/session/SessionMessages.d.ts.map +1 -1
  248. package/bin/types/session/SessionOptions.d.ts +5 -5
  249. package/bin/types/session/SessionOptions.d.ts.map +1 -1
  250. package/bin/types/session/SessionPort.d.ts +8 -9
  251. package/bin/types/session/SessionPort.d.ts.map +1 -1
  252. package/bin/types/session/SessionState.d.ts +2 -5
  253. package/bin/types/session/SessionState.d.ts.map +1 -1
  254. package/bin/types/session/SessionSystem.d.ts +14 -0
  255. package/bin/types/session/SessionSystem.d.ts.map +1 -1
  256. package/bin/types/session/SessionTool.d.ts +2 -2
  257. package/bin/types/session/SessionTool.d.ts.map +1 -1
  258. package/bin/types/session/SessionTurnCompletion.d.ts +23 -0
  259. package/bin/types/session/SessionTurnCompletion.d.ts.map +1 -0
  260. package/bin/types/session/SessionTurnCompletion.js +8 -0
  261. package/bin/types/session/SessionTurnCompletion.js.map +1 -0
  262. package/bin/types/session/SessionTurnFileDiff.d.ts +42 -0
  263. package/bin/types/session/SessionTurnFileDiff.d.ts.map +1 -0
  264. package/bin/types/session/SessionTurnFileDiff.js +8 -0
  265. package/bin/types/session/SessionTurnFileDiff.js.map +1 -0
  266. package/bin/types/store/LocalStore.d.ts +6 -13
  267. package/bin/types/store/LocalStore.d.ts.map +1 -1
  268. package/bin/types/store/LocalStore.js +1 -1
  269. package/bin/types/store/SessionStorage.d.ts +103 -0
  270. package/bin/types/store/SessionStorage.d.ts.map +1 -0
  271. package/bin/types/store/SessionStorage.js +8 -0
  272. package/bin/types/store/SessionStorage.js.map +1 -0
  273. package/bin/types/store/SessionStore.d.ts +5 -3
  274. package/bin/types/store/SessionStore.d.ts.map +1 -1
  275. package/package.json +2 -2
  276. package/scripts/core-engine-context-compaction.test.mjs +96 -219
  277. package/scripts/core-engine-model-stream.test.mjs +2 -4
  278. package/scripts/executor-failure-result.test.mjs +14 -17
  279. package/scripts/session-agent-message-part-order.test.mjs +63 -0
  280. package/scripts/session-initialization.test.mjs +141 -0
  281. package/scripts/session-message-timeline.test.mjs +5 -6
  282. package/scripts/session-messages-error-part.test.mjs +175 -0
  283. package/scripts/session-messages-error.test.mjs +47 -6
  284. package/scripts/session-prompt-idempotency.test.mjs +91 -0
  285. package/scripts/session-queue.test.mjs +13 -12
  286. package/scripts/session-storage-sqlite.test.mjs +209 -0
  287. package/scripts/session-turn-context.test.mjs +21 -33
  288. package/src/agent/Agent.ts +48 -12
  289. package/src/agent/AgentInstructions.ts +2 -2
  290. package/src/agent/AgentMemoryStorage.ts +1 -0
  291. package/src/agent/AgentSessions.ts +31 -12
  292. package/src/executor/Executor.ts +47 -184
  293. package/src/executor/README.md +12 -13
  294. package/src/executor/composer/system/default/SystemPromptAssets.ts +0 -6
  295. package/src/executor/core-engine/CoreEngineContextCompaction.ts +3 -135
  296. package/src/executor/core-engine/CoreEngineRunner.ts +51 -273
  297. package/src/executor/core-engine/CoreEngineSignals.ts +9 -9
  298. package/src/executor/messages/SessionAttachmentMapper.ts +4 -4
  299. package/src/executor/messages/SessionMessageLog.ts +3 -3
  300. package/src/executor/messages/SessionModelMessages.ts +85 -103
  301. package/src/executor/model/ModelStepRunner.ts +9 -41
  302. package/src/executor/services/ExecutorRecoveryPolicy.ts +34 -127
  303. package/src/executor/types/SessionHistoryMeta.ts +1 -3
  304. package/src/index.ts +39 -47
  305. package/src/session/DefaultSessionComposer.ts +33 -30
  306. package/src/session/Session.ts +96 -227
  307. package/src/session/SessionComposition.ts +28 -65
  308. package/src/session/SessionLoop.ts +267 -370
  309. package/src/session/SessionMessages.ts +363 -242
  310. package/src/session/SessionQueue.ts +3 -2
  311. package/src/session/SessionState.ts +55 -101
  312. package/src/session/SessionSystem.ts +51 -1
  313. package/src/session/SessionTitle.ts +4 -4
  314. package/src/session/browse/Browse.ts +182 -468
  315. package/src/session/browse/SessionMessageTimeline.ts +63 -38
  316. package/src/session/composer/policies/AdaptivePartContextPolicy.ts +307 -0
  317. package/src/session/composer/policies/FullHistoryContextPolicy.ts +36 -0
  318. package/src/session/composer/policies/SessionSummaryPrompts.ts +42 -0
  319. package/src/session/execution/SessionAssistantOutputAdapter.ts +25 -11
  320. package/src/session/messages/{SessionActionMessageWriter.ts → SessionAgentActionPartWriter.ts} +8 -8
  321. package/src/session/messages/SessionAgentContent.ts +56 -0
  322. package/src/session/messages/SessionAgentMessageState.ts +378 -0
  323. package/src/session/messages/{SessionAssistantMessageWriter.ts → SessionAgentMessageWriter.ts} +89 -60
  324. package/src/session/messages/SessionForkMessageFiles.ts +25 -1
  325. package/src/session/messages/SessionMessageInteractionWriter.ts +19 -19
  326. package/src/session/messages/SessionMessageText.ts +3 -4
  327. package/src/session/messages/SessionTurnFileDiffData.ts +3 -3
  328. package/src/session/messages/SessionUserMessage.ts +10 -7
  329. package/src/session/preview/SessionMessagePreview.ts +26 -9
  330. package/src/session/runtime/SessionTurnCompletion.ts +159 -0
  331. package/src/session/runtime/SessionTurnContext.ts +20 -21
  332. package/src/session/runtime/SessionTurnFileDiff.ts +105 -0
  333. package/src/session/storage/LocalSessionDataStore.ts +27 -176
  334. package/src/session/storage/LocalSessionStore.ts +170 -38
  335. package/src/session/storage/LocalStorePaths.ts +14 -86
  336. package/src/session/storage/Metadata.ts +4 -13
  337. package/src/session/storage/RuntimeSessionPort.ts +7 -7
  338. package/src/session/storage/SessionStorageCodec.ts +465 -0
  339. package/src/session/storage/SessionStorageSchema.ts +132 -0
  340. package/src/session/storage/SqliteSessionStorage.ts +776 -0
  341. package/src/tools/ask/AskQuestionsTool.ts +3 -1
  342. package/src/types/action/ActionResult.ts +10 -10
  343. package/src/types/agent/AgentOptions.ts +11 -0
  344. package/src/types/agent/AgentStorage.ts +3 -1
  345. package/src/types/agent/SessionActor.ts +0 -10
  346. package/src/types/agent/SessionTypes.ts +5 -5
  347. package/src/types/executor/SessionAssistantOutput.ts +15 -4
  348. package/src/types/executor/SessionTurnContext.ts +25 -22
  349. package/src/types/sdk/AgentSessionAction.ts +1 -1
  350. package/src/types/sdk/AgentSessionPrompt.ts +15 -5
  351. package/src/types/session/AdaptivePartContextPolicy.ts +37 -0
  352. package/src/types/session/{SessionAssistantMessageState.ts → SessionAgentMessageState.ts} +6 -6
  353. package/src/types/session/SessionCommand.ts +21 -7
  354. package/src/types/session/SessionComposer.ts +48 -48
  355. package/src/types/session/SessionComposition.ts +2 -5
  356. package/src/types/session/SessionContextPolicy.ts +77 -0
  357. package/src/types/session/SessionExecution.ts +11 -36
  358. package/src/types/session/SessionLoop.ts +3 -8
  359. package/src/types/session/SessionMessages.ts +19 -29
  360. package/src/types/session/SessionOptions.ts +5 -5
  361. package/src/types/session/SessionPort.ts +10 -10
  362. package/src/types/session/SessionState.ts +2 -5
  363. package/src/types/session/SessionSystem.ts +19 -0
  364. package/src/types/session/SessionTool.ts +2 -2
  365. package/src/types/session/SessionTurnCompletion.ts +24 -0
  366. package/src/types/session/SessionTurnFileDiff.ts +44 -0
  367. package/src/types/store/LocalStore.ts +6 -14
  368. package/src/types/store/SessionStorage.ts +121 -0
  369. package/src/types/store/SessionStore.ts +6 -3
  370. package/tsconfig.tsbuildinfo +1 -1
  371. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.d.ts +0 -45
  372. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.d.ts.map +0 -1
  373. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.js +0 -144
  374. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.js.map +0 -1
  375. package/bin/executor/composer/system/SessionSystemComposer.d.ts +0 -23
  376. package/bin/executor/composer/system/SessionSystemComposer.d.ts.map +0 -1
  377. package/bin/executor/composer/system/SessionSystemComposer.js +0 -9
  378. package/bin/executor/composer/system/SessionSystemComposer.js.map +0 -1
  379. package/bin/executor/composer/system/default/DefaultSessionSystemComposer.d.ts +0 -43
  380. package/bin/executor/composer/system/default/DefaultSessionSystemComposer.d.ts.map +0 -1
  381. package/bin/executor/composer/system/default/DefaultSessionSystemComposer.js +0 -42
  382. package/bin/executor/composer/system/default/DefaultSessionSystemComposer.js.map +0 -1
  383. package/bin/executor/composer/system/default/PromptRenderer.d.ts +0 -35
  384. package/bin/executor/composer/system/default/PromptRenderer.d.ts.map +0 -1
  385. package/bin/executor/composer/system/default/PromptRenderer.js +0 -23
  386. package/bin/executor/composer/system/default/PromptRenderer.js.map +0 -1
  387. package/bin/executor/composer/system/default/SystemDomain.d.ts +0 -151
  388. package/bin/executor/composer/system/default/SystemDomain.d.ts.map +0 -1
  389. package/bin/executor/composer/system/default/SystemDomain.js +0 -162
  390. package/bin/executor/composer/system/default/SystemDomain.js.map +0 -1
  391. package/bin/executor/composer/system/default/assets/task.prompt.d.ts +0 -7
  392. package/bin/executor/composer/system/default/assets/task.prompt.d.ts.map +0 -1
  393. package/bin/executor/composer/system/default/assets/task.prompt.js +0 -8
  394. package/bin/executor/composer/system/default/assets/task.prompt.js.map +0 -1
  395. package/bin/executor/composer/system/default/variables/GeoContext.d.ts +0 -14
  396. package/bin/executor/composer/system/default/variables/GeoContext.d.ts.map +0 -1
  397. package/bin/executor/composer/system/default/variables/GeoContext.js +0 -150
  398. package/bin/executor/composer/system/default/variables/GeoContext.js.map +0 -1
  399. package/bin/executor/composer/system/default/variables/PromptTypes.d.ts +0 -36
  400. package/bin/executor/composer/system/default/variables/PromptTypes.d.ts.map +0 -1
  401. package/bin/executor/composer/system/default/variables/PromptTypes.js +0 -9
  402. package/bin/executor/composer/system/default/variables/PromptTypes.js.map +0 -1
  403. package/bin/executor/composer/system/default/variables/VariableReplacer.d.ts +0 -61
  404. package/bin/executor/composer/system/default/variables/VariableReplacer.d.ts.map +0 -1
  405. package/bin/executor/composer/system/default/variables/VariableReplacer.js +0 -93
  406. package/bin/executor/composer/system/default/variables/VariableReplacer.js.map +0 -1
  407. package/bin/executor/core-engine/CoreEngineMessageState.d.ts +0 -63
  408. package/bin/executor/core-engine/CoreEngineMessageState.d.ts.map +0 -1
  409. package/bin/executor/core-engine/CoreEngineMessageState.js +0 -81
  410. package/bin/executor/core-engine/CoreEngineMessageState.js.map +0 -1
  411. package/bin/session/SessionCommand.d.ts +0 -24
  412. package/bin/session/SessionCommand.d.ts.map +0 -1
  413. package/bin/session/SessionCommand.js +0 -35
  414. package/bin/session/SessionCommand.js.map +0 -1
  415. package/bin/session/messages/SessionActionMessageWriter.d.ts.map +0 -1
  416. package/bin/session/messages/SessionActionMessageWriter.js.map +0 -1
  417. package/bin/session/messages/SessionAssistantMessageState.d.ts +0 -49
  418. package/bin/session/messages/SessionAssistantMessageState.d.ts.map +0 -1
  419. package/bin/session/messages/SessionAssistantMessageState.js +0 -296
  420. package/bin/session/messages/SessionAssistantMessageState.js.map +0 -1
  421. package/bin/session/messages/SessionAssistantMessageWriter.d.ts.map +0 -1
  422. package/bin/session/messages/SessionAssistantMessageWriter.js.map +0 -1
  423. package/bin/session/messages/SessionMessageCompaction.d.ts +0 -29
  424. package/bin/session/messages/SessionMessageCompaction.d.ts.map +0 -1
  425. package/bin/session/messages/SessionMessageCompaction.js +0 -128
  426. package/bin/session/messages/SessionMessageCompaction.js.map +0 -1
  427. package/bin/session/runtime/SessionCompactOperation.d.ts +0 -29
  428. package/bin/session/runtime/SessionCompactOperation.d.ts.map +0 -1
  429. package/bin/session/runtime/SessionCompactOperation.js +0 -66
  430. package/bin/session/runtime/SessionCompactOperation.js.map +0 -1
  431. package/bin/session/runtime/SessionHistoryCompaction.d.ts +0 -22
  432. package/bin/session/runtime/SessionHistoryCompaction.d.ts.map +0 -1
  433. package/bin/session/runtime/SessionHistoryCompaction.js +0 -31
  434. package/bin/session/runtime/SessionHistoryCompaction.js.map +0 -1
  435. package/bin/session/storage/JsonlSessionMessageStore.d.ts +0 -77
  436. package/bin/session/storage/JsonlSessionMessageStore.d.ts.map +0 -1
  437. package/bin/session/storage/JsonlSessionMessageStore.js +0 -419
  438. package/bin/session/storage/JsonlSessionMessageStore.js.map +0 -1
  439. package/bin/session/storage/SessionMessageStoreFactory.d.ts +0 -12
  440. package/bin/session/storage/SessionMessageStoreFactory.d.ts.map +0 -1
  441. package/bin/session/storage/SessionMessageStoreFactory.js +0 -13
  442. package/bin/session/storage/SessionMessageStoreFactory.js.map +0 -1
  443. package/bin/types/common/Template.d.ts +0 -9
  444. package/bin/types/common/Template.d.ts.map +0 -1
  445. package/bin/types/common/Template.js +0 -9
  446. package/bin/types/common/Template.js.map +0 -1
  447. package/bin/types/sdk/AgentSessionCompact.d.ts +0 -30
  448. package/bin/types/sdk/AgentSessionCompact.d.ts.map +0 -1
  449. package/bin/types/sdk/AgentSessionCompact.js +0 -8
  450. package/bin/types/sdk/AgentSessionCompact.js.map +0 -1
  451. package/bin/types/session/SessionAssistantMessageState.d.ts.map +0 -1
  452. package/bin/types/session/SessionAssistantMessageState.js.map +0 -1
  453. package/bin/types/session/SessionSegment.d.ts +0 -57
  454. package/bin/types/session/SessionSegment.d.ts.map +0 -1
  455. package/bin/types/session/SessionSegment.js +0 -8
  456. package/bin/types/session/SessionSegment.js.map +0 -1
  457. package/bin/types/store/SessionDataStore.d.ts +0 -88
  458. package/bin/types/store/SessionDataStore.d.ts.map +0 -1
  459. package/bin/types/store/SessionDataStore.js +0 -9
  460. package/bin/types/store/SessionDataStore.js.map +0 -1
  461. package/bin/utils/Template.d.ts +0 -17
  462. package/bin/utils/Template.d.ts.map +0 -1
  463. package/bin/utils/Template.js +0 -24
  464. package/bin/utils/Template.js.map +0 -1
  465. package/scripts/session-compaction-prompts.test.mjs +0 -49
  466. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.ts +0 -162
  467. package/src/executor/composer/system/SessionSystemComposer.ts +0 -25
  468. package/src/executor/composer/system/default/DefaultSessionSystemComposer.ts +0 -76
  469. package/src/executor/composer/system/default/PromptRenderer.ts +0 -52
  470. package/src/executor/composer/system/default/SystemDomain.ts +0 -301
  471. package/src/executor/composer/system/default/assets/task.prompt.ts +0 -9
  472. package/src/executor/composer/system/default/assets/task.prompt.ts.txt +0 -33
  473. package/src/executor/composer/system/default/variables/GeoContext.ts +0 -180
  474. package/src/executor/composer/system/default/variables/PromptTypes.ts +0 -37
  475. package/src/executor/composer/system/default/variables/VariableReplacer.ts +0 -154
  476. package/src/executor/core-engine/CoreEngineMessageState.ts +0 -117
  477. package/src/session/SessionCommand.ts +0 -42
  478. package/src/session/messages/SessionAssistantMessageState.ts +0 -392
  479. package/src/session/messages/SessionMessageCompaction.ts +0 -160
  480. package/src/session/runtime/SessionCompactOperation.ts +0 -93
  481. package/src/session/runtime/SessionHistoryCompaction.ts +0 -45
  482. package/src/session/storage/JsonlSessionMessageStore.ts +0 -513
  483. package/src/session/storage/SessionMessageStoreFactory.ts +0 -18
  484. package/src/types/common/Template.ts +0 -9
  485. package/src/types/sdk/AgentSessionCompact.ts +0 -32
  486. package/src/types/session/SessionSegment.ts +0 -62
  487. package/src/types/store/SessionDataStore.ts +0 -113
  488. package/src/utils/Template.ts +0 -28
@@ -1,14 +1,11 @@
1
1
  /**
2
- * SDK Session 浏览辅助。
2
+ * Session 浏览投影。
3
3
  *
4
- * 关键点(中文)
5
- * - 统一负责 session 列表摘要、session 详情与 history 分页的投影逻辑。
6
- * - session title 允许为空;浏览层不会再从首条 user message 推导 fallback title。
7
- * - 面向 SDK / RemoteAgent / downcity gateway route 复用,避免在多个入口重复拼列表与分页语义。
8
- * - 这里不持有运行态状态;执行状态等动态信息通过调用参数显式注入。
4
+ * 本模块只从每个 Session 的 `session.db` 读取列表所需的轻量状态;Message 正文仍由
5
+ * SessionStorage 聚合读取。浏览逻辑不创建 schema,也不尝试迁移旧文件格式。
9
6
  */
10
7
 
11
- import path from "node:path";
8
+ import { DatabaseSync } from "node:sqlite";
12
9
  import type {
13
10
  AgentListSessionsInput,
14
11
  AgentSessionInfo,
@@ -18,53 +15,64 @@ import type {
18
15
  import type { SessionHistoryMeta } from "@/executor/types/SessionHistoryMeta.js";
19
16
  import { resolve_session_message_preview } from "@/session/preview/SessionMessagePreview.js";
20
17
  import {
21
- get_agent_archived_session_active_messages_path,
22
- get_agent_archived_session_meta_path,
18
+ get_agent_archived_session_database_path,
23
19
  get_agent_archived_sessions_path,
24
- get_agent_session_active_messages_path,
25
- get_agent_session_meta_path,
20
+ get_agent_session_database_path,
26
21
  get_agent_sessions_path,
27
22
  } from "@/session/storage/LocalStorePaths.js";
28
- import { read_session_metadata_from_path } from "@/session/storage/Metadata.js";
29
- import { normalize_session_origin_type } from "@downcity/type";
30
- import type { SessionMessage } from "@downcity/type";
31
- import type { FileSystem } from "@downcity/type";
23
+ import {
24
+ normalize_session_origin_type,
25
+ restore_session_origin,
26
+ type FileSystem,
27
+ type SessionMessage,
28
+ } from "@downcity/type";
29
+
30
+ /** SQLite 中列表投影所需的 session_state 行。 */
31
+ interface SessionBrowseStateRow {
32
+ /** Session 标识。 */
33
+ session_id: string;
34
+ /** Agent 标识。 */
35
+ agent_id: string;
36
+ /** 可选 Workspace 标识。 */
37
+ workspace_id: string | null;
38
+ /** JSON 编码的来源。 */
39
+ origin: string;
40
+ /** Session 时区。 */
41
+ timezone: string;
42
+ /** 可选标题。 */
43
+ title: string | null;
44
+ /** 可选模型标签。 */
45
+ model_label: string | null;
46
+ /** 可选审批模式。 */
47
+ approval_mode: "ask" | "always-allow" | null;
48
+ /** canonical Message 数量。 */
49
+ message_count: number;
50
+ /** 最新消息预览。 */
51
+ preview_text: string | null;
52
+ /** 创建时间。 */
53
+ created_at: number;
54
+ /** 更新时间。 */
55
+ updated_at: number;
56
+ }
32
57
 
33
- type SessionBrowseBaseInput = {
34
- /**
35
- * 当前项目根目录。
36
- */
58
+ /** Session 详情投影输入。 */
59
+ interface SessionBrowseBaseInput {
60
+ /** 当前项目或私有存储根目录。 */
37
61
  project_root: string;
38
-
39
- /**
40
- * 当前 agent_id。
41
- */
62
+ /** 当前 Agent 标识。 */
42
63
  agent_id: string;
43
-
44
- /**
45
- * 当前 session_id。
46
- */
64
+ /** 当前 Session 标识。 */
47
65
  session_id: string;
48
-
49
- /**
50
- * 当前 session 已读取到的 metadata。
51
- */
66
+ /** 已读取的 Session 状态。 */
52
67
  metadata: SessionHistoryMeta;
53
-
54
- /**
55
- * 当前 session 已读取到的完整消息。
56
- *
57
- * 说明(中文):列表查询已有 metadata 摘要时可省略,详情查询仍传完整记录。
58
- */
68
+ /** 可选完整 Message,用于即时生成详情预览。 */
59
69
  messages?: SessionMessage[];
60
-
61
- /**
62
- * 当前 session 是否正在执行。
63
- */
70
+ /** 当前 Session 是否正在执行。 */
64
71
  executing?: boolean;
65
- };
72
+ }
66
73
 
67
- function decodeMaybe(input: string): string {
74
+ /** 从目录名恢复 Session 标识。 */
75
+ function decode_session_id(input: string): string {
68
76
  try {
69
77
  return decodeURIComponent(input);
70
78
  } catch {
@@ -72,485 +80,191 @@ function decodeMaybe(input: string): string {
72
80
  }
73
81
  }
74
82
 
75
- function normalizeLimit(input: unknown, fallback: number, max: number): number {
76
- const value =
77
- typeof input === "number" && Number.isFinite(input)
78
- ? input
79
- : typeof input === "string" && input.trim()
80
- ? Number(input)
81
- : NaN;
82
- if (!Number.isFinite(value)) return fallback;
83
- return Math.max(1, Math.min(max, Math.floor(value)));
84
- }
85
-
86
- function truncateText(input: string, maxChars: number): string {
87
- const value = String(input || "").trim();
88
- if (!value) return "";
89
- if (value.length <= maxChars) return value;
90
- return `${value.slice(0, Math.max(0, maxChars - 1)).trimEnd()}…`;
91
- }
92
-
93
- function normalizeCursor(input: unknown): number {
94
- const raw = String(input || "").trim();
95
- if (!raw) return 0;
96
- const value = Number(raw);
97
- if (!Number.isFinite(value) || value < 0) return 0;
98
- return Math.floor(value);
99
- }
100
-
101
- function encodeCursor(offset: number): string | undefined {
102
- if (!Number.isFinite(offset) || offset <= 0) return undefined;
103
- return String(Math.floor(offset));
104
- }
105
-
106
- /**
107
- * 读取指定 JSONL 消息文件。
108
- */
109
- export async function load_session_messages_from_path(
110
- filePath: string,
111
- files: FileSystem,
112
- ): Promise<SessionMessage[]> {
113
- const messages_by_id = new Map<string, SessionMessage>();
114
- if (await files.path_exists(filePath)) {
115
- const raw = (await files.read_file(filePath)).toString("utf8");
116
- const lines = raw.split("\n").filter(Boolean);
117
- for (const line of lines) {
118
- try {
119
- const message = JSON.parse(line) as SessionMessage;
120
- if (!is_canonical_session_message(message)) continue;
121
- const previous = messages_by_id.get(message.message_id);
122
- if (!previous || message.revision > previous.revision) {
123
- messages_by_id.set(message.message_id, message);
124
- }
125
- } catch {
126
- // 关键点(中文):单行损坏不影响整个 session 的可读性。
127
- }
128
- }
129
- }
130
-
131
- const inflight_path = path.join(path.dirname(filePath), "assistant_message.json");
132
- if (await files.path_exists(inflight_path)) {
133
- try {
134
- const message = JSON.parse(
135
- (await files.read_file(inflight_path)).toString("utf8"),
136
- ) as SessionMessage;
137
- if (is_canonical_session_message(message) && message.type === "assistant") {
138
- messages_by_id.set(message.message_id, message);
139
- }
140
- } catch {
141
- // 运行中快照损坏时仍返回已经完成的历史。
142
- }
143
- }
144
-
145
- return [...messages_by_id.values()]
146
- .sort((left, right) => left.sequence - right.sequence);
147
- }
148
-
149
- function is_canonical_session_message(input: unknown): input is SessionMessage {
150
- if (!input || typeof input !== "object") return false;
151
- const candidate = input as Partial<SessionMessage>;
152
- return (
153
- typeof candidate.message_id === "string" &&
154
- typeof candidate.session_id === "string" &&
155
- typeof candidate.sequence === "number" &&
156
- typeof candidate.revision === "number" &&
157
- (candidate.type === "user" ||
158
- candidate.type === "assistant" ||
159
- candidate.type === "action" ||
160
- candidate.type === "error")
161
- );
83
+ /** 规范化分页上限。 */
84
+ function normalize_limit(input: unknown, fallback: number, max: number): number {
85
+ const value = typeof input === "number" && Number.isFinite(input)
86
+ ? input
87
+ : typeof input === "string" && input.trim()
88
+ ? Number(input)
89
+ : NaN;
90
+ return Number.isFinite(value)
91
+ ? Math.max(1, Math.min(max, Math.floor(value)))
92
+ : fallback;
162
93
  }
163
94
 
164
- function is_compact_summary_message(message: SessionMessage): boolean {
165
- return message.type === "assistant" && message.kind === "summary";
95
+ /** 规范化透明 offset cursor。 */
96
+ function normalize_cursor(input: unknown): number {
97
+ const value = Number(String(input || "").trim());
98
+ return Number.isFinite(value) && value >= 0 ? Math.floor(value) : 0;
166
99
  }
167
100
 
168
- function filter_user_visible_history_messages(
169
- messages: SessionMessage[],
170
- ): SessionMessage[] {
171
- return messages.filter((message) =>
172
- message.visibility === "visible" && !is_compact_summary_message(message)
173
- );
101
+ /** 裁剪用户可见预览。 */
102
+ function truncate_text(input: string, max_chars: number): string {
103
+ const value = String(input || "").trim();
104
+ if (value.length <= max_chars) return value;
105
+ return `${value.slice(0, Math.max(0, max_chars - 1)).trimEnd()}…`;
174
106
  }
175
107
 
176
- /**
177
- * 基于 metadata + messages 构建 SDK session 详情。
178
- */
179
- export function build_session_info(
180
- input: SessionBrowseBaseInput,
181
- ): AgentSessionInfo {
182
- const messages = input.messages;
183
- const preview_text = messages && messages.length > 0
184
- ? truncateText(
185
- resolve_session_message_preview(messages[messages.length - 1]),
186
- 180,
187
- )
108
+ /** 基于 metadata 与可选 Message 构建 SDK Session 详情。 */
109
+ export function build_session_info(input: SessionBrowseBaseInput): AgentSessionInfo {
110
+ const latest_message = input.messages?.at(-1);
111
+ const preview_text = latest_message
112
+ ? truncate_text(resolve_session_message_preview(latest_message), 180)
188
113
  : input.metadata.preview_text;
189
- const message_count = typeof input.metadata.message_count === "number"
190
- ? input.metadata.message_count
191
- : messages
192
- ? filter_user_visible_history_messages(messages).length
193
- : 0;
194
- const title =
195
- typeof input.metadata.title === "string" && input.metadata.title.trim()
196
- ? input.metadata.title.trim()
197
- : undefined;
198
114
  return {
199
115
  agent_id: input.agent_id,
200
116
  session_id: input.session_id,
201
- ...(title ? { title } : {}),
117
+ ...(input.metadata.title?.trim() ? { title: input.metadata.title.trim() } : {}),
202
118
  ...(preview_text ? { preview_text } : {}),
203
- message_count: message_count,
119
+ message_count: input.metadata.message_count ?? input.messages?.length ?? 0,
204
120
  ...(typeof input.metadata.created_at === "number"
205
121
  ? { created_at: input.metadata.created_at }
206
122
  : {}),
207
123
  ...(typeof input.metadata.updated_at === "number"
208
124
  ? { updated_at: input.metadata.updated_at }
209
125
  : {}),
210
- ...(input.metadata.model_label
211
- ? { model_label: input.metadata.model_label }
212
- : {}),
126
+ ...(input.metadata.model_label ? { model_label: input.metadata.model_label } : {}),
213
127
  origin: input.metadata.origin,
214
- ...(typeof input.metadata.timezone === "string" && input.metadata.timezone.trim()
215
- ? { timezone: input.metadata.timezone.trim() }
216
- : {}),
128
+ ...(input.metadata.workspace_id ? { workspace_id: input.metadata.workspace_id } : {}),
129
+ ...(input.metadata.timezone ? { timezone: input.metadata.timezone } : {}),
217
130
  ...(input.executing ? { executing: true } : {}),
218
131
  };
219
132
  }
220
133
 
221
- /**
222
- * 读取列表所需的轻量 session 摘要。
223
- *
224
- * 关键点(中文)
225
- * - 新记录直接使用 metadata 摘要,不扫描 active.jsonl。
226
- * - 旧记录或执行中记录回退读取一次完整历史,并把摘要补写回 metadata。
227
- */
228
- async function resolve_session_summary_metadata(input: {
229
- /** 当前 session metadata。 */
230
- metadata: SessionHistoryMeta;
231
- /** 当前消息 JSONL 路径。 */
232
- messagesPath: string;
233
- /** 当前 metadata 路径。 */
234
- metaPath: string;
235
- /** 是否强制刷新摘要。 */
236
- refresh: boolean;
237
- /** 当前 Workspace 的统一文件能力。 */
238
- files: FileSystem;
239
- }): Promise<SessionHistoryMeta> {
240
- const storage_stats = await resolve_session_disk_stats(
241
- input.messagesPath,
242
- input.files,
243
- );
244
- const history_bytes = storage_stats.history_bytes;
245
- const inflight_path = path.join(path.dirname(input.messagesPath), "assistant_message.json");
246
- const has_inflight = await input.files.path_exists(inflight_path);
247
- if (
248
- !input.refresh &&
249
- !has_inflight &&
250
- typeof input.metadata.message_count === "number" &&
251
- input.metadata.historyBytes === history_bytes
252
- ) {
253
- return input.metadata;
254
- }
255
- const messages = await load_session_messages_from_path(
256
- input.messagesPath,
257
- input.files,
258
- );
259
- const last_message = messages[messages.length - 1];
260
- const preview_text = last_message
261
- ? truncateText(resolve_session_message_preview(last_message), 180)
262
- : "";
263
- const { preview_text: _previous_preview, ...metadata_without_preview } = input.metadata;
264
- void _previous_preview;
265
- const next_metadata: SessionHistoryMeta = {
266
- ...metadata_without_preview,
267
- message_count: storage_stats.message_count,
268
- historyBytes: history_bytes,
269
- ...(preview_text || input.metadata.preview_text
270
- ? { preview_text: preview_text || input.metadata.preview_text }
271
- : {}),
272
- };
273
- await input.files.write_file_atomically(
274
- input.metaPath,
275
- `${JSON.stringify(next_metadata, null, 2)}\n`,
276
- );
277
- return next_metadata;
278
- }
279
-
280
- /**
281
- * 只读取 Active 和 Segment 文件索引,计算列表所需的持久化统计。
282
- *
283
- * 关键点(中文)
284
- * - Segment 的结束 sequence 直接来自文件名,不解析历史正文。
285
- * - Active 需要逐行读取,以同时覆盖 revision 行与运行中 Assistant sequence。
286
- */
287
- async function resolve_session_disk_stats(
288
- messages_path: string,
289
- files: FileSystem,
290
- ) {
291
- const messages_dir_path = path.dirname(messages_path);
292
- const segments_dir_path = path.join(messages_dir_path, "segments");
293
- const segment_entries = await files.read_directory(segments_dir_path)
294
- .catch(() => []);
295
- const segment_files = segment_entries.flatMap((entry) => {
296
- if (!entry.is_file) return [];
297
- const match = /^(\d+)-(\d+)\.jsonl$/.exec(entry.name);
298
- if (!match) return [];
299
- return [{
300
- file_path: path.join(segments_dir_path, entry.name),
301
- end_sequence: Number(match[2]),
302
- }];
303
- });
304
- const active_raw = await files.read_file(messages_path)
305
- .then((value) => value.toString("utf8"))
306
- .catch(() => "");
307
- let latest_active_sequence = 0;
308
- for (const line of active_raw.split("\n")) {
309
- if (!line.trim()) continue;
310
- try {
311
- const message = JSON.parse(line) as Partial<SessionMessage>;
312
- if (Number.isInteger(message.sequence)) {
313
- latest_active_sequence = Math.max(latest_active_sequence, Number(message.sequence));
314
- }
315
- } catch {
316
- // 单行损坏不阻断 Session 列表,其正文读取时会按既有规则忽略。
317
- }
318
- }
319
- const inflight_path = path.join(messages_dir_path, "assistant_message.json");
134
+ /** 只读打开一个现有数据库并读取 Session 状态;失败时不改写磁盘。 */
135
+ export function read_session_metadata_from_database(
136
+ database_path: string,
137
+ fallback_origin_type: string,
138
+ ): SessionHistoryMeta | null {
139
+ let database: DatabaseSync | null = null;
320
140
  try {
321
- const inflight = JSON.parse(
322
- (await files.read_file(inflight_path)).toString("utf8"),
323
- ) as Partial<SessionMessage>;
324
- if (Number.isInteger(inflight.sequence)) {
325
- latest_active_sequence = Math.max(latest_active_sequence, Number(inflight.sequence));
326
- }
141
+ database = new DatabaseSync(database_path, { readOnly: true });
142
+ const row = database.prepare(`
143
+ SELECT session_id, agent_id, workspace_id, origin, timezone, title,
144
+ model_label, approval_mode, message_count, preview_text,
145
+ created_at, updated_at
146
+ FROM session_state WHERE singleton_id = 1
147
+ `).get() as unknown as SessionBrowseStateRow | undefined;
148
+ if (!row) return null;
149
+ return {
150
+ v: 2,
151
+ session_id: row.session_id,
152
+ agent_id: row.agent_id,
153
+ ...(row.workspace_id ? { workspace_id: row.workspace_id } : {}),
154
+ origin: restore_session_origin(JSON.parse(row.origin), fallback_origin_type),
155
+ timezone: row.timezone,
156
+ ...(row.title ? { title: row.title } : {}),
157
+ ...(row.model_label ? { model_label: row.model_label } : {}),
158
+ ...(row.approval_mode ? { approval_mode: row.approval_mode } : {}),
159
+ message_count: row.message_count,
160
+ ...(row.preview_text ? { preview_text: row.preview_text } : {}),
161
+ created_at: row.created_at,
162
+ updated_at: row.updated_at,
163
+ };
327
164
  } catch {
328
- // 草稿不存在或损坏时只统计已完成历史。
165
+ return null;
166
+ } finally {
167
+ database?.close();
329
168
  }
330
- const segment_sizes = await Promise.all(
331
- segment_files.map(({ file_path }) => files.file_size(file_path)
332
- .catch(() => 0)),
333
- );
334
- const latest_segment_sequence = segment_files.reduce(
335
- (latest, segment) => Math.max(latest, segment.end_sequence),
336
- 0,
337
- );
338
- return {
339
- history_bytes: Buffer.byteLength(active_raw, "utf8") +
340
- segment_sizes.reduce((total, size) => total + size, 0),
341
- message_count: Math.max(latest_segment_sequence, latest_active_sequence),
342
- };
343
169
  }
344
170
 
345
- /**
346
- * 列出指定 agent 的 session 摘要页。
347
- */
348
- export async function list_agent_session_summary_page(params: {
171
+ /** 列出活动 Session 摘要页。 */
172
+ export async function list_agent_session_summary_page(input: {
173
+ /** Agent 私有存储根目录。 */
349
174
  project_root: string;
175
+ /** 当前 Agent 标识。 */
350
176
  agent_id: string;
177
+ /** 可选 Workspace 过滤。 */
351
178
  workspace_id?: string;
179
+ /** 列表查询。 */
352
180
  input?: AgentListSessionsInput;
353
- executingSessionIds?: Set<string>;
181
+ /** 当前执行中的 Session。 */
182
+ executing_session_ids?: ReadonlySet<string>;
183
+ /** Agent 私有文件能力。 */
354
184
  files: FileSystem;
355
185
  }): Promise<AgentSessionSummaryPage> {
356
- const limit = normalizeLimit(params.input?.limit, 50, 500);
357
- const cursor = normalizeCursor(params.input?.cursor);
358
- const query = String(params.input?.query || "").trim().toLowerCase();
359
- const origin_type = normalize_session_origin_type(params.input?.origin_type ?? "chat");
360
- const sessionsRoot = get_agent_sessions_path(params.project_root, origin_type);
361
-
362
- if (!(await params.files.path_exists(sessionsRoot))) {
363
- return {
364
- items: [],
365
- total: 0,
366
- has_more: false,
367
- };
368
- }
369
-
370
- const entries = await params.files.read_directory(sessionsRoot);
371
- const summaries: AgentSessionSummary[] = [];
372
-
373
- for (const entry of entries) {
374
- if (!entry.is_directory) continue;
375
- const session_id = decodeMaybe(entry.name);
376
- if (!session_id) continue;
377
- const meta_path = get_agent_session_meta_path(
378
- params.project_root,
379
- origin_type,
380
- session_id,
381
- );
382
- const messages_path = get_agent_session_active_messages_path(
383
- params.project_root,
384
- origin_type,
385
- session_id,
386
- );
387
- const persisted_metadata = await read_session_metadata_from_path({
388
- filePath: meta_path,
389
- session_id,
390
- agent_id: params.agent_id,
391
- workspace_id: params.workspace_id,
392
- origin_type,
393
- files: params.files,
394
- }).catch(() => null);
395
- if (!persisted_metadata) continue;
396
- const metadata = await resolve_session_summary_metadata({
397
- metadata: persisted_metadata,
398
- messagesPath: messages_path,
399
- metaPath: meta_path,
400
- refresh: params.executingSessionIds?.has(session_id) === true,
401
- files: params.files,
402
- });
403
- const info = build_session_info({
404
- project_root: params.project_root,
405
- agent_id: params.agent_id,
406
- session_id,
407
- metadata,
408
- executing: params.executingSessionIds?.has(session_id),
409
- });
410
- const summary: AgentSessionSummary = {
411
- agent_id: info.agent_id,
412
- session_id: info.session_id,
413
- ...(info.title ? { title: info.title } : {}),
414
- ...(info.preview_text ? { preview_text: info.preview_text } : {}),
415
- message_count: info.message_count,
416
- ...(typeof info.created_at === "number" ? { created_at: info.created_at } : {}),
417
- ...(typeof info.updated_at === "number" ? { updated_at: info.updated_at } : {}),
418
- ...(info.model_label ? { model_label: info.model_label } : {}),
419
- origin: info.origin,
420
- ...(persisted_metadata.workspace_id ? { workspace_id: persisted_metadata.workspace_id } : {}),
421
- ...(info.executing ? { executing: true } : {}),
422
- };
423
-
424
- if (query) {
425
- const haystack = [
426
- summary.session_id,
427
- summary.title || "",
428
- summary.preview_text || "",
429
- ]
430
- .join("\n")
431
- .toLowerCase();
432
- if (!haystack.includes(query)) continue;
433
- }
434
-
435
- summaries.push(summary);
436
- }
437
-
438
- summaries.sort((left, right) => (right.updated_at || 0) - (left.updated_at || 0));
439
-
440
- const items = summaries.slice(cursor, cursor + limit);
441
- const nextOffset = cursor + items.length;
442
- return {
443
- items,
444
- total: summaries.length,
445
- ...(nextOffset < summaries.length
446
- ? { next_cursor: encodeCursor(nextOffset) }
447
- : {}),
448
- has_more: nextOffset < summaries.length,
449
- };
186
+ return await list_session_summary_page({ ...input, archived: false });
450
187
  }
451
188
 
452
- /**
453
- * 列出指定 agent 的已归档 session 摘要页。
454
- */
455
- export async function list_archived_agent_session_summary_page(params: {
189
+ /** 列出归档 Session 摘要页。 */
190
+ export async function list_archived_agent_session_summary_page(input: {
191
+ /** Agent 私有存储根目录。 */
456
192
  project_root: string;
193
+ /** 当前 Agent 标识。 */
457
194
  agent_id: string;
195
+ /** 可选 Workspace 过滤。 */
458
196
  workspace_id?: string;
197
+ /** 列表查询。 */
459
198
  input?: AgentListSessionsInput;
199
+ /** Agent 私有文件能力。 */
460
200
  files: FileSystem;
461
201
  }): Promise<AgentSessionSummaryPage> {
462
- const limit = normalizeLimit(params.input?.limit, 50, 500);
463
- const cursor = normalizeCursor(params.input?.cursor);
464
- const query = String(params.input?.query || "").trim().toLowerCase();
465
- const origin_type = normalize_session_origin_type(params.input?.origin_type ?? "chat");
466
- const archivedRoot = get_agent_archived_sessions_path(params.project_root, origin_type);
202
+ return await list_session_summary_page({ ...input, archived: true });
203
+ }
467
204
 
468
- if (!(await params.files.path_exists(archivedRoot))) {
469
- return {
470
- items: [],
471
- total: 0,
472
- has_more: false,
473
- };
205
+ /** 扫描单个来源分区中的 Session 数据库并建立轻量列表。 */
206
+ async function list_session_summary_page(input: {
207
+ /** Agent 私有存储根目录。 */
208
+ project_root: string;
209
+ /** 当前 Agent 标识。 */
210
+ agent_id: string;
211
+ /** 可选 Workspace 过滤。 */
212
+ workspace_id?: string;
213
+ /** 列表查询。 */
214
+ input?: AgentListSessionsInput;
215
+ /** 当前执行中的 Session。 */
216
+ executing_session_ids?: ReadonlySet<string>;
217
+ /** Agent 私有文件能力。 */
218
+ files: FileSystem;
219
+ /** 是否扫描归档目录。 */
220
+ archived: boolean;
221
+ }): Promise<AgentSessionSummaryPage> {
222
+ const origin_type = normalize_session_origin_type(input.input?.origin_type ?? "chat");
223
+ const sessions_path = input.archived
224
+ ? get_agent_archived_sessions_path(input.project_root, origin_type)
225
+ : get_agent_sessions_path(input.project_root, origin_type);
226
+ if (!(await input.files.path_exists(sessions_path))) {
227
+ return { items: [], total: 0, has_more: false };
474
228
  }
475
-
476
- const entries = await params.files.read_directory(archivedRoot);
229
+ const query = String(input.input?.query || "").trim().toLowerCase();
477
230
  const summaries: AgentSessionSummary[] = [];
478
-
479
- for (const entry of entries) {
231
+ for (const entry of await input.files.read_directory(sessions_path)) {
480
232
  if (!entry.is_directory) continue;
481
- const session_id = decodeMaybe(entry.name);
482
- if (!session_id) continue;
483
- const meta_path = get_agent_archived_session_meta_path(
484
- params.project_root,
485
- origin_type,
486
- session_id,
487
- );
488
- const messages_path = get_agent_archived_session_active_messages_path(
489
- params.project_root,
490
- origin_type,
491
- session_id,
492
- );
493
- const persisted_metadata = await read_session_metadata_from_path({
494
- filePath: meta_path,
495
- session_id,
496
- agent_id: params.agent_id,
497
- workspace_id: params.workspace_id,
498
- origin_type,
499
- files: params.files,
500
- }).catch(() => null);
501
- if (!persisted_metadata) continue;
502
- const metadata = await resolve_session_summary_metadata({
503
- metadata: persisted_metadata,
504
- messagesPath: messages_path,
505
- metaPath: meta_path,
506
- refresh: false,
507
- files: params.files,
508
- });
509
- // 关键点(中文):归档 session 不再生成新 title,仅读取归档目录内已有 meta。
510
- const info = build_session_info({
511
- project_root: params.project_root,
512
- agent_id: params.agent_id,
233
+ const session_id = decode_session_id(entry.name);
234
+ const database_path = input.archived
235
+ ? get_agent_archived_session_database_path(input.project_root, origin_type, session_id)
236
+ : get_agent_session_database_path(input.project_root, origin_type, session_id);
237
+ if (!(await input.files.path_exists(database_path))) continue;
238
+ const metadata = read_session_metadata_from_database(database_path, origin_type);
239
+ if (
240
+ !metadata ||
241
+ metadata.agent_id !== input.agent_id ||
242
+ metadata.origin.type !== origin_type ||
243
+ (input.workspace_id && metadata.workspace_id !== input.workspace_id)
244
+ ) continue;
245
+ const summary = build_session_info({
246
+ project_root: input.project_root,
247
+ agent_id: input.agent_id,
513
248
  session_id,
514
249
  metadata,
515
- executing: false,
250
+ executing: !input.archived && input.executing_session_ids?.has(session_id) === true,
516
251
  });
517
- const summary: AgentSessionSummary = {
518
- agent_id: info.agent_id,
519
- session_id: info.session_id,
520
- ...(info.title ? { title: info.title } : {}),
521
- ...(info.preview_text ? { preview_text: info.preview_text } : {}),
522
- message_count: info.message_count,
523
- ...(typeof info.created_at === "number" ? { created_at: info.created_at } : {}),
524
- ...(typeof info.updated_at === "number" ? { updated_at: info.updated_at } : {}),
525
- ...(info.model_label ? { model_label: info.model_label } : {}),
526
- origin: info.origin,
527
- ...(persisted_metadata.workspace_id ? { workspace_id: persisted_metadata.workspace_id } : {}),
528
- };
529
-
530
- if (query) {
531
- const haystack = [
532
- summary.session_id,
533
- summary.title || "",
534
- summary.preview_text || "",
535
- ]
536
- .join("\n")
537
- .toLowerCase();
538
- if (!haystack.includes(query)) continue;
539
- }
540
-
252
+ if (query && ![
253
+ summary.session_id,
254
+ summary.title || "",
255
+ summary.preview_text || "",
256
+ ].join("\n").toLowerCase().includes(query)) continue;
541
257
  summaries.push(summary);
542
258
  }
543
-
544
259
  summaries.sort((left, right) => (right.updated_at || 0) - (left.updated_at || 0));
545
-
260
+ const cursor = normalize_cursor(input.input?.cursor);
261
+ const limit = normalize_limit(input.input?.limit, 50, 500);
546
262
  const items = summaries.slice(cursor, cursor + limit);
547
- const nextOffset = cursor + items.length;
263
+ const next_cursor = cursor + items.length;
548
264
  return {
549
265
  items,
550
266
  total: summaries.length,
551
- ...(nextOffset < summaries.length
552
- ? { next_cursor: encodeCursor(nextOffset) }
553
- : {}),
554
- has_more: nextOffset < summaries.length,
267
+ ...(next_cursor < summaries.length ? { next_cursor: String(next_cursor) } : {}),
268
+ has_more: next_cursor < summaries.length,
555
269
  };
556
270
  }