@xmoxmo/bncr 0.5.5 → 0.5.7

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 (78) hide show
  1. package/dist/index.js +1 -9
  2. package/index.ts +1 -9
  3. package/package.json +1 -1
  4. package/scripts/check-pack.mjs +0 -6
  5. package/scripts/selfcheck.mjs +0 -7
  6. package/src/channel.ts +114 -37
  7. package/src/core/accounts.ts +1 -6
  8. package/src/core/connection-reachability.ts +1 -5
  9. package/src/core/dead-letter-diagnostics.ts +4 -10
  10. package/src/core/outbox-entry-builders.ts +38 -15
  11. package/src/core/outbox-file-transfer-failure.ts +5 -0
  12. package/src/core/outbox-file-transfer-guards.ts +6 -0
  13. package/src/core/outbox-file-transfer-prep.ts +8 -5
  14. package/src/core/outbox-file-transfer-success.ts +5 -0
  15. package/src/core/outbox-queue.ts +1 -7
  16. package/src/core/outbox-summary.ts +15 -27
  17. package/src/core/outbox-text-push-prep.ts +1 -36
  18. package/src/core/permissions.ts +1 -9
  19. package/src/core/persisted-outbox-entry.ts +54 -11
  20. package/src/core/policy.ts +1 -11
  21. package/src/core/register-trace.ts +2 -5
  22. package/src/core/status-meta.ts +1 -9
  23. package/src/core/status.ts +1 -21
  24. package/src/core/targets.ts +52 -70
  25. package/src/core/types.ts +1 -17
  26. package/src/core/value-sanitize.ts +38 -1
  27. package/src/messaging/inbound/commands.ts +2 -24
  28. package/src/messaging/inbound/dispatch-prep.ts +1 -1
  29. package/src/messaging/inbound/gate.ts +2 -31
  30. package/src/messaging/inbound/group-history.ts +0 -75
  31. package/src/messaging/inbound/native-command.ts +7 -3
  32. package/src/messaging/inbound/parse.ts +1 -31
  33. package/src/messaging/inbound/scene-admin.ts +181 -5
  34. package/src/messaging/outbound/diagnostics.ts +1 -6
  35. package/src/messaging/outbound/durable-queue-adapter.ts +17 -11
  36. package/src/messaging/outbound/marker-parser.ts +188 -0
  37. package/src/messaging/outbound/media-dedupe.ts +2 -6
  38. package/src/messaging/outbound/media.ts +6 -20
  39. package/src/messaging/outbound/normalize-outbound-send.ts +327 -0
  40. package/src/messaging/outbound/queue-selectors.ts +1 -5
  41. package/src/messaging/outbound/reply-enqueue-media.ts +4 -0
  42. package/src/messaging/outbound/reply-enqueue.ts +130 -57
  43. package/src/messaging/outbound/session-route.ts +6 -11
  44. package/src/messaging/outbound/target-resolver.ts +1 -6
  45. package/src/openclaw/routing-runtime.ts +0 -11
  46. package/src/openclaw/sdk-helpers.ts +0 -2
  47. package/src/plugin/bridge-file-transfer-push-facade.ts +8 -6
  48. package/src/plugin/bridge-media-facade.ts +1 -1
  49. package/src/plugin/channel-components.ts +0 -13
  50. package/src/plugin/channel-plugin-surface-group.ts +57 -40
  51. package/src/plugin/channel-runtime-builders-delivery.ts +3 -0
  52. package/src/plugin/channel-runtime-types.ts +10 -24
  53. package/src/plugin/channel-send.ts +241 -154
  54. package/src/plugin/channel-utils.ts +8 -29
  55. package/src/plugin/connection-handlers-helpers.ts +0 -15
  56. package/src/plugin/connection-handlers.ts +6 -5
  57. package/src/plugin/file-inbound-abort.ts +5 -0
  58. package/src/plugin/file-inbound-chunk.ts +5 -0
  59. package/src/plugin/file-inbound-complete.ts +5 -0
  60. package/src/plugin/file-transfer-orchestrator.ts +105 -3
  61. package/src/plugin/file-transfer-setup.ts +1 -1
  62. package/src/plugin/media-dedupe-runtime.ts +1 -6
  63. package/src/plugin/media-orchestrators-runtime-group.ts +2 -0
  64. package/src/plugin/message-send.ts +7 -8
  65. package/src/plugin/outbound.ts +6 -22
  66. package/src/plugin/outbox-drain-loop.ts +2 -2
  67. package/src/plugin/outbox-file-push-flow.ts +7 -7
  68. package/src/plugin/outbox-text-push-flow.ts +1 -1
  69. package/src/plugin/target-runtime.ts +1 -6
  70. package/src/runtime/outbound-ack-timeout.ts +1 -8
  71. package/src/runtime/outbox-transitions.ts +1 -4
  72. package/src/runtime/status-worker.ts +1 -9
  73. package/src/messaging/outbound/build-send-action.ts +0 -130
  74. package/src/messaging/outbound/durable-message-adapter.ts +0 -121
  75. package/src/messaging/outbound/send-params.ts +0 -81
  76. package/src/messaging/outbound/send.ts +0 -121
  77. package/src/openclaw/ingress-runtime.ts +0 -25
  78. package/src/plugin/channel-send-runtime-group.ts +0 -37
