@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
@@ -48,7 +48,7 @@ export function isOpenClawRemoteHttpMediaUrl(mediaUrl: string): boolean {
48
48
  * Returns the first absolute path that exists on disk, or the original
49
49
  * relative path if nothing is found (the host will then emit its own error).
50
50
  */
51
- export function resolveRelativeMediaPath(mediaUrl: string, localRoots?: readonly string[]): string {
51
+ function resolveRelativeMediaPath(mediaUrl: string, localRoots?: readonly string[]): string {
52
52
  if (!mediaUrl || !localRoots?.length) return mediaUrl;
53
53
  if (path.isAbsolute(mediaUrl)) return mediaUrl;
54
54
  // HTTP / file:// / data: / ~ paths are handled elsewhere
@@ -20,6 +20,7 @@ export function createBncrAckOutboxRuntimeGroup(runtime: {
20
20
  clampFiniteNumber: (value: unknown, fallback: number, min?: number, max?: number) => number;
21
21
  normalizeAccountId: (accountId: string) => string;
22
22
  resolveAccountIdForSession: (sessionKey: string) => string | null;
23
+ resolveActiveAccountIds?: () => Iterable<string>;
23
24
  formatDisplayScope: (route: OutboxEntry['route']) => string;
24
25
  isFileTransferEntry: (entry: OutboxEntry) => boolean;
25
26
  recommendedAckTimeoutMaxMs: number;
@@ -237,6 +238,7 @@ export function createBncrAckOutboxRuntimeGroup(runtime: {
237
238
  handleTextPushFailure: runtime.handleTextPushFailure,
238
239
  isPrePushGuardDeferral: runtime.isPrePushGuardDeferral,
239
240
  resolveAccountIdForSession: runtime.resolveAccountIdForSession,
241
+ resolveActiveAccountIds: runtime.resolveActiveAccountIds,
240
242
  moveToDeadLetter: runtime.moveToDeadLetter,
241
243
  scheduleSave: runtime.scheduleSave,
242
244
  logInfo: runtime.logInfo,
@@ -2,7 +2,6 @@ import type { BncrRoute, FileSendTransferState } from '../core/types.ts';
2
2
  import type {
3
3
  NormalizedReplyPayload,
4
4
  OutboundReplyTargetPolicy,
5
- ReplyMediaEntriesParams,
6
5
  ReplyPayloadInput,
7
6
  } from '../messaging/outbound/reply-enqueue.ts';
8
7
  import type { OpenClawLoadedMedia } from '../openclaw/media-runtime.ts';
@@ -61,7 +60,6 @@ export function createBncrBridgeMediaFacade(runtime: {
61
60
  mediaLocalRoots?: readonly string[];
62
61
  replyTargetPolicy?: OutboundReplyTargetPolicy;
63
62
  }) => void;
64
- enqueueReplyMediaEntries: (params: ReplyMediaEntriesParams) => void;
65
63
  };
66
64
  logInfoJson: (
67
65
  scope: string | undefined,
@@ -210,7 +208,6 @@ export function createBncrBridgeMediaFacade(runtime: {
210
208
  waitCompleteAck: runtime.fileTransferOrchestrator.waitCompleteAck,
211
209
  transferMediaToBncrClient: runtime.fileTransferOrchestrator.transferMediaToBncrClient,
212
210
  enqueueFromReply: runtime.replyMediaOrchestrator.enqueueFromReply,
213
- enqueueReplyMediaEntries: runtime.replyMediaOrchestrator.enqueueReplyMediaEntries,
214
211
  logEnqueueFromReply,
215
212
  logFileChunkDiag: runtime.fileTransferLogs.logFileChunkDiag,
216
213
  logFileTransferStart: runtime.fileTransferLogs.logFileTransferStart,
@@ -53,8 +53,21 @@ export function createBncrBridgeOutboxFacade(runtime: {
53
53
  lastError: string;
54
54
  persist?: boolean;
55
55
  }) => {
56
+ const nowMs = runtime.now();
57
+ const nextRetry = (args.entry.retryCount || 0) + 1;
58
+ if (nextRetry > runtime.maxRetry) {
59
+ // Budget exhausted — dead-letter the entry
60
+ Object.assign(args.entry, {
61
+ lastError: args.lastError,
62
+ retryCount: nextRetry,
63
+ lastAttemptAt: nowMs,
64
+ });
65
+ moveToDeadLetter(args.entry, args.lastError);
66
+ return;
67
+ }
68
+ const nextAttemptAt = nowMs + runtime.backoffMs(nextRetry);
56
69
  const nextEntry = buildBncrOutboxFailureEntryPatch({
57
- entry: args.entry,
70
+ entry: { ...args.entry, retryCount: nextRetry, lastAttemptAt: nowMs, nextAttemptAt },
58
71
  lastError: args.lastError,
59
72
  });
60
73
  Object.assign(args.entry, nextEntry);
@@ -126,7 +139,6 @@ export function createBncrBridgeOutboxFacade(runtime: {
126
139
  ),
127
140
  { debugOnly: true },
128
141
  );
129
- runtime.logOutboundSummary(entry);
130
142
  const accountId = runtime.normalizeAccountId(entry.accountId);
131
143
  runtime.incrementCounter(runtime.outboundEnqueueCountByAccount, accountId);
132
144
  runtime.lastOutboundEnqueueAtByAccount.set(accountId, runtime.now());
@@ -1,18 +1,8 @@
1
1
  import type { GatewayRequestHandlerOptions } from 'openclaw/plugin-sdk/core';
2
- import type { RegisterDriftSnapshot } from '../core/register-trace.ts';
3
- import type { normalizeStoredSessionKey as normalizeStoredSessionKeyFromRuntime } from '../core/targets.ts';
4
- import type {
5
- BncrConnection,
6
- BncrRoute,
7
- FileSendTransferState,
8
- OutboxEntry,
9
- } from '../core/types.ts';
2
+ import type { BncrRoute, OutboxEntry } from '../core/types.ts';
10
3
  import type { BncrGroupHistoryMap } from '../messaging/inbound/group-history.ts';
11
4
  import type { parseBncrInboundParams } from '../messaging/inbound/parse.ts';
12
- import type {
13
- NormalizedReplyPayload,
14
- ReplyPayloadInput,
15
- } from '../messaging/outbound/reply-enqueue.ts';
5
+ import type { ReplyPayloadInput } from '../messaging/outbound/reply-enqueue.ts';
16
6
  import type { OutboundReplyTargetPolicy } from '../messaging/outbound/reply-target-policy.ts';
17
7
  import type { createBncrInboundHandlersComponent } from './channel-components.ts';
18
8
  import type {
@@ -26,14 +16,7 @@ import type {
26
16
  } from './channel-runtime-types.ts';
27
17
  import type { LeaseEventPayload } from './connection-handlers.ts';
28
18
  import type { BncrActiveConnectionDebugEntry } from './connection-state.ts';
29
- import type { FileAckPayloadState, FileAckWaiter } from './file-ack-runtime.ts';
30
19
  import type { createBncrFileInboundHandlers } from './file-inbound-handlers.ts';
31
- import type { BncrFileTransferOrchestratorRuntime } from './file-transfer-orchestrator.ts';
32
- import type { BncrFileTransferRouteDiagnostics } from './file-transfer-setup.ts';
33
- import type { MessageAckWaiter } from './message-ack-runtime.ts';
34
-
35
- type StoredRouteRecord = { accountId: string; route: BncrRoute; updatedAt: number };
36
- type StoredLastSessionRecord = { sessionKey: string; scope: string; updatedAt: number };
37
20
 
38
21
  // Delivery-side wiring catalog.
39
22
  //
@@ -42,349 +25,6 @@ type StoredLastSessionRecord = { sessionKey: string; scope: string; updatedAt: n
42
25
  // 2) outbound + file-transfer state machines
43
26
  // 3) inbound/public send surfaces
44
27
 
45
- export function buildBncrConnectionStateRuntime(deps: {
46
- bridgeId: string;
47
- now: () => number;
48
- asString: (value: unknown, fallback?: string) => string;
49
- connectTtlMs: number;
50
- recentInboundSendWindowMs: number;
51
- outboundReadyTtlMs: number;
52
- preferredOutboundTtlMs: number;
53
- connections: Map<string, BncrConnection>;
54
- activeConnectionByAccount: Map<string, string>;
55
- lastInboundByAccount: Map<string, number>;
56
- lastActivityByAccount: Map<string, number>;
57
- gcTransientState: () => void;
58
- connectionKey: (accountId: string, clientId?: string) => string;
59
- buildActiveConnectionDebugList: (
60
- accountId: string,
61
- options?: { includeOutboundState?: boolean },
62
- ) => BncrActiveConnectionDebugEntry[];
63
- rememberGatewayContext: (context: GatewayRequestHandlerOptions['context']) => void;
64
- markActivity: (accountId: string, at?: number) => void;
65
- logInfo: (scope: string, message: string, options?: { debugOnly?: boolean }) => void;
66
- logInfoDedupJson: (
67
- scope: string,
68
- label: string,
69
- payload: unknown,
70
- options?: { key?: string; sig?: string; debugOnly?: boolean },
71
- ) => void;
72
- }) {
73
- return { ...deps };
74
- }
75
-
76
- export function buildBncrFileTransferRuntime(deps: {
77
- bridgeId: string;
78
- now: () => number;
79
- asString: (value: unknown, fallback?: string) => string;
80
- clampFiniteNumber: (value: unknown, fallback: number, min?: number, max?: number) => number;
81
- fileAckTimeoutMs: number;
82
- maxEarlyFileAcks: number;
83
- fileAckWaiters: Map<string, FileAckWaiter>;
84
- earlyFileAcks: Map<string, FileAckPayloadState>;
85
- getFileAckOwnerInfo: (transferId: string) => Record<string, unknown>;
86
- fileForceChunk: boolean;
87
- fileInlineThreshold: number;
88
- normalizeAccountId: (accountId: string) => string;
89
- loadOutboundTransferMedia: (args: {
90
- mediaUrl: string;
91
- mediaLocalRoots?: readonly string[];
92
- }) => Promise<{ loaded: { buffer: Buffer }; size: number; mimeType?: string; fileName: string }>;
93
- resolveOutboxPushOwner: (accountId: string) => { connId?: string; clientId?: string } | null;
94
- hasRecentInboundReachability: (accountId: string) => boolean;
95
- buildTransferRouteDiagnostics: (args: {
96
- accountId: string;
97
- recentInboundReachable: boolean;
98
- }) => BncrFileTransferRouteDiagnostics;
99
- selectTransferConnIds: (args: {
100
- directConnIds: Set<string>;
101
- recentConnIds: Set<string>;
102
- recentInboundReachable: boolean;
103
- }) => Set<string>;
104
- broadcastToConnIds: (event: string, payload: unknown, connIds: ReadonlySet<string>) => void;
105
- chunkEvent: string;
106
- completeEvent: string;
107
- logInfo: (scope: string | undefined, message: string, options?: { debugOnly?: boolean }) => void;
108
- logWarn: (scope: string | undefined, message: string, options?: { debugOnly?: boolean }) => void;
109
- }) {
110
- return { ...deps };
111
- }
112
-
113
- export function buildBncrStateTransientRuntime(deps: {
114
- bridgeId: string;
115
- getStatePath: () => string | null;
116
- now: () => number;
117
- asString: (value: unknown, fallback?: string) => string;
118
- finiteNumberOr: (value: unknown, fallback: number) => number;
119
- normalizeAccountId: (accountId: string) => string;
120
- normalizeStoredSessionKey: typeof normalizeStoredSessionKeyFromRuntime;
121
- parseRouteLike: (value: unknown) => BncrRoute | null;
122
- routeKey: (accountId: string, route: BncrRoute) => string;
123
- formatDisplayScope: (route: BncrRoute) => string;
124
- canonicalAgentId: () => string;
125
- normalizePersistedOutboxEntry: (entry: unknown) => OutboxEntry | null;
126
- maxDeadLetterEntries: number;
127
- maxSessionRouteEntries: number;
128
- maxAccountActivityEntries: number;
129
- sceneRegistry: Map<string, BncrSceneRecord>;
130
- groupHistories: Map<
131
- string,
132
- import('./channel-runtime-types.ts').BncrPersistedGroupHistoryEntry[]
133
- >;
134
- outbox: Map<string, OutboxEntry>;
135
- getDeadLetter: () => OutboxEntry[];
136
- setDeadLetter: (entries: OutboxEntry[]) => void;
137
- sessionRoutes: Map<string, StoredRouteRecord>;
138
- routeAliases: Map<string, StoredRouteRecord>;
139
- lastSessionByAccount: Map<string, StoredLastSessionRecord>;
140
- lastActivityByAccount: Map<string, number>;
141
- lastInboundByAccount: Map<string, number>;
142
- lastOutboundByAccount: Map<string, number>;
143
- getLastDriftSnapshot: () => RegisterDriftSnapshot | null;
144
- setLastDriftSnapshot: (value: RegisterDriftSnapshot | null) => void;
145
- connectTtlMs: number;
146
- fileTransferKeepMs: number;
147
- fileTransferTerminalKeepMs: number;
148
- fileTransferAckTtlMs: number;
149
- connections: Map<string, BncrConnection>;
150
- activeConnectionByAccount: Map<string, string>;
151
- recentInbound: Map<string, number>;
152
- fileSendTransfers: Map<string, { status: string; startedAt: number; terminalAt?: number }>;
153
- fileRecvTransfers: Map<string, { status: string; startedAt: number; terminalAt?: number }>;
154
- earlyFileAcks: Map<string, { at: number }>;
155
- logInfo: (scope: string | undefined, message: string, options?: { debugOnly?: boolean }) => void;
156
- }) {
157
- return { ...deps };
158
- }
159
-
160
- export function buildBncrAckOutboxRuntime(deps: {
161
- bridgeId: string;
162
- pushEvent: string;
163
- now: () => number;
164
- asString: (value: unknown, fallback?: string) => string;
165
- backoffMs: (retryCount: number) => number;
166
- isPlainObject: (value: unknown) => value is Record<string, unknown>;
167
- clampFiniteNumber: (value: unknown, fallback: number, min?: number, max?: number) => number;
168
- normalizeAccountId: (accountId: string) => string;
169
- formatDisplayScope: (route: BncrRoute) => string;
170
- isFileTransferEntry: (entry: OutboxEntry) => boolean;
171
- recommendedAckTimeoutMaxMs: number;
172
- adaptiveAckTimeoutEnabled: boolean;
173
- defaultAckTimeoutMs: number;
174
- stopped: () => boolean;
175
- outbox: Map<string, OutboxEntry>;
176
- deadLetter: () => OutboxEntry[];
177
- connectionsValues: () => IterableIterator<BncrConnection>;
178
- gatewayContextAvailable: () => boolean;
179
- messageAckWaiters: Map<string, MessageAckWaiter>;
180
- fileAckWaiterCount: () => number;
181
- activeConnectionCount: (accountId: string) => number;
182
- getAccountPendingOutboxEntries: (accountId: string) => OutboxEntry[];
183
- pushDrainRunningAccounts: Set<string>;
184
- pushDrainRunningSinceByAccount: Map<string, number>;
185
- pushDrainStuckWarnedAtByAccount: Map<string, number>;
186
- isOnline: (accountId: string) => boolean;
187
- hasRecentInboundReachability: (accountId: string) => boolean;
188
- isOutboundAckRequired: (accountId?: string) => boolean;
189
- resolveMessageAckTimeoutMs: (accountId: string) => number;
190
- waitForMessageAck: (messageId: string, waitMs: number) => Promise<'acked' | 'timeout'>;
191
- resolvePushConnIds: (accountId: string) => Iterable<string>;
192
- sleepMs: (ms: number) => Promise<void>;
193
- schedulePushDrain: (delayMs: number) => void;
194
- tryPushEntry: (entry: OutboxEntry) => Promise<boolean>;
195
- handleFileTransferPushFailure: (args: { entry: OutboxEntry; error: unknown }) => void;
196
- handleTextPushFailure: (args: { entry: OutboxEntry; error: unknown }) => void;
197
- isPrePushGuardDeferral: (entry: OutboxEntry) => boolean;
198
- scheduleSave: () => void;
199
- logInfo: (scope: string | undefined, message: string, options?: { debugOnly?: boolean }) => void;
200
- logWarn: (scope: string | undefined, message: string, options?: { debugOnly?: boolean }) => void;
201
- logError: (scope: string, message: string) => void;
202
- observeLease: (
203
- kind:
204
- | 'connect'
205
- | 'inbound'
206
- | 'activity'
207
- | 'ack'
208
- | 'file.init'
209
- | 'file.chunk'
210
- | 'file.complete'
211
- | 'file.abort',
212
- payload: Record<string, unknown>,
213
- ) => { stale: boolean };
214
- rememberGatewayContext: (context: GatewayRequestHandlerOptions['context']) => void;
215
- markSeen: (accountId: string, connId: string, clientId?: string) => void;
216
- markOutboundCapability: (args: {
217
- accountId: string;
218
- connId: string;
219
- clientId?: string;
220
- outboundReady: boolean;
221
- preferredForOutbound: boolean;
222
- }) => void;
223
- recordAckOkTelemetry: (args: {
224
- accountId: string;
225
- entry: OutboxEntry;
226
- telemetryPatch: { queueLatencyMs?: number; pushLatencyMs?: number; lateAfterTimeout?: boolean };
227
- }) => void;
228
- deleteOutboxEntry: (messageId: string) => void;
229
- setOutboxEntry: (messageId: string, entry: OutboxEntry) => void;
230
- resolveMessageAck: (messageId: string, result: 'acked' | 'timeout') => boolean;
231
- moveToDeadLetter: (entry: OutboxEntry, reason: string) => void;
232
- recordAckTimeoutTelemetry: (accountId: string) => void;
233
- degradeOutboundCapability: (args: {
234
- accountId: string;
235
- connId?: string;
236
- clientId?: string;
237
- reason: string;
238
- }) => void;
239
- flushPushQueueBestEffort: (args?: {
240
- accountId?: string;
241
- trigger?: string;
242
- reason?: string;
243
- }) => void;
244
- flushTriggerTimer: string;
245
- flushReasonScheduledDrain: string;
246
- outboundFlushTriggerAckOk: string;
247
- outboundFlushReasonMessageAcked: string;
248
- pushDrainExceptionRetryLimit: number;
249
- pushDrainExceptionRetryDelayMs: number;
250
- pushDrainStuckWarnMs: number;
251
- pushDrainIntervalMs: number;
252
- pushDrainAccountTimeBudgetMs: number;
253
- pushDrainAccountBudget: number;
254
- pushAckTimeoutMs: number;
255
- maxRetry: number;
256
- prePushGuardRetryDelayMs: number;
257
- }) {
258
- return { ...deps };
259
- }
260
-
261
- export function buildBncrOutboxPushRouteRuntime(deps: {
262
- bridgeId: string;
263
- pushEvent: string;
264
- now: () => number;
265
- connectTtlMs: number;
266
- finiteNumberOr: (value: unknown, fallback: number) => number;
267
- outboxSize: () => number;
268
- gatewayBroadcastToConnIds: (
269
- event: string,
270
- payload: unknown,
271
- connIds: ReadonlySet<string>,
272
- ) => void;
273
- recordOutboxPushSuccess: (args: {
274
- entry: OutboxEntry;
275
- connIds: Iterable<string>;
276
- ownerConnId?: string;
277
- ownerClientId?: string;
278
- clearLastError?: boolean;
279
- }) => void;
280
- recordOutboxPushFailure: (args: {
281
- entry: OutboxEntry;
282
- error: unknown;
283
- fallbackError: string;
284
- persist?: boolean;
285
- }) => void;
286
- recordOutboxPrePushFailure: (args: {
287
- entry: OutboxEntry;
288
- lastError: string;
289
- persist?: boolean;
290
- }) => void;
291
- recordPrePushGuardSkip: (args: { accountId: string; reason: string }) => void;
292
- moveToDeadLetter: (entry: OutboxEntry, reason: string) => void;
293
- activeConnectionCount: (accountId: string) => number;
294
- connections: Map<string, BncrConnection>;
295
- connectionsValues: () => Iterable<BncrConnection>;
296
- activeConnectionByAccount: Map<string, string>;
297
- resolveRecentInboundConnIds: (accountId: string) => Set<string>;
298
- connectionKey: (accountId: string, clientId?: string) => string;
299
- isRetryableFileTransferError: (value: unknown) => boolean;
300
- logInfo: (scope: string, message: string, options?: { debugOnly?: boolean }) => void;
301
- buildActiveConnectionDebugList: (
302
- accountId: string,
303
- options?: { includeOutboundState?: boolean },
304
- ) => BncrActiveConnectionDebugEntry[];
305
- }) {
306
- return { ...deps };
307
- }
308
-
309
- export function buildBncrMediaOrchestratorsRuntime(deps: {
310
- now: () => number;
311
- asString: (value: unknown, fallback?: string) => string;
312
- fileSendTransfers: Map<string, FileSendTransferState>;
313
- getGatewayContext: () => GatewayRequestHandlerOptions['context'] | null;
314
- fileInitEvent: string;
315
- fileAbortEvent: string;
316
- prepareOutboundTransfer: BncrFileTransferOrchestratorRuntime['prepareOutboundTransfer'];
317
- sendChunk: BncrFileTransferOrchestratorRuntime['sendChunk'];
318
- sendComplete: BncrFileTransferOrchestratorRuntime['sendComplete'];
319
- waitForFileAck: BncrFileTransferOrchestratorRuntime['waitForFileAck'];
320
- logFileTransferChunkAck: BncrFileTransferOrchestratorRuntime['logFileTransferChunkAck'];
321
- logFileTransferChunkAckFail: BncrFileTransferOrchestratorRuntime['logFileTransferChunkAckFail'];
322
- logFileTransferCompleteAck: BncrFileTransferOrchestratorRuntime['logFileTransferCompleteAck'];
323
- logInfo: (scope: string | undefined, message: string, options?: { debugOnly?: boolean }) => void;
324
- logEnqueueFromReply: (args: {
325
- accountId: string;
326
- sessionKey: string;
327
- route: BncrRoute;
328
- payload: NormalizedReplyPayload;
329
- }) => void;
330
- enqueueOutbound: (entry: OutboxEntry) => void;
331
- buildTextOutboxEntry: (args: {
332
- accountId: string;
333
- sessionKey: string;
334
- route: BncrRoute;
335
- text: string;
336
- extra?: Record<string, unknown>;
337
- kind?: 'tool' | 'block' | 'final';
338
- replyToId?: string;
339
- replyTargetPolicy?: OutboundReplyTargetPolicy;
340
- }) => OutboxEntry;
341
- buildFileTransferOutboxEntry: (args: {
342
- accountId: string;
343
- sessionKey: string;
344
- route: BncrRoute;
345
- mediaUrl: string;
346
- mediaLocalRoots?: readonly string[];
347
- text: string;
348
- asVoice: boolean;
349
- audioAsVoice: boolean;
350
- type?: string;
351
- extra?: Record<string, unknown>;
352
- kind?: 'tool' | 'block' | 'final';
353
- replyToId?: string;
354
- replyTargetPolicy?: OutboundReplyTargetPolicy;
355
- downloadMedia?: boolean;
356
- }) => OutboxEntry;
357
- rememberRecentMediaSend: (args: {
358
- sessionKey: string;
359
- mediaUrl: string;
360
- text: string;
361
- replyToId: string;
362
- createdAt: number;
363
- }) => void;
364
- tryBuildMediaDedupeFallback: (args: {
365
- sessionKey: string;
366
- mediaUrl: string;
367
- text: string;
368
- replyToId: string;
369
- currentTime: number;
370
- }) => {
371
- text: string;
372
- reason: 'same-text-sent-checkmark' | 'text-changed-downgrade';
373
- } | null;
374
- }) {
375
- return {
376
- ...deps,
377
- getGatewayContext: () => {
378
- const context = deps.getGatewayContext();
379
- if (!context) return null;
380
- return {
381
- broadcastToConnIds: (event: string, payload: unknown, connIds: ReadonlySet<string>) =>
382
- context.broadcastToConnIds(event, payload, connIds),
383
- };
384
- },
385
- };
386
- }
387
-
388
28
  export function buildBncrInboundSurfaceRuntime(deps: {
389
29
  getApi: Parameters<typeof createBncrInboundHandlersComponent>[0]['getApi'];
390
30
  channelId: string;
@@ -1,24 +1,17 @@
1
1
  import type { GatewayRequestHandlerOptions } from 'openclaw/plugin-sdk/core';
2
2
  import type { BncrExtendedDiagnostics } from '../core/extended-diagnostics.ts';
3
- import type { RegisterTraceSummary } from '../core/register-trace.ts';
4
3
  import type {
5
4
  BncrAccountRuntimeSnapshot,
6
5
  buildIntegratedDiagnostics as buildIntegratedDiagnosticsFromRuntime,
7
6
  } from '../core/status.ts';
8
7
  import type {
9
- BncrAckObservability,
10
- BncrConnection,
11
8
  BncrDeadLetterDiagnosticsSummary,
12
- BncrDiagnosticsSummary,
13
9
  BncrDownlinkHealthSummary,
14
- BncrOutboxQueueDiagnostics,
15
- BncrRoute,
16
10
  FileSendTransferState,
17
11
  OutboxEntry,
18
12
  } from '../core/types.ts';
19
13
  import type { BncrRuntimeFlags } from '../runtime/outbound-flags.ts';
20
14
  import type { createBncrBridgeDiagnosticsHandlersComponent } from './channel-components.ts';
21
- import type { BncrChannelConfigRoot } from './channel-runtime-types.ts';
22
15
  import type {
23
16
  ConnectionQueueCounters,
24
17
  FileAckPayload,
@@ -37,9 +30,6 @@ type DiagnosticsRuntimeStatusOverrides = {
37
30
  legacyAccountResidue?: number;
38
31
  };
39
32
 
40
- type StoredRouteRecord = { accountId: string; route: BncrRoute; updatedAt: number };
41
- type StoredLastSessionRecord = { sessionKey: string; scope: string; updatedAt: number };
42
-
43
33
  // Status/diagnostics-side wiring catalog.
44
34
  //
45
35
  // Order is intentional:
@@ -179,153 +169,3 @@ export function buildBncrBridgeSurfaceHandlersRuntime(deps: {
179
169
  }) {
180
170
  return { ...deps };
181
171
  }
182
-
183
- export function buildBncrTargetStatusRuntime(deps: {
184
- api: unknown;
185
- channelId: string;
186
- canonicalAgentId: string | null;
187
- getPluginRoot: () => string | null;
188
- startedAt: number;
189
- debugVerbose: boolean;
190
- adaptiveAckTimeoutEnabled: boolean;
191
- defaultMessageAckTimeoutMs: number;
192
- fileAckTimeoutMs: number;
193
- maxAckTimeoutMs: number;
194
- now: () => number;
195
- normalizeAccountId: (accountId: string) => string;
196
- sessionRoutes: Map<string, StoredRouteRecord>;
197
- routeAliases: Map<string, StoredRouteRecord>;
198
- lastSessionByAccount: Map<string, StoredLastSessionRecord>;
199
- markActivity: (accountId: string, at?: number) => void;
200
- scheduleSave: () => void;
201
- logInfo: (scope: string | undefined, message: string, options?: { debugOnly?: boolean }) => void;
202
- logWarn: (scope: string | undefined, message: string, options?: { debugOnly?: boolean }) => void;
203
- ensureCanonicalAgentId: (args: {
204
- cfg: BncrChannelConfigRoot;
205
- accountId: string;
206
- peer?: unknown;
207
- channelId?: string;
208
- }) => string;
209
- recentMediaDedupeBySession: Map<string, Map<string, unknown>>;
210
- resolveMessageAckTimeoutMs: (accountId?: string) => number;
211
- isOnline: (accountId: string) => boolean;
212
- outboxValues: () => Iterable<OutboxEntry>;
213
- deadLetterEntries: () => OutboxEntry[];
214
- sessionRouteValues: () => Iterable<{ accountId: string }>;
215
- countInvalidOutboxSessionKeys: (accountId: string) => number;
216
- countLegacyAccountResidue: (accountId: string) => number;
217
- connectEventsByAccount: Map<string, number>;
218
- inboundEventsByAccount: Map<string, number>;
219
- activityEventsByAccount: Map<string, number>;
220
- ackEventsByAccount: Map<string, number>;
221
- activeConnectionCount: (accountId: string) => number;
222
- lastActivityByAccount: Map<string, number>;
223
- lastInboundByAccount: Map<string, number>;
224
- lastOutboundByAccount: Map<string, number>;
225
- buildRuntimeAckObservability: (accountId: string) => BncrAckObservability;
226
- buildRuntimeAckStrategy: (ackObservability: BncrAckObservability) => {
227
- timeoutMs: number;
228
- reason:
229
- | 'static-default'
230
- | 'adaptive-disabled'
231
- | 'invalid-observability'
232
- | 'late-ack-observed'
233
- | 'capped-max';
234
- };
235
- lastAckOkByAccount: Map<string, number>;
236
- lastAckTimeoutByAccount: Map<string, number>;
237
- getAckTimeoutCount: (accountId: string) => number;
238
- getAccountPendingOutboxEntries: (accountId: string) => OutboxEntry[];
239
- getAccountDeadLetterEntries: (accountId: string) => OutboxEntry[];
240
- connectionsValues: () => Iterable<{ lastSeenAt: number }>;
241
- connectTtlMs: number;
242
- }) {
243
- return { ...deps };
244
- }
245
-
246
- export function buildBncrDiagnosticsSelectionRuntime(deps: {
247
- normalizeAccountId: (accountId: string) => string;
248
- outboxValues: () => Iterable<OutboxEntry>;
249
- getDeadLetterEntries: () => OutboxEntry[];
250
- connectionsValues: () => Iterable<BncrConnection>;
251
- }) {
252
- return { ...deps };
253
- }
254
-
255
- export function buildBncrOutboxDiagnosticsRuntime(deps: {
256
- normalizeAccountId: (accountId: string) => string;
257
- outboxValues: () => Iterable<OutboxEntry>;
258
- pendingAllAccounts: () => number;
259
- resolvePushConnIds: (accountId: string) => Set<string>;
260
- }) {
261
- return { ...deps };
262
- }
263
-
264
- export function buildBncrRuntimeAckObservabilityRuntime(deps: {
265
- normalizeAccountId: (accountId: string) => string;
266
- getCounter: (map: Map<string, number>, accountId: string) => number;
267
- ackTimeoutCountByAccount: Map<string, number>;
268
- lateAckOkCountByAccount: Map<string, number>;
269
- lastLateAckPushLatencyMsByAccount: Map<string, number>;
270
- lastLateAckOkByAccount: Map<string, number>;
271
- adaptiveAckRecoveryOkCountByAccount: Map<string, number>;
272
- lastAckOkByAccount: Map<string, number>;
273
- lastAckTimeoutByAccount: Map<string, number>;
274
- lastAckQueueLatencyMsByAccount: Map<string, number>;
275
- lastAckPushLatencyMsByAccount: Map<string, number>;
276
- lastLateAckQueueLatencyMsByAccount: Map<string, number>;
277
- adaptiveAckTimeoutEnabled: boolean;
278
- defaultAckTimeoutMs: number;
279
- resolveMessageAckTimeoutMs: (accountId: string) => number;
280
- minAckTimeoutMs: number;
281
- maxAckTimeoutMs: number;
282
- lateAckObservationTtlMs: number;
283
- recoveryOkThreshold: number;
284
- now: () => number;
285
- }) {
286
- return { ...deps };
287
- }
288
-
289
- export function buildBncrDeadLetterDiagnosticsRuntime(deps: {
290
- normalizeAccountId: (accountId: string) => string;
291
- getDeadLetterEntries: () => OutboxEntry[];
292
- maxDeadLetterEntries: number;
293
- getCounter: (map: Map<string, number>, accountId: string) => number;
294
- deadLetterSinceStartByAccount: Map<string, number>;
295
- getAccountDeadLetterEntries: (accountId: string) => OutboxEntry[];
296
- logInfo: (scope: string, message: string, options?: { debugOnly?: boolean }) => void;
297
- logInfoDedup: (
298
- scope: string,
299
- message: string,
300
- options: { key: string; sig: string; windowMs?: number },
301
- ) => void;
302
- }) {
303
- return { ...deps };
304
- }
305
-
306
- export function buildBncrExtendedDiagnosticsAssemblerRuntime(deps: {
307
- normalizeAccountId: (accountId: string) => string;
308
- buildIntegratedDiagnostics: (
309
- accountId: string,
310
- runtimeStatusInput?: Parameters<typeof buildIntegratedDiagnosticsFromRuntime>[0],
311
- ) => BncrDiagnosticsSummary;
312
- buildOutboxDiagnostics: (accountId: string) => BncrOutboxQueueDiagnostics;
313
- buildRuntimeAckObservability: (accountId: string) => BncrAckObservability;
314
- getCounter: (map: Map<string, number>, accountId: string) => number;
315
- prePushGuardSkipCountByAccount: Map<string, number>;
316
- lastPrePushGuardSkipAtByAccount: Map<string, number>;
317
- lastPrePushGuardSkipReasonByAccount: Map<string, string>;
318
- hasGatewayContext: () => boolean;
319
- buildRuntimeSurfaceDiagnostics: () => Record<string, unknown>;
320
- getRegisterRuntime: () => Record<string, unknown>;
321
- buildRegisterTraceSummary: () => RegisterTraceSummary;
322
- activeConnectionCount: (accountId: string) => number;
323
- getConnectionRuntime: () => Record<string, unknown>;
324
- getOutboundRuntime: () => Record<string, unknown>;
325
- buildDeadLetterDiagnostics: (accountId: string) => BncrDeadLetterDiagnosticsSummary;
326
- bridgeVersion: number;
327
- staleCounters: Record<string, number>;
328
- now: () => number;
329
- }) {
330
- return { ...deps };
331
- }
@@ -1,25 +1,11 @@
1
1
  // Aggregated runtime wiring entrypoint.
2
2
  //
3
- // Delivery and status/diagnostics slices now live in dedicated files so the
4
- // bridge wiring catalog stays readable without changing import sites.
3
+ // Only builders actively called from channel.ts are kept here.
4
+ // Dead builder projections have been removed.
5
5
 
6
6
  export {
7
- buildBncrAckOutboxRuntime,
8
7
  buildBncrChannelSendRuntime,
9
- buildBncrConnectionStateRuntime,
10
- buildBncrFileTransferRuntime,
11
8
  buildBncrInboundSurfaceRuntime,
12
- buildBncrMediaOrchestratorsRuntime,
13
- buildBncrOutboxPushRouteRuntime,
14
- buildBncrStateTransientRuntime,
15
9
  } from './channel-runtime-builders-delivery.ts';
16
10
 
17
- export {
18
- buildBncrBridgeSurfaceHandlersRuntime,
19
- buildBncrDeadLetterDiagnosticsRuntime,
20
- buildBncrDiagnosticsSelectionRuntime,
21
- buildBncrExtendedDiagnosticsAssemblerRuntime,
22
- buildBncrOutboxDiagnosticsRuntime,
23
- buildBncrRuntimeAckObservabilityRuntime,
24
- buildBncrTargetStatusRuntime,
25
- } from './channel-runtime-builders-status.ts';
11
+ export { buildBncrBridgeSurfaceHandlersRuntime } from './channel-runtime-builders-status.ts';