@inline-openclaw/inline 0.0.66 → 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);
@@ -33910,7 +34176,8 @@ class AgentProjectCatalog$Type extends import_runtime4.MessageType {
33910
34176
  constructor() {
33911
34177
  super("AgentProjectCatalog", [
33912
34178
  { no: 1, name: "options", kind: "message", repeat: 1, T: () => AgentProjectOption },
33913
- { no: 2, name: "can_select_folder", kind: "scalar", opt: true, T: 8 }
34179
+ { no: 2, name: "can_select_folder", kind: "scalar", opt: true, T: 8 },
34180
+ { no: 3, name: "default_project_id", kind: "scalar", opt: true, T: 9 }
33914
34181
  ]);
33915
34182
  }
33916
34183
  create(value) {
@@ -33931,6 +34198,9 @@ class AgentProjectCatalog$Type extends import_runtime4.MessageType {
33931
34198
  case 2:
33932
34199
  message.canSelectFolder = reader.bool();
33933
34200
  break;
34201
+ case 3:
34202
+ message.defaultProjectId = reader.string();
34203
+ break;
33934
34204
  default:
33935
34205
  let u = options.readUnknownField;
33936
34206
  if (u === "throw")
@@ -33947,6 +34217,8 @@ class AgentProjectCatalog$Type extends import_runtime4.MessageType {
33947
34217
  AgentProjectOption.internalBinaryWrite(message.options[i], writer.tag(1, import_runtime.WireType.LengthDelimited).fork(), options).join();
33948
34218
  if (message.canSelectFolder !== undefined)
33949
34219
  writer.tag(2, import_runtime.WireType.Varint).bool(message.canSelectFolder);
34220
+ if (message.defaultProjectId !== undefined)
34221
+ writer.tag(3, import_runtime.WireType.LengthDelimited).string(message.defaultProjectId);
33950
34222
  let u = options.writeUnknownFields;
33951
34223
  if (u !== false)
33952
34224
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -34060,7 +34332,8 @@ class AgentModelOption$Type extends import_runtime4.MessageType {
34060
34332
  { no: 1, name: "id", kind: "scalar", T: 9 },
34061
34333
  { no: 2, name: "label", kind: "scalar", T: 9 },
34062
34334
  { no: 3, name: "description", kind: "scalar", opt: true, T: 9 },
34063
- { no: 4, name: "reasoning_effort_ids", kind: "scalar", repeat: 2, T: 9 }
34335
+ { no: 4, name: "reasoning_effort_ids", kind: "scalar", repeat: 2, T: 9 },
34336
+ { no: 5, name: "default_reasoning_effort_id", kind: "scalar", opt: true, T: 9 }
34064
34337
  ]);
34065
34338
  }
34066
34339
  create(value) {
@@ -34089,6 +34362,9 @@ class AgentModelOption$Type extends import_runtime4.MessageType {
34089
34362
  case 4:
34090
34363
  message.reasoningEffortIds.push(reader.string());
34091
34364
  break;
34365
+ case 5:
34366
+ message.defaultReasoningEffortId = reader.string();
34367
+ break;
34092
34368
  default:
34093
34369
  let u = options.readUnknownField;
34094
34370
  if (u === "throw")
@@ -34109,6 +34385,8 @@ class AgentModelOption$Type extends import_runtime4.MessageType {
34109
34385
  writer.tag(3, import_runtime.WireType.LengthDelimited).string(message.description);
34110
34386
  for (let i = 0;i < message.reasoningEffortIds.length; i++)
34111
34387
  writer.tag(4, import_runtime.WireType.LengthDelimited).string(message.reasoningEffortIds[i]);
34388
+ if (message.defaultReasoningEffortId !== undefined)
34389
+ writer.tag(5, import_runtime.WireType.LengthDelimited).string(message.defaultReasoningEffortId);
34112
34390
  let u = options.writeUnknownFields;
34113
34391
  if (u !== false)
34114
34392
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -34120,7 +34398,8 @@ var AgentModelOption = new AgentModelOption$Type;
34120
34398
  class AgentModelCatalog$Type extends import_runtime4.MessageType {
34121
34399
  constructor() {
34122
34400
  super("AgentModelCatalog", [
34123
- { no: 1, name: "options", kind: "message", repeat: 1, T: () => AgentModelOption }
34401
+ { no: 1, name: "options", kind: "message", repeat: 1, T: () => AgentModelOption },
34402
+ { no: 2, name: "default_model_id", kind: "scalar", opt: true, T: 9 }
34124
34403
  ]);
34125
34404
  }
34126
34405
  create(value) {
@@ -34138,6 +34417,9 @@ class AgentModelCatalog$Type extends import_runtime4.MessageType {
34138
34417
  case 1:
34139
34418
  message.options.push(AgentModelOption.internalBinaryRead(reader, reader.uint32(), options));
34140
34419
  break;
34420
+ case 2:
34421
+ message.defaultModelId = reader.string();
34422
+ break;
34141
34423
  default:
34142
34424
  let u = options.readUnknownField;
34143
34425
  if (u === "throw")
@@ -34152,6 +34434,8 @@ class AgentModelCatalog$Type extends import_runtime4.MessageType {
34152
34434
  internalBinaryWrite(message, writer, options) {
34153
34435
  for (let i = 0;i < message.options.length; i++)
34154
34436
  AgentModelOption.internalBinaryWrite(message.options[i], writer.tag(1, import_runtime.WireType.LengthDelimited).fork(), options).join();
34437
+ if (message.defaultModelId !== undefined)
34438
+ writer.tag(2, import_runtime.WireType.LengthDelimited).string(message.defaultModelId);
34155
34439
  let u = options.writeUnknownFields;
34156
34440
  if (u !== false)
34157
34441
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -35038,7 +35322,8 @@ class BotChatSettingsFolder$Type extends import_runtime4.MessageType {
35038
35322
  { no: 4, name: "host_label", kind: "scalar", T: 9 },
35039
35323
  { no: 5, name: "allows_local_picker", kind: "scalar", T: 8 },
35040
35324
  { no: 6, name: "local_picker_port", kind: "scalar", opt: true, T: 13 },
35041
- { 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 }
35042
35327
  ]);
35043
35328
  }
35044
35329
  create(value) {
@@ -35078,6 +35363,9 @@ class BotChatSettingsFolder$Type extends import_runtime4.MessageType {
35078
35363
  case 7:
35079
35364
  message.localPickerCapability = reader.string();
35080
35365
  break;
35366
+ case 8:
35367
+ message.remoteBrowserVersion = reader.uint32();
35368
+ break;
35081
35369
  default:
35082
35370
  let u = options.readUnknownField;
35083
35371
  if (u === "throw")
@@ -35104,6 +35392,8 @@ class BotChatSettingsFolder$Type extends import_runtime4.MessageType {
35104
35392
  writer.tag(6, import_runtime.WireType.Varint).uint32(message.localPickerPort);
35105
35393
  if (message.localPickerCapability !== undefined)
35106
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);
35107
35397
  let u = options.writeUnknownFields;
35108
35398
  if (u !== false)
35109
35399
  (u == true ? import_runtime2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -38348,6 +38638,542 @@ class ChatAcknowledgements$Type extends import_runtime4.MessageType {
38348
38638
  }
38349
38639
  var ChatAcknowledgements = new ChatAcknowledgements$Type;
38350
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
+
38351
39177
  // ../node_modules/.bun/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/utils.js
38352
39178
  /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
38353
39179
  function isBytes(a) {
@@ -39126,6 +39952,13 @@ var asInlineId = (value, fieldName = "id") => {
39126
39952
  };
39127
39953
 
39128
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
+
39129
39962
  class AsyncChannelOverflowError extends Error {
39130
39963
  capacity;
39131
39964
  constructor(capacity) {
@@ -39235,6 +40068,7 @@ class AcknowledgedAsyncChannel {
39235
40068
  closed = false;
39236
40069
  failure = null;
39237
40070
  iteratorClaimed = false;
40071
+ consumption = null;
39238
40072
  constructor(capacity, byteLimit) {
39239
40073
  this.capacity = capacity;
39240
40074
  this.byteLimit = byteLimit;
@@ -39248,7 +40082,7 @@ class AcknowledgedAsyncChannel {
39248
40082
  send(value) {
39249
40083
  if (this.closed)
39250
40084
  return Promise.resolve(false);
39251
- if (!this.waiter && this.queue.length >= this.capacity) {
40085
+ if (!this.waiter && this.queue.length + (this.consumption?.active.size ?? 0) >= this.capacity) {
39252
40086
  throw new AsyncChannelOverflowError(this.capacity);
39253
40087
  }
39254
40088
  const bytes = this.byteLimit?.byteLength(value) ?? 0;
@@ -39268,6 +40102,7 @@ class AcknowledgedAsyncChannel {
39268
40102
  waiter.resolve({ value, done: false });
39269
40103
  } else {
39270
40104
  this.queue.push(item);
40105
+ this.pumpConsumption();
39271
40106
  }
39272
40107
  });
39273
40108
  }
@@ -39282,6 +40117,16 @@ class AcknowledgedAsyncChannel {
39282
40117
  return;
39283
40118
  this.closed = true;
39284
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
+ }
39285
40130
  this.active?.acknowledge(false);
39286
40131
  this.active = null;
39287
40132
  for (const item of this.queue)
@@ -39297,6 +40142,65 @@ class AcknowledgedAsyncChannel {
39297
40142
  else
39298
40143
  waiter.resolve({ value: undefined, done: true });
39299
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
+ }
39300
40204
  [Symbol.asyncIterator]() {
39301
40205
  if (this.iteratorClaimed) {
39302
40206
  return {
@@ -39304,8 +40208,11 @@ class AcknowledgedAsyncChannel {
39304
40208
  };
39305
40209
  }
39306
40210
  this.iteratorClaimed = true;
40211
+ let returned = false;
39307
40212
  return {
39308
40213
  next: () => {
40214
+ if (returned)
40215
+ return Promise.resolve({ value: undefined, done: true });
39309
40216
  if (this.active) {
39310
40217
  this.bufferedBytes -= this.active.bytes;
39311
40218
  this.active.acknowledge(true);
@@ -39329,6 +40236,11 @@ class AcknowledgedAsyncChannel {
39329
40236
  });
39330
40237
  },
39331
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;
39332
40244
  if (this.active) {
39333
40245
  this.bufferedBytes -= this.active.bytes;
39334
40246
  this.active.acknowledge(false);
@@ -40007,10 +40919,12 @@ var normalizeRpcTimeoutMs = (timeoutMs, fallback) => {
40007
40919
 
40008
40920
  class ProtocolClientError extends Error {
40009
40921
  code;
40922
+ rpcCode;
40010
40923
  constructor(code, details) {
40011
40924
  super(details?.message ?? code);
40012
40925
  this.code = code;
40013
40926
  this.name = `ProtocolClientError:${code}`;
40927
+ this.rpcCode = details?.code;
40014
40928
  }
40015
40929
  }
40016
40930
  var commitOutcomeUnknownError = (message) => new ProtocolClientError("commit-outcome-unknown", { message });
@@ -44833,8 +45747,11 @@ class InlineSdkClient {
44833
45747
  peerResolutionRequestedByChatId = new Map;
44834
45748
  recoveryReconnectInFlight = null;
44835
45749
  degradedUpdateBuckets = new Map;
45750
+ discoveryRetry = null;
45751
+ recoveryRetries = new Map;
44836
45752
  liveCursorFences = new Set;
44837
45753
  liveAdmittedSeqByBucket = new Map;
45754
+ liveDeliveriesByBucket = new Map;
44838
45755
  discoveryRound = null;
44839
45756
  discoveryInFlight = null;
44840
45757
  discoveryCommitInFlight = null;
@@ -44927,12 +45844,14 @@ class InlineSdkClient {
44927
45844
  }
44928
45845
  }
44929
45846
  async close() {
44930
- if (!this.started)
44931
- return;
45847
+ const wasStarted = this.started;
44932
45848
  this.closed = true;
44933
45849
  this.started = false;
45850
+ this.cancelRecoveryRetries();
44934
45851
  this.rejectOpen(new Error("closed"));
44935
45852
  this.eventStream.close();
45853
+ if (!wasStarted)
45854
+ return;
44936
45855
  await settleWithin(this.protocol.stopTransport(), closeJoinTimeoutMs, () => this.log.warn?.("Timed out stopping SDK transport during close"));
44937
45856
  await settleWithin(Promise.allSettled([
44938
45857
  ...this.catchUpInFlightByChatId.values(),
@@ -44994,6 +45913,20 @@ class InlineSdkClient {
44994
45913
  events() {
44995
45914
  return this.eventStream;
44996
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
+ }
44997
45930
  exportState() {
44998
45931
  return {
44999
45932
  version: 1,
@@ -45403,6 +46336,7 @@ class InlineSdkClient {
45403
46336
  this.log.error?.("SDK listener crashed", failure);
45404
46337
  this.started = false;
45405
46338
  this.closed = true;
46339
+ this.cancelRecoveryRetries();
45406
46340
  this.rejectOpen(failure);
45407
46341
  this.eventStream.fail(failure);
45408
46342
  this.protocol.stopTransport().catch((stopError) => {
@@ -45415,6 +46349,7 @@ class InlineSdkClient {
45415
46349
  return;
45416
46350
  this.authenticationError = error;
45417
46351
  this.started = false;
46352
+ this.cancelRecoveryRetries();
45418
46353
  this.rejectOpen(error);
45419
46354
  this.eventStream.close();
45420
46355
  try {
@@ -45424,6 +46359,7 @@ class InlineSdkClient {
45424
46359
  }
45425
46360
  }
45426
46361
  async onOpen() {
46362
+ this.cancelRecoveryRetries();
45427
46363
  this.requestCatchUpUser();
45428
46364
  for (const bucket of this.degradedUpdateBuckets.values()) {
45429
46365
  this.requestCatchUpForDegradedBucket(bucket);
@@ -45474,6 +46410,8 @@ class InlineSdkClient {
45474
46410
  return this.discoveryInFlight;
45475
46411
  if (this.discoveryCommitInFlight)
45476
46412
  return this.discoveryCommitInFlight;
46413
+ if (this.discoveryRetry?.timer)
46414
+ return;
45477
46415
  const round = {
45478
46416
  resultReceived: false,
45479
46417
  collectingHints: true,
@@ -45506,6 +46444,11 @@ class InlineSdkClient {
45506
46444
  this.log.warn?.("GET_UPDATES_STATE failed (continuing without date cursor)", error);
45507
46445
  if (this.discoveryRound === round)
45508
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
+ }
45509
46452
  }
45510
46453
  }
45511
46454
  tryCommitDiscoveryRound(round) {
@@ -45530,12 +46473,15 @@ class InlineSdkClient {
45530
46473
  return;
45531
46474
  if (saved) {
45532
46475
  this.discoveryRound = null;
46476
+ clearTimeout(this.discoveryRetry?.timer);
46477
+ this.discoveryRetry = null;
45533
46478
  return;
45534
46479
  }
45535
46480
  this.state.dateCursor = previousDateCursor;
45536
46481
  this.scheduleStateSave();
45537
46482
  this.discoveryRound = null;
45538
46483
  this.log.warn?.("Failed to persist discovery checkpoint; preserving previous date cursor");
46484
+ this.scheduleDiscoveryRetry("checkpoint_write_failed");
45539
46485
  }).finally(() => {
45540
46486
  if (this.discoveryCommitInFlight === commit)
45541
46487
  this.discoveryCommitInFlight = null;
@@ -45870,20 +46816,23 @@ class InlineSdkClient {
45870
46816
  try {
45871
46817
  acknowledged = this.eventStream.send(event);
45872
46818
  } catch (error) {
45873
- const bucket = this.bucketForEvent(event);
45874
- if (bucket) {
45875
- this.fenceLiveCursor(bucket);
45876
- this.markUpdateBucketDegraded(bucket);
45877
- 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);
45878
46824
  }
45879
46825
  this.log.warn?.("Inbound event buffer overflow; durable cursor remains unchanged and transport will recover", {
45880
- bucket: bucket ? this.updateBucketKey(bucket) : "none",
46826
+ bucket: bucket2 ? this.updateBucketKey(bucket2) : "none",
45881
46827
  error: extractErrorMessage(error)
45882
46828
  });
45883
46829
  this.requestRecoveryReconnect("inbound-event-buffer-overflow");
45884
46830
  return Promise.resolve(false);
45885
46831
  }
45886
- 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) => {
45887
46836
  if (applied) {
45888
46837
  onApplied?.();
45889
46838
  if (source === "live")
@@ -45891,8 +46840,16 @@ class InlineSdkClient {
45891
46840
  } else if (source === "live" && this.started) {
45892
46841
  this.recoverLiveEvent(event, "consumer-did-not-apply");
45893
46842
  }
46843
+ deliveries?.delete(delivery);
46844
+ if (key && deliveries?.size === 0)
46845
+ this.liveDeliveriesByBucket.delete(key);
45894
46846
  return applied;
45895
46847
  });
46848
+ if (key && deliveries) {
46849
+ deliveries.add(delivery);
46850
+ this.liveDeliveriesByBucket.set(key, deliveries);
46851
+ }
46852
+ return delivery;
45896
46853
  }
45897
46854
  bucketForEvent(event) {
45898
46855
  switch (event.kind) {
@@ -46070,20 +47027,25 @@ class InlineSdkClient {
46070
47027
  }
46071
47028
  requestCatchUpForDegradedBucket(bucket) {
46072
47029
  switch (bucket.kind) {
46073
- case "chat":
46074
- if (bucket.peer && this.isReliableChatPeer(bucket.peer)) {
46075
- 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 });
46076
47036
  } else {
46077
- const persistedPeer = this.persistedChatPeer(bucket.chatId);
46078
- if (persistedPeer)
46079
- this.requestCatchUpChat({ chatId: bucket.chatId, peer: persistedPeer });
46080
- else
46081
- this.resolvePersistedChatPeer(bucket.chatId);
47037
+ this.resolvePersistedChatPeer(bucket.chatId, updateSeq);
46082
47038
  }
46083
47039
  return;
46084
- case "space":
46085
- 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
+ });
46086
47047
  return;
47048
+ }
46087
47049
  case "user":
46088
47050
  this.requestCatchUpUser(true);
46089
47051
  return;
@@ -46268,7 +47230,7 @@ class InlineSdkClient {
46268
47230
  bumpChatSeq(chatId, seq, source) {
46269
47231
  if (source === "user" || source === "space" || source === "chat")
46270
47232
  return;
46271
- 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)
46272
47234
  return;
46273
47235
  if (!Number.isFinite(seq))
46274
47236
  return;
@@ -46277,6 +47239,7 @@ class InlineSdkClient {
46277
47239
  const key = chatId.toString();
46278
47240
  const prev = this.state.lastSeqByChatId[key] ?? 0;
46279
47241
  if (seq > prev) {
47242
+ this.resetRecoveryBackoff({ kind: "chat", chatId });
46280
47243
  this.state.lastSeqByChatId[key] = seq;
46281
47244
  this.scheduleStateSave();
46282
47245
  }
@@ -46285,7 +47248,7 @@ class InlineSdkClient {
46285
47248
  bumpSpaceSeq(spaceId, seq, source) {
46286
47249
  if (source === "user" || source === "space" || source === "chat")
46287
47250
  return;
46288
- 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)
46289
47252
  return;
46290
47253
  if (!Number.isFinite(seq))
46291
47254
  return;
@@ -46294,6 +47257,7 @@ class InlineSdkClient {
46294
47257
  const key = spaceId.toString();
46295
47258
  const prev = this.state.lastSeqBySpaceId[key] ?? 0;
46296
47259
  if (seq > prev) {
47260
+ this.resetRecoveryBackoff({ kind: "space", spaceId });
46297
47261
  this.state.lastSeqBySpaceId[key] = seq;
46298
47262
  this.scheduleStateSave();
46299
47263
  }
@@ -46308,12 +47272,13 @@ class InlineSdkClient {
46308
47272
  bumpUserSeq(seq, source) {
46309
47273
  if (source === "user" || source === "space" || source === "chat")
46310
47274
  return;
46311
- if (source === "live" && this.liveCursorFences.has("user"))
47275
+ if (source === "live" && this.liveCursorFences.has("user") && seq !== (this.state.lastUserSeq ?? 0) + 1)
46312
47276
  return;
46313
47277
  if (!Number.isFinite(seq) || seq <= 0)
46314
47278
  return;
46315
47279
  const prev = this.state.lastUserSeq ?? 0;
46316
47280
  if (seq > prev) {
47281
+ this.resetRecoveryBackoff({ kind: "user" });
46317
47282
  this.state.lastUserSeq = seq;
46318
47283
  this.scheduleStateSave();
46319
47284
  }
@@ -46327,14 +47292,17 @@ class InlineSdkClient {
46327
47292
  if (this.userCatchUpInFlight) {
46328
47293
  return this.userCatchUpInFlight;
46329
47294
  }
47295
+ if (this.recoveryRetries.get("user")?.timer)
47296
+ return null;
46330
47297
  this.fenceLiveCursor({ kind: "user" });
46331
47298
  this.userCatchUpInFlight = this.doCatchUpUser(lastUserSeq ?? 0).catch((error) => {
46332
- this.markUpdateBucketDegraded({ kind: "user" });
47299
+ this.recordCatchUpFailure({ kind: "user" }, error);
46333
47300
  this.log.warn?.("GET_UPDATES user catch-up failed; bucket remains degraded", {
46334
47301
  error: extractErrorMessage(error)
46335
47302
  });
46336
47303
  }).finally(() => {
46337
47304
  this.userCatchUpInFlight = null;
47305
+ this.scheduleRecoveryRetry({ kind: "user" });
46338
47306
  });
46339
47307
  return this.userCatchUpInFlight;
46340
47308
  }
@@ -46387,7 +47355,7 @@ class InlineSdkClient {
46387
47355
  });
46388
47356
  }
46389
47357
  if (deliveredSeq <= cursor && !payload.final) {
46390
- this.markUpdateBucketDegraded({ kind: "user" });
47358
+ this.markUpdateBucketDegraded({ kind: "user" }, "non_progress");
46391
47359
  this.log.warn?.("GET_UPDATES user catch-up made no progress; bucket remains degraded", {
46392
47360
  cursor,
46393
47361
  deliveredSeq
@@ -46423,15 +47391,18 @@ class InlineSdkClient {
46423
47391
  const existing = this.catchUpInFlightByChatId.get(params.chatId);
46424
47392
  if (existing)
46425
47393
  return existing;
47394
+ if (this.recoveryRetries.get(`chat:${params.chatId}`)?.timer)
47395
+ return Promise.resolve();
47396
+ const initialDemand = this.catchUpRequestedByChatId.get(params.chatId);
46426
47397
  const task = this.drainCatchUpChat(params.chatId).catch((error) => {
46427
- this.catchUpRequestedByChatId.delete(params.chatId);
46428
- 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);
46429
47399
  this.log.warn?.("GET_UPDATES chat catch-up failed; bucket remains degraded", {
46430
47400
  chatId: params.chatId.toString(),
46431
47401
  error: extractErrorMessage(error)
46432
47402
  });
46433
47403
  }).finally(() => {
46434
47404
  this.catchUpInFlightByChatId.delete(params.chatId);
47405
+ this.scheduleRecoveryRetry({ kind: "chat", chatId: params.chatId });
46435
47406
  });
46436
47407
  this.catchUpInFlightByChatId.set(params.chatId, task);
46437
47408
  return task;
@@ -46455,12 +47426,8 @@ class InlineSdkClient {
46455
47426
  if (stop) {
46456
47427
  if (this.catchUpRequestedByChatId.get(chatId) !== request)
46457
47428
  continue;
46458
- this.catchUpRequestedByChatId.delete(chatId);
46459
- return;
46460
- }
46461
- const latest = this.catchUpRequestedByChatId.get(chatId);
46462
- const syncedSeq = this.state.lastSeqByChatId?.[key] ?? 0;
46463
- if (!latest || latest.endSeq != null && latest.endSeq <= syncedSeq) {
47429
+ if (this.degradedUpdateBuckets.has(`chat:${chatId}`))
47430
+ return;
46464
47431
  this.catchUpRequestedByChatId.delete(chatId);
46465
47432
  return;
46466
47433
  }
@@ -46527,7 +47494,7 @@ class InlineSdkClient {
46527
47494
  });
46528
47495
  }
46529
47496
  if (deliveredSeq <= cursor && !payload.final) {
46530
- this.markUpdateBucketDegraded({ kind: "chat", chatId, peer });
47497
+ this.markUpdateBucketDegraded({ kind: "chat", chatId, peer }, "non_progress");
46531
47498
  this.log.warn?.("GET_UPDATES made no progress; bucket remains degraded", {
46532
47499
  chatId: chatId.toString(),
46533
47500
  cursor,
@@ -46545,7 +47512,7 @@ class InlineSdkClient {
46545
47512
  continue;
46546
47513
  }
46547
47514
  if (endSeq != null && deliveredSeq < endSeq) {
46548
- this.markUpdateBucketDegraded({ kind: "chat", chatId, peer });
47515
+ this.markUpdateBucketDegraded({ kind: "chat", chatId, peer }, "target_not_reached");
46549
47516
  this.log.warn?.("GET_UPDATES final chat page remained behind the requested target", {
46550
47517
  chatId: chatId.toString(),
46551
47518
  requestedEndSeq: endSeq,
@@ -46571,15 +47538,18 @@ class InlineSdkClient {
46571
47538
  const existing = this.catchUpInFlightBySpaceId.get(params.spaceId);
46572
47539
  if (existing)
46573
47540
  return existing;
47541
+ if (this.recoveryRetries.get(`space:${params.spaceId}`)?.timer)
47542
+ return Promise.resolve();
47543
+ const initialDemand = this.catchUpRequestedBySpaceId.get(params.spaceId);
46574
47544
  const task = this.drainCatchUpSpace(params.spaceId).catch((error) => {
46575
- this.catchUpRequestedBySpaceId.delete(params.spaceId);
46576
- this.markUpdateBucketDegraded({ kind: "space", spaceId: params.spaceId });
47545
+ this.recordCatchUpFailure({ kind: "space", spaceId: params.spaceId }, error, this.catchUpRequestedBySpaceId.get(params.spaceId) !== initialDemand);
46577
47546
  this.log.warn?.("GET_UPDATES space catch-up failed; bucket remains degraded", {
46578
47547
  spaceId: params.spaceId.toString(),
46579
47548
  error: extractErrorMessage(error)
46580
47549
  });
46581
47550
  }).finally(() => {
46582
47551
  this.catchUpInFlightBySpaceId.delete(params.spaceId);
47552
+ this.scheduleRecoveryRetry({ kind: "space", spaceId: params.spaceId });
46583
47553
  });
46584
47554
  this.catchUpInFlightBySpaceId.set(params.spaceId, task);
46585
47555
  return task;
@@ -46603,12 +47573,8 @@ class InlineSdkClient {
46603
47573
  if (stop) {
46604
47574
  if (this.catchUpRequestedBySpaceId.get(spaceId) !== request)
46605
47575
  continue;
46606
- this.catchUpRequestedBySpaceId.delete(spaceId);
46607
- return;
46608
- }
46609
- const latest = this.catchUpRequestedBySpaceId.get(spaceId);
46610
- const syncedSeq = this.state.lastSeqBySpaceId?.[key] ?? 0;
46611
- if (!latest || latest.endSeq != null && latest.endSeq <= syncedSeq) {
47576
+ if (this.degradedUpdateBuckets.has(`space:${spaceId}`))
47577
+ return;
46612
47578
  this.catchUpRequestedBySpaceId.delete(spaceId);
46613
47579
  return;
46614
47580
  }
@@ -46677,7 +47643,7 @@ class InlineSdkClient {
46677
47643
  });
46678
47644
  }
46679
47645
  if (deliveredSeq <= cursor && !payload.final) {
46680
- this.markUpdateBucketDegraded({ kind: "space", spaceId });
47646
+ this.markUpdateBucketDegraded({ kind: "space", spaceId }, "non_progress");
46681
47647
  this.log.warn?.("GET_UPDATES space made no progress; bucket remains degraded", {
46682
47648
  spaceId: spaceId.toString(),
46683
47649
  cursor,
@@ -46695,7 +47661,7 @@ class InlineSdkClient {
46695
47661
  continue;
46696
47662
  }
46697
47663
  if (endSeq != null && deliveredSeq < endSeq) {
46698
- this.markUpdateBucketDegraded({ kind: "space", spaceId });
47664
+ this.markUpdateBucketDegraded({ kind: "space", spaceId }, "target_not_reached");
46699
47665
  this.log.warn?.("GET_UPDATES final space page remained behind the requested target", {
46700
47666
  spaceId: spaceId.toString(),
46701
47667
  requestedEndSeq: endSeq,
@@ -46720,6 +47686,9 @@ class InlineSdkClient {
46720
47686
  const existing = this.peerResolutionInFlightByChatId.get(chatId);
46721
47687
  if (existing)
46722
47688
  return existing;
47689
+ if (this.recoveryRetries.get(`chat:${chatId}`)?.timer)
47690
+ return Promise.resolve();
47691
+ const initialDemand = this.peerResolutionRequestedByChatId.get(chatId);
46723
47692
  const task = this.getChat({ chatId }).then(async (chat) => {
46724
47693
  const peer = chat.peer;
46725
47694
  if (!peer || !this.isReliableChatPeer(peer)) {
@@ -46733,14 +47702,16 @@ class InlineSdkClient {
46733
47702
  ...requested && !requested.toLatest && requested.endSeq != null ? { updateSeq: requested.endSeq } : {}
46734
47703
  });
46735
47704
  }).catch((error) => {
46736
- this.markUpdateBucketDegraded({ kind: "chat", chatId });
47705
+ this.recordCatchUpFailure({ kind: "chat", chatId }, error, this.peerResolutionRequestedByChatId.get(chatId) !== initialDemand);
46737
47706
  this.log.warn?.("Unable to resolve legacy chat peer; bucket remains degraded", {
46738
47707
  chatId: chatId.toString(),
46739
47708
  error: extractErrorMessage(error)
46740
47709
  });
46741
47710
  }).finally(() => {
46742
47711
  this.peerResolutionInFlightByChatId.delete(chatId);
46743
- this.peerResolutionRequestedByChatId.delete(chatId);
47712
+ if (!this.degradedUpdateBuckets.has(`chat:${chatId}`))
47713
+ this.peerResolutionRequestedByChatId.delete(chatId);
47714
+ this.scheduleRecoveryRetry({ kind: "chat", chatId });
46744
47715
  });
46745
47716
  this.peerResolutionInFlightByChatId.set(chatId, task);
46746
47717
  return task;
@@ -46793,7 +47764,7 @@ class InlineSdkClient {
46793
47764
  }
46794
47765
  validateCatchUpPage(payload, startSeq, bucket) {
46795
47766
  if (payload.resultType !== GetUpdatesResult_ResultType.SLICE && payload.resultType !== GetUpdatesResult_ResultType.EMPTY) {
46796
- this.markUpdateBucketDegraded(bucket);
47767
+ this.markUpdateBucketDegraded(bucket, "invalid_page_type");
46797
47768
  this.log.warn?.("GET_UPDATES returned an invalid page result type; bucket remains degraded", {
46798
47769
  bucket: this.updateBucketKey(bucket),
46799
47770
  resultType: payload.resultType
@@ -46802,7 +47773,7 @@ class InlineSdkClient {
46802
47773
  }
46803
47774
  const deliveredSeq = Number(payload.seq);
46804
47775
  if (!Number.isSafeInteger(deliveredSeq) || deliveredSeq < startSeq) {
46805
- this.markUpdateBucketDegraded(bucket);
47776
+ this.markUpdateBucketDegraded(bucket, "invalid_page_cursor");
46806
47777
  this.log.warn?.("GET_UPDATES page moved backwards or returned an invalid seq; bucket remains degraded", {
46807
47778
  bucket: this.updateBucketKey(bucket),
46808
47779
  startSeq,
@@ -46814,7 +47785,7 @@ class InlineSdkClient {
46814
47785
  for (const update of payload.updates) {
46815
47786
  const seq = update.seq;
46816
47787
  if (!Number.isSafeInteger(seq) || seq == null || seq <= startSeq || seq > deliveredSeq || accounted.has(seq)) {
46817
- this.markUpdateBucketDegraded(bucket);
47788
+ this.markUpdateBucketDegraded(bucket, "invalid_update_sequence");
46818
47789
  this.log.warn?.("GET_UPDATES page included an invalid or duplicate update seq; bucket remains degraded", {
46819
47790
  bucket: this.updateBucketKey(bucket),
46820
47791
  seq
@@ -46827,7 +47798,7 @@ class InlineSdkClient {
46827
47798
  for (const skipped of payload.skippedSequences) {
46828
47799
  const seq = Number(skipped.seq);
46829
47800
  if (!Number.isSafeInteger(seq) || seq <= startSeq || seq > deliveredSeq || accounted.has(seq)) {
46830
- this.markUpdateBucketDegraded(bucket);
47801
+ this.markUpdateBucketDegraded(bucket, "invalid_skipped_sequence");
46831
47802
  this.log.warn?.("GET_UPDATES page included an invalid or duplicate skipped seq; bucket remains degraded", {
46832
47803
  bucket: this.updateBucketKey(bucket),
46833
47804
  seq
@@ -46843,7 +47814,7 @@ class InlineSdkClient {
46843
47814
  break;
46844
47815
  case SyncSkippedSequence_Reason.REASON_UNSPECIFIED:
46845
47816
  default:
46846
- this.markUpdateBucketDegraded(bucket);
47817
+ this.markUpdateBucketDegraded(bucket, "unknown_skip_reason");
46847
47818
  this.log.warn?.("GET_UPDATES page included an unsupported skipped-sequence reason; bucket remains degraded", {
46848
47819
  bucket: this.updateBucketKey(bucket),
46849
47820
  reason: skipped.reason
@@ -46852,7 +47823,7 @@ class InlineSdkClient {
46852
47823
  }
46853
47824
  }
46854
47825
  if (accounted.size !== deliveredSeq - startSeq) {
46855
- this.markUpdateBucketDegraded(bucket);
47826
+ this.markUpdateBucketDegraded(bucket, "unaccounted_gap");
46856
47827
  this.log.warn?.("GET_UPDATES page did not account for every advanced sequence; bucket remains degraded", {
46857
47828
  bucket: this.updateBucketKey(bucket),
46858
47829
  startSeq,
@@ -46934,7 +47905,7 @@ class InlineSdkClient {
46934
47905
  this.clearUpdateBucketDegraded(bucket);
46935
47906
  return true;
46936
47907
  } catch (error) {
46937
- this.markUpdateBucketDegraded(bucket);
47908
+ this.markUpdateBucketDegraded(bucket, "repair_failed");
46938
47909
  this.log.warn?.("Authoritative update repair failed; bucket remains degraded", {
46939
47910
  bucket: this.updateBucketKey(bucket),
46940
47911
  error: extractErrorMessage(error)
@@ -46943,7 +47914,17 @@ class InlineSdkClient {
46943
47914
  }
46944
47915
  }
46945
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);
46946
47925
  for (const update of updates) {
47926
+ if (update.seq != null && update.seq > 0 && update.seq <= appliedThrough)
47927
+ continue;
46947
47928
  if (update.update.oneofKind === "chatSkipPts" && source === "chat") {
46948
47929
  continue;
46949
47930
  }
@@ -46954,7 +47935,7 @@ class InlineSdkClient {
46954
47935
  if (accepted === true)
46955
47936
  continue;
46956
47937
  if (accepted === false) {
46957
- this.markUpdateBucketDegraded(bucket);
47938
+ this.markUpdateBucketDegraded(bucket, "host_unacknowledged");
46958
47939
  this.log.warn?.("GET_UPDATES event was not acknowledged by the SDK host; cursor remains unchanged", {
46959
47940
  bucket: this.updateBucketKey(bucket),
46960
47941
  updateKind: update.update.oneofKind
@@ -46975,8 +47956,95 @@ class InlineSdkClient {
46975
47956
  }
46976
47957
  return true;
46977
47958
  }
46978
- markUpdateBucketDegraded(bucket) {
46979
- 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);
46980
48048
  }
46981
48049
  fenceLiveCursor(bucket) {
46982
48050
  this.liveCursorFences.add(this.updateBucketKey(bucket));
@@ -46984,6 +48052,8 @@ class InlineSdkClient {
46984
48052
  clearUpdateBucketDegraded(bucket) {
46985
48053
  const key = this.updateBucketKey(bucket);
46986
48054
  this.degradedUpdateBuckets.delete(key);
48055
+ clearTimeout(this.recoveryRetries.get(key)?.timer);
48056
+ this.recoveryRetries.delete(key);
46987
48057
  this.liveCursorFences.delete(key);
46988
48058
  this.liveAdmittedSeqByBucket.delete(key);
46989
48059
  }
@@ -62888,6 +63958,275 @@ function looksLikeInlineTargetId(raw, normalizedInput) {
62888
63958
  return /^[0-9]+$/.test(normalized);
62889
63959
  }
62890
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
+
62891
64230
  // src/inline/monitor.ts
62892
64231
  import { mkdir as mkdir2, stat } from "node:fs/promises";
62893
64232
  import path3 from "node:path";
@@ -62958,6 +64297,8 @@ import {
62958
64297
  createTransportActivityStatusPatch
62959
64298
  } from "openclaw/plugin-sdk/gateway-runtime";
62960
64299
  import {
64300
+ hasFinalInboundReplyDispatch,
64301
+ hasVisibleInboundReplyDispatch,
62961
64302
  classifyChannelInboundEvent,
62962
64303
  createChannelInboundDebouncer,
62963
64304
  resolveUnmentionedGroupInboundPolicy,
@@ -63156,7 +64497,7 @@ import {
63156
64497
  } from "openclaw/plugin-sdk/interactive-runtime";
63157
64498
 
63158
64499
  // src/inline/media.ts
63159
- import { randomUUID } from "node:crypto";
64500
+ import { randomUUID as randomUUID2 } from "node:crypto";
63160
64501
  import { mkdir, writeFile as writeFile2 } from "node:fs/promises";
63161
64502
  import os from "node:os";
63162
64503
  import path from "node:path";
@@ -63291,17 +64632,19 @@ function resolveMediaMaxBytes(params) {
63291
64632
  }
63292
64633
  function buildInlineMediaLoadOptions(params) {
63293
64634
  const explicitLocalRoots = params.mediaAccess?.localRoots ?? params.mediaLocalRoots;
63294
- const readFile2 = params.mediaAccess?.readFile ?? params.mediaReadFile;
64635
+ const readFile3 = params.mediaAccess?.readFile ?? params.mediaReadFile;
63295
64636
  const workspaceDir = params.mediaAccess?.workspaceDir;
63296
- const localRoots = explicitLocalRoots === "any" || explicitLocalRoots?.length ? explicitLocalRoots : readFile2 ? "any" : undefined;
63297
- 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) {
63298
64640
  return params.maxBytes;
63299
64641
  }
63300
64642
  return {
63301
64643
  maxBytes: params.maxBytes,
63302
64644
  ...localRoots ? { localRoots } : {},
63303
- ...readFile2 ? { readFile: readFile2, hostReadCapability: true } : {},
63304
- ...workspaceDir ? { workspaceDir } : {}
64645
+ ...readFile3 ? { readFile: readFile3, hostReadCapability: true } : {},
64646
+ ...workspaceDir ? { workspaceDir } : {},
64647
+ ...signal ? { signal } : {}
63305
64648
  };
63306
64649
  }
63307
64650
  function mediaFromUploadResult(params) {
@@ -63328,12 +64671,15 @@ async function uploadInlineMediaFromUrl(params) {
63328
64671
  let uploadType;
63329
64672
  let fileName;
63330
64673
  try {
64674
+ params.signal?.throwIfAborted();
63331
64675
  loaded = await loadWebMediaCompat(params.mediaUrl, buildInlineMediaLoadOptions({
63332
64676
  maxBytes,
63333
64677
  ...params.mediaAccess ? { mediaAccess: params.mediaAccess } : {},
63334
64678
  ...params.mediaLocalRoots ? { mediaLocalRoots: params.mediaLocalRoots } : {},
63335
- ...params.mediaReadFile ? { mediaReadFile: params.mediaReadFile } : {}
64679
+ ...params.mediaReadFile ? { mediaReadFile: params.mediaReadFile } : {},
64680
+ ...params.signal ? { signal: params.signal } : {}
63336
64681
  }));
64682
+ params.signal?.throwIfAborted();
63337
64683
  if (!loaded) {
63338
64684
  throw new Error("inline media upload: media load returned no data");
63339
64685
  }
@@ -63358,6 +64704,7 @@ async function uploadInlineMediaFromUrl(params) {
63358
64704
  file: loaded.buffer,
63359
64705
  fileName,
63360
64706
  ...detectedMime ? { contentType: detectedMime } : {},
64707
+ ...params.signal ? { signal: params.signal } : {},
63361
64708
  ...uploadType === "video" ? {
63362
64709
  width: DEFAULT_VIDEO_WIDTH,
63363
64710
  height: DEFAULT_VIDEO_HEIGHT,
@@ -63416,7 +64763,7 @@ async function downloadInlineMediaFromUrl(params) {
63416
64763
  });
63417
64764
  const dir = path.join(os.tmpdir(), "openclaw-inline-downloads");
63418
64765
  await mkdir(dir, { recursive: true });
63419
- const filePath = path.join(dir, `${randomUUID()}-${fileName}`);
64766
+ const filePath = path.join(dir, `${randomUUID2()}-${fileName}`);
63420
64767
  await writeFile2(filePath, loaded.buffer, { flag: "wx" });
63421
64768
  return {
63422
64769
  path: filePath,
@@ -63538,6 +64885,12 @@ var INLINE_MESSAGE_ENTITY_TYPE = {
63538
64885
  function compactWhitespace(raw) {
63539
64886
  return (raw ?? "").replace(/\s+/g, " ").trim();
63540
64887
  }
64888
+ function normalizeRawMessageText(raw) {
64889
+ return (raw ?? "").replaceAll(`\r
64890
+ `, `
64891
+ `).replaceAll("\r", `
64892
+ `).trim();
64893
+ }
63541
64894
  function bestPhotoSize(photo) {
63542
64895
  let best = {
63543
64896
  cdnUrl: null,
@@ -63842,7 +65195,7 @@ function formatEntitySummary(entity) {
63842
65195
  }
63843
65196
  }
63844
65197
  function summarizeInlineMessageContent(message) {
63845
- const rawText = compactWhitespace(message.message);
65198
+ const rawText = normalizeRawMessageText(message.message);
63846
65199
  const media = messageMediaSummary(message);
63847
65200
  const attachments = messageAttachmentSummaries(message);
63848
65201
  const entities = messageEntitySummaries(message);
@@ -70283,13 +71636,44 @@ function createInlineUpdateCommand(api2) {
70283
71636
  };
70284
71637
  }
70285
71638
 
71639
+ // src/inline/maintenance-command-specs.ts
71640
+ var INLINE_SYNC_COMMAND_SPEC = {
71641
+ name: "inline-sync",
71642
+ nativeNames: { inline: "inline_sync" },
71643
+ nativeProgressMessages: { inline: "Syncing Inline commands and skills…" },
71644
+ description: "Resync Inline commands and skills",
71645
+ channels: ["inline"],
71646
+ acceptsArgs: false
71647
+ };
71648
+ var INLINE_VERSION_COMMAND_SPEC = {
71649
+ name: "inline-version",
71650
+ nativeNames: { inline: "inline_version" },
71651
+ description: "Show Inline plugin and sync information",
71652
+ channels: ["inline"],
71653
+ acceptsArgs: false
71654
+ };
71655
+ function listInlineMaintenanceCommandSpecs() {
71656
+ return [INLINE_SYNC_COMMAND_SPEC, INLINE_VERSION_COMMAND_SPEC].map((spec) => ({
71657
+ name: spec.nativeNames.inline,
71658
+ description: spec.description,
71659
+ acceptsArgs: spec.acceptsArgs
71660
+ }));
71661
+ }
71662
+
70286
71663
  // src/inline/bot-commands-sync.ts
70287
71664
  var INLINE_COMMAND_NAME_RE = /^[a-z0-9_]{1,32}$/;
70288
71665
  var INLINE_COMMAND_LIMIT = 100;
70289
71666
  var INLINE_COMMAND_DESCRIPTION_LIMIT = 256;
70290
71667
  var INLINE_COMMAND_RETRY_RATIO = 0.8;
70291
71668
  var INLINE_NATIVE_COMMAND_PROVIDER = "inline";
70292
- var INLINE_REQUIRED_COMMAND_NAMES = new Set(["follow", "unfollow", "threadreply", "inline_update"]);
71669
+ var INLINE_REQUIRED_COMMAND_NAMES = new Set([
71670
+ "follow",
71671
+ "unfollow",
71672
+ "threadreply",
71673
+ "inline_update",
71674
+ "inline_sync",
71675
+ "inline_version"
71676
+ ]);
70293
71677
  function resolveInlineChannelCommands(cfg) {
70294
71678
  const inline = cfg.channels?.inline;
70295
71679
  if (typeof inline !== "object" || inline === null || Array.isArray(inline))
@@ -70399,7 +71783,8 @@ async function buildInlineNativeCommandsForConfig(params) {
70399
71783
  ...getPluginCommandSpecs("inline", { config: params.cfg }),
70400
71784
  ...listInlineFollowCommandSpecs(),
70401
71785
  ...listInlineBuiltinCommandSpecs(),
70402
- ...listInlineUpdateCommandSpecs()
71786
+ ...listInlineUpdateCommandSpecs(),
71787
+ ...listInlineMaintenanceCommandSpecs()
70403
71788
  ];
70404
71789
  const seen = new Set;
70405
71790
  const resolved = [];
@@ -71523,7 +72908,8 @@ function listInlinePluginCommandSpecs(cfg) {
71523
72908
  return [
71524
72909
  ...listHostInlinePluginCommandSpecs(cfg),
71525
72910
  ...listInlineFollowCommandSpecs(),
71526
- ...listInlineBuiltinCommandSpecs()
72911
+ ...listInlineBuiltinCommandSpecs(),
72912
+ ...listInlineMaintenanceCommandSpecs()
71527
72913
  ];
71528
72914
  }
71529
72915
  function hasInlineCommandSpec(specs, commandName) {
@@ -72631,31 +74017,20 @@ function resolveInlineMediaMaxBytes(params) {
72631
74017
  }
72632
74018
  function buildInlineInboundMediaFacts(media) {
72633
74019
  return toInboundMediaFacts(media.map((item) => ({
72634
- path: item.path,
72635
- ...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 } : {}
72636
74025
  })));
72637
74026
  }
72638
- function buildInlineAttachmentPlaceholder(content) {
72639
- const media = content.media;
72640
- if (!media)
72641
- return "";
72642
- switch (media.kind) {
72643
- case "photo":
72644
- return "<media:image>";
72645
- case "video":
72646
- return "<media:video>";
72647
- case "document":
72648
- return "<media:document>";
72649
- case "voice":
72650
- return "<media:audio>";
72651
- default:
72652
- return "";
72653
- }
72654
- }
72655
74027
  function buildInlineInboundBodyText(content) {
72656
- const textWithPlaceholder = [content.rawText, buildInlineAttachmentPlaceholder(content)].filter(Boolean).join(`
72657
- `).trim();
72658
- 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 "";
72659
74034
  }
72660
74035
  function resolveFilePathHint(params) {
72661
74036
  const preferred = params.preferredName?.trim();
@@ -72672,20 +74047,31 @@ function resolveFilePathHint(params) {
72672
74047
  async function resolveInlineInboundMedia(params) {
72673
74048
  const content = summarizeInlineMessageContent(params.message);
72674
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;
72675
74053
  if (content.media?.url) {
72676
74054
  candidates.set(content.media.url, {
72677
74055
  fileName: content.media.fileName ?? null,
72678
- 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
72679
74065
  });
72680
74066
  }
72681
74067
  for (const attachment of content.attachments) {
72682
74068
  if (attachment.kind !== "urlPreview" || !attachment.previewImageUrl)
72683
74069
  continue;
72684
74070
  candidates.set(attachment.previewImageUrl, {
72685
- mimeType: null
74071
+ mimeType: null,
74072
+ kind: "image"
72686
74073
  });
72687
74074
  }
72688
- const out = [];
72689
74075
  for (const [url2, candidate] of candidates.entries()) {
72690
74076
  try {
72691
74077
  const filePathHint = resolveFilePathHint({ sourceUrl: url2, preferredName: candidate.fileName });
@@ -72697,12 +74083,22 @@ async function resolveInlineInboundMedia(params) {
72697
74083
  const fetchedContentType = fetched.contentType ?? candidate.mimeType ?? undefined;
72698
74084
  const saved = await params.core.channel.media.saveMediaBuffer(fetched.buffer, fetchedContentType, "inbound", params.maxBytes, fetched.fileName ?? candidate.fileName ?? undefined);
72699
74085
  const contentType = saved.contentType ?? fetchedContentType;
74086
+ const fileName = fetched.fileName ?? candidate.fileName;
72700
74087
  out.push({
72701
74088
  path: saved.path,
72702
- ...contentType ? { contentType } : {}
74089
+ ...contentType ? { contentType } : {},
74090
+ ...fileName ? { fileName } : {},
74091
+ ...candidate.kind !== "document" ? { kind: candidate.kind } : {},
74092
+ messageId
72703
74093
  });
72704
74094
  } catch (err) {
72705
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
+ });
72706
74102
  }
72707
74103
  }
72708
74104
  return out;
@@ -72949,6 +74345,9 @@ async function monitorInlineProvider(params) {
72949
74345
  },
72950
74346
  error: (msg, meta3) => {
72951
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
+ }
72952
74351
  log?.error(line);
72953
74352
  if (isRecoverableInlineConnectionError(line)) {
72954
74353
  recoverableConnectionError = line;
@@ -72981,7 +74380,7 @@ async function monitorInlineProvider(params) {
72981
74380
  const meResult = await client.invokeRaw(Method.GET_ME, {
72982
74381
  oneofKind: "getMe",
72983
74382
  getMe: {}
72984
- });
74383
+ }, { signal: abortSignal });
72985
74384
  if (meResult.oneofKind !== "getMe" || !meResult.getMe.user) {
72986
74385
  throw new Error("missing user");
72987
74386
  }
@@ -73405,7 +74804,7 @@ async function monitorInlineProvider(params) {
73405
74804
  currentAttachmentText = currentContent.attachmentText || null;
73406
74805
  currentEntityText = currentContent.entityText || null;
73407
74806
  }
73408
- if (!rawBody)
74807
+ if (!rawBody && !currentContent?.media && !currentContent?.attachments.length)
73409
74808
  return;
73410
74809
  commandTarget = resolveInlineCommandTarget(rawBody, botUsername);
73411
74810
  if (commandTarget.targeted && !commandTarget.addressedToMe) {
@@ -74997,6 +76396,9 @@ This model will be used for your next message.`, []);
74997
76396
  }
74998
76397
  };
74999
76398
  const replyOptions = {
76399
+ onObservedReplyDelivery: async () => {
76400
+ delivered = true;
76401
+ },
75000
76402
  ...onModelSelected ? { onModelSelected } : {},
75001
76403
  blockReplyTimeoutMs: 25000,
75002
76404
  ...streamViaEditMessage ? {
@@ -75441,12 +76843,14 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
75441
76843
  if (!delivered && streamViaEditMessage && (editStreamState.messageId != null || editStreamState.initialSendMayHaveLanded) && !streamedFinalEditRejected) {
75442
76844
  delivered = true;
75443
76845
  }
75444
- 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;
75445
76849
  const deliberateSilence = skippedSilently || dispatchResult.deliberateSilentTerminalReply === true;
75446
76850
  const skipFallbackSuppressed = dispatchResult.sourceReplyDeliveryMode === "message_tool_only";
75447
76851
  const hostRequestedNoVisibleRecovery = dispatchResult.noVisibleReplyFallbackEligible === true;
75448
76852
  const explicitFailure = dispatchError != null || failedNonSilent;
75449
- if (!delivered && !adoptingThread && (explicitFailure || !hostHandledTurn && !deliberateSilence && (skippedNonSilent && !skipFallbackSuppressed || hostRequestedNoVisibleRecovery))) {
76853
+ if (!delivered && !hostDeliveredReply && !deferredToActiveRun && !adoptingThread && (explicitFailure || !hostHandledTurn && !deliberateSilence && (skippedNonSilent && !skipFallbackSuppressed || hostRequestedNoVisibleRecovery))) {
75450
76854
  botPresenceLifecycle.fail();
75451
76855
  const fallbackText = undeliveredFinalText.trim() ? undeliveredFinalText : dispatchError != null ? INLINE_REQUEST_ERROR_FALLBACK : EMPTY_RESPONSE_FALLBACK;
75452
76856
  const sent = await client.sendMessage({
@@ -76218,17 +77622,19 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76218
77622
  };
76219
77623
  const loop = (async () => {
76220
77624
  try {
76221
- for await (const event of client.events()) {
76222
- if (abortSignal.aborted)
76223
- break;
77625
+ await client.consumeEvents(async (event) => {
77626
+ if (abortSignal.aborted) {
77627
+ await client.close();
77628
+ return;
77629
+ }
76224
77630
  const rawEvent = event;
76225
77631
  if (event.kind === "bot.chatSettings.request") {
76226
77632
  scheduleInboundTask("agent settings request", () => answerOpenClawBotSettingsRequest(event));
76227
- continue;
77633
+ return;
76228
77634
  }
76229
77635
  if (event.kind === "bot.chatSettings.item.invoke") {
76230
77636
  scheduleInboundTask("agent settings update", () => answerOpenClawBotSettingsMutation(event), { serialKey: `agent-settings:${String(event.chatId)}` });
76231
- continue;
77637
+ return;
76232
77638
  }
76233
77639
  if (event.kind === "message.new") {
76234
77640
  const msg = {
@@ -76236,31 +77642,31 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76236
77642
  chatId: event.chatId
76237
77643
  };
76238
77644
  if (msg.out || msg.fromId === meId)
76239
- continue;
77645
+ return;
76240
77646
  if (!claimInlineInboundMessageInstance({
76241
77647
  seen: seenInboundMessageInstances,
76242
77648
  chatId: event.chatId,
76243
77649
  message: msg
76244
77650
  }))
76245
- continue;
77651
+ return;
76246
77652
  if (isInlineAbortRequestMessage(msg, botUsername) && await isAuthorizedInlineAbortMessage({ chatId: event.chatId, msg })) {
76247
77653
  cancelPendingInlineDebounce({ chatId: event.chatId, msg });
76248
77654
  cancelPendingInlineVoiceMessages({ chatId: event.chatId, msg });
76249
77655
  scheduleImmediateInboundMessage({ chatId: event.chatId, msg }, "priority abort dispatch");
76250
- continue;
77656
+ return;
76251
77657
  }
76252
77658
  if (voiceTranscriptWaitMs > 0 && shouldWaitForInlineVoiceTranscript(msg)) {
76253
77659
  holdInlineVoiceMessage({
76254
77660
  chatId: event.chatId,
76255
77661
  msg
76256
77662
  });
76257
- continue;
77663
+ return;
76258
77664
  }
76259
77665
  scheduleInboundMessage({
76260
77666
  chatId: event.chatId,
76261
77667
  msg
76262
77668
  });
76263
- continue;
77669
+ return;
76264
77670
  }
76265
77671
  if (event.kind === "message.edit") {
76266
77672
  const msg = {
@@ -76268,9 +77674,9 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76268
77674
  chatId: event.chatId
76269
77675
  };
76270
77676
  if (msg.out || msg.fromId === meId)
76271
- continue;
77677
+ return;
76272
77678
  if (await handlePendingInlineVoiceEdit({ chatId: event.chatId, msg })) {
76273
- continue;
77679
+ return;
76274
77680
  }
76275
77681
  await queueInlineMessageLifecycleSystemEvent({
76276
77682
  action: "edited",
@@ -76278,7 +77684,7 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76278
77684
  messageIds: [msg.id],
76279
77685
  senderId: msg.fromId
76280
77686
  });
76281
- continue;
77687
+ return;
76282
77688
  }
76283
77689
  if (event.kind === "message.delete") {
76284
77690
  await queueInlineMessageLifecycleSystemEvent({
@@ -76286,18 +77692,18 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76286
77692
  chatId: event.chatId,
76287
77693
  messageIds: event.messageIds
76288
77694
  });
76289
- continue;
77695
+ return;
76290
77696
  }
76291
77697
  if (event.kind === "reaction.add") {
76292
77698
  if (event.reaction.userId === meId)
76293
- continue;
77699
+ return;
76294
77700
  const shouldQueue = await shouldQueueInlineReactionSystemEvent({
76295
77701
  chatId: event.chatId,
76296
77702
  messageId: event.reaction.messageId,
76297
77703
  senderId: event.reaction.userId
76298
77704
  });
76299
77705
  if (!shouldQueue)
76300
- continue;
77706
+ return;
76301
77707
  await queueInlineReactionSystemEvent({
76302
77708
  action: "added",
76303
77709
  chatId: event.chatId,
@@ -76305,18 +77711,18 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76305
77711
  senderId: event.reaction.userId,
76306
77712
  emoji: event.reaction.emoji
76307
77713
  });
76308
- continue;
77714
+ return;
76309
77715
  }
76310
77716
  if (event.kind === "reaction.delete") {
76311
77717
  if (event.userId === meId)
76312
- continue;
77718
+ return;
76313
77719
  const shouldQueue = await shouldQueueInlineReactionSystemEvent({
76314
77720
  chatId: event.chatId,
76315
77721
  messageId: event.messageId,
76316
77722
  senderId: event.userId
76317
77723
  });
76318
77724
  if (!shouldQueue)
76319
- continue;
77725
+ return;
76320
77726
  await queueInlineReactionSystemEvent({
76321
77727
  action: "removed",
76322
77728
  chatId: event.chatId,
@@ -76324,12 +77730,12 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76324
77730
  senderId: event.userId,
76325
77731
  emoji: event.emoji
76326
77732
  });
76327
- continue;
77733
+ return;
76328
77734
  }
76329
77735
  if (rawEvent["kind"] === "chat.participant.add") {
76330
77736
  const eventChatId = rawEvent["chatId"];
76331
77737
  if (!eventChatId)
76332
- continue;
77738
+ return;
76333
77739
  const participant = rawEvent["participant"];
76334
77740
  const eventDate = rawEvent["date"];
76335
77741
  const recovered = await recoverInlineJoinMentions({
@@ -76349,7 +77755,7 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76349
77755
  msg: { ...msg, mentioned: true }
76350
77756
  }, "inline join mention recovery", { serializeWithChat: true });
76351
77757
  }
76352
- continue;
77758
+ return;
76353
77759
  }
76354
77760
  if (rawEvent["kind"] === "message.action.invoke") {
76355
77761
  const actorUserId = rawEvent["actorUserId"];
@@ -76360,10 +77766,10 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76360
77766
  const eventChatId = rawEvent["chatId"];
76361
77767
  const eventDate = rawEvent["date"];
76362
77768
  if (!actorUserId || !interactionId || !actionId || !targetMessageId || !eventChatId || !eventDate || !data) {
76363
- continue;
77769
+ return;
76364
77770
  }
76365
77771
  if (actorUserId === meId)
76366
- continue;
77772
+ return;
76367
77773
  scheduleImmediateInboundMessage({
76368
77774
  chatId: eventChatId,
76369
77775
  msg: {
@@ -76383,9 +77789,9 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
76383
77789
  data
76384
77790
  }
76385
77791
  }, "inline action dispatch", { serializeWithChat: true });
76386
- continue;
77792
+ return;
76387
77793
  }
76388
- }
77794
+ });
76389
77795
  } catch (err) {
76390
77796
  publishStatus({ connected: false, lastError: String(err) });
76391
77797
  runtime.error?.(`inline monitor loop crashed: ${String(err)}`);
@@ -77613,6 +79019,22 @@ var inlineNativeApprovalAdapter = splitChannelApprovalCapability(inlineApprovalC
77613
79019
 
77614
79020
  // src/inline/channel.ts
77615
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
+ }
77616
79038
  function resolveInlineStatePath(accountId) {
77617
79039
  return path4.join(getInlineRuntime().state.resolveStateDir(), "channels", "inline", `${accountId}.json`);
77618
79040
  }
@@ -77904,7 +79326,7 @@ function resolveInlineSessionTarget(params) {
77904
79326
  const raw = params.id.trim().replace(/^inline:/i, "").trim();
77905
79327
  if (!raw)
77906
79328
  return;
77907
- const target = /^chat:/i.test(raw) ? raw : `chat:${raw}`;
79329
+ const target = /^(?:chat|user):/i.test(raw) ? raw : `chat:${raw}`;
77908
79330
  try {
77909
79331
  return parseInlineExplicitTarget(target)?.to;
77910
79332
  } catch {
@@ -78234,29 +79656,32 @@ async function notifyPairingApprovedInline(params) {
78234
79656
  }
78235
79657
  }
78236
79658
  async function sendMessageInline(params) {
78237
- const account = resolveInlineAccount({ cfg: params.cfg, accountId: params.accountId ?? null });
78238
- if (!account.configured || !account.baseUrl) {
78239
- throw new Error(`Inline not configured for account "${account.accountId}" (missing token or baseUrl)`);
78240
- }
78241
- const token = await resolveInlineToken(account);
78242
- const target = parseInlineOutboundTarget({
78243
- raw: params.to,
78244
- context: "sendText"
78245
- });
78246
- const visibleText = sanitizeInlineVisibleText(params.text);
78247
- if (visibleText.shouldSkip) {
78248
- return {
78249
- messageId: "",
78250
- chatId: target.kind === "user" ? `user:${target.normalizedNumeric}` : target.normalizedNumeric
78251
- };
78252
- }
78253
- const text = sanitizeInlineOutgoingText(visibleText.text);
78254
- const client = new InlineSdkClient({
78255
- baseUrl: account.baseUrl,
78256
- token
78257
- });
78258
- await client.connect();
79659
+ let platformSendStarted = false;
79660
+ let client = null;
78259
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);
78260
79685
  const replyToMsgId = parseInlineId2(params.replyToId);
78261
79686
  const resolvedTarget = await resolveInlineOutboundTarget({
78262
79687
  client,
@@ -78269,12 +79694,20 @@ async function sendMessageInline(params) {
78269
79694
  parentChatId: resolvedTarget.targetId,
78270
79695
  threadId: params.threadId ?? null
78271
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;
78272
79703
  const result = await client.sendMessage({
78273
79704
  ...effectiveChatId != null ? { chatId: effectiveChatId } : buildInlineSendTarget(resolvedTarget),
78274
79705
  text,
79706
+ ...randomId != null ? { randomId } : {},
78275
79707
  ...params.actions !== undefined ? { actions: params.actions } : {},
78276
79708
  ...replyToMsgId != null ? { replyToMsgId } : {},
78277
- parseMarkdown: account.config.parseMarkdown ?? true
79709
+ parseMarkdown: account.config.parseMarkdown ?? true,
79710
+ ...params.silent ? { sendMode: "silent" } : {}
78278
79711
  }).catch((error51) => {
78279
79712
  throw wrapInlineTargetError({
78280
79713
  error: error51,
@@ -78283,7 +79716,6 @@ async function sendMessageInline(params) {
78283
79716
  resolvedTarget
78284
79717
  });
78285
79718
  });
78286
- const bestEffort = result.messageId != null ? String(result.messageId) : BigInt(Date.now()).toString();
78287
79719
  if (resolvedTarget.kind === "chat") {
78288
79720
  recordInlineOutboundThreadParticipation({
78289
79721
  accountId: account.accountId,
@@ -78293,32 +79725,38 @@ async function sendMessageInline(params) {
78293
79725
  });
78294
79726
  }
78295
79727
  return {
78296
- messageId: bestEffort,
79728
+ messageId: result.messageId != null ? String(result.messageId) : "",
78297
79729
  chatId: effectiveChatId != null ? String(effectiveChatId) : formatInlineResultChatId(resolvedTarget)
78298
79730
  };
79731
+ } catch (error51) {
79732
+ if (!platformSendStarted)
79733
+ throw asInlinePlatformNotDispatched(error51);
79734
+ throw error51;
78299
79735
  } finally {
78300
- await client.close().catch(() => {});
79736
+ await client?.close().catch(() => {});
78301
79737
  }
78302
79738
  }
78303
79739
  async function sendMediaInline(params) {
78304
- const account = resolveInlineAccount({ cfg: params.cfg, accountId: params.accountId ?? null });
78305
- if (!account.configured || !account.baseUrl) {
78306
- throw new Error(`Inline not configured for account "${account.accountId}" (missing token or baseUrl)`);
78307
- }
78308
- const token = await resolveInlineToken(account);
78309
- const target = parseInlineOutboundTarget({
78310
- raw: params.to,
78311
- context: "sendMedia"
78312
- });
78313
- const replyToMsgId = parseInlineId2(params.replyToId);
78314
- const visibleText = sanitizeInlineVisibleText(params.text);
78315
- const caption = visibleText.shouldSkip ? "" : sanitizeInlineOutgoingText(visibleText.text).trim();
78316
- const client = new InlineSdkClient({
78317
- baseUrl: account.baseUrl,
78318
- token
78319
- });
78320
- await client.connect();
79740
+ let platformSendStarted = false;
79741
+ let client = null;
78321
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);
78322
79760
  const resolvedTarget = await resolveInlineOutboundTarget({
78323
79761
  client,
78324
79762
  context: "sendMedia",
@@ -78337,15 +79775,24 @@ async function sendMediaInline(params) {
78337
79775
  mediaUrl: params.mediaUrl,
78338
79776
  ...params.mediaAccess ? { mediaAccess: params.mediaAccess } : {},
78339
79777
  ...params.mediaLocalRoots ? { mediaLocalRoots: params.mediaLocalRoots } : {},
78340
- ...params.mediaReadFile ? { mediaReadFile: params.mediaReadFile } : {}
79778
+ ...params.mediaReadFile ? { mediaReadFile: params.mediaReadFile } : {},
79779
+ ...params.signal ? { signal: params.signal } : {}
78341
79780
  });
79781
+ const randomId = deriveInlineDeliveryRandomId(params);
79782
+ params.signal?.throwIfAborted();
79783
+ await params.onPlatformSendDispatch?.();
79784
+ params.signal?.throwIfAborted();
79785
+ params.assertDirectAdapterHandoff?.();
79786
+ platformSendStarted = true;
78342
79787
  const result = await client.sendMessage({
78343
79788
  ...effectiveChatId != null ? { chatId: effectiveChatId } : buildInlineSendTarget(resolvedTarget),
78344
79789
  ...caption ? { text: caption } : {},
78345
79790
  media,
79791
+ ...randomId != null ? { randomId } : {},
78346
79792
  ...params.actions !== undefined ? { actions: params.actions } : {},
78347
79793
  ...replyToMsgId != null ? { replyToMsgId } : {},
78348
- ...caption ? { parseMarkdown: account.config.parseMarkdown ?? true } : {}
79794
+ ...caption ? { parseMarkdown: account.config.parseMarkdown ?? true } : {},
79795
+ ...params.silent ? { sendMode: "silent" } : {}
78349
79796
  }).catch((error51) => {
78350
79797
  throw wrapInlineTargetError({
78351
79798
  error: error51,
@@ -78354,7 +79801,6 @@ async function sendMediaInline(params) {
78354
79801
  resolvedTarget
78355
79802
  });
78356
79803
  });
78357
- const bestEffort = result.messageId != null ? String(result.messageId) : BigInt(Date.now()).toString();
78358
79804
  if (resolvedTarget.kind === "chat") {
78359
79805
  recordInlineOutboundThreadParticipation({
78360
79806
  accountId: account.accountId,
@@ -78364,11 +79810,15 @@ async function sendMediaInline(params) {
78364
79810
  });
78365
79811
  }
78366
79812
  return {
78367
- messageId: bestEffort,
79813
+ messageId: result.messageId != null ? String(result.messageId) : "",
78368
79814
  chatId: effectiveChatId != null ? String(effectiveChatId) : formatInlineResultChatId(resolvedTarget)
78369
79815
  };
79816
+ } catch (error51) {
79817
+ if (!platformSendStarted)
79818
+ throw asInlinePlatformNotDispatched(error51);
79819
+ throw error51;
78370
79820
  } finally {
78371
- await client.close().catch(() => {});
79821
+ await client?.close().catch(() => {});
78372
79822
  }
78373
79823
  }
78374
79824
  function resolveDirectoryLimit(limit) {
@@ -78472,8 +79922,22 @@ var resolveInlineAllowlistGroupOverrides = createFlatAllowlistOverrideResolver({
78472
79922
  label: (key2) => key2,
78473
79923
  resolveEntries: (value) => value?.allowFrom
78474
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
+ };
78475
79936
  var inlineOutbound = {
78476
79937
  deliveryMode: "direct",
79938
+ deliveryCapabilities: {
79939
+ durableFinal: inlineDurableFinalDeliveryCapabilities
79940
+ },
78477
79941
  targetsMatchForReplySuppression: ({ originTarget, targetKey, targetThreadId }) => {
78478
79942
  const origin = resolveInlineSessionTarget({ id: originTarget });
78479
79943
  const destination = resolveInlineSessionTarget({ id: targetThreadId ?? targetKey });
@@ -78506,17 +79970,25 @@ var inlineOutbound = {
78506
79970
  ...interactive ? { interactive } : {}
78507
79971
  };
78508
79972
  },
78509
- sendPayload: async ({
78510
- cfg,
78511
- to,
78512
- payload,
78513
- accountId,
78514
- replyToId,
78515
- threadId,
78516
- mediaAccess,
78517
- mediaLocalRoots,
78518
- mediaReadFile
78519
- }) => {
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;
78520
79992
  const text = resolveInlineInteractiveTextFallback({
78521
79993
  text: payload.text ?? undefined,
78522
79994
  interactive: payload.interactive,
@@ -78525,7 +79997,7 @@ var inlineOutbound = {
78525
79997
  const payloadReplyToId = typeof payload.replyToId === "string" ? payload.replyToId.trim() : null;
78526
79998
  const effectiveReplyToId = payloadReplyToId || replyToId || null;
78527
79999
  const actions = resolveInlinePayloadActions(payload);
78528
- 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);
78529
80001
  if (mediaUrls.length === 0) {
78530
80002
  const result = await sendMessageInline({
78531
80003
  cfg,
@@ -78534,17 +80006,32 @@ var inlineOutbound = {
78534
80006
  actions,
78535
80007
  accountId: accountId ?? null,
78536
80008
  replyToId: effectiveReplyToId,
78537
- threadId: threadId ?? null
80009
+ threadId: threadId ?? null,
80010
+ silent,
80011
+ signal,
80012
+ deliveryQueueId,
80013
+ deliveryPartIndex,
80014
+ onPlatformSendDispatch,
80015
+ assertDirectAdapterHandoff
78538
80016
  });
78539
- 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;
78540
80027
  }
78541
- let finalResult = null;
80028
+ const deliveries = [];
78542
80029
  for (let index = 0;index < mediaUrls.length; index += 1) {
78543
80030
  const mediaUrl = mediaUrls[index];
78544
- if (!mediaUrl?.trim())
80031
+ if (!mediaUrl)
78545
80032
  continue;
78546
80033
  const isFirst = index === 0;
78547
- finalResult = await sendMediaInline({
80034
+ const result = await sendMediaInline({
78548
80035
  cfg,
78549
80036
  to,
78550
80037
  text: isFirst ? text : "",
@@ -78555,9 +80042,25 @@ var inlineOutbound = {
78555
80042
  threadId: threadId ?? null,
78556
80043
  ...mediaAccess ? { mediaAccess } : {},
78557
80044
  ...mediaLocalRoots ? { mediaLocalRoots } : {},
78558
- ...mediaReadFile ? { mediaReadFile } : {}
80045
+ ...mediaReadFile ? { mediaReadFile } : {},
80046
+ silent,
80047
+ signal,
80048
+ deliveryQueueId,
80049
+ deliveryPartIndex,
80050
+ deliverySubpartIndex: index,
80051
+ onPlatformSendDispatch,
80052
+ assertDirectAdapterHandoff
78559
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);
78560
80062
  }
80063
+ const finalResult = deliveries.at(-1);
78561
80064
  if (!finalResult) {
78562
80065
  const result = await sendMessageInline({
78563
80066
  cfg,
@@ -78566,35 +80069,98 @@ var inlineOutbound = {
78566
80069
  actions,
78567
80070
  accountId: accountId ?? null,
78568
80071
  replyToId: effectiveReplyToId,
78569
- threadId: threadId ?? null
80072
+ threadId: threadId ?? null,
80073
+ silent,
80074
+ signal,
80075
+ deliveryQueueId,
80076
+ deliveryPartIndex,
80077
+ onPlatformSendDispatch,
80078
+ assertDirectAdapterHandoff
78570
80079
  });
78571
- return { channel: "inline", to, messageId: result.messageId, chatId: result.chatId };
78572
- }
78573
- 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
+ };
78574
80102
  },
78575
- 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;
78576
80119
  const result = await sendMessageInline({
78577
80120
  cfg,
78578
80121
  to,
78579
80122
  text,
78580
80123
  accountId: accountId ?? null,
78581
80124
  replyToId: replyToId ?? null,
78582
- threadId: threadId ?? null
80125
+ threadId: threadId ?? null,
80126
+ silent,
80127
+ signal,
80128
+ deliveryQueueId,
80129
+ deliveryPartIndex,
80130
+ onPlatformSendDispatch,
80131
+ assertDirectAdapterHandoff
78583
80132
  });
78584
- 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;
78585
80143
  },
78586
- sendMedia: async ({
78587
- cfg,
78588
- to,
78589
- text,
78590
- mediaUrl,
78591
- accountId,
78592
- replyToId,
78593
- threadId,
78594
- mediaAccess,
78595
- mediaLocalRoots,
78596
- mediaReadFile
78597
- }) => {
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;
78598
80164
  if (!mediaUrl) {
78599
80165
  const result2 = await sendMessageInline({
78600
80166
  cfg,
@@ -78602,9 +80168,24 @@ var inlineOutbound = {
78602
80168
  text,
78603
80169
  accountId: accountId ?? null,
78604
80170
  replyToId: replyToId ?? null,
78605
- threadId: threadId ?? null
80171
+ threadId: threadId ?? null,
80172
+ silent,
80173
+ signal,
80174
+ deliveryQueueId,
80175
+ deliveryPartIndex,
80176
+ onPlatformSendDispatch,
80177
+ assertDirectAdapterHandoff
78606
80178
  });
78607
- 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;
78608
80189
  }
78609
80190
  const result = await sendMediaInline({
78610
80191
  cfg,
@@ -78616,9 +80197,22 @@ var inlineOutbound = {
78616
80197
  threadId: threadId ?? null,
78617
80198
  ...mediaAccess ? { mediaAccess } : {},
78618
80199
  ...mediaLocalRoots ? { mediaLocalRoots } : {},
78619
- ...mediaReadFile ? { mediaReadFile } : {}
80200
+ ...mediaReadFile ? { mediaReadFile } : {},
80201
+ silent,
80202
+ signal,
80203
+ deliveryQueueId,
80204
+ deliveryPartIndex,
80205
+ onPlatformSendDispatch,
80206
+ assertDirectAdapterHandoff
78620
80207
  });
78621
- 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;
78622
80216
  }
78623
80217
  };
78624
80218
  function toInlineMessageBridgeResult(result) {
@@ -78637,21 +80231,31 @@ function toInlineMessageBridgeResult(result) {
78637
80231
  var inlineMessageAdapter = createChannelMessageAdapterFromOutbound({
78638
80232
  id: "inline",
78639
80233
  outbound: {
78640
- sendText: async ({ onDeliveryResult, ...ctx }) => {
78641
- const result = toInlineMessageBridgeResult(await inlineOutbound.sendText(ctx));
78642
- await onDeliveryResult?.(result);
78643
- return result;
78644
- },
78645
- sendMedia: async ({ onDeliveryResult, ...ctx }) => {
78646
- const result = toInlineMessageBridgeResult(await inlineOutbound.sendMedia(ctx));
78647
- await onDeliveryResult?.(result);
78648
- return result;
78649
- },
78650
- sendPayload: async ({ onDeliveryResult, ...ctx }) => {
78651
- const result = toInlineMessageBridgeResult(await inlineOutbound.sendPayload(ctx));
78652
- await onDeliveryResult?.(result);
78653
- return result;
78654
- }
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
+ }))
78655
80259
  },
78656
80260
  live: {
78657
80261
  capabilities: {
@@ -79218,280 +80822,11 @@ var inlineChannelPlugin = {
79218
80822
  }
79219
80823
  };
79220
80824
 
79221
- // src/telemetry.ts
79222
- import { randomUUID as randomUUID2 } from "node:crypto";
79223
- import { readFile as readFile2 } from "node:fs/promises";
79224
- var TELEMETRY_TIMEOUT_MS = 2000;
79225
- var TELEMETRY_DEDUP_MS = 5 * 60000;
79226
- var MAX_ERROR_MESSAGE_LENGTH = 8000;
79227
- var MAX_STACK_FRAMES = 80;
79228
- var SENSITIVE_ENV_NAME = /(?:token|secret|password|api[_-]?key|authorization)/i;
79229
- var lastReports = new Map;
79230
- var releasePromise;
79231
- function telemetryDisabled(env = process.env) {
79232
- const disabled = (value) => value != null && ["1", "true", "yes", "on"].includes(value.trim().toLowerCase());
79233
- const optedOut = (value) => value != null && ["0", "false", "off"].includes(value.trim().toLowerCase());
79234
- return disabled(env.DO_NOT_TRACK) || optedOut(env.INLINE_PLUGIN_TELEMETRY);
79235
- }
79236
- function resolveDsn(env = process.env) {
79237
- if (telemetryDisabled(env))
79238
- return "";
79239
- return env.INLINE_OPENCLAW_SENTRY_DSN?.trim() ?? "";
79240
- }
79241
- function sensitiveValues(env = process.env) {
79242
- return Object.entries(env).filter(([name, value]) => SENSITIVE_ENV_NAME.test(name) && (value?.length ?? 0) >= 8).map(([, value]) => value);
79243
- }
79244
- function redactOpenClawTelemetryText(value, env = process.env) {
79245
- 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]");
79246
- for (const secret of sensitiveValues(env)) {
79247
- text = text.replaceAll(secret, "[REDACTED]");
79248
- }
79249
- return text.slice(0, MAX_ERROR_MESSAGE_LENGTH);
79250
- }
79251
- function safeTag(value) {
79252
- const normalized = value.trim().toLowerCase();
79253
- return normalized.length > 0 && normalized.length <= 80 && /^[a-z0-9._-]+$/.test(normalized) ? normalized : "unknown";
79254
- }
79255
- function parseStack(error51, env) {
79256
- const stack = error51.stack ?? "";
79257
- const frames = [];
79258
- for (const rawLine of stack.split(`
79259
- `).slice(1)) {
79260
- const line = redactOpenClawTelemetryText(rawLine.trim(), env);
79261
- const match = /^at\s+(?:(.*?)\s+\()?(.+?):(\d+):(\d+)\)?$/.exec(line);
79262
- if (!match)
79263
- continue;
79264
- const filename = match[2];
79265
- const frame = {
79266
- filename,
79267
- abs_path: filename,
79268
- function: match[1] || "<anonymous>",
79269
- lineno: Number(match[3]),
79270
- colno: Number(match[4]),
79271
- in_app: filename.includes("@inline-openclaw/inline") || filename.includes("/openclaw/") || /\/(?:channel-plugin-api|runtime-register-api|index)\.js$/.test(filename)
79272
- };
79273
- frames.push(frame);
79274
- if (frames.length >= MAX_STACK_FRAMES)
79275
- break;
79276
- }
79277
- return frames.reverse();
79278
- }
79279
- function buildOpenClawTelemetryEvent(operation, error51, options = {}) {
79280
- const env = options.env ?? process.env;
79281
- const exception = error51 instanceof Error ? error51 : new Error(String(error51 ?? "Unknown error"));
79282
- const frames = parseStack(exception, env);
79283
- return {
79284
- event_id: randomUUID2().replaceAll("-", ""),
79285
- timestamp: new Date().toISOString(),
79286
- platform: "javascript",
79287
- level: "error",
79288
- logger: "inline.openclaw.plugin",
79289
- exception: {
79290
- values: [{
79291
- type: redactOpenClawTelemetryText(exception.name || "Error", env),
79292
- value: redactOpenClawTelemetryText(exception.message || String(error51), env),
79293
- mechanism: {
79294
- type: "inline_plugin_boundary",
79295
- handled: options.handled ?? true
79296
- },
79297
- ...frames.length > 0 ? { stacktrace: { frames } } : {}
79298
- }]
79299
- },
79300
- tags: {
79301
- operation: safeTag(operation),
79302
- runtime: "node",
79303
- os: process.platform,
79304
- arch: process.arch
79305
- },
79306
- sdk: { name: "inline.plugin.telemetry", version: "1" }
79307
- };
79308
- }
79309
- async function resolveRelease() {
79310
- releasePromise ??= (async () => {
79311
- try {
79312
- const parsed = JSON.parse(await readFile2(new URL("../package.json", import.meta.url), "utf8"));
79313
- if (typeof parsed.version === "string" && parsed.version.trim()) {
79314
- return `inline-openclaw-plugin@${parsed.version.trim()}`;
79315
- }
79316
- } catch {}
79317
- return;
79318
- })();
79319
- return releasePromise;
79320
- }
79321
- function parseSentryDsn(dsn) {
79322
- try {
79323
- const parsed = new URL(dsn);
79324
- if (!/^https?:$/.test(parsed.protocol) || !parsed.username)
79325
- return null;
79326
- const parts = parsed.pathname.split("/").filter(Boolean);
79327
- const projectId = parts.pop();
79328
- if (!projectId || !/^\d+$/.test(projectId))
79329
- return null;
79330
- const prefix = parts.length > 0 ? `/${parts.join("/")}` : "";
79331
- return {
79332
- endpoint: `${parsed.origin}${prefix}/api/${projectId}/envelope/`,
79333
- publicKey: parsed.username
79334
- };
79335
- } catch {
79336
- return null;
79337
- }
79338
- }
79339
- async function sendOpenClawPluginError(operation, error51, options = {}) {
79340
- const env = options.env ?? process.env;
79341
- const dsn = resolveDsn(env);
79342
- const target = parseSentryDsn(dsn);
79343
- if (!target)
79344
- return false;
79345
- const event = buildOpenClawTelemetryEvent(operation, error51, options);
79346
- const release = await resolveRelease();
79347
- if (release)
79348
- event.release = release;
79349
- const envelope = [
79350
- JSON.stringify({ event_id: event.event_id, dsn, sent_at: event.timestamp }),
79351
- JSON.stringify({ type: "event", content_type: "application/json" }),
79352
- JSON.stringify(event)
79353
- ].join(`
79354
- `);
79355
- const controller = new AbortController;
79356
- const timeout = setTimeout(() => controller.abort(), TELEMETRY_TIMEOUT_MS);
79357
- timeout.unref?.();
79358
- try {
79359
- const response = await fetch(target.endpoint, {
79360
- method: "POST",
79361
- headers: {
79362
- "content-type": "application/x-sentry-envelope",
79363
- "x-sentry-auth": `Sentry sentry_version=7, sentry_key=${target.publicKey}, sentry_client=inline.plugin.telemetry/1`
79364
- },
79365
- body: envelope,
79366
- signal: controller.signal
79367
- });
79368
- return response.ok;
79369
- } catch {
79370
- return false;
79371
- } finally {
79372
- clearTimeout(timeout);
79373
- }
79374
- }
79375
- function reportOpenClawPluginError(operation, error51, options = {}) {
79376
- try {
79377
- const exception = error51 instanceof Error ? error51 : new Error(String(error51 ?? "Unknown error"));
79378
- const key2 = `${safeTag(operation)}\x00${exception.name}\x00${redactOpenClawTelemetryText(exception.message)}`;
79379
- const now = Date.now();
79380
- if (now - (lastReports.get(key2) ?? 0) < TELEMETRY_DEDUP_MS)
79381
- return;
79382
- lastReports.set(key2, now);
79383
- sendOpenClawPluginError(operation, exception, options).catch(() => {});
79384
- } catch {}
79385
- }
79386
- function wrapCallback(operation, callback) {
79387
- return function(...args) {
79388
- try {
79389
- const result = Reflect.apply(callback, this, args);
79390
- if (result && typeof result.then === "function") {
79391
- return Promise.resolve(result).catch((error51) => {
79392
- reportOpenClawPluginError(operation, error51);
79393
- throw error51;
79394
- });
79395
- }
79396
- return result;
79397
- } catch (error51) {
79398
- reportOpenClawPluginError(operation, error51);
79399
- throw error51;
79400
- }
79401
- };
79402
- }
79403
- function wrapSurface(prefix, surface) {
79404
- const wrapped = { ...surface };
79405
- for (const [name, member] of Object.entries(wrapped)) {
79406
- if (typeof member === "function") {
79407
- wrapped[name] = wrapCallback(`${prefix}.${name}`, member);
79408
- }
79409
- }
79410
- return wrapped;
79411
- }
79412
- function instrumentToolValue(value) {
79413
- if (Array.isArray(value))
79414
- return value.map(instrumentToolValue);
79415
- if (!value || typeof value !== "object")
79416
- return value;
79417
- const tool = value;
79418
- const execute = tool.execute;
79419
- if (typeof execute !== "function")
79420
- return value;
79421
- const name = typeof tool.name === "string" ? safeTag(tool.name) : "unknown";
79422
- return new Proxy(tool, {
79423
- get(target, property, receiver) {
79424
- if (property === "execute") {
79425
- return wrapCallback(`tool.${name}`, execute);
79426
- }
79427
- return Reflect.get(target, property, receiver);
79428
- }
79429
- });
79430
- }
79431
- function instrumentOpenClawPluginApi(value) {
79432
- const api2 = value;
79433
- return new Proxy(api2, {
79434
- get(target, property, receiver) {
79435
- const member = Reflect.get(target, property, receiver);
79436
- if (property === "registerTool" && typeof member === "function") {
79437
- return (toolOrFactory, options) => {
79438
- const wrapped = typeof toolOrFactory === "function" ? wrapCallback("tool.factory", (...args) => instrumentToolValue(Reflect.apply(toolOrFactory, undefined, args))) : instrumentToolValue(toolOrFactory);
79439
- return Reflect.apply(member, target, [wrapped, options]);
79440
- };
79441
- }
79442
- if (property === "registerCommand" && typeof member === "function") {
79443
- return (command) => {
79444
- const handler = command.handler;
79445
- const name = typeof command.name === "string" ? safeTag(command.name) : "unknown";
79446
- const wrapped = typeof handler === "function" ? { ...command, handler: wrapCallback(`command.${name}`, handler) } : command;
79447
- return Reflect.apply(member, target, [wrapped]);
79448
- };
79449
- }
79450
- if (property === "on" && typeof member === "function") {
79451
- return (event, handler) => Reflect.apply(member, target, [event, wrapCallback(`hook.${safeTag(event)}`, handler)]);
79452
- }
79453
- return member;
79454
- }
79455
- });
79456
- }
79457
- function instrumentOpenClawChannelPlugin(value) {
79458
- const plugin = { ...value };
79459
- for (const name of [
79460
- "lifecycle",
79461
- "pairing",
79462
- "outbound",
79463
- "heartbeat",
79464
- "directory",
79465
- "resolver",
79466
- "allowlist",
79467
- "status",
79468
- "gateway"
79469
- ]) {
79470
- const surface = plugin[name];
79471
- if (surface && typeof surface === "object") {
79472
- plugin[name] = wrapSurface(name, surface);
79473
- }
79474
- }
79475
- const message = plugin.message;
79476
- if (message && typeof message === "object") {
79477
- const wrappedMessage = { ...message };
79478
- const send = wrappedMessage.send;
79479
- if (send && typeof send === "object") {
79480
- wrappedMessage.send = wrapSurface("message.send", send);
79481
- }
79482
- plugin.message = wrappedMessage;
79483
- }
79484
- return plugin;
79485
- }
79486
- function reportOpenClawRegistrationError(error51) {
79487
- reportOpenClawPluginError("plugin.register", error51, { handled: false });
79488
- }
79489
-
79490
80825
  // src/channel-plugin-api.ts
79491
80826
  var inlineChannelPlugin2 = instrumentOpenClawChannelPlugin(inlineChannelPlugin);
79492
80827
  export {
79493
80828
  inlineChannelPlugin2 as inlineChannelPlugin
79494
80829
  };
79495
80830
 
79496
- //# debugId=3BEABAA42C98A89864756E2164756E21
80831
+ //# debugId=B8D72C8F948823B764756E2164756E21
79497
80832
  //# sourceMappingURL=channel-plugin-api.js.map