@xmoxmo/bncr 0.5.7 → 0.5.9

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 (44) hide show
  1. package/package.json +1 -1
  2. package/scripts/check-pack.mjs +0 -2
  3. package/scripts/selfcheck.mjs +48 -13
  4. package/src/bootstrap/runtime-loader.ts +1 -1
  5. package/src/channel.ts +50 -138
  6. package/src/core/connection-reachability.ts +1 -1
  7. package/src/core/logging.ts +1 -1
  8. package/src/core/outbox-entry-builders.ts +60 -82
  9. package/src/core/outbox-summary.ts +5 -39
  10. package/src/core/permissions.ts +1 -1
  11. package/src/core/register-trace.ts +2 -2
  12. package/src/messaging/inbound/parse.ts +1 -1
  13. package/src/messaging/outbound/diagnostics-debug-builders.ts +0 -15
  14. package/src/messaging/outbound/diagnostics.ts +0 -1
  15. package/src/messaging/outbound/marker-parser.ts +234 -0
  16. package/src/messaging/outbound/media-dedupe.ts +1 -4
  17. package/src/messaging/outbound/normalize-outbound-send.ts +9 -7
  18. package/src/messaging/outbound/reply-enqueue-media.ts +1 -184
  19. package/src/messaging/outbound/reply-enqueue.ts +249 -162
  20. package/src/openclaw/media-runtime.ts +1 -1
  21. package/src/plugin/ack-outbox-runtime-group.ts +2 -0
  22. package/src/plugin/bridge-media-facade.ts +0 -3
  23. package/src/plugin/bridge-outbox-facade.ts +14 -2
  24. package/src/plugin/channel-runtime-builders-delivery.ts +2 -362
  25. package/src/plugin/channel-runtime-builders-status.ts +0 -160
  26. package/src/plugin/channel-runtime-builders.ts +3 -17
  27. package/src/plugin/channel-runtime-constants.ts +1 -1
  28. package/src/plugin/channel-send.ts +5 -4
  29. package/src/plugin/file-transfer-orchestrator.ts +39 -2
  30. package/src/plugin/media-orchestrators-runtime-group.ts +20 -149
  31. package/src/plugin/messaging.ts +3 -3
  32. package/src/plugin/outbox-drain-failure.ts +34 -1
  33. package/src/plugin/outbox-drain-runtime.ts +3 -0
  34. package/src/plugin/outbox-push.ts +1 -52
  35. package/src/plugin/outbox-unified-push-flow.ts +307 -0
  36. package/src/plugin/scene-registry.ts +1 -1
  37. package/src/runtime/log-dedupe.ts +3 -3
  38. package/src/runtime/outbound-ack-timeout.ts +2 -4
  39. package/src/runtime/status-snapshots.ts +2 -2
  40. package/src/runtime/status-worker.ts +2 -6
  41. package/src/core/outbox-text-push-prep.ts +0 -1
  42. package/src/plugin/bridge-file-transfer-push-facade.ts +0 -142
  43. package/src/plugin/outbox-file-push-flow.ts +0 -69
  44. package/src/plugin/outbox-text-push-flow.ts +0 -90
@@ -28,7 +28,7 @@ export const OUTBOUND_READY_TTL_MS = 30_000;
28
28
  export const PREFERRED_OUTBOUND_TTL_MS = 12_000;
29
29
  export const FILE_FORCE_CHUNK = true;
30
30
  export const FILE_INLINE_THRESHOLD = 5 * 1024 * 1024;
31
- export const FILE_CHUNK_SIZE = 256 * 1024;
31
+ const FILE_CHUNK_SIZE = 256 * 1024;
32
32
  export const INBOUND_FILE_TRANSFER_MAX_BYTES = 50 * 1024 * 1024;
33
33
  export const INBOUND_FILE_TRANSFER_MAX_CHUNKS =
34
34
  Math.ceil(INBOUND_FILE_TRANSFER_MAX_BYTES / FILE_CHUNK_SIZE) + 1;
