stitchkit 0.103.13 → 0.104.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/darwin-native.cjs +1 -3
  3. package/dist/agent-runtime/store-conformance-lifecycle.d.ts +10 -10
  4. package/dist/agent-runtime/store-conformance-support.d.ts +5 -5
  5. package/dist/application/directory-inbox-accept.d.ts +13 -0
  6. package/dist/application/directory-inbox-accept.d.ts.map +1 -0
  7. package/dist/application/directory-inbox-contract.d.ts +42 -5
  8. package/dist/application/directory-inbox-contract.d.ts.map +1 -1
  9. package/dist/application/directory-inbox-delivery.d.ts +14 -0
  10. package/dist/application/directory-inbox-delivery.d.ts.map +1 -0
  11. package/dist/application/directory-inbox-files.d.ts +28 -0
  12. package/dist/application/directory-inbox-files.d.ts.map +1 -0
  13. package/dist/application/directory-inbox-state.d.ts +14 -0
  14. package/dist/application/directory-inbox-state.d.ts.map +1 -0
  15. package/dist/application/directory-inbox.d.ts +2 -1
  16. package/dist/application/directory-inbox.d.ts.map +1 -1
  17. package/dist/application/file-state-store.d.ts +2 -8
  18. package/dist/application/file-state-store.d.ts.map +1 -1
  19. package/dist/application/state-store.d.ts +6 -1
  20. package/dist/application/state-store.d.ts.map +1 -1
  21. package/dist/browser/client-arguments.d.ts +4 -0
  22. package/dist/browser/client-arguments.d.ts.map +1 -0
  23. package/dist/browser/client-executors.d.ts.map +1 -1
  24. package/dist/browser/client.d.ts.map +1 -1
  25. package/dist/browser/contract-stream.d.ts.map +1 -1
  26. package/dist/browser/http.d.ts +2 -1
  27. package/dist/browser/http.d.ts.map +1 -1
  28. package/dist/browser/native-fetch.d.ts +8 -0
  29. package/dist/browser/native-fetch.d.ts.map +1 -0
  30. package/dist/contract/errors.d.ts +16 -12
  31. package/dist/contract/errors.d.ts.map +1 -1
  32. package/dist/contract/normalize.d.ts +5 -1
  33. package/dist/contract/normalize.d.ts.map +1 -1
  34. package/dist/contract/stream.d.ts +1 -0
  35. package/dist/contract/stream.d.ts.map +1 -1
  36. package/dist/entrypoints/agent-runtime/browser.js +3 -3
  37. package/dist/entrypoints/agent-runtime/coding-tools.js +6 -6
  38. package/dist/entrypoints/agent-runtime/harness-tools.js +8 -8
  39. package/dist/entrypoints/agent-runtime/harness.js +11 -11
  40. package/dist/entrypoints/agent-runtime/realtime.js +3 -3
  41. package/dist/entrypoints/agent-runtime/sandbox.js +6 -6
  42. package/dist/entrypoints/agent-runtime.js +13 -13
  43. package/dist/entrypoints/application/diagnostic-journal.js +1 -1
  44. package/dist/entrypoints/application/directory-inbox.js +424 -119
  45. package/dist/entrypoints/application/grammy.js +1 -1
  46. package/dist/entrypoints/application.d.ts +2 -2
  47. package/dist/entrypoints/application.d.ts.map +1 -1
  48. package/dist/entrypoints/application.js +7 -3
  49. package/dist/entrypoints/cli.d.ts +2 -0
  50. package/dist/entrypoints/cli.d.ts.map +1 -1
  51. package/dist/entrypoints/cli.js +757 -136
  52. package/dist/entrypoints/contract.js +3 -3
  53. package/dist/entrypoints/files/packaging.d.ts +3 -0
  54. package/dist/entrypoints/files/packaging.d.ts.map +1 -0
  55. package/dist/entrypoints/files/packaging.js +133 -0
  56. package/dist/entrypoints/files.js +10 -107
  57. package/dist/entrypoints/index.js +7 -7
  58. package/dist/entrypoints/node.js +8 -8
  59. package/dist/entrypoints/observability.js +2 -2
  60. package/dist/entrypoints/react.js +1 -1
  61. package/dist/entrypoints/remote.js +19 -6
  62. package/dist/entrypoints/server.d.ts +1 -1
  63. package/dist/entrypoints/server.d.ts.map +1 -1
  64. package/dist/entrypoints/server.js +23 -17
  65. package/dist/entrypoints/telegram.d.ts +1 -0
  66. package/dist/entrypoints/telegram.d.ts.map +1 -1
  67. package/dist/entrypoints/telegram.js +214 -98
  68. package/dist/entrypoints/testing.js +7 -7
  69. package/dist/entrypoints/tools/connections.d.ts +2 -2
  70. package/dist/entrypoints/tools/connections.d.ts.map +1 -1
  71. package/dist/entrypoints/tools/connections.js +427 -294
  72. package/dist/entrypoints/tools/invoker.js +6 -6
  73. package/dist/entrypoints/tools/mcp.d.ts +12 -0
  74. package/dist/entrypoints/tools/mcp.d.ts.map +1 -0
  75. package/dist/entrypoints/tools/mcp.js +45 -0
  76. package/dist/entrypoints/tools.d.ts +1 -0
  77. package/dist/entrypoints/tools.d.ts.map +1 -1
  78. package/dist/entrypoints/tools.js +82 -1147
  79. package/dist/entrypoints/tracking.js +1 -1
  80. package/dist/files/boundary.d.ts +2 -8
  81. package/dist/files/boundary.d.ts.map +1 -1
  82. package/dist/files/file-io.d.ts +0 -5
  83. package/dist/files/file-io.d.ts.map +1 -1
  84. package/dist/files/native-packaging-layout.d.ts +12 -0
  85. package/dist/files/native-packaging-layout.d.ts.map +1 -0
  86. package/dist/files/native-packaging.d.ts +72 -0
  87. package/dist/files/native-packaging.d.ts.map +1 -0
  88. package/dist/files/read.d.ts +2 -2
  89. package/dist/files/read.d.ts.map +1 -1
  90. package/dist/index-1a6jtnd9.js +88 -0
  91. package/dist/index-269zqj8m.js +77 -0
  92. package/dist/{index-r34mvse1.js → index-27a2pj09.js} +1 -1
  93. package/dist/{index-r956rndn.js → index-2hyavjjj.js} +3 -3
  94. package/dist/{index-m2xqkv55.js → index-2vnh05w4.js} +83 -14
  95. package/dist/{index-pw99k9h5.js → index-43p08g7t.js} +1 -1
  96. package/dist/{index-xwq9j1sf.js → index-4e0ah203.js} +9 -7
  97. package/dist/{index-qapzv4p5.js → index-5z6jn897.js} +1 -1
  98. package/dist/{index-ahvsksw5.js → index-6d9xaxw1.js} +1 -1
  99. package/dist/{index-8zfsgar0.js → index-6drst9sg.js} +11 -5
  100. package/dist/{index-x87j7csh.js → index-77nxk6ay.js} +2 -2
  101. package/dist/{index-dnn9z96q.js → index-a0zzh8ak.js} +3 -3
  102. package/dist/{index-kmpzj1cq.js → index-a3wma1hk.js} +1 -1
  103. package/dist/{index-j8aw2c0e.js → index-bakgedh8.js} +35 -7
  104. package/dist/index-bhb950qs.js +1145 -0
  105. package/dist/{index-tgzhq07n.js → index-cvda079a.js} +1 -1
  106. package/dist/{index-n2gre124.js → index-fa4wg312.js} +4 -4
  107. package/dist/{index-zp4jpkp0.js → index-fk18k56k.js} +2 -2
  108. package/dist/{index-afjvjyck.js → index-g2j7pnak.js} +2 -134
  109. package/dist/index-g95fk660.js +116 -0
  110. package/dist/{index-r5c4fedv.js → index-h2fhjqy7.js} +2 -1
  111. package/dist/{index-sybedc8b.js → index-hbd32c6a.js} +23 -94
  112. package/dist/{index-fyphpknh.js → index-hp9d77wk.js} +1 -1
  113. package/dist/index-jd470k6q.js +109 -0
  114. package/dist/{index-b2bz0kdm.js → index-kb8styz3.js} +4 -3
  115. package/dist/{index-0c419yx7.js → index-kemm0ej5.js} +12 -9
  116. package/dist/{index-db2spkv1.js → index-ptn0g0gj.js} +3 -3
  117. package/dist/{index-w575evhq.js → index-r4r70zmh.js} +1 -1
  118. package/dist/{index-12m2v2a9.js → index-s4evrmp5.js} +1 -1
  119. package/dist/{index-1khy8y7n.js → index-t1sr4aks.js} +3 -3
  120. package/dist/{index-45tdvqa3.js → index-wh0ecvyk.js} +1 -1
  121. package/dist/{index-n53mswt3.js → index-x928baz2.js} +8 -1
  122. package/dist/index-yk4g8805.js +133 -0
  123. package/dist/{index-ygkka6zn.js → index-ywppsaby.js} +28 -5
  124. package/dist/{index-9853ymwb.js → index-za6j7nwy.js} +18 -4
  125. package/dist/internal/bounded-file-read.d.ts +41 -0
  126. package/dist/internal/bounded-file-read.d.ts.map +1 -0
  127. package/dist/internal/exclusive-lock.d.ts +2 -0
  128. package/dist/internal/exclusive-lock.d.ts.map +1 -1
  129. package/dist/internal/with-exclusive-lock.d.ts +4 -2
  130. package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
  131. package/dist/telegram/broadcast-delivery.d.ts +23 -0
  132. package/dist/telegram/broadcast-delivery.d.ts.map +1 -0
  133. package/dist/telegram/broadcast-failure.d.ts +22 -0
  134. package/dist/telegram/broadcast-failure.d.ts.map +1 -0
  135. package/dist/telegram/broadcast-state.d.ts +6 -3
  136. package/dist/telegram/broadcast-state.d.ts.map +1 -1
  137. package/dist/telegram/broadcast.d.ts +10 -5
  138. package/dist/telegram/broadcast.d.ts.map +1 -1
  139. package/dist/tools/cli/format.d.ts.map +1 -1
  140. package/dist/tools/cli/invoke.d.ts +2 -2
  141. package/dist/tools/cli/invoke.d.ts.map +1 -1
  142. package/dist/tools/cli/publication-assets.d.ts +10 -0
  143. package/dist/tools/cli/publication-assets.d.ts.map +1 -0
  144. package/dist/tools/cli/publication-contract.d.ts +75 -0
  145. package/dist/tools/cli/publication-contract.d.ts.map +1 -0
  146. package/dist/tools/cli/publication-control.d.ts +4 -0
  147. package/dist/tools/cli/publication-control.d.ts.map +1 -0
  148. package/dist/tools/cli/publication-storage.d.ts +32 -0
  149. package/dist/tools/cli/publication-storage.d.ts.map +1 -0
  150. package/dist/tools/cli/publication.d.ts +35 -0
  151. package/dist/tools/cli/publication.d.ts.map +1 -0
  152. package/dist/tools/cli/update.d.ts.map +1 -1
  153. package/dist/tools/connections/define.d.ts.map +1 -1
  154. package/dist/tools/connections/error-projection.d.ts +4 -0
  155. package/dist/tools/connections/error-projection.d.ts.map +1 -0
  156. package/dist/tools/connections/errors.d.ts +24 -8
  157. package/dist/tools/connections/errors.d.ts.map +1 -1
  158. package/dist/tools/connections/limits.d.ts +11 -31
  159. package/dist/tools/connections/limits.d.ts.map +1 -1
  160. package/dist/tools/connections/mcp-client.d.ts +6 -4
  161. package/dist/tools/connections/mcp-client.d.ts.map +1 -1
  162. package/dist/tools/connections/mcp.d.ts.map +1 -1
  163. package/dist/tools/connections/openapi.d.ts.map +1 -1
  164. package/dist/tools/connections/operation-limits.d.ts +25 -0
  165. package/dist/tools/connections/operation-limits.d.ts.map +1 -0
  166. package/dist/tools/connections/sse-frames.d.ts +11 -2
  167. package/dist/tools/connections/sse-frames.d.ts.map +1 -1
  168. package/dist/tools/connections/sse-session.d.ts +15 -2
  169. package/dist/tools/connections/sse-session.d.ts.map +1 -1
  170. package/dist/tools/connections/types.d.ts +19 -1
  171. package/dist/tools/connections/types.d.ts.map +1 -1
  172. package/dist/tools/execute-result.d.ts.map +1 -1
  173. package/dist/tools/execute.d.ts.map +1 -1
  174. package/dist/tools/internal/observe-hook.d.ts +3 -0
  175. package/dist/tools/internal/observe-hook.d.ts.map +1 -0
  176. package/dist/tools/internal/surface-projector.d.ts +2 -1
  177. package/dist/tools/internal/surface-projector.d.ts.map +1 -1
  178. package/dist/tools/mcp/mount.d.ts +2 -2
  179. package/dist/tools/mcp/mount.d.ts.map +1 -1
  180. package/dist/tools/mcp/prepare.d.ts +4 -5
  181. package/dist/tools/mcp/prepare.d.ts.map +1 -1
  182. package/dist/tools/mcp/register.d.ts +4 -1
  183. package/dist/tools/mcp/register.d.ts.map +1 -1
  184. package/dist/tools/mcp/runtime-tools.d.ts.map +1 -1
  185. package/dist/tools/remote.d.ts.map +1 -1
  186. package/dist/tools/runtime-tool-execution.d.ts +65 -0
  187. package/dist/tools/runtime-tool-execution.d.ts.map +1 -0
  188. package/dist/tools/runtime-tool-mcp.d.ts +27 -0
  189. package/dist/tools/runtime-tool-mcp.d.ts.map +1 -0
  190. package/dist/tools/runtime-tool.d.ts +9 -60
  191. package/dist/tools/runtime-tool.d.ts.map +1 -1
  192. package/dist/tools/surface.d.ts +12 -14
  193. package/dist/tools/surface.d.ts.map +1 -1
  194. package/llms/application.2.txt +221 -44
  195. package/llms/application.3.txt +3 -1
  196. package/llms/application.txt +1 -1
  197. package/llms/cli.2.txt +144 -1
  198. package/llms/cli.txt +123 -104
  199. package/llms/contract.txt +1 -1
  200. package/llms/files-packaging.txt +27 -0
  201. package/llms/process.txt +63 -1
  202. package/llms/server.4.txt +4 -1
  203. package/llms/server.5.txt +1 -0
  204. package/llms/stitchkit.2.txt +14 -0
  205. package/llms/stitchkit.txt +6 -4
  206. package/llms/telegram.txt +64 -2
  207. package/llms/tools-connections.txt +3 -0
  208. package/llms/tools-mcp.txt +29 -0
  209. package/llms/tools.2.txt +59 -0
  210. package/llms/tools.3.txt +1 -0
  211. package/llms/tools.txt +11 -52
  212. package/llms/upgrading-0.37.0-0.44.0.txt +444 -0
  213. package/llms/{upgrading-0.44.0-0.60.0.txt → upgrading-0.44.0-0.61.0.txt} +140 -271
  214. package/llms/{upgrading-0.61.0-0.74.0.txt → upgrading-0.62.0-0.80.0.txt} +217 -140
  215. package/llms/{upgrading-0.75.0-0.103.0.txt → upgrading-0.81.0-0.104.0.txt} +154 -217
  216. package/llms/upgrading.txt +4 -4
  217. package/llms-full.txt +745 -60
  218. package/llms.txt +14 -12
  219. package/native-assets.json +8 -0
  220. package/package.json +12 -3
  221. package/dist/index-wykebpn9.js +0 -221
  222. package/llms/upgrading-0.37.0.txt +0 -176
  223. package/dist/{index-69nvze1q.js → index-pptyv13k.js} +3 -3
