@poolzin/pool-bot 2026.1.39 → 2026.2.1

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 (511) hide show
  1. package/assets/chrome-extension/README.md +3 -3
  2. package/assets/chrome-extension/background.js +5 -5
  3. package/assets/chrome-extension/manifest.json +3 -3
  4. package/assets/chrome-extension/options.html +4 -4
  5. package/assets/chrome-extension/options.js +1 -1
  6. package/dist/acp/client.js +3 -3
  7. package/dist/acp/types.js +1 -1
  8. package/dist/agents/agent-paths.js +3 -3
  9. package/dist/agents/auth-profiles/paths.js +3 -3
  10. package/dist/agents/bash-tools.exec.js +76 -25
  11. package/dist/agents/cli-runner/helpers.js +10 -12
  12. package/dist/agents/cli-runner.js +2 -2
  13. package/dist/agents/cloudflare-ai-gateway.js +31 -0
  14. package/dist/agents/compaction.js +16 -2
  15. package/dist/agents/context-window-guard.js +13 -10
  16. package/dist/agents/context.js +4 -4
  17. package/dist/agents/docs-path.js +1 -1
  18. package/dist/agents/identity.js +47 -7
  19. package/dist/agents/memory-search.js +25 -8
  20. package/dist/agents/minimax-vlm.js +1 -1
  21. package/dist/agents/model-auth.js +12 -1
  22. package/dist/agents/model-catalog.js +4 -4
  23. package/dist/agents/model-selection.js +31 -4
  24. package/dist/agents/models-config.js +3 -3
  25. package/dist/agents/models-config.providers.js +147 -39
  26. package/dist/agents/pi-embedded-block-chunker.js +117 -42
  27. package/dist/agents/pi-embedded-helpers/errors.js +183 -78
  28. package/dist/agents/pi-embedded-helpers/openai.js +1 -1
  29. package/dist/agents/pi-embedded-helpers.js +1 -1
  30. package/dist/agents/pi-embedded-runner/compact.js +9 -8
  31. package/dist/agents/pi-embedded-runner/model.js +63 -4
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +27 -17
  33. package/dist/agents/pi-embedded-runner/run.js +203 -50
  34. package/dist/agents/pi-embedded-runner/system-prompt.js +10 -2
  35. package/dist/agents/pi-embedded-runner/tool-result-truncation.js +275 -0
  36. package/dist/agents/pi-embedded-runner/utils.js +1 -1
  37. package/dist/agents/pi-embedded-subscribe.js +118 -29
  38. package/dist/agents/pi-model-discovery.js +10 -0
  39. package/dist/agents/pi-tool-definition-adapter.js +50 -9
  40. package/dist/agents/pi-tools.before-tool-call.js +67 -0
  41. package/dist/agents/pi-tools.js +20 -10
  42. package/dist/agents/pi-tools.read.js +2 -2
  43. package/dist/agents/poolbot-tools.js +15 -10
  44. package/dist/agents/sandbox-paths.js +31 -0
  45. package/dist/agents/session-file-repair.js +83 -0
  46. package/dist/agents/session-tool-result-guard.js +94 -15
  47. package/dist/agents/session-transcript-repair.js +68 -0
  48. package/dist/agents/shell-utils.js +51 -0
  49. package/dist/agents/skills/bundled-context.js +23 -0
  50. package/dist/agents/skills/bundled-dir.js +41 -7
  51. package/dist/agents/skills/frontmatter.js +1 -1
  52. package/dist/agents/skills/workspace.js +2 -2
  53. package/dist/agents/skills-install.js +60 -23
  54. package/dist/agents/subagent-announce.js +79 -34
  55. package/dist/agents/system-prompt.js +28 -4
  56. package/dist/agents/together-models.js +127 -0
  57. package/dist/agents/tool-images.js +1 -1
  58. package/dist/agents/tool-policy.conformance.js +14 -0
  59. package/dist/agents/tool-policy.js +25 -1
  60. package/dist/agents/tools/browser-tool.js +3 -3
  61. package/dist/agents/tools/cron-tool.js +166 -19
  62. package/dist/agents/tools/discord-actions-presence.js +78 -0
  63. package/dist/agents/tools/image-tool.js +2 -2
  64. package/dist/agents/tools/memory-tool.js +93 -5
  65. package/dist/agents/tools/message-tool.js +56 -2
  66. package/dist/agents/tools/sessions-history-tool.js +69 -1
  67. package/dist/agents/tools/web-search.js +211 -42
  68. package/dist/agents/usage.js +23 -1
  69. package/dist/agents/workspace-run.js +67 -0
  70. package/dist/agents/workspace-templates.js +44 -0
  71. package/dist/auto-reply/command-auth.js +121 -6
  72. package/dist/auto-reply/commands-registry.data.js +1 -1
  73. package/dist/auto-reply/envelope.js +50 -72
  74. package/dist/auto-reply/reply/commands-compact.js +1 -0
  75. package/dist/auto-reply/reply/commands-context-report.js +3 -2
  76. package/dist/auto-reply/reply/commands-context.js +1 -0
  77. package/dist/auto-reply/reply/commands-models.js +107 -60
  78. package/dist/auto-reply/reply/commands-ptt.js +171 -0
  79. package/dist/auto-reply/reply/commands-session.js +2 -2
  80. package/dist/auto-reply/reply/get-reply-run.js +16 -5
  81. package/dist/auto-reply/reply/groups.js +1 -1
  82. package/dist/auto-reply/reply/inbound-context.js +9 -1
  83. package/dist/auto-reply/reply/inbound-meta.js +130 -0
  84. package/dist/auto-reply/reply/model-selection.js +3 -3
  85. package/dist/auto-reply/reply/untrusted-context.js +15 -0
  86. package/dist/auto-reply/status.js +1 -1
  87. package/dist/auto-reply/thinking.js +88 -43
  88. package/dist/browser/bridge-server.js +13 -0
  89. package/dist/browser/cdp.helpers.js +38 -24
  90. package/dist/browser/client-fetch.js +51 -8
  91. package/dist/browser/config.js +2 -11
  92. package/dist/browser/extension-relay.js +104 -43
  93. package/dist/browser/pw-ai.js +1 -1
  94. package/dist/browser/pw-session.js +143 -8
  95. package/dist/browser/pw-tools-core.interactions.js +125 -27
  96. package/dist/browser/pw-tools-core.responses.js +1 -1
  97. package/dist/browser/pw-tools-core.state.js +1 -1
  98. package/dist/browser/routes/agent.act.js +86 -41
  99. package/dist/browser/routes/dispatcher.js +4 -4
  100. package/dist/browser/screenshot.js +1 -1
  101. package/dist/browser/server-context.js +2 -2
  102. package/dist/browser/server.js +13 -0
  103. package/dist/build-info.json +3 -3
  104. package/dist/canvas-host/a2ui.js +3 -3
  105. package/dist/channels/plugins/catalog.js +2 -2
  106. package/dist/channels/plugins/onboarding/imessage.js +1 -1
  107. package/dist/channels/plugins/onboarding/signal.js +1 -1
  108. package/dist/channels/plugins/onboarding/slack.js +4 -4
  109. package/dist/channels/plugins/onboarding/whatsapp.js +3 -3
  110. package/dist/channels/plugins/pairing-message.js +1 -1
  111. package/dist/channels/reply-prefix.js +8 -1
  112. package/dist/cli/browser-cli-extension.js +2 -2
  113. package/dist/cli/cron-cli/register.cron-add.js +61 -40
  114. package/dist/cli/cron-cli/register.cron-edit.js +60 -34
  115. package/dist/cli/cron-cli/shared.js +56 -41
  116. package/dist/cli/dns-cli.js +26 -14
  117. package/dist/cli/docs-cli.js +1 -1
  118. package/dist/cli/gateway-cli/dev.js +1 -1
  119. package/dist/cli/gateway-cli/register.js +37 -19
  120. package/dist/cli/memory-cli.js +30 -20
  121. package/dist/cli/nodes-cli/register.canvas.js +1 -1
  122. package/dist/cli/parse-bytes.js +37 -0
  123. package/dist/cli/plugins-cli.js +1 -1
  124. package/dist/cli/run-main.js +2 -2
  125. package/dist/cli/security-cli.js +1 -1
  126. package/dist/cli/tagline.js +1 -1
  127. package/dist/cli/update-cli.js +173 -52
  128. package/dist/cli/webhooks-cli.js +5 -5
  129. package/dist/commands/agent.js +1 -0
  130. package/dist/commands/agents.commands.add.js +1 -1
  131. package/dist/commands/auth-choice.apply.api-providers.js +305 -17
  132. package/dist/commands/auth-choice.apply.js +4 -1
  133. package/dist/commands/auth-choice.apply.plugin-provider.js +2 -2
  134. package/dist/commands/auth-choice.apply.xai.js +63 -0
  135. package/dist/commands/auth-choice.preferred-provider.js +7 -1
  136. package/dist/commands/configure.wizard.js +1 -1
  137. package/dist/commands/dashboard.js +1 -1
  138. package/dist/commands/docs.js +1 -1
  139. package/dist/commands/doctor-config-flow.js +61 -5
  140. package/dist/commands/doctor-gateway-services.js +3 -3
  141. package/dist/commands/doctor-state-migrations.js +1 -1
  142. package/dist/commands/doctor-update.js +3 -3
  143. package/dist/commands/doctor.js +1 -1
  144. package/dist/commands/health.js +1 -1
  145. package/dist/commands/model-allowlist.js +29 -0
  146. package/dist/commands/model-picker.js +2 -1
  147. package/dist/commands/models/list.probe.js +2 -2
  148. package/dist/commands/models/list.registry.js +4 -4
  149. package/dist/commands/models/list.status-command.js +44 -24
  150. package/dist/commands/models/shared.js +15 -0
  151. package/dist/commands/onboard-auth.config-core.js +366 -28
  152. package/dist/commands/onboard-auth.credentials.js +71 -9
  153. package/dist/commands/onboard-auth.js +3 -3
  154. package/dist/commands/onboard-auth.models.js +26 -24
  155. package/dist/commands/onboard-custom.js +384 -0
  156. package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +35 -0
  157. package/dist/commands/onboard-non-interactive/local/auth-choice.js +146 -9
  158. package/dist/commands/onboard-skills.js +63 -38
  159. package/dist/commands/openai-model-default.js +41 -0
  160. package/dist/commands/status-all/report-lines.js +1 -1
  161. package/dist/commands/status.command.js +1 -1
  162. package/dist/commands/uninstall.js +3 -3
  163. package/dist/compat/legacy-names.js +1 -1
  164. package/dist/config/defaults.js +3 -2
  165. package/dist/config/io.js +3 -3
  166. package/dist/config/paths.js +136 -35
  167. package/dist/config/plugin-auto-enable.js +21 -5
  168. package/dist/config/redact-snapshot.js +153 -0
  169. package/dist/config/schema.field-metadata.js +590 -0
  170. package/dist/config/schema.js +3 -3
  171. package/dist/config/sessions/store.js +291 -23
  172. package/dist/config/types.memory.js +1 -0
  173. package/dist/config/version.js +4 -4
  174. package/dist/config/zod-schema.agent-defaults.js +3 -0
  175. package/dist/config/zod-schema.agent-runtime.js +13 -2
  176. package/dist/config/zod-schema.providers-core.js +142 -0
  177. package/dist/config/zod-schema.session.js +3 -0
  178. package/dist/cron/delivery.js +57 -0
  179. package/dist/cron/isolated-agent/delivery-target.js +18 -3
  180. package/dist/cron/isolated-agent/helpers.js +22 -5
  181. package/dist/cron/isolated-agent/run.js +171 -63
  182. package/dist/cron/isolated-agent/session.js +2 -0
  183. package/dist/cron/normalize.js +356 -28
  184. package/dist/cron/parse.js +10 -5
  185. package/dist/cron/run-log.js +35 -10
  186. package/dist/cron/schedule.js +41 -6
  187. package/dist/cron/service/jobs.js +208 -35
  188. package/dist/cron/service/ops.js +72 -16
  189. package/dist/cron/service/state.js +2 -0
  190. package/dist/cron/service/store.js +386 -14
  191. package/dist/cron/service/timer.js +390 -147
  192. package/dist/cron/session-reaper.js +86 -0
  193. package/dist/cron/store.js +23 -8
  194. package/dist/cron/validate-timestamp.js +43 -0
  195. package/dist/daemon/constants.js +7 -7
  196. package/dist/daemon/inspect.js +6 -6
  197. package/dist/daemon/systemd-unit.js +1 -1
  198. package/dist/discord/monitor/agent-components.js +438 -0
  199. package/dist/discord/monitor/allow-list.js +28 -5
  200. package/dist/discord/monitor/gateway-registry.js +29 -0
  201. package/dist/discord/monitor/native-command.js +44 -23
  202. package/dist/discord/monitor/sender-identity.js +45 -0
  203. package/dist/discord/pluralkit.js +27 -0
  204. package/dist/discord/send.outbound.js +92 -5
  205. package/dist/discord/send.shared.js +60 -23
  206. package/dist/discord/targets.js +84 -1
  207. package/dist/entry.js +15 -9
  208. package/dist/extensionAPI.js +8 -0
  209. package/dist/gateway/control-ui.js +8 -1
  210. package/dist/gateway/hooks-mapping.js +3 -0
  211. package/dist/gateway/hooks.js +65 -0
  212. package/dist/gateway/live-image-probe.js +1 -66
  213. package/dist/gateway/net.js +96 -31
  214. package/dist/gateway/node-command-policy.js +50 -15
  215. package/dist/gateway/openai-http.js +2 -2
  216. package/dist/gateway/openresponses-http.js +4 -4
  217. package/dist/gateway/origin-check.js +56 -0
  218. package/dist/gateway/protocol/client-info.js +9 -0
  219. package/dist/gateway/protocol/index.js +9 -2
  220. package/dist/gateway/protocol/schema/agents-models-skills.js +71 -1
  221. package/dist/gateway/protocol/schema/cron.js +22 -10
  222. package/dist/gateway/protocol/schema/protocol-schemas.js +16 -2
  223. package/dist/gateway/protocol/schema/sessions.js +12 -0
  224. package/dist/gateway/server/hooks.js +1 -1
  225. package/dist/gateway/server-broadcast.js +26 -9
  226. package/dist/gateway/server-chat.js +112 -23
  227. package/dist/gateway/server-discovery-runtime.js +10 -2
  228. package/dist/gateway/server-discovery.js +2 -2
  229. package/dist/gateway/server-http.js +110 -12
  230. package/dist/gateway/server-methods/agent-timestamp.js +60 -0
  231. package/dist/gateway/server-methods/agents.js +321 -2
  232. package/dist/gateway/server-methods/usage.js +559 -16
  233. package/dist/gateway/server-runtime-state.js +22 -8
  234. package/dist/gateway/server-startup-memory.js +16 -0
  235. package/dist/gateway/server.impl.js +7 -3
  236. package/dist/gateway/session-utils.fs.js +23 -25
  237. package/dist/gateway/session-utils.js +20 -10
  238. package/dist/gateway/sessions-patch.js +7 -22
  239. package/dist/gateway/test-helpers.server.js +35 -2
  240. package/dist/hooks/frontmatter.js +1 -1
  241. package/dist/hooks/hooks-status.js +1 -1
  242. package/dist/hooks/install.js +2 -2
  243. package/dist/hooks/loader.js +1 -1
  244. package/dist/hooks/workspace.js +3 -3
  245. package/dist/imessage/constants.js +2 -0
  246. package/dist/imessage/monitor/deliver.js +4 -1
  247. package/dist/imessage/monitor/monitor-provider.js +51 -1
  248. package/dist/index.js +2 -2
  249. package/dist/infra/bonjour-discovery.js +131 -70
  250. package/dist/infra/bonjour.js +3 -3
  251. package/dist/infra/control-ui-assets.js +134 -12
  252. package/dist/infra/errors.js +12 -0
  253. package/dist/infra/exec-approvals.js +266 -57
  254. package/dist/infra/format-time/format-datetime.js +79 -0
  255. package/dist/infra/format-time/format-duration.js +81 -0
  256. package/dist/infra/format-time/format-relative.js +80 -0
  257. package/dist/infra/heartbeat-runner.js +140 -49
  258. package/dist/infra/home-dir.js +54 -0
  259. package/dist/infra/net/fetch-guard.js +122 -0
  260. package/dist/infra/net/ssrf.js +65 -29
  261. package/dist/infra/outbound/abort.js +14 -0
  262. package/dist/infra/outbound/message-action-runner.js +77 -13
  263. package/dist/infra/outbound/outbound-session.js +143 -37
  264. package/dist/infra/path-env.js +3 -3
  265. package/dist/infra/poolbot-root.js +43 -1
  266. package/dist/infra/provider-usage.fetch.minimax.js +1 -1
  267. package/dist/infra/restart.js +1 -1
  268. package/dist/infra/session-cost-usage.js +631 -41
  269. package/dist/infra/state-migrations.js +317 -47
  270. package/dist/infra/tailscale.js +1 -1
  271. package/dist/infra/update-global.js +35 -0
  272. package/dist/infra/update-runner.js +149 -43
  273. package/dist/infra/warning-filter.js +65 -0
  274. package/dist/infra/widearea-dns.js +30 -9
  275. package/dist/logging/redact-identifier.js +12 -0
  276. package/dist/macos/relay.js +2 -2
  277. package/dist/media/fetch.js +81 -58
  278. package/dist/media/input-files.js +1 -1
  279. package/dist/media/mime.js +4 -0
  280. package/dist/media/png-encode.js +74 -0
  281. package/dist/media-understanding/apply.js +403 -3
  282. package/dist/media-understanding/attachments.js +38 -27
  283. package/dist/media-understanding/defaults.js +16 -0
  284. package/dist/media-understanding/providers/deepgram/audio.js +22 -14
  285. package/dist/media-understanding/providers/google/audio.js +24 -17
  286. package/dist/media-understanding/providers/google/video.js +24 -17
  287. package/dist/media-understanding/providers/image.js +4 -4
  288. package/dist/media-understanding/providers/index.js +4 -1
  289. package/dist/media-understanding/providers/openai/audio.js +22 -14
  290. package/dist/media-understanding/providers/shared.js +16 -11
  291. package/dist/media-understanding/providers/zai/index.js +6 -0
  292. package/dist/media-understanding/runner.js +158 -90
  293. package/dist/memory/backend-config.js +207 -0
  294. package/dist/memory/batch-voyage.js +277 -0
  295. package/dist/memory/embeddings-voyage.js +75 -0
  296. package/dist/memory/embeddings.js +29 -17
  297. package/dist/memory/internal.js +101 -18
  298. package/dist/memory/manager.js +155 -48
  299. package/dist/memory/search-manager.js +173 -0
  300. package/dist/memory/session-files.js +9 -3
  301. package/dist/memory/types.js +1 -0
  302. package/dist/node-host/runner.js +36 -26
  303. package/dist/node-host/with-timeout.js +27 -0
  304. package/dist/pairing/pairing-messages.js +1 -1
  305. package/dist/plugins/commands.js +5 -1
  306. package/dist/plugins/config-state.js +86 -7
  307. package/dist/plugins/discovery.js +1 -1
  308. package/dist/plugins/install.js +2 -2
  309. package/dist/plugins/source-display.js +51 -0
  310. package/dist/plugins/update.js +1 -1
  311. package/dist/process/exec.js +20 -2
  312. package/dist/routing/resolve-route.js +12 -0
  313. package/dist/routing/session-key.js +15 -0
  314. package/dist/runtime.js +2 -0
  315. package/dist/security/audit-extra.async.js +601 -0
  316. package/dist/security/audit-extra.js +2 -830
  317. package/dist/security/audit-extra.sync.js +505 -0
  318. package/dist/security/audit.js +2 -2
  319. package/dist/security/channel-metadata.js +34 -0
  320. package/dist/security/external-content.js +88 -6
  321. package/dist/security/skill-scanner.js +330 -0
  322. package/dist/sessions/session-key-utils.js +7 -0
  323. package/dist/shared/text/reasoning-tags.js +52 -7
  324. package/dist/signal/monitor/event-handler.js +80 -1
  325. package/dist/slack/monitor/media.js +85 -15
  326. package/dist/tailscale/detect.js +145 -0
  327. package/dist/telegram/bot/helpers.js +109 -28
  328. package/dist/telegram/bot-handlers.js +144 -3
  329. package/dist/telegram/bot-message-context.js +38 -11
  330. package/dist/telegram/bot-message-dispatch.js +48 -15
  331. package/dist/telegram/bot-native-commands.js +86 -29
  332. package/dist/telegram/bot.js +30 -29
  333. package/dist/telegram/model-buttons.js +163 -0
  334. package/dist/telegram/monitor.js +110 -85
  335. package/dist/telegram/send.js +129 -47
  336. package/dist/terminal/restore.js +45 -0
  337. package/dist/test-helpers/state-dir-env.js +16 -0
  338. package/dist/test-helpers/workspace.js +11 -0
  339. package/dist/test-utils/channel-plugins.js +82 -0
  340. package/dist/test-utils/ports.js +73 -0
  341. package/dist/tts/tts.js +12 -6
  342. package/dist/tui/tui-session-actions.js +166 -54
  343. package/dist/utils/fetch-timeout.js +20 -0
  344. package/dist/utils/normalize-secret-input.js +19 -0
  345. package/dist/utils/shell-argv.js +61 -0
  346. package/dist/utils/transcript-tools.js +58 -0
  347. package/dist/utils.js +55 -14
  348. package/dist/version.js +42 -5
  349. package/dist/web/qr-image.js +1 -61
  350. package/dist/wizard/onboarding.finalize.js +7 -7
  351. package/dist/wizard/onboarding.js +3 -3
  352. package/docs/RELEASE_WORKFOTS_COMPARISON.md +3 -3
  353. package/docs/_config.yml +2 -2
  354. package/docs/_layouts/default.html +9 -9
  355. package/docs/concepts/typebox.md +1 -1
  356. package/docs/docs.json +1 -1
  357. package/docs/northflank.mdx +7 -7
  358. package/docs/railway.mdx +3 -3
  359. package/docs/render.mdx +5 -5
  360. package/docs/start/lore.md +2 -2
  361. package/extensions/bluebubbles/index.ts +2 -2
  362. package/extensions/bluebubbles/package.json +1 -1
  363. package/extensions/bluebubbles/src/accounts.ts +8 -8
  364. package/extensions/bluebubbles/src/actions.test.ts +22 -22
  365. package/extensions/bluebubbles/src/actions.ts +5 -5
  366. package/extensions/bluebubbles/src/attachments.ts +2 -2
  367. package/extensions/bluebubbles/src/channel.ts +16 -16
  368. package/extensions/bluebubbles/src/chat.ts +2 -2
  369. package/extensions/bluebubbles/src/media-send.ts +2 -2
  370. package/extensions/bluebubbles/src/monitor.test.ts +46 -46
  371. package/extensions/bluebubbles/src/monitor.ts +5 -5
  372. package/extensions/bluebubbles/src/onboarding.ts +7 -7
  373. package/extensions/bluebubbles/src/reactions.ts +2 -2
  374. package/extensions/bluebubbles/src/send.ts +2 -2
  375. package/extensions/copilot-proxy/README.md +1 -1
  376. package/extensions/copilot-proxy/package.json +1 -1
  377. package/extensions/diagnostics-otel/index.ts +2 -2
  378. package/extensions/diagnostics-otel/package.json +1 -1
  379. package/extensions/diagnostics-otel/src/service.ts +3 -3
  380. package/extensions/discord/index.ts +2 -2
  381. package/extensions/discord/package.json +1 -1
  382. package/extensions/google-antigravity-auth/README.md +1 -1
  383. package/extensions/google-antigravity-auth/index.ts +1 -1
  384. package/extensions/google-antigravity-auth/package.json +1 -1
  385. package/extensions/google-gemini-cli-auth/README.md +1 -1
  386. package/extensions/google-gemini-cli-auth/oauth.ts +1 -1
  387. package/extensions/google-gemini-cli-auth/package.json +1 -1
  388. package/extensions/googlechat/index.ts +3 -3
  389. package/extensions/googlechat/package.json +1 -1
  390. package/extensions/googlechat/src/accounts.ts +8 -8
  391. package/extensions/googlechat/src/actions.ts +6 -6
  392. package/extensions/googlechat/src/channel.ts +21 -21
  393. package/extensions/googlechat/src/monitor.ts +8 -8
  394. package/extensions/googlechat/src/onboarding.ts +10 -10
  395. package/extensions/imessage/index.ts +2 -2
  396. package/extensions/imessage/package.json +1 -1
  397. package/extensions/line/index.ts +2 -2
  398. package/extensions/line/package.json +1 -1
  399. package/extensions/line/src/card-command.ts +2 -2
  400. package/extensions/line/src/channel.logout.test.ts +4 -4
  401. package/extensions/line/src/channel.sendPayload.test.ts +8 -8
  402. package/extensions/line/src/channel.ts +3 -3
  403. package/extensions/llm-task/README.md +3 -3
  404. package/extensions/llm-task/index.ts +2 -2
  405. package/extensions/llm-task/package.json +1 -1
  406. package/extensions/llm-task/src/llm-task-tool.ts +4 -4
  407. package/extensions/lobster/README.md +6 -6
  408. package/extensions/lobster/index.ts +2 -2
  409. package/extensions/lobster/src/lobster-tool.test.ts +4 -4
  410. package/extensions/lobster/src/lobster-tool.ts +2 -2
  411. package/extensions/matrix/index.ts +2 -2
  412. package/extensions/matrix/package.json +1 -1
  413. package/extensions/matrix/src/matrix/client/config.ts +1 -1
  414. package/extensions/matrix/src/matrix/monitor/handler.ts +1 -1
  415. package/extensions/matrix/src/onboarding.ts +1 -1
  416. package/extensions/mattermost/index.ts +2 -2
  417. package/extensions/mattermost/package.json +1 -1
  418. package/extensions/mattermost/src/mattermost/accounts.ts +8 -8
  419. package/extensions/mattermost/src/mattermost/monitor-helpers.ts +5 -5
  420. package/extensions/mattermost/src/mattermost/monitor.ts +2 -2
  421. package/extensions/mattermost/src/onboarding-helpers.ts +3 -3
  422. package/extensions/mattermost/src/onboarding.ts +2 -2
  423. package/extensions/memory-core/index.ts +2 -2
  424. package/extensions/memory-core/package.json +1 -1
  425. package/extensions/memory-lancedb/index.ts +3 -3
  426. package/extensions/memory-lancedb/package.json +1 -1
  427. package/extensions/msteams/index.ts +2 -2
  428. package/extensions/msteams/package.json +1 -1
  429. package/extensions/msteams/src/channel.directory.test.ts +2 -2
  430. package/extensions/msteams/src/channel.ts +2 -2
  431. package/extensions/msteams/src/graph-upload.ts +4 -4
  432. package/extensions/msteams/src/monitor-handler.ts +2 -2
  433. package/extensions/msteams/src/monitor.ts +2 -2
  434. package/extensions/msteams/src/onboarding.ts +9 -9
  435. package/extensions/msteams/src/reply-dispatcher.ts +2 -2
  436. package/extensions/msteams/src/send-context.ts +2 -2
  437. package/extensions/msteams/src/send.ts +4 -4
  438. package/extensions/nextcloud-talk/index.ts +2 -2
  439. package/extensions/nextcloud-talk/package.json +1 -1
  440. package/extensions/nextcloud-talk/src/channel.ts +7 -7
  441. package/extensions/nextcloud-talk/src/inbound.ts +7 -7
  442. package/extensions/nextcloud-talk/src/onboarding.ts +1 -1
  443. package/extensions/nostr/README.md +2 -2
  444. package/extensions/nostr/index.ts +5 -5
  445. package/extensions/nostr/package.json +1 -1
  446. package/extensions/nostr/src/types.ts +4 -4
  447. package/extensions/open-prose/index.ts +2 -2
  448. package/extensions/qwen-portal-auth/README.md +1 -1
  449. package/extensions/signal/index.ts +2 -2
  450. package/extensions/signal/package.json +1 -1
  451. package/extensions/slack/index.ts +2 -2
  452. package/extensions/slack/package.json +1 -1
  453. package/extensions/telegram/index.ts +2 -2
  454. package/extensions/telegram/package.json +1 -1
  455. package/extensions/telegram/src/channel.ts +2 -2
  456. package/extensions/tlon/README.md +2 -2
  457. package/extensions/tlon/index.ts +2 -2
  458. package/extensions/tlon/package.json +1 -1
  459. package/extensions/tlon/src/channel.ts +13 -13
  460. package/extensions/tlon/src/monitor/index.ts +3 -3
  461. package/extensions/tlon/src/onboarding.ts +3 -3
  462. package/extensions/tlon/src/types.ts +3 -3
  463. package/extensions/twitch/README.md +1 -1
  464. package/extensions/twitch/index.ts +2 -2
  465. package/extensions/twitch/package.json +1 -1
  466. package/extensions/twitch/src/config.ts +3 -3
  467. package/extensions/twitch/src/monitor.ts +3 -3
  468. package/extensions/twitch/src/onboarding.ts +9 -9
  469. package/extensions/twitch/src/outbound.test.ts +2 -2
  470. package/extensions/twitch/src/plugin.test.ts +2 -2
  471. package/extensions/twitch/src/plugin.ts +8 -8
  472. package/extensions/twitch/src/send.test.ts +2 -2
  473. package/extensions/twitch/src/send.ts +4 -4
  474. package/extensions/twitch/src/token.test.ts +8 -8
  475. package/extensions/twitch/src/token.ts +3 -3
  476. package/extensions/twitch/src/twitch-client.ts +3 -3
  477. package/extensions/twitch/src/types.ts +3 -3
  478. package/extensions/twitch/src/utils/markdown.ts +1 -1
  479. package/extensions/voice-call/README.md +3 -3
  480. package/extensions/voice-call/package.json +1 -1
  481. package/extensions/voice-call/src/core-bridge.ts +2 -2
  482. package/extensions/voice-call/src/response-generator.ts +1 -1
  483. package/extensions/whatsapp/index.ts +2 -2
  484. package/extensions/whatsapp/package.json +1 -1
  485. package/extensions/zalo/README.md +1 -1
  486. package/extensions/zalo/index.ts +2 -2
  487. package/extensions/zalo/package.json +1 -1
  488. package/extensions/zalo/src/accounts.ts +8 -8
  489. package/extensions/zalo/src/actions.ts +4 -4
  490. package/extensions/zalo/src/channel.directory.test.ts +2 -2
  491. package/extensions/zalo/src/channel.ts +18 -18
  492. package/extensions/zalo/src/monitor.ts +9 -9
  493. package/extensions/zalo/src/monitor.webhook.test.ts +2 -2
  494. package/extensions/zalo/src/onboarding.ts +24 -24
  495. package/extensions/zalo/src/send.ts +2 -2
  496. package/extensions/zalouser/README.md +2 -2
  497. package/extensions/zalouser/index.ts +2 -2
  498. package/extensions/zalouser/package.json +1 -1
  499. package/extensions/zalouser/src/accounts.ts +9 -9
  500. package/extensions/zalouser/src/channel.ts +24 -24
  501. package/extensions/zalouser/src/monitor.ts +4 -4
  502. package/extensions/zalouser/src/onboarding.ts +28 -28
  503. package/package.json +13 -251
  504. package/skills/nano-banana-pro/scripts/generate_image.py +1 -1
  505. package/skills/tmux/scripts/find-sessions.sh +1 -1
  506. package/CHANGELOG.md +0 -102
  507. package/README-header.png +0 -0
  508. package/git-hooks/pre-commit +0 -4
  509. package/scripts/format-staged.js +0 -148
  510. package/scripts/postinstall.js +0 -300
  511. package/scripts/setup-git-hooks.js +0 -96
