@0xmaxma/claude-gateway 1.8.13 → 2.0.0

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 (594) hide show
  1. package/README.md +28 -1605
  2. package/config.template.json +7 -1
  3. package/dist/agent/runner.d.ts +394 -0
  4. package/dist/agent/runner.d.ts.map +1 -1
  5. package/dist/agent/runner.js +867 -38
  6. package/dist/agent/runner.js.map +1 -1
  7. package/dist/agent/skill-learning/index.d.ts +6 -4
  8. package/dist/agent/skill-learning/index.d.ts.map +1 -1
  9. package/dist/agent/skill-learning/index.js +3 -3
  10. package/dist/agent/skill-learning/index.js.map +1 -1
  11. package/dist/agent/skill-learning/notifier.d.ts +3 -4
  12. package/dist/agent/skill-learning/notifier.d.ts.map +1 -1
  13. package/dist/agent/skill-learning/notifier.js +15 -13
  14. package/dist/agent/skill-learning/notifier.js.map +1 -1
  15. package/dist/agent/skill-learning/reviewer.d.ts.map +1 -1
  16. package/dist/agent/skill-learning/reviewer.js +3 -1
  17. package/dist/agent/skill-learning/reviewer.js.map +1 -1
  18. package/dist/api/connectors-router.d.ts.map +1 -1
  19. package/dist/api/connectors-router.js +110 -4
  20. package/dist/api/connectors-router.js.map +1 -1
  21. package/dist/api/gateway-router.d.ts +1 -0
  22. package/dist/api/gateway-router.d.ts.map +1 -1
  23. package/dist/api/gateway-router.js +13 -1
  24. package/dist/api/gateway-router.js.map +1 -1
  25. package/dist/api/line-webhook-router.d.ts +2 -2
  26. package/dist/api/line-webhook-router.d.ts.map +1 -1
  27. package/dist/api/line-webhook-router.js +264 -230
  28. package/dist/api/line-webhook-router.js.map +1 -1
  29. package/dist/api/router.d.ts.map +1 -1
  30. package/dist/api/router.js +372 -11
  31. package/dist/api/router.js.map +1 -1
  32. package/dist/api/share-router.d.ts.map +1 -1
  33. package/dist/api/share-router.js +29 -10
  34. package/dist/api/share-router.js.map +1 -1
  35. package/dist/api/slack-client.d.ts +2 -0
  36. package/dist/api/slack-client.d.ts.map +1 -1
  37. package/dist/api/slack-client.js +6 -2
  38. package/dist/api/slack-client.js.map +1 -1
  39. package/dist/api/slack-webhook-router.d.ts +3 -0
  40. package/dist/api/slack-webhook-router.d.ts.map +1 -1
  41. package/dist/api/slack-webhook-router.js +226 -131
  42. package/dist/api/slack-webhook-router.js.map +1 -1
  43. package/dist/api/voice-router.d.ts +21 -0
  44. package/dist/api/voice-router.d.ts.map +1 -0
  45. package/dist/api/voice-router.js +372 -0
  46. package/dist/api/voice-router.js.map +1 -0
  47. package/dist/api/voice-settings-router.d.ts +5 -0
  48. package/dist/api/voice-settings-router.d.ts.map +1 -0
  49. package/dist/api/voice-settings-router.js +318 -0
  50. package/dist/api/voice-settings-router.js.map +1 -0
  51. package/dist/api/wechat-access.d.ts +45 -0
  52. package/dist/api/wechat-access.d.ts.map +1 -0
  53. package/dist/api/wechat-access.js +48 -0
  54. package/dist/api/wechat-access.js.map +1 -0
  55. package/dist/apps/agent-container-migration.d.ts +11 -0
  56. package/dist/apps/agent-container-migration.d.ts.map +1 -0
  57. package/dist/apps/agent-container-migration.js +85 -0
  58. package/dist/apps/agent-container-migration.js.map +1 -0
  59. package/dist/apps/installer.d.ts +1 -1
  60. package/dist/apps/installer.d.ts.map +1 -1
  61. package/dist/apps/installer.js +2 -1
  62. package/dist/apps/installer.js.map +1 -1
  63. package/dist/cli/commands/tasks.d.ts +5 -0
  64. package/dist/cli/commands/tasks.d.ts.map +1 -0
  65. package/dist/cli/commands/tasks.js +92 -0
  66. package/dist/cli/commands/tasks.js.map +1 -0
  67. package/dist/cli/http-client.d.ts +2 -0
  68. package/dist/cli/http-client.d.ts.map +1 -1
  69. package/dist/cli/http-client.js +8 -3
  70. package/dist/cli/http-client.js.map +1 -1
  71. package/dist/cli/index.d.ts.map +1 -1
  72. package/dist/cli/index.js +5 -1
  73. package/dist/cli/index.js.map +1 -1
  74. package/dist/config/config-write-lock.d.ts +2 -0
  75. package/dist/config/config-write-lock.d.ts.map +1 -1
  76. package/dist/config/config-write-lock.js +5 -0
  77. package/dist/config/config-write-lock.js.map +1 -1
  78. package/dist/config/loader.d.ts.map +1 -1
  79. package/dist/config/loader.js +87 -2
  80. package/dist/config/loader.js.map +1 -1
  81. package/dist/config/migrator.d.ts.map +1 -1
  82. package/dist/config/migrator.js +12 -1
  83. package/dist/config/migrator.js.map +1 -1
  84. package/dist/config/watcher.d.ts.map +1 -1
  85. package/dist/config/watcher.js +6 -0
  86. package/dist/config/watcher.js.map +1 -1
  87. package/dist/connectors/resolve.d.ts.map +1 -1
  88. package/dist/connectors/resolve.js +3 -1
  89. package/dist/connectors/resolve.js.map +1 -1
  90. package/dist/connectors/types.d.ts +8 -0
  91. package/dist/connectors/types.d.ts.map +1 -1
  92. package/dist/cron/manager.d.ts.map +1 -1
  93. package/dist/cron/manager.js +21 -2
  94. package/dist/cron/manager.js.map +1 -1
  95. package/dist/discord/receiver.d.ts +2 -1
  96. package/dist/discord/receiver.d.ts.map +1 -1
  97. package/dist/discord/receiver.js +5 -1
  98. package/dist/discord/receiver.js.map +1 -1
  99. package/dist/history/db.d.ts +3 -0
  100. package/dist/history/db.d.ts.map +1 -1
  101. package/dist/history/db.js +21 -1
  102. package/dist/history/db.js.map +1 -1
  103. package/dist/history/types.d.ts +12 -1
  104. package/dist/history/types.d.ts.map +1 -1
  105. package/dist/history/types.js +10 -1
  106. package/dist/history/types.js.map +1 -1
  107. package/dist/index.js +48 -9
  108. package/dist/index.js.map +1 -1
  109. package/dist/orchestration/bounded-queue.d.ts +15 -0
  110. package/dist/orchestration/bounded-queue.d.ts.map +1 -0
  111. package/dist/orchestration/bounded-queue.js +58 -0
  112. package/dist/orchestration/bounded-queue.js.map +1 -0
  113. package/dist/orchestration/bridge.d.ts +55 -0
  114. package/dist/orchestration/bridge.d.ts.map +1 -0
  115. package/dist/orchestration/bridge.js +234 -0
  116. package/dist/orchestration/bridge.js.map +1 -0
  117. package/dist/orchestration/browser-routing.d.ts +7 -0
  118. package/dist/orchestration/browser-routing.d.ts.map +1 -0
  119. package/dist/orchestration/browser-routing.js +22 -0
  120. package/dist/orchestration/browser-routing.js.map +1 -0
  121. package/dist/orchestration/capabilities.d.ts +49 -0
  122. package/dist/orchestration/capabilities.d.ts.map +1 -0
  123. package/dist/orchestration/capabilities.js +417 -0
  124. package/dist/orchestration/capabilities.js.map +1 -0
  125. package/dist/orchestration/capacity.d.ts +14 -0
  126. package/dist/orchestration/capacity.d.ts.map +1 -0
  127. package/dist/orchestration/capacity.js +52 -0
  128. package/dist/orchestration/capacity.js.map +1 -0
  129. package/dist/orchestration/channel-activity.d.ts +21 -0
  130. package/dist/orchestration/channel-activity.d.ts.map +1 -0
  131. package/dist/orchestration/channel-activity.js +72 -0
  132. package/dist/orchestration/channel-activity.js.map +1 -0
  133. package/dist/orchestration/channel-controls.d.ts +32 -0
  134. package/dist/orchestration/channel-controls.d.ts.map +1 -0
  135. package/dist/orchestration/channel-controls.js +105 -0
  136. package/dist/orchestration/channel-controls.js.map +1 -0
  137. package/dist/orchestration/channel-input-media.d.ts +11 -0
  138. package/dist/orchestration/channel-input-media.d.ts.map +1 -0
  139. package/dist/orchestration/channel-input-media.js +54 -0
  140. package/dist/orchestration/channel-input-media.js.map +1 -0
  141. package/dist/orchestration/channel-media.d.ts +4 -0
  142. package/dist/orchestration/channel-media.d.ts.map +1 -0
  143. package/dist/orchestration/channel-media.js +70 -0
  144. package/dist/orchestration/channel-media.js.map +1 -0
  145. package/dist/orchestration/channel-speech.d.ts +7 -0
  146. package/dist/orchestration/channel-speech.d.ts.map +1 -0
  147. package/dist/orchestration/channel-speech.js +65 -0
  148. package/dist/orchestration/channel-speech.js.map +1 -0
  149. package/dist/orchestration/cli-skills.d.ts +12 -0
  150. package/dist/orchestration/cli-skills.d.ts.map +1 -0
  151. package/dist/orchestration/cli-skills.js +132 -0
  152. package/dist/orchestration/cli-skills.js.map +1 -0
  153. package/dist/orchestration/config.d.ts +256 -0
  154. package/dist/orchestration/config.d.ts.map +1 -0
  155. package/dist/orchestration/config.js +110 -0
  156. package/dist/orchestration/config.js.map +1 -0
  157. package/dist/orchestration/container.d.ts +21 -0
  158. package/dist/orchestration/container.d.ts.map +1 -0
  159. package/dist/orchestration/container.js +195 -0
  160. package/dist/orchestration/container.js.map +1 -0
  161. package/dist/orchestration/control-delivery.d.ts +5 -0
  162. package/dist/orchestration/control-delivery.d.ts.map +1 -0
  163. package/dist/orchestration/control-delivery.js +50 -0
  164. package/dist/orchestration/control-delivery.js.map +1 -0
  165. package/dist/orchestration/conversation-intake.d.ts +32 -0
  166. package/dist/orchestration/conversation-intake.d.ts.map +1 -0
  167. package/dist/orchestration/conversation-intake.js +92 -0
  168. package/dist/orchestration/conversation-intake.js.map +1 -0
  169. package/dist/orchestration/decisions.d.ts +27 -0
  170. package/dist/orchestration/decisions.d.ts.map +1 -0
  171. package/dist/orchestration/decisions.js +148 -0
  172. package/dist/orchestration/decisions.js.map +1 -0
  173. package/dist/orchestration/delivery.d.ts +30 -0
  174. package/dist/orchestration/delivery.d.ts.map +1 -0
  175. package/dist/orchestration/delivery.js +219 -0
  176. package/dist/orchestration/delivery.js.map +1 -0
  177. package/dist/orchestration/display-stream.d.ts +4 -0
  178. package/dist/orchestration/display-stream.d.ts.map +1 -0
  179. package/dist/orchestration/display-stream.js +77 -0
  180. package/dist/orchestration/display-stream.js.map +1 -0
  181. package/dist/orchestration/events.d.ts +30 -0
  182. package/dist/orchestration/events.d.ts.map +1 -0
  183. package/dist/orchestration/events.js +65 -0
  184. package/dist/orchestration/events.js.map +1 -0
  185. package/dist/orchestration/execution-observation.d.ts +38 -0
  186. package/dist/orchestration/execution-observation.d.ts.map +1 -0
  187. package/dist/orchestration/execution-observation.js +25 -0
  188. package/dist/orchestration/execution-observation.js.map +1 -0
  189. package/dist/orchestration/file-delivery.d.ts +16 -0
  190. package/dist/orchestration/file-delivery.d.ts.map +1 -0
  191. package/dist/orchestration/file-delivery.js +139 -0
  192. package/dist/orchestration/file-delivery.js.map +1 -0
  193. package/dist/orchestration/gateway-config.d.ts +17 -0
  194. package/dist/orchestration/gateway-config.d.ts.map +1 -0
  195. package/dist/orchestration/gateway-config.js +128 -0
  196. package/dist/orchestration/gateway-config.js.map +1 -0
  197. package/dist/orchestration/history.d.ts +13 -0
  198. package/dist/orchestration/history.d.ts.map +1 -0
  199. package/dist/orchestration/history.js +48 -0
  200. package/dist/orchestration/history.js.map +1 -0
  201. package/dist/orchestration/identity.d.ts +6 -0
  202. package/dist/orchestration/identity.d.ts.map +1 -0
  203. package/dist/orchestration/identity.js +13 -0
  204. package/dist/orchestration/identity.js.map +1 -0
  205. package/dist/orchestration/inference-errors.d.ts +3 -0
  206. package/dist/orchestration/inference-errors.d.ts.map +1 -0
  207. package/dist/orchestration/inference-errors.js +16 -0
  208. package/dist/orchestration/inference-errors.js.map +1 -0
  209. package/dist/orchestration/input-images.d.ts +12 -0
  210. package/dist/orchestration/input-images.d.ts.map +1 -0
  211. package/dist/orchestration/input-images.js +66 -0
  212. package/dist/orchestration/input-images.js.map +1 -0
  213. package/dist/orchestration/instance-lock.d.ts +5 -0
  214. package/dist/orchestration/instance-lock.d.ts.map +1 -0
  215. package/dist/orchestration/instance-lock.js +33 -0
  216. package/dist/orchestration/instance-lock.js.map +1 -0
  217. package/dist/orchestration/line-loading.d.ts +21 -0
  218. package/dist/orchestration/line-loading.d.ts.map +1 -0
  219. package/dist/orchestration/line-loading.js +89 -0
  220. package/dist/orchestration/line-loading.js.map +1 -0
  221. package/dist/orchestration/media.d.ts +3 -0
  222. package/dist/orchestration/media.d.ts.map +1 -0
  223. package/dist/orchestration/media.js +46 -0
  224. package/dist/orchestration/media.js.map +1 -0
  225. package/dist/orchestration/migrations/schema.d.ts +3 -0
  226. package/dist/orchestration/migrations/schema.d.ts.map +1 -0
  227. package/dist/orchestration/migrations/schema.js +80 -0
  228. package/dist/orchestration/migrations/schema.js.map +1 -0
  229. package/dist/orchestration/notification-mailbox.d.ts +5 -0
  230. package/dist/orchestration/notification-mailbox.d.ts.map +1 -0
  231. package/dist/orchestration/notification-mailbox.js +29 -0
  232. package/dist/orchestration/notification-mailbox.js.map +1 -0
  233. package/dist/orchestration/process-activity.d.ts +23 -0
  234. package/dist/orchestration/process-activity.d.ts.map +1 -0
  235. package/dist/orchestration/process-activity.js +95 -0
  236. package/dist/orchestration/process-activity.js.map +1 -0
  237. package/dist/orchestration/process-supervisor.d.ts +15 -0
  238. package/dist/orchestration/process-supervisor.d.ts.map +1 -0
  239. package/dist/orchestration/process-supervisor.js +92 -0
  240. package/dist/orchestration/process-supervisor.js.map +1 -0
  241. package/dist/orchestration/process-turn.d.ts +35 -0
  242. package/dist/orchestration/process-turn.d.ts.map +1 -0
  243. package/dist/orchestration/process-turn.js +246 -0
  244. package/dist/orchestration/process-turn.js.map +1 -0
  245. package/dist/orchestration/progress-review.d.ts +28 -0
  246. package/dist/orchestration/progress-review.d.ts.map +1 -0
  247. package/dist/orchestration/progress-review.js +48 -0
  248. package/dist/orchestration/progress-review.js.map +1 -0
  249. package/dist/orchestration/recovery.d.ts +8 -0
  250. package/dist/orchestration/recovery.d.ts.map +1 -0
  251. package/dist/orchestration/recovery.js +35 -0
  252. package/dist/orchestration/recovery.js.map +1 -0
  253. package/dist/orchestration/reply-context.d.ts +7 -0
  254. package/dist/orchestration/reply-context.d.ts.map +1 -0
  255. package/dist/orchestration/reply-context.js +54 -0
  256. package/dist/orchestration/reply-context.js.map +1 -0
  257. package/dist/orchestration/runtime.d.ts +232 -0
  258. package/dist/orchestration/runtime.d.ts.map +1 -0
  259. package/dist/orchestration/runtime.js +962 -0
  260. package/dist/orchestration/runtime.js.map +1 -0
  261. package/dist/orchestration/skills.d.ts +17 -0
  262. package/dist/orchestration/skills.d.ts.map +1 -0
  263. package/dist/orchestration/skills.js +32 -0
  264. package/dist/orchestration/skills.js.map +1 -0
  265. package/dist/orchestration/source-policy.d.ts +6 -0
  266. package/dist/orchestration/source-policy.d.ts.map +1 -0
  267. package/dist/orchestration/source-policy.js +16 -0
  268. package/dist/orchestration/source-policy.js.map +1 -0
  269. package/dist/orchestration/speech.d.ts +24 -0
  270. package/dist/orchestration/speech.d.ts.map +1 -0
  271. package/dist/orchestration/speech.js +61 -0
  272. package/dist/orchestration/speech.js.map +1 -0
  273. package/dist/orchestration/stop-controls.d.ts +30 -0
  274. package/dist/orchestration/stop-controls.d.ts.map +1 -0
  275. package/dist/orchestration/stop-controls.js +79 -0
  276. package/dist/orchestration/stop-controls.js.map +1 -0
  277. package/dist/orchestration/store.d.ts +86 -0
  278. package/dist/orchestration/store.d.ts.map +1 -0
  279. package/dist/orchestration/store.js +275 -0
  280. package/dist/orchestration/store.js.map +1 -0
  281. package/dist/orchestration/task-controls.d.ts +130 -0
  282. package/dist/orchestration/task-controls.d.ts.map +1 -0
  283. package/dist/orchestration/task-controls.js +55 -0
  284. package/dist/orchestration/task-controls.js.map +1 -0
  285. package/dist/orchestration/task-files.d.ts +29 -0
  286. package/dist/orchestration/task-files.d.ts.map +1 -0
  287. package/dist/orchestration/task-files.js +200 -0
  288. package/dist/orchestration/task-files.js.map +1 -0
  289. package/dist/orchestration/task-report.d.ts +7 -0
  290. package/dist/orchestration/task-report.d.ts.map +1 -0
  291. package/dist/orchestration/task-report.js +33 -0
  292. package/dist/orchestration/task-report.js.map +1 -0
  293. package/dist/orchestration/tasks/checkpoint-hook.d.ts +19 -0
  294. package/dist/orchestration/tasks/checkpoint-hook.d.ts.map +1 -0
  295. package/dist/orchestration/tasks/checkpoint-hook.js +49 -0
  296. package/dist/orchestration/tasks/checkpoint-hook.js.map +1 -0
  297. package/dist/orchestration/tasks/cleanup.d.ts +18 -0
  298. package/dist/orchestration/tasks/cleanup.d.ts.map +1 -0
  299. package/dist/orchestration/tasks/cleanup.js +113 -0
  300. package/dist/orchestration/tasks/cleanup.js.map +1 -0
  301. package/dist/orchestration/tasks/driver.d.ts +23 -0
  302. package/dist/orchestration/tasks/driver.d.ts.map +1 -0
  303. package/dist/orchestration/tasks/driver.js +209 -0
  304. package/dist/orchestration/tasks/driver.js.map +1 -0
  305. package/dist/orchestration/tasks/failure.d.ts +5 -0
  306. package/dist/orchestration/tasks/failure.d.ts.map +1 -0
  307. package/dist/orchestration/tasks/failure.js +17 -0
  308. package/dist/orchestration/tasks/failure.js.map +1 -0
  309. package/dist/orchestration/tasks/pool.d.ts +18 -0
  310. package/dist/orchestration/tasks/pool.d.ts.map +1 -0
  311. package/dist/orchestration/tasks/pool.js +73 -0
  312. package/dist/orchestration/tasks/pool.js.map +1 -0
  313. package/dist/orchestration/tasks/scheduler.d.ts +38 -0
  314. package/dist/orchestration/tasks/scheduler.d.ts.map +1 -0
  315. package/dist/orchestration/tasks/scheduler.js +160 -0
  316. package/dist/orchestration/tasks/scheduler.js.map +1 -0
  317. package/dist/orchestration/tasks/service.d.ts +109 -0
  318. package/dist/orchestration/tasks/service.d.ts.map +1 -0
  319. package/dist/orchestration/tasks/service.js +697 -0
  320. package/dist/orchestration/tasks/service.js.map +1 -0
  321. package/dist/orchestration/tasks/shared-workspace.d.ts +25 -0
  322. package/dist/orchestration/tasks/shared-workspace.d.ts.map +1 -0
  323. package/dist/orchestration/tasks/shared-workspace.js +162 -0
  324. package/dist/orchestration/tasks/shared-workspace.js.map +1 -0
  325. package/dist/orchestration/tasks/task-directive.d.ts +6 -0
  326. package/dist/orchestration/tasks/task-directive.d.ts.map +1 -0
  327. package/dist/orchestration/tasks/task-directive.js +41 -0
  328. package/dist/orchestration/tasks/task-directive.js.map +1 -0
  329. package/dist/orchestration/tasks/timing.d.ts +15 -0
  330. package/dist/orchestration/tasks/timing.d.ts.map +1 -0
  331. package/dist/orchestration/tasks/timing.js +48 -0
  332. package/dist/orchestration/tasks/timing.js.map +1 -0
  333. package/dist/orchestration/tasks/tool-repetition.d.ts +3 -0
  334. package/dist/orchestration/tasks/tool-repetition.d.ts.map +1 -0
  335. package/dist/orchestration/tasks/tool-repetition.js +30 -0
  336. package/dist/orchestration/tasks/tool-repetition.js.map +1 -0
  337. package/dist/orchestration/tasks/workspace.d.ts +24 -0
  338. package/dist/orchestration/tasks/workspace.d.ts.map +1 -0
  339. package/dist/orchestration/tasks/workspace.js +147 -0
  340. package/dist/orchestration/tasks/workspace.js.map +1 -0
  341. package/dist/orchestration/telegram-speech.d.ts +17 -0
  342. package/dist/orchestration/telegram-speech.d.ts.map +1 -0
  343. package/dist/orchestration/telegram-speech.js +55 -0
  344. package/dist/orchestration/telegram-speech.js.map +1 -0
  345. package/dist/orchestration/telegram-tool-status.d.ts +23 -0
  346. package/dist/orchestration/telegram-tool-status.d.ts.map +1 -0
  347. package/dist/orchestration/telegram-tool-status.js +207 -0
  348. package/dist/orchestration/telegram-tool-status.js.map +1 -0
  349. package/dist/orchestration/telegram-voices.d.ts +42 -0
  350. package/dist/orchestration/telegram-voices.d.ts.map +1 -0
  351. package/dist/orchestration/telegram-voices.js +70 -0
  352. package/dist/orchestration/telegram-voices.js.map +1 -0
  353. package/dist/orchestration/tool-activity.d.ts +10 -0
  354. package/dist/orchestration/tool-activity.d.ts.map +1 -0
  355. package/dist/orchestration/tool-activity.js +38 -0
  356. package/dist/orchestration/tool-activity.js.map +1 -0
  357. package/dist/orchestration/types.d.ts +177 -0
  358. package/dist/orchestration/types.d.ts.map +1 -0
  359. package/dist/orchestration/types.js +13 -0
  360. package/dist/orchestration/types.js.map +1 -0
  361. package/dist/orchestration/voice-reply-policy.d.ts +8 -0
  362. package/dist/orchestration/voice-reply-policy.d.ts.map +1 -0
  363. package/dist/orchestration/voice-reply-policy.js +46 -0
  364. package/dist/orchestration/voice-reply-policy.js.map +1 -0
  365. package/dist/orchestration/worker-shares.d.ts +8 -0
  366. package/dist/orchestration/worker-shares.d.ts.map +1 -0
  367. package/dist/orchestration/worker-shares.js +59 -0
  368. package/dist/orchestration/worker-shares.js.map +1 -0
  369. package/dist/orchestration/workflow.d.ts +121 -0
  370. package/dist/orchestration/workflow.d.ts.map +1 -0
  371. package/dist/orchestration/workflow.js +69 -0
  372. package/dist/orchestration/workflow.js.map +1 -0
  373. package/dist/session/input-image.d.ts +10 -0
  374. package/dist/session/input-image.d.ts.map +1 -0
  375. package/dist/session/input-image.js +3 -0
  376. package/dist/session/input-image.js.map +1 -0
  377. package/dist/session/process.d.ts +15 -3
  378. package/dist/session/process.d.ts.map +1 -1
  379. package/dist/session/process.js +144 -35
  380. package/dist/session/process.js.map +1 -1
  381. package/dist/session/runtime-profile.d.ts +36 -0
  382. package/dist/session/runtime-profile.d.ts.map +1 -0
  383. package/dist/session/runtime-profile.js +63 -0
  384. package/dist/session/runtime-profile.js.map +1 -0
  385. package/dist/session/store.d.ts.map +1 -1
  386. package/dist/session/store.js +23 -1
  387. package/dist/session/store.js.map +1 -1
  388. package/dist/share/share-store.d.ts +3 -1
  389. package/dist/share/share-store.d.ts.map +1 -1
  390. package/dist/share/share-store.js +13 -2
  391. package/dist/share/share-store.js.map +1 -1
  392. package/dist/shared/line-request-order.d.ts +2 -0
  393. package/dist/shared/line-request-order.d.ts.map +1 -0
  394. package/dist/shared/line-request-order.js +16 -0
  395. package/dist/shared/line-request-order.js.map +1 -0
  396. package/dist/shared/task-elapsed.d.ts +3 -0
  397. package/dist/shared/task-elapsed.d.ts.map +1 -0
  398. package/dist/shared/task-elapsed.js +12 -0
  399. package/dist/shared/task-elapsed.js.map +1 -0
  400. package/dist/shared/task-updated-time.d.ts +3 -0
  401. package/dist/shared/task-updated-time.d.ts.map +1 -0
  402. package/dist/shared/task-updated-time.js +15 -0
  403. package/dist/shared/task-updated-time.js.map +1 -0
  404. package/dist/skills/loader.d.ts +2 -0
  405. package/dist/skills/loader.d.ts.map +1 -1
  406. package/dist/skills/loader.js.map +1 -1
  407. package/dist/telegram/chunks.d.ts +19 -0
  408. package/dist/telegram/chunks.d.ts.map +1 -0
  409. package/dist/telegram/chunks.js +129 -0
  410. package/dist/telegram/chunks.js.map +1 -0
  411. package/dist/telegram/markdown.d.ts.map +1 -1
  412. package/dist/telegram/markdown.js +18 -3
  413. package/dist/telegram/markdown.js.map +1 -1
  414. package/dist/telegram/receiver.d.ts +2 -1
  415. package/dist/telegram/receiver.d.ts.map +1 -1
  416. package/dist/telegram/receiver.js +6 -1
  417. package/dist/telegram/receiver.js.map +1 -1
  418. package/dist/types.d.ts +54 -0
  419. package/dist/types.d.ts.map +1 -1
  420. package/dist/ui/web-ui.d.ts.map +1 -1
  421. package/dist/ui/web-ui.js +31 -5
  422. package/dist/ui/web-ui.js.map +1 -1
  423. package/dist/voice/diagnostics.d.ts +29 -0
  424. package/dist/voice/diagnostics.d.ts.map +1 -0
  425. package/dist/voice/diagnostics.js +37 -0
  426. package/dist/voice/diagnostics.js.map +1 -0
  427. package/dist/voice/errors.d.ts +19 -0
  428. package/dist/voice/errors.d.ts.map +1 -0
  429. package/dist/voice/errors.js +133 -0
  430. package/dist/voice/errors.js.map +1 -0
  431. package/dist/voice/line-audio.d.ts +4 -0
  432. package/dist/voice/line-audio.d.ts.map +1 -0
  433. package/dist/voice/line-audio.js +27 -0
  434. package/dist/voice/line-audio.js.map +1 -0
  435. package/dist/voice/managed-quota.d.ts +5 -0
  436. package/dist/voice/managed-quota.d.ts.map +1 -0
  437. package/dist/voice/managed-quota.js +35 -0
  438. package/dist/voice/managed-quota.js.map +1 -0
  439. package/dist/voice/mp3.d.ts +3 -0
  440. package/dist/voice/mp3.d.ts.map +1 -0
  441. package/dist/voice/mp3.js +30 -0
  442. package/dist/voice/mp3.js.map +1 -0
  443. package/dist/voice/notes.d.ts +9 -0
  444. package/dist/voice/notes.d.ts.map +1 -0
  445. package/dist/voice/notes.js +68 -0
  446. package/dist/voice/notes.js.map +1 -0
  447. package/dist/voice/playback.d.ts +22 -0
  448. package/dist/voice/playback.d.ts.map +1 -0
  449. package/dist/voice/playback.js +52 -0
  450. package/dist/voice/playback.js.map +1 -0
  451. package/dist/voice/preview.d.ts +6 -0
  452. package/dist/voice/preview.d.ts.map +1 -0
  453. package/dist/voice/preview.js +44 -0
  454. package/dist/voice/preview.js.map +1 -0
  455. package/dist/voice/protocol.d.ts +10 -0
  456. package/dist/voice/protocol.d.ts.map +1 -0
  457. package/dist/voice/protocol.js +30 -0
  458. package/dist/voice/protocol.js.map +1 -0
  459. package/dist/voice/providers/cartesia-tts.d.ts +26 -0
  460. package/dist/voice/providers/cartesia-tts.d.ts.map +1 -0
  461. package/dist/voice/providers/cartesia-tts.js +95 -0
  462. package/dist/voice/providers/cartesia-tts.js.map +1 -0
  463. package/dist/voice/providers/deepgram-stt.d.ts +20 -0
  464. package/dist/voice/providers/deepgram-stt.d.ts.map +1 -0
  465. package/dist/voice/providers/deepgram-stt.js +66 -0
  466. package/dist/voice/providers/deepgram-stt.js.map +1 -0
  467. package/dist/voice/providers/elevenlabs-stt.d.ts +20 -0
  468. package/dist/voice/providers/elevenlabs-stt.d.ts.map +1 -0
  469. package/dist/voice/providers/elevenlabs-stt.js +92 -0
  470. package/dist/voice/providers/elevenlabs-stt.js.map +1 -0
  471. package/dist/voice/providers/elevenlabs-tts.d.ts +26 -0
  472. package/dist/voice/providers/elevenlabs-tts.d.ts.map +1 -0
  473. package/dist/voice/providers/elevenlabs-tts.js +82 -0
  474. package/dist/voice/providers/elevenlabs-tts.js.map +1 -0
  475. package/dist/voice/providers/encoded-audio-tts.d.ts +21 -0
  476. package/dist/voice/providers/encoded-audio-tts.d.ts.map +1 -0
  477. package/dist/voice/providers/encoded-audio-tts.js +175 -0
  478. package/dist/voice/providers/encoded-audio-tts.js.map +1 -0
  479. package/dist/voice/providers/fake.d.ts +39 -0
  480. package/dist/voice/providers/fake.d.ts.map +1 -0
  481. package/dist/voice/providers/fake.js +41 -0
  482. package/dist/voice/providers/fake.js.map +1 -0
  483. package/dist/voice/providers/gemini-live-stt.d.ts +21 -0
  484. package/dist/voice/providers/gemini-live-stt.d.ts.map +1 -0
  485. package/dist/voice/providers/gemini-live-stt.js +158 -0
  486. package/dist/voice/providers/gemini-live-stt.js.map +1 -0
  487. package/dist/voice/providers/gemini.d.ts +60 -0
  488. package/dist/voice/providers/gemini.d.ts.map +1 -0
  489. package/dist/voice/providers/gemini.js +124 -0
  490. package/dist/voice/providers/gemini.js.map +1 -0
  491. package/dist/voice/providers/model-ref.d.ts +9 -0
  492. package/dist/voice/providers/model-ref.d.ts.map +1 -0
  493. package/dist/voice/providers/model-ref.js +31 -0
  494. package/dist/voice/providers/model-ref.js.map +1 -0
  495. package/dist/voice/providers/openrouter.d.ts +39 -0
  496. package/dist/voice/providers/openrouter.d.ts.map +1 -0
  497. package/dist/voice/providers/openrouter.js +154 -0
  498. package/dist/voice/providers/openrouter.js.map +1 -0
  499. package/dist/voice/providers/paxalabs-stt.d.ts +12 -0
  500. package/dist/voice/providers/paxalabs-stt.d.ts.map +1 -0
  501. package/dist/voice/providers/paxalabs-stt.js +41 -0
  502. package/dist/voice/providers/paxalabs-stt.js.map +1 -0
  503. package/dist/voice/providers/paxalabs-tts.d.ts +23 -0
  504. package/dist/voice/providers/paxalabs-tts.d.ts.map +1 -0
  505. package/dist/voice/providers/paxalabs-tts.js +80 -0
  506. package/dist/voice/providers/paxalabs-tts.js.map +1 -0
  507. package/dist/voice/providers/recorded-stt.d.ts +34 -0
  508. package/dist/voice/providers/recorded-stt.d.ts.map +1 -0
  509. package/dist/voice/providers/recorded-stt.js +59 -0
  510. package/dist/voice/providers/recorded-stt.js.map +1 -0
  511. package/dist/voice/providers/registry.d.ts +10 -0
  512. package/dist/voice/providers/registry.d.ts.map +1 -0
  513. package/dist/voice/providers/registry.js +77 -0
  514. package/dist/voice/providers/registry.js.map +1 -0
  515. package/dist/voice/providers/socket.d.ts +10 -0
  516. package/dist/voice/providers/socket.d.ts.map +1 -0
  517. package/dist/voice/providers/socket.js +91 -0
  518. package/dist/voice/providers/socket.js.map +1 -0
  519. package/dist/voice/providers/upstream.d.ts +9 -0
  520. package/dist/voice/providers/upstream.d.ts.map +1 -0
  521. package/dist/voice/providers/upstream.js +51 -0
  522. package/dist/voice/providers/upstream.js.map +1 -0
  523. package/dist/voice/providers/voice-catalog.d.ts +17 -0
  524. package/dist/voice/providers/voice-catalog.d.ts.map +1 -0
  525. package/dist/voice/providers/voice-catalog.js +167 -0
  526. package/dist/voice/providers/voice-catalog.js.map +1 -0
  527. package/dist/voice/queue.d.ts +2 -0
  528. package/dist/voice/queue.d.ts.map +1 -0
  529. package/dist/voice/queue.js +6 -0
  530. package/dist/voice/queue.js.map +1 -0
  531. package/dist/voice/session.d.ts +86 -0
  532. package/dist/voice/session.d.ts.map +1 -0
  533. package/dist/voice/session.js +464 -0
  534. package/dist/voice/session.js.map +1 -0
  535. package/dist/voice/turn-manager.d.ts +27 -0
  536. package/dist/voice/turn-manager.d.ts.map +1 -0
  537. package/dist/voice/turn-manager.js +75 -0
  538. package/dist/voice/turn-manager.js.map +1 -0
  539. package/dist/voice/types.d.ts +78 -0
  540. package/dist/voice/types.d.ts.map +1 -0
  541. package/dist/voice/types.js +18 -0
  542. package/dist/voice/types.js.map +1 -0
  543. package/dist/voice/wav.d.ts +2 -0
  544. package/dist/voice/wav.d.ts.map +1 -0
  545. package/dist/voice/wav.js +21 -0
  546. package/dist/voice/wav.js.map +1 -0
  547. package/dist/wechat/ilink-client.d.ts +207 -0
  548. package/dist/wechat/ilink-client.d.ts.map +1 -0
  549. package/dist/wechat/ilink-client.js +660 -0
  550. package/dist/wechat/ilink-client.js.map +1 -0
  551. package/dist/wechat/manager.d.ts +93 -0
  552. package/dist/wechat/manager.d.ts.map +1 -0
  553. package/dist/wechat/manager.js +409 -0
  554. package/dist/wechat/manager.js.map +1 -0
  555. package/dist/whatsapp/manager.d.ts.map +1 -1
  556. package/dist/whatsapp/manager.js +51 -1
  557. package/dist/whatsapp/manager.js.map +1 -1
  558. package/mcp/capability-catalog.ts +206 -0
  559. package/mcp/modules.ts +56 -0
  560. package/mcp/server.ts +18 -35
  561. package/mcp/tools/browser/module.ts +1 -1
  562. package/mcp/tools/browser/skills/open-browser/SKILL.md +5 -3
  563. package/mcp/tools/discord/commands.ts +17 -1
  564. package/mcp/tools/discord/inbound.ts +11 -0
  565. package/mcp/tools/discord/module.ts +42 -2
  566. package/mcp/tools/discord/receiver-server.ts +10 -0
  567. package/mcp/tools/discord/types.ts +4 -1
  568. package/mcp/tools/image/module.ts +3 -1
  569. package/mcp/tools/receiver-spool.test.ts +28 -0
  570. package/mcp/tools/receiver-spool.ts +56 -0
  571. package/mcp/tools/share-file/module.ts +9 -1
  572. package/mcp/tools/shared/share-client.ts +19 -0
  573. package/mcp/tools/tasks/module.ts +35 -0
  574. package/mcp/tools/telegram/media-group.ts +21 -0
  575. package/mcp/tools/telegram/receiver-server.ts +232 -11
  576. package/mcp/tools/telegram/selection-confirmation.ts +20 -0
  577. package/mcp/tools/telegram/task-browser.ts +117 -0
  578. package/mcp/tools/telegram/task-detail.ts +36 -0
  579. package/mcp/tools/telegram/task-elapsed.ts +1 -0
  580. package/mcp/tools/telegram/typing.ts +6 -116
  581. package/mcp/tools/video/module.ts +1 -1
  582. package/mcp/tools/wechat/client.ts +49 -0
  583. package/mcp/tools/wechat/module.ts +88 -0
  584. package/mcp/types.ts +5 -0
  585. package/package.json +2 -1
  586. package/resource/claude_gateway.jpeg +0 -0
  587. package/scripts/orchestration/bench-store.cjs +30 -0
  588. package/scripts/orchestration/inspect.cjs +16 -0
  589. package/scripts/orchestration/probe-profile.cjs +67 -0
  590. package/scripts/orchestration/reconcile.cjs +21 -0
  591. package/scripts/orchestration/smoke-elevenlabs.cjs +90 -0
  592. package/scripts/orchestration/smoke-media.cjs +70 -0
  593. package/scripts/orchestration/smoke-text.cjs +101 -0
  594. package/scripts/orchestration/smoke-vision.cjs +49 -0
