@xgjktech/xg_cwork_im 1.19.43 → 1.19.45

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 (394) hide show
  1. package/README.md +492 -492
  2. package/dist/src/account-connection.d.ts +1 -1
  3. package/dist/src/account-connection.d.ts.map +1 -1
  4. package/dist/src/account-connection.js +136 -25
  5. package/dist/src/account-connection.js.map +1 -1
  6. package/dist/src/account-reconciler.d.ts +17 -8
  7. package/dist/src/account-reconciler.d.ts.map +1 -1
  8. package/dist/src/account-reconciler.js +31 -11
  9. package/dist/src/account-reconciler.js.map +1 -1
  10. package/dist/src/account-reconciler.test.js +19 -1
  11. package/dist/src/account-reconciler.test.js.map +1 -1
  12. package/dist/src/action-store-access.d.ts +2 -0
  13. package/dist/src/action-store-access.d.ts.map +1 -1
  14. package/dist/src/action-store-access.js +7 -0
  15. package/dist/src/action-store-access.js.map +1 -1
  16. package/dist/src/action-store-lifecycle.test.d.ts +2 -0
  17. package/dist/src/action-store-lifecycle.test.d.ts.map +1 -0
  18. package/dist/src/action-store-lifecycle.test.js +195 -0
  19. package/dist/src/action-store-lifecycle.test.js.map +1 -0
  20. package/dist/src/active-cron-context-store.d.ts +20 -0
  21. package/dist/src/active-cron-context-store.d.ts.map +1 -0
  22. package/dist/src/active-cron-context-store.js +73 -0
  23. package/dist/src/active-cron-context-store.js.map +1 -0
  24. package/dist/src/active-round-registry.d.ts +6 -0
  25. package/dist/src/active-round-registry.d.ts.map +1 -1
  26. package/dist/src/active-round-registry.js +27 -2
  27. package/dist/src/active-round-registry.js.map +1 -1
  28. package/dist/src/agent-stream-client-registry.d.ts +2 -0
  29. package/dist/src/agent-stream-client-registry.d.ts.map +1 -1
  30. package/dist/src/agent-stream-client-registry.js +6 -1
  31. package/dist/src/agent-stream-client-registry.js.map +1 -1
  32. package/dist/src/apply-sync-mapping.d.ts +1 -1
  33. package/dist/src/apply-sync-mapping.d.ts.map +1 -1
  34. package/dist/src/assistant-item-delivery.d.ts +27 -0
  35. package/dist/src/assistant-item-delivery.d.ts.map +1 -0
  36. package/dist/src/assistant-item-delivery.js +134 -0
  37. package/dist/src/assistant-item-delivery.js.map +1 -0
  38. package/dist/src/assistant-item-delivery.test.d.ts +2 -0
  39. package/dist/src/assistant-item-delivery.test.d.ts.map +1 -0
  40. package/dist/src/assistant-item-delivery.test.js +116 -0
  41. package/dist/src/assistant-item-delivery.test.js.map +1 -0
  42. package/dist/src/assistant-item-sink.d.ts +17 -0
  43. package/dist/src/assistant-item-sink.d.ts.map +1 -0
  44. package/dist/src/assistant-item-sink.js +34 -0
  45. package/dist/src/assistant-item-sink.js.map +1 -0
  46. package/dist/src/auth.d.ts +2 -0
  47. package/dist/src/auth.d.ts.map +1 -1
  48. package/dist/src/auth.js +4 -0
  49. package/dist/src/auth.js.map +1 -1
  50. package/dist/src/block-streaming-config.test.js +7 -1
  51. package/dist/src/block-streaming-config.test.js.map +1 -1
  52. package/dist/src/build-project-prompt.test.js +18 -18
  53. package/dist/src/channel-config.d.ts +83 -17
  54. package/dist/src/channel-config.d.ts.map +1 -1
  55. package/dist/src/channel-config.js +46 -13
  56. package/dist/src/channel-config.js.map +1 -1
  57. package/dist/src/channel-config.test.js +58 -1
  58. package/dist/src/channel-config.test.js.map +1 -1
  59. package/dist/src/channel.d.ts +4 -3
  60. package/dist/src/channel.d.ts.map +1 -1
  61. package/dist/src/channel.js +127 -4
  62. package/dist/src/channel.js.map +1 -1
  63. package/dist/src/connection-workspace-event.test.d.ts +2 -0
  64. package/dist/src/connection-workspace-event.test.d.ts.map +1 -0
  65. package/dist/src/connection-workspace-event.test.js +74 -0
  66. package/dist/src/connection-workspace-event.test.js.map +1 -0
  67. package/dist/src/connection.d.ts +28 -0
  68. package/dist/src/connection.d.ts.map +1 -1
  69. package/dist/src/connection.js +155 -78
  70. package/dist/src/connection.js.map +1 -1
  71. package/dist/src/connection.test.d.ts +2 -0
  72. package/dist/src/connection.test.d.ts.map +1 -0
  73. package/dist/src/connection.test.js +110 -0
  74. package/dist/src/connection.test.js.map +1 -0
  75. package/dist/src/cron-appkey-binding-store.d.ts +29 -0
  76. package/dist/src/cron-appkey-binding-store.d.ts.map +1 -0
  77. package/dist/src/cron-appkey-binding-store.js +239 -0
  78. package/dist/src/cron-appkey-binding-store.js.map +1 -0
  79. package/dist/src/cron-appkey-binding-store.test.d.ts +2 -0
  80. package/dist/src/cron-appkey-binding-store.test.d.ts.map +1 -0
  81. package/dist/src/cron-appkey-binding-store.test.js +387 -0
  82. package/dist/src/cron-appkey-binding-store.test.js.map +1 -0
  83. package/dist/src/deliver-text.test.js +22 -22
  84. package/dist/src/delivery/ai-task-push.d.ts +16 -0
  85. package/dist/src/delivery/ai-task-push.d.ts.map +1 -0
  86. package/dist/src/delivery/ai-task-push.js +44 -0
  87. package/dist/src/delivery/ai-task-push.js.map +1 -0
  88. package/dist/src/delivery/ai-task-push.test.d.ts +2 -0
  89. package/dist/src/delivery/ai-task-push.test.d.ts.map +1 -0
  90. package/dist/src/delivery/ai-task-push.test.js +44 -0
  91. package/dist/src/delivery/ai-task-push.test.js.map +1 -0
  92. package/dist/src/delivery/deliver-text.test.js +22 -22
  93. package/dist/src/delivery/send-service.d.ts +4 -1
  94. package/dist/src/delivery/send-service.d.ts.map +1 -1
  95. package/dist/src/delivery/send-service.js +3 -5
  96. package/dist/src/delivery/send-service.js.map +1 -1
  97. package/dist/src/delivery/turn-deliver-buffer.test.js +25 -25
  98. package/dist/src/dispatch-mentioned-reply.d.ts +7 -2
  99. package/dist/src/dispatch-mentioned-reply.d.ts.map +1 -1
  100. package/dist/src/dispatch-mentioned-reply.js +243 -68
  101. package/dist/src/dispatch-mentioned-reply.js.map +1 -1
  102. package/dist/src/gateway-session-queue.d.ts +2 -6
  103. package/dist/src/gateway-session-queue.d.ts.map +1 -1
  104. package/dist/src/gateway-session-queue.js +78 -21
  105. package/dist/src/gateway-session-queue.js.map +1 -1
  106. package/dist/src/group-history-tool.d.ts +1 -1
  107. package/dist/src/group-history-tool.d.ts.map +1 -1
  108. package/dist/src/inbound/dispatch-mentioned-reply.d.ts.map +1 -1
  109. package/dist/src/inbound/dispatch-mentioned-reply.js +43 -3
  110. package/dist/src/inbound/dispatch-mentioned-reply.js.map +1 -1
  111. package/dist/src/inbound/inbound-display.d.ts.map +1 -1
  112. package/dist/src/inbound/inbound-display.js +2 -0
  113. package/dist/src/inbound/inbound-display.js.map +1 -1
  114. package/dist/src/inbound/inbound-display.test.js +1 -0
  115. package/dist/src/inbound/inbound-display.test.js.map +1 -1
  116. package/dist/src/inbound-display.d.ts.map +1 -1
  117. package/dist/src/inbound-display.js +2 -1
  118. package/dist/src/inbound-display.js.map +1 -1
  119. package/dist/src/inbound-input-media.d.ts +1 -1
  120. package/dist/src/inbound-input-media.d.ts.map +1 -1
  121. package/dist/src/inbound-media-local.d.ts +1 -1
  122. package/dist/src/inbound-media-local.d.ts.map +1 -1
  123. package/dist/src/inbound-model.d.ts +9 -0
  124. package/dist/src/inbound-model.d.ts.map +1 -1
  125. package/dist/src/inbound-model.js +26 -0
  126. package/dist/src/inbound-model.js.map +1 -1
  127. package/dist/src/inbound-model.test.js +23 -1
  128. package/dist/src/inbound-model.test.js.map +1 -1
  129. package/dist/src/inbound-terminal-state.d.ts +2 -0
  130. package/dist/src/inbound-terminal-state.d.ts.map +1 -1
  131. package/dist/src/inbound-terminal-state.js +7 -2
  132. package/dist/src/inbound-terminal-state.js.map +1 -1
  133. package/dist/src/nas-site.d.ts +16 -0
  134. package/dist/src/nas-site.d.ts.map +1 -0
  135. package/dist/src/nas-site.js +17 -0
  136. package/dist/src/nas-site.js.map +1 -0
  137. package/dist/src/nas-volumes.d.ts +12 -2
  138. package/dist/src/nas-volumes.d.ts.map +1 -1
  139. package/dist/src/nas-volumes.js +147 -37
  140. package/dist/src/nas-volumes.js.map +1 -1
  141. package/dist/src/nas-volumes.test.js +39 -7
  142. package/dist/src/nas-volumes.test.js.map +1 -1
  143. package/dist/src/per-message-model-pending.d.ts +38 -3
  144. package/dist/src/per-message-model-pending.d.ts.map +1 -1
  145. package/dist/src/per-message-model-pending.js +96 -7
  146. package/dist/src/per-message-model-pending.js.map +1 -1
  147. package/dist/src/plan/action-store-lifecycle.test.js +5 -5
  148. package/dist/src/plan/plan-core-db.test.js +9 -9
  149. package/dist/src/plan/plan-core-snapshot.test.js +9 -9
  150. package/dist/src/plan-core-adapter.d.ts +54 -0
  151. package/dist/src/plan-core-adapter.d.ts.map +1 -0
  152. package/dist/src/plan-core-adapter.js +104 -0
  153. package/dist/src/plan-core-adapter.js.map +1 -0
  154. package/dist/src/plan-core-adapter.test.d.ts +2 -0
  155. package/dist/src/plan-core-adapter.test.d.ts.map +1 -0
  156. package/dist/src/plan-core-adapter.test.js +183 -0
  157. package/dist/src/plan-core-adapter.test.js.map +1 -0
  158. package/dist/src/plan-core-db.d.ts +22 -0
  159. package/dist/src/plan-core-db.d.ts.map +1 -0
  160. package/dist/src/plan-core-db.js +91 -0
  161. package/dist/src/plan-core-db.js.map +1 -0
  162. package/dist/src/plan-core-db.test.d.ts +2 -0
  163. package/dist/src/plan-core-db.test.d.ts.map +1 -0
  164. package/dist/src/plan-core-db.test.js +115 -0
  165. package/dist/src/plan-core-db.test.js.map +1 -0
  166. package/dist/src/plan-core-snapshot.d.ts +23 -0
  167. package/dist/src/plan-core-snapshot.d.ts.map +1 -0
  168. package/dist/src/plan-core-snapshot.js +66 -0
  169. package/dist/src/plan-core-snapshot.js.map +1 -0
  170. package/dist/src/plan-core-snapshot.test.d.ts +2 -0
  171. package/dist/src/plan-core-snapshot.test.d.ts.map +1 -0
  172. package/dist/src/plan-core-snapshot.test.js +157 -0
  173. package/dist/src/plan-core-snapshot.test.js.map +1 -0
  174. package/dist/src/plan-event-subscription.d.ts +1 -1
  175. package/dist/src/plan-event-subscription.d.ts.map +1 -1
  176. package/dist/src/plan-stat-event.d.ts +4 -15
  177. package/dist/src/plan-stat-event.d.ts.map +1 -1
  178. package/dist/src/plan-stat-event.js +4 -37
  179. package/dist/src/plan-stat-event.js.map +1 -1
  180. package/dist/src/plan-stat-event.test.js +1 -118
  181. package/dist/src/plan-stat-event.test.js.map +1 -1
  182. package/dist/src/plan-tool-middleware.d.ts +3 -11
  183. package/dist/src/plan-tool-middleware.d.ts.map +1 -1
  184. package/dist/src/plan-tool-middleware.js +11 -60
  185. package/dist/src/plan-tool-middleware.js.map +1 -1
  186. package/dist/src/plan-tool-middleware.test.js +83 -603
  187. package/dist/src/plan-tool-middleware.test.js.map +1 -1
  188. package/dist/src/plan-ws-registry.d.ts +4 -0
  189. package/dist/src/plan-ws-registry.d.ts.map +1 -1
  190. package/dist/src/plan-ws-registry.js +12 -0
  191. package/dist/src/plan-ws-registry.js.map +1 -1
  192. package/dist/src/plan-ws-registry.test.js +19 -1
  193. package/dist/src/plan-ws-registry.test.js.map +1 -1
  194. package/dist/src/plugin/types.d.ts +5 -0
  195. package/dist/src/plugin/types.d.ts.map +1 -1
  196. package/dist/src/plugin-dispose.d.ts +22 -0
  197. package/dist/src/plugin-dispose.d.ts.map +1 -0
  198. package/dist/src/plugin-dispose.js +66 -0
  199. package/dist/src/plugin-dispose.js.map +1 -0
  200. package/dist/src/process-shared-store.d.ts +48 -0
  201. package/dist/src/process-shared-store.d.ts.map +1 -0
  202. package/dist/src/process-shared-store.js +89 -0
  203. package/dist/src/process-shared-store.js.map +1 -0
  204. package/dist/src/process-shared-store.test.d.ts +2 -0
  205. package/dist/src/process-shared-store.test.d.ts.map +1 -0
  206. package/dist/src/process-shared-store.test.js +60 -0
  207. package/dist/src/process-shared-store.test.js.map +1 -0
  208. package/dist/src/register-exec-env-hook.d.ts +44 -0
  209. package/dist/src/register-exec-env-hook.d.ts.map +1 -0
  210. package/dist/src/register-exec-env-hook.js +473 -0
  211. package/dist/src/register-exec-env-hook.js.map +1 -0
  212. package/dist/src/register-exec-env-hook.test.d.ts +2 -0
  213. package/dist/src/register-exec-env-hook.test.d.ts.map +1 -0
  214. package/dist/src/register-exec-env-hook.test.js +189 -0
  215. package/dist/src/register-exec-env-hook.test.js.map +1 -0
  216. package/dist/src/register-group-prompt-hook.d.ts +17 -0
  217. package/dist/src/register-group-prompt-hook.d.ts.map +1 -0
  218. package/dist/src/register-group-prompt-hook.js +45 -0
  219. package/dist/src/register-group-prompt-hook.js.map +1 -0
  220. package/dist/src/register-group-prompt-hook.test.d.ts +2 -0
  221. package/dist/src/register-group-prompt-hook.test.d.ts.map +1 -0
  222. package/dist/src/register-group-prompt-hook.test.js +60 -0
  223. package/dist/src/register-group-prompt-hook.test.js.map +1 -0
  224. package/dist/src/register-per-message-model-hook.d.ts +10 -2
  225. package/dist/src/register-per-message-model-hook.d.ts.map +1 -1
  226. package/dist/src/register-per-message-model-hook.js +32 -6
  227. package/dist/src/register-per-message-model-hook.js.map +1 -1
  228. package/dist/src/register-per-message-model-hook.test.d.ts +2 -0
  229. package/dist/src/register-per-message-model-hook.test.d.ts.map +1 -0
  230. package/dist/src/register-per-message-model-hook.test.js +208 -0
  231. package/dist/src/register-per-message-model-hook.test.js.map +1 -0
  232. package/dist/src/register-run-model-context-hook.d.ts +11 -0
  233. package/dist/src/register-run-model-context-hook.d.ts.map +1 -0
  234. package/dist/src/register-run-model-context-hook.js +23 -0
  235. package/dist/src/register-run-model-context-hook.js.map +1 -0
  236. package/dist/src/reply-dispatch-driver.d.ts +89 -0
  237. package/dist/src/reply-dispatch-driver.d.ts.map +1 -0
  238. package/dist/src/reply-dispatch-driver.js +294 -0
  239. package/dist/src/reply-dispatch-driver.js.map +1 -0
  240. package/dist/src/reply-dispatch-driver.test.d.ts +2 -0
  241. package/dist/src/reply-dispatch-driver.test.d.ts.map +1 -0
  242. package/dist/src/reply-dispatch-driver.test.js +363 -0
  243. package/dist/src/reply-dispatch-driver.test.js.map +1 -0
  244. package/dist/src/resolve-inbound-group-prompt.d.ts +17 -1
  245. package/dist/src/resolve-inbound-group-prompt.d.ts.map +1 -1
  246. package/dist/src/resolve-inbound-group-prompt.js +16 -2
  247. package/dist/src/resolve-inbound-group-prompt.js.map +1 -1
  248. package/dist/src/run-model-context.d.ts +45 -0
  249. package/dist/src/run-model-context.d.ts.map +1 -0
  250. package/dist/src/run-model-context.js +108 -0
  251. package/dist/src/run-model-context.js.map +1 -0
  252. package/dist/src/run-model-context.test.d.ts +2 -0
  253. package/dist/src/run-model-context.test.d.ts.map +1 -0
  254. package/dist/src/run-model-context.test.js +68 -0
  255. package/dist/src/run-model-context.test.js.map +1 -0
  256. package/dist/src/run-usage-session.d.ts +4 -1
  257. package/dist/src/run-usage-session.d.ts.map +1 -1
  258. package/dist/src/run-usage-session.js +13 -1
  259. package/dist/src/run-usage-session.js.map +1 -1
  260. package/dist/src/run-usage.d.ts +15 -0
  261. package/dist/src/run-usage.d.ts.map +1 -1
  262. package/dist/src/run-usage.js +30 -4
  263. package/dist/src/run-usage.js.map +1 -1
  264. package/dist/src/run-usage.test.js +99 -11
  265. package/dist/src/run-usage.test.js.map +1 -1
  266. package/dist/src/send-file-tool.d.ts +1 -1
  267. package/dist/src/send-file-tool.d.ts.map +1 -1
  268. package/dist/src/send-group-message-tool.d.ts +1 -1
  269. package/dist/src/send-group-message-tool.d.ts.map +1 -1
  270. package/dist/src/session/build-project-prompt.test.js +18 -18
  271. package/dist/src/session/session-model-fallback.d.ts.map +1 -1
  272. package/dist/src/session/session-model-fallback.js +6 -3
  273. package/dist/src/session/session-model-fallback.js.map +1 -1
  274. package/dist/src/session-env-store.d.ts +55 -0
  275. package/dist/src/session-env-store.d.ts.map +1 -0
  276. package/dist/src/session-env-store.js +328 -0
  277. package/dist/src/session-env-store.js.map +1 -0
  278. package/dist/src/session-env-store.test.d.ts +2 -0
  279. package/dist/src/session-env-store.test.d.ts.map +1 -0
  280. package/dist/src/session-env-store.test.js +151 -0
  281. package/dist/src/session-env-store.test.js.map +1 -0
  282. package/dist/src/session-group-prompt.d.ts +34 -0
  283. package/dist/src/session-group-prompt.d.ts.map +1 -0
  284. package/dist/src/session-group-prompt.js +101 -0
  285. package/dist/src/session-group-prompt.js.map +1 -0
  286. package/dist/src/session-group-prompt.test.d.ts +2 -0
  287. package/dist/src/session-group-prompt.test.d.ts.map +1 -0
  288. package/dist/src/session-group-prompt.test.js +72 -0
  289. package/dist/src/session-group-prompt.test.js.map +1 -0
  290. package/dist/src/session-im-context.d.ts +2 -0
  291. package/dist/src/session-im-context.d.ts.map +1 -1
  292. package/dist/src/session-im-context.js +11 -2
  293. package/dist/src/session-im-context.js.map +1 -1
  294. package/dist/src/session-model-fallback.d.ts +13 -0
  295. package/dist/src/session-model-fallback.d.ts.map +1 -0
  296. package/dist/src/session-model-fallback.js +24 -0
  297. package/dist/src/session-model-fallback.js.map +1 -0
  298. package/dist/src/subagent-monitor.d.ts +14 -1
  299. package/dist/src/subagent-monitor.d.ts.map +1 -1
  300. package/dist/src/subagent-monitor.js +164 -36
  301. package/dist/src/subagent-monitor.js.map +1 -1
  302. package/dist/src/subagent-monitor.test.js +121 -0
  303. package/dist/src/subagent-monitor.test.js.map +1 -1
  304. package/dist/src/tool-event-adapter.d.ts +31 -0
  305. package/dist/src/tool-event-adapter.d.ts.map +1 -0
  306. package/dist/src/tool-event-adapter.js +83 -0
  307. package/dist/src/tool-event-adapter.js.map +1 -0
  308. package/dist/src/tool-event-adapter.test.d.ts +2 -0
  309. package/dist/src/tool-event-adapter.test.d.ts.map +1 -0
  310. package/dist/src/tool-event-adapter.test.js +93 -0
  311. package/dist/src/tool-event-adapter.test.js.map +1 -0
  312. package/dist/src/tool-json-result.d.ts +1 -1
  313. package/dist/src/tool-json-result.d.ts.map +1 -1
  314. package/dist/src/turn/run-usage-session.d.ts +1 -1
  315. package/dist/src/turn/run-usage-session.d.ts.map +1 -1
  316. package/dist/src/turn/run-usage-session.js +7 -4
  317. package/dist/src/turn/run-usage-session.js.map +1 -1
  318. package/dist/src/turn-agent-event-subscription.d.ts +29 -0
  319. package/dist/src/turn-agent-event-subscription.d.ts.map +1 -0
  320. package/dist/src/turn-agent-event-subscription.js +289 -0
  321. package/dist/src/turn-agent-event-subscription.js.map +1 -0
  322. package/dist/src/turn-agent-event-subscription.test.d.ts +2 -0
  323. package/dist/src/turn-agent-event-subscription.test.d.ts.map +1 -0
  324. package/dist/src/turn-agent-event-subscription.test.js +165 -0
  325. package/dist/src/turn-agent-event-subscription.test.js.map +1 -0
  326. package/dist/src/turn-deliver-buffer.test.js +25 -25
  327. package/dist/src/turn-end-controller.d.ts +61 -0
  328. package/dist/src/turn-end-controller.d.ts.map +1 -0
  329. package/dist/src/turn-end-controller.js +239 -0
  330. package/dist/src/turn-end-controller.js.map +1 -0
  331. package/dist/src/turn-end-controller.test.d.ts +2 -0
  332. package/dist/src/turn-end-controller.test.d.ts.map +1 -0
  333. package/dist/src/turn-end-controller.test.js +97 -0
  334. package/dist/src/turn-end-controller.test.js.map +1 -0
  335. package/dist/src/types.d.ts +48 -1
  336. package/dist/src/types.d.ts.map +1 -1
  337. package/dist/src/types.js.map +1 -1
  338. package/dist/src/workspace-event-protocol.d.ts +3 -0
  339. package/dist/src/workspace-event-protocol.d.ts.map +1 -0
  340. package/dist/src/workspace-event-protocol.js +3 -0
  341. package/dist/src/workspace-event-protocol.js.map +1 -0
  342. package/dist/src/workspace-event-scheduler.d.ts +54 -0
  343. package/dist/src/workspace-event-scheduler.d.ts.map +1 -0
  344. package/dist/src/workspace-event-scheduler.js +131 -0
  345. package/dist/src/workspace-event-scheduler.js.map +1 -0
  346. package/dist/src/workspace-event-scheduler.test.d.ts +2 -0
  347. package/dist/src/workspace-event-scheduler.test.d.ts.map +1 -0
  348. package/dist/src/workspace-event-scheduler.test.js +157 -0
  349. package/dist/src/workspace-event-scheduler.test.js.map +1 -0
  350. package/dist/src/workspace-event.d.ts +28 -0
  351. package/dist/src/workspace-event.d.ts.map +1 -0
  352. package/dist/src/workspace-event.js +674 -0
  353. package/dist/src/workspace-event.js.map +1 -0
  354. package/dist/src/workspace-event.test.d.ts +2 -0
  355. package/dist/src/workspace-event.test.d.ts.map +1 -0
  356. package/dist/src/workspace-event.test.js +265 -0
  357. package/dist/src/workspace-event.test.js.map +1 -0
  358. package/dist/src/ws-inbound-schema.d.ts.map +1 -1
  359. package/dist/src/ws-inbound-schema.js +1 -0
  360. package/dist/src/ws-inbound-schema.js.map +1 -1
  361. package/dist/src/ws-inbound-schema.test.d.ts +2 -0
  362. package/dist/src/ws-inbound-schema.test.d.ts.map +1 -0
  363. package/dist/src/ws-inbound-schema.test.js +58 -0
  364. package/dist/src/ws-inbound-schema.test.js.map +1 -0
  365. package/openclaw.plugin.json +30 -30
  366. package/package.json +83 -83
  367. package/dist/src/modified-file-push-tracker.d.ts +0 -24
  368. package/dist/src/modified-file-push-tracker.d.ts.map +0 -1
  369. package/dist/src/modified-file-push-tracker.js +0 -125
  370. package/dist/src/modified-file-push-tracker.js.map +0 -1
  371. package/dist/src/plan/action-dispatch-event-compat.test.d.ts +0 -2
  372. package/dist/src/plan/action-dispatch-event-compat.test.d.ts.map +0 -1
  373. package/dist/src/plan/action-dispatch-event-compat.test.js +0 -81
  374. package/dist/src/plan/action-dispatch-event-compat.test.js.map +0 -1
  375. package/dist/src/plan-store-access.d.ts +0 -23
  376. package/dist/src/plan-store-access.d.ts.map +0 -1
  377. package/dist/src/plan-store-access.js +0 -96
  378. package/dist/src/plan-store-access.js.map +0 -1
  379. package/dist/src/plan-store-access.test.d.ts +0 -2
  380. package/dist/src/plan-store-access.test.d.ts.map +0 -1
  381. package/dist/src/plan-store-access.test.js +0 -207
  382. package/dist/src/plan-store-access.test.js.map +0 -1
  383. package/dist/src/progress-display.d.ts +0 -77
  384. package/dist/src/progress-display.d.ts.map +0 -1
  385. package/dist/src/progress-display.js +0 -420
  386. package/dist/src/progress-display.js.map +0 -1
  387. package/dist/src/subagent-delivery-phase.d.ts +0 -10
  388. package/dist/src/subagent-delivery-phase.d.ts.map +0 -1
  389. package/dist/src/subagent-delivery-phase.js +0 -4
  390. package/dist/src/subagent-delivery-phase.js.map +0 -1
  391. package/dist/src/subagent-delivery-phase.test.d.ts +0 -2
  392. package/dist/src/subagent-delivery-phase.test.d.ts.map +0 -1
  393. package/dist/src/subagent-delivery-phase.test.js +0 -12
  394. package/dist/src/subagent-delivery-phase.test.js.map +0 -1