@@ -25,6 +25,7 @@ export const TelegramTopicSchema = z
25
25
  export const TelegramGroupSchema = z
26
26
  .object({
27
27
  requireMention: z.boolean().optional(),
28
+ groupPolicy: GroupPolicySchema.optional(),
28
29
  tools: ToolPolicySchema,
29
30
  toolsBySender: ToolPolicyBySenderSchema,
30
31
  skills: z.array(z.string()).optional(),
@@ -108,6 +109,7 @@ export const TelegramAccountSchemaBase = z
108
109
  reactionLevel: z.enum(["off", "ack", "minimal", "extensive"]).optional(),
109
110
  heartbeat: ChannelHeartbeatVisibilitySchema,
110
111
  linkPreview: z.boolean().optional(),
112
+ responsePrefix: z.string().optional(),
111
113
  })
112
114
  .strict();
113
115
  export const TelegramAccountSchema = TelegramAccountSchemaBase.superRefine((value, ctx) => {
@@ -131,6 +133,38 @@ export const TelegramConfigSchema = TelegramAccountSchemaBase.extend({
131
133
  message: 'channels.telegram.dmPolicy="open" requires channels.telegram.allowFrom to include "*"',
132
134
  });
133
135
  validateTelegramCustomCommands(value, ctx);
136
+ const baseWebhookUrl = typeof value.webhookUrl === "string" ? value.webhookUrl.trim() : "";
137
+ const baseWebhookSecret = typeof value.webhookSecret === "string" ? value.webhookSecret.trim() : "";
138
+ if (baseWebhookUrl && !baseWebhookSecret) {
139
+ ctx.addIssue({
140
+ code: z.ZodIssueCode.custom,
141
+ message: "channels.telegram.webhookUrl requires channels.telegram.webhookSecret",
142
+ path: ["webhookSecret"],
143
+ });
144
+ }
145
+ if (!value.accounts) {
146
+ return;
147
+ }
148
+ for (const [accountId, account] of Object.entries(value.accounts)) {
149
+ if (!account) {
150
+ continue;
151
+ }
152
+ if (account.enabled === false) {
153
+ continue;
154
+ }
155
+ const accountWebhookUrl = typeof account.webhookUrl === "string" ? account.webhookUrl.trim() : "";
156
+ if (!accountWebhookUrl) {
157
+ continue;
158
+ }
159
+ const accountSecret = typeof account.webhookSecret === "string" ? account.webhookSecret.trim() : "";
160
+ if (!accountSecret && !baseWebhookSecret) {
161
+ ctx.addIssue({
162
+ code: z.ZodIssueCode.custom,
163
+ message: "channels.telegram.accounts.*.webhookUrl requires channels.telegram.webhookSecret or channels.telegram.accounts.*.webhookSecret",
164
+ path: ["accounts", accountId, "webhookSecret"],
165
+ });
166
+ }
167
+ }
134
168
  });