@@ -0,0 +1,697 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TaskService = void 0;
4
+ const workflow_1 = require("../workflow");
5
+ const timing_1 = require("./timing");
6
+ const task_directive_1 = require("./task-directive");
7
+ const task_directive_2 = require("./task-directive");
8
+ const child_process_1 = require("child_process");
9
+ const util_1 = require("util");
10
+ const failure_1 = require("./failure");
11
+ const pool_1 = require("./pool");
12
+ const crypto_1 = require("crypto");
13
+ const store_1 = require("../store");
14
+ const config_1 = require("../config");
15
+ const types_1 = require("../types");
16
+ /** Task mutations use short durable transactions; admission probes are read-only. */
17
+ class TaskService {
18
+ constructor(store, config, defaultProjectRoot = '') {
19
+ this.store = store;
20
+ this.defaultProjectRoot = defaultProjectRoot;
21
+ this.repeatedTools = new Map();
22
+ this.config = (0, config_1.resolveOrchestrationConfig)(config);
23
+ this.pool = new pool_1.WorkerPool(store);
24
+ }
25
+ configure(config) { this.config = (0, config_1.resolveOrchestrationConfig)(config); }
26
+ /** Admission feedback reaches the agent before a doomed task is committed. */
27
+ async validateSpawnProfile(context, targetProfile) {
28
+ // A committed receipt remains replayable even if its original repository disappeared.
29
+ if (this.store.get('SELECT action_id FROM task_commands WHERE action_id=?', context.actionId))
30
+ return;
31
+ if (targetProfile !== 'default-worker' || this.config.tasks.workspaceMode !== 'isolated-worktree')
32
+ return;
33
+ const root = this.config.tasks.projectRoot || this.defaultProjectRoot;
34
+ try {
35
+ await (0, util_1.promisify)(child_process_1.execFile)('git', ['-C', root, 'rev-parse', '--show-toplevel'], { timeout: 3000, maxBuffer: 4096 });
36
+ }
37
+ catch {
38
+ throw new types_1.OrchestrationError('WORKER_GIT_PROJECT_REQUIRED', 'No task was queued: explicitly configured isolated-worktree mode could not validate the Git repository for default-worker. This requirement applies only to worktree isolation, not ordinary host/container execution. For GitHub status/API commands or other standalone work, use media-worker with an explicit repository (for example gh --repo owner/repo), preserving continue_task_id and existing user authorization. For project edits, configure tasks.projectRoot to the intended repository. Do not switch to host execution or replay already completed side effects.');
39
+ }
40
+ }
41
+ command(context, kind, payload, execute, operation, taskId) {
42
+ return this.store.transaction(() => {
43
+ this.store.assertMember(context.conversationId, context.principalId);
44
+ (0, store_1.boundedText)(context.actionId, 1024);
45
+ const hash = (0, store_1.payloadHash)({ kind, payload, inputId: context.inputId });
46
+ const prior = this.store.get('SELECT * FROM task_commands WHERE action_id=?', context.actionId);
47
+ // A committed command survives its decision being interrupted. Check its
48
+ // original identity before returning the saved receipt, then fence new work.
49
+ if (prior) {
50
+ if (prior.conversation_id !== context.conversationId || prior.principal_id !== context.principalId)
51
+ throw new types_1.OrchestrationError('ACCESS_DENIED');
52
+ if (prior.payload_hash !== hash)
53
+ throw new types_1.OrchestrationError('IDEMPOTENCY_CONFLICT');
54
+ return JSON.parse(String(prior.receipt_json));
55
+ }
56
+ const decision = this.store.get(`SELECT d.* FROM conversation_decisions d JOIN conversations c ON c.id=d.conversation_id
57
+ WHERE d.id=? AND d.conversation_id=? AND d.epoch=? AND c.epoch=d.epoch AND d.state='running'`, context.decisionId, context.conversationId, context.epoch);
58
+ if (!decision)
59
+ throw new types_1.OrchestrationError('STALE_DECISION');
60
+ const input = this.store.get('SELECT id FROM conversation_inputs WHERE id=? AND conversation_id=? AND principal_id=?', context.inputId, context.conversationId, context.principalId);
61
+ if (!input || !JSON.parse(String(decision.input_ids_json)).includes(context.inputId))
62
+ throw new types_1.OrchestrationError('ACCESS_DENIED');
63
+ if (execute && !context.execute)
64
+ throw new types_1.OrchestrationError('EXECUTION_DENIED');
65
+ // Recovery may re-run inference with new tool-call IDs or rephrased args.
66
+ // Only replay committed receipts for this original input; new mutations
67
+ // require a new user input rather than guessing whether effects happened.
68
+ const recovered = this.store.all(`SELECT tc.* FROM task_commands tc
69
+ JOIN conversation_decisions d ON d.id=tc.decision_id
70
+ WHERE tc.conversation_id=? AND tc.principal_id=? AND d.id!=? AND d.state='interrupted'
71
+ AND EXISTS (SELECT 1 FROM json_each(d.input_ids_json) WHERE value=?)`, context.conversationId, context.principalId, context.decisionId, context.inputId);
72
+ if (recovered.length) {
73
+ const receipt = recovered.find(row => row.payload_hash === hash);
74
+ if (receipt)
75
+ return JSON.parse(String(receipt.receipt_json));
76
+ throw new types_1.OrchestrationError('RECOVERY_COMMAND_CONFLICT', 'This input already committed task commands before interruption. Inspect their receipts; new changes require a new user input.');
77
+ }
78
+ const receipt = operation();
79
+ const id = taskId ?? receipt?.taskId ?? null;
80
+ this.store.run('INSERT INTO task_commands VALUES(?,?,?,?,?,?,?,?,?)', context.actionId, id, context.conversationId, context.principalId, context.decisionId, kind, hash, JSON.stringify(receipt), Date.now());
81
+ return receipt;
82
+ });
83
+ }
84
+ owned(taskId, conversationId) {
85
+ const task = this.store.task(taskId);
86
+ if (!task || task.conversationId !== conversationId)
87
+ throw new types_1.OrchestrationError('ACCESS_DENIED');
88
+ return task;
89
+ }
90
+ status(conversationId, principalId, taskId) {
91
+ this.store.assertMember(conversationId, principalId);
92
+ if (taskId) {
93
+ const task = this.owned(taskId, conversationId);
94
+ delete task.skill;
95
+ return [this.withRecentTools(task)];
96
+ }
97
+ return this.store.all(`SELECT snapshot_json FROM tasks WHERE conversation_id=? AND (state NOT IN ('completed','failed','cancelled') OR id IN
98
+ (SELECT id FROM tasks WHERE conversation_id=? AND state IN ('completed','failed','cancelled') ORDER BY created_at DESC,id DESC LIMIT 100))
99
+ ORDER BY CASE WHEN state IN ('completed','failed','cancelled') THEN 1 ELSE 0 END,created_at DESC,id DESC`, conversationId, conversationId).map(row => {
100
+ const task = JSON.parse(String(row.snapshot_json));
101
+ delete task.skill; // Installed skill bodies are worker-only execution context.
102
+ return this.withRecentTools(task);
103
+ });
104
+ }
105
+ /** Current reports are lossless. Other tasks are an index, never partial reports. */
106
+ context(conversationId, principalId, decisionId) {
107
+ const tasks = new Map(this.status(conversationId, principalId).map(task => [task.taskId, task]));
108
+ const reporting = new Set(this.store.all("SELECT DISTINCT task_id FROM notifications WHERE conversation_id=? AND decision_id=? AND status='assigned'", conversationId, decisionId).map(row => String(row.task_id)));
109
+ // An old task can finish after it has fallen outside the recent-task page.
110
+ for (const id of reporting)
111
+ if (!tasks.has(id))
112
+ tasks.set(id, this.status(conversationId, principalId, id)[0]);
113
+ return [...tasks.values()].map(task => reporting.has(task.taskId) ? task : {
114
+ taskId: task.taskId, title: task.title, state: task.state,
115
+ stateVersion: task.stateVersion, revision: task.revision, appliedRevision: task.appliedRevision,
116
+ createdAt: task.createdAt, updatedAt: task.updatedAt,
117
+ workflow: task.workflow,
118
+ latestProgress: types_1.TERMINAL_TASK_STATES.has(task.state) ? undefined : task.latestProgress,
119
+ execution: types_1.TERMINAL_TASK_STATES.has(task.state) ? undefined : task.execution,
120
+ pendingQuestion: task.pendingQuestion, failure: task.failure,
121
+ cancellation: task.cancellation, replacedByTaskId: task.replacedByTaskId,
122
+ workstreamId: task.workstreamId, continueTaskId: task.continueTaskId, continuationPolicy: task.continuationPolicy,
123
+ resultAvailable: Boolean(task.result),
124
+ details: { tool: 'task_status', task_id: task.taskId },
125
+ });
126
+ }
127
+ withRecentTools(task) {
128
+ task.recentTools = this.store.all("SELECT payload_json,occurred_at FROM conversation_events WHERE conversation_id=? AND type='tool.activity' AND json_extract(payload_json,'$.task_id')=? ORDER BY seq DESC LIMIT 8", task.conversationId, task.taskId).map(row => {
129
+ const event = JSON.parse(String(row.payload_json)).payload;
130
+ return { name: String(event.name ?? 'unknown'), description: typeof event.input?.description === 'string' ? (0, failure_1.taskFailure)(new Error(event.input.description)).message.slice(0, 512) : undefined, type: String(event.type), isError: event.is_error, occurredAt: Number(row.occurred_at) };
131
+ });
132
+ task.workspaceEvidence = {
133
+ registered: this.store.all('SELECT mode,worktree_path,lifecycle_state FROM task_resources WHERE task_id=?', task.taskId)
134
+ .map(row => ({ mode: String(row.mode), path: String(row.worktree_path), lifecycleState: String(row.lifecycle_state) })),
135
+ observedFilePaths: this.store.all("SELECT DISTINCT json_extract(payload_json,'$.payload.input.file_path') AS path FROM conversation_events WHERE conversation_id=? AND type='tool.activity' AND json_extract(payload_json,'$.task_id')=? AND json_type(payload_json,'$.payload.input.file_path')='text' ORDER BY seq DESC LIMIT 12", task.conversationId, task.taskId)
136
+ .map(row => String(row.path).slice(0, 2048)),
137
+ currentFilesystemVerified: false,
138
+ };
139
+ return task;
140
+ }
141
+ spawn(context, command) {
142
+ if (command.continueTaskId !== undefined)
143
+ (0, store_1.boundedText)(command.continueTaskId, 128);
144
+ if (command.continuationPolicy !== undefined && (!command.continueTaskId || !['after_success', 'after_terminal'].includes(command.continuationPolicy)))
145
+ throw new types_1.OrchestrationError('INVALID_INPUT');
146
+ (0, store_1.boundedText)(command.title, 512);
147
+ (0, store_1.boundedText)(command.instructions);
148
+ (0, store_1.boundedText)(command.targetProfile, 128);
149
+ if ((command.contextRefs?.length ?? 0) > 64 || command.contextRefs?.some(ref => typeof ref !== 'string' || ref.length > 1024))
150
+ throw new types_1.OrchestrationError('INVALID_INPUT');
151
+ if (!['default-worker', 'media-worker', 'skill-worker'].includes(command.targetProfile))
152
+ throw new types_1.OrchestrationError('UNKNOWN_WORKER_PROFILE');
153
+ return this.command(context, 'spawn', command, true, () => {
154
+ const conversation = this.store.get('SELECT * FROM conversations WHERE id=?', context.conversationId);
155
+ const available = new Set();
156
+ for (const input of this.store.all('SELECT id,attachment_refs_json FROM conversation_inputs WHERE conversation_id=?', context.conversationId)) {
157
+ available.add(String(input.id));
158
+ available.add(`input:${input.id}`);
159
+ for (const ref of JSON.parse(String(input.attachment_refs_json)))
160
+ available.add(ref);
161
+ }
162
+ for (const resource of this.store.all('SELECT r.id FROM task_resources r JOIN tasks t ON r.task_id=t.id WHERE t.conversation_id=?', context.conversationId))
163
+ available.add(String(resource.id));
164
+ for (const file of this.store.all('SELECT f.id,f.path FROM task_files f JOIN tasks t ON f.task_id=t.id WHERE t.conversation_id=? AND t.state=?', context.conversationId, 'completed')) {
165
+ available.add(String(file.id));
166
+ available.add(String(file.path));
167
+ }
168
+ if (command.contextRefs?.some(ref => !available.has(ref)))
169
+ throw new types_1.OrchestrationError('CONTEXT_ACCESS_DENIED');
170
+ if (conversation.status !== 'active')
171
+ throw new types_1.OrchestrationError('DRAINING');
172
+ const queued = this.store.all("SELECT conversation_id,COUNT(*) AS n FROM tasks WHERE state='queued' GROUP BY conversation_id");
173
+ if (queued.reduce((n, row) => n + Number(row.n), 0) >= this.config.tasks.maxQueuedPerAgent || Number(queued.find(row => row.conversation_id === context.conversationId)?.n ?? 0) >= this.config.tasks.maxQueuedPerConversation)
174
+ throw new types_1.OrchestrationError('QUEUE_FULL');
175
+ const prior = command.continueTaskId ? this.owned(command.continueTaskId, context.conversationId) : undefined;
176
+ const now = Math.max(Date.now(), (prior?.createdAt ?? 0) + 1);
177
+ const task = { taskId: (0, crypto_1.randomUUID)(), conversationId: context.conversationId,
178
+ agentId: this.store.agentId, agentSessionId: String(conversation.agent_session_id), ownerPrincipalId: context.principalId,
179
+ initiatingInputId: context.inputId, title: command.title, targetProfile: command.targetProfile,
180
+ state: 'queued', stateVersion: 1, revision: 1, appliedRevision: 0,
181
+ timing: { phase: 'queued', since: Date.now(), measuredFrom: Date.now(), totals: {} },
182
+ capabilities: { execute: context.execute, writeMemory: context.writeMemory }, createdAt: now, updatedAt: now };
183
+ task.workstreamId = prior?.workstreamId ?? prior?.taskId ?? task.taskId;
184
+ if (prior) {
185
+ task.continueTaskId = prior.taskId;
186
+ task.continuationPolicy = command.continuationPolicy ?? 'after_success';
187
+ task.latestProgress = { source: 'runtime', observedAt: now, text: `Queued after task ${prior.taskId} (${task.continuationPolicy}).` };
188
+ }
189
+ if (command.skill)
190
+ task.skill = command.skill;
191
+ if (context.model)
192
+ task.model = context.model;
193
+ const projectRoot = this.config.tasks.projectRoot || this.defaultProjectRoot;
194
+ if (projectRoot)
195
+ task.resourceProfile = { projectRoot, mode: this.config.tasks.workspaceMode };
196
+ this.store.run('INSERT INTO tasks VALUES(?,?,?,?,?,?,?,?,?)', task.taskId, task.conversationId, task.state, 1, 1, null, JSON.stringify(task), now, now);
197
+ const revision = { taskId: task.taskId, revision: 1, instructions: command.instructions,
198
+ contextRefs: command.contextRefs ?? [], mode: 'when_ready', originatingInputId: context.inputId };
199
+ this.store.run('INSERT INTO task_revisions VALUES(?,?,?)', task.taskId, 1, JSON.stringify(revision));
200
+ this.store.appendEvent(task.conversationId, 'task.created', task, task.taskId);
201
+ this.store.enqueue('schedule', `schedule:${task.taskId}:1`, { taskId: task.taskId });
202
+ return task;
203
+ });
204
+ }
205
+ update(context, taskId, expectedRevision, instruction, mode) {
206
+ (0, store_1.boundedText)(instruction);
207
+ if (!['when_ready', 'interrupt_and_resume'].includes(mode))
208
+ throw new types_1.OrchestrationError('INVALID_INPUT');
209
+ return this.command(context, 'update', { taskId, expectedRevision, instruction, mode }, context.execute, () => {
210
+ const task = this.owned(taskId, context.conversationId), version = task.stateVersion;
211
+ if (types_1.TERMINAL_TASK_STATES.has(task.state))
212
+ throw new types_1.OrchestrationError('TASK_TERMINAL');
213
+ if (['cancel_requested', 'recovering', 'needs_reconciliation', 'interrupting'].includes(task.state))
214
+ throw new types_1.OrchestrationError('STATE_CONFLICT');
215
+ if (task.revision !== expectedRevision)
216
+ throw new types_1.OrchestrationError('REVISION_CONFLICT');
217
+ const priorRevision = this.revision(taskId, expectedRevision);
218
+ if (!context.execute) {
219
+ // A worker progress report increments stateVersion without revoking this
220
+ // alert. Bind advice to the immutable alert and attempt, not that counter.
221
+ const assigned = this.store.get(`SELECT n.id FROM notifications n JOIN conversation_events e
222
+ ON e.conversation_id=n.conversation_id AND e.type='task.state_changed'
223
+ AND json_extract(e.payload_json,'$.payload.taskId')=n.task_id
224
+ AND json_extract(e.payload_json,'$.payload.stateVersion')=n.task_state_version
225
+ WHERE n.task_id=? AND n.decision_id=? AND n.status='assigned'
226
+ AND json_extract(e.payload_json,'$.payload.supervision.id')=?
227
+ AND json_extract(e.payload_json,'$.payload.activeAttemptId')=? LIMIT 1`, taskId, context.decisionId, task.supervision?.id ?? '', task.activeAttemptId ?? '');
228
+ const alreadyAdvised = this.store.get("SELECT action_id FROM task_commands WHERE task_id=? AND decision_id=? AND command_type='update' LIMIT 1", taskId, context.decisionId);
229
+ if (!assigned || alreadyAdvised || !task.supervision || task.state !== 'running' || !task.capabilities.execute || mode !== 'when_ready')
230
+ throw new types_1.OrchestrationError('EXECUTION_DENIED');
231
+ }
232
+ task.revision++;
233
+ const revision = { taskId, revision: task.revision, instructions: instruction,
234
+ contextRefs: priorRevision.contextRefs, mode, originatingInputId: context.inputId,
235
+ ...(!context.execute ? { instructions: priorRevision.instructions, answers: priorRevision.answers, originatingInputId: priorRevision.originatingInputId, guidance: instruction, guidanceBasis: { attemptId: task.activeAttemptId, workflowVersion: task.workflow?.version ?? 0, progressAt: task.latestProgress?.observedAt ?? 0 } } : {}) };
236
+ this.store.run('INSERT INTO task_revisions VALUES(?,?,?)', taskId, task.revision, JSON.stringify(revision));
237
+ if (task.state === 'waiting_input') {
238
+ task.pendingQuestion = undefined;
239
+ task.state = task.activeAttemptId ? 'interrupting' : 'queued';
240
+ }
241
+ else if (mode === 'interrupt_and_resume' && task.activeAttemptId)
242
+ task.state = 'interrupting';
243
+ this.store.saveTask(task, version);
244
+ this.store.appendEvent(task.conversationId, 'task.revision_accepted', { taskId, revision: task.revision }, taskId);
245
+ this.store.enqueue(task.state === 'interrupting' ? 'interrupt' : 'schedule', `revision:${taskId}:${task.revision}`, { taskId });
246
+ return task;
247
+ }, taskId);
248
+ }
249
+ cancel(context, taskId, replacedByTaskId) {
250
+ return this.command(context, 'cancel', { taskId, ...(replacedByTaskId ? { replacedByTaskId } : {}) }, false, () => this.cancelOwned(context.conversationId, taskId, replacedByTaskId), taskId);
251
+ }
252
+ /** Authenticated user control bypasses inference, but retains conversation ownership and task fencing. */
253
+ cancelByUser(conversationId, principalId, taskId) {
254
+ return this.store.transaction(() => {
255
+ this.store.assertMember(conversationId, principalId);
256
+ const task = this.cancelOwned(conversationId, taskId, undefined, 'user');
257
+ this.store.appendEvent(conversationId, 'task.user_cancel', { taskId, principalId, state: task.state }, taskId);
258
+ return task;
259
+ });
260
+ }
261
+ cancelOwned(conversationId, taskId, replacedByTaskId, requestedBy = 'agent') {
262
+ const task = this.owned(taskId, conversationId);
263
+ if (replacedByTaskId) {
264
+ if (replacedByTaskId === taskId)
265
+ throw new types_1.OrchestrationError('INVALID_REPLACEMENT');
266
+ this.owned(replacedByTaskId, conversationId);
267
+ }
268
+ if (types_1.TERMINAL_TASK_STATES.has(task.state))
269
+ return task;
270
+ if (task.state === 'cancel_requested') {
271
+ if (replacedByTaskId) {
272
+ task.replacedByTaskId = replacedByTaskId;
273
+ this.store.saveTask(task, task.stateVersion);
274
+ }
275
+ return task;
276
+ }
277
+ if (replacedByTaskId)
278
+ task.replacedByTaskId = replacedByTaskId;
279
+ const version = task.stateVersion;
280
+ task.cancellation = { requestedBy, requestedAt: Date.now() };
281
+ task.state = task.activeAttemptId ? 'cancel_requested' : 'cancelled';
282
+ task.pendingQuestion = undefined;
283
+ delete task.failure;
284
+ task.latestProgress = { source: 'runtime', observedAt: Date.now(), text: task.activeAttemptId ? `Cancellation requested by ${requestedBy}; verifying that task execution has stopped.` : `Cancelled by ${requestedBy}. Existing files and prior effects are retained.` };
285
+ this.store.saveTask(task, version);
286
+ if (task.state === 'cancelled')
287
+ this.notify(task);
288
+ else
289
+ this.store.enqueue('interrupt', `cancel:${taskId}:${task.stateVersion}`, { taskId });
290
+ return task;
291
+ }
292
+ /** Scheduler-only cleanup acknowledgment; never authorizes new worker writes. */
293
+ finishCleanup(attemptId, generation, stopped) {
294
+ this.store.transaction(() => {
295
+ const attempt = this.store.attempt(attemptId), task = attempt && this.store.task(attempt.taskId);
296
+ if (!attempt || !task || attempt.generation !== generation || task.activeAttemptId !== attemptId || task.state !== 'cancel_requested')
297
+ throw new types_1.OrchestrationError('STALE_ATTEMPT');
298
+ const message = stopped ? `Cancelled by ${task.cancellation?.requestedBy ?? 'agent'}. Task execution stopped; existing files and prior effects are retained.` : 'Cannot verify that this task has stopped. Retry cleanup; no unrelated processes were stopped.';
299
+ task.state = stopped ? 'cancelled' : 'needs_reconciliation';
300
+ task.latestProgress = { source: 'runtime', observedAt: Date.now(), text: message };
301
+ if (stopped) {
302
+ attempt.state = 'ended';
303
+ task.activeAttemptId = undefined;
304
+ delete task.failure;
305
+ this.pool.release(task.taskId, false);
306
+ }
307
+ else {
308
+ attempt.state = 'unknown';
309
+ task.failure = { code: 'CLEANUP_UNCONFIRMED', message, observedAt: Date.now() };
310
+ }
311
+ this.store.saveAttempt(attempt);
312
+ this.store.saveTask(task, task.stateVersion);
313
+ this.store.appendEvent(task.conversationId, 'task.cleanup', { stopped, message }, task.taskId);
314
+ this.notify(task);
315
+ });
316
+ }
317
+ answer(context, taskId, questionId, answer) {
318
+ (0, store_1.boundedText)(answer);
319
+ return this.command(context, 'answer', { taskId, questionId, answer }, true, () => {
320
+ const task = this.owned(taskId, context.conversationId), version = task.stateVersion;
321
+ if (task.state !== 'waiting_input' || task.pendingQuestion?.questionId !== questionId || task.pendingQuestion.revision !== task.revision)
322
+ throw new types_1.OrchestrationError('STALE_QUESTION');
323
+ // An early user answer can be persisted, but the scheduler must still wait
324
+ // for the old attempt's true end before claiming the next revision.
325
+ const previous = this.revision(taskId, task.revision);
326
+ task.revision++;
327
+ this.store.run('INSERT INTO task_revisions VALUES(?,?,?)', taskId, task.revision, JSON.stringify({ ...previous, revision: task.revision,
328
+ answers: [...(previous.answers ?? []), { questionId, text: answer, inputId: context.inputId }], originatingInputId: context.inputId }));
329
+ task.pendingQuestion = undefined;
330
+ task.state = task.activeAttemptId ? 'interrupting' : 'queued';
331
+ this.store.saveTask(task, version);
332
+ this.store.enqueue(task.activeAttemptId ? 'interrupt' : 'schedule', `answer:${questionId}`, { taskId });
333
+ return task;
334
+ }, taskId);
335
+ }
336
+ revision(taskId, revision) {
337
+ const row = this.store.get('SELECT payload_json FROM task_revisions WHERE task_id=? AND revision=?', taskId, revision);
338
+ if (!row)
339
+ throw new types_1.OrchestrationError('REVISION_NOT_FOUND');
340
+ const rows = this.store.all('SELECT payload_json FROM task_revisions WHERE task_id=? AND revision<=? ORDER BY revision', taskId, revision);
341
+ return (0, task_directive_2.normalizeTaskRevisions)(rows.map(r => JSON.parse(String(r.payload_json))));
342
+ }
343
+ pruneWorkers() { this.pool.prune(this.config.tasks.workerIdleTtlMs); }
344
+ claim(taskId) {
345
+ return this.store.transaction(() => {
346
+ const task = this.store.task(taskId);
347
+ if (!task || task.state !== 'queued' || task.activeAttemptId)
348
+ return undefined;
349
+ if (task.continueTaskId) {
350
+ const prior = this.store.task(task.continueTaskId);
351
+ // Old snapshots retain their terminal-only behavior. New continuations
352
+ // explicitly persist the success gate; notifications grant no authority.
353
+ if (!prior || prior.conversationId !== task.conversationId) {
354
+ this.failDependency(task, 'The recorded predecessor is unavailable.');
355
+ return undefined;
356
+ }
357
+ if (!types_1.TERMINAL_TASK_STATES.has(prior.state))
358
+ return undefined;
359
+ if (task.continuationPolicy === 'after_success' && prior.state !== 'completed') {
360
+ this.failDependency(task, `Predecessor ${prior.taskId} ended as ${prior.state}${prior.failure ? `: ${prior.failure.code}: ${prior.failure.message}` : ''}. This step was not started.`);
361
+ return undefined;
362
+ }
363
+ }
364
+ const active = this.store.all('SELECT conversation_id,COUNT(*) AS n FROM tasks WHERE active_attempt_id IS NOT NULL GROUP BY conversation_id');
365
+ if (active.reduce((n, row) => n + Number(row.n), 0) >= this.config.tasks.maxConcurrentPerAgent || Number(active.find(row => row.conversation_id === task.conversationId)?.n ?? 0) >= this.config.tasks.maxConcurrentPerConversation)
366
+ return undefined;
367
+ const worker = this.pool.acquire(task, this.config.tasks.maxConcurrentPerAgent, this.config.tasks.workerIdleTtlMs);
368
+ if (!worker)
369
+ return undefined;
370
+ task.workerId = worker.workerId;
371
+ delete task.failure;
372
+ delete task.execution; // A new attempt must not look active on old telemetry.
373
+ const generation = Number(this.store.get('SELECT COALESCE(MAX(generation),0)+1 AS n FROM task_attempts WHERE task_id=?', taskId).n);
374
+ const attempt = { attemptId: (0, crypto_1.randomUUID)(), taskId, generation, revision: task.revision, ...worker, state: 'starting' };
375
+ this.store.run('INSERT INTO task_attempts VALUES(?,?,?,?,?,?)', attempt.attemptId, taskId, generation, attempt.revision, attempt.state, JSON.stringify(attempt));
376
+ task.state = 'starting';
377
+ task.activeAttemptId = attempt.attemptId;
378
+ this.store.saveTask(task, task.stateVersion);
379
+ this.store.run("UPDATE outbox SET state='completed' WHERE kind='schedule' AND json_extract(payload_json,'$.taskId')=?", taskId);
380
+ return attempt;
381
+ });
382
+ }
383
+ failDependency(task, message) {
384
+ task.state = 'failed';
385
+ task.failure = { code: 'TASK_DEPENDENCY_FAILED', message: message.slice(0, 4096), observedAt: Date.now() };
386
+ task.latestProgress = { source: 'runtime', text: task.failure.message, observedAt: task.failure.observedAt };
387
+ this.store.saveTask(task, task.stateVersion);
388
+ this.store.run("UPDATE outbox SET state='completed' WHERE kind='schedule' AND json_extract(payload_json,'$.taskId')=?", task.taskId);
389
+ this.notify(task);
390
+ }
391
+ active(attemptId, generation) {
392
+ const attempt = this.store.attempt(attemptId), task = attempt && this.store.task(attempt.taskId);
393
+ if (!attempt || !task || attempt.generation !== generation || task.activeAttemptId !== attemptId || attempt.state === 'ended' || attempt.state === 'unknown')
394
+ throw new types_1.OrchestrationError('STALE_ATTEMPT');
395
+ return { task, attempt };
396
+ }
397
+ started(attemptId, generation, identity) {
398
+ return this.store.transaction(() => {
399
+ const { task, attempt } = this.active(attemptId, generation);
400
+ if (task.state !== 'starting')
401
+ throw new types_1.OrchestrationError('STATE_CONFLICT');
402
+ attempt.state = 'running';
403
+ attempt.startedAt = Date.now();
404
+ attempt.processIdentity = identity;
405
+ task.state = 'running';
406
+ task.appliedRevision = attempt.revision;
407
+ this.store.saveAttempt(attempt);
408
+ this.store.saveTask(task, task.stateVersion);
409
+ this.store.appendEvent(task.conversationId, 'task.revision_applied', { revision: attempt.revision }, task.taskId);
410
+ return task;
411
+ });
412
+ }
413
+ workerReceipt(attemptId, actionId, kind, payload) {
414
+ const hash = (0, store_1.payloadHash)({ kind, payload });
415
+ if (!actionId)
416
+ return { hash };
417
+ (0, store_1.boundedText)(actionId, 256);
418
+ const row = this.store.get("SELECT payload_json FROM worker_events WHERE attempt_id=? AND json_extract(payload_json,'$.actionId')=?", attemptId, actionId);
419
+ if (!row)
420
+ return { hash };
421
+ const saved = JSON.parse(String(row.payload_json));
422
+ if (saved.hash !== hash)
423
+ throw new types_1.OrchestrationError('IDEMPOTENCY_CONFLICT');
424
+ return { prior: saved.result, hash };
425
+ }
426
+ saveWorkerReceipt(attemptId, actionId, kind, hash, result) {
427
+ if (!actionId)
428
+ return;
429
+ const seq = Number(this.store.get('SELECT COALESCE(MAX(local_seq),0)+1 seq FROM worker_events WHERE attempt_id=?', attemptId).seq);
430
+ this.store.run('INSERT INTO worker_events VALUES(?,?,?,?,?)', attemptId, seq, kind, JSON.stringify({ actionId, hash, result }), Date.now());
431
+ }
432
+ /** Diagnostic snapshots do not change task state/version or refresh Updated
433
+ * merely because a polling timer ran. Late observations are attempt-fenced. */
434
+ observeExecution(attemptId, generation, observation) {
435
+ this.store.transaction(() => {
436
+ let task;
437
+ try {
438
+ task = this.active(attemptId, generation).task;
439
+ }
440
+ catch {
441
+ return;
442
+ }
443
+ if (!['starting', 'running'].includes(task.state))
444
+ return;
445
+ task.execution = observation;
446
+ (0, timing_1.advanceTiming)(task, observation.observedAt);
447
+ this.store.run('UPDATE tasks SET snapshot_json=? WHERE id=? AND active_attempt_id=?', JSON.stringify(task), task.taskId, attemptId);
448
+ this.store.appendEvent(task.conversationId, 'task.execution', observation, task.taskId);
449
+ const attempt = this.store.attempt(attemptId);
450
+ if (observation.observedAt - (attempt.startedAt ?? attempt.processIdentity?.startedAt ?? task.createdAt) >= this.config.tasks.progressStaleMs) {
451
+ this.supervise(task, 'stale_progress', 'A scheduled progress update is due. Report completed steps, the current step, and any concrete dependency being awaited. Use substantive evidence; process/tool activity alone does not prove progress. Do not volunteer reassurance that the task is not stuck or is really running.', observation.observedAt);
452
+ }
453
+ });
454
+ }
455
+ supervise(task, reason, message, now = Date.now()) {
456
+ // Keep internal inspection frequent even when user-facing reports are quiet.
457
+ // The agent independently decides whether this review merits a message.
458
+ const since = task.supervision?.observedAt ?? (task.activeAttemptId ? this.store.attempt(task.activeAttemptId)?.startedAt : undefined) ?? task.createdAt;
459
+ if ((task.supervision || reason === 'stale_progress') && now - since < this.config.tasks.progressNotifyCooldownMs)
460
+ return;
461
+ task.supervision = { id: (0, crypto_1.randomUUID)(), reason, observedAt: now, message };
462
+ this.store.saveTask(task, task.stateVersion);
463
+ this.notify(task);
464
+ }
465
+ /** Called at native CLI tool boundaries. No commands, raw tool results or secrets are persisted. */
466
+ checkpoint(attemptId, generation, args) {
467
+ return this.store.transaction(() => {
468
+ const { task, attempt } = this.active(attemptId, generation);
469
+ if (task.state !== 'running' || args.sessionId !== attempt.sessionId)
470
+ return {};
471
+ if (typeof args.ackRevision === 'number' && Number.isSafeInteger(args.ackRevision) && args.ackRevision > attempt.revision && args.ackRevision <= task.revision) {
472
+ const rev = this.revision(task.taskId, args.ackRevision);
473
+ if (rev.mode !== 'when_ready')
474
+ throw new types_1.OrchestrationError('STATE_CONFLICT');
475
+ attempt.revision = rev.revision;
476
+ task.appliedRevision = rev.revision;
477
+ this.store.saveAttempt(attempt);
478
+ this.store.saveTask(task, task.stateVersion);
479
+ this.store.appendEvent(task.conversationId, 'task.revision_applied', { revision: rev.revision, boundary: 'tool' }, task.taskId);
480
+ }
481
+ if (typeof args.ackFeedback === 'string' && task.supervision?.id === args.ackFeedback && !task.supervision.deliveredAt) {
482
+ task.supervision.deliveredAt = Date.now();
483
+ this.store.run('UPDATE tasks SET snapshot_json=? WHERE id=?', JSON.stringify(task), task.taskId);
484
+ }
485
+ const latest = this.revision(task.taskId, task.revision);
486
+ const changed = task.revision > attempt.revision && latest.mode === 'when_ready';
487
+ // A later advisory must not hide an earlier unacknowledged user amendment.
488
+ const pendingAssignment = changed && this.store.all('SELECT payload_json FROM task_revisions WHERE task_id=? AND revision>? AND revision<=?', task.taskId, attempt.revision, latest.revision)
489
+ .some(row => !JSON.parse(String(row.payload_json)).guidance);
490
+ return {
491
+ ...(changed ? { revision: latest.revision, directiveKind: pendingAssignment ? 'assignment' : 'advice', directive: (0, task_directive_1.taskDirective)(this.store, task.conversationId, latest) + '\nUpdated context references: ' + JSON.stringify(latest.contextRefs) } : {}),
492
+ ...(task.supervision && !task.supervision.deliveredAt ? { feedback: task.supervision } : {}),
493
+ };
494
+ });
495
+ }
496
+ observeToolBoundary(attemptId, generation, activeTools) {
497
+ this.store.transaction(() => {
498
+ let task;
499
+ try {
500
+ task = this.active(attemptId, generation).task;
501
+ }
502
+ catch {
503
+ return;
504
+ }
505
+ if (task.state !== 'running')
506
+ return;
507
+ // Before the first process sample, record phase without inventing process diagnostics.
508
+ if (task.execution?.attemptId === attemptId)
509
+ task.execution.activeTools = activeTools;
510
+ (0, timing_1.advanceTiming)(task);
511
+ const timing = task.timing;
512
+ timing.activeToolCount = activeTools.length;
513
+ timing.attemptId = attemptId;
514
+ const phase = activeTools.length ? 'tool' : 'working';
515
+ if (timing && timing.phase !== phase) {
516
+ const now = Date.now();
517
+ if (timing.phase !== 'finished')
518
+ timing.totals[timing.phase] = (timing.totals[timing.phase] ?? 0) + Math.max(0, now - timing.since);
519
+ timing.phase = phase;
520
+ timing.since = now;
521
+ }
522
+ this.store.run('UPDATE tasks SET snapshot_json=? WHERE id=? AND active_attempt_id=?', JSON.stringify(task), task.taskId, attemptId);
523
+ });
524
+ }
525
+ observeToolResult(attemptId, generation, signature, eventId) {
526
+ this.store.transaction(() => {
527
+ let task;
528
+ try {
529
+ task = this.active(attemptId, generation).task;
530
+ }
531
+ catch {
532
+ this.repeatedTools.delete(attemptId);
533
+ return;
534
+ }
535
+ if (task.state !== 'running')
536
+ return;
537
+ const progressAt = task.latestProgress?.source === 'worker' ? task.latestProgress.observedAt : 0;
538
+ const entry = this.repeatedTools.get(attemptId);
539
+ const state = entry && entry.progressAt === progressAt ? entry : { signatures: [], seen: new Set(), progressAt };
540
+ if (state.seen.has(eventId))
541
+ return;
542
+ state.seen.add(eventId);
543
+ state.signatures.push(signature);
544
+ if (state.seen.size > 128)
545
+ state.seen.delete(state.seen.values().next().value);
546
+ if (state.signatures.length > 64)
547
+ state.signatures.shift();
548
+ this.repeatedTools.set(attemptId, state);
549
+ if (state.signatures.filter(value => value === signature).length >= this.config.tasks.repeatedToolThreshold) {
550
+ this.supervise(task, 'repeated_tools', 'The same tool input and result have repeated without a new progress report. This may be legitimate polling, not a proven stall. Report the evidence and expected wait; if the approach is not producing new evidence, change it within the authorized scope. Do not repeat side effects blindly.');
551
+ state.signatures = [];
552
+ }
553
+ });
554
+ }
555
+ progress(attemptId, generation, text, actionId, checkpoint) {
556
+ (0, store_1.boundedText)(text, 4096);
557
+ const workflow = (0, workflow_1.parseWorkflow)(checkpoint);
558
+ return this.store.transaction(() => {
559
+ const { task } = this.active(attemptId, generation);
560
+ const receipt = this.workerReceipt(attemptId, actionId, 'progress', workflow ? JSON.stringify({ text, checkpoint: workflow }) : text);
561
+ if (receipt.prior)
562
+ return receipt.prior;
563
+ if (task.state !== 'running')
564
+ throw new types_1.OrchestrationError('STATE_CONFLICT');
565
+ if (workflow)
566
+ task.workflow = (0, workflow_1.advanceWorkflow)(task.workflow, workflow, attemptId);
567
+ const substantive = task.latestProgress?.text !== text;
568
+ task.latestProgress = { text, observedAt: substantive ? Date.now() : task.latestProgress.observedAt, source: 'worker' };
569
+ this.store.saveTask(task, task.stateVersion);
570
+ const result = { accepted: true, ...(task.workflow?.warning ? { workflowWarning: task.workflow.warning } : {}) };
571
+ this.saveWorkerReceipt(attemptId, actionId, 'progress', receipt.hash, result);
572
+ return result;
573
+ });
574
+ }
575
+ requestInput(attemptId, generation, question, actionId) {
576
+ (0, store_1.boundedText)(question, 4096);
577
+ return this.store.transaction(() => {
578
+ const { task, attempt } = this.active(attemptId, generation);
579
+ const receipt = this.workerReceipt(attemptId, actionId, 'question', question);
580
+ if (receipt.prior)
581
+ return receipt.prior;
582
+ if (task.state !== 'running' || task.revision !== attempt.revision)
583
+ throw new types_1.OrchestrationError('SUPERSEDED_QUESTION');
584
+ task.state = 'waiting_input';
585
+ task.pendingQuestion = { questionId: (0, crypto_1.randomUUID)(), text: question, revision: attempt.revision };
586
+ this.store.saveTask(task, task.stateVersion);
587
+ this.notify(task);
588
+ this.saveWorkerReceipt(attemptId, actionId, 'question', receipt.hash, task);
589
+ return task;
590
+ });
591
+ }
592
+ /** Driver terminal/exit acknowledgment, never a model's unverified "done". */
593
+ finish(attemptId, generation, outcome) {
594
+ this.repeatedTools.delete(attemptId);
595
+ if (outcome.type === 'completed') {
596
+ // Match the managed-turn text limit; reject oversized output explicitly,
597
+ // never silently shorten a successful worker report to fit an event.
598
+ (0, store_1.boundedText)(outcome.result.summary, 262144);
599
+ if (Buffer.byteLength(JSON.stringify(outcome.result)) > 2 * 1024 * 1024)
600
+ throw new types_1.OrchestrationError('PAYLOAD_TOO_LARGE');
601
+ if (outcome.result.artifactIds.length > 64 || outcome.result.artifactIds.some(id => typeof id !== 'string' || id.length > 1024))
602
+ throw new types_1.OrchestrationError('INVALID_INPUT');
603
+ }
604
+ return this.store.transaction(() => {
605
+ const { task, attempt } = this.active(attemptId, generation);
606
+ if (outcome.type !== 'completed') {
607
+ attempt.failure = outcome.failure ?? (0, failure_1.taskFailure)(undefined, outcome.type === 'stopped' ? 'WORKER_STOPPED' : 'WORKER_FAILED');
608
+ task.failure = attempt.failure;
609
+ }
610
+ else {
611
+ delete task.failure;
612
+ }
613
+ if (outcome.type === 'unknown') {
614
+ attempt.state = 'unknown';
615
+ task.state = 'needs_reconciliation';
616
+ }
617
+ else {
618
+ attempt.state = 'ended';
619
+ task.activeAttemptId = undefined;
620
+ if (outcome.type === 'completed')
621
+ attempt.result = outcome.result;
622
+ if (task.state === 'cancel_requested') {
623
+ task.state = outcome.type === 'completed' && task.revision === attempt.revision ? 'completed' : 'cancelled';
624
+ }
625
+ else if (task.state === 'waiting_input' && task.pendingQuestion) { /* retain question; execution slot now free */ }
626
+ else if (task.state === 'interrupting' || task.revision > attempt.revision)
627
+ task.state = 'queued';
628
+ else
629
+ task.state = outcome.type === 'completed' ? 'completed' : 'failed';
630
+ if (task.state === 'completed' && outcome.type === 'completed')
631
+ task.result = outcome.result;
632
+ }
633
+ if (task.state === 'cancelled') {
634
+ delete task.failure;
635
+ task.latestProgress = { source: 'runtime', observedAt: Date.now(), text: `Cancelled by ${task.cancellation?.requestedBy ?? 'agent'}. Existing files and prior effects are retained.` };
636
+ }
637
+ if (outcome.type !== 'unknown')
638
+ this.pool.release(task.taskId, outcome.type === 'completed');
639
+ this.store.saveAttempt(attempt);
640
+ this.store.saveTask(task, task.stateVersion);
641
+ if (task.state === 'queued')
642
+ this.store.enqueue('schedule', `schedule:${task.taskId}:${task.stateVersion}`, { taskId: task.taskId });
643
+ else if (types_1.TERMINAL_TASK_STATES.has(task.state) || task.state === 'needs_reconciliation')
644
+ this.notify(task);
645
+ return task;
646
+ });
647
+ }
648
+ notify(task) {
649
+ const input = this.store.get('SELECT binding_id FROM conversation_inputs WHERE id=?', task.initiatingInputId);
650
+ const notificationId = (0, crypto_1.randomUUID)();
651
+ this.store.run(`INSERT INTO notifications(id,conversation_id,task_id,task_state_version,originating_binding_id) VALUES(?,?,?,?,?) ON CONFLICT(task_id,task_state_version) DO NOTHING`, notificationId, task.conversationId, task.taskId, task.stateVersion, input.binding_id);
652
+ this.store.enqueue('notification', `notification:${task.taskId}:${task.stateVersion}`, { conversationId: task.conversationId, taskId: task.taskId, notificationId });
653
+ }
654
+ /** Offline operator workflow only; not exposed through conversation tools.
655
+ * Caller holds the instance lock and has checked liveness/side effects. */
656
+ reconcile(taskId, state, evidence) {
657
+ (0, store_1.boundedText)(evidence, 4096);
658
+ if (!['queued', 'failed', 'cancelled'].includes(state))
659
+ throw new types_1.OrchestrationError('INVALID_RECONCILIATION');
660
+ return this.store.transaction(() => {
661
+ const task = this.store.task(taskId);
662
+ if (!task || task.state !== 'needs_reconciliation' || !task.activeAttemptId)
663
+ throw new types_1.OrchestrationError('RECONCILIATION_NOT_REQUIRED');
664
+ const attempt = this.store.attempt(task.activeAttemptId);
665
+ attempt.state = 'ended';
666
+ task.activeAttemptId = undefined;
667
+ task.state = state;
668
+ this.pool.release(taskId, false);
669
+ task.pendingQuestion = undefined;
670
+ task.latestProgress = { source: 'runtime', observedAt: Date.now(), text: `Operator reconciliation: ${evidence}` };
671
+ this.store.saveAttempt(attempt);
672
+ this.store.saveTask(task, task.stateVersion);
673
+ this.store.appendEvent(task.conversationId, 'task.reconciled', { taskId, state, evidence }, taskId);
674
+ if (state === 'queued')
675
+ this.store.enqueue('schedule', `schedule:${task.taskId}:${task.stateVersion}`, { taskId });
676
+ else
677
+ this.notify(task);
678
+ return task;
679
+ });
680
+ }
681
+ deferUnstarted(attemptId, generation) {
682
+ this.store.transaction(() => {
683
+ const { task, attempt } = this.active(attemptId, generation);
684
+ if (attempt.state !== 'starting' || task.state !== 'starting')
685
+ throw new types_1.OrchestrationError('STATE_CONFLICT');
686
+ attempt.state = 'ended';
687
+ task.activeAttemptId = undefined;
688
+ task.state = 'queued';
689
+ this.pool.release(task.taskId, false);
690
+ task.latestProgress = { source: 'runtime', text: 'Waiting for the shared workspace owner to release its lock.', observedAt: Date.now() };
691
+ this.store.saveAttempt(attempt);
692
+ this.store.saveTask(task, task.stateVersion);
693
+ });
694
+ }
695
+ }
696
+ exports.TaskService = TaskService;
697
+ //# sourceMappingURL=service.js.map