@@ -0,0 +1,101 @@
1
+ /**
2
+ * 会话级「群背景」缓存(跨回合续轮补注入)。
3
+ *
4
+ * 背景:`GroupSystemPrompt` 由入站 @ 回合构建并注入(`account-connection.ts` → `inboundCtx`),
5
+ * 而 heartbeat / exec 完成唤醒等**自触发回合**没有入站消息,OpenClaw 不会重新注入,
6
+ * 导致 agent 在续轮丢失 `userInfo.background` + `agentContext`(「待办背景未带入」)。
7
+ *
8
+ * 本缓存只保存**动态段**(用户块 + 项目块,见 `resolveInboundGroupPromptParts`),
9
+ * 不含配置里的静态段;最新一轮动态段为空时**清空**,避免把过期背景补进续轮。
10
+ *
11
+ * 过期与容量:TTL + 条目上限双重兜底,防止无界增长;进程级共享,跨热重载存活。
12
+ */
13
+ import { getSharedMap } from "./process-shared-store.js";
14
+ /** 条目上限(防御无界增长)。 */
15
+ const MAX_ENTRIES = 500;
16
+ /**
17
+ * 条目有效期。唤醒轮多为 **exec 完成唤醒**,后台任务时长可达小时级,故取 24h 覆盖长任务;
18
+ * 内存由 `MAX_ENTRIES` 兜底,TTL 只负责防陈旧(下一次被 @ 的入站轮会覆盖或清空)。
19
+ */
20
+ const TTL_MS = 24 * 60 * 60 * 1000;
21
+ const bySessionKey = getSharedMap("session-group-prompt");
22
+ function nonEmpty(value) {
23
+ if (typeof value !== "string")
24
+ return undefined;
25
+ const text = value.trim();
26
+ return text.length > 0 ? text : undefined;
27
+ }
28
+ function pruneExpired(now) {
29
+ for (const [key, entry] of bySessionKey) {
30
+ if (now - entry.updatedAt > TTL_MS) {
31
+ bySessionKey.delete(key);
32
+ }
33
+ }
34
+ }
35
+ function evictOldestIfOverCapacity() {
36
+ if (bySessionKey.size < MAX_ENTRIES)
37
+ return;
38
+ let oldestKey;
39
+ let oldestAt = Number.POSITIVE_INFINITY;
40
+ for (const [key, entry] of bySessionKey) {
41
+ if (entry.updatedAt < oldestAt) {
42
+ oldestAt = entry.updatedAt;
43
+ oldestKey = key;
44
+ }
45
+ }
46
+ if (oldestKey !== undefined) {
47
+ bySessionKey.delete(oldestKey);
48
+ }
49
+ }
50
+ /**
51
+ * 记录一次入站构建的群背景动态段。
52
+ *
53
+ * - `prompt` 非空 → 覆盖写入并刷新 `updatedAt`;
54
+ * - `prompt` 为空 / undefined → **删除该会话缓存**(最新一轮没有背景,续轮不得复用旧背景)。
55
+ */
56
+ export function setSessionGroupPrompt(sessionKey, prompt) {
57
+ const key = nonEmpty(sessionKey);
58
+ if (!key)
59
+ return;
60
+ const text = nonEmpty(prompt);
61
+ if (!text) {
62
+ bySessionKey.delete(key);
63
+ return;
64
+ }
65
+ const now = Date.now();
66
+ pruneExpired(now);
67
+ if (!bySessionKey.has(key)) {
68
+ evictOldestIfOverCapacity();
69
+ }
70
+ bySessionKey.set(key, { prompt: text, updatedAt: now });
71
+ }
72
+ /** 读取某会话最近一次入站构建的群背景动态段(过期返回 undefined)。 */
73
+ export function getSessionGroupPrompt(sessionKey) {
74
+ const key = nonEmpty(sessionKey);
75
+ if (!key)
76
+ return undefined;
77
+ const entry = bySessionKey.get(key);
78
+ if (!entry)
79
+ return undefined;
80
+ if (Date.now() - entry.updatedAt > TTL_MS) {
81
+ bySessionKey.delete(key);
82
+ return undefined;
83
+ }
84
+ return entry.prompt;
85
+ }
86
+ /** 清除某会话的群背景缓存。 */
87
+ export function clearSessionGroupPrompt(sessionKey) {
88
+ const key = nonEmpty(sessionKey);
89
+ if (!key)
90
+ return;
91
+ bySessionKey.delete(key);
92
+ }
93
+ /** 插件卸载/重载时清空全部缓存。 */
94
+ export function clearAllSessionGroupPrompts() {
95
+ bySessionKey.clear();
96
+ }
97
+ /** 仅供测试:内部条目数。 */
98
+ export function __sessionGroupPromptSizeForTests() {
99
+ return bySessionKey.size;
100
+ }
101
+ //# sourceMappingURL=session-group-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-group-prompt.js","sourceRoot":"","sources":["../../src/session-group-prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-group-prompt.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-group-prompt.test.d.ts","sourceRoot":"","sources":["../../src/session-group-prompt.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ import assert from "node:assert/strict";
2
+ import { beforeEach, describe, it } from "node:test";
3
+ import { __sessionGroupPromptSizeForTests, clearAllSessionGroupPrompts, clearSessionGroupPrompt, getSessionGroupPrompt, setSessionGroupPrompt, } from "./session-group-prompt.js";
4
+ const TTL_MS = 24 * 60 * 60 * 1000;
5
+ const MAX_ENTRIES = 500;
6
+ describe("session-group-prompt", () => {
7
+ beforeEach(() => {
8
+ clearAllSessionGroupPrompts();
9
+ });
10
+ it("records and reads the dynamic group prompt per session", () => {
11
+ setSessionGroupPrompt("session-1", "## 当前用户\n\n发送者:张三");
12
+ assert.equal(getSessionGroupPrompt("session-1"), "## 当前用户\n\n发送者:张三");
13
+ });
14
+ it("overwrites the previous entry for the same session", () => {
15
+ setSessionGroupPrompt("session-1", "first");
16
+ setSessionGroupPrompt("session-1", "second");
17
+ assert.equal(getSessionGroupPrompt("session-1"), "second");
18
+ assert.equal(__sessionGroupPromptSizeForTests(), 1);
19
+ });
20
+ it("clears the cache when the latest turn has no dynamic prompt", () => {
21
+ setSessionGroupPrompt("session-1", "stale-background");
22
+ setSessionGroupPrompt("session-1", undefined);
23
+ assert.equal(getSessionGroupPrompt("session-1"), undefined);
24
+ assert.equal(__sessionGroupPromptSizeForTests(), 0);
25
+ setSessionGroupPrompt("session-1", "stale-background");
26
+ setSessionGroupPrompt("session-1", " ");
27
+ assert.equal(getSessionGroupPrompt("session-1"), undefined);
28
+ assert.equal(__sessionGroupPromptSizeForTests(), 0);
29
+ });
30
+ it("trims whitespace around the stored prompt", () => {
31
+ setSessionGroupPrompt("session-1", " bg ");
32
+ assert.equal(getSessionGroupPrompt("session-1"), "bg");
33
+ });
34
+ it("isolates sessions and ignores empty session keys", () => {
35
+ setSessionGroupPrompt("session-1", "a");
36
+ setSessionGroupPrompt("session-2", "b");
37
+ assert.equal(getSessionGroupPrompt("session-1"), "a");
38
+ assert.equal(getSessionGroupPrompt("session-2"), "b");
39
+ assert.equal(getSessionGroupPrompt("session-3"), undefined);
40
+ setSessionGroupPrompt("", "ignored");
41
+ setSessionGroupPrompt(undefined, "ignored");
42
+ assert.equal(__sessionGroupPromptSizeForTests(), 2);
43
+ });
44
+ it("expires entries past the TTL", (t) => {
45
+ t.mock.timers.enable({ apis: ["Date"], now: 1_000_000 });
46
+ setSessionGroupPrompt("session-1", "bg");
47
+ assert.equal(getSessionGroupPrompt("session-1"), "bg");
48
+ t.mock.timers.tick(TTL_MS);
49
+ assert.equal(getSessionGroupPrompt("session-1"), "bg");
50
+ t.mock.timers.tick(1);
51
+ assert.equal(getSessionGroupPrompt("session-1"), undefined);
52
+ assert.equal(__sessionGroupPromptSizeForTests(), 0);
53
+ });
54
+ it("evicts the oldest entry instead of growing past MAX_ENTRIES", () => {
55
+ for (let i = 0; i < MAX_ENTRIES; i++) {
56
+ setSessionGroupPrompt(`session-${i}`, `bg-${i}`);
57
+ }
58
+ assert.equal(__sessionGroupPromptSizeForTests(), MAX_ENTRIES);
59
+ setSessionGroupPrompt("session-new", "bg-new");
60
+ assert.equal(__sessionGroupPromptSizeForTests(), MAX_ENTRIES);
61
+ assert.equal(getSessionGroupPrompt("session-0"), undefined);
62
+ assert.equal(getSessionGroupPrompt("session-new"), "bg-new");
63
+ });
64
+ it("clearSessionGroupPrompt removes a single session", () => {
65
+ setSessionGroupPrompt("session-1", "a");
66
+ setSessionGroupPrompt("session-2", "b");
67
+ clearSessionGroupPrompt("session-1");
68
+ assert.equal(getSessionGroupPrompt("session-1"), undefined);
69
+ assert.equal(getSessionGroupPrompt("session-2"), "b");
70
+ });
71
+ });
72
+ //# sourceMappingURL=session-group-prompt.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-group-prompt.test.js","sourceRoot":"","sources":["../../src/session-group-prompt.test.ts"],"names":[],"mappings":"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"}
@@ -10,4 +10,6 @@ export declare function getSessionImContext(sessionKey: string): {
10
10
  } | undefined;
