@letta-ai/letta-code 0.28.7 → 0.28.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/letta.js CHANGED
@@ -4853,7 +4853,7 @@ var package_default;
4853
4853
  var init_package = __esm(() => {
4854
4854
  package_default = {
4855
4855
  name: "@letta-ai/letta-code",
4856
- version: "0.28.7",
4856
+ version: "0.28.8",
4857
4857
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
4858
4858
  type: "module",
4859
4859
  packageManager: "bun@1.3.0",
@@ -159689,6 +159689,85 @@ var init_models7 = __esm(() => {
159689
159689
  parallel_tool_calls: true
159690
159690
  }
159691
159691
  },
159692
+ {
159693
+ id: "gpt-5.6-luna-plus-pro-none",
159694
+ handle: "chatgpt-plus-pro/gpt-5.6-luna",
159695
+ label: "GPT-5.6 Luna (ChatGPT)",
159696
+ description: "GPT-5.6 Luna (no reasoning) via ChatGPT Plus/Pro",
159697
+ updateArgs: {
159698
+ reasoning_effort: "none",
159699
+ verbosity: "low",
159700
+ context_window: 272000,
159701
+ max_output_tokens: 128000,
159702
+ parallel_tool_calls: true
159703
+ }
159704
+ },
159705
+ {
159706
+ id: "gpt-5.6-luna-plus-pro-low",
159707
+ handle: "chatgpt-plus-pro/gpt-5.6-luna",
159708
+ label: "GPT-5.6 Luna (ChatGPT)",
159709
+ description: "GPT-5.6 Luna (low reasoning) via ChatGPT Plus/Pro",
159710
+ updateArgs: {
159711
+ reasoning_effort: "low",
159712
+ verbosity: "low",
159713
+ context_window: 272000,
159714
+ max_output_tokens: 128000,
159715
+ parallel_tool_calls: true
159716
+ }
159717
+ },
159718
+ {
159719
+ id: "gpt-5.6-luna-plus-pro-medium",
159720
+ handle: "chatgpt-plus-pro/gpt-5.6-luna",
159721
+ label: "GPT-5.6 Luna (ChatGPT)",
159722
+ description: "GPT-5.6 Luna (med reasoning) via ChatGPT Plus/Pro",
159723
+ updateArgs: {
159724
+ reasoning_effort: "medium",
159725
+ verbosity: "low",
159726
+ context_window: 272000,
159727
+ max_output_tokens: 128000,
159728
+ parallel_tool_calls: true
159729
+ }
159730
+ },
159731
+ {
159732
+ id: "gpt-5.6-luna-plus-pro-high",
159733
+ handle: "chatgpt-plus-pro/gpt-5.6-luna",
159734
+ label: "GPT-5.6 Luna (ChatGPT)",
159735
+ description: "GPT-5.6 Luna (high reasoning) via ChatGPT Plus/Pro",
159736
+ updateArgs: {
159737
+ reasoning_effort: "high",
159738
+ verbosity: "low",
159739
+ context_window: 272000,
159740
+ max_output_tokens: 128000,
159741
+ parallel_tool_calls: true
159742
+ },
159743
+ isFeatured: true
159744
+ },
159745
+ {
159746
+ id: "gpt-5.6-luna-plus-pro-xhigh",
159747
+ handle: "chatgpt-plus-pro/gpt-5.6-luna",
159748
+ label: "GPT-5.6 Luna (ChatGPT)",
159749
+ description: "GPT-5.6 Luna (extra-high reasoning) via ChatGPT Plus/Pro",
159750
+ updateArgs: {
159751
+ reasoning_effort: "xhigh",
159752
+ verbosity: "low",
159753
+ context_window: 272000,
159754
+ max_output_tokens: 128000,
159755
+ parallel_tool_calls: true
159756
+ }
159757
+ },
159758
+ {
159759
+ id: "gpt-5.6-luna-plus-pro-max",
159760
+ handle: "chatgpt-plus-pro/gpt-5.6-luna",
159761
+ label: "GPT-5.6 Luna (ChatGPT)",
159762
+ description: "GPT-5.6 Luna (max reasoning) via ChatGPT Plus/Pro",
159763
+ updateArgs: {
159764
+ reasoning_effort: "max",
159765
+ verbosity: "low",
159766
+ context_window: 272000,
159767
+ max_output_tokens: 128000,
159768
+ parallel_tool_calls: true
159769
+ }
159770
+ },
159692
159771
  {
159693
159772
  id: "fable",
159694
159773
  handle: "anthropic/claude-fable-5",
@@ -162195,6 +162274,44 @@ var init_mode = __esm(() => {
162195
162274
  permissionMode = new PermissionModeManager;
162196
162275
  });
162197
162276
 
162277
+ // src/channels/slack/bot-policy.ts
162278
+ function isValidSlackAllowBotsConfigValue(value) {
162279
+ return value === undefined || value === false || value === "mentions";
162280
+ }
162281
+ function normalizeSlackAllowBotsMode(value) {
162282
+ if (value === "mentions")
162283
+ return "mentions";
162284
+ return false;
162285
+ }
162286
+ function resolveSlackAllowBotsMode(value) {
162287
+ if (value === "mentions")
162288
+ return "mentions";
162289
+ return "off";
162290
+ }
162291
+ function isNonEmptyString(value) {
162292
+ return typeof value === "string" && value.length > 0;
162293
+ }
162294
+ function isSlackBotAuthoredInboundMessage(message) {
162295
+ return isNonEmptyString(message.bot_id) || message.subtype === "bot_message";
162296
+ }
162297
+ function isOwnSlackBotInboundMessage(params) {
162298
+ return isNonEmptyString(params.botUserId) && params.message.user === params.botUserId || isNonEmptyString(params.botId) && params.message.bot_id === params.botId;
162299
+ }
162300
+ function shouldAcceptSlackInboundBotMessage(params) {
162301
+ if (isOwnSlackBotInboundMessage({
162302
+ message: params.message,
162303
+ botUserId: params.botUserId,
162304
+ botId: params.botId
162305
+ })) {
162306
+ return false;
162307
+ }
162308
+ if (!isSlackBotAuthoredInboundMessage(params.message)) {
162309
+ return true;
162310
+ }
162311
+ const mode = resolveSlackAllowBotsMode(params.allowBots);
162312
+ return mode === "mentions" && params.wasMentioned;
162313
+ }
162314
+
162198
162315
  // src/channels/config.ts
162199
162316
  import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
162200
162317
  import { homedir as homedir5 } from "node:os";
@@ -162337,7 +162454,8 @@ var init_config2 = __esm(() => {
162337
162454
  dmPolicy: parsed.dm_policy ?? "pairing",
162338
162455
  allowedUsers: parsed.allowed_users ?? [],
162339
162456
  transcribeVoice: parsed.transcribe_voice === true,
162340
- listenMode: parsed.listen_mode === true
162457
+ listenMode: parsed.listen_mode === true,
162458
+ allowBots: normalizeSlackAllowBotsMode(parsed.allow_bots)
162341
162459
  };
162342
162460
  }
162343
162461
  };
@@ -162591,7 +162709,7 @@ var init_plugin = __esm(() => {
162591
162709
  });
162592
162710
 
162593
162711
  // src/channels/schema-config.ts
162594
- function isNonEmptyString(value) {
162712
+ function isNonEmptyString2(value) {
162595
162713
  return typeof value === "string" && value.length > 0;
162596
162714
  }
162597
162715
  function parseSelectOptions(value) {
@@ -162604,7 +162722,7 @@ function parseSelectOptions(value) {
162604
162722
  if (!isRecord(entry)) {
162605
162723
  return null;
162606
162724
  }
162607
- if (!isNonEmptyString(entry.value) || !isNonEmptyString(entry.label)) {
162725
+ if (!isNonEmptyString2(entry.value) || !isNonEmptyString2(entry.label)) {
162608
162726
  return null;
162609
162727
  }
162610
162728
  if (seen.has(entry.value)) {
@@ -162623,10 +162741,10 @@ function parseField(value) {
162623
162741
  if (typeof type3 !== "string" || !FIELD_TYPES.has(type3)) {
162624
162742
  return null;
162625
162743
  }
162626
- if (!isNonEmptyString(value.key) || !FIELD_KEY_PATTERN.test(value.key)) {
162744
+ if (!isNonEmptyString2(value.key) || !FIELD_KEY_PATTERN.test(value.key)) {
162627
162745
  return null;
162628
162746
  }
162629
- if (!isNonEmptyString(value.label)) {
162747
+ if (!isNonEmptyString2(value.label)) {
162630
162748
  return null;
162631
162749
  }
162632
162750
  if (value.description !== undefined && typeof value.description !== "string") {
@@ -166094,6 +166212,7 @@ function normalizeLoadedAccount(account) {
166094
166212
  delete next.progress_ui;
166095
166213
  delete next.progressUi;
166096
166214
  next.listenMode = next.listenMode === true;
166215
+ next.allowBots = normalizeSlackAllowBotsMode(next.allowBots);
166097
166216
  }
166098
166217
  if (isDiscordChannelAccount(next)) {
166099
166218
  const migrated = migratePermissionMode(next.defaultPermissionMode ?? "standard");
@@ -166220,6 +166339,7 @@ function makeDefaultLegacyAccount(channelId) {
166220
166339
  defaultPermissionMode: DEFAULT_SLACK_PERMISSION_MODE,
166221
166340
  transcribeVoice: config3.transcribeVoice === true,
166222
166341
  listenMode: config3.listenMode === true,
166342
+ allowBots: config3.allowBots ?? false,
166223
166343
  createdAt: now,
166224
166344
  updatedAt: now
166225
166345
  };
@@ -166407,6 +166527,7 @@ var init_accounts = __esm(() => {
166407
166527
  account_uuid: "accountUuid",
166408
166528
  allowed_channels: "allowedChannels",
166409
166529
  allowed_groups: "allowedGroups",
166530
+ allow_bots: "allowBots",
166410
166531
  auto_thread_on_mention: "autoThreadOnMention",
166411
166532
  base_url: "baseUrl",
166412
166533
  acknowledge_message_reaction: "acknowledgeMessageReaction",
@@ -166708,11 +166829,11 @@ function resolveSlackAppConstructor(mod) {
166708
166829
  }
166709
166830
  return App;
166710
166831
  }
166711
- function isNonEmptyString2(value) {
166832
+ function isNonEmptyString3(value) {
166712
166833
  return typeof value === "string" && value.length > 0;
166713
166834
  }
166714
166835
  function firstNonEmptyString(...values2) {
166715
- return values2.find(isNonEmptyString2);
166836
+ return values2.find(isNonEmptyString3);
166716
166837
  }
166717
166838
  function asRecord2(value) {
166718
166839
  return value && typeof value === "object" ? value : null;
@@ -166725,10 +166846,10 @@ function normalizeSlackText(text) {
166725
166846
  return text.replace(/^(?:\s*<@[A-Z0-9]+>\s*)+/, "").trim();
166726
166847
  }
166727
166848
  function isProcessableSlackInboundMessage(rawMessage) {
166728
- if (isNonEmptyString2(rawMessage.bot_id) || !isNonEmptyString2(rawMessage.user) || !isNonEmptyString2(rawMessage.ts) || rawMessage.hidden === true) {
166849
+ if (!isNonEmptyString3(rawMessage.user) && !isNonEmptyString3(rawMessage.bot_id) || !isNonEmptyString3(rawMessage.ts) || rawMessage.hidden === true) {
166729
166850
  return false;
166730
166851
  }
166731
- const subtype = isNonEmptyString2(rawMessage.subtype) ? rawMessage.subtype : null;
166852
+ const subtype = isNonEmptyString3(rawMessage.subtype) ? rawMessage.subtype : null;
166732
166853
  if (!subtype) {
166733
166854
  return true;
166734
166855
  }
@@ -166812,16 +166933,15 @@ function resolveSlackUserDisplayName(userInfo) {
166812
166933
  return firstNonEmptyString(profile?.display_name, profile?.real_name, user?.name);
166813
166934
  }
166814
166935
  function hasSlackMention(text, userId) {
166815
- return isNonEmptyString2(text) && isNonEmptyString2(userId) && (text.includes(`<@${userId}>`) || text.includes(`<@${userId}|`));
166936
+ return isNonEmptyString3(text) && isNonEmptyString3(userId) && (text.includes(`<@${userId}>`) || text.includes(`<@${userId}|`));
166816
166937
  }
166817
166938
  function isSlackFlatChannelThreadOpener(source2) {
166818
- return source2.chatType === "channel" && isNonEmptyString2(source2.messageId) && (!isNonEmptyString2(source2.threadId) || source2.threadId === source2.messageId);
166939
+ return source2.chatType === "channel" && isNonEmptyString3(source2.messageId) && (!isNonEmptyString3(source2.threadId) || source2.threadId === source2.messageId);
166819
166940
  }
166820
166941
  var IGNORED_SLACK_MESSAGE_SUBTYPES, WRAPPER_SLACK_MESSAGE_SUBTYPES;
166821
166942
  var init_utils5 = __esm(() => {
166822
166943
  IGNORED_SLACK_MESSAGE_SUBTYPES = new Set([
166823
166944
  "assistant_app_thread",
166824
- "bot_message",
166825
166945
  "channel_archive",
166826
166946
  "channel_convert_to_private",
166827
166947
  "channel_convert_to_public",
@@ -166863,7 +166983,7 @@ async function resolveSlackAccountDisplayName(botToken, appToken) {
166863
166983
  socketMode: true
166864
166984
  });
166865
166985
  const auth = await app.client.auth.test({ token: botToken });
166866
- if (isNonEmptyString2(auth.user_id)) {
166986
+ if (isNonEmptyString3(auth.user_id)) {
166867
166987
  try {
166868
166988
  const userInfo = await app.client.users.info({
166869
166989
  token: botToken,
@@ -166875,7 +166995,7 @@ async function resolveSlackAccountDisplayName(botToken, appToken) {
166875
166995
  }
166876
166996
  } catch {}
166877
166997
  }
166878
- return isNonEmptyString2(auth.user) ? auth.user : undefined;
166998
+ return isNonEmptyString3(auth.user) ? auth.user : undefined;
166879
166999
  }
166880
167000
  var init_account_display2 = __esm(() => {
166881
167001
  init_runtime2();
@@ -168247,10 +168367,10 @@ function formatSlackToolNameForDisplay(toolName) {
168247
168367
  return isTaskTool(toolName) ? "Subagent" : getDisplayToolName(toolName);
168248
168368
  }
168249
168369
  function resolveSlackConcreteActivity(event2) {
168250
- if (event2.kind === "command" && isNonEmptyString2(event2.command)) {
168370
+ if (event2.kind === "command" && isNonEmptyString3(event2.command)) {
168251
168371
  return sanitizeSlackStatusText(formatSlackToolNameForDisplay(event2.command), SLACK_STATUS_TEXT_MAX);
168252
168372
  }
168253
- if (event2.kind !== "tool" || !isNonEmptyString2(event2.toolName) || event2.toolName.toLowerCase() === "messagechannel") {
168373
+ if (event2.kind !== "tool" || !isNonEmptyString3(event2.toolName) || event2.toolName.toLowerCase() === "messagechannel") {
168254
168374
  return null;
168255
168375
  }
168256
168376
  for (const description of [
@@ -168259,7 +168379,7 @@ function resolveSlackConcreteActivity(event2) {
168259
168379
  isShellTool(event2.toolName) ? event2.message : undefined,
168260
168380
  formatSlackToolNameForDisplay(event2.toolName)
168261
168381
  ]) {
168262
- if (!isNonEmptyString2(description)) {
168382
+ if (!isNonEmptyString3(description)) {
168263
168383
  continue;
168264
168384
  }
168265
168385
  const sanitized = sanitizeSlackStatusText(description, SLACK_STATUS_TEXT_MAX);
@@ -168311,12 +168431,12 @@ Run \`${toolName}\`?`
168311
168431
  ];
168312
168432
  }
168313
168433
  function parseSlackApprovalActionPayload(value) {
168314
- if (!isNonEmptyString2(value)) {
168434
+ if (!isNonEmptyString3(value)) {
168315
168435
  return null;
168316
168436
  }
168317
168437
  try {
168318
168438
  const parsed = JSON.parse(value);
168319
- if (!isNonEmptyString2(parsed.requestId) || parsed.decision !== "allow" && parsed.decision !== "deny") {
168439
+ if (!isNonEmptyString3(parsed.requestId) || parsed.decision !== "allow" && parsed.decision !== "deny") {
168320
168440
  return null;
168321
168441
  }
168322
168442
  return { requestId: parsed.requestId, decision: parsed.decision };
@@ -168513,16 +168633,16 @@ async function mapSlackThreadMessage(message, attachmentOptions, sourceThreadId)
168513
168633
  const attachments = await resolveSlackMessageAttachments(message, attachmentOptions, sourceThreadId);
168514
168634
  return {
168515
168635
  text: resolveSlackThreadMessageText(message),
168516
- userId: isNonEmptyString3(message.user) ? message.user : undefined,
168517
- botId: isNonEmptyString3(message.bot_id) ? message.bot_id : undefined,
168518
- ts: isNonEmptyString3(message.ts) ? message.ts : undefined,
168636
+ userId: isNonEmptyString4(message.user) ? message.user : undefined,
168637
+ botId: isNonEmptyString4(message.bot_id) ? message.bot_id : undefined,
168638
+ ts: isNonEmptyString4(message.ts) ? message.ts : undefined,
168519
168639
  ...attachments.length > 0 ? { attachments } : {}
168520
168640
  };
168521
168641
  }
168522
168642
  function asRecord4(value) {
168523
168643
  return value && typeof value === "object" ? value : null;
168524
168644
  }
168525
- function isNonEmptyString3(value) {
168645
+ function isNonEmptyString4(value) {
168526
168646
  return typeof value === "string" && value.trim().length > 0;
168527
168647
  }
168528
168648
  function normalizeSlackFileLike(value) {
@@ -168531,12 +168651,12 @@ function normalizeSlackFileLike(value) {
168531
168651
  return null;
168532
168652
  }
168533
168653
  return {
168534
- id: isNonEmptyString3(record5.id) ? record5.id : undefined,
168535
- name: isNonEmptyString3(record5.name) ? record5.name : undefined,
168536
- mimetype: isNonEmptyString3(record5.mimetype) ? record5.mimetype : undefined,
168654
+ id: isNonEmptyString4(record5.id) ? record5.id : undefined,
168655
+ name: isNonEmptyString4(record5.name) ? record5.name : undefined,
168656
+ mimetype: isNonEmptyString4(record5.mimetype) ? record5.mimetype : undefined,
168537
168657
  size: typeof record5.size === "number" ? record5.size : undefined,
168538
- url_private: isNonEmptyString3(record5.url_private) ? record5.url_private : undefined,
168539
- url_private_download: isNonEmptyString3(record5.url_private_download) ? record5.url_private_download : undefined
168658
+ url_private: isNonEmptyString4(record5.url_private) ? record5.url_private : undefined,
168659
+ url_private_download: isNonEmptyString4(record5.url_private_download) ? record5.url_private_download : undefined
168540
168660
  };
168541
168661
  }
168542
168662
  function normalizeSlackAttachmentLike(value) {
@@ -168546,12 +168666,12 @@ function normalizeSlackAttachmentLike(value) {
168546
168666
  }
168547
168667
  const files = Array.isArray(record5.files) ? record5.files.map((entry) => normalizeSlackFileLike(entry)).filter((entry) => Boolean(entry)) : undefined;
168548
168668
  return {
168549
- text: isNonEmptyString3(record5.text) ? record5.text : undefined,
168550
- fallback: isNonEmptyString3(record5.fallback) ? record5.fallback : undefined,
168551
- pretext: isNonEmptyString3(record5.pretext) ? record5.pretext : undefined,
168552
- author_name: isNonEmptyString3(record5.author_name) ? record5.author_name : undefined,
168553
- title: isNonEmptyString3(record5.title) ? record5.title : undefined,
168554
- image_url: isNonEmptyString3(record5.image_url) ? record5.image_url : undefined,
168669
+ text: isNonEmptyString4(record5.text) ? record5.text : undefined,
168670
+ fallback: isNonEmptyString4(record5.fallback) ? record5.fallback : undefined,
168671
+ pretext: isNonEmptyString4(record5.pretext) ? record5.pretext : undefined,
168672
+ author_name: isNonEmptyString4(record5.author_name) ? record5.author_name : undefined,
168673
+ title: isNonEmptyString4(record5.title) ? record5.title : undefined,
168674
+ image_url: isNonEmptyString4(record5.image_url) ? record5.image_url : undefined,
168555
168675
  files
168556
168676
  };
168557
168677
  }
@@ -168584,7 +168704,7 @@ function resolveSlackThreadMessageText(message) {
168584
168704
  if (text) {
168585
168705
  return text;
168586
168706
  }
168587
- const attachmentTexts = Array.isArray(message.attachments) ? message.attachments.map((entry) => normalizeSlackAttachmentLike(entry)).filter((entry) => Boolean(entry)).map((attachment) => resolveSlackAttachmentText(attachment)).filter(isNonEmptyString3) : [];
168707
+ const attachmentTexts = Array.isArray(message.attachments) ? message.attachments.map((entry) => normalizeSlackAttachmentLike(entry)).filter((entry) => Boolean(entry)).map((attachment) => resolveSlackAttachmentText(attachment)).filter(isNonEmptyString4) : [];
168588
168708
  if (attachmentTexts.length > 0) {
168589
168709
  return attachmentTexts.join(`
168590
168710
 
@@ -168885,7 +169005,7 @@ async function resolveSlackFilesAsAttachments(params) {
168885
169005
  return resolved;
168886
169006
  }
168887
169007
  function resolveSlackThreadAttachmentOptions(params) {
168888
- if (!isNonEmptyString3(params.accountId) || !isNonEmptyString3(params.token)) {
169008
+ if (!isNonEmptyString4(params.accountId) || !isNonEmptyString4(params.token)) {
168889
169009
  return;
168890
169010
  }
168891
169011
  return {
@@ -168912,7 +169032,7 @@ async function resolveSlackMessageAttachments(message, attachmentOptions, source
168912
169032
  token: attachmentOptions.token,
168913
169033
  files: collectSlackFiles(message),
168914
169034
  sourceMessageId: message.ts,
168915
- sourceThreadId: sourceThreadId ?? (isNonEmptyString3(message.thread_ts) ? message.thread_ts : null),
169035
+ sourceThreadId: sourceThreadId ?? (isNonEmptyString4(message.thread_ts) ? message.thread_ts : null),
168916
169036
  transcribeVoice: attachmentOptions.transcribeVoice
168917
169037
  });
168918
169038
  }
@@ -168922,8 +169042,8 @@ async function resolveSlackInboundAttachments(params) {
168922
169042
  accountId: params.accountId,
168923
169043
  token: params.token,
168924
169044
  files: collectSlackFiles(params.rawEvent),
168925
- sourceMessageId: isNonEmptyString3(rawEvent?.ts) ? rawEvent.ts : undefined,
168926
- sourceThreadId: isNonEmptyString3(rawEvent?.thread_ts) ? rawEvent.thread_ts : null,
169045
+ sourceMessageId: isNonEmptyString4(rawEvent?.ts) ? rawEvent.ts : undefined,
169046
+ sourceThreadId: isNonEmptyString4(rawEvent?.thread_ts) ? rawEvent.thread_ts : null,
168927
169047
  transcribeVoice: params.transcribeVoice
168928
169048
  });
168929
169049
  }
@@ -168996,7 +169116,7 @@ async function resolveSlackThreadHistory(params) {
168996
169116
  ...cursor ? { cursor } : {}
168997
169117
  });
168998
169118
  for (const message of response.messages ?? []) {
168999
- if (params.include === "bot" && !isNonEmptyString3(message.bot_id)) {
169119
+ if (params.include === "bot" && !isNonEmptyString4(message.bot_id)) {
169000
169120
  continue;
169001
169121
  }
169002
169122
  if (!hasSlackThreadMessageContent(message, attachmentOptions)) {
@@ -169060,11 +169180,11 @@ var init_media2 = __esm(() => {
169060
169180
  });
169061
169181
 
169062
169182
  // src/channels/slack/attachment-download.ts
169063
- function isNonEmptyString4(value) {
169183
+ function isNonEmptyString5(value) {
169064
169184
  return typeof value === "string" && value.trim().length > 0;
169065
169185
  }
169066
169186
  async function resolveCanonicalSlackMessage(params) {
169067
- if (isNonEmptyString4(params.threadTs)) {
169187
+ if (isNonEmptyString5(params.threadTs)) {
169068
169188
  let cursor;
169069
169189
  do {
169070
169190
  const response2 = await params.client.conversations.replies({
@@ -169079,7 +169199,7 @@ async function resolveCanonicalSlackMessage(params) {
169079
169199
  return message;
169080
169200
  }
169081
169201
  const nextCursor = response2.response_metadata?.next_cursor;
169082
- cursor = isNonEmptyString4(nextCursor) ? nextCursor.trim() : undefined;
169202
+ cursor = isNonEmptyString5(nextCursor) ? nextCursor.trim() : undefined;
169083
169203
  } while (cursor);
169084
169204
  return null;
169085
169205
  }
@@ -169230,7 +169350,7 @@ function createSlackInboundDebounceController(params) {
169230
169350
  const deduped = [];
169231
169351
  for (const entry of entries) {
169232
169352
  const messageId = entry.inbound.messageId;
169233
- const messageKey = isNonEmptyString2(messageId) ? `${entry.inbound.chatId}:${messageId}` : null;
169353
+ const messageKey = isNonEmptyString3(messageId) ? `${entry.inbound.chatId}:${messageId}` : null;
169234
169354
  if (!messageKey) {
169235
169355
  deduped.push(entry);
169236
169356
  continue;
@@ -169265,7 +169385,7 @@ function createSlackInboundDebounceController(params) {
169265
169385
  if (pending?.size === 0)
169266
169386
  pendingTopLevelKeys.delete(conversationKey);
169267
169387
  }
169268
- if (isNonEmptyString2(last.inbound.messageId)) {
169388
+ if (isNonEmptyString3(last.inbound.messageId)) {
169269
169389
  const seenKey = `${last.inbound.chatId}:${last.inbound.messageId}`;
169270
169390
  pruneAppMentionMaps(Date.now());
169271
169391
  if (last.opts.source === "app_mention") {
@@ -169361,7 +169481,7 @@ function createSlackIngressController(params) {
169361
169481
  }
169362
169482
  }
169363
169483
  function markIngressMessageSeen(channelId, messageId) {
169364
- if (!isNonEmptyString2(channelId) || !isNonEmptyString2(messageId)) {
169484
+ if (!isNonEmptyString3(channelId) || !isNonEmptyString3(messageId)) {
169365
169485
  return false;
169366
169486
  }
169367
169487
  const key = `${channelId}:${messageId}`;
@@ -169372,12 +169492,12 @@ function createSlackIngressController(params) {
169372
169492
  return false;
169373
169493
  }
169374
169494
  function rememberMessageThread(messageId, threadId) {
169375
- if (isNonEmptyString2(messageId)) {
169495
+ if (isNonEmptyString3(messageId)) {
169376
169496
  knownThreadIdsByMessageId.set(messageId, threadId);
169377
169497
  }
169378
169498
  }
169379
169499
  async function resolveUserName(app, userId) {
169380
- if (!isNonEmptyString2(userId))
169500
+ if (!isNonEmptyString3(userId))
169381
169501
  return;
169382
169502
  const cached2 = knownUserDisplayNames.get(userId);
169383
169503
  if (cached2)
@@ -169392,6 +169512,21 @@ function createSlackIngressController(params) {
169392
169512
  knownUserDisplayNames.set(userId, userId);
169393
169513
  return userId;
169394
169514
  }
169515
+ async function resolveInboundSenderName(app, userId, botId) {
169516
+ if (isNonEmptyString3(userId)) {
169517
+ return resolveUserName(app, userId);
169518
+ }
169519
+ return isNonEmptyString3(botId) ? `Bot (${botId})` : undefined;
169520
+ }
169521
+ function shouldAcceptInboundMessageByBotPolicy(input) {
169522
+ return shouldAcceptSlackInboundBotMessage({
169523
+ message: input.message,
169524
+ allowBots: config3.allowBots,
169525
+ botUserId: params.getBotUserId(),
169526
+ botId: params.getBotId(),
169527
+ wasMentioned: input.wasMentioned
169528
+ });
169529
+ }
169395
169530
  async function dispatchInbound(inbound, raw, source2, wasMentioned, errorLabel) {
169396
169531
  try {
169397
169532
  await params.debounce.dispatch({
@@ -169409,11 +169544,20 @@ function createSlackIngressController(params) {
169409
169544
  return;
169410
169545
  const rawMessage = asRecord2(message);
169411
169546
  const channelId = rawMessage?.channel;
169412
- if (!rawMessage || !isNonEmptyString2(channelId) || !isProcessableSlackInboundMessage(rawMessage)) {
169547
+ if (!rawMessage || !isNonEmptyString3(channelId) || !isProcessableSlackInboundMessage(rawMessage)) {
169413
169548
  return;
169414
169549
  }
169415
- const text = isNonEmptyString2(rawMessage.text) ? rawMessage.text : "";
169550
+ const text = isNonEmptyString3(rawMessage.text) ? rawMessage.text : "";
169416
169551
  const wasMentioned = hasSlackMention(text, params.getBotUserId());
169552
+ if (!shouldAcceptInboundMessageByBotPolicy({
169553
+ message: rawMessage,
169554
+ wasMentioned
169555
+ })) {
169556
+ return;
169557
+ }
169558
+ const senderId = firstNonEmptyString(rawMessage.user, rawMessage.bot_id);
169559
+ if (!senderId)
169560
+ return;
169417
169561
  const attachments = await resolveSlackInboundAttachments({
169418
169562
  accountId: config3.accountId,
169419
169563
  token: config3.botToken,
@@ -169423,9 +169567,10 @@ function createSlackIngressController(params) {
169423
169567
  const chatType = resolveSlackChatType(channelId);
169424
169568
  const threadId = chatType === "direct" ? firstNonEmptyString(rawMessage.thread_ts) ?? null : firstNonEmptyString(rawMessage.thread_ts, rawMessage.ts) ?? null;
169425
169569
  rememberMessageThread(rawMessage.ts, threadId);
169426
- const senderName = await resolveUserName(app, rawMessage.user);
169427
- const isAgentThread = chatType === "channel" && isNonEmptyString2(threadId) && params.agentThreadTracker.has(channelId, threadId);
169428
- const effectiveMention = wasMentioned || isAgentThread;
169570
+ const senderName = await resolveInboundSenderName(app, rawMessage.user, rawMessage.bot_id);
169571
+ const isAgentThread = chatType === "channel" && isNonEmptyString3(threadId) && params.agentThreadTracker.has(channelId, threadId);
169572
+ const isBotAuthored = isSlackBotAuthoredInboundMessage(rawMessage);
169573
+ const effectiveMention = isBotAuthored ? wasMentioned : wasMentioned || isAgentThread;
169429
169574
  if (chatType === "direct") {
169430
169575
  const seenKey2 = `${channelId}:${rawMessage.ts}`;
169431
169576
  if (markIngressMessageSeen(channelId, rawMessage.ts))
@@ -169435,7 +169580,7 @@ function createSlackIngressController(params) {
169435
169580
  channel: "slack",
169436
169581
  accountId: config3.accountId,
169437
169582
  chatId: channelId,
169438
- senderId: rawMessage.user,
169583
+ senderId,
169439
169584
  senderTeamId: resolveSlackSenderTeamId(rawMessage),
169440
169585
  senderName,
169441
169586
  text: wasMentioned ? normalizeSlackText(text) : text,
@@ -169449,7 +169594,7 @@ function createSlackIngressController(params) {
169449
169594
  }, rawMessage, "message", wasMentioned, "DM message");
169450
169595
  return;
169451
169596
  }
169452
- if (!isNonEmptyString2(rawMessage.thread_ts))
169597
+ if (!isNonEmptyString3(rawMessage.thread_ts))
169453
169598
  return;
169454
169599
  const seenKey = `${channelId}:${rawMessage.ts}`;
169455
169600
  if (markIngressMessageSeen(channelId, rawMessage.ts))
@@ -169459,7 +169604,7 @@ function createSlackIngressController(params) {
169459
169604
  channel: "slack",
169460
169605
  accountId: config3.accountId,
169461
169606
  chatId: channelId,
169462
- senderId: rawMessage.user,
169607
+ senderId,
169463
169608
  senderTeamId: resolveSlackSenderTeamId(rawMessage),
169464
169609
  senderName,
169465
169610
  chatLabel: channelId,
@@ -169474,26 +169619,37 @@ function createSlackIngressController(params) {
169474
169619
  }, rawMessage, "message", effectiveMention, "threaded channel message");
169475
169620
  });
169476
169621
  app.event("app_mention", async ({ event: event2 }) => {
169477
- if (!params.getAdapter().onMessage || !isNonEmptyString2(event2.channel) || !isNonEmptyString2(event2.user) || !isNonEmptyString2(event2.ts)) {
169622
+ const rawEvent = asRecord2(event2);
169623
+ const channelId = rawEvent?.channel;
169624
+ const ts = rawEvent?.ts;
169625
+ const senderId = firstNonEmptyString(rawEvent?.user, rawEvent?.bot_id);
169626
+ if (!params.getAdapter().onMessage || !rawEvent || !isNonEmptyString3(channelId) || !isNonEmptyString3(ts) || !senderId) {
169627
+ return;
169628
+ }
169629
+ if (!shouldAcceptInboundMessageByBotPolicy({
169630
+ message: rawEvent,
169631
+ wasMentioned: true
169632
+ })) {
169478
169633
  return;
169479
169634
  }
169480
- const seenKey = `${event2.channel}:${event2.ts}`;
169481
- if (markIngressMessageSeen(event2.channel, event2.ts) && !params.debounce.consumeAppMentionRetry(seenKey)) {
169635
+ const threadId = firstNonEmptyString(rawEvent.thread_ts, ts) ?? ts;
169636
+ const seenKey = `${channelId}:${ts}`;
169637
+ if (markIngressMessageSeen(channelId, ts) && !params.debounce.consumeAppMentionRetry(seenKey)) {
169482
169638
  return;
169483
169639
  }
169484
- rememberMessageThread(event2.ts, event2.thread_ts ?? event2.ts);
169640
+ rememberMessageThread(ts, threadId);
169485
169641
  await dispatchInbound({
169486
169642
  channel: "slack",
169487
169643
  accountId: config3.accountId,
169488
- chatId: event2.channel,
169489
- senderId: event2.user,
169490
- senderTeamId: resolveSlackSenderTeamId(event2),
169491
- senderName: await resolveUserName(app, event2.user),
169492
- chatLabel: event2.channel,
169493
- text: normalizeSlackText(event2.text ?? ""),
169494
- timestamp: slackTimestampToMillis(event2.ts),
169495
- messageId: event2.ts,
169496
- threadId: event2.thread_ts ?? event2.ts,
169644
+ chatId: channelId,
169645
+ senderId,
169646
+ senderTeamId: resolveSlackSenderTeamId(rawEvent),
169647
+ senderName: await resolveInboundSenderName(app, firstNonEmptyString(rawEvent.user), firstNonEmptyString(rawEvent.bot_id)),
169648
+ chatLabel: channelId,
169649
+ text: normalizeSlackText(isNonEmptyString3(rawEvent.text) ? rawEvent.text : ""),
169650
+ timestamp: slackTimestampToMillis(ts),
169651
+ messageId: ts,
169652
+ threadId,
169497
169653
  chatType: "channel",
169498
169654
  isMention: true,
169499
169655
  attachments: await resolveSlackInboundAttachments({
@@ -169503,7 +169659,7 @@ function createSlackIngressController(params) {
169503
169659
  transcribeVoice: config3.transcribeVoice === true
169504
169660
  }),
169505
169661
  raw: event2
169506
- }, event2, "app_mention", true, "channel mention");
169662
+ }, rawEvent, "app_mention", true, "channel mention");
169507
169663
  });
169508
169664
  const handleCommand = async ({
169509
169665
  command,
@@ -169511,10 +169667,10 @@ function createSlackIngressController(params) {
169511
169667
  }) => {
169512
169668
  await ack();
169513
169669
  const adapter = params.getAdapter();
169514
- if (!adapter.onMessage || !isNonEmptyString2(command.command) || !isNonEmptyString2(command.channel_id) || !isNonEmptyString2(command.user_id)) {
169670
+ if (!adapter.onMessage || !isNonEmptyString3(command.command) || !isNonEmptyString3(command.channel_id) || !isNonEmptyString3(command.user_id)) {
169515
169671
  return;
169516
169672
  }
169517
- const args = isNonEmptyString2(command.text) ? command.text.trim() : "";
169673
+ const args = isNonEmptyString3(command.text) ? command.text.trim() : "";
169518
169674
  try {
169519
169675
  await adapter.onMessage({
169520
169676
  channel: "slack",
@@ -169578,7 +169734,7 @@ function createSlackIngressController(params) {
169578
169734
  const item = asRecord2(event2.item);
169579
169735
  const chatId = item?.channel;
169580
169736
  const targetMessageId = item?.ts;
169581
- if (!adapter.onMessage || item?.type !== "message" || !isNonEmptyString2(chatId) || !isNonEmptyString2(targetMessageId) || !isNonEmptyString2(event2.user) || !isNonEmptyString2(event2.reaction) || event2.user === params.getBotUserId()) {
169737
+ if (!adapter.onMessage || item?.type !== "message" || !isNonEmptyString3(chatId) || !isNonEmptyString3(targetMessageId) || !isNonEmptyString3(event2.user) || !isNonEmptyString3(event2.reaction) || event2.user === params.getBotUserId()) {
169582
169738
  return;
169583
169739
  }
169584
169740
  const chatType = resolveSlackChatType(chatId);
@@ -169602,7 +169758,7 @@ function createSlackIngressController(params) {
169602
169758
  action: action3,
169603
169759
  emoji: event2.reaction,
169604
169760
  targetMessageId,
169605
- targetSenderId: isNonEmptyString2(event2.item_user) ? event2.item_user : undefined
169761
+ targetSenderId: isNonEmptyString3(event2.item_user) ? event2.item_user : undefined
169606
169762
  },
169607
169763
  raw: event2
169608
169764
  });
@@ -169647,22 +169803,22 @@ function createSlackStatusController(params) {
169647
169803
  const keepaliveByConversation = new Map;
169648
169804
  const clearedStaleReplyKeys = new Set;
169649
169805
  function getConversationKey(source2) {
169650
- return source2.channel === "slack" && isNonEmptyString2(source2.agentId) && isNonEmptyString2(source2.conversationId) ? `${source2.agentId}:${source2.conversationId}` : null;
169806
+ return source2.channel === "slack" && isNonEmptyString3(source2.agentId) && isNonEmptyString3(source2.conversationId) ? `${source2.agentId}:${source2.conversationId}` : null;
169651
169807
  }
169652
169808
  function getLifecycleReplyKey(source2) {
169653
- if (source2.channel !== "slack" || !isNonEmptyString2(source2.chatId)) {
169809
+ if (source2.channel !== "slack" || !isNonEmptyString3(source2.chatId)) {
169654
169810
  return null;
169655
169811
  }
169656
169812
  const replyToMessageId = resolveSlackProgressThreadTs(source2);
169657
- return isNonEmptyString2(replyToMessageId) ? `${source2.chatId}:${replyToMessageId}` : null;
169813
+ return isNonEmptyString3(replyToMessageId) ? `${source2.chatId}:${replyToMessageId}` : null;
169658
169814
  }
169659
169815
  function getLifecycleErrorReplyKey(source2) {
169660
- if (source2.channel !== "slack" || !isNonEmptyString2(source2.chatId)) {
169816
+ if (source2.channel !== "slack" || !isNonEmptyString3(source2.chatId)) {
169661
169817
  return null;
169662
169818
  }
169663
169819
  if (source2.chatType === "direct" || resolveSlackChatType(source2.chatId) === "direct") {
169664
169820
  const replyToMessageId = resolveSlackSourceThreadTs(source2);
169665
- return isNonEmptyString2(replyToMessageId) ? `${source2.chatId}:${replyToMessageId}` : `${source2.chatId}:direct`;
169821
+ return isNonEmptyString3(replyToMessageId) ? `${source2.chatId}:${replyToMessageId}` : `${source2.chatId}:direct`;
169666
169822
  }
169667
169823
  return getLifecycleReplyKey(source2);
169668
169824
  }
@@ -169821,7 +169977,7 @@ ${loadingText}`;
169821
169977
  markAutoClearedByKey(key);
169822
169978
  },
169823
169979
  markAutoClearedForMessage(msg) {
169824
- if (isNonEmptyString2(msg.agentId) && isNonEmptyString2(msg.conversationId)) {
169980
+ if (isNonEmptyString3(msg.agentId) && isNonEmptyString3(msg.conversationId)) {
169825
169981
  markAutoClearedByKey(`${msg.agentId}:${msg.conversationId}`);
169826
169982
  return;
169827
169983
  }
@@ -169871,7 +170027,7 @@ function truncateThreadLabel(text, maxLength3 = 80) {
169871
170027
  return normalized.length <= maxLength3 ? normalized : `${normalized.slice(0, maxLength3 - 1).trimEnd()}…`;
169872
170028
  }
169873
170029
  function buildThreadLabel(msg, starterText) {
169874
- const roomLabel = msg.chatType === "channel" && isNonEmptyString2(msg.chatLabel) && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
170030
+ const roomLabel = msg.chatType === "channel" && isNonEmptyString3(msg.chatLabel) && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
169875
170031
  const preview = truncateThreadLabel(starterText ?? msg.text);
169876
170032
  const threadLabel = msg.chatType === "direct" ? "Slack DM thread" : "Slack thread";
169877
170033
  if (preview)
@@ -169881,12 +170037,12 @@ function buildThreadLabel(msg, starterText) {
169881
170037
  function buildChannelContextLabel(msg) {
169882
170038
  if (msg.chatType !== "channel")
169883
170039
  return;
169884
- const roomLabel = isNonEmptyString2(msg.chatLabel) && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
170040
+ const roomLabel = isNonEmptyString3(msg.chatLabel) && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
169885
170041
  return roomLabel ? `Slack channel context${roomLabel} before thread start` : "Slack channel context before thread start";
169886
170042
  }
169887
170043
  async function prepareSlackInboundMessage(params) {
169888
170044
  const { msg, config: config3 } = params;
169889
- if (msg.channel !== "slack" || !isNonEmptyString2(msg.threadId) || !isNonEmptyString2(msg.messageId)) {
170045
+ if (msg.channel !== "slack" || !isNonEmptyString3(msg.threadId) || !isNonEmptyString3(msg.messageId)) {
169890
170046
  return msg;
169891
170047
  }
169892
170048
  const isFirstRouteTurn = params.options?.isFirstRouteTurn === true;
@@ -169935,18 +170091,18 @@ async function prepareSlackInboundMessage(params) {
169935
170091
  return msg;
169936
170092
  }
169937
170093
  const userIds = new Set;
169938
- if (isNonEmptyString2(starter?.userId))
170094
+ if (isNonEmptyString3(starter?.userId))
169939
170095
  userIds.add(starter.userId);
169940
170096
  for (const entry of history) {
169941
- if (isNonEmptyString2(entry.userId))
170097
+ if (isNonEmptyString3(entry.userId))
169942
170098
  userIds.add(entry.userId);
169943
170099
  }
169944
170100
  await Promise.all(Array.from(userIds).map((userId) => params.resolveUserName(app, userId)));
169945
170101
  const resolveSenderName = (userId, botId) => {
169946
- if (isNonEmptyString2(userId)) {
170102
+ if (isNonEmptyString3(userId)) {
169947
170103
  return params.getKnownUserDisplayName(userId) ?? userId;
169948
170104
  }
169949
- return isNonEmptyString2(botId) ? `Bot (${botId})` : undefined;
170105
+ return isNonEmptyString3(botId) ? `Bot (${botId})` : undefined;
169950
170106
  };
169951
170107
  return {
169952
170108
  ...msg,
@@ -170016,6 +170172,7 @@ function createSlackAdapter(config3) {
170016
170172
  let writeClientPromise = null;
170017
170173
  let running = false;
170018
170174
  let botUserId = null;
170175
+ let botId = null;
170019
170176
  let adapter;
170020
170177
  const agentThreadTracker = createAgentThreadTracker();
170021
170178
  const debounce = createSlackInboundDebounceController({
@@ -170026,6 +170183,7 @@ function createSlackAdapter(config3) {
170026
170183
  config: config3,
170027
170184
  getAdapter: () => adapter,
170028
170185
  getBotUserId: () => botUserId,
170186
+ getBotId: () => botId,
170029
170187
  agentThreadTracker,
170030
170188
  debounce
170031
170189
  });
@@ -170102,7 +170260,7 @@ function createSlackAdapter(config3) {
170102
170260
  if (!running)
170103
170261
  return;
170104
170262
  if (event2.type === "queued") {
170105
- if (isSlackFlatChannelThreadOpener(event2.source) && isNonEmptyString2(event2.source.messageId) && !agentThreadTracker.has(event2.source.chatId, event2.source.messageId)) {
170263
+ if (isSlackFlatChannelThreadOpener(event2.source) && isNonEmptyString3(event2.source.messageId) && !agentThreadTracker.has(event2.source.chatId, event2.source.messageId)) {
170106
170264
  await status.activate(event2.source, SLACK_ASSISTANT_STARTUP_STATUS, SLACK_ASSISTANT_STARTUP_STATUS);
170107
170265
  }
170108
170266
  return;
@@ -170164,7 +170322,7 @@ function createSlackAdapter(config3) {
170164
170322
  if (msg.mediaPath) {
170165
170323
  const result = await uploadSlackFile(client, msg);
170166
170324
  const threadId = msg.threadId ?? msg.replyToMessageId ?? null;
170167
- if (resolveSlackChatType(msg.chatId) === "channel" && isNonEmptyString2(threadId)) {
170325
+ if (resolveSlackChatType(msg.chatId) === "channel" && isNonEmptyString3(threadId)) {
170168
170326
  agentThreadTracker.remember(msg.chatId, threadId);
170169
170327
  }
170170
170328
  status.markAutoClearedForMessage(msg);
@@ -170175,7 +170333,7 @@ function createSlackAdapter(config3) {
170175
170333
  threadId: msg.threadId,
170176
170334
  replyToMessageId: msg.replyToMessageId
170177
170335
  });
170178
- const footnote = isNonEmptyString2(msg.agentId) && isNonEmptyString2(msg.conversationId) ? buildSlackChatFootnote({
170336
+ const footnote = isNonEmptyString3(msg.agentId) && isNonEmptyString3(msg.conversationId) ? buildSlackChatFootnote({
170179
170337
  agentId: msg.agentId,
170180
170338
  conversationId: msg.conversationId
170181
170339
  }) : "";
@@ -170188,7 +170346,7 @@ function createSlackAdapter(config3) {
170188
170346
  });
170189
170347
  const outboundThreadId = threadTs ?? (resolveSlackChatType(msg.chatId) === "channel" ? response.ts ?? null : null);
170190
170348
  ingress.rememberMessageThread(response.ts, outboundThreadId);
170191
- if (resolveSlackChatType(msg.chatId) === "channel" && isNonEmptyString2(outboundThreadId)) {
170349
+ if (resolveSlackChatType(msg.chatId) === "channel" && isNonEmptyString3(outboundThreadId)) {
170192
170350
  agentThreadTracker.remember(msg.chatId, outboundThreadId);
170193
170351
  }
170194
170352
  status.markAutoClearedForMessage(msg);
@@ -170211,7 +170369,7 @@ function createSlackAdapter(config3) {
170211
170369
  });
170212
170370
  const outboundThreadId = threadTs ?? (resolveSlackChatType(chatId) === "channel" ? response.ts ?? null : null);
170213
170371
  ingress.rememberMessageThread(response.ts, outboundThreadId);
170214
- if (resolveSlackChatType(chatId) === "channel" && isNonEmptyString2(outboundThreadId)) {
170372
+ if (resolveSlackChatType(chatId) === "channel" && isNonEmptyString3(outboundThreadId)) {
170215
170373
  agentThreadTracker.remember(chatId, outboundThreadId);
170216
170374
  }
170217
170375
  status.markAutoClearedForMessage({
@@ -170237,7 +170395,7 @@ function createSlackAdapter(config3) {
170237
170395
  if (event2.kind === "generic_tool_approval" && response.ts) {
170238
170396
  approvals.rememberPrompt(event2, response.ts);
170239
170397
  }
170240
- if (resolveSlackChatType(event2.source.chatId) === "channel" && isNonEmptyString2(outboundThreadId)) {
170398
+ if (resolveSlackChatType(event2.source.chatId) === "channel" && isNonEmptyString3(outboundThreadId)) {
170241
170399
  agentThreadTracker.remember(event2.source.chatId, outboundThreadId);
170242
170400
  }
170243
170401
  status.markAutoCleared(event2.source);
@@ -170252,7 +170410,9 @@ function createSlackAdapter(config3) {
170252
170410
  return;
170253
170411
  const slackApp = await ensureApp();
170254
170412
  const auth = await slackApp.client.auth.test();
170255
- botUserId = isNonEmptyString2(auth.user_id) ? auth.user_id : null;
170413
+ const authRecord = auth;
170414
+ botUserId = isNonEmptyString3(authRecord.user_id) ? authRecord.user_id : null;
170415
+ botId = isNonEmptyString3(authRecord.bot_id) ? authRecord.bot_id : null;
170256
170416
  await slackApp.start();
170257
170417
  running = true;
170258
170418
  console.log(`[Slack] App started for workspace ${auth.team ?? "unknown"} (dm_policy: ${config3.dmPolicy})`);
@@ -170267,6 +170427,7 @@ function createSlackAdapter(config3) {
170267
170427
  writeClient = null;
170268
170428
  writeClientPromise = null;
170269
170429
  botUserId = null;
170430
+ botId = null;
170270
170431
  status.clear();
170271
170432
  approvals.clear();
170272
170433
  debounce.clear();
@@ -171167,7 +171328,7 @@ function formatDiscordDeliveryError(error54) {
171167
171328
  }
171168
171329
 
171169
171330
  // src/channels/discord/utils.ts
171170
- function isNonEmptyString5(value) {
171331
+ function isNonEmptyString6(value) {
171171
171332
  return typeof value === "string" && value.length > 0;
171172
171333
  }
171173
171334
  function isDiscordTextChannel(channel) {
@@ -171234,7 +171395,7 @@ function shouldAutoThreadOnDiscordMention(account, channelId) {
171234
171395
  return account.autoThreadOnMention ?? false;
171235
171396
  }
171236
171397
  function buildDiscordIngressMessageKey(accountId, messageId) {
171237
- if (!isNonEmptyString5(accountId) || !isNonEmptyString5(messageId)) {
171398
+ if (!isNonEmptyString6(accountId) || !isNonEmptyString6(messageId)) {
171238
171399
  return null;
171239
171400
  }
171240
171401
  return `${accountId}:${messageId}`;
@@ -171318,13 +171479,13 @@ function createDiscordAdapter(config3) {
171318
171479
  return false;
171319
171480
  }
171320
171481
  function getLifecycleMessageKey(source2) {
171321
- if (source2.channel !== "discord" || !isNonEmptyString5(source2.chatId) || !isNonEmptyString5(source2.messageId)) {
171482
+ if (source2.channel !== "discord" || !isNonEmptyString6(source2.chatId) || !isNonEmptyString6(source2.messageId)) {
171322
171483
  return null;
171323
171484
  }
171324
171485
  return `${source2.chatId}:${source2.messageId}`;
171325
171486
  }
171326
171487
  function getLifecycleReplyKey(source2) {
171327
- if (source2.channel !== "discord" || !isNonEmptyString5(source2.chatId)) {
171488
+ if (source2.channel !== "discord" || !isNonEmptyString6(source2.chatId)) {
171328
171489
  return null;
171329
171490
  }
171330
171491
  return [
@@ -171337,7 +171498,7 @@ function createDiscordAdapter(config3) {
171337
171498
  if (source2.channel !== "discord")
171338
171499
  return null;
171339
171500
  const channelId = source2.threadId ?? source2.chatId;
171340
- return isNonEmptyString5(channelId) ? channelId : null;
171501
+ return isNonEmptyString6(channelId) ? channelId : null;
171341
171502
  }
171342
171503
  function getTypingSourceKey(source2) {
171343
171504
  const channelId = getTypingChannelId(source2);
@@ -171389,7 +171550,7 @@ function createDiscordAdapter(config3) {
171389
171550
  return true;
171390
171551
  }
171391
171552
  async function sendLifecycleReaction(source2, emoji3, remove = false) {
171392
- if (!client || !isNonEmptyString5(source2.messageId))
171553
+ if (!client || !isNonEmptyString6(source2.messageId))
171393
171554
  return;
171394
171555
  try {
171395
171556
  const channel = await client.channels.fetch(source2.chatId);
@@ -171928,7 +172089,7 @@ function createDiscordAdapter(config3) {
171928
172089
  clearTypingForChannel(chatId);
171929
172090
  },
171930
172091
  async prepareInboundMessage(msg, options3) {
171931
- if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !isNonEmptyString5(msg.threadId) || !client) {
172092
+ if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !isNonEmptyString6(msg.threadId) || !client) {
171932
172093
  return msg;
171933
172094
  }
171934
172095
  const starter = await resolveDiscordThreadStarter({
@@ -182846,11 +183007,11 @@ When users ask you to perform tasks, check if any of the available skills match.
182846
183007
  When users reference a "slash command" or "/<something>" (e.g., "/commit", "/review-pr"), they are referring to a skill. Use this tool to invoke it.
182847
183008
 
182848
183009
  How to invoke:
182849
- - Use this tool with the skill name and optional arguments
183010
+ - Use this tool with only the skill name
182850
183011
  - Examples:
182851
183012
  - \`skill: "pdf"\` - invoke the pdf skill
182852
- - \`skill: "commit", args: "-m 'Fix bug'"\` - invoke with arguments
182853
- - \`skill: "review-pr", args: "123"\` - invoke with arguments
183013
+ - \`skill: "commit"\` - invoke the commit skill
183014
+ - \`skill: "review-pr"\` - invoke the review-pr skill
182854
183015
  - \`skill: "ms-office-suite:pdf"\` - invoke using fully qualified name
182855
183016
 
182856
183017
  Important:
@@ -196395,7 +196556,6 @@ When to use: ${whenToUse}` : description;
196395
196556
  description: modelDescription,
196396
196557
  whenToUse,
196397
196558
  argumentHint: getFrontmatterString(frontmatter, "argument-hint"),
196398
- arguments: getFrontmatterStringList(frontmatter, "arguments"),
196399
196559
  disableModelInvocation: getFrontmatterBoolean(frontmatter, "disable-model-invocation") ?? false,
196400
196560
  userInvocable: getFrontmatterBoolean(frontmatter, "user-invocable") ?? true,
196401
196561
  category: getFrontmatterString(frontmatter, "category"),
@@ -382984,6 +383144,7 @@ var init_skill_content_registry = __esm(() => {
382984
383144
  // src/tools/impl/skill.ts
382985
383145
  var exports_skill = {};
382986
383146
  __export(exports_skill, {
383147
+ wrapSkillPrompt: () => wrapSkillPrompt,
382987
383148
  wrapSkillContent: () => wrapSkillContent,
382988
383149
  skill: () => skill,
382989
383150
  renderSkillContent: () => renderSkillContent,
@@ -383081,50 +383242,6 @@ function getResolvedAgentId(args) {
383081
383242
  return;
383082
383243
  }
383083
383244
  }
383084
- function splitSkillArguments(args) {
383085
- const parts = [];
383086
- const pattern4 = /"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|\S+/g;
383087
- for (const match3 of args.matchAll(pattern4)) {
383088
- const raw = match3[1] ?? match3[2] ?? match3[0];
383089
- parts.push(raw.replace(/\\(["'\\])/g, "$1"));
383090
- }
383091
- return parts;
383092
- }
383093
- function substituteSkillArguments(content, args, argumentNames) {
383094
- const rawArgs = args?.trim() ?? "";
383095
- if (!rawArgs) {
383096
- return content;
383097
- }
383098
- const argParts = splitSkillArguments(rawArgs);
383099
- let result = content;
383100
- let substituted = false;
383101
- result = result.replace(/\$ARGUMENTS\[(\d+)\]/g, (_match, index) => {
383102
- substituted = true;
383103
- return argParts[Number(index)] ?? "";
383104
- });
383105
- result = result.replace(/\$ARGUMENTS/g, () => {
383106
- substituted = true;
383107
- return rawArgs;
383108
- });
383109
- result = result.replace(/\$(\d+)\b/g, (_match, index) => {
383110
- substituted = true;
383111
- return argParts[Number(index)] ?? "";
383112
- });
383113
- for (const [index, name] of (argumentNames ?? []).entries()) {
383114
- const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
383115
- const namePattern = new RegExp(`\\$${escapedName}\\b`, "g");
383116
- result = result.replace(namePattern, () => {
383117
- substituted = true;
383118
- return argParts[index] ?? "";
383119
- });
383120
- }
383121
- if (!substituted) {
383122
- result = `${result.trimEnd()}
383123
-
383124
- ARGUMENTS: ${rawArgs}`;
383125
- }
383126
- return result;
383127
- }
383128
383245
  function renderSkillContent(skillName, skillContent, skillPath, options3 = {}) {
383129
383246
  const { frontmatter } = parseFrontmatter(skillContent);
383130
383247
  if (!options3.allowDisabledModelInvocation && getFrontmatterBoolean(frontmatter, "disable-model-invocation") === true) {
@@ -383132,13 +383249,11 @@ function renderSkillContent(skillName, skillContent, skillPath, options3 = {}) {
383132
383249
  }
383133
383250
  const skillDir = dirname16(skillPath);
383134
383251
  const hasExtras = hasAdditionalFiles(skillPath);
383135
- const argumentNames = getFrontmatterStringList(frontmatter, "arguments");
383136
383252
  const withSkillDir = skillContent.replace(/<SKILL_DIR>/g, skillDir).replace(/\$\{CLAUDE_SKILL_DIR\}/g, skillDir);
383137
- const withArguments = substituteSkillArguments(withSkillDir, options3.args, argumentNames);
383138
383253
  const dirHeader = hasExtras ? `# Skill Directory: ${skillDir}
383139
383254
 
383140
383255
  ` : "";
383141
- return `${dirHeader}${withArguments}`;
383256
+ return `${dirHeader}${withSkillDir}`;
383142
383257
  }
383143
383258
  async function loadRenderedSkillContent(skillName, options3 = {}) {
383144
383259
  const skillsDir = options3.skillsDir ?? await getResolvedSkillsDir();
@@ -383158,6 +383273,12 @@ ${content}
383158
383273
  ${content}
383159
383274
  </skill>`;
383160
383275
  }
383276
+ function wrapSkillPrompt(skillName, content, userRequest) {
383277
+ const wrappedSkill = wrapSkillContent(skillName, content);
383278
+ return userRequest ? `${wrappedSkill}
383279
+
383280
+ ${userRequest}` : wrappedSkill;
383281
+ }
383161
383282
  async function skill(args) {
383162
383283
  validateRequiredParams(args, ["skill"], "Skill");
383163
383284
  const { skill: skillName, toolCallId } = args;
@@ -383169,8 +383290,7 @@ async function skill(args) {
383169
383290
  const skillsDir = await getResolvedSkillsDir();
383170
383291
  const fullContent = await loadRenderedSkillContent(skillName, {
383171
383292
  agentId,
383172
- skillsDir,
383173
- args: args.args
383293
+ skillsDir
383174
383294
  });
383175
383295
  if (toolCallId) {
383176
383296
  queueSkillContent(toolCallId, wrapSkillContent(skillName, fullContent));
@@ -386826,10 +386946,6 @@ var init_Skill2 = __esm(() => {
386826
386946
  skill: {
386827
386947
  type: "string",
386828
386948
  description: 'The skill name. E.g., "commit", "review-pr", or "pdf"'
386829
- },
386830
- args: {
386831
- type: "string",
386832
- description: "Optional arguments for the skill"
386833
386949
  }
386834
386950
  },
386835
386951
  required: ["skill"],
@@ -400213,10 +400329,6 @@ async function resolveAvailableLocalModelForTurn(input) {
400213
400329
  }
400214
400330
  };
400215
400331
  }
400216
- function shouldIncludeLocalModel(provider, model) {
400217
- const modelId = isPiProvider(provider) ? stripProviderHandlePrefix(model, provider) ?? model : model;
400218
- return !(localProviderTypeForModelConfig(provider) === "chatgpt_oauth" && UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS.has(modelId));
400219
- }
400220
400332
  async function listLocalModels(storageDir, options3 = {}) {
400221
400333
  const records = listLocalProviderRecords(storageDir);
400222
400334
  const providerNames = localProviderNamesFromRecords(records);
@@ -400225,8 +400337,6 @@ async function listLocalModels(storageDir, options3 = {}) {
400225
400337
  const registeredProviders2 = listRegisteredPiProviders();
400226
400338
  const registeredProvidersWithModels = new Set(registeredProviders2.filter((provider) => provider.config.models !== undefined).map((provider) => provider.providerName));
400227
400339
  const addModel = (provider, model, options4 = {}) => {
400228
- if (!shouldIncludeLocalModel(provider, model))
400229
- return;
400230
400340
  const handle = options4.handle ?? (typeof provider === "string" && !isPiProviderForLocalModelHandle(provider) ? `${provider}/${model}` : localModelHandle(provider, model));
400231
400341
  if (models3.some((entry) => entry.handle === handle))
400232
400342
  return;
@@ -400313,7 +400423,7 @@ async function listLocalModels(storageDir, options3 = {}) {
400313
400423
  }
400314
400424
  return models3;
400315
400425
  }
400316
- var LOCAL_MODEL_DISCOVERY_TIMEOUT_MS = 2000, LOCAL_MODEL_AUTODETECT_DISCOVERY_TIMEOUT_MS = 500, UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS;
400426
+ var LOCAL_MODEL_DISCOVERY_TIMEOUT_MS = 2000, LOCAL_MODEL_AUTODETECT_DISCOVERY_TIMEOUT_MS = 500;
400317
400427
  var init_local_model_config = __esm(() => {
400318
400428
  init_compat2();
400319
400429
  init_pi_model_factory();
@@ -400321,7 +400431,6 @@ var init_local_model_config = __esm(() => {
400321
400431
  init_pi_provider_registry();
400322
400432
  init_registered_pi_provider_runtime();
400323
400433
  init_local_provider_auth_store();
400324
- UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS = new Set(["gpt-5.6-luna"]);
400325
400434
  });
400326
400435
 
400327
400436
  // src/backend/local/local-context-estimate.ts
@@ -445716,6 +445825,117 @@ var init_cron_file = __esm(() => {
445716
445825
  GC_AGE_MS = 24 * 60 * 60 * 1000;
445717
445826
  });
445718
445827
 
445828
+ // src/cron/prompt.ts
445829
+ function pad(value, width) {
445830
+ return String(value).padStart(width, "0");
445831
+ }
445832
+ function formatOffset(minutes) {
445833
+ const sign = minutes >= 0 ? "+" : "-";
445834
+ const abs = Math.abs(minutes);
445835
+ return `${sign}${pad(Math.floor(abs / 60), 2)}:${pad(abs % 60, 2)}`;
445836
+ }
445837
+ function getLocalDateTimeParts(date6) {
445838
+ return {
445839
+ year: date6.getFullYear(),
445840
+ month: date6.getMonth() + 1,
445841
+ day: date6.getDate(),
445842
+ hour: date6.getHours(),
445843
+ minute: date6.getMinutes(),
445844
+ second: date6.getSeconds()
445845
+ };
445846
+ }
445847
+ function isValidTimezone(timezone) {
445848
+ try {
445849
+ new Intl.DateTimeFormat("en-US", { timeZone: timezone });
445850
+ return true;
445851
+ } catch {
445852
+ return false;
445853
+ }
445854
+ }
445855
+ function getSystemTimezone() {
445856
+ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
445857
+ if (!timezone || !isValidTimezone(timezone)) {
445858
+ return null;
445859
+ }
445860
+ return timezone;
445861
+ }
445862
+ function getEffectiveTimezone(timezone) {
445863
+ const trimmed = timezone.trim();
445864
+ if (trimmed && isValidTimezone(trimmed)) {
445865
+ return trimmed;
445866
+ }
445867
+ return getSystemTimezone();
445868
+ }
445869
+ function formatTimezoneDisplay(timezone) {
445870
+ const trimmed = timezone.trim();
445871
+ if (!trimmed) {
445872
+ return "local time";
445873
+ }
445874
+ if (isValidTimezone(trimmed)) {
445875
+ return trimmed;
445876
+ }
445877
+ return `${trimmed} (invalid; using local time)`;
445878
+ }
445879
+ function getZonedDateTimeParts(date6, timezone) {
445880
+ const formatter = new Intl.DateTimeFormat("en-US", {
445881
+ timeZone: timezone,
445882
+ calendar: "iso8601",
445883
+ numberingSystem: "latn",
445884
+ hourCycle: "h23",
445885
+ year: "numeric",
445886
+ month: "2-digit",
445887
+ day: "2-digit",
445888
+ hour: "2-digit",
445889
+ minute: "2-digit",
445890
+ second: "2-digit"
445891
+ });
445892
+ const parts = new Map(formatter.formatToParts(date6).map((part) => [part.type, part.value]));
445893
+ return {
445894
+ year: Number.parseInt(parts.get("year") ?? "0", 10),
445895
+ month: Number.parseInt(parts.get("month") ?? "1", 10),
445896
+ day: Number.parseInt(parts.get("day") ?? "1", 10),
445897
+ hour: Number.parseInt(parts.get("hour") ?? "0", 10),
445898
+ minute: Number.parseInt(parts.get("minute") ?? "0", 10),
445899
+ second: Number.parseInt(parts.get("second") ?? "0", 10)
445900
+ };
445901
+ }
445902
+ function formatTimezoneQualifiedIso(date6, timezone) {
445903
+ const effectiveTimezone = getEffectiveTimezone(timezone);
445904
+ const parts = effectiveTimezone ? getZonedDateTimeParts(date6, effectiveTimezone) : getLocalDateTimeParts(date6);
445905
+ const millis = date6.getMilliseconds();
445906
+ const zonedAsUtcMs = Date.UTC(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second, millis);
445907
+ const offsetMinutes = Math.round((zonedAsUtcMs - date6.getTime()) / 60000);
445908
+ return `${pad(parts.year, 4)}-${pad(parts.month, 2)}-${pad(parts.day, 2)}T${pad(parts.hour, 2)}:${pad(parts.minute, 2)}:${pad(parts.second, 2)}.${pad(millis, 3)}${formatOffset(offsetMinutes)}[${effectiveTimezone ?? "local"}]`;
445909
+ }
445910
+ function getIntendedCronOccurrence(task2, matchedAt) {
445911
+ if (!task2.recurring && task2.scheduled_for) {
445912
+ const scheduledFor = new Date(task2.scheduled_for);
445913
+ if (Number.isFinite(scheduledFor.getTime())) {
445914
+ return scheduledFor;
445915
+ }
445916
+ }
445917
+ const occurrence = new Date(matchedAt);
445918
+ occurrence.setSeconds(0, 0);
445919
+ return occurrence;
445920
+ }
445921
+ function formatCronPrompt(task2, timing) {
445922
+ const timezone = typeof task2.timezone === "string" ? task2.timezone : "";
445923
+ const lines = [
445924
+ `Scheduled task "${task2.name}" is firing.`,
445925
+ `Description: ${task2.description}`,
445926
+ `Timezone: ${formatTimezoneDisplay(timezone)}`,
445927
+ `Scheduled for: ${formatTimezoneQualifiedIso(timing.intendedOccurrence, timezone)}`,
445928
+ `Current time: ${formatTimezoneQualifiedIso(timing.schedulerNow, timezone)}`,
445929
+ task2.recurring ? `This is fire #${task2.fire_count + 1} (cron: ${task2.cron}).` : "This is a one-off scheduled task.",
445930
+ "",
445931
+ "You are running autonomously: no user is watching this turn and questions will not be answered. Deliver results through your available channels or record them in memory, and work until the task is done or genuinely blocked.",
445932
+ "",
445933
+ `Prompt: ${task2.prompt}`
445934
+ ];
445935
+ return lines.join(`
445936
+ `);
445937
+ }
445938
+
445719
445939
  // src/cron/run-log.ts
445720
445940
  import {
445721
445941
  appendFileSync as appendFileSync5,
@@ -445900,18 +446120,8 @@ var init_run_log = __esm(() => {
445900
446120
  function minuteKey(date6) {
445901
446121
  return `${date6.getFullYear()}-${String(date6.getMonth() + 1).padStart(2, "0")}-${String(date6.getDate()).padStart(2, "0")}T${String(date6.getHours()).padStart(2, "0")}:${String(date6.getMinutes()).padStart(2, "0")}`;
445902
446122
  }
445903
- function wrapCronPrompt(task2) {
445904
- const lines = [
445905
- `Scheduled task "${task2.name}" is firing.`,
445906
- `Description: ${task2.description}`,
445907
- task2.recurring ? `This is fire #${task2.fire_count + 1} (cron: ${task2.cron}).` : `This is a one-off scheduled task.`,
445908
- "",
445909
- "You are running autonomously: no user is watching this turn and questions will not be answered. Deliver results through your available channels or record them in memory, and work until the task is done or genuinely blocked.",
445910
- "",
445911
- `Prompt: ${task2.prompt}`
445912
- ];
445913
- return lines.join(`
445914
- `);
446123
+ function wrapCronPrompt(task2, timing) {
446124
+ return formatCronPrompt(task2, timing);
445915
446125
  }
445916
446126
  function getCronConversationSummary(task2) {
445917
446127
  return `[Schedule] ${task2.name}`;
@@ -445974,13 +446184,13 @@ function shouldFireTask(task2, now) {
445974
446184
  }
445975
446185
  return cronMatchesTime(task2.cron, now, task2.timezone);
445976
446186
  }
445977
- async function fireCronTask(task2, now, socket, opts, processQueuedTurn) {
446187
+ async function fireCronTask(task2, timing, socket, opts, processQueuedTurn) {
445978
446188
  const listener = getActiveRuntime();
445979
446189
  if (!listener) {
445980
446190
  setLastRunOutcome(task2.id, {
445981
446191
  outcome: "failed",
445982
446192
  reason: "runtime_unavailable",
445983
- runAt: now,
446193
+ runAt: timing.schedulerNow,
445984
446194
  error: "No active runtime"
445985
446195
  });
445986
446196
  safeAppendCronRunLogForTask(task2, {
@@ -445988,7 +446198,7 @@ async function fireCronTask(task2, now, socket, opts, processQueuedTurn) {
445988
446198
  outcome: "failed",
445989
446199
  reason: "runtime_unavailable",
445990
446200
  error: "No active runtime",
445991
- runAtMs: now.getTime(),
446201
+ runAtMs: timing.schedulerNow.getTime(),
445992
446202
  scheduledFor: task2.scheduled_for
445993
446203
  });
445994
446204
  return false;
@@ -446000,7 +446210,7 @@ async function fireCronTask(task2, now, socket, opts, processQueuedTurn) {
446000
446210
  safeAppendCronRunLogForTask(task2, {
446001
446211
  status: "error",
446002
446212
  error: err instanceof Error ? err.message : "failed to resolve conversation",
446003
- runAtMs: now.getTime(),
446213
+ runAtMs: timing.schedulerNow.getTime(),
446004
446214
  scheduledFor: task2.scheduled_for
446005
446215
  });
446006
446216
  return false;
@@ -446010,7 +446220,7 @@ async function fireCronTask(task2, now, socket, opts, processQueuedTurn) {
446010
446220
  setLastRunOutcome(task2.id, {
446011
446221
  outcome: "failed",
446012
446222
  reason: "runtime_unavailable",
446013
- runAt: now,
446223
+ runAt: timing.schedulerNow,
446014
446224
  error: "Conversation runtime unavailable"
446015
446225
  });
446016
446226
  safeAppendCronRunLogForTask(task2, {
@@ -446018,13 +446228,13 @@ async function fireCronTask(task2, now, socket, opts, processQueuedTurn) {
446018
446228
  outcome: "failed",
446019
446229
  reason: "runtime_unavailable",
446020
446230
  error: "Conversation runtime unavailable",
446021
- runAtMs: now.getTime(),
446231
+ runAtMs: timing.schedulerNow.getTime(),
446022
446232
  scheduledFor: task2.scheduled_for
446023
446233
  });
446024
446234
  return false;
446025
446235
  }
446026
446236
  const conversationRuntime = ensureConversationQueueRuntime(listener, rawRuntime);
446027
- const text2 = wrapCronPrompt(task2);
446237
+ const text2 = wrapCronPrompt(task2, timing);
446028
446238
  const queuedItem = conversationRuntime.queueRuntime.enqueue({
446029
446239
  kind: "cron_prompt",
446030
446240
  source: "cron",
@@ -446037,7 +446247,7 @@ async function fireCronTask(task2, now, socket, opts, processQueuedTurn) {
446037
446247
  setLastRunOutcome(task2.id, {
446038
446248
  outcome: "failed",
446039
446249
  reason: "queue_full",
446040
- runAt: now,
446250
+ runAt: timing.schedulerNow,
446041
446251
  error: "queue buffer limit"
446042
446252
  });
446043
446253
  safeAppendCronRunLogForTask(task2, {
@@ -446045,13 +446255,13 @@ async function fireCronTask(task2, now, socket, opts, processQueuedTurn) {
446045
446255
  outcome: "failed",
446046
446256
  reason: "queue_full",
446047
446257
  error: "queue buffer limit",
446048
- runAtMs: now.getTime(),
446258
+ runAtMs: timing.schedulerNow.getTime(),
446049
446259
  scheduledFor: task2.scheduled_for
446050
446260
  });
446051
446261
  return false;
446052
446262
  }
446053
446263
  scheduleQueuePump(conversationRuntime, socket, opts, processQueuedTurn);
446054
- const nowIso = now.toISOString();
446264
+ const nowIso = timing.schedulerNow.toISOString();
446055
446265
  if (task2.recurring) {
446056
446266
  updateTask2(task2.id, (t2) => {
446057
446267
  t2.last_fired_at = nowIso;
@@ -446077,7 +446287,7 @@ async function fireCronTask(task2, now, socket, opts, processQueuedTurn) {
446077
446287
  status: "ok",
446078
446288
  outcome: "queued",
446079
446289
  reason: task2.recurring ? "scheduled_time_matched" : "one_off_due",
446080
- runAtMs: now.getTime(),
446290
+ runAtMs: timing.schedulerNow.getTime(),
446081
446291
  queueItemId: queuedItem.id,
446082
446292
  scheduledFor: task2.scheduled_for,
446083
446293
  firedAt: nowIso,
@@ -446140,8 +446350,11 @@ async function runCronTaskNow(taskId) {
446140
446350
  error: "Cron scheduler is not running"
446141
446351
  };
446142
446352
  }
446143
- const now = new Date;
446144
- const fired = await fireCronTask(task2, now, ctx.socket, ctx.opts, ctx.processQueuedTurn);
446353
+ const schedulerNow = new Date;
446354
+ const fired = await fireCronTask(task2, {
446355
+ intendedOccurrence: getIntendedCronOccurrence(task2, schedulerNow),
446356
+ schedulerNow
446357
+ }, ctx.socket, ctx.opts, ctx.processQueuedTurn);
446145
446358
  if (!fired) {
446146
446359
  return {
446147
446360
  success: false,
@@ -446161,8 +446374,8 @@ function tick2(state, socket, opts, processQueuedTurn) {
446161
446374
  stopScheduler();
446162
446375
  return;
446163
446376
  }
446164
- const now = new Date;
446165
- const currentMinuteKey = minuteKey(now);
446377
+ const matchedAt = new Date;
446378
+ const currentMinuteKey = minuteKey(matchedAt);
446166
446379
  if (currentMinuteKey !== state.lastMinuteKey) {
446167
446380
  state.firedThisMinute.clear();
446168
446381
  state.lastMinuteKey = currentMinuteKey;
@@ -446171,12 +446384,13 @@ function tick2(state, socket, opts, processQueuedTurn) {
446171
446384
  for (const task2 of state.cachedTasks) {
446172
446385
  if (task2.status !== "active")
446173
446386
  continue;
446174
- if (handleMissedOneShot(task2, now))
446387
+ if (handleMissedOneShot(task2, matchedAt))
446175
446388
  continue;
446176
446389
  if (state.firedThisMinute.has(task2.id))
446177
446390
  continue;
446178
- if (shouldFireTask(task2, now)) {
446391
+ if (shouldFireTask(task2, matchedAt)) {
446179
446392
  state.firedThisMinute.add(task2.id);
446393
+ const intendedOccurrence = getIntendedCronOccurrence(task2, matchedAt);
446180
446394
  const jitterMs = task2.recurring ? task2.jitter_offset_ms : 0;
446181
446395
  const taskId = task2.id;
446182
446396
  const doFire = () => {
@@ -446185,12 +446399,13 @@ function tick2(state, socket, opts, processQueuedTurn) {
446185
446399
  const freshTask = getTask2(taskId);
446186
446400
  if (!freshTask || freshTask.status !== "active")
446187
446401
  return;
446188
- fireCronTask(freshTask, now, socket, opts, processQueuedTurn).catch((err) => {
446402
+ const schedulerNow = new Date;
446403
+ fireCronTask(freshTask, { intendedOccurrence, schedulerNow }, socket, opts, processQueuedTurn).catch((err) => {
446189
446404
  console.error(`[Cron] Error firing task ${taskId}:`, err);
446190
446405
  setLastRunOutcome(freshTask.id, {
446191
446406
  outcome: "failed",
446192
446407
  reason: "scheduler_error",
446193
- runAt: now,
446408
+ runAt: schedulerNow,
446194
446409
  error: err instanceof Error ? err.message : String(err)
446195
446410
  });
446196
446411
  safeAppendCronRunLogForTask(freshTask, {
@@ -446198,7 +446413,7 @@ function tick2(state, socket, opts, processQueuedTurn) {
446198
446413
  outcome: "failed",
446199
446414
  reason: "scheduler_error",
446200
446415
  error: err instanceof Error ? err.message : String(err),
446201
- runAtMs: now.getTime(),
446416
+ runAtMs: schedulerNow.getTime(),
446202
446417
  scheduledFor: freshTask.scheduled_for
446203
446418
  });
446204
446419
  });
@@ -447306,6 +447521,11 @@ function validateRequestedContextWindow(params) {
447306
447521
  throw new Error(`Context window cannot exceed the model.json default of ${formatContextWindowTokens(defaultContextWindow)} tokens. Use --override to apply a larger value.`);
447307
447522
  }
447308
447523
  }
447524
+ function formatMissingContextWindowDefaultError(params) {
447525
+ const modelDescription = params.modelHandle ? `model ${params.modelHandle}` : "the current model";
447526
+ const suggestedValue = typeof params.currentContextWindow === "number" && Number.isSafeInteger(params.currentContextWindow) && params.currentContextWindow > 0 ? String(params.currentContextWindow) : "<tokens>";
447527
+ return `No catalog default for ${modelDescription}, so reset is unavailable. Pass an explicit value: /context-limit ${suggestedValue}.`;
447528
+ }
447309
447529
  async function applySetMaxContext(params) {
447310
447530
  const parsed = parseSetMaxContextArgs(params.args);
447311
447531
  const backend4 = getBackend();
@@ -447328,7 +447548,10 @@ async function applySetMaxContext(params) {
447328
447548
  const reset = parsed.value === null;
447329
447549
  const contextWindow = reset ? modelDefault.contextWindow : parsed.value;
447330
447550
  if (contextWindow === undefined || contextWindow === null) {
447331
- throw new Error("No default value for max context window found in model.json");
447551
+ throw new Error(formatMissingContextWindowDefaultError({
447552
+ modelHandle: effectiveModelHandle,
447553
+ currentContextWindow: effectiveContextWindow ?? effectiveLlmConfig?.context_window ?? null
447554
+ }));
447332
447555
  }
447333
447556
  if (!reset) {
447334
447557
  validateRequestedContextWindow({
@@ -448057,7 +448280,8 @@ var init_account_config4 = __esm(() => {
448057
448280
  "default_permission_mode",
448058
448281
  "transcribe_voice",
448059
448282
  "show_completed_reaction",
448060
- "listen_mode"
448283
+ "listen_mode",
448284
+ "allow_bots"
448061
448285
  ]);
448062
448286
  slackAccountConfigAdapter = {
448063
448287
  isValidConfig(config3) {
@@ -448066,7 +448290,7 @@ var init_account_config4 = __esm(() => {
448066
448290
  return false;
448067
448291
  }
448068
448292
  }
448069
- return (config3.bot_token === undefined || isString3(config3.bot_token)) && (config3.app_token === undefined || isString3(config3.app_token)) && (config3.mode === undefined || config3.mode === "socket") && (config3.agent_id === undefined || isNullableString4(config3.agent_id)) && (config3.default_permission_mode === undefined || isDefaultPermissionMode2(config3.default_permission_mode)) && (config3.transcribe_voice === undefined || isBoolean3(config3.transcribe_voice)) && (config3.show_completed_reaction === undefined || isBoolean3(config3.show_completed_reaction)) && (config3.listen_mode === undefined || isBoolean3(config3.listen_mode));
448293
+ return (config3.bot_token === undefined || isString3(config3.bot_token)) && (config3.app_token === undefined || isString3(config3.app_token)) && (config3.mode === undefined || config3.mode === "socket") && (config3.agent_id === undefined || isNullableString4(config3.agent_id)) && (config3.default_permission_mode === undefined || isDefaultPermissionMode2(config3.default_permission_mode)) && (config3.transcribe_voice === undefined || isBoolean3(config3.transcribe_voice)) && (config3.show_completed_reaction === undefined || isBoolean3(config3.show_completed_reaction)) && (config3.listen_mode === undefined || isBoolean3(config3.listen_mode)) && isValidSlackAllowBotsConfigValue(config3.allow_bots);
448070
448294
  },
448071
448295
  toAccountPatch(config3) {
448072
448296
  return {
@@ -448076,7 +448300,8 @@ var init_account_config4 = __esm(() => {
448076
448300
  agentId: isNullableString4(config3.agent_id) ? config3.agent_id : undefined,
448077
448301
  defaultPermissionMode: isDefaultPermissionMode2(config3.default_permission_mode) ? migratePermissionMode(config3.default_permission_mode) : undefined,
448078
448302
  transcribeVoice: isBoolean3(config3.transcribe_voice) ? config3.transcribe_voice : undefined,
448079
- listenMode: isBoolean3(config3.listen_mode) ? config3.listen_mode : undefined
448303
+ listenMode: isBoolean3(config3.listen_mode) ? config3.listen_mode : undefined,
448304
+ allowBots: config3.allow_bots !== undefined && isValidSlackAllowBotsConfigValue(config3.allow_bots) ? normalizeSlackAllowBotsMode(config3.allow_bots) : undefined
448080
448305
  };
448081
448306
  },
448082
448307
  toAccountConfig(account) {
@@ -448087,7 +448312,8 @@ var init_account_config4 = __esm(() => {
448087
448312
  agent_id: account.agentId,
448088
448313
  default_permission_mode: account.defaultPermissionMode ?? DEFAULT_SLACK_PERMISSION_MODE,
448089
448314
  transcribe_voice: account.transcribeVoice === true,
448090
- listen_mode: account.listenMode === true
448315
+ listen_mode: account.listenMode === true,
448316
+ allow_bots: account.allowBots ?? false
448091
448317
  };
448092
448318
  },
448093
448319
  toConfigSnapshotConfig(account) {
@@ -448098,7 +448324,8 @@ var init_account_config4 = __esm(() => {
448098
448324
  agent_id: account.agentId,
448099
448325
  default_permission_mode: account.defaultPermissionMode ?? DEFAULT_SLACK_PERMISSION_MODE,
448100
448326
  transcribe_voice: account.transcribeVoice === true,
448101
- listen_mode: account.listenMode === true
448327
+ listen_mode: account.listenMode === true,
448328
+ allow_bots: account.allowBots ?? false
448102
448329
  };
448103
448330
  },
448104
448331
  shouldRefreshDisplayName(patch2) {
@@ -458863,6 +459090,7 @@ function createAccountFromPatch(channelId, accountId, patch2) {
458863
459090
  defaultPermissionMode: normalizedPatch.defaultPermissionMode ?? DEFAULT_SLACK_PERMISSION_MODE,
458864
459091
  transcribeVoice: normalizedPatch.transcribeVoice === true,
458865
459092
  listenMode: normalizedPatch.listenMode === true,
459093
+ allowBots: normalizedPatch.allowBots ?? false,
458866
459094
  dmPolicy: normalizedPatch.dmPolicy ?? "open",
458867
459095
  allowedUsers: normalizedPatch.allowedUsers ?? [],
458868
459096
  createdAt: now,
@@ -458969,6 +459197,7 @@ function mergeAccountPatch(existing, patch2) {
458969
459197
  defaultPermissionMode: normalizedPatch.defaultPermissionMode ?? existing.defaultPermissionMode ?? DEFAULT_SLACK_PERMISSION_MODE,
458970
459198
  transcribeVoice: normalizedPatch.transcribeVoice ?? existing.transcribeVoice ?? false,
458971
459199
  listenMode: normalizedPatch.listenMode ?? existing.listenMode ?? false,
459200
+ allowBots: normalizedPatch.allowBots ?? existing.allowBots ?? false,
458972
459201
  dmPolicy: normalizedPatch.dmPolicy ?? existing.dmPolicy,
458973
459202
  allowedUsers: normalizedPatch.allowedUsers ?? existing.allowedUsers,
458974
459203
  updatedAt: nextUpdatedAt
@@ -459150,6 +459379,7 @@ function toAccountSnapshot(account) {
459150
459379
  defaultPermissionMode: account.defaultPermissionMode ?? DEFAULT_SLACK_PERMISSION_MODE,
459151
459380
  transcribeVoice: account.transcribeVoice === true,
459152
459381
  listenMode: account.listenMode === true,
459382
+ allowBots: account.allowBots ?? false,
459153
459383
  createdAt: account.createdAt,
459154
459384
  updatedAt: account.updatedAt
459155
459385
  };
@@ -459297,7 +459527,8 @@ function getChannelConfigSnapshot(channelId, accountId) {
459297
459527
  agentId: account.agentId,
459298
459528
  defaultPermissionMode: account.defaultPermissionMode ?? DEFAULT_SLACK_PERMISSION_MODE,
459299
459529
  transcribeVoice: account.transcribeVoice === true,
459300
- listenMode: account.listenMode === true
459530
+ listenMode: account.listenMode === true,
459531
+ allowBots: account.allowBots ?? false
459301
459532
  };
459302
459533
  }
459303
459534
  async function getChannelConfigSnapshotWithSecrets(channelId, accountId) {
@@ -459820,6 +460051,7 @@ async function setChannelConfigLive(channelId, patch2, accountId) {
459820
460051
  threadPolicyByChannel: normalizedPatch.threadPolicyByChannel,
459821
460052
  acknowledgeMessageReaction: normalizedPatch.acknowledgeMessageReaction,
459822
460053
  listenMode: normalizedPatch.listenMode,
460054
+ allowBots: normalizedPatch.allowBots,
459823
460055
  removeStaleRoutes: normalizedPatch.removeStaleRoutes,
459824
460056
  inboundDebounceMs: normalizedPatch.inboundDebounceMs,
459825
460057
  selfChatMode: normalizedPatch.selfChatMode,
@@ -459854,6 +460086,7 @@ async function setChannelConfigLive(channelId, patch2, accountId) {
459854
460086
  threadPolicyByChannel: normalizedPatch.threadPolicyByChannel,
459855
460087
  acknowledgeMessageReaction: normalizedPatch.acknowledgeMessageReaction,
459856
460088
  listenMode: normalizedPatch.listenMode,
460089
+ allowBots: normalizedPatch.allowBots,
459857
460090
  removeStaleRoutes: normalizedPatch.removeStaleRoutes,
459858
460091
  inboundDebounceMs: normalizedPatch.inboundDebounceMs,
459859
460092
  selfChatMode: normalizedPatch.selfChatMode,
@@ -473482,7 +473715,6 @@ When to use: ${whenToUse}` : description;
473482
473715
  description: modelDescription,
473483
473716
  whenToUse,
473484
473717
  argumentHint: getFrontmatterString2(frontmatter, "argument-hint"),
473485
- arguments: getFrontmatterStringList2(frontmatter, "arguments"),
473486
473718
  disableModelInvocation: getFrontmatterBoolean2(frontmatter, "disable-model-invocation") ?? false,
473487
473719
  userInvocable: getFrontmatterBoolean2(frontmatter, "user-invocable") ?? true,
473488
473720
  category: getFrontmatterString2(frontmatter, "category"),
@@ -489812,10 +490044,10 @@ function columns(parts, width) {
489812
490044
  let extra = spare - base3 * gaps;
489813
490045
  let result = first;
489814
490046
  for (let i4 = 1;i4 < items3.length; i4 += 1) {
489815
- const pad = base3 + (extra > 0 ? 1 : 0);
490047
+ const pad3 = base3 + (extra > 0 ? 1 : 0);
489816
490048
  if (extra > 0)
489817
490049
  extra -= 1;
489818
- result += " ".repeat(pad) + items3[i4];
490050
+ result += " ".repeat(pad3) + items3[i4];
489819
490051
  }
489820
490052
  return truncateToWidth(result, width);
489821
490053
  }
@@ -507243,8 +507475,8 @@ function splitSystemReminderBlocks(text2) {
507243
507475
  return blocks;
507244
507476
  }
507245
507477
  function padToColumns(text2, columns2) {
507246
- const pad = Math.max(0, columns2 - inkStringWidth(text2));
507247
- return `${text2}${" ".repeat(pad)}`;
507478
+ const pad3 = Math.max(0, columns2 - inkStringWidth(text2));
507479
+ return `${text2}${" ".repeat(pad3)}`;
507248
507480
  }
507249
507481
  function renderBlock(text2, contentWidth, columns2, highlighted, promptPrefix, continuationPrefix) {
507250
507482
  const inputLines = text2.split(`
@@ -534222,7 +534454,6 @@ ${SYSTEM_REMINDER_CLOSE}`),
534222
534454
  const { loadRenderedSkillContent: loadRenderedSkillContent2, wrapSkillContent: wrapSkillContent2 } = await Promise.resolve().then(() => (init_skill(), exports_skill));
534223
534455
  const skillContent = await loadRenderedSkillContent2("generating-mod-envs", {
534224
534456
  agentId,
534225
- args,
534226
534457
  allowDisabledModelInvocation: true
534227
534458
  });
534228
534459
  const request = args ? `The user ran \`/mods generate-env ${args}\`. Use the loaded skill to help them generate, review, validate, or improve a mod learning env JSON.` : "The user ran `/mods generate-env` without arguments. Use the loaded skill's bare behavior for mod learning env generation.";
@@ -534492,7 +534723,6 @@ ${SYSTEM_REMINDER_CLOSE}`),
534492
534723
  const { loadRenderedSkillContent: loadRenderedSkillContent2, wrapSkillContent: wrapSkillContent2 } = await Promise.resolve().then(() => (init_skill(), exports_skill));
534493
534724
  const skillContent = await loadRenderedSkillContent2("customizing-statusline", {
534494
534725
  agentId,
534495
- args,
534496
534726
  allowDisabledModelInvocation: true
534497
534727
  });
534498
534728
  const request = args ? `The user ran \`/statusline ${args}\`. Use the loaded skill to help them create, edit, or migrate their Letta Code statusline mod.` : "The user ran `/statusline` without arguments. Use the loaded skill's bare `/statusline` behavior.";
@@ -535968,13 +536198,12 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
535968
536198
  cmd.fail(`Pending approval(s). Resolve approvals before running /${matchedSkill.id}.`);
535969
536199
  return { submitted: false };
535970
536200
  }
535971
- const args = trimmed.slice(`/${matchedSkill.id}`.length).trim();
536201
+ const userRequest = trimmed.slice(`/${matchedSkill.id}`.length).trim();
535972
536202
  setCommandRunning(true);
535973
536203
  try {
535974
- const { loadRenderedSkillContent: loadRenderedSkillContent2, wrapSkillContent: wrapSkillContent2 } = await Promise.resolve().then(() => (init_skill(), exports_skill));
536204
+ const { loadRenderedSkillContent: loadRenderedSkillContent2, wrapSkillPrompt: wrapSkillPrompt2 } = await Promise.resolve().then(() => (init_skill(), exports_skill));
535975
536205
  const skillContent = await loadRenderedSkillContent2(matchedSkill.id, {
535976
536206
  agentId,
535977
- args,
535978
536207
  allowDisabledModelInvocation: true
535979
536208
  });
535980
536209
  cmd.finish("Running skill...", true);
@@ -535982,7 +536211,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
535982
536211
  {
535983
536212
  type: "message",
535984
536213
  role: "user",
535985
- content: buildTextParts(wrapSkillContent2(matchedSkill.id, skillContent)),
536214
+ content: buildTextParts(wrapSkillPrompt2(matchedSkill.id, skillContent, userRequest)),
535986
536215
  otid: randomUUID37()
535987
536216
  }
535988
536217
  ]);
@@ -537021,26 +537250,25 @@ function App2({
537021
537250
  continue;
537022
537251
  if (shouldFireTask(task2, now)) {
537023
537252
  firedThisMinute.add(task2.id);
537253
+ const intendedOccurrence = getIntendedCronOccurrence(task2, now);
537024
537254
  const jitterMs = task2.recurring ? task2.jitter_offset_ms : 0;
537025
537255
  const taskId = task2.id;
537026
537256
  const doFire = () => {
537027
537257
  const freshTask = getTask2(taskId);
537028
537258
  if (!freshTask || freshTask.status !== "active")
537029
537259
  return;
537030
- const text2 = [
537031
- `Scheduled task "${freshTask.name}" is firing.`,
537032
- freshTask.recurring ? `This is fire #${freshTask.fire_count + 1} (cron: ${freshTask.cron}).` : `This is a one-off scheduled task.`,
537033
- "",
537034
- freshTask.prompt
537035
- ].join(`
537036
- `);
537260
+ const schedulerNow = new Date;
537261
+ const text2 = wrapCronPrompt(freshTask, {
537262
+ intendedOccurrence,
537263
+ schedulerNow
537264
+ });
537037
537265
  addToMessageQueue({
537038
537266
  kind: "user",
537039
537267
  text: text2,
537040
537268
  agentId: freshTask.agent_id,
537041
537269
  conversationId: freshTask.conversation_id
537042
537270
  });
537043
- const nowIso = new Date().toISOString();
537271
+ const nowIso = schedulerNow.toISOString();
537044
537272
  if (freshTask.recurring) {
537045
537273
  updateTask2(freshTask.id, (t2) => {
537046
537274
  t2.last_fired_at = nowIso;
@@ -537056,7 +537284,7 @@ function App2({
537056
537284
  }
537057
537285
  safeAppendCronRunLogForTask(freshTask, {
537058
537286
  status: "ok",
537059
- runAtMs: now.getTime(),
537287
+ runAtMs: schedulerNow.getTime(),
537060
537288
  scheduledFor: freshTask.scheduled_for,
537061
537289
  firedAt: nowIso
537062
537290
  });
@@ -549661,15 +549889,15 @@ function convertLegacyMessage(message, nextId2) {
549661
549889
  return result;
549662
549890
  }
549663
549891
  function timestampSuffix(date6 = new Date) {
549664
- const pad = (value) => String(value).padStart(2, "0");
549892
+ const pad3 = (value) => String(value).padStart(2, "0");
549665
549893
  return [
549666
549894
  date6.getFullYear(),
549667
- pad(date6.getMonth() + 1),
549668
- pad(date6.getDate()),
549895
+ pad3(date6.getMonth() + 1),
549896
+ pad3(date6.getDate()),
549669
549897
  "-",
549670
- pad(date6.getHours()),
549671
- pad(date6.getMinutes()),
549672
- pad(date6.getSeconds())
549898
+ pad3(date6.getHours()),
549899
+ pad3(date6.getMinutes()),
549900
+ pad3(date6.getSeconds())
549673
549901
  ].join("");
549674
549902
  }
549675
549903
  function manifest(input) {
@@ -550022,13 +550250,13 @@ function getAgentRoot(agentId) {
550022
550250
  return dirname28(getMemoryRoot(agentId));
550023
550251
  }
550024
550252
  function formatBackupTimestamp(date6 = new Date) {
550025
- const pad = (value) => String(value).padStart(2, "0");
550253
+ const pad3 = (value) => String(value).padStart(2, "0");
550026
550254
  const yyyy = date6.getFullYear();
550027
- const mm = pad(date6.getMonth() + 1);
550028
- const dd2 = pad(date6.getDate());
550029
- const hh = pad(date6.getHours());
550030
- const min = pad(date6.getMinutes());
550031
- const ss = pad(date6.getSeconds());
550255
+ const mm = pad3(date6.getMonth() + 1);
550256
+ const dd2 = pad3(date6.getDate());
550257
+ const hh = pad3(date6.getHours());
550258
+ const min = pad3(date6.getMinutes());
550259
+ const ss = pad3(date6.getSeconds());
550032
550260
  return `${yyyy}${mm}${dd2}-${hh}${min}${ss}`;
550033
550261
  }
550034
550262
  async function listBackups(agentId) {
@@ -556331,4 +556559,4 @@ Error during initialization: ${message}`);
556331
556559
  }
556332
556560
  main2();
556333
556561
 
556334
- //# debugId=37A057B0FA28037E64756E2164756E21
556562
+ //# debugId=5F03A493E92C4D6964756E2164756E21