@inline-openclaw/inline 0.0.67 → 0.0.68

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.
@@ -5585,6 +5585,7 @@ function hasInlineConfiguredState(params) {
5585
5585
  }
5586
5586
 
5587
5587
  // src/inline/channel.ts
5588
+ import { createHash } from "node:crypto";
5588
5589
  import { unlink } from "node:fs/promises";
5589
5590
  import path4 from "node:path";
5590
5591
  import {
@@ -5593,7 +5594,11 @@ import {
5593
5594
  resolveThreadSessionKeys
5594
5595
  } from "openclaw/plugin-sdk/core";
5595
5596
  import { parseAgentSessionKey, parseThreadSessionSuffix } from "openclaw/plugin-sdk/routing";
5596
- import { createChannelMessageAdapterFromOutbound } from "openclaw/plugin-sdk/channel-outbound";
5597
+ import {
5598
+ createChannelMessageAdapterFromOutbound,
5599
+ createMessageReceiptFromOutboundResults
5600
+ } from "openclaw/plugin-sdk/channel-outbound";
5601
+ import { PlatformMessageNotDispatchedError } from "openclaw/plugin-sdk/error-runtime";
5597
5602
  import {
5598
5603
  presentationToInteractiveReply,
5599
5604
  renderMessagePresentationFallbackText as renderMessagePresentationFallbackText2
@@ -5863,6 +5868,20 @@ var UploadFailure_Code;
5863
5868
  UploadFailure_Code2[UploadFailure_Code2["UPLOAD_FAILURE_PROCESSING"] = 3] = "UPLOAD_FAILURE_PROCESSING";
5864
5869
  UploadFailure_Code2[UploadFailure_Code2["UPLOAD_FAILURE_STORAGE"] = 4] = "UPLOAD_FAILURE_STORAGE";
5865
5870
  })(UploadFailure_Code || (UploadFailure_Code = {}));
5871
+ var RequestBotFilesystemInput_Operation;
5872
+ (function(RequestBotFilesystemInput_Operation2) {
5873
+ RequestBotFilesystemInput_Operation2[RequestBotFilesystemInput_Operation2["OPERATION_UNSPECIFIED"] = 0] = "OPERATION_UNSPECIFIED";
5874
+ RequestBotFilesystemInput_Operation2[RequestBotFilesystemInput_Operation2["LIST"] = 1] = "LIST";
5875
+ RequestBotFilesystemInput_Operation2[RequestBotFilesystemInput_Operation2["REGISTER_FOLDER"] = 2] = "REGISTER_FOLDER";
5876
+ })(RequestBotFilesystemInput_Operation || (RequestBotFilesystemInput_Operation = {}));
5877
+ var BotFilesystemEntry_Kind;
5878
+ (function(BotFilesystemEntry_Kind2) {
5879
+ BotFilesystemEntry_Kind2[BotFilesystemEntry_Kind2["KIND_UNSPECIFIED"] = 0] = "KIND_UNSPECIFIED";
5880
+ BotFilesystemEntry_Kind2[BotFilesystemEntry_Kind2["FILE"] = 1] = "FILE";
5881
+ BotFilesystemEntry_Kind2[BotFilesystemEntry_Kind2["DIRECTORY"] = 2] = "DIRECTORY";
5882
+ BotFilesystemEntry_Kind2[BotFilesystemEntry_Kind2["SYMLINK"] = 3] = "SYMLINK";
5883
+ BotFilesystemEntry_Kind2[BotFilesystemEntry_Kind2["OTHER"] = 4] = "OTHER";
5884
+ })(BotFilesystemEntry_Kind || (BotFilesystemEntry_Kind = {}));
5866
5885
  var DialogFollowMode;
5867
5886
  (function(DialogFollowMode2) {
5868
5887
  DialogFollowMode2[DialogFollowMode2["DIALOG_FOLLOW_MODE_UNSPECIFIED"] = 0] = "DIALOG_FOLLOW_MODE_UNSPECIFIED";
@@ -6061,6 +6080,10 @@ var Method;
6061
6080
  Method2[Method2["GET_USERS"] = 138] = "GET_USERS";
6062
6081
  Method2[Method2["GET_BOT_SKILLS"] = 139] = "GET_BOT_SKILLS";
6063
6082
  Method2[Method2["GET_BOT_CONFIGURATION_CATALOG"] = 140] = "GET_BOT_CONFIGURATION_CATALOG";
6083
+ Method2[Method2["UPDATE_DIALOG_TRANSLATION"] = 141] = "UPDATE_DIALOG_TRANSLATION";
6084
+ Method2[Method2["TRANSCRIBE_VOICE_DRAFT"] = 142] = "TRANSCRIBE_VOICE_DRAFT";
6085
+ Method2[Method2["REQUEST_BOT_FILESYSTEM"] = 143] = "REQUEST_BOT_FILESYSTEM";
6086
+ Method2[Method2["ANSWER_BOT_FILESYSTEM"] = 144] = "ANSWER_BOT_FILESYSTEM";
6064
6087
  })(Method || (Method = {}));
6065
6088
  var GridConnectionUnavailableReason;