11
11
  export declare function clearSessionImContext(sessionKey: string, expectedReplyToMsgId?: string): boolean;
12
12
  export declare function touchSessionImContext(sessionKey: string): void;
13
+ /** 插件卸载/重载时清空会话 IM 上下文与全部清理定时器。 */
14
+ export declare function disposeSessionImContext(): void;
13
15
  //# sourceMappingURL=session-im-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-im-context.d.ts","sourceRoot":"","sources":["../../src/session-im-context.ts"],"names":[],"mappings":"AA6BA,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC9D,IAAI,CAGN;AAED,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,GACjB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAOxE;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,OAAO,CAQhG;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAK9D"}
1
+ {"version":3,"file":"session-im-context.d.ts","sourceRoot":"","sources":["../../src/session-im-context.ts"],"names":[],"mappings":"AAkCA,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC9D,IAAI,CAGN;AAED,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,GACjB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAOxE;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,OAAO,CAQhG;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAK9D;AAED,mCAAmC;AACnC,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C"}
@@ -1,5 +1,6 @@
1
- const sessionCtxMap = new Map();
2
- const cleanupTimers = new Map();
1
+ import { getSharedMap } from "./process-shared-store.js";
2
+ const sessionCtxMap = getSharedMap("session-im-context");
3
+ const cleanupTimers = getSharedMap("session-im-context-timers");
3
4
  const CLEANUP_DELAY_MS = 60 * 60 * 1000;