135
169
  export const DiscordDmSchema = z
136
170
  .object({
@@ -160,6 +194,7 @@ export const DiscordGuildChannelSchema = z
160
194
  enabled: z.boolean().optional(),
161
195
  users: z.array(z.union([z.string(), z.number()])).optional(),
162
196
  systemPrompt: z.string().optional(),
197
+ includeThreadStarter: z.boolean().optional(),
163
198
  autoThread: z.boolean().optional(),
164
199
  })
165
200
  .strict();
@@ -215,6 +250,7 @@ export const DiscordAccountSchema = z
215
250
  events: z.boolean().optional(),
216
251
  moderation: z.boolean().optional(),
217
252
  channels: z.boolean().optional(),
253
+ presence: z.boolean().optional(),
218
254
  })
219
255
  .strict()
220
256
  .optional(),
@@ -228,6 +264,7 @@ export const DiscordAccountSchema = z
228
264
  approvers: z.array(z.union([z.string(), z.number()])).optional(),
229
265
  agentFilter: z.array(z.string()).optional(),
230
266
  sessionFilter: z.array(z.string()).optional(),
267
+ cleanupAfterResolve: z.boolean().optional(),
231
268
  })
232
269
  .strict()
233
270
  .optional(),
@@ -238,6 +275,14 @@ export const DiscordAccountSchema = z
238
275
  })