@@ -5,10 +5,21 @@ import {
5
5
  TELEGRAM_SEND_FAILURE_REASONS2,
6
6
  classifyTelegramSendFailure2
7
7
  } from "../index-e05cjgtf.js";
8
+ import {
9
+ attemptExclusiveLock
10
+ } from "../index-za6j7nwy.js";
11
+ import"../index-5csmzesf.js";
12
+ import"../index-v5ee8ath.js";
8
13
  import {
9
14
  TELEGRAM_TEXT_LIMIT2,
10
15
  truncateTelegramHtml2
11
16
  } from "../index-nmaqxdx7.js";
17
+ import {
18
+ writeFileAtomic2
19
+ } from "../index-s4evrmp5.js";
20
+ import {
21
+ raceAbort
22
+ } from "../index-mbnnw3f2.js";
12
23
  import {
13
24
  isRecord,
14
25
  transportResult
@@ -80,24 +91,156 @@ async function callTelegramBotApi(call) {
80
91
  }
81
92
  });
82
93
  }
94
+ // src/telegram/broadcast-delivery.ts
95
+ import { z as z2 } from "zod";
96
+
97
+ // src/telegram/broadcast-failure.ts
98
+ import { z } from "zod";
99
+ var reason = z.string().max(64).optional();
100
+ var TelegramBroadcastFailureSchema = z.discriminatedUnion("kind", [
101
+ z.object({
102
+ kind: z.literal("retry-after"),
103
+ retryAfterMs: z.int().nonnegative().max(2147483647),
104
+ reason
105
+ }).strict(),
106
+ z.object({ kind: z.literal("transient"), reason }).strict(),
107
+ z.object({
108
+ kind: z.literal("permanent"),
109
+ recipientUnreachable: z.boolean().optional(),
110
+ stopBroadcast: z.boolean().optional(),
111
+ reason
112
+ }).strict(),
113
+ z.object({ kind: z.literal("ambiguous"), reason }).strict()
114
+ ]);
115
+ function classifyBotBroadcastFailure(error) {
116
+ const failure = classifyTelegramSendFailure2(error);
117
+ if (failure.recipientUnreachable)
118
+ return { kind: "permanent", recipientUnreachable: true, reason: failure.reason };
119
+ if (failure.reason === "message-invalid")
120
+ return { kind: "permanent", stopBroadcast: true, reason: failure.reason };
121
+ if (failure.retryAfterSeconds !== undefined)
122
+ return {
123
+ kind: "retry-after",
124
+ retryAfterMs: failure.retryAfterSeconds * 1000,
125
+ reason: failure.reason
126
+ };
127
+ if (failure.retryable)
128
+ return { kind: "transient", reason: failure.reason };
129
+ if (failure.reason === "unknown" && failure.status === undefined)
130
+ return { kind: "ambiguous", reason: failure.reason };
131
+ return { kind: "permanent", reason: failure.reason };
132
+ }
133
+
134
+ // src/telegram/broadcast-delivery.ts
135
+ function pause(milliseconds, signal) {
136
+ return new Promise((resolve) => {
137
+ const done = () => {
138
+ clearTimeout(timer);
139
+ signal?.removeEventListener("abort", done);
140
+ resolve();
141
+ };
142
+ const timer = setTimeout(done, milliseconds);
143
+ signal?.addEventListener("abort", done, { once: true });
144
+ if (signal?.aborted)
145
+ done();
146
+ });
147
+ }
148
+ function broadcastLimits(config) {
149
+ const rate = z2.number().positive().min(1000 / 2147483647).parse(config.ratePerSecond ?? 25);
150
+ return {
151
+ intervalMs: 1000 / rate,
152
+ maxAttempts: z2.int().min(1).max(100).parse(config.maxAttempts ?? 5),
153
+ maxRetryDelayMs: z2.int().nonnegative().max(2147483647).parse(config.maxRetryDelayMs ?? 60000),
154
+ progressEveryMs: z2.int().nonnegative().max(2147483647).parse(config.progressEveryMs ?? 1e4)
155
+ };
156
+ }
157
+ function broadcastDelivery(config, limits, assertHeld) {
158
+ const sleep = config.sleep ?? pause;
159
+ const now = config.now ?? Date.now;
160
+ const classify = config.classify ?? classifyBotBroadcastFailure;
161
+ let lastSendAt = Number.NEGATIVE_INFINITY;
162
+ const wait = async (milliseconds) => {
163
+ if (config.signal?.aborted)
164
+ return false;
165
+ if (milliseconds > 0) {
166
+ try {
167
+ const pending = sleep(milliseconds, config.signal);
168
+ if (config.signal)
169
+ await raceAbort(pending, config.signal);
170
+ else
171
+ await pending;
172
+ } catch (error) {
173
+ if (config.signal?.aborted)
174
+ return false;
175
+ throw error;
176
+ }
177
+ }
178
+ return !config.signal?.aborted;
179
+ };
180
+ return async (recipient) => {
181
+ for (let attempt = 1;attempt <= limits.maxAttempts; attempt += 1) {
182
+ if (!await wait(lastSendAt + limits.intervalMs - now()))
183
+ return { kind: "stopped" };
184
+ await assertHeld();
185
+ if (config.signal?.aborted)
186
+ return { kind: "stopped" };
187
+ lastSendAt = now();
188
+ try {
189
+ await config.send({ recipient, attempt });
190
+ return { kind: "settled", outcome: "delivered" };
191
+ } catch (error) {
192
+ const failure = TelegramBroadcastFailureSchema.parse(classify(error));
193
+ if (failure.kind === "ambiguous")
194
+ return {
195
+ kind: "settled",
196
+ outcome: "uncertain",
197
+ ...failure.reason && { reason: failure.reason },
198
+ halt: failure
199
+ };
200
+ if (failure.kind === "permanent") {
201
+ if (failure.stopBroadcast)
202
+ return { kind: "halted", failure };
203
+ return {
204
+ kind: "settled",
205
+ outcome: failure.recipientUnreachable ? "unreachable" : "failed",
206
+ ...failure.reason && { reason: failure.reason }
207
+ };
208
+ }
209
+ const delay = failure.kind === "retry-after" ? failure.retryAfterMs : Math.min(60000, 1000 * 2 ** (attempt - 1));
210
+ if (delay > limits.maxRetryDelayMs)
211
+ return { kind: "halted", failure };
212
+ if (attempt >= limits.maxAttempts)
213
+ return {
214
+ kind: "settled",
215
+ outcome: "failed",
216
+ ...failure.reason && { reason: failure.reason }
217
+ };
218
+ if (!await wait(delay))
219
+ return { kind: "stopped" };
220
+ }
221
+ }
222
+ throw new Error("Broadcast retry budget produced no outcome");
223
+ };
224
+ }
225
+
83
226
  // src/telegram/broadcast-state.ts