@@ -8,7 +8,7 @@ import type { ReplyPayloadInput } from '../messaging/outbound/reply-enqueue.ts';
8
8
  import type { BncrChannelSendContext, BncrVerifiedTarget } from './channel-runtime-types.ts';
9
9
 
10
10
  /**
11
- * Resolve downloadMedia with cascade: override (host/user) > ctx > scene.
11
+ * Resolve downloadMedia with cascade: host override > ctx > scene > default(false).
12
12
  * Marker-level downloadMedia is extracted downstream by the orchestrator's
13
13
  * normalisation and has highest priority (overrides whatever we pass).
14
14
  */
@@ -52,7 +52,7 @@ export type BncrChannelSendRuntime = {
52
52
  mediaLocalRoots?: readonly string[];
53
53
  }) => Promise<void>;
54
54
  listOutboxEntries: () => OutboxEntry[];
55
- /** Resolve downloadMedia from scene config: marker > scene > global > default(false). */
55
+ /** Resolve downloadMedia from scene config (host/ctx already resolved above). */
56
56
  resolveSceneDownloadMedia?: (to: string) => boolean | undefined;
57
57
  };
58
58
 
@@ -81,8 +81,9 @@ async function enqueueChannelMessageHandoff(
81
81
  }
82
82
 
83
83
  /**
84
- * Resolve downloadMedia from scene config when not already set by marker/host.
85
- * Scene cascade: marker > scene config > global > default(false).
84
+ * Resolve downloadMedia from scene config when not already set.
85
+ * Scene cascade: host override > ctx > scene config > default(false).
86
+ * (Marker-level downloadMedia overrides everything and is handled downstream.)
86
87
  */
87
88
 
