pi-harness-runtime 1.1.398 → 1.1.402

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 (613) hide show
  1. package/AGENTS.md +44 -2
  2. package/CHANGELOG.md +21 -0
  3. package/RULES.md +28 -0
  4. package/harness/agent-handoff.ts +2 -3
  5. package/harness/autonomous-review.ts +1 -1
  6. package/harness/blackboard.ts +2 -3
  7. package/harness/context-compact-orchestrator.ts +1 -1
  8. package/harness/context-window-manager.ts +2 -2
  9. package/harness/e2e/playwright-runner.ts +6 -4
  10. package/harness/herdr-agents.ts +1 -1
  11. package/harness/job-state-machine.ts +1 -1
  12. package/harness/langchain/daemon.ts +3 -3
  13. package/harness/langchain/graph.ts +2 -2
  14. package/harness/langchain/ping-pong-middleware.ts +2 -2
  15. package/harness/loop-code-agent.ts +6 -4
  16. package/harness/loop-controller.ts +1 -1
  17. package/harness/loop-review-agent.ts +1 -1
  18. package/harness/loop-types.ts +1 -1
  19. package/harness/master-planner.ts +1 -1
  20. package/harness/project-detector/detector.ts +1 -2
  21. package/harness/repair-engine.ts +2 -4
  22. package/harness/service-diagnostics.ts +1 -1
  23. package/harness/skill-sync.ts +3 -3
  24. package/index.ts +276 -55
  25. package/mirror.ts +1 -1
  26. package/package.json +5 -3
  27. package/packages/a2a-adapter/dist/discovery.d.ts.map +1 -1
  28. package/packages/a2a-adapter/dist/discovery.js +0 -1
  29. package/packages/a2a-adapter/dist/discovery.js.map +1 -1
  30. package/packages/a2a-adapter/package.json +1 -1
  31. package/packages/a2a-adapter/src/discovery.ts +0 -1
  32. package/packages/agent-policy/package.json +1 -1
  33. package/packages/architecture-generator/package.json +1 -1
  34. package/packages/auth/dist/index.d.ts +9 -0
  35. package/packages/auth/dist/index.d.ts.map +1 -0
  36. package/packages/auth/dist/index.js +9 -0
  37. package/packages/auth/dist/index.js.map +1 -0
  38. package/packages/auth/package.json +1 -1
  39. package/packages/auth/src/index.ts +9 -0
  40. package/packages/autonomous-refactor/package.json +1 -1
  41. package/packages/autonomous-runtime/package.json +1 -1
  42. package/packages/cache-strategy/package.json +1 -1
  43. package/packages/capability-registry/package.json +1 -1
  44. package/packages/checkpoint/package.json +1 -1
  45. package/packages/cli-plugin-sdk/package.json +1 -1
  46. package/packages/clipboard/package.json +1 -1
  47. package/packages/clipboard-plugin/package.json +1 -1
  48. package/packages/code-generation/package.json +1 -1
  49. package/packages/code-review/package.json +1 -1
  50. package/packages/codex-adapter/package.json +1 -1
  51. package/packages/codex-watcher/package.json +1 -1
  52. package/packages/config-capture/dist/index.d.ts +52 -0
  53. package/packages/config-capture/dist/index.d.ts.map +1 -0
  54. package/packages/config-capture/dist/index.js +261 -0
  55. package/packages/config-capture/dist/index.js.map +1 -0
  56. package/packages/config-capture/package.json +1 -1
  57. package/packages/connection-runtime/package.json +1 -1
  58. package/packages/context-compiler/package.json +1 -1
  59. package/packages/context-discovery/package.json +1 -1
  60. package/packages/context-manager/package.json +1 -1
  61. package/packages/contracts/package.json +1 -1
  62. package/packages/cookie-sanitizer/package.json +1 -1
  63. package/packages/cost-optimizer/package.json +1 -1
  64. package/packages/dependency-analyzer/package.json +1 -1
  65. package/packages/django-plugin/package.json +1 -1
  66. package/packages/doc-generator/package.json +1 -1
  67. package/packages/durable-review/package.json +1 -1
  68. package/packages/e2e-tester/package.json +1 -1
  69. package/packages/evaluation-engine/package.json +1 -1
  70. package/packages/evaluation-runner/package.json +1 -1
  71. package/packages/event-bus/package.json +1 -1
  72. package/packages/event-sink/package.json +1 -1
  73. package/packages/event-store/package.json +1 -1
  74. package/packages/experience-replay/package.json +1 -1
  75. package/packages/feedback-collector/package.json +1 -1
  76. package/packages/file-copy-helper/dist/extension.d.ts +15 -0
  77. package/packages/file-copy-helper/dist/extension.d.ts.map +1 -0
  78. package/packages/file-copy-helper/dist/extension.debug.d.ts +15 -0
  79. package/packages/file-copy-helper/dist/extension.debug.d.ts.map +1 -0
  80. package/packages/file-copy-helper/dist/extension.debug.js +215 -0
  81. package/packages/file-copy-helper/dist/extension.debug.js.map +1 -0
  82. package/packages/file-copy-helper/dist/extension.js +222 -0
  83. package/packages/file-copy-helper/dist/extension.js.map +1 -0
  84. package/packages/file-copy-helper/dist/index.d.ts +3 -0
  85. package/packages/file-copy-helper/dist/index.d.ts.map +1 -0
  86. package/packages/file-copy-helper/dist/index.js +3 -0
  87. package/packages/file-copy-helper/dist/index.js.map +1 -0
  88. package/packages/file-copy-helper/dist/intent-detector.d.ts +21 -0
  89. package/packages/file-copy-helper/dist/intent-detector.d.ts.map +1 -0
  90. package/packages/file-copy-helper/dist/intent-detector.js +348 -0
  91. package/packages/file-copy-helper/dist/intent-detector.js.map +1 -0
  92. package/packages/file-copy-helper/package.json +1 -1
  93. package/packages/framework-detector/package.json +1 -1
  94. package/packages/framework-plugin-sdk/package.json +1 -1
  95. package/packages/frappe-plugin/package.json +1 -1
  96. package/packages/generic-web-plugin/package.json +1 -1
  97. package/packages/health-monitor/package.json +1 -1
  98. package/packages/intent-analyzer/package.json +1 -1
  99. package/packages/jev-judge/dist/auto-continue.d.ts +161 -2
  100. package/packages/jev-judge/dist/auto-continue.d.ts.map +1 -1
  101. package/packages/jev-judge/dist/auto-continue.js +267 -22
  102. package/packages/jev-judge/dist/auto-continue.js.map +1 -1
  103. package/packages/jev-judge/dist/index.d.ts +2 -0
  104. package/packages/jev-judge/dist/index.d.ts.map +1 -1
  105. package/packages/jev-judge/dist/index.js +2 -0
  106. package/packages/jev-judge/dist/index.js.map +1 -1
  107. package/packages/jev-judge/dist/question-risk.d.ts +50 -0
  108. package/packages/jev-judge/dist/question-risk.d.ts.map +1 -0
  109. package/packages/jev-judge/dist/question-risk.js +100 -0
  110. package/packages/jev-judge/dist/question-risk.js.map +1 -0
  111. package/packages/jev-judge/package.json +1 -1
  112. package/packages/jev-judge/src/auto-continue.ts +426 -29
  113. package/packages/jev-judge/src/index.ts +4 -0
  114. package/packages/jev-judge/src/question-risk.ts +151 -0
  115. package/packages/jev-judge/tests/auto-continue-context.test.ts +221 -0
  116. package/packages/jev-judge/tests/outcome-application.test.ts +132 -0
  117. package/packages/jev-judge/tests/question-risk.test.ts +116 -0
  118. package/packages/knowledge-graph/package.json +1 -1
  119. package/packages/knowledge-retrieval/package.json +1 -1
  120. package/packages/laravel-plugin/package.json +1 -1
  121. package/packages/learning-engine/package.json +1 -1
  122. package/packages/logging/README.md +36 -3
  123. package/packages/logging/dist/config.d.ts +7 -0
  124. package/packages/logging/dist/config.d.ts.map +1 -1
  125. package/packages/logging/dist/config.js +14 -0
  126. package/packages/logging/dist/config.js.map +1 -1
  127. package/packages/logging/dist/incidents/schema.d.ts +111 -0
  128. package/packages/logging/dist/incidents/schema.d.ts.map +1 -0
  129. package/packages/logging/dist/incidents/schema.js +0 -0
  130. package/packages/logging/dist/incidents/schema.js.map +1 -0
  131. package/packages/logging/dist/index.d.ts +2 -0
  132. package/packages/logging/dist/index.d.ts.map +1 -1
  133. package/packages/logging/dist/index.js +2 -0
  134. package/packages/logging/dist/index.js.map +1 -1
  135. package/packages/logging/dist/server/http.d.ts +4 -3
  136. package/packages/logging/dist/server/http.d.ts.map +1 -1
  137. package/packages/logging/dist/server/http.js +35 -3
  138. package/packages/logging/dist/server/http.js.map +1 -1
  139. package/packages/logging/dist/server/incident-qdrant.d.ts +83 -0
  140. package/packages/logging/dist/server/incident-qdrant.d.ts.map +1 -0
  141. package/packages/logging/dist/server/incident-qdrant.js +129 -0
  142. package/packages/logging/dist/server/incident-qdrant.js.map +1 -0
  143. package/packages/logging/dist/server/incident-store.d.ts +76 -0
  144. package/packages/logging/dist/server/incident-store.d.ts.map +1 -0
  145. package/packages/logging/dist/server/incident-store.js +157 -0
  146. package/packages/logging/dist/server/incident-store.js.map +1 -0
  147. package/packages/logging/dist/server/index.d.ts +4 -0
  148. package/packages/logging/dist/server/index.d.ts.map +1 -1
  149. package/packages/logging/dist/server/index.js +2 -0
  150. package/packages/logging/dist/server/index.js.map +1 -1
  151. package/packages/logging/dist/server/service.d.ts +33 -0
  152. package/packages/logging/dist/server/service.d.ts.map +1 -1
  153. package/packages/logging/dist/server/service.js +63 -0
  154. package/packages/logging/dist/server/service.js.map +1 -1
  155. package/packages/logging/dist/shipper.d.ts +74 -3
  156. package/packages/logging/dist/shipper.d.ts.map +1 -1
  157. package/packages/logging/dist/shipper.js +88 -5
  158. package/packages/logging/dist/shipper.js.map +1 -1
  159. package/packages/logging/dist/singleton.d.ts.map +1 -1
  160. package/packages/logging/dist/singleton.js +1 -0
  161. package/packages/logging/dist/singleton.js.map +1 -1
  162. package/packages/logging/package.json +1 -1
  163. package/packages/logging/src/config.ts +22 -0
  164. package/packages/logging/src/incidents/schema.ts +0 -0
  165. package/packages/logging/src/index.ts +17 -0
  166. package/packages/logging/src/server/http.ts +42 -3
  167. package/packages/logging/src/server/incident-qdrant.ts +177 -0
  168. package/packages/logging/src/server/incident-store.ts +192 -0
  169. package/packages/logging/src/server/index.ts +21 -0
  170. package/packages/logging/src/server/service.ts +79 -0
  171. package/packages/logging/src/shipper.ts +120 -5
  172. package/packages/logging/src/singleton.ts +1 -0
  173. package/packages/logging/test/fanout.test.ts +186 -0
  174. package/packages/logging/test/incidents.test.ts +404 -0
  175. package/packages/mcp-adapter/package.json +1 -1
  176. package/packages/memory-engine/package.json +1 -1
  177. package/packages/milestone-manager/package.json +1 -1
  178. package/packages/model-registry/package.json +1 -1
  179. package/packages/nextjs-plugin/package.json +1 -1
  180. package/packages/notification/dist/adapters/detail-format.d.ts +10 -2
  181. package/packages/notification/dist/adapters/detail-format.d.ts.map +1 -1
  182. package/packages/notification/dist/adapters/detail-format.js +39 -0
  183. package/packages/notification/dist/adapters/detail-format.js.map +1 -1
  184. package/packages/notification/dist/adapters/line-adapter.d.ts +33 -0
  185. package/packages/notification/dist/adapters/line-adapter.d.ts.map +1 -1
  186. package/packages/notification/dist/adapters/line-adapter.js +84 -7
  187. package/packages/notification/dist/adapters/line-adapter.js.map +1 -1
  188. package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +1 -1
  189. package/packages/notification/dist/adapters/telegram-adapter.js +6 -2
  190. package/packages/notification/dist/adapters/telegram-adapter.js.map +1 -1
  191. package/packages/notification/dist/notification-center.d.ts.map +1 -1
  192. package/packages/notification/dist/notification-center.js +59 -7
  193. package/packages/notification/dist/notification-center.js.map +1 -1
  194. package/packages/notification/dist/pending-question.d.ts +69 -2
  195. package/packages/notification/dist/pending-question.d.ts.map +1 -1
  196. package/packages/notification/dist/pending-question.js +88 -2
  197. package/packages/notification/dist/pending-question.js.map +1 -1
  198. package/packages/notification/dist/types.d.ts +18 -0
  199. package/packages/notification/dist/types.d.ts.map +1 -1
  200. package/packages/notification/package.json +1 -1
  201. package/packages/notification/src/adapters/detail-format.ts +42 -2
  202. package/packages/notification/src/adapters/line-adapter.ts +94 -7
  203. package/packages/notification/src/adapters/telegram-adapter.ts +6 -2
  204. package/packages/notification/src/notification-center.ts +65 -8
  205. package/packages/notification/src/pending-question.ts +160 -8
  206. package/packages/notification/src/types.ts +18 -0
  207. package/packages/notification/test/approval-payload.test.ts +269 -0
  208. package/packages/notification/test/pending-question-lifecycle.test.ts +195 -0
  209. package/packages/observability/package.json +1 -1
  210. package/packages/okf-indexer/dist/index.d.ts +9 -0
  211. package/packages/okf-indexer/dist/index.d.ts.map +1 -0
  212. package/packages/okf-indexer/dist/index.js +9 -0
  213. package/packages/okf-indexer/dist/index.js.map +1 -0
  214. package/packages/okf-indexer/package.json +1 -1
  215. package/packages/okf-indexer/src/index.ts +9 -0
  216. package/packages/paperclip-integration/package.json +1 -1
  217. package/packages/performance-optimizer/package.json +1 -1
  218. package/packages/permission-mode/package.json +1 -1
  219. package/packages/privilege-broker/package.json +1 -1
  220. package/packages/project-analyzer/package.json +1 -1
  221. package/packages/project-bootstrap/package.json +1 -1
  222. package/packages/projection-engine/package.json +1 -1
  223. package/packages/prompt-compiler/package.json +1 -1
  224. package/packages/prompt-versioning/package.json +1 -1
  225. package/packages/provider-adapter-sdk/package.json +1 -1
  226. package/packages/provider-router/dist/provider-router.d.ts.map +1 -1
  227. package/packages/provider-router/dist/types.d.ts +2 -2
  228. package/packages/provider-router/dist/types.d.ts.map +1 -1
  229. package/packages/provider-router/dist/types.js +1 -1
  230. package/packages/provider-router/package.json +1 -1
  231. package/packages/provider-router/src/types.ts +2 -2
  232. package/packages/provider-selector/package.json +1 -1
  233. package/packages/providers/package.json +1 -1
  234. package/packages/qdrant-skills/package.json +1 -1
  235. package/packages/quota-manager/package.json +1 -1
  236. package/packages/rate-limiter/package.json +1 -1
  237. package/packages/react-vite-plugin/package.json +1 -1
  238. package/packages/relay/package.json +1 -1
  239. package/packages/release-manager/package.json +1 -1
  240. package/packages/requirement-compiler/package.json +1 -1
  241. package/packages/runtime/package.json +1 -1
  242. package/packages/scheduler/dist/index.d.ts +9 -0
  243. package/packages/scheduler/dist/index.d.ts.map +1 -0
  244. package/packages/scheduler/dist/index.js +9 -0
  245. package/packages/scheduler/dist/index.js.map +1 -0
  246. package/packages/scheduler/dist/scheduler.d.ts +17 -0
  247. package/packages/scheduler/dist/scheduler.d.ts.map +1 -0
  248. package/packages/scheduler/dist/scheduler.js +41 -0
  249. package/packages/scheduler/dist/scheduler.js.map +1 -0
  250. package/packages/scheduler/package.json +1 -1
  251. package/packages/scheduler/src/index.ts +9 -0
  252. package/packages/scheduler-adapter/package.json +1 -1
  253. package/packages/session/package.json +1 -1
  254. package/packages/session-api/package.json +1 -1
  255. package/packages/session-export/package.json +1 -1
  256. package/packages/shared-context/dist/index.d.ts +7 -0
  257. package/packages/shared-context/dist/index.d.ts.map +1 -0
  258. package/packages/shared-context/dist/index.js +7 -0
  259. package/packages/shared-context/dist/index.js.map +1 -0
  260. package/packages/shared-context/dist/shared-context.d.ts +12 -0
  261. package/packages/shared-context/dist/shared-context.d.ts.map +1 -0
  262. package/packages/shared-context/dist/shared-context.js +39 -0
  263. package/packages/shared-context/dist/shared-context.js.map +1 -0
  264. package/packages/shared-context/package.json +1 -1
  265. package/packages/skill-mcp-client/dist/client.d.ts +56 -0
  266. package/packages/skill-mcp-client/dist/client.d.ts.map +1 -0
  267. package/packages/skill-mcp-client/dist/client.js +101 -0
  268. package/packages/skill-mcp-client/dist/client.js.map +1 -0
  269. package/packages/skill-mcp-client/dist/errors.d.ts +44 -0
  270. package/packages/skill-mcp-client/dist/errors.d.ts.map +1 -0
  271. package/packages/skill-mcp-client/dist/errors.js +68 -0
  272. package/packages/skill-mcp-client/dist/errors.js.map +1 -0
  273. package/packages/skill-mcp-client/dist/index.d.ts +9 -0
  274. package/packages/skill-mcp-client/dist/index.d.ts.map +1 -0
  275. package/packages/skill-mcp-client/dist/index.js +9 -0
  276. package/packages/skill-mcp-client/dist/index.js.map +1 -0
  277. package/packages/skill-mcp-client/dist/types.d.ts +106 -0
  278. package/packages/skill-mcp-client/dist/types.d.ts.map +1 -0
  279. package/packages/skill-mcp-client/dist/types.js +14 -0
  280. package/packages/skill-mcp-client/dist/types.js.map +1 -0
  281. package/packages/skill-mcp-client/package.json +1 -1
  282. package/packages/skill-registry/package.json +1 -1
  283. package/packages/skills/package.json +1 -5
  284. package/packages/sprint-planner/package.json +1 -1
  285. package/packages/subscription-engine/package.json +1 -1
  286. package/packages/task-compiler/package.json +1 -1
  287. package/packages/telegram/package.json +1 -1
  288. package/packages/telegram/src/agent-messages.d.ts +28 -0
  289. package/packages/telegram/src/agent-messages.js +90 -0
  290. package/packages/telegram/src/bindings.d.ts +296 -0
  291. package/packages/telegram/src/bindings.js +1086 -0
  292. package/packages/telegram/src/bus.d.ts +759 -0
  293. package/packages/telegram/src/bus.js +2732 -0
  294. package/packages/telegram/src/commands.d.ts +761 -0
  295. package/packages/telegram/src/commands.js +2622 -0
  296. package/packages/telegram/src/config.d.ts +222 -0
  297. package/packages/telegram/src/config.js +844 -0
  298. package/packages/telegram/src/delivery.d.ts +161 -0
  299. package/packages/telegram/src/delivery.js +550 -0
  300. package/packages/telegram/src/extension.d.ts +7 -0
  301. package/packages/telegram/src/extension.js +2444 -0
  302. package/packages/telegram/src/inbound.d.ts +94 -0
  303. package/packages/telegram/src/inbound.js +478 -0
  304. package/packages/telegram/src/index.d.ts +6 -0
  305. package/packages/telegram/src/index.js +6 -0
  306. package/packages/telegram/src/keyboard.d.ts +21 -0
  307. package/packages/telegram/src/keyboard.js +37 -0
  308. package/packages/telegram/src/lifecycle.d.ts +210 -0
  309. package/packages/telegram/src/lifecycle.js +538 -0
  310. package/packages/telegram/src/pi.d.ts +76 -0
  311. package/packages/telegram/src/pi.js +130 -0
  312. package/packages/telegram/src/polling.d.ts +332 -0
  313. package/packages/telegram/src/polling.js +1219 -0
  314. package/packages/telegram/src/replies.d.ts +210 -0
  315. package/packages/telegram/src/replies.js +752 -0
  316. package/packages/telegram/src/routing.d.ts +388 -0
  317. package/packages/telegram/src/routing.js +7886 -0
  318. package/packages/telegram/src/runtime.d.ts +159 -0
  319. package/packages/telegram/src/runtime.js +351 -0
  320. package/packages/telegram/src/telegram-api.d.ts +564 -0
  321. package/packages/telegram/src/telegram-api.js +1332 -0
  322. package/packages/telegram/src/turns.d.ts +108 -0
  323. package/packages/telegram/src/turns.js +482 -0
  324. package/packages/telegram/src/updates.d.ts +1545 -0
  325. package/packages/telegram/src/updates.js +6420 -0
  326. package/packages/tencentdb-memory/package.json +1 -1
  327. package/packages/tencentdb-sync/package.json +1 -1
  328. package/packages/test-data-generator/package.json +1 -1
  329. package/packages/test-generator/package.json +1 -1
  330. package/packages/todo-bd-sync/dist/detector.d.ts +54 -0
  331. package/packages/todo-bd-sync/dist/detector.d.ts.map +1 -0
  332. package/packages/todo-bd-sync/dist/detector.js +132 -0
  333. package/packages/todo-bd-sync/dist/detector.js.map +1 -0
  334. package/packages/todo-bd-sync/dist/extension.d.ts +30 -0
  335. package/packages/todo-bd-sync/dist/extension.d.ts.map +1 -0
  336. package/packages/todo-bd-sync/dist/extension.js +35 -0
  337. package/packages/todo-bd-sync/dist/extension.js.map +1 -0
  338. package/packages/todo-bd-sync/dist/index.d.ts +87 -0
  339. package/packages/todo-bd-sync/dist/index.d.ts.map +1 -0
  340. package/packages/todo-bd-sync/dist/index.js +296 -0
  341. package/packages/todo-bd-sync/dist/index.js.map +1 -0
  342. package/packages/todo-bd-sync/dist/sync.d.ts +72 -0
  343. package/packages/todo-bd-sync/dist/sync.d.ts.map +1 -0
  344. package/packages/todo-bd-sync/dist/sync.js +290 -0
  345. package/packages/todo-bd-sync/dist/sync.js.map +1 -0
  346. package/packages/todo-bd-sync/dist/task-analyzer.d.ts +49 -0
  347. package/packages/todo-bd-sync/dist/task-analyzer.d.ts.map +1 -0
  348. package/packages/todo-bd-sync/dist/task-analyzer.js +240 -0
  349. package/packages/todo-bd-sync/dist/task-analyzer.js.map +1 -0
  350. package/packages/todo-bd-sync/dist/todo-reminder.d.ts +126 -0
  351. package/packages/todo-bd-sync/dist/todo-reminder.d.ts.map +1 -0
  352. package/packages/todo-bd-sync/dist/todo-reminder.js +329 -0
  353. package/packages/todo-bd-sync/dist/todo-reminder.js.map +1 -0
  354. package/packages/todo-bd-sync/dist/types.d.ts +65 -0
  355. package/packages/todo-bd-sync/dist/types.d.ts.map +1 -0
  356. package/packages/todo-bd-sync/dist/types.js +67 -0
  357. package/packages/todo-bd-sync/dist/types.js.map +1 -0
  358. package/packages/todo-bd-sync/package.json +1 -1
  359. package/packages/token-estimation/dist/index.d.ts +94 -0
  360. package/packages/token-estimation/dist/index.d.ts.map +1 -0
  361. package/packages/token-estimation/dist/index.js +115 -0
  362. package/packages/token-estimation/dist/index.js.map +1 -0
  363. package/packages/token-estimation/package.json +1 -1
  364. package/packages/token-optimizer/package.json +1 -1
  365. package/packages/trajectory/package.json +1 -1
  366. package/packages/tui/package.json +1 -1
  367. package/packages/types/dist/ai-providers.d.ts +36 -0
  368. package/packages/types/dist/ai-providers.d.ts.map +1 -0
  369. package/packages/types/dist/ai-providers.js +66 -0
  370. package/packages/types/dist/ai-providers.js.map +1 -0
  371. package/packages/types/dist/index.d.ts +12 -0
  372. package/packages/types/dist/index.d.ts.map +1 -0
  373. package/packages/types/dist/index.js +12 -0
  374. package/packages/types/dist/index.js.map +1 -0
  375. package/packages/types/package.json +5 -5
  376. package/packages/types/src/index.ts +12 -0
  377. package/packages/voice-api/package.json +1 -1
  378. package/packages/webmcp-tester/package.json +1 -1
  379. package/packages/wiki/package.json +1 -1
  380. package/packages/workflow-events/package.json +1 -1
  381. package/packages/workspace-scanner/package.json +1 -1
  382. package/packages/worktree/package.json +1 -1
  383. package/packages/worktree/worktree.ts +1 -1
  384. package/packages/write-review/package.json +1 -1
  385. package/renderer.ts +1 -1
  386. package/scripts/build-packages.ts +162 -0
  387. package/scripts/relay-client.ts +2 -2
  388. package/scripts/typecheck-packages.mjs +3 -3
  389. package/scripts/unified-webhook-server.ts +22 -10
  390. package/scripts/verify-package-contents.ts +345 -0
  391. package/scripts/ws-server.ts +1 -1
  392. package/tracker.ts +1 -1
  393. package/harness/browser-scrapers/base-browser-scraper.d.ts +0 -91
  394. package/harness/browser-scrapers/chrome-profile-manager.d.ts +0 -80
  395. package/harness/browser-scrapers/codex-browser-scraper.d.ts +0 -60
  396. package/harness/browser-scrapers/index.d.ts +0 -29
  397. package/harness/browser-scrapers/zai-browser-scraper.d.ts +0 -79
  398. package/harness/e2e/browser-scrapers/base-browser-scraper.d.ts +0 -92
  399. package/harness/e2e/browser-scrapers/chrome-profile-manager.d.ts +0 -81
  400. package/harness/e2e/browser-scrapers/codex-browser-scraper.d.ts +0 -61
  401. package/harness/e2e/browser-scrapers/index.d.ts +0 -30
  402. package/harness/e2e/browser-scrapers/zai-browser-scraper.d.ts +0 -80
  403. package/harness/langchain/agents.d.ts +0 -143
  404. package/harness/langchain/agents.test.d.ts +0 -2
  405. package/harness/langchain/checkpointer.d.ts +0 -48
  406. package/harness/langchain/checkpointer.test.d.ts +0 -8
  407. package/harness/langchain/cron-cli.d.ts +0 -12
  408. package/harness/langchain/daemon.d.ts +0 -161
  409. package/harness/langchain/daemon.test.d.ts +0 -11
  410. package/harness/langchain/file-tools.d.ts +0 -97
  411. package/harness/langchain/graph.d.ts +0 -706
  412. package/harness/langchain/model-router.d.ts +0 -63
  413. package/harness/langchain/model-router.test.d.ts +0 -2
  414. package/harness/langchain/models.d.ts +0 -72
  415. package/harness/langchain/ping-pong-middleware.d.ts +0 -28
  416. package/harness/langchain/ping-pong-middleware.test.d.ts +0 -2
  417. package/harness/langchain/run.d.ts +0 -15
  418. package/harness/langchain/scoreboard.test.d.ts +0 -13
  419. package/harness/langchain/status-line.d.ts +0 -91
  420. package/harness/langchain/status-line.test.d.ts +0 -8
  421. package/harness/langchain/surge.d.ts +0 -111
  422. package/harness/langchain/surge.test.d.ts +0 -10
  423. package/harness/langchain/widget.d.ts +0 -105
  424. package/harness/langchain/widget.test.d.ts +0 -8
  425. package/packages/autonomous-runtime/dist/worker.d.ts +0 -63
  426. package/packages/autonomous-runtime/dist/worker.js +0 -133
  427. package/packages/capability-registry/src/types.d.ts +0 -47
  428. package/packages/clipboard/dist/clipboard.d.ts +0 -11
  429. package/packages/clipboard/dist/clipboard.js +0 -40
  430. package/packages/clipboard/dist/index.d.ts +0 -2
  431. package/packages/clipboard/dist/index.js +0 -2
  432. package/packages/clipboard/dist/types.d.ts +0 -13
  433. package/packages/clipboard/dist/types.js +0 -5
  434. package/packages/context-discovery/dist/discover.d.ts +0 -3
  435. package/packages/context-discovery/dist/discover.js +0 -42
  436. package/packages/context-discovery/dist/discovery.d.ts +0 -28
  437. package/packages/context-discovery/dist/discovery.js +0 -21
  438. package/packages/context-discovery/dist/index.d.ts +0 -3
  439. package/packages/context-discovery/dist/index.js +0 -2
  440. package/packages/context-discovery/dist/types.d.ts +0 -16
  441. package/packages/context-discovery/dist/types.js +0 -2
  442. package/packages/event-bus/dist/bus.d.ts +0 -15
  443. package/packages/event-bus/dist/bus.js +0 -90
  444. package/packages/event-bus/dist/index.d.ts +0 -4
  445. package/packages/event-bus/dist/index.js +0 -3
  446. package/packages/event-bus/dist/test/bus.test.js +0 -52
  447. package/packages/event-bus/dist/types.d.ts +0 -27
  448. package/packages/event-bus/dist/types.js +0 -10
  449. package/packages/event-store/dist/index.d.ts +0 -3
  450. package/packages/event-store/dist/index.js +0 -2
  451. package/packages/event-store/dist/store.d.ts +0 -15
  452. package/packages/event-store/dist/store.js +0 -131
  453. package/packages/event-store/dist/test/store.test.js +0 -57
  454. package/packages/event-store/dist/types.d.ts +0 -48
  455. package/packages/event-store/dist/types.js +0 -5
  456. package/packages/event-store/src/types.d.ts +0 -48
  457. package/packages/file-copy-helper/dist/src/extension.js +0 -186
  458. package/packages/model-registry/src/types.d.ts +0 -63
  459. package/packages/notification/dist/src/adapters/email-adapter.d.ts +0 -17
  460. package/packages/notification/dist/src/adapters/email-adapter.d.ts.map +0 -1
  461. package/packages/notification/dist/src/adapters/email-adapter.js +0 -89
  462. package/packages/notification/dist/src/adapters/email-adapter.js.map +0 -1
  463. package/packages/notification/dist/src/adapters/line-adapter.d.ts +0 -17
  464. package/packages/notification/dist/src/adapters/line-adapter.d.ts.map +0 -1
  465. package/packages/notification/dist/src/adapters/line-adapter.js +0 -99
  466. package/packages/notification/dist/src/adapters/line-adapter.js.map +0 -1
  467. package/packages/notification/dist/src/adapters/ntfy-adapter.d.ts +0 -17
  468. package/packages/notification/dist/src/adapters/ntfy-adapter.d.ts.map +0 -1
  469. package/packages/notification/dist/src/adapters/ntfy-adapter.js +0 -84
  470. package/packages/notification/dist/src/adapters/ntfy-adapter.js.map +0 -1
  471. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts +0 -56
  472. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts.map +0 -1
  473. package/packages/notification/dist/src/adapters/telegram-adapter.js +0 -251
  474. package/packages/notification/dist/src/adapters/telegram-adapter.js.map +0 -1
  475. package/packages/notification/dist/src/adapters/webhook-adapter.d.ts +0 -15
  476. package/packages/notification/dist/src/adapters/webhook-adapter.d.ts.map +0 -1
  477. package/packages/notification/dist/src/adapters/webhook-adapter.js +0 -64
  478. package/packages/notification/dist/src/adapters/webhook-adapter.js.map +0 -1
  479. package/packages/notification/dist/src/base-adapter.d.ts +0 -36
  480. package/packages/notification/dist/src/base-adapter.d.ts.map +0 -1
  481. package/packages/notification/dist/src/base-adapter.js +0 -39
  482. package/packages/notification/dist/src/base-adapter.js.map +0 -1
  483. package/packages/notification/dist/src/index.d.ts +0 -12
  484. package/packages/notification/dist/src/index.d.ts.map +0 -1
  485. package/packages/notification/dist/src/index.js +0 -12
  486. package/packages/notification/dist/src/index.js.map +0 -1
  487. package/packages/notification/dist/src/notification-center.d.ts +0 -89
  488. package/packages/notification/dist/src/notification-center.d.ts.map +0 -1
  489. package/packages/notification/dist/src/notification-center.js +0 -356
  490. package/packages/notification/dist/src/notification-center.js.map +0 -1
  491. package/packages/notification/dist/src/notification-policy.d.ts +0 -66
  492. package/packages/notification/dist/src/notification-policy.d.ts.map +0 -1
  493. package/packages/notification/dist/src/notification-policy.js +0 -153
  494. package/packages/notification/dist/src/notification-policy.js.map +0 -1
  495. package/packages/notification/dist/src/telegram-webhook-handler.d.ts +0 -86
  496. package/packages/notification/dist/src/telegram-webhook-handler.d.ts.map +0 -1
  497. package/packages/notification/dist/src/telegram-webhook-handler.js +0 -149
  498. package/packages/notification/dist/src/telegram-webhook-handler.js.map +0 -1
  499. package/packages/notification/dist/src/types.d.ts +0 -106
  500. package/packages/notification/dist/src/types.d.ts.map +0 -1
  501. package/packages/notification/dist/src/types.js +0 -7
  502. package/packages/notification/dist/src/types.js.map +0 -1
  503. package/packages/projection-engine/dist/engine.d.ts +0 -61
  504. package/packages/projection-engine/dist/engine.js +0 -76
  505. package/packages/projection-engine/dist/index.d.ts +0 -2
  506. package/packages/projection-engine/dist/index.js +0 -2
  507. package/packages/projection-engine/dist/project.d.ts +0 -3
  508. package/packages/projection-engine/dist/project.js +0 -24
  509. package/packages/projection-engine/dist/types.d.ts +0 -55
  510. package/packages/projection-engine/dist/types.js +0 -5
  511. package/packages/projection-engine/src/types.d.ts +0 -55
  512. package/packages/provider-adapter-sdk/dist/src/builder.d.ts +0 -140
  513. package/packages/provider-adapter-sdk/dist/src/builder.d.ts.map +0 -1
  514. package/packages/provider-adapter-sdk/dist/src/builder.js +0 -332
  515. package/packages/provider-adapter-sdk/dist/src/builder.js.map +0 -1
  516. package/packages/provider-adapter-sdk/dist/src/errors.d.ts +0 -71
  517. package/packages/provider-adapter-sdk/dist/src/errors.d.ts.map +0 -1
  518. package/packages/provider-adapter-sdk/dist/src/errors.js +0 -111
  519. package/packages/provider-adapter-sdk/dist/src/errors.js.map +0 -1
  520. package/packages/provider-adapter-sdk/dist/src/index.d.ts +0 -15
  521. package/packages/provider-adapter-sdk/dist/src/index.d.ts.map +0 -1
  522. package/packages/provider-adapter-sdk/dist/src/index.js +0 -19
  523. package/packages/provider-adapter-sdk/dist/src/index.js.map +0 -1
  524. package/packages/provider-adapter-sdk/dist/src/registry.d.ts +0 -108
  525. package/packages/provider-adapter-sdk/dist/src/registry.d.ts.map +0 -1
  526. package/packages/provider-adapter-sdk/dist/src/registry.js +0 -301
  527. package/packages/provider-adapter-sdk/dist/src/registry.js.map +0 -1
  528. package/packages/provider-adapter-sdk/dist/src/tester.d.ts +0 -71
  529. package/packages/provider-adapter-sdk/dist/src/tester.d.ts.map +0 -1
  530. package/packages/provider-adapter-sdk/dist/src/tester.js +0 -392
  531. package/packages/provider-adapter-sdk/dist/src/tester.js.map +0 -1
  532. package/packages/provider-adapter-sdk/dist/src/types.d.ts +0 -182
  533. package/packages/provider-adapter-sdk/dist/src/types.d.ts.map +0 -1
  534. package/packages/provider-adapter-sdk/dist/src/types.js +0 -11
  535. package/packages/provider-adapter-sdk/dist/src/types.js.map +0 -1
  536. package/packages/provider-router/dist/capability-registry/src/types.d.ts +0 -47
  537. package/packages/provider-router/dist/capability-registry/src/types.d.ts.map +0 -1
  538. package/packages/provider-router/dist/capability-registry/src/types.js +0 -10
  539. package/packages/provider-router/dist/capability-registry/src/types.js.map +0 -1
  540. package/packages/provider-router/dist/provider-router/src/index.d.ts +0 -23
  541. package/packages/provider-router/dist/provider-router/src/index.d.ts.map +0 -1
  542. package/packages/provider-router/dist/provider-router/src/index.js +0 -25
  543. package/packages/provider-router/dist/provider-router/src/index.js.map +0 -1
  544. package/packages/provider-router/dist/provider-router/src/policy.d.ts +0 -10
  545. package/packages/provider-router/dist/provider-router/src/policy.d.ts.map +0 -1
  546. package/packages/provider-router/dist/provider-router/src/policy.js +0 -45
  547. package/packages/provider-router/dist/provider-router/src/policy.js.map +0 -1
  548. package/packages/provider-router/dist/provider-router/src/provider-router.d.ts +0 -56
  549. package/packages/provider-router/dist/provider-router/src/provider-router.d.ts.map +0 -1
  550. package/packages/provider-router/dist/provider-router/src/provider-router.js +0 -222
  551. package/packages/provider-router/dist/provider-router/src/provider-router.js.map +0 -1
  552. package/packages/provider-router/dist/provider-router/src/strategies.d.ts +0 -19
  553. package/packages/provider-router/dist/provider-router/src/strategies.d.ts.map +0 -1
  554. package/packages/provider-router/dist/provider-router/src/strategies.js +0 -110
  555. package/packages/provider-router/dist/provider-router/src/strategies.js.map +0 -1
  556. package/packages/provider-router/dist/provider-router/src/types.d.ts +0 -91
  557. package/packages/provider-router/dist/provider-router/src/types.d.ts.map +0 -1
  558. package/packages/provider-router/dist/provider-router/src/types.js +0 -10
  559. package/packages/provider-router/dist/provider-router/src/types.js.map +0 -1
  560. package/packages/provider-router/dist/src/index.d.ts +0 -23
  561. package/packages/provider-router/dist/src/index.d.ts.map +0 -1
  562. package/packages/provider-router/dist/src/index.js +0 -25
  563. package/packages/provider-router/dist/src/index.js.map +0 -1
  564. package/packages/provider-router/dist/src/policy.d.ts +0 -10
  565. package/packages/provider-router/dist/src/policy.d.ts.map +0 -1
  566. package/packages/provider-router/dist/src/policy.js +0 -45
  567. package/packages/provider-router/dist/src/policy.js.map +0 -1
  568. package/packages/provider-router/dist/src/provider-router.d.ts +0 -56
  569. package/packages/provider-router/dist/src/provider-router.d.ts.map +0 -1
  570. package/packages/provider-router/dist/src/provider-router.js +0 -222
  571. package/packages/provider-router/dist/src/provider-router.js.map +0 -1
  572. package/packages/provider-router/dist/src/strategies.d.ts +0 -19
  573. package/packages/provider-router/dist/src/strategies.d.ts.map +0 -1
  574. package/packages/provider-router/dist/src/strategies.js +0 -110
  575. package/packages/provider-router/dist/src/strategies.js.map +0 -1
  576. package/packages/provider-router/dist/src/types.d.ts +0 -91
  577. package/packages/provider-router/dist/src/types.d.ts.map +0 -1
  578. package/packages/provider-router/dist/src/types.js +0 -10
  579. package/packages/provider-router/dist/src/types.js.map +0 -1
  580. package/packages/provider-router/dist/types/src/runtime-types.d.ts +0 -412
  581. package/packages/provider-router/dist/types/src/runtime-types.d.ts.map +0 -1
  582. package/packages/provider-router/dist/types/src/runtime-types.js +0 -2
  583. package/packages/provider-router/dist/types/src/runtime-types.js.map +0 -1
  584. package/packages/session-api/dist/api.d.ts +0 -83
  585. package/packages/session-api/dist/api.js +0 -35
  586. package/packages/session-api/dist/index.d.ts +0 -2
  587. package/packages/session-api/dist/index.js +0 -2
  588. package/packages/session-api/dist/types.d.ts +0 -22
  589. package/packages/session-api/dist/types.js +0 -5
  590. package/packages/session-export/dist/exporter.d.ts +0 -28
  591. package/packages/session-export/dist/exporter.js +0 -38
  592. package/packages/session-export/dist/index.d.ts +0 -2
  593. package/packages/session-export/dist/index.js +0 -2
  594. package/packages/session-export/dist/types.d.ts +0 -20
  595. package/packages/session-export/dist/types.js +0 -5
  596. package/packages/subscription-engine/dist/engine.d.ts +0 -13
  597. package/packages/subscription-engine/dist/engine.js +0 -40
  598. package/packages/subscription-engine/dist/index.d.ts +0 -2
  599. package/packages/subscription-engine/dist/index.js +0 -2
  600. package/packages/subscription-engine/dist/subscriptions.d.ts +0 -19
  601. package/packages/subscription-engine/dist/subscriptions.js +0 -32
  602. package/packages/subscription-engine/dist/types.d.ts +0 -24
  603. package/packages/subscription-engine/dist/types.js +0 -5
  604. package/packages/trajectory/test/store.test.d.ts +0 -2
  605. package/packages/workflow-events/dist/events.d.ts +0 -38
  606. package/packages/workflow-events/dist/events.js +0 -46
  607. package/packages/workflow-events/dist/index.d.ts +0 -2
  608. package/packages/workflow-events/dist/index.js +0 -2
  609. package/packages/workflow-events/dist/pipeline.d.ts +0 -21
  610. package/packages/workflow-events/dist/pipeline.js +0 -27
  611. package/packages/workflow-events/dist/types.d.ts +0 -110
  612. package/packages/workflow-events/dist/types.js +0 -5
  613. package/packages/workflow-events/src/types.d.ts +0 -110