4
5
  function clearCleanupTimer(sessionKey) {
5
6
  const t = cleanupTimers.get(sessionKey);
@@ -42,4 +43,12 @@ export function touchSessionImContext(sessionKey) {
42
43
  scheduleCleanup(sessionKey);
43
44
  }
44
45
  }
46
+ /** 插件卸载/重载时清空会话 IM 上下文与全部清理定时器。 */
47
+ export function disposeSessionImContext() {
48
+ for (const timer of cleanupTimers.values()) {
49
+ clearTimeout(timer);
50
+ }
51
+ cleanupTimers.clear();
52
+ sessionCtxMap.clear();
53
+ }
45
54
  //# sourceMappingURL=session-im-context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-im-context.js","sourceRoot":"","sources":["../../src/session-im-context.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GAAG,IAAI,GAAG,EAIzB,CAAA;AAEJ,MAAM,aAAa,GAAG,IAAI,GAAG,EAAyC,CAAA;AAEtE,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAEvC,SAAS,iBAAiB,CAAC,UAAkB;IAC3C,MAAM,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACvC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;QACpB,YAAY,CAAC,CAAC,CAAC,CAAA;QACf,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAClC,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,UAAkB;IACzC,iBAAiB,CAAC,UAAU,CAAC,CAAA;IAC7B,aAAa,CAAC,GAAG,CACf,UAAU,EACV,UAAU,CAAC,GAAG,EAAE;QACd,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAChC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAClC,CAAC,EAAE,gBAAgB,CAAC,CAAC,KAAK,EAAE,EAAE,CAC/B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,UAAkB,EAClB,GAA+D;IAE/D,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;IAClC,eAAe,CAAC,UAAU,CAAC,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,UAAkB;IAElB,IAAI,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,iBAAiB,CAAC,UAAU,CAAC,CAAA;QAC7B,eAAe,CAAC,UAAU,CAAC,CAAA;QAC3B,OAAO,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACtC,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,UAAkB,EAAE,oBAA6B;IACrF,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAC7C,IAAI,CAAC,OAAO,IAAI,CAAC,oBAAoB,IAAI,OAAO,CAAC,YAAY,KAAK,oBAAoB,CAAC,EAAE,CAAC;QACxF,OAAO,KAAK,CAAA;IACd,CAAC;IACD,iBAAiB,CAAC,UAAU,CAAC,CAAA;IAC7B,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAChC,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,UAAkB;IACtD,IAAI,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,iBAAiB,CAAC,UAAU,CAAC,CAAA;QAC7B,eAAe,CAAC,UAAU,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"session-im-context.js","sourceRoot":"","sources":["../../src/session-im-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,aAAa,GAAG,YAAY,CAOhC,oBAAoB,CAAC,CAAC;AAExB,MAAM,aAAa,GAAG,YAAY,CAAwC,2BAA2B,CAAC,CAAC;AAEvG,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAEvC,SAAS,iBAAiB,CAAC,UAAkB;IAC3C,MAAM,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACvC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;QACpB,YAAY,CAAC,CAAC,CAAC,CAAA;QACf,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAClC,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,UAAkB;IACzC,iBAAiB,CAAC,UAAU,CAAC,CAAA;IAC7B,aAAa,CAAC,GAAG,CACf,UAAU,EACV,UAAU,CAAC,GAAG,EAAE;QACd,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAChC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAClC,CAAC,EAAE,gBAAgB,CAAC,CAAC,KAAK,EAAE,EAAE,CAC/B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,UAAkB,EAClB,GAA+D;IAE/D,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;IAClC,eAAe,CAAC,UAAU,CAAC,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,UAAkB;IAElB,IAAI,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,iBAAiB,CAAC,UAAU,CAAC,CAAA;QAC7B,eAAe,CAAC,UAAU,CAAC,CAAA;QAC3B,OAAO,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACtC,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,UAAkB,EAAE,oBAA6B;IACrF,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAC7C,IAAI,CAAC,OAAO,IAAI,CAAC,oBAAoB,IAAI,OAAO,CAAC,YAAY,KAAK,oBAAoB,CAAC,EAAE,CAAC;QACxF,OAAO,KAAK,CAAA;IACd,CAAC;IACD,iBAAiB,CAAC,UAAU,CAAC,CAAA;IAC7B,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAChC,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,UAAkB;IACtD,IAAI,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,iBAAiB,CAAC,UAAU,CAAC,CAAA;QAC7B,eAAe,CAAC,UAAU,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,uBAAuB;IACrC,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;QAC3C,YAAY,CAAC,KAAK,CAAC,CAAA;IACrB,CAAC;IACD,aAAa,CAAC,KAAK,EAAE,CAAA;IACrB,aAAa,CAAC,KAAK,EAAE,CAAA;AACvB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 读取 session store 中的自动降级上下文,供单轮模型覆盖的守卫判定使用。
