@llblab/pi-telegram 0.46.0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/AGENTS.md +4 -2
  2. package/BACKLOG.md +0 -6
  3. package/CHANGELOG.md +14 -0
  4. package/README.md +5 -2
  5. package/dist/api/activity.d.ts +6 -0
  6. package/dist/api/activity.js +6 -0
  7. package/dist/api/commands.d.ts +6 -0
  8. package/dist/api/commands.js +6 -0
  9. package/dist/api/delivery.d.ts +6 -0
  10. package/dist/api/delivery.js +6 -0
  11. package/dist/api/inbound.d.ts +6 -0
  12. package/dist/api/inbound.js +6 -0
  13. package/dist/api/keyboard.d.ts +6 -0
  14. package/dist/api/keyboard.js +6 -0
  15. package/dist/api/outbound.d.ts +6 -0
  16. package/dist/api/outbound.js +6 -0
  17. package/dist/api/sections.d.ts +7 -0
  18. package/dist/api/sections.js +6 -0
  19. package/dist/api/status.d.ts +6 -0
  20. package/dist/api/status.js +6 -0
  21. package/dist/api/updates.d.ts +6 -0
  22. package/dist/api/updates.js +6 -0
  23. package/dist/api/voice.d.ts +6 -0
  24. package/dist/api/voice.js +6 -0
  25. package/dist/index.d.ts +6 -0
  26. package/dist/index.js +6 -0
  27. package/dist/lib/activity-verbosity.d.ts +52 -0
  28. package/dist/lib/activity-verbosity.js +596 -0
  29. package/dist/lib/activity.d.ts +220 -0
  30. package/dist/lib/activity.js +574 -0
  31. package/dist/lib/agent-messages.d.ts +28 -0
  32. package/dist/lib/agent-messages.js +86 -0
  33. package/dist/lib/bindings.d.ts +250 -0
  34. package/dist/lib/bindings.js +936 -0
  35. package/dist/lib/bus-api.d.ts +18 -0
  36. package/dist/lib/bus-api.js +254 -0
  37. package/dist/lib/bus-follower.d.ts +464 -0
  38. package/dist/lib/bus-follower.js +1686 -0
  39. package/dist/lib/bus-leader.d.ts +292 -0
  40. package/dist/lib/bus-leader.js +2242 -0
  41. package/dist/lib/bus-transport.d.ts +64 -0
  42. package/dist/lib/bus-transport.js +140 -0
  43. package/dist/lib/bus.d.ts +518 -0
  44. package/dist/lib/bus.js +2055 -0
  45. package/dist/lib/channel-posts.d.ts +170 -0
  46. package/dist/lib/channel-posts.js +611 -0
  47. package/dist/lib/command-templates.d.ts +70 -0
  48. package/dist/lib/command-templates.js +744 -0
  49. package/dist/lib/commands.d.ts +541 -0
  50. package/dist/lib/commands.js +1155 -0
  51. package/dist/lib/config.d.ts +252 -0
  52. package/dist/lib/config.js +889 -0
  53. package/dist/lib/delivery.d.ts +163 -0
  54. package/dist/lib/delivery.js +542 -0
  55. package/dist/lib/extension.d.ts +7 -0
  56. package/dist/lib/extension.js +1604 -0
  57. package/dist/lib/generative-app-worker.mjs +104 -0
  58. package/dist/lib/generative-apps.d.ts +212 -0
  59. package/dist/lib/generative-apps.js +1006 -0
  60. package/dist/lib/inbound.d.ts +91 -0
  61. package/dist/lib/inbound.js +502 -0
  62. package/dist/lib/journal.d.ts +665 -0
  63. package/dist/lib/journal.js +3701 -0
  64. package/dist/lib/keyboard.d.ts +23 -0
  65. package/dist/lib/keyboard.js +37 -0
  66. package/dist/lib/lifecycle.d.ts +157 -0
  67. package/dist/lib/lifecycle.js +395 -0
  68. package/dist/lib/locks.d.ts +164 -0
  69. package/dist/lib/locks.js +1208 -0
  70. package/dist/lib/logging.d.ts +50 -0
  71. package/dist/lib/logging.js +274 -0
  72. package/dist/lib/media.d.ts +181 -0
  73. package/dist/lib/media.js +602 -0
  74. package/dist/lib/menu-model.d.ts +217 -0
  75. package/dist/lib/menu-model.js +663 -0
  76. package/dist/lib/menu-queue.d.ts +37 -0
  77. package/dist/lib/menu-queue.js +408 -0
  78. package/dist/lib/menu-settings.d.ts +115 -0
  79. package/dist/lib/menu-settings.js +595 -0
  80. package/dist/lib/menu-status.d.ts +32 -0
  81. package/dist/lib/menu-status.js +112 -0
  82. package/dist/lib/menu-thinking.d.ts +29 -0
  83. package/dist/lib/menu-thinking.js +82 -0
  84. package/dist/lib/menu.d.ts +171 -0
  85. package/dist/lib/menu.js +323 -0
  86. package/dist/lib/model.d.ts +127 -0
  87. package/dist/lib/model.js +409 -0
  88. package/dist/lib/outbound-attachments.d.ts +241 -0
  89. package/dist/lib/outbound-attachments.js +639 -0
  90. package/dist/lib/outbound-buttons.d.ts +69 -0
  91. package/dist/lib/outbound-buttons.js +248 -0
  92. package/dist/lib/outbound-markup.d.ts +42 -0
  93. package/dist/lib/outbound-markup.js +678 -0
  94. package/dist/lib/outbound-voice.d.ts +55 -0
  95. package/dist/lib/outbound-voice.js +152 -0
  96. package/dist/lib/outbound.d.ts +185 -0
  97. package/dist/lib/outbound.js +516 -0
  98. package/dist/lib/ownership.d.ts +77 -0
  99. package/dist/lib/ownership.js +174 -0
  100. package/dist/lib/paths.d.ts +40 -0
  101. package/dist/lib/paths.js +94 -0
  102. package/dist/lib/pi.d.ts +72 -0
  103. package/dist/lib/pi.js +121 -0
  104. package/dist/lib/polling.d.ts +351 -0
  105. package/dist/lib/polling.js +1196 -0
  106. package/dist/lib/preview.d.ts +192 -0
  107. package/dist/lib/preview.js +614 -0
  108. package/dist/lib/prompt-templates.d.ts +24 -0
  109. package/dist/lib/prompt-templates.js +118 -0
  110. package/dist/lib/prompts.d.ts +57 -0
  111. package/dist/lib/prompts.js +167 -0
  112. package/dist/lib/queue.d.ts +766 -0
  113. package/dist/lib/queue.js +1965 -0
  114. package/dist/lib/recovery.d.ts +86 -0
  115. package/dist/lib/recovery.js +285 -0
  116. package/dist/lib/rendering.d.ts +20 -0
  117. package/dist/lib/rendering.js +983 -0
  118. package/dist/lib/replies.d.ts +214 -0
  119. package/dist/lib/replies.js +737 -0
  120. package/dist/lib/routing.d.ts +207 -0
  121. package/dist/lib/routing.js +2282 -0
  122. package/dist/lib/runtime.d.ts +172 -0
  123. package/dist/lib/runtime.js +402 -0
  124. package/dist/lib/sections.d.ts +165 -0
  125. package/dist/lib/sections.js +327 -0
  126. package/dist/lib/setup.d.ts +82 -0
  127. package/dist/lib/setup.js +150 -0
  128. package/dist/lib/skills.d.ts +8 -0
  129. package/dist/lib/skills.js +12 -0
  130. package/dist/lib/status.d.ts +442 -0
  131. package/dist/lib/status.js +1008 -0
  132. package/dist/lib/sync.d.ts +179 -0
  133. package/dist/lib/sync.js +782 -0
  134. package/dist/lib/target.d.ts +20 -0
  135. package/dist/lib/target.js +27 -0
  136. package/dist/lib/telegram-api.d.ts +541 -0
  137. package/dist/lib/telegram-api.js +1159 -0
  138. package/dist/lib/text-groups.d.ts +89 -0
  139. package/dist/lib/text-groups.js +317 -0
  140. package/dist/lib/thread-cleanup-manager.d.ts +288 -0
  141. package/dist/lib/thread-cleanup-manager.js +560 -0
  142. package/dist/lib/thread-display.d.ts +46 -0
  143. package/dist/lib/thread-display.js +257 -0
  144. package/dist/lib/thread-naming.d.ts +46 -0
  145. package/dist/lib/thread-naming.js +78 -0
  146. package/dist/lib/thread-reconciler.d.ts +239 -0
  147. package/dist/lib/thread-reconciler.js +644 -0
  148. package/dist/lib/threads.d.ts +621 -0
  149. package/dist/lib/threads.js +3679 -0
  150. package/dist/lib/time-injection.d.ts +15 -0
  151. package/dist/lib/time-injection.js +56 -0
  152. package/dist/lib/turns.d.ts +109 -0
  153. package/dist/lib/turns.js +500 -0
  154. package/dist/lib/updates.d.ts +1290 -0
  155. package/dist/lib/updates.js +3634 -0
  156. package/dist/lib/voice.d.ts +117 -0
  157. package/dist/lib/voice.js +174 -0
  158. package/dist/lib/workspace-admission.d.ts +264 -0
  159. package/dist/lib/workspace-admission.js +1136 -0
  160. package/dist/lib/workspace-retirement.d.ts +219 -0
  161. package/dist/lib/workspace-retirement.js +587 -0
  162. package/dist/lib/workspace-slots.d.ts +30 -0
  163. package/dist/lib/workspace-slots.js +54 -0
  164. package/dist/package.json +126 -0
  165. package/dist/pi-telegram/index.js +1 -0
  166. package/dist/skills/generated-control-surface/SKILL.md +107 -0
  167. package/dist/skills/generated-control-surface/references/capability-adapters.md +27 -0
  168. package/dist/skills/generated-control-surface/references/layout-and-state.md +37 -0
  169. package/dist/skills/generative-apps/SKILL.md +115 -0
  170. package/dist/skills/show-me/SKILL.md +166 -0
  171. package/dist/skills/show-me/references/telegram-surfaces.md +43 -0
  172. package/dist/skills/telegram-bridge/SKILL.md +129 -0
  173. package/dist/skills/telegram-bridge/references/configuration.md +15 -0
  174. package/dist/skills/telegram-bridge/references/delivery-and-threads.md +27 -0
  175. package/dist/skills/telegram-bridge/references/diagnosis.md +18 -0
  176. package/docs/README.md +2 -0
  177. package/docs/architecture.md +1 -1
  178. package/docs/compact-matrix-literal.md +10 -3
  179. package/docs/generative-apps.md +15 -13
  180. package/docs/multi-instance-bus.md +6 -4
  181. package/docs/outbound.md +1 -1
  182. package/docs/public-api.md +3 -3
  183. package/lib/bindings.ts +89 -6
  184. package/lib/bus-follower.ts +7 -3
  185. package/lib/bus-leader.ts +44 -19
  186. package/lib/bus.ts +4 -1
  187. package/lib/commands.ts +2 -2
  188. package/lib/config.ts +14 -7
  189. package/lib/delivery.ts +38 -6
  190. package/lib/extension.ts +7 -0
  191. package/lib/generative-apps.ts +379 -13
  192. package/lib/menu-settings.ts +20 -6
  193. package/lib/outbound-markup.ts +16 -7
  194. package/lib/status.ts +15 -12
  195. package/lib/telegram-api.ts +12 -1
  196. package/lib/thread-display.ts +96 -18
  197. package/package.json +56 -13
  198. package/scripts/build-dist.mjs +44 -0
  199. package/scripts/measure-bus.mjs +8 -1
  200. package/scripts/measure-workspace.mjs +8 -1
  201. package/skills/generative-apps/SKILL.md +1 -1
  202. package/skills/show-me/SKILL.md +1 -1
  203. package/skills/show-me/references/telegram-surfaces.md +1 -1
  204. package/skills/telegram-bridge/SKILL.md +1 -1
