@code-yeongyu/senpi 2026.8.26 → 2026.8.28-2

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 (335) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/README.md +3 -3
  3. package/dist/cli/args.d.ts +5 -1
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +18 -1
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/core/agent-session-services.d.ts.map +1 -1
  8. package/dist/core/agent-session-services.js +2 -0
  9. package/dist/core/agent-session-services.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +5 -0
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +11 -1
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/auth-storage.d.ts +1 -0
  15. package/dist/core/auth-storage.d.ts.map +1 -1
  16. package/dist/core/auth-storage.js +3 -0
  17. package/dist/core/auth-storage.js.map +1 -1
  18. package/dist/core/bash-executor.d.ts.map +1 -1
  19. package/dist/core/bash-executor.js +67 -29
  20. package/dist/core/bash-executor.js.map +1 -1
  21. package/dist/core/credential-accounts.d.ts +31 -0
  22. package/dist/core/credential-accounts.d.ts.map +1 -0
  23. package/dist/core/credential-accounts.js +135 -0
  24. package/dist/core/credential-accounts.js.map +1 -0
  25. package/dist/core/credential-pool/classify.d.ts +47 -0
  26. package/dist/core/credential-pool/classify.d.ts.map +1 -0
  27. package/dist/core/credential-pool/classify.js +92 -0
  28. package/dist/core/credential-pool/classify.js.map +1 -0
  29. package/dist/core/credential-pool/env-slots.d.ts +22 -0
  30. package/dist/core/credential-pool/env-slots.d.ts.map +1 -0
  31. package/dist/core/credential-pool/env-slots.js +37 -0
  32. package/dist/core/credential-pool/env-slots.js.map +1 -0
  33. package/dist/core/credential-pool/failover.d.ts +62 -0
  34. package/dist/core/credential-pool/failover.d.ts.map +1 -0
  35. package/dist/core/credential-pool/failover.js +124 -0
  36. package/dist/core/credential-pool/failover.js.map +1 -0
  37. package/dist/core/credential-pool/rotation-stream.d.ts +54 -0
  38. package/dist/core/credential-pool/rotation-stream.d.ts.map +1 -0
  39. package/dist/core/credential-pool/rotation-stream.js +183 -0
  40. package/dist/core/credential-pool/rotation-stream.js.map +1 -0
  41. package/dist/core/credential-pool/state-store.d.ts +89 -0
  42. package/dist/core/credential-pool/state-store.d.ts.map +1 -0
  43. package/dist/core/credential-pool/state-store.js +166 -0
  44. package/dist/core/credential-pool/state-store.js.map +1 -0
  45. package/dist/core/extensions/builtin/account/index.d.ts +9 -0
  46. package/dist/core/extensions/builtin/account/index.d.ts.map +1 -0
  47. package/dist/core/extensions/builtin/account/index.js +69 -0
  48. package/dist/core/extensions/builtin/account/index.js.map +1 -0
  49. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/compaction/index.js +67 -0
  51. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  52. package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
  53. package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/compaction/log.js +1 -0
  55. package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
  56. package/dist/core/extensions/builtin/config-reload/index.js +14 -22
  57. package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
  58. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +1 -0
  59. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -1
  60. package/dist/core/extensions/builtin/goal/continuation-recovery.js +2 -0
  61. package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -1
  62. package/dist/core/extensions/builtin/goal/continuation.d.ts +8 -1
  63. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  64. package/dist/core/extensions/builtin/goal/continuation.js +15 -0
  65. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  66. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +2 -2
  67. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js.map +1 -1
  68. package/dist/core/extensions/builtin/goal/format.d.ts +6 -1
  69. package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
  70. package/dist/core/extensions/builtin/goal/format.js +6 -0
  71. package/dist/core/extensions/builtin/goal/format.js.map +1 -1
  72. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/goal/index.js +7 -0
  74. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  75. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  76. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +5 -2
  77. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  78. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  79. package/dist/core/extensions/builtin/goal/monitor-continuation.js +31 -7
  80. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  81. package/dist/core/extensions/builtin/goal/persistence.js +2 -0
  82. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -1
  83. package/dist/core/extensions/builtin/goal/renderers.d.ts +14 -0
  84. package/dist/core/extensions/builtin/goal/renderers.d.ts.map +1 -0
  85. package/dist/core/extensions/builtin/goal/renderers.js +153 -0
  86. package/dist/core/extensions/builtin/goal/renderers.js.map +1 -0
  87. package/dist/core/extensions/builtin/goal/store.d.ts +6 -2
  88. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  89. package/dist/core/extensions/builtin/goal/store.js +8 -2
  90. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  91. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  92. package/dist/core/extensions/builtin/goal/tool-registration.js +16 -6
  93. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  94. package/dist/core/extensions/builtin/goal/types.d.ts +1 -0
  95. package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
  96. package/dist/core/extensions/builtin/goal/types.js.map +1 -1
  97. package/dist/core/extensions/builtin/imagegen/index.d.ts.map +1 -1
  98. package/dist/core/extensions/builtin/imagegen/index.js +10 -3
  99. package/dist/core/extensions/builtin/imagegen/index.js.map +1 -1
  100. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  101. package/dist/core/extensions/builtin/index.js +4 -0
  102. package/dist/core/extensions/builtin/index.js.map +1 -1
  103. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  104. package/dist/core/extensions/builtin/service-tier.js +13 -0
  105. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  106. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  107. package/dist/core/extensions/builtin/terminal/extension.js +4 -2
  108. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  109. package/dist/core/extensions/builtin/todotools/index.js +1 -1
  110. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  111. package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts +1 -1
  112. package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts.map +1 -1
  113. package/dist/core/extensions/builtin/todotools/native-todo-mirror.js +1 -1
  114. package/dist/core/extensions/builtin/todotools/native-todo-mirror.js.map +1 -1
  115. package/dist/core/hidden-stdout-log.d.ts +10 -0
  116. package/dist/core/hidden-stdout-log.d.ts.map +1 -1
  117. package/dist/core/hidden-stdout-log.js +36 -5
  118. package/dist/core/hidden-stdout-log.js.map +1 -1
  119. package/dist/core/model-config-schema.d.ts +85 -12
  120. package/dist/core/model-config-schema.d.ts.map +1 -1
  121. package/dist/core/model-config-schema.js +25 -0
  122. package/dist/core/model-config-schema.js.map +1 -1
  123. package/dist/core/model-runtime.d.ts +36 -1
  124. package/dist/core/model-runtime.d.ts.map +1 -1
  125. package/dist/core/model-runtime.js +142 -12
  126. package/dist/core/model-runtime.js.map +1 -1
  127. package/dist/core/retry-fallback/chains.d.ts +23 -1
  128. package/dist/core/retry-fallback/chains.d.ts.map +1 -1
  129. package/dist/core/retry-fallback/chains.js +59 -3
  130. package/dist/core/retry-fallback/chains.js.map +1 -1
  131. package/dist/core/retry-fallback/controller.d.ts.map +1 -1
  132. package/dist/core/retry-fallback/controller.js +9 -2
  133. package/dist/core/retry-fallback/controller.js.map +1 -1
  134. package/dist/core/retry-fallback/settings.d.ts.map +1 -1
  135. package/dist/core/retry-fallback/settings.js +9 -0
  136. package/dist/core/retry-fallback/settings.js.map +1 -1
  137. package/dist/core/retry-fallback/validate.js +1 -1
  138. package/dist/core/retry-fallback/validate.js.map +1 -1
  139. package/dist/core/sdk.js +1 -1
  140. package/dist/core/sdk.js.map +1 -1
  141. package/dist/core/session-manager.d.ts +9 -0
  142. package/dist/core/session-manager.d.ts.map +1 -1
  143. package/dist/core/session-manager.js +31 -0
  144. package/dist/core/session-manager.js.map +1 -1
  145. package/dist/core/tools/output-accumulator.d.ts +2 -0
  146. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  147. package/dist/core/tools/output-accumulator.js +32 -7
  148. package/dist/core/tools/output-accumulator.js.map +1 -1
  149. package/dist/index.d.ts +1 -1
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +1 -1
  152. package/dist/index.js.map +1 -1
  153. package/dist/main.d.ts +7 -0
  154. package/dist/main.d.ts.map +1 -1
  155. package/dist/main.js +48 -4
  156. package/dist/main.js.map +1 -1
  157. package/dist/modes/app-server/server/account.d.ts.map +1 -1
  158. package/dist/modes/app-server/server/account.js +5 -5
  159. package/dist/modes/app-server/server/account.js.map +1 -1
  160. package/dist/modes/index.d.ts +1 -0
  161. package/dist/modes/index.d.ts.map +1 -1
  162. package/dist/modes/index.js +1 -0
  163. package/dist/modes/index.js.map +1 -1
  164. package/dist/modes/interactive/components/footer.d.ts +11 -3
  165. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  166. package/dist/modes/interactive/components/footer.js +31 -1
  167. package/dist/modes/interactive/components/footer.js.map +1 -1
  168. package/dist/modes/interactive/components/tool-execution-fallback.d.ts.map +1 -1
  169. package/dist/modes/interactive/components/tool-execution-fallback.js +82 -1
  170. package/dist/modes/interactive/components/tool-execution-fallback.js.map +1 -1
  171. package/dist/modes/interactive/grok/chrome.d.ts +4 -4
  172. package/dist/modes/interactive/grok/chrome.d.ts.map +1 -1
  173. package/dist/modes/interactive/grok/chrome.js.map +1 -1
  174. package/dist/modes/interactive/grok/footer.d.ts +3 -3
  175. package/dist/modes/interactive/grok/footer.d.ts.map +1 -1
  176. package/dist/modes/interactive/grok/footer.js.map +1 -1
  177. package/dist/modes/interactive/interactive-host-runtime.d.ts +44 -0
  178. package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -0
  179. package/dist/modes/interactive/interactive-host-runtime.js +529 -0
  180. package/dist/modes/interactive/interactive-host-runtime.js.map +1 -0
  181. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  182. package/dist/modes/interactive/interactive-mode.js +340 -257
  183. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  184. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  185. package/dist/modes/rpc/connection-handler.js +151 -30
  186. package/dist/modes/rpc/connection-handler.js.map +1 -1
  187. package/dist/modes/rpc/host-ensure.d.ts +41 -0
  188. package/dist/modes/rpc/host-ensure.d.ts.map +1 -0
  189. package/dist/modes/rpc/host-ensure.js +245 -0
  190. package/dist/modes/rpc/host-ensure.js.map +1 -0
  191. package/dist/modes/rpc/host-lifecycle.d.ts +57 -0
  192. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -0
  193. package/dist/modes/rpc/host-lifecycle.js +491 -0
  194. package/dist/modes/rpc/host-lifecycle.js.map +1 -0
  195. package/dist/modes/rpc/host-watchdog.d.ts +33 -0
  196. package/dist/modes/rpc/host-watchdog.d.ts.map +1 -0
  197. package/dist/modes/rpc/host-watchdog.js +142 -0
  198. package/dist/modes/rpc/host-watchdog.js.map +1 -0
  199. package/dist/modes/rpc/multi-session-host.d.ts +7 -1
  200. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  201. package/dist/modes/rpc/multi-session-host.js +216 -32
  202. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  203. package/dist/modes/rpc/rpc-client.d.ts +115 -8
  204. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  205. package/dist/modes/rpc/rpc-client.js +200 -32
  206. package/dist/modes/rpc/rpc-client.js.map +1 -1
  207. package/dist/modes/rpc/rpc-mode.d.ts +4 -2
  208. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  209. package/dist/modes/rpc/rpc-mode.js +4 -2
  210. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  211. package/dist/modes/rpc/rpc-types.d.ts +166 -3
  212. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  213. package/dist/modes/rpc/rpc-types.js.map +1 -1
  214. package/dist/modes/rpc/session-command-router.d.ts +22 -0
  215. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  216. package/dist/modes/rpc/session-command-router.js +165 -16
  217. package/dist/modes/rpc/session-command-router.js.map +1 -1
  218. package/dist/modes/rpc/session-event-writer.d.ts +15 -2
  219. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  220. package/dist/modes/rpc/session-event-writer.js +69 -25
  221. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  222. package/dist/modes/rpc/session-registry.d.ts +16 -0
  223. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  224. package/dist/modes/rpc/session-registry.js +40 -3
  225. package/dist/modes/rpc/session-registry.js.map +1 -1
  226. package/docs/providers.md +48 -0
  227. package/docs/rpc.md +96 -5
  228. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +56 -0
  229. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  230. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +13 -1
  231. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +15 -1
  232. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +711 -1
  233. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +14 -1
  234. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +10 -10
  235. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-eval-result.ts +9 -3
  236. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +6 -1
  237. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.d.ts.map +1 -1
  238. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js +20 -4
  239. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js.map +1 -1
  240. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts +1 -1
  241. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.js.map +1 -1
  243. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts +21 -0
  244. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts.map +1 -0
  245. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js +27 -0
  246. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js.map +1 -0
  247. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts +24 -0
  248. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts.map +1 -1
  249. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.js.map +1 -1
  250. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.d.ts.map +1 -1
  251. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js +7 -2
  252. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js.map +1 -1
  253. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  254. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts +1 -1
  255. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.d.ts.map +1 -1
  256. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js +46 -14
  257. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-pairs.js.map +1 -1
  258. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +11 -0
  259. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
  260. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +30 -16
  261. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
  262. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts +2 -1
  263. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts.map +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js +2 -1
  265. package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js.map +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts +16 -0
  267. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.d.ts.map +1 -0
  268. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js +75 -0
  269. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/classify.js.map +1 -0
  270. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts +45 -0
  271. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.d.ts.map +1 -0
  272. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js +81 -0
  273. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/failover.js.map +1 -0
  274. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts +31 -0
  275. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.d.ts.map +1 -0
  276. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js +65 -0
  277. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/select.js.map +1 -0
  278. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +12 -0
  279. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
  280. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +37 -0
  281. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +6 -0
  283. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +32 -6
  285. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  286. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +3 -2
  287. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  289. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts +6 -0
  290. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  291. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +6 -1
  292. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  293. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +75 -0
  294. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  295. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +75 -0
  296. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  297. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  298. package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
  299. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  300. package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  301. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  302. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
  303. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  304. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  305. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  306. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax-cn.json +1 -1
  307. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax.json +1 -1
  308. package/node_modules/@earendil-works/pi-ai/dist/providers/data/mistral.json +1 -1
  309. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  310. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
  311. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  312. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  313. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  314. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  315. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  316. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
  317. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
  318. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  319. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  320. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  321. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  322. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  323. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +4 -0
  324. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  325. package/node_modules/@earendil-works/pi-ai/package.json +5 -5
  326. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  327. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  328. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +5 -0
  329. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  330. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +90 -1
  331. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  332. package/node_modules/@earendil-works/pi-tui/dist/tui.js +1 -1
  333. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  334. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  335. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"continuation.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/continuation.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAC/C,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAC7C,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAC5C,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAgC/C,MAAM,UAAU,mCAAmC,CAClD,IAAiB,EACjB,MAAe,EACf,kBAA2B;IAE3B,OAAO,IAAI,EAAE,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,CAAC,kBAAkB,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,wCAAwC,CACvD,IAAiB,EACjB,kBAA2B,EAC3B,QAAiC;IAEjC,OAAO,IAAI,EAAE,MAAM,KAAK,QAAQ,IAAI,CAAC,kBAAkB,IAAI,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AACzF,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAiC;IAC5D,MAAM,kBAAkB,GAAG,6BAA6B,CAAC,QAAQ,CAAC,CAAC;IACnE,IAAI,kBAAkB,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAEnD,MAAM,aAAa,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACnD,IAAI,aAAa,EAAE,IAAI,KAAK,WAAW,IAAI,CAAC,uBAAuB,CAAC,aAAa,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5G,KAAK,IAAI,KAAK,GAAG,kBAAkB,GAAG,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3E,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,OAAO,EAAE,IAAI,KAAK,YAAY,IAAI,mBAAmB,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;IAClF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,6BAA6B,CAAC,QAAiC;IACvE,KAAK,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3D,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,OAAO,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,uBAAuB,CAAC,UAA+C;IAC/E,OAAO,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,QAAQ,CAAC;AACzD,CAAC;AAED,SAAS,mBAAmB,CAAC,OAA+B;IAC3D,IAAI,CAAC,OAAO,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7G,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAA4B;IACpE,IAAI,CAAC,6BAA6B,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAC3F,IAAI,KAAK,CAAC,mBAAmB;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAChF,IAAI,+BAA+B,CAAC,KAAK,CAAC,4BAA4B,CAAC;QACtE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAC/C,IAAI,KAAK,CAAC,wBAAwB,IAAI,qBAAqB,EAAE,CAAC;QAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IACD,IACC,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC;QAC1D,KAAK,CAAC,yBAAyB,KAAK,SAAS;QAC7C,KAAK,CAAC,yBAAyB,KAAK,KAAK,CAAC,gBAAgB,EACzD,CAAC;QACF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC1C,CAAC;IACD,IAAI,KAAK,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,2BAA2B,IAAI,0BAA0B,EAAE,CAAC;YACrE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;QACrD,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;IAC3F,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;AACxF,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,sBAAsB,CAAC,IAAY;IAClD,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACvD,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC7C,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,IAAI,GAAG,UAAU,CAAC;IACtB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACxD,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,8BAA8B,CAC7C,IAAsB,EACtB,SAAiB,EACjB,UAAkB,EAClB,qBAA6B;IAE7B,OAAO,GAAG,IAAI,CAAC,EAAE,IAAI,SAAS,IAAI,UAAU,IAAI,qBAAqB,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,2BAA2B,CAC1C,KAAoF;IAEpF,OAAO,CACN,KAAK,CAAC,yBAAyB,KAAK,SAAS;QAC7C,KAAK,CAAC,gBAAgB,KAAK,SAAS;QACpC,KAAK,CAAC,yBAAyB,KAAK,KAAK,CAAC,gBAAgB,CAC1D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAiC;IAC1E,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QAChC,IAAI,OAAO,EAAE,IAAI,KAAK,YAAY;YAAE,OAAO,IAAI,CAAC;QAChD,OAAO,OAAO,EAAE,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACxG,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,6BAA6B,CAAC,KAA4B;IAClE,IAAI,KAAK,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,kBAAkB;QAAE,OAAO,KAAK,CAAC;IAC9E,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB;QAAE,OAAO,IAAI,CAAC;IACtF,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC,cAAc,KAAK,SAAS,IAAI,uBAAuB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,SAAS,+BAA+B,CAAC,MAAyB;IACjE,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAE3C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC;QACzF,MAAM,IAAI,CAAC,CAAC;IACb,CAAC;IACD,OAAO,MAAM,IAAI,2BAA2B,CAAC;AAC9C,CAAC;AAED,SAAS,qBAAqB,CAAC,KAA4B;IAC1D,OAAO,KAAK,CAAC,0BAA0B,IAAI,6BAA6B,CAAC;AAC1E,CAAC","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { Goal } from \"./types.ts\";\n\ntype AssistantAgentMessage = Extract<AgentMessage, { role: \"assistant\" }>;\ntype ToolResultAgentMessage = Extract<AgentMessage, { role: \"toolResult\" }>;\n\nexport const GOAL_CONTINUATION_CAP = 8;\nexport const GOAL_STALL_TOOLLESS_THRESHOLD = 3;\nexport const GOAL_REPETITION_HASH_STREAK = 3;\nexport const GOAL_LENGTH_RECOVERY_LIMIT = 1;\nexport const GOAL_USER_GRACE_DELAY_MS = 10_000;\n\nexport type GoalContinuationPath =\n\t| \"immediate\"\n\t| \"monitorDelayed\"\n\t| \"userGrace\"\n\t| \"sessionStart\"\n\t| \"systemRecovery\"\n\t| \"providerRecovery\";\n\nexport type GoalContinuationInput = {\n\treadonly goal: Goal | null;\n\treadonly isIdle: boolean;\n\treadonly hasPendingMessages: boolean;\n\treadonly path: GoalContinuationPath;\n\treadonly lastStopReason: AssistantAgentMessage[\"stopReason\"] | undefined;\n\treadonly consecutiveContinuations: number;\n\treadonly lastContinuationSignature: string | undefined;\n\treadonly currentSignature: string | undefined;\n\treadonly consecutiveLengthRecoveries: number;\n\treadonly recentNormalizedOutputHashes: readonly string[];\n\treadonly toollessContinuationStreak: number;\n\treadonly continuationPending: boolean;\n};\n\nexport type GoalContinuationVerdict =\n\t| { kind: \"continue\"; prompt: \"full\" | \"minimal\"; stallNotice: boolean }\n\t| {\n\t\t\tkind: \"deny\";\n\t\t\treason: \"not-eligible\" | \"single-flight\" | \"cap\" | \"stale\" | \"repetition\" | \"length-exhausted\";\n\t };\n\nexport function shouldQueueGoalContinuationWhenIdle(\n\tgoal: Goal | null,\n\tisIdle: boolean,\n\thasPendingMessages: boolean,\n): goal is Goal {\n\treturn goal?.status === \"active\" && isIdle && !hasPendingMessages;\n}\n\nexport function shouldQueueGoalContinuationAfterAgentEnd(\n\tgoal: Goal | null,\n\thasPendingMessages: boolean,\n\tmessages: readonly AgentMessage[],\n): goal is Goal {\n\treturn goal?.status === \"active\" && !hasPendingMessages && didAgentEndCleanly(messages);\n}\n\nfunction didAgentEndCleanly(messages: readonly AgentMessage[]): boolean {\n\tconst lastAssistantIndex = findLastAssistantMessageIndex(messages);\n\tif (lastAssistantIndex === undefined) return false;\n\n\tconst lastAssistant = messages[lastAssistantIndex];\n\tif (lastAssistant?.role !== \"assistant\" || !isContinuableStopReason(lastAssistant.stopReason)) return false;\n\n\tfor (let index = lastAssistantIndex + 1; index < messages.length; index++) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"toolResult\" && isAbortedToolResult(message)) return false;\n\t}\n\treturn true;\n}\n\nfunction findLastAssistantMessageIndex(messages: readonly AgentMessage[]): number | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"assistant\") {\n\t\t\treturn index;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction isContinuableStopReason(stopReason: AssistantAgentMessage[\"stopReason\"]): boolean {\n\treturn stopReason === \"stop\" || stopReason === \"length\";\n}\n\nfunction isAbortedToolResult(message: ToolResultAgentMessage): boolean {\n\tif (!message.isError) return false;\n\treturn message.content.some((content) => content.type === \"text\" && /\\babort(?:ed)?\\b/i.test(content.text));\n}\n\nexport function evaluateGoalContinuation(input: GoalContinuationInput): GoalContinuationVerdict {\n\tif (!isEligibleForGoalContinuation(input)) return { kind: \"deny\", reason: \"not-eligible\" };\n\tif (input.continuationPending) return { kind: \"deny\", reason: \"single-flight\" };\n\tif (hasRepeatedNormalizedOutputHash(input.recentNormalizedOutputHashes))\n\t\treturn { kind: \"deny\", reason: \"repetition\" };\n\tif (input.consecutiveContinuations >= GOAL_CONTINUATION_CAP) {\n\t\treturn { kind: \"deny\", reason: \"cap\" };\n\t}\n\tif (\n\t\t(input.path === \"immediate\" || input.path === \"userGrace\") &&\n\t\tinput.lastContinuationSignature !== undefined &&\n\t\tinput.lastContinuationSignature === input.currentSignature\n\t) {\n\t\treturn { kind: \"deny\", reason: \"stale\" };\n\t}\n\tif (input.lastStopReason === \"length\") {\n\t\tif (input.consecutiveLengthRecoveries >= GOAL_LENGTH_RECOVERY_LIMIT) {\n\t\t\treturn { kind: \"deny\", reason: \"length-exhausted\" };\n\t\t}\n\t\treturn { kind: \"continue\", prompt: \"minimal\", stallNotice: shouldShowStallNotice(input) };\n\t}\n\treturn { kind: \"continue\", prompt: \"full\", stallNotice: shouldShowStallNotice(input) };\n}\n\n/** Produces a stable, whitespace-insensitive representation for repetition detection. */\nexport function normalizeAssistantText(text: string): string {\n\treturn text.toLowerCase().replace(/\\s+/g, \" \").trim();\n}\n\n/** Hashes normalized assistant text with the deterministic 32-bit FNV-1a algorithm. */\nexport function hashAssistantText(text: string): string {\n\tconst normalized = normalizeAssistantText(text);\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < normalized.length; index++) {\n\t\thash ^= normalized.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(16).padStart(8, \"0\");\n}\n\n/**\n * Identifies the observable goal progress for stale-continuation admission.\n * Deliberately excludes goal.updatedAt because usage accounting updates it after every agent turn.\n */\nexport function buildGoalContinuationSignature(\n\tgoal: Pick<Goal, \"id\">,\n\topenTodos: number,\n\ttotalTodos: number,\n\tlastAssistantTextHash: string,\n): string {\n\treturn `${goal.id}:${openTodos}/${totalTodos}:${lastAssistantTextHash}`;\n}\n\nexport function hasGoalContinuationProgress(\n\tinput: Pick<GoalContinuationInput, \"lastContinuationSignature\" | \"currentSignature\">,\n): boolean {\n\treturn (\n\t\tinput.lastContinuationSignature !== undefined &&\n\t\tinput.currentSignature !== undefined &&\n\t\tinput.lastContinuationSignature !== input.currentSignature\n\t);\n}\n\nexport function continuationTurnUsedTools(messages: readonly AgentMessage[]): boolean {\n\treturn messages.some((message) => {\n\t\tif (message?.role === \"toolResult\") return true;\n\t\treturn message?.role === \"assistant\" && message.content.some((content) => content.type === \"toolCall\");\n\t});\n}\n\nfunction isEligibleForGoalContinuation(input: GoalContinuationInput): boolean {\n\tif (input.goal?.status !== \"active\" || input.hasPendingMessages) return false;\n\tif (input.path === \"systemRecovery\" || input.path === \"providerRecovery\") return true;\n\tif (input.path === \"immediate\") {\n\t\treturn input.lastStopReason !== undefined && isContinuableStopReason(input.lastStopReason);\n\t}\n\treturn input.isIdle;\n}\n\nfunction hasRepeatedNormalizedOutputHash(hashes: readonly string[]): boolean {\n\tconst latestHash = hashes.at(-1);\n\tif (latestHash === undefined) return false;\n\n\tlet streak = 0;\n\tfor (let index = hashes.length - 1; index >= 0 && hashes[index] === latestHash; index--) {\n\t\tstreak += 1;\n\t}\n\treturn streak >= GOAL_REPETITION_HASH_STREAK;\n}\n\nfunction shouldShowStallNotice(input: GoalContinuationInput): boolean {\n\treturn input.toollessContinuationStreak >= GOAL_STALL_TOOLLESS_THRESHOLD;\n}\n"]}
