@downcity/agent 1.1.237 → 1.1.258

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 (578) hide show
  1. package/README.md +21 -20
  2. package/bin/agent/{local/Agent.d.ts → Agent.d.ts} +37 -27
  3. package/bin/agent/Agent.d.ts.map +1 -0
  4. package/bin/agent/Agent.js +211 -0
  5. package/bin/agent/Agent.js.map +1 -0
  6. package/bin/agent/AgentContext.d.ts +64 -0
  7. package/bin/agent/AgentContext.d.ts.map +1 -0
  8. package/bin/agent/AgentContext.js +53 -0
  9. package/bin/agent/AgentContext.js.map +1 -0
  10. package/bin/agent/{local/AgentInstructions.d.ts → AgentInstructions.d.ts} +1 -6
  11. package/bin/agent/AgentInstructions.d.ts.map +1 -0
  12. package/bin/agent/{local/AgentInstructions.js → AgentInstructions.js} +1 -10
  13. package/bin/agent/AgentInstructions.js.map +1 -0
  14. package/bin/{model/CityModelAdapter.d.ts → agent/AgentModel.d.ts} +3 -3
  15. package/bin/agent/AgentModel.d.ts.map +1 -0
  16. package/bin/{model/CityModelAdapter.js → agent/AgentModel.js} +11 -4
  17. package/bin/agent/AgentModel.js.map +1 -0
  18. package/bin/agent/{local/services/AgentSessions.d.ts → AgentSessions.d.ts} +30 -40
  19. package/bin/agent/AgentSessions.d.ts.map +1 -0
  20. package/bin/agent/{local/services/AgentSessions.js → AgentSessions.js} +62 -79
  21. package/bin/agent/AgentSessions.js.map +1 -0
  22. package/bin/agent/AgentState.d.ts +64 -0
  23. package/bin/agent/AgentState.d.ts.map +1 -0
  24. package/bin/agent/AgentState.js +118 -0
  25. package/bin/agent/AgentState.js.map +1 -0
  26. package/bin/config/Paths.d.ts +0 -43
  27. package/bin/config/Paths.d.ts.map +1 -1
  28. package/bin/config/Paths.js +0 -79
  29. package/bin/config/Paths.js.map +1 -1
  30. package/bin/config/ProjectSetup.d.ts.map +1 -0
  31. package/bin/{agent/local → config}/ProjectSetup.js +1 -1
  32. package/bin/config/ProjectSetup.js.map +1 -0
  33. package/bin/executor/Executor.d.ts +20 -86
  34. package/bin/executor/Executor.d.ts.map +1 -1
  35. package/bin/executor/Executor.js +109 -260
  36. package/bin/executor/Executor.js.map +1 -1
  37. package/bin/executor/composer/system/default/DefaultSessionSystemComposer.d.ts +1 -1
  38. package/bin/executor/composer/system/default/DefaultSessionSystemComposer.d.ts.map +1 -1
  39. package/bin/executor/composer/system/default/SystemDomain.d.ts +1 -1
  40. package/bin/executor/composer/system/default/SystemDomain.d.ts.map +1 -1
  41. package/bin/executor/composer/system/default/SystemDomain.js +4 -1
  42. package/bin/executor/composer/system/default/SystemDomain.js.map +1 -1
  43. package/bin/executor/composer/system/default/assets/core.prompt.d.ts +1 -1
  44. package/bin/executor/composer/system/default/assets/core.prompt.d.ts.map +1 -1
  45. package/bin/executor/composer/system/default/assets/core.prompt.js +1 -1
  46. package/bin/executor/composer/system/default/assets/core.prompt.js.map +1 -1
  47. package/bin/executor/core-engine/CoreEngineRunner.d.ts +7 -13
  48. package/bin/executor/core-engine/CoreEngineRunner.d.ts.map +1 -1
  49. package/bin/executor/core-engine/CoreEngineRunner.js +81 -34
  50. package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
  51. package/bin/executor/services/ExecutorRecoveryPolicy.d.ts +6 -12
  52. package/bin/executor/services/ExecutorRecoveryPolicy.d.ts.map +1 -1
  53. package/bin/executor/services/ExecutorRecoveryPolicy.js +20 -6
  54. package/bin/executor/services/ExecutorRecoveryPolicy.js.map +1 -1
  55. package/bin/executor/tools/file/ReadImageToolBridge.d.ts +21 -0
  56. package/bin/executor/tools/file/ReadImageToolBridge.d.ts.map +1 -0
  57. package/bin/executor/tools/file/ReadImageToolBridge.js +69 -0
  58. package/bin/executor/tools/file/ReadImageToolBridge.js.map +1 -0
  59. package/bin/executor/tools/plugin/PluginToolBridge.d.ts.map +1 -1
  60. package/bin/executor/tools/plugin/PluginToolBridge.js +6 -5
  61. package/bin/executor/tools/plugin/PluginToolBridge.js.map +1 -1
  62. package/bin/executor/tools/plugin/PluginToolDefinition.d.ts.map +1 -1
  63. package/bin/executor/tools/plugin/PluginToolDefinition.js +15 -2
  64. package/bin/executor/tools/plugin/PluginToolDefinition.js.map +1 -1
  65. package/bin/executor/types/SessionHistoryMeta.d.ts +0 -2
  66. package/bin/executor/types/SessionHistoryMeta.d.ts.map +1 -1
  67. package/bin/index.d.ts +17 -21
  68. package/bin/index.d.ts.map +1 -1
  69. package/bin/index.js +9 -11
  70. package/bin/index.js.map +1 -1
  71. package/bin/plugin/core/ActionScheduleExecutor.d.ts +1 -1
  72. package/bin/plugin/core/ActionScheduleExecutor.d.ts.map +1 -1
  73. package/bin/plugin/core/ActionScheduleRuntime.d.ts +1 -1
  74. package/bin/plugin/core/ActionScheduleRuntime.d.ts.map +1 -1
  75. package/bin/plugin/core/BasePlugin.d.ts +4 -3
  76. package/bin/plugin/core/BasePlugin.d.ts.map +1 -1
  77. package/bin/plugin/core/BasePlugin.js.map +1 -1
  78. package/bin/plugin/core/HookRegistry.d.ts +5 -8
  79. package/bin/plugin/core/HookRegistry.d.ts.map +1 -1
  80. package/bin/plugin/core/HookRegistry.js +12 -12
  81. package/bin/plugin/core/HookRegistry.js.map +1 -1
  82. package/bin/plugin/core/PluginActionFactory.d.ts +6 -3
  83. package/bin/plugin/core/PluginActionFactory.d.ts.map +1 -1
  84. package/bin/plugin/core/PluginActionFactory.js.map +1 -1
  85. package/bin/plugin/core/PluginActionRunner.d.ts +1 -1
  86. package/bin/plugin/core/PluginActionRunner.d.ts.map +1 -1
  87. package/bin/plugin/core/PluginCatalog.d.ts +1 -1
  88. package/bin/plugin/core/PluginCatalog.d.ts.map +1 -1
  89. package/bin/plugin/core/PluginHttpRoutes.d.ts +1 -1
  90. package/bin/plugin/core/PluginHttpRoutes.d.ts.map +1 -1
  91. package/bin/plugin/core/PluginLocalExecution.d.ts +4 -5
  92. package/bin/plugin/core/PluginLocalExecution.d.ts.map +1 -1
  93. package/bin/plugin/core/PluginLocalExecution.js +4 -12
  94. package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
  95. package/bin/plugin/core/PluginRegistry.d.ts +16 -12
  96. package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
  97. package/bin/plugin/core/PluginRegistry.js +43 -22
  98. package/bin/plugin/core/PluginRegistry.js.map +1 -1
  99. package/bin/plugin/core/PluginStateController.d.ts +1 -1
  100. package/bin/plugin/core/PluginStateController.d.ts.map +1 -1
  101. package/bin/{agent/remote → remote}/RemoteAgent.d.ts +4 -4
  102. package/bin/remote/RemoteAgent.d.ts.map +1 -0
  103. package/bin/{agent/remote → remote}/RemoteAgent.js +3 -3
  104. package/bin/remote/RemoteAgent.js.map +1 -0
  105. package/bin/{agent/remote → remote}/RemoteSession.d.ts +9 -11
  106. package/bin/remote/RemoteSession.d.ts.map +1 -0
  107. package/bin/{agent/remote → remote}/RemoteSession.js +3 -33
  108. package/bin/remote/RemoteSession.js.map +1 -0
  109. package/bin/{agent/remote → remote}/RemoteTransport.d.ts +7 -9
  110. package/bin/remote/RemoteTransport.d.ts.map +1 -0
  111. package/bin/remote/RemoteTransport.js.map +1 -0
  112. package/bin/{agent/remote → remote}/TransportFactory.d.ts +1 -1
  113. package/bin/remote/TransportFactory.d.ts.map +1 -0
  114. package/bin/{agent/remote → remote}/TransportFactory.js +2 -2
  115. package/bin/remote/TransportFactory.js.map +1 -0
  116. package/bin/{agent/remote → remote}/transports/HttpRemoteAgentTransport.d.ts +8 -9
  117. package/bin/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -0
  118. package/bin/{agent/remote → remote}/transports/HttpRemoteAgentTransport.js +0 -13
  119. package/bin/remote/transports/HttpRemoteAgentTransport.js.map +1 -0
  120. package/bin/{rpc/Client.d.ts → remote/transports/RpcClient.d.ts} +15 -22
  121. package/bin/remote/transports/RpcClient.d.ts.map +1 -0
  122. package/bin/{rpc/Client.js → remote/transports/RpcClient.js} +2 -13
  123. package/bin/remote/transports/RpcClient.js.map +1 -0
  124. package/bin/{agent/remote → remote}/transports/RpcRemoteAgentTransport.d.ts +8 -9
  125. package/bin/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -0
  126. package/bin/{agent/remote → remote}/transports/RpcRemoteAgentTransport.js +1 -4
  127. package/bin/remote/transports/RpcRemoteAgentTransport.js.map +1 -0
  128. package/bin/session/DefaultSessionComposer.d.ts +18 -0
  129. package/bin/session/DefaultSessionComposer.d.ts.map +1 -0
  130. package/bin/session/DefaultSessionComposer.js +62 -0
  131. package/bin/session/DefaultSessionComposer.js.map +1 -0
  132. package/bin/session/Session.d.ts +44 -33
  133. package/bin/session/Session.d.ts.map +1 -1
  134. package/bin/session/Session.js +440 -274
  135. package/bin/session/Session.js.map +1 -1
  136. package/bin/session/SessionMessages.d.ts +117 -0
  137. package/bin/session/SessionMessages.d.ts.map +1 -0
  138. package/bin/session/{recorder/SessionRecorder.js → SessionMessages.js} +194 -284
  139. package/bin/session/SessionMessages.js.map +1 -0
  140. package/bin/session/SessionQueue.d.ts +34 -0
  141. package/bin/session/SessionQueue.d.ts.map +1 -0
  142. package/bin/session/SessionQueue.js +60 -0
  143. package/bin/session/SessionQueue.js.map +1 -0
  144. package/bin/session/SessionState.d.ts +70 -0
  145. package/bin/session/SessionState.d.ts.map +1 -0
  146. package/bin/session/SessionState.js +267 -0
  147. package/bin/session/SessionState.js.map +1 -0
  148. package/bin/session/SessionSystem.d.ts +15 -0
  149. package/bin/session/SessionSystem.d.ts.map +1 -0
  150. package/bin/session/SessionSystem.js +95 -0
  151. package/bin/session/SessionSystem.js.map +1 -0
  152. package/bin/session/SessionTurn.d.ts +84 -0
  153. package/bin/session/SessionTurn.d.ts.map +1 -0
  154. package/bin/session/SessionTurn.js +588 -0
  155. package/bin/session/SessionTurn.js.map +1 -0
  156. package/bin/session/approval/SessionApprovalBroker.d.ts +48 -0
  157. package/bin/session/approval/SessionApprovalBroker.d.ts.map +1 -0
  158. package/bin/session/approval/SessionApprovalBroker.js +126 -0
  159. package/bin/session/approval/SessionApprovalBroker.js.map +1 -0
  160. package/bin/session/browse/Browse.d.ts.map +1 -1
  161. package/bin/session/browse/Browse.js +1 -4
  162. package/bin/session/browse/Browse.js.map +1 -1
  163. package/bin/session/{recorder → messages}/JsonlSessionMessageStore.d.ts.map +1 -1
  164. package/bin/session/{recorder → messages}/JsonlSessionMessageStore.js.map +1 -1
  165. package/bin/session/messages/SessionAssistantMessageWriter.d.ts +62 -0
  166. package/bin/session/messages/SessionAssistantMessageWriter.d.ts.map +1 -0
  167. package/bin/session/messages/SessionAssistantMessageWriter.js +287 -0
  168. package/bin/session/messages/SessionAssistantMessageWriter.js.map +1 -0
  169. package/bin/session/messages/SessionJsonValue.d.ts +10 -0
  170. package/bin/session/messages/SessionJsonValue.d.ts.map +1 -0
  171. package/bin/session/messages/SessionJsonValue.js +23 -0
  172. package/bin/session/messages/SessionJsonValue.js.map +1 -0
  173. package/bin/session/{recorder → messages}/SessionMessageCodec.d.ts +4 -1
  174. package/bin/session/messages/SessionMessageCodec.d.ts.map +1 -0
  175. package/bin/session/{recorder → messages}/SessionMessageCodec.js +33 -19
  176. package/bin/session/messages/SessionMessageCodec.js.map +1 -0
  177. package/bin/session/messages/SessionMessageCompaction.d.ts +22 -0
  178. package/bin/session/messages/SessionMessageCompaction.d.ts.map +1 -0
  179. package/bin/session/{recorder/SessionRecorderCompaction.js → messages/SessionMessageCompaction.js} +19 -51
  180. package/bin/session/messages/SessionMessageCompaction.js.map +1 -0
  181. package/bin/session/runtime/SessionEventHub.d.ts +1 -8
  182. package/bin/session/runtime/SessionEventHub.d.ts.map +1 -1
  183. package/bin/session/runtime/SessionEventHub.js +1 -6
  184. package/bin/session/runtime/SessionEventHub.js.map +1 -1
  185. package/bin/session/storage/Metadata.d.ts +23 -5
  186. package/bin/session/storage/Metadata.d.ts.map +1 -1
  187. package/bin/session/storage/Metadata.js +32 -29
  188. package/bin/session/storage/Metadata.js.map +1 -1
  189. package/bin/session/storage/RuntimeSessionPort.d.ts +5 -10
  190. package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
  191. package/bin/session/storage/RuntimeSessionPort.js +2 -4
  192. package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
  193. package/bin/types/agent/AgentOptions.d.ts +6 -35
  194. package/bin/types/agent/AgentOptions.d.ts.map +1 -1
  195. package/bin/types/agent/AgentState.d.ts +28 -0
  196. package/bin/types/agent/AgentState.d.ts.map +1 -0
  197. package/bin/types/agent/AgentState.js +9 -0
  198. package/bin/types/agent/AgentState.js.map +1 -0
  199. package/bin/types/agent/SessionActor.d.ts +0 -2
  200. package/bin/types/agent/SessionActor.d.ts.map +1 -1
  201. package/bin/types/agent/SessionTypes.d.ts +5 -18
  202. package/bin/types/agent/SessionTypes.d.ts.map +1 -1
  203. package/bin/types/executor/SessionRunContext.d.ts +8 -2
  204. package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
  205. package/bin/types/executor/SessionRunContext.js +1 -1
  206. package/bin/types/executor/SessionToolExecutionContext.d.ts +20 -0
  207. package/bin/types/executor/SessionToolExecutionContext.d.ts.map +1 -0
  208. package/bin/types/executor/SessionToolExecutionContext.js +10 -0
  209. package/bin/types/executor/SessionToolExecutionContext.js.map +1 -0
  210. package/bin/types/plugin/PluginAction.d.ts +10 -1
  211. package/bin/types/plugin/PluginAction.d.ts.map +1 -1
  212. package/bin/types/plugin/PluginCommand.d.ts +3 -11
  213. package/bin/types/plugin/PluginCommand.d.ts.map +1 -1
  214. package/bin/types/plugin/PluginConfig.d.ts +12 -0
  215. package/bin/types/plugin/PluginConfig.d.ts.map +1 -0
  216. package/bin/types/plugin/PluginConfig.js +5 -0
  217. package/bin/types/plugin/PluginConfig.js.map +1 -0
  218. package/bin/types/plugin/PluginDefinition.d.ts +10 -3
  219. package/bin/types/plugin/PluginDefinition.d.ts.map +1 -1
  220. package/bin/types/plugin/PluginHttp.d.ts +1 -1
  221. package/bin/types/plugin/PluginHttp.d.ts.map +1 -1
  222. package/bin/types/plugin/PluginRunContext.d.ts +26 -0
  223. package/bin/types/plugin/PluginRunContext.d.ts.map +1 -0
  224. package/bin/types/plugin/PluginRunContext.js +10 -0
  225. package/bin/types/plugin/PluginRunContext.js.map +1 -0
  226. package/bin/types/plugin/PluginRuntime.d.ts +9 -3
  227. package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
  228. package/bin/types/plugin/PluginToolRuntime.d.ts +11 -0
  229. package/bin/types/plugin/PluginToolRuntime.d.ts.map +1 -1
  230. package/bin/types/rpc/RpcProtocol.d.ts +1 -13
  231. package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
  232. package/bin/types/session/SessionApproval.d.ts +4 -38
  233. package/bin/types/session/SessionApproval.d.ts.map +1 -1
  234. package/bin/types/session/SessionApprovalBroker.d.ts +17 -0
  235. package/bin/types/session/SessionApprovalBroker.d.ts.map +1 -0
  236. package/bin/types/session/SessionApprovalBroker.js +7 -0
  237. package/bin/types/session/SessionApprovalBroker.js.map +1 -0
  238. package/bin/types/session/SessionComposer.d.ts +99 -0
  239. package/bin/types/session/SessionComposer.d.ts.map +1 -0
  240. package/bin/types/session/SessionComposer.js +8 -0
  241. package/bin/types/session/SessionComposer.js.map +1 -0
  242. package/bin/types/session/SessionLocalState.d.ts +6 -6
  243. package/bin/types/session/SessionLocalState.d.ts.map +1 -1
  244. package/bin/types/session/SessionLocalState.js +1 -1
  245. package/bin/types/session/SessionMessage.d.ts +3 -2
  246. package/bin/types/session/SessionMessage.d.ts.map +1 -1
  247. package/bin/types/session/SessionMessages.d.ts +115 -0
  248. package/bin/types/session/SessionMessages.d.ts.map +1 -0
  249. package/bin/types/session/SessionMessages.js +7 -0
  250. package/bin/types/session/SessionMessages.js.map +1 -0
  251. package/bin/types/session/SessionMutation.d.ts +1 -10
  252. package/bin/types/session/SessionMutation.d.ts.map +1 -1
  253. package/bin/types/session/SessionMutation.js.map +1 -1
  254. package/bin/types/session/SessionOptions.d.ts +8 -23
  255. package/bin/types/session/SessionOptions.d.ts.map +1 -1
  256. package/bin/types/session/SessionPort.d.ts +72 -0
  257. package/bin/types/session/SessionPort.d.ts.map +1 -0
  258. package/bin/types/session/SessionPort.js +9 -0
  259. package/bin/types/session/SessionPort.js.map +1 -0
  260. package/bin/types/session/SessionQueue.d.ts +104 -0
  261. package/bin/types/session/SessionQueue.d.ts.map +1 -0
  262. package/bin/types/session/SessionQueue.js +7 -0
  263. package/bin/types/session/SessionQueue.js.map +1 -0
  264. package/bin/types/session/SessionState.d.ts +43 -0
  265. package/bin/types/session/SessionState.d.ts.map +1 -0
  266. package/bin/types/session/SessionState.js +7 -0
  267. package/bin/types/session/SessionState.js.map +1 -0
  268. package/bin/types/session/SessionSystem.d.ts +26 -0
  269. package/bin/types/session/SessionSystem.d.ts.map +1 -0
  270. package/bin/types/session/SessionSystem.js +7 -0
  271. package/bin/types/session/SessionSystem.js.map +1 -0
  272. package/bin/types/session/SessionTool.d.ts +23 -0
  273. package/bin/types/session/SessionTool.d.ts.map +1 -0
  274. package/bin/types/session/SessionTool.js +7 -0
  275. package/bin/types/session/SessionTool.js.map +1 -0
  276. package/bin/types/session/SessionTurn.d.ts +52 -0
  277. package/bin/types/session/SessionTurn.d.ts.map +1 -0
  278. package/bin/types/session/SessionTurn.js +7 -0
  279. package/bin/types/session/SessionTurn.js.map +1 -0
  280. package/package.json +3 -3
  281. package/scripts/agent-env.test.mjs +4 -18
  282. package/scripts/agent-ready.test.mjs +33 -2
  283. package/scripts/agent-session-maintenance.test.mjs +52 -0
  284. package/scripts/city-model-tool-loop.test.mjs +3 -4
  285. package/scripts/core-engine-context-compaction.test.mjs +5 -22
  286. package/scripts/image-plugin-job.test.mjs +4 -6
  287. package/scripts/plugin-tool-bridge.test.mjs +44 -36
  288. package/scripts/read-image-tool-bridge.test.mjs +71 -0
  289. package/scripts/remote-session-reconnect.test.mjs +1 -34
  290. package/scripts/session-compaction-prompts.test.mjs +1 -49
  291. package/scripts/session-composer.test.mjs +163 -0
  292. package/scripts/session-config-turn-boundary.test.mjs +2 -5
  293. package/scripts/session-list-title.test.mjs +3 -2
  294. package/scripts/session-messages-error.test.mjs +57 -0
  295. package/scripts/{session-recorder.test.mjs → session-messages.test.mjs} +131 -90
  296. package/scripts/session-queue.test.mjs +64 -0
  297. package/scripts/session-shell-approval.test.mjs +171 -0
  298. package/scripts/session-system-blocks.test.mjs +10 -10
  299. package/scripts/session-title-event.test.mjs +1 -0
  300. package/src/agent/Agent.ts +241 -0
  301. package/src/agent/AgentContext.ts +92 -0
  302. package/src/agent/{local/AgentInstructions.ts → AgentInstructions.ts} +0 -11
  303. package/src/{model/CityModelAdapter.ts → agent/AgentModel.ts} +10 -3
  304. package/src/agent/{local/services/AgentSessions.ts → AgentSessions.ts} +81 -110
  305. package/src/agent/AgentState.ts +151 -0
  306. package/src/config/Paths.ts +0 -91
  307. package/src/executor/Executor.ts +180 -386
  308. package/src/executor/README.md +29 -89
  309. package/src/executor/composer/system/default/DefaultSessionSystemComposer.ts +1 -1
  310. package/src/executor/composer/system/default/SystemDomain.ts +4 -2
  311. package/src/executor/composer/system/default/assets/core.prompt.ts +1 -1
  312. package/src/executor/composer/system/default/assets/core.prompt.ts.txt +15 -2
  313. package/src/executor/core-engine/CoreEngineRunner.ts +95 -54
  314. package/src/executor/services/ExecutorRecoveryPolicy.ts +24 -19
  315. package/src/executor/tools/file/ReadImageToolBridge.ts +79 -0
  316. package/src/executor/tools/plugin/PluginToolBridge.ts +6 -8
  317. package/src/executor/tools/plugin/PluginToolDefinition.ts +23 -3
  318. package/src/executor/types/SessionHistoryMeta.ts +0 -2
  319. package/src/index.ts +34 -53
  320. package/src/plugin/core/ActionScheduleExecutor.ts +1 -1
  321. package/src/plugin/core/ActionScheduleRuntime.ts +1 -1
  322. package/src/plugin/core/BasePlugin.ts +7 -3
  323. package/src/plugin/core/HookRegistry.ts +15 -18
  324. package/src/plugin/core/PluginActionFactory.ts +9 -3
  325. package/src/plugin/core/PluginActionRunner.ts +1 -1
  326. package/src/plugin/core/PluginCatalog.ts +1 -1
  327. package/src/plugin/core/PluginHttpRoutes.ts +1 -1
  328. package/src/plugin/core/PluginLocalExecution.ts +11 -24
  329. package/src/plugin/core/PluginRegistry.ts +55 -32
  330. package/src/plugin/core/PluginStateController.ts +1 -1
  331. package/src/{agent/remote → remote}/RemoteAgent.ts +4 -4
  332. package/src/{agent/remote → remote}/RemoteSession.ts +2 -35
  333. package/src/{agent/remote → remote}/RemoteTransport.ts +0 -3
  334. package/src/{agent/remote → remote}/TransportFactory.ts +3 -3
  335. package/src/{agent/remote → remote}/transports/HttpRemoteAgentTransport.ts +1 -23
  336. package/src/{rpc/Client.ts → remote/transports/RpcClient.ts} +1 -19
  337. package/src/{agent/remote → remote}/transports/RpcRemoteAgentTransport.ts +2 -10
  338. package/src/session/DefaultSessionComposer.ts +79 -0
  339. package/src/session/Session.ts +496 -332
  340. package/src/session/{recorder/SessionRecorder.ts → SessionMessages.ts} +254 -428
  341. package/src/session/SessionQueue.ts +86 -0
  342. package/src/session/SessionState.ts +322 -0
  343. package/src/session/SessionSystem.ts +117 -0
  344. package/src/session/SessionTurn.ts +684 -0
  345. package/src/session/approval/SessionApprovalBroker.ts +164 -0
  346. package/src/session/browse/Browse.ts +1 -4
  347. package/src/session/messages/SessionAssistantMessageWriter.ts +345 -0
  348. package/src/session/messages/SessionJsonValue.ts +25 -0
  349. package/src/session/{recorder → messages}/SessionMessageCodec.ts +38 -20
  350. package/src/session/{recorder/SessionRecorderCompaction.ts → messages/SessionMessageCompaction.ts} +30 -69
  351. package/src/session/runtime/SessionEventHub.ts +1 -14
  352. package/src/session/storage/Metadata.ts +60 -34
  353. package/src/session/storage/RuntimeSessionPort.ts +7 -14
  354. package/src/types/agent/AgentOptions.ts +6 -38
  355. package/src/types/agent/AgentState.ts +33 -0
  356. package/src/types/agent/SessionActor.ts +0 -3
  357. package/src/types/agent/SessionTypes.ts +5 -18
  358. package/src/types/executor/SessionRunContext.ts +10 -2
  359. package/src/types/executor/SessionToolExecutionContext.ts +21 -0
  360. package/src/types/plugin/PluginAction.ts +10 -1
  361. package/src/types/plugin/PluginCommand.ts +3 -14
  362. package/src/types/plugin/PluginConfig.ts +13 -0
  363. package/src/types/plugin/PluginDefinition.ts +13 -6
  364. package/src/types/plugin/PluginHttp.ts +1 -1
  365. package/src/types/plugin/PluginRunContext.ts +31 -0
  366. package/src/types/plugin/PluginRuntime.ts +13 -6
  367. package/src/types/plugin/PluginToolRuntime.ts +13 -1
  368. package/src/types/rpc/RpcProtocol.ts +0 -14
  369. package/src/types/session/SessionApproval.ts +4 -43
  370. package/src/types/session/SessionApprovalBroker.ts +18 -0
  371. package/src/types/session/SessionComposer.ts +114 -0
  372. package/src/types/session/SessionLocalState.ts +6 -6
  373. package/src/types/session/SessionMessage.ts +3 -2
  374. package/src/types/session/SessionMessages.ts +127 -0
  375. package/src/types/session/SessionMutation.ts +0 -11
  376. package/src/types/session/SessionOptions.ts +8 -40
  377. package/src/types/session/SessionPort.ts +97 -0
  378. package/src/types/session/SessionQueue.ts +122 -0
  379. package/src/types/session/SessionState.ts +47 -0
  380. package/src/types/session/SessionSystem.ts +27 -0
  381. package/src/types/session/SessionTool.ts +25 -0
  382. package/src/types/session/SessionTurn.ts +56 -0
  383. package/tsconfig.tsbuildinfo +1 -1
  384. package/bin/agent/local/Agent.d.ts.map +0 -1
  385. package/bin/agent/local/Agent.js +0 -216
  386. package/bin/agent/local/Agent.js.map +0 -1
  387. package/bin/agent/local/AgentInstructions.d.ts.map +0 -1
  388. package/bin/agent/local/AgentInstructions.js.map +0 -1
  389. package/bin/agent/local/AgentPluginFactory.d.ts +0 -26
  390. package/bin/agent/local/AgentPluginFactory.d.ts.map +0 -1
  391. package/bin/agent/local/AgentPluginFactory.js +0 -33
  392. package/bin/agent/local/AgentPluginFactory.js.map +0 -1
  393. package/bin/agent/local/AgentRuntimeAssembly.d.ts +0 -10
  394. package/bin/agent/local/AgentRuntimeAssembly.d.ts.map +0 -1
  395. package/bin/agent/local/AgentRuntimeAssembly.js +0 -43
  396. package/bin/agent/local/AgentRuntimeAssembly.js.map +0 -1
  397. package/bin/agent/local/ProjectSetup.d.ts.map +0 -1
  398. package/bin/agent/local/ProjectSetup.js.map +0 -1
  399. package/bin/agent/local/services/AgentAssemblyService.d.ts +0 -105
  400. package/bin/agent/local/services/AgentAssemblyService.d.ts.map +0 -1
  401. package/bin/agent/local/services/AgentAssemblyService.js +0 -184
  402. package/bin/agent/local/services/AgentAssemblyService.js.map +0 -1
  403. package/bin/agent/local/services/AgentBackgroundService.d.ts +0 -55
  404. package/bin/agent/local/services/AgentBackgroundService.d.ts.map +0 -1
  405. package/bin/agent/local/services/AgentBackgroundService.js +0 -85
  406. package/bin/agent/local/services/AgentBackgroundService.js.map +0 -1
  407. package/bin/agent/local/services/AgentSessions.d.ts.map +0 -1
  408. package/bin/agent/local/services/AgentSessions.js.map +0 -1
  409. package/bin/agent/remote/RemoteAgent.d.ts.map +0 -1
  410. package/bin/agent/remote/RemoteAgent.js.map +0 -1
  411. package/bin/agent/remote/RemoteSession.d.ts.map +0 -1
  412. package/bin/agent/remote/RemoteSession.js.map +0 -1
  413. package/bin/agent/remote/RemoteTransport.d.ts.map +0 -1
  414. package/bin/agent/remote/RemoteTransport.js.map +0 -1
  415. package/bin/agent/remote/TransportFactory.d.ts.map +0 -1
  416. package/bin/agent/remote/TransportFactory.js.map +0 -1
  417. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +0 -1
  418. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +0 -1
  419. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +0 -1
  420. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +0 -1
  421. package/bin/executor/SessionRunScope.d.ts +0 -68
  422. package/bin/executor/SessionRunScope.d.ts.map +0 -1
  423. package/bin/executor/SessionRunScope.js +0 -96
  424. package/bin/executor/SessionRunScope.js.map +0 -1
  425. package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts +0 -74
  426. package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts.map +0 -1
  427. package/bin/executor/composer/compaction/SessionCompactionComposer.js +0 -9
  428. package/bin/executor/composer/compaction/SessionCompactionComposer.js.map +0 -1
  429. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts +0 -27
  430. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts.map +0 -1
  431. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js +0 -39
  432. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js.map +0 -1
  433. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +0 -44
  434. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +0 -1
  435. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +0 -218
  436. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +0 -1
  437. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts +0 -27
  438. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts.map +0 -1
  439. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js +0 -181
  440. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js.map +0 -1
  441. package/bin/executor/composer/context/LocalSessionContextComposer.d.ts +0 -50
  442. package/bin/executor/composer/context/LocalSessionContextComposer.d.ts.map +0 -1
  443. package/bin/executor/composer/context/LocalSessionContextComposer.js +0 -108
  444. package/bin/executor/composer/context/LocalSessionContextComposer.js.map +0 -1
  445. package/bin/executor/composer/context/SessionContextComposer.d.ts +0 -67
  446. package/bin/executor/composer/context/SessionContextComposer.d.ts.map +0 -1
  447. package/bin/executor/composer/context/SessionContextComposer.js +0 -9
  448. package/bin/executor/composer/context/SessionContextComposer.js.map +0 -1
  449. package/bin/executor/composer/history/SessionHistoryComposer.d.ts +0 -54
  450. package/bin/executor/composer/history/SessionHistoryComposer.d.ts.map +0 -1
  451. package/bin/executor/composer/history/SessionHistoryComposer.js +0 -10
  452. package/bin/executor/composer/history/SessionHistoryComposer.js.map +0 -1
  453. package/bin/executor/composer/history/SessionHistoryWriter.d.ts +0 -46
  454. package/bin/executor/composer/history/SessionHistoryWriter.d.ts.map +0 -1
  455. package/bin/executor/composer/history/SessionHistoryWriter.js +0 -65
  456. package/bin/executor/composer/history/SessionHistoryWriter.js.map +0 -1
  457. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts +0 -35
  458. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts.map +0 -1
  459. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js +0 -105
  460. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js.map +0 -1
  461. package/bin/executor/messages/AssistantResultPersistence.d.ts +0 -66
  462. package/bin/executor/messages/AssistantResultPersistence.d.ts.map +0 -1
  463. package/bin/executor/messages/AssistantResultPersistence.js +0 -44
  464. package/bin/executor/messages/AssistantResultPersistence.js.map +0 -1
  465. package/bin/executor/services/ExecutorInflightService.d.ts +0 -34
  466. package/bin/executor/services/ExecutorInflightService.d.ts.map +0 -1
  467. package/bin/executor/services/ExecutorInflightService.js +0 -73
  468. package/bin/executor/services/ExecutorInflightService.js.map +0 -1
  469. package/bin/executor/store/history/SessionHistoryStore.d.ts +0 -140
  470. package/bin/executor/store/history/SessionHistoryStore.d.ts.map +0 -1
  471. package/bin/executor/store/history/SessionHistoryStore.js +0 -10
  472. package/bin/executor/store/history/SessionHistoryStore.js.map +0 -1
  473. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +0 -116
  474. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +0 -1
  475. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +0 -709
  476. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +0 -1
  477. package/bin/executor/types/SessionHistoryPaths.d.ts +0 -34
  478. package/bin/executor/types/SessionHistoryPaths.d.ts.map +0 -1
  479. package/bin/executor/types/SessionHistoryPaths.js +0 -2
  480. package/bin/executor/types/SessionHistoryPaths.js.map +0 -1
  481. package/bin/model/CityModelAdapter.d.ts.map +0 -1
  482. package/bin/model/CityModelAdapter.js.map +0 -1
  483. package/bin/rpc/Client.d.ts.map +0 -1
  484. package/bin/rpc/Client.js.map +0 -1
  485. package/bin/session/SessionSystemBuilder.d.ts +0 -107
  486. package/bin/session/SessionSystemBuilder.d.ts.map +0 -1
  487. package/bin/session/SessionSystemBuilder.js +0 -148
  488. package/bin/session/SessionSystemBuilder.js.map +0 -1
  489. package/bin/session/recorder/SessionMessageCodec.d.ts.map +0 -1
  490. package/bin/session/recorder/SessionMessageCodec.js.map +0 -1
  491. package/bin/session/recorder/SessionRecorder.d.ts +0 -217
  492. package/bin/session/recorder/SessionRecorder.d.ts.map +0 -1
  493. package/bin/session/recorder/SessionRecorder.js.map +0 -1
  494. package/bin/session/recorder/SessionRecorderCompaction.d.ts +0 -18
  495. package/bin/session/recorder/SessionRecorderCompaction.d.ts.map +0 -1
  496. package/bin/session/recorder/SessionRecorderCompaction.js.map +0 -1
  497. package/bin/session/recorder/SessionRecorderHistoryStore.d.ts +0 -66
  498. package/bin/session/recorder/SessionRecorderHistoryStore.d.ts.map +0 -1
  499. package/bin/session/recorder/SessionRecorderHistoryStore.js +0 -190
  500. package/bin/session/recorder/SessionRecorderHistoryStore.js.map +0 -1
  501. package/bin/session/runtime/SessionPromptRuntime.d.ts +0 -112
  502. package/bin/session/runtime/SessionPromptRuntime.d.ts.map +0 -1
  503. package/bin/session/runtime/SessionPromptRuntime.js +0 -357
  504. package/bin/session/runtime/SessionPromptRuntime.js.map +0 -1
  505. package/bin/session/services/SessionStateService.d.ts +0 -187
  506. package/bin/session/services/SessionStateService.d.ts.map +0 -1
  507. package/bin/session/services/SessionStateService.js +0 -467
  508. package/bin/session/services/SessionStateService.js.map +0 -1
  509. package/bin/session/services/SessionTurnService.d.ts +0 -90
  510. package/bin/session/services/SessionTurnService.d.ts.map +0 -1
  511. package/bin/session/services/SessionTurnService.js +0 -293
  512. package/bin/session/services/SessionTurnService.js.map +0 -1
  513. package/bin/session/services/SessionViewService.d.ts +0 -114
  514. package/bin/session/services/SessionViewService.d.ts.map +0 -1
  515. package/bin/session/services/SessionViewService.js +0 -204
  516. package/bin/session/services/SessionViewService.js.map +0 -1
  517. package/bin/session/storage/Persistence.d.ts +0 -73
  518. package/bin/session/storage/Persistence.d.ts.map +0 -1
  519. package/bin/session/storage/Persistence.js +0 -63
  520. package/bin/session/storage/Persistence.js.map +0 -1
  521. package/bin/types/agent/AgentRuntimeAssembly.d.ts +0 -72
  522. package/bin/types/agent/AgentRuntimeAssembly.d.ts.map +0 -1
  523. package/bin/types/agent/AgentRuntimeAssembly.js +0 -10
  524. package/bin/types/agent/AgentRuntimeAssembly.js.map +0 -1
  525. package/bin/types/runtime/agent/AgentContext.d.ts +0 -306
  526. package/bin/types/runtime/agent/AgentContext.d.ts.map +0 -1
  527. package/bin/types/runtime/agent/AgentContext.js +0 -128
  528. package/bin/types/runtime/agent/AgentContext.js.map +0 -1
  529. package/bin/types/session/SessionComposerOptions.d.ts +0 -90
  530. package/bin/types/session/SessionComposerOptions.d.ts.map +0 -1
  531. package/bin/types/session/SessionComposerOptions.js +0 -10
  532. package/bin/types/session/SessionComposerOptions.js.map +0 -1
  533. package/bin/types/session/SessionQueueCommand.d.ts +0 -68
  534. package/bin/types/session/SessionQueueCommand.d.ts.map +0 -1
  535. package/bin/types/session/SessionQueueCommand.js +0 -10
  536. package/bin/types/session/SessionQueueCommand.js.map +0 -1
  537. package/scripts/session-action-message.test.mjs +0 -410
  538. package/scripts/session-compaction-context-window.test.mjs +0 -96
  539. package/scripts/session-history-inflight.test.mjs +0 -146
  540. package/scripts/session-history-writer-error.test.mjs +0 -57
  541. package/scripts/session-prompt-runtime.test.mjs +0 -390
  542. package/src/agent/local/Agent.ts +0 -250
  543. package/src/agent/local/AgentPluginFactory.ts +0 -51
  544. package/src/agent/local/AgentRuntimeAssembly.ts +0 -65
  545. package/src/agent/local/services/AgentAssemblyService.ts +0 -307
  546. package/src/agent/local/services/AgentBackgroundService.ts +0 -115
  547. package/src/executor/SessionRunScope.ts +0 -122
  548. package/src/executor/composer/compaction/SessionCompactionComposer.ts +0 -84
  549. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.ts +0 -51
  550. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +0 -294
  551. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.ts +0 -197
  552. package/src/executor/composer/context/LocalSessionContextComposer.ts +0 -175
  553. package/src/executor/composer/context/SessionContextComposer.ts +0 -83
  554. package/src/executor/composer/history/SessionHistoryComposer.ts +0 -62
  555. package/src/executor/composer/history/SessionHistoryWriter.ts +0 -100
  556. package/src/executor/composer/history/jsonl/JsonlSessionHistoryComposer.ts +0 -133
  557. package/src/executor/messages/AssistantResultPersistence.ts +0 -106
  558. package/src/executor/services/ExecutorInflightService.ts +0 -95
  559. package/src/executor/store/history/SessionHistoryStore.ts +0 -172
  560. package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +0 -879
  561. package/src/executor/types/SessionHistoryPaths.ts +0 -38
  562. package/src/session/SessionSystemBuilder.ts +0 -262
  563. package/src/session/recorder/SessionRecorderHistoryStore.ts +0 -256
  564. package/src/session/runtime/SessionPromptRuntime.ts +0 -518
  565. package/src/session/services/SessionStateService.ts +0 -628
  566. package/src/session/services/SessionTurnService.ts +0 -368
  567. package/src/session/services/SessionViewService.ts +0 -335
  568. package/src/session/storage/Persistence.ts +0 -137
  569. package/src/types/agent/AgentRuntimeAssembly.ts +0 -74
  570. package/src/types/runtime/agent/AgentContext.ts +0 -387
  571. package/src/types/session/SessionComposerOptions.ts +0 -107
  572. package/src/types/session/SessionQueueCommand.ts +0 -78
  573. /package/bin/{agent/local → config}/ProjectSetup.d.ts +0 -0
  574. /package/bin/{agent/remote → remote}/RemoteTransport.js +0 -0
  575. /package/bin/session/{recorder → messages}/JsonlSessionMessageStore.d.ts +0 -0
  576. /package/bin/session/{recorder → messages}/JsonlSessionMessageStore.js +0 -0
  577. /package/src/{agent/local → config}/ProjectSetup.ts +0 -0
  578. /package/src/session/{recorder → messages}/JsonlSessionMessageStore.ts +0 -0