@@ -0,0 +1,351 @@
1
+ /**
2
+ * Telegram polling runtime domain helpers
3
+ * Zones: telegram transport, polling runtime
4
+ * Owns polling request builders, stop conditions, and the long-poll loop runtime for Telegram updates
5
+ */
6
+ type MaybePromise<T> = T | Promise<T>;
7
+ export interface TelegramPollingConfig {
8
+ botToken?: string;
9
+ }
10
+ export interface TelegramUpdate {
11
+ update_id: number;
12
+ }
13
+ export declare const TELEGRAM_GET_UPDATES_CONFLICT_STOP_LIMIT = 10;
14
+ export declare const TELEGRAM_GET_UPDATES_GRACE_MS = 10000;
15
+ export declare const TELEGRAM_ALLOWED_UPDATES: readonly ["message", "edited_message", "callback_query", "message_reaction", "guest_message"];
16
+ export declare function buildTelegramInitialSyncRequest(): {
17
+ offset: number;
18
+ limit: number;
19
+ timeout: number;
20
+ };
21
+ export declare function buildTelegramLongPollRequest(lastUpdateId?: number): {
22
+ offset?: number;
23
+ limit: number;
24
+ timeout: number;
25
+ allowed_updates: readonly string[];
26
+ };
27
+ export declare function getLatestTelegramUpdateId(updates: readonly TelegramUpdate[]): number | undefined;
28
+ export declare class TelegramPersistentGetUpdatesConflictError extends Error {
29
+ readonly count: number;
30
+ constructor(count: number);
31
+ }
32
+ export declare class TelegramGetUpdatesTimeoutError extends Error {
33
+ readonly timeoutMs: number;
34
+ constructor(timeoutMs: number);
35
+ }
36
+ export declare function getTelegramGetUpdatesRequestBudgetMs(body: Record<string, unknown>, graceMs?: number): number;
37
+ export declare function shouldStopTelegramPolling(signalAborted: boolean, error: unknown): boolean;
38
+ export interface TelegramPollingStartState {
39
+ hasBotToken: boolean;
40
+ hasPollingPromise: boolean;
41
+ }
42
+ export type TelegramPollingWorkPhase = "long-poll" | "persisting-journal" | "persisting-offset" | "retrying";
43
+ export type TelegramPollingPhase = "stopped" | "starting" | TelegramPollingWorkPhase;
44
+ export type TelegramPollingStopReason = "not-started" | "requested" | "completed" | "failed" | "persistent-conflict";
45
+ export interface TelegramPollingStateSnapshot {
46
+ phase: TelegramPollingPhase;
47
+ phaseStartedAtMs?: number;
48
+ currentUpdateId?: number;
49
+ startedAtMs?: number;
50
+ stoppedAtMs?: number;
51
+ lastSuccessfulResponseAtMs?: number;
52
+ lastSuccessfulResponseUpdateCount?: number;
53
+ stopReason?: TelegramPollingStopReason;
54
+ }
55
+ export interface TelegramPollingControllerState extends TelegramPollingStateSnapshot {
56
+ pollingPromise?: Promise<void>;
57
+ pollingController?: AbortController;
58
+ }
59
+ export declare function createTelegramPollingControllerState(): TelegramPollingControllerState;
60
+ export declare function getTelegramPollingStateSnapshot(state: TelegramPollingControllerState): TelegramPollingStateSnapshot;
61
+ export declare function createTelegramPollingStateReader(state: TelegramPollingControllerState): () => TelegramPollingStateSnapshot;
62
+ export declare function isTelegramPollingControllerActive(state: TelegramPollingControllerState): boolean;
63
+ export declare function createTelegramPollingActivityReader(state: TelegramPollingControllerState): () => boolean;
64
+ export interface TelegramPollingRuntimeDeps<TContext> extends TelegramRuntimeEventRecorderPort {
65
+ hasBotToken: () => boolean;
66
+ getPollingPromise: () => Promise<void> | undefined;
67
+ setPollingPromise: (promise: Promise<void> | undefined) => void;
68
+ getPollingController: () => AbortController | undefined;
69
+ setPollingController: (controller: AbortController | undefined) => void;
70
+ stopTypingLoop: () => unknown;
71
+ runPollLoop: (ctx: TContext, signal: AbortSignal) => Promise<void>;
72
+ updateStatus: (ctx: TContext, message?: string) => void;
73
+ createAbortController?: () => AbortController;
74
+ getNowMs?: () => number;
75
+ onPollingStateChange?: () => void;
76
+ onPersistentConflict?: (ctx: TContext, count: number) => MaybePromise<void>;
77
+ onPollingStarted?: () => void;
78
+ onPollingStopped?: (reason: TelegramPollingStopReason) => void;
79
+ }
80
+ export type TelegramPollingControllerDeps<TContext> = Omit<TelegramPollingRuntimeDeps<TContext>, "getPollingPromise" | "setPollingPromise" | "getPollingController" | "setPollingController"> & {
81
+ state?: TelegramPollingControllerState;
82
+ };
83
+ export interface TelegramPollingController<TContext> {
84
+ isActive: () => boolean;
85
+ start: (ctx: TContext) => void;
86
+ stop: () => Promise<void>;
87
+ }
88
+ export interface TelegramPollingAdmissionRuntime<TContext> {
89
+ isActive: () => boolean;
90
+ start: (ctx: TContext) => Promise<void>;
91
+ stop: () => Promise<void>;
92
+ }
93
+ export declare function createTelegramPollingAdmissionRuntime<TContext>(deps: {
94
+ polling: TelegramPollingController<TContext>;
95
+ prepareStart?: () => MaybePromise<void>;
96
+ canStart?: (ctx: TContext) => boolean;
97
+ validateStart?: () => void;
98
+ worker: {
99
+ onSessionStart: (ctx: TContext) => Promise<void>;
100
+ };
101
+ }): TelegramPollingAdmissionRuntime<TContext>;
102
+ export interface TelegramDurablePollingRuntimeAssembly<TContext> {
103
+ controller: TelegramPollingController<TContext>;
104
+ admission: TelegramPollingAdmissionRuntime<TContext>;
105
+ }
106
+ export type TelegramDurablePollingRuntimeAssemblyDeps<TUpdate extends TelegramUpdate, TContext> = Omit<TelegramPollingControllerRuntimeDeps<TUpdate, TContext>, "appendUpdateBatch" | "getJournalEntryCount" | "signalUpdateWorker"> & {
107
+ canStart?: (ctx: TContext) => boolean;
108
+ prepareUpdateBatch?: (updates: readonly TUpdate[]) => void;
109
+ journal: {
110
+ appendBatch: (updates: readonly TUpdate[], acceptedThroughUpdateId?: number) => {
111
+ nonExcludedUpdateIds: readonly number[];
112
+ };
113
+ getAcceptedThroughUpdateId: () => number | undefined;
114
+ prepareCursorCutover?: () => MaybePromise<void>;
115
+ getEntryCount: () => number;
116
+ signalWorker: () => void;
117
+ getBootstrapEntryCount: () => number;
118
+ onSessionStart: (ctx: TContext) => Promise<void>;
119
+ };
120
+ };
121
+ /** Own journal-first polling assembly and cursor bootstrap validation. */
122
+ export declare function createTelegramDurablePollingRuntimeAssembly<TUpdate extends TelegramUpdate, TContext>(deps: TelegramDurablePollingRuntimeAssemblyDeps<TUpdate, TContext>): TelegramDurablePollingRuntimeAssembly<TContext>;
123
+ export type TelegramPollingControllerRuntimeDeps<TUpdate extends TelegramUpdate, TContext = unknown> = Omit<TelegramPollLoopRunnerDeps<TUpdate, TContext>, "onPhaseChange" | "onSuccessfulResponse"> & {
124
+ state?: TelegramPollingControllerState;
125
+ hasBotToken: () => boolean;
126
+ stopTypingLoop: () => unknown;
127
+ createAbortController?: () => AbortController;
128
+ getNowMs?: () => number;
129
+ onPollingStateChange?: () => void;
130
+ onPersistentConflict?: (ctx: TContext, count: number) => MaybePromise<void>;
131
+ };
132
+ export declare function createTelegramPollingControllerRuntime<TUpdate extends TelegramUpdate, TContext = unknown>(deps: TelegramPollingControllerRuntimeDeps<TUpdate, TContext>): TelegramPollingController<TContext>;
133
+ export declare function createTelegramPollingController<TContext>(deps: TelegramPollingControllerDeps<TContext>): TelegramPollingController<TContext>;
134
+ export declare function shouldStartTelegramPolling(state: TelegramPollingStartState): boolean;
135
+ export declare function stopTelegramPollingRuntime<TContext>(deps: TelegramPollingRuntimeDeps<TContext>): Promise<void>;
136
+ export declare function startTelegramPollingRuntime<TContext>(ctx: TContext, deps: TelegramPollingRuntimeDeps<TContext>): void;
137
+ export interface TelegramRuntimeEventRecorderPort {
138
+ recordRuntimeEvent?: (category: string, error: unknown, details?: Record<string, unknown>) => void;
139
+ }
140
+ export type TelegramThreadCapabilityMode = "enabled" | "disabled" | "unknown";
141
+ export interface TelegramThreadCapabilityState {
142
+ threadMode?: TelegramThreadCapabilityMode;
143
+ updatedAtMs?: number;
144
+ lastSlot?: string;
145
+ lastReconcileAction?: string;
146
+ }
147
+ export interface TelegramThreadCapabilityRecordView {
148
+ status?: string;
149
+ target?: {
150
+ chatId?: number;
151
+ threadId?: number;
152
+ };
153
+ }
154
+ export interface TelegramThreadCapabilityStore {
155
+ load: () => Promise<void>;
156
+ refresh?: () => Promise<void>;
157
+ persist: () => Promise<void>;
158
+ getBotState: () => TelegramThreadCapabilityState;
159
+ setBotState: (state: TelegramThreadCapabilityState) => void;
160
+ list?: () => TelegramThreadCapabilityRecordView[];
161
+ }
162
+ export interface TelegramThreadCapabilityReaderDeps {
163
+ getAllowedUserId: () => number | undefined;
164
+ callApi: <TResponse>(method: string, body: Record<string, unknown>) => Promise<TResponse>;
165
+ }
166
+ interface TelegramThreadCapabilityLifecycle {
167
+ capture: () => () => boolean;
168
+ invalidate: () => void;
169
+ }
170
+ export interface TelegramStartupThreadCapabilityProbeDeps extends TelegramThreadCapabilityReaderDeps {
171
+ topicTargetStore: TelegramThreadCapabilityStore;
172
+ recordEvent: (category: string, message: unknown, details?: Record<string, unknown>) => void;
173
+ setTopicModeUnavailable: (unavailable: boolean) => void;
174
+ getNowMs?: () => number;
175
+ }
176
+ export interface TelegramThreadCapabilityRuntimeDeps<TContext> extends TelegramThreadCapabilityReaderDeps {
177
+ lifecycle?: TelegramThreadCapabilityLifecycle;
178
+ topicTargetStore: TelegramThreadCapabilityStore;
179
+ ownsLock: (ctx: TContext) => boolean;
180
+ isFollowerRegistered?: () => boolean;
181
+ getPollingStartedWithTelegramBus: () => boolean;
182
+ setPollingStartedWithTelegramBus: (started: boolean) => void;
183
+ setTopicModeUnavailable: (unavailable: boolean) => void;
184
+ suspendLiveThreadTarget?: () => void;
185
+ stopFollowerRegistration: () => void;
186
+ startClassicPolling: (ctx: TContext) => MaybePromise<void>;
187
+ stopClassicPolling: () => MaybePromise<void>;
188
+ startBusPolling: (ctx: TContext) => MaybePromise<void>;
189
+ stopBusPolling: () => MaybePromise<void>;
190
+ startLeaderHealth: () => void;
191
+ stopLeaderHealth: () => void;
192
+ isTopicModeUnavailableError?: (error: unknown) => boolean;
193
+ updateStatus: (ctx: TContext) => void;
194
+ recordEvent: (category: string, message: unknown, details?: Record<string, unknown>) => void;
195
+ getNowMs?: () => number;
196
+ intervalMs?: number;
197
+ }
198
+ export interface TelegramThreadCapabilityMonitor<TContext> {
199
+ start: (ctx: TContext) => void;
200
+ stop: () => void;
201
+ }
202
+ export interface TelegramThreadCapabilityStateRuntime {
203
+ isBusPollingStarted(): boolean;
204
+ setBusPollingStarted(started: boolean): void;
205
+ isTopicModeUnavailable(): boolean;
206
+ setTopicModeUnavailable(unavailable: boolean): void;
207
+ isBusRuntimeEnabled(): boolean;
208
+ shouldForceFreshLeaderThread(): boolean;
209
+ setForceFreshLeaderThread(forceFresh: boolean): void;
210
+ getRequestedThreadName(): string | undefined;
211
+ setRequestedThreadName(threadName: string | undefined): void;
212
+ }
213
+ export type TelegramThreadTargetObservationHandler<TContext> = (ctx: TContext) => Promise<void>;
214
+ export interface TelegramThreadTargetObservationBinding<TContext> {
215
+ handle: TelegramThreadTargetObservationHandler<TContext>;
216
+ set(handler: TelegramThreadTargetObservationHandler<TContext>): void;
217
+ }
218
+ export declare function createTelegramThreadTargetObservationBinding<TContext>(): TelegramThreadTargetObservationBinding<TContext>;
219
+ export interface TelegramThreadAwarePollingPorts<TContext, TOwner> {
220
+ startPolling: (ctx: TContext, options?: {
221
+ forceFreshLeaderThread?: boolean;
222
+ }) => Promise<void>;
223
+ stopPolling: () => Promise<void>;
224
+ registerFollowerWithOwner: (ctx: TContext, owner: TOwner) => Promise<boolean | undefined>;
225
+ restoreFollowerWithOwner: (ctx: TContext, owner: TOwner) => Promise<boolean | undefined>;
226
+ stopFollowerRegistration: () => void;
227
+ }
228
+ export interface TelegramThreadAwarePollingDeps<TContext, TOwner> extends TelegramStartupThreadCapabilityProbeDeps {
229
+ lifecycle?: TelegramThreadCapabilityLifecycle;
230
+ isBusRuntimeEnabled: () => boolean;
231
+ isTopicModeUnavailableError: (error: unknown) => boolean;
232
+ getPollingStartedWithTelegramBus: () => boolean;
233
+ setPollingStartedWithTelegramBus: (started: boolean) => void;
234
+ setForceFreshLeaderThreadOnNextStart: (forceFresh: boolean) => void;
235
+ startClassicPolling: (ctx: TContext) => MaybePromise<void>;
236
+ stopClassicPolling: () => Promise<void>;
237
+ startBusLeaderPolling: (ctx: TContext) => Promise<void>;
238
+ stopBusLeaderPolling: () => Promise<void>;
239
+ startLeaderHealth: () => void;
240
+ stopLeaderHealth: () => void;
241
+ registerFollowerWithLeader: (ctx: TContext, owner: TOwner) => Promise<boolean | undefined>;
242
+ restoreFollowerWithLeader?: (ctx: TContext, owner: TOwner) => Promise<boolean | undefined>;
243
+ hasRememberedWorkspaceBinding?: (ctx: TContext) => boolean;
244
+ stopFollowerRegistration: () => void;
245
+ }
246
+ export interface TelegramThreadCapabilityOrchestrationDeps<TContext, TOwner> extends TelegramThreadCapabilityReaderDeps {
247
+ state: TelegramThreadCapabilityStateRuntime;
248
+ topicTargetStore: TelegramThreadCapabilityStore;
249
+ isBusRuntimeEnabled: () => boolean;
250
+ ownsLock: (ctx: TContext) => boolean;
251
+ isFollowerRegistered?: () => boolean;
252
+ startClassicPolling: (ctx: TContext) => MaybePromise<void>;
253
+ stopClassicPolling: () => Promise<void>;
254
+ startBusLeaderPolling: (ctx: TContext) => Promise<void>;
255
+ stopBusLeaderPolling: () => Promise<void>;
256
+ startLeaderHealth: () => void;
257
+ stopLeaderHealth: () => void;
258
+ registerFollowerWithLeader: (ctx: TContext, owner: TOwner) => Promise<boolean | undefined>;
259
+ restoreFollowerWithLeader?: (ctx: TContext, owner: TOwner) => Promise<boolean | undefined>;
260
+ hasRememberedWorkspaceBinding?: (ctx: TContext) => boolean;
261
+ suspendLiveThreadTarget?: () => void;
262
+ stopFollowerRegistration: () => void;
263
+ isTopicModeUnavailableError: (error: unknown) => boolean;
264
+ updateStatus: (ctx: TContext) => void;
265
+ recordEvent: (category: string, message: unknown, details?: Record<string, unknown>) => void;
266
+ }
267
+ export interface TelegramThreadCapabilityOrchestration<TContext, TOwner> {
268
+ monitor: TelegramThreadCapabilityMonitor<TContext>;
269
+ observeTarget: TelegramThreadTargetObservationHandler<TContext>;
270
+ pollingPorts: TelegramThreadAwarePollingPorts<TContext, TOwner>;
271
+ }
272
+ export declare function createTelegramThreadCapabilityStateRuntime(): TelegramThreadCapabilityStateRuntime;
273
+ export declare function createTelegramThreadCapabilityOrchestration<TContext, TOwner>(deps: TelegramThreadCapabilityOrchestrationDeps<TContext, TOwner>): TelegramThreadCapabilityOrchestration<TContext, TOwner>;
274
+ export declare function readTelegramThreadCapability(deps: TelegramThreadCapabilityReaderDeps): Promise<boolean | undefined>;
275
+ export declare function probeTelegramStartupThreadCapability(deps: TelegramStartupThreadCapabilityProbeDeps, isCurrent?: () => boolean): Promise<boolean | undefined>;
276
+ export declare function applyTelegramThreadCapability<TContext>(ctx: TContext, threadModeEnabled: boolean, phase: string, deps: TelegramThreadCapabilityRuntimeDeps<TContext>, isCurrent?: () => boolean): Promise<void>;
277
+ export declare function createTelegramThreadAwarePollingPorts<TContext, TOwner>(deps: TelegramThreadAwarePollingDeps<TContext, TOwner>): TelegramThreadAwarePollingPorts<TContext, TOwner>;
278
+ export declare function createTelegramThreadTargetObservationHandler<TContext>(deps: TelegramThreadCapabilityRuntimeDeps<TContext>): TelegramThreadTargetObservationHandler<TContext>;
279
+ export declare function canProbeTelegramThreadCapability<TContext>(ctx: TContext, deps: Pick<TelegramThreadCapabilityRuntimeDeps<TContext>, "ownsLock" | "isFollowerRegistered">): boolean;
280
+ export declare function createTelegramThreadCapabilityMonitor<TContext>(deps: TelegramThreadCapabilityRuntimeDeps<TContext>): TelegramThreadCapabilityMonitor<TContext>;
281
+ export declare class TelegramPollingBatchValidationError extends Error {
282
+ constructor(message: string);
283
+ }
284
+ export declare class TelegramPollingCursorBootstrapError extends Error {
285
+ constructor(message: string);
286
+ }
287
+ export interface TelegramPollingCursorCutoverDeps {
288
+ getLegacyCursor: () => number | undefined;
289
+ readJournal: () => {
290
+ acceptedThroughUpdateId?: number;
291
+ entries: readonly {
292
+ updateId: number;
293
+ }[];
294
+ };
295
+ publishJournalCursor: (acceptedThroughUpdateId: number) => MaybePromise<void>;
296
+ removeLegacyCursor: () => MaybePromise<void>;
297
+ }
298
+ /** Transfer one legacy config cursor into journal authority before deleting it. */
299
+ export declare function cutOverTelegramPollingCursor(deps: TelegramPollingCursorCutoverDeps): Promise<void>;
300
+ export interface TelegramPollingBatchAdmissionResult {
301
+ updateCount: number;
302
+ latestUpdateId?: number;
303
+ }
304
+ export interface TelegramPollingBatchAdmissionDeps<TUpdate extends TelegramUpdate> extends TelegramRuntimeEventRecorderPort {
305
+ updates: readonly TUpdate[];
306
+ config: TelegramPollingConfig;
307
+ appendBatch: (updates: readonly TUpdate[], acceptedThroughUpdateId?: number) => MaybePromise<unknown>;
308
+ getAcceptedThroughUpdateId?: () => number | undefined;
309
+ persistConfig: (config: TelegramPollingConfig) => Promise<void>;
310
+ signalWorker: () => void;
311
+ onPhaseChange?: (phase: TelegramPollingWorkPhase, currentUpdateId?: number) => void;
312
+ }
313
+ export declare function admitTelegramPollingUpdateBatch<TUpdate extends TelegramUpdate>(deps: TelegramPollingBatchAdmissionDeps<TUpdate>): Promise<TelegramPollingBatchAdmissionResult>;
314
+ export interface TelegramPollLoopDeps<TUpdate extends TelegramUpdate, TContext = unknown> extends TelegramRuntimeEventRecorderPort {
315
+ ctx: TContext;
316
+ signal: AbortSignal;
317
+ config: TelegramPollingConfig;
318
+ deleteWebhook: (signal: AbortSignal) => Promise<unknown>;
319
+ getUpdates: (body: Record<string, unknown>, signal: AbortSignal) => Promise<TUpdate[]>;
320
+ getUpdatesRequestBudgetMs?: (body: Record<string, unknown>) => number;
321
+ persistConfig: (config: TelegramPollingConfig) => Promise<void>;
322
+ appendUpdateBatch: (updates: readonly TUpdate[], acceptedThroughUpdateId?: number) => MaybePromise<unknown>;
323
+ getAcceptedThroughUpdateId?: () => number | undefined;
324
+ getJournalEntryCount: () => number;
325
+ signalUpdateWorker: () => void;
326
+ onErrorStatus: (message: string) => void;
327
+ onStatusReset: () => void;
328
+ sleep: (ms: number, signal?: AbortSignal) => Promise<void>;
329
+ onPhaseChange?: (phase: TelegramPollingWorkPhase, currentUpdateId?: number) => void;
330
+ onSuccessfulResponse?: (updateCount: number) => void;
331
+ }
332
+ export interface TelegramPollLoopRunnerDeps<TUpdate extends TelegramUpdate, TContext = unknown> extends TelegramRuntimeEventRecorderPort {
333
+ getConfig: () => TelegramPollingConfig;
334
+ deleteWebhook: (signal: AbortSignal) => Promise<unknown>;
335
+ getUpdates: (body: Record<string, unknown>, signal: AbortSignal) => Promise<TUpdate[]>;
336
+ getUpdatesRequestBudgetMs?: (body: Record<string, unknown>) => number;
337
+ persistConfig: (config: TelegramPollingConfig) => Promise<void>;
338
+ appendUpdateBatch: (updates: readonly TUpdate[], acceptedThroughUpdateId?: number) => MaybePromise<unknown>;
339
+ getAcceptedThroughUpdateId?: () => number | undefined;
340
+ getJournalEntryCount: () => number;
341
+ signalUpdateWorker: () => void;
342
+ updateStatus: (ctx: TContext, message?: string) => void;
343
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
344
+ onPhaseChange?: (phase: TelegramPollingWorkPhase, currentUpdateId?: number) => void;
345
+ onSuccessfulResponse?: (updateCount: number) => void;
346
+ }
347
+ export declare function sleepTelegramPollingRetry(ms: number, signal?: AbortSignal): Promise<void>;
348
+ export declare function createTelegramPollLoopRunner<TUpdate extends TelegramUpdate, TContext = unknown>(deps: TelegramPollLoopRunnerDeps<TUpdate, TContext>): (ctx: TContext, signal: AbortSignal) => Promise<void>;
349
+ export declare function isTelegramGetUpdatesConflictError(error: unknown): boolean;
350
+ export declare function runTelegramPollLoop<TUpdate extends TelegramUpdate, TContext = unknown>(deps: TelegramPollLoopDeps<TUpdate, TContext>): Promise<void>;
351
+ export {};