pi-harness-runtime 1.1.397 → 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 (624) 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/notification-events.ts +6 -6
  21. package/harness/project-detector/detector.ts +1 -2
  22. package/harness/repair-engine.ts +2 -4
  23. package/harness/service-diagnostics.ts +1 -1
  24. package/harness/skill-sync.ts +3 -3
  25. package/index.ts +276 -55
  26. package/mirror.ts +1 -1
  27. package/package.json +5 -3
  28. package/packages/a2a-adapter/dist/discovery.d.ts.map +1 -1
  29. package/packages/a2a-adapter/dist/discovery.js +0 -1
  30. package/packages/a2a-adapter/dist/discovery.js.map +1 -1
  31. package/packages/a2a-adapter/package.json +1 -1
  32. package/packages/a2a-adapter/src/discovery.ts +0 -1
  33. package/packages/agent-policy/package.json +1 -1
  34. package/packages/architecture-generator/package.json +1 -1
  35. package/packages/auth/dist/index.d.ts +9 -0
  36. package/packages/auth/dist/index.d.ts.map +1 -0
  37. package/packages/auth/dist/index.js +9 -0
  38. package/packages/auth/dist/index.js.map +1 -0
  39. package/packages/auth/package.json +1 -1
  40. package/packages/auth/src/index.ts +9 -0
  41. package/packages/autonomous-refactor/package.json +1 -1
  42. package/packages/autonomous-runtime/package.json +1 -1
  43. package/packages/cache-strategy/package.json +1 -1
  44. package/packages/capability-registry/package.json +1 -1
  45. package/packages/checkpoint/package.json +1 -1
  46. package/packages/cli-plugin-sdk/package.json +1 -1
  47. package/packages/clipboard/package.json +1 -1
  48. package/packages/clipboard-plugin/package.json +1 -1
  49. package/packages/code-generation/package.json +1 -1
  50. package/packages/code-review/package.json +1 -1
  51. package/packages/codex-adapter/package.json +1 -1
  52. package/packages/codex-watcher/package.json +1 -1
  53. package/packages/config-capture/dist/index.d.ts +52 -0
  54. package/packages/config-capture/dist/index.d.ts.map +1 -0
  55. package/packages/config-capture/dist/index.js +261 -0
  56. package/packages/config-capture/dist/index.js.map +1 -0
  57. package/packages/config-capture/package.json +1 -1
  58. package/packages/connection-runtime/package.json +1 -1
  59. package/packages/context-compiler/package.json +1 -1
  60. package/packages/context-discovery/package.json +1 -1
  61. package/packages/context-manager/package.json +1 -1
  62. package/packages/contracts/package.json +1 -1
  63. package/packages/cookie-sanitizer/package.json +1 -1
  64. package/packages/cost-optimizer/package.json +1 -1
  65. package/packages/dependency-analyzer/package.json +1 -1
  66. package/packages/django-plugin/package.json +1 -1
  67. package/packages/doc-generator/package.json +1 -1
  68. package/packages/durable-review/package.json +1 -1
  69. package/packages/e2e-tester/package.json +1 -1
  70. package/packages/evaluation-engine/package.json +1 -1
  71. package/packages/evaluation-runner/package.json +1 -1
  72. package/packages/event-bus/package.json +1 -1
  73. package/packages/event-sink/package.json +1 -1
  74. package/packages/event-store/package.json +1 -1
  75. package/packages/experience-replay/package.json +1 -1
  76. package/packages/feedback-collector/package.json +1 -1
  77. package/packages/file-copy-helper/dist/extension.d.ts +15 -0
  78. package/packages/file-copy-helper/dist/extension.d.ts.map +1 -0
  79. package/packages/file-copy-helper/dist/extension.debug.d.ts +15 -0
  80. package/packages/file-copy-helper/dist/extension.debug.d.ts.map +1 -0
  81. package/packages/file-copy-helper/dist/extension.debug.js +215 -0
  82. package/packages/file-copy-helper/dist/extension.debug.js.map +1 -0
  83. package/packages/file-copy-helper/dist/extension.js +222 -0
  84. package/packages/file-copy-helper/dist/extension.js.map +1 -0
  85. package/packages/file-copy-helper/dist/index.d.ts +3 -0
  86. package/packages/file-copy-helper/dist/index.d.ts.map +1 -0
  87. package/packages/file-copy-helper/dist/index.js +3 -0
  88. package/packages/file-copy-helper/dist/index.js.map +1 -0
  89. package/packages/file-copy-helper/dist/intent-detector.d.ts +21 -0
  90. package/packages/file-copy-helper/dist/intent-detector.d.ts.map +1 -0
  91. package/packages/file-copy-helper/dist/intent-detector.js +348 -0
  92. package/packages/file-copy-helper/dist/intent-detector.js.map +1 -0
  93. package/packages/file-copy-helper/package.json +1 -1
  94. package/packages/framework-detector/package.json +1 -1
  95. package/packages/framework-plugin-sdk/package.json +1 -1
  96. package/packages/frappe-plugin/package.json +1 -1
  97. package/packages/generic-web-plugin/package.json +1 -1
  98. package/packages/health-monitor/package.json +1 -1
  99. package/packages/intent-analyzer/package.json +1 -1
  100. package/packages/jev-judge/dist/auto-continue.d.ts +161 -2
  101. package/packages/jev-judge/dist/auto-continue.d.ts.map +1 -1
  102. package/packages/jev-judge/dist/auto-continue.js +267 -22
  103. package/packages/jev-judge/dist/auto-continue.js.map +1 -1
  104. package/packages/jev-judge/dist/index.d.ts +2 -0
  105. package/packages/jev-judge/dist/index.d.ts.map +1 -1
  106. package/packages/jev-judge/dist/index.js +2 -0
  107. package/packages/jev-judge/dist/index.js.map +1 -1
  108. package/packages/jev-judge/dist/question-risk.d.ts +50 -0
  109. package/packages/jev-judge/dist/question-risk.d.ts.map +1 -0
  110. package/packages/jev-judge/dist/question-risk.js +100 -0
  111. package/packages/jev-judge/dist/question-risk.js.map +1 -0
  112. package/packages/jev-judge/package.json +1 -1
  113. package/packages/jev-judge/src/auto-continue.ts +426 -29
  114. package/packages/jev-judge/src/index.ts +4 -0
  115. package/packages/jev-judge/src/question-risk.ts +151 -0
  116. package/packages/jev-judge/tests/auto-continue-context.test.ts +221 -0
  117. package/packages/jev-judge/tests/outcome-application.test.ts +132 -0
  118. package/packages/jev-judge/tests/question-risk.test.ts +116 -0
  119. package/packages/knowledge-graph/package.json +1 -1
  120. package/packages/knowledge-retrieval/package.json +1 -1
  121. package/packages/laravel-plugin/package.json +1 -1
  122. package/packages/learning-engine/package.json +1 -1
  123. package/packages/logging/README.md +36 -3
  124. package/packages/logging/dist/config.d.ts +7 -0
  125. package/packages/logging/dist/config.d.ts.map +1 -1
  126. package/packages/logging/dist/config.js +14 -0
  127. package/packages/logging/dist/config.js.map +1 -1
  128. package/packages/logging/dist/incidents/schema.d.ts +111 -0
  129. package/packages/logging/dist/incidents/schema.d.ts.map +1 -0
  130. package/packages/logging/dist/incidents/schema.js +0 -0
  131. package/packages/logging/dist/incidents/schema.js.map +1 -0
  132. package/packages/logging/dist/index.d.ts +2 -0
  133. package/packages/logging/dist/index.d.ts.map +1 -1
  134. package/packages/logging/dist/index.js +2 -0
  135. package/packages/logging/dist/index.js.map +1 -1
  136. package/packages/logging/dist/server/http.d.ts +4 -3
  137. package/packages/logging/dist/server/http.d.ts.map +1 -1
  138. package/packages/logging/dist/server/http.js +35 -3
  139. package/packages/logging/dist/server/http.js.map +1 -1
  140. package/packages/logging/dist/server/incident-qdrant.d.ts +83 -0
  141. package/packages/logging/dist/server/incident-qdrant.d.ts.map +1 -0
  142. package/packages/logging/dist/server/incident-qdrant.js +129 -0
  143. package/packages/logging/dist/server/incident-qdrant.js.map +1 -0
  144. package/packages/logging/dist/server/incident-store.d.ts +76 -0
  145. package/packages/logging/dist/server/incident-store.d.ts.map +1 -0
  146. package/packages/logging/dist/server/incident-store.js +157 -0
  147. package/packages/logging/dist/server/incident-store.js.map +1 -0
  148. package/packages/logging/dist/server/index.d.ts +4 -0
  149. package/packages/logging/dist/server/index.d.ts.map +1 -1
  150. package/packages/logging/dist/server/index.js +2 -0
  151. package/packages/logging/dist/server/index.js.map +1 -1
  152. package/packages/logging/dist/server/service.d.ts +33 -0
  153. package/packages/logging/dist/server/service.d.ts.map +1 -1
  154. package/packages/logging/dist/server/service.js +63 -0
  155. package/packages/logging/dist/server/service.js.map +1 -1
  156. package/packages/logging/dist/shipper.d.ts +74 -3
  157. package/packages/logging/dist/shipper.d.ts.map +1 -1
  158. package/packages/logging/dist/shipper.js +88 -5
  159. package/packages/logging/dist/shipper.js.map +1 -1
  160. package/packages/logging/dist/singleton.d.ts.map +1 -1
  161. package/packages/logging/dist/singleton.js +1 -0
  162. package/packages/logging/dist/singleton.js.map +1 -1
  163. package/packages/logging/package.json +1 -1
  164. package/packages/logging/src/config.ts +22 -0
  165. package/packages/logging/src/incidents/schema.ts +0 -0
  166. package/packages/logging/src/index.ts +17 -0
  167. package/packages/logging/src/server/http.ts +42 -3
  168. package/packages/logging/src/server/incident-qdrant.ts +177 -0
  169. package/packages/logging/src/server/incident-store.ts +192 -0
  170. package/packages/logging/src/server/index.ts +21 -0
  171. package/packages/logging/src/server/service.ts +79 -0
  172. package/packages/logging/src/shipper.ts +120 -5
  173. package/packages/logging/src/singleton.ts +1 -0
  174. package/packages/logging/test/fanout.test.ts +186 -0
  175. package/packages/logging/test/incidents.test.ts +404 -0
  176. package/packages/mcp-adapter/package.json +1 -1
  177. package/packages/memory-engine/package.json +1 -1
  178. package/packages/milestone-manager/package.json +1 -1
  179. package/packages/model-registry/package.json +1 -1
  180. package/packages/nextjs-plugin/package.json +1 -1
  181. package/packages/notification/dist/adapters/detail-format.d.ts +42 -0
  182. package/packages/notification/dist/adapters/detail-format.d.ts.map +1 -0
  183. package/packages/notification/dist/adapters/detail-format.js +94 -0
  184. package/packages/notification/dist/adapters/detail-format.js.map +1 -0
  185. package/packages/notification/dist/adapters/email-adapter.d.ts.map +1 -1
  186. package/packages/notification/dist/adapters/email-adapter.js +3 -2
  187. package/packages/notification/dist/adapters/email-adapter.js.map +1 -1
  188. package/packages/notification/dist/adapters/line-adapter.d.ts +33 -0
  189. package/packages/notification/dist/adapters/line-adapter.d.ts.map +1 -1
  190. package/packages/notification/dist/adapters/line-adapter.js +87 -9
  191. package/packages/notification/dist/adapters/line-adapter.js.map +1 -1
  192. package/packages/notification/dist/adapters/ntfy-adapter.d.ts.map +1 -1
  193. package/packages/notification/dist/adapters/ntfy-adapter.js +3 -2
  194. package/packages/notification/dist/adapters/ntfy-adapter.js.map +1 -1
  195. package/packages/notification/dist/adapters/telegram-adapter.d.ts +14 -0
  196. package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +1 -1
  197. package/packages/notification/dist/adapters/telegram-adapter.js +89 -69
  198. package/packages/notification/dist/adapters/telegram-adapter.js.map +1 -1
  199. package/packages/notification/dist/notification-center.d.ts.map +1 -1
  200. package/packages/notification/dist/notification-center.js +60 -7
  201. package/packages/notification/dist/notification-center.js.map +1 -1
  202. package/packages/notification/dist/pending-question.d.ts +69 -2
  203. package/packages/notification/dist/pending-question.d.ts.map +1 -1
  204. package/packages/notification/dist/pending-question.js +88 -2
  205. package/packages/notification/dist/pending-question.js.map +1 -1
  206. package/packages/notification/dist/types.d.ts +21 -0
  207. package/packages/notification/dist/types.d.ts.map +1 -1
  208. package/packages/notification/package.json +1 -1
  209. package/packages/notification/src/adapters/detail-format.ts +114 -0
  210. package/packages/notification/src/adapters/email-adapter.ts +3 -2
  211. package/packages/notification/src/adapters/line-adapter.ts +97 -9
  212. package/packages/notification/src/adapters/ntfy-adapter.ts +3 -2
  213. package/packages/notification/src/adapters/telegram-adapter.ts +98 -76
  214. package/packages/notification/src/notification-center.ts +66 -8
  215. package/packages/notification/src/pending-question.ts +160 -8
  216. package/packages/notification/src/types.ts +21 -0
  217. package/packages/notification/test/approval-payload.test.ts +269 -0
  218. package/packages/notification/test/detail-format.test.ts +106 -0
  219. package/packages/notification/test/pending-question-lifecycle.test.ts +195 -0
  220. package/packages/observability/package.json +1 -1
  221. package/packages/okf-indexer/dist/index.d.ts +9 -0
  222. package/packages/okf-indexer/dist/index.d.ts.map +1 -0
  223. package/packages/okf-indexer/dist/index.js +9 -0
  224. package/packages/okf-indexer/dist/index.js.map +1 -0
  225. package/packages/okf-indexer/package.json +1 -1
  226. package/packages/okf-indexer/src/index.ts +9 -0
  227. package/packages/paperclip-integration/package.json +1 -1
  228. package/packages/performance-optimizer/package.json +1 -1
  229. package/packages/permission-mode/package.json +1 -1
  230. package/packages/privilege-broker/package.json +1 -1
  231. package/packages/project-analyzer/package.json +1 -1
  232. package/packages/project-bootstrap/package.json +1 -1
  233. package/packages/projection-engine/package.json +1 -1
  234. package/packages/prompt-compiler/package.json +1 -1
  235. package/packages/prompt-versioning/package.json +1 -1
  236. package/packages/provider-adapter-sdk/package.json +1 -1
  237. package/packages/provider-router/dist/provider-router.d.ts.map +1 -1
  238. package/packages/provider-router/dist/types.d.ts +2 -2
  239. package/packages/provider-router/dist/types.d.ts.map +1 -1
  240. package/packages/provider-router/dist/types.js +1 -1
  241. package/packages/provider-router/package.json +1 -1
  242. package/packages/provider-router/src/types.ts +2 -2
  243. package/packages/provider-selector/package.json +1 -1
  244. package/packages/providers/package.json +1 -1
  245. package/packages/qdrant-skills/package.json +1 -1
  246. package/packages/quota-manager/package.json +1 -1
  247. package/packages/rate-limiter/package.json +1 -1
  248. package/packages/react-vite-plugin/package.json +1 -1
  249. package/packages/relay/package.json +1 -1
  250. package/packages/release-manager/package.json +1 -1
  251. package/packages/requirement-compiler/package.json +1 -1
  252. package/packages/runtime/package.json +1 -1
  253. package/packages/scheduler/dist/index.d.ts +9 -0
  254. package/packages/scheduler/dist/index.d.ts.map +1 -0
  255. package/packages/scheduler/dist/index.js +9 -0
  256. package/packages/scheduler/dist/index.js.map +1 -0
  257. package/packages/scheduler/dist/scheduler.d.ts +17 -0
  258. package/packages/scheduler/dist/scheduler.d.ts.map +1 -0
  259. package/packages/scheduler/dist/scheduler.js +41 -0
  260. package/packages/scheduler/dist/scheduler.js.map +1 -0
  261. package/packages/scheduler/package.json +1 -1
  262. package/packages/scheduler/src/index.ts +9 -0
  263. package/packages/scheduler-adapter/package.json +1 -1
  264. package/packages/session/package.json +1 -1
  265. package/packages/session-api/package.json +1 -1
  266. package/packages/session-export/package.json +1 -1
  267. package/packages/shared-context/dist/index.d.ts +7 -0
  268. package/packages/shared-context/dist/index.d.ts.map +1 -0
  269. package/packages/shared-context/dist/index.js +7 -0
  270. package/packages/shared-context/dist/index.js.map +1 -0
  271. package/packages/shared-context/dist/shared-context.d.ts +12 -0
  272. package/packages/shared-context/dist/shared-context.d.ts.map +1 -0
  273. package/packages/shared-context/dist/shared-context.js +39 -0
  274. package/packages/shared-context/dist/shared-context.js.map +1 -0
  275. package/packages/shared-context/package.json +1 -1
  276. package/packages/skill-mcp-client/dist/client.d.ts +56 -0
  277. package/packages/skill-mcp-client/dist/client.d.ts.map +1 -0
  278. package/packages/skill-mcp-client/dist/client.js +101 -0
  279. package/packages/skill-mcp-client/dist/client.js.map +1 -0
  280. package/packages/skill-mcp-client/dist/errors.d.ts +44 -0
  281. package/packages/skill-mcp-client/dist/errors.d.ts.map +1 -0
  282. package/packages/skill-mcp-client/dist/errors.js +68 -0
  283. package/packages/skill-mcp-client/dist/errors.js.map +1 -0
  284. package/packages/skill-mcp-client/dist/index.d.ts +9 -0
  285. package/packages/skill-mcp-client/dist/index.d.ts.map +1 -0
  286. package/packages/skill-mcp-client/dist/index.js +9 -0
  287. package/packages/skill-mcp-client/dist/index.js.map +1 -0
  288. package/packages/skill-mcp-client/dist/types.d.ts +106 -0
  289. package/packages/skill-mcp-client/dist/types.d.ts.map +1 -0
  290. package/packages/skill-mcp-client/dist/types.js +14 -0
  291. package/packages/skill-mcp-client/dist/types.js.map +1 -0
  292. package/packages/skill-mcp-client/package.json +1 -1
  293. package/packages/skill-registry/package.json +1 -1
  294. package/packages/skills/package.json +1 -5
  295. package/packages/sprint-planner/package.json +1 -1
  296. package/packages/subscription-engine/package.json +1 -1
  297. package/packages/task-compiler/package.json +1 -1
  298. package/packages/telegram/package.json +1 -1
  299. package/packages/telegram/src/agent-messages.d.ts +28 -0
  300. package/packages/telegram/src/agent-messages.js +90 -0
  301. package/packages/telegram/src/bindings.d.ts +296 -0
  302. package/packages/telegram/src/bindings.js +1086 -0
  303. package/packages/telegram/src/bus.d.ts +759 -0
  304. package/packages/telegram/src/bus.js +2732 -0
  305. package/packages/telegram/src/commands.d.ts +761 -0
  306. package/packages/telegram/src/commands.js +2622 -0
  307. package/packages/telegram/src/config.d.ts +222 -0
  308. package/packages/telegram/src/config.js +844 -0
  309. package/packages/telegram/src/delivery.d.ts +161 -0
  310. package/packages/telegram/src/delivery.js +550 -0
  311. package/packages/telegram/src/extension.d.ts +7 -0
  312. package/packages/telegram/src/extension.js +2444 -0
  313. package/packages/telegram/src/inbound.d.ts +94 -0
  314. package/packages/telegram/src/inbound.js +478 -0
  315. package/packages/telegram/src/index.d.ts +6 -0
  316. package/packages/telegram/src/index.js +6 -0
  317. package/packages/telegram/src/keyboard.d.ts +21 -0
  318. package/packages/telegram/src/keyboard.js +37 -0
  319. package/packages/telegram/src/lifecycle.d.ts +210 -0
  320. package/packages/telegram/src/lifecycle.js +538 -0
  321. package/packages/telegram/src/pi.d.ts +76 -0
  322. package/packages/telegram/src/pi.js +130 -0
  323. package/packages/telegram/src/polling.d.ts +332 -0
  324. package/packages/telegram/src/polling.js +1219 -0
  325. package/packages/telegram/src/replies.d.ts +210 -0
  326. package/packages/telegram/src/replies.js +752 -0
  327. package/packages/telegram/src/routing.d.ts +388 -0
  328. package/packages/telegram/src/routing.js +7886 -0
  329. package/packages/telegram/src/runtime.d.ts +159 -0
  330. package/packages/telegram/src/runtime.js +351 -0
  331. package/packages/telegram/src/telegram-api.d.ts +564 -0
  332. package/packages/telegram/src/telegram-api.js +1332 -0
  333. package/packages/telegram/src/turns.d.ts +108 -0
  334. package/packages/telegram/src/turns.js +482 -0
  335. package/packages/telegram/src/updates.d.ts +1545 -0
  336. package/packages/telegram/src/updates.js +6420 -0
  337. package/packages/tencentdb-memory/package.json +1 -1
  338. package/packages/tencentdb-sync/package.json +1 -1
  339. package/packages/test-data-generator/package.json +1 -1
  340. package/packages/test-generator/package.json +1 -1
  341. package/packages/todo-bd-sync/dist/detector.d.ts +54 -0
  342. package/packages/todo-bd-sync/dist/detector.d.ts.map +1 -0
  343. package/packages/todo-bd-sync/dist/detector.js +132 -0
  344. package/packages/todo-bd-sync/dist/detector.js.map +1 -0
  345. package/packages/todo-bd-sync/dist/extension.d.ts +30 -0
  346. package/packages/todo-bd-sync/dist/extension.d.ts.map +1 -0
  347. package/packages/todo-bd-sync/dist/extension.js +35 -0
  348. package/packages/todo-bd-sync/dist/extension.js.map +1 -0
  349. package/packages/todo-bd-sync/dist/index.d.ts +87 -0
  350. package/packages/todo-bd-sync/dist/index.d.ts.map +1 -0
  351. package/packages/todo-bd-sync/dist/index.js +296 -0
  352. package/packages/todo-bd-sync/dist/index.js.map +1 -0
  353. package/packages/todo-bd-sync/dist/sync.d.ts +72 -0
  354. package/packages/todo-bd-sync/dist/sync.d.ts.map +1 -0
  355. package/packages/todo-bd-sync/dist/sync.js +290 -0
  356. package/packages/todo-bd-sync/dist/sync.js.map +1 -0
  357. package/packages/todo-bd-sync/dist/task-analyzer.d.ts +49 -0
  358. package/packages/todo-bd-sync/dist/task-analyzer.d.ts.map +1 -0
  359. package/packages/todo-bd-sync/dist/task-analyzer.js +240 -0
  360. package/packages/todo-bd-sync/dist/task-analyzer.js.map +1 -0
  361. package/packages/todo-bd-sync/dist/todo-reminder.d.ts +126 -0
  362. package/packages/todo-bd-sync/dist/todo-reminder.d.ts.map +1 -0
  363. package/packages/todo-bd-sync/dist/todo-reminder.js +329 -0
  364. package/packages/todo-bd-sync/dist/todo-reminder.js.map +1 -0
  365. package/packages/todo-bd-sync/dist/types.d.ts +65 -0
  366. package/packages/todo-bd-sync/dist/types.d.ts.map +1 -0
  367. package/packages/todo-bd-sync/dist/types.js +67 -0
  368. package/packages/todo-bd-sync/dist/types.js.map +1 -0
  369. package/packages/todo-bd-sync/package.json +1 -1
  370. package/packages/token-estimation/dist/index.d.ts +94 -0
  371. package/packages/token-estimation/dist/index.d.ts.map +1 -0
  372. package/packages/token-estimation/dist/index.js +115 -0
  373. package/packages/token-estimation/dist/index.js.map +1 -0
  374. package/packages/token-estimation/package.json +1 -1
  375. package/packages/token-optimizer/package.json +1 -1
  376. package/packages/trajectory/package.json +1 -1
  377. package/packages/tui/package.json +1 -1
  378. package/packages/types/dist/ai-providers.d.ts +36 -0
  379. package/packages/types/dist/ai-providers.d.ts.map +1 -0
  380. package/packages/types/dist/ai-providers.js +66 -0
  381. package/packages/types/dist/ai-providers.js.map +1 -0
  382. package/packages/types/dist/index.d.ts +12 -0
  383. package/packages/types/dist/index.d.ts.map +1 -0
  384. package/packages/types/dist/index.js +12 -0
  385. package/packages/types/dist/index.js.map +1 -0
  386. package/packages/types/package.json +5 -5
  387. package/packages/types/src/index.ts +12 -0
  388. package/packages/voice-api/package.json +1 -1
  389. package/packages/webmcp-tester/package.json +1 -1
  390. package/packages/wiki/package.json +1 -1
  391. package/packages/workflow-events/package.json +1 -1
  392. package/packages/workspace-scanner/package.json +1 -1
  393. package/packages/worktree/package.json +1 -1
  394. package/packages/worktree/worktree.ts +1 -1
  395. package/packages/write-review/package.json +1 -1
  396. package/renderer.ts +1 -1
  397. package/scripts/build-packages.ts +162 -0
  398. package/scripts/relay-client.ts +2 -2
  399. package/scripts/typecheck-packages.mjs +3 -3
  400. package/scripts/unified-webhook-server.ts +22 -10
  401. package/scripts/verify-package-contents.ts +345 -0
  402. package/scripts/ws-server.ts +1 -1
  403. package/tracker.ts +1 -1
  404. package/harness/browser-scrapers/base-browser-scraper.d.ts +0 -91
  405. package/harness/browser-scrapers/chrome-profile-manager.d.ts +0 -80
  406. package/harness/browser-scrapers/codex-browser-scraper.d.ts +0 -60
  407. package/harness/browser-scrapers/index.d.ts +0 -29
  408. package/harness/browser-scrapers/zai-browser-scraper.d.ts +0 -79
  409. package/harness/e2e/browser-scrapers/base-browser-scraper.d.ts +0 -92
  410. package/harness/e2e/browser-scrapers/chrome-profile-manager.d.ts +0 -81
  411. package/harness/e2e/browser-scrapers/codex-browser-scraper.d.ts +0 -61
  412. package/harness/e2e/browser-scrapers/index.d.ts +0 -30
  413. package/harness/e2e/browser-scrapers/zai-browser-scraper.d.ts +0 -80
  414. package/harness/langchain/agents.d.ts +0 -143
  415. package/harness/langchain/agents.test.d.ts +0 -2
  416. package/harness/langchain/checkpointer.d.ts +0 -48
  417. package/harness/langchain/checkpointer.test.d.ts +0 -8
  418. package/harness/langchain/cron-cli.d.ts +0 -12
  419. package/harness/langchain/daemon.d.ts +0 -161
  420. package/harness/langchain/daemon.test.d.ts +0 -11
  421. package/harness/langchain/file-tools.d.ts +0 -97
  422. package/harness/langchain/graph.d.ts +0 -706
  423. package/harness/langchain/model-router.d.ts +0 -63
  424. package/harness/langchain/model-router.test.d.ts +0 -2
  425. package/harness/langchain/models.d.ts +0 -72
  426. package/harness/langchain/ping-pong-middleware.d.ts +0 -28
  427. package/harness/langchain/ping-pong-middleware.test.d.ts +0 -2
  428. package/harness/langchain/run.d.ts +0 -15
  429. package/harness/langchain/scoreboard.test.d.ts +0 -13
  430. package/harness/langchain/status-line.d.ts +0 -91
  431. package/harness/langchain/status-line.test.d.ts +0 -8
  432. package/harness/langchain/surge.d.ts +0 -111
  433. package/harness/langchain/surge.test.d.ts +0 -10
  434. package/harness/langchain/widget.d.ts +0 -105
  435. package/harness/langchain/widget.test.d.ts +0 -8
  436. package/packages/autonomous-runtime/dist/worker.d.ts +0 -63
  437. package/packages/autonomous-runtime/dist/worker.js +0 -133
  438. package/packages/capability-registry/src/types.d.ts +0 -47
  439. package/packages/clipboard/dist/clipboard.d.ts +0 -11
  440. package/packages/clipboard/dist/clipboard.js +0 -40
  441. package/packages/clipboard/dist/index.d.ts +0 -2
  442. package/packages/clipboard/dist/index.js +0 -2
  443. package/packages/clipboard/dist/types.d.ts +0 -13
  444. package/packages/clipboard/dist/types.js +0 -5
  445. package/packages/context-discovery/dist/discover.d.ts +0 -3
  446. package/packages/context-discovery/dist/discover.js +0 -42
  447. package/packages/context-discovery/dist/discovery.d.ts +0 -28
  448. package/packages/context-discovery/dist/discovery.js +0 -21
  449. package/packages/context-discovery/dist/index.d.ts +0 -3
  450. package/packages/context-discovery/dist/index.js +0 -2
  451. package/packages/context-discovery/dist/types.d.ts +0 -16
  452. package/packages/context-discovery/dist/types.js +0 -2
  453. package/packages/event-bus/dist/bus.d.ts +0 -15
  454. package/packages/event-bus/dist/bus.js +0 -90
  455. package/packages/event-bus/dist/index.d.ts +0 -4
  456. package/packages/event-bus/dist/index.js +0 -3
  457. package/packages/event-bus/dist/test/bus.test.js +0 -52
  458. package/packages/event-bus/dist/types.d.ts +0 -27
  459. package/packages/event-bus/dist/types.js +0 -10
  460. package/packages/event-store/dist/index.d.ts +0 -3
  461. package/packages/event-store/dist/index.js +0 -2
  462. package/packages/event-store/dist/store.d.ts +0 -15
  463. package/packages/event-store/dist/store.js +0 -131
  464. package/packages/event-store/dist/test/store.test.js +0 -57
  465. package/packages/event-store/dist/types.d.ts +0 -48
  466. package/packages/event-store/dist/types.js +0 -5
  467. package/packages/event-store/src/types.d.ts +0 -48
  468. package/packages/file-copy-helper/dist/src/extension.js +0 -186
  469. package/packages/model-registry/src/types.d.ts +0 -63
  470. package/packages/notification/dist/src/adapters/email-adapter.d.ts +0 -17
  471. package/packages/notification/dist/src/adapters/email-adapter.d.ts.map +0 -1
  472. package/packages/notification/dist/src/adapters/email-adapter.js +0 -89
  473. package/packages/notification/dist/src/adapters/email-adapter.js.map +0 -1
  474. package/packages/notification/dist/src/adapters/line-adapter.d.ts +0 -17
  475. package/packages/notification/dist/src/adapters/line-adapter.d.ts.map +0 -1
  476. package/packages/notification/dist/src/adapters/line-adapter.js +0 -99
  477. package/packages/notification/dist/src/adapters/line-adapter.js.map +0 -1
  478. package/packages/notification/dist/src/adapters/ntfy-adapter.d.ts +0 -17
  479. package/packages/notification/dist/src/adapters/ntfy-adapter.d.ts.map +0 -1
  480. package/packages/notification/dist/src/adapters/ntfy-adapter.js +0 -84
  481. package/packages/notification/dist/src/adapters/ntfy-adapter.js.map +0 -1
  482. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts +0 -56
  483. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts.map +0 -1
  484. package/packages/notification/dist/src/adapters/telegram-adapter.js +0 -251
  485. package/packages/notification/dist/src/adapters/telegram-adapter.js.map +0 -1
  486. package/packages/notification/dist/src/adapters/webhook-adapter.d.ts +0 -15
  487. package/packages/notification/dist/src/adapters/webhook-adapter.d.ts.map +0 -1
  488. package/packages/notification/dist/src/adapters/webhook-adapter.js +0 -64
  489. package/packages/notification/dist/src/adapters/webhook-adapter.js.map +0 -1
  490. package/packages/notification/dist/src/base-adapter.d.ts +0 -36
  491. package/packages/notification/dist/src/base-adapter.d.ts.map +0 -1
  492. package/packages/notification/dist/src/base-adapter.js +0 -39
  493. package/packages/notification/dist/src/base-adapter.js.map +0 -1
  494. package/packages/notification/dist/src/index.d.ts +0 -12
  495. package/packages/notification/dist/src/index.d.ts.map +0 -1
  496. package/packages/notification/dist/src/index.js +0 -12
  497. package/packages/notification/dist/src/index.js.map +0 -1
  498. package/packages/notification/dist/src/notification-center.d.ts +0 -89
  499. package/packages/notification/dist/src/notification-center.d.ts.map +0 -1
  500. package/packages/notification/dist/src/notification-center.js +0 -356
  501. package/packages/notification/dist/src/notification-center.js.map +0 -1
  502. package/packages/notification/dist/src/notification-policy.d.ts +0 -66
  503. package/packages/notification/dist/src/notification-policy.d.ts.map +0 -1
  504. package/packages/notification/dist/src/notification-policy.js +0 -153
  505. package/packages/notification/dist/src/notification-policy.js.map +0 -1
  506. package/packages/notification/dist/src/telegram-webhook-handler.d.ts +0 -86
  507. package/packages/notification/dist/src/telegram-webhook-handler.d.ts.map +0 -1
  508. package/packages/notification/dist/src/telegram-webhook-handler.js +0 -149
  509. package/packages/notification/dist/src/telegram-webhook-handler.js.map +0 -1
  510. package/packages/notification/dist/src/types.d.ts +0 -106
  511. package/packages/notification/dist/src/types.d.ts.map +0 -1
  512. package/packages/notification/dist/src/types.js +0 -7
  513. package/packages/notification/dist/src/types.js.map +0 -1
  514. package/packages/projection-engine/dist/engine.d.ts +0 -61
  515. package/packages/projection-engine/dist/engine.js +0 -76
  516. package/packages/projection-engine/dist/index.d.ts +0 -2
  517. package/packages/projection-engine/dist/index.js +0 -2
  518. package/packages/projection-engine/dist/project.d.ts +0 -3
  519. package/packages/projection-engine/dist/project.js +0 -24
  520. package/packages/projection-engine/dist/types.d.ts +0 -55
  521. package/packages/projection-engine/dist/types.js +0 -5
  522. package/packages/projection-engine/src/types.d.ts +0 -55
  523. package/packages/provider-adapter-sdk/dist/src/builder.d.ts +0 -140
  524. package/packages/provider-adapter-sdk/dist/src/builder.d.ts.map +0 -1
  525. package/packages/provider-adapter-sdk/dist/src/builder.js +0 -332
  526. package/packages/provider-adapter-sdk/dist/src/builder.js.map +0 -1
  527. package/packages/provider-adapter-sdk/dist/src/errors.d.ts +0 -71
  528. package/packages/provider-adapter-sdk/dist/src/errors.d.ts.map +0 -1
  529. package/packages/provider-adapter-sdk/dist/src/errors.js +0 -111
  530. package/packages/provider-adapter-sdk/dist/src/errors.js.map +0 -1
  531. package/packages/provider-adapter-sdk/dist/src/index.d.ts +0 -15
  532. package/packages/provider-adapter-sdk/dist/src/index.d.ts.map +0 -1
  533. package/packages/provider-adapter-sdk/dist/src/index.js +0 -19
  534. package/packages/provider-adapter-sdk/dist/src/index.js.map +0 -1
  535. package/packages/provider-adapter-sdk/dist/src/registry.d.ts +0 -108
  536. package/packages/provider-adapter-sdk/dist/src/registry.d.ts.map +0 -1
  537. package/packages/provider-adapter-sdk/dist/src/registry.js +0 -301
  538. package/packages/provider-adapter-sdk/dist/src/registry.js.map +0 -1
  539. package/packages/provider-adapter-sdk/dist/src/tester.d.ts +0 -71
  540. package/packages/provider-adapter-sdk/dist/src/tester.d.ts.map +0 -1
  541. package/packages/provider-adapter-sdk/dist/src/tester.js +0 -392
  542. package/packages/provider-adapter-sdk/dist/src/tester.js.map +0 -1
  543. package/packages/provider-adapter-sdk/dist/src/types.d.ts +0 -182
  544. package/packages/provider-adapter-sdk/dist/src/types.d.ts.map +0 -1
  545. package/packages/provider-adapter-sdk/dist/src/types.js +0 -11
  546. package/packages/provider-adapter-sdk/dist/src/types.js.map +0 -1
  547. package/packages/provider-router/dist/capability-registry/src/types.d.ts +0 -47
  548. package/packages/provider-router/dist/capability-registry/src/types.d.ts.map +0 -1
  549. package/packages/provider-router/dist/capability-registry/src/types.js +0 -10
  550. package/packages/provider-router/dist/capability-registry/src/types.js.map +0 -1
  551. package/packages/provider-router/dist/provider-router/src/index.d.ts +0 -23
  552. package/packages/provider-router/dist/provider-router/src/index.d.ts.map +0 -1
  553. package/packages/provider-router/dist/provider-router/src/index.js +0 -25
  554. package/packages/provider-router/dist/provider-router/src/index.js.map +0 -1
  555. package/packages/provider-router/dist/provider-router/src/policy.d.ts +0 -10
  556. package/packages/provider-router/dist/provider-router/src/policy.d.ts.map +0 -1
  557. package/packages/provider-router/dist/provider-router/src/policy.js +0 -45
  558. package/packages/provider-router/dist/provider-router/src/policy.js.map +0 -1
  559. package/packages/provider-router/dist/provider-router/src/provider-router.d.ts +0 -56
  560. package/packages/provider-router/dist/provider-router/src/provider-router.d.ts.map +0 -1
  561. package/packages/provider-router/dist/provider-router/src/provider-router.js +0 -222
  562. package/packages/provider-router/dist/provider-router/src/provider-router.js.map +0 -1
  563. package/packages/provider-router/dist/provider-router/src/strategies.d.ts +0 -19
  564. package/packages/provider-router/dist/provider-router/src/strategies.d.ts.map +0 -1
  565. package/packages/provider-router/dist/provider-router/src/strategies.js +0 -110
  566. package/packages/provider-router/dist/provider-router/src/strategies.js.map +0 -1
  567. package/packages/provider-router/dist/provider-router/src/types.d.ts +0 -91
  568. package/packages/provider-router/dist/provider-router/src/types.d.ts.map +0 -1
  569. package/packages/provider-router/dist/provider-router/src/types.js +0 -10
  570. package/packages/provider-router/dist/provider-router/src/types.js.map +0 -1
  571. package/packages/provider-router/dist/src/index.d.ts +0 -23
  572. package/packages/provider-router/dist/src/index.d.ts.map +0 -1
  573. package/packages/provider-router/dist/src/index.js +0 -25
  574. package/packages/provider-router/dist/src/index.js.map +0 -1
  575. package/packages/provider-router/dist/src/policy.d.ts +0 -10
  576. package/packages/provider-router/dist/src/policy.d.ts.map +0 -1
  577. package/packages/provider-router/dist/src/policy.js +0 -45
  578. package/packages/provider-router/dist/src/policy.js.map +0 -1
  579. package/packages/provider-router/dist/src/provider-router.d.ts +0 -56
  580. package/packages/provider-router/dist/src/provider-router.d.ts.map +0 -1
  581. package/packages/provider-router/dist/src/provider-router.js +0 -222
  582. package/packages/provider-router/dist/src/provider-router.js.map +0 -1
  583. package/packages/provider-router/dist/src/strategies.d.ts +0 -19
  584. package/packages/provider-router/dist/src/strategies.d.ts.map +0 -1
  585. package/packages/provider-router/dist/src/strategies.js +0 -110
  586. package/packages/provider-router/dist/src/strategies.js.map +0 -1
  587. package/packages/provider-router/dist/src/types.d.ts +0 -91
  588. package/packages/provider-router/dist/src/types.d.ts.map +0 -1
  589. package/packages/provider-router/dist/src/types.js +0 -10
  590. package/packages/provider-router/dist/src/types.js.map +0 -1
  591. package/packages/provider-router/dist/types/src/runtime-types.d.ts +0 -412
  592. package/packages/provider-router/dist/types/src/runtime-types.d.ts.map +0 -1
  593. package/packages/provider-router/dist/types/src/runtime-types.js +0 -2
  594. package/packages/provider-router/dist/types/src/runtime-types.js.map +0 -1
  595. package/packages/session-api/dist/api.d.ts +0 -83
  596. package/packages/session-api/dist/api.js +0 -35
  597. package/packages/session-api/dist/index.d.ts +0 -2
  598. package/packages/session-api/dist/index.js +0 -2
  599. package/packages/session-api/dist/types.d.ts +0 -22
  600. package/packages/session-api/dist/types.js +0 -5
  601. package/packages/session-export/dist/exporter.d.ts +0 -28
  602. package/packages/session-export/dist/exporter.js +0 -38
  603. package/packages/session-export/dist/index.d.ts +0 -2
  604. package/packages/session-export/dist/index.js +0 -2
  605. package/packages/session-export/dist/types.d.ts +0 -20
  606. package/packages/session-export/dist/types.js +0 -5
  607. package/packages/subscription-engine/dist/engine.d.ts +0 -13
  608. package/packages/subscription-engine/dist/engine.js +0 -40
  609. package/packages/subscription-engine/dist/index.d.ts +0 -2
  610. package/packages/subscription-engine/dist/index.js +0 -2
  611. package/packages/subscription-engine/dist/subscriptions.d.ts +0 -19
  612. package/packages/subscription-engine/dist/subscriptions.js +0 -32
  613. package/packages/subscription-engine/dist/types.d.ts +0 -24
  614. package/packages/subscription-engine/dist/types.js +0 -5
  615. package/packages/trajectory/test/store.test.d.ts +0 -2
  616. package/packages/workflow-events/dist/events.d.ts +0 -38
  617. package/packages/workflow-events/dist/events.js +0 -46
  618. package/packages/workflow-events/dist/index.d.ts +0 -2
  619. package/packages/workflow-events/dist/index.js +0 -2
  620. package/packages/workflow-events/dist/pipeline.d.ts +0 -21
  621. package/packages/workflow-events/dist/pipeline.js +0 -27
  622. package/packages/workflow-events/dist/types.d.ts +0 -110
  623. package/packages/workflow-events/dist/types.js +0 -5
  624. package/packages/workflow-events/src/types.d.ts +0 -110