239
276
  .strict()
240
277
  .optional(),
278
+ pluralkit: z
279
+ .object({
280
+ enabled: z.boolean().optional(),
281
+ token: z.string().optional(),
282
+ })
283
+ .strict()
284
+ .optional(),
285
+ responsePrefix: z.string().optional(),
241
286
  })
242
287
  .strict();
243
288
  export const DiscordConfigSchema = DiscordAccountSchema.extend({
@@ -303,6 +348,7 @@ export const GoogleChatAccountSchema = z
303
348
  .optional(),
304
349
  dm: GoogleChatDmSchema.optional(),
305
350
  typingIndicator: z.enum(["none", "message", "reaction"]).optional(),
351
+ responsePrefix: z.string().optional(),
306
352
  })
307
353
  .strict();
308
354
  export const GoogleChatConfigSchema = GoogleChatAccountSchema.extend({
@@ -410,6 +456,7 @@ export const SlackAccountSchema = z
410
456
  dm: SlackDmSchema.optional(),
411
457
  channels: z.record(z.string(), SlackChannelSchema.optional()).optional(),
412
458
  heartbeat: ChannelHeartbeatVisibilitySchema,
459
+ responsePrefix: z.string().optional(),
413
460
  })
414
461
  .strict();
415
462
  export const SlackConfigSchema = SlackAccountSchema.extend({
@@ -486,6 +533,7 @@ export const SignalAccountSchemaBase = z
486
533
  .optional(),
487
534
  reactionLevel: z.enum(["off", "ack", "minimal", "extensive"]).optional(),
488
535
  heartbeat: ChannelHeartbeatVisibilitySchema,
536
+ responsePrefix: z.string().optional(),
489
537
  })
