@downcity/agent 1.1.430 → 1.1.437

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
@@ -6,15 +6,16 @@
6
6
  * - 不把调度逻辑塞进 Executor;Executor 继续只负责单次执行。
7
7
  * - Queue 由 Session 持有;这里不解释配置种类,只执行出队 Command。
8
8
  */
9
+ import { createHash } from "node:crypto";
9
10
  import { nanoid } from "nanoid";
10
11
  import { is_agent_session_prompt_input_empty } from "../types/sdk/AgentSessionPrompt.js";
11
12
  import { create_session_turn_context } from "../session/runtime/SessionTurnContext.js";
13
+ import { normalize_session_user_parts, } from "../session/SessionMessages.js";
12
14
  import { SessionAssistantOutputAdapter } from "../session/execution/SessionAssistantOutputAdapter.js";
13
- import { SessionCommand } from "../session/SessionCommand.js";
14
- import { SESSION_TURN_FILE_DIFF_DATA_TYPE } from "../session/messages/SessionTurnFileDiffData.js";
15
- import { build_session_turn_file_diff, build_session_turn_file_diff_summary, } from "../session/messages/SessionTurnFileDiffBuilder.js";
16
- import { SESSION_HOOK_POINTS } from "../session/SessionHookPoints.js";
15
+ import { extract_session_message_text } from "../session/messages/SessionMessageText.js";
17
16
  import { create_session_model_request_warning } from "../session/runtime/SessionModelRequestWarning.js";
17
+ import { complete_session_turn, fail_session_turn, } from "../session/runtime/SessionTurnCompletion.js";
18
+ import { append_session_turn_file_diff, publish_session_turn_file_diff, } from "../session/runtime/SessionTurnFileDiff.js";
18
19
  const TURN_STOPPED_MESSAGE = "Turn stopped";
19
20
  const QUEUED_PROMPT_CANCELLED_MESSAGE = "Prompt cancelled because session was stopped";
20
21
  /**
@@ -25,7 +26,7 @@ export class SessionLoop {
25
26
  session_origin;
26
27
  workspace_path;
27
28
  executor;
28
- compact_history_handler;
29
+ maintain_context;
29
30
  state;
30
31
  messages;
31
32
  events;
@@ -36,13 +37,14 @@ export class SessionLoop {
36
37
  pending_prompt_count = 0;
37
38
  processing_promise = null;
38
39
  active_turn = null;
39
- checkpoint_merged_messages = null;
40
+ /** 尚未完成 canonical 接收的幂等 Prompt,防止进程内并发重复入队。 */
41
+ pending_request_handles = new Map();
40
42
  constructor(options) {
41
43
  this.session_id = String(options.session_id || "").trim();
42
44
  this.session_origin = options.session_origin;
43
45
  this.workspace_path = String(options.workspace_path || "").trim();
44
46
  this.executor = options.executor;
45
- this.compact_history_handler = options.compact_history;
47
+ this.maintain_context = options.maintain_context;
46
48
  this.state = options.state;
47
49
  this.messages = options.messages;
48
50
  this.events = options.events;
@@ -65,20 +67,55 @@ export class SessionLoop {
65
67
  throw new Error("session.prompt requires a non-empty query");
66
68
  }
67
69
  await this.state.ensure_runnable();
70
+ const request_identity = resolve_prompt_request_identity(this.session_id, input.request_id);
71
+ if (!request_identity)
72
+ return await this.enqueue_prompt(input);
73
+ const pending_handle = this.pending_request_handles.get(request_identity.turn_id);
74
+ if (pending_handle)
75
+ return await pending_handle;
76
+ const operation = this.prompt_with_identity(input, request_identity);
77
+ this.pending_request_handles.set(request_identity.turn_id, operation);
78
+ try {
79
+ return await operation;
80
+ }
81
+ finally {
82
+ if (this.pending_request_handles.get(request_identity.turn_id) === operation) {
83
+ this.pending_request_handles.delete(request_identity.turn_id);
84
+ }
85
+ }
86
+ }
87
+ /** 解析已有幂等结果,或把同一个稳定 Prompt 加入队列。 */
88
+ async prompt_with_identity(input, request_identity) {
89
+ const existing_handle = await this.resolve_idempotent_prompt(request_identity);
90
+ if (existing_handle)
91
+ return existing_handle;
92
+ const persisted_message = this.messages.get_message(request_identity.message_id);
93
+ return await this.enqueue_prompt(input, request_identity, persisted_message?.role === "user"
94
+ ? persisted_message
95
+ : undefined);
96
+ }
97
+ /** 把一个已校验的 Prompt 加入 Session FIFO。 */
98
+ async enqueue_prompt(input, request_identity, persisted_message) {
68
99
  const deferred_handle = create_deferred();
69
100
  this.pending_prompt_count += 1;
70
- this.queue.enqueue_command(new SessionCommand({
101
+ this.enqueue_command({
102
+ kind: "prompt",
103
+ ...(request_identity ? { turn_id: request_identity.turn_id } : {}),
71
104
  execute: async () => {
72
- await this.execute_prompt_command(input, deferred_handle);
105
+ await this.execute_prompt_command(input, deferred_handle, request_identity?.message_id, persisted_message);
73
106
  },
74
107
  cancel: () => {
75
108
  this.pending_prompt_count = Math.max(0, this.pending_prompt_count - 1);
76
109
  this.resolve_cancelled_prompt(deferred_handle);
77
110
  },
78
- }));
79
- this.ensure_processing();
111
+ });
80
112
  return await deferred_handle.promise;
81
113
  }