@@ -7,6 +7,7 @@ import {
7
7
  routeScopeToHex,
8
8
  } from '../../core/targets.ts';
9
9
  import type { BncrRoute } from '../../core/types.ts';
10
+ import { asString } from '../../core/value-sanitize.ts';
10
11
  import { buildOpenClawChannelOutboundSessionRoute } from '../../openclaw/session-route-runtime.ts';
11
12
  import type { BncrChannelConfigRoot } from '../../plugin/channel-runtime-types.ts';
12
13
 
@@ -18,7 +19,7 @@ type BncrChannelRouteRefFields = {
18
19
  rawTo: string;
19
20
  chatType: 'direct' | 'group';
20
21
  };
21
- thread?: { id: string };
22
+ thread?: { id: string | number };
22
23
  };
23
24
 
24
25
  type BncrOutboundSessionRoute = ChannelOutboundSessionRoute & BncrChannelRouteRefFields;
@@ -30,24 +31,18 @@ type ResolveBncrOutboundSessionRouteParams = {
30
31
  accountId?: string;
31
32
  target: string;
32
33
  resolvedTarget?: { to?: string } | null;
33
- threadId?: string;
34
+ threadId?: string | number | null;
34
35
  canonicalAgentId: string;
35
36
  resolveRouteBySession?: (raw: string, accountId: string) => BncrRoute | null;
36
37
  };
37
38
 
38
- function asString(v: unknown, fallback = ''): string {
39
- if (typeof v === 'string') return v;
40
- if (v == null) return fallback;
41
- return String(v);
42
- }
43
-
44
39
  function attachBncrChannelRouteRefFields(args: {
45
40
  built: ChannelOutboundSessionRoute;
46
41
  channel: string;
47
42
  accountId?: string;
48
43
  to: string;
49
44
  chatType: 'direct' | 'group';
50
- threadId?: string;
45
+ threadId?: string | number | null;
51
46
  }): BncrOutboundSessionRoute {
52
47
  const { built, channel, accountId, to, chatType, threadId } = args;
53
48
  return {
@@ -59,7 +54,7 @@ function attachBncrChannelRouteRefFields(args: {
59
54
  rawTo: to,
60
55
  chatType,
61
56
  },
62
- ...(threadId !== undefined ? { thread: { id: threadId } } : {}),
57
+ ...(threadId != null ? { thread: { id: threadId } } : {}),
63
58
  };
64
59
  }
65
60
 
@@ -99,7 +94,7 @@ export function resolveBncrOutboundSessionRoute(params: ResolveBncrOutboundSessi
99
94
  chatType: 'direct',
100
95
  from: displayTo,
101
96
  to: displayTo,
102
- ...(params.threadId !== undefined ? { threadId: params.threadId } : {}),
97
+ ...(params.threadId != null ? { threadId: params.threadId } : {}),
103
98
  });
