@opentag/dispatcher 0.3.2 → 0.3.4

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.
@@ -17,6 +17,13 @@ export declare function createSlackSourceReceiptSink(input: {
17
17
  reactionsAddUri?: string;
18
18
  timeoutMs?: number;
19
19
  }): SourceReceiptSink;
20
+ export declare function createLarkSourceReceiptSink(input: {
21
+ appId?: string;
22
+ appSecret?: string;
23
+ domain?: "lark" | "feishu";
24
+ client?: LarkReplyClient;
25
+ receivedEmojiType?: string;
26
+ }): SourceReceiptSink;
20
27
  export declare function createLarkCallbackSink(input: {
21
28
  appId?: string;
22
29
  appSecret?: string;
@@ -29,4 +36,5 @@ export declare function createTelegramCallbackSink(input: {
29
36
  fetchImpl?: FetchLike;
30
37
  }): CallbackSink;
31
38
  export declare function createCompositeCallbackSink(sinks: CallbackSink[]): CallbackSink;
39
+ export declare function createCompositeSourceReceiptSink(sinks: SourceReceiptSink[]): SourceReceiptSink;
32
40
  //# sourceMappingURL=callbacks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"callbacks.d.ts","sourceRoot":"","sources":["../src/callbacks.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,eAAe,EAIrB,MAAM,eAAe,CAAC;AASvB,OAAO,KAAK,EAA2C,YAAY,EAAiB,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE3H,MAAM,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC;AAkErC,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,YAAY,CA+CvG;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,GAAG,YAAY,CA0Df;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,iBAAiB,CAgDpB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B,GAAG,YAAY,CA6Cf;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,GAAG,YAAY,CAyDf;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,CAuB/E"}
1
+ {"version":3,"file":"callbacks.d.ts","sourceRoot":"","sources":["../src/callbacks.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,eAAe,EAIrB,MAAM,eAAe,CAAC;AASvB,OAAO,KAAK,EAA2C,YAAY,EAAiB,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE3H,MAAM,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC;AA0ErC,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,YAAY,CA+CvG;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,GAAG,YAAY,CA0Df;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,iBAAiB,CAgDpB;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,iBAAiB,CAuBpB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B,GAAG,YAAY,CA6Cf;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,GAAG,YAAY,CAyDf;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,CAuB/E;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,CAmB9F"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/callbacks.ts
2
2
  import {
3
+ addLarkMessageReaction,
3
4
  createLarkReplyClient,
4
5
  patchLarkMessageCard,
5
6
  parseLarkThreadKey,
@@ -15,6 +16,7 @@ import {
15
16
  } from "@opentag/slack";
16
17
  import { createTelegramSendMessageDraftPayload, createTelegramSendMessagePayload, parseTelegramThreadKey } from "@opentag/telegram";
17
18
  var DEFAULT_SLACK_SOURCE_RECEIPT_TIMEOUT_MS = 5e3;
19
+ var DEFAULT_LARK_RECEIVED_REACTION = "Typing";
18
20
  function slackUpdateUriFrom(postMessageUri) {
19
21
  return postMessageUri.replace(/\/chat\.postMessage$/, "/chat.update");
20
22
  }
@@ -41,6 +43,12 @@ function slackSourceMessageTarget(receipt) {
41
43
  const messageTs = metadataString(receipt.event.metadata, "messageTs");
42
44
  return channelId && messageTs ? { channelId, messageTs } : null;
43
45
  }
46
+ function larkSourceMessageTarget(receipt) {
47
+ if (receipt.provider !== "lark" || receipt.state !== "received") return null;
48
+ const threadKey = receipt.event.callback.threadKey;
49
+ if (!threadKey) return null;
50
+ return { messageId: parseLarkThreadKey(threadKey).messageId };
51
+ }
44
52
  function isAbortError(error) {
45
53
  return error instanceof Error && error.name === "AbortError";
46
54
  }
@@ -200,6 +208,24 @@ function createSlackSourceReceiptSink(input) {
200
208
  }
201
209
  };
202
210
  }
211
+ function createLarkSourceReceiptSink(input) {
212
+ if (!input.client && Boolean(input.appId) !== Boolean(input.appSecret)) {
213
+ throw new Error("Lark source receipt sink requires both appId and appSecret (or neither).");
214
+ }
215
+ const client = input.client ?? (input.appId && input.appSecret ? createLarkReplyClient({ appId: input.appId, appSecret: input.appSecret, ...input.domain ? { domain: input.domain } : {} }) : void 0);
216
+ const receivedEmojiType = input.receivedEmojiType ?? DEFAULT_LARK_RECEIVED_REACTION;
217
+ return {
218
+ async deliver(receipt) {
219
+ const target = larkSourceMessageTarget(receipt);
220
+ if (!target || !client) return { delivered: false };
221
+ await addLarkMessageReaction(client, {
222
+ messageId: target.messageId,
223
+ emojiType: receivedEmojiType
224
+ });
225
+ return { delivered: true };
226
+ }
227
+ };
228
+ }
203
229
  function createLarkCallbackSink(input) {
204
230
  if (!input.client && Boolean(input.appId) !== Boolean(input.appSecret)) {
205
231
  throw new Error("Lark callback sink requires both appId and appSecret (or neither).");
@@ -314,6 +340,26 @@ function createCompositeCallbackSink(sinks) {
314
340
  }
315
341
  };
316
342
  }
343
+ function createCompositeSourceReceiptSink(sinks) {
344
+ return {
345
+ async deliver(receipt) {
346
+ let delivered = false;
347
+ const failures = [];
348
+ for (const sink of sinks) {
349
+ try {
350
+ const result = await sink.deliver(receipt);
351
+ delivered ||= result.delivered;
352
+ } catch (error) {
353
+ failures.push(error);
354
+ }
355
+ }
356
+ if (!delivered && failures.length > 0) {
357
+ throw new AggregateError(failures, "Composite source receipt delivery failed for every sink.");
358
+ }
359
+ return { delivered };
360
+ }
361
+ };
362
+ }
317
363
 
318
364
  // src/presentation.ts
319
365
  import {
@@ -874,6 +920,16 @@ function shouldDeliverRunStatusUpdate(presentation, input) {
874
920
  function larkLifecycleStatusMessageKey(input) {
875
921
  return input.provider === "lark" ? `${input.runId}:status` : void 0;
876
922
  }
923
+ function isTerminalRun(run) {
924
+ return ["succeeded", "failed", "cancelled", "interrupted", "timed_out"].includes(run.status);
925
+ }
926
+ function shouldUseDelayedLarkStatusCard(provider, options) {
927
+ return provider === "lark" && options.enabled !== false;
928
+ }
929
+ function safeExecutorLabel(executor) {
930
+ if (!executor || !/^[a-z0-9._-]{1,40}$/i.test(executor)) return "the selected agent";
931
+ return executor;
932
+ }
877
933
  var CreateRunnerSchema = z.object({
878
934
  runnerId: z.string().min(1),
879
935
  name: z.string().min(1)
@@ -1946,7 +2002,7 @@ async function deliverAndAudit(input) {
1946
2002
  ...input.message.blocks ? { blocks: input.message.blocks } : {},
1947
2003
  ...input.message.rich ? { rich: input.message.rich } : {}
1948
2004
  });
1949
- await deliverCallbackDelivery({
2005
+ return deliverCallbackDelivery({
1950
2006
  repo: input.repo,
1951
2007
  sink: input.sink,
1952
2008
  delivery,
@@ -2070,6 +2126,13 @@ function createDispatcherApp(input) {
2070
2126
  const sourceReceiptSink = input.sourceReceiptSink ?? noopSourceReceiptSink;
2071
2127
  const presentation = input.presentation ?? createDefaultCallbackPresentation();
2072
2128
  const callbackRetry = input.callbackRetry ?? {};
2129
+ const larkStatusCardOptions = input.larkStatusCards ?? {};
2130
+ const larkStatusCardDelayMs = larkStatusCardOptions.delayMs ?? 1e4;
2131
+ const larkStatusCardMinUpdateIntervalMs = larkStatusCardOptions.minUpdateIntervalMs ?? 5e3;
2132
+ const larkStatusCardNow = larkStatusCardOptions.now ?? (() => Date.now());
2133
+ const setLarkStatusCardTimeout = larkStatusCardOptions.setTimeout ?? ((callback, delayMs) => globalThis.setTimeout(callback, delayMs));
2134
+ const clearLarkStatusCardTimeout = larkStatusCardOptions.clearTimeout ?? ((handle) => globalThis.clearTimeout(handle));
2135
+ const delayedLarkStatusCards = /* @__PURE__ */ new Map();
2073
2136
  const maxRequestBodyBytes = input.maxRequestBodyBytes ?? DEFAULT_MAX_REQUEST_BODY_BYTES;
2074
2137
  const runnerTokens = configuredRunnerTokens(input);
2075
2138
  const revokedRunnerTokenFingerprints = normalizeRevokedRunnerTokenFingerprints(input.revokedRunnerTokenFingerprints);
@@ -2132,6 +2195,145 @@ function createDispatcherApp(input) {
2132
2195
  message: "Run status callback suppressed by platform liveness strategy; use status or audit for details."
2133
2196
  });
2134
2197
  };
2198
+ function delayedLarkStatusMessage(input2) {
2199
+ if (input2.phase === "queued") return "Waiting for the local runner.";
2200
+ if (input2.phase === "progress") return "OpenTag is still working.";
2201
+ return `Running with ${safeExecutorLabel(input2.run.executor)}.`;
2202
+ }
2203
+ function delayedLarkStatusState(input2) {
2204
+ if (input2.phase === "queued") return "queued";
2205
+ return "running";
2206
+ }
2207
+ async function appendDelayedLarkStatusFailure(input2) {
2208
+ await repo.appendRunEvent({
2209
+ runId: input2.runId,
2210
+ type: "callback.progress.failed",
2211
+ payload: {
2212
+ provider: "lark",
2213
+ reason: "delayed_status_card",
2214
+ error: input2.error instanceof Error ? input2.error.message : String(input2.error)
2215
+ },
2216
+ visibility: "audit",
2217
+ importance: "low",
2218
+ message: "Delayed Lark status card update failed."
2219
+ });
2220
+ }
2221
+ async function deliverDelayedLarkStatusCard(input2) {
2222
+ if (!shouldUseDelayedLarkStatusCard(input2.event.callback.provider, larkStatusCardOptions)) return false;
2223
+ if (!input2.event.callback.threadKey) return false;
2224
+ if (isTerminalRun(input2.run)) return false;
2225
+ const statusMessageKey = larkLifecycleStatusMessageKey({ provider: input2.event.callback.provider, runId: input2.run.id });
2226
+ if (!statusMessageKey) return false;
2227
+ const state = delayedLarkStatusCards.get(input2.run.id) ?? { cardCreated: false };
2228
+ delayedLarkStatusCards.set(input2.run.id, state);
2229
+ if (!input2.createIfMissing && !state.cardCreated) return false;
2230
+ const now = larkStatusCardNow();
2231
+ const phaseChanged = state.lastPhase !== input2.phase;
2232
+ const intervalElapsed = !state.lastUpdateAt || now - state.lastUpdateAt >= larkStatusCardMinUpdateIntervalMs;
2233
+ if (!input2.createIfMissing && !phaseChanged && !intervalElapsed) return false;
2234
+ const statusPresentation = presentation.runStatusPresentation({
2235
+ runId: input2.run.id,
2236
+ state: delayedLarkStatusState({ run: input2.run, phase: input2.phase }),
2237
+ message: delayedLarkStatusMessage({ run: input2.run, phase: input2.phase }),
2238
+ nextAction: "Use /status here for active-run and queue state, or wait for the final result.",
2239
+ detailVisibility: "source_thread"
2240
+ });
2241
+ const rendered = presentation.render({
2242
+ provider: input2.event.callback.provider,
2243
+ presentation: statusPresentation
2244
+ });
2245
+ const delivered = await deliverAndAudit({
2246
+ repo,
2247
+ sink: callbackSink,
2248
+ retry: callbackRetry,
2249
+ message: {
2250
+ runId: input2.run.id,
2251
+ kind: "progress",
2252
+ provider: input2.event.callback.provider,
2253
+ uri: input2.event.callback.uri,
2254
+ body: rendered.body,
2255
+ ...input2.event.target.agentId ? { agentId: input2.event.target.agentId } : {},
2256
+ threadKey: input2.event.callback.threadKey,
2257
+ ...rendered.blocks?.length ? { blocks: rendered.blocks } : {},
2258
+ ...rendered.rich ? { rich: rendered.rich } : {},
2259
+ statusMessageKey
2260
+ }
2261
+ });
2262
+ if (!delivered) return false;
2263
+ state.cardCreated = true;
2264
+ state.lastPhase = input2.phase;
2265
+ state.lastUpdateAt = now;
2266
+ return true;
2267
+ }
2268
+ function scheduleDelayedLarkStatusCard(input2) {
2269
+ if (!shouldUseDelayedLarkStatusCard(input2.event.callback.provider, larkStatusCardOptions)) return;
2270
+ if (!input2.event.callback.threadKey) return;
2271
+ if (larkStatusCardDelayMs < 0) return;
2272
+ const existing = delayedLarkStatusCards.get(input2.run.id);
2273
+ if (existing?.timer || existing?.cardCreated) return;
2274
+ const state = existing ?? { cardCreated: false };
2275
+ const timer = setLarkStatusCardTimeout(() => {
2276
+ delete state.timer;
2277
+ void (async () => {
2278
+ try {
2279
+ const latestRun = await repo.getRun({ runId: input2.run.id });
2280
+ if (!latestRun || isTerminalRun(latestRun.run)) {
2281
+ delayedLarkStatusCards.delete(input2.run.id);
2282
+ return;
2283
+ }
2284
+ const phase = latestRun.run.status === "queued" ? "queued" : "running";
2285
+ await deliverDelayedLarkStatusCard({
2286
+ run: latestRun.run,
2287
+ event: input2.event,
2288
+ phase,
2289
+ createIfMissing: true
2290
+ });
2291
+ } catch (error) {
2292
+ await appendDelayedLarkStatusFailure({ runId: input2.run.id, error });
2293
+ }
2294
+ })();
2295
+ }, larkStatusCardDelayMs);
2296
+ if (timer && typeof timer === "object" && "unref" in timer && typeof timer.unref === "function") {
2297
+ timer.unref();
2298
+ }
2299
+ state.timer = timer;
2300
+ delayedLarkStatusCards.set(input2.run.id, state);
2301
+ }
2302
+ function cancelPendingDelayedLarkStatusCard(runId) {
2303
+ const state = delayedLarkStatusCards.get(runId);
2304
+ if (!state?.timer) return;
2305
+ clearLarkStatusCardTimeout(state.timer);
2306
+ delete state.timer;
2307
+ }
2308
+ function clearDelayedLarkStatusCard(runId) {
2309
+ cancelPendingDelayedLarkStatusCard(runId);
2310
+ delayedLarkStatusCards.delete(runId);
2311
+ }
2312
+ async function patchDelayedLarkStatusCard(input2) {
2313
+ let state = delayedLarkStatusCards.get(input2.run.id);
2314
+ if (!state?.cardCreated) {
2315
+ const statusMessageKey = larkLifecycleStatusMessageKey({ provider: input2.event.callback.provider, runId: input2.run.id });
2316
+ const externalMessageId = statusMessageKey && input2.event.callback.threadKey ? await repo.findCallbackExternalMessageId({
2317
+ runId: input2.run.id,
2318
+ provider: input2.event.callback.provider,
2319
+ threadKey: input2.event.callback.threadKey,
2320
+ statusMessageKey
2321
+ }) : void 0;
2322
+ if (!externalMessageId) return;
2323
+ state = state ?? { cardCreated: true };
2324
+ state.cardCreated = true;
2325
+ delayedLarkStatusCards.set(input2.run.id, state);
2326
+ }
2327
+ try {
2328
+ await deliverDelayedLarkStatusCard({
2329
+ run: input2.run,
2330
+ event: input2.event,
2331
+ phase: input2.phase
2332
+ });
2333
+ } catch (error) {
2334
+ await appendDelayedLarkStatusFailure({ runId: input2.run.id, error });
2335
+ }
2336
+ }
2135
2337
  async function deliverPromotedFollowUpAcknowledgement(input2) {
2136
2338
  if (!presentation.shouldDeliverAcknowledgement(input2.event.callback.provider)) return;
2137
2339
  const acknowledgementPresentation = presentation.acknowledgementPresentation({ runId: input2.run.id });
@@ -2645,6 +2847,9 @@ function createDispatcherApp(input) {
2645
2847
  ...parsed.event.target.agentId ? { agentId: parsed.event.target.agentId } : {}
2646
2848
  }
2647
2849
  });
2850
+ if (sourceReceiptDelivery.delivered) {
2851
+ scheduleDelayedLarkStatusCard({ run, event: parsed.event });
2852
+ }
2648
2853
  const shouldDeliverAcknowledgement = presentation.shouldDeliverAcknowledgement(parsed.event.callback.provider) || shouldDeliverSourceReceipt(parsed.event.callback.provider) && !sourceReceiptDelivery.delivered;
2649
2854
  if (shouldDeliverAcknowledgement) {
2650
2855
  const acknowledgementPresentation = presentation.acknowledgementPresentation({ runId: run.id });
@@ -3123,6 +3328,11 @@ function createDispatcherApp(input) {
3123
3328
  } else if (presentation.shouldDeliverStatusUpdate(provider)) {
3124
3329
  await appendSuppressedRunStatusCallback({ runId, provider, state: "running" });
3125
3330
  }
3331
+ await patchDelayedLarkStatusCard({
3332
+ run: stored.run,
3333
+ event: stored.event,
3334
+ phase: "running"
3335
+ });
3126
3336
  return c.json({ ok: true });
3127
3337
  });
3128
3338
  app.post("/v1/runs/:runId/progress", async () => {
@@ -3191,6 +3401,11 @@ function createDispatcherApp(input) {
3191
3401
  message: "Progress callback suppressed by platform liveness strategy; use status or audit for details."
3192
3402
  });
3193
3403
  }
3404
+ await patchDelayedLarkStatusCard({
3405
+ run: stored.run,
3406
+ event: stored.event,
3407
+ phase: "progress"
3408
+ });
3194
3409
  return c.json({ ok: true });
3195
3410
  });
3196
3411
  app.post("/v1/runs/:runId/complete", async () => {
@@ -3214,6 +3429,7 @@ function createDispatcherApp(input) {
3214
3429
  if (outcome === "duplicate") return c.json({ ok: true, replayed: true });
3215
3430
  const stored = await repo.getRun({ runId });
3216
3431
  if (!stored) return c.json({ error: "run_not_found" }, 404);
3432
+ cancelPendingDelayedLarkStatusCard(runId);
3217
3433
  const receiptContext = await actionReceiptContextForFinal({
3218
3434
  event: stored.event,
3219
3435
  result: parsed.result,
@@ -3276,6 +3492,7 @@ function createDispatcherApp(input) {
3276
3492
  ...finalCallback.rich ? { rich: finalCallback.rich } : {}
3277
3493
  }
3278
3494
  });
3495
+ clearDelayedLarkStatusCard(runId);
3279
3496
  const shouldPromoteFollowUp = parsed.result.conclusion !== "needs_human" && parsed.result.conclusion !== "cancelled";
3280
3497
  const promotedFollowUp = shouldPromoteFollowUp ? await promoteNextFollowUpAfterTerminalRun({ activeRunId: runId }) : null;
3281
3498
  return c.json({
@@ -3482,10 +3699,12 @@ function createDispatcherApp(input) {
3482
3699
  }
3483
3700
  export {
3484
3701
  createCompositeCallbackSink,
3702
+ createCompositeSourceReceiptSink,
3485
3703
  createDefaultCallbackPresentation,
3486
3704
  createDispatcherApp,
3487
3705
  createGitHubCallbackSink,
3488
3706
  createLarkCallbackSink,
3707
+ createLarkSourceReceiptSink,
3489
3708
  createSlackCallbackSink,
3490
3709
  createSlackSourceReceiptSink,
3491
3710
  createTelegramCallbackSink,