490
538
  .strict();
491
539
  export const SignalAccountSchema = SignalAccountSchemaBase.superRefine((value, ctx) => {
@@ -508,6 +556,96 @@ export const SignalConfigSchema = SignalAccountSchemaBase.extend({
508
556
  message: 'channels.signal.dmPolicy="open" requires channels.signal.allowFrom to include "*"',
509
557
  });
510
558
  });
559
+ export const IrcGroupSchema = z
560
+ .object({
561
+ requireMention: z.boolean().optional(),
562
+ tools: ToolPolicySchema,
563
+ toolsBySender: ToolPolicyBySenderSchema,
564
+ skills: z.array(z.string()).optional(),
565
+ enabled: z.boolean().optional(),
566
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
567
+ systemPrompt: z.string().optional(),
568
+ })
569
+ .strict();
570
+ export const IrcNickServSchema = z
571
+ .object({
572
+ enabled: z.boolean().optional(),
573
+ service: z.string().optional(),
574
+ password: z.string().optional(),
575
+ passwordFile: z.string().optional(),
576
+ register: z.boolean().optional(),
577
+ registerEmail: z.string().optional(),
578
+ })
579
+ .strict();
580
+ export const IrcAccountSchemaBase = z
581
+ .object({
582
+ name: z.string().optional(),
583
+ capabilities: z.array(z.string()).optional(),
584
+ markdown: MarkdownConfigSchema,
585
+ enabled: z.boolean().optional(),
586
+ configWrites: z.boolean().optional(),
587
+ host: z.string().optional(),
588
+ port: z.number().int().min(1).max(65535).optional(),
589
+ tls: z.boolean().optional(),
590
+ nick: z.string().optional(),
591
+ username: z.string().optional(),
592
+ realname: z.string().optional(),
593
+ password: z.string().optional(),
594
+ passwordFile: z.string().optional(),
595
+ nickserv: IrcNickServSchema.optional(),
596
+ channels: z.array(z.string()).optional(),
597
+ dmPolicy: DmPolicySchema.optional().default("pairing"),
598
+ allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
599
+ groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
600
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
601
+ groups: z.record(z.string(), IrcGroupSchema.optional()).optional(),
602
+ mentionPatterns: z.array(z.string()).optional(),
603
+ historyLimit: z.number().int().min(0).optional(),
604
+ dmHistoryLimit: z.number().int().min(0).optional(),
605
+ dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
606
+ textChunkLimit: z.number().int().positive().optional(),
607
+ chunkMode: z.enum(["length", "newline"]).optional(),
608
+ blockStreaming: z.boolean().optional(),
609
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
610
+ mediaMaxMb: z.number().positive().optional(),
611
+ heartbeat: ChannelHeartbeatVisibilitySchema,
612
+ responsePrefix: z.string().optional(),
613
+ })
614
+ .strict();
615
+ export const IrcAccountSchema = IrcAccountSchemaBase.superRefine((value, ctx) => {
616
+ requireOpenAllowFrom({
617
+ policy: value.dmPolicy,
618
+ allowFrom: value.allowFrom,
619
+ ctx,
620
+ path: ["allowFrom"],
621
+ message: 'channels.irc.dmPolicy="open" requires channels.irc.allowFrom to include "*"',
622
+ });
623
+ if (value.nickserv?.register && !value.nickserv.registerEmail?.trim()) {
624
+ ctx.addIssue({
625
+ code: z.ZodIssueCode.custom,
626
+ path: ["nickserv", "registerEmail"],
627
+ message: "channels.irc.nickserv.register=true requires channels.irc.nickserv.registerEmail",
628
+ });
629
+ }
630
+ });
631
+ export const IrcConfigSchema = IrcAccountSchemaBase.extend({
632
+ accounts: z.record(z.string(), IrcAccountSchema.optional()).optional(),
633
+ }).superRefine((value, ctx) => {
634
+ requireOpenAllowFrom({
635
+ policy: value.dmPolicy,
636
+ allowFrom: value.allowFrom,
637
+ ctx,
638
+ path: ["allowFrom"],
639
+ message: 'channels.irc.dmPolicy="open" requires channels.irc.allowFrom to include "*"',
640
+ });
641
+ if (value.nickserv?.register && !value.nickserv.registerEmail?.trim()) {
642
+ ctx.addIssue({
643
+ code: z.ZodIssueCode.custom,
644
+ path: ["nickserv", "registerEmail"],
645
+ message: "channels.irc.nickserv.register=true requires channels.irc.nickserv.registerEmail",
646
+ });
647
+ }
648
+ });
511
649
  export const IMessageAccountSchemaBase = z