88
89
  export function createBncrChannelSendRuntime(runtime: BncrChannelSendRuntime) {
@@ -193,7 +193,38 @@ export function createBncrFileTransferOrchestrator(runtime: BncrFileTransferOrch
193
193
  };
194
194
  const HTTP_URL_RE = /^https?:\/\//i;
195
195
 
196
- /** Try HEAD for Content-Type; fall back to Range+sniff for magic bytes when unclear. */
196
+ const EXT_TO_MIME: Record<string, string> = {
197
+ jpg: 'image/jpeg',
198
+ jpeg: 'image/jpeg',
199
+ png: 'image/png',
200
+ gif: 'image/gif',
201
+ webp: 'image/webp',
202
+ bmp: 'image/bmp',
203
+ heic: 'image/heic',
204
+ heif: 'image/heif',
205
+ mp4: 'video/mp4',
206
+ mov: 'video/quicktime',
207
+ mkv: 'video/x-matroska',
208
+ webm: 'video/webm',
209
+ avi: 'video/x-msvideo',
210
+ m4v: 'video/x-m4v',
211
+ mp3: 'audio/mpeg',
212
+ wav: 'audio/wav',
213
+ ogg: 'audio/ogg',
214
+ oga: 'audio/ogg',
215
+ opus: 'audio/opus',
216
+ m4a: 'audio/mp4',
217
+ aac: 'audio/aac',
218
+ flac: 'audio/flac',
219
+ };
220
+
221
+ function mimeFromUrlExt(url: string): string | undefined {
222
+ const clean = url.split(/[?#]/, 1)[0] || '';
223
+ const ext = clean.includes('.') ? clean.slice(clean.lastIndexOf('.') + 1).toLowerCase() : '';
224
+ return EXT_TO_MIME[ext];
225
+ }
226
+
227
+ /** Try HEAD for Content-Type; fall back to Range+sniff for magic bytes; then URL extension. */
197
228
  async function resolveRemoteMediaType(url: string): Promise<{ mimeType?: string }> {
198
229
  // 1) HEAD -> Content-Type
199
230
  let headerType = '';
@@ -229,8 +260,14 @@ export function createBncrFileTransferOrchestrator(runtime: BncrFileTransferOrch
229
260
  if (!sniffed) return {};
230
261
  return { mimeType: sniffed };
231
262
  } catch {
232
- return {};
263
+ /* Range sniff failed, fall through to extension inference */
233
264
  }
265
+
266
+ // 3) URL extension -> mime type (fallback when HEAD and Range both fail)
267
+ const extMime = mimeFromUrlExt(url);
268
+ if (extMime) return { mimeType: extMime };
269
+
270
+ return {};
234
271
  }
235
272
 
236
273
  /** Minimal magic-byte MIME sniffer for the first ~512 bytes. */
@@ -1,21 +1,13 @@
1
1
  import type { BncrRoute, FileSendTransferState, OutboxEntry } from '../core/types.ts';
2
- import { normalizeMessageText } from '../messaging/outbound/media-dedupe.ts';
3
2
  import type {
4
3
  NormalizedReplyPayload,
5
4
  OutboundReplyTargetPolicy,
6
- ReplyMediaEntriesParams,
7
5
  ReplyPayloadInput,
8
6
  } from '../messaging/outbound/reply-enqueue.ts';
9
7
  import {
10
8
  enqueueNormalizedReplyPayload,
11
- enqueueReplyTextEntry,
12
9
  normalizeReplyPayload,
13
10
  } from '../messaging/outbound/reply-enqueue.ts';
14
- import {
15
- enqueueReplyMediaFallbackTextEntry,
16
- enqueueReplyMediaFileTransferEntry,
17
- enqueueSingleReplyMediaEntry,
18
- } from '../messaging/outbound/reply-enqueue-media.ts';
19
11
  import type { createBncrFileAckRuntime } from './file-ack-runtime.ts';
20
12
  import { createBncrFileTransferOrchestrator } from './file-transfer-orchestrator.ts';
21
13
  import type { createBncrFileTransferSetup } from './file-transfer-setup.ts';
@@ -27,92 +19,12 @@ type FileAckPayload = Awaited<
27
19
  ReturnType<ReturnType<typeof createBncrFileAckRuntime>['waitForFileAck']>
28
20
  >;
29
21
 
30
- function buildReplyMediaEntryHelpers(runtime: {
31
- logInfo: (scope: string | undefined, message: string, options?: { debugOnly?: boolean }) => void;
32
- enqueueOutbound: (entry: OutboxEntry) => void;
33
- buildTextOutboxEntry: (args: {
34
- accountId: string;
35
- sessionKey: string;
36
- route: BncrRoute;
37
- text: string;
38
- kind?: 'tool' | 'block' | 'final';
39
- replyToId?: string;
40
- replyTargetPolicy?: OutboundReplyTargetPolicy;
41
- }) => OutboxEntry;
42
- buildFileTransferOutboxEntry: (args: {
43
- accountId: string;
44
- sessionKey: string;
45
- route: BncrRoute;
46
- mediaUrl: string;
47
- mediaLocalRoots?: readonly string[];
48
- text: string;
49
- asVoice: boolean;
50
- audioAsVoice: boolean;
51
- type?: string;
52
- extra?: Record<string, unknown>;
53
- kind?: 'tool' | 'block' | 'final';
54
- replyToId?: string;
55
- replyTargetPolicy?: OutboundReplyTargetPolicy;
56
- downloadMedia?: boolean;
57
- }) => OutboxEntry;
58
- rememberRecentMediaSend: (args: {
59
- sessionKey: string;
60
- mediaUrl: string;
61
- text: string;
62
- replyToId: string;
63
- createdAt: number;
64
- }) => void;
65
- }) {
66
- return {
67
- enqueueReplyMediaFallbackTextEntry: (
68
- params: Parameters<typeof enqueueReplyMediaFallbackTextEntry>[0],
69
- ) =>
70
- enqueueReplyMediaFallbackTextEntry(params, {
71
- logInfo: runtime.logInfo,
72
- enqueueOutbound: runtime.enqueueOutbound,
73
- buildTextOutboxEntry: runtime.buildTextOutboxEntry,
74
- }),
75
- enqueueReplyMediaFileTransferEntry: (
76
- params: Parameters<typeof enqueueReplyMediaFileTransferEntry>[0],
77
- ) =>
78
- enqueueReplyMediaFileTransferEntry(params, {
79
- enqueueOutbound: runtime.enqueueOutbound,
80
- buildFileTransferOutboxEntry: runtime.buildFileTransferOutboxEntry,
81
- rememberRecentMediaSend: runtime.rememberRecentMediaSend,
82
- }),
83
- };
84
- }
85
-
86
- function buildReplyTextEntryHelper(runtime: {
87
- enqueueOutbound: (entry: OutboxEntry) => void;
88
- buildTextOutboxEntry: (args: {
89
- accountId: string;
90
- sessionKey: string;
91
- route: BncrRoute;
92
- text: string;
93
- kind?: 'tool' | 'block' | 'final';
94
- replyToId?: string;
95
- replyTargetPolicy?: OutboundReplyTargetPolicy;
96
- }) => OutboxEntry;
97
- }) {
98
- return (params: {
99
- accountId: string;
100
- sessionKey: string;
101
- route: BncrRoute;
102
- payload: NormalizedReplyPayload;
103
- }) =>
104
- enqueueReplyTextEntry(params, {
105
- enqueueOutbound: runtime.enqueueOutbound,
106
- buildTextOutboxEntry: runtime.buildTextOutboxEntry,
107
- });
108
- }
109
-
110
- function normalizeReplyOrchestratorPayload(args: {
22
+ async function normalizeReplyOrchestratorPayload(args: {
111
23
  payload: ReplyPayloadInput;
112
24
  asString: (value: unknown, fallback?: string) => string;
113
25
  replyTargetPolicy?: OutboundReplyTargetPolicy;
114
26
  }) {
115
- return normalizeReplyPayload(
27
+ return await normalizeReplyPayload(
116
28
  args.payload,
117
29
  { asString: args.asString },
118
30
  {
@@ -186,29 +98,21 @@ export function createBncrMediaOrchestratorsRuntimeGroup(runtime: {
186
98
  payload: NormalizedReplyPayload;
187
99
  }) => void;
188
100
  enqueueOutbound: (entry: OutboxEntry) => void;
189
- buildTextOutboxEntry: (args: {
101
+ buildOutboxEntry: (args: {
190
102
  accountId: string;
191
103
  sessionKey: string;
192
104
  route: BncrRoute;
193
- text: string;
194
- kind?: 'tool' | 'block' | 'final';
195
- replyToId?: string;
196
- replyTargetPolicy?: OutboundReplyTargetPolicy;
197
- }) => OutboxEntry;
198
- buildFileTransferOutboxEntry: (args: {
199
- accountId: string;
200
- sessionKey: string;
201
- route: BncrRoute;
202
- mediaUrl: string;
203
- mediaLocalRoots?: readonly string[];
204
- text: string;
205
- asVoice: boolean;
206
- audioAsVoice: boolean;
207
105
  type?: string;
208
- extra?: Record<string, unknown>;
106
+ msg: string;
209
107
  kind?: 'tool' | 'block' | 'final';
210
108
  replyToId?: string;
211
109
  replyTargetPolicy?: OutboundReplyTargetPolicy;
110
+ extra?: Record<string, unknown>;
111
+ transferMode?: 'text' | 'media';
112
+ mediaUrl?: string;
113
+ mediaLocalRoots?: readonly string[];
114
+ asVoice?: boolean;
115
+ audioAsVoice?: boolean;
212
116
  downloadMedia?: boolean;
213
117
  }) => OutboxEntry;
214
118
  rememberRecentMediaSend: (args: {
@@ -244,40 +148,7 @@ export function createBncrMediaOrchestratorsRuntimeGroup(runtime: {
244
148
  logFileTransferCompleteAck: runtime.logFileTransferCompleteAck,
245
149
  });
246
150
 
247
- const replyMediaEntryHelpers = buildReplyMediaEntryHelpers(runtime);
248
- const replyTextEntryHelper = buildReplyTextEntryHelper(runtime);
249
-
250
- const enqueueReplyMediaEntries = (params: ReplyMediaEntriesParams) => {
251
- let first = true;
252
- const currentTime = runtime.now();
253
-
254
- for (const mediaUrl of params.payload.mediaList) {
255
- const normalizedText = normalizeMessageText(first ? params.payload.text : '');
256
- const fallback = runtime.tryBuildMediaDedupeFallback({
257
- sessionKey: params.sessionKey,
258
- mediaUrl,
259
- text: normalizedText,
260
- replyToId: params.payload.replyToId,
261
- currentTime,
262
- });
263
-
264
- enqueueSingleReplyMediaEntry(
265
- {
266
- params,
267
- mediaUrl,
268
- normalizedText,
269
- text: first ? params.payload.text : '',
270
- fallback,
271
- currentTime,
272
- },
273
- replyMediaEntryHelpers,
274
- );
275
-
276
- first = false;
277
- }
278
- };
279
-
280
- const enqueueFromReply = (params: {
151
+ const enqueueFromReply = async (params: {
281
152
  accountId: string;
282
153
  sessionKey: string;
283
154
  route: BncrRoute;
@@ -286,7 +157,7 @@ export function createBncrMediaOrchestratorsRuntimeGroup(runtime: {
286
157
  replyTargetPolicy?: OutboundReplyTargetPolicy;
287
158
  }) => {
288
159
  const { accountId, sessionKey, route, payload, mediaLocalRoots, replyTargetPolicy } = params;
289
- const normalized = normalizeReplyOrchestratorPayload({
160
+ const normalized = await normalizeReplyOrchestratorPayload({
290
161
  payload,
291
162
  asString: runtime.asString,
292
163
  replyTargetPolicy,
@@ -302,19 +173,19 @@ export function createBncrMediaOrchestratorsRuntimeGroup(runtime: {
302
173
  },
303
174
  {
304
175
  logEnqueueFromReply: runtime.logEnqueueFromReply,
305
- enqueueReplyMediaEntries,
306
- enqueueReplyTextEntry: replyTextEntryHelper,
176
+ enqueueOutbound: runtime.enqueueOutbound,
177
+ buildOutboxEntry: runtime.buildOutboxEntry,
178
+ tryBuildMediaDedupeFallback: runtime.tryBuildMediaDedupeFallback,
179
+ rememberRecentMediaSend: runtime.rememberRecentMediaSend,
180
+ logInfo: runtime.logInfo,
307
181
  },
308
182
  );
309
183
  };
310
184
 
311
- const replyMediaOrchestrator = {
312
- enqueueFromReply,
313
- enqueueReplyMediaEntries,
314
- };
315
-
316
185
  return {
317
186
  fileTransferOrchestrator,
318
- replyMediaOrchestrator,
187
+ replyMediaOrchestrator: {
188
+ enqueueFromReply,
189
+ },
319
190
  };
320
191
  }
@@ -67,12 +67,12 @@ function isDisplayTarget(
67
67
  return Boolean(value && typeof value === 'object');
68
68
  }
69
69
 
70
- export function normalizeBncrMessagingTarget(raw: string) {
70
+ function normalizeBncrMessagingTarget(raw: string) {
71
71
  const input = asSanitizedString(raw).trim();
72
72
  return input || undefined;
73
73
  }
74
74
 
75
- export function formatBncrMessagingTargetDisplay({ target }: BncrMessagingTargetDisplayInput) {
75
+ function formatBncrMessagingTargetDisplay({ target }: BncrMessagingTargetDisplayInput) {
76
76
  if (typeof target === 'string') {
77
77
  const parsed = parseExplicitTarget(asSanitizedString(target).trim());
78
78
  return parsed?.route ? formatBncrHumanDisplay(parsed.route) : asSanitizedString(target).trim();
@@ -183,7 +183,7 @@ export function createBncrMessagingSurface(getBridge: () => BncrMessagingRuntime
183
183
  };
184
184
  }
185
185
 
186
- export function createBncrMessagingTargetResolver(getBridge: () => BncrMessagingRuntimeBridge) {
186
+ function createBncrMessagingTargetResolver(getBridge: () => BncrMessagingRuntimeBridge) {
187
187
  return {
188
188
  looksLikeId: (raw: string, normalized?: string) => {
189
189
  return looksLikeBncrExplicitTarget(asSanitizedString(normalized || raw).trim());
@@ -21,6 +21,8 @@ type BncrOutboxDrainFailureRuntime = {
21
21
  backoffMs: (retryCount: number) => number;
22
22
  outbox: Map<string, OutboxEntry>;
23
23
  resolveAccountIdForSession: (sessionKey: string) => string | null;
24
+ resolveActiveAccountIds?: () => Iterable<string>;
25
+ resolvePushConnIds?: (accountId: string) => Iterable<string>;
24
26
  logInfo: (scope: string, message: string, options?: { debugOnly?: boolean }) => void;
25
27
  logWarn: (scope: string, message: string, options?: { debugOnly?: boolean }) => void;
26
28
  isPrePushGuardDeferral: (entry: OutboxEntry) => boolean;
@@ -45,7 +47,7 @@ export function createBncrOutboxDrainFailure(runtime: BncrOutboxDrainFailureRunt
45
47
  // If the entry keeps hitting pre-push guard (no active connection), the
46
48
  // accountId on the entry might be wrong (e.g. constructed from route data).
47
49
  // Try to correct it from recent inbound session context before giving up.
48
- if (runtime.isPrePushGuardDeferral(entry) && entry.retryCount > 0) {
50
+ if (runtime.isPrePushGuardDeferral(entry) && entry.retryCount >= 1) {
49
51
  const corrected = runtime.resolveAccountIdForSession(entry.sessionKey);
50
52
  if (corrected && corrected !== entry.accountId) {
51
53
  const oldAccountId = entry.accountId;
@@ -75,7 +77,38 @@ export function createBncrOutboxDrainFailure(runtime: BncrOutboxDrainFailureRunt
75
77
  }
76
78
  }
77
79
 
80
+ // Round-robin fallback: try all active accounts when session healing fails
81
+ if (
82
+ runtime.isPrePushGuardDeferral(entry) &&
83
+ runtime.resolveActiveAccountIds &&
84
+ runtime.resolvePushConnIds
85
+ ) {
86
+ const currentId = entry.accountId;
87
+ for (const candidateId of runtime.resolveActiveAccountIds()) {
88
+ if (candidateId === currentId) continue;
89
+ const connIds = Array.from(runtime.resolvePushConnIds(candidateId));
90
+ if (connIds.length > 0) {
91
+ const oldAccountId = entry.accountId;
92
+ runtime.logWarn(
93
+ 'outbound',
94
+ `account round-robin corrected sessionKey=${entry.sessionKey} ${oldAccountId}→${candidateId}`,
95
+ );
96
+ entry.accountId = candidateId;
97
+ entry.retryCount = 0;
98
+ entry.lastError = undefined;
99
+ runtime.outbox.set(entry.messageId, entry);
100
+ runtime.scheduleSave();
101
+ return { action: 'continue', localNextDelay };
102
+ }
103
+ }
104
+ }
105
+
78
106
  if (runtime.isPrePushGuardDeferral(entry)) {
107
+ // Budget check: guard failures that exceed maxRetry go to dead-letter
108
+ if ((entry.retryCount || 0) >= runtime.maxRetry) {
109
+ runtime.moveToDeadLetter(entry, entry.lastError || 'guard-failure-limit');
110
+ return { action: 'continue', localNextDelay };
111
+ }
79
112
  const wait = runtime.prePushGuardRetryDelayMs;
80
113
  localNextDelay = runtime.outboxDrainSchedule.scheduleAccountWait({
81
114
  accountId,
@@ -59,6 +59,7 @@ type BncrOutboxDrainRuntime = {
59
59
  isPlainObject: (value: unknown) => value is Record<string, unknown>;
60
60
  normalizeAccountId: (accountId: string) => string;
61
61
  resolveAccountIdForSession: (sessionKey: string) => string | null;
62
+ resolveActiveAccountIds?: () => Iterable<string>;
62
63
  stopped: () => boolean;
63
64
  outbox: Map<string, OutboxEntry>;
64
65
  deadLetter: () => OutboxEntry[];
@@ -137,6 +138,8 @@ export function createBncrOutboxDrainRuntime(runtime: BncrOutboxDrainRuntime) {
137
138
  backoffMs: runtime.backoffMs,
138
139
  outbox: runtime.outbox,
139
140
  resolveAccountIdForSession: runtime.resolveAccountIdForSession,
141
+ resolveActiveAccountIds: runtime.resolveActiveAccountIds,
142
+ resolvePushConnIds: runtime.resolvePushConnIds,
140
143
  logInfo: runtime.logInfo,
141
144
  logWarn: runtime.logWarn,
142
145
  isPrePushGuardDeferral: runtime.isPrePushGuardDeferral,
@@ -3,12 +3,7 @@ import {
3
3
  resolveFileTransferFailureState,
4
4
  } from '../core/outbox-file-transfer-failure.ts';
5
5
  import { buildTextPushFailureArgs } from '../core/outbox-text-push-failure.ts';
6
- import {
7
- buildTextPushBroadcastPayload,
8
- buildTextPushOkArgs,
9
- buildTextPushRouteSelectArgs,
10
- buildTextPushSuccessArgs,
11
- } from '../core/outbox-text-push-success.ts';
6
+
12
7
  import type { BncrConnection, OutboxEntry } from '../core/types.ts';
13
8
  import {
14
9
  buildOutboxPushOkDebugInfo,
@@ -137,51 +132,6 @@ export function createBncrOutboxPush(runtime: BncrOutboxPushRuntime) {
137
132
  );
138
133
  };
139
134
 
140
- const pushTextSuccessPath = (args: {
141
- entry: OutboxEntry;
142
- owner: BncrConnection | null;
143
- connIds: Iterable<string>;
144
- recentInboundReachable: boolean;
145
- routeReason: string;
146
- ownerConnId?: string;
147
- }) => {
148
- runtime.gatewayBroadcastToConnIds(
149
- runtime.pushEvent,
150
- buildTextPushBroadcastPayload({
151
- payload: args.entry.payload,
152
- messageId: args.entry.messageId,
153
- }),
154
- new Set(args.connIds),
155
- );
156
- logOutboxRouteSelect(
157
- buildTextPushRouteSelectArgs({
158
- entry: args.entry,
159
- connIds: args.connIds,
160
- routeReason: args.routeReason,
161
- recentInboundReachable: args.recentInboundReachable,
162
- owner: args.owner,
163
- event: runtime.pushEvent,
164
- }),
165
- );
166
- runtime.recordOutboxPushSuccess(
167
- buildTextPushSuccessArgs({
168
- entry: args.entry,
169
- connIds: args.connIds,
170
- ownerConnId: args.ownerConnId,
171
- ownerClientId: args.ownerConnId ? args.owner?.clientId : undefined,
172
- }),
173
- );
174
- logOutboxPushOkSummary(args.entry.messageId);
175
- logOutboxPushOk(
176
- buildTextPushOkArgs({
177
- entry: args.entry,
178
- connIds: args.connIds,
179
- recentInboundReachable: args.recentInboundReachable,
180
- event: runtime.pushEvent,
181
- }),
182
- );
183
- };
184
-
185
135
  const handleTextPushFailure = (args: { entry: OutboxEntry; error: unknown }) => {
186
136
  runtime.recordOutboxPushFailure({
187
137
  entry: args.entry,
@@ -253,7 +203,6 @@ export function createBncrOutboxPush(runtime: BncrOutboxPushRuntime) {
253
203
  };
254
204
 
255
205
  return {
256
- pushTextSuccessPath,
257
206
  handleTextPushFailure,
258
207
  handleFileTransferPushFailure,
259
208
  handleFileTransferPushGuardFailure,