@code-yeongyu/senpi 2026.8.3 → 2026.8.4

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 (302) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +9 -0
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +1 -0
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/client/remote-session.d.ts +2 -2
  7. package/dist/client/transcript.d.ts +1 -1
  8. package/dist/core/agent-session.d.ts +6 -0
  9. package/dist/core/agent-session.d.ts.map +1 -1
  10. package/dist/core/agent-session.js +174 -39
  11. package/dist/core/agent-session.js.map +1 -1
  12. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +2 -1
  13. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
  14. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +126 -26
  15. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
  16. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  17. package/dist/core/extensions/builtin/compaction/index.js +12 -7
  18. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  19. package/dist/core/extensions/builtin/compaction/per-turn-cap.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/compaction/per-turn-cap.js +4 -1
  21. package/dist/core/extensions/builtin/compaction/per-turn-cap.js.map +1 -1
  22. package/dist/core/extensions/builtin/compaction/retained-message-safety.d.ts +4 -0
  23. package/dist/core/extensions/builtin/compaction/retained-message-safety.d.ts.map +1 -0
  24. package/dist/core/extensions/builtin/compaction/retained-message-safety.js +155 -0
  25. package/dist/core/extensions/builtin/compaction/retained-message-safety.js.map +1 -0
  26. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/compaction/speculative.js +21 -13
  28. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  29. package/dist/core/extensions/builtin/goal/cache-warm-renderer.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +9 -14
  31. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
  32. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +1 -0
  33. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/goal/continuation-recovery.js +7 -0
  35. package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -1
  36. package/dist/core/extensions/builtin/goal/continuation.d.ts +2 -1
  37. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  38. package/dist/core/extensions/builtin/goal/continuation.js +2 -1
  39. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  40. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  41. package/dist/core/extensions/builtin/goal/index.js +26 -11
  42. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  43. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +7 -1
  44. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  45. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +14 -2
  46. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  47. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +3 -2
  48. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  49. package/dist/core/extensions/builtin/goal/monitor-continuation.js +89 -46
  50. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  51. package/dist/core/extensions/builtin/goal/wait-progress.d.ts +11 -0
  52. package/dist/core/extensions/builtin/goal/wait-progress.d.ts.map +1 -0
  53. package/dist/core/extensions/builtin/goal/wait-progress.js +30 -0
  54. package/dist/core/extensions/builtin/goal/wait-progress.js.map +1 -0
  55. package/dist/core/extensions/builtin/goal/wait-ticker.d.ts +38 -0
  56. package/dist/core/extensions/builtin/goal/wait-ticker.d.ts.map +1 -0
  57. package/dist/core/extensions/builtin/goal/wait-ticker.js +71 -0
  58. package/dist/core/extensions/builtin/goal/wait-ticker.js.map +1 -0
  59. package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts.map +1 -1
  60. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +14 -1
  61. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
  62. package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts +1 -0
  63. package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts.map +1 -1
  64. package/dist/core/extensions/builtin/gpt-apply-patch/types.js.map +1 -1
  65. package/dist/core/extensions/builtin/loop-guard/renderer.d.ts.map +1 -1
  66. package/dist/core/extensions/builtin/loop-guard/renderer.js +4 -12
  67. package/dist/core/extensions/builtin/loop-guard/renderer.js.map +1 -1
  68. package/dist/core/extensions/builtin/rule-activation/index.d.ts +6 -0
  69. package/dist/core/extensions/builtin/rule-activation/index.d.ts.map +1 -0
  70. package/dist/core/extensions/builtin/rule-activation/index.js +10 -0
  71. package/dist/core/extensions/builtin/rule-activation/index.js.map +1 -0
  72. package/dist/core/extensions/builtin/rule-activation/renderer.d.ts +3 -0
  73. package/dist/core/extensions/builtin/rule-activation/renderer.d.ts.map +1 -0
  74. package/dist/core/extensions/builtin/rule-activation/renderer.js +37 -0
  75. package/dist/core/extensions/builtin/rule-activation/renderer.js.map +1 -0
  76. package/dist/core/extensions/builtin/rule-activation/types.d.ts +15 -0
  77. package/dist/core/extensions/builtin/rule-activation/types.d.ts.map +1 -0
  78. package/dist/core/extensions/builtin/rule-activation/types.js +45 -0
  79. package/dist/core/extensions/builtin/rule-activation/types.js.map +1 -0
  80. package/dist/core/extensions/builtin/rules/config.d.ts +3 -0
  81. package/dist/core/extensions/builtin/rules/config.d.ts.map +1 -0
  82. package/dist/core/extensions/builtin/rules/config.js +24 -0
  83. package/dist/core/extensions/builtin/rules/config.js.map +1 -0
  84. package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
  85. package/dist/core/extensions/builtin/rules/index.js +14 -4
  86. package/dist/core/extensions/builtin/rules/index.js.map +1 -1
  87. package/dist/core/extensions/builtin/rules/rules/formatter.d.ts.map +1 -1
  88. package/dist/core/extensions/builtin/rules/rules/formatter.js +21 -5
  89. package/dist/core/extensions/builtin/rules/rules/formatter.js.map +1 -1
  90. package/dist/core/extensions/builtin/rules/rules/types.d.ts +1 -1
  91. package/dist/core/extensions/builtin/rules/rules/types.js.map +1 -1
  92. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  93. package/dist/core/extensions/builtin/service-tier.js +2 -3
  94. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  95. package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.d.ts +22 -0
  96. package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.d.ts.map +1 -0
  97. package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js +93 -0
  98. package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js.map +1 -0
  99. package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/ttsr/index.js +60 -21
  101. package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
  102. package/dist/core/extensions/builtin/ttsr/prompts.d.ts +1 -0
  103. package/dist/core/extensions/builtin/ttsr/prompts.d.ts.map +1 -1
  104. package/dist/core/extensions/builtin/ttsr/prompts.js +5 -0
  105. package/dist/core/extensions/builtin/ttsr/prompts.js.map +1 -1
  106. package/dist/core/extensions/builtin/ttsr/repetitive-turns-lane.d.ts +23 -0
  107. package/dist/core/extensions/builtin/ttsr/repetitive-turns-lane.d.ts.map +1 -0
  108. package/dist/core/extensions/builtin/ttsr/repetitive-turns-lane.js +101 -0
  109. package/dist/core/extensions/builtin/ttsr/repetitive-turns-lane.js.map +1 -0
  110. package/dist/core/extensions/builtin/ttsr/stream-remediation.d.ts +15 -0
  111. package/dist/core/extensions/builtin/ttsr/stream-remediation.d.ts.map +1 -0
  112. package/dist/core/extensions/builtin/ttsr/stream-remediation.js +22 -0
  113. package/dist/core/extensions/builtin/ttsr/stream-remediation.js.map +1 -0
  114. package/dist/core/extensions/builtin/ttsr/types.d.ts +1 -1
  115. package/dist/core/extensions/builtin/ttsr/types.d.ts.map +1 -1
  116. package/dist/core/extensions/builtin/ttsr/types.js.map +1 -1
  117. package/dist/core/extensions/notice/adapters.d.ts +15 -0
  118. package/dist/core/extensions/notice/adapters.d.ts.map +1 -0
  119. package/dist/core/extensions/notice/adapters.js +22 -0
  120. package/dist/core/extensions/notice/adapters.js.map +1 -0
  121. package/dist/core/extensions/notice/box.d.ts +8 -0
  122. package/dist/core/extensions/notice/box.d.ts.map +1 -0
  123. package/dist/core/extensions/notice/box.js +17 -0
  124. package/dist/core/extensions/notice/box.js.map +1 -0
  125. package/dist/core/extensions/notice/index.d.ts +4 -0
  126. package/dist/core/extensions/notice/index.d.ts.map +1 -0
  127. package/dist/core/extensions/notice/index.js +3 -0
  128. package/dist/core/extensions/notice/index.js.map +1 -0
  129. package/dist/core/extensions/notice/spec.d.ts +23 -0
  130. package/dist/core/extensions/notice/spec.d.ts.map +1 -0
  131. package/dist/core/extensions/notice/spec.js +2 -0
  132. package/dist/core/extensions/notice/spec.js.map +1 -0
  133. package/dist/core/model-resolver.d.ts.map +1 -1
  134. package/dist/core/model-resolver.js +1 -0
  135. package/dist/core/model-resolver.js.map +1 -1
  136. package/dist/core/model-runtime.d.ts.map +1 -1
  137. package/dist/core/model-runtime.js +2 -2
  138. package/dist/core/model-runtime.js.map +1 -1
  139. package/dist/core/provider-composer.d.ts.map +1 -1
  140. package/dist/core/provider-composer.js +8 -3
  141. package/dist/core/provider-composer.js.map +1 -1
  142. package/dist/core/provider-display-names.d.ts.map +1 -1
  143. package/dist/core/provider-display-names.js +1 -0
  144. package/dist/core/provider-display-names.js.map +1 -1
  145. package/dist/core/retry-fallback/settings.d.ts.map +1 -1
  146. package/dist/core/retry-fallback/settings.js +16 -1
  147. package/dist/core/retry-fallback/settings.js.map +1 -1
  148. package/dist/core/retry-fallback/validate.d.ts.map +1 -1
  149. package/dist/core/retry-fallback/validate.js +15 -2
  150. package/dist/core/retry-fallback/validate.js.map +1 -1
  151. package/dist/core/session-log.js +1 -1
  152. package/dist/core/session-log.js.map +1 -1
  153. package/dist/core/settings-manager.d.ts +7 -0
  154. package/dist/core/settings-manager.d.ts.map +1 -1
  155. package/dist/core/settings-manager.js +13 -0
  156. package/dist/core/settings-manager.js.map +1 -1
  157. package/dist/modes/interactive/components/custom-editor.d.ts +5 -0
  158. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  159. package/dist/modes/interactive/components/custom-editor.js +22 -1
  160. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  161. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  162. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  163. package/dist/modes/interactive/interactive-mode.js +42 -7
  164. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  165. package/dist/modes/interactive/interactive-stderr-guard.d.ts.map +1 -1
  166. package/dist/modes/interactive/interactive-stderr-guard.js +37 -0
  167. package/dist/modes/interactive/interactive-stderr-guard.js.map +1 -1
  168. package/docs/providers.md +19 -0
  169. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +40 -0
  170. package/node_modules/@code-yeongyu/senpi-codemode/README.md +13 -3
  171. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  172. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-status.ts +1 -1
  173. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +6 -6
  174. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-runtime.ts +4 -4
  175. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +2 -2
  176. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-snapshot.ts +2 -2
  177. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-request.ts +20 -2
  178. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +17 -2
  179. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +18 -7
  180. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +19 -5
  181. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  182. package/node_modules/@earendil-works/pi-ai/README.md +3 -1
  183. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +1 -1
  184. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  185. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  186. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +1 -0
  187. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  188. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +1 -1
  189. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  190. package/node_modules/@earendil-works/pi-ai/dist/models.js +1 -1
  191. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  192. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts +2 -1
  193. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
  194. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +3 -1
  195. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
  196. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  197. package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
  198. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  199. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  200. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  201. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  202. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
  204. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  205. package/node_modules/@earendil-works/pi-ai/dist/providers/ollama.d.ts +9 -0
  206. package/node_modules/@earendil-works/pi-ai/dist/providers/ollama.d.ts.map +1 -0
  207. package/node_modules/@earendil-works/pi-ai/dist/providers/ollama.js +142 -0
  208. package/node_modules/@earendil-works/pi-ai/dist/providers/ollama.js.map +1 -0
  209. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +1 -1
  210. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  211. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  212. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  213. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  214. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  215. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +5 -1
  216. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  217. package/node_modules/@earendil-works/pi-tui/dist/slash-command-autocomplete.d.ts.map +1 -1
  218. package/node_modules/@earendil-works/pi-tui/dist/slash-command-autocomplete.js +36 -8
  219. package/node_modules/@earendil-works/pi-tui/dist/slash-command-autocomplete.js.map +1 -1
  220. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +2 -0
  221. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  222. package/node_modules/@earendil-works/pi-tui/dist/tui.js +49 -33
  223. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  224. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  225. package/package.json +8 -13
  226. package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/client.d.ts +1 -1
  227. package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/client.js +1 -1
  228. package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/connection.d.ts +1 -1
  229. package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/connection.js +1 -1
  230. package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/errors.d.ts +1 -1
  231. package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/session-handle.d.ts +1 -1
  232. package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/state.d.ts +1 -1
  233. package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/types.d.ts +1 -1
  234. package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/unix.js +1 -1
  235. package/node_modules/@earendil-works/pi-client/CHANGELOG.md +0 -7
  236. package/node_modules/@earendil-works/pi-client/README.md +0 -64
  237. package/node_modules/@earendil-works/pi-client/package.json +0 -56
  238. package/node_modules/@earendil-works/pi-protocol/README.md +0 -68
  239. package/node_modules/@earendil-works/pi-protocol/package.json +0 -48
  240. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/client.d.ts.map +0 -0
  241. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/client.js.map +0 -0
  242. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/connection.d.ts.map +0 -0
  243. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/connection.js.map +0 -0
  244. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/errors.d.ts.map +0 -0
  245. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/errors.js +0 -0
  246. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/errors.js.map +0 -0
  247. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/index.d.ts +0 -0
  248. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/index.d.ts.map +0 -0
  249. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/index.js +0 -0
  250. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/index.js.map +0 -0
  251. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/promise.d.ts +0 -0
  252. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/promise.d.ts.map +0 -0
  253. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/promise.js +0 -0
  254. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/promise.js.map +0 -0
  255. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/session-handle.d.ts.map +0 -0
  256. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/session-handle.js +0 -0
  257. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/session-handle.js.map +0 -0
  258. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/state.d.ts.map +0 -0
  259. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/state.js +0 -0
  260. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/state.js.map +0 -0
  261. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/transport.d.ts +0 -0
  262. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/transport.d.ts.map +0 -0
  263. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/transport.js +0 -0
  264. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/transport.js.map +0 -0
  265. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/types.d.ts.map +0 -0
  266. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/types.js +0 -0
  267. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/types.js.map +0 -0
  268. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/unix.d.ts +0 -0
  269. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/unix.d.ts.map +0 -0
  270. /package/{node_modules/@earendil-works/pi-client/dist → vendor/pi-client}/unix.js.map +0 -0
  271. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/decoder.d.ts +0 -0
  272. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/decoder.d.ts.map +0 -0
  273. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/decoder.js +0 -0
  274. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/decoder.js.map +0 -0
  275. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/encoder.d.ts +0 -0
  276. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/encoder.d.ts.map +0 -0
  277. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/encoder.js +0 -0
  278. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/encoder.js.map +0 -0
  279. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/index.d.ts +0 -0
  280. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/index.d.ts.map +0 -0
  281. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/index.js +0 -0
  282. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/index.js.map +0 -0
  283. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/options.d.ts +0 -0
  284. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/options.d.ts.map +0 -0
  285. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/options.js +0 -0
  286. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/cbor/options.js.map +0 -0
  287. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/codec.d.ts +0 -0
  288. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/codec.d.ts.map +0 -0
  289. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/codec.js +0 -0
  290. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/codec.js.map +0 -0
  291. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/framing.d.ts +0 -0
  292. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/framing.d.ts.map +0 -0
  293. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/framing.js +0 -0
  294. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/framing.js.map +0 -0
  295. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/index.d.ts +0 -0
  296. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/index.d.ts.map +0 -0
  297. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/index.js +0 -0
  298. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/index.js.map +0 -0
  299. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/schemas.d.ts +0 -0
  300. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/schemas.d.ts.map +0 -0
  301. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/schemas.js +0 -0
  302. /package/{node_modules/@earendil-works/pi-protocol/dist → vendor/pi-protocol}/schemas.js.map +0 -0