512
650
  .object({
513
651
  name: z.string().optional(),
@@ -544,6 +682,7 @@ export const IMessageAccountSchemaBase = z
544
682
  .optional())
545
683
  .optional(),
546
684
  heartbeat: ChannelHeartbeatVisibilitySchema,
685
+ responsePrefix: z.string().optional(),
547
686
  })
548
687
  .strict();
549
688
  export const IMessageAccountSchema = IMessageAccountSchemaBase.superRefine((value, ctx) => {
@@ -615,6 +754,7 @@ export const BlueBubblesAccountSchemaBase = z
615
754
  blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
616
755
  groups: z.record(z.string(), BlueBubblesGroupConfigSchema.optional()).optional(),
617
756
  heartbeat: ChannelHeartbeatVisibilitySchema,
757
+ responsePrefix: z.string().optional(),
618
758
  })
619
759
  .strict();
620
760
  export const BlueBubblesAccountSchema = BlueBubblesAccountSchemaBase.superRefine((value, ctx) => {
@@ -679,6 +819,7 @@ export const MSTeamsConfigSchema = z
679
819
  chunkMode: z.enum(["length", "newline"]).optional(),
680
820
  blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
681
821
  mediaAllowHosts: z.array(z.string()).optional(),
822
+ mediaAuthAllowHosts: z.array(z.string()).optional(),
682
823
  requireMention: z.boolean().optional(),
683
824
  historyLimit: z.number().int().min(0).optional(),
684
825
  dmHistoryLimit: z.number().int().min(0).optional(),
@@ -690,6 +831,7 @@ export const MSTeamsConfigSchema = z
690
831
  /** SharePoint site ID for file uploads in group chats/channels (e.g., "contoso.sharepoint.com,guid1,guid2") */
691
832
  sharePointSiteId: z.string().optional(),
692
833
  heartbeat: ChannelHeartbeatVisibilitySchema,
834
+ responsePrefix: z.string().optional(),
693
835
  })