@@ -1,879 +0,0 @@
1
- /**
2
- * JsonlSessionHistoryStore:基于 JSONL 的 session records 事实源。
3
- *
4
- * 关键点(中文)
5
- * - 负责 `.downcity/.../messages/messages.jsonl`、`meta.json`、archive 与文件锁。
6
- * - append 与 compact 共用同一把文件锁,避免并发覆盖。
7
- * - 不负责为模型组装 messages;组装逻辑放在 `JsonlSessionHistoryComposer`。
8
- */
9
-
10
- import fs from "fs-extra";
11
- import {
12
- open as openFile,
13
- readFile as readFileNative,
14
- stat as statNative,
15
- } from "node:fs/promises";
16
- import path from "node:path";
17
- import { generateId } from "@/utils/Id.js";
18
- import { getLogger } from "@/utils/logger/Logger.js";
19
- import { compactSessionMessagesIfNeeded } from "@executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js";
20
- import type {
21
- SessionActionRecordV1,
22
- SessionRecordV1,
23
- SessionMetadataV1,
24
- } from "@/executor/types/SessionRecords.js";
25
- import {
26
- is_session_action_record,
27
- is_session_message_record,
28
- to_session_action_record,
29
- } from "@/executor/types/SessionRecords.js";
30
- import type { SessionSystemMessage } from "@/executor/types/SessionPrompts.js";
31
- import type { SessionHistoryMetaV1 } from "@/executor/types/SessionHistoryMeta.js";
32
- import type { SessionHistoryPathOverrides } from "@/executor/types/SessionHistoryPaths.js";
33
- import type {
34
- SessionHistoryCompactInput,
35
- SessionHistoryStore,
36
- } from "@/executor/store/history/SessionHistoryStore.js";
37
- import { resolve_session_message_preview } from "@/session/preview/SessionMessagePreview.js";
38
-
39
- /**
40
- * JSONL history store 构造参数。
41
- */
42
- export type JsonlSessionHistoryStoreOptions = {
43
- /**
44
- * 当前项目根目录。
45
- */
46
- rootPath: string;
47
- /**
48
- * 当前 agentId。
49
- *
50
- * 关键点(中文)
51
- * - 仅在未提供 `paths` 覆盖时必需。
52
- * - 默认目录统一收敛到 `.downcity/agents/<agentId>/sessions/...`。
53
- */
54
- agentId?: string;
55
- /**
56
- * 当前 sessionId。
57
- */
58
- sessionId?: string;
59
- /**
60
- * 可选路径覆盖,供 SDK session / task run 复用同一 JSONL store。
61
- */
62
- paths?: SessionHistoryPathOverrides;
63
- };
64
-
65
- function getDowncityDirPath(rootPath: string): string {
66
- return path.join(rootPath, ".downcity");
67
- }
68
-
69
- function getDowncityAgentsRootDirPath(rootPath: string): string {
70
- return path.join(getDowncityDirPath(rootPath), "agents");
71
- }
72
-
73
- function getDowncitySessionRootDirPath(rootPath: string, agentId: string): string {
74
- return path.join(
75
- getDowncityAgentsRootDirPath(rootPath),
76
- encodeURIComponent(agentId),
77
- "sessions",
78
- );
79
- }
80
-
81
- function getDowncitySessionDirPath(
82
- rootPath: string,
83
- agentId: string,
84
- sessionId: string,
85
- ): string {
86
- return path.join(
87
- getDowncitySessionRootDirPath(rootPath, agentId),
88
- encodeURIComponent(sessionId),
89
- );
90
- }
91
-
92
- function getDowncitySessionMessagesDirPath(
93
- rootPath: string,
94
- agentId: string,
95
- sessionId: string,
96
- ): string {
97
- return path.join(
98
- getDowncitySessionDirPath(rootPath, agentId, sessionId),
99
- "messages",
100
- );
101
- }
102
-
103
- /**
104
- * JSONL Session history store。
105
- */
106
- export class JsonlSessionHistoryStore implements SessionHistoryStore {
107
- readonly sessionId: string;
108
-
109
- private readonly rootPath: string;
110
- private readonly agentId?: string;
111
- private readonly overrideSessionDirPath?: string;
112
- private readonly overrideMessagesDirPath?: string;
113
- private readonly overrideMessagesFilePath?: string;
114
- private readonly overrideMetaFilePath?: string;
115
- private readonly overrideArchiveDirPath?: string;
116
- private readonly overrideInflightFilePath?: string;
117
-
118
- constructor(options: JsonlSessionHistoryStoreOptions) {
119
- const rootPath = String(options.rootPath || "").trim();
120
- if (!rootPath) {
121
- throw new Error("JsonlSessionHistoryStore requires a non-empty rootPath");
122
- }
123
- const sessionId = String(options.sessionId || "").trim();
124
- if (!sessionId) {
125
- throw new Error("JsonlSessionHistoryStore requires a non-empty sessionId");
126
- }
127
-
128
- this.rootPath = rootPath;
129
- this.sessionId = sessionId;
130
- this.agentId = this.readOptionalPath(options.agentId);
131
- this.overrideSessionDirPath = this.readOptionalPath(
132
- options.paths?.sessionDirPath,
133
- );
134
- this.overrideMessagesDirPath = this.readOptionalPath(
135
- options.paths?.messagesDirPath,
136
- );
137
- this.overrideMessagesFilePath = this.readOptionalPath(
138
- options.paths?.messagesFilePath,
139
- );
140
- this.overrideMetaFilePath = this.readOptionalPath(
141
- options.paths?.metaFilePath,
142
- );
143
- this.overrideArchiveDirPath = this.readOptionalPath(
144
- options.paths?.archiveDirPath,
145
- );
146
- this.overrideInflightFilePath = this.readOptionalPath(
147
- options.paths?.inflightFilePath,
148
- );
149
- }
150
-
151
- private readOptionalPath(value: string | undefined): string | undefined {
152
- const out = String(value || "").trim();
153
- return out || undefined;
154
- }
155
-
156
- private getMessagesDirPath(): string {
157
- if (this.overrideMessagesDirPath) return this.overrideMessagesDirPath;
158
- if (this.overrideSessionDirPath) {
159
- return path.join(this.overrideSessionDirPath, "messages");
160
- }
161
- if (!this.agentId) {
162
- throw new Error(
163
- "JsonlSessionHistoryStore requires agentId when default session paths are used",
164
- );
165
- }
166
- return getDowncitySessionMessagesDirPath(
167
- this.rootPath,
168
- this.agentId,
169
- this.sessionId,
170
- );
171
- }
172
-
173
- private getMessagesFilePath(): string {
174
- if (this.overrideMessagesFilePath) return this.overrideMessagesFilePath;
175
- if (this.overrideMessagesDirPath) {
176
- return path.join(this.overrideMessagesDirPath, "messages.jsonl");
177
- }
178
- return path.join(this.getMessagesDirPath(), "messages.jsonl");
179
- }
180
-
181
- private getMetaFilePath(): string {
182
- if (this.overrideMetaFilePath) return this.overrideMetaFilePath;
183
- if (this.overrideMessagesDirPath) {
184
- return path.join(this.overrideMessagesDirPath, "meta.json");
185
- }
186
- return path.join(this.getMessagesDirPath(), "meta.json");
187
- }
188
-
189
- private getArchiveDirPath(): string {
190
- if (this.overrideArchiveDirPath) return this.overrideArchiveDirPath;
191
- if (this.overrideMessagesDirPath) {
192
- return path.join(this.overrideMessagesDirPath, "archive");
193
- }
194
- return path.join(this.getMessagesDirPath(), "archive");
195
- }
196
-
197
- private getInflightFilePath(): string {
198
- if (this.overrideInflightFilePath) return this.overrideInflightFilePath;
199
- if (this.overrideMessagesDirPath) {
200
- return path.join(this.overrideMessagesDirPath, "assistant_message.json");
201
- }
202
- return path.join(this.getMessagesDirPath(), "assistant_message.json");
203
- }
204
-
205
- private getLockFilePath(): string {
206
- return path.join(this.getMessagesDirPath(), ".session.lock");
207
- }
208
-
209
- private async ensureLayout(): Promise<void> {
210
- // 关键点(中文):以 messages 目录为最小落盘单元,统一保证 messages/meta/archive 可写。
211
- await fs.ensureDir(this.getMessagesDirPath());
212
- await fs.ensureDir(this.getArchiveDirPath());
213
- await fs.ensureFile(this.getMessagesFilePath());
214
- }
215
-
216
- private normalizeText(input: unknown): string | undefined {
217
- const value = typeof input === "string" ? input.trim() : "";
218
- return value || undefined;
219
- }
220
-
221
- private normalizePersistedMessage(
222
- input: unknown,
223
- ): SessionRecordV1 | null {
224
- if (!input || typeof input !== "object") return null;
225
- if ((input as { type?: unknown }).type === "action") {
226
- return this.normalize_action_record(input);
227
- }
228
- const candidate = input as { role?: unknown; parts?: unknown };
229
- const role = String(candidate.role || "");
230
- if (role !== "user" && role !== "assistant") {
231
- return null;
232
- }
233
- if (!Array.isArray(candidate.parts)) return null;
234
- return input as SessionRecordV1;
235
- }
236
-
237
- private normalize_action_record(input: unknown): SessionActionRecordV1 | null {
238
- if (!input || typeof input !== "object") return null;
239
- const candidate = input as Partial<SessionActionRecordV1>;
240
- const id = String(candidate.id || "").trim();
241
- const title = String(candidate.title || "").trim();
242
- const state = String(candidate.state || "").trim();
243
- if (!id || !title) return null;
244
- if (state !== "running" && state !== "completed" && state !== "failed") {
245
- return null;
246
- }
247
- const metadata_input =
248
- candidate.metadata && typeof candidate.metadata === "object"
249
- ? candidate.metadata
250
- : {};
251
- const metadata_candidate = metadata_input as Partial<SessionActionRecordV1["metadata"]>;
252
- const session_id =
253
- String(metadata_candidate.sessionId || "").trim() || this.sessionId;
254
- const description = String(candidate.description || "").trim();
255
- return {
256
- type: "action",
257
- id,
258
- title,
259
- ...(description ? { description } : {}),
260
- state,
261
- metadata: {
262
- v: 1,
263
- ts:
264
- typeof metadata_candidate.ts === "number"
265
- ? metadata_candidate.ts
266
- : Date.now(),
267
- sessionId: session_id,
268
- ...(metadata_candidate.turnId ? { turnId: metadata_candidate.turnId } : {}),
269
- },
270
- };
271
- }
272
-
273
- private hasStructuredAssistantParts(message: SessionRecordV1 | null): boolean {
274
- if (
275
- !is_session_message_record(message) ||
276
- message.role !== "assistant" ||
277
- !Array.isArray(message.parts)
278
- ) {
279
- return false;
280
- }
281
- return message.parts.some((part) => {
282
- if (!part || typeof part !== "object") return false;
283
- const type = typeof part.type === "string" ? part.type.trim() : "";
284
- return Boolean(type) && type !== "text";
285
- });
286
- }
287
-
288
- private mergeInflightWithFinal(
289
- inflight: SessionRecordV1,
290
- finalMessage: SessionRecordV1,
291
- ): SessionRecordV1 {
292
- if (!is_session_message_record(finalMessage)) return inflight;
293
- if (!is_session_message_record(inflight)) return finalMessage;
294
- const final_parts = Array.isArray(finalMessage.parts)
295
- ? finalMessage.parts.filter((part) => part && typeof part === "object")
296
- : [];
297
- if (this.hasStructuredAssistantParts(finalMessage)) {
298
- return finalMessage;
299
- }
300
- if (final_parts.length === 0) return inflight;
301
-
302
- const inflight_parts = Array.isArray(inflight.parts)
303
- ? inflight.parts
304
- : [];
305
- const last_inflight_part =
306
- inflight_parts.length > 0 ? inflight_parts[inflight_parts.length - 1] : undefined;
307
- const last_inflight_text =
308
- last_inflight_part &&
309
- typeof last_inflight_part === "object" &&
310
- last_inflight_part.type === "text" &&
311
- typeof last_inflight_part.text === "string"
312
- ? last_inflight_part.text.trim()
313
- : "";
314
- const append_parts = final_parts.filter((part, index) => {
315
- if (index > 0) return true;
316
- if (!part || typeof part !== "object" || part.type !== "text") return true;
317
- const next_text = typeof part.text === "string" ? part.text.trim() : "";
318
- if (!next_text) return false;
319
- return next_text !== last_inflight_text;
320
- });
321
-
322
- return {
323
- ...inflight,
324
- id: finalMessage.id,
325
- metadata: {
326
- ...(inflight.metadata || {
327
- v: 1 as const,
328
- ts: Date.now(),
329
- sessionId: this.sessionId,
330
- }),
331
- ...(finalMessage.metadata || {}),
332
- },
333
- parts: [...inflight_parts, ...append_parts],
334
- };
335
- }
336
-
337
- private async readMetaUnsafe(): Promise<SessionHistoryMetaV1> {
338
- const file = this.getMetaFilePath();
339
- try {
340
- const raw = (await fs.readJson(
341
- file,
342
- )) as Partial<SessionHistoryMetaV1> | null;
343
- if (!raw || typeof raw !== "object") throw new Error("invalid_meta");
344
- return {
345
- v: 1,
346
- sessionId: this.sessionId,
347
- ...(typeof raw.agentId === "string" && raw.agentId.trim()
348
- ? { agentId: raw.agentId.trim() }
349
- : {}),
350
- ...(typeof raw.createdAt === "number" && Number.isFinite(raw.createdAt)
351
- ? { createdAt: raw.createdAt }
352
- : {}),
353
- ...(this.normalizeText(raw.timezone)
354
- ? { timezone: this.normalizeText(raw.timezone) }
355
- : {}),
356
- updatedAt: typeof raw.updatedAt === "number" ? raw.updatedAt : 0,
357
- ...(this.normalizeText(raw.title)
358
- ? { title: this.normalizeText(raw.title) }
359
- : {}),
360
- ...(this.normalizeText(raw.modelLabel)
361
- ? { modelLabel: this.normalizeText(raw.modelLabel) }
362
- : {}),
363
- ...(typeof raw.messageCount === "number" &&
364
- Number.isInteger(raw.messageCount) &&
365
- raw.messageCount >= 0
366
- ? { messageCount: raw.messageCount }
367
- : {}),
368
- ...(this.normalizeText(raw.previewText)
369
- ? { previewText: this.normalizeText(raw.previewText) }
370
- : {}),
371
- ...(typeof raw.historyBytes === "number" &&
372
- Number.isInteger(raw.historyBytes) &&
373
- raw.historyBytes >= 0
374
- ? { historyBytes: raw.historyBytes }
375
- : {}),
376
- };
377
- } catch {
378
- return {
379
- v: 1,
380
- sessionId: this.sessionId,
381
- createdAt: Date.now(),
382
- updatedAt: 0,
383
- };
384
- }
385
- }
386
-
387
- private async writeMetaUnsafe(next: SessionHistoryMetaV1): Promise<void> {
388
- const normalized: SessionHistoryMetaV1 = {
389
- v: 1,
390
- sessionId: this.sessionId,
391
- ...(typeof next.agentId === "string" && next.agentId.trim()
392
- ? { agentId: next.agentId.trim() }
393
- : {}),
394
- ...(typeof next.createdAt === "number" && Number.isFinite(next.createdAt)
395
- ? { createdAt: next.createdAt }
396
- : {}),
397
- ...(this.normalizeText(next.timezone)
398
- ? { timezone: this.normalizeText(next.timezone) }
399
- : {}),
400
- updatedAt:
401
- typeof next.updatedAt === "number" ? next.updatedAt : Date.now(),
402
- ...(this.normalizeText(next.title)
403
- ? { title: this.normalizeText(next.title) }
404
- : {}),
405
- ...(this.normalizeText(next.modelLabel)
406
- ? { modelLabel: this.normalizeText(next.modelLabel) }
407
- : {}),
408
- ...(typeof next.messageCount === "number" &&
409
- Number.isInteger(next.messageCount) &&
410
- next.messageCount >= 0
411
- ? { messageCount: next.messageCount }
412
- : {}),
413
- ...(this.normalizeText(next.previewText)
414
- ? { previewText: this.normalizeText(next.previewText) }
415
- : {}),
416
- ...(typeof next.historyBytes === "number" &&
417
- Number.isInteger(next.historyBytes) &&
418
- next.historyBytes >= 0
419
- ? { historyBytes: next.historyBytes }
420
- : {}),
421
- };
422
- await fs.writeJson(this.getMetaFilePath(), normalized, { spaces: 2 });
423
- }
424
-
425
- private async read_inflight_unsafe(): Promise<SessionRecordV1 | null> {
426
- const file = this.getInflightFilePath();
427
- try {
428
- const raw = await fs.readJson(file);
429
- return this.normalizePersistedMessage(raw);
430
- } catch {
431
- return null;
432
- }
433
- }
434
-
435
- private async write_inflight_unsafe(message: SessionRecordV1): Promise<void> {
436
- const normalized = this.normalizePersistedMessage(message);
437
- if (
438
- !is_session_message_record(normalized) ||
439
- normalized.role !== "assistant"
440
- ) {
441
- throw new Error("inflight assistant must be an assistant UIMessage");
442
- }
443
- const file = this.getInflightFilePath();
444
- const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
445
- await fs.ensureDir(path.dirname(file));
446
- await fs.writeJson(temp, normalized, { spaces: 2 });
447
- await fs.move(temp, file, { overwrite: true });
448
- }
449
-
450
- private async removeInflightUnsafe(): Promise<void> {
451
- await fs.remove(this.getInflightFilePath());
452
- }
453
-
454
- private async appendMessageUnsafe(message: SessionRecordV1): Promise<void> {
455
- await fs.appendFile(
456
- this.getMessagesFilePath(),
457
- JSON.stringify(message) + "\n",
458
- "utf8",
459
- );
460
- }
461
-
462
- private async get_history_bytes_unsafe(): Promise<number> {
463
- try {
464
- const file_stat = await statNative(this.getMessagesFilePath());
465
- return file_stat.size;
466
- } catch {
467
- return 0;
468
- }
469
- }
470
-
471
- private async read_persisted_records_unsafe(): Promise<SessionRecordV1[]> {
472
- const raw = await fs.readFile(this.getMessagesFilePath(), "utf8").catch(() => "");
473
- const records: SessionRecordV1[] = [];
474
- for (const line of raw.split("\n").filter(Boolean)) {
475
- try {
476
- const record = this.normalizePersistedMessage(JSON.parse(line));
477
- if (record) records.push(record);
478
- } catch {
479
- // 关键点(中文):摘要重建跳过损坏行,与正式历史读取语义保持一致。
480
- }
481
- }
482
- return records;
483
- }
484
-
485
- private async write_history_summary_unsafe(
486
- records: SessionRecordV1[],
487
- ): Promise<void> {
488
- const current = await this.readMetaUnsafe();
489
- const last_record = records[records.length - 1];
490
- const preview_text = last_record
491
- ? resolve_session_message_preview(last_record).slice(0, 180).trim()
492
- : "";
493
- const { previewText: _previous_preview, ...metadata_without_preview } = current;
494
- void _previous_preview;
495
- await this.writeMetaUnsafe({
496
- ...metadata_without_preview,
497
- updatedAt: Date.now(),
498
- messageCount: records.length,
499
- historyBytes: await this.get_history_bytes_unsafe(),
500
- ...(preview_text ? { previewText: preview_text } : {}),
501
- });
502
- }
503
-
504
- private async update_history_summary_after_append_unsafe(input: {
505
- /** 本次追加前 messages.jsonl 的字节长度。 */
506
- previous_history_bytes: number;
507
- /** 本次实际追加的 records,按写入顺序排列。 */
508
- appended_records: SessionRecordV1[];
509
- }): Promise<void> {
510
- if (input.appended_records.length === 0) return;
511
- const current = await this.readMetaUnsafe();
512
- const previous_message_count = current.messageCount;
513
- if (
514
- current.historyBytes !== input.previous_history_bytes ||
515
- typeof previous_message_count !== "number"
516
- ) {
517
- await this.write_history_summary_unsafe(
518
- await this.read_persisted_records_unsafe(),
519
- );
520
- return;
521
- }
522
-
523
- const last_record = input.appended_records[input.appended_records.length - 1];
524
- const preview_text = resolve_session_message_preview(last_record)
525
- .slice(0, 180)
526
- .trim();
527
- const { previewText: _previous_preview, ...metadata_without_preview } = current;
528
- void _previous_preview;
529
- await this.writeMetaUnsafe({
530
- ...metadata_without_preview,
531
- updatedAt: Date.now(),
532
- messageCount: previous_message_count + input.appended_records.length,
533
- historyBytes: await this.get_history_bytes_unsafe(),
534
- ...(preview_text ? { previewText: preview_text } : {}),
535
- });
536
- }
537
-
538
- private async rewriteMessagesUnsafe(messages: SessionRecordV1[]): Promise<void> {
539
- const file = this.getMessagesFilePath();
540
- const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
541
- const payload =
542
- messages.length > 0
543
- ? messages.map((message) => JSON.stringify(message)).join("\n") + "\n"
544
- : "";
545
- await fs.writeFile(temp, payload, "utf8");
546
- await fs.move(temp, file, { overwrite: true });
547
- }
548
-
549
- private async upsert_action_record_unsafe(
550
- message: SessionActionRecordV1,
551
- ): Promise<SessionRecordV1[]> {
552
- const file = this.getMessagesFilePath();
553
- const raw = await fs.readFile(file, "utf8").catch(() => "");
554
- const messages: SessionRecordV1[] = [];
555
- let replaced = false;
556
-
557
- for (const line of raw.split("\n").filter(Boolean)) {
558
- try {
559
- const current = this.normalizePersistedMessage(JSON.parse(line));
560
- if (!current) continue;
561
- if (is_session_action_record(current) && current.id === message.id) {
562
- messages.push(message);
563
- replaced = true;
564
- continue;
565
- }
566
- messages.push(current);
567
- } catch {
568
- // 关键点(中文):重写 action 时顺手跳过损坏行,避免坏 JSON 阻断状态更新。
569
- }
570
- }
571
-
572
- if (!replaced) messages.push(message);
573
- await this.rewriteMessagesUnsafe(messages);
574
- return messages;
575
- }
576
-
577
- private async withWriteLock<T>(fn: () => Promise<T>): Promise<T> {
578
- await this.ensureLayout();
579
- const lockPath = this.getLockFilePath();
580
- const token = `${process.pid}:${Date.now()}:${generateId()}`;
581
- const logger = getLogger(this.rootPath, "info");
582
-
583
- // 关键点(中文):append 与 compact 共用同一把文件锁,防止 rewrite 覆盖 append。
584
- const staleMs = 30_000;
585
- const start = Date.now();
586
- while (true) {
587
- try {
588
- const fh = await openFile(lockPath, "wx");
589
- await fh.writeFile(token, "utf8");
590
- await fh.close();
591
- break;
592
- } catch (error) {
593
- const err = error as NodeJS.ErrnoException;
594
- if (err.code !== "EEXIST") throw err;
595
- try {
596
- const stat = await statNative(lockPath);
597
- const age = Date.now() - stat.mtimeMs;
598
- if (age > staleMs) {
599
- await fs.remove(lockPath);
600
- await logger.log("warn", "Removed stale session lock", {
601
- sessionId: this.sessionId,
602
- lockPath,
603
- ageMs: age,
604
- });
605
- continue;
606
- }
607
- } catch {
608
- // ignore
609
- }
610
- if (Date.now() - start > staleMs * 2) {
611
- throw new Error(`Context lock timeout: ${lockPath}`);
612
- }
613
- await new Promise((resolve) => setTimeout(resolve, 60));
614
- }
615
- }
616
-
617
- try {
618
- return await fn();
619
- } finally {
620
- try {
621
- const current = await readFileNative(lockPath, "utf8");
622
- if (String(current || "").trim() === token) {
623
- await fs.remove(lockPath);
624
- }
625
- } catch {
626
- // ignore
627
- }
628
- }
629
- }
630
-
631
- private normalizeSystem(system: SessionSystemMessage[]): SessionSystemMessage[] {
632
- if (!Array.isArray(system)) return [];
633
- return system.filter((item) => item && typeof item === "object");
634
- }
635
-
636
- async compact(input: SessionHistoryCompactInput): Promise<{
637
- compacted: boolean;
638
- reason?: string;
639
- }> {
640
- return await compactSessionMessagesIfNeeded(
641
- {
642
- rootPath: this.rootPath,
643
- sessionId: this.sessionId,
644
- withWriteLock: (fn) => this.withWriteLock(fn),
645
- loadAll: () => this.list_records(),
646
- createSummaryMessage: ({ text, archiveId, sourceRange }) => ({
647
- id: `a:${this.sessionId}:${generateId()}`,
648
- role: "assistant",
649
- metadata: {
650
- v: 1,
651
- ts: Date.now(),
652
- sessionId: this.sessionId,
653
- source: "compact",
654
- kind: "summary",
655
- ...(archiveId ? { archiveId } : {}),
656
- ...(sourceRange ? { sourceRange } : {}),
657
- },
658
- parts: [{ type: "text", text: String(text ?? "") }],
659
- }),
660
- getArchiveDirPath: () => this.getArchiveDirPath(),
661
- getMessagesFilePath: () => this.getMessagesFilePath(),
662
- writeHistorySummaryUnsafe: (records) =>
663
- this.write_history_summary_unsafe(records),
664
- },
665
- {
666
- model: input.model,
667
- system: this.normalizeSystem(input.system),
668
- archiveOnCompact: false,
669
- force: input.force,
670
- ...(input.onAction ? { onAction: input.onAction } : {}),
671
- },
672
- );
673
- }
674
-
675
- async write_record(message: SessionRecordV1): Promise<void> {
676
- await this.withWriteLock(async () => {
677
- const normalized = this.normalizePersistedMessage(message);
678
- if (!normalized) return;
679
- if (is_session_action_record(normalized)) {
680
- const records = await this.upsert_action_record_unsafe(normalized);
681
- await this.write_history_summary_unsafe(records);
682
- return;
683
- }
684
-
685
- const previous_history_bytes = await this.get_history_bytes_unsafe();
686
- const appended_records: SessionRecordV1[] = [];
687
-
688
- // 关键点(中文):若上一次 assistant 在运行中中断,新的 user 到来前先把残留快照收口到正式历史,
689
- // 避免 `list_records()` 时旧 inflight 跑到新 user 后面,打乱时序。
690
- if (is_session_message_record(normalized) && normalized.role === "user") {
691
- const current_inflight = await this.read_inflight_unsafe();
692
- if (current_inflight) {
693
- await this.appendMessageUnsafe(current_inflight);
694
- appended_records.push(current_inflight);
695
- await this.removeInflightUnsafe();
696
- }
697
- }
698
-
699
- await this.appendMessageUnsafe(normalized);
700
- appended_records.push(normalized);
701
- await this.update_history_summary_after_append_unsafe({
702
- previous_history_bytes,
703
- appended_records,
704
- });
705
- });
706
- }
707
-
708
- /**
709
- * 批量追加消息。
710
- *
711
- * 关键点(中文)
712
- * - 一次锁、一次 IO,适合 fork 等需要拷贝整段历史的场景。
713
- * - 不处理 inflight,调用方需自行确保历史已经收口。
714
- */
715
- async write_records(messages: SessionRecordV1[]): Promise<void> {
716
- if (!Array.isArray(messages) || messages.length === 0) return;
717
- const normalized_list = messages
718
- .map((message) => this.normalizePersistedMessage(message))
719
- .filter((message): message is SessionRecordV1 => message !== null);
720
- if (normalized_list.length === 0) return;
721
-
722
- const payload = normalized_list
723
- .map((message) => `${JSON.stringify(message)}\n`)
724
- .join("");
725
- await this.withWriteLock(async () => {
726
- const previous_history_bytes = await this.get_history_bytes_unsafe();
727
- await fs.appendFile(this.getMessagesFilePath(), payload, "utf8");
728
- await this.update_history_summary_after_append_unsafe({
729
- previous_history_bytes,
730
- appended_records: normalized_list,
731
- });
732
- });
733
- }
734
-
735
- async read_inflight(): Promise<SessionRecordV1 | null> {
736
- await this.ensureLayout();
737
- return this.read_inflight_unsafe();
738
- }
739
-
740
- async write_inflight(message: SessionRecordV1): Promise<void> {
741
- await this.withWriteLock(async () => {
742
- await this.write_inflight_unsafe(message);
743
- });
744
- }
745
-
746
- async finalize_inflight(message?: SessionRecordV1 | null): Promise<void> {
747
- await this.withWriteLock(async () => {
748
- const previous_history_bytes = await this.get_history_bytes_unsafe();
749
- const current_inflight = await this.read_inflight_unsafe();
750
- const normalized_message = this.normalizePersistedMessage(message);
751
- const final_message =
752
- current_inflight && normalized_message
753
- ? this.mergeInflightWithFinal(current_inflight, normalized_message)
754
- : normalized_message || current_inflight;
755
- if (final_message) {
756
- await this.appendMessageUnsafe(final_message);
757
- }
758
- if (current_inflight) {
759
- await this.removeInflightUnsafe();
760
- }
761
- if (final_message) {
762
- await this.update_history_summary_after_append_unsafe({
763
- previous_history_bytes,
764
- appended_records: [final_message],
765
- });
766
- }
767
- });
768
- }
769
-
770
- async list_records(): Promise<SessionRecordV1[]> {
771
- await this.ensureLayout();
772
- const file = this.getMessagesFilePath();
773
- const raw = await fs.readFile(file, "utf8");
774
- const lines = raw.split("\n").filter(Boolean);
775
- const out: SessionRecordV1[] = [];
776
- for (const line of lines) {
777
- try {
778
- const obj = this.normalizePersistedMessage(JSON.parse(line));
779
- if (!obj) continue;
780
- out.push(obj);
781
- } catch {
782
- // ignore invalid lines
783
- }
784
- }
785
- const current_inflight = await this.read_inflight_unsafe();
786
- if (current_inflight) {
787
- out.push(current_inflight);
788
- }
789
- return out;
790
- }
791
-
792
- async slice_records(start: number, end: number): Promise<SessionRecordV1[]> {
793
- const msgs = await this.list_records();
794
- const startIndex = Math.max(0, Math.floor(start));
795
- const endIndex = Math.max(startIndex, Math.floor(end));
796
- return msgs.slice(startIndex, endIndex);
797
- }
798
-
799
- async record_count(): Promise<number> {
800
- const msgs = await this.list_records();
801
- return msgs.length;
802
- }
803
-
804
- async meta(): Promise<Record<string, unknown>> {
805
- await this.ensureLayout();
806
- const metadata = await this.readMetaUnsafe();
807
- return (
808
- metadata && typeof metadata === "object" ? { ...metadata } : {}
809
- ) as Record<string, unknown>;
810
- }
811
-
812
- userText(input: {
813
- text: string;
814
- metadata: Omit<SessionMetadataV1, "v" | "ts"> &
815
- Partial<Pick<SessionMetadataV1, "ts">>;
816
- id?: string;
817
- }): SessionRecordV1 {
818
- const { ts, ...metadata } = input.metadata;
819
- const md: SessionMetadataV1 = {
820
- v: 1,
821
- ts: typeof ts === "number" ? ts : Date.now(),
822
- ...metadata,
823
- source: "ingress",
824
- kind: "normal",
825
- };
826
- const id = input.id || `u:${this.sessionId}:${generateId()}`;
827
- return {
828
- id,
829
- role: "user",
830
- metadata: md,
831
- parts: [{ type: "text", text: String(input.text ?? "") }],
832
- };
833
- }
834
-
835
- assistantText(input: {
836
- text: string;
837
- metadata: Omit<SessionMetadataV1, "v" | "ts"> &
838
- Partial<Pick<SessionMetadataV1, "ts">>;
839
- id?: string;
840
- kind?: "normal" | "summary";
841
- source?: "egress" | "compact";
842
- }): SessionRecordV1 {
843
- const { ts, ...metadata } = input.metadata;
844
- const md: SessionMetadataV1 = {
845
- v: 1,
846
- ts: typeof ts === "number" ? ts : Date.now(),
847
- ...metadata,
848
- source: input.source || "egress",
849
- kind: input.kind || "normal",
850
- };
851
- const id = input.id || `a:${this.sessionId}:${generateId()}`;
852
- return {
853
- id,
854
- role: "assistant",
855
- metadata: md,
856
- parts: [{ type: "text", text: String(input.text ?? "") }],
857
- };
858
- }
859
-
860
- action(input: {
861
- action: SessionActionRecordV1;
862
- metadata: Pick<SessionMetadataV1, "sessionId"> &
863
- Partial<Pick<SessionMetadataV1, "ts">>;
864
- id?: string;
865
- }): SessionActionRecordV1 {
866
- const { ts, ...metadata } = input.metadata;
867
- const message = to_session_action_record(
868
- input.id ? { ...input.action, id: input.id } : input.action,
869
- metadata.sessionId || this.sessionId,
870
- );
871
- return {
872
- ...message,
873
- metadata: {
874
- ...message.metadata,
875
- ts: typeof ts === "number" ? ts : message.metadata.ts,
876
- },
877
- };
878
- }
879
- }