@@ -1,6 +1,6 @@
1
1
  import { isTerminalMonitorStateEvent, TERMINAL_MONITOR_STATE_EVENT } from "../monitor-state-event.js";
2
2
  import { buildCacheWarmResumedNotice, buildCacheWarmScheduledNotice, estimateCacheWarmMetrics, GOAL_CACHE_WARMUP_ENTRY_TYPE, } from "./cache-warm.js";
3
- import { continuationTurnUsedTools, evaluateGoalContinuation, GOAL_STALL_TOOLLESS_THRESHOLD, hasGoalContinuationProgress, hashAssistantText, normalizeAssistantText, } from "./continuation.js";
3
+ import { continuationTurnUsedTools, evaluateGoalContinuation, GOAL_STALL_TOOLLESS_THRESHOLD, GOAL_USER_GRACE_DELAY_MS, hasGoalContinuationProgress, hashAssistantText, normalizeAssistantText, } from "./continuation.js";
4
4
  import { admitAndQueueGoalContinuation, buildCurrentGoalContinuationSignature, lastAssistantText, } from "./lifecycle-helpers.js";
5
5
  import { buildContinuationPrompt, buildGoalStallNotice, buildTruncationRecoveryPrompt } from "./prompt.js";
6
6
  import { resetContinuationStreak } from "./store.js";