114
+ /** 追加 Command,并确保空闲 Session 也会主动消费维护操作。 */
115
+ enqueue_command(command) {
116
+ this.queue.enqueue_command(command);
117
+ this.ensure_processing();
118
+ }
82
119
  /**
83
120
  * 判断是否存在等待并入下一 Session step 的 prompt。
84
121
  */
@@ -107,7 +144,7 @@ export class SessionLoop {
107
144
  * - Session 会用它阻止内部 direct execution 与 actor 模式并发混用。
108
145
  */
109
146
  is_active() {
110
- return this.processing_promise !== null || this.has_pending_prompt();
147
+ return this.processing_promise !== null || this.has_pending_command();
111
148
  }
112
149
  /**
113
150
  * 停止当前 turn,并取消尚未被吸收的排队 prompt。
@@ -131,14 +168,21 @@ export class SessionLoop {
131
168
  return;
132
169
  this.processing_promise = this.process_loop().finally(() => {
133
170
  this.processing_promise = null;
134
- if (this.has_pending_prompt()) {
171
+ if (this.has_pending_command()) {
135
172
  this.ensure_processing();
136
173
  }
137
174
  });
138
175
  }
139
176
  async process_loop() {
140
- while (this.has_pending_prompt()) {
141
- const turn_id = `turn:${this.session_id}:${Date.now()}:${nanoid(6)}`;
177
+ while (this.has_pending_command()) {
178
+ const command = this.queue.take_next();
179
+ if (!command)
180
+ return;
181
+ if (command.kind === "maintenance") {
182
+ await this.execute_maintenance_command(command);
183
+ continue;
184
+ }
185
+ const turn_id = command.turn_id || `turn:${this.session_id}:${Date.now()}:${nanoid(6)}`;
142
186
  const active_turn = create_active_session_turn_state(turn_id);
143
187
  this.active_turn = active_turn;
144
188
  active_turn.turn_context = this.create_turn_context(active_turn);
@@ -151,18 +195,28 @@ export class SessionLoop {
151
195
  status: "running",
152
196
  created_at: Date.now(),
153
197
  });
154
- while (this.active_turn === active_turn) {
155
- const command = this.queue.take_next();
156
- if (!command) {
157
- await this.fail_active_turn(active_turn, new Error("Session Queue lost its pending Prompt Command"));
158
- break;
159
- }
160
- try {
161
- await this.execute_command(command);
162
- }
163
- catch (error) {
164
- await this.fail_active_turn(active_turn, error);
165
- }
198
+ try {
199
+ await this.execute_command(command);
200
+ }
201
+ catch (error) {
202
+ await this.fail_active_turn(active_turn, error);
203
+ }
204
+ }
205
+ }
206
+ /** 在没有 Active Turn 时执行 Session 级维护命令。 */
207
+ async execute_maintenance_command(command) {
208
+ try {
209
+ await this.execute_command(command);
210
+ }
211
+ catch (error) {
212
+ try {
213
+ await this.logger.log("warn", "[agent] session maintenance command failed", {
214
+ session_id: this.session_id,
215
+ error: error instanceof Error ? error.message : String(error),
216
+ });
217
+ }
218
+ catch {
219
+ // Maintenance Command 已经失败,日志失败不能阻止后续 Command 继续执行。
166
220
  }
167
221
  }
168
222
  }
@@ -172,45 +226,38 @@ export class SessionLoop {
172
226
  /**
173
227
  * 在下一 Session step 检查点按入队顺序提交配置并持久化 steer。
174
228
  */
175
- async drain_queued_inputs(active_turn) {
229
+ async drain_queued_inputs() {
176
230
  const drained = this.queue.drain();
177
231
  if (drained.length <= 0)
178
- return [];
179
- const merged = [];
180
- this.checkpoint_merged_messages = merged;
181
- try {
182
- for (let index = 0; index < drained.length; index += 1) {
183
- const command = drained[index];
184
- try {
185
- await this.execute_command(command);
186
- }
187
- catch {
188
- // Prompt 持久化失败时恢复尚未处理的对象;Action 自己负责失败观测。
189
- this.queue.restore_front(drained.slice(index));
190
- break;
191
- }
232
+ return;
233
+ for (let index = 0; index < drained.length; index += 1) {
234
+ const command = drained[index];
235
+ try {
236
+ await this.execute_command(command);
237
+ }
238
+ catch {
239
+ // Prompt 持久化失败时恢复尚未处理的对象;Action 自己负责失败观测。
240
+ this.queue.restore_front(drained.slice(index));
241
+ break;
192
242
  }
193
243
  }
194
- finally {
195
- this.checkpoint_merged_messages = null;
196
- }
197
- return merged;
198
244
  }
199
245
  /** 执行 Command,并尽力持久化其声明的 canonical 完成信息。 */
200
246
  async execute_command(command) {
201
- const completion = await command.execute();
247
+ await command.execute();
248
+ const completion = command.completion;
202
249
  if (!completion)
203
250
  return;
204
251
  await this.persist_command_completion(completion);
205
252
  }
206
253
  /** 持久化 Command 完成信息;观测失败不能反向改变已经提交的领域状态。 */
207
254
  async persist_command_completion(completion) {
208
- const turn_id = this.require_active_turn().turn_id;
255
+ const turn_id = this.current_turn_id();
209
256
  try {
210
257
  await this.persist_action_event({
211
258
  action_id: completion.id,
212
259
  action_type: "command",
213
- turn_id,
260
+ ...(turn_id ? { turn_id } : {}),
214
261
  title: completion.title,
215
262
  ...(completion.description
216
263
  ? { description: completion.description }
@@ -233,63 +280,32 @@ export class SessionLoop {
233
280
  }
234
281
  }
235
282
  }
236
- /** 在当前 Turn 上执行一次显式历史压缩。 */
237
- async compact_history(compact_id) {
238
- const turn_id = this.require_active_turn().turn_id;
239
- const result = await this.compact_history_handler({ turn_id });
240
- if (result.compacted &&
241
- this.active_turn?.turn_context) {
242
- this.require_active_turn().history_reload_requested = true;
243
- }
244
- if (result.reason === "nothing_to_compact") {
245
- try {
246
- await this.persist_action_event({
247
- action_id: compact_id,
248
- action_type: "history-compaction",
249
- turn_id,
250
- title: "Session messages already compact",
251
- description: "The Session has no active messages to compact.",
252
- status: "completed",
253
- });
254
- }
255
- catch (error) {
256
- try {
257
- await this.logger.log("warn", "[agent] compact result persistence failed", {
258
- session_id: this.session_id,
259
- compact_id,
260
- error: error instanceof Error ? error.message : String(error),
261
- });
262
- }
263
- catch {
264
- // 领域结果已经确定,Action 与日志失败都不能把成功压缩改写为失败。
265
- }
266
- }
267
- }
268
- return result;
269
- }
270
283
  /** 执行一个出队 Prompt;首条 Prompt 启动 Turn,后续 Prompt 作为 steer 合并。 */
271
- async execute_prompt_command(input, deferred_handle) {
284
+ async execute_prompt_command(input, deferred_handle, message_id, persisted_message) {
272
285
  const active_turn = this.require_active_turn();
273
286
  if (active_turn.prompt_started) {
274
- const message = await this.persist_prompt_message(input, active_turn.turn_id, "steer");
287
+ const message = await this.persist_prompt_message(input, active_turn.turn_id);
288
+ active_turn.turn_context?.input.observe_user_message(message);
275
289
  this.pending_prompt_count = Math.max(0, this.pending_prompt_count - 1);
276
290
  deferred_handle.resolve(create_turn_handle(active_turn));
277
- this.checkpoint_merged_messages?.push(message);
278
291
  return;
279
292
  }
280
293
  active_turn.prompt_started = true;
281
294
  this.pending_prompt_count = Math.max(0, this.pending_prompt_count - 1);
282
295
  let handle_resolved = false;
283
296
  try {
284
- await this.persist_prompt_message(input, active_turn.turn_id, "prompt");
297
+ const message = persisted_message || await this.persist_prompt_message(input, active_turn.turn_id, message_id);
298
+ active_turn.turn_context?.input.observe_user_message(message);
285
299
  // 只有 canonical user message 已经写入 Session 后,调用方才认为输入被接收。
286
300
  deferred_handle.resolve(create_turn_handle(active_turn));
287
301
  handle_resolved = true;
288
302
  const result = await this.execute_prompt_turn({
289
303
  active_turn,
290
- prompt_input: input,
291
304
  });
292
- await this.finish_active_turn(active_turn, result);
305
+ const final_result = await complete_session_turn(this.turn_completion_options(), active_turn, result);
306
+ if (this.active_turn === active_turn)
307
+ this.active_turn = null;
308
+ active_turn.deferred_finished.resolve(final_result);
293
309
  }
294
310
  catch (error) {
295
311
  // 持久化失败时仍兑现句柄,让调用方可以观察到失败的 Turn,而不是永久等待。
@@ -304,80 +320,12 @@ export class SessionLoop {
304
320
  return this.active_turn;
305
321
  throw new Error("Session Command requires an active Turn");
306
322
  }
307
- /** Executor 结果结束当前 Active Turn。 */
308
- async finish_active_turn(active_turn, result) {
309
- const stopped = active_turn.turn_context?.lifecycle.abort_signal.aborted === true;
310
- const final_result = {
311
- turn_id: active_turn.turn_id,
312
- text: result.text,
313
- success: stopped ? false : result.success,
314
- ...(stopped
315
- ? { error: TURN_STOPPED_MESSAGE }
316
- : result.error ? { error: result.error } : {}),
317
- };
318
- active_turn.result = final_result;
319
- this.events.publish({
320
- mutation_id: nanoid(),
321
- variant: "turn",
322
- type: "finish",
323
- session_id: this.session_id,
324
- turn_id: active_turn.turn_id,
325
- status: stopped ? "stopped" : final_result.success ? "completed" : "failed",
326
- created_at: Date.now(),
327
- text: final_result.text,
328
- ...(final_result.error ? { error: final_result.error } : {}),
329
- });
330
- await this.notify_turn_committed(active_turn, stopped ? "stopped" : final_result.success ? "completed" : "failed");
331
- await this.dispose_turn_context(active_turn);
332
- active_turn.deferred_finished.resolve(final_result);
333
- if (this.active_turn === active_turn)
334
- this.active_turn = null;
335
- }
336
- /** 以失败结果结束当前 Active Turn,并尽力持久化 Error Message。 */
323
+ /** 以失败结果结束当前 Active Turn,并尽力持久化包含 Error Part 的 Agent Message。 */
337
324
  async fail_active_turn(active_turn, error) {
338
- if (active_turn.result)
339
- return;
340
- const stopped = active_turn.turn_context?.lifecycle.abort_signal.aborted === true;
341
- const message = stopped
342
- ? TURN_STOPPED_MESSAGE
343
- : error instanceof Error ? error.message : String(error);
344
- const final_result = {
345
- turn_id: active_turn.turn_id,
346
- text: "",
347
- success: false,
348
- error: message,
349
- };
350
- active_turn.result = final_result;
351
- if (message !== TURN_STOPPED_MESSAGE) {
352
- try {
353
- await this.messages.append_error_message({
354
- scope: "turn",
355
- turn_id: active_turn.turn_id,
356
- code: "turn_execution_failed",
357
- message,
358
- recoverable: true,
359
- });
360
- }
361
- catch {
362
- // Error Message 写入失败不能阻止 Turn Handle 收口。
363
- }
364
- }
365
- this.events.publish({
366
- mutation_id: nanoid(),
367
- variant: "turn",
368
- type: "finish",
369
- session_id: this.session_id,
370
- turn_id: active_turn.turn_id,
371
- status: stopped ? "stopped" : "failed",
372
- created_at: Date.now(),
373
- text: "",
374
- error: message,
375
- });
376
- await this.notify_turn_committed(active_turn, stopped ? "stopped" : "failed");
377
- await this.dispose_turn_context(active_turn);
378
- active_turn.deferred_finished.resolve(final_result);
325
+ const final_result = await fail_session_turn(this.turn_completion_options(), active_turn, error);
379
326
  if (this.active_turn === active_turn)
380
327
  this.active_turn = null;
328
+ active_turn.deferred_finished.resolve(final_result);
381
329
  }
382
330
  /** 为一条尚未执行的 Prompt 创建可观测取消结果。 */
383
331
  resolve_cancelled_prompt(deferred_handle) {
@@ -420,34 +368,33 @@ export class SessionLoop {
420
368
  if (!turn_context || !assistant_output) {
421
369
  throw new Error("Active Session Turn requires an initialized context");
422
370
  }
423
- const query = input.prompt_input.query;
424
- const executor_query = typeof query === "string"
425
- ? query
426
- : query
427
- .flatMap((part) => part.type === "text" ? [part.text] : [])
428
- .join("\n")
429
- .trim();
430
371
  let result;
431
372
  try {
432
- result = await this.executor.execute({
433
- query: executor_query,
434
- turn_context,
435
- });
373
+ result = await this.executor.execute({ turn_context });
436
374
  }
437
375
  catch (error) {
438
- await this.append_turn_file_diff(input.active_turn.turn_id, turn_context, assistant_output);
439
- try {
440
- await assistant_output.finish({
441
- status: turn_context.lifecycle.abort_signal.aborted ? "stopped" : "failed",
442
- error: error instanceof Error ? error.message : String(error),
443
- });
444
- }
445
- catch (finish_error) {
446
- await this.log_file_diff_warning(input.active_turn.turn_id, "failed to close Assistant output after execution error", finish_error);
447
- }
448
- throw error;
376
+ result = {
377
+ text: "",
378
+ success: false,
379
+ error: error instanceof Error ? error.message : String(error),
380
+ };
449
381
  }
450
- await this.append_turn_file_diff(input.active_turn.turn_id, turn_context, assistant_output);
382
+ if (!result.success && !turn_context.lifecycle.abort_signal.aborted && result.error) {
383
+ await assistant_output.append_error({
384
+ scope: "turn",
385
+ code: "turn_execution_failed",
386
+ message: result.error,
387
+ recoverable: true,
388
+ });
389
+ }
390
+ await append_session_turn_file_diff({
391
+ session_id: this.session_id,
392
+ turn_id: input.active_turn.turn_id,
393
+ workspace_path: this.workspace_path,
394
+ turn_context,
395
+ assistant_output,
396
+ logger: this.logger,
397
+ });
451
398
  await assistant_output.finish({
452
399
  status: turn_context.lifecycle.abort_signal.aborted
453
400
  ? "stopped"
@@ -456,23 +403,8 @@ export class SessionLoop {
456
403
  : "failed",
457
404
  ...(result.error ? { error: result.error } : {}),
458
405
  });
459
- if (!result.success && !turn_context.lifecycle.abort_signal.aborted && result.error) {
460
- await this.messages.append_error_message({
461
- scope: "turn",
462
- turn_id: input.active_turn.turn_id,
463
- code: "turn_execution_failed",
464
- message: result.error,
465
- recoverable: true,
466
- });
467
- }
468
- await this.state.touch_metadata();
469
- const deferred_count = await this.messages.append_deferred_user_messages(result.deferred_persisted_user_messages);
470
- if (deferred_count > 0)
471
- await this.state.touch_metadata();
472
406
  if (result.compact_required) {
473
- await this.compact_history_handler({
474
- turn_id: input.active_turn.turn_id,
475
- });
407
+ await this.maintain_context();
476
408
  }
477
409
  return {
478
410
  text: result.text,
@@ -480,46 +412,6 @@ export class SessionLoop {
480
412
  ...(result.error ? { error: result.error } : {}),
481
413
  };
482
414
  }
483
- /** 把当前 Turn 成功的结构化文件修改写入 canonical Assistant data part。 */
484
- async append_turn_file_diff(turn_id, turn_context, assistant_output) {
485
- try {
486
- const file_diff = build_session_turn_file_diff(this.workspace_path, turn_context.effects.snapshot());
487
- if (!file_diff)
488
- return;
489
- await assistant_output.append_result_parts([{
490
- type: "data",
491
- data_type: SESSION_TURN_FILE_DIFF_DATA_TYPE,
492
- data_id: `turn-file-diff:${turn_id}`,
493
- data: {
494
- files: file_diff.files.map((file) => ({
495
- file: file.file,
496
- status: file.status,
497
- additions: file.additions,
498
- deletions: file.deletions,
499
- patch: file.patch,
500
- })),
501
- additions: file_diff.additions,
502
- deletions: file_diff.deletions,
503
- },
504
- }]);
505
- }
506
- catch (error) {
507
- await this.log_file_diff_warning(turn_id, "failed to persist structured file edits", error);
508
- }
509
- }
510
- /** 文件修改展示属于辅助观测能力,失败不能改变 Turn 结果。 */
511
- async log_file_diff_warning(turn_id, message, error) {
512
- try {
513
- await this.logger.log("warn", `[agent] ${message}`, {
514
- session_id: this.session_id,
515
- turn_id,
516
- error: error instanceof Error ? error.message : String(error),
517
- });
518
- }
519
- catch {
520
- // 文件编辑观测失败不影响 canonical 对话执行。
521
- }
522
- }
523
415
  /** 在 Turn 创建时建立其唯一执行上下文和 Assistant 输出端口。 */
524
416
  create_turn_context(active_turn) {
525
417
  const assistant_output = new SessionAssistantOutputAdapter({
@@ -531,41 +423,34 @@ export class SessionLoop {
531
423
  session_id: this.session_id,
532
424
  session_origin: this.session_origin,
533
425
  project_root: this.workspace_path,
534
- merge_step_input: async () => {
535
- const merged = await this.drain_queued_inputs(active_turn);
536
- if (merged.length > 0)
426
+ commit_step_input: async () => {
427
+ const had_pending_prompt = this.has_pending_prompt();
428
+ await this.drain_queued_inputs();
429
+ if (had_pending_prompt)
537
430
  await assistant_output.close_current_message();
538
- return merged;
539
431
  },
540
- has_pending_step_input: () => this.has_pending_prompt(),
541
- consume_history_reload: () => {
542
- const requested = active_turn.history_reload_requested;
543
- active_turn.history_reload_requested = false;
544
- return requested;
432
+ append_internal_user_message: async (parts) => {
433
+ const message = await this.messages.append_user_message({
434
+ turn_id: active_turn.turn_id,
435
+ visibility: "internal",
436
+ parts: normalize_session_user_parts([...parts]),
437
+ });
438
+ active_turn.turn_context?.input.observe_user_message(message);
439
+ return message;
545
440
  },
441
+ has_pending_step_input: () => this.has_pending_prompt(),
546
442
  assistant_output,
547
443
  shell_approval_gateway: this.shell_approval_gateway,
548
444
  interactions: this.interactions,
549
445
  on_effects_changed: (effects) => {
550
- // Thinking 状态行的文件改动是辅助观测,失败不影响 Turn 结果。
551
- try {
552
- const summary = build_session_turn_file_diff_summary(this.workspace_path, effects);
553
- if (summary.files_count === 0)
554
- return;
555
- this.events.publish({
556
- mutation_id: nanoid(),
557
- variant: "file_diff",
558
- session_id: this.session_id,
559
- turn_id: active_turn.turn_id,
560
- created_at: Date.now(),
561
- files_count: summary.files_count,
562
- additions: summary.additions,
563
- deletions: summary.deletions,
564
- });
565
- }
566
- catch (error) {
567
- void this.log_file_diff_warning(active_turn.turn_id, "failed to publish live file edit summary", error);
568
- }
446
+ publish_session_turn_file_diff({
447
+ session_id: this.session_id,
448
+ turn_id: active_turn.turn_id,
449
+ workspace_path: this.workspace_path,
450
+ effects,
451
+ publish: (mutation) => this.events.publish(mutation),
452
+ logger: this.logger,
453
+ });
569
454
  },
570
455
  publish_action: async (event) => {
571
456
  await this.persist_action_event(event);
@@ -580,70 +465,45 @@ export class SessionLoop {
580
465
  });
581
466
  }
582
467
  /** 持久化本轮 User 输入,并同步刷新标题与 metadata。 */
583
- async persist_prompt_message(prompt, turn_id, input_type) {
468
+ async persist_prompt_message(prompt, turn_id, message_id) {
584
469
  const message = await this.messages.append_prompt_message({
585
470
  project_root: this.workspace_path,
586
471
  prompt,
587
472
  turn_id,
588
- input_type,
473
+ ...(message_id ? { message_id } : {}),
589
474
  });
590
- this.state.touch_metadata_in_background();
591
475
  this.state.schedule_title_generation();
592
476
  return message;
593
477
  }
478
+ /** 解析已经持久化或仍在执行的幂等 Prompt。 */
479
+ async resolve_idempotent_prompt(identity) {
480
+ const existing_message = this.messages.get_message(identity.message_id);
481
+ if (!existing_message)
482
+ return null;
483
+ if (existing_message.role !== "user" || existing_message.turn_id !== identity.turn_id) {
484
+ throw new Error("Session prompt request identity conflicts with canonical history");
485
+ }
486
+ if (this.active_turn?.turn_id === identity.turn_id) {
487
+ return create_turn_handle(this.active_turn);
488
+ }
489
+ const agent_message = await this.messages.read_latest_agent_message(identity.turn_id);
490
+ if (!agent_message || agent_message.state === "streaming")
491
+ return null;
492
+ return create_completed_turn_handle(to_persisted_turn_result(identity.turn_id, agent_message));
493
+ }
594
494
  /** 持久化 Executor Action,并同步刷新 Session metadata。 */
595
495
  async persist_action_event(event, options) {
596
496
  await this.messages.persist_action(event, options);
597
- await this.state.touch_metadata();
598
- }
599
- /** 由 Turn 生命周期所有者尽力释放其唯一 Context。 */
600
- async dispose_turn_context(active_turn) {
601
- try {
602
- await active_turn.turn_context?.lifecycle.dispose();
603
- }
604
- catch (error) {
605
- try {
606
- await this.logger.log("warn", "[agent] turn context disposal failed", {
607
- session_id: this.session_id,
608
- turn_id: active_turn.turn_id,
609
- error: error instanceof Error ? error.message : String(error),
610
- });
611
- }
612
- catch {
613
- // Context 已进入释放流程,日志失败不能阻止 Turn Handle 收口。
614
- }
615
- }
616
497
  }
617
- /** 在释放当前 lease 前触发现有 Plugin effect point。 */
618
- async notify_turn_committed(active_turn, status) {
619
- const extensions = active_turn.turn_context?.step.hooks;
620
- if (!extensions)
621
- return;
622
- try {
623
- const messages = (await this.messages.list_history_messages())
624
- .filter((message) => message.turn_id === active_turn.turn_id)
625
- .map((message) => structuredClone(message));
626
- const value = {
627
- session_id: this.session_id,
628
- turn_id: active_turn.turn_id,
629
- status,
630
- messages: messages,
631
- };
632
- await extensions.effect(SESSION_HOOK_POINTS.turn_committed, value);
633
- }
634
- catch (error) {
635
- try {
636
- await this.logger.log("warn", "[agent] session plugin effect failed", {
637
- session_id: this.session_id,
638
- turn_id: active_turn.turn_id,
639
- point_name: SESSION_HOOK_POINTS.turn_committed,
640
- error: error instanceof Error ? error.message : String(error),
641
- });
642
- }
643
- catch {
644
- // Plugin effect 不改变已经确定的 Turn 结果。
645
- }
646
- }
498
+ /** Turn 收口领域函数投影稳定依赖。 */
499
+ turn_completion_options() {
500
+ return {
501
+ session_id: this.session_id,
502
+ messages: this.messages,
503
+ events: this.events,
504
+ logger: this.logger,
505
+ stopped_message: TURN_STOPPED_MESSAGE,
506
+ };
647
507
  }
648
508
  }
649
509
  function create_deferred() {
@@ -662,7 +522,6 @@ function create_active_session_turn_state(turn_id) {
662
522
  result: null,
663
523
  deferred_finished: create_deferred(),
664
524
  turn_context: null,
665
- history_reload_requested: false,
666
525
  prompt_started: false,
667
526
  };
668
527
  }
@@ -675,4 +534,42 @@ function create_turn_handle(active_turn) {
675
534
  finished: active_turn.deferred_finished.promise,
676
535
  };
677
536
  }
537
+ /** 把调用方业务键映射为不暴露原值的 Session 内稳定身份。 */
538
+ function resolve_prompt_request_identity(session_id, request_id_input) {
539
+ const request_id = String(request_id_input || "").trim();
540
+ if (!request_id)
541
+ return null;
542
+ if (request_id.length > 512) {
543
+ throw new Error("session.prompt request_id must not exceed 512 characters");
544
+ }
545
+ const digest = createHash("sha256")
546
+ .update(session_id)
547
+ .update("\u0000")
548
+ .update(request_id)
549
+ .digest("hex");
550
+ return {
551
+ message_id: `user-request:${digest}`,
552
+ turn_id: `turn-request:${digest}`,
553
+ };
554
+ }
555
+ /** 从已完成的 canonical Agent Message 恢复 Turn 结果。 */
556
+ function to_persisted_turn_result(turn_id, message) {
557
+ const error_part = [...message.parts].reverse().find((part) => part.type === "error");
558
+ const error = error_part?.type === "error" ? error_part.message : undefined;
559
+ const success = !error;
560
+ return {
561
+ turn_id,
562
+ text: extract_session_message_text(message),
563
+ success,
564
+ ...(!success ? { error } : {}),
565
+ };
566
+ }
567
+ /** 为已经持久化完成的 Turn 创建立即兑现的句柄。 */
568
+ function create_completed_turn_handle(result) {
569
+ return {
570
+ id: result.turn_id,
571
+ result,
572
+ finished: Promise.resolve(result),
573
+ };
574
+ }
678
575
  //# sourceMappingURL=SessionLoop.js.map