@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
@@ -190,6 +190,10 @@ export class DiscordModule implements ChannelModule {
190
190
  const { createDiscordClient } = await import('./client');
191
191
  this.client = await createDiscordClient(token);
192
192
  this.running = true;
193
+ if(process.env.CLAUDE_CHANNEL_CALLBACK){
194
+ const {registerCommands}=await import('./commands');
195
+ await registerCommands(this.client,token,process.env.GATEWAY_ORCHESTRATION_ENABLED==='true',process.env.GATEWAY_INTERACTIVE_CLI_ENABLED==='true').catch(err=>process.stderr.write(`discord: command registration failed: ${err}\n`));
196
+ }
193
197
  }
194
198
 
195
199
  async start(handler: InboundMessageHandler, signal: AbortSignal): Promise<void> {
@@ -296,7 +300,12 @@ export class DiscordModule implements ChannelModule {
296
300
  // button) instead of forwarding the text to the agent. Only reached after
297
301
  // gate() authorized this user, so it inherits the channel's access control.
298
302
  const cliText = (msg.content ?? '').replace(/<@!?\d+>/g, '').trim().toLowerCase();
303
+ if(/^\/(voice|voices|tasks|stop|help|orch)(?:\s|$)/.test(cliText)){
304
+ await handler({channel:'discord',accountId:this.client.user?.id??'discord',senderId:context.userId,chatId:context.channelId,chatType:isDM?'direct':'group',text:(msg.content??'').replace(/<@!?\d+>/g,'').trim(),messageId:msg.id,ts:Date.now()});
305
+ return;
306
+ }
299
307
  if (cliText === '/cli') {
308
+ if(process.env.GATEWAY_INTERACTIVE_CLI_ENABLED!=='true'){await msg.channel.send('The terminal viewer requires interactive mode.');return;}
300
309
  const base = cliCallbackBase();
301
310
  try {
302
311
  const res = await fetch(base + '/command', {
@@ -336,7 +345,7 @@ export class DiscordModule implements ChannelModule {
336
345
  const typingFileDir = path.join(this.stateDir, 'typing');
337
346
  try {
338
347
  fs.mkdirSync(typingFileDir, { recursive: true });
339
- fs.writeFileSync(path.join(typingFileDir, channelId), '');
348
+ if (process.env.GATEWAY_ORCHESTRATION_ENABLED !== 'true') fs.writeFileSync(path.join(typingFileDir, channelId), '');
340
349
  await fetch(`https://discord.com/api/v10/channels/${channelId}/typing`, {
341
350
  method: 'POST',
342
351
  headers: { Authorization: `Bot ${this.getToken()!}`, 'Content-Length': '0' },
@@ -388,7 +397,14 @@ export class DiscordModule implements ChannelModule {
388
397
  // Security mirrors the message path: the access gate must return 'deliver'.
389
398
  // discord.js client is typed as `any` (dynamic import) so we narrow locally.
390
399
  interface ButtonInteraction {
400
+ id?: string;
391
401
  isButton?: () => boolean;
402
+ isChatInputCommand?: () => boolean;
403
+ commandName?: string;
404
+ options?: {getString(name:string):string|null};
405
+ deferUpdate?: () => Promise<unknown>;
406
+ deferReply?: (options: {ephemeral:boolean}) => Promise<unknown>;
407
+ deleteReply?: () => Promise<unknown>;
392
408
  customId?: string;
393
409
  guildId?: string | null;
394
410
  channelId: string;
@@ -401,6 +417,28 @@ export class DiscordModule implements ChannelModule {
401
417
  }
402
418
  this.client.on('interactionCreate', async (interaction: ButtonInteraction) => {
403
419
  try {
420
+ const orchButton=interaction.isButton?.()&&/^orch:[a-f0-9-]{36}$/.test(interaction.customId??'');
421
+ const slash=interaction.isChatInputCommand?.();
422
+ if(orchButton||slash){
423
+ const isDM=!interaction.guildId,isThread=interaction.channel?.isThread?.()??false;
424
+ const context:DiscordMessageContext={guildId:interaction.guildId??null,channelId:interaction.channelId,threadId:isThread?interaction.channelId:null,userId:interaction.user.id,username:interaction.user.username,messageId:interaction.message?.id??'',isDM,isThread,mentionsBot:true};
425
+ const access=gate(loadAccessFn(),context,saveAccessFn,()=>randomBytes(3).toString('hex'));
426
+ if(access.action!=='deliver'){await interaction.reply({content:'Not authorized.',ephemeral:true});return;}
427
+ if(orchButton)await interaction.deferUpdate?.();else await interaction.deferReply?.({ephemeral:true});
428
+ let text=orchButton?`/orch ${interaction.customId!.slice(5)}`:`/${interaction.commandName}`;
429
+ if(slash){
430
+ const name=interaction.commandName;
431
+ const arg=interaction.options?.getString(name==='voice'?'mode':name==='ask'?'question':'name');
432
+ if(name==='ask')text=arg??'';else if(arg)text+=' '+arg;
433
+ if(name==='cli'){
434
+ const channel=await this.client.channels.fetch(interaction.channelId);
435
+ await handleDiscordMessage({id:randomBytes(12).toString('hex'),content:'/cli',author:{id:interaction.user.id,username:interaction.user.username,bot:false},guild:interaction.guildId?{id:interaction.guildId}:null,guildId:interaction.guildId,channelId:interaction.channelId,channel,mentions:{has:()=>true}} as any);
436
+ await interaction.deleteReply?.();return;
437
+ }
438
+ }
439
+ await handler({channel:'discord',accountId:interaction.client.user?.id??'discord',senderId:interaction.user.id,chatId:interaction.channelId,chatType:isDM?'direct':'group',text,messageId:interaction.id??randomBytes(12).toString('hex'),controlMessageId:orchButton?interaction.message?.id:undefined,ts:Date.now()});
440
+ if(slash)await interaction.deleteReply?.();return;
441
+ }
404
442
  if (!interaction.isButton?.()) return;
405
443
 
406
444
  // `/cli` approve/deny — unlock (or reject) a pending terminal-viewer
@@ -518,7 +556,7 @@ export class DiscordModule implements ChannelModule {
518
556
  const typingFileDir = path.join(this.stateDir, 'typing');
519
557
  try {
520
558
  fs.mkdirSync(typingFileDir, { recursive: true });
521
- fs.writeFileSync(path.join(typingFileDir, channelId), '');
559
+ if (process.env.GATEWAY_ORCHESTRATION_ENABLED !== 'true') fs.writeFileSync(path.join(typingFileDir, channelId), '');
522
560
  } catch {}
523
561
 
524
562
  const inbound: InboundMessage = {
@@ -621,6 +659,8 @@ export class DiscordModule implements ChannelModule {
621
659
  }
622
660
 
623
661
  private async processTypingSignals(typingDir: string, token: string): Promise<void> {
662
+ // Managed activity is derived from durable Agent/Worker state; stale legacy files are not work.
663
+ if (process.env.GATEWAY_ORCHESTRATION_ENABLED === 'true') return;
624
664
  let files: string[];
625
665
  try { files = fs.readdirSync(typingDir); } catch { return; }
626
666
 
@@ -7,8 +7,10 @@
7
7
 
8
8
  import { DiscordModule } from './module';
9
9
  import type { InboundMessage } from '../../types';
10
+ import { ReceiverSpool } from '../receiver-spool';
10
11
 
11
12
  const CALLBACK_URL = process.env.CLAUDE_CHANNEL_CALLBACK;
13
+ const spool = process.env.GATEWAY_ORCHESTRATION_INGRESS_DIR && CALLBACK_URL ? new ReceiverSpool(process.env.GATEWAY_ORCHESTRATION_INGRESS_DIR, CALLBACK_URL) : undefined;
12
14
  if (!CALLBACK_URL) {
13
15
  process.stderr.write('discord receiver: CLAUDE_CHANNEL_CALLBACK required\n');
14
16
  process.exit(1);
@@ -30,6 +32,14 @@ async function postCallback(inbound: InboundMessage): Promise<void> {
30
32
  if (inbound.attachmentFileId) {
31
33
  meta['attachment_file_id'] = inbound.attachmentFileId;
32
34
  }
35
+ if(inbound.attachments?.length)meta.attachments_json=JSON.stringify(inbound.attachments.map(a=>({ref:a.url,name:a.name,kind:a.kind,quoted:a.quoted})));
36
+ if(inbound.replyToMessageId)meta.replied_message_id=inbound.replyToMessageId;
37
+ if(inbound.repliedText)meta.replied_text=inbound.repliedText;
38
+ if(inbound.repliedSender)meta.replied_user=inbound.repliedSender;
39
+ if(inbound.threadId)meta.thread_ts=inbound.threadId;
40
+ if(inbound.attachmentKind)meta.attachment_kind=inbound.attachmentKind;
41
+ if(inbound.controlMessageId)meta.control_message_id=inbound.controlMessageId;
42
+ if (spool && !/^\/(voice|voices|tasks|stop|orch)(?:\s|$)/.test(inbound.text??'')) { spool.enqueue({ content: inbound.text ?? '', meta }); return; }
33
43
 
34
44
  try {
35
45
  await fetch(CALLBACK_URL!, {
@@ -108,7 +108,10 @@ export interface DiscordMessage {
108
108
  parentId?: string | null;
109
109
  };
110
110
  createdTimestamp: number;
111
- attachments: { first(): { url: string } | undefined };
111
+ reference?: {messageId?:string;channelId?:string};
112
+ fetchReference?(): Promise<DiscordMessage>;
113
+ flags?: number | {has(bit:number):boolean};
114
+ attachments: { first(): { url: string; contentType?: string | null; name?: string } | undefined; values?(): IterableIterator<{url:string;contentType?:string|null;name?:string}> };
112
115
  client: { user: { id: string } | null };
113
116
  startThread(options: { name: string; autoArchiveDuration: number }): Promise<{ id: string }>;
114
117
  }
@@ -735,7 +735,9 @@ export class ImageModule implements ToolModule {
735
735
  files,
736
736
  ...(artifacts ? { artifacts } : {}),
737
737
  ...(droppedImages > 0 ? { dropped_images: droppedImages } : {}),
738
- note: 'Image saved. Deliver it to the user with your channel delivery tool — api_reply/reply (files: [...]), or line_image on LINE. Do NOT open/Read the file to inspect it first; attach it and answer briefly.'
738
+ note: (process.env.GATEWAY_ORCHESTRATION_ROLE === 'worker'
739
+ ? 'Image saved. Call task_stage_file for each output path, then finish this task. The agent orchestration engine owns user-facing delivery.'
740
+ : 'Image saved. Deliver it to the user with your channel delivery tool — api_reply/reply (files: [...]), or line_image on LINE. Do NOT open/Read the file to inspect it first; attach it and answer briefly.')
739
741
  + (model ? ` Mention which model made it (${model}).` : '')
740
742
  + (artifacts ? ' To edit this image later, reference it via its artifact_ref (e.g. image: "artifact:...").' : '')
741
743
  + (droppedImages > 0 ? ` (${droppedImages} extra image(s) beyond the cap were not saved)` : ''),
@@ -0,0 +1,28 @@
1
+ import { test, expect } from 'bun:test';
2
+ import { mkdtempSync, readdirSync, rmSync, readFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { ReceiverSpool } from './receiver-spool';
6
+
7
+ test('receiver restart retains unacknowledged input and removes it only after gateway acceptance', async () => {
8
+ const root = mkdtempSync(join(tmpdir(), 'receiver-spool-'));
9
+ let fail = true;
10
+ const delivered: unknown[] = [];
11
+ const request = (async (_url: string | URL | Request, options?: RequestInit) => {
12
+ delivered.push(JSON.parse(String(options?.body)));
13
+ return new Response('', { status: fail ? 503 : 200 });
14
+ }) as typeof fetch;
15
+ let spool = new ReceiverSpool(root, 'http://fixture.invalid/channel', request);
16
+ try {
17
+ const input = { content: 'hello', meta: { chat_id: 'original', message_id: '1' } };
18
+ spool.enqueue(input);
19
+ await new Promise(resolve => setTimeout(resolve, 10));
20
+ const file = readdirSync(root).find(file => file.endsWith('.json'))!;
21
+ expect(JSON.parse(readFileSync(join(root, file), 'utf8'))).toEqual(input);
22
+ spool.close(); fail = false;
23
+ spool = new ReceiverSpool(root, 'http://fixture.invalid/channel', request);
24
+ await new Promise(resolve => setTimeout(resolve, 10));
25
+ expect(readdirSync(root)).toEqual([]);
26
+ expect(delivered.at(-1)).toEqual(input);
27
+ } finally { spool.close(); rmSync(root, { recursive: true, force: true }); }
28
+ });
@@ -0,0 +1,56 @@
1
+ import { mediaGroupKey, mergeMediaGroup, type ChannelInput } from './telegram/media-group';
2
+ import { createHash, randomUUID } from 'node:crypto';
3
+ import { mkdirSync, readdirSync, openSync, closeSync, writeFileSync, fsyncSync, renameSync, readFileSync, unlinkSync, statSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+
6
+ /** Receiver-local handoff journal. Persist before returning to the platform
7
+ * client; only remove after the gateway confirms its SQLite admission. */
8
+ export class ReceiverSpool {
9
+ private active = false;
10
+ private readonly timer: ReturnType<typeof setInterval>;
11
+ constructor(private readonly directory: string, private readonly callback: string, private readonly request: typeof fetch = fetch, private readonly mediaGroupWaitMs = 2000) {
12
+ mkdirSync(directory, { recursive: true, mode: 0o700 });
13
+ this.timer = setInterval(() => { void this.flush(); }, 1000); this.timer.unref();
14
+ void this.flush();
15
+ }
16
+ enqueue(input: unknown): void {
17
+ const group=mediaGroupKey(input as ChannelInput);
18
+ if(group){
19
+ let prior:ChannelInput|undefined;
20
+ try{prior=JSON.parse(readFileSync(join(this.directory,`${group}.json`),'utf8'));}catch{}
21
+ input=mergeMediaGroup(prior,input as ChannelInput);
22
+ }
23
+ const payload = JSON.stringify(input);
24
+ if (Buffer.byteLength(payload) > 131072) throw new Error('Ingress payload too large');
25
+ if (readdirSync(this.directory).filter(file => file.endsWith('.json')).length >= 1000) throw new Error('Ingress spool full');
26
+ const key = group ?? createHash('sha256').update(payload).digest('hex');
27
+ const temporary = join(this.directory, `${key}.${randomUUID()}.tmp`);
28
+ const descriptor = openSync(temporary, 'wx', 0o600);
29
+ try { writeFileSync(descriptor, payload); fsyncSync(descriptor); } finally { closeSync(descriptor); }
30
+ renameSync(temporary, join(this.directory, `${key}.json`));
31
+ this.syncDirectory();
32
+ void this.flush();
33
+ }
34
+ private syncDirectory(): void {
35
+ const descriptor = openSync(this.directory, 'r');
36
+ try { fsyncSync(descriptor); } finally { closeSync(descriptor); }
37
+ }
38
+ async flush(): Promise<void> {
39
+ if (this.active) return;
40
+ this.active = true;
41
+ try {
42
+ const files = readdirSync(this.directory).filter(file => /^[a-f0-9]{64}\.json$/.test(file)).map(file => ({ file, created: statSync(join(this.directory, file)).mtimeMs })).sort((a, b) => a.created - b.created);
43
+ for (const { file } of files.slice(0, 100)) {
44
+ const location = join(this.directory, file);
45
+ const payload=readFileSync(location,'utf8');
46
+ const input=JSON.parse(payload) as ChannelInput;
47
+ if(mediaGroupKey(input)&&Date.now()-statSync(location).mtimeMs<this.mediaGroupWaitMs)continue;
48
+ const response = await this.request(this.callback, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: payload, signal: AbortSignal.timeout(10000) });
49
+ if (!response.ok) break;
50
+ if(readFileSync(location,'utf8')===payload){unlinkSync(location); this.syncDirectory();}
51
+ }
52
+ } catch { /* persisted message is retried on next tick or process restart */ }
53
+ finally { this.active = false; }
54
+ }
55
+ close(): void { clearInterval(this.timer); }
56
+ }
@@ -28,7 +28,15 @@ export class ShareFileModule implements ToolModule {
28
28
  }
29
29
 
30
30
  getTools(): McpToolDefinition[] {
31
- return shareFileToolDefs;
31
+ if (process.env.GATEWAY_ORCHESTRATION_ROLE !== 'worker') return shareFileToolDefs;
32
+ return shareFileToolDefs.map(tool => ({
33
+ ...tool,
34
+ description: tool.description + ' In a task, use the original absolute file path in the active task workspace, a supplied input attachment or this session’s media directory. The gateway stages it automatically; do not copy it to the agent-wide media root. Describe this as creating a link (Thai: สร้างลิงก์).',
35
+ inputSchema: { ...shareFileInputSchema, properties: { ...shareFileInputSchema.properties,
36
+ path: { type: 'string', description: 'Original absolute file path in the active task workspace or session media, or artifact:<id>.' },
37
+ paths: { type: 'array', items: { type: 'string' }, description: 'Up to 5 authorized absolute file paths or artifact refs.' },
38
+ } },
39
+ }));
32
40
  }
33
41
 
34
42
  async handleTool(name: string, args: Record<string, unknown>): Promise<McpToolResult> {
@@ -71,6 +71,7 @@ export class ShareClientError extends Error {
71
71
  * is absent the private mint endpoint is not mounted and calls fail closed.
72
72
  */
73
73
  export function shareBridgeEnabled(): boolean {
74
+ if (process.env.GATEWAY_ORCHESTRATION_ROLE === 'worker' && process.env.GATEWAY_ORCHESTRATION_MEDIA === 'true' && process.env.GATEWAY_ORCHESTRATION_TICKET_FILE) return true;
74
75
  return (
75
76
  !!process.env.GATEWAY_API_URL &&
76
77
  !!process.env.GATEWAY_API_KEY &&
@@ -88,6 +89,24 @@ async function callGateway(
88
89
  pathname: string,
89
90
  body?: Record<string, unknown>,
90
91
  ): Promise<{ status: number; json: Record<string, unknown> }> {
92
+ if (process.env.GATEWAY_ORCHESTRATION_ROLE === 'worker' && process.env.GATEWAY_ORCHESTRATION_TICKET_FILE) {
93
+ const { readFile } = await import('node:fs/promises');
94
+ const ticket = JSON.parse(await readFile(process.env.GATEWAY_ORCHESTRATION_TICKET_FILE, 'utf8'));
95
+ const response = await fetch(ticket.url, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${ticket.token}` },
96
+ body: JSON.stringify({ tool: 'task_share_call', action_id: crypto.randomUUID(), args: { method, pathname, body } }), signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
97
+ if (!response.ok) {
98
+ const failure = await response.json().catch(() => ({})) as Record<string, unknown> | null;
99
+ // The bridge uses {error: CODE}; retain that cause instead of treating
100
+ // path validation, stale attempts and unavailable configuration alike.
101
+ const code = typeof failure?.error === 'string' && /^[A-Z][A-Z0-9_]{0,79}$/.test(failure.error)
102
+ ? failure.error : 'share_scope_denied';
103
+ const error = code === 'ARTIFACT_PATH_DENIED'
104
+ ? 'File is outside this task scope. Use the original file’s absolute path in the active task workspace, a supplied input attachment, or this session’s media directory. Do not copy it to the agent-wide media root. The gateway stages authorized files automatically.'
105
+ : code === 'share_scope_denied' ? 'Scoped share request denied' : code;
106
+ return { status: response.status, json: { error, code } };
107
+ }
108
+ return await response.json() as { status: number; json: Record<string, unknown> };
109
+ }
91
110
  const res = await fetch(`${apiBase()}${pathname}`, {
92
111
  method,
93
112
  headers: {
@@ -0,0 +1,35 @@
1
+ // MCP sources are published, src/ is not. Share the compiled schema so an
2
+ // installed package has the same inventory as a development checkout.
3
+ import { WORKFLOW_SCHEMA } from '../../../dist/orchestration/workflow.js';
4
+ import type { McpToolDefinition, McpToolResult } from '../../types';
5
+
6
+ const schema = (properties: Record<string, unknown>, required: string[]) => ({ type: 'object', properties, required, additionalProperties: false });
7
+ const text = { type: 'string' };
8
+ export const AGENT_TASK_TOOLS: McpToolDefinition[] = [
9
+ { name: 'capabilities_list', description: 'Discover all capabilities this agent can offer: installed/shared/native skills, gateway MCP tools and enabled connector/plugin MCP tools, including tools executed only by workers. Read metadata only; never executes a tool or grants permissions. Use query to find relevant tools before assigning work. Follow next_offset until null when the user asks for the complete list, passing catalog_version from the first page. On CAPABILITY_CATALOG_CHANGED restart from offset 0. Report unavailable discovery honestly; do not confuse your own restricted callable tools with the capabilities of the agent as a whole.', inputSchema: schema({query:text,catalog_version:text,offset:{type:'integer',minimum:0}},[]) },
10
+ { name: 'conversation_intake', description: 'Prepare executable work, incomplete materials, or an amendment to an existing task. Do not call this for greetings, introductions, casual conversation or questions you can answer directly; answer those normally once. When semantic intake is enabled, acknowledge before work mutations. Incomplete material is inspected now; the gateway asks the supplied clarification after the configured silence interval, not on every item.',
11
+ inputSchema: schema({mode:{type:'string',enum:['ready','wait','update']},acknowledgement:{type:'string',description:'A brief contextual message addressed directly to the user about the work you will do. Immediately displayed and spoken aloud. Never include private classification, reasoning, or instructions to yourself.'},preparation:text,clarification:text,task_id:text},['mode']) },
12
+ { name: 'task_spawn', description: 'Durably queue a task for an independent worker. Returns after commit without waiting for worker startup or completion.',
13
+ inputSchema: schema({ title: text, instructions: text, target_profile: text, spoken_acknowledgement: { type: 'string', description: 'Required for live voice: a short natural response in the user language explaining the specific work you are about to do. Describe the specific user request as your own task, in the voice of your existing persona; do not announce handing it to a worker or use a generic acknowledgement. Speak as the person doing the work; avoid Thai delegation phrases such as สั่งเช็คแล้ว, สั่งไปแล้ว or ส่งให้ตรวจแล้ว. Describe queued work as accepted/to do next, and only say it is running when that state is confirmed. Do not claim completion. The gateway manages playback and channel text-before-voice ordering.' }, skill_name: { type: 'string', description: 'Exact installed gateway or discovered Claude Code runtime skill name for skill-worker. Native skills are invoked directly by the CLI; shared/workspace skills are supplied with their resources. Never supply a file path.' }, skill_args: { type: 'string', description: 'Arguments for the installed skill; required with skill_name.' }, continue_task_id: { type: 'string', description: 'Prior task ID in this conversation for related follow-up work. Reuses its worker session when compatible; waits for success by default. Queue every authorized dependent step now, using each returned task ID for the next step. Omit for independent work.' }, continuation_policy: { type: 'string', enum: ['after_success', 'after_terminal'], description: 'With continue_task_id: after_success (default) starts only after the predecessor succeeds; otherwise fails without executing. Use after_terminal only for explicitly authorized recovery/inspection that must run after failure or cancellation.' }, context_refs: { type: 'array', items: text, description: 'Only orchestration input IDs, authorized attachment refs or task artifact IDs. Put project filenames in instructions instead.' } }, ['title', 'instructions', 'target_profile']) },
14
+ { name: 'task_status', description: 'Read the task index in this conversation without waiting. Pass task_id to retrieve the complete stored result and evidence before discussing an earlier task. An index entry is not a partial worker report.', inputSchema: schema({ task_id: text }, []) },
15
+ { name: 'task_cancel', description: 'Request cancellation, including needs_reconciliation cleanup. cancel_requested is not proof of termination. Existing files are retained. Set replaced_by_task_id only for a known replacement task, never infer from similar titles.', inputSchema: schema({ task_id: text, replaced_by_task_id: text }, ['task_id']) },
16
+ { name: 'task_update', description: 'Accept a revised task instruction. applied_revision changes only when the worker accepts it.', inputSchema: schema({ task_id: text, expected_revision: { type: 'integer', minimum: 1 }, instruction: text, mode: { type: 'string', enum: ['when_ready', 'interrupt_and_resume'] } }, ['task_id', 'expected_revision', 'instruction', 'mode']) },
17
+ { name: 'task_answer', description: 'Answer the matching pending question on a task.', inputSchema: schema({ task_id: text, question_id: text, answer: text }, ['task_id', 'question_id', 'answer']) },
18
+ ];
19
+ export const WORKER_REPORT_TOOLS: McpToolDefinition[] = [
20
+ { name: 'task_memory_append', description: 'Append an explicitly requested memory note for a channel task. API tasks cannot write memory. Files are restricted to MEMORY.md, USER.md, or memory/<name>.md. Retains existing content and deduplicates retries.', inputSchema: schema({ note: text, path: text }, ['note']) },
21
+ { name: 'task_stage_file', description: 'Stage a finished image or document for the user. The orchestration attaches it to the next completed agent response after this task succeeds, using the original destination. This tool does not send to a channel. Call once per output file. For an image returned by an MCP tool (such as a remote browser screenshot), omit path to use the latest captured image in this attempt, or pass source_tool_call_id to select its tool call. The gateway saves the actual image bytes; never invent a screenshot filename. For an existing local file supply path.', inputSchema: schema({ path: text, source_tool_call_id: text, caption: text }, []) },
22
+ { name: 'task_report_progress', description: 'Report factual progress internally. At phase changes include a checkpoint with phase, evidenceVersion, checks, findings and nextAction. This does not send a user message.', inputSchema: schema({ text, checkpoint: WORKFLOW_SCHEMA }, ['text']) },
23
+ { name: 'task_request_input', description: 'Ask the user for information required by your task, then end this turn immediately.', inputSchema: schema({ question: text }, ['question']) },
24
+ ];
25
+
26
+ export async function callTaskBridge(tool: string, args: Record<string, unknown>, requestId: string, signal: AbortSignal): Promise<McpToolResult> {
27
+ // Rotated by the gateway at each decision/attempt boundary. A loaded token is
28
+ // immutable for this request; late requests cannot borrow the next decision.
29
+ const { readFile } = await import('node:fs/promises');
30
+ const scope = JSON.parse(await readFile(process.env.GATEWAY_ORCHESTRATION_TICKET_FILE!, 'utf8')) as { url: string; token: string };
31
+ const response = await fetch(scope.url, { method: 'POST', signal, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${scope.token}` },
32
+ body: JSON.stringify({ tool, args, action_id: requestId }) });
33
+ const body = await response.text();
34
+ return { content: [{ type: 'text', text: body }], ...(response.ok ? {} : { isError: true }) };
35
+ }
@@ -0,0 +1,21 @@
1
+ import { createHash } from 'node:crypto';
2
+ export type ChannelInput = {content:string;meta:Record<string,string>};
3
+ export function mediaGroupKey(input: ChannelInput): string | undefined {
4
+ const m=input?.meta;
5
+ return m?.media_group_id ? createHash('sha256').update(JSON.stringify([m.chat_id,m.user_id,m.message_thread_id??'',m.media_group_id])).digest('hex') : undefined;
6
+ }
7
+ /** Telegram albums arrive as separate updates. Keep the native group intact. */
8
+ export function mergeMediaGroup(prior:ChannelInput|undefined,input:ChannelInput):ChannelInput {
9
+ const ids:string[]=prior?JSON.parse(prior.meta.message_ids_json):[];
10
+ if(ids.includes(input.meta.message_id))return prior!;
11
+ if(ids.length>=10)throw Error('Telegram media group exceeds 10 items');
12
+ const parts:Array<{id:string;caption:string;ref?:string;path?:string;name?:string}> = prior?JSON.parse(prior.meta.media_group_parts_json):[];
13
+ parts.push({id:input.meta.message_id,caption:input.meta.media_caption??'',ref:input.meta.attachment_file_id,path:input.meta.image_path,name:input.meta.attachment_name});
14
+ parts.sort((a,b)=>Number(a.id)-Number(b.id));
15
+ const meta:Record<string,string>={...(prior?.meta??input.meta),media_group_id:input.meta.media_group_id,message_id:parts[0]!.id,
16
+ message_ids_json:JSON.stringify(parts.map(p=>p.id)),media_group_parts_json:JSON.stringify(parts),
17
+ attachments_json:JSON.stringify(parts.map(({ref,path,name})=>({ref,path,name})))};
18
+ // Album files must not turn a mixed album into a single-file voice-note turn.
19
+ delete meta.attachment_file_id;delete meta.image_path;delete meta.attachment_kind;
20
+ return {content:parts.map(p=>p.caption).filter(Boolean).join('\n\n')||'[Media album attached]',meta};
21
+ }