@xmoxmo/bncr 0.3.6 → 0.3.8

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 (165) hide show
  1. package/README.md +5 -0
  2. package/dist/index.js +28 -5
  3. package/index.ts +55 -721
  4. package/openclaw.plugin.json +1 -0
  5. package/package.json +8 -4
  6. package/scripts/check-pack.mjs +93 -18
  7. package/scripts/check-register-drift.mjs +35 -13
  8. package/scripts/selfcheck.mjs +80 -11
  9. package/src/bootstrap/channel-plugin-runtime.ts +81 -0
  10. package/src/bootstrap/cli.ts +97 -0
  11. package/src/bootstrap/register-runtime-gateway.ts +129 -0
  12. package/src/bootstrap/register-runtime-helpers.ts +140 -0
  13. package/src/bootstrap/register-runtime-singleton.ts +137 -0
  14. package/src/bootstrap/register-runtime.ts +201 -0
  15. package/src/bootstrap/runtime-discovery.ts +187 -0
  16. package/src/bootstrap/runtime-loader.ts +54 -0
  17. package/src/channel.ts +1590 -4967
  18. package/src/core/accounts.ts +23 -4
  19. package/src/core/dead-letter-diagnostics.ts +37 -5
  20. package/src/core/diagnostics.ts +31 -15
  21. package/src/core/downlink-health.ts +3 -11
  22. package/src/core/extended-diagnostics.ts +78 -36
  23. package/src/core/file-transfer-payloads.ts +1 -1
  24. package/src/core/logging.ts +1 -0
  25. package/src/core/outbox-enqueue.ts +13 -2
  26. package/src/core/outbox-entry-builders.ts +2 -0
  27. package/src/core/outbox-summary.ts +75 -3
  28. package/src/core/permissions.ts +15 -2
  29. package/src/core/persisted-outbox-entry.ts +21 -6
  30. package/src/core/policy.ts +45 -4
  31. package/src/core/probe.ts +3 -15
  32. package/src/core/register-trace.ts +3 -3
  33. package/src/core/status.ts +43 -4
  34. package/src/core/targets.ts +216 -205
  35. package/src/core/types.ts +221 -0
  36. package/src/core/value-sanitize.ts +29 -0
  37. package/src/messaging/inbound/commands.ts +147 -172
  38. package/src/messaging/inbound/context-facts.ts +4 -2
  39. package/src/messaging/inbound/contracts.ts +70 -0
  40. package/src/messaging/inbound/dispatch-prep.ts +303 -0
  41. package/src/messaging/inbound/dispatch.ts +49 -462
  42. package/src/messaging/inbound/gate.ts +18 -5
  43. package/src/messaging/inbound/last-route.ts +10 -4
  44. package/src/messaging/inbound/media-url-download.ts +109 -0
  45. package/src/messaging/inbound/native-command-runtime.ts +225 -0
  46. package/src/messaging/inbound/parse.ts +2 -1
  47. package/src/messaging/inbound/remote-media.ts +49 -0
  48. package/src/messaging/inbound/reply-config.ts +16 -4
  49. package/src/messaging/inbound/reply-dispatch.ts +162 -0
  50. package/src/messaging/inbound/runtime-compat.ts +31 -10
  51. package/src/messaging/inbound/session-label.ts +15 -7
  52. package/src/messaging/inbound/turn-context.ts +131 -0
  53. package/src/messaging/outbound/actions.ts +24 -10
  54. package/src/messaging/outbound/diagnostics-debug-builders.ts +365 -0
  55. package/src/messaging/outbound/diagnostics.ts +31 -355
  56. package/src/messaging/outbound/durable-message-adapter.ts +20 -16
  57. package/src/messaging/outbound/durable-queue-adapter.ts +20 -7
  58. package/src/messaging/outbound/media.ts +24 -13
  59. package/src/messaging/outbound/reply-enqueue-media.ts +181 -0
  60. package/src/messaging/outbound/reply-enqueue.ts +46 -155
  61. package/src/messaging/outbound/send-params.ts +3 -0
  62. package/src/messaging/outbound/send.ts +19 -10
  63. package/src/messaging/outbound/session-route.ts +18 -3
  64. package/src/openclaw/channel-runtime-contracts.ts +76 -0
  65. package/src/openclaw/config-runtime.ts +13 -7
  66. package/src/openclaw/inbound-session-runtime.ts +7 -3
  67. package/src/openclaw/ingress-runtime.ts +17 -27
  68. package/src/openclaw/reply-runtime.ts +54 -59
  69. package/src/openclaw/routing-runtime.ts +35 -18
  70. package/src/openclaw/runtime-surface.ts +156 -12
  71. package/src/openclaw/sdk-helpers.ts +8 -1
  72. package/src/openclaw/session-route-runtime.ts +12 -12
  73. package/src/plugin/ack-outbox-runtime-group.ts +264 -0
  74. package/src/plugin/bridge-ack-facade.ts +137 -0
  75. package/src/plugin/bridge-connection-facade.ts +111 -0
  76. package/src/plugin/bridge-diagnostics-facade.ts +23 -0
  77. package/src/plugin/bridge-drain-facade.ts +98 -0
  78. package/src/plugin/bridge-extended-diagnostics-facade.ts +149 -0
  79. package/src/plugin/bridge-file-transfer-push-facade.ts +140 -0
  80. package/src/plugin/bridge-lifecycle.ts +156 -0
  81. package/src/plugin/bridge-media-facade.ts +241 -0
  82. package/src/plugin/bridge-outbox-facade.ts +182 -0
  83. package/src/plugin/bridge-runtime-helpers.ts +266 -0
  84. package/src/plugin/bridge-runtime-snapshots.ts +104 -0
  85. package/src/plugin/bridge-runtime-surface-facade.ts +8 -0
  86. package/src/plugin/bridge-status-facade.ts +76 -0
  87. package/src/plugin/bridge-status-worker-facade.ts +72 -0
  88. package/src/plugin/bridge-support-runtime.ts +137 -0
  89. package/src/plugin/bridge-surface-handlers-group.ts +242 -0
  90. package/src/plugin/bridge-surface-helpers.ts +28 -0
  91. package/src/plugin/capabilities.ts +1 -3
  92. package/src/plugin/channel-components.ts +289 -0
  93. package/src/plugin/channel-inbound-helpers.ts +149 -0
  94. package/src/plugin/channel-plugin-bridge-group.ts +129 -0
  95. package/src/plugin/channel-plugin-surface-group.ts +202 -0
  96. package/src/plugin/channel-runtime-builders-delivery.ts +513 -0
  97. package/src/plugin/channel-runtime-builders-status.ts +331 -0
  98. package/src/plugin/channel-runtime-builders.ts +25 -0
  99. package/src/plugin/channel-runtime-constants.ts +40 -0
  100. package/src/plugin/channel-runtime-types.ts +146 -0
  101. package/src/plugin/channel-send-runtime-group.ts +37 -0
  102. package/src/plugin/channel-send.ts +226 -0
  103. package/src/plugin/channel-utils.ts +102 -0
  104. package/src/plugin/config.ts +24 -3
  105. package/src/plugin/connection-handlers-helpers.ts +254 -0
  106. package/src/plugin/connection-handlers.ts +440 -0
  107. package/src/plugin/connection-state-helpers.ts +159 -0
  108. package/src/plugin/connection-state-runtime-group.ts +51 -0
  109. package/src/plugin/connection-state.ts +527 -0
  110. package/src/plugin/diagnostics-handlers.ts +211 -0
  111. package/src/plugin/error-message.ts +15 -0
  112. package/src/plugin/file-ack-runtime.ts +284 -0
  113. package/src/plugin/file-inbound-abort.ts +112 -0
  114. package/src/plugin/file-inbound-chunk.ts +146 -0
  115. package/src/plugin/file-inbound-complete.ts +153 -0
  116. package/src/plugin/file-inbound-handlers.ts +19 -0
  117. package/src/plugin/file-inbound-init.ts +122 -0
  118. package/src/plugin/file-inbound-runtime.ts +51 -0
  119. package/src/plugin/file-inbound-state.ts +62 -0
  120. package/src/plugin/file-transfer-logs.ts +227 -0
  121. package/src/plugin/file-transfer-orchestrator-chunk.ts +135 -0
  122. package/src/plugin/file-transfer-orchestrator.ts +304 -0
  123. package/src/plugin/file-transfer-runtime-group.ts +102 -0
  124. package/src/plugin/file-transfer-send.ts +89 -0
  125. package/src/plugin/file-transfer-setup.ts +206 -0
  126. package/src/plugin/gateway-event-context.ts +41 -0
  127. package/src/plugin/gateway-runtime.ts +17 -4
  128. package/src/plugin/inbound-acceptance.ts +107 -0
  129. package/src/plugin/inbound-handlers.ts +248 -0
  130. package/src/plugin/inbound-surface-handlers-group.ts +152 -0
  131. package/src/plugin/media-dedupe-runtime.ts +90 -0
  132. package/src/plugin/media-orchestrators-runtime-group.ts +316 -0
  133. package/src/plugin/message-ack-runtime.ts +284 -0
  134. package/src/plugin/message-send.ts +16 -6
  135. package/src/plugin/messaging.ts +98 -36
  136. package/src/plugin/outbound.ts +50 -8
  137. package/src/plugin/outbox-ack-logs.ts +136 -0
  138. package/src/plugin/outbox-ack-outcome.ts +128 -0
  139. package/src/plugin/outbox-drain-ack.ts +145 -0
  140. package/src/plugin/outbox-drain-failure.ts +84 -0
  141. package/src/plugin/outbox-drain-loop.ts +554 -0
  142. package/src/plugin/outbox-drain-post-push.ts +159 -0
  143. package/src/plugin/outbox-drain-runtime.ts +141 -0
  144. package/src/plugin/outbox-drain-schedule.ts +116 -0
  145. package/src/plugin/outbox-file-push-flow.ts +69 -0
  146. package/src/plugin/outbox-push-route-runtime-group.ts +81 -0
  147. package/src/plugin/outbox-push.ts +267 -0
  148. package/src/plugin/outbox-route.ts +181 -0
  149. package/src/plugin/outbox-text-push-flow.ts +90 -0
  150. package/src/plugin/runtime-diagnostics-assembler.ts +183 -0
  151. package/src/plugin/runtime-diagnostics-helpers.ts +302 -0
  152. package/src/plugin/runtime-diagnostics-payload-builders.ts +171 -0
  153. package/src/plugin/runtime-diagnostics-snapshot.ts +31 -0
  154. package/src/plugin/setup.ts +33 -6
  155. package/src/plugin/state-store.ts +249 -0
  156. package/src/plugin/state-transient-runtime-group.ts +105 -0
  157. package/src/plugin/status-runtime.ts +251 -0
  158. package/src/plugin/status.ts +33 -7
  159. package/src/plugin/target-runtime.ts +141 -0
  160. package/src/plugin/target-status-runtime-group.ts +130 -0
  161. package/src/plugin/transient-state-runtime.ts +82 -0
  162. package/src/runtime/outbound-ack-timeout.ts +5 -3
  163. package/src/runtime/outbound-flags.ts +24 -8
  164. package/src/runtime/status-snapshots.ts +36 -7
  165. package/src/runtime/status-worker.ts +34 -4
