@inline-openclaw/inline 0.0.41 → 0.0.43

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.
@@ -20589,6 +20589,8 @@ class InlineSdkClient {
20589
20589
  saveInFlight = null;
20590
20590
  catchUpInFlightByChatId = new Map;
20591
20591
  catchUpRequestedByChatId = new Map;
20592
+ catchUpInFlightBySpaceId = new Map;
20593
+ catchUpRequestedBySpaceId = new Map;
20592
20594
  userCatchUpInFlight = null;
20593
20595
  constructor(options) {
20594
20596
  this.options = options;
@@ -20653,7 +20655,11 @@ class InlineSdkClient {
20653
20655
  this.started = false;
20654
20656
  this.rejectOpen(new Error("closed"));
20655
20657
  this.eventStream.close();
20656
- await Promise.allSettled(this.catchUpInFlightByChatId.values());
20658
+ await Promise.allSettled([
20659
+ ...this.catchUpInFlightByChatId.values(),
20660
+ ...this.catchUpInFlightBySpaceId.values(),
20661
+ ...this.userCatchUpInFlight ? [this.userCatchUpInFlight] : []
20662
+ ]);
20657
20663
  await this.flushStateSave();
20658
20664
  await this.protocol.stopTransport();
20659
20665
  }
@@ -20677,6 +20683,7 @@ class InlineSdkClient {
20677
20683
  version: 1,
20678
20684
  ...this.state.dateCursor != null ? { dateCursor: this.state.dateCursor } : {},
20679
20685
  ...this.state.lastSeqByChatId != null ? { lastSeqByChatId: { ...this.state.lastSeqByChatId } } : {},
20686
+ ...this.state.lastSeqBySpaceId != null ? { lastSeqBySpaceId: { ...this.state.lastSeqBySpaceId } } : {},
20680
20687
  ...this.state.lastUserSeq != null ? { lastUserSeq: this.state.lastUserSeq } : {}
20681
20688
  };
20682
20689
  }
@@ -20697,12 +20704,7 @@ class InlineSdkClient {
20697
20704
  const chat = result.getChat.chat;
20698
20705
  if (!chat)
20699
20706
  throw new Error("getChat: missing chat");
20700
- return {
20701
- chatId: chat.id,
20702
- peer: chat.peerId,
20703
- title: chat.title,
20704
- ...chat.lastMsgId != null ? { lastMsgId: chat.lastMsgId } : {}
20705
- };
20707
+ return { chatId: chat.id, peer: chat.peerId, title: chat.title };
20706
20708
  }
20707
20709
  async getMessages(params) {
20708
20710
  const peerId = this.inputPeerFromTarget(params, "getMessages");
@@ -21031,32 +21033,57 @@ class InlineSdkClient {
21031
21033
  }
21032
21034
  case "clearChatHistory": {
21033
21035
  const payload = update.update.clearChatHistory;
21036
+ if (!payload.target) {
21037
+ this.log.warn?.("Skipping clearChatHistory update without target");
21038
+ return;
21039
+ }
21034
21040
  if (payload.target.oneofKind === "spaceId") {
21041
+ this.bumpSpaceSeq(payload.target.spaceId, seq);
21035
21042
  await this.eventStream.send({
21036
21043
  kind: "space.history.clear",
21037
21044
  spaceId: payload.target.spaceId,
21038
21045
  ...payload.beforeDate != null ? { beforeDate: payload.beforeDate } : {},
21039
21046
  deleteReplyThreads: payload.deleteReplyThreads,
21047
+ deletedChatIds: payload.deletedChatIds,
21048
+ orphanedChatIds: payload.orphanedChatIds,
21049
+ detachedChatIds: payload.detachedChatIds,
21040
21050
  seq,
21041
21051
  date
21042
21052
  });
21043
21053
  return;
21044
21054
  }
21045
21055
  const peerId = payload.target.oneofKind === "peerId" ? payload.target.peerId : undefined;
21046
- const chatId = peerId?.type.oneofKind === "chat" ? peerId.type.chat.chatId : null;
21047
- if (!chatId) {
21048
- this.log.warn?.("Skipping clearChatHistory update without chat peer", peerId);
21056
+ if (peerId?.type.oneofKind === "chat") {
21057
+ const chatId = peerId.type.chat.chatId;
21058
+ this.bumpChatSeq(chatId, seq);
21059
+ await this.eventStream.send({
21060
+ kind: "message.history.clear",
21061
+ chatId,
21062
+ ...payload.beforeDate != null ? { beforeDate: payload.beforeDate } : {},
21063
+ deleteReplyThreads: payload.deleteReplyThreads,
21064
+ deletedChatIds: payload.deletedChatIds,
21065
+ orphanedChatIds: payload.orphanedChatIds,
21066
+ detachedChatIds: payload.detachedChatIds,
21067
+ seq,
21068
+ date
21069
+ });
21049
21070
  return;
21050
21071
  }
21051
- this.bumpChatSeq(chatId, seq);
21052
- await this.eventStream.send({
21053
- kind: "message.history.clear",
21054
- chatId,
21055
- ...payload.beforeDate != null ? { beforeDate: payload.beforeDate } : {},
21056
- deleteReplyThreads: payload.deleteReplyThreads,
21057
- seq,
21058
- date
21059
- });
21072
+ if (peerId?.type.oneofKind === "user") {
21073
+ await this.eventStream.send({
21074
+ kind: "message.history.clear",
21075
+ userId: peerId.type.user.userId,
21076
+ ...payload.beforeDate != null ? { beforeDate: payload.beforeDate } : {},
21077
+ deleteReplyThreads: payload.deleteReplyThreads,
21078
+ deletedChatIds: payload.deletedChatIds,
21079
+ orphanedChatIds: payload.orphanedChatIds,
21080
+ detachedChatIds: payload.detachedChatIds,
21081
+ seq,
21082
+ date
21083
+ });
21084
+ return;
21085
+ }
21086
+ this.log.warn?.("Skipping clearChatHistory update without peer target", peerId);
21060
21087
  return;
21061
21088
  }
21062
21089
  case "updateReaction": {
@@ -21140,6 +21167,7 @@ class InlineSdkClient {
21140
21167
  seq,
21141
21168
  date
21142
21169
  });
21170
+ this.requestCatchUpSpace({ spaceId: payload.spaceId, updateSeq: payload.updateSeq });
21143
21171
  return;
21144
21172
  }
21145
21173
  default:
@@ -21158,6 +21186,18 @@ class InlineSdkClient {
21158
21186
  this.scheduleStateSave();
21159
21187
  }
21160
21188
  }
21189
+ bumpSpaceSeq(spaceId, seq) {
21190
+ if (!Number.isFinite(seq))
21191
+ return;
21192
+ if (!this.state.lastSeqBySpaceId)
21193
+ this.state.lastSeqBySpaceId = {};
21194
+ const key = spaceId.toString();
21195
+ const prev = this.state.lastSeqBySpaceId[key] ?? 0;
21196
+ if (seq > prev) {
21197
+ this.state.lastSeqBySpaceId[key] = seq;
21198
+ this.scheduleStateSave();
21199
+ }
21200
+ }
21161
21201
  shouldSkipUserSeq(seq) {
21162
21202
  if (!Number.isFinite(seq))
21163
21203
  return false;
@@ -21337,6 +21377,112 @@ class InlineSdkClient {
21337
21377
  }
21338
21378
  return false;
21339
21379
  }
21380
+ requestCatchUpSpace(params) {
21381
+ const previous = this.catchUpRequestedBySpaceId.get(params.spaceId);
21382
+ this.catchUpRequestedBySpaceId.set(params.spaceId, {
21383
+ endSeq: Math.max(previous?.endSeq ?? 0, params.updateSeq)
21384
+ });
21385
+ if (this.catchUpInFlightBySpaceId.has(params.spaceId)) {
21386
+ return;
21387
+ }
21388
+ const task = this.drainCatchUpSpace(params.spaceId).catch((error) => {
21389
+ this.catchUpRequestedBySpaceId.delete(params.spaceId);
21390
+ this.log.warn?.("GET_UPDATES space catch-up failed; continuing live delivery", {
21391
+ spaceId: params.spaceId.toString(),
21392
+ error: extractErrorMessage(error)
21393
+ });
21394
+ }).finally(() => {
21395
+ this.catchUpInFlightBySpaceId.delete(params.spaceId);
21396
+ });
21397
+ this.catchUpInFlightBySpaceId.set(params.spaceId, task);
21398
+ }
21399
+ async drainCatchUpSpace(spaceId) {
21400
+ const key = spaceId.toString();
21401
+ while (true) {
21402
+ const request = this.catchUpRequestedBySpaceId.get(spaceId);
21403
+ if (!request)
21404
+ return;
21405
+ const lastSeq = this.state.lastSeqBySpaceId?.[key];
21406
+ const startSeq = lastSeq ?? Math.max(0, request.endSeq - defaultColdStartCatchUpWindow);
21407
+ if (request.endSeq <= startSeq) {
21408
+ this.catchUpRequestedBySpaceId.delete(spaceId);
21409
+ return;
21410
+ }
21411
+ const stop = await this.doCatchUpSpace(spaceId, startSeq, request.endSeq);
21412
+ if (stop) {
21413
+ this.catchUpRequestedBySpaceId.delete(spaceId);
21414
+ return;
21415
+ }
21416
+ const latest = this.catchUpRequestedBySpaceId.get(spaceId);
21417
+ const syncedSeq = this.state.lastSeqBySpaceId?.[key] ?? 0;
21418
+ if (!latest || latest.endSeq <= syncedSeq) {
21419
+ this.catchUpRequestedBySpaceId.delete(spaceId);
21420
+ return;
21421
+ }
21422
+ }
21423
+ }
21424
+ async doCatchUpSpace(spaceId, startSeq, endSeq) {
21425
+ let cursor = startSeq;
21426
+ while (cursor < endSeq) {
21427
+ const result = await this.invoke(Method.GET_UPDATES, {
21428
+ oneofKind: "getUpdates",
21429
+ getUpdates: GetUpdatesInput.create({
21430
+ bucket: UpdateBucket.create({
21431
+ type: {
21432
+ oneofKind: "space",
21433
+ space: {
21434
+ spaceId
21435
+ }
21436
+ }
21437
+ }),
21438
+ startSeq: BigInt(cursor),
21439
+ seqEnd: BigInt(endSeq),
21440
+ totalLimit: defaultCatchUpTotalLimit,
21441
+ limit: defaultCatchUpPageLimit
21442
+ })
21443
+ });
21444
+ const payload = result.getUpdates;
21445
+ if (payload.resultType === GetUpdatesResult_ResultType.TOO_LONG) {
21446
+ this.log.warn?.("GET_UPDATES space too long; fast-forwarding cursor", {
21447
+ spaceId: spaceId.toString(),
21448
+ seq: payload.seq
21449
+ });
21450
+ this.bumpSpaceSeq(spaceId, endSeq);
21451
+ if (payload.date !== 0n) {
21452
+ this.state.dateCursor = payload.date;
21453
+ }
21454
+ this.scheduleStateSave();
21455
+ return true;
21456
+ }
21457
+ const deliveredSeq = Number(payload.seq ?? 0n);
21458
+ if (!Number.isSafeInteger(deliveredSeq)) {
21459
+ this.log.warn?.("GET_UPDATES space returned non-integer seq; aborting catch-up", {
21460
+ spaceId: spaceId.toString()
21461
+ });
21462
+ return true;
21463
+ }
21464
+ this.bumpSpaceSeq(spaceId, deliveredSeq);
21465
+ for (const update of payload.updates) {
21466
+ await this.handleUpdate(update);
21467
+ }
21468
+ if (payload.date !== 0n) {
21469
+ this.state.dateCursor = payload.date;
21470
+ }
21471
+ this.scheduleStateSave();
21472
+ if (payload.final)
21473
+ return true;
21474
+ if (deliveredSeq <= cursor) {
21475
+ this.log.warn?.("GET_UPDATES space made no progress; aborting catch-up", {
21476
+ spaceId: spaceId.toString(),
21477
+ cursor,
21478
+ deliveredSeq
21479
+ });
21480
+ return true;
21481
+ }
21482
+ cursor = deliveredSeq;
21483
+ }
21484
+ return false;
21485
+ }
21340
21486
  peerToInputPeer(peer, chatId) {
21341
21487
  if (!peer) {
21342
21488
  return InputPeer.create({ type: { oneofKind: "chat", chat: { chatId } } });
@@ -21417,6 +21563,7 @@ class InlineSdkClient {
21417
21563
  version: 1,
21418
21564
  ...this.state.dateCursor != null ? { dateCursor: this.state.dateCursor } : {},
21419
21565
  ...this.state.lastSeqByChatId != null ? { lastSeqByChatId: { ...this.state.lastSeqByChatId } } : {},
21566
+ ...this.state.lastSeqBySpaceId != null ? { lastSeqBySpaceId: { ...this.state.lastSeqBySpaceId } } : {},
21420
21567
  ...this.state.lastUserSeq != null ? { lastUserSeq: this.state.lastUserSeq } : {}
21421
21568
  };
21422
21569
  this.saveInFlight = store.save(snapshot).catch((error) => {
@@ -21634,7 +21781,9 @@ var serializeStateV1 = (state) => {
21634
21781
  const json = {
21635
21782
  version: 1,
21636
21783
  ...state.dateCursor != null ? { dateCursor: state.dateCursor.toString() } : {},
21637
- ...state.lastSeqByChatId != null ? { lastSeqByChatId: state.lastSeqByChatId } : {}
21784
+ ...state.lastSeqByChatId != null ? { lastSeqByChatId: state.lastSeqByChatId } : {},
21785
+ ...state.lastSeqBySpaceId != null ? { lastSeqBySpaceId: state.lastSeqBySpaceId } : {},
21786
+ ...state.lastUserSeq != null ? { lastUserSeq: state.lastUserSeq } : {}
21638
21787
  };
21639
21788
  return JSON.stringify(json, null, 2);
21640
21789
  };
@@ -21646,10 +21795,21 @@ var deserializeStateV1 = (raw) => {
21646
21795
  return {
21647
21796
  version: 1,
21648
21797
  ...parsed.dateCursor != null ? { dateCursor: BigInt(parsed.dateCursor) } : {},
21649
- ...parsed.lastSeqByChatId != null ? { lastSeqByChatId: parsed.lastSeqByChatId } : {}
21798
+ ...parsed.lastSeqByChatId != null ? { lastSeqByChatId: parsed.lastSeqByChatId } : {},
21799
+ ...parsed.lastSeqBySpaceId != null ? { lastSeqBySpaceId: parsed.lastSeqBySpaceId } : {},
21800
+ ...parsed.lastUserSeq != null ? { lastUserSeq: parsed.lastUserSeq } : {}
21650
21801
  };
21651
21802
  };
21652
21803
  var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
21804
+ var isSeqRecord = (value) => {
21805
+ if (!isRecord2(value))
21806
+ return false;
21807
+ for (const v of Object.values(value)) {
21808
+ if (typeof v !== "number" || !Number.isFinite(v))
21809
+ return false;
21810
+ }
21811
+ return true;
21812
+ };
21653
21813
  var isStateJsonV1 = (value) => {
21654
21814
  if (!isRecord2(value))
21655
21815
  return false;
@@ -21657,14 +21817,12 @@ var isStateJsonV1 = (value) => {
21657
21817
  return false;
21658
21818
  if (value.dateCursor != null && typeof value.dateCursor !== "string")
21659
21819
  return false;
21660
- if (value.lastSeqByChatId != null) {
21661
- if (!isRecord2(value.lastSeqByChatId))
21662
- return false;
21663
- for (const v of Object.values(value.lastSeqByChatId)) {
21664
- if (typeof v !== "number" || !Number.isFinite(v))
21665
- return false;
21666
- }
21667
- }
21820
+ if (value.lastSeqByChatId != null && !isSeqRecord(value.lastSeqByChatId))
21821
+ return false;
21822
+ if (value.lastSeqBySpaceId != null && !isSeqRecord(value.lastSeqBySpaceId))
21823
+ return false;
21824
+ if (value.lastUserSeq != null && (typeof value.lastUserSeq !== "number" || !Number.isFinite(value.lastUserSeq)))
21825
+ return false;
21668
21826
  return true;
21669
21827
  };
21670
21828
 
@@ -37570,6 +37728,7 @@ var INLINE_FORMATTING_RULES = [
37570
37728
  "Prefer bullet lists over markdown tables.",
37571
37729
  "If a table is necessary, render it inside a fenced code block.",
37572
37730
  "Use plain URLs or markdown links; do not wrap bare URLs in inline code or backticks.",
37731
+ "Mention Inline users with markdown links like [@FirstName](inline://user?id=123); use inline://user?username=username only when the user id is unavailable.",
37573
37732
  "Use inline code only for actual code, commands, file paths, env vars, or identifiers."
37574
37733
  ];
37575
37734
  var INLINE_COPY_REPLACEMENTS = [
@@ -37759,6 +37918,7 @@ function keysForLookup(params) {
37759
37918
  const keys = new Set;
37760
37919
  if (params.parentMessageId) {
37761
37920
  keys.add(messageKey(params.accountId, params.parentChatId, params.parentMessageId));
37921
+ return [...keys];
37762
37922
  }
37763
37923
  if (params.agentId) {
37764
37924
  keys.add(activeKey(params.accountId, params.parentChatId, params.agentId));
@@ -40826,6 +40986,40 @@ function buildInlineTypingDispatcherOptions(typingCallbacks) {
40826
40986
  ...typingCallbacks.onCleanup ? { onCleanup: typingCallbacks.onCleanup } : {}
40827
40987
  };
40828
40988
  }
40989
+ function uniqueInlineChatIds(chatIds) {
40990
+ const seen = new Set;
40991
+ const out = [];
40992
+ for (const chatId of chatIds) {
40993
+ if (chatId == null)
40994
+ continue;
40995
+ const key = String(chatId);
40996
+ if (seen.has(key))
40997
+ continue;
40998
+ seen.add(key);
40999
+ out.push(chatId);
41000
+ }
41001
+ return out;
41002
+ }
41003
+ async function sendInlineTypingToChats(params) {
41004
+ if (params.chatIds.length === 0)
41005
+ return;
41006
+ const failures = [];
41007
+ await Promise.all(params.chatIds.map(async (chatId) => {
41008
+ try {
41009
+ await params.client.sendTyping({ chatId, typing: params.typing });
41010
+ } catch (error51) {
41011
+ failures.push({ chatId, error: error51 });
41012
+ }
41013
+ }));
41014
+ if (failures.length === 0)
41015
+ return;
41016
+ if (failures.length === params.chatIds.length) {
41017
+ throw failures[0]?.error ?? new Error("inline typing failed");
41018
+ }
41019
+ for (const failure of failures) {
41020
+ params.onPartialError?.(failure.chatId, failure.error);
41021
+ }
41022
+ }
40829
41023
  function buildInlineReplyThreadSessionKey(parentSessionKey, threadChatId) {
40830
41024
  const suffix = `:thread:${String(threadChatId)}`;
40831
41025
  return parentSessionKey.endsWith(suffix) ? parentSessionKey : `${parentSessionKey}${suffix}`;
@@ -42644,6 +42838,7 @@ async function monitorInlineProvider(params) {
42644
42838
  statusSink?.({ lastError: `getChat failed: ${String(err)}` });
42645
42839
  }
42646
42840
  const isGroup = chatInfo.kind !== "direct";
42841
+ const inlineThreadDefaults = cfg.channels?.inline ?? {};
42647
42842
  const replyThreadsEnabled = isInlineReplyThreadsEnabled({ cfg, accountId: account.accountId });
42648
42843
  const replyThreadContext = await resolveInlineInboundReplyThreadContext({
42649
42844
  replyThreadsEnabled,
@@ -42661,25 +42856,25 @@ async function monitorInlineProvider(params) {
42661
42856
  cfg,
42662
42857
  accountId: account.accountId,
42663
42858
  groupId: String(effectiveChatId),
42664
- defaultMode: normalizeInlineReplyThreadMode(account.config.replyThreadMode)
42859
+ defaultMode: normalizeInlineReplyThreadMode(account.config.replyThreadMode ?? inlineThreadDefaults.replyThreadMode)
42665
42860
  }) : "auto";
42666
42861
  const replyThreadAutoCreateMinMessages = isGroup && replyThreadsEnabled ? resolveInlineGroupReplyThreadAutoCreateMinMessages({
42667
42862
  cfg,
42668
42863
  accountId: account.accountId,
42669
42864
  groupId: String(effectiveChatId),
42670
- defaultMinMessages: account.config.replyThreadAutoCreateMinMessages ?? DEFAULT_REPLY_THREAD_AUTO_CREATE_MIN_MESSAGES
42865
+ defaultMinMessages: account.config.replyThreadAutoCreateMinMessages ?? inlineThreadDefaults.replyThreadAutoCreateMinMessages ?? DEFAULT_REPLY_THREAD_AUTO_CREATE_MIN_MESSAGES
42671
42866
  }) : DEFAULT_REPLY_THREAD_AUTO_CREATE_MIN_MESSAGES;
42672
42867
  const replyThreadRequireExplicitMention = isGroup && replyThreadsEnabled ? resolveInlineGroupReplyThreadRequireExplicitMention({
42673
42868
  cfg,
42674
42869
  accountId: account.accountId,
42675
42870
  groupId: String(effectiveChatId),
42676
- defaultRequireExplicitMention: account.config.replyThreadRequireExplicitMention ?? false
42871
+ defaultRequireExplicitMention: account.config.replyThreadRequireExplicitMention ?? inlineThreadDefaults.replyThreadRequireExplicitMention ?? false
42677
42872
  }) : false;
42678
42873
  const replyThreadParentHistoryLimit = isGroup && replyThreadsEnabled ? resolveInlineGroupReplyThreadParentHistoryLimit({
42679
42874
  cfg,
42680
42875
  accountId: account.accountId,
42681
42876
  groupId: String(effectiveChatId),
42682
- defaultLimit: account.config.replyThreadParentHistoryLimit ?? DEFAULT_REPLY_THREAD_PARENT_HISTORY_LIMIT
42877
+ defaultLimit: account.config.replyThreadParentHistoryLimit ?? inlineThreadDefaults.replyThreadParentHistoryLimit ?? DEFAULT_REPLY_THREAD_PARENT_HISTORY_LIMIT
42683
42878
  }) : DEFAULT_REPLY_THREAD_PARENT_HISTORY_LIMIT;
42684
42879
  const senderId = String(msg.fromId);
42685
42880
  await hydrateChatParticipants(chatId);
@@ -42763,14 +42958,15 @@ async function monitorInlineProvider(params) {
42763
42958
  replyThreadContext: params2.replyThreadContext ?? null
42764
42959
  });
42765
42960
  };
42766
- const nativeCallbackCommandBody = callbackActionEvent ? parseInlineNativeCommandCallbackData(callbackDataToUtf8(callbackActionEvent.data)) : null;
42767
- const hasControlCommand = core3.channel.text.hasControlCommand(callbackCommandBody ?? rawBody, cfg, botUsername ? { botUsername } : undefined);
42768
- const commandSource = hasControlCommand ? (nativeCallbackCommandBody != null || !callbackActionEvent) && isInlineNativeCommandBody({
42961
+ const hasTextControlCommand = core3.channel.text.hasControlCommand(callbackCommandBody ?? rawBody, cfg, botUsername ? { botUsername } : undefined);
42962
+ const isRegisteredNativeCommand = isInlineNativeCommandBody({
42769
42963
  cfg,
42770
42964
  account,
42771
42965
  commandBody: normalizedCommandBody,
42772
42966
  agentId: route.agentId
42773
- }) ? "native" : "text" : undefined;
42967
+ });
42968
+ const hasControlCommand = hasTextControlCommand || isRegisteredNativeCommand;
42969
+ const commandSource = hasControlCommand ? isRegisteredNativeCommand ? "native" : "text" : undefined;
42774
42970
  const allowTextCommands = core3.channel.commands.shouldHandleTextCommands({
42775
42971
  cfg,
42776
42972
  surface: CHANNEL_ID,
@@ -43183,7 +43379,15 @@ This model will be used for your next message.`, []);
43183
43379
  messageId: msg.id,
43184
43380
  minMessages: replyThreadAutoCreateMinMessages
43185
43381
  }) && !shouldEditCallbackTargetInPlace;
43382
+ let parentThreadCreationTyping = false;
43383
+ const setParentThreadCreationTyping = async (typing) => {
43384
+ if (!shouldCreateDeliveryThread || parentThreadCreationTyping === typing)
43385
+ return;
43386
+ parentThreadCreationTyping = typing;
43387
+ await client.sendTyping({ chatId: effectiveChatId, typing }).catch((error51) => runtime.error?.(`inline parent reply-thread typing failed: ${String(error51)}`));
43388
+ };
43186
43389
  if (shouldCreateDeliveryThread) {
43390
+ await setParentThreadCreationTyping(true);
43187
43391
  const cachedRoute = await lookupInlineReplyThreadRoute({
43188
43392
  accountId: account.accountId,
43189
43393
  parentChatId: effectiveChatId,
@@ -43259,6 +43463,7 @@ This model will be used for your next message.`, []);
43259
43463
  if (shouldCreateDeliveryThread && !deliveryReplyThreadContext) {
43260
43464
  runtime.error?.("inline create reply thread failed; falling back to parent chat delivery");
43261
43465
  }
43466
+ await setParentThreadCreationTyping(false);
43262
43467
  if (!replyThreadContext && deliveryReplyThreadContext?.anchorMessage != null) {
43263
43468
  effectiveHistoryContext = prependInlineReplyThreadAnchor({
43264
43469
  historyContext: {
@@ -43296,6 +43501,10 @@ This model will be used for your next message.`, []);
43296
43501
  }
43297
43502
  }
43298
43503
  const deliveryChatId = deliveryReplyThreadContext?.childChatId ?? chatId;
43504
+ const typingChatIds = uniqueInlineChatIds([
43505
+ deliveryChatId,
43506
+ !replyThreadContext && deliveryReplyThreadContext ? deliveryReplyThreadContext.parentChatId : null
43507
+ ]);
43299
43508
  const deliverySessionKey = deliveryReplyThreadContext && isGroup ? buildInlineReplyThreadSessionKey(route.sessionKey, deliveryReplyThreadContext.childChatId) : route.sessionKey;
43300
43509
  const groupHistoryKey = isGroup ? deliveryReplyThreadContext ? deliverySessionKey : route.sessionKey : null;
43301
43510
  const inboundMedia = await resolveInlineInboundMedia({
@@ -43433,8 +43642,18 @@ This model will be used for your next message.`, []);
43433
43642
  channel: CHANNEL_ID,
43434
43643
  accountId: account.accountId,
43435
43644
  typing: {
43436
- start: () => client.sendTyping({ chatId: deliveryChatId, typing: true }),
43437
- stop: () => client.sendTyping({ chatId: deliveryChatId, typing: false }),
43645
+ start: () => sendInlineTypingToChats({
43646
+ client,
43647
+ chatIds: typingChatIds,
43648
+ typing: true,
43649
+ onPartialError: (chatId2, error51) => runtime.error?.(`inline typing start failed for chat ${String(chatId2)}: ${String(error51)}`)
43650
+ }),
43651
+ stop: () => sendInlineTypingToChats({
43652
+ client,
43653
+ chatIds: typingChatIds,
43654
+ typing: false,
43655
+ onPartialError: (chatId2, error51) => runtime.error?.(`inline typing stop failed for chat ${String(chatId2)}: ${String(error51)}`)
43656
+ }),
43438
43657
  onStartError: (err) => runtime.error?.(`inline typing start failed: ${String(err)}`),
43439
43658
  onStopError: (err) => runtime.error?.(`inline typing stop failed: ${String(err)}`)
43440
43659
  }
@@ -43977,6 +44196,7 @@ Attachment: ${mediaUrl}` : `Attachment: ${mediaUrl}`;
43977
44196
  statusSink?.({ lastOutboundAt: Date.now() });
43978
44197
  }
43979
44198
  } finally {
44199
+ await setParentThreadCreationTyping(false);
43980
44200
  if (callbackActionEvent && !callbackActionAnswered) {
43981
44201
  try {
43982
44202
  await answerCallbackIfNeeded();
@@ -46482,8 +46702,9 @@ var inlineChannelPlugin = {
46482
46702
  "- Inline history tools: `read` and `search` return media-aware message payloads (`media`, `attachments`, `attachmentUrls`) so image-only history remains discoverable. `search` is chat-scoped; run it per chat.",
46483
46703
  "- Inline special tools: use `inline_nudge` to send a nudge, and `inline_forward` to forward message ids between chats or users.",
46484
46704
  "- Inline reply threads: use normal `reply` for short or newly started parent-chat conversations unless the user asks for a thread.",
46485
- "- Inline reply threads: use `thread-create` to create or reuse a real reply thread under the current/target chat. On inbound turns, omit `messageId` to anchor it to the current message, or pass `messageId`/`parentMessageId` explicitly.",
46486
- "- Inline reply threads: use `thread-reply` to send into a real reply thread, with `threadId` set to the reply-thread chat id returned by `thread-create`. Reuse that `threadId`; do not create one thread per message.",
46705
+ "- Inline reply threads: use `thread-create` to create or reuse a real reply thread under the current/target chat. On parent-chat inbound turns, omit `messageId` to anchor it to the current message, or pass `messageId`/`parentMessageId` explicitly.",
46706
+ "- Inline reply threads: use `thread-reply` to send into a real reply thread, with `threadId` set to the reply-thread chat id returned by `thread-create`. Reuse that `threadId` only for the same reply-thread session; unrelated parent-chat messages need separate parent-message anchors.",
46707
+ "- Inline reply threads: when already inside a reply-thread chat, continue in that reply thread and do not create nested reply threads.",
46487
46708
  "- Inline reply-thread turns include nearby parent-chat context by default. If that context is incomplete, call `inline_parent_context` before answering."
46488
46709
  ]
46489
46710
  },
@@ -46847,5 +47068,5 @@ export {
46847
47068
  inlineChannelPlugin
46848
47069
  };
46849
47070
 
46850
- //# debugId=A439BD5C99EA226864756E2164756E21
47071
+ //# debugId=FEB3F6CD06C6A7CC64756E2164756E21
46851
47072
  //# sourceMappingURL=channel-plugin-api.js.map