84
- import { appendFile, mkdir, open, readFile, rename, rm, writeFile } from "node:fs/promises";
227
+ import { mkdir, open, readFile } from "node:fs/promises";
85
228
  import { join } from "node:path";
86
- import { z } from "zod";
87
- var TelegramBroadcastOutcomeSchema = z.enum([
229
+ import { z as z3 } from "zod";
230
+ var TelegramBroadcastOutcomeSchema = z3.enum([
88
231
  "delivered",
89
232
  "unreachable",
90
233
  "failed",
91
234
  "uncertain"
92
235
  ]);
93
- var ChatIdSchema = z.union([z.number().int(), z.string().min(1).max(64)]);
94
- var RecipientsSchema = z.array(ChatIdSchema);
95
- var JournalLineSchema = z.union([
96
- z.object({ i: z.number().int().nonnegative(), s: z.enum(["sending", "released"]) }).strict(),
97
- z.object({
98
- i: z.number().int().nonnegative(),
236
+ var ChatIdSchema = z3.union([z3.number().int(), z3.string().min(1).max(64)]);
237
+ var RecipientsSchema = z3.array(ChatIdSchema);
238
+ var JournalLineSchema = z3.union([
239
+ z3.object({ i: z3.number().int().nonnegative(), s: z3.enum(["sending", "released"]) }).strict(),
240
+ z3.object({
241
+ i: z3.number().int().nonnegative(),
99
242
  o: TelegramBroadcastOutcomeSchema,
100
- r: z.string().max(64).optional()
243
+ r: z3.string().max(64).optional()
101
244
  }).strict()
102
245
  ]);
103
246
  var NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
@@ -123,10 +266,21 @@ async function readRecipients(files) {
123
266
  throw error;
124
267
  }
125
268
  }
126
- async function writeRecipients(files, recipients) {
127
- const temporary = `${files.recipients}.${process.pid}.tmp`;
128
- await writeFile(temporary, JSON.stringify(recipients));
129
- await rename(temporary, files.recipients);
269
+ async function writeRecipients(files, recipients, lock) {
270
+ await lock.assertHeld();
271
+ await writeFileAtomic2(files.recipients, JSON.stringify(recipients), {
272
+ replace: false,
273
+ durability: "directory"
274
+ });
275
+ }
276
+ async function prepareJournal(files, lock) {
277
+ await lock.assertHeld();
278
+ try {
279
+ await writeFileAtomic2(files.journal, "", { replace: false, durability: "directory" });
280
+ } catch (error) {
281
+ if (!(error instanceof Error && ("code" in error) && error.code === "EEXIST"))
282
+ throw error;
283
+ }
130
284
  }
131
285
  async function readProgress(files) {
132
286
  const progress = new Map;
@@ -157,43 +311,33 @@ async function readProgress(files) {
157
311
  }
158
312
  return progress;
159
313
  }
160
- function appendJournal(files, line) {
161
- return appendFile(files.journal, `${JSON.stringify(line)}
162
- `);
163
- }
164
- function alive(pid) {
314
+ async function appendJournal(files, line, lock) {
315
+ await lock.assertHeld();
316
+ const handle = await open(files.journal, "a", 384);
165
317
  try {
166
- process.kill(pid, 0);
167
- return true;
168
- } catch (error) {
169
- return error instanceof Error && "code" in error && error.code === "EPERM";
318
+ await lock.assertHeld();
319
+ await handle.writeFile(`${JSON.stringify(line)}
320
+ `);
321
+ await handle.sync();
322
+ } finally {
323
+ await handle.close();
170
324
  }
171
325
  }
172
326
  async function lockBroadcast(directory, files) {
173
327
  await mkdir(directory, { recursive: true });
174
- for (let attempt = 0;attempt < 2; attempt += 1) {
175
- try {
176
- const handle = await open(files.lock, "wx");
177
- await handle.writeFile(String(process.pid));
178
- await handle.close();
179
- return () => rm(files.lock, { force: true });
180
- } catch (error) {
181
- if (!(error instanceof Error && ("code" in error) && error.code === "EEXIST"))
182
- throw error;
183
- const owner = Number.parseInt(await readFile(files.lock, "utf8").catch(() => ""), 10);
184
- if (Number.isInteger(owner) && owner > 0 && alive(owner)) {
185
- throw new Error("Telegram broadcast is already running in another process");
186
- }
187
- await rm(files.lock, { force: true });
188
- }
189
- }
190
- throw new Error("Telegram broadcast lock could not be taken");
328
+ const attempt = await attemptExclusiveLock(files.lock, {
329
+ mode: 384,
330
+ reclaim: true,
331
+ ownerlessGraceMs: null
332
+ });
333
+ if ("held" in attempt)
334
+ return attempt.held;
335
+ throw new Error("Telegram broadcast is already running or its lock owner is unknown", {
336
+ cause: attempt.diagnosis?.cause ?? attempt.error
337
+ });
191
338
  }
192
339
 
193
340
  // src/telegram/broadcast.ts
194
- function pause(milliseconds) {
195
- return new Promise((resolve) => setTimeout(resolve, milliseconds));
196
- }
197
341
  function tally(name, total, progress, outcome, halt) {
198
342
  const counts = { delivered: 0, unreachable: 0, failed: 0, uncertain: 0 };
199
343
  for (const state of progress.values())
@@ -223,9 +367,7 @@ async function audience(config) {
223
367
  async function runTelegramBroadcast(config) {
224
368
  assertBroadcastName(config.name);
225
369
  const files = broadcastFiles(config.directory, config.name);
226
- const intervalMs = 1000 / (config.ratePerSecond ?? 25);
227
- const maxAttempts = config.maxAttempts ?? 5;
228
- const sleep = config.sleep ?? pause;
370
+ const limits = broadcastLimits(config);
229
371
  const now = config.now ?? Date.now;
230
372
  let recipients = [];
231
373
  let progress = new Map;
@@ -235,20 +377,22 @@ async function runTelegramBroadcast(config) {
235
377
  progress = await readProgress(files);
236
378
  return report("dry-run");
237
379
  }
238
- const unlock = await lockBroadcast(config.directory, files);
380
+ const lock = await lockBroadcast(config.directory, files);
381
+ const deliver = broadcastDelivery(config, limits, () => lock.assertHeld());
239
382
  try {
240
383
  const snapshot = await readRecipients(files);
241
384
  if (snapshot)
242
385
  recipients = snapshot;
243
386
  else {
244
387
  recipients = await audience(config);
245
- await writeRecipients(files, recipients);
388
+ await writeRecipients(files, recipients, lock);
246
389
  }
390
+ await prepareJournal(files, lock);
247
391
  progress = await readProgress(files);
248
392
  for (const [index, state] of progress) {
249
393
  if (state !== "sending")
250
394
  continue;
251
- await appendJournal(files, { i: index, o: "uncertain" });
395
+ await appendJournal(files, { i: index, o: "uncertain" }, lock);
252
396
  progress.set(index, "uncertain");
253
397
  }
254
398
  const emit = (value) => {
@@ -259,37 +403,6 @@ async function runTelegramBroadcast(config) {
259
403
  };
260
404
  emit(report("running"));
261
405
  let lastProgressAt = now();
262
- let lastSendAt = Number.NEGATIVE_INFINITY;
263
- let halted;
264
- const halt = (failure) => {
265
- halted = failure;
266
- return "halt";
267
- };
268
- const deliver = async (recipient) => {
269
- for (let attempt = 1;; attempt += 1) {
270
- const wait = lastSendAt + intervalMs - now();
271
- if (wait > 0)
272
- await sleep(wait);
273
- lastSendAt = now();
274
- try {
275
- await config.send({ recipient, attempt });
276
- return { outcome: "delivered" };
277
- } catch (error) {
278
- const failure = classifyTelegramSendFailure2(error);
279
- if (failure.recipientUnreachable)
280
- return { outcome: "unreachable", reason: failure.reason };
281
- if (failure.reason === "message-invalid")
282
- return halt(failure);
283
- const transport = failure.reason === "unknown" && failure.status === undefined;
284
- if (!failure.retryable && !transport)
285
- return { outcome: "failed", reason: failure.reason };
286
- if (attempt >= maxAttempts) {
287
- return transport ? halt(failure) : { outcome: "failed", reason: failure.reason };
288
- }
289
- await sleep(failure.retryAfterSeconds !== undefined ? failure.retryAfterSeconds * 1000 : Math.min(60000, 1000 * 2 ** (attempt - 1)));
290
- }
291
- }
292
- };
293
406
  for (let index = 0;index < recipients.length; index += 1) {
294
407
  if (progress.has(index))
295
408
  continue;
@@ -298,26 +411,28 @@ async function runTelegramBroadcast(config) {
298
411
  const recipient = recipients[index];
299
412
  if (recipient === undefined)
300
413
  continue;
301
- await appendJournal(files, { i: index, s: "sending" });
414
+ await appendJournal(files, { i: index, s: "sending" }, lock);
302
415
  const result = await deliver(recipient);
303
- if (result === "halt") {
304
- await appendJournal(files, { i: index, s: "released" });
305
- return emit(report("halted", halted));
416
+ if (result.kind !== "settled") {
417
+ await appendJournal(files, { i: index, s: "released" }, lock);
418
+ return emit(result.kind === "stopped" ? report("stopped") : report("halted", result.failure));
306
419
  }
307
420
  await appendJournal(files, {
308
421
  i: index,
309
422
  o: result.outcome,
310
423
  ...result.reason && { r: result.reason }
311
- });
424
+ }, lock);
312
425
  progress.set(index, result.outcome);
313
- if (now() - lastProgressAt >= (config.progressEveryMs ?? 1e4)) {
426
+ if (result.halt)
427
+ return emit(report("halted", result.halt));
428
+ if (now() - lastProgressAt >= limits.progressEveryMs) {
314
429
  lastProgressAt = now();
315
430
  emit(report("running"));
316
431
  }
317
432
  }
318
433
  return emit(report("finished"));
319
434
  } finally {
320
- await unlock();
435
+ await lock.release();
321
436
  }
322
437
  }
323
438
  function telegramBroadcastSender(config) {
@@ -363,17 +478,17 @@ function digestsEqual(a, b) {
363
478
  }
364
479
 
365
480
  // src/telegram/user.ts
366
- import { z as z2 } from "zod";
367
- var TelegramUserSchema = z2.object({
368
- id: z2.int(),
369
- is_bot: z2.boolean().optional(),
370
- first_name: z2.string(),
371
- last_name: z2.string().optional(),
372
- username: z2.string().optional(),
373
- language_code: z2.string().optional(),
374
- is_premium: z2.boolean().optional(),
375
- allows_write_to_pm: z2.boolean().optional(),
376
- photo_url: z2.string().optional()
481
+ import { z as z4 } from "zod";
482
+ var TelegramUserSchema = z4.object({
483
+ id: z4.int(),
484
+ is_bot: z4.boolean().optional(),
485
+ first_name: z4.string(),
486
+ last_name: z4.string().optional(),
487
+ username: z4.string().optional(),
488
+ language_code: z4.string().optional(),
489
+ is_premium: z4.boolean().optional(),
490
+ allows_write_to_pm: z4.boolean().optional(),
491
+ photo_url: z4.string().optional()
377
492
  }).transform((user) => ({
378
493
  id: user.id,
379
494
  firstName: user.first_name,
@@ -1423,6 +1538,7 @@ export {
1423
1538
  TELEGRAM_SEND_FAILURE_REASONS2 as TELEGRAM_SEND_FAILURE_REASONS,
1424
1539
  TELEGRAM_WEBHOOK_NONE,
1425
1540
  TelegramBotApiError,
1541
+ TelegramBroadcastFailureSchema,
1426
1542
  TelegramLocalFileError,
1427
1543
  TelegramWebhookClaimError,
1428
1544
  callTelegramBotApi,
@@ -1,18 +1,18 @@
1
1
  import"../index-yex7eg1v.js";
2
- import"../index-ygkka6zn.js";
2
+ import"../index-ywppsaby.js";
3
3
  import {
4
4
  joinRoutePath
5
5
  } from "../index-m38ej7e5.js";
6
- import"../index-r5c4fedv.js";
6
+ import"../index-h2fhjqy7.js";
7
7
  import {
8
8
  createClient2,
9
9
  createClients2
10
- } from "../index-0c419yx7.js";
11
- import"../index-n53mswt3.js";
10
+ } from "../index-kemm0ej5.js";
11
+ import"../index-x928baz2.js";
12
12
  import"../index-q0th8q0z.js";
13
13
  import {
14
14
  createApplication2
15
- } from "../index-w575evhq.js";
15
+ } from "../index-r4r70zmh.js";
16
16
  import"../index-w5s3xftz.js";
17
17
  import {
18
18
  RealtimeRequestTimeoutError2,
@@ -36,8 +36,8 @@ import {
36
36
  projectToolSurface,
37
37
  mcpProjectionCandidate,
38
38
  prepareProjectedMcpTools
39
- } from "../index-x87j7csh.js";
40
- import"../index-b2bz0kdm.js";
39
+ } from "../index-77nxk6ay.js";
40
+ import"../index-kb8styz3.js";
41
41
  import {
42
42
  compareCodeUnits,
43
43
  serializeCanonicalJson
@@ -12,8 +12,8 @@
12
12
  * explicit `allowHosts`), and credentials are resolved separately for each call.
13
13
  */
14
14
  export { defineMcpClientConnection, defineOpenApiConnection, } from '../../tools/connections/define.js';
15
- export { ConnectionAuthorizationRequiredError, ConnectionBudgetExceededError, ConnectionRequestError, ConnectionUrlError, } from '../../tools/connections/errors.js';
15
+ export { ConnectionAuthorizationRequiredError, ConnectionBudgetExceededError, type ConnectionFailureContext, ConnectionRequestError, ConnectionResponseTooLargeError, ConnectionTimeoutError, ConnectionUrlError, } from '../../tools/connections/errors.js';
16
16
  export { mountConnections } from '../../tools/connections/mount.js';
17
17
  export type { ConnectionTokenProvider, ConnectionToolSkipReporter, SkippedConnectionTool, } from '../../tools/connections/runtime.js';
18
- export type { ConnectionBudget, ConnectionDefinition, ConnectionMountOptions, McpClientConnection, McpClientConnectionConfig, McpConnectionTransport, McpToolFilter, OpenApiConnection, OpenApiConnectionConfig, } from '../../tools/connections/types.js';
18
+ export type { ConnectionBudget, ConnectionDefinition, ConnectionMountOptions, ConnectionOperation, ConnectionOperationLimits, ConnectionPhase, McpClientConnection, McpClientConnectionConfig, McpConnectionLimits, McpConnectionTransport, McpToolFilter, OpenApiConnection, OpenApiConnectionConfig, } from '../../tools/connections/types.js';
19
19
  //# sourceMappingURL=connections.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../../../src/entrypoints/tools/connections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EACV,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../../../src/entrypoints/tools/connections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,KAAK,wBAAwB,EAC7B,sBAAsB,EACtB,+BAA+B,EAC/B,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EACV,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,+BAA+B,CAAC"}