3
+ *
4
+ * OpenClaw 在自动降级时会把 `modelOverrideSource: "auto"` 与
5
+ * `modelOverrideFallbackOriginProvider/Model`(被跳过的原模型)写入 session entry。
6
+ * 入站时读取一次即可判断「用户点名的模型是否就是冷却中的降级来源」。
7
+ */
8
+ import { type SessionModelFallbackContext } from "./per-message-model-pending.js";
9
+ export declare function resolveSessionModelFallbackContext(args: {
10
+ storePath: string;
11
+ sessionKey: string;
12
+ }): SessionModelFallbackContext;
13
+ //# sourceMappingURL=session-model-fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-model-fallback.d.ts","sourceRoot":"","sources":["../../src/session-model-fallback.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAEH,KAAK,2BAA2B,EACnC,MAAM,gCAAgC,CAAC;AAExC,wBAAgB,kCAAkC,CAAC,IAAI,EAAE;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACtB,GAAG,2BAA2B,CAW9B"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 读取 session store 中的自动降级上下文,供单轮模型覆盖的守卫判定使用。
3
+ *
4
+ * OpenClaw 在自动降级时会把 `modelOverrideSource: "auto"` 与
5
+ * `modelOverrideFallbackOriginProvider/Model`(被跳过的原模型)写入 session entry。
6
+ * 入站时读取一次即可判断「用户点名的模型是否就是冷却中的降级来源」。
7
+ */
8
+ import { loadSessionStore, resolveSessionStoreEntry, } from "openclaw/plugin-sdk/session-store-runtime";
9
+ import { resolveSessionFallbackContextFromEntry, } from "./per-message-model-pending.js";
10
+ export function resolveSessionModelFallbackContext(args) {
11
+ const storePath = args.storePath?.trim();
12
+ const sessionKey = args.sessionKey?.trim();
13
+ if (!storePath || !sessionKey)
14
+ return { sessionInAutoFallback: false };
15
+ try {
16
+ const store = loadSessionStore(storePath, { skipCache: true });
17
+ const { existing } = resolveSessionStoreEntry({ store, sessionKey });
18
+ return resolveSessionFallbackContextFromEntry(existing);
19
+ }
20
+ catch {
21
+ return { sessionInAutoFallback: false };
22
+ }
23
+ }
24
+ //# sourceMappingURL=session-model-fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-model-fallback.js","sourceRoot":"","sources":["../../src/session-model-fallback.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACH,gBAAgB,EAChB,wBAAwB,GAC3B,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACH,sCAAsC,GAEzC,MAAM,gCAAgC,CAAC;AAExC,MAAM,UAAU,kCAAkC,CAAC,IAGlD;IACG,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC;IACvE,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,MAAM,EAAE,QAAQ,EAAE,GAAG,wBAAwB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACrE,OAAO,sCAAsC,CAAC,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;AACL,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
1
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/channel-plugin-common";
2
2
  import type { ImStreamClient } from "./connection.js";