@@ -0,0 +1,752 @@
1
+ /**
2
+ * Telegram reply delivery helpers
3
+ * Zones: telegram outbound, native rich markdown, UI/compat rendering transport
4
+ * Owns native assistant replies, rendered UI delivery, guest placeholder rotation, reply transport wiring, and plain text replies
5
+ */
6
+ import { assertTelegramInlineKeyboardCallbackData } from "./keyboard.js";
7
+ import { renderTelegramMessage, } from "./rendering.js";
8
+ import { getTelegramTargetThreadParams, } from "./target.js";
9
+ import { assertTelegramApiCallAuthority, isTelegramApiCommitUnknownError, TelegramApiAuthorityError, } from "./telegram-api.js";
10
+ export { renderTelegramMessage, };
11
+ export function renderTelegramMarkdownToHtmlDraft(markdown) {
12
+ return renderTelegramMessage(markdown, { mode: "markdown" })
13
+ .map((chunk) => chunk.text)
14
+ .join("\n");
15
+ }
16
+ export const TELEGRAM_RICH_MESSAGE_MAX_CHARS = 32768;
17
+ export const TELEGRAM_RICH_MESSAGE_MAX_BLOCKS = 500;
18
+ const lastRepliedToMessageIdByTarget = new Map();
19
+ const replyDedupPreservedOnNextReset = new Map();
20
+ let replyDedupGeneration = 0;
21
+ function getReplyDedupTargetKey(chatId, target) {
22
+ const threadId = target?.threadId;
23
+ return typeof threadId === "number"
24
+ ? `${chatId}:thread:${threadId}`
25
+ : `${chatId}:private`;
26
+ }
27
+ export function resetTransportReplyDedup() {
28
+ replyDedupGeneration += 1;
29
+ lastRepliedToMessageIdByTarget.clear();
30
+ for (const [key, messageId] of replyDedupPreservedOnNextReset) {
31
+ lastRepliedToMessageIdByTarget.set(key, messageId);
32
+ }
33
+ replyDedupPreservedOnNextReset.clear();
34
+ }
35
+ /** Keeps a successfully published transition notice as the first reply of the
36
+ * next agent turn. The following agent-start reset consumes this one-shot
37
+ * preservation, so later messages in that turn do not repeat the reply header. */
38
+ export function preserveTransportReplyDedupOnNextReset(chatId, messageId, target) {
39
+ const key = getReplyDedupTargetKey(chatId, target);
40
+ if (lastRepliedToMessageIdByTarget.get(key) !== messageId)
41
+ return;
42
+ replyDedupPreservedOnNextReset.set(key, messageId);
43
+ }
44
+ export function buildTelegramReplyParameters(chatId, messageId, target) {
45
+ if (messageId === undefined || messageId <= 0)
46
+ return undefined;
47
+ const key = getReplyDedupTargetKey(chatId, target);
48
+ if (lastRepliedToMessageIdByTarget.get(key) === messageId) {
49
+ return undefined;
50
+ }
51
+ lastRepliedToMessageIdByTarget.set(key, messageId);
52
+ return {
53
+ message_id: messageId,
54
+ allow_sending_without_reply: true,
55
+ };
56
+ }
57
+ // Answer publications are caller-serialized. A rejected send releases its anchor;
58
+ // an uncertain ACK retains it because Telegram may already have delivered it.
59
+ export async function withTelegramReplyParameters(chatId, messageId, target, send) {
60
+ const key = getReplyDedupTargetKey(chatId, target);
61
+ const generation = replyDedupGeneration;
62
+ const previous = lastRepliedToMessageIdByTarget.get(key);
63
+ const parameters = buildTelegramReplyParameters(chatId, messageId, target);
64
+ try {
65
+ return await send(parameters);
66
+ }
67
+ catch (error) {
68
+ if (parameters &&
69
+ !isTelegramApiCommitUnknownError(error) &&
70
+ !(error instanceof TelegramApiAuthorityError && error.requestIssued) &&
71
+ generation === replyDedupGeneration &&
72
+ lastRepliedToMessageIdByTarget.get(key) === messageId) {
73
+ if (previous === undefined)
74
+ lastRepliedToMessageIdByTarget.delete(key);
75
+ else
76
+ lastRepliedToMessageIdByTarget.set(key, previous);
77
+ }
78
+ throw error;
79
+ }
80
+ }
81
+ function getAgentMessageField(message, field) {
82
+ if (typeof message !== "object" || message === null || !(field in message)) {
83
+ return undefined;
84
+ }
85
+ return Reflect.get(message, field);
86
+ }
87
+ export function isAssistantAgentMessage(message) {
88
+ return getAgentMessageField(message, "role") === "assistant";
89
+ }
90
+ function extractAgentTextContent(content) {
91
+ const blocks = Array.isArray(content) ? content : [];
92
+ return blocks
93
+ .filter((block) => typeof block === "object" && block !== null && "type" in block)
94
+ .filter((block) => block.type === "text" && typeof block.text === "string")
95
+ .map((block) => block.text)
96
+ .join("")
97
+ .trim();
98
+ }
99
+ export function getAgentMessageText(message) {
100
+ return extractAgentTextContent(getAgentMessageField(message, "content"));
101
+ }
102
+ export function extractLatestAssistantMessageText(messages) {
103
+ for (let i = messages.length - 1; i >= 0; i--) {
104
+ const message = messages[i];
105
+ if (!message || !isAssistantAgentMessage(message))
106
+ continue;
107
+ const rawStopReason = getAgentMessageField(message, "stopReason");
108
+ const rawErrorMessage = getAgentMessageField(message, "errorMessage");
109
+ const stopReason = typeof rawStopReason === "string" ? rawStopReason : undefined;
110
+ const errorMessage = typeof rawErrorMessage === "string" ? rawErrorMessage : undefined;
111
+ const text = getAgentMessageText(message);
112
+ return { text: text || undefined, stopReason, errorMessage };
113
+ }
114
+ return {};
115
+ }
116
+ /**
117
+ * Extract the run's answer without trusting an empty final assistant message.
118
+ * A low-level run may end with a completed assistant message whose content was
119
+ * suppressed (a companion extension preserving an earlier draft, for example
120
+ * State Flow's fallback final:true patch turn). In that case the run's answer
121
+ * is the latest earlier completed assistant message that carries text;
122
+ * tool-use prefaces, errors, and aborts stay excluded.
123
+ */
124
+ export function extractRunAssistantMessage(messages) {
125
+ const latest = extractLatestAssistantMessageText(messages);
126
+ if (latest.text || latest.stopReason !== "stop")
127
+ return latest;
128
+ for (let i = messages.length - 1; i >= 0; i--) {
129
+ const message = messages[i];
130
+ if (!message || !isAssistantAgentMessage(message))
131
+ continue;
132
+ const rawStopReason = getAgentMessageField(message, "stopReason");
133
+ if (rawStopReason === "toolUse" ||
134
+ rawStopReason === "error" ||
135
+ rawStopReason === "aborted") {
136
+ continue;
137
+ }
138
+ const text = getAgentMessageText(message);
139
+ if (!text)
140
+ continue;
141
+ const rawErrorMessage = getAgentMessageField(message, "errorMessage");
142
+ return {
143
+ text,
144
+ stopReason: typeof rawStopReason === "string" ? rawStopReason : undefined,
145
+ errorMessage: typeof rawErrorMessage === "string" ? rawErrorMessage : undefined,
146
+ recoveredFromEarlier: true,
147
+ };
148
+ }
149
+ return latest;
150
+ }
151
+ export function buildTelegramReplyTransport(deps) {
152
+ return {
153
+ sendRenderedChunks: async (chatId, chunks, options) => {
154
+ return sendTelegramRenderedChunks(chatId, chunks, deps, options);
155
+ },
156
+ editRenderedMessage: async (chatId, messageId, chunks, options) => {
157
+ return editTelegramRenderedMessage(chatId, messageId, chunks, deps, options);
158
+ },
159
+ };
160
+ }
161
+ export async function sendTelegramRenderedChunks(chatId, chunks, deps, options) {
162
+ return sendTelegramChunkSequence(chatId, chunks, options?.replyToMessageId, options, deps.recordOwnership, (chunk, fields, callOptions) => deps.sendMessage({
163
+ chat_id: chatId,
164
+ text: chunk.text,
165
+ parse_mode: chunk.parseMode,
166
+ ...fields,
167
+ }, callOptions));
168
+ }
169
+ /**
170
+ * Ordered chunk delivery: only the first chunk replies, only the last carries markup, and authority is rechecked
171
+ * before issuance and after every response/ownership publication.
172
+ */
173
+ async function sendTelegramChunkSequence(chatId, chunks, replyToMessageId, options, recordOwnership, send) {
174
+ const target = options?.target && { ...options.target }, assertAuthority = options?.assertAuthority, replyMarkup = options?.replyMarkup;
175
+ assertTelegramInlineKeyboardCallbackData(replyMarkup);
176
+ let lastMessageId;
177
+ for (const [index, chunk] of chunks.entries()) {
178
+ assertTelegramApiCallAuthority(assertAuthority, false);
179
+ const sent = await withTelegramReplyParameters(chatId, index === 0 ? replyToMessageId : undefined, target, async (replyParameters) => {
180
+ const sent = await send(chunk, {
181
+ reply_markup: index === chunks.length - 1 ? replyMarkup : undefined,
182
+ ...(replyParameters ? { reply_parameters: replyParameters } : {}),
183
+ ...(target ? getTelegramTargetThreadParams(target) : {}),
184
+ }, assertAuthority ? { assertAuthority } : undefined);
185
+ assertTelegramApiCallAuthority(assertAuthority, true);
186
+ return sent;
187
+ });
188
+ assertTelegramApiCallAuthority(assertAuthority, true);
189
+ lastMessageId = sent.message_id;
190
+ recordOwnership?.({ chatId, messageId: sent.message_id, target });
191
+ assertTelegramApiCallAuthority(assertAuthority, true);
192
+ }
193
+ return lastMessageId;
194
+ }
195
+ export async function editTelegramRenderedMessage(chatId, messageId, chunks, deps, options) {
196
+ options = { ...options, target: options?.target && { ...options.target } };
197
+ const assertAuthority = options.assertAuthority;
198
+ assertTelegramApiCallAuthority(assertAuthority, false);
199
+ assertTelegramInlineKeyboardCallbackData(options?.replyMarkup);
200
+ if (chunks.length === 0)
201
+ return messageId;
202
+ const [firstChunk, ...remainingChunks] = chunks;
203
+ if (!assertAuthority)
204
+ deps.recordOwnership?.({ chatId, messageId, target: options.target });
205
+ await deps.editMessage({
206
+ chat_id: chatId,
207
+ message_id: messageId,
208
+ text: firstChunk.text,
209
+ parse_mode: firstChunk.parseMode,
210
+ reply_markup: remainingChunks.length === 0 ? options?.replyMarkup : undefined,
211
+ ...(options?.target ? getTelegramTargetThreadParams(options.target) : {}),
212
+ }, assertAuthority ? { assertAuthority } : undefined);
213
+ assertTelegramApiCallAuthority(assertAuthority, true);
214
+ if (assertAuthority)
215
+ deps.recordOwnership?.({ chatId, messageId, target: options.target });
216
+ assertTelegramApiCallAuthority(assertAuthority, true);
217
+ if (remainingChunks.length > 0) {
218
+ return sendTelegramRenderedChunks(chatId, remainingChunks, deps, {
219
+ replyMarkup: options?.replyMarkup,
220
+ target: options?.target,
221
+ assertAuthority,
222
+ });
223
+ }
224
+ return messageId;
225
+ }
226
+ export async function sendTelegramPlainReply(text, deps, options) {
227
+ options = { ...options, target: options?.target && { ...options.target } };
228
+ const chunks = deps.renderTelegramMessage(text, {
229
+ mode: options?.parseMode === "HTML" ? "html" : "plain",
230
+ });
231
+ return deps.sendRenderedChunks(chunks, {
232
+ target: options?.target,
233
+ replyToMessageId: options?.replyToMessageId,
234
+ assertAuthority: options.assertAuthority,
235
+ });
236
+ }
237
+ function normalizeIndentedTelegramNativeMarkdownList(line) {
238
+ return line.replace(/^( +|\t+)([-*+] |\d+\. )/, (_match, indent, marker) => {
239
+ const visibleIndent = indent
240
+ .replace(/ /g, "\u00A0")
241
+ .replace(/\t/g, "\u00A0\u00A0");
242
+ return `${visibleIndent}${marker}`;
243
+ });
244
+ }
245
+ function normalizeTelegramNativeMarkdownLine(line) {
246
+ let result = normalizeIndentedTelegramNativeMarkdownList(line.replace(/^( {0,3}>)[ \t]/, "$1"));
247
+ const codeSpans = [];
248
+ result = result.replace(/`+[^`]*`+/g, (code) => {
249
+ const token = `\u0000${codeSpans.length}\u0000`;
250
+ codeSpans.push(code);
251
+ return token;
252
+ });
253
+ result = result.replace(/(^|[^\\$])\$([A-Z][A-Z0-9]{1,})(?!\$)(?=\b|[.,;:)/-])/g, (_match, prefix, ticker) => `${prefix}\\$${ticker}`);
254
+ return result.replace(/\u0000(\d+)\u0000/g, (_match, index) => codeSpans[Number(index)] ?? "");
255
+ }
256
+ export function parseTelegramMarkdownFenceOpening(line) {
257
+ const markerText = line.match(/^ {0,3}(`{3,}|~{3,})/)?.[1];
258
+ return markerText
259
+ ? { marker: markerText[0], length: markerText.length }
260
+ : undefined;
261
+ }
262
+ export function isTelegramMarkdownFenceClosing(line, fence) {
263
+ return new RegExp(`^ {0,3}${fence.marker}{${fence.length},}\\s*$`).test(line);
264
+ }
265
+ /** Fence state after one line: outside a fence a marker opens one; inside, a matching marker closes it. */
266
+ function advanceTelegramMarkdownFence(fence, line) {
267
+ if (!fence)
268
+ return parseTelegramMarkdownFenceOpening(line);
269
+ return isTelegramMarkdownFenceClosing(line, fence) ? undefined : fence;
270
+ }
271
+ function hasClosingDisplayMathDelimiter(lines, startIndex) {
272
+ let fence;
273
+ for (let index = startIndex + 1; index < lines.length; index += 1) {
274
+ const line = lines[index] ?? "";
275
+ if (!fence && line.trim() === "$$")
276
+ return true;
277
+ fence = advanceTelegramMarkdownFence(fence, line);
278
+ }
279
+ return false;
280
+ }
281
+ export function normalizeTelegramNativeMarkdown(markdown) {
282
+ const lines = markdown.replace(/\r\n/g, "\n").split("\n");
283
+ let fence;
284
+ let displayMath = false;
285
+ return lines
286
+ .map((line, index) => {
287
+ const inFence = fence !== undefined;
288
+ if (!inFence && line.trim() === "$$") {
289
+ if (displayMath) {
290
+ displayMath = false;
291
+ return "```";
292
+ }
293
+ if (hasClosingDisplayMathDelimiter(lines, index)) {
294
+ displayMath = true;
295
+ return "```math";
296
+ }
297
+ }
298
+ if (displayMath)
299
+ return line;
300
+ const nextFence = advanceTelegramMarkdownFence(fence, line);
301
+ if (nextFence !== fence) {
302
+ fence = nextFence;
303
+ return line;
304
+ }
305
+ if (!inFence)
306
+ return normalizeTelegramNativeMarkdownLine(line);
307
+ return line;
308
+ })
309
+ .join("\n");
310
+ }
311
+ export function splitTelegramNativeMarkdown(markdown) {
312
+ const normalizedMarkdown = normalizeTelegramNativeMarkdown(markdown);
313
+ if (normalizedMarkdown.length <= TELEGRAM_RICH_MESSAGE_MAX_CHARS &&
314
+ countTelegramNativeMarkdownBlocks(normalizedMarkdown) <=
315
+ TELEGRAM_RICH_MESSAGE_MAX_BLOCKS) {
316
+ return [normalizedMarkdown];
317
+ }
318
+ const chunks = [];
319
+ let current = "";
320
+ let currentBlockCount = 0;
321
+ for (const rawBlock of splitTelegramNativeMarkdownBlocks(normalizedMarkdown)) {
322
+ for (const block of splitTelegramNativeMarkdownCountedBlocks(rawBlock)) {
323
+ const blockCount = countTelegramNativeMarkdownBlocks(block);
324
+ const candidate = current ? `${current}\n\n${block}` : block;
325
+ const exceedsChars = candidate.length > TELEGRAM_RICH_MESSAGE_MAX_CHARS;
326
+ const exceedsBlocks = currentBlockCount + blockCount > TELEGRAM_RICH_MESSAGE_MAX_BLOCKS;
327
+ if (!exceedsChars && !exceedsBlocks) {
328
+ current = candidate;
329
+ currentBlockCount += blockCount;
330
+ continue;
331
+ }
332
+ if (current)
333
+ chunks.push(current.trimEnd());
334
+ if (block.length <= TELEGRAM_RICH_MESSAGE_MAX_CHARS &&
335
+ blockCount <= TELEGRAM_RICH_MESSAGE_MAX_BLOCKS) {
336
+ current = block;
337
+ currentBlockCount = blockCount;
338
+ continue;
339
+ }
340
+ chunks.push(...splitTelegramNativeMarkdownLongBlock(block));
341
+ current = "";
342
+ currentBlockCount = 0;
343
+ }
344
+ }
345
+ if (current)
346
+ chunks.push(current.trimEnd());
347
+ return chunks;
348
+ }
349
+ function splitTelegramNativeMarkdownBlocks(markdown) {
350
+ const blocks = [];
351
+ const current = [];
352
+ let fence;
353
+ const flush = () => {
354
+ if (current.length === 0)
355
+ return;
356
+ blocks.push(current.join("\n"));
357
+ current.length = 0;
358
+ };
359
+ for (const line of markdown.split("\n")) {
360
+ if (!fence && line.trim().length === 0) {
361
+ flush();
362
+ continue;
363
+ }
364
+ current.push(line);
365
+ fence = advanceTelegramMarkdownFence(fence, line);
366
+ }
367
+ flush();
368
+ return blocks;
369
+ }
370
+ function splitTelegramNativeMarkdownCountedBlocks(block) {
371
+ if (countTelegramNativeMarkdownBlocks(block) <= TELEGRAM_RICH_MESSAGE_MAX_BLOCKS) {
372
+ return [block];
373
+ }
374
+ const chunks = [];
375
+ let current = [];
376
+ let fence;
377
+ for (const line of block.split("\n")) {
378
+ if (!fence && current.length >= TELEGRAM_RICH_MESSAGE_MAX_BLOCKS) {
379
+ chunks.push(current.join("\n"));
380
+ current = [];
381
+ }
382
+ current.push(line);
383
+ fence = advanceTelegramMarkdownFence(fence, line);
384
+ }
385
+ if (current.length > 0)
386
+ chunks.push(current.join("\n"));
387
+ return chunks;
388
+ }
389
+ function countTelegramNativeMarkdownBlocks(block) {
390
+ if (/^ {0,3}(`{3,}|~{3,})/.test(block))
391
+ return 1;
392
+ const lines = block.split("\n").filter((line) => line.trim().length > 0);
393
+ if (lines.some((line) => /^\s*([-*+] |\d+\. |>|\||<tg-button-row>)/.test(line))) {
394
+ return Math.max(1, lines.length);
395
+ }
396
+ return 1;
397
+ }
398
+ function splitTelegramNativeMarkdownLongBlock(block) {
399
+ return (splitTelegramNativeMarkdownLongFenceBlock(block) ??
400
+ splitTelegramNativeMarkdownLongWrappedInlineBlock(block) ??
401
+ splitTelegramNativeMarkdownLongPlainBlock(block));
402
+ }
403
+ function splitTelegramNativeMarkdownLongPlainBlock(block) {
404
+ const chunks = [];
405
+ let remaining = block;
406
+ while (remaining.length > TELEGRAM_RICH_MESSAGE_MAX_CHARS) {
407
+ const window = remaining.slice(0, TELEGRAM_RICH_MESSAGE_MAX_CHARS + 1);
408
+ const splitIndex = findTelegramNativeMarkdownSplitIndex(window);
409
+ chunks.push(remaining.slice(0, splitIndex).trimEnd());
410
+ remaining = remaining.slice(splitIndex).trimStart();
411
+ }
412
+ if (remaining.length > 0)
413
+ chunks.push(remaining);
414
+ return chunks;
415
+ }
416
+ function splitTelegramNativeMarkdownLongFenceBlock(block) {
417
+ const lines = block.split("\n");
418
+ const opening = lines[0] ?? "";
419
+ const closing = lines[lines.length - 1] ?? "";
420
+ const openingFence = parseTelegramMarkdownFenceOpening(opening);
421
+ if (!openingFence || !closing || lines.length < 2)
422
+ return undefined;
423
+ if (!isTelegramMarkdownFenceClosing(closing, openingFence)) {
424
+ return undefined;
425
+ }
426
+ const maxContentLength = TELEGRAM_RICH_MESSAGE_MAX_CHARS - opening.length - closing.length - 2;
427
+ if (maxContentLength <= 0)
428
+ return undefined;
429
+ const content = lines.slice(1, -1).join("\n");
430
+ return splitTelegramNativeMarkdownWrappedContent(content, maxContentLength, (chunk) => `${opening}\n${chunk}${chunk.endsWith("\n") ? "" : "\n"}${closing}`);
431
+ }
432
+ function splitTelegramNativeMarkdownLongWrappedInlineBlock(block) {
433
+ const delimiter = ["**", "__", "~~", "`", "*", "_"].find((candidate) => block.startsWith(candidate) &&
434
+ block.endsWith(candidate) &&
435
+ block.length > candidate.length * 2);
436
+ if (!delimiter)
437
+ return undefined;
438
+ const maxContentLength = TELEGRAM_RICH_MESSAGE_MAX_CHARS - delimiter.length * 2;
439
+ if (maxContentLength <= 0)
440
+ return undefined;
441
+ return splitTelegramNativeMarkdownWrappedContent(block.slice(delimiter.length, -delimiter.length), maxContentLength, (chunk) => `${delimiter}${chunk}${delimiter}`);
442
+ }
443
+ function splitTelegramNativeMarkdownWrappedContent(content, maxContentLength, wrap) {
444
+ const chunks = [];
445
+ let remaining = content;
446
+ while (remaining.length > maxContentLength) {
447
+ const window = remaining.slice(0, maxContentLength + 1);
448
+ const splitIndex = findTelegramNativeMarkdownSplitIndex(window, maxContentLength);
449
+ chunks.push(wrap(remaining.slice(0, splitIndex)));
450
+ remaining = remaining.slice(splitIndex);
451
+ }
452
+ if (remaining.length > 0)
453
+ chunks.push(wrap(remaining));
454
+ return chunks;
455
+ }
456
+ function findTelegramNativeMarkdownSplitIndex(text, hardLimit = TELEGRAM_RICH_MESSAGE_MAX_CHARS) {
457
+ const paragraphIndex = text.lastIndexOf("\n\n", hardLimit);
458
+ if (paragraphIndex > 0)
459
+ return paragraphIndex + 2;
460
+ const lineIndex = text.lastIndexOf("\n", hardLimit);
461
+ if (lineIndex > 0)
462
+ return lineIndex + 1;
463
+ const spaceIndex = text.lastIndexOf(" ", hardLimit);
464
+ if (spaceIndex > 0)
465
+ return spaceIndex + 1;
466
+ return hardLimit;
467
+ }
468
+ export async function sendTelegramNativeMarkdownReply(chatId, replyToMessageId, markdown, deps, options) {
469
+ return sendTelegramChunkSequence(chatId, splitTelegramNativeMarkdown(markdown), replyToMessageId, options, deps.recordOwnership, (chunk, fields, callOptions) => deps.sendRichMessage({ chat_id: chatId, rich_message: { markdown: chunk }, ...fields }, callOptions));
470
+ }
471
+ async function sendTelegramNativeRichMessage(chatId, richMessage, deps, options) {
472
+ options = { ...options, target: options?.target && { ...options.target } };
473
+ const assertAuthority = options.assertAuthority;
474
+ assertTelegramApiCallAuthority(assertAuthority, false);
475
+ const sent = await deps.sendRichMessage({
476
+ chat_id: chatId,
477
+ rich_message: richMessage,
478
+ ...(options?.target ? getTelegramTargetThreadParams(options.target) : {}),
479
+ }, assertAuthority ? { assertAuthority } : undefined);
480
+ assertTelegramApiCallAuthority(assertAuthority, true);
481
+ deps.recordOwnership?.({
482
+ chatId,
483
+ messageId: sent.message_id,
484
+ target: options?.target,
485
+ });
486
+ assertTelegramApiCallAuthority(assertAuthority, true);
487
+ return sent.message_id;
488
+ }
489
+ export function createTelegramRenderedMessageDeliveryRuntime(deps) {
490
+ const replyTransport = buildTelegramReplyTransport({
491
+ recordOwnership: deps.recordOwnership,
492
+ sendMessage: deps.sendMessage,
493
+ editMessage: deps.editMessage,
494
+ });
495
+ return {
496
+ replyTransport,
497
+ ...createTelegramRenderedMessageRuntime({
498
+ renderTelegramMessage: deps.renderTelegramMessage ?? renderTelegramMessage,
499
+ replyTransport,
500
+ recordOwnership: deps.recordOwnership,
501
+ getAssistantRenderingMode: deps.getAssistantRenderingMode,
502
+ sendRichMessage: deps.sendRichMessage,
503
+ }),
504
+ };
505
+ }
506
+ export function createTelegramRenderedMessageRuntime(deps) {
507
+ return {
508
+ sendTextReply: async (chatId, replyToMessageId, text, options) => {
509
+ return sendTelegramPlainReply(text, {
510
+ renderTelegramMessage: deps.renderTelegramMessage,
511
+ sendRenderedChunks: (chunks, chunkOptions) => deps.replyTransport.sendRenderedChunks(chatId, chunks, {
512
+ target: chunkOptions?.target,
513
+ assertAuthority: chunkOptions?.assertAuthority,
514
+ replyToMessageId: chunkOptions?.replyToMessageId ?? replyToMessageId,
515
+ }),
516
+ }, options);
517
+ },
518
+ sendMarkdownReply: async (chatId, replyToMessageId, markdown, options) => {
519
+ options = {
520
+ ...options,
521
+ target: options?.target && { ...options.target },
522
+ };
523
+ const renderingMode = deps.getAssistantRenderingMode?.() ?? "rich";
524
+ if (renderingMode === "html") {
525
+ return deps.replyTransport.sendRenderedChunks(chatId, deps.renderTelegramMessage(markdown, { mode: "markdown" }), {
526
+ replyMarkup: options?.replyMarkup,
527
+ target: options?.target,
528
+ replyToMessageId,
529
+ assertAuthority: options.assertAuthority,
530
+ });
531
+ }
532
+ return sendTelegramNativeMarkdownReply(chatId, replyToMessageId, markdown, {
533
+ recordOwnership: deps.recordOwnership,
534
+ sendRichMessage: deps.sendRichMessage,
535
+ }, options);
536
+ },
537
+ editInteractiveMessage: async (chatId, messageId, text, mode, replyMarkup, options) => {
538
+ options = {
539
+ ...options,
540
+ target: options?.target && { ...options.target },
541
+ };
542
+ await deps.replyTransport.editRenderedMessage(chatId, messageId, deps.renderTelegramMessage(text, { mode }), { ...options, replyMarkup });
543
+ },
544
+ sendInteractiveMessage: async (chatId, text, mode, replyMarkup, options) => {
545
+ options = {
546
+ ...options,
547
+ target: options?.target && { ...options.target },
548
+ };
549
+ return deps.replyTransport.sendRenderedChunks(chatId, deps.renderTelegramMessage(text, { mode }), {
550
+ replyMarkup,
551
+ target: options?.target,
552
+ replyToMessageId: options?.replyToMessageId,
553
+ assertAuthority: options.assertAuthority,
554
+ });
555
+ },
556
+ sendSectionRichMessage: (chatId, message, options) => sendTelegramNativeRichMessage(chatId, message, {
557
+ recordOwnership: deps.recordOwnership,
558
+ sendRichMessage: deps.sendRichMessage,
559
+ }, options),
560
+ };
561
+ }
562
+ /**
563
+ * Guest reply sender: answers guest queries with native Rich Markdown content.
564
+ * Guest queries use InlineQueryResult input_message_content rather than chat
565
+ * sendRichMessage, so this stays as a dedicated guest transport adapter.
566
+ */
567
+ export function createGuestMarkdownReplySender(deps) {
568
+ return async (guestQueryId, markdown) => {
569
+ const [richMarkdown = markdown] = splitTelegramNativeMarkdown(markdown);
570
+ await deps.answerGuestQuery(guestQueryId, undefined, {
571
+ richMessage: { markdown: richMarkdown },
572
+ });
573
+ };
574
+ }
575
+ /**
576
+ * Guest reply editor: replaces the early Guest Mode placeholder ACK with
577
+ * native Rich Markdown content addressed by `inline_message_id` instead of a
578
+ * chat/message pair.
579
+ */
580
+ export function createGuestMarkdownReplyEditor(deps) {
581
+ return async (inlineMessageId, markdown) => {
582
+ const [richMarkdown = markdown] = splitTelegramNativeMarkdown(markdown);
583
+ await deps.editGuestInlineMessage(inlineMessageId, {
584
+ richMessage: { markdown: richMarkdown },
585
+ });
586
+ };
587
+ }
588
+ /**
589
+ * Guest Mode placeholder rotation: the early ACK is the first placeholder
590
+ * frame and the runtime steps the remaining frames once per interval, moving
591
+ * the globe every second while the trailing dots grow once every two seconds.
592
+ *
593
+ * Rotation completes whole six-frame cycles and only stops once at least
594
+ * `TELEGRAM_GUEST_PLACEHOLDER_MIN_MS` has elapsed, so a pending answer holds
595
+ * the finished cycle's last frame (`🌏 Working on it...`) instead of whatever
596
+ * step a hard time cap happens to cut. The `TELEGRAM_GUEST_PLACEHOLDER_MAX_MS`
597
+ * safety bound keeps the edit stream clear of the first flood-control
598
+ * rejections measured in live guest runs (+26.5 s at ~53 edits, +27.8 s at
599
+ * ~28 edits): rotation caps at 23 edits and never starts a frame after 26 s.
600
+ */
601
+ export const TELEGRAM_GUEST_PLACEHOLDER_FRAME_MS = 1_000;
602
+ export const TELEGRAM_GUEST_PLACEHOLDER_MIN_MS = 20_000;
603
+ export const TELEGRAM_GUEST_PLACEHOLDER_MAX_MS = 26_000;
604
+ export const TELEGRAM_GUEST_PLACEHOLDER_FRAMES = [
605
+ "<b>🌎 Working on it.</b>",
606
+ "<b>🌍 Working on it.</b>",
607
+ "<b>🌏 Working on it..</b>",
608
+ "<b>🌎 Working on it..</b>",
609
+ "<b>🌍 Working on it...</b>",
610
+ "<b>🌏 Working on it...</b>",
611
+ ];
612
+ // Telegram does not expose deletion for inline messages. This non-printing,
613
+ // non-empty edit visually clears a guest placeholder after its query is skipped.
614
+ export const TELEGRAM_DISMISSED_GUEST_PLACEHOLDER_TEXT = "\u2063";
615
+ export function buildTelegramGuestPlaceholderFrame(step) {
616
+ const frames = TELEGRAM_GUEST_PLACEHOLDER_FRAMES;
617
+ const index = ((step % frames.length) + frames.length) % frames.length;
618
+ return frames[index];
619
+ }
620
+ function getTelegramGuestPlaceholderRetryDelayMs(error, fallbackMs) {
621
+ const retryAfterSeconds = error?.retryAfterSeconds;
622
+ return typeof retryAfterSeconds === "number" && retryAfterSeconds > 0
623
+ ? Math.max(fallbackMs, retryAfterSeconds * 1_000)
624
+ : fallbackMs;
625
+ }
626
+ export function createTelegramGuestPlaceholderRuntime(deps) {
627
+ const intervalMs = deps.intervalMs ?? TELEGRAM_GUEST_PLACEHOLDER_FRAME_MS;
628
+ const minMs = deps.minMs ?? TELEGRAM_GUEST_PLACEHOLDER_MIN_MS;
629
+ const maxMs = deps.maxMs ?? TELEGRAM_GUEST_PLACEHOLDER_MAX_MS;
630
+ const now = deps.now ?? Date.now;
631
+ const setTimer = deps.setTimer ??
632
+ ((callback, ms) => setTimeout(callback, ms));
633
+ const clearTimer = deps.clearTimer ??
634
+ ((timer) => clearTimeout(timer));
635
+ const sessions = new Map();
636
+ const finishRotation = (session, elapsedMs) => {
637
+ if (session.finished)
638
+ return;
639
+ session.finished = true;
640
+ deps.recordRuntimeEvent?.("guest", "Guest placeholder rotation reached its bound", {
641
+ phase: "guest-placeholder-capped",
642
+ minMs,
643
+ maxMs,
644
+ elapsedMs,
645
+ step: session.step,
646
+ });
647
+ };
648
+ const scheduleFrame = (inlineMessageId, session, delayMs) => {
649
+ if (session.stopped)
650
+ return;
651
+ const elapsedMs = now() - session.startedAtMs;
652
+ const frameCount = TELEGRAM_GUEST_PLACEHOLDER_FRAMES.length;
653
+ const cycleComplete = session.step > 0 && session.step % frameCount === frameCount - 1;
654
+ if (cycleComplete && elapsedMs >= minMs) {
655
+ finishRotation(session, elapsedMs);
656
+ return;
657
+ }
658
+ if (elapsedMs + delayMs > maxMs) {
659
+ finishRotation(session, elapsedMs);
660
+ return;
661
+ }
662
+ const timer = setTimer(() => {
663
+ session.timer = undefined;
664
+ runFrame(inlineMessageId, session);
665
+ }, delayMs);
666
+ timer.unref?.();
667
+ session.timer = timer;
668
+ };
669
+ const runFrame = (inlineMessageId, session) => {
670
+ if (session.stopped)
671
+ return;
672
+ session.step += 1;
673
+ let nextDelayMs = intervalMs;
674
+ session.inflight = (async () => {
675
+ try {
676
+ await deps.editGuestInlineMessage(inlineMessageId, {
677
+ text: buildTelegramGuestPlaceholderFrame(session.step),
678
+ parseMode: "HTML",
679
+ });
680
+ }
681
+ catch (error) {
682
+ nextDelayMs = getTelegramGuestPlaceholderRetryDelayMs(error, intervalMs);
683
+ deps.recordRuntimeEvent?.("guest", error, {
684
+ phase: "guest-placeholder-edit",
685
+ retryAfterMs: nextDelayMs,
686
+ });
687
+ }
688
+ finally {
689
+ session.inflight = undefined;
690
+ scheduleFrame(inlineMessageId, session, nextDelayMs);
691
+ }
692
+ })();
693
+ };
694
+ const stop = async (inlineMessageId) => {
695
+ const session = sessions.get(inlineMessageId);
696
+ if (!session)
697
+ return;
698
+ sessions.delete(inlineMessageId);
699
+ session.stopped = true;
700
+ if (session.timer !== undefined) {
701
+ clearTimer(session.timer);
702
+ session.timer = undefined;
703
+ }
704
+ try {
705
+ await session.inflight;
706
+ }
707
+ catch {
708
+ // Frame failures are reported as runtime events; stopping stays fail-open.
709
+ }
710
+ };
711
+ return {
712
+ start(inlineMessageId) {
713
+ const existing = sessions.get(inlineMessageId);
714
+ if (existing) {
715
+ existing.stopped = true;
716
+ if (existing.timer !== undefined)
717
+ clearTimer(existing.timer);
718
+ }
719
+ const session = {
720
+ step: 0,
721
+ stopped: false,
722
+ startedAtMs: now(),
723
+ finished: false,
724
+ };
725
+ sessions.set(inlineMessageId, session);
726
+ scheduleFrame(inlineMessageId, session, intervalMs);
727
+ },
728
+ stop,
729
+ stopAll() {
730
+ for (const session of sessions.values()) {
731
+ session.stopped = true;
732
+ if (session.timer !== undefined)
733
+ clearTimer(session.timer);
734
+ }
735
+ sessions.clear();
736
+ },
737
+ async dismiss(inlineMessageId) {
738
+ await stop(inlineMessageId);
739
+ try {
740
+ await deps.editGuestInlineMessage(inlineMessageId, {
741
+ text: TELEGRAM_DISMISSED_GUEST_PLACEHOLDER_TEXT,
742
+ parseMode: "HTML",
743
+ });
744
+ }
745
+ catch (error) {
746
+ deps.recordRuntimeEvent?.("guest", error, {
747
+ phase: "guest-placeholder-dismiss",
748
+ });
749
+ }
750
+ },
751
+ };
752
+ }