6066
6089
  (function(GridConnectionUnavailableReason2) {
@@ -6529,7 +6552,8 @@ class BotEvent$Type extends import_runtime4.MessageType {
6529
6552
  constructor() {
6530
6553
  super("BotEvent", [
6531
6554
  { no: 1, name: "chat_settings_requested", kind: "message", oneof: "event", T: () => BotChatSettingsRequested },
6532
- { no: 2, name: "chat_settings_item_invoked", kind: "message", oneof: "event", T: () => BotChatSettingsItemInvoked }
6555
+ { no: 2, name: "chat_settings_item_invoked", kind: "message", oneof: "event", T: () => BotChatSettingsItemInvoked },
6556
+ { no: 3, name: "filesystem_requested", kind: "message", oneof: "event", T: () => BotFilesystemRequested }
6533
6557
  ]);
6534
6558
  }
6535
6559
  create(value) {
@@ -6556,6 +6580,12 @@ class BotEvent$Type extends import_runtime4.MessageType {
6556
6580
  chatSettingsItemInvoked: BotChatSettingsItemInvoked.internalBinaryRead(reader, reader.uint32(), options, message.event.chatSettingsItemInvoked)
6557
6581
  };
6558
6582
  break;
6583
+ case 3:
6584
+ message.event = {
6585
+ oneofKind: "filesystemRequested",
6586
+ filesystemRequested: BotFilesystemRequested.internalBinaryRead(reader, reader.uint32(), options, message.event.filesystemRequested)
6587
+ };
6588
+ break;
6559
6589
  default:
6560
6590
  let u = options.readUnknownField;
6561
6591
  if (u === "throw")
@@ -6572,6 +6602,8 @@ class BotEvent$Type extends import_runtime4.MessageType {
6572
6602
  BotChatSettingsRequested.internalBinaryWrite(message.event.chatSettingsRequested, writer.tag(1, import_runtime.WireType.LengthDelimited).fork(), options).join();
6573
6603
  if (message.event.oneofKind === "chatSettingsItemInvoked")
6574
6604
  BotChatSettingsItemInvoked.internalBinaryWrite(message.event.chatSettingsItemInvoked, writer.tag(2, import_runtime.WireType.LengthDelimited).fork(), options).join();
6605
+ if (message.event.oneofKind === "filesystemRequested")
6606
+ BotFilesystemRequested.internalBinaryWrite(message.event.filesystemRequested, writer.tag(3, import_runtime.WireType.LengthDelimited).fork(), options).join();
6575
6607
  let u = options.writeUnknownFields;
6576
6608
  if (u !== false)
6577
6609
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -7728,7 +7760,8 @@ class Dialog$Type extends import_runtime4.MessageType {
7728
7760
  { no: 15, name: "pinned_order", kind: "scalar", opt: true, T: 9 },
7729
7761
  { no: 16, name: "follow_mode", kind: "enum", opt: true, T: () => ["DialogFollowMode", DialogFollowMode] },
7730
7762
  { no: 17, name: "collapsed_max_id", kind: "scalar", opt: true, T: 3, L: 0 },
7731
- { no: 18, name: "folder_id", kind: "scalar", opt: true, T: 3, L: 0 }
7763
+ { no: 18, name: "folder_id", kind: "scalar", opt: true, T: 3, L: 0 },
7764
+ { no: 19, name: "translation_enabled", kind: "scalar", opt: true, T: 8 }
7732
7765
  ]);
7733
7766
  }
7734
7767
  create(value) {
@@ -7796,6 +7829,9 @@ class Dialog$Type extends import_runtime4.MessageType {
7796
7829
  case 18:
7797
7830
  message.folderId = reader.int64().toBigInt();
7798
7831
  break;
7832
+ case 19:
7833
+ message.translationEnabled = reader.bool();
7834
+ break;
7799
7835
  default:
7800
7836
  let u = options.readUnknownField;
7801
7837
  if (u === "throw")
@@ -7844,6 +7880,8 @@ class Dialog$Type extends import_runtime4.MessageType {
7844
7880
  writer.tag(17, import_runtime.WireType.Varint).int64(message.collapsedMaxId);
7845
7881
  if (message.folderId !== undefined)
7846
7882
  writer.tag(18, import_runtime.WireType.Varint).int64(message.folderId);
7883
+ if (message.translationEnabled !== undefined)
7884
+ writer.tag(19, import_runtime.WireType.Varint).bool(message.translationEnabled);
7847
7885
  let u = options.writeUnknownFields;
7848
7886
  if (u !== false)
7849
7887
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -13976,7 +14014,11 @@ class RpcCall$Type extends import_runtime4.MessageType {
13976
14014
  { no: 138, name: "acknowledgeMessages", kind: "message", oneof: "input", T: () => AcknowledgeMessagesInput },
13977
14015
  { no: 139, name: "getUsers", kind: "message", oneof: "input", T: () => GetUsersInput },
13978
14016
  { no: 140, name: "getBotSkills", kind: "message", oneof: "input", T: () => GetBotSkillsInput },
13979
- { no: 141, name: "getBotConfigurationCatalog", kind: "message", oneof: "input", T: () => GetBotConfigurationCatalogInput }
14017
+ { no: 141, name: "getBotConfigurationCatalog", kind: "message", oneof: "input", T: () => GetBotConfigurationCatalogInput },
14018
+ { no: 142, name: "updateDialogTranslation", kind: "message", oneof: "input", T: () => UpdateDialogTranslationInput },
14019
+ { no: 143, name: "transcribeVoiceDraft", kind: "message", oneof: "input", T: () => TranscribeVoiceDraftInput },
14020
+ { no: 144, name: "requestBotFilesystem", kind: "message", oneof: "input", T: () => RequestBotFilesystemInput },
14021
+ { no: 145, name: "answerBotFilesystem", kind: "message", oneof: "input", T: () => AnswerBotFilesystemInput }
13980
14022
  ]);
13981
14023
  }
13982
14024
  create(value) {
@@ -14829,6 +14871,30 @@ class RpcCall$Type extends import_runtime4.MessageType {
14829
14871
  getBotConfigurationCatalog: GetBotConfigurationCatalogInput.internalBinaryRead(reader, reader.uint32(), options, message.input.getBotConfigurationCatalog)
14830
14872
  };
14831
14873
  break;
14874
+ case 142:
14875
+ message.input = {
14876
+ oneofKind: "updateDialogTranslation",
14877
+ updateDialogTranslation: UpdateDialogTranslationInput.internalBinaryRead(reader, reader.uint32(), options, message.input.updateDialogTranslation)
14878
+ };
14879
+ break;
14880
+ case 143:
14881
+ message.input = {
14882
+ oneofKind: "transcribeVoiceDraft",
14883
+ transcribeVoiceDraft: TranscribeVoiceDraftInput.internalBinaryRead(reader, reader.uint32(), options, message.input.transcribeVoiceDraft)
14884
+ };
14885
+ break;
14886
+ case 144:
14887
+ message.input = {
14888
+ oneofKind: "requestBotFilesystem",
14889
+ requestBotFilesystem: RequestBotFilesystemInput.internalBinaryRead(reader, reader.uint32(), options, message.input.requestBotFilesystem)
14890
+ };
14891
+ break;
14892
+ case 145:
14893
+ message.input = {
14894
+ oneofKind: "answerBotFilesystem",
14895
+ answerBotFilesystem: AnswerBotFilesystemInput.internalBinaryRead(reader, reader.uint32(), options, message.input.answerBotFilesystem)
14896
+ };
14897
+ break;
14832
14898
  default:
14833
14899
  let u = options.readUnknownField;
14834
14900
  if (u === "throw")
@@ -15121,6 +15187,14 @@ class RpcCall$Type extends import_runtime4.MessageType {
15121
15187
  GetBotSkillsInput.internalBinaryWrite(message.input.getBotSkills, writer.tag(140, import_runtime.WireType.LengthDelimited).fork(), options).join();
15122
15188
  if (message.input.oneofKind === "getBotConfigurationCatalog")
15123
15189
  GetBotConfigurationCatalogInput.internalBinaryWrite(message.input.getBotConfigurationCatalog, writer.tag(141, import_runtime.WireType.LengthDelimited).fork(), options).join();
15190
+ if (message.input.oneofKind === "updateDialogTranslation")
15191
+ UpdateDialogTranslationInput.internalBinaryWrite(message.input.updateDialogTranslation, writer.tag(142, import_runtime.WireType.LengthDelimited).fork(), options).join();
15192
+ if (message.input.oneofKind === "transcribeVoiceDraft")
15193
+ TranscribeVoiceDraftInput.internalBinaryWrite(message.input.transcribeVoiceDraft, writer.tag(143, import_runtime.WireType.LengthDelimited).fork(), options).join();
15194
+ if (message.input.oneofKind === "requestBotFilesystem")
15195
+ RequestBotFilesystemInput.internalBinaryWrite(message.input.requestBotFilesystem, writer.tag(144, import_runtime.WireType.LengthDelimited).fork(), options).join();
15196
+ if (message.input.oneofKind === "answerBotFilesystem")
15197
+ AnswerBotFilesystemInput.internalBinaryWrite(message.input.answerBotFilesystem, writer.tag(145, import_runtime.WireType.LengthDelimited).fork(), options).join();
15124
15198
  let u = options.writeUnknownFields;
15125
15199
  if (u !== false)
15126
15200
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -15271,7 +15345,11 @@ class RpcResult$Type extends import_runtime4.MessageType {
15271
15345
  { no: 138, name: "acknowledgeMessages", kind: "message", oneof: "result", T: () => AcknowledgeMessagesResult },
15272
15346
  { no: 139, name: "getUsers", kind: "message", oneof: "result", T: () => GetUsersResult },
15273
15347
  { no: 140, name: "getBotSkills", kind: "message", oneof: "result", T: () => GetBotSkillsResult },
15274
- { no: 141, name: "getBotConfigurationCatalog", kind: "message", oneof: "result", T: () => GetBotConfigurationCatalogResult }
15348
+ { no: 141, name: "getBotConfigurationCatalog", kind: "message", oneof: "result", T: () => GetBotConfigurationCatalogResult },
15349
+ { no: 142, name: "updateDialogTranslation", kind: "message", oneof: "result", T: () => UpdateDialogTranslationResult },
15350
+ { no: 143, name: "transcribeVoiceDraft", kind: "message", oneof: "result", T: () => TranscribeVoiceDraftResult },
15351
+ { no: 144, name: "requestBotFilesystem", kind: "message", oneof: "result", T: () => RequestBotFilesystemResult },
15352
+ { no: 145, name: "answerBotFilesystem", kind: "message", oneof: "result", T: () => AnswerBotFilesystemResult }
15275
15353
  ]);
15276
15354
  }
15277
15355
  create(value) {
@@ -16124,6 +16202,30 @@ class RpcResult$Type extends import_runtime4.MessageType {
16124
16202
  getBotConfigurationCatalog: GetBotConfigurationCatalogResult.internalBinaryRead(reader, reader.uint32(), options, message.result.getBotConfigurationCatalog)
16125
16203
  };
16126
16204
  break;
16205
+ case 142:
16206
+ message.result = {
16207
+ oneofKind: "updateDialogTranslation",
16208
+ updateDialogTranslation: UpdateDialogTranslationResult.internalBinaryRead(reader, reader.uint32(), options, message.result.updateDialogTranslation)
16209
+ };
16210
+ break;
16211
+ case 143:
16212
+ message.result = {
16213
+ oneofKind: "transcribeVoiceDraft",
16214
+ transcribeVoiceDraft: TranscribeVoiceDraftResult.internalBinaryRead(reader, reader.uint32(), options, message.result.transcribeVoiceDraft)
16215
+ };
16216
+ break;
16217
+ case 144:
16218
+ message.result = {
16219
+ oneofKind: "requestBotFilesystem",
16220
+ requestBotFilesystem: RequestBotFilesystemResult.internalBinaryRead(reader, reader.uint32(), options, message.result.requestBotFilesystem)
16221
+ };
16222
+ break;
16223
+ case 145:
16224
+ message.result = {
16225
+ oneofKind: "answerBotFilesystem",
16226
+ answerBotFilesystem: AnswerBotFilesystemResult.internalBinaryRead(reader, reader.uint32(), options, message.result.answerBotFilesystem)
16227
+ };
16228
+ break;
16127
16229
  default:
16128
16230
  let u = options.readUnknownField;
16129
16231
  if (u === "throw")
@@ -16416,6 +16518,14 @@ class RpcResult$Type extends import_runtime4.MessageType {
16416
16518
  GetBotSkillsResult.internalBinaryWrite(message.result.getBotSkills, writer.tag(140, import_runtime.WireType.LengthDelimited).fork(), options).join();
16417
16519
  if (message.result.oneofKind === "getBotConfigurationCatalog")
16418
16520
  GetBotConfigurationCatalogResult.internalBinaryWrite(message.result.getBotConfigurationCatalog, writer.tag(141, import_runtime.WireType.LengthDelimited).fork(), options).join();
16521
+ if (message.result.oneofKind === "updateDialogTranslation")
16522
+ UpdateDialogTranslationResult.internalBinaryWrite(message.result.updateDialogTranslation, writer.tag(142, import_runtime.WireType.LengthDelimited).fork(), options).join();
16523
+ if (message.result.oneofKind === "transcribeVoiceDraft")
16524
+ TranscribeVoiceDraftResult.internalBinaryWrite(message.result.transcribeVoiceDraft, writer.tag(143, import_runtime.WireType.LengthDelimited).fork(), options).join();
16525
+ if (message.result.oneofKind === "requestBotFilesystem")
16526
+ RequestBotFilesystemResult.internalBinaryWrite(message.result.requestBotFilesystem, writer.tag(144, import_runtime.WireType.LengthDelimited).fork(), options).join();
16527
+ if (message.result.oneofKind === "answerBotFilesystem")
16528
+ AnswerBotFilesystemResult.internalBinaryWrite(message.result.answerBotFilesystem, writer.tag(145, import_runtime.WireType.LengthDelimited).fork(), options).join();
16419
16529
  let u = options.writeUnknownFields;
16420
16530
  if (u !== false)
16421
16531
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -19980,6 +20090,153 @@ class UpdateDialogFollowModeResult$Type extends import_runtime4.MessageType {
19980
20090
  }
19981
20091
  var UpdateDialogFollowModeResult = new UpdateDialogFollowModeResult$Type;
19982
20092
 
20093
+ class UpdateDialogTranslationInput$Type extends import_runtime4.MessageType {
20094
+ constructor() {
20095
+ super("UpdateDialogTranslationInput", [
20096
+ { no: 1, name: "peer_id", kind: "message", T: () => InputPeer },
20097
+ { no: 2, name: "enabled", kind: "scalar", opt: true, T: 8 },
20098
+ { no: 3, name: "import_legacy_enabled", kind: "scalar", T: 8 }
20099
+ ]);
20100
+ }
20101
+ create(value) {
20102
+ const message = globalThis.Object.create(this.messagePrototype);
20103
+ message.importLegacyEnabled = false;
20104
+ if (value !== undefined)
20105
+ import_runtime3.reflectionMergePartial(this, message, value);
20106
+ return message;
20107
+ }
20108
+ internalBinaryRead(reader, length, options, target) {
20109
+ let message = target ?? this.create(), end = reader.pos + length;
20110
+ while (reader.pos < end) {
20111
+ let [fieldNo, wireType] = reader.tag();
20112
+ switch (fieldNo) {
20113
+ case 1:
20114
+ message.peerId = InputPeer.internalBinaryRead(reader, reader.uint32(), options, message.peerId);
20115
+ break;
20116
+ case 2:
20117
+ message.enabled = reader.bool();
20118
+ break;
20119
+ case 3:
20120
+ message.importLegacyEnabled = reader.bool();
20121
+ break;
20122
+ default:
20123
+ let u = options.readUnknownField;
20124
+ if (u === "throw")
20125
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
20126
+ let d = reader.skip(wireType);
20127
+ if (u !== false)
20128
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
20129
+ }
20130
+ }
20131
+ return message;
20132
+ }
20133
+ internalBinaryWrite(message, writer, options) {
20134
+ if (message.peerId)
20135
+ InputPeer.internalBinaryWrite(message.peerId, writer.tag(1, import_runtime.WireType.LengthDelimited).fork(), options).join();
20136
+ if (message.enabled !== undefined)
20137
+ writer.tag(2, import_runtime.WireType.Varint).bool(message.enabled);
20138
+ if (message.importLegacyEnabled !== false)
20139
+ writer.tag(3, import_runtime.WireType.Varint).bool(message.importLegacyEnabled);
20140
+ let u = options.writeUnknownFields;
20141
+ if (u !== false)
20142
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
20143
+ return writer;
20144
+ }
20145
+ }
20146
+ var UpdateDialogTranslationInput = new UpdateDialogTranslationInput$Type;
20147
+
20148
+ class UpdateDialogTranslationResult$Type extends import_runtime4.MessageType {
20149
+ constructor() {
20150
+ super("UpdateDialogTranslationResult", [
20151
+ { no: 1, name: "updates", kind: "message", repeat: 1, T: () => Update }
20152
+ ]);
20153
+ }
20154
+ create(value) {
20155
+ const message = globalThis.Object.create(this.messagePrototype);
20156
+ message.updates = [];
20157
+ if (value !== undefined)
20158
+ import_runtime3.reflectionMergePartial(this, message, value);
20159
+ return message;
20160
+ }
20161
+ internalBinaryRead(reader, length, options, target) {
20162
+ let message = target ?? this.create(), end = reader.pos + length;
20163
+ while (reader.pos < end) {
20164
+ let [fieldNo, wireType] = reader.tag();
20165
+ switch (fieldNo) {
20166
+ case 1:
20167
+ message.updates.push(Update.internalBinaryRead(reader, reader.uint32(), options));
20168
+ break;
20169
+ default:
20170
+ let u = options.readUnknownField;
20171
+ if (u === "throw")
20172
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
20173
+ let d = reader.skip(wireType);
20174
+ if (u !== false)
20175
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
20176
+ }
20177
+ }
20178
+ return message;
20179
+ }
20180
+ internalBinaryWrite(message, writer, options) {
20181
+ for (let i = 0;i < message.updates.length; i++)
20182
+ Update.internalBinaryWrite(message.updates[i], writer.tag(1, import_runtime.WireType.LengthDelimited).fork(), options).join();
20183
+ let u = options.writeUnknownFields;
20184
+ if (u !== false)
20185
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
20186
+ return writer;
20187
+ }
20188
+ }
20189
+ var UpdateDialogTranslationResult = new UpdateDialogTranslationResult$Type;
20190
+
20191
+ class UpdateDialogTranslation$Type extends import_runtime4.MessageType {
20192
+ constructor() {
20193
+ super("UpdateDialogTranslation", [
20194
+ { no: 1, name: "peer_id", kind: "message", T: () => Peer },
20195
+ { no: 2, name: "enabled", kind: "scalar", T: 8 }
20196
+ ]);
20197
+ }
20198
+ create(value) {
20199
+ const message = globalThis.Object.create(this.messagePrototype);
20200
+ message.enabled = false;
20201
+ if (value !== undefined)
20202
+ import_runtime3.reflectionMergePartial(this, message, value);
20203
+ return message;
20204
+ }
20205
+ internalBinaryRead(reader, length, options, target) {
20206
+ let message = target ?? this.create(), end = reader.pos + length;
20207
+ while (reader.pos < end) {
20208
+ let [fieldNo, wireType] = reader.tag();
20209
+ switch (fieldNo) {
20210
+ case 1:
20211
+ message.peerId = Peer.internalBinaryRead(reader, reader.uint32(), options, message.peerId);
20212
+ break;
20213
+ case 2:
20214
+ message.enabled = reader.bool();
20215
+ break;
20216
+ default:
20217
+ let u = options.readUnknownField;
20218
+ if (u === "throw")
20219
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
20220
+ let d = reader.skip(wireType);
20221
+ if (u !== false)
20222
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
20223
+ }
20224
+ }
20225
+ return message;
20226
+ }
20227
+ internalBinaryWrite(message, writer, options) {
20228
+ if (message.peerId)
20229
+ Peer.internalBinaryWrite(message.peerId, writer.tag(1, import_runtime.WireType.LengthDelimited).fork(), options).join();
20230
+ if (message.enabled !== false)
20231
+ writer.tag(2, import_runtime.WireType.Varint).bool(message.enabled);
20232
+ let u = options.writeUnknownFields;
20233
+ if (u !== false)
20234
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
20235
+ return writer;
20236
+ }
20237
+ }
20238
+ var UpdateDialogTranslation = new UpdateDialogTranslation$Type;
20239
+
19983
20240
  class CollapseHistoryInput$Type extends import_runtime4.MessageType {
19984
20241
  constructor() {
19985
20242
  super("CollapseHistoryInput", [
@@ -29506,7 +29763,8 @@ class Update$Type extends import_runtime4.MessageType {
29506
29763
  { no: 46, name: "dialog_folder", kind: "message", oneof: "update", T: () => UpdateDialogFolder },
29507
29764
  { no: 47, name: "user_added_to_chat", kind: "message", oneof: "update", T: () => UpdateUserAddedToChat },
29508
29765
  { no: 48, name: "user_removed_from_chat", kind: "message", oneof: "update", T: () => UpdateUserRemovedFromChat },
29509
- { no: 49, name: "acknowledgement", kind: "message", oneof: "update", T: () => ChatAcknowledgement }
29766
+ { no: 49, name: "acknowledgement", kind: "message", oneof: "update", T: () => ChatAcknowledgement },
29767
+ { no: 50, name: "dialog_translation", kind: "message", oneof: "update", T: () => UpdateDialogTranslation }
29510
29768
  ]);
29511
29769
  }
29512
29770
  create(value) {
@@ -29803,6 +30061,12 @@ class Update$Type extends import_runtime4.MessageType {
29803
30061
  acknowledgement: ChatAcknowledgement.internalBinaryRead(reader, reader.uint32(), options, message.update.acknowledgement)
29804
30062
  };
29805
30063
  break;
30064
+ case 50:
30065
+ message.update = {
30066
+ oneofKind: "dialogTranslation",
30067
+ dialogTranslation: UpdateDialogTranslation.internalBinaryRead(reader, reader.uint32(), options, message.update.dialogTranslation)
30068
+ };
30069
+ break;
29806
30070
  default:
29807
30071
  let u = options.readUnknownField;
29808
30072
  if (u === "throw")
@@ -29911,6 +30175,8 @@ class Update$Type extends import_runtime4.MessageType {
29911
30175
  UpdateUserRemovedFromChat.internalBinaryWrite(message.update.userRemovedFromChat, writer.tag(48, import_runtime.WireType.LengthDelimited).fork(), options).join();
29912
30176
  if (message.update.oneofKind === "acknowledgement")
29913
30177
  ChatAcknowledgement.internalBinaryWrite(message.update.acknowledgement, writer.tag(49, import_runtime.WireType.LengthDelimited).fork(), options).join();
30178
+ if (message.update.oneofKind === "dialogTranslation")
30179
+ UpdateDialogTranslation.internalBinaryWrite(message.update.dialogTranslation, writer.tag(50, import_runtime.WireType.LengthDelimited).fork(), options).join();
29914
30180
  let u = options.writeUnknownFields;
29915
30181
  if (u !== false)
29916
30182
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -35056,7 +35322,8 @@ class BotChatSettingsFolder$Type extends import_runtime4.MessageType {
35056
35322
  { no: 4, name: "host_label", kind: "scalar", T: 9 },
35057
35323
  { no: 5, name: "allows_local_picker", kind: "scalar", T: 8 },
35058
35324
  { no: 6, name: "local_picker_port", kind: "scalar", opt: true, T: 13 },
35059
- { no: 7, name: "local_picker_capability", kind: "scalar", opt: true, T: 9 }
35325
+ { no: 7, name: "local_picker_capability", kind: "scalar", opt: true, T: 9 },
35326
+ { no: 8, name: "remote_browser_version", kind: "scalar", opt: true, T: 13 }
35060
35327
  ]);
35061
35328
  }
35062
35329
  create(value) {
@@ -35096,6 +35363,9 @@ class BotChatSettingsFolder$Type extends import_runtime4.MessageType {
35096
35363
  case 7:
35097
35364
  message.localPickerCapability = reader.string();
35098
35365
  break;
35366
+ case 8:
35367
+ message.remoteBrowserVersion = reader.uint32();
35368
+ break;
35099
35369
  default:
35100
35370
  let u = options.readUnknownField;
35101
35371
  if (u === "throw")
@@ -35122,6 +35392,8 @@ class BotChatSettingsFolder$Type extends import_runtime4.MessageType {
35122
35392
  writer.tag(6, import_runtime.WireType.Varint).uint32(message.localPickerPort);
35123
35393
  if (message.localPickerCapability !== undefined)
35124
35394
  writer.tag(7, import_runtime.WireType.LengthDelimited).string(message.localPickerCapability);
35395
+ if (message.remoteBrowserVersion !== undefined)
35396
+ writer.tag(8, import_runtime.WireType.Varint).uint32(message.remoteBrowserVersion);
35125
35397
  let u = options.writeUnknownFields;
35126
35398
  if (u !== false)
35127
35399
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -38366,6 +38638,542 @@ class ChatAcknowledgements$Type extends import_runtime4.MessageType {
38366
38638
  }
38367
38639
  var ChatAcknowledgements = new ChatAcknowledgements$Type;
38368
38640
 
38641
+ class TranscribeVoiceDraftInput$Type extends import_runtime4.MessageType {
38642
+ constructor() {
38643
+ super("TranscribeVoiceDraftInput", [
38644
+ { no: 1, name: "audio", kind: "scalar", T: 12 },
38645
+ { no: 2, name: "mime_type", kind: "scalar", T: 9 },
38646
+ { no: 3, name: "duration", kind: "scalar", T: 13 }
38647
+ ]);
38648
+ }
38649
+ create(value) {
38650
+ const message = globalThis.Object.create(this.messagePrototype);
38651
+ message.audio = new Uint8Array(0);
38652
+ message.mimeType = "";
38653
+ message.duration = 0;
38654
+ if (value !== undefined)
38655
+ import_runtime3.reflectionMergePartial(this, message, value);
38656
+ return message;
38657
+ }
38658
+ internalBinaryRead(reader, length, options, target) {
38659
+ let message = target ?? this.create(), end = reader.pos + length;
38660
+ while (reader.pos < end) {
38661
+ let [fieldNo, wireType] = reader.tag();
38662
+ switch (fieldNo) {
38663
+ case 1:
38664
+ message.audio = reader.bytes();
38665
+ break;
38666
+ case 2:
38667
+ message.mimeType = reader.string();
38668
+ break;
38669
+ case 3:
38670
+ message.duration = reader.uint32();
38671
+ break;
38672
+ default:
38673
+ let u = options.readUnknownField;
38674
+ if (u === "throw")
38675
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
38676
+ let d = reader.skip(wireType);
38677
+ if (u !== false)
38678
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
38679
+ }
38680
+ }
38681
+ return message;
38682
+ }
38683
+ internalBinaryWrite(message, writer, options) {
38684
+ if (message.audio.length)
38685
+ writer.tag(1, import_runtime.WireType.LengthDelimited).bytes(message.audio);
38686
+ if (message.mimeType !== "")
38687
+ writer.tag(2, import_runtime.WireType.LengthDelimited).string(message.mimeType);
38688
+ if (message.duration !== 0)
38689
+ writer.tag(3, import_runtime.WireType.Varint).uint32(message.duration);
38690
+ let u = options.writeUnknownFields;
38691
+ if (u !== false)
38692
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
38693
+ return writer;
38694
+ }
38695
+ }
38696
+ var TranscribeVoiceDraftInput = new TranscribeVoiceDraftInput$Type;
38697
+
38698
+ class TranscribeVoiceDraftResult$Type extends import_runtime4.MessageType {
38699
+ constructor() {
38700
+ super("TranscribeVoiceDraftResult", [
38701
+ { no: 1, name: "text", kind: "scalar", T: 9 }
38702
+ ]);
38703
+ }
38704
+ create(value) {
38705
+ const message = globalThis.Object.create(this.messagePrototype);
38706
+ message.text = "";
38707
+ if (value !== undefined)
38708
+ import_runtime3.reflectionMergePartial(this, message, value);
38709
+ return message;
38710
+ }
38711
+ internalBinaryRead(reader, length, options, target) {
38712
+ let message = target ?? this.create(), end = reader.pos + length;
38713
+ while (reader.pos < end) {
38714
+ let [fieldNo, wireType] = reader.tag();
38715
+ switch (fieldNo) {
38716
+ case 1:
38717
+ message.text = reader.string();
38718
+ break;
38719
+ default:
38720
+ let u = options.readUnknownField;
38721
+ if (u === "throw")
38722
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
38723
+ let d = reader.skip(wireType);
38724
+ if (u !== false)
38725
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
38726
+ }
38727
+ }
38728
+ return message;
38729
+ }
38730
+ internalBinaryWrite(message, writer, options) {
38731
+ if (message.text !== "")
38732
+ writer.tag(1, import_runtime.WireType.LengthDelimited).string(message.text);
38733
+ let u = options.writeUnknownFields;
38734
+ if (u !== false)
38735
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
38736
+ return writer;
38737
+ }
38738
+ }
38739
+ var TranscribeVoiceDraftResult = new TranscribeVoiceDraftResult$Type;
38740
+
38741
+ class RequestBotFilesystemInput$Type extends import_runtime4.MessageType {
38742
+ constructor() {
38743
+ super("RequestBotFilesystemInput", [
38744
+ { no: 1, name: "peer_id", kind: "message", T: () => InputPeer },
38745
+ { no: 2, name: "bot_user_id", kind: "scalar", T: 3, L: 0 },
38746
+ { no: 3, name: "host_installation_id", kind: "scalar", T: 9 },
38747
+ { no: 4, name: "operation", kind: "enum", T: () => ["RequestBotFilesystemInput.Operation", RequestBotFilesystemInput_Operation] },
38748
+ { no: 5, name: "path", kind: "scalar", T: 9 },
38749
+ { no: 6, name: "after", kind: "scalar", T: 9 }
38750
+ ]);
38751
+ }
38752
+ create(value) {
38753
+ const message = globalThis.Object.create(this.messagePrototype);
38754
+ message.botUserId = 0n;
38755
+ message.hostInstallationId = "";
38756
+ message.operation = 0;
38757
+ message.path = "";
38758
+ message.after = "";
38759
+ if (value !== undefined)
38760
+ import_runtime3.reflectionMergePartial(this, message, value);
38761
+ return message;
38762
+ }
38763
+ internalBinaryRead(reader, length, options, target) {
38764
+ let message = target ?? this.create(), end = reader.pos + length;
38765
+ while (reader.pos < end) {
38766
+ let [fieldNo, wireType] = reader.tag();
38767
+ switch (fieldNo) {
38768
+ case 1:
38769
+ message.peerId = InputPeer.internalBinaryRead(reader, reader.uint32(), options, message.peerId);
38770
+ break;
38771
+ case 2:
38772
+ message.botUserId = reader.int64().toBigInt();
38773
+ break;
38774
+ case 3:
38775
+ message.hostInstallationId = reader.string();
38776
+ break;
38777
+ case 4:
38778
+ message.operation = reader.int32();
38779
+ break;
38780
+ case 5:
38781
+ message.path = reader.string();
38782
+ break;
38783
+ case 6:
38784
+ message.after = reader.string();
38785
+ break;
38786
+ default:
38787
+ let u = options.readUnknownField;
38788
+ if (u === "throw")
38789
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
38790
+ let d = reader.skip(wireType);
38791
+ if (u !== false)
38792
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
38793
+ }
38794
+ }
38795
+ return message;
38796
+ }
38797
+ internalBinaryWrite(message, writer, options) {
38798
+ if (message.peerId)
38799
+ InputPeer.internalBinaryWrite(message.peerId, writer.tag(1, import_runtime.WireType.LengthDelimited).fork(), options).join();
38800
+ if (message.botUserId !== 0n)
38801
+ writer.tag(2, import_runtime.WireType.Varint).int64(message.botUserId);
38802
+ if (message.hostInstallationId !== "")
38803
+ writer.tag(3, import_runtime.WireType.LengthDelimited).string(message.hostInstallationId);
38804
+ if (message.operation !== 0)
38805
+ writer.tag(4, import_runtime.WireType.Varint).int32(message.operation);
38806
+ if (message.path !== "")
38807
+ writer.tag(5, import_runtime.WireType.LengthDelimited).string(message.path);
38808
+ if (message.after !== "")
38809
+ writer.tag(6, import_runtime.WireType.LengthDelimited).string(message.after);
38810
+ let u = options.writeUnknownFields;
38811
+ if (u !== false)
38812
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
38813
+ return writer;
38814
+ }
38815
+ }
38816
+ var RequestBotFilesystemInput = new RequestBotFilesystemInput$Type;
38817
+
38818
+ class BotFilesystemEntry$Type extends import_runtime4.MessageType {
38819
+ constructor() {
38820
+ super("BotFilesystemEntry", [
38821
+ { no: 1, name: "name", kind: "scalar", T: 9 },
38822
+ { no: 2, name: "kind", kind: "enum", T: () => ["BotFilesystemEntry.Kind", BotFilesystemEntry_Kind] },
38823
+ { no: 3, name: "size", kind: "scalar", T: 4, L: 0 }
38824
+ ]);
38825
+ }
38826
+ create(value) {
38827
+ const message = globalThis.Object.create(this.messagePrototype);
38828
+ message.name = "";
38829
+ message.kind = 0;
38830
+ message.size = 0n;
38831
+ if (value !== undefined)
38832
+ import_runtime3.reflectionMergePartial(this, message, value);
38833
+ return message;
38834
+ }
38835
+ internalBinaryRead(reader, length, options, target) {
38836
+ let message = target ?? this.create(), end = reader.pos + length;
38837
+ while (reader.pos < end) {
38838
+ let [fieldNo, wireType] = reader.tag();
38839
+ switch (fieldNo) {
38840
+ case 1:
38841
+ message.name = reader.string();
38842
+ break;
38843
+ case 2:
38844
+ message.kind = reader.int32();
38845
+ break;
38846
+ case 3:
38847
+ message.size = reader.uint64().toBigInt();
38848
+ break;
38849
+ default:
38850
+ let u = options.readUnknownField;
38851
+ if (u === "throw")
38852
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
38853
+ let d = reader.skip(wireType);
38854
+ if (u !== false)
38855
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
38856
+ }
38857
+ }
38858
+ return message;
38859
+ }
38860
+ internalBinaryWrite(message, writer, options) {
38861
+ if (message.name !== "")
38862
+ writer.tag(1, import_runtime.WireType.LengthDelimited).string(message.name);
38863
+ if (message.kind !== 0)
38864
+ writer.tag(2, import_runtime.WireType.Varint).int32(message.kind);
38865
+ if (message.size !== 0n)
38866
+ writer.tag(3, import_runtime.WireType.Varint).uint64(message.size);
38867
+ let u = options.writeUnknownFields;
38868
+ if (u !== false)
38869
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
38870
+ return writer;
38871
+ }
38872
+ }
38873
+ var BotFilesystemEntry = new BotFilesystemEntry$Type;
38874
+
38875
+ class BotFilesystemListing$Type extends import_runtime4.MessageType {
38876
+ constructor() {
38877
+ super("BotFilesystemListing", [
38878
+ { no: 1, name: "path", kind: "scalar", T: 9 },
38879
+ { no: 2, name: "parent_path", kind: "scalar", opt: true, T: 9 },
38880
+ { no: 3, name: "entries", kind: "message", repeat: 1, T: () => BotFilesystemEntry },
38881
+ { no: 4, name: "next_after", kind: "scalar", opt: true, T: 9 }
38882
+ ]);
38883
+ }
38884
+ create(value) {
38885
+ const message = globalThis.Object.create(this.messagePrototype);
38886
+ message.path = "";
38887
+ message.entries = [];
38888
+ if (value !== undefined)
38889
+ import_runtime3.reflectionMergePartial(this, message, value);
38890
+ return message;
38891
+ }
38892
+ internalBinaryRead(reader, length, options, target) {
38893
+ let message = target ?? this.create(), end = reader.pos + length;
38894
+ while (reader.pos < end) {
38895
+ let [fieldNo, wireType] = reader.tag();
38896
+ switch (fieldNo) {
38897
+ case 1:
38898
+ message.path = reader.string();
38899
+ break;
38900
+ case 2:
38901
+ message.parentPath = reader.string();
38902
+ break;
38903
+ case 3:
38904
+ message.entries.push(BotFilesystemEntry.internalBinaryRead(reader, reader.uint32(), options));
38905
+ break;
38906
+ case 4:
38907
+ message.nextAfter = reader.string();
38908
+ break;
38909
+ default:
38910
+ let u = options.readUnknownField;
38911
+ if (u === "throw")
38912
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
38913
+ let d = reader.skip(wireType);
38914
+ if (u !== false)
38915
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
38916
+ }
38917
+ }
38918
+ return message;
38919
+ }
38920
+ internalBinaryWrite(message, writer, options) {
38921
+ if (message.path !== "")
38922
+ writer.tag(1, import_runtime.WireType.LengthDelimited).string(message.path);
38923
+ if (message.parentPath !== undefined)
38924
+ writer.tag(2, import_runtime.WireType.LengthDelimited).string(message.parentPath);
38925
+ for (let i = 0;i < message.entries.length; i++)
38926
+ BotFilesystemEntry.internalBinaryWrite(message.entries[i], writer.tag(3, import_runtime.WireType.LengthDelimited).fork(), options).join();
38927
+ if (message.nextAfter !== undefined)
38928
+ writer.tag(4, import_runtime.WireType.LengthDelimited).string(message.nextAfter);
38929
+ let u = options.writeUnknownFields;
38930
+ if (u !== false)
38931
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
38932
+ return writer;
38933
+ }
38934
+ }
38935
+ var BotFilesystemListing = new BotFilesystemListing$Type;
38936
+
38937
+ class BotFilesystemResponse$Type extends import_runtime4.MessageType {
38938
+ constructor() {
38939
+ super("BotFilesystemResponse", [
38940
+ { no: 1, name: "listing", kind: "message", oneof: "result", T: () => BotFilesystemListing },
38941
+ { no: 2, name: "workspace_id", kind: "scalar", oneof: "result", T: 9 },
38942
+ { no: 3, name: "problem", kind: "scalar", oneof: "result", T: 9 }
38943
+ ]);
38944
+ }
38945
+ create(value) {
38946
+ const message = globalThis.Object.create(this.messagePrototype);
38947
+ message.result = { oneofKind: undefined };
38948
+ if (value !== undefined)
38949
+ import_runtime3.reflectionMergePartial(this, message, value);
38950
+ return message;
38951
+ }
38952
+ internalBinaryRead(reader, length, options, target) {
38953
+ let message = target ?? this.create(), end = reader.pos + length;
38954
+ while (reader.pos < end) {
38955
+ let [fieldNo, wireType] = reader.tag();
38956
+ switch (fieldNo) {
38957
+ case 1:
38958
+ message.result = {
38959
+ oneofKind: "listing",
38960
+ listing: BotFilesystemListing.internalBinaryRead(reader, reader.uint32(), options, message.result.listing)
38961
+ };
38962
+ break;
38963
+ case 2:
38964
+ message.result = {
38965
+ oneofKind: "workspaceId",
38966
+ workspaceId: reader.string()
38967
+ };
38968
+ break;
38969
+ case 3:
38970
+ message.result = {
38971
+ oneofKind: "problem",
38972
+ problem: reader.string()
38973
+ };
38974
+ break;
38975
+ default:
38976
+ let u = options.readUnknownField;
38977
+ if (u === "throw")
38978
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
38979
+ let d = reader.skip(wireType);
38980
+ if (u !== false)
38981
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
38982
+ }
38983
+ }
38984
+ return message;
38985
+ }
38986
+ internalBinaryWrite(message, writer, options) {
38987
+ if (message.result.oneofKind === "listing")
38988
+ BotFilesystemListing.internalBinaryWrite(message.result.listing, writer.tag(1, import_runtime.WireType.LengthDelimited).fork(), options).join();
38989
+ if (message.result.oneofKind === "workspaceId")
38990
+ writer.tag(2, import_runtime.WireType.LengthDelimited).string(message.result.workspaceId);
38991
+ if (message.result.oneofKind === "problem")
38992
+ writer.tag(3, import_runtime.WireType.LengthDelimited).string(message.result.problem);
38993
+ let u = options.writeUnknownFields;
38994
+ if (u !== false)
38995
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
38996
+ return writer;
38997
+ }
38998
+ }
38999
+ var BotFilesystemResponse = new BotFilesystemResponse$Type;
39000
+
39001
+ class RequestBotFilesystemResult$Type extends import_runtime4.MessageType {
39002
+ constructor() {
39003
+ super("RequestBotFilesystemResult", [
39004
+ { no: 1, name: "response", kind: "message", T: () => BotFilesystemResponse }
39005
+ ]);
39006
+ }
39007
+ create(value) {
39008
+ const message = globalThis.Object.create(this.messagePrototype);
39009
+ if (value !== undefined)
39010
+ import_runtime3.reflectionMergePartial(this, message, value);
39011
+ return message;
39012
+ }
39013
+ internalBinaryRead(reader, length, options, target) {
39014
+ let message = target ?? this.create(), end = reader.pos + length;
39015
+ while (reader.pos < end) {
39016
+ let [fieldNo, wireType] = reader.tag();
39017
+ switch (fieldNo) {
39018
+ case 1:
39019
+ message.response = BotFilesystemResponse.internalBinaryRead(reader, reader.uint32(), options, message.response);
39020
+ break;
39021
+ default:
39022
+ let u = options.readUnknownField;
39023
+ if (u === "throw")
39024
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
39025
+ let d = reader.skip(wireType);
39026
+ if (u !== false)
39027
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
39028
+ }
39029
+ }
39030
+ return message;
39031
+ }
39032
+ internalBinaryWrite(message, writer, options) {
39033
+ if (message.response)
39034
+ BotFilesystemResponse.internalBinaryWrite(message.response, writer.tag(1, import_runtime.WireType.LengthDelimited).fork(), options).join();
39035
+ let u = options.writeUnknownFields;
39036
+ if (u !== false)
39037
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
39038
+ return writer;
39039
+ }
39040
+ }
39041
+ var RequestBotFilesystemResult = new RequestBotFilesystemResult$Type;
39042
+
39043
+ class BotFilesystemRequested$Type extends import_runtime4.MessageType {
39044
+ constructor() {
39045
+ super("BotFilesystemRequested", [
39046
+ { no: 1, name: "request_id", kind: "scalar", T: 4, L: 0 },
39047
+ { no: 2, name: "actor_user_id", kind: "scalar", T: 3, L: 0 },
39048
+ { no: 3, name: "chat_id", kind: "scalar", T: 3, L: 0 },
39049
+ { no: 4, name: "input", kind: "message", T: () => RequestBotFilesystemInput }
39050
+ ]);
39051
+ }
39052
+ create(value) {
39053
+ const message = globalThis.Object.create(this.messagePrototype);
39054
+ message.requestId = 0n;
39055
+ message.actorUserId = 0n;
39056
+ message.chatId = 0n;
39057
+ if (value !== undefined)
39058
+ import_runtime3.reflectionMergePartial(this, message, value);
39059
+ return message;
39060
+ }
39061
+ internalBinaryRead(reader, length, options, target) {
39062
+ let message = target ?? this.create(), end = reader.pos + length;
39063
+ while (reader.pos < end) {
39064
+ let [fieldNo, wireType] = reader.tag();
39065
+ switch (fieldNo) {
39066
+ case 1:
39067
+ message.requestId = reader.uint64().toBigInt();
39068
+ break;
39069
+ case 2:
39070
+ message.actorUserId = reader.int64().toBigInt();
39071
+ break;
39072
+ case 3:
39073
+ message.chatId = reader.int64().toBigInt();
39074
+ break;
39075
+ case 4:
39076
+ message.input = RequestBotFilesystemInput.internalBinaryRead(reader, reader.uint32(), options, message.input);
39077
+ break;
39078
+ default:
39079
+ let u = options.readUnknownField;
39080
+ if (u === "throw")
39081
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
39082
+ let d = reader.skip(wireType);
39083
+ if (u !== false)
39084
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
39085
+ }
39086
+ }
39087
+ return message;
39088
+ }
39089
+ internalBinaryWrite(message, writer, options) {
39090
+ if (message.requestId !== 0n)
39091
+ writer.tag(1, import_runtime.WireType.Varint).uint64(message.requestId);
39092
+ if (message.actorUserId !== 0n)
39093
+ writer.tag(2, import_runtime.WireType.Varint).int64(message.actorUserId);
39094
+ if (message.chatId !== 0n)
39095
+ writer.tag(3, import_runtime.WireType.Varint).int64(message.chatId);
39096
+ if (message.input)
39097
+ RequestBotFilesystemInput.internalBinaryWrite(message.input, writer.tag(4, import_runtime.WireType.LengthDelimited).fork(), options).join();
39098
+ let u = options.writeUnknownFields;
39099
+ if (u !== false)
39100
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
39101
+ return writer;
39102
+ }
39103
+ }
39104
+ var BotFilesystemRequested = new BotFilesystemRequested$Type;
39105
+
39106
+ class AnswerBotFilesystemInput$Type extends import_runtime4.MessageType {
39107
+ constructor() {
39108
+ super("AnswerBotFilesystemInput", [
39109
+ { no: 1, name: "request_id", kind: "scalar", T: 4, L: 0 },
39110
+ { no: 2, name: "response", kind: "message", T: () => BotFilesystemResponse }
39111
+ ]);
39112
+ }
39113
+ create(value) {
39114
+ const message = globalThis.Object.create(this.messagePrototype);
39115
+ message.requestId = 0n;
39116
+ if (value !== undefined)
39117
+ import_runtime3.reflectionMergePartial(this, message, value);
39118
+ return message;
39119
+ }
39120
+ internalBinaryRead(reader, length, options, target) {
39121
+ let message = target ?? this.create(), end = reader.pos + length;
39122
+ while (reader.pos < end) {
39123
+ let [fieldNo, wireType] = reader.tag();
39124
+ switch (fieldNo) {
39125
+ case 1:
39126
+ message.requestId = reader.uint64().toBigInt();
39127
+ break;
39128
+ case 2:
39129
+ message.response = BotFilesystemResponse.internalBinaryRead(reader, reader.uint32(), options, message.response);
39130
+ break;
39131
+ default:
39132
+ let u = options.readUnknownField;
39133
+ if (u === "throw")
39134
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
39135
+ let d = reader.skip(wireType);
39136
+ if (u !== false)
39137
+ (u === true ? import_runtime2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
39138
+ }
39139
+ }
39140
+ return message;
39141
+ }
39142
+ internalBinaryWrite(message, writer, options) {
39143
+ if (message.requestId !== 0n)
39144
+ writer.tag(1, import_runtime.WireType.Varint).uint64(message.requestId);
39145
+ if (message.response)
39146
+ BotFilesystemResponse.internalBinaryWrite(message.response, writer.tag(2, import_runtime.WireType.LengthDelimited).fork(), options).join();
39147
+ let u = options.writeUnknownFields;
39148
+ if (u !== false)
39149
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
39150
+ return writer;
39151
+ }
39152
+ }
39153
+ var AnswerBotFilesystemInput = new AnswerBotFilesystemInput$Type;
39154
+
39155
+ class AnswerBotFilesystemResult$Type extends import_runtime4.MessageType {
39156
+ constructor() {
39157
+ super("AnswerBotFilesystemResult", []);
39158
+ }
39159
+ create(value) {
39160
+ const message = globalThis.Object.create(this.messagePrototype);
39161
+ if (value !== undefined)
39162
+ import_runtime3.reflectionMergePartial(this, message, value);
39163
+ return message;
39164
+ }
39165
+ internalBinaryRead(reader, length, options, target) {
39166
+ return target ?? this.create();
39167
+ }
39168
+ internalBinaryWrite(message, writer, options) {
39169
+ let u = options.writeUnknownFields;
39170
+ if (u !== false)
39171
+ (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
39172
+ return writer;
39173
+ }
39174
+ }
39175
+ var AnswerBotFilesystemResult = new AnswerBotFilesystemResult$Type;
39176
+
38369
39177
  // ../node_modules/.bun/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/utils.js
38370
39178
  /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
38371
39179
  function isBytes(a) {
@@ -39144,6 +39952,13 @@ var asInlineId = (value, fieldName = "id") => {
39144
39952
  };
39145
39953
 
39146
39954
  // ../sdk/dist/utils/async-channel.js
39955
+ class ChannelConsumerError extends Error {
39956
+ constructor(message) {
39957
+ super(message);
39958
+ this.name = "ChannelConsumerError";
39959
+ }
39960
+ }
39961
+
39147
39962
  class AsyncChannelOverflowError extends Error {
39148
39963
  capacity;
39149
39964
  constructor(capacity) {
@@ -39253,6 +40068,7 @@ class AcknowledgedAsyncChannel {
39253
40068
  closed = false;
39254
40069
  failure = null;
39255
40070
  iteratorClaimed = false;
40071
+ consumption = null;
39256
40072
  constructor(capacity, byteLimit) {
39257
40073
  this.capacity = capacity;
39258
40074
  this.byteLimit = byteLimit;
@@ -39266,7 +40082,7 @@ class AcknowledgedAsyncChannel {
39266
40082
  send(value) {
39267
40083
  if (this.closed)
39268
40084
  return Promise.resolve(false);
39269
- if (!this.waiter && this.queue.length >= this.capacity) {
40085
+ if (!this.waiter && this.queue.length + (this.consumption?.active.size ?? 0) >= this.capacity) {
39270
40086
  throw new AsyncChannelOverflowError(this.capacity);
39271
40087
  }
39272
40088
  const bytes = this.byteLimit?.byteLength(value) ?? 0;
@@ -39286,6 +40102,7 @@ class AcknowledgedAsyncChannel {
39286
40102
  waiter.resolve({ value, done: false });
39287
40103
  } else {
39288
40104
  this.queue.push(item);
40105
+ this.pumpConsumption();
39289
40106
  }
39290
40107
  });
39291
40108
  }
@@ -39300,6 +40117,16 @@ class AcknowledgedAsyncChannel {
39300
40117
  return;
39301
40118
  this.closed = true;
39302
40119
  this.failure = error;
40120
+ const consumption = this.consumption;
40121
+ this.consumption = null;
40122
+ if (consumption) {
40123
+ for (const item of consumption.active.keys())
40124
+ item.acknowledge(false);
40125
+ if (error)
40126
+ consumption.reject(error);
40127
+ else
40128
+ consumption.resolve();
40129
+ }
39303
40130
  this.active?.acknowledge(false);
39304
40131
  this.active = null;
39305
40132
  for (const item of this.queue)
@@ -39315,6 +40142,65 @@ class AcknowledgedAsyncChannel {
39315
40142
  else
39316
40143
  waiter.resolve({ value: undefined, done: true });
39317
40144
  }
40145
+ consume(handler, key, concurrency = 8) {
40146
+ if (this.iteratorClaimed)
40147
+ return Promise.reject(new ChannelConsumerError("AcknowledgedAsyncChannel supports one consumer"));
40148
+ if (!Number.isSafeInteger(concurrency) || concurrency < 1) {
40149
+ return Promise.reject(new ChannelConsumerError("Consumer concurrency must be a positive safe integer"));
40150
+ }
40151
+ if (this.closed)
40152
+ return this.failure ? Promise.reject(this.failure) : Promise.resolve();
40153
+ this.iteratorClaimed = true;
40154
+ return new Promise((resolve, reject) => {
40155
+ this.consumption = { handler, key, concurrency, active: new Map, resolve, reject };
40156
+ this.pumpConsumption();
40157
+ });
40158
+ }
40159
+ pumpConsumption() {
40160
+ const owner = this.consumption;
40161
+ if (!owner || this.closed)
40162
+ return;
40163
+ try {
40164
+ while (owner.active.size < owner.concurrency && this.queue.length > 0) {
40165
+ if ([...owner.active.values()].includes(null))
40166
+ return;
40167
+ const keys = new Set(owner.active.values());
40168
+ let index = -1;
40169
+ let key = null;
40170
+ for (let i = 0;i < this.queue.length; i++) {
40171
+ const candidate = this.queue[i];
40172
+ const candidateKey = owner.key(candidate.value);
40173
+ if (candidateKey === null) {
40174
+ if (i === 0 && owner.active.size === 0)
40175
+ index = i;
40176
+ break;
40177
+ }
40178
+ if (!keys.has(candidateKey)) {
40179
+ index = i;
40180
+ key = candidateKey;
40181
+ break;
40182
+ }
40183
+ }
40184
+ if (index < 0)
40185
+ return;
40186
+ const item = this.queue.splice(index, 1)[0];
40187
+ owner.active.set(item, key);
40188
+ Promise.resolve().then(() => owner.handler(item.value)).then(() => {
40189
+ if (this.consumption !== owner)
40190
+ return;
40191
+ owner.active.delete(item);
40192
+ this.bufferedBytes -= item.bytes;
40193
+ item.acknowledge(true);
40194
+ this.pumpConsumption();
40195
+ }, (error) => {
40196
+ if (this.consumption === owner)
40197
+ this.fail(error instanceof Error ? error : new Error("Inbound handler failed"));
40198
+ });
40199
+ }
40200
+ } catch (error) {
40201
+ this.fail(error instanceof Error ? error : new Error("Inbound routing failed"));
40202
+ }
40203
+ }
39318
40204
  [Symbol.asyncIterator]() {
39319
40205
  if (this.iteratorClaimed) {
39320
40206
  return {
@@ -39322,8 +40208,11 @@ class AcknowledgedAsyncChannel {
39322
40208
  };
39323
40209
  }
39324
40210
  this.iteratorClaimed = true;
40211
+ let returned = false;
39325
40212
  return {
39326
40213
  next: () => {
40214
+ if (returned)
40215
+ return Promise.resolve({ value: undefined, done: true });
39327
40216
  if (this.active) {
39328
40217
  this.bufferedBytes -= this.active.bytes;
39329
40218
  this.active.acknowledge(true);
@@ -39347,6 +40236,11 @@ class AcknowledgedAsyncChannel {
39347
40236
  });
39348
40237
  },
39349
40238
  return: () => {
40239
+ if (returned)
40240
+ return Promise.resolve({ value: undefined, done: true });
40241
+ returned = true;
40242
+ this.waiter?.resolve({ value: undefined, done: true });
40243
+ this.waiter = null;
39350
40244
  if (this.active) {
39351
40245
  this.bufferedBytes -= this.active.bytes;
39352
40246
  this.active.acknowledge(false);
@@ -40025,10 +40919,12 @@ var normalizeRpcTimeoutMs = (timeoutMs, fallback) => {
40025
40919
 
40026
40920
  class ProtocolClientError extends Error {
40027
40921
  code;
40922
+ rpcCode;
40028
40923
  constructor(code, details) {
40029
40924
  super(details?.message ?? code);
40030
40925
  this.code = code;
40031
40926
  this.name = `ProtocolClientError:${code}`;
40927
+ this.rpcCode = details?.code;
40032
40928
  }
40033
40929
  }
40034
40930
  var commitOutcomeUnknownError = (message) => new ProtocolClientError("commit-outcome-unknown", { message });
@@ -44851,8 +45747,11 @@ class InlineSdkClient {
44851
45747
  peerResolutionRequestedByChatId = new Map;
44852
45748
  recoveryReconnectInFlight = null;
44853
45749
  degradedUpdateBuckets = new Map;
45750
+ discoveryRetry = null;
45751
+ recoveryRetries = new Map;
44854
45752
  liveCursorFences = new Set;
44855
45753
  liveAdmittedSeqByBucket = new Map;
45754
+ liveDeliveriesByBucket = new Map;
44856
45755
  discoveryRound = null;
44857
45756
  discoveryInFlight = null;
44858
45757
  discoveryCommitInFlight = null;
@@ -44945,12 +45844,14 @@ class InlineSdkClient {
44945
45844
  }
44946
45845
  }
44947
45846
  async close() {
44948
- if (!this.started)
44949
- return;
45847
+ const wasStarted = this.started;
44950
45848
  this.closed = true;
44951
45849
  this.started = false;
45850
+ this.cancelRecoveryRetries();
44952
45851
  this.rejectOpen(new Error("closed"));
44953
45852
  this.eventStream.close();
45853
+ if (!wasStarted)
45854
+ return;
44954
45855
  await settleWithin(this.protocol.stopTransport(), closeJoinTimeoutMs, () => this.log.warn?.("Timed out stopping SDK transport during close"));
44955
45856
  await settleWithin(Promise.allSettled([
44956
45857
  ...this.catchUpInFlightByChatId.values(),
@@ -45012,6 +45913,20 @@ class InlineSdkClient {
45012
45913
  events() {
45013
45914
  return this.eventStream;
45014
45915
  }
45916
+ consumeEvents(handler, options) {
45917
+ return this.eventStream.consume(handler, (event) => {
45918
+ const bucket = this.bucketForEvent(event);
45919
+ if (bucket?.kind === "user")
45920
+ return null;
45921
+ if (bucket)
45922
+ return this.updateBucketKey(bucket);
45923
+ return "chatId" in event && typeof event.chatId === "bigint" ? `chat:${event.chatId}` : null;
45924
+ }, options?.concurrency).catch(async (error) => {
45925
+ if (!(error instanceof ChannelConsumerError))
45926
+ await this.close();
45927
+ throw error;
45928
+ });
45929
+ }
45015
45930
  exportState() {
45016
45931
  return {
45017
45932
  version: 1,
@@ -45421,6 +46336,7 @@ class InlineSdkClient {
45421
46336
  this.log.error?.("SDK listener crashed", failure);
45422
46337
  this.started = false;
45423
46338
  this.closed = true;
46339
+ this.cancelRecoveryRetries();
45424
46340
  this.rejectOpen(failure);
45425
46341
  this.eventStream.fail(failure);
45426
46342
  this.protocol.stopTransport().catch((stopError) => {
@@ -45433,6 +46349,7 @@ class InlineSdkClient {
45433
46349
  return;
45434
46350
  this.authenticationError = error;
45435
46351
  this.started = false;
46352
+ this.cancelRecoveryRetries();
45436
46353
  this.rejectOpen(error);
45437
46354
  this.eventStream.close();
45438
46355
  try {
@@ -45442,6 +46359,7 @@ class InlineSdkClient {
45442
46359
  }
45443
46360
  }
45444
46361
  async onOpen() {
46362
+ this.cancelRecoveryRetries();
45445
46363
  this.requestCatchUpUser();
45446
46364
  for (const bucket of this.degradedUpdateBuckets.values()) {
45447
46365
  this.requestCatchUpForDegradedBucket(bucket);
@@ -45492,6 +46410,8 @@ class InlineSdkClient {
45492
46410
  return this.discoveryInFlight;
45493
46411
  if (this.discoveryCommitInFlight)
45494
46412
  return this.discoveryCommitInFlight;
46413
+ if (this.discoveryRetry?.timer)
46414
+ return;
45495
46415
  const round = {
45496
46416
  resultReceived: false,
45497
46417
  collectingHints: true,
@@ -45524,6 +46444,11 @@ class InlineSdkClient {
45524
46444
  this.log.warn?.("GET_UPDATES_STATE failed (continuing without date cursor)", error);
45525
46445
  if (this.discoveryRound === round)
45526
46446
  this.discoveryRound = null;
46447
+ if (error instanceof ProtocolClientError && (error.code === "timeout" || error.code === "not-connected" || error.code === "capacity-exceeded" || error.rpcCode === RpcError_Code.INTERNAL_ERROR || error.rpcCode === 500 || error.rpcCode === RpcError_Code.RATE_LIMIT || error.rpcCode === 429)) {
46448
+ this.scheduleDiscoveryRetry(error.rpcCode === RpcError_Code.RATE_LIMIT || error.rpcCode === 429 ? "rate_limited" : "discovery_failed");
46449
+ } else {
46450
+ this.log.error?.("Sync discovery unavailable", { reason: "request_rejected" });
46451
+ }
45527
46452
  }
45528
46453
  }
45529
46454
  tryCommitDiscoveryRound(round) {
@@ -45548,12 +46473,15 @@ class InlineSdkClient {
45548
46473
  return;
45549
46474
  if (saved) {
45550
46475
  this.discoveryRound = null;
46476
+ clearTimeout(this.discoveryRetry?.timer);
46477
+ this.discoveryRetry = null;
45551
46478
  return;
45552
46479
  }
45553
46480
  this.state.dateCursor = previousDateCursor;
45554
46481
  this.scheduleStateSave();
45555
46482
  this.discoveryRound = null;
45556
46483
  this.log.warn?.("Failed to persist discovery checkpoint; preserving previous date cursor");
46484
+ this.scheduleDiscoveryRetry("checkpoint_write_failed");
45557
46485
  }).finally(() => {
45558
46486
  if (this.discoveryCommitInFlight === commit)
45559
46487
  this.discoveryCommitInFlight = null;
@@ -45888,20 +46816,23 @@ class InlineSdkClient {
45888
46816
  try {
45889
46817
  acknowledged = this.eventStream.send(event);
45890
46818
  } catch (error) {
45891
- const bucket = this.bucketForEvent(event);
45892
- if (bucket) {
45893
- this.fenceLiveCursor(bucket);
45894
- this.markUpdateBucketDegraded(bucket);
45895
- this.requestCatchUpAfterEventOverflow(bucket, event);
46819
+ const bucket2 = this.bucketForEvent(event);
46820
+ if (bucket2) {
46821
+ this.fenceLiveCursor(bucket2);
46822
+ this.markUpdateBucketDegraded(bucket2);
46823
+ this.requestCatchUpAfterEventOverflow(bucket2, event);
45896
46824
  }
45897
46825
  this.log.warn?.("Inbound event buffer overflow; durable cursor remains unchanged and transport will recover", {
45898
- bucket: bucket ? this.updateBucketKey(bucket) : "none",
46826
+ bucket: bucket2 ? this.updateBucketKey(bucket2) : "none",
45899
46827
  error: extractErrorMessage(error)
45900
46828
  });
45901
46829
  this.requestRecoveryReconnect("inbound-event-buffer-overflow");
45902
46830
  return Promise.resolve(false);
45903
46831
  }
45904
- return acknowledged.then((applied) => {
46832
+ const bucket = source === "live" ? this.sequencedBucketForEvent(event) : undefined;
46833
+ const key = bucket ? this.updateBucketKey(bucket) : undefined;
46834
+ const deliveries = key ? this.liveDeliveriesByBucket.get(key) ?? new Set : undefined;
46835
+ const delivery = acknowledged.then((applied) => {
45905
46836
  if (applied) {
45906
46837
  onApplied?.();
45907
46838
  if (source === "live")
@@ -45909,8 +46840,16 @@ class InlineSdkClient {
45909
46840
  } else if (source === "live" && this.started) {
45910
46841
  this.recoverLiveEvent(event, "consumer-did-not-apply");
45911
46842
  }
46843
+ deliveries?.delete(delivery);
46844
+ if (key && deliveries?.size === 0)
46845
+ this.liveDeliveriesByBucket.delete(key);
45912
46846
  return applied;
45913
46847
  });
46848
+ if (key && deliveries) {
46849
+ deliveries.add(delivery);
46850
+ this.liveDeliveriesByBucket.set(key, deliveries);
46851
+ }
46852
+ return delivery;
45914
46853
  }
45915
46854
  bucketForEvent(event) {
45916
46855
  switch (event.kind) {
@@ -46088,20 +47027,25 @@ class InlineSdkClient {
46088
47027
  }
46089
47028
  requestCatchUpForDegradedBucket(bucket) {
46090
47029
  switch (bucket.kind) {
46091
- case "chat":
46092
- if (bucket.peer && this.isReliableChatPeer(bucket.peer)) {
46093
- this.requestCatchUpChat({ chatId: bucket.chatId, peer: bucket.peer });
47030
+ case "chat": {
47031
+ const request = this.catchUpRequestedByChatId.get(bucket.chatId) ?? this.peerResolutionRequestedByChatId.get(bucket.chatId);
47032
+ const updateSeq = request && !request.toLatest ? request.endSeq : undefined;
47033
+ const peer = bucket.peer ?? this.persistedChatPeer(bucket.chatId);
47034
+ if (peer && this.isReliableChatPeer(peer)) {
47035
+ this.requestCatchUpChat({ chatId: bucket.chatId, peer, updateSeq });
46094
47036
  } else {
46095
- const persistedPeer = this.persistedChatPeer(bucket.chatId);
46096
- if (persistedPeer)
46097
- this.requestCatchUpChat({ chatId: bucket.chatId, peer: persistedPeer });
46098
- else
46099
- this.resolvePersistedChatPeer(bucket.chatId);
47037
+ this.resolvePersistedChatPeer(bucket.chatId, updateSeq);
46100
47038
  }
46101
47039
  return;
46102
- case "space":
46103
- this.requestCatchUpSpace({ spaceId: bucket.spaceId });
47040
+ }
47041
+ case "space": {
47042
+ const request = this.catchUpRequestedBySpaceId.get(bucket.spaceId);
47043
+ this.requestCatchUpSpace({
47044
+ spaceId: bucket.spaceId,
47045
+ updateSeq: request && !request.toLatest ? request.endSeq : undefined
47046
+ });
46104
47047
  return;
47048
+ }
46105
47049
  case "user":
46106
47050
  this.requestCatchUpUser(true);
46107
47051
  return;
@@ -46286,7 +47230,7 @@ class InlineSdkClient {
46286
47230
  bumpChatSeq(chatId, seq, source) {
46287
47231
  if (source === "user" || source === "space" || source === "chat")
46288
47232
  return;
46289
- if (source === "live" && this.liveCursorFences.has(`chat:${chatId}`))
47233
+ if (source === "live" && this.liveCursorFences.has(`chat:${chatId}`) && seq !== (this.state.lastSeqByChatId?.[chatId.toString()] ?? 0) + 1)
46290
47234
  return;
46291
47235
  if (!Number.isFinite(seq))
46292
47236
  return;
@@ -46295,6 +47239,7 @@ class InlineSdkClient {
46295
47239
  const key = chatId.toString();
46296
47240
  const prev = this.state.lastSeqByChatId[key] ?? 0;
46297
47241
  if (seq > prev) {
47242
+ this.resetRecoveryBackoff({ kind: "chat", chatId });
46298
47243
  this.state.lastSeqByChatId[key] = seq;
46299
47244
  this.scheduleStateSave();
46300
47245
  }
@@ -46303,7 +47248,7 @@ class InlineSdkClient {
46303
47248
  bumpSpaceSeq(spaceId, seq, source) {
46304
47249
  if (source === "user" || source === "space" || source === "chat")
46305
47250
  return;
46306
- if (source === "live" && this.liveCursorFences.has(`space:${spaceId}`))
47251
+ if (source === "live" && this.liveCursorFences.has(`space:${spaceId}`) && seq !== (this.state.lastSeqBySpaceId?.[spaceId.toString()] ?? 0) + 1)
46307
47252
  return;
46308
47253
  if (!Number.isFinite(seq))
46309
47254
  return;
@@ -46312,6 +47257,7 @@ class InlineSdkClient {
46312
47257
  const key = spaceId.toString();
46313
47258
  const prev = this.state.lastSeqBySpaceId[key] ?? 0;
46314
47259
  if (seq > prev) {
47260
+ this.resetRecoveryBackoff({ kind: "space", spaceId });
46315
47261
  this.state.lastSeqBySpaceId[key] = seq;
46316
47262
  this.scheduleStateSave();
46317
47263
  }
@@ -46326,12 +47272,13 @@ class InlineSdkClient {
46326
47272
  bumpUserSeq(seq, source) {
46327
47273
  if (source === "user" || source === "space" || source === "chat")
46328
47274
  return;
46329
- if (source === "live" && this.liveCursorFences.has("user"))
47275
+ if (source === "live" && this.liveCursorFences.has("user") && seq !== (this.state.lastUserSeq ?? 0) + 1)
46330
47276
  return;
46331
47277
  if (!Number.isFinite(seq) || seq <= 0)
46332
47278
  return;
46333
47279
  const prev = this.state.lastUserSeq ?? 0;
46334
47280
  if (seq > prev) {
47281
+ this.resetRecoveryBackoff({ kind: "user" });
46335
47282
  this.state.lastUserSeq = seq;
46336
47283
  this.scheduleStateSave();
46337
47284
  }
@@ -46345,14 +47292,17 @@ class InlineSdkClient {
46345
47292
  if (this.userCatchUpInFlight) {
46346
47293
  return this.userCatchUpInFlight;
46347
47294
  }
47295
+ if (this.recoveryRetries.get("user")?.timer)
47296
+ return null;
46348
47297
  this.fenceLiveCursor({ kind: "user" });
46349
47298
  this.userCatchUpInFlight = this.doCatchUpUser(lastUserSeq ?? 0).catch((error) => {
46350
- this.markUpdateBucketDegraded({ kind: "user" });
47299
+ this.recordCatchUpFailure({ kind: "user" }, error);
46351
47300
  this.log.warn?.("GET_UPDATES user catch-up failed; bucket remains degraded", {
46352
47301
  error: extractErrorMessage(error)
46353
47302
  });
46354
47303
  }).finally(() => {
46355
47304
  this.userCatchUpInFlight = null;
47305
+ this.scheduleRecoveryRetry({ kind: "user" });
46356
47306
  });
46357
47307
  return this.userCatchUpInFlight;
46358
47308
  }
@@ -46405,7 +47355,7 @@ class InlineSdkClient {
46405
47355
  });
46406
47356
  }
46407
47357
  if (deliveredSeq <= cursor && !payload.final) {
46408
- this.markUpdateBucketDegraded({ kind: "user" });
47358
+ this.markUpdateBucketDegraded({ kind: "user" }, "non_progress");
46409
47359
  this.log.warn?.("GET_UPDATES user catch-up made no progress; bucket remains degraded", {
46410
47360
  cursor,
46411
47361
  deliveredSeq
@@ -46441,15 +47391,18 @@ class InlineSdkClient {
46441
47391
  const existing = this.catchUpInFlightByChatId.get(params.chatId);
46442
47392
  if (existing)
46443
47393
  return existing;
47394
+ if (this.recoveryRetries.get(`chat:${params.chatId}`)?.timer)
47395
+ return Promise.resolve();
47396
+ const initialDemand = this.catchUpRequestedByChatId.get(params.chatId);
46444
47397
  const task = this.drainCatchUpChat(params.chatId).catch((error) => {
46445
- this.catchUpRequestedByChatId.delete(params.chatId);
46446
- this.markUpdateBucketDegraded({ kind: "chat", chatId: params.chatId, peer: params.peer });
47398
+ this.recordCatchUpFailure({ kind: "chat", chatId: params.chatId, peer: params.peer }, error, this.catchUpRequestedByChatId.get(params.chatId) !== initialDemand);
46447
47399
  this.log.warn?.("GET_UPDATES chat catch-up failed; bucket remains degraded", {
46448
47400
  chatId: params.chatId.toString(),
46449
47401
  error: extractErrorMessage(error)
46450
47402
  });
46451
47403
  }).finally(() => {
46452
47404
  this.catchUpInFlightByChatId.delete(params.chatId);
47405
+ this.scheduleRecoveryRetry({ kind: "chat", chatId: params.chatId });
46453
47406
  });
46454
47407
  this.catchUpInFlightByChatId.set(params.chatId, task);
46455
47408
  return task;
@@ -46473,12 +47426,8 @@ class InlineSdkClient {
46473
47426
  if (stop) {
46474
47427
  if (this.catchUpRequestedByChatId.get(chatId) !== request)
46475
47428
  continue;
46476
- this.catchUpRequestedByChatId.delete(chatId);
46477
- return;
46478
- }
46479
- const latest = this.catchUpRequestedByChatId.get(chatId);
46480
- const syncedSeq = this.state.lastSeqByChatId?.[key] ?? 0;
46481
- if (!latest || latest.endSeq != null && latest.endSeq <= syncedSeq) {
47429
+ if (this.degradedUpdateBuckets.has(`chat:${chatId}`))
47430
+ return;
46482
47431
  this.catchUpRequestedByChatId.delete(chatId);
46483
47432
  return;
46484
47433
  }
@@ -46545,7 +47494,7 @@ class InlineSdkClient {
46545
47494
  });
46546
47495
  }
46547
47496
  if (deliveredSeq <= cursor && !payload.final) {
46548
- this.markUpdateBucketDegraded({ kind: "chat", chatId, peer });
47497
+ this.markUpdateBucketDegraded({ kind: "chat", chatId, peer }, "non_progress");
46549
47498
  this.log.warn?.("GET_UPDATES made no progress; bucket remains degraded", {
46550
47499
  chatId: chatId.toString(),
46551
47500
  cursor,
@@ -46563,7 +47512,7 @@ class InlineSdkClient {
46563
47512
  continue;
46564
47513
  }
46565
47514
  if (endSeq != null && deliveredSeq < endSeq) {
46566
- this.markUpdateBucketDegraded({ kind: "chat", chatId, peer });
47515
+ this.markUpdateBucketDegraded({ kind: "chat", chatId, peer }, "target_not_reached");
46567
47516
  this.log.warn?.("GET_UPDATES final chat page remained behind the requested target", {
46568
47517
  chatId: chatId.toString(),
46569
47518
  requestedEndSeq: endSeq,
@@ -46589,15 +47538,18 @@ class InlineSdkClient {
46589
47538
  const existing = this.catchUpInFlightBySpaceId.get(params.spaceId);
46590
47539
  if (existing)
46591
47540
  return existing;
47541
+ if (this.recoveryRetries.get(`space:${params.spaceId}`)?.timer)
47542
+ return Promise.resolve();
47543
+ const initialDemand = this.catchUpRequestedBySpaceId.get(params.spaceId);
46592
47544
  const task = this.drainCatchUpSpace(params.spaceId).catch((error) => {
46593
- this.catchUpRequestedBySpaceId.delete(params.spaceId);
46594
- this.markUpdateBucketDegraded({ kind: "space", spaceId: params.spaceId });
47545
+ this.recordCatchUpFailure({ kind: "space", spaceId: params.spaceId }, error, this.catchUpRequestedBySpaceId.get(params.spaceId) !== initialDemand);
46595
47546
  this.log.warn?.("GET_UPDATES space catch-up failed; bucket remains degraded", {
46596
47547
  spaceId: params.spaceId.toString(),
46597
47548
  error: extractErrorMessage(error)
46598
47549
  });
46599
47550
  }).finally(() => {
46600
47551
  this.catchUpInFlightBySpaceId.delete(params.spaceId);
47552
+ this.scheduleRecoveryRetry({ kind: "space", spaceId: params.spaceId });
46601
47553
  });
46602
47554
  this.catchUpInFlightBySpaceId.set(params.spaceId, task);
46603
47555
  return task;
@@ -46621,12 +47573,8 @@ class InlineSdkClient {
46621
47573
  if (stop) {
46622
47574
  if (this.catchUpRequestedBySpaceId.get(spaceId) !== request)
46623
47575
  continue;
46624
- this.catchUpRequestedBySpaceId.delete(spaceId);
46625
- return;
46626
- }
46627
- const latest = this.catchUpRequestedBySpaceId.get(spaceId);
46628
- const syncedSeq = this.state.lastSeqBySpaceId?.[key] ?? 0;
46629
- if (!latest || latest.endSeq != null && latest.endSeq <= syncedSeq) {
47576
+ if (this.degradedUpdateBuckets.has(`space:${spaceId}`))
47577
+ return;
46630
47578
  this.catchUpRequestedBySpaceId.delete(spaceId);
46631
47579
  return;
46632
47580
  }
@@ -46695,7 +47643,7 @@ class InlineSdkClient {
46695
47643
  });
46696
47644
  }
46697
47645
  if (deliveredSeq <= cursor && !payload.final) {
46698
- this.markUpdateBucketDegraded({ kind: "space", spaceId });
47646
+ this.markUpdateBucketDegraded({ kind: "space", spaceId }, "non_progress");
46699
47647
  this.log.warn?.("GET_UPDATES space made no progress; bucket remains degraded", {
46700
47648
  spaceId: spaceId.toString(),
46701
47649
  cursor,
@@ -46713,7 +47661,7 @@ class InlineSdkClient {
46713
47661
  continue;
46714
47662
  }
46715
47663
  if (endSeq != null && deliveredSeq < endSeq) {
46716
- this.markUpdateBucketDegraded({ kind: "space", spaceId });
47664
+ this.markUpdateBucketDegraded({ kind: "space", spaceId }, "target_not_reached");
46717
47665
  this.log.warn?.("GET_UPDATES final space page remained behind the requested target", {
46718
47666
  spaceId: spaceId.toString(),
46719
47667
  requestedEndSeq: endSeq,
@@ -46738,6 +47686,9 @@ class InlineSdkClient {
46738
47686
  const existing = this.peerResolutionInFlightByChatId.get(chatId);
46739
47687
  if (existing)
46740
47688
  return existing;
47689
+ if (this.recoveryRetries.get(`chat:${chatId}`)?.timer)
47690
+ return Promise.resolve();
47691
+ const initialDemand = this.peerResolutionRequestedByChatId.get(chatId);
46741
47692
  const task = this.getChat({ chatId }).then(async (chat) => {
46742
47693
  const peer = chat.peer;
46743
47694
  if (!peer || !this.isReliableChatPeer(peer)) {
@@ -46751,14 +47702,16 @@ class InlineSdkClient {
46751
47702
  ...requested && !requested.toLatest && requested.endSeq != null ? { updateSeq: requested.endSeq } : {}
46752
47703
  });
46753
47704
  }).catch((error) => {
46754
- this.markUpdateBucketDegraded({ kind: "chat", chatId });
47705
+ this.recordCatchUpFailure({ kind: "chat", chatId }, error, this.peerResolutionRequestedByChatId.get(chatId) !== initialDemand);
46755
47706
  this.log.warn?.("Unable to resolve legacy chat peer; bucket remains degraded", {
46756
47707
  chatId: chatId.toString(),
46757
47708
  error: extractErrorMessage(error)
46758
47709
  });
46759
47710
  }).finally(() => {
46760
47711
  this.peerResolutionInFlightByChatId.delete(chatId);
46761
- this.peerResolutionRequestedByChatId.delete(chatId);
47712
+ if (!this.degradedUpdateBuckets.has(`chat:${chatId}`))
47713
+ this.peerResolutionRequestedByChatId.delete(chatId);
47714
+ this.scheduleRecoveryRetry({ kind: "chat", chatId });
46762
47715
  });
46763
47716
  this.peerResolutionInFlightByChatId.set(chatId, task);
46764
47717
  return task;
@@ -46811,7 +47764,7 @@ class InlineSdkClient {
46811
47764
  }
46812
47765
  validateCatchUpPage(payload, startSeq, bucket) {
46813
47766
  if (payload.resultType !== GetUpdatesResult_ResultType.SLICE && payload.resultType !== GetUpdatesResult_ResultType.EMPTY) {
46814
- this.markUpdateBucketDegraded(bucket);
47767
+ this.markUpdateBucketDegraded(bucket, "invalid_page_type");
46815
47768
  this.log.warn?.("GET_UPDATES returned an invalid page result type; bucket remains degraded", {
46816
47769
  bucket: this.updateBucketKey(bucket),
46817
47770
  resultType: payload.resultType
@@ -46820,7 +47773,7 @@ class InlineSdkClient {
46820
47773
  }
46821
47774
  const deliveredSeq = Number(payload.seq);
46822
47775
  if (!Number.isSafeInteger(deliveredSeq) || deliveredSeq < startSeq) {
46823
- this.markUpdateBucketDegraded(bucket);
47776
+ this.markUpdateBucketDegraded(bucket, "invalid_page_cursor");
46824
47777
  this.log.warn?.("GET_UPDATES page moved backwards or returned an invalid seq; bucket remains degraded", {
46825
47778
  bucket: this.updateBucketKey(bucket),
46826
47779
  startSeq,
@@ -46832,7 +47785,7 @@ class InlineSdkClient {
46832
47785
  for (const update of payload.updates) {
46833
47786
  const seq = update.seq;
46834
47787
  if (!Number.isSafeInteger(seq) || seq == null || seq <= startSeq || seq > deliveredSeq || accounted.has(seq)) {
46835
- this.markUpdateBucketDegraded(bucket);
47788
+ this.markUpdateBucketDegraded(bucket, "invalid_update_sequence");
46836
47789
  this.log.warn?.("GET_UPDATES page included an invalid or duplicate update seq; bucket remains degraded", {
46837
47790
  bucket: this.updateBucketKey(bucket),
46838
47791
  seq
@@ -46845,7 +47798,7 @@ class InlineSdkClient {
46845
47798
  for (const skipped of payload.skippedSequences) {
46846
47799
  const seq = Number(skipped.seq);
46847
47800
  if (!Number.isSafeInteger(seq) || seq <= startSeq || seq > deliveredSeq || accounted.has(seq)) {
46848
- this.markUpdateBucketDegraded(bucket);
47801
+ this.markUpdateBucketDegraded(bucket, "invalid_skipped_sequence");
46849
47802
  this.log.warn?.("GET_UPDATES page included an invalid or duplicate skipped seq; bucket remains degraded", {
46850
47803
  bucket: this.updateBucketKey(bucket),
46851
47804
  seq
@@ -46861,7 +47814,7 @@ class InlineSdkClient {
46861
47814
  break;
46862
47815
  case SyncSkippedSequence_Reason.REASON_UNSPECIFIED:
46863
47816
  default:
46864
- this.markUpdateBucketDegraded(bucket);
47817
+ this.markUpdateBucketDegraded(bucket, "unknown_skip_reason");
46865
47818
  this.log.warn?.("GET_UPDATES page included an unsupported skipped-sequence reason; bucket remains degraded", {
46866
47819
  bucket: this.updateBucketKey(bucket),
46867
47820
  reason: skipped.reason
@@ -46870,7 +47823,7 @@ class InlineSdkClient {
46870
47823
  }
46871
47824
  }
46872
47825
  if (accounted.size !== deliveredSeq - startSeq) {
46873
- this.markUpdateBucketDegraded(bucket);
47826
+ this.markUpdateBucketDegraded(bucket, "unaccounted_gap");
46874
47827
  this.log.warn?.("GET_UPDATES page did not account for every advanced sequence; bucket remains degraded", {
46875
47828
  bucket: this.updateBucketKey(bucket),
46876
47829
  startSeq,
@@ -46952,7 +47905,7 @@ class InlineSdkClient {
46952
47905
  this.clearUpdateBucketDegraded(bucket);
46953
47906
  return true;
46954
47907
  } catch (error) {
46955
- this.markUpdateBucketDegraded(bucket);
47908
+ this.markUpdateBucketDegraded(bucket, "repair_failed");
46956
47909
  this.log.warn?.("Authoritative update repair failed; bucket remains degraded", {
46957
47910
  bucket: this.updateBucketKey(bucket),
46958
47911
  error: extractErrorMessage(error)
@@ -46961,7 +47914,17 @@ class InlineSdkClient {
46961
47914
  }
46962
47915
  }
46963
47916
  async acceptCatchUpUpdates(updates, source, bucket) {
47917
+ const liveDeliveries = this.liveDeliveriesByBucket.get(this.updateBucketKey(bucket));
47918
+ if (liveDeliveries && (await Promise.all(liveDeliveries)).some((applied) => !applied)) {
47919
+ this.markUpdateBucketDegraded(bucket, "host_unacknowledged");
47920
+ return false;
47921
+ }
47922
+ if (this.closed)
47923
+ return false;
47924
+ const appliedThrough = this.bucketCursor(bucket);
46964
47925
  for (const update of updates) {
47926
+ if (update.seq != null && update.seq > 0 && update.seq <= appliedThrough)
47927
+ continue;
46965
47928
  if (update.update.oneofKind === "chatSkipPts" && source === "chat") {
46966
47929
  continue;
46967
47930
  }
@@ -46972,7 +47935,7 @@ class InlineSdkClient {
46972
47935
  if (accepted === true)
46973
47936
  continue;
46974
47937
  if (accepted === false) {
46975
- this.markUpdateBucketDegraded(bucket);
47938
+ this.markUpdateBucketDegraded(bucket, "host_unacknowledged");
46976
47939
  this.log.warn?.("GET_UPDATES event was not acknowledged by the SDK host; cursor remains unchanged", {
46977
47940
  bucket: this.updateBucketKey(bucket),
46978
47941
  updateKind: update.update.oneofKind
@@ -46993,8 +47956,95 @@ class InlineSdkClient {
46993
47956
  }
46994
47957
  return true;
46995
47958
  }
46996
- markUpdateBucketDegraded(bucket) {
46997
- this.degradedUpdateBuckets.set(this.updateBucketKey(bucket), bucket);
47959
+ recordCatchUpFailure(bucket, error, hasNewerDemand = false) {
47960
+ const rpcCode = error instanceof ProtocolClientError ? error.rpcCode : undefined;
47961
+ if (!hasNewerDemand && bucket.kind !== "user" && (rpcCode === RpcError_Code.PEER_ID_INVALID || rpcCode === RpcError_Code.CHAT_ID_INVALID || rpcCode === RpcError_Code.SPACE_ID_INVALID)) {
47962
+ this.clearUpdateBucketDegraded(bucket);
47963
+ if (bucket.kind === "chat") {
47964
+ this.catchUpRequestedByChatId.delete(bucket.chatId);
47965
+ this.peerResolutionRequestedByChatId.delete(bucket.chatId);
47966
+ } else
47967
+ this.catchUpRequestedBySpaceId.delete(bucket.spaceId);
47968
+ const round = this.discoveryRound;
47969
+ if (round) {
47970
+ round.targets.delete(this.updateBucketKey(bucket));
47971
+ this.tryCommitDiscoveryRound(round);
47972
+ }
47973
+ this.log.error?.("Sync bucket unavailable", { bucketKind: bucket.kind, reason: "access_rejected" });
47974
+ return;
47975
+ }
47976
+ this.markUpdateBucketDegraded(bucket, rpcCode === RpcError_Code.RATE_LIMIT || rpcCode === 429 ? "rate_limited" : error instanceof ProtocolClientError ? error.code : "request_failed");
47977
+ }
47978
+ markUpdateBucketDegraded(bucket, failure = "incomplete") {
47979
+ const key = this.updateBucketKey(bucket);
47980
+ this.degradedUpdateBuckets.set(key, bucket);
47981
+ const retry = this.recoveryRetries.get(key) ?? { attempt: 0, failure, reported: new Set };
47982
+ retry.failure = failure;
47983
+ this.recoveryRetries.set(key, retry);
47984
+ queueMicrotask(() => this.scheduleRecoveryRetry(bucket));
47985
+ }
47986
+ resetRecoveryBackoff(bucket) {
47987
+ const retry = this.recoveryRetries.get(this.updateBucketKey(bucket));
47988
+ if (retry)
47989
+ retry.attempt = 0;
47990
+ }
47991
+ cancelRecoveryRetries() {
47992
+ clearTimeout(this.discoveryRetry?.timer);
47993
+ this.discoveryRetry = null;
47994
+ for (const retry of this.recoveryRetries.values())
47995
+ clearTimeout(retry.timer);
47996
+ this.recoveryRetries.clear();
47997
+ }
47998
+ scheduleDiscoveryRetry(reason) {
47999
+ if (!this.started || this.closed || this.protocol.getDiagnostics().state !== "open")
48000
+ return;
48001
+ const retry = this.discoveryRetry ?? { attempt: 0, reported: new Set };
48002
+ if (retry.timer)
48003
+ return;
48004
+ if (!retry.reported.has(reason)) {
48005
+ retry.reported.add(reason);
48006
+ this.log.error?.("Sync recovery scheduled", { bucketKind: "discovery", reason });
48007
+ }
48008
+ const delayMs = reason === "rate_limited" ? 60000 : Math.min(30000, 1000 * 2 ** Math.min(retry.attempt, 5));
48009
+ retry.attempt++;
48010
+ retry.timer = setTimeout(() => {
48011
+ retry.timer = undefined;
48012
+ if (this.started && !this.closed && this.protocol.getDiagnostics().state === "open") {
48013
+ this.initializeDateCursor();
48014
+ }
48015
+ }, delayMs);
48016
+ retry.timer.unref?.();
48017
+ this.discoveryRetry = retry;
48018
+ }
48019
+ scheduleRecoveryRetry(bucket) {
48020
+ const key = this.updateBucketKey(bucket);
48021
+ if (!this.started || this.closed || !this.degradedUpdateBuckets.has(key))
48022
+ return;
48023
+ if (bucket.kind === "chat" && (this.catchUpInFlightByChatId.has(bucket.chatId) || this.peerResolutionInFlightByChatId.has(bucket.chatId)))
48024
+ return;
48025
+ if (bucket.kind === "space" && this.catchUpInFlightBySpaceId.has(bucket.spaceId))
48026
+ return;
48027
+ if (bucket.kind === "user" && this.userCatchUpInFlight)
48028
+ return;
48029
+ const retry = this.recoveryRetries.get(key) ?? { attempt: 0, failure: "incomplete", reported: new Set };
48030
+ if (retry.timer || this.protocol.getDiagnostics().state !== "open")
48031
+ return;
48032
+ const delayMs = retry.failure === "rate_limited" ? 60000 : Math.min(5000, 1000 * 2 ** Math.min(retry.attempt, 3));
48033
+ if (!retry.reported.has(retry.failure)) {
48034
+ retry.reported.add(retry.failure);
48035
+ this.log.error?.("Sync recovery scheduled", { bucketKind: bucket.kind, reason: retry.failure });
48036
+ }
48037
+ retry.attempt++;
48038
+ retry.timer = setTimeout(() => {
48039
+ retry.timer = undefined;
48040
+ if (!this.started || this.closed || this.protocol.getDiagnostics().state !== "open")
48041
+ return;
48042
+ const pending = this.degradedUpdateBuckets.get(key);
48043
+ if (pending)
48044
+ this.requestCatchUpForDegradedBucket(pending);
48045
+ }, delayMs);
48046
+ retry.timer.unref?.();
48047
+ this.recoveryRetries.set(key, retry);
46998
48048
  }
46999
48049
  fenceLiveCursor(bucket) {
47000
48050
  this.liveCursorFences.add(this.updateBucketKey(bucket));
@@ -47002,6 +48052,8 @@ class InlineSdkClient {
47002
48052
  clearUpdateBucketDegraded(bucket) {
47003
48053
  const key = this.updateBucketKey(bucket);
47004
48054
  this.degradedUpdateBuckets.delete(key);
48055
+ clearTimeout(this.recoveryRetries.get(key)?.timer);
48056
+ this.recoveryRetries.delete(key);
47005
48057
  this.liveCursorFences.delete(key);
47006
48058
  this.liveAdmittedSeqByBucket.delete(key);
47007
48059
  }
@@ -62906,6 +63958,275 @@ function looksLikeInlineTargetId(raw, normalizedInput) {
62906
63958
  return /^[0-9]+$/.test(normalized);
62907
63959
  }
62908
63960
 
63961
+ // src/telemetry.ts
63962
+ import { randomUUID } from "node:crypto";
63963
+ import { readFile as readFile2 } from "node:fs/promises";
63964
+ var TELEMETRY_TIMEOUT_MS = 2000;
63965
+ var TELEMETRY_DEDUP_MS = 5 * 60000;
63966
+ var MAX_ERROR_MESSAGE_LENGTH = 8000;
63967
+ var MAX_STACK_FRAMES = 80;
63968
+ var SENSITIVE_ENV_NAME = /(?:token|secret|password|api[_-]?key|authorization)/i;
63969
+ var lastReports = new Map;
63970
+ var releasePromise;
63971
+ function telemetryDisabled(env = process.env) {
63972
+ const disabled = (value) => value != null && ["1", "true", "yes", "on"].includes(value.trim().toLowerCase());
63973
+ const optedOut = (value) => value != null && ["0", "false", "off"].includes(value.trim().toLowerCase());
63974
+ return disabled(env.DO_NOT_TRACK) || optedOut(env.INLINE_PLUGIN_TELEMETRY);
63975
+ }
63976
+ function resolveDsn(env = process.env) {
63977
+ if (telemetryDisabled(env))
63978
+ return "";
63979
+ return env.INLINE_OPENCLAW_SENTRY_DSN?.trim() ?? "";
63980
+ }
63981
+ function sensitiveValues(env = process.env) {
63982
+ return Object.entries(env).filter(([name, value]) => SENSITIVE_ENV_NAME.test(name) && (value?.length ?? 0) >= 8).map(([, value]) => value);
63983
+ }
63984
+ function redactOpenClawTelemetryText(value, env = process.env) {
63985
+ let text = String(value ?? "").replace(/\b(Authorization\s*[:=]\s*)(?:Basic|Bearer)\s+\S+/gi, "$1[REDACTED]").replace(/\b((?:Basic|Bearer)\s+)\S+/gi, "$1[REDACTED]").replace(/(https?:\/\/)[^/\s:@]+:[^@\s/]+@/gi, "$1[REDACTED]@").replace(/([?&](?:access_token|auth|authorization|key|password|secret|token)[^=\s&]*)=([^&\s]+)/gi, "$1=[REDACTED]").replace(/\b([A-Za-z0-9_-]*(?:token|secret|password|api[_-]?key|authorization)[A-Za-z0-9_-]*)\s*([=:])\s*\S+/gi, "$1$2[REDACTED]");
63986
+ for (const secret of sensitiveValues(env)) {
63987
+ text = text.replaceAll(secret, "[REDACTED]");
63988
+ }
63989
+ return text.slice(0, MAX_ERROR_MESSAGE_LENGTH);
63990
+ }
63991
+ function safeTag(value) {
63992
+ const normalized = value.trim().toLowerCase();
63993
+ return normalized.length > 0 && normalized.length <= 80 && /^[a-z0-9._-]+$/.test(normalized) ? normalized : "unknown";
63994
+ }
63995
+ function parseStack(error51, env) {
63996
+ const stack = error51.stack ?? "";
63997
+ const frames = [];
63998
+ for (const rawLine of stack.split(`
63999
+ `).slice(1)) {
64000
+ const line = redactOpenClawTelemetryText(rawLine.trim(), env);
64001
+ const match = /^at\s+(?:(.*?)\s+\()?(.+?):(\d+):(\d+)\)?$/.exec(line);
64002
+ if (!match)
64003
+ continue;
64004
+ const filename = match[2];
64005
+ const frame = {
64006
+ filename,
64007
+ abs_path: filename,
64008
+ function: match[1] || "<anonymous>",
64009
+ lineno: Number(match[3]),
64010
+ colno: Number(match[4]),
64011
+ in_app: filename.includes("@inline-openclaw/inline") || filename.includes("/openclaw/") || /\/(?:channel-plugin-api|runtime-register-api|index)\.js$/.test(filename)
64012
+ };
64013
+ frames.push(frame);
64014
+ if (frames.length >= MAX_STACK_FRAMES)
64015
+ break;
64016
+ }
64017
+ return frames.reverse();
64018
+ }
64019
+ function buildOpenClawTelemetryEvent(operation, error51, options = {}) {
64020
+ const env = options.env ?? process.env;
64021
+ const exception = error51 instanceof Error ? error51 : new Error(String(error51 ?? "Unknown error"));
64022
+ const frames = parseStack(exception, env);
64023
+ return {
64024
+ event_id: randomUUID().replaceAll("-", ""),
64025
+ timestamp: new Date().toISOString(),
64026
+ platform: "javascript",
64027
+ level: "error",
64028
+ logger: "inline.openclaw.plugin",
64029
+ exception: {
64030
+ values: [{
64031
+ type: redactOpenClawTelemetryText(exception.name || "Error", env),
64032
+ value: redactOpenClawTelemetryText(exception.message || String(error51), env),
64033
+ mechanism: {
64034
+ type: "inline_plugin_boundary",
64035
+ handled: options.handled ?? true
64036
+ },
64037
+ ...frames.length > 0 ? { stacktrace: { frames } } : {}
64038
+ }]
64039
+ },
64040
+ tags: {
64041
+ operation: safeTag(operation),
64042
+ runtime: "node",
64043
+ os: process.platform,
64044
+ arch: process.arch
64045
+ },
64046
+ sdk: { name: "inline.plugin.telemetry", version: "1" }
64047
+ };
64048
+ }
64049
+ async function resolveRelease() {
64050
+ releasePromise ??= (async () => {
64051
+ try {
64052
+ const parsed = JSON.parse(await readFile2(new URL("../package.json", import.meta.url), "utf8"));
64053
+ if (typeof parsed.version === "string" && parsed.version.trim()) {
64054
+ return `inline-openclaw-plugin@${parsed.version.trim()}`;
64055
+ }
64056
+ } catch {}
64057
+ return;
64058
+ })();
64059
+ return releasePromise;
64060
+ }
64061
+ function parseSentryDsn(dsn) {
64062
+ try {
64063
+ const parsed = new URL(dsn);
64064
+ if (!/^https?:$/.test(parsed.protocol) || !parsed.username)
64065
+ return null;
64066
+ const parts = parsed.pathname.split("/").filter(Boolean);
64067
+ const projectId = parts.pop();
64068
+ if (!projectId || !/^\d+$/.test(projectId))
64069
+ return null;
64070
+ const prefix = parts.length > 0 ? `/${parts.join("/")}` : "";
64071
+ return {
64072
+ endpoint: `${parsed.origin}${prefix}/api/${projectId}/envelope/`,
64073
+ publicKey: parsed.username
64074
+ };
64075
+ } catch {
64076
+ return null;
64077
+ }
64078
+ }
64079
+ async function sendOpenClawPluginError(operation, error51, options = {}) {
64080
+ const env = options.env ?? process.env;
64081
+ const dsn = resolveDsn(env);
64082
+ const target = parseSentryDsn(dsn);
64083
+ if (!target)
64084
+ return false;
64085
+ const event = buildOpenClawTelemetryEvent(operation, error51, options);
64086
+ const release = await resolveRelease();
64087
+ if (release)
64088
+ event.release = release;
64089
+ const envelope = [
64090
+ JSON.stringify({ event_id: event.event_id, dsn, sent_at: event.timestamp }),
64091
+ JSON.stringify({ type: "event", content_type: "application/json" }),
64092
+ JSON.stringify(event)
64093
+ ].join(`
64094
+ `);
64095
+ const controller = new AbortController;
64096
+ const timeout = setTimeout(() => controller.abort(), TELEMETRY_TIMEOUT_MS);
64097
+ timeout.unref?.();
64098
+ try {
64099
+ const response = await fetch(target.endpoint, {
64100
+ method: "POST",
64101
+ headers: {
64102
+ "content-type": "application/x-sentry-envelope",
64103
+ "x-sentry-auth": `Sentry sentry_version=7, sentry_key=${target.publicKey}, sentry_client=inline.plugin.telemetry/1`
64104
+ },
64105
+ body: envelope,
64106
+ signal: controller.signal
64107
+ });
64108
+ return response.ok;
64109
+ } catch {
64110
+ return false;
64111
+ } finally {
64112
+ clearTimeout(timeout);
64113
+ }
64114
+ }
64115
+ function reportOpenClawPluginError(operation, error51, options = {}) {
64116
+ try {
64117
+ const exception = error51 instanceof Error ? error51 : new Error(String(error51 ?? "Unknown error"));
64118
+ const key = `${safeTag(operation)}\x00${exception.name}\x00${redactOpenClawTelemetryText(exception.message)}`;
64119
+ const now = Date.now();
64120
+ if (now - (lastReports.get(key) ?? 0) < TELEMETRY_DEDUP_MS)
64121
+ return;
64122
+ lastReports.set(key, now);
64123
+ sendOpenClawPluginError(operation, exception, options).catch(() => {});
64124
+ } catch {}
64125
+ }
64126
+ function wrapCallback(operation, callback) {
64127
+ return function(...args) {
64128
+ try {
64129
+ const result = Reflect.apply(callback, this, args);
64130
+ if (result && typeof result.then === "function") {
64131
+ return Promise.resolve(result).catch((error51) => {
64132
+ reportOpenClawPluginError(operation, error51);
64133
+ throw error51;
64134
+ });
64135
+ }
64136
+ return result;
64137
+ } catch (error51) {
64138
+ reportOpenClawPluginError(operation, error51);
64139
+ throw error51;
64140
+ }
64141
+ };
64142
+ }
64143
+ function wrapSurface(prefix, surface) {
64144
+ const wrapped = { ...surface };
64145
+ for (const [name, member] of Object.entries(wrapped)) {
64146
+ if (typeof member === "function") {
64147
+ wrapped[name] = wrapCallback(`${prefix}.${name}`, member);
64148
+ }
64149
+ }
64150
+ return wrapped;
64151
+ }
64152
+ function instrumentToolValue(value) {
64153
+ if (Array.isArray(value))
64154
+ return value.map(instrumentToolValue);
64155
+ if (!value || typeof value !== "object")
64156
+ return value;
64157
+ const tool = value;
64158
+ const execute = tool.execute;
64159
+ if (typeof execute !== "function")
64160
+ return value;
64161
+ const name = typeof tool.name === "string" ? safeTag(tool.name) : "unknown";
64162
+ return new Proxy(tool, {
64163
+ get(target, property, receiver) {
64164
+ if (property === "execute") {
64165
+ return wrapCallback(`tool.${name}`, execute);
64166
+ }
64167
+ return Reflect.get(target, property, receiver);
64168
+ }
64169
+ });
64170
+ }
64171
+ function instrumentOpenClawPluginApi(value) {
64172
+ const api2 = value;
64173
+ return new Proxy(api2, {
64174
+ get(target, property, receiver) {
64175
+ const member = Reflect.get(target, property, receiver);
64176
+ if (property === "registerTool" && typeof member === "function") {
64177
+ return (toolOrFactory, options) => {
64178
+ const wrapped = typeof toolOrFactory === "function" ? wrapCallback("tool.factory", (...args) => instrumentToolValue(Reflect.apply(toolOrFactory, undefined, args))) : instrumentToolValue(toolOrFactory);
64179
+ return Reflect.apply(member, target, [wrapped, options]);
64180
+ };
64181
+ }
64182
+ if (property === "registerCommand" && typeof member === "function") {
64183
+ return (command) => {
64184
+ const handler = command.handler;
64185
+ const name = typeof command.name === "string" ? safeTag(command.name) : "unknown";
64186
+ const wrapped = typeof handler === "function" ? { ...command, handler: wrapCallback(`command.${name}`, handler) } : command;
64187
+ return Reflect.apply(member, target, [wrapped]);
64188
+ };
64189
+ }
64190
+ if (property === "on" && typeof member === "function") {
64191
+ return (event, handler) => Reflect.apply(member, target, [event, wrapCallback(`hook.${safeTag(event)}`, handler)]);
64192
+ }
64193
+ return member;
64194
+ }
64195
+ });
64196
+ }
64197
+ function instrumentOpenClawChannelPlugin(value) {
64198
+ const plugin = { ...value };
64199
+ for (const name of [
64200
+ "lifecycle",
64201
+ "pairing",
64202
+ "outbound",
64203
+ "heartbeat",
64204
+ "directory",
64205
+ "resolver",
64206
+ "allowlist",
64207
+ "status",
64208
+ "gateway"
64209
+ ]) {
64210
+ const surface = plugin[name];
64211
+ if (surface && typeof surface === "object") {
64212
+ plugin[name] = wrapSurface(name, surface);
64213
+ }
64214
+ }
64215
+ const message = plugin.message;
64216
+ if (message && typeof message === "object") {
64217
+ const wrappedMessage = { ...message };
64218
+ const send = wrappedMessage.send;
64219
+ if (send && typeof send === "object") {
64220
+ wrappedMessage.send = wrapSurface("message.send", send);
64221
+ }
64222
+ plugin.message = wrappedMessage;
64223
+ }
64224
+ return plugin;
64225
+ }
64226
+ function reportOpenClawRegistrationError(error51) {
64227
+ reportOpenClawPluginError("plugin.register", error51, { handled: false });
64228
+ }
64229
+
62909
64230
  // src/inline/monitor.ts
62910
64231
  import { mkdir as mkdir2, stat } from "node:fs/promises";
62911
64232
  import path3 from "node:path";
@@ -62976,6 +64297,8 @@ import {
62976
64297
  createTransportActivityStatusPatch
62977
64298
  } from "openclaw/plugin-sdk/gateway-runtime";
62978
64299
  import {
64300
+ hasFinalInboundReplyDispatch,
64301
+ hasVisibleInboundReplyDispatch,
62979
64302
  classifyChannelInboundEvent,
62980
64303
  createChannelInboundDebouncer,
62981
64304
  resolveUnmentionedGroupInboundPolicy,
@@ -63174,7 +64497,7 @@ import {
63174
64497
  } from "openclaw/plugin-sdk/interactive-runtime";
63175
64498
 
63176
64499
  // src/inline/media.ts
63177
- import { randomUUID } from "node:crypto";
64500
+ import { randomUUID as randomUUID2 } from "node:crypto";
63178
64501
  import { mkdir, writeFile as writeFile2 } from "node:fs/promises";
63179
64502
  import os from "node:os";
63180
64503
  import path from "node:path";
@@ -63309,17 +64632,19 @@ function resolveMediaMaxBytes(params) {
63309
64632
  }
63310
64633
  function buildInlineMediaLoadOptions(params) {
63311
64634
  const explicitLocalRoots = params.mediaAccess?.localRoots ?? params.mediaLocalRoots;
63312
- const readFile2 = params.mediaAccess?.readFile ?? params.mediaReadFile;
64635
+ const readFile3 = params.mediaAccess?.readFile ?? params.mediaReadFile;
63313
64636
  const workspaceDir = params.mediaAccess?.workspaceDir;
63314
- const localRoots = explicitLocalRoots === "any" || explicitLocalRoots?.length ? explicitLocalRoots : readFile2 ? "any" : undefined;
63315
- if (!localRoots && !readFile2 && !workspaceDir) {
64637
+ const signal = params.signal;
64638
+ const localRoots = explicitLocalRoots === "any" || explicitLocalRoots?.length ? explicitLocalRoots : readFile3 ? "any" : undefined;
64639
+ if (!localRoots && !readFile3 && !workspaceDir && !signal) {
63316
64640
  return params.maxBytes;
63317
64641
  }
63318
64642
  return {
63319
64643
  maxBytes: params.maxBytes,
63320
64644
  ...localRoots ? { localRoots } : {},
63321
- ...readFile2 ? { readFile: readFile2, hostReadCapability: true } : {},
63322
- ...workspaceDir ? { workspaceDir } : {}
64645
+ ...readFile3 ? { readFile: readFile3, hostReadCapability: true } : {},
64646
+ ...workspaceDir ? { workspaceDir } : {},
64647
+ ...signal ? { signal } : {}
63323
64648
  };
63324
64649
  }
63325
64650
  function mediaFromUploadResult(params) {
@@ -63346,12 +64671,15 @@ async function uploadInlineMediaFromUrl(params) {
63346
64671
  let uploadType;
63347
64672
  let fileName;
63348
64673
  try {
64674
+ params.signal?.throwIfAborted();
63349
64675
  loaded = await loadWebMediaCompat(params.mediaUrl, buildInlineMediaLoadOptions({
63350
64676
  maxBytes,
63351
64677
  ...params.mediaAccess ? { mediaAccess: params.mediaAccess } : {},
63352
64678
  ...params.mediaLocalRoots ? { mediaLocalRoots: params.mediaLocalRoots } : {},
63353
- ...params.mediaReadFile ? { mediaReadFile: params.mediaReadFile } : {}
64679
+ ...params.mediaReadFile ? { mediaReadFile: params.mediaReadFile } : {},
64680
+ ...params.signal ? { signal: params.signal } : {}
63354
64681
  }));
64682
+ params.signal?.throwIfAborted();
63355
64683
  if (!loaded) {
63356
64684
  throw new Error("inline media upload: media load returned no data");
63357
64685
  }
@@ -63376,6 +64704,7 @@ async function uploadInlineMediaFromUrl(params) {
63376
64704
  file: loaded.buffer,
63377
64705
  fileName,
63378
64706
  ...detectedMime ? { contentType: detectedMime } : {},
64707
+ ...params.signal ? { signal: params.signal } : {},
63379
64708
  ...uploadType === "video" ? {
63380
64709
  width: DEFAULT_VIDEO_WIDTH,
63381
64710
  height: DEFAULT_VIDEO_HEIGHT,
@@ -63434,7 +64763,7 @@ async function downloadInlineMediaFromUrl(params) {
63434
64763
  });
63435
64764
  const dir = path.join(os.tmpdir(), "openclaw-inline-downloads");
63436
64765
  await mkdir(dir, { recursive: true });
63437
- const filePath = path.join(dir, `${randomUUID()}-${fileName}`);
64766
+ const filePath = path.join(dir, `${randomUUID2()}-${fileName}`);
63438
64767
  await writeFile2(filePath, loaded.buffer, { flag: "wx" });
63439
64768
  return {
63440
64769
  path: filePath,
@@ -63556,6 +64885,12 @@ var INLINE_MESSAGE_ENTITY_TYPE = {
63556
64885
  function compactWhitespace(raw) {
63557
64886
  return (raw ?? "").replace(/\s+/g, " ").trim();
63558
64887
  }
64888
+ function normalizeRawMessageText(raw) {
64889
+ return (raw ?? "").replaceAll(`\r
64890
+ `, `
64891
+ `).replaceAll("\r", `
64892
+ `).trim();
64893
+ }
63559
64894
  function bestPhotoSize(photo) {
63560
64895
  let best = {
63561
64896
  cdnUrl: null,
@@ -63860,7 +65195,7 @@ function formatEntitySummary(entity) {
63860
65195
  }
63861
65196
  }
63862
65197
  function summarizeInlineMessageContent(message) {
63863
- const rawText = compactWhitespace(message.message);
65198
+ const rawText = normalizeRawMessageText(message.message);
63864
65199
  const media = messageMediaSummary(message);
63865
65200
  const attachments = messageAttachmentSummaries(message);
63866
65201
  const entities = messageEntitySummaries(message);
@@ -72682,31 +74017,20 @@ function resolveInlineMediaMaxBytes(params) {
72682
74017
  }
72683
74018
  function buildInlineInboundMediaFacts(media) {
72684
74019
  return toInboundMediaFacts(media.map((item) => ({
72685
- path: item.path,
72686
- ...item.contentType?.trim() ? { contentType: item.contentType.trim() } : {}
74020
+ ...item.path ? { path: item.path } : {},
74021
+ ...item.contentType?.trim() ? { contentType: item.contentType.trim() } : {},
74022
+ ...item.fileName?.trim() ? { fileName: item.fileName.trim() } : {},
74023
+ ...item.kind ? { kind: item.kind } : {},
74024
+ ...item.messageId ? { messageId: item.messageId } : {}
72687
74025
  })));
72688
74026
  }
72689
- function buildInlineAttachmentPlaceholder(content) {
72690
- const media = content.media;
72691
- if (!media)
72692
- return "";
72693
- switch (media.kind) {
72694
- case "photo":
72695
- return "<media:image>";
72696
- case "video":
72697
- return "<media:video>";
72698
- case "document":
72699
- return "<media:document>";
72700
- case "voice":
72701
- return "<media:audio>";
72702
- default:
72703
- return "";
72704
- }
72705
- }
72706
74027
  function buildInlineInboundBodyText(content) {
72707
- const textWithPlaceholder = [content.rawText, buildInlineAttachmentPlaceholder(content)].filter(Boolean).join(`
72708
- `).trim();
72709
- return textWithPlaceholder || content.text;
74028
+ if (content.rawText)
74029
+ return content.rawText;
74030
+ if (content.media?.kind === "nudge" || !content.media && content.attachmentText) {
74031
+ return content.text;
74032
+ }
74033
+ return "";
72710
74034
  }
72711
74035
  function resolveFilePathHint(params) {
72712
74036
  const preferred = params.preferredName?.trim();
@@ -72723,20 +74047,31 @@ function resolveFilePathHint(params) {
72723
74047
  async function resolveInlineInboundMedia(params) {
72724
74048
  const content = summarizeInlineMessageContent(params.message);
72725
74049
  const candidates = new Map;
74050
+ const out = [];
74051
+ const messageId = String(params.message.id);
74052
+ const inlineMediaKind = content.media?.kind === "photo" ? "image" : content.media?.kind === "video" ? "video" : content.media?.kind === "voice" ? "audio" : content.media?.kind === "document" ? "document" : null;
72726
74053
  if (content.media?.url) {
72727
74054
  candidates.set(content.media.url, {
72728
74055
  fileName: content.media.fileName ?? null,
72729
- mimeType: content.media.mimeType ?? null
74056
+ mimeType: content.media.mimeType ?? null,
74057
+ kind: inlineMediaKind ?? "document"
74058
+ });
74059
+ } else if (inlineMediaKind) {
74060
+ out.push({
74061
+ kind: inlineMediaKind,
74062
+ ...content.media?.fileName ? { fileName: content.media.fileName } : {},
74063
+ ...content.media?.mimeType ? { contentType: content.media.mimeType } : {},
74064
+ messageId
72730
74065
  });
72731
74066
  }
72732
74067
  for (const attachment of content.attachments) {
72733
74068
  if (attachment.kind !== "urlPreview" || !attachment.previewImageUrl)
72734
74069
  continue;
72735
74070
  candidates.set(attachment.previewImageUrl, {
72736
- mimeType: null
74071
+ mimeType: null,
74072
+ kind: "image"
72737
74073
  });
72738
74074
  }
72739
- const out = [];
72740
74075
  for (const [url2, candidate] of candidates.entries()) {
72741
74076
  try {
72742
74077
  const filePathHint = resolveFilePathHint({ sourceUrl: url2, preferredName: candidate.fileName });
@@ -72748,12 +74083,22 @@ async function resolveInlineInboundMedia(params) {
72748
74083
  const fetchedContentType = fetched.contentType ?? candidate.mimeType ?? undefined;
72749
74084
  const saved = await params.core.channel.media.saveMediaBuffer(fetched.buffer, fetchedContentType, "inbound", params.maxBytes, fetched.fileName ?? candidate.fileName ?? undefined);
72750
74085
  const contentType = saved.contentType ?? fetchedContentType;
74086
+ const fileName = fetched.fileName ?? candidate.fileName;
72751
74087
  out.push({
72752
74088
  path: saved.path,
72753
- ...contentType ? { contentType } : {}
74089
+ ...contentType ? { contentType } : {},
74090
+ ...fileName ? { fileName } : {},
74091
+ ...candidate.kind !== "document" ? { kind: candidate.kind } : {},
74092
+ messageId
72754
74093
  });
72755
74094
  } catch (err) {
72756
74095
  params.log?.warn?.(`inline: failed to download inbound media ${url2}: ${String(err)}`);
74096
+ out.push({
74097
+ kind: candidate.kind,
74098
+ ...candidate.fileName ? { fileName: candidate.fileName } : {},
74099
+ ...candidate.mimeType ? { contentType: candidate.mimeType } : {},
74100
+ messageId
74101
+ });
72757
74102
  }
72758
74103
  }
72759
74104
  return out;
@@ -73000,6 +74345,9 @@ async function monitorInlineProvider(params) {
73000
74345
  },
73001
74346
  error: (msg, meta3) => {
73002
74347
  const line = formatSdkLogLine(msg, meta3);
74348
+ if (msg === "Sync recovery scheduled" || msg === "Sync bucket unavailable" || msg === "Sync discovery unavailable") {
74349
+ reportOpenClawPluginError("sdk.sync_recovery", new Error(line));
74350
+ }
73003
74351
  log?.error(line);
73004
74352
  if (isRecoverableInlineConnectionError(line)) {
73005
74353
  recoverableConnectionError = line;
@@ -73032,7 +74380,7 @@ async function monitorInlineProvider(params) {
73032
74380
  const meResult = await client.invokeRaw(Method.GET_ME, {
73033
74381
  oneofKind: "getMe",
73034
74382
  getMe: {}
73035
- });
74383
+ }, { signal: abortSignal });
73036
74384
  if (meResult.oneofKind !== "getMe" || !meResult.getMe.user) {
73037
74385
  throw new Error("missing user");
73038
74386
  }
@@ -73456,7 +74804,7 @@ async function monitorInlineProvider(params) {
73456
74804
  currentAttachmentText = currentContent.attachmentText || null;
73457
74805
  currentEntityText = currentContent.entityText || null;
73458
74806
  }
73459
- if (!rawBody)
74807
+ if (!rawBody && !currentContent?.media && !currentContent?.attachments.length)
73460
74808
  return;
73461
74809
  commandTarget = resolveInlineCommandTarget(rawBody, botUsername);
73462
74810
  if (commandTarget.targeted && !commandTarget.addressedToMe) {
@@ -75048,6 +76396,9 @@ This model will be used for your next message.`, []);
75048
76396
  }
75049
76397
  };
75050
76398
  const replyOptions = {
76399
+ onObservedReplyDelivery: async () => {
76400
+ delivered = true;
76401
+ },
75051
76402
  ...onModelSelected ? { onModelSelected } : {},
75052
76403
  blockReplyTimeoutMs: 25000,
75053
76404
  ...streamViaEditMessage ? {
@@ -75492,12 +76843,14 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
75492
76843
  if (!delivered && streamViaEditMessage && (editStreamState.messageId != null || editStreamState.initialSendMayHaveLanded) && !streamedFinalEditRejected) {
75493
76844
  delivered = true;
75494
76845
  }
75495
- const hostHandledTurn = dispatchResult.queuedFinal === true || dispatchResult.observedReplyDelivery === true || dispatchResult.noVisibleReplyFallbackDelivered === true;
76846
+ const hostDeliveredReply = hasVisibleInboundReplyDispatch({ ...dispatchResult, queuedFinal: false }, { fallbackDelivered: dispatchResult.noVisibleReplyFallbackDelivered === true });
76847
+ const hostHandledTurn = hasFinalInboundReplyDispatch(dispatchResult) || hostDeliveredReply;
76848
+ const deferredToActiveRun = dispatchResult.deferredToActiveRun != null;
75496
76849
  const deliberateSilence = skippedSilently || dispatchResult.deliberateSilentTerminalReply === true;
75497
76850
  const skipFallbackSuppressed = dispatchResult.sourceReplyDeliveryMode === "message_tool_only";
75498
76851
  const hostRequestedNoVisibleRecovery = dispatchResult.noVisibleReplyFallbackEligible === true;
75499
76852
  const explicitFailure = dispatchError != null || failedNonSilent;
75500
- if (!delivered && !adoptingThread && (explicitFailure || !hostHandledTurn && !deliberateSilence && (skippedNonSilent && !skipFallbackSuppressed || hostRequestedNoVisibleRecovery))) {
76853
+ if (!delivered && !hostDeliveredReply && !deferredToActiveRun && !adoptingThread && (explicitFailure || !hostHandledTurn && !deliberateSilence && (skippedNonSilent && !skipFallbackSuppressed || hostRequestedNoVisibleRecovery))) {
75501
76854
  botPresenceLifecycle.fail();
75502
76855
  const fallbackText = undeliveredFinalText.trim() ? undeliveredFinalText : dispatchError != null ? INLINE_REQUEST_ERROR_FALLBACK : EMPTY_RESPONSE_FALLBACK;
75503
76856
  const sent = await client.sendMessage({
@@ -76269,17 +77622,19 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76269
77622
  };
76270
77623
  const loop = (async () => {
76271
77624
  try {
76272
- for await (const event of client.events()) {
76273
- if (abortSignal.aborted)
76274
- break;
77625
+ await client.consumeEvents(async (event) => {
77626
+ if (abortSignal.aborted) {
77627
+ await client.close();
77628
+ return;
77629
+ }
76275
77630
  const rawEvent = event;
76276
77631
  if (event.kind === "bot.chatSettings.request") {
76277
77632
  scheduleInboundTask("agent settings request", () => answerOpenClawBotSettingsRequest(event));
76278
- continue;
77633
+ return;
76279
77634
  }
76280
77635
  if (event.kind === "bot.chatSettings.item.invoke") {
76281
77636
  scheduleInboundTask("agent settings update", () => answerOpenClawBotSettingsMutation(event), { serialKey: `agent-settings:${String(event.chatId)}` });
76282
- continue;
77637
+ return;
76283
77638
  }
76284
77639
  if (event.kind === "message.new") {
76285
77640
  const msg = {
@@ -76287,31 +77642,31 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76287
77642
  chatId: event.chatId
76288
77643
  };
76289
77644
  if (msg.out || msg.fromId === meId)
76290
- continue;
77645
+ return;
76291
77646
  if (!claimInlineInboundMessageInstance({
76292
77647
  seen: seenInboundMessageInstances,
76293
77648
  chatId: event.chatId,
76294
77649
  message: msg
76295
77650
  }))
76296
- continue;
77651
+ return;
76297
77652
  if (isInlineAbortRequestMessage(msg, botUsername) && await isAuthorizedInlineAbortMessage({ chatId: event.chatId, msg })) {
76298
77653
  cancelPendingInlineDebounce({ chatId: event.chatId, msg });
76299
77654
  cancelPendingInlineVoiceMessages({ chatId: event.chatId, msg });
76300
77655
  scheduleImmediateInboundMessage({ chatId: event.chatId, msg }, "priority abort dispatch");
76301
- continue;
77656
+ return;
76302
77657
  }
76303
77658
  if (voiceTranscriptWaitMs > 0 && shouldWaitForInlineVoiceTranscript(msg)) {
76304
77659
  holdInlineVoiceMessage({
76305
77660
  chatId: event.chatId,
76306
77661
  msg
76307
77662
  });
76308
- continue;
77663
+ return;
76309
77664
  }
76310
77665
  scheduleInboundMessage({
76311
77666
  chatId: event.chatId,
76312
77667
  msg
76313
77668
  });
76314
- continue;
77669
+ return;
76315
77670
  }
76316
77671
  if (event.kind === "message.edit") {
76317
77672
  const msg = {
@@ -76319,9 +77674,9 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76319
77674
  chatId: event.chatId
76320
77675
  };
76321
77676
  if (msg.out || msg.fromId === meId)
76322
- continue;
77677
+ return;
76323
77678
  if (await handlePendingInlineVoiceEdit({ chatId: event.chatId, msg })) {
76324
- continue;
77679
+ return;
76325
77680
  }
76326
77681
  await queueInlineMessageLifecycleSystemEvent({
76327
77682
  action: "edited",
@@ -76329,7 +77684,7 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76329
77684
  messageIds: [msg.id],
76330
77685
  senderId: msg.fromId
76331
77686
  });
76332
- continue;
77687
+ return;
76333
77688
  }
76334
77689
  if (event.kind === "message.delete") {
76335
77690
  await queueInlineMessageLifecycleSystemEvent({
@@ -76337,18 +77692,18 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76337
77692
  chatId: event.chatId,
76338
77693
  messageIds: event.messageIds
76339
77694
  });
76340
- continue;
77695
+ return;
76341
77696
  }
76342
77697
  if (event.kind === "reaction.add") {
76343
77698
  if (event.reaction.userId === meId)
76344
- continue;
77699
+ return;
76345
77700
  const shouldQueue = await shouldQueueInlineReactionSystemEvent({
76346
77701
  chatId: event.chatId,
76347
77702
  messageId: event.reaction.messageId,
76348
77703
  senderId: event.reaction.userId
76349
77704
  });
76350
77705
  if (!shouldQueue)
76351
- continue;
77706
+ return;
76352
77707
  await queueInlineReactionSystemEvent({
76353
77708
  action: "added",
76354
77709
  chatId: event.chatId,
@@ -76356,18 +77711,18 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76356
77711
  senderId: event.reaction.userId,
76357
77712
  emoji: event.reaction.emoji
76358
77713
  });
76359
- continue;
77714
+ return;
76360
77715
  }
76361
77716
  if (event.kind === "reaction.delete") {
76362
77717
  if (event.userId === meId)
76363
- continue;
77718
+ return;
76364
77719
  const shouldQueue = await shouldQueueInlineReactionSystemEvent({
76365
77720
  chatId: event.chatId,
76366
77721
  messageId: event.messageId,
76367
77722
  senderId: event.userId
76368
77723
  });
76369
77724
  if (!shouldQueue)
76370
- continue;
77725
+ return;
76371
77726
  await queueInlineReactionSystemEvent({
76372
77727
  action: "removed",
76373
77728
  chatId: event.chatId,
@@ -76375,12 +77730,12 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76375
77730
  senderId: event.userId,
76376
77731
  emoji: event.emoji
76377
77732
  });
76378
- continue;
77733
+ return;
76379
77734
  }
76380
77735
  if (rawEvent["kind"] === "chat.participant.add") {
76381
77736
  const eventChatId = rawEvent["chatId"];
76382
77737
  if (!eventChatId)
76383
- continue;
77738
+ return;
76384
77739
  const participant = rawEvent["participant"];
76385
77740
  const eventDate = rawEvent["date"];
76386
77741
  const recovered = await recoverInlineJoinMentions({
@@ -76400,7 +77755,7 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76400
77755
  msg: { ...msg, mentioned: true }
76401
77756
  }, "inline join mention recovery", { serializeWithChat: true });
76402
77757
  }
76403
- continue;
77758
+ return;
76404
77759
  }
76405
77760
  if (rawEvent["kind"] === "message.action.invoke") {
76406
77761
  const actorUserId = rawEvent["actorUserId"];
@@ -76411,10 +77766,10 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76411
77766
  const eventChatId = rawEvent["chatId"];
76412
77767
  const eventDate = rawEvent["date"];
76413
77768
  if (!actorUserId || !interactionId || !actionId || !targetMessageId || !eventChatId || !eventDate || !data) {
76414
- continue;
77769
+ return;
76415
77770
  }
76416
77771
  if (actorUserId === meId)
76417
- continue;
77772
+ return;
76418
77773
  scheduleImmediateInboundMessage({
76419
77774
  chatId: eventChatId,
76420
77775
  msg: {
@@ -76434,9 +77789,9 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76434
77789
  data
76435
77790
  }
76436
77791
  }, "inline action dispatch", { serializeWithChat: true });
76437
- continue;
77792
+ return;
76438
77793
  }
76439
- }
77794
+ });
76440
77795
  } catch (err) {
76441
77796
  publishStatus({ connected: false, lastError: String(err) });
76442
77797
  runtime.error?.(`inline monitor loop crashed: ${String(err)}`);
@@ -77664,6 +79019,22 @@ var inlineNativeApprovalAdapter = splitChannelApprovalCapability(inlineApprovalC
77664
79019
 
77665
79020
  // src/inline/channel.ts
77666
79021
  var activeMonitors = new Map;
79022
+ function inlineErrorMessage(error51) {
79023
+ return error51 instanceof Error ? error51.message : String(error51);
79024
+ }
79025
+ function asInlinePlatformNotDispatched(error51) {
79026
+ if (error51 instanceof PlatformMessageNotDispatchedError)
79027
+ return error51;
79028
+ return new PlatformMessageNotDispatchedError(inlineErrorMessage(error51), { cause: error51 });
79029
+ }
79030
+ function deriveInlineDeliveryRandomId(context) {
79031
+ const queueId = context.deliveryQueueId?.trim();
79032
+ if (!queueId)
79033
+ return;
79034
+ const digest = createHash("sha256").update("openclaw:inline:delivery:v1\x00").update(queueId).update("\x00").update(String(context.deliveryPartIndex ?? 0)).update("\x00").update(String(context.deliverySubpartIndex ?? 0)).digest();
79035
+ const value = digest.readBigInt64BE(0);
79036
+ return value === 0n ? 1n : value;
79037
+ }
77667
79038
  function resolveInlineStatePath(accountId) {
77668
79039
  return path4.join(getInlineRuntime().state.resolveStateDir(), "channels", "inline", `${accountId}.json`);
77669
79040
  }
@@ -77955,7 +79326,7 @@ function resolveInlineSessionTarget(params) {
77955
79326
  const raw = params.id.trim().replace(/^inline:/i, "").trim();
77956
79327
  if (!raw)
77957
79328
  return;
77958
- const target = /^chat:/i.test(raw) ? raw : `chat:${raw}`;
79329
+ const target = /^(?:chat|user):/i.test(raw) ? raw : `chat:${raw}`;
77959
79330
  try {
77960
79331
  return parseInlineExplicitTarget(target)?.to;
77961
79332
  } catch {
@@ -78285,29 +79656,32 @@ async function notifyPairingApprovedInline(params) {
78285
79656
  }
78286
79657
  }
78287
79658
  async function sendMessageInline(params) {
78288
- const account = resolveInlineAccount({ cfg: params.cfg, accountId: params.accountId ?? null });
78289
- if (!account.configured || !account.baseUrl) {
78290
- throw new Error(`Inline not configured for account "${account.accountId}" (missing token or baseUrl)`);
78291
- }
78292
- const token = await resolveInlineToken(account);
78293
- const target = parseInlineOutboundTarget({
78294
- raw: params.to,
78295
- context: "sendText"
78296
- });
78297
- const visibleText = sanitizeInlineVisibleText(params.text);
78298
- if (visibleText.shouldSkip) {
78299
- return {
78300
- messageId: "",
78301
- chatId: target.kind === "user" ? `user:${target.normalizedNumeric}` : target.normalizedNumeric
78302
- };
78303
- }
78304
- const text = sanitizeInlineOutgoingText(visibleText.text);
78305
- const client = new InlineSdkClient({
78306
- baseUrl: account.baseUrl,
78307
- token
78308
- });
78309
- await client.connect();
79659
+ let platformSendStarted = false;
79660
+ let client = null;
78310
79661
  try {
79662
+ const account = resolveInlineAccount({ cfg: params.cfg, accountId: params.accountId ?? null });
79663
+ if (!account.configured || !account.baseUrl) {
79664
+ throw new Error(`Inline not configured for account "${account.accountId}" (missing token or baseUrl)`);
79665
+ }
79666
+ const token = await resolveInlineToken(account);
79667
+ const target = parseInlineOutboundTarget({
79668
+ raw: params.to,
79669
+ context: "sendText"
79670
+ });
79671
+ const visibleText = sanitizeInlineVisibleText(params.text);
79672
+ if (visibleText.shouldSkip) {
79673
+ return {
79674
+ outcome: "not_sent",
79675
+ messageId: "",
79676
+ chatId: target.kind === "user" ? `user:${target.normalizedNumeric}` : target.normalizedNumeric
79677
+ };
79678
+ }
79679
+ const text = sanitizeInlineOutgoingText(visibleText.text);
79680
+ client = new InlineSdkClient({
79681
+ baseUrl: account.baseUrl,
79682
+ token
79683
+ });
79684
+ await client.connect(params.signal);
78311
79685
  const replyToMsgId = parseInlineId2(params.replyToId);
78312
79686
  const resolvedTarget = await resolveInlineOutboundTarget({
78313
79687
  client,
@@ -78320,12 +79694,20 @@ async function sendMessageInline(params) {
78320
79694
  parentChatId: resolvedTarget.targetId,
78321
79695
  threadId: params.threadId ?? null
78322
79696
  }) : null;
79697
+ const randomId = deriveInlineDeliveryRandomId(params);
79698
+ params.signal?.throwIfAborted();
79699
+ await params.onPlatformSendDispatch?.();
79700
+ params.signal?.throwIfAborted();
79701
+ params.assertDirectAdapterHandoff?.();
79702
+ platformSendStarted = true;
78323
79703
  const result = await client.sendMessage({
78324
79704
  ...effectiveChatId != null ? { chatId: effectiveChatId } : buildInlineSendTarget(resolvedTarget),
78325
79705
  text,
79706
+ ...randomId != null ? { randomId } : {},
78326
79707
  ...params.actions !== undefined ? { actions: params.actions } : {},
78327
79708
  ...replyToMsgId != null ? { replyToMsgId } : {},
78328
- parseMarkdown: account.config.parseMarkdown ?? true
79709
+ parseMarkdown: account.config.parseMarkdown ?? true,
79710
+ ...params.silent ? { sendMode: "silent" } : {}
78329
79711
  }).catch((error51) => {
78330
79712
  throw wrapInlineTargetError({
78331
79713
  error: error51,
@@ -78334,7 +79716,6 @@ async function sendMessageInline(params) {
78334
79716
  resolvedTarget
78335
79717
  });
78336
79718
  });
78337
- const bestEffort = result.messageId != null ? String(result.messageId) : BigInt(Date.now()).toString();
78338
79719
  if (resolvedTarget.kind === "chat") {
78339
79720
  recordInlineOutboundThreadParticipation({
78340
79721
  accountId: account.accountId,
@@ -78344,32 +79725,38 @@ async function sendMessageInline(params) {
78344
79725
  });
78345
79726
  }
78346
79727
  return {
78347
- messageId: bestEffort,
79728
+ messageId: result.messageId != null ? String(result.messageId) : "",
78348
79729
  chatId: effectiveChatId != null ? String(effectiveChatId) : formatInlineResultChatId(resolvedTarget)
78349
79730
  };
79731
+ } catch (error51) {
79732
+ if (!platformSendStarted)
79733
+ throw asInlinePlatformNotDispatched(error51);
79734
+ throw error51;
78350
79735
  } finally {
78351
- await client.close().catch(() => {});
79736
+ await client?.close().catch(() => {});
78352
79737
  }
78353
79738
  }
78354
79739
  async function sendMediaInline(params) {
78355
- const account = resolveInlineAccount({ cfg: params.cfg, accountId: params.accountId ?? null });
78356
- if (!account.configured || !account.baseUrl) {
78357
- throw new Error(`Inline not configured for account "${account.accountId}" (missing token or baseUrl)`);
78358
- }
78359
- const token = await resolveInlineToken(account);
78360
- const target = parseInlineOutboundTarget({
78361
- raw: params.to,
78362
- context: "sendMedia"
78363
- });
78364
- const replyToMsgId = parseInlineId2(params.replyToId);
78365
- const visibleText = sanitizeInlineVisibleText(params.text);
78366
- const caption = visibleText.shouldSkip ? "" : sanitizeInlineOutgoingText(visibleText.text).trim();
78367
- const client = new InlineSdkClient({
78368
- baseUrl: account.baseUrl,
78369
- token
78370
- });
78371
- await client.connect();
79740
+ let platformSendStarted = false;
79741
+ let client = null;
78372
79742
  try {
79743
+ const account = resolveInlineAccount({ cfg: params.cfg, accountId: params.accountId ?? null });
79744
+ if (!account.configured || !account.baseUrl) {
79745
+ throw new Error(`Inline not configured for account "${account.accountId}" (missing token or baseUrl)`);
79746
+ }
79747
+ const token = await resolveInlineToken(account);
79748
+ const target = parseInlineOutboundTarget({
79749
+ raw: params.to,
79750
+ context: "sendMedia"
79751
+ });
79752
+ const replyToMsgId = parseInlineId2(params.replyToId);
79753
+ const visibleText = sanitizeInlineVisibleText(params.text);
79754
+ const caption = visibleText.shouldSkip ? "" : sanitizeInlineOutgoingText(visibleText.text).trim();
79755
+ client = new InlineSdkClient({
79756
+ baseUrl: account.baseUrl,
79757
+ token
79758
+ });
79759
+ await client.connect(params.signal);
78373
79760
  const resolvedTarget = await resolveInlineOutboundTarget({
78374
79761
  client,
78375
79762
  context: "sendMedia",
@@ -78388,15 +79775,24 @@ async function sendMediaInline(params) {
78388
79775
  mediaUrl: params.mediaUrl,
78389
79776
  ...params.mediaAccess ? { mediaAccess: params.mediaAccess } : {},
78390
79777
  ...params.mediaLocalRoots ? { mediaLocalRoots: params.mediaLocalRoots } : {},
78391
- ...params.mediaReadFile ? { mediaReadFile: params.mediaReadFile } : {}
79778
+ ...params.mediaReadFile ? { mediaReadFile: params.mediaReadFile } : {},
79779
+ ...params.signal ? { signal: params.signal } : {}
78392
79780
  });
79781
+ const randomId = deriveInlineDeliveryRandomId(params);
79782
+ params.signal?.throwIfAborted();
79783
+ await params.onPlatformSendDispatch?.();
79784
+ params.signal?.throwIfAborted();
79785
+ params.assertDirectAdapterHandoff?.();
79786
+ platformSendStarted = true;
78393
79787
  const result = await client.sendMessage({
78394
79788
  ...effectiveChatId != null ? { chatId: effectiveChatId } : buildInlineSendTarget(resolvedTarget),
78395
79789
  ...caption ? { text: caption } : {},
78396
79790
  media,
79791
+ ...randomId != null ? { randomId } : {},
78397
79792
  ...params.actions !== undefined ? { actions: params.actions } : {},
78398
79793
  ...replyToMsgId != null ? { replyToMsgId } : {},
78399
- ...caption ? { parseMarkdown: account.config.parseMarkdown ?? true } : {}
79794
+ ...caption ? { parseMarkdown: account.config.parseMarkdown ?? true } : {},
79795
+ ...params.silent ? { sendMode: "silent" } : {}
78400
79796
  }).catch((error51) => {
78401
79797
  throw wrapInlineTargetError({
78402
79798
  error: error51,
@@ -78405,7 +79801,6 @@ async function sendMediaInline(params) {
78405
79801
  resolvedTarget
78406
79802
  });
78407
79803
  });
78408
- const bestEffort = result.messageId != null ? String(result.messageId) : BigInt(Date.now()).toString();
78409
79804
  if (resolvedTarget.kind === "chat") {
78410
79805
  recordInlineOutboundThreadParticipation({
78411
79806
  accountId: account.accountId,
@@ -78415,11 +79810,15 @@ async function sendMediaInline(params) {
78415
79810
  });
78416
79811
  }
78417
79812
  return {
78418
- messageId: bestEffort,
79813
+ messageId: result.messageId != null ? String(result.messageId) : "",
78419
79814
  chatId: effectiveChatId != null ? String(effectiveChatId) : formatInlineResultChatId(resolvedTarget)
78420
79815
  };
79816
+ } catch (error51) {
79817
+ if (!platformSendStarted)
79818
+ throw asInlinePlatformNotDispatched(error51);
79819
+ throw error51;
78421
79820
  } finally {
78422
- await client.close().catch(() => {});
79821
+ await client?.close().catch(() => {});
78423
79822
  }
78424
79823
  }
78425
79824
  function resolveDirectoryLimit(limit) {
@@ -78523,8 +79922,22 @@ var resolveInlineAllowlistGroupOverrides = createFlatAllowlistOverrideResolver({
78523
79922
  label: (key2) => key2,
78524
79923
  resolveEntries: (value) => value?.allowFrom
78525
79924
  });
79925
+ var inlineDurableFinalDeliveryCapabilities = {
79926
+ text: true,
79927
+ media: true,
79928
+ payload: true,
79929
+ silent: true,
79930
+ replyTo: true,
79931
+ thread: true,
79932
+ nativeQuote: false,
79933
+ messageSendingHooks: true,
79934
+ batch: true
79935
+ };
78526
79936
  var inlineOutbound = {
78527
79937
  deliveryMode: "direct",
79938
+ deliveryCapabilities: {
79939
+ durableFinal: inlineDurableFinalDeliveryCapabilities
79940
+ },
78528
79941
  targetsMatchForReplySuppression: ({ originTarget, targetKey, targetThreadId }) => {
78529
79942
  const origin = resolveInlineSessionTarget({ id: originTarget });
78530
79943
  const destination = resolveInlineSessionTarget({ id: targetThreadId ?? targetKey });
@@ -78557,17 +79970,25 @@ var inlineOutbound = {
78557
79970
  ...interactive ? { interactive } : {}
78558
79971
  };
78559
79972
  },
78560
- sendPayload: async ({
78561
- cfg,
78562
- to,
78563
- payload,
78564
- accountId,
78565
- replyToId,
78566
- threadId,
78567
- mediaAccess,
78568
- mediaLocalRoots,
78569
- mediaReadFile
78570
- }) => {
79973
+ sendPayload: async (context) => {
79974
+ const {
79975
+ cfg,
79976
+ to,
79977
+ payload,
79978
+ accountId,
79979
+ replyToId,
79980
+ threadId,
79981
+ mediaAccess,
79982
+ mediaLocalRoots,
79983
+ mediaReadFile,
79984
+ silent,
79985
+ deliveryQueueId,
79986
+ deliveryPartIndex,
79987
+ onPlatformSendDispatch,
79988
+ assertDirectAdapterHandoff,
79989
+ onDeliveryResult
79990
+ } = context;
79991
+ const { signal } = context;
78571
79992
  const text = resolveInlineInteractiveTextFallback({
78572
79993
  text: payload.text ?? undefined,
78573
79994
  interactive: payload.interactive,
@@ -78576,7 +79997,7 @@ var inlineOutbound = {
78576
79997
  const payloadReplyToId = typeof payload.replyToId === "string" ? payload.replyToId.trim() : null;
78577
79998
  const effectiveReplyToId = payloadReplyToId || replyToId || null;
78578
79999
  const actions = resolveInlinePayloadActions(payload);
78579
- const mediaUrls = payload.mediaUrls?.length ? payload.mediaUrls : payload.mediaUrl ? [payload.mediaUrl] : [];
80000
+ const mediaUrls = ((payload.mediaUrls?.length) ? payload.mediaUrls : payload.mediaUrl ? [payload.mediaUrl] : []).map((url2) => url2.trim()).filter(Boolean);
78580
80001
  if (mediaUrls.length === 0) {
78581
80002
  const result = await sendMessageInline({
78582
80003
  cfg,
@@ -78585,17 +80006,32 @@ var inlineOutbound = {
78585
80006
  actions,
78586
80007
  accountId: accountId ?? null,
78587
80008
  replyToId: effectiveReplyToId,
78588
- threadId: threadId ?? null
80009
+ threadId: threadId ?? null,
80010
+ silent,
80011
+ signal,
80012
+ deliveryQueueId,
80013
+ deliveryPartIndex,
80014
+ onPlatformSendDispatch,
80015
+ assertDirectAdapterHandoff
78589
80016
  });
78590
- return { channel: "inline", to, messageId: result.messageId, chatId: result.chatId };
80017
+ const delivery = {
80018
+ ...result.outcome ? { outcome: result.outcome } : {},
80019
+ channel: "inline",
80020
+ to,
80021
+ messageId: result.messageId,
80022
+ chatId: result.chatId
80023
+ };
80024
+ if (result.outcome !== "not_sent")
80025
+ await onDeliveryResult?.(delivery);
80026
+ return delivery;
78591
80027
  }
78592
- let finalResult = null;
80028
+ const deliveries = [];
78593
80029
  for (let index = 0;index < mediaUrls.length; index += 1) {
78594
80030
  const mediaUrl = mediaUrls[index];
78595
- if (!mediaUrl?.trim())
80031
+ if (!mediaUrl)
78596
80032
  continue;
78597
80033
  const isFirst = index === 0;
78598
- finalResult = await sendMediaInline({
80034
+ const result = await sendMediaInline({
78599
80035
  cfg,
78600
80036
  to,
78601
80037
  text: isFirst ? text : "",
@@ -78606,9 +80042,25 @@ var inlineOutbound = {
78606
80042
  threadId: threadId ?? null,
78607
80043
  ...mediaAccess ? { mediaAccess } : {},
78608
80044
  ...mediaLocalRoots ? { mediaLocalRoots } : {},
78609
- ...mediaReadFile ? { mediaReadFile } : {}
80045
+ ...mediaReadFile ? { mediaReadFile } : {},
80046
+ silent,
80047
+ signal,
80048
+ deliveryQueueId,
80049
+ deliveryPartIndex,
80050
+ deliverySubpartIndex: index,
80051
+ onPlatformSendDispatch,
80052
+ assertDirectAdapterHandoff
78610
80053
  });
80054
+ const delivery = {
80055
+ channel: "inline",
80056
+ to,
80057
+ messageId: result.messageId,
80058
+ chatId: result.chatId
80059
+ };
80060
+ deliveries.push(delivery);
80061
+ await onDeliveryResult?.(delivery);
78611
80062
  }
80063
+ const finalResult = deliveries.at(-1);
78612
80064
  if (!finalResult) {
78613
80065
  const result = await sendMessageInline({
78614
80066
  cfg,
@@ -78617,35 +80069,98 @@ var inlineOutbound = {
78617
80069
  actions,
78618
80070
  accountId: accountId ?? null,
78619
80071
  replyToId: effectiveReplyToId,
78620
- threadId: threadId ?? null
80072
+ threadId: threadId ?? null,
80073
+ silent,
80074
+ signal,
80075
+ deliveryQueueId,
80076
+ deliveryPartIndex,
80077
+ onPlatformSendDispatch,
80078
+ assertDirectAdapterHandoff
78621
80079
  });
78622
- return { channel: "inline", to, messageId: result.messageId, chatId: result.chatId };
78623
- }
78624
- return { channel: "inline", to, messageId: finalResult.messageId, chatId: finalResult.chatId };
80080
+ const delivery = {
80081
+ ...result.outcome ? { outcome: result.outcome } : {},
80082
+ channel: "inline",
80083
+ to,
80084
+ messageId: result.messageId,
80085
+ chatId: result.chatId
80086
+ };
80087
+ if (result.outcome !== "not_sent")
80088
+ await onDeliveryResult?.(delivery);
80089
+ return delivery;
80090
+ }
80091
+ const receipt = createMessageReceiptFromOutboundResults({
80092
+ results: deliveries,
80093
+ kind: "media",
80094
+ ...threadId != null ? { threadId: String(threadId) } : {},
80095
+ ...effectiveReplyToId ? { replyToId: effectiveReplyToId } : {}
80096
+ });
80097
+ return {
80098
+ ...finalResult,
80099
+ messageId: receipt.primaryPlatformMessageId ?? finalResult.messageId,
80100
+ receipt
80101
+ };
78625
80102
  },
78626
- sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {
80103
+ sendText: async (context) => {
80104
+ const {
80105
+ cfg,
80106
+ to,
80107
+ text,
80108
+ accountId,
80109
+ replyToId,
80110
+ threadId,
80111
+ silent,
80112
+ deliveryQueueId,
80113
+ deliveryPartIndex,
80114
+ onPlatformSendDispatch,
80115
+ assertDirectAdapterHandoff,
80116
+ onDeliveryResult
80117
+ } = context;
80118
+ const { signal } = context;
78627
80119
  const result = await sendMessageInline({
78628
80120
  cfg,
78629
80121
  to,
78630
80122
  text,
78631
80123
  accountId: accountId ?? null,
78632
80124
  replyToId: replyToId ?? null,
78633
- threadId: threadId ?? null
80125
+ threadId: threadId ?? null,
80126
+ silent,
80127
+ signal,
80128
+ deliveryQueueId,
80129
+ deliveryPartIndex,
80130
+ onPlatformSendDispatch,
80131
+ assertDirectAdapterHandoff
78634
80132
  });
78635
- return { channel: "inline", to, messageId: result.messageId, chatId: result.chatId };
80133
+ const delivery = {
80134
+ ...result.outcome ? { outcome: result.outcome } : {},
80135
+ channel: "inline",
80136
+ to,
80137
+ messageId: result.messageId,
80138
+ chatId: result.chatId
80139
+ };
80140
+ if (result.outcome !== "not_sent")
80141
+ await onDeliveryResult?.(delivery);
80142
+ return delivery;
78636
80143
  },
78637
- sendMedia: async ({
78638
- cfg,
78639
- to,
78640
- text,
78641
- mediaUrl,
78642
- accountId,
78643
- replyToId,
78644
- threadId,
78645
- mediaAccess,
78646
- mediaLocalRoots,
78647
- mediaReadFile
78648
- }) => {
80144
+ sendMedia: async (context) => {
80145
+ const {
80146
+ cfg,
80147
+ to,
80148
+ text,
80149
+ mediaUrl,
80150
+ accountId,
80151
+ replyToId,
80152
+ threadId,
80153
+ mediaAccess,
80154
+ mediaLocalRoots,
80155
+ mediaReadFile,
80156
+ silent,
80157
+ deliveryQueueId,
80158
+ deliveryPartIndex,
80159
+ onPlatformSendDispatch,
80160
+ assertDirectAdapterHandoff,
80161
+ onDeliveryResult
80162
+ } = context;
80163
+ const { signal } = context;
78649
80164
  if (!mediaUrl) {
78650
80165
  const result2 = await sendMessageInline({
78651
80166
  cfg,
@@ -78653,9 +80168,24 @@ var inlineOutbound = {
78653
80168
  text,
78654
80169
  accountId: accountId ?? null,
78655
80170
  replyToId: replyToId ?? null,
78656
- threadId: threadId ?? null
80171
+ threadId: threadId ?? null,
80172
+ silent,
80173
+ signal,
80174
+ deliveryQueueId,
80175
+ deliveryPartIndex,
80176
+ onPlatformSendDispatch,
80177
+ assertDirectAdapterHandoff
78657
80178
  });
78658
- return { channel: "inline", to, messageId: result2.messageId, chatId: result2.chatId };
80179
+ const delivery2 = {
80180
+ ...result2.outcome ? { outcome: result2.outcome } : {},
80181
+ channel: "inline",
80182
+ to,
80183
+ messageId: result2.messageId,
80184
+ chatId: result2.chatId
80185
+ };
80186
+ if (result2.outcome !== "not_sent")
80187
+ await onDeliveryResult?.(delivery2);
80188
+ return delivery2;
78659
80189
  }
78660
80190
  const result = await sendMediaInline({
78661
80191
  cfg,
@@ -78667,9 +80197,22 @@ var inlineOutbound = {
78667
80197
  threadId: threadId ?? null,
78668
80198
  ...mediaAccess ? { mediaAccess } : {},
78669
80199
  ...mediaLocalRoots ? { mediaLocalRoots } : {},
78670
- ...mediaReadFile ? { mediaReadFile } : {}
80200
+ ...mediaReadFile ? { mediaReadFile } : {},
80201
+ silent,
80202
+ signal,
80203
+ deliveryQueueId,
80204
+ deliveryPartIndex,
80205
+ onPlatformSendDispatch,
80206
+ assertDirectAdapterHandoff
78671
80207
  });
78672
- return { channel: "inline", to, messageId: result.messageId, chatId: result.chatId };
80208
+ const delivery = {
80209
+ channel: "inline",
80210
+ to,
80211
+ messageId: result.messageId,
80212
+ chatId: result.chatId
80213
+ };
80214
+ await onDeliveryResult?.(delivery);
80215
+ return delivery;
78673
80216
  }
78674
80217
  };
78675
80218
  function toInlineMessageBridgeResult(result) {
@@ -78688,21 +80231,31 @@ function toInlineMessageBridgeResult(result) {
78688
80231
  var inlineMessageAdapter = createChannelMessageAdapterFromOutbound({
78689
80232
  id: "inline",
78690
80233
  outbound: {
78691
- sendText: async ({ onDeliveryResult, ...ctx }) => {
78692
- const result = toInlineMessageBridgeResult(await inlineOutbound.sendText(ctx));
78693
- await onDeliveryResult?.(result);
78694
- return result;
78695
- },
78696
- sendMedia: async ({ onDeliveryResult, ...ctx }) => {
78697
- const result = toInlineMessageBridgeResult(await inlineOutbound.sendMedia(ctx));
78698
- await onDeliveryResult?.(result);
78699
- return result;
78700
- },
78701
- sendPayload: async ({ onDeliveryResult, ...ctx }) => {
78702
- const result = toInlineMessageBridgeResult(await inlineOutbound.sendPayload(ctx));
78703
- await onDeliveryResult?.(result);
78704
- return result;
78705
- }
80234
+ deliveryCapabilities: { durableFinal: inlineDurableFinalDeliveryCapabilities },
80235
+ sendText: async ({ onDeliveryResult, ...ctx }) => toInlineMessageBridgeResult(await inlineOutbound.sendText({
80236
+ ...ctx,
80237
+ ...onDeliveryResult ? {
80238
+ onDeliveryResult: async (result) => {
80239
+ await onDeliveryResult(toInlineMessageBridgeResult(result));
80240
+ }
80241
+ } : {}
80242
+ })),
80243
+ sendMedia: async ({ onDeliveryResult, ...ctx }) => toInlineMessageBridgeResult(await inlineOutbound.sendMedia({
80244
+ ...ctx,
80245
+ ...onDeliveryResult ? {
80246
+ onDeliveryResult: async (result) => {
80247
+ await onDeliveryResult(toInlineMessageBridgeResult(result));
80248
+ }
80249
+ } : {}
80250
+ })),
80251
+ sendPayload: async ({ onDeliveryResult, ...ctx }) => toInlineMessageBridgeResult(await inlineOutbound.sendPayload({
80252
+ ...ctx,
80253
+ ...onDeliveryResult ? {
80254
+ onDeliveryResult: async (result) => {
80255
+ await onDeliveryResult(toInlineMessageBridgeResult(result));
80256
+ }
80257
+ } : {}
80258
+ }))
78706
80259
  },
78707
80260
  live: {
78708
80261
  capabilities: {
@@ -79269,280 +80822,11 @@ var inlineChannelPlugin = {
79269
80822
  }
79270
80823
  };
79271
80824
 
79272
- // src/telemetry.ts
79273
- import { randomUUID as randomUUID2 } from "node:crypto";
79274
- import { readFile as readFile2 } from "node:fs/promises";
79275
- var TELEMETRY_TIMEOUT_MS = 2000;
79276
- var TELEMETRY_DEDUP_MS = 5 * 60000;
79277
- var MAX_ERROR_MESSAGE_LENGTH = 8000;
79278
- var MAX_STACK_FRAMES = 80;
79279
- var SENSITIVE_ENV_NAME = /(?:token|secret|password|api[_-]?key|authorization)/i;
79280
- var lastReports = new Map;
79281
- var releasePromise;
79282
- function telemetryDisabled(env = process.env) {
79283
- const disabled = (value) => value != null && ["1", "true", "yes", "on"].includes(value.trim().toLowerCase());
79284
- const optedOut = (value) => value != null && ["0", "false", "off"].includes(value.trim().toLowerCase());
79285
- return disabled(env.DO_NOT_TRACK) || optedOut(env.INLINE_PLUGIN_TELEMETRY);
79286
- }
79287
- function resolveDsn(env = process.env) {
79288
- if (telemetryDisabled(env))
79289
- return "";
79290
- return env.INLINE_OPENCLAW_SENTRY_DSN?.trim() ?? "";
79291
- }
79292
- function sensitiveValues(env = process.env) {
79293
- return Object.entries(env).filter(([name, value]) => SENSITIVE_ENV_NAME.test(name) && (value?.length ?? 0) >= 8).map(([, value]) => value);
79294
- }
79295
- function redactOpenClawTelemetryText(value, env = process.env) {
79296
- let text = String(value ?? "").replace(/\b(Authorization\s*[:=]\s*)(?:Basic|Bearer)\s+\S+/gi, "$1[REDACTED]").replace(/\b((?:Basic|Bearer)\s+)\S+/gi, "$1[REDACTED]").replace(/(https?:\/\/)[^/\s:@]+:[^@\s/]+@/gi, "$1[REDACTED]@").replace(/([?&](?:access_token|auth|authorization|key|password|secret|token)[^=\s&]*)=([^&\s]+)/gi, "$1=[REDACTED]").replace(/\b([A-Za-z0-9_-]*(?:token|secret|password|api[_-]?key|authorization)[A-Za-z0-9_-]*)\s*([=:])\s*\S+/gi, "$1$2[REDACTED]");
79297
- for (const secret of sensitiveValues(env)) {
79298
- text = text.replaceAll(secret, "[REDACTED]");
79299
- }
79300
- return text.slice(0, MAX_ERROR_MESSAGE_LENGTH);
79301
- }
79302
- function safeTag(value) {
79303
- const normalized = value.trim().toLowerCase();
79304
- return normalized.length > 0 && normalized.length <= 80 && /^[a-z0-9._-]+$/.test(normalized) ? normalized : "unknown";
79305
- }
79306
- function parseStack(error51, env) {
79307
- const stack = error51.stack ?? "";
79308
- const frames = [];
79309
- for (const rawLine of stack.split(`
79310
- `).slice(1)) {
79311
- const line = redactOpenClawTelemetryText(rawLine.trim(), env);
79312
- const match = /^at\s+(?:(.*?)\s+\()?(.+?):(\d+):(\d+)\)?$/.exec(line);
79313
- if (!match)
79314
- continue;
79315
- const filename = match[2];
79316
- const frame = {
79317
- filename,
79318
- abs_path: filename,
79319
- function: match[1] || "<anonymous>",
79320
- lineno: Number(match[3]),
79321
- colno: Number(match[4]),
79322
- in_app: filename.includes("@inline-openclaw/inline") || filename.includes("/openclaw/") || /\/(?:channel-plugin-api|runtime-register-api|index)\.js$/.test(filename)
79323
- };
79324
- frames.push(frame);
79325
- if (frames.length >= MAX_STACK_FRAMES)
79326
- break;
79327
- }
79328
- return frames.reverse();
79329
- }
79330
- function buildOpenClawTelemetryEvent(operation, error51, options = {}) {
79331
- const env = options.env ?? process.env;
79332
- const exception = error51 instanceof Error ? error51 : new Error(String(error51 ?? "Unknown error"));
79333
- const frames = parseStack(exception, env);
79334
- return {
79335
- event_id: randomUUID2().replaceAll("-", ""),
79336
- timestamp: new Date().toISOString(),
79337
- platform: "javascript",
79338
- level: "error",
79339
- logger: "inline.openclaw.plugin",
79340
- exception: {
79341
- values: [{
79342
- type: redactOpenClawTelemetryText(exception.name || "Error", env),
79343
- value: redactOpenClawTelemetryText(exception.message || String(error51), env),
79344
- mechanism: {
79345
- type: "inline_plugin_boundary",
79346
- handled: options.handled ?? true
79347
- },
79348
- ...frames.length > 0 ? { stacktrace: { frames } } : {}
79349
- }]
79350
- },
79351
- tags: {
79352
- operation: safeTag(operation),
79353
- runtime: "node",
79354
- os: process.platform,
79355
- arch: process.arch
79356
- },
79357
- sdk: { name: "inline.plugin.telemetry", version: "1" }
79358
- };
79359
- }
79360
- async function resolveRelease() {
79361
- releasePromise ??= (async () => {
79362
- try {
79363
- const parsed = JSON.parse(await readFile2(new URL("../package.json", import.meta.url), "utf8"));
79364
- if (typeof parsed.version === "string" && parsed.version.trim()) {
79365
- return `inline-openclaw-plugin@${parsed.version.trim()}`;
79366
- }
79367
- } catch {}
79368
- return;
79369
- })();
79370
- return releasePromise;
79371
- }
79372
- function parseSentryDsn(dsn) {
79373
- try {
79374
- const parsed = new URL(dsn);
79375
- if (!/^https?:$/.test(parsed.protocol) || !parsed.username)
79376
- return null;
79377
- const parts = parsed.pathname.split("/").filter(Boolean);
79378
- const projectId = parts.pop();
79379
- if (!projectId || !/^\d+$/.test(projectId))
79380
- return null;
79381
- const prefix = parts.length > 0 ? `/${parts.join("/")}` : "";
79382
- return {
79383
- endpoint: `${parsed.origin}${prefix}/api/${projectId}/envelope/`,
79384
- publicKey: parsed.username
79385
- };
79386
- } catch {
79387
- return null;
79388
- }
79389
- }
79390
- async function sendOpenClawPluginError(operation, error51, options = {}) {
79391
- const env = options.env ?? process.env;
79392
- const dsn = resolveDsn(env);
79393
- const target = parseSentryDsn(dsn);
79394
- if (!target)
79395
- return false;
79396
- const event = buildOpenClawTelemetryEvent(operation, error51, options);
79397
- const release = await resolveRelease();
79398
- if (release)
79399
- event.release = release;
79400
- const envelope = [
79401
- JSON.stringify({ event_id: event.event_id, dsn, sent_at: event.timestamp }),
79402
- JSON.stringify({ type: "event", content_type: "application/json" }),
79403
- JSON.stringify(event)
79404
- ].join(`
79405
- `);
79406
- const controller = new AbortController;
79407
- const timeout = setTimeout(() => controller.abort(), TELEMETRY_TIMEOUT_MS);
79408
- timeout.unref?.();
79409
- try {
79410
- const response = await fetch(target.endpoint, {
79411
- method: "POST",
79412
- headers: {
79413
- "content-type": "application/x-sentry-envelope",
79414
- "x-sentry-auth": `Sentry sentry_version=7, sentry_key=${target.publicKey}, sentry_client=inline.plugin.telemetry/1`
79415
- },
79416
- body: envelope,
79417
- signal: controller.signal
79418
- });
79419
- return response.ok;
79420
- } catch {
79421
- return false;
79422
- } finally {
79423
- clearTimeout(timeout);
79424
- }
79425
- }
79426
- function reportOpenClawPluginError(operation, error51, options = {}) {
79427
- try {
79428
- const exception = error51 instanceof Error ? error51 : new Error(String(error51 ?? "Unknown error"));
79429
- const key2 = `${safeTag(operation)}\x00${exception.name}\x00${redactOpenClawTelemetryText(exception.message)}`;
79430
- const now = Date.now();
79431
- if (now - (lastReports.get(key2) ?? 0) < TELEMETRY_DEDUP_MS)
79432
- return;
79433
- lastReports.set(key2, now);
79434
- sendOpenClawPluginError(operation, exception, options).catch(() => {});
79435
- } catch {}
79436
- }
79437
- function wrapCallback(operation, callback) {
79438
- return function(...args) {
79439
- try {
79440
- const result = Reflect.apply(callback, this, args);
79441
- if (result && typeof result.then === "function") {
79442
- return Promise.resolve(result).catch((error51) => {
79443
- reportOpenClawPluginError(operation, error51);
79444
- throw error51;
79445
- });
79446
- }
79447
- return result;
79448
- } catch (error51) {
79449
- reportOpenClawPluginError(operation, error51);
79450
- throw error51;
79451
- }
79452
- };
79453
- }
79454
- function wrapSurface(prefix, surface) {
79455
- const wrapped = { ...surface };
79456
- for (const [name, member] of Object.entries(wrapped)) {
79457
- if (typeof member === "function") {
79458
- wrapped[name] = wrapCallback(`${prefix}.${name}`, member);
79459
- }
79460
- }
79461
- return wrapped;
79462
- }
79463
- function instrumentToolValue(value) {
79464
- if (Array.isArray(value))
79465
- return value.map(instrumentToolValue);
79466
- if (!value || typeof value !== "object")
79467
- return value;
79468
- const tool = value;
79469
- const execute = tool.execute;
79470
- if (typeof execute !== "function")
79471
- return value;
79472
- const name = typeof tool.name === "string" ? safeTag(tool.name) : "unknown";
79473
- return new Proxy(tool, {
79474
- get(target, property, receiver) {
79475
- if (property === "execute") {
79476
- return wrapCallback(`tool.${name}`, execute);
79477
- }
79478
- return Reflect.get(target, property, receiver);
79479
- }
79480
- });
79481
- }
79482
- function instrumentOpenClawPluginApi(value) {
79483
- const api2 = value;
79484
- return new Proxy(api2, {
79485
- get(target, property, receiver) {
79486
- const member = Reflect.get(target, property, receiver);
79487
- if (property === "registerTool" && typeof member === "function") {
79488
- return (toolOrFactory, options) => {
79489
- const wrapped = typeof toolOrFactory === "function" ? wrapCallback("tool.factory", (...args) => instrumentToolValue(Reflect.apply(toolOrFactory, undefined, args))) : instrumentToolValue(toolOrFactory);
79490
- return Reflect.apply(member, target, [wrapped, options]);
79491
- };
79492
- }
79493
- if (property === "registerCommand" && typeof member === "function") {
79494
- return (command) => {
79495
- const handler = command.handler;
79496
- const name = typeof command.name === "string" ? safeTag(command.name) : "unknown";
79497
- const wrapped = typeof handler === "function" ? { ...command, handler: wrapCallback(`command.${name}`, handler) } : command;
79498
- return Reflect.apply(member, target, [wrapped]);
79499
- };
79500
- }
79501
- if (property === "on" && typeof member === "function") {
79502
- return (event, handler) => Reflect.apply(member, target, [event, wrapCallback(`hook.${safeTag(event)}`, handler)]);
79503
- }
79504
- return member;
79505
- }
79506
- });
79507
- }
79508
- function instrumentOpenClawChannelPlugin(value) {
79509
- const plugin = { ...value };
79510
- for (const name of [
79511
- "lifecycle",
79512
- "pairing",
79513
- "outbound",
79514
- "heartbeat",
79515
- "directory",
79516
- "resolver",
79517
- "allowlist",
79518
- "status",
79519
- "gateway"
79520
- ]) {
79521
- const surface = plugin[name];
79522
- if (surface && typeof surface === "object") {
79523
- plugin[name] = wrapSurface(name, surface);
79524
- }
79525
- }
79526
- const message = plugin.message;
79527
- if (message && typeof message === "object") {
79528
- const wrappedMessage = { ...message };
79529
- const send = wrappedMessage.send;
79530
- if (send && typeof send === "object") {
79531
- wrappedMessage.send = wrapSurface("message.send", send);
79532
- }
79533
- plugin.message = wrappedMessage;
79534
- }
79535
- return plugin;
79536
- }
79537
- function reportOpenClawRegistrationError(error51) {
79538
- reportOpenClawPluginError("plugin.register", error51, { handled: false });
79539
- }
79540
-
79541
80825
  // src/channel-plugin-api.ts
79542
80826
  var inlineChannelPlugin2 = instrumentOpenClawChannelPlugin(inlineChannelPlugin);
79543
80827
  export {
79544
80828
  inlineChannelPlugin2 as inlineChannelPlugin
79545
80829
  };
79546
80830
 
79547
- //# debugId=0CD7141E321D85A264756E2164756E21
80831
+ //# debugId=B8D72C8F948823B764756E2164756E21
79548
80832
  //# sourceMappingURL=channel-plugin-api.js.map