@@ -16,11 +16,12 @@ export class MonitorAwareGoalContinuation {
16
16
  #pi;
17
17
  #isContinuationPending;
18
18
  #markContinuationPending;
19
+ #waitTicker;
19
20
  #activeMonitorCount = 0;
20
21
  #ctx;
21
22
  #goal = null;
22
23
  #timer;
23
- #continuationScheduled = false;
24
+ #scheduledContinuationKind;
24
25
  #unsubscribeMonitorState;
25
26
  #lastAgentEndMessages = [];
26
27
  #consecutiveLengthRecoveries = new Map();
@@ -34,10 +35,11 @@ export class MonitorAwareGoalContinuation {
34
35
  #scheduledCache;
35
36
  #heldTimer;
36
37
  #directInputHolds = new Set();
37
- constructor(pi, isContinuationPending = () => false, markContinuationPending = () => { }) {
38
+ constructor(pi, isContinuationPending = () => false, markContinuationPending = () => { }, waitTicker) {
38
39
  this.#pi = pi;
39
40
  this.#isContinuationPending = isContinuationPending;
40
41
  this.#markContinuationPending = markContinuationPending;
42
+ this.#waitTicker = waitTicker;
41
43
  }
42
44
  start(ctx) {
43
45
  this.#cancelTimer();
@@ -56,9 +58,13 @@ export class MonitorAwareGoalContinuation {
56
58
  return;
57
59
  this.#activeMonitorCount = data.activeCount;
58
60
  if (data.activeCount === 0) {
59
- if (this.#continuationScheduled)
61
+ if (this.#scheduledContinuationKind === "monitor")
60
62
  this.#cancelTimer();
61
63
  this.#resetToollessContinuationStreak();
64
+ return;
65
+ }
66
+ if (this.#scheduledContinuationKind === "monitor") {
67
+ this.#waitTicker?.setActiveMonitorCount(data.activeCount);
62
68
  }
63
69
  });
64
70
  }
@@ -83,15 +89,30 @@ export class MonitorAwareGoalContinuation {
83
89
  options.goal)
84
90
  : options.goal;
85
91
  this.#goal = goal;
86
- if (this.#endedTurnWasUserInitiated) {
87
- this.#endedTurnWasUserInitiated = false;
88
- this.#cancelTimer();
89
- return goal;
90
- }
91
92
  const immediateVerdict = evaluateGoalContinuation({
92
93
  goal,
93
94
  ...this.#buildVerdictInput(options.ctx, goal, "immediate", options.messages),
94
95
  });
96
+ if (this.#endedTurnWasUserInitiated) {
97
+ this.#endedTurnWasUserInitiated = false;
98
+ this.#cancelTimer();
99
+ if (immediateVerdict.kind === "continue") {
100
+ this.#schedule(goal, "userGrace");
101
+ return goal;
102
+ }
103
+ switch (immediateVerdict.reason) {
104
+ case "not-eligible":
105
+ case "single-flight":
106
+ case "stale":
107
+ return goal;
108
+ case "cap":
109
+ case "repetition":
110
+ case "length-exhausted": {
111
+ const admission = await this.#admitAndQueue(options.ctx, goal, "immediate", options.messages);
112
+ return admission.goal;
113
+ }
114
+ }
115
+ }
95
116
  if (immediateVerdict.kind === "deny" && immediateVerdict.reason === "not-eligible")
96
117
  return goal;
97
118
  if (this.#activeMonitorCount === 0) {
@@ -99,7 +120,7 @@ export class MonitorAwareGoalContinuation {
99
120
  const admission = await this.#admitAndQueue(options.ctx, goal, "immediate", options.messages);
100
121
  return admission.goal;
101
122
  }
102
- this.#schedule(goal);
123
+ this.#schedule(goal, "monitor");
103
124
  return goal;
104
125
  }
105
126
  syncGoal(goal) {
@@ -116,14 +137,19 @@ export class MonitorAwareGoalContinuation {
116
137
  if (this.#directInputHolds.has(inputId))
117
138
  return;
118
139
  this.#directInputHolds.add(inputId);
119
- if (this.#directInputHolds.size !== 1 || this.#timer === undefined || !this.#continuationScheduled)
140
+ if (this.#directInputHolds.size !== 1 ||
141
+ this.#timer === undefined ||
142
+ this.#scheduledContinuationKind === undefined) {
120
143
  return;
144
+ }
121
145
  this.#heldTimer = {
146
+ kind: this.#scheduledContinuationKind,
122
147
  remainingMs: Math.max(0, (this.#scheduledDueAtMs ?? Date.now()) - Date.now()),
123
148
  };
124
149
  clearTimeout(this.#timer);
125
150
  this.#timer = undefined;
126
151
  this.#scheduledDueAtMs = undefined;
152
+ this.#waitTicker?.stop();
127
153
  }
128
154
  /** Resolves one admission hold without allowing overlapping inputs to consume each other. */
129
155
  resolveDirectInput(inputId, accepted) {
@@ -138,9 +164,9 @@ export class MonitorAwareGoalContinuation {
138
164
  return;
139
165
  const held = this.#heldTimer;
140
166
  this.#heldTimer = undefined;
141
- this.#armTimer(held.remainingMs);
167
+ this.#armTimer(held.kind, held.remainingMs);
142
168
  }
143
- /** An accepted real user prompt disarms continuation for that user-initiated turn. */
169
+ /** An accepted real user prompt starts a grace-governed user turn. */
144
170
  noteUserPrompt() {
145
171
  this.#cancelTimer();
146
172
  this.#endedTurnWasUserInitiated = true;
@@ -161,40 +187,55 @@ export class MonitorAwareGoalContinuation {
161
187
  this.#directInputHolds.clear();
162
188
  this.#resetContinuationState();
163
189
  }
164
- #schedule(goal) {
165
- if (this.#continuationScheduled)
190
+ #schedule(goal, kind) {
191
+ if (this.#scheduledContinuationKind !== undefined)
166
192
  return;
167
- const delayMs = GOAL_MONITOR_CONTINUATION_DELAY_MS;
168
- const cache = estimateCacheWarmMetrics(this.#ctx?.model, process.env, this.#lastTurnUsage);
169
- this.#scheduledCache = cache;
170
- this.#scheduledAtMs = Date.now();
171
- if (this.#ctx?.hasUI) {
172
- this.#ctx.ui.notify(buildCacheWarmScheduledNotice(delayMs, this.#activeMonitorCount, cache), "info");
193
+ const delayMs = kind === "monitor" ? GOAL_MONITOR_CONTINUATION_DELAY_MS : GOAL_USER_GRACE_DELAY_MS;
194
+ if (kind === "monitor") {
195
+ const cache = estimateCacheWarmMetrics(this.#ctx?.model, process.env, this.#lastTurnUsage);
196
+ this.#scheduledCache = cache;
197
+ this.#scheduledAtMs = Date.now();
198
+ if (this.#ctx?.hasUI) {
199
+ this.#ctx.ui.notify(buildCacheWarmScheduledNotice(delayMs, this.#activeMonitorCount, cache), "info");
200
+ }
201
+ this.#pi.events?.emit(GOAL_CONTINUATION_SCHEDULED_EVENT, {
202
+ goalId: goal.id,
203
+ delayMs,
204
+ activeMonitorCount: this.#activeMonitorCount,
205
+ cache,
206
+ });
207
+ this.#appendWarmupEntry({
208
+ phase: "scheduled",
209
+ goalId: goal.id,
210
+ delayMs,
211
+ activeMonitorCount: this.#activeMonitorCount,
212
+ ...(cache !== undefined ? { cache } : {}),
213
+ });
173
214
  }
174
- this.#pi.events?.emit(GOAL_CONTINUATION_SCHEDULED_EVENT, {
175
- goalId: goal.id,
176
- delayMs,
177
- activeMonitorCount: this.#activeMonitorCount,
178
- cache,
179
- });
180
- this.#appendWarmupEntry({
181
- phase: "scheduled",
182
- goalId: goal.id,
183
- delayMs,
184
- activeMonitorCount: this.#activeMonitorCount,
185
- ...(cache !== undefined ? { cache } : {}),
186
- });
187
- this.#continuationScheduled = true;
215
+ else {
216
+ this.#scheduledAtMs = undefined;
217
+ this.#scheduledCache = undefined;
218
+ }
219
+ this.#scheduledContinuationKind = kind;
188
220
  if (this.#directInputHolds.size > 0) {
189
- this.#heldTimer = { remainingMs: delayMs };
221
+ this.#heldTimer = { kind, remainingMs: delayMs };
190
222
  return;
191
223
  }
192
- this.#armTimer(delayMs);
224
+ this.#armTimer(kind, delayMs);
193
225
  }
194
- #armTimer(delayMs) {
226
+ #armTimer(kind, delayMs) {
195
227
  this.#scheduledDueAtMs = Date.now() + delayMs;
228
+ const ctx = this.#ctx;
229
+ if (ctx?.hasUI) {
230
+ this.#waitTicker?.sync(ctx, {
231
+ kind,
232
+ remainingMs: delayMs,
233
+ totalMs: kind === "monitor" ? GOAL_MONITOR_CONTINUATION_DELAY_MS : GOAL_USER_GRACE_DELAY_MS,
234
+ activeMonitorCount: this.#activeMonitorCount,
235
+ });
236
+ }
196
237
  this.#timer = setTimeout(() => {
197
- void this.#continueIfEligible().catch((error) => {
238
+ void this.#continueIfEligible(kind).catch((error) => {
198
239
  if (this.#ctx?.hasUI) {
199
240
  const message = error instanceof Error ? error.message : String(error);
200
241
  this.#ctx.ui.notify(`Goal continuation delivery failed: ${message}`, "error");
@@ -202,11 +243,12 @@ export class MonitorAwareGoalContinuation {
202
243
  });
203
244
  }, delayMs);
204
245
  }
205
- async #continueIfEligible() {
246
+ async #continueIfEligible(kind) {
206
247
  this.#timer = undefined;
207
248
  this.#scheduledDueAtMs = undefined;
208
- this.#continuationScheduled = false;
209
- const delayMs = GOAL_MONITOR_CONTINUATION_DELAY_MS;
249
+ this.#scheduledContinuationKind = undefined;
250
+ this.#waitTicker?.stop();
251
+ const delayMs = kind === "monitor" ? GOAL_MONITOR_CONTINUATION_DELAY_MS : GOAL_USER_GRACE_DELAY_MS;
210
252
  const waitedMs = this.#scheduledAtMs === undefined ? delayMs : Math.max(0, Date.now() - this.#scheduledAtMs);
211
253
  const cache = this.#scheduledCache;
212
254
  this.#scheduledAtMs = undefined;
@@ -215,10 +257,10 @@ export class MonitorAwareGoalContinuation {
215
257
  const goal = this.#goal;
216
258
  if (ctx === undefined || goal?.status !== "active" || !ctx.isIdle() || ctx.hasPendingMessages())
217
259
  return;
218
- if (this.#activeMonitorCount === 0)
260
+ if (kind === "monitor" && this.#activeMonitorCount === 0)
219
261
  return;
220
- const admission = await this.#admitAndQueue(ctx, goal, "monitorDelayed", this.#lastAgentEndMessages);
221
- if (!admission.admitted)
262
+ const admission = await this.#admitAndQueue(ctx, goal, kind === "monitor" ? "monitorDelayed" : "userGrace", this.#lastAgentEndMessages);
263
+ if (kind !== "monitor" || !admission.admitted)
222
264
  return;
223
265
  this.#pi.events?.emit(GOAL_CONTINUATION_RESUMED_EVENT, {
224
266
  goalId: goal.id,
@@ -339,7 +381,8 @@ export class MonitorAwareGoalContinuation {
339
381
  if (this.#timer !== undefined)
340
382
  clearTimeout(this.#timer);
341
383
  this.#timer = undefined;
342
- this.#continuationScheduled = false;
384
+ this.#scheduledContinuationKind = undefined;
385
+ this.#waitTicker?.stop();
343
386
  }
344
387
  }
345
388
  function findLastAssistantMessage(messages) {
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-continuation.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/monitor-continuation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { isTerminalMonitorStateEvent, TERMINAL_MONITOR_STATE_EVENT } from \"../monitor-state-event.ts\";\nimport {\n\tbuildCacheWarmResumedNotice,\n\tbuildCacheWarmScheduledNotice,\n\testimateCacheWarmMetrics,\n\tGOAL_CACHE_WARMUP_ENTRY_TYPE,\n\ttype GoalCacheWarmMetrics,\n\ttype GoalCacheWarmupEntryData,\n} from \"./cache-warm.ts\";\nimport {\n\tcontinuationTurnUsedTools,\n\tevaluateGoalContinuation,\n\tGOAL_STALL_TOOLLESS_THRESHOLD,\n\ttype GoalContinuationInput,\n\ttype GoalContinuationPath,\n\ttype GoalContinuationVerdict,\n\thasGoalContinuationProgress,\n\thashAssistantText,\n\tnormalizeAssistantText,\n} from \"./continuation.ts\";\nimport {\n\tadmitAndQueueGoalContinuation,\n\tbuildCurrentGoalContinuationSignature,\n\tlastAssistantText,\n} from \"./lifecycle-helpers.ts\";\nimport { buildContinuationPrompt, buildGoalStallNotice, buildTruncationRecoveryPrompt } from \"./prompt.ts\";\nimport { resetContinuationStreak } from \"./store.ts\";\nimport { goalStoreRef } from \"./store-ref.ts\";\nimport { collectAssistantUsage } from \"./turn-usage.ts\";\nimport type { Goal, TokenUsageSnapshot } from \"./types.ts\";\n\nexport const GOAL_MONITOR_CONTINUATION_DELAY_MS = 240_000;\nexport const GOAL_CONTINUATION_SCHEDULED_EVENT = \"goal_continuation_scheduled\";\nexport const GOAL_CONTINUATION_RESUMED_EVENT = \"goal_continuation_resumed\";\nexport const GOAL_MONITOR_CONTINUATION_NOTICE = \"Goal continuation scheduled in 4 minutes while a monitor is active.\";\nexport const GOAL_MONITOR_STALL_THRESHOLD = GOAL_STALL_TOOLLESS_THRESHOLD;\nexport const GOAL_MONITOR_STALL_EVENT = \"goal_monitor_continuation_stall\";\n\ninterface AgentEndOptions {\n\treadonly ctx: ExtensionContext;\n\treadonly goal: Goal | null;\n\treadonly messages: readonly AgentMessage[];\n}\n\ntype ContinuingGoalContinuationVerdict = Extract<GoalContinuationVerdict, { kind: \"continue\" }>;\n\ntype GoalContinuationAdmission = {\n\treadonly goal: Goal;\n\treadonly admitted: boolean;\n};\n\nexport class MonitorAwareGoalContinuation {\n\treadonly #pi: ExtensionAPI;\n\treadonly #isContinuationPending: () => boolean;\n\treadonly #markContinuationPending: () => void;\n\t#activeMonitorCount = 0;\n\t#ctx: ExtensionContext | undefined;\n\t#goal: Goal | null = null;\n\t#timer: ReturnType<typeof setTimeout> | undefined;\n\t#continuationScheduled = false;\n\t#unsubscribeMonitorState: (() => void) | undefined;\n\t#lastAgentEndMessages: readonly AgentMessage[] = [];\n\t#consecutiveLengthRecoveries = new Map<string, number>();\n\t#recentNormalizedOutputHashes: string[] = [];\n\t#toollessContinuationStreak = 0;\n\t#toollessStreakGoalId: string | null = null;\n\t#endedTurnWasUserInitiated = false;\n\t#lastTurnUsage: TokenUsageSnapshot | undefined;\n\t#scheduledAtMs: number | undefined;\n\t#scheduledDueAtMs: number | undefined;\n\t#scheduledCache: GoalCacheWarmMetrics | undefined;\n\t#heldTimer: { remainingMs: number } | undefined;\n\t#directInputHolds = new Set<string>();\n\n\tconstructor(\n\t\tpi: ExtensionAPI,\n\t\tisContinuationPending: () => boolean = () => false,\n\t\tmarkContinuationPending: () => void = () => {},\n\t) {\n\t\tthis.#pi = pi;\n\t\tthis.#isContinuationPending = isContinuationPending;\n\t\tthis.#markContinuationPending = markContinuationPending;\n\t}\n\n\tstart(ctx: ExtensionContext): void {\n\t\tthis.#cancelTimer();\n\t\tthis.#unsubscribeMonitorState?.();\n\t\tthis.#ctx = ctx;\n\t\tthis.#activeMonitorCount = 0;\n\t\tthis.#goal = null;\n\t\tthis.#lastAgentEndMessages = [];\n\t\tthis.#directInputHolds.clear();\n\t\tthis.#resetContinuationState();\n\t\tconst events = this.#pi.events;\n\t\tif (events === undefined) return;\n\t\tthis.#unsubscribeMonitorState = events.on(TERMINAL_MONITOR_STATE_EVENT, (data) => {\n\t\t\tif (!isTerminalMonitorStateEvent(data)) return;\n\t\t\tthis.#activeMonitorCount = data.activeCount;\n\t\t\tif (data.activeCount === 0) {\n\t\t\t\tif (this.#continuationScheduled) this.#cancelTimer();\n\t\t\t\tthis.#resetToollessContinuationStreak();\n\t\t\t}\n\t\t});\n\t}\n\n\tasync afterAgentEnd(options: AgentEndOptions): Promise<Goal | null> {\n\t\tif (options.goal?.id !== this.#goal?.id) this.#resetToollessContinuationStreak();\n\t\tthis.#ctx = options.ctx;\n\t\tthis.#goal = options.goal;\n\t\tthis.#lastAgentEndMessages = options.messages;\n\t\tthis.#lastTurnUsage = collectAssistantUsage([...options.messages]);\n\t\tthis.#resetLengthRecoveryAfterCleanStop(options.goal, options.messages);\n\t\tconst turnUsedTools = continuationTurnUsedTools(options.messages);\n\t\tthis.#recordAssistantOutput(options.messages, turnUsedTools);\n\t\tif (options.goal?.status !== \"active\") {\n\t\t\tthis.#cancelTimer();\n\t\t\treturn options.goal;\n\t\t}\n\t\tthis.#recordToollessContinuationTurn(options.goal, turnUsedTools);\n\t\tconst immediateInput = this.#buildVerdictInput(options.ctx, options.goal, \"immediate\", options.messages);\n\t\tconst goal =\n\t\t\t!this.#endedTurnWasUserInitiated && (turnUsedTools || hasGoalContinuationProgress(immediateInput))\n\t\t\t\t? ((await resetContinuationStreak(goalStoreRef(options.ctx.sessionManager, options.ctx.cwd))) ??\n\t\t\t\t\toptions.goal)\n\t\t\t\t: options.goal;\n\t\tthis.#goal = goal;\n\t\tif (this.#endedTurnWasUserInitiated) {\n\t\t\tthis.#endedTurnWasUserInitiated = false;\n\t\t\tthis.#cancelTimer();\n\t\t\treturn goal;\n\t\t}\n\n\t\tconst immediateVerdict = evaluateGoalContinuation({\n\t\t\tgoal,\n\t\t\t...this.#buildVerdictInput(options.ctx, goal, \"immediate\", options.messages),\n\t\t});\n\t\tif (immediateVerdict.kind === \"deny\" && immediateVerdict.reason === \"not-eligible\") return goal;\n\n\t\tif (this.#activeMonitorCount === 0) {\n\t\t\tthis.#cancelTimer();\n\t\t\tconst admission = await this.#admitAndQueue(options.ctx, goal, \"immediate\", options.messages);\n\t\t\treturn admission.goal;\n\t\t}\n\t\tthis.#schedule(goal);\n\t\treturn goal;\n\t}\n\n\tsyncGoal(goal: Goal | null): void {\n\t\tif (goal?.id !== this.#goal?.id) this.#resetContinuationState();\n\t\tthis.#goal = goal;\n\t\tif (goal?.status !== \"active\") {\n\t\t\tthis.#cancelTimer();\n\t\t\tthis.#resetContinuationState();\n\t\t}\n\t}\n\n\t/** Temporarily prevents a scheduled continuation from racing unresolved direct-input admission. */\n\tholdDirectInput(inputId: string): void {\n\t\tif (this.#directInputHolds.has(inputId)) return;\n\t\tthis.#directInputHolds.add(inputId);\n\t\tif (this.#directInputHolds.size !== 1 || this.#timer === undefined || !this.#continuationScheduled) return;\n\t\tthis.#heldTimer = {\n\t\t\tremainingMs: Math.max(0, (this.#scheduledDueAtMs ?? Date.now()) - Date.now()),\n\t\t};\n\t\tclearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tthis.#scheduledDueAtMs = undefined;\n\t}\n\n\t/** Resolves one admission hold without allowing overlapping inputs to consume each other. */\n\tresolveDirectInput(inputId: string, accepted: boolean): void {\n\t\tif (!this.#directInputHolds.delete(inputId)) return;\n\t\tif (accepted) {\n\t\t\tthis.#heldTimer = undefined;\n\t\t\tthis.noteUserPrompt();\n\t\t\treturn;\n\t\t}\n\t\tif (this.#directInputHolds.size > 0 || this.#heldTimer === undefined) return;\n\t\tconst held = this.#heldTimer;\n\t\tthis.#heldTimer = undefined;\n\t\tthis.#armTimer(held.remainingMs);\n\t}\n\n\t/** An accepted real user prompt disarms continuation for that user-initiated turn. */\n\tnoteUserPrompt(): void {\n\t\tthis.#cancelTimer();\n\t\tthis.#endedTurnWasUserInitiated = true;\n\t\tthis.#resetContinuationState();\n\t}\n\n\t/** A queued hidden continuation has started, so the next end is not user-initiated. */\n\tnoteContinuationStarted(): void {\n\t\tthis.#endedTurnWasUserInitiated = false;\n\t}\n\n\tdispose(): void {\n\t\tthis.#cancelTimer();\n\t\tthis.#unsubscribeMonitorState?.();\n\t\tthis.#unsubscribeMonitorState = undefined;\n\t\tthis.#ctx = undefined;\n\t\tthis.#goal = null;\n\t\tthis.#activeMonitorCount = 0;\n\t\tthis.#lastAgentEndMessages = [];\n\t\tthis.#directInputHolds.clear();\n\t\tthis.#resetContinuationState();\n\t}\n\n\t#schedule(goal: Goal): void {\n\t\tif (this.#continuationScheduled) return;\n\t\tconst delayMs = GOAL_MONITOR_CONTINUATION_DELAY_MS;\n\t\tconst cache = estimateCacheWarmMetrics(this.#ctx?.model, process.env, this.#lastTurnUsage);\n\t\tthis.#scheduledCache = cache;\n\t\tthis.#scheduledAtMs = Date.now();\n\t\tif (this.#ctx?.hasUI) {\n\t\t\tthis.#ctx.ui.notify(buildCacheWarmScheduledNotice(delayMs, this.#activeMonitorCount, cache), \"info\");\n\t\t}\n\t\tthis.#pi.events?.emit(GOAL_CONTINUATION_SCHEDULED_EVENT, {\n\t\t\tgoalId: goal.id,\n\t\t\tdelayMs,\n\t\t\tactiveMonitorCount: this.#activeMonitorCount,\n\t\t\tcache,\n\t\t});\n\t\tthis.#appendWarmupEntry({\n\t\t\tphase: \"scheduled\",\n\t\t\tgoalId: goal.id,\n\t\t\tdelayMs,\n\t\t\tactiveMonitorCount: this.#activeMonitorCount,\n\t\t\t...(cache !== undefined ? { cache } : {}),\n\t\t});\n\t\tthis.#continuationScheduled = true;\n\t\tif (this.#directInputHolds.size > 0) {\n\t\t\tthis.#heldTimer = { remainingMs: delayMs };\n\t\t\treturn;\n\t\t}\n\t\tthis.#armTimer(delayMs);\n\t}\n\n\t#armTimer(delayMs: number): void {\n\t\tthis.#scheduledDueAtMs = Date.now() + delayMs;\n\t\tthis.#timer = setTimeout(() => {\n\t\t\tvoid this.#continueIfEligible().catch((error: unknown) => {\n\t\t\t\tif (this.#ctx?.hasUI) {\n\t\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tthis.#ctx.ui.notify(`Goal continuation delivery failed: ${message}`, \"error\");\n\t\t\t\t}\n\t\t\t});\n\t\t}, delayMs);\n\t}\n\n\tasync #continueIfEligible(): Promise<void> {\n\t\tthis.#timer = undefined;\n\t\tthis.#scheduledDueAtMs = undefined;\n\t\tthis.#continuationScheduled = false;\n\t\tconst delayMs = GOAL_MONITOR_CONTINUATION_DELAY_MS;\n\t\tconst waitedMs = this.#scheduledAtMs === undefined ? delayMs : Math.max(0, Date.now() - this.#scheduledAtMs);\n\t\tconst cache = this.#scheduledCache;\n\t\tthis.#scheduledAtMs = undefined;\n\t\tthis.#scheduledCache = undefined;\n\t\tconst ctx = this.#ctx;\n\t\tconst goal = this.#goal;\n\t\tif (ctx === undefined || goal?.status !== \"active\" || !ctx.isIdle() || ctx.hasPendingMessages()) return;\n\t\tif (this.#activeMonitorCount === 0) return;\n\t\tconst admission = await this.#admitAndQueue(ctx, goal, \"monitorDelayed\", this.#lastAgentEndMessages);\n\t\tif (!admission.admitted) return;\n\t\tthis.#pi.events?.emit(GOAL_CONTINUATION_RESUMED_EVENT, {\n\t\t\tgoalId: goal.id,\n\t\t\tdelayMs,\n\t\t\twaitedMs,\n\t\t\tactiveMonitorCount: this.#activeMonitorCount,\n\t\t\tcache,\n\t\t});\n\t\tthis.#appendWarmupEntry({\n\t\t\tphase: \"resumed\",\n\t\t\tgoalId: goal.id,\n\t\t\tdelayMs,\n\t\t\twaitedMs,\n\t\t\tactiveMonitorCount: this.#activeMonitorCount,\n\t\t\t...(cache !== undefined ? { cache } : {}),\n\t\t});\n\t\tif (ctx.hasUI) {\n\t\t\tctx.ui.notify(buildCacheWarmResumedNotice(waitedMs, this.#activeMonitorCount, cache), \"info\");\n\t\t}\n\t}\n\n\tasync #admitAndQueue(\n\t\tctx: ExtensionContext,\n\t\tgoal: Goal,\n\t\tpath: GoalContinuationPath,\n\t\tmessages: readonly AgentMessage[],\n\t): Promise<GoalContinuationAdmission> {\n\t\tconst input = this.#buildVerdictInput(ctx, goal, path, messages);\n\t\tconst verdict = evaluateGoalContinuation({ goal, ...input });\n\t\tconst admittedGoal = await admitAndQueueGoalContinuation(this.#pi, ctx, goal, {\n\t\t\tinput,\n\t\t\tcontent: (continuationVerdict) => this.#buildContinuationContent(ctx, goal, continuationVerdict),\n\t\t\tmarkContinuationPending: this.#markContinuationPending,\n\t\t});\n\t\tif (verdict.kind === \"continue\" && input.lastStopReason === \"length\") {\n\t\t\tthis.#consecutiveLengthRecoveries.set(goal.id, input.consecutiveLengthRecoveries + 1);\n\t\t}\n\t\tthis.#goal = admittedGoal;\n\t\tif (admittedGoal.status !== \"active\") {\n\t\t\tthis.#cancelTimer();\n\t\t\tthis.#resetToollessContinuationStreak();\n\t\t}\n\t\treturn { goal: admittedGoal, admitted: verdict.kind === \"continue\" };\n\t}\n\n\t#appendWarmupEntry(data: GoalCacheWarmupEntryData): void {\n\t\tthis.#pi.appendEntry?.<GoalCacheWarmupEntryData>(GOAL_CACHE_WARMUP_ENTRY_TYPE, data);\n\t}\n\n\t#buildVerdictInput(\n\t\tctx: ExtensionContext,\n\t\tgoal: Goal,\n\t\tpath: GoalContinuationPath,\n\t\tmessages: readonly AgentMessage[],\n\t): Omit<GoalContinuationInput, \"goal\"> {\n\t\tconst lastAssistant = findLastAssistantMessage(messages);\n\t\treturn {\n\t\t\tisIdle: ctx.isIdle(),\n\t\t\thasPendingMessages: ctx.hasPendingMessages(),\n\t\t\tpath,\n\t\t\tlastStopReason: lastAssistant?.stopReason,\n\t\t\tconsecutiveContinuations: goal.consecutiveContinuations ?? 0,\n\t\t\tlastContinuationSignature: goal.lastContinuationSignature,\n\t\t\tcurrentSignature: buildCurrentGoalContinuationSignature(ctx, goal, lastAssistantText(messages)),\n\t\t\tconsecutiveLengthRecoveries: this.#consecutiveLengthRecoveries.get(goal.id) ?? 0,\n\t\t\trecentNormalizedOutputHashes: this.#recentNormalizedOutputHashes,\n\t\t\ttoollessContinuationStreak: this.#toollessContinuationStreak,\n\t\t\tcontinuationPending: this.#isContinuationPending(),\n\t\t};\n\t}\n\n\t#buildContinuationContent(ctx: ExtensionContext, goal: Goal, verdict: ContinuingGoalContinuationVerdict): string {\n\t\tlet content = verdict.prompt === \"minimal\" ? buildTruncationRecoveryPrompt() : buildContinuationPrompt(goal);\n\t\tif (!verdict.stallNotice) return content;\n\n\t\tconst monitorsActive = this.#activeMonitorCount > 0;\n\t\tthis.#pi.events?.emit(GOAL_MONITOR_STALL_EVENT, {\n\t\t\tgoalId: goal.id,\n\t\t\tconsecutiveContinuations: this.#toollessContinuationStreak,\n\t\t\ttoolless: true,\n\t\t});\n\t\tif (ctx.hasUI) {\n\t\t\tconst context = monitorsActive ? \"while monitors stayed active\" : \"without tool use\";\n\t\t\tctx.ui.notify(\n\t\t\t\t`Goal continuation repeated ${this.#toollessContinuationStreak} toolless turns ${context} - injected a stall check.`,\n\t\t\t\t\"info\",\n\t\t\t);\n\t\t}\n\t\tcontent = `${buildGoalStallNotice(this.#toollessContinuationStreak, { monitorsActive })}\\n\\n${content}`;\n\t\treturn content;\n\t}\n\n\t/** A tool-using turn is forward progress, so it clears the repetition window instead of extending it. */\n\t#recordAssistantOutput(messages: readonly AgentMessage[], turnUsedTools: boolean): void {\n\t\tif (turnUsedTools) {\n\t\t\tthis.#recentNormalizedOutputHashes = [];\n\t\t\treturn;\n\t\t}\n\t\tconst text = lastAssistantText(messages);\n\t\tif (normalizeAssistantText(text).length === 0) return;\n\t\tthis.#recentNormalizedOutputHashes = [...this.#recentNormalizedOutputHashes, hashAssistantText(text)].slice(-3);\n\t}\n\n\t#recordToollessContinuationTurn(goal: Goal, turnUsedTools: boolean): void {\n\t\tif (goal.id !== this.#toollessStreakGoalId) {\n\t\t\tthis.#toollessStreakGoalId = goal.id;\n\t\t\tthis.#toollessContinuationStreak = 0;\n\t\t}\n\t\tif (this.#endedTurnWasUserInitiated) return;\n\t\tif (turnUsedTools) {\n\t\t\tthis.#toollessContinuationStreak = 0;\n\t\t\treturn;\n\t\t}\n\t\tthis.#toollessContinuationStreak += 1;\n\t}\n\n\t#resetLengthRecoveryAfterCleanStop(goal: Goal | null, messages: readonly AgentMessage[]): void {\n\t\tif (goal === null || findLastAssistantMessage(messages)?.stopReason !== \"stop\") return;\n\t\tthis.#consecutiveLengthRecoveries.delete(goal.id);\n\t}\n\n\t#resetContinuationState(): void {\n\t\tthis.#consecutiveLengthRecoveries.clear();\n\t\tthis.#recentNormalizedOutputHashes = [];\n\t\tthis.#resetToollessContinuationStreak();\n\t}\n\n\t#resetToollessContinuationStreak(): void {\n\t\tthis.#toollessContinuationStreak = 0;\n\t\tthis.#toollessStreakGoalId = null;\n\t}\n\n\t#cancelTimer(): void {\n\t\tthis.#scheduledAtMs = undefined;\n\t\tthis.#scheduledDueAtMs = undefined;\n\t\tthis.#scheduledCache = undefined;\n\t\tthis.#heldTimer = undefined;\n\t\tif (this.#timer !== undefined) clearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tthis.#continuationScheduled = false;\n\t}\n}\n\nfunction findLastAssistantMessage(\n\tmessages: readonly AgentMessage[],\n): Extract<AgentMessage, { role: \"assistant\" }> | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"assistant\") return message;\n\t}\n\treturn undefined;\n}\n"]}
1
+ {"version":3,"file":"monitor-continuation.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/monitor-continuation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { isTerminalMonitorStateEvent, TERMINAL_MONITOR_STATE_EVENT } from \"../monitor-state-event.ts\";\nimport {\n\tbuildCacheWarmResumedNotice,\n\tbuildCacheWarmScheduledNotice,\n\testimateCacheWarmMetrics,\n\tGOAL_CACHE_WARMUP_ENTRY_TYPE,\n\ttype GoalCacheWarmMetrics,\n\ttype GoalCacheWarmupEntryData,\n} from \"./cache-warm.ts\";\nimport {\n\tcontinuationTurnUsedTools,\n\tevaluateGoalContinuation,\n\tGOAL_STALL_TOOLLESS_THRESHOLD,\n\tGOAL_USER_GRACE_DELAY_MS,\n\ttype GoalContinuationInput,\n\ttype GoalContinuationPath,\n\ttype GoalContinuationVerdict,\n\thasGoalContinuationProgress,\n\thashAssistantText,\n\tnormalizeAssistantText,\n} from \"./continuation.ts\";\nimport {\n\tadmitAndQueueGoalContinuation,\n\tbuildCurrentGoalContinuationSignature,\n\tlastAssistantText,\n} from \"./lifecycle-helpers.ts\";\nimport { buildContinuationPrompt, buildGoalStallNotice, buildTruncationRecoveryPrompt } from \"./prompt.ts\";\nimport { resetContinuationStreak } from \"./store.ts\";\nimport { goalStoreRef } from \"./store-ref.ts\";\nimport { collectAssistantUsage } from \"./turn-usage.ts\";\nimport type { Goal, TokenUsageSnapshot } from \"./types.ts\";\nimport type { GoalWaitKind } from \"./wait-progress.ts\";\nimport type { GoalWaitTicker } from \"./wait-ticker.ts\";\n\nexport const GOAL_MONITOR_CONTINUATION_DELAY_MS = 240_000;\nexport const GOAL_CONTINUATION_SCHEDULED_EVENT = \"goal_continuation_scheduled\";\nexport const GOAL_CONTINUATION_RESUMED_EVENT = \"goal_continuation_resumed\";\nexport const GOAL_MONITOR_CONTINUATION_NOTICE = \"Goal continuation scheduled in 4 minutes while a monitor is active.\";\nexport const GOAL_MONITOR_STALL_THRESHOLD = GOAL_STALL_TOOLLESS_THRESHOLD;\nexport const GOAL_MONITOR_STALL_EVENT = \"goal_monitor_continuation_stall\";\n\ninterface AgentEndOptions {\n\treadonly ctx: ExtensionContext;\n\treadonly goal: Goal | null;\n\treadonly messages: readonly AgentMessage[];\n}\n\ntype ContinuingGoalContinuationVerdict = Extract<GoalContinuationVerdict, { kind: \"continue\" }>;\ntype DelayedContinuationKind = GoalWaitKind;\n\ntype GoalContinuationAdmission = {\n\treadonly goal: Goal;\n\treadonly admitted: boolean;\n};\n\nexport class MonitorAwareGoalContinuation {\n\treadonly #pi: ExtensionAPI;\n\treadonly #isContinuationPending: () => boolean;\n\treadonly #markContinuationPending: () => void;\n\treadonly #waitTicker: GoalWaitTicker | undefined;\n\t#activeMonitorCount = 0;\n\t#ctx: ExtensionContext | undefined;\n\t#goal: Goal | null = null;\n\t#timer: ReturnType<typeof setTimeout> | undefined;\n\t#scheduledContinuationKind: DelayedContinuationKind | undefined;\n\t#unsubscribeMonitorState: (() => void) | undefined;\n\t#lastAgentEndMessages: readonly AgentMessage[] = [];\n\t#consecutiveLengthRecoveries = new Map<string, number>();\n\t#recentNormalizedOutputHashes: string[] = [];\n\t#toollessContinuationStreak = 0;\n\t#toollessStreakGoalId: string | null = null;\n\t#endedTurnWasUserInitiated = false;\n\t#lastTurnUsage: TokenUsageSnapshot | undefined;\n\t#scheduledAtMs: number | undefined;\n\t#scheduledDueAtMs: number | undefined;\n\t#scheduledCache: GoalCacheWarmMetrics | undefined;\n\t#heldTimer: { kind: DelayedContinuationKind; remainingMs: number } | undefined;\n\t#directInputHolds = new Set<string>();\n\n\tconstructor(\n\t\tpi: ExtensionAPI,\n\t\tisContinuationPending: () => boolean = () => false,\n\t\tmarkContinuationPending: () => void = () => {},\n\t\twaitTicker?: GoalWaitTicker,\n\t) {\n\t\tthis.#pi = pi;\n\t\tthis.#isContinuationPending = isContinuationPending;\n\t\tthis.#markContinuationPending = markContinuationPending;\n\t\tthis.#waitTicker = waitTicker;\n\t}\n\n\tstart(ctx: ExtensionContext): void {\n\t\tthis.#cancelTimer();\n\t\tthis.#unsubscribeMonitorState?.();\n\t\tthis.#ctx = ctx;\n\t\tthis.#activeMonitorCount = 0;\n\t\tthis.#goal = null;\n\t\tthis.#lastAgentEndMessages = [];\n\t\tthis.#directInputHolds.clear();\n\t\tthis.#resetContinuationState();\n\t\tconst events = this.#pi.events;\n\t\tif (events === undefined) return;\n\t\tthis.#unsubscribeMonitorState = events.on(TERMINAL_MONITOR_STATE_EVENT, (data) => {\n\t\t\tif (!isTerminalMonitorStateEvent(data)) return;\n\t\t\tthis.#activeMonitorCount = data.activeCount;\n\t\t\tif (data.activeCount === 0) {\n\t\t\t\tif (this.#scheduledContinuationKind === \"monitor\") this.#cancelTimer();\n\t\t\t\tthis.#resetToollessContinuationStreak();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.#scheduledContinuationKind === \"monitor\") {\n\t\t\t\tthis.#waitTicker?.setActiveMonitorCount(data.activeCount);\n\t\t\t}\n\t\t});\n\t}\n\n\tasync afterAgentEnd(options: AgentEndOptions): Promise<Goal | null> {\n\t\tif (options.goal?.id !== this.#goal?.id) this.#resetToollessContinuationStreak();\n\t\tthis.#ctx = options.ctx;\n\t\tthis.#goal = options.goal;\n\t\tthis.#lastAgentEndMessages = options.messages;\n\t\tthis.#lastTurnUsage = collectAssistantUsage([...options.messages]);\n\t\tthis.#resetLengthRecoveryAfterCleanStop(options.goal, options.messages);\n\t\tconst turnUsedTools = continuationTurnUsedTools(options.messages);\n\t\tthis.#recordAssistantOutput(options.messages, turnUsedTools);\n\t\tif (options.goal?.status !== \"active\") {\n\t\t\tthis.#cancelTimer();\n\t\t\treturn options.goal;\n\t\t}\n\t\tthis.#recordToollessContinuationTurn(options.goal, turnUsedTools);\n\t\tconst immediateInput = this.#buildVerdictInput(options.ctx, options.goal, \"immediate\", options.messages);\n\t\tconst goal =\n\t\t\t!this.#endedTurnWasUserInitiated && (turnUsedTools || hasGoalContinuationProgress(immediateInput))\n\t\t\t\t? ((await resetContinuationStreak(goalStoreRef(options.ctx.sessionManager, options.ctx.cwd))) ??\n\t\t\t\t\toptions.goal)\n\t\t\t\t: options.goal;\n\t\tthis.#goal = goal;\n\t\tconst immediateVerdict = evaluateGoalContinuation({\n\t\t\tgoal,\n\t\t\t...this.#buildVerdictInput(options.ctx, goal, \"immediate\", options.messages),\n\t\t});\n\t\tif (this.#endedTurnWasUserInitiated) {\n\t\t\tthis.#endedTurnWasUserInitiated = false;\n\t\t\tthis.#cancelTimer();\n\t\t\tif (immediateVerdict.kind === \"continue\") {\n\t\t\t\tthis.#schedule(goal, \"userGrace\");\n\t\t\t\treturn goal;\n\t\t\t}\n\t\t\tswitch (immediateVerdict.reason) {\n\t\t\t\tcase \"not-eligible\":\n\t\t\t\tcase \"single-flight\":\n\t\t\t\tcase \"stale\":\n\t\t\t\t\treturn goal;\n\t\t\t\tcase \"cap\":\n\t\t\t\tcase \"repetition\":\n\t\t\t\tcase \"length-exhausted\": {\n\t\t\t\t\tconst admission = await this.#admitAndQueue(options.ctx, goal, \"immediate\", options.messages);\n\t\t\t\t\treturn admission.goal;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (immediateVerdict.kind === \"deny\" && immediateVerdict.reason === \"not-eligible\") return goal;\n\n\t\tif (this.#activeMonitorCount === 0) {\n\t\t\tthis.#cancelTimer();\n\t\t\tconst admission = await this.#admitAndQueue(options.ctx, goal, \"immediate\", options.messages);\n\t\t\treturn admission.goal;\n\t\t}\n\t\tthis.#schedule(goal, \"monitor\");\n\t\treturn goal;\n\t}\n\n\tsyncGoal(goal: Goal | null): void {\n\t\tif (goal?.id !== this.#goal?.id) this.#resetContinuationState();\n\t\tthis.#goal = goal;\n\t\tif (goal?.status !== \"active\") {\n\t\t\tthis.#cancelTimer();\n\t\t\tthis.#resetContinuationState();\n\t\t}\n\t}\n\n\t/** Temporarily prevents a scheduled continuation from racing unresolved direct-input admission. */\n\tholdDirectInput(inputId: string): void {\n\t\tif (this.#directInputHolds.has(inputId)) return;\n\t\tthis.#directInputHolds.add(inputId);\n\t\tif (\n\t\t\tthis.#directInputHolds.size !== 1 ||\n\t\t\tthis.#timer === undefined ||\n\t\t\tthis.#scheduledContinuationKind === undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#heldTimer = {\n\t\t\tkind: this.#scheduledContinuationKind,\n\t\t\tremainingMs: Math.max(0, (this.#scheduledDueAtMs ?? Date.now()) - Date.now()),\n\t\t};\n\t\tclearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tthis.#scheduledDueAtMs = undefined;\n\t\tthis.#waitTicker?.stop();\n\t}\n\n\t/** Resolves one admission hold without allowing overlapping inputs to consume each other. */\n\tresolveDirectInput(inputId: string, accepted: boolean): void {\n\t\tif (!this.#directInputHolds.delete(inputId)) return;\n\t\tif (accepted) {\n\t\t\tthis.#heldTimer = undefined;\n\t\t\tthis.noteUserPrompt();\n\t\t\treturn;\n\t\t}\n\t\tif (this.#directInputHolds.size > 0 || this.#heldTimer === undefined) return;\n\t\tconst held = this.#heldTimer;\n\t\tthis.#heldTimer = undefined;\n\t\tthis.#armTimer(held.kind, held.remainingMs);\n\t}\n\n\t/** An accepted real user prompt starts a grace-governed user turn. */\n\tnoteUserPrompt(): void {\n\t\tthis.#cancelTimer();\n\t\tthis.#endedTurnWasUserInitiated = true;\n\t\tthis.#resetContinuationState();\n\t}\n\n\t/** A queued hidden continuation has started, so the next end is not user-initiated. */\n\tnoteContinuationStarted(): void {\n\t\tthis.#endedTurnWasUserInitiated = false;\n\t}\n\n\tdispose(): void {\n\t\tthis.#cancelTimer();\n\t\tthis.#unsubscribeMonitorState?.();\n\t\tthis.#unsubscribeMonitorState = undefined;\n\t\tthis.#ctx = undefined;\n\t\tthis.#goal = null;\n\t\tthis.#activeMonitorCount = 0;\n\t\tthis.#lastAgentEndMessages = [];\n\t\tthis.#directInputHolds.clear();\n\t\tthis.#resetContinuationState();\n\t}\n\n\t#schedule(goal: Goal, kind: DelayedContinuationKind): void {\n\t\tif (this.#scheduledContinuationKind !== undefined) return;\n\t\tconst delayMs = kind === \"monitor\" ? GOAL_MONITOR_CONTINUATION_DELAY_MS : GOAL_USER_GRACE_DELAY_MS;\n\t\tif (kind === \"monitor\") {\n\t\t\tconst cache = estimateCacheWarmMetrics(this.#ctx?.model, process.env, this.#lastTurnUsage);\n\t\t\tthis.#scheduledCache = cache;\n\t\t\tthis.#scheduledAtMs = Date.now();\n\t\t\tif (this.#ctx?.hasUI) {\n\t\t\t\tthis.#ctx.ui.notify(buildCacheWarmScheduledNotice(delayMs, this.#activeMonitorCount, cache), \"info\");\n\t\t\t}\n\t\t\tthis.#pi.events?.emit(GOAL_CONTINUATION_SCHEDULED_EVENT, {\n\t\t\t\tgoalId: goal.id,\n\t\t\t\tdelayMs,\n\t\t\t\tactiveMonitorCount: this.#activeMonitorCount,\n\t\t\t\tcache,\n\t\t\t});\n\t\t\tthis.#appendWarmupEntry({\n\t\t\t\tphase: \"scheduled\",\n\t\t\t\tgoalId: goal.id,\n\t\t\t\tdelayMs,\n\t\t\t\tactiveMonitorCount: this.#activeMonitorCount,\n\t\t\t\t...(cache !== undefined ? { cache } : {}),\n\t\t\t});\n\t\t} else {\n\t\t\tthis.#scheduledAtMs = undefined;\n\t\t\tthis.#scheduledCache = undefined;\n\t\t}\n\t\tthis.#scheduledContinuationKind = kind;\n\t\tif (this.#directInputHolds.size > 0) {\n\t\t\tthis.#heldTimer = { kind, remainingMs: delayMs };\n\t\t\treturn;\n\t\t}\n\t\tthis.#armTimer(kind, delayMs);\n\t}\n\n\t#armTimer(kind: DelayedContinuationKind, delayMs: number): void {\n\t\tthis.#scheduledDueAtMs = Date.now() + delayMs;\n\t\tconst ctx = this.#ctx;\n\t\tif (ctx?.hasUI) {\n\t\t\tthis.#waitTicker?.sync(ctx, {\n\t\t\t\tkind,\n\t\t\t\tremainingMs: delayMs,\n\t\t\t\ttotalMs: kind === \"monitor\" ? GOAL_MONITOR_CONTINUATION_DELAY_MS : GOAL_USER_GRACE_DELAY_MS,\n\t\t\t\tactiveMonitorCount: this.#activeMonitorCount,\n\t\t\t});\n\t\t}\n\t\tthis.#timer = setTimeout(() => {\n\t\t\tvoid this.#continueIfEligible(kind).catch((error: unknown) => {\n\t\t\t\tif (this.#ctx?.hasUI) {\n\t\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tthis.#ctx.ui.notify(`Goal continuation delivery failed: ${message}`, \"error\");\n\t\t\t\t}\n\t\t\t});\n\t\t}, delayMs);\n\t}\n\n\tasync #continueIfEligible(kind: DelayedContinuationKind): Promise<void> {\n\t\tthis.#timer = undefined;\n\t\tthis.#scheduledDueAtMs = undefined;\n\t\tthis.#scheduledContinuationKind = undefined;\n\t\tthis.#waitTicker?.stop();\n\t\tconst delayMs = kind === \"monitor\" ? GOAL_MONITOR_CONTINUATION_DELAY_MS : GOAL_USER_GRACE_DELAY_MS;\n\t\tconst waitedMs = this.#scheduledAtMs === undefined ? delayMs : Math.max(0, Date.now() - this.#scheduledAtMs);\n\t\tconst cache = this.#scheduledCache;\n\t\tthis.#scheduledAtMs = undefined;\n\t\tthis.#scheduledCache = undefined;\n\t\tconst ctx = this.#ctx;\n\t\tconst goal = this.#goal;\n\t\tif (ctx === undefined || goal?.status !== \"active\" || !ctx.isIdle() || ctx.hasPendingMessages()) return;\n\t\tif (kind === \"monitor\" && this.#activeMonitorCount === 0) return;\n\t\tconst admission = await this.#admitAndQueue(\n\t\t\tctx,\n\t\t\tgoal,\n\t\t\tkind === \"monitor\" ? \"monitorDelayed\" : \"userGrace\",\n\t\t\tthis.#lastAgentEndMessages,\n\t\t);\n\t\tif (kind !== \"monitor\" || !admission.admitted) return;\n\t\tthis.#pi.events?.emit(GOAL_CONTINUATION_RESUMED_EVENT, {\n\t\t\tgoalId: goal.id,\n\t\t\tdelayMs,\n\t\t\twaitedMs,\n\t\t\tactiveMonitorCount: this.#activeMonitorCount,\n\t\t\tcache,\n\t\t});\n\t\tthis.#appendWarmupEntry({\n\t\t\tphase: \"resumed\",\n\t\t\tgoalId: goal.id,\n\t\t\tdelayMs,\n\t\t\twaitedMs,\n\t\t\tactiveMonitorCount: this.#activeMonitorCount,\n\t\t\t...(cache !== undefined ? { cache } : {}),\n\t\t});\n\t\tif (ctx.hasUI) {\n\t\t\tctx.ui.notify(buildCacheWarmResumedNotice(waitedMs, this.#activeMonitorCount, cache), \"info\");\n\t\t}\n\t}\n\n\tasync #admitAndQueue(\n\t\tctx: ExtensionContext,\n\t\tgoal: Goal,\n\t\tpath: GoalContinuationPath,\n\t\tmessages: readonly AgentMessage[],\n\t): Promise<GoalContinuationAdmission> {\n\t\tconst input = this.#buildVerdictInput(ctx, goal, path, messages);\n\t\tconst verdict = evaluateGoalContinuation({ goal, ...input });\n\t\tconst admittedGoal = await admitAndQueueGoalContinuation(this.#pi, ctx, goal, {\n\t\t\tinput,\n\t\t\tcontent: (continuationVerdict) => this.#buildContinuationContent(ctx, goal, continuationVerdict),\n\t\t\tmarkContinuationPending: this.#markContinuationPending,\n\t\t});\n\t\tif (verdict.kind === \"continue\" && input.lastStopReason === \"length\") {\n\t\t\tthis.#consecutiveLengthRecoveries.set(goal.id, input.consecutiveLengthRecoveries + 1);\n\t\t}\n\t\tthis.#goal = admittedGoal;\n\t\tif (admittedGoal.status !== \"active\") {\n\t\t\tthis.#cancelTimer();\n\t\t\tthis.#resetToollessContinuationStreak();\n\t\t}\n\t\treturn { goal: admittedGoal, admitted: verdict.kind === \"continue\" };\n\t}\n\n\t#appendWarmupEntry(data: GoalCacheWarmupEntryData): void {\n\t\tthis.#pi.appendEntry?.<GoalCacheWarmupEntryData>(GOAL_CACHE_WARMUP_ENTRY_TYPE, data);\n\t}\n\n\t#buildVerdictInput(\n\t\tctx: ExtensionContext,\n\t\tgoal: Goal,\n\t\tpath: GoalContinuationPath,\n\t\tmessages: readonly AgentMessage[],\n\t): Omit<GoalContinuationInput, \"goal\"> {\n\t\tconst lastAssistant = findLastAssistantMessage(messages);\n\t\treturn {\n\t\t\tisIdle: ctx.isIdle(),\n\t\t\thasPendingMessages: ctx.hasPendingMessages(),\n\t\t\tpath,\n\t\t\tlastStopReason: lastAssistant?.stopReason,\n\t\t\tconsecutiveContinuations: goal.consecutiveContinuations ?? 0,\n\t\t\tlastContinuationSignature: goal.lastContinuationSignature,\n\t\t\tcurrentSignature: buildCurrentGoalContinuationSignature(ctx, goal, lastAssistantText(messages)),\n\t\t\tconsecutiveLengthRecoveries: this.#consecutiveLengthRecoveries.get(goal.id) ?? 0,\n\t\t\trecentNormalizedOutputHashes: this.#recentNormalizedOutputHashes,\n\t\t\ttoollessContinuationStreak: this.#toollessContinuationStreak,\n\t\t\tcontinuationPending: this.#isContinuationPending(),\n\t\t};\n\t}\n\n\t#buildContinuationContent(ctx: ExtensionContext, goal: Goal, verdict: ContinuingGoalContinuationVerdict): string {\n\t\tlet content = verdict.prompt === \"minimal\" ? buildTruncationRecoveryPrompt() : buildContinuationPrompt(goal);\n\t\tif (!verdict.stallNotice) return content;\n\n\t\tconst monitorsActive = this.#activeMonitorCount > 0;\n\t\tthis.#pi.events?.emit(GOAL_MONITOR_STALL_EVENT, {\n\t\t\tgoalId: goal.id,\n\t\t\tconsecutiveContinuations: this.#toollessContinuationStreak,\n\t\t\ttoolless: true,\n\t\t});\n\t\tif (ctx.hasUI) {\n\t\t\tconst context = monitorsActive ? \"while monitors stayed active\" : \"without tool use\";\n\t\t\tctx.ui.notify(\n\t\t\t\t`Goal continuation repeated ${this.#toollessContinuationStreak} toolless turns ${context} - injected a stall check.`,\n\t\t\t\t\"info\",\n\t\t\t);\n\t\t}\n\t\tcontent = `${buildGoalStallNotice(this.#toollessContinuationStreak, { monitorsActive })}\\n\\n${content}`;\n\t\treturn content;\n\t}\n\n\t/** A tool-using turn is forward progress, so it clears the repetition window instead of extending it. */\n\t#recordAssistantOutput(messages: readonly AgentMessage[], turnUsedTools: boolean): void {\n\t\tif (turnUsedTools) {\n\t\t\tthis.#recentNormalizedOutputHashes = [];\n\t\t\treturn;\n\t\t}\n\t\tconst text = lastAssistantText(messages);\n\t\tif (normalizeAssistantText(text).length === 0) return;\n\t\tthis.#recentNormalizedOutputHashes = [...this.#recentNormalizedOutputHashes, hashAssistantText(text)].slice(-3);\n\t}\n\n\t#recordToollessContinuationTurn(goal: Goal, turnUsedTools: boolean): void {\n\t\tif (goal.id !== this.#toollessStreakGoalId) {\n\t\t\tthis.#toollessStreakGoalId = goal.id;\n\t\t\tthis.#toollessContinuationStreak = 0;\n\t\t}\n\t\tif (this.#endedTurnWasUserInitiated) return;\n\t\tif (turnUsedTools) {\n\t\t\tthis.#toollessContinuationStreak = 0;\n\t\t\treturn;\n\t\t}\n\t\tthis.#toollessContinuationStreak += 1;\n\t}\n\n\t#resetLengthRecoveryAfterCleanStop(goal: Goal | null, messages: readonly AgentMessage[]): void {\n\t\tif (goal === null || findLastAssistantMessage(messages)?.stopReason !== \"stop\") return;\n\t\tthis.#consecutiveLengthRecoveries.delete(goal.id);\n\t}\n\n\t#resetContinuationState(): void {\n\t\tthis.#consecutiveLengthRecoveries.clear();\n\t\tthis.#recentNormalizedOutputHashes = [];\n\t\tthis.#resetToollessContinuationStreak();\n\t}\n\n\t#resetToollessContinuationStreak(): void {\n\t\tthis.#toollessContinuationStreak = 0;\n\t\tthis.#toollessStreakGoalId = null;\n\t}\n\n\t#cancelTimer(): void {\n\t\tthis.#scheduledAtMs = undefined;\n\t\tthis.#scheduledDueAtMs = undefined;\n\t\tthis.#scheduledCache = undefined;\n\t\tthis.#heldTimer = undefined;\n\t\tif (this.#timer !== undefined) clearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tthis.#scheduledContinuationKind = undefined;\n\t\tthis.#waitTicker?.stop();\n\t}\n}\n\nfunction findLastAssistantMessage(\n\tmessages: readonly AgentMessage[],\n): Extract<AgentMessage, { role: \"assistant\" }> | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst message = messages[index];\n\t\tif (message?.role === \"assistant\") return message;\n\t}\n\treturn undefined;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ export type GoalWaitKind = "monitor" | "userGrace";
2
+ export interface GoalWaitLabelInput {
3
+ readonly kind: GoalWaitKind;
4
+ readonly remainingMs: number;
5
+ readonly totalMs: number;
6
+ readonly activeMonitorCount: number;
7
+ }
8
+ export declare const GOAL_WAIT_BAR_CELLS = 12;
9
+ export declare function renderGoalWaitBar(elapsedRatio: number): string;
10
+ export declare function formatGoalWaitLabel(input: GoalWaitLabelInput): string;
11
+ //# sourceMappingURL=wait-progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-progress.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/wait-progress.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACpC;AAED,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAUtC,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAG9D;AAWD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAOrE"}
@@ -0,0 +1,30 @@
1
+ import { formatWakeDuration } from "./cache-warm.js";
2
+ export const GOAL_WAIT_BAR_CELLS = 12;
3
+ const FILLED_CELL = "\u25b0";
4
+ const EMPTY_CELL = "\u25b1";
5
+ function clampRatio(value) {
6
+ if (!Number.isFinite(value))
7
+ return 0;
8
+ return Math.min(1, Math.max(0, value));
9
+ }
10
+ export function renderGoalWaitBar(elapsedRatio) {
11
+ const filled = Math.round(clampRatio(elapsedRatio) * GOAL_WAIT_BAR_CELLS);
12
+ return FILLED_CELL.repeat(filled) + EMPTY_CELL.repeat(GOAL_WAIT_BAR_CELLS - filled);
13
+ }
14
+ function elapsedRatioOf(remainingMs, totalMs) {
15
+ if (totalMs <= 0)
16
+ return 1;
17
+ return clampRatio((totalMs - Math.max(0, remainingMs)) / totalMs);
18
+ }
19
+ function monitorsOnDuty(count) {
20
+ return count === 1 ? "1 monitor on duty" : `${count} monitors on duty`;
21
+ }
22
+ export function formatGoalWaitLabel(input) {
23
+ const bar = renderGoalWaitBar(elapsedRatioOf(input.remainingMs, input.totalMs));
24
+ const remaining = formatWakeDuration(Math.max(0, input.remainingMs));
25
+ if (input.kind === "monitor") {
26
+ return `${bar} goal continues in ${remaining} \u00b7 ${monitorsOnDuty(input.activeMonitorCount)}`;
27
+ }
28
+ return `${bar} goal resumes in ${remaining}`;
29
+ }
30
+ //# sourceMappingURL=wait-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-progress.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/wait-progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAWrD,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAC7B,MAAM,UAAU,GAAG,QAAQ,CAAC;AAE5B,SAAS,UAAU,CAAC,KAAa;IAChC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,YAAoB;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,mBAAmB,CAAC,CAAC;IAC1E,OAAO,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,mBAAmB,GAAG,MAAM,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,cAAc,CAAC,WAAmB,EAAE,OAAe;IAC3D,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3B,OAAO,UAAU,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACpC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,KAAK,mBAAmB,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAyB;IAC5D,MAAM,GAAG,GAAG,iBAAiB,CAAC,cAAc,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAChF,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IACrE,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,GAAG,GAAG,sBAAsB,SAAS,WAAW,cAAc,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;IACnG,CAAC;IACD,OAAO,GAAG,GAAG,oBAAoB,SAAS,EAAE,CAAC;AAC9C,CAAC","sourcesContent":["import { formatWakeDuration } from \"./cache-warm.ts\";\n\nexport type GoalWaitKind = \"monitor\" | \"userGrace\";\n\nexport interface GoalWaitLabelInput {\n\treadonly kind: GoalWaitKind;\n\treadonly remainingMs: number;\n\treadonly totalMs: number;\n\treadonly activeMonitorCount: number;\n}\n\nexport const GOAL_WAIT_BAR_CELLS = 12;\n\nconst FILLED_CELL = \"\\u25b0\";\nconst EMPTY_CELL = \"\\u25b1\";\n\nfunction clampRatio(value: number): number {\n\tif (!Number.isFinite(value)) return 0;\n\treturn Math.min(1, Math.max(0, value));\n}\n\nexport function renderGoalWaitBar(elapsedRatio: number): string {\n\tconst filled = Math.round(clampRatio(elapsedRatio) * GOAL_WAIT_BAR_CELLS);\n\treturn FILLED_CELL.repeat(filled) + EMPTY_CELL.repeat(GOAL_WAIT_BAR_CELLS - filled);\n}\n\nfunction elapsedRatioOf(remainingMs: number, totalMs: number): number {\n\tif (totalMs <= 0) return 1;\n\treturn clampRatio((totalMs - Math.max(0, remainingMs)) / totalMs);\n}\n\nfunction monitorsOnDuty(count: number): string {\n\treturn count === 1 ? \"1 monitor on duty\" : `${count} monitors on duty`;\n}\n\nexport function formatGoalWaitLabel(input: GoalWaitLabelInput): string {\n\tconst bar = renderGoalWaitBar(elapsedRatioOf(input.remainingMs, input.totalMs));\n\tconst remaining = formatWakeDuration(Math.max(0, input.remainingMs));\n\tif (input.kind === \"monitor\") {\n\t\treturn `${bar} goal continues in ${remaining} \\u00b7 ${monitorsOnDuty(input.activeMonitorCount)}`;\n\t}\n\treturn `${bar} goal resumes in ${remaining}`;\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import type { ExtensionContext } from "../../types.ts";
2
+ import { type GoalWaitLabelInput } from "./wait-progress.ts";
3
+ /** Footer countdown refresh cadence while a Goal continuation is delayed. */
4
+ export declare const GOAL_WAIT_TICK_INTERVAL_MS = 1000;
5
+ export declare const GOAL_WAIT_STATUS_KEY = "goal-wait";
6
+ /** Receives the freshly formatted footer status text (undefined clears the status). */
7
+ export type GoalWaitRender = (ctx: ExtensionContext, status: string | undefined) => void;
8
+ export interface GoalWaitTickerOptions {
9
+ readonly render: GoalWaitRender;
10
+ /** Injectable clock for tests; defaults to Date.now. */
11
+ readonly now?: () => number;
12
+ }
13
+ /**
14
+ * Drives a once-per-second footer countdown while a Goal continuation timer is
15
+ * armed. Mirrors the existing GoalElapsedTicker and MonitorStatusTicker: the
16
+ * interval is unref'd and unchanged visible labels are not rendered again.
17
+ */
18
+ export declare class GoalWaitTicker {
19
+ private readonly render;
20
+ private readonly now;
21
+ private intervalId;
22
+ private ctx;
23
+ private kind;
24
+ private dueAtMs;
25
+ private totalMs;
26
+ private activeMonitorCount;
27
+ private lastRenderedStatus;
28
+ constructor(options: GoalWaitTickerOptions);
29
+ get running(): boolean;
30
+ /** Render the current wait immediately and keep it live until stopped. */
31
+ sync(ctx: ExtensionContext, input: GoalWaitLabelInput): void;
32
+ /** Refresh monitor wording without changing the countdown deadline. */
33
+ setActiveMonitorCount(activeMonitorCount: number): void;
34
+ /** Stop ticking, clear the footer segment, and drop the retained context. */
35
+ stop(): void;
36
+ private tick;
37
+ }
38
+ //# sourceMappingURL=wait-ticker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-ticker.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/wait-ticker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAA0C,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAErG,6EAA6E;AAC7E,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAC/C,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAEhD,uFAAuF;AACvF,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;AAEzF,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,wDAAwD;IACxD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,GAAG,CAA+B;IAC1C,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,YAAY,OAAO,EAAE,qBAAqB,EAGzC;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,0EAA0E;IAC1E,IAAI,CAAC,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAY3D;IAED,uEAAuE;IACvE,qBAAqB,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAItD;IAED,6EAA6E;IAC7E,IAAI,IAAI,IAAI,CAUX;IAED,OAAO,CAAC,IAAI;CAYZ"}
@@ -0,0 +1,71 @@
1
+ import { formatGoalWaitLabel } from "./wait-progress.js";
2
+ /** Footer countdown refresh cadence while a Goal continuation is delayed. */
3
+ export const GOAL_WAIT_TICK_INTERVAL_MS = 1000;
4
+ export const GOAL_WAIT_STATUS_KEY = "goal-wait";
5
+ /**
6
+ * Drives a once-per-second footer countdown while a Goal continuation timer is
7
+ * armed. Mirrors the existing GoalElapsedTicker and MonitorStatusTicker: the
8
+ * interval is unref'd and unchanged visible labels are not rendered again.
9
+ */
10
+ export class GoalWaitTicker {
11
+ constructor(options) {
12
+ this.dueAtMs = 0;
13
+ this.totalMs = 0;
14
+ this.activeMonitorCount = 0;
15
+ this.render = options.render;
16
+ this.now = options.now ?? Date.now;
17
+ }
18
+ get running() {
19
+ return this.intervalId !== undefined;
20
+ }
21
+ /** Render the current wait immediately and keep it live until stopped. */
22
+ sync(ctx, input) {
23
+ this.ctx = ctx;
24
+ this.kind = input.kind;
25
+ this.dueAtMs = this.now() + Math.max(0, input.remainingMs);
26
+ this.totalMs = input.totalMs;
27
+ this.activeMonitorCount = input.activeMonitorCount;
28
+ this.lastRenderedStatus = undefined;
29
+ this.tick();
30
+ if (this.intervalId !== undefined)
31
+ return;
32
+ const handle = setInterval(() => this.tick(), GOAL_WAIT_TICK_INTERVAL_MS);
33
+ handle.unref();
34
+ this.intervalId = handle;
35
+ }
36
+ /** Refresh monitor wording without changing the countdown deadline. */
37
+ setActiveMonitorCount(activeMonitorCount) {
38
+ if (this.ctx === undefined || this.kind !== "monitor")
39
+ return;
40
+ this.activeMonitorCount = activeMonitorCount;
41
+ this.tick();
42
+ }
43
+ /** Stop ticking, clear the footer segment, and drop the retained context. */
44
+ stop() {
45
+ if (this.intervalId !== undefined) {
46
+ clearInterval(this.intervalId);
47
+ this.intervalId = undefined;
48
+ }
49
+ const ctx = this.ctx;
50
+ this.ctx = undefined;
51
+ this.kind = undefined;
52
+ this.lastRenderedStatus = undefined;
53
+ if (ctx !== undefined)
54
+ this.render(ctx, undefined);
55
+ }
56
+ tick() {
57
+ if (this.ctx === undefined || this.kind === undefined)
58
+ return;
59
+ const status = formatGoalWaitLabel({
60
+ kind: this.kind,
61
+ remainingMs: Math.max(0, this.dueAtMs - this.now()),
62
+ totalMs: this.totalMs,
63
+ activeMonitorCount: this.activeMonitorCount,
64
+ });
65
+ if (status === this.lastRenderedStatus)
66
+ return;
67
+ this.lastRenderedStatus = status;
68
+ this.render(this.ctx, status);
69
+ }
70
+ }
71
+ //# sourceMappingURL=wait-ticker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-ticker.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/wait-ticker.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionContext } from \"../../types.ts\";\nimport { formatGoalWaitLabel, type GoalWaitKind, type GoalWaitLabelInput } from \"./wait-progress.ts\";\n\n/** Footer countdown refresh cadence while a Goal continuation is delayed. */\nexport const GOAL_WAIT_TICK_INTERVAL_MS = 1000;\nexport const GOAL_WAIT_STATUS_KEY = \"goal-wait\";\n\n/** Receives the freshly formatted footer status text (undefined clears the status). */\nexport type GoalWaitRender = (ctx: ExtensionContext, status: string | undefined) => void;\n\nexport interface GoalWaitTickerOptions {\n\treadonly render: GoalWaitRender;\n\t/** Injectable clock for tests; defaults to Date.now. */\n\treadonly now?: () => number;\n}\n\n/**\n * Drives a once-per-second footer countdown while a Goal continuation timer is\n * armed. Mirrors the existing GoalElapsedTicker and MonitorStatusTicker: the\n * interval is unref'd and unchanged visible labels are not rendered again.\n */\nexport class GoalWaitTicker {\n\tprivate readonly render: GoalWaitRender;\n\tprivate readonly now: () => number;\n\tprivate intervalId: NodeJS.Timeout | undefined;\n\tprivate ctx: ExtensionContext | undefined;\n\tprivate kind: GoalWaitKind | undefined;\n\tprivate dueAtMs = 0;\n\tprivate totalMs = 0;\n\tprivate activeMonitorCount = 0;\n\tprivate lastRenderedStatus: string | undefined;\n\n\tconstructor(options: GoalWaitTickerOptions) {\n\t\tthis.render = options.render;\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tget running(): boolean {\n\t\treturn this.intervalId !== undefined;\n\t}\n\n\t/** Render the current wait immediately and keep it live until stopped. */\n\tsync(ctx: ExtensionContext, input: GoalWaitLabelInput): void {\n\t\tthis.ctx = ctx;\n\t\tthis.kind = input.kind;\n\t\tthis.dueAtMs = this.now() + Math.max(0, input.remainingMs);\n\t\tthis.totalMs = input.totalMs;\n\t\tthis.activeMonitorCount = input.activeMonitorCount;\n\t\tthis.lastRenderedStatus = undefined;\n\t\tthis.tick();\n\t\tif (this.intervalId !== undefined) return;\n\t\tconst handle = setInterval(() => this.tick(), GOAL_WAIT_TICK_INTERVAL_MS);\n\t\thandle.unref();\n\t\tthis.intervalId = handle;\n\t}\n\n\t/** Refresh monitor wording without changing the countdown deadline. */\n\tsetActiveMonitorCount(activeMonitorCount: number): void {\n\t\tif (this.ctx === undefined || this.kind !== \"monitor\") return;\n\t\tthis.activeMonitorCount = activeMonitorCount;\n\t\tthis.tick();\n\t}\n\n\t/** Stop ticking, clear the footer segment, and drop the retained context. */\n\tstop(): void {\n\t\tif (this.intervalId !== undefined) {\n\t\t\tclearInterval(this.intervalId);\n\t\t\tthis.intervalId = undefined;\n\t\t}\n\t\tconst ctx = this.ctx;\n\t\tthis.ctx = undefined;\n\t\tthis.kind = undefined;\n\t\tthis.lastRenderedStatus = undefined;\n\t\tif (ctx !== undefined) this.render(ctx, undefined);\n\t}\n\n\tprivate tick(): void {\n\t\tif (this.ctx === undefined || this.kind === undefined) return;\n\t\tconst status = formatGoalWaitLabel({\n\t\t\tkind: this.kind,\n\t\t\tremainingMs: Math.max(0, this.dueAtMs - this.now()),\n\t\t\ttotalMs: this.totalMs,\n\t\t\tactiveMonitorCount: this.activeMonitorCount,\n\t\t});\n\t\tif (status === this.lastRenderedStatus) return;\n\t\tthis.lastRenderedStatus = status;\n\t\tthis.render(this.ctx, status);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/gpt-apply-patch/extension.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EACX,sBAAsB,EAGtB,kBAAkB,EAClB,MAAM,YAAY,CAAC;AAepB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,SAAS,GAAG,kBAAkB,CAK9G;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,SAAS,GAAG,OAAO,CAE9F;AA0DD,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,sBAAsB,GAAG,IAAI,CAoB5E;eAEc,2BAA2B"}
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/gpt-apply-patch/extension.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EACX,sBAAsB,EAGtB,kBAAkB,EAClB,MAAM,YAAY,CAAC;AAepB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,SAAS,GAAG,kBAAkB,CAK9G;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,SAAS,GAAG,OAAO,CAE9F;AA2ED,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,sBAAsB,GAAG,IAAI,CAwB5E;eAEc,2BAA2B"}
@@ -48,6 +48,7 @@ function hasApplyPatchFailures(details) {
48
48
  }
49
49
  function syncToolset(pi, model, state, variants) {
50
50
  const mode = getApplyPatchWireMode(model);
51
+ state.wireMode = mode;
51
52
  const currentToolNames = pi.getActiveTools();
52
53
  if (mode !== "none") {
53
54
  if (state.activeVariant !== mode) {
@@ -71,14 +72,26 @@ function syncToolset(pi, model, state, variants) {
71
72
  state.removedEditToolNames = [];
72
73
  pi.setActiveTools([...new Set(restored)]);
73
74
  }
75
+ function registerApplyPatchLazyActivator(pi, state) {
76
+ pi.registerLazyToolActivator?.((toolName) => {
77
+ if (toolName !== APPLY_PATCH_NAME || state.wireMode === "none")
78
+ return false;
79
+ const activeToolNames = pi.getActiveTools();
80
+ if (activeToolNames.includes(APPLY_PATCH_NAME))
81
+ return false;
82
+ pi.setActiveTools([...activeToolNames, APPLY_PATCH_NAME]);
83
+ return true;
84
+ });
85
+ }
74
86
  export function registerApplyPatchExtension(pi) {
75
- const state = { removedEditToolNames: [] };
87
+ const state = { removedEditToolNames: [], wireMode: "none" };
76
88
  const variants = {
77
89
  freeform: createApplyPatchTool("freeform"),
78
90
  json: createApplyPatchTool("json"),
79
91
  };
80
92
  state.activeVariant = "freeform";
81
93
  pi.registerTool(variants.freeform);
94
+ registerApplyPatchLazyActivator(pi, state);
82
95
  pi.on("tool_result", async (event) => {
83
96
  if (event.toolName !== APPLY_PATCH_NAME || event.isError || !hasApplyPatchFailures(event.details)) {
84
97
  return undefined;