694
836
  .strict()
695
837
  .superRefine((value, ctx) => {
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { ElevatedAllowFromSchema } from "./zod-schema.agent-runtime.js";
2
3
  import { GroupChatSchema, InboundDebounceSchema, NativeCommandsSettingSchema, QueueSchema, TtsConfigSchema, } from "./zod-schema.core.js";
3
4
  const SessionResetConfigSchema = z
4
5
  .object({
@@ -94,6 +95,8 @@ export const CommandsSchema = z
94
95
  debug: z.boolean().optional(),
95
96
  restart: z.boolean().optional(),
96
97
  useAccessGroups: z.boolean().optional(),
98
+ ownerAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
99
+ allowFrom: ElevatedAllowFromSchema.optional(),
97
100
  })
98
101
  .strict()
99
102
  .optional()
@@ -0,0 +1,57 @@
1
+ function normalizeChannel(value) {
2
+ if (typeof value !== "string") {
3
+ return undefined;
4
+ }
5
+ const trimmed = value.trim().toLowerCase();
6
+ if (!trimmed) {
7
+ return undefined;
8
+ }
9
+ return trimmed;
10
+ }
11
+ function normalizeTo(value) {
12
+ if (typeof value !== "string") {
13
+ return undefined;
14
+ }
15
+ const trimmed = value.trim();
16
+ return trimmed ? trimmed : undefined;
17
+ }
18
+ export function resolveCronDeliveryPlan(job) {
19
+ const payload = job.payload.kind === "agentTurn" ? job.payload : null;
20
+ const delivery = job.delivery;
21
+ const hasDelivery = delivery && typeof delivery === "object";
22
+ const rawMode = hasDelivery ? delivery.mode : undefined;
23
+ const normalizedMode = typeof rawMode === "string" ? rawMode.trim().toLowerCase() : rawMode;
24
+ const mode = normalizedMode === "announce"
25
+ ? "announce"
26
+ : normalizedMode === "none"
27
+ ? "none"
28
+ : normalizedMode === "deliver"
29
+ ? "announce"
30
+ : undefined;
31
+ const payloadChannel = normalizeChannel(payload?.channel);
32
+ const payloadTo = normalizeTo(payload?.to);
33
+ const deliveryChannel = normalizeChannel(delivery?.channel);
34
+ const deliveryTo = normalizeTo(delivery?.to);
35
+ const channel = deliveryChannel ?? payloadChannel ?? "last";
36
+ const to = deliveryTo ?? payloadTo;
37
+ if (hasDelivery) {
38
+ const resolvedMode = mode ?? "announce";
39
+ return {
40
+ mode: resolvedMode,
41
+ channel,
42
+ to,
43
+ source: "delivery",
44
+ requested: resolvedMode === "announce",
45
+ };
46
+ }
47
+ const legacyMode = payload?.deliver === true ? "explicit" : payload?.deliver === false ? "off" : "auto";
48
+ const hasExplicitTarget = Boolean(to);
49
+ const requested = legacyMode === "explicit" || (legacyMode === "auto" && hasExplicitTarget);
50
+ return {
51
+ mode: requested ? "announce" : "none",
52
+ channel,
53
+ to,
54
+ source: "payload",
55
+ requested,
56
+ };
57
+ }
@@ -5,6 +5,7 @@ import { resolveOutboundTarget, resolveSessionDeliveryTarget, } from "../../infr
5
5
  export async function resolveDeliveryTarget(cfg, agentId, jobPayload) {
6
6
  const requestedChannel = typeof jobPayload.channel === "string" ? jobPayload.channel : "last";
7
7
  const explicitTo = typeof jobPayload.to === "string" ? jobPayload.to : undefined;
8
+ const allowMismatchedLastTo = requestedChannel === "last";
8
9
  const sessionCfg = cfg.session;
9
10
  const mainSessionKey = resolveAgentMainSessionKey({ cfg, agentId });
10
11
  const storePath = resolveStorePath(sessionCfg?.store, { agentId });
@@ -14,7 +15,7 @@ export async function resolveDeliveryTarget(cfg, agentId, jobPayload) {
14
15
  entry: main,
15
16
  requestedChannel,
16
17
  explicitTo,
17
- allowMismatchedLastTo: true,
18
+ allowMismatchedLastTo,
18
19
  });
19
20
  let fallbackChannel;
20
21
  if (!preliminary.channel) {
@@ -32,15 +33,28 @@ export async function resolveDeliveryTarget(cfg, agentId, jobPayload) {
32
33
  requestedChannel,
33
34
  explicitTo,
34
35
  fallbackChannel,
35
- allowMismatchedLastTo: true,
36
+ allowMismatchedLastTo,
36
37
  mode: preliminary.mode,
37
38
  })
38
39
  : preliminary;
39
40
  const channel = resolved.channel ?? fallbackChannel ?? DEFAULT_CHAT_CHANNEL;
40
41
  const mode = resolved.mode;
41
42
  const toCandidate = resolved.to;
43
+ // Only carry threadId when delivering to the same recipient as the session's
44
+ // last conversation. This prevents stale thread IDs (e.g. from a Telegram
45
+ // supergroup topic) from being sent to a different target (e.g. a private
46
+ // chat) where they would cause API errors.
47
+ const threadId = resolved.threadId && resolved.to && resolved.to === resolved.lastTo
48
+ ? resolved.threadId
49
+ : undefined;
42
50
  if (!toCandidate) {
43
- return { channel, to: undefined, accountId: resolved.accountId, mode };
51
+ return {
52
+ channel,
53
+ to: undefined,
54
+ accountId: resolved.accountId,
55
+ threadId,
56
+ mode,
57
+ };
44
58
  }
45
59
  const docked = resolveOutboundTarget({
46
60
  channel,
@@ -53,6 +67,7 @@ export async function resolveDeliveryTarget(cfg, agentId, jobPayload) {
53
67
  channel,
54
68
  to: docked.ok ? docked.to : undefined,
55
69
  accountId: resolved.accountId,
70
+ threadId,
56
71
  mode,
57
72
  error: docked.ok ? undefined : docked.error,
58
73
  };
@@ -2,24 +2,39 @@ import { DEFAULT_HEARTBEAT_ACK_MAX_CHARS, stripHeartbeatToken, } from "../../aut
2
2
  import { truncateUtf16Safe } from "../../utils.js";
3
3
  export function pickSummaryFromOutput(text) {
4
4
  const clean = (text ?? "").trim();
5
- if (!clean)
5
+ if (!clean) {
6
6
  return undefined;
7
+ }
7
8
  const limit = 2000;
8
9
  return clean.length > limit ? `${truncateUtf16Safe(clean, limit)}…` : clean;
9
10
  }
10
11
  export function pickSummaryFromPayloads(payloads) {
11
12
  for (let i = payloads.length - 1; i >= 0; i--) {
12
13
  const summary = pickSummaryFromOutput(payloads[i]?.text);
13
- if (summary)
14
+ if (summary) {
14
15
  return summary;
16
+ }
15
17
  }
16
18
  return undefined;
17
19
  }
18
20
  export function pickLastNonEmptyTextFromPayloads(payloads) {
19
21
  for (let i = payloads.length - 1; i >= 0; i--) {
20
22
  const clean = (payloads[i]?.text ?? "").trim();
21
- if (clean)
23
+ if (clean) {
22
24
  return clean;
25
+ }
26
+ }
27
+ return undefined;
28
+ }
29
+ export function pickLastDeliverablePayload(payloads) {
30
+ for (let i = payloads.length - 1; i >= 0; i--) {
31
+ const payload = payloads[i];
32
+ const text = (payload?.text ?? "").trim();
33
+ const hasMedia = Boolean(payload?.mediaUrl) || (payload?.mediaUrls?.length ?? 0) > 0;
34
+ const hasChannelData = Object.keys(payload?.channelData ?? {}).length > 0;
35
+ if (text || hasMedia || hasChannelData) {
36
+ return payload;
37
+ }
23
38
  }
24
39
  return undefined;
25
40
  }
@@ -28,13 +43,15 @@ export function pickLastNonEmptyTextFromPayloads(payloads) {
28
43
  * Returns true if delivery should be skipped because there's no real content.
29
44
  */
30
45
  export function isHeartbeatOnlyResponse(payloads, ackMaxChars) {
31
- if (payloads.length === 0)
46
+ if (payloads.length === 0) {
32
47
  return true;
48
+ }
33
49
  return payloads.every((payload) => {
34
50
  // If there's media, we should deliver regardless of text content.
35
51
  const hasMedia = (payload.mediaUrls?.length ?? 0) > 0 || Boolean(payload.mediaUrl);
36
- if (hasMedia)
52
+ if (hasMedia) {
37
53
  return false;
54
+ }
38
55
  // Use heartbeat mode to check if text is just HEARTBEAT_OK or short ack.
39
56
  const result = stripHeartbeatToken(payload.text, {
40
57
  mode: "heartbeat",