1
+ {"version":3,"file":"continuation.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/continuation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { Goal } from \"./types.ts\";\n\ntype AssistantAgentMessage = Extract<AgentMessage, { role: \"assistant\" }>;\ntype ToolResultAgentMessage = Extract<AgentMessage, { role: \"toolResult\" }>;\n\nexport const GOAL_CONTINUATION_CAP = 8;\nexport const GOAL_STALL_TOOLLESS_THRESHOLD = 3;\nexport const GOAL_REPETITION_HASH_STREAK = 3;\nexport const GOAL_LENGTH_RECOVERY_LIMIT = 1;\n/**\n * Hard budget of automatic continuations without accepted direct user input (#1139).\n * Progress and tool use never refill it: only direct input does. Stays above the\n * #447 distinct-progress pin (50) and an 8-hour monitor-backstop cadence\n * (~120 deliveries at 240s), below the observed 289-continuation incident run.\n */\nexport const GOAL_UNATTENDED_CONTINUATION_LIMIT = 150;\nexport const GOAL_USER_GRACE_DELAY_MS = 10_000;\n\nexport type GoalContinuationPath =\n\t| \"immediate\"\n\t| \"monitorDelayed\"\n\t| \"userGrace\"\n\t| \"sessionStart\"\n\t| \"systemRecovery\"\n\t| \"providerRecovery\";\n\nexport type GoalContinuationInput = {\n\treadonly goal: Goal | null;\n\treadonly isIdle: boolean;\n\treadonly hasPendingMessages: boolean;\n\treadonly path: GoalContinuationPath;\n\treadonly lastStopReason: AssistantAgentMessage[\"stopReason\"] | undefined;\n\treadonly consecutiveContinuations: number;\n\treadonly lastContinuationSignature: string | undefined;\n\treadonly currentSignature: string | undefined;\n\treadonly consecutiveLengthRecoveries: number;\n\treadonly recentNormalizedOutputHashes: readonly string[];\n\treadonly toollessContinuationStreak: number;\n\treadonly continuationPending: boolean;\n};\n\nexport type GoalContinuationVerdict =\n\t| { kind: \"continue\"; prompt: \"full\" | \"minimal\"; stallNotice: boolean }\n\t| {\n\t\t\tkind: \"deny\";\n\t\t\treason: \"not-eligible\" | \"single-flight\" | \"cap\" | \"stale\" | \"repetition\" | \"length-exhausted\" | \"unattended\";\n\t };\n\nexport function shouldQueueGoalContinuationWhenIdle(\n\tgoal: Goal | null,\n\tisIdle: boolean,\n\thasPendingMessages: boolean,\n): goal is Goal {\n\treturn goal?.status === \"active\" && isIdle && !hasPendingMessages;\n}\n\nexport function shouldQueueGoalContinuationAfterAgentEnd(\n\tgoal: Goal | null,\n\thasPendingMessages: boolean,\n\tmessages: readonly AgentMessage[],\n): goal is Goal {\n\treturn goal?.status === \"active\" && !hasPendingMessages && didAgentEndCleanly(messages);\n}\n\nfunction didAgentEndCleanly(messages: readonly AgentMessage[]): boolean {\n\tconst lastAssistantIndex = findLastAssistantMessageIndex(messages);\n\tif (lastAssistantIndex === undefined) return false;\n\n\tconst lastAssistant = messages[lastAssistantIndex];\n\tif (lastAssistant?.role !== \"assistant\" || !isContinuableStopReason(lastAssistant.stopReason)) return false;\n\n\tfor (let index = lastAssistantIndex + 1; index < messages.length; index++) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"toolResult\" && isAbortedToolResult(message)) return false;\n\t}\n\treturn true;\n}\n\nfunction findLastAssistantMessageIndex(messages: readonly AgentMessage[]): number | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"assistant\") {\n\t\t\treturn index;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction isContinuableStopReason(stopReason: AssistantAgentMessage[\"stopReason\"]): boolean {\n\treturn stopReason === \"stop\" || stopReason === \"length\";\n}\n\nfunction isAbortedToolResult(message: ToolResultAgentMessage): boolean {\n\tif (!message.isError) return false;\n\treturn message.content.some((content) => content.type === \"text\" && /\\babort(?:ed)?\\b/i.test(content.text));\n}\n\nexport function evaluateGoalContinuation(input: GoalContinuationInput): GoalContinuationVerdict {\n\tif (!isEligibleForGoalContinuation(input)) return { kind: \"deny\", reason: \"not-eligible\" };\n\tif (input.continuationPending) return { kind: \"deny\", reason: \"single-flight\" };\n\tif (hasRepeatedNormalizedOutputHash(input.recentNormalizedOutputHashes))\n\t\treturn { kind: \"deny\", reason: \"repetition\" };\n\tif (isUnattendedBudgetExhausted(input)) return { kind: \"deny\", reason: \"unattended\" };\n\tif (input.consecutiveContinuations >= GOAL_CONTINUATION_CAP) {\n\t\treturn { kind: \"deny\", reason: \"cap\" };\n\t}\n\tif (\n\t\t(input.path === \"immediate\" || input.path === \"userGrace\") &&\n\t\tinput.lastContinuationSignature !== undefined &&\n\t\tinput.lastContinuationSignature === input.currentSignature\n\t) {\n\t\treturn { kind: \"deny\", reason: \"stale\" };\n\t}\n\tif (input.lastStopReason === \"length\") {\n\t\tif (input.consecutiveLengthRecoveries >= GOAL_LENGTH_RECOVERY_LIMIT) {\n\t\t\treturn { kind: \"deny\", reason: \"length-exhausted\" };\n\t\t}\n\t\treturn { kind: \"continue\", prompt: \"minimal\", stallNotice: shouldShowStallNotice(input) };\n\t}\n\treturn { kind: \"continue\", prompt: \"full\", stallNotice: shouldShowStallNotice(input) };\n}\n\n/** Produces a stable, whitespace-insensitive representation for repetition detection. */\nexport function normalizeAssistantText(text: string): string {\n\treturn text.toLowerCase().replace(/\\s+/g, \" \").trim();\n}\n\n/** Hashes normalized assistant text with the deterministic 32-bit FNV-1a algorithm. */\nexport function hashAssistantText(text: string): string {\n\tconst normalized = normalizeAssistantText(text);\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < normalized.length; index++) {\n\t\thash ^= normalized.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(16).padStart(8, \"0\");\n}\n\n/**\n * Identifies the observable goal progress for stale-continuation admission.\n * Deliberately excludes goal.updatedAt because usage accounting updates it after every agent turn.\n */\nexport function buildGoalContinuationSignature(\n\tgoal: Pick<Goal, \"id\">,\n\topenTodos: number,\n\ttotalTodos: number,\n\tlastAssistantTextHash: string,\n): string {\n\treturn `${goal.id}:${openTodos}/${totalTodos}:${lastAssistantTextHash}`;\n}\n\nexport function hasGoalContinuationProgress(\n\tinput: Pick<GoalContinuationInput, \"lastContinuationSignature\" | \"currentSignature\">,\n): boolean {\n\treturn (\n\t\tinput.lastContinuationSignature !== undefined &&\n\t\tinput.currentSignature !== undefined &&\n\t\tinput.lastContinuationSignature !== input.currentSignature\n\t);\n}\n\nexport function continuationTurnUsedTools(messages: readonly AgentMessage[]): boolean {\n\treturn messages.some((message) => {\n\t\tif (message?.role === \"toolResult\") return true;\n\t\treturn message?.role === \"assistant\" && message.content.some((content) => content.type === \"toolCall\");\n\t});\n}\n\nfunction isEligibleForGoalContinuation(input: GoalContinuationInput): boolean {\n\tif (input.goal?.status !== \"active\" || input.hasPendingMessages) return false;\n\tif (input.path === \"systemRecovery\" || input.path === \"providerRecovery\") return true;\n\tif (input.path === \"immediate\") {\n\t\treturn input.lastStopReason !== undefined && isContinuableStopReason(input.lastStopReason);\n\t}\n\treturn input.isIdle;\n}\n\n/** Monitor-delayed deliveries are exempt: armed-wake waiting is by-design and rate-limited by the cache-aware timer. */\nfunction isUnattendedBudgetExhausted(input: GoalContinuationInput): boolean {\n\tif (input.path === \"monitorDelayed\") return false;\n\treturn (input.goal?.unattendedContinuations ?? 0) >= GOAL_UNATTENDED_CONTINUATION_LIMIT;\n}\n\nfunction hasRepeatedNormalizedOutputHash(hashes: readonly string[]): boolean {\n\tconst latestHash = hashes.at(-1);\n\tif (latestHash === undefined) return false;\n\n\tlet streak = 0;\n\tfor (let index = hashes.length - 1; index >= 0 && hashes[index] === latestHash; index--) {\n\t\tstreak += 1;\n\t}\n\treturn streak >= GOAL_REPETITION_HASH_STREAK;\n}\n\nfunction shouldShowStallNotice(input: GoalContinuationInput): boolean {\n\treturn input.toollessContinuationStreak >= GOAL_STALL_TOOLLESS_THRESHOLD;\n}\n"]}
@@ -38,7 +38,7 @@ export class GoalDirectInputLifecycle {
38
38
  if (currentGoal?.id !== candidate.goalId)
39
39
  return;
40
40
  if (currentGoal.status === "blocked" && isMechanicalContinuationBlock(currentGoal.blockedReason)) {
41
- await resetContinuationStreak(ref);
41
+ await resetContinuationStreak(ref, { unattended: true });
42
42
  const reactivated = await updateGoal(ref, { status: "active" }, "user");
43
43
  this.#dependencies.beginAgentGoalAccounting(reactivated);
44
44
  this.#dependencies.refreshGoalUi(ctx, reactivated);
@@ -46,7 +46,7 @@ export class GoalDirectInputLifecycle {
46
46
  }
47
47
  if (currentGoal.status !== "active")
48
48
  return;
49
- const reset = await resetContinuationStreak(ref);
49
+ const reset = await resetContinuationStreak(ref, { unattended: true });
50
50
  if (reset !== null)
51
51
  this.#dependencies.refreshGoalUi(ctx, reset);
52
52
  if (this.#suppressedLoadResumeArmed) {
@@ -1 +1 @@
1
- {"version":3,"file":"direct-input-lifecycle.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/direct-input-lifecycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAE3E,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAoB3E,gFAAgF;AAChF,MAAM,OAAO,wBAAwB;IAC3B,aAAa,CAAmC;IAChD,WAAW,GAAG,IAAI,GAAG,EAAgC,CAAC;IAC/D,0BAA0B,GAAG,KAAK,CAAC;IAEnC,YAAY,YAA8C;QACzD,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,0BAA0B,GAAG,KAAK,CAAC;IACzC,CAAC;IAED,iFAAiF;IACjF,uBAAuB;QACtB,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAAiB,EAAE,GAAqB;QACrD,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;YAAE,OAAO;QAEzC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAA4B,EAAE,GAAqB;QACtE,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO;QACpC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC;QACnF,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvE,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,MAAM,KAAK,IAAI;YAAE,OAAO;QAEnD,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACjD,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,WAAW,EAAE,EAAE,KAAK,SAAS,CAAC,MAAM;YAAE,OAAO;QAEjD,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS,IAAI,6BAA6B,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;YAClG,MAAM,uBAAuB,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC;YACxE,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC;YACzD,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;YACnD,OAAO;QACR,CAAC;QAED,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO;QAC5C,MAAM,KAAK,GAAG,MAAM,uBAAuB,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,KAAK,KAAK,IAAI;YAAE,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,0BAA0B,EAAE,CAAC;YACrC,IAAI,CAAC,0BAA0B,GAAG,KAAK,CAAC;YACxC,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,EAAE,CAAC,GAAG,EAAE,KAAK,IAAI,WAAW,CAAC,CAAC;QACjF,CAAC;IACF,CAAC;CACD","sourcesContent":["import type { ExtensionContext, InputDispositionEvent, InputEvent } from \"../../types.ts\";\nimport { isMechanicalContinuationBlock } from \"./continuation-recovery.ts\";\nimport type { MonitorAwareGoalContinuation } from \"./monitor-continuation.ts\";\nimport { readGoal, resetContinuationStreak, updateGoal } from \"./store.ts\";\nimport type { Goal, GoalStoreRef } from \"./types.ts\";\n\ntype DirectInputCandidate = {\n\treadonly goalId: string | null;\n};\n\ntype DirectInputLifecycleDependencies = {\n\treadonly monitor: MonitorAwareGoalContinuation;\n\treadonly goalStoreRef: (ctx: ExtensionContext) => GoalStoreRef;\n\treadonly beginAgentGoalAccounting: (goal: Goal) => void;\n\treadonly refreshGoalUi: (ctx: ExtensionContext, goal: Goal) => void;\n\t/**\n\t * One-shot resume fired when the first user message after a suppressed\n\t * flooded load is accepted. The load-time suppression notice tells the user\n\t * to \"send a message to resume\"; this callback is what keeps that promise.\n\t */\n\treadonly resumeAfterSuppressedLoad?: (ctx: ExtensionContext, goal: Goal) => Promise<void>;\n};\n\n/** Correlates raw input with admission before changing persisted Goal state. */\nexport class GoalDirectInputLifecycle {\n\treadonly #dependencies: DirectInputLifecycleDependencies;\n\treadonly #candidates = new Map<string, DirectInputCandidate>();\n\t#suppressedLoadResumeArmed = false;\n\n\tconstructor(dependencies: DirectInputLifecycleDependencies) {\n\t\tthis.#dependencies = dependencies;\n\t}\n\n\treset(): void {\n\t\tthis.#candidates.clear();\n\t\tthis.#suppressedLoadResumeArmed = false;\n\t}\n\n\t/** Arms the one-shot resume for a goal parked by load-time flood suppression. */\n\tarmSuppressedLoadResume(): void {\n\t\tthis.#suppressedLoadResumeArmed = true;\n\t}\n\n\tasync onInput(event: InputEvent, ctx: ExtensionContext): Promise<void> {\n\t\tif (event.source === \"extension\") return;\n\n\t\tthis.#dependencies.monitor.holdDirectInput(event.inputId);\n\t\tthis.#candidates.set(event.inputId, { goalId: null });\n\t\tconst goal = await readGoal(this.#dependencies.goalStoreRef(ctx));\n\t\tthis.#candidates.set(event.inputId, { goalId: goal?.id ?? null });\n\t}\n\n\tasync onDisposition(event: InputDispositionEvent, ctx: ExtensionContext): Promise<void> {\n\t\tconst candidate = this.#candidates.get(event.inputId);\n\t\tif (candidate === undefined) return;\n\t\tthis.#candidates.delete(event.inputId);\n\t\tconst accepted = event.disposition === \"started\" || event.disposition === \"queued\";\n\t\tthis.#dependencies.monitor.resolveDirectInput(event.inputId, accepted);\n\t\tif (!accepted || candidate.goalId === null) return;\n\n\t\tconst ref = this.#dependencies.goalStoreRef(ctx);\n\t\tconst currentGoal = await readGoal(ref);\n\t\tif (currentGoal?.id !== candidate.goalId) return;\n\n\t\tif (currentGoal.status === \"blocked\" && isMechanicalContinuationBlock(currentGoal.blockedReason)) {\n\t\t\tawait resetContinuationStreak(ref);\n\t\t\tconst reactivated = await updateGoal(ref, { status: \"active\" }, \"user\");\n\t\t\tthis.#dependencies.beginAgentGoalAccounting(reactivated);\n\t\t\tthis.#dependencies.refreshGoalUi(ctx, reactivated);\n\t\t\treturn;\n\t\t}\n\n\t\tif (currentGoal.status !== \"active\") return;\n\t\tconst reset = await resetContinuationStreak(ref);\n\t\tif (reset !== null) this.#dependencies.refreshGoalUi(ctx, reset);\n\t\tif (this.#suppressedLoadResumeArmed) {\n\t\t\tthis.#suppressedLoadResumeArmed = false;\n\t\t\tawait this.#dependencies.resumeAfterSuppressedLoad?.(ctx, reset ?? currentGoal);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"direct-input-lifecycle.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/direct-input-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionContext, InputDispositionEvent, InputEvent } from \"../../types.ts\";\nimport { isMechanicalContinuationBlock } from \"./continuation-recovery.ts\";\nimport type { MonitorAwareGoalContinuation } from \"./monitor-continuation.ts\";\nimport { readGoal, resetContinuationStreak, updateGoal } from \"./store.ts\";\nimport type { Goal, GoalStoreRef } from \"./types.ts\";\n\ntype DirectInputCandidate = {\n\treadonly goalId: string | null;\n};\n\ntype DirectInputLifecycleDependencies = {\n\treadonly monitor: MonitorAwareGoalContinuation;\n\treadonly goalStoreRef: (ctx: ExtensionContext) => GoalStoreRef;\n\treadonly beginAgentGoalAccounting: (goal: Goal) => void;\n\treadonly refreshGoalUi: (ctx: ExtensionContext, goal: Goal) => void;\n\t/**\n\t * One-shot resume fired when the first user message after a suppressed\n\t * flooded load is accepted. The load-time suppression notice tells the user\n\t * to \"send a message to resume\"; this callback is what keeps that promise.\n\t */\n\treadonly resumeAfterSuppressedLoad?: (ctx: ExtensionContext, goal: Goal) => Promise<void>;\n};\n\n/** Correlates raw input with admission before changing persisted Goal state. */\nexport class GoalDirectInputLifecycle {\n\treadonly #dependencies: DirectInputLifecycleDependencies;\n\treadonly #candidates = new Map<string, DirectInputCandidate>();\n\t#suppressedLoadResumeArmed = false;\n\n\tconstructor(dependencies: DirectInputLifecycleDependencies) {\n\t\tthis.#dependencies = dependencies;\n\t}\n\n\treset(): void {\n\t\tthis.#candidates.clear();\n\t\tthis.#suppressedLoadResumeArmed = false;\n\t}\n\n\t/** Arms the one-shot resume for a goal parked by load-time flood suppression. */\n\tarmSuppressedLoadResume(): void {\n\t\tthis.#suppressedLoadResumeArmed = true;\n\t}\n\n\tasync onInput(event: InputEvent, ctx: ExtensionContext): Promise<void> {\n\t\tif (event.source === \"extension\") return;\n\n\t\tthis.#dependencies.monitor.holdDirectInput(event.inputId);\n\t\tthis.#candidates.set(event.inputId, { goalId: null });\n\t\tconst goal = await readGoal(this.#dependencies.goalStoreRef(ctx));\n\t\tthis.#candidates.set(event.inputId, { goalId: goal?.id ?? null });\n\t}\n\n\tasync onDisposition(event: InputDispositionEvent, ctx: ExtensionContext): Promise<void> {\n\t\tconst candidate = this.#candidates.get(event.inputId);\n\t\tif (candidate === undefined) return;\n\t\tthis.#candidates.delete(event.inputId);\n\t\tconst accepted = event.disposition === \"started\" || event.disposition === \"queued\";\n\t\tthis.#dependencies.monitor.resolveDirectInput(event.inputId, accepted);\n\t\tif (!accepted || candidate.goalId === null) return;\n\n\t\tconst ref = this.#dependencies.goalStoreRef(ctx);\n\t\tconst currentGoal = await readGoal(ref);\n\t\tif (currentGoal?.id !== candidate.goalId) return;\n\n\t\tif (currentGoal.status === \"blocked\" && isMechanicalContinuationBlock(currentGoal.blockedReason)) {\n\t\t\tawait resetContinuationStreak(ref, { unattended: true });\n\t\t\tconst reactivated = await updateGoal(ref, { status: \"active\" }, \"user\");\n\t\t\tthis.#dependencies.beginAgentGoalAccounting(reactivated);\n\t\t\tthis.#dependencies.refreshGoalUi(ctx, reactivated);\n\t\t\treturn;\n\t\t}\n\n\t\tif (currentGoal.status !== \"active\") return;\n\t\tconst reset = await resetContinuationStreak(ref, { unattended: true });\n\t\tif (reset !== null) this.#dependencies.refreshGoalUi(ctx, reset);\n\t\tif (this.#suppressedLoadResumeArmed) {\n\t\t\tthis.#suppressedLoadResumeArmed = false;\n\t\t\tawait this.#dependencies.resumeAfterSuppressedLoad?.(ctx, reset ?? currentGoal);\n\t\t}\n\t}\n}\n"]}
@@ -1,8 +1,13 @@
1
- import type { Goal, GoalStatus, GoalToolResponse } from "./types.ts";
1
+ import type { Goal, GoalStatus, GoalToolResponse, GoalToolSnapshot } from "./types.ts";
2
2
  export declare function formatGoalElapsedSeconds(value: number): string;
3
3
  export declare function formatTokensCompact(value: number): string;
4
4
  export declare function goalStatusLabel(status: GoalStatus): string;
5
5
  export declare function formatGoalForTool(goal: Goal | null): string;
6
+ export type GoalToolRenderDetails = {
7
+ goal: GoalToolSnapshot | null;
8
+ notice?: string;
9
+ };
10
+ export declare function goalToolRenderDetails(goal: Goal | null, notice?: string): GoalToolRenderDetails;
6
11
  export declare function goalToolResponse(goal: Goal | null): GoalToolResponse;
7
12
  export declare function formatGoalToolResponse(goal: Goal | null, notice?: string): string;
8
13
  //# sourceMappingURL=format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAoB,MAAM,YAAY,CAAC;AAEvF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiB9D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAW1D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAW3D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,gBAAgB,CAEpE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAGjF"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEvF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiB9D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAW1D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAW3D;AAED,MAAM,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAK/F;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,gBAAgB,CAEpE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAGjF"}
@@ -51,6 +51,12 @@ export function formatGoalForTool(goal) {
51
51
  lines.push(`Completed at: ${new Date(goal.completedAt * 1000).toISOString()}`);
52
52
  return lines.join("\n");
53
53
  }
54
+ export function goalToolRenderDetails(goal, notice) {
55
+ return {
56
+ goal: goal === null ? null : goalToolSnapshot(goal),
57
+ ...(notice === undefined ? {} : { notice }),
58
+ };
59
+ }
54
60
  export function goalToolResponse(goal) {
55
61
  return { goal: goal === null ? null : goalToolSnapshot(goal) };
56
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/format.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Goal, GoalStatus, GoalToolResponse, GoalToolSnapshot } from \"./types.ts\";\n\nexport function formatGoalElapsedSeconds(value: number): string {\n\tconst seconds = Math.max(0, Math.trunc(value));\n\tif (seconds < 60) return `${seconds}s`;\n\n\tconst minutes = Math.trunc(seconds / 60);\n\tif (minutes < 60) return `${minutes}m`;\n\n\tconst hours = Math.trunc(minutes / 60);\n\tconst remainingMinutes = minutes % 60;\n\tif (hours >= 24) {\n\t\tconst days = Math.trunc(hours / 24);\n\t\tconst remainingHours = hours % 24;\n\t\treturn `${days}d ${remainingHours}h ${remainingMinutes}m`;\n\t}\n\n\tif (remainingMinutes === 0) return `${hours}h`;\n\treturn `${hours}h ${remainingMinutes}m`;\n}\n\nexport function formatTokensCompact(value: number): string {\n\tconst abs = Math.abs(value);\n\tif (abs >= 1_000_000) return `${formatOneDecimal(value / 1_000_000)}M`;\n\tif (abs >= 1_000) return `${formatOneDecimal(value / 1_000)}K`;\n\treturn `${Math.trunc(value)}`;\n}\n\nexport function goalStatusLabel(status: GoalStatus): string {\n\tswitch (status) {\n\t\tcase \"active\":\n\t\t\treturn \"active\";\n\t\tcase \"paused\":\n\t\t\treturn \"paused\";\n\t\tcase \"blocked\":\n\t\t\treturn \"blocked\";\n\t\tcase \"complete\":\n\t\t\treturn \"complete\";\n\t}\n}\n\nexport function formatGoalForTool(goal: Goal | null): string {\n\tif (!goal) return \"No active goal is set.\";\n\tconst lines = [\n\t\t`Objective: ${goal.objective}`,\n\t\t`Status: ${goalStatusLabel(goal.status)}`,\n\t\t`Time used: ${formatGoalElapsedSeconds(goal.timeUsedSeconds)}`,\n\t\t`Tokens used: ${formatTokensCompact(goal.tokensUsed)}`,\n\t];\n\tif (goal.blockedReason) lines.push(`Blocked reason: ${goal.blockedReason}`);\n\tif (goal.completedAt) lines.push(`Completed at: ${new Date(goal.completedAt * 1000).toISOString()}`);\n\treturn lines.join(\"\\n\");\n}\n\nexport function goalToolResponse(goal: Goal | null): GoalToolResponse {\n\treturn { goal: goal === null ? null : goalToolSnapshot(goal) };\n}\n\nexport function formatGoalToolResponse(goal: Goal | null, notice?: string): string {\n\tconst response = JSON.stringify(goalToolResponse(goal), null, 2);\n\treturn notice === undefined ? response : `${response}\\n${notice}`;\n}\n\nfunction goalToolSnapshot(goal: Goal): GoalToolSnapshot {\n\treturn {\n\t\tthreadId: goal.threadId,\n\t\tobjective: goal.objective,\n\t\tstatus: goal.status,\n\t\ttokensUsed: goal.tokensUsed,\n\t\ttimeUsedSeconds: goal.timeUsedSeconds,\n\t\tcreatedAt: goal.createdAt,\n\t\tupdatedAt: goal.updatedAt,\n\t\t...(goal.blockedReason === undefined ? {} : { blockedReason: goal.blockedReason }),\n\t\t...(goal.blockedAt === undefined ? {} : { blockedAt: goal.blockedAt }),\n\t};\n}\n\nfunction formatOneDecimal(value: number): string {\n\tconst rounded = value.toFixed(1);\n\treturn rounded.endsWith(\".0\") ? rounded.slice(0, -2) : rounded;\n}\n"]}
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/format.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Goal, GoalStatus, GoalToolResponse, GoalToolSnapshot } from \"./types.ts\";\n\nexport function formatGoalElapsedSeconds(value: number): string {\n\tconst seconds = Math.max(0, Math.trunc(value));\n\tif (seconds < 60) return `${seconds}s`;\n\n\tconst minutes = Math.trunc(seconds / 60);\n\tif (minutes < 60) return `${minutes}m`;\n\n\tconst hours = Math.trunc(minutes / 60);\n\tconst remainingMinutes = minutes % 60;\n\tif (hours >= 24) {\n\t\tconst days = Math.trunc(hours / 24);\n\t\tconst remainingHours = hours % 24;\n\t\treturn `${days}d ${remainingHours}h ${remainingMinutes}m`;\n\t}\n\n\tif (remainingMinutes === 0) return `${hours}h`;\n\treturn `${hours}h ${remainingMinutes}m`;\n}\n\nexport function formatTokensCompact(value: number): string {\n\tconst abs = Math.abs(value);\n\tif (abs >= 1_000_000) return `${formatOneDecimal(value / 1_000_000)}M`;\n\tif (abs >= 1_000) return `${formatOneDecimal(value / 1_000)}K`;\n\treturn `${Math.trunc(value)}`;\n}\n\nexport function goalStatusLabel(status: GoalStatus): string {\n\tswitch (status) {\n\t\tcase \"active\":\n\t\t\treturn \"active\";\n\t\tcase \"paused\":\n\t\t\treturn \"paused\";\n\t\tcase \"blocked\":\n\t\t\treturn \"blocked\";\n\t\tcase \"complete\":\n\t\t\treturn \"complete\";\n\t}\n}\n\nexport function formatGoalForTool(goal: Goal | null): string {\n\tif (!goal) return \"No active goal is set.\";\n\tconst lines = [\n\t\t`Objective: ${goal.objective}`,\n\t\t`Status: ${goalStatusLabel(goal.status)}`,\n\t\t`Time used: ${formatGoalElapsedSeconds(goal.timeUsedSeconds)}`,\n\t\t`Tokens used: ${formatTokensCompact(goal.tokensUsed)}`,\n\t];\n\tif (goal.blockedReason) lines.push(`Blocked reason: ${goal.blockedReason}`);\n\tif (goal.completedAt) lines.push(`Completed at: ${new Date(goal.completedAt * 1000).toISOString()}`);\n\treturn lines.join(\"\\n\");\n}\n\nexport type GoalToolRenderDetails = {\n\tgoal: GoalToolSnapshot | null;\n\tnotice?: string;\n};\n\nexport function goalToolRenderDetails(goal: Goal | null, notice?: string): GoalToolRenderDetails {\n\treturn {\n\t\tgoal: goal === null ? null : goalToolSnapshot(goal),\n\t\t...(notice === undefined ? {} : { notice }),\n\t};\n}\n\nexport function goalToolResponse(goal: Goal | null): GoalToolResponse {\n\treturn { goal: goal === null ? null : goalToolSnapshot(goal) };\n}\n\nexport function formatGoalToolResponse(goal: Goal | null, notice?: string): string {\n\tconst response = JSON.stringify(goalToolResponse(goal), null, 2);\n\treturn notice === undefined ? response : `${response}\\n${notice}`;\n}\n\nfunction goalToolSnapshot(goal: Goal): GoalToolSnapshot {\n\treturn {\n\t\tthreadId: goal.threadId,\n\t\tobjective: goal.objective,\n\t\tstatus: goal.status,\n\t\ttokensUsed: goal.tokensUsed,\n\t\ttimeUsedSeconds: goal.timeUsedSeconds,\n\t\tcreatedAt: goal.createdAt,\n\t\tupdatedAt: goal.updatedAt,\n\t\t...(goal.blockedReason === undefined ? {} : { blockedReason: goal.blockedReason }),\n\t\t...(goal.blockedAt === undefined ? {} : { blockedAt: goal.blockedAt }),\n\t};\n}\n\nfunction formatOneDecimal(value: number): string {\n\tconst rounded = value.toFixed(1);\n\treturn rounded.endsWith(\".0\") ? rounded.slice(0, -2) : rounded;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAgCrE,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAoX5D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAgCrE,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA8X5D"}
@@ -246,6 +246,13 @@ export default function goalExtension(pi) {
246
246
  if (!isResumeOfStoppedGoal(ctx, sessionStartReason, goal)) {
247
247
  return false;
248
248
  }
249
+ // RPC switch_session cannot service a nested interactive UI request until the
250
+ // switch response completes. Keep the goal stopped and let the user resume it
251
+ // explicitly after the new session finishes binding.
252
+ if (ctx.mode === "rpc") {
253
+ ctx.ui.notify(`Goal remains ${goal.status} after session resume. Resume it explicitly after the session finishes loading.`, "info");
254
+ return true;
255
+ }
249
256
  const choice = await ctx.ui.select(`Resume ${goal.status} goal?\nGoal: ${goal.objective}`, [
250
257
  RESUME_GOAL_CHOICE,
251
258
  LEAVE_GOAL_STOPPED_CHOICE,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { GOAL_CONTINUATION_MESSAGE_TYPE } from \"../../../messages.ts\";\nimport type { SessionEntry } from \"../../../session-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { continueGoalAfterAgentEnd } from \"./agent-end-continuation.ts\";\nimport { GOAL_CACHE_WARMUP_ENTRY_TYPE } from \"./cache-warm.ts\";\nimport { renderGoalCacheWarmupEntry } from \"./cache-warm-renderer.ts\";\nimport { registerGoalCommand } from \"./command-registration.ts\";\nimport { GOAL_CONTINUATION_CAP } from \"./continuation.ts\";\nimport { GoalDirectInputLifecycle } from \"./direct-input-lifecycle.ts\";\nimport { GoalElapsedTicker } from \"./elapsed-ticker.ts\";\nimport { formatGoalForTool, goalStatusLabel } from \"./format.ts\";\nimport { isResumeOfStoppedGoal, queueGoalContinuation } from \"./lifecycle-helpers.ts\";\nimport { GOAL_CONTINUATION_SCHEDULED_EVENT, MonitorAwareGoalContinuation } from \"./monitor-continuation.ts\";\nimport { migrateLegacyGoalFile } from \"./persistence.ts\";\nimport { reengageGoalAfterReload } from \"./reload-reengagement.ts\";\nimport { isStaleExtensionContextError } from \"./stale-context.ts\";\nimport { accountGoalUsage, readGoal, updateGoal } from \"./store.ts\";\nimport { GOAL_STORE_CHANGED_EVENT, isGoalStoreChangedEvent } from \"./store-changed-event.ts\";\nimport { goalStoreRef as buildGoalStoreRef } from \"./store-ref.ts\";\nimport { staleGoalTodoReminder, todoResultAddsOpenTasks } from \"./todo-gate.ts\";\nimport { registerGoalTools } from \"./tool-registration.ts\";\nimport { TurnUsageTracker } from \"./turn-usage.ts\";\nimport type { Goal, GoalAccountingMode, GoalStoreRef } from \"./types.ts\";\nimport { updateGoalUi } from \"./ui.ts\";\nimport { GOAL_WAIT_STATUS_KEY, GoalWaitTicker } from \"./wait-ticker.ts\";\n\nconst RESUME_GOAL_CHOICE = \"Resume goal\";\nconst LEAVE_GOAL_STOPPED_CHOICE = \"Leave stopped\";\n\ntype AgentGoalAccounting = {\n\tgoalId: string;\n\tmeasuredFromMilliseconds: number;\n};\n\nexport default function goalExtension(pi: ExtensionAPI): void {\n\tlet agentTurnInProgress = false;\n\tlet staleGoalReminderSentThisTurn = false;\n\tlet agentGoalAccounting: AgentGoalAccounting | null = null;\n\tlet blockedThisTurnGoalId: string | null = null;\n\tlet completedThisTurnGoalId: string | null = null;\n\tlet continuationPending = false;\n\tlet activeContext: ExtensionContext | undefined;\n\tconst turnUsage = new TurnUsageTracker();\n\t// No stale-ctx swallow here: GoalWaitTicker retires itself on a stale render\n\t// (a ticker that keeps ticking against a retired ctx freezes the footer\n\t// countdown forever); non-stale render errors still propagate.\n\tconst goalWaitTicker = new GoalWaitTicker({\n\t\trender: (renderCtx, status) => renderCtx.ui.setStatus(GOAL_WAIT_STATUS_KEY, status),\n\t});\n\tconst monitorContinuation = new MonitorAwareGoalContinuation(\n\t\tpi,\n\t\t() => continuationPending,\n\t\t() => {\n\t\t\tcontinuationPending = true;\n\t\t},\n\t\tgoalWaitTicker,\n\t);\n\tconst directInputLifecycle = new GoalDirectInputLifecycle({\n\t\tmonitor: monitorContinuation,\n\t\tgoalStoreRef,\n\t\tbeginAgentGoalAccounting,\n\t\trefreshGoalUi: refreshGoalUiBestEffort,\n\t\tresumeAfterSuppressedLoad: (resumeCtx, goal) => queueGoalContinuationForCurrentSession(pi, resumeCtx, goal),\n\t});\n\n\tconst goalTicker = new GoalElapsedTicker({\n\t\trender: (renderCtx, renderGoal, live) => updateGoalUi(renderCtx, renderGoal, live),\n\t});\n\n\tpi.registerEntryRenderer(GOAL_CACHE_WARMUP_ENTRY_TYPE, renderGoalCacheWarmupEntry);\n\tregisterGoalTools(pi, {\n\t\tgoalStoreRef: (ctx) => buildGoalStoreRef(ctx.sessionManager, ctx.cwd),\n\t\taccountCurrentAgentTurn,\n\t\tbeginAgentGoalAccounting: (goal) => {\n\t\t\tmonitorContinuation.noteContinuationStarted();\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t},\n\t\tmarkGoalBlockedThisTurn,\n\t\tmarkGoalCompletedThisTurn,\n\t\trefreshGoalUi,\n\t});\n\tregisterGoalCommand(pi, {\n\t\tgoalStoreRef: (ctx) => buildGoalStoreRef(ctx.sessionManager, ctx.cwd),\n\t\taccountCurrentAgentTurn,\n\t\tbeginAgentGoalAccounting,\n\t\tstopAgentGoalAccounting,\n\t\tclearAgentGoalAccounting,\n\t\tqueueGoalContinuation: (extensionApi, commandCtx, goal) => {\n\t\t\tvoid queueGoalContinuationForCurrentSession(extensionApi, commandCtx, goal);\n\t\t},\n\t\trefreshGoalUi,\n\t});\n\n\tconst unsubscribeGoalStoreChanged =\n\t\tpi.events?.on(GOAL_STORE_CHANGED_EVENT, async (data) => {\n\t\t\tif (!isGoalStoreChangedEvent(data)) return;\n\t\t\tconst ctx = data.ctx ?? activeContext;\n\t\t\tif (\n\t\t\t\tctx === undefined ||\n\t\t\t\tctx.sessionManager.getSessionId() !== data.threadId ||\n\t\t\t\t!ctx.isIdle() ||\n\t\t\t\tctx.hasPendingMessages()\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\t\tif (goal?.status !== \"active\") return;\n\t\t\tmonitorContinuation.syncGoal(goal);\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t\trefreshGoalUiBestEffort(ctx, goal);\n\t\t\tpi.events?.emit(GOAL_CONTINUATION_SCHEDULED_EVENT, {\n\t\t\t\tgoalId: goal.id,\n\t\t\t\tdelayMs: 0,\n\t\t\t\tactiveMonitorCount: 0,\n\t\t\t\twakeSources: {},\n\t\t\t\treason: GOAL_STORE_CHANGED_EVENT,\n\t\t\t});\n\t\t\tawait queueGoalContinuationForCurrentSession(pi, ctx, goal);\n\t\t}) ?? (() => {});\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tactiveContext = ctx;\n\t\tmonitorContinuation.start(ctx);\n\t\tdirectInputLifecycle.reset();\n\t\tconst ref = goalStoreRef(ctx);\n\t\tawait migrateLegacyGoalFile(ref);\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\trefreshGoalUi(ctx, goal);\n\t\tif (await maybePromptResumeStoppedGoal(pi, ctx, event.reason, goal)) {\n\t\t\treturn;\n\t\t}\n\t\tif (goal && event.reason === \"reload\") {\n\t\t\t// A reload retires the extension generation and every armed continuation\n\t\t\t// timer with it. Re-engage through the reload path: stopped goals stay\n\t\t\t// stopped, active goals resume the wait the reload tore down.\n\t\t\tawait reengageGoalAfterReload({\n\t\t\t\tctx,\n\t\t\t\tgoal,\n\t\t\t\tmonitor: monitorContinuation,\n\t\t\t\tcountTrailingContinuations: () => countTrailingGoalContinuationEntries(ctx.sessionManager.getBranch()),\n\t\t\t\tqueueContinuation: () => queueGoalContinuationForCurrentSession(pi, ctx, goal),\n\t\t\t});\n\t\t} else if (goal) {\n\t\t\t// Migration-lite admission: a resumed session carrying a trailing flood of\n\t\t\t// historical continuations must not reignite on load. Skip the auto-queue,\n\t\t\t// leave the goal active (no status rewrite), and tell the user how to resume.\n\t\t\tconst trailingContinuations = countTrailingGoalContinuationEntries(ctx.sessionManager.getBranch());\n\t\t\tif (trailingContinuations >= GOAL_CONTINUATION_CAP) {\n\t\t\t\t// The load-time flood suppression parks the goal without rewriting its\n\t\t\t\t// status, so the only resume signal left is the user's next message.\n\t\t\t\t// Arm the one-shot latch the direct-input lifecycle fires when that\n\t\t\t\t// message is accepted; without it the promise in the notice is a lie\n\t\t\t\t// and the resumed session sits idle until the goal is recreated.\n\t\t\t\tdirectInputLifecycle.armSuppressedLoadResume();\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Goal auto-continuation suppressed for this resumed session (${trailingContinuations} historical continuations). Send a message to resume.`,\n\t\t\t\t\t\"info\",\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait queueGoalContinuationForCurrentSession(pi, ctx, goal);\n\t\t\t}\n\t\t}\n\t});\n\n\tpi.on(\"input\", async (event, ctx) => {\n\t\tawait directInputLifecycle.onInput(event, ctx);\n\t});\n\n\tpi.on(\"input_disposition\", async (event, ctx) => {\n\t\tawait directInputLifecycle.onDisposition(event, ctx);\n\t});\n\n\tpi.on(\"turn_start\", async () => {\n\t\tstaleGoalReminderSentThisTurn = false;\n\t});\n\n\t// When the model starts tracking new open todo work while the thread has no\n\t// goal (or only a stale, already-complete one), append a system reminder to\n\t// the todo result so the model registers the goal when the work warrants it.\n\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\tif (event.toolName !== \"todo\" || event.isError || staleGoalReminderSentThisTurn) return undefined;\n\t\tif (!todoResultAddsOpenTasks(event.details)) return undefined;\n\t\tconst reminder = staleGoalTodoReminder(await readGoal(goalStoreRef(ctx)));\n\t\tif (reminder === undefined) return undefined;\n\t\tstaleGoalReminderSentThisTurn = true;\n\t\treturn { content: [...event.content, { type: \"text\" as const, text: reminder }] };\n\t});\n\n\tpi.on(\"agent_start\", async (_event, ctx) => {\n\t\tconst continuationStarted = continuationPending;\n\t\tcontinuationPending = false;\n\t\tif (continuationStarted) monitorContinuation.noteContinuationStarted();\n\t\tagentTurnInProgress = true;\n\t\tblockedThisTurnGoalId = null;\n\t\tcompletedThisTurnGoalId = null;\n\t\tturnUsage.reset();\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tagentGoalAccounting = null;\n\t\t}\n\t});\n\n\tpi.on(\"message_end\", async (event) => {\n\t\tturnUsage.noteMessageEnd(event.message);\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\tconst mode: GoalAccountingMode =\n\t\t\tblockedThisTurnGoalId !== null\n\t\t\t\t? \"activeOrBlocked\"\n\t\t\t\t: completedThisTurnGoalId === null\n\t\t\t\t\t? \"active\"\n\t\t\t\t\t: \"activeOrComplete\";\n\t\tlet goal = await accountCurrentAgentTurn(ctx, mode, event.messages);\n\t\tagentTurnInProgress = false;\n\t\tblockedThisTurnGoalId = null;\n\t\tcompletedThisTurnGoalId = null;\n\t\tif (event.aborted === true && event.abortSource === \"user\" && goal?.status === \"active\") {\n\t\t\tgoal = await updateGoal(\n\t\t\t\tgoalStoreRef(ctx),\n\t\t\t\t{ status: \"blocked\", reason: \"user interrupted the turn\" },\n\t\t\t\t\"model\",\n\t\t\t);\n\t\t}\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\trefreshGoalUiBestEffort(ctx, goal);\n\t\tconst continuationGoal = await continueGoalAfterAgentEnd(monitorContinuation, { ctx, event, goal });\n\t\tif (continuationGoal !== goal) {\n\t\t\tgoal = continuationGoal;\n\t\t\tsyncContinuationGoal(ctx, goal);\n\t\t}\n\t});\n\n\tpi.on(\"agent_settled\", async (_event, ctx) => {\n\t\tconst goal = await monitorContinuation.afterAgentSettled();\n\t\tif (goal !== undefined) syncContinuationGoal(ctx, goal);\n\t});\n\n\tpi.on(\"session_abort\", async (_event, ctx) => {\n\t\tcontinuationPending = false;\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status !== \"active\") return;\n\t\tconst accounted = await accountCurrentAgentTurn(ctx, \"active\");\n\t\tif (accounted?.status === \"active\") {\n\t\t\tconst blocked = await updateGoal(\n\t\t\t\tgoalStoreRef(ctx),\n\t\t\t\t{ status: \"blocked\", reason: \"user interrupted the turn\" },\n\t\t\t\t\"model\",\n\t\t\t);\n\t\t\tclearAgentGoalAccounting();\n\t\t\trefreshGoalUiBestEffort(ctx, blocked);\n\t\t}\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tactiveContext = undefined;\n\t\tunsubscribeGoalStoreChanged();\n\t\tif (agentGoalAccounting !== null) {\n\t\t\tawait accountCurrentAgentTurn(ctx, \"active\");\n\t\t}\n\t\tclearAgentGoalAccounting();\n\t\tgoalTicker.stop();\n\t\tmonitorContinuation.dispose();\n\t});\n\n\tasync function maybePromptResumeStoppedGoal(\n\t\tpi: ExtensionAPI,\n\t\tctx: ExtensionContext,\n\t\tsessionStartReason: string,\n\t\tgoal: Goal | null,\n\t): Promise<boolean> {\n\t\tif (!isResumeOfStoppedGoal(ctx, sessionStartReason, goal)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst choice = await ctx.ui.select(`Resume ${goal.status} goal?\\nGoal: ${goal.objective}`, [\n\t\t\tRESUME_GOAL_CHOICE,\n\t\t\tLEAVE_GOAL_STOPPED_CHOICE,\n\t\t]);\n\t\tif (choice !== RESUME_GOAL_CHOICE) return true;\n\n\t\tconst resumed = await updateGoal(goalStoreRef(ctx), { status: \"active\" }, \"user\");\n\t\tbeginAgentGoalAccounting(resumed);\n\t\trefreshGoalUi(ctx, resumed);\n\t\tctx.ui.notify(`Goal ${goalStatusLabel(resumed.status)}\\n${formatGoalForTool(resumed)}`, \"info\");\n\t\tawait queueGoalContinuationForCurrentSession(pi, ctx, resumed);\n\t\treturn true;\n\t}\n\n\tasync function queueGoalContinuationForCurrentSession(\n\t\textensionApi: ExtensionAPI,\n\t\tctx: ExtensionContext,\n\t\tgoal: Goal,\n\t): Promise<void> {\n\t\tconst continuedGoal = await queueGoalContinuation(extensionApi, ctx, goal, {\n\t\t\tcontinuationPending,\n\t\t\tmarkContinuationPending: () => {\n\t\t\t\tcontinuationPending = true;\n\t\t\t},\n\t\t});\n\t\tif (continuedGoal === null) {\n\t\t\tclearAgentGoalAccounting();\n\t\t\trefreshGoalUiBestEffort(ctx, null);\n\t\t\treturn;\n\t\t}\n\t\tif (continuedGoal.status === goal.status) return;\n\t\tif (continuedGoal.status === \"active\") beginAgentGoalAccounting(continuedGoal);\n\t\telse clearAgentGoalAccounting();\n\t\trefreshGoalUiBestEffort(ctx, continuedGoal);\n\t}\n\n\tfunction beginAgentGoalAccounting(goal: Goal): void {\n\t\tif (goal.status !== \"active\") return;\n\t\tif (agentGoalAccounting?.goalId === goal.id) return;\n\t\tturnUsage.discardPending();\n\t\tagentGoalAccounting = { goalId: goal.id, measuredFromMilliseconds: Date.now() };\n\t}\n\n\tfunction markGoalBlockedThisTurn(goal: Goal): void {\n\t\tif (agentTurnInProgress) blockedThisTurnGoalId = goal.id;\n\t}\n\n\tfunction markGoalCompletedThisTurn(goal: Goal): void {\n\t\tif (!agentTurnInProgress) return;\n\t\tcompletedThisTurnGoalId = goal.id;\n\t\tagentGoalAccounting = { goalId: goal.id, measuredFromMilliseconds: Date.now() };\n\t}\n\n\tfunction stopAgentGoalAccounting(goalId: string): void {\n\t\tif (agentGoalAccounting?.goalId === goalId) {\n\t\t\tagentGoalAccounting = null;\n\t\t}\n\t\tif (blockedThisTurnGoalId === goalId) {\n\t\t\tblockedThisTurnGoalId = null;\n\t\t}\n\t\tif (completedThisTurnGoalId === goalId) {\n\t\t\tcompletedThisTurnGoalId = null;\n\t\t}\n\t}\n\n\tfunction clearAgentGoalAccounting(): void {\n\t\tagentGoalAccounting = null;\n\t\tblockedThisTurnGoalId = null;\n\t\tcompletedThisTurnGoalId = null;\n\t}\n\n\tfunction syncContinuationGoal(ctx: ExtensionContext, goal: Goal | null): void {\n\t\tif (goal?.status === \"active\") beginAgentGoalAccounting(goal);\n\t\telse clearAgentGoalAccounting();\n\t\trefreshGoalUiBestEffort(ctx, goal);\n\t}\n\n\tfunction refreshGoalUi(ctx: ExtensionContext, goal: Goal | null): void {\n\t\tmonitorContinuation.syncGoal(goal);\n\t\tconst accounting = agentGoalAccounting;\n\t\tif (ctx.hasUI && goal?.status === \"active\" && accounting?.goalId === goal.id) {\n\t\t\tgoalTicker.sync(ctx, goal, accounting.measuredFromMilliseconds);\n\t\t\treturn;\n\t\t}\n\t\tgoalTicker.stop();\n\t\tupdateGoalUi(ctx, goal);\n\t}\n\n\tfunction refreshGoalUiBestEffort(ctx: ExtensionContext, goal: Goal | null): void {\n\t\ttry {\n\t\t\trefreshGoalUi(ctx, goal);\n\t\t} catch (error) {\n\t\t\tif (isStaleExtensionContextError(error)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function accountCurrentAgentTurn(\n\t\tctx: ExtensionContext,\n\t\tmode: GoalAccountingMode,\n\t\tagentRunMessages?: unknown[],\n\t): Promise<Goal | null> {\n\t\tconst accounting = agentGoalAccounting;\n\t\tconst ref = goalStoreRef(ctx);\n\t\tif (accounting === null) return readGoal(ref);\n\n\t\tconst usage =\n\t\t\tagentRunMessages === undefined ? turnUsage.takePending() : turnUsage.takeRemaining(agentRunMessages);\n\t\tconst now = Date.now();\n\t\tconst elapsedSeconds = Math.max(0, Math.round((now - accounting.measuredFromMilliseconds) / 1000));\n\t\tconst goal = await accountGoalUsage(ref, usage, elapsedSeconds, mode, accounting.goalId);\n\t\tif (goal?.id === accounting.goalId) {\n\t\t\tagentGoalAccounting = { goalId: accounting.goalId, measuredFromMilliseconds: now };\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\treturn goal;\n\t}\n}\n\n/**\n * Counts goal-continuation entries queued since the most recent real user message\n * in the current branch (mirrors the todo-gate / todo-bridge backward branch read).\n * A real user message is the only reset: the assistant turns in between are exactly\n * the unattended loop this admission guard exists to stop.\n */\nfunction countTrailingGoalContinuationEntries(entries: readonly SessionEntry[]): number {\n\tlet count = 0;\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type === \"message\" && entry.message.role === \"user\") break;\n\t\tif (entry?.type === \"custom_message\" && entry.customType === GOAL_CONTINUATION_MESSAGE_TYPE) count += 1;\n\t}\n\treturn count;\n}\n\nfunction goalStoreRef(ctx: ExtensionContext): GoalStoreRef {\n\treturn buildGoalStoreRef(ctx.sessionManager, ctx.cwd);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { GOAL_CONTINUATION_MESSAGE_TYPE } from \"../../../messages.ts\";\nimport type { SessionEntry } from \"../../../session-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { continueGoalAfterAgentEnd } from \"./agent-end-continuation.ts\";\nimport { GOAL_CACHE_WARMUP_ENTRY_TYPE } from \"./cache-warm.ts\";\nimport { renderGoalCacheWarmupEntry } from \"./cache-warm-renderer.ts\";\nimport { registerGoalCommand } from \"./command-registration.ts\";\nimport { GOAL_CONTINUATION_CAP } from \"./continuation.ts\";\nimport { GoalDirectInputLifecycle } from \"./direct-input-lifecycle.ts\";\nimport { GoalElapsedTicker } from \"./elapsed-ticker.ts\";\nimport { formatGoalForTool, goalStatusLabel } from \"./format.ts\";\nimport { isResumeOfStoppedGoal, queueGoalContinuation } from \"./lifecycle-helpers.ts\";\nimport { GOAL_CONTINUATION_SCHEDULED_EVENT, MonitorAwareGoalContinuation } from \"./monitor-continuation.ts\";\nimport { migrateLegacyGoalFile } from \"./persistence.ts\";\nimport { reengageGoalAfterReload } from \"./reload-reengagement.ts\";\nimport { isStaleExtensionContextError } from \"./stale-context.ts\";\nimport { accountGoalUsage, readGoal, updateGoal } from \"./store.ts\";\nimport { GOAL_STORE_CHANGED_EVENT, isGoalStoreChangedEvent } from \"./store-changed-event.ts\";\nimport { goalStoreRef as buildGoalStoreRef } from \"./store-ref.ts\";\nimport { staleGoalTodoReminder, todoResultAddsOpenTasks } from \"./todo-gate.ts\";\nimport { registerGoalTools } from \"./tool-registration.ts\";\nimport { TurnUsageTracker } from \"./turn-usage.ts\";\nimport type { Goal, GoalAccountingMode, GoalStoreRef } from \"./types.ts\";\nimport { updateGoalUi } from \"./ui.ts\";\nimport { GOAL_WAIT_STATUS_KEY, GoalWaitTicker } from \"./wait-ticker.ts\";\n\nconst RESUME_GOAL_CHOICE = \"Resume goal\";\nconst LEAVE_GOAL_STOPPED_CHOICE = \"Leave stopped\";\n\ntype AgentGoalAccounting = {\n\tgoalId: string;\n\tmeasuredFromMilliseconds: number;\n};\n\nexport default function goalExtension(pi: ExtensionAPI): void {\n\tlet agentTurnInProgress = false;\n\tlet staleGoalReminderSentThisTurn = false;\n\tlet agentGoalAccounting: AgentGoalAccounting | null = null;\n\tlet blockedThisTurnGoalId: string | null = null;\n\tlet completedThisTurnGoalId: string | null = null;\n\tlet continuationPending = false;\n\tlet activeContext: ExtensionContext | undefined;\n\tconst turnUsage = new TurnUsageTracker();\n\t// No stale-ctx swallow here: GoalWaitTicker retires itself on a stale render\n\t// (a ticker that keeps ticking against a retired ctx freezes the footer\n\t// countdown forever); non-stale render errors still propagate.\n\tconst goalWaitTicker = new GoalWaitTicker({\n\t\trender: (renderCtx, status) => renderCtx.ui.setStatus(GOAL_WAIT_STATUS_KEY, status),\n\t});\n\tconst monitorContinuation = new MonitorAwareGoalContinuation(\n\t\tpi,\n\t\t() => continuationPending,\n\t\t() => {\n\t\t\tcontinuationPending = true;\n\t\t},\n\t\tgoalWaitTicker,\n\t);\n\tconst directInputLifecycle = new GoalDirectInputLifecycle({\n\t\tmonitor: monitorContinuation,\n\t\tgoalStoreRef,\n\t\tbeginAgentGoalAccounting,\n\t\trefreshGoalUi: refreshGoalUiBestEffort,\n\t\tresumeAfterSuppressedLoad: (resumeCtx, goal) => queueGoalContinuationForCurrentSession(pi, resumeCtx, goal),\n\t});\n\n\tconst goalTicker = new GoalElapsedTicker({\n\t\trender: (renderCtx, renderGoal, live) => updateGoalUi(renderCtx, renderGoal, live),\n\t});\n\n\tpi.registerEntryRenderer(GOAL_CACHE_WARMUP_ENTRY_TYPE, renderGoalCacheWarmupEntry);\n\tregisterGoalTools(pi, {\n\t\tgoalStoreRef: (ctx) => buildGoalStoreRef(ctx.sessionManager, ctx.cwd),\n\t\taccountCurrentAgentTurn,\n\t\tbeginAgentGoalAccounting: (goal) => {\n\t\t\tmonitorContinuation.noteContinuationStarted();\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t},\n\t\tmarkGoalBlockedThisTurn,\n\t\tmarkGoalCompletedThisTurn,\n\t\trefreshGoalUi,\n\t});\n\tregisterGoalCommand(pi, {\n\t\tgoalStoreRef: (ctx) => buildGoalStoreRef(ctx.sessionManager, ctx.cwd),\n\t\taccountCurrentAgentTurn,\n\t\tbeginAgentGoalAccounting,\n\t\tstopAgentGoalAccounting,\n\t\tclearAgentGoalAccounting,\n\t\tqueueGoalContinuation: (extensionApi, commandCtx, goal) => {\n\t\t\tvoid queueGoalContinuationForCurrentSession(extensionApi, commandCtx, goal);\n\t\t},\n\t\trefreshGoalUi,\n\t});\n\n\tconst unsubscribeGoalStoreChanged =\n\t\tpi.events?.on(GOAL_STORE_CHANGED_EVENT, async (data) => {\n\t\t\tif (!isGoalStoreChangedEvent(data)) return;\n\t\t\tconst ctx = data.ctx ?? activeContext;\n\t\t\tif (\n\t\t\t\tctx === undefined ||\n\t\t\t\tctx.sessionManager.getSessionId() !== data.threadId ||\n\t\t\t\t!ctx.isIdle() ||\n\t\t\t\tctx.hasPendingMessages()\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\t\tif (goal?.status !== \"active\") return;\n\t\t\tmonitorContinuation.syncGoal(goal);\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t\trefreshGoalUiBestEffort(ctx, goal);\n\t\t\tpi.events?.emit(GOAL_CONTINUATION_SCHEDULED_EVENT, {\n\t\t\t\tgoalId: goal.id,\n\t\t\t\tdelayMs: 0,\n\t\t\t\tactiveMonitorCount: 0,\n\t\t\t\twakeSources: {},\n\t\t\t\treason: GOAL_STORE_CHANGED_EVENT,\n\t\t\t});\n\t\t\tawait queueGoalContinuationForCurrentSession(pi, ctx, goal);\n\t\t}) ?? (() => {});\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tactiveContext = ctx;\n\t\tmonitorContinuation.start(ctx);\n\t\tdirectInputLifecycle.reset();\n\t\tconst ref = goalStoreRef(ctx);\n\t\tawait migrateLegacyGoalFile(ref);\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\trefreshGoalUi(ctx, goal);\n\t\tif (await maybePromptResumeStoppedGoal(pi, ctx, event.reason, goal)) {\n\t\t\treturn;\n\t\t}\n\t\tif (goal && event.reason === \"reload\") {\n\t\t\t// A reload retires the extension generation and every armed continuation\n\t\t\t// timer with it. Re-engage through the reload path: stopped goals stay\n\t\t\t// stopped, active goals resume the wait the reload tore down.\n\t\t\tawait reengageGoalAfterReload({\n\t\t\t\tctx,\n\t\t\t\tgoal,\n\t\t\t\tmonitor: monitorContinuation,\n\t\t\t\tcountTrailingContinuations: () => countTrailingGoalContinuationEntries(ctx.sessionManager.getBranch()),\n\t\t\t\tqueueContinuation: () => queueGoalContinuationForCurrentSession(pi, ctx, goal),\n\t\t\t});\n\t\t} else if (goal) {\n\t\t\t// Migration-lite admission: a resumed session carrying a trailing flood of\n\t\t\t// historical continuations must not reignite on load. Skip the auto-queue,\n\t\t\t// leave the goal active (no status rewrite), and tell the user how to resume.\n\t\t\tconst trailingContinuations = countTrailingGoalContinuationEntries(ctx.sessionManager.getBranch());\n\t\t\tif (trailingContinuations >= GOAL_CONTINUATION_CAP) {\n\t\t\t\t// The load-time flood suppression parks the goal without rewriting its\n\t\t\t\t// status, so the only resume signal left is the user's next message.\n\t\t\t\t// Arm the one-shot latch the direct-input lifecycle fires when that\n\t\t\t\t// message is accepted; without it the promise in the notice is a lie\n\t\t\t\t// and the resumed session sits idle until the goal is recreated.\n\t\t\t\tdirectInputLifecycle.armSuppressedLoadResume();\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Goal auto-continuation suppressed for this resumed session (${trailingContinuations} historical continuations). Send a message to resume.`,\n\t\t\t\t\t\"info\",\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait queueGoalContinuationForCurrentSession(pi, ctx, goal);\n\t\t\t}\n\t\t}\n\t});\n\n\tpi.on(\"input\", async (event, ctx) => {\n\t\tawait directInputLifecycle.onInput(event, ctx);\n\t});\n\n\tpi.on(\"input_disposition\", async (event, ctx) => {\n\t\tawait directInputLifecycle.onDisposition(event, ctx);\n\t});\n\n\tpi.on(\"turn_start\", async () => {\n\t\tstaleGoalReminderSentThisTurn = false;\n\t});\n\n\t// When the model starts tracking new open todo work while the thread has no\n\t// goal (or only a stale, already-complete one), append a system reminder to\n\t// the todo result so the model registers the goal when the work warrants it.\n\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\tif (event.toolName !== \"todo\" || event.isError || staleGoalReminderSentThisTurn) return undefined;\n\t\tif (!todoResultAddsOpenTasks(event.details)) return undefined;\n\t\tconst reminder = staleGoalTodoReminder(await readGoal(goalStoreRef(ctx)));\n\t\tif (reminder === undefined) return undefined;\n\t\tstaleGoalReminderSentThisTurn = true;\n\t\treturn { content: [...event.content, { type: \"text\" as const, text: reminder }] };\n\t});\n\n\tpi.on(\"agent_start\", async (_event, ctx) => {\n\t\tconst continuationStarted = continuationPending;\n\t\tcontinuationPending = false;\n\t\tif (continuationStarted) monitorContinuation.noteContinuationStarted();\n\t\tagentTurnInProgress = true;\n\t\tblockedThisTurnGoalId = null;\n\t\tcompletedThisTurnGoalId = null;\n\t\tturnUsage.reset();\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tagentGoalAccounting = null;\n\t\t}\n\t});\n\n\tpi.on(\"message_end\", async (event) => {\n\t\tturnUsage.noteMessageEnd(event.message);\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\tconst mode: GoalAccountingMode =\n\t\t\tblockedThisTurnGoalId !== null\n\t\t\t\t? \"activeOrBlocked\"\n\t\t\t\t: completedThisTurnGoalId === null\n\t\t\t\t\t? \"active\"\n\t\t\t\t\t: \"activeOrComplete\";\n\t\tlet goal = await accountCurrentAgentTurn(ctx, mode, event.messages);\n\t\tagentTurnInProgress = false;\n\t\tblockedThisTurnGoalId = null;\n\t\tcompletedThisTurnGoalId = null;\n\t\tif (event.aborted === true && event.abortSource === \"user\" && goal?.status === \"active\") {\n\t\t\tgoal = await updateGoal(\n\t\t\t\tgoalStoreRef(ctx),\n\t\t\t\t{ status: \"blocked\", reason: \"user interrupted the turn\" },\n\t\t\t\t\"model\",\n\t\t\t);\n\t\t}\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\trefreshGoalUiBestEffort(ctx, goal);\n\t\tconst continuationGoal = await continueGoalAfterAgentEnd(monitorContinuation, { ctx, event, goal });\n\t\tif (continuationGoal !== goal) {\n\t\t\tgoal = continuationGoal;\n\t\t\tsyncContinuationGoal(ctx, goal);\n\t\t}\n\t});\n\n\tpi.on(\"agent_settled\", async (_event, ctx) => {\n\t\tconst goal = await monitorContinuation.afterAgentSettled();\n\t\tif (goal !== undefined) syncContinuationGoal(ctx, goal);\n\t});\n\n\tpi.on(\"session_abort\", async (_event, ctx) => {\n\t\tcontinuationPending = false;\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status !== \"active\") return;\n\t\tconst accounted = await accountCurrentAgentTurn(ctx, \"active\");\n\t\tif (accounted?.status === \"active\") {\n\t\t\tconst blocked = await updateGoal(\n\t\t\t\tgoalStoreRef(ctx),\n\t\t\t\t{ status: \"blocked\", reason: \"user interrupted the turn\" },\n\t\t\t\t\"model\",\n\t\t\t);\n\t\t\tclearAgentGoalAccounting();\n\t\t\trefreshGoalUiBestEffort(ctx, blocked);\n\t\t}\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tactiveContext = undefined;\n\t\tunsubscribeGoalStoreChanged();\n\t\tif (agentGoalAccounting !== null) {\n\t\t\tawait accountCurrentAgentTurn(ctx, \"active\");\n\t\t}\n\t\tclearAgentGoalAccounting();\n\t\tgoalTicker.stop();\n\t\tmonitorContinuation.dispose();\n\t});\n\n\tasync function maybePromptResumeStoppedGoal(\n\t\tpi: ExtensionAPI,\n\t\tctx: ExtensionContext,\n\t\tsessionStartReason: string,\n\t\tgoal: Goal | null,\n\t): Promise<boolean> {\n\t\tif (!isResumeOfStoppedGoal(ctx, sessionStartReason, goal)) {\n\t\t\treturn false;\n\t\t}\n\t\t// RPC switch_session cannot service a nested interactive UI request until the\n\t\t// switch response completes. Keep the goal stopped and let the user resume it\n\t\t// explicitly after the new session finishes binding.\n\t\tif (ctx.mode === \"rpc\") {\n\t\t\tctx.ui.notify(\n\t\t\t\t`Goal remains ${goal.status} after session resume. Resume it explicitly after the session finishes loading.`,\n\t\t\t\t\"info\",\n\t\t\t);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst choice = await ctx.ui.select(`Resume ${goal.status} goal?\\nGoal: ${goal.objective}`, [\n\t\t\tRESUME_GOAL_CHOICE,\n\t\t\tLEAVE_GOAL_STOPPED_CHOICE,\n\t\t]);\n\t\tif (choice !== RESUME_GOAL_CHOICE) return true;\n\n\t\tconst resumed = await updateGoal(goalStoreRef(ctx), { status: \"active\" }, \"user\");\n\t\tbeginAgentGoalAccounting(resumed);\n\t\trefreshGoalUi(ctx, resumed);\n\t\tctx.ui.notify(`Goal ${goalStatusLabel(resumed.status)}\\n${formatGoalForTool(resumed)}`, \"info\");\n\t\tawait queueGoalContinuationForCurrentSession(pi, ctx, resumed);\n\t\treturn true;\n\t}\n\n\tasync function queueGoalContinuationForCurrentSession(\n\t\textensionApi: ExtensionAPI,\n\t\tctx: ExtensionContext,\n\t\tgoal: Goal,\n\t): Promise<void> {\n\t\tconst continuedGoal = await queueGoalContinuation(extensionApi, ctx, goal, {\n\t\t\tcontinuationPending,\n\t\t\tmarkContinuationPending: () => {\n\t\t\t\tcontinuationPending = true;\n\t\t\t},\n\t\t});\n\t\tif (continuedGoal === null) {\n\t\t\tclearAgentGoalAccounting();\n\t\t\trefreshGoalUiBestEffort(ctx, null);\n\t\t\treturn;\n\t\t}\n\t\tif (continuedGoal.status === goal.status) return;\n\t\tif (continuedGoal.status === \"active\") beginAgentGoalAccounting(continuedGoal);\n\t\telse clearAgentGoalAccounting();\n\t\trefreshGoalUiBestEffort(ctx, continuedGoal);\n\t}\n\n\tfunction beginAgentGoalAccounting(goal: Goal): void {\n\t\tif (goal.status !== \"active\") return;\n\t\tif (agentGoalAccounting?.goalId === goal.id) return;\n\t\tturnUsage.discardPending();\n\t\tagentGoalAccounting = { goalId: goal.id, measuredFromMilliseconds: Date.now() };\n\t}\n\n\tfunction markGoalBlockedThisTurn(goal: Goal): void {\n\t\tif (agentTurnInProgress) blockedThisTurnGoalId = goal.id;\n\t}\n\n\tfunction markGoalCompletedThisTurn(goal: Goal): void {\n\t\tif (!agentTurnInProgress) return;\n\t\tcompletedThisTurnGoalId = goal.id;\n\t\tagentGoalAccounting = { goalId: goal.id, measuredFromMilliseconds: Date.now() };\n\t}\n\n\tfunction stopAgentGoalAccounting(goalId: string): void {\n\t\tif (agentGoalAccounting?.goalId === goalId) {\n\t\t\tagentGoalAccounting = null;\n\t\t}\n\t\tif (blockedThisTurnGoalId === goalId) {\n\t\t\tblockedThisTurnGoalId = null;\n\t\t}\n\t\tif (completedThisTurnGoalId === goalId) {\n\t\t\tcompletedThisTurnGoalId = null;\n\t\t}\n\t}\n\n\tfunction clearAgentGoalAccounting(): void {\n\t\tagentGoalAccounting = null;\n\t\tblockedThisTurnGoalId = null;\n\t\tcompletedThisTurnGoalId = null;\n\t}\n\n\tfunction syncContinuationGoal(ctx: ExtensionContext, goal: Goal | null): void {\n\t\tif (goal?.status === \"active\") beginAgentGoalAccounting(goal);\n\t\telse clearAgentGoalAccounting();\n\t\trefreshGoalUiBestEffort(ctx, goal);\n\t}\n\n\tfunction refreshGoalUi(ctx: ExtensionContext, goal: Goal | null): void {\n\t\tmonitorContinuation.syncGoal(goal);\n\t\tconst accounting = agentGoalAccounting;\n\t\tif (ctx.hasUI && goal?.status === \"active\" && accounting?.goalId === goal.id) {\n\t\t\tgoalTicker.sync(ctx, goal, accounting.measuredFromMilliseconds);\n\t\t\treturn;\n\t\t}\n\t\tgoalTicker.stop();\n\t\tupdateGoalUi(ctx, goal);\n\t}\n\n\tfunction refreshGoalUiBestEffort(ctx: ExtensionContext, goal: Goal | null): void {\n\t\ttry {\n\t\t\trefreshGoalUi(ctx, goal);\n\t\t} catch (error) {\n\t\t\tif (isStaleExtensionContextError(error)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function accountCurrentAgentTurn(\n\t\tctx: ExtensionContext,\n\t\tmode: GoalAccountingMode,\n\t\tagentRunMessages?: unknown[],\n\t): Promise<Goal | null> {\n\t\tconst accounting = agentGoalAccounting;\n\t\tconst ref = goalStoreRef(ctx);\n\t\tif (accounting === null) return readGoal(ref);\n\n\t\tconst usage =\n\t\t\tagentRunMessages === undefined ? turnUsage.takePending() : turnUsage.takeRemaining(agentRunMessages);\n\t\tconst now = Date.now();\n\t\tconst elapsedSeconds = Math.max(0, Math.round((now - accounting.measuredFromMilliseconds) / 1000));\n\t\tconst goal = await accountGoalUsage(ref, usage, elapsedSeconds, mode, accounting.goalId);\n\t\tif (goal?.id === accounting.goalId) {\n\t\t\tagentGoalAccounting = { goalId: accounting.goalId, measuredFromMilliseconds: now };\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\treturn goal;\n\t}\n}\n\n/**\n * Counts goal-continuation entries queued since the most recent real user message\n * in the current branch (mirrors the todo-gate / todo-bridge backward branch read).\n * A real user message is the only reset: the assistant turns in between are exactly\n * the unattended loop this admission guard exists to stop.\n */\nfunction countTrailingGoalContinuationEntries(entries: readonly SessionEntry[]): number {\n\tlet count = 0;\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type === \"message\" && entry.message.role === \"user\") break;\n\t\tif (entry?.type === \"custom_message\" && entry.customType === GOAL_CONTINUATION_MESSAGE_TYPE) count += 1;\n\t}\n\treturn count;\n}\n\nfunction goalStoreRef(ctx: ExtensionContext): GoalStoreRef {\n\treturn buildGoalStoreRef(ctx.sessionManager, ctx.cwd);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-helpers.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/lifecycle-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAGlE,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAGN,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAE5B,MAAM,mBAAmB,CAAC;AAW3B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,KAAK,iCAAiC,GAAG,OAAO,CAAC,uBAAuB,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAEhG,KAAK,+BAA+B,GAAG;IACtC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,iCAAiC,KAAK,MAAM,CAAC;IACzE,QAAQ,CAAC,uBAAuB,EAAE,MAAM,IAAI,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC7C,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,uBAAuB,EAAE,MAAM,IAAI,CAAC;CAC7C,CAAC;AAQF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,gBAAgB,EACrB,kBAAkB,EAAE,MAAM,EAC1B,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,IAAI,CASd;AAED,sFAAsF;AACtF,wBAAsB,6BAA6B,CAClD,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,+BAA+B,GACtC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAgBtB;AAED,mHAAmH;AACnH,wBAAsB,qBAAqB,CAC1C,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,+BAA+B,GACtC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAuBtB;AAED,wBAAgB,qCAAqC,CACpD,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,IAAI,EACV,iBAAiB,EAAE,MAAM,GACvB,MAAM,CAKR;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAM3E;AA0DD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAK7E"}
1
+ {"version":3,"file":"lifecycle-helpers.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/lifecycle-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAGlE,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAGN,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAE5B,MAAM,mBAAmB,CAAC;AAY3B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,KAAK,iCAAiC,GAAG,OAAO,CAAC,uBAAuB,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAEhG,KAAK,+BAA+B,GAAG;IACtC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,iCAAiC,KAAK,MAAM,CAAC;IACzE,QAAQ,CAAC,uBAAuB,EAAE,MAAM,IAAI,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC7C,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,uBAAuB,EAAE,MAAM,IAAI,CAAC;CAC7C,CAAC;AAQF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,gBAAgB,EACrB,kBAAkB,EAAE,MAAM,EAC1B,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,IAAI,IAAI,IAAI,CASd;AAED,sFAAsF;AACtF,wBAAsB,6BAA6B,CAClD,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,+BAA+B,GACtC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAiBtB;AAED,mHAAmH;AACnH,wBAAsB,qBAAqB,CAC1C,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,+BAA+B,GACtC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAuBtB;AAED,wBAAgB,qCAAqC,CACpD,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,IAAI,EACV,iBAAiB,EAAE,MAAM,GACvB,MAAM,CAKR;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAM3E;AA6DD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAK7E"}
@@ -1,7 +1,7 @@
1
1
  import { GOAL_CONTINUATION_MESSAGE_TYPE } from "../../../messages.js";
2
2
  import { getLatestPhasesFromBranchEntries } from "../todotools/state.js";
3
3
  import { buildGoalContinuationSignature, evaluateGoalContinuation, hashAssistantText, } from "./continuation.js";
4
- import { CONTINUATION_CAP_BLOCKED_REASON, continuationCapRecoveryHint, LENGTH_EXHAUSTED_BLOCKED_REASON, REPETITION_BLOCKED_REASON, } from "./continuation-recovery.js";
4
+ import { CONTINUATION_CAP_BLOCKED_REASON, continuationCapRecoveryHint, LENGTH_EXHAUSTED_BLOCKED_REASON, REPETITION_BLOCKED_REASON, UNATTENDED_CONTINUATION_BLOCKED_REASON, } from "./continuation-recovery.js";
5
5
  import { buildContinuationPrompt } from "./prompt.js";
6
6
  import { recordContinuationDelivered, updateGoal } from "./store.js";
7
7
  import { goalStoreRef } from "./store-ref.js";
@@ -33,7 +33,7 @@ export async function admitAndQueueGoalContinuation(pi, ctx, goal, options) {
33
33
  if (options.input.currentSignature === undefined) {
34
34
  throw new Error("Cannot queue a goal continuation without a progress signature");
35
35
  }
36
- const recordedGoal = await recordContinuationDelivered(goalStoreRef(ctx.sessionManager, ctx.cwd), options.input.currentSignature, goal.id);
36
+ const recordedGoal = await recordContinuationDelivered(goalStoreRef(ctx.sessionManager, ctx.cwd), options.input.currentSignature, goal.id, { countUnattended: options.input.path !== "monitorDelayed" });
37
37
  if (recordedGoal === null)
38
38
  return null;
39
39
  options.markContinuationPending();
@@ -100,6 +100,7 @@ async function handleDeniedContinuation(pi, ctx, goal, input, reason) {
100
100
  goalId: goal.id,
101
101
  reason,
102
102
  count: input.consecutiveContinuations,
103
+ unattendedContinuations: goal.unattendedContinuations ?? 0,
103
104
  });
104
105
  return blocked;
105
106
  }
@@ -107,6 +108,8 @@ function blockedReasonForContinuationGuard(reason) {
107
108
  switch (reason) {
108
109
  case "cap":
109
110
  return CONTINUATION_CAP_BLOCKED_REASON;
111
+ case "unattended":
112
+ return UNATTENDED_CONTINUATION_BLOCKED_REASON;
110
113
  case "repetition":
111
114
  return REPETITION_BLOCKED_REASON;
112
115
  case "length-exhausted":
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-helpers.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/lifecycle-helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport { GOAL_CONTINUATION_MESSAGE_TYPE } from \"../../../messages.ts\";\nimport type { SessionEntry } from \"../../../session-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { getLatestPhasesFromBranchEntries } from \"../todotools/state.ts\";\nimport {\n\tbuildGoalContinuationSignature,\n\tevaluateGoalContinuation,\n\ttype GoalContinuationInput,\n\ttype GoalContinuationVerdict,\n\thashAssistantText,\n} from \"./continuation.ts\";\nimport {\n\tCONTINUATION_CAP_BLOCKED_REASON,\n\tcontinuationCapRecoveryHint,\n\tLENGTH_EXHAUSTED_BLOCKED_REASON,\n\tREPETITION_BLOCKED_REASON,\n} from \"./continuation-recovery.ts\";\nimport { buildContinuationPrompt } from \"./prompt.ts\";\nimport { recordContinuationDelivered, updateGoal } from \"./store.ts\";\nimport { goalStoreRef } from \"./store-ref.ts\";\nimport { openTodoTaskContents } from \"./todo-gate.ts\";\nimport type { Goal } from \"./types.ts\";\n\ntype ContinuingGoalContinuationVerdict = Extract<GoalContinuationVerdict, { kind: \"continue\" }>;\n\ntype GoalContinuationDeliveryOptions = {\n\treadonly input: Omit<GoalContinuationInput, \"goal\">;\n\treadonly content: (verdict: ContinuingGoalContinuationVerdict) => string;\n\treadonly markContinuationPending: () => void;\n};\n\nexport type SessionStartContinuationOptions = {\n\treadonly continuationPending: boolean;\n\treadonly markContinuationPending: () => void;\n};\n\n/**\n * Statuses that leave a goal stopped without finishing it. A restart is the only\n * moment the user can act on them, so both earn the resume prompt.\n */\nconst STOPPED_UNFINISHED_GOAL_STATUSES: readonly Goal[\"status\"][] = [\"paused\", \"blocked\"];\n\n/**\n * Mirrors codex `maybe_prompt_resume_paused_goal_after_resume`\n * (codex-rs/tui/src/app/thread_goal_actions.rs), which prompts on resume for every\n * stopped-but-unfinished status. senpi is budget-free, so codex's `UsageLimited`\n * has no counterpart here and the stopped set is `paused | blocked`.\n */\nexport function isResumeOfStoppedGoal(\n\tctx: ExtensionContext,\n\tsessionStartReason: string,\n\tgoal: Goal | null,\n): goal is Goal {\n\treturn (\n\t\tsessionStartReason === \"resume\" &&\n\t\tgoal !== null &&\n\t\tSTOPPED_UNFINISHED_GOAL_STATUSES.includes(goal.status) &&\n\t\tctx.hasUI &&\n\t\tctx.isIdle() &&\n\t\t!ctx.hasPendingMessages()\n\t);\n}\n\n/** Evaluates and delivers a continuation only after all guardrail checks admit it. */\nexport async function admitAndQueueGoalContinuation(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tgoal: Goal,\n\toptions: GoalContinuationDeliveryOptions,\n): Promise<Goal | null> {\n\tconst verdict = evaluateGoalContinuation({ goal, ...options.input });\n\tif (verdict.kind === \"deny\") return handleDeniedContinuation(pi, ctx, goal, options.input, verdict.reason);\n\n\tif (options.input.currentSignature === undefined) {\n\t\tthrow new Error(\"Cannot queue a goal continuation without a progress signature\");\n\t}\n\tconst recordedGoal = await recordContinuationDelivered(\n\t\tgoalStoreRef(ctx.sessionManager, ctx.cwd),\n\t\toptions.input.currentSignature,\n\t\tgoal.id,\n\t);\n\tif (recordedGoal === null) return null;\n\toptions.markContinuationPending();\n\tqueueHiddenGoalPrompt(pi, options.content(verdict));\n\treturn recordedGoal;\n}\n\n/** Routes startup and resume continuations through the same verdict and delivery accounting as agent-end paths. */\nexport async function queueGoalContinuation(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tgoal: Goal,\n\toptions: SessionStartContinuationOptions,\n): Promise<Goal | null> {\n\tconst signature = buildCurrentGoalContinuationSignature(\n\t\tctx,\n\t\tgoal,\n\t\tlastAssistantTextFromEntries(ctx.sessionManager.getBranch()),\n\t);\n\treturn admitAndQueueGoalContinuation(pi, ctx, goal, {\n\t\tinput: {\n\t\t\tisIdle: ctx.isIdle(),\n\t\t\thasPendingMessages: ctx.hasPendingMessages(),\n\t\t\tpath: \"sessionStart\",\n\t\t\tlastStopReason: undefined,\n\t\t\tconsecutiveContinuations: goal.consecutiveContinuations ?? 0,\n\t\t\tlastContinuationSignature: goal.lastContinuationSignature,\n\t\t\tcurrentSignature: signature,\n\t\t\tconsecutiveLengthRecoveries: 0,\n\t\t\trecentNormalizedOutputHashes: [],\n\t\t\ttoollessContinuationStreak: 0,\n\t\t\tcontinuationPending: options.continuationPending,\n\t\t},\n\t\tcontent: () => buildContinuationPrompt(goal),\n\t\tmarkContinuationPending: options.markContinuationPending,\n\t});\n}\n\nexport function buildCurrentGoalContinuationSignature(\n\tctx: ExtensionContext,\n\tgoal: Goal,\n\tlastAssistantText: string,\n): string {\n\tconst entries = ctx.sessionManager.getBranch();\n\tconst openTodos = openTodoTaskContents(entries).length;\n\tconst totalTodos = getLatestPhasesFromBranchEntries(entries).reduce((count, phase) => count + phase.tasks.length, 0);\n\treturn buildGoalContinuationSignature(goal, openTodos, totalTodos, hashAssistantText(lastAssistantText));\n}\n\nexport function lastAssistantText(messages: readonly AgentMessage[]): string {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"assistant\") return textContent(message);\n\t}\n\treturn \"\";\n}\n\nfunction lastAssistantTextFromEntries(entries: readonly SessionEntry[]): string {\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type === \"message\" && entry.message.role === \"assistant\") return textContent(entry.message);\n\t}\n\treturn \"\";\n}\n\nfunction textContent(message: Extract<AgentMessage, { role: \"assistant\" }>): string {\n\treturn message.content\n\t\t.filter((content) => content.type === \"text\")\n\t\t.map((content) => content.text)\n\t\t.join(\"\\n\");\n}\n\nasync function handleDeniedContinuation(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tgoal: Goal,\n\tinput: Omit<GoalContinuationInput, \"goal\">,\n\treason: Extract<GoalContinuationVerdict, { kind: \"deny\" }>[\"reason\"],\n): Promise<Goal> {\n\tconst blockedReason = blockedReasonForContinuationGuard(reason);\n\tif (blockedReason === undefined) return goal;\n\n\tconst blocked = await updateGoal(\n\t\tgoalStoreRef(ctx.sessionManager, ctx.cwd),\n\t\t{ status: \"blocked\", reason: blockedReason },\n\t\t\"model\",\n\t);\n\tif (ctx.hasUI) ctx.ui.notify(continuationCapRecoveryHint(blockedReason), \"warning\");\n\tpi.events?.emit(\"goal_continuation_guard_tripped\", {\n\t\tgoalId: goal.id,\n\t\treason,\n\t\tcount: input.consecutiveContinuations,\n\t});\n\treturn blocked;\n}\n\nfunction blockedReasonForContinuationGuard(\n\treason: Extract<GoalContinuationVerdict, { kind: \"deny\" }>[\"reason\"],\n): string | undefined {\n\tswitch (reason) {\n\t\tcase \"cap\":\n\t\t\treturn CONTINUATION_CAP_BLOCKED_REASON;\n\t\tcase \"repetition\":\n\t\t\treturn REPETITION_BLOCKED_REASON;\n\t\tcase \"length-exhausted\":\n\t\t\treturn LENGTH_EXHAUSTED_BLOCKED_REASON;\n\t\tcase \"not-eligible\":\n\t\tcase \"single-flight\":\n\t\tcase \"stale\":\n\t\t\treturn undefined;\n\t}\n}\n\nexport function queueHiddenGoalPrompt(pi: ExtensionAPI, content: string): void {\n\tpi.sendMessage(\n\t\t{ customType: GOAL_CONTINUATION_MESSAGE_TYPE, content, display: false },\n\t\t{ triggerTurn: true, deliverAs: \"followUp\" },\n\t);\n}\n"]}
1
+ {"version":3,"file":"lifecycle-helpers.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/lifecycle-helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport { GOAL_CONTINUATION_MESSAGE_TYPE } from \"../../../messages.ts\";\nimport type { SessionEntry } from \"../../../session-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { getLatestPhasesFromBranchEntries } from \"../todotools/state.ts\";\nimport {\n\tbuildGoalContinuationSignature,\n\tevaluateGoalContinuation,\n\ttype GoalContinuationInput,\n\ttype GoalContinuationVerdict,\n\thashAssistantText,\n} from \"./continuation.ts\";\nimport {\n\tCONTINUATION_CAP_BLOCKED_REASON,\n\tcontinuationCapRecoveryHint,\n\tLENGTH_EXHAUSTED_BLOCKED_REASON,\n\tREPETITION_BLOCKED_REASON,\n\tUNATTENDED_CONTINUATION_BLOCKED_REASON,\n} from \"./continuation-recovery.ts\";\nimport { buildContinuationPrompt } from \"./prompt.ts\";\nimport { recordContinuationDelivered, updateGoal } from \"./store.ts\";\nimport { goalStoreRef } from \"./store-ref.ts\";\nimport { openTodoTaskContents } from \"./todo-gate.ts\";\nimport type { Goal } from \"./types.ts\";\n\ntype ContinuingGoalContinuationVerdict = Extract<GoalContinuationVerdict, { kind: \"continue\" }>;\n\ntype GoalContinuationDeliveryOptions = {\n\treadonly input: Omit<GoalContinuationInput, \"goal\">;\n\treadonly content: (verdict: ContinuingGoalContinuationVerdict) => string;\n\treadonly markContinuationPending: () => void;\n};\n\nexport type SessionStartContinuationOptions = {\n\treadonly continuationPending: boolean;\n\treadonly markContinuationPending: () => void;\n};\n\n/**\n * Statuses that leave a goal stopped without finishing it. A restart is the only\n * moment the user can act on them, so both earn the resume prompt.\n */\nconst STOPPED_UNFINISHED_GOAL_STATUSES: readonly Goal[\"status\"][] = [\"paused\", \"blocked\"];\n\n/**\n * Mirrors codex `maybe_prompt_resume_paused_goal_after_resume`\n * (codex-rs/tui/src/app/thread_goal_actions.rs), which prompts on resume for every\n * stopped-but-unfinished status. senpi is budget-free, so codex's `UsageLimited`\n * has no counterpart here and the stopped set is `paused | blocked`.\n */\nexport function isResumeOfStoppedGoal(\n\tctx: ExtensionContext,\n\tsessionStartReason: string,\n\tgoal: Goal | null,\n): goal is Goal {\n\treturn (\n\t\tsessionStartReason === \"resume\" &&\n\t\tgoal !== null &&\n\t\tSTOPPED_UNFINISHED_GOAL_STATUSES.includes(goal.status) &&\n\t\tctx.hasUI &&\n\t\tctx.isIdle() &&\n\t\t!ctx.hasPendingMessages()\n\t);\n}\n\n/** Evaluates and delivers a continuation only after all guardrail checks admit it. */\nexport async function admitAndQueueGoalContinuation(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tgoal: Goal,\n\toptions: GoalContinuationDeliveryOptions,\n): Promise<Goal | null> {\n\tconst verdict = evaluateGoalContinuation({ goal, ...options.input });\n\tif (verdict.kind === \"deny\") return handleDeniedContinuation(pi, ctx, goal, options.input, verdict.reason);\n\n\tif (options.input.currentSignature === undefined) {\n\t\tthrow new Error(\"Cannot queue a goal continuation without a progress signature\");\n\t}\n\tconst recordedGoal = await recordContinuationDelivered(\n\t\tgoalStoreRef(ctx.sessionManager, ctx.cwd),\n\t\toptions.input.currentSignature,\n\t\tgoal.id,\n\t\t{ countUnattended: options.input.path !== \"monitorDelayed\" },\n\t);\n\tif (recordedGoal === null) return null;\n\toptions.markContinuationPending();\n\tqueueHiddenGoalPrompt(pi, options.content(verdict));\n\treturn recordedGoal;\n}\n\n/** Routes startup and resume continuations through the same verdict and delivery accounting as agent-end paths. */\nexport async function queueGoalContinuation(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tgoal: Goal,\n\toptions: SessionStartContinuationOptions,\n): Promise<Goal | null> {\n\tconst signature = buildCurrentGoalContinuationSignature(\n\t\tctx,\n\t\tgoal,\n\t\tlastAssistantTextFromEntries(ctx.sessionManager.getBranch()),\n\t);\n\treturn admitAndQueueGoalContinuation(pi, ctx, goal, {\n\t\tinput: {\n\t\t\tisIdle: ctx.isIdle(),\n\t\t\thasPendingMessages: ctx.hasPendingMessages(),\n\t\t\tpath: \"sessionStart\",\n\t\t\tlastStopReason: undefined,\n\t\t\tconsecutiveContinuations: goal.consecutiveContinuations ?? 0,\n\t\t\tlastContinuationSignature: goal.lastContinuationSignature,\n\t\t\tcurrentSignature: signature,\n\t\t\tconsecutiveLengthRecoveries: 0,\n\t\t\trecentNormalizedOutputHashes: [],\n\t\t\ttoollessContinuationStreak: 0,\n\t\t\tcontinuationPending: options.continuationPending,\n\t\t},\n\t\tcontent: () => buildContinuationPrompt(goal),\n\t\tmarkContinuationPending: options.markContinuationPending,\n\t});\n}\n\nexport function buildCurrentGoalContinuationSignature(\n\tctx: ExtensionContext,\n\tgoal: Goal,\n\tlastAssistantText: string,\n): string {\n\tconst entries = ctx.sessionManager.getBranch();\n\tconst openTodos = openTodoTaskContents(entries).length;\n\tconst totalTodos = getLatestPhasesFromBranchEntries(entries).reduce((count, phase) => count + phase.tasks.length, 0);\n\treturn buildGoalContinuationSignature(goal, openTodos, totalTodos, hashAssistantText(lastAssistantText));\n}\n\nexport function lastAssistantText(messages: readonly AgentMessage[]): string {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"assistant\") return textContent(message);\n\t}\n\treturn \"\";\n}\n\nfunction lastAssistantTextFromEntries(entries: readonly SessionEntry[]): string {\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type === \"message\" && entry.message.role === \"assistant\") return textContent(entry.message);\n\t}\n\treturn \"\";\n}\n\nfunction textContent(message: Extract<AgentMessage, { role: \"assistant\" }>): string {\n\treturn message.content\n\t\t.filter((content) => content.type === \"text\")\n\t\t.map((content) => content.text)\n\t\t.join(\"\\n\");\n}\n\nasync function handleDeniedContinuation(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tgoal: Goal,\n\tinput: Omit<GoalContinuationInput, \"goal\">,\n\treason: Extract<GoalContinuationVerdict, { kind: \"deny\" }>[\"reason\"],\n): Promise<Goal> {\n\tconst blockedReason = blockedReasonForContinuationGuard(reason);\n\tif (blockedReason === undefined) return goal;\n\n\tconst blocked = await updateGoal(\n\t\tgoalStoreRef(ctx.sessionManager, ctx.cwd),\n\t\t{ status: \"blocked\", reason: blockedReason },\n\t\t\"model\",\n\t);\n\tif (ctx.hasUI) ctx.ui.notify(continuationCapRecoveryHint(blockedReason), \"warning\");\n\tpi.events?.emit(\"goal_continuation_guard_tripped\", {\n\t\tgoalId: goal.id,\n\t\treason,\n\t\tcount: input.consecutiveContinuations,\n\t\tunattendedContinuations: goal.unattendedContinuations ?? 0,\n\t});\n\treturn blocked;\n}\n\nfunction blockedReasonForContinuationGuard(\n\treason: Extract<GoalContinuationVerdict, { kind: \"deny\" }>[\"reason\"],\n): string | undefined {\n\tswitch (reason) {\n\t\tcase \"cap\":\n\t\t\treturn CONTINUATION_CAP_BLOCKED_REASON;\n\t\tcase \"unattended\":\n\t\t\treturn UNATTENDED_CONTINUATION_BLOCKED_REASON;\n\t\tcase \"repetition\":\n\t\t\treturn REPETITION_BLOCKED_REASON;\n\t\tcase \"length-exhausted\":\n\t\t\treturn LENGTH_EXHAUSTED_BLOCKED_REASON;\n\t\tcase \"not-eligible\":\n\t\tcase \"single-flight\":\n\t\tcase \"stale\":\n\t\t\treturn undefined;\n\t}\n}\n\nexport function queueHiddenGoalPrompt(pi: ExtensionAPI, content: string): void {\n\tpi.sendMessage(\n\t\t{ customType: GOAL_CONTINUATION_MESSAGE_TYPE, content, display: false },\n\t\t{ triggerTurn: true, deliverAs: \"followUp\" },\n\t);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-continuation.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/monitor-continuation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAarE,OAAO,EAAE,2CAA2C,EAAE,MAAM,iBAAiB,CAAC;AAkB9E,OAAO,KAAK,EACX,eAAe,EAIf,uBAAuB,EAEvB,kBAAkB,EAClB,MAAM,iCAAiC,CAAC;AAKzC,OAAO,KAAK,EAAE,IAAI,EAAsB,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,eAAO,MAAM,iCAAiC,gCAAgC,CAAC;AAC/E,eAAO,MAAM,+BAA+B,8BAA8B,CAAC;AAC3E,eAAO,MAAM,mCAAmC,kCAAkC,CAAC;AACnF,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAE1E,qBAAa,4BAA4B;;gBAiCvC,EAAE,EAAE,YAAY,EAChB,qBAAqB,GAAE,MAAM,OAAqB,EAClD,uBAAuB,GAAE,MAAM,IAAe,EAC9C,UAAU,CAAC,EAAE,cAAc;IAS5B,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;IAW5B,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAyD7D,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAoBnE,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAgB5E,iBAAiB,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IA2B3D,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI;IASjC,sGAAsG;IACtG,oBAAoB,IAAI,OAAO;IAI/B;;;;;OAKG;IACH,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAMtC,mGAAmG;IACnG,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAwBtC,6FAA6F;IAC7F,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAc5D,sEAAsE;IACtE,cAAc,IAAI,IAAI;IAOtB,mGAAmG;IACnG,uBAAuB,IAAI,IAAI;IAI/B,OAAO,IAAI,IAAI;CA8Uf"}
1
+ {"version":3,"file":"monitor-continuation.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/monitor-continuation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAarE,OAAO,EAAE,2CAA2C,EAAE,MAAM,iBAAiB,CAAC;AAkB9E,OAAO,KAAK,EACX,eAAe,EAIf,uBAAuB,EAEvB,kBAAkB,EAClB,MAAM,iCAAiC,CAAC;AAMzC,OAAO,KAAK,EAAE,IAAI,EAAsB,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,eAAO,MAAM,iCAAiC,gCAAgC,CAAC;AAC/E,eAAO,MAAM,+BAA+B,8BAA8B,CAAC;AAC3E,eAAO,MAAM,mCAAmC,kCAAkC,CAAC;AACnF,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAE1E,qBAAa,4BAA4B;;gBAiCvC,EAAE,EAAE,YAAY,EAChB,qBAAqB,GAAE,MAAM,OAAqB,EAClD,uBAAuB,GAAE,MAAM,IAAe,EAC9C,UAAU,CAAC,EAAE,cAAc;IAS5B,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;IAW5B,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IA0D7D,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAoBnE,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAgB5E,iBAAiB,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IA2B3D,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI;IASjC,sGAAsG;IACtG,oBAAoB,IAAI,OAAO;IAI/B;;;;;OAKG;IACH,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAMtC,mGAAmG;IACnG,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAwBtC,6FAA6F;IAC7F,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAc5D,sEAAsE;IACtE,cAAc,IAAI,IAAI;IAOtB,mGAAmG;IACnG,uBAAuB,IAAI,IAAI;IAI/B,OAAO,IAAI,IAAI;CAkWf"}
@@ -5,6 +5,7 @@ import { continuationTurnUsedTools, evaluateGoalContinuation, GOAL_USER_GRACE_DE
5
5
  import { lastAssistantMessage } from "./last-assistant-message.js";
6
6
  import { admitAndQueueGoalContinuation, buildCurrentGoalContinuationSignature, lastAssistantText, } from "./lifecycle-helpers.js";
7
7
  import { buildContinuationPrompt, buildGoalStallNotice, buildTruncationRecoveryPrompt } from "./prompt.js";
8
+ import { isStaleExtensionContextError } from "./stale-context.js";
8
9
  import { resetContinuationStreak } from "./store.js";
9
10
  import { goalStoreRef } from "./store-ref.js";
10
11
  import { collectAssistantUsage } from "./turn-usage.js";
@@ -100,7 +101,8 @@ export class MonitorAwareGoalContinuation {
100
101
  return goal;
101
102
  case "cap":
102
103
  case "repetition":
103
- case "length-exhausted": {
104
+ case "length-exhausted":
105
+ case "unattended": {
104
106
  const admission = await this.#admitAndQueue(options.ctx, goal, "immediate", options.messages);
105
107
  return admission.goal;
106
108
  }
@@ -300,10 +302,28 @@ export class MonitorAwareGoalContinuation {
300
302
  }
301
303
  this.#armTimer(kind, delayMs, delayMs);
302
304
  }
305
+ /**
306
+ * `hasUI` is an `assertActive()`-guarded getter, so a ctx retired by session
307
+ * replacement or reload THROWS instead of reporting false. Optional chaining
308
+ * only guards an undefined ctx (what `dispose()` leaves behind), never a stale
309
+ * object left by a replacement that never disposed this monitor. Callers reach
310
+ * this from timer and event callbacks where a throw is fatal, so a retired ctx
311
+ * reports "no UI" and any other failure keeps its current behavior.
312
+ */
313
+ #ctxHasUI(ctx = this.#ctx) {
314
+ try {
315
+ return ctx?.hasUI === true;
316
+ }
317
+ catch (error) {
318
+ if (isStaleExtensionContextError(error))
319
+ return false;
320
+ throw error;
321
+ }
322
+ }
303
323
  #armTimer(kind, delayMs, totalMs, drainFire = false) {
304
324
  this.#scheduledDueAtMs = Date.now() + delayMs;
305
325
  const ctx = this.#ctx;
306
- if (ctx?.hasUI) {
326
+ if (ctx !== undefined && this.#ctxHasUI(ctx)) {
307
327
  this.#waitTicker?.sync(ctx, {
308
328
  kind,
309
329
  remainingMs: delayMs,
@@ -313,10 +333,14 @@ export class MonitorAwareGoalContinuation {
313
333
  }
314
334
  this.#timer = setTimeout(() => {
315
335
  void this.#continueIfEligible(kind, drainFire).catch((error) => {
316
- if (this.#ctx?.hasUI) {
317
- const message = error instanceof Error ? error.message : String(error);
318
- this.#ctx.ui.notify(`Goal continuation delivery failed: ${message}`, "error");
319
- }
336
+ // Runs from a bare setTimeout: anything thrown here escapes as an
337
+ // uncaughtException and kills the session. A retired ctx cannot be
338
+ // notified, and its own staleness is the expected cause of this
339
+ // rejection after a session replacement, so drop it quietly.
340
+ if (isStaleExtensionContextError(error) || !this.#ctxHasUI())
341
+ return;
342
+ const message = error instanceof Error ? error.message : String(error);
343
+ this.#ctx?.ui.notify(`Goal continuation delivery failed: ${message}`, "error");
320
344
  });
321
345
  }, delayMs);
322
346
  }
@@ -420,7 +444,7 @@ export class MonitorAwareGoalContinuation {
420
444
  consecutiveContinuations: this.#toollessContinuationStreak,
421
445
  toolless: true,
422
446
  });
423
- if (ctx.hasUI) {
447
+ if (this.#ctxHasUI(ctx)) {
424
448
  const context = liveSources.length > 0 ? `while ${liveSources.join(", ")} channels stayed active` : "without tool use";
425
449
  ctx.ui.notify(`Goal continuation repeated ${this.#toollessContinuationStreak} toolless turns ${context} - injected a stall check.`, "info");
426
450
  }