@@ -0,0 +1,2444 @@
1
+ /**
2
+ * Telegram bridge extension composition and orchestration layer
3
+ * Zones: telegram, pi agent, orchestration
4
+ * Keeps runtime wiring in one place while the package entrypoint remains a thin re-export
5
+ */
6
+ import * as AgentMessages from "./agent-messages.js";
7
+ import * as Bindings from "./bindings.js";
8
+ import * as BusApi from "./bus-api.js";
9
+ import * as BusFollower from "./bus-follower.js";
10
+ import * as BusLeader from "./bus-leader.js";
11
+ import * as BusTransport from "./bus-transport.js";
12
+ import * as Bus from "./bus.js";
13
+ import * as ChannelPosts from "./channel-posts.js";
14
+ import * as CommandTemplates from "./command-templates.js";
15
+ import * as Commands from "./commands.js";
16
+ import * as Config from "./config.js";
17
+ import * as Delivery from "./delivery.js";
18
+ import * as Inbound from "./inbound.js";
19
+ import * as Journal from "./journal.js";
20
+ import * as Lifecycle from "./lifecycle.js";
21
+ import * as Locks from "./locks.js";
22
+ import * as Logging from "./logging.js";
23
+ import * as Media from "./media.js";
24
+ import * as MenuQueue from "./menu-queue.js";
25
+ import * as MenuSettings from "./menu-settings.js";
26
+ import * as Menu from "./menu.js";
27
+ import * as Model from "./model.js";
28
+ import * as Outbound from "./outbound.js";
29
+ import * as Ownership from "./ownership.js";
30
+ import * as Paths from "./paths.js";
31
+ import * as Pi from "./pi.js";
32
+ import * as Polling from "./polling.js";
33
+ import * as Preview from "./preview.js";
34
+ import * as ProcessIdentity from "./process-identity.js";
35
+ import * as PromptTemplates from "./prompt-templates.js";
36
+ import * as Prompts from "./prompts.js";
37
+ import * as Queue from "./queue.js";
38
+ import * as Recovery from "./recovery.js";
39
+ import * as Replies from "./replies.js";
40
+ import * as Routing from "./routing.js";
41
+ import * as Runtime from "./runtime.js";
42
+ import * as Sections from "./sections.js";
43
+ import * as Skills from "./skills.js";
44
+ import * as Status from "./status.js";
45
+ import * as Sync from "./sync.js";
46
+ import * as Targets from "./target.js";
47
+ import * as TelegramApi from "./telegram-api.js";
48
+ import * as TextGroups from "./text-groups.js";
49
+ import * as ThreadCleanupManager from "./thread-cleanup-manager.js";
50
+ import * as ThreadDisplay from "./thread-display.js";
51
+ import * as ThreadNaming from "./thread-naming.js";
52
+ import * as ThreadReconciler from "./thread-reconciler.js";
53
+ import * as Threads from "./threads.js";
54
+ import * as TimeInjection from "./time-injection.js";
55
+ import * as Updates from "./updates.js";
56
+ import * as Voice from "./voice.js";
57
+ import * as WorkspaceAdmission from "./workspace-admission.js";
58
+ import * as WorkspaceRetirement from "./workspace-retirement.js";
59
+ const telegramBusProtocolIdentity = Bus.createTelegramCurrentBusProtocolIdentity([
60
+ Bus.TELEGRAM_BUS_CAPABILITY_DURABLE_FOLLOWER_ADMISSION,
61
+ Bus.TELEGRAM_BUS_CAPABILITY_QUEUE_HANDOFF,
62
+ Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_FOLLOWER_AUTO_CONNECT,
63
+ Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_THREAD_RENAME,
64
+ Bus.TELEGRAM_BUS_CAPABILITY_THREAD_DISPLAY_MODE,
65
+ Bus.TELEGRAM_BUS_CAPABILITY_DIRECTORY_DISPLAY_FORMAT,
66
+ Bus.TELEGRAM_BUS_CAPABILITY_SESSION_REPLACEMENT_INTENT,
67
+ Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE,
68
+ Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SAVE,
69
+ Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY,
70
+ Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SETTLE,
71
+ Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_COMMAND_SET,
72
+ Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY,
73
+ ]);
74
+ // --- Extension Runtime ---
75
+ export default function (pi) {
76
+ Skills.registerTelegramSkillDiscovery(pi);
77
+ const piRuntime = Pi.createExtensionApiRuntimePorts(pi);
78
+ const { getActiveTools, getCommands, getThinkingLevel, sendUserMessage, registerCommand, setActiveTools, setModel, setThinkingLevel, } = piRuntime;
79
+ const bridgeRuntime = Runtime.createTelegramBridgeRuntime();
80
+ const runtimeDiagnostics = Logging.createTelegramRuntimeDiagnosticsRuntime({
81
+ sharedFile: true,
82
+ });
83
+ const runtimeEvents = runtimeDiagnostics.events;
84
+ const recordRuntimeEvent = runtimeDiagnostics.recordRuntimeEvent;
85
+ const configStore = Config.createTelegramConfigStore({ recordRuntimeEvent });
86
+ const busProcessRuntime = Bus.createCurrentTelegramBusProcessRuntime({
87
+ getActiveProfileName: configStore.getActiveProfileName,
88
+ endpointLayout: "consolidated",
89
+ });
90
+ const { instanceId: telegramInstanceId, processId: telegramProcessId, processBirthId: telegramQueueProcessBirthId, manualFollowerOwnerId: telegramManualFollowerOwnerId, getLeaderSocketPath: getTelegramBusSocketPath, getFollowerSocketPath: getTelegramBusFollowerSocketPath, } = busProcessRuntime;
91
+ const getTelegramBotId = Config.createTelegramConfigBotIdGetter(configStore);
92
+ const workspaceAdmissionRuntime = WorkspaceAdmission.createTelegramWorkspaceAdmissionRuntimeBinding({
93
+ getProfileName: configStore.getActiveProfileName,
94
+ getBotToken: configStore.getBotToken,
95
+ getStatePath: Paths.resolveTelegramStatePath,
96
+ owner: {
97
+ processId: telegramProcessId,
98
+ processBirthId: telegramQueueProcessBirthId,
99
+ },
100
+ });
101
+ const telegramWorkspaceOperationRuntime = WorkspaceRetirement.createTelegramWorkspaceOperationRuntime({
102
+ getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
103
+ onReleaseError(error, operationKind) {
104
+ recordRuntimeEvent("bus", error, {
105
+ phase: "workspace-admission-release",
106
+ operationKind,
107
+ });
108
+ },
109
+ });
110
+ const getTelegramActiveProfileKey = Config.createTelegramActiveProfileKeyGetter(configStore);
111
+ const getTelegramManualFollowerProfileKey = BusFollower.createTelegramManualFollowerProfileKeyResolver({
112
+ getActiveProfileName: configStore.getActiveProfileName,
113
+ manualFollowerOwnerId: telegramManualFollowerOwnerId,
114
+ });
115
+ const telegramBusAuthSecret = Bus.createTelegramBusAuthSecret();
116
+ const telegramBusFollowerControlState = BusFollower.createTelegramBusFollowerControlState();
117
+ const telegramBusFollowerRegistry = Bus.createTelegramBusFollowerRegistry();
118
+ const modelContextAvailabilityBinding = Prompts.createTelegramModelContextAvailabilityBinding();
119
+ const telegramBusFollowerRegistrationState = BusFollower.createTelegramBusFollowerRegistrationState({
120
+ onAvailabilityChanged: modelContextAvailabilityBinding.reconcile,
121
+ });
122
+ const telegramBusLeaderState = Threads.createTelegramLeaderThreadStateRuntime();
123
+ const telegramThreadCapabilityState = Polling.createTelegramThreadCapabilityStateRuntime();
124
+ const telegramProvisioningActivity = Sync.createTelegramProvisioningActivityRuntime();
125
+ const messageOwnershipRuntime = Ownership.createTelegramBusMessageOwnershipRuntime({
126
+ instanceId: telegramInstanceId,
127
+ getProfileKey: getTelegramActiveProfileKey,
128
+ listFollowers: telegramBusFollowerRegistry.list,
129
+ });
130
+ const { abort, lifecycle, queue, setup, typing } = bridgeRuntime;
131
+ const getTelegramUpdateAdmissionScope = Journal.createTelegramUpdateJournalReceiptScopeResolver({
132
+ getProfileName: configStore.getActiveProfileName,
133
+ getBotToken: configStore.getBotToken,
134
+ getBotId: getTelegramBotId,
135
+ });
136
+ const telegramLeaderJournalPath = Locks.createTelegramLeaderJournalPathResolver({
137
+ getNamedJournalPath() {
138
+ return lockRuntime.getJournalPath();
139
+ },
140
+ getSessionId() {
141
+ return Pi.getExtensionContextSessionId(telegramSessionContextStore.get());
142
+ },
143
+ getProfileName: configStore.getActiveProfileName,
144
+ });
145
+ const withTelegramJournalSourceSerialization = Journal.createTelegramJournalSourceSerialization();
146
+ const telegramJournalBindingRuntime = Journal.createTelegramUpdateJournalBindingRuntime({
147
+ base: {
148
+ getProfileName: configStore.getActiveProfileName,
149
+ getBotToken: configStore.getBotToken,
150
+ getBotId: getTelegramBotId,
151
+ withSourceSerialization: withTelegramJournalSourceSerialization,
152
+ onRecovery(event) {
153
+ recordRuntimeEvent("recovery", event.kind === "repaired"
154
+ ? "Telegram update journal was repaired automatically."
155
+ : "Telegram update journal was reset after its damaged files were deleted.", {
156
+ phase: "journal-auto-recovery",
157
+ recoveryKind: event.kind,
158
+ journalPath: event.path,
159
+ revision: event.revision,
160
+ deletedPaths: event.deletedPaths,
161
+ reason: event.reason,
162
+ });
163
+ },
164
+ getQueueRuntimeIdentity() {
165
+ return {
166
+ instanceId: telegramInstanceId,
167
+ processId: telegramProcessId,
168
+ processBirthId: telegramQueueProcessBirthId,
169
+ };
170
+ },
171
+ getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
172
+ },
173
+ getLeaderJournalPath: telegramLeaderJournalPath.resolve,
174
+ getRuntimeDir: Paths.resolveTelegramTempDir,
175
+ getFollowerJournalPath(bindingKey, profileName, sessionId) {
176
+ if (sessionId !== undefined)
177
+ return Paths.resolveTelegramSessionJournalPath(sessionId, bindingKey, undefined, profileName);
178
+ return Paths.resolveTelegramFollowerJournalPath(bindingKey, undefined, profileName);
179
+ },
180
+ getActiveFollowerBindingKey: getTelegramManualFollowerProfileKey,
181
+ getActiveFollowerSessionId() {
182
+ return telegramBusFollowerRegistrationState.getSessionId(Pi.getExtensionContextSessionId(telegramSessionContextStore.get()));
183
+ },
184
+ isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
185
+ });
186
+ const telegramJournalReferenceRegistry = Journal.createTelegramUpdateJournalReferenceRegistry();
187
+ const resolveTelegramUpdateJournalBinding = telegramJournalBindingRuntime.resolveLeader;
188
+ const resolveTelegramFollowerJournalBinding = telegramJournalBindingRuntime.resolveFollower;
189
+ const getTelegramQueueJournalBinding = telegramJournalBindingRuntime.getActiveRecoveryKey;
190
+ const isTelegramBusRuntimeEnabled = telegramThreadCapabilityState.isBusRuntimeEnabled;
191
+ const configControls = Config.createTelegramConfigControls(configStore);
192
+ const lockRuntime = Locks.createTelegramLockRuntime({
193
+ key: Locks.createTelegramLockKeyResolver(configStore),
194
+ statePath: Paths.resolveTelegramStatePath(),
195
+ instanceId: telegramInstanceId,
196
+ busSecret: telegramBusAuthSecret,
197
+ staleHeartbeatMs: Locks.TELEGRAM_BUS_LEADER_STALE_HEARTBEAT_MS,
198
+ legacyLocksPath: Paths.resolveLegacyTelegramOwnersPath(),
199
+ createJournalPath() {
200
+ return telegramLeaderJournalPath.createJournalPath();
201
+ },
202
+ });
203
+ const proveTelegramLeaderUnresponsive = Bus.createTelegramBusLeaderUnresponsivenessProof({
204
+ getLeaderState: lockRuntime.getState,
205
+ getLeaderSocketPath: getTelegramBusSocketPath,
206
+ });
207
+ const telegramSessionContextStore = Lifecycle.createTelegramSessionContextStore({
208
+ getIdentity(ctx) {
209
+ return ctx.sessionManager ?? ctx.cwd;
210
+ },
211
+ });
212
+ const captureTelegramStateAuthority = Locks.createTelegramOwnedStateAuthorityCapture(lockRuntime, telegramSessionContextStore);
213
+ const threadStore = Threads.createTelegramTopicTargetStore({
214
+ path: Paths.resolveTelegramStatePath,
215
+ telegramProfile: function () {
216
+ return configStore.getActiveProfileName();
217
+ },
218
+ canPersist: lockRuntime.owns,
219
+ consolidated: {
220
+ captureAuthority: captureTelegramStateAuthority,
221
+ publishIfOwned: lockRuntime.publishStateSectionIfOwned,
222
+ },
223
+ getExternalReservedSlots: function () {
224
+ return workspaceAdmissionRuntime.resolve()?.listReservedSlots() ?? [];
225
+ },
226
+ });
227
+ const resolveWorkspaceRestoreStore = Threads.createTelegramWorkspaceRestoreResolver({
228
+ getProfileName: configStore.getActiveProfileName,
229
+ getBotToken: configStore.getBotToken,
230
+ threadStore,
231
+ });
232
+ runtimeDiagnostics.bindStorage({
233
+ getBotToken: configStore.getBotToken,
234
+ getProfileName: configStore.getActiveProfileName,
235
+ canReset: lockRuntime.owns,
236
+ commitReset: lockRuntime.commitIfOwned,
237
+ captureAuthority: captureTelegramStateAuthority,
238
+ });
239
+ const sessionActionAssembly = Commands.createTelegramSessionActionAssembly({
240
+ registerCommand,
241
+ sendUserMessage,
242
+ store: threadStore,
243
+ getProfileName: configStore.getActiveProfileName,
244
+ ownsPersistence: lockRuntime.owns,
245
+ follower: {
246
+ instanceId: telegramInstanceId,
247
+ isRegisteredFor(target) {
248
+ const registered = telegramBusFollowerRegistrationState.getTarget();
249
+ return (telegramBusFollowerRegistrationState.isRegistered() &&
250
+ registered?.chatId === target.chatId &&
251
+ registered.threadId === target.threadId);
252
+ },
253
+ async requestSessionReplacement(operation, intent) {
254
+ const request = telegramBusFollowerRegistration.requestSessionReplacement;
255
+ if (!request)
256
+ return false;
257
+ return await request(operation, intent);
258
+ },
259
+ },
260
+ async sendResult(target, html) {
261
+ const delivery = await Delivery.sendTelegramView({ text: html, parseMode: "html", replyMarkup: { inline_keyboard: [] } }, { scope: { kind: "target", target } });
262
+ return delivery.ok
263
+ ? { ok: true }
264
+ : {
265
+ ok: false,
266
+ retryable: delivery.reason === "runtime-unavailable" ||
267
+ delivery.reason === "target-unavailable" ||
268
+ delivery.reason === "transport-retryable",
269
+ };
270
+ },
271
+ handoffTtlMs: Threads.TELEGRAM_LEADER_SESSION_HANDOFF_TTL_MS,
272
+ recordRuntimeEvent,
273
+ });
274
+ const sessionActionsRuntime = sessionActionAssembly.action;
275
+ const lockOwnershipGuard = Locks.createTelegramLockOwnershipGuard(lockRuntime);
276
+ const getCurrentLeaderEpoch = lockRuntime.getOwnedLeaderEpoch;
277
+ const ownsTelegramDirectDelivery = Locks.createTelegramDirectDeliveryOwnershipChecker({
278
+ lock: lockRuntime,
279
+ contextStore: telegramSessionContextStore,
280
+ });
281
+ const modelContextAvailabilityRuntime = Prompts.createTelegramModelContextAvailabilityRuntime({
282
+ getActiveTools,
283
+ setActiveTools,
284
+ isAvailable() {
285
+ return (ownsTelegramDirectDelivery() ||
286
+ telegramBusFollowerRegistrationState.isRegistered());
287
+ },
288
+ canReconcile() {
289
+ const ctx = telegramSessionContextStore.get();
290
+ return !ctx || Pi.isExtensionContextIdle(ctx);
291
+ },
292
+ });
293
+ modelContextAvailabilityBinding.bind(modelContextAvailabilityRuntime);
294
+ const activeTurnRuntime = Queue.createTelegramActiveTurnStore();
295
+ const proactivePushTargetGetter = Config.createTelegramProactivePushTargetGetter({
296
+ getActiveTurnTarget: activeTurnRuntime.getTarget,
297
+ getAssignedTarget() {
298
+ return (telegramBusFollowerRegistrationState.getTarget() ??
299
+ telegramBusLeaderState.getTarget());
300
+ },
301
+ getAllowedUserId: configStore.getAllowedUserId,
302
+ });
303
+ const proactivePushChatIdGetter = Config.createTelegramProactivePushChatIdGetter(proactivePushTargetGetter);
304
+ const buttonActionStore = Outbound.createTelegramButtonActionStore();
305
+ const planGenerativeAppOutput = Outbound.createTelegramOutboundReplyPlanner(buttonActionStore, configControls.getAssistantRenderingMode);
306
+ const pendingModelSwitchStore = Model.createPendingModelSwitchStore();
307
+ const modelMenuRuntime = Menu.createTelegramModelMenuRuntime();
308
+ const sectionRegistry = Sections.createAndBindTelegramSectionRegistry();
309
+ const timeInjectionRuntime = TimeInjection.createTimeInjectionRuntime({
310
+ getConfig: Config.createTelegramTimeConfigGetter(configStore),
311
+ recordRuntimeEvent,
312
+ });
313
+ Outbound.bindTelegramRuntimeEventRecorder(recordRuntimeEvent);
314
+ const getContextModel = Pi.getExtensionContextModel;
315
+ const isIdle = Pi.isExtensionContextIdle;
316
+ const hasPendingMessages = Pi.hasExtensionContextPendingMessages;
317
+ const compact = Pi.compactExtensionContext;
318
+ const mediaGroupRuntime = Media.createTelegramMediaGroupController();
319
+ const textGroupRuntime = TextGroups.createTelegramTextGroupController();
320
+ const rawTelegramQueueStore = Queue.createTelegramQueueStore();
321
+ const telegramTransportStampRuntime = Queue.createTelegramTransportStampRuntime({
322
+ getProfileName: configStore.getActiveProfileName,
323
+ getBotToken: configStore.getBotToken,
324
+ });
325
+ const telegramQueueStore = Queue.createTelegramTransportStampedQueueStore(rawTelegramQueueStore, telegramTransportStampRuntime.getStamp);
326
+ const telegramApiTargetActivityRuntime = TelegramApi.createTelegramApiTargetActivityRuntime();
327
+ // Retirement protection and dead-owner reclamation must inspect the same journal sources.
328
+ const workspaceRetirementJournalPorts = {
329
+ getActiveTurnTarget: activeTurnRuntime.getTarget,
330
+ getQueuedItems: telegramQueueStore.getQueuedItems,
331
+ resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
332
+ createFollowerJournalResolver: telegramJournalBindingRuntime.createLegacyRecipientResolver,
333
+ createSessionJournalResolver: telegramJournalBindingRuntime.createRecipientResolver,
334
+ createJournalPathResolver: telegramJournalBindingRuntime.createPathResolver,
335
+ discoverFollowerJournals() {
336
+ return Journal.discoverTelegramRecipientJournalPaths({
337
+ directory: Paths.resolveTelegramTempDir(),
338
+ profileName: configStore.getActiveProfileName(),
339
+ });
340
+ },
341
+ };
342
+ const workspaceProtectionObserver = WorkspaceRetirement.createTelegramWorkspaceProtectionObserver({
343
+ listFollowers: telegramBusFollowerRegistry.list,
344
+ ...workspaceRetirementJournalPorts,
345
+ withJournalReference(binding, operation) {
346
+ if (!binding.recoveryKey)
347
+ throw new Error("Telegram workspace journal reference identity is unavailable.");
348
+ return telegramJournalReferenceRegistry.withReference({
349
+ referenceClass: "workspace-retirement",
350
+ recoveryKey: binding.recoveryKey,
351
+ }, operation);
352
+ },
353
+ inspectJournalNamespace() {
354
+ const botToken = configStore.getBotToken();
355
+ if (!botToken)
356
+ throw new Error("Telegram namespace inspection requires current bot identity.");
357
+ return Journal.inspectTelegramSessionJournalNamespace({
358
+ directory: Paths.resolveTelegramTempDir(),
359
+ profile: configStore.getActiveProfileName() ?? "default",
360
+ pollingPath: telegramLeaderJournalPath.resolve(configStore.getActiveProfileName()),
361
+ botIdentity: Journal.createTelegramUpdateJournalBotIdentity({
362
+ botToken,
363
+ botId: getTelegramBotId(),
364
+ }),
365
+ limits: {
366
+ maxDirectoryEntries: 10_000,
367
+ maxFiles: 4096,
368
+ maxBytes: 64 * 1024 * 1024,
369
+ maxEntries: 10_000,
370
+ maxWork: 100_000,
371
+ },
372
+ });
373
+ },
374
+ getJournalWriterProtection(journalBindingKey) {
375
+ const owner = Threads.getTelegramThreadOwnerFromProfileKey(journalBindingKey);
376
+ if (owner.kind !== "manual-follower")
377
+ return "unknown";
378
+ const liveness = ProcessIdentity.getTelegramProcessBirthIdentityLiveness(owner.instanceId);
379
+ return liveness === "alive"
380
+ ? "protected"
381
+ : liveness === "dead"
382
+ ? "clear"
383
+ : "unknown";
384
+ },
385
+ getDeliveryAuthorityProtection(binding) {
386
+ const retainedRestore = resolveWorkspaceRestoreStore()
387
+ ?.list()
388
+ .some(function (intent) {
389
+ return (intent.request.binding.bindingKey === binding.bindingKey ||
390
+ Targets.areTelegramTargetsEqual(intent.request.binding.target, binding.target) ||
391
+ Targets.areTelegramTargetsEqual(intent.request.target, binding.target));
392
+ });
393
+ return retainedRestore ||
394
+ telegramApiTargetActivityRuntime.hasPendingTarget(binding.target)
395
+ ? "protected"
396
+ : "clear";
397
+ },
398
+ });
399
+ const captureWorkspaceExternalProtection = workspaceProtectionObserver.capture;
400
+ const pruneWorkspaceJournalEvidence = WorkspaceRetirement.createTelegramWorkspaceJournalEvidencePruner({
401
+ store: threadStore,
402
+ getAdmission: workspaceAdmissionRuntime.resolve,
403
+ getLeaderEpoch: getCurrentLeaderEpoch,
404
+ runExclusive: telegramWorkspaceOperationRuntime.runExclusive,
405
+ protection: workspaceProtectionObserver,
406
+ });
407
+ const reclaimTelegramWorkspaceDeadOwnerQueue = WorkspaceRetirement.createTelegramWorkspaceDeadOwnerQueueReclaimer({
408
+ getExternalProtection: captureWorkspaceExternalProtection,
409
+ ...workspaceRetirementJournalPorts,
410
+ withJournalReference(binding, operation) {
411
+ if (!binding.recoveryKey)
412
+ throw new Error("Telegram workspace journal reference identity is unavailable.");
413
+ return telegramJournalReferenceRegistry.withReference({
414
+ referenceClass: "workspace-retirement",
415
+ recoveryKey: binding.recoveryKey,
416
+ }, operation);
417
+ },
418
+ getRecoveryOwner() {
419
+ return {
420
+ instanceId: telegramInstanceId,
421
+ processId: telegramProcessId,
422
+ processBirthId: telegramQueueProcessBirthId,
423
+ sessionGeneration: telegramSessionContextStore.getGeneration(),
424
+ };
425
+ },
426
+ getQueueOwnerLiveness: ProcessIdentity.getTelegramProcessLiveness,
427
+ onMutationError(error) {
428
+ recordRuntimeEvent("Telegram dead-owner queue reclamation was refused.", {
429
+ error: error instanceof Error ? error.message : String(error),
430
+ });
431
+ },
432
+ isBindingCurrent(binding) {
433
+ return WorkspaceRetirement.isCurrentTelegramWorkspaceBinding(threadStore, binding);
434
+ },
435
+ });
436
+ const inactiveThreadCleanupReviewRuntime = ThreadCleanupManager.createTelegramInactiveThreadCleanupReviewRuntime({
437
+ getProfileName() {
438
+ return configStore.getActiveProfileName() ?? "default";
439
+ },
440
+ listBindings: threadStore.listWorkspaceBindings,
441
+ getProtection: captureWorkspaceExternalProtection,
442
+ listReservations: threadStore.listReservations,
443
+ listPendingProvisions: threadStore.listPendingProvisions,
444
+ listPendingCleanups: threadStore.listPendingCleanups,
445
+ getWorkStore() {
446
+ const profileName = configStore.getActiveProfileName() ?? "default";
447
+ const botToken = configStore.getBotToken();
448
+ if (!botToken)
449
+ throw new Error("Telegram Thread cleanup review requires an active bot token.");
450
+ return ThreadCleanupManager.createTelegramThreadCleanupWorkStore({
451
+ ...Paths.resolveTelegramServiceJournalStorage("thread-cleanup", undefined, profileName),
452
+ profileName,
453
+ tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({
454
+ botToken,
455
+ }).tokenSha256,
456
+ });
457
+ },
458
+ runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
459
+ });
460
+ const updateAdmissionRuntimeBinding = Updates.createTelegramUpdateAdmissionRuntimeBinding({
461
+ isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
462
+ });
463
+ const deferredQueueDispatchRuntime = Queue.createTelegramDeferredQueueDispatchRuntime({
464
+ recordRuntimeEvent,
465
+ });
466
+ const pollingControllerState = Polling.createTelegramPollingControllerState();
467
+ const telegramSyncStateRuntime = Sync.createTelegramSyncStateRuntime();
468
+ const threadReconciliationRuntime = ThreadReconciler.createThreadReconciliationRuntime({
469
+ recordRuntimeEvent,
470
+ scheduleSnapshotPersist: runtimeDiagnostics.scheduleSnapshotPersist,
471
+ });
472
+ const recordThreadReconciliationPlan = threadReconciliationRuntime.recordPlan;
473
+ const persistTelegramConfigWithSync = Sync.createTelegramConfigSyncPersister({
474
+ persist: configStore.persist,
475
+ markConfigChange: telegramSyncStateRuntime.markConfigChange,
476
+ });
477
+ const { current: currentInstanceThreadRuntime, status: threadStatusProjectionRuntime, getDisplayTitle: getThreadDisplayTitle, } = Threads.createTelegramCurrentThreadAssembly({
478
+ instanceId: telegramInstanceId,
479
+ listRecords: threadStore.list,
480
+ listWorkspaceBindings: threadStore.listWorkspaceBindings,
481
+ getFollowerDisplayTitle: telegramBusFollowerRegistrationState.getDisplayTitle,
482
+ getActiveTurnTarget: activeTurnRuntime.getTarget,
483
+ getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
484
+ isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
485
+ getFollowerSlot: telegramBusFollowerRegistrationState.getSlot,
486
+ getFollowerThreadName: telegramBusFollowerRegistrationState.getThreadName,
487
+ getLeaderIdentity: telegramBusLeaderState.getIdentity,
488
+ getLeaderTarget: telegramBusLeaderState.getTarget,
489
+ getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
490
+ status: {
491
+ getThreadMode: function () {
492
+ return threadStore.getBotState().threadMode;
493
+ },
494
+ isBusPollingStarted: telegramThreadCapabilityState.isBusPollingStarted,
495
+ listFollowers: telegramBusFollowerRegistry.list,
496
+ listReservations: threadStore.listReservations,
497
+ listSyncObservations: threadStore.listSyncObservations,
498
+ getLeaderSocketPath: getTelegramBusSocketPath,
499
+ getFollowerSocketPath: getTelegramBusFollowerSocketPath,
500
+ getTransportKind: BusTransport.getTelegramBusTransportKind,
501
+ },
502
+ });
503
+ const findCurrentThreadRecord = currentInstanceThreadRuntime.findRecord;
504
+ const getCurrentInstanceThreadIdentity = currentInstanceThreadRuntime.getIdentity;
505
+ const statusRuntime = Status.createTelegramBridgeStatusRuntime({
506
+ getConfig: Status.createTelegramBridgeStatusConfigGetter(configStore),
507
+ getActiveProfileName: configStore.getActiveProfileName,
508
+ getDiagnosticPaths: Paths.getTelegramDiagnosticsDisplayPaths,
509
+ isPollingActive: Polling.createTelegramPollingActivityReader(pollingControllerState),
510
+ getPollingState: Polling.createTelegramPollingStateReader(pollingControllerState),
511
+ getInboundWorkerState() {
512
+ return updateAdmissionRuntimeBinding.getActive()?.getState();
513
+ },
514
+ getAcceptedThroughUpdateId() {
515
+ return Journal.withTelegramResolvedUpdateJournalReference({
516
+ registry: telegramJournalReferenceRegistry,
517
+ resolveBinding: resolveTelegramUpdateJournalBinding,
518
+ referenceClass: "polling-cursor",
519
+ operation(binding) {
520
+ return binding.journal.read().acceptedThroughUpdateId;
521
+ },
522
+ });
523
+ },
524
+ getActiveSourceMessageIds: activeTurnRuntime.getSourceMessageIds,
525
+ hasActiveTurn: activeTurnRuntime.has,
526
+ hasDispatchPending: lifecycle.hasDispatchPending,
527
+ isCompactionInProgress: lifecycle.isCompactionInProgress,
528
+ getActiveToolExecutions: lifecycle.getActiveToolExecutions,
529
+ hasPendingModelSwitch: pendingModelSwitchStore.has,
530
+ getQueuedItems: telegramQueueStore.getQueuedItems,
531
+ getQueuedItemCount: Queue.countExecutableTelegramQueueItems,
532
+ formatQueuedStatus: Queue.formatQueuedTelegramItemsStatus,
533
+ getRecentRuntimeEvents: runtimeEvents.getEvents,
534
+ getRuntimeLockState: lockRuntime.getStatusLabel,
535
+ ...threadStatusProjectionRuntime,
536
+ getBusProtocol() {
537
+ return telegramBusProtocolIdentity;
538
+ },
539
+ getBusLifecyclePhase: telegramBusFollowerControlState.getLifecyclePhase,
540
+ getBotThreadMode() {
541
+ return threadStore.getBotState();
542
+ },
543
+ getSyncState: telegramSyncStateRuntime.getState,
544
+ getThreadReconciliationState() {
545
+ return threadReconciliationRuntime.getState();
546
+ },
547
+ });
548
+ runtimeDiagnostics.bindStatus({
549
+ instanceId: telegramInstanceId,
550
+ updateStatus: statusRuntime.updateStatus,
551
+ getStatusState: statusRuntime.getStatusState,
552
+ session: telegramSessionContextStore,
553
+ async persistSnapshot(snapshot) {
554
+ threadStore.setStatusSnapshot(snapshot);
555
+ await threadStore.persistStatus();
556
+ },
557
+ });
558
+ const updateStatus = runtimeDiagnostics.updateStatus;
559
+ const getStatusLines = runtimeDiagnostics.getStatusLines;
560
+ const inboundHandlerRuntime = Inbound.createTelegramInboundHandlerRuntime({
561
+ getHandlers: configStore.getInboundHandlers,
562
+ execCommand: CommandTemplates.execCommandTemplate,
563
+ getCwd: Pi.getExtensionContextCwd,
564
+ recordRuntimeEvent,
565
+ });
566
+ // --- Telegram API ---
567
+ const directTelegramApiRuntime = TelegramApi.createDefaultTelegramBridgeApiRuntime({
568
+ getBotToken: configStore.getBotToken,
569
+ getBotScope() {
570
+ const config = configStore.get();
571
+ return (config.botUsername ??
572
+ (config.botId === undefined ? undefined : String(config.botId)));
573
+ },
574
+ recordRuntimeEvent,
575
+ targetActivity: telegramApiTargetActivityRuntime,
576
+ workspaceAdmission: workspaceAdmissionRuntime.resolve,
577
+ captureRequestErrorHandler(body) {
578
+ return Sync.captureTelegramStaleTargetRequestRecovery(body, {
579
+ ...staleTopicApiErrorRecoveryDeps,
580
+ getCurrentLeaderEpoch,
581
+ getSessionGeneration: telegramSessionContextStore.getGeneration,
582
+ getProfileName: configStore.getActiveProfileName,
583
+ onRecovered: runtimeDiagnostics.scheduleSnapshotPersist,
584
+ });
585
+ },
586
+ });
587
+ const telegramBusFollowerClients = BusFollower.createTelegramBusFollowerClientRuntime({
588
+ socketPath: getTelegramBusSocketPath,
589
+ instanceId: telegramInstanceId,
590
+ getApiAuthSecret: telegramBusFollowerControlState.getActiveAuthSecret,
591
+ getForwardingAuthSecret() {
592
+ return telegramBusAuthSecret;
593
+ },
594
+ getRegistrationGeneration: telegramBusFollowerRegistrationState.getGeneration,
595
+ waitForRegistrationGeneration: telegramBusFollowerRegistrationState.waitForGeneration,
596
+ getForwardCommentBatchPosition: textGroupRuntime.getPreparedForwardingPosition,
597
+ validateForwardOwnership: Bus.createTelegramBusForwardOwnershipValidator(telegramBusFollowerRegistry),
598
+ recordRuntimeEvent,
599
+ });
600
+ const telegramApiRuntime = BusApi.createTelegramBusAwareApiRuntime({
601
+ directRuntime: directTelegramApiRuntime,
602
+ ownsDirect() {
603
+ return lockRuntime.owns();
604
+ },
605
+ getDefaultTarget: proactivePushTargetGetter,
606
+ callFollowerApi: telegramBusFollowerClients.callApi,
607
+ });
608
+ const { call: callTelegramApi, callMultipart, deleteWebhook, getUpdates, setMyCommands, sendTypingAction, sendChatAction, sendRecordVoiceAction, sendMessageDraft, sendMessage, sendRichMessage, sendRichMessageDraft, downloadFile: downloadTelegramBridgeFile, editMessageText: editTelegramMessageText, editMessageReplyMarkup: editTelegramMessageReplyMarkup, answerCallbackQuery, answerGuestQuery, deleteMessage: deleteTelegramMessage, prepareTempDir, } = telegramApiRuntime;
609
+ // --- Message Delivery ---
610
+ const sendGuestReply = Replies.createGuestMarkdownReplySender({
611
+ answerGuestQuery,
612
+ });
613
+ // Answer guest queries immediately and replace the ACK with the final text.
614
+ const answerGuestQueryForInlineMessage = telegramApiRuntime.answerGuestQueryForInlineMessage;
615
+ const editGuestReply = Replies.createGuestMarkdownReplyEditor({
616
+ editGuestInlineMessage: telegramApiRuntime.editGuestInlineMessage,
617
+ });
618
+ // Rotate the guest placeholder frames until the final replacement stops them.
619
+ const guestPlaceholderRuntime = Replies.createTelegramGuestPlaceholderRuntime({
620
+ editGuestInlineMessage: telegramApiRuntime.editGuestInlineMessage,
621
+ recordRuntimeEvent,
622
+ });
623
+ const promptDispatchRuntime = Runtime.createTelegramPromptDispatchRuntime({
624
+ lifecycle,
625
+ typing,
626
+ getDefaultChatId: proactivePushChatIdGetter,
627
+ sendTypingAction,
628
+ updateStatus,
629
+ isContextActive: telegramSessionContextStore.isCurrent,
630
+ getTransportAuthority() {
631
+ if (ownsTelegramDirectDelivery()) {
632
+ const epoch = getCurrentLeaderEpoch();
633
+ return epoch === undefined ? undefined : `direct:${epoch}`;
634
+ }
635
+ if (!telegramBusFollowerRegistrationState.isRegistered())
636
+ return undefined;
637
+ const generation = telegramBusFollowerRegistrationState.getGeneration();
638
+ return generation ? `follower:${generation}` : undefined;
639
+ },
640
+ recordRuntimeEvent,
641
+ });
642
+ const currentModelRuntime = Model.createCurrentModelRuntime({
643
+ getContextModel,
644
+ updateStatus,
645
+ });
646
+ // --- Reply Runtime & Preview ---
647
+ const replyRuntime = Replies.createTelegramRenderedMessageDeliveryRuntime({
648
+ recordOwnership: messageOwnershipRuntime.recordLocal,
649
+ sendMessage,
650
+ sendRichMessage,
651
+ getAssistantRenderingMode: configControls.getAssistantRenderingMode,
652
+ editMessage: editTelegramMessageText,
653
+ });
654
+ const { replyTransport, editInteractiveMessage, sendInteractiveMessage, sendSectionRichMessage, } = replyRuntime;
655
+ const deliveryTargetPolicyRuntime = Delivery.createTelegramDeliveryTargetPolicyRuntime({
656
+ ownsDirect: lockRuntime.owns,
657
+ isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
658
+ getAllowedChatId: configStore.getAllowedUserId,
659
+ getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
660
+ getLeaderTarget: telegramBusLeaderState.getTarget,
661
+ listThreadRecords: threadStore.list,
662
+ getActiveTurnTarget: activeTurnRuntime.getTarget,
663
+ getActiveGuestQueryId: activeTurnRuntime.getGuestQueryId,
664
+ });
665
+ const deliveryGenerationSeed = Delivery.createTelegramDeliveryGenerationSeed(telegramInstanceId);
666
+ const deliveryLifecycleRuntime = Delivery.createTelegramBridgeDeliveryLifecycleHooks({
667
+ generationSeed: deliveryGenerationSeed,
668
+ getTargetPolicyView: deliveryTargetPolicyRuntime.getTargetPolicyView,
669
+ getTransportStamp: telegramTransportStampRuntime.getStamp,
670
+ isTransportStampActive: telegramTransportStampRuntime.isActive,
671
+ getActiveTurnTarget: deliveryTargetPolicyRuntime.getActiveTurnTarget,
672
+ api: telegramApiRuntime,
673
+ recordOwnership: messageOwnershipRuntime.recordLocal,
674
+ recordFailure(operation, error, target) {
675
+ recordRuntimeEvent("delivery", error, {
676
+ operation,
677
+ scope: target?.threadId === undefined ? "aggregate" : "thread",
678
+ });
679
+ },
680
+ });
681
+ const { sendTextReply, sendMarkdownReply } = Outbound.createTelegramOutboundTextReplyRuntime({
682
+ sendTextReply: replyRuntime.sendTextReply,
683
+ sendMarkdownReply: replyRuntime.sendMarkdownReply,
684
+ execCommand: CommandTemplates.execCommandTemplate,
685
+ getHandlers: configStore.getOutboundHandlers,
686
+ recordRuntimeEvent,
687
+ });
688
+ const generativeAppLiveSurfaceBinding = Bindings.createTelegramGenerativeAppLiveSurfaceBinding();
689
+ const invokeGenerativeAppBoundButtonAction = Bindings.createTelegramGenerativeAppBoundButtonActionInvoker({
690
+ agentDir: Paths.resolveAgentDir(),
691
+ assertExecutionCurrent: Updates.assertTelegramUpdateExecutionCurrent,
692
+ getExecutionFence: Updates.getTelegramUpdateExecutionFence,
693
+ getActiveProfileName: configStore.getActiveProfileName,
694
+ getLiveSurfaceRuntime: generativeAppLiveSurfaceBinding.get,
695
+ planOutput: planGenerativeAppOutput,
696
+ sendMarkdownReply,
697
+ editInteractiveMessage,
698
+ recordRuntimeEvent,
699
+ });
700
+ const nativeMarkdownDraftSender = TelegramApi.createTelegramAssistantDraftSender({
701
+ getAssistantRenderingMode: configControls.getAssistantRenderingMode,
702
+ renderMarkdownToHtmlDraft: Replies.renderTelegramMarkdownToHtmlDraft,
703
+ sendMessageDraft,
704
+ sendRichMessageDraft,
705
+ });
706
+ const previewRuntime = Preview.createTelegramAssistantPreviewRuntime({
707
+ getActiveTurn: activeTurnRuntime.get,
708
+ isAssistantMessage: Replies.isAssistantAgentMessage,
709
+ getMessageText: Replies.getAgentMessageText,
710
+ getDefaultReplyToMessageId: activeTurnRuntime.getReplyToMessageId,
711
+ sendDraft: nativeMarkdownDraftSender,
712
+ canSend: configControls.areDraftPreviewsEnabled,
713
+ sendMarkdownReply,
714
+ recordRuntimeEvent,
715
+ ...replyTransport,
716
+ });
717
+ const { activityRuntime, activityVerbosityRuntime, assistantOutputRuntime, publicationRuntime, } = Bindings.createTelegramActivityBindingRuntime({
718
+ generation: deliveryGenerationSeed,
719
+ assistantOutput: {
720
+ prepareTelegramPreview: previewRuntime.preparePublication,
721
+ authority: {
722
+ getPreferredTarget: proactivePushTargetGetter,
723
+ getFallbackChatId: proactivePushChatIdGetter,
724
+ getTransportStamp: telegramTransportStampRuntime.getStamp,
725
+ isTransportStampActive: telegramTransportStampRuntime.isActive,
726
+ ownsDirect: lockRuntime.owns,
727
+ getDirectEpoch: lockRuntime.getOwnedLeaderEpoch,
728
+ isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
729
+ getFollowerGeneration: telegramBusFollowerRegistrationState.getGeneration,
730
+ },
731
+ sender: {
732
+ recordOwnership: messageOwnershipRuntime.recordLocal,
733
+ sendMessage,
734
+ sendRichMessage,
735
+ editMessage: editTelegramMessageText,
736
+ getAssistantRenderingMode: configControls.getAssistantRenderingMode,
737
+ planButtonReply: Outbound.createTelegramButtonReplyPlanner(buttonActionStore),
738
+ execCommand: CommandTemplates.execCommandTemplate,
739
+ getHandlers: configStore.getOutboundHandlers,
740
+ recordRuntimeEvent,
741
+ },
742
+ recordRuntimeEvent,
743
+ },
744
+ activityVerbosity: {
745
+ getActivityMode: configControls.getActivityVerbosity,
746
+ refreshActivityMode: configControls.refreshActivityVerbosity,
747
+ resolveTarget(event) {
748
+ return event.target ?? proactivePushTargetGetter();
749
+ },
750
+ sendMessage,
751
+ sendRichMessage,
752
+ editMessageText: editTelegramMessageText,
753
+ },
754
+ });
755
+ const { mutation: queueMutationRuntime, dispatchNext: dispatchNextQueuedTelegramTurn, requestNextDispatchAnnouncement, cancelNextDispatchAnnouncement, watchdog: queueDispatchWatchdogRuntime, } = Bindings.createTelegramQueueBindingRuntime({
756
+ store: telegramQueueStore,
757
+ queue,
758
+ lifecycle,
759
+ activeTurn: activeTurnRuntime,
760
+ admission: updateAdmissionRuntimeBinding,
761
+ transportStamp: telegramTransportStampRuntime,
762
+ deferredDispatch: deferredQueueDispatchRuntime,
763
+ promptDispatch: promptDispatchRuntime,
764
+ isIdle,
765
+ hasPendingMessages,
766
+ updateStatus,
767
+ sendTextReply,
768
+ sendUserMessage,
769
+ reconcileNextDispatchAnnouncementReplyOwnership(item) {
770
+ Replies.preserveTransportReplyDedupOnNextReset(item.chatId, item.replyToMessageId, item.target);
771
+ },
772
+ recordRuntimeEvent,
773
+ });
774
+ const { finalizeMarkdownPreview, preparePreviewDelivery } = Outbound.createTelegramOutboundTextPreviewRuntime({
775
+ finalizeMarkdownPreview: previewRuntime.finalizeMarkdown,
776
+ preparePreviewDelivery: previewRuntime.prepareDelivery,
777
+ execCommand: CommandTemplates.execCommandTemplate,
778
+ getHandlers: configStore.getOutboundHandlers,
779
+ recordRuntimeEvent,
780
+ });
781
+ // --- Model And Menu Setup ---
782
+ const modelSwitchController = Model.createTelegramModelSwitchControllerRuntime({
783
+ isIdle,
784
+ getPendingModelSwitch: pendingModelSwitchStore.get,
785
+ setPendingModelSwitch: pendingModelSwitchStore.set,
786
+ getActiveTurn: activeTurnRuntime.get,
787
+ getAbortHandler: abort.getHandler,
788
+ hasAbortHandler: abort.hasHandler,
789
+ getActiveToolExecutions: lifecycle.getActiveToolExecutions,
790
+ allocateItemOrder: queue.allocateItemOrder,
791
+ allocateControlOrder: queue.allocateControlOrder,
792
+ appendQueuedItem: queueMutationRuntime.append,
793
+ updateStatus,
794
+ });
795
+ const getQueueItemCount = Queue.createTelegramQueueItemCountGetter(telegramQueueStore);
796
+ const getPromptTemplateCommands = PromptTemplates.createTelegramPromptTemplateCommandGetter({
797
+ getCommands,
798
+ getReservedCommandNames: Commands.getTelegramReservedCommandNames,
799
+ });
800
+ const getQueueMenuState = Menu.createTelegramModelMenuStateBuilder({
801
+ runtime: modelMenuRuntime,
802
+ createSettingsManager: Pi.createSettingsManager,
803
+ getActiveModel: currentModelRuntime.get,
804
+ });
805
+ const menuActionPorts = {
806
+ getModelMenuState: getQueueMenuState,
807
+ getActiveModel: currentModelRuntime.get,
808
+ getThinkingLevel,
809
+ getQueueItemCount,
810
+ getPendingCancellationCount() {
811
+ return getCurrentLeaderEpoch() === undefined
812
+ ? 0
813
+ : (updateAdmissionRuntimeBinding.getActive()?.getState()
814
+ ?.abandoningClaimCount ?? 0);
815
+ },
816
+ buildStatusHtml: Commands.createTelegramAppMenuHtmlBuilder({
817
+ buildStatusHtml: Status.createTelegramStatusHtmlBuilder({
818
+ getActiveModel: currentModelRuntime.get,
819
+ isCompactionInProgress: lifecycle.isCompactionInProgress,
820
+ getBridgeStatusLineState: statusRuntime.getStatusState,
821
+ }),
822
+ getPromptTemplateCommands,
823
+ }),
824
+ storeModelMenuState: modelMenuRuntime.storeState,
825
+ isIdle,
826
+ canOfferInFlightModelSwitch: modelSwitchController.canOfferInFlightSwitch,
827
+ sectionRegistry,
828
+ // Menu/status UI uses this to reflect whether the active Telegram turn expects voice delivery.
829
+ isVoiceReplyActive: function () {
830
+ const turn = activeTurnRuntime.get();
831
+ return Voice.isVoiceTurn(turn);
832
+ },
833
+ };
834
+ const menuActions = Menu.createTelegramMenuActionRuntime({
835
+ ...menuActionPorts,
836
+ sendTextReply,
837
+ editInteractiveMessage,
838
+ sendInteractiveMessage,
839
+ });
840
+ // --- Queue And Settings Menus ---
841
+ const queueMenuRuntime = MenuQueue.createTelegramQueueMenuRuntime({
842
+ telegramQueueStore,
843
+ queueMutationRuntime,
844
+ sendInteractiveMessage,
845
+ editInteractiveMessage,
846
+ answerCallbackQuery,
847
+ getModelMenuState: getQueueMenuState,
848
+ getStoredModelMenuState: modelMenuRuntime.getState,
849
+ storeModelMenuState: modelMenuRuntime.storeState,
850
+ updateStatusMessage: menuActions.updateStatusMessage,
851
+ updateStatus,
852
+ dismissGuestPlaceholder: guestPlaceholderRuntime.dismiss,
853
+ });
854
+ const threadDisplaySettingsRuntime = ThreadDisplay.createTelegramThreadDisplaySettingsRuntime({
855
+ getTarget() {
856
+ return (telegramBusFollowerRegistrationState.getTarget() ??
857
+ telegramBusLeaderState.getTarget());
858
+ },
859
+ getBinding(target) {
860
+ return threadStore.getWorkspaceBindingByTarget(target);
861
+ },
862
+ apply(mode) {
863
+ return ThreadDisplay.applyTelegramThreadDisplaySetting(mode, {
864
+ getProfileKey: configStore.getActiveProfileName,
865
+ ownsLeader() {
866
+ return getCurrentLeaderEpoch() !== undefined;
867
+ },
868
+ getLeaderSetter() {
869
+ return telegramBusLeaderRuntime.setThreadDisplayMode;
870
+ },
871
+ getFollowerSetter() {
872
+ return telegramBusFollowerRegistration.setThreadDisplayMode;
873
+ },
874
+ reloadConfig: configStore.load,
875
+ });
876
+ },
877
+ reset(target) {
878
+ return telegramThreadDisplayNameResetBinding.reset(target);
879
+ },
880
+ });
881
+ const settingsMenuRuntime = MenuSettings.createTelegramSettingsMenuRuntime({
882
+ reloadConfig: configStore.load,
883
+ getModelMenuState: getQueueMenuState,
884
+ getStoredModelMenuState: modelMenuRuntime.getState,
885
+ storeModelMenuState: modelMenuRuntime.storeState,
886
+ editInteractiveMessage,
887
+ sendInteractiveMessage,
888
+ answerCallbackQuery,
889
+ ...configControls,
890
+ reviewInactiveThreads: inactiveThreadCleanupReviewRuntime.review,
891
+ getThreadDisplayMode() {
892
+ return threadStore.getBotState().threadMode === "enabled"
893
+ ? Config.resolveTelegramThreadDisplayMode(configStore.get())
894
+ : undefined;
895
+ },
896
+ isThreadDisplayCustom: threadDisplaySettingsRuntime.isCustom,
897
+ async setThreadDisplayMode(mode) {
898
+ try {
899
+ await threadDisplaySettingsRuntime.setMode(mode);
900
+ }
901
+ catch (error) {
902
+ recordRuntimeEvent("bus", error, { phase: "thread-display-setting" });
903
+ throw error;
904
+ }
905
+ },
906
+ }, sectionRegistry);
907
+ // --- Polling ---
908
+ const foreignOwnedUpdateForwarder = telegramBusFollowerClients.foreignOwnedUpdateForwarder;
909
+ const workspaceRestoreFollowerController = Bus.createTelegramBusWorkspaceRestoreController({
910
+ getFollower: telegramBusFollowerRegistry.get,
911
+ localProtocolIdentity: telegramBusProtocolIdentity,
912
+ createRequestId: telegramBusFollowerClients.createRequestId,
913
+ getAuthSecret() {
914
+ return telegramBusAuthSecret;
915
+ },
916
+ });
917
+ const liveRebindFollowerController = Bus.createTelegramBusLiveRebindController({
918
+ getFollower: telegramBusFollowerRegistry.get,
919
+ localProtocolIdentity: telegramBusProtocolIdentity,
920
+ createRequestId: telegramBusFollowerClients.createRequestId,
921
+ getAuthSecret() {
922
+ return telegramBusAuthSecret;
923
+ },
924
+ });
925
+ const liveFollowerPorts = {
926
+ getJournalBindingKey(follower) {
927
+ if (!follower.profileKey || !follower.sessionId)
928
+ return undefined;
929
+ return telegramJournalBindingRuntime.createRecipientResolver(follower.profileKey, follower.sessionId)()?.recoveryKey;
930
+ },
931
+ isSelectedCommandAvailable(follower, name) {
932
+ return (Bus.hasTelegramBusSharedCapabilities(telegramBusProtocolIdentity, follower.protocol, [
933
+ ...Bus.TELEGRAM_BUS_LIVE_REBIND_CAPABILITIES,
934
+ ...Bus.TELEGRAM_BUS_HELD_COMMAND_CAPABILITIES,
935
+ ]) &&
936
+ typeof selectedMenuDelivery === "function" &&
937
+ typeof inboundRouteRuntime.prepareHeldCommand === "function" &&
938
+ typeof inboundRouteRuntime.canPrepareHeldCommand === "function" &&
939
+ inboundRouteRuntime.canPrepareHeldCommand(name, {
940
+ showStatus: menuActions.sendStatusMessage,
941
+ sendTextReply,
942
+ }) &&
943
+ !!captureTelegramStateAuthority() &&
944
+ !!workspaceAdmissionRuntime.resolve() &&
945
+ !!resolveWorkspaceRestoreStore());
946
+ },
947
+ run: liveRebindFollowerController,
948
+ };
949
+ const observedThreadTargetBinding = Polling.createTelegramThreadTargetObservationBinding();
950
+ const topicLifecycleSync = Sync.createTelegramObservedTopicLifecycleSyncHandler({
951
+ topicTargetStore: threadStore,
952
+ isBusEnabled: isTelegramBusRuntimeEnabled,
953
+ callApi: callTelegramApi,
954
+ isTopicProvisioningActive: telegramProvisioningActivity.isActive,
955
+ getCurrentLeaderEpoch,
956
+ getThreadReconciliationMachineState: threadReconciliationRuntime.getState,
957
+ recordThreadReconciliationPlan,
958
+ runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
959
+ assertExecutionCurrent(message) {
960
+ Updates.assertTelegramUpdateExecutionCurrent(message);
961
+ },
962
+ getSyncState: telegramSyncStateRuntime.getState,
963
+ setSyncState: telegramSyncStateRuntime.setState,
964
+ recordEvent: recordRuntimeEvent,
965
+ });
966
+ const inboundBusProjectionRuntime = Routing.createTelegramInboundBusProjectionRuntime({
967
+ instanceId: telegramInstanceId,
968
+ listFollowers: telegramBusFollowerRegistry.list,
969
+ listThreadRecords: threadStore.list,
970
+ getLeaderTarget: telegramBusLeaderState.getTarget,
971
+ isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
972
+ getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
973
+ getCurrentIdentity: getCurrentInstanceThreadIdentity,
974
+ });
975
+ const telegramThreadDisplayNameRenameBinding = Commands.createTelegramThreadDisplayNameRenameBinding();
976
+ const telegramThreadDisplayNameResetBinding = Commands.createTelegramThreadDisplayNameResetBinding();
977
+ const observeLiveTargetWork = Bindings.createTelegramLiveTargetWorkObserver({
978
+ queue: telegramQueueStore,
979
+ activeTurn: activeTurnRuntime,
980
+ lifecycle: bridgeRuntime.lifecycle,
981
+ isIdle,
982
+ hasPendingMessages,
983
+ hasPendingControl: pendingModelSwitchStore.has,
984
+ publication: publicationRuntime,
985
+ activity: activityRuntime,
986
+ delivery: deliveryLifecycleRuntime,
987
+ api: telegramApiTargetActivityRuntime,
988
+ });
989
+ const inboundRouteRuntime = Routing.createTelegramInboundRouteRuntime({
990
+ configStore,
991
+ callApi: callTelegramApi,
992
+ getCurrentInstanceId() {
993
+ return telegramInstanceId;
994
+ },
995
+ getAdmissionScope: getTelegramUpdateAdmissionScope,
996
+ getAdmissionJournalBinding: getTelegramQueueJournalBinding,
997
+ beginCommandEffectWork: publicationRuntime.beginWork,
998
+ getMessageOwnership: messageOwnershipRuntime.getForwardOwnership,
999
+ recordMessageOwnership: messageOwnershipRuntime.recordRouted,
1000
+ ...inboundBusProjectionRuntime,
1001
+ getDisplayTitle: getThreadDisplayTitle,
1002
+ getCurrentLeaderEpoch,
1003
+ setCurrentLeaderIdentity: telegramBusLeaderState.set,
1004
+ getThreadReconciliationMachineState: threadReconciliationRuntime.getState,
1005
+ recordThreadReconciliationPlan,
1006
+ handleTelegramTopicLifecycleUpdate: topicLifecycleSync,
1007
+ handleTelegramThreadTargetObserved(_target, ctx) {
1008
+ return observedThreadTargetBinding.handle(ctx);
1009
+ },
1010
+ foreignOwnedUpdateForwarder,
1011
+ workspaceRestoreRecipient: {
1012
+ getSessionId: Pi.getExtensionContextSessionId,
1013
+ getCwd: Pi.getExtensionContextCwd,
1014
+ getLeaderIdentity: telegramBusLeaderState.getIdentity,
1015
+ observeLeaderWork: observeLiveTargetWork,
1016
+ followerRegistry: telegramBusFollowerRegistry,
1017
+ runFollower: workspaceRestoreFollowerController,
1018
+ liveFollower: liveFollowerPorts,
1019
+ },
1020
+ getWorkspaceRestoreStore: resolveWorkspaceRestoreStore,
1021
+ captureWorkspaceExternalProtection,
1022
+ inspectRestoreSourceCompletion(expected) {
1023
+ return telegramJournalReferenceRegistry.withReference({
1024
+ referenceClass: "operator-disposition",
1025
+ recoveryKey: expected.journalBindingKey,
1026
+ }, function () {
1027
+ const observed = telegramJournalBindingRuntime.inspectSourceCompletion(expected.journalBindingKey, {
1028
+ updateId: expected.updateId,
1029
+ sourceSha256: expected.sourceSha256,
1030
+ completionSha256: expected.completionSha256,
1031
+ });
1032
+ return (observed && {
1033
+ journalBindingKey: expected.journalBindingKey,
1034
+ ...observed,
1035
+ });
1036
+ });
1037
+ },
1038
+ inspectRestoreQueuedReceipt(expected) {
1039
+ return telegramJournalReferenceRegistry.withReference({
1040
+ referenceClass: "operator-disposition",
1041
+ recoveryKey: expected.journalBindingKey,
1042
+ }, function () {
1043
+ return telegramJournalBindingRuntime.inspectQueuedReceipt(expected.journalBindingKey, {
1044
+ queueKind: expected.queueKind,
1045
+ receiptId: expected.receiptId,
1046
+ sourceUpdateIds: [...expected.sourceUpdateIds],
1047
+ queueOwner: { ...expected.queueOwner },
1048
+ });
1049
+ });
1050
+ },
1051
+ inspectRestoreSourceAbandonment(updateId, journalBindingKey) {
1052
+ return telegramJournalReferenceRegistry.withReference({
1053
+ referenceClass: "operator-disposition",
1054
+ recoveryKey: journalBindingKey,
1055
+ }, function () {
1056
+ return telegramJournalBindingRuntime.inspectSourceAbandonment(journalBindingKey, updateId);
1057
+ });
1058
+ },
1059
+ inspectRoutingInputGroupExpiry(input) {
1060
+ return telegramJournalReferenceRegistry.withReference({
1061
+ referenceClass: "operator-disposition",
1062
+ recoveryKey: input.journalBindingKey,
1063
+ }, function () {
1064
+ return telegramJournalBindingRuntime.inspectSourceGroupExpiry(input.journalBindingKey, input.updateIds);
1065
+ });
1066
+ },
1067
+ inspectTemporaryThreadSources(target, requiredJournalBindingKeys, ownInputs) {
1068
+ const binding = resolveTelegramUpdateJournalBinding();
1069
+ const botToken = configStore.getBotToken();
1070
+ if (!binding || !botToken)
1071
+ return undefined;
1072
+ const profile = configStore.getActiveProfileName() ?? "default";
1073
+ const botIdentity = Journal.createTelegramUpdateJournalBotIdentity({
1074
+ botToken,
1075
+ botId: getTelegramBotId(),
1076
+ });
1077
+ return withTelegramJournalSourceSerialization(function () {
1078
+ return Journal.isTelegramThreadCleanupJournalNamespaceClear({
1079
+ directory: Paths.resolveTelegramTempDir(),
1080
+ profile,
1081
+ botIdentity,
1082
+ pollingPath: telegramLeaderJournalPath.resolve(configStore.getActiveProfileName()),
1083
+ requiredJournalBindingKeys: [
1084
+ binding.recoveryKey,
1085
+ ...requiredJournalBindingKeys,
1086
+ ],
1087
+ ...(target.threadId !== undefined && ownInputs
1088
+ ? {
1089
+ cleanup: {
1090
+ target: { chatId: target.chatId, threadId: target.threadId },
1091
+ ownInputs,
1092
+ },
1093
+ }
1094
+ : {}),
1095
+ limits: {
1096
+ maxDirectoryEntries: 10_000,
1097
+ maxFiles: 4096,
1098
+ maxBytes: 64 * 1024 * 1024,
1099
+ maxEntries: 10_000,
1100
+ maxWork: 100_000,
1101
+ },
1102
+ withSourceReference(path, operation) {
1103
+ return telegramJournalReferenceRegistry.withReference({
1104
+ referenceClass: "operator-disposition",
1105
+ recoveryKey: Journal.createTelegramUpdateJournalBindingKey({
1106
+ path,
1107
+ profileName: profile,
1108
+ botIdentity,
1109
+ }),
1110
+ }, operation);
1111
+ },
1112
+ })
1113
+ ? []
1114
+ : undefined;
1115
+ });
1116
+ },
1117
+ hasWorkspaceRestoreAuthority() {
1118
+ return (lockRuntime.owns() &&
1119
+ Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE));
1120
+ },
1121
+ hasWorkspaceLiveRebindAuthority() {
1122
+ return (lockRuntime.owns() &&
1123
+ Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SAVE) &&
1124
+ Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY) &&
1125
+ Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SETTLE));
1126
+ },
1127
+ getSessionGeneration: telegramSessionContextStore.getGeneration,
1128
+ bridgeRuntime,
1129
+ requestNewSession(source) {
1130
+ const updateId = Updates.getTelegramUpdateExecutionFence(source)?.updateId;
1131
+ if (updateId === undefined) {
1132
+ throw new Error("Telegram session replacement requires durable update authority.");
1133
+ }
1134
+ const callbackMessage = source && typeof source === "object" && "message" in source
1135
+ ? source.message
1136
+ : source;
1137
+ const messageTarget = callbackMessage;
1138
+ const target = typeof messageTarget?.chat?.id === "number" &&
1139
+ typeof messageTarget.message_id === "number"
1140
+ ? {
1141
+ chatId: messageTarget.chat.id,
1142
+ messageId: messageTarget.message_id,
1143
+ ...(typeof messageTarget.message_thread_id === "number"
1144
+ ? { threadId: messageTarget.message_thread_id }
1145
+ : {}),
1146
+ }
1147
+ : undefined;
1148
+ if (!target) {
1149
+ throw new Error("Telegram session replacement target is unavailable.");
1150
+ }
1151
+ if (!sessionActionsRuntime.scheduleAfterUpdate(updateId, target)) {
1152
+ throw new Error("A Telegram session replacement is already pending.");
1153
+ }
1154
+ },
1155
+ activeTurnRuntime,
1156
+ mediaGroupRuntime,
1157
+ textGroupRuntime,
1158
+ telegramQueueStore,
1159
+ queueMutationRuntime,
1160
+ modelMenuRuntime,
1161
+ currentModelRuntime,
1162
+ modelSwitchController,
1163
+ menuActions,
1164
+ isVoiceReplyActive: menuActionPorts.isVoiceReplyActive,
1165
+ updateSettingsMenuMessage: settingsMenuRuntime.updateSettingsMenuMessage,
1166
+ openQueueMenu: queueMenuRuntime.openQueueMenu,
1167
+ queueMenuCallbackHandler: queueMenuRuntime.handleCallbackQuery,
1168
+ openSettingsMenu: settingsMenuRuntime.openSettingsMenu,
1169
+ settingsMenuCallbackHandler: settingsMenuRuntime.handleCallbackQuery,
1170
+ sectionRegistry,
1171
+ sendSectionRichMessage,
1172
+ buttonActionStore,
1173
+ invokeBoundButtonAction: invokeGenerativeAppBoundButtonAction,
1174
+ inboundHandlerRuntime,
1175
+ threadStore,
1176
+ runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
1177
+ liveRebindCleanupSchedule: Routing.TELEGRAM_LIVE_REBIND_CLEANUP_SCHEDULE,
1178
+ updateStatus,
1179
+ isContextActive: telegramSessionContextStore.isCurrent,
1180
+ dispatchNextQueuedTelegramTurn,
1181
+ requestNextDispatchAnnouncement,
1182
+ cancelNextDispatchAnnouncement,
1183
+ requestDeferredDispatchNextQueuedTelegramTurn: deferredQueueDispatchRuntime.request,
1184
+ hasDeferredDispatchContext: deferredQueueDispatchRuntime.isBound,
1185
+ startTypingLoop: promptDispatchRuntime.startTypingLoop,
1186
+ stopTypingLoop: typing.stop,
1187
+ answerCallbackQuery,
1188
+ editInteractiveMessage,
1189
+ editMessageReplyMarkup: editTelegramMessageReplyMarkup,
1190
+ sendInteractiveMessage,
1191
+ deleteMessage: deleteTelegramMessage,
1192
+ answerGuestQuery,
1193
+ answerGuestQueryForInlineMessage,
1194
+ startGuestPlaceholder: guestPlaceholderRuntime.start,
1195
+ sendTextReply,
1196
+ setMyCommands,
1197
+ captureThreadNameRecipientAuthority(target, ctx) {
1198
+ // Ordinary follower/classic dialogs keep their unguarded policy; closures are leader-local only.
1199
+ if (telegramBusFollowerRegistrationState.isRegistered() ||
1200
+ target.threadId === undefined)
1201
+ return undefined;
1202
+ return Threads.createTelegramWorkspaceThreadRenameRecipient({
1203
+ store: threadStore,
1204
+ instanceId: telegramInstanceId,
1205
+ target,
1206
+ assertAuthority() {
1207
+ if (telegramSessionContextStore.get() !== ctx)
1208
+ throw new Error("Telegram Thread name dialog lost Pi context.");
1209
+ },
1210
+ getAuthority: threadNameRecipientAuthority.getAuthority,
1211
+ }).assertAuthority;
1212
+ },
1213
+ validateThreadName(threadName) {
1214
+ return ThreadNaming.getTelegramManualThreadDisplayNameValidationError(threadName);
1215
+ },
1216
+ renameCurrentThread: telegramThreadDisplayNameRenameBinding.rename,
1217
+ resetCurrentThreadName: telegramThreadDisplayNameResetBinding.reset,
1218
+ getCommands,
1219
+ downloadFile: downloadTelegramBridgeFile,
1220
+ resolveTimeLine: timeInjectionRuntime.resolveLine,
1221
+ getThinkingLevel,
1222
+ setThinkingLevel,
1223
+ persistScopedModelPatterns: Pi.createScopedModelPatternPersister({
1224
+ createSettingsManager: Pi.createSettingsManager,
1225
+ clearCachedModelMenuInputs: modelMenuRuntime.clearCachedInputs,
1226
+ }),
1227
+ setModel,
1228
+ sendUserMessage,
1229
+ isIdle,
1230
+ hasPendingMessages,
1231
+ compact,
1232
+ recordRuntimeEvent,
1233
+ });
1234
+ const queueHandoffReconciliationBinding = Updates.createTelegramQueueHandoffReconciliationBinding(function (error) {
1235
+ recordRuntimeEvent("inbound-worker", error, {
1236
+ phase: "queue-handoff-reconcile",
1237
+ });
1238
+ });
1239
+ const staleTopicApiErrorRecoveryDeps = {
1240
+ topicTargetStore: threadStore,
1241
+ getSyncState: telegramSyncStateRuntime.getState,
1242
+ setSyncState: telegramSyncStateRuntime.setState,
1243
+ recordEvent: recordRuntimeEvent,
1244
+ getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
1245
+ };
1246
+ const recoverStaleTelegramTopicApiError = Sync.createTelegramStaleTopicApiErrorRecoveryRuntime(staleTopicApiErrorRecoveryDeps);
1247
+ const { owner: updateWorkerOwnerRuntime, leader: updateAdmissionLifecycleRuntime, follower: followerAdmissionLifecycleRuntime, } = Updates.createTelegramUpdateAdmissionRuntimeAssembly({
1248
+ runtimeBinding: updateAdmissionRuntimeBinding,
1249
+ acquireSourceReference(role, binding) {
1250
+ return telegramJournalReferenceRegistry.acquire({
1251
+ referenceClass: role === "leader" ? "leader-lifecycle" : "follower-lifecycle",
1252
+ recoveryKey: binding.recoveryKey,
1253
+ });
1254
+ },
1255
+ owner: {
1256
+ instanceId: telegramInstanceId,
1257
+ processId: telegramProcessId,
1258
+ processBirthId: telegramQueueProcessBirthId,
1259
+ getSessionGeneration: telegramSessionContextStore.getGeneration,
1260
+ isContextCurrent: telegramSessionContextStore.isCurrent,
1261
+ dispatchNext: dispatchNextQueuedTelegramTurn,
1262
+ requestQueueHandoffReconciliation: queueHandoffReconciliationBinding.request,
1263
+ afterQueueReceiptCommitted: inboundRouteRuntime.onQueueReceiptCommitted,
1264
+ afterUpdateCompleted(updateId, ctx, journalBindingKey) {
1265
+ sessionActionsRuntime.onUpdateCompleted(updateId);
1266
+ inboundRouteRuntime.onUpdateCompleted(updateId, ctx, journalBindingKey);
1267
+ },
1268
+ },
1269
+ worker: {
1270
+ expireRoutingInput: inboundRouteRuntime.expireRoutingInput,
1271
+ beforeQueueReceiptPublished: inboundRouteRuntime.beforeQueueReceiptPublished,
1272
+ onQueueReceiptCompleted: inboundRouteRuntime.onQueueReceiptCompleted,
1273
+ defaultHandle: inboundRouteRuntime.handleUpdate,
1274
+ async shouldReviewHistoricalInput(entry, ctx, signal) {
1275
+ if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
1276
+ throw new Error("Workspace Restore source generation ended.");
1277
+ }
1278
+ const verdict = await inboundRouteRuntime.shouldReviewHistoricalInput(entry, ctx, signal);
1279
+ if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
1280
+ throw new Error("Workspace Restore source generation ended.");
1281
+ }
1282
+ if (verdict === "retain")
1283
+ return verdict;
1284
+ const journalBindingKey = getTelegramQueueJournalBinding();
1285
+ if (journalBindingKey &&
1286
+ resolveWorkspaceRestoreStore()
1287
+ ?.list()
1288
+ .some(function (intent) {
1289
+ return (intent.request.source.journalBindingKey === journalBindingKey &&
1290
+ intent.request.source.updateIds.includes(entry.updateId));
1291
+ }))
1292
+ return true;
1293
+ return verdict;
1294
+ },
1295
+ spendHistoricalInput: true,
1296
+ onHeldSourcesPrepared(input) {
1297
+ return inboundRouteRuntime
1298
+ .forgetPreviousWorld(input, lockedPollingRuntime.captureTransportAuthority)
1299
+ .then(function () { });
1300
+ },
1301
+ async shouldHoldPendingInput(entry, ctx, signal) {
1302
+ if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
1303
+ throw new Error("Temporary Thread source generation ended.");
1304
+ }
1305
+ return inboundRouteRuntime.shouldHoldPendingInput(entry, ctx, signal);
1306
+ },
1307
+ onStateChange: runtimeDiagnostics.scheduleSnapshotPersist,
1308
+ settleTerminalExecutionFailure(error) {
1309
+ return Sync.settleStaleTelegramTopicExecutionFailure(error, staleTopicApiErrorRecoveryDeps);
1310
+ },
1311
+ },
1312
+ leader: {
1313
+ resolveBinding: resolveTelegramUpdateJournalBinding,
1314
+ hasAuthority: lockRuntime.owns,
1315
+ },
1316
+ follower: {
1317
+ resolveBinding: resolveTelegramFollowerJournalBinding,
1318
+ isRegistered: telegramBusFollowerRegistrationState.isRegistered,
1319
+ getGeneration: telegramBusFollowerRegistrationState.getGeneration,
1320
+ prepareBinding(binding) {
1321
+ telegramJournalBindingRuntime.prepareActiveFollowerSuccession(function () {
1322
+ return binding.hasAuthority?.() === true;
1323
+ });
1324
+ },
1325
+ prepareUpdateForExecution(update) {
1326
+ return BusFollower.prepareTelegramBusFollowerJournaledUpdateForExecution(update, textGroupRuntime.prepareForwardedMessage);
1327
+ },
1328
+ },
1329
+ recordRuntimeEvent,
1330
+ });
1331
+ const queueHandoffStagingRuntime = Queue.createTelegramQueueHandoffStagingRuntime({
1332
+ liveStore: telegramQueueStore,
1333
+ createControlExecution: Updates.createTelegramQueueHandoffControlExecutionFactory({
1334
+ isContextCurrent: telegramSessionContextStore.isCurrent,
1335
+ showStatus: menuActions.sendStatusMessage,
1336
+ openModelMenu: menuActions.openModelMenu,
1337
+ }),
1338
+ });
1339
+ const acceptStagedQueueHandoff = Updates.createTelegramQueueHandoffRecipientRuntime({
1340
+ staging: queueHandoffStagingRuntime,
1341
+ getRecipientOwner: updateWorkerOwnerRuntime.getQueueOwnerIdentity,
1342
+ getLifecycleForBinding: updateAdmissionRuntimeBinding.getLifecycleForJournalBinding,
1343
+ isTransportStampActive: telegramTransportStampRuntime.isActive,
1344
+ dispatchNext: dispatchNextQueuedTelegramTurn,
1345
+ });
1346
+ const followerDurableAdmissionRuntime = BusFollower.createTelegramBusFollowerDurableAdmissionRuntime({
1347
+ journal: {
1348
+ appendBatch(updates) {
1349
+ return followerAdmissionLifecycleRuntime.appendBatch(updates);
1350
+ },
1351
+ },
1352
+ signalWorker() {
1353
+ followerAdmissionLifecycleRuntime.signal();
1354
+ },
1355
+ });
1356
+ const promoteTelegramBusFollowerToLeader = BusFollower.createTelegramBusFollowerPromotionHandler({
1357
+ topicTargetStore: threadStore,
1358
+ instanceId: telegramInstanceId,
1359
+ getActiveProfileName: configStore.getActiveProfileName,
1360
+ getSessionId: Pi.getExtensionContextSessionId,
1361
+ getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
1362
+ async startLeader(ctx, election, onAcquired) {
1363
+ const result = await lockedPollingRuntime.start(ctx, {
1364
+ election,
1365
+ onAcquired,
1366
+ });
1367
+ return result.ok;
1368
+ },
1369
+ recordRuntimeEvent,
1370
+ });
1371
+ const agentMessageRuntime = AgentMessages.createTelegramAgentMessageRuntime({
1372
+ instanceId: telegramInstanceId,
1373
+ getAllowedChatId: configStore.getAllowedUserId,
1374
+ getLeaderTarget: telegramBusLeaderState.getTarget,
1375
+ getLeaderThreadName() {
1376
+ return findCurrentThreadRecord()?.threadName;
1377
+ },
1378
+ followerRegistry: telegramBusFollowerRegistry,
1379
+ getDisplayTitle: getThreadDisplayTitle,
1380
+ getContext: telegramSessionContextStore.get,
1381
+ handleUpdate: inboundRouteRuntime.handleUpdate,
1382
+ });
1383
+ const agentMessageToolRoutingRuntime = Bindings.createTelegramAgentMessageToolRoutingRuntime({
1384
+ ownsLeader: lockRuntime.owns,
1385
+ ownsDirectDelivery: ownsTelegramDirectDelivery,
1386
+ isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
1387
+ getSourceTarget: proactivePushTargetGetter,
1388
+ getSourceThreadName() {
1389
+ return findCurrentThreadRecord()?.threadName;
1390
+ },
1391
+ local: agentMessageRuntime,
1392
+ follower: telegramBusFollowerClients.agentMessages,
1393
+ });
1394
+ const followerWorkspaceTargetContextPorts = {
1395
+ isContextCurrent: telegramSessionContextStore.isCurrent,
1396
+ getSessionId: Pi.getExtensionContextSessionId,
1397
+ getCwd: Pi.getExtensionContextCwd,
1398
+ getGeneration: telegramSessionContextStore.getGeneration,
1399
+ getProfileBindingKey() {
1400
+ return workspaceAdmissionRuntime.resolve()?.getProfileKey();
1401
+ },
1402
+ getOperatorUserId: configStore.getAllowedUserId,
1403
+ getLeaderState: lockRuntime.getState,
1404
+ getAuthenticatedSecret: telegramBusFollowerControlState.getActiveAuthSecret,
1405
+ getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
1406
+ };
1407
+ const followerWorkspaceTargetOwnerPorts = {
1408
+ instanceId: telegramInstanceId,
1409
+ readRestoreIntent(operationId, profileBindingKey) {
1410
+ if (profileBindingKey !==
1411
+ workspaceAdmissionRuntime.resolve()?.getProfileKey())
1412
+ return undefined;
1413
+ return resolveWorkspaceRestoreStore()
1414
+ ?.list()
1415
+ .find(function (intent) {
1416
+ return intent.request.operationId === operationId;
1417
+ });
1418
+ },
1419
+ readLiveRebindIntent(operationId, profileBindingKey) {
1420
+ if (profileBindingKey !==
1421
+ workspaceAdmissionRuntime.resolve()?.getProfileKey())
1422
+ return undefined;
1423
+ return resolveWorkspaceRestoreStore()
1424
+ ?.listLiveRebindings()
1425
+ .find(function (intent) {
1426
+ return intent.request.operationId === operationId;
1427
+ });
1428
+ },
1429
+ topicTargetStore: threadStore,
1430
+ registrationState: telegramBusFollowerRegistrationState,
1431
+ getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
1432
+ recordRuntimeEvent,
1433
+ };
1434
+ const followerWorkspaceRestore = BusFollower.createTelegramBusFollowerWorkspaceRestoreHandler({
1435
+ ...followerWorkspaceTargetOwnerPorts,
1436
+ getContextAuthority: BusFollower.createTelegramBusFollowerRestoreContextGetter(followerWorkspaceTargetContextPorts),
1437
+ });
1438
+ const followerLiveRebindTarget = BusFollower.createTelegramBusFollowerWorkspaceRestoreHandler({
1439
+ ...followerWorkspaceTargetOwnerPorts,
1440
+ getContextAuthority: BusFollower.createTelegramBusFollowerRestoreContextGetter({
1441
+ ...followerWorkspaceTargetContextPorts,
1442
+ capability: Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY,
1443
+ }),
1444
+ });
1445
+ const selectedMenuCaller = BusFollower.createTelegramBusFollowerSelectedMenuCaller({
1446
+ client: {
1447
+ socketPath: getTelegramBusSocketPath,
1448
+ instanceId: telegramInstanceId,
1449
+ createRequestId: telegramBusFollowerClients.createRequestId,
1450
+ getAuthSecret: telegramBusFollowerControlState.getActiveAuthSecret,
1451
+ getRegistrationGeneration: telegramBusFollowerRegistrationState.getGeneration,
1452
+ },
1453
+ protocolIdentity: telegramBusProtocolIdentity,
1454
+ recipient: {
1455
+ getContextAuthority: BusFollower.createTelegramBusFollowerRestoreContextGetter({
1456
+ ...followerWorkspaceTargetContextPorts,
1457
+ // Wire recipient identity is the registered profile key, not the admission namespace.
1458
+ getProfileBindingKey: getTelegramManualFollowerProfileKey,
1459
+ capability: Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY,
1460
+ }),
1461
+ getJournalBindingKey: followerAdmissionLifecycleRuntime.getJournalBindingKey,
1462
+ getProcessIdentity() {
1463
+ return {
1464
+ processId: telegramProcessId,
1465
+ processBirthId: telegramQueueProcessBirthId,
1466
+ };
1467
+ },
1468
+ registrationState: telegramBusFollowerRegistrationState,
1469
+ },
1470
+ });
1471
+ const followerLiveRebindRuntime = BusFollower.createTelegramBusFollowerLiveRebindRuntime({
1472
+ getAdmission(ctx) {
1473
+ return telegramSessionContextStore.isCurrent(ctx)
1474
+ ? followerAdmissionLifecycleRuntime
1475
+ : undefined;
1476
+ },
1477
+ applyTarget: followerLiveRebindTarget,
1478
+ getCommandOwner(input, ctx) {
1479
+ if (!Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_COMMAND_SET) ||
1480
+ !Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY) ||
1481
+ !input.selectedCommand ||
1482
+ !telegramSessionContextStore.isCurrent(ctx) ||
1483
+ followerAdmissionLifecycleRuntime.getJournalBindingKey() !==
1484
+ input.recipientBindingKey)
1485
+ return undefined;
1486
+ const recipient = followerLiveRebindTarget.prepareLiveCommandRecipient({
1487
+ operationId: input.operationId,
1488
+ registrationGeneration: input.recipientRegistrationGeneration,
1489
+ sessionId: input.recipientSessionId,
1490
+ sourceUpdateIds: input.updates.map(function sourceUpdateId(update) {
1491
+ return update.update_id;
1492
+ }),
1493
+ target: input.selectedCommand.target,
1494
+ }, ctx);
1495
+ return (recipient &&
1496
+ Bindings.createTelegramFollowerSelectedCommandBinding({
1497
+ ctx,
1498
+ operationId: input.operationId,
1499
+ registrationGeneration: input.recipientRegistrationGeneration,
1500
+ name: input.selectedCommand.name,
1501
+ target: input.selectedCommand.target,
1502
+ recipient,
1503
+ command: inboundRouteRuntime,
1504
+ menu: menuActionPorts,
1505
+ recordOwnership: messageOwnershipRuntime.recordLocal,
1506
+ deliver(effect, assertAuthority) {
1507
+ return selectedMenuCaller({
1508
+ ctx,
1509
+ operationId: input.operationId,
1510
+ registrationGeneration: input.recipientRegistrationGeneration,
1511
+ effect,
1512
+ assertAuthority,
1513
+ });
1514
+ },
1515
+ }));
1516
+ },
1517
+ observeWork: observeLiveTargetWork,
1518
+ });
1519
+ const telegramBusFollowerAssembly = BusFollower.createTelegramBusFollowerRuntimeAssembly({
1520
+ instanceId: telegramInstanceId,
1521
+ registrationState: telegramBusFollowerRegistrationState,
1522
+ recordRuntimeEvent,
1523
+ receiver: {
1524
+ socketPath: getTelegramBusFollowerSocketPath,
1525
+ getContext: telegramSessionContextStore.get,
1526
+ getAuthSecret: telegramBusFollowerControlState.getActiveAuthSecret,
1527
+ getRecipientBindingKey: getTelegramManualFollowerProfileKey,
1528
+ getLiveRebindJournalBindingKey: followerAdmissionLifecycleRuntime.getJournalBindingKey,
1529
+ getSessionId() {
1530
+ return telegramBusFollowerAssembly.getReadySessionId();
1531
+ },
1532
+ getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
1533
+ getLocalProtocol() {
1534
+ return telegramBusProtocolIdentity;
1535
+ },
1536
+ isLiveRebindSaveEnabled() {
1537
+ return Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SAVE);
1538
+ },
1539
+ isLiveRebindApplyEnabled() {
1540
+ return Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY);
1541
+ },
1542
+ isLiveRebindSettleEnabled() {
1543
+ return Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SETTLE);
1544
+ },
1545
+ isLiveRebindCommandSetEnabled() {
1546
+ return (Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_COMMAND_SET) &&
1547
+ Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY));
1548
+ },
1549
+ handleLiveRebindSave: followerLiveRebindRuntime.save,
1550
+ handleLiveRebindApply: followerLiveRebindRuntime.apply,
1551
+ handleLiveRebindSettle: followerLiveRebindRuntime.settle,
1552
+ durableAdmission: followerDurableAdmissionRuntime,
1553
+ handleQueueHandoff: acceptStagedQueueHandoff,
1554
+ handleWorkspaceRestore: followerWorkspaceRestore,
1555
+ isWorkspaceRestoreEnabled() {
1556
+ return (Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE) &&
1557
+ Bus.hasTelegramBusCapability(telegramBusFollowerRegistrationState.getLeaderProtocol(), Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE));
1558
+ },
1559
+ },
1560
+ recovery: {
1561
+ getLeaderState: lockRuntime.getState,
1562
+ proveLeaderUnresponsive: proveTelegramLeaderUnresponsive,
1563
+ async isThreadModeDisabled() {
1564
+ await threadStore.refresh?.();
1565
+ return threadStore.getBotState().threadMode === "disabled";
1566
+ },
1567
+ setLifecyclePhase: telegramBusFollowerControlState.setLifecyclePhase,
1568
+ updateStatus,
1569
+ promoteToLeader: promoteTelegramBusFollowerToLeader,
1570
+ getActiveContext: telegramSessionContextStore.get,
1571
+ },
1572
+ registration: {
1573
+ protocolIdentity: telegramBusProtocolIdentity,
1574
+ getFollowerBusSocketPath: getTelegramBusFollowerSocketPath,
1575
+ getLeaderSocketPath: getTelegramBusSocketPath,
1576
+ isContextActive: telegramSessionContextStore.isCurrent,
1577
+ createRequestId: telegramBusFollowerClients.createRequestId,
1578
+ setActiveAuthSecret: telegramBusFollowerControlState.setActiveAuthSecret,
1579
+ getProfileKey: getTelegramManualFollowerProfileKey,
1580
+ getThreadName() {
1581
+ return telegramThreadCapabilityState.getRequestedThreadName();
1582
+ },
1583
+ getProcessBirthId() {
1584
+ return telegramQueueProcessBirthId;
1585
+ },
1586
+ getSessionId: Pi.getExtensionContextSessionId,
1587
+ getSessionGeneration: telegramSessionContextStore.getGeneration,
1588
+ async onRegistered(ctx) {
1589
+ await followerAdmissionLifecycleRuntime.onTransportChanged(ctx);
1590
+ queueHandoffReconciliationBinding.request(ctx);
1591
+ },
1592
+ onDisplayTitleChanged: updateStatus,
1593
+ },
1594
+ });
1595
+ const telegramBusFollowerRegistration = telegramBusFollowerAssembly.registration;
1596
+ const { admission: pollingAdmissionRuntime } = Polling.createTelegramDurablePollingRuntimeAssembly({
1597
+ state: pollingControllerState,
1598
+ canStart(ctx) {
1599
+ return (telegramSessionContextStore.isCurrent(ctx) && lockRuntime.owns(ctx));
1600
+ },
1601
+ onPersistentConflict(ctx, count) {
1602
+ return lockedPollingRuntime.onPersistentConflict(ctx, count);
1603
+ },
1604
+ getConfig: configStore.get,
1605
+ hasBotToken: configStore.hasBotToken,
1606
+ deleteWebhook,
1607
+ getUpdates,
1608
+ persistConfig: persistTelegramConfigWithSync,
1609
+ prepareUpdateBatch: textGroupRuntime.prepareUpdateBatch,
1610
+ journal: {
1611
+ appendBatch(updates, acceptedThroughUpdateId) {
1612
+ return updateAdmissionLifecycleRuntime.appendBatch(updates, acceptedThroughUpdateId);
1613
+ },
1614
+ getAcceptedThroughUpdateId() {
1615
+ return Journal.withTelegramResolvedUpdateJournalReference({
1616
+ registry: telegramJournalReferenceRegistry,
1617
+ resolveBinding: resolveTelegramUpdateJournalBinding,
1618
+ referenceClass: "polling-cursor",
1619
+ operation(binding) {
1620
+ return binding.journal.read().acceptedThroughUpdateId;
1621
+ },
1622
+ });
1623
+ },
1624
+ async prepareCursorCutover() {
1625
+ const cutover = Journal.withTelegramResolvedUpdateJournalReference({
1626
+ registry: telegramJournalReferenceRegistry,
1627
+ resolveBinding: resolveTelegramUpdateJournalBinding,
1628
+ referenceClass: "polling-cursor",
1629
+ operation(binding) {
1630
+ return Polling.cutOverTelegramPollingCursor({
1631
+ getLegacyCursor: configStore.getLegacyPollingCursor,
1632
+ readJournal: binding.journal.read,
1633
+ publishJournalCursor(acceptedThroughUpdateId) {
1634
+ binding.journal.appendBatch([], acceptedThroughUpdateId);
1635
+ },
1636
+ async removeLegacyCursor() {
1637
+ configStore.removeLegacyPollingCursor();
1638
+ await persistTelegramConfigWithSync();
1639
+ },
1640
+ });
1641
+ },
1642
+ });
1643
+ if (!cutover)
1644
+ throw new Error("Telegram update journal binding is unavailable.");
1645
+ await cutover;
1646
+ },
1647
+ getEntryCount: updateAdmissionLifecycleRuntime.getJournalEntryCount,
1648
+ signalWorker: updateAdmissionLifecycleRuntime.signal,
1649
+ getBootstrapEntryCount() {
1650
+ return (Journal.withTelegramResolvedUpdateJournalReference({
1651
+ registry: telegramJournalReferenceRegistry,
1652
+ resolveBinding: resolveTelegramUpdateJournalBinding,
1653
+ referenceClass: "polling-bootstrap",
1654
+ operation(binding) {
1655
+ return binding.journal.read().entries.length;
1656
+ },
1657
+ }) ?? 0);
1658
+ },
1659
+ onSessionStart: updateAdmissionLifecycleRuntime.onSessionStart,
1660
+ },
1661
+ stopTypingLoop: typing.stop,
1662
+ updateStatus,
1663
+ onPollingStateChange: runtimeDiagnostics.scheduleSnapshotPersist,
1664
+ recordRuntimeEvent,
1665
+ });
1666
+ const authorizeFollowerApiCall = Bus.createTelegramFollowerApiCallAuthorizer({
1667
+ isMessageOwned: messageOwnershipRuntime.isOwnedByFollower,
1668
+ });
1669
+ const selectedMenuDelivery = BusLeader.createTelegramBusSelectedMenuDeliveryHandler({
1670
+ followerRegistry: telegramBusFollowerRegistry,
1671
+ protocolIdentity: telegramBusProtocolIdentity,
1672
+ workspace: {
1673
+ getScopeKey() {
1674
+ return workspaceAdmissionRuntime.resolve()?.getProfileKey();
1675
+ },
1676
+ captureAuthority() {
1677
+ const isCurrent = captureTelegramStateAuthority(), epoch = lockRuntime.getOwnedLeaderEpoch(), operatorUserId = configStore.getAllowedUserId();
1678
+ return isCurrent &&
1679
+ epoch !== undefined &&
1680
+ operatorUserId !== undefined
1681
+ ? {
1682
+ executor: {
1683
+ instanceId: telegramInstanceId,
1684
+ leaderEpoch: String(epoch),
1685
+ },
1686
+ operatorUserId,
1687
+ isCurrent,
1688
+ }
1689
+ : undefined;
1690
+ },
1691
+ getStore: resolveWorkspaceRestoreStore,
1692
+ threadStore,
1693
+ getJournalBindingKey: liveFollowerPorts.getJournalBindingKey,
1694
+ run: telegramWorkspaceOperationRuntime.run,
1695
+ },
1696
+ api: {
1697
+ runtime: directTelegramApiRuntime,
1698
+ authorize: authorizeFollowerApiCall,
1699
+ record(record, assertCurrent) {
1700
+ assertCurrent();
1701
+ messageOwnershipRuntime.recordFollower(record);
1702
+ assertCurrent();
1703
+ return messageOwnershipRuntime.isOwnedByFollower(record);
1704
+ },
1705
+ },
1706
+ });
1707
+ const telegramSessionFolderSweeper = Recovery.createTelegramSessionFolderSweeper({
1708
+ getSessionsDir: Paths.resolveTelegramSessionsDir,
1709
+ getProfileName: configStore.getActiveProfileName,
1710
+ getKeptSessionIds() {
1711
+ return [
1712
+ ...threadStore
1713
+ .listWorkspaceBindings()
1714
+ .map(function bindingSession(binding) {
1715
+ return binding.sessionId;
1716
+ }),
1717
+ ...telegramBusFollowerRegistry
1718
+ .list()
1719
+ .map(function followerSession(follower) {
1720
+ return follower.sessionId;
1721
+ }),
1722
+ Pi.getExtensionContextSessionId(telegramSessionContextStore.get()),
1723
+ ];
1724
+ },
1725
+ });
1726
+ const telegramBusLeaderRuntime = BusLeader.createTelegramBusLeaderRuntimeAssembly({
1727
+ runtime: {
1728
+ socketPath: getTelegramBusSocketPath,
1729
+ commitEndpointPublication(commit) {
1730
+ return lockRuntime.commitIfOwned(commit);
1731
+ },
1732
+ followerRegistry: telegramBusFollowerRegistry,
1733
+ authSecret: telegramBusAuthSecret,
1734
+ protocolIdentity: telegramBusProtocolIdentity,
1735
+ selectedMenuDelivery,
1736
+ startPolling: pollingAdmissionRuntime.start,
1737
+ stopPolling: pollingAdmissionRuntime.stop,
1738
+ authorizeFollowerApiCall,
1739
+ resolveAgentTarget(follower, selector) {
1740
+ return agentMessageRuntime.resolveTarget(selector, follower.target);
1741
+ },
1742
+ routeAgentMessage(follower, message) {
1743
+ return agentMessageRuntime.route({
1744
+ sourceTarget: follower.target,
1745
+ sourceThreadName: follower.threadName,
1746
+ message,
1747
+ });
1748
+ },
1749
+ isFollowerProcessAlive: ProcessIdentity.isProcessAlive,
1750
+ afterFollowerPrune() {
1751
+ telegramSessionFolderSweeper.sweep();
1752
+ },
1753
+ shouldCleanupConfirmedDeadFollower: configControls.resolveAutomaticThreadCleanupEnabled,
1754
+ recordFollowerMessageOwnership(record) {
1755
+ messageOwnershipRuntime.recordFollower(record);
1756
+ },
1757
+ onWorkspaceRestoreRecipientObserved(follower, isCurrent) {
1758
+ return inboundRouteRuntime.onWorkspaceRestoreRecipientObserved(follower, isCurrent, telegramSessionContextStore.get());
1759
+ },
1760
+ },
1761
+ getAllowedUserId: configStore.getAllowedUserId,
1762
+ instanceId: telegramInstanceId,
1763
+ getCwd: Pi.getExtensionContextCwd,
1764
+ getSessionId: Pi.getExtensionContextSessionId,
1765
+ getTelegramProfile: configStore.getActiveProfileName,
1766
+ getThreadDisplayMode() {
1767
+ return Config.resolveTelegramThreadDisplayMode(configStore.get());
1768
+ },
1769
+ persistThreadDisplayMode(mode, isCurrent) {
1770
+ return Config.setTelegramThreadDisplayMode(configStore, mode, isCurrent);
1771
+ },
1772
+ onThreadDisplayChanged() {
1773
+ const ctx = telegramSessionContextStore.get();
1774
+ if (ctx)
1775
+ updateStatus(ctx);
1776
+ },
1777
+ shouldForceFreshUnnamed: telegramThreadCapabilityState.shouldForceFreshLeaderThread,
1778
+ getRequestedThreadName: telegramThreadCapabilityState.getRequestedThreadName,
1779
+ topicTargetStore: threadStore,
1780
+ getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
1781
+ runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
1782
+ captureWorkspaceExternalProtection,
1783
+ workspaceRotation: {
1784
+ getAdmission: workspaceAdmissionRuntime.resolve,
1785
+ runExclusive: telegramWorkspaceOperationRuntime.runExclusive,
1786
+ deleteThread: directTelegramApiRuntime.deleteWorkspaceThread,
1787
+ pruneJournalEvidence: pruneWorkspaceJournalEvidence,
1788
+ reclaimDeadOwnerQueuedWork(binding, isCurrent) {
1789
+ return telegramWorkspaceOperationRuntime.run({
1790
+ operationId: WorkspaceAdmission.createTelegramWorkspaceAdmissionOperationId(),
1791
+ operationKind: "workspace.reclaim-dead-owner-queue",
1792
+ scopes: [{ kind: "target", target: binding.target }],
1793
+ }, reclaimTelegramWorkspaceDeadOwnerQueue.bind(undefined, binding, isCurrent));
1794
+ },
1795
+ },
1796
+ callApi(method, body, options) {
1797
+ return directTelegramApiRuntime.call(method, body, options);
1798
+ },
1799
+ callMultipart: directTelegramApiRuntime.callMultipart,
1800
+ downloadFile: directTelegramApiRuntime.downloadFile,
1801
+ recoverStaleTargetError: recoverStaleTelegramTopicApiError,
1802
+ getCurrentLeaderEpoch,
1803
+ getThreadReconciliationMachineState: threadReconciliationRuntime.getState,
1804
+ recordThreadReconciliationPlan,
1805
+ getSyncState: telegramSyncStateRuntime.getState,
1806
+ setSyncState: telegramSyncStateRuntime.setState,
1807
+ setLeaderTarget: telegramBusLeaderState.set,
1808
+ onProvisioningStart: telegramProvisioningActivity.start,
1809
+ onProvisioningEnd: telegramProvisioningActivity.end,
1810
+ recordRuntimeEvent,
1811
+ });
1812
+ queueHandoffReconciliationBinding.set(Updates.createTelegramQueueHandoffReconciliationRuntimeAssembly({
1813
+ ownsDirect: lockRuntime.owns,
1814
+ isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
1815
+ isBusEnabled: isTelegramBusRuntimeEnabled,
1816
+ canHandoffWithLeader() {
1817
+ return Bus.hasTelegramBusCapability(telegramBusFollowerRegistrationState.getLeaderProtocol(), Bus.TELEGRAM_BUS_CAPABILITY_QUEUE_HANDOFF);
1818
+ },
1819
+ listFollowers: telegramBusFollowerRegistry.list,
1820
+ createRecipientJournalResolver: telegramJournalBindingRuntime.createRecipientResolver,
1821
+ queueStore: telegramQueueStore,
1822
+ admission: updateAdmissionRuntimeBinding,
1823
+ createHandoffToken: Journal.createTelegramUpdateQueueHandoffToken,
1824
+ createRequestId: telegramBusFollowerClients.createRequestId,
1825
+ donorInstanceId: telegramInstanceId,
1826
+ authSecret: telegramBusAuthSecret,
1827
+ stageThroughFollower: telegramBusFollowerClients.queueHandoff,
1828
+ routeThroughLeader: telegramBusLeaderRuntime.routeQueueHandoff,
1829
+ recordRuntimeEvent,
1830
+ }));
1831
+ const telegramLeaderHealthRuntime = Sync.createTelegramLeaderHealthRuntime({
1832
+ callGetMe() {
1833
+ return directTelegramApiRuntime.call("getMe", {});
1834
+ },
1835
+ getSyncState: telegramSyncStateRuntime.getState,
1836
+ setSyncState: telegramSyncStateRuntime.setState,
1837
+ recordEvent: recordRuntimeEvent,
1838
+ });
1839
+ const telegramThreadCapabilityRuntime = Polling.createTelegramThreadCapabilityOrchestration({
1840
+ state: telegramThreadCapabilityState,
1841
+ getAllowedUserId: configStore.getAllowedUserId,
1842
+ callApi: callTelegramApi,
1843
+ topicTargetStore: threadStore,
1844
+ isBusRuntimeEnabled: isTelegramBusRuntimeEnabled,
1845
+ ownsLock: lockRuntime.owns,
1846
+ isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
1847
+ startClassicPolling: pollingAdmissionRuntime.start,
1848
+ stopClassicPolling: pollingAdmissionRuntime.stop,
1849
+ startBusLeaderPolling: telegramBusLeaderRuntime.startPolling,
1850
+ stopBusLeaderPolling: telegramBusLeaderRuntime.stopPolling,
1851
+ startLeaderHealth: telegramLeaderHealthRuntime.start,
1852
+ stopLeaderHealth: telegramLeaderHealthRuntime.stop,
1853
+ registerFollowerWithLeader: telegramBusFollowerRegistration.registerWithLeader,
1854
+ restoreFollowerWithLeader(ctx, owner) {
1855
+ return telegramBusFollowerRegistration.registerWithLeader(ctx, owner, {
1856
+ restoreWorkspace: true,
1857
+ });
1858
+ },
1859
+ hasRememberedWorkspaceBinding(ctx) {
1860
+ return threadStore.hasWorkspaceBinding(Pi.getExtensionContextCwd(ctx), Pi.getExtensionContextSessionId(ctx));
1861
+ },
1862
+ suspendLiveThreadTarget: telegramBusLeaderState.clear,
1863
+ stopFollowerRegistration: telegramBusFollowerRegistration.stop,
1864
+ isTopicModeUnavailableError: Threads.isTelegramTopicModeUnavailableError,
1865
+ updateStatus,
1866
+ recordEvent: recordRuntimeEvent,
1867
+ });
1868
+ const telegramThreadCapabilityMonitor = telegramThreadCapabilityRuntime.monitor;
1869
+ observedThreadTargetBinding.set(telegramThreadCapabilityRuntime.observeTarget);
1870
+ const threadAwarePollingPorts = telegramThreadCapabilityRuntime.pollingPorts;
1871
+ const lockedPollingRuntime = Locks.createTelegramLockedPollingRuntime({
1872
+ lock: lockRuntime,
1873
+ proveOwnerUnresponsive: proveTelegramLeaderUnresponsive,
1874
+ resetDamagedState() {
1875
+ return Locks.resetDamagedTelegramRuntimeState(Paths.resolveTelegramStatePath(), function (profile, sections) {
1876
+ Threads.parseTelegramWorkspaceStateSection(sections.workspace, profile);
1877
+ WorkspaceAdmission.assertTelegramConsolidatedAdmissionSection(sections.admission, profile);
1878
+ });
1879
+ },
1880
+ transportMonitor: telegramThreadCapabilityMonitor,
1881
+ hasBotToken: configStore.hasBotToken,
1882
+ getBotTokenDiagnostic: configStore.getBotTokenDiagnostic,
1883
+ canStartPolling: Pi.canStartPollingInExtensionContext,
1884
+ isContextCurrent: telegramSessionContextStore.isCurrent,
1885
+ formatStartBlockedMessage: Pi.formatPollingStartBlockedByRunMode,
1886
+ startPolling: threadAwarePollingPorts.startPolling,
1887
+ stopPolling: threadAwarePollingPorts.stopPolling,
1888
+ registerFollowerWithOwner: threadAwarePollingPorts.registerFollowerWithOwner,
1889
+ restoreFollowerWithOwner: threadAwarePollingPorts.restoreFollowerWithOwner,
1890
+ stopFollowerRegistration: threadAwarePollingPorts.stopFollowerRegistration,
1891
+ onTransportAvailabilityChanged() {
1892
+ modelContextAvailabilityRuntime.reconcile();
1893
+ const ctx = telegramSessionContextStore.get();
1894
+ if (ctx)
1895
+ queueHandoffReconciliationBinding.request(ctx);
1896
+ },
1897
+ updateStatus,
1898
+ recordRuntimeEvent,
1899
+ });
1900
+ const { disconnect: disconnectTelegramAndDeleteCurrentThread, cleanupForSessionRestart: cleanupTelegramThreadForSessionRestart, } = Sync.createTelegramThreadDisconnectAssembly({
1901
+ instanceId: telegramInstanceId,
1902
+ getCurrentThreadRecord: findCurrentThreadRecord,
1903
+ topicTargetStore: threadStore,
1904
+ callApi: callTelegramApi,
1905
+ getCurrentLeaderEpoch,
1906
+ getLeaderTarget: telegramBusLeaderState.getTarget,
1907
+ clearLeaderTarget: telegramBusLeaderState.clear,
1908
+ disconnectFollowerThread: telegramBusFollowerRegistration.disconnectFromLeader,
1909
+ getSyncState: telegramSyncStateRuntime.getState,
1910
+ setSyncState: telegramSyncStateRuntime.setState,
1911
+ stopPolling: lockedPollingRuntime.stop,
1912
+ captureStopPolling: lockedPollingRuntime.captureStop,
1913
+ suspendPolling: lockedPollingRuntime.suspend,
1914
+ recordRuntimeEvent,
1915
+ runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
1916
+ });
1917
+ const prepareThreadPreservationOnQuit = Sync.createTelegramPreservedLeaderQuitHandler({
1918
+ instanceId: telegramInstanceId,
1919
+ topicTargetStore: threadStore,
1920
+ getCurrentLeaderEpoch,
1921
+ getProfileName: configStore.getActiveProfileName,
1922
+ isPollingSuspended: lockedPollingRuntime.isSuspended,
1923
+ resolveAutomaticThreadCleanupEnabled: configControls.resolveAutomaticThreadCleanupEnabled,
1924
+ runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
1925
+ });
1926
+ const connectionIntent = Lifecycle.createTelegramConnectionIntentRuntime();
1927
+ const connectionLifecycle = Lifecycle.createTelegramConnectionLifecycle({
1928
+ intent: connectionIntent,
1929
+ getGeneration: telegramSessionContextStore.getGeneration,
1930
+ isCurrent: telegramSessionContextStore.isCurrent,
1931
+ getProfileName: configStore.getActiveProfileName,
1932
+ isConnected() {
1933
+ return (lockRuntime.owns() ||
1934
+ telegramBusFollowerRegistrationState.isRegistered());
1935
+ },
1936
+ async activateProfile(profileName, isCurrent) {
1937
+ await configStore.load();
1938
+ if (!isCurrent())
1939
+ return false;
1940
+ return (configStore.activateProfile(profileName) && configStore.hasBotToken());
1941
+ },
1942
+ start(ctx) {
1943
+ return lockedPollingRuntime.start(ctx);
1944
+ },
1945
+ recordError(error) {
1946
+ recordRuntimeEvent("connection", error, { phase: "resume-connect" });
1947
+ },
1948
+ });
1949
+ const telegramBridgeSessionLifecycleDeps = Lifecycle.createTelegramBridgeSessionLifecycleDeps({
1950
+ contextStore: telegramSessionContextStore,
1951
+ queue: {
1952
+ getCurrentModel: getContextModel,
1953
+ loadConfig: configStore.load,
1954
+ setQueuedItems: telegramQueueStore.setQueuedItems,
1955
+ setCurrentModel: currentModelRuntime.set,
1956
+ setPendingModelSwitch: modelSwitchController.clearPendingSwitch,
1957
+ syncCounters: queue.syncCounters,
1958
+ syncFlags: lifecycle.syncFlags,
1959
+ bindDeferredDispatchContext: deferredQueueDispatchRuntime.bind,
1960
+ prepareTempDir() {
1961
+ Recovery.removeTelegramLegacyRecoveryStorage(Paths.resolveTelegramTempDir());
1962
+ return prepareTempDir();
1963
+ },
1964
+ updateStatus,
1965
+ unbindDeferredDispatchContext: deferredQueueDispatchRuntime.unbind,
1966
+ discardQueuedItems: queueMutationRuntime.clear,
1967
+ clearModelMenuState: modelMenuRuntime.clear,
1968
+ getActiveTurnChatId: activeTurnRuntime.getChatId,
1969
+ getActiveTurnTarget: activeTurnRuntime.getTarget,
1970
+ clearPreview: previewRuntime.clear,
1971
+ clearActiveTurn: activeTurnRuntime.clear,
1972
+ clearAbort: abort.clearHandler,
1973
+ recordRuntimeEvent,
1974
+ },
1975
+ follower: {
1976
+ registrationState: telegramBusFollowerRegistrationState,
1977
+ registrationRuntime: telegramBusFollowerRegistration,
1978
+ instanceId: telegramInstanceId,
1979
+ suspendPolling: lockedPollingRuntime.suspend,
1980
+ isLeader: lockRuntime.owns,
1981
+ getLeaderBinding: currentInstanceThreadRuntime.getRestorationIdentity,
1982
+ getActiveContext: telegramSessionContextStore.get,
1983
+ getActiveProfileName: configStore.getActiveProfileName,
1984
+ getLeaderState: lockRuntime.getState,
1985
+ updateStatus,
1986
+ recordRuntimeEvent,
1987
+ },
1988
+ services: {
1989
+ mediaGroup: {
1990
+ resume: mediaGroupRuntime.resume,
1991
+ suspend: mediaGroupRuntime.suspend,
1992
+ },
1993
+ textGroup: {
1994
+ resume: textGroupRuntime.resume,
1995
+ suspend: textGroupRuntime.suspend,
1996
+ },
1997
+ delivery: deliveryLifecycleRuntime,
1998
+ polling: lockedPollingRuntime,
1999
+ connection: connectionLifecycle,
2000
+ inboundWorker: {
2001
+ onSessionShutdown: updateAdmissionRuntimeBinding.onSessionShutdown,
2002
+ },
2003
+ capabilityMonitor: telegramThreadCapabilityMonitor,
2004
+ queueWatchdog: queueDispatchWatchdogRuntime,
2005
+ guestPlaceholder: { stopAll: guestPlaceholderRuntime.stopAll },
2006
+ prepareThreadPreservationOnQuit,
2007
+ },
2008
+ });
2009
+ const sessionLifecycleRuntime = Lifecycle.createTelegramBridgeSessionLifecycleAssembly(telegramBridgeSessionLifecycleDeps);
2010
+ // --- Extension API Bindings ---
2011
+ const threadNameRecipientAuthority = {
2012
+ getAuthority() {
2013
+ const ctx = telegramSessionContextStore.get();
2014
+ return {
2015
+ context: ctx,
2016
+ sessionId: Pi.getExtensionContextSessionId(ctx),
2017
+ sessionGeneration: telegramSessionContextStore.getGeneration(),
2018
+ cwd: ctx && Pi.getExtensionContextCwd(ctx),
2019
+ profileName: configStore.getActiveProfileName(),
2020
+ botToken: configStore.getBotToken(),
2021
+ operatorUserId: configStore.getAllowedUserId(),
2022
+ leaderEpoch: getCurrentLeaderEpoch(),
2023
+ ownsDirectDelivery: ownsTelegramDirectDelivery(),
2024
+ followerRegistered: telegramBusFollowerRegistrationState.isRegistered(),
2025
+ localTarget: telegramBusLeaderState.getTarget(),
2026
+ localSlot: telegramBusLeaderState.getIdentity()?.slot,
2027
+ };
2028
+ },
2029
+ };
2030
+ telegramThreadDisplayNameRenameBinding.bind({
2031
+ async rename(expectedTarget, threadName, options) {
2032
+ try {
2033
+ const assertCaller = options?.assertAuthority;
2034
+ assertCaller?.();
2035
+ if (telegramBusFollowerRegistrationState.isRegistered()) {
2036
+ if (assertCaller)
2037
+ return {
2038
+ ok: false,
2039
+ message: "Guarded follower Workspace Thread rename is unavailable.",
2040
+ };
2041
+ if (typeof expectedTarget.threadId !== "number") {
2042
+ return {
2043
+ ok: false,
2044
+ message: "Telegram Workspace Thread target is unavailable.",
2045
+ };
2046
+ }
2047
+ const renamedThreadName = await telegramBusFollowerRegistration.renameThread?.({
2048
+ chatId: expectedTarget.chatId,
2049
+ threadId: expectedTarget.threadId,
2050
+ }, threadName);
2051
+ if (!renamedThreadName) {
2052
+ return {
2053
+ ok: false,
2054
+ message: "Telegram follower Workspace Thread rename is unavailable.",
2055
+ };
2056
+ }
2057
+ return {
2058
+ ok: true,
2059
+ threadName: renamedThreadName,
2060
+ };
2061
+ }
2062
+ if (!ownsTelegramDirectDelivery()) {
2063
+ return {
2064
+ ok: false,
2065
+ message: "Telegram Workspace Thread rename requires an active leader or follower connection.",
2066
+ };
2067
+ }
2068
+ if (typeof expectedTarget.threadId !== "number") {
2069
+ return {
2070
+ ok: false,
2071
+ message: "Telegram Workspace Thread target is unavailable.",
2072
+ };
2073
+ }
2074
+ const target = {
2075
+ chatId: expectedTarget.chatId,
2076
+ threadId: expectedTarget.threadId,
2077
+ };
2078
+ const recipient = assertCaller
2079
+ ? Threads.createTelegramWorkspaceThreadRenameRecipient({
2080
+ store: threadStore,
2081
+ instanceId: telegramInstanceId,
2082
+ target,
2083
+ assertAuthority: assertCaller,
2084
+ getAuthority: threadNameRecipientAuthority.getAuthority,
2085
+ })
2086
+ : undefined;
2087
+ const renamed = await telegramBusLeaderRuntime.renameLeaderThreadAdmitted(threadName, target, recipient?.assertAuthority);
2088
+ recipient?.assertResult(renamed);
2089
+ telegramBusLeaderState.set({
2090
+ target: renamed.target,
2091
+ slot: renamed.slot,
2092
+ threadName: renamed.manualThreadName ?? renamed.threadName,
2093
+ });
2094
+ recipient?.assertResult(renamed);
2095
+ return {
2096
+ ok: true,
2097
+ threadName: renamed.manualThreadName,
2098
+ };
2099
+ }
2100
+ catch (error) {
2101
+ return {
2102
+ ok: false,
2103
+ message: error instanceof Error
2104
+ ? error.message
2105
+ : "Telegram Workspace Thread rename failed.",
2106
+ };
2107
+ }
2108
+ },
2109
+ }.rename);
2110
+ telegramThreadDisplayNameResetBinding.bind({
2111
+ async reset(expectedTarget, options) {
2112
+ try {
2113
+ const assertCaller = options?.assertAuthority;
2114
+ assertCaller?.();
2115
+ const wasFollower = telegramBusFollowerRegistrationState.isRegistered();
2116
+ if (wasFollower && assertCaller)
2117
+ return {
2118
+ ok: false,
2119
+ message: "Guarded follower Workspace Thread reset is unavailable.",
2120
+ };
2121
+ if (typeof expectedTarget.threadId !== "number") {
2122
+ return {
2123
+ ok: false,
2124
+ message: "Telegram Workspace Thread target is unavailable.",
2125
+ };
2126
+ }
2127
+ const target = {
2128
+ chatId: expectedTarget.chatId,
2129
+ threadId: expectedTarget.threadId,
2130
+ };
2131
+ const recipient = assertCaller
2132
+ ? Threads.createTelegramWorkspaceThreadResetRecipient({
2133
+ store: threadStore,
2134
+ instanceId: telegramInstanceId,
2135
+ target,
2136
+ assertAuthority: assertCaller,
2137
+ getAuthority: threadNameRecipientAuthority.getAuthority,
2138
+ })
2139
+ : undefined;
2140
+ const result = wasFollower
2141
+ ? await telegramBusFollowerRegistration.resetThreadName?.(target)
2142
+ : (await (recipient
2143
+ ? telegramBusLeaderRuntime.resetLeaderThreadName(target, recipient.assertAuthority)
2144
+ : telegramBusLeaderRuntime.resetLeaderThreadName(target))).threadName;
2145
+ if (!result) {
2146
+ return {
2147
+ ok: false,
2148
+ message: "Thread display name reset is unavailable.",
2149
+ };
2150
+ }
2151
+ recipient?.assertResult(result);
2152
+ const leaderTarget = telegramBusLeaderState.getTarget();
2153
+ if (!wasFollower && leaderTarget) {
2154
+ telegramBusLeaderState.set({
2155
+ target: leaderTarget,
2156
+ threadName: result,
2157
+ ...(recipient
2158
+ ? { slot: telegramBusLeaderState.getIdentity()?.slot }
2159
+ : {}),
2160
+ });
2161
+ }
2162
+ recipient?.assertResult(result);
2163
+ return {
2164
+ ok: true,
2165
+ threadName: result,
2166
+ };
2167
+ }
2168
+ catch (error) {
2169
+ return {
2170
+ ok: false,
2171
+ message: error instanceof Error
2172
+ ? error.message
2173
+ : "Thread display name reset failed.",
2174
+ };
2175
+ }
2176
+ },
2177
+ }.reset);
2178
+ sessionActionsRuntime.register();
2179
+ Bindings.registerTelegramCommandsAndTools({
2180
+ pi,
2181
+ agentDir: Paths.resolveAgentDir(),
2182
+ configStore,
2183
+ persistConfig: persistTelegramConfigWithSync,
2184
+ setup,
2185
+ activeTurnRuntime,
2186
+ lockedPollingRuntime,
2187
+ stopPolling: disconnectTelegramAndDeleteCurrentThread,
2188
+ // Consolidated envelope failures remain protective; legacy whole-file recovery cannot reset sibling authority.
2189
+ getDisconnectThreadName() {
2190
+ const record = findCurrentThreadRecord();
2191
+ if (!record?.target.threadId)
2192
+ return undefined;
2193
+ return record.threadName ?? "current Telegram thread";
2194
+ },
2195
+ onTransportChanged() {
2196
+ deliveryLifecycleRuntime.onSessionStart();
2197
+ activityVerbosityRuntime.reset();
2198
+ modelContextAvailabilityRuntime.reconcile();
2199
+ },
2200
+ getStatusLines,
2201
+ isContextCurrent: telegramSessionContextStore.isCurrent,
2202
+ getSessionGeneration: telegramSessionContextStore.getGeneration,
2203
+ connectionIntent,
2204
+ buttonActionStore,
2205
+ sendMarkdownReply,
2206
+ async sendChannelMarkdownMessage(channel, markdown, options) {
2207
+ if (!lockRuntime.owns()) {
2208
+ throw new Error("Telegram channel delivery requires direct leader transport ownership.");
2209
+ }
2210
+ const profileName = configStore.getActiveProfileName() ?? "default";
2211
+ const botToken = configStore.getBotToken();
2212
+ if (!botToken)
2213
+ throw new Error("Telegram channel delivery requires an active bot token.");
2214
+ const store = ChannelPosts.openTelegramChannelPostJournalStore({
2215
+ profileName,
2216
+ botToken,
2217
+ });
2218
+ const record = await ChannelPosts.publishTelegramChannelPost({
2219
+ store,
2220
+ operationId: options.operationId,
2221
+ channel: channel,
2222
+ markdown,
2223
+ async observeChannel(channelAddress) {
2224
+ return telegramApiRuntime.call("getChat", {
2225
+ chat_id: channelAddress,
2226
+ });
2227
+ },
2228
+ async send(channelAddress, body) {
2229
+ const sent = await telegramApiRuntime.call("sendRichMessage", {
2230
+ chat_id: channelAddress,
2231
+ rich_message: { markdown: body },
2232
+ ...(options.replyMarkup
2233
+ ? { reply_markup: options.replyMarkup }
2234
+ : {}),
2235
+ });
2236
+ return { messageId: sent.message_id, chat: sent.chat };
2237
+ },
2238
+ });
2239
+ return record.state === "published" ? record.messageId : undefined;
2240
+ },
2241
+ async sendChannelMediaMessage(channel, mediaPath, markdown, options) {
2242
+ if (!lockRuntime.owns()) {
2243
+ throw new Error("Telegram channel media delivery requires direct leader transport ownership.");
2244
+ }
2245
+ const profileName = configStore.getActiveProfileName() ?? "default";
2246
+ const botToken = configStore.getBotToken();
2247
+ if (!botToken)
2248
+ throw new Error("Telegram channel media delivery requires an active bot token.");
2249
+ const media = await ChannelPosts.inspectTelegramChannelPostMedia(mediaPath);
2250
+ const caption = Replies.renderTelegramMarkdownToHtmlDraft(markdown);
2251
+ ChannelPosts.assertTelegramChannelPostCaptionWithinLimit(caption);
2252
+ const store = ChannelPosts.openTelegramChannelPostJournalStore({
2253
+ profileName,
2254
+ botToken,
2255
+ });
2256
+ const record = await ChannelPosts.publishTelegramChannelPost({
2257
+ store,
2258
+ operationId: options.operationId,
2259
+ channel: channel,
2260
+ markdown,
2261
+ media,
2262
+ async observeChannel(channelAddress) {
2263
+ return telegramApiRuntime.call("getChat", {
2264
+ chat_id: channelAddress,
2265
+ });
2266
+ },
2267
+ async send(channelAddress) {
2268
+ const sent = await telegramApiRuntime.callMultipart(media.kind === "photo" ? "sendPhoto" : "sendVideo", {
2269
+ chat_id: String(channelAddress),
2270
+ caption,
2271
+ parse_mode: "HTML",
2272
+ ...(options.replyMarkup
2273
+ ? { reply_markup: JSON.stringify(options.replyMarkup) }
2274
+ : {}),
2275
+ }, media.kind === "photo" ? "photo" : "video", mediaPath, media.fileName);
2276
+ return { messageId: sent.message_id, chat: sent.chat };
2277
+ },
2278
+ });
2279
+ return record.state === "published" ? record.messageId : undefined;
2280
+ },
2281
+ listChannelPosts(input) {
2282
+ const profileName = configStore.getActiveProfileName() ?? "default";
2283
+ const botToken = configStore.getBotToken();
2284
+ if (!botToken)
2285
+ throw new Error("Telegram channel posts require an active bot token.");
2286
+ return ChannelPosts.openTelegramChannelPostJournalStore({
2287
+ profileName,
2288
+ botToken,
2289
+ }).list(input);
2290
+ },
2291
+ async mutateChannelPost(input) {
2292
+ if (!lockRuntime.owns())
2293
+ throw new Error("Telegram channel post mutation requires direct leader ownership.");
2294
+ const profileName = configStore.getActiveProfileName() ?? "default";
2295
+ const botToken = configStore.getBotToken();
2296
+ if (!botToken)
2297
+ throw new Error("Telegram channel post mutation requires an active bot token.");
2298
+ const store = ChannelPosts.openTelegramChannelPostJournalStore({
2299
+ profileName,
2300
+ botToken,
2301
+ });
2302
+ if (input.action === "edit") {
2303
+ if (!input.markdown)
2304
+ throw new Error("Telegram channel post edit requires markdown.");
2305
+ const current = store.get(input.operationId);
2306
+ const caption = current?.media
2307
+ ? Replies.renderTelegramMarkdownToHtmlDraft(input.markdown)
2308
+ : undefined;
2309
+ if (caption !== undefined) {
2310
+ ChannelPosts.assertTelegramChannelPostCaptionWithinLimit(caption);
2311
+ }
2312
+ const begun = store.beginEdit({
2313
+ operationId: input.operationId,
2314
+ mutationId: input.mutationId,
2315
+ markdown: input.markdown,
2316
+ });
2317
+ if (!begun.began) {
2318
+ if (begun.record.state === "published" &&
2319
+ begun.record.lastMutationId === input.mutationId)
2320
+ return begun.record;
2321
+ throw new Error("Telegram channel post edit outcome is unknown; refusing automatic replay.");
2322
+ }
2323
+ if (begun.record.state !== "edit-outcome-unknown")
2324
+ throw new Error("Telegram channel post edit authority is invalid.");
2325
+ if (begun.record.media) {
2326
+ if (caption === undefined) {
2327
+ throw new Error("Telegram channel post media caption edit requires retained media identity.");
2328
+ }
2329
+ await telegramApiRuntime.call("editMessageCaption", {
2330
+ chat_id: begun.record.channelId,
2331
+ message_id: begun.record.messageId,
2332
+ caption,
2333
+ parse_mode: "HTML",
2334
+ });
2335
+ }
2336
+ else {
2337
+ await telegramApiRuntime.call("editMessageText", {
2338
+ chat_id: begun.record.channelId,
2339
+ message_id: begun.record.messageId,
2340
+ text: Replies.renderTelegramMarkdownToHtmlDraft(input.markdown),
2341
+ parse_mode: "HTML",
2342
+ });
2343
+ }
2344
+ return store.confirmEdited({
2345
+ operationId: input.operationId,
2346
+ mutationId: input.mutationId,
2347
+ }).record;
2348
+ }
2349
+ if (input.markdown !== undefined)
2350
+ throw new Error("Telegram channel post deletion does not accept markdown.");
2351
+ const begun = store.beginDelete({
2352
+ operationId: input.operationId,
2353
+ mutationId: input.mutationId,
2354
+ });
2355
+ if (!begun.began) {
2356
+ if (begun.record.state === "deleted" &&
2357
+ begun.record.mutationId === input.mutationId)
2358
+ return begun.record;
2359
+ throw new Error("Telegram channel post deletion outcome is unknown; refusing automatic replay.");
2360
+ }
2361
+ if (begun.record.state !== "delete-outcome-unknown")
2362
+ throw new Error("Telegram channel post deletion authority is invalid.");
2363
+ await telegramApiRuntime.call("deleteMessage", {
2364
+ chat_id: begun.record.channelId,
2365
+ message_id: begun.record.messageId,
2366
+ });
2367
+ return store.confirmDeleted({
2368
+ operationId: input.operationId,
2369
+ mutationId: input.mutationId,
2370
+ }).record;
2371
+ },
2372
+ callMultipart,
2373
+ getDefaultChatId: proactivePushChatIdGetter,
2374
+ getDefaultTarget: proactivePushTargetGetter,
2375
+ ...agentMessageToolRoutingRuntime,
2376
+ setGenerativeAppLiveSurfaceRuntime: generativeAppLiveSurfaceBinding.set,
2377
+ updateStatus,
2378
+ recordRuntimeEvent,
2379
+ });
2380
+ // --- Lifecycle Hooks ---
2381
+ Bindings.registerTelegramLifecycleRuntimeHooks({
2382
+ pi,
2383
+ sessionLifecycleRuntime: {
2384
+ ...sessionLifecycleRuntime,
2385
+ onModelSelect: currentModelRuntime.onModelSelect,
2386
+ },
2387
+ activityRuntime,
2388
+ activityVerbosityRuntime,
2389
+ diagnostics: runtimeDiagnostics,
2390
+ assistantOutputRuntime,
2391
+ publicationRuntime,
2392
+ configStore,
2393
+ abort,
2394
+ typing,
2395
+ lifecycle,
2396
+ activeTurnRuntime,
2397
+ telegramQueueStore,
2398
+ modelSwitchController,
2399
+ previewRuntime,
2400
+ promptDispatchRuntime,
2401
+ deferredQueueDispatchRuntime,
2402
+ modelContextAvailabilityRuntime,
2403
+ disconnectOnQuit: cleanupTelegramThreadForSessionRestart,
2404
+ shutdownGenerativeAppLiveSurfaces: generativeAppLiveSurfaceBinding.shutdown,
2405
+ resolveAutomaticThreadCleanupEnabled: configControls.resolveAutomaticThreadCleanupEnabled,
2406
+ onSessionStarted(_event, ctx) {
2407
+ sessionActionAssembly.settlement.onSessionStart(ctx);
2408
+ },
2409
+ buttonActionStore,
2410
+ callMultipart,
2411
+ sendChatAction,
2412
+ sendRecordVoiceAction,
2413
+ sendMarkdownReply,
2414
+ sendTextReply,
2415
+ dispatchNextQueuedTelegramTurn,
2416
+ onPromptHandedOff(turn, ctx) {
2417
+ updateAdmissionRuntimeBinding
2418
+ .getSettlement()
2419
+ ?.onPromptHandedOff(turn, ctx);
2420
+ },
2421
+ answerGuestQuery,
2422
+ deleteMessage: deleteTelegramMessage,
2423
+ sendGuestReply,
2424
+ editGuestReply,
2425
+ stopGuestPlaceholder: guestPlaceholderRuntime.stop,
2426
+ finalizeMarkdownPreview,
2427
+ preparePreviewDelivery,
2428
+ proactivePushTargetGetter,
2429
+ getAssistantRenderingMode: configControls.getAssistantRenderingMode,
2430
+ recordMessageOwnership: messageOwnershipRuntime.recordLocal,
2431
+ canSendAgentActivity(ctx) {
2432
+ return (lockOwnershipGuard.ownsContext(ctx) ||
2433
+ telegramBusFollowerRegistrationState.isRegistered());
2434
+ },
2435
+ isSessionContextActive(ctx) {
2436
+ return telegramSessionContextStore.isCurrent(ctx);
2437
+ },
2438
+ isTurnTransportActive(turn) {
2439
+ return telegramTransportStampRuntime.isActive(turn.transportStamp);
2440
+ },
2441
+ updateStatus,
2442
+ recordRuntimeEvent,
2443
+ });
2444
+ }