@@ -0,0 +1,331 @@
1
+ import type { GatewayRequestHandlerOptions } from 'openclaw/plugin-sdk/core';
2
+ import type { BncrExtendedDiagnostics } from '../core/extended-diagnostics.ts';
3
+ import type { RegisterTraceSummary } from '../core/register-trace.ts';
4
+ import type {
5
+ BncrAccountRuntimeSnapshot,
6
+ buildIntegratedDiagnostics as buildIntegratedDiagnosticsFromRuntime,
7
+ } from '../core/status.ts';
8
+ import type {
9
+ BncrAckObservability,
10
+ BncrConnection,
11
+ BncrDeadLetterDiagnosticsSummary,
12
+ BncrDiagnosticsSummary,
13
+ BncrDownlinkHealthSummary,
14
+ BncrOutboxQueueDiagnostics,
15
+ BncrRoute,
16
+ FileSendTransferState,
17
+ OutboxEntry,
18
+ } from '../core/types.ts';
19
+ import type { BncrRuntimeFlags } from '../runtime/outbound-flags.ts';
20
+ import type { createBncrBridgeDiagnosticsHandlersComponent } from './channel-components.ts';
21
+ import type { BncrChannelConfigRoot } from './channel-runtime-types.ts';
22
+ import type {
23
+ ConnectionQueueCounters,
24
+ FileAckPayload,
25
+ LeaseEventPayload,
26
+ PreparedAckHandling,
27
+ } from './connection-handlers.ts';
28
+
29
+ type DiagnosticsRuntimeStatusInput = Parameters<typeof buildIntegratedDiagnosticsFromRuntime>[0] & {
30
+ running: boolean | undefined;
31
+ channelRoot: string;
32
+ };
33
+
34
+ type DiagnosticsRuntimeStatusOverrides = {
35
+ running: boolean;
36
+ invalidOutboxSessionKeys?: number;
37
+ legacyAccountResidue?: number;
38
+ };
39
+
40
+ type StoredRouteRecord = { accountId: string; route: BncrRoute; updatedAt: number };
41
+ type StoredLastSessionRecord = { sessionKey: string; scope: string; updatedAt: number };
42
+
43
+ // Status/diagnostics-side wiring catalog.
44
+ //
45
+ // Order is intentional:
46
+ // 1) gateway-adjacent diagnostics host surfaces
47
+ // 2) persistence/status read-model slices
48
+ // 3) diagnostics assembly slices
49
+
50
+ export function buildBncrBridgeSurfaceHandlersRuntime(deps: {
51
+ bridgeId: string;
52
+ gatewayPid: number;
53
+ pushEvent: string;
54
+ bridgeVersion: number;
55
+ getApi: Parameters<typeof createBncrBridgeDiagnosticsHandlersComponent>[0]['getApi'];
56
+ channelId: string;
57
+ asString: (value: unknown, fallback?: string) => string;
58
+ now: () => number;
59
+ finiteNonNegativeNumberOrNull: (value: unknown) => number | null;
60
+ syncDebugFlag: () => Promise<void>;
61
+ logInfo: (scope: string, message: string, options?: { debugOnly?: boolean }) => void;
62
+ logWarn: (scope: string, message: string, options?: { debugOnly?: boolean }) => void;
63
+ normalizeAccountId: (value: string) => string;
64
+ pluginRoot: string;
65
+ buildAccountQueueCounters: (accountId: string) => ConnectionQueueCounters;
66
+ buildExtendedDiagnostics: (
67
+ accountId: string,
68
+ args?: Record<string, unknown>,
69
+ ) => BncrExtendedDiagnostics;
70
+ buildRuntimeFlags: (accountId: string) => BncrRuntimeFlags;
71
+ buildRuntimeStatusInput: (
72
+ accountId: string,
73
+ overrides: DiagnosticsRuntimeStatusOverrides,
74
+ ) => DiagnosticsRuntimeStatusInput;
75
+ getAccountRuntimeSnapshot: (
76
+ accountId: string,
77
+ runtimeStatusInput: DiagnosticsRuntimeStatusInput,
78
+ ) => BncrAccountRuntimeSnapshot;
79
+ buildIntegratedDiagnostics: (
80
+ accountId: string,
81
+ runtimeStatusInput: DiagnosticsRuntimeStatusInput,
82
+ ) => ReturnType<typeof buildIntegratedDiagnosticsFromRuntime>;
83
+ buildDownlinkHealth: (accountId: string) => BncrDownlinkHealthSummary;
84
+ isPrimaryConnection: (accountId: string, clientId?: string) => boolean;
85
+ acceptConnection: () => { leaseId: string; connectionEpoch: number; acceptedAt: number };
86
+ refreshLiveConnectionState: (args: {
87
+ accountId: string;
88
+ connId: string;
89
+ clientId?: string;
90
+ outboundReady: boolean;
91
+ preferredForOutbound: boolean;
92
+ inboundOnly: boolean;
93
+ context: GatewayRequestHandlerOptions['context'];
94
+ }) => void;
95
+ flushOnConnect: (accountId: string) => void;
96
+ flushOnActivity: (accountId: string) => void;
97
+ shouldIgnoreStaleEvent: (args: {
98
+ kind:
99
+ | 'activity'
100
+ | 'ack'
101
+ | 'file.init'
102
+ | 'file.chunk'
103
+ | 'file.complete'
104
+ | 'file.abort'
105
+ | 'inbound';
106
+ payload: LeaseEventPayload;
107
+ accountId: string;
108
+ connId: string;
109
+ clientId?: string;
110
+ }) => boolean;
111
+ incrementConnectEvents: (accountId: string) => void;
112
+ incrementActivityEvents: (accountId: string) => void;
113
+ incrementAckEvents: (accountId: string) => void;
114
+ markLastActivityAt: () => void;
115
+ markLastAckAt: () => void;
116
+ messageAckWaiterCount: () => number;
117
+ fileAckWaiterCount: () => number;
118
+ prepareAckHandling: (args: {
119
+ params: GatewayRequestHandlerOptions['params'];
120
+ respond: GatewayRequestHandlerOptions['respond'];
121
+ client: GatewayRequestHandlerOptions['client'];
122
+ context: GatewayRequestHandlerOptions['context'];
123
+ }) => PreparedAckHandling | null;
124
+ handleAckOutcome: (
125
+ args: {
126
+ params: GatewayRequestHandlerOptions['params'];
127
+ respond: GatewayRequestHandlerOptions['respond'];
128
+ } & PreparedAckHandling,
129
+ ) => void;
130
+ fileSendTransfers: Map<string, FileSendTransferState>;
131
+ hasFileAckWaiter: (key: string) => boolean;
132
+ fileAckKey: (transferId: string, stage: string, chunkIndex?: number) => string;
133
+ observeLease: (
134
+ kind:
135
+ | 'connect'
136
+ | 'inbound'
137
+ | 'activity'
138
+ | 'ack'
139
+ | 'file.init'
140
+ | 'file.chunk'
141
+ | 'file.complete'
142
+ | 'file.abort',
143
+ payload: LeaseEventPayload,
144
+ ) => { stale: boolean };
145
+ tryAdoptTransferOwner: (args: {
146
+ accountId: string;
147
+ transfer: FileSendTransferState | undefined;
148
+ connId: string;
149
+ clientId?: string;
150
+ }) => boolean;
151
+ refreshAcceptedFileTransferLiveState: (args: {
152
+ accountId: string;
153
+ connId: string;
154
+ clientId?: string;
155
+ context: GatewayRequestHandlerOptions['context'];
156
+ }) => void;
157
+ resolveFileAck: (args: {
158
+ transferId: string;
159
+ stage: string;
160
+ chunkIndex?: number;
161
+ payload: FileAckPayload;
162
+ ok: boolean;
163
+ }) => void;
164
+ countInvalidOutboxSessionKeys: (accountId: string) => number;
165
+ countLegacyAccountResidue: (accountId: string) => number;
166
+ activeConnectionCount: (accountId: string) => number;
167
+ getMessageAckWaiterCount: () => number;
168
+ getFileAckWaiterCount: () => number;
169
+ filterDeadLetterEntries: (args: {
170
+ accountId: string;
171
+ reason?: string | null;
172
+ olderThan?: number | null;
173
+ }) => OutboxEntry[];
174
+ listDeadLetterEntries: () => OutboxEntry[];
175
+ buildDeadLetterDiagnostics: (accountId: string) => BncrDeadLetterDiagnosticsSummary;
176
+ replaceDeadLetterEntries: (nextEntries: OutboxEntry[]) => void;
177
+ scheduleSave: () => void;
178
+ logDeadLetterSummary: (accountId: string, args: { force: boolean; source: string }) => void;
179
+ }) {
180
+ return { ...deps };
181
+ }
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
+ }
@@ -0,0 +1,25 @@
1
+ // Aggregated runtime wiring entrypoint.
2
+ //
3
+ // Delivery and status/diagnostics slices now live in dedicated files so the
4
+ // bridge wiring catalog stays readable without changing import sites.
5
+
6
+ export {
7
+ buildBncrAckOutboxRuntime,
8
+ buildBncrChannelSendRuntime,
9
+ buildBncrConnectionStateRuntime,
10
+ buildBncrFileTransferRuntime,
11
+ buildBncrInboundSurfaceRuntime,
12
+ buildBncrMediaOrchestratorsRuntime,
13
+ buildBncrOutboxPushRouteRuntime,
14
+ buildBncrStateTransientRuntime,
15
+ } from './channel-runtime-builders-delivery.ts';
16
+
17
+ export {
18
+ buildBncrBridgeSurfaceHandlersRuntime,
19
+ buildBncrDeadLetterDiagnosticsRuntime,
20
+ buildBncrDiagnosticsSelectionRuntime,
21
+ buildBncrExtendedDiagnosticsAssemblerRuntime,
22
+ buildBncrOutboxDiagnosticsRuntime,
23
+ buildBncrRuntimeAckObservabilityRuntime,
24
+ buildBncrTargetStatusRuntime,
25
+ } from './channel-runtime-builders-status.ts';
@@ -0,0 +1,40 @@
1
+ export const BRIDGE_VERSION = 2;
2
+ export const BNCR_PUSH_EVENT = 'plugin.bncr.push';
3
+ export const BNCR_FILE_INIT_EVENT = 'plugin.bncr.file.init';
4
+ export const BNCR_FILE_CHUNK_EVENT = 'plugin.bncr.file.chunk';
5
+ export const BNCR_FILE_COMPLETE_EVENT = 'plugin.bncr.file.complete';
6
+ export const BNCR_FILE_ABORT_EVENT = 'plugin.bncr.file.abort';
7
+ export const CONNECT_TTL_MS = 120_000;
8
+ export const RECENT_INBOUND_SEND_WINDOW_MS = 60_000;
9
+ export const MAX_RETRY = 10;
10
+ export const MAX_DEAD_LETTER_ENTRIES = 1000;
11
+ export const MAX_SESSION_ROUTE_ENTRIES = 1000;
12
+ export const MAX_ACCOUNT_ACTIVITY_ENTRIES = 1000;
13
+ export const PUSH_DRAIN_INTERVAL_MS = 500;
14
+ export const PUSH_DRAIN_ACCOUNT_BUDGET = 5;
15
+ export const PUSH_DRAIN_ACCOUNT_TIME_BUDGET_MS = 2_000;
16
+ export const PUSH_DRAIN_EXCEPTION_RETRY_LIMIT = 3;
17
+ export const PUSH_DRAIN_EXCEPTION_RETRY_DELAY_MS = 1_000;
18
+ export const PUSH_DRAIN_STUCK_WARN_MS = 30_000;
19
+ export const PRE_PUSH_GUARD_RETRY_DELAY_MS = 1_000;
20
+ export const PUSH_ACK_TIMEOUT_MS = 30_000;
21
+ export const ADAPTIVE_ACK_TIMEOUT_DEFAULT_ENABLED = true;
22
+ export const RECOMMENDED_ACK_TIMEOUT_MIN_MS = PUSH_ACK_TIMEOUT_MS;
23
+ export const RECOMMENDED_ACK_TIMEOUT_MAX_MS = 90_000;
24
+ export const ADAPTIVE_ACK_TIMEOUT_OBSERVATION_TTL_MS = 60 * 60 * 1000;
25
+ export const ADAPTIVE_ACK_TIMEOUT_RECOVERY_OK_THRESHOLD = 3;
26
+ export const ADAPTIVE_ACK_TIMEOUT_LOG_THROTTLE_MS = 5 * 60 * 1000;
27
+ export const OUTBOUND_READY_TTL_MS = 30_000;
28
+ export const PREFERRED_OUTBOUND_TTL_MS = 12_000;
29
+ export const FILE_FORCE_CHUNK = true;
30
+ export const FILE_INLINE_THRESHOLD = 5 * 1024 * 1024;
31
+ export const FILE_CHUNK_SIZE = 256 * 1024;
32
+ export const INBOUND_FILE_TRANSFER_MAX_BYTES = 50 * 1024 * 1024;
33
+ export const INBOUND_FILE_TRANSFER_MAX_CHUNKS =
34
+ Math.ceil(INBOUND_FILE_TRANSFER_MAX_BYTES / FILE_CHUNK_SIZE) + 1;
35
+ export const FILE_ACK_TIMEOUT_MS = 30_000;
36
+ export const FILE_TRANSFER_ACK_TTL_MS = 30_000;
37
+ export const MAX_EARLY_FILE_ACKS = 1000;
38
+ export const FILE_TRANSFER_KEEP_MS = 6 * 60 * 60 * 1000;
39
+ export const FILE_TRANSFER_TERMINAL_KEEP_MS = 10 * 60 * 1000;
40
+ export const REGISTER_WARMUP_WINDOW_MS = 30_000;
@@ -0,0 +1,146 @@
1
+ import type { RegisterDriftSnapshot, RegisterTraceEntry } from '../core/register-trace.ts';
2
+ import type { BncrDiagnosticsSummary, BncrRoute, OutboxEntry } from '../core/types.ts';
3
+ import type { OpenClawChannelToolSend, openClawJsonResult } from '../openclaw/sdk-helpers.ts';
4
+
5
+ type OpenClawJsonResultPayload = ReturnType<typeof openClawJsonResult>;
6
+
7
+ export type BncrChannelConfigRoot = {
8
+ channels?: Record<string, BncrChannelConfigSection | undefined>;
9
+ };
10
+
11
+ export type BncrChannelConfigSection = {
12
+ enabled?: boolean;
13
+ name?: string;
14
+ debug?: {
15
+ verbose?: boolean;
16
+ };
17
+ accounts?: Record<string, BncrAccountConfig | undefined>;
18
+ outboundRequireAck?: boolean;
19
+ [key: string]: unknown;
20
+ };
21
+
22
+ export type BncrAccountConfig = {
23
+ enabled?: boolean;
24
+ name?: string;
25
+ [key: string]: unknown;
26
+ };
27
+
28
+ export type BncrPersistedSessionRoute = {
29
+ sessionKey: string;
30
+ accountId: string;
31
+ route: BncrRoute;
32
+ updatedAt: number;
33
+ };
34
+
35
+ export type BncrPersistedAccountTimestamp = {
36
+ accountId: string;
37
+ updatedAt: number;
38
+ };
39
+
40
+ export type BncrPersistedLastSession = {
41
+ accountId: string;
42
+ sessionKey: string;
43
+ scope: string;
44
+ updatedAt: number;
45
+ };
46
+
47
+ export type BncrStatusRuntimeSnapshot = {
48
+ connected?: boolean;
49
+ running?: boolean;
50
+ mode?: string;
51
+ pending?: number | null;
52
+ deadLetter?: number | null;
53
+ lastEventAt?: number | null;
54
+ lastError?: string | null;
55
+ lastSessionKey?: string | null;
56
+ lastSessionScope?: string | null;
57
+ lastSessionAt?: number | null;
58
+ lastActivityAt?: number | null;
59
+ lastInboundAt?: number | null;
60
+ lastOutboundAt?: number | null;
61
+ lastSessionAgo?: string | null;
62
+ lastActivityAgo?: string | null;
63
+ lastInboundAgo?: string | null;
64
+ lastOutboundAgo?: string | null;
65
+ diagnostics?: BncrDiagnosticsSummary | Record<string, unknown> | null;
66
+ meta?: Record<string, unknown> | null;
67
+ [key: string]: unknown;
68
+ };
69
+
70
+ export type BncrVerifiedTarget = {
71
+ sessionKey: string;
72
+ route: BncrRoute;
73
+ displayScope: string;
74
+ };
75
+
76
+ export type BncrChannelSendContext = {
77
+ accountId?: string | null;
78
+ to?: string;
79
+ text?: string;
80
+ mediaUrl?: string;
81
+ mediaUrls?: string[];
82
+ type?: string;
83
+ kind?: string;
84
+ replyToId?: string | null;
85
+ replyToMessageId?: string | null;
86
+ asVoice?: boolean;
87
+ audioAsVoice?: boolean;
88
+ mediaLocalRoots?: readonly string[];
89
+ payload?: Record<string, unknown>;
90
+ sessionKey?: string;
91
+ mirror?: { sessionKey?: string };
92
+ threadId?: string;
93
+ };
94
+
95
+ export type BncrRegisterRuntimeSnapshot = {
96
+ bridgeId: string;
97
+ gatewayPid: number;
98
+ pluginVersion: string | null;
99
+ pluginSource: string | null;
100
+ lastApiInstanceId: string | null;
101
+ lastRegistryFingerprint: string | null;
102
+ registerCount: number;
103
+ firstRegisterAt: number | null;
104
+ lastRegisterAt: number | null;
105
+ lastApiRebindAt: number | null;
106
+ apiGeneration: number;
107
+ registerTraceRecent: RegisterTraceEntry[];
108
+ lastDriftSnapshot: RegisterDriftSnapshot | null;
109
+ };
110
+
111
+ export type FileAckPayloadState = {
112
+ payload: Record<string, unknown>;
113
+ ok: boolean;
114
+ at: number;
115
+ };
116
+
117
+ export type ChannelMessageActionAdapter = {
118
+ describeMessageTool: (ctx: { cfg: BncrChannelConfigRoot }) => {
119
+ actions: readonly ['send'];
120
+ capabilities: readonly [];
121
+ } | null;
122
+ supportsAction: (ctx: { action: string }) => boolean;
123
+ extractToolSend: (ctx: { args: unknown }) => OpenClawChannelToolSend | null;
124
+ handleAction: (ctx: {
125
+ action: string;
126
+ params: unknown;
127
+ accountId?: string | null;
128
+ mediaLocalRoots?: readonly string[];
129
+ }) => Promise<OpenClawJsonResultPayload>;
130
+ };
131
+
132
+ export type PersistedState = {
133
+ outbox: OutboxEntry[];
134
+ deadLetter: OutboxEntry[];
135
+ sessionRoutes: BncrPersistedSessionRoute[];
136
+ lastSessionByAccount?: BncrPersistedLastSession[];
137
+ lastActivityByAccount?: BncrPersistedAccountTimestamp[];
138
+ lastInboundByAccount?: BncrPersistedAccountTimestamp[];
139
+ lastOutboundByAccount?: BncrPersistedAccountTimestamp[];
140
+ lastDriftSnapshot?: RegisterDriftSnapshot | null;
141
+ };
142
+
143
+ export type BncrBridgeRuntimePaths = {
144
+ pluginRoot?: string | null;
145
+ pluginFile?: string | null;
146
+ };
@@ -0,0 +1,37 @@
1
+ import type { BncrRoute } from '../core/types.ts';
2
+ import { createBncrChannelSendRuntimeComponent } from './channel-components.ts';
3
+
4
+ export function createBncrChannelSendRuntimeGroup(runtime: {
5
+ channelId: string;
6
+ asString: (value: unknown, fallback?: string) => string;
7
+ syncDebugFlag: () => Promise<void>;
8
+ logInfo: (scope: string, message: string, options?: Record<string, unknown>) => void;
9
+ resolveVerifiedTarget: (
10
+ to: string,
11
+ accountId: string,
12
+ ) => {
13
+ sessionKey: string;
14
+ route: BncrRoute;
15
+ displayScope: string;
16
+ };
17
+ rememberSessionRoute: (sessionKey: string, accountId: string, route: BncrRoute) => void;
18
+ enqueueFromReply: Parameters<typeof createBncrChannelSendRuntimeComponent>[0]['enqueueFromReply'];
19
+ listOutboxEntries: Parameters<
20
+ typeof createBncrChannelSendRuntimeComponent
21
+ >[0]['listOutboxEntries'];
22
+ }) {
23
+ const channelSendRuntime = createBncrChannelSendRuntimeComponent({
24
+ channelId: runtime.channelId,
25
+ asString: runtime.asString,
26
+ syncDebugFlag: runtime.syncDebugFlag,
27
+ logInfo: runtime.logInfo,
28
+ resolveVerifiedTarget: runtime.resolveVerifiedTarget,
29
+ rememberSessionRoute: runtime.rememberSessionRoute,
30
+ enqueueFromReply: runtime.enqueueFromReply,
31
+ listOutboxEntries: runtime.listOutboxEntries,
32
+ });
33
+
34
+ return {
35
+ channelSendRuntime,
36
+ };
37
+ }