104
99
 
105
100
  return attachBncrChannelRouteRefFields({
@@ -4,6 +4,7 @@ import {
4
4
  parseStrictBncrSessionKey,
5
5
  } from '../../core/targets.ts';
6
6
  import type { BncrRoute } from '../../core/types.ts';
7
+ import { asString } from '../../core/value-sanitize.ts';
7
8
 
8
9
  type ResolveBncrOutboundTargetParams = {
9
10
  target: string;
@@ -11,12 +12,6 @@ type ResolveBncrOutboundTargetParams = {
11
12
  resolveRouteBySession?: (raw: string, accountId: string) => BncrRoute | null;
12
13
  };
13
14
 
14
- function asString(v: unknown, fallback = ''): string {
15
- if (typeof v === 'string') return v;
16
- if (v == null) return fallback;
17
- return String(v);
18
- }
19
-
20
15
  export function looksLikeBncrExplicitTarget(input: string): boolean {
21
16
  const raw = asString(input).trim();
22
17
  if (!raw) return false;
@@ -1,4 +1,3 @@
1
- import { buildChannelOutboundSessionRoute } from 'openclaw/plugin-sdk/core';
2
1
  import { resolveInboundLastRouteSessionKey } from 'openclaw/plugin-sdk/routing';
3
2
  import type { BncrChannelConfigRoot } from '../plugin/channel-runtime-types.ts';
4
3
  import type {
@@ -17,10 +16,6 @@ type OpenClawRoutingApi = {
17
16
  }) => OpenClawResolvedAgentRoute;
18
17
  };
19
18
 
20
- type BuildChannelOutboundSessionRouteParams = Parameters<
21
- typeof buildChannelOutboundSessionRoute
22
- >[0];
23
-
24
19
  function resolveRoutingApi(api: OpenClawChannelRuntimeApiHolder): OpenClawRoutingApi {
25
20
  const routing = api?.runtime?.channel?.routing;
26
21
  if (!routing || typeof routing !== 'object') {
@@ -56,9 +51,3 @@ export function resolveOpenClawInboundLastRouteSessionKey(params: {
56
51
  },
57
52
  );
58
53
  }
59
-
60
- export function buildOpenClawChannelOutboundSessionRoute(
61
- params: BuildChannelOutboundSessionRouteParams,
62
- ) {
63
- return buildChannelOutboundSessionRoute(params);
64
- }
@@ -1,4 +1,3 @@
1
- import { readBooleanParam as sdkReadBooleanParam } from 'openclaw/plugin-sdk/boolean-param';
2
1
  import {
3
2
  applyAccountNameToChannelSection as sdkApplyAccountNameToChannelSection,
4
3
  jsonResult as sdkJsonResult,
@@ -15,7 +14,6 @@ import { extractToolSend as sdkExtractToolSend } from 'openclaw/plugin-sdk/tool-
15
14
 
16
15
  export type OpenClawChannelToolSend = ChannelToolSend;
17
16
 
18
- export const readOpenClawBooleanParam = sdkReadBooleanParam;
19
17
  export const readOpenClawStringParam = sdkReadStringParam;
20
18
  export const readOpenClawJsonFileWithFallback = sdkReadJsonFileWithFallback;
21
19
  export const writeOpenClawJsonFileAtomically = sdkWriteJsonFileAtomically;
@@ -19,16 +19,17 @@ export function createBncrBridgeFileTransferPushFacade(runtime: {
19
19
  route: BncrRoute;
20
20
  mediaUrl: string;
21
21
  mediaLocalRoots?: readonly string[];
22
+ downloadMedia?: boolean;
22
23
  }) => Promise<{
23
24
  mode: 'base64' | 'chunk';
24
25
  mimeType?: string;
25
26
  fileName?: string;
26
- mediaBase64?: string;
27
+ base64?: string;
27
28
  path?: string;
28
29
  }>;
29
30
  buildFileTransferOutboundFrame: (params: {
30
31
  entry: OutboxEntry;
31
- meta: Record<string, unknown>;
32
+ msg: Record<string, unknown>;
32
33
  media: { fileName?: string; mimeType?: string; path?: string; base64?: string; type?: string };
33
34
  mediaUrl: string;
34
35
  }) => Record<string, unknown>;
@@ -73,7 +74,7 @@ export function createBncrBridgeFileTransferPushFacade(runtime: {
73
74
  }) {
74
75
  const pushFileTransferSuccessPath = async (args: {
75
76
  entry: OutboxEntry;
76
- meta: Record<string, unknown>;
77
+ msg: Record<string, unknown>;
77
78
  owner: BncrConnection | null;
78
79
  connIds: Iterable<string>;
79
80
  recentInboundReachable: boolean;
@@ -85,13 +86,14 @@ export function createBncrBridgeFileTransferPushFacade(runtime: {
85
86
  sessionKey: args.entry.sessionKey,
86
87
  route: args.entry.route,
87
88
  mediaUrl: args.mediaUrl,
88
- mediaLocalRoots: Array.isArray(args.meta.mediaLocalRoots)
89
- ? args.meta.mediaLocalRoots.filter((v): v is string => typeof v === 'string')
89
+ mediaLocalRoots: Array.isArray(args.msg.mediaLocalRoots)
90
+ ? args.msg.mediaLocalRoots.filter((v): v is string => typeof v === 'string')
90
91
  : undefined,
92
+ downloadMedia: args.msg.downloadMedia as boolean | undefined,
91
93
  });
92
94
  const frame = runtime.buildFileTransferOutboundFrame({
93
95
  entry: args.entry,
94
- meta: args.meta,
96
+ msg: args.msg,
95
97
  media,
96
98
  mediaUrl: args.mediaUrl,
97
99
  });
@@ -48,7 +48,7 @@ export function createBncrBridgeMediaFacade(runtime: {
48
48
  mode: 'base64' | 'chunk';
49
49
  mimeType?: string;
50
50
  fileName?: string;
51
- mediaBase64?: string;
51
+ base64?: string;
52
52
  path?: string;
53
53
  }>;
54
54
  };
@@ -11,7 +11,6 @@ import { OUTBOUND_FLUSH_REASON, OUTBOUND_FLUSH_TRIGGER } from '../messaging/outb
11
11
  import type { ReplyPayloadInput } from '../messaging/outbound/reply-enqueue.ts';
12
12
  import { getOpenClawRuntimeConfig } from '../openclaw/config-runtime.ts';
13
13
  import { saveOpenClawChannelMediaBuffer } from '../openclaw/media-runtime.ts';
14
- import { createBncrChannelSendRuntime } from './channel-send.ts';
15
14
  import { createBncrConnectionHandlers } from './connection-handlers.ts';
16
15
  import { createBncrDiagnosticsHandlers } from './diagnostics-handlers.ts';
17
16
  import { createBncrFileInboundHandlers } from './file-inbound-handlers.ts';
@@ -23,12 +22,6 @@ export function createBncrConnectionHandlersComponent(
23
22
  return createBncrConnectionHandlers(runtime);
24
23
  }
25
24
 
26
- export function createBncrDiagnosticsHandlersComponent(
27
- runtime: Parameters<typeof createBncrDiagnosticsHandlers>[0],
28
- ) {
29
- return createBncrDiagnosticsHandlers(runtime);
30
- }
31
-
32
25
  export function createBncrBridgeDiagnosticsHandlersComponent(runtime: {
33
26
  getApi: () => OpenClawPluginApi;
34
27
  channelId: string;
@@ -312,12 +305,6 @@ export function createBncrInboundHandlersComponent(runtime: {
312
305
  });
313
306
  }
314
307
 
315
- export function createBncrChannelSendRuntimeComponent(
316
- runtime: Parameters<typeof createBncrChannelSendRuntime>[0],
317
- ) {
318
- return createBncrChannelSendRuntime(runtime);
319
- }
320
-
321
308
  export function resolveBncrChannelRoot(pluginRoot: string) {
322
309
  return pluginRoot || path.join(process.cwd(), 'plugins', 'bncr');
323
310
  }
@@ -1,15 +1,15 @@
1
- import { randomUUID } from 'node:crypto';
2
1
  import type { ChannelMessageSendResult } from 'openclaw/plugin-sdk/channel-message';
3
- import { listAccountIds, resolveAccount } from '../core/accounts.ts';
2
+ import { listAccountIds, normalizeAccountId, resolveAccount } from '../core/accounts.ts';
4
3
  import { BncrConfigSchema } from '../core/config-schema.ts';
5
4
  import { resolveBncrChannelPolicy } from '../core/policy.ts';
6
5
  import type { ReplyPayloadInput } from '../messaging/outbound/reply-enqueue.ts';
7
6
  import type { OutboundReplyTargetPolicy } from '../messaging/outbound/reply-target-policy.ts';
8
- import { sendBncrMedia, sendBncrText } from '../messaging/outbound/send.ts';
9
- import { normalizeBncrSendParams } from '../messaging/outbound/send-params.ts';
10
7
  import type { OpenClawChannelToolSend, openClawJsonResult } from '../openclaw/sdk-helpers.ts';
8
+ import { readOpenClawStringParam } from '../openclaw/sdk-helpers.ts';
11
9
  import type {
12
10
  BncrChannelConfigRoot,
11
+ BncrChannelSendContext,
12
+ BncrSceneRecord,
13
13
  BncrStatusRuntimeSnapshot,
14
14
  BncrVerifiedTarget,
15
15
  ChannelMessageActionAdapter,
@@ -37,6 +37,7 @@ type PluginSurfaceResult = ReturnType<typeof openClawJsonResult>;
37
37
 
38
38
  export function createBncrChannelPluginSurfaceGroup(runtime: {
39
39
  channelId: string;
40
+ sceneRegistry: Map<string, BncrSceneRecord>;
40
41
  getMessageSendBridge: () => {
41
42
  channelMessageSendText: (
42
43
  ctx: Record<string, unknown>,
@@ -137,43 +138,59 @@ export function createBncrChannelPluginSurfaceGroup(runtime: {
137
138
  if (action !== 'send') {
138
139
  throw new Error(`Action ${action} is not supported for provider ${runtime.channelId}.`);
139
140
  }
140
- const normalized = normalizeBncrSendParams({ params, accountId: accountId || '' });
141
141
 
142
- const toolActionBridge = runtime.getToolActionBridge();
143
- const result =
144
- normalized.mediaUrl || normalized.mediaUrls?.length
145
- ? await sendBncrMedia({
146
- channelId: runtime.channelId,
147
- accountId: normalized.accountId,
148
- to: normalized.to,
149
- text: normalized.caption,
150
- mediaUrl: normalized.mediaUrl,
151
- mediaUrls: normalized.mediaUrls,
152
- asVoice: normalized.asVoice,
153
- audioAsVoice: normalized.audioAsVoice,
154
- type: normalized.type,
155
- extra: normalized.extra,
156
- mediaLocalRoots,
157
- resolveVerifiedTarget: (to, accountId) =>
158
- toolActionBridge.resolveVerifiedTarget(to, accountId),
159
- rememberSessionRoute: (sessionKey, accountId, route) =>
160
- toolActionBridge.rememberSessionRoute(sessionKey, accountId, route),
161
- enqueueFromReply: (args) => toolActionBridge.enqueueFromReply(args),
162
- createMessageId: () => randomUUID(),
163
- })
164
- : await sendBncrText({
165
- channelId: runtime.channelId,
166
- accountId: normalized.accountId,
167
- to: normalized.to,
168
- text: normalized.message,
169
- mediaLocalRoots,
170
- resolveVerifiedTarget: (to, accountId) =>
171
- toolActionBridge.resolveVerifiedTarget(to, accountId),
172
- rememberSessionRoute: (sessionKey, accountId, route) =>
173
- toolActionBridge.rememberSessionRoute(sessionKey, accountId, route),
174
- enqueueFromReply: (args) => toolActionBridge.enqueueFromReply(args),
175
- createMessageId: () => randomUUID(),
176
- });
142
+ /* -- extract raw params (no normalization) ----------------------- */
143
+ const paramsObj = (params && typeof params === 'object' ? params : {}) as Record<
144
+ string,
145
+ unknown
146
+ >;
147
+ const to = readOpenClawStringParam(paramsObj, 'to', { required: true });
148
+ const resolvedAccountId = normalizeAccountId(
149
+ (readOpenClawStringParam(paramsObj, 'accountId') ?? accountId) || '',
150
+ );
151
+ const toolMediaUrl =
152
+ (typeof paramsObj.mediaUrl === 'string' ? paramsObj.mediaUrl : '') ||
153
+ (typeof paramsObj.media === 'string' ? paramsObj.media : '') ||
154
+ (typeof paramsObj.path === 'string' ? paramsObj.path : '') ||
155
+ (typeof paramsObj.filePath === 'string' ? paramsObj.filePath : '');
156
+ const rawExtra = paramsObj.extra;
157
+ const extra =
158
+ rawExtra && typeof rawExtra === 'object' && !Array.isArray(rawExtra)
159
+ ? (rawExtra as Record<string, unknown>)
160
+ : undefined;
161
+ const rawMediaUrls = paramsObj.mediaUrls;
162
+ const mediaUrls = Array.isArray(rawMediaUrls)
163
+ ? rawMediaUrls.filter((u): u is string => typeof u === 'string')
164
+ : undefined;
165
+
166
+ const toolMessage = readOpenClawStringParam(paramsObj, 'message', { allowEmpty: true }) ?? '';
167
+ const toolCaption = readOpenClawStringParam(paramsObj, 'caption', { allowEmpty: true }) ?? '';
168
+ const text = toolCaption || toolMessage || '';
169
+ const ctx: BncrChannelSendContext = {
170
+ to,
171
+ accountId: resolvedAccountId,
172
+ text,
173
+ mediaUrl: toolMediaUrl || undefined,
174
+ mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
175
+ asVoice: paramsObj.asVoice === true,
176
+ audioAsVoice: paramsObj.audioAsVoice === true,
177
+ downloadMedia: paramsObj.downloadMedia as boolean | undefined,
178
+ type: typeof paramsObj.type === 'string' ? paramsObj.type : undefined,
179
+ extra,
180
+ forceDocument: paramsObj.forceDocument === true,
181
+ gifPlayback: paramsObj.gifPlayback === true,
182
+ silent: paramsObj.silent === true,
183
+ mediaLocalRoots,
184
+ };
185
+
186
+ const hasContent = Boolean(text?.trim() || toolMediaUrl || mediaUrls?.length || extra);
187
+ if (!hasContent) {
188
+ throw new Error('send requires message, media, or extra params');
189
+ }
190
+
191
+ /* -- bridge to sendDispatch (normalization + routing inside) ----- */
192
+ const outboundBridge = runtime.getOutboundBridge();
193
+ const result = await outboundBridge.channelSendText(ctx);
177
194
 
178
195
  return runtime.openClawJsonResult({ ok: true, ...result });
179
196
  },
@@ -333,6 +333,7 @@ export function buildBncrMediaOrchestratorsRuntime(deps: {
333
333
  sessionKey: string;
334
334
  route: BncrRoute;
335
335
  text: string;
336
+ extra?: Record<string, unknown>;
336
337
  kind?: 'tool' | 'block' | 'final';
337
338
  replyToId?: string;
338
339
  replyTargetPolicy?: OutboundReplyTargetPolicy;
@@ -351,6 +352,7 @@ export function buildBncrMediaOrchestratorsRuntime(deps: {
351
352
  kind?: 'tool' | 'block' | 'final';
352
353
  replyToId?: string;
353
354
  replyTargetPolicy?: OutboundReplyTargetPolicy;
355
+ downloadMedia?: boolean;
354
356
  }) => OutboxEntry;
355
357
  rememberRecentMediaSend: (args: {
356
358
  sessionKey: string;
@@ -533,6 +535,7 @@ export function buildBncrChannelSendRuntime(deps: {
533
535
  replyTargetPolicy?: OutboundReplyTargetPolicy;
534
536
  }) => Promise<void>;
535
537
  listOutboxEntries: () => OutboxEntry[];
538
+ resolveSceneDownloadMedia?: (to: string) => boolean | undefined;
536
539
  }) {
537
540
  return { ...deps };
538
541
  }
@@ -1,4 +1,4 @@
1
- import type { RegisterDriftSnapshot, RegisterTraceEntry } from '../core/register-trace.ts';
1
+ import type { RegisterDriftSnapshot } from '../core/register-trace.ts';
2
2
  import type { BncrDiagnosticsSummary, BncrRoute, OutboxEntry } from '../core/types.ts';
3
3
  import type { OpenClawChannelToolSend, openClawJsonResult } from '../openclaw/sdk-helpers.ts';
4
4
 
@@ -63,6 +63,7 @@ export type BncrSceneRecord = {
63
63
  groupReplyMode?: BncrGroupReplyMode;
64
64
  historyLimit?: number;
65
65
  historyForce?: boolean;
66
+ downloadMedia?: boolean;
66
67
  lastSeenAt: number;
67
68
  };
68
69
 
@@ -132,29 +133,14 @@ export type BncrChannelSendContext = {
132
133
  payload?: Record<string, unknown>;
133
134
  sessionKey?: string;
134
135
  mirror?: { sessionKey?: string };
135
- threadId?: string;
136
- };
137
-
138
- export type BncrRegisterRuntimeSnapshot = {
139
- bridgeId: string;
140
- gatewayPid: number;
141
- pluginVersion: string | null;
142
- pluginSource: string | null;
143
- lastApiInstanceId: string | null;
144
- lastRegistryFingerprint: string | null;
145
- registerCount: number;
146
- firstRegisterAt: number | null;
147
- lastRegisterAt: number | null;
148
- lastApiRebindAt: number | null;
149
- apiGeneration: number;
150
- registerTraceRecent: RegisterTraceEntry[];
151
- lastDriftSnapshot: RegisterDriftSnapshot | null;
152
- };
153
-
154
- export type FileAckPayloadState = {
155
- payload: Record<string, unknown>;
156
- ok: boolean;
157
- at: number;
136
+ threadId?: string | number | null;
137
+ /** Pass-through fields from host - bncr plugin does NOT consume these. */
138
+ forceDocument?: boolean;
139
+ gifPlayback?: boolean;
140
+ silent?: boolean;
141
+ downloadMedia?: boolean;
142
+ /** Extra key-value pairs from marker parsing or direct pass-through. */
143
+ extra?: Record<string, unknown>;
158
144
  };
159
145
 
160
146
  export type ChannelMessageActionAdapter = {