3
3
  interface SubagentSpawnInfo {
4
4
  childSessionKey: string;
@@ -23,10 +23,23 @@ export declare function startMonitor(params: {
23
23
  spawn: SubagentSpawnInfo;
24
24
  }): boolean;
25
25
  export declare function hasActiveSubagents(roundKey: string, generation: number): boolean;
26
+ /** 子任务结束事件定位其所属轮次(供 turn-end-controller 递减活跃子任务数)。 */
27
+ export declare function findChildRoundIndex(childSessionKey: string): {
28
+ roundKey: string;
29
+ generation: number;
30
+ runId: string;
31
+ } | undefined;
26
32
  export declare function deferFinished(roundKey: string, generation: number, reason: string): void;
27
33
  export declare function prepareSubagentInterrupt(roundKey: string, generation: number, now?: number): InterruptedSubagent[];
28
34
  export declare function markSubagentCompleted(childSessionKey: string, runId?: string): void;
35
+ /**
36
+ * 整轮收尾时(dispatch wrapper 在 turn-end-controller 放行后)清理本轮监控。
37
+ * 与 removeMonitor 的 settle 路径不同:此处轮次真正结束,直接拆监控与子任务索引。
38
+ */
39
+ export declare function finalizeRoundMonitoring(roundKey: string, generation: number): void;
29
40
  export declare function __tickForTests(): Promise<void>;
30
41
  export declare function __resetSubagentMonitorForTests(): void;
42
+ /** 插件卸载/重载时停掉 subagent-monitor 的全部轮询与状态,避免旧实例 ticker 泄漏。 */
43
+ export declare function disposeSubagentMonitor(): void;
31
44
  export {};
32
45
  //# sourceMappingURL=subagent-monitor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"subagent-monitor.d.ts","sourceRoot":"","sources":["../../src/subagent-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,UAAU,iBAAiB;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAqBD,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,GAAG,WAAW,CAAC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAwBD,wBAAgB,YAAY,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAGzD;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAsCD,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,cAAc,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;CAC5B,GAAG,OAAO,CAsDV;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAOhF;AAED,wBAAgB,aAAa,CACzB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACf,IAAI,CAEN;AAED,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,GAAG,SAAa,GACjB,mBAAmB,EAAE,CAoBvB;AAED,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CA+CnF;AA0KD,wBAAgB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAE9C;AAED,wBAAgB,8BAA8B,IAAI,IAAI,CASrD"}
1
+ {"version":3,"file":"subagent-monitor.d.ts","sourceRoot":"","sources":["../../src/subagent-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAGnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,UAAU,iBAAiB;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AA4BD,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,GAAG,WAAW,CAAC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAkDD,wBAAgB,YAAY,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAsCzD;AA+CD,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAsCD,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,cAAc,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;CAC5B,GAAG,OAAO,CAsDV;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAOhF;AAED,sDAAsD;AACtD,wBAAgB,mBAAmB,CAC/B,eAAe,EAAE,MAAM,GACxB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAErE;AAED,wBAAgB,aAAa,CACzB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACf,IAAI,CAEN;AAED,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,GAAG,SAAa,GACjB,mBAAmB,EAAE,CAoBvB;AAED,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CA+CnF;AA4BD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAIlF;AAsKD,wBAAgB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAE9C;AAED,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAED,4DAA4D;AAC5D,wBAAgB,sBAAsB,IAAI,IAAI,CAW7C"}
@@ -1,25 +1,112 @@
1
- import { completeActiveRound } from "./active-round-registry.js";
1
+ import { getOrCreateShared, getSharedMap } from "./process-shared-store.js";
2
+ import { turnOnAllChildrenDone } from "./turn-end-controller.js";
2
3
  /** 模块实例 ID:用于确认插件是否被重复加载(若日志出现两个不同 id,则存在双实例,spawn/end 可能被不同实例处理)。 */
3
4
  const MODULE_INSTANCE_ID = `m${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
4
- console.log(`[subagent-monitor] module loaded instance=${MODULE_INSTANCE_ID}`);
5
- const childToRound = new Map();
6
- const roundMonitors = new Map();
7
- const deferredFinished = new Map();
8
- const roundAdmissionTombstones = new Map();
5
+ console.log(`[subagent-monitor] module loaded instance=${MODULE_INSTANCE_ID} pid=${process.pid} title=${(process.title || "(none)").trim()}`);
6
+ // 进程级共享:跨模块重载后监控不中断——各代模块读写同一份 maps/轮询/api 候选。
7
+ const childToRound = getSharedMap("subagent-child-to-round");
8
+ const roundMonitors = getSharedMap("subagent-round-monitors");
9
+ const deferredFinished = getSharedMap("subagent-deferred-finished");
10
+ const roundAdmissionTombstones = getSharedMap("subagent-round-admission-tombstones");
9
11
  /** 记录被 `/stop` 中断的 subagent run(按 childSessionKey 索引,存被中断 runId 与过期时间)。 */
10
- const childTombstones = new Map();
12
+ const childTombstones = getSharedMap("subagent-child-tombstones");
11
13
  const POLL_INTERVAL_MS = 15_000;
14
+ /**
15
+ * apiCandidates 保留上限:OpenClaw 会对同一模块反复重注册(多代 registry 并存且从不触发
16
+ * cleanup,见日志 `registerSeq` 递增而 `cleanup` 为 0)。每代 register 都会 push 一个新 api 进
17
+ * 进程级 candidates,若不停老代则数组无限增长、引用无法回收。该数组仅作为「当前 runtime 探测
18
+ * 不可用时的回退池」(resolveUsablePluginApi),而单进程内 register 是按时间顺序的短爆发(通常
19
+ * 2~4 次),功能上只需最近几代即可,故截断更早的候选。
20
+ */
21
+ const MAX_API_CANDIDATES = 4;
12
22
  const ROUND_TOMBSTONE_TTL_MS = 30_000;
13
23
  const CHILD_TOMBSTONE_TTL_MS = 5 * 60_000;
14
24
  const MAX_INCR_MSGS = 5;
15
25
  const MSG_TRUNCATE_LEN = 40;
16
26
  /** 单次 tick 用 openclaw `agent.wait` 对账 subagent run 状态的探测超时。 */
17
27
  const RUN_STATUS_PROBE_TIMEOUT_MS = 1_000;
18
- let tickerTimer = null;
19
- let pluginApi = null;
28
+ const m = getOrCreateShared("subagent-monitor-runtime", () => ({
29
+ api: null,
30
+ apiCandidates: [],
31
+ apiProbe: "unverified",
32
+ ticker: null,
33
+ }));
20
34
  export function setPluginApi(api) {
21
- pluginApi = api;
22
- console.log(`[subagent-monitor] setPluginApi instance=${MODULE_INSTANCE_ID}`);
35
+ const isNewCandidate = api !== m.api && !m.apiCandidates.includes(api);
36
+ if (isNewCandidate) {
37
+ m.apiCandidates.push(api);
38
+ if (m.apiCandidates.length > MAX_API_CANDIDATES) {
39
+ m.apiCandidates.splice(0, m.apiCandidates.length - MAX_API_CANDIDATES);
40
+ }
41
+ }
42
+ if (m.api === null) {
43
+ m.api = api;
44
+ m.apiProbe = "unverified";
45
+ console.log(`[subagent-monitor] setPluginApi instance=${MODULE_INSTANCE_ID} adopt=first`);
46
+ return;
47
+ }
48
+ if (m.apiProbe === "good") {
49
+ // 已有确认可用的 runtime:拒绝未验证的新 runtime 覆盖,防止无绑定 registry 劫持监控。
50
+ if (isNewCandidate) {
51
+ console.warn(`[subagent-monitor] setPluginApi instance=${MODULE_INSTANCE_ID} keep=verified ` +
52
+ `candidates=${m.apiCandidates.length}`);
53
+ }
54
+ return;
55
+ }
56
+ if (m.apiProbe === "unverified") {
57
+ // 当前尚未探测:不切换,等首次 tick 探测出结果再决定。
58
+ console.log(`[subagent-monitor] setPluginApi instance=${MODULE_INSTANCE_ID} keep=unverified ` +
59
+ `candidates=${m.apiCandidates.length}`);
60
+ return;
61
+ }
62
+ // 当前已确认为不可用:采纳新候选重新探测。
63
+ m.api = api;
64
+ m.apiProbe = "unverified";
65
+ console.log(`[subagent-monitor] setPluginApi instance=${MODULE_INSTANCE_ID} adopt=switch candidates=${m.apiCandidates.length}`);
66
+ }
67
+ function isRequestScopedSubagentError(err) {
68
+ return err instanceof Error && err.name === "RequestScopedSubagentRuntimeError";
69
+ }
70
+ /**
71
+ * 探测某个 plugin api 的 runtime.subagent 是否可用。
72
+ * RequestScopedSubagentRuntimeError = 绑定不可用(无绑定 registry / 非 gateway 上下文);
73
+ * 其它结果(如 runId 不存在返回 error/timeout)说明绑定存在、dispatch 通了,视为可用。
74
+ */
75
+ async function probeApiUsable(api) {
76
+ try {
77
+ await api.runtime.subagent.waitForRun({ runId: "probe", timeoutMs: 1 });
78
+ return true;
79
+ }
80
+ catch (err) {
81
+ return !isRequestScopedSubagentError(err);
82
+ }
83
+ }
84
+ /**
85
+ * 确认当前 m.api 可用;若不可用,尝试从候选里切回可用的 runtime。
86
+ * 返回最终使用的 m.api(所有候选都不可用时仍返回当前,由事件路径兜底)。
87
+ */
88
+ async function resolveUsablePluginApi() {
89
+ if (!m.api)
90
+ return null;
91
+ if (m.apiProbe === "good")
92
+ return m.api;
93
+ if (await probeApiUsable(m.api)) {
94
+ m.apiProbe = "good";
95
+ return m.api;
96
+ }
97
+ for (const candidate of m.apiCandidates) {
98
+ if (candidate === m.api)
99
+ continue;
100
+ if (await probeApiUsable(candidate)) {
101
+ console.warn(`[subagent-monitor] m.api switch instance=${MODULE_INSTANCE_ID} ` +
102
+ `candidates=${m.apiCandidates.length}`);
103
+ m.api = candidate;
104
+ m.apiProbe = "good";
105
+ return m.api;
106
+ }
107
+ }
108
+ m.apiProbe = "bad";
109
+ return m.api;
23
110
  }
24
111
  export function getSubagentMonitorInstanceId() {
25
112
  return MODULE_INSTANCE_ID;
@@ -35,9 +122,9 @@ function pruneTombstones(now = Date.now()) {
35
122
  }
36
123
  }
37
124
  function stopTickerIfIdle() {
38
- if (roundMonitors.size === 0 && tickerTimer) {
39
- clearInterval(tickerTimer);
40
- tickerTimer = null;
125
+ if (roundMonitors.size === 0 && m.ticker) {
126
+ clearInterval(m.ticker);
127
+ m.ticker = null;
41
128
  }
42
129
  }
43
130
  function removeMonitor(monitor, reason) {
@@ -110,6 +197,10 @@ export function hasActiveSubagents(roundKey, generation) {
110
197
  monitor.generation === generation &&
111
198
  Array.from(monitor.subagents.values()).some((record) => !record.completed));
112
199
  }
200
+ /** 子任务结束事件定位其所属轮次(供 turn-end-controller 递减活跃子任务数)。 */
201
+ export function findChildRoundIndex(childSessionKey) {
202
+ return childToRound.get(childSessionKey);
203
+ }
113
204
  export function deferFinished(roundKey, generation, reason) {
114
205
  deferredFinished.set(roundKey, { reason, generation });
115
206
  }
@@ -183,33 +274,46 @@ async function settleMonitorIfComplete(monitor) {
183
274
  return;
184
275
  if (!Array.from(monitor.subagents.values()).every((record) => record.completed))
185
276
  return;
186
- const deferred = deferredFinished.get(monitor.roundKey);
187
- const shouldCompleteRound = deferred?.generation === monitor.generation;
277
+ const signature = statSignature(monitor);
278
+ if (signature === monitor.lastPushedSignature)
279
+ return;
280
+ // 整轮收尾(WS FINISHED + RUN_USAGE + completeActiveRound)改由 turn-end-controller 在
281
+ // 主会话出现非 yield 段终态(或静默兜底)后,由 dispatch wrapper 统一执行;
282
+ // 这里只负责推送 SUBAGENT_STAT 快照,绝不自行 end/remove/complete ——
283
+ // OpenClaw 7.1+/8.x 中「所有已知子任务完成」不代表整轮结束(主会话可能 resume
284
+ // 继续派发新一批子任务),因此本快照允许多波次多次推送,仅对完全相同的状态去重。
188
285
  try {
189
286
  await sendFinalStat(monitor, monitor.streamClient);
190
- if (shouldCompleteRound && deferred) {
191
- await monitor.streamClient.end(deferred.reason, {
192
- groupId: monitor.groupId,
193
- replyToMsgId: monitor.replyToMsgId,
194
- });
287
+ for (const record of monitor.subagents.values()) {
288
+ record.sendFrom = record.messages.length;
195
289
  }
290
+ monitor.lastPushedSignature = signature;
291
+ console.log(`[subagent-monitor] final SUBAGENT_STAT sent (settle) roundKey=${monitor.roundKey} gen=${monitor.generation} ` +
292
+ `subagents=${Array.from(monitor.subagents.values()).length} — waiting turn-end for FINISHED`);
196
293
  }
197
294
  catch (err) {
198
295
  console.error(`[subagent-monitor] final state send failed: ${String(err)}`);
199
296
  }
200
- removeMonitor(monitor, "settle");
201
- if (shouldCompleteRound) {
202
- completeActiveRound(monitor.roundKey, monitor.generation);
203
- }
297
+ turnOnAllChildrenDone(monitor.roundKey, monitor.generation);
298
+ }
299
+ /**
300
+ * 整轮收尾时(dispatch wrapper 在 turn-end-controller 放行后)清理本轮监控。
301
+ * 与 removeMonitor 的 settle 路径不同:此处轮次真正结束,直接拆监控与子任务索引。
302
+ */
303
+ export function finalizeRoundMonitoring(roundKey, generation) {
304
+ const monitor = roundMonitors.get(roundKey);
305
+ if (!monitor || monitor.generation !== generation)
306
+ return;
307
+ removeMonitor(monitor, "round-finished");
204
308
  }
205
309
  async function readSubagentMessages(record) {
206
- if (!pluginApi || record.reading)
310
+ if (!m.api || record.reading)
207
311
  return;
208
312
  record.reading = true;
209
313
  try {
210
314
  let messages = [];
211
315
  try {
212
- const result = await pluginApi.runtime.subagent.getSessionMessages({
316
+ const result = await m.api.runtime.subagent.getSessionMessages({
213
317
  sessionKey: record.childSessionKey,
214
318
  });
215
319
  messages = Array.isArray(result.messages) ? result.messages : [];
@@ -232,10 +336,10 @@ async function readSubagentMessages(record) {
232
336
  * 探测失败(如 runId 已不存在、状态码异常)保守按「仍在运行」处理,交给事件路径兜底。
233
337
  */
234
338
  async function probeRunStatus(record) {
235
- if (!pluginApi)
339
+ if (!m.api)
236
340
  return false;
237
341
  try {
238
- const result = await pluginApi.runtime.subagent.waitForRun({
342
+ const result = await m.api.runtime.subagent.waitForRun({
239
343
  runId: record.runId,
240
344
  timeoutMs: RUN_STATUS_PROBE_TIMEOUT_MS,
241
345
  });
@@ -247,17 +351,19 @@ async function probeRunStatus(record) {
247
351
  }
248
352
  }
249
353
  function ensureTickerRunning() {
250
- if (tickerTimer)
354
+ if (m.ticker)
251
355
  return;
252
356
  void tick();
253
- tickerTimer = setInterval(() => void tick(), POLL_INTERVAL_MS);
254
- tickerTimer.unref?.();
357
+ m.ticker = setInterval(() => void tick(), POLL_INTERVAL_MS);
358
+ m.ticker.unref?.();
255
359
  }
256
360
  async function tick() {
257
361
  if (roundMonitors.size === 0) {
258
362
  stopTickerIfIdle();
259
363
  return;
260
364
  }
365
+ // 确保使用可用的 runtime:探测并必要时切回候选中的可用 api,避免坏 runtime 继续抛 RequestScoped。
366
+ await resolveUsablePluginApi();
261
367
  for (const monitor of Array.from(roundMonitors.values())) {
262
368
  try {
263
369
  const runningRecords = Array.from(monitor.subagents.values()).filter((record) => !record.completed);
@@ -325,7 +431,22 @@ function toSubagentList(monitor, incremental) {
325
431
  : record.messages,
326
432
  }));
327
433
  }
434
+ /**
435
+ * 客户端可见状态的稳定签名:新增子任务、状态翻转(running→completed)或消息数变化都会改变。
436
+ * 仅凭它做「无变化不重复推送」的去重;同一轮多波次派发不会被锁死。
437
+ */
438
+ function statSignature(monitor) {
439
+ return Array.from(monitor.subagents.values())
440
+ .map((r) => `${r.runId}:${r.completed ? "completed" : "running"}:${r.messages.length}`)
441
+ .join("|");
442
+ }
328
443
  function sendWsStat(monitor, client) {
444
+ const signature = statSignature(monitor);
445
+ // 有 running 子任务时保持逐 tick 推送(running/新增消息语义不变);
446
+ // 全部已完成且状态无变化(等 turn-end 的空窗)则去重,避免 tick 刷同一份完成快照。
447
+ const hasRunning = Array.from(monitor.subagents.values()).some((r) => !r.completed);
448
+ if (!hasRunning && signature === monitor.lastPushedSignature)
449
+ return;
329
450
  const subagentList = toSubagentList(monitor, true);
330
451
  client
331
452
  .sendEvent({
@@ -340,6 +461,7 @@ function sendWsStat(monitor, client) {
340
461
  if (record)
341
462
  record.sendFrom += item.messages.length;
342
463
  });
464
+ monitor.lastPushedSignature = signature;
343
465
  })
344
466
  .catch((err) => {
345
467
  console.error(`[subagent-monitor] SUBAGENT_STAT failed: ${String(err)}`);
@@ -357,10 +479,16 @@ export function __tickForTests() {
357
479
  return tick();
358
480
  }
359
481
  export function __resetSubagentMonitorForTests() {
360
- if (tickerTimer)
361
- clearInterval(tickerTimer);
362
- tickerTimer = null;
363
- pluginApi = null;
482
+ disposeSubagentMonitor();
483
+ }
484
+ /** 插件卸载/重载时停掉 subagent-monitor 的全部轮询与状态,避免旧实例 ticker 泄漏。 */
485
+ export function disposeSubagentMonitor() {
486
+ if (m.ticker)
487
+ clearInterval(m.ticker);
488
+ m.ticker = null;
489
+ m.api = null;
490
+ m.apiProbe = "unverified";
491
+ m.apiCandidates.length = 0;
364
492
  childToRound.clear();
365
493
  roundMonitors.clear();
366
494
  deferredFinished.clear();